Unified · Split
| @@ -122,6 +122,7 @@ ForEachMacros: · 121 unmodified lines | ||
| 122 | 122 | - 'drm_for_each_bridge_in_chain' |
| 123 | 123 | - 'drm_for_each_connector_iter' |
| 124 | 124 | - 'drm_for_each_crtc' |
| 125 | + - 'drm_for_each_crtc_reverse' | |
| 125 | 126 | - 'drm_for_each_encoder' |
| 126 | 127 | - 'drm_for_each_encoder_mask' |
| 127 | 128 | - 'drm_for_each_fb' |
| @@ -203,14 +204,13 @@ ForEachMacros: · 75 unmodified lines | ||
| 203 | 204 | - 'for_each_matching_node' |
| 204 | 205 | - 'for_each_matching_node_and_match' |
| 205 | 206 | - 'for_each_member' |
| 206 | − - 'for_each_mem_region' | |
| 207 | − - 'for_each_memblock_type' | |
| 208 | 207 | - 'for_each_memcg_cache_index' |
| 209 | 208 | - 'for_each_mem_pfn_range' |
| 210 | 209 | - '__for_each_mem_range' |
| 211 | 210 | - 'for_each_mem_range' |
| 212 | 211 | - '__for_each_mem_range_rev' |
| 213 | 212 | - 'for_each_mem_range_rev' |
| 213 | + - 'for_each_mem_region' | |
| 214 | 214 | - 'for_each_migratetype_order' |
| 215 | 215 | - 'for_each_msi_entry' |
| 216 | 216 | - 'for_each_msi_entry_safe' |
| @@ -276,10 +276,8 @@ ForEachMacros: · 59 unmodified lines | ||
| 276 | 276 | - 'for_each_reserved_mem_range' |
| 277 | 277 | - 'for_each_reserved_mem_region' |
| 278 | 278 | - 'for_each_rtd_codec_dais' |
| 279 | − - 'for_each_rtd_codec_dais_rollback' | |
| 280 | 279 | - 'for_each_rtd_components' |
| 281 | 280 | - 'for_each_rtd_cpu_dais' |
| 282 | − - 'for_each_rtd_cpu_dais_rollback' | |
| 283 | 281 | - 'for_each_rtd_dais' |
| 284 | 282 | - 'for_each_set_bit' |
| 285 | 283 | - 'for_each_set_bit_from' |
| @@ -298,6 +296,7 @@ ForEachMacros: · 12 unmodified lines | ||
| 298 | 296 | - '__for_each_thread' |
| 299 | 297 | - 'for_each_thread' |
| 300 | 298 | - 'for_each_unicast_dest_pgid' |
| 299 | + - 'for_each_vsi' | |
| 301 | 300 | - 'for_each_wakeup_source' |
| 302 | 301 | - 'for_each_zone' |
| 303 | 302 | - 'for_each_zone_zonelist' |
| @@ -330,6 +329,7 @@ ForEachMacros: · 26 unmodified lines | ||
| 330 | 329 | - 'hlist_for_each_entry_rcu_bh' |
| 331 | 330 | - 'hlist_for_each_entry_rcu_notrace' |
| 332 | 331 | - 'hlist_for_each_entry_safe' |
| 332 | + - 'hlist_for_each_entry_srcu' | |
| 333 | 333 | - '__hlist_for_each_rcu' |
| 334 | 334 | - 'hlist_for_each_safe' |
| 335 | 335 | - 'hlist_nulls_for_each_entry' |
| @@ -378,6 +378,7 @@ ForEachMacros: · 42 unmodified lines | ||
| 378 | 378 | - 'list_for_each_entry_safe_continue' |
| 379 | 379 | - 'list_for_each_entry_safe_from' |
| 380 | 380 | - 'list_for_each_entry_safe_reverse' |
| 381 | + - 'list_for_each_entry_srcu' | |
| 381 | 382 | - 'list_for_each_prev' |
| 382 | 383 | - 'list_for_each_prev_safe' |
| 383 | 384 | - 'list_for_each_safe' |
| @@ -411,6 +412,8 @@ ForEachMacros: · 27 unmodified lines | ||
| 411 | 412 | - 'of_property_for_each_string' |
| 412 | 413 | - 'of_property_for_each_u32' |
| 413 | 414 | - 'pci_bus_for_each_resource' |
| 415 | + - 'pcl_for_each_chunk' | |
| 416 | + - 'pcl_for_each_segment' | |
| 414 | 417 | - 'pcm_for_each_format' |
| 415 | 418 | - 'ping_portaddr_for_each_entry' |
| 416 | 419 | - 'plist_for_each' |
| @@ -9,9 +9,6 @@ · 8 unmodified lines | ||
| 9 | 9 | # |
| 10 | 10 | # Please keep this list dictionary sorted. |
| 11 | 11 | # |
| 12 | −# This comment is parsed by git-shortlog: | |
| 13 | −# repo-abbrev: /pub/scm/linux/kernel/git/ | |
| 14 | −# | |
| 15 | 12 | Aaron Durbin <adurbin@google.com> |
| 16 | 13 | Adam Oldham <oldhamca@gmail.com> |
| 17 | 14 | Adam Radford <aradford@gmail.com> |
| @@ -40,6 +37,7 @@ Andrew Murray <amurray@thegoodpenguin.co.uk> <amurray@embedded-bits.co.uk> · 22 unmodified lines | ||
| 40 | 37 | Andrew Murray <amurray@thegoodpenguin.co.uk> <andrew.murray@arm.com> |
| 41 | 38 | Andrew Vasquez <andrew.vasquez@qlogic.com> |
| 42 | 39 | Andrey Ryabinin <ryabinin.a.a@gmail.com> <a.ryabinin@samsung.com> |
| 40 | +Andrey Ryabinin <ryabinin.a.a@gmail.com> <aryabinin@virtuozzo.com> | |
| 43 | 41 | Andy Adamson <andros@citi.umich.edu> |
| 44 | 42 | Antoine Tenart <atenart@kernel.org> <antoine.tenart@bootlin.com> |
| 45 | 43 | Antoine Tenart <atenart@kernel.org> <antoine.tenart@free-electrons.com> |
| @@ -55,6 +53,8 @@ Bart Van Assche <bvanassche@acm.org> <bart.vanassche@wdc.com> · 9 unmodified lines | ||
| 55 | 53 | Ben Gardner <bgardner@wabtec.com> |
| 56 | 54 | Ben M Cahill <ben.m.cahill@intel.com> |
| 57 | 55 | Björn Steinbrink <B.Steinbrink@gmx.de> |
| 56 | +Björn Töpel <bjorn@kernel.org> <bjorn.topel@gmail.com> | |
| 57 | +Björn Töpel <bjorn@kernel.org> <bjorn.topel@intel.com> | |
| 58 | 58 | Boris Brezillon <bbrezillon@kernel.org> <b.brezillon.dev@gmail.com> |
| 59 | 59 | Boris Brezillon <bbrezillon@kernel.org> <b.brezillon@overkiz.com> |
| 60 | 60 | Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@bootlin.com> |
| @@ -180,6 +180,8 @@ Kees Cook <keescook@chromium.org> <kees.cook@canonical.com> · 119 unmodified lines | ||
| 180 | 180 | Kees Cook <keescook@chromium.org> <keescook@google.com> |
| 181 | 181 | Kees Cook <keescook@chromium.org> <kees@outflux.net> |
| 182 | 182 | Kees Cook <keescook@chromium.org> <kees@ubuntu.com> |
| 183 | +Keith Busch <kbusch@kernel.org> <keith.busch@intel.com> | |
| 184 | +Keith Busch <kbusch@kernel.org> <keith.busch@linux.intel.com> | |
| 183 | 185 | Kenneth W Chen <kenneth.w.chen@intel.com> |
| 184 | 186 | Konstantin Khlebnikov <koct9i@gmail.com> <khlebnikov@yandex-team.ru> |
| 185 | 187 | Konstantin Khlebnikov <koct9i@gmail.com> <k.khlebnikov@samsung.com> |
| @@ -200,6 +202,8 @@ Li Yang <leoyang.li@nxp.com> <leoli@freescale.com> · 14 unmodified lines | ||
| 200 | 202 | Li Yang <leoyang.li@nxp.com> <leo@zh-kernel.org> |
| 201 | 203 | Lukasz Luba <lukasz.luba@arm.com> <l.luba@partner.samsung.com> |
| 202 | 204 | Maciej W. Rozycki <macro@mips.com> <macro@imgtec.com> |
| 205 | +Manivannan Sadhasivam <mani@kernel.org> <manivannanece23@gmail.com> | |
| 206 | +Manivannan Sadhasivam <mani@kernel.org> <manivannan.sadhasivam@linaro.org> | |
| 203 | 207 | Marcin Nowakowski <marcin.nowakowski@mips.com> <marcin.nowakowski@imgtec.com> |
| 204 | 208 | Marc Zyngier <maz@kernel.org> <marc.zyngier@arm.com> |
| 205 | 209 | Mark Brown <broonie@sirena.org.uk> |
| @@ -245,6 +249,7 @@ Morten Welinder <welinder@anemone.rentec.com> · 39 unmodified lines | ||
| 245 | 249 | Morten Welinder <welinder@darter.rentec.com> |
| 246 | 250 | Morten Welinder <welinder@troll.com> |
| 247 | 251 | Mythri P K <mythripk@ti.com> |
| 252 | +Nathan Chancellor <nathan@kernel.org> <natechancellor@gmail.com> | |
| 248 | 253 | Nguyen Anh Quynh <aquynh@gmail.com> |
| 249 | 254 | Nicolas Ferre <nicolas.ferre@microchip.com> <nicolas.ferre@atmel.com> |
| 250 | 255 | Nicolas Pitre <nico@fluxnic.net> <nicolas.pitre@linaro.org> |
| @@ -335,6 +340,8 @@ Vinod Koul <vkoul@kernel.org> <vkoul@infradead.org> · 84 unmodified lines | ||
| 335 | 340 | Viresh Kumar <vireshk@kernel.org> <viresh.kumar2@arm.com> |
| 336 | 341 | Viresh Kumar <vireshk@kernel.org> <viresh.kumar@st.com> |
| 337 | 342 | Viresh Kumar <vireshk@kernel.org> <viresh.linux@gmail.com> |
| 343 | +Viresh Kumar <viresh.kumar@linaro.org> <viresh.kumar@linaro.org> | |
| 344 | +Viresh Kumar <viresh.kumar@linaro.org> <viresh.kumar@linaro.com> | |
| 338 | 345 | Vivien Didelot <vivien.didelot@gmail.com> <vivien.didelot@savoirfairelinux.com> |
| 339 | 346 | Vlad Dogaru <ddvlad@gmail.com> <vlad.dogaru@intel.com> |
| 340 | 347 | Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@parallels.com> |
| @@ -710,6 +710,10 @@ S: Las Cuevas 2385 - Bo Guemes · 709 unmodified lines | ||
| 710 | 710 | S: Las Heras, Mendoza CP 5539 |
| 711 | 711 | S: Argentina |
| 712 | 712 | |
| 713 | +N: Jay Cliburn | |
| 714 | +E: jcliburn@gmail.com | |
| 715 | +D: ATLX Ethernet drivers | |
| 716 | + | |
| 713 | 717 | N: Steven P. Cole |
| 714 | 718 | E: scole@lanl.gov |
| 715 | 719 | E: elenstev@mesatop.com |
| @@ -1284,6 +1288,10 @@ D: Major kbuild rework during the 2.5 cycle · 568 unmodified lines | ||
| 1284 | 1288 | D: ISDN Maintainer |
| 1285 | 1289 | S: USA |
| 1286 | 1290 | |
| 1291 | +N: Gerrit Renker | |
| 1292 | +E: gerrit@erg.abdn.ac.uk | |
| 1293 | +D: DCCP protocol support. | |
| 1294 | + | |
| 1287 | 1295 | N: Philip Gladstone |
| 1288 | 1296 | E: philip@gladstonefamily.net |
| 1289 | 1297 | D: Kernel / timekeeping stuff |
| @@ -2138,6 +2146,10 @@ E: seasons@falcon.sch.bme.hu · 848 unmodified lines | ||
| 2138 | 2146 | E: seasons@makosteszta.sote.hu |
| 2139 | 2147 | D: Original author of software suspend |
| 2140 | 2148 | |
| 2149 | +N: Alexey Kuznetsov | |
| 2150 | +E: kuznet@ms2.inr.ac.ru | |
| 2151 | +D: Author and maintainer of large parts of the networking stack | |
| 2152 | + | |
| 2141 | 2153 | N: Jaroslav Kysela |
| 2142 | 2154 | E: perex@perex.cz |
| 2143 | 2155 | W: https://www.perex.cz |
| @@ -2696,6 +2708,10 @@ N: Wolfgang Muees · 552 unmodified lines | ||
| 2696 | 2708 | E: wolfgang@iksw-muees.de |
| 2697 | 2709 | D: Auerswald USB driver |
| 2698 | 2710 | |
| 2711 | +N: Shrijeet Mukherjee | |
| 2712 | +E: shrijeet@gmail.com | |
| 2713 | +D: Network routing domains (VRF). | |
| 2714 | + | |
| 2699 | 2715 | N: Paul Mundt |
| 2700 | 2716 | E: paul.mundt@gmail.com |
| 2701 | 2717 | D: SuperH maintainer |
| @@ -4110,6 +4126,10 @@ S: B-1206 Jingmao Guojigongyu · 1408 unmodified lines | ||
| 4110 | 4126 | S: 16 Baliqiao Nanjie, Beijing 101100 |
| 4111 | 4127 | S: People's Repulic of China |
| 4112 | 4128 | |
| 4129 | +N: Aviad Yehezkel | |
| 4130 | +E: aviadye@nvidia.com | |
| 4131 | +D: Kernel TLS implementation and offload support. | |
| 4132 | + | |
| 4113 | 4133 | N: Victor Yodaiken |
| 4114 | 4134 | E: yodaiken@fsmlabs.com |
| 4115 | 4135 | D: RTLinux (RealTime Linux) |
| @@ -4167,6 +4187,10 @@ S: 1507 145th Place SE #B5 · 51 unmodified lines | ||
| 4167 | 4187 | S: Bellevue, Washington 98007 |
| 4168 | 4188 | S: USA |
| 4169 | 4189 | |
| 4190 | +N: Wensong Zhang | |
| 4191 | +E: wensong@linux-vs.org | |
| 4192 | +D: IP virtual server (IPVS). | |
| 4193 | + | |
| 4170 | 4194 | N: Haojian Zhuang |
| 4171 | 4195 | E: haojian.zhuang@gmail.com |
| 4172 | 4196 | D: MMP support |
| @@ -5,8 +5,8 @@ Description: · 4 unmodified lines | ||
| 5 | 5 | Provide a place in sysfs for the device link objects in the |
| 6 | 6 | kernel at any given time. The name of a device link directory, |
| 7 | 7 | denoted as ... above, is of the form <supplier>--<consumer> |
| 8 | − where <supplier> is the supplier device name and <consumer> is | |
| 9 | − the consumer device name. | |
| 8 | + where <supplier> is the supplier bus:device name and <consumer> | |
| 9 | + is the consumer bus:device name. | |
| 10 | 10 | |
| 11 | 11 | What: /sys/class/devlink/.../auto_remove_on |
| 12 | 12 | Date: May 2020 |
| @@ -4,5 +4,6 @@ Contact: Saravana Kannan <saravanak@google.com> · 3 unmodified lines | ||
| 4 | 4 | Description: |
| 5 | 5 | The /sys/devices/.../consumer:<consumer> are symlinks to device |
| 6 | 6 | links where this device is the supplier. <consumer> denotes the |
| 7 | − name of the consumer in that device link. There can be zero or | |
| 8 | − more of these symlinks for a given device. | |
| 7 | + name of the consumer in that device link and is of the form | |
| 8 | + bus:device name. There can be zero or more of these symlinks | |
| 9 | + for a given device. | |
| @@ -4,5 +4,6 @@ Contact: Saravana Kannan <saravanak@google.com> · 3 unmodified lines | ||
| 4 | 4 | Description: |
| 5 | 5 | The /sys/devices/.../supplier:<supplier> are symlinks to device |
| 6 | 6 | links where this device is the consumer. <supplier> denotes the |
| 7 | − name of the supplier in that device link. There can be zero or | |
| 8 | − more of these symlinks for a given device. | |
| 7 | + name of the supplier in that device link and is of the form | |
| 8 | + bus:device name. There can be zero or more of these symlinks | |
| 9 | + for a given device. | |
| @@ -916,21 +916,25 @@ Date: September 2014 · 915 unmodified lines | ||
| 916 | 916 | Contact: Subhash Jadavani <subhashj@codeaurora.org> |
| 917 | 917 | Description: This entry could be used to set or show the UFS device |
| 918 | 918 | runtime power management level. The current driver |
| 919 | − implementation supports 6 levels with next target states: | |
| 919 | + implementation supports 7 levels with next target states: | |
| 920 | 920 | |
| 921 | 921 | == ==================================================== |
| 922 | − 0 an UFS device will stay active, an UIC link will | |
| 922 | + 0 UFS device will stay active, UIC link will | |
| 923 | 923 | stay active |
| 924 | − 1 an UFS device will stay active, an UIC link will | |
| 924 | + 1 UFS device will stay active, UIC link will | |
| 925 | 925 | hibernate |
| 926 | − 2 an UFS device will moved to sleep, an UIC link will | |
| 926 | + 2 UFS device will be moved to sleep, UIC link will | |
| 927 | 927 | stay active |
| 928 | − 3 an UFS device will moved to sleep, an UIC link will | |
| 928 | + 3 UFS device will be moved to sleep, UIC link will | |
| 929 | 929 | hibernate |
| 930 | − 4 an UFS device will be powered off, an UIC link will | |
| 930 | + 4 UFS device will be powered off, UIC link will | |
| 931 | 931 | hibernate |
| 932 | − 5 an UFS device will be powered off, an UIC link will | |
| 932 | + 5 UFS device will be powered off, UIC link will | |
| 933 | 933 | be powered off |
| 934 | + 6 UFS device will be moved to deep sleep, UIC link | |
| 935 | + will be powered off. Note, deep sleep might not be | |
| 936 | + supported in which case this value will not be | |
| 937 | + accepted | |
| 934 | 938 | == ==================================================== |
| 935 | 939 | |
| 936 | 940 | What: /sys/bus/platform/drivers/ufshcd/*/rpm_target_dev_state |
| @@ -954,21 +958,25 @@ Date: September 2014 · 17 unmodified lines | ||
| 954 | 958 | Contact: Subhash Jadavani <subhashj@codeaurora.org> |
| 955 | 959 | Description: This entry could be used to set or show the UFS device |
| 956 | 960 | system power management level. The current driver |
| 957 | − implementation supports 6 levels with next target states: | |
| 961 | + implementation supports 7 levels with next target states: | |
| 958 | 962 | |
| 959 | 963 | == ==================================================== |
| 960 | − 0 an UFS device will stay active, an UIC link will | |
| 964 | + 0 UFS device will stay active, UIC link will | |
| 961 | 965 | stay active |
| 962 | − 1 an UFS device will stay active, an UIC link will | |
| 966 | + 1 UFS device will stay active, UIC link will | |
| 963 | 967 | hibernate |
| 964 | − 2 an UFS device will moved to sleep, an UIC link will | |
| 968 | + 2 UFS device will be moved to sleep, UIC link will | |
| 965 | 969 | stay active |
| 966 | − 3 an UFS device will moved to sleep, an UIC link will | |
| 970 | + 3 UFS device will be moved to sleep, UIC link will | |
| 967 | 971 | hibernate |
| 968 | − 4 an UFS device will be powered off, an UIC link will | |
| 972 | + 4 UFS device will be powered off, UIC link will | |
| 969 | 973 | hibernate |
| 970 | − 5 an UFS device will be powered off, an UIC link will | |
| 974 | + 5 UFS device will be powered off, UIC link will | |
| 971 | 975 | be powered off |
| 976 | + 6 UFS device will be moved to deep sleep, UIC link | |
| 977 | + will be powered off. Note, deep sleep might not be | |
| 978 | + supported in which case this value will not be | |
| 979 | + accepted | |
| 972 | 980 | == ==================================================== |
| 973 | 981 | |
| 974 | 982 | What: /sys/bus/platform/drivers/ufshcd/*/spm_target_dev_state |
| @@ -75,7 +75,7 @@ quiet_cmd_sphinx = SPHINX $@ --> file://$(abspath $(BUILDDIR)/$3/$4) · 74 unmodified lines | ||
| 75 | 75 | cmd_sphinx = $(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/userspace-api/media $2 && \ |
| 76 | 76 | PYTHONDONTWRITEBYTECODE=1 \ |
| 77 | 77 | BUILDDIR=$(abspath $(BUILDDIR)) SPHINX_CONF=$(abspath $(srctree)/$(src)/$5/$(SPHINX_CONF)) \ |
| 78 | − $(PYTHON) $(srctree)/scripts/jobserver-exec \ | |
| 78 | + $(PYTHON3) $(srctree)/scripts/jobserver-exec \ | |
| 79 | 79 | $(SHELL) $(srctree)/Documentation/sphinx/parallel-wrapper.sh \ |
| 80 | 80 | $(SPHINXBUILD) \ |
| 81 | 81 | -b $2 \ |
| @@ -473,7 +473,7 @@ read-side critical sections that follow the idle period (the oval near · 472 unmodified lines | ||
| 473 | 473 | the bottom of the diagram above). |
| 474 | 474 | |
| 475 | 475 | Plumbing this into the full grace-period execution is described |
| 476 | −`below <#Forcing%20Quiescent%20States>`__. | |
| 476 | +`below <Forcing Quiescent States_>`__. | |
| 477 | 477 | |
| 478 | 478 | CPU-Hotplug Interface |
| 479 | 479 | ^^^^^^^^^^^^^^^^^^^^^ |
| @@ -494,7 +494,7 @@ mask to detect CPUs having gone offline since the beginning of this · 14 unmodified lines | ||
| 494 | 494 | grace period. |
| 495 | 495 | |
| 496 | 496 | Plumbing this into the full grace-period execution is described |
| 497 | −`below <#Forcing%20Quiescent%20States>`__. | |
| 497 | +`below <Forcing Quiescent States_>`__. | |
| 498 | 498 | |
| 499 | 499 | Forcing Quiescent States |
| 500 | 500 | ^^^^^^^^^^^^^^^^^^^^^^^^ |
| @@ -532,7 +532,7 @@ from other CPUs. · 31 unmodified lines | ||
| 532 | 532 | | RCU. But this diagram is complex enough as it is, so simplicity | |
| 533 | 533 | | overrode accuracy. You can think of it as poetic license, or you can | |
| 534 | 534 | | think of it as misdirection that is resolved in the | |
| 535 | −| `stitched-together diagram <#Putting%20It%20All%20Together>`__. | | |
| 535 | +| `stitched-together diagram <Putting It All Together_>`__. | | |
| 536 | 536 | +-----------------------------------------------------------------------+ |
| 537 | 537 | |
| 538 | 538 | Grace-Period Cleanup |
| @@ -596,7 +596,7 @@ maintain ordering. For example, if the callback function wakes up a task · 57 unmodified lines | ||
| 596 | 596 | that runs on some other CPU, proper ordering must in place in both the |
| 597 | 597 | callback function and the task being awakened. To see why this is |
| 598 | 598 | important, consider the top half of the `grace-period |
| 599 | −cleanup <#Grace-Period%20Cleanup>`__ diagram. The callback might be | |
| 599 | +cleanup`_ diagram. The callback might be | |
| 600 | 600 | running on a CPU corresponding to the leftmost leaf ``rcu_node`` |
| 601 | 601 | structure, and awaken a task that is to run on a CPU corresponding to |
| 602 | 602 | the rightmost leaf ``rcu_node`` structure, and the grace-period kernel |
| @@ -45,7 +45,7 @@ requirements: · 44 unmodified lines | ||
| 45 | 45 | #. `Other RCU Flavors`_ |
| 46 | 46 | #. `Possible Future Changes`_ |
| 47 | 47 | |
| 48 | −This is followed by a `summary <#Summary>`__, however, the answers to | |
| 48 | +This is followed by a summary_, however, the answers to | |
| 49 | 49 | each quick quiz immediately follows the quiz. Select the big white space |
| 50 | 50 | with your mouse to see the answer. |
| 51 | 51 | |
| @@ -1096,7 +1096,7 @@ memory barriers. · 1044 unmodified lines | ||
| 1096 | 1096 | | case, voluntary context switch) within an RCU read-side critical | |
| 1097 | 1097 | | section. However, sleeping locks may be used within userspace RCU | |
| 1098 | 1098 | | read-side critical sections, and also within Linux-kernel sleepable | |
| 1099 | −| RCU `(SRCU) <#Sleepable%20RCU>`__ read-side critical sections. In | | |
| 1099 | +| RCU `(SRCU) <Sleepable RCU_>`__ read-side critical sections. In | | |
| 1100 | 1100 | | addition, the -rt patchset turns spinlocks into a sleeping locks so | |
| 1101 | 1101 | | that the corresponding critical sections can be preempted, which also | |
| 1102 | 1102 | | means that these sleeplockified spinlocks (but not other sleeping | |
| @@ -1186,7 +1186,7 @@ non-preemptible (``CONFIG_PREEMPT=n``) kernels, and thus `tiny · 83 unmodified lines | ||
| 1186 | 1186 | RCU <https://lkml.kernel.org/g/20090113221724.GA15307@linux.vnet.ibm.com>`__ |
| 1187 | 1187 | was born. Josh Triplett has since taken over the small-memory banner |
| 1188 | 1188 | with his `Linux kernel tinification <https://tiny.wiki.kernel.org/>`__ |
| 1189 | −project, which resulted in `SRCU <#Sleepable%20RCU>`__ becoming optional | |
| 1189 | +project, which resulted in `SRCU <Sleepable RCU_>`__ becoming optional | |
| 1190 | 1190 | for those kernels not needing it. |
| 1191 | 1191 | |
| 1192 | 1192 | The remaining performance requirements are, for the most part, |
| @@ -1457,8 +1457,8 @@ will vary as the value of ``HZ`` varies, and can also be changed using · 264 unmodified lines | ||
| 1457 | 1457 | the relevant Kconfig options and kernel boot parameters. RCU currently |
| 1458 | 1458 | does not do much sanity checking of these parameters, so please use |
| 1459 | 1459 | caution when changing them. Note that these forward-progress measures |
| 1460 | −are provided only for RCU, not for `SRCU <#Sleepable%20RCU>`__ or `Tasks | |
| 1461 | −RCU <#Tasks%20RCU>`__. | |
| 1460 | +are provided only for RCU, not for `SRCU <Sleepable RCU_>`__ or `Tasks | |
| 1461 | +RCU`_. | |
| 1462 | 1462 | |
| 1463 | 1463 | RCU takes the following steps in ``call_rcu()`` to encourage timely |
| 1464 | 1464 | invocation of callbacks when any given non-\ ``rcu_nocbs`` CPU has |
| @@ -1477,8 +1477,8 @@ encouragement was provided: · 12 unmodified lines | ||
| 1477 | 1477 | |
| 1478 | 1478 | Again, these are default values when running at ``HZ=1000``, and can be |
| 1479 | 1479 | overridden. Again, these forward-progress measures are provided only for |
| 1480 | −RCU, not for `SRCU <#Sleepable%20RCU>`__ or `Tasks | |
| 1481 | −RCU <#Tasks%20RCU>`__. Even for RCU, callback-invocation forward | |
| 1480 | +RCU, not for `SRCU <Sleepable RCU_>`__ or `Tasks | |
| 1481 | +RCU`_. Even for RCU, callback-invocation forward | |
| 1482 | 1482 | progress for ``rcu_nocbs`` CPUs is much less well-developed, in part |
| 1483 | 1483 | because workloads benefiting from ``rcu_nocbs`` CPUs tend to invoke |
| 1484 | 1484 | ``call_rcu()`` relatively infrequently. If workloads emerge that need |
| @@ -1920,7 +1920,7 @@ Hotplug CPU · 435 unmodified lines | ||
| 1920 | 1920 | |
| 1921 | 1921 | The Linux kernel supports CPU hotplug, which means that CPUs can come |
| 1922 | 1922 | and go. It is of course illegal to use any RCU API member from an |
| 1923 | −offline CPU, with the exception of `SRCU <#Sleepable%20RCU>`__ read-side | |
| 1923 | +offline CPU, with the exception of `SRCU <Sleepable RCU_>`__ read-side | |
| 1924 | 1924 | critical sections. This requirement was present from day one in |
| 1925 | 1925 | DYNIX/ptx, but on the other hand, the Linux kernel's CPU-hotplug |
| 1926 | 1926 | implementation is “interesting.” |
| @@ -2177,7 +2177,7 @@ handles these states differently: · 250 unmodified lines | ||
| 2177 | 2177 | However, RCU must be reliably informed as to whether any given CPU is |
| 2178 | 2178 | currently in the idle loop, and, for ``NO_HZ_FULL``, also whether that |
| 2179 | 2179 | CPU is executing in usermode, as discussed |
| 2180 | −`earlier <#Energy%20Efficiency>`__. It also requires that the | |
| 2180 | +`earlier <Energy Efficiency_>`__. It also requires that the | |
| 2181 | 2181 | scheduling-clock interrupt be enabled when RCU needs it to be: |
| 2182 | 2182 | |
| 2183 | 2183 | #. If a CPU is either idle or executing in usermode, and RCU believes it |
| @@ -2294,7 +2294,7 @@ Performance, Scalability, Response Time, and Reliability · 110 unmodified lines | ||
| 2294 | 2294 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 2295 | 2295 | |
| 2296 | 2296 | Expanding on the `earlier |
| 2297 | −discussion <#Performance%20and%20Scalability>`__, RCU is used heavily by | |
| 2297 | +discussion <Performance and Scalability_>`__, RCU is used heavily by | |
| 2298 | 2298 | hot code paths in performance-critical portions of the Linux kernel's |
| 2299 | 2299 | networking, security, virtualization, and scheduling code paths. RCU |
| 2300 | 2300 | must therefore use efficient implementations, especially in its |
| @@ -23,7 +23,7 @@ Here is what the fields mean: · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | - ``name`` |
| 25 | 25 | is an identifier string. A new /proc file will be created with this |
| 26 | − ``name below /proc/sys/fs/binfmt_misc``; cannot contain slashes ``/`` for | |
| 26 | + name below ``/proc/sys/fs/binfmt_misc``; cannot contain slashes ``/`` for | |
| 27 | 27 | obvious reasons. |
| 28 | 28 | - ``type`` |
| 29 | 29 | is the type of recognition. Give ``M`` for magic and ``E`` for extension. |
| @@ -83,7 +83,7 @@ Here is what the fields mean: · 53 unmodified lines | ||
| 83 | 83 | ``F`` - fix binary |
| 84 | 84 | The usual behaviour of binfmt_misc is to spawn the |
| 85 | 85 | binary lazily when the misc format file is invoked. However, |
| 86 | − this doesn``t work very well in the face of mount namespaces and | |
| 86 | + this doesn't work very well in the face of mount namespaces and | |
| 87 | 87 | changeroots, so the ``F`` mode opens the binary as soon as the |
| 88 | 88 | emulation is installed and uses the opened image to spawn the |
| 89 | 89 | emulator, meaning it is always available once installed, |
| @@ -154,7 +154,7 @@ get the boot configuration data. · 153 unmodified lines | ||
| 154 | 154 | Because of this "piggyback" method, there is no need to change or |
| 155 | 155 | update the boot loader and the kernel image itself as long as the boot |
| 156 | 156 | loader passes the correct initrd file size. If by any chance, the boot |
| 157 | −loader passes a longer size, the kernel feils to find the bootconfig data. | |
| 157 | +loader passes a longer size, the kernel fails to find the bootconfig data. | |
| 158 | 158 | |
| 159 | 159 | To do this operation, Linux kernel provides "bootconfig" command under |
| 160 | 160 | tools/bootconfig, which allows admin to apply or delete the config file |
| @@ -1029,7 +1029,7 @@ All time durations are in microseconds. · 1028 unmodified lines | ||
| 1029 | 1029 | one number is written, $MAX is updated. |
| 1030 | 1030 | |
| 1031 | 1031 | cpu.pressure |
| 1032 | − A read-only nested-key file which exists on non-root cgroups. | |
| 1032 | + A read-write nested-keyed file. | |
| 1033 | 1033 | |
| 1034 | 1034 | Shows pressure stall information for CPU. See |
| 1035 | 1035 | :ref:`Documentation/accounting/psi.rst <psi>` for details. |
| @@ -1475,7 +1475,7 @@ PAGE_SIZE multiple when read back. · 439 unmodified lines | ||
| 1475 | 1475 | reduces the impact on the workload and memory management. |
| 1476 | 1476 | |
| 1477 | 1477 | memory.pressure |
| 1478 | − A read-only nested-key file which exists on non-root cgroups. | |
| 1478 | + A read-only nested-keyed file. | |
| 1479 | 1479 | |
| 1480 | 1480 | Shows pressure stall information for memory. See |
| 1481 | 1481 | :ref:`Documentation/accounting/psi.rst <psi>` for details. |
| @@ -1714,7 +1714,7 @@ IO Interface Files · 232 unmodified lines | ||
| 1714 | 1714 | 8:16 rbps=2097152 wbps=max riops=max wiops=max |
| 1715 | 1715 | |
| 1716 | 1716 | io.pressure |
| 1717 | − A read-only nested-key file which exists on non-root cgroups. | |
| 1717 | + A read-only nested-keyed file. | |
| 1718 | 1718 | |
| 1719 | 1719 | Shows pressure stall information for IO. See |
| 1720 | 1720 | :ref:`Documentation/accounting/psi.rst <psi>` for details. |
| @@ -177,14 +177,20 @@ bitmap_flush_interval:number · 176 unmodified lines | ||
| 177 | 177 | The bitmap flush interval in milliseconds. The metadata buffers |
| 178 | 178 | are synchronized when this interval expires. |
| 179 | 179 | |
| 180 | +allow_discards | |
| 181 | + Allow block discard requests (a.k.a. TRIM) for the integrity device. | |
| 182 | + Discards are only allowed to devices using internal hash. | |
| 183 | + | |
| 180 | 184 | fix_padding |
| 181 | 185 | Use a smaller padding of the tag area that is more |
| 182 | 186 | space-efficient. If this option is not present, large padding is |
| 183 | 187 | used - that is for compatibility with older kernels. |
| 184 | 188 | |
| 185 | −allow_discards | |
| 186 | − Allow block discard requests (a.k.a. TRIM) for the integrity device. | |
| 187 | − Discards are only allowed to devices using internal hash. | |
| 189 | +legacy_recalculate | |
| 190 | + Allow recalculating of volumes with HMAC keys. This is disabled by | |
| 191 | + default for security reasons - an attacker could modify the volume, | |
| 192 | + set recalc_sector to zero, and the kernel would not detect the | |
| 193 | + modification. | |
| 188 | 194 | |
| 189 | 195 | The journal mode (D/J), buffer_sectors, journal_watermark, commit_time and |
| 190 | 196 | allow_discards can be changed when reloading the target (load an inactive |
| @@ -3,8 +3,8 @@ · 2 unmodified lines | ||
| 3 | 3 | The kernel's command-line parameters |
| 4 | 4 | ==================================== |
| 5 | 5 | |
| 6 | −The following is a consolidated list of the kernel parameters as | |
| 7 | −implemented by the __setup(), core_param() and module_param() macros | |
| 6 | +The following is a consolidated list of the kernel parameters as implemented | |
| 7 | +by the __setup(), early_param(), core_param() and module_param() macros | |
| 8 | 8 | and sorted into English Dictionary order (defined as ignoring all |
| 9 | 9 | punctuation and sorting digits before letters in a case insensitive |
| 10 | 10 | manner), and with descriptions where known. |
| @@ -1385,7 +1385,7 @@ · 1384 unmodified lines | ||
| 1385 | 1385 | |
| 1386 | 1386 | ftrace_filter=[function-list] |
| 1387 | 1387 | [FTRACE] Limit the functions traced by the function |
| 1388 | − tracer at boot up. function-list is a comma separated | |
| 1388 | + tracer at boot up. function-list is a comma-separated | |
| 1389 | 1389 | list of functions. This list can be changed at run |
| 1390 | 1390 | time by the set_ftrace_filter file in the debugfs |
| 1391 | 1391 | tracing directory. |
| @@ -1399,13 +1399,13 @@ · 7 unmodified lines | ||
| 1399 | 1399 | ftrace_graph_filter=[function-list] |
| 1400 | 1400 | [FTRACE] Limit the top level callers functions traced |
| 1401 | 1401 | by the function graph tracer at boot up. |
| 1402 | − function-list is a comma separated list of functions | |
| 1402 | + function-list is a comma-separated list of functions | |
| 1403 | 1403 | that can be changed at run time by the |
| 1404 | 1404 | set_graph_function file in the debugfs tracing directory. |
| 1405 | 1405 | |
| 1406 | 1406 | ftrace_graph_notrace=[function-list] |
| 1407 | 1407 | [FTRACE] Do not trace from the functions specified in |
| 1408 | − function-list. This list is a comma separated list of | |
| 1408 | + function-list. This list is a comma-separated list of | |
| 1409 | 1409 | functions that can be changed at run time by the |
| 1410 | 1410 | set_graph_notrace file in the debugfs tracing directory. |
| 1411 | 1411 | |
| @@ -2421,7 +2421,7 @@ · 1009 unmodified lines | ||
| 2421 | 2421 | when set. |
| 2422 | 2422 | Format: <int> |
| 2423 | 2423 | |
| 2424 | − libata.force= [LIBATA] Force configurations. The format is comma | |
| 2424 | + libata.force= [LIBATA] Force configurations. The format is comma- | |
| 2425 | 2425 | separated list of "[ID:]VAL" where ID is |
| 2426 | 2426 | PORT[.DEVICE]. PORT and DEVICE are decimal numbers |
| 2427 | 2427 | matching port, link or device. Basically, it matches |
| @@ -5145,7 +5145,7 @@ · 2717 unmodified lines | ||
| 5145 | 5145 | |
| 5146 | 5146 | stacktrace_filter=[function-list] |
| 5147 | 5147 | [FTRACE] Limit the functions that the stack tracer |
| 5148 | − will trace at boot up. function-list is a comma separated | |
| 5148 | + will trace at boot up. function-list is a comma-separated | |
| 5149 | 5149 | list of functions. This list can be changed at run |
| 5150 | 5150 | time by the stack_trace_filter file in the debugfs |
| 5151 | 5151 | tracing directory. Note, this enables stack tracing |
| @@ -5348,7 +5348,7 @@ · 196 unmodified lines | ||
| 5348 | 5348 | trace_event=[event-list] |
| 5349 | 5349 | [FTRACE] Set and start specified trace events in order |
| 5350 | 5350 | to facilitate early boot debugging. The event-list is a |
| 5351 | − comma separated list of trace events to enable. See | |
| 5351 | + comma-separated list of trace events to enable. See | |
| 5352 | 5352 | also Documentation/trace/events.rst |
| 5353 | 5353 | |
| 5354 | 5354 | trace_options=[option-list] |
| @@ -5972,6 +5972,10 @@ · 617 unmodified lines | ||
| 5972 | 5972 | This option is obsoleted by the "nopv" option, which |
| 5973 | 5973 | has equivalent effect for XEN platform. |
| 5974 | 5974 | |
| 5975 | + xen_no_vector_callback | |
| 5976 | + [KNL,X86,XEN] Disable the vector callback for Xen | |
| 5977 | + event channel interrupts. | |
| 5978 | + | |
| 5975 | 5979 | xen_scrub_pages= [XEN] |
| 5976 | 5980 | Boolean option to control scrubbing pages before giving them back |
| 5977 | 5981 | to Xen, for use by other domains. Can be also changed at runtime |
| @@ -13,6 +13,22 @@ This file documents the driver for the Rockchip ISP1 that is part of RK3288 · 12 unmodified lines | ||
| 13 | 13 | and RK3399 SoCs. The driver is located under drivers/staging/media/rkisp1 |
| 14 | 14 | and uses the Media-Controller API. |
| 15 | 15 | |
| 16 | +Revisions | |
| 17 | +========= | |
| 18 | + | |
| 19 | +There exist multiple smaller revisions to this ISP that got introduced in | |
| 20 | +later SoCs. Revisions can be found in the enum :c:type:`rkisp1_cif_isp_version` | |
| 21 | +in the UAPI and the revision of the ISP inside the running SoC can be read | |
| 22 | +in the field hw_revision of struct media_device_info as returned by | |
| 23 | +ioctl MEDIA_IOC_DEVICE_INFO. | |
| 24 | + | |
| 25 | +Versions in use are: | |
| 26 | + | |
| 27 | +- RKISP1_V10: used at least in rk3288 and rk3399 | |
| 28 | +- RKISP1_V11: declared in the original vendor code, but not used | |
| 29 | +- RKISP1_V12: used at least in rk3326 and px30 | |
| 30 | +- RKISP1_V13: used at least in rk1808 | |
| 31 | + | |
| 16 | 32 | Topology |
| 17 | 33 | ======== |
| 18 | 34 | .. _rkisp1_topology_graph: |
| @@ -184,7 +184,7 @@ pages either asynchronously or synchronously, depending on the state · 183 unmodified lines | ||
| 184 | 184 | of the system. When the system is not loaded, most of the memory is free |
| 185 | 185 | and allocation requests will be satisfied immediately from the free |
| 186 | 186 | pages supply. As the load increases, the amount of the free pages goes |
| 187 | −down and when it reaches a certain threshold (high watermark), an | |
| 187 | +down and when it reaches a certain threshold (low watermark), an | |
| 188 | 188 | allocation request will awaken the ``kswapd`` daemon. It will |
| 189 | 189 | asynchronously scan memory pages and either just free them if the data |
| 190 | 190 | they contain is available elsewhere, or evict to the backing storage |
| @@ -70,8 +70,8 @@ trampoline code on the vDSO, that trampoline is never intercepted. · 69 unmodified lines | ||
| 70 | 70 | [selector] is a pointer to a char-sized region in the process memory |
| 71 | 71 | region, that provides a quick way to enable disable syscall redirection |
| 72 | 72 | thread-wide, without the need to invoke the kernel directly. selector |
| 73 | −can be set to PR_SYS_DISPATCH_ON or PR_SYS_DISPATCH_OFF. Any other | |
| 74 | −value should terminate the program with a SIGSYS. | |
| 73 | +can be set to SYSCALL_DISPATCH_FILTER_ALLOW or SYSCALL_DISPATCH_FILTER_BLOCK. | |
| 74 | +Any other value should terminate the program with a SIGSYS. | |
| 75 | 75 | |
| 76 | 76 | Security Notes |
| 77 | 77 | -------------- |
| @@ -100,6 +100,11 @@ Instruction Macros · 99 unmodified lines | ||
| 100 | 100 | ~~~~~~~~~~~~~~~~~~ |
| 101 | 101 | This section covers ``SYM_FUNC_*`` and ``SYM_CODE_*`` enumerated above. |
| 102 | 102 | |
| 103 | +``objtool`` requires that all code must be contained in an ELF symbol. Symbol | |
| 104 | +names that have a ``.L`` prefix do not emit symbol table entries. ``.L`` | |
| 105 | +prefixed symbols can be used within a code region, but should be avoided for | |
| 106 | +denoting a range of code via ``SYM_*_START/END`` annotations. | |
| 107 | + | |
| 103 | 108 | * ``SYM_FUNC_START`` and ``SYM_FUNC_START_LOCAL`` are supposed to be **the |
| 104 | 109 | most frequent markings**. They are used for functions with standard calling |
| 105 | 110 | conventions -- global and local. Like in C, they both align the functions to |
| @@ -53,7 +53,6 @@ How Linux keeps everything from happening at the same time. See · 52 unmodified lines | ||
| 53 | 53 | .. toctree:: |
| 54 | 54 | :maxdepth: 1 |
| 55 | 55 | |
| 56 | − atomic_ops | |
| 57 | 56 | refcount-vs-atomic |
| 58 | 57 | irq/index |
| 59 | 58 | local_ops |
| @@ -160,29 +160,13 @@ intended for use in production as a security mitigation. Therefore it supports · 159 unmodified lines | ||
| 160 | 160 | boot parameters that allow to disable KASAN competely or otherwise control |
| 161 | 161 | particular KASAN features. |
| 162 | 162 | |
| 163 | −The things that can be controlled are: | |
| 163 | +- ``kasan=off`` or ``=on`` controls whether KASAN is enabled (default: ``on``). | |
| 164 | 164 | |
| 165 | −1. Whether KASAN is enabled at all. | |
| 166 | −2. Whether KASAN collects and saves alloc/free stacks. | |
| 167 | −3. Whether KASAN panics on a detected bug or not. | |
| 165 | +- ``kasan.stacktrace=off`` or ``=on`` disables or enables alloc and free stack | |
| 166 | + traces collection (default: ``on``). | |
| 168 | 167 | |
| 169 | −The ``kasan.mode`` boot parameter allows to choose one of three main modes: | |
| 170 | − | |
| 171 | −- ``kasan.mode=off`` - KASAN is disabled, no tag checks are performed | |
| 172 | −- ``kasan.mode=prod`` - only essential production features are enabled | |
| 173 | −- ``kasan.mode=full`` - all KASAN features are enabled | |
| 174 | − | |
| 175 | −The chosen mode provides default control values for the features mentioned | |
| 176 | −above. However it's also possible to override the default values by providing: | |
| 177 | − | |
| 178 | −- ``kasan.stacktrace=off`` or ``=on`` - enable alloc/free stack collection | |
| 179 | − (default: ``on`` for ``mode=full``, | |
| 180 | − otherwise ``off``) | |
| 181 | −- ``kasan.fault=report`` or ``=panic`` - only print KASAN report or also panic | |
| 182 | − (default: ``report``) | |
| 183 | − | |
| 184 | −If ``kasan.mode`` parameter is not provided, it defaults to ``full`` when | |
| 185 | −``CONFIG_DEBUG_KERNEL`` is enabled, and to ``prod`` otherwise. | |
| 168 | +- ``kasan.fault=report`` or ``=panic`` controls whether to only print a KASAN | |
| 169 | + report or also panic the kernel (default: ``report``). | |
| 186 | 170 | |
| 187 | 171 | For developers |
| 188 | 172 | ~~~~~~~~~~~~~~ |
| @@ -522,6 +522,63 @@ There's more boilerplate involved, but it can: · 521 unmodified lines | ||
| 522 | 522 | * E.g. if we wanted to also test ``sha256sum``, we could add a ``sha256`` |
| 523 | 523 | field and reuse ``cases``. |
| 524 | 524 | |
| 525 | +* be converted to a "parameterized test", see below. | |
| 526 | + | |
| 527 | +Parameterized Testing | |
| 528 | +~~~~~~~~~~~~~~~~~~~~~ | |
| 529 | + | |
| 530 | +The table-driven testing pattern is common enough that KUnit has special | |
| 531 | +support for it. | |
| 532 | + | |
| 533 | +Reusing the same ``cases`` array from above, we can write the test as a | |
| 534 | +"parameterized test" with the following. | |
| 535 | + | |
| 536 | +.. code-block:: c | |
| 537 | + | |
| 538 | + // This is copy-pasted from above. | |
| 539 | + struct sha1_test_case { | |
| 540 | + const char *str; | |
| 541 | + const char *sha1; | |
| 542 | + }; | |
| 543 | + struct sha1_test_case cases[] = { | |
| 544 | + { | |
| 545 | + .str = "hello world", | |
| 546 | + .sha1 = "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed", | |
| 547 | + }, | |
| 548 | + { | |
| 549 | + .str = "hello world!", | |
| 550 | + .sha1 = "430ce34d020724ed75a196dfc2ad67c77772d169", | |
| 551 | + }, | |
| 552 | + }; | |
| 553 | + | |
| 554 | + // Need a helper function to generate a name for each test case. | |
| 555 | + static void case_to_desc(const struct sha1_test_case *t, char *desc) | |
| 556 | + { | |
| 557 | + strcpy(desc, t->str); | |
| 558 | + } | |
| 559 | + // Creates `sha1_gen_params()` to iterate over `cases`. | |
| 560 | + KUNIT_ARRAY_PARAM(sha1, cases, case_to_desc); | |
| 561 | + | |
| 562 | + // Looks no different from a normal test. | |
| 563 | + static void sha1_test(struct kunit *test) | |
| 564 | + { | |
| 565 | + // This function can just contain the body of the for-loop. | |
| 566 | + // The former `cases[i]` is accessible under test->param_value. | |
| 567 | + char out[40]; | |
| 568 | + struct sha1_test_case *test_param = (struct sha1_test_case *)(test->param_value); | |
| 569 | + | |
| 570 | + sha1sum(test_param->str, out); | |
| 571 | + KUNIT_EXPECT_STREQ_MSG(test, (char *)out, test_param->sha1, | |
| 572 | + "sha1sum(%s)", test_param->str); | |
| 573 | + } | |
| 574 | + | |
| 575 | + // Instead of KUNIT_CASE, we use KUNIT_CASE_PARAM and pass in the | |
| 576 | + // function declared by KUNIT_ARRAY_PARAM. | |
| 577 | + static struct kunit_case sha1_test_cases[] = { | |
| 578 | + KUNIT_CASE_PARAM(sha1_test, sha1_gen_params), | |
| 579 | + {} | |
| 580 | + }; | |
| 581 | + | |
| 525 | 582 | .. _kunit-on-non-uml: |
| 526 | 583 | |
| 527 | 584 | KUnit on non-UML architectures |
| @@ -232,7 +232,6 @@ properties: · 231 unmodified lines | ||
| 232 | 232 | by this cpu (see ./idle-states.yaml). |
| 233 | 233 | |
| 234 | 234 | capacity-dmips-mhz: |
| 235 | − $ref: '/schemas/types.yaml#/definitions/uint32' | |
| 236 | 235 | description: |
| 237 | 236 | u32 value representing CPU capacity (see ./cpu-capacity.txt) in |
| 238 | 237 | DMIPS/MHz, relative to highest capacity-dmips-mhz |
| @@ -40,7 +40,7 @@ Optional properties: · 39 unmodified lines | ||
| 40 | 40 | documents on how to describe the way the sii902x device is |
| 41 | 41 | connected to the rest of the audio system: |
| 42 | 42 | Documentation/devicetree/bindings/sound/simple-card.yaml |
| 43 | − Documentation/devicetree/bindings/sound/audio-graph-card.txt | |
| 43 | + Documentation/devicetree/bindings/sound/audio-graph-card.yaml | |
| 44 | 44 | Note: In case of the audio-graph-card binding the used port |
| 45 | 45 | index should be 3. |
| 46 | 46 | |
| @@ -23,7 +23,7 @@ connected to. · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | For a description of the display interface sink function blocks, see |
| 25 | 25 | Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt and |
| 26 | −Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt. | |
| 26 | +Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml. | |
| 27 | 27 | |
| 28 | 28 | Required properties (all function blocks): |
| 29 | 29 | - compatible: "mediatek,<chip>-disp-<function>", one of |
| @@ -61,7 +61,7 @@ Required properties (DMA function blocks): · 31 unmodified lines | ||
| 61 | 61 | "mediatek,<chip>-disp-wdma" |
| 62 | 62 | the supported chips are mt2701, mt8167 and mt8173. |
| 63 | 63 | - larb: Should contain a phandle pointing to the local arbiter device as defined |
| 64 | − in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt | |
| 64 | + in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml | |
| 65 | 65 | - iommus: Should point to the respective IOMMU block with master port as |
| 66 | 66 | argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt |
| 67 | 67 | for details. |
| @@ -1,4 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | +# Copyright (C) 2020 Texas Instruments Incorporated | |
| 3 | +# Author: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 2 | 4 | %YAML 1.2 |
| 3 | 5 | --- |
| 4 | 6 | $id: http://devicetree.org/schemas/dma/ti/k3-bcdma.yaml# |
| @@ -7,7 +9,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 2 unmodified lines | ||
| 7 | 9 | title: Texas Instruments K3 DMSS BCDMA Device Tree Bindings |
| 8 | 10 | |
| 9 | 11 | maintainers: |
| 10 | − - Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 12 | + - Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 11 | 13 | |
| 12 | 14 | description: | |
| 13 | 15 | The Block Copy DMA (BCDMA) is intended to perform similar functions as the TR |
| @@ -1,4 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | +# Copyright (C) 2020 Texas Instruments Incorporated | |
| 3 | +# Author: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 2 | 4 | %YAML 1.2 |
| 3 | 5 | --- |
| 4 | 6 | $id: http://devicetree.org/schemas/dma/ti/k3-pktdma.yaml# |
| @@ -7,7 +9,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 2 unmodified lines | ||
| 7 | 9 | title: Texas Instruments K3 DMSS PKTDMA Device Tree Bindings |
| 8 | 10 | |
| 9 | 11 | maintainers: |
| 10 | − - Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 12 | + - Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 11 | 13 | |
| 12 | 14 | description: | |
| 13 | 15 | The Packet DMA (PKTDMA) is intended to perform similar functions as the packet |
| @@ -1,4 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | +# Copyright (C) 2019 Texas Instruments Incorporated | |
| 3 | +# Author: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 2 | 4 | %YAML 1.2 |
| 3 | 5 | --- |
| 4 | 6 | $id: http://devicetree.org/schemas/dma/ti/k3-udma.yaml# |
| @@ -7,7 +9,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 2 unmodified lines | ||
| 7 | 9 | title: Texas Instruments K3 NAVSS Unified DMA Device Tree Bindings |
| 8 | 10 | |
| 9 | 11 | maintainers: |
| 10 | − - Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 12 | + - Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 11 | 13 | |
| 12 | 14 | description: | |
| 13 | 15 | The UDMA-P is intended to perform similar (but significantly upgraded) |
| @@ -85,7 +85,6 @@ properties: · 84 unmodified lines | ||
| 85 | 85 | wlf,micd-timeout-ms: |
| 86 | 86 | description: |
| 87 | 87 | Timeout for microphone detection, specified in milliseconds. |
| 88 | − $ref: "/schemas/types.yaml#/definitions/uint32" | |
| 89 | 88 | |
| 90 | 89 | wlf,micd-force-micbias: |
| 91 | 90 | description: |
| @@ -49,7 +49,6 @@ properties: · 48 unmodified lines | ||
| 49 | 49 | description: |
| 50 | 50 | This property controls the Accumulation Dead band which allows to set the |
| 51 | 51 | level of current below which no accumulation takes place. |
| 52 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 53 | 52 | maximum: 255 |
| 54 | 53 | default: 0 |
| 55 | 54 | |
| @@ -73,11 +73,9 @@ properties: · 72 unmodified lines | ||
| 73 | 73 | description: | |
| 74 | 74 | Temperature sensor trimming factor. It can be used to manually adjust the |
| 75 | 75 | temperature measurements within 7.130 degrees Celsius. |
| 76 | − maxItems: 1 | |
| 77 | − items: | |
| 78 | − default: 0 | |
| 79 | − minimum: 0 | |
| 80 | − maximum: 7130 | |
| 76 | + default: 0 | |
| 77 | + minimum: 0 | |
| 78 | + maximum: 7130 | |
| 81 | 79 | |
| 82 | 80 | additionalProperties: false |
| 83 | 81 | |
| @@ -52,7 +52,6 @@ properties: · 51 unmodified lines | ||
| 52 | 52 | ti,bus-range-microvolt: |
| 53 | 53 | description: | |
| 54 | 54 | This is the operating range of the bus voltage in microvolt |
| 55 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 56 | 55 | enum: [16000000, 32000000] |
| 57 | 56 | default: 32000000 |
| 58 | 57 | |
| @@ -39,11 +39,9 @@ properties: · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | i2c-gpio,delay-us: |
| 41 | 41 | description: delay between GPIO operations (may depend on each platform) |
| 42 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 43 | 42 | |
| 44 | 43 | i2c-gpio,timeout-ms: |
| 45 | 44 | description: timeout to get data |
| 46 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 47 | 45 | |
| 48 | 46 | # Deprecated properties, do not use in new device tree sources: |
| 49 | 47 | gpios: |
| @@ -66,21 +66,18 @@ properties: · 65 unmodified lines | ||
| 66 | 66 | default: 400000 |
| 67 | 67 | |
| 68 | 68 | i2c-sda-hold-time-ns: |
| 69 | − maxItems: 1 | |
| 70 | 69 | description: | |
| 71 | 70 | The property should contain the SDA hold time in nanoseconds. This option |
| 72 | 71 | is only supported in hardware blocks version 1.11a or newer or on |
| 73 | 72 | Microsemi SoCs. |
| 74 | 73 | |
| 75 | 74 | i2c-scl-falling-time-ns: |
| 76 | − maxItems: 1 | |
| 77 | 75 | description: | |
| 78 | 76 | The property should contain the SCL falling time in nanoseconds. |
| 79 | 77 | This value is used to compute the tLOW period. |
| 80 | 78 | default: 300 |
| 81 | 79 | |
| 82 | 80 | i2c-sda-falling-time-ns: |
| 83 | − maxItems: 1 | |
| 84 | 81 | description: | |
| 85 | 82 | The property should contain the SDA falling time in nanoseconds. |
| 86 | 83 | This value is used to compute the tHIGH period. |
| @@ -16,8 +16,8 @@ description: · 15 unmodified lines | ||
| 16 | 16 | properties: |
| 17 | 17 | compatible: |
| 18 | 18 | enum: |
| 19 | − - bosch,bmc150 | |
| 20 | − - bosch,bmi055 | |
| 19 | + - bosch,bmc150_accel | |
| 20 | + - bosch,bmi055_accel | |
| 21 | 21 | - bosch,bma255 |
| 22 | 22 | - bosch,bma250e |
| 23 | 23 | - bosch,bma222 |
| @@ -80,7 +80,7 @@ properties: · 79 unmodified lines | ||
| 80 | 80 | type: boolean |
| 81 | 81 | |
| 82 | 82 | bipolar: |
| 83 | − description: see Documentation/devicetree/bindings/iio/adc/adc.txt | |
| 83 | + description: see Documentation/devicetree/bindings/iio/adc/adc.yaml | |
| 84 | 84 | type: boolean |
| 85 | 85 | |
| 86 | 86 | required: |
| @@ -23,7 +23,6 @@ properties: · 22 unmodified lines | ||
| 23 | 23 | maxItems: 1 |
| 24 | 24 | |
| 25 | 25 | shunt-resistor-micro-ohms: |
| 26 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 27 | 26 | description: | |
| 28 | 27 | Value in micro Ohms of the shunt resistor connected between the RS+ and |
| 29 | 28 | RS- inputs, across which the current is measured. Value needed to compute |
| @@ -246,7 +246,6 @@ patternProperties: · 245 unmodified lines | ||
| 246 | 246 | Resolution (bits) to use for conversions: |
| 247 | 247 | - can be 6, 8, 10 or 12 on stm32f4 |
| 248 | 248 | - can be 8, 10, 12, 14 or 16 on stm32h7 and stm32mp1 |
| 249 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 250 | 249 | |
| 251 | 250 | st,adc-channels: |
| 252 | 251 | description: | |
| @@ -42,7 +42,6 @@ properties: · 41 unmodified lines | ||
| 42 | 42 | const: 1 |
| 43 | 43 | |
| 44 | 44 | ti,channel0-current-microamp: |
| 45 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 46 | 45 | description: Channel 0 current in uA. |
| 47 | 46 | enum: |
| 48 | 47 | - 0 |
| @@ -51,7 +50,6 @@ properties: · 2 unmodified lines | ||
| 51 | 50 | - 20 |
| 52 | 51 | |
| 53 | 52 | ti,channel3-current-microamp: |
| 54 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 55 | 53 | description: Channel 3 current in uA. |
| 56 | 54 | enum: |
| 57 | 55 | - 0 |
| @@ -46,31 +46,42 @@ properties: · 45 unmodified lines | ||
| 46 | 46 | two properties must be present: |
| 47 | 47 | |
| 48 | 48 | adi,range-microvolt: |
| 49 | − $ref: /schemas/types.yaml#/definitions/int32-array | |
| 50 | 49 | description: | |
| 51 | 50 | Voltage output range specified as <minimum, maximum> |
| 52 | − enum: | |
| 53 | − - [[0, 5000000]] | |
| 54 | − - [[0, 10000000]] | |
| 55 | − - [[-5000000, 5000000]] | |
| 56 | − - [[-10000000, 10000000]] | |
| 51 | + oneOf: | |
| 52 | + - items: | |
| 53 | + - const: 0 | |
| 54 | + - enum: [5000000, 10000000] | |
| 55 | + - items: | |
| 56 | + - const: -5000000 | |
| 57 | + - const: 5000000 | |
| 58 | + - items: | |
| 59 | + - const: -10000000 | |
| 60 | + - const: 10000000 | |
| 57 | 61 | |
| 58 | 62 | adi,range-microamp: |
| 59 | − $ref: /schemas/types.yaml#/definitions/int32-array | |
| 60 | 63 | description: | |
| 61 | 64 | Current output range specified as <minimum, maximum> |
| 62 | − enum: | |
| 63 | − - [[0, 20000]] | |
| 64 | − - [[0, 24000]] | |
| 65 | − - [[4, 24000]] | |
| 66 | − - [[-20000, 20000]] | |
| 67 | − - [[-24000, 24000]] | |
| 68 | − - [[-1000, 22000]] | |
| 65 | + oneOf: | |
| 66 | + - items: | |
| 67 | + - const: 0 | |
| 68 | + - enum: [20000, 24000] | |
| 69 | + - items: | |
| 70 | + - const: 4 | |
| 71 | + - const: 24000 | |
| 72 | + - items: | |
| 73 | + - const: -20000 | |
| 74 | + - const: 20000 | |
| 75 | + - items: | |
| 76 | + - const: -24000 | |
| 77 | + - const: 24000 | |
| 78 | + - items: | |
| 79 | + - const: -1000 | |
| 80 | + - const: 22000 | |
| 69 | 81 | |
| 70 | 82 | reset-gpios: true |
| 71 | 83 | |
| 72 | 84 | adi,dc-dc-ilim-microamp: |
| 73 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 74 | 85 | enum: [150000, 200000, 250000, 300000, 350000, 400000] |
| 75 | 86 | description: | |
| 76 | 87 | The dc-to-dc converter current limit. |
| @@ -21,7 +21,6 @@ properties: · 20 unmodified lines | ||
| 21 | 21 | description: Connected to ADC_RDY pin. |
| 22 | 22 | |
| 23 | 23 | maxim,led-current-microamp: |
| 24 | − $ref: /schemas/types.yaml#/definitions/uint32-array | |
| 25 | 24 | minItems: 2 |
| 26 | 25 | maxItems: 2 |
| 27 | 26 | description: | |
| @@ -5,7 +5,8 @@ Required properties: · 4 unmodified lines | ||
| 5 | 5 | - compatible: "adc-keys" |
| 6 | 6 | - io-channels: Phandle to an ADC channel |
| 7 | 7 | - io-channel-names = "buttons"; |
| 8 | − - keyup-threshold-microvolt: Voltage at which all the keys are considered up. | |
| 8 | + - keyup-threshold-microvolt: Voltage above or equal to which all the keys are | |
| 9 | + considered up. | |
| 9 | 10 | |
| 10 | 11 | Optional properties: |
| 11 | 12 | - poll-interval: Poll interval time in milliseconds |
| @@ -17,7 +18,12 @@ Each button (key) is represented as a sub-node of "adc-keys": · 5 unmodified lines | ||
| 17 | 18 | Required subnode-properties: |
| 18 | 19 | - label: Descriptive name of the key. |
| 19 | 20 | - linux,code: Keycode to emit. |
| 20 | − - press-threshold-microvolt: Voltage ADC input when this key is pressed. | |
| 21 | + - press-threshold-microvolt: voltage above or equal to which this key is | |
| 22 | + considered pressed. | |
| 23 | + | |
| 24 | +No two values of press-threshold-microvolt may be the same. | |
| 25 | +All values of press-threshold-microvolt must be less than | |
| 26 | +keyup-threshold-microvolt. | |
| 21 | 27 | |
| 22 | 28 | Example: |
| 23 | 29 | |
| @@ -47,3 +53,15 @@ Example: · 23 unmodified lines | ||
| 47 | 53 | press-threshold-microvolt = <500000>; |
| 48 | 54 | }; |
| 49 | 55 | }; |
| 56 | + | |
| 57 | ++--------------------------------+------------------------+ | |
| 58 | +| 2.000.000 <= value | no key pressed | | |
| 59 | ++--------------------------------+------------------------+ | |
| 60 | +| 1.500.000 <= value < 2.000.000 | KEY_VOLUMEUP pressed | | |
| 61 | ++--------------------------------+------------------------+ | |
| 62 | +| 1.000.000 <= value < 1.500.000 | KEY_VOLUMEDOWN pressed | | |
| 63 | ++--------------------------------+------------------------+ | |
| 64 | +| 500.000 <= value < 1.000.000 | KEY_ENTER pressed | | |
| 65 | ++--------------------------------+------------------------+ | |
| 66 | +| value < 500.000 | no key pressed | | |
| 67 | ++--------------------------------+------------------------+ | |
| @@ -26,6 +26,7 @@ properties: · 25 unmodified lines | ||
| 26 | 26 | - goodix,gt927 |
| 27 | 27 | - goodix,gt9271 |
| 28 | 28 | - goodix,gt928 |
| 29 | + - goodix,gt9286 | |
| 29 | 30 | - goodix,gt967 |
| 30 | 31 | |
| 31 | 32 | reg: |
| @@ -70,11 +70,9 @@ properties: · 69 unmodified lines | ||
| 70 | 70 | |
| 71 | 71 | touchscreen-x-mm: |
| 72 | 72 | description: horizontal length in mm of the touchscreen |
| 73 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 74 | 73 | |
| 75 | 74 | touchscreen-y-mm: |
| 76 | 75 | description: vertical length in mm of the touchscreen |
| 77 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 78 | 76 | |
| 79 | 77 | dependencies: |
| 80 | 78 | touchscreen-size-x: [ touchscreen-size-y ] |
| @@ -0,0 +1,111 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/leds/richtek,rt8515.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Richtek RT8515 1.5A dual channel LED driver | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Linus Walleij <linus.walleij@linaro.org> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + The Richtek RT8515 is a dual channel (two mode) LED driver that | |
| 14 | + supports driving a white LED in flash or torch mode. The maximum | |
| 15 | + current for each mode is defined in hardware using two resistors | |
| 16 | + RFS and RTS. | |
| 17 | + | |
| 18 | +properties: | |
| 19 | + compatible: | |
| 20 | + const: richtek,rt8515 | |
| 21 | + | |
| 22 | + enf-gpios: | |
| 23 | + maxItems: 1 | |
| 24 | + description: A connection to the 'ENF' (enable flash) pin. | |
| 25 | + | |
| 26 | + ent-gpios: | |
| 27 | + maxItems: 1 | |
| 28 | + description: A connection to the 'ENT' (enable torch) pin. | |
| 29 | + | |
| 30 | + richtek,rfs-ohms: | |
| 31 | + minimum: 7680 | |
| 32 | + maximum: 367000 | |
| 33 | + description: The resistance value of the RFS resistor. This | |
| 34 | + resistors limits the maximum flash current. This must be set | |
| 35 | + for the property flash-max-microamp to work, the RFS resistor | |
| 36 | + defines the range of the dimmer setting (brightness) of the | |
| 37 | + flash LED. | |
| 38 | + | |
| 39 | + richtek,rts-ohms: | |
| 40 | + minimum: 7680 | |
| 41 | + maximum: 367000 | |
| 42 | + description: The resistance value of the RTS resistor. This | |
| 43 | + resistors limits the maximum torch current. This must be set | |
| 44 | + for the property torch-max-microamp to work, the RTS resistor | |
| 45 | + defines the range of the dimmer setting (brightness) of the | |
| 46 | + torch LED. | |
| 47 | + | |
| 48 | + led: | |
| 49 | + type: object | |
| 50 | + $ref: common.yaml# | |
| 51 | + properties: | |
| 52 | + function: true | |
| 53 | + color: true | |
| 54 | + flash-max-timeout-us: true | |
| 55 | + | |
| 56 | + flash-max-microamp: | |
| 57 | + maximum: 700000 | |
| 58 | + description: The maximum current for flash mode | |
| 59 | + is hardwired to the component using the RFS resistor to | |
| 60 | + ground. The maximum hardware current setting is calculated | |
| 61 | + according to the formula Imax = 5500 / RFS. The lowest | |
| 62 | + allowed resistance value is 7.86 kOhm giving an absolute | |
| 63 | + maximum current of 700mA. By setting this attribute in | |
| 64 | + the device tree, you can further restrict the maximum | |
| 65 | + current below the hardware limit. This requires the RFS | |
| 66 | + to be defined as it defines the maximum range. | |
| 67 | + | |
| 68 | + led-max-microamp: | |
| 69 | + maximum: 700000 | |
| 70 | + description: The maximum current for torch mode | |
| 71 | + is hardwired to the component using the RTS resistor to | |
| 72 | + ground. The maximum hardware current setting is calculated | |
| 73 | + according to the formula Imax = 5500 / RTS. The lowest | |
| 74 | + allowed resistance value is 7.86 kOhm giving an absolute | |
| 75 | + maximum current of 700mA. By setting this attribute in | |
| 76 | + the device tree, you can further restrict the maximum | |
| 77 | + current below the hardware limit. This requires the RTS | |
| 78 | + to be defined as it defines the maximum range. | |
| 79 | + | |
| 80 | + additionalProperties: false | |
| 81 | + | |
| 82 | +required: | |
| 83 | + - compatible | |
| 84 | + - ent-gpios | |
| 85 | + - enf-gpios | |
| 86 | + - led | |
| 87 | + | |
| 88 | +additionalProperties: false | |
| 89 | + | |
| 90 | +examples: | |
| 91 | + - | | |
| 92 | + #include <dt-bindings/gpio/gpio.h> | |
| 93 | + #include <dt-bindings/leds/common.h> | |
| 94 | + | |
| 95 | + led-controller { | |
| 96 | + compatible = "richtek,rt8515"; | |
| 97 | + enf-gpios = <&gpio4 12 GPIO_ACTIVE_HIGH>; | |
| 98 | + ent-gpios = <&gpio4 13 GPIO_ACTIVE_HIGH>; | |
| 99 | + richtek,rfs-ohms = <16000>; | |
| 100 | + richtek,rts-ohms = <100000>; | |
| 101 | + | |
| 102 | + led { | |
| 103 | + function = LED_FUNCTION_FLASH; | |
| 104 | + color = <LED_COLOR_ID_WHITE>; | |
| 105 | + flash-max-timeout-us = <250000>; | |
| 106 | + flash-max-microamp = <150000>; | |
| 107 | + led-max-microamp = <25000>; | |
| 108 | + }; | |
| 109 | + }; | |
| 110 | + | |
| 111 | +... | |
| @@ -16,7 +16,7 @@ Required properties: · 15 unmodified lines | ||
| 16 | 16 | - power-domains: a phandle to the power domain, see |
| 17 | 17 | Documentation/devicetree/bindings/power/power_domain.txt for details. |
| 18 | 18 | - mediatek,larb: must contain the local arbiters in the current Socs, see |
| 19 | − Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt | |
| 19 | + Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml | |
| 20 | 20 | for details. |
| 21 | 21 | - iommus: should point to the respective IOMMU block with master port as |
| 22 | 22 | argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt |
| @@ -14,7 +14,7 @@ Required properties: · 13 unmodified lines | ||
| 14 | 14 | - power-domains: a phandle to the power domain, see |
| 15 | 15 | Documentation/devicetree/bindings/power/power_domain.txt for details. |
| 16 | 16 | - mediatek,larb: must contain the local arbiters in the current SoCs, see |
| 17 | − Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt | |
| 17 | + Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml | |
| 18 | 18 | for details. |
| 19 | 19 | - iommus: should point to the respective IOMMU block with master port as |
| 20 | 20 | argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt |
| @@ -28,7 +28,7 @@ Required properties (DMA function blocks, child node): · 27 unmodified lines | ||
| 28 | 28 | argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt |
| 29 | 29 | for details. |
| 30 | 30 | - mediatek,larb: must contain the local arbiters in the current Socs, see |
| 31 | − Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt | |
| 31 | + Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml | |
| 32 | 32 | for details. |
| 33 | 33 | |
| 34 | 34 | Example: |
| @@ -259,7 +259,6 @@ properties: · 258 unmodified lines | ||
| 259 | 259 | waiting for I/O signalling and card power supply to be stable, |
| 260 | 260 | regardless of whether pwrseq-simple is used. Default to 10ms if |
| 261 | 261 | no available. |
| 262 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 263 | 262 | default: 10 |
| 264 | 263 | |
| 265 | 264 | supports-cqe: |
| @@ -41,13 +41,11 @@ properties: · 40 unmodified lines | ||
| 41 | 41 | description: |
| 42 | 42 | Delay in ms after powering the card and de-asserting the |
| 43 | 43 | reset-gpios (if any). |
| 44 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 45 | 44 | |
| 46 | 45 | power-off-delay-us: |
| 47 | 46 | description: |
| 48 | 47 | Delay in us after asserting the reset-gpios (if any) |
| 49 | 48 | during power off of the card. |
| 50 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 51 | 49 | |
| 52 | 50 | required: |
| 53 | 51 | - compatible |
| @@ -122,7 +122,6 @@ properties: · 121 unmodified lines | ||
| 122 | 122 | such as flow control thresholds. |
| 123 | 123 | |
| 124 | 124 | rx-internal-delay-ps: |
| 125 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 126 | 125 | description: | |
| 127 | 126 | RGMII Receive Clock Delay defined in pico seconds. |
| 128 | 127 | This is used for controllers that have configurable RX internal delays. |
| @@ -140,7 +139,6 @@ properties: · 11 unmodified lines | ||
| 140 | 139 | is used for components that can have configurable fifo sizes. |
| 141 | 140 | |
| 142 | 141 | tx-internal-delay-ps: |
| 143 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 144 | 142 | description: | |
| 145 | 143 | RGMII Transmit Clock Delay defined in pico seconds. |
| 146 | 144 | This is used for controllers that have configurable TX internal delays. |
| @@ -163,6 +163,7 @@ allOf: · 162 unmodified lines | ||
| 163 | 163 | enum: |
| 164 | 164 | - renesas,etheravb-r8a774a1 |
| 165 | 165 | - renesas,etheravb-r8a774b1 |
| 166 | + - renesas,etheravb-r8a774e1 | |
| 166 | 167 | - renesas,etheravb-r8a7795 |
| 167 | 168 | - renesas,etheravb-r8a7796 |
| 168 | 169 | - renesas,etheravb-r8a77961 |
| @@ -161,7 +161,8 @@ properties: · 160 unmodified lines | ||
| 161 | 161 | * snps,route-dcbcp, DCB Control Packets |
| 162 | 162 | * snps,route-up, Untagged Packets |
| 163 | 163 | * snps,route-multi-broad, Multicast & Broadcast Packets |
| 164 | − * snps,priority, RX queue priority (Range 0x0 to 0xF) | |
| 164 | + * snps,priority, bitmask of the tagged frames priorities assigned to | |
| 165 | + the queue | |
| 165 | 166 | |
| 166 | 167 | snps,mtl-tx-config: |
| 167 | 168 | $ref: /schemas/types.yaml#/definitions/phandle |
| @@ -188,7 +189,10 @@ properties: · 20 unmodified lines | ||
| 188 | 189 | * snps,idle_slope, unlock on WoL |
| 189 | 190 | * snps,high_credit, max write outstanding req. limit |
| 190 | 191 | * snps,low_credit, max read outstanding req. limit |
| 191 | − * snps,priority, TX queue priority (Range 0x0 to 0xF) | |
| 192 | + * snps,priority, bitmask of the priorities assigned to the queue. | |
| 193 | + When a PFC frame is received with priorities matching the bitmask, | |
| 194 | + the queue is blocked from transmitting for the pause time specified | |
| 195 | + in the PFC frame. | |
| 192 | 196 | |
| 193 | 197 | snps,reset-gpio: |
| 194 | 198 | deprecated: true |
| @@ -208,7 +212,6 @@ properties: · 13 unmodified lines | ||
| 208 | 212 | Triplet of delays. The 1st cell is reset pre-delay in micro |
| 209 | 213 | seconds. The 2nd cell is reset pulse in micro seconds. The 3rd |
| 210 | 214 | cell is reset post-delay in micro seconds. |
| 211 | − $ref: /schemas/types.yaml#/definitions/uint32-array | |
| 212 | 215 | minItems: 3 |
| 213 | 216 | maxItems: 3 |
| 214 | 217 | |
| @@ -83,21 +83,18 @@ properties: · 82 unmodified lines | ||
| 83 | 83 | for each of the battery capacity lookup table. |
| 84 | 84 | |
| 85 | 85 | operating-range-celsius: |
| 86 | − $ref: /schemas/types.yaml#/definitions/uint32-array | |
| 87 | 86 | description: operating temperature range of a battery |
| 88 | 87 | items: |
| 89 | 88 | - description: minimum temperature at which battery can operate |
| 90 | 89 | - description: maximum temperature at which battery can operate |
| 91 | 90 | |
| 92 | 91 | ambient-celsius: |
| 93 | − $ref: /schemas/types.yaml#/definitions/uint32-array | |
| 94 | 92 | description: safe range of ambient temperature |
| 95 | 93 | items: |
| 96 | 94 | - description: alert when ambient temperature is lower than this value |
| 97 | 95 | - description: alert when ambient temperature is higher than this value |
| 98 | 96 | |
| 99 | 97 | alert-celsius: |
| 100 | − $ref: /schemas/types.yaml#/definitions/uint32-array | |
| 101 | 98 | description: safe range of battery temperature |
| 102 | 99 | items: |
| 103 | 100 | - description: alert when battery temperature is lower than this value |
| @@ -50,7 +50,6 @@ properties: · 49 unmodified lines | ||
| 50 | 50 | maxItems: 1 |
| 51 | 51 | |
| 52 | 52 | input-current-limit-microamp: |
| 53 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 54 | 53 | description: Maximum input current in micro Amps. |
| 55 | 54 | minimum: 50000 |
| 56 | 55 | maximum: 500000 |
| @@ -62,7 +62,6 @@ properties: · 61 unmodified lines | ||
| 62 | 62 | description: IRQ line information. |
| 63 | 63 | |
| 64 | 64 | dlg,irq-polling-delay-passive-ms: |
| 65 | − $ref: "/schemas/types.yaml#/definitions/uint32" | |
| 66 | 65 | minimum: 1000 |
| 67 | 66 | maximum: 10000 |
| 68 | 67 | description: | |
| @@ -72,11 +72,9 @@ properties: · 71 unmodified lines | ||
| 72 | 72 | |
| 73 | 73 | startup-delay-us: |
| 74 | 74 | description: startup time in microseconds |
| 75 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 76 | 75 | |
| 77 | 76 | off-on-delay-us: |
| 78 | 77 | description: off delay time in microseconds |
| 79 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 80 | 78 | |
| 81 | 79 | enable-active-high: |
| 82 | 80 | description: |
| @@ -19,7 +19,9 @@ description: | · 18 unmodified lines | ||
| 19 | 19 | properties: |
| 20 | 20 | compatible: |
| 21 | 21 | enum: |
| 22 | − - nxp,pf8x00 | |
| 22 | + - nxp,pf8100 | |
| 23 | + - nxp,pf8121a | |
| 24 | + - nxp,pf8200 | |
| 23 | 25 | |
| 24 | 26 | reg: |
| 25 | 27 | maxItems: 1 |
| @@ -118,7 +120,7 @@ examples: · 92 unmodified lines | ||
| 118 | 120 | #size-cells = <0>; |
| 119 | 121 | |
| 120 | 122 | pmic@8 { |
| 121 | − compatible = "nxp,pf8x00"; | |
| 123 | + compatible = "nxp,pf8100"; | |
| 122 | 124 | reg = <0x08>; |
| 123 | 125 | |
| 124 | 126 | regulators { |
| @@ -44,6 +44,7 @@ First Level Nodes - PMIC · 43 unmodified lines | ||
| 44 | 44 | Definition: Must be one of below: |
| 45 | 45 | "qcom,pm8005-rpmh-regulators" |
| 46 | 46 | "qcom,pm8009-rpmh-regulators" |
| 47 | + "qcom,pm8009-1-rpmh-regulators" | |
| 47 | 48 | "qcom,pm8150-rpmh-regulators" |
| 48 | 49 | "qcom,pm8150l-rpmh-regulators" |
| 49 | 50 | "qcom,pm8350-rpmh-regulators" |
| @@ -27,7 +27,6 @@ properties: · 26 unmodified lines | ||
| 27 | 27 | 1: chargeable |
| 28 | 28 | |
| 29 | 29 | quartz-load-femtofarads: |
| 30 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 31 | 30 | description: |
| 32 | 31 | The capacitive load of the quartz(x-tal), expressed in femto |
| 33 | 32 | Farad (fF). The default value shall be listed (if optional), |
| @@ -47,7 +46,6 @@ properties: · 13 unmodified lines | ||
| 47 | 46 | deprecated: true |
| 48 | 47 | |
| 49 | 48 | trickle-resistor-ohms: |
| 50 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 51 | 49 | description: |
| 52 | 50 | Selected resistor for trickle charger. Should be given |
| 53 | 51 | if trickle charger should be enabled. |
| @@ -88,14 +88,12 @@ properties: · 87 unmodified lines | ||
| 88 | 88 | description: |
| 89 | 89 | Rate at which poll occurs when auto-poll is set. |
| 90 | 90 | default 100ms. |
| 91 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 92 | 91 | default: 100 |
| 93 | 92 | |
| 94 | 93 | poll-timeout-ms: |
| 95 | 94 | description: |
| 96 | 95 | Poll timeout when auto-poll is set, default |
| 97 | 96 | 3000ms. |
| 98 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 99 | 97 | default: 3000 |
| 100 | 98 | |
| 101 | 99 | required: |
| @@ -7,8 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | ||
| 7 | 7 | title: Mediatek MT8192 with MT6359, RT1015 and RT5682 ASoC sound card driver |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | − - Jiaxin Yu <jiaxin.yu@mediatek.com> | |
| 11 | − - Shane Chien <shane.chien@mediatek.com> | |
| 10 | + - Jiaxin Yu <jiaxin.yu@mediatek.com> | |
| 11 | + - Shane Chien <shane.chien@mediatek.com> | |
| 12 | 12 | |
| 13 | 13 | description: |
| 14 | 14 | This binding describes the MT8192 sound card. |
| @@ -41,14 +41,12 @@ properties: · 40 unmodified lines | ||
| 41 | 41 | values of 2k, 4k or 8k. If set to 0 it will be off. If this node is not |
| 42 | 42 | mentioned or if the value is unknown, then micbias resistor is set to |
| 43 | 43 | 4k. |
| 44 | − $ref: "/schemas/types.yaml#/definitions/uint32" | |
| 45 | 44 | enum: [ 0, 2, 4, 8 ] |
| 46 | 45 | |
| 47 | 46 | micbias-voltage-m-volts: |
| 48 | 47 | description: The bias voltage to be used in mVolts. The voltage can take |
| 49 | 48 | values from 1.25V to 3V by 250mV steps. If this node is not mentioned |
| 50 | 49 | or the value is unknown, then the value is set to 1.25V. |
| 51 | − $ref: "/schemas/types.yaml#/definitions/uint32" | |
| 52 | 50 | enum: [ 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000 ] |
| 53 | 51 | |
| 54 | 52 | lrclk-strength: |
| @@ -1,4 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | +# Copyright (C) 2020 Texas Instruments Incorporated | |
| 3 | +# Author: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 2 | 4 | %YAML 1.2 |
| 3 | 5 | --- |
| 4 | 6 | $id: http://devicetree.org/schemas/sound/ti,j721e-cpb-audio.yaml# |
| @@ -7,7 +9,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 2 unmodified lines | ||
| 7 | 9 | title: Texas Instruments J721e Common Processor Board Audio Support |
| 8 | 10 | |
| 9 | 11 | maintainers: |
| 10 | − - Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 12 | + - Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 11 | 13 | |
| 12 | 14 | description: | |
| 13 | 15 | The audio support on the board is using pcm3168a codec connected to McASP10 |
| @@ -1,4 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | +# Copyright (C) 2020 Texas Instruments Incorporated | |
| 3 | +# Author: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 2 | 4 | %YAML 1.2 |
| 3 | 5 | --- |
| 4 | 6 | $id: http://devicetree.org/schemas/sound/ti,j721e-cpb-ivi-audio.yaml# |
| @@ -7,7 +9,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 2 unmodified lines | ||
| 7 | 9 | title: Texas Instruments J721e Common Processor Board Audio Support |
| 8 | 10 | |
| 9 | 11 | maintainers: |
| 10 | − - Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 12 | + - Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 11 | 13 | |
| 12 | 14 | description: | |
| 13 | 15 | The Infotainment board plugs into the Common Processor Board, the support of the |
| @@ -11,12 +11,18 @@ maintainers: · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | properties: |
| 13 | 13 | compatible: |
| 14 | − items: | |
| 14 | + oneOf: | |
| 15 | 15 | - const: ti,j721e-usb |
| 16 | + - const: ti,am64-usb | |
| 17 | + - items: | |
| 18 | + - const: ti,j721e-usb | |
| 19 | + - const: ti,am64-usb | |
| 16 | 20 | |
| 17 | 21 | reg: |
| 18 | 22 | description: module registers |
| 19 | 23 | |
| 24 | + ranges: true | |
| 25 | + | |
| 20 | 26 | power-domains: |
| 21 | 27 | description: |
| 22 | 28 | PM domain provider node and an args specifier containing |
| @@ -58,6 +64,8 @@ properties: · 35 unmodified lines | ||
| 58 | 64 | '#size-cells': |
| 59 | 65 | const: 2 |
| 60 | 66 | |
| 67 | + dma-coherent: true | |
| 68 | + | |
| 61 | 69 | patternProperties: |
| 62 | 70 | "^usb@": |
| 63 | 71 | type: object |
| @@ -19,7 +19,6 @@ properties: · 18 unmodified lines | ||
| 19 | 19 | pattern: "^watchdog(@.*|-[0-9a-f])?$" |
| 20 | 20 | |
| 21 | 21 | timeout-sec: |
| 22 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 23 | 22 | description: |
| 24 | 23 | Contains the watchdog timeout in seconds. |
| 25 | 24 | |
| @@ -48,12 +48,12 @@ or ``virtualenv``, depending on how your distribution packaged Python 3. · 47 unmodified lines | ||
| 48 | 48 | those versions, you should run ``pip install 'docutils==0.12'``. |
| 49 | 49 | |
| 50 | 50 | #) It is recommended to use the RTD theme for html output. Depending |
| 51 | − on the Sphinx version, it should be installed in separate, | |
| 51 | + on the Sphinx version, it should be installed separately, | |
| 52 | 52 | with ``pip install sphinx_rtd_theme``. |
| 53 | 53 | |
| 54 | − #) Some ReST pages contain math expressions. Due to the way Sphinx work, | |
| 54 | + #) Some ReST pages contain math expressions. Due to the way Sphinx works, | |
| 55 | 55 | those expressions are written using LaTeX notation. It needs texlive |
| 56 | − installed with amdfonts and amsmath in order to evaluate them. | |
| 56 | + installed with amsfonts and amsmath in order to evaluate them. | |
| 57 | 57 | |
| 58 | 58 | In summary, if you want to install Sphinx version 1.7.9, you should do:: |
| 59 | 59 | |
| @@ -128,7 +128,7 @@ Sphinx Build · 68 unmodified lines | ||
| 128 | 128 | ============ |
| 129 | 129 | |
| 130 | 130 | The usual way to generate the documentation is to run ``make htmldocs`` or |
| 131 | −``make pdfdocs``. There are also other formats available, see the documentation | |
| 131 | +``make pdfdocs``. There are also other formats available: see the documentation | |
| 132 | 132 | section of ``make help``. The generated documentation is placed in |
| 133 | 133 | format-specific subdirectories under ``Documentation/output``. |
| 134 | 134 | |
| @@ -303,17 +303,17 @@ and *targets* (e.g. a ref to ``:ref:`last row <last row>``` / :ref:`last row · 168 unmodified lines | ||
| 303 | 303 | - head col 3 |
| 304 | 304 | - head col 4 |
| 305 | 305 | |
| 306 | − * - column 1 | |
| 306 | + * - row 1 | |
| 307 | 307 | - field 1.1 |
| 308 | 308 | - field 1.2 with autospan |
| 309 | 309 | |
| 310 | − * - column 2 | |
| 310 | + * - row 2 | |
| 311 | 311 | - field 2.1 |
| 312 | 312 | - :rspan:`1` :cspan:`1` field 2.2 - 3.3 |
| 313 | 313 | |
| 314 | 314 | * .. _`last row`: |
| 315 | 315 | |
| 316 | − - column 3 | |
| 316 | + - row 3 | |
| 317 | 317 | |
| 318 | 318 | Rendered as: |
| 319 | 319 | |
| @@ -325,17 +325,17 @@ Rendered as: · 5 unmodified lines | ||
| 325 | 325 | - head col 3 |
| 326 | 326 | - head col 4 |
| 327 | 327 | |
| 328 | − * - column 1 | |
| 328 | + * - row 1 | |
| 329 | 329 | - field 1.1 |
| 330 | 330 | - field 1.2 with autospan |
| 331 | 331 | |
| 332 | − * - column 2 | |
| 332 | + * - row 2 | |
| 333 | 333 | - field 2.1 |
| 334 | 334 | - :rspan:`1` :cspan:`1` field 2.2 - 3.3 |
| 335 | 335 | |
| 336 | 336 | * .. _`last row`: |
| 337 | 337 | |
| 338 | − - column 3 | |
| 338 | + - row 3 | |
| 339 | 339 | |
| 340 | 340 | Cross-referencing |
| 341 | 341 | ----------------- |
| @@ -361,7 +361,7 @@ Figures & Images · 19 unmodified lines | ||
| 361 | 361 | |
| 362 | 362 | If you want to add an image, you should use the ``kernel-figure`` and |
| 363 | 363 | ``kernel-image`` directives. E.g. to insert a figure with a scalable |
| 364 | −image format use SVG (:ref:`svg_image_example`):: | |
| 364 | +image format, use SVG (:ref:`svg_image_example`):: | |
| 365 | 365 | |
| 366 | 366 | .. kernel-figure:: svg_image.svg |
| 367 | 367 | :alt: simple SVG image |
| @@ -375,7 +375,7 @@ image format use SVG (:ref:`svg_image_example`):: · 7 unmodified lines | ||
| 375 | 375 | |
| 376 | 376 | SVG image example |
| 377 | 377 | |
| 378 | −The kernel figure (and image) directive support **DOT** formatted files, see | |
| 378 | +The kernel figure (and image) directive supports **DOT** formatted files, see | |
| 379 | 379 | |
| 380 | 380 | * DOT: http://graphviz.org/pdf/dotguide.pdf |
| 381 | 381 | * Graphviz: http://www.graphviz.org/content/dot-language |
| @@ -394,7 +394,7 @@ A simple example (:ref:`hello_dot_file`):: · 12 unmodified lines | ||
| 394 | 394 | |
| 395 | 395 | DOT's hello world example |
| 396 | 396 | |
| 397 | −Embed *render* markups (or languages) like Graphviz's **DOT** is provided by the | |
| 397 | +Embedded *render* markups (or languages) like Graphviz's **DOT** are provided by the | |
| 398 | 398 | ``kernel-render`` directives.:: |
| 399 | 399 | |
| 400 | 400 | .. kernel-render:: DOT |
| @@ -406,7 +406,7 @@ Embed *render* markups (or languages) like Graphviz's **DOT** is provided by the · 5 unmodified lines | ||
| 406 | 406 | } |
| 407 | 407 | |
| 408 | 408 | How this will be rendered depends on the installed tools. If Graphviz is |
| 409 | −installed, you will see an vector image. If not the raw markup is inserted as | |
| 409 | +installed, you will see a vector image. If not, the raw markup is inserted as | |
| 410 | 410 | *literal-block* (:ref:`hello_dot_render`). |
| 411 | 411 | |
| 412 | 412 | .. _hello_dot_render: |
| @@ -421,8 +421,8 @@ installed, you will see an vector image. If not the raw markup is inserted as · 8 unmodified lines | ||
| 421 | 421 | |
| 422 | 422 | The *render* directive has all the options known from the *figure* directive, |
| 423 | 423 | plus option ``caption``. If ``caption`` has a value, a *figure* node is |
| 424 | −inserted. If not, a *image* node is inserted. A ``caption`` is also needed, if | |
| 425 | −you want to refer it (:ref:`hello_svg_render`). | |
| 424 | +inserted. If not, an *image* node is inserted. A ``caption`` is also needed, if | |
| 425 | +you want to refer to it (:ref:`hello_svg_render`). | |
| 426 | 426 | |
| 427 | 427 | Embedded **SVG**:: |
| 428 | 428 | |
| @@ -586,6 +586,14 @@ without significant effort. · 585 unmodified lines | ||
| 586 | 586 | The advantage of mounting with the "volatile" option is that all forms of |
| 587 | 587 | sync calls to the upper filesystem are omitted. |
| 588 | 588 | |
| 589 | +In order to avoid a giving a false sense of safety, the syncfs (and fsync) | |
| 590 | +semantics of volatile mounts are slightly different than that of the rest of | |
| 591 | +VFS. If any writeback error occurs on the upperdir's filesystem after a | |
| 592 | +volatile mount takes place, all sync functions will return an error. Once this | |
| 593 | +condition is reached, the filesystem will not recover, and every subsequent sync | |
| 594 | +call will return an error, even if the upperdir has not experience a new error | |
| 595 | +since the last sync call. | |
| 596 | + | |
| 589 | 597 | When overlay is mounted with "volatile" option, the directory |
| 590 | 598 | "$workdir/work/incompat/volatile" is created. During next mount, overlay |
| 591 | 599 | checks for this directory and refuses to mount if present. This is a strong |
| @@ -50,8 +50,8 @@ The following files belong to it: · 49 unmodified lines | ||
| 50 | 50 | 0x00000010 Memory Uncorrectable non-fatal |
| 51 | 51 | 0x00000020 Memory Uncorrectable fatal |
| 52 | 52 | 0x00000040 PCI Express Correctable |
| 53 | − 0x00000080 PCI Express Uncorrectable fatal | |
| 54 | − 0x00000100 PCI Express Uncorrectable non-fatal | |
| 53 | + 0x00000080 PCI Express Uncorrectable non-fatal | |
| 54 | + 0x00000100 PCI Express Uncorrectable fatal | |
| 55 | 55 | 0x00000200 Platform Correctable |
| 56 | 56 | 0x00000400 Platform Uncorrectable non-fatal |
| 57 | 57 | 0x00000800 Platform Uncorrectable fatal |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | .. SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | 2 | |
| 3 | 3 | Kernel driver sbtsi_temp |
| 4 | −================== | |
| 4 | +======================== | |
| 5 | 5 | |
| 6 | 6 | Supported hardware: |
| 7 | 7 | |
| @@ -11,16 +11,13 @@ compiler [1]_. They are useful for runtime instrumentation and static analysis. · 10 unmodified lines | ||
| 11 | 11 | We can analyse, change and add further code during compilation via |
| 12 | 12 | callbacks [2]_, GIMPLE [3]_, IPA [4]_ and RTL passes [5]_. |
| 13 | 13 | |
| 14 | −The GCC plugin infrastructure of the kernel supports all gcc versions from | |
| 15 | −4.5 to 6.0, building out-of-tree modules, cross-compilation and building in a | |
| 16 | −separate directory. | |
| 17 | −Plugin source files have to be compilable by both a C and a C++ compiler as well | |
| 18 | −because gcc versions 4.5 and 4.6 are compiled by a C compiler, | |
| 19 | −gcc-4.7 can be compiled by a C or a C++ compiler, | |
| 20 | −and versions 4.8+ can only be compiled by a C++ compiler. | |
| 14 | +The GCC plugin infrastructure of the kernel supports building out-of-tree | |
| 15 | +modules, cross-compilation and building in a separate directory. | |
| 16 | +Plugin source files have to be compilable by a C++ compiler. | |
| 21 | 17 | |
| 22 | −Currently the GCC plugin infrastructure supports only the x86, arm, arm64 and | |
| 23 | −powerpc architectures. | |
| 18 | +Currently the GCC plugin infrastructure supports only some architectures. | |
| 19 | +Grep "select HAVE_GCC_PLUGINS" to find out which architectures support | |
| 20 | +GCC plugins. | |
| 24 | 21 | |
| 25 | 22 | This infrastructure was ported from grsecurity [6]_ and PaX [7]_. |
| 26 | 23 | |
| @@ -47,20 +44,13 @@ Files · 20 unmodified lines | ||
| 47 | 44 | This is a compatibility header for GCC plugins. |
| 48 | 45 | It should be always included instead of individual gcc headers. |
| 49 | 46 | |
| 50 | −**$(src)/scripts/gcc-plugin.sh** | |
| 51 | − | |
| 52 | − This script checks the availability of the included headers in | |
| 53 | − gcc-common.h and chooses the proper host compiler to build the plugins | |
| 54 | − (gcc-4.7 can be built by either gcc or g++). | |
| 55 | − | |
| 56 | 47 | **$(src)/scripts/gcc-plugins/gcc-generate-gimple-pass.h, |
| 57 | 48 | $(src)/scripts/gcc-plugins/gcc-generate-ipa-pass.h, |
| 58 | 49 | $(src)/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h, |
| 59 | 50 | $(src)/scripts/gcc-plugins/gcc-generate-rtl-pass.h** |
| 60 | 51 | |
| 61 | 52 | These headers automatically generate the registration structures for |
| 62 | − GIMPLE, SIMPLE_IPA, IPA and RTL passes. They support all gcc versions | |
| 63 | − from 4.5 to 6.0. | |
| 53 | + GIMPLE, SIMPLE_IPA, IPA and RTL passes. | |
| 64 | 54 | They should be preferred to creating the structures by hand. |
| 65 | 55 | |
| 66 | 56 | |
| @@ -68,21 +58,25 @@ Usage · 1 unmodified line | ||
| 68 | 58 | ===== |
| 69 | 59 | |
| 70 | 60 | You must install the gcc plugin headers for your gcc version, |
| 71 | −e.g., on Ubuntu for gcc-4.9:: | |
| 61 | +e.g., on Ubuntu for gcc-10:: | |
| 72 | 62 | |
| 73 | − apt-get install gcc-4.9-plugin-dev | |
| 63 | + apt-get install gcc-10-plugin-dev | |
| 74 | 64 | |
| 75 | 65 | Or on Fedora:: |
| 76 | 66 | |
| 77 | 67 | dnf install gcc-plugin-devel |
| 78 | 68 | |
| 79 | −Enable a GCC plugin based feature in the kernel config:: | |
| 69 | +Enable the GCC plugin infrastructure and some plugin(s) you want to use | |
| 70 | +in the kernel config:: | |
| 80 | 71 | |
| 81 | − CONFIG_GCC_PLUGIN_CYC_COMPLEXITY = y | |
| 72 | + CONFIG_GCC_PLUGINS=y | |
| 73 | + CONFIG_GCC_PLUGIN_CYC_COMPLEXITY=y | |
| 74 | + CONFIG_GCC_PLUGIN_LATENT_ENTROPY=y | |
| 75 | + ... | |
| 82 | 76 | |
| 83 | −To compile only the plugin(s):: | |
| 77 | +To compile the minimum tool set including the plugin(s):: | |
| 84 | 78 | |
| 85 | − make gcc-plugins | |
| 79 | + make scripts | |
| 86 | 80 | |
| 87 | 81 | or just run the kernel make and compile the whole kernel with |
| 88 | 82 | the cyclomatic complexity GCC plugin. |
| @@ -91,7 +85,8 @@ the cyclomatic complexity GCC plugin. · 2 unmodified lines | ||
| 91 | 85 | 4. How to add a new GCC plugin |
| 92 | 86 | ============================== |
| 93 | 87 | |
| 94 | −The GCC plugins are in $(src)/scripts/gcc-plugins/. You can use a file or a directory | |
| 95 | −here. It must be added to $(src)/scripts/gcc-plugins/Makefile, | |
| 96 | −$(src)/scripts/Makefile.gcc-plugins and $(src)/arch/Kconfig. | |
| 88 | +The GCC plugins are in scripts/gcc-plugins/. You need to put plugin source files | |
| 89 | +right under scripts/gcc-plugins/. Creating subdirectories is not supported. | |
| 90 | +It must be added to scripts/gcc-plugins/Makefile, scripts/Makefile.gcc-plugins | |
| 91 | +and a relevant Kconfig file. | |
| 97 | 92 | See the cyc_complexity_plugin.c (CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) GCC plugin. |
| @@ -63,6 +63,50 @@ They can be enabled individually. The full list of the parameters: :: · 62 unmodified lines | ||
| 63 | 63 | Currently, the integrated assembler is disabled by default. You can pass |
| 64 | 64 | ``LLVM_IAS=1`` to enable it. |
| 65 | 65 | |
| 66 | +Supported Architectures | |
| 67 | +----------------------- | |
| 68 | + | |
| 69 | +LLVM does not target all of the architectures that Linux supports and | |
| 70 | +just because a target is supported in LLVM does not mean that the kernel | |
| 71 | +will build or work without any issues. Below is a general summary of | |
| 72 | +architectures that currently work with ``CC=clang`` or ``LLVM=1``. Level | |
| 73 | +of support corresponds to "S" values in the MAINTAINERS files. If an | |
| 74 | +architecture is not present, it either means that LLVM does not target | |
| 75 | +it or there are known issues. Using the latest stable version of LLVM or | |
| 76 | +even the development tree will generally yield the best results. | |
| 77 | +An architecture's ``defconfig`` is generally expected to work well, | |
| 78 | +certain configurations may have problems that have not been uncovered | |
| 79 | +yet. Bug reports are always welcome at the issue tracker below! | |
| 80 | + | |
| 81 | +.. list-table:: | |
| 82 | + :widths: 10 10 10 | |
| 83 | + :header-rows: 1 | |
| 84 | + | |
| 85 | + * - Architecture | |
| 86 | + - Level of support | |
| 87 | + - ``make`` command | |
| 88 | + * - arm | |
| 89 | + - Supported | |
| 90 | + - ``LLVM=1`` | |
| 91 | + * - arm64 | |
| 92 | + - Supported | |
| 93 | + - ``LLVM=1`` | |
| 94 | + * - mips | |
| 95 | + - Maintained | |
| 96 | + - ``CC=clang`` | |
| 97 | + * - powerpc | |
| 98 | + - Maintained | |
| 99 | + - ``CC=clang`` | |
| 100 | + * - riscv | |
| 101 | + - Maintained | |
| 102 | + - ``CC=clang`` | |
| 103 | + * - s390 | |
| 104 | + - Maintained | |
| 105 | + - ``CC=clang`` | |
| 106 | + * - x86 | |
| 107 | + - Supported | |
| 108 | + - ``LLVM=1`` | |
| 109 | + | |
| 66 | 110 | Getting Help |
| 67 | 111 | ------------ |
| 68 | 112 | |
| @@ -598,7 +598,7 @@ more details, with real examples. · 597 unmodified lines | ||
| 598 | 598 | explicitly added to $(targets). |
| 599 | 599 | |
| 600 | 600 | Assignments to $(targets) are without $(obj)/ prefix. if_changed may be |
| 601 | − used in conjunction with custom rules as defined in "3.9 Custom Rules". | |
| 601 | + used in conjunction with custom rules as defined in "3.11 Custom Rules". | |
| 602 | 602 | |
| 603 | 603 | Note: It is a typical mistake to forget the FORCE prerequisite. |
| 604 | 604 | Another common pitfall is that whitespace is sometimes significant; for |
| @@ -755,7 +755,7 @@ more details, with real examples. · 150 unmodified lines | ||
| 755 | 755 | bits on the scripts nonetheless. |
| 756 | 756 | |
| 757 | 757 | Kbuild provides variables $(CONFIG_SHELL), $(AWK), $(PERL), |
| 758 | − $(PYTHON) and $(PYTHON3) to refer to interpreters for the respective | |
| 758 | + and $(PYTHON3) to refer to interpreters for the respective | |
| 759 | 759 | scripts. |
| 760 | 760 | |
| 761 | 761 | Example:: |
| @@ -118,11 +118,11 @@ spinlock, but you may block holding a mutex. If you can't lock a mutex, · 117 unmodified lines | ||
| 118 | 118 | your task will suspend itself, and be woken up when the mutex is |
| 119 | 119 | released. This means the CPU can do something else while you are |
| 120 | 120 | waiting. There are many cases when you simply can't sleep (see |
| 121 | −`What Functions Are Safe To Call From Interrupts? <#sleeping-things>`__), | |
| 121 | +`What Functions Are Safe To Call From Interrupts?`_), | |
| 122 | 122 | and so have to use a spinlock instead. |
| 123 | 123 | |
| 124 | 124 | Neither type of lock is recursive: see |
| 125 | −`Deadlock: Simple and Advanced <#deadlock>`__. | |
| 125 | +`Deadlock: Simple and Advanced`_. | |
| 126 | 126 | |
| 127 | 127 | Locks and Uniprocessor Kernels |
| 128 | 128 | ------------------------------ |
| @@ -179,7 +179,7 @@ perfect world). · 50 unmodified lines | ||
| 179 | 179 | |
| 180 | 180 | Note that you can also use spin_lock_irq() or |
| 181 | 181 | spin_lock_irqsave() here, which stop hardware interrupts |
| 182 | −as well: see `Hard IRQ Context <#hard-irq-context>`__. | |
| 182 | +as well: see `Hard IRQ Context`_. | |
| 183 | 183 | |
| 184 | 184 | This works perfectly for UP as well: the spin lock vanishes, and this |
| 185 | 185 | macro simply becomes local_bh_disable() |
| @@ -230,7 +230,7 @@ The Same Softirq · 44 unmodified lines | ||
| 230 | 230 | ~~~~~~~~~~~~~~~~ |
| 231 | 231 | |
| 232 | 232 | The same softirq can run on the other CPUs: you can use a per-CPU array |
| 233 | −(see `Per-CPU Data <#per-cpu-data>`__) for better performance. If you're | |
| 233 | +(see `Per-CPU Data`_) for better performance. If you're | |
| 234 | 234 | going so far as to use a softirq, you probably care about scalable |
| 235 | 235 | performance enough to justify the extra complexity. |
| 236 | 236 | |
| @@ -164,46 +164,56 @@ Devlink health reporters · 163 unmodified lines | ||
| 164 | 164 | |
| 165 | 165 | NPA Reporters |
| 166 | 166 | ------------- |
| 167 | −The NPA reporters are responsible for reporting and recovering the following group of errors | |
| 167 | +The NPA reporters are responsible for reporting and recovering the following group of errors: | |
| 168 | + | |
| 168 | 169 | 1. GENERAL events |
| 170 | + | |
| 169 | 171 | - Error due to operation of unmapped PF. |
| 170 | 172 | - Error due to disabled alloc/free for other HW blocks (NIX, SSO, TIM, DPI and AURA). |
| 173 | + | |
| 171 | 174 | 2. ERROR events |
| 175 | + | |
| 172 | 176 | - Fault due to NPA_AQ_INST_S read or NPA_AQ_RES_S write. |
| 173 | 177 | - AQ Doorbell Error. |
| 178 | + | |
| 174 | 179 | 3. RAS events |
| 180 | + | |
| 175 | 181 | - RAS Error Reporting for NPA_AQ_INST_S/NPA_AQ_RES_S. |
| 182 | + | |
| 176 | 183 | 4. RVU events |
| 184 | + | |
| 177 | 185 | - Error due to unmapped slot. |
| 178 | 186 | |
| 179 | −Sample Output | |
| 180 | −------------- | |
| 181 | −~# devlink health | |
| 182 | −pci/0002:01:00.0: | |
| 183 | − reporter hw_npa_intr | |
| 184 | − state healthy error 2872 recover 2872 last_dump_date 2020-12-10 last_dump_time 09:39:09 grace_period 0 auto_recover true auto_dump true | |
| 185 | − reporter hw_npa_gen | |
| 186 | − state healthy error 2872 recover 2872 last_dump_date 2020-12-11 last_dump_time 04:43:04 grace_period 0 auto_recover true auto_dump true | |
| 187 | − reporter hw_npa_err | |
| 188 | − state healthy error 2871 recover 2871 last_dump_date 2020-12-10 last_dump_time 09:39:17 grace_period 0 auto_recover true auto_dump true | |
| 189 | − reporter hw_npa_ras | |
| 190 | − state healthy error 0 recover 0 last_dump_date 2020-12-10 last_dump_time 09:32:40 grace_period 0 auto_recover true auto_dump true | |
| 187 | +Sample Output:: | |
| 188 | + | |
| 189 | + ~# devlink health | |
| 190 | + pci/0002:01:00.0: | |
| 191 | + reporter hw_npa_intr | |
| 192 | + state healthy error 2872 recover 2872 last_dump_date 2020-12-10 last_dump_time 09:39:09 grace_period 0 auto_recover true auto_dump true | |
| 193 | + reporter hw_npa_gen | |
| 194 | + state healthy error 2872 recover 2872 last_dump_date 2020-12-11 last_dump_time 04:43:04 grace_period 0 auto_recover true auto_dump true | |
| 195 | + reporter hw_npa_err | |
| 196 | + state healthy error 2871 recover 2871 last_dump_date 2020-12-10 last_dump_time 09:39:17 grace_period 0 auto_recover true auto_dump true | |
| 197 | + reporter hw_npa_ras | |
| 198 | + state healthy error 0 recover 0 last_dump_date 2020-12-10 last_dump_time 09:32:40 grace_period 0 auto_recover true auto_dump true | |
| 191 | 199 | |
| 192 | 200 | Each reporter dumps the |
| 201 | + | |
| 193 | 202 | - Error Type |
| 194 | 203 | - Error Register value |
| 195 | 204 | - Reason in words |
| 196 | 205 | |
| 197 | −For eg: | |
| 198 | −~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_gen | |
| 199 | − NPA_AF_GENERAL: | |
| 200 | − NPA General Interrupt Reg : 1 | |
| 201 | − NIX0: free disabled RX | |
| 202 | −~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_intr | |
| 203 | − NPA_AF_RVU: | |
| 204 | − NPA RVU Interrupt Reg : 1 | |
| 205 | − Unmap Slot Error | |
| 206 | −~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_err | |
| 207 | − NPA_AF_ERR: | |
| 208 | − NPA Error Interrupt Reg : 4096 | |
| 209 | − AQ Doorbell Error | |
| 206 | +For example:: | |
| 207 | + | |
| 208 | + ~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_gen | |
| 209 | + NPA_AF_GENERAL: | |
| 210 | + NPA General Interrupt Reg : 1 | |
| 211 | + NIX0: free disabled RX | |
| 212 | + ~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_intr | |
| 213 | + NPA_AF_RVU: | |
| 214 | + NPA RVU Interrupt Reg : 1 | |
| 215 | + Unmap Slot Error | |
| 216 | + ~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_err | |
| 217 | + NPA_AF_ERR: | |
| 218 | + NPA Error Interrupt Reg : 4096 | |
| 219 | + AQ Doorbell Error | |
| @@ -1196,7 +1196,7 @@ icmp_errors_use_inbound_ifaddr - BOOLEAN · 1195 unmodified lines | ||
| 1196 | 1196 | |
| 1197 | 1197 | If non-zero, the message will be sent with the primary address of |
| 1198 | 1198 | the interface that received the packet that caused the icmp error. |
| 1199 | − This is the behaviour network many administrators will expect from | |
| 1199 | + This is the behaviour many network administrators will expect from | |
| 1200 | 1200 | a router. And it can make debugging complicated network layouts |
| 1201 | 1201 | much easier. |
| 1202 | 1202 | |
| @@ -1807,12 +1807,24 @@ seg6_flowlabel - INTEGER · 604 unmodified lines | ||
| 1807 | 1807 | ``conf/default/*``: |
| 1808 | 1808 | Change the interface-specific default settings. |
| 1809 | 1809 | |
| 1810 | + These settings would be used during creating new interfaces. | |
| 1811 | + | |
| 1810 | 1812 | |
| 1811 | 1813 | ``conf/all/*``: |
| 1812 | 1814 | Change all the interface-specific settings. |
| 1813 | 1815 | |
| 1814 | 1816 | [XXX: Other special features than forwarding?] |
| 1815 | 1817 | |
| 1818 | +conf/all/disable_ipv6 - BOOLEAN | |
| 1819 | + Changing this value is same as changing ``conf/default/disable_ipv6`` | |
| 1820 | + setting and also all per-interface ``disable_ipv6`` settings to the same | |
| 1821 | + value. | |
| 1822 | + | |
| 1823 | + Reading this value does not have any particular meaning. It does not say | |
| 1824 | + whether IPv6 support is enabled or disabled. Returned value can be 1 | |
| 1825 | + also in the case when some interface has ``disable_ipv6`` set to 0 and | |
| 1826 | + has configured IPv6 addresses. | |
| 1827 | + | |
| 1816 | 1828 | conf/all/forwarding - BOOLEAN |
| 1817 | 1829 | Enable global IPv6 forwarding between all interfaces. |
| 1818 | 1830 | |
| @@ -6,9 +6,9 @@ · 5 unmodified lines | ||
| 6 | 6 | netdev FAQ |
| 7 | 7 | ========== |
| 8 | 8 | |
| 9 | −Q: What is netdev? | |
| 10 | −------------------ | |
| 11 | −A: It is a mailing list for all network-related Linux stuff. This | |
| 9 | +What is netdev? | |
| 10 | +--------------- | |
| 11 | +It is a mailing list for all network-related Linux stuff. This | |
| 12 | 12 | includes anything found under net/ (i.e. core code like IPv6) and |
| 13 | 13 | drivers/net (i.e. hardware specific drivers) in the Linux source tree. |
| 14 | 14 | |
| @@ -25,9 +25,9 @@ Aside from subsystems like that mentioned above, all network-related · 10 unmodified lines | ||
| 25 | 25 | Linux development (i.e. RFC, review, comments, etc.) takes place on |
| 26 | 26 | netdev. |
| 27 | 27 | |
| 28 | −Q: How do the changes posted to netdev make their way into Linux? | |
| 29 | −----------------------------------------------------------------- | |
| 30 | −A: There are always two trees (git repositories) in play. Both are | |
| 28 | +How do the changes posted to netdev make their way into Linux? | |
| 29 | +-------------------------------------------------------------- | |
| 30 | +There are always two trees (git repositories) in play. Both are | |
| 31 | 31 | driven by David Miller, the main network maintainer. There is the |
| 32 | 32 | ``net`` tree, and the ``net-next`` tree. As you can probably guess from |
| 33 | 33 | the names, the ``net`` tree is for fixes to existing code already in the |
| @@ -37,9 +37,9 @@ for the future release. You can find the trees here: · 3 unmodified lines | ||
| 37 | 37 | - https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git |
| 38 | 38 | - https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git |
| 39 | 39 | |
| 40 | −Q: How often do changes from these trees make it to the mainline Linus tree? | |
| 41 | −---------------------------------------------------------------------------- | |
| 42 | −A: To understand this, you need to know a bit of background information on | |
| 40 | +How often do changes from these trees make it to the mainline Linus tree? | |
| 41 | +------------------------------------------------------------------------- | |
| 42 | +To understand this, you need to know a bit of background information on | |
| 43 | 43 | the cadence of Linux development. Each new release starts off with a |
| 44 | 44 | two week "merge window" where the main maintainers feed their new stuff |
| 45 | 45 | to Linus for merging into the mainline tree. After the two weeks, the |
| @@ -81,7 +81,8 @@ focus for ``net`` is on stabilization and bug fixes. · 35 unmodified lines | ||
| 81 | 81 | |
| 82 | 82 | Finally, the vX.Y gets released, and the whole cycle starts over. |
| 83 | 83 | |
| 84 | −Q: So where are we now in this cycle? | |
| 84 | +So where are we now in this cycle? | |
| 85 | +---------------------------------- | |
| 85 | 86 | |
| 86 | 87 | Load the mainline (Linus) page here: |
| 87 | 88 | |
| @@ -91,9 +92,9 @@ and note the top of the "tags" section. If it is rc1, it is early in · 3 unmodified lines | ||
| 91 | 92 | the dev cycle. If it was tagged rc7 a week ago, then a release is |
| 92 | 93 | probably imminent. |
| 93 | 94 | |
| 94 | −Q: How do I indicate which tree (net vs. net-next) my patch should be in? | |
| 95 | −------------------------------------------------------------------------- | |
| 96 | −A: Firstly, think whether you have a bug fix or new "next-like" content. | |
| 95 | +How do I indicate which tree (net vs. net-next) my patch should be in? | |
| 96 | +---------------------------------------------------------------------- | |
| 97 | +Firstly, think whether you have a bug fix or new "next-like" content. | |
| 97 | 98 | Then once decided, assuming that you use git, use the prefix flag, i.e. |
| 98 | 99 | :: |
| 99 | 100 | |
| @@ -105,48 +106,45 @@ in the above is just the subject text of the outgoing e-mail, and you · 5 unmodified lines | ||
| 105 | 106 | can manually change it yourself with whatever MUA you are comfortable |
| 106 | 107 | with. |
| 107 | 108 | |
| 108 | −Q: I sent a patch and I'm wondering what happened to it? | |
| 109 | −-------------------------------------------------------- | |
| 110 | −Q: How can I tell whether it got merged? | |
| 111 | −A: Start by looking at the main patchworks queue for netdev: | |
| 109 | +I sent a patch and I'm wondering what happened to it - how can I tell whether it got merged? | |
| 110 | +-------------------------------------------------------------------------------------------- | |
| 111 | +Start by looking at the main patchworks queue for netdev: | |
| 112 | 112 | |
| 113 | 113 | https://patchwork.kernel.org/project/netdevbpf/list/ |
| 114 | 114 | |
| 115 | 115 | The "State" field will tell you exactly where things are at with your |
| 116 | 116 | patch. |
| 117 | 117 | |
| 118 | −Q: The above only says "Under Review". How can I find out more? | |
| 119 | −---------------------------------------------------------------- | |
| 120 | −A: Generally speaking, the patches get triaged quickly (in less than | |
| 118 | +The above only says "Under Review". How can I find out more? | |
| 119 | +------------------------------------------------------------- | |
| 120 | +Generally speaking, the patches get triaged quickly (in less than | |
| 121 | 121 | 48h). So be patient. Asking the maintainer for status updates on your |
| 122 | 122 | patch is a good way to ensure your patch is ignored or pushed to the |
| 123 | 123 | bottom of the priority list. |
| 124 | 124 | |
| 125 | −Q: I submitted multiple versions of the patch series | |
| 126 | −---------------------------------------------------- | |
| 127 | −Q: should I directly update patchwork for the previous versions of these | |
| 128 | −patch series? | |
| 129 | −A: No, please don't interfere with the patch status on patchwork, leave | |
| 125 | +I submitted multiple versions of the patch series. Should I directly update patchwork for the previous versions of these patch series? | |
| 126 | +-------------------------------------------------------------------------------------------------------------------------------------- | |
| 127 | +No, please don't interfere with the patch status on patchwork, leave | |
| 130 | 128 | it to the maintainer to figure out what is the most recent and current |
| 131 | 129 | version that should be applied. If there is any doubt, the maintainer |
| 132 | 130 | will reply and ask what should be done. |
| 133 | 131 | |
| 134 | −Q: I made changes to only a few patches in a patch series should I resend only those changed? | |
| 135 | −--------------------------------------------------------------------------------------------- | |
| 136 | −A: No, please resend the entire patch series and make sure you do number your | |
| 132 | +I made changes to only a few patches in a patch series should I resend only those changed? | |
| 133 | +------------------------------------------------------------------------------------------ | |
| 134 | +No, please resend the entire patch series and make sure you do number your | |
| 137 | 135 | patches such that it is clear this is the latest and greatest set of patches |
| 138 | 136 | that can be applied. |
| 139 | 137 | |
| 140 | −Q: I submitted multiple versions of a patch series and it looks like a version other than the last one has been accepted, what should I do? | |
| 141 | −------------------------------------------------------------------------------------------------------------------------------------------- | |
| 142 | −A: There is no revert possible, once it is pushed out, it stays like that. | |
| 138 | +I submitted multiple versions of a patch series and it looks like a version other than the last one has been accepted, what should I do? | |
| 139 | +---------------------------------------------------------------------------------------------------------------------------------------- | |
| 140 | +There is no revert possible, once it is pushed out, it stays like that. | |
| 143 | 141 | Please send incremental versions on top of what has been merged in order to fix |
| 144 | 142 | the patches the way they would look like if your latest patch series was to be |
| 145 | 143 | merged. |
| 146 | 144 | |
| 147 | −Q: How can I tell what patches are queued up for backporting to the various stable releases? | |
| 148 | −-------------------------------------------------------------------------------------------- | |
| 149 | −A: Normally Greg Kroah-Hartman collects stable commits himself, but for | |
| 145 | +How can I tell what patches are queued up for backporting to the various stable releases? | |
| 146 | +----------------------------------------------------------------------------------------- | |
| 147 | +Normally Greg Kroah-Hartman collects stable commits himself, but for | |
| 150 | 148 | networking, Dave collects up patches he deems critical for the |
| 151 | 149 | networking subsystem, and then hands them off to Greg. |
| 152 | 150 | |
| @@ -169,11 +167,9 @@ simply clone the repo, and then git grep the mainline commit ID, e.g. · 16 unmodified lines | ||
| 169 | 167 | releases/3.9.8/ipv6-fix-possible-crashes-in-ip6_cork_release.patch |
| 170 | 168 | stable/stable-queue$ |
| 171 | 169 | |
| 172 | −Q: I see a network patch and I think it should be backported to stable. | |
| 173 | −----------------------------------------------------------------------- | |
| 174 | −Q: Should I request it via stable@vger.kernel.org like the references in | |
| 175 | −the kernel's Documentation/process/stable-kernel-rules.rst file say? | |
| 176 | −A: No, not for networking. Check the stable queues as per above first | |
| 170 | +I see a network patch and I think it should be backported to stable. Should I request it via stable@vger.kernel.org like the references in the kernel's Documentation/process/stable-kernel-rules.rst file say? | |
| 171 | +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| 172 | +No, not for networking. Check the stable queues as per above first | |
| 177 | 173 | to see if it is already queued. If not, then send a mail to netdev, |
| 178 | 174 | listing the upstream commit ID and why you think it should be a stable |
| 179 | 175 | candidate. |
| @@ -190,11 +186,9 @@ mainline, the better the odds that it is an OK candidate for stable. So · 10 unmodified lines | ||
| 190 | 186 | scrambling to request a commit be added the day after it appears should |
| 191 | 187 | be avoided. |
| 192 | 188 | |
| 193 | −Q: I have created a network patch and I think it should be backported to stable. | |
| 194 | −-------------------------------------------------------------------------------- | |
| 195 | −Q: Should I add a Cc: stable@vger.kernel.org like the references in the | |
| 196 | −kernel's Documentation/ directory say? | |
| 197 | −A: No. See above answer. In short, if you think it really belongs in | |
| 189 | +I have created a network patch and I think it should be backported to stable. Should I add a Cc: stable@vger.kernel.org like the references in the kernel's Documentation/ directory say? | |
| 190 | +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| 191 | +No. See above answer. In short, if you think it really belongs in | |
| 198 | 192 | stable, then ensure you write a decent commit log that describes who |
| 199 | 193 | gets impacted by the bug fix and how it manifests itself, and when the |
| 200 | 194 | bug was introduced. If you do that properly, then the commit will get |
| @@ -207,18 +201,18 @@ marker line as described in · 6 unmodified lines | ||
| 207 | 201 | :ref:`Documentation/process/submitting-patches.rst <the_canonical_patch_format>` |
| 208 | 202 | to temporarily embed that information into the patch that you send. |
| 209 | 203 | |
| 210 | −Q: Are all networking bug fixes backported to all stable releases? | |
| 211 | −------------------------------------------------------------------ | |
| 212 | −A: Due to capacity, Dave could only take care of the backports for the | |
| 204 | +Are all networking bug fixes backported to all stable releases? | |
| 205 | +--------------------------------------------------------------- | |
| 206 | +Due to capacity, Dave could only take care of the backports for the | |
| 213 | 207 | last two stable releases. For earlier stable releases, each stable |
| 214 | 208 | branch maintainer is supposed to take care of them. If you find any |
| 215 | 209 | patch is missing from an earlier stable branch, please notify |
| 216 | 210 | stable@vger.kernel.org with either a commit ID or a formal patch |
| 217 | 211 | backported, and CC Dave and other relevant networking developers. |
| 218 | 212 | |
| 219 | −Q: Is the comment style convention different for the networking content? | |
| 220 | −------------------------------------------------------------------------ | |
| 221 | −A: Yes, in a largely trivial way. Instead of this:: | |
| 213 | +Is the comment style convention different for the networking content? | |
| 214 | +--------------------------------------------------------------------- | |
| 215 | +Yes, in a largely trivial way. Instead of this:: | |
| 222 | 216 | |
| 223 | 217 | /* |
| 224 | 218 | * foobar blah blah blah |
| @@ -231,32 +225,30 @@ it is requested that you make it look like this:: · 6 unmodified lines | ||
| 231 | 225 | * another line of text |
| 232 | 226 | */ |
| 233 | 227 | |
| 234 | −Q: I am working in existing code that has the former comment style and not the latter. | |
| 235 | −-------------------------------------------------------------------------------------- | |
| 236 | −Q: Should I submit new code in the former style or the latter? | |
| 237 | −A: Make it the latter style, so that eventually all code in the domain | |
| 228 | +I am working in existing code that has the former comment style and not the latter. Should I submit new code in the former style or the latter? | |
| 229 | +----------------------------------------------------------------------------------------------------------------------------------------------- | |
| 230 | +Make it the latter style, so that eventually all code in the domain | |
| 238 | 231 | of netdev is of this format. |
| 239 | 232 | |
| 240 | −Q: I found a bug that might have possible security implications or similar. | |
| 241 | −--------------------------------------------------------------------------- | |
| 242 | −Q: Should I mail the main netdev maintainer off-list?** | |
| 243 | −A: No. The current netdev maintainer has consistently requested that | |
| 233 | +I found a bug that might have possible security implications or similar. Should I mail the main netdev maintainer off-list? | |
| 234 | +--------------------------------------------------------------------------------------------------------------------------- | |
| 235 | +No. The current netdev maintainer has consistently requested that | |
| 244 | 236 | people use the mailing lists and not reach out directly. If you aren't |
| 245 | 237 | OK with that, then perhaps consider mailing security@kernel.org or |
| 246 | 238 | reading about http://oss-security.openwall.org/wiki/mailing-lists/distros |
| 247 | 239 | as possible alternative mechanisms. |
| 248 | 240 | |
| 249 | −Q: What level of testing is expected before I submit my change? | |
| 250 | −--------------------------------------------------------------- | |
| 251 | −A: If your changes are against ``net-next``, the expectation is that you | |
| 241 | +What level of testing is expected before I submit my change? | |
| 242 | +------------------------------------------------------------ | |
| 243 | +If your changes are against ``net-next``, the expectation is that you | |
| 252 | 244 | have tested by layering your changes on top of ``net-next``. Ideally |
| 253 | 245 | you will have done run-time testing specific to your change, but at a |
| 254 | 246 | minimum, your changes should survive an ``allyesconfig`` and an |
| 255 | 247 | ``allmodconfig`` build without new warnings or failures. |
| 256 | 248 | |
| 257 | −Q: How do I post corresponding changes to user space components? | |
| 258 | −---------------------------------------------------------------- | |
| 259 | −A: User space code exercising kernel features should be posted | |
| 249 | +How do I post corresponding changes to user space components? | |
| 250 | +------------------------------------------------------------- | |
| 251 | +User space code exercising kernel features should be posted | |
| 260 | 252 | alongside kernel patches. This gives reviewers a chance to see |
| 261 | 253 | how any new interface is used and how well it works. |
| 262 | 254 | |
| @@ -280,9 +272,9 @@ to the mailing list, e.g.:: · 17 unmodified lines | ||
| 280 | 272 | Posting as one thread is discouraged because it confuses patchwork |
| 281 | 273 | (as of patchwork 2.2.2). |
| 282 | 274 | |
| 283 | −Q: Any other tips to help ensure my net/net-next patch gets OK'd? | |
| 284 | −----------------------------------------------------------------- | |
| 285 | −A: Attention to detail. Re-read your own work as if you were the | |
| 275 | +Any other tips to help ensure my net/net-next patch gets OK'd? | |
| 276 | +-------------------------------------------------------------- | |
| 277 | +Attention to detail. Re-read your own work as if you were the | |
| 286 | 278 | reviewer. You can start with using ``checkpatch.pl``, perhaps even with |
| 287 | 279 | the ``--strict`` flag. But do not be mindlessly robotic in doing so. |
| 288 | 280 | If your change is a bug fix, make sure your commit log indicates the |
| @@ -10,18 +10,177 @@ Introduction · 9 unmodified lines | ||
| 10 | 10 | The following is a random collection of documentation regarding |
| 11 | 11 | network devices. |
| 12 | 12 | |
| 13 | −struct net_device allocation rules | |
| 14 | −================================== | |
| 13 | +struct net_device lifetime rules | |
| 14 | +================================ | |
| 15 | 15 | Network device structures need to persist even after module is unloaded and |
| 16 | 16 | must be allocated with alloc_netdev_mqs() and friends. |
| 17 | 17 | If device has registered successfully, it will be freed on last use |
| 18 | −by free_netdev(). This is required to handle the pathologic case cleanly | |
| 19 | −(example: rmmod mydriver </sys/class/net/myeth/mtu ) | |
| 18 | +by free_netdev(). This is required to handle the pathological case cleanly | |
| 19 | +(example: ``rmmod mydriver </sys/class/net/myeth/mtu``) | |
| 20 | 20 | |
| 21 | −alloc_netdev_mqs()/alloc_netdev() reserve extra space for driver | |
| 21 | +alloc_netdev_mqs() / alloc_netdev() reserve extra space for driver | |
| 22 | 22 | private data which gets freed when the network device is freed. If |
| 23 | 23 | separately allocated data is attached to the network device |
| 24 | −(netdev_priv(dev)) then it is up to the module exit handler to free that. | |
| 24 | +(netdev_priv()) then it is up to the module exit handler to free that. | |
| 25 | + | |
| 26 | +There are two groups of APIs for registering struct net_device. | |
| 27 | +First group can be used in normal contexts where ``rtnl_lock`` is not already | |
| 28 | +held: register_netdev(), unregister_netdev(). | |
| 29 | +Second group can be used when ``rtnl_lock`` is already held: | |
| 30 | +register_netdevice(), unregister_netdevice(), free_netdevice(). | |
| 31 | + | |
| 32 | +Simple drivers | |
| 33 | +-------------- | |
| 34 | + | |
| 35 | +Most drivers (especially device drivers) handle lifetime of struct net_device | |
| 36 | +in context where ``rtnl_lock`` is not held (e.g. driver probe and remove paths). | |
| 37 | + | |
| 38 | +In that case the struct net_device registration is done using | |
| 39 | +the register_netdev(), and unregister_netdev() functions: | |
| 40 | + | |
| 41 | +.. code-block:: c | |
| 42 | + | |
| 43 | + int probe() | |
| 44 | + { | |
| 45 | + struct my_device_priv *priv; | |
| 46 | + int err; | |
| 47 | + | |
| 48 | + dev = alloc_netdev_mqs(...); | |
| 49 | + if (!dev) | |
| 50 | + return -ENOMEM; | |
| 51 | + priv = netdev_priv(dev); | |
| 52 | + | |
| 53 | + /* ... do all device setup before calling register_netdev() ... | |
| 54 | + */ | |
| 55 | + | |
| 56 | + err = register_netdev(dev); | |
| 57 | + if (err) | |
| 58 | + goto err_undo; | |
| 59 | + | |
| 60 | + /* net_device is visible to the user! */ | |
| 61 | + | |
| 62 | + err_undo: | |
| 63 | + /* ... undo the device setup ... */ | |
| 64 | + free_netdev(dev); | |
| 65 | + return err; | |
| 66 | + } | |
| 67 | + | |
| 68 | + void remove() | |
| 69 | + { | |
| 70 | + unregister_netdev(dev); | |
| 71 | + free_netdev(dev); | |
| 72 | + } | |
| 73 | + | |
| 74 | +Note that after calling register_netdev() the device is visible in the system. | |
| 75 | +Users can open it and start sending / receiving traffic immediately, | |
| 76 | +or run any other callback, so all initialization must be done prior to | |
| 77 | +registration. | |
| 78 | + | |
| 79 | +unregister_netdev() closes the device and waits for all users to be done | |
| 80 | +with it. The memory of struct net_device itself may still be referenced | |
| 81 | +by sysfs but all operations on that device will fail. | |
| 82 | + | |
| 83 | +free_netdev() can be called after unregister_netdev() returns on when | |
| 84 | +register_netdev() failed. | |
| 85 | + | |
| 86 | +Device management under RTNL | |
| 87 | +---------------------------- | |
| 88 | + | |
| 89 | +Registering struct net_device while in context which already holds | |
| 90 | +the ``rtnl_lock`` requires extra care. In those scenarios most drivers | |
| 91 | +will want to make use of struct net_device's ``needs_free_netdev`` | |
| 92 | +and ``priv_destructor`` members for freeing of state. | |
| 93 | + | |
| 94 | +Example flow of netdev handling under ``rtnl_lock``: | |
| 95 | + | |
| 96 | +.. code-block:: c | |
| 97 | + | |
| 98 | + static void my_setup(struct net_device *dev) | |
| 99 | + { | |
| 100 | + dev->needs_free_netdev = true; | |
| 101 | + } | |
| 102 | + | |
| 103 | + static void my_destructor(struct net_device *dev) | |
| 104 | + { | |
| 105 | + some_obj_destroy(priv->obj); | |
| 106 | + some_uninit(priv); | |
| 107 | + } | |
| 108 | + | |
| 109 | + int create_link() | |
| 110 | + { | |
| 111 | + struct my_device_priv *priv; | |
| 112 | + int err; | |
| 113 | + | |
| 114 | + ASSERT_RTNL(); | |
| 115 | + | |
| 116 | + dev = alloc_netdev(sizeof(*priv), "net%d", NET_NAME_UNKNOWN, my_setup); | |
| 117 | + if (!dev) | |
| 118 | + return -ENOMEM; | |
| 119 | + priv = netdev_priv(dev); | |
| 120 | + | |
| 121 | + /* Implicit constructor */ | |
| 122 | + err = some_init(priv); | |
| 123 | + if (err) | |
| 124 | + goto err_free_dev; | |
| 125 | + | |
| 126 | + priv->obj = some_obj_create(); | |
| 127 | + if (!priv->obj) { | |
| 128 | + err = -ENOMEM; | |
| 129 | + goto err_some_uninit; | |
| 130 | + } | |
| 131 | + /* End of constructor, set the destructor: */ | |
| 132 | + dev->priv_destructor = my_destructor; | |
| 133 | + | |
| 134 | + err = register_netdevice(dev); | |
| 135 | + if (err) | |
| 136 | + /* register_netdevice() calls destructor on failure */ | |
| 137 | + goto err_free_dev; | |
| 138 | + | |
| 139 | + /* If anything fails now unregister_netdevice() (or unregister_netdev()) | |
| 140 | + * will take care of calling my_destructor and free_netdev(). | |
| 141 | + */ | |
| 142 | + | |
| 143 | + return 0; | |
| 144 | + | |
| 145 | + err_some_uninit: | |
| 146 | + some_uninit(priv); | |
| 147 | + err_free_dev: | |
| 148 | + free_netdev(dev); | |
| 149 | + return err; | |
| 150 | + } | |
| 151 | + | |
| 152 | +If struct net_device.priv_destructor is set it will be called by the core | |
| 153 | +some time after unregister_netdevice(), it will also be called if | |
| 154 | +register_netdevice() fails. The callback may be invoked with or without | |
| 155 | +``rtnl_lock`` held. | |
| 156 | + | |
| 157 | +There is no explicit constructor callback, driver "constructs" the private | |
| 158 | +netdev state after allocating it and before registration. | |
| 159 | + | |
| 160 | +Setting struct net_device.needs_free_netdev makes core call free_netdevice() | |
| 161 | +automatically after unregister_netdevice() when all references to the device | |
| 162 | +are gone. It only takes effect after a successful call to register_netdevice() | |
| 163 | +so if register_netdevice() fails driver is responsible for calling | |
| 164 | +free_netdev(). | |
| 165 | + | |
| 166 | +free_netdev() is safe to call on error paths right after unregister_netdevice() | |
| 167 | +or when register_netdevice() fails. Parts of netdev (de)registration process | |
| 168 | +happen after ``rtnl_lock`` is released, therefore in those cases free_netdev() | |
| 169 | +will defer some of the processing until ``rtnl_lock`` is released. | |
| 170 | + | |
| 171 | +Devices spawned from struct rtnl_link_ops should never free the | |
| 172 | +struct net_device directly. | |
| 173 | + | |
| 174 | +.ndo_init and .ndo_uninit | |
| 175 | +~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 176 | + | |
| 177 | +``.ndo_init`` and ``.ndo_uninit`` callbacks are called during net_device | |
| 178 | +registration and de-registration, under ``rtnl_lock``. Drivers can use | |
| 179 | +those e.g. when parts of their init process need to run under ``rtnl_lock``. | |
| 180 | + | |
| 181 | +``.ndo_init`` runs before device is visible in the system, ``.ndo_uninit`` | |
| 182 | +runs during de-registering after device is closed but other subsystems | |
| 183 | +may still have outstanding references to the netdevice. | |
| 25 | 184 | |
| 26 | 185 | MTU |
| 27 | 186 | === |
| @@ -64,8 +223,8 @@ ndo_do_ioctl: · 36 unmodified lines | ||
| 64 | 223 | Context: process |
| 65 | 224 | |
| 66 | 225 | ndo_get_stats: |
| 67 | − Synchronization: dev_base_lock rwlock. | |
| 68 | − Context: nominally process, but don't sleep inside an rwlock | |
| 226 | + Synchronization: rtnl_lock() semaphore, dev_base_lock rwlock, or RCU. | |
| 227 | + Context: atomic (can't sleep under rwlock or RCU) | |
| 69 | 228 | |
| 70 | 229 | ndo_start_xmit: |
| 71 | 230 | Synchronization: __netif_tx_lock spinlock. |
| @@ -8,7 +8,7 @@ Abstract · 7 unmodified lines | ||
| 8 | 8 | ======== |
| 9 | 9 | |
| 10 | 10 | This file documents the mmap() facility available with the PACKET |
| 11 | −socket interface on 2.4/2.6/3.x kernels. This type of sockets is used for | |
| 11 | +socket interface. This type of sockets is used for | |
| 12 | 12 | |
| 13 | 13 | i) capture network traffic with utilities like tcpdump, |
| 14 | 14 | ii) transmit network traffic, or any other that needs raw |
| @@ -25,12 +25,12 @@ Please send your comments to · 10 unmodified lines | ||
| 25 | 25 | Why use PACKET_MMAP |
| 26 | 26 | =================== |
| 27 | 27 | |
| 28 | −In Linux 2.4/2.6/3.x if PACKET_MMAP is not enabled, the capture process is very | |
| 28 | +Non PACKET_MMAP capture process (plain AF_PACKET) is very | |
| 29 | 29 | inefficient. It uses very limited buffers and requires one system call to |
| 30 | 30 | capture each packet, it requires two if you want to get packet's timestamp |
| 31 | 31 | (like libpcap always does). |
| 32 | 32 | |
| 33 | −In the other hand PACKET_MMAP is very efficient. PACKET_MMAP provides a size | |
| 33 | +On the other hand PACKET_MMAP is very efficient. PACKET_MMAP provides a size | |
| 34 | 34 | configurable circular buffer mapped in user space that can be used to either |
| 35 | 35 | send or receive packets. This way reading packets just needs to wait for them, |
| 36 | 36 | most of the time there is no need to issue a single system call. Concerning |
| @@ -252,8 +252,7 @@ PACKET_MMAP setting constraints · 215 unmodified lines | ||
| 252 | 252 | |
| 253 | 253 | In kernel versions prior to 2.4.26 (for the 2.4 branch) and 2.6.5 (2.6 branch), |
| 254 | 254 | the PACKET_MMAP buffer could hold only 32768 frames in a 32 bit architecture or |
| 255 | −16384 in a 64 bit architecture. For information on these kernel versions | |
| 256 | −see http://pusa.uv.es/~ulisses/packet_mmap/packet_mmap.pre-2.4.26_2.6.5.txt | |
| 255 | +16384 in a 64 bit architecture. | |
| 257 | 256 | |
| 258 | 257 | Block size limit |
| 259 | 258 | ---------------- |
| @@ -437,7 +436,7 @@ and the following flags apply: · 177 unmodified lines | ||
| 437 | 436 | Capture process |
| 438 | 437 | ^^^^^^^^^^^^^^^ |
| 439 | 438 | |
| 440 | − from include/linux/if_packet.h | |
| 439 | +From include/linux/if_packet.h:: | |
| 441 | 440 | |
| 442 | 441 | #define TP_STATUS_COPY (1 << 1) |
| 443 | 442 | #define TP_STATUS_LOSING (1 << 2) |
| @@ -530,7 +530,10 @@ TLS device feature flags only control adding of new TLS connection · 529 unmodified lines | ||
| 530 | 530 | offloads, old connections will remain active after flags are cleared. |
| 531 | 531 | |
| 532 | 532 | TLS encryption cannot be offloaded to devices without checksum calculation |
| 533 | −offload. Hence, TLS TX device feature flag requires NETIF_F_HW_CSUM being set. | |
| 533 | +offload. Hence, TLS TX device feature flag requires TX csum offload being set. | |
| 534 | 534 | Disabling the latter implies clearing the former. Disabling TX checksum offload |
| 535 | 535 | should not affect old connections, and drivers should make sure checksum |
| 536 | 536 | calculation does not break for them. |
| 537 | +Similarly, device-offloaded TLS decryption implies doing RXCSUM. If the user | |
| 538 | +does not want to enable RX csum offload, TLS RX device feature is disabled | |
| 539 | +as well. | |
| @@ -249,10 +249,8 @@ features; most of these are found in the "kernel hacking" submenu. Several · 248 unmodified lines | ||
| 249 | 249 | of these options should be turned on for any kernel used for development or |
| 250 | 250 | testing purposes. In particular, you should turn on: |
| 251 | 251 | |
| 252 | − - ENABLE_MUST_CHECK and FRAME_WARN to get an | |
| 253 | − extra set of warnings for problems like the use of deprecated interfaces | |
| 254 | − or ignoring an important return value from a function. The output | |
| 255 | − generated by these warnings can be verbose, but one need not worry about | |
| 252 | + - FRAME_WARN to get warnings for stack frames larger than a given amount. | |
| 253 | + The output generated can be verbose, but one need not worry about | |
| 256 | 254 | warnings from other parts of the kernel. |
| 257 | 255 | |
| 258 | 256 | - DEBUG_OBJECTS will add code to track the lifetime of various objects |
| @@ -1501,7 +1501,7 @@ Module for Digigram miXart8 sound cards. · 1500 unmodified lines | ||
| 1501 | 1501 | |
| 1502 | 1502 | This module supports multiple cards. |
| 1503 | 1503 | Note: One miXart8 board will be represented as 4 alsa cards. |
| 1504 | −See MIXART.txt for details. | |
| 1504 | +See Documentation/sound/cards/mixart.rst for details. | |
| 1505 | 1505 | |
| 1506 | 1506 | When the driver is compiled as a module and the hotplug firmware |
| 1507 | 1507 | is supported, the firmware data is loaded via hotplug automatically. |
| @@ -71,7 +71,7 @@ core/oss · 70 unmodified lines | ||
| 71 | 71 | The codes for PCM and mixer OSS emulation modules are stored in this |
| 72 | 72 | directory. The rawmidi OSS emulation is included in the ALSA rawmidi |
| 73 | 73 | code since it's quite small. The sequencer code is stored in |
| 74 | −``core/seq/oss`` directory (see `below <#core-seq-oss>`__). | |
| 74 | +``core/seq/oss`` directory (see `below <core/seq/oss_>`__). | |
| 75 | 75 | |
| 76 | 76 | core/seq |
| 77 | 77 | ~~~~~~~~ |
| @@ -382,7 +382,7 @@ where ``enable[dev]`` is the module option. · 304 unmodified lines | ||
| 382 | 382 | Each time the ``probe`` callback is called, check the availability of |
| 383 | 383 | the device. If not available, simply increment the device index and |
| 384 | 384 | returns. dev will be incremented also later (`step 7 |
| 385 | −<#set-the-pci-driver-data-and-return-zero>`__). | |
| 385 | +<7) Set the PCI driver data and return zero._>`__). | |
| 386 | 386 | |
| 387 | 387 | 2) Create a card instance |
| 388 | 388 | ~~~~~~~~~~~~~~~~~~~~~~~~~ |
| @@ -450,10 +450,10 @@ field contains the information shown in ``/proc/asound/cards``. · 61 unmodified lines | ||
| 450 | 450 | 5) Create other components, such as mixer, MIDI, etc. |
| 451 | 451 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 452 | 452 | |
| 453 | −Here you define the basic components such as `PCM <#PCM-Interface>`__, | |
| 454 | −mixer (e.g. `AC97 <#API-for-AC97-Codec>`__), MIDI (e.g. | |
| 455 | −`MPU-401 <#MIDI-MPU401-UART-Interface>`__), and other interfaces. | |
| 456 | −Also, if you want a `proc file <#Proc-Interface>`__, define it here, | |
| 453 | +Here you define the basic components such as `PCM <PCM Interface_>`__, | |
| 454 | +mixer (e.g. `AC97 <API for AC97 Codec_>`__), MIDI (e.g. | |
| 455 | +`MPU-401 <MIDI (MPU401-UART) Interface_>`__), and other interfaces. | |
| 456 | +Also, if you want a `proc file <Proc Interface_>`__, define it here, | |
| 457 | 457 | too. |
| 458 | 458 | |
| 459 | 459 | 6) Register the card instance. |
| @@ -941,7 +941,7 @@ The allocation of an interrupt source is done like this: · 481 unmodified lines | ||
| 941 | 941 | chip->irq = pci->irq; |
| 942 | 942 | |
| 943 | 943 | where :c:func:`snd_mychip_interrupt()` is the interrupt handler |
| 944 | −defined `later <#pcm-interface-interrupt-handler>`__. Note that | |
| 944 | +defined `later <PCM Interrupt Handler_>`__. Note that | |
| 945 | 945 | ``chip->irq`` should be defined only when :c:func:`request_irq()` |
| 946 | 946 | succeeded. |
| 947 | 947 | |
| @@ -3104,7 +3104,7 @@ processing the output stream in the irq handler. · 2156 unmodified lines | ||
| 3104 | 3104 | |
| 3105 | 3105 | If the MPU-401 interface shares its interrupt with the other logical |
| 3106 | 3106 | devices on the card, set ``MPU401_INFO_IRQ_HOOK`` (see |
| 3107 | −`below <#MIDI-Interrupt-Handler>`__). | |
| 3107 | +`below <MIDI Interrupt Handler_>`__). | |
| 3108 | 3108 | |
| 3109 | 3109 | Usually, the port address corresponds to the command port and port + 1 |
| 3110 | 3110 | corresponds to the data port. If not, you may change the ``cport`` |
| @@ -360,10 +360,9 @@ since the last call to this ioctl. Bit 0 is the first page in the · 359 unmodified lines | ||
| 360 | 360 | memory slot. Ensure the entire structure is cleared to avoid padding |
| 361 | 361 | issues. |
| 362 | 362 | |
| 363 | −If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 specifies | |
| 364 | −the address space for which you want to return the dirty bitmap. | |
| 365 | −They must be less than the value that KVM_CHECK_EXTENSION returns for | |
| 366 | −the KVM_CAP_MULTI_ADDRESS_SPACE capability. | |
| 363 | +If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 of slot field specifies | |
| 364 | +the address space for which you want to return the dirty bitmap. See | |
| 365 | +KVM_SET_USER_MEMORY_REGION for details on the usage of slot field. | |
| 367 | 366 | |
| 368 | 367 | The bits in the dirty bitmap are cleared before the ioctl returns, unless |
| 369 | 368 | KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is enabled. For more information, |
| @@ -392,9 +391,14 @@ This ioctl is obsolete and has been removed. · 22 unmodified lines | ||
| 392 | 391 | |
| 393 | 392 | Errors: |
| 394 | 393 | |
| 395 | − ===== ============================= | |
| 394 | + ======= ============================================================== | |
| 396 | 395 | EINTR an unmasked signal is pending |
| 397 | − ===== ============================= | |
| 396 | + ENOEXEC the vcpu hasn't been initialized or the guest tried to execute | |
| 397 | + instructions from device memory (arm64) | |
| 398 | + ENOSYS data abort outside memslots with no syndrome info and | |
| 399 | + KVM_CAP_ARM_NISV_TO_USER not enabled (arm64) | |
| 400 | + EPERM SVE feature set but not finalized (arm64) | |
| 401 | + ======= ============================================================== | |
| 398 | 402 | |
| 399 | 403 | This ioctl is used to run a guest virtual cpu. While there are no |
| 400 | 404 | explicit parameters, there is an implicit parameter block that can be |
| @@ -1276,6 +1280,9 @@ field userspace_addr, which must point at user addressable memory for · 875 unmodified lines | ||
| 1276 | 1280 | the entire memory slot size. Any object may back this memory, including |
| 1277 | 1281 | anonymous memory, ordinary files, and hugetlbfs. |
| 1278 | 1282 | |
| 1283 | +On architectures that support a form of address tagging, userspace_addr must | |
| 1284 | +be an untagged address. | |
| 1285 | + | |
| 1279 | 1286 | It is recommended that the lower 21 bits of guest_phys_addr and userspace_addr |
| 1280 | 1287 | be identical. This allows large pages in the guest to be backed by large |
| 1281 | 1288 | pages in the host. |
| @@ -1328,7 +1335,7 @@ documentation when it pops into existence). · 46 unmodified lines | ||
| 1328 | 1335 | |
| 1329 | 1336 | :Capability: KVM_CAP_ENABLE_CAP_VM |
| 1330 | 1337 | :Architectures: all |
| 1331 | −:Type: vcpu ioctl | |
| 1338 | +:Type: vm ioctl | |
| 1332 | 1339 | :Parameters: struct kvm_enable_cap (in) |
| 1333 | 1340 | :Returns: 0 on success; -1 on error |
| 1334 | 1341 | |
| @@ -4427,7 +4434,7 @@ to I/O ports. · 3092 unmodified lines | ||
| 4427 | 4434 | :Capability: KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 |
| 4428 | 4435 | :Architectures: x86, arm, arm64, mips |
| 4429 | 4436 | :Type: vm ioctl |
| 4430 | −:Parameters: struct kvm_dirty_log (in) | |
| 4437 | +:Parameters: struct kvm_clear_dirty_log (in) | |
| 4431 | 4438 | :Returns: 0 on success, -1 on error |
| 4432 | 4439 | |
| 4433 | 4440 | :: |
| @@ -4454,10 +4461,9 @@ in KVM's dirty bitmap, and dirty tracking is re-enabled for that page · 20 unmodified lines | ||
| 4454 | 4461 | (for example via write-protection, or by clearing the dirty bit in |
| 4455 | 4462 | a page table entry). |
| 4456 | 4463 | |
| 4457 | −If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 specifies | |
| 4458 | −the address space for which you want to return the dirty bitmap. | |
| 4459 | −They must be less than the value that KVM_CHECK_EXTENSION returns for | |
| 4460 | −the KVM_CAP_MULTI_ADDRESS_SPACE capability. | |
| 4464 | +If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 of slot field specifies | |
| 4465 | +the address space for which you want to clear the dirty status. See | |
| 4466 | +KVM_SET_USER_MEMORY_REGION for details on the usage of slot field. | |
| 4461 | 4467 | |
| 4462 | 4468 | This ioctl is mostly useful when KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 |
| 4463 | 4469 | is enabled; for more information, see the description of the capability. |
| @@ -37,8 +37,10 @@ call L2. · 36 unmodified lines | ||
| 37 | 37 | Running nested VMX |
| 38 | 38 | ------------------ |
| 39 | 39 | |
| 40 | −The nested VMX feature is disabled by default. It can be enabled by giving | |
| 41 | −the "nested=1" option to the kvm-intel module. | |
| 40 | +The nested VMX feature is enabled by default since Linux kernel v4.20. For | |
| 41 | +older Linux kernel, it can be enabled by giving the "nested=1" option to the | |
| 42 | +kvm-intel module. | |
| 43 | + | |
| 42 | 44 | |
| 43 | 45 | No modifications are required to user space (qemu). However, qemu's default |
| 44 | 46 | emulated CPU type (qemu64) does not list the "VMX" CPU feature, so it must be |
| @@ -74,7 +74,7 @@ few: · 73 unmodified lines | ||
| 74 | 74 | Enabling "nested" (x86) |
| 75 | 75 | ----------------------- |
| 76 | 76 | |
| 77 | −From Linux kernel v4.19 onwards, the ``nested`` KVM parameter is enabled | |
| 77 | +From Linux kernel v4.20 onwards, the ``nested`` KVM parameter is enabled | |
| 78 | 78 | by default for Intel and AMD. (Though your Linux distribution might |
| 79 | 79 | override this default.) |
| 80 | 80 | |
| @@ -203,8 +203,8 @@ F: include/uapi/linux/nl80211.h · 202 unmodified lines | ||
| 203 | 203 | F: net/wireless/ |
| 204 | 204 | |
| 205 | 205 | 8169 10/100/1000 GIGABIT ETHERNET DRIVER |
| 206 | −M: Realtek linux nic maintainers <nic_swsd@realtek.com> | |
| 207 | 206 | M: Heiner Kallweit <hkallweit1@gmail.com> |
| 207 | +M: nic_swsd@realtek.com | |
| 208 | 208 | L: netdev@vger.kernel.org |
| 209 | 209 | S: Maintained |
| 210 | 210 | F: drivers/net/ethernet/realtek/r8169* |
| @@ -820,7 +820,6 @@ M: Netanel Belgazal <netanel@amazon.com> · 609 unmodified lines | ||
| 820 | 820 | M: Arthur Kiyanovski <akiyano@amazon.com> |
| 821 | 821 | R: Guy Tzalik <gtzalik@amazon.com> |
| 822 | 822 | R: Saeed Bishara <saeedb@amazon.com> |
| 823 | −R: Zorik Machulsky <zorik@amazon.com> | |
| 824 | 823 | L: netdev@vger.kernel.org |
| 825 | 824 | S: Supported |
| 826 | 825 | F: Documentation/networking/device_drivers/ethernet/amazon/ena.rst |
| @@ -907,7 +906,7 @@ AMD KFD · 80 unmodified lines | ||
| 907 | 906 | M: Felix Kuehling <Felix.Kuehling@amd.com> |
| 908 | 907 | L: amd-gfx@lists.freedesktop.org |
| 909 | 908 | S: Supported |
| 910 | −T: git git://people.freedesktop.org/~agd5f/linux | |
| 909 | +T: git https://gitlab.freedesktop.org/agd5f/linux.git | |
| 911 | 910 | F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd*.[ch] |
| 912 | 911 | F: drivers/gpu/drm/amd/amdkfd/ |
| 913 | 912 | F: drivers/gpu/drm/amd/include/cik_structs.h |
| @@ -2119,7 +2118,7 @@ N: atmel · 1205 unmodified lines | ||
| 2119 | 2118 | ARM/Microchip Sparx5 SoC support |
| 2120 | 2119 | M: Lars Povlsen <lars.povlsen@microchip.com> |
| 2121 | 2120 | M: Steen Hegelund <Steen.Hegelund@microchip.com> |
| 2122 | −M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | |
| 2121 | +M: UNGLinuxDriver@microchip.com | |
| 2123 | 2122 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 2124 | 2123 | S: Supported |
| 2125 | 2124 | T: git git://github.com/microchip-ung/linux-upstream.git |
| @@ -2617,8 +2616,8 @@ S: Maintained · 491 unmodified lines | ||
| 2617 | 2616 | F: drivers/power/reset/keystone-reset.c |
| 2618 | 2617 | |
| 2619 | 2618 | ARM/TEXAS INSTRUMENTS K3 ARCHITECTURE |
| 2620 | −M: Tero Kristo <t-kristo@ti.com> | |
| 2621 | 2619 | M: Nishanth Menon <nm@ti.com> |
| 2620 | +M: Tero Kristo <kristo@kernel.org> | |
| 2622 | 2621 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 2623 | 2622 | S: Supported |
| 2624 | 2623 | F: Documentation/devicetree/bindings/arm/ti/k3.yaml |
| @@ -2942,7 +2941,6 @@ S: Maintained · 317 unmodified lines | ||
| 2942 | 2941 | F: drivers/hwmon/asus_atk0110.c |
| 2943 | 2942 | |
| 2944 | 2943 | ATLX ETHERNET DRIVERS |
| 2945 | −M: Jay Cliburn <jcliburn@gmail.com> | |
| 2946 | 2944 | M: Chris Snook <chris.snook@gmail.com> |
| 2947 | 2945 | L: netdev@vger.kernel.org |
| 2948 | 2946 | S: Maintained |
| @@ -3241,6 +3239,7 @@ L: netdev@vger.kernel.org · 292 unmodified lines | ||
| 3241 | 3239 | S: Supported |
| 3242 | 3240 | W: http://sourceforge.net/projects/bonding/ |
| 3243 | 3241 | F: drivers/net/bonding/ |
| 3242 | +F: include/net/bonding.h | |
| 3244 | 3243 | F: include/uapi/linux/if_bonding.h |
| 3245 | 3244 | |
| 3246 | 3245 | BOSCH SENSORTEC BMA400 ACCELEROMETER IIO DRIVER |
| @@ -3336,7 +3335,7 @@ F: arch/riscv/net/ · 89 unmodified lines | ||
| 3336 | 3335 | X: arch/riscv/net/bpf_jit_comp64.c |
| 3337 | 3336 | |
| 3338 | 3337 | BPF JIT for RISC-V (64-bit) |
| 3339 | −M: Björn Töpel <bjorn.topel@gmail.com> | |
| 3338 | +M: Björn Töpel <bjorn@kernel.org> | |
| 3340 | 3339 | L: netdev@vger.kernel.org |
| 3341 | 3340 | L: bpf@vger.kernel.org |
| 3342 | 3341 | S: Maintained |
| @@ -3413,7 +3412,7 @@ F: Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml · 70 unmodified lines | ||
| 3413 | 3412 | F: drivers/pci/controller/pcie-brcmstb.c |
| 3414 | 3413 | F: drivers/staging/vc04_services |
| 3415 | 3414 | N: bcm2711 |
| 3416 | −N: bcm2835 | |
| 3415 | +N: bcm283* | |
| 3417 | 3416 | |
| 3418 | 3417 | BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITECTURE |
| 3419 | 3418 | M: Florian Fainelli <f.fainelli@gmail.com> |
| @@ -3556,7 +3555,7 @@ S: Supported · 136 unmodified lines | ||
| 3556 | 3555 | F: drivers/net/ethernet/broadcom/bnxt/ |
| 3557 | 3556 | |
| 3558 | 3557 | BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER |
| 3559 | −M: Arend van Spriel <arend.vanspriel@broadcom.com> | |
| 3558 | +M: Arend van Spriel <aspriel@gmail.com> | |
| 3560 | 3559 | M: Franky Lin <franky.lin@broadcom.com> |
| 3561 | 3560 | M: Hante Meuleman <hante.meuleman@broadcom.com> |
| 3562 | 3561 | M: Chi-hsien Lin <chi-hsien.lin@infineon.com> |
| @@ -3881,9 +3880,9 @@ F: Documentation/devicetree/bindings/mtd/cadence-nand-controller.txt · 318 unmodified lines | ||
| 3881 | 3880 | F: drivers/mtd/nand/raw/cadence-nand-controller.c |
| 3882 | 3881 | |
| 3883 | 3882 | CADENCE USB3 DRD IP DRIVER |
| 3884 | −M: Peter Chen <peter.chen@nxp.com> | |
| 3883 | +M: Peter Chen <peter.chen@kernel.org> | |
| 3885 | 3884 | M: Pawel Laszczak <pawell@cadence.com> |
| 3886 | −M: Roger Quadros <rogerq@ti.com> | |
| 3885 | +R: Roger Quadros <rogerq@kernel.org> | |
| 3887 | 3886 | R: Aswath Govindraju <a-govindraju@ti.com> |
| 3888 | 3887 | L: linux-usb@vger.kernel.org |
| 3889 | 3888 | S: Maintained |
| @@ -3961,7 +3960,7 @@ F: net/can/ · 71 unmodified lines | ||
| 3961 | 3960 | CAN-J1939 NETWORK LAYER |
| 3962 | 3961 | M: Robin van der Gracht <robin@protonic.nl> |
| 3963 | 3962 | M: Oleksij Rempel <o.rempel@pengutronix.de> |
| 3964 | −R: Pengutronix Kernel Team <kernel@pengutronix.de> | |
| 3963 | +R: kernel@pengutronix.de | |
| 3965 | 3964 | L: linux-can@vger.kernel.org |
| 3966 | 3965 | S: Maintained |
| 3967 | 3966 | F: Documentation/networking/j1939.rst |
| @@ -4163,7 +4162,7 @@ S: Maintained · 195 unmodified lines | ||
| 4163 | 4162 | F: Documentation/translations/zh_CN/ |
| 4164 | 4163 | |
| 4165 | 4164 | CHIPIDEA USB HIGH SPEED DUAL ROLE CONTROLLER |
| 4166 | −M: Peter Chen <Peter.Chen@nxp.com> | |
| 4165 | +M: Peter Chen <peter.chen@kernel.org> | |
| 4167 | 4166 | L: linux-usb@vger.kernel.org |
| 4168 | 4167 | S: Maintained |
| 4169 | 4168 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git |
| @@ -4305,7 +4304,7 @@ S: Maintained · 135 unmodified lines | ||
| 4305 | 4304 | F: .clang-format |
| 4306 | 4305 | |
| 4307 | 4306 | CLANG/LLVM BUILD SUPPORT |
| 4308 | −M: Nathan Chancellor <natechancellor@gmail.com> | |
| 4307 | +M: Nathan Chancellor <nathan@kernel.org> | |
| 4309 | 4308 | M: Nick Desaulniers <ndesaulniers@google.com> |
| 4310 | 4309 | L: clang-built-linux@googlegroups.com |
| 4311 | 4310 | S: Supported |
| @@ -4313,7 +4312,9 @@ W: https://clangbuiltlinux.github.io/ · 1 unmodified line | ||
| 4313 | 4312 | B: https://github.com/ClangBuiltLinux/linux/issues |
| 4314 | 4313 | C: irc://chat.freenode.net/clangbuiltlinux |
| 4315 | 4314 | F: Documentation/kbuild/llvm.rst |
| 4315 | +F: include/linux/compiler-clang.h | |
| 4316 | 4316 | F: scripts/clang-tools/ |
| 4317 | +F: scripts/clang-version.sh | |
| 4317 | 4318 | F: scripts/lld-version.sh |
| 4318 | 4319 | K: \b(?i:clang|llvm)\b |
| 4319 | 4320 | |
| @@ -4467,7 +4468,7 @@ F: include/linux/console* · 147 unmodified lines | ||
| 4467 | 4468 | |
| 4468 | 4469 | CONTROL GROUP (CGROUP) |
| 4469 | 4470 | M: Tejun Heo <tj@kernel.org> |
| 4470 | −M: Li Zefan <lizefan@huawei.com> | |
| 4471 | +M: Zefan Li <lizefan.x@bytedance.com> | |
| 4471 | 4472 | M: Johannes Weiner <hannes@cmpxchg.org> |
| 4472 | 4473 | L: cgroups@vger.kernel.org |
| 4473 | 4474 | S: Maintained |
| @@ -4491,11 +4492,9 @@ F: block/blk-throttle.c · 17 unmodified lines | ||
| 4491 | 4492 | F: include/linux/blk-cgroup.h |
| 4492 | 4493 | |
| 4493 | 4494 | CONTROL GROUP - CPUSET |
| 4494 | −M: Li Zefan <lizefan@huawei.com> | |
| 4495 | +M: Zefan Li <lizefan.x@bytedance.com> | |
| 4495 | 4496 | L: cgroups@vger.kernel.org |
| 4496 | 4497 | S: Maintained |
| 4497 | −W: http://www.bullopensource.org/cpuset/ | |
| 4498 | −W: http://oss.sgi.com/projects/cpusets/ | |
| 4499 | 4498 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git |
| 4500 | 4499 | F: Documentation/admin-guide/cgroup-v1/cpusets.rst |
| 4501 | 4500 | F: include/linux/cpuset.h |
| @@ -4922,9 +4921,8 @@ F: Documentation/scsi/dc395x.rst · 420 unmodified lines | ||
| 4922 | 4921 | F: drivers/scsi/dc395x.* |
| 4923 | 4922 | |
| 4924 | 4923 | DCCP PROTOCOL |
| 4925 | −M: Gerrit Renker <gerrit@erg.abdn.ac.uk> | |
| 4926 | 4924 | L: dccp@vger.kernel.org |
| 4927 | −S: Maintained | |
| 4925 | +S: Orphan | |
| 4928 | 4926 | W: http://www.linuxfoundation.org/collaborate/workgroups/networking/dccp |
| 4929 | 4927 | F: include/linux/dccp.h |
| 4930 | 4928 | F: include/linux/tfrc.h |
| @@ -6474,9 +6472,9 @@ S: Maintained · 1543 unmodified lines | ||
| 6474 | 6472 | F: drivers/edac/skx_*.[ch] |
| 6475 | 6473 | |
| 6476 | 6474 | EDAC-TI |
| 6477 | −M: Tero Kristo <t-kristo@ti.com> | |
| 6475 | +M: Tero Kristo <kristo@kernel.org> | |
| 6478 | 6476 | L: linux-edac@vger.kernel.org |
| 6479 | −S: Maintained | |
| 6477 | +S: Odd Fixes | |
| 6480 | 6478 | F: drivers/edac/ti_edac.c |
| 6481 | 6479 | |
| 6482 | 6480 | EDIROL UA-101/UA-1000 DRIVER |
| @@ -7363,7 +7361,6 @@ L: linux-hardening@vger.kernel.org · 880 unmodified lines | ||
| 7363 | 7361 | S: Maintained |
| 7364 | 7362 | F: Documentation/kbuild/gcc-plugins.rst |
| 7365 | 7363 | F: scripts/Makefile.gcc-plugins |
| 7366 | −F: scripts/gcc-plugin.sh | |
| 7367 | 7364 | F: scripts/gcc-plugins/ |
| 7368 | 7365 | |
| 7369 | 7366 | GCOV BASED KERNEL PROFILING |
| @@ -8435,11 +8432,8 @@ F: drivers/i3c/ · 1065 unmodified lines | ||
| 8435 | 8432 | F: include/linux/i3c/ |
| 8436 | 8433 | |
| 8437 | 8434 | IA64 (Itanium) PLATFORM |
| 8438 | −M: Tony Luck <tony.luck@intel.com> | |
| 8439 | −M: Fenghua Yu <fenghua.yu@intel.com> | |
| 8440 | 8435 | L: linux-ia64@vger.kernel.org |
| 8441 | −S: Odd Fixes | |
| 8442 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux.git | |
| 8436 | +S: Orphan | |
| 8443 | 8437 | F: Documentation/ia64/ |
| 8444 | 8438 | F: arch/ia64/ |
| 8445 | 8439 | |
| @@ -9240,7 +9234,7 @@ F: tools/testing/selftests/sgx/* · 794 unmodified lines | ||
| 9240 | 9234 | K: \bSGX_ |
| 9241 | 9235 | |
| 9242 | 9236 | INTERCONNECT API |
| 9243 | −M: Georgi Djakov <georgi.djakov@linaro.org> | |
| 9237 | +M: Georgi Djakov <djakov@kernel.org> | |
| 9244 | 9238 | L: linux-pm@vger.kernel.org |
| 9245 | 9239 | S: Maintained |
| 9246 | 9240 | F: Documentation/devicetree/bindings/interconnect/ |
| @@ -9273,7 +9267,7 @@ F: drivers/net/ethernet/sgi/ioc3-eth.c · 26 unmodified lines | ||
| 9273 | 9267 | |
| 9274 | 9268 | IOMAP FILESYSTEM LIBRARY |
| 9275 | 9269 | M: Christoph Hellwig <hch@infradead.org> |
| 9276 | −M: Darrick J. Wong <darrick.wong@oracle.com> | |
| 9270 | +M: Darrick J. Wong <djwong@kernel.org> | |
| 9277 | 9271 | M: linux-xfs@vger.kernel.org |
| 9278 | 9272 | M: linux-fsdevel@vger.kernel.org |
| 9279 | 9273 | L: linux-xfs@vger.kernel.org |
| @@ -9327,7 +9321,6 @@ W: http://www.adaptec.com/ · 47 unmodified lines | ||
| 9327 | 9321 | F: drivers/scsi/ips* |
| 9328 | 9322 | |
| 9329 | 9323 | IPVS |
| 9330 | −M: Wensong Zhang <wensong@linux-vs.org> | |
| 9331 | 9324 | M: Simon Horman <horms@verge.net.au> |
| 9332 | 9325 | M: Julian Anastasov <ja@ssi.bg> |
| 9333 | 9326 | L: netdev@vger.kernel.org |
| @@ -9564,16 +9557,18 @@ F: Documentation/hwmon/k8temp.rst · 230 unmodified lines | ||
| 9564 | 9557 | F: drivers/hwmon/k8temp.c |
| 9565 | 9558 | |
| 9566 | 9559 | KASAN |
| 9567 | −M: Andrey Ryabinin <aryabinin@virtuozzo.com> | |
| 9560 | +M: Andrey Ryabinin <ryabinin.a.a@gmail.com> | |
| 9568 | 9561 | R: Alexander Potapenko <glider@google.com> |
| 9562 | +R: Andrey Konovalov <andreyknvl@gmail.com> | |
| 9569 | 9563 | R: Dmitry Vyukov <dvyukov@google.com> |
| 9570 | 9564 | L: kasan-dev@googlegroups.com |
| 9571 | 9565 | S: Maintained |
| 9572 | 9566 | F: Documentation/dev-tools/kasan.rst |
| 9573 | −F: arch/*/include/asm/kasan.h | |
| 9567 | +F: arch/*/include/asm/*kasan.h | |
| 9574 | 9568 | F: arch/*/mm/kasan_init* |
| 9575 | 9569 | F: include/linux/kasan*.h |
| 9576 | −F: lib/test_kasan.c | |
| 9570 | +F: lib/Kconfig.kasan | |
| 9571 | +F: lib/test_kasan*.c | |
| 9577 | 9572 | F: mm/kasan/ |
| 9578 | 9573 | F: scripts/Makefile.kasan |
| 9579 | 9574 | |
| @@ -9588,7 +9583,7 @@ F: scripts/kconfig/ · 8 unmodified lines | ||
| 9588 | 9583 | |
| 9589 | 9584 | KCOV |
| 9590 | 9585 | R: Dmitry Vyukov <dvyukov@google.com> |
| 9591 | −R: Andrey Konovalov <andreyknvl@google.com> | |
| 9586 | +R: Andrey Konovalov <andreyknvl@gmail.com> | |
| 9592 | 9587 | L: kasan-dev@googlegroups.com |
| 9593 | 9588 | S: Maintained |
| 9594 | 9589 | F: Documentation/dev-tools/kcov.rst |
| @@ -9776,7 +9771,7 @@ F: tools/testing/selftests/kvm/s390x/ · 181 unmodified lines | ||
| 9776 | 9771 | |
| 9777 | 9772 | KERNEL VIRTUAL MACHINE FOR X86 (KVM/x86) |
| 9778 | 9773 | M: Paolo Bonzini <pbonzini@redhat.com> |
| 9779 | −R: Sean Christopherson <sean.j.christopherson@intel.com> | |
| 9774 | +R: Sean Christopherson <seanjc@google.com> | |
| 9780 | 9775 | R: Vitaly Kuznetsov <vkuznets@redhat.com> |
| 9781 | 9776 | R: Wanpeng Li <wanpengli@tencent.com> |
| 9782 | 9777 | R: Jim Mattson <jmattson@google.com> |
| @@ -10260,7 +10255,6 @@ S: Supported · 477 unmodified lines | ||
| 10260 | 10255 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev |
| 10261 | 10256 | F: Documentation/atomic_bitops.txt |
| 10262 | 10257 | F: Documentation/atomic_t.txt |
| 10263 | −F: Documentation/core-api/atomic_ops.rst | |
| 10264 | 10258 | F: Documentation/core-api/refcount-vs-atomic.rst |
| 10265 | 10259 | F: Documentation/litmus-tests/ |
| 10266 | 10260 | F: Documentation/memory-barriers.txt |
| @@ -10847,7 +10841,7 @@ F: drivers/media/radio/radio-maxiradio* · 580 unmodified lines | ||
| 10847 | 10841 | |
| 10848 | 10842 | MCAN MMIO DEVICE DRIVER |
| 10849 | 10843 | M: Dan Murphy <dmurphy@ti.com> |
| 10850 | −M: Sriram Dash <sriram.dash@samsung.com> | |
| 10844 | +M: Pankaj Sharma <pankj.sharma@samsung.com> | |
| 10851 | 10845 | L: linux-can@vger.kernel.org |
| 10852 | 10846 | S: Maintained |
| 10853 | 10847 | F: Documentation/devicetree/bindings/net/can/bosch,m_can.yaml |
| @@ -11667,7 +11661,7 @@ F: drivers/media/platform/atmel/atmel-isi.h · 813 unmodified lines | ||
| 11667 | 11661 | |
| 11668 | 11662 | MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER |
| 11669 | 11663 | M: Woojung Huh <woojung.huh@microchip.com> |
| 11670 | −M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | |
| 11664 | +M: UNGLinuxDriver@microchip.com | |
| 11671 | 11665 | L: netdev@vger.kernel.org |
| 11672 | 11666 | S: Maintained |
| 11673 | 11667 | F: Documentation/devicetree/bindings/net/dsa/microchip,ksz.yaml |
| @@ -11677,7 +11671,7 @@ F: net/dsa/tag_ksz.c · 3 unmodified lines | ||
| 11677 | 11671 | |
| 11678 | 11672 | MICROCHIP LAN743X ETHERNET DRIVER |
| 11679 | 11673 | M: Bryan Whitehead <bryan.whitehead@microchip.com> |
| 11680 | −M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | |
| 11674 | +M: UNGLinuxDriver@microchip.com | |
| 11681 | 11675 | L: netdev@vger.kernel.org |
| 11682 | 11676 | S: Maintained |
| 11683 | 11677 | F: drivers/net/ethernet/microchip/lan743x_* |
| @@ -11771,7 +11765,7 @@ F: drivers/net/wireless/microchip/wilc1000/ · 87 unmodified lines | ||
| 11771 | 11765 | |
| 11772 | 11766 | MICROSEMI MIPS SOCS |
| 11773 | 11767 | M: Alexandre Belloni <alexandre.belloni@bootlin.com> |
| 11774 | −M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | |
| 11768 | +M: UNGLinuxDriver@microchip.com | |
| 11775 | 11769 | L: linux-mips@vger.kernel.org |
| 11776 | 11770 | S: Supported |
| 11777 | 11771 | F: Documentation/devicetree/bindings/mips/mscc.txt |
| @@ -12418,8 +12412,8 @@ F: tools/testing/selftests/net/ipsec.c · 640 unmodified lines | ||
| 12418 | 12412 | |
| 12419 | 12413 | NETWORKING [IPv4/IPv6] |
| 12420 | 12414 | M: "David S. Miller" <davem@davemloft.net> |
| 12421 | −M: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> | |
| 12422 | 12415 | M: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> |
| 12416 | +M: David Ahern <dsahern@kernel.org> | |
| 12423 | 12417 | L: netdev@vger.kernel.org |
| 12424 | 12418 | S: Maintained |
| 12425 | 12419 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git |
| @@ -12475,7 +12469,6 @@ F: net/ipv6/tcp*.c · 49 unmodified lines | ||
| 12475 | 12469 | |
| 12476 | 12470 | NETWORKING [TLS] |
| 12477 | 12471 | M: Boris Pismenny <borisp@nvidia.com> |
| 12478 | −M: Aviad Yehezkel <aviadye@nvidia.com> | |
| 12479 | 12472 | M: John Fastabend <john.fastabend@gmail.com> |
| 12480 | 12473 | M: Daniel Borkmann <daniel@iogearbox.net> |
| 12481 | 12474 | M: Jakub Kicinski <kuba@kernel.org> |
| @@ -12825,10 +12818,10 @@ F: tools/objtool/ · 343 unmodified lines | ||
| 12825 | 12818 | F: include/linux/objtool.h |
| 12826 | 12819 | |
| 12827 | 12820 | OCELOT ETHERNET SWITCH DRIVER |
| 12828 | −M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | |
| 12829 | 12821 | M: Vladimir Oltean <vladimir.oltean@nxp.com> |
| 12830 | 12822 | M: Claudiu Manoil <claudiu.manoil@nxp.com> |
| 12831 | 12823 | M: Alexandre Belloni <alexandre.belloni@bootlin.com> |
| 12824 | +M: UNGLinuxDriver@microchip.com | |
| 12832 | 12825 | L: netdev@vger.kernel.org |
| 12833 | 12826 | S: Supported |
| 12834 | 12827 | F: drivers/net/dsa/ocelot/* |
| @@ -12850,7 +12843,7 @@ F: include/misc/ocxl* · 15 unmodified lines | ||
| 12850 | 12843 | F: include/uapi/misc/ocxl.h |
| 12851 | 12844 | |
| 12852 | 12845 | OMAP AUDIO SUPPORT |
| 12853 | −M: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 12846 | +M: Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 12854 | 12847 | M: Jarkko Nikula <jarkko.nikula@bitmer.com> |
| 12855 | 12848 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 12856 | 12849 | L: linux-omap@vger.kernel.org |
| @@ -13890,7 +13883,7 @@ F: drivers/platform/x86/peaq-wmi.c · 1033 unmodified lines | ||
| 13890 | 13883 | |
| 13891 | 13884 | PENSANDO ETHERNET DRIVERS |
| 13892 | 13885 | M: Shannon Nelson <snelson@pensando.io> |
| 13893 | −M: Pensando Drivers <drivers@pensando.io> | |
| 13886 | +M: drivers@pensando.io | |
| 13894 | 13887 | L: netdev@vger.kernel.org |
| 13895 | 13888 | S: Supported |
| 13896 | 13889 | F: Documentation/networking/device_drivers/ethernet/pensando/ionic.rst |
| @@ -14512,10 +14505,18 @@ S: Supported · 615 unmodified lines | ||
| 14512 | 14505 | F: drivers/crypto/qat/ |
| 14513 | 14506 | |
| 14514 | 14507 | QCOM AUDIO (ASoC) DRIVERS |
| 14515 | −M: Patrick Lai <plai@codeaurora.org> | |
| 14508 | +M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | |
| 14516 | 14509 | M: Banajit Goswami <bgoswami@codeaurora.org> |
| 14517 | 14510 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 14518 | 14511 | S: Supported |
| 14512 | +F: sound/soc/codecs/lpass-va-macro.c | |
| 14513 | +F: sound/soc/codecs/lpass-wsa-macro.* | |
| 14514 | +F: sound/soc/codecs/msm8916-wcd-analog.c | |
| 14515 | +F: sound/soc/codecs/msm8916-wcd-digital.c | |
| 14516 | +F: sound/soc/codecs/wcd9335.* | |
| 14517 | +F: sound/soc/codecs/wcd934x.c | |
| 14518 | +F: sound/soc/codecs/wcd-clsh-v2.* | |
| 14519 | +F: sound/soc/codecs/wsa881x.c | |
| 14519 | 14520 | F: sound/soc/qcom/ |
| 14520 | 14521 | |
| 14521 | 14522 | QCOM IPA DRIVER |
| @@ -14669,7 +14670,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git · 147 unmodified lines | ||
| 14669 | 14670 | F: drivers/net/wireless/ath/ath11k/ |
| 14670 | 14671 | |
| 14671 | 14672 | QUALCOMM ATHEROS ATH9K WIRELESS DRIVER |
| 14672 | −M: QCA ath9k Development <ath9k-devel@qca.qualcomm.com> | |
| 14673 | +M: ath9k-devel@qca.qualcomm.com | |
| 14673 | 14674 | L: linux-wireless@vger.kernel.org |
| 14674 | 14675 | S: Supported |
| 14675 | 14676 | W: https://wireless.wiki.kernel.org/en/users/Drivers/ath9k |
| @@ -14820,7 +14821,7 @@ M: Alex Deucher <alexander.deucher@amd.com> · 144 unmodified lines | ||
| 14820 | 14821 | M: Christian König <christian.koenig@amd.com> |
| 14821 | 14822 | L: amd-gfx@lists.freedesktop.org |
| 14822 | 14823 | S: Supported |
| 14823 | −T: git git://people.freedesktop.org/~agd5f/linux | |
| 14824 | +T: git https://gitlab.freedesktop.org/agd5f/linux.git | |
| 14824 | 14825 | F: drivers/gpu/drm/amd/ |
| 14825 | 14826 | F: drivers/gpu/drm/radeon/ |
| 14826 | 14827 | F: include/uapi/drm/amdgpu_drm.h |
| @@ -16321,6 +16322,7 @@ M: Pekka Enberg <penberg@kernel.org> · 1494 unmodified lines | ||
| 16321 | 16322 | M: David Rientjes <rientjes@google.com> |
| 16322 | 16323 | M: Joonsoo Kim <iamjoonsoo.kim@lge.com> |
| 16323 | 16324 | M: Andrew Morton <akpm@linux-foundation.org> |
| 16325 | +M: Vlastimil Babka <vbabka@suse.cz> | |
| 16324 | 16326 | L: linux-mm@kvack.org |
| 16325 | 16327 | S: Maintained |
| 16326 | 16328 | F: include/linux/sl?b*.h |
| @@ -16710,6 +16712,8 @@ M: Samuel Thibault <samuel.thibault@ens-lyon.org> · 383 unmodified lines | ||
| 16710 | 16712 | L: speakup@linux-speakup.org |
| 16711 | 16713 | S: Odd Fixes |
| 16712 | 16714 | W: http://www.linux-speakup.org/ |
| 16715 | +W: https://github.com/linux-speakup/speakup | |
| 16716 | +B: https://github.com/linux-speakup/speakup/issues | |
| 16713 | 16717 | F: drivers/accessibility/speakup/ |
| 16714 | 16718 | |
| 16715 | 16719 | SPEAR CLOCK FRAMEWORK SUPPORT |
| @@ -16964,7 +16968,7 @@ M: Olivier Moysan <olivier.moysan@st.com> · 248 unmodified lines | ||
| 16964 | 16968 | M: Arnaud Pouliquen <arnaud.pouliquen@st.com> |
| 16965 | 16969 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 16966 | 16970 | S: Maintained |
| 16967 | −F: Documentation/devicetree/bindings/sound/st,stm32-*.txt | |
| 16971 | +F: Documentation/devicetree/bindings/iio/adc/st,stm32-*.yaml | |
| 16968 | 16972 | F: sound/soc/stm/ |
| 16969 | 16973 | |
| 16970 | 16974 | STM32 TIMER/LPTIMER DRIVERS |
| @@ -17541,7 +17545,7 @@ F: arch/xtensa/ · 570 unmodified lines | ||
| 17541 | 17545 | F: drivers/irqchip/irq-xtensa-* |
| 17542 | 17546 | |
| 17543 | 17547 | TEXAS INSTRUMENTS ASoC DRIVERS |
| 17544 | −M: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 17548 | +M: Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 17545 | 17549 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 17546 | 17550 | S: Maintained |
| 17547 | 17551 | F: sound/soc/ti/ |
| @@ -17553,9 +17557,22 @@ S: Supported · 5 unmodified lines | ||
| 17553 | 17557 | F: Documentation/devicetree/bindings/iio/dac/ti,dac7612.txt |
| 17554 | 17558 | F: drivers/iio/dac/ti-dac7612.c |
| 17555 | 17559 | |
| 17560 | +TEXAS INSTRUMENTS DMA DRIVERS | |
| 17561 | +M: Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 17562 | +L: dmaengine@vger.kernel.org | |
| 17563 | +S: Maintained | |
| 17564 | +F: Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt | |
| 17565 | +F: Documentation/devicetree/bindings/dma/ti-edma.txt | |
| 17566 | +F: Documentation/devicetree/bindings/dma/ti/ | |
| 17567 | +F: drivers/dma/ti/ | |
| 17568 | +X: drivers/dma/ti/cppi41.c | |
| 17569 | +F: include/linux/dma/k3-udma-glue.h | |
| 17570 | +F: include/linux/dma/ti-cppi5.h | |
| 17571 | +F: include/linux/dma/k3-psil.h | |
| 17572 | + | |
| 17556 | 17573 | TEXAS INSTRUMENTS' SYSTEM CONTROL INTERFACE (TISCI) PROTOCOL DRIVER |
| 17557 | 17574 | M: Nishanth Menon <nm@ti.com> |
| 17558 | −M: Tero Kristo <t-kristo@ti.com> | |
| 17575 | +M: Tero Kristo <kristo@kernel.org> | |
| 17559 | 17576 | M: Santosh Shilimkar <ssantosh@kernel.org> |
| 17560 | 17577 | L: linux-arm-kernel@lists.infradead.org |
| 17561 | 17578 | S: Maintained |
| @@ -17699,9 +17716,9 @@ S: Maintained · 137 unmodified lines | ||
| 17699 | 17716 | F: drivers/clk/clk-cdce706.c |
| 17700 | 17717 | |
| 17701 | 17718 | TI CLOCK DRIVER |
| 17702 | −M: Tero Kristo <t-kristo@ti.com> | |
| 17719 | +M: Tero Kristo <kristo@kernel.org> | |
| 17703 | 17720 | L: linux-omap@vger.kernel.org |
| 17704 | −S: Maintained | |
| 17721 | +S: Odd Fixes | |
| 17705 | 17722 | F: drivers/clk/ti/ |
| 17706 | 17723 | F: include/linux/clk/ti.h |
| 17707 | 17724 | |
| @@ -17838,7 +17855,7 @@ F: Documentation/devicetree/bindings/net/nfc/trf7970a.txt · 130 unmodified lines | ||
| 17838 | 17855 | F: drivers/nfc/trf7970a.c |
| 17839 | 17856 | |
| 17840 | 17857 | TI TWL4030 SERIES SOC CODEC DRIVER |
| 17841 | −M: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 17858 | +M: Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 17842 | 17859 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 17843 | 17860 | S: Maintained |
| 17844 | 17861 | F: sound/soc/codecs/twl4030* |
| @@ -18370,7 +18387,7 @@ F: include/linux/usb/isp116x.h · 525 unmodified lines | ||
| 18370 | 18387 | |
| 18371 | 18388 | USB LAN78XX ETHERNET DRIVER |
| 18372 | 18389 | M: Woojung Huh <woojung.huh@microchip.com> |
| 18373 | −M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | |
| 18390 | +M: UNGLinuxDriver@microchip.com | |
| 18374 | 18391 | L: netdev@vger.kernel.org |
| 18375 | 18392 | S: Maintained |
| 18376 | 18393 | F: Documentation/devicetree/bindings/net/microchip,lan78xx.txt |
| @@ -18404,7 +18421,7 @@ F: Documentation/usb/ohci.rst · 27 unmodified lines | ||
| 18404 | 18421 | F: drivers/usb/host/ohci* |
| 18405 | 18422 | |
| 18406 | 18423 | USB OTG FSM (Finite State Machine) |
| 18407 | −M: Peter Chen <Peter.Chen@nxp.com> | |
| 18424 | +M: Peter Chen <peter.chen@kernel.org> | |
| 18408 | 18425 | L: linux-usb@vger.kernel.org |
| 18409 | 18426 | S: Maintained |
| 18410 | 18427 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git |
| @@ -18484,7 +18501,7 @@ F: drivers/net/usb/smsc75xx.* · 73 unmodified lines | ||
| 18484 | 18501 | |
| 18485 | 18502 | USB SMSC95XX ETHERNET DRIVER |
| 18486 | 18503 | M: Steve Glendinning <steve.glendinning@shawell.net> |
| 18487 | −M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | |
| 18504 | +M: UNGLinuxDriver@microchip.com | |
| 18488 | 18505 | L: netdev@vger.kernel.org |
| 18489 | 18506 | S: Maintained |
| 18490 | 18507 | F: drivers/net/usb/smsc95xx.* |
| @@ -19031,7 +19048,7 @@ F: drivers/input/mouse/vmmouse.h · 540 unmodified lines | ||
| 19031 | 19048 | |
| 19032 | 19049 | VMWARE VMXNET3 ETHERNET DRIVER |
| 19033 | 19050 | M: Ronak Doshi <doshir@vmware.com> |
| 19034 | −M: "VMware, Inc." <pv-drivers@vmware.com> | |
| 19051 | +M: pv-drivers@vmware.com | |
| 19035 | 19052 | L: netdev@vger.kernel.org |
| 19036 | 19053 | S: Maintained |
| 19037 | 19054 | F: drivers/net/vmxnet3/ |
| @@ -19058,7 +19075,6 @@ K: regulator_get_optional · 20 unmodified lines | ||
| 19058 | 19075 | |
| 19059 | 19076 | VRF |
| 19060 | 19077 | M: David Ahern <dsahern@kernel.org> |
| 19061 | −M: Shrijeet Mukherjee <shrijeet@gmail.com> | |
| 19062 | 19078 | L: netdev@vger.kernel.org |
| 19063 | 19079 | S: Maintained |
| 19064 | 19080 | F: Documentation/networking/vrf.rst |
| @@ -19409,7 +19425,7 @@ F: drivers/net/ethernet/*/*/*xdp* · 344 unmodified lines | ||
| 19409 | 19425 | K: (?:\b|_)xdp(?:\b|_) |
| 19410 | 19426 | |
| 19411 | 19427 | XDP SOCKETS (AF_XDP) |
| 19412 | −M: Björn Töpel <bjorn.topel@intel.com> | |
| 19428 | +M: Björn Töpel <bjorn@kernel.org> | |
| 19413 | 19429 | M: Magnus Karlsson <magnus.karlsson@intel.com> |
| 19414 | 19430 | R: Jonathan Lemon <jonathan.lemon@gmail.com> |
| 19415 | 19431 | L: netdev@vger.kernel.org |
| @@ -19505,7 +19521,7 @@ F: arch/x86/xen/*swiotlb* · 89 unmodified lines | ||
| 19505 | 19521 | F: drivers/xen/*swiotlb* |
| 19506 | 19522 | |
| 19507 | 19523 | XFS FILESYSTEM |
| 19508 | −M: Darrick J. Wong <darrick.wong@oracle.com> | |
| 19524 | +M: Darrick J. Wong <djwong@kernel.org> | |
| 19509 | 19525 | M: linux-xfs@vger.kernel.org |
| 19510 | 19526 | L: linux-xfs@vger.kernel.org |
| 19511 | 19527 | S: Supported |
| @@ -2,8 +2,8 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 11 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc2 | |
| 6 | −NAME = Kleptomaniac Octopus | |
| 5 | +EXTRAVERSION = | |
| 6 | +NAME = 💕 Valentine's Day Edition 💕 | |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| 9 | 9 | # To see a list of typical targets execute "make help" |
| @@ -452,7 +452,6 @@ AWK = awk · 442 unmodified lines | ||
| 452 | 452 | INSTALLKERNEL := installkernel |
| 453 | 453 | DEPMOD = depmod |
| 454 | 454 | PERL = perl |
| 455 | −PYTHON = python | |
| 456 | 455 | PYTHON3 = python3 |
| 457 | 456 | CHECK = sparse |
| 458 | 457 | BASH = bash |
| @@ -508,7 +507,7 @@ CLANG_FLAGS := · 49 unmodified lines | ||
| 508 | 507 | |
| 509 | 508 | export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC |
| 510 | 509 | export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL |
| 511 | −export PERL PYTHON PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX | |
| 510 | +export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX | |
| 512 | 511 | export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD |
| 513 | 512 | export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE |
| 514 | 513 | |
| @@ -812,10 +811,12 @@ KBUILD_CFLAGS += -ftrivial-auto-var-init=zero · 297 unmodified lines | ||
| 812 | 811 | KBUILD_CFLAGS += -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang |
| 813 | 812 | endif |
| 814 | 813 | |
| 814 | +DEBUG_CFLAGS := | |
| 815 | + | |
| 815 | 816 | # Workaround for GCC versions < 5.0 |
| 816 | 817 | # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61801 |
| 817 | 818 | ifdef CONFIG_CC_IS_GCC |
| 818 | −DEBUG_CFLAGS := $(call cc-ifversion, -lt, 0500, $(call cc-option, -fno-var-tracking-assignments)) | |
| 819 | +DEBUG_CFLAGS += $(call cc-ifversion, -lt, 0500, $(call cc-option, -fno-var-tracking-assignments)) | |
| 819 | 820 | endif |
| 820 | 821 | |
| 821 | 822 | ifdef CONFIG_DEBUG_INFO |
| @@ -948,12 +949,6 @@ KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init) · 126 unmodified lines | ||
| 948 | 949 | # change __FILE__ to the relative path from the srctree |
| 949 | 950 | KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=) |
| 950 | 951 | |
| 951 | −# ensure -fcf-protection is disabled when using retpoline as it is | |
| 952 | −# incompatible with -mindirect-branch=thunk-extern | |
| 953 | −ifdef CONFIG_RETPOLINE | |
| 954 | −KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none) | |
| 955 | −endif | |
| 956 | − | |
| 957 | 952 | # include additional Makefiles when needed |
| 958 | 953 | include-y := scripts/Makefile.extrawarn |
| 959 | 954 | include-$(CONFIG_KASAN) += scripts/Makefile.kasan |
| @@ -1105,6 +1105,12 @@ config HAVE_ARCH_PFN_VALID · 1104 unmodified lines | ||
| 1105 | 1105 | config ARCH_SUPPORTS_DEBUG_PAGEALLOC |
| 1106 | 1106 | bool |
| 1107 | 1107 | |
| 1108 | +config ARCH_SPLIT_ARG64 | |
| 1109 | + bool | |
| 1110 | + help | |
| 1111 | + If a 32-bit architecture requires 64-bit arguments to be split into | |
| 1112 | + pairs of 32-bit arguments, select this option. | |
| 1113 | + | |
| 1108 | 1114 | source "kernel/gcov/Kconfig" |
| 1109 | 1115 | |
| 1110 | 1116 | source "scripts/gcc-plugins/Kconfig" |
| @@ -102,16 +102,22 @@ libs-y += arch/arc/lib/ $(LIBGCC) · 101 unmodified lines | ||
| 102 | 102 | |
| 103 | 103 | boot := arch/arc/boot |
| 104 | 104 | |
| 105 | −#default target for make without any arguments. | |
| 106 | −KBUILD_IMAGE := $(boot)/bootpImage | |
| 107 | − | |
| 108 | −all: bootpImage | |
| 109 | −bootpImage: vmlinux | |
| 110 | − | |
| 111 | −boot_targets += uImage uImage.bin uImage.gz | |
| 105 | +boot_targets := uImage.bin uImage.gz uImage.lzma | |
| 112 | 106 | |
| 107 | +PHONY += $(boot_targets) | |
| 113 | 108 | $(boot_targets): vmlinux |
| 114 | 109 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ |
| 115 | 110 | |
| 111 | +uimage-default-y := uImage.bin | |
| 112 | +uimage-default-$(CONFIG_KERNEL_GZIP) := uImage.gz | |
| 113 | +uimage-default-$(CONFIG_KERNEL_LZMA) := uImage.lzma | |
| 114 | + | |
| 115 | +PHONY += uImage | |
| 116 | +uImage: $(uimage-default-y) | |
| 117 | + @ln -sf $< $(boot)/uImage | |
| 118 | + @$(kecho) ' Image $(boot)/uImage is ready' | |
| 119 | + | |
| 120 | +CLEAN_FILES += $(boot)/uImage | |
| 121 | + | |
| 116 | 122 | archclean: |
| 117 | 123 | $(Q)$(MAKE) $(clean)=$(boot) |
| @@ -1,5 +1,4 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | −targets := vmlinux.bin vmlinux.bin.gz uImage | |
| 3 | 2 | |
| 4 | 3 | # uImage build relies on mkimage being availble on your host for ARC target |
| 5 | 4 | # You will need to build u-boot for ARC, rename mkimage to arc-elf32-mkimage |
| @@ -7,23 +6,18 @@ targets := vmlinux.bin vmlinux.bin.gz uImage · 1 unmodified line | ||
| 7 | 6 | |
| 8 | 7 | OBJCOPYFLAGS= -O binary -R .note -R .note.gnu.build-id -R .comment -S |
| 9 | 8 | |
| 10 | −LINUX_START_TEXT = $$(readelf -h vmlinux | \ | |
| 9 | +LINUX_START_TEXT = $$($(READELF) -h vmlinux | \ | |
| 11 | 10 | grep "Entry point address" | grep -o 0x.*) |
| 12 | 11 | |
| 13 | 12 | UIMAGE_LOADADDR = $(CONFIG_LINUX_LINK_BASE) |
| 14 | 13 | UIMAGE_ENTRYADDR = $(LINUX_START_TEXT) |
| 15 | 14 | |
| 16 | −suffix-y := bin | |
| 17 | −suffix-$(CONFIG_KERNEL_GZIP) := gz | |
| 18 | −suffix-$(CONFIG_KERNEL_LZMA) := lzma | |
| 19 | − | |
| 20 | −targets += uImage | |
| 15 | +targets += vmlinux.bin | |
| 16 | +targets += vmlinux.bin.gz | |
| 17 | +targets += vmlinux.bin.lzma | |
| 21 | 18 | targets += uImage.bin |
| 22 | 19 | targets += uImage.gz |
| 23 | 20 | targets += uImage.lzma |
| 24 | −extra-y += vmlinux.bin | |
| 25 | −extra-y += vmlinux.bin.gz | |
| 26 | −extra-y += vmlinux.bin.lzma | |
| 27 | 21 | |
| 28 | 22 | $(obj)/vmlinux.bin: vmlinux FORCE |
| 29 | 23 | $(call if_changed,objcopy) |
| @@ -42,7 +36,3 @@ $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz FORCE · 12 unmodified lines | ||
| 42 | 36 | |
| 43 | 37 | $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma FORCE |
| 44 | 38 | $(call if_changed,uimage,lzma) |
| 45 | − | |
| 46 | −$(obj)/uImage: $(obj)/uImage.$(suffix-y) | |
| 47 | − @ln -sf $(notdir $<) $@ | |
| 48 | − @echo ' Image $@ is ready' | |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #ifndef __ASSEMBLY__ |
| 11 | 11 | |
| 12 | 12 | #define clear_page(paddr) memset((paddr), 0, PAGE_SIZE) |
| 13 | +#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) | |
| 13 | 14 | #define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) |
| 14 | 15 | |
| 15 | 16 | struct vm_area_struct; |
| @@ -307,7 +307,7 @@ resume_user_mode_begin: · 306 unmodified lines | ||
| 307 | 307 | mov r0, sp ; pt_regs for arg to do_signal()/do_notify_resume() |
| 308 | 308 | |
| 309 | 309 | GET_CURR_THR_INFO_FLAGS r9 |
| 310 | − and.f 0, r9, TIF_SIGPENDING|TIF_NOTIFY_SIGNAL | |
| 310 | + and.f 0, r9, _TIF_SIGPENDING|_TIF_NOTIFY_SIGNAL | |
| 311 | 311 | bz .Lchk_notify_resume |
| 312 | 312 | |
| 313 | 313 | ; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs |
| @@ -7,6 +7,7 @@ menuconfig ARC_SOC_HSDK · 6 unmodified lines | ||
| 7 | 7 | depends on ISA_ARCV2 |
| 8 | 8 | select ARC_HAS_ACCL_REGS |
| 9 | 9 | select ARC_IRQ_NO_AUTOSAVE |
| 10 | + select ARC_FPU_SAVE_RESTORE | |
| 10 | 11 | select CLK_HSDK |
| 11 | 12 | select RESET_CONTROLLER |
| 12 | 13 | select RESET_HSDK |
| @@ -15,7 +15,8 @@ static int node_offset(void *fdt, const char *node_path) · 14 unmodified lines | ||
| 15 | 15 | { |
| 16 | 16 | int offset = fdt_path_offset(fdt, node_path); |
| 17 | 17 | if (offset == -FDT_ERR_NOTFOUND) |
| 18 | − offset = fdt_add_subnode(fdt, 0, node_path); | |
| 18 | + /* Add the node to root if not found, dropping the leading '/' */ | |
| 19 | + offset = fdt_add_subnode(fdt, 0, node_path + 1); | |
| 19 | 20 | return offset; |
| 20 | 21 | } |
| 21 | 22 | |
| @@ -16,6 +16,13 @@ · 15 unmodified lines | ||
| 16 | 16 | stdout-path = &uart1; |
| 17 | 17 | }; |
| 18 | 18 | |
| 19 | + aliases { | |
| 20 | + mmc0 = &usdhc2; | |
| 21 | + mmc1 = &usdhc3; | |
| 22 | + mmc2 = &usdhc4; | |
| 23 | + /delete-property/ mmc3; | |
| 24 | + }; | |
| 25 | + | |
| 19 | 26 | memory@10000000 { |
| 20 | 27 | device_type = "memory"; |
| 21 | 28 | reg = <0x10000000 0x80000000>; |
| @@ -418,7 +418,7 @@ · 417 unmodified lines | ||
| 418 | 418 | |
| 419 | 419 | /* VDD_AUD_1P8: Audio codec */ |
| 420 | 420 | reg_aud_1p8v: ldo3 { |
| 421 | − regulator-name = "vdd1p8"; | |
| 421 | + regulator-name = "vdd1p8a"; | |
| 422 | 422 | regulator-min-microvolt = <1800000>; |
| 423 | 423 | regulator-max-microvolt = <1800000>; |
| 424 | 424 | regulator-boot-on; |
| @@ -137,7 +137,7 @@ · 136 unmodified lines | ||
| 137 | 137 | |
| 138 | 138 | lcd_backlight: lcd-backlight { |
| 139 | 139 | compatible = "pwm-backlight"; |
| 140 | − pwms = <&pwm4 0 5000000>; | |
| 140 | + pwms = <&pwm4 0 5000000 0>; | |
| 141 | 141 | pwm-names = "LCD_BKLT_PWM"; |
| 142 | 142 | |
| 143 | 143 | brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>; |
| @@ -167,7 +167,7 @@ · 23 unmodified lines | ||
| 167 | 167 | i2c-gpio,delay-us = <2>; /* ~100 kHz */ |
| 168 | 168 | #address-cells = <1>; |
| 169 | 169 | #size-cells = <0>; |
| 170 | − status = "disabld"; | |
| 170 | + status = "disabled"; | |
| 171 | 171 | }; |
| 172 | 172 | |
| 173 | 173 | i2c_cam: i2c-gpio-cam { |
| @@ -179,7 +179,7 @@ · 5 unmodified lines | ||
| 179 | 179 | i2c-gpio,delay-us = <2>; /* ~100 kHz */ |
| 180 | 180 | #address-cells = <1>; |
| 181 | 181 | #size-cells = <0>; |
| 182 | − status = "disabld"; | |
| 182 | + status = "disabled"; | |
| 183 | 183 | }; |
| 184 | 184 | }; |
| 185 | 185 | |
| @@ -53,7 +53,6 @@ · 52 unmodified lines | ||
| 53 | 53 | &fec { |
| 54 | 54 | pinctrl-names = "default"; |
| 55 | 55 | pinctrl-0 = <&pinctrl_microsom_enet_ar8035>; |
| 56 | − phy-handle = <&phy>; | |
| 57 | 56 | phy-mode = "rgmii-id"; |
| 58 | 57 | phy-reset-duration = <2>; |
| 59 | 58 | phy-reset-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; |
| @@ -63,10 +62,19 @@ · 3 unmodified lines | ||
| 63 | 62 | #address-cells = <1>; |
| 64 | 63 | #size-cells = <0>; |
| 65 | 64 | |
| 66 | − phy: ethernet-phy@0 { | |
| 65 | + /* | |
| 66 | + * The PHY can appear at either address 0 or 4 due to the | |
| 67 | + * configuration (LED) pin not being pulled sufficiently. | |
| 68 | + */ | |
| 69 | + ethernet-phy@0 { | |
| 67 | 70 | reg = <0>; |
| 68 | 71 | qca,clk-out-frequency = <125000000>; |
| 69 | 72 | }; |
| 73 | + | |
| 74 | + ethernet-phy@4 { | |
| 75 | + reg = <4>; | |
| 76 | + qca,clk-out-frequency = <125000000>; | |
| 77 | + }; | |
| 70 | 78 | }; |
| 71 | 79 | }; |
| 72 | 80 | |
| @@ -115,6 +115,7 @@ · 114 unmodified lines | ||
| 115 | 115 | compatible = "nxp,pcf2127"; |
| 116 | 116 | reg = <0>; |
| 117 | 117 | spi-max-frequency = <2000000>; |
| 118 | + reset-source; | |
| 118 | 119 | }; |
| 119 | 120 | }; |
| 120 | 121 | |
| @@ -326,9 +326,6 @@ · 325 unmodified lines | ||
| 326 | 326 | |
| 327 | 327 | clocks = <&xtal_32k>, <&xtal>; |
| 328 | 328 | clock-names = "xtal_32k", "xtal"; |
| 329 | − | |
| 330 | − assigned-clocks = <&clk LPC32XX_CLK_HCLK_PLL>; | |
| 331 | − assigned-clock-rates = <208000000>; | |
| 332 | 329 | }; |
| 333 | 330 | }; |
| 334 | 331 | |
| @@ -114,7 +114,7 @@ · 113 unmodified lines | ||
| 114 | 114 | gpio-sck = <&gpio1 12 GPIO_ACTIVE_HIGH>; |
| 115 | 115 | gpio-miso = <&gpio1 18 GPIO_ACTIVE_HIGH>; |
| 116 | 116 | gpio-mosi = <&gpio1 20 GPIO_ACTIVE_HIGH>; |
| 117 | − cs-gpios = <&gpio1 19 GPIO_ACTIVE_HIGH>; | |
| 117 | + cs-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>; | |
| 118 | 118 | num-chipselects = <1>; |
| 119 | 119 | |
| 120 | 120 | /* lcd panel */ |
| @@ -124,7 +124,6 @@ · 3 unmodified lines | ||
| 124 | 124 | spi-max-frequency = <100000>; |
| 125 | 125 | spi-cpol; |
| 126 | 126 | spi-cpha; |
| 127 | − spi-cs-high; | |
| 128 | 127 | |
| 129 | 128 | backlight= <&backlight>; |
| 130 | 129 | label = "lcd"; |
| @@ -494,3 +494,11 @@ · 493 unmodified lines | ||
| 494 | 494 | clock-names = "sysclk"; |
| 495 | 495 | }; |
| 496 | 496 | }; |
| 497 | + | |
| 498 | +&aes1_target { | |
| 499 | + status = "disabled"; | |
| 500 | +}; | |
| 501 | + | |
| 502 | +&aes2_target { | |
| 503 | + status = "disabled"; | |
| 504 | +}; | |
| @@ -16,8 +16,13 @@ · 15 unmodified lines | ||
| 16 | 16 | debounce-interval = <10>; |
| 17 | 17 | }; |
| 18 | 18 | |
| 19 | + /* | |
| 20 | + * We use pad 0x4a100116 abe_dmic_din3.gpio_122 as the irq instead | |
| 21 | + * of the gpio interrupt to avoid lost events in deeper idle states. | |
| 22 | + */ | |
| 19 | 23 | slider { |
| 20 | 24 | label = "Keypad Slide"; |
| 25 | + interrupts-extended = <&omap4_pmx_core 0xd6>; | |
| 21 | 26 | gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>; /* gpio122 */ |
| 22 | 27 | linux,input-type = <EV_SW>; |
| 23 | 28 | linux,code = <SW_KEYPAD_SLIDE>; |
| @@ -45,18 +45,21 @@ · 44 unmodified lines | ||
| 45 | 45 | emac: gem@30000 { |
| 46 | 46 | compatible = "cadence,gem"; |
| 47 | 47 | reg = <0x30000 0x10000>; |
| 48 | + interrupt-parent = <&vic0>; | |
| 48 | 49 | interrupts = <31>; |
| 49 | 50 | }; |
| 50 | 51 | |
| 51 | 52 | dmac1: dmac@40000 { |
| 52 | 53 | compatible = "snps,dw-dmac"; |
| 53 | 54 | reg = <0x40000 0x10000>; |
| 55 | + interrupt-parent = <&vic0>; | |
| 54 | 56 | interrupts = <25>; |
| 55 | 57 | }; |
| 56 | 58 | |
| 57 | 59 | dmac2: dmac@50000 { |
| 58 | 60 | compatible = "snps,dw-dmac"; |
| 59 | 61 | reg = <0x50000 0x10000>; |
| 62 | + interrupt-parent = <&vic0>; | |
| 60 | 63 | interrupts = <26>; |
| 61 | 64 | }; |
| 62 | 65 | |
| @@ -233,6 +236,7 @@ · 170 unmodified lines | ||
| 233 | 236 | axi2pico@c0000000 { |
| 234 | 237 | compatible = "picochip,axi2pico-pc3x2"; |
| 235 | 238 | reg = <0xc0000000 0x10000>; |
| 239 | + interrupt-parent = <&vic0>; | |
| 236 | 240 | interrupts = <13 14 15 16 17 18 19 20 21>; |
| 237 | 241 | }; |
| 238 | 242 | }; |
| @@ -12,4 +12,42 @@ · 11 unmodified lines | ||
| 12 | 12 | 200000 0>; |
| 13 | 13 | }; |
| 14 | 14 | }; |
| 15 | + | |
| 16 | + reserved-memory { | |
| 17 | + #address-cells = <1>; | |
| 18 | + #size-cells = <1>; | |
| 19 | + ranges; | |
| 20 | + | |
| 21 | + /* Modem trace memory */ | |
| 22 | + ram@06000000 { | |
| 23 | + reg = <0x06000000 0x00f00000>; | |
| 24 | + no-map; | |
| 25 | + }; | |
| 26 | + | |
| 27 | + /* Modem shared memory */ | |
| 28 | + ram@06f00000 { | |
| 29 | + reg = <0x06f00000 0x00100000>; | |
| 30 | + no-map; | |
| 31 | + }; | |
| 32 | + | |
| 33 | + /* Modem private memory */ | |
| 34 | + ram@07000000 { | |
| 35 | + reg = <0x07000000 0x01000000>; | |
| 36 | + no-map; | |
| 37 | + }; | |
| 38 | + | |
| 39 | + /* | |
| 40 | + * Initial Secure Software ISSW memory | |
| 41 | + * | |
| 42 | + * This is probably only used if the kernel tries | |
| 43 | + * to actually call into trustzone to run secure | |
| 44 | + * applications, which the mainline kernel probably | |
| 45 | + * will not do on this old chipset. But you can never | |
| 46 | + * be too careful, so reserve this memory anyway. | |
| 47 | + */ | |
| 48 | + ram@17f00000 { | |
| 49 | + reg = <0x17f00000 0x00100000>; | |
| 50 | + no-map; | |
| 51 | + }; | |
| 52 | + }; | |
| 15 | 53 | }; |
| @@ -12,4 +12,42 @@ · 11 unmodified lines | ||
| 12 | 12 | 200000 0>; |
| 13 | 13 | }; |
| 14 | 14 | }; |
| 15 | + | |
| 16 | + reserved-memory { | |
| 17 | + #address-cells = <1>; | |
| 18 | + #size-cells = <1>; | |
| 19 | + ranges; | |
| 20 | + | |
| 21 | + /* Modem trace memory */ | |
| 22 | + ram@06000000 { | |
| 23 | + reg = <0x06000000 0x00f00000>; | |
| 24 | + no-map; | |
| 25 | + }; | |
| 26 | + | |
| 27 | + /* Modem shared memory */ | |
| 28 | + ram@06f00000 { | |
| 29 | + reg = <0x06f00000 0x00100000>; | |
| 30 | + no-map; | |
| 31 | + }; | |
| 32 | + | |
| 33 | + /* Modem private memory */ | |
| 34 | + ram@07000000 { | |
| 35 | + reg = <0x07000000 0x01000000>; | |
| 36 | + no-map; | |
| 37 | + }; | |
| 38 | + | |
| 39 | + /* | |
| 40 | + * Initial Secure Software ISSW memory | |
| 41 | + * | |
| 42 | + * This is probably only used if the kernel tries | |
| 43 | + * to actually call into trustzone to run secure | |
| 44 | + * applications, which the mainline kernel probably | |
| 45 | + * will not do on this old chipset. But you can never | |
| 46 | + * be too careful, so reserve this memory anyway. | |
| 47 | + */ | |
| 48 | + ram@17f00000 { | |
| 49 | + reg = <0x17f00000 0x00100000>; | |
| 50 | + no-map; | |
| 51 | + }; | |
| 52 | + }; | |
| 15 | 53 | }; |
| @@ -0,0 +1,35 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later | |
| 2 | + | |
| 3 | +#include "ste-dbx5x0.dtsi" | |
| 4 | + | |
| 5 | +/ { | |
| 6 | + cpus { | |
| 7 | + cpu@300 { | |
| 8 | + /* cpufreq controls */ | |
| 9 | + operating-points = <1152000 0 | |
| 10 | + 800000 0 | |
| 11 | + 400000 0 | |
| 12 | + 200000 0>; | |
| 13 | + }; | |
| 14 | + }; | |
| 15 | + | |
| 16 | + reserved-memory { | |
| 17 | + #address-cells = <1>; | |
| 18 | + #size-cells = <1>; | |
| 19 | + ranges; | |
| 20 | + | |
| 21 | + /* | |
| 22 | + * Initial Secure Software ISSW memory | |
| 23 | + * | |
| 24 | + * This is probably only used if the kernel tries | |
| 25 | + * to actually call into trustzone to run secure | |
| 26 | + * applications, which the mainline kernel probably | |
| 27 | + * will not do on this old chipset. But you can never | |
| 28 | + * be too careful, so reserve this memory anyway. | |
| 29 | + */ | |
| 30 | + ram@17f00000 { | |
| 31 | + reg = <0x17f00000 0x00100000>; | |
| 32 | + no-map; | |
| 33 | + }; | |
| 34 | + }; | |
| 35 | +}; | |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | 6 | /dts-v1/; |
| 7 | −#include "ste-db8500.dtsi" | |
| 7 | +#include "ste-db9500.dtsi" | |
| 8 | 8 | #include "ste-href-ab8500.dtsi" |
| 9 | 9 | #include "ste-href-family-pinctrl.dtsi" |
| 10 | 10 | |
| @@ -329,6 +329,7 @@ · 328 unmodified lines | ||
| 329 | 329 | panel@0 { |
| 330 | 330 | compatible = "samsung,s6e63m0"; |
| 331 | 331 | reg = <0>; |
| 332 | + max-brightness = <15>; | |
| 332 | 333 | vdd3-supply = <&panel_reg_3v0>; |
| 333 | 334 | vci-supply = <&panel_reg_1v8>; |
| 334 | 335 | reset-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; |
| @@ -33,9 +33,9 @@ · 32 unmodified lines | ||
| 33 | 33 | * during TX anyway and that it only controls drive enable DE |
| 34 | 34 | * line. Hence, the RX is always enabled here. |
| 35 | 35 | */ |
| 36 | − rs485-rx-en { | |
| 36 | + rs485-rx-en-hog { | |
| 37 | 37 | gpio-hog; |
| 38 | − gpios = <8 GPIO_ACTIVE_HIGH>; | |
| 38 | + gpios = <8 0>; | |
| 39 | 39 | output-low; |
| 40 | 40 | line-name = "rs485-rx-en"; |
| 41 | 41 | }; |
| @@ -61,9 +61,9 @@ · 19 unmodified lines | ||
| 61 | 61 | * order to reset the Hub when USB bus is powered down, but |
| 62 | 62 | * so far there is no such functionality. |
| 63 | 63 | */ |
| 64 | − usb-hub { | |
| 64 | + usb-hub-hog { | |
| 65 | 65 | gpio-hog; |
| 66 | − gpios = <2 GPIO_ACTIVE_HIGH>; | |
| 66 | + gpios = <2 0>; | |
| 67 | 67 | output-high; |
| 68 | 68 | line-name = "usb-hub-reset"; |
| 69 | 69 | }; |
| @@ -87,6 +87,12 @@ · 17 unmodified lines | ||
| 87 | 87 | }; |
| 88 | 88 | }; |
| 89 | 89 | |
| 90 | +&i2c4 { | |
| 91 | + touchscreen@49 { | |
| 92 | + status = "disabled"; | |
| 93 | + }; | |
| 94 | +}; | |
| 95 | + | |
| 90 | 96 | &i2c5 { /* TP7/TP8 */ |
| 91 | 97 | pinctrl-names = "default"; |
| 92 | 98 | pinctrl-0 = <&i2c5_pins_a>; |
| @@ -104,7 +110,7 @@ · 11 unmodified lines | ||
| 104 | 110 | * are used for on-board microSD slot instead. |
| 105 | 111 | */ |
| 106 | 112 | /delete-property/broken-cd; |
| 107 | − cd-gpios = <&gpioi 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; | |
| 113 | + cd-gpios = <&gpioi 10 GPIO_ACTIVE_HIGH>; | |
| 108 | 114 | disable-wp; |
| 109 | 115 | }; |
| 110 | 116 | |
| @@ -43,9 +43,9 @@ · 42 unmodified lines | ||
| 43 | 43 | * in order to turn on port power when USB bus is powered up, but so |
| 44 | 44 | * far there is no such functionality. |
| 45 | 45 | */ |
| 46 | − usb-port-power { | |
| 46 | + usb-port-power-hog { | |
| 47 | 47 | gpio-hog; |
| 48 | − gpios = <13 GPIO_ACTIVE_LOW>; | |
| 48 | + gpios = <13 0>; | |
| 49 | 49 | output-low; |
| 50 | 50 | line-name = "usb-port-power"; |
| 51 | 51 | }; |
| @@ -390,7 +390,8 @@ · 389 unmodified lines | ||
| 390 | 390 | pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; |
| 391 | 391 | pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_dir_pins_a>; |
| 392 | 392 | pinctrl-2 = <&sdmmc1_b4_sleep_pins_a &sdmmc1_dir_sleep_pins_a>; |
| 393 | − broken-cd; | |
| 393 | + cd-gpios = <&gpiog 1 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; | |
| 394 | + disable-wp; | |
| 394 | 395 | st,sig-dir; |
| 395 | 396 | st,neg-edge; |
| 396 | 397 | st,use-ckin; |
| @@ -110,7 +110,7 @@ · 109 unmodified lines | ||
| 110 | 110 | pinctrl-names = "default"; |
| 111 | 111 | pinctrl-0 = <&gmac_rgmii_pins>; |
| 112 | 112 | phy-handle = <&phy1>; |
| 113 | − phy-mode = "rgmii"; | |
| 113 | + phy-mode = "rgmii-id"; | |
| 114 | 114 | phy-supply = <®_gmac_3v3>; |
| 115 | 115 | status = "okay"; |
| 116 | 116 | }; |
| @@ -279,6 +279,7 @@ CONFIG_SERIAL_OMAP_CONSOLE=y · 278 unmodified lines | ||
| 279 | 279 | CONFIG_SERIAL_DEV_BUS=y |
| 280 | 280 | CONFIG_I2C_CHARDEV=y |
| 281 | 281 | CONFIG_SPI=y |
| 282 | +CONFIG_SPI_GPIO=m | |
| 282 | 283 | CONFIG_SPI_OMAP24XX=y |
| 283 | 284 | CONFIG_SPI_TI_QSPI=m |
| 284 | 285 | CONFIG_HSI=m |
| @@ -296,7 +297,6 @@ CONFIG_GPIO_TWL4030=y · 11 unmodified lines | ||
| 296 | 297 | CONFIG_W1=m |
| 297 | 298 | CONFIG_HDQ_MASTER_OMAP=m |
| 298 | 299 | CONFIG_W1_SLAVE_DS250X=m |
| 299 | −CONFIG_POWER_AVS=y | |
| 300 | 300 | CONFIG_POWER_RESET=y |
| 301 | 301 | CONFIG_POWER_RESET_GPIO=y |
| 302 | 302 | CONFIG_BATTERY_BQ27XXX=m |
| @@ -60,6 +60,7 @@ static void chacha_doneon(u32 *state, u8 *dst, const u8 *src, · 59 unmodified lines | ||
| 60 | 60 | chacha_block_xor_neon(state, d, s, nrounds); |
| 61 | 61 | if (d != dst) |
| 62 | 62 | memcpy(dst, buf, bytes); |
| 63 | + state[12]++; | |
| 63 | 64 | } |
| 64 | 65 | } |
| 65 | 66 | |
| @@ -0,0 +1,12 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +#ifndef _ARM_KEXEC_INTERNAL_H | |
| 3 | +#define _ARM_KEXEC_INTERNAL_H | |
| 4 | + | |
| 5 | +struct kexec_relocate_data { | |
| 6 | + unsigned long kexec_start_address; | |
| 7 | + unsigned long kexec_indirection_page; | |
| 8 | + unsigned long kexec_mach_type; | |
| 9 | + unsigned long kexec_r2; | |
| 10 | +}; | |
| 11 | + | |
| 12 | +#endif | |
| @@ -149,7 +149,34 @@ · 148 unmodified lines | ||
| 149 | 149 | |
| 150 | 150 | .align |
| 151 | 151 | 99: .word . |
| 152 | +#if defined(ZIMAGE) | |
| 153 | + .word . + 4 | |
| 154 | +/* | |
| 155 | + * Storage for the state maintained by the macro. | |
| 156 | + * | |
| 157 | + * In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c. | |
| 158 | + * That's because this header is included from multiple files, and we only | |
| 159 | + * want a single copy of the data. In particular, the UART probing code above | |
| 160 | + * assumes it's running using physical addresses. This is true when this file | |
| 161 | + * is included from head.o, but not when included from debug.o. So we need | |
| 162 | + * to share the probe results between the two copies, rather than having | |
| 163 | + * to re-run the probing again later. | |
| 164 | + * | |
| 165 | + * In the decompressor, we put the storage right here, since common.c | |
| 166 | + * isn't included in the decompressor build. This storage data gets put in | |
| 167 | + * .text even though it's really data, since .data is discarded from the | |
| 168 | + * decompressor. Luckily, .text is writeable in the decompressor, unless | |
| 169 | + * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug. | |
| 170 | + */ | |
| 171 | + /* Debug UART initialization required */ | |
| 172 | + .word 1 | |
| 173 | + /* Debug UART physical address */ | |
| 174 | + .word 0 | |
| 175 | + /* Debug UART virtual address */ | |
| 176 | + .word 0 | |
| 177 | +#else | |
| 152 | 178 | .word tegra_uart_config |
| 179 | +#endif | |
| 153 | 180 | .ltorg |
| 154 | 181 | |
| 155 | 182 | /* Load previously selected UART address */ |
| @@ -189,30 +216,3 @@ · 33 unmodified lines | ||
| 189 | 216 | |
| 190 | 217 | .macro waituarttxrdy,rd,rx |
| 191 | 218 | .endm |
| 192 | − | |
| 193 | −/* | |
| 194 | − * Storage for the state maintained by the macros above. | |
| 195 | − * | |
| 196 | − * In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c. | |
| 197 | − * That's because this header is included from multiple files, and we only | |
| 198 | − * want a single copy of the data. In particular, the UART probing code above | |
| 199 | − * assumes it's running using physical addresses. This is true when this file | |
| 200 | − * is included from head.o, but not when included from debug.o. So we need | |
| 201 | − * to share the probe results between the two copies, rather than having | |
| 202 | − * to re-run the probing again later. | |
| 203 | − * | |
| 204 | − * In the decompressor, we put the symbol/storage right here, since common.c | |
| 205 | − * isn't included in the decompressor build. This symbol gets put in .text | |
| 206 | − * even though it's really data, since .data is discarded from the | |
| 207 | − * decompressor. Luckily, .text is writeable in the decompressor, unless | |
| 208 | − * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug. | |
| 209 | − */ | |
| 210 | −#if defined(ZIMAGE) | |
| 211 | −tegra_uart_config: | |
| 212 | − /* Debug UART initialization required */ | |
| 213 | − .word 1 | |
| 214 | − /* Debug UART physical address */ | |
| 215 | − .word 0 | |
| 216 | − /* Debug UART virtual address */ | |
| 217 | − .word 0 | |
| 218 | −#endif | |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/mm.h> |
| 13 | 13 | #include <linux/dma-mapping.h> |
| 14 | 14 | #include <asm/cacheflush.h> |
| 15 | +#include <asm/kexec-internal.h> | |
| 15 | 16 | #include <asm/glue-df.h> |
| 16 | 17 | #include <asm/glue-pf.h> |
| 17 | 18 | #include <asm/mach/arch.h> |
| @@ -170,5 +171,9 @@ int main(void) · 152 unmodified lines | ||
| 170 | 171 | DEFINE(MPU_RGN_PRBAR, offsetof(struct mpu_rgn, prbar)); |
| 171 | 172 | DEFINE(MPU_RGN_PRLAR, offsetof(struct mpu_rgn, prlar)); |
| 172 | 173 | #endif |
| 174 | + DEFINE(KEXEC_START_ADDR, offsetof(struct kexec_relocate_data, kexec_start_address)); | |
| 175 | + DEFINE(KEXEC_INDIR_PAGE, offsetof(struct kexec_relocate_data, kexec_indirection_page)); | |
| 176 | + DEFINE(KEXEC_MACH_TYPE, offsetof(struct kexec_relocate_data, kexec_mach_type)); | |
| 177 | + DEFINE(KEXEC_R2, offsetof(struct kexec_relocate_data, kexec_r2)); | |
| 173 | 178 | return 0; |
| 174 | 179 | } |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/of_fdt.h> |
| 14 | 14 | #include <asm/mmu_context.h> |
| 15 | 15 | #include <asm/cacheflush.h> |
| 16 | +#include <asm/kexec-internal.h> | |
| 16 | 17 | #include <asm/fncpy.h> |
| 17 | 18 | #include <asm/mach-types.h> |
| 18 | 19 | #include <asm/smp_plat.h> |
| @@ -22,11 +23,6 @@ · 3 unmodified lines | ||
| 22 | 23 | extern void relocate_new_kernel(void); |
| 23 | 24 | extern const unsigned int relocate_new_kernel_size; |
| 24 | 25 | |
| 25 | −extern unsigned long kexec_start_address; | |
| 26 | −extern unsigned long kexec_indirection_page; | |
| 27 | −extern unsigned long kexec_mach_type; | |
| 28 | −extern unsigned long kexec_boot_atags; | |
| 29 | − | |
| 30 | 26 | static atomic_t waiting_for_crash_ipi; |
| 31 | 27 | |
| 32 | 28 | /* |
| @@ -159,6 +155,7 @@ void (*kexec_reinit)(void); · 126 unmodified lines | ||
| 159 | 155 | void machine_kexec(struct kimage *image) |
| 160 | 156 | { |
| 161 | 157 | unsigned long page_list, reboot_entry_phys; |
| 158 | + struct kexec_relocate_data *data; | |
| 162 | 159 | void (*reboot_entry)(void); |
| 163 | 160 | void *reboot_code_buffer; |
| 164 | 161 | |
| @@ -174,18 +171,17 @@ void machine_kexec(struct kimage *image) · 9 unmodified lines | ||
| 174 | 171 | |
| 175 | 172 | reboot_code_buffer = page_address(image->control_code_page); |
| 176 | 173 | |
| 177 | − /* Prepare parameters for reboot_code_buffer*/ | |
| 178 | − set_kernel_text_rw(); | |
| 179 | − kexec_start_address = image->start; | |
| 180 | − kexec_indirection_page = page_list; | |
| 181 | − kexec_mach_type = machine_arch_type; | |
| 182 | − kexec_boot_atags = image->arch.kernel_r2; | |
| 183 | − | |
| 184 | 174 | /* copy our kernel relocation code to the control code page */ |
| 185 | 175 | reboot_entry = fncpy(reboot_code_buffer, |
| 186 | 176 | &relocate_new_kernel, |
| 187 | 177 | relocate_new_kernel_size); |
| 188 | 178 | |
| 179 | + data = reboot_code_buffer + relocate_new_kernel_size; | |
| 180 | + data->kexec_start_address = image->start; | |
| 181 | + data->kexec_indirection_page = page_list; | |
| 182 | + data->kexec_mach_type = machine_arch_type; | |
| 183 | + data->kexec_r2 = image->arch.kernel_r2; | |
| 184 | + | |
| 189 | 185 | /* get the identity mapping physical address for the reboot code */ |
| 190 | 186 | reboot_entry_phys = virt_to_idmap(reboot_entry); |
| 191 | 187 | |
| @@ -5,14 +5,16 @@ · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | #include <linux/linkage.h> |
| 7 | 7 | #include <asm/assembler.h> |
| 8 | +#include <asm/asm-offsets.h> | |
| 8 | 9 | #include <asm/kexec.h> |
| 9 | 10 | |
| 10 | 11 | .align 3 /* not needed for this code, but keeps fncpy() happy */ |
| 11 | 12 | |
| 12 | 13 | ENTRY(relocate_new_kernel) |
| 13 | 14 | |
| 14 | − ldr r0,kexec_indirection_page | |
| 15 | − ldr r1,kexec_start_address | |
| 15 | + adr r7, relocate_new_kernel_end | |
| 16 | + ldr r0, [r7, #KEXEC_INDIR_PAGE] | |
| 17 | + ldr r1, [r7, #KEXEC_START_ADDR] | |
| 16 | 18 | |
| 17 | 19 | /* |
| 18 | 20 | * If there is no indirection page (we are doing crashdumps) |
| @@ -57,34 +59,16 @@ ENTRY(relocate_new_kernel) · 38 unmodified lines | ||
| 57 | 59 | |
| 58 | 60 | 2: |
| 59 | 61 | /* Jump to relocated kernel */ |
| 60 | − mov lr,r1 | |
| 61 | − mov r0,#0 | |
| 62 | − ldr r1,kexec_mach_type | |
| 63 | − ldr r2,kexec_boot_atags | |
| 64 | − ARM( ret lr ) | |
| 65 | − THUMB( bx lr ) | |
| 66 | − | |
| 67 | − .align | |
| 68 | − | |
| 69 | − .globl kexec_start_address | |
| 70 | −kexec_start_address: | |
| 71 | − .long 0x0 | |
| 72 | − | |
| 73 | − .globl kexec_indirection_page | |
| 74 | −kexec_indirection_page: | |
| 75 | − .long 0x0 | |
| 76 | − | |
| 77 | − .globl kexec_mach_type | |
| 78 | −kexec_mach_type: | |
| 79 | − .long 0x0 | |
| 80 | − | |
| 81 | − /* phy addr of the atags for the new kernel */ | |
| 82 | − .globl kexec_boot_atags | |
| 83 | −kexec_boot_atags: | |
| 84 | − .long 0x0 | |
| 62 | + mov lr, r1 | |
| 63 | + mov r0, #0 | |
| 64 | + ldr r1, [r7, #KEXEC_MACH_TYPE] | |
| 65 | + ldr r2, [r7, #KEXEC_R2] | |
| 66 | + ARM( ret lr ) | |
| 67 | + THUMB( bx lr ) | |
| 85 | 68 | |
| 86 | 69 | ENDPROC(relocate_new_kernel) |
| 87 | 70 | |
| 71 | + .align 3 | |
| 88 | 72 | relocate_new_kernel_end: |
| 89 | 73 | |
| 90 | 74 | .globl relocate_new_kernel_size |
| @@ -693,18 +693,20 @@ struct page *get_signal_page(void) · 692 unmodified lines | ||
| 693 | 693 | |
| 694 | 694 | addr = page_address(page); |
| 695 | 695 | |
| 696 | + /* Poison the entire page */ | |
| 697 | + memset32(addr, __opcode_to_mem_arm(0xe7fddef1), | |
| 698 | + PAGE_SIZE / sizeof(u32)); | |
| 699 | + | |
| 696 | 700 | /* Give the signal return code some randomness */ |
| 697 | 701 | offset = 0x200 + (get_random_int() & 0x7fc); |
| 698 | 702 | signal_return_offset = offset; |
| 699 | 703 | |
| 700 | − /* | |
| 701 | − * Copy signal return handlers into the vector page, and | |
| 702 | − * set sigreturn to be a pointer to these. | |
| 703 | − */ | |
| 704 | + /* Copy signal return handlers into the page */ | |
| 704 | 705 | memcpy(addr + offset, sigreturn_codes, sizeof(sigreturn_codes)); |
| 705 | 706 | |
| 706 | − ptr = (unsigned long)addr + offset; | |
| 707 | − flush_icache_range(ptr, ptr + sizeof(sigreturn_codes)); | |
| 707 | + /* Flush out all instructions in this page */ | |
| 708 | + ptr = (unsigned long)addr; | |
| 709 | + flush_icache_range(ptr, ptr + PAGE_SIZE); | |
| 708 | 710 | |
| 709 | 711 | return page; |
| 710 | 712 | } |
| @@ -65,15 +65,15 @@ dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where, · 64 unmodified lines | ||
| 65 | 65 | if (addr) |
| 66 | 66 | switch (size) { |
| 67 | 67 | case 1: |
| 68 | − asm("ldrb %0, [%1, %2]" | |
| 68 | + asm volatile("ldrb %0, [%1, %2]" | |
| 69 | 69 | : "=r" (v) : "r" (addr), "r" (where) : "cc"); |
| 70 | 70 | break; |
| 71 | 71 | case 2: |
| 72 | − asm("ldrh %0, [%1, %2]" | |
| 72 | + asm volatile("ldrh %0, [%1, %2]" | |
| 73 | 73 | : "=r" (v) : "r" (addr), "r" (where) : "cc"); |
| 74 | 74 | break; |
| 75 | 75 | case 4: |
| 76 | − asm("ldr %0, [%1, %2]" | |
| 76 | + asm volatile("ldr %0, [%1, %2]" | |
| 77 | 77 | : "=r" (v) : "r" (addr), "r" (where) : "cc"); |
| 78 | 78 | break; |
| 79 | 79 | } |
| @@ -99,17 +99,17 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where, · 19 unmodified lines | ||
| 99 | 99 | if (addr) |
| 100 | 100 | switch (size) { |
| 101 | 101 | case 1: |
| 102 | − asm("strb %0, [%1, %2]" | |
| 102 | + asm volatile("strb %0, [%1, %2]" | |
| 103 | 103 | : : "r" (value), "r" (addr), "r" (where) |
| 104 | 104 | : "cc"); |
| 105 | 105 | break; |
| 106 | 106 | case 2: |
| 107 | − asm("strh %0, [%1, %2]" | |
| 107 | + asm volatile("strh %0, [%1, %2]" | |
| 108 | 108 | : : "r" (value), "r" (addr), "r" (where) |
| 109 | 109 | : "cc"); |
| 110 | 110 | break; |
| 111 | 111 | case 4: |
| 112 | − asm("str %0, [%1, %2]" | |
| 112 | + asm volatile("str %0, [%1, %2]" | |
| 113 | 113 | : : "r" (value), "r" (addr), "r" (where) |
| 114 | 114 | : "cc"); |
| 115 | 115 | break; |
| @@ -67,6 +67,7 @@ · 66 unmodified lines | ||
| 67 | 67 | #define MX6Q_CCM_CCR 0x0 |
| 68 | 68 | |
| 69 | 69 | .align 3 |
| 70 | + .arm | |
| 70 | 71 | |
| 71 | 72 | .macro sync_l2_cache |
| 72 | 73 | |
| @@ -203,6 +203,8 @@ static int osk_tps_setup(struct i2c_client *client, void *context) · 202 unmodified lines | ||
| 203 | 203 | */ |
| 204 | 204 | gpio_request(OSK_TPS_GPIO_USB_PWR_EN, "n_vbus_en"); |
| 205 | 205 | gpio_direction_output(OSK_TPS_GPIO_USB_PWR_EN, 1); |
| 206 | + /* Free the GPIO again as the driver will request it */ | |
| 207 | + gpio_free(OSK_TPS_GPIO_USB_PWR_EN); | |
| 206 | 208 | |
| 207 | 209 | /* Set GPIO 2 high so LED D3 is off by default */ |
| 208 | 210 | tps65010_set_gpio_out_value(GPIO2, HIGH); |
| @@ -17,11 +17,10 @@ config ARCH_OMAP3 · 16 unmodified lines | ||
| 17 | 17 | bool "TI OMAP3" |
| 18 | 18 | depends on ARCH_MULTI_V7 |
| 19 | 19 | select ARCH_OMAP2PLUS |
| 20 | − select ARM_CPU_SUSPEND if PM | |
| 20 | + select ARM_CPU_SUSPEND | |
| 21 | 21 | select OMAP_HWMOD |
| 22 | 22 | select OMAP_INTERCONNECT |
| 23 | − select PM_OPP if PM | |
| 24 | − select PM if CPU_IDLE | |
| 23 | + select PM_OPP | |
| 25 | 24 | select SOC_HAS_OMAP2_SDRC |
| 26 | 25 | select ARM_ERRATA_430973 |
| 27 | 26 | |
| @@ -30,7 +29,7 @@ config ARCH_OMAP4 · 2 unmodified lines | ||
| 30 | 29 | depends on ARCH_MULTI_V7 |
| 31 | 30 | select ARCH_OMAP2PLUS |
| 32 | 31 | select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP |
| 33 | − select ARM_CPU_SUSPEND if PM | |
| 32 | + select ARM_CPU_SUSPEND | |
| 34 | 33 | select ARM_ERRATA_720789 |
| 35 | 34 | select ARM_GIC |
| 36 | 35 | select HAVE_ARM_SCU if SMP |
| @@ -40,7 +39,7 @@ config ARCH_OMAP4 · 3 unmodified lines | ||
| 40 | 39 | select OMAP_INTERCONNECT_BARRIER |
| 41 | 40 | select PL310_ERRATA_588369 if CACHE_L2X0 |
| 42 | 41 | select PL310_ERRATA_727915 if CACHE_L2X0 |
| 43 | − select PM_OPP if PM | |
| 42 | + select PM_OPP | |
| 44 | 43 | select PM if CPU_IDLE |
| 45 | 44 | select ARM_ERRATA_754322 |
| 46 | 45 | select ARM_ERRATA_775420 |
| @@ -50,7 +49,7 @@ config SOC_OMAP5 · 3 unmodified lines | ||
| 50 | 49 | bool "TI OMAP5" |
| 51 | 50 | depends on ARCH_MULTI_V7 |
| 52 | 51 | select ARCH_OMAP2PLUS |
| 53 | − select ARM_CPU_SUSPEND if PM | |
| 52 | + select ARM_CPU_SUSPEND | |
| 54 | 53 | select ARM_GIC |
| 55 | 54 | select HAVE_ARM_SCU if SMP |
| 56 | 55 | select HAVE_ARM_ARCH_TIMER |
| @@ -58,14 +57,14 @@ config SOC_OMAP5 · 1 unmodified line | ||
| 58 | 57 | select OMAP_HWMOD |
| 59 | 58 | select OMAP_INTERCONNECT |
| 60 | 59 | select OMAP_INTERCONNECT_BARRIER |
| 61 | − select PM_OPP if PM | |
| 60 | + select PM_OPP | |
| 62 | 61 | select ZONE_DMA if ARM_LPAE |
| 63 | 62 | |
| 64 | 63 | config SOC_AM33XX |
| 65 | 64 | bool "TI AM33XX" |
| 66 | 65 | depends on ARCH_MULTI_V7 |
| 67 | 66 | select ARCH_OMAP2PLUS |
| 68 | − select ARM_CPU_SUSPEND if PM | |
| 67 | + select ARM_CPU_SUSPEND | |
| 69 | 68 | |
| 70 | 69 | config SOC_AM43XX |
| 71 | 70 | bool "TI AM43x" |
| @@ -79,13 +78,13 @@ config SOC_AM43XX · 7 unmodified lines | ||
| 79 | 78 | select ARM_ERRATA_754322 |
| 80 | 79 | select ARM_ERRATA_775420 |
| 81 | 80 | select OMAP_INTERCONNECT |
| 82 | − select ARM_CPU_SUSPEND if PM | |
| 81 | + select ARM_CPU_SUSPEND | |
| 83 | 82 | |
| 84 | 83 | config SOC_DRA7XX |
| 85 | 84 | bool "TI DRA7XX" |
| 86 | 85 | depends on ARCH_MULTI_V7 |
| 87 | 86 | select ARCH_OMAP2PLUS |
| 88 | − select ARM_CPU_SUSPEND if PM | |
| 87 | + select ARM_CPU_SUSPEND | |
| 89 | 88 | select ARM_GIC |
| 90 | 89 | select HAVE_ARM_SCU if SMP |
| 91 | 90 | select HAVE_ARM_ARCH_TIMER |
| @@ -94,7 +93,7 @@ config SOC_DRA7XX · 2 unmodified lines | ||
| 94 | 93 | select OMAP_HWMOD |
| 95 | 94 | select OMAP_INTERCONNECT |
| 96 | 95 | select OMAP_INTERCONNECT_BARRIER |
| 97 | − select PM_OPP if PM | |
| 96 | + select PM_OPP | |
| 98 | 97 | select ZONE_DMA if ARM_LPAE |
| 99 | 98 | select PINCTRL_TI_IODELAY if OF && PINCTRL |
| 100 | 99 | |
| @@ -112,9 +111,11 @@ config ARCH_OMAP2PLUS · 11 unmodified lines | ||
| 112 | 111 | select OMAP_DM_TIMER |
| 113 | 112 | select OMAP_GPMC |
| 114 | 113 | select PINCTRL |
| 115 | − select PM_GENERIC_DOMAINS if PM | |
| 116 | − select PM_GENERIC_DOMAINS_OF if PM | |
| 114 | + select PM | |
| 115 | + select PM_GENERIC_DOMAINS | |
| 116 | + select PM_GENERIC_DOMAINS_OF | |
| 117 | 117 | select RESET_CONTROLLER |
| 118 | + select SIMPLE_PM_BUS | |
| 118 | 119 | select SOC_BUS |
| 119 | 120 | select TI_SYSC |
| 120 | 121 | select OMAP_IRQCHIP |
| @@ -140,7 +141,6 @@ config ARCH_OMAP2PLUS_TYPICAL · 19 unmodified lines | ||
| 140 | 141 | select I2C_OMAP |
| 141 | 142 | select MENELAUS if ARCH_OMAP2 |
| 142 | 143 | select NEON if CPU_V7 |
| 143 | − select PM | |
| 144 | 144 | select REGULATOR |
| 145 | 145 | select REGULATOR_FIXED_VOLTAGE |
| 146 | 146 | select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4 |
| @@ -151,10 +151,10 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, · 150 unmodified lines | ||
| 151 | 151 | (cx->mpu_logic_state == PWRDM_POWER_OFF); |
| 152 | 152 | |
| 153 | 153 | /* Enter broadcast mode for periodic timers */ |
| 154 | − tick_broadcast_enable(); | |
| 154 | + RCU_NONIDLE(tick_broadcast_enable()); | |
| 155 | 155 | |
| 156 | 156 | /* Enter broadcast mode for one-shot timers */ |
| 157 | − tick_broadcast_enter(); | |
| 157 | + RCU_NONIDLE(tick_broadcast_enter()); | |
| 158 | 158 | |
| 159 | 159 | /* |
| 160 | 160 | * Call idle CPU PM enter notifier chain so that |
| @@ -166,7 +166,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, · 5 unmodified lines | ||
| 166 | 166 | |
| 167 | 167 | if (dev->cpu == 0) { |
| 168 | 168 | pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); |
| 169 | − omap_set_pwrdm_state(mpu_pd, cx->mpu_state); | |
| 169 | + RCU_NONIDLE(omap_set_pwrdm_state(mpu_pd, cx->mpu_state)); | |
| 170 | 170 | |
| 171 | 171 | /* |
| 172 | 172 | * Call idle CPU cluster PM enter notifier chain |
| @@ -178,7 +178,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, · 5 unmodified lines | ||
| 178 | 178 | index = 0; |
| 179 | 179 | cx = state_ptr + index; |
| 180 | 180 | pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); |
| 181 | − omap_set_pwrdm_state(mpu_pd, cx->mpu_state); | |
| 181 | + RCU_NONIDLE(omap_set_pwrdm_state(mpu_pd, cx->mpu_state)); | |
| 182 | 182 | mpuss_can_lose_context = 0; |
| 183 | 183 | } |
| 184 | 184 | } |
| @@ -194,9 +194,9 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, · 9 unmodified lines | ||
| 194 | 194 | mpuss_can_lose_context) |
| 195 | 195 | gic_dist_disable(); |
| 196 | 196 | |
| 197 | − clkdm_deny_idle(cpu_clkdm[1]); | |
| 198 | − omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON); | |
| 199 | − clkdm_allow_idle(cpu_clkdm[1]); | |
| 197 | + RCU_NONIDLE(clkdm_deny_idle(cpu_clkdm[1])); | |
| 198 | + RCU_NONIDLE(omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON)); | |
| 199 | + RCU_NONIDLE(clkdm_allow_idle(cpu_clkdm[1])); | |
| 200 | 200 | |
| 201 | 201 | if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD) && |
| 202 | 202 | mpuss_can_lose_context) { |
| @@ -222,7 +222,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, · 19 unmodified lines | ||
| 222 | 222 | cpu_pm_exit(); |
| 223 | 223 | |
| 224 | 224 | cpu_pm_out: |
| 225 | − tick_broadcast_exit(); | |
| 225 | + RCU_NONIDLE(tick_broadcast_exit()); | |
| 226 | 226 | |
| 227 | 227 | fail: |
| 228 | 228 | cpuidle_coupled_parallel_barrier(dev, &abort_barrier); |
| @@ -230,10 +230,12 @@ static int _omap_device_notifier_call(struct notifier_block *nb, · 229 unmodified lines | ||
| 230 | 230 | break; |
| 231 | 231 | case BUS_NOTIFY_BIND_DRIVER: |
| 232 | 232 | od = to_omap_device(pdev); |
| 233 | − if (od && (od->_state == OMAP_DEVICE_STATE_ENABLED) && | |
| 234 | − pm_runtime_status_suspended(dev)) { | |
| 233 | + if (od) { | |
| 235 | 234 | od->_driver_status = BUS_NOTIFY_BIND_DRIVER; |
| 236 | − pm_runtime_set_active(dev); | |
| 235 | + if (od->_state == OMAP_DEVICE_STATE_ENABLED && | |
| 236 | + pm_runtime_status_suspended(dev)) { | |
| 237 | + pm_runtime_set_active(dev); | |
| 238 | + } | |
| 237 | 239 | } |
| 238 | 240 | break; |
| 239 | 241 | case BUS_NOTIFY_ADD_DEVICE: |
| @@ -522,6 +522,7 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = { · 521 unmodified lines | ||
| 522 | 522 | &dra7_ipu1_dsp_iommu_pdata), |
| 523 | 523 | #endif |
| 524 | 524 | /* Common auxdata */ |
| 525 | + OF_DEV_AUXDATA("simple-pm-bus", 0, NULL, omap_auxdata_lookup), | |
| 525 | 526 | OF_DEV_AUXDATA("ti,sysc", 0, NULL, &ti_sysc_pdata), |
| 526 | 527 | OF_DEV_AUXDATA("pinctrl-single", 0, NULL, &pcs_pdata), |
| 527 | 528 | OF_DEV_AUXDATA("ti,omap-prm-inst", 0, NULL, &ti_prm_pdata), |
| @@ -71,7 +71,7 @@ static struct omap_voltdm_pmic omap_cpcap_iva = { · 70 unmodified lines | ||
| 71 | 71 | .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN, |
| 72 | 72 | .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX, |
| 73 | 73 | .vddmin = 900000, |
| 74 | − .vddmax = 1350000, | |
| 74 | + .vddmax = 1375000, | |
| 75 | 75 | .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US, |
| 76 | 76 | .i2c_slave_addr = 0x44, |
| 77 | 77 | .volt_reg_addr = 0x0, |
| @@ -370,8 +370,6 @@ static int __init xen_guest_init(void) · 369 unmodified lines | ||
| 370 | 370 | return -ENOMEM; |
| 371 | 371 | } |
| 372 | 372 | gnttab_init(); |
| 373 | − if (!xen_initial_domain()) | |
| 374 | − xenbus_probe(NULL); | |
| 375 | 373 | |
| 376 | 374 | /* |
| 377 | 375 | * Making sure board specific code will not set up ops for |
| @@ -174,8 +174,6 @@ config ARM64 · 173 unmodified lines | ||
| 174 | 174 | select HAVE_NMI |
| 175 | 175 | select HAVE_PATA_PLATFORM |
| 176 | 176 | select HAVE_PERF_EVENTS |
| 177 | − select HAVE_PERF_EVENTS_NMI if ARM64_PSEUDO_NMI && HW_PERF_EVENTS | |
| 178 | − select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && HAVE_PERF_EVENTS_NMI | |
| 179 | 177 | select HAVE_PERF_REGS |
| 180 | 178 | select HAVE_PERF_USER_STACK_DUMP |
| 181 | 179 | select HAVE_REGS_AND_STACK_ACCESS_API |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | # |
| 11 | 11 | # Copyright (C) 1995-2001 by Russell King |
| 12 | 12 | |
| 13 | −LDFLAGS_vmlinux :=--no-undefined -X -z norelro | |
| 13 | +LDFLAGS_vmlinux :=--no-undefined -X | |
| 14 | 14 | |
| 15 | 15 | ifeq ($(CONFIG_RELOCATABLE), y) |
| 16 | 16 | # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour |
| @@ -115,16 +115,20 @@ KBUILD_CPPFLAGS += -mbig-endian · 98 unmodified lines | ||
| 115 | 115 | CHECKFLAGS += -D__AARCH64EB__ |
| 116 | 116 | # Prefer the baremetal ELF build target, but not all toolchains include |
| 117 | 117 | # it so fall back to the standard linux version if needed. |
| 118 | −KBUILD_LDFLAGS += -EB $(call ld-option, -maarch64elfb, -maarch64linuxb) | |
| 118 | +KBUILD_LDFLAGS += -EB $(call ld-option, -maarch64elfb, -maarch64linuxb -z norelro) | |
| 119 | 119 | UTS_MACHINE := aarch64_be |
| 120 | 120 | else |
| 121 | 121 | KBUILD_CPPFLAGS += -mlittle-endian |
| 122 | 122 | CHECKFLAGS += -D__AARCH64EL__ |
| 123 | 123 | # Same as above, prefer ELF but fall back to linux target if needed. |
| 124 | −KBUILD_LDFLAGS += -EL $(call ld-option, -maarch64elf, -maarch64linux) | |
| 124 | +KBUILD_LDFLAGS += -EL $(call ld-option, -maarch64elf, -maarch64linux -z norelro) | |
| 125 | 125 | UTS_MACHINE := aarch64 |
| 126 | 126 | endif |
| 127 | 127 | |
| 128 | +ifeq ($(CONFIG_LD_IS_LLD), y) | |
| 129 | +KBUILD_LDFLAGS += -z norelro | |
| 130 | +endif | |
| 131 | + | |
| 128 | 132 | CHECKFLAGS += -D__aarch64__ |
| 129 | 133 | |
| 130 | 134 | ifeq ($(CONFIG_DYNAMIC_FTRACE_WITH_REGS),y) |
| @@ -280,8 +280,6 @@ · 279 unmodified lines | ||
| 280 | 280 | "timing-adjustment"; |
| 281 | 281 | rx-fifo-depth = <4096>; |
| 282 | 282 | tx-fifo-depth = <2048>; |
| 283 | − resets = <&reset RESET_ETHERNET>; | |
| 284 | − reset-names = "stmmaceth"; | |
| 285 | 283 | power-domains = <&pwrc PWRC_AXG_ETHERNET_MEM_ID>; |
| 286 | 284 | status = "disabled"; |
| 287 | 285 | }; |
| @@ -224,8 +224,6 @@ · 223 unmodified lines | ||
| 224 | 224 | "timing-adjustment"; |
| 225 | 225 | rx-fifo-depth = <4096>; |
| 226 | 226 | tx-fifo-depth = <2048>; |
| 227 | − resets = <&reset RESET_ETHERNET>; | |
| 228 | − reset-names = "stmmaceth"; | |
| 229 | 227 | status = "disabled"; |
| 230 | 228 | |
| 231 | 229 | mdio0: mdio { |
| @@ -2390,7 +2388,7 @@ · 2158 unmodified lines | ||
| 2390 | 2388 | interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; |
| 2391 | 2389 | dr_mode = "host"; |
| 2392 | 2390 | snps,dis_u2_susphy_quirk; |
| 2393 | − snps,quirk-frame-length-adjustment; | |
| 2391 | + snps,quirk-frame-length-adjustment = <0x20>; | |
| 2394 | 2392 | snps,parkmode-disable-ss-quirk; |
| 2395 | 2393 | }; |
| 2396 | 2394 | }; |
| @@ -13,7 +13,6 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <dt-bindings/interrupt-controller/irq.h> |
| 14 | 14 | #include <dt-bindings/interrupt-controller/arm-gic.h> |
| 15 | 15 | #include <dt-bindings/power/meson-gxbb-power.h> |
| 16 | −#include <dt-bindings/reset/amlogic,meson-gxbb-reset.h> | |
| 17 | 16 | #include <dt-bindings/thermal/thermal.h> |
| 18 | 17 | |
| 19 | 18 | / { |
| @@ -576,8 +575,6 @@ · 556 unmodified lines | ||
| 576 | 575 | interrupt-names = "macirq"; |
| 577 | 576 | rx-fifo-depth = <4096>; |
| 578 | 577 | tx-fifo-depth = <2048>; |
| 579 | − resets = <&reset RESET_ETHERNET>; | |
| 580 | − reset-names = "stmmaceth"; | |
| 581 | 578 | power-domains = <&pwrc PWRC_GXBB_ETHERNET_MEM_ID>; |
| 582 | 579 | status = "disabled"; |
| 583 | 580 | }; |
| @@ -52,7 +52,7 @@ · 51 unmodified lines | ||
| 52 | 52 | regulator-min-microvolt = <3300000>; |
| 53 | 53 | regulator-max-microvolt = <3300000>; |
| 54 | 54 | |
| 55 | − gpio = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>; | |
| 55 | + gpio = <&gpio_ao GPIOAO_3 GPIO_OPEN_DRAIN>; | |
| 56 | 56 | enable-active-high; |
| 57 | 57 | regulator-always-on; |
| 58 | 58 | }; |
| @@ -127,7 +127,7 @@ · 126 unmodified lines | ||
| 127 | 127 | compatible = "snps,dw-apb-gpio-port"; |
| 128 | 128 | gpio-controller; |
| 129 | 129 | #gpio-cells = <2>; |
| 130 | − snps,nr-gpios = <32>; | |
| 130 | + ngpios = <32>; | |
| 131 | 131 | reg = <0>; |
| 132 | 132 | interrupt-controller; |
| 133 | 133 | #interrupt-cells = <2>; |
| @@ -145,7 +145,7 @@ · 11 unmodified lines | ||
| 145 | 145 | compatible = "snps,dw-apb-gpio-port"; |
| 146 | 146 | gpio-controller; |
| 147 | 147 | #gpio-cells = <2>; |
| 148 | − snps,nr-gpios = <32>; | |
| 148 | + ngpios = <32>; | |
| 149 | 149 | reg = <0>; |
| 150 | 150 | interrupt-controller; |
| 151 | 151 | #interrupt-cells = <2>; |
| @@ -163,7 +163,7 @@ · 11 unmodified lines | ||
| 163 | 163 | compatible = "snps,dw-apb-gpio-port"; |
| 164 | 164 | gpio-controller; |
| 165 | 165 | #gpio-cells = <2>; |
| 166 | − snps,nr-gpios = <8>; | |
| 166 | + ngpios = <8>; | |
| 167 | 167 | reg = <0>; |
| 168 | 168 | interrupt-controller; |
| 169 | 169 | #interrupt-cells = <2>; |
| @@ -4,11 +4,16 @@ · 3 unmodified lines | ||
| 4 | 4 | */ |
| 5 | 5 | usb { |
| 6 | 6 | compatible = "simple-bus"; |
| 7 | − dma-ranges; | |
| 8 | 7 | #address-cells = <2>; |
| 9 | 8 | #size-cells = <2>; |
| 10 | 9 | ranges = <0x0 0x0 0x0 0x68500000 0x0 0x00400000>; |
| 11 | 10 | |
| 11 | + /* | |
| 12 | + * Internally, USB bus to the interconnect can only address up | |
| 13 | + * to 40-bit | |
| 14 | + */ | |
| 15 | + dma-ranges = <0 0 0 0 0x100 0x0>; | |
| 16 | + | |
| 12 | 17 | usbphy0: usb-phy@0 { |
| 13 | 18 | compatible = "brcm,sr-usb-combo-phy"; |
| 14 | 19 | reg = <0x0 0x00000000 0x0 0x100>; |
| @@ -101,7 +101,7 @@ · 100 unmodified lines | ||
| 101 | 101 | reboot { |
| 102 | 102 | compatible ="syscon-reboot"; |
| 103 | 103 | regmap = <&rst>; |
| 104 | − offset = <0xb0>; | |
| 104 | + offset = <0>; | |
| 105 | 105 | mask = <0x02>; |
| 106 | 106 | }; |
| 107 | 107 | |
| @@ -385,7 +385,7 @@ · 384 unmodified lines | ||
| 385 | 385 | |
| 386 | 386 | dcfg: dcfg@1ee0000 { |
| 387 | 387 | compatible = "fsl,ls1046a-dcfg", "syscon"; |
| 388 | − reg = <0x0 0x1ee0000 0x0 0x10000>; | |
| 388 | + reg = <0x0 0x1ee0000 0x0 0x1000>; | |
| 389 | 389 | big-endian; |
| 390 | 390 | }; |
| 391 | 391 | |
| @@ -253,7 +253,7 @@ · 252 unmodified lines | ||
| 253 | 253 | #size-cells = <1>; |
| 254 | 254 | ranges; |
| 255 | 255 | |
| 256 | − spba: bus@30000000 { | |
| 256 | + spba: spba-bus@30000000 { | |
| 257 | 257 | compatible = "fsl,spba-bus", "simple-bus"; |
| 258 | 258 | #address-cells = <1>; |
| 259 | 259 | #size-cells = <1>; |
| @@ -266,7 +266,7 @@ · 265 unmodified lines | ||
| 266 | 266 | #gpio-cells = <2>; |
| 267 | 267 | interrupt-controller; |
| 268 | 268 | #interrupt-cells = <2>; |
| 269 | − gpio-ranges = <&iomuxc 0 56 26>, <&iomuxc 0 144 4>; | |
| 269 | + gpio-ranges = <&iomuxc 0 56 26>, <&iomuxc 26 144 4>; | |
| 270 | 270 | }; |
| 271 | 271 | |
| 272 | 272 | gpio4: gpio@30230000 { |
| @@ -415,7 +415,9 @@ · 414 unmodified lines | ||
| 415 | 415 | &gcc { |
| 416 | 416 | protected-clocks = <GCC_QSPI_CORE_CLK>, |
| 417 | 417 | <GCC_QSPI_CORE_CLK_SRC>, |
| 418 | − <GCC_QSPI_CNOC_PERIPH_AHB_CLK>; | |
| 418 | + <GCC_QSPI_CNOC_PERIPH_AHB_CLK>, | |
| 419 | + <GCC_LPASS_Q6_AXI_CLK>, | |
| 420 | + <GCC_LPASS_SWAY_CLK>; | |
| 419 | 421 | }; |
| 420 | 422 | |
| 421 | 423 | &gpu { |
| @@ -302,7 +302,9 @@ · 301 unmodified lines | ||
| 302 | 302 | &gcc { |
| 303 | 303 | protected-clocks = <GCC_QSPI_CORE_CLK>, |
| 304 | 304 | <GCC_QSPI_CORE_CLK_SRC>, |
| 305 | − <GCC_QSPI_CNOC_PERIPH_AHB_CLK>; | |
| 305 | + <GCC_QSPI_CNOC_PERIPH_AHB_CLK>, | |
| 306 | + <GCC_LPASS_Q6_AXI_CLK>, | |
| 307 | + <GCC_LPASS_SWAY_CLK>; | |
| 306 | 308 | }; |
| 307 | 309 | |
| 308 | 310 | &gpu { |
| @@ -320,6 +322,8 @@ · 11 unmodified lines | ||
| 320 | 322 | &i2c3 { |
| 321 | 323 | status = "okay"; |
| 322 | 324 | clock-frequency = <400000>; |
| 325 | + /* Overwrite pinctrl-0 from sdm845.dtsi */ | |
| 326 | + pinctrl-0 = <&qup_i2c3_default &i2c3_hid_active>; | |
| 323 | 327 | |
| 324 | 328 | tsel: hid@15 { |
| 325 | 329 | compatible = "hid-over-i2c"; |
| @@ -327,9 +331,6 @@ · 1 unmodified line | ||
| 327 | 331 | hid-descr-addr = <0x1>; |
| 328 | 332 | |
| 329 | 333 | interrupts-extended = <&tlmm 37 IRQ_TYPE_LEVEL_HIGH>; |
| 330 | − | |
| 331 | − pinctrl-names = "default"; | |
| 332 | − pinctrl-0 = <&i2c3_hid_active>; | |
| 333 | 334 | }; |
| 334 | 335 | |
| 335 | 336 | tsc2: hid@2c { |
| @@ -338,11 +339,6 @@ · 2 unmodified lines | ||
| 338 | 339 | hid-descr-addr = <0x20>; |
| 339 | 340 | |
| 340 | 341 | interrupts-extended = <&tlmm 37 IRQ_TYPE_LEVEL_HIGH>; |
| 341 | − | |
| 342 | − pinctrl-names = "default"; | |
| 343 | − pinctrl-0 = <&i2c3_hid_active>; | |
| 344 | − | |
| 345 | − status = "disabled"; | |
| 346 | 342 | }; |
| 347 | 343 | }; |
| 348 | 344 | |
| @@ -1097,7 +1097,7 @@ · 1096 unmodified lines | ||
| 1097 | 1097 | vopl_mmu: iommu@ff470f00 { |
| 1098 | 1098 | compatible = "rockchip,iommu"; |
| 1099 | 1099 | reg = <0x0 0xff470f00 0x0 0x100>; |
| 1100 | − interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; | |
| 1100 | + interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; | |
| 1101 | 1101 | interrupt-names = "vopl_mmu"; |
| 1102 | 1102 | clocks = <&cru ACLK_VOPL>, <&cru HCLK_VOPL>; |
| 1103 | 1103 | clock-names = "aclk", "iface"; |
| @@ -114,6 +114,10 @@ · 113 unmodified lines | ||
| 114 | 114 | cpu-supply = <&vdd_arm>; |
| 115 | 115 | }; |
| 116 | 116 | |
| 117 | +&display_subsystem { | |
| 118 | + status = "disabled"; | |
| 119 | +}; | |
| 120 | + | |
| 117 | 121 | &gmac2io { |
| 118 | 122 | assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; |
| 119 | 123 | assigned-clock-parents = <&gmac_clk>, <&gmac_clk>; |
| @@ -790,7 +790,6 @@ · 789 unmodified lines | ||
| 790 | 790 | &pcie0 { |
| 791 | 791 | bus-scan-delay-ms = <1000>; |
| 792 | 792 | ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; |
| 793 | − max-link-speed = <2>; | |
| 794 | 793 | num-lanes = <4>; |
| 795 | 794 | pinctrl-names = "default"; |
| 796 | 795 | pinctrl-0 = <&pcie_clkreqn_cpm>; |
| @@ -234,6 +234,7 @@ · 233 unmodified lines | ||
| 234 | 234 | reg = <0x0 0xf8000000 0x0 0x2000000>, |
| 235 | 235 | <0x0 0xfd000000 0x0 0x1000000>; |
| 236 | 236 | reg-names = "axi-base", "apb-base"; |
| 237 | + device_type = "pci"; | |
| 237 | 238 | #address-cells = <3>; |
| 238 | 239 | #size-cells = <2>; |
| 239 | 240 | #interrupt-cells = <1>; |
| @@ -252,7 +253,6 @@ · 12 unmodified lines | ||
| 252 | 253 | <0 0 0 2 &pcie0_intc 1>, |
| 253 | 254 | <0 0 0 3 &pcie0_intc 2>, |
| 254 | 255 | <0 0 0 4 &pcie0_intc 3>; |
| 255 | − linux,pci-domain = <0>; | |
| 256 | 256 | max-link-speed = <1>; |
| 257 | 257 | msi-map = <0x0 &its 0x0 0x1000>; |
| 258 | 258 | phys = <&pcie_phy 0>, <&pcie_phy 1>, |
| @@ -1278,7 +1278,6 @@ · 1019 unmodified lines | ||
| 1278 | 1278 | compatible = "rockchip,rk3399-vdec"; |
| 1279 | 1279 | reg = <0x0 0xff660000 0x0 0x400>; |
| 1280 | 1280 | interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH 0>; |
| 1281 | − interrupt-names = "vdpu"; | |
| 1282 | 1281 | clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>, |
| 1283 | 1282 | <&cru SCLK_VDU_CA>, <&cru SCLK_VDU_CORE>; |
| 1284 | 1283 | clock-names = "axi", "ahb", "cabac", "core"; |
| @@ -991,8 +991,6 @@ CONFIG_ARCH_TEGRA_210_SOC=y · 990 unmodified lines | ||
| 991 | 991 | CONFIG_ARCH_TEGRA_186_SOC=y |
| 992 | 992 | CONFIG_ARCH_TEGRA_194_SOC=y |
| 993 | 993 | CONFIG_ARCH_TEGRA_234_SOC=y |
| 994 | −CONFIG_ARCH_K3_AM6_SOC=y | |
| 995 | −CONFIG_ARCH_K3_J721E_SOC=y | |
| 996 | 994 | CONFIG_TI_SCI_PM_DOMAINS=y |
| 997 | 995 | CONFIG_EXTCON_PTN5150=m |
| 998 | 996 | CONFIG_EXTCON_USB_GPIO=y |
| @@ -1078,7 +1076,7 @@ CONFIG_INTERCONNECT=y · 79 unmodified lines | ||
| 1078 | 1076 | CONFIG_INTERCONNECT_QCOM=y |
| 1079 | 1077 | CONFIG_INTERCONNECT_QCOM_MSM8916=m |
| 1080 | 1078 | CONFIG_INTERCONNECT_QCOM_OSM_L3=m |
| 1081 | −CONFIG_INTERCONNECT_QCOM_SDM845=m | |
| 1079 | +CONFIG_INTERCONNECT_QCOM_SDM845=y | |
| 1082 | 1080 | CONFIG_INTERCONNECT_QCOM_SM8150=m |
| 1083 | 1081 | CONFIG_INTERCONNECT_QCOM_SM8250=m |
| 1084 | 1082 | CONFIG_EXT2_FS=y |
| @@ -17,7 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <asm/lse.h> |
| 18 | 18 | |
| 19 | 19 | #define ATOMIC_OP(op) \ |
| 20 | −static inline void arch_##op(int i, atomic_t *v) \ | |
| 20 | +static __always_inline void arch_##op(int i, atomic_t *v) \ | |
| 21 | 21 | { \ |
| 22 | 22 | __lse_ll_sc_body(op, i, v); \ |
| 23 | 23 | } |
| @@ -32,7 +32,7 @@ ATOMIC_OP(atomic_sub) · 8 unmodified lines | ||
| 32 | 32 | #undef ATOMIC_OP |
| 33 | 33 | |
| 34 | 34 | #define ATOMIC_FETCH_OP(name, op) \ |
| 35 | −static inline int arch_##op##name(int i, atomic_t *v) \ | |
| 35 | +static __always_inline int arch_##op##name(int i, atomic_t *v) \ | |
| 36 | 36 | { \ |
| 37 | 37 | return __lse_ll_sc_body(op##name, i, v); \ |
| 38 | 38 | } |
| @@ -56,7 +56,7 @@ ATOMIC_FETCH_OPS(atomic_sub_return) · 17 unmodified lines | ||
| 56 | 56 | #undef ATOMIC_FETCH_OPS |
| 57 | 57 | |
| 58 | 58 | #define ATOMIC64_OP(op) \ |
| 59 | −static inline void arch_##op(long i, atomic64_t *v) \ | |
| 59 | +static __always_inline void arch_##op(long i, atomic64_t *v) \ | |
| 60 | 60 | { \ |
| 61 | 61 | __lse_ll_sc_body(op, i, v); \ |
| 62 | 62 | } |
| @@ -71,7 +71,7 @@ ATOMIC64_OP(atomic64_sub) · 8 unmodified lines | ||
| 71 | 71 | #undef ATOMIC64_OP |
| 72 | 72 | |
| 73 | 73 | #define ATOMIC64_FETCH_OP(name, op) \ |
| 74 | −static inline long arch_##op##name(long i, atomic64_t *v) \ | |
| 74 | +static __always_inline long arch_##op##name(long i, atomic64_t *v) \ | |
| 75 | 75 | { \ |
| 76 | 76 | return __lse_ll_sc_body(op##name, i, v); \ |
| 77 | 77 | } |
| @@ -94,7 +94,7 @@ ATOMIC64_FETCH_OPS(atomic64_sub_return) · 16 unmodified lines | ||
| 94 | 94 | #undef ATOMIC64_FETCH_OP |
| 95 | 95 | #undef ATOMIC64_FETCH_OPS |
| 96 | 96 | |
| 97 | −static inline long arch_atomic64_dec_if_positive(atomic64_t *v) | |
| 97 | +static __always_inline long arch_atomic64_dec_if_positive(atomic64_t *v) | |
| 98 | 98 | { |
| 99 | 99 | return __lse_ll_sc_body(atomic64_dec_if_positive, v); |
| 100 | 100 | } |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/jump_label.h> |
| 18 | 18 | #include <linux/kvm_types.h> |
| 19 | 19 | #include <linux/percpu.h> |
| 20 | +#include <linux/psci.h> | |
| 20 | 21 | #include <asm/arch_gicv3.h> |
| 21 | 22 | #include <asm/barrier.h> |
| 22 | 23 | #include <asm/cpufeature.h> |
| @@ -240,6 +241,28 @@ struct kvm_host_data { · 217 unmodified lines | ||
| 240 | 241 | struct kvm_pmu_events pmu_events; |
| 241 | 242 | }; |
| 242 | 243 | |
| 244 | +struct kvm_host_psci_config { | |
| 245 | + /* PSCI version used by host. */ | |
| 246 | + u32 version; | |
| 247 | + | |
| 248 | + /* Function IDs used by host if version is v0.1. */ | |
| 249 | + struct psci_0_1_function_ids function_ids_0_1; | |
| 250 | + | |
| 251 | + bool psci_0_1_cpu_suspend_implemented; | |
| 252 | + bool psci_0_1_cpu_on_implemented; | |
| 253 | + bool psci_0_1_cpu_off_implemented; | |
| 254 | + bool psci_0_1_migrate_implemented; | |
| 255 | +}; | |
| 256 | + | |
| 257 | +extern struct kvm_host_psci_config kvm_nvhe_sym(kvm_host_psci_config); | |
| 258 | +#define kvm_host_psci_config CHOOSE_NVHE_SYM(kvm_host_psci_config) | |
| 259 | + | |
| 260 | +extern s64 kvm_nvhe_sym(hyp_physvirt_offset); | |
| 261 | +#define hyp_physvirt_offset CHOOSE_NVHE_SYM(hyp_physvirt_offset) | |
| 262 | + | |
| 263 | +extern u64 kvm_nvhe_sym(hyp_cpu_logical_map)[NR_CPUS]; | |
| 264 | +#define hyp_cpu_logical_map CHOOSE_NVHE_SYM(hyp_cpu_logical_map) | |
| 265 | + | |
| 243 | 266 | struct vcpu_reset_state { |
| 244 | 267 | unsigned long pc; |
| 245 | 268 | unsigned long r0; |
| @@ -247,11 +247,13 @@ static inline const void *__tag_set(const void *addr, u8 tag) · 246 unmodified lines | ||
| 247 | 247 | |
| 248 | 248 | |
| 249 | 249 | /* |
| 250 | − * The linear kernel range starts at the bottom of the virtual address space. | |
| 250 | + * Check whether an arbitrary address is within the linear map, which | |
| 251 | + * lives in the [PAGE_OFFSET, PAGE_END) interval at the bottom of the | |
| 252 | + * kernel's TTBR1 address range. | |
| 251 | 253 | */ |
| 252 | −#define __is_lm_address(addr) (((u64)(addr) & ~PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET)) | |
| 254 | +#define __is_lm_address(addr) (((u64)(addr) - PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET)) | |
| 253 | 255 | |
| 254 | −#define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET) | |
| 256 | +#define __lm_to_phys(addr) (((addr) - PAGE_OFFSET) + PHYS_OFFSET) | |
| 255 | 257 | #define __kimg_to_phys(addr) ((addr) - kimage_voffset) |
| 256 | 258 | |
| 257 | 259 | #define __virt_to_phys_nodebug(x) ({ \ |
| @@ -330,7 +332,7 @@ static inline void *phys_to_virt(phys_addr_t x) · 72 unmodified lines | ||
| 330 | 332 | #endif /* !CONFIG_SPARSEMEM_VMEMMAP || CONFIG_DEBUG_VIRTUAL */ |
| 331 | 333 | |
| 332 | 334 | #define virt_addr_valid(addr) ({ \ |
| 333 | − __typeof__(addr) __addr = addr; \ | |
| 335 | + __typeof__(addr) __addr = __tag_reset(addr); \ | |
| 334 | 336 | __is_lm_address(__addr) && pfn_valid(virt_to_pfn(__addr)); \ |
| 335 | 337 | }) |
| 336 | 338 | |
| @@ -176,10 +176,21 @@ static inline void __uaccess_enable_hw_pan(void) · 175 unmodified lines | ||
| 176 | 176 | * The Tag check override (TCO) bit disables temporarily the tag checking |
| 177 | 177 | * preventing the issue. |
| 178 | 178 | */ |
| 179 | −static inline void uaccess_disable_privileged(void) | |
| 179 | +static inline void __uaccess_disable_tco(void) | |
| 180 | 180 | { |
| 181 | 181 | asm volatile(ALTERNATIVE("nop", SET_PSTATE_TCO(0), |
| 182 | 182 | ARM64_MTE, CONFIG_KASAN_HW_TAGS)); |
| 183 | +} | |
| 184 | + | |
| 185 | +static inline void __uaccess_enable_tco(void) | |
| 186 | +{ | |
| 187 | + asm volatile(ALTERNATIVE("nop", SET_PSTATE_TCO(1), | |
| 188 | + ARM64_MTE, CONFIG_KASAN_HW_TAGS)); | |
| 189 | +} | |
| 190 | + | |
| 191 | +static inline void uaccess_disable_privileged(void) | |
| 192 | +{ | |
| 193 | + __uaccess_disable_tco(); | |
| 183 | 194 | |
| 184 | 195 | if (uaccess_ttbr0_disable()) |
| 185 | 196 | return; |
| @@ -189,8 +200,7 @@ static inline void uaccess_disable_privileged(void) · 3 unmodified lines | ||
| 189 | 200 | |
| 190 | 201 | static inline void uaccess_enable_privileged(void) |
| 191 | 202 | { |
| 192 | − asm volatile(ALTERNATIVE("nop", SET_PSTATE_TCO(1), | |
| 193 | − ARM64_MTE, CONFIG_KASAN_HW_TAGS)); | |
| 203 | + __uaccess_enable_tco(); | |
| 194 | 204 | |
| 195 | 205 | if (uaccess_ttbr0_enable()) |
| 196 | 206 | return; |
| @@ -75,7 +75,7 @@ int main(void) · 74 unmodified lines | ||
| 75 | 75 | DEFINE(S_SDEI_TTBR1, offsetof(struct pt_regs, sdei_ttbr1)); |
| 76 | 76 | DEFINE(S_PMR_SAVE, offsetof(struct pt_regs, pmr_save)); |
| 77 | 77 | DEFINE(S_STACKFRAME, offsetof(struct pt_regs, stackframe)); |
| 78 | − DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs)); | |
| 78 | + DEFINE(PT_REGS_SIZE, sizeof(struct pt_regs)); | |
| 79 | 79 | BLANK(); |
| 80 | 80 | #ifdef CONFIG_COMPAT |
| 81 | 81 | DEFINE(COMPAT_SIGFRAME_REGS_OFFSET, offsetof(struct compat_sigframe, uc.uc_mcontext.arm_r0)); |
| @@ -1701,16 +1701,12 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused) · 1700 unmodified lines | ||
| 1701 | 1701 | #ifdef CONFIG_ARM64_MTE |
| 1702 | 1702 | static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) |
| 1703 | 1703 | { |
| 1704 | − static bool cleared_zero_page = false; | |
| 1705 | − | |
| 1706 | 1704 | /* |
| 1707 | 1705 | * Clear the tags in the zero page. This needs to be done via the |
| 1708 | 1706 | * linear map which has the Tagged attribute. |
| 1709 | 1707 | */ |
| 1710 | − if (!cleared_zero_page) { | |
| 1711 | − cleared_zero_page = true; | |
| 1708 | + if (!test_and_set_bit(PG_mte_tagged, &ZERO_PAGE(0)->flags)) | |
| 1712 | 1709 | mte_clear_page_tags(lm_alias(empty_zero_page)); |
| 1713 | − } | |
| 1714 | 1710 | |
| 1715 | 1711 | kasan_init_hw_tags_cpu(); |
| 1716 | 1712 | } |
| @@ -2568,7 +2564,7 @@ static void verify_hyp_capabilities(void) · 851 unmodified lines | ||
| 2568 | 2564 | int parange, ipa_max; |
| 2569 | 2565 | unsigned int safe_vmid_bits, vmid_bits; |
| 2570 | 2566 | |
| 2571 | − if (!IS_ENABLED(CONFIG_KVM) || !IS_ENABLED(CONFIG_KVM_ARM_HOST)) | |
| 2567 | + if (!IS_ENABLED(CONFIG_KVM)) | |
| 2572 | 2568 | return; |
| 2573 | 2569 | |
| 2574 | 2570 | safe_mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1); |
| @@ -35,7 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | */ |
| 36 | 36 | .macro ftrace_regs_entry, allregs=0 |
| 37 | 37 | /* Make room for pt_regs, plus a callee frame */ |
| 38 | − sub sp, sp, #(S_FRAME_SIZE + 16) | |
| 38 | + sub sp, sp, #(PT_REGS_SIZE + 16) | |
| 39 | 39 | |
| 40 | 40 | /* Save function arguments (and x9 for simplicity) */ |
| 41 | 41 | stp x0, x1, [sp, #S_X0] |
| @@ -61,15 +61,15 @@ · 19 unmodified lines | ||
| 61 | 61 | .endif |
| 62 | 62 | |
| 63 | 63 | /* Save the callsite's SP and LR */ |
| 64 | − add x10, sp, #(S_FRAME_SIZE + 16) | |
| 64 | + add x10, sp, #(PT_REGS_SIZE + 16) | |
| 65 | 65 | stp x9, x10, [sp, #S_LR] |
| 66 | 66 | |
| 67 | 67 | /* Save the PC after the ftrace callsite */ |
| 68 | 68 | str x30, [sp, #S_PC] |
| 69 | 69 | |
| 70 | 70 | /* Create a frame record for the callsite above pt_regs */ |
| 71 | − stp x29, x9, [sp, #S_FRAME_SIZE] | |
| 72 | − add x29, sp, #S_FRAME_SIZE | |
| 71 | + stp x29, x9, [sp, #PT_REGS_SIZE] | |
| 72 | + add x29, sp, #PT_REGS_SIZE | |
| 73 | 73 | |
| 74 | 74 | /* Create our frame record within pt_regs. */ |
| 75 | 75 | stp x29, x30, [sp, #S_STACKFRAME] |
| @@ -120,7 +120,7 @@ ftrace_common_return: · 44 unmodified lines | ||
| 120 | 120 | ldr x9, [sp, #S_PC] |
| 121 | 121 | |
| 122 | 122 | /* Restore the callsite's SP */ |
| 123 | − add sp, sp, #S_FRAME_SIZE + 16 | |
| 123 | + add sp, sp, #PT_REGS_SIZE + 16 | |
| 124 | 124 | |
| 125 | 125 | ret x9 |
| 126 | 126 | SYM_CODE_END(ftrace_common) |
| @@ -130,7 +130,7 @@ SYM_CODE_START(ftrace_graph_caller) · 3 unmodified lines | ||
| 130 | 130 | ldr x0, [sp, #S_PC] |
| 131 | 131 | sub x0, x0, #AARCH64_INSN_SIZE // ip (callsite's BL insn) |
| 132 | 132 | add x1, sp, #S_LR // parent_ip (callsite's LR) |
| 133 | − ldr x2, [sp, #S_FRAME_SIZE] // parent fp (callsite's FP) | |
| 133 | + ldr x2, [sp, #PT_REGS_SIZE] // parent fp (callsite's FP) | |
| 134 | 134 | bl prepare_ftrace_return |
| 135 | 135 | b ftrace_common_return |
| 136 | 136 | SYM_CODE_END(ftrace_graph_caller) |
| @@ -75,7 +75,7 @@ alternative_else_nop_endif · 74 unmodified lines | ||
| 75 | 75 | .endif |
| 76 | 76 | #endif |
| 77 | 77 | |
| 78 | − sub sp, sp, #S_FRAME_SIZE | |
| 78 | + sub sp, sp, #PT_REGS_SIZE | |
| 79 | 79 | #ifdef CONFIG_VMAP_STACK |
| 80 | 80 | /* |
| 81 | 81 | * Test whether the SP has overflowed, without corrupting a GPR. |
| @@ -96,7 +96,7 @@ alternative_else_nop_endif · 14 unmodified lines | ||
| 96 | 96 | * userspace, and can clobber EL0 registers to free up GPRs. |
| 97 | 97 | */ |
| 98 | 98 | |
| 99 | − /* Stash the original SP (minus S_FRAME_SIZE) in tpidr_el0. */ | |
| 99 | + /* Stash the original SP (minus PT_REGS_SIZE) in tpidr_el0. */ | |
| 100 | 100 | msr tpidr_el0, x0 |
| 101 | 101 | |
| 102 | 102 | /* Recover the original x0 value and stash it in tpidrro_el0 */ |
| @@ -182,7 +182,6 @@ alternative_else_nop_endif · 79 unmodified lines | ||
| 182 | 182 | mrs_s \tmp2, SYS_GCR_EL1 |
| 183 | 183 | bfi \tmp2, \tmp, #0, #16 |
| 184 | 184 | msr_s SYS_GCR_EL1, \tmp2 |
| 185 | − isb | |
| 186 | 185 | #endif |
| 187 | 186 | .endm |
| 188 | 187 | |
| @@ -194,6 +193,7 @@ alternative_else_nop_endif · 5 unmodified lines | ||
| 194 | 193 | ldr_l \tmp, gcr_kernel_excl |
| 195 | 194 | |
| 196 | 195 | mte_set_gcr \tmp, \tmp2 |
| 196 | + isb | |
| 197 | 197 | 1: |
| 198 | 198 | #endif |
| 199 | 199 | .endm |
| @@ -253,7 +253,7 @@ alternative_else_nop_endif · 53 unmodified lines | ||
| 253 | 253 | |
| 254 | 254 | scs_load tsk, x20 |
| 255 | 255 | .else |
| 256 | − add x21, sp, #S_FRAME_SIZE | |
| 256 | + add x21, sp, #PT_REGS_SIZE | |
| 257 | 257 | get_current_task tsk |
| 258 | 258 | .endif /* \el == 0 */ |
| 259 | 259 | mrs x22, elr_el1 |
| @@ -377,7 +377,7 @@ alternative_else_nop_endif · 117 unmodified lines | ||
| 377 | 377 | ldp x26, x27, [sp, #16 * 13] |
| 378 | 378 | ldp x28, x29, [sp, #16 * 14] |
| 379 | 379 | ldr lr, [sp, #S_LR] |
| 380 | − add sp, sp, #S_FRAME_SIZE // restore sp | |
| 380 | + add sp, sp, #PT_REGS_SIZE // restore sp | |
| 381 | 381 | |
| 382 | 382 | .if \el == 0 |
| 383 | 383 | alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0 |
| @@ -580,12 +580,12 @@ __bad_stack: · 196 unmodified lines | ||
| 580 | 580 | |
| 581 | 581 | /* |
| 582 | 582 | * Store the original GPRs to the new stack. The orginal SP (minus |
| 583 | − * S_FRAME_SIZE) was stashed in tpidr_el0 by kernel_ventry. | |
| 583 | + * PT_REGS_SIZE) was stashed in tpidr_el0 by kernel_ventry. | |
| 584 | 584 | */ |
| 585 | − sub sp, sp, #S_FRAME_SIZE | |
| 585 | + sub sp, sp, #PT_REGS_SIZE | |
| 586 | 586 | kernel_entry 1 |
| 587 | 587 | mrs x0, tpidr_el0 |
| 588 | − add x0, x0, #S_FRAME_SIZE | |
| 588 | + add x0, x0, #PT_REGS_SIZE | |
| 589 | 589 | str x0, [sp, #S_SP] |
| 590 | 590 | |
| 591 | 591 | /* Stash the regs for handle_bad_stack */ |
| @@ -329,11 +329,12 @@ static int __access_remote_tags(struct mm_struct *mm, unsigned long addr, · 328 unmodified lines | ||
| 329 | 329 | * would cause the existing tags to be cleared if the page |
| 330 | 330 | * was never mapped with PROT_MTE. |
| 331 | 331 | */ |
| 332 | − if (!test_bit(PG_mte_tagged, &page->flags)) { | |
| 332 | + if (!(vma->vm_flags & VM_MTE)) { | |
| 333 | 333 | ret = -EOPNOTSUPP; |
| 334 | 334 | put_page(page); |
| 335 | 335 | break; |
| 336 | 336 | } |
| 337 | + WARN_ON_ONCE(!test_bit(PG_mte_tagged, &page->flags)); | |
| 337 | 338 | |
| 338 | 339 | /* limit access to the end of the page */ |
| 339 | 340 | offset = offset_in_page(addr); |
| @@ -23,8 +23,6 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <linux/platform_device.h> |
| 24 | 24 | #include <linux/sched_clock.h> |
| 25 | 25 | #include <linux/smp.h> |
| 26 | −#include <linux/nmi.h> | |
| 27 | −#include <linux/cpufreq.h> | |
| 28 | 26 | |
| 29 | 27 | /* ARMv8 Cortex-A53 specific event types. */ |
| 30 | 28 | #define ARMV8_A53_PERFCTR_PREF_LINEFILL 0xC2 |
| @@ -1250,21 +1248,10 @@ static struct platform_driver armv8_pmu_driver = { · 1219 unmodified lines | ||
| 1250 | 1248 | |
| 1251 | 1249 | static int __init armv8_pmu_driver_init(void) |
| 1252 | 1250 | { |
| 1253 | − int ret; | |
| 1254 | − | |
| 1255 | 1251 | if (acpi_disabled) |
| 1256 | − ret = platform_driver_register(&armv8_pmu_driver); | |
| 1252 | + return platform_driver_register(&armv8_pmu_driver); | |
| 1257 | 1253 | else |
| 1258 | − ret = arm_pmu_acpi_probe(armv8_pmuv3_init); | |
| 1259 | − | |
| 1260 | − /* | |
| 1261 | − * Try to re-initialize lockup detector after PMU init in | |
| 1262 | − * case PMU events are triggered via NMIs. | |
| 1263 | − */ | |
| 1264 | − if (ret == 0 && arm_pmu_irq_is_nmi()) | |
| 1265 | − lockup_detector_init(); | |
| 1266 | − | |
| 1267 | − return ret; | |
| 1254 | + return arm_pmu_acpi_probe(armv8_pmuv3_init); | |
| 1268 | 1255 | } |
| 1269 | 1256 | device_initcall(armv8_pmu_driver_init) |
| 1270 | 1257 | |
| @@ -1322,27 +1309,3 @@ void arch_perf_update_userpage(struct perf_event *event, · 51 unmodified lines | ||
| 1322 | 1309 | userpg->cap_user_time_zero = 1; |
| 1323 | 1310 | userpg->cap_user_time_short = 1; |
| 1324 | 1311 | } |
| 1325 | − | |
| 1326 | −#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF | |
| 1327 | −/* | |
| 1328 | − * Safe maximum CPU frequency in case a particular platform doesn't implement | |
| 1329 | − * cpufreq driver. Although, architecture doesn't put any restrictions on | |
| 1330 | − * maximum frequency but 5 GHz seems to be safe maximum given the available | |
| 1331 | − * Arm CPUs in the market which are clocked much less than 5 GHz. On the other | |
| 1332 | − * hand, we can't make it much higher as it would lead to a large hard-lockup | |
| 1333 | − * detection timeout on parts which are running slower (eg. 1GHz on | |
| 1334 | − * Developerbox) and doesn't possess a cpufreq driver. | |
| 1335 | − */ | |
| 1336 | −#define SAFE_MAX_CPU_FREQ 5000000000UL // 5 GHz | |
| 1337 | −u64 hw_nmi_get_sample_period(int watchdog_thresh) | |
| 1338 | −{ | |
| 1339 | − unsigned int cpu = smp_processor_id(); | |
| 1340 | − unsigned long max_cpu_freq; | |
| 1341 | − | |
| 1342 | − max_cpu_freq = cpufreq_get_hw_max_freq(cpu) * 1000UL; | |
| 1343 | − if (!max_cpu_freq) | |
| 1344 | − max_cpu_freq = SAFE_MAX_CPU_FREQ; | |
| 1345 | − | |
| 1346 | − return (u64)max_cpu_freq * watchdog_thresh; | |
| 1347 | −} | |
| 1348 | −#endif | |
| @@ -352,8 +352,8 @@ kprobe_breakpoint_ss_handler(struct pt_regs *regs, unsigned int esr) · 351 unmodified lines | ||
| 352 | 352 | unsigned long addr = instruction_pointer(regs); |
| 353 | 353 | struct kprobe *cur = kprobe_running(); |
| 354 | 354 | |
| 355 | − if (cur && (kcb->kprobe_status == KPROBE_HIT_SS) | |
| 356 | − && ((unsigned long)&cur->ainsn.api.insn[1] == addr)) { | |
| 355 | + if (cur && (kcb->kprobe_status & (KPROBE_HIT_SS | KPROBE_REENTER)) && | |
| 356 | + ((unsigned long)&cur->ainsn.api.insn[1] == addr)) { | |
| 357 | 357 | kprobes_restore_local_irqflag(kcb, regs); |
| 358 | 358 | post_kprobe_handler(cur, kcb, regs); |
| 359 | 359 | |
| @@ -25,7 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | stp x24, x25, [sp, #S_X24] |
| 26 | 26 | stp x26, x27, [sp, #S_X26] |
| 27 | 27 | stp x28, x29, [sp, #S_X28] |
| 28 | − add x0, sp, #S_FRAME_SIZE | |
| 28 | + add x0, sp, #PT_REGS_SIZE | |
| 29 | 29 | stp lr, x0, [sp, #S_LR] |
| 30 | 30 | /* |
| 31 | 31 | * Construct a useful saved PSTATE |
| @@ -62,7 +62,7 @@ · 30 unmodified lines | ||
| 62 | 62 | .endm |
| 63 | 63 | |
| 64 | 64 | SYM_CODE_START(kretprobe_trampoline) |
| 65 | − sub sp, sp, #S_FRAME_SIZE | |
| 65 | + sub sp, sp, #PT_REGS_SIZE | |
| 66 | 66 | |
| 67 | 67 | save_all_base_regs |
| 68 | 68 | |
| @@ -76,7 +76,7 @@ SYM_CODE_START(kretprobe_trampoline) · 7 unmodified lines | ||
| 76 | 76 | |
| 77 | 77 | restore_all_base_regs |
| 78 | 78 | |
| 79 | − add sp, sp, #S_FRAME_SIZE | |
| 79 | + add sp, sp, #PT_REGS_SIZE | |
| 80 | 80 | ret |
| 81 | 81 | |
| 82 | 82 | SYM_CODE_END(kretprobe_trampoline) |
| @@ -914,13 +914,6 @@ static void do_signal(struct pt_regs *regs) · 913 unmodified lines | ||
| 914 | 914 | asmlinkage void do_notify_resume(struct pt_regs *regs, |
| 915 | 915 | unsigned long thread_flags) |
| 916 | 916 | { |
| 917 | − /* | |
| 918 | − * The assembly code enters us with IRQs off, but it hasn't | |
| 919 | − * informed the tracing code of that for efficiency reasons. | |
| 920 | − * Update the trace code with the current status. | |
| 921 | − */ | |
| 922 | − trace_hardirqs_off(); | |
| 923 | − | |
| 924 | 917 | do { |
| 925 | 918 | if (thread_flags & _TIF_NEED_RESCHED) { |
| 926 | 919 | /* Unmask Debug and SError for the next task */ |
| @@ -434,7 +434,7 @@ static void __init hyp_mode_check(void) · 433 unmodified lines | ||
| 434 | 434 | "CPU: CPUs started in inconsistent modes"); |
| 435 | 435 | else |
| 436 | 436 | pr_info("CPU: All CPU(s) started at EL1\n"); |
| 437 | − if (IS_ENABLED(CONFIG_KVM)) | |
| 437 | + if (IS_ENABLED(CONFIG_KVM) && !is_kernel_in_hyp_mode()) | |
| 438 | 438 | kvm_compute_layout(); |
| 439 | 439 | } |
| 440 | 440 | |
| @@ -807,7 +807,6 @@ int arch_show_interrupts(struct seq_file *p, int prec) · 366 unmodified lines | ||
| 807 | 807 | unsigned int cpu, i; |
| 808 | 808 | |
| 809 | 809 | for (i = 0; i < NR_IPI; i++) { |
| 810 | − unsigned int irq = irq_desc_get_irq(ipi_desc[i]); | |
| 811 | 810 | seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i, |
| 812 | 811 | prec >= 4 ? " " : ""); |
| 813 | 812 | for_each_online_cpu(cpu) |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | #include <asm/daifflags.h> |
| 11 | 11 | #include <asm/debug-monitors.h> |
| 12 | +#include <asm/exception.h> | |
| 12 | 13 | #include <asm/fpsimd.h> |
| 13 | 14 | #include <asm/syscall.h> |
| 14 | 15 | #include <asm/thread_info.h> |
| @@ -165,15 +166,8 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, · 150 unmodified lines | ||
| 165 | 166 | if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) { |
| 166 | 167 | local_daif_mask(); |
| 167 | 168 | flags = current_thread_info()->flags; |
| 168 | − if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) { | |
| 169 | − /* | |
| 170 | − * We're off to userspace, where interrupts are | |
| 171 | − * always enabled after we restore the flags from | |
| 172 | − * the SPSR. | |
| 173 | − */ | |
| 174 | − trace_hardirqs_on(); | |
| 169 | + if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) | |
| 175 | 170 | return; |
| 176 | − } | |
| 177 | 171 | local_daif_restore(DAIF_PROCCTX); |
| 178 | 172 | } |
| 179 | 173 | |
| @@ -42,7 +42,6 @@ · 41 unmodified lines | ||
| 42 | 42 | #include <asm/smp.h> |
| 43 | 43 | #include <asm/stack_pointer.h> |
| 44 | 44 | #include <asm/stacktrace.h> |
| 45 | −#include <asm/exception.h> | |
| 46 | 45 | #include <asm/system_misc.h> |
| 47 | 46 | #include <asm/sysreg.h> |
| 48 | 47 | |
| @@ -24,8 +24,7 @@ btildflags-$(CONFIG_ARM64_BTI_KERNEL) += -z force-bti · 23 unmodified lines | ||
| 24 | 24 | # routines, as x86 does (see 6f121e548f83 ("x86, vdso: Reimplement vdso.so |
| 25 | 25 | # preparation in build-time C")). |
| 26 | 26 | ldflags-y := -shared -nostdlib -soname=linux-vdso.so.1 --hash-style=sysv \ |
| 27 | − -Bsymbolic $(call ld-option, --no-eh-frame-hdr) --build-id=sha1 -n \ | |
| 28 | − $(btildflags-y) -T | |
| 27 | + -Bsymbolic --build-id=sha1 -n $(btildflags-y) -T | |
| 29 | 28 | |
| 30 | 29 | ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18 |
| 31 | 30 | ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO |
| @@ -40,9 +40,6 @@ SECTIONS · 39 unmodified lines | ||
| 40 | 40 | PROVIDE (_etext = .); |
| 41 | 41 | PROVIDE (etext = .); |
| 42 | 42 | |
| 43 | − .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr | |
| 44 | − .eh_frame : { KEEP (*(.eh_frame)) } :text | |
| 45 | − | |
| 46 | 43 | .dynamic : { *(.dynamic) } :text :dynamic |
| 47 | 44 | |
| 48 | 45 | .rodata : { *(.rodata*) } :text |
| @@ -54,6 +51,7 @@ SECTIONS · 5 unmodified lines | ||
| 54 | 51 | *(.note.GNU-stack) |
| 55 | 52 | *(.data .data.* .gnu.linkonce.d.* .sdata*) |
| 56 | 53 | *(.bss .sbss .dynbss .dynsbss) |
| 54 | + *(.eh_frame .eh_frame_hdr) | |
| 57 | 55 | } |
| 58 | 56 | } |
| 59 | 57 | |
| @@ -66,7 +64,6 @@ PHDRS · 6 unmodified lines | ||
| 66 | 64 | text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ |
| 67 | 65 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ |
| 68 | 66 | note PT_NOTE FLAGS(4); /* PF_R */ |
| 69 | − eh_frame_hdr PT_GNU_EH_FRAME; | |
| 70 | 67 | } |
| 71 | 68 | |
| 72 | 69 | /* |
| @@ -49,14 +49,6 @@ if KVM · 48 unmodified lines | ||
| 49 | 49 | |
| 50 | 50 | source "virt/kvm/Kconfig" |
| 51 | 51 | |
| 52 | −config KVM_ARM_PMU | |
| 53 | − bool "Virtual Performance Monitoring Unit (PMU) support" | |
| 54 | − depends on HW_PERF_EVENTS | |
| 55 | − default y | |
| 56 | − help | |
| 57 | − Adds support for a virtual Performance Monitoring Unit (PMU) in | |
| 58 | − virtual machines. | |
| 59 | − | |
| 60 | 52 | endif # KVM |
| 61 | 53 | |
| 62 | 54 | endif # VIRTUALIZATION |
| @@ -24,4 +24,4 @@ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \ · 23 unmodified lines | ||
| 24 | 24 | vgic/vgic-mmio-v3.o vgic/vgic-kvm-device.o \ |
| 25 | 25 | vgic/vgic-its.o vgic/vgic-debug.o |
| 26 | 26 | |
| 27 | −kvm-$(CONFIG_KVM_ARM_PMU) += pmu-emul.o | |
| 27 | +kvm-$(CONFIG_HW_PERF_EVENTS) += pmu-emul.o | |
| @@ -1129,9 +1129,10 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) · 1128 unmodified lines | ||
| 1129 | 1129 | if (!irqchip_in_kernel(vcpu->kvm)) |
| 1130 | 1130 | goto no_vgic; |
| 1131 | 1131 | |
| 1132 | − if (!vgic_initialized(vcpu->kvm)) | |
| 1133 | − return -ENODEV; | |
| 1134 | − | |
| 1132 | + /* | |
| 1133 | + * At this stage, we have the guarantee that the vgic is both | |
| 1134 | + * available and initialized. | |
| 1135 | + */ | |
| 1135 | 1136 | if (!timer_irqs_are_valid(vcpu)) { |
| 1136 | 1137 | kvm_debug("incorrectly configured timer irqs\n"); |
| 1137 | 1138 | return -EINVAL; |
| @@ -65,10 +65,6 @@ static bool vgic_present; · 64 unmodified lines | ||
| 65 | 65 | static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled); |
| 66 | 66 | DEFINE_STATIC_KEY_FALSE(userspace_irqchip_in_use); |
| 67 | 67 | |
| 68 | −extern u64 kvm_nvhe_sym(__cpu_logical_map)[NR_CPUS]; | |
| 69 | −extern u32 kvm_nvhe_sym(kvm_host_psci_version); | |
| 70 | −extern struct psci_0_1_function_ids kvm_nvhe_sym(kvm_host_psci_0_1_function_ids); | |
| 71 | − | |
| 72 | 68 | int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) |
| 73 | 69 | { |
| 74 | 70 | return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE; |
| @@ -584,11 +580,9 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) · 509 unmodified lines | ||
| 584 | 580 | * Map the VGIC hardware resources before running a vcpu the |
| 585 | 581 | * first time on this VM. |
| 586 | 582 | */ |
| 587 | − if (unlikely(!vgic_ready(kvm))) { | |
| 588 | − ret = kvm_vgic_map_resources(kvm); | |
| 589 | − if (ret) | |
| 590 | − return ret; | |
| 591 | − } | |
| 583 | + ret = kvm_vgic_map_resources(kvm); | |
| 584 | + if (ret) | |
| 585 | + return ret; | |
| 592 | 586 | } else { |
| 593 | 587 | /* |
| 594 | 588 | * Tell the rest of the code that there are userspace irqchip |
| @@ -1402,8 +1396,9 @@ static void cpu_init_hyp_mode(void) · 807 unmodified lines | ||
| 1402 | 1396 | * Calculate the raw per-cpu offset without a translation from the |
| 1403 | 1397 | * kernel's mapping to the linear mapping, and store it in tpidr_el2 |
| 1404 | 1398 | * so that we can use adr_l to access per-cpu variables in EL2. |
| 1399 | + * Also drop the KASAN tag which gets in the way... | |
| 1405 | 1400 | */ |
| 1406 | − params->tpidr_el2 = (unsigned long)this_cpu_ptr_nvhe_sym(__per_cpu_start) - | |
| 1401 | + params->tpidr_el2 = (unsigned long)kasan_reset_tag(this_cpu_ptr_nvhe_sym(__per_cpu_start)) - | |
| 1407 | 1402 | (unsigned long)kvm_ksym_ref(CHOOSE_NVHE_SYM(__per_cpu_start)); |
| 1408 | 1403 | |
| 1409 | 1404 | params->mair_el2 = read_sysreg(mair_el1); |
| @@ -1574,12 +1569,12 @@ static struct notifier_block hyp_init_cpu_pm_nb = { · 164 unmodified lines | ||
| 1574 | 1569 | .notifier_call = hyp_init_cpu_pm_notifier, |
| 1575 | 1570 | }; |
| 1576 | 1571 | |
| 1577 | −static void __init hyp_cpu_pm_init(void) | |
| 1572 | +static void hyp_cpu_pm_init(void) | |
| 1578 | 1573 | { |
| 1579 | 1574 | if (!is_protected_kvm_enabled()) |
| 1580 | 1575 | cpu_pm_register_notifier(&hyp_init_cpu_pm_nb); |
| 1581 | 1576 | } |
| 1582 | −static void __init hyp_cpu_pm_exit(void) | |
| 1577 | +static void hyp_cpu_pm_exit(void) | |
| 1583 | 1578 | { |
| 1584 | 1579 | if (!is_protected_kvm_enabled()) |
| 1585 | 1580 | cpu_pm_unregister_notifier(&hyp_init_cpu_pm_nb); |
| @@ -1604,9 +1599,12 @@ static void init_cpu_logical_map(void) · 18 unmodified lines | ||
| 1604 | 1599 | * allow any other CPUs from the `possible` set to boot. |
| 1605 | 1600 | */ |
| 1606 | 1601 | for_each_online_cpu(cpu) |
| 1607 | − kvm_nvhe_sym(__cpu_logical_map)[cpu] = cpu_logical_map(cpu); | |
| 1602 | + hyp_cpu_logical_map[cpu] = cpu_logical_map(cpu); | |
| 1608 | 1603 | } |
| 1609 | 1604 | |
| 1605 | +#define init_psci_0_1_impl_state(config, what) \ | |
| 1606 | + config.psci_0_1_ ## what ## _implemented = psci_ops.what | |
| 1607 | + | |
| 1610 | 1608 | static bool init_psci_relay(void) |
| 1611 | 1609 | { |
| 1612 | 1610 | /* |
| @@ -1618,8 +1616,15 @@ static bool init_psci_relay(void) · 5 unmodified lines | ||
| 1618 | 1616 | return false; |
| 1619 | 1617 | } |
| 1620 | 1618 | |
| 1621 | − kvm_nvhe_sym(kvm_host_psci_version) = psci_ops.get_version(); | |
| 1622 | − kvm_nvhe_sym(kvm_host_psci_0_1_function_ids) = get_psci_0_1_function_ids(); | |
| 1619 | + kvm_host_psci_config.version = psci_ops.get_version(); | |
| 1620 | + | |
| 1621 | + if (kvm_host_psci_config.version == PSCI_VERSION(0, 1)) { | |
| 1622 | + kvm_host_psci_config.function_ids_0_1 = get_psci_0_1_function_ids(); | |
| 1623 | + init_psci_0_1_impl_state(kvm_host_psci_config, cpu_suspend); | |
| 1624 | + init_psci_0_1_impl_state(kvm_host_psci_config, cpu_on); | |
| 1625 | + init_psci_0_1_impl_state(kvm_host_psci_config, cpu_off); | |
| 1626 | + init_psci_0_1_impl_state(kvm_host_psci_config, migrate); | |
| 1627 | + } | |
| 1623 | 1628 | return true; |
| 1624 | 1629 | } |
| 1625 | 1630 | |
| @@ -59,4 +59,13 @@ static inline void __adjust_pc(struct kvm_vcpu *vcpu) · 58 unmodified lines | ||
| 59 | 59 | } |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | +/* | |
| 63 | + * Skip an instruction while host sysregs are live. | |
| 64 | + * Assumes host is always 64-bit. | |
| 65 | + */ | |
| 66 | +static inline void kvm_skip_host_instr(void) | |
| 67 | +{ | |
| 68 | + write_sysreg_el2(read_sysreg_el2(SYS_ELR) + 4, SYS_ELR); | |
| 69 | +} | |
| 70 | + | |
| 62 | 71 | #endif |
| @@ -47,6 +47,8 @@ __invalid: · 46 unmodified lines | ||
| 47 | 47 | b . |
| 48 | 48 | |
| 49 | 49 | /* |
| 50 | + * Only uses x0..x3 so as to not clobber callee-saved SMCCC registers. | |
| 51 | + * | |
| 50 | 52 | * x0: SMCCC function ID |
| 51 | 53 | * x1: struct kvm_nvhe_init_params PA |
| 52 | 54 | */ |
| @@ -70,9 +72,9 @@ __do_hyp_init: · 17 unmodified lines | ||
| 70 | 72 | eret |
| 71 | 73 | |
| 72 | 74 | 1: mov x0, x1 |
| 73 | − mov x4, lr | |
| 74 | − bl ___kvm_hyp_init | |
| 75 | − mov lr, x4 | |
| 75 | + mov x3, lr | |
| 76 | + bl ___kvm_hyp_init // Clobbers x0..x2 | |
| 77 | + mov lr, x3 | |
| 76 | 78 | |
| 77 | 79 | /* Hello, World! */ |
| 78 | 80 | mov x0, #SMCCC_RET_SUCCESS |
| @@ -82,8 +84,8 @@ SYM_CODE_END(__kvm_hyp_init) · 3 unmodified lines | ||
| 82 | 84 | /* |
| 83 | 85 | * Initialize the hypervisor in EL2. |
| 84 | 86 | * |
| 85 | − * Only uses x0..x3 so as to not clobber callee-saved SMCCC registers | |
| 86 | − * and leave x4 for the caller. | |
| 87 | + * Only uses x0..x2 so as to not clobber callee-saved SMCCC registers | |
| 88 | + * and leave x3 for the caller. | |
| 87 | 89 | * |
| 88 | 90 | * x0: struct kvm_nvhe_init_params PA |
| 89 | 91 | */ |
| @@ -112,9 +114,9 @@ alternative_else_nop_endif · 22 unmodified lines | ||
| 112 | 114 | /* |
| 113 | 115 | * Set the PS bits in TCR_EL2. |
| 114 | 116 | */ |
| 115 | − ldr x1, [x0, #NVHE_INIT_TCR_EL2] | |
| 116 | − tcr_compute_pa_size x1, #TCR_EL2_PS_SHIFT, x2, x3 | |
| 117 | − msr tcr_el2, x1 | |
| 117 | + ldr x0, [x0, #NVHE_INIT_TCR_EL2] | |
| 118 | + tcr_compute_pa_size x0, #TCR_EL2_PS_SHIFT, x1, x2 | |
| 119 | + msr tcr_el2, x0 | |
| 118 | 120 | |
| 119 | 121 | isb |
| 120 | 122 | |
| @@ -193,7 +195,7 @@ SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu) · 72 unmodified lines | ||
| 193 | 195 | |
| 194 | 196 | /* Enable MMU, set vectors and stack. */ |
| 195 | 197 | mov x0, x28 |
| 196 | − bl ___kvm_hyp_init // Clobbers x0..x3 | |
| 198 | + bl ___kvm_hyp_init // Clobbers x0..x2 | |
| 197 | 199 | |
| 198 | 200 | /* Leave idmap. */ |
| 199 | 201 | mov x0, x29 |
| @@ -157,11 +157,6 @@ static void default_host_smc_handler(struct kvm_cpu_context *host_ctxt) · 156 unmodified lines | ||
| 157 | 157 | __kvm_hyp_host_forward_smc(host_ctxt); |
| 158 | 158 | } |
| 159 | 159 | |
| 160 | −static void skip_host_instruction(void) | |
| 161 | −{ | |
| 162 | − write_sysreg_el2(read_sysreg_el2(SYS_ELR) + 4, SYS_ELR); | |
| 163 | −} | |
| 164 | − | |
| 165 | 160 | static void handle_host_smc(struct kvm_cpu_context *host_ctxt) |
| 166 | 161 | { |
| 167 | 162 | bool handled; |
| @@ -170,11 +165,8 @@ static void handle_host_smc(struct kvm_cpu_context *host_ctxt) · 2 unmodified lines | ||
| 170 | 165 | if (!handled) |
| 171 | 166 | default_host_smc_handler(host_ctxt); |
| 172 | 167 | |
| 173 | − /* | |
| 174 | − * Unlike HVC, the return address of an SMC is the instruction's PC. | |
| 175 | − * Move the return address past the instruction. | |
| 176 | − */ | |
| 177 | − skip_host_instruction(); | |
| 168 | + /* SMC was trapped, move ELR past the current PC. */ | |
| 169 | + kvm_skip_host_instr(); | |
| 178 | 170 | } |
| 179 | 171 | |
| 180 | 172 | void handle_trap(struct kvm_cpu_context *host_ctxt) |
| @@ -14,14 +14,14 @@ · 13 unmodified lines | ||
| 14 | 14 | * Other CPUs should not be allowed to boot because their features were |
| 15 | 15 | * not checked against the finalized system capabilities. |
| 16 | 16 | */ |
| 17 | −u64 __ro_after_init __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID }; | |
| 17 | +u64 __ro_after_init hyp_cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID }; | |
| 18 | 18 | |
| 19 | 19 | u64 cpu_logical_map(unsigned int cpu) |
| 20 | 20 | { |
| 21 | − if (cpu >= ARRAY_SIZE(__cpu_logical_map)) | |
| 21 | + if (cpu >= ARRAY_SIZE(hyp_cpu_logical_map)) | |
| 22 | 22 | hyp_panic(); |
| 23 | 23 | |
| 24 | − return __cpu_logical_map[cpu]; | |
| 24 | + return hyp_cpu_logical_map[cpu]; | |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | 27 | unsigned long __hyp_per_cpu_offset(unsigned int cpu) |
| @@ -7,11 +7,8 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <asm/kvm_asm.h> |
| 8 | 8 | #include <asm/kvm_hyp.h> |
| 9 | 9 | #include <asm/kvm_mmu.h> |
| 10 | −#include <kvm/arm_hypercalls.h> | |
| 11 | 10 | #include <linux/arm-smccc.h> |
| 12 | 11 | #include <linux/kvm_host.h> |
| 13 | −#include <linux/psci.h> | |
| 14 | −#include <kvm/arm_psci.h> | |
| 15 | 12 | #include <uapi/linux/psci.h> |
| 16 | 13 | |
| 17 | 14 | #include <nvhe/trap_handler.h> |
| @@ -22,9 +19,8 @@ void kvm_hyp_cpu_resume(unsigned long r0); · 4 unmodified lines | ||
| 22 | 19 | void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt); |
| 23 | 20 | |
| 24 | 21 | /* Config options set by the host. */ |
| 25 | −__ro_after_init u32 kvm_host_psci_version; | |
| 26 | −__ro_after_init struct psci_0_1_function_ids kvm_host_psci_0_1_function_ids; | |
| 27 | −__ro_after_init s64 hyp_physvirt_offset; | |
| 22 | +struct kvm_host_psci_config __ro_after_init kvm_host_psci_config; | |
| 23 | +s64 __ro_after_init hyp_physvirt_offset; | |
| 28 | 24 | |
| 29 | 25 | #define __hyp_pa(x) ((phys_addr_t)((x)) + hyp_physvirt_offset) |
| 30 | 26 | |
| @@ -47,19 +43,16 @@ struct psci_boot_args { · 16 unmodified lines | ||
| 47 | 43 | static DEFINE_PER_CPU(struct psci_boot_args, cpu_on_args) = PSCI_BOOT_ARGS_INIT; |
| 48 | 44 | static DEFINE_PER_CPU(struct psci_boot_args, suspend_args) = PSCI_BOOT_ARGS_INIT; |
| 49 | 45 | |
| 50 | −static u64 get_psci_func_id(struct kvm_cpu_context *host_ctxt) | |
| 51 | −{ | |
| 52 | − DECLARE_REG(u64, func_id, host_ctxt, 0); | |
| 53 | − | |
| 54 | − return func_id; | |
| 55 | −} | |
| 46 | +#define is_psci_0_1(what, func_id) \ | |
| 47 | + (kvm_host_psci_config.psci_0_1_ ## what ## _implemented && \ | |
| 48 | + (func_id) == kvm_host_psci_config.function_ids_0_1.what) | |
| 56 | 49 | |
| 57 | 50 | static bool is_psci_0_1_call(u64 func_id) |
| 58 | 51 | { |
| 59 | − return (func_id == kvm_host_psci_0_1_function_ids.cpu_suspend) || | |
| 60 | − (func_id == kvm_host_psci_0_1_function_ids.cpu_on) || | |
| 61 | − (func_id == kvm_host_psci_0_1_function_ids.cpu_off) || | |
| 62 | − (func_id == kvm_host_psci_0_1_function_ids.migrate); | |
| 52 | + return (is_psci_0_1(cpu_suspend, func_id) || | |
| 53 | + is_psci_0_1(cpu_on, func_id) || | |
| 54 | + is_psci_0_1(cpu_off, func_id) || | |
| 55 | + is_psci_0_1(migrate, func_id)); | |
| 63 | 56 | } |
| 64 | 57 | |
| 65 | 58 | static bool is_psci_0_2_call(u64 func_id) |
| @@ -69,16 +62,6 @@ static bool is_psci_0_2_call(u64 func_id) · 3 unmodified lines | ||
| 69 | 62 | (PSCI_0_2_FN64(0) <= func_id && func_id <= PSCI_0_2_FN64(31)); |
| 70 | 63 | } |
| 71 | 64 | |
| 72 | −static bool is_psci_call(u64 func_id) | |
| 73 | −{ | |
| 74 | − switch (kvm_host_psci_version) { | |
| 75 | − case PSCI_VERSION(0, 1): | |
| 76 | − return is_psci_0_1_call(func_id); | |
| 77 | − default: | |
| 78 | − return is_psci_0_2_call(func_id); | |
| 79 | − } | |
| 80 | −} | |
| 81 | − | |
| 82 | 65 | static unsigned long psci_call(unsigned long fn, unsigned long arg0, |
| 83 | 66 | unsigned long arg1, unsigned long arg2) |
| 84 | 67 | { |
| @@ -94,12 +77,6 @@ static unsigned long psci_forward(struct kvm_cpu_context *host_ctxt) · 9 unmodified lines | ||
| 94 | 77 | cpu_reg(host_ctxt, 2), cpu_reg(host_ctxt, 3)); |
| 95 | 78 | } |
| 96 | 79 | |
| 97 | −static __noreturn unsigned long psci_forward_noreturn(struct kvm_cpu_context *host_ctxt) | |
| 98 | −{ | |
| 99 | − psci_forward(host_ctxt); | |
| 100 | − hyp_panic(); /* unreachable */ | |
| 101 | −} | |
| 102 | − | |
| 103 | 80 | static unsigned int find_cpu_id(u64 mpidr) |
| 104 | 81 | { |
| 105 | 82 | unsigned int i; |
| @@ -248,15 +225,14 @@ asmlinkage void __noreturn kvm_host_psci_cpu_entry(bool is_cpu_on) · 142 unmodified lines | ||
| 248 | 225 | |
| 249 | 226 | static unsigned long psci_0_1_handler(u64 func_id, struct kvm_cpu_context *host_ctxt) |
| 250 | 227 | { |
| 251 | − if ((func_id == kvm_host_psci_0_1_function_ids.cpu_off) || | |
| 252 | − (func_id == kvm_host_psci_0_1_function_ids.migrate)) | |
| 228 | + if (is_psci_0_1(cpu_off, func_id) || is_psci_0_1(migrate, func_id)) | |
| 253 | 229 | return psci_forward(host_ctxt); |
| 254 | − else if (func_id == kvm_host_psci_0_1_function_ids.cpu_on) | |
| 230 | + if (is_psci_0_1(cpu_on, func_id)) | |
| 255 | 231 | return psci_cpu_on(func_id, host_ctxt); |
| 256 | − else if (func_id == kvm_host_psci_0_1_function_ids.cpu_suspend) | |
| 232 | + if (is_psci_0_1(cpu_suspend, func_id)) | |
| 257 | 233 | return psci_cpu_suspend(func_id, host_ctxt); |
| 258 | − else | |
| 259 | − return PSCI_RET_NOT_SUPPORTED; | |
| 234 | + | |
| 235 | + return PSCI_RET_NOT_SUPPORTED; | |
| 260 | 236 | } |
| 261 | 237 | |
| 262 | 238 | static unsigned long psci_0_2_handler(u64 func_id, struct kvm_cpu_context *host_ctxt) |
| @@ -269,10 +245,13 @@ static unsigned long psci_0_2_handler(u64 func_id, struct kvm_cpu_context *host_ · 6 unmodified lines | ||
| 269 | 245 | case PSCI_0_2_FN_MIGRATE_INFO_TYPE: |
| 270 | 246 | case PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU: |
| 271 | 247 | return psci_forward(host_ctxt); |
| 248 | + /* | |
| 249 | + * SYSTEM_OFF/RESET should not return according to the spec. | |
| 250 | + * Allow it so as to stay robust to broken firmware. | |
| 251 | + */ | |
| 272 | 252 | case PSCI_0_2_FN_SYSTEM_OFF: |
| 273 | 253 | case PSCI_0_2_FN_SYSTEM_RESET: |
| 274 | − psci_forward_noreturn(host_ctxt); | |
| 275 | − unreachable(); | |
| 254 | + return psci_forward(host_ctxt); | |
| 276 | 255 | case PSCI_0_2_FN64_CPU_SUSPEND: |
| 277 | 256 | return psci_cpu_suspend(func_id, host_ctxt); |
| 278 | 257 | case PSCI_0_2_FN64_CPU_ON: |
| @@ -298,20 +277,23 @@ static unsigned long psci_1_0_handler(u64 func_id, struct kvm_cpu_context *host_ · 19 unmodified lines | ||
| 298 | 277 | |
| 299 | 278 | bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt) |
| 300 | 279 | { |
| 301 | − u64 func_id = get_psci_func_id(host_ctxt); | |
| 280 | + DECLARE_REG(u64, func_id, host_ctxt, 0); | |
| 302 | 281 | unsigned long ret; |
| 303 | 282 | |
| 304 | − if (!is_psci_call(func_id)) | |
| 305 | − return false; | |
| 306 | − | |
| 307 | − switch (kvm_host_psci_version) { | |
| 283 | + switch (kvm_host_psci_config.version) { | |
| 308 | 284 | case PSCI_VERSION(0, 1): |
| 285 | + if (!is_psci_0_1_call(func_id)) | |
| 286 | + return false; | |
| 309 | 287 | ret = psci_0_1_handler(func_id, host_ctxt); |
| 310 | 288 | break; |
| 311 | 289 | case PSCI_VERSION(0, 2): |
| 290 | + if (!is_psci_0_2_call(func_id)) | |
| 291 | + return false; | |
| 312 | 292 | ret = psci_0_2_handler(func_id, host_ctxt); |
| 313 | 293 | break; |
| 314 | 294 | default: |
| 295 | + if (!is_psci_0_2_call(func_id)) | |
| 296 | + return false; | |
| 315 | 297 | ret = psci_1_0_handler(func_id, host_ctxt); |
| 316 | 298 | break; |
| 317 | 299 | } |
| @@ -788,7 +788,7 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1) · 787 unmodified lines | ||
| 788 | 788 | { |
| 789 | 789 | unsigned long *bmap = vcpu->kvm->arch.pmu_filter; |
| 790 | 790 | u64 val, mask = 0; |
| 791 | − int base, i; | |
| 791 | + int base, i, nr_events; | |
| 792 | 792 | |
| 793 | 793 | if (!pmceid1) { |
| 794 | 794 | val = read_sysreg(pmceid0_el0); |
| @@ -801,13 +801,17 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1) · 6 unmodified lines | ||
| 801 | 801 | if (!bmap) |
| 802 | 802 | return val; |
| 803 | 803 | |
| 804 | + nr_events = kvm_pmu_event_mask(vcpu->kvm) + 1; | |
| 805 | + | |
| 804 | 806 | for (i = 0; i < 32; i += 8) { |
| 805 | 807 | u64 byte; |
| 806 | 808 | |
| 807 | 809 | byte = bitmap_get_value8(bmap, base + i); |
| 808 | 810 | mask |= byte << i; |
| 809 | − byte = bitmap_get_value8(bmap, 0x4000 + base + i); | |
| 810 | − mask |= byte << (32 + i); | |
| 811 | + if (nr_events >= (0x4000 + base + 32)) { | |
| 812 | + byte = bitmap_get_value8(bmap, 0x4000 + base + i); | |
| 813 | + mask |= byte << (32 + i); | |
| 814 | + } | |
| 811 | 815 | } |
| 812 | 816 | |
| 813 | 817 | return val & mask; |
| @@ -850,8 +854,6 @@ int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu) · 36 unmodified lines | ||
| 850 | 854 | return -EINVAL; |
| 851 | 855 | } |
| 852 | 856 | |
| 853 | − kvm_pmu_vcpu_reset(vcpu); | |
| 854 | − | |
| 855 | 857 | return 0; |
| 856 | 858 | } |
| 857 | 859 | |
| @@ -43,6 +43,10 @@ · 42 unmodified lines | ||
| 43 | 43 | * 64bit interface. |
| 44 | 44 | */ |
| 45 | 45 | |
| 46 | +#define reg_to_encoding(x) \ | |
| 47 | + sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \ | |
| 48 | + (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2) | |
| 49 | + | |
| 46 | 50 | static bool read_from_write_only(struct kvm_vcpu *vcpu, |
| 47 | 51 | struct sys_reg_params *params, |
| 48 | 52 | const struct sys_reg_desc *r) |
| @@ -273,8 +277,7 @@ static bool trap_loregion(struct kvm_vcpu *vcpu, · 224 unmodified lines | ||
| 273 | 277 | const struct sys_reg_desc *r) |
| 274 | 278 | { |
| 275 | 279 | u64 val = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1); |
| 276 | − u32 sr = sys_reg((u32)r->Op0, (u32)r->Op1, | |
| 277 | − (u32)r->CRn, (u32)r->CRm, (u32)r->Op2); | |
| 280 | + u32 sr = reg_to_encoding(r); | |
| 278 | 281 | |
| 279 | 282 | if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) { |
| 280 | 283 | kvm_inject_undefined(vcpu); |
| @@ -590,10 +593,23 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) · 309 unmodified lines | ||
| 590 | 593 | vcpu_write_sys_reg(vcpu, (1ULL << 31) | mpidr, MPIDR_EL1); |
| 591 | 594 | } |
| 592 | 595 | |
| 596 | +static unsigned int pmu_visibility(const struct kvm_vcpu *vcpu, | |
| 597 | + const struct sys_reg_desc *r) | |
| 598 | +{ | |
| 599 | + if (kvm_vcpu_has_pmu(vcpu)) | |
| 600 | + return 0; | |
| 601 | + | |
| 602 | + return REG_HIDDEN; | |
| 603 | +} | |
| 604 | + | |
| 593 | 605 | static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) |
| 594 | 606 | { |
| 595 | 607 | u64 pmcr, val; |
| 596 | 608 | |
| 609 | + /* No PMU available, PMCR_EL0 may UNDEF... */ | |
| 610 | + if (!kvm_arm_support_pmu_v3()) | |
| 611 | + return; | |
| 612 | + | |
| 597 | 613 | pmcr = read_sysreg(pmcr_el0); |
| 598 | 614 | /* |
| 599 | 615 | * Writable bits of PMCR_EL0 (ARMV8_PMU_PMCR_MASK) are reset to UNKNOWN |
| @@ -609,9 +625,8 @@ static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) · 9 unmodified lines | ||
| 609 | 625 | static bool check_pmu_access_disabled(struct kvm_vcpu *vcpu, u64 flags) |
| 610 | 626 | { |
| 611 | 627 | u64 reg = __vcpu_sys_reg(vcpu, PMUSERENR_EL0); |
| 612 | − bool enabled = kvm_vcpu_has_pmu(vcpu); | |
| 628 | + bool enabled = (reg & flags) || vcpu_mode_priv(vcpu); | |
| 613 | 629 | |
| 614 | − enabled &= (reg & flags) || vcpu_mode_priv(vcpu); | |
| 615 | 630 | if (!enabled) |
| 616 | 631 | kvm_inject_undefined(vcpu); |
| 617 | 632 | |
| @@ -896,11 +911,6 @@ static bool access_pmswinc(struct kvm_vcpu *vcpu, struct sys_reg_params *p, · 278 unmodified lines | ||
| 896 | 911 | static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, |
| 897 | 912 | const struct sys_reg_desc *r) |
| 898 | 913 | { |
| 899 | − if (!kvm_vcpu_has_pmu(vcpu)) { | |
| 900 | − kvm_inject_undefined(vcpu); | |
| 901 | − return false; | |
| 902 | − } | |
| 903 | − | |
| 904 | 914 | if (p->is_write) { |
| 905 | 915 | if (!vcpu_mode_priv(vcpu)) { |
| 906 | 916 | kvm_inject_undefined(vcpu); |
| @@ -917,10 +927,6 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, · 10 unmodified lines | ||
| 917 | 927 | return true; |
| 918 | 928 | } |
| 919 | 929 | |
| 920 | −#define reg_to_encoding(x) \ | |
| 921 | − sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \ | |
| 922 | − (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2); | |
| 923 | − | |
| 924 | 930 | /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */ |
| 925 | 931 | #define DBG_BCR_BVR_WCR_WVR_EL1(n) \ |
| 926 | 932 | { SYS_DESC(SYS_DBGBVRn_EL1(n)), \ |
| @@ -932,15 +938,18 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, · 5 unmodified lines | ||
| 932 | 938 | { SYS_DESC(SYS_DBGWCRn_EL1(n)), \ |
| 933 | 939 | trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr } |
| 934 | 940 | |
| 941 | +#define PMU_SYS_REG(r) \ | |
| 942 | + SYS_DESC(r), .reset = reset_unknown, .visibility = pmu_visibility | |
| 943 | + | |
| 935 | 944 | /* Macro to expand the PMEVCNTRn_EL0 register */ |
| 936 | 945 | #define PMU_PMEVCNTR_EL0(n) \ |
| 937 | − { SYS_DESC(SYS_PMEVCNTRn_EL0(n)), \ | |
| 938 | − access_pmu_evcntr, reset_unknown, (PMEVCNTR0_EL0 + n), } | |
| 946 | + { PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)), \ | |
| 947 | + .access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), } | |
| 939 | 948 | |
| 940 | 949 | /* Macro to expand the PMEVTYPERn_EL0 register */ |
| 941 | 950 | #define PMU_PMEVTYPER_EL0(n) \ |
| 942 | − { SYS_DESC(SYS_PMEVTYPERn_EL0(n)), \ | |
| 943 | − access_pmu_evtyper, reset_unknown, (PMEVTYPER0_EL0 + n), } | |
| 951 | + { PMU_SYS_REG(SYS_PMEVTYPERn_EL0(n)), \ | |
| 952 | + .access = access_pmu_evtyper, .reg = (PMEVTYPER0_EL0 + n), } | |
| 944 | 953 | |
| 945 | 954 | static bool undef_access(struct kvm_vcpu *vcpu, struct sys_reg_params *p, |
| 946 | 955 | const struct sys_reg_desc *r) |
| @@ -1016,8 +1025,7 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu, · 69 unmodified lines | ||
| 1016 | 1025 | static u64 read_id_reg(const struct kvm_vcpu *vcpu, |
| 1017 | 1026 | struct sys_reg_desc const *r, bool raz) |
| 1018 | 1027 | { |
| 1019 | − u32 id = sys_reg((u32)r->Op0, (u32)r->Op1, | |
| 1020 | − (u32)r->CRn, (u32)r->CRm, (u32)r->Op2); | |
| 1028 | + u32 id = reg_to_encoding(r); | |
| 1021 | 1029 | u64 val = raz ? 0 : read_sanitised_ftr_reg(id); |
| 1022 | 1030 | |
| 1023 | 1031 | if (id == SYS_ID_AA64PFR0_EL1) { |
| @@ -1058,8 +1066,7 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, · 34 unmodified lines | ||
| 1058 | 1066 | static unsigned int id_visibility(const struct kvm_vcpu *vcpu, |
| 1059 | 1067 | const struct sys_reg_desc *r) |
| 1060 | 1068 | { |
| 1061 | − u32 id = sys_reg((u32)r->Op0, (u32)r->Op1, | |
| 1062 | − (u32)r->CRn, (u32)r->CRm, (u32)r->Op2); | |
| 1069 | + u32 id = reg_to_encoding(r); | |
| 1063 | 1070 | |
| 1064 | 1071 | switch (id) { |
| 1065 | 1072 | case SYS_ID_AA64ZFR0_EL1: |
| @@ -1482,8 +1489,10 @@ static const struct sys_reg_desc sys_reg_descs[] = { · 416 unmodified lines | ||
| 1482 | 1489 | { SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 }, |
| 1483 | 1490 | { SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 }, |
| 1484 | 1491 | |
| 1485 | − { SYS_DESC(SYS_PMINTENSET_EL1), access_pminten, reset_unknown, PMINTENSET_EL1 }, | |
| 1486 | − { SYS_DESC(SYS_PMINTENCLR_EL1), access_pminten, reset_unknown, PMINTENSET_EL1 }, | |
| 1492 | + { PMU_SYS_REG(SYS_PMINTENSET_EL1), | |
| 1493 | + .access = access_pminten, .reg = PMINTENSET_EL1 }, | |
| 1494 | + { PMU_SYS_REG(SYS_PMINTENCLR_EL1), | |
| 1495 | + .access = access_pminten, .reg = PMINTENSET_EL1 }, | |
| 1487 | 1496 | |
| 1488 | 1497 | { SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 }, |
| 1489 | 1498 | { SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 }, |
| @@ -1522,23 +1531,36 @@ static const struct sys_reg_desc sys_reg_descs[] = { · 32 unmodified lines | ||
| 1522 | 1531 | { SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 }, |
| 1523 | 1532 | { SYS_DESC(SYS_CTR_EL0), access_ctr }, |
| 1524 | 1533 | |
| 1525 | − { SYS_DESC(SYS_PMCR_EL0), access_pmcr, reset_pmcr, PMCR_EL0 }, | |
| 1526 | − { SYS_DESC(SYS_PMCNTENSET_EL0), access_pmcnten, reset_unknown, PMCNTENSET_EL0 }, | |
| 1527 | − { SYS_DESC(SYS_PMCNTENCLR_EL0), access_pmcnten, reset_unknown, PMCNTENSET_EL0 }, | |
| 1528 | − { SYS_DESC(SYS_PMOVSCLR_EL0), access_pmovs, reset_unknown, PMOVSSET_EL0 }, | |
| 1529 | − { SYS_DESC(SYS_PMSWINC_EL0), access_pmswinc, reset_unknown, PMSWINC_EL0 }, | |
| 1530 | − { SYS_DESC(SYS_PMSELR_EL0), access_pmselr, reset_unknown, PMSELR_EL0 }, | |
| 1531 | − { SYS_DESC(SYS_PMCEID0_EL0), access_pmceid }, | |
| 1532 | − { SYS_DESC(SYS_PMCEID1_EL0), access_pmceid }, | |
| 1533 | − { SYS_DESC(SYS_PMCCNTR_EL0), access_pmu_evcntr, reset_unknown, PMCCNTR_EL0 }, | |
| 1534 | − { SYS_DESC(SYS_PMXEVTYPER_EL0), access_pmu_evtyper }, | |
| 1535 | − { SYS_DESC(SYS_PMXEVCNTR_EL0), access_pmu_evcntr }, | |
| 1534 | + { PMU_SYS_REG(SYS_PMCR_EL0), .access = access_pmcr, | |
| 1535 | + .reset = reset_pmcr, .reg = PMCR_EL0 }, | |
| 1536 | + { PMU_SYS_REG(SYS_PMCNTENSET_EL0), | |
| 1537 | + .access = access_pmcnten, .reg = PMCNTENSET_EL0 }, | |
| 1538 | + { PMU_SYS_REG(SYS_PMCNTENCLR_EL0), | |
| 1539 | + .access = access_pmcnten, .reg = PMCNTENSET_EL0 }, | |
| 1540 | + { PMU_SYS_REG(SYS_PMOVSCLR_EL0), | |
| 1541 | + .access = access_pmovs, .reg = PMOVSSET_EL0 }, | |
| 1542 | + { PMU_SYS_REG(SYS_PMSWINC_EL0), | |
| 1543 | + .access = access_pmswinc, .reg = PMSWINC_EL0 }, | |
| 1544 | + { PMU_SYS_REG(SYS_PMSELR_EL0), | |
| 1545 | + .access = access_pmselr, .reg = PMSELR_EL0 }, | |
| 1546 | + { PMU_SYS_REG(SYS_PMCEID0_EL0), | |
| 1547 | + .access = access_pmceid, .reset = NULL }, | |
| 1548 | + { PMU_SYS_REG(SYS_PMCEID1_EL0), | |
| 1549 | + .access = access_pmceid, .reset = NULL }, | |
| 1550 | + { PMU_SYS_REG(SYS_PMCCNTR_EL0), | |
| 1551 | + .access = access_pmu_evcntr, .reg = PMCCNTR_EL0 }, | |
| 1552 | + { PMU_SYS_REG(SYS_PMXEVTYPER_EL0), | |
| 1553 | + .access = access_pmu_evtyper, .reset = NULL }, | |
| 1554 | + { PMU_SYS_REG(SYS_PMXEVCNTR_EL0), | |
| 1555 | + .access = access_pmu_evcntr, .reset = NULL }, | |
| 1536 | 1556 | /* |
| 1537 | 1557 | * PMUSERENR_EL0 resets as unknown in 64bit mode while it resets as zero |
| 1538 | 1558 | * in 32bit mode. Here we choose to reset it as zero for consistency. |
| 1539 | 1559 | */ |
| 1540 | − { SYS_DESC(SYS_PMUSERENR_EL0), access_pmuserenr, reset_val, PMUSERENR_EL0, 0 }, | |
| 1541 | − { SYS_DESC(SYS_PMOVSSET_EL0), access_pmovs, reset_unknown, PMOVSSET_EL0 }, | |
| 1560 | + { PMU_SYS_REG(SYS_PMUSERENR_EL0), .access = access_pmuserenr, | |
| 1561 | + .reset = reset_val, .reg = PMUSERENR_EL0, .val = 0 }, | |
| 1562 | + { PMU_SYS_REG(SYS_PMOVSSET_EL0), | |
| 1563 | + .access = access_pmovs, .reg = PMOVSSET_EL0 }, | |
| 1542 | 1564 | |
| 1543 | 1565 | { SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 }, |
| 1544 | 1566 | { SYS_DESC(SYS_TPIDRRO_EL0), NULL, reset_unknown, TPIDRRO_EL0 }, |
| @@ -1690,7 +1712,8 @@ static const struct sys_reg_desc sys_reg_descs[] = { · 145 unmodified lines | ||
| 1690 | 1712 | * PMCCFILTR_EL0 resets as unknown in 64bit mode while it resets as zero |
| 1691 | 1713 | * in 32bit mode. Here we choose to reset it as zero for consistency. |
| 1692 | 1714 | */ |
| 1693 | − { SYS_DESC(SYS_PMCCFILTR_EL0), access_pmu_evtyper, reset_val, PMCCFILTR_EL0, 0 }, | |
| 1715 | + { PMU_SYS_REG(SYS_PMCCFILTR_EL0), .access = access_pmu_evtyper, | |
| 1716 | + .reset = reset_val, .reg = PMCCFILTR_EL0, .val = 0 }, | |
| 1694 | 1717 | |
| 1695 | 1718 | { SYS_DESC(SYS_DACR32_EL2), NULL, reset_unknown, DACR32_EL2 }, |
| 1696 | 1719 | { SYS_DESC(SYS_IFSR32_EL2), NULL, reset_unknown, IFSR32_EL2 }, |
| @@ -34,17 +34,16 @@ static u64 __early_kern_hyp_va(u64 addr) · 33 unmodified lines | ||
| 34 | 34 | } |
| 35 | 35 | |
| 36 | 36 | /* |
| 37 | − * Store a hyp VA <-> PA offset into a hyp-owned variable. | |
| 37 | + * Store a hyp VA <-> PA offset into a EL2-owned variable. | |
| 38 | 38 | */ |
| 39 | 39 | static void init_hyp_physvirt_offset(void) |
| 40 | 40 | { |
| 41 | − extern s64 kvm_nvhe_sym(hyp_physvirt_offset); | |
| 42 | 41 | u64 kern_va, hyp_va; |
| 43 | 42 | |
| 44 | 43 | /* Compute the offset from the hyp VA and PA of a random symbol. */ |
| 45 | − kern_va = (u64)kvm_ksym_ref(__hyp_text_start); | |
| 44 | + kern_va = (u64)lm_alias(__hyp_text_start); | |
| 46 | 45 | hyp_va = __early_kern_hyp_va(kern_va); |
| 47 | − CHOOSE_NVHE_SYM(hyp_physvirt_offset) = (s64)__pa(kern_va) - (s64)hyp_va; | |
| 46 | + hyp_physvirt_offset = (s64)__pa(kern_va) - (s64)hyp_va; | |
| 48 | 47 | } |
| 49 | 48 | |
| 50 | 49 | /* |
| @@ -419,7 +419,8 @@ int vgic_lazy_init(struct kvm *kvm) · 418 unmodified lines | ||
| 419 | 419 | * Map the MMIO regions depending on the VGIC model exposed to the guest |
| 420 | 420 | * called on the first VCPU run. |
| 421 | 421 | * Also map the virtual CPU interface into the VM. |
| 422 | − * v2/v3 derivatives call vgic_init if not already done. | |
| 422 | + * v2 calls vgic_init() if not already done. | |
| 423 | + * v3 and derivatives return an error if the VGIC is not initialized. | |
| 423 | 424 | * vgic_ready() returns true if this function has succeeded. |
| 424 | 425 | * @kvm: kvm struct pointer |
| 425 | 426 | */ |
| @@ -428,7 +429,13 @@ int kvm_vgic_map_resources(struct kvm *kvm) · 2 unmodified lines | ||
| 428 | 429 | struct vgic_dist *dist = &kvm->arch.vgic; |
| 429 | 430 | int ret = 0; |
| 430 | 431 | |
| 432 | + if (likely(vgic_ready(kvm))) | |
| 433 | + return 0; | |
| 434 | + | |
| 431 | 435 | mutex_lock(&kvm->lock); |
| 436 | + if (vgic_ready(kvm)) | |
| 437 | + goto out; | |
| 438 | + | |
| 432 | 439 | if (!irqchip_in_kernel(kvm)) |
| 433 | 440 | goto out; |
| 434 | 441 | |
| @@ -439,6 +446,8 @@ int kvm_vgic_map_resources(struct kvm *kvm) · 4 unmodified lines | ||
| 439 | 446 | |
| 440 | 447 | if (ret) |
| 441 | 448 | __kvm_vgic_destroy(kvm); |
| 449 | + else | |
| 450 | + dist->ready = true; | |
| 442 | 451 | |
| 443 | 452 | out: |
| 444 | 453 | mutex_unlock(&kvm->lock); |
| @@ -306,20 +306,15 @@ int vgic_v2_map_resources(struct kvm *kvm) · 305 unmodified lines | ||
| 306 | 306 | struct vgic_dist *dist = &kvm->arch.vgic; |
| 307 | 307 | int ret = 0; |
| 308 | 308 | |
| 309 | − if (vgic_ready(kvm)) | |
| 310 | − goto out; | |
| 311 | − | |
| 312 | 309 | if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base) || |
| 313 | 310 | IS_VGIC_ADDR_UNDEF(dist->vgic_cpu_base)) { |
| 314 | 311 | kvm_err("Need to set vgic cpu and dist addresses first\n"); |
| 315 | − ret = -ENXIO; | |
| 316 | − goto out; | |
| 312 | + return -ENXIO; | |
| 317 | 313 | } |
| 318 | 314 | |
| 319 | 315 | if (!vgic_v2_check_base(dist->vgic_dist_base, dist->vgic_cpu_base)) { |
| 320 | 316 | kvm_err("VGIC CPU and dist frames overlap\n"); |
| 321 | − ret = -EINVAL; | |
| 322 | − goto out; | |
| 317 | + return -EINVAL; | |
| 323 | 318 | } |
| 324 | 319 | |
| 325 | 320 | /* |
| @@ -329,13 +324,13 @@ int vgic_v2_map_resources(struct kvm *kvm) · 3 unmodified lines | ||
| 329 | 324 | ret = vgic_init(kvm); |
| 330 | 325 | if (ret) { |
| 331 | 326 | kvm_err("Unable to initialize VGIC dynamic data structures\n"); |
| 332 | − goto out; | |
| 327 | + return ret; | |
| 333 | 328 | } |
| 334 | 329 | |
| 335 | 330 | ret = vgic_register_dist_iodev(kvm, dist->vgic_dist_base, VGIC_V2); |
| 336 | 331 | if (ret) { |
| 337 | 332 | kvm_err("Unable to register VGIC MMIO regions\n"); |
| 338 | − goto out; | |
| 333 | + return ret; | |
| 339 | 334 | } |
| 340 | 335 | |
| 341 | 336 | if (!static_branch_unlikely(&vgic_v2_cpuif_trap)) { |
| @@ -344,14 +339,11 @@ int vgic_v2_map_resources(struct kvm *kvm) · 2 unmodified lines | ||
| 344 | 339 | KVM_VGIC_V2_CPU_SIZE, true); |
| 345 | 340 | if (ret) { |
| 346 | 341 | kvm_err("Unable to remap VGIC CPU to VCPU\n"); |
| 347 | − goto out; | |
| 342 | + return ret; | |
| 348 | 343 | } |
| 349 | 344 | } |
| 350 | 345 | |
| 351 | − dist->ready = true; | |
| 352 | − | |
| 353 | −out: | |
| 354 | − return ret; | |
| 346 | + return 0; | |
| 355 | 347 | } |
| 356 | 348 | |
| 357 | 349 | DEFINE_STATIC_KEY_FALSE(vgic_v2_cpuif_trap); |
| @@ -500,29 +500,23 @@ int vgic_v3_map_resources(struct kvm *kvm) · 499 unmodified lines | ||
| 500 | 500 | int ret = 0; |
| 501 | 501 | int c; |
| 502 | 502 | |
| 503 | − if (vgic_ready(kvm)) | |
| 504 | − goto out; | |
| 505 | − | |
| 506 | 503 | kvm_for_each_vcpu(c, vcpu, kvm) { |
| 507 | 504 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; |
| 508 | 505 | |
| 509 | 506 | if (IS_VGIC_ADDR_UNDEF(vgic_cpu->rd_iodev.base_addr)) { |
| 510 | 507 | kvm_debug("vcpu %d redistributor base not set\n", c); |
| 511 | − ret = -ENXIO; | |
| 512 | − goto out; | |
| 508 | + return -ENXIO; | |
| 513 | 509 | } |
| 514 | 510 | } |
| 515 | 511 | |
| 516 | 512 | if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base)) { |
| 517 | 513 | kvm_err("Need to set vgic distributor addresses first\n"); |
| 518 | − ret = -ENXIO; | |
| 519 | − goto out; | |
| 514 | + return -ENXIO; | |
| 520 | 515 | } |
| 521 | 516 | |
| 522 | 517 | if (!vgic_v3_check_base(kvm)) { |
| 523 | 518 | kvm_err("VGIC redist and dist frames overlap\n"); |
| 524 | − ret = -EINVAL; | |
| 525 | − goto out; | |
| 519 | + return -EINVAL; | |
| 526 | 520 | } |
| 527 | 521 | |
| 528 | 522 | /* |
| @@ -530,22 +524,19 @@ int vgic_v3_map_resources(struct kvm *kvm) · 1 unmodified line | ||
| 530 | 524 | * the VGIC before we need to use it. |
| 531 | 525 | */ |
| 532 | 526 | if (!vgic_initialized(kvm)) { |
| 533 | − ret = -EBUSY; | |
| 534 | − goto out; | |
| 527 | + return -EBUSY; | |
| 535 | 528 | } |
| 536 | 529 | |
| 537 | 530 | ret = vgic_register_dist_iodev(kvm, dist->vgic_dist_base, VGIC_V3); |
| 538 | 531 | if (ret) { |
| 539 | 532 | kvm_err("Unable to register VGICv3 dist MMIO regions\n"); |
| 540 | − goto out; | |
| 533 | + return ret; | |
| 541 | 534 | } |
| 542 | 535 | |
| 543 | 536 | if (kvm_vgic_global_state.has_gicv4_1) |
| 544 | 537 | vgic_v4_configure_vsgis(kvm); |
| 545 | − dist->ready = true; | |
| 546 | 538 | |
| 547 | −out: | |
| 548 | − return ret; | |
| 539 | + return 0; | |
| 549 | 540 | } |
| 550 | 541 | |
| 551 | 542 | DEFINE_STATIC_KEY_FALSE(vgic_v3_cpuif_trap); |
| @@ -709,10 +709,11 @@ static int do_tag_check_fault(unsigned long far, unsigned int esr, · 708 unmodified lines | ||
| 709 | 709 | struct pt_regs *regs) |
| 710 | 710 | { |
| 711 | 711 | /* |
| 712 | − * The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN for tag | |
| 713 | − * check faults. Mask them out now so that userspace doesn't see them. | |
| 712 | + * The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN | |
| 713 | + * for tag check faults. Set them to corresponding bits in the untagged | |
| 714 | + * address. | |
| 714 | 715 | */ |
| 715 | − far &= (1UL << 60) - 1; | |
| 716 | + far = (__untagged_addr(far) & ~MTE_TAG_MASK) | (far & MTE_TAG_MASK); | |
| 716 | 717 | do_bad_area(far, esr, regs); |
| 717 | 718 | return 0; |
| 718 | 719 | } |
| @@ -53,13 +53,13 @@ s64 memstart_addr __ro_after_init = -1; · 52 unmodified lines | ||
| 53 | 53 | EXPORT_SYMBOL(memstart_addr); |
| 54 | 54 | |
| 55 | 55 | /* |
| 56 | − * We create both ZONE_DMA and ZONE_DMA32. ZONE_DMA covers the first 1G of | |
| 57 | − * memory as some devices, namely the Raspberry Pi 4, have peripherals with | |
| 58 | − * this limited view of the memory. ZONE_DMA32 will cover the rest of the 32 | |
| 59 | − * bit addressable memory area. | |
| 56 | + * If the corresponding config options are enabled, we create both ZONE_DMA | |
| 57 | + * and ZONE_DMA32. By default ZONE_DMA covers the 32-bit addressable memory | |
| 58 | + * unless restricted on specific platforms (e.g. 30-bit on Raspberry Pi 4). | |
| 59 | + * In such case, ZONE_DMA32 covers the rest of the 32-bit addressable memory, | |
| 60 | + * otherwise it is empty. | |
| 60 | 61 | */ |
| 61 | 62 | phys_addr_t arm64_dma_phys_limit __ro_after_init; |
| 62 | −static phys_addr_t arm64_dma32_phys_limit __ro_after_init; | |
| 63 | 63 | |
| 64 | 64 | #ifdef CONFIG_KEXEC_CORE |
| 65 | 65 | /* |
| @@ -84,7 +84,7 @@ static void __init reserve_crashkernel(void) · 18 unmodified lines | ||
| 84 | 84 | |
| 85 | 85 | if (crash_base == 0) { |
| 86 | 86 | /* Current arm64 boot protocol requires 2MB alignment */ |
| 87 | − crash_base = memblock_find_in_range(0, arm64_dma32_phys_limit, | |
| 87 | + crash_base = memblock_find_in_range(0, arm64_dma_phys_limit, | |
| 88 | 88 | crash_size, SZ_2M); |
| 89 | 89 | if (crash_base == 0) { |
| 90 | 90 | pr_warn("cannot allocate crashkernel (size:0x%llx)\n", |
| @@ -196,6 +196,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) · 105 unmodified lines | ||
| 196 | 196 | unsigned long max_zone_pfns[MAX_NR_ZONES] = {0}; |
| 197 | 197 | unsigned int __maybe_unused acpi_zone_dma_bits; |
| 198 | 198 | unsigned int __maybe_unused dt_zone_dma_bits; |
| 199 | + phys_addr_t __maybe_unused dma32_phys_limit = max_zone_phys(32); | |
| 199 | 200 | |
| 200 | 201 | #ifdef CONFIG_ZONE_DMA |
| 201 | 202 | acpi_zone_dma_bits = fls64(acpi_iort_dma_get_max_cpu_address()); |
| @@ -205,8 +206,12 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) · 3 unmodified lines | ||
| 205 | 206 | max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit); |
| 206 | 207 | #endif |
| 207 | 208 | #ifdef CONFIG_ZONE_DMA32 |
| 208 | − max_zone_pfns[ZONE_DMA32] = PFN_DOWN(arm64_dma32_phys_limit); | |
| 209 | + max_zone_pfns[ZONE_DMA32] = PFN_DOWN(dma32_phys_limit); | |
| 210 | + if (!arm64_dma_phys_limit) | |
| 211 | + arm64_dma_phys_limit = dma32_phys_limit; | |
| 209 | 212 | #endif |
| 213 | + if (!arm64_dma_phys_limit) | |
| 214 | + arm64_dma_phys_limit = PHYS_MASK + 1; | |
| 210 | 215 | max_zone_pfns[ZONE_NORMAL] = max; |
| 211 | 216 | |
| 212 | 217 | free_area_init(max_zone_pfns); |
| @@ -394,16 +399,9 @@ void __init arm64_memblock_init(void) · 181 unmodified lines | ||
| 394 | 399 | |
| 395 | 400 | early_init_fdt_scan_reserved_mem(); |
| 396 | 401 | |
| 397 | − if (IS_ENABLED(CONFIG_ZONE_DMA32)) | |
| 398 | − arm64_dma32_phys_limit = max_zone_phys(32); | |
| 399 | − else | |
| 400 | − arm64_dma32_phys_limit = PHYS_MASK + 1; | |
| 401 | − | |
| 402 | 402 | reserve_elfcorehdr(); |
| 403 | 403 | |
| 404 | 404 | high_memory = __va(memblock_end_of_DRAM() - 1) + 1; |
| 405 | − | |
| 406 | − dma_contiguous_reserve(arm64_dma32_phys_limit); | |
| 407 | 405 | } |
| 408 | 406 | |
| 409 | 407 | void __init bootmem_init(void) |
| @@ -438,6 +436,11 @@ void __init bootmem_init(void) · 28 unmodified lines | ||
| 438 | 436 | sparse_init(); |
| 439 | 437 | zone_sizes_init(min, max); |
| 440 | 438 | |
| 439 | + /* | |
| 440 | + * Reserve the CMA area after arm64_dma_phys_limit was initialised. | |
| 441 | + */ | |
| 442 | + dma_contiguous_reserve(arm64_dma_phys_limit); | |
| 443 | + | |
| 441 | 444 | /* |
| 442 | 445 | * request_standard_resources() depends on crashkernel's memory being |
| 443 | 446 | * reserved, so do it here. |
| @@ -455,7 +458,7 @@ void __init bootmem_init(void) · 11 unmodified lines | ||
| 455 | 458 | void __init mem_init(void) |
| 456 | 459 | { |
| 457 | 460 | if (swiotlb_force == SWIOTLB_FORCE || |
| 458 | − max_pfn > PFN_DOWN(arm64_dma_phys_limit ? : arm64_dma32_phys_limit)) | |
| 461 | + max_pfn > PFN_DOWN(arm64_dma_phys_limit)) | |
| 459 | 462 | swiotlb_init(1); |
| 460 | 463 | else |
| 461 | 464 | swiotlb_force = SWIOTLB_NO_FORCE; |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | phys_addr_t __virt_to_phys(unsigned long x) |
| 11 | 11 | { |
| 12 | − WARN(!__is_lm_address(x), | |
| 12 | + WARN(!__is_lm_address(__tag_reset(x)), | |
| 13 | 13 | "virt_to_phys used for non-linear address: %pK (%pS)\n", |
| 14 | 14 | (void *)x, |
| 15 | 15 | (void *)x); |
| @@ -46,7 +46,7 @@ · 45 unmodified lines | ||
| 46 | 46 | #endif |
| 47 | 47 | |
| 48 | 48 | #ifdef CONFIG_KASAN_HW_TAGS |
| 49 | −#define TCR_KASAN_HW_FLAGS SYS_TCR_EL1_TCMA1 | TCR_TBI1 | |
| 49 | +#define TCR_KASAN_HW_FLAGS SYS_TCR_EL1_TCMA1 | TCR_TBI1 | TCR_TBID1 | |
| 50 | 50 | #else |
| 51 | 51 | #define TCR_KASAN_HW_FLAGS 0 |
| 52 | 52 | #endif |
| @@ -63,6 +63,9 @@ int main(void) · 62 unmodified lines | ||
| 63 | 63 | OFFSET(TI_FLAGS, thread_info, flags); |
| 64 | 64 | OFFSET(TI_CPU, thread_info, cpu); |
| 65 | 65 | OFFSET(TI_PRE, thread_info, preempt_count); |
| 66 | +#ifdef CONFIG_PREEMPTION | |
| 67 | + DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count)); | |
| 68 | +#endif | |
| 66 | 69 | |
| 67 | 70 | return 0; |
| 68 | 71 | } |
| @@ -69,7 +69,7 @@ vmlinux.bin: vmlinux FORCE · 68 unmodified lines | ||
| 69 | 69 | $(call if_changed,objcopy) |
| 70 | 70 | |
| 71 | 71 | unwcheck: vmlinux |
| 72 | − -$(Q)READELF=$(READELF) $(PYTHON) $(srctree)/arch/ia64/scripts/unwcheck.py $< | |
| 72 | + -$(Q)READELF=$(READELF) $(PYTHON3) $(srctree)/arch/ia64/scripts/unwcheck.py $< | |
| 73 | 73 | |
| 74 | 74 | archclean: |
| 75 | 75 | |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | #define _ASM_IA64_SPARSEMEM_H |
| 4 | 4 | |
| 5 | 5 | #ifdef CONFIG_SPARSEMEM |
| 6 | +#include <asm/page.h> | |
| 6 | 7 | /* |
| 7 | 8 | * SECTION_SIZE_BITS 2^N: how big each section will be |
| 8 | 9 | * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space |
| @@ -54,7 +54,7 @@ extern void ia64_xchg_called_with_bad_pointer(void); · 53 unmodified lines | ||
| 54 | 54 | }) |
| 55 | 55 | |
| 56 | 56 | #define xchg(ptr, x) \ |
| 57 | −((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)))) | |
| 57 | +({(__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)));}) | |
| 58 | 58 | |
| 59 | 59 | /* |
| 60 | 60 | * Atomic compare and exchange. Compare OLD with MEM, if identical, |
| @@ -171,29 +171,34 @@ void vtime_account_hardirq(struct task_struct *tsk) · 170 unmodified lines | ||
| 171 | 171 | static irqreturn_t |
| 172 | 172 | timer_interrupt (int irq, void *dev_id) |
| 173 | 173 | { |
| 174 | − unsigned long cur_itm, new_itm, ticks; | |
| 174 | + unsigned long new_itm; | |
| 175 | 175 | |
| 176 | 176 | if (cpu_is_offline(smp_processor_id())) { |
| 177 | 177 | return IRQ_HANDLED; |
| 178 | 178 | } |
| 179 | 179 | |
| 180 | 180 | new_itm = local_cpu_data->itm_next; |
| 181 | − cur_itm = ia64_get_itc(); | |
| 182 | 181 | |
| 183 | − if (!time_after(cur_itm, new_itm)) { | |
| 182 | + if (!time_after(ia64_get_itc(), new_itm)) | |
| 184 | 183 | printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n", |
| 185 | − cur_itm, new_itm); | |
| 186 | − ticks = 1; | |
| 187 | − } else { | |
| 188 | − ticks = DIV_ROUND_UP(cur_itm - new_itm, | |
| 189 | − local_cpu_data->itm_delta); | |
| 190 | − new_itm += ticks * local_cpu_data->itm_delta; | |
| 191 | − } | |
| 184 | + ia64_get_itc(), new_itm); | |
| 185 | + | |
| 186 | + while (1) { | |
| 187 | + new_itm += local_cpu_data->itm_delta; | |
| 188 | + | |
| 189 | + legacy_timer_tick(smp_processor_id() == time_keeper_id); | |
| 192 | 190 | |
| 193 | − if (smp_processor_id() != time_keeper_id) | |
| 194 | − ticks = 0; | |
| 191 | + local_cpu_data->itm_next = new_itm; | |
| 195 | 192 | |
| 196 | − legacy_timer_tick(ticks); | |
| 193 | + if (time_after(new_itm, ia64_get_itc())) | |
| 194 | + break; | |
| 195 | + | |
| 196 | + /* | |
| 197 | + * Allow IPIs to interrupt the timer loop. | |
| 198 | + */ | |
| 199 | + local_irq_enable(); | |
| 200 | + local_irq_disable(); | |
| 201 | + } | |
| 197 | 202 | |
| 198 | 203 | do { |
| 199 | 204 | /* |
| @@ -1,4 +1,4 @@ | ||
| 1 | −#!/usr/bin/env python | |
| 1 | +#!/usr/bin/env python3 | |
| 2 | 2 | # SPDX-License-Identifier: GPL-2.0 |
| 3 | 3 | # |
| 4 | 4 | # Usage: unwcheck.py FILE |
| @@ -62,7 +62,7 @@ extern unsigned long _ramend; · 61 unmodified lines | ||
| 62 | 62 | #include <asm/page_no.h> |
| 63 | 63 | #endif |
| 64 | 64 | |
| 65 | −#ifdef CONFIG_DISCONTIGMEM | |
| 65 | +#if !defined(CONFIG_MMU) || defined(CONFIG_DISCONTIGMEM) | |
| 66 | 66 | #define __phys_to_pfn(paddr) ((unsigned long)((paddr) >> PAGE_SHIFT)) |
| 67 | 67 | #define __pfn_to_phys(pfn) PFN_PHYS(pfn) |
| 68 | 68 | #endif |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/libfdt.h> |
| 14 | 14 | |
| 15 | 15 | #include <asm/addrspace.h> |
| 16 | +#include <asm/unaligned.h> | |
| 16 | 17 | |
| 17 | 18 | /* |
| 18 | 19 | * These two variables specify the free mem region |
| @@ -117,7 +118,7 @@ void decompress_kernel(unsigned long boot_heap_start) · 98 unmodified lines | ||
| 117 | 118 | dtb_size = fdt_totalsize((void *)&__appended_dtb); |
| 118 | 119 | |
| 119 | 120 | /* last four bytes is always image size in little endian */ |
| 120 | − image_size = le32_to_cpup((void *)&__image_end - 4); | |
| 121 | + image_size = get_unaligned_le32((void *)&__image_end - 4); | |
| 121 | 122 | |
| 122 | 123 | /* copy dtb to where the booted kernel will expect it */ |
| 123 | 124 | memcpy((void *)VMLINUX_LOAD_ADDRESS_ULL + image_size, |
| @@ -1444,7 +1444,7 @@ static void octeon_irq_setup_secondary_ciu2(void) · 1443 unmodified lines | ||
| 1444 | 1444 | static int __init octeon_irq_init_ciu( |
| 1445 | 1445 | struct device_node *ciu_node, struct device_node *parent) |
| 1446 | 1446 | { |
| 1447 | − unsigned int i, r; | |
| 1447 | + int i, r; | |
| 1448 | 1448 | struct irq_chip *chip; |
| 1449 | 1449 | struct irq_chip *chip_edge; |
| 1450 | 1450 | struct irq_chip *chip_mbox; |
| @@ -51,6 +51,7 @@ extern void kmap_flush_tlb(unsigned long addr); · 50 unmodified lines | ||
| 51 | 51 | |
| 52 | 52 | #define flush_cache_kmaps() BUG_ON(cpu_has_dc_aliases) |
| 53 | 53 | |
| 54 | +#define arch_kmap_local_set_pte(mm, vaddr, ptep, ptev) set_pte(ptep, ptev) | |
| 54 | 55 | #define arch_kmap_local_post_map(vaddr, pteval) local_flush_tlb_one(vaddr) |
| 55 | 56 | #define arch_kmap_local_post_unmap(vaddr) local_flush_tlb_one(vaddr) |
| 56 | 57 | |
| @@ -103,4 +103,11 @@ jiffies_to_old_timeval32(unsigned long jiffies, struct old_timeval32 *value) · 102 unmodified lines | ||
| 103 | 103 | #undef ns_to_kernel_old_timeval |
| 104 | 104 | #define ns_to_kernel_old_timeval ns_to_old_timeval32 |
| 105 | 105 | |
| 106 | +/* | |
| 107 | + * Some data types as stored in coredump. | |
| 108 | + */ | |
| 109 | +#define user_long_t compat_long_t | |
| 110 | +#define user_siginfo_t compat_siginfo_t | |
| 111 | +#define copy_siginfo_to_external copy_siginfo_to_external32 | |
| 112 | + | |
| 106 | 113 | #include "../../../fs/binfmt_elf.c" |
| @@ -106,4 +106,11 @@ jiffies_to_old_timeval32(unsigned long jiffies, struct old_timeval32 *value) · 105 unmodified lines | ||
| 106 | 106 | #undef ns_to_kernel_old_timeval |
| 107 | 107 | #define ns_to_kernel_old_timeval ns_to_old_timeval32 |
| 108 | 108 | |
| 109 | +/* | |
| 110 | + * Some data types as stored in coredump. | |
| 111 | + */ | |
| 112 | +#define user_long_t compat_long_t | |
| 113 | +#define user_siginfo_t compat_siginfo_t | |
| 114 | +#define copy_siginfo_to_external copy_siginfo_to_external32 | |
| 115 | + | |
| 109 | 116 | #include "../../../fs/binfmt_elf.c" |
| @@ -187,8 +187,14 @@ static int __init relocate_exception_table(long offset) · 186 unmodified lines | ||
| 187 | 187 | static inline __init unsigned long rotate_xor(unsigned long hash, |
| 188 | 188 | const void *area, size_t size) |
| 189 | 189 | { |
| 190 | − size_t i; | |
| 191 | − unsigned long *ptr = (unsigned long *)area; | |
| 190 | + const typeof(hash) *ptr = PTR_ALIGN(area, sizeof(hash)); | |
| 191 | + size_t diff, i; | |
| 192 | + | |
| 193 | + diff = (void *)ptr - area; | |
| 194 | + if (unlikely(size < diff + sizeof(hash))) | |
| 195 | + return hash; | |
| 196 | + | |
| 197 | + size = ALIGN_DOWN(size - diff, sizeof(hash)); | |
| 192 | 198 | |
| 193 | 199 | for (i = 0; i < size / sizeof(hash); i++) { |
| 194 | 200 | /* Rotate by odd number of bits and XOR. */ |
| @@ -31,7 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | void __iomem *ioremap(phys_addr_t offset, unsigned long size); |
| 32 | 32 | |
| 33 | 33 | #define iounmap iounmap |
| 34 | −extern void iounmap(void *addr); | |
| 34 | +extern void iounmap(void __iomem *addr); | |
| 35 | 35 | |
| 36 | 36 | #include <asm-generic/io.h> |
| 37 | 37 | |
| @@ -77,7 +77,7 @@ void __iomem *__ref ioremap(phys_addr_t addr, unsigned long size) · 76 unmodified lines | ||
| 77 | 77 | } |
| 78 | 78 | EXPORT_SYMBOL(ioremap); |
| 79 | 79 | |
| 80 | −void iounmap(void *addr) | |
| 80 | +void iounmap(void __iomem *addr) | |
| 81 | 81 | { |
| 82 | 82 | /* If the page is from the fixmap pool then we just clear out |
| 83 | 83 | * the fixmap mapping. |
| @@ -202,9 +202,8 @@ config PREFETCH · 201 unmodified lines | ||
| 202 | 202 | depends on PA8X00 || PA7200 |
| 203 | 203 | |
| 204 | 204 | config MLONGCALLS |
| 205 | − bool "Enable the -mlong-calls compiler option for big kernels" | |
| 206 | − default y if !MODULES || UBSAN || FTRACE | |
| 207 | − default n | |
| 205 | + def_bool y if !MODULES || UBSAN || FTRACE | |
| 206 | + bool "Enable the -mlong-calls compiler option for big kernels" if MODULES && !UBSAN && !FTRACE | |
| 208 | 207 | depends on PA8X00 |
| 209 | 208 | help |
| 210 | 209 | If you configure the kernel to include many drivers built-in instead |
| @@ -47,7 +47,4 @@ extern unsigned long txn_affinity_addr(unsigned int irq, int cpu); · 46 unmodified lines | ||
| 47 | 47 | extern int cpu_claim_irq(unsigned int irq, struct irq_chip *, void *); |
| 48 | 48 | extern int cpu_check_affinity(struct irq_data *d, const struct cpumask *dest); |
| 49 | 49 | |
| 50 | −/* soft power switch support (power.c) */ | |
| 51 | −extern struct tasklet_struct power_tasklet; | |
| 52 | − | |
| 53 | 50 | #endif /* _ASM_PARISC_IRQ_H */ |
| @@ -997,10 +997,17 @@ intr_do_preempt: · 996 unmodified lines | ||
| 997 | 997 | bb,<,n %r20, 31 - PSW_SM_I, intr_restore |
| 998 | 998 | nop |
| 999 | 999 | |
| 1000 | + /* ssm PSW_SM_I done later in intr_restore */ | |
| 1001 | +#ifdef CONFIG_MLONGCALLS | |
| 1002 | + ldil L%intr_restore, %r2 | |
| 1003 | + load32 preempt_schedule_irq, %r1 | |
| 1004 | + bv %r0(%r1) | |
| 1005 | + ldo R%intr_restore(%r2), %r2 | |
| 1006 | +#else | |
| 1007 | + ldil L%intr_restore, %r1 | |
| 1000 | 1008 | BL preempt_schedule_irq, %r2 |
| 1001 | − nop | |
| 1002 | − | |
| 1003 | − b,n intr_restore /* ssm PSW_SM_I done by intr_restore */ | |
| 1009 | + ldo R%intr_restore(%r1), %r2 | |
| 1010 | +#endif | |
| 1004 | 1011 | #endif /* CONFIG_PREEMPTION */ |
| 1005 | 1012 | |
| 1006 | 1013 | /* |
| @@ -199,25 +199,31 @@ DECLARE_STATIC_KEY_FALSE(uaccess_flush_key); · 198 unmodified lines | ||
| 199 | 199 | |
| 200 | 200 | #ifdef CONFIG_PPC_PKEY |
| 201 | 201 | |
| 202 | +extern u64 __ro_after_init default_uamor; | |
| 203 | +extern u64 __ro_after_init default_amr; | |
| 204 | +extern u64 __ro_after_init default_iamr; | |
| 205 | + | |
| 202 | 206 | #include <asm/mmu.h> |
| 203 | 207 | #include <asm/ptrace.h> |
| 204 | 208 | |
| 205 | −/* | |
| 206 | − * For kernel thread that doesn't have thread.regs return | |
| 207 | − * default AMR/IAMR values. | |
| 209 | +/* usage of kthread_use_mm() should inherit the | |
| 210 | + * AMR value of the operating address space. But, the AMR value is | |
| 211 | + * thread-specific and we inherit the address space and not thread | |
| 212 | + * access restrictions. Because of this ignore AMR value when accessing | |
| 213 | + * userspace via kernel thread. | |
| 208 | 214 | */ |
| 209 | 215 | static inline u64 current_thread_amr(void) |
| 210 | 216 | { |
| 211 | 217 | if (current->thread.regs) |
| 212 | 218 | return current->thread.regs->amr; |
| 213 | − return AMR_KUAP_BLOCKED; | |
| 219 | + return default_amr; | |
| 214 | 220 | } |
| 215 | 221 | |
| 216 | 222 | static inline u64 current_thread_iamr(void) |
| 217 | 223 | { |
| 218 | 224 | if (current->thread.regs) |
| 219 | 225 | return current->thread.regs->iamr; |
| 220 | − return AMR_KUEP_BLOCKED; | |
| 226 | + return default_iamr; | |
| 221 | 227 | } |
| 222 | 228 | #endif /* CONFIG_PPC_PKEY */ |
| 223 | 229 | |
| @@ -5,10 +5,6 @@ · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | #include <asm/book3s/64/hash-pkey.h> |
| 7 | 7 | |
| 8 | −extern u64 __ro_after_init default_uamor; | |
| 9 | −extern u64 __ro_after_init default_amr; | |
| 10 | −extern u64 __ro_after_init default_iamr; | |
| 11 | − | |
| 12 | 8 | static inline u64 vmflag_to_pte_pkey_bits(u64 vm_flags) |
| 13 | 9 | { |
| 14 | 10 | if (!mmu_has_feature(MMU_FTR_PKEY)) |
| @@ -63,6 +63,12 @@ · 62 unmodified lines | ||
| 63 | 63 | nop; \ |
| 64 | 64 | nop; |
| 65 | 65 | |
| 66 | +#define SCV_ENTRY_FLUSH_SLOT \ | |
| 67 | + SCV_ENTRY_FLUSH_FIXUP_SECTION; \ | |
| 68 | + nop; \ | |
| 69 | + nop; \ | |
| 70 | + nop; | |
| 71 | + | |
| 66 | 72 | /* |
| 67 | 73 | * r10 must be free to use, r13 must be paca |
| 68 | 74 | */ |
| @@ -70,6 +76,13 @@ · 1 unmodified line | ||
| 70 | 76 | STF_ENTRY_BARRIER_SLOT; \ |
| 71 | 77 | ENTRY_FLUSH_SLOT |
| 72 | 78 | |
| 79 | +/* | |
| 80 | + * r10, ctr must be free to use, r13 must be paca | |
| 81 | + */ | |
| 82 | +#define SCV_INTERRUPT_TO_KERNEL \ | |
| 83 | + STF_ENTRY_BARRIER_SLOT; \ | |
| 84 | + SCV_ENTRY_FLUSH_SLOT | |
| 85 | + | |
| 73 | 86 | /* |
| 74 | 87 | * Macros for annotating the expected destination of (h)rfid |
| 75 | 88 | * |
| @@ -240,6 +240,14 @@ label##3: \ · 239 unmodified lines | ||
| 240 | 240 | FTR_ENTRY_OFFSET 957b-958b; \ |
| 241 | 241 | .popsection; |
| 242 | 242 | |
| 243 | +#define SCV_ENTRY_FLUSH_FIXUP_SECTION \ | |
| 244 | +957: \ | |
| 245 | + .pushsection __scv_entry_flush_fixup,"a"; \ | |
| 246 | + .align 2; \ | |
| 247 | +958: \ | |
| 248 | + FTR_ENTRY_OFFSET 957b-958b; \ | |
| 249 | + .popsection; | |
| 250 | + | |
| 243 | 251 | #define RFI_FLUSH_FIXUP_SECTION \ |
| 244 | 252 | 951: \ |
| 245 | 253 | .pushsection __rfi_flush_fixup,"a"; \ |
| @@ -273,10 +281,12 @@ label##3: \ · 27 unmodified lines | ||
| 273 | 281 | |
| 274 | 282 | extern long stf_barrier_fallback; |
| 275 | 283 | extern long entry_flush_fallback; |
| 284 | +extern long scv_entry_flush_fallback; | |
| 276 | 285 | extern long __start___stf_entry_barrier_fixup, __stop___stf_entry_barrier_fixup; |
| 277 | 286 | extern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup; |
| 278 | 287 | extern long __start___uaccess_flush_fixup, __stop___uaccess_flush_fixup; |
| 279 | 288 | extern long __start___entry_flush_fixup, __stop___entry_flush_fixup; |
| 289 | +extern long __start___scv_entry_flush_fixup, __stop___scv_entry_flush_fixup; | |
| 280 | 290 | extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup; |
| 281 | 291 | extern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup; |
| 282 | 292 | extern long __start__btb_flush_fixup, __stop__btb_flush_fixup; |
| @@ -58,6 +58,8 @@ extern pte_t *pkmap_page_table; · 57 unmodified lines | ||
| 58 | 58 | |
| 59 | 59 | #define flush_cache_kmaps() flush_cache_all() |
| 60 | 60 | |
| 61 | +#define arch_kmap_local_set_pte(mm, vaddr, ptep, ptev) \ | |
| 62 | + __set_pte_at(mm, vaddr, ptep, ptev, 1) | |
| 61 | 63 | #define arch_kmap_local_post_map(vaddr, pteval) \ |
| 62 | 64 | local_flush_tlb_page(NULL, vaddr) |
| 63 | 65 | #define arch_kmap_local_post_unmap(vaddr) \ |
| @@ -103,6 +103,8 @@ int gettimeofday_fallback(struct __kernel_old_timeval *_tv, struct timezone *_tz · 102 unmodified lines | ||
| 103 | 103 | return do_syscall_2(__NR_gettimeofday, (unsigned long)_tv, (unsigned long)_tz); |
| 104 | 104 | } |
| 105 | 105 | |
| 106 | +#ifdef __powerpc64__ | |
| 107 | + | |
| 106 | 108 | static __always_inline |
| 107 | 109 | int clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) |
| 108 | 110 | { |
| @@ -115,10 +117,22 @@ int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) · 6 unmodified lines | ||
| 115 | 117 | return do_syscall_2(__NR_clock_getres, _clkid, (unsigned long)_ts); |
| 116 | 118 | } |
| 117 | 119 | |
| 118 | −#ifdef CONFIG_VDSO32 | |
| 120 | +#else | |
| 119 | 121 | |
| 120 | 122 | #define BUILD_VDSO32 1 |
| 121 | 123 | |
| 124 | +static __always_inline | |
| 125 | +int clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) | |
| 126 | +{ | |
| 127 | + return do_syscall_2(__NR_clock_gettime64, _clkid, (unsigned long)_ts); | |
| 128 | +} | |
| 129 | + | |
| 130 | +static __always_inline | |
| 131 | +int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) | |
| 132 | +{ | |
| 133 | + return do_syscall_2(__NR_clock_getres_time64, _clkid, (unsigned long)_ts); | |
| 134 | +} | |
| 135 | + | |
| 122 | 136 | static __always_inline |
| 123 | 137 | int clock_gettime32_fallback(clockid_t _clkid, struct old_timespec32 *_ts) |
| 124 | 138 | { |
| @@ -51,7 +51,7 @@ obj-y += ptrace/ · 50 unmodified lines | ||
| 51 | 51 | obj-$(CONFIG_PPC64) += setup_64.o \ |
| 52 | 52 | paca.o nvram_64.o note.o syscall_64.o |
| 53 | 53 | obj-$(CONFIG_COMPAT) += sys_ppc32.o signal_32.o |
| 54 | −obj-$(CONFIG_VDSO32) += vdso32/ | |
| 54 | +obj-$(CONFIG_VDSO32) += vdso32_wrapper.o | |
| 55 | 55 | obj-$(CONFIG_PPC_WATCHDOG) += watchdog.o |
| 56 | 56 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o |
| 57 | 57 | obj-$(CONFIG_PPC_DAWR) += dawr.o |
| @@ -60,7 +60,7 @@ obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o · 2 unmodified lines | ||
| 60 | 60 | obj-$(CONFIG_PPC_BOOK3S_64) += mce.o mce_power.o |
| 61 | 61 | obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_book3e.o |
| 62 | 62 | obj-$(CONFIG_PPC_BARRIER_NOSPEC) += security.o |
| 63 | −obj-$(CONFIG_PPC64) += vdso64/ | |
| 63 | +obj-$(CONFIG_PPC64) += vdso64_wrapper.o | |
| 64 | 64 | obj-$(CONFIG_ALTIVEC) += vecemu.o |
| 65 | 65 | obj-$(CONFIG_PPC_BOOK3S_IDLE) += idle_book3s.o |
| 66 | 66 | procfs-y := proc_powerpc.o |
| @@ -75,7 +75,7 @@ BEGIN_FTR_SECTION · 74 unmodified lines | ||
| 75 | 75 | bne .Ltabort_syscall |
| 76 | 76 | END_FTR_SECTION_IFSET(CPU_FTR_TM) |
| 77 | 77 | #endif |
| 78 | − INTERRUPT_TO_KERNEL | |
| 78 | + SCV_INTERRUPT_TO_KERNEL | |
| 79 | 79 | mr r10,r1 |
| 80 | 80 | ld r1,PACAKSAVE(r13) |
| 81 | 81 | std r10,0(r1) |
| @@ -2993,6 +2993,25 @@ TRAMP_REAL_BEGIN(entry_flush_fallback) · 2992 unmodified lines | ||
| 2993 | 2993 | ld r11,PACA_EXRFI+EX_R11(r13) |
| 2994 | 2994 | blr |
| 2995 | 2995 | |
| 2996 | +/* | |
| 2997 | + * The SCV entry flush happens with interrupts enabled, so it must disable | |
| 2998 | + * to prevent EXRFI being clobbered by NMIs (e.g., soft_nmi_common). r10 | |
| 2999 | + * (containing LR) does not need to be preserved here because scv entry | |
| 3000 | + * puts 0 in the pt_regs, CTR can be clobbered for the same reason. | |
| 3001 | + */ | |
| 3002 | +TRAMP_REAL_BEGIN(scv_entry_flush_fallback) | |
| 3003 | + li r10,0 | |
| 3004 | + mtmsrd r10,1 | |
| 3005 | + lbz r10,PACAIRQHAPPENED(r13) | |
| 3006 | + ori r10,r10,PACA_IRQ_HARD_DIS | |
| 3007 | + stb r10,PACAIRQHAPPENED(r13) | |
| 3008 | + std r11,PACA_EXRFI+EX_R11(r13) | |
| 3009 | + L1D_DISPLACEMENT_FLUSH | |
| 3010 | + ld r11,PACA_EXRFI+EX_R11(r13) | |
| 3011 | + li r10,MSR_RI | |
| 3012 | + mtmsrd r10,1 | |
| 3013 | + blr | |
| 3014 | + | |
| 2996 | 3015 | TRAMP_REAL_BEGIN(rfi_flush_fallback) |
| 2997 | 3016 | SET_SCRATCH0(r13); |
| 2998 | 3017 | GET_PACA(r13); |
| @@ -260,10 +260,19 @@ __secondary_hold_acknowledge: · 259 unmodified lines | ||
| 260 | 260 | MachineCheck: |
| 261 | 261 | EXCEPTION_PROLOG_0 |
| 262 | 262 | #ifdef CONFIG_PPC_CHRP |
| 263 | +#ifdef CONFIG_VMAP_STACK | |
| 264 | + mtspr SPRN_SPRG_SCRATCH2,r1 | |
| 265 | + mfspr r1, SPRN_SPRG_THREAD | |
| 266 | + lwz r1, RTAS_SP(r1) | |
| 267 | + cmpwi cr1, r1, 0 | |
| 268 | + bne cr1, 7f | |
| 269 | + mfspr r1, SPRN_SPRG_SCRATCH2 | |
| 270 | +#else | |
| 263 | 271 | mfspr r11, SPRN_SPRG_THREAD |
| 264 | 272 | lwz r11, RTAS_SP(r11) |
| 265 | 273 | cmpwi cr1, r11, 0 |
| 266 | 274 | bne cr1, 7f |
| 275 | +#endif | |
| 267 | 276 | #endif /* CONFIG_PPC_CHRP */ |
| 268 | 277 | EXCEPTION_PROLOG_1 for_rtas=1 |
| 269 | 278 | 7: EXCEPTION_PROLOG_2 |
| @@ -180,13 +180,18 @@ void notrace restore_interrupts(void) · 179 unmodified lines | ||
| 180 | 180 | |
| 181 | 181 | void replay_soft_interrupts(void) |
| 182 | 182 | { |
| 183 | + struct pt_regs regs; | |
| 184 | + | |
| 183 | 185 | /* |
| 184 | − * We use local_paca rather than get_paca() to avoid all | |
| 185 | − * the debug_smp_processor_id() business in this low level | |
| 186 | − * function | |
| 186 | + * Be careful here, calling these interrupt handlers can cause | |
| 187 | + * softirqs to be raised, which they may run when calling irq_exit, | |
| 188 | + * which will cause local_irq_enable() to be run, which can then | |
| 189 | + * recurse into this function. Don't keep any state across | |
| 190 | + * interrupt handler calls which may change underneath us. | |
| 191 | + * | |
| 192 | + * We use local_paca rather than get_paca() to avoid all the | |
| 193 | + * debug_smp_processor_id() business in this low level function. | |
| 187 | 194 | */ |
| 188 | − unsigned char happened = local_paca->irq_happened; | |
| 189 | − struct pt_regs regs; | |
| 190 | 195 | |
| 191 | 196 | ppc_save_regs(®s); |
| 192 | 197 | regs.softe = IRQS_ENABLED; |
| @@ -209,7 +214,7 @@ again: · 16 unmodified lines | ||
| 209 | 214 | * This is a higher priority interrupt than the others, so |
| 210 | 215 | * replay it first. |
| 211 | 216 | */ |
| 212 | − if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (happened & PACA_IRQ_HMI)) { | |
| 217 | + if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (local_paca->irq_happened & PACA_IRQ_HMI)) { | |
| 213 | 218 | local_paca->irq_happened &= ~PACA_IRQ_HMI; |
| 214 | 219 | regs.trap = 0xe60; |
| 215 | 220 | handle_hmi_exception(®s); |
| @@ -217,7 +222,7 @@ again: · 1 unmodified line | ||
| 217 | 222 | hard_irq_disable(); |
| 218 | 223 | } |
| 219 | 224 | |
| 220 | − if (happened & PACA_IRQ_DEC) { | |
| 225 | + if (local_paca->irq_happened & PACA_IRQ_DEC) { | |
| 221 | 226 | local_paca->irq_happened &= ~PACA_IRQ_DEC; |
| 222 | 227 | regs.trap = 0x900; |
| 223 | 228 | timer_interrupt(®s); |
| @@ -225,7 +230,7 @@ again: · 1 unmodified line | ||
| 225 | 230 | hard_irq_disable(); |
| 226 | 231 | } |
| 227 | 232 | |
| 228 | − if (happened & PACA_IRQ_EE) { | |
| 233 | + if (local_paca->irq_happened & PACA_IRQ_EE) { | |
| 229 | 234 | local_paca->irq_happened &= ~PACA_IRQ_EE; |
| 230 | 235 | regs.trap = 0x500; |
| 231 | 236 | do_IRQ(®s); |
| @@ -233,7 +238,7 @@ again: · 1 unmodified line | ||
| 233 | 238 | hard_irq_disable(); |
| 234 | 239 | } |
| 235 | 240 | |
| 236 | − if (IS_ENABLED(CONFIG_PPC_DOORBELL) && (happened & PACA_IRQ_DBELL)) { | |
| 241 | + if (IS_ENABLED(CONFIG_PPC_DOORBELL) && (local_paca->irq_happened & PACA_IRQ_DBELL)) { | |
| 237 | 242 | local_paca->irq_happened &= ~PACA_IRQ_DBELL; |
| 238 | 243 | if (IS_ENABLED(CONFIG_PPC_BOOK3E)) |
| 239 | 244 | regs.trap = 0x280; |
| @@ -245,7 +250,7 @@ again: · 5 unmodified lines | ||
| 245 | 250 | } |
| 246 | 251 | |
| 247 | 252 | /* Book3E does not support soft-masking PMI interrupts */ |
| 248 | − if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (happened & PACA_IRQ_PMI)) { | |
| 253 | + if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (local_paca->irq_happened & PACA_IRQ_PMI)) { | |
| 249 | 254 | local_paca->irq_happened &= ~PACA_IRQ_PMI; |
| 250 | 255 | regs.trap = 0xf00; |
| 251 | 256 | performance_monitor_exception(®s); |
| @@ -253,8 +258,7 @@ again: · 1 unmodified line | ||
| 253 | 258 | hard_irq_disable(); |
| 254 | 259 | } |
| 255 | 260 | |
| 256 | − happened = local_paca->irq_happened; | |
| 257 | − if (happened & ~PACA_IRQ_HARD_DIS) { | |
| 261 | + if (local_paca->irq_happened & ~PACA_IRQ_HARD_DIS) { | |
| 258 | 262 | /* |
| 259 | 263 | * We are responding to the next interrupt, so interrupt-off |
| 260 | 264 | * latencies should be reset here. |
| @@ -30,7 +30,7 @@ CC32FLAGS += -m32 · 29 unmodified lines | ||
| 30 | 30 | KBUILD_CFLAGS := $(filter-out -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc,$(KBUILD_CFLAGS)) |
| 31 | 31 | endif |
| 32 | 32 | |
| 33 | −targets := $(obj-vdso32) vdso32.so.dbg | |
| 33 | +targets := $(obj-vdso32) vdso32.so.dbg vgettimeofday.o | |
| 34 | 34 | obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32)) |
| 35 | 35 | |
| 36 | 36 | GCOV_PROFILE := n |
| @@ -46,9 +46,6 @@ obj-y += vdso32_wrapper.o · 9 unmodified lines | ||
| 46 | 46 | targets += vdso32.lds |
| 47 | 47 | CPPFLAGS_vdso32.lds += -P -C -Upowerpc |
| 48 | 48 | |
| 49 | −# Force dependency (incbin is bad) | |
| 50 | −$(obj)/vdso32_wrapper.o : $(obj)/vdso32.so.dbg | |
| 51 | − | |
| 52 | 49 | # link rule for the .so file, .lds has to be first |
| 53 | 50 | $(obj)/vdso32.so.dbg: $(src)/vdso32.lds $(obj-vdso32) $(obj)/vgettimeofday.o FORCE |
| 54 | 51 | $(call if_changed,vdso32ld_and_check) |
File renamed without changes.
| @@ -17,7 +17,7 @@ endif · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | # Build rules |
| 19 | 19 | |
| 20 | −targets := $(obj-vdso64) vdso64.so.dbg | |
| 20 | +targets := $(obj-vdso64) vdso64.so.dbg vgettimeofday.o | |
| 21 | 21 | obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64)) |
| 22 | 22 | |
| 23 | 23 | GCOV_PROFILE := n |
| @@ -29,15 +29,9 @@ ccflags-y := -shared -fno-common -fno-builtin -nostdlib \ · 5 unmodified lines | ||
| 29 | 29 | -Wl,-soname=linux-vdso64.so.1 -Wl,--hash-style=both |
| 30 | 30 | asflags-y := -D__VDSO64__ -s |
| 31 | 31 | |
| 32 | −obj-y += vdso64_wrapper.o | |
| 33 | 32 | targets += vdso64.lds |
| 34 | 33 | CPPFLAGS_vdso64.lds += -P -C -U$(ARCH) |
| 35 | 34 | |
| 36 | −$(obj)/vgettimeofday.o: %.o: %.c FORCE | |
| 37 | − | |
| 38 | −# Force dependency (incbin is bad) | |
| 39 | −$(obj)/vdso64_wrapper.o : $(obj)/vdso64.so.dbg | |
| 40 | − | |
| 41 | 35 | # link rule for the .so file, .lds has to be first |
| 42 | 36 | $(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) $(obj)/vgettimeofday.o FORCE |
| 43 | 37 | $(call if_changed,vdso64ld_and_check) |
| @@ -15,11 +15,20 @@ · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | .text |
| 17 | 17 | |
| 18 | +/* | |
| 19 | + * __kernel_start_sigtramp_rt64 and __kernel_sigtramp_rt64 together | |
| 20 | + * are one function split in two parts. The kernel jumps to the former | |
| 21 | + * and the signal handler indirectly (by blr) returns to the latter. | |
| 22 | + * __kernel_sigtramp_rt64 needs to point to the return address so | |
| 23 | + * glibc can correctly identify the trampoline stack frame. | |
| 24 | + */ | |
| 18 | 25 | .balign 8 |
| 19 | 26 | .balign IFETCH_ALIGN_BYTES |
| 20 | −V_FUNCTION_BEGIN(__kernel_sigtramp_rt64) | |
| 27 | +V_FUNCTION_BEGIN(__kernel_start_sigtramp_rt64) | |
| 21 | 28 | .Lsigrt_start: |
| 22 | 29 | bctrl /* call the handler */ |
| 30 | +V_FUNCTION_END(__kernel_start_sigtramp_rt64) | |
| 31 | +V_FUNCTION_BEGIN(__kernel_sigtramp_rt64) | |
| 23 | 32 | addi r1, r1, __SIGNAL_FRAMESIZE |
| 24 | 33 | li r0,__NR_rt_sigreturn |
| 25 | 34 | sc |
| @@ -131,4 +131,4 @@ VERSION · 130 unmodified lines | ||
| 131 | 131 | /* |
| 132 | 132 | * Make the sigreturn code visible to the kernel. |
| 133 | 133 | */ |
| 134 | −VDSO_sigtramp_rt64 = __kernel_sigtramp_rt64; | |
| 134 | +VDSO_sigtramp_rt64 = __kernel_start_sigtramp_rt64; | |
File renamed without changes.
| @@ -85,7 +85,7 @@ SECTIONS · 84 unmodified lines | ||
| 85 | 85 | ALIGN_FUNCTION(); |
| 86 | 86 | #endif |
| 87 | 87 | /* careful! __ftr_alt_* sections need to be close to .text */ |
| 88 | − *(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text); | |
| 88 | + *(.text.hot .text.hot.* TEXT_MAIN .text.fixup .text.unlikely .text.unlikely.* .fixup __ftr_alt_* .ref.text); | |
| 89 | 89 | #ifdef CONFIG_PPC64 |
| 90 | 90 | *(.tramp.ftrace.text); |
| 91 | 91 | #endif |
| @@ -145,6 +145,13 @@ SECTIONS · 53 unmodified lines | ||
| 145 | 145 | __stop___entry_flush_fixup = .; |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | + . = ALIGN(8); | |
| 149 | + __scv_entry_flush_fixup : AT(ADDR(__scv_entry_flush_fixup) - LOAD_OFFSET) { | |
| 150 | + __start___scv_entry_flush_fixup = .; | |
| 151 | + *(__scv_entry_flush_fixup) | |
| 152 | + __stop___scv_entry_flush_fixup = .; | |
| 153 | + } | |
| 154 | + | |
| 148 | 155 | . = ALIGN(8); |
| 149 | 156 | __stf_exit_barrier_fixup : AT(ADDR(__stf_exit_barrier_fixup) - LOAD_OFFSET) { |
| 150 | 157 | __start___stf_exit_barrier_fixup = .; |
| @@ -187,6 +194,12 @@ SECTIONS · 36 unmodified lines | ||
| 187 | 194 | .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { |
| 188 | 195 | _sinittext = .; |
| 189 | 196 | INIT_TEXT |
| 197 | + | |
| 198 | + /* | |
| 199 | + *.init.text might be RO so we must ensure this section ends on | |
| 200 | + * a page boundary. | |
| 201 | + */ | |
| 202 | + . = ALIGN(PAGE_SIZE); | |
| 190 | 203 | _einittext = .; |
| 191 | 204 | #ifdef CONFIG_PPC64 |
| 192 | 205 | *(.tramp.ftrace.init); |
| @@ -200,6 +213,8 @@ SECTIONS · 7 unmodified lines | ||
| 200 | 213 | EXIT_TEXT |
| 201 | 214 | } |
| 202 | 215 | |
| 216 | + . = ALIGN(PAGE_SIZE); | |
| 217 | + | |
| 203 | 218 | INIT_DATA_SECTION(16) |
| 204 | 219 | |
| 205 | 220 | . = ALIGN(8); |
| @@ -290,9 +290,6 @@ void do_entry_flush_fixups(enum l1d_flush_type types) · 289 unmodified lines | ||
| 290 | 290 | long *start, *end; |
| 291 | 291 | int i; |
| 292 | 292 | |
| 293 | − start = PTRRELOC(&__start___entry_flush_fixup); | |
| 294 | − end = PTRRELOC(&__stop___entry_flush_fixup); | |
| 295 | − | |
| 296 | 293 | instrs[0] = 0x60000000; /* nop */ |
| 297 | 294 | instrs[1] = 0x60000000; /* nop */ |
| 298 | 295 | instrs[2] = 0x60000000; /* nop */ |
| @@ -312,6 +309,8 @@ void do_entry_flush_fixups(enum l1d_flush_type types) · 13 unmodified lines | ||
| 312 | 309 | if (types & L1D_FLUSH_MTTRIG) |
| 313 | 310 | instrs[i++] = 0x7c12dba6; /* mtspr TRIG2,r0 (SPR #882) */ |
| 314 | 311 | |
| 312 | + start = PTRRELOC(&__start___entry_flush_fixup); | |
| 313 | + end = PTRRELOC(&__stop___entry_flush_fixup); | |
| 315 | 314 | for (i = 0; start < end; start++, i++) { |
| 316 | 315 | dest = (void *)start + *start; |
| 317 | 316 | |
| @@ -328,6 +327,25 @@ void do_entry_flush_fixups(enum l1d_flush_type types) · 10 unmodified lines | ||
| 328 | 327 | patch_instruction((struct ppc_inst *)(dest + 2), ppc_inst(instrs[2])); |
| 329 | 328 | } |
| 330 | 329 | |
| 330 | + start = PTRRELOC(&__start___scv_entry_flush_fixup); | |
| 331 | + end = PTRRELOC(&__stop___scv_entry_flush_fixup); | |
| 332 | + for (; start < end; start++, i++) { | |
| 333 | + dest = (void *)start + *start; | |
| 334 | + | |
| 335 | + pr_devel("patching dest %lx\n", (unsigned long)dest); | |
| 336 | + | |
| 337 | + patch_instruction((struct ppc_inst *)dest, ppc_inst(instrs[0])); | |
| 338 | + | |
| 339 | + if (types == L1D_FLUSH_FALLBACK) | |
| 340 | + patch_branch((struct ppc_inst *)(dest + 1), (unsigned long)&scv_entry_flush_fallback, | |
| 341 | + BRANCH_SET_LINK); | |
| 342 | + else | |
| 343 | + patch_instruction((struct ppc_inst *)(dest + 1), ppc_inst(instrs[1])); | |
| 344 | + | |
| 345 | + patch_instruction((struct ppc_inst *)(dest + 2), ppc_inst(instrs[2])); | |
| 346 | + } | |
| 347 | + | |
| 348 | + | |
| 331 | 349 | printk(KERN_DEBUG "entry-flush: patched %d locations (%s flush)\n", i, |
| 332 | 350 | (types == L1D_FLUSH_NONE) ? "no" : |
| 333 | 351 | (types == L1D_FLUSH_FALLBACK) ? "fallback displacement" : |
| @@ -818,13 +818,15 @@ void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg, · 817 unmodified lines | ||
| 818 | 818 | break; |
| 819 | 819 | if (rev) { |
| 820 | 820 | /* reverse 32 bytes */ |
| 821 | − buf.d[0] = byterev_8(reg->d[3]); | |
| 822 | − buf.d[1] = byterev_8(reg->d[2]); | |
| 823 | − buf.d[2] = byterev_8(reg->d[1]); | |
| 824 | − buf.d[3] = byterev_8(reg->d[0]); | |
| 825 | − reg = &buf; | |
| 821 | + union vsx_reg buf32[2]; | |
| 822 | + buf32[0].d[0] = byterev_8(reg[1].d[1]); | |
| 823 | + buf32[0].d[1] = byterev_8(reg[1].d[0]); | |
| 824 | + buf32[1].d[0] = byterev_8(reg[0].d[1]); | |
| 825 | + buf32[1].d[1] = byterev_8(reg[0].d[0]); | |
| 826 | + memcpy(mem, buf32, size); | |
| 827 | + } else { | |
| 828 | + memcpy(mem, reg, size); | |
| 826 | 829 | } |
| 827 | − memcpy(mem, reg, size); | |
| 828 | 830 | break; |
| 829 | 831 | case 16: |
| 830 | 832 | /* stxv, stxvx, stxvl, stxvll */ |
| @@ -31,6 +31,7 @@ static u32 initial_allocation_mask __ro_after_init; · 30 unmodified lines | ||
| 31 | 31 | u64 default_amr __ro_after_init = ~0x0UL; |
| 32 | 32 | u64 default_iamr __ro_after_init = 0x5555555555555555UL; |
| 33 | 33 | u64 default_uamor __ro_after_init; |
| 34 | +EXPORT_SYMBOL(default_amr); | |
| 34 | 35 | /* |
| 35 | 36 | * Key used to implement PROT_EXEC mmap. Denies READ/WRITE |
| 36 | 37 | * We pick key 2 because 0 is special key and 1 is reserved as per ISA. |
| @@ -137,7 +137,7 @@ config PA_BITS · 136 unmodified lines | ||
| 137 | 137 | |
| 138 | 138 | config PAGE_OFFSET |
| 139 | 139 | hex |
| 140 | − default 0xC0000000 if 32BIT && MAXPHYSMEM_2GB | |
| 140 | + default 0xC0000000 if 32BIT && MAXPHYSMEM_1GB | |
| 141 | 141 | default 0x80000000 if 64BIT && !MMU |
| 142 | 142 | default 0xffffffff80000000 if 64BIT && MAXPHYSMEM_2GB |
| 143 | 143 | default 0xffffffe000000000 if 64BIT && MAXPHYSMEM_128GB |
| @@ -247,11 +247,15 @@ config MODULE_SECTIONS · 103 unmodified lines | ||
| 247 | 247 | |
| 248 | 248 | choice |
| 249 | 249 | prompt "Maximum Physical Memory" |
| 250 | − default MAXPHYSMEM_2GB if 32BIT | |
| 250 | + default MAXPHYSMEM_1GB if 32BIT | |
| 251 | 251 | default MAXPHYSMEM_2GB if 64BIT && CMODEL_MEDLOW |
| 252 | 252 | default MAXPHYSMEM_128GB if 64BIT && CMODEL_MEDANY |
| 253 | 253 | |
| 254 | + config MAXPHYSMEM_1GB | |
| 255 | + depends on 32BIT | |
| 256 | + bool "1GiB" | |
| 254 | 257 | config MAXPHYSMEM_2GB |
| 258 | + depends on 64BIT && CMODEL_MEDLOW | |
| 255 | 259 | bool "2GiB" |
| 256 | 260 | config MAXPHYSMEM_128GB |
| 257 | 261 | depends on 64BIT && CMODEL_MEDANY |
| @@ -88,6 +88,7 @@ · 87 unmodified lines | ||
| 88 | 88 | phy-mode = "gmii"; |
| 89 | 89 | phy-handle = <&phy0>; |
| 90 | 90 | phy0: ethernet-phy@0 { |
| 91 | + compatible = "ethernet-phy-id0007.0771"; | |
| 91 | 92 | reg = <0>; |
| 92 | 93 | }; |
| 93 | 94 | }; |
| @@ -64,6 +64,8 @@ CONFIG_HW_RANDOM=y · 63 unmodified lines | ||
| 64 | 64 | CONFIG_HW_RANDOM_VIRTIO=y |
| 65 | 65 | CONFIG_SPI=y |
| 66 | 66 | CONFIG_SPI_SIFIVE=y |
| 67 | +CONFIG_GPIOLIB=y | |
| 68 | +CONFIG_GPIO_SIFIVE=y | |
| 67 | 69 | # CONFIG_PTP_1588_CLOCK is not set |
| 68 | 70 | CONFIG_POWER_RESET=y |
| 69 | 71 | CONFIG_DRM=y |
| @@ -135,7 +135,10 @@ extern phys_addr_t __phys_addr_symbol(unsigned long x); · 134 unmodified lines | ||
| 135 | 135 | |
| 136 | 136 | #endif /* __ASSEMBLY__ */ |
| 137 | 137 | |
| 138 | −#define virt_addr_valid(vaddr) (pfn_valid(virt_to_pfn(vaddr))) | |
| 138 | +#define virt_addr_valid(vaddr) ({ \ | |
| 139 | + unsigned long _addr = (unsigned long)vaddr; \ | |
| 140 | + (unsigned long)(_addr) >= PAGE_OFFSET && pfn_valid(virt_to_pfn(_addr)); \ | |
| 141 | +}) | |
| 139 | 142 | |
| 140 | 143 | #define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_NON_EXEC |
| 141 | 144 | |
| @@ -99,7 +99,6 @@ · 98 unmodified lines | ||
| 99 | 99 | | _PAGE_DIRTY) |
| 100 | 100 | |
| 101 | 101 | #define PAGE_KERNEL __pgprot(_PAGE_KERNEL) |
| 102 | −#define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL | _PAGE_EXEC) | |
| 103 | 102 | #define PAGE_KERNEL_READ __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE) |
| 104 | 103 | #define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL | _PAGE_EXEC) |
| 105 | 104 | #define PAGE_KERNEL_READ_EXEC __pgprot((_PAGE_KERNEL & ~_PAGE_WRITE) \ |
| @@ -32,14 +32,14 @@ bool kernel_page_present(struct page *page); · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | #endif /* __ASSEMBLY__ */ |
| 34 | 34 | |
| 35 | −#ifdef CONFIG_ARCH_HAS_STRICT_KERNEL_RWX | |
| 35 | +#ifdef CONFIG_STRICT_KERNEL_RWX | |
| 36 | 36 | #ifdef CONFIG_64BIT |
| 37 | 37 | #define SECTION_ALIGN (1 << 21) |
| 38 | 38 | #else |
| 39 | 39 | #define SECTION_ALIGN (1 << 22) |
| 40 | 40 | #endif |
| 41 | −#else /* !CONFIG_ARCH_HAS_STRICT_KERNEL_RWX */ | |
| 41 | +#else /* !CONFIG_STRICT_KERNEL_RWX */ | |
| 42 | 42 | #define SECTION_ALIGN L1_CACHE_BYTES |
| 43 | −#endif /* CONFIG_ARCH_HAS_STRICT_KERNEL_RWX */ | |
| 43 | +#endif /* CONFIG_STRICT_KERNEL_RWX */ | |
| 44 | 44 | |
| 45 | 45 | #endif /* _ASM_RISCV_SET_MEMORY_H */ |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | |
| 11 | 11 | #include <linux/types.h> |
| 12 | 12 | |
| 13 | −#ifndef GENERIC_TIME_VSYSCALL | |
| 13 | +#ifndef CONFIG_GENERIC_TIME_VSYSCALL | |
| 14 | 14 | struct vdso_data { |
| 15 | 15 | }; |
| 16 | 16 | #endif |
| @@ -26,7 +26,16 @@ cache_get_priv_group(struct cacheinfo *this_leaf) · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | static struct cacheinfo *get_cacheinfo(u32 level, enum cache_type type) |
| 28 | 28 | { |
| 29 | − struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(smp_processor_id()); | |
| 29 | + /* | |
| 30 | + * Using raw_smp_processor_id() elides a preemptability check, but this | |
| 31 | + * is really indicative of a larger problem: the cacheinfo UABI assumes | |
| 32 | + * that cores have a homonogenous view of the cache hierarchy. That | |
| 33 | + * happens to be the case for the current set of RISC-V systems, but | |
| 34 | + * likely won't be true in general. Since there's no way to provide | |
| 35 | + * correct information for these systems via the current UABI we're | |
| 36 | + * just eliding the check for now. | |
| 37 | + */ | |
| 38 | + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(raw_smp_processor_id()); | |
| 30 | 39 | struct cacheinfo *this_leaf; |
| 31 | 40 | int index; |
| 32 | 41 | |
| @@ -124,15 +124,15 @@ skip_context_tracking: · 123 unmodified lines | ||
| 124 | 124 | REG_L a1, (a1) |
| 125 | 125 | jr a1 |
| 126 | 126 | 1: |
| 127 | −#ifdef CONFIG_TRACE_IRQFLAGS | |
| 128 | − call trace_hardirqs_on | |
| 129 | −#endif | |
| 130 | 127 | /* |
| 131 | 128 | * Exceptions run with interrupts enabled or disabled depending on the |
| 132 | 129 | * state of SR_PIE in m/sstatus. |
| 133 | 130 | */ |
| 134 | 131 | andi t0, s1, SR_PIE |
| 135 | 132 | beqz t0, 1f |
| 133 | +#ifdef CONFIG_TRACE_IRQFLAGS | |
| 134 | + call trace_hardirqs_on | |
| 135 | +#endif | |
| 136 | 136 | csrs CSR_STATUS, SR_IE |
| 137 | 137 | |
| 138 | 138 | 1: |
| @@ -155,6 +155,15 @@ skip_context_tracking: · 16 unmodified lines | ||
| 155 | 155 | tail do_trap_unknown |
| 156 | 156 | |
| 157 | 157 | handle_syscall: |
| 158 | +#ifdef CONFIG_RISCV_M_MODE | |
| 159 | + /* | |
| 160 | + * When running is M-Mode (no MMU config), MPIE does not get set. | |
| 161 | + * As a result, we need to force enable interrupts here because | |
| 162 | + * handle_exception did not do set SR_IE as it always sees SR_PIE | |
| 163 | + * being cleared. | |
| 164 | + */ | |
| 165 | + csrs CSR_STATUS, SR_IE | |
| 166 | +#endif | |
| 158 | 167 | #if defined(CONFIG_TRACE_IRQFLAGS) || defined(CONFIG_CONTEXT_TRACKING) |
| 159 | 168 | /* Recover a0 - a7 for system calls */ |
| 160 | 169 | REG_L a0, PT_A0(sp) |
| @@ -186,14 +195,7 @@ check_syscall_nr: · 25 unmodified lines | ||
| 186 | 195 | * Syscall number held in a7. |
| 187 | 196 | * If syscall number is above allowed value, redirect to ni_syscall. |
| 188 | 197 | */ |
| 189 | − bge a7, t0, 1f | |
| 190 | − /* | |
| 191 | − * Check if syscall is rejected by tracer, i.e., a7 == -1. | |
| 192 | − * If yes, we pretend it was executed. | |
| 193 | − */ | |
| 194 | − li t1, -1 | |
| 195 | − beq a7, t1, ret_from_syscall_rejected | |
| 196 | − blt a7, t1, 1f | |
| 198 | + bgeu a7, t0, 1f | |
| 197 | 199 | /* Call syscall */ |
| 198 | 200 | la s0, sys_call_table |
| 199 | 201 | slli t0, a7, RISCV_LGPTR |
| @@ -127,7 +127,9 @@ static void __init init_resources(void) · 126 unmodified lines | ||
| 127 | 127 | { |
| 128 | 128 | struct memblock_region *region = NULL; |
| 129 | 129 | struct resource *res = NULL; |
| 130 | − int ret = 0; | |
| 130 | + struct resource *mem_res = NULL; | |
| 131 | + size_t mem_res_sz = 0; | |
| 132 | + int ret = 0, i = 0; | |
| 131 | 133 | |
| 132 | 134 | code_res.start = __pa_symbol(_text); |
| 133 | 135 | code_res.end = __pa_symbol(_etext) - 1; |
| @@ -145,16 +147,17 @@ static void __init init_resources(void) · 11 unmodified lines | ||
| 145 | 147 | bss_res.end = __pa_symbol(__bss_stop) - 1; |
| 146 | 148 | bss_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; |
| 147 | 149 | |
| 150 | + mem_res_sz = (memblock.memory.cnt + memblock.reserved.cnt) * sizeof(*mem_res); | |
| 151 | + mem_res = memblock_alloc(mem_res_sz, SMP_CACHE_BYTES); | |
| 152 | + if (!mem_res) | |
| 153 | + panic("%s: Failed to allocate %zu bytes\n", __func__, mem_res_sz); | |
| 148 | 154 | /* |
| 149 | 155 | * Start by adding the reserved regions, if they overlap |
| 150 | 156 | * with /memory regions, insert_resource later on will take |
| 151 | 157 | * care of it. |
| 152 | 158 | */ |
| 153 | 159 | for_each_reserved_mem_region(region) { |
| 154 | − res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES); | |
| 155 | − if (!res) | |
| 156 | − panic("%s: Failed to allocate %zu bytes\n", __func__, | |
| 157 | − sizeof(struct resource)); | |
| 160 | + res = &mem_res[i++]; | |
| 158 | 161 | |
| 159 | 162 | res->name = "Reserved"; |
| 160 | 163 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; |
| @@ -171,8 +174,10 @@ static void __init init_resources(void) · 10 unmodified lines | ||
| 171 | 174 | * Ignore any other reserved regions within |
| 172 | 175 | * system memory. |
| 173 | 176 | */ |
| 174 | − if (memblock_is_memory(res->start)) | |
| 177 | + if (memblock_is_memory(res->start)) { | |
| 178 | + memblock_free((phys_addr_t) res, sizeof(struct resource)); | |
| 175 | 179 | continue; |
| 180 | + } | |
| 176 | 181 | |
| 177 | 182 | ret = add_resource(&iomem_resource, res); |
| 178 | 183 | if (ret < 0) |
| @@ -181,10 +186,7 @@ static void __init init_resources(void) · 2 unmodified lines | ||
| 181 | 186 | |
| 182 | 187 | /* Add /memory regions to the resource tree */ |
| 183 | 188 | for_each_mem_region(region) { |
| 184 | − res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES); | |
| 185 | − if (!res) | |
| 186 | − panic("%s: Failed to allocate %zu bytes\n", __func__, | |
| 187 | − sizeof(struct resource)); | |
| 189 | + res = &mem_res[i++]; | |
| 188 | 190 | |
| 189 | 191 | if (unlikely(memblock_is_nomap(region))) { |
| 190 | 192 | res->name = "Reserved"; |
| @@ -205,9 +207,9 @@ static void __init init_resources(void) · 14 unmodified lines | ||
| 205 | 207 | return; |
| 206 | 208 | |
| 207 | 209 | error: |
| 208 | − memblock_free((phys_addr_t) res, sizeof(struct resource)); | |
| 209 | 210 | /* Better an empty resource tree than an inconsistent one */ |
| 210 | 211 | release_child_resources(&iomem_resource); |
| 212 | + memblock_free((phys_addr_t) mem_res, mem_res_sz); | |
| 211 | 213 | } |
| 212 | 214 | |
| 213 | 215 | |
| @@ -291,6 +293,8 @@ void free_initmem(void) · 77 unmodified lines | ||
| 291 | 293 | unsigned long init_begin = (unsigned long)__init_begin; |
| 292 | 294 | unsigned long init_end = (unsigned long)__init_end; |
| 293 | 295 | |
| 294 | − set_memory_rw_nx(init_begin, (init_end - init_begin) >> PAGE_SHIFT); | |
| 296 | + if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) | |
| 297 | + set_memory_rw_nx(init_begin, (init_end - init_begin) >> PAGE_SHIFT); | |
| 298 | + | |
| 295 | 299 | free_initmem_default(POISON_FREE_INITMEM); |
| 296 | 300 | } |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | #include <asm/stacktrace.h> |
| 16 | 16 | |
| 17 | −register unsigned long sp_in_global __asm__("sp"); | |
| 17 | +register const unsigned long sp_in_global __asm__("sp"); | |
| 18 | 18 | |
| 19 | 19 | #ifdef CONFIG_FRAME_POINTER |
| 20 | 20 | |
| @@ -28,9 +28,8 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, · 7 unmodified lines | ||
| 28 | 28 | sp = user_stack_pointer(regs); |
| 29 | 29 | pc = instruction_pointer(regs); |
| 30 | 30 | } else if (task == NULL || task == current) { |
| 31 | − const register unsigned long current_sp = sp_in_global; | |
| 32 | 31 | fp = (unsigned long)__builtin_frame_address(0); |
| 33 | − sp = current_sp; | |
| 32 | + sp = sp_in_global; | |
| 34 | 33 | pc = (unsigned long)walk_stackframe; |
| 35 | 34 | } else { |
| 36 | 35 | /* task blocked in __switch_to */ |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Copyright (C) 2017 SiFive |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | +#include <linux/of_clk.h> | |
| 7 | 8 | #include <linux/clocksource.h> |
| 8 | 9 | #include <linux/delay.h> |
| 9 | 10 | #include <asm/sbi.h> |
| @@ -24,6 +25,8 @@ void __init time_init(void) · 14 unmodified lines | ||
| 24 | 25 | riscv_timebase = prop; |
| 25 | 26 | |
| 26 | 27 | lpj_fine = riscv_timebase / HZ; |
| 28 | + | |
| 29 | + of_clk_init(NULL); | |
| 27 | 30 | timer_probe(); |
| 28 | 31 | } |
| 29 | 32 | |
| @@ -12,7 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/binfmts.h> |
| 13 | 13 | #include <linux/err.h> |
| 14 | 14 | #include <asm/page.h> |
| 15 | −#ifdef GENERIC_TIME_VSYSCALL | |
| 15 | +#ifdef CONFIG_GENERIC_TIME_VSYSCALL | |
| 16 | 16 | #include <vdso/datapage.h> |
| 17 | 17 | #else |
| 18 | 18 | #include <asm/vdso.h> |
| @@ -157,9 +157,10 @@ disable: · 156 unmodified lines | ||
| 157 | 157 | void __init setup_bootmem(void) |
| 158 | 158 | { |
| 159 | 159 | phys_addr_t mem_start = 0; |
| 160 | − phys_addr_t start, end = 0; | |
| 160 | + phys_addr_t start, dram_end, end = 0; | |
| 161 | 161 | phys_addr_t vmlinux_end = __pa_symbol(&_end); |
| 162 | 162 | phys_addr_t vmlinux_start = __pa_symbol(&_start); |
| 163 | + phys_addr_t max_mapped_addr = __pa(~(ulong)0); | |
| 163 | 164 | u64 i; |
| 164 | 165 | |
| 165 | 166 | /* Find the memory region containing the kernel */ |
| @@ -181,10 +182,21 @@ void __init setup_bootmem(void) · 15 unmodified lines | ||
| 181 | 182 | /* Reserve from the start of the kernel to the end of the kernel */ |
| 182 | 183 | memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); |
| 183 | 184 | |
| 184 | − max_pfn = PFN_DOWN(memblock_end_of_DRAM()); | |
| 185 | + dram_end = memblock_end_of_DRAM(); | |
| 186 | + | |
| 187 | + /* | |
| 188 | + * memblock allocator is not aware of the fact that last 4K bytes of | |
| 189 | + * the addressable memory can not be mapped because of IS_ERR_VALUE | |
| 190 | + * macro. Make sure that last 4k bytes are not usable by memblock | |
| 191 | + * if end of dram is equal to maximum addressable memory. | |
| 192 | + */ | |
| 193 | + if (max_mapped_addr == (dram_end - 1)) | |
| 194 | + memblock_set_current_limit(max_mapped_addr - 4096); | |
| 195 | + | |
| 196 | + max_pfn = PFN_DOWN(dram_end); | |
| 185 | 197 | max_low_pfn = max_pfn; |
| 186 | 198 | dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn)); |
| 187 | − set_max_mapnr(max_low_pfn); | |
| 199 | + set_max_mapnr(max_low_pfn - ARCH_PFN_OFFSET); | |
| 188 | 200 | |
| 189 | 201 | #ifdef CONFIG_BLK_DEV_INITRD |
| 190 | 202 | setup_initrd(); |
| @@ -93,8 +93,8 @@ void __init kasan_init(void) · 92 unmodified lines | ||
| 93 | 93 | VMALLOC_END)); |
| 94 | 94 | |
| 95 | 95 | for_each_mem_range(i, &_start, &_end) { |
| 96 | − void *start = (void *)_start; | |
| 97 | − void *end = (void *)_end; | |
| 96 | + void *start = (void *)__va(_start); | |
| 97 | + void *end = (void *)__va(_end); | |
| 98 | 98 | |
| 99 | 99 | if (start >= end) |
| 100 | 100 | break; |
| @@ -35,7 +35,7 @@ void uv_query_info(void) · 34 unmodified lines | ||
| 35 | 35 | uv_info.guest_cpu_stor_len = uvcb.cpu_stor_len; |
| 36 | 36 | uv_info.max_sec_stor_addr = ALIGN(uvcb.max_guest_stor_addr, PAGE_SIZE); |
| 37 | 37 | uv_info.max_num_sec_conf = uvcb.max_num_sec_conf; |
| 38 | − uv_info.max_guest_cpus = uvcb.max_guest_cpus; | |
| 38 | + uv_info.max_guest_cpu_id = uvcb.max_guest_cpu_id; | |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | 41 | #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST |
| @@ -96,7 +96,7 @@ struct uv_cb_qui { · 95 unmodified lines | ||
| 96 | 96 | u32 max_num_sec_conf; |
| 97 | 97 | u64 max_guest_stor_addr; |
| 98 | 98 | u8 reserved88[158 - 136]; |
| 99 | − u16 max_guest_cpus; | |
| 99 | + u16 max_guest_cpu_id; | |
| 100 | 100 | u8 reserveda0[200 - 160]; |
| 101 | 101 | } __packed __aligned(8); |
| 102 | 102 | |
| @@ -273,7 +273,7 @@ struct uv_info { · 170 unmodified lines | ||
| 273 | 273 | unsigned long guest_cpu_stor_len; |
| 274 | 274 | unsigned long max_sec_stor_addr; |
| 275 | 275 | unsigned int max_num_sec_conf; |
| 276 | − unsigned short max_guest_cpus; | |
| 276 | + unsigned short max_guest_cpu_id; | |
| 277 | 277 | }; |
| 278 | 278 | |
| 279 | 279 | extern struct uv_info uv_info; |
| @@ -368,7 +368,7 @@ static ssize_t uv_query_max_guest_cpus(struct kobject *kobj, · 367 unmodified lines | ||
| 368 | 368 | struct kobj_attribute *attr, char *page) |
| 369 | 369 | { |
| 370 | 370 | return scnprintf(page, PAGE_SIZE, "%d\n", |
| 371 | − uv_info.max_guest_cpus); | |
| 371 | + uv_info.max_guest_cpu_id + 1); | |
| 372 | 372 | } |
| 373 | 373 | |
| 374 | 374 | static struct kobj_attribute uv_query_max_guest_cpus_attr = |
| @@ -29,7 +29,6 @@ config SUPERH · 28 unmodified lines | ||
| 29 | 29 | select HAVE_ARCH_KGDB |
| 30 | 30 | select HAVE_ARCH_SECCOMP_FILTER |
| 31 | 31 | select HAVE_ARCH_TRACEHOOK |
| 32 | − select HAVE_COPY_THREAD_TLS | |
| 33 | 32 | select HAVE_DEBUG_BUGVERBOSE |
| 34 | 33 | select HAVE_DEBUG_KMEMLEAK |
| 35 | 34 | select HAVE_DYNAMIC_FTRACE |
| @@ -11,7 +11,6 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/sched.h> |
| 12 | 12 | #include <linux/time.h> |
| 13 | 13 | #include <linux/bcd.h> |
| 14 | −#include <linux/rtc.h> | |
| 15 | 14 | #include <linux/spinlock.h> |
| 16 | 15 | #include <linux/io.h> |
| 17 | 16 | #include <linux/rtc.h> |
| @@ -27,13 +27,12 @@ CONFIG_NETFILTER=y · 26 unmodified lines | ||
| 27 | 27 | CONFIG_ATALK=m |
| 28 | 28 | CONFIG_BLK_DEV_LOOP=y |
| 29 | 29 | CONFIG_BLK_DEV_RAM=y |
| 30 | −CONFIG_IDE=y | |
| 31 | −CONFIG_BLK_DEV_IDECD=y | |
| 32 | −CONFIG_BLK_DEV_OFFBOARD=y | |
| 33 | −CONFIG_BLK_DEV_GENERIC=y | |
| 34 | −CONFIG_BLK_DEV_AEC62XX=y | |
| 30 | +CONFIG_ATA=y | |
| 31 | +CONFIG_ATA_GENERIC=y | |
| 32 | +CONFIG_PATA_ATP867X=y | |
| 35 | 33 | CONFIG_SCSI=y |
| 36 | 34 | CONFIG_BLK_DEV_SD=y |
| 35 | +CONFIG_BLK_DEV_SR=y | |
| 37 | 36 | CONFIG_SCSI_MULTI_LUN=y |
| 38 | 37 | CONFIG_MD=y |
| 39 | 38 | CONFIG_BLK_DEV_MD=m |
| @@ -20,8 +20,6 @@ CONFIG_IP_PNP=y · 19 unmodified lines | ||
| 20 | 20 | # CONFIG_IPV6 is not set |
| 21 | 21 | # CONFIG_FW_LOADER is not set |
| 22 | 22 | CONFIG_BLK_DEV_RAM=y |
| 23 | −CONFIG_IDE=y | |
| 24 | −CONFIG_BLK_DEV_IDECD=y | |
| 25 | 23 | CONFIG_NETDEVICES=y |
| 26 | 24 | CONFIG_NET_ETHERNET=y |
| 27 | 25 | CONFIG_SMC91X=y |
| @@ -44,16 +44,14 @@ CONFIG_NET_SCHED=y · 43 unmodified lines | ||
| 44 | 44 | CONFIG_PARPORT=y |
| 45 | 45 | CONFIG_BLK_DEV_LOOP=y |
| 46 | 46 | CONFIG_BLK_DEV_RAM=y |
| 47 | −CONFIG_IDE=y | |
| 48 | −CONFIG_BLK_DEV_IDECD=y | |
| 49 | −CONFIG_BLK_DEV_PLATFORM=y | |
| 50 | −CONFIG_BLK_DEV_GENERIC=y | |
| 51 | 47 | CONFIG_BLK_DEV_SD=y |
| 52 | 48 | CONFIG_BLK_DEV_SR=y |
| 53 | 49 | CONFIG_CHR_DEV_SG=y |
| 54 | 50 | CONFIG_SCSI_SPI_ATTRS=y |
| 55 | 51 | CONFIG_SCSI_FC_ATTRS=y |
| 56 | 52 | CONFIG_ATA=y |
| 53 | +CONFIG_ATA_GENERIC=y | |
| 54 | +CONFIG_PATA_PLATFORM=y | |
| 57 | 55 | CONFIG_MD=y |
| 58 | 56 | CONFIG_BLK_DEV_DM=y |
| 59 | 57 | CONFIG_NETDEVICES=y |
| @@ -116,9 +116,6 @@ CONFIG_MTD_UBI_GLUEBI=m · 115 unmodified lines | ||
| 116 | 116 | CONFIG_BLK_DEV_LOOP=y |
| 117 | 117 | CONFIG_BLK_DEV_CRYPTOLOOP=y |
| 118 | 118 | CONFIG_BLK_DEV_RAM=y |
| 119 | −CONFIG_IDE=y | |
| 120 | −CONFIG_BLK_DEV_IDECD=y | |
| 121 | −CONFIG_BLK_DEV_PLATFORM=y | |
| 122 | 119 | CONFIG_BLK_DEV_SD=y |
| 123 | 120 | CONFIG_BLK_DEV_SR=y |
| 124 | 121 | CONFIG_SCSI_MULTI_LUN=y |
| @@ -29,7 +29,6 @@ CONFIG_MTD_BLOCK=y · 28 unmodified lines | ||
| 29 | 29 | CONFIG_MTD_CFI=y |
| 30 | 30 | CONFIG_MTD_CFI_AMDSTD=y |
| 31 | 31 | CONFIG_MTD_ROM=y |
| 32 | −CONFIG_IDE=y | |
| 33 | 32 | CONFIG_SCSI=y |
| 34 | 33 | CONFIG_NETDEVICES=y |
| 35 | 34 | CONFIG_NET_ETHERNET=y |
| @@ -39,9 +39,6 @@ CONFIG_IP_PNP_RARP=y · 38 unmodified lines | ||
| 39 | 39 | CONFIG_BLK_DEV_LOOP=y |
| 40 | 40 | CONFIG_BLK_DEV_NBD=y |
| 41 | 41 | CONFIG_BLK_DEV_RAM=y |
| 42 | −CONFIG_IDE=y | |
| 43 | −CONFIG_BLK_DEV_IDECD=m | |
| 44 | −CONFIG_BLK_DEV_IDETAPE=m | |
| 45 | 42 | CONFIG_SCSI=m |
| 46 | 43 | CONFIG_BLK_DEV_SD=m |
| 47 | 44 | CONFIG_BLK_DEV_SR=m |
| @@ -63,8 +63,7 @@ config PVR2_DMA · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | config G2_DMA |
| 65 | 65 | tristate "G2 Bus DMA support" |
| 66 | − depends on SH_DREAMCAST | |
| 67 | − select SH_DMA_API | |
| 66 | + depends on SH_DREAMCAST && SH_DMA_API | |
| 68 | 67 | help |
| 69 | 68 | This enables support for the DMA controller for the Dreamcast's |
| 70 | 69 | G2 bus. Drivers that want this will generally enable this on |
| @@ -16,7 +16,6 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <cpu/gpio.h> |
| 17 | 17 | #endif |
| 18 | 18 | |
| 19 | −#define ARCH_NR_GPIOS 512 | |
| 20 | 19 | #include <asm-generic/gpio.h> |
| 21 | 20 | |
| 22 | 21 | #ifdef CONFIG_GPIOLIB |
| @@ -14,7 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <cpu/mmu_context.h> |
| 15 | 15 | #include <asm/page.h> |
| 16 | 16 | #include <asm/cache.h> |
| 17 | −#include <asm/thread_info.h> | |
| 18 | 17 | |
| 19 | 18 | ! NOTE: |
| 20 | 19 | ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address |
| @@ -105,7 +105,7 @@ config VSYSCALL · 104 unmodified lines | ||
| 105 | 105 | (the default value) say Y. |
| 106 | 106 | |
| 107 | 107 | config NUMA |
| 108 | − bool "Non Uniform Memory Access (NUMA) Support" | |
| 108 | + bool "Non-Uniform Memory Access (NUMA) Support" | |
| 109 | 109 | depends on MMU && SYS_SUPPORTS_NUMA |
| 110 | 110 | select ARCH_WANT_NUMA_VARIABLE_LOCALITY |
| 111 | 111 | default n |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <asm/processor.h> |
| 27 | 27 | #include <asm/mmu_context.h> |
| 28 | 28 | |
| 29 | −static int asids_seq_show(struct seq_file *file, void *iter) | |
| 29 | +static int asids_debugfs_show(struct seq_file *file, void *iter) | |
| 30 | 30 | { |
| 31 | 31 | struct task_struct *p; |
| 32 | 32 | |
| @@ -48,18 +48,7 @@ static int asids_seq_show(struct seq_file *file, void *iter) · 15 unmodified lines | ||
| 48 | 48 | return 0; |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | −static int asids_debugfs_open(struct inode *inode, struct file *file) | |
| 52 | −{ | |
| 53 | − return single_open(file, asids_seq_show, inode->i_private); | |
| 54 | −} | |
| 55 | − | |
| 56 | −static const struct file_operations asids_debugfs_fops = { | |
| 57 | − .owner = THIS_MODULE, | |
| 58 | − .open = asids_debugfs_open, | |
| 59 | − .read = seq_read, | |
| 60 | − .llseek = seq_lseek, | |
| 61 | − .release = single_release, | |
| 62 | −}; | |
| 51 | +DEFINE_SHOW_ATTRIBUTE(asids_debugfs); | |
| 63 | 52 | |
| 64 | 53 | static int __init asids_debugfs_init(void) |
| 65 | 54 | { |
| @@ -22,7 +22,7 @@ enum cache_type { · 21 unmodified lines | ||
| 22 | 22 | CACHE_TYPE_UNIFIED, |
| 23 | 23 | }; |
| 24 | 24 | |
| 25 | −static int cache_seq_show(struct seq_file *file, void *iter) | |
| 25 | +static int cache_debugfs_show(struct seq_file *file, void *iter) | |
| 26 | 26 | { |
| 27 | 27 | unsigned int cache_type = (unsigned int)file->private; |
| 28 | 28 | struct cache_info *cache; |
| @@ -94,18 +94,7 @@ static int cache_seq_show(struct seq_file *file, void *iter) · 65 unmodified lines | ||
| 94 | 94 | return 0; |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | −static int cache_debugfs_open(struct inode *inode, struct file *file) | |
| 98 | −{ | |
| 99 | − return single_open(file, cache_seq_show, inode->i_private); | |
| 100 | −} | |
| 101 | − | |
| 102 | −static const struct file_operations cache_debugfs_fops = { | |
| 103 | − .owner = THIS_MODULE, | |
| 104 | − .open = cache_debugfs_open, | |
| 105 | − .read = seq_read, | |
| 106 | − .llseek = seq_lseek, | |
| 107 | − .release = single_release, | |
| 108 | −}; | |
| 97 | +DEFINE_SHOW_ATTRIBUTE(cache_debugfs); | |
| 109 | 98 | |
| 110 | 99 | static int __init cache_debugfs_init(void) |
| 111 | 100 | { |
| @@ -812,7 +812,7 @@ bool __in_29bit_mode(void) · 811 unmodified lines | ||
| 812 | 812 | return (__raw_readl(PMB_PASCR) & PASCR_SE) == 0; |
| 813 | 813 | } |
| 814 | 814 | |
| 815 | −static int pmb_seq_show(struct seq_file *file, void *iter) | |
| 815 | +static int pmb_debugfs_show(struct seq_file *file, void *iter) | |
| 816 | 816 | { |
| 817 | 817 | int i; |
| 818 | 818 | |
| @@ -846,18 +846,7 @@ static int pmb_seq_show(struct seq_file *file, void *iter) · 27 unmodified lines | ||
| 846 | 846 | return 0; |
| 847 | 847 | } |
| 848 | 848 | |
| 849 | −static int pmb_debugfs_open(struct inode *inode, struct file *file) | |
| 850 | −{ | |
| 851 | − return single_open(file, pmb_seq_show, NULL); | |
| 852 | −} | |
| 853 | − | |
| 854 | −static const struct file_operations pmb_debugfs_fops = { | |
| 855 | − .owner = THIS_MODULE, | |
| 856 | − .open = pmb_debugfs_open, | |
| 857 | − .read = seq_read, | |
| 858 | − .llseek = seq_lseek, | |
| 859 | − .release = single_release, | |
| 860 | −}; | |
| 849 | +DEFINE_SHOW_ATTRIBUTE(pmb_debugfs); | |
| 861 | 850 | |
| 862 | 851 | static int __init pmb_debugfs_init(void) |
| 863 | 852 | { |
| @@ -1,6 +1,4 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | −# User exported sparc header files | |
| 3 | − | |
| 4 | 2 | generated-y += syscall_table_32.h |
| 5 | 3 | generated-y += syscall_table_64.h |
| 6 | 4 | generated-y += syscall_table_c32.h |
| @@ -50,10 +50,11 @@ extern pte_t *pkmap_page_table; · 49 unmodified lines | ||
| 50 | 50 | |
| 51 | 51 | #define flush_cache_kmaps() flush_cache_all() |
| 52 | 52 | |
| 53 | −/* FIXME: Use __flush_tlb_one(vaddr) instead of flush_cache_all() -- Anton */ | |
| 54 | −#define arch_kmap_local_post_map(vaddr, pteval) flush_cache_all() | |
| 55 | −#define arch_kmap_local_post_unmap(vaddr) flush_cache_all() | |
| 56 | − | |
| 53 | +/* FIXME: Use __flush_*_one(vaddr) instead of flush_*_all() -- Anton */ | |
| 54 | +#define arch_kmap_local_pre_map(vaddr, pteval) flush_cache_all() | |
| 55 | +#define arch_kmap_local_pre_unmap(vaddr) flush_cache_all() | |
| 56 | +#define arch_kmap_local_post_map(vaddr, pteval) flush_tlb_all() | |
| 57 | +#define arch_kmap_local_post_unmap(vaddr) flush_tlb_all() | |
| 57 | 58 | |
| 58 | 59 | #endif /* __KERNEL__ */ |
| 59 | 60 | |
| @@ -15,7 +15,6 @@ config UML · 14 unmodified lines | ||
| 15 | 15 | select HAVE_DEBUG_KMEMLEAK |
| 16 | 16 | select HAVE_DEBUG_BUGVERBOSE |
| 17 | 17 | select NO_DMA |
| 18 | − select ARCH_HAS_SET_MEMORY | |
| 19 | 18 | select GENERIC_IRQ_SHOW |
| 20 | 19 | select GENERIC_CPU_DEVICES |
| 21 | 20 | select HAVE_GCC_PLUGINS |
| @@ -375,11 +375,11 @@ break_loop: · 374 unmodified lines | ||
| 375 | 375 | file = NULL; |
| 376 | 376 | |
| 377 | 377 | backing_file = strsep(&str, ",:"); |
| 378 | − if (*backing_file == '\0') | |
| 378 | + if (backing_file && *backing_file == '\0') | |
| 379 | 379 | backing_file = NULL; |
| 380 | 380 | |
| 381 | 381 | serial = strsep(&str, ",:"); |
| 382 | − if (*serial == '\0') | |
| 382 | + if (serial && *serial == '\0') | |
| 383 | 383 | serial = NULL; |
| 384 | 384 | |
| 385 | 385 | if (backing_file && ubd_dev->no_cow) { |
| @@ -1241,7 +1241,7 @@ static int __init ubd_driver_init(void){ · 855 unmodified lines | ||
| 1241 | 1241 | /* Letting ubd=sync be like using ubd#s= instead of ubd#= is |
| 1242 | 1242 | * enough. So use anyway the io thread. */ |
| 1243 | 1243 | } |
| 1244 | − stack = alloc_stack(0); | |
| 1244 | + stack = alloc_stack(0, 0); | |
| 1245 | 1245 | io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), |
| 1246 | 1246 | &thread_fd); |
| 1247 | 1247 | if(io_pid < 0){ |
| @@ -1084,6 +1084,7 @@ static void virtio_uml_release_dev(struct device *d) · 1083 unmodified lines | ||
| 1084 | 1084 | } |
| 1085 | 1085 | |
| 1086 | 1086 | os_close_file(vu_dev->sock); |
| 1087 | + kfree(vu_dev); | |
| 1087 | 1088 | } |
| 1088 | 1089 | |
| 1089 | 1090 | /* Platform device */ |
| @@ -1097,7 +1098,7 @@ static int virtio_uml_probe(struct platform_device *pdev) · 7 unmodified lines | ||
| 1097 | 1098 | if (!pdata) |
| 1098 | 1099 | return -EINVAL; |
| 1099 | 1100 | |
| 1100 | − vu_dev = devm_kzalloc(&pdev->dev, sizeof(*vu_dev), GFP_KERNEL); | |
| 1101 | + vu_dev = kzalloc(sizeof(*vu_dev), GFP_KERNEL); | |
| 1101 | 1102 | if (!vu_dev) |
| 1102 | 1103 | return -ENOMEM; |
| 1103 | 1104 | |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | #define ioremap ioremap |
| 6 | 6 | static inline void __iomem *ioremap(phys_addr_t offset, size_t size) |
| 7 | 7 | { |
| 8 | − return (void __iomem *)(unsigned long)offset; | |
| 8 | + return NULL; | |
| 9 | 9 | } |
| 10 | 10 | |
| 11 | 11 | #define iounmap iounmap |
| @@ -55,15 +55,12 @@ extern unsigned long end_iomem; · 54 unmodified lines | ||
| 55 | 55 | #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) |
| 56 | 56 | #define __PAGE_KERNEL_EXEC \ |
| 57 | 57 | (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) |
| 58 | −#define __PAGE_KERNEL_RO \ | |
| 59 | − (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED) | |
| 60 | 58 | #define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) |
| 61 | 59 | #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) |
| 62 | 60 | #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) |
| 63 | 61 | #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) |
| 64 | 62 | #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) |
| 65 | 63 | #define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) |
| 66 | −#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) | |
| 67 | 64 | |
| 68 | 65 | /* |
| 69 | 66 | * The i386 can't do page protection for execute, and considers that the same |
| @@ -1 +0,0 @@ | ||
| 1 | −#include <asm-generic/set_memory.h> | |
| @@ -19,7 +19,7 @@ extern int kmalloc_ok; · 18 unmodified lines | ||
| 19 | 19 | #define UML_ROUND_UP(addr) \ |
| 20 | 20 | ((((unsigned long) addr) + PAGE_SIZE - 1) & PAGE_MASK) |
| 21 | 21 | |
| 22 | −extern unsigned long alloc_stack(int atomic); | |
| 22 | +extern unsigned long alloc_stack(int order, int atomic); | |
| 23 | 23 | extern void free_stack(unsigned long stack, int order); |
| 24 | 24 | |
| 25 | 25 | struct pt_regs; |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | #include <linux/kmsg_dump.h> |
| 3 | 3 | #include <linux/console.h> |
| 4 | +#include <linux/string.h> | |
| 4 | 5 | #include <shared/init.h> |
| 5 | 6 | #include <shared/kern.h> |
| 6 | 7 | #include <os.h> |
| @@ -16,8 +17,12 @@ static void kmsg_dumper_stdout(struct kmsg_dumper *dumper, · 9 unmodified lines | ||
| 16 | 17 | if (!console_trylock()) |
| 17 | 18 | return; |
| 18 | 19 | |
| 19 | − for_each_console(con) | |
| 20 | − break; | |
| 20 | + for_each_console(con) { | |
| 21 | + if(strcmp(con->name, "tty") == 0 && | |
| 22 | + (con->flags & (CON_ENABLED | CON_CONSDEV)) != 0) { | |
| 23 | + break; | |
| 24 | + } | |
| 25 | + } | |
| 21 | 26 | |
| 22 | 27 | console_unlock(); |
| 23 | 28 | |
| @@ -32,7 +32,6 @@ · 31 unmodified lines | ||
| 32 | 32 | #include <os.h> |
| 33 | 33 | #include <skas.h> |
| 34 | 34 | #include <linux/time-internal.h> |
| 35 | −#include <asm/set_memory.h> | |
| 36 | 35 | |
| 37 | 36 | /* |
| 38 | 37 | * This is a per-cpu array. A processor only modifies its entry and it only |
| @@ -63,18 +62,16 @@ void free_stack(unsigned long stack, int order) · 24 unmodified lines | ||
| 63 | 62 | free_pages(stack, order); |
| 64 | 63 | } |
| 65 | 64 | |
| 66 | −unsigned long alloc_stack(int atomic) | |
| 65 | +unsigned long alloc_stack(int order, int atomic) | |
| 67 | 66 | { |
| 68 | − unsigned long addr; | |
| 67 | + unsigned long page; | |
| 69 | 68 | gfp_t flags = GFP_KERNEL; |
| 70 | 69 | |
| 71 | 70 | if (atomic) |
| 72 | 71 | flags = GFP_ATOMIC; |
| 73 | − addr = __get_free_pages(flags, 1); | |
| 72 | + page = __get_free_pages(flags, order); | |
| 74 | 73 | |
| 75 | − set_memory_ro(addr, 1); | |
| 76 | − | |
| 77 | − return addr + PAGE_SIZE; | |
| 74 | + return page; | |
| 78 | 75 | } |
| 79 | 76 | |
| 80 | 77 | static inline void set_current(struct task_struct *task) |
| @@ -535,6 +535,31 @@ invalid_number: · 534 unmodified lines | ||
| 535 | 535 | |
| 536 | 536 | return 1; |
| 537 | 537 | } |
| 538 | + | |
| 539 | +static void time_travel_set_start(void) | |
| 540 | +{ | |
| 541 | + if (time_travel_start_set) | |
| 542 | + return; | |
| 543 | + | |
| 544 | + switch (time_travel_mode) { | |
| 545 | + case TT_MODE_EXTERNAL: | |
| 546 | + time_travel_start = time_travel_ext_req(UM_TIMETRAVEL_GET_TOD, -1); | |
| 547 | + /* controller gave us the *current* time, so adjust by that */ | |
| 548 | + time_travel_ext_get_time(); | |
| 549 | + time_travel_start -= time_travel_time; | |
| 550 | + break; | |
| 551 | + case TT_MODE_INFCPU: | |
| 552 | + case TT_MODE_BASIC: | |
| 553 | + if (!time_travel_start_set) | |
| 554 | + time_travel_start = os_persistent_clock_emulation(); | |
| 555 | + break; | |
| 556 | + case TT_MODE_OFF: | |
| 557 | + /* we just read the host clock with os_persistent_clock_emulation() */ | |
| 558 | + break; | |
| 559 | + } | |
| 560 | + | |
| 561 | + time_travel_start_set = true; | |
| 562 | +} | |
| 538 | 563 | #else /* CONFIG_UML_TIME_TRAVEL_SUPPORT */ |
| 539 | 564 | #define time_travel_start_set 0 |
| 540 | 565 | #define time_travel_start 0 |
| @@ -553,6 +578,10 @@ static void time_travel_set_interval(unsigned long long interval) · 12 unmodified lines | ||
| 553 | 578 | { |
| 554 | 579 | } |
| 555 | 580 | |
| 581 | +static inline void time_travel_set_start(void) | |
| 582 | +{ | |
| 583 | +} | |
| 584 | + | |
| 556 | 585 | /* fail link if this actually gets used */ |
| 557 | 586 | extern u64 time_travel_ext_req(u32 op, u64 time); |
| 558 | 587 | |
| @@ -731,6 +760,8 @@ void read_persistent_clock64(struct timespec64 *ts) · 172 unmodified lines | ||
| 731 | 760 | { |
| 732 | 761 | long long nsecs; |
| 733 | 762 | |
| 763 | + time_travel_set_start(); | |
| 764 | + | |
| 734 | 765 | if (time_travel_mode != TT_MODE_OFF) |
| 735 | 766 | nsecs = time_travel_start + time_travel_time; |
| 736 | 767 | else |
| @@ -742,25 +773,6 @@ void read_persistent_clock64(struct timespec64 *ts) · 5 unmodified lines | ||
| 742 | 773 | |
| 743 | 774 | void __init time_init(void) |
| 744 | 775 | { |
| 745 | −#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT | |
| 746 | − switch (time_travel_mode) { | |
| 747 | − case TT_MODE_EXTERNAL: | |
| 748 | − time_travel_start = time_travel_ext_req(UM_TIMETRAVEL_GET_TOD, -1); | |
| 749 | − /* controller gave us the *current* time, so adjust by that */ | |
| 750 | − time_travel_ext_get_time(); | |
| 751 | − time_travel_start -= time_travel_time; | |
| 752 | − break; | |
| 753 | − case TT_MODE_INFCPU: | |
| 754 | − case TT_MODE_BASIC: | |
| 755 | − if (!time_travel_start_set) | |
| 756 | − time_travel_start = os_persistent_clock_emulation(); | |
| 757 | − break; | |
| 758 | − case TT_MODE_OFF: | |
| 759 | − /* we just read the host clock with os_persistent_clock_emulation() */ | |
| 760 | − break; | |
| 761 | − } | |
| 762 | −#endif | |
| 763 | − | |
| 764 | 776 | timer_set_signal_handler(); |
| 765 | 777 | late_time_init = um_timer_setup; |
| 766 | 778 | } |
| @@ -608,57 +608,3 @@ void force_flush_all(void) · 607 unmodified lines | ||
| 608 | 608 | vma = vma->vm_next; |
| 609 | 609 | } |
| 610 | 610 | } |
| 611 | − | |
| 612 | −struct page_change_data { | |
| 613 | − unsigned int set_mask, clear_mask; | |
| 614 | −}; | |
| 615 | − | |
| 616 | −static int change_page_range(pte_t *ptep, unsigned long addr, void *data) | |
| 617 | −{ | |
| 618 | − struct page_change_data *cdata = data; | |
| 619 | − pte_t pte = READ_ONCE(*ptep); | |
| 620 | − | |
| 621 | − pte_clear_bits(pte, cdata->clear_mask); | |
| 622 | − pte_set_bits(pte, cdata->set_mask); | |
| 623 | − | |
| 624 | − set_pte(ptep, pte); | |
| 625 | − return 0; | |
| 626 | −} | |
| 627 | − | |
| 628 | −static int change_memory(unsigned long start, unsigned long pages, | |
| 629 | − unsigned int set_mask, unsigned int clear_mask) | |
| 630 | −{ | |
| 631 | − unsigned long size = pages * PAGE_SIZE; | |
| 632 | − struct page_change_data data; | |
| 633 | − int ret; | |
| 634 | − | |
| 635 | − data.set_mask = set_mask; | |
| 636 | − data.clear_mask = clear_mask; | |
| 637 | − | |
| 638 | − ret = apply_to_page_range(&init_mm, start, size, change_page_range, | |
| 639 | − &data); | |
| 640 | − | |
| 641 | − flush_tlb_kernel_range(start, start + size); | |
| 642 | − | |
| 643 | − return ret; | |
| 644 | −} | |
| 645 | − | |
| 646 | −int set_memory_ro(unsigned long addr, int numpages) | |
| 647 | −{ | |
| 648 | − return change_memory(addr, numpages, 0, _PAGE_RW); | |
| 649 | −} | |
| 650 | − | |
| 651 | −int set_memory_rw(unsigned long addr, int numpages) | |
| 652 | −{ | |
| 653 | − return change_memory(addr, numpages, _PAGE_RW, 0); | |
| 654 | −} | |
| 655 | − | |
| 656 | −int set_memory_nx(unsigned long addr, int numpages) | |
| 657 | −{ | |
| 658 | − return -EOPNOTSUPP; | |
| 659 | −} | |
| 660 | − | |
| 661 | −int set_memory_x(unsigned long addr, int numpages) | |
| 662 | −{ | |
| 663 | − return -EOPNOTSUPP; | |
| 664 | −} | |
| @@ -26,7 +26,8 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <mem_user.h> |
| 27 | 27 | #include <os.h> |
| 28 | 28 | |
| 29 | −#define DEFAULT_COMMAND_LINE "root=98:0" | |
| 29 | +#define DEFAULT_COMMAND_LINE_ROOT "root=98:0" | |
| 30 | +#define DEFAULT_COMMAND_LINE_CONSOLE "console=tty" | |
| 30 | 31 | |
| 31 | 32 | /* Changed in add_arg and setup_arch, which run before SMP is started */ |
| 32 | 33 | static char __initdata command_line[COMMAND_LINE_SIZE] = { 0 }; |
| @@ -109,7 +110,8 @@ unsigned long end_vm; · 76 unmodified lines | ||
| 109 | 110 | int ncpus = 1; |
| 110 | 111 | |
| 111 | 112 | /* Set in early boot */ |
| 112 | −static int have_root __initdata = 0; | |
| 113 | +static int have_root __initdata; | |
| 114 | +static int have_console __initdata; | |
| 113 | 115 | |
| 114 | 116 | /* Set in uml_mem_setup and modified in linux_main */ |
| 115 | 117 | long long physmem_size = 32 * 1024 * 1024; |
| @@ -161,6 +163,17 @@ __uml_setup("debug", no_skas_debug_setup, · 45 unmodified lines | ||
| 161 | 163 | " this flag is not needed to run gdb on UML in skas mode\n\n" |
| 162 | 164 | ); |
| 163 | 165 | |
| 166 | +static int __init uml_console_setup(char *line, int *add) | |
| 167 | +{ | |
| 168 | + have_console = 1; | |
| 169 | + return 0; | |
| 170 | +} | |
| 171 | + | |
| 172 | +__uml_setup("console=", uml_console_setup, | |
| 173 | +"console=<preferred console>\n" | |
| 174 | +" Specify the preferred console output driver\n\n" | |
| 175 | +); | |
| 176 | + | |
| 164 | 177 | static int __init Usage(char *line, int *add) |
| 165 | 178 | { |
| 166 | 179 | const char **p; |
| @@ -264,7 +277,10 @@ int __init linux_main(int argc, char **argv) · 97 unmodified lines | ||
| 264 | 277 | add_arg(argv[i]); |
| 265 | 278 | } |
| 266 | 279 | if (have_root == 0) |
| 267 | − add_arg(DEFAULT_COMMAND_LINE); | |
| 280 | + add_arg(DEFAULT_COMMAND_LINE_ROOT); | |
| 281 | + | |
| 282 | + if (have_console == 0) | |
| 283 | + add_arg(DEFAULT_COMMAND_LINE_CONSOLE); | |
| 268 | 284 | |
| 269 | 285 | host_task_size = os_get_top_address(); |
| 270 | 286 | /* |
| @@ -45,7 +45,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv) · 44 unmodified lines | ||
| 45 | 45 | unsigned long stack, sp; |
| 46 | 46 | int pid, fds[2], ret, n; |
| 47 | 47 | |
| 48 | − stack = alloc_stack(__cant_sleep()); | |
| 48 | + stack = alloc_stack(0, __cant_sleep()); | |
| 49 | 49 | if (stack == 0) |
| 50 | 50 | return -ENOMEM; |
| 51 | 51 | |
| @@ -116,7 +116,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, · 64 unmodified lines | ||
| 116 | 116 | unsigned long stack, sp; |
| 117 | 117 | int pid, status, err; |
| 118 | 118 | |
| 119 | − stack = alloc_stack(__cant_sleep()); | |
| 119 | + stack = alloc_stack(0, __cant_sleep()); | |
| 120 | 120 | if (stack == 0) |
| 121 | 121 | return -ENOMEM; |
| 122 | 122 | |
| @@ -104,5 +104,18 @@ long long os_nsecs(void) · 103 unmodified lines | ||
| 104 | 104 | */ |
| 105 | 105 | void os_idle_sleep(void) |
| 106 | 106 | { |
| 107 | − pause(); | |
| 107 | + struct itimerspec its; | |
| 108 | + sigset_t set, old; | |
| 109 | + | |
| 110 | + /* block SIGALRM while we analyze the timer state */ | |
| 111 | + sigemptyset(&set); | |
| 112 | + sigaddset(&set, SIGALRM); | |
| 113 | + sigprocmask(SIG_BLOCK, &set, &old); | |
| 114 | + | |
| 115 | + /* check the timer, and if it'll fire then wait for it */ | |
| 116 | + timer_gettime(event_high_res_timer, &its); | |
| 117 | + if (its.it_value.tv_sec || its.it_value.tv_nsec) | |
| 118 | + sigsuspend(&old); | |
| 119 | + /* either way, restore the signal mask */ | |
| 120 | + sigprocmask(SIG_UNBLOCK, &set, NULL); | |
| 108 | 121 | } |
| @@ -19,6 +19,7 @@ config X86_32 · 18 unmodified lines | ||
| 19 | 19 | select KMAP_LOCAL |
| 20 | 20 | select MODULES_USE_ELF_REL |
| 21 | 21 | select OLD_SIGACTION |
| 22 | + select ARCH_SPLIT_ARG64 | |
| 22 | 23 | |
| 23 | 24 | config X86_64 |
| 24 | 25 | def_bool y |
| @@ -50,6 +50,9 @@ export BITS · 49 unmodified lines | ||
| 50 | 50 | KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow |
| 51 | 51 | KBUILD_CFLAGS += $(call cc-option,-mno-avx,) |
| 52 | 52 | |
| 53 | +# Intel CET isn't enabled in the kernel | |
| 54 | +KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none) | |
| 55 | + | |
| 53 | 56 | ifeq ($(CONFIG_X86_32),y) |
| 54 | 57 | BITS := 32 |
| 55 | 58 | UTS_MACHINE := i386 |
| @@ -73,10 +73,8 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, · 72 unmodified lines | ||
| 73 | 73 | unsigned int nr) |
| 74 | 74 | { |
| 75 | 75 | if (likely(nr < IA32_NR_syscalls)) { |
| 76 | − instrumentation_begin(); | |
| 77 | 76 | nr = array_index_nospec(nr, IA32_NR_syscalls); |
| 78 | 77 | regs->ax = ia32_sys_call_table[nr](regs); |
| 79 | − instrumentation_end(); | |
| 80 | 78 | } |
| 81 | 79 | } |
| 82 | 80 | |
| @@ -91,8 +89,11 @@ __visible noinstr void do_int80_syscall_32(struct pt_regs *regs) · 8 unmodified lines | ||
| 91 | 89 | * or may not be necessary, but it matches the old asm behavior. |
| 92 | 90 | */ |
| 93 | 91 | nr = (unsigned int)syscall_enter_from_user_mode(regs, nr); |
| 92 | + instrumentation_begin(); | |
| 94 | 93 | |
| 95 | 94 | do_syscall_32_irqs_on(regs, nr); |
| 95 | + | |
| 96 | + instrumentation_end(); | |
| 96 | 97 | syscall_exit_to_user_mode(regs); |
| 97 | 98 | } |
| 98 | 99 | |
| @@ -121,11 +122,12 @@ static noinstr bool __do_fast_syscall_32(struct pt_regs *regs) · 22 unmodified lines | ||
| 121 | 122 | res = get_user(*(u32 *)®s->bp, |
| 122 | 123 | (u32 __user __force *)(unsigned long)(u32)regs->sp); |
| 123 | 124 | } |
| 124 | − instrumentation_end(); | |
| 125 | 125 | |
| 126 | 126 | if (res) { |
| 127 | 127 | /* User code screwed up. */ |
| 128 | 128 | regs->ax = -EFAULT; |
| 129 | + | |
| 130 | + instrumentation_end(); | |
| 129 | 131 | syscall_exit_to_user_mode(regs); |
| 130 | 132 | return false; |
| 131 | 133 | } |
| @@ -135,6 +137,8 @@ static noinstr bool __do_fast_syscall_32(struct pt_regs *regs) · 3 unmodified lines | ||
| 135 | 137 | |
| 136 | 138 | /* Now this is just like a normal syscall. */ |
| 137 | 139 | do_syscall_32_irqs_on(regs, nr); |
| 140 | + | |
| 141 | + instrumentation_end(); | |
| 138 | 142 | syscall_exit_to_user_mode(regs); |
| 139 | 143 | return true; |
| 140 | 144 | } |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <asm/export.h> |
| 11 | 11 | |
| 12 | 12 | /* rdi: arg1 ... normal C conventions. rax is saved/restored. */ |
| 13 | − .macro THUNK name, func, put_ret_addr_in_rdi=0 | |
| 13 | + .macro THUNK name, func | |
| 14 | 14 | SYM_FUNC_START_NOALIGN(\name) |
| 15 | 15 | pushq %rbp |
| 16 | 16 | movq %rsp, %rbp |
| @@ -25,13 +25,8 @@ SYM_FUNC_START_NOALIGN(\name) · 8 unmodified lines | ||
| 25 | 25 | pushq %r10 |
| 26 | 26 | pushq %r11 |
| 27 | 27 | |
| 28 | − .if \put_ret_addr_in_rdi | |
| 29 | − /* 8(%rbp) is return addr on stack */ | |
| 30 | − movq 8(%rbp), %rdi | |
| 31 | − .endif | |
| 32 | − | |
| 33 | 28 | call \func |
| 34 | − jmp .L_restore | |
| 29 | + jmp __thunk_restore | |
| 35 | 30 | SYM_FUNC_END(\name) |
| 36 | 31 | _ASM_NOKPROBE(\name) |
| 37 | 32 | .endm |
| @@ -44,7 +39,7 @@ SYM_FUNC_END(\name) · 6 unmodified lines | ||
| 44 | 39 | #endif |
| 45 | 40 | |
| 46 | 41 | #ifdef CONFIG_PREEMPTION |
| 47 | −SYM_CODE_START_LOCAL_NOALIGN(.L_restore) | |
| 42 | +SYM_CODE_START_LOCAL_NOALIGN(__thunk_restore) | |
| 48 | 43 | popq %r11 |
| 49 | 44 | popq %r10 |
| 50 | 45 | popq %r9 |
| @@ -56,6 +51,6 @@ SYM_CODE_START_LOCAL_NOALIGN(.L_restore) · 5 unmodified lines | ||
| 56 | 51 | popq %rdi |
| 57 | 52 | popq %rbp |
| 58 | 53 | ret |
| 59 | − _ASM_NOKPROBE(.L_restore) | |
| 60 | −SYM_CODE_END(.L_restore) | |
| 54 | + _ASM_NOKPROBE(__thunk_restore) | |
| 55 | +SYM_CODE_END(__thunk_restore) | |
| 61 | 56 | #endif |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <asm/hyperv-tlfs.h> |
| 17 | 17 | #include <asm/mshyperv.h> |
| 18 | 18 | #include <asm/idtentry.h> |
| 19 | +#include <linux/kexec.h> | |
| 19 | 20 | #include <linux/version.h> |
| 20 | 21 | #include <linux/vmalloc.h> |
| 21 | 22 | #include <linux/mm.h> |
| @@ -26,6 +27,8 @@ · 4 unmodified lines | ||
| 26 | 27 | #include <linux/syscore_ops.h> |
| 27 | 28 | #include <clocksource/hyperv_timer.h> |
| 28 | 29 | |
| 30 | +int hyperv_init_cpuhp; | |
| 31 | + | |
| 29 | 32 | void *hv_hypercall_pg; |
| 30 | 33 | EXPORT_SYMBOL_GPL(hv_hypercall_pg); |
| 31 | 34 | |
| @@ -312,6 +315,25 @@ static struct syscore_ops hv_syscore_ops = { · 280 unmodified lines | ||
| 312 | 315 | .resume = hv_resume, |
| 313 | 316 | }; |
| 314 | 317 | |
| 318 | +static void (* __initdata old_setup_percpu_clockev)(void); | |
| 319 | + | |
| 320 | +static void __init hv_stimer_setup_percpu_clockev(void) | |
| 321 | +{ | |
| 322 | + /* | |
| 323 | + * Ignore any errors in setting up stimer clockevents | |
| 324 | + * as we can run with the LAPIC timer as a fallback. | |
| 325 | + */ | |
| 326 | + (void)hv_stimer_alloc(); | |
| 327 | + | |
| 328 | + /* | |
| 329 | + * Still register the LAPIC timer, because the direct-mode STIMER is | |
| 330 | + * not supported by old versions of Hyper-V. This also allows users | |
| 331 | + * to switch to LAPIC timer via /sys, if they want to. | |
| 332 | + */ | |
| 333 | + if (old_setup_percpu_clockev) | |
| 334 | + old_setup_percpu_clockev(); | |
| 335 | +} | |
| 336 | + | |
| 315 | 337 | /* |
| 316 | 338 | * This function is to be invoked early in the boot sequence after the |
| 317 | 339 | * hypervisor has been detected. |
| @@ -390,10 +412,14 @@ void __init hyperv_init(void) · 72 unmodified lines | ||
| 390 | 412 | wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); |
| 391 | 413 | |
| 392 | 414 | /* |
| 393 | − * Ignore any errors in setting up stimer clockevents | |
| 394 | − * as we can run with the LAPIC timer as a fallback. | |
| 415 | + * hyperv_init() is called before LAPIC is initialized: see | |
| 416 | + * apic_intr_mode_init() -> x86_platform.apic_post_init() and | |
| 417 | + * apic_bsp_setup() -> setup_local_APIC(). The direct-mode STIMER | |
| 418 | + * depends on LAPIC, so hv_stimer_alloc() should be called from | |
| 419 | + * x86_init.timers.setup_percpu_clockev. | |
| 395 | 420 | */ |
| 396 | − (void)hv_stimer_alloc(); | |
| 421 | + old_setup_percpu_clockev = x86_init.timers.setup_percpu_clockev; | |
| 422 | + x86_init.timers.setup_percpu_clockev = hv_stimer_setup_percpu_clockev; | |
| 397 | 423 | |
| 398 | 424 | hv_apic_init(); |
| 399 | 425 | |
| @@ -401,6 +427,7 @@ void __init hyperv_init(void) · 1 unmodified line | ||
| 401 | 427 | |
| 402 | 428 | register_syscore_ops(&hv_syscore_ops); |
| 403 | 429 | |
| 430 | + hyperv_init_cpuhp = cpuhp; | |
| 404 | 431 | return; |
| 405 | 432 | |
| 406 | 433 | remove_cpuhp_state: |
| @@ -66,11 +66,17 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus, · 65 unmodified lines | ||
| 66 | 66 | if (!hv_hypercall_pg) |
| 67 | 67 | goto do_native; |
| 68 | 68 | |
| 69 | − if (cpumask_empty(cpus)) | |
| 70 | − return; | |
| 71 | − | |
| 72 | 69 | local_irq_save(flags); |
| 73 | 70 | |
| 71 | + /* | |
| 72 | + * Only check the mask _after_ interrupt has been disabled to avoid the | |
| 73 | + * mask changing under our feet. | |
| 74 | + */ | |
| 75 | + if (cpumask_empty(cpus)) { | |
| 76 | + local_irq_restore(flags); | |
| 77 | + return; | |
| 78 | + } | |
| 79 | + | |
| 74 | 80 | flush_pcpu = (struct hv_tlb_flush **) |
| 75 | 81 | this_cpu_ptr(hyperv_pcpu_input_arg); |
| 76 | 82 | |
| @@ -197,16 +197,6 @@ static inline bool apic_needs_pit(void) { return true; } · 196 unmodified lines | ||
| 197 | 197 | #endif /* !CONFIG_X86_LOCAL_APIC */ |
| 198 | 198 | |
| 199 | 199 | #ifdef CONFIG_X86_X2APIC |
| 200 | −/* | |
| 201 | − * Make previous memory operations globally visible before | |
| 202 | − * sending the IPI through x2apic wrmsr. We need a serializing instruction or | |
| 203 | − * mfence for this. | |
| 204 | − */ | |
| 205 | −static inline void x2apic_wrmsr_fence(void) | |
| 206 | −{ | |
| 207 | − asm volatile("mfence" : : : "memory"); | |
| 208 | −} | |
| 209 | − | |
| 210 | 200 | static inline void native_apic_msr_write(u32 reg, u32 v) |
| 211 | 201 | { |
| 212 | 202 | if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR || |
| @@ -84,4 +84,22 @@ do { \ · 83 unmodified lines | ||
| 84 | 84 | |
| 85 | 85 | #include <asm-generic/barrier.h> |
| 86 | 86 | |
| 87 | +/* | |
| 88 | + * Make previous memory operations globally visible before | |
| 89 | + * a WRMSR. | |
| 90 | + * | |
| 91 | + * MFENCE makes writes visible, but only affects load/store | |
| 92 | + * instructions. WRMSR is unfortunately not a load/store | |
| 93 | + * instruction and is unaffected by MFENCE. The LFENCE ensures | |
| 94 | + * that the WRMSR is not reordered. | |
| 95 | + * | |
| 96 | + * Most WRMSRs are full serializing instructions themselves and | |
| 97 | + * do not require this barrier. This is only required for the | |
| 98 | + * IA32_TSC_DEADLINE and X2APIC MSRs. | |
| 99 | + */ | |
| 100 | +static inline void weak_wrmsr_fence(void) | |
| 101 | +{ | |
| 102 | + asm volatile("mfence; lfence" : : : "memory"); | |
| 103 | +} | |
| 104 | + | |
| 87 | 105 | #endif /* _ASM_X86_BARRIER_H */ |
| @@ -43,8 +43,6 @@ static __always_inline void arch_check_user_regs(struct pt_regs *regs) · 42 unmodified lines | ||
| 43 | 43 | } |
| 44 | 44 | #define arch_check_user_regs arch_check_user_regs |
| 45 | 45 | |
| 46 | −#define ARCH_SYSCALL_EXIT_WORK (_TIF_SINGLESTEP) | |
| 47 | − | |
| 48 | 46 | static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs, |
| 49 | 47 | unsigned long ti_work) |
| 50 | 48 | { |
| @@ -16,14 +16,25 @@ · 15 unmodified lines | ||
| 16 | 16 | * Use kernel_fpu_begin/end() if you intend to use FPU in kernel context. It |
| 17 | 17 | * disables preemption so be careful if you intend to use it for long periods |
| 18 | 18 | * of time. |
| 19 | − * If you intend to use the FPU in softirq you need to check first with | |
| 19 | + * If you intend to use the FPU in irq/softirq you need to check first with | |
| 20 | 20 | * irq_fpu_usable() if it is possible. |
| 21 | 21 | */ |
| 22 | −extern void kernel_fpu_begin(void); | |
| 22 | + | |
| 23 | +/* Kernel FPU states to initialize in kernel_fpu_begin_mask() */ | |
| 24 | +#define KFPU_387 _BITUL(0) /* 387 state will be initialized */ | |
| 25 | +#define KFPU_MXCSR _BITUL(1) /* MXCSR will be initialized */ | |
| 26 | + | |
| 27 | +extern void kernel_fpu_begin_mask(unsigned int kfpu_mask); | |
| 23 | 28 | extern void kernel_fpu_end(void); |
| 24 | 29 | extern bool irq_fpu_usable(void); |
| 25 | 30 | extern void fpregs_mark_activate(void); |
| 26 | 31 | |
| 32 | +/* Code that is unaware of kernel_fpu_begin_mask() can use this */ | |
| 33 | +static inline void kernel_fpu_begin(void) | |
| 34 | +{ | |
| 35 | + kernel_fpu_begin_mask(KFPU_387 | KFPU_MXCSR); | |
| 36 | +} | |
| 37 | + | |
| 27 | 38 | /* |
| 28 | 39 | * Use fpregs_lock() while editing CPU's FPU registers or fpu->state. |
| 29 | 40 | * A context switch will (and softirq might) save CPU's FPU registers to |
| @@ -613,6 +613,7 @@ DECLARE_IDTENTRY_VC(X86_TRAP_VC, exc_vmm_communication); · 612 unmodified lines | ||
| 613 | 613 | |
| 614 | 614 | #ifdef CONFIG_XEN_PV |
| 615 | 615 | DECLARE_IDTENTRY_XENCB(X86_TRAP_OTHER, exc_xen_hypervisor_callback); |
| 616 | +DECLARE_IDTENTRY_RAW(X86_TRAP_OTHER, exc_xen_unknown_trap); | |
| 616 | 617 | #endif |
| 617 | 618 | |
| 618 | 619 | /* Device interrupts common/spurious */ |
| @@ -97,6 +97,7 @@ · 96 unmodified lines | ||
| 97 | 97 | |
| 98 | 98 | #define INTEL_FAM6_LAKEFIELD 0x8A |
| 99 | 99 | #define INTEL_FAM6_ALDERLAKE 0x97 |
| 100 | +#define INTEL_FAM6_ALDERLAKE_L 0x9A | |
| 100 | 101 | |
| 101 | 102 | /* "Small Core" Processors (Atom) */ |
| 102 | 103 | |
| @@ -1010,9 +1010,21 @@ struct kvm_arch { · 1009 unmodified lines | ||
| 1010 | 1010 | */ |
| 1011 | 1011 | bool tdp_mmu_enabled; |
| 1012 | 1012 | |
| 1013 | − /* List of struct tdp_mmu_pages being used as roots */ | |
| 1013 | + /* | |
| 1014 | + * List of struct kvmp_mmu_pages being used as roots. | |
| 1015 | + * All struct kvm_mmu_pages in the list should have | |
| 1016 | + * tdp_mmu_page set. | |
| 1017 | + * All struct kvm_mmu_pages in the list should have a positive | |
| 1018 | + * root_count except when a thread holds the MMU lock and is removing | |
| 1019 | + * an entry from the list. | |
| 1020 | + */ | |
| 1014 | 1021 | struct list_head tdp_mmu_roots; |
| 1015 | − /* List of struct tdp_mmu_pages not being used as roots */ | |
| 1022 | + | |
| 1023 | + /* | |
| 1024 | + * List of struct kvmp_mmu_pages not being used as roots. | |
| 1025 | + * All struct kvm_mmu_pages in the list should have | |
| 1026 | + * tdp_mmu_page set and a root_count of 0. | |
| 1027 | + */ | |
| 1016 | 1028 | struct list_head tdp_mmu_pages; |
| 1017 | 1029 | }; |
| 1018 | 1030 | |
| @@ -1287,6 +1299,8 @@ struct kvm_x86_ops { · 268 unmodified lines | ||
| 1287 | 1299 | void (*migrate_timers)(struct kvm_vcpu *vcpu); |
| 1288 | 1300 | void (*msr_filter_changed)(struct kvm_vcpu *vcpu); |
| 1289 | 1301 | int (*complete_emulated_msr)(struct kvm_vcpu *vcpu, int err); |
| 1302 | + | |
| 1303 | + void (*vcpu_deliver_sipi_vector)(struct kvm_vcpu *vcpu, u8 vector); | |
| 1290 | 1304 | }; |
| 1291 | 1305 | |
| 1292 | 1306 | struct kvm_x86_nested_ops { |
| @@ -1468,6 +1482,7 @@ int kvm_fast_pio(struct kvm_vcpu *vcpu, int size, unsigned short port, int in); · 175 unmodified lines | ||
| 1468 | 1482 | int kvm_emulate_cpuid(struct kvm_vcpu *vcpu); |
| 1469 | 1483 | int kvm_emulate_halt(struct kvm_vcpu *vcpu); |
| 1470 | 1484 | int kvm_vcpu_halt(struct kvm_vcpu *vcpu); |
| 1485 | +int kvm_emulate_ap_reset_hold(struct kvm_vcpu *vcpu); | |
| 1471 | 1486 | int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu); |
| 1472 | 1487 | |
| 1473 | 1488 | void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); |
| @@ -74,6 +74,8 @@ static inline void hv_disable_stimer0_percpu_irq(int irq) {} · 73 unmodified lines | ||
| 74 | 74 | |
| 75 | 75 | |
| 76 | 76 | #if IS_ENABLED(CONFIG_HYPERV) |
| 77 | +extern int hyperv_init_cpuhp; | |
| 78 | + | |
| 77 | 79 | extern void *hv_hypercall_pg; |
| 78 | 80 | extern void __percpu **hyperv_pcpu_input_arg; |
| 79 | 81 | |
| @@ -86,7 +86,7 @@ static inline void do_trace_rdpmc(unsigned int msr, u64 val, int failed) {} · 85 unmodified lines | ||
| 86 | 86 | * think of extending them - you will be slapped with a stinking trout or a frozen |
| 87 | 87 | * shark will reach you, wherever you are! You've been warned. |
| 88 | 88 | */ |
| 89 | −static inline unsigned long long notrace __rdmsr(unsigned int msr) | |
| 89 | +static __always_inline unsigned long long __rdmsr(unsigned int msr) | |
| 90 | 90 | { |
| 91 | 91 | DECLARE_ARGS(val, low, high); |
| 92 | 92 | |
| @@ -98,7 +98,7 @@ static inline unsigned long long notrace __rdmsr(unsigned int msr) · 5 unmodified lines | ||
| 98 | 98 | return EAX_EDX_VAL(val, low, high); |
| 99 | 99 | } |
| 100 | 100 | |
| 101 | −static inline void notrace __wrmsr(unsigned int msr, u32 low, u32 high) | |
| 101 | +static __always_inline void __wrmsr(unsigned int msr, u32 low, u32 high) | |
| 102 | 102 | { |
| 103 | 103 | asm volatile("1: wrmsr\n" |
| 104 | 104 | "2:\n" |
| @@ -110,6 +110,8 @@ extern const struct cpumask *cpu_coregroup_mask(int cpu); · 109 unmodified lines | ||
| 110 | 110 | #define topology_die_id(cpu) (cpu_data(cpu).cpu_die_id) |
| 111 | 111 | #define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) |
| 112 | 112 | |
| 113 | +extern unsigned int __max_die_per_package; | |
| 114 | + | |
| 113 | 115 | #ifdef CONFIG_SMP |
| 114 | 116 | #define topology_die_cpumask(cpu) (per_cpu(cpu_die_map, cpu)) |
| 115 | 117 | #define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) |
| @@ -118,8 +120,6 @@ extern const struct cpumask *cpu_coregroup_mask(int cpu); · 2 unmodified lines | ||
| 118 | 120 | extern unsigned int __max_logical_packages; |
| 119 | 121 | #define topology_max_packages() (__max_logical_packages) |
| 120 | 122 | |
| 121 | −extern unsigned int __max_die_per_package; | |
| 122 | − | |
| 123 | 123 | static inline int topology_max_die_per_package(void) |
| 124 | 124 | { |
| 125 | 125 | return __max_die_per_package; |
| @@ -41,6 +41,7 @@ · 40 unmodified lines | ||
| 41 | 41 | #include <asm/perf_event.h> |
| 42 | 42 | #include <asm/x86_init.h> |
| 43 | 43 | #include <linux/atomic.h> |
| 44 | +#include <asm/barrier.h> | |
| 44 | 45 | #include <asm/mpspec.h> |
| 45 | 46 | #include <asm/i8259.h> |
| 46 | 47 | #include <asm/proto.h> |
| @@ -477,6 +478,9 @@ static int lapic_next_deadline(unsigned long delta, · 430 unmodified lines | ||
| 477 | 478 | { |
| 478 | 479 | u64 tsc; |
| 479 | 480 | |
| 481 | + /* This MSR is special and need a special fence: */ | |
| 482 | + weak_wrmsr_fence(); | |
| 483 | + | |
| 480 | 484 | tsc = rdtsc(); |
| 481 | 485 | wrmsrl(MSR_IA32_TSC_DEADLINE, tsc + (((u64) delta) * TSC_DIVISOR)); |
| 482 | 486 | return 0; |
| @@ -29,7 +29,8 @@ static void x2apic_send_IPI(int cpu, int vector) · 28 unmodified lines | ||
| 29 | 29 | { |
| 30 | 30 | u32 dest = per_cpu(x86_cpu_to_logical_apicid, cpu); |
| 31 | 31 | |
| 32 | − x2apic_wrmsr_fence(); | |
| 32 | + /* x2apic MSRs are special and need a special fence: */ | |
| 33 | + weak_wrmsr_fence(); | |
| 33 | 34 | __x2apic_send_IPI_dest(dest, vector, APIC_DEST_LOGICAL); |
| 34 | 35 | } |
| 35 | 36 | |
| @@ -41,7 +42,8 @@ __x2apic_send_IPI_mask(const struct cpumask *mask, int vector, int apic_dest) · 5 unmodified lines | ||
| 41 | 42 | unsigned long flags; |
| 42 | 43 | u32 dest; |
| 43 | 44 | |
| 44 | − x2apic_wrmsr_fence(); | |
| 45 | + /* x2apic MSRs are special and need a special fence: */ | |
| 46 | + weak_wrmsr_fence(); | |
| 45 | 47 | local_irq_save(flags); |
| 46 | 48 | |
| 47 | 49 | tmpmsk = this_cpu_cpumask_var_ptr(ipi_mask); |
| @@ -43,7 +43,8 @@ static void x2apic_send_IPI(int cpu, int vector) · 42 unmodified lines | ||
| 43 | 43 | { |
| 44 | 44 | u32 dest = per_cpu(x86_cpu_to_apicid, cpu); |
| 45 | 45 | |
| 46 | − x2apic_wrmsr_fence(); | |
| 46 | + /* x2apic MSRs are special and need a special fence: */ | |
| 47 | + weak_wrmsr_fence(); | |
| 47 | 48 | __x2apic_send_IPI_dest(dest, vector, APIC_DEST_PHYSICAL); |
| 48 | 49 | } |
| 49 | 50 | |
| @@ -54,7 +55,8 @@ __x2apic_send_IPI_mask(const struct cpumask *mask, int vector, int apic_dest) · 4 unmodified lines | ||
| 54 | 55 | unsigned long this_cpu; |
| 55 | 56 | unsigned long flags; |
| 56 | 57 | |
| 57 | − x2apic_wrmsr_fence(); | |
| 58 | + /* x2apic MSRs are special and need a special fence: */ | |
| 59 | + weak_wrmsr_fence(); | |
| 58 | 60 | |
| 59 | 61 | local_irq_save(flags); |
| 60 | 62 | |
| @@ -125,7 +127,8 @@ void __x2apic_send_IPI_shorthand(int vector, u32 which) · 64 unmodified lines | ||
| 125 | 127 | { |
| 126 | 128 | unsigned long cfg = __prepare_ICR(which, vector, 0); |
| 127 | 129 | |
| 128 | − x2apic_wrmsr_fence(); | |
| 130 | + /* x2apic MSRs are special and need a special fence: */ | |
| 131 | + weak_wrmsr_fence(); | |
| 129 | 132 | native_x2apic_icr_write(cfg, 0); |
| 130 | 133 | } |
| 131 | 134 | |
| @@ -542,12 +542,12 @@ static void bsp_init_amd(struct cpuinfo_x86 *c) · 541 unmodified lines | ||
| 542 | 542 | u32 ecx; |
| 543 | 543 | |
| 544 | 544 | ecx = cpuid_ecx(0x8000001e); |
| 545 | − nodes_per_socket = ((ecx >> 8) & 7) + 1; | |
| 545 | + __max_die_per_package = nodes_per_socket = ((ecx >> 8) & 7) + 1; | |
| 546 | 546 | } else if (boot_cpu_has(X86_FEATURE_NODEID_MSR)) { |
| 547 | 547 | u64 value; |
| 548 | 548 | |
| 549 | 549 | rdmsrl(MSR_FAM10H_NODE_ID, value); |
| 550 | − nodes_per_socket = ((value >> 3) & 7) + 1; | |
| 550 | + __max_die_per_package = nodes_per_socket = ((value >> 3) & 7) + 1; | |
| 551 | 551 | } |
| 552 | 552 | |
| 553 | 553 | if (!boot_cpu_has(X86_FEATURE_AMD_SSBD) && |
| @@ -1159,6 +1159,7 @@ static const struct x86_cpu_id split_lock_cpu_ids[] __initconst = { · 1158 unmodified lines | ||
| 1159 | 1159 | X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, 1), |
| 1160 | 1160 | X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, 1), |
| 1161 | 1161 | X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, 1), |
| 1162 | + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, 1), | |
| 1162 | 1163 | {} |
| 1163 | 1164 | }; |
| 1164 | 1165 | |
| @@ -1992,10 +1992,9 @@ static __always_inline void exc_machine_check_kernel(struct pt_regs *regs) · 1991 unmodified lines | ||
| 1992 | 1992 | * that out because it's an indirect call. Annotate it. |
| 1993 | 1993 | */ |
| 1994 | 1994 | instrumentation_begin(); |
| 1995 | − trace_hardirqs_off_finish(); | |
| 1995 | + | |
| 1996 | 1996 | machine_check_vector(regs); |
| 1997 | − if (regs->flags & X86_EFLAGS_IF) | |
| 1998 | − trace_hardirqs_on_prepare(); | |
| 1997 | + | |
| 1999 | 1998 | instrumentation_end(); |
| 2000 | 1999 | irqentry_nmi_exit(regs, irq_state); |
| 2001 | 2000 | } |
| @@ -2004,7 +2003,9 @@ static __always_inline void exc_machine_check_user(struct pt_regs *regs) · 2 unmodified lines | ||
| 2004 | 2003 | { |
| 2005 | 2004 | irqentry_enter_from_user_mode(regs); |
| 2006 | 2005 | instrumentation_begin(); |
| 2006 | + | |
| 2007 | 2007 | machine_check_vector(regs); |
| 2008 | + | |
| 2008 | 2009 | instrumentation_end(); |
| 2009 | 2010 | irqentry_exit_to_user_mode(regs); |
| 2010 | 2011 | } |
| @@ -135,14 +135,32 @@ static void hv_machine_shutdown(void) · 134 unmodified lines | ||
| 135 | 135 | { |
| 136 | 136 | if (kexec_in_progress && hv_kexec_handler) |
| 137 | 137 | hv_kexec_handler(); |
| 138 | + | |
| 139 | + /* | |
| 140 | + * Call hv_cpu_die() on all the CPUs, otherwise later the hypervisor | |
| 141 | + * corrupts the old VP Assist Pages and can crash the kexec kernel. | |
| 142 | + */ | |
| 143 | + if (kexec_in_progress && hyperv_init_cpuhp > 0) | |
| 144 | + cpuhp_remove_state(hyperv_init_cpuhp); | |
| 145 | + | |
| 146 | + /* The function calls stop_other_cpus(). */ | |
| 138 | 147 | native_machine_shutdown(); |
| 148 | + | |
| 149 | + /* Disable the hypercall page when there is only 1 active CPU. */ | |
| 150 | + if (kexec_in_progress) | |
| 151 | + hyperv_cleanup(); | |
| 139 | 152 | } |
| 140 | 153 | |
| 141 | 154 | static void hv_machine_crash_shutdown(struct pt_regs *regs) |
| 142 | 155 | { |
| 143 | 156 | if (hv_crash_handler) |
| 144 | 157 | hv_crash_handler(regs); |
| 158 | + | |
| 159 | + /* The function calls crash_smp_send_stop(). */ | |
| 145 | 160 | native_machine_crash_shutdown(regs); |
| 161 | + | |
| 162 | + /* Disable the hypercall page when there is only 1 active CPU. */ | |
| 163 | + hyperv_cleanup(); | |
| 146 | 164 | } |
| 147 | 165 | #endif /* CONFIG_KEXEC_CORE */ |
| 148 | 166 | #endif /* CONFIG_HYPERV */ |
| @@ -167,9 +167,6 @@ static u8 mtrr_type_lookup_variable(u64 start, u64 end, u64 *partial_end, · 166 unmodified lines | ||
| 167 | 167 | *repeat = 0; |
| 168 | 168 | *uniform = 1; |
| 169 | 169 | |
| 170 | − /* Make end inclusive instead of exclusive */ | |
| 171 | − end--; | |
| 172 | − | |
| 173 | 170 | prev_match = MTRR_TYPE_INVALID; |
| 174 | 171 | for (i = 0; i < num_var_ranges; ++i) { |
| 175 | 172 | unsigned short start_state, end_state, inclusive; |
| @@ -261,6 +258,9 @@ u8 mtrr_type_lookup(u64 start, u64 end, u8 *uniform) · 85 unmodified lines | ||
| 261 | 258 | int repeat; |
| 262 | 259 | u64 partial_end; |
| 263 | 260 | |
| 261 | + /* Make end inclusive instead of exclusive */ | |
| 262 | + end--; | |
| 263 | + | |
| 264 | 264 | if (!mtrr_state_set) |
| 265 | 265 | return MTRR_TYPE_INVALID; |
| 266 | 266 | |
| @@ -525,89 +525,70 @@ static void rdtgroup_remove(struct rdtgroup *rdtgrp) · 524 unmodified lines | ||
| 525 | 525 | kfree(rdtgrp); |
| 526 | 526 | } |
| 527 | 527 | |
| 528 | −struct task_move_callback { | |
| 529 | − struct callback_head work; | |
| 530 | − struct rdtgroup *rdtgrp; | |
| 531 | −}; | |
| 532 | − | |
| 533 | −static void move_myself(struct callback_head *head) | |
| 528 | +static void _update_task_closid_rmid(void *task) | |
| 534 | 529 | { |
| 535 | − struct task_move_callback *callback; | |
| 536 | − struct rdtgroup *rdtgrp; | |
| 537 | − | |
| 538 | − callback = container_of(head, struct task_move_callback, work); | |
| 539 | − rdtgrp = callback->rdtgrp; | |
| 540 | − | |
| 541 | 530 | /* |
| 542 | − * If resource group was deleted before this task work callback | |
| 543 | − * was invoked, then assign the task to root group and free the | |
| 544 | − * resource group. | |
| 531 | + * If the task is still current on this CPU, update PQR_ASSOC MSR. | |
| 532 | + * Otherwise, the MSR is updated when the task is scheduled in. | |
| 545 | 533 | */ |
| 546 | − if (atomic_dec_and_test(&rdtgrp->waitcount) && | |
| 547 | − (rdtgrp->flags & RDT_DELETED)) { | |
| 548 | − current->closid = 0; | |
| 549 | − current->rmid = 0; | |
| 550 | − rdtgroup_remove(rdtgrp); | |
| 551 | − } | |
| 552 | − | |
| 553 | − if (unlikely(current->flags & PF_EXITING)) | |
| 554 | − goto out; | |
| 555 | − | |
| 556 | − preempt_disable(); | |
| 557 | − /* update PQR_ASSOC MSR to make resource group go into effect */ | |
| 558 | − resctrl_sched_in(); | |
| 559 | − preempt_enable(); | |
| 534 | + if (task == current) | |
| 535 | + resctrl_sched_in(); | |
| 536 | +} | |
| 560 | 537 | |
| 561 | −out: | |
| 562 | − kfree(callback); | |
| 538 | +static void update_task_closid_rmid(struct task_struct *t) | |
| 539 | +{ | |
| 540 | + if (IS_ENABLED(CONFIG_SMP) && task_curr(t)) | |
| 541 | + smp_call_function_single(task_cpu(t), _update_task_closid_rmid, t, 1); | |
| 542 | + else | |
| 543 | + _update_task_closid_rmid(t); | |
| 563 | 544 | } |
| 564 | 545 | |
| 565 | 546 | static int __rdtgroup_move_task(struct task_struct *tsk, |
| 566 | 547 | struct rdtgroup *rdtgrp) |
| 567 | 548 | { |
| 568 | − struct task_move_callback *callback; | |
| 569 | − int ret; | |
| 570 | − | |
| 571 | − callback = kzalloc(sizeof(*callback), GFP_KERNEL); | |
| 572 | − if (!callback) | |
| 573 | − return -ENOMEM; | |
| 574 | − callback->work.func = move_myself; | |
| 575 | − callback->rdtgrp = rdtgrp; | |
| 549 | + /* If the task is already in rdtgrp, no need to move the task. */ | |
| 550 | + if ((rdtgrp->type == RDTCTRL_GROUP && tsk->closid == rdtgrp->closid && | |
| 551 | + tsk->rmid == rdtgrp->mon.rmid) || | |
| 552 | + (rdtgrp->type == RDTMON_GROUP && tsk->rmid == rdtgrp->mon.rmid && | |
| 553 | + tsk->closid == rdtgrp->mon.parent->closid)) | |
| 554 | + return 0; | |
| 576 | 555 | |
| 577 | 556 | /* |
| 578 | − * Take a refcount, so rdtgrp cannot be freed before the | |
| 579 | − * callback has been invoked. | |
| 557 | + * Set the task's closid/rmid before the PQR_ASSOC MSR can be | |
| 558 | + * updated by them. | |
| 559 | + * | |
| 560 | + * For ctrl_mon groups, move both closid and rmid. | |
| 561 | + * For monitor groups, can move the tasks only from | |
| 562 | + * their parent CTRL group. | |
| 580 | 563 | */ |
| 581 | − atomic_inc(&rdtgrp->waitcount); | |
| 582 | − ret = task_work_add(tsk, &callback->work, TWA_RESUME); | |
| 583 | − if (ret) { | |
| 584 | − /* | |
| 585 | − * Task is exiting. Drop the refcount and free the callback. | |
| 586 | − * No need to check the refcount as the group cannot be | |
| 587 | − * deleted before the write function unlocks rdtgroup_mutex. | |
| 588 | − */ | |
| 589 | − atomic_dec(&rdtgrp->waitcount); | |
| 590 | − kfree(callback); | |
| 591 | − rdt_last_cmd_puts("Task exited\n"); | |
| 592 | − } else { | |
| 593 | − /* | |
| 594 | − * For ctrl_mon groups move both closid and rmid. | |
| 595 | − * For monitor groups, can move the tasks only from | |
| 596 | − * their parent CTRL group. | |
| 597 | − */ | |
| 598 | − if (rdtgrp->type == RDTCTRL_GROUP) { | |
| 599 | − tsk->closid = rdtgrp->closid; | |
| 564 | + | |
| 565 | + if (rdtgrp->type == RDTCTRL_GROUP) { | |
| 566 | + tsk->closid = rdtgrp->closid; | |
| 567 | + tsk->rmid = rdtgrp->mon.rmid; | |
| 568 | + } else if (rdtgrp->type == RDTMON_GROUP) { | |
| 569 | + if (rdtgrp->mon.parent->closid == tsk->closid) { | |
| 600 | 570 | tsk->rmid = rdtgrp->mon.rmid; |
| 601 | − } else if (rdtgrp->type == RDTMON_GROUP) { | |
| 602 | − if (rdtgrp->mon.parent->closid == tsk->closid) { | |
| 603 | − tsk->rmid = rdtgrp->mon.rmid; | |
| 604 | − } else { | |
| 605 | − rdt_last_cmd_puts("Can't move task to different control group\n"); | |
| 606 | − ret = -EINVAL; | |
| 607 | − } | |
| 571 | + } else { | |
| 572 | + rdt_last_cmd_puts("Can't move task to different control group\n"); | |
| 573 | + return -EINVAL; | |
| 608 | 574 | } |
| 609 | 575 | } |
| 610 | − return ret; | |
| 576 | + | |
| 577 | + /* | |
| 578 | + * Ensure the task's closid and rmid are written before determining if | |
| 579 | + * the task is current that will decide if it will be interrupted. | |
| 580 | + */ | |
| 581 | + barrier(); | |
| 582 | + | |
| 583 | + /* | |
| 584 | + * By now, the task's closid and rmid are set. If the task is current | |
| 585 | + * on a CPU, the PQR_ASSOC MSR needs to be updated to make the resource | |
| 586 | + * group go into effect. If the task is not current, the MSR will be | |
| 587 | + * updated when the task is scheduled in. | |
| 588 | + */ | |
| 589 | + update_task_closid_rmid(tsk); | |
| 590 | + | |
| 591 | + return 0; | |
| 611 | 592 | } |
| 612 | 593 | |
| 613 | 594 | static bool is_closid_match(struct task_struct *t, struct rdtgroup *r) |
| @@ -72,6 +72,9 @@ static int sgx_release(struct inode *inode, struct file *file) · 71 unmodified lines | ||
| 72 | 72 | synchronize_srcu(&encl->srcu); |
| 73 | 73 | mmu_notifier_unregister(&encl_mm->mmu_notifier, encl_mm->mm); |
| 74 | 74 | kfree(encl_mm); |
| 75 | + | |
| 76 | + /* 'encl_mm' is gone, put encl_mm->encl reference: */ | |
| 77 | + kref_put(&encl->refcount, sgx_encl_release); | |
| 75 | 78 | } |
| 76 | 79 | |
| 77 | 80 | kref_put(&encl->refcount, sgx_encl_release); |
| @@ -481,6 +481,9 @@ static void sgx_mmu_notifier_free(struct mmu_notifier *mn) · 480 unmodified lines | ||
| 481 | 481 | { |
| 482 | 482 | struct sgx_encl_mm *encl_mm = container_of(mn, struct sgx_encl_mm, mmu_notifier); |
| 483 | 483 | |
| 484 | + /* 'encl_mm' is going away, put encl_mm->encl reference: */ | |
| 485 | + kref_put(&encl_mm->encl->refcount, sgx_encl_release); | |
| 486 | + | |
| 484 | 487 | kfree(encl_mm); |
| 485 | 488 | } |
| 486 | 489 | |
| @@ -534,6 +537,8 @@ int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm) · 47 unmodified lines | ||
| 534 | 537 | if (!encl_mm) |
| 535 | 538 | return -ENOMEM; |
| 536 | 539 | |
| 540 | + /* Grab a refcount for the encl_mm->encl reference: */ | |
| 541 | + kref_get(&encl->refcount); | |
| 537 | 542 | encl_mm->encl = encl; |
| 538 | 543 | encl_mm->mm = mm; |
| 539 | 544 | encl_mm->mmu_notifier.ops = &sgx_mmu_notifier_ops; |
| @@ -25,10 +25,10 @@ · 24 unmodified lines | ||
| 25 | 25 | #define BITS_SHIFT_NEXT_LEVEL(eax) ((eax) & 0x1f) |
| 26 | 26 | #define LEVEL_MAX_SIBLINGS(ebx) ((ebx) & 0xffff) |
| 27 | 27 | |
| 28 | −#ifdef CONFIG_SMP | |
| 29 | 28 | unsigned int __max_die_per_package __read_mostly = 1; |
| 30 | 29 | EXPORT_SYMBOL(__max_die_per_package); |
| 31 | 30 | |
| 31 | +#ifdef CONFIG_SMP | |
| 32 | 32 | /* |
| 33 | 33 | * Check if given CPUID extended toplogy "leaf" is implemented |
| 34 | 34 | */ |
| @@ -121,7 +121,7 @@ int copy_fpregs_to_fpstate(struct fpu *fpu) · 120 unmodified lines | ||
| 121 | 121 | } |
| 122 | 122 | EXPORT_SYMBOL(copy_fpregs_to_fpstate); |
| 123 | 123 | |
| 124 | −void kernel_fpu_begin(void) | |
| 124 | +void kernel_fpu_begin_mask(unsigned int kfpu_mask) | |
| 125 | 125 | { |
| 126 | 126 | preempt_disable(); |
| 127 | 127 | |
| @@ -141,13 +141,14 @@ void kernel_fpu_begin(void) · 13 unmodified lines | ||
| 141 | 141 | } |
| 142 | 142 | __cpu_invalidate_fpregs_state(); |
| 143 | 143 | |
| 144 | − if (boot_cpu_has(X86_FEATURE_XMM)) | |
| 144 | + /* Put sane initial values into the control registers. */ | |
| 145 | + if (likely(kfpu_mask & KFPU_MXCSR) && boot_cpu_has(X86_FEATURE_XMM)) | |
| 145 | 146 | ldmxcsr(MXCSR_DEFAULT); |
| 146 | 147 | |
| 147 | − if (boot_cpu_has(X86_FEATURE_FPU)) | |
| 148 | + if (unlikely(kfpu_mask & KFPU_387) && boot_cpu_has(X86_FEATURE_FPU)) | |
| 148 | 149 | asm volatile ("fninit"); |
| 149 | 150 | } |
| 150 | −EXPORT_SYMBOL_GPL(kernel_fpu_begin); | |
| 151 | +EXPORT_SYMBOL_GPL(kernel_fpu_begin_mask); | |
| 151 | 152 | |
| 152 | 153 | void kernel_fpu_end(void) |
| 153 | 154 | { |
| @@ -269,6 +269,20 @@ static inline bool within_cpu_entry(unsigned long addr, unsigned long end) · 268 unmodified lines | ||
| 269 | 269 | CPU_ENTRY_AREA_TOTAL_SIZE)) |
| 270 | 270 | return true; |
| 271 | 271 | |
| 272 | + /* | |
| 273 | + * When FSGSBASE is enabled, paranoid_entry() fetches the per-CPU | |
| 274 | + * GSBASE value via __per_cpu_offset or pcpu_unit_offsets. | |
| 275 | + */ | |
| 276 | +#ifdef CONFIG_SMP | |
| 277 | + if (within_area(addr, end, (unsigned long)__per_cpu_offset, | |
| 278 | + sizeof(unsigned long) * nr_cpu_ids)) | |
| 279 | + return true; | |
| 280 | +#else | |
| 281 | + if (within_area(addr, end, (unsigned long)&pcpu_unit_offsets, | |
| 282 | + sizeof(pcpu_unit_offsets))) | |
| 283 | + return true; | |
| 284 | +#endif | |
| 285 | + | |
| 272 | 286 | for_each_possible_cpu(cpu) { |
| 273 | 287 | /* The original rw GDT is being used after load_direct_gdt() */ |
| 274 | 288 | if (within_area(addr, end, (unsigned long)get_cpu_gdt_rw(cpu), |
| @@ -293,6 +307,14 @@ static inline bool within_cpu_entry(unsigned long addr, unsigned long end) · 18 unmodified lines | ||
| 293 | 307 | (unsigned long)&per_cpu(cpu_tlbstate, cpu), |
| 294 | 308 | sizeof(struct tlb_state))) |
| 295 | 309 | return true; |
| 310 | + | |
| 311 | + /* | |
| 312 | + * When in guest (X86_FEATURE_HYPERVISOR), local_db_save() | |
| 313 | + * will read per-cpu cpu_dr7 before clear dr7 register. | |
| 314 | + */ | |
| 315 | + if (within_area(addr, end, (unsigned long)&per_cpu(cpu_dr7, cpu), | |
| 316 | + sizeof(cpu_dr7))) | |
| 317 | + return true; | |
| 296 | 318 | } |
| 297 | 319 | |
| 298 | 320 | return false; |
| @@ -491,15 +513,12 @@ static int hw_breakpoint_handler(struct die_args *args) · 192 unmodified lines | ||
| 491 | 513 | struct perf_event *bp; |
| 492 | 514 | unsigned long *dr6_p; |
| 493 | 515 | unsigned long dr6; |
| 516 | + bool bpx; | |
| 494 | 517 | |
| 495 | 518 | /* The DR6 value is pointed by args->err */ |
| 496 | 519 | dr6_p = (unsigned long *)ERR_PTR(args->err); |
| 497 | 520 | dr6 = *dr6_p; |
| 498 | 521 | |
| 499 | − /* If it's a single step, TRAP bits are random */ | |
| 500 | − if (dr6 & DR_STEP) | |
| 501 | − return NOTIFY_DONE; | |
| 502 | − | |
| 503 | 522 | /* Do an early return if no trap bits are set in DR6 */ |
| 504 | 523 | if ((dr6 & DR_TRAP_BITS) == 0) |
| 505 | 524 | return NOTIFY_DONE; |
| @@ -509,28 +528,29 @@ static int hw_breakpoint_handler(struct die_args *args) · 3 unmodified lines | ||
| 509 | 528 | if (likely(!(dr6 & (DR_TRAP0 << i)))) |
| 510 | 529 | continue; |
| 511 | 530 | |
| 531 | + bp = this_cpu_read(bp_per_reg[i]); | |
| 532 | + if (!bp) | |
| 533 | + continue; | |
| 534 | + | |
| 535 | + bpx = bp->hw.info.type == X86_BREAKPOINT_EXECUTE; | |
| 536 | + | |
| 512 | 537 | /* |
| 513 | − * The counter may be concurrently released but that can only | |
| 514 | − * occur from a call_rcu() path. We can then safely fetch | |
| 515 | − * the breakpoint, use its callback, touch its counter | |
| 516 | − * while we are in an rcu_read_lock() path. | |
| 538 | + * TF and data breakpoints are traps and can be merged, however | |
| 539 | + * instruction breakpoints are faults and will be raised | |
| 540 | + * separately. | |
| 541 | + * | |
| 542 | + * However DR6 can indicate both TF and instruction | |
| 543 | + * breakpoints. In that case take TF as that has precedence and | |
| 544 | + * delay the instruction breakpoint for the next exception. | |
| 517 | 545 | */ |
| 518 | − rcu_read_lock(); | |
| 546 | + if (bpx && (dr6 & DR_STEP)) | |
| 547 | + continue; | |
| 519 | 548 | |
| 520 | − bp = this_cpu_read(bp_per_reg[i]); | |
| 521 | 549 | /* |
| 522 | 550 | * Reset the 'i'th TRAP bit in dr6 to denote completion of |
| 523 | 551 | * exception handling |
| 524 | 552 | */ |
| 525 | 553 | (*dr6_p) &= ~(DR_TRAP0 << i); |
| 526 | − /* | |
| 527 | − * bp can be NULL due to lazy debug register switching | |
| 528 | − * or due to concurrent perf counter removing. | |
| 529 | − */ | |
| 530 | − if (!bp) { | |
| 531 | − rcu_read_unlock(); | |
| 532 | − break; | |
| 533 | − } | |
| 534 | 554 | |
| 535 | 555 | perf_bp_event(bp, args->regs); |
| 536 | 556 | |
| @@ -538,11 +558,10 @@ static int hw_breakpoint_handler(struct die_args *args) · 1 unmodified line | ||
| 538 | 558 | * Set up resume flag to avoid breakpoint recursion when |
| 539 | 559 | * returning back to origin. |
| 540 | 560 | */ |
| 541 | − if (bp->hw.info.type == X86_BREAKPOINT_EXECUTE) | |
| 561 | + if (bpx) | |
| 542 | 562 | args->regs->flags |= X86_EFLAGS_RF; |
| 543 | − | |
| 544 | − rcu_read_unlock(); | |
| 545 | 563 | } |
| 564 | + | |
| 546 | 565 | /* |
| 547 | 566 | * Further processing in do_debug() is needed for a) user-space |
| 548 | 567 | * breakpoints (to generate signals) and b) when the system has |
| @@ -305,14 +305,14 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) · 304 unmodified lines | ||
| 305 | 305 | case 0xe4: |
| 306 | 306 | case 0xe5: |
| 307 | 307 | *exitinfo |= IOIO_TYPE_IN; |
| 308 | − *exitinfo |= (u64)insn->immediate.value << 16; | |
| 308 | + *exitinfo |= (u8)insn->immediate.value << 16; | |
| 309 | 309 | break; |
| 310 | 310 | |
| 311 | 311 | /* OUT immediate opcodes */ |
| 312 | 312 | case 0xe6: |
| 313 | 313 | case 0xe7: |
| 314 | 314 | *exitinfo |= IOIO_TYPE_OUT; |
| 315 | − *exitinfo |= (u64)insn->immediate.value << 16; | |
| 315 | + *exitinfo |= (u8)insn->immediate.value << 16; | |
| 316 | 316 | break; |
| 317 | 317 | |
| 318 | 318 | /* IN register opcodes */ |
| @@ -225,7 +225,7 @@ static inline u64 sev_es_rd_ghcb_msr(void) · 224 unmodified lines | ||
| 225 | 225 | return __rdmsr(MSR_AMD64_SEV_ES_GHCB); |
| 226 | 226 | } |
| 227 | 227 | |
| 228 | −static inline void sev_es_wr_ghcb_msr(u64 val) | |
| 228 | +static __always_inline void sev_es_wr_ghcb_msr(u64 val) | |
| 229 | 229 | { |
| 230 | 230 | u32 low, high; |
| 231 | 231 | |
| @@ -286,6 +286,12 @@ static enum es_result vc_write_mem(struct es_em_ctxt *ctxt, · 54 unmodified lines | ||
| 286 | 286 | u16 d2; |
| 287 | 287 | u8 d1; |
| 288 | 288 | |
| 289 | + /* If instruction ran in kernel mode and the I/O buffer is in kernel space */ | |
| 290 | + if (!user_mode(ctxt->regs) && !access_ok(target, size)) { | |
| 291 | + memcpy(dst, buf, size); | |
| 292 | + return ES_OK; | |
| 293 | + } | |
| 294 | + | |
| 289 | 295 | switch (size) { |
| 290 | 296 | case 1: |
| 291 | 297 | memcpy(&d1, buf, 1); |
| @@ -335,6 +341,12 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt, · 43 unmodified lines | ||
| 335 | 341 | u16 d2; |
| 336 | 342 | u8 d1; |
| 337 | 343 | |
| 344 | + /* If instruction ran in kernel mode and the I/O buffer is in kernel space */ | |
| 345 | + if (!user_mode(ctxt->regs) && !access_ok(s, size)) { | |
| 346 | + memcpy(buf, src, size); | |
| 347 | + return ES_OK; | |
| 348 | + } | |
| 349 | + | |
| 338 | 350 | switch (size) { |
| 339 | 351 | case 1: |
| 340 | 352 | if (get_user(d1, s)) |
| @@ -56,6 +56,7 @@ · 55 unmodified lines | ||
| 56 | 56 | #include <linux/numa.h> |
| 57 | 57 | #include <linux/pgtable.h> |
| 58 | 58 | #include <linux/overflow.h> |
| 59 | +#include <linux/syscore_ops.h> | |
| 59 | 60 | |
| 60 | 61 | #include <asm/acpi.h> |
| 61 | 62 | #include <asm/desc.h> |
| @@ -1832,6 +1833,7 @@ void arch_set_max_freq_ratio(bool turbo_disabled) · 1770 unmodified lines | ||
| 1832 | 1833 | arch_max_freq_ratio = turbo_disabled ? SCHED_CAPACITY_SCALE : |
| 1833 | 1834 | arch_turbo_freq_ratio; |
| 1834 | 1835 | } |
| 1836 | +EXPORT_SYMBOL_GPL(arch_set_max_freq_ratio); | |
| 1835 | 1837 | |
| 1836 | 1838 | static bool turbo_disabled(void) |
| 1837 | 1839 | { |
| @@ -2083,6 +2085,23 @@ static void init_counter_refs(void) · 245 unmodified lines | ||
| 2083 | 2085 | this_cpu_write(arch_prev_mperf, mperf); |
| 2084 | 2086 | } |
| 2085 | 2087 | |
| 2088 | +#ifdef CONFIG_PM_SLEEP | |
| 2089 | +static struct syscore_ops freq_invariance_syscore_ops = { | |
| 2090 | + .resume = init_counter_refs, | |
| 2091 | +}; | |
| 2092 | + | |
| 2093 | +static void register_freq_invariance_syscore_ops(void) | |
| 2094 | +{ | |
| 2095 | + /* Bail out if registered already. */ | |
| 2096 | + if (freq_invariance_syscore_ops.node.prev) | |
| 2097 | + return; | |
| 2098 | + | |
| 2099 | + register_syscore_ops(&freq_invariance_syscore_ops); | |
| 2100 | +} | |
| 2101 | +#else | |
| 2102 | +static inline void register_freq_invariance_syscore_ops(void) {} | |
| 2103 | +#endif | |
| 2104 | + | |
| 2086 | 2105 | static void init_freq_invariance(bool secondary, bool cppc_ready) |
| 2087 | 2106 | { |
| 2088 | 2107 | bool ret = false; |
| @@ -2109,6 +2128,7 @@ static void init_freq_invariance(bool secondary, bool cppc_ready) · 20 unmodified lines | ||
| 2109 | 2128 | if (ret) { |
| 2110 | 2129 | init_counter_refs(); |
| 2111 | 2130 | static_branch_enable(&arch_scale_freq_key); |
| 2131 | + register_freq_invariance_syscore_ops(); | |
| 2112 | 2132 | pr_info("Estimated ratio of average max frequency by base frequency (times 1024): %llu\n", arch_max_freq_ratio); |
| 2113 | 2133 | } else { |
| 2114 | 2134 | pr_debug("Couldn't determine max cpu frequency, necessary for scale-invariant accounting.\n"); |
| @@ -127,12 +127,17 @@ static int enable_single_step(struct task_struct *child) · 126 unmodified lines | ||
| 127 | 127 | regs->flags |= X86_EFLAGS_TF; |
| 128 | 128 | |
| 129 | 129 | /* |
| 130 | − * Always set TIF_SINGLESTEP - this guarantees that | |
| 131 | − * we single-step system calls etc.. This will also | |
| 130 | + * Always set TIF_SINGLESTEP. This will also | |
| 132 | 131 | * cause us to set TF when returning to user mode. |
| 133 | 132 | */ |
| 134 | 133 | set_tsk_thread_flag(child, TIF_SINGLESTEP); |
| 135 | 134 | |
| 135 | + /* | |
| 136 | + * Ensure that a trap is triggered once stepping out of a system | |
| 137 | + * call prior to executing any user instruction. | |
| 138 | + */ | |
| 139 | + set_task_syscall_work(child, SYSCALL_EXIT_TRAP); | |
| 140 | + | |
| 136 | 141 | oflags = regs->flags; |
| 137 | 142 | |
| 138 | 143 | /* Set TF on the kernel stack.. */ |
| @@ -230,6 +235,7 @@ void user_disable_single_step(struct task_struct *child) · 91 unmodified lines | ||
| 230 | 235 | |
| 231 | 236 | /* Always clear TIF_SINGLESTEP... */ |
| 232 | 237 | clear_tsk_thread_flag(child, TIF_SINGLESTEP); |
| 238 | + clear_task_syscall_work(child, SYSCALL_EXIT_TRAP); | |
| 233 | 239 | |
| 234 | 240 | /* But touch TF only if it was set by us.. */ |
| 235 | 241 | if (test_and_clear_tsk_thread_flag(child, TIF_FORCED_TF)) |
| @@ -321,7 +321,7 @@ int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, · 320 unmodified lines | ||
| 321 | 321 | if (cpuid->nent < vcpu->arch.cpuid_nent) |
| 322 | 322 | goto out; |
| 323 | 323 | r = -EFAULT; |
| 324 | − if (copy_to_user(entries, &vcpu->arch.cpuid_entries, | |
| 324 | + if (copy_to_user(entries, vcpu->arch.cpuid_entries, | |
| 325 | 325 | vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2))) |
| 326 | 326 | goto out; |
| 327 | 327 | return 0; |
| @@ -2879,6 +2879,8 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt) · 2878 unmodified lines | ||
| 2879 | 2879 | ops->get_msr(ctxt, MSR_IA32_SYSENTER_ESP, &msr_data); |
| 2880 | 2880 | *reg_write(ctxt, VCPU_REGS_RSP) = (efer & EFER_LMA) ? msr_data : |
| 2881 | 2881 | (u32)msr_data; |
| 2882 | + if (efer & EFER_LMA) | |
| 2883 | + ctxt->mode = X86EMUL_MODE_PROT64; | |
| 2882 | 2884 | |
| 2883 | 2885 | return X86EMUL_CONTINUE; |
| 2884 | 2886 | } |
| @@ -9,31 +9,6 @@ · 8 unmodified lines | ||
| 9 | 9 | (X86_CR4_PVI | X86_CR4_DE | X86_CR4_PCE | X86_CR4_OSFXSR \ |
| 10 | 10 | | X86_CR4_OSXMMEXCPT | X86_CR4_PGE | X86_CR4_TSD | X86_CR4_FSGSBASE) |
| 11 | 11 | |
| 12 | −static inline bool kvm_register_is_available(struct kvm_vcpu *vcpu, | |
| 13 | − enum kvm_reg reg) | |
| 14 | −{ | |
| 15 | − return test_bit(reg, (unsigned long *)&vcpu->arch.regs_avail); | |
| 16 | −} | |
| 17 | − | |
| 18 | −static inline bool kvm_register_is_dirty(struct kvm_vcpu *vcpu, | |
| 19 | − enum kvm_reg reg) | |
| 20 | −{ | |
| 21 | − return test_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty); | |
| 22 | −} | |
| 23 | − | |
| 24 | −static inline void kvm_register_mark_available(struct kvm_vcpu *vcpu, | |
| 25 | − enum kvm_reg reg) | |
| 26 | −{ | |
| 27 | − __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail); | |
| 28 | −} | |
| 29 | − | |
| 30 | −static inline void kvm_register_mark_dirty(struct kvm_vcpu *vcpu, | |
| 31 | − enum kvm_reg reg) | |
| 32 | −{ | |
| 33 | − __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail); | |
| 34 | − __set_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty); | |
| 35 | −} | |
| 36 | − | |
| 37 | 12 | #define BUILD_KVM_GPR_ACCESSORS(lname, uname) \ |
| 38 | 13 | static __always_inline unsigned long kvm_##lname##_read(struct kvm_vcpu *vcpu)\ |
| 39 | 14 | { \ |
| @@ -43,7 +18,6 @@ static __always_inline void kvm_##lname##_write(struct kvm_vcpu *vcpu, \ · 3 unmodified lines | ||
| 43 | 18 | unsigned long val) \ |
| 44 | 19 | { \ |
| 45 | 20 | vcpu->arch.regs[VCPU_REGS_##uname] = val; \ |
| 46 | − kvm_register_mark_dirty(vcpu, VCPU_REGS_##uname); \ | |
| 47 | 21 | } |
| 48 | 22 | BUILD_KVM_GPR_ACCESSORS(rax, RAX) |
| 49 | 23 | BUILD_KVM_GPR_ACCESSORS(rbx, RBX) |
| @@ -63,6 +37,31 @@ BUILD_KVM_GPR_ACCESSORS(r14, R14) · 13 unmodified lines | ||
| 63 | 37 | BUILD_KVM_GPR_ACCESSORS(r15, R15) |
| 64 | 38 | #endif |
| 65 | 39 | |
| 40 | +static inline bool kvm_register_is_available(struct kvm_vcpu *vcpu, | |
| 41 | + enum kvm_reg reg) | |
| 42 | +{ | |
| 43 | + return test_bit(reg, (unsigned long *)&vcpu->arch.regs_avail); | |
| 44 | +} | |
| 45 | + | |
| 46 | +static inline bool kvm_register_is_dirty(struct kvm_vcpu *vcpu, | |
| 47 | + enum kvm_reg reg) | |
| 48 | +{ | |
| 49 | + return test_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty); | |
| 50 | +} | |
| 51 | + | |
| 52 | +static inline void kvm_register_mark_available(struct kvm_vcpu *vcpu, | |
| 53 | + enum kvm_reg reg) | |
| 54 | +{ | |
| 55 | + __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail); | |
| 56 | +} | |
| 57 | + | |
| 58 | +static inline void kvm_register_mark_dirty(struct kvm_vcpu *vcpu, | |
| 59 | + enum kvm_reg reg) | |
| 60 | +{ | |
| 61 | + __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail); | |
| 62 | + __set_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty); | |
| 63 | +} | |
| 64 | + | |
| 66 | 65 | static inline unsigned long kvm_register_read(struct kvm_vcpu *vcpu, int reg) |
| 67 | 66 | { |
| 68 | 67 | if (WARN_ON_ONCE((unsigned int)reg >= NR_VCPU_REGS)) |
| @@ -674,7 +674,7 @@ static bool pv_eoi_get_pending(struct kvm_vcpu *vcpu) · 673 unmodified lines | ||
| 674 | 674 | (unsigned long long)vcpu->arch.pv_eoi.msr_val); |
| 675 | 675 | return false; |
| 676 | 676 | } |
| 677 | − return val & 0x1; | |
| 677 | + return val & KVM_PV_EOI_ENABLED; | |
| 678 | 678 | } |
| 679 | 679 | |
| 680 | 680 | static void pv_eoi_set_pending(struct kvm_vcpu *vcpu) |
| @@ -2898,7 +2898,7 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu) · 2217 unmodified lines | ||
| 2898 | 2898 | /* evaluate pending_events before reading the vector */ |
| 2899 | 2899 | smp_rmb(); |
| 2900 | 2900 | sipi_vector = apic->sipi_vector; |
| 2901 | − kvm_vcpu_deliver_sipi_vector(vcpu, sipi_vector); | |
| 2901 | + kvm_x86_ops.vcpu_deliver_sipi_vector(vcpu, sipi_vector); | |
| 2902 | 2902 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; |
| 2903 | 2903 | } |
| 2904 | 2904 | } |
| @@ -44,12 +44,19 @@ · 43 unmodified lines | ||
| 44 | 44 | #define PT32_ROOT_LEVEL 2 |
| 45 | 45 | #define PT32E_ROOT_LEVEL 3 |
| 46 | 46 | |
| 47 | −static inline u64 rsvd_bits(int s, int e) | |
| 47 | +static __always_inline u64 rsvd_bits(int s, int e) | |
| 48 | 48 | { |
| 49 | + BUILD_BUG_ON(__builtin_constant_p(e) && __builtin_constant_p(s) && e < s); | |
| 50 | + | |
| 51 | + if (__builtin_constant_p(e)) | |
| 52 | + BUILD_BUG_ON(e > 63); | |
| 53 | + else | |
| 54 | + e &= 63; | |
| 55 | + | |
| 49 | 56 | if (e < s) |
| 50 | 57 | return 0; |
| 51 | 58 | |
| 52 | − return ((1ULL << (e - s + 1)) - 1) << s; | |
| 59 | + return ((2ULL << (e - s)) - 1) << s; | |
| 53 | 60 | } |
| 54 | 61 | |
| 55 | 62 | void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 access_mask); |
| @@ -3493,26 +3493,25 @@ static bool mmio_info_in_cache(struct kvm_vcpu *vcpu, u64 addr, bool direct) · 3492 unmodified lines | ||
| 3493 | 3493 | * Return the level of the lowest level SPTE added to sptes. |
| 3494 | 3494 | * That SPTE may be non-present. |
| 3495 | 3495 | */ |
| 3496 | −static int get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes) | |
| 3496 | +static int get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, int *root_level) | |
| 3497 | 3497 | { |
| 3498 | 3498 | struct kvm_shadow_walk_iterator iterator; |
| 3499 | − int leaf = vcpu->arch.mmu->root_level; | |
| 3499 | + int leaf = -1; | |
| 3500 | 3500 | u64 spte; |
| 3501 | 3501 | |
| 3502 | − | |
| 3503 | 3502 | walk_shadow_page_lockless_begin(vcpu); |
| 3504 | 3503 | |
| 3505 | − for (shadow_walk_init(&iterator, vcpu, addr); | |
| 3504 | + for (shadow_walk_init(&iterator, vcpu, addr), | |
| 3505 | + *root_level = iterator.level; | |
| 3506 | 3506 | shadow_walk_okay(&iterator); |
| 3507 | 3507 | __shadow_walk_next(&iterator, spte)) { |
| 3508 | 3508 | leaf = iterator.level; |
| 3509 | 3509 | spte = mmu_spte_get_lockless(iterator.sptep); |
| 3510 | 3510 | |
| 3511 | − sptes[leaf - 1] = spte; | |
| 3511 | + sptes[leaf] = spte; | |
| 3512 | 3512 | |
| 3513 | 3513 | if (!is_shadow_present_pte(spte)) |
| 3514 | 3514 | break; |
| 3515 | − | |
| 3516 | 3515 | } |
| 3517 | 3516 | |
| 3518 | 3517 | walk_shadow_page_lockless_end(vcpu); |
| @@ -3520,14 +3519,12 @@ static int get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes) · 1 unmodified line | ||
| 3520 | 3519 | return leaf; |
| 3521 | 3520 | } |
| 3522 | 3521 | |
| 3523 | −/* return true if reserved bit is detected on spte. */ | |
| 3522 | +/* return true if reserved bit(s) are detected on a valid, non-MMIO SPTE. */ | |
| 3524 | 3523 | static bool get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr, u64 *sptep) |
| 3525 | 3524 | { |
| 3526 | − u64 sptes[PT64_ROOT_MAX_LEVEL]; | |
| 3525 | + u64 sptes[PT64_ROOT_MAX_LEVEL + 1]; | |
| 3527 | 3526 | struct rsvd_bits_validate *rsvd_check; |
| 3528 | − int root = vcpu->arch.mmu->shadow_root_level; | |
| 3529 | − int leaf; | |
| 3530 | − int level; | |
| 3527 | + int root, leaf, level; | |
| 3531 | 3528 | bool reserved = false; |
| 3532 | 3529 | |
| 3533 | 3530 | if (!VALID_PAGE(vcpu->arch.mmu->root_hpa)) { |
| @@ -3536,35 +3533,45 @@ static bool get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr, u64 *sptep) · 2 unmodified lines | ||
| 3536 | 3533 | } |
| 3537 | 3534 | |
| 3538 | 3535 | if (is_tdp_mmu_root(vcpu->kvm, vcpu->arch.mmu->root_hpa)) |
| 3539 | − leaf = kvm_tdp_mmu_get_walk(vcpu, addr, sptes); | |
| 3536 | + leaf = kvm_tdp_mmu_get_walk(vcpu, addr, sptes, &root); | |
| 3540 | 3537 | else |
| 3541 | − leaf = get_walk(vcpu, addr, sptes); | |
| 3538 | + leaf = get_walk(vcpu, addr, sptes, &root); | |
| 3539 | + | |
| 3540 | + if (unlikely(leaf < 0)) { | |
| 3541 | + *sptep = 0ull; | |
| 3542 | + return reserved; | |
| 3543 | + } | |
| 3544 | + | |
| 3545 | + *sptep = sptes[leaf]; | |
| 3546 | + | |
| 3547 | + /* | |
| 3548 | + * Skip reserved bits checks on the terminal leaf if it's not a valid | |
| 3549 | + * SPTE. Note, this also (intentionally) skips MMIO SPTEs, which, by | |
| 3550 | + * design, always have reserved bits set. The purpose of the checks is | |
| 3551 | + * to detect reserved bits on non-MMIO SPTEs. i.e. buggy SPTEs. | |
| 3552 | + */ | |
| 3553 | + if (!is_shadow_present_pte(sptes[leaf])) | |
| 3554 | + leaf++; | |
| 3542 | 3555 | |
| 3543 | 3556 | rsvd_check = &vcpu->arch.mmu->shadow_zero_check; |
| 3544 | 3557 | |
| 3545 | − for (level = root; level >= leaf; level--) { | |
| 3546 | − if (!is_shadow_present_pte(sptes[level - 1])) | |
| 3547 | − break; | |
| 3558 | + for (level = root; level >= leaf; level--) | |
| 3548 | 3559 | /* |
| 3549 | 3560 | * Use a bitwise-OR instead of a logical-OR to aggregate the |
| 3550 | 3561 | * reserved bit and EPT's invalid memtype/XWR checks to avoid |
| 3551 | 3562 | * adding a Jcc in the loop. |
| 3552 | 3563 | */ |
| 3553 | − reserved |= __is_bad_mt_xwr(rsvd_check, sptes[level - 1]) | | |
| 3554 | − __is_rsvd_bits_set(rsvd_check, sptes[level - 1], | |
| 3555 | − level); | |
| 3556 | − } | |
| 3564 | + reserved |= __is_bad_mt_xwr(rsvd_check, sptes[level]) | | |
| 3565 | + __is_rsvd_bits_set(rsvd_check, sptes[level], level); | |
| 3557 | 3566 | |
| 3558 | 3567 | if (reserved) { |
| 3559 | 3568 | pr_err("%s: detect reserved bits on spte, addr 0x%llx, dump hierarchy:\n", |
| 3560 | 3569 | __func__, addr); |
| 3561 | 3570 | for (level = root; level >= leaf; level--) |
| 3562 | 3571 | pr_err("------ spte 0x%llx level %d.\n", |
| 3563 | − sptes[level - 1], level); | |
| 3572 | + sptes[level], level); | |
| 3564 | 3573 | } |
| 3565 | 3574 | |
| 3566 | − *sptep = sptes[leaf - 1]; | |
| 3567 | − | |
| 3568 | 3575 | return reserved; |
| 3569 | 3576 | } |
| 3570 | 3577 | |
| @@ -44,7 +44,48 @@ void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm) · 43 unmodified lines | ||
| 44 | 44 | WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots)); |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | −#define for_each_tdp_mmu_root(_kvm, _root) \ | |
| 47 | +static void tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root) | |
| 48 | +{ | |
| 49 | + if (kvm_mmu_put_root(kvm, root)) | |
| 50 | + kvm_tdp_mmu_free_root(kvm, root); | |
| 51 | +} | |
| 52 | + | |
| 53 | +static inline bool tdp_mmu_next_root_valid(struct kvm *kvm, | |
| 54 | + struct kvm_mmu_page *root) | |
| 55 | +{ | |
| 56 | + lockdep_assert_held(&kvm->mmu_lock); | |
| 57 | + | |
| 58 | + if (list_entry_is_head(root, &kvm->arch.tdp_mmu_roots, link)) | |
| 59 | + return false; | |
| 60 | + | |
| 61 | + kvm_mmu_get_root(kvm, root); | |
| 62 | + return true; | |
| 63 | + | |
| 64 | +} | |
| 65 | + | |
| 66 | +static inline struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm, | |
| 67 | + struct kvm_mmu_page *root) | |
| 68 | +{ | |
| 69 | + struct kvm_mmu_page *next_root; | |
| 70 | + | |
| 71 | + next_root = list_next_entry(root, link); | |
| 72 | + tdp_mmu_put_root(kvm, root); | |
| 73 | + return next_root; | |
| 74 | +} | |
| 75 | + | |
| 76 | +/* | |
| 77 | + * Note: this iterator gets and puts references to the roots it iterates over. | |
| 78 | + * This makes it safe to release the MMU lock and yield within the loop, but | |
| 79 | + * if exiting the loop early, the caller must drop the reference to the most | |
| 80 | + * recent root. (Unless keeping a live reference is desirable.) | |
| 81 | + */ | |
| 82 | +#define for_each_tdp_mmu_root_yield_safe(_kvm, _root) \ | |
| 83 | + for (_root = list_first_entry(&_kvm->arch.tdp_mmu_roots, \ | |
| 84 | + typeof(*_root), link); \ | |
| 85 | + tdp_mmu_next_root_valid(_kvm, _root); \ | |
| 86 | + _root = tdp_mmu_next_root(_kvm, _root)) | |
| 87 | + | |
| 88 | +#define for_each_tdp_mmu_root(_kvm, _root) \ | |
| 48 | 89 | list_for_each_entry(_root, &_kvm->arch.tdp_mmu_roots, link) |
| 49 | 90 | |
| 50 | 91 | bool is_tdp_mmu_root(struct kvm *kvm, hpa_t hpa) |
| @@ -447,18 +488,9 @@ bool kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t start, gfn_t end) · 396 unmodified lines | ||
| 447 | 488 | struct kvm_mmu_page *root; |
| 448 | 489 | bool flush = false; |
| 449 | 490 | |
| 450 | − for_each_tdp_mmu_root(kvm, root) { | |
| 451 | − /* | |
| 452 | − * Take a reference on the root so that it cannot be freed if | |
| 453 | − * this thread releases the MMU lock and yields in this loop. | |
| 454 | − */ | |
| 455 | − kvm_mmu_get_root(kvm, root); | |
| 456 | − | |
| 491 | + for_each_tdp_mmu_root_yield_safe(kvm, root) | |
| 457 | 492 | flush |= zap_gfn_range(kvm, root, start, end, true); |
| 458 | 493 | |
| 459 | − kvm_mmu_put_root(kvm, root); | |
| 460 | − } | |
| 461 | − | |
| 462 | 494 | return flush; |
| 463 | 495 | } |
| 464 | 496 | |
| @@ -619,13 +651,7 @@ static int kvm_tdp_mmu_handle_hva_range(struct kvm *kvm, unsigned long start, · 154 unmodified lines | ||
| 619 | 651 | int ret = 0; |
| 620 | 652 | int as_id; |
| 621 | 653 | |
| 622 | − for_each_tdp_mmu_root(kvm, root) { | |
| 623 | − /* | |
| 624 | − * Take a reference on the root so that it cannot be freed if | |
| 625 | − * this thread releases the MMU lock and yields in this loop. | |
| 626 | − */ | |
| 627 | − kvm_mmu_get_root(kvm, root); | |
| 628 | − | |
| 654 | + for_each_tdp_mmu_root_yield_safe(kvm, root) { | |
| 629 | 655 | as_id = kvm_mmu_page_as_id(root); |
| 630 | 656 | slots = __kvm_memslots(kvm, as_id); |
| 631 | 657 | kvm_for_each_memslot(memslot, slots) { |
| @@ -647,8 +673,6 @@ static int kvm_tdp_mmu_handle_hva_range(struct kvm *kvm, unsigned long start, · 15 unmodified lines | ||
| 647 | 673 | ret |= handler(kvm, memslot, root, gfn_start, |
| 648 | 674 | gfn_end, data); |
| 649 | 675 | } |
| 650 | − | |
| 651 | − kvm_mmu_put_root(kvm, root); | |
| 652 | 676 | } |
| 653 | 677 | |
| 654 | 678 | return ret; |
| @@ -838,21 +862,13 @@ bool kvm_tdp_mmu_wrprot_slot(struct kvm *kvm, struct kvm_memory_slot *slot, · 183 unmodified lines | ||
| 838 | 862 | int root_as_id; |
| 839 | 863 | bool spte_set = false; |
| 840 | 864 | |
| 841 | − for_each_tdp_mmu_root(kvm, root) { | |
| 865 | + for_each_tdp_mmu_root_yield_safe(kvm, root) { | |
| 842 | 866 | root_as_id = kvm_mmu_page_as_id(root); |
| 843 | 867 | if (root_as_id != slot->as_id) |
| 844 | 868 | continue; |
| 845 | 869 | |
| 846 | − /* | |
| 847 | − * Take a reference on the root so that it cannot be freed if | |
| 848 | − * this thread releases the MMU lock and yields in this loop. | |
| 849 | − */ | |
| 850 | − kvm_mmu_get_root(kvm, root); | |
| 851 | − | |
| 852 | 870 | spte_set |= wrprot_gfn_range(kvm, root, slot->base_gfn, |
| 853 | 871 | slot->base_gfn + slot->npages, min_level); |
| 854 | − | |
| 855 | − kvm_mmu_put_root(kvm, root); | |
| 856 | 872 | } |
| 857 | 873 | |
| 858 | 874 | return spte_set; |
| @@ -906,21 +922,13 @@ bool kvm_tdp_mmu_clear_dirty_slot(struct kvm *kvm, struct kvm_memory_slot *slot) · 47 unmodified lines | ||
| 906 | 922 | int root_as_id; |
| 907 | 923 | bool spte_set = false; |
| 908 | 924 | |
| 909 | − for_each_tdp_mmu_root(kvm, root) { | |
| 925 | + for_each_tdp_mmu_root_yield_safe(kvm, root) { | |
| 910 | 926 | root_as_id = kvm_mmu_page_as_id(root); |
| 911 | 927 | if (root_as_id != slot->as_id) |
| 912 | 928 | continue; |
| 913 | 929 | |
| 914 | − /* | |
| 915 | − * Take a reference on the root so that it cannot be freed if | |
| 916 | − * this thread releases the MMU lock and yields in this loop. | |
| 917 | − */ | |
| 918 | − kvm_mmu_get_root(kvm, root); | |
| 919 | − | |
| 920 | 930 | spte_set |= clear_dirty_gfn_range(kvm, root, slot->base_gfn, |
| 921 | 931 | slot->base_gfn + slot->npages); |
| 922 | − | |
| 923 | − kvm_mmu_put_root(kvm, root); | |
| 924 | 932 | } |
| 925 | 933 | |
| 926 | 934 | return spte_set; |
| @@ -1029,28 +1037,20 @@ bool kvm_tdp_mmu_slot_set_dirty(struct kvm *kvm, struct kvm_memory_slot *slot) · 102 unmodified lines | ||
| 1029 | 1037 | int root_as_id; |
| 1030 | 1038 | bool spte_set = false; |
| 1031 | 1039 | |
| 1032 | − for_each_tdp_mmu_root(kvm, root) { | |
| 1040 | + for_each_tdp_mmu_root_yield_safe(kvm, root) { | |
| 1033 | 1041 | root_as_id = kvm_mmu_page_as_id(root); |
| 1034 | 1042 | if (root_as_id != slot->as_id) |
| 1035 | 1043 | continue; |
| 1036 | 1044 | |
| 1037 | − /* | |
| 1038 | − * Take a reference on the root so that it cannot be freed if | |
| 1039 | − * this thread releases the MMU lock and yields in this loop. | |
| 1040 | − */ | |
| 1041 | − kvm_mmu_get_root(kvm, root); | |
| 1042 | − | |
| 1043 | 1045 | spte_set |= set_dirty_gfn_range(kvm, root, slot->base_gfn, |
| 1044 | 1046 | slot->base_gfn + slot->npages); |
| 1045 | − | |
| 1046 | − kvm_mmu_put_root(kvm, root); | |
| 1047 | 1047 | } |
| 1048 | 1048 | return spte_set; |
| 1049 | 1049 | } |
| 1050 | 1050 | |
| 1051 | 1051 | /* |
| 1052 | − * Clear non-leaf entries (and free associated page tables) which could | |
| 1053 | − * be replaced by large mappings, for GFNs within the slot. | |
| 1052 | + * Clear leaf entries which could be replaced by large mappings, for | |
| 1053 | + * GFNs within the slot. | |
| 1054 | 1054 | */ |
| 1055 | 1055 | static void zap_collapsible_spte_range(struct kvm *kvm, |
| 1056 | 1056 | struct kvm_mmu_page *root, |
| @@ -1062,7 +1062,7 @@ static void zap_collapsible_spte_range(struct kvm *kvm, · 5 unmodified lines | ||
| 1062 | 1062 | |
| 1063 | 1063 | tdp_root_for_each_pte(iter, root, start, end) { |
| 1064 | 1064 | if (!is_shadow_present_pte(iter.old_spte) || |
| 1065 | − is_last_spte(iter.old_spte, iter.level)) | |
| 1065 | + !is_last_spte(iter.old_spte, iter.level)) | |
| 1066 | 1066 | continue; |
| 1067 | 1067 | |
| 1068 | 1068 | pfn = spte_to_pfn(iter.old_spte); |
| @@ -1089,21 +1089,13 @@ void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, · 20 unmodified lines | ||
| 1089 | 1089 | struct kvm_mmu_page *root; |
| 1090 | 1090 | int root_as_id; |
| 1091 | 1091 | |
| 1092 | − for_each_tdp_mmu_root(kvm, root) { | |
| 1092 | + for_each_tdp_mmu_root_yield_safe(kvm, root) { | |
| 1093 | 1093 | root_as_id = kvm_mmu_page_as_id(root); |
| 1094 | 1094 | if (root_as_id != slot->as_id) |
| 1095 | 1095 | continue; |
| 1096 | 1096 | |
| 1097 | − /* | |
| 1098 | − * Take a reference on the root so that it cannot be freed if | |
| 1099 | − * this thread releases the MMU lock and yields in this loop. | |
| 1100 | − */ | |
| 1101 | − kvm_mmu_get_root(kvm, root); | |
| 1102 | − | |
| 1103 | 1097 | zap_collapsible_spte_range(kvm, root, slot->base_gfn, |
| 1104 | 1098 | slot->base_gfn + slot->npages); |
| 1105 | − | |
| 1106 | − kvm_mmu_put_root(kvm, root); | |
| 1107 | 1099 | } |
| 1108 | 1100 | } |
| 1109 | 1101 | |
| @@ -1160,16 +1152,19 @@ bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, · 50 unmodified lines | ||
| 1160 | 1152 | * Return the level of the lowest level SPTE added to sptes. |
| 1161 | 1153 | * That SPTE may be non-present. |
| 1162 | 1154 | */ |
| 1163 | −int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes) | |
| 1155 | +int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, | |
| 1156 | + int *root_level) | |
| 1164 | 1157 | { |
| 1165 | 1158 | struct tdp_iter iter; |
| 1166 | 1159 | struct kvm_mmu *mmu = vcpu->arch.mmu; |
| 1167 | − int leaf = vcpu->arch.mmu->shadow_root_level; | |
| 1168 | 1160 | gfn_t gfn = addr >> PAGE_SHIFT; |
| 1161 | + int leaf = -1; | |
| 1162 | + | |
| 1163 | + *root_level = vcpu->arch.mmu->shadow_root_level; | |
| 1169 | 1164 | |
| 1170 | 1165 | tdp_mmu_for_each_pte(iter, mmu, gfn, gfn + 1) { |
| 1171 | 1166 | leaf = iter.level; |
| 1172 | − sptes[leaf - 1] = iter.old_spte; | |
| 1167 | + sptes[leaf] = iter.old_spte; | |
| 1173 | 1168 | } |
| 1174 | 1169 | |
| 1175 | 1170 | return leaf; |
| @@ -44,5 +44,7 @@ void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, · 43 unmodified lines | ||
| 44 | 44 | bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, |
| 45 | 45 | struct kvm_memory_slot *slot, gfn_t gfn); |
| 46 | 46 | |
| 47 | −int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes); | |
| 47 | +int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, | |
| 48 | + int *root_level); | |
| 49 | + | |
| 48 | 50 | #endif /* __KVM_X86_MMU_TDP_MMU_H */ |
| @@ -199,6 +199,10 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) · 198 unmodified lines | ||
| 199 | 199 | static bool svm_get_nested_state_pages(struct kvm_vcpu *vcpu) |
| 200 | 200 | { |
| 201 | 201 | struct vcpu_svm *svm = to_svm(vcpu); |
| 202 | + | |
| 203 | + if (WARN_ON(!is_guest_mode(vcpu))) | |
| 204 | + return true; | |
| 205 | + | |
| 202 | 206 | if (!nested_svm_vmrun_msrpm(svm)) { |
| 203 | 207 | vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; |
| 204 | 208 | vcpu->run->internal.suberror = |
| @@ -227,6 +231,7 @@ static bool nested_vmcb_check_controls(struct vmcb_control_area *control) · 22 unmodified lines | ||
| 227 | 231 | |
| 228 | 232 | static bool nested_vmcb_checks(struct vcpu_svm *svm, struct vmcb *vmcb12) |
| 229 | 233 | { |
| 234 | + struct kvm_vcpu *vcpu = &svm->vcpu; | |
| 230 | 235 | bool vmcb12_lma; |
| 231 | 236 | |
| 232 | 237 | if ((vmcb12->save.efer & EFER_SVME) == 0) |
| @@ -240,18 +245,10 @@ static bool nested_vmcb_checks(struct vcpu_svm *svm, struct vmcb *vmcb12) · 7 unmodified lines | ||
| 240 | 245 | |
| 241 | 246 | vmcb12_lma = (vmcb12->save.efer & EFER_LME) && (vmcb12->save.cr0 & X86_CR0_PG); |
| 242 | 247 | |
| 243 | − if (!vmcb12_lma) { | |
| 244 | − if (vmcb12->save.cr4 & X86_CR4_PAE) { | |
| 245 | − if (vmcb12->save.cr3 & MSR_CR3_LEGACY_PAE_RESERVED_MASK) | |
| 246 | − return false; | |
| 247 | − } else { | |
| 248 | − if (vmcb12->save.cr3 & MSR_CR3_LEGACY_RESERVED_MASK) | |
| 249 | − return false; | |
| 250 | − } | |
| 251 | − } else { | |
| 248 | + if (vmcb12_lma) { | |
| 252 | 249 | if (!(vmcb12->save.cr4 & X86_CR4_PAE) || |
| 253 | 250 | !(vmcb12->save.cr0 & X86_CR0_PE) || |
| 254 | − (vmcb12->save.cr3 & MSR_CR3_LONG_MBZ_MASK)) | |
| 251 | + (vmcb12->save.cr3 & vcpu->arch.cr3_lm_rsvd_bits)) | |
| 255 | 252 | return false; |
| 256 | 253 | } |
| 257 | 254 | if (!kvm_is_valid_cr4(&svm->vcpu, vmcb12->save.cr4)) |
| @@ -595,6 +592,8 @@ int nested_svm_vmexit(struct vcpu_svm *svm) · 337 unmodified lines | ||
| 595 | 592 | svm->nested.vmcb12_gpa = 0; |
| 596 | 593 | WARN_ON_ONCE(svm->nested.nested_run_pending); |
| 597 | 594 | |
| 595 | + kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, &svm->vcpu); | |
| 596 | + | |
| 598 | 597 | /* in case we halted in L2 */ |
| 599 | 598 | svm->vcpu.arch.mp_state = KVM_MP_STATE_RUNNABLE; |
| 600 | 599 | |
| @@ -754,6 +753,7 @@ void svm_leave_nested(struct vcpu_svm *svm) · 153 unmodified lines | ||
| 754 | 753 | leave_guest_mode(&svm->vcpu); |
| 755 | 754 | copy_vmcb_control_area(&vmcb->control, &hsave->control); |
| 756 | 755 | nested_svm_uninit_mmu_context(&svm->vcpu); |
| 756 | + vmcb_mark_all_dirty(svm->vmcb); | |
| 757 | 757 | } |
| 758 | 758 | |
| 759 | 759 | kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, &svm->vcpu); |
| @@ -1194,6 +1194,10 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, · 434 unmodified lines | ||
| 1194 | 1194 | * in the registers, the save area of the nested state instead |
| 1195 | 1195 | * contains saved L1 state. |
| 1196 | 1196 | */ |
| 1197 | + | |
| 1198 | + svm->nested.nested_run_pending = | |
| 1199 | + !!(kvm_state->flags & KVM_STATE_NESTED_RUN_PENDING); | |
| 1200 | + | |
| 1197 | 1201 | copy_vmcb_control_area(&hsave->control, &svm->vmcb->control); |
| 1198 | 1202 | hsave->save = *save; |
| 1199 | 1203 | |
| @@ -342,6 +342,8 @@ static struct page **sev_pin_memory(struct kvm *kvm, unsigned long uaddr, · 341 unmodified lines | ||
| 342 | 342 | unsigned long first, last; |
| 343 | 343 | int ret; |
| 344 | 344 | |
| 345 | + lockdep_assert_held(&kvm->lock); | |
| 346 | + | |
| 345 | 347 | if (ulen == 0 || uaddr + ulen < uaddr) |
| 346 | 348 | return ERR_PTR(-EINVAL); |
| 347 | 349 | |
| @@ -1119,12 +1121,20 @@ int svm_register_enc_region(struct kvm *kvm, · 771 unmodified lines | ||
| 1119 | 1121 | if (!region) |
| 1120 | 1122 | return -ENOMEM; |
| 1121 | 1123 | |
| 1124 | + mutex_lock(&kvm->lock); | |
| 1122 | 1125 | region->pages = sev_pin_memory(kvm, range->addr, range->size, ®ion->npages, 1); |
| 1123 | 1126 | if (IS_ERR(region->pages)) { |
| 1124 | 1127 | ret = PTR_ERR(region->pages); |
| 1128 | + mutex_unlock(&kvm->lock); | |
| 1125 | 1129 | goto e_free; |
| 1126 | 1130 | } |
| 1127 | 1131 | |
| 1132 | + region->uaddr = range->addr; | |
| 1133 | + region->size = range->size; | |
| 1134 | + | |
| 1135 | + list_add_tail(®ion->list, &sev->regions_list); | |
| 1136 | + mutex_unlock(&kvm->lock); | |
| 1137 | + | |
| 1128 | 1138 | /* |
| 1129 | 1139 | * The guest may change the memory encryption attribute from C=0 -> C=1 |
| 1130 | 1140 | * or vice versa for this memory range. Lets make sure caches are |
| @@ -1133,13 +1143,6 @@ int svm_register_enc_region(struct kvm *kvm, · 2 unmodified lines | ||
| 1133 | 1143 | */ |
| 1134 | 1144 | sev_clflush_pages(region->pages, region->npages); |
| 1135 | 1145 | |
| 1136 | − region->uaddr = range->addr; | |
| 1137 | − region->size = range->size; | |
| 1138 | − | |
| 1139 | − mutex_lock(&kvm->lock); | |
| 1140 | − list_add_tail(®ion->list, &sev->regions_list); | |
| 1141 | − mutex_unlock(&kvm->lock); | |
| 1142 | − | |
| 1143 | 1146 | return ret; |
| 1144 | 1147 | |
| 1145 | 1148 | e_free: |
| @@ -1415,16 +1418,13 @@ static void sev_es_sync_to_ghcb(struct vcpu_svm *svm) · 269 unmodified lines | ||
| 1415 | 1418 | * to be returned: |
| 1416 | 1419 | * GPRs RAX, RBX, RCX, RDX |
| 1417 | 1420 | * |
| 1418 | − * Copy their values to the GHCB if they are dirty. | |
| 1421 | + * Copy their values, even if they may not have been written during the | |
| 1422 | + * VM-Exit. It's the guest's responsibility to not consume random data. | |
| 1419 | 1423 | */ |
| 1420 | − if (kvm_register_is_dirty(vcpu, VCPU_REGS_RAX)) | |
| 1421 | − ghcb_set_rax(ghcb, vcpu->arch.regs[VCPU_REGS_RAX]); | |
| 1422 | − if (kvm_register_is_dirty(vcpu, VCPU_REGS_RBX)) | |
| 1423 | − ghcb_set_rbx(ghcb, vcpu->arch.regs[VCPU_REGS_RBX]); | |
| 1424 | − if (kvm_register_is_dirty(vcpu, VCPU_REGS_RCX)) | |
| 1425 | − ghcb_set_rcx(ghcb, vcpu->arch.regs[VCPU_REGS_RCX]); | |
| 1426 | − if (kvm_register_is_dirty(vcpu, VCPU_REGS_RDX)) | |
| 1427 | − ghcb_set_rdx(ghcb, vcpu->arch.regs[VCPU_REGS_RDX]); | |
| 1424 | + ghcb_set_rax(ghcb, vcpu->arch.regs[VCPU_REGS_RAX]); | |
| 1425 | + ghcb_set_rbx(ghcb, vcpu->arch.regs[VCPU_REGS_RBX]); | |
| 1426 | + ghcb_set_rcx(ghcb, vcpu->arch.regs[VCPU_REGS_RCX]); | |
| 1427 | + ghcb_set_rdx(ghcb, vcpu->arch.regs[VCPU_REGS_RDX]); | |
| 1428 | 1428 | } |
| 1429 | 1429 | |
| 1430 | 1430 | static void sev_es_sync_from_ghcb(struct vcpu_svm *svm) |
| @@ -1563,6 +1563,7 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) · 132 unmodified lines | ||
| 1563 | 1563 | goto vmgexit_err; |
| 1564 | 1564 | break; |
| 1565 | 1565 | case SVM_VMGEXIT_NMI_COMPLETE: |
| 1566 | + case SVM_VMGEXIT_AP_HLT_LOOP: | |
| 1566 | 1567 | case SVM_VMGEXIT_AP_JUMP_TABLE: |
| 1567 | 1568 | case SVM_VMGEXIT_UNSUPPORTED_EVENT: |
| 1568 | 1569 | break; |
| @@ -1888,6 +1889,9 @@ int sev_handle_vmgexit(struct vcpu_svm *svm) · 319 unmodified lines | ||
| 1888 | 1889 | case SVM_VMGEXIT_NMI_COMPLETE: |
| 1889 | 1890 | ret = svm_invoke_exit_handler(svm, SVM_EXIT_IRET); |
| 1890 | 1891 | break; |
| 1892 | + case SVM_VMGEXIT_AP_HLT_LOOP: | |
| 1893 | + ret = kvm_emulate_ap_reset_hold(&svm->vcpu); | |
| 1894 | + break; | |
| 1891 | 1895 | case SVM_VMGEXIT_AP_JUMP_TABLE: { |
| 1892 | 1896 | struct kvm_sev_info *sev = &to_kvm_svm(svm->vcpu.kvm)->sev_info; |
| 1893 | 1897 | |
| @@ -2001,7 +2005,7 @@ void sev_es_vcpu_load(struct vcpu_svm *svm, int cpu) · 107 unmodified lines | ||
| 2001 | 2005 | * of which one step is to perform a VMLOAD. Since hardware does not |
| 2002 | 2006 | * perform a VMSAVE on VMRUN, the host savearea must be updated. |
| 2003 | 2007 | */ |
| 2004 | − asm volatile(__ex("vmsave") : : "a" (__sme_page_pa(sd->save_area)) : "memory"); | |
| 2008 | + asm volatile(__ex("vmsave %0") : : "a" (__sme_page_pa(sd->save_area)) : "memory"); | |
| 2005 | 2009 | |
| 2006 | 2010 | /* |
| 2007 | 2011 | * Certain MSRs are restored on VMEXIT, only save ones that aren't |
| @@ -2040,3 +2044,21 @@ void sev_es_vcpu_put(struct vcpu_svm *svm) · 32 unmodified lines | ||
| 2040 | 2044 | wrmsrl(host_save_user_msrs[i].index, svm->host_user_msrs[i]); |
| 2041 | 2045 | } |
| 2042 | 2046 | } |
| 2047 | + | |
| 2048 | +void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector) | |
| 2049 | +{ | |
| 2050 | + struct vcpu_svm *svm = to_svm(vcpu); | |
| 2051 | + | |
| 2052 | + /* First SIPI: Use the values as initially set by the VMM */ | |
| 2053 | + if (!svm->received_first_sipi) { | |
| 2054 | + svm->received_first_sipi = true; | |
| 2055 | + return; | |
| 2056 | + } | |
| 2057 | + | |
| 2058 | + /* | |
| 2059 | + * Subsequent SIPI: Return from an AP Reset Hold VMGEXIT, where | |
| 2060 | + * the guest will set the CS and RIP. Set SW_EXIT_INFO_2 to a | |
| 2061 | + * non-zero value. | |
| 2062 | + */ | |
| 2063 | + ghcb_set_sw_exit_info_2(svm->ghcb, 1); | |
| 2064 | +} | |
| @@ -454,6 +454,11 @@ static int has_svm(void) · 453 unmodified lines | ||
| 454 | 454 | return 0; |
| 455 | 455 | } |
| 456 | 456 | |
| 457 | + if (sev_active()) { | |
| 458 | + pr_info("KVM is unsupported when running as an SEV guest\n"); | |
| 459 | + return 0; | |
| 460 | + } | |
| 461 | + | |
| 457 | 462 | return 1; |
| 458 | 463 | } |
| 459 | 464 | |
| @@ -3677,8 +3682,6 @@ static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu) · 3217 unmodified lines | ||
| 3677 | 3682 | return EXIT_FASTPATH_NONE; |
| 3678 | 3683 | } |
| 3679 | 3684 | |
| 3680 | −void __svm_vcpu_run(unsigned long vmcb_pa, unsigned long *regs); | |
| 3681 | − | |
| 3682 | 3685 | static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu, |
| 3683 | 3686 | struct vcpu_svm *svm) |
| 3684 | 3687 | { |
| @@ -3741,6 +3744,8 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) · 56 unmodified lines | ||
| 3741 | 3744 | { |
| 3742 | 3745 | struct vcpu_svm *svm = to_svm(vcpu); |
| 3743 | 3746 | |
| 3747 | + trace_kvm_entry(vcpu); | |
| 3748 | + | |
| 3744 | 3749 | svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX]; |
| 3745 | 3750 | svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP]; |
| 3746 | 3751 | svm->vmcb->save.rip = vcpu->arch.regs[VCPU_REGS_RIP]; |
| @@ -4384,6 +4389,14 @@ static bool svm_apic_init_signal_blocked(struct kvm_vcpu *vcpu) · 637 unmodified lines | ||
| 4384 | 4389 | (vmcb_is_intercept(&svm->vmcb->control, INTERCEPT_INIT)); |
| 4385 | 4390 | } |
| 4386 | 4391 | |
| 4392 | +static void svm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector) | |
| 4393 | +{ | |
| 4394 | + if (!sev_es_guest(vcpu->kvm)) | |
| 4395 | + return kvm_vcpu_deliver_sipi_vector(vcpu, vector); | |
| 4396 | + | |
| 4397 | + sev_vcpu_deliver_sipi_vector(vcpu, vector); | |
| 4398 | +} | |
| 4399 | + | |
| 4387 | 4400 | static void svm_vm_destroy(struct kvm *kvm) |
| 4388 | 4401 | { |
| 4389 | 4402 | avic_vm_destroy(kvm); |
| @@ -4526,6 +4539,8 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { · 136 unmodified lines | ||
| 4526 | 4539 | |
| 4527 | 4540 | .msr_filter_changed = svm_msr_filter_changed, |
| 4528 | 4541 | .complete_emulated_msr = svm_complete_emulated_msr, |
| 4542 | + | |
| 4543 | + .vcpu_deliver_sipi_vector = svm_vcpu_deliver_sipi_vector, | |
| 4529 | 4544 | }; |
| 4530 | 4545 | |
| 4531 | 4546 | static struct kvm_x86_init_ops svm_init_ops __initdata = { |
| @@ -185,6 +185,7 @@ struct vcpu_svm { · 184 unmodified lines | ||
| 185 | 185 | struct vmcb_save_area *vmsa; |
| 186 | 186 | struct ghcb *ghcb; |
| 187 | 187 | struct kvm_host_map ghcb_map; |
| 188 | + bool received_first_sipi; | |
| 188 | 189 | |
| 189 | 190 | /* SEV-ES scratch area support */ |
| 190 | 191 | void *ghcb_sa; |
| @@ -402,9 +403,6 @@ static inline bool gif_set(struct vcpu_svm *svm) · 211 unmodified lines | ||
| 402 | 403 | } |
| 403 | 404 | |
| 404 | 405 | /* svm.c */ |
| 405 | −#define MSR_CR3_LEGACY_RESERVED_MASK 0xfe7U | |
| 406 | −#define MSR_CR3_LEGACY_PAE_RESERVED_MASK 0x7U | |
| 407 | −#define MSR_CR3_LONG_MBZ_MASK 0xfff0000000000000U | |
| 408 | 406 | #define MSR_INVALID 0xffffffffU |
| 409 | 407 | |
| 410 | 408 | extern int sev; |
| @@ -591,6 +589,7 @@ void sev_es_init_vmcb(struct vcpu_svm *svm); · 180 unmodified lines | ||
| 591 | 589 | void sev_es_create_vcpu(struct vcpu_svm *svm); |
| 592 | 590 | void sev_es_vcpu_load(struct vcpu_svm *svm, int cpu); |
| 593 | 591 | void sev_es_vcpu_put(struct vcpu_svm *svm); |
| 592 | +void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector); | |
| 594 | 593 | |
| 595 | 594 | /* vmenter.S */ |
| 596 | 595 | |
| @@ -3124,13 +3124,9 @@ static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu) · 3123 unmodified lines | ||
| 3124 | 3124 | return 0; |
| 3125 | 3125 | } |
| 3126 | 3126 | |
| 3127 | −static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu) | |
| 3127 | +static bool nested_get_evmcs_page(struct kvm_vcpu *vcpu) | |
| 3128 | 3128 | { |
| 3129 | − struct vmcs12 *vmcs12 = get_vmcs12(vcpu); | |
| 3130 | 3129 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| 3131 | − struct kvm_host_map *map; | |
| 3132 | − struct page *page; | |
| 3133 | − u64 hpa; | |
| 3134 | 3130 | |
| 3135 | 3131 | /* |
| 3136 | 3132 | * hv_evmcs may end up being not mapped after migration (when |
| @@ -3153,6 +3149,17 @@ static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu) · 16 unmodified lines | ||
| 3153 | 3149 | } |
| 3154 | 3150 | } |
| 3155 | 3151 | |
| 3152 | + return true; | |
| 3153 | +} | |
| 3154 | + | |
| 3155 | +static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu) | |
| 3156 | +{ | |
| 3157 | + struct vmcs12 *vmcs12 = get_vmcs12(vcpu); | |
| 3158 | + struct vcpu_vmx *vmx = to_vmx(vcpu); | |
| 3159 | + struct kvm_host_map *map; | |
| 3160 | + struct page *page; | |
| 3161 | + u64 hpa; | |
| 3162 | + | |
| 3156 | 3163 | if (nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) { |
| 3157 | 3164 | /* |
| 3158 | 3165 | * Translate L1 physical address to host physical |
| @@ -3221,6 +3228,18 @@ static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu) · 62 unmodified lines | ||
| 3221 | 3228 | exec_controls_setbit(vmx, CPU_BASED_USE_MSR_BITMAPS); |
| 3222 | 3229 | else |
| 3223 | 3230 | exec_controls_clearbit(vmx, CPU_BASED_USE_MSR_BITMAPS); |
| 3231 | + | |
| 3232 | + return true; | |
| 3233 | +} | |
| 3234 | + | |
| 3235 | +static bool vmx_get_nested_state_pages(struct kvm_vcpu *vcpu) | |
| 3236 | +{ | |
| 3237 | + if (!nested_get_evmcs_page(vcpu)) | |
| 3238 | + return false; | |
| 3239 | + | |
| 3240 | + if (is_guest_mode(vcpu) && !nested_get_vmcs12_pages(vcpu)) | |
| 3241 | + return false; | |
| 3242 | + | |
| 3224 | 3243 | return true; |
| 3225 | 3244 | } |
| 3226 | 3245 | |
| @@ -4442,6 +4461,8 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason, · 1215 unmodified lines | ||
| 4442 | 4461 | /* trying to cancel vmlaunch/vmresume is a bug */ |
| 4443 | 4462 | WARN_ON_ONCE(vmx->nested.nested_run_pending); |
| 4444 | 4463 | |
| 4464 | + kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu); | |
| 4465 | + | |
| 4445 | 4466 | /* Service the TLB flush request for L2 before switching to L1. */ |
| 4446 | 4467 | if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) |
| 4447 | 4468 | kvm_vcpu_flush_tlb_current(vcpu); |
| @@ -6075,11 +6096,14 @@ static int vmx_get_nested_state(struct kvm_vcpu *vcpu, · 1627 unmodified lines | ||
| 6075 | 6096 | if (is_guest_mode(vcpu)) { |
| 6076 | 6097 | sync_vmcs02_to_vmcs12(vcpu, vmcs12); |
| 6077 | 6098 | sync_vmcs02_to_vmcs12_rare(vcpu, vmcs12); |
| 6078 | − } else if (!vmx->nested.need_vmcs12_to_shadow_sync) { | |
| 6079 | − if (vmx->nested.hv_evmcs) | |
| 6080 | − copy_enlightened_to_vmcs12(vmx); | |
| 6081 | − else if (enable_shadow_vmcs) | |
| 6082 | − copy_shadow_to_vmcs12(vmx); | |
| 6099 | + } else { | |
| 6100 | + copy_vmcs02_to_vmcs12_rare(vcpu, get_vmcs12(vcpu)); | |
| 6101 | + if (!vmx->nested.need_vmcs12_to_shadow_sync) { | |
| 6102 | + if (vmx->nested.hv_evmcs) | |
| 6103 | + copy_enlightened_to_vmcs12(vmx); | |
| 6104 | + else if (enable_shadow_vmcs) | |
| 6105 | + copy_shadow_to_vmcs12(vmx); | |
| 6106 | + } | |
| 6083 | 6107 | } |
| 6084 | 6108 | |
| 6085 | 6109 | BUILD_BUG_ON(sizeof(user_vmx_nested_state->vmcs12) < VMCS12_SIZE); |
| @@ -6600,7 +6624,7 @@ struct kvm_x86_nested_ops vmx_nested_ops = { · 514 unmodified lines | ||
| 6600 | 6624 | .hv_timer_pending = nested_vmx_preemption_timer_pending, |
| 6601 | 6625 | .get_state = vmx_get_nested_state, |
| 6602 | 6626 | .set_state = vmx_set_nested_state, |
| 6603 | − .get_nested_state_pages = nested_get_vmcs12_pages, | |
| 6627 | + .get_nested_state_pages = vmx_get_nested_state_pages, | |
| 6604 | 6628 | .write_log_dirty = nested_vmx_write_pml_buffer, |
| 6605 | 6629 | .enable_evmcs = nested_enable_evmcs, |
| 6606 | 6630 | .get_evmcs_version = nested_get_evmcs_version, |
| @@ -29,7 +29,7 @@ static struct kvm_event_hw_type_mapping intel_arch_events[] = { · 28 unmodified lines | ||
| 29 | 29 | [4] = { 0x2e, 0x41, PERF_COUNT_HW_CACHE_MISSES }, |
| 30 | 30 | [5] = { 0xc4, 0x00, PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, |
| 31 | 31 | [6] = { 0xc5, 0x00, PERF_COUNT_HW_BRANCH_MISSES }, |
| 32 | − [7] = { 0x00, 0x30, PERF_COUNT_HW_REF_CPU_CYCLES }, | |
| 32 | + [7] = { 0x00, 0x03, PERF_COUNT_HW_REF_CPU_CYCLES }, | |
| 33 | 33 | }; |
| 34 | 34 | |
| 35 | 35 | /* mapping between fixed pmc index and intel_arch_events array */ |
| @@ -345,7 +345,9 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) · 309 unmodified lines | ||
| 345 | 345 | |
| 346 | 346 | pmu->nr_arch_gp_counters = min_t(int, eax.split.num_counters, |
| 347 | 347 | x86_pmu.num_counters_gp); |
| 348 | + eax.split.bit_width = min_t(int, eax.split.bit_width, x86_pmu.bit_width_gp); | |
| 348 | 349 | pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << eax.split.bit_width) - 1; |
| 350 | + eax.split.mask_length = min_t(int, eax.split.mask_length, x86_pmu.events_mask_len); | |
| 349 | 351 | pmu->available_event_types = ~entry->ebx & |
| 350 | 352 | ((1ull << eax.split.mask_length) - 1); |
| 351 | 353 | |
| @@ -355,6 +357,8 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) · 3 unmodified lines | ||
| 355 | 357 | pmu->nr_arch_fixed_counters = |
| 356 | 358 | min_t(int, edx.split.num_counters_fixed, |
| 357 | 359 | x86_pmu.num_counters_fixed); |
| 360 | + edx.split.bit_width_fixed = min_t(int, | |
| 361 | + edx.split.bit_width_fixed, x86_pmu.bit_width_fixed); | |
| 358 | 362 | pmu->counter_bitmask[KVM_PMC_FIXED] = |
| 359 | 363 | ((u64)1 << edx.split.bit_width_fixed) - 1; |
| 360 | 364 | } |
| @@ -6653,6 +6653,8 @@ reenter_guest: · 6652 unmodified lines | ||
| 6653 | 6653 | if (vmx->emulation_required) |
| 6654 | 6654 | return EXIT_FASTPATH_NONE; |
| 6655 | 6655 | |
| 6656 | + trace_kvm_entry(vcpu); | |
| 6657 | + | |
| 6656 | 6658 | if (vmx->ple_window_dirty) { |
| 6657 | 6659 | vmx->ple_window_dirty = false; |
| 6658 | 6660 | vmcs_write32(PLE_WINDOW, vmx->ple_window); |
| @@ -6858,11 +6860,20 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu) · 199 unmodified lines | ||
| 6858 | 6860 | switch (index) { |
| 6859 | 6861 | case MSR_IA32_TSX_CTRL: |
| 6860 | 6862 | /* |
| 6861 | − * No need to pass TSX_CTRL_CPUID_CLEAR through, so | |
| 6862 | − * let's avoid changing CPUID bits under the host | |
| 6863 | − * kernel's feet. | |
| 6863 | + * TSX_CTRL_CPUID_CLEAR is handled in the CPUID | |
| 6864 | + * interception. Keep the host value unchanged to avoid | |
| 6865 | + * changing CPUID bits under the host kernel's feet. | |
| 6866 | + * | |
| 6867 | + * hle=0, rtm=0, tsx_ctrl=1 can be found with some | |
| 6868 | + * combinations of new kernel and old userspace. If | |
| 6869 | + * those guests run on a tsx=off host, do allow guests | |
| 6870 | + * to use TSX_CTRL, but do not change the value on the | |
| 6871 | + * host so that TSX remains always disabled. | |
| 6864 | 6872 | */ |
| 6865 | − vmx->guest_uret_msrs[j].mask = ~(u64)TSX_CTRL_CPUID_CLEAR; | |
| 6873 | + if (boot_cpu_has(X86_FEATURE_RTM)) | |
| 6874 | + vmx->guest_uret_msrs[j].mask = ~(u64)TSX_CTRL_CPUID_CLEAR; | |
| 6875 | + else | |
| 6876 | + vmx->guest_uret_msrs[j].mask = 0; | |
| 6866 | 6877 | break; |
| 6867 | 6878 | default: |
| 6868 | 6879 | vmx->guest_uret_msrs[j].mask = -1ull; |
| @@ -7707,6 +7718,8 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { · 838 unmodified lines | ||
| 7707 | 7718 | .msr_filter_changed = vmx_msr_filter_changed, |
| 7708 | 7719 | .complete_emulated_msr = kvm_complete_insn_gp, |
| 7709 | 7720 | .cpu_dirty_log_size = vmx_cpu_dirty_log_size, |
| 7721 | + | |
| 7722 | + .vcpu_deliver_sipi_vector = kvm_vcpu_deliver_sipi_vector, | |
| 7710 | 7723 | }; |
| 7711 | 7724 | |
| 7712 | 7725 | static __init int hardware_setup(void) |
| @@ -105,6 +105,7 @@ static u64 __read_mostly cr4_reserved_bits = CR4_RESERVED_BITS; · 104 unmodified lines | ||
| 105 | 105 | |
| 106 | 106 | static void update_cr8_intercept(struct kvm_vcpu *vcpu); |
| 107 | 107 | static void process_nmi(struct kvm_vcpu *vcpu); |
| 108 | +static void process_smi(struct kvm_vcpu *vcpu); | |
| 108 | 109 | static void enter_smm(struct kvm_vcpu *vcpu); |
| 109 | 110 | static void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags); |
| 110 | 111 | static void store_regs(struct kvm_vcpu *vcpu); |
| @@ -1393,16 +1394,24 @@ static u64 kvm_get_arch_capabilities(void) · 1282 unmodified lines | ||
| 1393 | 1394 | if (!boot_cpu_has_bug(X86_BUG_MDS)) |
| 1394 | 1395 | data |= ARCH_CAP_MDS_NO; |
| 1395 | 1396 | |
| 1396 | − /* | |
| 1397 | − * On TAA affected systems: | |
| 1398 | − * - nothing to do if TSX is disabled on the host. | |
| 1399 | − * - we emulate TSX_CTRL if present on the host. | |
| 1400 | − * This lets the guest use VERW to clear CPU buffers. | |
| 1401 | − */ | |
| 1402 | − if (!boot_cpu_has(X86_FEATURE_RTM)) | |
| 1403 | − data &= ~(ARCH_CAP_TAA_NO | ARCH_CAP_TSX_CTRL_MSR); | |
| 1404 | − else if (!boot_cpu_has_bug(X86_BUG_TAA)) | |
| 1397 | + if (!boot_cpu_has(X86_FEATURE_RTM)) { | |
| 1398 | + /* | |
| 1399 | + * If RTM=0 because the kernel has disabled TSX, the host might | |
| 1400 | + * have TAA_NO or TSX_CTRL. Clear TAA_NO (the guest sees RTM=0 | |
| 1401 | + * and therefore knows that there cannot be TAA) but keep | |
| 1402 | + * TSX_CTRL: some buggy userspaces leave it set on tsx=on hosts, | |
| 1403 | + * and we want to allow migrating those guests to tsx=off hosts. | |
| 1404 | + */ | |
| 1405 | + data &= ~ARCH_CAP_TAA_NO; | |
| 1406 | + } else if (!boot_cpu_has_bug(X86_BUG_TAA)) { | |
| 1405 | 1407 | data |= ARCH_CAP_TAA_NO; |
| 1408 | + } else { | |
| 1409 | + /* | |
| 1410 | + * Nothing to do here; we emulate TSX_CTRL if present on the | |
| 1411 | + * host so the guest can choose between disabling TSX or | |
| 1412 | + * using VERW to clear CPU buffers. | |
| 1413 | + */ | |
| 1414 | + } | |
| 1406 | 1415 | |
| 1407 | 1416 | return data; |
| 1408 | 1417 | } |
| @@ -4230,6 +4239,9 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, · 2821 unmodified lines | ||
| 4230 | 4239 | { |
| 4231 | 4240 | process_nmi(vcpu); |
| 4232 | 4241 | |
| 4242 | + if (kvm_check_request(KVM_REQ_SMI, vcpu)) | |
| 4243 | + process_smi(vcpu); | |
| 4244 | + | |
| 4233 | 4245 | /* |
| 4234 | 4246 | * In guest mode, payload delivery should be deferred, |
| 4235 | 4247 | * so that the L1 hypervisor can intercept #PF before |
| @@ -7976,17 +7988,22 @@ void kvm_arch_exit(void) · 3740 unmodified lines | ||
| 7976 | 7988 | kmem_cache_destroy(x86_fpu_cache); |
| 7977 | 7989 | } |
| 7978 | 7990 | |
| 7979 | −int kvm_vcpu_halt(struct kvm_vcpu *vcpu) | |
| 7991 | +static int __kvm_vcpu_halt(struct kvm_vcpu *vcpu, int state, int reason) | |
| 7980 | 7992 | { |
| 7981 | 7993 | ++vcpu->stat.halt_exits; |
| 7982 | 7994 | if (lapic_in_kernel(vcpu)) { |
| 7983 | − vcpu->arch.mp_state = KVM_MP_STATE_HALTED; | |
| 7995 | + vcpu->arch.mp_state = state; | |
| 7984 | 7996 | return 1; |
| 7985 | 7997 | } else { |
| 7986 | − vcpu->run->exit_reason = KVM_EXIT_HLT; | |
| 7998 | + vcpu->run->exit_reason = reason; | |
| 7987 | 7999 | return 0; |
| 7988 | 8000 | } |
| 7989 | 8001 | } |
| 8002 | + | |
| 8003 | +int kvm_vcpu_halt(struct kvm_vcpu *vcpu) | |
| 8004 | +{ | |
| 8005 | + return __kvm_vcpu_halt(vcpu, KVM_MP_STATE_HALTED, KVM_EXIT_HLT); | |
| 8006 | +} | |
| 7990 | 8007 | EXPORT_SYMBOL_GPL(kvm_vcpu_halt); |
| 7991 | 8008 | |
| 7992 | 8009 | int kvm_emulate_halt(struct kvm_vcpu *vcpu) |
| @@ -8000,6 +8017,14 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu) · 7 unmodified lines | ||
| 8000 | 8017 | } |
| 8001 | 8018 | EXPORT_SYMBOL_GPL(kvm_emulate_halt); |
| 8002 | 8019 | |
| 8020 | +int kvm_emulate_ap_reset_hold(struct kvm_vcpu *vcpu) | |
| 8021 | +{ | |
| 8022 | + int ret = kvm_skip_emulated_instruction(vcpu); | |
| 8023 | + | |
| 8024 | + return __kvm_vcpu_halt(vcpu, KVM_MP_STATE_AP_RESET_HOLD, KVM_EXIT_AP_RESET_HOLD) && ret; | |
| 8025 | +} | |
| 8026 | +EXPORT_SYMBOL_GPL(kvm_emulate_ap_reset_hold); | |
| 8027 | + | |
| 8003 | 8028 | #ifdef CONFIG_X86_64 |
| 8004 | 8029 | static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr, |
| 8005 | 8030 | unsigned long clock_type) |
| @@ -8973,8 +8998,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) · 967 unmodified lines | ||
| 8973 | 8998 | kvm_x86_ops.request_immediate_exit(vcpu); |
| 8974 | 8999 | } |
| 8975 | 9000 | |
| 8976 | − trace_kvm_entry(vcpu); | |
| 8977 | − | |
| 8978 | 9001 | fpregs_assert_state_consistent(); |
| 8979 | 9002 | if (test_thread_flag(TIF_NEED_FPU_LOAD)) |
| 8980 | 9003 | switch_fpu_return(); |
| @@ -9094,6 +9117,7 @@ static inline int vcpu_block(struct kvm *kvm, struct kvm_vcpu *vcpu) · 113 unmodified lines | ||
| 9094 | 9117 | kvm_apic_accept_events(vcpu); |
| 9095 | 9118 | switch(vcpu->arch.mp_state) { |
| 9096 | 9119 | case KVM_MP_STATE_HALTED: |
| 9120 | + case KVM_MP_STATE_AP_RESET_HOLD: | |
| 9097 | 9121 | vcpu->arch.pv.pv_unhalted = false; |
| 9098 | 9122 | vcpu->arch.mp_state = |
| 9099 | 9123 | KVM_MP_STATE_RUNNABLE; |
| @@ -9520,8 +9544,9 @@ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, · 420 unmodified lines | ||
| 9520 | 9544 | kvm_load_guest_fpu(vcpu); |
| 9521 | 9545 | |
| 9522 | 9546 | kvm_apic_accept_events(vcpu); |
| 9523 | − if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED && | |
| 9524 | − vcpu->arch.pv.pv_unhalted) | |
| 9547 | + if ((vcpu->arch.mp_state == KVM_MP_STATE_HALTED || | |
| 9548 | + vcpu->arch.mp_state == KVM_MP_STATE_AP_RESET_HOLD) && | |
| 9549 | + vcpu->arch.pv.pv_unhalted) | |
| 9525 | 9550 | mp_state->mp_state = KVM_MP_STATE_RUNNABLE; |
| 9526 | 9551 | else |
| 9527 | 9552 | mp_state->mp_state = vcpu->arch.mp_state; |
| @@ -9599,6 +9624,8 @@ static bool kvm_is_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) · 71 unmodified lines | ||
| 9599 | 9624 | */ |
| 9600 | 9625 | if (!(sregs->cr4 & X86_CR4_PAE) || !(sregs->efer & EFER_LMA)) |
| 9601 | 9626 | return false; |
| 9627 | + if (sregs->cr3 & vcpu->arch.cr3_lm_rsvd_bits) | |
| 9628 | + return false; | |
| 9602 | 9629 | } else { |
| 9603 | 9630 | /* |
| 9604 | 9631 | * Not in 64-bit mode: EFER.LMA is clear and the code |
| @@ -9976,6 +10003,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) · 371 unmodified lines | ||
| 9976 | 10003 | fx_init(vcpu); |
| 9977 | 10004 | |
| 9978 | 10005 | vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu); |
| 10006 | + vcpu->arch.cr3_lm_rsvd_bits = rsvd_bits(cpuid_maxphyaddr(vcpu), 63); | |
| 9979 | 10007 | |
| 9980 | 10008 | vcpu->arch.pat = MSR_IA32_CR_PAT_DEFAULT; |
| 9981 | 10009 | |
| @@ -10152,6 +10180,7 @@ void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector) · 170 unmodified lines | ||
| 10152 | 10180 | kvm_set_segment(vcpu, &cs, VCPU_SREG_CS); |
| 10153 | 10181 | kvm_rip_write(vcpu, 0); |
| 10154 | 10182 | } |
| 10183 | +EXPORT_SYMBOL_GPL(kvm_vcpu_deliver_sipi_vector); | |
| 10155 | 10184 | |
| 10156 | 10185 | int kvm_arch_hardware_enable(void) |
| 10157 | 10186 | { |
| @@ -10476,7 +10505,7 @@ void __user * __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, · 318 unmodified lines | ||
| 10476 | 10505 | return 0; |
| 10477 | 10506 | |
| 10478 | 10507 | old_npages = slot->npages; |
| 10479 | − hva = 0; | |
| 10508 | + hva = slot->userspace_addr; | |
| 10480 | 10509 | } |
| 10481 | 10510 | |
| 10482 | 10511 | for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) { |
| @@ -11538,6 +11567,7 @@ int kvm_sev_es_string_io(struct kvm_vcpu *vcpu, unsigned int size, · 1055 unmodified lines | ||
| 11538 | 11567 | } |
| 11539 | 11568 | EXPORT_SYMBOL_GPL(kvm_sev_es_string_io); |
| 11540 | 11569 | |
| 11570 | +EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_entry); | |
| 11541 | 11571 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit); |
| 11542 | 11572 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_fast_mmio); |
| 11543 | 11573 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq); |
| @@ -425,6 +425,8 @@ bool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type); · 424 unmodified lines | ||
| 425 | 425 | __reserved_bits |= X86_CR4_UMIP; \ |
| 426 | 426 | if (!__cpu_has(__c, X86_FEATURE_VMX)) \ |
| 427 | 427 | __reserved_bits |= X86_CR4_VMXE; \ |
| 428 | + if (!__cpu_has(__c, X86_FEATURE_PCID)) \ | |
| 429 | + __reserved_bits |= X86_CR4_PCIDE; \ | |
| 428 | 430 | __reserved_bits; \ |
| 429 | 431 | }) |
| 430 | 432 | |
| @@ -26,6 +26,16 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <asm/fpu/api.h> |
| 27 | 27 | #include <asm/asm.h> |
| 28 | 28 | |
| 29 | +/* | |
| 30 | + * Use KFPU_387. MMX instructions are not affected by MXCSR, | |
| 31 | + * but both AMD and Intel documentation states that even integer MMX | |
| 32 | + * operations will result in #MF if an exception is pending in FCW. | |
| 33 | + * | |
| 34 | + * EMMS is not needed afterwards because, after calling kernel_fpu_end(), | |
| 35 | + * any subsequent user of the 387 stack will reinitialize it using | |
| 36 | + * KFPU_387. | |
| 37 | + */ | |
| 38 | + | |
| 29 | 39 | void *_mmx_memcpy(void *to, const void *from, size_t len) |
| 30 | 40 | { |
| 31 | 41 | void *p; |
| @@ -37,7 +47,7 @@ void *_mmx_memcpy(void *to, const void *from, size_t len) · 5 unmodified lines | ||
| 37 | 47 | p = to; |
| 38 | 48 | i = len >> 6; /* len/64 */ |
| 39 | 49 | |
| 40 | − kernel_fpu_begin(); | |
| 50 | + kernel_fpu_begin_mask(KFPU_387); | |
| 41 | 51 | |
| 42 | 52 | __asm__ __volatile__ ( |
| 43 | 53 | "1: prefetch (%0)\n" /* This set is 28 bytes */ |
| @@ -127,7 +137,7 @@ static void fast_clear_page(void *page) · 83 unmodified lines | ||
| 127 | 137 | { |
| 128 | 138 | int i; |
| 129 | 139 | |
| 130 | − kernel_fpu_begin(); | |
| 140 | + kernel_fpu_begin_mask(KFPU_387); | |
| 131 | 141 | |
| 132 | 142 | __asm__ __volatile__ ( |
| 133 | 143 | " pxor %%mm0, %%mm0\n" : : |
| @@ -160,7 +170,7 @@ static void fast_copy_page(void *to, void *from) · 26 unmodified lines | ||
| 160 | 170 | { |
| 161 | 171 | int i; |
| 162 | 172 | |
| 163 | − kernel_fpu_begin(); | |
| 173 | + kernel_fpu_begin_mask(KFPU_387); | |
| 164 | 174 | |
| 165 | 175 | /* |
| 166 | 176 | * maybe the prefetch stuff can go before the expensive fnsave... |
| @@ -247,7 +257,7 @@ static void fast_clear_page(void *page) · 80 unmodified lines | ||
| 247 | 257 | { |
| 248 | 258 | int i; |
| 249 | 259 | |
| 250 | − kernel_fpu_begin(); | |
| 260 | + kernel_fpu_begin_mask(KFPU_387); | |
| 251 | 261 | |
| 252 | 262 | __asm__ __volatile__ ( |
| 253 | 263 | " pxor %%mm0, %%mm0\n" : : |
| @@ -282,7 +292,7 @@ static void fast_copy_page(void *to, void *from) · 28 unmodified lines | ||
| 282 | 292 | { |
| 283 | 293 | int i; |
| 284 | 294 | |
| 285 | − kernel_fpu_begin(); | |
| 295 | + kernel_fpu_begin_mask(KFPU_387); | |
| 286 | 296 | |
| 287 | 297 | __asm__ __volatile__ ( |
| 288 | 298 | "1: prefetch (%0)\n" |
| @@ -382,6 +382,7 @@ bool sev_active(void) · 381 unmodified lines | ||
| 382 | 382 | { |
| 383 | 383 | return sev_status & MSR_AMD64_SEV_ENABLED; |
| 384 | 384 | } |
| 385 | +EXPORT_SYMBOL_GPL(sev_active); | |
| 385 | 386 | |
| 386 | 387 | /* Needs to be called from non-instrumentable code */ |
| 387 | 388 | bool noinstr sev_es_active(void) |
| @@ -829,6 +829,8 @@ int pud_free_pmd_page(pud_t *pud, unsigned long addr) · 828 unmodified lines | ||
| 829 | 829 | } |
| 830 | 830 | |
| 831 | 831 | free_page((unsigned long)pmd_sv); |
| 832 | + | |
| 833 | + pgtable_pmd_page_dtor(virt_to_page(pmd)); | |
| 832 | 834 | free_page((unsigned long)pmd); |
| 833 | 835 | |
| 834 | 836 | return 1; |
| @@ -9,16 +9,23 @@ · 8 unmodified lines | ||
| 9 | 9 | in the right sequence from here. */ |
| 10 | 10 | static __init int pci_arch_init(void) |
| 11 | 11 | { |
| 12 | − int type; | |
| 13 | − | |
| 14 | − x86_create_pci_msi_domain(); | |
| 12 | + int type, pcbios = 1; | |
| 15 | 13 | |
| 16 | 14 | type = pci_direct_probe(); |
| 17 | 15 | |
| 18 | 16 | if (!(pci_probe & PCI_PROBE_NOEARLY)) |
| 19 | 17 | pci_mmcfg_early_init(); |
| 20 | 18 | |
| 21 | − if (x86_init.pci.arch_init && !x86_init.pci.arch_init()) | |
| 19 | + if (x86_init.pci.arch_init) | |
| 20 | + pcbios = x86_init.pci.arch_init(); | |
| 21 | + | |
| 22 | + /* | |
| 23 | + * Must happen after x86_init.pci.arch_init(). Xen sets up the | |
| 24 | + * x86_init.irqs.create_pci_msi_domain there. | |
| 25 | + */ | |
| 26 | + x86_create_pci_msi_domain(); | |
| 27 | + | |
| 28 | + if (!pcbios) | |
| 22 | 29 | return 0; |
| 23 | 30 | |
| 24 | 31 | pci_pcbios_init(); |
| @@ -115,31 +115,12 @@ void efi_sync_low_kernel_mappings(void) · 114 unmodified lines | ||
| 115 | 115 | pud_t *pud_k, *pud_efi; |
| 116 | 116 | pgd_t *efi_pgd = efi_mm.pgd; |
| 117 | 117 | |
| 118 | − /* | |
| 119 | − * We can share all PGD entries apart from the one entry that | |
| 120 | − * covers the EFI runtime mapping space. | |
| 121 | − * | |
| 122 | − * Make sure the EFI runtime region mappings are guaranteed to | |
| 123 | − * only span a single PGD entry and that the entry also maps | |
| 124 | − * other important kernel regions. | |
| 125 | − */ | |
| 126 | − MAYBE_BUILD_BUG_ON(pgd_index(EFI_VA_END) != pgd_index(MODULES_END)); | |
| 127 | − MAYBE_BUILD_BUG_ON((EFI_VA_START & PGDIR_MASK) != | |
| 128 | − (EFI_VA_END & PGDIR_MASK)); | |
| 129 | − | |
| 130 | 118 | pgd_efi = efi_pgd + pgd_index(PAGE_OFFSET); |
| 131 | 119 | pgd_k = pgd_offset_k(PAGE_OFFSET); |
| 132 | 120 | |
| 133 | 121 | num_entries = pgd_index(EFI_VA_END) - pgd_index(PAGE_OFFSET); |
| 134 | 122 | memcpy(pgd_efi, pgd_k, sizeof(pgd_t) * num_entries); |
| 135 | 123 | |
| 136 | − /* | |
| 137 | − * As with PGDs, we share all P4D entries apart from the one entry | |
| 138 | − * that covers the EFI runtime mapping space. | |
| 139 | − */ | |
| 140 | − BUILD_BUG_ON(p4d_index(EFI_VA_END) != p4d_index(MODULES_END)); | |
| 141 | − BUILD_BUG_ON((EFI_VA_START & P4D_MASK) != (EFI_VA_END & P4D_MASK)); | |
| 142 | − | |
| 143 | 124 | pgd_efi = efi_pgd + pgd_index(EFI_VA_END); |
| 144 | 125 | pgd_k = pgd_offset_k(EFI_VA_END); |
| 145 | 126 | p4d_efi = p4d_offset(pgd_efi, 0); |
| @@ -164,10 +164,10 @@ static int xen_cpu_up_prepare_hvm(unsigned int cpu) · 163 unmodified lines | ||
| 164 | 164 | else |
| 165 | 165 | per_cpu(xen_vcpu_id, cpu) = cpu; |
| 166 | 166 | rc = xen_vcpu_setup(cpu); |
| 167 | − if (rc) | |
| 167 | + if (rc || !xen_have_vector_callback) | |
| 168 | 168 | return rc; |
| 169 | 169 | |
| 170 | − if (xen_have_vector_callback && xen_feature(XENFEAT_hvm_safe_pvclock)) | |
| 170 | + if (xen_feature(XENFEAT_hvm_safe_pvclock)) | |
| 171 | 171 | xen_setup_timer(cpu); |
| 172 | 172 | |
| 173 | 173 | rc = xen_smp_intr_init(cpu); |
| @@ -188,6 +188,8 @@ static int xen_cpu_dead_hvm(unsigned int cpu) · 14 unmodified lines | ||
| 188 | 188 | return 0; |
| 189 | 189 | } |
| 190 | 190 | |
| 191 | +static bool no_vector_callback __initdata; | |
| 192 | + | |
| 191 | 193 | static void __init xen_hvm_guest_init(void) |
| 192 | 194 | { |
| 193 | 195 | if (xen_pv_domain()) |
| @@ -207,7 +209,7 @@ static void __init xen_hvm_guest_init(void) · 13 unmodified lines | ||
| 207 | 209 | |
| 208 | 210 | xen_panic_handler_init(); |
| 209 | 211 | |
| 210 | − if (xen_feature(XENFEAT_hvm_callback_vector)) | |
| 212 | + if (!no_vector_callback && xen_feature(XENFEAT_hvm_callback_vector)) | |
| 211 | 213 | xen_have_vector_callback = 1; |
| 212 | 214 | |
| 213 | 215 | xen_hvm_smp_init(); |
| @@ -233,6 +235,13 @@ static __init int xen_parse_nopv(char *arg) · 19 unmodified lines | ||
| 233 | 235 | } |
| 234 | 236 | early_param("xen_nopv", xen_parse_nopv); |
| 235 | 237 | |
| 238 | +static __init int xen_parse_no_vector_callback(char *arg) | |
| 239 | +{ | |
| 240 | + no_vector_callback = true; | |
| 241 | + return 0; | |
| 242 | +} | |
| 243 | +early_param("xen_no_vector_callback", xen_parse_no_vector_callback); | |
| 244 | + | |
| 236 | 245 | bool __init xen_hvm_need_lapic(void) |
| 237 | 246 | { |
| 238 | 247 | if (xen_pv_domain()) |
| @@ -583,6 +583,13 @@ DEFINE_IDTENTRY_RAW(xenpv_exc_debug) · 582 unmodified lines | ||
| 583 | 583 | exc_debug(regs); |
| 584 | 584 | } |
| 585 | 585 | |
| 586 | +DEFINE_IDTENTRY_RAW(exc_xen_unknown_trap) | |
| 587 | +{ | |
| 588 | + /* This should never happen and there is no way to handle it. */ | |
| 589 | + pr_err("Unknown trap in Xen PV mode."); | |
| 590 | + BUG(); | |
| 591 | +} | |
| 592 | + | |
| 586 | 593 | struct trap_array_entry { |
| 587 | 594 | void (*orig)(void); |
| 588 | 595 | void (*xen)(void); |
| @@ -631,6 +638,7 @@ static bool __ref get_trap_addr(void **addr, unsigned int ist) · 42 unmodified lines | ||
| 631 | 638 | { |
| 632 | 639 | unsigned int nr; |
| 633 | 640 | bool ist_okay = false; |
| 641 | + bool found = false; | |
| 634 | 642 | |
| 635 | 643 | /* |
| 636 | 644 | * Replace trap handler addresses by Xen specific ones. |
| @@ -645,6 +653,7 @@ static bool __ref get_trap_addr(void **addr, unsigned int ist) · 8 unmodified lines | ||
| 645 | 653 | if (*addr == entry->orig) { |
| 646 | 654 | *addr = entry->xen; |
| 647 | 655 | ist_okay = entry->ist_okay; |
| 656 | + found = true; | |
| 648 | 657 | break; |
| 649 | 658 | } |
| 650 | 659 | } |
| @@ -655,9 +664,13 @@ static bool __ref get_trap_addr(void **addr, unsigned int ist) · 4 unmodified lines | ||
| 655 | 664 | nr = (*addr - (void *)early_idt_handler_array[0]) / |
| 656 | 665 | EARLY_IDT_HANDLER_SIZE; |
| 657 | 666 | *addr = (void *)xen_early_idt_handler_array[nr]; |
| 667 | + found = true; | |
| 658 | 668 | } |
| 659 | 669 | |
| 660 | − if (WARN_ON(ist != 0 && !ist_okay)) | |
| 670 | + if (!found) | |
| 671 | + *addr = (void *)xen_asm_exc_xen_unknown_trap; | |
| 672 | + | |
| 673 | + if (WARN_ON(found && ist != 0 && !ist_okay)) | |
| 661 | 674 | return false; |
| 662 | 675 | |
| 663 | 676 | return true; |
| @@ -33,9 +33,11 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) · 32 unmodified lines | ||
| 33 | 33 | int cpu; |
| 34 | 34 | |
| 35 | 35 | native_smp_prepare_cpus(max_cpus); |
| 36 | − WARN_ON(xen_smp_intr_init(0)); | |
| 37 | 36 | |
| 38 | − xen_init_lock_cpu(0); | |
| 37 | + if (xen_have_vector_callback) { | |
| 38 | + WARN_ON(xen_smp_intr_init(0)); | |
| 39 | + xen_init_lock_cpu(0); | |
| 40 | + } | |
| 39 | 41 | |
| 40 | 42 | for_each_possible_cpu(cpu) { |
| 41 | 43 | if (cpu == 0) |
| @@ -50,9 +52,11 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) · 8 unmodified lines | ||
| 50 | 52 | static void xen_hvm_cpu_die(unsigned int cpu) |
| 51 | 53 | { |
| 52 | 54 | if (common_cpu_die(cpu) == 0) { |
| 53 | − xen_smp_intr_free(cpu); | |
| 54 | − xen_uninit_lock_cpu(cpu); | |
| 55 | − xen_teardown_timer(cpu); | |
| 55 | + if (xen_have_vector_callback) { | |
| 56 | + xen_smp_intr_free(cpu); | |
| 57 | + xen_uninit_lock_cpu(cpu); | |
| 58 | + xen_teardown_timer(cpu); | |
| 59 | + } | |
| 56 | 60 | } |
| 57 | 61 | } |
| 58 | 62 | #else |
| @@ -64,14 +68,19 @@ static void xen_hvm_cpu_die(unsigned int cpu) · 5 unmodified lines | ||
| 64 | 68 | |
| 65 | 69 | void __init xen_hvm_smp_init(void) |
| 66 | 70 | { |
| 67 | − if (!xen_have_vector_callback) | |
| 71 | + smp_ops.smp_prepare_boot_cpu = xen_hvm_smp_prepare_boot_cpu; | |
| 72 | + smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus; | |
| 73 | + smp_ops.smp_cpus_done = xen_smp_cpus_done; | |
| 74 | + smp_ops.cpu_die = xen_hvm_cpu_die; | |
| 75 | + | |
| 76 | + if (!xen_have_vector_callback) { | |
| 77 | +#ifdef CONFIG_PARAVIRT_SPINLOCKS | |
| 78 | + nopvspin = true; | |
| 79 | +#endif | |
| 68 | 80 | return; |
| 81 | + } | |
| 69 | 82 | |
| 70 | − smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus; | |
| 71 | 83 | smp_ops.smp_send_reschedule = xen_smp_send_reschedule; |
| 72 | − smp_ops.cpu_die = xen_hvm_cpu_die; | |
| 73 | 84 | smp_ops.send_call_func_ipi = xen_smp_send_call_function_ipi; |
| 74 | 85 | smp_ops.send_call_func_single_ipi = xen_smp_send_call_function_single_ipi; |
| 75 | − smp_ops.smp_prepare_boot_cpu = xen_hvm_smp_prepare_boot_cpu; | |
| 76 | − smp_ops.smp_cpus_done = xen_smp_cpus_done; | |
| 77 | 86 | } |
| @@ -178,6 +178,7 @@ xen_pv_trap asm_exc_simd_coprocessor_error · 177 unmodified lines | ||
| 178 | 178 | #ifdef CONFIG_IA32_EMULATION |
| 179 | 179 | xen_pv_trap entry_INT80_compat |
| 180 | 180 | #endif |
| 181 | +xen_pv_trap asm_exc_xen_unknown_trap | |
| 181 | 182 | xen_pv_trap asm_exc_xen_hypervisor_callback |
| 182 | 183 | |
| 183 | 184 | __INIT |
| @@ -1016,6 +1016,8 @@ static void blkcg_css_offline(struct cgroup_subsys_state *css) · 1015 unmodified lines | ||
| 1016 | 1016 | */ |
| 1017 | 1017 | void blkcg_destroy_blkgs(struct blkcg *blkcg) |
| 1018 | 1018 | { |
| 1019 | + might_sleep(); | |
| 1020 | + | |
| 1019 | 1021 | spin_lock_irq(&blkcg->lock); |
| 1020 | 1022 | |
| 1021 | 1023 | while (!hlist_empty(&blkcg->blkg_list)) { |
| @@ -1023,14 +1025,20 @@ void blkcg_destroy_blkgs(struct blkcg *blkcg) · 1 unmodified line | ||
| 1023 | 1025 | struct blkcg_gq, blkcg_node); |
| 1024 | 1026 | struct request_queue *q = blkg->q; |
| 1025 | 1027 | |
| 1026 | − if (spin_trylock(&q->queue_lock)) { | |
| 1027 | − blkg_destroy(blkg); | |
| 1028 | − spin_unlock(&q->queue_lock); | |
| 1029 | − } else { | |
| 1028 | + if (need_resched() || !spin_trylock(&q->queue_lock)) { | |
| 1029 | + /* | |
| 1030 | + * Given that the system can accumulate a huge number | |
| 1031 | + * of blkgs in pathological cases, check to see if we | |
| 1032 | + * need to rescheduling to avoid softlockup. | |
| 1033 | + */ | |
| 1030 | 1034 | spin_unlock_irq(&blkcg->lock); |
| 1031 | − cpu_relax(); | |
| 1035 | + cond_resched(); | |
| 1032 | 1036 | spin_lock_irq(&blkcg->lock); |
| 1037 | + continue; | |
| 1033 | 1038 | } |
| 1039 | + | |
| 1040 | + blkg_destroy(blkg); | |
| 1041 | + spin_unlock(&q->queue_lock); | |
| 1034 | 1042 | } |
| 1035 | 1043 | |
| 1036 | 1044 | spin_unlock_irq(&blkcg->lock); |
| @@ -2551,8 +2551,8 @@ static void ioc_rqos_throttle(struct rq_qos *rqos, struct bio *bio) · 2550 unmodified lines | ||
| 2551 | 2551 | bool use_debt, ioc_locked; |
| 2552 | 2552 | unsigned long flags; |
| 2553 | 2553 | |
| 2554 | − /* bypass IOs if disabled or for root cgroup */ | |
| 2555 | − if (!ioc->enabled || !iocg->level) | |
| 2554 | + /* bypass IOs if disabled, still initializing, or for root cgroup */ | |
| 2555 | + if (!ioc->enabled || !iocg || !iocg->level) | |
| 2556 | 2556 | return; |
| 2557 | 2557 | |
| 2558 | 2558 | /* calculate the absolute vtime cost */ |
| @@ -2679,14 +2679,14 @@ static void ioc_rqos_merge(struct rq_qos *rqos, struct request *rq, · 120 unmodified lines | ||
| 2679 | 2679 | struct bio *bio) |
| 2680 | 2680 | { |
| 2681 | 2681 | struct ioc_gq *iocg = blkg_to_iocg(bio->bi_blkg); |
| 2682 | − struct ioc *ioc = iocg->ioc; | |
| 2682 | + struct ioc *ioc = rqos_to_ioc(rqos); | |
| 2683 | 2683 | sector_t bio_end = bio_end_sector(bio); |
| 2684 | 2684 | struct ioc_now now; |
| 2685 | 2685 | u64 vtime, abs_cost, cost; |
| 2686 | 2686 | unsigned long flags; |
| 2687 | 2687 | |
| 2688 | − /* bypass if disabled or for root cgroup */ | |
| 2689 | − if (!ioc->enabled || !iocg->level) | |
| 2688 | + /* bypass if disabled, still initializing, or for root cgroup */ | |
| 2689 | + if (!ioc->enabled || !iocg || !iocg->level) | |
| 2690 | 2690 | return; |
| 2691 | 2691 | |
| 2692 | 2692 | abs_cost = calc_vtime_cost(bio, iocg, true); |
| @@ -2863,6 +2863,12 @@ static int blk_iocost_init(struct request_queue *q) · 170 unmodified lines | ||
| 2863 | 2863 | ioc_refresh_params(ioc, true); |
| 2864 | 2864 | spin_unlock_irq(&ioc->lock); |
| 2865 | 2865 | |
| 2866 | + /* | |
| 2867 | + * rqos must be added before activation to allow iocg_pd_init() to | |
| 2868 | + * lookup the ioc from q. This means that the rqos methods may get | |
| 2869 | + * called before policy activation completion, can't assume that the | |
| 2870 | + * target bio has an iocg associated and need to test for NULL iocg. | |
| 2871 | + */ | |
| 2866 | 2872 | rq_qos_add(q, rqos); |
| 2867 | 2873 | ret = blkcg_activate_policy(q, &blkcg_policy_iocost); |
| 2868 | 2874 | if (ret) { |
| @@ -246,6 +246,7 @@ static const char *const hctx_flag_name[] = { · 245 unmodified lines | ||
| 246 | 246 | HCTX_FLAG_NAME(BLOCKING), |
| 247 | 247 | HCTX_FLAG_NAME(NO_SCHED), |
| 248 | 248 | HCTX_FLAG_NAME(STACKING), |
| 249 | + HCTX_FLAG_NAME(TAG_HCTX_SHARED), | |
| 249 | 250 | }; |
| 250 | 251 | #undef HCTX_FLAG_NAME |
| 251 | 252 | |
| @@ -304,7 +304,7 @@ static inline bool hctx_may_queue(struct blk_mq_hw_ctx *hctx, · 303 unmodified lines | ||
| 304 | 304 | struct request_queue *q = hctx->queue; |
| 305 | 305 | struct blk_mq_tag_set *set = q->tag_set; |
| 306 | 306 | |
| 307 | − if (!test_bit(BLK_MQ_S_TAG_ACTIVE, &q->queue_flags)) | |
| 307 | + if (!test_bit(QUEUE_FLAG_HCTX_ACTIVE, &q->queue_flags)) | |
| 308 | 308 | return true; |
| 309 | 309 | users = atomic_read(&set->active_queues_shared_sbitmap); |
| 310 | 310 | } else { |
| @@ -45,10 +45,11 @@ static void disk_release_events(struct gendisk *disk); · 44 unmodified lines | ||
| 45 | 45 | void set_capacity(struct gendisk *disk, sector_t sectors) |
| 46 | 46 | { |
| 47 | 47 | struct block_device *bdev = disk->part0; |
| 48 | + unsigned long flags; | |
| 48 | 49 | |
| 49 | − spin_lock(&bdev->bd_size_lock); | |
| 50 | + spin_lock_irqsave(&bdev->bd_size_lock, flags); | |
| 50 | 51 | i_size_write(bdev->bd_inode, (loff_t)sectors << SECTOR_SHIFT); |
| 51 | − spin_unlock(&bdev->bd_size_lock); | |
| 52 | + spin_unlock_irqrestore(&bdev->bd_size_lock, flags); | |
| 52 | 53 | } |
| 53 | 54 | EXPORT_SYMBOL(set_capacity); |
| 54 | 55 | |
| @@ -246,15 +247,18 @@ struct block_device *disk_part_iter_next(struct disk_part_iter *piter) · 191 unmodified lines | ||
| 246 | 247 | part = rcu_dereference(ptbl->part[piter->idx]); |
| 247 | 248 | if (!part) |
| 248 | 249 | continue; |
| 250 | + piter->part = bdgrab(part); | |
| 251 | + if (!piter->part) | |
| 252 | + continue; | |
| 249 | 253 | if (!bdev_nr_sectors(part) && |
| 250 | 254 | !(piter->flags & DISK_PITER_INCL_EMPTY) && |
| 251 | 255 | !(piter->flags & DISK_PITER_INCL_EMPTY_PART0 && |
| 252 | − piter->idx == 0)) | |
| 256 | + piter->idx == 0)) { | |
| 257 | + bdput(piter->part); | |
| 258 | + piter->part = NULL; | |
| 253 | 259 | continue; |
| 260 | + } | |
| 254 | 261 | |
| 255 | − piter->part = bdgrab(part); | |
| 256 | − if (!piter->part) | |
| 257 | − continue; | |
| 258 | 262 | piter->idx += inc; |
| 259 | 263 | break; |
| 260 | 264 | } |
| @@ -88,9 +88,11 @@ static int (*check_part[])(struct parsed_partitions *) = { · 87 unmodified lines | ||
| 88 | 88 | |
| 89 | 89 | static void bdev_set_nr_sectors(struct block_device *bdev, sector_t sectors) |
| 90 | 90 | { |
| 91 | − spin_lock(&bdev->bd_size_lock); | |
| 91 | + unsigned long flags; | |
| 92 | + | |
| 93 | + spin_lock_irqsave(&bdev->bd_size_lock, flags); | |
| 92 | 94 | i_size_write(bdev->bd_inode, (loff_t)sectors << SECTOR_SHIFT); |
| 93 | − spin_unlock(&bdev->bd_size_lock); | |
| 95 | + spin_unlock_irqrestore(&bdev->bd_size_lock, flags); | |
| 94 | 96 | } |
| 95 | 97 | |
| 96 | 98 | static struct parsed_partitions *allocate_partitions(struct gendisk *hd) |
| @@ -384,7 +386,7 @@ static struct block_device *add_partition(struct gendisk *disk, int partno, · 287 unmodified lines | ||
| 384 | 386 | |
| 385 | 387 | err = blk_alloc_devt(bdev, &devt); |
| 386 | 388 | if (err) |
| 387 | − goto out_bdput; | |
| 389 | + goto out_put; | |
| 388 | 390 | pdev->devt = devt; |
| 389 | 391 | |
| 390 | 392 | /* delay uevent until 'holders' subdir is created */ |
| @@ -354,7 +354,7 @@ static uint32_t derive_pub_key(const void *pub_key, uint32_t len, uint8_t *buf) · 353 unmodified lines | ||
| 354 | 354 | memcpy(cur, e, sizeof(e)); |
| 355 | 355 | cur += sizeof(e); |
| 356 | 356 | /* Zero parameters to satisfy set_pub_key ABI. */ |
| 357 | − memset(cur, 0, SETKEY_PARAMS_SIZE); | |
| 357 | + memzero_explicit(cur, SETKEY_PARAMS_SIZE); | |
| 358 | 358 | |
| 359 | 359 | return cur - buf; |
| 360 | 360 | } |
| @@ -356,7 +356,8 @@ int public_key_verify_signature(const struct public_key *pkey, · 355 unmodified lines | ||
| 356 | 356 | if (ret) |
| 357 | 357 | goto error_free_key; |
| 358 | 358 | |
| 359 | − if (strcmp(sig->pkey_algo, "sm2") == 0 && sig->data_size) { | |
| 359 | + if (sig->pkey_algo && strcmp(sig->pkey_algo, "sm2") == 0 && | |
| 360 | + sig->data_size) { | |
| 360 | 361 | ret = cert_sig_digest_update(sig, tfm); |
| 361 | 362 | if (ret) |
| 362 | 363 | goto error_free_key; |
| @@ -39,7 +39,8 @@ static int ecdh_set_secret(struct crypto_kpp *tfm, const void *buf, · 38 unmodified lines | ||
| 39 | 39 | struct ecdh params; |
| 40 | 40 | unsigned int ndigits; |
| 41 | 41 | |
| 42 | − if (crypto_ecdh_decode_key(buf, len, ¶ms) < 0) | |
| 42 | + if (crypto_ecdh_decode_key(buf, len, ¶ms) < 0 || | |
| 43 | + params.key_size > sizeof(ctx->private_key)) | |
| 43 | 44 | return -EINVAL; |
| 44 | 45 | |
| 45 | 46 | ndigits = ecdh_supported_curve(params.curve_id); |
| @@ -107,6 +107,8 @@ do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2) · 106 unmodified lines | ||
| 107 | 107 | preempt_enable(); |
| 108 | 108 | |
| 109 | 109 | // bytes/ns == GB/s, multiply by 1000 to get MB/s [not MiB/s] |
| 110 | + if (!min) | |
| 111 | + min = 1; | |
| 110 | 112 | speed = (1000 * REPS * BENCH_SIZE) / (unsigned int)ktime_to_ns(min); |
| 111 | 113 | tmpl->speed = speed; |
| 112 | 114 | |
| @@ -395,9 +395,6 @@ config ACPI_CONTAINER · 394 unmodified lines | ||
| 395 | 395 | |
| 396 | 396 | This helps support hotplug of nodes, CPUs, and memory. |
| 397 | 397 | |
| 398 | − To compile this driver as a module, choose M here: | |
| 399 | − the module will be called container. | |
| 400 | − | |
| 401 | 398 | config ACPI_HOTPLUG_MEMORY |
| 402 | 399 | bool "Memory Hotplug" |
| 403 | 400 | depends on MEMORY_HOTPLUG |
| @@ -411,9 +408,6 @@ config ACPI_HOTPLUG_MEMORY · 7 unmodified lines | ||
| 411 | 408 | removing memory devices at runtime, you need not enable |
| 412 | 409 | this driver. |
| 413 | 410 | |
| 414 | − To compile this driver as a module, choose M here: | |
| 415 | − the module will be called acpi_memhotplug. | |
| 416 | − | |
| 417 | 411 | config ACPI_HOTPLUG_IOAPIC |
| 418 | 412 | bool |
| 419 | 413 | depends on PCI |
| @@ -495,8 +495,9 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, · 494 unmodified lines | ||
| 495 | 495 | union acpi_operand_object **return_object_ptr) |
| 496 | 496 | { |
| 497 | 497 | union acpi_operand_object *return_object = *return_object_ptr; |
| 498 | − char *dest; | |
| 498 | + union acpi_operand_object *new_string; | |
| 499 | 499 | char *source; |
| 500 | + char *dest; | |
| 500 | 501 | |
| 501 | 502 | ACPI_FUNCTION_NAME(ns_repair_HID); |
| 502 | 503 | |
| @@ -517,6 +518,13 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, · 14 unmodified lines | ||
| 517 | 518 | return_ACPI_STATUS(AE_OK); |
| 518 | 519 | } |
| 519 | 520 | |
| 521 | + /* It is simplest to always create a new string object */ | |
| 522 | + | |
| 523 | + new_string = acpi_ut_create_string_object(return_object->string.length); | |
| 524 | + if (!new_string) { | |
| 525 | + return_ACPI_STATUS(AE_NO_MEMORY); | |
| 526 | + } | |
| 527 | + | |
| 520 | 528 | /* |
| 521 | 529 | * Remove a leading asterisk if present. For some unknown reason, there |
| 522 | 530 | * are many machines in the field that contains IDs like this. |
| @@ -526,7 +534,7 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, · 3 unmodified lines | ||
| 526 | 534 | source = return_object->string.pointer; |
| 527 | 535 | if (*source == '*') { |
| 528 | 536 | source++; |
| 529 | − return_object->string.length--; | |
| 537 | + new_string->string.length--; | |
| 530 | 538 | |
| 531 | 539 | ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, |
| 532 | 540 | "%s: Removed invalid leading asterisk\n", |
| @@ -541,11 +549,12 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, · 8 unmodified lines | ||
| 541 | 549 | * "NNNN####" where N is an uppercase letter or decimal digit, and |
| 542 | 550 | * # is a hex digit. |
| 543 | 551 | */ |
| 544 | − for (dest = return_object->string.pointer; *source; dest++, source++) { | |
| 552 | + for (dest = new_string->string.pointer; *source; dest++, source++) { | |
| 545 | 553 | *dest = (char)toupper((int)*source); |
| 546 | 554 | } |
| 547 | − return_object->string.pointer[return_object->string.length] = 0; | |
| 548 | 555 | |
| 556 | + acpi_ut_remove_reference(return_object); | |
| 557 | + *return_object_ptr = new_string; | |
| 549 | 558 | return_ACPI_STATUS(AE_OK); |
| 550 | 559 | } |
| 551 | 560 | |
| @@ -1107,6 +1107,11 @@ static int nc_dma_get_range(struct device *dev, u64 *size) · 1106 unmodified lines | ||
| 1107 | 1107 | |
| 1108 | 1108 | ncomp = (struct acpi_iort_named_component *)node->node_data; |
| 1109 | 1109 | |
| 1110 | + if (!ncomp->memory_address_limit) { | |
| 1111 | + pr_warn(FW_BUG "Named component missing memory address limit\n"); | |
| 1112 | + return -EINVAL; | |
| 1113 | + } | |
| 1114 | + | |
| 1110 | 1115 | *size = ncomp->memory_address_limit >= 64 ? U64_MAX : |
| 1111 | 1116 | 1ULL<<ncomp->memory_address_limit; |
| 1112 | 1117 | |
| @@ -1126,6 +1131,11 @@ static int rc_dma_get_range(struct device *dev, u64 *size) · 13 unmodified lines | ||
| 1126 | 1131 | |
| 1127 | 1132 | rc = (struct acpi_iort_root_complex *)node->node_data; |
| 1128 | 1133 | |
| 1134 | + if (!rc->memory_address_limit) { | |
| 1135 | + pr_warn(FW_BUG "Root complex missing memory address limit\n"); | |
| 1136 | + return -EINVAL; | |
| 1137 | + } | |
| 1138 | + | |
| 1129 | 1139 | *size = rc->memory_address_limit >= 64 ? U64_MAX : |
| 1130 | 1140 | 1ULL<<rc->memory_address_limit; |
| 1131 | 1141 | |
| @@ -1173,8 +1183,8 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size) · 41 unmodified lines | ||
| 1173 | 1183 | end = dmaaddr + size - 1; |
| 1174 | 1184 | mask = DMA_BIT_MASK(ilog2(end) + 1); |
| 1175 | 1185 | dev->bus_dma_limit = end; |
| 1176 | − dev->coherent_dma_mask = mask; | |
| 1177 | − *dev->dma_mask = mask; | |
| 1186 | + dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask); | |
| 1187 | + *dev->dma_mask = min(*dev->dma_mask, mask); | |
| 1178 | 1188 | } |
| 1179 | 1189 | |
| 1180 | 1190 | *dma_addr = dmaaddr; |
| @@ -251,20 +251,12 @@ int __acpi_device_uevent_modalias(struct acpi_device *adev, · 250 unmodified lines | ||
| 251 | 251 | if (add_uevent_var(env, "MODALIAS=")) |
| 252 | 252 | return -ENOMEM; |
| 253 | 253 | |
| 254 | − len = create_pnp_modalias(adev, &env->buf[env->buflen - 1], | |
| 255 | − sizeof(env->buf) - env->buflen); | |
| 256 | − if (len < 0) | |
| 257 | − return len; | |
| 258 | − | |
| 259 | − env->buflen += len; | |
| 260 | − if (!adev->data.of_compatible) | |
| 261 | − return 0; | |
| 262 | − | |
| 263 | − if (len > 0 && add_uevent_var(env, "MODALIAS=")) | |
| 264 | − return -ENOMEM; | |
| 265 | − | |
| 266 | − len = create_of_modalias(adev, &env->buf[env->buflen - 1], | |
| 267 | − sizeof(env->buf) - env->buflen); | |
| 254 | + if (adev->data.of_compatible) | |
| 255 | + len = create_of_modalias(adev, &env->buf[env->buflen - 1], | |
| 256 | + sizeof(env->buf) - env->buflen); | |
| 257 | + else | |
| 258 | + len = create_pnp_modalias(adev, &env->buf[env->buflen - 1], | |
| 259 | + sizeof(env->buf) - env->buflen); | |
| 268 | 260 | if (len < 0) |
| 269 | 261 | return len; |
| 270 | 262 | |
| @@ -97,7 +97,7 @@ void acpi_scan_table_handler(u32 event, void *table, void *context); · 96 unmodified lines | ||
| 97 | 97 | extern struct list_head acpi_bus_id_list; |
| 98 | 98 | |
| 99 | 99 | struct acpi_device_bus_id { |
| 100 | − char bus_id[15]; | |
| 100 | + const char *bus_id; | |
| 101 | 101 | unsigned int instance_no; |
| 102 | 102 | struct list_head node; |
| 103 | 103 | }; |
| @@ -2269,40 +2269,24 @@ static const struct attribute_group *acpi_nfit_region_attribute_groups[] = { · 2268 unmodified lines | ||
| 2269 | 2269 | |
| 2270 | 2270 | /* enough info to uniquely specify an interleave set */ |
| 2271 | 2271 | struct nfit_set_info { |
| 2272 | − struct nfit_set_info_map { | |
| 2273 | − u64 region_offset; | |
| 2274 | − u32 serial_number; | |
| 2275 | − u32 pad; | |
| 2276 | − } mapping[0]; | |
| 2272 | + u64 region_offset; | |
| 2273 | + u32 serial_number; | |
| 2274 | + u32 pad; | |
| 2277 | 2275 | }; |
| 2278 | 2276 | |
| 2279 | 2277 | struct nfit_set_info2 { |
| 2280 | − struct nfit_set_info_map2 { | |
| 2281 | − u64 region_offset; | |
| 2282 | − u32 serial_number; | |
| 2283 | − u16 vendor_id; | |
| 2284 | − u16 manufacturing_date; | |
| 2285 | − u8 manufacturing_location; | |
| 2286 | − u8 reserved[31]; | |
| 2287 | − } mapping[0]; | |
| 2278 | + u64 region_offset; | |
| 2279 | + u32 serial_number; | |
| 2280 | + u16 vendor_id; | |
| 2281 | + u16 manufacturing_date; | |
| 2282 | + u8 manufacturing_location; | |
| 2283 | + u8 reserved[31]; | |
| 2288 | 2284 | }; |
| 2289 | 2285 | |
| 2290 | −static size_t sizeof_nfit_set_info(int num_mappings) | |
| 2291 | −{ | |
| 2292 | − return sizeof(struct nfit_set_info) | |
| 2293 | − + num_mappings * sizeof(struct nfit_set_info_map); | |
| 2294 | −} | |
| 2295 | − | |
| 2296 | −static size_t sizeof_nfit_set_info2(int num_mappings) | |
| 2297 | −{ | |
| 2298 | − return sizeof(struct nfit_set_info2) | |
| 2299 | − + num_mappings * sizeof(struct nfit_set_info_map2); | |
| 2300 | −} | |
| 2301 | − | |
| 2302 | 2286 | static int cmp_map_compat(const void *m0, const void *m1) |
| 2303 | 2287 | { |
| 2304 | − const struct nfit_set_info_map *map0 = m0; | |
| 2305 | − const struct nfit_set_info_map *map1 = m1; | |
| 2288 | + const struct nfit_set_info *map0 = m0; | |
| 2289 | + const struct nfit_set_info *map1 = m1; | |
| 2306 | 2290 | |
| 2307 | 2291 | return memcmp(&map0->region_offset, &map1->region_offset, |
| 2308 | 2292 | sizeof(u64)); |
| @@ -2310,8 +2294,8 @@ static int cmp_map_compat(const void *m0, const void *m1) · 1 unmodified line | ||
| 2310 | 2294 | |
| 2311 | 2295 | static int cmp_map(const void *m0, const void *m1) |
| 2312 | 2296 | { |
| 2313 | − const struct nfit_set_info_map *map0 = m0; | |
| 2314 | − const struct nfit_set_info_map *map1 = m1; | |
| 2297 | + const struct nfit_set_info *map0 = m0; | |
| 2298 | + const struct nfit_set_info *map1 = m1; | |
| 2315 | 2299 | |
| 2316 | 2300 | if (map0->region_offset < map1->region_offset) |
| 2317 | 2301 | return -1; |
| @@ -2322,8 +2306,8 @@ static int cmp_map(const void *m0, const void *m1) · 4 unmodified lines | ||
| 2322 | 2306 | |
| 2323 | 2307 | static int cmp_map2(const void *m0, const void *m1) |
| 2324 | 2308 | { |
| 2325 | − const struct nfit_set_info_map2 *map0 = m0; | |
| 2326 | − const struct nfit_set_info_map2 *map1 = m1; | |
| 2309 | + const struct nfit_set_info2 *map0 = m0; | |
| 2310 | + const struct nfit_set_info2 *map1 = m1; | |
| 2327 | 2311 | |
| 2328 | 2312 | if (map0->region_offset < map1->region_offset) |
| 2329 | 2313 | return -1; |
| @@ -2361,22 +2345,22 @@ static int acpi_nfit_init_interleave_set(struct acpi_nfit_desc *acpi_desc, · 31 unmodified lines | ||
| 2361 | 2345 | return -ENOMEM; |
| 2362 | 2346 | import_guid(&nd_set->type_guid, spa->range_guid); |
| 2363 | 2347 | |
| 2364 | − info = devm_kzalloc(dev, sizeof_nfit_set_info(nr), GFP_KERNEL); | |
| 2348 | + info = devm_kcalloc(dev, nr, sizeof(*info), GFP_KERNEL); | |
| 2365 | 2349 | if (!info) |
| 2366 | 2350 | return -ENOMEM; |
| 2367 | 2351 | |
| 2368 | − info2 = devm_kzalloc(dev, sizeof_nfit_set_info2(nr), GFP_KERNEL); | |
| 2352 | + info2 = devm_kcalloc(dev, nr, sizeof(*info2), GFP_KERNEL); | |
| 2369 | 2353 | if (!info2) |
| 2370 | 2354 | return -ENOMEM; |
| 2371 | 2355 | |
| 2372 | 2356 | for (i = 0; i < nr; i++) { |
| 2373 | 2357 | struct nd_mapping_desc *mapping = &ndr_desc->mapping[i]; |
| 2374 | − struct nfit_set_info_map *map = &info->mapping[i]; | |
| 2375 | − struct nfit_set_info_map2 *map2 = &info2->mapping[i]; | |
| 2376 | 2358 | struct nvdimm *nvdimm = mapping->nvdimm; |
| 2377 | 2359 | struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); |
| 2378 | − struct acpi_nfit_memory_map *memdev = memdev_from_spa(acpi_desc, | |
| 2379 | − spa->range_index, i); | |
| 2360 | + struct nfit_set_info *map = &info[i]; | |
| 2361 | + struct nfit_set_info2 *map2 = &info2[i]; | |
| 2362 | + struct acpi_nfit_memory_map *memdev = | |
| 2363 | + memdev_from_spa(acpi_desc, spa->range_index, i); | |
| 2380 | 2364 | struct acpi_nfit_control_region *dcr = nfit_mem->dcr; |
| 2381 | 2365 | |
| 2382 | 2366 | if (!memdev || !nfit_mem->dcr) { |
| @@ -2395,23 +2379,20 @@ static int acpi_nfit_init_interleave_set(struct acpi_nfit_desc *acpi_desc, · 12 unmodified lines | ||
| 2395 | 2379 | } |
| 2396 | 2380 | |
| 2397 | 2381 | /* v1.1 namespaces */ |
| 2398 | − sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map), | |
| 2399 | − cmp_map, NULL); | |
| 2400 | − nd_set->cookie1 = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0); | |
| 2382 | + sort(info, nr, sizeof(*info), cmp_map, NULL); | |
| 2383 | + nd_set->cookie1 = nd_fletcher64(info, sizeof(*info) * nr, 0); | |
| 2401 | 2384 | |
| 2402 | 2385 | /* v1.2 namespaces */ |
| 2403 | − sort(&info2->mapping[0], nr, sizeof(struct nfit_set_info_map2), | |
| 2404 | − cmp_map2, NULL); | |
| 2405 | − nd_set->cookie2 = nd_fletcher64(info2, sizeof_nfit_set_info2(nr), 0); | |
| 2386 | + sort(info2, nr, sizeof(*info2), cmp_map2, NULL); | |
| 2387 | + nd_set->cookie2 = nd_fletcher64(info2, sizeof(*info2) * nr, 0); | |
| 2406 | 2388 | |
| 2407 | 2389 | /* support v1.1 namespaces created with the wrong sort order */ |
| 2408 | − sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map), | |
| 2409 | − cmp_map_compat, NULL); | |
| 2410 | − nd_set->altcookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0); | |
| 2390 | + sort(info, nr, sizeof(*info), cmp_map_compat, NULL); | |
| 2391 | + nd_set->altcookie = nd_fletcher64(info, sizeof(*info) * nr, 0); | |
| 2411 | 2392 | |
| 2412 | 2393 | /* record the result of the sort for the mapping position */ |
| 2413 | 2394 | for (i = 0; i < nr; i++) { |
| 2414 | − struct nfit_set_info_map2 *map2 = &info2->mapping[i]; | |
| 2395 | + struct nfit_set_info2 *map2 = &info2[i]; | |
| 2415 | 2396 | int j; |
| 2416 | 2397 | |
| 2417 | 2398 | for (j = 0; j < nr; j++) { |
| @@ -486,6 +486,7 @@ static void acpi_device_del(struct acpi_device *device) · 485 unmodified lines | ||
| 486 | 486 | acpi_device_bus_id->instance_no--; |
| 487 | 487 | else { |
| 488 | 488 | list_del(&acpi_device_bus_id->node); |
| 489 | + kfree_const(acpi_device_bus_id->bus_id); | |
| 489 | 490 | kfree(acpi_device_bus_id); |
| 490 | 491 | } |
| 491 | 492 | break; |
| @@ -585,6 +586,8 @@ static int acpi_get_device_data(acpi_handle handle, struct acpi_device **device, · 93 unmodified lines | ||
| 585 | 586 | if (!device) |
| 586 | 587 | return -EINVAL; |
| 587 | 588 | |
| 589 | + *device = NULL; | |
| 590 | + | |
| 588 | 591 | status = acpi_get_data_full(handle, acpi_scan_drop_device, |
| 589 | 592 | (void **)device, callback); |
| 590 | 593 | if (ACPI_FAILURE(status) || !*device) { |
| @@ -674,7 +677,14 @@ int acpi_device_add(struct acpi_device *device, · 83 unmodified lines | ||
| 674 | 677 | } |
| 675 | 678 | if (!found) { |
| 676 | 679 | acpi_device_bus_id = new_bus_id; |
| 677 | − strcpy(acpi_device_bus_id->bus_id, acpi_device_hid(device)); | |
| 680 | + acpi_device_bus_id->bus_id = | |
| 681 | + kstrdup_const(acpi_device_hid(device), GFP_KERNEL); | |
| 682 | + if (!acpi_device_bus_id->bus_id) { | |
| 683 | + pr_err(PREFIX "Memory allocation error for bus id\n"); | |
| 684 | + result = -ENOMEM; | |
| 685 | + goto err_free_new_bus_id; | |
| 686 | + } | |
| 687 | + | |
| 678 | 688 | acpi_device_bus_id->instance_no = 0; |
| 679 | 689 | list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); |
| 680 | 690 | } |
| @@ -709,6 +719,11 @@ int acpi_device_add(struct acpi_device *device, · 28 unmodified lines | ||
| 709 | 719 | if (device->parent) |
| 710 | 720 | list_del(&device->node); |
| 711 | 721 | list_del(&device->wakeup_list); |
| 722 | + | |
| 723 | + err_free_new_bus_id: | |
| 724 | + if (!found) | |
| 725 | + kfree(new_bus_id); | |
| 726 | + | |
| 712 | 727 | mutex_unlock(&acpi_device_lock); |
| 713 | 728 | |
| 714 | 729 | err_detach: |
| @@ -2108,12 +2123,12 @@ void acpi_walk_dep_device_list(acpi_handle handle) · 1393 unmodified lines | ||
| 2108 | 2123 | list_for_each_entry_safe(dep, tmp, &acpi_dep_list, node) { |
| 2109 | 2124 | if (dep->supplier == handle) { |
| 2110 | 2125 | acpi_bus_get_device(dep->consumer, &adev); |
| 2111 | − if (!adev) | |
| 2112 | − continue; | |
| 2113 | 2126 | |
| 2114 | − adev->dep_unmet--; | |
| 2115 | − if (!adev->dep_unmet) | |
| 2116 | − acpi_bus_attach(adev, true); | |
| 2127 | + if (adev) { | |
| 2128 | + adev->dep_unmet--; | |
| 2129 | + if (!adev->dep_unmet) | |
| 2130 | + acpi_bus_attach(adev, true); | |
| 2131 | + } | |
| 2117 | 2132 | |
| 2118 | 2133 | list_del(&dep->node); |
| 2119 | 2134 | kfree(dep); |
| @@ -174,6 +174,8 @@ struct acpi_thermal { · 173 unmodified lines | ||
| 174 | 174 | struct thermal_zone_device *thermal_zone; |
| 175 | 175 | int kelvin_offset; /* in millidegrees */ |
| 176 | 176 | struct work_struct thermal_check_work; |
| 177 | + struct mutex thermal_check_lock; | |
| 178 | + refcount_t thermal_check_count; | |
| 177 | 179 | }; |
| 178 | 180 | |
| 179 | 181 | /* -------------------------------------------------------------------------- |
| @@ -495,14 +497,6 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) · 315 unmodified lines | ||
| 495 | 497 | return 0; |
| 496 | 498 | } |
| 497 | 499 | |
| 498 | −static void acpi_thermal_check(void *data) | |
| 499 | −{ | |
| 500 | − struct acpi_thermal *tz = data; | |
| 501 | − | |
| 502 | − thermal_zone_device_update(tz->thermal_zone, | |
| 503 | − THERMAL_EVENT_UNSPECIFIED); | |
| 504 | −} | |
| 505 | − | |
| 506 | 500 | /* sys I/F for generic thermal sysfs support */ |
| 507 | 501 | |
| 508 | 502 | static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp) |
| @@ -900,6 +894,12 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz) · 391 unmodified lines | ||
| 900 | 894 | Driver Interface |
| 901 | 895 | -------------------------------------------------------------------------- */ |
| 902 | 896 | |
| 897 | +static void acpi_queue_thermal_check(struct acpi_thermal *tz) | |
| 898 | +{ | |
| 899 | + if (!work_pending(&tz->thermal_check_work)) | |
| 900 | + queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work); | |
| 901 | +} | |
| 902 | + | |
| 903 | 903 | static void acpi_thermal_notify(struct acpi_device *device, u32 event) |
| 904 | 904 | { |
| 905 | 905 | struct acpi_thermal *tz = acpi_driver_data(device); |
| @@ -910,17 +910,17 @@ static void acpi_thermal_notify(struct acpi_device *device, u32 event) · 4 unmodified lines | ||
| 910 | 910 | |
| 911 | 911 | switch (event) { |
| 912 | 912 | case ACPI_THERMAL_NOTIFY_TEMPERATURE: |
| 913 | − acpi_thermal_check(tz); | |
| 913 | + acpi_queue_thermal_check(tz); | |
| 914 | 914 | break; |
| 915 | 915 | case ACPI_THERMAL_NOTIFY_THRESHOLDS: |
| 916 | 916 | acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS); |
| 917 | − acpi_thermal_check(tz); | |
| 917 | + acpi_queue_thermal_check(tz); | |
| 918 | 918 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
| 919 | 919 | dev_name(&device->dev), event, 0); |
| 920 | 920 | break; |
| 921 | 921 | case ACPI_THERMAL_NOTIFY_DEVICES: |
| 922 | 922 | acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES); |
| 923 | − acpi_thermal_check(tz); | |
| 923 | + acpi_queue_thermal_check(tz); | |
| 924 | 924 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
| 925 | 925 | dev_name(&device->dev), event, 0); |
| 926 | 926 | break; |
| @@ -1020,7 +1020,25 @@ static void acpi_thermal_check_fn(struct work_struct *work) · 93 unmodified lines | ||
| 1020 | 1020 | { |
| 1021 | 1021 | struct acpi_thermal *tz = container_of(work, struct acpi_thermal, |
| 1022 | 1022 | thermal_check_work); |
| 1023 | − acpi_thermal_check(tz); | |
| 1023 | + | |
| 1024 | + /* | |
| 1025 | + * In general, it is not sufficient to check the pending bit, because | |
| 1026 | + * subsequent instances of this function may be queued after one of them | |
| 1027 | + * has started running (e.g. if _TMP sleeps). Avoid bailing out if just | |
| 1028 | + * one of them is running, though, because it may have done the actual | |
| 1029 | + * check some time ago, so allow at least one of them to block on the | |
| 1030 | + * mutex while another one is running the update. | |
| 1031 | + */ | |
| 1032 | + if (!refcount_dec_not_one(&tz->thermal_check_count)) | |
| 1033 | + return; | |
| 1034 | + | |
| 1035 | + mutex_lock(&tz->thermal_check_lock); | |
| 1036 | + | |
| 1037 | + thermal_zone_device_update(tz->thermal_zone, THERMAL_EVENT_UNSPECIFIED); | |
| 1038 | + | |
| 1039 | + refcount_inc(&tz->thermal_check_count); | |
| 1040 | + | |
| 1041 | + mutex_unlock(&tz->thermal_check_lock); | |
| 1024 | 1042 | } |
| 1025 | 1043 | |
| 1026 | 1044 | static int acpi_thermal_add(struct acpi_device *device) |
| @@ -1052,6 +1070,8 @@ static int acpi_thermal_add(struct acpi_device *device) · 25 unmodified lines | ||
| 1052 | 1070 | if (result) |
| 1053 | 1071 | goto free_memory; |
| 1054 | 1072 | |
| 1073 | + refcount_set(&tz->thermal_check_count, 3); | |
| 1074 | + mutex_init(&tz->thermal_check_lock); | |
| 1055 | 1075 | INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn); |
| 1056 | 1076 | |
| 1057 | 1077 | pr_info(PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device), |
| @@ -1117,7 +1137,7 @@ static int acpi_thermal_resume(struct device *dev) · 59 unmodified lines | ||
| 1117 | 1137 | tz->state.active |= tz->trips.active[i].flags.enabled; |
| 1118 | 1138 | } |
| 1119 | 1139 | |
| 1120 | − queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work); | |
| 1140 | + acpi_queue_thermal_check(tz); | |
| 1121 | 1141 | |
| 1122 | 1142 | return AE_OK; |
| 1123 | 1143 | } |
| @@ -105,18 +105,8 @@ static void lpi_device_get_constraints_amd(void) · 104 unmodified lines | ||
| 105 | 105 | |
| 106 | 106 | for (i = 0; i < out_obj->package.count; i++) { |
| 107 | 107 | union acpi_object *package = &out_obj->package.elements[i]; |
| 108 | − struct lpi_device_info_amd info = { }; | |
| 109 | 108 | |
| 110 | − if (package->type == ACPI_TYPE_INTEGER) { | |
| 111 | − switch (i) { | |
| 112 | − case 0: | |
| 113 | − info.revision = package->integer.value; | |
| 114 | − break; | |
| 115 | − case 1: | |
| 116 | − info.count = package->integer.value; | |
| 117 | − break; | |
| 118 | − } | |
| 119 | − } else if (package->type == ACPI_TYPE_PACKAGE) { | |
| 109 | + if (package->type == ACPI_TYPE_PACKAGE) { | |
| 120 | 110 | lpi_constraints_table = kcalloc(package->package.count, |
| 121 | 111 | sizeof(*lpi_constraints_table), |
| 122 | 112 | GFP_KERNEL); |
| @@ -135,12 +125,10 @@ static void lpi_device_get_constraints_amd(void) · 12 unmodified lines | ||
| 135 | 125 | |
| 136 | 126 | for (k = 0; k < info_obj->package.count; ++k) { |
| 137 | 127 | union acpi_object *obj = &info_obj->package.elements[k]; |
| 138 | − union acpi_object *obj_new; | |
| 139 | 128 | |
| 140 | 129 | list = &lpi_constraints_table[lpi_constraints_table_size]; |
| 141 | 130 | list->min_dstate = -1; |
| 142 | 131 | |
| 143 | − obj_new = &obj[k]; | |
| 144 | 132 | switch (k) { |
| 145 | 133 | case 0: |
| 146 | 134 | dev_info.enabled = obj->integer.value; |
| @@ -3607,7 +3607,7 @@ static int idt77252_init_one(struct pci_dev *pcidev, · 3606 unmodified lines | ||
| 3607 | 3607 | |
| 3608 | 3608 | if ((err = dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32)))) { |
| 3609 | 3609 | printk("idt77252: can't enable DMA for PCI device at %s\n", pci_name(pcidev)); |
| 3610 | − return err; | |
| 3610 | + goto err_out_disable_pdev; | |
| 3611 | 3611 | } |
| 3612 | 3612 | |
| 3613 | 3613 | card = kzalloc(sizeof(struct idt77252_dev), GFP_KERNEL); |
| @@ -208,6 +208,16 @@ int device_links_read_lock_held(void) · 207 unmodified lines | ||
| 208 | 208 | #endif |
| 209 | 209 | #endif /* !CONFIG_SRCU */ |
| 210 | 210 | |
| 211 | +static bool device_is_ancestor(struct device *dev, struct device *target) | |
| 212 | +{ | |
| 213 | + while (target->parent) { | |
| 214 | + target = target->parent; | |
| 215 | + if (dev == target) | |
| 216 | + return true; | |
| 217 | + } | |
| 218 | + return false; | |
| 219 | +} | |
| 220 | + | |
| 211 | 221 | /** |
| 212 | 222 | * device_is_dependent - Check if one device depends on another one |
| 213 | 223 | * @dev: Device to check dependencies for. |
| @@ -221,7 +231,12 @@ int device_is_dependent(struct device *dev, void *target) · 7 unmodified lines | ||
| 221 | 231 | struct device_link *link; |
| 222 | 232 | int ret; |
| 223 | 233 | |
| 224 | − if (dev == target) | |
| 234 | + /* | |
| 235 | + * The "ancestors" check is needed to catch the case when the target | |
| 236 | + * device has not been completely initialized yet and it is still | |
| 237 | + * missing from the list of children of its parent device. | |
| 238 | + */ | |
| 239 | + if (dev == target || device_is_ancestor(dev, target)) | |
| 225 | 240 | return 1; |
| 226 | 241 | |
| 227 | 242 | ret = device_for_each_child(dev, target, device_is_dependent); |
| @@ -456,7 +471,9 @@ static int devlink_add_symlinks(struct device *dev, · 228 unmodified lines | ||
| 456 | 471 | struct device *con = link->consumer; |
| 457 | 472 | char *buf; |
| 458 | 473 | |
| 459 | − len = max(strlen(dev_name(sup)), strlen(dev_name(con))); | |
| 474 | + len = max(strlen(dev_bus_name(sup)) + strlen(dev_name(sup)), | |
| 475 | + strlen(dev_bus_name(con)) + strlen(dev_name(con))); | |
| 476 | + len += strlen(":"); | |
| 460 | 477 | len += strlen("supplier:") + 1; |
| 461 | 478 | buf = kzalloc(len, GFP_KERNEL); |
| 462 | 479 | if (!buf) |
| @@ -470,12 +487,12 @@ static int devlink_add_symlinks(struct device *dev, · 7 unmodified lines | ||
| 470 | 487 | if (ret) |
| 471 | 488 | goto err_con; |
| 472 | 489 | |
| 473 | − snprintf(buf, len, "consumer:%s", dev_name(con)); | |
| 490 | + snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con)); | |
| 474 | 491 | ret = sysfs_create_link(&sup->kobj, &link->link_dev.kobj, buf); |
| 475 | 492 | if (ret) |
| 476 | 493 | goto err_con_dev; |
| 477 | 494 | |
| 478 | − snprintf(buf, len, "supplier:%s", dev_name(sup)); | |
| 495 | + snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup)); | |
| 479 | 496 | ret = sysfs_create_link(&con->kobj, &link->link_dev.kobj, buf); |
| 480 | 497 | if (ret) |
| 481 | 498 | goto err_sup_dev; |
| @@ -483,7 +500,7 @@ static int devlink_add_symlinks(struct device *dev, · 1 unmodified line | ||
| 483 | 500 | goto out; |
| 484 | 501 | |
| 485 | 502 | err_sup_dev: |
| 486 | − snprintf(buf, len, "consumer:%s", dev_name(con)); | |
| 503 | + snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con)); | |
| 487 | 504 | sysfs_remove_link(&sup->kobj, buf); |
| 488 | 505 | err_con_dev: |
| 489 | 506 | sysfs_remove_link(&link->link_dev.kobj, "consumer"); |
| @@ -506,7 +523,9 @@ static void devlink_remove_symlinks(struct device *dev, · 16 unmodified lines | ||
| 506 | 523 | sysfs_remove_link(&link->link_dev.kobj, "consumer"); |
| 507 | 524 | sysfs_remove_link(&link->link_dev.kobj, "supplier"); |
| 508 | 525 | |
| 509 | − len = max(strlen(dev_name(sup)), strlen(dev_name(con))); | |
| 526 | + len = max(strlen(dev_bus_name(sup)) + strlen(dev_name(sup)), | |
| 527 | + strlen(dev_bus_name(con)) + strlen(dev_name(con))); | |
| 528 | + len += strlen(":"); | |
| 510 | 529 | len += strlen("supplier:") + 1; |
| 511 | 530 | buf = kzalloc(len, GFP_KERNEL); |
| 512 | 531 | if (!buf) { |
| @@ -514,9 +533,9 @@ static void devlink_remove_symlinks(struct device *dev, · 1 unmodified line | ||
| 514 | 533 | return; |
| 515 | 534 | } |
| 516 | 535 | |
| 517 | − snprintf(buf, len, "supplier:%s", dev_name(sup)); | |
| 536 | + snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup)); | |
| 518 | 537 | sysfs_remove_link(&con->kobj, buf); |
| 519 | − snprintf(buf, len, "consumer:%s", dev_name(con)); | |
| 538 | + snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con)); | |
| 520 | 539 | sysfs_remove_link(&sup->kobj, buf); |
| 521 | 540 | kfree(buf); |
| 522 | 541 | } |
| @@ -737,8 +756,9 @@ struct device_link *device_link_add(struct device *consumer, · 214 unmodified lines | ||
| 737 | 756 | |
| 738 | 757 | link->link_dev.class = &devlink_class; |
| 739 | 758 | device_set_pm_not_required(&link->link_dev); |
| 740 | − dev_set_name(&link->link_dev, "%s--%s", | |
| 741 | − dev_name(supplier), dev_name(consumer)); | |
| 759 | + dev_set_name(&link->link_dev, "%s:%s--%s:%s", | |
| 760 | + dev_bus_name(supplier), dev_name(supplier), | |
| 761 | + dev_bus_name(consumer), dev_name(consumer)); | |
| 742 | 762 | if (device_register(&link->link_dev)) { |
| 743 | 763 | put_device(consumer); |
| 744 | 764 | put_device(supplier); |
| @@ -1808,9 +1828,7 @@ const char *dev_driver_string(const struct device *dev) · 1063 unmodified lines | ||
| 1808 | 1828 | * never change once they are set, so they don't need special care. |
| 1809 | 1829 | */ |
| 1810 | 1830 | drv = READ_ONCE(dev->driver); |
| 1811 | − return drv ? drv->name : | |
| 1812 | − (dev->bus ? dev->bus->name : | |
| 1813 | − (dev->class ? dev->class->name : "")); | |
| 1831 | + return drv ? drv->name : dev_bus_name(dev); | |
| 1814 | 1832 | } |
| 1815 | 1833 | EXPORT_SYMBOL(dev_driver_string); |
| 1816 | 1834 | |
| @@ -4414,6 +4432,12 @@ static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) · 2597 unmodified lines | ||
| 4414 | 4432 | * |
| 4415 | 4433 | * Set the device's firmware node pointer to @fwnode, but if a secondary |
| 4416 | 4434 | * firmware node of the device is present, preserve it. |
| 4435 | + * | |
| 4436 | + * Valid fwnode cases are: | |
| 4437 | + * - primary --> secondary --> -ENODEV | |
| 4438 | + * - primary --> NULL | |
| 4439 | + * - secondary --> -ENODEV | |
| 4440 | + * - NULL | |
| 4417 | 4441 | */ |
| 4418 | 4442 | void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) |
| 4419 | 4443 | { |
| @@ -4432,8 +4456,9 @@ void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) · 12 unmodified lines | ||
| 4432 | 4456 | } else { |
| 4433 | 4457 | if (fwnode_is_primary(fn)) { |
| 4434 | 4458 | dev->fwnode = fn->secondary; |
| 4459 | + /* Set fn->secondary = NULL, so fn remains the primary fwnode */ | |
| 4435 | 4460 | if (!(parent && fn == parent->fwnode)) |
| 4436 | − fn->secondary = ERR_PTR(-ENODEV); | |
| 4461 | + fn->secondary = NULL; | |
| 4437 | 4462 | } else { |
| 4438 | 4463 | dev->fwnode = NULL; |
| 4439 | 4464 | } |
| @@ -370,13 +370,6 @@ static void driver_bound(struct device *dev) · 369 unmodified lines | ||
| 370 | 370 | |
| 371 | 371 | device_pm_check_callbacks(dev); |
| 372 | 372 | |
| 373 | − /* | |
| 374 | − * Reorder successfully probed devices to the end of the device list. | |
| 375 | − * This ensures that suspend/resume order matches probe order, which | |
| 376 | − * is usually what drivers rely on. | |
| 377 | − */ | |
| 378 | − device_pm_move_to_tail(dev); | |
| 379 | − | |
| 380 | 373 | /* |
| 381 | 374 | * Make sure the device is no longer in one of the deferred lists and |
| 382 | 375 | * kick off retrying all pending devices |
| @@ -619,6 +612,8 @@ dev_groups_failed: · 236 unmodified lines | ||
| 619 | 612 | else if (drv->remove) |
| 620 | 613 | drv->remove(dev); |
| 621 | 614 | probe_failed: |
| 615 | + kfree(dev->dma_range_map); | |
| 616 | + dev->dma_range_map = NULL; | |
| 622 | 617 | if (dev->bus) |
| 623 | 618 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
| 624 | 619 | BUS_NOTIFY_DRIVER_NOT_BOUND, dev); |
| @@ -366,6 +366,8 @@ int devm_platform_get_irqs_affinity(struct platform_device *dev, · 365 unmodified lines | ||
| 366 | 366 | return -ERANGE; |
| 367 | 367 | |
| 368 | 368 | nvec = platform_irq_count(dev); |
| 369 | + if (nvec < 0) | |
| 370 | + return nvec; | |
| 369 | 371 | |
| 370 | 372 | if (nvec < minvec) |
| 371 | 373 | return -ENOSPC; |
| @@ -582,8 +582,12 @@ void regmap_debugfs_init(struct regmap *map) · 581 unmodified lines | ||
| 582 | 582 | devname = dev_name(map->dev); |
| 583 | 583 | |
| 584 | 584 | if (name) { |
| 585 | − map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s", | |
| 585 | + if (!map->debugfs_name) { | |
| 586 | + map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s", | |
| 586 | 587 | devname, name); |
| 588 | + if (!map->debugfs_name) | |
| 589 | + return; | |
| 590 | + } | |
| 587 | 591 | name = map->debugfs_name; |
| 588 | 592 | } else { |
| 589 | 593 | name = devname; |
| @@ -591,9 +595,10 @@ void regmap_debugfs_init(struct regmap *map) · 1 unmodified line | ||
| 591 | 595 | |
| 592 | 596 | if (!strcmp(name, "dummy")) { |
| 593 | 597 | kfree(map->debugfs_name); |
| 594 | − | |
| 595 | 598 | map->debugfs_name = kasprintf(GFP_KERNEL, "dummy%d", |
| 596 | 599 | dummy_index); |
| 600 | + if (!map->debugfs_name) | |
| 601 | + return; | |
| 597 | 602 | name = map->debugfs_name; |
| 598 | 603 | dummy_index++; |
| 599 | 604 | } |
| @@ -445,6 +445,7 @@ config BLK_DEV_RBD · 444 unmodified lines | ||
| 445 | 445 | config BLK_DEV_RSXX |
| 446 | 446 | tristate "IBM Flash Adapter 900GB Full Height PCIe Device Driver" |
| 447 | 447 | depends on PCI |
| 448 | + select CRC32 | |
| 448 | 449 | help |
| 449 | 450 | Device driver for IBM's high speed PCIe SSD |
| 450 | 451 | storage device: Flash Adapter 900GB Full Height. |
| @@ -1022,6 +1022,12 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg, · 1021 unmodified lines | ||
| 1022 | 1022 | if (!sock) |
| 1023 | 1023 | return err; |
| 1024 | 1024 | |
| 1025 | + /* | |
| 1026 | + * We need to make sure we don't get any errant requests while we're | |
| 1027 | + * reallocating the ->socks array. | |
| 1028 | + */ | |
| 1029 | + blk_mq_freeze_queue(nbd->disk->queue); | |
| 1030 | + | |
| 1025 | 1031 | if (!netlink && !nbd->task_setup && |
| 1026 | 1032 | !test_bit(NBD_RT_BOUND, &config->runtime_flags)) |
| 1027 | 1033 | nbd->task_setup = current; |
| @@ -1060,10 +1066,12 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg, · 32 unmodified lines | ||
| 1060 | 1066 | nsock->cookie = 0; |
| 1061 | 1067 | socks[config->num_connections++] = nsock; |
| 1062 | 1068 | atomic_inc(&config->live_connections); |
| 1069 | + blk_mq_unfreeze_queue(nbd->disk->queue); | |
| 1063 | 1070 | |
| 1064 | 1071 | return 0; |
| 1065 | 1072 | |
| 1066 | 1073 | put_socket: |
| 1074 | + blk_mq_unfreeze_queue(nbd->disk->queue); | |
| 1067 | 1075 | sockfd_put(sock); |
| 1068 | 1076 | return err; |
| 1069 | 1077 | } |
| @@ -6,7 +6,10 @@ · 5 unmodified lines | ||
| 6 | 6 | #define CREATE_TRACE_POINTS |
| 7 | 7 | #include "trace.h" |
| 8 | 8 | |
| 9 | −#define MB_TO_SECTS(mb) (((sector_t)mb * SZ_1M) >> SECTOR_SHIFT) | |
| 9 | +static inline sector_t mb_to_sects(unsigned long mb) | |
| 10 | +{ | |
| 11 | + return ((sector_t)mb * SZ_1M) >> SECTOR_SHIFT; | |
| 12 | +} | |
| 10 | 13 | |
| 11 | 14 | static inline unsigned int null_zone_no(struct nullb_device *dev, sector_t sect) |
| 12 | 15 | { |
| @@ -77,12 +80,11 @@ int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q) · 64 unmodified lines | ||
| 77 | 80 | return -EINVAL; |
| 78 | 81 | } |
| 79 | 82 | |
| 80 | − zone_capacity_sects = MB_TO_SECTS(dev->zone_capacity); | |
| 81 | − dev_capacity_sects = MB_TO_SECTS(dev->size); | |
| 82 | − dev->zone_size_sects = MB_TO_SECTS(dev->zone_size); | |
| 83 | − dev->nr_zones = dev_capacity_sects >> ilog2(dev->zone_size_sects); | |
| 84 | − if (dev_capacity_sects & (dev->zone_size_sects - 1)) | |
| 85 | − dev->nr_zones++; | |
| 83 | + zone_capacity_sects = mb_to_sects(dev->zone_capacity); | |
| 84 | + dev_capacity_sects = mb_to_sects(dev->size); | |
| 85 | + dev->zone_size_sects = mb_to_sects(dev->zone_size); | |
| 86 | + dev->nr_zones = round_up(dev_capacity_sects, dev->zone_size_sects) | |
| 87 | + >> ilog2(dev->zone_size_sects); | |
| 86 | 88 | |
| 87 | 89 | dev->zones = kvmalloc_array(dev->nr_zones, sizeof(struct nullb_zone), |
| 88 | 90 | GFP_KERNEL | __GFP_ZERO); |
| @@ -7,6 +7,7 @@ config BLK_DEV_RNBD_CLIENT · 6 unmodified lines | ||
| 7 | 7 | tristate "RDMA Network Block Device driver client" |
| 8 | 8 | depends on INFINIBAND_RTRS_CLIENT |
| 9 | 9 | select BLK_DEV_RNBD |
| 10 | + select SG_POOL | |
| 10 | 11 | help |
| 11 | 12 | RNBD client is a network block device driver using rdma transport. |
| 12 | 13 | |
| @@ -90,3 +90,4 @@ Kleber Souza <kleber.souza@profitbricks.com> · 89 unmodified lines | ||
| 90 | 90 | Lutz Pogrell <lutz.pogrell@cloud.ionos.com> |
| 91 | 91 | Milind Dumbare <Milind.dumbare@gmail.com> |
| 92 | 92 | Roman Penyaev <roman.penyaev@profitbricks.com> |
| 93 | +Swapnil Ingle <ingleswapnil@gmail.com> | |
| @@ -375,12 +375,19 @@ static struct rnbd_iu *rnbd_get_iu(struct rnbd_clt_session *sess, · 374 unmodified lines | ||
| 375 | 375 | init_waitqueue_head(&iu->comp.wait); |
| 376 | 376 | iu->comp.errno = INT_MAX; |
| 377 | 377 | |
| 378 | + if (sg_alloc_table(&iu->sgt, 1, GFP_KERNEL)) { | |
| 379 | + rnbd_put_permit(sess, permit); | |
| 380 | + kfree(iu); | |
| 381 | + return NULL; | |
| 382 | + } | |
| 383 | + | |
| 378 | 384 | return iu; |
| 379 | 385 | } |
| 380 | 386 | |
| 381 | 387 | static void rnbd_put_iu(struct rnbd_clt_session *sess, struct rnbd_iu *iu) |
| 382 | 388 | { |
| 383 | 389 | if (atomic_dec_and_test(&iu->refcount)) { |
| 390 | + sg_free_table(&iu->sgt); | |
| 384 | 391 | rnbd_put_permit(sess, iu->permit); |
| 385 | 392 | kfree(iu); |
| 386 | 393 | } |
| @@ -487,8 +494,6 @@ static int send_msg_close(struct rnbd_clt_dev *dev, u32 device_id, bool wait) · 100 unmodified lines | ||
| 487 | 494 | iu->buf = NULL; |
| 488 | 495 | iu->dev = dev; |
| 489 | 496 | |
| 490 | − sg_alloc_table(&iu->sgt, 1, GFP_KERNEL); | |
| 491 | − | |
| 492 | 497 | msg.hdr.type = cpu_to_le16(RNBD_MSG_CLOSE); |
| 493 | 498 | msg.device_id = cpu_to_le32(device_id); |
| 494 | 499 | |
| @@ -502,7 +507,6 @@ static int send_msg_close(struct rnbd_clt_dev *dev, u32 device_id, bool wait) · 7 unmodified lines | ||
| 502 | 507 | err = errno; |
| 503 | 508 | } |
| 504 | 509 | |
| 505 | − sg_free_table(&iu->sgt); | |
| 506 | 510 | rnbd_put_iu(sess, iu); |
| 507 | 511 | return err; |
| 508 | 512 | } |
| @@ -575,7 +579,6 @@ static int send_msg_open(struct rnbd_clt_dev *dev, bool wait) · 66 unmodified lines | ||
| 575 | 579 | iu->buf = rsp; |
| 576 | 580 | iu->dev = dev; |
| 577 | 581 | |
| 578 | − sg_alloc_table(&iu->sgt, 1, GFP_KERNEL); | |
| 579 | 582 | sg_init_one(iu->sgt.sgl, rsp, sizeof(*rsp)); |
| 580 | 583 | |
| 581 | 584 | msg.hdr.type = cpu_to_le16(RNBD_MSG_OPEN); |
| @@ -594,7 +597,6 @@ static int send_msg_open(struct rnbd_clt_dev *dev, bool wait) · 12 unmodified lines | ||
| 594 | 597 | err = errno; |
| 595 | 598 | } |
| 596 | 599 | |
| 597 | − sg_free_table(&iu->sgt); | |
| 598 | 600 | rnbd_put_iu(sess, iu); |
| 599 | 601 | return err; |
| 600 | 602 | } |
| @@ -622,8 +624,6 @@ static int send_msg_sess_info(struct rnbd_clt_session *sess, bool wait) · 21 unmodified lines | ||
| 622 | 624 | |
| 623 | 625 | iu->buf = rsp; |
| 624 | 626 | iu->sess = sess; |
| 625 | − | |
| 626 | − sg_alloc_table(&iu->sgt, 1, GFP_KERNEL); | |
| 627 | 627 | sg_init_one(iu->sgt.sgl, rsp, sizeof(*rsp)); |
| 628 | 628 | |
| 629 | 629 | msg.hdr.type = cpu_to_le16(RNBD_MSG_SESS_INFO); |
| @@ -650,7 +650,6 @@ put_iu: · 20 unmodified lines | ||
| 650 | 650 | } else { |
| 651 | 651 | err = errno; |
| 652 | 652 | } |
| 653 | − sg_free_table(&iu->sgt); | |
| 654 | 653 | rnbd_put_iu(sess, iu); |
| 655 | 654 | return err; |
| 656 | 655 | } |
| @@ -1698,7 +1697,8 @@ static void rnbd_destroy_sessions(void) · 1041 unmodified lines | ||
| 1698 | 1697 | */ |
| 1699 | 1698 | |
| 1700 | 1699 | list_for_each_entry_safe(sess, sn, &sess_list, list) { |
| 1701 | − WARN_ON(!rnbd_clt_get_sess(sess)); | |
| 1700 | + if (!rnbd_clt_get_sess(sess)) | |
| 1701 | + continue; | |
| 1702 | 1702 | close_rtrs(sess); |
| 1703 | 1703 | list_for_each_entry_safe(dev, tn, &sess->devs_list, list) { |
| 1704 | 1704 | /* |
| @@ -338,10 +338,12 @@ static int rnbd_srv_link_ev(struct rtrs_srv *rtrs, · 337 unmodified lines | ||
| 338 | 338 | |
| 339 | 339 | void rnbd_srv_sess_dev_force_close(struct rnbd_srv_sess_dev *sess_dev) |
| 340 | 340 | { |
| 341 | − mutex_lock(&sess_dev->sess->lock); | |
| 342 | − rnbd_srv_destroy_dev_session_sysfs(sess_dev); | |
| 343 | − mutex_unlock(&sess_dev->sess->lock); | |
| 341 | + struct rnbd_srv_session *sess = sess_dev->sess; | |
| 342 | + | |
| 344 | 343 | sess_dev->keep_id = true; |
| 344 | + mutex_lock(&sess->lock); | |
| 345 | + rnbd_srv_destroy_dev_session_sysfs(sess_dev); | |
| 346 | + mutex_unlock(&sess->lock); | |
| 345 | 347 | } |
| 346 | 348 | |
| 347 | 349 | static int process_msg_close(struct rtrs_srv *rtrs, |
| @@ -945,7 +945,8 @@ static void blkif_set_queue_limits(struct blkfront_info *info) · 944 unmodified lines | ||
| 945 | 945 | if (info->feature_discard) { |
| 946 | 946 | blk_queue_flag_set(QUEUE_FLAG_DISCARD, rq); |
| 947 | 947 | blk_queue_max_discard_sectors(rq, get_capacity(gd)); |
| 948 | − rq->limits.discard_granularity = info->discard_granularity; | |
| 948 | + rq->limits.discard_granularity = info->discard_granularity ?: | |
| 949 | + info->physical_sector_size; | |
| 949 | 950 | rq->limits.discard_alignment = info->discard_alignment; |
| 950 | 951 | if (info->feature_secdiscard) |
| 951 | 952 | blk_queue_flag_set(QUEUE_FLAG_SECERASE, rq); |
| @@ -2179,19 +2180,12 @@ static void blkfront_closing(struct blkfront_info *info) · 1227 unmodified lines | ||
| 2179 | 2180 | |
| 2180 | 2181 | static void blkfront_setup_discard(struct blkfront_info *info) |
| 2181 | 2182 | { |
| 2182 | − int err; | |
| 2183 | − unsigned int discard_granularity; | |
| 2184 | − unsigned int discard_alignment; | |
| 2185 | − | |
| 2186 | 2183 | info->feature_discard = 1; |
| 2187 | − err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | |
| 2188 | − "discard-granularity", "%u", &discard_granularity, | |
| 2189 | − "discard-alignment", "%u", &discard_alignment, | |
| 2190 | − NULL); | |
| 2191 | − if (!err) { | |
| 2192 | − info->discard_granularity = discard_granularity; | |
| 2193 | − info->discard_alignment = discard_alignment; | |
| 2194 | − } | |
| 2184 | + info->discard_granularity = xenbus_read_unsigned(info->xbdev->otherend, | |
| 2185 | + "discard-granularity", | |
| 2186 | + 0); | |
| 2187 | + info->discard_alignment = xenbus_read_unsigned(info->xbdev->otherend, | |
| 2188 | + "discard-alignment", 0); | |
| 2195 | 2189 | info->feature_secdiscard = |
| 2196 | 2190 | !!xenbus_read_unsigned(info->xbdev->otherend, "discard-secure", |
| 2197 | 2191 | 0); |
| @@ -54,6 +54,7 @@ static int integrator_lm_populate(int num, struct device *dev) · 53 unmodified lines | ||
| 54 | 54 | ret = of_platform_default_populate(child, NULL, dev); |
| 55 | 55 | if (ret) { |
| 56 | 56 | dev_err(dev, "failed to populate module\n"); |
| 57 | + of_node_put(child); | |
| 57 | 58 | return ret; |
| 58 | 59 | } |
| 59 | 60 | } |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | static int simple_pm_bus_probe(struct platform_device *pdev) |
| 18 | 18 | { |
| 19 | + const struct of_dev_auxdata *lookup = dev_get_platdata(&pdev->dev); | |
| 19 | 20 | struct device_node *np = pdev->dev.of_node; |
| 20 | 21 | |
| 21 | 22 | dev_dbg(&pdev->dev, "%s\n", __func__); |
| @@ -23,7 +24,7 @@ static int simple_pm_bus_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 23 | 24 | pm_runtime_enable(&pdev->dev); |
| 24 | 25 | |
| 25 | 26 | if (np) |
| 26 | − of_platform_populate(np, NULL, NULL, &pdev->dev); | |
| 27 | + of_platform_populate(np, NULL, lookup, &pdev->dev); | |
| 27 | 28 | |
| 28 | 29 | return 0; |
| 29 | 30 | } |
| @@ -6,8 +6,6 @@ config MXC_CLK · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | config MXC_CLK_SCU |
| 8 | 8 | tristate |
| 9 | − depends on ARCH_MXC | |
| 10 | − depends on IMX_SCU && HAVE_ARM_SMCCC | |
| 11 | 9 | |
| 12 | 10 | config CLK_IMX1 |
| 13 | 11 | def_bool SOC_IMX1 |
| @@ -392,7 +392,8 @@ static int mmp2_audio_clk_remove(struct platform_device *pdev) · 391 unmodified lines | ||
| 392 | 392 | return 0; |
| 393 | 393 | } |
| 394 | 394 | |
| 395 | −static int __maybe_unused mmp2_audio_clk_suspend(struct device *dev) | |
| 395 | +#ifdef CONFIG_PM | |
| 396 | +static int mmp2_audio_clk_suspend(struct device *dev) | |
| 396 | 397 | { |
| 397 | 398 | struct mmp2_audio_clk *priv = dev_get_drvdata(dev); |
| 398 | 399 | |
| @@ -404,7 +405,7 @@ static int __maybe_unused mmp2_audio_clk_suspend(struct device *dev) · 5 unmodified lines | ||
| 404 | 405 | return 0; |
| 405 | 406 | } |
| 406 | 407 | |
| 407 | −static int __maybe_unused mmp2_audio_clk_resume(struct device *dev) | |
| 408 | +static int mmp2_audio_clk_resume(struct device *dev) | |
| 408 | 409 | { |
| 409 | 410 | struct mmp2_audio_clk *priv = dev_get_drvdata(dev); |
| 410 | 411 | |
| @@ -415,6 +416,7 @@ static int __maybe_unused mmp2_audio_clk_resume(struct device *dev) · 4 unmodified lines | ||
| 415 | 416 | |
| 416 | 417 | return 0; |
| 417 | 418 | } |
| 419 | +#endif | |
| 418 | 420 | |
| 419 | 421 | static const struct dev_pm_ops mmp2_audio_clk_pm_ops = { |
| 420 | 422 | SET_RUNTIME_PM_OPS(mmp2_audio_clk_suspend, mmp2_audio_clk_resume, NULL) |
| @@ -891,21 +891,6 @@ static struct clk_branch gcc_boot_rom_ahb_clk = { · 890 unmodified lines | ||
| 891 | 891 | }, |
| 892 | 892 | }; |
| 893 | 893 | |
| 894 | −static struct clk_branch gcc_camera_ahb_clk = { | |
| 895 | − .halt_reg = 0xb008, | |
| 896 | − .halt_check = BRANCH_HALT, | |
| 897 | − .hwcg_reg = 0xb008, | |
| 898 | − .hwcg_bit = 1, | |
| 899 | − .clkr = { | |
| 900 | − .enable_reg = 0xb008, | |
| 901 | − .enable_mask = BIT(0), | |
| 902 | − .hw.init = &(struct clk_init_data){ | |
| 903 | − .name = "gcc_camera_ahb_clk", | |
| 904 | − .ops = &clk_branch2_ops, | |
| 905 | − }, | |
| 906 | − }, | |
| 907 | −}; | |
| 908 | − | |
| 909 | 894 | static struct clk_branch gcc_camera_hf_axi_clk = { |
| 910 | 895 | .halt_reg = 0xb020, |
| 911 | 896 | .halt_check = BRANCH_HALT, |
| @@ -2317,7 +2302,6 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { · 1405 unmodified lines | ||
| 2317 | 2302 | [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr, |
| 2318 | 2303 | [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr, |
| 2319 | 2304 | [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, |
| 2320 | − [GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr, | |
| 2321 | 2305 | [GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr, |
| 2322 | 2306 | [GCC_CAMERA_THROTTLE_HF_AXI_CLK] = &gcc_camera_throttle_hf_axi_clk.clkr, |
| 2323 | 2307 | [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr, |
| @@ -2519,11 +2503,12 @@ static int gcc_sc7180_probe(struct platform_device *pdev) · 195 unmodified lines | ||
| 2519 | 2503 | |
| 2520 | 2504 | /* |
| 2521 | 2505 | * Keep the clocks always-ON |
| 2522 | − * GCC_CPUSS_GNOC_CLK, GCC_VIDEO_AHB_CLK, GCC_DISP_AHB_CLK | |
| 2523 | − * GCC_GPU_CFG_AHB_CLK | |
| 2506 | + * GCC_CPUSS_GNOC_CLK, GCC_VIDEO_AHB_CLK, GCC_CAMERA_AHB_CLK, | |
| 2507 | + * GCC_DISP_AHB_CLK, GCC_GPU_CFG_AHB_CLK | |
| 2524 | 2508 | */ |
| 2525 | 2509 | regmap_update_bits(regmap, 0x48004, BIT(0), BIT(0)); |
| 2526 | 2510 | regmap_update_bits(regmap, 0x0b004, BIT(0), BIT(0)); |
| 2511 | + regmap_update_bits(regmap, 0x0b008, BIT(0), BIT(0)); | |
| 2527 | 2512 | regmap_update_bits(regmap, 0x0b00c, BIT(0), BIT(0)); |
| 2528 | 2513 | regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0)); |
| 2529 | 2514 | |
| @@ -722,7 +722,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { · 721 unmodified lines | ||
| 722 | 722 | .name = "gcc_sdcc2_apps_clk_src", |
| 723 | 723 | .parent_data = gcc_parent_data_4, |
| 724 | 724 | .num_parents = 5, |
| 725 | − .ops = &clk_rcg2_ops, | |
| 725 | + .ops = &clk_rcg2_floor_ops, | |
| 726 | 726 | }, |
| 727 | 727 | }; |
| 728 | 728 | |
| @@ -745,7 +745,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { · 16 unmodified lines | ||
| 745 | 745 | .name = "gcc_sdcc4_apps_clk_src", |
| 746 | 746 | .parent_data = gcc_parent_data_0, |
| 747 | 747 | .num_parents = 3, |
| 748 | − .ops = &clk_rcg2_ops, | |
| 748 | + .ops = &clk_rcg2_floor_ops, | |
| 749 | 749 | }, |
| 750 | 750 | }; |
| 751 | 751 | |
| @@ -108,7 +108,7 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, · 107 unmodified lines | ||
| 108 | 108 | max_m = cmp->m.max ?: 1 << cmp->m.width; |
| 109 | 109 | max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); |
| 110 | 110 | |
| 111 | − if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { | |
| 111 | + if (!clk_hw_can_set_rate_parent(&cmp->common.hw)) { | |
| 112 | 112 | ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p); |
| 113 | 113 | rate = *parent_rate / p / m; |
| 114 | 114 | } else { |
| @@ -1256,6 +1256,8 @@ static struct tegra_clk_init_table init_table[] __initdata = { · 1255 unmodified lines | ||
| 1256 | 1256 | { TEGRA30_CLK_I2S3_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, |
| 1257 | 1257 | { TEGRA30_CLK_I2S4_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, |
| 1258 | 1258 | { TEGRA30_CLK_VIMCLK_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, |
| 1259 | + { TEGRA30_CLK_HDA, TEGRA30_CLK_PLL_P, 102000000, 0 }, | |
| 1260 | + { TEGRA30_CLK_HDA2CODEC_2X, TEGRA30_CLK_PLL_P, 48000000, 0 }, | |
| 1259 | 1261 | /* must be the last entry */ |
| 1260 | 1262 | { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 }, |
| 1261 | 1263 | }; |
| @@ -235,36 +235,6 @@ static ssize_t ti_eqep_position_ceiling_write(struct counter_device *counter, · 234 unmodified lines | ||
| 235 | 235 | return len; |
| 236 | 236 | } |
| 237 | 237 | |
| 238 | −static ssize_t ti_eqep_position_floor_read(struct counter_device *counter, | |
| 239 | − struct counter_count *count, | |
| 240 | − void *ext_priv, char *buf) | |
| 241 | −{ | |
| 242 | − struct ti_eqep_cnt *priv = counter->priv; | |
| 243 | − u32 qposinit; | |
| 244 | − | |
| 245 | − regmap_read(priv->regmap32, QPOSINIT, &qposinit); | |
| 246 | − | |
| 247 | − return sprintf(buf, "%u\n", qposinit); | |
| 248 | −} | |
| 249 | − | |
| 250 | −static ssize_t ti_eqep_position_floor_write(struct counter_device *counter, | |
| 251 | − struct counter_count *count, | |
| 252 | − void *ext_priv, const char *buf, | |
| 253 | − size_t len) | |
| 254 | −{ | |
| 255 | − struct ti_eqep_cnt *priv = counter->priv; | |
| 256 | − int err; | |
| 257 | − u32 res; | |
| 258 | − | |
| 259 | − err = kstrtouint(buf, 0, &res); | |
| 260 | − if (err < 0) | |
| 261 | − return err; | |
| 262 | − | |
| 263 | − regmap_write(priv->regmap32, QPOSINIT, res); | |
| 264 | − | |
| 265 | − return len; | |
| 266 | −} | |
| 267 | − | |
| 268 | 238 | static ssize_t ti_eqep_position_enable_read(struct counter_device *counter, |
| 269 | 239 | struct counter_count *count, |
| 270 | 240 | void *ext_priv, char *buf) |
| @@ -301,11 +271,6 @@ static struct counter_count_ext ti_eqep_position_ext[] = { · 30 unmodified lines | ||
| 301 | 271 | .read = ti_eqep_position_ceiling_read, |
| 302 | 272 | .write = ti_eqep_position_ceiling_write, |
| 303 | 273 | }, |
| 304 | − { | |
| 305 | − .name = "floor", | |
| 306 | − .read = ti_eqep_position_floor_read, | |
| 307 | − .write = ti_eqep_position_floor_write, | |
| 308 | − }, | |
| 309 | 274 | { |
| 310 | 275 | .name = "enable", |
| 311 | 276 | .read = ti_eqep_position_enable_read, |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/uaccess.h> |
| 27 | 27 | |
| 28 | 28 | #include <acpi/processor.h> |
| 29 | +#include <acpi/cppc_acpi.h> | |
| 29 | 30 | |
| 30 | 31 | #include <asm/msr.h> |
| 31 | 32 | #include <asm/processor.h> |
| @@ -53,6 +54,7 @@ struct acpi_cpufreq_data { · 21 unmodified lines | ||
| 53 | 54 | unsigned int resume; |
| 54 | 55 | unsigned int cpu_feature; |
| 55 | 56 | unsigned int acpi_perf_cpu; |
| 57 | + unsigned int first_perf_state; | |
| 56 | 58 | cpumask_var_t freqdomain_cpus; |
| 57 | 59 | void (*cpu_freq_write)(struct acpi_pct_register *reg, u32 val); |
| 58 | 60 | u32 (*cpu_freq_read)(struct acpi_pct_register *reg); |
| @@ -221,10 +223,10 @@ static unsigned extract_msr(struct cpufreq_policy *policy, u32 msr) · 162 unmodified lines | ||
| 221 | 223 | |
| 222 | 224 | perf = to_perf_data(data); |
| 223 | 225 | |
| 224 | − cpufreq_for_each_entry(pos, policy->freq_table) | |
| 226 | + cpufreq_for_each_entry(pos, policy->freq_table + data->first_perf_state) | |
| 225 | 227 | if (msr == perf->states[pos->driver_data].status) |
| 226 | 228 | return pos->frequency; |
| 227 | − return policy->freq_table[0].frequency; | |
| 229 | + return policy->freq_table[data->first_perf_state].frequency; | |
| 228 | 230 | } |
| 229 | 231 | |
| 230 | 232 | static unsigned extract_freq(struct cpufreq_policy *policy, u32 val) |
| @@ -363,6 +365,7 @@ static unsigned int get_cur_freq_on_cpu(unsigned int cpu) · 132 unmodified lines | ||
| 363 | 365 | struct cpufreq_policy *policy; |
| 364 | 366 | unsigned int freq; |
| 365 | 367 | unsigned int cached_freq; |
| 368 | + unsigned int state; | |
| 366 | 369 | |
| 367 | 370 | pr_debug("%s (%d)\n", __func__, cpu); |
| 368 | 371 | |
| @@ -374,7 +377,11 @@ static unsigned int get_cur_freq_on_cpu(unsigned int cpu) · 5 unmodified lines | ||
| 374 | 377 | if (unlikely(!data || !policy->freq_table)) |
| 375 | 378 | return 0; |
| 376 | 379 | |
| 377 | − cached_freq = policy->freq_table[to_perf_data(data)->state].frequency; | |
| 380 | + state = to_perf_data(data)->state; | |
| 381 | + if (state < data->first_perf_state) | |
| 382 | + state = data->first_perf_state; | |
| 383 | + | |
| 384 | + cached_freq = policy->freq_table[state].frequency; | |
| 378 | 385 | freq = extract_freq(policy, get_cur_val(cpumask_of(cpu), data)); |
| 379 | 386 | if (freq != cached_freq) { |
| 380 | 387 | /* |
| @@ -628,16 +635,54 @@ static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c) · 247 unmodified lines | ||
| 628 | 635 | } |
| 629 | 636 | #endif |
| 630 | 637 | |
| 638 | +#ifdef CONFIG_ACPI_CPPC_LIB | |
| 639 | +static u64 get_max_boost_ratio(unsigned int cpu) | |
| 640 | +{ | |
| 641 | + struct cppc_perf_caps perf_caps; | |
| 642 | + u64 highest_perf, nominal_perf; | |
| 643 | + int ret; | |
| 644 | + | |
| 645 | + if (acpi_pstate_strict) | |
| 646 | + return 0; | |
| 647 | + | |
| 648 | + ret = cppc_get_perf_caps(cpu, &perf_caps); | |
| 649 | + if (ret) { | |
| 650 | + pr_debug("CPU%d: Unable to get performance capabilities (%d)\n", | |
| 651 | + cpu, ret); | |
| 652 | + return 0; | |
| 653 | + } | |
| 654 | + | |
| 655 | + highest_perf = perf_caps.highest_perf; | |
| 656 | + nominal_perf = perf_caps.nominal_perf; | |
| 657 | + | |
| 658 | + if (!highest_perf || !nominal_perf) { | |
| 659 | + pr_debug("CPU%d: highest or nominal performance missing\n", cpu); | |
| 660 | + return 0; | |
| 661 | + } | |
| 662 | + | |
| 663 | + if (highest_perf < nominal_perf) { | |
| 664 | + pr_debug("CPU%d: nominal performance above highest\n", cpu); | |
| 665 | + return 0; | |
| 666 | + } | |
| 667 | + | |
| 668 | + return div_u64(highest_perf << SCHED_CAPACITY_SHIFT, nominal_perf); | |
| 669 | +} | |
| 670 | +#else | |
| 671 | +static inline u64 get_max_boost_ratio(unsigned int cpu) { return 0; } | |
| 672 | +#endif | |
| 673 | + | |
| 631 | 674 | static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) |
| 632 | 675 | { |
| 633 | − unsigned int i; | |
| 634 | − unsigned int valid_states = 0; | |
| 635 | − unsigned int cpu = policy->cpu; | |
| 676 | + struct cpufreq_frequency_table *freq_table; | |
| 677 | + struct acpi_processor_performance *perf; | |
| 636 | 678 | struct acpi_cpufreq_data *data; |
| 679 | + unsigned int cpu = policy->cpu; | |
| 680 | + struct cpuinfo_x86 *c = &cpu_data(cpu); | |
| 681 | + unsigned int valid_states = 0; | |
| 637 | 682 | unsigned int result = 0; |
| 638 | − struct cpuinfo_x86 *c = &cpu_data(policy->cpu); | |
| 639 | − struct acpi_processor_performance *perf; | |
| 640 | − struct cpufreq_frequency_table *freq_table; | |
| 683 | + unsigned int state_count; | |
| 684 | + u64 max_boost_ratio; | |
| 685 | + unsigned int i; | |
| 641 | 686 | #ifdef CONFIG_SMP |
| 642 | 687 | static int blacklisted; |
| 643 | 688 | #endif |
| @@ -750,8 +795,28 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) · 106 unmodified lines | ||
| 750 | 795 | goto err_unreg; |
| 751 | 796 | } |
| 752 | 797 | |
| 753 | − freq_table = kcalloc(perf->state_count + 1, sizeof(*freq_table), | |
| 754 | − GFP_KERNEL); | |
| 798 | + state_count = perf->state_count + 1; | |
| 799 | + | |
| 800 | + max_boost_ratio = get_max_boost_ratio(cpu); | |
| 801 | + if (max_boost_ratio) { | |
| 802 | + /* | |
| 803 | + * Make a room for one more entry to represent the highest | |
| 804 | + * available "boost" frequency. | |
| 805 | + */ | |
| 806 | + state_count++; | |
| 807 | + valid_states++; | |
| 808 | + data->first_perf_state = valid_states; | |
| 809 | + } else { | |
| 810 | + /* | |
| 811 | + * If the maximum "boost" frequency is unknown, ask the arch | |
| 812 | + * scale-invariance code to use the "nominal" performance for | |
| 813 | + * CPU utilization scaling so as to prevent the schedutil | |
| 814 | + * governor from selecting inadequate CPU frequencies. | |
| 815 | + */ | |
| 816 | + arch_set_max_freq_ratio(true); | |
| 817 | + } | |
| 818 | + | |
| 819 | + freq_table = kcalloc(state_count, sizeof(*freq_table), GFP_KERNEL); | |
| 755 | 820 | if (!freq_table) { |
| 756 | 821 | result = -ENOMEM; |
| 757 | 822 | goto err_unreg; |
| @@ -785,6 +850,30 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) · 27 unmodified lines | ||
| 785 | 850 | valid_states++; |
| 786 | 851 | } |
| 787 | 852 | freq_table[valid_states].frequency = CPUFREQ_TABLE_END; |
| 853 | + | |
| 854 | + if (max_boost_ratio) { | |
| 855 | + unsigned int state = data->first_perf_state; | |
| 856 | + unsigned int freq = freq_table[state].frequency; | |
| 857 | + | |
| 858 | + /* | |
| 859 | + * Because the loop above sorts the freq_table entries in the | |
| 860 | + * descending order, freq is the maximum frequency in the table. | |
| 861 | + * Assume that it corresponds to the CPPC nominal frequency and | |
| 862 | + * use it to populate the frequency field of the extra "boost" | |
| 863 | + * frequency entry. | |
| 864 | + */ | |
| 865 | + freq_table[0].frequency = freq * max_boost_ratio >> SCHED_CAPACITY_SHIFT; | |
| 866 | + /* | |
| 867 | + * The purpose of the extra "boost" frequency entry is to make | |
| 868 | + * the rest of cpufreq aware of the real maximum frequency, but | |
| 869 | + * the way to request it is the same as for the first_perf_state | |
| 870 | + * entry that is expected to cover the entire range of "boost" | |
| 871 | + * frequencies of the CPU, so copy the driver_data value from | |
| 872 | + * that entry. | |
| 873 | + */ | |
| 874 | + freq_table[0].driver_data = freq_table[state].driver_data; | |
| 875 | + } | |
| 876 | + | |
| 788 | 877 | policy->freq_table = freq_table; |
| 789 | 878 | perf->state = 0; |
| 790 | 879 | |
| @@ -858,8 +947,10 @@ static void acpi_cpufreq_cpu_ready(struct cpufreq_policy *policy) · 67 unmodified lines | ||
| 858 | 947 | { |
| 859 | 948 | struct acpi_processor_performance *perf = per_cpu_ptr(acpi_perf_data, |
| 860 | 949 | policy->cpu); |
| 950 | + struct acpi_cpufreq_data *data = policy->driver_data; | |
| 951 | + unsigned int freq = policy->freq_table[data->first_perf_state].frequency; | |
| 861 | 952 | |
| 862 | − if (perf->states[0].core_frequency * 1000 != policy->cpuinfo.max_freq) | |
| 953 | + if (perf->states[0].core_frequency * 1000 != freq) | |
| 863 | 954 | pr_warn(FW_WARN "P-state 0 is not max freq\n"); |
| 864 | 955 | } |
| 865 | 956 | |
| @@ -76,11 +76,6 @@ static inline int ceiling_fp(int32_t x) · 75 unmodified lines | ||
| 76 | 76 | return ret; |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | −static inline int32_t percent_fp(int percent) | |
| 80 | −{ | |
| 81 | − return div_fp(percent, 100); | |
| 82 | −} | |
| 83 | − | |
| 84 | 79 | static inline u64 mul_ext_fp(u64 x, u64 y) |
| 85 | 80 | { |
| 86 | 81 | return (x * y) >> EXT_FRAC_BITS; |
| @@ -91,11 +86,6 @@ static inline u64 div_ext_fp(u64 x, u64 y) · 4 unmodified lines | ||
| 91 | 86 | return div64_u64(x << EXT_FRAC_BITS, y); |
| 92 | 87 | } |
| 93 | 88 | |
| 94 | −static inline int32_t percent_ext_fp(int percent) | |
| 95 | −{ | |
| 96 | − return div_ext_fp(percent, 100); | |
| 97 | −} | |
| 98 | − | |
| 99 | 89 | /** |
| 100 | 90 | * struct sample - Store performance sample |
| 101 | 91 | * @core_avg_perf: Ratio of APERF/MPERF which is the actual average |
| @@ -2653,12 +2643,13 @@ static void intel_cpufreq_adjust_perf(unsigned int cpunum, · 2551 unmodified lines | ||
| 2653 | 2643 | unsigned long capacity) |
| 2654 | 2644 | { |
| 2655 | 2645 | struct cpudata *cpu = all_cpu_data[cpunum]; |
| 2646 | + u64 hwp_cap = READ_ONCE(cpu->hwp_cap_cached); | |
| 2656 | 2647 | int old_pstate = cpu->pstate.current_pstate; |
| 2657 | 2648 | int cap_pstate, min_pstate, max_pstate, target_pstate; |
| 2658 | 2649 | |
| 2659 | 2650 | update_turbo_state(); |
| 2660 | − cap_pstate = global.turbo_disabled ? cpu->pstate.max_pstate : | |
| 2661 | − cpu->pstate.turbo_pstate; | |
| 2651 | + cap_pstate = global.turbo_disabled ? HWP_GUARANTEED_PERF(hwp_cap) : | |
| 2652 | + HWP_HIGHEST_PERF(hwp_cap); | |
| 2662 | 2653 | |
| 2663 | 2654 | /* Optimization: Avoid unnecessary divisions. */ |
| 2664 | 2655 | |
| @@ -878,9 +878,9 @@ static int get_transition_latency(struct powernow_k8_data *data) · 877 unmodified lines | ||
| 878 | 878 | |
| 879 | 879 | /* Take a frequency, and issue the fid/vid transition command */ |
| 880 | 880 | static int transition_frequency_fidvid(struct powernow_k8_data *data, |
| 881 | − unsigned int index) | |
| 881 | + unsigned int index, | |
| 882 | + struct cpufreq_policy *policy) | |
| 882 | 883 | { |
| 883 | − struct cpufreq_policy *policy; | |
| 884 | 884 | u32 fid = 0; |
| 885 | 885 | u32 vid = 0; |
| 886 | 886 | int res; |
| @@ -912,9 +912,6 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, · 25 unmodified lines | ||
| 912 | 912 | freqs.old = find_khz_freq_from_fid(data->currfid); |
| 913 | 913 | freqs.new = find_khz_freq_from_fid(fid); |
| 914 | 914 | |
| 915 | − policy = cpufreq_cpu_get(smp_processor_id()); | |
| 916 | − cpufreq_cpu_put(policy); | |
| 917 | − | |
| 918 | 915 | cpufreq_freq_transition_begin(policy, &freqs); |
| 919 | 916 | res = transition_fid_vid(data, fid, vid); |
| 920 | 917 | cpufreq_freq_transition_end(policy, &freqs, res); |
| @@ -969,7 +966,7 @@ static long powernowk8_target_fn(void *arg) · 48 unmodified lines | ||
| 969 | 966 | |
| 970 | 967 | powernow_k8_acpi_pst_values(data, newstate); |
| 971 | 968 | |
| 972 | − ret = transition_frequency_fidvid(data, newstate); | |
| 969 | + ret = transition_frequency_fidvid(data, newstate, pol); | |
| 973 | 970 | |
| 974 | 971 | if (ret) { |
| 975 | 972 | pr_err("transition frequency failed\n"); |
| @@ -366,6 +366,7 @@ if CRYPTO_DEV_OMAP · 365 unmodified lines | ||
| 366 | 366 | config CRYPTO_DEV_OMAP_SHAM |
| 367 | 367 | tristate "Support for OMAP MD5/SHA1/SHA2 hw accelerator" |
| 368 | 368 | depends on ARCH_OMAP2PLUS |
| 369 | + select CRYPTO_ENGINE | |
| 369 | 370 | select CRYPTO_SHA1 |
| 370 | 371 | select CRYPTO_MD5 |
| 371 | 372 | select CRYPTO_SHA256 |
| @@ -300,11 +300,11 @@ struct mv_cesa_tdma_desc { · 299 unmodified lines | ||
| 300 | 300 | __le32 byte_cnt; |
| 301 | 301 | union { |
| 302 | 302 | __le32 src; |
| 303 | − dma_addr_t src_dma; | |
| 303 | + u32 src_dma; | |
| 304 | 304 | }; |
| 305 | 305 | union { |
| 306 | 306 | __le32 dst; |
| 307 | − dma_addr_t dst_dma; | |
| 307 | + u32 dst_dma; | |
| 308 | 308 | }; |
| 309 | 309 | __le32 next_dma; |
| 310 | 310 | |
| @@ -76,10 +76,6 @@ static void dma_buf_release(struct dentry *dentry) · 75 unmodified lines | ||
| 76 | 76 | |
| 77 | 77 | dmabuf->ops->release(dmabuf); |
| 78 | 78 | |
| 79 | − mutex_lock(&db_list.lock); | |
| 80 | − list_del(&dmabuf->list_node); | |
| 81 | − mutex_unlock(&db_list.lock); | |
| 82 | − | |
| 83 | 79 | if (dmabuf->resv == (struct dma_resv *)&dmabuf[1]) |
| 84 | 80 | dma_resv_fini(dmabuf->resv); |
| 85 | 81 | |
| @@ -88,6 +84,22 @@ static void dma_buf_release(struct dentry *dentry) · 2 unmodified lines | ||
| 88 | 84 | kfree(dmabuf); |
| 89 | 85 | } |
| 90 | 86 | |
| 87 | +static int dma_buf_file_release(struct inode *inode, struct file *file) | |
| 88 | +{ | |
| 89 | + struct dma_buf *dmabuf; | |
| 90 | + | |
| 91 | + if (!is_dma_buf_file(file)) | |
| 92 | + return -EINVAL; | |
| 93 | + | |
| 94 | + dmabuf = file->private_data; | |
| 95 | + | |
| 96 | + mutex_lock(&db_list.lock); | |
| 97 | + list_del(&dmabuf->list_node); | |
| 98 | + mutex_unlock(&db_list.lock); | |
| 99 | + | |
| 100 | + return 0; | |
| 101 | +} | |
| 102 | + | |
| 91 | 103 | static const struct dentry_operations dma_buf_dentry_ops = { |
| 92 | 104 | .d_dname = dmabuffs_dname, |
| 93 | 105 | .d_release = dma_buf_release, |
| @@ -413,6 +425,7 @@ static void dma_buf_show_fdinfo(struct seq_file *m, struct file *file) · 319 unmodified lines | ||
| 413 | 425 | } |
| 414 | 426 | |
| 415 | 427 | static const struct file_operations dma_buf_fops = { |
| 428 | + .release = dma_buf_file_release, | |
| 416 | 429 | .mmap = dma_buf_mmap_internal, |
| 417 | 430 | .llseek = dma_buf_llseek, |
| 418 | 431 | .poll = dma_buf_poll, |
| @@ -251,6 +251,9 @@ static void cma_heap_dma_buf_release(struct dma_buf *dmabuf) · 250 unmodified lines | ||
| 251 | 251 | buffer->vaddr = NULL; |
| 252 | 252 | } |
| 253 | 253 | |
| 254 | + /* free page list */ | |
| 255 | + kfree(buffer->pages); | |
| 256 | + /* release memory */ | |
| 254 | 257 | cma_release(cma_heap->cma, buffer->cma_pages, buffer->pagecount); |
| 255 | 258 | kfree(buffer); |
| 256 | 259 | } |
| @@ -1110,7 +1110,6 @@ static void __dma_async_device_channel_unregister(struct dma_device *device, · 1109 unmodified lines | ||
| 1110 | 1110 | "%s called while %d clients hold a reference\n", |
| 1111 | 1111 | __func__, chan->client_count); |
| 1112 | 1112 | mutex_lock(&dma_list_mutex); |
| 1113 | − list_del(&chan->device_node); | |
| 1114 | 1113 | device->chancnt--; |
| 1115 | 1114 | chan->dev->chan = NULL; |
| 1116 | 1115 | mutex_unlock(&dma_list_mutex); |
| @@ -86,12 +86,12 @@ static struct dw_edma_chunk *dw_edma_alloc_chunk(struct dw_edma_desc *desc) · 85 unmodified lines | ||
| 86 | 86 | |
| 87 | 87 | if (desc->chunk) { |
| 88 | 88 | /* Create and add new element into the linked list */ |
| 89 | − desc->chunks_alloc++; | |
| 90 | − list_add_tail(&chunk->list, &desc->chunk->list); | |
| 91 | 89 | if (!dw_edma_alloc_burst(chunk)) { |
| 92 | 90 | kfree(chunk); |
| 93 | 91 | return NULL; |
| 94 | 92 | } |
| 93 | + desc->chunks_alloc++; | |
| 94 | + list_add_tail(&chunk->list, &desc->chunk->list); | |
| 95 | 95 | } else { |
| 96 | 96 | /* List head */ |
| 97 | 97 | chunk->burst = NULL; |
| @@ -982,11 +982,8 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) · 981 unmodified lines | ||
| 982 | 982 | |
| 983 | 983 | dev_vdbg(chan2dev(chan), "%s\n", __func__); |
| 984 | 984 | |
| 985 | − pm_runtime_get_sync(dw->dma.dev); | |
| 986 | − | |
| 987 | 985 | /* ASSERT: channel is idle */ |
| 988 | 986 | if (dma_readl(dw, CH_EN) & dwc->mask) { |
| 989 | − pm_runtime_put_sync_suspend(dw->dma.dev); | |
| 990 | 987 | dev_dbg(chan2dev(chan), "DMA channel not idle?\n"); |
| 991 | 988 | return -EIO; |
| 992 | 989 | } |
| @@ -1003,7 +1000,6 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) · 10 unmodified lines | ||
| 1003 | 1000 | * We need controller-specific data to set up slave transfers. |
| 1004 | 1001 | */ |
| 1005 | 1002 | if (chan->private && !dw_dma_filter(chan, chan->private)) { |
| 1006 | − pm_runtime_put_sync_suspend(dw->dma.dev); | |
| 1007 | 1003 | dev_warn(chan2dev(chan), "Wrong controller-specific data\n"); |
| 1008 | 1004 | return -EINVAL; |
| 1009 | 1005 | } |
| @@ -1047,8 +1043,6 @@ static void dwc_free_chan_resources(struct dma_chan *chan) · 37 unmodified lines | ||
| 1047 | 1043 | if (!dw->in_use) |
| 1048 | 1044 | do_dw_dma_off(dw); |
| 1049 | 1045 | |
| 1050 | − pm_runtime_put_sync_suspend(dw->dma.dev); | |
| 1051 | − | |
| 1052 | 1046 | dev_vdbg(chan2dev(chan), "%s: done\n", __func__); |
| 1053 | 1047 | } |
| 1054 | 1048 | |
| @@ -398,17 +398,31 @@ static inline bool idxd_is_enabled(struct idxd_device *idxd) · 397 unmodified lines | ||
| 398 | 398 | return false; |
| 399 | 399 | } |
| 400 | 400 | |
| 401 | +static inline bool idxd_device_is_halted(struct idxd_device *idxd) | |
| 402 | +{ | |
| 403 | + union gensts_reg gensts; | |
| 404 | + | |
| 405 | + gensts.bits = ioread32(idxd->reg_base + IDXD_GENSTATS_OFFSET); | |
| 406 | + | |
| 407 | + return (gensts.state == IDXD_DEVICE_STATE_HALT); | |
| 408 | +} | |
| 409 | + | |
| 401 | 410 | /* |
| 402 | 411 | * This is function is only used for reset during probe and will |
| 403 | 412 | * poll for completion. Once the device is setup with interrupts, |
| 404 | 413 | * all commands will be done via interrupt completion. |
| 405 | 414 | */ |
| 406 | −void idxd_device_init_reset(struct idxd_device *idxd) | |
| 415 | +int idxd_device_init_reset(struct idxd_device *idxd) | |
| 407 | 416 | { |
| 408 | 417 | struct device *dev = &idxd->pdev->dev; |
| 409 | 418 | union idxd_command_reg cmd; |
| 410 | 419 | unsigned long flags; |
| 411 | 420 | |
| 421 | + if (idxd_device_is_halted(idxd)) { | |
| 422 | + dev_warn(&idxd->pdev->dev, "Device is HALTED!\n"); | |
| 423 | + return -ENXIO; | |
| 424 | + } | |
| 425 | + | |
| 412 | 426 | memset(&cmd, 0, sizeof(cmd)); |
| 413 | 427 | cmd.cmd = IDXD_CMD_RESET_DEVICE; |
| 414 | 428 | dev_dbg(dev, "%s: sending reset for init.\n", __func__); |
| @@ -419,6 +433,7 @@ void idxd_device_init_reset(struct idxd_device *idxd) · 4 unmodified lines | ||
| 419 | 433 | IDXD_CMDSTS_ACTIVE) |
| 420 | 434 | cpu_relax(); |
| 421 | 435 | spin_unlock_irqrestore(&idxd->dev_lock, flags); |
| 436 | + return 0; | |
| 422 | 437 | } |
| 423 | 438 | |
| 424 | 439 | static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand, |
| @@ -428,6 +443,12 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand, · 3 unmodified lines | ||
| 428 | 443 | DECLARE_COMPLETION_ONSTACK(done); |
| 429 | 444 | unsigned long flags; |
| 430 | 445 | |
| 446 | + if (idxd_device_is_halted(idxd)) { | |
| 447 | + dev_warn(&idxd->pdev->dev, "Device is HALTED!\n"); | |
| 448 | + *status = IDXD_CMDSTS_HW_ERR; | |
| 449 | + return; | |
| 450 | + } | |
| 451 | + | |
| 431 | 452 | memset(&cmd, 0, sizeof(cmd)); |
| 432 | 453 | cmd.cmd = cmd_code; |
| 433 | 454 | cmd.operand = operand; |
| @@ -205,5 +205,8 @@ int idxd_register_dma_channel(struct idxd_wq *wq) · 204 unmodified lines | ||
| 205 | 205 | |
| 206 | 206 | void idxd_unregister_dma_channel(struct idxd_wq *wq) |
| 207 | 207 | { |
| 208 | − dma_async_device_channel_unregister(&wq->idxd->dma_dev, &wq->dma_chan); | |
| 208 | + struct dma_chan *chan = &wq->dma_chan; | |
| 209 | + | |
| 210 | + dma_async_device_channel_unregister(&wq->idxd->dma_dev, chan); | |
| 211 | + list_del(&chan->device_node); | |
| 209 | 212 | } |
| @@ -326,7 +326,7 @@ void idxd_mask_msix_vector(struct idxd_device *idxd, int vec_id); · 325 unmodified lines | ||
| 326 | 326 | void idxd_unmask_msix_vector(struct idxd_device *idxd, int vec_id); |
| 327 | 327 | |
| 328 | 328 | /* device control */ |
| 329 | −void idxd_device_init_reset(struct idxd_device *idxd); | |
| 329 | +int idxd_device_init_reset(struct idxd_device *idxd); | |
| 330 | 330 | int idxd_device_enable(struct idxd_device *idxd); |
| 331 | 331 | int idxd_device_disable(struct idxd_device *idxd); |
| 332 | 332 | void idxd_device_reset(struct idxd_device *idxd); |
| @@ -335,7 +335,10 @@ static int idxd_probe(struct idxd_device *idxd) · 334 unmodified lines | ||
| 335 | 335 | int rc; |
| 336 | 336 | |
| 337 | 337 | dev_dbg(dev, "%s entered and resetting device\n", __func__); |
| 338 | − idxd_device_init_reset(idxd); | |
| 338 | + rc = idxd_device_init_reset(idxd); | |
| 339 | + if (rc < 0) | |
| 340 | + return rc; | |
| 341 | + | |
| 339 | 342 | dev_dbg(dev, "IDXD reset complete\n"); |
| 340 | 343 | |
| 341 | 344 | if (IS_ENABLED(CONFIG_INTEL_IDXD_SVM)) { |
| @@ -111,19 +111,14 @@ irqreturn_t idxd_irq_handler(int vec, void *data) · 110 unmodified lines | ||
| 111 | 111 | return IRQ_WAKE_THREAD; |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | −irqreturn_t idxd_misc_thread(int vec, void *data) | |
| 114 | +static int process_misc_interrupts(struct idxd_device *idxd, u32 cause) | |
| 115 | 115 | { |
| 116 | − struct idxd_irq_entry *irq_entry = data; | |
| 117 | − struct idxd_device *idxd = irq_entry->idxd; | |
| 118 | 116 | struct device *dev = &idxd->pdev->dev; |
| 119 | 117 | union gensts_reg gensts; |
| 120 | − u32 cause, val = 0; | |
| 118 | + u32 val = 0; | |
| 121 | 119 | int i; |
| 122 | 120 | bool err = false; |
| 123 | 121 | |
| 124 | − cause = ioread32(idxd->reg_base + IDXD_INTCAUSE_OFFSET); | |
| 125 | − iowrite32(cause, idxd->reg_base + IDXD_INTCAUSE_OFFSET); | |
| 126 | − | |
| 127 | 122 | if (cause & IDXD_INTC_ERR) { |
| 128 | 123 | spin_lock_bh(&idxd->dev_lock); |
| 129 | 124 | for (i = 0; i < 4; i++) |
| @@ -181,7 +176,7 @@ irqreturn_t idxd_misc_thread(int vec, void *data) · 51 unmodified lines | ||
| 181 | 176 | val); |
| 182 | 177 | |
| 183 | 178 | if (!err) |
| 184 | − goto out; | |
| 179 | + return 0; | |
| 185 | 180 | |
| 186 | 181 | /* |
| 187 | 182 | * This case should rarely happen and typically is due to software |
| @@ -211,37 +206,58 @@ irqreturn_t idxd_misc_thread(int vec, void *data) · 23 unmodified lines | ||
| 211 | 206 | gensts.reset_type == IDXD_DEVICE_RESET_FLR ? |
| 212 | 207 | "FLR" : "system reset"); |
| 213 | 208 | spin_unlock_bh(&idxd->dev_lock); |
| 209 | + return -ENXIO; | |
| 214 | 210 | } |
| 215 | 211 | } |
| 216 | 212 | |
| 217 | − out: | |
| 213 | + return 0; | |
| 214 | +} | |
| 215 | + | |
| 216 | +irqreturn_t idxd_misc_thread(int vec, void *data) | |
| 217 | +{ | |
| 218 | + struct idxd_irq_entry *irq_entry = data; | |
| 219 | + struct idxd_device *idxd = irq_entry->idxd; | |
| 220 | + int rc; | |
| 221 | + u32 cause; | |
| 222 | + | |
| 223 | + cause = ioread32(idxd->reg_base + IDXD_INTCAUSE_OFFSET); | |
| 224 | + if (cause) | |
| 225 | + iowrite32(cause, idxd->reg_base + IDXD_INTCAUSE_OFFSET); | |
| 226 | + | |
| 227 | + while (cause) { | |
| 228 | + rc = process_misc_interrupts(idxd, cause); | |
| 229 | + if (rc < 0) | |
| 230 | + break; | |
| 231 | + cause = ioread32(idxd->reg_base + IDXD_INTCAUSE_OFFSET); | |
| 232 | + if (cause) | |
| 233 | + iowrite32(cause, idxd->reg_base + IDXD_INTCAUSE_OFFSET); | |
| 234 | + } | |
| 235 | + | |
| 218 | 236 | idxd_unmask_msix_vector(idxd, irq_entry->id); |
| 219 | 237 | return IRQ_HANDLED; |
| 220 | 238 | } |
| 221 | 239 | |
| 222 | −static bool process_fault(struct idxd_desc *desc, u64 fault_addr) | |
| 240 | +static inline bool match_fault(struct idxd_desc *desc, u64 fault_addr) | |
| 223 | 241 | { |
| 224 | 242 | /* |
| 225 | 243 | * Completion address can be bad as well. Check fault address match for descriptor |
| 226 | 244 | * and completion address. |
| 227 | 245 | */ |
| 228 | − if ((u64)desc->hw == fault_addr || | |
| 229 | − (u64)desc->completion == fault_addr) { | |
| 230 | − idxd_dma_complete_txd(desc, IDXD_COMPLETE_DEV_FAIL); | |
| 246 | + if ((u64)desc->hw == fault_addr || (u64)desc->completion == fault_addr) { | |
| 247 | + struct idxd_device *idxd = desc->wq->idxd; | |
| 248 | + struct device *dev = &idxd->pdev->dev; | |
| 249 | + | |
| 250 | + dev_warn(dev, "desc with fault address: %#llx\n", fault_addr); | |
| 231 | 251 | return true; |
| 232 | 252 | } |
| 233 | 253 | |
| 234 | 254 | return false; |
| 235 | 255 | } |
| 236 | 256 | |
| 237 | −static bool complete_desc(struct idxd_desc *desc) | |
| 257 | +static inline void complete_desc(struct idxd_desc *desc, enum idxd_complete_type reason) | |
| 238 | 258 | { |
| 239 | − if (desc->completion->status) { | |
| 240 | − idxd_dma_complete_txd(desc, IDXD_COMPLETE_NORMAL); | |
| 241 | − return true; | |
| 242 | − } | |
| 243 | − | |
| 244 | − return false; | |
| 259 | + idxd_dma_complete_txd(desc, reason); | |
| 260 | + idxd_free_desc(desc->wq, desc); | |
| 245 | 261 | } |
| 246 | 262 | |
| 247 | 263 | static int irq_process_pending_llist(struct idxd_irq_entry *irq_entry, |
| @@ -251,25 +267,25 @@ static int irq_process_pending_llist(struct idxd_irq_entry *irq_entry, · 3 unmodified lines | ||
| 251 | 267 | struct idxd_desc *desc, *t; |
| 252 | 268 | struct llist_node *head; |
| 253 | 269 | int queued = 0; |
| 254 | − bool completed = false; | |
| 255 | 270 | unsigned long flags; |
| 271 | + enum idxd_complete_type reason; | |
| 256 | 272 | |
| 257 | 273 | *processed = 0; |
| 258 | 274 | head = llist_del_all(&irq_entry->pending_llist); |
| 259 | 275 | if (!head) |
| 260 | 276 | goto out; |
| 261 | 277 | |
| 262 | − llist_for_each_entry_safe(desc, t, head, llnode) { | |
| 263 | − if (wtype == IRQ_WORK_NORMAL) | |
| 264 | − completed = complete_desc(desc); | |
| 265 | − else if (wtype == IRQ_WORK_PROCESS_FAULT) | |
| 266 | − completed = process_fault(desc, data); | |
| 278 | + if (wtype == IRQ_WORK_NORMAL) | |
| 279 | + reason = IDXD_COMPLETE_NORMAL; | |
| 280 | + else | |
| 281 | + reason = IDXD_COMPLETE_DEV_FAIL; | |
| 267 | 282 | |
| 268 | − if (completed) { | |
| 269 | − idxd_free_desc(desc->wq, desc); | |
| 283 | + llist_for_each_entry_safe(desc, t, head, llnode) { | |
| 284 | + if (desc->completion->status) { | |
| 285 | + if ((desc->completion->status & DSA_COMP_STATUS_MASK) != DSA_COMP_SUCCESS) | |
| 286 | + match_fault(desc, data); | |
| 287 | + complete_desc(desc, reason); | |
| 270 | 288 | (*processed)++; |
| 271 | − if (wtype == IRQ_WORK_PROCESS_FAULT) | |
| 272 | − break; | |
| 273 | 289 | } else { |
| 274 | 290 | spin_lock_irqsave(&irq_entry->list_lock, flags); |
| 275 | 291 | list_add_tail(&desc->list, |
| @@ -287,42 +303,46 @@ static int irq_process_work_list(struct idxd_irq_entry *irq_entry, · 11 unmodified lines | ||
| 287 | 303 | enum irq_work_type wtype, |
| 288 | 304 | int *processed, u64 data) |
| 289 | 305 | { |
| 290 | − struct list_head *node, *next; | |
| 291 | 306 | int queued = 0; |
| 292 | − bool completed = false; | |
| 293 | 307 | unsigned long flags; |
| 308 | + LIST_HEAD(flist); | |
| 309 | + struct idxd_desc *desc, *n; | |
| 310 | + enum idxd_complete_type reason; | |
| 294 | 311 | |
| 295 | 312 | *processed = 0; |
| 296 | − spin_lock_irqsave(&irq_entry->list_lock, flags); | |
| 297 | − if (list_empty(&irq_entry->work_list)) | |
| 298 | − goto out; | |
| 299 | − | |
| 300 | − list_for_each_safe(node, next, &irq_entry->work_list) { | |
| 301 | − struct idxd_desc *desc = | |
| 302 | − container_of(node, struct idxd_desc, list); | |
| 313 | + if (wtype == IRQ_WORK_NORMAL) | |
| 314 | + reason = IDXD_COMPLETE_NORMAL; | |
| 315 | + else | |
| 316 | + reason = IDXD_COMPLETE_DEV_FAIL; | |
| 303 | 317 | |
| 318 | + /* | |
| 319 | + * This lock protects list corruption from access of list outside of the irq handler | |
| 320 | + * thread. | |
| 321 | + */ | |
| 322 | + spin_lock_irqsave(&irq_entry->list_lock, flags); | |
| 323 | + if (list_empty(&irq_entry->work_list)) { | |
| 304 | 324 | spin_unlock_irqrestore(&irq_entry->list_lock, flags); |
| 305 | − if (wtype == IRQ_WORK_NORMAL) | |
| 306 | − completed = complete_desc(desc); | |
| 307 | − else if (wtype == IRQ_WORK_PROCESS_FAULT) | |
| 308 | − completed = process_fault(desc, data); | |
| 325 | + return 0; | |
| 326 | + } | |
| 309 | 327 | |
| 310 | − if (completed) { | |
| 311 | − spin_lock_irqsave(&irq_entry->list_lock, flags); | |
| 328 | + list_for_each_entry_safe(desc, n, &irq_entry->work_list, list) { | |
| 329 | + if (desc->completion->status) { | |
| 312 | 330 | list_del(&desc->list); |
| 313 | − spin_unlock_irqrestore(&irq_entry->list_lock, flags); | |
| 314 | − idxd_free_desc(desc->wq, desc); | |
| 315 | 331 | (*processed)++; |
| 316 | − if (wtype == IRQ_WORK_PROCESS_FAULT) | |
| 317 | − return queued; | |
| 332 | + list_add_tail(&desc->list, &flist); | |
| 318 | 333 | } else { |
| 319 | 334 | queued++; |
| 320 | 335 | } |
| 321 | − spin_lock_irqsave(&irq_entry->list_lock, flags); | |
| 322 | 336 | } |
| 323 | 337 | |
| 324 | − out: | |
| 325 | 338 | spin_unlock_irqrestore(&irq_entry->list_lock, flags); |
| 339 | + | |
| 340 | + list_for_each_entry(desc, &flist, list) { | |
| 341 | + if ((desc->completion->status & DSA_COMP_STATUS_MASK) != DSA_COMP_SUCCESS) | |
| 342 | + match_fault(desc, data); | |
| 343 | + complete_desc(desc, reason); | |
| 344 | + } | |
| 345 | + | |
| 326 | 346 | return queued; |
| 327 | 347 | } |
| 328 | 348 | |
| @@ -434,7 +434,7 @@ int idxd_register_driver(void) · 433 unmodified lines | ||
| 434 | 434 | return 0; |
| 435 | 435 | |
| 436 | 436 | drv_fail: |
| 437 | − for (; i > 0; i--) | |
| 437 | + while (--i >= 0) | |
| 438 | 438 | driver_unregister(&idxd_drvs[i]->drv); |
| 439 | 439 | return rc; |
| 440 | 440 | } |
| @@ -1840,7 +1840,7 @@ int idxd_register_bus_type(void) · 1399 unmodified lines | ||
| 1840 | 1840 | return 0; |
| 1841 | 1841 | |
| 1842 | 1842 | bus_err: |
| 1843 | − for (; i > 0; i--) | |
| 1843 | + while (--i >= 0) | |
| 1844 | 1844 | bus_unregister(idxd_bus_types[i]); |
| 1845 | 1845 | return rc; |
| 1846 | 1846 | } |
| @@ -1007,6 +1007,7 @@ static int mtk_hsdma_probe(struct platform_device *pdev) · 1006 unmodified lines | ||
| 1007 | 1007 | return 0; |
| 1008 | 1008 | |
| 1009 | 1009 | err_free: |
| 1010 | + mtk_hsdma_hw_deinit(hsdma); | |
| 1010 | 1011 | of_dma_controller_free(pdev->dev.of_node); |
| 1011 | 1012 | err_unregister: |
| 1012 | 1013 | dma_async_device_unregister(dd); |
| @@ -350,7 +350,7 @@ static int milbeaut_xdmac_probe(struct platform_device *pdev) · 349 unmodified lines | ||
| 350 | 350 | |
| 351 | 351 | ret = dma_async_device_register(ddev); |
| 352 | 352 | if (ret) |
| 353 | − return ret; | |
| 353 | + goto disable_xdmac; | |
| 354 | 354 | |
| 355 | 355 | ret = of_dma_controller_register(dev->of_node, |
| 356 | 356 | of_dma_simple_xlate, mdev); |
| @@ -363,6 +363,8 @@ static int milbeaut_xdmac_probe(struct platform_device *pdev) · 6 unmodified lines | ||
| 363 | 363 | |
| 364 | 364 | unregister_dmac: |
| 365 | 365 | dma_async_device_unregister(ddev); |
| 366 | +disable_xdmac: | |
| 367 | + disable_xdmac(mdev); | |
| 366 | 368 | return ret; |
| 367 | 369 | } |
| 368 | 370 | |
| @@ -630,7 +630,7 @@ static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan, · 629 unmodified lines | ||
| 630 | 630 | GFP_NOWAIT); |
| 631 | 631 | |
| 632 | 632 | if (!async_desc) |
| 633 | − goto err_out; | |
| 633 | + return NULL; | |
| 634 | 634 | |
| 635 | 635 | if (flags & DMA_PREP_FENCE) |
| 636 | 636 | async_desc->flags |= DESC_FLAG_NWD; |
| @@ -670,10 +670,6 @@ static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan, · 33 unmodified lines | ||
| 670 | 670 | } |
| 671 | 671 | |
| 672 | 672 | return vchan_tx_prep(&bchan->vc, &async_desc->vd, flags); |
| 673 | − | |
| 674 | −err_out: | |
| 675 | − kfree(async_desc); | |
| 676 | − return NULL; | |
| 677 | 673 | } |
| 678 | 674 | |
| 679 | 675 | /** |
| @@ -1416,7 +1416,7 @@ static int gpi_alloc_ring(struct gpi_ring *ring, u32 elements, · 1415 unmodified lines | ||
| 1416 | 1416 | len = 1 << bit; |
| 1417 | 1417 | ring->alloc_size = (len + (len - 1)); |
| 1418 | 1418 | dev_dbg(gpii->gpi_dev->dev, |
| 1419 | − "#el:%u el_size:%u len:%u actual_len:%llu alloc_size:%lu\n", | |
| 1419 | + "#el:%u el_size:%u len:%u actual_len:%llu alloc_size:%zu\n", | |
| 1420 | 1420 | elements, el_size, (elements * el_size), len, |
| 1421 | 1421 | ring->alloc_size); |
| 1422 | 1422 | |
| @@ -1424,7 +1424,7 @@ static int gpi_alloc_ring(struct gpi_ring *ring, u32 elements, · 1 unmodified line | ||
| 1424 | 1424 | ring->alloc_size, |
| 1425 | 1425 | &ring->dma_handle, GFP_KERNEL); |
| 1426 | 1426 | if (!ring->pre_aligned) { |
| 1427 | − dev_err(gpii->gpi_dev->dev, "could not alloc size:%lu mem for ring\n", | |
| 1427 | + dev_err(gpii->gpi_dev->dev, "could not alloc size:%zu mem for ring\n", | |
| 1428 | 1428 | ring->alloc_size); |
| 1429 | 1429 | return -ENOMEM; |
| 1430 | 1430 | } |
| @@ -1444,8 +1444,8 @@ static int gpi_alloc_ring(struct gpi_ring *ring, u32 elements, · 13 unmodified lines | ||
| 1444 | 1444 | smp_wmb(); |
| 1445 | 1445 | |
| 1446 | 1446 | dev_dbg(gpii->gpi_dev->dev, |
| 1447 | − "phy_pre:0x%0llx phy_alig:0x%0llx len:%u el_size:%u elements:%u\n", | |
| 1448 | − ring->dma_handle, ring->phys_addr, ring->len, | |
| 1447 | + "phy_pre:%pad phy_alig:%pa len:%u el_size:%u elements:%u\n", | |
| 1448 | + &ring->dma_handle, &ring->phys_addr, ring->len, | |
| 1449 | 1449 | ring->el_size, ring->elements); |
| 1450 | 1450 | |
| 1451 | 1451 | return 0; |
| @@ -1948,7 +1948,7 @@ static int gpi_ch_init(struct gchan *gchan) · 496 unmodified lines | ||
| 1948 | 1948 | return ret; |
| 1949 | 1949 | |
| 1950 | 1950 | error_start_chan: |
| 1951 | − for (i = i - 1; i >= 0; i++) { | |
| 1951 | + for (i = i - 1; i >= 0; i--) { | |
| 1952 | 1952 | gpi_stop_chan(&gpii->gchan[i]); |
| 1953 | 1953 | gpi_send_cmd(gpii, gchan, GPI_CH_CMD_RESET); |
| 1954 | 1954 | } |
| @@ -199,7 +199,7 @@ · 198 unmodified lines | ||
| 199 | 199 | #define STM32_MDMA_MAX_CHANNELS 63 |
| 200 | 200 | #define STM32_MDMA_MAX_REQUESTS 256 |
| 201 | 201 | #define STM32_MDMA_MAX_BURST 128 |
| 202 | −#define STM32_MDMA_VERY_HIGH_PRIORITY 0x11 | |
| 202 | +#define STM32_MDMA_VERY_HIGH_PRIORITY 0x3 | |
| 203 | 203 | |
| 204 | 204 | enum stm32_mdma_trigger_mode { |
| 205 | 205 | STM32_MDMA_BUFFER, |
| @@ -2401,7 +2401,8 @@ static int bcdma_alloc_chan_resources(struct dma_chan *chan) · 2400 unmodified lines | ||
| 2401 | 2401 | dev_err(ud->ddev.dev, |
| 2402 | 2402 | "Descriptor pool allocation failed\n"); |
| 2403 | 2403 | uc->use_dma_pool = false; |
| 2404 | − return -ENOMEM; | |
| 2404 | + ret = -ENOMEM; | |
| 2405 | + goto err_res_free; | |
| 2405 | 2406 | } |
| 2406 | 2407 | |
| 2407 | 2408 | uc->use_dma_pool = true; |
| @@ -4698,9 +4699,9 @@ static int pktdma_setup_resources(struct udma_dev *ud) · 2290 unmodified lines | ||
| 4698 | 4699 | ud->tchan_tpl.levels = 1; |
| 4699 | 4700 | } |
| 4700 | 4701 | |
| 4701 | − ud->tchan_tpl.levels = ud->tchan_tpl.levels; | |
| 4702 | − ud->tchan_tpl.start_idx[0] = ud->tchan_tpl.start_idx[0]; | |
| 4703 | − ud->tchan_tpl.start_idx[1] = ud->tchan_tpl.start_idx[1]; | |
| 4702 | + ud->rchan_tpl.levels = ud->tchan_tpl.levels; | |
| 4703 | + ud->rchan_tpl.start_idx[0] = ud->tchan_tpl.start_idx[0]; | |
| 4704 | + ud->rchan_tpl.start_idx[1] = ud->tchan_tpl.start_idx[1]; | |
| 4704 | 4705 | |
| 4705 | 4706 | ud->tchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tchan_cnt), |
| 4706 | 4707 | sizeof(unsigned long), GFP_KERNEL); |
| @@ -2781,7 +2781,7 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, · 2780 unmodified lines | ||
| 2781 | 2781 | has_dre = false; |
| 2782 | 2782 | |
| 2783 | 2783 | if (!has_dre) |
| 2784 | − xdev->common.copy_align = fls(width - 1); | |
| 2784 | + xdev->common.copy_align = (enum dmaengine_alignment)fls(width - 1); | |
| 2785 | 2785 | |
| 2786 | 2786 | if (of_device_is_compatible(node, "xlnx,axi-vdma-mm2s-channel") || |
| 2787 | 2787 | of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel") || |
| @@ -2900,7 +2900,8 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, · 112 unmodified lines | ||
| 2900 | 2900 | static int xilinx_dma_child_probe(struct xilinx_dma_device *xdev, |
| 2901 | 2901 | struct device_node *node) |
| 2902 | 2902 | { |
| 2903 | − int ret, i, nr_channels = 1; | |
| 2903 | + int ret, i; | |
| 2904 | + u32 nr_channels = 1; | |
| 2904 | 2905 | |
| 2905 | 2906 | ret = of_property_read_u32(node, "dma-channels", &nr_channels); |
| 2906 | 2907 | if (xdev->dma_config->dmatype == XDMA_TYPE_AXIMCDMA && ret < 0) |
| @@ -3112,7 +3113,11 @@ static int xilinx_dma_probe(struct platform_device *pdev) · 205 unmodified lines | ||
| 3112 | 3113 | } |
| 3113 | 3114 | |
| 3114 | 3115 | /* Register the DMA engine with the core */ |
| 3115 | − dma_async_device_register(&xdev->common); | |
| 3116 | + err = dma_async_device_register(&xdev->common); | |
| 3117 | + if (err) { | |
| 3118 | + dev_err(xdev->dev, "failed to register the dma device\n"); | |
| 3119 | + goto error; | |
| 3120 | + } | |
| 3116 | 3121 | |
| 3117 | 3122 | err = of_dma_controller_register(node, of_dma_xilinx_xlate, |
| 3118 | 3123 | xdev); |
| @@ -3,8 +3,9 @@ · 2 unmodified lines | ||
| 3 | 3 | * apple-properties.c - EFI device properties on Macs |
| 4 | 4 | * Copyright (C) 2016 Lukas Wunner <lukas@wunner.de> |
| 5 | 5 | * |
| 6 | − * Note, all properties are considered as u8 arrays. | |
| 7 | − * To get a value of any of them the caller must use device_property_read_u8_array(). | |
| 6 | + * Properties are stored either as: | |
| 7 | + * u8 arrays which can be retrieved with device_property_read_u8_array() or | |
| 8 | + * booleans which can be queried with device_property_present(). | |
| 8 | 9 | */ |
| 9 | 10 | |
| 10 | 11 | #define pr_fmt(fmt) "apple-properties: " fmt |
| @@ -88,8 +89,12 @@ static void __init unmarshal_key_value_pairs(struct dev_header *dev_header, · 77 unmodified lines | ||
| 88 | 89 | |
| 89 | 90 | entry_data = ptr + key_len + sizeof(val_len); |
| 90 | 91 | entry_len = val_len - sizeof(val_len); |
| 91 | − entry[i] = PROPERTY_ENTRY_U8_ARRAY_LEN(key, entry_data, | |
| 92 | − entry_len); | |
| 92 | + if (entry_len) | |
| 93 | + entry[i] = PROPERTY_ENTRY_U8_ARRAY_LEN(key, entry_data, | |
| 94 | + entry_len); | |
| 95 | + else | |
| 96 | + entry[i] = PROPERTY_ENTRY_BOOL(key); | |
| 97 | + | |
| 93 | 98 | if (dump_properties) { |
| 94 | 99 | dev_info(dev, "property: %s\n", key); |
| 95 | 100 | print_hex_dump(KERN_INFO, pr_fmt(), DUMP_PREFIX_OFFSET, |
| @@ -13,6 +13,7 @@ config IMX_DSP · 12 unmodified lines | ||
| 13 | 13 | config IMX_SCU |
| 14 | 14 | bool "IMX SCU Protocol driver" |
| 15 | 15 | depends on IMX_MBOX |
| 16 | + select SOC_BUS | |
| 16 | 17 | help |
| 17 | 18 | The System Controller Firmware (SCFW) is a low-level system function |
| 18 | 19 | which runs on a dedicated Cortex-M core to provide power, clock, and |
| @@ -441,8 +441,9 @@ config GPIO_MXC · 440 unmodified lines | ||
| 441 | 441 | select GENERIC_IRQ_CHIP |
| 442 | 442 | |
| 443 | 443 | config GPIO_MXS |
| 444 | − def_bool y | |
| 444 | + bool "Freescale MXS GPIO support" if COMPILE_TEST | |
| 445 | 445 | depends on ARCH_MXS || COMPILE_TEST |
| 446 | + default y if ARCH_MXS | |
| 446 | 447 | select GPIO_GENERIC |
| 447 | 448 | select GENERIC_IRQ_CHIP |
| 448 | 449 | |
| @@ -521,7 +522,8 @@ config GPIO_SAMA5D2_PIOBU · 72 unmodified lines | ||
| 521 | 522 | |
| 522 | 523 | config GPIO_SIFIVE |
| 523 | 524 | bool "SiFive GPIO support" |
| 524 | − depends on OF_GPIO && IRQ_DOMAIN_HIERARCHY | |
| 525 | + depends on OF_GPIO | |
| 526 | + select IRQ_DOMAIN_HIERARCHY | |
| 525 | 527 | select GPIO_GENERIC |
| 526 | 528 | select GPIOLIB_IRQCHIP |
| 527 | 529 | select REGMAP_MMIO |
| @@ -597,6 +599,8 @@ config GPIO_TEGRA · 69 unmodified lines | ||
| 597 | 599 | default ARCH_TEGRA |
| 598 | 600 | depends on ARCH_TEGRA || COMPILE_TEST |
| 599 | 601 | depends on OF_GPIO |
| 602 | + select GPIOLIB_IRQCHIP | |
| 603 | + select IRQ_DOMAIN_HIERARCHY | |
| 600 | 604 | help |
| 601 | 605 | Say yes here to support GPIO pins on NVIDIA Tegra SoCs. |
| 602 | 606 | |
| @@ -25,6 +25,9 @@ · 24 unmodified lines | ||
| 25 | 25 | /* Maximum value for gpio line identifiers */ |
| 26 | 26 | #define EP93XX_GPIO_LINE_MAX 63 |
| 27 | 27 | |
| 28 | +/* Number of GPIO chips in EP93XX */ | |
| 29 | +#define EP93XX_GPIO_CHIP_NUM 8 | |
| 30 | + | |
| 28 | 31 | /* Maximum value for irq capable line identifiers */ |
| 29 | 32 | #define EP93XX_GPIO_LINE_MAX_IRQ 23 |
| 30 | 33 | |
| @@ -34,74 +37,75 @@ · 3 unmodified lines | ||
| 34 | 37 | */ |
| 35 | 38 | #define EP93XX_GPIO_F_IRQ_BASE 80 |
| 36 | 39 | |
| 37 | −struct ep93xx_gpio { | |
| 38 | − void __iomem *base; | |
| 39 | − struct gpio_chip gc[8]; | |
| 40 | +struct ep93xx_gpio_irq_chip { | |
| 41 | + struct irq_chip ic; | |
| 42 | + u8 irq_offset; | |
| 43 | + u8 int_unmasked; | |
| 44 | + u8 int_enabled; | |
| 45 | + u8 int_type1; | |
| 46 | + u8 int_type2; | |
| 47 | + u8 int_debounce; | |
| 40 | 48 | }; |
| 41 | 49 | |
| 42 | −/************************************************************************* | |
| 43 | − * Interrupt handling for EP93xx on-chip GPIOs | |
| 44 | − *************************************************************************/ | |
| 45 | −static unsigned char gpio_int_unmasked[3]; | |
| 46 | −static unsigned char gpio_int_enabled[3]; | |
| 47 | −static unsigned char gpio_int_type1[3]; | |
| 48 | −static unsigned char gpio_int_type2[3]; | |
| 49 | −static unsigned char gpio_int_debounce[3]; | |
| 50 | − | |
| 51 | −/* Port ordering is: A B F */ | |
| 52 | −static const u8 int_type1_register_offset[3] = { 0x90, 0xac, 0x4c }; | |
| 53 | −static const u8 int_type2_register_offset[3] = { 0x94, 0xb0, 0x50 }; | |
| 54 | −static const u8 eoi_register_offset[3] = { 0x98, 0xb4, 0x54 }; | |
| 55 | −static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x58 }; | |
| 56 | −static const u8 int_debounce_register_offset[3] = { 0xa8, 0xc4, 0x64 }; | |
| 57 | − | |
| 58 | −static void ep93xx_gpio_update_int_params(struct ep93xx_gpio *epg, unsigned port) | |
| 59 | −{ | |
| 60 | − BUG_ON(port > 2); | |
| 50 | +struct ep93xx_gpio_chip { | |
| 51 | + struct gpio_chip gc; | |
| 52 | + struct ep93xx_gpio_irq_chip *eic; | |
| 53 | +}; | |
| 61 | 54 | |
| 62 | − writeb_relaxed(0, epg->base + int_en_register_offset[port]); | |
| 55 | +struct ep93xx_gpio { | |
| 56 | + void __iomem *base; | |
| 57 | + struct ep93xx_gpio_chip gc[EP93XX_GPIO_CHIP_NUM]; | |
| 58 | +}; | |
| 63 | 59 | |
| 64 | − writeb_relaxed(gpio_int_type2[port], | |
| 65 | − epg->base + int_type2_register_offset[port]); | |
| 60 | +#define to_ep93xx_gpio_chip(x) container_of(x, struct ep93xx_gpio_chip, gc) | |
| 66 | 61 | |
| 67 | − writeb_relaxed(gpio_int_type1[port], | |
| 68 | − epg->base + int_type1_register_offset[port]); | |
| 62 | +static struct ep93xx_gpio_irq_chip *to_ep93xx_gpio_irq_chip(struct gpio_chip *gc) | |
| 63 | +{ | |
| 64 | + struct ep93xx_gpio_chip *egc = to_ep93xx_gpio_chip(gc); | |
| 69 | 65 | |
| 70 | − writeb(gpio_int_unmasked[port] & gpio_int_enabled[port], | |
| 71 | − epg->base + int_en_register_offset[port]); | |
| 66 | + return egc->eic; | |
| 72 | 67 | } |
| 73 | 68 | |
| 74 | −static int ep93xx_gpio_port(struct gpio_chip *gc) | |
| 69 | +/************************************************************************* | |
| 70 | + * Interrupt handling for EP93xx on-chip GPIOs | |
| 71 | + *************************************************************************/ | |
| 72 | +#define EP93XX_INT_TYPE1_OFFSET 0x00 | |
| 73 | +#define EP93XX_INT_TYPE2_OFFSET 0x04 | |
| 74 | +#define EP93XX_INT_EOI_OFFSET 0x08 | |
| 75 | +#define EP93XX_INT_EN_OFFSET 0x0c | |
| 76 | +#define EP93XX_INT_STATUS_OFFSET 0x10 | |
| 77 | +#define EP93XX_INT_RAW_STATUS_OFFSET 0x14 | |
| 78 | +#define EP93XX_INT_DEBOUNCE_OFFSET 0x18 | |
| 79 | + | |
| 80 | +static void ep93xx_gpio_update_int_params(struct ep93xx_gpio *epg, | |
| 81 | + struct ep93xx_gpio_irq_chip *eic) | |
| 75 | 82 | { |
| 76 | − struct ep93xx_gpio *epg = gpiochip_get_data(gc); | |
| 77 | − int port = 0; | |
| 83 | + writeb_relaxed(0, epg->base + eic->irq_offset + EP93XX_INT_EN_OFFSET); | |
| 78 | 84 | |
| 79 | − while (port < ARRAY_SIZE(epg->gc) && gc != &epg->gc[port]) | |
| 80 | − port++; | |
| 85 | + writeb_relaxed(eic->int_type2, | |
| 86 | + epg->base + eic->irq_offset + EP93XX_INT_TYPE2_OFFSET); | |
| 81 | 87 | |
| 82 | − /* This should not happen but is there as a last safeguard */ | |
| 83 | − if (port == ARRAY_SIZE(epg->gc)) { | |
| 84 | − pr_crit("can't find the GPIO port\n"); | |
| 85 | − return 0; | |
| 86 | − } | |
| 88 | + writeb_relaxed(eic->int_type1, | |
| 89 | + epg->base + eic->irq_offset + EP93XX_INT_TYPE1_OFFSET); | |
| 87 | 90 | |
| 88 | − return port; | |
| 91 | + writeb_relaxed(eic->int_unmasked & eic->int_enabled, | |
| 92 | + epg->base + eic->irq_offset + EP93XX_INT_EN_OFFSET); | |
| 89 | 93 | } |
| 90 | 94 | |
| 91 | 95 | static void ep93xx_gpio_int_debounce(struct gpio_chip *gc, |
| 92 | 96 | unsigned int offset, bool enable) |
| 93 | 97 | { |
| 94 | 98 | struct ep93xx_gpio *epg = gpiochip_get_data(gc); |
| 95 | − int port = ep93xx_gpio_port(gc); | |
| 99 | + struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc); | |
| 96 | 100 | int port_mask = BIT(offset); |
| 97 | 101 | |
| 98 | 102 | if (enable) |
| 99 | − gpio_int_debounce[port] |= port_mask; | |
| 103 | + eic->int_debounce |= port_mask; | |
| 100 | 104 | else |
| 101 | − gpio_int_debounce[port] &= ~port_mask; | |
| 105 | + eic->int_debounce &= ~port_mask; | |
| 102 | 106 | |
| 103 | − writeb(gpio_int_debounce[port], | |
| 104 | − epg->base + int_debounce_register_offset[port]); | |
| 107 | + writeb(eic->int_debounce, | |
| 108 | + epg->base + eic->irq_offset + EP93XX_INT_DEBOUNCE_OFFSET); | |
| 105 | 109 | } |
| 106 | 110 | |
| 107 | 111 | static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc) |
| @@ -122,12 +126,12 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc) · 14 unmodified lines | ||
| 122 | 126 | */ |
| 123 | 127 | stat = readb(epg->base + EP93XX_GPIO_A_INT_STATUS); |
| 124 | 128 | for_each_set_bit(offset, &stat, 8) |
| 125 | − generic_handle_irq(irq_find_mapping(epg->gc[0].irq.domain, | |
| 129 | + generic_handle_irq(irq_find_mapping(epg->gc[0].gc.irq.domain, | |
| 126 | 130 | offset)); |
| 127 | 131 | |
| 128 | 132 | stat = readb(epg->base + EP93XX_GPIO_B_INT_STATUS); |
| 129 | 133 | for_each_set_bit(offset, &stat, 8) |
| 130 | − generic_handle_irq(irq_find_mapping(epg->gc[1].irq.domain, | |
| 134 | + generic_handle_irq(irq_find_mapping(epg->gc[1].gc.irq.domain, | |
| 131 | 135 | offset)); |
| 132 | 136 | |
| 133 | 137 | chained_irq_exit(irqchip, desc); |
| @@ -153,52 +157,52 @@ static void ep93xx_gpio_f_irq_handler(struct irq_desc *desc) · 19 unmodified lines | ||
| 153 | 157 | static void ep93xx_gpio_irq_ack(struct irq_data *d) |
| 154 | 158 | { |
| 155 | 159 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 160 | + struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc); | |
| 156 | 161 | struct ep93xx_gpio *epg = gpiochip_get_data(gc); |
| 157 | − int port = ep93xx_gpio_port(gc); | |
| 158 | 162 | int port_mask = BIT(d->irq & 7); |
| 159 | 163 | |
| 160 | 164 | if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) { |
| 161 | − gpio_int_type2[port] ^= port_mask; /* switch edge direction */ | |
| 162 | − ep93xx_gpio_update_int_params(epg, port); | |
| 165 | + eic->int_type2 ^= port_mask; /* switch edge direction */ | |
| 166 | + ep93xx_gpio_update_int_params(epg, eic); | |
| 163 | 167 | } |
| 164 | 168 | |
| 165 | − writeb(port_mask, epg->base + eoi_register_offset[port]); | |
| 169 | + writeb(port_mask, epg->base + eic->irq_offset + EP93XX_INT_EOI_OFFSET); | |
| 166 | 170 | } |
| 167 | 171 | |
| 168 | 172 | static void ep93xx_gpio_irq_mask_ack(struct irq_data *d) |
| 169 | 173 | { |
| 170 | 174 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 175 | + struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc); | |
| 171 | 176 | struct ep93xx_gpio *epg = gpiochip_get_data(gc); |
| 172 | − int port = ep93xx_gpio_port(gc); | |
| 173 | 177 | int port_mask = BIT(d->irq & 7); |
| 174 | 178 | |
| 175 | 179 | if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) |
| 176 | − gpio_int_type2[port] ^= port_mask; /* switch edge direction */ | |
| 180 | + eic->int_type2 ^= port_mask; /* switch edge direction */ | |
| 177 | 181 | |
| 178 | − gpio_int_unmasked[port] &= ~port_mask; | |
| 179 | − ep93xx_gpio_update_int_params(epg, port); | |
| 182 | + eic->int_unmasked &= ~port_mask; | |
| 183 | + ep93xx_gpio_update_int_params(epg, eic); | |
| 180 | 184 | |
| 181 | − writeb(port_mask, epg->base + eoi_register_offset[port]); | |
| 185 | + writeb(port_mask, epg->base + eic->irq_offset + EP93XX_INT_EOI_OFFSET); | |
| 182 | 186 | } |
| 183 | 187 | |
| 184 | 188 | static void ep93xx_gpio_irq_mask(struct irq_data *d) |
| 185 | 189 | { |
| 186 | 190 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 191 | + struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc); | |
| 187 | 192 | struct ep93xx_gpio *epg = gpiochip_get_data(gc); |
| 188 | − int port = ep93xx_gpio_port(gc); | |
| 189 | 193 | |
| 190 | − gpio_int_unmasked[port] &= ~BIT(d->irq & 7); | |
| 191 | − ep93xx_gpio_update_int_params(epg, port); | |
| 194 | + eic->int_unmasked &= ~BIT(d->irq & 7); | |
| 195 | + ep93xx_gpio_update_int_params(epg, eic); | |
| 192 | 196 | } |
| 193 | 197 | |
| 194 | 198 | static void ep93xx_gpio_irq_unmask(struct irq_data *d) |
| 195 | 199 | { |
| 196 | 200 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 201 | + struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc); | |
| 197 | 202 | struct ep93xx_gpio *epg = gpiochip_get_data(gc); |
| 198 | − int port = ep93xx_gpio_port(gc); | |
| 199 | 203 | |
| 200 | − gpio_int_unmasked[port] |= BIT(d->irq & 7); | |
| 201 | − ep93xx_gpio_update_int_params(epg, port); | |
| 204 | + eic->int_unmasked |= BIT(d->irq & 7); | |
| 205 | + ep93xx_gpio_update_int_params(epg, eic); | |
| 202 | 206 | } |
| 203 | 207 | |
| 204 | 208 | /* |
| @@ -209,8 +213,8 @@ static void ep93xx_gpio_irq_unmask(struct irq_data *d) · 4 unmodified lines | ||
| 209 | 213 | static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type) |
| 210 | 214 | { |
| 211 | 215 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 216 | + struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc); | |
| 212 | 217 | struct ep93xx_gpio *epg = gpiochip_get_data(gc); |
| 213 | − int port = ep93xx_gpio_port(gc); | |
| 214 | 218 | int offset = d->irq & 7; |
| 215 | 219 | int port_mask = BIT(offset); |
| 216 | 220 | irq_flow_handler_t handler; |
| @@ -219,32 +223,32 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type) · 2 unmodified lines | ||
| 219 | 223 | |
| 220 | 224 | switch (type) { |
| 221 | 225 | case IRQ_TYPE_EDGE_RISING: |
| 222 | − gpio_int_type1[port] |= port_mask; | |
| 223 | − gpio_int_type2[port] |= port_mask; | |
| 226 | + eic->int_type1 |= port_mask; | |
| 227 | + eic->int_type2 |= port_mask; | |
| 224 | 228 | handler = handle_edge_irq; |
| 225 | 229 | break; |
| 226 | 230 | case IRQ_TYPE_EDGE_FALLING: |
| 227 | − gpio_int_type1[port] |= port_mask; | |
| 228 | − gpio_int_type2[port] &= ~port_mask; | |
| 231 | + eic->int_type1 |= port_mask; | |
| 232 | + eic->int_type2 &= ~port_mask; | |
| 229 | 233 | handler = handle_edge_irq; |
| 230 | 234 | break; |
| 231 | 235 | case IRQ_TYPE_LEVEL_HIGH: |
| 232 | − gpio_int_type1[port] &= ~port_mask; | |
| 233 | − gpio_int_type2[port] |= port_mask; | |
| 236 | + eic->int_type1 &= ~port_mask; | |
| 237 | + eic->int_type2 |= port_mask; | |
| 234 | 238 | handler = handle_level_irq; |
| 235 | 239 | break; |
| 236 | 240 | case IRQ_TYPE_LEVEL_LOW: |
| 237 | − gpio_int_type1[port] &= ~port_mask; | |
| 238 | − gpio_int_type2[port] &= ~port_mask; | |
| 241 | + eic->int_type1 &= ~port_mask; | |
| 242 | + eic->int_type2 &= ~port_mask; | |
| 239 | 243 | handler = handle_level_irq; |
| 240 | 244 | break; |
| 241 | 245 | case IRQ_TYPE_EDGE_BOTH: |
| 242 | − gpio_int_type1[port] |= port_mask; | |
| 246 | + eic->int_type1 |= port_mask; | |
| 243 | 247 | /* set initial polarity based on current input level */ |
| 244 | 248 | if (gc->get(gc, offset)) |
| 245 | − gpio_int_type2[port] &= ~port_mask; /* falling */ | |
| 249 | + eic->int_type2 &= ~port_mask; /* falling */ | |
| 246 | 250 | else |
| 247 | − gpio_int_type2[port] |= port_mask; /* rising */ | |
| 251 | + eic->int_type2 |= port_mask; /* rising */ | |
| 248 | 252 | handler = handle_edge_irq; |
| 249 | 253 | break; |
| 250 | 254 | default: |
| @@ -253,22 +257,13 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type) · 2 unmodified lines | ||
| 253 | 257 | |
| 254 | 258 | irq_set_handler_locked(d, handler); |
| 255 | 259 | |
| 256 | − gpio_int_enabled[port] |= port_mask; | |
| 260 | + eic->int_enabled |= port_mask; | |
| 257 | 261 | |
| 258 | − ep93xx_gpio_update_int_params(epg, port); | |
| 262 | + ep93xx_gpio_update_int_params(epg, eic); | |
| 259 | 263 | |
| 260 | 264 | return 0; |
| 261 | 265 | } |
| 262 | 266 | |
| 263 | −static struct irq_chip ep93xx_gpio_irq_chip = { | |
| 264 | − .name = "GPIO", | |
| 265 | − .irq_ack = ep93xx_gpio_irq_ack, | |
| 266 | − .irq_mask_ack = ep93xx_gpio_irq_mask_ack, | |
| 267 | − .irq_mask = ep93xx_gpio_irq_mask, | |
| 268 | − .irq_unmask = ep93xx_gpio_irq_unmask, | |
| 269 | − .irq_set_type = ep93xx_gpio_irq_type, | |
| 270 | −}; | |
| 271 | − | |
| 272 | 267 | /************************************************************************* |
| 273 | 268 | * gpiolib interface for EP93xx on-chip GPIOs |
| 274 | 269 | *************************************************************************/ |
| @@ -276,17 +271,19 @@ struct ep93xx_gpio_bank { · 1 unmodified line | ||
| 276 | 271 | const char *label; |
| 277 | 272 | int data; |
| 278 | 273 | int dir; |
| 274 | + int irq; | |
| 279 | 275 | int base; |
| 280 | 276 | bool has_irq; |
| 281 | 277 | bool has_hierarchical_irq; |
| 282 | 278 | unsigned int irq_base; |
| 283 | 279 | }; |
| 284 | 280 | |
| 285 | −#define EP93XX_GPIO_BANK(_label, _data, _dir, _base, _has_irq, _has_hier, _irq_base) \ | |
| 281 | +#define EP93XX_GPIO_BANK(_label, _data, _dir, _irq, _base, _has_irq, _has_hier, _irq_base) \ | |
| 286 | 282 | { \ |
| 287 | 283 | .label = _label, \ |
| 288 | 284 | .data = _data, \ |
| 289 | 285 | .dir = _dir, \ |
| 286 | + .irq = _irq, \ | |
| 290 | 287 | .base = _base, \ |
| 291 | 288 | .has_irq = _has_irq, \ |
| 292 | 289 | .has_hierarchical_irq = _has_hier, \ |
| @@ -295,16 +292,16 @@ struct ep93xx_gpio_bank { · 2 unmodified lines | ||
| 295 | 292 | |
| 296 | 293 | static struct ep93xx_gpio_bank ep93xx_gpio_banks[] = { |
| 297 | 294 | /* Bank A has 8 IRQs */ |
| 298 | − EP93XX_GPIO_BANK("A", 0x00, 0x10, 0, true, false, 64), | |
| 295 | + EP93XX_GPIO_BANK("A", 0x00, 0x10, 0x90, 0, true, false, 64), | |
| 299 | 296 | /* Bank B has 8 IRQs */ |
| 300 | − EP93XX_GPIO_BANK("B", 0x04, 0x14, 8, true, false, 72), | |
| 301 | − EP93XX_GPIO_BANK("C", 0x08, 0x18, 40, false, false, 0), | |
| 302 | − EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24, false, false, 0), | |
| 303 | − EP93XX_GPIO_BANK("E", 0x20, 0x24, 32, false, false, 0), | |
| 297 | + EP93XX_GPIO_BANK("B", 0x04, 0x14, 0xac, 8, true, false, 72), | |
| 298 | + EP93XX_GPIO_BANK("C", 0x08, 0x18, 0x00, 40, false, false, 0), | |
| 299 | + EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 0x00, 24, false, false, 0), | |
| 300 | + EP93XX_GPIO_BANK("E", 0x20, 0x24, 0x00, 32, false, false, 0), | |
| 304 | 301 | /* Bank F has 8 IRQs */ |
| 305 | − EP93XX_GPIO_BANK("F", 0x30, 0x34, 16, false, true, 0), | |
| 306 | − EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48, false, false, 0), | |
| 307 | − EP93XX_GPIO_BANK("H", 0x40, 0x44, 56, false, false, 0), | |
| 302 | + EP93XX_GPIO_BANK("F", 0x30, 0x34, 0x4c, 16, false, true, 0), | |
| 303 | + EP93XX_GPIO_BANK("G", 0x38, 0x3c, 0x00, 48, false, false, 0), | |
| 304 | + EP93XX_GPIO_BANK("H", 0x40, 0x44, 0x00, 56, false, false, 0), | |
| 308 | 305 | }; |
| 309 | 306 | |
| 310 | 307 | static int ep93xx_gpio_set_config(struct gpio_chip *gc, unsigned offset, |
| @@ -326,13 +323,23 @@ static int ep93xx_gpio_f_to_irq(struct gpio_chip *gc, unsigned offset) · 15 unmodified lines | ||
| 326 | 323 | return EP93XX_GPIO_F_IRQ_BASE + offset; |
| 327 | 324 | } |
| 328 | 325 | |
| 329 | −static int ep93xx_gpio_add_bank(struct gpio_chip *gc, | |
| 326 | +static void ep93xx_init_irq_chip(struct device *dev, struct irq_chip *ic) | |
| 327 | +{ | |
| 328 | + ic->irq_ack = ep93xx_gpio_irq_ack; | |
| 329 | + ic->irq_mask_ack = ep93xx_gpio_irq_mask_ack; | |
| 330 | + ic->irq_mask = ep93xx_gpio_irq_mask; | |
| 331 | + ic->irq_unmask = ep93xx_gpio_irq_unmask; | |
| 332 | + ic->irq_set_type = ep93xx_gpio_irq_type; | |
| 333 | +} | |
| 334 | + | |
| 335 | +static int ep93xx_gpio_add_bank(struct ep93xx_gpio_chip *egc, | |
| 330 | 336 | struct platform_device *pdev, |
| 331 | 337 | struct ep93xx_gpio *epg, |
| 332 | 338 | struct ep93xx_gpio_bank *bank) |
| 333 | 339 | { |
| 334 | 340 | void __iomem *data = epg->base + bank->data; |
| 335 | 341 | void __iomem *dir = epg->base + bank->dir; |
| 342 | + struct gpio_chip *gc = &egc->gc; | |
| 336 | 343 | struct device *dev = &pdev->dev; |
| 337 | 344 | struct gpio_irq_chip *girq; |
| 338 | 345 | int err; |
| @@ -346,8 +353,21 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, · 7 unmodified lines | ||
| 346 | 353 | |
| 347 | 354 | girq = &gc->irq; |
| 348 | 355 | if (bank->has_irq || bank->has_hierarchical_irq) { |
| 356 | + struct irq_chip *ic; | |
| 357 | + | |
| 349 | 358 | gc->set_config = ep93xx_gpio_set_config; |
| 350 | − girq->chip = &ep93xx_gpio_irq_chip; | |
| 359 | + egc->eic = devm_kcalloc(dev, 1, | |
| 360 | + sizeof(*egc->eic), | |
| 361 | + GFP_KERNEL); | |
| 362 | + if (!egc->eic) | |
| 363 | + return -ENOMEM; | |
| 364 | + egc->eic->irq_offset = bank->irq; | |
| 365 | + ic = &egc->eic->ic; | |
| 366 | + ic->name = devm_kasprintf(dev, GFP_KERNEL, "gpio-irq-%s", bank->label); | |
| 367 | + if (!ic->name) | |
| 368 | + return -ENOMEM; | |
| 369 | + ep93xx_init_irq_chip(dev, ic); | |
| 370 | + girq->chip = ic; | |
| 351 | 371 | } |
| 352 | 372 | |
| 353 | 373 | if (bank->has_irq) { |
| @@ -389,7 +409,7 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, · 35 unmodified lines | ||
| 389 | 409 | gpio_irq = EP93XX_GPIO_F_IRQ_BASE + i; |
| 390 | 410 | irq_set_chip_data(gpio_irq, &epg->gc[5]); |
| 391 | 411 | irq_set_chip_and_handler(gpio_irq, |
| 392 | − &ep93xx_gpio_irq_chip, | |
| 412 | + girq->chip, | |
| 393 | 413 | handle_level_irq); |
| 394 | 414 | irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST); |
| 395 | 415 | } |
| @@ -415,7 +435,7 @@ static int ep93xx_gpio_probe(struct platform_device *pdev) · 19 unmodified lines | ||
| 415 | 435 | return PTR_ERR(epg->base); |
| 416 | 436 | |
| 417 | 437 | for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) { |
| 418 | − struct gpio_chip *gc = &epg->gc[i]; | |
| 438 | + struct ep93xx_gpio_chip *gc = &epg->gc[i]; | |
| 419 | 439 | struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i]; |
| 420 | 440 | |
| 421 | 441 | if (ep93xx_gpio_add_bank(gc, pdev, epg, bank)) |
| @@ -676,20 +676,17 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip, · 675 unmodified lines | ||
| 676 | 676 | else |
| 677 | 677 | state->duty_cycle = 1; |
| 678 | 678 | |
| 679 | + val = (unsigned long long) u; /* on duration */ | |
| 679 | 680 | regmap_read(mvpwm->regs, mvebu_pwmreg_blink_off_duration(mvpwm), &u); |
| 680 | − val = (unsigned long long) u * NSEC_PER_SEC; | |
| 681 | + val += (unsigned long long) u; /* period = on + off duration */ | |
| 682 | + val *= NSEC_PER_SEC; | |
| 681 | 683 | do_div(val, mvpwm->clk_rate); |
| 682 | − if (val < state->duty_cycle) { | |
| 684 | + if (val > UINT_MAX) | |
| 685 | + state->period = UINT_MAX; | |
| 686 | + else if (val) | |
| 687 | + state->period = val; | |
| 688 | + else | |
| 683 | 689 | state->period = 1; |
| 684 | − } else { | |
| 685 | − val -= state->duty_cycle; | |
| 686 | − if (val > UINT_MAX) | |
| 687 | − state->period = UINT_MAX; | |
| 688 | − else if (val) | |
| 689 | − state->period = val; | |
| 690 | − else | |
| 691 | − state->period = 1; | |
| 692 | − } | |
| 693 | 690 | |
| 694 | 691 | regmap_read(mvchip->regs, GPIO_BLINK_EN_OFF + mvchip->offset, &u); |
| 695 | 692 | if (u) |
| @@ -776,6 +776,8 @@ static void edge_detector_stop(struct line *line) · 775 unmodified lines | ||
| 776 | 776 | cancel_delayed_work_sync(&line->work); |
| 777 | 777 | WRITE_ONCE(line->sw_debounced, 0); |
| 778 | 778 | WRITE_ONCE(line->eflags, 0); |
| 779 | + if (line->desc) | |
| 780 | + WRITE_ONCE(line->desc->debounce_period_us, 0); | |
| 779 | 781 | /* do not change line->level - see comment in debounced_value() */ |
| 780 | 782 | } |
| 781 | 783 | |
| @@ -1979,6 +1981,21 @@ struct gpio_chardev_data { · 1197 unmodified lines | ||
| 1979 | 1981 | #endif |
| 1980 | 1982 | }; |
| 1981 | 1983 | |
| 1984 | +static int chipinfo_get(struct gpio_chardev_data *cdev, void __user *ip) | |
| 1985 | +{ | |
| 1986 | + struct gpio_device *gdev = cdev->gdev; | |
| 1987 | + struct gpiochip_info chipinfo; | |
| 1988 | + | |
| 1989 | + memset(&chipinfo, 0, sizeof(chipinfo)); | |
| 1990 | + | |
| 1991 | + strscpy(chipinfo.name, dev_name(&gdev->dev), sizeof(chipinfo.name)); | |
| 1992 | + strscpy(chipinfo.label, gdev->label, sizeof(chipinfo.label)); | |
| 1993 | + chipinfo.lines = gdev->ngpio; | |
| 1994 | + if (copy_to_user(ip, &chipinfo, sizeof(chipinfo))) | |
| 1995 | + return -EFAULT; | |
| 1996 | + return 0; | |
| 1997 | +} | |
| 1998 | + | |
| 1982 | 1999 | #ifdef CONFIG_GPIO_CDEV_V1 |
| 1983 | 2000 | /* |
| 1984 | 2001 | * returns 0 if the versions match, else the previously selected ABI version |
| @@ -1993,6 +2010,41 @@ static int lineinfo_ensure_abi_version(struct gpio_chardev_data *cdata, · 8 unmodified lines | ||
| 1993 | 2010 | |
| 1994 | 2011 | return abiv; |
| 1995 | 2012 | } |
| 2013 | + | |
| 2014 | +static int lineinfo_get_v1(struct gpio_chardev_data *cdev, void __user *ip, | |
| 2015 | + bool watch) | |
| 2016 | +{ | |
| 2017 | + struct gpio_desc *desc; | |
| 2018 | + struct gpioline_info lineinfo; | |
| 2019 | + struct gpio_v2_line_info lineinfo_v2; | |
| 2020 | + | |
| 2021 | + if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) | |
| 2022 | + return -EFAULT; | |
| 2023 | + | |
| 2024 | + /* this doubles as a range check on line_offset */ | |
| 2025 | + desc = gpiochip_get_desc(cdev->gdev->chip, lineinfo.line_offset); | |
| 2026 | + if (IS_ERR(desc)) | |
| 2027 | + return PTR_ERR(desc); | |
| 2028 | + | |
| 2029 | + if (watch) { | |
| 2030 | + if (lineinfo_ensure_abi_version(cdev, 1)) | |
| 2031 | + return -EPERM; | |
| 2032 | + | |
| 2033 | + if (test_and_set_bit(lineinfo.line_offset, cdev->watched_lines)) | |
| 2034 | + return -EBUSY; | |
| 2035 | + } | |
| 2036 | + | |
| 2037 | + gpio_desc_to_lineinfo(desc, &lineinfo_v2); | |
| 2038 | + gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo); | |
| 2039 | + | |
| 2040 | + if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) { | |
| 2041 | + if (watch) | |
| 2042 | + clear_bit(lineinfo.line_offset, cdev->watched_lines); | |
| 2043 | + return -EFAULT; | |
| 2044 | + } | |
| 2045 | + | |
| 2046 | + return 0; | |
| 2047 | +} | |
| 1996 | 2048 | #endif |
| 1997 | 2049 | |
| 1998 | 2050 | static int lineinfo_get(struct gpio_chardev_data *cdev, void __user *ip, |
| @@ -2030,6 +2082,22 @@ static int lineinfo_get(struct gpio_chardev_data *cdev, void __user *ip, · 31 unmodified lines | ||
| 2030 | 2082 | return 0; |
| 2031 | 2083 | } |
| 2032 | 2084 | |
| 2085 | +static int lineinfo_unwatch(struct gpio_chardev_data *cdev, void __user *ip) | |
| 2086 | +{ | |
| 2087 | + __u32 offset; | |
| 2088 | + | |
| 2089 | + if (copy_from_user(&offset, ip, sizeof(offset))) | |
| 2090 | + return -EFAULT; | |
| 2091 | + | |
| 2092 | + if (offset >= cdev->gdev->ngpio) | |
| 2093 | + return -EINVAL; | |
| 2094 | + | |
| 2095 | + if (!test_and_clear_bit(offset, cdev->watched_lines)) | |
| 2096 | + return -EBUSY; | |
| 2097 | + | |
| 2098 | + return 0; | |
| 2099 | +} | |
| 2100 | + | |
| 2033 | 2101 | /* |
| 2034 | 2102 | * gpio_ioctl() - ioctl handler for the GPIO chardev |
| 2035 | 2103 | */ |
| @@ -2037,80 +2105,24 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) · 1 unmodified line | ||
| 2037 | 2105 | { |
| 2038 | 2106 | struct gpio_chardev_data *cdev = file->private_data; |
| 2039 | 2107 | struct gpio_device *gdev = cdev->gdev; |
| 2040 | − struct gpio_chip *gc = gdev->chip; | |
| 2041 | 2108 | void __user *ip = (void __user *)arg; |
| 2042 | − __u32 offset; | |
| 2043 | 2109 | |
| 2044 | 2110 | /* We fail any subsequent ioctl():s when the chip is gone */ |
| 2045 | − if (!gc) | |
| 2111 | + if (!gdev->chip) | |
| 2046 | 2112 | return -ENODEV; |
| 2047 | 2113 | |
| 2048 | 2114 | /* Fill in the struct and pass to userspace */ |
| 2049 | 2115 | if (cmd == GPIO_GET_CHIPINFO_IOCTL) { |
| 2050 | − struct gpiochip_info chipinfo; | |
| 2051 | − | |
| 2052 | − memset(&chipinfo, 0, sizeof(chipinfo)); | |
| 2053 | − | |
| 2054 | − strscpy(chipinfo.name, dev_name(&gdev->dev), | |
| 2055 | − sizeof(chipinfo.name)); | |
| 2056 | − strscpy(chipinfo.label, gdev->label, | |
| 2057 | − sizeof(chipinfo.label)); | |
| 2058 | − chipinfo.lines = gdev->ngpio; | |
| 2059 | − if (copy_to_user(ip, &chipinfo, sizeof(chipinfo))) | |
| 2060 | − return -EFAULT; | |
| 2061 | − return 0; | |
| 2116 | + return chipinfo_get(cdev, ip); | |
| 2062 | 2117 | #ifdef CONFIG_GPIO_CDEV_V1 |
| 2063 | − } else if (cmd == GPIO_GET_LINEINFO_IOCTL) { | |
| 2064 | − struct gpio_desc *desc; | |
| 2065 | − struct gpioline_info lineinfo; | |
| 2066 | − struct gpio_v2_line_info lineinfo_v2; | |
| 2067 | − | |
| 2068 | − if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) | |
| 2069 | − return -EFAULT; | |
| 2070 | − | |
| 2071 | − /* this doubles as a range check on line_offset */ | |
| 2072 | − desc = gpiochip_get_desc(gc, lineinfo.line_offset); | |
| 2073 | − if (IS_ERR(desc)) | |
| 2074 | − return PTR_ERR(desc); | |
| 2075 | − | |
| 2076 | − gpio_desc_to_lineinfo(desc, &lineinfo_v2); | |
| 2077 | − gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo); | |
| 2078 | − | |
| 2079 | − if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) | |
| 2080 | − return -EFAULT; | |
| 2081 | − return 0; | |
| 2082 | 2118 | } else if (cmd == GPIO_GET_LINEHANDLE_IOCTL) { |
| 2083 | 2119 | return linehandle_create(gdev, ip); |
| 2084 | 2120 | } else if (cmd == GPIO_GET_LINEEVENT_IOCTL) { |
| 2085 | 2121 | return lineevent_create(gdev, ip); |
| 2086 | − } else if (cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) { | |
| 2087 | − struct gpio_desc *desc; | |
| 2088 | − struct gpioline_info lineinfo; | |
| 2089 | − struct gpio_v2_line_info lineinfo_v2; | |
| 2090 | − | |
| 2091 | − if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) | |
| 2092 | − return -EFAULT; | |
| 2093 | − | |
| 2094 | − /* this doubles as a range check on line_offset */ | |
| 2095 | − desc = gpiochip_get_desc(gc, lineinfo.line_offset); | |
| 2096 | − if (IS_ERR(desc)) | |
| 2097 | − return PTR_ERR(desc); | |
| 2098 | − | |
| 2099 | − if (lineinfo_ensure_abi_version(cdev, 1)) | |
| 2100 | − return -EPERM; | |
| 2101 | − | |
| 2102 | − if (test_and_set_bit(lineinfo.line_offset, cdev->watched_lines)) | |
| 2103 | − return -EBUSY; | |
| 2104 | − | |
| 2105 | − gpio_desc_to_lineinfo(desc, &lineinfo_v2); | |
| 2106 | − gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo); | |
| 2107 | − | |
| 2108 | − if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) { | |
| 2109 | − clear_bit(lineinfo.line_offset, cdev->watched_lines); | |
| 2110 | − return -EFAULT; | |
| 2111 | − } | |
| 2112 | − | |
| 2113 | − return 0; | |
| 2122 | + } else if (cmd == GPIO_GET_LINEINFO_IOCTL || | |
| 2123 | + cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) { | |
| 2124 | + return lineinfo_get_v1(cdev, ip, | |
| 2125 | + cmd == GPIO_GET_LINEINFO_WATCH_IOCTL); | |
| 2114 | 2126 | #endif /* CONFIG_GPIO_CDEV_V1 */ |
| 2115 | 2127 | } else if (cmd == GPIO_V2_GET_LINEINFO_IOCTL || |
| 2116 | 2128 | cmd == GPIO_V2_GET_LINEINFO_WATCH_IOCTL) { |
| @@ -2119,16 +2131,7 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) · 2 unmodified lines | ||
| 2119 | 2131 | } else if (cmd == GPIO_V2_GET_LINE_IOCTL) { |
| 2120 | 2132 | return linereq_create(gdev, ip); |
| 2121 | 2133 | } else if (cmd == GPIO_GET_LINEINFO_UNWATCH_IOCTL) { |
| 2122 | − if (copy_from_user(&offset, ip, sizeof(offset))) | |
| 2123 | − return -EFAULT; | |
| 2124 | − | |
| 2125 | − if (offset >= cdev->gdev->ngpio) | |
| 2126 | − return -EINVAL; | |
| 2127 | − | |
| 2128 | − if (!test_and_clear_bit(offset, cdev->watched_lines)) | |
| 2129 | − return -EBUSY; | |
| 2130 | − | |
| 2131 | − return 0; | |
| 2134 | + return lineinfo_unwatch(cdev, ip); | |
| 2132 | 2135 | } |
| 2133 | 2136 | return -EINVAL; |
| 2134 | 2137 | } |
| @@ -603,7 +603,11 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, · 602 unmodified lines | ||
| 603 | 603 | ret = gdev->id; |
| 604 | 604 | goto err_free_gdev; |
| 605 | 605 | } |
| 606 | − dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id); | |
| 606 | + | |
| 607 | + ret = dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id); | |
| 608 | + if (ret) | |
| 609 | + goto err_free_ida; | |
| 610 | + | |
| 607 | 611 | device_initialize(&gdev->dev); |
| 608 | 612 | dev_set_drvdata(&gdev->dev, gdev); |
| 609 | 613 | if (gc->parent && gc->parent->driver) |
| @@ -617,7 +621,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, · 7 unmodified lines | ||
| 617 | 621 | gdev->descs = kcalloc(gc->ngpio, sizeof(gdev->descs[0]), GFP_KERNEL); |
| 618 | 622 | if (!gdev->descs) { |
| 619 | 623 | ret = -ENOMEM; |
| 620 | − goto err_free_ida; | |
| 624 | + goto err_free_dev_name; | |
| 621 | 625 | } |
| 622 | 626 | |
| 623 | 627 | if (gc->ngpio == 0) { |
| @@ -768,6 +772,8 @@ err_free_label: · 144 unmodified lines | ||
| 768 | 772 | kfree_const(gdev->label); |
| 769 | 773 | err_free_descs: |
| 770 | 774 | kfree(gdev->descs); |
| 775 | +err_free_dev_name: | |
| 776 | + kfree(dev_name(&gdev->dev)); | |
| 771 | 777 | err_free_ida: |
| 772 | 778 | ida_free(&gpio_ida, gdev->id); |
| 773 | 779 | err_free_gdev: |
| @@ -1489,6 +1495,9 @@ static int gpiochip_add_irqchip(struct gpio_chip *gc, · 715 unmodified lines | ||
| 1489 | 1495 | type = IRQ_TYPE_NONE; |
| 1490 | 1496 | } |
| 1491 | 1497 | |
| 1498 | + if (gc->to_irq) | |
| 1499 | + chip_warn(gc, "to_irq is redefined in %s and you shouldn't rely on it\n", __func__); | |
| 1500 | + | |
| 1492 | 1501 | gc->to_irq = gpiochip_to_irq; |
| 1493 | 1502 | gc->irq.default_type = type; |
| 1494 | 1503 | gc->irq.lock_key = lock_key; |
| @@ -2548,7 +2557,7 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep, · 1053 unmodified lines | ||
| 2548 | 2557 | struct gpio_chip *gc = desc_array[i]->gdev->chip; |
| 2549 | 2558 | unsigned long fastpath[2 * BITS_TO_LONGS(FASTPATH_NGPIO)]; |
| 2550 | 2559 | unsigned long *mask, *bits; |
| 2551 | − int first, j, ret; | |
| 2560 | + int first, j; | |
| 2552 | 2561 | |
| 2553 | 2562 | if (likely(gc->ngpio <= FASTPATH_NGPIO)) { |
| 2554 | 2563 | mask = fastpath; |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/sched/task.h> |
| 27 | 27 | |
| 28 | 28 | #include "amdgpu_object.h" |
| 29 | +#include "amdgpu_gem.h" | |
| 29 | 30 | #include "amdgpu_vm.h" |
| 30 | 31 | #include "amdgpu_amdkfd.h" |
| 31 | 32 | #include "amdgpu_dma_buf.h" |
| @@ -1152,7 +1153,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( · 1120 unmodified lines | ||
| 1152 | 1153 | struct sg_table *sg = NULL; |
| 1153 | 1154 | uint64_t user_addr = 0; |
| 1154 | 1155 | struct amdgpu_bo *bo; |
| 1155 | − struct amdgpu_bo_param bp; | |
| 1156 | + struct drm_gem_object *gobj; | |
| 1156 | 1157 | u32 domain, alloc_domain; |
| 1157 | 1158 | u64 alloc_flags; |
| 1158 | 1159 | int ret; |
| @@ -1220,19 +1221,14 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( · 61 unmodified lines | ||
| 1220 | 1221 | pr_debug("\tcreate BO VA 0x%llx size 0x%llx domain %s\n", |
| 1221 | 1222 | va, size, domain_string(alloc_domain)); |
| 1222 | 1223 | |
| 1223 | − memset(&bp, 0, sizeof(bp)); | |
| 1224 | − bp.size = size; | |
| 1225 | − bp.byte_align = 1; | |
| 1226 | − bp.domain = alloc_domain; | |
| 1227 | − bp.flags = alloc_flags; | |
| 1228 | − bp.type = bo_type; | |
| 1229 | − bp.resv = NULL; | |
| 1230 | − ret = amdgpu_bo_create(adev, &bp, &bo); | |
| 1224 | + ret = amdgpu_gem_object_create(adev, size, 1, alloc_domain, alloc_flags, | |
| 1225 | + bo_type, NULL, &gobj); | |
| 1231 | 1226 | if (ret) { |
| 1232 | 1227 | pr_debug("Failed to create BO on domain %s. ret %d\n", |
| 1233 | − domain_string(alloc_domain), ret); | |
| 1228 | + domain_string(alloc_domain), ret); | |
| 1234 | 1229 | goto err_bo_create; |
| 1235 | 1230 | } |
| 1231 | + bo = gem_to_amdgpu_bo(gobj); | |
| 1236 | 1232 | if (bo_type == ttm_bo_type_sg) { |
| 1237 | 1233 | bo->tbo.sg = sg; |
| 1238 | 1234 | bo->tbo.ttm->sg = sg; |
| @@ -112,6 +112,7 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev) · 111 unmodified lines | ||
| 112 | 112 | union igp_info { |
| 113 | 113 | struct atom_integrated_system_info_v1_11 v11; |
| 114 | 114 | struct atom_integrated_system_info_v1_12 v12; |
| 115 | + struct atom_integrated_system_info_v2_1 v21; | |
| 115 | 116 | }; |
| 116 | 117 | |
| 117 | 118 | union umc_info { |
| @@ -209,24 +210,42 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev, · 91 unmodified lines | ||
| 209 | 210 | if (adev->flags & AMD_IS_APU) { |
| 210 | 211 | igp_info = (union igp_info *) |
| 211 | 212 | (mode_info->atom_context->bios + data_offset); |
| 212 | − switch (crev) { | |
| 213 | − case 11: | |
| 214 | − mem_channel_number = igp_info->v11.umachannelnumber; | |
| 215 | − /* channel width is 64 */ | |
| 216 | − if (vram_width) | |
| 217 | − *vram_width = mem_channel_number * 64; | |
| 218 | − mem_type = igp_info->v11.memorytype; | |
| 219 | − if (vram_type) | |
| 220 | − *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); | |
| 213 | + switch (frev) { | |
| 214 | + case 1: | |
| 215 | + switch (crev) { | |
| 216 | + case 11: | |
| 217 | + case 12: | |
| 218 | + mem_channel_number = igp_info->v11.umachannelnumber; | |
| 219 | + if (!mem_channel_number) | |
| 220 | + mem_channel_number = 1; | |
| 221 | + /* channel width is 64 */ | |
| 222 | + if (vram_width) | |
| 223 | + *vram_width = mem_channel_number * 64; | |
| 224 | + mem_type = igp_info->v11.memorytype; | |
| 225 | + if (vram_type) | |
| 226 | + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); | |
| 227 | + break; | |
| 228 | + default: | |
| 229 | + return -EINVAL; | |
| 230 | + } | |
| 221 | 231 | break; |
| 222 | − case 12: | |
| 223 | − mem_channel_number = igp_info->v12.umachannelnumber; | |
| 224 | − /* channel width is 64 */ | |
| 225 | − if (vram_width) | |
| 226 | − *vram_width = mem_channel_number * 64; | |
| 227 | − mem_type = igp_info->v12.memorytype; | |
| 228 | − if (vram_type) | |
| 229 | − *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); | |
| 232 | + case 2: | |
| 233 | + switch (crev) { | |
| 234 | + case 1: | |
| 235 | + case 2: | |
| 236 | + mem_channel_number = igp_info->v21.umachannelnumber; | |
| 237 | + if (!mem_channel_number) | |
| 238 | + mem_channel_number = 1; | |
| 239 | + /* channel width is 64 */ | |
| 240 | + if (vram_width) | |
| 241 | + *vram_width = mem_channel_number * 64; | |
| 242 | + mem_type = igp_info->v21.memorytype; | |
| 243 | + if (vram_type) | |
| 244 | + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); | |
| 245 | + break; | |
| 246 | + default: | |
| 247 | + return -EINVAL; | |
| 248 | + } | |
| 230 | 249 | break; |
| 231 | 250 | default: |
| 232 | 251 | return -EINVAL; |
| @@ -81,7 +81,6 @@ MODULE_FIRMWARE("amdgpu/navi10_gpu_info.bin"); · 80 unmodified lines | ||
| 81 | 81 | MODULE_FIRMWARE("amdgpu/navi14_gpu_info.bin"); |
| 82 | 82 | MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin"); |
| 83 | 83 | MODULE_FIRMWARE("amdgpu/vangogh_gpu_info.bin"); |
| 84 | −MODULE_FIRMWARE("amdgpu/green_sardine_gpu_info.bin"); | |
| 85 | 84 | |
| 86 | 85 | #define AMDGPU_RESUME_MS 2000 |
| 87 | 86 | |
| @@ -2548,11 +2547,11 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) · 2460 unmodified lines | ||
| 2548 | 2547 | if (adev->gmc.xgmi.num_physical_nodes > 1) |
| 2549 | 2548 | amdgpu_xgmi_remove_device(adev); |
| 2550 | 2549 | |
| 2551 | − amdgpu_amdkfd_device_fini(adev); | |
| 2552 | − | |
| 2553 | 2550 | amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE); |
| 2554 | 2551 | amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE); |
| 2555 | 2552 | |
| 2553 | + amdgpu_amdkfd_device_fini(adev); | |
| 2554 | + | |
| 2556 | 2555 | /* need to disable SMC first */ |
| 2557 | 2556 | for (i = 0; i < adev->num_ip_blocks; i++) { |
| 2558 | 2557 | if (!adev->ip_blocks[i].status.hw) |
| @@ -3034,7 +3033,7 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) · 475 unmodified lines | ||
| 3034 | 3033 | #endif |
| 3035 | 3034 | default: |
| 3036 | 3035 | if (amdgpu_dc > 0) |
| 3037 | − DRM_INFO("Display Core has been requested via kernel parameter " | |
| 3036 | + DRM_INFO_ONCE("Display Core has been requested via kernel parameter " | |
| 3038 | 3037 | "but isn't supported by ASIC, ignoring\n"); |
| 3039 | 3038 | return false; |
| 3040 | 3039 | } |
| @@ -926,8 +926,10 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev, · 925 unmodified lines | ||
| 926 | 926 | struct drm_file *file_priv, |
| 927 | 927 | const struct drm_mode_fb_cmd2 *mode_cmd) |
| 928 | 928 | { |
| 929 | − struct drm_gem_object *obj; | |
| 930 | 929 | struct amdgpu_framebuffer *amdgpu_fb; |
| 930 | + struct drm_gem_object *obj; | |
| 931 | + struct amdgpu_bo *bo; | |
| 932 | + uint32_t domains; | |
| 931 | 933 | int ret; |
| 932 | 934 | |
| 933 | 935 | obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); |
| @@ -938,7 +940,9 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev, · 4 unmodified lines | ||
| 938 | 940 | } |
| 939 | 941 | |
| 940 | 942 | /* Handle is imported dma-buf, so cannot be migrated to VRAM for scanout */ |
| 941 | − if (obj->import_attach) { | |
| 943 | + bo = gem_to_amdgpu_bo(obj); | |
| 944 | + domains = amdgpu_display_supported_domains(drm_to_adev(dev), bo->flags); | |
| 945 | + if (obj->import_attach && !(domains & AMDGPU_GEM_DOMAIN_GTT)) { | |
| 942 | 946 | drm_dbg_kms(dev, "Cannot create framebuffer from imported dma_buf\n"); |
| 943 | 947 | return ERR_PTR(-EINVAL); |
| 944 | 948 | } |
| @@ -1085,6 +1085,8 @@ static const struct pci_device_id pciidlist[] = { · 1084 unmodified lines | ||
| 1085 | 1085 | |
| 1086 | 1086 | /* Renoir */ |
| 1087 | 1087 | {0x1002, 0x1636, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU}, |
| 1088 | + {0x1002, 0x1638, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU}, | |
| 1089 | + {0x1002, 0x164C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU}, | |
| 1088 | 1090 | |
| 1089 | 1091 | /* Navi12 */ |
| 1090 | 1092 | {0x1002, 0x7360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI12}, |
| @@ -269,8 +269,8 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data, · 268 unmodified lines | ||
| 269 | 269 | resv = vm->root.base.bo->tbo.base.resv; |
| 270 | 270 | } |
| 271 | 271 | |
| 272 | −retry: | |
| 273 | 272 | initial_domain = (u32)(0xffffffff & args->in.domains); |
| 273 | +retry: | |
| 274 | 274 | r = amdgpu_gem_object_create(adev, size, args->in.alignment, |
| 275 | 275 | initial_domain, |
| 276 | 276 | flags, ttm_bo_type_device, resv, &gobj); |
| @@ -897,7 +897,7 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, · 896 unmodified lines | ||
| 897 | 897 | return -EINVAL; |
| 898 | 898 | |
| 899 | 899 | /* A shared bo cannot be migrated to VRAM */ |
| 900 | − if (bo->prime_shared_count) { | |
| 900 | + if (bo->prime_shared_count || bo->tbo.base.import_attach) { | |
| 901 | 901 | if (domain & AMDGPU_GEM_DOMAIN_GTT) |
| 902 | 902 | domain = AMDGPU_GEM_DOMAIN_GTT; |
| 903 | 903 | else |
| @@ -563,7 +563,7 @@ static int psp_asd_load(struct psp_context *psp) · 562 unmodified lines | ||
| 563 | 563 | * add workaround to bypass it for sriov now. |
| 564 | 564 | * TODO: add version check to make it common |
| 565 | 565 | */ |
| 566 | − if (amdgpu_sriov_vf(psp->adev) || !psp->asd_fw) | |
| 566 | + if (amdgpu_sriov_vf(psp->adev) || !psp->asd_ucode_size) | |
| 567 | 567 | return 0; |
| 568 | 568 | |
| 569 | 569 | cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); |
| @@ -1315,8 +1315,12 @@ static int psp_hdcp_terminate(struct psp_context *psp) · 745 unmodified lines | ||
| 1315 | 1315 | if (amdgpu_sriov_vf(psp->adev)) |
| 1316 | 1316 | return 0; |
| 1317 | 1317 | |
| 1318 | − if (!psp->hdcp_context.hdcp_initialized) | |
| 1319 | − return 0; | |
| 1318 | + if (!psp->hdcp_context.hdcp_initialized) { | |
| 1319 | + if (psp->hdcp_context.hdcp_shared_buf) | |
| 1320 | + goto out; | |
| 1321 | + else | |
| 1322 | + return 0; | |
| 1323 | + } | |
| 1320 | 1324 | |
| 1321 | 1325 | ret = psp_hdcp_unload(psp); |
| 1322 | 1326 | if (ret) |
| @@ -1324,6 +1328,7 @@ static int psp_hdcp_terminate(struct psp_context *psp) · 1 unmodified line | ||
| 1324 | 1328 | |
| 1325 | 1329 | psp->hdcp_context.hdcp_initialized = false; |
| 1326 | 1330 | |
| 1331 | +out: | |
| 1327 | 1332 | /* free hdcp shared memory */ |
| 1328 | 1333 | amdgpu_bo_free_kernel(&psp->hdcp_context.hdcp_shared_bo, |
| 1329 | 1334 | &psp->hdcp_context.hdcp_shared_mc_addr, |
| @@ -1462,8 +1467,12 @@ static int psp_dtm_terminate(struct psp_context *psp) · 132 unmodified lines | ||
| 1462 | 1467 | if (amdgpu_sriov_vf(psp->adev)) |
| 1463 | 1468 | return 0; |
| 1464 | 1469 | |
| 1465 | − if (!psp->dtm_context.dtm_initialized) | |
| 1466 | − return 0; | |
| 1470 | + if (!psp->dtm_context.dtm_initialized) { | |
| 1471 | + if (psp->dtm_context.dtm_shared_buf) | |
| 1472 | + goto out; | |
| 1473 | + else | |
| 1474 | + return 0; | |
| 1475 | + } | |
| 1467 | 1476 | |
| 1468 | 1477 | ret = psp_dtm_unload(psp); |
| 1469 | 1478 | if (ret) |
| @@ -1471,6 +1480,7 @@ static int psp_dtm_terminate(struct psp_context *psp) · 1 unmodified line | ||
| 1471 | 1480 | |
| 1472 | 1481 | psp->dtm_context.dtm_initialized = false; |
| 1473 | 1482 | |
| 1483 | +out: | |
| 1474 | 1484 | /* free hdcp shared memory */ |
| 1475 | 1485 | amdgpu_bo_free_kernel(&psp->dtm_context.dtm_shared_bo, |
| 1476 | 1486 | &psp->dtm_context.dtm_shared_mc_addr, |
| @@ -2589,11 +2599,10 @@ static int parse_ta_bin_descriptor(struct psp_context *psp, · 1112 unmodified lines | ||
| 2589 | 2599 | |
| 2590 | 2600 | switch (desc->fw_type) { |
| 2591 | 2601 | case TA_FW_TYPE_PSP_ASD: |
| 2592 | − psp->asd_fw_version = le32_to_cpu(desc->fw_version); | |
| 2602 | + psp->asd_fw_version = le32_to_cpu(desc->fw_version); | |
| 2593 | 2603 | psp->asd_feature_version = le32_to_cpu(desc->fw_version); |
| 2594 | − psp->asd_ucode_size = le32_to_cpu(desc->size_bytes); | |
| 2604 | + psp->asd_ucode_size = le32_to_cpu(desc->size_bytes); | |
| 2595 | 2605 | psp->asd_start_addr = ucode_start_addr; |
| 2596 | − psp->asd_fw = psp->ta_fw; | |
| 2597 | 2606 | break; |
| 2598 | 2607 | case TA_FW_TYPE_PSP_XGMI: |
| 2599 | 2608 | psp->ta_xgmi_ucode_version = le32_to_cpu(desc->fw_version); |
| @@ -1518,7 +1518,7 @@ static int amdgpu_ras_badpages_read(struct amdgpu_device *adev, · 1517 unmodified lines | ||
| 1518 | 1518 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
| 1519 | 1519 | struct ras_err_handler_data *data; |
| 1520 | 1520 | int i = 0; |
| 1521 | − int ret = 0; | |
| 1521 | + int ret = 0, status; | |
| 1522 | 1522 | |
| 1523 | 1523 | if (!con || !con->eh_data || !bps || !count) |
| 1524 | 1524 | return -EINVAL; |
| @@ -1543,12 +1543,12 @@ static int amdgpu_ras_badpages_read(struct amdgpu_device *adev, · 18 unmodified lines | ||
| 1543 | 1543 | .size = AMDGPU_GPU_PAGE_SIZE, |
| 1544 | 1544 | .flags = AMDGPU_RAS_RETIRE_PAGE_RESERVED, |
| 1545 | 1545 | }; |
| 1546 | − ret = amdgpu_vram_mgr_query_page_status( | |
| 1546 | + status = amdgpu_vram_mgr_query_page_status( | |
| 1547 | 1547 | ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM), |
| 1548 | 1548 | data->bps[i].retired_page); |
| 1549 | − if (ret == -EBUSY) | |
| 1549 | + if (status == -EBUSY) | |
| 1550 | 1550 | (*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_PENDING; |
| 1551 | − else if (ret == -ENOENT) | |
| 1551 | + else if (status == -ENOENT) | |
| 1552 | 1552 | (*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_FAULT; |
| 1553 | 1553 | } |
| 1554 | 1554 | |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #define EEPROM_I2C_TARGET_ADDR_VEGA20 0xA0 |
| 31 | 31 | #define EEPROM_I2C_TARGET_ADDR_ARCTURUS 0xA8 |
| 32 | 32 | #define EEPROM_I2C_TARGET_ADDR_ARCTURUS_D342 0xA0 |
| 33 | +#define EEPROM_I2C_TARGET_ADDR_SIENNA_CICHLID 0xA0 | |
| 33 | 34 | |
| 34 | 35 | /* |
| 35 | 36 | * The 2 macros bellow represent the actual size in bytes that |
| @@ -62,7 +63,8 @@ · 26 unmodified lines | ||
| 62 | 63 | static bool __is_ras_eeprom_supported(struct amdgpu_device *adev) |
| 63 | 64 | { |
| 64 | 65 | if ((adev->asic_type == CHIP_VEGA20) || |
| 65 | − (adev->asic_type == CHIP_ARCTURUS)) | |
| 66 | + (adev->asic_type == CHIP_ARCTURUS) || | |
| 67 | + (adev->asic_type == CHIP_SIENNA_CICHLID)) | |
| 66 | 68 | return true; |
| 67 | 69 | |
| 68 | 70 | return false; |
| @@ -100,6 +102,10 @@ static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev, · 31 unmodified lines | ||
| 100 | 102 | case CHIP_ARCTURUS: |
| 101 | 103 | return __get_eeprom_i2c_addr_arct(adev, i2c_addr); |
| 102 | 104 | |
| 105 | + case CHIP_SIENNA_CICHLID: | |
| 106 | + *i2c_addr = EEPROM_I2C_TARGET_ADDR_SIENNA_CICHLID; | |
| 107 | + break; | |
| 108 | + | |
| 103 | 109 | default: |
| 104 | 110 | return false; |
| 105 | 111 | } |
| @@ -99,6 +99,14 @@ · 98 unmodified lines | ||
| 99 | 99 | #define mmGCR_GENERAL_CNTL_Sienna_Cichlid 0x1580 |
| 100 | 100 | #define mmGCR_GENERAL_CNTL_Sienna_Cichlid_BASE_IDX 0 |
| 101 | 101 | |
| 102 | +#define mmCGTS_TCC_DISABLE_Vangogh 0x5006 | |
| 103 | +#define mmCGTS_TCC_DISABLE_Vangogh_BASE_IDX 1 | |
| 104 | +#define mmCGTS_USER_TCC_DISABLE_Vangogh 0x5007 | |
| 105 | +#define mmCGTS_USER_TCC_DISABLE_Vangogh_BASE_IDX 1 | |
| 106 | +#define mmGOLDEN_TSC_COUNT_UPPER_Vangogh 0x0025 | |
| 107 | +#define mmGOLDEN_TSC_COUNT_UPPER_Vangogh_BASE_IDX 1 | |
| 108 | +#define mmGOLDEN_TSC_COUNT_LOWER_Vangogh 0x0026 | |
| 109 | +#define mmGOLDEN_TSC_COUNT_LOWER_Vangogh_BASE_IDX 1 | |
| 102 | 110 | #define mmSPI_CONFIG_CNTL_1_Vangogh 0x2441 |
| 103 | 111 | #define mmSPI_CONFIG_CNTL_1_Vangogh_BASE_IDX 1 |
| 104 | 112 | #define mmVGT_TF_MEMORY_BASE_HI_Vangogh 0x2261 |
| @@ -115,6 +123,8 @@ · 10 unmodified lines | ||
| 115 | 123 | #define mmVGT_ESGS_RING_SIZE_Vangogh_BASE_IDX 1 |
| 116 | 124 | #define mmSPI_CONFIG_CNTL_Vangogh 0x2440 |
| 117 | 125 | #define mmSPI_CONFIG_CNTL_Vangogh_BASE_IDX 1 |
| 126 | +#define mmGCR_GENERAL_CNTL_Vangogh 0x1580 | |
| 127 | +#define mmGCR_GENERAL_CNTL_Vangogh_BASE_IDX 0 | |
| 118 | 128 | |
| 119 | 129 | #define mmCP_HYP_PFP_UCODE_ADDR 0x5814 |
| 120 | 130 | #define mmCP_HYP_PFP_UCODE_ADDR_BASE_IDX 1 |
| @@ -160,6 +170,9 @@ · 39 unmodified lines | ||
| 160 | 170 | #define mmGCVM_L2_CGTT_CLK_CTRL_Sienna_Cichlid 0x15db |
| 161 | 171 | #define mmGCVM_L2_CGTT_CLK_CTRL_Sienna_Cichlid_BASE_IDX 0 |
| 162 | 172 | |
| 173 | +#define mmGC_THROTTLE_CTRL_Sienna_Cichlid 0x2030 | |
| 174 | +#define mmGC_THROTTLE_CTRL_Sienna_Cichlid_BASE_IDX 0 | |
| 175 | + | |
| 163 | 176 | MODULE_FIRMWARE("amdgpu/navi10_ce.bin"); |
| 164 | 177 | MODULE_FIRMWARE("amdgpu/navi10_pfp.bin"); |
| 165 | 178 | MODULE_FIRMWARE("amdgpu/navi10_me.bin"); |
| @@ -3237,7 +3250,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_3_vangogh[] = · 3071 unmodified lines | ||
| 3237 | 3250 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG4, 0xffffffff, 0x00800000), |
| 3238 | 3251 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_EXCEPTION_CONTROL, 0x7fff0f1f, 0x00b80000), |
| 3239 | 3252 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG, 0x0c1807ff, 0x00000142), |
| 3240 | − SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL, 0x1ff1ffff, 0x00000500), | |
| 3253 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL_Vangogh, 0x1ff1ffff, 0x00000500), | |
| 3241 | 3254 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL1_PIPE_STEER, 0x000000ff, 0x000000e4), |
| 3242 | 3255 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2_PIPE_STEER_0, 0x77777777, 0x32103210), |
| 3243 | 3256 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2_PIPE_STEER_1, 0x77777777, 0x32103210), |
| @@ -3324,6 +3337,7 @@ static void gfx_v10_0_ring_emit_de_meta(struct amdgpu_ring *ring, bool resume); · 80 unmodified lines | ||
| 3324 | 3337 | static void gfx_v10_0_ring_emit_frame_cntl(struct amdgpu_ring *ring, bool start, bool secure); |
| 3325 | 3338 | static u32 gfx_v10_3_get_disabled_sa(struct amdgpu_device *adev); |
| 3326 | 3339 | static void gfx_v10_3_program_pbb_mode(struct amdgpu_device *adev); |
| 3340 | +static void gfx_v10_3_set_power_brake_sequence(struct amdgpu_device *adev); | |
| 3327 | 3341 | |
| 3328 | 3342 | static void gfx10_kiq_set_resources(struct amdgpu_ring *kiq_ring, uint64_t queue_mask) |
| 3329 | 3343 | { |
| @@ -4926,8 +4940,18 @@ static void gfx_v10_0_tcp_harvest(struct amdgpu_device *adev) · 1596 unmodified lines | ||
| 4926 | 4940 | static void gfx_v10_0_get_tcc_info(struct amdgpu_device *adev) |
| 4927 | 4941 | { |
| 4928 | 4942 | /* TCCs are global (not instanced). */ |
| 4929 | − uint32_t tcc_disable = RREG32_SOC15(GC, 0, mmCGTS_TCC_DISABLE) | | |
| 4930 | − RREG32_SOC15(GC, 0, mmCGTS_USER_TCC_DISABLE); | |
| 4943 | + uint32_t tcc_disable; | |
| 4944 | + | |
| 4945 | + switch (adev->asic_type) { | |
| 4946 | + case CHIP_VANGOGH: | |
| 4947 | + tcc_disable = RREG32_SOC15(GC, 0, mmCGTS_TCC_DISABLE_Vangogh) | | |
| 4948 | + RREG32_SOC15(GC, 0, mmCGTS_USER_TCC_DISABLE_Vangogh); | |
| 4949 | + break; | |
| 4950 | + default: | |
| 4951 | + tcc_disable = RREG32_SOC15(GC, 0, mmCGTS_TCC_DISABLE) | | |
| 4952 | + RREG32_SOC15(GC, 0, mmCGTS_USER_TCC_DISABLE); | |
| 4953 | + break; | |
| 4954 | + } | |
| 4931 | 4955 | |
| 4932 | 4956 | adev->gfx.config.tcc_disabled_mask = |
| 4933 | 4957 | REG_GET_FIELD(tcc_disable, CGTS_TCC_DISABLE, TCC_DISABLE) | |
| @@ -7192,6 +7216,9 @@ static int gfx_v10_0_hw_init(void *handle) · 2258 unmodified lines | ||
| 7192 | 7216 | if (adev->asic_type == CHIP_SIENNA_CICHLID) |
| 7193 | 7217 | gfx_v10_3_program_pbb_mode(adev); |
| 7194 | 7218 | |
| 7219 | + if (adev->asic_type >= CHIP_SIENNA_CICHLID) | |
| 7220 | + gfx_v10_3_set_power_brake_sequence(adev); | |
| 7221 | + | |
| 7195 | 7222 | return r; |
| 7196 | 7223 | } |
| 7197 | 7224 | |
| @@ -7377,8 +7404,16 @@ static uint64_t gfx_v10_0_get_gpu_clock_counter(struct amdgpu_device *adev) · 179 unmodified lines | ||
| 7377 | 7404 | |
| 7378 | 7405 | amdgpu_gfx_off_ctrl(adev, false); |
| 7379 | 7406 | mutex_lock(&adev->gfx.gpu_clock_mutex); |
| 7380 | − clock = (uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER) | | |
| 7381 | − ((uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER) << 32ULL); | |
| 7407 | + switch (adev->asic_type) { | |
| 7408 | + case CHIP_VANGOGH: | |
| 7409 | + clock = (uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh) | | |
| 7410 | + ((uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh) << 32ULL); | |
| 7411 | + break; | |
| 7412 | + default: | |
| 7413 | + clock = (uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER) | | |
| 7414 | + ((uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER) << 32ULL); | |
| 7415 | + break; | |
| 7416 | + } | |
| 7382 | 7417 | mutex_unlock(&adev->gfx.gpu_clock_mutex); |
| 7383 | 7418 | amdgpu_gfx_off_ctrl(adev, true); |
| 7384 | 7419 | return clock; |
| @@ -9169,6 +9204,31 @@ static void gfx_v10_3_program_pbb_mode(struct amdgpu_device *adev) · 1784 unmodified lines | ||
| 9169 | 9204 | } |
| 9170 | 9205 | } |
| 9171 | 9206 | |
| 9207 | +static void gfx_v10_3_set_power_brake_sequence(struct amdgpu_device *adev) | |
| 9208 | +{ | |
| 9209 | + WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, | |
| 9210 | + (0x1 << GRBM_GFX_INDEX__SA_BROADCAST_WRITES__SHIFT) | | |
| 9211 | + (0x1 << GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES__SHIFT) | | |
| 9212 | + (0x1 << GRBM_GFX_INDEX__SE_BROADCAST_WRITES__SHIFT)); | |
| 9213 | + | |
| 9214 | + WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, ixPWRBRK_STALL_PATTERN_CTRL); | |
| 9215 | + WREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA, | |
| 9216 | + (0x1 << PWRBRK_STALL_PATTERN_CTRL__PWRBRK_STEP_INTERVAL__SHIFT) | | |
| 9217 | + (0x12 << PWRBRK_STALL_PATTERN_CTRL__PWRBRK_BEGIN_STEP__SHIFT) | | |
| 9218 | + (0x13 << PWRBRK_STALL_PATTERN_CTRL__PWRBRK_END_STEP__SHIFT) | | |
| 9219 | + (0xf << PWRBRK_STALL_PATTERN_CTRL__PWRBRK_THROTTLE_PATTERN_BIT_NUMS__SHIFT)); | |
| 9220 | + | |
| 9221 | + WREG32_SOC15(GC, 0, mmGC_THROTTLE_CTRL_Sienna_Cichlid, | |
| 9222 | + (0x1 << GC_THROTTLE_CTRL__PWRBRK_STALL_EN__SHIFT) | | |
| 9223 | + (0x1 << GC_THROTTLE_CTRL__PATTERN_MODE__SHIFT) | | |
| 9224 | + (0x5 << GC_THROTTLE_CTRL__RELEASE_STEP_INTERVAL__SHIFT)); | |
| 9225 | + | |
| 9226 | + WREG32_SOC15(GC, 0, mmDIDT_IND_INDEX, ixDIDT_SQ_THROTTLE_CTRL); | |
| 9227 | + | |
| 9228 | + WREG32_SOC15(GC, 0, mmDIDT_IND_DATA, | |
| 9229 | + (0x1 << DIDT_SQ_THROTTLE_CTRL__PWRBRK_STALL_EN__SHIFT)); | |
| 9230 | +} | |
| 9231 | + | |
| 9172 | 9232 | const struct amdgpu_ip_block_version gfx_v10_0_ip_block = |
| 9173 | 9233 | { |
| 9174 | 9234 | .type = AMD_IP_BLOCK_TYPE_GFX, |
| @@ -310,7 +310,7 @@ static void mmhub_v2_3_setup_vmid_config(struct amdgpu_device *adev) · 309 unmodified lines | ||
| 310 | 310 | /* Send no-retry XNACK on fault to suppress VM fault storm. */ |
| 311 | 311 | tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, |
| 312 | 312 | RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, |
| 313 | − !amdgpu_noretry); | |
| 313 | + !adev->gmc.noretry); | |
| 314 | 314 | WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_CNTL, |
| 315 | 315 | i * hub->ctx_distance, tmp); |
| 316 | 316 | WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32, |
| @@ -491,12 +491,11 @@ mmhub_v2_3_update_medium_grain_clock_gating(struct amdgpu_device *adev, · 174 unmodified lines | ||
| 491 | 491 | { |
| 492 | 492 | uint32_t def, data, def1, data1; |
| 493 | 493 | |
| 494 | − def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG); | |
| 494 | + def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL); | |
| 495 | 495 | def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2); |
| 496 | 496 | |
| 497 | 497 | if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_MGCG)) { |
| 498 | − data |= MM_ATC_L2_MISC_CG__ENABLE_MASK; | |
| 499 | − | |
| 498 | + data &= ~MM_ATC_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK; | |
| 500 | 499 | data1 &= ~(DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK | |
| 501 | 500 | DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK | |
| 502 | 501 | DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK | |
| @@ -505,8 +504,7 @@ mmhub_v2_3_update_medium_grain_clock_gating(struct amdgpu_device *adev, · 2 unmodified lines | ||
| 505 | 504 | DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK); |
| 506 | 505 | |
| 507 | 506 | } else { |
| 508 | − data &= ~MM_ATC_L2_MISC_CG__ENABLE_MASK; | |
| 509 | − | |
| 507 | + data |= MM_ATC_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK; | |
| 510 | 508 | data1 |= (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK | |
| 511 | 509 | DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK | |
| 512 | 510 | DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK | |
| @@ -516,7 +514,7 @@ mmhub_v2_3_update_medium_grain_clock_gating(struct amdgpu_device *adev, · 3 unmodified lines | ||
| 516 | 514 | } |
| 517 | 515 | |
| 518 | 516 | if (def != data) |
| 519 | − WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data); | |
| 517 | + WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL, data); | |
| 520 | 518 | if (def1 != data1) |
| 521 | 519 | WREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2, data1); |
| 522 | 520 | } |
| @@ -525,17 +523,44 @@ static void · 2 unmodified lines | ||
| 525 | 523 | mmhub_v2_3_update_medium_grain_light_sleep(struct amdgpu_device *adev, |
| 526 | 524 | bool enable) |
| 527 | 525 | { |
| 528 | − uint32_t def, data; | |
| 529 | − | |
| 530 | − def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG); | |
| 531 | − | |
| 532 | − if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_LS)) | |
| 533 | − data |= MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK; | |
| 534 | − else | |
| 535 | − data &= ~MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK; | |
| 526 | + uint32_t def, data, def1, data1, def2, data2; | |
| 527 | + | |
| 528 | + def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL); | |
| 529 | + def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_WR_CGTT_CLK_CTRL); | |
| 530 | + def2 = data2 = RREG32_SOC15(MMHUB, 0, mmDAGB0_RD_CGTT_CLK_CTRL); | |
| 531 | + | |
| 532 | + if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_LS)) { | |
| 533 | + data &= ~MM_ATC_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK; | |
| 534 | + data1 &= !(DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_MASK | | |
| 535 | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK | | |
| 536 | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK | | |
| 537 | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK | | |
| 538 | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK); | |
| 539 | + data2 &= !(DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_MASK | | |
| 540 | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK | | |
| 541 | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK | | |
| 542 | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK | | |
| 543 | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK); | |
| 544 | + } else { | |
| 545 | + data |= MM_ATC_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK; | |
| 546 | + data1 |= (DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_MASK | | |
| 547 | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK | | |
| 548 | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK | | |
| 549 | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK | | |
| 550 | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK); | |
| 551 | + data2 |= (DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_MASK | | |
| 552 | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK | | |
| 553 | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK | | |
| 554 | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK | | |
| 555 | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK); | |
| 556 | + } | |
| 536 | 557 | |
| 537 | 558 | if (def != data) |
| 538 | − WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data); | |
| 559 | + WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL, data); | |
| 560 | + if (def1 != data1) | |
| 561 | + WREG32_SOC15(MMHUB, 0, mmDAGB0_WR_CGTT_CLK_CTRL, data1); | |
| 562 | + if (def2 != data2) | |
| 563 | + WREG32_SOC15(MMHUB, 0, mmDAGB0_RD_CGTT_CLK_CTRL, data2); | |
| 539 | 564 | } |
| 540 | 565 | |
| 541 | 566 | static int mmhub_v2_3_set_clockgating(struct amdgpu_device *adev, |
| @@ -554,26 +579,39 @@ static int mmhub_v2_3_set_clockgating(struct amdgpu_device *adev, · 12 unmodified lines | ||
| 554 | 579 | |
| 555 | 580 | static void mmhub_v2_3_get_clockgating(struct amdgpu_device *adev, u32 *flags) |
| 556 | 581 | { |
| 557 | − int data, data1; | |
| 582 | + int data, data1, data2, data3; | |
| 558 | 583 | |
| 559 | 584 | if (amdgpu_sriov_vf(adev)) |
| 560 | 585 | *flags = 0; |
| 561 | 586 | |
| 562 | − data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG); | |
| 563 | − data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2); | |
| 587 | + data = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2); | |
| 588 | + data1 = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL); | |
| 589 | + data2 = RREG32_SOC15(MMHUB, 0, mmDAGB0_WR_CGTT_CLK_CTRL); | |
| 590 | + data3 = RREG32_SOC15(MMHUB, 0, mmDAGB0_RD_CGTT_CLK_CTRL); | |
| 564 | 591 | |
| 565 | 592 | /* AMD_CG_SUPPORT_MC_MGCG */ |
| 566 | − if ((data & MM_ATC_L2_MISC_CG__ENABLE_MASK) && | |
| 567 | − !(data1 & (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK | | |
| 593 | + if (!(data & (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK | | |
| 568 | 594 | DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK | |
| 569 | 595 | DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK | |
| 570 | 596 | DAGB0_CNTL_MISC2__DISABLE_RDRET_CG_MASK | |
| 571 | 597 | DAGB0_CNTL_MISC2__DISABLE_TLBWR_CG_MASK | |
| 572 | − DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK))) | |
| 573 | − *flags |= AMD_CG_SUPPORT_MC_MGCG; | |
| 598 | + DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK)) | |
| 599 | + && !(data1 & MM_ATC_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK)) { | |
| 600 | + *flags |= AMD_CG_SUPPORT_MC_MGCG; | |
| 601 | + } | |
| 574 | 602 | |
| 575 | 603 | /* AMD_CG_SUPPORT_MC_LS */ |
| 576 | − if (data & MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK) | |
| 604 | + if (!(data1 & MM_ATC_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK) | |
| 605 | + && !(data2 & (DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_MASK | | |
| 606 | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK | | |
| 607 | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK | | |
| 608 | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK | | |
| 609 | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK)) | |
| 610 | + && !(data3 & (DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_MASK | | |
| 611 | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK | | |
| 612 | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK | | |
| 613 | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK | | |
| 614 | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK))) | |
| 577 | 615 | *flags |= AMD_CG_SUPPORT_MC_LS; |
| 578 | 616 | } |
| 579 | 617 | |
| @@ -47,7 +47,7 @@ enum psp_gfx_crtl_cmd_id · 46 unmodified lines | ||
| 47 | 47 | GFX_CTRL_CMD_ID_DISABLE_INT = 0x00060000, /* disable PSP-to-Gfx interrupt */ |
| 48 | 48 | GFX_CTRL_CMD_ID_MODE1_RST = 0x00070000, /* trigger the Mode 1 reset */ |
| 49 | 49 | GFX_CTRL_CMD_ID_GBR_IH_SET = 0x00080000, /* set Gbr IH_RB_CNTL registers */ |
| 50 | − GFX_CTRL_CMD_ID_CONSUME_CMD = 0x000A0000, /* send interrupt to psp for updating write pointer of vf */ | |
| 50 | + GFX_CTRL_CMD_ID_CONSUME_CMD = 0x00090000, /* send interrupt to psp for updating write pointer of vf */ | |
| 51 | 51 | GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING = 0x000C0000, /* destroy GPCOM ring */ |
| 52 | 52 | |
| 53 | 53 | GFX_CTRL_CMD_ID_MAX = 0x000F0000, /* max command ID */ |
| @@ -1239,7 +1239,8 @@ static int soc15_common_early_init(void *handle) · 1238 unmodified lines | ||
| 1239 | 1239 | break; |
| 1240 | 1240 | case CHIP_RENOIR: |
| 1241 | 1241 | adev->asic_funcs = &soc15_asic_funcs; |
| 1242 | − if (adev->pdev->device == 0x1636) | |
| 1242 | + if ((adev->pdev->device == 0x1636) || | |
| 1243 | + (adev->pdev->device == 0x164c)) | |
| 1243 | 1244 | adev->apu_flags |= AMD_APU_IS_RENOIR; |
| 1244 | 1245 | else |
| 1245 | 1246 | adev->apu_flags |= AMD_APU_IS_GREEN_SARDINE; |
| @@ -1040,11 +1040,14 @@ static int kfd_create_vcrat_image_cpu(void *pcrat_image, size_t *size) · 1039 unmodified lines | ||
| 1040 | 1040 | (struct crat_subtype_iolink *)sub_type_hdr); |
| 1041 | 1041 | if (ret < 0) |
| 1042 | 1042 | return ret; |
| 1043 | − crat_table->length += (sub_type_hdr->length * entries); | |
| 1044 | − crat_table->total_entries += entries; | |
| 1045 | 1043 | |
| 1046 | − sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr + | |
| 1047 | − sub_type_hdr->length * entries); | |
| 1044 | + if (entries) { | |
| 1045 | + crat_table->length += (sub_type_hdr->length * entries); | |
| 1046 | + crat_table->total_entries += entries; | |
| 1047 | + | |
| 1048 | + sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr + | |
| 1049 | + sub_type_hdr->length * entries); | |
| 1050 | + } | |
| 1048 | 1051 | #else |
| 1049 | 1052 | pr_info("IO link not available for non x86 platforms\n"); |
| 1050 | 1053 | #endif |
| @@ -6,7 +6,7 @@ config DRM_AMD_DC · 5 unmodified lines | ||
| 6 | 6 | bool "AMD DC - Enable new display engine" |
| 7 | 7 | default y |
| 8 | 8 | select SND_HDA_COMPONENT if SND_HDA_CORE |
| 9 | − select DRM_AMD_DC_DCN if (X86 || PPC64 || (ARM64 && KERNEL_MODE_NEON)) && !(KCOV_INSTRUMENT_ALL && KCOV_ENABLE_COMPARISONS) | |
| 9 | + select DRM_AMD_DC_DCN if (X86 || PPC64) && !(KCOV_INSTRUMENT_ALL && KCOV_ENABLE_COMPARISONS) | |
| 10 | 10 | help |
| 11 | 11 | Choose this option if you want to use the new display engine |
| 12 | 12 | support for AMDGPU. This adds required support for Vega and |
| @@ -939,41 +939,6 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_ · 938 unmodified lines | ||
| 939 | 939 | } |
| 940 | 940 | #endif |
| 941 | 941 | |
| 942 | −#ifdef CONFIG_DEBUG_FS | |
| 943 | −static int create_crtc_crc_properties(struct amdgpu_display_manager *dm) | |
| 944 | −{ | |
| 945 | − dm->crc_win_x_start_property = | |
| 946 | − drm_property_create_range(adev_to_drm(dm->adev), | |
| 947 | − DRM_MODE_PROP_ATOMIC, | |
| 948 | − "AMD_CRC_WIN_X_START", 0, U16_MAX); | |
| 949 | − if (!dm->crc_win_x_start_property) | |
| 950 | − return -ENOMEM; | |
| 951 | − | |
| 952 | − dm->crc_win_y_start_property = | |
| 953 | − drm_property_create_range(adev_to_drm(dm->adev), | |
| 954 | − DRM_MODE_PROP_ATOMIC, | |
| 955 | − "AMD_CRC_WIN_Y_START", 0, U16_MAX); | |
| 956 | − if (!dm->crc_win_y_start_property) | |
| 957 | − return -ENOMEM; | |
| 958 | − | |
| 959 | − dm->crc_win_x_end_property = | |
| 960 | − drm_property_create_range(adev_to_drm(dm->adev), | |
| 961 | − DRM_MODE_PROP_ATOMIC, | |
| 962 | − "AMD_CRC_WIN_X_END", 0, U16_MAX); | |
| 963 | − if (!dm->crc_win_x_end_property) | |
| 964 | − return -ENOMEM; | |
| 965 | − | |
| 966 | − dm->crc_win_y_end_property = | |
| 967 | − drm_property_create_range(adev_to_drm(dm->adev), | |
| 968 | − DRM_MODE_PROP_ATOMIC, | |
| 969 | − "AMD_CRC_WIN_Y_END", 0, U16_MAX); | |
| 970 | − if (!dm->crc_win_y_end_property) | |
| 971 | − return -ENOMEM; | |
| 972 | − | |
| 973 | − return 0; | |
| 974 | −} | |
| 975 | −#endif | |
| 976 | − | |
| 977 | 942 | static int amdgpu_dm_init(struct amdgpu_device *adev) |
| 978 | 943 | { |
| 979 | 944 | struct dc_init_data init_data; |
| @@ -1120,10 +1085,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 140 unmodified lines | ||
| 1120 | 1085 | |
| 1121 | 1086 | dc_init_callbacks(adev->dm.dc, &init_params); |
| 1122 | 1087 | } |
| 1123 | −#endif | |
| 1124 | −#ifdef CONFIG_DEBUG_FS | |
| 1125 | − if (create_crtc_crc_properties(&adev->dm)) | |
| 1126 | − DRM_ERROR("amdgpu: failed to create crc property.\n"); | |
| 1127 | 1088 | #endif |
| 1128 | 1089 | if (amdgpu_dm_initialize_drm_device(adev)) { |
| 1129 | 1090 | DRM_ERROR( |
| @@ -1872,8 +1833,8 @@ static void emulated_link_detect(struct dc_link *link) · 742 unmodified lines | ||
| 1872 | 1833 | link->type = dc_connection_none; |
| 1873 | 1834 | prev_sink = link->local_sink; |
| 1874 | 1835 | |
| 1875 | − if (prev_sink != NULL) | |
| 1876 | − dc_sink_retain(prev_sink); | |
| 1836 | + if (prev_sink) | |
| 1837 | + dc_sink_release(prev_sink); | |
| 1877 | 1838 | |
| 1878 | 1839 | switch (link->connector_signal) { |
| 1879 | 1840 | case SIGNAL_TYPE_HDMI_TYPE_A: { |
| @@ -1973,7 +1934,7 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state, · 93 unmodified lines | ||
| 1973 | 1934 | dc_commit_updates_for_stream( |
| 1974 | 1935 | dm->dc, bundle->surface_updates, |
| 1975 | 1936 | dc_state->stream_status->plane_count, |
| 1976 | − dc_state->streams[k], &bundle->stream_update, dc_state); | |
| 1937 | + dc_state->streams[k], &bundle->stream_update); | |
| 1977 | 1938 | } |
| 1978 | 1939 | |
| 1979 | 1940 | cleanup: |
| @@ -2004,8 +1965,7 @@ static void dm_set_dpms_off(struct dc_link *link) · 24 unmodified lines | ||
| 2004 | 1965 | |
| 2005 | 1966 | stream_update.stream = stream_state; |
| 2006 | 1967 | dc_commit_updates_for_stream(stream_state->ctx->dc, NULL, 0, |
| 2007 | − stream_state, &stream_update, | |
| 2008 | − stream_state->ctx->dc->current_state); | |
| 1968 | + stream_state, &stream_update); | |
| 2009 | 1969 | mutex_unlock(&adev->dm.dc_lock); |
| 2010 | 1970 | } |
| 2011 | 1971 | |
| @@ -2369,8 +2329,10 @@ void amdgpu_dm_update_connector_after_detect( · 357 unmodified lines | ||
| 2369 | 2329 | * TODO: check if we still need the S3 mode update workaround. |
| 2370 | 2330 | * If yes, put it here. |
| 2371 | 2331 | */ |
| 2372 | − if (aconnector->dc_sink) | |
| 2332 | + if (aconnector->dc_sink) { | |
| 2373 | 2333 | amdgpu_dm_update_freesync_caps(connector, NULL); |
| 2334 | + dc_sink_release(aconnector->dc_sink); | |
| 2335 | + } | |
| 2374 | 2336 | |
| 2375 | 2337 | aconnector->dc_sink = sink; |
| 2376 | 2338 | dc_sink_retain(aconnector->dc_sink); |
| @@ -2386,9 +2348,6 @@ void amdgpu_dm_update_connector_after_detect( · 9 unmodified lines | ||
| 2386 | 2348 | |
| 2387 | 2349 | drm_connector_update_edid_property(connector, |
| 2388 | 2350 | aconnector->edid); |
| 2389 | − aconnector->num_modes = drm_add_edid_modes(connector, aconnector->edid); | |
| 2390 | − drm_connector_list_update(connector); | |
| 2391 | − | |
| 2392 | 2351 | if (aconnector->dc_link->aux_mode) |
| 2393 | 2352 | drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux, |
| 2394 | 2353 | aconnector->edid); |
| @@ -5334,64 +5293,12 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc) · 2939 unmodified lines | ||
| 5334 | 5293 | state->crc_src = cur->crc_src; |
| 5335 | 5294 | state->cm_has_degamma = cur->cm_has_degamma; |
| 5336 | 5295 | state->cm_is_degamma_srgb = cur->cm_is_degamma_srgb; |
| 5337 | −#ifdef CONFIG_DEBUG_FS | |
| 5338 | − state->crc_window = cur->crc_window; | |
| 5339 | −#endif | |
| 5296 | + | |
| 5340 | 5297 | /* TODO Duplicate dc_stream after objects are stream object is flattened */ |
| 5341 | 5298 | |
| 5342 | 5299 | return &state->base; |
| 5343 | 5300 | } |
| 5344 | 5301 | |
| 5345 | −#ifdef CONFIG_DEBUG_FS | |
| 5346 | −static int amdgpu_dm_crtc_atomic_set_property(struct drm_crtc *crtc, | |
| 5347 | − struct drm_crtc_state *crtc_state, | |
| 5348 | − struct drm_property *property, | |
| 5349 | − uint64_t val) | |
| 5350 | −{ | |
| 5351 | − struct drm_device *dev = crtc->dev; | |
| 5352 | − struct amdgpu_device *adev = drm_to_adev(dev); | |
| 5353 | − struct dm_crtc_state *dm_new_state = | |
| 5354 | − to_dm_crtc_state(crtc_state); | |
| 5355 | − | |
| 5356 | − if (property == adev->dm.crc_win_x_start_property) | |
| 5357 | − dm_new_state->crc_window.x_start = val; | |
| 5358 | − else if (property == adev->dm.crc_win_y_start_property) | |
| 5359 | − dm_new_state->crc_window.y_start = val; | |
| 5360 | − else if (property == adev->dm.crc_win_x_end_property) | |
| 5361 | − dm_new_state->crc_window.x_end = val; | |
| 5362 | − else if (property == adev->dm.crc_win_y_end_property) | |
| 5363 | − dm_new_state->crc_window.y_end = val; | |
| 5364 | − else | |
| 5365 | − return -EINVAL; | |
| 5366 | − | |
| 5367 | − return 0; | |
| 5368 | −} | |
| 5369 | − | |
| 5370 | −static int amdgpu_dm_crtc_atomic_get_property(struct drm_crtc *crtc, | |
| 5371 | − const struct drm_crtc_state *state, | |
| 5372 | − struct drm_property *property, | |
| 5373 | − uint64_t *val) | |
| 5374 | −{ | |
| 5375 | − struct drm_device *dev = crtc->dev; | |
| 5376 | − struct amdgpu_device *adev = drm_to_adev(dev); | |
| 5377 | − struct dm_crtc_state *dm_state = | |
| 5378 | − to_dm_crtc_state(state); | |
| 5379 | − | |
| 5380 | − if (property == adev->dm.crc_win_x_start_property) | |
| 5381 | − *val = dm_state->crc_window.x_start; | |
| 5382 | − else if (property == adev->dm.crc_win_y_start_property) | |
| 5383 | − *val = dm_state->crc_window.y_start; | |
| 5384 | − else if (property == adev->dm.crc_win_x_end_property) | |
| 5385 | − *val = dm_state->crc_window.x_end; | |
| 5386 | − else if (property == adev->dm.crc_win_y_end_property) | |
| 5387 | − *val = dm_state->crc_window.y_end; | |
| 5388 | − else | |
| 5389 | − return -EINVAL; | |
| 5390 | − | |
| 5391 | − return 0; | |
| 5392 | −} | |
| 5393 | −#endif | |
| 5394 | − | |
| 5395 | 5302 | static inline int dm_set_vupdate_irq(struct drm_crtc *crtc, bool enable) |
| 5396 | 5303 | { |
| 5397 | 5304 | enum dc_irq_source irq_source; |
| @@ -5458,10 +5365,6 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { · 60 unmodified lines | ||
| 5458 | 5365 | .enable_vblank = dm_enable_vblank, |
| 5459 | 5366 | .disable_vblank = dm_disable_vblank, |
| 5460 | 5367 | .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp, |
| 5461 | −#ifdef CONFIG_DEBUG_FS | |
| 5462 | − .atomic_set_property = amdgpu_dm_crtc_atomic_set_property, | |
| 5463 | − .atomic_get_property = amdgpu_dm_crtc_atomic_get_property, | |
| 5464 | −#endif | |
| 5465 | 5368 | }; |
| 5466 | 5369 | |
| 5467 | 5370 | static enum drm_connector_status |
| @@ -6663,25 +6566,6 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, · 1195 unmodified lines | ||
| 6663 | 6566 | return 0; |
| 6664 | 6567 | } |
| 6665 | 6568 | |
| 6666 | −#ifdef CONFIG_DEBUG_FS | |
| 6667 | −static void attach_crtc_crc_properties(struct amdgpu_display_manager *dm, | |
| 6668 | − struct amdgpu_crtc *acrtc) | |
| 6669 | −{ | |
| 6670 | − drm_object_attach_property(&acrtc->base.base, | |
| 6671 | − dm->crc_win_x_start_property, | |
| 6672 | − 0); | |
| 6673 | − drm_object_attach_property(&acrtc->base.base, | |
| 6674 | − dm->crc_win_y_start_property, | |
| 6675 | − 0); | |
| 6676 | − drm_object_attach_property(&acrtc->base.base, | |
| 6677 | − dm->crc_win_x_end_property, | |
| 6678 | − 0); | |
| 6679 | − drm_object_attach_property(&acrtc->base.base, | |
| 6680 | − dm->crc_win_y_end_property, | |
| 6681 | − 0); | |
| 6682 | −} | |
| 6683 | −#endif | |
| 6684 | − | |
| 6685 | 6569 | static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, |
| 6686 | 6570 | struct drm_plane *plane, |
| 6687 | 6571 | uint32_t crtc_index) |
| @@ -6729,9 +6613,7 @@ static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, · 41 unmodified lines | ||
| 6729 | 6613 | drm_crtc_enable_color_mgmt(&acrtc->base, MAX_COLOR_LUT_ENTRIES, |
| 6730 | 6614 | true, MAX_COLOR_LUT_ENTRIES); |
| 6731 | 6615 | drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES); |
| 6732 | −#ifdef CONFIG_DEBUG_FS | |
| 6733 | − attach_crtc_crc_properties(dm, acrtc); | |
| 6734 | −#endif | |
| 6616 | + | |
| 6735 | 6617 | return 0; |
| 6736 | 6618 | |
| 6737 | 6619 | fail: |
| @@ -7666,7 +7548,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, · 928 unmodified lines | ||
| 7666 | 7548 | struct drm_crtc *pcrtc, |
| 7667 | 7549 | bool wait_for_vblank) |
| 7668 | 7550 | { |
| 7669 | − uint32_t i; | |
| 7551 | + int i; | |
| 7670 | 7552 | uint64_t timestamp_ns; |
| 7671 | 7553 | struct drm_plane *plane; |
| 7672 | 7554 | struct drm_plane_state *old_plane_state, *new_plane_state; |
| @@ -7707,7 +7589,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, · 34 unmodified lines | ||
| 7707 | 7589 | amdgpu_dm_commit_cursors(state); |
| 7708 | 7590 | |
| 7709 | 7591 | /* update planes when needed */ |
| 7710 | − for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { | |
| 7592 | + for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) { | |
| 7711 | 7593 | struct drm_crtc *crtc = new_plane_state->crtc; |
| 7712 | 7594 | struct drm_crtc_state *new_crtc_state; |
| 7713 | 7595 | struct drm_framebuffer *fb = new_plane_state->fb; |
| @@ -7930,8 +7812,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, · 216 unmodified lines | ||
| 7930 | 7812 | bundle->surface_updates, |
| 7931 | 7813 | planes_count, |
| 7932 | 7814 | acrtc_state->stream, |
| 7933 | − &bundle->stream_update, | |
| 7934 | − dc_state); | |
| 7815 | + &bundle->stream_update); | |
| 7935 | 7816 | |
| 7936 | 7817 | /** |
| 7937 | 7818 | * Enable or disable the interrupts on the backend. |
| @@ -8267,13 +8148,13 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 329 unmodified lines | ||
| 8267 | 8148 | struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state); |
| 8268 | 8149 | struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state); |
| 8269 | 8150 | struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); |
| 8270 | − struct dc_surface_update dummy_updates[MAX_SURFACES]; | |
| 8151 | + struct dc_surface_update surface_updates[MAX_SURFACES]; | |
| 8271 | 8152 | struct dc_stream_update stream_update; |
| 8272 | 8153 | struct dc_info_packet hdr_packet; |
| 8273 | 8154 | struct dc_stream_status *status = NULL; |
| 8274 | 8155 | bool abm_changed, hdr_changed, scaling_changed; |
| 8275 | 8156 | |
| 8276 | − memset(&dummy_updates, 0, sizeof(dummy_updates)); | |
| 8157 | + memset(&surface_updates, 0, sizeof(surface_updates)); | |
| 8277 | 8158 | memset(&stream_update, 0, sizeof(stream_update)); |
| 8278 | 8159 | |
| 8279 | 8160 | if (acrtc) { |
| @@ -8330,16 +8211,15 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 50 unmodified lines | ||
| 8330 | 8211 | * To fix this, DC should permit updating only stream properties. |
| 8331 | 8212 | */ |
| 8332 | 8213 | for (j = 0; j < status->plane_count; j++) |
| 8333 | − dummy_updates[j].surface = status->plane_states[0]; | |
| 8214 | + surface_updates[j].surface = status->plane_states[j]; | |
| 8334 | 8215 | |
| 8335 | 8216 | |
| 8336 | 8217 | mutex_lock(&dm->dc_lock); |
| 8337 | 8218 | dc_commit_updates_for_stream(dm->dc, |
| 8338 | − dummy_updates, | |
| 8219 | + surface_updates, | |
| 8339 | 8220 | status->plane_count, |
| 8340 | 8221 | dm_new_crtc_state->stream, |
| 8341 | − &stream_update, | |
| 8342 | − dc_state); | |
| 8222 | + &stream_update); | |
| 8343 | 8223 | mutex_unlock(&dm->dc_lock); |
| 8344 | 8224 | } |
| 8345 | 8225 | |
| @@ -8368,7 +8248,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 22 unmodified lines | ||
| 8368 | 8248 | */ |
| 8369 | 8249 | for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { |
| 8370 | 8250 | struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); |
| 8371 | − bool configure_crc = false; | |
| 8372 | 8251 | |
| 8373 | 8252 | dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); |
| 8374 | 8253 | |
| @@ -8378,30 +8257,21 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 3 unmodified lines | ||
| 8378 | 8257 | dc_stream_retain(dm_new_crtc_state->stream); |
| 8379 | 8258 | acrtc->dm_irq_params.stream = dm_new_crtc_state->stream; |
| 8380 | 8259 | manage_dm_interrupts(adev, acrtc, true); |
| 8381 | − } | |
| 8260 | + | |
| 8382 | 8261 | #ifdef CONFIG_DEBUG_FS |
| 8383 | − if (new_crtc_state->active && | |
| 8384 | − amdgpu_dm_is_valid_crc_source(dm_new_crtc_state->crc_src)) { | |
| 8385 | 8262 | /** |
| 8386 | 8263 | * Frontend may have changed so reapply the CRC capture |
| 8387 | 8264 | * settings for the stream. |
| 8388 | 8265 | */ |
| 8389 | 8266 | dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); |
| 8390 | − dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); | |
| 8391 | − | |
| 8392 | − if (amdgpu_dm_crc_window_is_default(dm_new_crtc_state)) { | |
| 8393 | − if (!old_crtc_state->active || drm_atomic_crtc_needs_modeset(new_crtc_state)) | |
| 8394 | − configure_crc = true; | |
| 8395 | − } else { | |
| 8396 | − if (amdgpu_dm_crc_window_changed(dm_new_crtc_state, dm_old_crtc_state)) | |
| 8397 | − configure_crc = true; | |
| 8398 | − } | |
| 8399 | 8267 | |
| 8400 | − if (configure_crc) | |
| 8268 | + if (amdgpu_dm_is_valid_crc_source(dm_new_crtc_state->crc_src)) { | |
| 8401 | 8269 | amdgpu_dm_crtc_configure_crc_source( |
| 8402 | − crtc, dm_new_crtc_state, dm_new_crtc_state->crc_src); | |
| 8403 | − } | |
| 8270 | + crtc, dm_new_crtc_state, | |
| 8271 | + dm_new_crtc_state->crc_src); | |
| 8272 | + } | |
| 8404 | 8273 | #endif |
| 8274 | + } | |
| 8405 | 8275 | } |
| 8406 | 8276 | |
| 8407 | 8277 | for_each_new_crtc_in_state(state, crtc, new_crtc_state, j) |
| @@ -8486,14 +8356,14 @@ static int dm_force_atomic_commit(struct drm_connector *connector) · 78 unmodified lines | ||
| 8486 | 8356 | |
| 8487 | 8357 | ret = PTR_ERR_OR_ZERO(conn_state); |
| 8488 | 8358 | if (ret) |
| 8489 | − goto err; | |
| 8359 | + goto out; | |
| 8490 | 8360 | |
| 8491 | 8361 | /* Attach crtc to drm_atomic_state*/ |
| 8492 | 8362 | crtc_state = drm_atomic_get_crtc_state(state, &disconnected_acrtc->base); |
| 8493 | 8363 | |
| 8494 | 8364 | ret = PTR_ERR_OR_ZERO(crtc_state); |
| 8495 | 8365 | if (ret) |
| 8496 | − goto err; | |
| 8366 | + goto out; | |
| 8497 | 8367 | |
| 8498 | 8368 | /* force a restore */ |
| 8499 | 8369 | crtc_state->mode_changed = true; |
| @@ -8503,17 +8373,15 @@ static int dm_force_atomic_commit(struct drm_connector *connector) · 3 unmodified lines | ||
| 8503 | 8373 | |
| 8504 | 8374 | ret = PTR_ERR_OR_ZERO(plane_state); |
| 8505 | 8375 | if (ret) |
| 8506 | − goto err; | |
| 8507 | − | |
| 8376 | + goto out; | |
| 8508 | 8377 | |
| 8509 | 8378 | /* Call commit internally with the state we just constructed */ |
| 8510 | 8379 | ret = drm_atomic_commit(state); |
| 8511 | − if (!ret) | |
| 8512 | − return 0; | |
| 8513 | 8380 | |
| 8514 | −err: | |
| 8515 | − DRM_ERROR("Restoring old state failed with %i\n", ret); | |
| 8381 | +out: | |
| 8516 | 8382 | drm_atomic_state_put(state); |
| 8383 | + if (ret) | |
| 8384 | + DRM_ERROR("Restoring old state failed with %i\n", ret); | |
| 8517 | 8385 | |
| 8518 | 8386 | return ret; |
| 8519 | 8387 | } |
| @@ -336,32 +336,6 @@ struct amdgpu_display_manager { · 335 unmodified lines | ||
| 336 | 336 | */ |
| 337 | 337 | const struct gpu_info_soc_bounding_box_v1_0 *soc_bounding_box; |
| 338 | 338 | |
| 339 | −#ifdef CONFIG_DEBUG_FS | |
| 340 | − /** | |
| 341 | − * @crc_win_x_start_property: | |
| 342 | − * | |
| 343 | − * X start of the crc calculation window | |
| 344 | − */ | |
| 345 | − struct drm_property *crc_win_x_start_property; | |
| 346 | − /** | |
| 347 | − * @crc_win_y_start_property: | |
| 348 | − * | |
| 349 | − * Y start of the crc calculation window | |
| 350 | − */ | |
| 351 | − struct drm_property *crc_win_y_start_property; | |
| 352 | − /** | |
| 353 | − * @crc_win_x_end_property: | |
| 354 | − * | |
| 355 | − * X end of the crc calculation window | |
| 356 | − */ | |
| 357 | − struct drm_property *crc_win_x_end_property; | |
| 358 | − /** | |
| 359 | − * @crc_win_y_end_property: | |
| 360 | − * | |
| 361 | − * Y end of the crc calculation window | |
| 362 | − */ | |
| 363 | − struct drm_property *crc_win_y_end_property; | |
| 364 | −#endif | |
| 365 | 339 | /** |
| 366 | 340 | * @mst_encoders: |
| 367 | 341 | * |
| @@ -448,15 +422,6 @@ struct dm_plane_state { · 80 unmodified lines | ||
| 448 | 422 | struct dc_plane_state *dc_state; |
| 449 | 423 | }; |
| 450 | 424 | |
| 451 | −#ifdef CONFIG_DEBUG_FS | |
| 452 | −struct crc_rec { | |
| 453 | − uint16_t x_start; | |
| 454 | − uint16_t y_start; | |
| 455 | − uint16_t x_end; | |
| 456 | − uint16_t y_end; | |
| 457 | − }; | |
| 458 | −#endif | |
| 459 | − | |
| 460 | 425 | struct dm_crtc_state { |
| 461 | 426 | struct drm_crtc_state base; |
| 462 | 427 | struct dc_stream_state *stream; |
| @@ -479,9 +444,6 @@ struct dm_crtc_state { · 16 unmodified lines | ||
| 479 | 444 | struct dc_info_packet vrr_infopacket; |
| 480 | 445 | |
| 481 | 446 | int abm_level; |
| 482 | −#ifdef CONFIG_DEBUG_FS | |
| 483 | − struct crc_rec crc_window; | |
| 484 | −#endif | |
| 485 | 447 | }; |
| 486 | 448 | |
| 487 | 449 | #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base) |
| @@ -81,41 +81,6 @@ const char *const *amdgpu_dm_crtc_get_crc_sources(struct drm_crtc *crtc, · 80 unmodified lines | ||
| 81 | 81 | return pipe_crc_sources; |
| 82 | 82 | } |
| 83 | 83 | |
| 84 | −static void amdgpu_dm_set_crc_window_default(struct dm_crtc_state *dm_crtc_state) | |
| 85 | −{ | |
| 86 | − dm_crtc_state->crc_window.x_start = 0; | |
| 87 | − dm_crtc_state->crc_window.y_start = 0; | |
| 88 | − dm_crtc_state->crc_window.x_end = 0; | |
| 89 | − dm_crtc_state->crc_window.y_end = 0; | |
| 90 | −} | |
| 91 | − | |
| 92 | −bool amdgpu_dm_crc_window_is_default(struct dm_crtc_state *dm_crtc_state) | |
| 93 | −{ | |
| 94 | − bool ret = true; | |
| 95 | − | |
| 96 | − if ((dm_crtc_state->crc_window.x_start != 0) || | |
| 97 | − (dm_crtc_state->crc_window.y_start != 0) || | |
| 98 | − (dm_crtc_state->crc_window.x_end != 0) || | |
| 99 | − (dm_crtc_state->crc_window.y_end != 0)) | |
| 100 | − ret = false; | |
| 101 | − | |
| 102 | − return ret; | |
| 103 | −} | |
| 104 | − | |
| 105 | −bool amdgpu_dm_crc_window_changed(struct dm_crtc_state *dm_new_crtc_state, | |
| 106 | − struct dm_crtc_state *dm_old_crtc_state) | |
| 107 | −{ | |
| 108 | − bool ret = false; | |
| 109 | − | |
| 110 | − if ((dm_new_crtc_state->crc_window.x_start != dm_old_crtc_state->crc_window.x_start) || | |
| 111 | − (dm_new_crtc_state->crc_window.y_start != dm_old_crtc_state->crc_window.y_start) || | |
| 112 | − (dm_new_crtc_state->crc_window.x_end != dm_old_crtc_state->crc_window.x_end) || | |
| 113 | − (dm_new_crtc_state->crc_window.y_end != dm_old_crtc_state->crc_window.y_end)) | |
| 114 | − ret = true; | |
| 115 | − | |
| 116 | − return ret; | |
| 117 | −} | |
| 118 | − | |
| 119 | 84 | int |
| 120 | 85 | amdgpu_dm_crtc_verify_crc_source(struct drm_crtc *crtc, const char *src_name, |
| 121 | 86 | size_t *values_cnt) |
| @@ -140,7 +105,6 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, · 18 unmodified lines | ||
| 140 | 105 | struct dc_stream_state *stream_state = dm_crtc_state->stream; |
| 141 | 106 | bool enable = amdgpu_dm_is_valid_crc_source(source); |
| 142 | 107 | int ret = 0; |
| 143 | − struct crc_params *crc_window = NULL, tmp_window; | |
| 144 | 108 | |
| 145 | 109 | /* Configuration will be deferred to stream enable. */ |
| 146 | 110 | if (!stream_state) |
| @@ -150,24 +114,8 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, · 3 unmodified lines | ||
| 150 | 114 | |
| 151 | 115 | /* Enable CRTC CRC generation if necessary. */ |
| 152 | 116 | if (dm_is_crc_source_crtc(source) || source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE) { |
| 153 | − if (!enable) | |
| 154 | − amdgpu_dm_set_crc_window_default(dm_crtc_state); | |
| 155 | − | |
| 156 | − if (!amdgpu_dm_crc_window_is_default(dm_crtc_state)) { | |
| 157 | − crc_window = &tmp_window; | |
| 158 | − | |
| 159 | − tmp_window.windowa_x_start = dm_crtc_state->crc_window.x_start; | |
| 160 | − tmp_window.windowa_y_start = dm_crtc_state->crc_window.y_start; | |
| 161 | − tmp_window.windowa_x_end = dm_crtc_state->crc_window.x_end; | |
| 162 | − tmp_window.windowa_y_end = dm_crtc_state->crc_window.y_end; | |
| 163 | − tmp_window.windowb_x_start = dm_crtc_state->crc_window.x_start; | |
| 164 | − tmp_window.windowb_y_start = dm_crtc_state->crc_window.y_start; | |
| 165 | − tmp_window.windowb_x_end = dm_crtc_state->crc_window.x_end; | |
| 166 | − tmp_window.windowb_y_end = dm_crtc_state->crc_window.y_end; | |
| 167 | − } | |
| 168 | − | |
| 169 | 117 | if (!dc_stream_configure_crc(stream_state->ctx->dc, |
| 170 | − stream_state, crc_window, enable, enable)) { | |
| 118 | + stream_state, NULL, enable, enable)) { | |
| 171 | 119 | ret = -EINVAL; |
| 172 | 120 | goto unlock; |
| 173 | 121 | } |
| @@ -47,9 +47,6 @@ static inline bool amdgpu_dm_is_valid_crc_source(enum amdgpu_dm_pipe_crc_source · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | /* amdgpu_dm_crc.c */ |
| 49 | 49 | #ifdef CONFIG_DEBUG_FS |
| 50 | −bool amdgpu_dm_crc_window_is_default(struct dm_crtc_state *dm_crtc_state); | |
| 51 | −bool amdgpu_dm_crc_window_changed(struct dm_crtc_state *dm_new_crtc_state, | |
| 52 | − struct dm_crtc_state *dm_old_crtc_state); | |
| 53 | 50 | int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, |
| 54 | 51 | struct dm_crtc_state *dm_crtc_state, |
| 55 | 52 | enum amdgpu_dm_pipe_crc_source source); |
| @@ -833,6 +833,9 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, · 832 unmodified lines | ||
| 833 | 833 | if (computed_streams[i]) |
| 834 | 834 | continue; |
| 835 | 835 | |
| 836 | + if (dcn20_remove_stream_from_ctx(stream->ctx->dc, dc_state, stream) != DC_OK) | |
| 837 | + return false; | |
| 838 | + | |
| 836 | 839 | mutex_lock(&aconnector->mst_mgr.lock); |
| 837 | 840 | if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link)) { |
| 838 | 841 | mutex_unlock(&aconnector->mst_mgr.lock); |
| @@ -850,7 +853,8 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, · 11 unmodified lines | ||
| 850 | 853 | stream = dc_state->streams[i]; |
| 851 | 854 | |
| 852 | 855 | if (stream->timing.flags.DSC == 1) |
| 853 | − dc_stream_add_dsc_to_resource(stream->ctx->dc, dc_state, stream); | |
| 856 | + if (dc_stream_add_dsc_to_resource(stream->ctx->dc, dc_state, stream) != DC_OK) | |
| 857 | + return false; | |
| 854 | 858 | } |
| 855 | 859 | |
| 856 | 860 | return true; |
| @@ -33,10 +33,6 @@ ifdef CONFIG_PPC64 · 32 unmodified lines | ||
| 33 | 33 | calcs_ccflags := -mhard-float -maltivec |
| 34 | 34 | endif |
| 35 | 35 | |
| 36 | −ifdef CONFIG_ARM64 | |
| 37 | −calcs_rcflags := -mgeneral-regs-only | |
| 38 | −endif | |
| 39 | − | |
| 40 | 36 | ifdef CONFIG_CC_IS_GCC |
| 41 | 37 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 42 | 38 | IS_OLD_GCC = 1 |
| @@ -104,13 +104,6 @@ ifdef CONFIG_PPC64 · 103 unmodified lines | ||
| 104 | 104 | CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn21/rn_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) |
| 105 | 105 | endif |
| 106 | 106 | |
| 107 | −# prevent build errors: | |
| 108 | −# ...: '-mgeneral-regs-only' is incompatible with the use of floating-point types | |
| 109 | −# this file is unused on arm64, just like on ppc64 | |
| 110 | −ifdef CONFIG_ARM64 | |
| 111 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/clk_mgr/dcn21/rn_clk_mgr.o := -mgeneral-regs-only | |
| 112 | −endif | |
| 113 | − | |
| 114 | 107 | AMD_DAL_CLK_MGR_DCN21 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn21/,$(CLK_MGR_DCN21)) |
| 115 | 108 | |
| 116 | 109 | AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21) |
| @@ -125,13 +118,6 @@ ifdef CONFIG_PPC64 · 8 unmodified lines | ||
| 125 | 118 | CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn30/dcn30_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) |
| 126 | 119 | endif |
| 127 | 120 | |
| 128 | −# prevent build errors: | |
| 129 | −# ...: '-mgeneral-regs-only' is incompatible with the use of floating-point types | |
| 130 | −# this file is unused on arm64, just like on ppc64 | |
| 131 | −ifdef CONFIG_ARM64 | |
| 132 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/clk_mgr/dcn30/dcn30_clk_mgr.o := -mgeneral-regs-only | |
| 133 | −endif | |
| 134 | − | |
| 135 | 121 | AMD_DAL_CLK_MGR_DCN30 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn30/,$(CLK_MGR_DCN30)) |
| 136 | 122 | |
| 137 | 123 | AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN30) |
| @@ -146,13 +132,6 @@ ifdef CONFIG_PPC64 · 8 unmodified lines | ||
| 146 | 132 | CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn301/vg_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) |
| 147 | 133 | endif |
| 148 | 134 | |
| 149 | −# prevent build errors: | |
| 150 | −# ...: '-mgeneral-regs-only' is incompatible with the use of floating-point types | |
| 151 | −# this file is unused on arm64, just like on ppc64 | |
| 152 | −ifdef CONFIG_ARM64 | |
| 153 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/clk_mgr/dcn301/vg_clk_mgr.o := -mgeneral-regs-only | |
| 154 | −endif | |
| 155 | − | |
| 156 | 135 | AMD_DAL_CLK_MGR_DCN301 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn301/,$(CLK_MGR_DCN301)) |
| 157 | 136 | |
| 158 | 137 | AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN301) |
| @@ -251,6 +251,7 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base, · 250 unmodified lines | ||
| 251 | 251 | struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu; |
| 252 | 252 | bool force_reset = false; |
| 253 | 253 | bool update_uclk = false; |
| 254 | + bool p_state_change_support; | |
| 254 | 255 | |
| 255 | 256 | if (dc->work_arounds.skip_clock_update || !clk_mgr->smu_present) |
| 256 | 257 | return; |
| @@ -291,8 +292,9 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base, · 34 unmodified lines | ||
| 291 | 292 | clk_mgr_base->clks.socclk_khz = new_clocks->socclk_khz; |
| 292 | 293 | |
| 293 | 294 | clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support; |
| 294 | − if (should_update_pstate_support(safe_to_lower, new_clocks->p_state_change_support, clk_mgr_base->clks.p_state_change_support)) { | |
| 295 | − clk_mgr_base->clks.p_state_change_support = new_clocks->p_state_change_support; | |
| 295 | + p_state_change_support = new_clocks->p_state_change_support || (display_count == 0); | |
| 296 | + if (should_update_pstate_support(safe_to_lower, p_state_change_support, clk_mgr_base->clks.p_state_change_support)) { | |
| 297 | + clk_mgr_base->clks.p_state_change_support = p_state_change_support; | |
| 296 | 298 | |
| 297 | 299 | /* to disable P-State switching, set UCLK min = max */ |
| 298 | 300 | if (!clk_mgr_base->clks.p_state_change_support) |
| @@ -2679,8 +2679,7 @@ void dc_commit_updates_for_stream(struct dc *dc, · 2678 unmodified lines | ||
| 2679 | 2679 | struct dc_surface_update *srf_updates, |
| 2680 | 2680 | int surface_count, |
| 2681 | 2681 | struct dc_stream_state *stream, |
| 2682 | − struct dc_stream_update *stream_update, | |
| 2683 | − struct dc_state *state) | |
| 2682 | + struct dc_stream_update *stream_update) | |
| 2684 | 2683 | { |
| 2685 | 2684 | const struct dc_stream_status *stream_status; |
| 2686 | 2685 | enum surface_update_type update_type; |
| @@ -2699,6 +2698,12 @@ void dc_commit_updates_for_stream(struct dc *dc, · 12 unmodified lines | ||
| 2699 | 2698 | |
| 2700 | 2699 | |
| 2701 | 2700 | if (update_type >= UPDATE_TYPE_FULL) { |
| 2701 | + struct dc_plane_state *new_planes[MAX_SURFACES]; | |
| 2702 | + | |
| 2703 | + memset(new_planes, 0, sizeof(new_planes)); | |
| 2704 | + | |
| 2705 | + for (i = 0; i < surface_count; i++) | |
| 2706 | + new_planes[i] = srf_updates[i].surface; | |
| 2702 | 2707 | |
| 2703 | 2708 | /* initialize scratch memory for building context */ |
| 2704 | 2709 | context = dc_create_state(dc); |
| @@ -2707,15 +2712,21 @@ void dc_commit_updates_for_stream(struct dc *dc, · 2 unmodified lines | ||
| 2707 | 2712 | return; |
| 2708 | 2713 | } |
| 2709 | 2714 | |
| 2710 | − dc_resource_state_copy_construct(state, context); | |
| 2715 | + dc_resource_state_copy_construct( | |
| 2716 | + dc->current_state, context); | |
| 2711 | 2717 | |
| 2712 | − for (i = 0; i < dc->res_pool->pipe_count; i++) { | |
| 2713 | − struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i]; | |
| 2714 | − struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; | |
| 2718 | + /*remove old surfaces from context */ | |
| 2719 | + if (!dc_rem_all_planes_for_stream(dc, stream, context)) { | |
| 2720 | + DC_ERROR("Failed to remove streams for new validate context!\n"); | |
| 2721 | + return; | |
| 2722 | + } | |
| 2715 | 2723 | |
| 2716 | − if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state) | |
| 2717 | − new_pipe->plane_state->force_full_update = true; | |
| 2724 | + /* add surface to context */ | |
| 2725 | + if (!dc_add_all_planes_for_stream(dc, stream, new_planes, surface_count, context)) { | |
| 2726 | + DC_ERROR("Failed to add streams for new validate context!\n"); | |
| 2727 | + return; | |
| 2718 | 2728 | } |
| 2729 | + | |
| 2719 | 2730 | } |
| 2720 | 2731 | |
| 2721 | 2732 | |
| @@ -2487,9 +2487,14 @@ enum dc_status dc_link_validate_mode_timing( · 2486 unmodified lines | ||
| 2487 | 2487 | static struct abm *get_abm_from_stream_res(const struct dc_link *link) |
| 2488 | 2488 | { |
| 2489 | 2489 | int i; |
| 2490 | − struct dc *dc = link->ctx->dc; | |
| 2490 | + struct dc *dc = NULL; | |
| 2491 | 2491 | struct abm *abm = NULL; |
| 2492 | 2492 | |
| 2493 | + if (!link || !link->ctx) | |
| 2494 | + return NULL; | |
| 2495 | + | |
| 2496 | + dc = link->ctx->dc; | |
| 2497 | + | |
| 2493 | 2498 | for (i = 0; i < MAX_PIPES; i++) { |
| 2494 | 2499 | struct pipe_ctx pipe_ctx = dc->current_state->res_ctx.pipe_ctx[i]; |
| 2495 | 2500 | struct dc_stream_state *stream = pipe_ctx.stream; |
| @@ -892,13 +892,13 @@ static uint32_t translate_training_aux_read_interval(uint32_t dpcd_aux_read_inte · 891 unmodified lines | ||
| 892 | 892 | |
| 893 | 893 | switch (dpcd_aux_read_interval) { |
| 894 | 894 | case 0x01: |
| 895 | − aux_rd_interval_us = 400; | |
| 895 | + aux_rd_interval_us = 4000; | |
| 896 | 896 | break; |
| 897 | 897 | case 0x02: |
| 898 | − aux_rd_interval_us = 4000; | |
| 898 | + aux_rd_interval_us = 8000; | |
| 899 | 899 | break; |
| 900 | 900 | case 0x03: |
| 901 | − aux_rd_interval_us = 8000; | |
| 901 | + aux_rd_interval_us = 12000; | |
| 902 | 902 | break; |
| 903 | 903 | case 0x04: |
| 904 | 904 | aux_rd_interval_us = 16000; |
| @@ -2399,6 +2399,9 @@ static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_setting · 1494 unmodified lines | ||
| 2399 | 2399 | initial_link_setting; |
| 2400 | 2400 | uint32_t link_bw; |
| 2401 | 2401 | |
| 2402 | + if (req_bw > dc_link_bandwidth_kbps(link, &link->verified_link_cap)) | |
| 2403 | + return false; | |
| 2404 | + | |
| 2402 | 2405 | /* search for the minimum link setting that: |
| 2403 | 2406 | * 1. is supported according to the link training result |
| 2404 | 2407 | * 2. could support the b/w requested by the timing |
| @@ -3045,14 +3048,14 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd · 640 unmodified lines | ||
| 3045 | 3048 | for (i = 0; i < MAX_PIPES; i++) { |
| 3046 | 3049 | pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 3047 | 3050 | if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off && |
| 3048 | − pipe_ctx->stream->link == link) | |
| 3051 | + pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) | |
| 3049 | 3052 | core_link_disable_stream(pipe_ctx); |
| 3050 | 3053 | } |
| 3051 | 3054 | |
| 3052 | 3055 | for (i = 0; i < MAX_PIPES; i++) { |
| 3053 | 3056 | pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 3054 | 3057 | if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off && |
| 3055 | − pipe_ctx->stream->link == link) | |
| 3058 | + pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) | |
| 3056 | 3059 | core_link_enable_stream(link->dc->current_state, pipe_ctx); |
| 3057 | 3060 | } |
| 3058 | 3061 | |
| @@ -3992,7 +3995,7 @@ bool dc_link_dp_set_test_pattern( · 933 unmodified lines | ||
| 3992 | 3995 | unsigned int cust_pattern_size) |
| 3993 | 3996 | { |
| 3994 | 3997 | struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx; |
| 3995 | − struct pipe_ctx *pipe_ctx = &pipes[0]; | |
| 3998 | + struct pipe_ctx *pipe_ctx = NULL; | |
| 3996 | 3999 | unsigned int lane; |
| 3997 | 4000 | unsigned int i; |
| 3998 | 4001 | unsigned char link_qual_pattern[LANE_COUNT_DP_MAX] = {0}; |
| @@ -4002,12 +4005,18 @@ bool dc_link_dp_set_test_pattern( · 3 unmodified lines | ||
| 4002 | 4005 | memset(&training_pattern, 0, sizeof(training_pattern)); |
| 4003 | 4006 | |
| 4004 | 4007 | for (i = 0; i < MAX_PIPES; i++) { |
| 4008 | + if (pipes[i].stream == NULL) | |
| 4009 | + continue; | |
| 4010 | + | |
| 4005 | 4011 | if (pipes[i].stream->link == link && !pipes[i].top_pipe && !pipes[i].prev_odm_pipe) { |
| 4006 | 4012 | pipe_ctx = &pipes[i]; |
| 4007 | 4013 | break; |
| 4008 | 4014 | } |
| 4009 | 4015 | } |
| 4010 | 4016 | |
| 4017 | + if (pipe_ctx == NULL) | |
| 4018 | + return false; | |
| 4019 | + | |
| 4011 | 4020 | /* Reset CRTC Test Pattern if it is currently running and request is VideoMode */ |
| 4012 | 4021 | if (link->test_pattern_enabled && test_pattern == |
| 4013 | 4022 | DP_TEST_PATTERN_VIDEO_MODE) { |
| @@ -283,8 +283,7 @@ void dc_commit_updates_for_stream(struct dc *dc, · 282 unmodified lines | ||
| 283 | 283 | struct dc_surface_update *srf_updates, |
| 284 | 284 | int surface_count, |
| 285 | 285 | struct dc_stream_state *stream, |
| 286 | − struct dc_stream_update *stream_update, | |
| 287 | − struct dc_state *state); | |
| 286 | + struct dc_stream_update *stream_update); | |
| 288 | 287 | /* |
| 289 | 288 | * Log the current stream state. |
| 290 | 289 | */ |
| @@ -31,11 +31,4 @@ DCN10 = dcn10_init.o dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o \ · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10)) |
| 33 | 33 | |
| 34 | −# fix: | |
| 35 | −# ...: '-mgeneral-regs-only' is incompatible with the use of floating-point types | |
| 36 | −# aarch64 does not support soft-float, so use hard-float and handle this in code | |
| 37 | −ifdef CONFIG_ARM64 | |
| 38 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn10/dcn10_resource.o := -mgeneral-regs-only | |
| 39 | −endif | |
| 40 | − | |
| 41 | 34 | AMD_DISPLAY_FILES += $(AMD_DAL_DCN10) |
| @@ -647,8 +647,13 @@ static void power_on_plane( · 646 unmodified lines | ||
| 647 | 647 | if (REG(DC_IP_REQUEST_CNTL)) { |
| 648 | 648 | REG_SET(DC_IP_REQUEST_CNTL, 0, |
| 649 | 649 | IP_REQUEST_EN, 1); |
| 650 | − hws->funcs.dpp_pg_control(hws, plane_id, true); | |
| 651 | − hws->funcs.hubp_pg_control(hws, plane_id, true); | |
| 650 | + | |
| 651 | + if (hws->funcs.dpp_pg_control) | |
| 652 | + hws->funcs.dpp_pg_control(hws, plane_id, true); | |
| 653 | + | |
| 654 | + if (hws->funcs.hubp_pg_control) | |
| 655 | + hws->funcs.hubp_pg_control(hws, plane_id, true); | |
| 656 | + | |
| 652 | 657 | REG_SET(DC_IP_REQUEST_CNTL, 0, |
| 653 | 658 | IP_REQUEST_EN, 0); |
| 654 | 659 | DC_LOG_DEBUG( |
| @@ -1082,8 +1087,13 @@ void dcn10_plane_atomic_power_down(struct dc *dc, · 427 unmodified lines | ||
| 1082 | 1087 | if (REG(DC_IP_REQUEST_CNTL)) { |
| 1083 | 1088 | REG_SET(DC_IP_REQUEST_CNTL, 0, |
| 1084 | 1089 | IP_REQUEST_EN, 1); |
| 1085 | − hws->funcs.dpp_pg_control(hws, dpp->inst, false); | |
| 1086 | − hws->funcs.hubp_pg_control(hws, hubp->inst, false); | |
| 1090 | + | |
| 1091 | + if (hws->funcs.dpp_pg_control) | |
| 1092 | + hws->funcs.dpp_pg_control(hws, dpp->inst, false); | |
| 1093 | + | |
| 1094 | + if (hws->funcs.hubp_pg_control) | |
| 1095 | + hws->funcs.hubp_pg_control(hws, hubp->inst, false); | |
| 1096 | + | |
| 1087 | 1097 | dpp->funcs->dpp_reset(dpp); |
| 1088 | 1098 | REG_SET(DC_IP_REQUEST_CNTL, 0, |
| 1089 | 1099 | IP_REQUEST_EN, 0); |
| @@ -470,7 +470,7 @@ void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock) · 469 unmodified lines | ||
| 470 | 470 | unsigned int mpc1_get_mpc_out_mux(struct mpc *mpc, int opp_id) |
| 471 | 471 | { |
| 472 | 472 | struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); |
| 473 | − uint32_t val = 0; | |
| 473 | + uint32_t val = 0xf; | |
| 474 | 474 | |
| 475 | 475 | if (opp_id < MAX_OPP && REG(MUX[opp_id])) |
| 476 | 476 | REG_GET(MUX[opp_id], MPC_OUT_MUX, &val); |
| @@ -608,8 +608,8 @@ static const struct dc_debug_options debug_defaults_drv = { · 607 unmodified lines | ||
| 608 | 608 | .disable_pplib_clock_request = false, |
| 609 | 609 | .disable_pplib_wm_range = false, |
| 610 | 610 | .pplib_wm_report_mode = WM_REPORT_DEFAULT, |
| 611 | − .pipe_split_policy = MPC_SPLIT_DYNAMIC, | |
| 612 | − .force_single_disp_pipe_split = true, | |
| 611 | + .pipe_split_policy = MPC_SPLIT_AVOID, | |
| 612 | + .force_single_disp_pipe_split = false, | |
| 613 | 613 | .disable_dcc = DCC_ENABLE, |
| 614 | 614 | .voltage_align_fclk = true, |
| 615 | 615 | .disable_stereo_support = true, |
| @@ -1534,15 +1534,8 @@ static bool dcn10_resource_construct( · 918 unmodified lines | ||
| 1534 | 1534 | memcpy(dc->dcn_ip, &dcn10_ip_defaults, sizeof(dcn10_ip_defaults)); |
| 1535 | 1535 | memcpy(dc->dcn_soc, &dcn10_soc_defaults, sizeof(dcn10_soc_defaults)); |
| 1536 | 1536 | |
| 1537 | −#if defined(CONFIG_ARM64) | |
| 1538 | − /* Aarch64 does not support -msoft-float/-mfloat-abi=soft */ | |
| 1539 | − DC_FP_START(); | |
| 1540 | − dcn10_resource_construct_fp(dc); | |
| 1541 | − DC_FP_END(); | |
| 1542 | −#else | |
| 1543 | 1537 | /* Other architectures we build for build this with soft-float */ |
| 1544 | 1538 | dcn10_resource_construct_fp(dc); |
| 1545 | −#endif | |
| 1546 | 1539 | |
| 1547 | 1540 | pool->base.pp_smu = dcn10_pp_smu_create(ctx); |
| 1548 | 1541 | |
| @@ -17,10 +17,6 @@ ifdef CONFIG_PPC64 · 16 unmodified lines | ||
| 17 | 17 | CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -mhard-float -maltivec |
| 18 | 18 | endif |
| 19 | 19 | |
| 20 | −ifdef CONFIG_ARM64 | |
| 21 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -mgeneral-regs-only | |
| 22 | −endif | |
| 23 | − | |
| 24 | 20 | ifdef CONFIG_CC_IS_GCC |
| 25 | 21 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 26 | 22 | IS_OLD_GCC = 1 |
| @@ -1062,8 +1062,13 @@ static void dcn20_power_on_plane( · 1061 unmodified lines | ||
| 1062 | 1062 | if (REG(DC_IP_REQUEST_CNTL)) { |
| 1063 | 1063 | REG_SET(DC_IP_REQUEST_CNTL, 0, |
| 1064 | 1064 | IP_REQUEST_EN, 1); |
| 1065 | − dcn20_dpp_pg_control(hws, pipe_ctx->plane_res.dpp->inst, true); | |
| 1066 | − dcn20_hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, true); | |
| 1065 | + | |
| 1066 | + if (hws->funcs.dpp_pg_control) | |
| 1067 | + hws->funcs.dpp_pg_control(hws, pipe_ctx->plane_res.dpp->inst, true); | |
| 1068 | + | |
| 1069 | + if (hws->funcs.hubp_pg_control) | |
| 1070 | + hws->funcs.hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, true); | |
| 1071 | + | |
| 1067 | 1072 | REG_SET(DC_IP_REQUEST_CNTL, 0, |
| 1068 | 1073 | IP_REQUEST_EN, 0); |
| 1069 | 1074 | DC_LOG_DEBUG( |
| @@ -297,8 +297,8 @@ static struct _vcs_dpi_soc_bounding_box_st dcn2_0_soc = { · 296 unmodified lines | ||
| 297 | 297 | }, |
| 298 | 298 | }, |
| 299 | 299 | .num_states = 5, |
| 300 | − .sr_exit_time_us = 11.6, | |
| 301 | − .sr_enter_plus_exit_time_us = 13.9, | |
| 300 | + .sr_exit_time_us = 8.6, | |
| 301 | + .sr_enter_plus_exit_time_us = 10.9, | |
| 302 | 302 | .urgent_latency_us = 4.0, |
| 303 | 303 | .urgent_latency_pixel_data_only_us = 4.0, |
| 304 | 304 | .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, |
| @@ -2517,8 +2517,7 @@ struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc, · 2212 unmodified lines | ||
| 2517 | 2517 | * if this primary pipe has a bottom pipe in prev. state |
| 2518 | 2518 | * and if the bottom pipe is still available (which it should be), |
| 2519 | 2519 | * pick that pipe as secondary |
| 2520 | − * Same logic applies for ODM pipes. Since mpo is not allowed with odm | |
| 2521 | − * check in else case. | |
| 2520 | + * Same logic applies for ODM pipes | |
| 2522 | 2521 | */ |
| 2523 | 2522 | if (dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].bottom_pipe) { |
| 2524 | 2523 | preferred_pipe_idx = dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].bottom_pipe->pipe_idx; |
| @@ -2526,7 +2525,9 @@ struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc, · 1 unmodified line | ||
| 2526 | 2525 | secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx]; |
| 2527 | 2526 | secondary_pipe->pipe_idx = preferred_pipe_idx; |
| 2528 | 2527 | } |
| 2529 | − } else if (dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe) { | |
| 2528 | + } | |
| 2529 | + if (secondary_pipe == NULL && | |
| 2530 | + dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe) { | |
| 2530 | 2531 | preferred_pipe_idx = dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe->pipe_idx; |
| 2531 | 2532 | if (res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) { |
| 2532 | 2533 | secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx]; |
| @@ -13,10 +13,6 @@ ifdef CONFIG_PPC64 · 12 unmodified lines | ||
| 13 | 13 | CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mhard-float -maltivec |
| 14 | 14 | endif |
| 15 | 15 | |
| 16 | −ifdef CONFIG_ARM64 | |
| 17 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mgeneral-regs-only | |
| 18 | −endif | |
| 19 | − | |
| 20 | 16 | ifdef CONFIG_CC_IS_GCC |
| 21 | 17 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 22 | 18 | IS_OLD_GCC = 1 |
| @@ -296,7 +296,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { · 295 unmodified lines | ||
| 296 | 296 | .num_banks = 8, |
| 297 | 297 | .num_chans = 4, |
| 298 | 298 | .vmm_page_size_bytes = 4096, |
| 299 | − .dram_clock_change_latency_us = 23.84, | |
| 299 | + .dram_clock_change_latency_us = 11.72, | |
| 300 | 300 | .return_bus_width_bytes = 64, |
| 301 | 301 | .dispclk_dppclk_vco_speed_mhz = 3600, |
| 302 | 302 | .xfc_bus_transport_time_us = 4, |
| @@ -906,6 +906,8 @@ enum dcn20_clk_src_array_id { · 603 unmodified lines | ||
| 906 | 906 | DCN20_CLK_SRC_PLL0, |
| 907 | 907 | DCN20_CLK_SRC_PLL1, |
| 908 | 908 | DCN20_CLK_SRC_PLL2, |
| 909 | + DCN20_CLK_SRC_PLL3, | |
| 910 | + DCN20_CLK_SRC_PLL4, | |
| 909 | 911 | DCN20_CLK_SRC_TOTAL_DCN21 |
| 910 | 912 | }; |
| 911 | 913 | |
| @@ -2030,6 +2032,14 @@ static bool dcn21_resource_construct( · 1118 unmodified lines | ||
| 2030 | 2032 | dcn21_clock_source_create(ctx, ctx->dc_bios, |
| 2031 | 2033 | CLOCK_SOURCE_COMBO_PHY_PLL2, |
| 2032 | 2034 | &clk_src_regs[2], false); |
| 2035 | + pool->base.clock_sources[DCN20_CLK_SRC_PLL3] = | |
| 2036 | + dcn21_clock_source_create(ctx, ctx->dc_bios, | |
| 2037 | + CLOCK_SOURCE_COMBO_PHY_PLL3, | |
| 2038 | + &clk_src_regs[3], false); | |
| 2039 | + pool->base.clock_sources[DCN20_CLK_SRC_PLL4] = | |
| 2040 | + dcn21_clock_source_create(ctx, ctx->dc_bios, | |
| 2041 | + CLOCK_SOURCE_COMBO_PHY_PLL4, | |
| 2042 | + &clk_src_regs[4], false); | |
| 2033 | 2043 | |
| 2034 | 2044 | pool->base.clk_src_count = DCN20_CLK_SRC_TOTAL_DCN21; |
| 2035 | 2045 | |
| @@ -32,8 +32,8 @@ DCN30 = dcn30_init.o dcn30_hubbub.o dcn30_hubp.o dcn30_dpp.o dcn30_optc.o \ · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | |
| 34 | 34 | ifdef CONFIG_X86 |
| 35 | −CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -mhard-float -msse | |
| 36 | −CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -mhard-float -msse | |
| 35 | +CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -msse | |
| 36 | +CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -msse | |
| 37 | 37 | endif |
| 38 | 38 | |
| 39 | 39 | ifdef CONFIG_PPC64 |
| @@ -41,15 +41,12 @@ CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -mhard-float -maltivec · 1 unmodified line | ||
| 41 | 41 | CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -mhard-float -maltivec |
| 42 | 42 | endif |
| 43 | 43 | |
| 44 | −ifdef CONFIG_ARM64 | |
| 45 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -mgeneral-regs-only | |
| 46 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -mgeneral-regs-only | |
| 47 | −endif | |
| 48 | − | |
| 49 | 44 | ifdef CONFIG_CC_IS_GCC |
| 50 | 45 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 51 | 46 | IS_OLD_GCC = 1 |
| 52 | 47 | endif |
| 48 | +CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o += -mhard-float | |
| 49 | +CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o += -mhard-float | |
| 53 | 50 | endif |
| 54 | 51 | |
| 55 | 52 | ifdef CONFIG_X86 |
| @@ -14,21 +14,18 @@ DCN301 = dcn301_init.o dcn301_resource.o dcn301_dccg.o \ · 13 unmodified lines | ||
| 14 | 14 | dcn301_dio_link_encoder.o dcn301_hwseq.o dcn301_panel_cntl.o dcn301_hubbub.o |
| 15 | 15 | |
| 16 | 16 | ifdef CONFIG_X86 |
| 17 | −CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mhard-float -msse | |
| 17 | +CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -msse | |
| 18 | 18 | endif |
| 19 | 19 | |
| 20 | 20 | ifdef CONFIG_PPC64 |
| 21 | 21 | CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mhard-float -maltivec |
| 22 | 22 | endif |
| 23 | 23 | |
| 24 | −ifdef CONFIG_ARM64 | |
| 25 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mgeneral-regs-only | |
| 26 | −endif | |
| 27 | − | |
| 28 | 24 | ifdef CONFIG_CC_IS_GCC |
| 29 | 25 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 30 | 26 | IS_OLD_GCC = 1 |
| 31 | 27 | endif |
| 28 | +CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -mhard-float | |
| 32 | 29 | endif |
| 33 | 30 | |
| 34 | 31 | ifdef CONFIG_X86 |
| @@ -1731,6 +1731,7 @@ static struct resource_funcs dcn301_res_pool_funcs = { · 1730 unmodified lines | ||
| 1731 | 1731 | .populate_dml_pipes = dcn30_populate_dml_pipes_from_context, |
| 1732 | 1732 | .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer, |
| 1733 | 1733 | .add_stream_to_ctx = dcn30_add_stream_to_ctx, |
| 1734 | + .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource, | |
| 1734 | 1735 | .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, |
| 1735 | 1736 | .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context, |
| 1736 | 1737 | .set_mcif_arb_params = dcn30_set_mcif_arb_params, |
| @@ -13,21 +13,18 @@ · 12 unmodified lines | ||
| 13 | 13 | DCN3_02 = dcn302_init.o dcn302_hwseq.o dcn302_resource.o |
| 14 | 14 | |
| 15 | 15 | ifdef CONFIG_X86 |
| 16 | −CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -mhard-float -msse | |
| 16 | +CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -msse | |
| 17 | 17 | endif |
| 18 | 18 | |
| 19 | 19 | ifdef CONFIG_PPC64 |
| 20 | 20 | CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -mhard-float -maltivec |
| 21 | 21 | endif |
| 22 | 22 | |
| 23 | −ifdef CONFIG_ARM64 | |
| 24 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -mgeneral-regs-only | |
| 25 | −endif | |
| 26 | − | |
| 27 | 23 | ifdef CONFIG_CC_IS_GCC |
| 28 | 24 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 29 | 25 | IS_OLD_GCC = 1 |
| 30 | 26 | endif |
| 27 | +CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o += -mhard-float | |
| 31 | 28 | endif |
| 32 | 29 | |
| 33 | 30 | ifdef CONFIG_X86 |
| @@ -33,10 +33,6 @@ ifdef CONFIG_PPC64 · 32 unmodified lines | ||
| 33 | 33 | dml_ccflags := -mhard-float -maltivec |
| 34 | 34 | endif |
| 35 | 35 | |
| 36 | −ifdef CONFIG_ARM64 | |
| 37 | −dml_rcflags := -mgeneral-regs-only | |
| 38 | −endif | |
| 39 | − | |
| 40 | 36 | ifdef CONFIG_CC_IS_GCC |
| 41 | 37 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 42 | 38 | IS_OLD_GCC = 1 |
| @@ -2635,14 +2635,15 @@ static void dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndP · 2634 unmodified lines | ||
| 2635 | 2635 | } |
| 2636 | 2636 | |
| 2637 | 2637 | if (mode_lib->vba.DRAMClockChangeSupportsVActive && |
| 2638 | − mode_lib->vba.MinActiveDRAMClockChangeMargin > 60 && | |
| 2639 | − mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 0) { | |
| 2638 | + mode_lib->vba.MinActiveDRAMClockChangeMargin > 60) { | |
| 2640 | 2639 | mode_lib->vba.DRAMClockChangeWatermark += 25; |
| 2641 | 2640 | |
| 2642 | 2641 | for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { |
| 2643 | − if (mode_lib->vba.DRAMClockChangeWatermark > | |
| 2644 | − dml_max(mode_lib->vba.StutterEnterPlusExitWatermark, mode_lib->vba.UrgentWatermark)) | |
| 2645 | − mode_lib->vba.MinTTUVBlank[k] += 25; | |
| 2642 | + if (mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 0) { | |
| 2643 | + if (mode_lib->vba.DRAMClockChangeWatermark > | |
| 2644 | + dml_max(mode_lib->vba.StutterEnterPlusExitWatermark, mode_lib->vba.UrgentWatermark)) | |
| 2645 | + mode_lib->vba.MinTTUVBlank[k] += 25; | |
| 2646 | + } | |
| 2646 | 2647 | } |
| 2647 | 2648 | |
| 2648 | 2649 | mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive; |
| @@ -10,10 +10,6 @@ ifdef CONFIG_PPC64 · 9 unmodified lines | ||
| 10 | 10 | dsc_ccflags := -mhard-float -maltivec |
| 11 | 11 | endif |
| 12 | 12 | |
| 13 | −ifdef CONFIG_ARM64 | |
| 14 | −dsc_rcflags := -mgeneral-regs-only | |
| 15 | −endif | |
| 16 | − | |
| 17 | 13 | ifdef CONFIG_CC_IS_GCC |
| 18 | 14 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 19 | 15 | IS_OLD_GCC = 1 |
| @@ -55,10 +55,6 @@ · 54 unmodified lines | ||
| 55 | 55 | #include <asm/fpu/api.h> |
| 56 | 56 | #define DC_FP_START() kernel_fpu_begin() |
| 57 | 57 | #define DC_FP_END() kernel_fpu_end() |
| 58 | −#elif defined(CONFIG_ARM64) | |
| 59 | −#include <asm/neon.h> | |
| 60 | −#define DC_FP_START() kernel_neon_begin() | |
| 61 | −#define DC_FP_END() kernel_neon_end() | |
| 62 | 58 | #elif defined(CONFIG_PPC64) |
| 63 | 59 | #include <asm/switch_to.h> |
| 64 | 60 | #include <asm/cputable.h> |
| @@ -553,6 +553,7 @@ struct pptable_funcs { · 552 unmodified lines | ||
| 553 | 553 | *clock_req); |
| 554 | 554 | uint32_t (*get_fan_control_mode)(struct smu_context *smu); |
| 555 | 555 | int (*set_fan_control_mode)(struct smu_context *smu, uint32_t mode); |
| 556 | + int (*set_fan_speed_percent)(struct smu_context *smu, uint32_t speed); | |
| 556 | 557 | int (*set_fan_speed_rpm)(struct smu_context *smu, uint32_t speed); |
| 557 | 558 | int (*set_xgmi_pstate)(struct smu_context *smu, uint32_t pstate); |
| 558 | 559 | int (*gfx_off_control)(struct smu_context *smu, bool enable); |
| @@ -203,6 +203,9 @@ int · 202 unmodified lines | ||
| 203 | 203 | smu_v11_0_set_fan_control_mode(struct smu_context *smu, |
| 204 | 204 | uint32_t mode); |
| 205 | 205 | |
| 206 | +int | |
| 207 | +smu_v11_0_set_fan_speed_percent(struct smu_context *smu, uint32_t speed); | |
| 208 | + | |
| 206 | 209 | int smu_v11_0_set_fan_speed_rpm(struct smu_context *smu, |
| 207 | 210 | uint32_t speed); |
| 208 | 211 | |
| @@ -251,7 +251,7 @@ static int smu10_set_hard_min_gfxclk_by_freq(struct pp_hwmgr *hwmgr, uint32_t cl · 250 unmodified lines | ||
| 251 | 251 | smu10_data->gfx_actual_soft_min_freq = clock; |
| 252 | 252 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 253 | 253 | PPSMC_MSG_SetHardMinGfxClk, |
| 254 | − smu10_data->gfx_actual_soft_min_freq, | |
| 254 | + clock, | |
| 255 | 255 | NULL); |
| 256 | 256 | } |
| 257 | 257 | return 0; |
| @@ -558,7 +558,8 @@ static int smu10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) · 300 unmodified lines | ||
| 558 | 558 | |
| 559 | 559 | /* enable the pp_od_clk_voltage sysfs file */ |
| 560 | 560 | hwmgr->od_enabled = 1; |
| 561 | − | |
| 561 | + /* disabled fine grain tuning function by default */ | |
| 562 | + data->fine_grain_enabled = 0; | |
| 562 | 563 | return result; |
| 563 | 564 | } |
| 564 | 565 | |
| @@ -597,6 +598,7 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 32 unmodified lines | ||
| 597 | 598 | uint32_t min_mclk = hwmgr->display_config->min_mem_set_clock/100; |
| 598 | 599 | uint32_t index_fclk = data->clock_vol_info.vdd_dep_on_fclk->count - 1; |
| 599 | 600 | uint32_t index_socclk = data->clock_vol_info.vdd_dep_on_socclk->count - 1; |
| 601 | + uint32_t fine_grain_min_freq = 0, fine_grain_max_freq = 0; | |
| 600 | 602 | |
| 601 | 603 | if (hwmgr->smu_version < 0x1E3700) { |
| 602 | 604 | pr_info("smu firmware version too old, can not set dpm level\n"); |
| @@ -613,6 +615,14 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 10 unmodified lines | ||
| 613 | 615 | switch (level) { |
| 614 | 616 | case AMD_DPM_FORCED_LEVEL_HIGH: |
| 615 | 617 | case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: |
| 618 | + data->fine_grain_enabled = 0; | |
| 619 | + | |
| 620 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &fine_grain_min_freq); | |
| 621 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &fine_grain_max_freq); | |
| 622 | + | |
| 623 | + data->gfx_actual_soft_min_freq = fine_grain_min_freq; | |
| 624 | + data->gfx_actual_soft_max_freq = fine_grain_max_freq; | |
| 625 | + | |
| 616 | 626 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 617 | 627 | PPSMC_MSG_SetHardMinGfxClk, |
| 618 | 628 | data->gfx_max_freq_limit/100, |
| @@ -648,6 +658,14 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 29 unmodified lines | ||
| 648 | 658 | NULL); |
| 649 | 659 | break; |
| 650 | 660 | case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: |
| 661 | + data->fine_grain_enabled = 0; | |
| 662 | + | |
| 663 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &fine_grain_min_freq); | |
| 664 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &fine_grain_max_freq); | |
| 665 | + | |
| 666 | + data->gfx_actual_soft_min_freq = fine_grain_min_freq; | |
| 667 | + data->gfx_actual_soft_max_freq = fine_grain_max_freq; | |
| 668 | + | |
| 651 | 669 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 652 | 670 | PPSMC_MSG_SetHardMinGfxClk, |
| 653 | 671 | min_sclk, |
| @@ -658,6 +676,14 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 4 unmodified lines | ||
| 658 | 676 | NULL); |
| 659 | 677 | break; |
| 660 | 678 | case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: |
| 679 | + data->fine_grain_enabled = 0; | |
| 680 | + | |
| 681 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &fine_grain_min_freq); | |
| 682 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &fine_grain_max_freq); | |
| 683 | + | |
| 684 | + data->gfx_actual_soft_min_freq = fine_grain_min_freq; | |
| 685 | + data->gfx_actual_soft_max_freq = fine_grain_max_freq; | |
| 686 | + | |
| 661 | 687 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 662 | 688 | PPSMC_MSG_SetHardMinFclkByFreq, |
| 663 | 689 | min_mclk, |
| @@ -668,6 +694,14 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 4 unmodified lines | ||
| 668 | 694 | NULL); |
| 669 | 695 | break; |
| 670 | 696 | case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: |
| 697 | + data->fine_grain_enabled = 0; | |
| 698 | + | |
| 699 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &fine_grain_min_freq); | |
| 700 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &fine_grain_max_freq); | |
| 701 | + | |
| 702 | + data->gfx_actual_soft_min_freq = fine_grain_min_freq; | |
| 703 | + data->gfx_actual_soft_max_freq = fine_grain_max_freq; | |
| 704 | + | |
| 671 | 705 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 672 | 706 | PPSMC_MSG_SetHardMinGfxClk, |
| 673 | 707 | SMU10_UMD_PSTATE_GFXCLK, |
| @@ -703,6 +737,14 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 29 unmodified lines | ||
| 703 | 737 | NULL); |
| 704 | 738 | break; |
| 705 | 739 | case AMD_DPM_FORCED_LEVEL_AUTO: |
| 740 | + data->fine_grain_enabled = 0; | |
| 741 | + | |
| 742 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &fine_grain_min_freq); | |
| 743 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &fine_grain_max_freq); | |
| 744 | + | |
| 745 | + data->gfx_actual_soft_min_freq = fine_grain_min_freq; | |
| 746 | + data->gfx_actual_soft_max_freq = fine_grain_max_freq; | |
| 747 | + | |
| 706 | 748 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 707 | 749 | PPSMC_MSG_SetHardMinGfxClk, |
| 708 | 750 | min_sclk, |
| @@ -741,6 +783,14 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 32 unmodified lines | ||
| 741 | 783 | NULL); |
| 742 | 784 | break; |
| 743 | 785 | case AMD_DPM_FORCED_LEVEL_LOW: |
| 786 | + data->fine_grain_enabled = 0; | |
| 787 | + | |
| 788 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &fine_grain_min_freq); | |
| 789 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &fine_grain_max_freq); | |
| 790 | + | |
| 791 | + data->gfx_actual_soft_min_freq = fine_grain_min_freq; | |
| 792 | + data->gfx_actual_soft_max_freq = fine_grain_max_freq; | |
| 793 | + | |
| 744 | 794 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 745 | 795 | PPSMC_MSG_SetHardMinGfxClk, |
| 746 | 796 | data->gfx_min_freq_limit/100, |
| @@ -759,6 +809,7 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 12 unmodified lines | ||
| 759 | 809 | NULL); |
| 760 | 810 | break; |
| 761 | 811 | case AMD_DPM_FORCED_LEVEL_MANUAL: |
| 812 | + data->fine_grain_enabled = 1; | |
| 762 | 813 | case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT: |
| 763 | 814 | default: |
| 764 | 815 | break; |
| @@ -948,6 +999,8 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, · 183 unmodified lines | ||
| 948 | 999 | struct smu10_voltage_dependency_table *mclk_table = |
| 949 | 1000 | data->clock_vol_info.vdd_dep_on_fclk; |
| 950 | 1001 | uint32_t i, now, size = 0; |
| 1002 | + uint32_t min_freq, max_freq = 0; | |
| 1003 | + uint32_t ret = 0; | |
| 951 | 1004 | |
| 952 | 1005 | switch (type) { |
| 953 | 1006 | case PP_SCLK: |
| @@ -983,18 +1036,28 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, · 29 unmodified lines | ||
| 983 | 1036 | break; |
| 984 | 1037 | case OD_SCLK: |
| 985 | 1038 | if (hwmgr->od_enabled) { |
| 986 | − size = sprintf(buf, "%s:\n", "OD_SCLK"); | |
| 1039 | + ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); | |
| 1040 | + if (ret) | |
| 1041 | + return ret; | |
| 1042 | + ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); | |
| 1043 | + if (ret) | |
| 1044 | + return ret; | |
| 987 | 1045 | |
| 1046 | + size = sprintf(buf, "%s:\n", "OD_SCLK"); | |
| 988 | 1047 | size += sprintf(buf + size, "0: %10uMhz\n", |
| 989 | − (data->gfx_actual_soft_min_freq > 0) ? data->gfx_actual_soft_min_freq : data->gfx_min_freq_limit/100); | |
| 990 | − size += sprintf(buf + size, "1: %10uMhz\n", data->gfx_max_freq_limit/100); | |
| 1048 | + (data->gfx_actual_soft_min_freq > 0) ? data->gfx_actual_soft_min_freq : min_freq); | |
| 1049 | + size += sprintf(buf + size, "1: %10uMhz\n", | |
| 1050 | + (data->gfx_actual_soft_max_freq > 0) ? data->gfx_actual_soft_max_freq : max_freq); | |
| 991 | 1051 | } |
| 992 | 1052 | break; |
| 993 | 1053 | case OD_RANGE: |
| 994 | 1054 | if (hwmgr->od_enabled) { |
| 995 | − uint32_t min_freq, max_freq = 0; | |
| 996 | − smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); | |
| 997 | − smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); | |
| 1055 | + ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); | |
| 1056 | + if (ret) | |
| 1057 | + return ret; | |
| 1058 | + ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); | |
| 1059 | + if (ret) | |
| 1060 | + return ret; | |
| 998 | 1061 | |
| 999 | 1062 | size = sprintf(buf, "%s:\n", "OD_RANGE"); |
| 1000 | 1063 | size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n", |
| @@ -1414,23 +1477,96 @@ static int smu10_set_fine_grain_clk_vol(struct pp_hwmgr *hwmgr, · 413 unmodified lines | ||
| 1414 | 1477 | enum PP_OD_DPM_TABLE_COMMAND type, |
| 1415 | 1478 | long *input, uint32_t size) |
| 1416 | 1479 | { |
| 1480 | + uint32_t min_freq, max_freq = 0; | |
| 1481 | + struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); | |
| 1482 | + int ret = 0; | |
| 1483 | + | |
| 1417 | 1484 | if (!hwmgr->od_enabled) { |
| 1418 | 1485 | pr_err("Fine grain not support\n"); |
| 1419 | 1486 | return -EINVAL; |
| 1420 | 1487 | } |
| 1421 | 1488 | |
| 1422 | − if (size != 2) { | |
| 1423 | − pr_err("Input parameter number not correct\n"); | |
| 1489 | + if (!smu10_data->fine_grain_enabled) { | |
| 1490 | + pr_err("Fine grain not started\n"); | |
| 1424 | 1491 | return -EINVAL; |
| 1425 | 1492 | } |
| 1426 | 1493 | |
| 1427 | 1494 | if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) { |
| 1428 | − if (input[0] == 0) | |
| 1429 | − smu10_set_hard_min_gfxclk_by_freq(hwmgr, input[1]); | |
| 1430 | − else if (input[0] == 1) | |
| 1431 | − smu10_set_soft_max_gfxclk_by_freq(hwmgr, input[1]); | |
| 1432 | − else | |
| 1495 | + if (size != 2) { | |
| 1496 | + pr_err("Input parameter number not correct\n"); | |
| 1433 | 1497 | return -EINVAL; |
| 1498 | + } | |
| 1499 | + | |
| 1500 | + if (input[0] == 0) { | |
| 1501 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); | |
| 1502 | + if (input[1] < min_freq) { | |
| 1503 | + pr_err("Fine grain setting minimum sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n", | |
| 1504 | + input[1], min_freq); | |
| 1505 | + return -EINVAL; | |
| 1506 | + } | |
| 1507 | + smu10_data->gfx_actual_soft_min_freq = input[1]; | |
| 1508 | + } else if (input[0] == 1) { | |
| 1509 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); | |
| 1510 | + if (input[1] > max_freq) { | |
| 1511 | + pr_err("Fine grain setting maximum sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n", | |
| 1512 | + input[1], max_freq); | |
| 1513 | + return -EINVAL; | |
| 1514 | + } | |
| 1515 | + smu10_data->gfx_actual_soft_max_freq = input[1]; | |
| 1516 | + } else { | |
| 1517 | + return -EINVAL; | |
| 1518 | + } | |
| 1519 | + } else if (type == PP_OD_RESTORE_DEFAULT_TABLE) { | |
| 1520 | + if (size != 0) { | |
| 1521 | + pr_err("Input parameter number not correct\n"); | |
| 1522 | + return -EINVAL; | |
| 1523 | + } | |
| 1524 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); | |
| 1525 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); | |
| 1526 | + | |
| 1527 | + smu10_data->gfx_actual_soft_min_freq = min_freq; | |
| 1528 | + smu10_data->gfx_actual_soft_max_freq = max_freq; | |
| 1529 | + | |
| 1530 | + ret = smum_send_msg_to_smc_with_parameter(hwmgr, | |
| 1531 | + PPSMC_MSG_SetHardMinGfxClk, | |
| 1532 | + min_freq, | |
| 1533 | + NULL); | |
| 1534 | + if (ret) | |
| 1535 | + return ret; | |
| 1536 | + | |
| 1537 | + ret = smum_send_msg_to_smc_with_parameter(hwmgr, | |
| 1538 | + PPSMC_MSG_SetSoftMaxGfxClk, | |
| 1539 | + max_freq, | |
| 1540 | + NULL); | |
| 1541 | + if (ret) | |
| 1542 | + return ret; | |
| 1543 | + } else if (type == PP_OD_COMMIT_DPM_TABLE) { | |
| 1544 | + if (size != 0) { | |
| 1545 | + pr_err("Input parameter number not correct\n"); | |
| 1546 | + return -EINVAL; | |
| 1547 | + } | |
| 1548 | + | |
| 1549 | + if (smu10_data->gfx_actual_soft_min_freq > smu10_data->gfx_actual_soft_max_freq) { | |
| 1550 | + pr_err("The setting minimun sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n", | |
| 1551 | + smu10_data->gfx_actual_soft_min_freq, smu10_data->gfx_actual_soft_max_freq); | |
| 1552 | + return -EINVAL; | |
| 1553 | + } | |
| 1554 | + | |
| 1555 | + ret = smum_send_msg_to_smc_with_parameter(hwmgr, | |
| 1556 | + PPSMC_MSG_SetHardMinGfxClk, | |
| 1557 | + smu10_data->gfx_actual_soft_min_freq, | |
| 1558 | + NULL); | |
| 1559 | + if (ret) | |
| 1560 | + return ret; | |
| 1561 | + | |
| 1562 | + ret = smum_send_msg_to_smc_with_parameter(hwmgr, | |
| 1563 | + PPSMC_MSG_SetSoftMaxGfxClk, | |
| 1564 | + smu10_data->gfx_actual_soft_max_freq, | |
| 1565 | + NULL); | |
| 1566 | + if (ret) | |
| 1567 | + return ret; | |
| 1568 | + } else { | |
| 1569 | + return -EINVAL; | |
| 1434 | 1570 | } |
| 1435 | 1571 | |
| 1436 | 1572 | return 0; |
| @@ -283,6 +283,7 @@ struct smu10_hwmgr { · 282 unmodified lines | ||
| 283 | 283 | uint32_t vclk_soft_min; |
| 284 | 284 | uint32_t dclk_soft_min; |
| 285 | 285 | uint32_t gfx_actual_soft_min_freq; |
| 286 | + uint32_t gfx_actual_soft_max_freq; | |
| 286 | 287 | uint32_t gfx_min_freq_limit; |
| 287 | 288 | uint32_t gfx_max_freq_limit; /* in 10Khz*/ |
| 288 | 289 | |
| @@ -299,6 +300,8 @@ struct smu10_hwmgr { · 10 unmodified lines | ||
| 299 | 300 | bool need_min_deep_sleep_dcefclk; |
| 300 | 301 | uint32_t deep_sleep_dcefclk; |
| 301 | 302 | uint32_t num_active_display; |
| 303 | + | |
| 304 | + bool fine_grain_enabled; | |
| 302 | 305 | }; |
| 303 | 306 | |
| 304 | 307 | struct pp_hwmgr; |
| @@ -2151,19 +2151,14 @@ int smu_get_fan_speed_percent(struct smu_context *smu, uint32_t *speed) · 2150 unmodified lines | ||
| 2151 | 2151 | int smu_set_fan_speed_percent(struct smu_context *smu, uint32_t speed) |
| 2152 | 2152 | { |
| 2153 | 2153 | int ret = 0; |
| 2154 | − uint32_t rpm; | |
| 2155 | 2154 | |
| 2156 | 2155 | if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) |
| 2157 | 2156 | return -EOPNOTSUPP; |
| 2158 | 2157 | |
| 2159 | 2158 | mutex_lock(&smu->mutex); |
| 2160 | 2159 | |
| 2161 | − if (smu->ppt_funcs->set_fan_speed_rpm) { | |
| 2162 | − if (speed > 100) | |
| 2163 | − speed = 100; | |
| 2164 | − rpm = speed * smu->fan_max_rpm / 100; | |
| 2165 | − ret = smu->ppt_funcs->set_fan_speed_rpm(smu, rpm); | |
| 2166 | − } | |
| 2160 | + if (smu->ppt_funcs->set_fan_speed_percent) | |
| 2161 | + ret = smu->ppt_funcs->set_fan_speed_percent(smu, speed); | |
| 2167 | 2162 | |
| 2168 | 2163 | mutex_unlock(&smu->mutex); |
| 2169 | 2164 | |
| @@ -2326,6 +2326,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = { · 2325 unmodified lines | ||
| 2326 | 2326 | .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request, |
| 2327 | 2327 | .get_fan_control_mode = smu_v11_0_get_fan_control_mode, |
| 2328 | 2328 | .set_fan_control_mode = smu_v11_0_set_fan_control_mode, |
| 2329 | + .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent, | |
| 2329 | 2330 | .set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm, |
| 2330 | 2331 | .set_xgmi_pstate = smu_v11_0_set_xgmi_pstate, |
| 2331 | 2332 | .gfx_off_control = smu_v11_0_gfx_off_control, |
| @@ -2456,6 +2456,7 @@ static const struct pptable_funcs navi10_ppt_funcs = { · 2455 unmodified lines | ||
| 2456 | 2456 | .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request, |
| 2457 | 2457 | .get_fan_control_mode = smu_v11_0_get_fan_control_mode, |
| 2458 | 2458 | .set_fan_control_mode = smu_v11_0_set_fan_control_mode, |
| 2459 | + .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent, | |
| 2459 | 2460 | .set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm, |
| 2460 | 2461 | .set_xgmi_pstate = smu_v11_0_set_xgmi_pstate, |
| 2461 | 2462 | .gfx_off_control = smu_v11_0_gfx_off_control, |
| @@ -2372,7 +2372,7 @@ static void sienna_cichlid_fill_i2c_req(SwI2cRequest_t *req, bool write, · 2371 unmodified lines | ||
| 2372 | 2372 | { |
| 2373 | 2373 | int i; |
| 2374 | 2374 | |
| 2375 | − req->I2CcontrollerPort = 0; | |
| 2375 | + req->I2CcontrollerPort = 1; | |
| 2376 | 2376 | req->I2CSpeed = 2; |
| 2377 | 2377 | req->SlaveAddress = address; |
| 2378 | 2378 | req->NumCmds = numbytes; |
| @@ -2802,6 +2802,7 @@ static const struct pptable_funcs sienna_cichlid_ppt_funcs = { · 423 unmodified lines | ||
| 2802 | 2802 | .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request, |
| 2803 | 2803 | .get_fan_control_mode = smu_v11_0_get_fan_control_mode, |
| 2804 | 2804 | .set_fan_control_mode = smu_v11_0_set_fan_control_mode, |
| 2805 | + .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent, | |
| 2805 | 2806 | .set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm, |
| 2806 | 2807 | .set_xgmi_pstate = smu_v11_0_set_xgmi_pstate, |
| 2807 | 2808 | .gfx_off_control = smu_v11_0_gfx_off_control, |
| @@ -1173,6 +1173,35 @@ smu_v11_0_set_fan_static_mode(struct smu_context *smu, uint32_t mode) · 1172 unmodified lines | ||
| 1173 | 1173 | return 0; |
| 1174 | 1174 | } |
| 1175 | 1175 | |
| 1176 | +int | |
| 1177 | +smu_v11_0_set_fan_speed_percent(struct smu_context *smu, uint32_t speed) | |
| 1178 | +{ | |
| 1179 | + struct amdgpu_device *adev = smu->adev; | |
| 1180 | + uint32_t duty100, duty; | |
| 1181 | + uint64_t tmp64; | |
| 1182 | + | |
| 1183 | + if (speed > 100) | |
| 1184 | + speed = 100; | |
| 1185 | + | |
| 1186 | + if (smu_v11_0_auto_fan_control(smu, 0)) | |
| 1187 | + return -EINVAL; | |
| 1188 | + | |
| 1189 | + duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1), | |
| 1190 | + CG_FDO_CTRL1, FMAX_DUTY100); | |
| 1191 | + if (!duty100) | |
| 1192 | + return -EINVAL; | |
| 1193 | + | |
| 1194 | + tmp64 = (uint64_t)speed * duty100; | |
| 1195 | + do_div(tmp64, 100); | |
| 1196 | + duty = (uint32_t)tmp64; | |
| 1197 | + | |
| 1198 | + WREG32_SOC15(THM, 0, mmCG_FDO_CTRL0, | |
| 1199 | + REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL0), | |
| 1200 | + CG_FDO_CTRL0, FDO_STATIC_DUTY, duty)); | |
| 1201 | + | |
| 1202 | + return smu_v11_0_set_fan_static_mode(smu, FDO_PWM_MODE_STATIC); | |
| 1203 | +} | |
| 1204 | + | |
| 1176 | 1205 | int |
| 1177 | 1206 | smu_v11_0_set_fan_control_mode(struct smu_context *smu, |
| 1178 | 1207 | uint32_t mode) |
| @@ -1181,7 +1210,7 @@ smu_v11_0_set_fan_control_mode(struct smu_context *smu, · 2 unmodified lines | ||
| 1181 | 1210 | |
| 1182 | 1211 | switch (mode) { |
| 1183 | 1212 | case AMD_FAN_CTRL_NONE: |
| 1184 | − ret = smu_v11_0_set_fan_speed_rpm(smu, smu->fan_max_rpm); | |
| 1213 | + ret = smu_v11_0_set_fan_speed_percent(smu, 100); | |
| 1185 | 1214 | break; |
| 1186 | 1215 | case AMD_FAN_CTRL_MANUAL: |
| 1187 | 1216 | ret = smu_v11_0_auto_fan_control(smu, 0); |
| @@ -252,7 +252,8 @@ static int vangogh_get_smu_metrics_data(struct smu_context *smu, · 251 unmodified lines | ||
| 252 | 252 | *value = metrics->UvdActivity; |
| 253 | 253 | break; |
| 254 | 254 | case METRICS_AVERAGE_SOCKETPOWER: |
| 255 | − *value = metrics->CurrentSocketPower; | |
| 255 | + *value = (metrics->CurrentSocketPower << 8) / | |
| 256 | + 1000 ; | |
| 256 | 257 | break; |
| 257 | 258 | case METRICS_TEMPERATURE_EDGE: |
| 258 | 259 | *value = metrics->GfxTemperature / 100 * |
| @@ -590,14 +591,17 @@ static ssize_t vangogh_get_gpu_metrics(struct smu_context *smu, · 331 unmodified lines | ||
| 590 | 591 | gpu_metrics->average_socket_power = metrics.CurrentSocketPower; |
| 591 | 592 | gpu_metrics->average_cpu_power = metrics.Power[0]; |
| 592 | 593 | gpu_metrics->average_soc_power = metrics.Power[1]; |
| 594 | + gpu_metrics->average_gfx_power = metrics.Power[2]; | |
| 593 | 595 | memcpy(&gpu_metrics->average_core_power[0], |
| 594 | 596 | &metrics.CorePower[0], |
| 595 | 597 | sizeof(uint16_t) * 8); |
| 596 | 598 | |
| 597 | 599 | gpu_metrics->average_gfxclk_frequency = metrics.GfxclkFrequency; |
| 598 | 600 | gpu_metrics->average_socclk_frequency = metrics.SocclkFrequency; |
| 601 | + gpu_metrics->average_uclk_frequency = metrics.MemclkFrequency; | |
| 599 | 602 | gpu_metrics->average_fclk_frequency = metrics.MemclkFrequency; |
| 600 | 603 | gpu_metrics->average_vclk_frequency = metrics.VclkFrequency; |
| 604 | + gpu_metrics->average_dclk_frequency = metrics.DclkFrequency; | |
| 601 | 605 | |
| 602 | 606 | memcpy(&gpu_metrics->current_coreclk[0], |
| 603 | 607 | &metrics.CoreFrequency[0], |
| @@ -188,6 +188,7 @@ static int renoir_get_dpm_clk_limited(struct smu_context *smu, enum smu_clk_type · 187 unmodified lines | ||
| 188 | 188 | return -EINVAL; |
| 189 | 189 | *freq = clk_table->SocClocks[dpm_level].Freq; |
| 190 | 190 | break; |
| 191 | + case SMU_UCLK: | |
| 191 | 192 | case SMU_MCLK: |
| 192 | 193 | if (dpm_level >= NUM_FCLK_DPM_LEVELS) |
| 193 | 194 | return -EINVAL; |
| @@ -1120,7 +1121,7 @@ static ssize_t renoir_get_gpu_metrics(struct smu_context *smu, · 926 unmodified lines | ||
| 1120 | 1121 | static int renoir_gfx_state_change_set(struct smu_context *smu, uint32_t state) |
| 1121 | 1122 | { |
| 1122 | 1123 | |
| 1123 | − return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GpuChangeState, state, NULL); | |
| 1124 | + return 0; | |
| 1124 | 1125 | } |
| 1125 | 1126 | |
| 1126 | 1127 | static const struct pptable_funcs renoir_ppt_funcs = { |
| @@ -225,6 +225,7 @@ int smu_v12_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_ · 224 unmodified lines | ||
| 225 | 225 | break; |
| 226 | 226 | case SMU_FCLK: |
| 227 | 227 | case SMU_MCLK: |
| 228 | + case SMU_UCLK: | |
| 228 | 229 | ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinFclkByFreq, min, NULL); |
| 229 | 230 | if (ret) |
| 230 | 231 | return ret; |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/regmap.h> |
| 15 | 15 | #include <linux/regulator/consumer.h> |
| 16 | 16 | #include <linux/wait.h> |
| 17 | +#include <linux/workqueue.h> | |
| 17 | 18 | |
| 18 | 19 | #include <sound/hdmi-codec.h> |
| 19 | 20 | |
| @@ -36,6 +37,7 @@ struct lt9611uxc { · 16 unmodified lines | ||
| 36 | 37 | struct mutex ocm_lock; |
| 37 | 38 | |
| 38 | 39 | struct wait_queue_head wq; |
| 40 | + struct work_struct work; | |
| 39 | 41 | |
| 40 | 42 | struct device_node *dsi0_node; |
| 41 | 43 | struct device_node *dsi1_node; |
| @@ -52,6 +54,8 @@ struct lt9611uxc { · 10 unmodified lines | ||
| 52 | 54 | |
| 53 | 55 | bool hpd_supported; |
| 54 | 56 | bool edid_read; |
| 57 | + /* can be accessed from different threads, so protect this with ocm_lock */ | |
| 58 | + bool hdmi_connected; | |
| 55 | 59 | uint8_t fw_version; |
| 56 | 60 | }; |
| 57 | 61 | |
| @@ -143,21 +147,41 @@ static irqreturn_t lt9611uxc_irq_thread_handler(int irq, void *dev_id) · 85 unmodified lines | ||
| 143 | 147 | if (irq_status) |
| 144 | 148 | regmap_write(lt9611uxc->regmap, 0xb022, 0); |
| 145 | 149 | |
| 146 | − lt9611uxc_unlock(lt9611uxc); | |
| 147 | − | |
| 148 | − if (irq_status & BIT(0)) | |
| 150 | + if (irq_status & BIT(0)) { | |
| 149 | 151 | lt9611uxc->edid_read = !!(hpd_status & BIT(0)); |
| 152 | + wake_up_all(<9611uxc->wq); | |
| 153 | + } | |
| 150 | 154 | |
| 151 | 155 | if (irq_status & BIT(1)) { |
| 152 | − if (lt9611uxc->connector.dev) | |
| 153 | − drm_kms_helper_hotplug_event(lt9611uxc->connector.dev); | |
| 154 | − else | |
| 155 | − drm_bridge_hpd_notify(<9611uxc->bridge, !!(hpd_status & BIT(1))); | |
| 156 | + lt9611uxc->hdmi_connected = hpd_status & BIT(1); | |
| 157 | + schedule_work(<9611uxc->work); | |
| 156 | 158 | } |
| 157 | 159 | |
| 160 | + lt9611uxc_unlock(lt9611uxc); | |
| 161 | + | |
| 158 | 162 | return IRQ_HANDLED; |
| 159 | 163 | } |
| 160 | 164 | |
| 165 | +static void lt9611uxc_hpd_work(struct work_struct *work) | |
| 166 | +{ | |
| 167 | + struct lt9611uxc *lt9611uxc = container_of(work, struct lt9611uxc, work); | |
| 168 | + bool connected; | |
| 169 | + | |
| 170 | + if (lt9611uxc->connector.dev) | |
| 171 | + drm_kms_helper_hotplug_event(lt9611uxc->connector.dev); | |
| 172 | + else { | |
| 173 | + | |
| 174 | + mutex_lock(<9611uxc->ocm_lock); | |
| 175 | + connected = lt9611uxc->hdmi_connected; | |
| 176 | + mutex_unlock(<9611uxc->ocm_lock); | |
| 177 | + | |
| 178 | + drm_bridge_hpd_notify(<9611uxc->bridge, | |
| 179 | + connected ? | |
| 180 | + connector_status_connected : | |
| 181 | + connector_status_disconnected); | |
| 182 | + } | |
| 183 | +} | |
| 184 | + | |
| 161 | 185 | static void lt9611uxc_reset(struct lt9611uxc *lt9611uxc) |
| 162 | 186 | { |
| 163 | 187 | gpiod_set_value_cansleep(lt9611uxc->reset_gpio, 1); |
| @@ -445,18 +469,21 @@ static enum drm_connector_status lt9611uxc_bridge_detect(struct drm_bridge *brid · 281 unmodified lines | ||
| 445 | 469 | struct lt9611uxc *lt9611uxc = bridge_to_lt9611uxc(bridge); |
| 446 | 470 | unsigned int reg_val = 0; |
| 447 | 471 | int ret; |
| 448 | − int connected = 1; | |
| 472 | + bool connected = true; | |
| 473 | + | |
| 474 | + lt9611uxc_lock(lt9611uxc); | |
| 449 | 475 | |
| 450 | 476 | if (lt9611uxc->hpd_supported) { |
| 451 | − lt9611uxc_lock(lt9611uxc); | |
| 452 | 477 | ret = regmap_read(lt9611uxc->regmap, 0xb023, ®_val); |
| 453 | − lt9611uxc_unlock(lt9611uxc); | |
| 454 | 478 | |
| 455 | 479 | if (ret) |
| 456 | 480 | dev_err(lt9611uxc->dev, "failed to read hpd status: %d\n", ret); |
| 457 | 481 | else |
| 458 | 482 | connected = reg_val & BIT(1); |
| 459 | 483 | } |
| 484 | + lt9611uxc->hdmi_connected = connected; | |
| 485 | + | |
| 486 | + lt9611uxc_unlock(lt9611uxc); | |
| 460 | 487 | |
| 461 | 488 | return connected ? connector_status_connected : |
| 462 | 489 | connector_status_disconnected; |
| @@ -465,7 +492,7 @@ static enum drm_connector_status lt9611uxc_bridge_detect(struct drm_bridge *brid · 2 unmodified lines | ||
| 465 | 492 | static int lt9611uxc_wait_for_edid(struct lt9611uxc *lt9611uxc) |
| 466 | 493 | { |
| 467 | 494 | return wait_event_interruptible_timeout(lt9611uxc->wq, lt9611uxc->edid_read, |
| 468 | − msecs_to_jiffies(100)); | |
| 495 | + msecs_to_jiffies(500)); | |
| 469 | 496 | } |
| 470 | 497 | |
| 471 | 498 | static int lt9611uxc_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len) |
| @@ -503,7 +530,10 @@ static struct edid *lt9611uxc_bridge_get_edid(struct drm_bridge *bridge, · 31 unmodified lines | ||
| 503 | 530 | ret = lt9611uxc_wait_for_edid(lt9611uxc); |
| 504 | 531 | if (ret < 0) { |
| 505 | 532 | dev_err(lt9611uxc->dev, "wait for EDID failed: %d\n", ret); |
| 506 | − return ERR_PTR(ret); | |
| 533 | + return NULL; | |
| 534 | + } else if (ret == 0) { | |
| 535 | + dev_err(lt9611uxc->dev, "wait for EDID timeout\n"); | |
| 536 | + return NULL; | |
| 507 | 537 | } |
| 508 | 538 | |
| 509 | 539 | return drm_do_get_edid(connector, lt9611uxc_get_edid_block, lt9611uxc); |
| @@ -926,6 +956,8 @@ retry: · 416 unmodified lines | ||
| 926 | 956 | lt9611uxc->fw_version = ret; |
| 927 | 957 | |
| 928 | 958 | init_waitqueue_head(<9611uxc->wq); |
| 959 | + INIT_WORK(<9611uxc->work, lt9611uxc_hpd_work); | |
| 960 | + | |
| 929 | 961 | ret = devm_request_threaded_irq(dev, client->irq, NULL, |
| 930 | 962 | lt9611uxc_irq_thread_handler, |
| 931 | 963 | IRQF_ONESHOT, "lt9611uxc", lt9611uxc); |
| @@ -962,6 +994,7 @@ static int lt9611uxc_remove(struct i2c_client *client) · 30 unmodified lines | ||
| 962 | 994 | struct lt9611uxc *lt9611uxc = i2c_get_clientdata(client); |
| 963 | 995 | |
| 964 | 996 | disable_irq(client->irq); |
| 997 | + flush_scheduled_work(); | |
| 965 | 998 | lt9611uxc_audio_exit(lt9611uxc); |
| 966 | 999 | drm_bridge_remove(<9611uxc->bridge); |
| 967 | 1000 | |
| @@ -3021,7 +3021,7 @@ int drm_atomic_helper_set_config(struct drm_mode_set *set, · 3020 unmodified lines | ||
| 3021 | 3021 | |
| 3022 | 3022 | ret = handle_conflicting_encoders(state, true); |
| 3023 | 3023 | if (ret) |
| 3024 | − return ret; | |
| 3024 | + goto fail; | |
| 3025 | 3025 | |
| 3026 | 3026 | ret = drm_atomic_commit(state); |
| 3027 | 3027 | |
| @@ -3629,14 +3629,26 @@ static int drm_dp_send_up_ack_reply(struct drm_dp_mst_topology_mgr *mgr, · 3628 unmodified lines | ||
| 3629 | 3629 | return 0; |
| 3630 | 3630 | } |
| 3631 | 3631 | |
| 3632 | −static int drm_dp_get_vc_payload_bw(u8 dp_link_bw, u8 dp_link_count) | |
| 3632 | +/** | |
| 3633 | + * drm_dp_get_vc_payload_bw - get the VC payload BW for an MST link | |
| 3634 | + * @link_rate: link rate in 10kbits/s units | |
| 3635 | + * @link_lane_count: lane count | |
| 3636 | + * | |
| 3637 | + * Calculate the total bandwidth of a MultiStream Transport link. The returned | |
| 3638 | + * value is in units of PBNs/(timeslots/1 MTP). This value can be used to | |
| 3639 | + * convert the number of PBNs required for a given stream to the number of | |
| 3640 | + * timeslots this stream requires in each MTP. | |
| 3641 | + */ | |
| 3642 | +int drm_dp_get_vc_payload_bw(int link_rate, int link_lane_count) | |
| 3633 | 3643 | { |
| 3634 | − if (dp_link_bw == 0 || dp_link_count == 0) | |
| 3635 | − DRM_DEBUG_KMS("invalid link bandwidth in DPCD: %x (link count: %d)\n", | |
| 3636 | − dp_link_bw, dp_link_count); | |
| 3644 | + if (link_rate == 0 || link_lane_count == 0) | |
| 3645 | + DRM_DEBUG_KMS("invalid link rate/lane count: (%d / %d)\n", | |
| 3646 | + link_rate, link_lane_count); | |
| 3637 | 3647 | |
| 3638 | − return dp_link_bw * dp_link_count / 2; | |
| 3648 | + /* See DP v2.0 2.6.4.2, VCPayload_Bandwidth_for_OneTimeSlotPer_MTP_Allocation */ | |
| 3649 | + return link_rate * link_lane_count / 54000; | |
| 3639 | 3650 | } |
| 3651 | +EXPORT_SYMBOL(drm_dp_get_vc_payload_bw); | |
| 3640 | 3652 | |
| 3641 | 3653 | /** |
| 3642 | 3654 | * drm_dp_read_mst_cap() - check whether or not a sink supports MST |
| @@ -3692,7 +3704,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms · 49 unmodified lines | ||
| 3692 | 3704 | goto out_unlock; |
| 3693 | 3705 | } |
| 3694 | 3706 | |
| 3695 | − mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr->dpcd[1], | |
| 3707 | + mgr->pbn_div = drm_dp_get_vc_payload_bw(drm_dp_bw_code_to_link_rate(mgr->dpcd[1]), | |
| 3696 | 3708 | mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK); |
| 3697 | 3709 | if (mgr->pbn_div == 0) { |
| 3698 | 3710 | ret = -EINVAL; |
| @@ -4212,6 +4224,7 @@ drm_dp_mst_detect_port(struct drm_connector *connector, · 513 unmodified lines | ||
| 4212 | 4224 | |
| 4213 | 4225 | switch (port->pdt) { |
| 4214 | 4226 | case DP_PEER_DEVICE_NONE: |
| 4227 | + break; | |
| 4215 | 4228 | case DP_PEER_DEVICE_MST_BRANCHING: |
| 4216 | 4229 | if (!port->mcs) |
| 4217 | 4230 | ret = connector_status_connected; |
| @@ -387,9 +387,16 @@ static int drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo, · 386 unmodified lines | ||
| 387 | 387 | if (gbo->vmap_use_count > 0) |
| 388 | 388 | goto out; |
| 389 | 389 | |
| 390 | − ret = ttm_bo_vmap(&gbo->bo, &gbo->map); | |
| 391 | − if (ret) | |
| 392 | − return ret; | |
| 390 | + /* | |
| 391 | + * VRAM helpers unmap the BO only on demand. So the previous | |
| 392 | + * page mapping might still be around. Only vmap if the there's | |
| 393 | + * no mapping present. | |
| 394 | + */ | |
| 395 | + if (dma_buf_map_is_null(&gbo->map)) { | |
| 396 | + ret = ttm_bo_vmap(&gbo->bo, &gbo->map); | |
| 397 | + if (ret) | |
| 398 | + return ret; | |
| 399 | + } | |
| 393 | 400 | |
| 394 | 401 | out: |
| 395 | 402 | ++gbo->vmap_use_count; |
| @@ -577,6 +584,7 @@ static void drm_gem_vram_bo_driver_move_notify(struct drm_gem_vram_object *gbo, · 181 unmodified lines | ||
| 577 | 584 | return; |
| 578 | 585 | |
| 579 | 586 | ttm_bo_vunmap(bo, &gbo->map); |
| 587 | + dma_buf_map_clear(&gbo->map); /* explicitly clear mapping for next vmap call */ | |
| 580 | 588 | } |
| 581 | 589 | |
| 582 | 590 | static int drm_gem_vram_bo_driver_move(struct drm_gem_vram_object *gbo, |
| @@ -1163,7 +1163,14 @@ retry: · 1162 unmodified lines | ||
| 1163 | 1163 | if (ret) |
| 1164 | 1164 | goto out; |
| 1165 | 1165 | |
| 1166 | − if (old_fb->format != fb->format) { | |
| 1166 | + /* | |
| 1167 | + * Only check the FOURCC format code, excluding modifiers. This is | |
| 1168 | + * enough for all legacy drivers. Atomic drivers have their own | |
| 1169 | + * checks in their ->atomic_check implementation, which will | |
| 1170 | + * return -EINVAL if any hw or driver constraint is violated due | |
| 1171 | + * to modifier changes. | |
| 1172 | + */ | |
| 1173 | + if (old_fb->format->format != fb->format->format) { | |
| 1167 | 1174 | DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n"); |
| 1168 | 1175 | ret = -EINVAL; |
| 1169 | 1176 | goto out; |
| @@ -388,19 +388,18 @@ int drm_syncobj_find_fence(struct drm_file *file_private, · 387 unmodified lines | ||
| 388 | 388 | return -ENOENT; |
| 389 | 389 | |
| 390 | 390 | *fence = drm_syncobj_fence_get(syncobj); |
| 391 | − drm_syncobj_put(syncobj); | |
| 392 | 391 | |
| 393 | 392 | if (*fence) { |
| 394 | 393 | ret = dma_fence_chain_find_seqno(fence, point); |
| 395 | 394 | if (!ret) |
| 396 | − return 0; | |
| 395 | + goto out; | |
| 397 | 396 | dma_fence_put(*fence); |
| 398 | 397 | } else { |
| 399 | 398 | ret = -EINVAL; |
| 400 | 399 | } |
| 401 | 400 | |
| 402 | 401 | if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT)) |
| 403 | − return ret; | |
| 402 | + goto out; | |
| 404 | 403 | |
| 405 | 404 | memset(&wait, 0, sizeof(wait)); |
| 406 | 405 | wait.task = current; |
| @@ -432,6 +431,9 @@ int drm_syncobj_find_fence(struct drm_file *file_private, · 25 unmodified lines | ||
| 432 | 431 | if (wait.node.next) |
| 433 | 432 | drm_syncobj_remove_wait(syncobj, &wait); |
| 434 | 433 | |
| 434 | +out: | |
| 435 | + drm_syncobj_put(syncobj); | |
| 436 | + | |
| 435 | 437 | return ret; |
| 436 | 438 | } |
| 437 | 439 | EXPORT_SYMBOL(drm_syncobj_find_fence); |
| @@ -38,6 +38,7 @@ i915-y += i915_drv.o \ · 37 unmodified lines | ||
| 38 | 38 | i915_config.o \ |
| 39 | 39 | i915_irq.o \ |
| 40 | 40 | i915_getparam.o \ |
| 41 | + i915_mitigations.o \ | |
| 41 | 42 | i915_params.o \ |
| 42 | 43 | i915_pci.o \ |
| 43 | 44 | i915_scatterlist.o \ |
| @@ -1616,10 +1616,6 @@ static void gen11_dsi_get_power_domains(struct intel_encoder *encoder, · 1615 unmodified lines | ||
| 1616 | 1616 | |
| 1617 | 1617 | get_dsi_io_power_domains(i915, |
| 1618 | 1618 | enc_to_intel_dsi(encoder)); |
| 1619 | − | |
| 1620 | − if (crtc_state->dsc.compression_enable) | |
| 1621 | − intel_display_power_get(i915, | |
| 1622 | − intel_dsc_power_domain(crtc_state)); | |
| 1623 | 1619 | } |
| 1624 | 1620 | |
| 1625 | 1621 | static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, |
| @@ -2754,13 +2754,15 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, · 2753 unmodified lines | ||
| 2754 | 2754 | int n_entries, ln; |
| 2755 | 2755 | u32 val; |
| 2756 | 2756 | |
| 2757 | + if (enc_to_dig_port(encoder)->tc_mode == TC_PORT_TBT_ALT) | |
| 2758 | + return; | |
| 2759 | + | |
| 2757 | 2760 | ddi_translations = icl_get_mg_buf_trans(encoder, crtc_state, &n_entries); |
| 2758 | − /* The table does not have values for level 3 and level 9. */ | |
| 2759 | − if (level >= n_entries || level == 3 || level == 9) { | |
| 2761 | + if (level >= n_entries) { | |
| 2760 | 2762 | drm_dbg_kms(&dev_priv->drm, |
| 2761 | 2763 | "DDI translation not found for level %d. Using %d instead.", |
| 2762 | − level, n_entries - 2); | |
| 2763 | − level = n_entries - 2; | |
| 2764 | + level, n_entries - 1); | |
| 2765 | + level = n_entries - 1; | |
| 2764 | 2766 | } |
| 2765 | 2767 | |
| 2766 | 2768 | /* Set MG_TX_LINK_PARAMS cri_use_fs32 to 0. */ |
| @@ -2891,6 +2893,9 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, · 124 unmodified lines | ||
| 2891 | 2893 | u32 val, dpcnt_mask, dpcnt_val; |
| 2892 | 2894 | int n_entries, ln; |
| 2893 | 2895 | |
| 2896 | + if (enc_to_dig_port(encoder)->tc_mode == TC_PORT_TBT_ALT) | |
| 2897 | + return; | |
| 2898 | + | |
| 2894 | 2899 | ddi_translations = tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries); |
| 2895 | 2900 | |
| 2896 | 2901 | if (level >= n_entries) |
| @@ -3532,6 +3537,23 @@ static void intel_ddi_disable_fec_state(struct intel_encoder *encoder, · 635 unmodified lines | ||
| 3532 | 3537 | intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); |
| 3533 | 3538 | } |
| 3534 | 3539 | |
| 3540 | +static void intel_ddi_power_up_lanes(struct intel_encoder *encoder, | |
| 3541 | + const struct intel_crtc_state *crtc_state) | |
| 3542 | +{ | |
| 3543 | + struct drm_i915_private *i915 = to_i915(encoder->base.dev); | |
| 3544 | + struct intel_digital_port *dig_port = enc_to_dig_port(encoder); | |
| 3545 | + enum phy phy = intel_port_to_phy(i915, encoder->port); | |
| 3546 | + | |
| 3547 | + if (intel_phy_is_combo(i915, phy)) { | |
| 3548 | + bool lane_reversal = | |
| 3549 | + dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL; | |
| 3550 | + | |
| 3551 | + intel_combo_phy_power_up_lanes(i915, phy, false, | |
| 3552 | + crtc_state->lane_count, | |
| 3553 | + lane_reversal); | |
| 3554 | + } | |
| 3555 | +} | |
| 3556 | + | |
| 3535 | 3557 | static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, |
| 3536 | 3558 | struct intel_encoder *encoder, |
| 3537 | 3559 | const struct intel_crtc_state *crtc_state, |
| @@ -3621,14 +3643,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, · 83 unmodified lines | ||
| 3621 | 3643 | * 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up |
| 3622 | 3644 | * the used lanes of the DDI. |
| 3623 | 3645 | */ |
| 3624 | − if (intel_phy_is_combo(dev_priv, phy)) { | |
| 3625 | − bool lane_reversal = | |
| 3626 | − dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL; | |
| 3627 | − | |
| 3628 | − intel_combo_phy_power_up_lanes(dev_priv, phy, false, | |
| 3629 | − crtc_state->lane_count, | |
| 3630 | − lane_reversal); | |
| 3631 | − } | |
| 3646 | + intel_ddi_power_up_lanes(encoder, crtc_state); | |
| 3632 | 3647 | |
| 3633 | 3648 | /* |
| 3634 | 3649 | * 7.g Configure and enable DDI_BUF_CTL |
| @@ -3713,19 +3728,12 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, · 78 unmodified lines | ||
| 3713 | 3728 | else |
| 3714 | 3729 | intel_prepare_dp_ddi_buffers(encoder, crtc_state); |
| 3715 | 3730 | |
| 3716 | − if (intel_phy_is_combo(dev_priv, phy)) { | |
| 3717 | − bool lane_reversal = | |
| 3718 | − dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL; | |
| 3719 | − | |
| 3720 | − intel_combo_phy_power_up_lanes(dev_priv, phy, false, | |
| 3721 | − crtc_state->lane_count, | |
| 3722 | − lane_reversal); | |
| 3723 | − } | |
| 3731 | + intel_ddi_power_up_lanes(encoder, crtc_state); | |
| 3724 | 3732 | |
| 3725 | 3733 | intel_ddi_init_dp_buf_reg(encoder, crtc_state); |
| 3726 | 3734 | if (!is_mst) |
| 3727 | 3735 | intel_dp_set_power(intel_dp, DP_SET_POWER_D0); |
| 3728 | − intel_dp_configure_protocol_converter(intel_dp); | |
| 3736 | + intel_dp_configure_protocol_converter(intel_dp, crtc_state); | |
| 3729 | 3737 | intel_dp_sink_set_decompression_state(intel_dp, crtc_state, |
| 3730 | 3738 | true); |
| 3731 | 3739 | intel_dp_sink_set_fec_ready(intel_dp, crtc_state); |
| @@ -4206,6 +4214,8 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state, · 474 unmodified lines | ||
| 4206 | 4214 | intel_de_write(dev_priv, reg, val); |
| 4207 | 4215 | } |
| 4208 | 4216 | |
| 4217 | + intel_ddi_power_up_lanes(encoder, crtc_state); | |
| 4218 | + | |
| 4209 | 4219 | /* In HDMI/DVI mode, the port width, and swing/emphasis values |
| 4210 | 4220 | * are ignored so nothing special needs to be done besides |
| 4211 | 4221 | * enabling the port. |
| @@ -2309,7 +2309,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, · 2308 unmodified lines | ||
| 2309 | 2309 | */ |
| 2310 | 2310 | ret = i915_vma_pin_fence(vma); |
| 2311 | 2311 | if (ret != 0 && INTEL_GEN(dev_priv) < 4) { |
| 2312 | − i915_gem_object_unpin_from_display_plane(vma); | |
| 2312 | + i915_vma_unpin(vma); | |
| 2313 | 2313 | vma = ERR_PTR(ret); |
| 2314 | 2314 | goto err; |
| 2315 | 2315 | } |
| @@ -2327,12 +2327,9 @@ err: · 11 unmodified lines | ||
| 2327 | 2327 | |
| 2328 | 2328 | void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags) |
| 2329 | 2329 | { |
| 2330 | − i915_gem_object_lock(vma->obj, NULL); | |
| 2331 | 2330 | if (flags & PLANE_HAS_FENCE) |
| 2332 | 2331 | i915_vma_unpin_fence(vma); |
| 2333 | − i915_gem_object_unpin_from_display_plane(vma); | |
| 2334 | − i915_gem_object_unlock(vma->obj); | |
| 2335 | − | |
| 2332 | + i915_vma_unpin(vma); | |
| 2336 | 2333 | i915_vma_put(vma); |
| 2337 | 2334 | } |
| 2338 | 2335 | |
| @@ -4807,6 +4804,8 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, · 2468 unmodified lines | ||
| 4807 | 4804 | plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE; |
| 4808 | 4805 | } else if (fb->format->is_yuv) { |
| 4809 | 4806 | plane_color_ctl |= PLANE_COLOR_INPUT_CSC_ENABLE; |
| 4807 | + if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) | |
| 4808 | + plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE; | |
| 4810 | 4809 | } |
| 4811 | 4810 | |
| 4812 | 4811 | return plane_color_ctl; |
| @@ -1436,6 +1436,9 @@ struct intel_dp { · 1435 unmodified lines | ||
| 1436 | 1436 | bool ycbcr_444_to_420; |
| 1437 | 1437 | } dfp; |
| 1438 | 1438 | |
| 1439 | + /* To control wakeup latency, e.g. for irq-driven dp aux transfers. */ | |
| 1440 | + struct pm_qos_request pm_qos; | |
| 1441 | + | |
| 1439 | 1442 | /* Display stream compression testing */ |
| 1440 | 1443 | bool force_dsc_en; |
| 1441 | 1444 | |
| @@ -1489,7 +1489,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp, · 1488 unmodified lines | ||
| 1489 | 1489 | * lowest possible wakeup latency and so prevent the cpu from going into |
| 1490 | 1490 | * deep sleep states. |
| 1491 | 1491 | */ |
| 1492 | − cpu_latency_qos_update_request(&i915->pm_qos, 0); | |
| 1492 | + cpu_latency_qos_update_request(&intel_dp->pm_qos, 0); | |
| 1493 | 1493 | |
| 1494 | 1494 | intel_dp_check_edp(intel_dp); |
| 1495 | 1495 | |
| @@ -1622,7 +1622,7 @@ done: · 126 unmodified lines | ||
| 1622 | 1622 | |
| 1623 | 1623 | ret = recv_bytes; |
| 1624 | 1624 | out: |
| 1625 | − cpu_latency_qos_update_request(&i915->pm_qos, PM_QOS_DEFAULT_VALUE); | |
| 1625 | + cpu_latency_qos_update_request(&intel_dp->pm_qos, PM_QOS_DEFAULT_VALUE); | |
| 1626 | 1626 | |
| 1627 | 1627 | if (vdd) |
| 1628 | 1628 | edp_panel_vdd_off(intel_dp, false); |
| @@ -1898,6 +1898,9 @@ static i915_reg_t tgl_aux_data_reg(struct intel_dp *intel_dp, int index) · 269 unmodified lines | ||
| 1898 | 1898 | static void |
| 1899 | 1899 | intel_dp_aux_fini(struct intel_dp *intel_dp) |
| 1900 | 1900 | { |
| 1901 | + if (cpu_latency_qos_request_active(&intel_dp->pm_qos)) | |
| 1902 | + cpu_latency_qos_remove_request(&intel_dp->pm_qos); | |
| 1903 | + | |
| 1901 | 1904 | kfree(intel_dp->aux.name); |
| 1902 | 1905 | } |
| 1903 | 1906 | |
| @@ -1950,6 +1953,7 @@ intel_dp_aux_init(struct intel_dp *intel_dp) · 46 unmodified lines | ||
| 1950 | 1953 | encoder->base.name); |
| 1951 | 1954 | |
| 1952 | 1955 | intel_dp->aux.transfer = intel_dp_aux_transfer; |
| 1956 | + cpu_latency_qos_add_request(&intel_dp->pm_qos, PM_QOS_DEFAULT_VALUE); | |
| 1953 | 1957 | } |
| 1954 | 1958 | |
| 1955 | 1959 | bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp) |
| @@ -4010,7 +4014,8 @@ static void intel_dp_enable_port(struct intel_dp *intel_dp, · 2054 unmodified lines | ||
| 4010 | 4014 | intel_de_posting_read(dev_priv, intel_dp->output_reg); |
| 4011 | 4015 | } |
| 4012 | 4016 | |
| 4013 | −void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp) | |
| 4017 | +void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp, | |
| 4018 | + const struct intel_crtc_state *crtc_state) | |
| 4014 | 4019 | { |
| 4015 | 4020 | struct drm_i915_private *i915 = dp_to_i915(intel_dp); |
| 4016 | 4021 | u8 tmp; |
| @@ -4029,8 +4034,8 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp) · 12 unmodified lines | ||
| 4029 | 4034 | drm_dbg_kms(&i915->drm, "Failed to set protocol converter HDMI mode to %s\n", |
| 4030 | 4035 | enableddisabled(intel_dp->has_hdmi_sink)); |
| 4031 | 4036 | |
| 4032 | − tmp = intel_dp->dfp.ycbcr_444_to_420 ? | |
| 4033 | − DP_CONVERSION_TO_YCBCR420_ENABLE : 0; | |
| 4037 | + tmp = crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 && | |
| 4038 | + intel_dp->dfp.ycbcr_444_to_420 ? DP_CONVERSION_TO_YCBCR420_ENABLE : 0; | |
| 4034 | 4039 | |
| 4035 | 4040 | if (drm_dp_dpcd_writeb(&intel_dp->aux, |
| 4036 | 4041 | DP_PROTOCOL_CONVERTER_CONTROL_1, tmp) != 1) |
| @@ -4084,7 +4089,7 @@ static void intel_enable_dp(struct intel_atomic_state *state, · 47 unmodified lines | ||
| 4084 | 4089 | } |
| 4085 | 4090 | |
| 4086 | 4091 | intel_dp_set_power(intel_dp, DP_SET_POWER_D0); |
| 4087 | − intel_dp_configure_protocol_converter(intel_dp); | |
| 4092 | + intel_dp_configure_protocol_converter(intel_dp, pipe_config); | |
| 4088 | 4093 | intel_dp_start_link_train(intel_dp, pipe_config); |
| 4089 | 4094 | intel_dp_stop_link_train(intel_dp, pipe_config); |
| 4090 | 4095 | |
| @@ -4632,24 +4637,6 @@ ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp, · 541 unmodified lines | ||
| 4632 | 4637 | intel_de_posting_read(dev_priv, intel_dp->output_reg); |
| 4633 | 4638 | } |
| 4634 | 4639 | |
| 4635 | −void intel_dp_set_signal_levels(struct intel_dp *intel_dp, | |
| 4636 | − const struct intel_crtc_state *crtc_state) | |
| 4637 | −{ | |
| 4638 | − struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 4639 | − u8 train_set = intel_dp->train_set[0]; | |
| 4640 | − | |
| 4641 | − drm_dbg_kms(&dev_priv->drm, "Using vswing level %d%s\n", | |
| 4642 | − train_set & DP_TRAIN_VOLTAGE_SWING_MASK, | |
| 4643 | − train_set & DP_TRAIN_MAX_SWING_REACHED ? " (max)" : ""); | |
| 4644 | − drm_dbg_kms(&dev_priv->drm, "Using pre-emphasis level %d%s\n", | |
| 4645 | − (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >> | |
| 4646 | − DP_TRAIN_PRE_EMPHASIS_SHIFT, | |
| 4647 | − train_set & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ? | |
| 4648 | − " (max)" : ""); | |
| 4649 | − | |
| 4650 | − intel_dp->set_signal_levels(intel_dp, crtc_state); | |
| 4651 | −} | |
| 4652 | − | |
| 4653 | 4640 | void |
| 4654 | 4641 | intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, |
| 4655 | 4642 | const struct intel_crtc_state *crtc_state, |
| @@ -5698,7 +5685,7 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp, · 1042 unmodified lines | ||
| 5698 | 5685 | |
| 5699 | 5686 | intel_dp_autotest_phy_ddi_disable(intel_dp, crtc_state); |
| 5700 | 5687 | |
| 5701 | − intel_dp_set_signal_levels(intel_dp, crtc_state); | |
| 5688 | + intel_dp_set_signal_levels(intel_dp, crtc_state, DP_PHY_DPRX); | |
| 5702 | 5689 | |
| 5703 | 5690 | intel_dp_phy_pattern_update(intel_dp, crtc_state); |
| 5704 | 5691 | |
| @@ -51,7 +51,8 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp, · 50 unmodified lines | ||
| 51 | 51 | int intel_dp_retrain_link(struct intel_encoder *encoder, |
| 52 | 52 | struct drm_modeset_acquire_ctx *ctx); |
| 53 | 53 | void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode); |
| 54 | −void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp); | |
| 54 | +void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp, | |
| 55 | + const struct intel_crtc_state *crtc_state); | |
| 55 | 56 | void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp, |
| 56 | 57 | const struct intel_crtc_state *crtc_state, |
| 57 | 58 | bool enable); |
| @@ -95,9 +96,6 @@ void · 37 unmodified lines | ||
| 95 | 96 | intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, |
| 96 | 97 | const struct intel_crtc_state *crtc_state, |
| 97 | 98 | u8 dp_train_pat); |
| 98 | −void | |
| 99 | −intel_dp_set_signal_levels(struct intel_dp *intel_dp, | |
| 100 | − const struct intel_crtc_state *crtc_state); | |
| 101 | 99 | void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, |
| 102 | 100 | u8 *link_bw, u8 *rate_select); |
| 103 | 101 | bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp); |
| @@ -334,6 +334,27 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, · 333 unmodified lines | ||
| 334 | 334 | return drm_dp_dpcd_write(&intel_dp->aux, reg, buf, len) == len; |
| 335 | 335 | } |
| 336 | 336 | |
| 337 | +void intel_dp_set_signal_levels(struct intel_dp *intel_dp, | |
| 338 | + const struct intel_crtc_state *crtc_state, | |
| 339 | + enum drm_dp_phy dp_phy) | |
| 340 | +{ | |
| 341 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 342 | + u8 train_set = intel_dp->train_set[0]; | |
| 343 | + char phy_name[10]; | |
| 344 | + | |
| 345 | + drm_dbg_kms(&dev_priv->drm, "Using vswing level %d%s, pre-emphasis level %d%s, at %s\n", | |
| 346 | + train_set & DP_TRAIN_VOLTAGE_SWING_MASK, | |
| 347 | + train_set & DP_TRAIN_MAX_SWING_REACHED ? " (max)" : "", | |
| 348 | + (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >> | |
| 349 | + DP_TRAIN_PRE_EMPHASIS_SHIFT, | |
| 350 | + train_set & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ? | |
| 351 | + " (max)" : "", | |
| 352 | + intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name))); | |
| 353 | + | |
| 354 | + if (intel_dp_phy_is_downstream_of_source(intel_dp, dp_phy)) | |
| 355 | + intel_dp->set_signal_levels(intel_dp, crtc_state); | |
| 356 | +} | |
| 357 | + | |
| 337 | 358 | static bool |
| 338 | 359 | intel_dp_reset_link_train(struct intel_dp *intel_dp, |
| 339 | 360 | const struct intel_crtc_state *crtc_state, |
| @@ -341,7 +362,7 @@ intel_dp_reset_link_train(struct intel_dp *intel_dp, · 1 unmodified line | ||
| 341 | 362 | u8 dp_train_pat) |
| 342 | 363 | { |
| 343 | 364 | memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set)); |
| 344 | − intel_dp_set_signal_levels(intel_dp, crtc_state); | |
| 365 | + intel_dp_set_signal_levels(intel_dp, crtc_state, dp_phy); | |
| 345 | 366 | return intel_dp_set_link_train(intel_dp, crtc_state, dp_phy, dp_train_pat); |
| 346 | 367 | } |
| 347 | 368 | |
| @@ -355,7 +376,7 @@ intel_dp_update_link_train(struct intel_dp *intel_dp, · 7 unmodified lines | ||
| 355 | 376 | DP_TRAINING_LANE0_SET_PHY_REPEATER(dp_phy); |
| 356 | 377 | int ret; |
| 357 | 378 | |
| 358 | − intel_dp_set_signal_levels(intel_dp, crtc_state); | |
| 379 | + intel_dp_set_signal_levels(intel_dp, crtc_state, dp_phy); | |
| 359 | 380 | |
| 360 | 381 | ret = drm_dp_dpcd_write(&intel_dp->aux, reg, |
| 361 | 382 | intel_dp->train_set, crtc_state->lane_count); |
| @@ -17,6 +17,9 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp, · 16 unmodified lines | ||
| 17 | 17 | const struct intel_crtc_state *crtc_state, |
| 18 | 18 | enum drm_dp_phy dp_phy, |
| 19 | 19 | const u8 link_status[DP_LINK_STATUS_SIZE]); |
| 20 | +void intel_dp_set_signal_levels(struct intel_dp *intel_dp, | |
| 21 | + const struct intel_crtc_state *crtc_state, | |
| 22 | + enum drm_dp_phy dp_phy); | |
| 20 | 23 | void intel_dp_start_link_train(struct intel_dp *intel_dp, |
| 21 | 24 | const struct intel_crtc_state *crtc_state); |
| 22 | 25 | void intel_dp_stop_link_train(struct intel_dp *intel_dp, |
| @@ -69,7 +69,9 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder, · 68 unmodified lines | ||
| 69 | 69 | |
| 70 | 70 | slots = drm_dp_atomic_find_vcpi_slots(state, &intel_dp->mst_mgr, |
| 71 | 71 | connector->port, |
| 72 | − crtc_state->pbn, 0); | |
| 72 | + crtc_state->pbn, | |
| 73 | + drm_dp_get_vc_payload_bw(crtc_state->port_clock, | |
| 74 | + crtc_state->lane_count)); | |
| 73 | 75 | if (slots == -EDEADLK) |
| 74 | 76 | return slots; |
| 75 | 77 | if (slots >= 0) |
| @@ -2210,6 +2210,7 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state, · 2209 unmodified lines | ||
| 2210 | 2210 | if (content_protection_type_changed) { |
| 2211 | 2211 | mutex_lock(&hdcp->mutex); |
| 2212 | 2212 | hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED; |
| 2213 | + drm_connector_get(&connector->base); | |
| 2213 | 2214 | schedule_work(&hdcp->prop_work); |
| 2214 | 2215 | mutex_unlock(&hdcp->mutex); |
| 2215 | 2216 | } |
| @@ -2221,6 +2222,14 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state, · 5 unmodified lines | ||
| 2221 | 2222 | desired_and_not_enabled = |
| 2222 | 2223 | hdcp->value != DRM_MODE_CONTENT_PROTECTION_ENABLED; |
| 2223 | 2224 | mutex_unlock(&hdcp->mutex); |
| 2225 | + /* | |
| 2226 | + * If HDCP already ENABLED and CP property is DESIRED, schedule | |
| 2227 | + * prop_work to update correct CP property to user space. | |
| 2228 | + */ | |
| 2229 | + if (!desired_and_not_enabled && !content_protection_type_changed) { | |
| 2230 | + drm_connector_get(&connector->base); | |
| 2231 | + schedule_work(&hdcp->prop_work); | |
| 2232 | + } | |
| 2224 | 2233 | } |
| 2225 | 2234 | |
| 2226 | 2235 | if (desired_and_not_enabled || content_protection_type_changed) |
| @@ -182,6 +182,7 @@ struct intel_overlay { · 181 unmodified lines | ||
| 182 | 182 | struct intel_crtc *crtc; |
| 183 | 183 | struct i915_vma *vma; |
| 184 | 184 | struct i915_vma *old_vma; |
| 185 | + struct intel_frontbuffer *frontbuffer; | |
| 185 | 186 | bool active; |
| 186 | 187 | bool pfit_active; |
| 187 | 188 | u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */ |
| @@ -282,21 +283,19 @@ static void intel_overlay_flip_prepare(struct intel_overlay *overlay, · 94 unmodified lines | ||
| 282 | 283 | struct i915_vma *vma) |
| 283 | 284 | { |
| 284 | 285 | enum pipe pipe = overlay->crtc->pipe; |
| 285 | − struct intel_frontbuffer *from = NULL, *to = NULL; | |
| 286 | + struct intel_frontbuffer *frontbuffer = NULL; | |
| 286 | 287 | |
| 287 | 288 | drm_WARN_ON(&overlay->i915->drm, overlay->old_vma); |
| 288 | 289 | |
| 289 | − if (overlay->vma) | |
| 290 | − from = intel_frontbuffer_get(overlay->vma->obj); | |
| 291 | 290 | if (vma) |
| 292 | − to = intel_frontbuffer_get(vma->obj); | |
| 291 | + frontbuffer = intel_frontbuffer_get(vma->obj); | |
| 293 | 292 | |
| 294 | − intel_frontbuffer_track(from, to, INTEL_FRONTBUFFER_OVERLAY(pipe)); | |
| 293 | + intel_frontbuffer_track(overlay->frontbuffer, frontbuffer, | |
| 294 | + INTEL_FRONTBUFFER_OVERLAY(pipe)); | |
| 295 | 295 | |
| 296 | − if (to) | |
| 297 | − intel_frontbuffer_put(to); | |
| 298 | − if (from) | |
| 299 | − intel_frontbuffer_put(from); | |
| 296 | + if (overlay->frontbuffer) | |
| 297 | + intel_frontbuffer_put(overlay->frontbuffer); | |
| 298 | + overlay->frontbuffer = frontbuffer; | |
| 300 | 299 | |
| 301 | 300 | intel_frontbuffer_flip_prepare(overlay->i915, |
| 302 | 301 | INTEL_FRONTBUFFER_OVERLAY(pipe)); |
| @@ -359,7 +358,7 @@ static void intel_overlay_release_old_vma(struct intel_overlay *overlay) · 56 unmodified lines | ||
| 359 | 358 | intel_frontbuffer_flip_complete(overlay->i915, |
| 360 | 359 | INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe)); |
| 361 | 360 | |
| 362 | − i915_gem_object_unpin_from_display_plane(vma); | |
| 361 | + i915_vma_unpin(vma); | |
| 363 | 362 | i915_vma_put(vma); |
| 364 | 363 | } |
| 365 | 364 | |
| @@ -860,7 +859,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, · 494 unmodified lines | ||
| 860 | 859 | return 0; |
| 861 | 860 | |
| 862 | 861 | out_unpin: |
| 863 | − i915_gem_object_unpin_from_display_plane(vma); | |
| 862 | + i915_vma_unpin(vma); | |
| 864 | 863 | out_pin_section: |
| 865 | 864 | atomic_dec(&dev_priv->gpu_error.pending_fb_pin); |
| 866 | 865 | |
| @@ -1650,16 +1650,13 @@ static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unus · 1649 unmodified lines | ||
| 1650 | 1650 | val = pch_get_backlight(connector); |
| 1651 | 1651 | else |
| 1652 | 1652 | val = lpt_get_backlight(connector); |
| 1653 | − val = intel_panel_compute_brightness(connector, val); | |
| 1654 | − panel->backlight.level = clamp(val, panel->backlight.min, | |
| 1655 | − panel->backlight.max); | |
| 1656 | 1653 | |
| 1657 | 1654 | if (cpu_mode) { |
| 1658 | 1655 | drm_dbg_kms(&dev_priv->drm, |
| 1659 | 1656 | "CPU backlight register was enabled, switching to PCH override\n"); |
| 1660 | 1657 | |
| 1661 | 1658 | /* Write converted CPU PWM value to PCH override register */ |
| 1662 | − lpt_set_backlight(connector->base.state, panel->backlight.level); | |
| 1659 | + lpt_set_backlight(connector->base.state, val); | |
| 1663 | 1660 | intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, |
| 1664 | 1661 | pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE); |
| 1665 | 1662 | |
| @@ -1667,6 +1664,10 @@ static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unus · 1 unmodified line | ||
| 1667 | 1664 | cpu_ctl2 & ~BLM_PWM_ENABLE); |
| 1668 | 1665 | } |
| 1669 | 1666 | |
| 1667 | + val = intel_panel_compute_brightness(connector, val); | |
| 1668 | + panel->backlight.level = clamp(val, panel->backlight.min, | |
| 1669 | + panel->backlight.max); | |
| 1670 | + | |
| 1670 | 1671 | return 0; |
| 1671 | 1672 | } |
| 1672 | 1673 | |
| @@ -618,13 +618,19 @@ skl_program_scaler(struct intel_plane *plane, · 617 unmodified lines | ||
| 618 | 618 | |
| 619 | 619 | /* Preoffset values for YUV to RGB Conversion */ |
| 620 | 620 | #define PREOFF_YUV_TO_RGB_HI 0x1800 |
| 621 | −#define PREOFF_YUV_TO_RGB_ME 0x1F00 | |
| 621 | +#define PREOFF_YUV_TO_RGB_ME 0x0000 | |
| 622 | 622 | #define PREOFF_YUV_TO_RGB_LO 0x1800 |
| 623 | 623 | |
| 624 | 624 | #define ROFF(x) (((x) & 0xffff) << 16) |
| 625 | 625 | #define GOFF(x) (((x) & 0xffff) << 0) |
| 626 | 626 | #define BOFF(x) (((x) & 0xffff) << 16) |
| 627 | 627 | |
| 628 | +/* | |
| 629 | + * Programs the input color space conversion stage for ICL HDR planes. | |
| 630 | + * Note that it is assumed that this stage always happens after YUV | |
| 631 | + * range correction. Thus, the input to this stage is assumed to be | |
| 632 | + * in full-range YCbCr. | |
| 633 | + */ | |
| 628 | 634 | static void |
| 629 | 635 | icl_program_input_csc(struct intel_plane *plane, |
| 630 | 636 | const struct intel_crtc_state *crtc_state, |
| @@ -672,52 +678,7 @@ icl_program_input_csc(struct intel_plane *plane, · 41 unmodified lines | ||
| 672 | 678 | 0x0, 0x7800, 0x7F10, |
| 673 | 679 | }, |
| 674 | 680 | }; |
| 675 | − | |
| 676 | − /* Matrix for Limited Range to Full Range Conversion */ | |
| 677 | − static const u16 input_csc_matrix_lr[][9] = { | |
| 678 | − /* | |
| 679 | − * BT.601 Limted range YCbCr -> full range RGB | |
| 680 | − * The matrix required is : | |
| 681 | − * [1.164384, 0.000, 1.596027, | |
| 682 | − * 1.164384, -0.39175, -0.812813, | |
| 683 | − * 1.164384, 2.017232, 0.0000] | |
| 684 | − */ | |
| 685 | − [DRM_COLOR_YCBCR_BT601] = { | |
| 686 | − 0x7CC8, 0x7950, 0x0, | |
| 687 | − 0x8D00, 0x7950, 0x9C88, | |
| 688 | − 0x0, 0x7950, 0x6810, | |
| 689 | − }, | |
| 690 | − /* | |
| 691 | − * BT.709 Limited range YCbCr -> full range RGB | |
| 692 | − * The matrix required is : | |
| 693 | − * [1.164384, 0.000, 1.792741, | |
| 694 | − * 1.164384, -0.213249, -0.532909, | |
| 695 | − * 1.164384, 2.112402, 0.0000] | |
| 696 | − */ | |
| 697 | − [DRM_COLOR_YCBCR_BT709] = { | |
| 698 | − 0x7E58, 0x7950, 0x0, | |
| 699 | − 0x8888, 0x7950, 0xADA8, | |
| 700 | − 0x0, 0x7950, 0x6870, | |
| 701 | − }, | |
| 702 | − /* | |
| 703 | − * BT.2020 Limited range YCbCr -> full range RGB | |
| 704 | − * The matrix required is : | |
| 705 | − * [1.164, 0.000, 1.678, | |
| 706 | − * 1.164, -0.1873, -0.6504, | |
| 707 | − * 1.164, 2.1417, 0.0000] | |
| 708 | − */ | |
| 709 | − [DRM_COLOR_YCBCR_BT2020] = { | |
| 710 | − 0x7D70, 0x7950, 0x0, | |
| 711 | − 0x8A68, 0x7950, 0xAC00, | |
| 712 | − 0x0, 0x7950, 0x6890, | |
| 713 | − }, | |
| 714 | − }; | |
| 715 | − const u16 *csc; | |
| 716 | − | |
| 717 | − if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) | |
| 718 | − csc = input_csc_matrix[plane_state->hw.color_encoding]; | |
| 719 | − else | |
| 720 | − csc = input_csc_matrix_lr[plane_state->hw.color_encoding]; | |
| 681 | + const u16 *csc = input_csc_matrix[plane_state->hw.color_encoding]; | |
| 721 | 682 | |
| 722 | 683 | intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0), |
| 723 | 684 | ROFF(csc[0]) | GOFF(csc[1])); |
| @@ -734,14 +695,8 @@ icl_program_input_csc(struct intel_plane *plane, · 10 unmodified lines | ||
| 734 | 695 | |
| 735 | 696 | intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0), |
| 736 | 697 | PREOFF_YUV_TO_RGB_HI); |
| 737 | − if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) | |
| 738 | − intel_de_write_fw(dev_priv, | |
| 739 | − PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), | |
| 740 | − 0); | |
| 741 | − else | |
| 742 | − intel_de_write_fw(dev_priv, | |
| 743 | − PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), | |
| 744 | − PREOFF_YUV_TO_RGB_ME); | |
| 698 | + intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), | |
| 699 | + PREOFF_YUV_TO_RGB_ME); | |
| 745 | 700 | intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2), |
| 746 | 701 | PREOFF_YUV_TO_RGB_LO); |
| 747 | 702 | intel_de_write_fw(dev_priv, |
| @@ -23,36 +23,6 @@ static const char *tc_port_mode_name(enum tc_port_mode mode) · 22 unmodified lines | ||
| 23 | 23 | return names[mode]; |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | −static void | |
| 27 | −tc_port_load_fia_params(struct drm_i915_private *i915, | |
| 28 | − struct intel_digital_port *dig_port) | |
| 29 | −{ | |
| 30 | − enum port port = dig_port->base.port; | |
| 31 | − enum tc_port tc_port = intel_port_to_tc(i915, port); | |
| 32 | − u32 modular_fia; | |
| 33 | − | |
| 34 | − if (INTEL_INFO(i915)->display.has_modular_fia) { | |
| 35 | − modular_fia = intel_uncore_read(&i915->uncore, | |
| 36 | − PORT_TX_DFLEXDPSP(FIA1)); | |
| 37 | − drm_WARN_ON(&i915->drm, modular_fia == 0xffffffff); | |
| 38 | − modular_fia &= MODULAR_FIA_MASK; | |
| 39 | − } else { | |
| 40 | − modular_fia = 0; | |
| 41 | − } | |
| 42 | − | |
| 43 | − /* | |
| 44 | − * Each Modular FIA instance houses 2 TC ports. In SOC that has more | |
| 45 | − * than two TC ports, there are multiple instances of Modular FIA. | |
| 46 | − */ | |
| 47 | − if (modular_fia) { | |
| 48 | − dig_port->tc_phy_fia = tc_port / 2; | |
| 49 | − dig_port->tc_phy_fia_idx = tc_port % 2; | |
| 50 | − } else { | |
| 51 | − dig_port->tc_phy_fia = FIA1; | |
| 52 | − dig_port->tc_phy_fia_idx = tc_port; | |
| 53 | − } | |
| 54 | −} | |
| 55 | − | |
| 56 | 26 | static enum intel_display_power_domain |
| 57 | 27 | tc_cold_get_power_domain(struct intel_digital_port *dig_port) |
| 58 | 28 | { |
| @@ -646,6 +616,43 @@ void intel_tc_port_put_link(struct intel_digital_port *dig_port) · 587 unmodified lines | ||
| 646 | 616 | mutex_unlock(&dig_port->tc_lock); |
| 647 | 617 | } |
| 648 | 618 | |
| 619 | +static bool | |
| 620 | +tc_has_modular_fia(struct drm_i915_private *i915, struct intel_digital_port *dig_port) | |
| 621 | +{ | |
| 622 | + intel_wakeref_t wakeref; | |
| 623 | + u32 val; | |
| 624 | + | |
| 625 | + if (!INTEL_INFO(i915)->display.has_modular_fia) | |
| 626 | + return false; | |
| 627 | + | |
| 628 | + wakeref = tc_cold_block(dig_port); | |
| 629 | + val = intel_uncore_read(&i915->uncore, PORT_TX_DFLEXDPSP(FIA1)); | |
| 630 | + tc_cold_unblock(dig_port, wakeref); | |
| 631 | + | |
| 632 | + drm_WARN_ON(&i915->drm, val == 0xffffffff); | |
| 633 | + | |
| 634 | + return val & MODULAR_FIA_MASK; | |
| 635 | +} | |
| 636 | + | |
| 637 | +static void | |
| 638 | +tc_port_load_fia_params(struct drm_i915_private *i915, struct intel_digital_port *dig_port) | |
| 639 | +{ | |
| 640 | + enum port port = dig_port->base.port; | |
| 641 | + enum tc_port tc_port = intel_port_to_tc(i915, port); | |
| 642 | + | |
| 643 | + /* | |
| 644 | + * Each Modular FIA instance houses 2 TC ports. In SOC that has more | |
| 645 | + * than two TC ports, there are multiple instances of Modular FIA. | |
| 646 | + */ | |
| 647 | + if (tc_has_modular_fia(i915, dig_port)) { | |
| 648 | + dig_port->tc_phy_fia = tc_port / 2; | |
| 649 | + dig_port->tc_phy_fia_idx = tc_port % 2; | |
| 650 | + } else { | |
| 651 | + dig_port->tc_phy_fia = FIA1; | |
| 652 | + dig_port->tc_phy_fia_idx = tc_port; | |
| 653 | + } | |
| 654 | +} | |
| 655 | + | |
| 649 | 656 | void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) |
| 650 | 657 | { |
| 651 | 658 | struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); |
| @@ -812,10 +812,20 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, · 811 unmodified lines | ||
| 812 | 812 | intel_dsi_prepare(encoder, pipe_config); |
| 813 | 813 | |
| 814 | 814 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_ON); |
| 815 | − intel_dsi_msleep(intel_dsi, intel_dsi->panel_on_delay); | |
| 816 | 815 | |
| 817 | − /* Deassert reset */ | |
| 818 | − intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); | |
| 816 | + /* | |
| 817 | + * Give the panel time to power-on and then deassert its reset. | |
| 818 | + * Depending on the VBT MIPI sequences version the deassert-seq | |
| 819 | + * may contain the necessary delay, intel_dsi_msleep() will skip | |
| 820 | + * the delay in that case. If there is no deassert-seq, then an | |
| 821 | + * unconditional msleep is used to give the panel time to power-on. | |
| 822 | + */ | |
| 823 | + if (dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET]) { | |
| 824 | + intel_dsi_msleep(intel_dsi, intel_dsi->panel_on_delay); | |
| 825 | + intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); | |
| 826 | + } else { | |
| 827 | + msleep(intel_dsi->panel_on_delay); | |
| 828 | + } | |
| 819 | 829 | |
| 820 | 830 | if (IS_GEMINILAKE(dev_priv)) { |
| 821 | 831 | glk_cold_boot = glk_dsi_enable_io(encoder); |
| @@ -387,48 +387,6 @@ err: · 386 unmodified lines | ||
| 387 | 387 | return vma; |
| 388 | 388 | } |
| 389 | 389 | |
| 390 | −static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj) | |
| 391 | −{ | |
| 392 | − struct drm_i915_private *i915 = to_i915(obj->base.dev); | |
| 393 | − struct i915_vma *vma; | |
| 394 | − | |
| 395 | − if (list_empty(&obj->vma.list)) | |
| 396 | − return; | |
| 397 | − | |
| 398 | − mutex_lock(&i915->ggtt.vm.mutex); | |
| 399 | − spin_lock(&obj->vma.lock); | |
| 400 | − for_each_ggtt_vma(vma, obj) { | |
| 401 | − if (!drm_mm_node_allocated(&vma->node)) | |
| 402 | − continue; | |
| 403 | − | |
| 404 | − GEM_BUG_ON(vma->vm != &i915->ggtt.vm); | |
| 405 | − list_move_tail(&vma->vm_link, &vma->vm->bound_list); | |
| 406 | − } | |
| 407 | − spin_unlock(&obj->vma.lock); | |
| 408 | − mutex_unlock(&i915->ggtt.vm.mutex); | |
| 409 | − | |
| 410 | − if (i915_gem_object_is_shrinkable(obj)) { | |
| 411 | − unsigned long flags; | |
| 412 | − | |
| 413 | − spin_lock_irqsave(&i915->mm.obj_lock, flags); | |
| 414 | − | |
| 415 | − if (obj->mm.madv == I915_MADV_WILLNEED && | |
| 416 | − !atomic_read(&obj->mm.shrink_pin)) | |
| 417 | − list_move_tail(&obj->mm.link, &i915->mm.shrink_list); | |
| 418 | − | |
| 419 | − spin_unlock_irqrestore(&i915->mm.obj_lock, flags); | |
| 420 | − } | |
| 421 | −} | |
| 422 | − | |
| 423 | −void | |
| 424 | −i915_gem_object_unpin_from_display_plane(struct i915_vma *vma) | |
| 425 | −{ | |
| 426 | − /* Bump the LRU to try and avoid premature eviction whilst flipping */ | |
| 427 | − i915_gem_object_bump_inactive_ggtt(vma->obj); | |
| 428 | − | |
| 429 | − i915_vma_unpin(vma); | |
| 430 | −} | |
| 431 | − | |
| 432 | 390 | /** |
| 433 | 391 | * Moves a single object to the CPU read, and possibly write domain. |
| 434 | 392 | * @obj: object to act on |
| @@ -569,9 +527,6 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, · 134 unmodified lines | ||
| 569 | 527 | else |
| 570 | 528 | err = i915_gem_object_set_to_cpu_domain(obj, write_domain); |
| 571 | 529 | |
| 572 | − /* And bump the LRU for this access */ | |
| 573 | − i915_gem_object_bump_inactive_ggtt(obj); | |
| 574 | − | |
| 575 | 530 | i915_gem_object_unlock(obj); |
| 576 | 531 | |
| 577 | 532 | if (write_domain) |
| @@ -1046,7 +1046,7 @@ static void reloc_gpu_flush(struct i915_execbuffer *eb, struct reloc_cache *cach · 1045 unmodified lines | ||
| 1046 | 1046 | GEM_BUG_ON(cache->rq_size >= obj->base.size / sizeof(u32)); |
| 1047 | 1047 | cache->rq_cmd[cache->rq_size] = MI_BATCH_BUFFER_END; |
| 1048 | 1048 | |
| 1049 | − __i915_gem_object_flush_map(obj, 0, sizeof(u32) * (cache->rq_size + 1)); | |
| 1049 | + i915_gem_object_flush_map(obj); | |
| 1050 | 1050 | i915_gem_object_unpin_map(obj); |
| 1051 | 1051 | |
| 1052 | 1052 | intel_gt_chipset_flush(cache->rq->engine->gt); |
| @@ -1296,6 +1296,8 @@ static int __reloc_gpu_alloc(struct i915_execbuffer *eb, · 243 unmodified lines | ||
| 1296 | 1296 | goto err_pool; |
| 1297 | 1297 | } |
| 1298 | 1298 | |
| 1299 | + memset32(cmd, 0, pool->obj->base.size / sizeof(u32)); | |
| 1300 | + | |
| 1299 | 1301 | batch = i915_vma_instance(pool->obj, vma->vm, NULL); |
| 1300 | 1302 | if (IS_ERR(batch)) { |
| 1301 | 1303 | err = PTR_ERR(batch); |
| @@ -486,7 +486,6 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, · 485 unmodified lines | ||
| 486 | 486 | u32 alignment, |
| 487 | 487 | const struct i915_ggtt_view *view, |
| 488 | 488 | unsigned int flags); |
| 489 | −void i915_gem_object_unpin_from_display_plane(struct i915_vma *vma); | |
| 490 | 489 | |
| 491 | 490 | void i915_gem_object_make_unshrinkable(struct drm_i915_gem_object *obj); |
| 492 | 491 | void i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj); |
| @@ -7,8 +7,6 @@ · 6 unmodified lines | ||
| 7 | 7 | #include "i915_drv.h" |
| 8 | 8 | #include "intel_gpu_commands.h" |
| 9 | 9 | |
| 10 | −#define MAX_URB_ENTRIES 64 | |
| 11 | −#define STATE_SIZE (4 * 1024) | |
| 12 | 10 | #define GT3_INLINE_DATA_DELAYS 0x1E00 |
| 13 | 11 | #define batch_advance(Y, CS) GEM_BUG_ON((Y)->end != (CS)) |
| 14 | 12 | |
| @@ -34,38 +32,59 @@ struct batch_chunk { · 19 unmodified lines | ||
| 34 | 32 | }; |
| 35 | 33 | |
| 36 | 34 | struct batch_vals { |
| 37 | − u32 max_primitives; | |
| 38 | − u32 max_urb_entries; | |
| 39 | − u32 cmd_size; | |
| 40 | − u32 state_size; | |
| 35 | + u32 max_threads; | |
| 41 | 36 | u32 state_start; |
| 42 | − u32 batch_size; | |
| 37 | + u32 surface_start; | |
| 43 | 38 | u32 surface_height; |
| 44 | 39 | u32 surface_width; |
| 45 | − u32 scratch_size; | |
| 46 | − u32 max_size; | |
| 40 | + u32 size; | |
| 47 | 41 | }; |
| 48 | 42 | |
| 43 | +static inline int num_primitives(const struct batch_vals *bv) | |
| 44 | +{ | |
| 45 | + /* | |
| 46 | + * We need to saturate the GPU with work in order to dispatch | |
| 47 | + * a shader on every HW thread, and clear the thread-local registers. | |
| 48 | + * In short, we have to dispatch work faster than the shaders can | |
| 49 | + * run in order to fill the EU and occupy each HW thread. | |
| 50 | + */ | |
| 51 | + return bv->max_threads; | |
| 52 | +} | |
| 53 | + | |
| 49 | 54 | static void |
| 50 | 55 | batch_get_defaults(struct drm_i915_private *i915, struct batch_vals *bv) |
| 51 | 56 | { |
| 52 | 57 | if (IS_HASWELL(i915)) { |
| 53 | − bv->max_primitives = 280; | |
| 54 | − bv->max_urb_entries = MAX_URB_ENTRIES; | |
| 58 | + switch (INTEL_INFO(i915)->gt) { | |
| 59 | + default: | |
| 60 | + case 1: | |
| 61 | + bv->max_threads = 70; | |
| 62 | + break; | |
| 63 | + case 2: | |
| 64 | + bv->max_threads = 140; | |
| 65 | + break; | |
| 66 | + case 3: | |
| 67 | + bv->max_threads = 280; | |
| 68 | + break; | |
| 69 | + } | |
| 55 | 70 | bv->surface_height = 16 * 16; |
| 56 | 71 | bv->surface_width = 32 * 2 * 16; |
| 57 | 72 | } else { |
| 58 | − bv->max_primitives = 128; | |
| 59 | − bv->max_urb_entries = MAX_URB_ENTRIES / 2; | |
| 73 | + switch (INTEL_INFO(i915)->gt) { | |
| 74 | + default: | |
| 75 | + case 1: /* including vlv */ | |
| 76 | + bv->max_threads = 36; | |
| 77 | + break; | |
| 78 | + case 2: | |
| 79 | + bv->max_threads = 128; | |
| 80 | + break; | |
| 81 | + } | |
| 60 | 82 | bv->surface_height = 16 * 8; |
| 61 | 83 | bv->surface_width = 32 * 16; |
| 62 | 84 | } |
| 63 | − bv->cmd_size = bv->max_primitives * 4096; | |
| 64 | − bv->state_size = STATE_SIZE; | |
| 65 | − bv->state_start = bv->cmd_size; | |
| 66 | − bv->batch_size = bv->cmd_size + bv->state_size; | |
| 67 | − bv->scratch_size = bv->surface_height * bv->surface_width; | |
| 68 | − bv->max_size = bv->batch_size + bv->scratch_size; | |
| 85 | + bv->state_start = round_up(SZ_1K + num_primitives(bv) * 64, SZ_4K); | |
| 86 | + bv->surface_start = bv->state_start + SZ_4K; | |
| 87 | + bv->size = bv->surface_start + bv->surface_height * bv->surface_width; | |
| 69 | 88 | } |
| 70 | 89 | |
| 71 | 90 | static void batch_init(struct batch_chunk *bc, |
| @@ -155,7 +174,8 @@ static u32 · 83 unmodified lines | ||
| 155 | 174 | gen7_fill_binding_table(struct batch_chunk *state, |
| 156 | 175 | const struct batch_vals *bv) |
| 157 | 176 | { |
| 158 | − u32 surface_start = gen7_fill_surface_state(state, bv->batch_size, bv); | |
| 177 | + u32 surface_start = | |
| 178 | + gen7_fill_surface_state(state, bv->surface_start, bv); | |
| 159 | 179 | u32 *cs = batch_alloc_items(state, 32, 8); |
| 160 | 180 | u32 offset = batch_offset(state, cs); |
| 161 | 181 | |
| @@ -214,9 +234,9 @@ static void · 52 unmodified lines | ||
| 214 | 234 | gen7_emit_state_base_address(struct batch_chunk *batch, |
| 215 | 235 | u32 surface_state_base) |
| 216 | 236 | { |
| 217 | − u32 *cs = batch_alloc_items(batch, 0, 12); | |
| 237 | + u32 *cs = batch_alloc_items(batch, 0, 10); | |
| 218 | 238 | |
| 219 | − *cs++ = STATE_BASE_ADDRESS | (12 - 2); | |
| 239 | + *cs++ = STATE_BASE_ADDRESS | (10 - 2); | |
| 220 | 240 | /* general */ |
| 221 | 241 | *cs++ = batch_addr(batch) | BASE_ADDRESS_MODIFY; |
| 222 | 242 | /* surface */ |
| @@ -233,8 +253,6 @@ gen7_emit_state_base_address(struct batch_chunk *batch, · 10 unmodified lines | ||
| 233 | 253 | *cs++ = BASE_ADDRESS_MODIFY; |
| 234 | 254 | *cs++ = 0; |
| 235 | 255 | *cs++ = BASE_ADDRESS_MODIFY; |
| 236 | − *cs++ = 0; | |
| 237 | − *cs++ = 0; | |
| 238 | 256 | batch_advance(batch, cs); |
| 239 | 257 | } |
| 240 | 258 | |
| @@ -244,8 +262,7 @@ gen7_emit_vfe_state(struct batch_chunk *batch, · 3 unmodified lines | ||
| 244 | 262 | u32 urb_size, u32 curbe_size, |
| 245 | 263 | u32 mode) |
| 246 | 264 | { |
| 247 | − u32 urb_entries = bv->max_urb_entries; | |
| 248 | − u32 threads = bv->max_primitives - 1; | |
| 265 | + u32 threads = bv->max_threads - 1; | |
| 249 | 266 | u32 *cs = batch_alloc_items(batch, 32, 8); |
| 250 | 267 | |
| 251 | 268 | *cs++ = MEDIA_VFE_STATE | (8 - 2); |
| @@ -254,7 +271,7 @@ gen7_emit_vfe_state(struct batch_chunk *batch, · 2 unmodified lines | ||
| 254 | 271 | *cs++ = 0; |
| 255 | 272 | |
| 256 | 273 | /* number of threads & urb entries for GPGPU vs Media Mode */ |
| 257 | − *cs++ = threads << 16 | urb_entries << 8 | mode << 2; | |
| 274 | + *cs++ = threads << 16 | 1 << 8 | mode << 2; | |
| 258 | 275 | |
| 259 | 276 | *cs++ = 0; |
| 260 | 277 | |
| @@ -293,17 +310,12 @@ gen7_emit_media_object(struct batch_chunk *batch, · 32 unmodified lines | ||
| 293 | 310 | { |
| 294 | 311 | unsigned int x_offset = (media_object_index % 16) * 64; |
| 295 | 312 | unsigned int y_offset = (media_object_index / 16) * 16; |
| 296 | − unsigned int inline_data_size; | |
| 297 | − unsigned int media_batch_size; | |
| 298 | − unsigned int i; | |
| 313 | + unsigned int pkt = 6 + 3; | |
| 299 | 314 | u32 *cs; |
| 300 | 315 | |
| 301 | − inline_data_size = 112 * 8; | |
| 302 | − media_batch_size = inline_data_size + 6; | |
| 303 | − | |
| 304 | − cs = batch_alloc_items(batch, 8, media_batch_size); | |
| 316 | + cs = batch_alloc_items(batch, 8, pkt); | |
| 305 | 317 | |
| 306 | − *cs++ = MEDIA_OBJECT | (media_batch_size - 2); | |
| 318 | + *cs++ = MEDIA_OBJECT | (pkt - 2); | |
| 307 | 319 | |
| 308 | 320 | /* interface descriptor offset */ |
| 309 | 321 | *cs++ = 0; |
| @@ -317,25 +329,44 @@ gen7_emit_media_object(struct batch_chunk *batch, · 7 unmodified lines | ||
| 317 | 329 | *cs++ = 0; |
| 318 | 330 | |
| 319 | 331 | /* inline */ |
| 320 | − *cs++ = (y_offset << 16) | (x_offset); | |
| 332 | + *cs++ = y_offset << 16 | x_offset; | |
| 321 | 333 | *cs++ = 0; |
| 322 | 334 | *cs++ = GT3_INLINE_DATA_DELAYS; |
| 323 | − for (i = 3; i < inline_data_size; i++) | |
| 324 | − *cs++ = 0; | |
| 325 | 335 | |
| 326 | 336 | batch_advance(batch, cs); |
| 327 | 337 | } |
| 328 | 338 | |
| 329 | 339 | static void gen7_emit_pipeline_flush(struct batch_chunk *batch) |
| 330 | 340 | { |
| 331 | − u32 *cs = batch_alloc_items(batch, 0, 5); | |
| 341 | + u32 *cs = batch_alloc_items(batch, 0, 4); | |
| 332 | 342 | |
| 333 | − *cs++ = GFX_OP_PIPE_CONTROL(5); | |
| 334 | − *cs++ = PIPE_CONTROL_STATE_CACHE_INVALIDATE | | |
| 335 | − PIPE_CONTROL_GLOBAL_GTT_IVB; | |
| 343 | + *cs++ = GFX_OP_PIPE_CONTROL(4); | |
| 344 | + *cs++ = PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH | | |
| 345 | + PIPE_CONTROL_DEPTH_CACHE_FLUSH | | |
| 346 | + PIPE_CONTROL_DC_FLUSH_ENABLE | | |
| 347 | + PIPE_CONTROL_CS_STALL; | |
| 336 | 348 | *cs++ = 0; |
| 337 | 349 | *cs++ = 0; |
| 350 | + | |
| 351 | + batch_advance(batch, cs); | |
| 352 | +} | |
| 353 | + | |
| 354 | +static void gen7_emit_pipeline_invalidate(struct batch_chunk *batch) | |
| 355 | +{ | |
| 356 | + u32 *cs = batch_alloc_items(batch, 0, 8); | |
| 357 | + | |
| 358 | + /* ivb: Stall before STATE_CACHE_INVALIDATE */ | |
| 359 | + *cs++ = GFX_OP_PIPE_CONTROL(4); | |
| 360 | + *cs++ = PIPE_CONTROL_STALL_AT_SCOREBOARD | | |
| 361 | + PIPE_CONTROL_CS_STALL; | |
| 362 | + *cs++ = 0; | |
| 363 | + *cs++ = 0; | |
| 364 | + | |
| 365 | + *cs++ = GFX_OP_PIPE_CONTROL(4); | |
| 366 | + *cs++ = PIPE_CONTROL_STATE_CACHE_INVALIDATE; | |
| 338 | 367 | *cs++ = 0; |
| 368 | + *cs++ = 0; | |
| 369 | + | |
| 339 | 370 | batch_advance(batch, cs); |
| 340 | 371 | } |
| 341 | 372 | |
| @@ -344,34 +375,46 @@ static void emit_batch(struct i915_vma * const vma, · 2 unmodified lines | ||
| 344 | 375 | const struct batch_vals *bv) |
| 345 | 376 | { |
| 346 | 377 | struct drm_i915_private *i915 = vma->vm->i915; |
| 347 | − unsigned int desc_count = 64; | |
| 348 | − const u32 urb_size = 112; | |
| 378 | + const unsigned int desc_count = 1; | |
| 379 | + const unsigned int urb_size = 1; | |
| 349 | 380 | struct batch_chunk cmds, state; |
| 350 | − u32 interface_descriptor; | |
| 381 | + u32 descriptors; | |
| 351 | 382 | unsigned int i; |
| 352 | 383 | |
| 353 | − batch_init(&cmds, vma, start, 0, bv->cmd_size); | |
| 354 | − batch_init(&state, vma, start, bv->state_start, bv->state_size); | |
| 355 | − | |
| 356 | − interface_descriptor = | |
| 357 | − gen7_fill_interface_descriptor(&state, bv, | |
| 358 | − IS_HASWELL(i915) ? | |
| 359 | − &cb_kernel_hsw : | |
| 360 | − &cb_kernel_ivb, | |
| 361 | − desc_count); | |
| 384 | + batch_init(&cmds, vma, start, 0, bv->state_start); | |
| 385 | + batch_init(&state, vma, start, bv->state_start, SZ_4K); | |
| 386 | + | |
| 387 | + descriptors = gen7_fill_interface_descriptor(&state, bv, | |
| 388 | + IS_HASWELL(i915) ? | |
| 389 | + &cb_kernel_hsw : | |
| 390 | + &cb_kernel_ivb, | |
| 391 | + desc_count); | |
| 392 | + | |
| 393 | + /* Reset inherited context registers */ | |
| 394 | + gen7_emit_pipeline_invalidate(&cmds); | |
| 395 | + batch_add(&cmds, MI_LOAD_REGISTER_IMM(2)); | |
| 396 | + batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_0_GEN7)); | |
| 397 | + batch_add(&cmds, 0xffff0000); | |
| 398 | + batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_1)); | |
| 399 | + batch_add(&cmds, 0xffff0000 | PIXEL_SUBSPAN_COLLECT_OPT_DISABLE); | |
| 362 | 400 | gen7_emit_pipeline_flush(&cmds); |
| 401 | + | |
| 402 | + /* Switch to the media pipeline and our base address */ | |
| 403 | + gen7_emit_pipeline_invalidate(&cmds); | |
| 363 | 404 | batch_add(&cmds, PIPELINE_SELECT | PIPELINE_SELECT_MEDIA); |
| 364 | 405 | batch_add(&cmds, MI_NOOP); |
| 365 | − gen7_emit_state_base_address(&cmds, interface_descriptor); | |
| 406 | + gen7_emit_pipeline_invalidate(&cmds); | |
| 407 | + | |
| 366 | 408 | gen7_emit_pipeline_flush(&cmds); |
| 409 | + gen7_emit_state_base_address(&cmds, descriptors); | |
| 410 | + gen7_emit_pipeline_invalidate(&cmds); | |
| 367 | 411 | |
| 412 | + /* Set the clear-residual kernel state */ | |
| 368 | 413 | gen7_emit_vfe_state(&cmds, bv, urb_size - 1, 0, 0); |
| 414 | + gen7_emit_interface_descriptor_load(&cmds, descriptors, desc_count); | |
| 369 | 415 | |
| 370 | − gen7_emit_interface_descriptor_load(&cmds, | |
| 371 | − interface_descriptor, | |
| 372 | − desc_count); | |
| 373 | − | |
| 374 | − for (i = 0; i < bv->max_primitives; i++) | |
| 416 | + /* Execute the kernel on all HW threads */ | |
| 417 | + for (i = 0; i < num_primitives(bv); i++) | |
| 375 | 418 | gen7_emit_media_object(&cmds, i); |
| 376 | 419 | |
| 377 | 420 | batch_add(&cmds, MI_BATCH_BUFFER_END); |
| @@ -385,15 +428,15 @@ int gen7_setup_clear_gpr_bb(struct intel_engine_cs * const engine, · 7 unmodified lines | ||
| 385 | 428 | |
| 386 | 429 | batch_get_defaults(engine->i915, &bv); |
| 387 | 430 | if (!vma) |
| 388 | − return bv.max_size; | |
| 431 | + return bv.size; | |
| 389 | 432 | |
| 390 | − GEM_BUG_ON(vma->obj->base.size < bv.max_size); | |
| 433 | + GEM_BUG_ON(vma->obj->base.size < bv.size); | |
| 391 | 434 | |
| 392 | 435 | batch = i915_gem_object_pin_map(vma->obj, I915_MAP_WC); |
| 393 | 436 | if (IS_ERR(batch)) |
| 394 | 437 | return PTR_ERR(batch); |
| 395 | 438 | |
| 396 | − emit_batch(vma, memset(batch, 0, bv.max_size), &bv); | |
| 439 | + emit_batch(vma, memset(batch, 0, bv.size), &bv); | |
| 397 | 440 | |
| 398 | 441 | i915_gem_object_flush_map(vma->obj); |
| 399 | 442 | __i915_gem_object_release_map(vma->obj); |
| @@ -134,11 +134,6 @@ static bool remove_signaling_context(struct intel_breadcrumbs *b, · 133 unmodified lines | ||
| 134 | 134 | return true; |
| 135 | 135 | } |
| 136 | 136 | |
| 137 | −static inline bool __request_completed(const struct i915_request *rq) | |
| 138 | −{ | |
| 139 | − return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno); | |
| 140 | −} | |
| 141 | − | |
| 142 | 137 | __maybe_unused static bool |
| 143 | 138 | check_signal_order(struct intel_context *ce, struct i915_request *rq) |
| 144 | 139 | { |
| @@ -192,18 +187,6 @@ static void add_retire(struct intel_breadcrumbs *b, struct intel_timeline *tl) · 47 unmodified lines | ||
| 192 | 187 | intel_engine_add_retire(b->irq_engine, tl); |
| 193 | 188 | } |
| 194 | 189 | |
| 195 | −static bool __signal_request(struct i915_request *rq) | |
| 196 | −{ | |
| 197 | − GEM_BUG_ON(test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)); | |
| 198 | − | |
| 199 | − if (!__dma_fence_signal(&rq->fence)) { | |
| 200 | − i915_request_put(rq); | |
| 201 | − return false; | |
| 202 | − } | |
| 203 | − | |
| 204 | − return true; | |
| 205 | −} | |
| 206 | − | |
| 207 | 190 | static struct llist_node * |
| 208 | 191 | slist_add(struct llist_node *node, struct llist_node *head) |
| 209 | 192 | { |
| @@ -257,7 +240,7 @@ static void signal_irq_work(struct irq_work *work) · 47 unmodified lines | ||
| 257 | 240 | list_for_each_entry_rcu(rq, &ce->signals, signal_link) { |
| 258 | 241 | bool release; |
| 259 | 242 | |
| 260 | − if (!__request_completed(rq)) | |
| 243 | + if (!__i915_request_is_complete(rq)) | |
| 261 | 244 | break; |
| 262 | 245 | |
| 263 | 246 | if (!test_and_clear_bit(I915_FENCE_FLAG_SIGNAL, |
| @@ -274,9 +257,11 @@ static void signal_irq_work(struct irq_work *work) · 10 unmodified lines | ||
| 274 | 257 | release = remove_signaling_context(b, ce); |
| 275 | 258 | spin_unlock(&ce->signal_lock); |
| 276 | 259 | |
| 277 | − if (__signal_request(rq)) | |
| 260 | + if (__dma_fence_signal(&rq->fence)) | |
| 278 | 261 | /* We own signal_node now, xfer to local list */ |
| 279 | 262 | signal = slist_add(&rq->signal_node, signal); |
| 263 | + else | |
| 264 | + i915_request_put(rq); | |
| 280 | 265 | |
| 281 | 266 | if (release) { |
| 282 | 267 | add_retire(b, ce->timeline); |
| @@ -363,6 +348,17 @@ void intel_breadcrumbs_free(struct intel_breadcrumbs *b) · 80 unmodified lines | ||
| 363 | 348 | kfree(b); |
| 364 | 349 | } |
| 365 | 350 | |
| 351 | +static void irq_signal_request(struct i915_request *rq, | |
| 352 | + struct intel_breadcrumbs *b) | |
| 353 | +{ | |
| 354 | + if (!__dma_fence_signal(&rq->fence)) | |
| 355 | + return; | |
| 356 | + | |
| 357 | + i915_request_get(rq); | |
| 358 | + if (llist_add(&rq->signal_node, &b->signaled_requests)) | |
| 359 | + irq_work_queue(&b->irq_work); | |
| 360 | +} | |
| 361 | + | |
| 366 | 362 | static void insert_breadcrumb(struct i915_request *rq) |
| 367 | 363 | { |
| 368 | 364 | struct intel_breadcrumbs *b = READ_ONCE(rq->engine)->breadcrumbs; |
| @@ -372,17 +368,13 @@ static void insert_breadcrumb(struct i915_request *rq) · 3 unmodified lines | ||
| 372 | 368 | if (test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) |
| 373 | 369 | return; |
| 374 | 370 | |
| 375 | − i915_request_get(rq); | |
| 376 | − | |
| 377 | 371 | /* |
| 378 | 372 | * If the request is already completed, we can transfer it |
| 379 | 373 | * straight onto a signaled list, and queue the irq worker for |
| 380 | 374 | * its signal completion. |
| 381 | 375 | */ |
| 382 | − if (__request_completed(rq)) { | |
| 383 | − if (__signal_request(rq) && | |
| 384 | − llist_add(&rq->signal_node, &b->signaled_requests)) | |
| 385 | − irq_work_queue(&b->irq_work); | |
| 376 | + if (__i915_request_is_complete(rq)) { | |
| 377 | + irq_signal_request(rq, b); | |
| 386 | 378 | return; |
| 387 | 379 | } |
| 388 | 380 | |
| @@ -413,6 +405,8 @@ static void insert_breadcrumb(struct i915_request *rq) · 24 unmodified lines | ||
| 413 | 405 | break; |
| 414 | 406 | } |
| 415 | 407 | } |
| 408 | + | |
| 409 | + i915_request_get(rq); | |
| 416 | 410 | list_add_rcu(&rq->signal_link, pos); |
| 417 | 411 | GEM_BUG_ON(!check_signal_order(ce, rq)); |
| 418 | 412 | GEM_BUG_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags)); |
| @@ -453,19 +447,25 @@ bool i915_request_enable_breadcrumb(struct i915_request *rq) · 34 unmodified lines | ||
| 453 | 447 | |
| 454 | 448 | void i915_request_cancel_breadcrumb(struct i915_request *rq) |
| 455 | 449 | { |
| 450 | + struct intel_breadcrumbs *b = READ_ONCE(rq->engine)->breadcrumbs; | |
| 456 | 451 | struct intel_context *ce = rq->context; |
| 457 | 452 | bool release; |
| 458 | 453 | |
| 459 | − if (!test_and_clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) | |
| 454 | + spin_lock(&ce->signal_lock); | |
| 455 | + if (!test_and_clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) { | |
| 456 | + spin_unlock(&ce->signal_lock); | |
| 460 | 457 | return; |
| 458 | + } | |
| 461 | 459 | |
| 462 | − spin_lock(&ce->signal_lock); | |
| 463 | 460 | list_del_rcu(&rq->signal_link); |
| 464 | − release = remove_signaling_context(rq->engine->breadcrumbs, ce); | |
| 461 | + release = remove_signaling_context(b, ce); | |
| 465 | 462 | spin_unlock(&ce->signal_lock); |
| 466 | 463 | if (release) |
| 467 | 464 | intel_context_put(ce); |
| 468 | 465 | |
| 466 | + if (__i915_request_is_complete(rq)) | |
| 467 | + irq_signal_request(rq, b); | |
| 468 | + | |
| 469 | 469 | i915_request_put(rq); |
| 470 | 470 | } |
| 471 | 471 | |
| @@ -526,16 +526,39 @@ static int init_ggtt(struct i915_ggtt *ggtt) · 525 unmodified lines | ||
| 526 | 526 | |
| 527 | 527 | mutex_init(&ggtt->error_mutex); |
| 528 | 528 | if (ggtt->mappable_end) { |
| 529 | − /* Reserve a mappable slot for our lockless error capture */ | |
| 530 | − ret = drm_mm_insert_node_in_range(&ggtt->vm.mm, | |
| 531 | − &ggtt->error_capture, | |
| 532 | − PAGE_SIZE, 0, | |
| 533 | − I915_COLOR_UNEVICTABLE, | |
| 534 | − 0, ggtt->mappable_end, | |
| 535 | − DRM_MM_INSERT_LOW); | |
| 536 | − if (ret) | |
| 537 | − return ret; | |
| 529 | + /* | |
| 530 | + * Reserve a mappable slot for our lockless error capture. | |
| 531 | + * | |
| 532 | + * We strongly prefer taking address 0x0 in order to protect | |
| 533 | + * other critical buffers against accidental overwrites, | |
| 534 | + * as writing to address 0 is a very common mistake. | |
| 535 | + * | |
| 536 | + * Since 0 may already be in use by the system (e.g. the BIOS | |
| 537 | + * framebuffer), we let the reservation fail quietly and hope | |
| 538 | + * 0 remains reserved always. | |
| 539 | + * | |
| 540 | + * If we fail to reserve 0, and then fail to find any space | |
| 541 | + * for an error-capture, remain silent. We can afford not | |
| 542 | + * to reserve an error_capture node as we have fallback | |
| 543 | + * paths, and we trust that 0 will remain reserved. However, | |
| 544 | + * the only likely reason for failure to insert is a driver | |
| 545 | + * bug, which we expect to cause other failures... | |
| 546 | + */ | |
| 547 | + ggtt->error_capture.size = I915_GTT_PAGE_SIZE; | |
| 548 | + ggtt->error_capture.color = I915_COLOR_UNEVICTABLE; | |
| 549 | + if (drm_mm_reserve_node(&ggtt->vm.mm, &ggtt->error_capture)) | |
| 550 | + drm_mm_insert_node_in_range(&ggtt->vm.mm, | |
| 551 | + &ggtt->error_capture, | |
| 552 | + ggtt->error_capture.size, 0, | |
| 553 | + ggtt->error_capture.color, | |
| 554 | + 0, ggtt->mappable_end, | |
| 555 | + DRM_MM_INSERT_LOW); | |
| 538 | 556 | } |
| 557 | + if (drm_mm_node_allocated(&ggtt->error_capture)) | |
| 558 | + drm_dbg(&ggtt->vm.i915->drm, | |
| 559 | + "Reserved GGTT:[%llx, %llx] for use by error capture\n", | |
| 560 | + ggtt->error_capture.start, | |
| 561 | + ggtt->error_capture.start + ggtt->error_capture.size); | |
| 539 | 562 | |
| 540 | 563 | /* |
| 541 | 564 | * The upper portion of the GuC address space has a sizeable hole |
| @@ -548,9 +571,9 @@ static int init_ggtt(struct i915_ggtt *ggtt) · 6 unmodified lines | ||
| 548 | 571 | |
| 549 | 572 | /* Clear any non-preallocated blocks */ |
| 550 | 573 | drm_mm_for_each_hole(entry, &ggtt->vm.mm, hole_start, hole_end) { |
| 551 | − drm_dbg_kms(&ggtt->vm.i915->drm, | |
| 552 | − "clearing unused GTT space: [%lx, %lx]\n", | |
| 553 | − hole_start, hole_end); | |
| 574 | + drm_dbg(&ggtt->vm.i915->drm, | |
| 575 | + "clearing unused GTT space: [%lx, %lx]\n", | |
| 576 | + hole_start, hole_end); | |
| 554 | 577 | ggtt->vm.clear_range(&ggtt->vm, hole_start, |
| 555 | 578 | hole_end - hole_start); |
| 556 | 579 | } |
| @@ -3988,6 +3988,9 @@ err: · 3987 unmodified lines | ||
| 3988 | 3988 | static void lrc_destroy_wa_ctx(struct intel_engine_cs *engine) |
| 3989 | 3989 | { |
| 3990 | 3990 | i915_vma_unpin_and_release(&engine->wa_ctx.vma, 0); |
| 3991 | + | |
| 3992 | + /* Called on error unwind, clear all flags to prevent further use */ | |
| 3993 | + memset(&engine->wa_ctx, 0, sizeof(engine->wa_ctx)); | |
| 3991 | 3994 | } |
| 3992 | 3995 | |
| 3993 | 3996 | typedef u32 *(*wa_bb_func_t)(struct intel_engine_cs *engine, u32 *batch); |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | #include "gen6_ppgtt.h" |
| 33 | 33 | #include "gen7_renderclear.h" |
| 34 | 34 | #include "i915_drv.h" |
| 35 | +#include "i915_mitigations.h" | |
| 35 | 36 | #include "intel_breadcrumbs.h" |
| 36 | 37 | #include "intel_context.h" |
| 37 | 38 | #include "intel_gt.h" |
| @@ -886,7 +887,8 @@ static int switch_context(struct i915_request *rq) · 848 unmodified lines | ||
| 886 | 887 | GEM_BUG_ON(HAS_EXECLISTS(engine->i915)); |
| 887 | 888 | |
| 888 | 889 | if (engine->wa_ctx.vma && ce != engine->kernel_context) { |
| 889 | − if (engine->wa_ctx.vma->private != ce) { | |
| 890 | + if (engine->wa_ctx.vma->private != ce && | |
| 891 | + i915_mitigate_clear_residuals()) { | |
| 890 | 892 | ret = clear_residuals(rq); |
| 891 | 893 | if (ret) |
| 892 | 894 | return ret; |
| @@ -1290,7 +1292,7 @@ int intel_ring_submission_setup(struct intel_engine_cs *engine) · 397 unmodified lines | ||
| 1290 | 1292 | |
| 1291 | 1293 | GEM_BUG_ON(timeline->hwsp_ggtt != engine->status_page.vma); |
| 1292 | 1294 | |
| 1293 | − if (IS_HASWELL(engine->i915) && engine->class == RENDER_CLASS) { | |
| 1295 | + if (IS_GEN(engine->i915, 7) && engine->class == RENDER_CLASS) { | |
| 1294 | 1296 | err = gen7_ctx_switch_bb_init(engine); |
| 1295 | 1297 | if (err) |
| 1296 | 1298 | goto err_ring_unpin; |
| @@ -126,6 +126,10 @@ static void __rcu_cacheline_free(struct rcu_head *rcu) · 125 unmodified lines | ||
| 126 | 126 | struct intel_timeline_cacheline *cl = |
| 127 | 127 | container_of(rcu, typeof(*cl), rcu); |
| 128 | 128 | |
| 129 | + /* Must wait until after all *rq->hwsp are complete before removing */ | |
| 130 | + i915_gem_object_unpin_map(cl->hwsp->vma->obj); | |
| 131 | + __idle_hwsp_free(cl->hwsp, ptr_unmask_bits(cl->vaddr, CACHELINE_BITS)); | |
| 132 | + | |
| 129 | 133 | i915_active_fini(&cl->active); |
| 130 | 134 | kfree(cl); |
| 131 | 135 | } |
| @@ -133,11 +137,6 @@ static void __rcu_cacheline_free(struct rcu_head *rcu) · 1 unmodified line | ||
| 133 | 137 | static void __idle_cacheline_free(struct intel_timeline_cacheline *cl) |
| 134 | 138 | { |
| 135 | 139 | GEM_BUG_ON(!i915_active_is_idle(&cl->active)); |
| 136 | − | |
| 137 | − i915_gem_object_unpin_map(cl->hwsp->vma->obj); | |
| 138 | − i915_vma_put(cl->hwsp->vma); | |
| 139 | − __idle_hwsp_free(cl->hwsp, ptr_unmask_bits(cl->vaddr, CACHELINE_BITS)); | |
| 140 | − | |
| 141 | 140 | call_rcu(&cl->rcu, __rcu_cacheline_free); |
| 142 | 141 | } |
| 143 | 142 | |
| @@ -179,7 +178,6 @@ cacheline_alloc(struct intel_timeline_hwsp *hwsp, unsigned int cacheline) · 35 unmodified lines | ||
| 179 | 178 | return ERR_CAST(vaddr); |
| 180 | 179 | } |
| 181 | 180 | |
| 182 | − i915_vma_get(hwsp->vma); | |
| 183 | 181 | cl->hwsp = hwsp; |
| 184 | 182 | cl->vaddr = page_pack_bits(vaddr, cacheline); |
| 185 | 183 | |
| @@ -53,6 +53,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw, · 52 unmodified lines | ||
| 53 | 53 | fw_def(ELKHARTLAKE, 0, guc_def(ehl, 49, 0, 1), huc_def(ehl, 9, 0, 0)) \ |
| 54 | 54 | fw_def(ICELAKE, 0, guc_def(icl, 49, 0, 1), huc_def(icl, 9, 0, 0)) \ |
| 55 | 55 | fw_def(COMETLAKE, 5, guc_def(cml, 49, 0, 1), huc_def(cml, 4, 0, 0)) \ |
| 56 | + fw_def(COMETLAKE, 0, guc_def(kbl, 49, 0, 1), huc_def(kbl, 4, 0, 0)) \ | |
| 56 | 57 | fw_def(COFFEELAKE, 0, guc_def(kbl, 49, 0, 1), huc_def(kbl, 4, 0, 0)) \ |
| 57 | 58 | fw_def(GEMINILAKE, 0, guc_def(glk, 49, 0, 1), huc_def(glk, 4, 0, 0)) \ |
| 58 | 59 | fw_def(KABYLAKE, 0, guc_def(kbl, 49, 0, 1), huc_def(kbl, 4, 0, 0)) \ |
| @@ -217,6 +217,15 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) · 216 unmodified lines | ||
| 217 | 217 | DDI_BUF_CTL_ENABLE); |
| 218 | 218 | vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) |= DDI_BUF_IS_IDLE; |
| 219 | 219 | } |
| 220 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= | |
| 221 | + ~(PORTA_HOTPLUG_ENABLE | PORTA_HOTPLUG_STATUS_MASK); | |
| 222 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= | |
| 223 | + ~(PORTB_HOTPLUG_ENABLE | PORTB_HOTPLUG_STATUS_MASK); | |
| 224 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= | |
| 225 | + ~(PORTC_HOTPLUG_ENABLE | PORTC_HOTPLUG_STATUS_MASK); | |
| 226 | + /* No hpd_invert set in vgpu vbt, need to clear invert mask */ | |
| 227 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= ~BXT_DDI_HPD_INVERT_MASK; | |
| 228 | + vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~BXT_DE_PORT_HOTPLUG_MASK; | |
| 220 | 229 | |
| 221 | 230 | vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) &= ~(BIT(0) | BIT(1)); |
| 222 | 231 | vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) &= |
| @@ -273,6 +282,8 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) · 50 unmodified lines | ||
| 273 | 282 | vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)) |= |
| 274 | 283 | (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST | |
| 275 | 284 | TRANS_DDI_FUNC_ENABLE); |
| 285 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | |
| 286 | + PORTA_HOTPLUG_ENABLE; | |
| 276 | 287 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= |
| 277 | 288 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_A); |
| 278 | 289 | } |
| @@ -301,6 +312,8 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) · 22 unmodified lines | ||
| 301 | 312 | (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST | |
| 302 | 313 | (PORT_B << TRANS_DDI_PORT_SHIFT) | |
| 303 | 314 | TRANS_DDI_FUNC_ENABLE); |
| 315 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | |
| 316 | + PORTB_HOTPLUG_ENABLE; | |
| 304 | 317 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= |
| 305 | 318 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_B); |
| 306 | 319 | } |
| @@ -329,6 +342,8 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) · 22 unmodified lines | ||
| 329 | 342 | (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST | |
| 330 | 343 | (PORT_B << TRANS_DDI_PORT_SHIFT) | |
| 331 | 344 | TRANS_DDI_FUNC_ENABLE); |
| 345 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | |
| 346 | + PORTC_HOTPLUG_ENABLE; | |
| 332 | 347 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= |
| 333 | 348 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_C); |
| 334 | 349 | } |
| @@ -661,44 +676,62 @@ void intel_vgpu_emulate_hotplug(struct intel_vgpu *vgpu, bool connected) · 326 unmodified lines | ||
| 661 | 676 | PORTD_HOTPLUG_STATUS_MASK; |
| 662 | 677 | intel_vgpu_trigger_virtual_event(vgpu, DP_D_HOTPLUG); |
| 663 | 678 | } else if (IS_BROXTON(i915)) { |
| 664 | − if (connected) { | |
| 665 | − if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) { | |
| 679 | + if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) { | |
| 680 | + if (connected) { | |
| 666 | 681 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= |
| 667 | 682 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_A); |
| 683 | + } else { | |
| 684 | + vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= | |
| 685 | + ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_A); | |
| 668 | 686 | } |
| 669 | − if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) { | |
| 670 | − vgpu_vreg_t(vgpu, SFUSE_STRAP) |= | |
| 671 | − SFUSE_STRAP_DDIB_DETECTED; | |
| 687 | + vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |= | |
| 688 | + GEN8_DE_PORT_HOTPLUG(HPD_PORT_A); | |
| 689 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= | |
| 690 | + ~PORTA_HOTPLUG_STATUS_MASK; | |
| 691 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | |
| 692 | + PORTA_HOTPLUG_LONG_DETECT; | |
| 693 | + intel_vgpu_trigger_virtual_event(vgpu, DP_A_HOTPLUG); | |
| 694 | + } | |
| 695 | + if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) { | |
| 696 | + if (connected) { | |
| 672 | 697 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= |
| 673 | 698 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_B); |
| 674 | − } | |
| 675 | − if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) { | |
| 676 | 699 | vgpu_vreg_t(vgpu, SFUSE_STRAP) |= |
| 677 | − SFUSE_STRAP_DDIC_DETECTED; | |
| 678 | − vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= | |
| 679 | − GEN8_DE_PORT_HOTPLUG(HPD_PORT_C); | |
| 680 | − } | |
| 681 | − } else { | |
| 682 | − if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) { | |
| 700 | + SFUSE_STRAP_DDIB_DETECTED; | |
| 701 | + } else { | |
| 683 | 702 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= |
| 684 | − ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_A); | |
| 685 | − } | |
| 686 | − if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) { | |
| 703 | + ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_B); | |
| 687 | 704 | vgpu_vreg_t(vgpu, SFUSE_STRAP) &= |
| 688 | 705 | ~SFUSE_STRAP_DDIB_DETECTED; |
| 689 | − vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= | |
| 690 | − ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_B); | |
| 691 | 706 | } |
| 692 | − if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) { | |
| 693 | − vgpu_vreg_t(vgpu, SFUSE_STRAP) &= | |
| 694 | − ~SFUSE_STRAP_DDIC_DETECTED; | |
| 707 | + vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |= | |
| 708 | + GEN8_DE_PORT_HOTPLUG(HPD_PORT_B); | |
| 709 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= | |
| 710 | + ~PORTB_HOTPLUG_STATUS_MASK; | |
| 711 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | |
| 712 | + PORTB_HOTPLUG_LONG_DETECT; | |
| 713 | + intel_vgpu_trigger_virtual_event(vgpu, DP_B_HOTPLUG); | |
| 714 | + } | |
| 715 | + if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) { | |
| 716 | + if (connected) { | |
| 717 | + vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= | |
| 718 | + GEN8_DE_PORT_HOTPLUG(HPD_PORT_C); | |
| 719 | + vgpu_vreg_t(vgpu, SFUSE_STRAP) |= | |
| 720 | + SFUSE_STRAP_DDIC_DETECTED; | |
| 721 | + } else { | |
| 695 | 722 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= |
| 696 | 723 | ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_C); |
| 724 | + vgpu_vreg_t(vgpu, SFUSE_STRAP) &= | |
| 725 | + ~SFUSE_STRAP_DDIC_DETECTED; | |
| 697 | 726 | } |
| 727 | + vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |= | |
| 728 | + GEN8_DE_PORT_HOTPLUG(HPD_PORT_C); | |
| 729 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= | |
| 730 | + ~PORTC_HOTPLUG_STATUS_MASK; | |
| 731 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | |
| 732 | + PORTC_HOTPLUG_LONG_DETECT; | |
| 733 | + intel_vgpu_trigger_virtual_event(vgpu, DP_C_HOTPLUG); | |
| 698 | 734 | } |
| 699 | − vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | |
| 700 | − PORTB_HOTPLUG_STATUS_MASK; | |
| 701 | − intel_vgpu_trigger_virtual_event(vgpu, DP_B_HOTPLUG); | |
| 702 | 735 | } |
| 703 | 736 | } |
| 704 | 737 | |
| @@ -437,10 +437,9 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt, · 436 unmodified lines | ||
| 437 | 437 | if (ret) |
| 438 | 438 | goto out_clean_sched_policy; |
| 439 | 439 | |
| 440 | − if (IS_BROADWELL(dev_priv)) | |
| 440 | + if (IS_BROADWELL(dev_priv) || IS_BROXTON(dev_priv)) | |
| 441 | 441 | ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_B); |
| 442 | − /* FixMe: Re-enable APL/BXT once vfio_edid enabled */ | |
| 443 | − else if (!IS_BROXTON(dev_priv)) | |
| 442 | + else | |
| 444 | 443 | ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_D); |
| 445 | 444 | if (ret) |
| 446 | 445 | goto out_clean_sched_policy; |
| @@ -631,24 +631,26 @@ static int flush_lazy_signals(struct i915_active *ref) · 630 unmodified lines | ||
| 631 | 631 | |
| 632 | 632 | int __i915_active_wait(struct i915_active *ref, int state) |
| 633 | 633 | { |
| 634 | − int err; | |
| 635 | − | |
| 636 | 634 | might_sleep(); |
| 637 | 635 | |
| 638 | − if (!i915_active_acquire_if_busy(ref)) | |
| 639 | − return 0; | |
| 640 | − | |
| 641 | 636 | /* Any fence added after the wait begins will not be auto-signaled */ |
| 642 | − err = flush_lazy_signals(ref); | |
| 643 | − i915_active_release(ref); | |
| 644 | − if (err) | |
| 645 | − return err; | |
| 637 | + if (i915_active_acquire_if_busy(ref)) { | |
| 638 | + int err; | |
| 646 | 639 | |
| 647 | − if (!i915_active_is_idle(ref) && | |
| 648 | − ___wait_var_event(ref, i915_active_is_idle(ref), | |
| 649 | − state, 0, 0, schedule())) | |
| 650 | − return -EINTR; | |
| 640 | + err = flush_lazy_signals(ref); | |
| 641 | + i915_active_release(ref); | |
| 642 | + if (err) | |
| 643 | + return err; | |
| 651 | 644 | |
| 645 | + if (___wait_var_event(ref, i915_active_is_idle(ref), | |
| 646 | + state, 0, 0, schedule())) | |
| 647 | + return -EINTR; | |
| 648 | + } | |
| 649 | + | |
| 650 | + /* | |
| 651 | + * After the wait is complete, the caller may free the active. | |
| 652 | + * We have to flush any concurrent retirement before returning. | |
| 653 | + */ | |
| 652 | 654 | flush_work(&ref->work); |
| 653 | 655 | return 0; |
| 654 | 656 | } |
| @@ -1166,7 +1166,7 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, · 1165 unmodified lines | ||
| 1166 | 1166 | } |
| 1167 | 1167 | } |
| 1168 | 1168 | if (IS_ERR(src)) { |
| 1169 | − unsigned long x, n; | |
| 1169 | + unsigned long x, n, remain; | |
| 1170 | 1170 | void *ptr; |
| 1171 | 1171 | |
| 1172 | 1172 | /* |
| @@ -1177,14 +1177,15 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, · 4 unmodified lines | ||
| 1177 | 1177 | * We don't care about copying too much here as we only |
| 1178 | 1178 | * validate up to the end of the batch. |
| 1179 | 1179 | */ |
| 1180 | + remain = length; | |
| 1180 | 1181 | if (!(dst_obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)) |
| 1181 | − length = round_up(length, | |
| 1182 | + remain = round_up(remain, | |
| 1182 | 1183 | boot_cpu_data.x86_clflush_size); |
| 1183 | 1184 | |
| 1184 | 1185 | ptr = dst; |
| 1185 | 1186 | x = offset_in_page(offset); |
| 1186 | − for (n = offset >> PAGE_SHIFT; length; n++) { | |
| 1187 | − int len = min(length, PAGE_SIZE - x); | |
| 1187 | + for (n = offset >> PAGE_SHIFT; remain; n++) { | |
| 1188 | + int len = min(remain, PAGE_SIZE - x); | |
| 1188 | 1189 | |
| 1189 | 1190 | src = kmap_atomic(i915_gem_object_get_page(src_obj, n)); |
| 1190 | 1191 | if (needs_clflush) |
| @@ -1193,13 +1194,15 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, · 2 unmodified lines | ||
| 1193 | 1194 | kunmap_atomic(src); |
| 1194 | 1195 | |
| 1195 | 1196 | ptr += len; |
| 1196 | − length -= len; | |
| 1197 | + remain -= len; | |
| 1197 | 1198 | x = 0; |
| 1198 | 1199 | } |
| 1199 | 1200 | } |
| 1200 | 1201 | |
| 1201 | 1202 | i915_gem_object_unpin_pages(src_obj); |
| 1202 | 1203 | |
| 1204 | + memset32(dst + length, 0, (dst_obj->base.size - length) / sizeof(u32)); | |
| 1205 | + | |
| 1203 | 1206 | /* dst_obj is returned with vmap pinned */ |
| 1204 | 1207 | return dst; |
| 1205 | 1208 | } |
| @@ -1392,11 +1395,6 @@ static unsigned long *alloc_whitelist(u32 batch_length) · 186 unmodified lines | ||
| 1392 | 1395 | |
| 1393 | 1396 | #define LENGTH_BIAS 2 |
| 1394 | 1397 | |
| 1395 | −static bool shadow_needs_clflush(struct drm_i915_gem_object *obj) | |
| 1396 | −{ | |
| 1397 | − return !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE); | |
| 1398 | −} | |
| 1399 | − | |
| 1400 | 1398 | /** |
| 1401 | 1399 | * intel_engine_cmd_parser() - parse a batch buffer for privilege violations |
| 1402 | 1400 | * @engine: the engine on which the batch is to execute |
| @@ -1538,16 +1536,9 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine, · 135 unmodified lines | ||
| 1538 | 1536 | ret = 0; /* allow execution */ |
| 1539 | 1537 | } |
| 1540 | 1538 | } |
| 1541 | − | |
| 1542 | − if (shadow_needs_clflush(shadow->obj)) | |
| 1543 | − drm_clflush_virt_range(batch_end, 8); | |
| 1544 | 1539 | } |
| 1545 | 1540 | |
| 1546 | − if (shadow_needs_clflush(shadow->obj)) { | |
| 1547 | − void *ptr = page_mask_bits(shadow->obj->mm.mapping); | |
| 1548 | − | |
| 1549 | − drm_clflush_virt_range(ptr, (void *)(cmd + 1) - ptr); | |
| 1550 | − } | |
| 1541 | + i915_gem_object_flush_map(shadow->obj); | |
| 1551 | 1542 | |
| 1552 | 1543 | if (!IS_ERR_OR_NULL(jump_whitelist)) |
| 1553 | 1544 | kfree(jump_whitelist); |
| @@ -578,8 +578,6 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv) · 577 unmodified lines | ||
| 578 | 578 | |
| 579 | 579 | pci_set_master(pdev); |
| 580 | 580 | |
| 581 | − cpu_latency_qos_add_request(&dev_priv->pm_qos, PM_QOS_DEFAULT_VALUE); | |
| 582 | − | |
| 583 | 581 | intel_gt_init_workarounds(dev_priv); |
| 584 | 582 | |
| 585 | 583 | /* On the 945G/GM, the chipset reports the MSI capability on the |
| @@ -626,7 +624,6 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv) · 40 unmodified lines | ||
| 626 | 624 | err_msi: |
| 627 | 625 | if (pdev->msi_enabled) |
| 628 | 626 | pci_disable_msi(pdev); |
| 629 | − cpu_latency_qos_remove_request(&dev_priv->pm_qos); | |
| 630 | 627 | err_mem_regions: |
| 631 | 628 | intel_memory_regions_driver_release(dev_priv); |
| 632 | 629 | err_ggtt: |
| @@ -648,8 +645,6 @@ static void i915_driver_hw_remove(struct drm_i915_private *dev_priv) · 15 unmodified lines | ||
| 648 | 645 | |
| 649 | 646 | if (pdev->msi_enabled) |
| 650 | 647 | pci_disable_msi(pdev); |
| 651 | − | |
| 652 | − cpu_latency_qos_remove_request(&dev_priv->pm_qos); | |
| 653 | 648 | } |
| 654 | 649 | |
| 655 | 650 | /** |
| @@ -1052,6 +1047,8 @@ static void intel_shutdown_encoders(struct drm_i915_private *dev_priv) · 396 unmodified lines | ||
| 1052 | 1047 | |
| 1053 | 1048 | void i915_driver_shutdown(struct drm_i915_private *i915) |
| 1054 | 1049 | { |
| 1050 | + disable_rpm_wakeref_asserts(&i915->runtime_pm); | |
| 1051 | + | |
| 1055 | 1052 | i915_gem_suspend(i915); |
| 1056 | 1053 | |
| 1057 | 1054 | drm_kms_helper_poll_disable(&i915->drm); |
| @@ -1065,6 +1062,8 @@ void i915_driver_shutdown(struct drm_i915_private *i915) · 7 unmodified lines | ||
| 1065 | 1062 | |
| 1066 | 1063 | intel_suspend_encoders(i915); |
| 1067 | 1064 | intel_shutdown_encoders(i915); |
| 1065 | + | |
| 1066 | + enable_rpm_wakeref_asserts(&i915->runtime_pm); | |
| 1068 | 1067 | } |
| 1069 | 1068 | |
| 1070 | 1069 | static bool suspend_to_idle(struct drm_i915_private *dev_priv) |
| @@ -891,9 +891,6 @@ struct drm_i915_private { · 890 unmodified lines | ||
| 891 | 891 | |
| 892 | 892 | bool display_irqs_enabled; |
| 893 | 893 | |
| 894 | − /* To control wakeup latency, e.g. for irq-driven dp aux transfers. */ | |
| 895 | − struct pm_qos_request pm_qos; | |
| 896 | − | |
| 897 | 894 | /* Sideband mailbox protection */ |
| 898 | 895 | struct mutex sb_lock; |
| 899 | 896 | struct pm_qos_request sb_qos; |
| @@ -1349,7 +1346,7 @@ intel_subplatform(const struct intel_runtime_info *info, enum intel_platform p) · 449 unmodified lines | ||
| 1349 | 1346 | { |
| 1350 | 1347 | const unsigned int pi = __platform_mask_index(info, p); |
| 1351 | 1348 | |
| 1352 | − return info->platform_mask[pi] & INTEL_SUBPLATFORM_BITS; | |
| 1349 | + return info->platform_mask[pi] & ((1 << INTEL_SUBPLATFORM_BITS) - 1); | |
| 1353 | 1350 | } |
| 1354 | 1351 | |
| 1355 | 1352 | static __always_inline bool |
| @@ -0,0 +1,146 @@ | ||
| 1 | +// SPDX-License-Identifier: MIT | |
| 2 | +/* | |
| 3 | + * Copyright © 2021 Intel Corporation | |
| 4 | + */ | |
| 5 | + | |
| 6 | +#include <linux/kernel.h> | |
| 7 | +#include <linux/moduleparam.h> | |
| 8 | +#include <linux/slab.h> | |
| 9 | +#include <linux/string.h> | |
| 10 | + | |
| 11 | +#include "i915_drv.h" | |
| 12 | +#include "i915_mitigations.h" | |
| 13 | + | |
| 14 | +static unsigned long mitigations __read_mostly = ~0UL; | |
| 15 | + | |
| 16 | +enum { | |
| 17 | + CLEAR_RESIDUALS = 0, | |
| 18 | +}; | |
| 19 | + | |
| 20 | +static const char * const names[] = { | |
| 21 | + [CLEAR_RESIDUALS] = "residuals", | |
| 22 | +}; | |
| 23 | + | |
| 24 | +bool i915_mitigate_clear_residuals(void) | |
| 25 | +{ | |
| 26 | + return READ_ONCE(mitigations) & BIT(CLEAR_RESIDUALS); | |
| 27 | +} | |
| 28 | + | |
| 29 | +static int mitigations_set(const char *val, const struct kernel_param *kp) | |
| 30 | +{ | |
| 31 | + unsigned long new = ~0UL; | |
| 32 | + char *str, *sep, *tok; | |
| 33 | + bool first = true; | |
| 34 | + int err = 0; | |
| 35 | + | |
| 36 | + BUILD_BUG_ON(ARRAY_SIZE(names) >= BITS_PER_TYPE(mitigations)); | |
| 37 | + | |
| 38 | + str = kstrdup(val, GFP_KERNEL); | |
| 39 | + if (!str) | |
| 40 | + return -ENOMEM; | |
| 41 | + | |
| 42 | + for (sep = str; (tok = strsep(&sep, ","));) { | |
| 43 | + bool enable = true; | |
| 44 | + int i; | |
| 45 | + | |
| 46 | + /* Be tolerant of leading/trailing whitespace */ | |
| 47 | + tok = strim(tok); | |
| 48 | + | |
| 49 | + if (first) { | |
| 50 | + first = false; | |
| 51 | + | |
| 52 | + if (!strcmp(tok, "auto")) | |
| 53 | + continue; | |
| 54 | + | |
| 55 | + new = 0; | |
| 56 | + if (!strcmp(tok, "off")) | |
| 57 | + continue; | |
| 58 | + } | |
| 59 | + | |
| 60 | + if (*tok == '!') { | |
| 61 | + enable = !enable; | |
| 62 | + tok++; | |
| 63 | + } | |
| 64 | + | |
| 65 | + if (!strncmp(tok, "no", 2)) { | |
| 66 | + enable = !enable; | |
| 67 | + tok += 2; | |
| 68 | + } | |
| 69 | + | |
| 70 | + if (*tok == '\0') | |
| 71 | + continue; | |
| 72 | + | |
| 73 | + for (i = 0; i < ARRAY_SIZE(names); i++) { | |
| 74 | + if (!strcmp(tok, names[i])) { | |
| 75 | + if (enable) | |
| 76 | + new |= BIT(i); | |
| 77 | + else | |
| 78 | + new &= ~BIT(i); | |
| 79 | + break; | |
| 80 | + } | |
| 81 | + } | |
| 82 | + if (i == ARRAY_SIZE(names)) { | |
| 83 | + pr_err("Bad \"%s.mitigations=%s\", '%s' is unknown\n", | |
| 84 | + DRIVER_NAME, val, tok); | |
| 85 | + err = -EINVAL; | |
| 86 | + break; | |
| 87 | + } | |
| 88 | + } | |
| 89 | + kfree(str); | |
| 90 | + if (err) | |
| 91 | + return err; | |
| 92 | + | |
| 93 | + WRITE_ONCE(mitigations, new); | |
| 94 | + return 0; | |
| 95 | +} | |
| 96 | + | |
| 97 | +static int mitigations_get(char *buffer, const struct kernel_param *kp) | |
| 98 | +{ | |
| 99 | + unsigned long local = READ_ONCE(mitigations); | |
| 100 | + int count, i; | |
| 101 | + bool enable; | |
| 102 | + | |
| 103 | + if (!local) | |
| 104 | + return scnprintf(buffer, PAGE_SIZE, "%s\n", "off"); | |
| 105 | + | |
| 106 | + if (local & BIT(BITS_PER_LONG - 1)) { | |
| 107 | + count = scnprintf(buffer, PAGE_SIZE, "%s,", "auto"); | |
| 108 | + enable = false; | |
| 109 | + } else { | |
| 110 | + enable = true; | |
| 111 | + count = 0; | |
| 112 | + } | |
| 113 | + | |
| 114 | + for (i = 0; i < ARRAY_SIZE(names); i++) { | |
| 115 | + if ((local & BIT(i)) != enable) | |
| 116 | + continue; | |
| 117 | + | |
| 118 | + count += scnprintf(buffer + count, PAGE_SIZE - count, | |
| 119 | + "%s%s,", enable ? "" : "!", names[i]); | |
| 120 | + } | |
| 121 | + | |
| 122 | + buffer[count - 1] = '\n'; | |
| 123 | + return count; | |
| 124 | +} | |
| 125 | + | |
| 126 | +static const struct kernel_param_ops ops = { | |
| 127 | + .set = mitigations_set, | |
| 128 | + .get = mitigations_get, | |
| 129 | +}; | |
| 130 | + | |
| 131 | +module_param_cb_unsafe(mitigations, &ops, NULL, 0600); | |
| 132 | +MODULE_PARM_DESC(mitigations, | |
| 133 | +"Selectively enable security mitigations for all Intel® GPUs in the system.\n" | |
| 134 | +"\n" | |
| 135 | +" auto -- enables all mitigations required for the platform [default]\n" | |
| 136 | +" off -- disables all mitigations\n" | |
| 137 | +"\n" | |
| 138 | +"Individual mitigations can be enabled by passing a comma-separated string,\n" | |
| 139 | +"e.g. mitigations=residuals to enable only clearing residuals or\n" | |
| 140 | +"mitigations=auto,noresiduals to disable only the clear residual mitigation.\n" | |
| 141 | +"Either '!' or 'no' may be used to switch from enabling the mitigation to\n" | |
| 142 | +"disabling it.\n" | |
| 143 | +"\n" | |
| 144 | +"Active mitigations for Ivybridge, Baytrail, Haswell:\n" | |
| 145 | +" residuals -- clear all thread-local registers between contexts" | |
| 146 | +); | |
| @@ -0,0 +1,13 @@ | ||
| 1 | +/* SPDX-License-Identifier: MIT */ | |
| 2 | +/* | |
| 3 | + * Copyright © 2021 Intel Corporation | |
| 4 | + */ | |
| 5 | + | |
| 6 | +#ifndef __I915_MITIGATIONS_H__ | |
| 7 | +#define __I915_MITIGATIONS_H__ | |
| 8 | + | |
| 9 | +#include <linux/types.h> | |
| 10 | + | |
| 11 | +bool i915_mitigate_clear_residuals(void); | |
| 12 | + | |
| 13 | +#endif /* __I915_MITIGATIONS_H__ */ | |
| @@ -184,13 +184,24 @@ static u64 get_rc6(struct intel_gt *gt) · 183 unmodified lines | ||
| 184 | 184 | return val; |
| 185 | 185 | } |
| 186 | 186 | |
| 187 | −static void park_rc6(struct drm_i915_private *i915) | |
| 187 | +static void init_rc6(struct i915_pmu *pmu) | |
| 188 | 188 | { |
| 189 | − struct i915_pmu *pmu = &i915->pmu; | |
| 189 | + struct drm_i915_private *i915 = container_of(pmu, typeof(*i915), pmu); | |
| 190 | + intel_wakeref_t wakeref; | |
| 190 | 191 | |
| 191 | − if (pmu->enable & config_enabled_mask(I915_PMU_RC6_RESIDENCY)) | |
| 192 | + with_intel_runtime_pm(i915->gt.uncore->rpm, wakeref) { | |
| 192 | 193 | pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt); |
| 194 | + pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur = | |
| 195 | + pmu->sample[__I915_SAMPLE_RC6].cur; | |
| 196 | + pmu->sleep_last = ktime_get(); | |
| 197 | + } | |
| 198 | +} | |
| 193 | 199 | |
| 200 | +static void park_rc6(struct drm_i915_private *i915) | |
| 201 | +{ | |
| 202 | + struct i915_pmu *pmu = &i915->pmu; | |
| 203 | + | |
| 204 | + pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt); | |
| 194 | 205 | pmu->sleep_last = ktime_get(); |
| 195 | 206 | } |
| 196 | 207 | |
| @@ -201,6 +212,7 @@ static u64 get_rc6(struct intel_gt *gt) · 4 unmodified lines | ||
| 201 | 212 | return __get_rc6(gt); |
| 202 | 213 | } |
| 203 | 214 | |
| 215 | +static void init_rc6(struct i915_pmu *pmu) { } | |
| 204 | 216 | static void park_rc6(struct drm_i915_private *i915) {} |
| 205 | 217 | |
| 206 | 218 | #endif |
| @@ -612,10 +624,8 @@ static void i915_pmu_enable(struct perf_event *event) · 405 unmodified lines | ||
| 612 | 624 | container_of(event->pmu, typeof(*i915), pmu.base); |
| 613 | 625 | unsigned int bit = event_enabled_bit(event); |
| 614 | 626 | struct i915_pmu *pmu = &i915->pmu; |
| 615 | − intel_wakeref_t wakeref; | |
| 616 | 627 | unsigned long flags; |
| 617 | 628 | |
| 618 | − wakeref = intel_runtime_pm_get(&i915->runtime_pm); | |
| 619 | 629 | spin_lock_irqsave(&pmu->lock, flags); |
| 620 | 630 | |
| 621 | 631 | /* |
| @@ -626,13 +636,6 @@ static void i915_pmu_enable(struct perf_event *event) · 4 unmodified lines | ||
| 626 | 636 | GEM_BUG_ON(bit >= ARRAY_SIZE(pmu->enable_count)); |
| 627 | 637 | GEM_BUG_ON(pmu->enable_count[bit] == ~0); |
| 628 | 638 | |
| 629 | − if (pmu->enable_count[bit] == 0 && | |
| 630 | − config_enabled_mask(I915_PMU_RC6_RESIDENCY) & BIT_ULL(bit)) { | |
| 631 | − pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur = 0; | |
| 632 | − pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt); | |
| 633 | − pmu->sleep_last = ktime_get(); | |
| 634 | − } | |
| 635 | − | |
| 636 | 639 | pmu->enable |= BIT_ULL(bit); |
| 637 | 640 | pmu->enable_count[bit]++; |
| 638 | 641 | |
| @@ -673,8 +676,6 @@ static void i915_pmu_enable(struct perf_event *event) · 34 unmodified lines | ||
| 673 | 676 | * an existing non-zero value. |
| 674 | 677 | */ |
| 675 | 678 | local64_set(&event->hw.prev_count, __i915_pmu_event_read(event)); |
| 676 | − | |
| 677 | − intel_runtime_pm_put(&i915->runtime_pm, wakeref); | |
| 678 | 679 | } |
| 679 | 680 | |
| 680 | 681 | static void i915_pmu_disable(struct perf_event *event) |
| @@ -1130,6 +1131,7 @@ void i915_pmu_register(struct drm_i915_private *i915) · 449 unmodified lines | ||
| 1130 | 1131 | hrtimer_init(&pmu->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
| 1131 | 1132 | pmu->timer.function = i915_sample; |
| 1132 | 1133 | pmu->cpuhp.cpu = -1; |
| 1134 | + init_rc6(pmu); | |
| 1133 | 1135 | |
| 1134 | 1136 | if (!is_igp(i915)) { |
| 1135 | 1137 | pmu->name = kasprintf(GFP_KERNEL, |
| @@ -434,7 +434,7 @@ static inline u32 hwsp_seqno(const struct i915_request *rq) · 433 unmodified lines | ||
| 434 | 434 | |
| 435 | 435 | static inline bool __i915_request_has_started(const struct i915_request *rq) |
| 436 | 436 | { |
| 437 | − return i915_seqno_passed(hwsp_seqno(rq), rq->fence.seqno - 1); | |
| 437 | + return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno - 1); | |
| 438 | 438 | } |
| 439 | 439 | |
| 440 | 440 | /** |
| @@ -465,11 +465,19 @@ static inline bool __i915_request_has_started(const struct i915_request *rq) · 24 unmodified lines | ||
| 465 | 465 | */ |
| 466 | 466 | static inline bool i915_request_started(const struct i915_request *rq) |
| 467 | 467 | { |
| 468 | + bool result; | |
| 469 | + | |
| 468 | 470 | if (i915_request_signaled(rq)) |
| 469 | 471 | return true; |
| 470 | 472 | |
| 471 | − /* Remember: started but may have since been preempted! */ | |
| 472 | − return __i915_request_has_started(rq); | |
| 473 | + result = true; | |
| 474 | + rcu_read_lock(); /* the HWSP may be freed at runtime */ | |
| 475 | + if (likely(!i915_request_signaled(rq))) | |
| 476 | + /* Remember: started but may have since been preempted! */ | |
| 477 | + result = __i915_request_has_started(rq); | |
| 478 | + rcu_read_unlock(); | |
| 479 | + | |
| 480 | + return result; | |
| 473 | 481 | } |
| 474 | 482 | |
| 475 | 483 | /** |
| @@ -482,10 +490,16 @@ static inline bool i915_request_started(const struct i915_request *rq) · 6 unmodified lines | ||
| 482 | 490 | */ |
| 483 | 491 | static inline bool i915_request_is_running(const struct i915_request *rq) |
| 484 | 492 | { |
| 493 | + bool result; | |
| 494 | + | |
| 485 | 495 | if (!i915_request_is_active(rq)) |
| 486 | 496 | return false; |
| 487 | 497 | |
| 488 | − return __i915_request_has_started(rq); | |
| 498 | + rcu_read_lock(); | |
| 499 | + result = __i915_request_has_started(rq) && i915_request_is_active(rq); | |
| 500 | + rcu_read_unlock(); | |
| 501 | + | |
| 502 | + return result; | |
| 489 | 503 | } |
| 490 | 504 | |
| 491 | 505 | /** |
| @@ -509,12 +523,25 @@ static inline bool i915_request_is_ready(const struct i915_request *rq) · 17 unmodified lines | ||
| 509 | 523 | return !list_empty(&rq->sched.link); |
| 510 | 524 | } |
| 511 | 525 | |
| 526 | +static inline bool __i915_request_is_complete(const struct i915_request *rq) | |
| 527 | +{ | |
| 528 | + return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno); | |
| 529 | +} | |
| 530 | + | |
| 512 | 531 | static inline bool i915_request_completed(const struct i915_request *rq) |
| 513 | 532 | { |
| 533 | + bool result; | |
| 534 | + | |
| 514 | 535 | if (i915_request_signaled(rq)) |
| 515 | 536 | return true; |
| 516 | 537 | |
| 517 | − return i915_seqno_passed(hwsp_seqno(rq), rq->fence.seqno); | |
| 538 | + result = true; | |
| 539 | + rcu_read_lock(); /* the HWSP may be freed at runtime */ | |
| 540 | + if (likely(!i915_request_signaled(rq))) | |
| 541 | + result = __i915_request_is_complete(rq); | |
| 542 | + rcu_read_unlock(); | |
| 543 | + | |
| 544 | + return result; | |
| 518 | 545 | } |
| 519 | 546 | |
| 520 | 547 | static inline void i915_request_mark_complete(struct i915_request *rq) |
| @@ -1880,7 +1880,7 @@ static int igt_cs_tlb(void *arg) · 1879 unmodified lines | ||
| 1880 | 1880 | vma = i915_vma_instance(out, vm, NULL); |
| 1881 | 1881 | if (IS_ERR(vma)) { |
| 1882 | 1882 | err = PTR_ERR(vma); |
| 1883 | − goto out_put_batch; | |
| 1883 | + goto out_put_out; | |
| 1884 | 1884 | } |
| 1885 | 1885 | |
| 1886 | 1886 | err = i915_vma_pin(vma, 0, 0, |
| @@ -534,8 +534,10 @@ struct msm_gpu *a2xx_gpu_init(struct drm_device *dev) · 533 unmodified lines | ||
| 534 | 534 | |
| 535 | 535 | if (!gpu->aspace) { |
| 536 | 536 | dev_err(dev->dev, "No memory protection without MMU\n"); |
| 537 | − ret = -ENXIO; | |
| 538 | − goto fail; | |
| 537 | + if (!allow_vram_carveout) { | |
| 538 | + ret = -ENXIO; | |
| 539 | + goto fail; | |
| 540 | + } | |
| 539 | 541 | } |
| 540 | 542 | |
| 541 | 543 | return gpu; |
| @@ -564,8 +564,10 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) · 563 unmodified lines | ||
| 564 | 564 | * implement a cmdstream validator. |
| 565 | 565 | */ |
| 566 | 566 | DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n"); |
| 567 | − ret = -ENXIO; | |
| 568 | − goto fail; | |
| 567 | + if (!allow_vram_carveout) { | |
| 568 | + ret = -ENXIO; | |
| 569 | + goto fail; | |
| 570 | + } | |
| 569 | 571 | } |
| 570 | 572 | |
| 571 | 573 | icc_path = devm_of_icc_get(&pdev->dev, "gfx-mem"); |
| @@ -692,8 +692,10 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) · 691 unmodified lines | ||
| 692 | 692 | * implement a cmdstream validator. |
| 693 | 693 | */ |
| 694 | 694 | DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n"); |
| 695 | − ret = -ENXIO; | |
| 696 | − goto fail; | |
| 695 | + if (!allow_vram_carveout) { | |
| 696 | + ret = -ENXIO; | |
| 697 | + goto fail; | |
| 698 | + } | |
| 697 | 699 | } |
| 698 | 700 | |
| 699 | 701 | icc_path = devm_of_icc_get(&pdev->dev, "gfx-mem"); |
| @@ -18,6 +18,10 @@ bool snapshot_debugbus = false; · 17 unmodified lines | ||
| 18 | 18 | MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)"); |
| 19 | 19 | module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600); |
| 20 | 20 | |
| 21 | +bool allow_vram_carveout = false; | |
| 22 | +MODULE_PARM_DESC(allow_vram_carveout, "Allow using VRAM Carveout, in place of IOMMU"); | |
| 23 | +module_param_named(allow_vram_carveout, allow_vram_carveout, bool, 0600); | |
| 24 | + | |
| 21 | 25 | static const struct adreno_info gpulist[] = { |
| 22 | 26 | { |
| 23 | 27 | .rev = ADRENO_REV(2, 0, 0, 0), |
| @@ -191,8 +191,6 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu, · 190 unmodified lines | ||
| 191 | 191 | struct platform_device *pdev) |
| 192 | 192 | { |
| 193 | 193 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); |
| 194 | − struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); | |
| 195 | − struct io_pgtable_domain_attr pgtbl_cfg; | |
| 196 | 194 | struct iommu_domain *iommu; |
| 197 | 195 | struct msm_mmu *mmu; |
| 198 | 196 | struct msm_gem_address_space *aspace; |
| @@ -202,13 +200,18 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu, · 3 unmodified lines | ||
| 202 | 200 | if (!iommu) |
| 203 | 201 | return NULL; |
| 204 | 202 | |
| 205 | − /* | |
| 206 | − * This allows GPU to set the bus attributes required to use system | |
| 207 | − * cache on behalf of the iommu page table walker. | |
| 208 | − */ | |
| 209 | − if (!IS_ERR(a6xx_gpu->htw_llc_slice)) { | |
| 210 | − pgtbl_cfg.quirks = IO_PGTABLE_QUIRK_ARM_OUTER_WBWA; | |
| 211 | − iommu_domain_set_attr(iommu, DOMAIN_ATTR_IO_PGTABLE_CFG, &pgtbl_cfg); | |
| 203 | + | |
| 204 | + if (adreno_is_a6xx(adreno_gpu)) { | |
| 205 | + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); | |
| 206 | + struct io_pgtable_domain_attr pgtbl_cfg; | |
| 207 | + /* | |
| 208 | + * This allows GPU to set the bus attributes required to use system | |
| 209 | + * cache on behalf of the iommu page table walker. | |
| 210 | + */ | |
| 211 | + if (!IS_ERR(a6xx_gpu->htw_llc_slice)) { | |
| 212 | + pgtbl_cfg.quirks = IO_PGTABLE_QUIRK_ARM_OUTER_WBWA; | |
| 213 | + iommu_domain_set_attr(iommu, DOMAIN_ATTR_IO_PGTABLE_CFG, &pgtbl_cfg); | |
| 214 | + } | |
| 212 | 215 | } |
| 213 | 216 | |
| 214 | 217 | mmu = msm_iommu_new(&pdev->dev, iommu); |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include "adreno_pm4.xml.h" |
| 19 | 19 | |
| 20 | 20 | extern bool snapshot_debugbus; |
| 21 | +extern bool allow_vram_carveout; | |
| 21 | 22 | |
| 22 | 23 | enum { |
| 23 | 24 | ADRENO_FW_PM4 = 0, |
| @@ -211,6 +212,11 @@ static inline int adreno_is_a540(struct adreno_gpu *gpu) · 187 unmodified lines | ||
| 211 | 212 | return gpu->revn == 540; |
| 212 | 213 | } |
| 213 | 214 | |
| 215 | +static inline bool adreno_is_a6xx(struct adreno_gpu *gpu) | |
| 216 | +{ | |
| 217 | + return ((gpu->revn < 700 && gpu->revn > 599)); | |
| 218 | +} | |
| 219 | + | |
| 214 | 220 | static inline int adreno_is_a618(struct adreno_gpu *gpu) |
| 215 | 221 | { |
| 216 | 222 | return gpu->revn == 618; |
| @@ -693,6 +693,13 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data) · 692 unmodified lines | ||
| 693 | 693 | return 0; |
| 694 | 694 | } |
| 695 | 695 | |
| 696 | + if (state == ST_CONNECT_PENDING) { | |
| 697 | + /* wait until ST_CONNECTED */ | |
| 698 | + dp_add_event(dp, EV_IRQ_HPD_INT, 0, 1); /* delay = 1 */ | |
| 699 | + mutex_unlock(&dp->event_mutex); | |
| 700 | + return 0; | |
| 701 | + } | |
| 702 | + | |
| 696 | 703 | ret = dp_display_usbpd_attention_cb(&dp->pdev->dev); |
| 697 | 704 | if (ret == -ECONNRESET) { /* cable unplugged */ |
| 698 | 705 | dp->core_initialized = false; |
| @@ -167,12 +167,18 @@ int dp_panel_read_sink_caps(struct dp_panel *dp_panel, · 166 unmodified lines | ||
| 167 | 167 | panel = container_of(dp_panel, struct dp_panel_private, dp_panel); |
| 168 | 168 | |
| 169 | 169 | rc = dp_panel_read_dpcd(dp_panel); |
| 170 | + if (rc) { | |
| 171 | + DRM_ERROR("read dpcd failed %d\n", rc); | |
| 172 | + return rc; | |
| 173 | + } | |
| 174 | + | |
| 170 | 175 | bw_code = drm_dp_link_rate_to_bw_code(dp_panel->link_info.rate); |
| 171 | − if (rc || !is_link_rate_valid(bw_code) || | |
| 176 | + if (!is_link_rate_valid(bw_code) || | |
| 172 | 177 | !is_lane_count_valid(dp_panel->link_info.num_lanes) || |
| 173 | 178 | (bw_code > dp_panel->max_bw_code)) { |
| 174 | − DRM_ERROR("read dpcd failed %d\n", rc); | |
| 175 | − return rc; | |
| 179 | + DRM_ERROR("Illegal link rate=%d lane=%d\n", dp_panel->link_info.rate, | |
| 180 | + dp_panel->link_info.num_lanes); | |
| 181 | + return -EINVAL; | |
| 176 | 182 | } |
| 177 | 183 | |
| 178 | 184 | if (dp_panel->dfp_present) { |
| @@ -457,14 +457,14 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv) · 456 unmodified lines | ||
| 457 | 457 | |
| 458 | 458 | drm_mode_config_init(ddev); |
| 459 | 459 | |
| 460 | − /* Bind all our sub-components: */ | |
| 461 | − ret = component_bind_all(dev, ddev); | |
| 460 | + ret = msm_init_vram(ddev); | |
| 462 | 461 | if (ret) |
| 463 | 462 | goto err_destroy_mdss; |
| 464 | 463 | |
| 465 | − ret = msm_init_vram(ddev); | |
| 464 | + /* Bind all our sub-components: */ | |
| 465 | + ret = component_bind_all(dev, ddev); | |
| 466 | 466 | if (ret) |
| 467 | − goto err_msm_uninit; | |
| 467 | + goto err_destroy_mdss; | |
| 468 | 468 | |
| 469 | 469 | dma_set_max_seg_size(dev, UINT_MAX); |
| 470 | 470 | |
| @@ -96,6 +96,8 @@ static struct page **get_pages(struct drm_gem_object *obj) · 95 unmodified lines | ||
| 96 | 96 | { |
| 97 | 97 | struct msm_gem_object *msm_obj = to_msm_bo(obj); |
| 98 | 98 | |
| 99 | + WARN_ON(!msm_gem_is_locked(obj)); | |
| 100 | + | |
| 99 | 101 | if (!msm_obj->pages) { |
| 100 | 102 | struct drm_device *dev = obj->dev; |
| 101 | 103 | struct page **p; |
| @@ -988,6 +990,8 @@ void msm_gem_free_object(struct drm_gem_object *obj) · 886 unmodified lines | ||
| 988 | 990 | if (msm_obj->pages) |
| 989 | 991 | kvfree(msm_obj->pages); |
| 990 | 992 | |
| 993 | + put_iova_vmas(obj); | |
| 994 | + | |
| 991 | 995 | /* dma_buf_detach() grabs resv lock, so we need to unlock |
| 992 | 996 | * prior to drm_prime_gem_destroy |
| 993 | 997 | */ |
| @@ -997,11 +1001,10 @@ void msm_gem_free_object(struct drm_gem_object *obj) · 3 unmodified lines | ||
| 997 | 1001 | } else { |
| 998 | 1002 | msm_gem_vunmap(obj); |
| 999 | 1003 | put_pages(obj); |
| 1004 | + put_iova_vmas(obj); | |
| 1000 | 1005 | msm_gem_unlock(obj); |
| 1001 | 1006 | } |
| 1002 | 1007 | |
| 1003 | − put_iova_vmas(obj); | |
| 1004 | − | |
| 1005 | 1008 | drm_gem_object_release(obj); |
| 1006 | 1009 | |
| 1007 | 1010 | kfree(msm_obj); |
| @@ -1115,6 +1118,8 @@ static struct drm_gem_object *_msm_gem_new(struct drm_device *dev, · 107 unmodified lines | ||
| 1115 | 1118 | struct msm_gem_vma *vma; |
| 1116 | 1119 | struct page **pages; |
| 1117 | 1120 | |
| 1121 | + drm_gem_private_object_init(dev, obj, size); | |
| 1122 | + | |
| 1118 | 1123 | msm_gem_lock(obj); |
| 1119 | 1124 | |
| 1120 | 1125 | vma = add_vma(obj, NULL); |
| @@ -1126,9 +1131,9 @@ static struct drm_gem_object *_msm_gem_new(struct drm_device *dev, · 5 unmodified lines | ||
| 1126 | 1131 | |
| 1127 | 1132 | to_msm_bo(obj)->vram_node = &vma->node; |
| 1128 | 1133 | |
| 1129 | − drm_gem_private_object_init(dev, obj, size); | |
| 1130 | − | |
| 1134 | + msm_gem_lock(obj); | |
| 1131 | 1135 | pages = get_pages(obj); |
| 1136 | + msm_gem_unlock(obj); | |
| 1132 | 1137 | if (IS_ERR(pages)) { |
| 1133 | 1138 | ret = PTR_ERR(pages); |
| 1134 | 1139 | goto fail; |
| @@ -37,6 +37,7 @@ nouveau-y += dispnv50/wimmc37b.o · 36 unmodified lines | ||
| 37 | 37 | nouveau-y += dispnv50/wndw.o |
| 38 | 38 | nouveau-y += dispnv50/wndwc37e.o |
| 39 | 39 | nouveau-y += dispnv50/wndwc57e.o |
| 40 | +nouveau-y += dispnv50/wndwc67e.o | |
| 40 | 41 | |
| 41 | 42 | nouveau-y += dispnv50/base.o |
| 42 | 43 | nouveau-y += dispnv50/base507c.o |
| @@ -88,7 +88,11 @@ base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) · 87 unmodified lines | ||
| 88 | 88 | NVVAL(NV507C, SET_CONVERSION, OFS, 0x64)); |
| 89 | 89 | } else { |
| 90 | 90 | PUSH_MTHD(push, NV507C, SET_PROCESSING, |
| 91 | − NVDEF(NV507C, SET_PROCESSING, USE_GAIN_OFS, DISABLE)); | |
| 91 | + NVDEF(NV507C, SET_PROCESSING, USE_GAIN_OFS, DISABLE), | |
| 92 | + | |
| 93 | + SET_CONVERSION, | |
| 94 | + NVVAL(NV507C, SET_CONVERSION, GAIN, 0) | | |
| 95 | + NVVAL(NV507C, SET_CONVERSION, OFS, 0)); | |
| 92 | 96 | } |
| 93 | 97 | |
| 94 | 98 | PUSH_MTHD(push, NV507C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8); |
| @@ -49,7 +49,11 @@ base827c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) · 48 unmodified lines | ||
| 49 | 49 | NVVAL(NV827C, SET_CONVERSION, OFS, 0x64)); |
| 50 | 50 | } else { |
| 51 | 51 | PUSH_MTHD(push, NV827C, SET_PROCESSING, |
| 52 | − NVDEF(NV827C, SET_PROCESSING, USE_GAIN_OFS, DISABLE)); | |
| 52 | + NVDEF(NV827C, SET_PROCESSING, USE_GAIN_OFS, DISABLE), | |
| 53 | + | |
| 54 | + SET_CONVERSION, | |
| 55 | + NVVAL(NV827C, SET_CONVERSION, GAIN, 0) | | |
| 56 | + NVVAL(NV827C, SET_CONVERSION, OFS, 0)); | |
| 53 | 57 | } |
| 54 | 58 | |
| 55 | 59 | PUSH_MTHD(push, NV827C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8, |
| @@ -42,6 +42,7 @@ nv50_core_new(struct nouveau_drm *drm, struct nv50_core **pcore) · 41 unmodified lines | ||
| 42 | 42 | int version; |
| 43 | 43 | int (*new)(struct nouveau_drm *, s32, struct nv50_core **); |
| 44 | 44 | } cores[] = { |
| 45 | + { GA102_DISP_CORE_CHANNEL_DMA, 0, corec57d_new }, | |
| 45 | 46 | { TU102_DISP_CORE_CHANNEL_DMA, 0, corec57d_new }, |
| 46 | 47 | { GV100_DISP_CORE_CHANNEL_DMA, 0, corec37d_new }, |
| 47 | 48 | { GP102_DISP_CORE_CHANNEL_DMA, 0, core917d_new }, |
| @@ -31,6 +31,7 @@ nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) · 30 unmodified lines | ||
| 31 | 31 | int version; |
| 32 | 32 | int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); |
| 33 | 33 | } curses[] = { |
| 34 | + { GA102_DISP_CURSOR, 0, cursc37a_new }, | |
| 34 | 35 | { TU102_DISP_CURSOR, 0, cursc37a_new }, |
| 35 | 36 | { GV100_DISP_CURSOR, 0, cursc37a_new }, |
| 36 | 37 | { GK104_DISP_CURSOR, 0, curs907a_new }, |
| @@ -222,7 +222,7 @@ nv50_dmac_wait(struct nvif_push *push, u32 size) · 221 unmodified lines | ||
| 222 | 222 | |
| 223 | 223 | int |
| 224 | 224 | nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, |
| 225 | − const s32 *oclass, u8 head, void *data, u32 size, u64 syncbuf, | |
| 225 | + const s32 *oclass, u8 head, void *data, u32 size, s64 syncbuf, | |
| 226 | 226 | struct nv50_dmac *dmac) |
| 227 | 227 | { |
| 228 | 228 | struct nouveau_cli *cli = (void *)device->object.client; |
| @@ -271,7 +271,7 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, · 42 unmodified lines | ||
| 271 | 271 | if (ret) |
| 272 | 272 | return ret; |
| 273 | 273 | |
| 274 | − if (!syncbuf) | |
| 274 | + if (syncbuf < 0) | |
| 275 | 275 | return 0; |
| 276 | 276 | |
| 277 | 277 | ret = nvif_object_ctor(&dmac->base.user, "kmsSyncCtxDma", NV50_DISP_HANDLE_SYNCBUF, |
| @@ -2663,6 +2663,14 @@ nv50_display_create(struct drm_device *dev) · 2385 unmodified lines | ||
| 2663 | 2663 | else |
| 2664 | 2664 | nouveau_display(dev)->format_modifiers = disp50xx_modifiers; |
| 2665 | 2665 | |
| 2666 | + if (disp->disp->object.oclass >= GK104_DISP) { | |
| 2667 | + dev->mode_config.cursor_width = 256; | |
| 2668 | + dev->mode_config.cursor_height = 256; | |
| 2669 | + } else { | |
| 2670 | + dev->mode_config.cursor_width = 64; | |
| 2671 | + dev->mode_config.cursor_height = 64; | |
| 2672 | + } | |
| 2673 | + | |
| 2666 | 2674 | /* create crtc objects to represent the hw heads */ |
| 2667 | 2675 | if (disp->disp->object.oclass >= GV100_DISP) |
| 2668 | 2676 | crtcs = nvif_rd32(&device->object, 0x610060) & 0xff; |
| @@ -95,7 +95,7 @@ struct nv50_outp_atom { · 94 unmodified lines | ||
| 95 | 95 | |
| 96 | 96 | int nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, |
| 97 | 97 | const s32 *oclass, u8 head, void *data, u32 size, |
| 98 | − u64 syncbuf, struct nv50_dmac *dmac); | |
| 98 | + s64 syncbuf, struct nv50_dmac *dmac); | |
| 99 | 99 | void nv50_dmac_destroy(struct nv50_dmac *); |
| 100 | 100 | |
| 101 | 101 | /* |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include "head.h" |
| 23 | 23 | #include "core.h" |
| 24 | 24 | |
| 25 | +#include "nvif/push.h" | |
| 25 | 26 | #include <nvif/push507c.h> |
| 26 | 27 | |
| 27 | 28 | #include <nvhw/class/cl917d.h> |
| @@ -73,6 +74,31 @@ head917d_base(struct nv50_head *head, struct nv50_head_atom *asyh) · 45 unmodified lines | ||
| 73 | 74 | return 0; |
| 74 | 75 | } |
| 75 | 76 | |
| 77 | +static int | |
| 78 | +head917d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) | |
| 79 | +{ | |
| 80 | + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; | |
| 81 | + const int i = head->base.index; | |
| 82 | + int ret; | |
| 83 | + | |
| 84 | + ret = PUSH_WAIT(push, 5); | |
| 85 | + if (ret) | |
| 86 | + return ret; | |
| 87 | + | |
| 88 | + PUSH_MTHD(push, NV917D, HEAD_SET_CONTROL_CURSOR(i), | |
| 89 | + NVDEF(NV917D, HEAD_SET_CONTROL_CURSOR, ENABLE, ENABLE) | | |
| 90 | + NVVAL(NV917D, HEAD_SET_CONTROL_CURSOR, FORMAT, asyh->curs.format) | | |
| 91 | + NVVAL(NV917D, HEAD_SET_CONTROL_CURSOR, SIZE, asyh->curs.layout) | | |
| 92 | + NVVAL(NV917D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_X, 0) | | |
| 93 | + NVVAL(NV917D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_Y, 0) | | |
| 94 | + NVDEF(NV917D, HEAD_SET_CONTROL_CURSOR, COMPOSITION, ALPHA_BLEND), | |
| 95 | + | |
| 96 | + HEAD_SET_OFFSET_CURSOR(i), asyh->curs.offset >> 8); | |
| 97 | + | |
| 98 | + PUSH_MTHD(push, NV917D, HEAD_SET_CONTEXT_DMA_CURSOR(i), asyh->curs.handle); | |
| 99 | + return 0; | |
| 100 | +} | |
| 101 | + | |
| 76 | 102 | int |
| 77 | 103 | head917d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw, |
| 78 | 104 | struct nv50_head_atom *asyh) |
| @@ -101,7 +127,7 @@ head917d = { · 22 unmodified lines | ||
| 101 | 127 | .core_clr = head907d_core_clr, |
| 102 | 128 | .curs_layout = head917d_curs_layout, |
| 103 | 129 | .curs_format = head507d_curs_format, |
| 104 | − .curs_set = head907d_curs_set, | |
| 130 | + .curs_set = head917d_curs_set, | |
| 105 | 131 | .curs_clr = head907d_curs_clr, |
| 106 | 132 | .base = head917d_base, |
| 107 | 133 | .ovly = head907d_ovly, |
| @@ -31,6 +31,7 @@ nv50_wimm_init(struct nouveau_drm *drm, struct nv50_wndw *wndw) · 30 unmodified lines | ||
| 31 | 31 | int version; |
| 32 | 32 | int (*init)(struct nouveau_drm *, s32, struct nv50_wndw *); |
| 33 | 33 | } wimms[] = { |
| 34 | + { GA102_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, | |
| 34 | 35 | { TU102_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, |
| 35 | 36 | { GV100_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, |
| 36 | 37 | {} |
| @@ -76,7 +76,7 @@ wimmc37b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, · 75 unmodified lines | ||
| 76 | 76 | int ret; |
| 77 | 77 | |
| 78 | 78 | ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, |
| 79 | − &oclass, 0, &args, sizeof(args), 0, | |
| 79 | + &oclass, 0, &args, sizeof(args), -1, | |
| 80 | 80 | &wndw->wimm); |
| 81 | 81 | if (ret) { |
| 82 | 82 | NV_ERROR(drm, "wimm%04x allocation failed: %d\n", oclass, ret); |
| @@ -702,6 +702,11 @@ nv50_wndw_init(struct nv50_wndw *wndw) · 701 unmodified lines | ||
| 702 | 702 | nvif_notify_get(&wndw->notify); |
| 703 | 703 | } |
| 704 | 704 | |
| 705 | +static const u64 nv50_cursor_format_modifiers[] = { | |
| 706 | + DRM_FORMAT_MOD_LINEAR, | |
| 707 | + DRM_FORMAT_MOD_INVALID, | |
| 708 | +}; | |
| 709 | + | |
| 705 | 710 | int |
| 706 | 711 | nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, |
| 707 | 712 | enum drm_plane_type type, const char *name, int index, |
| @@ -713,6 +718,7 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, · 5 unmodified lines | ||
| 713 | 718 | struct nvif_mmu *mmu = &drm->client.mmu; |
| 714 | 719 | struct nv50_disp *disp = nv50_disp(dev); |
| 715 | 720 | struct nv50_wndw *wndw; |
| 721 | + const u64 *format_modifiers; | |
| 716 | 722 | int nformat; |
| 717 | 723 | int ret; |
| 718 | 724 | |
| @@ -728,10 +734,13 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, · 9 unmodified lines | ||
| 728 | 734 | |
| 729 | 735 | for (nformat = 0; format[nformat]; nformat++); |
| 730 | 736 | |
| 731 | − ret = drm_universal_plane_init(dev, &wndw->plane, heads, &nv50_wndw, | |
| 732 | − format, nformat, | |
| 733 | − nouveau_display(dev)->format_modifiers, | |
| 734 | − type, "%s-%d", name, index); | |
| 737 | + if (type == DRM_PLANE_TYPE_CURSOR) | |
| 738 | + format_modifiers = nv50_cursor_format_modifiers; | |
| 739 | + else | |
| 740 | + format_modifiers = nouveau_display(dev)->format_modifiers; | |
| 741 | + | |
| 742 | + ret = drm_universal_plane_init(dev, &wndw->plane, heads, &nv50_wndw, format, nformat, | |
| 743 | + format_modifiers, type, "%s-%d", name, index); | |
| 735 | 744 | if (ret) { |
| 736 | 745 | kfree(*pwndw); |
| 737 | 746 | *pwndw = NULL; |
| @@ -784,6 +793,7 @@ nv50_wndw_new(struct nouveau_drm *drm, enum drm_plane_type type, int index, · 46 unmodified lines | ||
| 784 | 793 | int (*new)(struct nouveau_drm *, enum drm_plane_type, |
| 785 | 794 | int, s32, struct nv50_wndw **); |
| 786 | 795 | } wndws[] = { |
| 796 | + { GA102_DISP_WINDOW_CHANNEL_DMA, 0, wndwc67e_new }, | |
| 787 | 797 | { TU102_DISP_WINDOW_CHANNEL_DMA, 0, wndwc57e_new }, |
| 788 | 798 | { GV100_DISP_WINDOW_CHANNEL_DMA, 0, wndwc37e_new }, |
| 789 | 799 | {} |
| @@ -129,6 +129,14 @@ int wndwc37e_update(struct nv50_wndw *, u32 *); · 128 unmodified lines | ||
| 129 | 129 | |
| 130 | 130 | int wndwc57e_new(struct nouveau_drm *, enum drm_plane_type, int, s32, |
| 131 | 131 | struct nv50_wndw **); |
| 132 | +bool wndwc57e_ilut(struct nv50_wndw *, struct nv50_wndw_atom *, int); | |
| 133 | +int wndwc57e_ilut_set(struct nv50_wndw *, struct nv50_wndw_atom *); | |
| 134 | +int wndwc57e_ilut_clr(struct nv50_wndw *); | |
| 135 | +int wndwc57e_csc_set(struct nv50_wndw *, struct nv50_wndw_atom *); | |
| 136 | +int wndwc57e_csc_clr(struct nv50_wndw *); | |
| 137 | + | |
| 138 | +int wndwc67e_new(struct nouveau_drm *, enum drm_plane_type, int, s32, | |
| 139 | + struct nv50_wndw **); | |
| 132 | 140 | |
| 133 | 141 | int nv50_wndw_new(struct nouveau_drm *, enum drm_plane_type, int index, |
| 134 | 142 | struct nv50_wndw **); |
| @@ -80,7 +80,7 @@ wndwc57e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) · 79 unmodified lines | ||
| 80 | 80 | return 0; |
| 81 | 81 | } |
| 82 | 82 | |
| 83 | −static int | |
| 83 | +int | |
| 84 | 84 | wndwc57e_csc_clr(struct nv50_wndw *wndw) |
| 85 | 85 | { |
| 86 | 86 | struct nvif_push *push = wndw->wndw.push; |
| @@ -98,7 +98,7 @@ wndwc57e_csc_clr(struct nv50_wndw *wndw) · 11 unmodified lines | ||
| 98 | 98 | return 0; |
| 99 | 99 | } |
| 100 | 100 | |
| 101 | −static int | |
| 101 | +int | |
| 102 | 102 | wndwc57e_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) |
| 103 | 103 | { |
| 104 | 104 | struct nvif_push *push = wndw->wndw.push; |
| @@ -111,7 +111,7 @@ wndwc57e_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) · 6 unmodified lines | ||
| 111 | 111 | return 0; |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | −static int | |
| 114 | +int | |
| 115 | 115 | wndwc57e_ilut_clr(struct nv50_wndw *wndw) |
| 116 | 116 | { |
| 117 | 117 | struct nvif_push *push = wndw->wndw.push; |
| @@ -124,7 +124,7 @@ wndwc57e_ilut_clr(struct nv50_wndw *wndw) · 6 unmodified lines | ||
| 124 | 124 | return 0; |
| 125 | 125 | } |
| 126 | 126 | |
| 127 | −static int | |
| 127 | +int | |
| 128 | 128 | wndwc57e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) |
| 129 | 129 | { |
| 130 | 130 | struct nvif_push *push = wndw->wndw.push; |
| @@ -179,7 +179,7 @@ wndwc57e_ilut_load(struct drm_color_lut *in, int size, void __iomem *mem) · 48 unmodified lines | ||
| 179 | 179 | writew(readw(mem - 4), mem + 4); |
| 180 | 180 | } |
| 181 | 181 | |
| 182 | −static bool | |
| 182 | +bool | |
| 183 | 183 | wndwc57e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size) |
| 184 | 184 | { |
| 185 | 185 | if (size = size ? size : 1024, size != 256 && size != 1024) |
| @@ -0,0 +1,106 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 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 shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "wndw.h" | |
| 23 | +#include "atom.h" | |
| 24 | + | |
| 25 | +#include <nvif/pushc37b.h> | |
| 26 | + | |
| 27 | +#include <nvhw/class/clc57e.h> | |
| 28 | + | |
| 29 | +static int | |
| 30 | +wndwc67e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) | |
| 31 | +{ | |
| 32 | + struct nvif_push *push = wndw->wndw.push; | |
| 33 | + int ret; | |
| 34 | + | |
| 35 | + if ((ret = PUSH_WAIT(push, 17))) | |
| 36 | + return ret; | |
| 37 | + | |
| 38 | + PUSH_MTHD(push, NVC57E, SET_PRESENT_CONTROL, | |
| 39 | + NVVAL(NVC57E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval) | | |
| 40 | + NVVAL(NVC57E, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) | | |
| 41 | + NVDEF(NVC57E, SET_PRESENT_CONTROL, TIMESTAMP_MODE, DISABLE)); | |
| 42 | + | |
| 43 | + PUSH_MTHD(push, NVC57E, SET_SIZE, | |
| 44 | + NVVAL(NVC57E, SET_SIZE, WIDTH, asyw->image.w) | | |
| 45 | + NVVAL(NVC57E, SET_SIZE, HEIGHT, asyw->image.h), | |
| 46 | + | |
| 47 | + SET_STORAGE, | |
| 48 | + NVVAL(NVC57E, SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh), | |
| 49 | + | |
| 50 | + SET_PARAMS, | |
| 51 | + NVVAL(NVC57E, SET_PARAMS, FORMAT, asyw->image.format) | | |
| 52 | + NVDEF(NVC57E, SET_PARAMS, CLAMP_BEFORE_BLEND, DISABLE) | | |
| 53 | + NVDEF(NVC57E, SET_PARAMS, SWAP_UV, DISABLE) | | |
| 54 | + NVDEF(NVC57E, SET_PARAMS, FMT_ROUNDING_MODE, ROUND_TO_NEAREST), | |
| 55 | + | |
| 56 | + SET_PLANAR_STORAGE(0), | |
| 57 | + NVVAL(NVC57E, SET_PLANAR_STORAGE, PITCH, asyw->image.blocks[0]) | | |
| 58 | + NVVAL(NVC57E, SET_PLANAR_STORAGE, PITCH, asyw->image.pitch[0] >> 6)); | |
| 59 | + | |
| 60 | + PUSH_MTHD(push, NVC57E, SET_CONTEXT_DMA_ISO(0), asyw->image.handle, 1); | |
| 61 | + PUSH_MTHD(push, NVC57E, SET_OFFSET(0), asyw->image.offset[0] >> 8); | |
| 62 | + | |
| 63 | + PUSH_MTHD(push, NVC57E, SET_POINT_IN(0), | |
| 64 | + NVVAL(NVC57E, SET_POINT_IN, X, asyw->state.src_x >> 16) | | |
| 65 | + NVVAL(NVC57E, SET_POINT_IN, Y, asyw->state.src_y >> 16)); | |
| 66 | + | |
| 67 | + PUSH_MTHD(push, NVC57E, SET_SIZE_IN, | |
| 68 | + NVVAL(NVC57E, SET_SIZE_IN, WIDTH, asyw->state.src_w >> 16) | | |
| 69 | + NVVAL(NVC57E, SET_SIZE_IN, HEIGHT, asyw->state.src_h >> 16)); | |
| 70 | + | |
| 71 | + PUSH_MTHD(push, NVC57E, SET_SIZE_OUT, | |
| 72 | + NVVAL(NVC57E, SET_SIZE_OUT, WIDTH, asyw->state.crtc_w) | | |
| 73 | + NVVAL(NVC57E, SET_SIZE_OUT, HEIGHT, asyw->state.crtc_h)); | |
| 74 | + return 0; | |
| 75 | +} | |
| 76 | + | |
| 77 | +static const struct nv50_wndw_func | |
| 78 | +wndwc67e = { | |
| 79 | + .acquire = wndwc37e_acquire, | |
| 80 | + .release = wndwc37e_release, | |
| 81 | + .sema_set = wndwc37e_sema_set, | |
| 82 | + .sema_clr = wndwc37e_sema_clr, | |
| 83 | + .ntfy_set = wndwc37e_ntfy_set, | |
| 84 | + .ntfy_clr = wndwc37e_ntfy_clr, | |
| 85 | + .ntfy_reset = corec37d_ntfy_init, | |
| 86 | + .ntfy_wait_begun = base507c_ntfy_wait_begun, | |
| 87 | + .ilut = wndwc57e_ilut, | |
| 88 | + .ilut_identity = true, | |
| 89 | + .ilut_size = 1024, | |
| 90 | + .xlut_set = wndwc57e_ilut_set, | |
| 91 | + .xlut_clr = wndwc57e_ilut_clr, | |
| 92 | + .csc = base907c_csc, | |
| 93 | + .csc_set = wndwc57e_csc_set, | |
| 94 | + .csc_clr = wndwc57e_csc_clr, | |
| 95 | + .image_set = wndwc67e_image_set, | |
| 96 | + .image_clr = wndwc37e_image_clr, | |
| 97 | + .blend_set = wndwc37e_blend_set, | |
| 98 | + .update = wndwc37e_update, | |
| 99 | +}; | |
| 100 | + | |
| 101 | +int | |
| 102 | +wndwc67e_new(struct nouveau_drm *drm, enum drm_plane_type type, int index, | |
| 103 | + s32 oclass, struct nv50_wndw **pwndw) | |
| 104 | +{ | |
| 105 | + return wndwc37e_new_(&wndwc67e, drm, type, index, oclass, BIT(index >> 1), pwndw); | |
| 106 | +} | |
| @@ -66,6 +66,10 @@ · 65 unmodified lines | ||
| 66 | 66 | #define NV917D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_ALPHA_BLEND (0x00000000) |
| 67 | 67 | #define NV917D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_PREMULT_ALPHA_BLEND (0x00000001) |
| 68 | 68 | #define NV917D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_XOR (0x00000002) |
| 69 | +#define NV917D_HEAD_SET_OFFSET_CURSOR(a) (0x00000484 + (a)*0x00000300) | |
| 70 | +#define NV917D_HEAD_SET_OFFSET_CURSOR_ORIGIN 31:0 | |
| 71 | +#define NV917D_HEAD_SET_CONTEXT_DMA_CURSOR(a) (0x0000048C + (a)*0x00000300) | |
| 72 | +#define NV917D_HEAD_SET_CONTEXT_DMA_CURSOR_HANDLE 31:0 | |
| 69 | 73 | #define NV917D_HEAD_SET_DITHER_CONTROL(a) (0x000004A0 + (a)*0x00000300) |
| 70 | 74 | #define NV917D_HEAD_SET_DITHER_CONTROL_ENABLE 0:0 |
| 71 | 75 | #define NV917D_HEAD_SET_DITHER_CONTROL_ENABLE_DISABLE (0x00000000) |
| @@ -33,6 +33,7 @@ struct nv_device_info_v0 { · 32 unmodified lines | ||
| 33 | 33 | #define NV_DEVICE_INFO_V0_PASCAL 0x0a |
| 34 | 34 | #define NV_DEVICE_INFO_V0_VOLTA 0x0b |
| 35 | 35 | #define NV_DEVICE_INFO_V0_TURING 0x0c |
| 36 | +#define NV_DEVICE_INFO_V0_AMPERE 0x0d | |
| 36 | 37 | __u8 family; |
| 37 | 38 | __u8 pad06[2]; |
| 38 | 39 | __u64 ram_size; |
| @@ -88,6 +88,7 @@ · 87 unmodified lines | ||
| 88 | 88 | #define GP102_DISP /* cl5070.h */ 0x00009870 |
| 89 | 89 | #define GV100_DISP /* cl5070.h */ 0x0000c370 |
| 90 | 90 | #define TU102_DISP /* cl5070.h */ 0x0000c570 |
| 91 | +#define GA102_DISP /* cl5070.h */ 0x0000c670 | |
| 91 | 92 | |
| 92 | 93 | #define GV100_DISP_CAPS 0x0000c373 |
| 93 | 94 | |
| @@ -103,6 +104,7 @@ · 9 unmodified lines | ||
| 103 | 104 | #define GK104_DISP_CURSOR /* cl507a.h */ 0x0000917a |
| 104 | 105 | #define GV100_DISP_CURSOR /* cl507a.h */ 0x0000c37a |
| 105 | 106 | #define TU102_DISP_CURSOR /* cl507a.h */ 0x0000c57a |
| 107 | +#define GA102_DISP_CURSOR /* cl507a.h */ 0x0000c67a | |
| 106 | 108 | |
| 107 | 109 | #define NV50_DISP_OVERLAY /* cl507b.h */ 0x0000507b |
| 108 | 110 | #define G82_DISP_OVERLAY /* cl507b.h */ 0x0000827b |
| @@ -112,6 +114,7 @@ · 3 unmodified lines | ||
| 112 | 114 | |
| 113 | 115 | #define GV100_DISP_WINDOW_IMM_CHANNEL_DMA /* clc37b.h */ 0x0000c37b |
| 114 | 116 | #define TU102_DISP_WINDOW_IMM_CHANNEL_DMA /* clc37b.h */ 0x0000c57b |
| 117 | +#define GA102_DISP_WINDOW_IMM_CHANNEL_DMA /* clc37b.h */ 0x0000c67b | |
| 115 | 118 | |
| 116 | 119 | #define NV50_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000507c |
| 117 | 120 | #define G82_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000827c |
| @@ -135,6 +138,7 @@ · 17 unmodified lines | ||
| 135 | 138 | #define GP102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000987d |
| 136 | 139 | #define GV100_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c37d |
| 137 | 140 | #define TU102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c57d |
| 141 | +#define GA102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c67d | |
| 138 | 142 | |
| 139 | 143 | #define NV50_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000507e |
| 140 | 144 | #define G82_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000827e |
| @@ -145,6 +149,7 @@ · 4 unmodified lines | ||
| 145 | 149 | |
| 146 | 150 | #define GV100_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c37e |
| 147 | 151 | #define TU102_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c57e |
| 152 | +#define GA102_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c67e | |
| 148 | 153 | |
| 149 | 154 | #define NV50_TESLA 0x00005097 |
| 150 | 155 | #define G82_TESLA 0x00008297 |
| @@ -123,131 +123,131 @@ PUSH_KICK(struct nvif_push *push) · 122 unmodified lines | ||
| 123 | 123 | } while(0) |
| 124 | 124 | #endif |
| 125 | 125 | |
| 126 | −#define PUSH_1(X,f,ds,n,c,o,p,s,mA,dA) do { \ | |
| 127 | − PUSH_##o##_HDR((p), s, mA, (c)+(n)); \ | |
| 128 | − PUSH_##f(X, (p), X##mA, 1, o, (dA), ds, ""); \ | |
| 126 | +#define PUSH_1(X,f,ds,n,o,p,s,mA,dA) do { \ | |
| 127 | + PUSH_##o##_HDR((p), s, mA, (ds)+(n)); \ | |
| 128 | + PUSH_##f(X, (p), X##mA, 1, o, (dA), ds, ""); \ | |
| 129 | 129 | } while(0) |
| 130 | −#define PUSH_2(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 131 | − PUSH_ASSERT((mB) - (mA) == (1?PUSH_##o##_INC), "mthd1"); \ | |
| 132 | − PUSH_1(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ | |
| 133 | − PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 130 | +#define PUSH_2(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 131 | + PUSH_ASSERT((mB) - (mA) == (1?PUSH_##o##_INC), "mthd1"); \ | |
| 132 | + PUSH_1(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ | |
| 133 | + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 134 | 134 | } while(0) |
| 135 | −#define PUSH_3(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 136 | − PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd2"); \ | |
| 137 | − PUSH_2(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ | |
| 138 | − PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 135 | +#define PUSH_3(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 136 | + PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd2"); \ | |
| 137 | + PUSH_2(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ | |
| 138 | + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 139 | 139 | } while(0) |
| 140 | −#define PUSH_4(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 141 | − PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd3"); \ | |
| 142 | − PUSH_3(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ | |
| 143 | − PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 140 | +#define PUSH_4(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 141 | + PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd3"); \ | |
| 142 | + PUSH_3(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ | |
| 143 | + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 144 | 144 | } while(0) |
| 145 | −#define PUSH_5(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 146 | − PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd4"); \ | |
| 147 | − PUSH_4(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ | |
| 148 | − PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 145 | +#define PUSH_5(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 146 | + PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd4"); \ | |
| 147 | + PUSH_4(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ | |
| 148 | + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 149 | 149 | } while(0) |
| 150 | −#define PUSH_6(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 151 | − PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd5"); \ | |
| 152 | − PUSH_5(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ | |
| 153 | − PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 150 | +#define PUSH_6(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 151 | + PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd5"); \ | |
| 152 | + PUSH_5(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ | |
| 153 | + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 154 | 154 | } while(0) |
| 155 | −#define PUSH_7(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 156 | − PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd6"); \ | |
| 157 | − PUSH_6(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ | |
| 158 | − PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 155 | +#define PUSH_7(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 156 | + PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd6"); \ | |
| 157 | + PUSH_6(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ | |
| 158 | + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 159 | 159 | } while(0) |
| 160 | −#define PUSH_8(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 161 | − PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd7"); \ | |
| 162 | − PUSH_7(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ | |
| 163 | − PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 160 | +#define PUSH_8(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 161 | + PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd7"); \ | |
| 162 | + PUSH_7(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ | |
| 163 | + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 164 | 164 | } while(0) |
| 165 | −#define PUSH_9(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 166 | − PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd8"); \ | |
| 167 | − PUSH_8(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ | |
| 168 | − PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 165 | +#define PUSH_9(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 166 | + PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd8"); \ | |
| 167 | + PUSH_8(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ | |
| 168 | + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 169 | 169 | } while(0) |
| 170 | −#define PUSH_10(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 171 | − PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd9"); \ | |
| 172 | − PUSH_9(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ | |
| 173 | − PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 170 | +#define PUSH_10(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ | |
| 171 | + PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd9"); \ | |
| 172 | + PUSH_9(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ | |
| 173 | + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ | |
| 174 | 174 | } while(0) |
| 175 | 175 | |
| 176 | −#define PUSH_1D(X,o,p,s,mA,dA) \ | |
| 177 | − PUSH_1(X, DATA_, 1, 1, 0, o, (p), s, X##mA, (dA)) | |
| 178 | −#define PUSH_2D(X,o,p,s,mA,dA,mB,dB) \ | |
| 179 | − PUSH_2(X, DATA_, 1, 1, 0, o, (p), s, X##mB, (dB), \ | |
| 180 | − X##mA, (dA)) | |
| 181 | −#define PUSH_3D(X,o,p,s,mA,dA,mB,dB,mC,dC) \ | |
| 182 | − PUSH_3(X, DATA_, 1, 1, 0, o, (p), s, X##mC, (dC), \ | |
| 183 | − X##mB, (dB), \ | |
| 184 | − X##mA, (dA)) | |
| 185 | −#define PUSH_4D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD) \ | |
| 186 | − PUSH_4(X, DATA_, 1, 1, 0, o, (p), s, X##mD, (dD), \ | |
| 187 | − X##mC, (dC), \ | |
| 188 | − X##mB, (dB), \ | |
| 189 | − X##mA, (dA)) | |
| 190 | −#define PUSH_5D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE) \ | |
| 191 | − PUSH_5(X, DATA_, 1, 1, 0, o, (p), s, X##mE, (dE), \ | |
| 192 | − X##mD, (dD), \ | |
| 193 | − X##mC, (dC), \ | |
| 194 | − X##mB, (dB), \ | |
| 195 | − X##mA, (dA)) | |
| 176 | +#define PUSH_1D(X,o,p,s,mA,dA) \ | |
| 177 | + PUSH_1(X, DATA_, 1, 0, o, (p), s, X##mA, (dA)) | |
| 178 | +#define PUSH_2D(X,o,p,s,mA,dA,mB,dB) \ | |
| 179 | + PUSH_2(X, DATA_, 1, 0, o, (p), s, X##mB, (dB), \ | |
| 180 | + X##mA, (dA)) | |
| 181 | +#define PUSH_3D(X,o,p,s,mA,dA,mB,dB,mC,dC) \ | |
| 182 | + PUSH_3(X, DATA_, 1, 0, o, (p), s, X##mC, (dC), \ | |
| 183 | + X##mB, (dB), \ | |
| 184 | + X##mA, (dA)) | |
| 185 | +#define PUSH_4D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD) \ | |
| 186 | + PUSH_4(X, DATA_, 1, 0, o, (p), s, X##mD, (dD), \ | |
| 187 | + X##mC, (dC), \ | |
| 188 | + X##mB, (dB), \ | |
| 189 | + X##mA, (dA)) | |
| 190 | +#define PUSH_5D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE) \ | |
| 191 | + PUSH_5(X, DATA_, 1, 0, o, (p), s, X##mE, (dE), \ | |
| 192 | + X##mD, (dD), \ | |
| 193 | + X##mC, (dC), \ | |
| 194 | + X##mB, (dB), \ | |
| 195 | + X##mA, (dA)) | |
| 196 | 196 | #define PUSH_6D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF) \ |
| 197 | − PUSH_6(X, DATA_, 1, 1, 0, o, (p), s, X##mF, (dF), \ | |
| 198 | − X##mE, (dE), \ | |
| 199 | − X##mD, (dD), \ | |
| 200 | − X##mC, (dC), \ | |
| 201 | − X##mB, (dB), \ | |
| 202 | − X##mA, (dA)) | |
| 197 | + PUSH_6(X, DATA_, 1, 0, o, (p), s, X##mF, (dF), \ | |
| 198 | + X##mE, (dE), \ | |
| 199 | + X##mD, (dD), \ | |
| 200 | + X##mC, (dC), \ | |
| 201 | + X##mB, (dB), \ | |
| 202 | + X##mA, (dA)) | |
| 203 | 203 | #define PUSH_7D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG) \ |
| 204 | − PUSH_7(X, DATA_, 1, 1, 0, o, (p), s, X##mG, (dG), \ | |
| 205 | − X##mF, (dF), \ | |
| 206 | − X##mE, (dE), \ | |
| 207 | − X##mD, (dD), \ | |
| 208 | − X##mC, (dC), \ | |
| 209 | − X##mB, (dB), \ | |
| 210 | − X##mA, (dA)) | |
| 204 | + PUSH_7(X, DATA_, 1, 0, o, (p), s, X##mG, (dG), \ | |
| 205 | + X##mF, (dF), \ | |
| 206 | + X##mE, (dE), \ | |
| 207 | + X##mD, (dD), \ | |
| 208 | + X##mC, (dC), \ | |
| 209 | + X##mB, (dB), \ | |
| 210 | + X##mA, (dA)) | |
| 211 | 211 | #define PUSH_8D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG,mH,dH) \ |
| 212 | − PUSH_8(X, DATA_, 1, 1, 0, o, (p), s, X##mH, (dH), \ | |
| 213 | − X##mG, (dG), \ | |
| 214 | − X##mF, (dF), \ | |
| 215 | − X##mE, (dE), \ | |
| 216 | − X##mD, (dD), \ | |
| 217 | − X##mC, (dC), \ | |
| 218 | − X##mB, (dB), \ | |
| 219 | − X##mA, (dA)) | |
| 212 | + PUSH_8(X, DATA_, 1, 0, o, (p), s, X##mH, (dH), \ | |
| 213 | + X##mG, (dG), \ | |
| 214 | + X##mF, (dF), \ | |
| 215 | + X##mE, (dE), \ | |
| 216 | + X##mD, (dD), \ | |
| 217 | + X##mC, (dC), \ | |
| 218 | + X##mB, (dB), \ | |
| 219 | + X##mA, (dA)) | |
| 220 | 220 | #define PUSH_9D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG,mH,dH,mI,dI) \ |
| 221 | − PUSH_9(X, DATA_, 1, 1, 0, o, (p), s, X##mI, (dI), \ | |
| 222 | − X##mH, (dH), \ | |
| 223 | − X##mG, (dG), \ | |
| 224 | − X##mF, (dF), \ | |
| 225 | − X##mE, (dE), \ | |
| 226 | − X##mD, (dD), \ | |
| 227 | − X##mC, (dC), \ | |
| 228 | − X##mB, (dB), \ | |
| 229 | − X##mA, (dA)) | |
| 221 | + PUSH_9(X, DATA_, 1, 0, o, (p), s, X##mI, (dI), \ | |
| 222 | + X##mH, (dH), \ | |
| 223 | + X##mG, (dG), \ | |
| 224 | + X##mF, (dF), \ | |
| 225 | + X##mE, (dE), \ | |
| 226 | + X##mD, (dD), \ | |
| 227 | + X##mC, (dC), \ | |
| 228 | + X##mB, (dB), \ | |
| 229 | + X##mA, (dA)) | |
| 230 | 230 | #define PUSH_10D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG,mH,dH,mI,dI,mJ,dJ) \ |
| 231 | − PUSH_10(X, DATA_, 1, 1, 0, o, (p), s, X##mJ, (dJ), \ | |
| 232 | − X##mI, (dI), \ | |
| 233 | − X##mH, (dH), \ | |
| 234 | − X##mG, (dG), \ | |
| 235 | − X##mF, (dF), \ | |
| 236 | − X##mE, (dE), \ | |
| 237 | − X##mD, (dD), \ | |
| 238 | − X##mC, (dC), \ | |
| 239 | − X##mB, (dB), \ | |
| 240 | − X##mA, (dA)) | |
| 231 | + PUSH_10(X, DATA_, 1, 0, o, (p), s, X##mJ, (dJ), \ | |
| 232 | + X##mI, (dI), \ | |
| 233 | + X##mH, (dH), \ | |
| 234 | + X##mG, (dG), \ | |
| 235 | + X##mF, (dF), \ | |
| 236 | + X##mE, (dE), \ | |
| 237 | + X##mD, (dD), \ | |
| 238 | + X##mC, (dC), \ | |
| 239 | + X##mB, (dB), \ | |
| 240 | + X##mA, (dA)) | |
| 241 | 241 | |
| 242 | −#define PUSH_1P(X,o,p,s,mA,dp,ds) \ | |
| 243 | − PUSH_1(X, DATAp, ds, ds, 0, o, (p), s, X##mA, (dp)) | |
| 244 | −#define PUSH_2P(X,o,p,s,mA,dA,mB,dp,ds) \ | |
| 245 | − PUSH_2(X, DATAp, ds, ds, 0, o, (p), s, X##mB, (dp), \ | |
| 246 | − X##mA, (dA)) | |
| 247 | −#define PUSH_3P(X,o,p,s,mA,dA,mB,dB,mC,dp,ds) \ | |
| 248 | − PUSH_3(X, DATAp, ds, ds, 0, o, (p), s, X##mC, (dp), \ | |
| 249 | − X##mB, (dB), \ | |
| 250 | − X##mA, (dA)) | |
| 242 | +#define PUSH_1P(X,o,p,s,mA,dp,ds) \ | |
| 243 | + PUSH_1(X, DATAp, ds, 0, o, (p), s, X##mA, (dp)) | |
| 244 | +#define PUSH_2P(X,o,p,s,mA,dA,mB,dp,ds) \ | |
| 245 | + PUSH_2(X, DATAp, ds, 0, o, (p), s, X##mB, (dp), \ | |
| 246 | + X##mA, (dA)) | |
| 247 | +#define PUSH_3P(X,o,p,s,mA,dA,mB,dB,mC,dp,ds) \ | |
| 248 | + PUSH_3(X, DATAp, ds, 0, o, (p), s, X##mC, (dp), \ | |
| 249 | + X##mB, (dB), \ | |
| 250 | + X##mA, (dA)) | |
| 251 | 251 | |
| 252 | 252 | #define PUSH_(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,IMPL,...) IMPL |
| 253 | 253 | #define PUSH(A...) PUSH_(A, PUSH_10P, PUSH_10D, \ |
| @@ -120,6 +120,7 @@ struct nvkm_device { · 119 unmodified lines | ||
| 120 | 120 | GP100 = 0x130, |
| 121 | 121 | GV100 = 0x140, |
| 122 | 122 | TU100 = 0x160, |
| 123 | + GA100 = 0x170, | |
| 123 | 124 | } card_type; |
| 124 | 125 | u32 chipset; |
| 125 | 126 | u8 chiprev; |
| @@ -37,4 +37,5 @@ int gp100_disp_new(struct nvkm_device *, int, struct nvkm_disp **); · 36 unmodified lines | ||
| 37 | 37 | int gp102_disp_new(struct nvkm_device *, int, struct nvkm_disp **); |
| 38 | 38 | int gv100_disp_new(struct nvkm_device *, int, struct nvkm_disp **); |
| 39 | 39 | int tu102_disp_new(struct nvkm_device *, int, struct nvkm_disp **); |
| 40 | +int ga102_disp_new(struct nvkm_device *, int, struct nvkm_disp **); | |
| 40 | 41 | #endif |
| @@ -32,4 +32,5 @@ int gm107_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); · 31 unmodified lines | ||
| 32 | 32 | int gm200_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); |
| 33 | 33 | int gv100_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); |
| 34 | 34 | int tu102_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); |
| 35 | +int ga100_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); | |
| 35 | 36 | #endif |
| @@ -86,6 +86,8 @@ int gp100_fb_new(struct nvkm_device *, int, struct nvkm_fb **); · 85 unmodified lines | ||
| 86 | 86 | int gp102_fb_new(struct nvkm_device *, int, struct nvkm_fb **); |
| 87 | 87 | int gp10b_fb_new(struct nvkm_device *, int, struct nvkm_fb **); |
| 88 | 88 | int gv100_fb_new(struct nvkm_device *, int, struct nvkm_fb **); |
| 89 | +int ga100_fb_new(struct nvkm_device *, int, struct nvkm_fb **); | |
| 90 | +int ga102_fb_new(struct nvkm_device *, int, struct nvkm_fb **); | |
| 89 | 91 | |
| 90 | 92 | #include <subdev/bios.h> |
| 91 | 93 | #include <subdev/bios/ramcfg.h> |
| @@ -37,4 +37,5 @@ int nv50_gpio_new(struct nvkm_device *, int, struct nvkm_gpio **); · 36 unmodified lines | ||
| 37 | 37 | int g94_gpio_new(struct nvkm_device *, int, struct nvkm_gpio **); |
| 38 | 38 | int gf119_gpio_new(struct nvkm_device *, int, struct nvkm_gpio **); |
| 39 | 39 | int gk104_gpio_new(struct nvkm_device *, int, struct nvkm_gpio **); |
| 40 | +int ga102_gpio_new(struct nvkm_device *, int, struct nvkm_gpio **); | |
| 40 | 41 | #endif |
| @@ -92,6 +92,7 @@ int g94_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); · 91 unmodified lines | ||
| 92 | 92 | int gf117_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); |
| 93 | 93 | int gf119_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); |
| 94 | 94 | int gk104_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); |
| 95 | +int gk110_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); | |
| 95 | 96 | int gm200_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); |
| 96 | 97 | |
| 97 | 98 | static inline int |
| @@ -32,4 +32,5 @@ int gk20a_mc_new(struct nvkm_device *, int, struct nvkm_mc **); · 31 unmodified lines | ||
| 32 | 32 | int gp100_mc_new(struct nvkm_device *, int, struct nvkm_mc **); |
| 33 | 33 | int gp10b_mc_new(struct nvkm_device *, int, struct nvkm_mc **); |
| 34 | 34 | int tu102_mc_new(struct nvkm_device *, int, struct nvkm_mc **); |
| 35 | +int ga100_mc_new(struct nvkm_device *, int, struct nvkm_mc **); | |
| 35 | 36 | #endif |
| @@ -256,6 +256,7 @@ nouveau_backlight_init(struct drm_connector *connector) · 255 unmodified lines | ||
| 256 | 256 | case NV_DEVICE_INFO_V0_PASCAL: |
| 257 | 257 | case NV_DEVICE_INFO_V0_VOLTA: |
| 258 | 258 | case NV_DEVICE_INFO_V0_TURING: |
| 259 | + case NV_DEVICE_INFO_V0_AMPERE: //XXX: not confirmed | |
| 259 | 260 | ret = nv50_backlight_init(nv_encoder, &props, &ops); |
| 260 | 261 | break; |
| 261 | 262 | default: |
| @@ -547,7 +547,7 @@ nouveau_bo_sync_for_device(struct nouveau_bo *nvbo) · 546 unmodified lines | ||
| 547 | 547 | { |
| 548 | 548 | struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); |
| 549 | 549 | struct ttm_tt *ttm_dma = (struct ttm_tt *)nvbo->bo.ttm; |
| 550 | − int i; | |
| 550 | + int i, j; | |
| 551 | 551 | |
| 552 | 552 | if (!ttm_dma) |
| 553 | 553 | return; |
| @@ -556,10 +556,21 @@ nouveau_bo_sync_for_device(struct nouveau_bo *nvbo) · 2 unmodified lines | ||
| 556 | 556 | if (nvbo->force_coherent) |
| 557 | 557 | return; |
| 558 | 558 | |
| 559 | − for (i = 0; i < ttm_dma->num_pages; i++) | |
| 559 | + for (i = 0; i < ttm_dma->num_pages; ++i) { | |
| 560 | + struct page *p = ttm_dma->pages[i]; | |
| 561 | + size_t num_pages = 1; | |
| 562 | + | |
| 563 | + for (j = i + 1; j < ttm_dma->num_pages; ++j) { | |
| 564 | + if (++p != ttm_dma->pages[j]) | |
| 565 | + break; | |
| 566 | + | |
| 567 | + ++num_pages; | |
| 568 | + } | |
| 560 | 569 | dma_sync_single_for_device(drm->dev->dev, |
| 561 | 570 | ttm_dma->dma_address[i], |
| 562 | − PAGE_SIZE, DMA_TO_DEVICE); | |
| 571 | + num_pages * PAGE_SIZE, DMA_TO_DEVICE); | |
| 572 | + i += num_pages; | |
| 573 | + } | |
| 563 | 574 | } |
| 564 | 575 | |
| 565 | 576 | void |
| @@ -567,7 +578,7 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo) · 1 unmodified line | ||
| 567 | 578 | { |
| 568 | 579 | struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); |
| 569 | 580 | struct ttm_tt *ttm_dma = (struct ttm_tt *)nvbo->bo.ttm; |
| 570 | − int i; | |
| 581 | + int i, j; | |
| 571 | 582 | |
| 572 | 583 | if (!ttm_dma) |
| 573 | 584 | return; |
| @@ -576,9 +587,21 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo) · 2 unmodified lines | ||
| 576 | 587 | if (nvbo->force_coherent) |
| 577 | 588 | return; |
| 578 | 589 | |
| 579 | − for (i = 0; i < ttm_dma->num_pages; i++) | |
| 590 | + for (i = 0; i < ttm_dma->num_pages; ++i) { | |
| 591 | + struct page *p = ttm_dma->pages[i]; | |
| 592 | + size_t num_pages = 1; | |
| 593 | + | |
| 594 | + for (j = i + 1; j < ttm_dma->num_pages; ++j) { | |
| 595 | + if (++p != ttm_dma->pages[j]) | |
| 596 | + break; | |
| 597 | + | |
| 598 | + ++num_pages; | |
| 599 | + } | |
| 600 | + | |
| 580 | 601 | dma_sync_single_for_cpu(drm->dev->dev, ttm_dma->dma_address[i], |
| 581 | − PAGE_SIZE, DMA_FROM_DEVICE); | |
| 602 | + num_pages * PAGE_SIZE, DMA_FROM_DEVICE); | |
| 603 | + i += num_pages; | |
| 604 | + } | |
| 582 | 605 | } |
| 583 | 606 | |
| 584 | 607 | void nouveau_bo_add_io_reserve_lru(struct ttm_buffer_object *bo) |
| @@ -315,6 +315,10 @@ nouveau_svmm_init(struct drm_device *dev, void *data, · 314 unmodified lines | ||
| 315 | 315 | struct drm_nouveau_svm_init *args = data; |
| 316 | 316 | int ret; |
| 317 | 317 | |
| 318 | + /* We need to fail if svm is disabled */ | |
| 319 | + if (!cli->drm->svm) | |
| 320 | + return -ENOSYS; | |
| 321 | + | |
| 318 | 322 | /* Allocate tracking for SVM-enabled VMM. */ |
| 319 | 323 | if (!(svmm = kzalloc(sizeof(*svmm), GFP_KERNEL))) |
| 320 | 324 | return -ENOMEM; |
| @@ -35,6 +35,7 @@ nvif_disp_ctor(struct nvif_device *device, const char *name, s32 oclass, · 34 unmodified lines | ||
| 35 | 35 | struct nvif_disp *disp) |
| 36 | 36 | { |
| 37 | 37 | static const struct nvif_mclass disps[] = { |
| 38 | + { GA102_DISP, -1 }, | |
| 38 | 39 | { TU102_DISP, -1 }, |
| 39 | 40 | { GV100_DISP, -1 }, |
| 40 | 41 | { GP102_DISP, -1 }, |
| @@ -1815,7 +1815,7 @@ nvf0_chipset = { · 1814 unmodified lines | ||
| 1815 | 1815 | .fb = gk110_fb_new, |
| 1816 | 1816 | .fuse = gf100_fuse_new, |
| 1817 | 1817 | .gpio = gk104_gpio_new, |
| 1818 | − .i2c = gk104_i2c_new, | |
| 1818 | + .i2c = gk110_i2c_new, | |
| 1819 | 1819 | .ibus = gk104_ibus_new, |
| 1820 | 1820 | .iccsense = gf100_iccsense_new, |
| 1821 | 1821 | .imem = nv50_instmem_new, |
| @@ -1853,7 +1853,7 @@ nvf1_chipset = { · 31 unmodified lines | ||
| 1853 | 1853 | .fb = gk110_fb_new, |
| 1854 | 1854 | .fuse = gf100_fuse_new, |
| 1855 | 1855 | .gpio = gk104_gpio_new, |
| 1856 | − .i2c = gk104_i2c_new, | |
| 1856 | + .i2c = gk110_i2c_new, | |
| 1857 | 1857 | .ibus = gk104_ibus_new, |
| 1858 | 1858 | .iccsense = gf100_iccsense_new, |
| 1859 | 1859 | .imem = nv50_instmem_new, |
| @@ -1891,7 +1891,7 @@ nv106_chipset = { · 31 unmodified lines | ||
| 1891 | 1891 | .fb = gk110_fb_new, |
| 1892 | 1892 | .fuse = gf100_fuse_new, |
| 1893 | 1893 | .gpio = gk104_gpio_new, |
| 1894 | − .i2c = gk104_i2c_new, | |
| 1894 | + .i2c = gk110_i2c_new, | |
| 1895 | 1895 | .ibus = gk104_ibus_new, |
| 1896 | 1896 | .iccsense = gf100_iccsense_new, |
| 1897 | 1897 | .imem = nv50_instmem_new, |
| @@ -1929,7 +1929,7 @@ nv108_chipset = { · 31 unmodified lines | ||
| 1929 | 1929 | .fb = gk110_fb_new, |
| 1930 | 1930 | .fuse = gf100_fuse_new, |
| 1931 | 1931 | .gpio = gk104_gpio_new, |
| 1932 | − .i2c = gk104_i2c_new, | |
| 1932 | + .i2c = gk110_i2c_new, | |
| 1933 | 1933 | .ibus = gk104_ibus_new, |
| 1934 | 1934 | .iccsense = gf100_iccsense_new, |
| 1935 | 1935 | .imem = nv50_instmem_new, |
| @@ -1967,7 +1967,7 @@ nv117_chipset = { · 31 unmodified lines | ||
| 1967 | 1967 | .fb = gm107_fb_new, |
| 1968 | 1968 | .fuse = gm107_fuse_new, |
| 1969 | 1969 | .gpio = gk104_gpio_new, |
| 1970 | − .i2c = gk104_i2c_new, | |
| 1970 | + .i2c = gk110_i2c_new, | |
| 1971 | 1971 | .ibus = gk104_ibus_new, |
| 1972 | 1972 | .iccsense = gf100_iccsense_new, |
| 1973 | 1973 | .imem = nv50_instmem_new, |
| @@ -2003,7 +2003,7 @@ nv118_chipset = { · 29 unmodified lines | ||
| 2003 | 2003 | .fb = gm107_fb_new, |
| 2004 | 2004 | .fuse = gm107_fuse_new, |
| 2005 | 2005 | .gpio = gk104_gpio_new, |
| 2006 | − .i2c = gk104_i2c_new, | |
| 2006 | + .i2c = gk110_i2c_new, | |
| 2007 | 2007 | .ibus = gk104_ibus_new, |
| 2008 | 2008 | .iccsense = gf100_iccsense_new, |
| 2009 | 2009 | .imem = nv50_instmem_new, |
| @@ -2652,6 +2652,61 @@ nv168_chipset = { · 642 unmodified lines | ||
| 2652 | 2652 | .sec2 = tu102_sec2_new, |
| 2653 | 2653 | }; |
| 2654 | 2654 | |
| 2655 | +static const struct nvkm_device_chip | |
| 2656 | +nv170_chipset = { | |
| 2657 | + .name = "GA100", | |
| 2658 | + .bar = tu102_bar_new, | |
| 2659 | + .bios = nvkm_bios_new, | |
| 2660 | + .devinit = ga100_devinit_new, | |
| 2661 | + .fb = ga100_fb_new, | |
| 2662 | + .gpio = gk104_gpio_new, | |
| 2663 | + .i2c = gm200_i2c_new, | |
| 2664 | + .ibus = gm200_ibus_new, | |
| 2665 | + .imem = nv50_instmem_new, | |
| 2666 | + .mc = ga100_mc_new, | |
| 2667 | + .mmu = tu102_mmu_new, | |
| 2668 | + .pci = gp100_pci_new, | |
| 2669 | + .timer = gk20a_timer_new, | |
| 2670 | +}; | |
| 2671 | + | |
| 2672 | +static const struct nvkm_device_chip | |
| 2673 | +nv172_chipset = { | |
| 2674 | + .name = "GA102", | |
| 2675 | + .bar = tu102_bar_new, | |
| 2676 | + .bios = nvkm_bios_new, | |
| 2677 | + .devinit = ga100_devinit_new, | |
| 2678 | + .fb = ga102_fb_new, | |
| 2679 | + .gpio = ga102_gpio_new, | |
| 2680 | + .i2c = gm200_i2c_new, | |
| 2681 | + .ibus = gm200_ibus_new, | |
| 2682 | + .imem = nv50_instmem_new, | |
| 2683 | + .mc = ga100_mc_new, | |
| 2684 | + .mmu = tu102_mmu_new, | |
| 2685 | + .pci = gp100_pci_new, | |
| 2686 | + .timer = gk20a_timer_new, | |
| 2687 | + .disp = ga102_disp_new, | |
| 2688 | + .dma = gv100_dma_new, | |
| 2689 | +}; | |
| 2690 | + | |
| 2691 | +static const struct nvkm_device_chip | |
| 2692 | +nv174_chipset = { | |
| 2693 | + .name = "GA104", | |
| 2694 | + .bar = tu102_bar_new, | |
| 2695 | + .bios = nvkm_bios_new, | |
| 2696 | + .devinit = ga100_devinit_new, | |
| 2697 | + .fb = ga102_fb_new, | |
| 2698 | + .gpio = ga102_gpio_new, | |
| 2699 | + .i2c = gm200_i2c_new, | |
| 2700 | + .ibus = gm200_ibus_new, | |
| 2701 | + .imem = nv50_instmem_new, | |
| 2702 | + .mc = ga100_mc_new, | |
| 2703 | + .mmu = tu102_mmu_new, | |
| 2704 | + .pci = gp100_pci_new, | |
| 2705 | + .timer = gk20a_timer_new, | |
| 2706 | + .disp = ga102_disp_new, | |
| 2707 | + .dma = gv100_dma_new, | |
| 2708 | +}; | |
| 2709 | + | |
| 2655 | 2710 | static int |
| 2656 | 2711 | nvkm_device_event_ctor(struct nvkm_object *object, void *data, u32 size, |
| 2657 | 2712 | struct nvkm_notify *notify) |
| @@ -3063,6 +3118,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, · 405 unmodified lines | ||
| 3063 | 3118 | case 0x130: device->card_type = GP100; break; |
| 3064 | 3119 | case 0x140: device->card_type = GV100; break; |
| 3065 | 3120 | case 0x160: device->card_type = TU100; break; |
| 3121 | + case 0x170: device->card_type = GA100; break; | |
| 3066 | 3122 | default: |
| 3067 | 3123 | break; |
| 3068 | 3124 | } |
| @@ -3160,10 +3216,23 @@ nvkm_device_ctor(const struct nvkm_device_func *func, · 91 unmodified lines | ||
| 3160 | 3216 | case 0x166: device->chip = &nv166_chipset; break; |
| 3161 | 3217 | case 0x167: device->chip = &nv167_chipset; break; |
| 3162 | 3218 | case 0x168: device->chip = &nv168_chipset; break; |
| 3219 | + case 0x172: device->chip = &nv172_chipset; break; | |
| 3220 | + case 0x174: device->chip = &nv174_chipset; break; | |
| 3163 | 3221 | default: |
| 3164 | − nvdev_error(device, "unknown chipset (%08x)\n", boot0); | |
| 3165 | − ret = -ENODEV; | |
| 3166 | − goto done; | |
| 3222 | + if (nvkm_boolopt(device->cfgopt, "NvEnableUnsupportedChipsets", false)) { | |
| 3223 | + switch (device->chipset) { | |
| 3224 | + case 0x170: device->chip = &nv170_chipset; break; | |
| 3225 | + default: | |
| 3226 | + break; | |
| 3227 | + } | |
| 3228 | + } | |
| 3229 | + | |
| 3230 | + if (!device->chip) { | |
| 3231 | + nvdev_error(device, "unknown chipset (%08x)\n", boot0); | |
| 3232 | + ret = -ENODEV; | |
| 3233 | + goto done; | |
| 3234 | + } | |
| 3235 | + break; | |
| 3167 | 3236 | } |
| 3168 | 3237 | |
| 3169 | 3238 | nvdev_info(device, "NVIDIA %s (%08x)\n", |
| @@ -176,6 +176,7 @@ nvkm_udevice_info(struct nvkm_udevice *udev, void *data, u32 size) · 175 unmodified lines | ||
| 176 | 176 | case GP100: args->v0.family = NV_DEVICE_INFO_V0_PASCAL; break; |
| 177 | 177 | case GV100: args->v0.family = NV_DEVICE_INFO_V0_VOLTA; break; |
| 178 | 178 | case TU100: args->v0.family = NV_DEVICE_INFO_V0_TURING; break; |
| 179 | + case GA100: args->v0.family = NV_DEVICE_INFO_V0_AMPERE; break; | |
| 179 | 180 | default: |
| 180 | 181 | args->v0.family = 0; |
| 181 | 182 | break; |
| @@ -17,6 +17,7 @@ nvkm-y += nvkm/engine/disp/gp100.o · 16 unmodified lines | ||
| 17 | 17 | nvkm-y += nvkm/engine/disp/gp102.o |
| 18 | 18 | nvkm-y += nvkm/engine/disp/gv100.o |
| 19 | 19 | nvkm-y += nvkm/engine/disp/tu102.o |
| 20 | +nvkm-y += nvkm/engine/disp/ga102.o | |
| 20 | 21 | nvkm-y += nvkm/engine/disp/vga.o |
| 21 | 22 | |
| 22 | 23 | nvkm-y += nvkm/engine/disp/head.o |
| @@ -42,6 +43,7 @@ nvkm-y += nvkm/engine/disp/sorgm200.o · 19 unmodified lines | ||
| 42 | 43 | nvkm-y += nvkm/engine/disp/sorgp100.o |
| 43 | 44 | nvkm-y += nvkm/engine/disp/sorgv100.o |
| 44 | 45 | nvkm-y += nvkm/engine/disp/sortu102.o |
| 46 | +nvkm-y += nvkm/engine/disp/sorga102.o | |
| 45 | 47 | |
| 46 | 48 | nvkm-y += nvkm/engine/disp/outp.o |
| 47 | 49 | nvkm-y += nvkm/engine/disp/dp.o |
| @@ -75,6 +77,7 @@ nvkm-y += nvkm/engine/disp/rootgp100.o · 27 unmodified lines | ||
| 75 | 77 | nvkm-y += nvkm/engine/disp/rootgp102.o |
| 76 | 78 | nvkm-y += nvkm/engine/disp/rootgv100.o |
| 77 | 79 | nvkm-y += nvkm/engine/disp/roottu102.o |
| 80 | +nvkm-y += nvkm/engine/disp/rootga102.o | |
| 78 | 81 | |
| 79 | 82 | nvkm-y += nvkm/engine/disp/capsgv100.o |
| 80 | 83 | |
| @@ -33,6 +33,12 @@ · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | #include <nvif/event.h> |
| 35 | 35 | |
| 36 | +/* IED scripts are no longer used by UEFI/RM from Ampere, but have been updated for | |
| 37 | + * the x86 option ROM. However, the relevant VBIOS table versions weren't modified, | |
| 38 | + * so we're unable to detect this in a nice way. | |
| 39 | + */ | |
| 40 | +#define AMPERE_IED_HACK(disp) ((disp)->engine.subdev.device->card_type >= GA100) | |
| 41 | + | |
| 36 | 42 | struct lt_state { |
| 37 | 43 | struct nvkm_dp *dp; |
| 38 | 44 | u8 stat[6]; |
| @@ -238,6 +244,19 @@ nvkm_dp_train_links(struct nvkm_dp *dp) · 199 unmodified lines | ||
| 238 | 244 | dp->dpcd[DPCD_RC02] &= ~DPCD_RC02_TPS3_SUPPORTED; |
| 239 | 245 | lt.pc2 = dp->dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED; |
| 240 | 246 | |
| 247 | + if (AMPERE_IED_HACK(disp) && (lnkcmp = lt.dp->info.script[0])) { | |
| 248 | + /* Execute BeforeLinkTraining script from DP Info table. */ | |
| 249 | + while (ior->dp.bw < nvbios_rd08(bios, lnkcmp)) | |
| 250 | + lnkcmp += 3; | |
| 251 | + lnkcmp = nvbios_rd16(bios, lnkcmp + 1); | |
| 252 | + | |
| 253 | + nvbios_init(&dp->outp.disp->engine.subdev, lnkcmp, | |
| 254 | + init.outp = &dp->outp.info; | |
| 255 | + init.or = ior->id; | |
| 256 | + init.link = ior->asy.link; | |
| 257 | + ); | |
| 258 | + } | |
| 259 | + | |
| 241 | 260 | /* Set desired link configuration on the source. */ |
| 242 | 261 | if ((lnkcmp = lt.dp->info.lnkcmp)) { |
| 243 | 262 | if (dp->version < 0x30) { |
| @@ -316,12 +335,14 @@ nvkm_dp_train_init(struct nvkm_dp *dp) · 72 unmodified lines | ||
| 316 | 335 | ); |
| 317 | 336 | } |
| 318 | 337 | |
| 319 | − /* Execute BeforeLinkTraining script from DP Info table. */ | |
| 320 | − nvbios_init(&dp->outp.disp->engine.subdev, dp->info.script[0], | |
| 321 | − init.outp = &dp->outp.info; | |
| 322 | − init.or = dp->outp.ior->id; | |
| 323 | − init.link = dp->outp.ior->asy.link; | |
| 324 | − ); | |
| 338 | + if (!AMPERE_IED_HACK(dp->outp.disp)) { | |
| 339 | + /* Execute BeforeLinkTraining script from DP Info table. */ | |
| 340 | + nvbios_init(&dp->outp.disp->engine.subdev, dp->info.script[0], | |
| 341 | + init.outp = &dp->outp.info; | |
| 342 | + init.or = dp->outp.ior->id; | |
| 343 | + init.link = dp->outp.ior->asy.link; | |
| 344 | + ); | |
| 345 | + } | |
| 325 | 346 | } |
| 326 | 347 | |
| 327 | 348 | static const struct dp_rates { |
| @@ -0,0 +1,46 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 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 shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "nv50.h" | |
| 23 | +#include "head.h" | |
| 24 | +#include "ior.h" | |
| 25 | +#include "channv50.h" | |
| 26 | +#include "rootnv50.h" | |
| 27 | + | |
| 28 | +static const struct nv50_disp_func | |
| 29 | +ga102_disp = { | |
| 30 | + .init = tu102_disp_init, | |
| 31 | + .fini = gv100_disp_fini, | |
| 32 | + .intr = gv100_disp_intr, | |
| 33 | + .uevent = &gv100_disp_chan_uevent, | |
| 34 | + .super = gv100_disp_super, | |
| 35 | + .root = &ga102_disp_root_oclass, | |
| 36 | + .wndw = { .cnt = gv100_disp_wndw_cnt }, | |
| 37 | + .head = { .cnt = gv100_head_cnt, .new = gv100_head_new }, | |
| 38 | + .sor = { .cnt = gv100_sor_cnt, .new = ga102_sor_new }, | |
| 39 | + .ramht_size = 0x2000, | |
| 40 | +}; | |
| 41 | + | |
| 42 | +int | |
| 43 | +ga102_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) | |
| 44 | +{ | |
| 45 | + return nv50_disp_new_(&ga102_disp, device, index, pdisp); | |
| 46 | +} | |
| @@ -150,6 +150,8 @@ void gv100_sor_dp_audio(struct nvkm_ior *, int, bool); · 149 unmodified lines | ||
| 150 | 150 | void gv100_sor_dp_audio_sym(struct nvkm_ior *, int, u16, u32); |
| 151 | 151 | void gv100_sor_dp_watermark(struct nvkm_ior *, int, u8); |
| 152 | 152 | |
| 153 | +void tu102_sor_dp_vcpi(struct nvkm_ior *, int, u8, u8, u16, u16); | |
| 154 | + | |
| 153 | 155 | void g84_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); |
| 154 | 156 | void gt215_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); |
| 155 | 157 | void gf119_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); |
| @@ -207,4 +209,6 @@ int gv100_sor_cnt(struct nvkm_disp *, unsigned long *); · 51 unmodified lines | ||
| 207 | 209 | int gv100_sor_new(struct nvkm_disp *, int); |
| 208 | 210 | |
| 209 | 211 | int tu102_sor_new(struct nvkm_disp *, int); |
| 212 | + | |
| 213 | +int ga102_sor_new(struct nvkm_disp *, int); | |
| 210 | 214 | #endif |
| @@ -86,6 +86,8 @@ void gv100_disp_intr(struct nv50_disp *); · 85 unmodified lines | ||
| 86 | 86 | void gv100_disp_super(struct work_struct *); |
| 87 | 87 | int gv100_disp_wndw_cnt(struct nvkm_disp *, unsigned long *); |
| 88 | 88 | |
| 89 | +int tu102_disp_init(struct nv50_disp *); | |
| 90 | + | |
| 89 | 91 | void nv50_disp_dptmds_war_2(struct nv50_disp *, struct dcb_output *); |
| 90 | 92 | void nv50_disp_dptmds_war_3(struct nv50_disp *, struct dcb_output *); |
| 91 | 93 | void nv50_disp_update_sppll1(struct nv50_disp *); |
| @@ -0,0 +1,52 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 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 shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "rootnv50.h" | |
| 23 | +#include "channv50.h" | |
| 24 | + | |
| 25 | +#include <nvif/class.h> | |
| 26 | + | |
| 27 | +static const struct nv50_disp_root_func | |
| 28 | +ga102_disp_root = { | |
| 29 | + .user = { | |
| 30 | + {{-1,-1,GV100_DISP_CAPS }, gv100_disp_caps_new }, | |
| 31 | + {{0,0,GA102_DISP_CURSOR }, gv100_disp_curs_new }, | |
| 32 | + {{0,0,GA102_DISP_WINDOW_IMM_CHANNEL_DMA}, gv100_disp_wimm_new }, | |
| 33 | + {{0,0,GA102_DISP_CORE_CHANNEL_DMA }, gv100_disp_core_new }, | |
| 34 | + {{0,0,GA102_DISP_WINDOW_CHANNEL_DMA }, gv100_disp_wndw_new }, | |
| 35 | + {} | |
| 36 | + }, | |
| 37 | +}; | |
| 38 | + | |
| 39 | +static int | |
| 40 | +ga102_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass, | |
| 41 | + void *data, u32 size, struct nvkm_object **pobject) | |
| 42 | +{ | |
| 43 | + return nv50_disp_root_new_(&ga102_disp_root, disp, oclass, data, size, pobject); | |
| 44 | +} | |
| 45 | + | |
| 46 | +const struct nvkm_disp_oclass | |
| 47 | +ga102_disp_root_oclass = { | |
| 48 | + .base.oclass = GA102_DISP, | |
| 49 | + .base.minver = -1, | |
| 50 | + .base.maxver = -1, | |
| 51 | + .ctor = ga102_disp_root_new, | |
| 52 | +}; | |
| @@ -41,4 +41,5 @@ extern const struct nvkm_disp_oclass gp100_disp_root_oclass; · 40 unmodified lines | ||
| 41 | 41 | extern const struct nvkm_disp_oclass gp102_disp_root_oclass; |
| 42 | 42 | extern const struct nvkm_disp_oclass gv100_disp_root_oclass; |
| 43 | 43 | extern const struct nvkm_disp_oclass tu102_disp_root_oclass; |
| 44 | +extern const struct nvkm_disp_oclass ga102_disp_root_oclass; | |
| 44 | 45 | #endif |
| @@ -0,0 +1,140 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 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 shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "ior.h" | |
| 23 | + | |
| 24 | +#include <subdev/timer.h> | |
| 25 | + | |
| 26 | +static int | |
| 27 | +ga102_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux) | |
| 28 | +{ | |
| 29 | + struct nvkm_device *device = sor->disp->engine.subdev.device; | |
| 30 | + const u32 soff = nv50_ior_base(sor); | |
| 31 | + const u32 loff = nv50_sor_link(sor); | |
| 32 | + u32 dpctrl = 0x00000000; | |
| 33 | + u32 clksor = 0x00000000; | |
| 34 | + | |
| 35 | + switch (sor->dp.bw) { | |
| 36 | + case 0x06: clksor |= 0x00000000; break; | |
| 37 | + case 0x0a: clksor |= 0x00040000; break; | |
| 38 | + case 0x14: clksor |= 0x00080000; break; | |
| 39 | + case 0x1e: clksor |= 0x000c0000; break; | |
| 40 | + default: | |
| 41 | + WARN_ON(1); | |
| 42 | + return -EINVAL; | |
| 43 | + } | |
| 44 | + | |
| 45 | + dpctrl |= ((1 << sor->dp.nr) - 1) << 16; | |
| 46 | + if (sor->dp.mst) | |
| 47 | + dpctrl |= 0x40000000; | |
| 48 | + if (sor->dp.ef) | |
| 49 | + dpctrl |= 0x00004000; | |
| 50 | + | |
| 51 | + nvkm_mask(device, 0x612300 + soff, 0x007c0000, clksor); | |
| 52 | + | |
| 53 | + /*XXX*/ | |
| 54 | + nvkm_msec(device, 40, NVKM_DELAY); | |
| 55 | + nvkm_mask(device, 0x612300 + soff, 0x00030000, 0x00010000); | |
| 56 | + nvkm_mask(device, 0x61c10c + loff, 0x00000003, 0x00000001); | |
| 57 | + | |
| 58 | + nvkm_mask(device, 0x61c10c + loff, 0x401f4000, dpctrl); | |
| 59 | + return 0; | |
| 60 | +} | |
| 61 | + | |
| 62 | +static void | |
| 63 | +ga102_sor_clock(struct nvkm_ior *sor) | |
| 64 | +{ | |
| 65 | + struct nvkm_device *device = sor->disp->engine.subdev.device; | |
| 66 | + u32 div2 = 0; | |
| 67 | + if (sor->asy.proto == TMDS) { | |
| 68 | + if (sor->tmds.high_speed) | |
| 69 | + div2 = 1; | |
| 70 | + } | |
| 71 | + nvkm_wr32(device, 0x00ec08 + (sor->id * 0x10), 0x00000000); | |
| 72 | + nvkm_wr32(device, 0x00ec04 + (sor->id * 0x10), div2); | |
| 73 | +} | |
| 74 | + | |
| 75 | +static const struct nvkm_ior_func | |
| 76 | +ga102_sor_hda = { | |
| 77 | + .route = { | |
| 78 | + .get = gm200_sor_route_get, | |
| 79 | + .set = gm200_sor_route_set, | |
| 80 | + }, | |
| 81 | + .state = gv100_sor_state, | |
| 82 | + .power = nv50_sor_power, | |
| 83 | + .clock = ga102_sor_clock, | |
| 84 | + .hdmi = { | |
| 85 | + .ctrl = gv100_hdmi_ctrl, | |
| 86 | + .scdc = gm200_hdmi_scdc, | |
| 87 | + }, | |
| 88 | + .dp = { | |
| 89 | + .lanes = { 0, 1, 2, 3 }, | |
| 90 | + .links = ga102_sor_dp_links, | |
| 91 | + .power = g94_sor_dp_power, | |
| 92 | + .pattern = gm107_sor_dp_pattern, | |
| 93 | + .drive = gm200_sor_dp_drive, | |
| 94 | + .vcpi = tu102_sor_dp_vcpi, | |
| 95 | + .audio = gv100_sor_dp_audio, | |
| 96 | + .audio_sym = gv100_sor_dp_audio_sym, | |
| 97 | + .watermark = gv100_sor_dp_watermark, | |
| 98 | + }, | |
| 99 | + .hda = { | |
| 100 | + .hpd = gf119_hda_hpd, | |
| 101 | + .eld = gf119_hda_eld, | |
| 102 | + .device_entry = gv100_hda_device_entry, | |
| 103 | + }, | |
| 104 | +}; | |
| 105 | + | |
| 106 | +static const struct nvkm_ior_func | |
| 107 | +ga102_sor = { | |
| 108 | + .route = { | |
| 109 | + .get = gm200_sor_route_get, | |
| 110 | + .set = gm200_sor_route_set, | |
| 111 | + }, | |
| 112 | + .state = gv100_sor_state, | |
| 113 | + .power = nv50_sor_power, | |
| 114 | + .clock = ga102_sor_clock, | |
| 115 | + .hdmi = { | |
| 116 | + .ctrl = gv100_hdmi_ctrl, | |
| 117 | + .scdc = gm200_hdmi_scdc, | |
| 118 | + }, | |
| 119 | + .dp = { | |
| 120 | + .lanes = { 0, 1, 2, 3 }, | |
| 121 | + .links = ga102_sor_dp_links, | |
| 122 | + .power = g94_sor_dp_power, | |
| 123 | + .pattern = gm107_sor_dp_pattern, | |
| 124 | + .drive = gm200_sor_dp_drive, | |
| 125 | + .vcpi = tu102_sor_dp_vcpi, | |
| 126 | + .audio = gv100_sor_dp_audio, | |
| 127 | + .audio_sym = gv100_sor_dp_audio_sym, | |
| 128 | + .watermark = gv100_sor_dp_watermark, | |
| 129 | + }, | |
| 130 | +}; | |
| 131 | + | |
| 132 | +int | |
| 133 | +ga102_sor_new(struct nvkm_disp *disp, int id) | |
| 134 | +{ | |
| 135 | + struct nvkm_device *device = disp->engine.subdev.device; | |
| 136 | + u32 hda = nvkm_rd32(device, 0x08a15c); | |
| 137 | + if (hda & BIT(id)) | |
| 138 | + return nvkm_ior_new_(&ga102_sor_hda, disp, SOR, id); | |
| 139 | + return nvkm_ior_new_(&ga102_sor, disp, SOR, id); | |
| 140 | +} | |
| @@ -23,7 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | #include <subdev/timer.h> |
| 25 | 25 | |
| 26 | −static void | |
| 26 | +void | |
| 27 | 27 | tu102_sor_dp_vcpi(struct nvkm_ior *sor, int head, |
| 28 | 28 | u8 slot, u8 slot_nr, u16 pbn, u16 aligned) |
| 29 | 29 | { |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <core/gpuobj.h> |
| 29 | 29 | #include <subdev/timer.h> |
| 30 | 30 | |
| 31 | −static int | |
| 31 | +int | |
| 32 | 32 | tu102_disp_init(struct nv50_disp *disp) |
| 33 | 33 | { |
| 34 | 34 | struct nvkm_device *device = disp->base.engine.subdev.device; |
| @@ -75,7 +75,7 @@ shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd) · 74 unmodified lines | ||
| 75 | 75 | nvkm_debug(subdev, "%08x: type %02x, %d bytes\n", |
| 76 | 76 | image.base, image.type, image.size); |
| 77 | 77 | |
| 78 | − if (!shadow_fetch(bios, mthd, image.size)) { | |
| 78 | + if (!shadow_fetch(bios, mthd, image.base + image.size)) { | |
| 79 | 79 | nvkm_debug(subdev, "%08x: fetch failed\n", image.base); |
| 80 | 80 | return 0; |
| 81 | 81 | } |
| @@ -64,6 +64,9 @@ pramin_init(struct nvkm_bios *bios, const char *name) · 63 unmodified lines | ||
| 64 | 64 | return NULL; |
| 65 | 65 | |
| 66 | 66 | /* we can't get the bios image pointer without PDISP */ |
| 67 | + if (device->card_type >= GA100) | |
| 68 | + addr = device->chipset == 0x170; /*XXX: find the fuse reg for this */ | |
| 69 | + else | |
| 67 | 70 | if (device->card_type >= GM100) |
| 68 | 71 | addr = nvkm_rd32(device, 0x021c04); |
| 69 | 72 | else |
| @@ -15,3 +15,4 @@ nvkm-y += nvkm/subdev/devinit/gm107.o · 14 unmodified lines | ||
| 15 | 15 | nvkm-y += nvkm/subdev/devinit/gm200.o |
| 16 | 16 | nvkm-y += nvkm/subdev/devinit/gv100.o |
| 17 | 17 | nvkm-y += nvkm/subdev/devinit/tu102.o |
| 18 | +nvkm-y += nvkm/subdev/devinit/ga100.o | |
| @@ -0,0 +1,76 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 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 shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "nv50.h" | |
| 23 | + | |
| 24 | +#include <subdev/bios.h> | |
| 25 | +#include <subdev/bios/pll.h> | |
| 26 | +#include <subdev/clk/pll.h> | |
| 27 | + | |
| 28 | +static int | |
| 29 | +ga100_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq) | |
| 30 | +{ | |
| 31 | + struct nvkm_subdev *subdev = &init->subdev; | |
| 32 | + struct nvkm_device *device = subdev->device; | |
| 33 | + struct nvbios_pll info; | |
| 34 | + int head = type - PLL_VPLL0; | |
| 35 | + int N, fN, M, P; | |
| 36 | + int ret; | |
| 37 | + | |
| 38 | + ret = nvbios_pll_parse(device->bios, type, &info); | |
| 39 | + if (ret) | |
| 40 | + return ret; | |
| 41 | + | |
| 42 | + ret = gt215_pll_calc(subdev, &info, freq, &N, &fN, &M, &P); | |
| 43 | + if (ret < 0) | |
| 44 | + return ret; | |
| 45 | + | |
| 46 | + switch (info.type) { | |
| 47 | + case PLL_VPLL0: | |
| 48 | + case PLL_VPLL1: | |
| 49 | + case PLL_VPLL2: | |
| 50 | + case PLL_VPLL3: | |
| 51 | + nvkm_wr32(device, 0x00ef00 + (head * 0x40), 0x02080004); | |
| 52 | + nvkm_wr32(device, 0x00ef18 + (head * 0x40), (N << 16) | fN); | |
| 53 | + nvkm_wr32(device, 0x00ef04 + (head * 0x40), (P << 16) | M); | |
| 54 | + nvkm_wr32(device, 0x00e9c0 + (head * 0x04), 0x00000001); | |
| 55 | + break; | |
| 56 | + default: | |
| 57 | + nvkm_warn(subdev, "%08x/%dKhz unimplemented\n", type, freq); | |
| 58 | + ret = -EINVAL; | |
| 59 | + break; | |
| 60 | + } | |
| 61 | + | |
| 62 | + return ret; | |
| 63 | +} | |
| 64 | + | |
| 65 | +static const struct nvkm_devinit_func | |
| 66 | +ga100_devinit = { | |
| 67 | + .init = nv50_devinit_init, | |
| 68 | + .post = tu102_devinit_post, | |
| 69 | + .pll_set = ga100_devinit_pll_set, | |
| 70 | +}; | |
| 71 | + | |
| 72 | +int | |
| 73 | +ga100_devinit_new(struct nvkm_device *device, int index, struct nvkm_devinit **pinit) | |
| 74 | +{ | |
| 75 | + return nv50_devinit_new_(&ga100_devinit, device, index, pinit); | |
| 76 | +} | |
| @@ -19,4 +19,5 @@ void nvkm_devinit_ctor(const struct nvkm_devinit_func *, struct nvkm_device *, · 18 unmodified lines | ||
| 19 | 19 | int index, struct nvkm_devinit *); |
| 20 | 20 | |
| 21 | 21 | int nv04_devinit_post(struct nvkm_devinit *, bool); |
| 22 | +int tu102_devinit_post(struct nvkm_devinit *, bool); | |
| 22 | 23 | #endif |
| @@ -65,7 +65,7 @@ tu102_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq) · 64 unmodified lines | ||
| 65 | 65 | return ret; |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | −static int | |
| 68 | +int | |
| 69 | 69 | tu102_devinit_post(struct nvkm_devinit *base, bool post) |
| 70 | 70 | { |
| 71 | 71 | struct nv50_devinit *init = nv50_devinit(base); |
| @@ -32,6 +32,8 @@ nvkm-y += nvkm/subdev/fb/gp100.o · 31 unmodified lines | ||
| 32 | 32 | nvkm-y += nvkm/subdev/fb/gp102.o |
| 33 | 33 | nvkm-y += nvkm/subdev/fb/gp10b.o |
| 34 | 34 | nvkm-y += nvkm/subdev/fb/gv100.o |
| 35 | +nvkm-y += nvkm/subdev/fb/ga100.o | |
| 36 | +nvkm-y += nvkm/subdev/fb/ga102.o | |
| 35 | 37 | |
| 36 | 38 | nvkm-y += nvkm/subdev/fb/ram.o |
| 37 | 39 | nvkm-y += nvkm/subdev/fb/ramnv04.o |
| @@ -52,6 +54,7 @@ nvkm-y += nvkm/subdev/fb/ramgk104.o · 14 unmodified lines | ||
| 52 | 54 | nvkm-y += nvkm/subdev/fb/ramgm107.o |
| 53 | 55 | nvkm-y += nvkm/subdev/fb/ramgm200.o |
| 54 | 56 | nvkm-y += nvkm/subdev/fb/ramgp100.o |
| 57 | +nvkm-y += nvkm/subdev/fb/ramga102.o | |
| 55 | 58 | nvkm-y += nvkm/subdev/fb/sddr2.o |
| 56 | 59 | nvkm-y += nvkm/subdev/fb/sddr3.o |
| 57 | 60 | nvkm-y += nvkm/subdev/fb/gddr3.o |
| @@ -0,0 +1,40 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 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 shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "gf100.h" | |
| 23 | +#include "ram.h" | |
| 24 | + | |
| 25 | +static const struct nvkm_fb_func | |
| 26 | +ga100_fb = { | |
| 27 | + .dtor = gf100_fb_dtor, | |
| 28 | + .oneinit = gf100_fb_oneinit, | |
| 29 | + .init = gp100_fb_init, | |
| 30 | + .init_page = gv100_fb_init_page, | |
| 31 | + .init_unkn = gp100_fb_init_unkn, | |
| 32 | + .ram_new = gp100_ram_new, | |
| 33 | + .default_bigpage = 16, | |
| 34 | +}; | |
| 35 | + | |
| 36 | +int | |
| 37 | +ga100_fb_new(struct nvkm_device *device, int index, struct nvkm_fb **pfb) | |
| 38 | +{ | |
| 39 | + return gp102_fb_new_(&ga100_fb, device, index, pfb); | |
| 40 | +} | |
| @@ -0,0 +1,40 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 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 shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "gf100.h" | |
| 23 | +#include "ram.h" | |
| 24 | + | |
| 25 | +static const struct nvkm_fb_func | |
| 26 | +ga102_fb = { | |
| 27 | + .dtor = gf100_fb_dtor, | |
| 28 | + .oneinit = gf100_fb_oneinit, | |
| 29 | + .init = gp100_fb_init, | |
| 30 | + .init_page = gv100_fb_init_page, | |
| 31 | + .init_unkn = gp100_fb_init_unkn, | |
| 32 | + .ram_new = ga102_ram_new, | |
| 33 | + .default_bigpage = 16, | |
| 34 | +}; | |
| 35 | + | |
| 36 | +int | |
| 37 | +ga102_fb_new(struct nvkm_device *device, int index, struct nvkm_fb **pfb) | |
| 38 | +{ | |
| 39 | + return gp102_fb_new_(&ga102_fb, device, index, pfb); | |
| 40 | +} | |
| @@ -22,7 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include "gf100.h" |
| 23 | 23 | #include "ram.h" |
| 24 | 24 | |
| 25 | −static int | |
| 25 | +int | |
| 26 | 26 | gv100_fb_init_page(struct nvkm_fb *fb) |
| 27 | 27 | { |
| 28 | 28 | return (fb->page == 16) ? 0 : -EINVAL; |
| @@ -82,4 +82,6 @@ int gp102_fb_new_(const struct nvkm_fb_func *, struct nvkm_device *, int, · 81 unmodified lines | ||
| 82 | 82 | struct nvkm_fb **); |
| 83 | 83 | bool gp102_fb_vpr_scrub_required(struct nvkm_fb *); |
| 84 | 84 | int gp102_fb_vpr_scrub(struct nvkm_fb *); |
| 85 | + | |
| 86 | +int gv100_fb_init_page(struct nvkm_fb *); | |
| 85 | 87 | #endif |
| @@ -70,4 +70,5 @@ int gk104_ram_new(struct nvkm_fb *, struct nvkm_ram **); · 69 unmodified lines | ||
| 70 | 70 | int gm107_ram_new(struct nvkm_fb *, struct nvkm_ram **); |
| 71 | 71 | int gm200_ram_new(struct nvkm_fb *, struct nvkm_ram **); |
| 72 | 72 | int gp100_ram_new(struct nvkm_fb *, struct nvkm_ram **); |
| 73 | +int ga102_ram_new(struct nvkm_fb *, struct nvkm_ram **); | |
| 73 | 74 | #endif |
| @@ -0,0 +1,40 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 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 shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "ram.h" | |
| 23 | + | |
| 24 | +#include <subdev/bios.h> | |
| 25 | +#include <subdev/bios/init.h> | |
| 26 | +#include <subdev/bios/rammap.h> | |
| 27 | + | |
| 28 | +static const struct nvkm_ram_func | |
| 29 | +ga102_ram = { | |
| 30 | +}; | |
| 31 | + | |
| 32 | +int | |
| 33 | +ga102_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) | |
| 34 | +{ | |
| 35 | + struct nvkm_device *device = fb->subdev.device; | |
| 36 | + enum nvkm_ram_type type = nvkm_fb_bios_memtype(device->bios); | |
| 37 | + u32 size = nvkm_rd32(device, 0x1183a4); | |
| 38 | + | |
| 39 | + return nvkm_ram_new_(&ga102_ram, fb, type, (u64)size << 20, pram); | |
| 40 | +} | |
| @@ -5,3 +5,4 @@ nvkm-y += nvkm/subdev/gpio/nv50.o · 4 unmodified lines | ||
| 5 | 5 | nvkm-y += nvkm/subdev/gpio/g94.o |
| 6 | 6 | nvkm-y += nvkm/subdev/gpio/gf119.o |
| 7 | 7 | nvkm-y += nvkm/subdev/gpio/gk104.o |
| 8 | +nvkm-y += nvkm/subdev/gpio/ga102.o | |
| @@ -0,0 +1,118 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 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 shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "priv.h" | |
| 23 | + | |
| 24 | +static void | |
| 25 | +ga102_gpio_reset(struct nvkm_gpio *gpio, u8 match) | |
| 26 | +{ | |
| 27 | + struct nvkm_device *device = gpio->subdev.device; | |
| 28 | + struct nvkm_bios *bios = device->bios; | |
| 29 | + u8 ver, len; | |
| 30 | + u16 entry; | |
| 31 | + int ent = -1; | |
| 32 | + | |
| 33 | + while ((entry = dcb_gpio_entry(bios, 0, ++ent, &ver, &len))) { | |
| 34 | + u32 data = nvbios_rd32(bios, entry); | |
| 35 | + u8 line = (data & 0x0000003f); | |
| 36 | + u8 defs = !!(data & 0x00000080); | |
| 37 | + u8 func = (data & 0x0000ff00) >> 8; | |
| 38 | + u8 unk0 = (data & 0x00ff0000) >> 16; | |
| 39 | + u8 unk1 = (data & 0x1f000000) >> 24; | |
| 40 | + | |
| 41 | + if ( func == DCB_GPIO_UNUSED || | |
| 42 | + (match != DCB_GPIO_UNUSED && match != func)) | |
| 43 | + continue; | |
| 44 | + | |
| 45 | + nvkm_gpio_set(gpio, 0, func, line, defs); | |
| 46 | + | |
| 47 | + nvkm_mask(device, 0x021200 + (line * 4), 0xff, unk0); | |
| 48 | + if (unk1--) | |
| 49 | + nvkm_mask(device, 0x00d740 + (unk1 * 4), 0xff, line); | |
| 50 | + } | |
| 51 | +} | |
| 52 | + | |
| 53 | +static int | |
| 54 | +ga102_gpio_drive(struct nvkm_gpio *gpio, int line, int dir, int out) | |
| 55 | +{ | |
| 56 | + struct nvkm_device *device = gpio->subdev.device; | |
| 57 | + u32 data = ((dir ^ 1) << 13) | (out << 12); | |
| 58 | + nvkm_mask(device, 0x021200 + (line * 4), 0x00003000, data); | |
| 59 | + nvkm_mask(device, 0x00d604, 0x00000001, 0x00000001); /* update? */ | |
| 60 | + return 0; | |
| 61 | +} | |
| 62 | + | |
| 63 | +static int | |
| 64 | +ga102_gpio_sense(struct nvkm_gpio *gpio, int line) | |
| 65 | +{ | |
| 66 | + struct nvkm_device *device = gpio->subdev.device; | |
| 67 | + return !!(nvkm_rd32(device, 0x021200 + (line * 4)) & 0x00004000); | |
| 68 | +} | |
| 69 | + | |
| 70 | +static void | |
| 71 | +ga102_gpio_intr_stat(struct nvkm_gpio *gpio, u32 *hi, u32 *lo) | |
| 72 | +{ | |
| 73 | + struct nvkm_device *device = gpio->subdev.device; | |
| 74 | + u32 intr0 = nvkm_rd32(device, 0x021640); | |
| 75 | + u32 intr1 = nvkm_rd32(device, 0x02164c); | |
| 76 | + u32 stat0 = nvkm_rd32(device, 0x021648) & intr0; | |
| 77 | + u32 stat1 = nvkm_rd32(device, 0x021654) & intr1; | |
| 78 | + *lo = (stat1 & 0xffff0000) | (stat0 >> 16); | |
| 79 | + *hi = (stat1 << 16) | (stat0 & 0x0000ffff); | |
| 80 | + nvkm_wr32(device, 0x021640, intr0); | |
| 81 | + nvkm_wr32(device, 0x02164c, intr1); | |
| 82 | +} | |
| 83 | + | |
| 84 | +static void | |
| 85 | +ga102_gpio_intr_mask(struct nvkm_gpio *gpio, u32 type, u32 mask, u32 data) | |
| 86 | +{ | |
| 87 | + struct nvkm_device *device = gpio->subdev.device; | |
| 88 | + u32 inte0 = nvkm_rd32(device, 0x021648); | |
| 89 | + u32 inte1 = nvkm_rd32(device, 0x021654); | |
| 90 | + if (type & NVKM_GPIO_LO) | |
| 91 | + inte0 = (inte0 & ~(mask << 16)) | (data << 16); | |
| 92 | + if (type & NVKM_GPIO_HI) | |
| 93 | + inte0 = (inte0 & ~(mask & 0xffff)) | (data & 0xffff); | |
| 94 | + mask >>= 16; | |
| 95 | + data >>= 16; | |
| 96 | + if (type & NVKM_GPIO_LO) | |
| 97 | + inte1 = (inte1 & ~(mask << 16)) | (data << 16); | |
| 98 | + if (type & NVKM_GPIO_HI) | |
| 99 | + inte1 = (inte1 & ~mask) | data; | |
| 100 | + nvkm_wr32(device, 0x021648, inte0); | |
| 101 | + nvkm_wr32(device, 0x021654, inte1); | |
| 102 | +} | |
| 103 | + | |
| 104 | +static const struct nvkm_gpio_func | |
| 105 | +ga102_gpio = { | |
| 106 | + .lines = 32, | |
| 107 | + .intr_stat = ga102_gpio_intr_stat, | |
| 108 | + .intr_mask = ga102_gpio_intr_mask, | |
| 109 | + .drive = ga102_gpio_drive, | |
| 110 | + .sense = ga102_gpio_sense, | |
| 111 | + .reset = ga102_gpio_reset, | |
| 112 | +}; | |
| 113 | + | |
| 114 | +int | |
| 115 | +ga102_gpio_new(struct nvkm_device *device, int index, struct nvkm_gpio **pgpio) | |
| 116 | +{ | |
| 117 | + return nvkm_gpio_new_(&ga102_gpio, device, index, pgpio); | |
| 118 | +} | |
| @@ -7,6 +7,7 @@ nvkm-y += nvkm/subdev/i2c/g94.o · 6 unmodified lines | ||
| 7 | 7 | nvkm-y += nvkm/subdev/i2c/gf117.o |
| 8 | 8 | nvkm-y += nvkm/subdev/i2c/gf119.o |
| 9 | 9 | nvkm-y += nvkm/subdev/i2c/gk104.o |
| 10 | +nvkm-y += nvkm/subdev/i2c/gk110.o | |
| 10 | 11 | nvkm-y += nvkm/subdev/i2c/gm200.o |
| 11 | 12 | |
| 12 | 13 | nvkm-y += nvkm/subdev/i2c/pad.o |
| @@ -3,6 +3,13 @@ · 2 unmodified lines | ||
| 3 | 3 | #define __NVKM_I2C_AUX_H__ |
| 4 | 4 | #include "pad.h" |
| 5 | 5 | |
| 6 | +static inline void | |
| 7 | +nvkm_i2c_aux_autodpcd(struct nvkm_i2c *i2c, int aux, bool enable) | |
| 8 | +{ | |
| 9 | + if (i2c->func->aux_autodpcd) | |
| 10 | + i2c->func->aux_autodpcd(i2c, aux, false); | |
| 11 | +} | |
| 12 | + | |
| 6 | 13 | struct nvkm_i2c_aux_func { |
| 7 | 14 | bool address_only; |
| 8 | 15 | int (*xfer)(struct nvkm_i2c_aux *, bool retry, u8 type, |
| @@ -77,7 +77,8 @@ g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 76 unmodified lines | ||
| 77 | 77 | u8 type, u32 addr, u8 *data, u8 *size) |
| 78 | 78 | { |
| 79 | 79 | struct g94_i2c_aux *aux = g94_i2c_aux(obj); |
| 80 | − struct nvkm_device *device = aux->base.pad->i2c->subdev.device; | |
| 80 | + struct nvkm_i2c *i2c = aux->base.pad->i2c; | |
| 81 | + struct nvkm_device *device = i2c->subdev.device; | |
| 81 | 82 | const u32 base = aux->ch * 0x50; |
| 82 | 83 | u32 ctrl, stat, timeout, retries = 0; |
| 83 | 84 | u32 xbuf[4] = {}; |
| @@ -96,6 +97,8 @@ g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 12 unmodified lines | ||
| 96 | 97 | goto out; |
| 97 | 98 | } |
| 98 | 99 | |
| 100 | + nvkm_i2c_aux_autodpcd(i2c, aux->ch, false); | |
| 101 | + | |
| 99 | 102 | if (!(type & 1)) { |
| 100 | 103 | memcpy(xbuf, data, *size); |
| 101 | 104 | for (i = 0; i < 16; i += 4) { |
| @@ -128,7 +131,7 @@ g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 26 unmodified lines | ||
| 128 | 131 | if (!timeout--) { |
| 129 | 132 | AUX_ERR(&aux->base, "timeout %08x", ctrl); |
| 130 | 133 | ret = -EIO; |
| 131 | − goto out; | |
| 134 | + goto out_err; | |
| 132 | 135 | } |
| 133 | 136 | } while (ctrl & 0x00010000); |
| 134 | 137 | ret = 0; |
| @@ -154,7 +157,8 @@ g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 19 unmodified lines | ||
| 154 | 157 | memcpy(data, xbuf, *size); |
| 155 | 158 | *size = stat & 0x0000001f; |
| 156 | 159 | } |
| 157 | − | |
| 160 | +out_err: | |
| 161 | + nvkm_i2c_aux_autodpcd(i2c, aux->ch, true); | |
| 158 | 162 | out: |
| 159 | 163 | g94_i2c_aux_fini(aux); |
| 160 | 164 | return ret < 0 ? ret : (stat & 0x000f0000) >> 16; |
| @@ -33,7 +33,7 @@ static void · 32 unmodified lines | ||
| 33 | 33 | gm200_i2c_aux_fini(struct gm200_i2c_aux *aux) |
| 34 | 34 | { |
| 35 | 35 | struct nvkm_device *device = aux->base.pad->i2c->subdev.device; |
| 36 | − nvkm_mask(device, 0x00d954 + (aux->ch * 0x50), 0x00310000, 0x00000000); | |
| 36 | + nvkm_mask(device, 0x00d954 + (aux->ch * 0x50), 0x00710000, 0x00000000); | |
| 37 | 37 | } |
| 38 | 38 | |
| 39 | 39 | static int |
| @@ -54,10 +54,10 @@ gm200_i2c_aux_init(struct gm200_i2c_aux *aux) · 14 unmodified lines | ||
| 54 | 54 | AUX_ERR(&aux->base, "begin idle timeout %08x", ctrl); |
| 55 | 55 | return -EBUSY; |
| 56 | 56 | } |
| 57 | − } while (ctrl & 0x03010000); | |
| 57 | + } while (ctrl & 0x07010000); | |
| 58 | 58 | |
| 59 | 59 | /* set some magic, and wait up to 1ms for it to appear */ |
| 60 | − nvkm_mask(device, 0x00d954 + (aux->ch * 0x50), 0x00300000, ureq); | |
| 60 | + nvkm_mask(device, 0x00d954 + (aux->ch * 0x50), 0x00700000, ureq); | |
| 61 | 61 | timeout = 1000; |
| 62 | 62 | do { |
| 63 | 63 | ctrl = nvkm_rd32(device, 0x00d954 + (aux->ch * 0x50)); |
| @@ -67,7 +67,7 @@ gm200_i2c_aux_init(struct gm200_i2c_aux *aux) · 3 unmodified lines | ||
| 67 | 67 | gm200_i2c_aux_fini(aux); |
| 68 | 68 | return -EBUSY; |
| 69 | 69 | } |
| 70 | − } while ((ctrl & 0x03000000) != urep); | |
| 70 | + } while ((ctrl & 0x07000000) != urep); | |
| 71 | 71 | |
| 72 | 72 | return 0; |
| 73 | 73 | } |
| @@ -77,7 +77,8 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 3 unmodified lines | ||
| 77 | 77 | u8 type, u32 addr, u8 *data, u8 *size) |
| 78 | 78 | { |
| 79 | 79 | struct gm200_i2c_aux *aux = gm200_i2c_aux(obj); |
| 80 | − struct nvkm_device *device = aux->base.pad->i2c->subdev.device; | |
| 80 | + struct nvkm_i2c *i2c = aux->base.pad->i2c; | |
| 81 | + struct nvkm_device *device = i2c->subdev.device; | |
| 81 | 82 | const u32 base = aux->ch * 0x50; |
| 82 | 83 | u32 ctrl, stat, timeout, retries = 0; |
| 83 | 84 | u32 xbuf[4] = {}; |
| @@ -96,6 +97,8 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 12 unmodified lines | ||
| 96 | 97 | goto out; |
| 97 | 98 | } |
| 98 | 99 | |
| 100 | + nvkm_i2c_aux_autodpcd(i2c, aux->ch, false); | |
| 101 | + | |
| 99 | 102 | if (!(type & 1)) { |
| 100 | 103 | memcpy(xbuf, data, *size); |
| 101 | 104 | for (i = 0; i < 16; i += 4) { |
| @@ -128,7 +131,7 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 26 unmodified lines | ||
| 128 | 131 | if (!timeout--) { |
| 129 | 132 | AUX_ERR(&aux->base, "timeout %08x", ctrl); |
| 130 | 133 | ret = -EIO; |
| 131 | − goto out; | |
| 134 | + goto out_err; | |
| 132 | 135 | } |
| 133 | 136 | } while (ctrl & 0x00010000); |
| 134 | 137 | ret = 0; |
| @@ -155,6 +158,8 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 20 unmodified lines | ||
| 155 | 158 | *size = stat & 0x0000001f; |
| 156 | 159 | } |
| 157 | 160 | |
| 161 | +out_err: | |
| 162 | + nvkm_i2c_aux_autodpcd(i2c, aux->ch, true); | |
| 158 | 163 | out: |
| 159 | 164 | gm200_i2c_aux_fini(aux); |
| 160 | 165 | return ret < 0 ? ret : (stat & 0x000f0000) >> 16; |
| @@ -0,0 +1,45 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 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 shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "priv.h" | |
| 23 | +#include "pad.h" | |
| 24 | + | |
| 25 | +static void | |
| 26 | +gk110_aux_autodpcd(struct nvkm_i2c *i2c, int aux, bool enable) | |
| 27 | +{ | |
| 28 | + nvkm_mask(i2c->subdev.device, 0x00e4f8 + (aux * 0x50), 0x00010000, enable << 16); | |
| 29 | +} | |
| 30 | + | |
| 31 | +static const struct nvkm_i2c_func | |
| 32 | +gk110_i2c = { | |
| 33 | + .pad_x_new = gf119_i2c_pad_x_new, | |
| 34 | + .pad_s_new = gf119_i2c_pad_s_new, | |
| 35 | + .aux = 4, | |
| 36 | + .aux_stat = gk104_aux_stat, | |
| 37 | + .aux_mask = gk104_aux_mask, | |
| 38 | + .aux_autodpcd = gk110_aux_autodpcd, | |
| 39 | +}; | |
| 40 | + | |
| 41 | +int | |
| 42 | +gk110_i2c_new(struct nvkm_device *device, int index, struct nvkm_i2c **pi2c) | |
| 43 | +{ | |
| 44 | + return nvkm_i2c_new_(&gk110_i2c, device, index, pi2c); | |
| 45 | +} | |
| @@ -24,6 +24,12 @@ · 23 unmodified lines | ||
| 24 | 24 | #include "priv.h" |
| 25 | 25 | #include "pad.h" |
| 26 | 26 | |
| 27 | +static void | |
| 28 | +gm200_aux_autodpcd(struct nvkm_i2c *i2c, int aux, bool enable) | |
| 29 | +{ | |
| 30 | + nvkm_mask(i2c->subdev.device, 0x00d968 + (aux * 0x50), 0x00010000, enable << 16); | |
| 31 | +} | |
| 32 | + | |
| 27 | 33 | static const struct nvkm_i2c_func |
| 28 | 34 | gm200_i2c = { |
| 29 | 35 | .pad_x_new = gf119_i2c_pad_x_new, |
| @@ -31,6 +37,7 @@ gm200_i2c = { · 1 unmodified line | ||
| 31 | 37 | .aux = 8, |
| 32 | 38 | .aux_stat = gk104_aux_stat, |
| 33 | 39 | .aux_mask = gk104_aux_mask, |
| 40 | + .aux_autodpcd = gm200_aux_autodpcd, | |
| 34 | 41 | }; |
| 35 | 42 | |
| 36 | 43 | int |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | /* SPDX-License-Identifier: MIT */ |
| 2 | 2 | #ifndef __NVKM_I2C_PAD_H__ |
| 3 | 3 | #define __NVKM_I2C_PAD_H__ |
| 4 | −#include <subdev/i2c.h> | |
| 4 | +#include "priv.h" | |
| 5 | 5 | |
| 6 | 6 | struct nvkm_i2c_pad { |
| 7 | 7 | const struct nvkm_i2c_pad_func *func; |
| @@ -23,6 +23,10 @@ struct nvkm_i2c_func { · 22 unmodified lines | ||
| 23 | 23 | /* mask on/off interrupt types for a given set of auxch |
| 24 | 24 | */ |
| 25 | 25 | void (*aux_mask)(struct nvkm_i2c *, u32, u32, u32); |
| 26 | + | |
| 27 | + /* enable/disable HW-initiated DPCD reads | |
| 28 | + */ | |
| 29 | + void (*aux_autodpcd)(struct nvkm_i2c *, int aux, bool enable); | |
| 26 | 30 | }; |
| 27 | 31 | |
| 28 | 32 | void g94_aux_stat(struct nvkm_i2c *, u32 *, u32 *, u32 *, u32 *); |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | * Authors: Ben Skeggs |
| 23 | 23 | */ |
| 24 | 24 | #include "priv.h" |
| 25 | +#include <subdev/timer.h> | |
| 25 | 26 | |
| 26 | 27 | static void |
| 27 | 28 | gf100_ibus_intr_hub(struct nvkm_subdev *ibus, int i) |
| @@ -31,7 +32,6 @@ gf100_ibus_intr_hub(struct nvkm_subdev *ibus, int i) · 3 unmodified lines | ||
| 31 | 32 | u32 data = nvkm_rd32(device, 0x122124 + (i * 0x0400)); |
| 32 | 33 | u32 stat = nvkm_rd32(device, 0x122128 + (i * 0x0400)); |
| 33 | 34 | nvkm_debug(ibus, "HUB%d: %06x %08x (%08x)\n", i, addr, data, stat); |
| 34 | − nvkm_mask(device, 0x122128 + (i * 0x0400), 0x00000200, 0x00000000); | |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | 37 | static void |
| @@ -42,7 +42,6 @@ gf100_ibus_intr_rop(struct nvkm_subdev *ibus, int i) · 4 unmodified lines | ||
| 42 | 42 | u32 data = nvkm_rd32(device, 0x124124 + (i * 0x0400)); |
| 43 | 43 | u32 stat = nvkm_rd32(device, 0x124128 + (i * 0x0400)); |
| 44 | 44 | nvkm_debug(ibus, "ROP%d: %06x %08x (%08x)\n", i, addr, data, stat); |
| 45 | − nvkm_mask(device, 0x124128 + (i * 0x0400), 0x00000200, 0x00000000); | |
| 46 | 45 | } |
| 47 | 46 | |
| 48 | 47 | static void |
| @@ -53,7 +52,6 @@ gf100_ibus_intr_gpc(struct nvkm_subdev *ibus, int i) · 4 unmodified lines | ||
| 53 | 52 | u32 data = nvkm_rd32(device, 0x128124 + (i * 0x0400)); |
| 54 | 53 | u32 stat = nvkm_rd32(device, 0x128128 + (i * 0x0400)); |
| 55 | 54 | nvkm_debug(ibus, "GPC%d: %06x %08x (%08x)\n", i, addr, data, stat); |
| 56 | − nvkm_mask(device, 0x128128 + (i * 0x0400), 0x00000200, 0x00000000); | |
| 57 | 55 | } |
| 58 | 56 | |
| 59 | 57 | void |
| @@ -90,6 +88,12 @@ gf100_ibus_intr(struct nvkm_subdev *ibus) · 30 unmodified lines | ||
| 90 | 88 | intr1 &= ~stat; |
| 91 | 89 | } |
| 92 | 90 | } |
| 91 | + | |
| 92 | + nvkm_mask(device, 0x121c4c, 0x0000003f, 0x00000002); | |
| 93 | + nvkm_msec(device, 2000, | |
| 94 | + if (!(nvkm_rd32(device, 0x121c4c) & 0x0000003f)) | |
| 95 | + break; | |
| 96 | + ); | |
| 93 | 97 | } |
| 94 | 98 | |
| 95 | 99 | static int |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | * Authors: Ben Skeggs |
| 23 | 23 | */ |
| 24 | 24 | #include "priv.h" |
| 25 | +#include <subdev/timer.h> | |
| 25 | 26 | |
| 26 | 27 | static void |
| 27 | 28 | gk104_ibus_intr_hub(struct nvkm_subdev *ibus, int i) |
| @@ -31,7 +32,6 @@ gk104_ibus_intr_hub(struct nvkm_subdev *ibus, int i) · 3 unmodified lines | ||
| 31 | 32 | u32 data = nvkm_rd32(device, 0x122124 + (i * 0x0800)); |
| 32 | 33 | u32 stat = nvkm_rd32(device, 0x122128 + (i * 0x0800)); |
| 33 | 34 | nvkm_debug(ibus, "HUB%d: %06x %08x (%08x)\n", i, addr, data, stat); |
| 34 | − nvkm_mask(device, 0x122128 + (i * 0x0800), 0x00000200, 0x00000000); | |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | 37 | static void |
| @@ -42,7 +42,6 @@ gk104_ibus_intr_rop(struct nvkm_subdev *ibus, int i) · 4 unmodified lines | ||
| 42 | 42 | u32 data = nvkm_rd32(device, 0x124124 + (i * 0x0800)); |
| 43 | 43 | u32 stat = nvkm_rd32(device, 0x124128 + (i * 0x0800)); |
| 44 | 44 | nvkm_debug(ibus, "ROP%d: %06x %08x (%08x)\n", i, addr, data, stat); |
| 45 | − nvkm_mask(device, 0x124128 + (i * 0x0800), 0x00000200, 0x00000000); | |
| 46 | 45 | } |
| 47 | 46 | |
| 48 | 47 | static void |
| @@ -53,7 +52,6 @@ gk104_ibus_intr_gpc(struct nvkm_subdev *ibus, int i) · 4 unmodified lines | ||
| 53 | 52 | u32 data = nvkm_rd32(device, 0x128124 + (i * 0x0800)); |
| 54 | 53 | u32 stat = nvkm_rd32(device, 0x128128 + (i * 0x0800)); |
| 55 | 54 | nvkm_debug(ibus, "GPC%d: %06x %08x (%08x)\n", i, addr, data, stat); |
| 56 | − nvkm_mask(device, 0x128128 + (i * 0x0800), 0x00000200, 0x00000000); | |
| 57 | 55 | } |
| 58 | 56 | |
| 59 | 57 | void |
| @@ -90,6 +88,12 @@ gk104_ibus_intr(struct nvkm_subdev *ibus) · 30 unmodified lines | ||
| 90 | 88 | intr1 &= ~stat; |
| 91 | 89 | } |
| 92 | 90 | } |
| 91 | + | |
| 92 | + nvkm_mask(device, 0x12004c, 0x0000003f, 0x00000002); | |
| 93 | + nvkm_msec(device, 2000, | |
| 94 | + if (!(nvkm_rd32(device, 0x12004c) & 0x0000003f)) | |
| 95 | + break; | |
| 96 | + ); | |
| 93 | 97 | } |
| 94 | 98 | |
| 95 | 99 | static int |
| @@ -14,3 +14,4 @@ nvkm-y += nvkm/subdev/mc/gk20a.o · 13 unmodified lines | ||
| 14 | 14 | nvkm-y += nvkm/subdev/mc/gp100.o |
| 15 | 15 | nvkm-y += nvkm/subdev/mc/gp10b.o |
| 16 | 16 | nvkm-y += nvkm/subdev/mc/tu102.o |
| 17 | +nvkm-y += nvkm/subdev/mc/ga100.o | |
| @@ -0,0 +1,74 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 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 shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "priv.h" | |
| 23 | + | |
| 24 | +static void | |
| 25 | +ga100_mc_intr_unarm(struct nvkm_mc *mc) | |
| 26 | +{ | |
| 27 | + nvkm_wr32(mc->subdev.device, 0xb81610, 0x00000004); | |
| 28 | +} | |
| 29 | + | |
| 30 | +static void | |
| 31 | +ga100_mc_intr_rearm(struct nvkm_mc *mc) | |
| 32 | +{ | |
| 33 | + nvkm_wr32(mc->subdev.device, 0xb81608, 0x00000004); | |
| 34 | +} | |
| 35 | + | |
| 36 | +static void | |
| 37 | +ga100_mc_intr_mask(struct nvkm_mc *mc, u32 mask, u32 intr) | |
| 38 | +{ | |
| 39 | + nvkm_wr32(mc->subdev.device, 0xb81210, mask & intr ); | |
| 40 | + nvkm_wr32(mc->subdev.device, 0xb81410, mask & ~(mask & intr)); | |
| 41 | +} | |
| 42 | + | |
| 43 | +static u32 | |
| 44 | +ga100_mc_intr_stat(struct nvkm_mc *mc) | |
| 45 | +{ | |
| 46 | + u32 intr_top = nvkm_rd32(mc->subdev.device, 0xb81600), intr = 0x00000000; | |
| 47 | + if (intr_top & 0x00000004) | |
| 48 | + intr = nvkm_mask(mc->subdev.device, 0xb81010, 0x00000000, 0x00000000); | |
| 49 | + return intr; | |
| 50 | +} | |
| 51 | + | |
| 52 | +static void | |
| 53 | +ga100_mc_init(struct nvkm_mc *mc) | |
| 54 | +{ | |
| 55 | + nv50_mc_init(mc); | |
| 56 | + nvkm_wr32(mc->subdev.device, 0xb81210, 0xffffffff); | |
| 57 | +} | |
| 58 | + | |
| 59 | +static const struct nvkm_mc_func | |
| 60 | +ga100_mc = { | |
| 61 | + .init = ga100_mc_init, | |
| 62 | + .intr = gp100_mc_intr, | |
| 63 | + .intr_unarm = ga100_mc_intr_unarm, | |
| 64 | + .intr_rearm = ga100_mc_intr_rearm, | |
| 65 | + .intr_mask = ga100_mc_intr_mask, | |
| 66 | + .intr_stat = ga100_mc_intr_stat, | |
| 67 | + .reset = gk104_mc_reset, | |
| 68 | +}; | |
| 69 | + | |
| 70 | +int | |
| 71 | +ga100_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc) | |
| 72 | +{ | |
| 73 | + return nvkm_mc_new_(&ga100_mc, device, index, pmc); | |
| 74 | +} | |
| @@ -316,9 +316,9 @@ nvkm_mmu_vram(struct nvkm_mmu *mmu) · 315 unmodified lines | ||
| 316 | 316 | { |
| 317 | 317 | struct nvkm_device *device = mmu->subdev.device; |
| 318 | 318 | struct nvkm_mm *mm = &device->fb->ram->vram; |
| 319 | − const u32 sizeN = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NORMAL); | |
| 320 | − const u32 sizeU = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NOMAP); | |
| 321 | − const u32 sizeM = nvkm_mm_heap_size(mm, NVKM_RAM_MM_MIXED); | |
| 319 | + const u64 sizeN = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NORMAL); | |
| 320 | + const u64 sizeU = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NOMAP); | |
| 321 | + const u64 sizeM = nvkm_mm_heap_size(mm, NVKM_RAM_MM_MIXED); | |
| 322 | 322 | u8 type = NVKM_MEM_KIND * !!mmu->func->kind; |
| 323 | 323 | u8 heap = NVKM_MEM_VRAM; |
| 324 | 324 | int heapM, heapN, heapU; |
| @@ -730,9 +730,6 @@ int radeon_ttm_init(struct radeon_device *rdev) · 729 unmodified lines | ||
| 730 | 730 | } |
| 731 | 731 | rdev->mman.initialized = true; |
| 732 | 732 | |
| 733 | − ttm_pool_init(&rdev->mman.bdev.pool, rdev->dev, rdev->need_swiotlb, | |
| 734 | − dma_addressing_limited(&rdev->pdev->dev)); | |
| 735 | − | |
| 736 | 733 | r = radeon_ttm_init_vram(rdev); |
| 737 | 734 | if (r) { |
| 738 | 735 | DRM_ERROR("Failed initializing VRAM heap.\n"); |
| @@ -689,6 +689,30 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, · 688 unmodified lines | ||
| 689 | 689 | SUN4I_TCON1_BASIC5_V_SYNC(vsync) | |
| 690 | 690 | SUN4I_TCON1_BASIC5_H_SYNC(hsync)); |
| 691 | 691 | |
| 692 | + /* Setup the polarity of multiple signals */ | |
| 693 | + if (tcon->quirks->polarity_in_ch0) { | |
| 694 | + val = 0; | |
| 695 | + | |
| 696 | + if (mode->flags & DRM_MODE_FLAG_PHSYNC) | |
| 697 | + val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE; | |
| 698 | + | |
| 699 | + if (mode->flags & DRM_MODE_FLAG_PVSYNC) | |
| 700 | + val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE; | |
| 701 | + | |
| 702 | + regmap_write(tcon->regs, SUN4I_TCON0_IO_POL_REG, val); | |
| 703 | + } else { | |
| 704 | + /* according to vendor driver, this bit must be always set */ | |
| 705 | + val = SUN4I_TCON1_IO_POL_UNKNOWN; | |
| 706 | + | |
| 707 | + if (mode->flags & DRM_MODE_FLAG_PHSYNC) | |
| 708 | + val |= SUN4I_TCON1_IO_POL_HSYNC_POSITIVE; | |
| 709 | + | |
| 710 | + if (mode->flags & DRM_MODE_FLAG_PVSYNC) | |
| 711 | + val |= SUN4I_TCON1_IO_POL_VSYNC_POSITIVE; | |
| 712 | + | |
| 713 | + regmap_write(tcon->regs, SUN4I_TCON1_IO_POL_REG, val); | |
| 714 | + } | |
| 715 | + | |
| 692 | 716 | /* Map output pins to channel 1 */ |
| 693 | 717 | regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG, |
| 694 | 718 | SUN4I_TCON_GCTL_IOMAP_MASK, |
| @@ -1517,6 +1541,7 @@ static const struct sun4i_tcon_quirks sun8i_a83t_tv_quirks = { · 822 unmodified lines | ||
| 1517 | 1541 | |
| 1518 | 1542 | static const struct sun4i_tcon_quirks sun8i_r40_tv_quirks = { |
| 1519 | 1543 | .has_channel_1 = true, |
| 1544 | + .polarity_in_ch0 = true, | |
| 1520 | 1545 | .set_mux = sun8i_r40_tcon_tv_set_mux, |
| 1521 | 1546 | }; |
| 1522 | 1547 | |
| @@ -153,6 +153,11 @@ · 152 unmodified lines | ||
| 153 | 153 | #define SUN4I_TCON1_BASIC5_V_SYNC(height) (((height) - 1) & 0x3ff) |
| 154 | 154 | |
| 155 | 155 | #define SUN4I_TCON1_IO_POL_REG 0xf0 |
| 156 | +/* there is no documentation about this bit */ | |
| 157 | +#define SUN4I_TCON1_IO_POL_UNKNOWN BIT(26) | |
| 158 | +#define SUN4I_TCON1_IO_POL_HSYNC_POSITIVE BIT(25) | |
| 159 | +#define SUN4I_TCON1_IO_POL_VSYNC_POSITIVE BIT(24) | |
| 160 | + | |
| 156 | 161 | #define SUN4I_TCON1_IO_TRI_REG 0xf4 |
| 157 | 162 | |
| 158 | 163 | #define SUN4I_TCON_ECC_FIFO_REG 0xf8 |
| @@ -235,6 +240,7 @@ struct sun4i_tcon_quirks { · 76 unmodified lines | ||
| 235 | 240 | bool needs_de_be_mux; /* sun6i needs mux to select backend */ |
| 236 | 241 | bool needs_edp_reset; /* a80 edp reset needed for tcon0 access */ |
| 237 | 242 | bool supports_lvds; /* Does the TCON support an LVDS output? */ |
| 243 | + bool polarity_in_ch0; /* some tcon1 channels have polarity bits in tcon0 pol register */ | |
| 238 | 244 | u8 dclk_min_div; /* minimum divider for TCON0 DCLK */ |
| 239 | 245 | |
| 240 | 246 | /* callback to handle tcon muxing options */ |
| @@ -21,8 +21,7 @@ static void sun8i_dw_hdmi_encoder_mode_set(struct drm_encoder *encoder, · 20 unmodified lines | ||
| 21 | 21 | { |
| 22 | 22 | struct sun8i_dw_hdmi *hdmi = encoder_to_sun8i_dw_hdmi(encoder); |
| 23 | 23 | |
| 24 | − if (hdmi->quirks->set_rate) | |
| 25 | − clk_set_rate(hdmi->clk_tmds, mode->crtc_clock * 1000); | |
| 24 | + clk_set_rate(hdmi->clk_tmds, mode->crtc_clock * 1000); | |
| 26 | 25 | } |
| 27 | 26 | |
| 28 | 27 | static const struct drm_encoder_helper_funcs |
| @@ -48,11 +47,9 @@ sun8i_dw_hdmi_mode_valid_h6(struct dw_hdmi *hdmi, void *data, · 19 unmodified lines | ||
| 48 | 47 | { |
| 49 | 48 | /* |
| 50 | 49 | * Controller support maximum of 594 MHz, which correlates to |
| 51 | − * 4K@60Hz 4:4:4 or RGB. However, for frequencies greater than | |
| 52 | − * 340 MHz scrambling has to be enabled. Because scrambling is | |
| 53 | − * not yet implemented, just limit to 340 MHz for now. | |
| 50 | + * 4K@60Hz 4:4:4 or RGB. | |
| 54 | 51 | */ |
| 55 | − if (mode->clock > 340000) | |
| 52 | + if (mode->clock > 594000) | |
| 56 | 53 | return MODE_CLOCK_HIGH; |
| 57 | 54 | |
| 58 | 55 | return MODE_OK; |
| @@ -295,7 +292,6 @@ static int sun8i_dw_hdmi_remove(struct platform_device *pdev) · 236 unmodified lines | ||
| 295 | 292 | |
| 296 | 293 | static const struct sun8i_dw_hdmi_quirks sun8i_a83t_quirks = { |
| 297 | 294 | .mode_valid = sun8i_dw_hdmi_mode_valid_a83t, |
| 298 | − .set_rate = true, | |
| 299 | 295 | }; |
| 300 | 296 | |
| 301 | 297 | static const struct sun8i_dw_hdmi_quirks sun50i_h6_quirks = { |
| @@ -179,7 +179,6 @@ struct sun8i_dw_hdmi_quirks { · 178 unmodified lines | ||
| 179 | 179 | enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data, |
| 180 | 180 | const struct drm_display_info *info, |
| 181 | 181 | const struct drm_display_mode *mode); |
| 182 | − unsigned int set_rate : 1; | |
| 183 | 182 | unsigned int use_drm_infoframe : 1; |
| 184 | 183 | }; |
| 185 | 184 | |
| @@ -104,29 +104,21 @@ static const struct dw_hdmi_mpll_config sun50i_h6_mpll_cfg[] = { · 103 unmodified lines | ||
| 104 | 104 | |
| 105 | 105 | static const struct dw_hdmi_curr_ctrl sun50i_h6_cur_ctr[] = { |
| 106 | 106 | /* pixelclk bpp8 bpp10 bpp12 */ |
| 107 | − { 25175000, { 0x0000, 0x0000, 0x0000 }, }, | |
| 108 | 107 | { 27000000, { 0x0012, 0x0000, 0x0000 }, }, |
| 109 | − { 59400000, { 0x0008, 0x0008, 0x0008 }, }, | |
| 110 | − { 72000000, { 0x0008, 0x0008, 0x001b }, }, | |
| 111 | − { 74250000, { 0x0013, 0x0013, 0x0013 }, }, | |
| 112 | − { 90000000, { 0x0008, 0x001a, 0x001b }, }, | |
| 113 | − { 118800000, { 0x001b, 0x001a, 0x001b }, }, | |
| 114 | − { 144000000, { 0x001b, 0x001a, 0x0034 }, }, | |
| 115 | − { 180000000, { 0x001b, 0x0033, 0x0034 }, }, | |
| 116 | − { 216000000, { 0x0036, 0x0033, 0x0034 }, }, | |
| 117 | − { 237600000, { 0x0036, 0x0033, 0x001b }, }, | |
| 118 | − { 288000000, { 0x0036, 0x001b, 0x001b }, }, | |
| 119 | − { 297000000, { 0x0019, 0x001b, 0x0019 }, }, | |
| 120 | − { 330000000, { 0x0036, 0x001b, 0x001b }, }, | |
| 121 | − { 594000000, { 0x003f, 0x001b, 0x001b }, }, | |
| 108 | + { 74250000, { 0x0013, 0x001a, 0x001b }, }, | |
| 109 | + { 148500000, { 0x0019, 0x0033, 0x0034 }, }, | |
| 110 | + { 297000000, { 0x0019, 0x001b, 0x001b }, }, | |
| 111 | + { 594000000, { 0x0010, 0x001b, 0x001b }, }, | |
| 122 | 112 | { ~0UL, { 0x0000, 0x0000, 0x0000 }, } |
| 123 | 113 | }; |
| 124 | 114 | |
| 125 | 115 | static const struct dw_hdmi_phy_config sun50i_h6_phy_config[] = { |
| 126 | 116 | /*pixelclk symbol term vlev*/ |
| 127 | − { 74250000, 0x8009, 0x0004, 0x0232}, | |
| 128 | − { 148500000, 0x8029, 0x0004, 0x0273}, | |
| 129 | − { 594000000, 0x8039, 0x0004, 0x014a}, | |
| 117 | + { 27000000, 0x8009, 0x0007, 0x02b0 }, | |
| 118 | + { 74250000, 0x8009, 0x0006, 0x022d }, | |
| 119 | + { 148500000, 0x8029, 0x0006, 0x0270 }, | |
| 120 | + { 297000000, 0x8039, 0x0005, 0x01ab }, | |
| 121 | + { 594000000, 0x8029, 0x0000, 0x008a }, | |
| 130 | 122 | { ~0UL, 0x0000, 0x0000, 0x0000} |
| 131 | 123 | }; |
| 132 | 124 | |
| @@ -33,6 +33,7 @@ · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | #include <linux/module.h> |
| 35 | 35 | #include <linux/dma-mapping.h> |
| 36 | +#include <linux/highmem.h> | |
| 36 | 37 | |
| 37 | 38 | #ifdef CONFIG_X86 |
| 38 | 39 | #include <asm/set_memory.h> |
| @@ -66,7 +67,7 @@ static struct ttm_pool_type global_uncached[MAX_ORDER]; · 27 unmodified lines | ||
| 66 | 67 | static struct ttm_pool_type global_dma32_write_combined[MAX_ORDER]; |
| 67 | 68 | static struct ttm_pool_type global_dma32_uncached[MAX_ORDER]; |
| 68 | 69 | |
| 69 | −static spinlock_t shrinker_lock; | |
| 70 | +static struct mutex shrinker_lock; | |
| 70 | 71 | static struct list_head shrinker_list; |
| 71 | 72 | static struct shrinker mm_shrinker; |
| 72 | 73 | |
| @@ -79,12 +80,13 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags, · 6 unmodified lines | ||
| 79 | 80 | struct page *p; |
| 80 | 81 | void *vaddr; |
| 81 | 82 | |
| 82 | − if (order) { | |
| 83 | − gfp_flags |= GFP_TRANSHUGE_LIGHT | __GFP_NORETRY | | |
| 83 | + /* Don't set the __GFP_COMP flag for higher order allocations. | |
| 84 | + * Mapping pages directly into an userspace process and calling | |
| 85 | + * put_page() on a TTM allocated page is illegal. | |
| 86 | + */ | |
| 87 | + if (order) | |
| 88 | + gfp_flags |= __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN | | |
| 84 | 89 | __GFP_KSWAPD_RECLAIM; |
| 85 | − gfp_flags &= ~__GFP_MOVABLE; | |
| 86 | − gfp_flags &= ~__GFP_COMP; | |
| 87 | − } | |
| 88 | 90 | |
| 89 | 91 | if (!pool->use_dma_alloc) { |
| 90 | 92 | p = alloc_pages(gfp_flags, order); |
| @@ -190,7 +192,7 @@ static int ttm_pool_map(struct ttm_pool *pool, unsigned int order, · 99 unmodified lines | ||
| 190 | 192 | size_t size = (1ULL << order) * PAGE_SIZE; |
| 191 | 193 | |
| 192 | 194 | addr = dma_map_page(pool->dev, p, 0, size, DMA_BIDIRECTIONAL); |
| 193 | − if (dma_mapping_error(pool->dev, **dma_addr)) | |
| 195 | + if (dma_mapping_error(pool->dev, addr)) | |
| 194 | 196 | return -EFAULT; |
| 195 | 197 | } |
| 196 | 198 | |
| @@ -217,6 +219,15 @@ static void ttm_pool_unmap(struct ttm_pool *pool, dma_addr_t dma_addr, · 20 unmodified lines | ||
| 217 | 219 | /* Give pages into a specific pool_type */ |
| 218 | 220 | static void ttm_pool_type_give(struct ttm_pool_type *pt, struct page *p) |
| 219 | 221 | { |
| 222 | + unsigned int i, num_pages = 1 << pt->order; | |
| 223 | + | |
| 224 | + for (i = 0; i < num_pages; ++i) { | |
| 225 | + if (PageHighMem(p)) | |
| 226 | + clear_highpage(p + i); | |
| 227 | + else | |
| 228 | + clear_page(page_address(p + i)); | |
| 229 | + } | |
| 230 | + | |
| 220 | 231 | spin_lock(&pt->lock); |
| 221 | 232 | list_add(&p->lru, &pt->pages); |
| 222 | 233 | spin_unlock(&pt->lock); |
| @@ -249,9 +260,9 @@ static void ttm_pool_type_init(struct ttm_pool_type *pt, struct ttm_pool *pool, · 26 unmodified lines | ||
| 249 | 260 | spin_lock_init(&pt->lock); |
| 250 | 261 | INIT_LIST_HEAD(&pt->pages); |
| 251 | 262 | |
| 252 | − spin_lock(&shrinker_lock); | |
| 263 | + mutex_lock(&shrinker_lock); | |
| 253 | 264 | list_add_tail(&pt->shrinker_list, &shrinker_list); |
| 254 | − spin_unlock(&shrinker_lock); | |
| 265 | + mutex_unlock(&shrinker_lock); | |
| 255 | 266 | } |
| 256 | 267 | |
| 257 | 268 | /* Remove a pool_type from the global shrinker list and free all pages */ |
| @@ -259,9 +270,9 @@ static void ttm_pool_type_fini(struct ttm_pool_type *pt) · 1 unmodified line | ||
| 259 | 270 | { |
| 260 | 271 | struct page *p, *tmp; |
| 261 | 272 | |
| 262 | − spin_lock(&shrinker_lock); | |
| 273 | + mutex_lock(&shrinker_lock); | |
| 263 | 274 | list_del(&pt->shrinker_list); |
| 264 | − spin_unlock(&shrinker_lock); | |
| 275 | + mutex_unlock(&shrinker_lock); | |
| 265 | 276 | |
| 266 | 277 | list_for_each_entry_safe(p, tmp, &pt->pages, lru) |
| 267 | 278 | ttm_pool_free_page(pt->pool, pt->caching, pt->order, p); |
| @@ -302,7 +313,7 @@ static unsigned int ttm_pool_shrink(void) · 34 unmodified lines | ||
| 302 | 313 | unsigned int num_freed; |
| 303 | 314 | struct page *p; |
| 304 | 315 | |
| 305 | − spin_lock(&shrinker_lock); | |
| 316 | + mutex_lock(&shrinker_lock); | |
| 306 | 317 | pt = list_first_entry(&shrinker_list, typeof(*pt), shrinker_list); |
| 307 | 318 | |
| 308 | 319 | p = ttm_pool_type_take(pt); |
| @@ -314,7 +325,7 @@ static unsigned int ttm_pool_shrink(void) · 5 unmodified lines | ||
| 314 | 325 | } |
| 315 | 326 | |
| 316 | 327 | list_move_tail(&pt->shrinker_list, &shrinker_list); |
| 317 | − spin_unlock(&shrinker_lock); | |
| 328 | + mutex_unlock(&shrinker_lock); | |
| 318 | 329 | |
| 319 | 330 | return num_freed; |
| 320 | 331 | } |
| @@ -507,7 +518,6 @@ void ttm_pool_init(struct ttm_pool *pool, struct device *dev, · 186 unmodified lines | ||
| 507 | 518 | ttm_pool_type_init(&pool->caching[i].orders[j], |
| 508 | 519 | pool, i, j); |
| 509 | 520 | } |
| 510 | −EXPORT_SYMBOL(ttm_pool_init); | |
| 511 | 521 | |
| 512 | 522 | /** |
| 513 | 523 | * ttm_pool_fini - Cleanup a pool |
| @@ -525,7 +535,6 @@ void ttm_pool_fini(struct ttm_pool *pool) · 11 unmodified lines | ||
| 525 | 535 | for (j = 0; j < MAX_ORDER; ++j) |
| 526 | 536 | ttm_pool_type_fini(&pool->caching[i].orders[j]); |
| 527 | 537 | } |
| 528 | −EXPORT_SYMBOL(ttm_pool_fini); | |
| 529 | 538 | |
| 530 | 539 | #ifdef CONFIG_DEBUG_FS |
| 531 | 540 | /* Count the number of pages available in a pool_type */ |
| @@ -566,7 +575,7 @@ int ttm_pool_debugfs(struct ttm_pool *pool, struct seq_file *m) · 34 unmodified lines | ||
| 566 | 575 | { |
| 567 | 576 | unsigned int i; |
| 568 | 577 | |
| 569 | − spin_lock(&shrinker_lock); | |
| 578 | + mutex_lock(&shrinker_lock); | |
| 570 | 579 | |
| 571 | 580 | seq_puts(m, "\t "); |
| 572 | 581 | for (i = 0; i < MAX_ORDER; ++i) |
| @@ -602,7 +611,7 @@ int ttm_pool_debugfs(struct ttm_pool *pool, struct seq_file *m) · 29 unmodified lines | ||
| 602 | 611 | seq_printf(m, "\ntotal\t: %8lu of %8lu\n", |
| 603 | 612 | atomic_long_read(&allocated_pages), page_pool_size); |
| 604 | 613 | |
| 605 | − spin_unlock(&shrinker_lock); | |
| 614 | + mutex_unlock(&shrinker_lock); | |
| 606 | 615 | |
| 607 | 616 | return 0; |
| 608 | 617 | } |
| @@ -646,7 +655,7 @@ int ttm_pool_mgr_init(unsigned long num_pages) · 37 unmodified lines | ||
| 646 | 655 | if (!page_pool_size) |
| 647 | 656 | page_pool_size = num_pages; |
| 648 | 657 | |
| 649 | − spin_lock_init(&shrinker_lock); | |
| 658 | + mutex_init(&shrinker_lock); | |
| 650 | 659 | INIT_LIST_HEAD(&shrinker_list); |
| 651 | 660 | |
| 652 | 661 | for (i = 0; i < MAX_ORDER; ++i) { |
| @@ -1267,6 +1267,7 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi) · 1266 unmodified lines | ||
| 1267 | 1267 | card->dai_link = dai_link; |
| 1268 | 1268 | card->num_links = 1; |
| 1269 | 1269 | card->name = vc4_hdmi->variant->card_name; |
| 1270 | + card->driver_name = "vc4-hdmi"; | |
| 1270 | 1271 | card->dev = dev; |
| 1271 | 1272 | card->owner = THIS_MODULE; |
| 1272 | 1273 | |
| @@ -620,11 +620,11 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) · 619 unmodified lines | ||
| 620 | 620 | * for now we just allocate globally. |
| 621 | 621 | */ |
| 622 | 622 | if (!hvs->hvs5) |
| 623 | − /* 96kB */ | |
| 624 | − drm_mm_init(&hvs->lbm_mm, 0, 96 * 1024); | |
| 623 | + /* 48k words of 2x12-bit pixels */ | |
| 624 | + drm_mm_init(&hvs->lbm_mm, 0, 48 * 1024); | |
| 625 | 625 | else |
| 626 | − /* 70k words */ | |
| 627 | − drm_mm_init(&hvs->lbm_mm, 0, 70 * 2 * 1024); | |
| 626 | + /* 60k words of 4x12-bit pixels */ | |
| 627 | + drm_mm_init(&hvs->lbm_mm, 0, 60 * 1024); | |
| 628 | 628 | |
| 629 | 629 | /* Upload filter kernels. We only have the one for now, so we |
| 630 | 630 | * keep it around for the lifetime of the driver. |
| @@ -220,7 +220,7 @@ static void vc4_plane_reset(struct drm_plane *plane) · 219 unmodified lines | ||
| 220 | 220 | __drm_atomic_helper_plane_reset(plane, &vc4_state->base); |
| 221 | 221 | } |
| 222 | 222 | |
| 223 | −static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val) | |
| 223 | +static void vc4_dlist_counter_increment(struct vc4_plane_state *vc4_state) | |
| 224 | 224 | { |
| 225 | 225 | if (vc4_state->dlist_count == vc4_state->dlist_size) { |
| 226 | 226 | u32 new_size = max(4u, vc4_state->dlist_count * 2); |
| @@ -235,7 +235,15 @@ static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val) · 8 unmodified lines | ||
| 235 | 235 | vc4_state->dlist_size = new_size; |
| 236 | 236 | } |
| 237 | 237 | |
| 238 | − vc4_state->dlist[vc4_state->dlist_count++] = val; | |
| 238 | + vc4_state->dlist_count++; | |
| 239 | +} | |
| 240 | + | |
| 241 | +static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val) | |
| 242 | +{ | |
| 243 | + unsigned int idx = vc4_state->dlist_count; | |
| 244 | + | |
| 245 | + vc4_dlist_counter_increment(vc4_state); | |
| 246 | + vc4_state->dlist[idx] = val; | |
| 239 | 247 | } |
| 240 | 248 | |
| 241 | 249 | /* Returns the scl0/scl1 field based on whether the dimensions need to |
| @@ -437,6 +445,7 @@ static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst) · 195 unmodified lines | ||
| 437 | 445 | static u32 vc4_lbm_size(struct drm_plane_state *state) |
| 438 | 446 | { |
| 439 | 447 | struct vc4_plane_state *vc4_state = to_vc4_plane_state(state); |
| 448 | + struct vc4_dev *vc4 = to_vc4_dev(state->plane->dev); | |
| 440 | 449 | u32 pix_per_line; |
| 441 | 450 | u32 lbm; |
| 442 | 451 | |
| @@ -472,7 +481,11 @@ static u32 vc4_lbm_size(struct drm_plane_state *state) · 29 unmodified lines | ||
| 472 | 481 | lbm = pix_per_line * 16; |
| 473 | 482 | } |
| 474 | 483 | |
| 475 | − lbm = roundup(lbm, 32); | |
| 484 | + /* Align it to 64 or 128 (hvs5) bytes */ | |
| 485 | + lbm = roundup(lbm, vc4->hvs->hvs5 ? 128 : 64); | |
| 486 | + | |
| 487 | + /* Each "word" of the LBM memory contains 2 or 4 (hvs5) pixels */ | |
| 488 | + lbm /= vc4->hvs->hvs5 ? 4 : 2; | |
| 476 | 489 | |
| 477 | 490 | return lbm; |
| 478 | 491 | } |
| @@ -912,9 +925,9 @@ static int vc4_plane_mode_set(struct drm_plane *plane, · 433 unmodified lines | ||
| 912 | 925 | if (!vc4_state->is_unity) { |
| 913 | 926 | vc4_dlist_write(vc4_state, |
| 914 | 927 | VC4_SET_FIELD(vc4_state->crtc_w, |
| 915 | − SCALER_POS1_SCL_WIDTH) | | |
| 928 | + SCALER5_POS1_SCL_WIDTH) | | |
| 916 | 929 | VC4_SET_FIELD(vc4_state->crtc_h, |
| 917 | − SCALER_POS1_SCL_HEIGHT)); | |
| 930 | + SCALER5_POS1_SCL_HEIGHT)); | |
| 918 | 931 | } |
| 919 | 932 | |
| 920 | 933 | /* Position Word 2: Source Image Size */ |
| @@ -973,8 +986,10 @@ static int vc4_plane_mode_set(struct drm_plane *plane, · 52 unmodified lines | ||
| 973 | 986 | * be set when calling vc4_plane_allocate_lbm(). |
| 974 | 987 | */ |
| 975 | 988 | if (vc4_state->y_scaling[0] != VC4_SCALING_NONE || |
| 976 | − vc4_state->y_scaling[1] != VC4_SCALING_NONE) | |
| 977 | − vc4_state->lbm_offset = vc4_state->dlist_count++; | |
| 989 | + vc4_state->y_scaling[1] != VC4_SCALING_NONE) { | |
| 990 | + vc4_state->lbm_offset = vc4_state->dlist_count; | |
| 991 | + vc4_dlist_counter_increment(vc4_state); | |
| 992 | + } | |
| 978 | 993 | |
| 979 | 994 | if (num_planes > 1) { |
| 980 | 995 | /* Emit Cb/Cr as channel 0 and Y as channel |
| @@ -1396,19 +1396,11 @@ static void zynqmp_disp_enable(struct zynqmp_disp *disp) · 1395 unmodified lines | ||
| 1396 | 1396 | */ |
| 1397 | 1397 | static void zynqmp_disp_disable(struct zynqmp_disp *disp) |
| 1398 | 1398 | { |
| 1399 | − struct drm_crtc *crtc = &disp->crtc; | |
| 1400 | − | |
| 1401 | 1399 | zynqmp_disp_audio_disable(&disp->audio); |
| 1402 | 1400 | |
| 1403 | 1401 | zynqmp_disp_avbuf_disable_audio(&disp->avbuf); |
| 1404 | 1402 | zynqmp_disp_avbuf_disable_channels(&disp->avbuf); |
| 1405 | 1403 | zynqmp_disp_avbuf_disable(&disp->avbuf); |
| 1406 | − | |
| 1407 | − /* Mark the flip is done as crtc is disabled anyway */ | |
| 1408 | − if (crtc->state->event) { | |
| 1409 | − complete_all(crtc->state->event->base.completion); | |
| 1410 | − crtc->state->event = NULL; | |
| 1411 | − } | |
| 1412 | 1404 | } |
| 1413 | 1405 | |
| 1414 | 1406 | static inline struct zynqmp_disp *crtc_to_disp(struct drm_crtc *crtc) |
| @@ -1499,6 +1491,13 @@ zynqmp_disp_crtc_atomic_disable(struct drm_crtc *crtc, · 84 unmodified lines | ||
| 1499 | 1491 | |
| 1500 | 1492 | drm_crtc_vblank_off(&disp->crtc); |
| 1501 | 1493 | |
| 1494 | + spin_lock_irq(&crtc->dev->event_lock); | |
| 1495 | + if (crtc->state->event) { | |
| 1496 | + drm_crtc_send_vblank_event(crtc, crtc->state->event); | |
| 1497 | + crtc->state->event = NULL; | |
| 1498 | + } | |
| 1499 | + spin_unlock_irq(&crtc->dev->event_lock); | |
| 1500 | + | |
| 1502 | 1501 | clk_disable_unprepare(disp->pclk); |
| 1503 | 1502 | pm_runtime_put_sync(disp->dev); |
| 1504 | 1503 | } |
| @@ -899,6 +899,7 @@ config HID_SONY · 898 unmodified lines | ||
| 899 | 899 | depends on NEW_LEDS |
| 900 | 900 | depends on LEDS_CLASS |
| 901 | 901 | select POWER_SUPPLY |
| 902 | + select CRC32 | |
| 902 | 903 | help |
| 903 | 904 | Support for |
| 904 | 905 | |
| @@ -154,7 +154,7 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) · 153 unmodified lines | ||
| 154 | 154 | |
| 155 | 155 | for (i = 0; i < cl_data->num_hid_devices; i++) { |
| 156 | 156 | cl_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8, |
| 157 | − &cl_data->sensor_phys_addr[i], | |
| 157 | + &cl_data->sensor_dma_addr[i], | |
| 158 | 158 | GFP_KERNEL); |
| 159 | 159 | cl_data->sensor_sts[i] = 0; |
| 160 | 160 | cl_data->sensor_requested_cnt[i] = 0; |
| @@ -187,7 +187,7 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) · 26 unmodified lines | ||
| 187 | 187 | } |
| 188 | 188 | info.period = msecs_to_jiffies(AMD_SFH_IDLE_LOOP); |
| 189 | 189 | info.sensor_idx = cl_idx; |
| 190 | − info.phys_address = cl_data->sensor_phys_addr[i]; | |
22 more lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 273 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 311 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 398 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 276 lines aren’t shown here.
This diff is large: its 206 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 268 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 338 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 116 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 245 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 204 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 229 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 335 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 325 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 268 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 180 lines aren’t shown here.
This diff is large: its 216 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 253 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 276 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 134 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 190 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 163 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 123 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 203 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 139 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 204 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 169 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 375 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 1002 lines aren’t shown here.
This diff is large: its 164 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 272 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 153 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 173 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 383 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 204 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 135 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 148 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 134 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 207 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 203 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 135 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 185 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 166 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 268 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 150 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 840 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 158 lines aren’t shown here.
This diff is large: its 221 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 1130 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 151 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 226 lines aren’t shown here.
This diff is large: its 295 lines aren’t shown here.
This diff is large: its 219 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 193 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 135 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 207 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
File renamed without changes.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.