Required for following patches. Resolve merge conflict by using the hunk from the for-next branch and shifting the iommufd_object_deref_user() into iommufd_hw_pagetable_put()
Unified · Split
| @@ -13,7 +13,9 @@ · 12 unmodified lines | ||
| 13 | 13 | Aaron Durbin <adurbin@google.com> |
| 14 | 14 | Abel Vesa <abelvesa@kernel.org> <abel.vesa@nxp.com> |
| 15 | 15 | Abel Vesa <abelvesa@kernel.org> <abelvesa@gmail.com> |
| 16 | +Abhijeet Dharmapurikar <quic_adharmap@quicinc.com> <adharmap@codeaurora.org> | |
| 16 | 17 | Abhinav Kumar <quic_abhinavk@quicinc.com> <abhinavk@codeaurora.org> |
| 18 | +Ahmad Masri <quic_amasri@quicinc.com> <amasri@codeaurora.org> | |
| 17 | 19 | Adam Oldham <oldhamca@gmail.com> |
| 18 | 20 | Adam Radford <aradford@gmail.com> |
| 19 | 21 | Adriana Reus <adi.reus@gmail.com> <adriana.reus@intel.com> |
| @@ -30,6 +32,7 @@ Alexander Mikhalitsyn <alexander@mihalicyn.com> <alexander.mikhalitsyn@virtuozzo · 10 unmodified lines | ||
| 30 | 32 | Alexander Mikhalitsyn <alexander@mihalicyn.com> <aleksandr.mikhalitsyn@canonical.com> |
| 31 | 33 | Alexandre Belloni <alexandre.belloni@bootlin.com> <alexandre.belloni@free-electrons.com> |
| 32 | 34 | Alexandre Ghiti <alex@ghiti.fr> <alexandre.ghiti@canonical.com> |
| 35 | +Alexei Avshalom Lazar <quic_ailizaro@quicinc.com> <ailizaro@codeaurora.org> | |
| 33 | 36 | Alexei Starovoitov <ast@kernel.org> <alexei.starovoitov@gmail.com> |
| 34 | 37 | Alexei Starovoitov <ast@kernel.org> <ast@fb.com> |
| 35 | 38 | Alexei Starovoitov <ast@kernel.org> <ast@plumgrid.com> |
| @@ -37,8 +40,11 @@ Alex Hung <alexhung@gmail.com> <alex.hung@canonical.com> · 1 unmodified line | ||
| 37 | 40 | Alex Shi <alexs@kernel.org> <alex.shi@intel.com> |
| 38 | 41 | Alex Shi <alexs@kernel.org> <alex.shi@linaro.org> |
| 39 | 42 | Alex Shi <alexs@kernel.org> <alex.shi@linux.alibaba.com> |
| 43 | +Aloka Dixit <quic_alokad@quicinc.com> <alokad@codeaurora.org> | |
| 40 | 44 | Al Viro <viro@ftp.linux.org.uk> |
| 41 | 45 | Al Viro <viro@zenIV.linux.org.uk> |
| 46 | +Amit Blay <quic_ablay@quicinc.com> <ablay@codeaurora.org> | |
| 47 | +Amit Nischal <quic_anischal@quicinc.com> <anischal@codeaurora.org> | |
| 42 | 48 | Andi Kleen <ak@linux.intel.com> <ak@suse.de> |
| 43 | 49 | Andi Shyti <andi@etezian.org> <andi.shyti@samsung.com> |
| 44 | 50 | Andreas Herrmann <aherrman@de.ibm.com> |
| @@ -54,6 +60,8 @@ Andrey Ryabinin <ryabinin.a.a@gmail.com> <aryabinin@virtuozzo.com> · 9 unmodified lines | ||
| 54 | 60 | Andrzej Hajda <andrzej.hajda@intel.com> <a.hajda@samsung.com> |
| 55 | 61 | André Almeida <andrealmeid@igalia.com> <andrealmeid@collabora.com> |
| 56 | 62 | Andy Adamson <andros@citi.umich.edu> |
| 63 | +Anilkumar Kolli <quic_akolli@quicinc.com> <akolli@codeaurora.org> | |
| 64 | +Anirudh Ghayal <quic_aghayal@quicinc.com> <aghayal@codeaurora.org> | |
| 57 | 65 | Antoine Tenart <atenart@kernel.org> <antoine.tenart@bootlin.com> |
| 58 | 66 | Antoine Tenart <atenart@kernel.org> <antoine.tenart@free-electrons.com> |
| 59 | 67 | Antonio Ospite <ao2@ao2.it> <ao2@amarulasolutions.com> |
| @@ -62,9 +70,17 @@ Archit Taneja <archit@ti.com> · 2 unmodified lines | ||
| 62 | 70 | Ard Biesheuvel <ardb@kernel.org> <ard.biesheuvel@linaro.org> |
| 63 | 71 | Arnaud Patard <arnaud.patard@rtp-net.org> |
| 64 | 72 | Arnd Bergmann <arnd@arndb.de> |
| 73 | +Arun Kumar Neelakantam <quic_aneela@quicinc.com> <aneela@codeaurora.org> | |
| 74 | +Ashok Raj Nagarajan <quic_arnagara@quicinc.com> <arnagara@codeaurora.org> | |
| 75 | +Ashwin Chaugule <quic_ashwinc@quicinc.com> <ashwinc@codeaurora.org> | |
| 76 | +Asutosh Das <quic_asutoshd@quicinc.com> <asutoshd@codeaurora.org> | |
| 65 | 77 | Atish Patra <atishp@atishpatra.org> <atish.patra@wdc.com> |
| 78 | +Avaneesh Kumar Dwivedi <quic_akdwived@quicinc.com> <akdwived@codeaurora.org> | |
| 66 | 79 | Axel Dyks <xl@xlsigned.net> |
| 67 | 80 | Axel Lin <axel.lin@gmail.com> |
| 81 | +Balakrishna Godavarthi <quic_bgodavar@quicinc.com> <bgodavar@codeaurora.org> | |
| 82 | +Banajit Goswami <quic_bgoswami@quicinc.com> <bgoswami@codeaurora.org> | |
| 83 | +Baochen Qiang <quic_bqiang@quicinc.com> <bqiang@codeaurora.org> | |
| 68 | 84 | Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@linaro.org> |
| 69 | 85 | Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@spreadtrum.com> |
| 70 | 86 | Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@unisoc.com> |
| @@ -93,12 +109,15 @@ Brian Avery <b.avery@hp.com> · 22 unmodified lines | ||
| 93 | 109 | Brian King <brking@us.ibm.com> |
| 94 | 110 | Brian Silverman <bsilver16384@gmail.com> <brian.silverman@bluerivertech.com> |
| 95 | 111 | Cai Huoqing <cai.huoqing@linux.dev> <caihuoqing@baidu.com> |
| 112 | +Can Guo <quic_cang@quicinc.com> <cang@codeaurora.org> | |
| 113 | +Carl Huang <quic_cjhuang@quicinc.com> <cjhuang@codeaurora.org> | |
| 96 | 114 | Changbin Du <changbin.du@intel.com> <changbin.du@gmail.com> |
| 97 | 115 | Changbin Du <changbin.du@intel.com> <changbin.du@intel.com> |
| 98 | 116 | Chao Yu <chao@kernel.org> <chao2.yu@samsung.com> |
| 99 | 117 | Chao Yu <chao@kernel.org> <yuchao0@huawei.com> |
| 100 | 118 | Chris Chiu <chris.chiu@canonical.com> <chiu@endlessm.com> |
| 101 | 119 | Chris Chiu <chris.chiu@canonical.com> <chiu@endlessos.org> |
| 120 | +Chris Lew <quic_clew@quicinc.com> <clew@codeaurora.org> | |
| 102 | 121 | Christian Borntraeger <borntraeger@linux.ibm.com> <borntraeger@de.ibm.com> |
| 103 | 122 | Christian Borntraeger <borntraeger@linux.ibm.com> <cborntra@de.ibm.com> |
| 104 | 123 | Christian Borntraeger <borntraeger@linux.ibm.com> <borntrae@de.ibm.com> |
| @@ -119,7 +138,10 @@ Daniel Borkmann <daniel@iogearbox.net> <dborkmann@redhat.com> · 14 unmodified lines | ||
| 119 | 138 | Daniel Borkmann <daniel@iogearbox.net> <dborkman@redhat.com> |
| 120 | 139 | Daniel Borkmann <daniel@iogearbox.net> <dxchgb@gmail.com> |
| 121 | 140 | David Brownell <david-b@pacbell.net> |
| 141 | +David Collins <quic_collinsd@quicinc.com> <collinsd@codeaurora.org> | |
| 122 | 142 | David Woodhouse <dwmw2@shinybook.infradead.org> |
| 143 | +Dedy Lansky <quic_dlansky@quicinc.com> <dlansky@codeaurora.org> | |
| 144 | +Deepak Kumar Singh <quic_deesin@quicinc.com> <deesin@codeaurora.org> | |
| 123 | 145 | Dengcheng Zhu <dzhu@wavecomp.com> <dczhu@mips.com> |
| 124 | 146 | Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@gmail.com> |
| 125 | 147 | Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@imgtec.com> |
| @@ -136,6 +158,7 @@ Dmitry Safonov <0x7f454c46@gmail.com> <dsafonov@virtuozzo.com> · 10 unmodified lines | ||
| 136 | 158 | Domen Puncer <domen@coderock.org> |
| 137 | 159 | Douglas Gilbert <dougg@torque.net> |
| 138 | 160 | Ed L. Cashin <ecashin@coraid.com> |
| 161 | +Elliot Berman <quic_eberman@quicinc.com> <eberman@codeaurora.org> | |
| 139 | 162 | Enric Balletbo i Serra <eballetbo@kernel.org> <enric.balletbo@collabora.com> |
| 140 | 163 | Enric Balletbo i Serra <eballetbo@kernel.org> <eballetbo@iseebcn.com> |
| 141 | 164 | Erik Kaneda <erik.kaneda@intel.com> <erik.schmauss@intel.com> |
| @@ -148,6 +171,7 @@ Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@collabora.com> · 6 unmodified lines | ||
| 148 | 171 | Felipe W Damasio <felipewd@terra.com.br> |
| 149 | 172 | Felix Kuhling <fxkuehl@gmx.de> |
| 150 | 173 | Felix Moeller <felix@derklecks.de> |
| 174 | +Fenglin Wu <quic_fenglinw@quicinc.com> <fenglinw@codeaurora.org> | |
| 151 | 175 | Filipe Lautert <filipe@icewall.org> |
| 152 | 176 | Finn Thain <fthain@linux-m68k.org> <fthain@telegraphics.com.au> |
| 153 | 177 | Franck Bui-Huu <vagabon.xyz@gmail.com> |
| @@ -171,8 +195,11 @@ Greg Kurz <groug@kaod.org> <gkurz@linux.vnet.ibm.com> · 17 unmodified lines | ||
| 171 | 195 | Gregory CLEMENT <gregory.clement@bootlin.com> <gregory.clement@free-electrons.com> |
| 172 | 196 | Guilherme G. Piccoli <kernel@gpiccoli.net> <gpiccoli@linux.vnet.ibm.com> |
| 173 | 197 | Guilherme G. Piccoli <kernel@gpiccoli.net> <gpiccoli@canonical.com> |
| 198 | +Gokul Sriram Palanisamy <quic_gokulsri@quicinc.com> <gokulsri@codeaurora.org> | |
| 199 | +Govindaraj Saminathan <quic_gsamin@quicinc.com> <gsamin@codeaurora.org> | |
| 174 | 200 | Guo Ren <guoren@kernel.org> <guoren@linux.alibaba.com> |
| 175 | 201 | Guo Ren <guoren@kernel.org> <ren_guo@c-sky.com> |
| 202 | +Guru Das Srinagesh <quic_gurus@quicinc.com> <gurus@codeaurora.org> | |
| 176 | 203 | Gustavo Padovan <gustavo@las.ic.unicamp.br> |
| 177 | 204 | Gustavo Padovan <padovan@profusion.mobi> |
| 178 | 205 | Hanjun Guo <guohanjun@huawei.com> <hanjun.guo@linaro.org> |
| @@ -190,6 +217,7 @@ Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn> · 11 unmodified lines | ||
| 190 | 217 | J. Bruce Fields <bfields@fieldses.org> <bfields@redhat.com> |
| 191 | 218 | J. Bruce Fields <bfields@fieldses.org> <bfields@citi.umich.edu> |
| 192 | 219 | Jacob Shin <Jacob.Shin@amd.com> |
| 220 | +Jack Pham <quic_jackp@quicinc.com> <jackp@codeaurora.org> | |
| 193 | 221 | Jaegeuk Kim <jaegeuk@kernel.org> <jaegeuk@google.com> |
| 194 | 222 | Jaegeuk Kim <jaegeuk@kernel.org> <jaegeuk.kim@samsung.com> |
| 195 | 223 | Jaegeuk Kim <jaegeuk@kernel.org> <jaegeuk@motorola.com> |
| @@ -217,10 +245,12 @@ Jayachandran C <c.jayachandran@gmail.com> <jchandra@digeo.com> · 21 unmodified lines | ||
| 217 | 245 | Jayachandran C <c.jayachandran@gmail.com> <jnair@caviumnetworks.com> |
| 218 | 246 | <jean-philippe@linaro.org> <jean-philippe.brucker@arm.com> |
| 219 | 247 | Jean Tourrilhes <jt@hpl.hp.com> |
| 248 | +Jeevan Shriram <quic_jshriram@quicinc.com> <jshriram@codeaurora.org> | |
| 220 | 249 | Jeff Garzik <jgarzik@pretzel.yyz.us> |
| 221 | 250 | Jeff Layton <jlayton@kernel.org> <jlayton@poochiereds.net> |
| 222 | 251 | Jeff Layton <jlayton@kernel.org> <jlayton@primarydata.com> |
| 223 | 252 | Jeff Layton <jlayton@kernel.org> <jlayton@redhat.com> |
| 253 | +Jeffrey Hugo <quic_jhugo@quicinc.com> <jhugo@codeaurora.org> | |
| 224 | 254 | Jens Axboe <axboe@kernel.dk> <axboe@suse.de> |
| 225 | 255 | Jens Axboe <axboe@kernel.dk> <jens.axboe@oracle.com> |
| 226 | 256 | Jens Axboe <axboe@kernel.dk> <axboe@fb.com> |
| @@ -228,6 +258,7 @@ Jens Axboe <axboe@kernel.dk> <axboe@meta.com> · 1 unmodified line | ||
| 228 | 258 | Jens Osterkamp <Jens.Osterkamp@de.ibm.com> |
| 229 | 259 | Jernej Skrabec <jernej.skrabec@gmail.com> <jernej.skrabec@siol.net> |
| 230 | 260 | Jessica Zhang <quic_jesszhan@quicinc.com> <jesszhan@codeaurora.org> |
| 261 | +Jilai Wang <quic_jilaiw@quicinc.com> <jilaiw@codeaurora.org> | |
| 231 | 262 | Jiri Pirko <jiri@resnulli.us> <jiri@nvidia.com> |
| 232 | 263 | Jiri Pirko <jiri@resnulli.us> <jiri@mellanox.com> |
| 233 | 264 | Jiri Pirko <jiri@resnulli.us> <jpirko@redhat.com> |
| @@ -238,6 +269,7 @@ Jiri Slaby <jirislaby@kernel.org> <jslaby@suse.cz> · 4 unmodified lines | ||
| 238 | 269 | Jiri Slaby <jirislaby@kernel.org> <xslaby@fi.muni.cz> |
| 239 | 270 | Jisheng Zhang <jszhang@kernel.org> <jszhang@marvell.com> |
| 240 | 271 | Jisheng Zhang <jszhang@kernel.org> <Jisheng.Zhang@synaptics.com> |
| 272 | +Jishnu Prakash <quic_jprakash@quicinc.com> <jprakash@codeaurora.org> | |
| 241 | 273 | Johan Hovold <johan@kernel.org> <jhovold@gmail.com> |
| 242 | 274 | Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com> |
| 243 | 275 | John Crispin <john@phrozen.org> <blogic@openwrt.org> |
| @@ -256,6 +288,7 @@ Jordan Crouse <jordan@cosmicpenguin.net> <jcrouse@codeaurora.org> · 12 unmodified lines | ||
| 256 | 288 | <josh@joshtriplett.org> <josht@vnet.ibm.com> |
| 257 | 289 | Josh Poimboeuf <jpoimboe@kernel.org> <jpoimboe@redhat.com> |
| 258 | 290 | Josh Poimboeuf <jpoimboe@kernel.org> <jpoimboe@us.ibm.com> |
| 291 | +Jouni Malinen <quic_jouni@quicinc.com> <jouni@codeaurora.org> | |
| 259 | 292 | Juha Yrjola <at solidboot.com> |
| 260 | 293 | Juha Yrjola <juha.yrjola@nokia.com> |
| 261 | 294 | Juha Yrjola <juha.yrjola@solidboot.com> |
| @@ -263,6 +296,8 @@ Julien Thierry <julien.thierry.kdev@gmail.com> <julien.thierry@arm.com> · 1 unmodified line | ||
| 263 | 296 | Iskren Chernev <me@iskren.info> <iskren.chernev@gmail.com> |
| 264 | 297 | Kalle Valo <kvalo@kernel.org> <kvalo@codeaurora.org> |
| 265 | 298 | Kalyan Thota <quic_kalyant@quicinc.com> <kalyan_t@codeaurora.org> |
| 299 | +Karthikeyan Periyasamy <quic_periyasa@quicinc.com> <periyasa@codeaurora.org> | |
| 300 | +Kathiravan T <quic_kathirav@quicinc.com> <kathirav@codeaurora.org> | |
| 266 | 301 | Kay Sievers <kay.sievers@vrfy.org> |
| 267 | 302 | Kees Cook <keescook@chromium.org> <kees.cook@canonical.com> |
| 268 | 303 | Kees Cook <keescook@chromium.org> <keescook@google.com> |
| @@ -271,6 +306,8 @@ Kees Cook <keescook@chromium.org> <kees@ubuntu.com> · 2 unmodified lines | ||
| 271 | 306 | Keith Busch <kbusch@kernel.org> <keith.busch@intel.com> |
| 272 | 307 | Keith Busch <kbusch@kernel.org> <keith.busch@linux.intel.com> |
| 273 | 308 | Kenneth W Chen <kenneth.w.chen@intel.com> |
| 309 | +Kenneth Westfield <quic_kwestfie@quicinc.com> <kwestfie@codeaurora.org> | |
| 310 | +Kiran Gunda <quic_kgunda@quicinc.com> <kgunda@codeaurora.org> | |
| 274 | 311 | Kirill Tkhai <tkhai@ya.ru> <ktkhai@virtuozzo.com> |
| 275 | 312 | Konstantin Khlebnikov <koct9i@gmail.com> <khlebnikov@yandex-team.ru> |
| 276 | 313 | Konstantin Khlebnikov <koct9i@gmail.com> <k.khlebnikov@samsung.com> |
| @@ -279,6 +316,7 @@ Krishna Manikandan <quic_mkrishn@quicinc.com> <mkrishn@codeaurora.org> · 2 unmodified lines | ||
| 279 | 316 | Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski.k@gmail.com> |
| 280 | 317 | Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski@samsung.com> |
| 281 | 318 | Krzysztof Kozlowski <krzk@kernel.org> <krzysztof.kozlowski@canonical.com> |
| 319 | +Kshitiz Godara <quic_kgodara@quicinc.com> <kgodara@codeaurora.org> | |
| 282 | 320 | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| 283 | 321 | Kuogee Hsieh <quic_khsieh@quicinc.com> <khsieh@codeaurora.org> |
| 284 | 322 | Lee Jones <lee@kernel.org> <joneslee@google.com> |
| @@ -292,19 +330,27 @@ Leonid I Ananiev <leonid.i.ananiev@intel.com> · 7 unmodified lines | ||
| 292 | 330 | Leon Romanovsky <leon@kernel.org> <leon@leon.nu> |
| 293 | 331 | Leon Romanovsky <leon@kernel.org> <leonro@mellanox.com> |
| 294 | 332 | Leon Romanovsky <leon@kernel.org> <leonro@nvidia.com> |
| 333 | +Liam Mark <quic_lmark@quicinc.com> <lmark@codeaurora.org> | |
| 295 | 334 | Linas Vepstas <linas@austin.ibm.com> |
| 296 | 335 | Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@ascom.ch> |
| 297 | 336 | Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@web.de> |
| 298 | 337 | <linux-hardening@vger.kernel.org> <kernel-hardening@lists.openwall.com> |
| 299 | 338 | Li Yang <leoyang.li@nxp.com> <leoli@freescale.com> |
| 300 | 339 | Li Yang <leoyang.li@nxp.com> <leo@zh-kernel.org> |
| 340 | +Lior David <quic_liord@quicinc.com> <liord@codeaurora.org> | |
| 301 | 341 | Lorenzo Pieralisi <lpieralisi@kernel.org> <lorenzo.pieralisi@arm.com> |
| 302 | 342 | Luca Ceresoli <luca.ceresoli@bootlin.com> <luca@lucaceresoli.net> |
| 303 | 343 | Lukasz Luba <lukasz.luba@arm.com> <l.luba@partner.samsung.com> |
| 344 | +Luo Jie <quic_luoj@quicinc.com> <luoj@codeaurora.org> | |
| 304 | 345 | Maciej W. Rozycki <macro@mips.com> <macro@imgtec.com> |
| 305 | 346 | Maciej W. Rozycki <macro@orcam.me.uk> <macro@linux-mips.org> |
| 347 | +Maharaja Kennadyrajan <quic_mkenna@quicinc.com> <mkenna@codeaurora.org> | |
| 348 | +Maheshwar Ajja <quic_majja@quicinc.com> <majja@codeaurora.org> | |
| 349 | +Malathi Gottam <quic_mgottam@quicinc.com> <mgottam@codeaurora.org> | |
| 350 | +Manikanta Pubbisetty <quic_mpubbise@quicinc.com> <mpubbise@codeaurora.org> | |
| 306 | 351 | Manivannan Sadhasivam <mani@kernel.org> <manivannanece23@gmail.com> |
| 307 | 352 | Manivannan Sadhasivam <mani@kernel.org> <manivannan.sadhasivam@linaro.org> |
| 353 | +Manoj Basapathi <quic_manojbm@quicinc.com> <manojbm@codeaurora.org> | |
| 308 | 354 | Marcin Nowakowski <marcin.nowakowski@mips.com> <marcin.nowakowski@imgtec.com> |
| 309 | 355 | Marc Zyngier <maz@kernel.org> <marc.zyngier@arm.com> |
| 310 | 356 | Marek Behún <kabel@kernel.org> <marek.behun@nic.cz> |
| @@ -334,6 +380,7 @@ Matt Ranostay <matt.ranostay@konsulko.com> <matt@ranostay.consulting> · 23 unmodified lines | ||
| 334 | 380 | Matt Ranostay <mranostay@gmail.com> Matthew Ranostay <mranostay@embeddedalley.com> |
| 335 | 381 | Matt Ranostay <mranostay@gmail.com> <matt.ranostay@intel.com> |
| 336 | 382 | Matt Redfearn <matt.redfearn@mips.com> <matt.redfearn@imgtec.com> |
| 383 | +Maulik Shah <quic_mkshah@quicinc.com> <mkshah@codeaurora.org> | |
| 337 | 384 | Mauro Carvalho Chehab <mchehab@kernel.org> <maurochehab@gmail.com> |
| 338 | 385 | Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@brturbo.com.br> |
| 339 | 386 | Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@infradead.org> |
| @@ -346,7 +393,10 @@ Maxim Mikityanskiy <maxtram95@gmail.com> <maximmi@nvidia.com> · 6 unmodified lines | ||
| 346 | 393 | Maxime Ripard <mripard@kernel.org> <maxime@cerno.tech> |
| 347 | 394 | Maxime Ripard <mripard@kernel.org> <maxime.ripard@bootlin.com> |
| 348 | 395 | Maxime Ripard <mripard@kernel.org> <maxime.ripard@free-electrons.com> |
| 396 | +Maya Erez <quic_merez@quicinc.com> <merez@codeaurora.org> | |
| 349 | 397 | Mayuresh Janorkar <mayur@ti.com> |
| 398 | +Md Sadre Alam <quic_mdalam@quicinc.com> <mdalam@codeaurora.org> | |
| 399 | +Miaoqing Pan <quic_miaoqing@quicinc.com> <miaoqing@codeaurora.org> | |
| 350 | 400 | Michael Buesch <m@bues.ch> |
| 351 | 401 | Michal Simek <michal.simek@amd.com> <michal.simek@xilinx.com> |
| 352 | 402 | Michel Dänzer <michel@tungstengraphics.com> |
| @@ -357,6 +407,7 @@ Miguel Ojeda <ojeda@kernel.org> <miguel.ojeda.sandonis@gmail.com> · 4 unmodified lines | ||
| 357 | 407 | Mike Rapoport <rppt@kernel.org> <mike@compulab.co.il> |
| 358 | 408 | Mike Rapoport <rppt@kernel.org> <mike.rapoport@gmail.com> |
| 359 | 409 | Mike Rapoport <rppt@kernel.org> <rppt@linux.ibm.com> |
| 410 | +Mike Tipton <quic_mdtipton@quicinc.com> <mdtipton@codeaurora.org> | |
| 360 | 411 | Miodrag Dinic <miodrag.dinic@mips.com> <miodrag.dinic@imgtec.com> |
| 361 | 412 | Miquel Raynal <miquel.raynal@bootlin.com> <miquel.raynal@free-electrons.com> |
| 362 | 413 | Mitesh shah <mshah@teja.com> |
| @@ -365,9 +416,13 @@ Morten Welinder <terra@gnome.org> · 2 unmodified lines | ||
| 365 | 416 | Morten Welinder <welinder@anemone.rentec.com> |
| 366 | 417 | Morten Welinder <welinder@darter.rentec.com> |
| 367 | 418 | Morten Welinder <welinder@troll.com> |
| 419 | +Mukesh Ojha <quic_mojha@quicinc.com> <mojha@codeaurora.org> | |
| 420 | +Muna Sinada <quic_msinada@quicinc.com> <msinada@codeaurora.org> | |
| 421 | +Murali Nalajala <quic_mnalajal@quicinc.com> <mnalajal@codeaurora.org> | |
| 368 | 422 | Mythri P K <mythripk@ti.com> |
| 369 | 423 | Nadia Yvette Chambers <nyc@holomorphy.com> William Lee Irwin III <wli@holomorphy.com> |
| 370 | 424 | Nathan Chancellor <nathan@kernel.org> <natechancellor@gmail.com> |
| 425 | +Neeraj Upadhyay <quic_neeraju@quicinc.com> <neeraju@codeaurora.org> | |
| 371 | 426 | Neil Armstrong <neil.armstrong@linaro.org> <narmstrong@baylibre.com> |
| 372 | 427 | Nguyen Anh Quynh <aquynh@gmail.com> |
| 373 | 428 | Nicholas Piggin <npiggin@gmail.com> <npiggen@suse.de> |
| @@ -386,6 +441,7 @@ Nikolay Aleksandrov <razor@blackwall.org> <nikolay@redhat.com> · 12 unmodified lines | ||
| 386 | 441 | Nikolay Aleksandrov <razor@blackwall.org> <nikolay@cumulusnetworks.com> |
| 387 | 442 | Nikolay Aleksandrov <razor@blackwall.org> <nikolay@nvidia.com> |
| 388 | 443 | Nikolay Aleksandrov <razor@blackwall.org> <nikolay@isovalent.com> |
| 444 | +Odelu Kukatla <quic_okukatla@quicinc.com> <okukatla@codeaurora.org> | |
| 389 | 445 | Oleksandr Natalenko <oleksandr@natalenko.name> <oleksandr@redhat.com> |
| 390 | 446 | Oleksij Rempel <linux@rempel-privat.de> <bug-track@fisher-privat.net> |
| 391 | 447 | Oleksij Rempel <linux@rempel-privat.de> <external.Oleksij.Rempel@de.bosch.com> |
| @@ -393,6 +449,7 @@ Oleksij Rempel <linux@rempel-privat.de> <fixed-term.Oleksij.Rempel@de.bosch.com> · 1 unmodified line | ||
| 393 | 449 | Oleksij Rempel <linux@rempel-privat.de> <o.rempel@pengutronix.de> |
| 394 | 450 | Oleksij Rempel <linux@rempel-privat.de> <ore@pengutronix.de> |
| 395 | 451 | Oliver Upton <oliver.upton@linux.dev> <oupton@google.com> |
| 452 | +Oza Pawandeep <quic_poza@quicinc.com> <poza@codeaurora.org> | |
| 396 | 453 | Pali Rohár <pali@kernel.org> <pali.rohar@gmail.com> |
| 397 | 454 | Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> |
| 398 | 455 | Patrick Mochel <mochel@digitalimplant.org> |
| @@ -404,11 +461,14 @@ Paul E. McKenney <paulmck@kernel.org> <paulmck@linux.vnet.ibm.com> · 5 unmodified lines | ||
| 404 | 461 | Paul E. McKenney <paulmck@kernel.org> <paulmck@us.ibm.com> |
| 405 | 462 | Paul Mackerras <paulus@ozlabs.org> <paulus@samba.org> |
| 406 | 463 | Paul Mackerras <paulus@ozlabs.org> <paulus@au1.ibm.com> |
| 464 | +Pavankumar Kondeti <quic_pkondeti@quicinc.com> <pkondeti@codeaurora.org> | |
| 407 | 465 | Peter A Jonsson <pj@ludd.ltu.se> |
| 408 | 466 | Peter Oruba <peter.oruba@amd.com> |
| 409 | 467 | Peter Oruba <peter@oruba.de> |
| 410 | 468 | Pratyush Anand <pratyush.anand@gmail.com> <pratyush.anand@st.com> |
| 411 | 469 | Praveen BP <praveenbp@ti.com> |
| 470 | +Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com> <pradeepc@codeaurora.org> | |
| 471 | +Prasad Sodagudi <quic_psodagud@quicinc.com> <psodagud@codeaurora.org> | |
| 412 | 472 | Punit Agrawal <punitagrawal@gmail.com> <punit.agrawal@arm.com> |
| 413 | 473 | Qais Yousef <qyousef@layalina.io> <qais.yousef@imgtec.com> |
| 414 | 474 | Qais Yousef <qyousef@layalina.io> <qais.yousef@arm.com> |
| @@ -417,10 +477,16 @@ Quentin Perret <qperret@qperret.net> <quentin.perret@arm.com> · 2 unmodified lines | ||
| 417 | 477 | Rafael J. Wysocki <rjw@rjwysocki.net> <rjw@sisk.pl> |
| 418 | 478 | Rajeev Nandan <quic_rajeevny@quicinc.com> <rajeevny@codeaurora.org> |
| 419 | 479 | Rajendra Nayak <quic_rjendra@quicinc.com> <rnayak@codeaurora.org> |
| 480 | +Rajeshwari Ravindra Kamble <quic_rkambl@quicinc.com> <rkambl@codeaurora.org> | |
| 481 | +Raju P.L.S.S.S.N <quic_rplsssn@quicinc.com> <rplsssn@codeaurora.org> | |
| 420 | 482 | Rajesh Shah <rajesh.shah@intel.com> |
| 483 | +Rakesh Pillai <quic_pillair@quicinc.com> <pillair@codeaurora.org> | |
| 421 | 484 | Ralf Baechle <ralf@linux-mips.org> |
| 422 | 485 | Ralf Wildenhues <Ralf.Wildenhues@gmx.de> |
| 486 | +Ram Chandra Jangir <quic_rjangir@quicinc.com> <rjangir@codeaurora.org> | |
| 423 | 487 | Randy Dunlap <rdunlap@infradead.org> <rdunlap@xenotime.net> |
| 488 | +Ravi Kumar Bokka <quic_rbokka@quicinc.com> <rbokka@codeaurora.org> | |
| 489 | +Ravi Kumar Siddojigari <quic_rsiddoji@quicinc.com> <rsiddoji@codeaurora.org> | |
| 424 | 490 | Rémi Denis-Courmont <rdenis@simphalempin.com> |
| 425 | 491 | Ricardo Ribalda <ribalda@kernel.org> <ricardo@ribalda.com> |
| 426 | 492 | Ricardo Ribalda <ribalda@kernel.org> Ricardo Ribalda Delgado <ribalda@kernel.org> |
| @@ -429,6 +495,7 @@ Richard Leitner <richard.leitner@linux.dev> <dev@g0hl1n.net> · 2 unmodified lines | ||
| 429 | 495 | Richard Leitner <richard.leitner@linux.dev> <me@g0hl1n.net> |
| 430 | 496 | Richard Leitner <richard.leitner@linux.dev> <richard.leitner@skidata.com> |
| 431 | 497 | Robert Foss <rfoss@kernel.org> <robert.foss@linaro.org> |
| 498 | +Rocky Liao <quic_rjliao@quicinc.com> <rjliao@codeaurora.org> | |
| 432 | 499 | Roman Gushchin <roman.gushchin@linux.dev> <guro@fb.com> |
| 433 | 500 | Roman Gushchin <roman.gushchin@linux.dev> <guroan@gmail.com> |
| 434 | 501 | Roman Gushchin <roman.gushchin@linux.dev> <klamm@yandex-team.ru> |
| @@ -446,24 +513,35 @@ Santosh Shilimkar <santosh.shilimkar@oracle.org> · 11 unmodified lines | ||
| 446 | 513 | Santosh Shilimkar <ssantosh@kernel.org> |
| 447 | 514 | Sarangdhar Joshi <spjoshi@codeaurora.org> |
| 448 | 515 | Sascha Hauer <s.hauer@pengutronix.de> |
| 516 | +Sahitya Tummala <quic_stummala@quicinc.com> <stummala@codeaurora.org> | |
| 517 | +Sathishkumar Muruganandam <quic_murugana@quicinc.com> <murugana@codeaurora.org> | |
| 449 | 518 | Satya Priya <quic_c_skakit@quicinc.com> <skakit@codeaurora.org> |
| 450 | 519 | S.Çağlar Onur <caglar@pardus.org.tr> |
| 520 | +Sayali Lokhande <quic_sayalil@quicinc.com> <sayalil@codeaurora.org> | |
| 451 | 521 | Sean Christopherson <seanjc@google.com> <sean.j.christopherson@intel.com> |
| 452 | 522 | Sean Nyekjaer <sean@geanix.com> <sean.nyekjaer@prevas.dk> |
| 523 | +Sean Tranchetti <quic_stranche@quicinc.com> <stranche@codeaurora.org> | |
| 453 | 524 | Sebastian Reichel <sre@kernel.org> <sebastian.reichel@collabora.co.uk> |
| 454 | 525 | Sebastian Reichel <sre@kernel.org> <sre@debian.org> |
| 455 | 526 | Sedat Dilek <sedat.dilek@gmail.com> <sedat.dilek@credativ.de> |
| 527 | +Senthilkumar N L <quic_snlakshm@quicinc.com> <snlakshm@codeaurora.org> | |
| 456 | 528 | Seth Forshee <sforshee@kernel.org> <seth.forshee@canonical.com> |
| 457 | 529 | Shannon Nelson <shannon.nelson@amd.com> <snelson@pensando.io> |
| 458 | 530 | Shannon Nelson <shannon.nelson@amd.com> <shannon.nelson@intel.com> |
| 459 | 531 | Shannon Nelson <shannon.nelson@amd.com> <shannon.nelson@oracle.com> |
| 532 | +Sharath Chandra Vurukala <quic_sharathv@quicinc.com> <sharathv@codeaurora.org> | |
| 460 | 533 | Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com> |
| 461 | 534 | Shuah Khan <shuah@kernel.org> <shuahkhan@gmail.com> |
| 462 | 535 | Shuah Khan <shuah@kernel.org> <shuah.khan@hp.com> |
| 463 | 536 | Shuah Khan <shuah@kernel.org> <shuahkh@osg.samsung.com> |
| 464 | 537 | Shuah Khan <shuah@kernel.org> <shuah.kh@samsung.com> |
| 538 | +Sibi Sankar <quic_sibis@quicinc.com> <sibis@codeaurora.org> | |
| 539 | +Sid Manning <quic_sidneym@quicinc.com> <sidneym@codeaurora.org> | |
| 465 | 540 | Simon Arlott <simon@octiron.net> <simon@fire.lp0.eu> |
| 466 | 541 | Simon Kelley <simon@thekelleys.org.uk> |
| 542 | +Sricharan Ramabadhran <quic_srichara@quicinc.com> <sricharan@codeaurora.org> | |
| 543 | +Srinivas Ramana <quic_sramana@quicinc.com> <sramana@codeaurora.org> | |
| 544 | +Sriram R <quic_srirrama@quicinc.com> <srirrama@codeaurora.org> | |
| 467 | 545 | Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr> |
| 468 | 546 | Stephen Hemminger <stephen@networkplumber.org> <shemminger@linux-foundation.org> |
| 469 | 547 | Stephen Hemminger <stephen@networkplumber.org> <shemminger@osdl.org> |
| @@ -471,22 +549,30 @@ Stephen Hemminger <stephen@networkplumber.org> <sthemmin@microsoft.com> · 1 unmodified line | ||
| 471 | 549 | Stephen Hemminger <stephen@networkplumber.org> <sthemmin@vyatta.com> |
| 472 | 550 | Steve Wise <larrystevenwise@gmail.com> <swise@chelsio.com> |
| 473 | 551 | Steve Wise <larrystevenwise@gmail.com> <swise@opengridcomputing.com> |
| 474 | −Subash Abhinov Kasiviswanathan <subashab@codeaurora.org> | |
| 552 | +Subash Abhinov Kasiviswanathan <quic_subashab@quicinc.com> <subashab@codeaurora.org> | |
| 553 | +Subbaraman Narayanamurthy <quic_subbaram@quicinc.com> <subbaram@codeaurora.org> | |
| 475 | 554 | Subhash Jadavani <subhashj@codeaurora.org> |
| 555 | +Sudarshan Rajagopalan <quic_sudaraja@quicinc.com> <sudaraja@codeaurora.org> | |
| 476 | 556 | Sudeep Holla <sudeep.holla@arm.com> Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com> |
| 477 | 557 | Sumit Semwal <sumit.semwal@ti.com> |
| 558 | +Surabhi Vishnoi <quic_svishnoi@quicinc.com> <svishnoi@codeaurora.org> | |
| 478 | 559 | Takashi YOSHII <takashi.yoshii.zj@renesas.com> |
| 560 | +Tamizh Chelvam Raja <quic_tamizhr@quicinc.com> <tamizhr@codeaurora.org> | |
| 561 | +Taniya Das <quic_tdas@quicinc.com> <tdas@codeaurora.org> | |
| 479 | 562 | Tejun Heo <htejun@gmail.com> |
| 480 | 563 | Thomas Graf <tgraf@suug.ch> |
| 481 | 564 | Thomas Körper <socketcan@esd.eu> <thomas.koerper@esd.eu> |
| 482 | 565 | Thomas Pedersen <twp@codeaurora.org> |
| 483 | 566 | Tiezhu Yang <yangtiezhu@loongson.cn> <kernelpatch@126.com> |
| 567 | +Tingwei Zhang <quic_tingwei@quicinc.com> <tingwei@codeaurora.org> | |
| 568 | +Tirupathi Reddy <quic_tirupath@quicinc.com> <tirupath@codeaurora.org> | |
| 484 | 569 | Tobias Klauser <tklauser@distanz.ch> <tobias.klauser@gmail.com> |
| 485 | 570 | Tobias Klauser <tklauser@distanz.ch> <klto@zhaw.ch> |
| 486 | 571 | Tobias Klauser <tklauser@distanz.ch> <tklauser@nuerscht.ch> |
| 487 | 572 | Tobias Klauser <tklauser@distanz.ch> <tklauser@xenon.tklauser.home> |
| 488 | 573 | Todor Tomov <todor.too@gmail.com> <todor.tomov@linaro.org> |
| 489 | 574 | Tony Luck <tony.luck@intel.com> |
| 575 | +Trilok Soni <quic_tsoni@quicinc.com> <tsoni@codeaurora.org> | |
| 490 | 576 | TripleX Chung <xxx.phy@gmail.com> <triplex@zh-kernel.org> |
| 491 | 577 | TripleX Chung <xxx.phy@gmail.com> <zhongyu@18mail.cn> |
| 492 | 578 | Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com> |
| @@ -499,11 +585,17 @@ Uwe Kleine-König <ukleinek@strlen.de> · 6 unmodified lines | ||
| 499 | 585 | Uwe Kleine-König <ukl@pengutronix.de> |
| 500 | 586 | Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com> |
| 501 | 587 | Valdis Kletnieks <Valdis.Kletnieks@vt.edu> |
| 588 | +Vara Reddy <quic_varar@quicinc.com> <varar@codeaurora.org> | |
| 589 | +Varadarajan Narayanan <quic_varada@quicinc.com> <varada@codeaurora.org> | |
| 590 | +Vasanthakumar Thiagarajan <quic_vthiagar@quicinc.com> <vthiagar@codeaurora.org> | |
| 502 | 591 | Vasily Averin <vasily.averin@linux.dev> <vvs@virtuozzo.com> |
| 503 | 592 | Vasily Averin <vasily.averin@linux.dev> <vvs@openvz.org> |
| 504 | 593 | Vasily Averin <vasily.averin@linux.dev> <vvs@parallels.com> |
| 505 | 594 | Vasily Averin <vasily.averin@linux.dev> <vvs@sw.ru> |
| 506 | 595 | Valentin Schneider <vschneid@redhat.com> <valentin.schneider@arm.com> |
| 596 | +Veera Sundaram Sankaran <quic_veeras@quicinc.com> <veeras@codeaurora.org> | |
| 597 | +Veerabhadrarao Badiganti <quic_vbadigan@quicinc.com> <vbadigan@codeaurora.org> | |
| 598 | +Venkateswara Naralasetty <quic_vnaralas@quicinc.com> <vnaralas@codeaurora.org> | |
| 507 | 599 | Vikash Garodia <quic_vgarodia@quicinc.com> <vgarodia@codeaurora.org> |
| 508 | 600 | Vinod Koul <vkoul@kernel.org> <vinod.koul@intel.com> |
| 509 | 601 | Vinod Koul <vkoul@kernel.org> <vinod.koul@linux.intel.com> |
| @@ -513,11 +605,14 @@ Viresh Kumar <vireshk@kernel.org> <viresh.kumar@st.com> · 3 unmodified lines | ||
| 513 | 605 | Viresh Kumar <vireshk@kernel.org> <viresh.linux@gmail.com> |
| 514 | 606 | Viresh Kumar <viresh.kumar@linaro.org> <viresh.kumar@linaro.org> |
| 515 | 607 | Viresh Kumar <viresh.kumar@linaro.org> <viresh.kumar@linaro.com> |
| 608 | +Vivek Aknurwar <quic_viveka@quicinc.com> <viveka@codeaurora.org> | |
| 516 | 609 | Vivien Didelot <vivien.didelot@gmail.com> <vivien.didelot@savoirfairelinux.com> |
| 517 | 610 | Vlad Dogaru <ddvlad@gmail.com> <vlad.dogaru@intel.com> |
| 518 | 611 | Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@parallels.com> |
| 519 | 612 | Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@virtuozzo.com> |
| 520 | 613 | WeiXiong Liao <gmpy.liaowx@gmail.com> <liaoweixiong@allwinnertech.com> |
| 614 | +Wen Gong <quic_wgong@quicinc.com> <wgong@codeaurora.org> | |
| 615 | +Wesley Cheng <quic_wcheng@quicinc.com> <wcheng@codeaurora.org> | |
| 521 | 616 | Will Deacon <will@kernel.org> <will.deacon@arm.com> |
| 522 | 617 | Wolfram Sang <wsa@kernel.org> <w.sang@pengutronix.de> |
| 523 | 618 | Wolfram Sang <wsa@kernel.org> <wsa@the-dreams.de> |
| @@ -82,7 +82,12 @@ Description: · 81 unmodified lines | ||
| 82 | 82 | whether it resides in persistent capacity, volatile capacity, |
| 83 | 83 | or the LSA, is made permanently unavailable by whatever means |
| 84 | 84 | is appropriate for the media type. This functionality requires |
| 85 | − the device to be not be actively decoding any HPA ranges. | |
| 85 | + the device to be disabled, that is, not actively decoding any | |
| 86 | + HPA ranges. This permits avoiding explicit global CPU cache | |
| 87 | + management, relying instead for it to be done when a region | |
| 88 | + transitions between software programmed and hardware committed | |
| 89 | + states. If this file is not present, then there is no hardware | |
| 90 | + support for the operation. | |
| 86 | 91 | |
| 87 | 92 | |
| 88 | 93 | What /sys/bus/cxl/devices/memX/security/erase |
| @@ -92,7 +97,13 @@ Contact: linux-cxl@vger.kernel.org · 3 unmodified lines | ||
| 92 | 97 | Description: |
| 93 | 98 | (WO) Write a boolean 'true' string value to this attribute to |
| 94 | 99 | secure erase user data by changing the media encryption keys for |
| 95 | − all user data areas of the device. | |
| 100 | + all user data areas of the device. This functionality requires | |
| 101 | + the device to be disabled, that is, not actively decoding any | |
| 102 | + HPA ranges. This permits avoiding explicit global CPU cache | |
| 103 | + management, relying instead for it to be done when a region | |
| 104 | + transitions between software programmed and hardware committed | |
| 105 | + states. If this file is not present, then there is no hardware | |
| 106 | + support for the operation. | |
| 96 | 107 | |
| 97 | 108 | |
| 98 | 109 | What: /sys/bus/cxl/devices/memX/firmware/ |
| @@ -513,17 +513,18 @@ Description: information about CPUs heterogeneity. · 512 unmodified lines | ||
| 513 | 513 | cpu_capacity: capacity of cpuX. |
| 514 | 514 | |
| 515 | 515 | What: /sys/devices/system/cpu/vulnerabilities |
| 516 | + /sys/devices/system/cpu/vulnerabilities/gather_data_sampling | |
| 517 | + /sys/devices/system/cpu/vulnerabilities/itlb_multihit | |
| 518 | + /sys/devices/system/cpu/vulnerabilities/l1tf | |
| 519 | + /sys/devices/system/cpu/vulnerabilities/mds | |
| 516 | 520 | /sys/devices/system/cpu/vulnerabilities/meltdown |
| 521 | + /sys/devices/system/cpu/vulnerabilities/mmio_stale_data | |
| 522 | + /sys/devices/system/cpu/vulnerabilities/retbleed | |
| 523 | + /sys/devices/system/cpu/vulnerabilities/spec_store_bypass | |
| 517 | 524 | /sys/devices/system/cpu/vulnerabilities/spectre_v1 |
| 518 | 525 | /sys/devices/system/cpu/vulnerabilities/spectre_v2 |
| 519 | − /sys/devices/system/cpu/vulnerabilities/spec_store_bypass | |
| 520 | − /sys/devices/system/cpu/vulnerabilities/l1tf | |
| 521 | − /sys/devices/system/cpu/vulnerabilities/mds | |
| 522 | 526 | /sys/devices/system/cpu/vulnerabilities/srbds |
| 523 | 527 | /sys/devices/system/cpu/vulnerabilities/tsx_async_abort |
| 524 | − /sys/devices/system/cpu/vulnerabilities/itlb_multihit | |
| 525 | − /sys/devices/system/cpu/vulnerabilities/mmio_stale_data | |
| 526 | − /sys/devices/system/cpu/vulnerabilities/retbleed | |
| 527 | 528 | Date: January 2018 |
| 528 | 529 | Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> |
| 529 | 530 | Description: Information about CPU vulnerabilities |
| @@ -60,3 +60,14 @@ Description: Module taint flags: · 59 unmodified lines | ||
| 60 | 60 | C staging driver module |
| 61 | 61 | E unsigned module |
| 62 | 62 | == ===================== |
| 63 | + | |
| 64 | +What: /sys/module/grant_table/parameters/free_per_iteration | |
| 65 | +Date: July 2023 | |
| 66 | +KernelVersion: 6.5 but backported to all supported stable branches | |
| 67 | +Contact: Xen developer discussion <xen-devel@lists.xenproject.org> | |
| 68 | +Description: Read and write number of grant entries to attempt to free per iteration. | |
| 69 | + | |
| 70 | + Note: Future versions of Xen and Linux may provide a better | |
| 71 | + interface for controlling the rate of deferred grant reclaim | |
| 72 | + or may not need it at all. | |
| 73 | +Users: Qubes OS (https://www.qubes-os.org) | |
| @@ -2,7 +2,7 @@ What: /sys/devices/platform/hidma-*/chid · 1 unmodified line | ||
| 2 | 2 | /sys/devices/platform/QCOM8061:*/chid |
| 3 | 3 | Date: Dec 2015 |
| 4 | 4 | KernelVersion: 4.4 |
| 5 | −Contact: "Sinan Kaya <okaya@codeaurora.org>" | |
| 5 | +Contact: "Sinan Kaya <okaya@kernel.org>" | |
| 6 | 6 | Description: |
| 7 | 7 | Contains the ID of the channel within the HIDMA instance. |
| 8 | 8 | It is used to associate a given HIDMA channel with the |
| @@ -2,7 +2,7 @@ What: /sys/devices/platform/hidma-mgmt*/chanops/chan*/priority · 1 unmodified line | ||
| 2 | 2 | /sys/devices/platform/QCOM8060:*/chanops/chan*/priority |
| 3 | 3 | Date: Nov 2015 |
| 4 | 4 | KernelVersion: 4.4 |
| 5 | −Contact: "Sinan Kaya <okaya@codeaurora.org>" | |
| 5 | +Contact: "Sinan Kaya <okaya@kernel.org>" | |
| 6 | 6 | Description: |
| 7 | 7 | Contains either 0 or 1 and indicates if the DMA channel is a |
| 8 | 8 | low priority (0) or high priority (1) channel. |
| @@ -11,7 +11,7 @@ What: /sys/devices/platform/hidma-mgmt*/chanops/chan*/weight · 2 unmodified lines | ||
| 11 | 11 | /sys/devices/platform/QCOM8060:*/chanops/chan*/weight |
| 12 | 12 | Date: Nov 2015 |
| 13 | 13 | KernelVersion: 4.4 |
| 14 | −Contact: "Sinan Kaya <okaya@codeaurora.org>" | |
| 14 | +Contact: "Sinan Kaya <okaya@kernel.org>" | |
| 15 | 15 | Description: |
| 16 | 16 | Contains 0..15 and indicates the weight of the channel among |
| 17 | 17 | equal priority channels during round robin scheduling. |
| @@ -20,7 +20,7 @@ What: /sys/devices/platform/hidma-mgmt*/chreset_timeout_cycles · 2 unmodified lines | ||
| 20 | 20 | /sys/devices/platform/QCOM8060:*/chreset_timeout_cycles |
| 21 | 21 | Date: Nov 2015 |
| 22 | 22 | KernelVersion: 4.4 |
| 23 | −Contact: "Sinan Kaya <okaya@codeaurora.org>" | |
| 23 | +Contact: "Sinan Kaya <okaya@kernel.org>" | |
| 24 | 24 | Description: |
| 25 | 25 | Contains the platform specific cycle value to wait after a |
| 26 | 26 | reset command is issued. If the value is chosen too short, |
| @@ -32,7 +32,7 @@ What: /sys/devices/platform/hidma-mgmt*/dma_channels · 5 unmodified lines | ||
| 32 | 32 | /sys/devices/platform/QCOM8060:*/dma_channels |
| 33 | 33 | Date: Nov 2015 |
| 34 | 34 | KernelVersion: 4.4 |
| 35 | −Contact: "Sinan Kaya <okaya@codeaurora.org>" | |
| 35 | +Contact: "Sinan Kaya <okaya@kernel.org>" | |
| 36 | 36 | Description: |
| 37 | 37 | Contains the number of dma channels supported by one instance |
| 38 | 38 | of HIDMA hardware. The value may change from chip to chip. |
| @@ -41,7 +41,7 @@ What: /sys/devices/platform/hidma-mgmt*/hw_version_major · 2 unmodified lines | ||
| 41 | 41 | /sys/devices/platform/QCOM8060:*/hw_version_major |
| 42 | 42 | Date: Nov 2015 |
| 43 | 43 | KernelVersion: 4.4 |
| 44 | −Contact: "Sinan Kaya <okaya@codeaurora.org>" | |
| 44 | +Contact: "Sinan Kaya <okaya@kernel.org>" | |
| 45 | 45 | Description: |
| 46 | 46 | Version number major for the hardware. |
| 47 | 47 | |
| @@ -49,7 +49,7 @@ What: /sys/devices/platform/hidma-mgmt*/hw_version_minor · 1 unmodified line | ||
| 49 | 49 | /sys/devices/platform/QCOM8060:*/hw_version_minor |
| 50 | 50 | Date: Nov 2015 |
| 51 | 51 | KernelVersion: 4.4 |
| 52 | −Contact: "Sinan Kaya <okaya@codeaurora.org>" | |
| 52 | +Contact: "Sinan Kaya <okaya@kernel.org>" | |
| 53 | 53 | Description: |
| 54 | 54 | Version number minor for the hardware. |
| 55 | 55 | |
| @@ -57,7 +57,7 @@ What: /sys/devices/platform/hidma-mgmt*/max_rd_xactions · 1 unmodified line | ||
| 57 | 57 | /sys/devices/platform/QCOM8060:*/max_rd_xactions |
| 58 | 58 | Date: Nov 2015 |
| 59 | 59 | KernelVersion: 4.4 |
| 60 | −Contact: "Sinan Kaya <okaya@codeaurora.org>" | |
| 60 | +Contact: "Sinan Kaya <okaya@kernel.org>" | |
| 61 | 61 | Description: |
| 62 | 62 | Contains a value between 0 and 31. Maximum number of |
| 63 | 63 | read transactions that can be issued back to back. |
| @@ -69,7 +69,7 @@ What: /sys/devices/platform/hidma-mgmt*/max_read_request · 5 unmodified lines | ||
| 69 | 69 | /sys/devices/platform/QCOM8060:*/max_read_request |
| 70 | 70 | Date: Nov 2015 |
| 71 | 71 | KernelVersion: 4.4 |
| 72 | −Contact: "Sinan Kaya <okaya@codeaurora.org>" | |
| 72 | +Contact: "Sinan Kaya <okaya@kernel.org>" | |
| 73 | 73 | Description: |
| 74 | 74 | Size of each read request. The value needs to be a power |
| 75 | 75 | of two and can be between 128 and 1024. |
| @@ -78,7 +78,7 @@ What: /sys/devices/platform/hidma-mgmt*/max_wr_xactions · 2 unmodified lines | ||
| 78 | 78 | /sys/devices/platform/QCOM8060:*/max_wr_xactions |
| 79 | 79 | Date: Nov 2015 |
| 80 | 80 | KernelVersion: 4.4 |
| 81 | −Contact: "Sinan Kaya <okaya@codeaurora.org>" | |
| 81 | +Contact: "Sinan Kaya <okaya@kernel.org>" | |
| 82 | 82 | Description: |
| 83 | 83 | Contains a value between 0 and 31. Maximum number of |
| 84 | 84 | write transactions that can be issued back to back. |
| @@ -91,7 +91,7 @@ What: /sys/devices/platform/hidma-mgmt*/max_write_request · 6 unmodified lines | ||
| 91 | 91 | /sys/devices/platform/QCOM8060:*/max_write_request |
| 92 | 92 | Date: Nov 2015 |
| 93 | 93 | KernelVersion: 4.4 |
| 94 | −Contact: "Sinan Kaya <okaya@codeaurora.org>" | |
| 94 | +Contact: "Sinan Kaya <okaya@kernel.org>" | |
| 95 | 95 | Description: |
| 96 | 96 | Size of each write request. The value needs to be a power |
| 97 | 97 | of two and can be between 128 and 1024. |
| @@ -2691,7 +2691,7 @@ · 2690 unmodified lines | ||
| 2691 | 2691 | 45 = /dev/ttyMM1 Marvell MPSC - port 1 (obsolete unused) |
| 2692 | 2692 | 46 = /dev/ttyCPM0 PPC CPM (SCC or SMC) - port 0 |
| 2693 | 2693 | ... |
| 2694 | − 47 = /dev/ttyCPM5 PPC CPM (SCC or SMC) - port 5 | |
| 2694 | + 49 = /dev/ttyCPM5 PPC CPM (SCC or SMC) - port 3 | |
| 2695 | 2695 | 50 = /dev/ttyIOC0 Altix serial card |
| 2696 | 2696 | ... |
| 2697 | 2697 | 81 = /dev/ttyIOC31 Altix serial card |
| @@ -0,0 +1,109 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +GDS - Gather Data Sampling | |
| 4 | +========================== | |
| 5 | + | |
| 6 | +Gather Data Sampling is a hardware vulnerability which allows unprivileged | |
| 7 | +speculative access to data which was previously stored in vector registers. | |
| 8 | + | |
| 9 | +Problem | |
| 10 | +------- | |
| 11 | +When a gather instruction performs loads from memory, different data elements | |
| 12 | +are merged into the destination vector register. However, when a gather | |
| 13 | +instruction that is transiently executed encounters a fault, stale data from | |
| 14 | +architectural or internal vector registers may get transiently forwarded to the | |
| 15 | +destination vector register instead. This will allow a malicious attacker to | |
| 16 | +infer stale data using typical side channel techniques like cache timing | |
| 17 | +attacks. GDS is a purely sampling-based attack. | |
| 18 | + | |
| 19 | +The attacker uses gather instructions to infer the stale vector register data. | |
| 20 | +The victim does not need to do anything special other than use the vector | |
| 21 | +registers. The victim does not need to use gather instructions to be | |
| 22 | +vulnerable. | |
| 23 | + | |
| 24 | +Because the buffers are shared between Hyper-Threads cross Hyper-Thread attacks | |
| 25 | +are possible. | |
| 26 | + | |
| 27 | +Attack scenarios | |
| 28 | +---------------- | |
| 29 | +Without mitigation, GDS can infer stale data across virtually all | |
| 30 | +permission boundaries: | |
| 31 | + | |
| 32 | + Non-enclaves can infer SGX enclave data | |
| 33 | + Userspace can infer kernel data | |
| 34 | + Guests can infer data from hosts | |
| 35 | + Guest can infer guest from other guests | |
| 36 | + Users can infer data from other users | |
| 37 | + | |
| 38 | +Because of this, it is important to ensure that the mitigation stays enabled in | |
| 39 | +lower-privilege contexts like guests and when running outside SGX enclaves. | |
| 40 | + | |
| 41 | +The hardware enforces the mitigation for SGX. Likewise, VMMs should ensure | |
| 42 | +that guests are not allowed to disable the GDS mitigation. If a host erred and | |
| 43 | +allowed this, a guest could theoretically disable GDS mitigation, mount an | |
| 44 | +attack, and re-enable it. | |
| 45 | + | |
| 46 | +Mitigation mechanism | |
| 47 | +-------------------- | |
| 48 | +This issue is mitigated in microcode. The microcode defines the following new | |
| 49 | +bits: | |
| 50 | + | |
| 51 | + ================================ === ============================ | |
| 52 | + IA32_ARCH_CAPABILITIES[GDS_CTRL] R/O Enumerates GDS vulnerability | |
| 53 | + and mitigation support. | |
| 54 | + IA32_ARCH_CAPABILITIES[GDS_NO] R/O Processor is not vulnerable. | |
| 55 | + IA32_MCU_OPT_CTRL[GDS_MITG_DIS] R/W Disables the mitigation | |
| 56 | + 0 by default. | |
| 57 | + IA32_MCU_OPT_CTRL[GDS_MITG_LOCK] R/W Locks GDS_MITG_DIS=0. Writes | |
| 58 | + to GDS_MITG_DIS are ignored | |
| 59 | + Can't be cleared once set. | |
| 60 | + ================================ === ============================ | |
| 61 | + | |
| 62 | +GDS can also be mitigated on systems that don't have updated microcode by | |
| 63 | +disabling AVX. This can be done by setting gather_data_sampling="force" or | |
| 64 | +"clearcpuid=avx" on the kernel command-line. | |
| 65 | + | |
| 66 | +If used, these options will disable AVX use by turning off XSAVE YMM support. | |
| 67 | +However, the processor will still enumerate AVX support. Userspace that | |
| 68 | +does not follow proper AVX enumeration to check both AVX *and* XSAVE YMM | |
| 69 | +support will break. | |
| 70 | + | |
| 71 | +Mitigation control on the kernel command line | |
| 72 | +--------------------------------------------- | |
| 73 | +The mitigation can be disabled by setting "gather_data_sampling=off" or | |
| 74 | +"mitigations=off" on the kernel command line. Not specifying either will default | |
| 75 | +to the mitigation being enabled. Specifying "gather_data_sampling=force" will | |
| 76 | +use the microcode mitigation when available or disable AVX on affected systems | |
| 77 | +where the microcode hasn't been updated to include the mitigation. | |
| 78 | + | |
| 79 | +GDS System Information | |
| 80 | +------------------------ | |
| 81 | +The kernel provides vulnerability status information through sysfs. For | |
| 82 | +GDS this can be accessed by the following sysfs file: | |
| 83 | + | |
| 84 | +/sys/devices/system/cpu/vulnerabilities/gather_data_sampling | |
| 85 | + | |
| 86 | +The possible values contained in this file are: | |
| 87 | + | |
| 88 | + ============================== ============================================= | |
| 89 | + Not affected Processor not vulnerable. | |
| 90 | + Vulnerable Processor vulnerable and mitigation disabled. | |
| 91 | + Vulnerable: No microcode Processor vulnerable and microcode is missing | |
| 92 | + mitigation. | |
| 93 | + Mitigation: AVX disabled, | |
| 94 | + no microcode Processor is vulnerable and microcode is missing | |
| 95 | + mitigation. AVX disabled as mitigation. | |
| 96 | + Mitigation: Microcode Processor is vulnerable and mitigation is in | |
| 97 | + effect. | |
| 98 | + Mitigation: Microcode (locked) Processor is vulnerable and mitigation is in | |
| 99 | + effect and cannot be disabled. | |
| 100 | + Unknown: Dependent on | |
| 101 | + hypervisor status Running on a virtual guest processor that is | |
| 102 | + affected but with no way to know if host | |
| 103 | + processor is mitigated or vulnerable. | |
| 104 | + ============================== ============================================= | |
| 105 | + | |
| 106 | +GDS Default mitigation | |
| 107 | +---------------------- | |
| 108 | +The updated microcode will enable the mitigation by default. The kernel's | |
| 109 | +default action is to leave the mitigation enabled. | |
| @@ -13,9 +13,11 @@ are configurable at compile, boot or run time. · 12 unmodified lines | ||
| 13 | 13 | l1tf |
| 14 | 14 | mds |
| 15 | 15 | tsx_async_abort |
| 16 | − multihit.rst | |
| 17 | − special-register-buffer-data-sampling.rst | |
| 18 | − core-scheduling.rst | |
| 19 | − l1d_flush.rst | |
| 20 | − processor_mmio_stale_data.rst | |
| 21 | − cross-thread-rsb.rst | |
| 16 | + multihit | |
| 17 | + special-register-buffer-data-sampling | |
| 18 | + core-scheduling | |
| 19 | + l1d_flush | |
| 20 | + processor_mmio_stale_data | |
| 21 | + cross-thread-rsb | |
| 22 | + srso | |
| 23 | + gather_data_sampling | |
| @@ -484,11 +484,14 @@ Spectre variant 2 · 483 unmodified lines | ||
| 484 | 484 | |
| 485 | 485 | Systems which support enhanced IBRS (eIBRS) enable IBRS protection once at |
| 486 | 486 | boot, by setting the IBRS bit, and they're automatically protected against |
| 487 | − Spectre v2 variant attacks, including cross-thread branch target injections | |
| 488 | − on SMT systems (STIBP). In other words, eIBRS enables STIBP too. | |
| 487 | + Spectre v2 variant attacks. | |
| 489 | 488 | |
| 490 | − Legacy IBRS systems clear the IBRS bit on exit to userspace and | |
| 491 | − therefore explicitly enable STIBP for that | |
| 489 | + On Intel's enhanced IBRS systems, this includes cross-thread branch target | |
| 490 | + injections on SMT systems (STIBP). In other words, Intel eIBRS enables | |
| 491 | + STIBP, too. | |
| 492 | + | |
| 493 | + AMD Automatic IBRS does not protect userspace, and Legacy IBRS systems clear | |
| 494 | + the IBRS bit on exit to userspace, therefore both explicitly enable STIBP. | |
| 492 | 495 | |
| 493 | 496 | The retpoline mitigation is turned on by default on vulnerable |
| 494 | 497 | CPUs. It can be forced on or off by the administrator |
| @@ -0,0 +1,150 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +Speculative Return Stack Overflow (SRSO) | |
| 4 | +======================================== | |
| 5 | + | |
| 6 | +This is a mitigation for the speculative return stack overflow (SRSO) | |
| 7 | +vulnerability found on AMD processors. The mechanism is by now the well | |
| 8 | +known scenario of poisoning CPU functional units - the Branch Target | |
| 9 | +Buffer (BTB) and Return Address Predictor (RAP) in this case - and then | |
| 10 | +tricking the elevated privilege domain (the kernel) into leaking | |
| 11 | +sensitive data. | |
| 12 | + | |
| 13 | +AMD CPUs predict RET instructions using a Return Address Predictor (aka | |
| 14 | +Return Address Stack/Return Stack Buffer). In some cases, a non-architectural | |
| 15 | +CALL instruction (i.e., an instruction predicted to be a CALL but is | |
| 16 | +not actually a CALL) can create an entry in the RAP which may be used | |
| 17 | +to predict the target of a subsequent RET instruction. | |
| 18 | + | |
| 19 | +The specific circumstances that lead to this varies by microarchitecture | |
| 20 | +but the concern is that an attacker can mis-train the CPU BTB to predict | |
| 21 | +non-architectural CALL instructions in kernel space and use this to | |
| 22 | +control the speculative target of a subsequent kernel RET, potentially | |
| 23 | +leading to information disclosure via a speculative side-channel. | |
| 24 | + | |
| 25 | +The issue is tracked under CVE-2023-20569. | |
| 26 | + | |
| 27 | +Affected processors | |
| 28 | +------------------- | |
| 29 | + | |
| 30 | +AMD Zen, generations 1-4. That is, all families 0x17 and 0x19. Older | |
| 31 | +processors have not been investigated. | |
| 32 | + | |
| 33 | +System information and options | |
| 34 | +------------------------------ | |
| 35 | + | |
| 36 | +First of all, it is required that the latest microcode be loaded for | |
| 37 | +mitigations to be effective. | |
| 38 | + | |
| 39 | +The sysfs file showing SRSO mitigation status is: | |
| 40 | + | |
| 41 | + /sys/devices/system/cpu/vulnerabilities/spec_rstack_overflow | |
| 42 | + | |
| 43 | +The possible values in this file are: | |
| 44 | + | |
| 45 | + * 'Not affected': | |
| 46 | + | |
| 47 | + The processor is not vulnerable | |
| 48 | + | |
| 49 | + * 'Vulnerable: no microcode': | |
| 50 | + | |
| 51 | + The processor is vulnerable, no microcode extending IBPB | |
| 52 | + functionality to address the vulnerability has been applied. | |
| 53 | + | |
| 54 | + * 'Mitigation: microcode': | |
| 55 | + | |
| 56 | + Extended IBPB functionality microcode patch has been applied. It does | |
| 57 | + not address User->Kernel and Guest->Host transitions protection but it | |
| 58 | + does address User->User and VM->VM attack vectors. | |
| 59 | + | |
| 60 | + Note that User->User mitigation is controlled by how the IBPB aspect in | |
| 61 | + the Spectre v2 mitigation is selected: | |
| 62 | + | |
| 63 | + * conditional IBPB: | |
| 64 | + | |
| 65 | + where each process can select whether it needs an IBPB issued | |
| 66 | + around it PR_SPEC_DISABLE/_ENABLE etc, see :doc:`spectre` | |
| 67 | + | |
| 68 | + * strict: | |
| 69 | + | |
| 70 | + i.e., always on - by supplying spectre_v2_user=on on the kernel | |
| 71 | + command line | |
| 72 | + | |
| 73 | + (spec_rstack_overflow=microcode) | |
| 74 | + | |
| 75 | + * 'Mitigation: safe RET': | |
| 76 | + | |
| 77 | + Software-only mitigation. It complements the extended IBPB microcode | |
| 78 | + patch functionality by addressing User->Kernel and Guest->Host | |
| 79 | + transitions protection. | |
| 80 | + | |
| 81 | + Selected by default or by spec_rstack_overflow=safe-ret | |
| 82 | + | |
| 83 | + * 'Mitigation: IBPB': | |
| 84 | + | |
| 85 | + Similar protection as "safe RET" above but employs an IBPB barrier on | |
| 86 | + privilege domain crossings (User->Kernel, Guest->Host). | |
| 87 | + | |
| 88 | + (spec_rstack_overflow=ibpb) | |
| 89 | + | |
| 90 | + * 'Mitigation: IBPB on VMEXIT': | |
| 91 | + | |
| 92 | + Mitigation addressing the cloud provider scenario - the Guest->Host | |
| 93 | + transitions only. | |
| 94 | + | |
| 95 | + (spec_rstack_overflow=ibpb-vmexit) | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | +In order to exploit vulnerability, an attacker needs to: | |
| 100 | + | |
| 101 | + - gain local access on the machine | |
| 102 | + | |
| 103 | + - break kASLR | |
| 104 | + | |
| 105 | + - find gadgets in the running kernel in order to use them in the exploit | |
| 106 | + | |
| 107 | + - potentially create and pin an additional workload on the sibling | |
| 108 | + thread, depending on the microarchitecture (not necessary on fam 0x19) | |
| 109 | + | |
| 110 | + - run the exploit | |
| 111 | + | |
| 112 | +Considering the performance implications of each mitigation type, the | |
| 113 | +default one is 'Mitigation: safe RET' which should take care of most | |
| 114 | +attack vectors, including the local User->Kernel one. | |
| 115 | + | |
| 116 | +As always, the user is advised to keep her/his system up-to-date by | |
| 117 | +applying software updates regularly. | |
| 118 | + | |
| 119 | +The default setting will be reevaluated when needed and especially when | |
| 120 | +new attack vectors appear. | |
| 121 | + | |
| 122 | +As one can surmise, 'Mitigation: safe RET' does come at the cost of some | |
| 123 | +performance depending on the workload. If one trusts her/his userspace | |
| 124 | +and does not want to suffer the performance impact, one can always | |
| 125 | +disable the mitigation with spec_rstack_overflow=off. | |
| 126 | + | |
| 127 | +Similarly, 'Mitigation: IBPB' is another full mitigation type employing | |
| 128 | +an indrect branch prediction barrier after having applied the required | |
| 129 | +microcode patch for one's system. This mitigation comes also at | |
| 130 | +a performance cost. | |
| 131 | + | |
| 132 | +Mitigation: safe RET | |
| 133 | +-------------------- | |
| 134 | + | |
| 135 | +The mitigation works by ensuring all RET instructions speculate to | |
| 136 | +a controlled location, similar to how speculation is controlled in the | |
| 137 | +retpoline sequence. To accomplish this, the __x86_return_thunk forces | |
| 138 | +the CPU to mispredict every function return using a 'safe return' | |
| 139 | +sequence. | |
| 140 | + | |
| 141 | +To ensure the safety of this mitigation, the kernel must ensure that the | |
| 142 | +safe return sequence is itself free from attacker interference. In Zen3 | |
| 143 | +and Zen4, this is accomplished by creating a BTB alias between the | |
| 144 | +untraining function srso_untrain_ret_alias() and the safe return | |
| 145 | +function srso_safe_ret_alias() which results in evicting a potentially | |
| 146 | +poisoned BTB entry and using that safe one for all function returns. | |
| 147 | + | |
| 148 | +In older Zen1 and Zen2, this is accomplished using a reinterpretation | |
| 149 | +technique similar to Retbleed one: srso_untrain_ret() and | |
| 150 | +srso_safe_ret(). | |
| @@ -624,3 +624,9 @@ Used to get the correct ranges: · 623 unmodified lines | ||
| 624 | 624 | * VMALLOC_START ~ VMALLOC_END : vmalloc() / ioremap() space. |
| 625 | 625 | * VMEMMAP_START ~ VMEMMAP_END : vmemmap space, used for struct page array. |
| 626 | 626 | * KERNEL_LINK_ADDR : start address of Kernel link and BPF |
| 627 | + | |
| 628 | +va_kernel_pa_offset | |
| 629 | +------------------- | |
| 630 | + | |
| 631 | +Indicates the offset between the kernel virtual and physical mappings. | |
| 632 | +Used to translate virtual to physical addresses. | |
| @@ -1623,6 +1623,26 @@ · 1622 unmodified lines | ||
| 1623 | 1623 | Format: off | on |
| 1624 | 1624 | default: on |
| 1625 | 1625 | |
| 1626 | + gather_data_sampling= | |
| 1627 | + [X86,INTEL] Control the Gather Data Sampling (GDS) | |
| 1628 | + mitigation. | |
| 1629 | + | |
| 1630 | + Gather Data Sampling is a hardware vulnerability which | |
| 1631 | + allows unprivileged speculative access to data which was | |
| 1632 | + previously stored in vector registers. | |
| 1633 | + | |
| 1634 | + This issue is mitigated by default in updated microcode. | |
| 1635 | + The mitigation may have a performance impact but can be | |
| 1636 | + disabled. On systems without the microcode mitigation | |
| 1637 | + disabling AVX serves as a mitigation. | |
| 1638 | + | |
| 1639 | + force: Disable AVX to mitigate systems without | |
| 1640 | + microcode mitigation. No effect if the microcode | |
| 1641 | + mitigation is present. Known to cause crashes in | |
| 1642 | + userspace with buggy AVX enumeration. | |
| 1643 | + | |
| 1644 | + off: Disable GDS mitigation. | |
| 1645 | + | |
| 1626 | 1646 | gcov_persist= [GCOV] When non-zero (default), profiling data for |
| 1627 | 1647 | kernel modules is saved and remains accessible via |
| 1628 | 1648 | debugfs, even when the module is unloaded/reloaded. |
| @@ -3273,24 +3293,25 @@ · 1644 unmodified lines | ||
| 3273 | 3293 | Disable all optional CPU mitigations. This |
| 3274 | 3294 | improves system performance, but it may also |
| 3275 | 3295 | expose users to several CPU vulnerabilities. |
| 3276 | − Equivalent to: nopti [X86,PPC] | |
| 3277 | − if nokaslr then kpti=0 [ARM64] | |
| 3278 | − nospectre_v1 [X86,PPC] | |
| 3279 | − nobp=0 [S390] | |
| 3280 | − nospectre_v2 [X86,PPC,S390,ARM64] | |
| 3281 | − spectre_v2_user=off [X86] | |
| 3282 | − spec_store_bypass_disable=off [X86,PPC] | |
| 3283 | − ssbd=force-off [ARM64] | |
| 3284 | − nospectre_bhb [ARM64] | |
| 3296 | + Equivalent to: if nokaslr then kpti=0 [ARM64] | |
| 3297 | + gather_data_sampling=off [X86] | |
| 3298 | + kvm.nx_huge_pages=off [X86] | |
| 3285 | 3299 | l1tf=off [X86] |
| 3286 | 3300 | mds=off [X86] |
| 3287 | − tsx_async_abort=off [X86] | |
| 3288 | − kvm.nx_huge_pages=off [X86] | |
| 3289 | − srbds=off [X86,INTEL] | |
| 3301 | + mmio_stale_data=off [X86] | |
| 3290 | 3302 | no_entry_flush [PPC] |
| 3291 | 3303 | no_uaccess_flush [PPC] |
| 3292 | − mmio_stale_data=off [X86] | |
| 3304 | + nobp=0 [S390] | |
| 3305 | + nopti [X86,PPC] | |
| 3306 | + nospectre_bhb [ARM64] | |
| 3307 | + nospectre_v1 [X86,PPC] | |
| 3308 | + nospectre_v2 [X86,PPC,S390,ARM64] | |
| 3293 | 3309 | retbleed=off [X86] |
| 3310 | + spec_store_bypass_disable=off [X86,PPC] | |
| 3311 | + spectre_v2_user=off [X86] | |
| 3312 | + srbds=off [X86,INTEL] | |
| 3313 | + ssbd=force-off [ARM64] | |
| 3314 | + tsx_async_abort=off [X86] | |
| 3294 | 3315 | |
| 3295 | 3316 | Exceptions: |
| 3296 | 3317 | This does not have any effect on |
| @@ -5875,6 +5896,17 @@ · 2578 unmodified lines | ||
| 5875 | 5896 | Not specifying this option is equivalent to |
| 5876 | 5897 | spectre_v2_user=auto. |
| 5877 | 5898 | |
| 5899 | + spec_rstack_overflow= | |
| 5900 | + [X86] Control RAS overflow mitigation on AMD Zen CPUs | |
| 5901 | + | |
| 5902 | + off - Disable mitigation | |
| 5903 | + microcode - Enable microcode mitigation only | |
| 5904 | + safe-ret - Enable sw-only safe RET mitigation (default) | |
| 5905 | + ibpb - Enable mitigation by issuing IBPB on | |
| 5906 | + kernel entry | |
| 5907 | + ibpb-vmexit - Issue IBPB only on VMEXIT | |
| 5908 | + (cloud-specific mitigation) | |
| 5909 | + | |
| 5878 | 5910 | spec_store_bypass_disable= |
| 5879 | 5911 | [HW] Control Speculative Store Bypass (SSB) Disable mitigation |
| 5880 | 5912 | (Speculative Store Bypass vulnerability) |
| @@ -148,6 +148,9 @@ stable kernels. · 147 unmodified lines | ||
| 148 | 148 | | ARM | MMU-700 | #2268618,2812531| N/A | |
| 149 | 149 | +----------------+-----------------+-----------------+-----------------------------+ |
| 150 | 150 | +----------------+-----------------+-----------------+-----------------------------+ |
| 151 | +| ARM | GIC-700 | #2941627 | ARM64_ERRATUM_2941627 | | |
| 152 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 153 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 151 | 154 | | Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_845719 | |
| 152 | 155 | +----------------+-----------------+-----------------+-----------------------------+ |
| 153 | 156 | | Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_843419 | |
| @@ -216,7 +216,6 @@ properties: · 215 unmodified lines | ||
| 216 | 216 | description: Whether to enable burnout current for EXT1. |
| 217 | 217 | |
| 218 | 218 | adi,ext1-burnout-current-nanoamp: |
| 219 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 220 | 219 | description: |
| 221 | 220 | Burnout current in nanoamps to be applied to EXT1. |
| 222 | 221 | enum: [0, 50, 500, 1000, 10000] |
| @@ -233,7 +232,6 @@ properties: · 10 unmodified lines | ||
| 233 | 232 | description: Whether to enable burnout current for EXT2. |
| 234 | 233 | |
| 235 | 234 | adi,ext2-burnout-current-nanoamp: |
| 236 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 237 | 235 | description: Burnout current in nanoamps to be applied to EXT2. |
| 238 | 236 | enum: [0, 50, 500, 1000, 10000] |
| 239 | 237 | default: 0 |
| @@ -249,7 +247,6 @@ properties: · 9 unmodified lines | ||
| 249 | 247 | description: Whether to enable burnout current for VIOUT. |
| 250 | 248 | |
| 251 | 249 | adi,viout-burnout-current-nanoamp: |
| 252 | − $ref: /schemas/types.yaml#/definitions/uint32 | |
| 253 | 250 | description: Burnout current in nanoamps to be applied to VIOUT. |
| 254 | 251 | enum: [0, 1000, 10000] |
| 255 | 252 | default: 0 |
| @@ -293,7 +293,7 @@ allOf: · 292 unmodified lines | ||
| 293 | 293 | patternProperties: |
| 294 | 294 | "^mac@[0-1]$": |
| 295 | 295 | type: object |
| 296 | − additionalProperties: false | |
| 296 | + unevaluatedProperties: false | |
| 297 | 297 | allOf: |
| 298 | 298 | - $ref: ethernet-controller.yaml# |
| 299 | 299 | description: |
| @@ -305,14 +305,9 @@ patternProperties: · 5 unmodified lines | ||
| 305 | 305 | reg: |
| 306 | 306 | maxItems: 1 |
| 307 | 307 | |
| 308 | − phy-handle: true | |
| 309 | − | |
| 310 | − phy-mode: true | |
| 311 | − | |
| 312 | 308 | required: |
| 313 | 309 | - reg |
| 314 | 310 | - compatible |
| 315 | − - phy-handle | |
| 316 | 311 | |
| 317 | 312 | required: |
| 318 | 313 | - compatible |
| @@ -91,12 +91,18 @@ properties: · 90 unmodified lines | ||
| 91 | 91 | $ref: /schemas/types.yaml#/definitions/phandle |
| 92 | 92 | |
| 93 | 93 | tx_delay: |
| 94 | − description: Delay value for TXD timing. Range value is 0~0x7F, 0x30 as default. | |
| 94 | + description: Delay value for TXD timing. | |
| 95 | 95 | $ref: /schemas/types.yaml#/definitions/uint32 |
| 96 | + minimum: 0 | |
| 97 | + maximum: 0x7F | |
| 98 | + default: 0x30 | |
| 96 | 99 | |
| 97 | 100 | rx_delay: |
| 98 | − description: Delay value for RXD timing. Range value is 0~0x7F, 0x10 as default. | |
| 101 | + description: Delay value for RXD timing. | |
| 99 | 102 | $ref: /schemas/types.yaml#/definitions/uint32 |
| 103 | + minimum: 0 | |
| 104 | + maximum: 0x7F | |
| 105 | + default: 0x10 | |
| 100 | 106 | |
| 101 | 107 | phy-supply: |
| 102 | 108 | description: PHY regulator |
| @@ -16,13 +16,15 @@ properties: · 15 unmodified lines | ||
| 16 | 16 | - enum: |
| 17 | 17 | - atmel,at91rm9200-usart |
| 18 | 18 | - atmel,at91sam9260-usart |
| 19 | − - microchip,sam9x60-usart | |
| 20 | 19 | - items: |
| 21 | 20 | - const: atmel,at91rm9200-dbgu |
| 22 | 21 | - const: atmel,at91rm9200-usart |
| 23 | 22 | - items: |
| 24 | 23 | - const: atmel,at91sam9260-dbgu |
| 25 | 24 | - const: atmel,at91sam9260-usart |
| 25 | + - items: | |
| 26 | + - const: microchip,sam9x60-usart | |
| 27 | + - const: atmel,at91sam9260-usart | |
| 26 | 28 | - items: |
| 27 | 29 | - const: microchip,sam9x60-dbgu |
| 28 | 30 | - const: microchip,sam9x60-usart |
| @@ -551,9 +551,8 @@ mutex or just to use i_size_read() instead. · 550 unmodified lines | ||
| 551 | 551 | Note: this does not protect the file->f_pos against concurrent modifications |
| 552 | 552 | since this is something the userspace has to take care about. |
| 553 | 553 | |
| 554 | −->iterate() is called with i_rwsem exclusive. | |
| 555 | − | |
| 556 | −->iterate_shared() is called with i_rwsem at least shared. | |
| 554 | +->iterate_shared() is called with i_rwsem held for reading, and with the | |
| 555 | +file f_pos_lock held exclusively | |
| 557 | 556 | |
| 558 | 557 | ->fasync() is responsible for maintaining the FASYNC bit in filp->f_flags. |
| 559 | 558 | Most instances call fasync_helper(), which does that maintenance, so it's |
| @@ -537,7 +537,7 @@ vfs_readdir() is gone; switch to iterate_dir() instead · 536 unmodified lines | ||
| 537 | 537 | |
| 538 | 538 | **mandatory** |
| 539 | 539 | |
| 540 | −->readdir() is gone now; switch to ->iterate() | |
| 540 | +->readdir() is gone now; switch to ->iterate_shared() | |
| 541 | 541 | |
| 542 | 542 | **mandatory** |
| 543 | 543 | |
| @@ -693,24 +693,19 @@ parallel now. · 149 unmodified lines | ||
| 693 | 693 | |
| 694 | 694 | --- |
| 695 | 695 | |
| 696 | −**recommended** | |
| 696 | +**mandatory** | |
| 697 | 697 | |
| 698 | −->iterate_shared() is added; it's a parallel variant of ->iterate(). | |
| 698 | +->iterate_shared() is added. | |
| 699 | 699 | Exclusion on struct file level is still provided (as well as that |
| 700 | 700 | between it and lseek on the same struct file), but if your directory |
| 701 | 701 | has been opened several times, you can get these called in parallel. |
| 702 | 702 | Exclusion between that method and all directory-modifying ones is |
| 703 | 703 | still provided, of course. |
| 704 | 704 | |
| 705 | −Often enough ->iterate() can serve as ->iterate_shared() without any | |
| 706 | −changes - it is a read-only operation, after all. If you have any | |
| 707 | −per-inode or per-dentry in-core data structures modified by ->iterate(), | |
| 708 | −you might need something to serialize the access to them. If you | |
| 709 | −do dcache pre-seeding, you'll need to switch to d_alloc_parallel() for | |
| 710 | −that; look for in-tree examples. | |
| 711 | − | |
| 712 | −Old method is only used if the new one is absent; eventually it will | |
| 713 | −be removed. Switch while you still can; the old one won't stay. | |
| 705 | +If you have any per-inode or per-dentry in-core data structures modified | |
| 706 | +by ->iterate_shared(), you might need something to serialize the access | |
| 707 | +to them. If you do dcache pre-seeding, you'll need to switch to | |
| 708 | +d_alloc_parallel() for that; look for in-tree examples. | |
| 714 | 709 | |
| 715 | 710 | --- |
| 716 | 711 | |
| @@ -930,9 +925,9 @@ should be done by looking at FMODE_LSEEK in file->f_mode. · 213 unmodified lines | ||
| 930 | 925 | filldir_t (readdir callbacks) calling conventions have changed. Instead of |
| 931 | 926 | returning 0 or -E... it returns bool now. false means "no more" (as -E... used |
| 932 | 927 | to) and true - "keep going" (as 0 in old calling conventions). Rationale: |
| 933 | −callers never looked at specific -E... values anyway. ->iterate() and | |
| 934 | −->iterate_shared() instance require no changes at all, all filldir_t ones in | |
| 935 | −the tree converted. | |
| 928 | +callers never looked at specific -E... values anyway. -> iterate_shared() | |
| 929 | +instances require no changes at all, all filldir_t ones in the tree | |
| 930 | +converted. | |
| 936 | 931 | |
| 937 | 932 | --- |
| 938 | 933 | |
| @@ -84,8 +84,6 @@ nr_inodes The maximum number of inodes for this instance. The default · 83 unmodified lines | ||
| 84 | 84 | is half of the number of your physical RAM pages, or (on a |
| 85 | 85 | machine with highmem) the number of lowmem RAM pages, |
| 86 | 86 | whichever is the lower. |
| 87 | −noswap Disables swap. Remounts must respect the original settings. | |
| 88 | − By default swap is enabled. | |
| 89 | 87 | ========= ============================================================ |
| 90 | 88 | |
| 91 | 89 | These parameters accept a suffix k, m or g for kilo, mega and giga and |
| @@ -99,36 +97,31 @@ mount with such options, since it allows any user with write access to · 7 unmodified lines | ||
| 99 | 97 | use up all the memory on the machine; but enhances the scalability of |
| 100 | 98 | that instance in a system with many CPUs making intensive use of it. |
| 101 | 99 | |
| 100 | +tmpfs blocks may be swapped out, when there is a shortage of memory. | |
| 101 | +tmpfs has a mount option to disable its use of swap: | |
| 102 | + | |
| 103 | +====== =========================================================== | |
| 104 | +noswap Disables swap. Remounts must respect the original settings. | |
| 105 | + By default swap is enabled. | |
| 106 | +====== =========================================================== | |
| 107 | + | |
| 102 | 108 | tmpfs also supports Transparent Huge Pages which requires a kernel |
| 103 | 109 | configured with CONFIG_TRANSPARENT_HUGEPAGE and with huge supported for |
| 104 | 110 | your system (has_transparent_hugepage(), which is architecture specific). |
| 105 | 111 | The mount options for this are: |
| 106 | 112 | |
| 107 | −====== ============================================================ | |
| 108 | −huge=0 never: disables huge pages for the mount | |
| 109 | −huge=1 always: enables huge pages for the mount | |
| 110 | −huge=2 within_size: only allocate huge pages if the page will be | |
| 111 | − fully within i_size, also respect fadvise()/madvise() hints. | |
| 112 | −huge=3 advise: only allocate huge pages if requested with | |
| 113 | − fadvise()/madvise() | |
| 114 | −====== ============================================================ | |
| 115 | − | |
| 116 | −There is a sysfs file which you can also use to control system wide THP | |
| 117 | −configuration for all tmpfs mounts, the file is: | |
| 118 | − | |
| 119 | −/sys/kernel/mm/transparent_hugepage/shmem_enabled | |
| 120 | − | |
| 121 | −This sysfs file is placed on top of THP sysfs directory and so is registered | |
| 122 | −by THP code. It is however only used to control all tmpfs mounts with one | |
| 123 | −single knob. Since it controls all tmpfs mounts it should only be used either | |
| 124 | −for emergency or testing purposes. The values you can set for shmem_enabled are: | |
| 125 | − | |
| 126 | −== ============================================================ | |
| 127 | −-1 deny: disables huge on shm_mnt and all mounts, for | |
| 128 | − emergency use | |
| 129 | −-2 force: enables huge on shm_mnt and all mounts, w/o needing | |
| 130 | − option, for testing | |
| 131 | −== ============================================================ | |
| 113 | +================ ============================================================== | |
| 114 | +huge=never Do not allocate huge pages. This is the default. | |
| 115 | +huge=always Attempt to allocate huge page every time a new page is needed. | |
| 116 | +huge=within_size Only allocate huge page if it will be fully within i_size. | |
| 117 | + Also respect madvise(2) hints. | |
| 118 | +huge=advise Only allocate huge page if requested with madvise(2). | |
| 119 | +================ ============================================================== | |
| 120 | + | |
| 121 | +See also Documentation/admin-guide/mm/transhuge.rst, which describes the | |
| 122 | +sysfs file /sys/kernel/mm/transparent_hugepage/shmem_enabled: which can | |
| 123 | +be used to deny huge pages on all tmpfs mounts in an emergency, or to | |
| 124 | +force huge pages on all tmpfs mounts for testing. | |
| 132 | 125 | |
| 133 | 126 | tmpfs has a mount option to set the NUMA memory allocation policy for |
| 134 | 127 | all files in that instance (if CONFIG_NUMA is enabled) - which can be |
| @@ -65,15 +65,16 @@ argument - drivers can process completions for any number of Tx · 64 unmodified lines | ||
| 65 | 65 | packets but should only process up to ``budget`` number of |
| 66 | 66 | Rx packets. Rx processing is usually much more expensive. |
| 67 | 67 | |
| 68 | −In other words, it is recommended to ignore the budget argument when | |
| 69 | −performing TX buffer reclamation to ensure that the reclamation is not | |
| 70 | −arbitrarily bounded; however, it is required to honor the budget argument | |
| 71 | −for RX processing. | |
| 68 | +In other words for Rx processing the ``budget`` argument limits how many | |
| 69 | +packets driver can process in a single poll. Rx specific APIs like page | |
| 70 | +pool or XDP cannot be used at all when ``budget`` is 0. | |
| 71 | +skb Tx processing should happen regardless of the ``budget``, but if | |
| 72 | +the argument is 0 driver cannot call any XDP (or page pool) APIs. | |
| 72 | 73 | |
| 73 | 74 | .. warning:: |
| 74 | 75 | |
| 75 | − The ``budget`` argument may be 0 if core tries to only process Tx completions | |
| 76 | − and no Rx packets. | |
| 76 | + The ``budget`` argument may be 0 if core tries to only process | |
| 77 | + skb Tx completions and no Rx or XDP packets. | |
| 77 | 78 | |
| 78 | 79 | The poll method returns the amount of work done. If the driver still |
| 79 | 80 | has outstanding work to do (e.g. ``budget`` was exhausted) |
| @@ -254,7 +254,6 @@ an involved disclosed party. The current ambassadors list: · 253 unmodified lines | ||
| 254 | 254 | Samsung Javier González <javier.gonz@samsung.com> |
| 255 | 255 | |
| 256 | 256 | Microsoft James Morris <jamorris@linux.microsoft.com> |
| 257 | − VMware | |
| 258 | 257 | Xen Andrew Cooper <andrew.cooper3@citrix.com> |
| 259 | 258 | |
| 260 | 259 | Canonical John Johansen <john.johansen@canonical.com> |
| @@ -263,10 +262,8 @@ an involved disclosed party. The current ambassadors list: · 2 unmodified lines | ||
| 263 | 262 | Red Hat Josh Poimboeuf <jpoimboe@redhat.com> |
| 264 | 263 | SUSE Jiri Kosina <jkosina@suse.cz> |
| 265 | 264 | |
| 266 | − Amazon | |
| 267 | 265 | Google Kees Cook <keescook@chromium.org> |
| 268 | 266 | |
| 269 | − GCC | |
| 270 | 267 | LLVM Nick Desaulniers <ndesaulniers@google.com> |
| 271 | 268 | ============= ======================================================== |
| 272 | 269 | |
| @@ -63,31 +63,28 @@ information submitted to the security list and any followup discussions · 62 unmodified lines | ||
| 63 | 63 | of the report are treated confidentially even after the embargo has been |
| 64 | 64 | lifted, in perpetuity. |
| 65 | 65 | |
| 66 | −Coordination | |
| 67 | −------------ | |
| 68 | − | |
| 69 | −Fixes for sensitive bugs, such as those that might lead to privilege | |
| 70 | −escalations, may need to be coordinated with the private | |
| 71 | −<linux-distros@vs.openwall.org> mailing list so that distribution vendors | |
| 72 | −are well prepared to issue a fixed kernel upon public disclosure of the | |
| 73 | −upstream fix. Distros will need some time to test the proposed patch and | |
| 74 | −will generally request at least a few days of embargo, and vendor update | |
| 75 | −publication prefers to happen Tuesday through Thursday. When appropriate, | |
| 76 | −the security team can assist with this coordination, or the reporter can | |
| 77 | −include linux-distros from the start. In this case, remember to prefix | |
| 78 | −the email Subject line with "[vs]" as described in the linux-distros wiki: | |
| 79 | −<http://oss-security.openwall.org/wiki/mailing-lists/distros#how-to-use-the-lists> | |
| 66 | +Coordination with other groups | |
| 67 | +------------------------------ | |
| 68 | + | |
| 69 | +The kernel security team strongly recommends that reporters of potential | |
| 70 | +security issues NEVER contact the "linux-distros" mailing list until | |
| 71 | +AFTER discussing it with the kernel security team. Do not Cc: both | |
| 72 | +lists at once. You may contact the linux-distros mailing list after a | |
| 73 | +fix has been agreed on and you fully understand the requirements that | |
| 74 | +doing so will impose on you and the kernel community. | |
| 75 | + | |
| 76 | +The different lists have different goals and the linux-distros rules do | |
| 77 | +not contribute to actually fixing any potential security problems. | |
| 80 | 78 | |
| 81 | 79 | CVE assignment |
| 82 | 80 | -------------- |
| 83 | 81 | |
| 84 | −The security team does not normally assign CVEs, nor do we require them | |
| 85 | −for reports or fixes, as this can needlessly complicate the process and | |
| 86 | −may delay the bug handling. If a reporter wishes to have a CVE identifier | |
| 87 | −assigned ahead of public disclosure, they will need to contact the private | |
| 88 | −linux-distros list, described above. When such a CVE identifier is known | |
| 89 | −before a patch is provided, it is desirable to mention it in the commit | |
| 90 | −message if the reporter agrees. | |
| 82 | +The security team does not assign CVEs, nor do we require them for | |
| 83 | +reports or fixes, as this can needlessly complicate the process and may | |
| 84 | +delay the bug handling. If a reporter wishes to have a CVE identifier | |
| 85 | +assigned, they should find one by themselves, for example by contacting | |
| 86 | +MITRE directly. However under no circumstances will a patch inclusion | |
| 87 | +be delayed to wait for a CVE identifier to arrive. | |
| 91 | 88 | |
| 92 | 89 | Non-disclosure agreements |
| 93 | 90 | ------------------------- |
| @@ -2339,7 +2339,7 @@ F: drivers/phy/mediatek/ · 2338 unmodified lines | ||
| 2339 | 2339 | ARM/MICROCHIP (ARM64) SoC support |
| 2340 | 2340 | M: Conor Dooley <conor@kernel.org> |
| 2341 | 2341 | M: Nicolas Ferre <nicolas.ferre@microchip.com> |
| 2342 | −M: Claudiu Beznea <claudiu.beznea@microchip.com> | |
| 2342 | +M: Claudiu Beznea <claudiu.beznea@tuxon.dev> | |
| 2343 | 2343 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 2344 | 2344 | S: Supported |
| 2345 | 2345 | T: git https://git.kernel.org/pub/scm/linux/kernel/git/at91/linux.git |
| @@ -2348,7 +2348,7 @@ F: arch/arm64/boot/dts/microchip/ · 2 unmodified lines | ||
| 2348 | 2348 | ARM/Microchip (AT91) SoC support |
| 2349 | 2349 | M: Nicolas Ferre <nicolas.ferre@microchip.com> |
| 2350 | 2350 | M: Alexandre Belloni <alexandre.belloni@bootlin.com> |
| 2351 | −M: Claudiu Beznea <claudiu.beznea@microchip.com> | |
| 2351 | +M: Claudiu Beznea <claudiu.beznea@tuxon.dev> | |
| 2352 | 2352 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 2353 | 2353 | S: Supported |
| 2354 | 2354 | W: http://www.linux4sam.org |
| @@ -3250,7 +3250,7 @@ F: include/uapi/linux/atm* · 895 unmodified lines | ||
| 3250 | 3250 | |
| 3251 | 3251 | ATMEL MACB ETHERNET DRIVER |
| 3252 | 3252 | M: Nicolas Ferre <nicolas.ferre@microchip.com> |
| 3253 | −M: Claudiu Beznea <claudiu.beznea@microchip.com> | |
| 3253 | +M: Claudiu Beznea <claudiu.beznea@tuxon.dev> | |
| 3254 | 3254 | S: Supported |
| 3255 | 3255 | F: drivers/net/ethernet/cadence/ |
| 3256 | 3256 | |
| @@ -3262,9 +3262,8 @@ F: Documentation/devicetree/bindings/input/atmel,maxtouch.yaml · 5 unmodified lines | ||
| 3262 | 3262 | F: drivers/input/touchscreen/atmel_mxt_ts.c |
| 3263 | 3263 | |
| 3264 | 3264 | ATMEL WIRELESS DRIVER |
| 3265 | −M: Simon Kelley <simon@thekelleys.org.uk> | |
| 3266 | 3265 | L: linux-wireless@vger.kernel.org |
| 3267 | −S: Maintained | |
| 3266 | +S: Orphan | |
| 3268 | 3267 | W: http://www.thekelleys.org.uk/atmel |
| 3269 | 3268 | W: http://atmelwlandriver.sourceforge.net/ |
| 3270 | 3269 | F: drivers/net/wireless/atmel/atmel* |
| @@ -3394,7 +3393,7 @@ F: drivers/media/radio/radio-aztech* · 123 unmodified lines | ||
| 3394 | 3393 | B43 WIRELESS DRIVER |
| 3395 | 3394 | L: linux-wireless@vger.kernel.org |
| 3396 | 3395 | L: b43-dev@lists.infradead.org |
| 3397 | −S: Odd Fixes | |
| 3396 | +S: Orphan | |
| 3398 | 3397 | W: https://wireless.wiki.kernel.org/en/users/Drivers/b43 |
| 3399 | 3398 | F: drivers/net/wireless/broadcom/b43/ |
| 3400 | 3399 | |
| @@ -4463,7 +4462,6 @@ CADENCE USB3 DRD IP DRIVER · 1062 unmodified lines | ||
| 4463 | 4462 | M: Peter Chen <peter.chen@kernel.org> |
| 4464 | 4463 | M: Pawel Laszczak <pawell@cadence.com> |
| 4465 | 4464 | R: Roger Quadros <rogerq@kernel.org> |
| 4466 | −R: Aswath Govindraju <a-govindraju@ti.com> | |
| 4467 | 4465 | L: linux-usb@vger.kernel.org |
| 4468 | 4466 | S: Maintained |
| 4469 | 4467 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git |
| @@ -5149,10 +5147,12 @@ S: Maintained · 679 unmodified lines | ||
| 5149 | 5147 | F: include/linux/compiler_attributes.h |
| 5150 | 5148 | |
| 5151 | 5149 | COMPUTE EXPRESS LINK (CXL) |
| 5150 | +M: Davidlohr Bueso <dave@stgolabs.net> | |
| 5151 | +M: Jonathan Cameron <jonathan.cameron@huawei.com> | |
| 5152 | +M: Dave Jiang <dave.jiang@intel.com> | |
| 5152 | 5153 | M: Alison Schofield <alison.schofield@intel.com> |
| 5153 | 5154 | M: Vishal Verma <vishal.l.verma@intel.com> |
| 5154 | 5155 | M: Ira Weiny <ira.weiny@intel.com> |
| 5155 | −M: Ben Widawsky <bwidawsk@kernel.org> | |
| 5156 | 5156 | M: Dan Williams <dan.j.williams@intel.com> |
| 5157 | 5157 | L: linux-cxl@vger.kernel.org |
| 5158 | 5158 | S: Maintained |
| @@ -5461,8 +5461,7 @@ F: Documentation/devicetree/bindings/net/can/ctu,ctucanfd.yaml · 302 unmodified lines | ||
| 5461 | 5461 | F: drivers/net/can/ctucanfd/ |
| 5462 | 5462 | |
| 5463 | 5463 | CW1200 WLAN driver |
| 5464 | −M: Solomon Peachy <pizza@shaftnet.org> | |
| 5465 | −S: Maintained | |
| 5464 | +S: Orphan | |
| 5466 | 5465 | F: drivers/net/wireless/st/cw1200/ |
| 5467 | 5466 | |
| 5468 | 5467 | CX18 VIDEO4LINUX DRIVER |
| @@ -9376,7 +9375,6 @@ F: drivers/crypto/hisilicon/sgl.c · 3907 unmodified lines | ||
| 9376 | 9375 | F: include/linux/hisi_acc_qm.h |
| 9377 | 9376 | |
| 9378 | 9377 | HISILICON ROCE DRIVER |
| 9379 | −M: Haoyue Xu <xuhaoyue1@hisilicon.com> | |
| 9380 | 9378 | M: Junxian Huang <huangjunxian6@hisilicon.com> |
| 9381 | 9379 | L: linux-rdma@vger.kernel.org |
| 9382 | 9380 | S: Maintained |
| @@ -9661,6 +9659,7 @@ F: tools/hv/ · 278 unmodified lines | ||
| 9661 | 9659 | |
| 9662 | 9660 | HYPERBUS SUPPORT |
| 9663 | 9661 | M: Vignesh Raghavendra <vigneshr@ti.com> |
| 9662 | +R: Tudor Ambarus <tudor.ambarus@linaro.org> | |
| 9664 | 9663 | L: linux-mtd@lists.infradead.org |
| 9665 | 9664 | S: Supported |
| 9666 | 9665 | Q: http://patchwork.ozlabs.org/project/linux-mtd/list/ |
| @@ -12480,6 +12479,7 @@ F: net/mctp/ · 2813 unmodified lines | ||
| 12480 | 12479 | |
| 12481 | 12480 | MAPLE TREE |
| 12482 | 12481 | M: Liam R. Howlett <Liam.Howlett@oracle.com> |
| 12482 | +L: maple-tree@lists.infradead.org | |
| 12483 | 12483 | L: linux-mm@kvack.org |
| 12484 | 12484 | S: Supported |
| 12485 | 12485 | F: Documentation/core-api/maple_tree.rst |
| @@ -12591,18 +12591,14 @@ F: Documentation/devicetree/bindings/net/marvell,pp2.yaml · 105 unmodified lines | ||
| 12591 | 12591 | F: drivers/net/ethernet/marvell/mvpp2/ |
| 12592 | 12592 | |
| 12593 | 12593 | MARVELL MWIFIEX WIRELESS DRIVER |
| 12594 | −M: Amitkumar Karwar <amitkarwar@gmail.com> | |
| 12595 | −M: Ganapathi Bhat <ganapathi017@gmail.com> | |
| 12596 | −M: Sharvari Harisangam <sharvari.harisangam@nxp.com> | |
| 12597 | −M: Xinming Hu <huxinming820@gmail.com> | |
| 12594 | +M: Brian Norris <briannorris@chromium.org> | |
| 12598 | 12595 | L: linux-wireless@vger.kernel.org |
| 12599 | −S: Maintained | |
| 12596 | +S: Odd Fixes | |
| 12600 | 12597 | F: drivers/net/wireless/marvell/mwifiex/ |
| 12601 | 12598 | |
| 12602 | 12599 | MARVELL MWL8K WIRELESS DRIVER |
| 12603 | −M: Lennert Buytenhek <buytenh@wantstofly.org> | |
| 12604 | 12600 | L: linux-wireless@vger.kernel.org |
| 12605 | −S: Odd Fixes | |
| 12601 | +S: Orphan | |
| 12606 | 12602 | F: drivers/net/wireless/marvell/mwl8k.c |
| 12607 | 12603 | |
| 12608 | 12604 | MARVELL NAND CONTROLLER DRIVER |
| @@ -13790,7 +13786,7 @@ F: Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml · 1181 unmodified lines | ||
| 13790 | 13786 | F: drivers/spi/spi-at91-usart.c |
| 13791 | 13787 | |
| 13792 | 13788 | MICROCHIP AUDIO ASOC DRIVERS |
| 13793 | −M: Claudiu Beznea <claudiu.beznea@microchip.com> | |
| 13789 | +M: Claudiu Beznea <claudiu.beznea@tuxon.dev> | |
| 13794 | 13790 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 13795 | 13791 | S: Supported |
| 13796 | 13792 | F: Documentation/devicetree/bindings/sound/atmel* |
| @@ -13813,7 +13809,7 @@ S: Maintained · 16 unmodified lines | ||
| 13813 | 13809 | F: drivers/crypto/atmel-ecc.* |
| 13814 | 13810 | |
| 13815 | 13811 | MICROCHIP EIC DRIVER |
| 13816 | −M: Claudiu Beznea <claudiu.beznea@microchip.com> | |
| 13812 | +M: Claudiu Beznea <claudiu.beznea@tuxon.dev> | |
| 13817 | 13813 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 13818 | 13814 | S: Supported |
| 13819 | 13815 | F: Documentation/devicetree/bindings/interrupt-controller/microchip,sama7g5-eic.yaml |
| @@ -13886,7 +13882,7 @@ F: drivers/video/fbdev/atmel_lcdfb.c · 66 unmodified lines | ||
| 13886 | 13882 | F: include/video/atmel_lcdc.h |
| 13887 | 13883 | |
| 13888 | 13884 | MICROCHIP MCP16502 PMIC DRIVER |
| 13889 | −M: Claudiu Beznea <claudiu.beznea@microchip.com> | |
| 13885 | +M: Claudiu Beznea <claudiu.beznea@tuxon.dev> | |
| 13890 | 13886 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 13891 | 13887 | S: Supported |
| 13892 | 13888 | F: Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt |
| @@ -13913,7 +13909,7 @@ F: Documentation/devicetree/bindings/mtd/atmel-nand.txt · 20 unmodified lines | ||
| 13913 | 13909 | F: drivers/mtd/nand/raw/atmel/* |
| 13914 | 13910 | |
| 13915 | 13911 | MICROCHIP OTPC DRIVER |
| 13916 | −M: Claudiu Beznea <claudiu.beznea@microchip.com> | |
| 13912 | +M: Claudiu Beznea <claudiu.beznea@tuxon.dev> | |
| 13917 | 13913 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 13918 | 13914 | S: Supported |
| 13919 | 13915 | F: Documentation/devicetree/bindings/nvmem/microchip,sama7g5-otpc.yaml |
| @@ -13952,7 +13948,7 @@ F: Documentation/devicetree/bindings/fpga/microchip,mpf-spi-fpga-mgr.yaml · 32 unmodified lines | ||
| 13952 | 13948 | F: drivers/fpga/microchip-spi.c |
| 13953 | 13949 | |
| 13954 | 13950 | MICROCHIP PWM DRIVER |
| 13955 | −M: Claudiu Beznea <claudiu.beznea@microchip.com> | |
| 13951 | +M: Claudiu Beznea <claudiu.beznea@tuxon.dev> | |
| 13956 | 13952 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 13957 | 13953 | L: linux-pwm@vger.kernel.org |
| 13958 | 13954 | S: Supported |
| @@ -13968,7 +13964,7 @@ F: drivers/iio/adc/at91-sama5d2_adc.c · 9 unmodified lines | ||
| 13968 | 13964 | F: include/dt-bindings/iio/adc/at91-sama5d2_adc.h |
| 13969 | 13965 | |
| 13970 | 13966 | MICROCHIP SAMA5D2-COMPATIBLE SHUTDOWN CONTROLLER |
| 13971 | −M: Claudiu Beznea <claudiu.beznea@microchip.com> | |
| 13967 | +M: Claudiu Beznea <claudiu.beznea@tuxon.dev> | |
| 13972 | 13968 | S: Supported |
| 13973 | 13969 | F: Documentation/devicetree/bindings/power/reset/atmel,sama5d2-shdwc.yaml |
| 13974 | 13970 | F: drivers/power/reset/at91-sama5d2_shdwc.c |
| @@ -13985,7 +13981,7 @@ S: Supported · 10 unmodified lines | ||
| 13985 | 13981 | F: drivers/spi/spi-atmel.* |
| 13986 | 13982 | |
| 13987 | 13983 | MICROCHIP SSC DRIVER |
| 13988 | −M: Claudiu Beznea <claudiu.beznea@microchip.com> | |
| 13984 | +M: Claudiu Beznea <claudiu.beznea@tuxon.dev> | |
| 13989 | 13985 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 13990 | 13986 | S: Supported |
| 13991 | 13987 | F: Documentation/devicetree/bindings/misc/atmel-ssc.txt |
| @@ -14014,7 +14010,7 @@ F: drivers/usb/gadget/udc/atmel_usba_udc.* · 22 unmodified lines | ||
| 14014 | 14010 | |
| 14015 | 14011 | MICROCHIP WILC1000 WIFI DRIVER |
| 14016 | 14012 | M: Ajay Singh <ajay.kathat@microchip.com> |
| 14017 | −M: Claudiu Beznea <claudiu.beznea@microchip.com> | |
| 14013 | +M: Claudiu Beznea <claudiu.beznea@tuxon.dev> | |
| 14018 | 14014 | L: linux-wireless@vger.kernel.org |
| 14019 | 14015 | S: Supported |
| 14020 | 14016 | F: drivers/net/wireless/microchip/wilc1000/ |
| @@ -16297,6 +16293,7 @@ F: drivers/pci/controller/dwc/pci-exynos.c · 2276 unmodified lines | ||
| 16297 | 16293 | PCI DRIVER FOR SYNOPSYS DESIGNWARE |
| 16298 | 16294 | M: Jingoo Han <jingoohan1@gmail.com> |
| 16299 | 16295 | M: Gustavo Pimentel <gustavo.pimentel@synopsys.com> |
| 16296 | +M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> | |
| 16300 | 16297 | L: linux-pci@vger.kernel.org |
| 16301 | 16298 | S: Maintained |
| 16302 | 16299 | F: Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml |
| @@ -17448,6 +17445,7 @@ F: drivers/media/tuners/qt1010* · 1145 unmodified lines | ||
| 17448 | 17445 | |
| 17449 | 17446 | QUALCOMM ATH12K WIRELESS DRIVER |
| 17450 | 17447 | M: Kalle Valo <kvalo@kernel.org> |
| 17448 | +M: Jeff Johnson <quic_jjohnson@quicinc.com> | |
| 17451 | 17449 | L: ath12k@lists.infradead.org |
| 17452 | 17450 | S: Supported |
| 17453 | 17451 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git |
| @@ -17455,6 +17453,7 @@ F: drivers/net/wireless/ath/ath12k/ · 1 unmodified line | ||
| 17455 | 17453 | |
| 17456 | 17454 | QUALCOMM ATHEROS ATH10K WIRELESS DRIVER |
| 17457 | 17455 | M: Kalle Valo <kvalo@kernel.org> |
| 17456 | +M: Jeff Johnson <quic_jjohnson@quicinc.com> | |
| 17458 | 17457 | L: ath10k@lists.infradead.org |
| 17459 | 17458 | S: Supported |
| 17460 | 17459 | W: https://wireless.wiki.kernel.org/en/users/Drivers/ath10k |
| @@ -17464,6 +17463,7 @@ F: drivers/net/wireless/ath/ath10k/ · 3 unmodified lines | ||
| 17464 | 17463 | |
| 17465 | 17464 | QUALCOMM ATHEROS ATH11K WIRELESS DRIVER |
| 17466 | 17465 | M: Kalle Valo <kvalo@kernel.org> |
| 17466 | +M: Jeff Johnson <quic_jjohnson@quicinc.com> | |
| 17467 | 17467 | L: ath11k@lists.infradead.org |
| 17468 | 17468 | S: Supported |
| 17469 | 17469 | W: https://wireless.wiki.kernel.org/en/users/Drivers/ath11k |
| @@ -17984,7 +17984,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.g · 514 unmodified lines | ||
| 17984 | 17984 | F: drivers/net/wireless/realtek/rtlwifi/ |
| 17985 | 17985 | |
| 17986 | 17986 | REALTEK WIRELESS DRIVER (rtw88) |
| 17987 | −M: Yan-Hsuan Chuang <tony0620emma@gmail.com> | |
| 17987 | +M: Ping-Ke Shih <pkshih@realtek.com> | |
| 17988 | 17988 | L: linux-wireless@vger.kernel.org |
| 17989 | 17989 | S: Maintained |
| 17990 | 17990 | F: drivers/net/wireless/realtek/rtw88/ |
| @@ -18509,17 +18509,14 @@ RTL8180 WIRELESS DRIVER · 518 unmodified lines | ||
| 18509 | 18509 | L: linux-wireless@vger.kernel.org |
| 18510 | 18510 | S: Orphan |
| 18511 | 18511 | W: https://wireless.wiki.kernel.org/ |
| 18512 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git | |
| 18513 | 18512 | F: drivers/net/wireless/realtek/rtl818x/rtl8180/ |
| 18514 | 18513 | |
| 18515 | 18514 | RTL8187 WIRELESS DRIVER |
| 18516 | −M: Herton Ronaldo Krzesinski <herton@canonical.com> | |
| 18517 | −M: Hin-Tak Leung <htl10@users.sourceforge.net> | |
| 18515 | +M: Hin-Tak Leung <hintak.leung@gmail.com> | |
| 18518 | 18516 | M: Larry Finger <Larry.Finger@lwfinger.net> |
| 18519 | 18517 | L: linux-wireless@vger.kernel.org |
| 18520 | 18518 | S: Maintained |
| 18521 | 18519 | W: https://wireless.wiki.kernel.org/ |
| 18522 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git | |
| 18523 | 18520 | F: drivers/net/wireless/realtek/rtl818x/rtl8187/ |
| 18524 | 18521 | |
| 18525 | 18522 | RTL8XXXU WIRELESS DRIVER (rtl8xxxu) |
| @@ -20403,7 +20400,6 @@ F: drivers/pwm/pwm-stm32* · 1877 unmodified lines | ||
| 20403 | 20400 | F: include/linux/*/stm32-*tim* |
| 20404 | 20401 | |
| 20405 | 20402 | STMMAC ETHERNET DRIVER |
| 20406 | −M: Giuseppe Cavallaro <peppe.cavallaro@st.com> | |
| 20407 | 20403 | M: Alexandre Torgue <alexandre.torgue@foss.st.com> |
| 20408 | 20404 | M: Jose Abreu <joabreu@synopsys.com> |
| 20409 | 20405 | L: netdev@vger.kernel.org |
| @@ -21641,11 +21637,17 @@ F: Documentation/translations/zh_TW/ · 1231 unmodified lines | ||
| 21641 | 21637 | TTY LAYER |
| 21642 | 21638 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| 21643 | 21639 | M: Jiri Slaby <jirislaby@kernel.org> |
| 21640 | +L: linux-kernel@vger.kernel.org | |
| 21641 | +L: linux-serial@vger.kernel.org | |
| 21644 | 21642 | S: Supported |
| 21645 | 21643 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git |
| 21646 | 21644 | F: Documentation/driver-api/serial/ |
| 21647 | 21645 | F: drivers/tty/ |
| 21646 | +F: drivers/tty/serial/serial_base.h | |
| 21647 | +F: drivers/tty/serial/serial_base_bus.c | |
| 21648 | 21648 | F: drivers/tty/serial/serial_core.c |
| 21649 | +F: drivers/tty/serial/serial_ctrl.c | |
| 21650 | +F: drivers/tty/serial/serial_port.c | |
| 21649 | 21651 | F: include/linux/selection.h |
| 21650 | 21652 | F: include/linux/serial.h |
| 21651 | 21653 | F: include/linux/serial_core.h |
| @@ -21674,11 +21676,14 @@ S: Orphan · 22 unmodified lines | ||
| 21674 | 21676 | F: drivers/net/ethernet/dec/tulip/ |
| 21675 | 21677 | |
| 21676 | 21678 | TUN/TAP driver |
| 21677 | −M: Maxim Krasnyansky <maxk@qti.qualcomm.com> | |
| 21679 | +M: Willem de Bruijn <willemdebruijn.kernel@gmail.com> | |
| 21680 | +M: Jason Wang <jasowang@redhat.com> | |
| 21678 | 21681 | S: Maintained |
| 21679 | 21682 | W: http://vtun.sourceforge.net/tun |
| 21680 | 21683 | F: Documentation/networking/tuntap.rst |
| 21681 | 21684 | F: arch/um/os-Linux/drivers/ |
| 21685 | +F: drivers/net/tap.c | |
| 21686 | +F: drivers/net/tun.c | |
| 21682 | 21687 | |
| 21683 | 21688 | TURBOCHANNEL SUBSYSTEM |
| 21684 | 21689 | M: "Maciej W. Rozycki" <macro@orcam.me.uk> |
| @@ -21901,9 +21906,8 @@ S: Maintained · 216 unmodified lines | ||
| 21901 | 21906 | F: drivers/usb/misc/apple-mfi-fastcharge.c |
| 21902 | 21907 | |
| 21903 | 21908 | USB AR5523 WIRELESS DRIVER |
| 21904 | −M: Pontus Fuchs <pontus.fuchs@gmail.com> | |
| 21905 | 21909 | L: linux-wireless@vger.kernel.org |
| 21906 | −S: Maintained | |
| 21910 | +S: Orphan | |
| 21907 | 21911 | F: drivers/net/wireless/ath/ar5523/ |
| 21908 | 21912 | |
| 21909 | 21913 | USB ATTACHED SCSI |
| @@ -22180,9 +22184,8 @@ F: drivers/usb/gadget/legacy/webcam.c · 270 unmodified lines | ||
| 22180 | 22184 | F: include/uapi/linux/usb/g_uvc.h |
| 22181 | 22185 | |
| 22182 | 22186 | USB WIRELESS RNDIS DRIVER (rndis_wlan) |
| 22183 | −M: Jussi Kivilinna <jussi.kivilinna@iki.fi> | |
| 22184 | 22187 | L: linux-wireless@vger.kernel.org |
| 22185 | −S: Maintained | |
| 22188 | +S: Orphan | |
| 22186 | 22189 | F: drivers/net/wireless/legacy/rndis_wlan.c |
| 22187 | 22190 | |
| 22188 | 22191 | USB XHCI DRIVER |
| @@ -22957,7 +22960,7 @@ F: drivers/input/misc/wistron_btns.c · 768 unmodified lines | ||
| 22957 | 22960 | |
| 22958 | 22961 | WL3501 WIRELESS PCMCIA CARD DRIVER |
| 22959 | 22962 | L: linux-wireless@vger.kernel.org |
| 22960 | −S: Odd fixes | |
| 22963 | +S: Orphan | |
| 22961 | 22964 | F: drivers/net/wireless/legacy/wl3501* |
| 22962 | 22965 | |
| 22963 | 22966 | WMI BINARY MOF DRIVER |
| @@ -23528,11 +23531,8 @@ S: Maintained · 564 unmodified lines | ||
| 23528 | 23531 | F: mm/zbud.c |
| 23529 | 23532 | |
| 23530 | 23533 | ZD1211RW WIRELESS DRIVER |
| 23531 | −M: Ulrich Kunitz <kune@deine-taler.de> | |
| 23532 | 23534 | L: linux-wireless@vger.kernel.org |
| 23533 | −L: zd1211-devs@lists.sourceforge.net (subscribers-only) | |
| 23534 | −S: Maintained | |
| 23535 | −W: http://zd1211.ath.cx/wiki/DriverRewrite | |
| 23535 | +S: Orphan | |
| 23536 | 23536 | F: drivers/net/wireless/zydas/zd1211rw/ |
| 23537 | 23537 | |
| 23538 | 23538 | ZD1301 MEDIA DRIVER |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 6 |
| 3 | 3 | PATCHLEVEL = 5 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc3 | |
| 5 | +EXTRAVERSION = -rc6 | |
| 6 | 6 | NAME = Hurr durr I'ma ninja sloth |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -47,12 +47,6 @@ unsigned long __get_wchan(struct task_struct *p); · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | #define ARCH_HAS_PREFETCH |
| 49 | 49 | #define ARCH_HAS_PREFETCHW |
| 50 | −#define ARCH_HAS_SPINLOCK_PREFETCH | |
| 51 | − | |
| 52 | −#ifndef CONFIG_SMP | |
| 53 | −/* Nothing to prefetch. */ | |
| 54 | −#define spin_lock_prefetch(lock) do { } while (0) | |
| 55 | −#endif | |
| 56 | 50 | |
| 57 | 51 | extern inline void prefetch(const void *ptr) |
| 58 | 52 | { |
| @@ -64,11 +58,4 @@ extern inline void prefetchw(const void *ptr) · 5 unmodified lines | ||
| 64 | 58 | __builtin_prefetch(ptr, 1, 3); |
| 65 | 59 | } |
| 66 | 60 | |
| 67 | −#ifdef CONFIG_SMP | |
| 68 | −extern inline void spin_lock_prefetch(const void *ptr) | |
| 69 | −{ | |
| 70 | − __builtin_prefetch(ptr, 1, 3); | |
| 71 | −} | |
| 72 | −#endif | |
| 73 | − | |
| 74 | 61 | #endif /* __ASM_ALPHA_PROCESSOR_H */ |
| @@ -385,8 +385,7 @@ setup_memory(void *kernel_end) · 384 unmodified lines | ||
| 385 | 385 | #endif /* CONFIG_BLK_DEV_INITRD */ |
| 386 | 386 | } |
| 387 | 387 | |
| 388 | −int __init | |
| 389 | −page_is_ram(unsigned long pfn) | |
| 388 | +int page_is_ram(unsigned long pfn) | |
| 390 | 389 | { |
| 391 | 390 | struct memclust_struct * cluster; |
| 392 | 391 | struct memdesc_struct * memdesc; |
| @@ -172,7 +172,7 @@ · 171 unmodified lines | ||
| 172 | 172 | status = "disabled"; |
| 173 | 173 | |
| 174 | 174 | uart4: serial@200 { |
| 175 | − compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; | |
| 175 | + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; | |
| 176 | 176 | reg = <0x200 0x200>; |
| 177 | 177 | interrupts = <13 IRQ_TYPE_LEVEL_HIGH 7>; |
| 178 | 178 | dmas = <&dma0 |
| @@ -240,7 +240,7 @@ · 61 unmodified lines | ||
| 240 | 240 | status = "disabled"; |
| 241 | 241 | |
| 242 | 242 | uart5: serial@200 { |
| 243 | − compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; | |
| 243 | + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; | |
| 244 | 244 | reg = <0x200 0x200>; |
| 245 | 245 | atmel,usart-mode = <AT91_USART_MODE_SERIAL>; |
| 246 | 246 | interrupts = <14 IRQ_TYPE_LEVEL_HIGH 7>; |
| @@ -370,7 +370,7 @@ · 123 unmodified lines | ||
| 370 | 370 | status = "disabled"; |
| 371 | 371 | |
| 372 | 372 | uart11: serial@200 { |
| 373 | − compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; | |
| 373 | + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; | |
| 374 | 374 | reg = <0x200 0x200>; |
| 375 | 375 | interrupts = <32 IRQ_TYPE_LEVEL_HIGH 7>; |
| 376 | 376 | dmas = <&dma0 |
| @@ -419,7 +419,7 @@ · 42 unmodified lines | ||
| 419 | 419 | status = "disabled"; |
| 420 | 420 | |
| 421 | 421 | uart12: serial@200 { |
| 422 | − compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; | |
| 422 | + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; | |
| 423 | 423 | reg = <0x200 0x200>; |
| 424 | 424 | interrupts = <33 IRQ_TYPE_LEVEL_HIGH 7>; |
| 425 | 425 | dmas = <&dma0 |
| @@ -576,7 +576,7 @@ · 150 unmodified lines | ||
| 576 | 576 | status = "disabled"; |
| 577 | 577 | |
| 578 | 578 | uart6: serial@200 { |
| 579 | − compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; | |
| 579 | + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; | |
| 580 | 580 | reg = <0x200 0x200>; |
| 581 | 581 | interrupts = <9 IRQ_TYPE_LEVEL_HIGH 7>; |
| 582 | 582 | dmas = <&dma0 |
| @@ -625,7 +625,7 @@ · 42 unmodified lines | ||
| 625 | 625 | status = "disabled"; |
| 626 | 626 | |
| 627 | 627 | uart7: serial@200 { |
| 628 | − compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; | |
| 628 | + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; | |
| 629 | 629 | reg = <0x200 0x200>; |
| 630 | 630 | interrupts = <10 IRQ_TYPE_LEVEL_HIGH 7>; |
| 631 | 631 | dmas = <&dma0 |
| @@ -674,7 +674,7 @@ · 42 unmodified lines | ||
| 674 | 674 | status = "disabled"; |
| 675 | 675 | |
| 676 | 676 | uart8: serial@200 { |
| 677 | − compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; | |
| 677 | + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; | |
| 678 | 678 | reg = <0x200 0x200>; |
| 679 | 679 | interrupts = <11 IRQ_TYPE_LEVEL_HIGH 7>; |
| 680 | 680 | dmas = <&dma0 |
| @@ -723,7 +723,7 @@ · 42 unmodified lines | ||
| 723 | 723 | status = "disabled"; |
| 724 | 724 | |
| 725 | 725 | uart0: serial@200 { |
| 726 | − compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; | |
| 726 | + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; | |
| 727 | 727 | reg = <0x200 0x200>; |
| 728 | 728 | interrupts = <5 IRQ_TYPE_LEVEL_HIGH 7>; |
| 729 | 729 | dmas = <&dma0 |
| @@ -791,7 +791,7 @@ · 61 unmodified lines | ||
| 791 | 791 | status = "disabled"; |
| 792 | 792 | |
| 793 | 793 | uart1: serial@200 { |
| 794 | − compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; | |
| 794 | + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; | |
| 795 | 795 | reg = <0x200 0x200>; |
| 796 | 796 | interrupts = <6 IRQ_TYPE_LEVEL_HIGH 7>; |
| 797 | 797 | dmas = <&dma0 |
| @@ -859,7 +859,7 @@ · 61 unmodified lines | ||
| 859 | 859 | status = "disabled"; |
| 860 | 860 | |
| 861 | 861 | uart2: serial@200 { |
| 862 | − compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; | |
| 862 | + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; | |
| 863 | 863 | reg = <0x200 0x200>; |
| 864 | 864 | interrupts = <7 IRQ_TYPE_LEVEL_HIGH 7>; |
| 865 | 865 | dmas = <&dma0 |
| @@ -927,7 +927,7 @@ · 61 unmodified lines | ||
| 927 | 927 | status = "disabled"; |
| 928 | 928 | |
| 929 | 929 | uart3: serial@200 { |
| 930 | − compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; | |
| 930 | + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; | |
| 931 | 931 | reg = <0x200 0x200>; |
| 932 | 932 | interrupts = <8 IRQ_TYPE_LEVEL_HIGH 7>; |
| 933 | 933 | dmas = <&dma0 |
| @@ -1050,7 +1050,7 @@ · 116 unmodified lines | ||
| 1050 | 1050 | status = "disabled"; |
| 1051 | 1051 | |
| 1052 | 1052 | uart9: serial@200 { |
| 1053 | − compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; | |
| 1053 | + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; | |
| 1054 | 1054 | reg = <0x200 0x200>; |
| 1055 | 1055 | interrupts = <15 IRQ_TYPE_LEVEL_HIGH 7>; |
| 1056 | 1056 | dmas = <&dma0 |
| @@ -1099,7 +1099,7 @@ · 42 unmodified lines | ||
| 1099 | 1099 | status = "disabled"; |
| 1100 | 1100 | |
| 1101 | 1101 | uart10: serial@200 { |
| 1102 | − compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; | |
| 1102 | + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; | |
| 1103 | 1103 | reg = <0x200 0x200>; |
| 1104 | 1104 | interrupts = <16 IRQ_TYPE_LEVEL_HIGH 7>; |
| 1105 | 1105 | dmas = <&dma0 |
| @@ -161,7 +161,7 @@ · 160 unmodified lines | ||
| 161 | 161 | }; |
| 162 | 162 | |
| 163 | 163 | watchdog: watchdog@90060000 { |
| 164 | − compatible = "arm,amba-primecell"; | |
| 164 | + compatible = "arm,primecell"; | |
| 165 | 165 | reg = <0x90060000 0x1000>; |
| 166 | 166 | interrupts = <3>; |
| 167 | 167 | }; |
| @@ -60,6 +60,16 @@ · 59 unmodified lines | ||
| 60 | 60 | status = "okay"; |
| 61 | 61 | }; |
| 62 | 62 | |
| 63 | +&cpu0 { | |
| 64 | + /* CPU rated to 800 MHz, not the default 1.2GHz. */ | |
| 65 | + operating-points = < | |
| 66 | + /* kHz uV */ | |
| 67 | + 166666 850000 | |
| 68 | + 400000 900000 | |
| 69 | + 800000 1050000 | |
| 70 | + >; | |
| 71 | +}; | |
| 72 | + | |
| 63 | 73 | &ecspi1 { |
| 64 | 74 | pinctrl-names = "default"; |
| 65 | 75 | pinctrl-0 = <&pinctrl_ecspi1>; |
| @@ -552,7 +552,7 @@ · 551 unmodified lines | ||
| 552 | 552 | reg = <0x020ca000 0x1000>; |
| 553 | 553 | interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; |
| 554 | 554 | clocks = <&clks IMX6SLL_CLK_USBPHY2>; |
| 555 | − phy-reg_3p0-supply = <®_3p0>; | |
| 555 | + phy-3p0-supply = <®_3p0>; | |
| 556 | 556 | fsl,anatop = <&anatop>; |
| 557 | 557 | }; |
| 558 | 558 | |
| @@ -197,7 +197,7 @@ CONFIG_EXT2_FS=y · 196 unmodified lines | ||
| 197 | 197 | CONFIG_EXT3_FS=y |
| 198 | 198 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
| 199 | 199 | CONFIG_EXT4_FS=y |
| 200 | −CONFIG_AUTOFS4_FS=y | |
| 200 | +CONFIG_AUTOFS_FS=y | |
| 201 | 201 | CONFIG_FUSE_FS=y |
| 202 | 202 | CONFIG_CUSE=y |
| 203 | 203 | CONFIG_FSCACHE=y |
| @@ -232,7 +232,7 @@ CONFIG_EXT2_FS=y · 231 unmodified lines | ||
| 232 | 232 | CONFIG_EXT3_FS=y |
| 233 | 233 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 234 | 234 | CONFIG_XFS_FS=m |
| 235 | −CONFIG_AUTOFS4_FS=m | |
| 235 | +CONFIG_AUTOFS_FS=m | |
| 236 | 236 | CONFIG_MSDOS_FS=y |
| 237 | 237 | CONFIG_VFAT_FS=y |
| 238 | 238 | CONFIG_TMPFS=y |
| @@ -327,7 +327,7 @@ CONFIG_PWM_SAMSUNG=y · 326 unmodified lines | ||
| 327 | 327 | CONFIG_PHY_EXYNOS5250_SATA=y |
| 328 | 328 | CONFIG_EXT2_FS=y |
| 329 | 329 | CONFIG_EXT4_FS=y |
| 330 | −CONFIG_AUTOFS4_FS=y | |
| 330 | +CONFIG_AUTOFS_FS=y | |
| 331 | 331 | CONFIG_MSDOS_FS=y |
| 332 | 332 | CONFIG_VFAT_FS=y |
| 333 | 333 | CONFIG_TMPFS=y |
| @@ -94,7 +94,7 @@ CONFIG_LEDS_CLASS=y · 93 unmodified lines | ||
| 94 | 94 | CONFIG_LEDS_TRIGGERS=y |
| 95 | 95 | CONFIG_LEDS_TRIGGER_TIMER=y |
| 96 | 96 | CONFIG_EXT2_FS=y |
| 97 | −CONFIG_AUTOFS4_FS=y | |
| 97 | +CONFIG_AUTOFS_FS=y | |
| 98 | 98 | CONFIG_ISO9660_FS=m |
| 99 | 99 | CONFIG_JOLIET=y |
| 100 | 100 | CONFIG_MSDOS_FS=m |
| @@ -442,7 +442,7 @@ CONFIG_EXT3_FS_SECURITY=y · 441 unmodified lines | ||
| 442 | 442 | CONFIG_QUOTA=y |
| 443 | 443 | CONFIG_QUOTA_NETLINK_INTERFACE=y |
| 444 | 444 | # CONFIG_PRINT_QUOTA_WARNING is not set |
| 445 | −CONFIG_AUTOFS4_FS=y | |
| 445 | +CONFIG_AUTOFS_FS=y | |
| 446 | 446 | CONFIG_FUSE_FS=y |
| 447 | 447 | CONFIG_ISO9660_FS=m |
| 448 | 448 | CONFIG_JOLIET=y |
| @@ -207,7 +207,7 @@ CONFIG_RESET_TI_SYSCON=m · 206 unmodified lines | ||
| 207 | 207 | CONFIG_EXT4_FS=y |
| 208 | 208 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 209 | 209 | CONFIG_FANOTIFY=y |
| 210 | −CONFIG_AUTOFS4_FS=y | |
| 210 | +CONFIG_AUTOFS_FS=y | |
| 211 | 211 | CONFIG_MSDOS_FS=y |
| 212 | 212 | CONFIG_VFAT_FS=y |
| 213 | 213 | CONFIG_NTFS_FS=y |
| @@ -162,7 +162,7 @@ CONFIG_MAX517=y · 161 unmodified lines | ||
| 162 | 162 | CONFIG_PWM=y |
| 163 | 163 | CONFIG_PWM_LPC32XX=y |
| 164 | 164 | CONFIG_EXT2_FS=y |
| 165 | −CONFIG_AUTOFS4_FS=y | |
| 165 | +CONFIG_AUTOFS_FS=y | |
| 166 | 166 | CONFIG_MSDOS_FS=y |
| 167 | 167 | CONFIG_VFAT_FS=y |
| 168 | 168 | CONFIG_TMPFS=y |
| @@ -81,7 +81,7 @@ CONFIG_SOC_BRCMSTB=y · 80 unmodified lines | ||
| 81 | 81 | CONFIG_MEMORY=y |
| 82 | 82 | # CONFIG_ARM_PMU is not set |
| 83 | 83 | CONFIG_EXT4_FS=y |
| 84 | −CONFIG_AUTOFS4_FS=y | |
| 84 | +CONFIG_AUTOFS_FS=y | |
| 85 | 85 | CONFIG_MSDOS_FS=y |
| 86 | 86 | CONFIG_VFAT_FS=y |
| 87 | 87 | CONFIG_NTFS_FS=y |
| @@ -1226,7 +1226,7 @@ CONFIG_COUNTER=m · 1225 unmodified lines | ||
| 1226 | 1226 | CONFIG_STM32_TIMER_CNT=m |
| 1227 | 1227 | CONFIG_STM32_LPTIMER_CNT=m |
| 1228 | 1228 | CONFIG_EXT4_FS=y |
| 1229 | −CONFIG_AUTOFS4_FS=y | |
| 1229 | +CONFIG_AUTOFS_FS=y | |
| 1230 | 1230 | CONFIG_MSDOS_FS=y |
| 1231 | 1231 | CONFIG_VFAT_FS=y |
| 1232 | 1232 | CONFIG_NTFS_FS=y |
| @@ -188,7 +188,7 @@ CONFIG_RTC_DRV_OMAP=y · 187 unmodified lines | ||
| 188 | 188 | CONFIG_EXT2_FS=y |
| 189 | 189 | CONFIG_EXT3_FS=y |
| 190 | 190 | # CONFIG_DNOTIFY is not set |
| 191 | −CONFIG_AUTOFS4_FS=y | |
| 191 | +CONFIG_AUTOFS_FS=y | |
| 192 | 192 | CONFIG_ISO9660_FS=y |
| 193 | 193 | CONFIG_JOLIET=y |
| 194 | 194 | CONFIG_MSDOS_FS=y |
| @@ -678,7 +678,7 @@ CONFIG_EXT4_FS_SECURITY=y · 677 unmodified lines | ||
| 678 | 678 | CONFIG_FANOTIFY=y |
| 679 | 679 | CONFIG_QUOTA=y |
| 680 | 680 | CONFIG_QFMT_V2=y |
| 681 | −CONFIG_AUTOFS4_FS=m | |
| 681 | +CONFIG_AUTOFS_FS=m | |
| 682 | 682 | CONFIG_MSDOS_FS=y |
| 683 | 683 | CONFIG_VFAT_FS=y |
| 684 | 684 | CONFIG_TMPFS=y |
| @@ -589,7 +589,7 @@ CONFIG_REISERFS_FS_XATTR=y · 588 unmodified lines | ||
| 589 | 589 | CONFIG_REISERFS_FS_POSIX_ACL=y |
| 590 | 590 | CONFIG_REISERFS_FS_SECURITY=y |
| 591 | 591 | CONFIG_XFS_FS=m |
| 592 | −CONFIG_AUTOFS4_FS=m | |
| 592 | +CONFIG_AUTOFS_FS=m | |
| 593 | 593 | CONFIG_FUSE_FS=m |
| 594 | 594 | CONFIG_CUSE=m |
| 595 | 595 | CONFIG_FSCACHE=y |
| @@ -79,7 +79,7 @@ CONFIG_RTC_CLASS=y · 78 unmodified lines | ||
| 79 | 79 | CONFIG_RTC_DRV_PCF8583=y |
| 80 | 80 | CONFIG_EXT2_FS=y |
| 81 | 81 | CONFIG_EXT3_FS=y |
| 82 | −CONFIG_AUTOFS4_FS=m | |
| 82 | +CONFIG_AUTOFS_FS=m | |
| 83 | 83 | CONFIG_ISO9660_FS=y |
| 84 | 84 | CONFIG_JOLIET=y |
| 85 | 85 | CONFIG_MSDOS_FS=m |
| @@ -103,7 +103,7 @@ CONFIG_PHY_SAMSUNG_USB2=m · 102 unmodified lines | ||
| 103 | 103 | CONFIG_PHY_S5PV210_USB2=y |
| 104 | 104 | CONFIG_EXT2_FS=y |
| 105 | 105 | CONFIG_EXT4_FS=y |
| 106 | −CONFIG_AUTOFS4_FS=y | |
| 106 | +CONFIG_AUTOFS_FS=y | |
| 107 | 107 | CONFIG_MSDOS_FS=y |
| 108 | 108 | CONFIG_VFAT_FS=y |
| 109 | 109 | CONFIG_TMPFS=y |
| @@ -136,7 +136,7 @@ CONFIG_EXT2_FS=y · 135 unmodified lines | ||
| 136 | 136 | CONFIG_EXT2_FS_XATTR=y |
| 137 | 137 | CONFIG_EXT2_FS_POSIX_ACL=y |
| 138 | 138 | CONFIG_EXT3_FS=y |
| 139 | −CONFIG_AUTOFS4_FS=y | |
| 139 | +CONFIG_AUTOFS_FS=y | |
| 140 | 140 | CONFIG_VFAT_FS=y |
| 141 | 141 | CONFIG_NTFS_FS=y |
| 142 | 142 | CONFIG_NTFS_RW=y |
| @@ -85,7 +85,7 @@ CONFIG_EXT2_FS_XATTR=y · 84 unmodified lines | ||
| 85 | 85 | CONFIG_EXT2_FS_SECURITY=y |
| 86 | 86 | CONFIG_EXT3_FS=y |
| 87 | 87 | CONFIG_EXT3_FS_SECURITY=y |
| 88 | −CONFIG_AUTOFS4_FS=m | |
| 88 | +CONFIG_AUTOFS_FS=m | |
| 89 | 89 | CONFIG_FUSE_FS=y |
| 90 | 90 | CONFIG_MSDOS_FS=m |
| 91 | 91 | CONFIG_VFAT_FS=m |
| @@ -68,7 +68,7 @@ CONFIG_EXT2_FS_XATTR=y · 67 unmodified lines | ||
| 68 | 68 | CONFIG_EXT2_FS_SECURITY=y |
| 69 | 69 | CONFIG_EXT3_FS=y |
| 70 | 70 | CONFIG_EXT3_FS_SECURITY=y |
| 71 | −CONFIG_AUTOFS4_FS=m | |
| 71 | +CONFIG_AUTOFS_FS=m | |
| 72 | 72 | CONFIG_MSDOS_FS=m |
| 73 | 73 | CONFIG_VFAT_FS=m |
| 74 | 74 | CONFIG_FAT_DEFAULT_IOCHARSET="ascii" |
| @@ -54,7 +54,7 @@ CONFIG_EXT2_FS_XATTR=y · 53 unmodified lines | ||
| 54 | 54 | CONFIG_EXT2_FS_SECURITY=y |
| 55 | 55 | CONFIG_EXT3_FS=y |
| 56 | 56 | CONFIG_EXT3_FS_SECURITY=y |
| 57 | −CONFIG_AUTOFS4_FS=m | |
| 57 | +CONFIG_AUTOFS_FS=m | |
| 58 | 58 | CONFIG_MSDOS_FS=m |
| 59 | 59 | CONFIG_VFAT_FS=m |
| 60 | 60 | CONFIG_FAT_DEFAULT_IOCHARSET="ascii" |
| @@ -105,5 +105,4 @@ void sharpsl_pm_led(int val); · 104 unmodified lines | ||
| 105 | 105 | #define MAX1111_ACIN_VOLT 6u |
| 106 | 106 | int sharpsl_pm_pxa_read_max1111(int channel); |
| 107 | 107 | |
| 108 | −void corgi_lcd_limit_intensity(int limit); | |
| 109 | 108 | #endif |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/interrupt.h> |
| 16 | 16 | #include <linux/platform_device.h> |
| 17 | 17 | #include <linux/apm-emulation.h> |
| 18 | +#include <linux/spi/corgi_lcd.h> | |
| 18 | 19 | |
| 19 | 20 | #include <asm/irq.h> |
| 20 | 21 | #include <asm/mach-types.h> |
| @@ -145,7 +145,7 @@ · 144 unmodified lines | ||
| 145 | 145 | status = "okay"; |
| 146 | 146 | clock-frequency = <100000>; |
| 147 | 147 | i2c-sda-falling-time-ns = <890>; /* hcnt */ |
| 148 | − i2c-sdl-falling-time-ns = <890>; /* lcnt */ | |
| 148 | + i2c-scl-falling-time-ns = <890>; /* lcnt */ | |
| 149 | 149 | |
| 150 | 150 | pinctrl-names = "default", "gpio"; |
| 151 | 151 | pinctrl-0 = <&i2c1_pmx_func>; |
| @@ -141,7 +141,7 @@ · 140 unmodified lines | ||
| 141 | 141 | status = "okay"; |
| 142 | 142 | clock-frequency = <100000>; |
| 143 | 143 | i2c-sda-falling-time-ns = <890>; /* hcnt */ |
| 144 | − i2c-sdl-falling-time-ns = <890>; /* lcnt */ | |
| 144 | + i2c-scl-falling-time-ns = <890>; /* lcnt */ | |
| 145 | 145 | |
| 146 | 146 | adc@14 { |
| 147 | 147 | compatible = "lltc,ltc2497"; |
| @@ -1 +0,0 @@ | ||
| 1 | −../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi | |
| @@ -141,7 +141,7 @@ · 140 unmodified lines | ||
| 141 | 141 | }; |
| 142 | 142 | |
| 143 | 143 | &gpio1 { |
| 144 | − gpio-line-names = "nINT_ETHPHY", "LED_RED", "WDOG_INT", "X_RTC_INT", | |
| 144 | + gpio-line-names = "", "LED_RED", "WDOG_INT", "X_RTC_INT", | |
| 145 | 145 | "", "", "", "RESET_ETHPHY", |
| 146 | 146 | "CAN_nINT", "CAN_EN", "nENABLE_FLATLINK", "", |
| 147 | 147 | "USB_OTG_VBUS_EN", "", "LED_GREEN", "LED_BLUE"; |
| @@ -111,7 +111,7 @@ · 110 unmodified lines | ||
| 111 | 111 | }; |
| 112 | 112 | |
| 113 | 113 | &gpio1 { |
| 114 | − gpio-line-names = "nINT_ETHPHY", "", "WDOG_INT", "X_RTC_INT", | |
| 114 | + gpio-line-names = "", "", "WDOG_INT", "X_RTC_INT", | |
| 115 | 115 | "", "", "", "RESET_ETHPHY", |
| 116 | 116 | "", "", "nENABLE_FLATLINK"; |
| 117 | 117 | }; |
| @@ -210,7 +210,7 @@ · 92 unmodified lines | ||
| 210 | 210 | }; |
| 211 | 211 | }; |
| 212 | 212 | |
| 213 | − reg_vdd_gpu: buck3 { | |
| 213 | + reg_vdd_vpu: buck3 { | |
| 214 | 214 | regulator-always-on; |
| 215 | 215 | regulator-boot-on; |
| 216 | 216 | regulator-max-microvolt = <1000000>; |
| @@ -567,6 +567,10 @@ · 566 unmodified lines | ||
| 567 | 567 | status = "okay"; |
| 568 | 568 | }; |
| 569 | 569 | |
| 570 | +&disp_blk_ctrl { | |
| 571 | + status = "disabled"; | |
| 572 | +}; | |
| 573 | + | |
| 570 | 574 | &pgc_mipi { |
| 571 | 575 | status = "disabled"; |
| 572 | 576 | }; |
| @@ -628,6 +628,10 @@ · 627 unmodified lines | ||
| 628 | 628 | status = "okay"; |
| 629 | 629 | }; |
| 630 | 630 | |
| 631 | +&disp_blk_ctrl { | |
| 632 | + status = "disabled"; | |
| 633 | +}; | |
| 634 | + | |
| 631 | 635 | &pgc_mipi { |
| 632 | 636 | status = "disabled"; |
| 633 | 637 | }; |
| @@ -358,7 +358,7 @@ · 357 unmodified lines | ||
| 358 | 358 | MX8MN_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 |
| 359 | 359 | MX8MN_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 |
| 360 | 360 | MX8MN_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f |
| 361 | − MX8MN_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19 | |
| 361 | + MX8MN_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x159 | |
| 362 | 362 | >; |
| 363 | 363 | }; |
| 364 | 364 | |
| @@ -772,7 +772,7 @@ · 771 unmodified lines | ||
| 772 | 772 | <&clk IMX8MQ_SYS1_PLL_800M>, |
| 773 | 773 | <&clk IMX8MQ_VPU_PLL>; |
| 774 | 774 | assigned-clock-rates = <600000000>, |
| 775 | − <600000000>, | |
| 775 | + <300000000>, | |
| 776 | 776 | <800000000>, |
| 777 | 777 | <0>; |
| 778 | 778 | }; |
| @@ -223,20 +223,20 @@ · 222 unmodified lines | ||
| 223 | 223 | <GIC_SPI 212 IRQ_TYPE_EDGE_RISING>, |
| 224 | 224 | <GIC_SPI 213 IRQ_TYPE_EDGE_RISING>; |
| 225 | 225 | interrupt-names = "tgia0", "tgib0", "tgic0", "tgid0", |
| 226 | − "tgiv0", "tgie0", "tgif0", | |
| 227 | − "tgia1", "tgib1", "tgiv1", "tgiu1", | |
| 228 | − "tgia2", "tgib2", "tgiv2", "tgiu2", | |
| 226 | + "tciv0", "tgie0", "tgif0", | |
| 227 | + "tgia1", "tgib1", "tciv1", "tciu1", | |
| 228 | + "tgia2", "tgib2", "tciv2", "tciu2", | |
| 229 | 229 | "tgia3", "tgib3", "tgic3", "tgid3", |
| 230 | − "tgiv3", | |
| 230 | + "tciv3", | |
| 231 | 231 | "tgia4", "tgib4", "tgic4", "tgid4", |
| 232 | − "tgiv4", | |
| 232 | + "tciv4", | |
| 233 | 233 | "tgiu5", "tgiv5", "tgiw5", |
| 234 | 234 | "tgia6", "tgib6", "tgic6", "tgid6", |
| 235 | − "tgiv6", | |
| 235 | + "tciv6", | |
| 236 | 236 | "tgia7", "tgib7", "tgic7", "tgid7", |
| 237 | − "tgiv7", | |
| 237 | + "tciv7", | |
| 238 | 238 | "tgia8", "tgib8", "tgic8", "tgid8", |
| 239 | − "tgiv8", "tgiu8"; | |
| 239 | + "tciv8", "tciu8"; | |
| 240 | 240 | clocks = <&cpg CPG_MOD R9A07G044_MTU_X_MCK_MTU3>; |
| 241 | 241 | power-domains = <&cpg>; |
| 242 | 242 | resets = <&cpg R9A07G044_MTU_X_PRESET_MTU3>; |
| @@ -223,20 +223,20 @@ · 222 unmodified lines | ||
| 223 | 223 | <GIC_SPI 212 IRQ_TYPE_EDGE_RISING>, |
| 224 | 224 | <GIC_SPI 213 IRQ_TYPE_EDGE_RISING>; |
| 225 | 225 | interrupt-names = "tgia0", "tgib0", "tgic0", "tgid0", |
| 226 | − "tgiv0", "tgie0", "tgif0", | |
| 227 | − "tgia1", "tgib1", "tgiv1", "tgiu1", | |
| 228 | − "tgia2", "tgib2", "tgiv2", "tgiu2", | |
| 226 | + "tciv0", "tgie0", "tgif0", | |
| 227 | + "tgia1", "tgib1", "tciv1", "tciu1", | |
| 228 | + "tgia2", "tgib2", "tciv2", "tciu2", | |
| 229 | 229 | "tgia3", "tgib3", "tgic3", "tgid3", |
| 230 | − "tgiv3", | |
| 230 | + "tciv3", | |
| 231 | 231 | "tgia4", "tgib4", "tgic4", "tgid4", |
| 232 | − "tgiv4", | |
| 232 | + "tciv4", | |
| 233 | 233 | "tgiu5", "tgiv5", "tgiw5", |
| 234 | 234 | "tgia6", "tgib6", "tgic6", "tgid6", |
| 235 | − "tgiv6", | |
| 235 | + "tciv6", | |
| 236 | 236 | "tgia7", "tgib7", "tgic7", "tgid7", |
| 237 | − "tgiv7", | |
| 237 | + "tciv7", | |
| 238 | 238 | "tgia8", "tgib8", "tgic8", "tgid8", |
| 239 | − "tgiv8", "tgiu8"; | |
| 239 | + "tciv8", "tciu8"; | |
| 240 | 240 | clocks = <&cpg CPG_MOD R9A07G054_MTU_X_MCK_MTU3>; |
| 241 | 241 | power-domains = <&cpg>; |
| 242 | 242 | resets = <&cpg R9A07G054_MTU_X_PRESET_MTU3>; |
| @@ -1469,7 +1469,7 @@ CONFIG_BTRFS_FS_POSIX_ACL=y · 1468 unmodified lines | ||
| 1469 | 1469 | CONFIG_FANOTIFY=y |
| 1470 | 1470 | CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y |
| 1471 | 1471 | CONFIG_QUOTA=y |
| 1472 | −CONFIG_AUTOFS4_FS=y | |
| 1472 | +CONFIG_AUTOFS_FS=y | |
| 1473 | 1473 | CONFIG_FUSE_FS=m |
| 1474 | 1474 | CONFIG_CUSE=m |
| 1475 | 1475 | CONFIG_OVERLAY_FS=m |
| @@ -31,6 +31,13 @@ · 30 unmodified lines | ||
| 31 | 31 | .Lskip_hcrx_\@: |
| 32 | 32 | .endm |
| 33 | 33 | |
| 34 | +/* Check if running in host at EL2 mode, i.e., (h)VHE. Jump to fail if not. */ | |
| 35 | +.macro __check_hvhe fail, tmp | |
| 36 | + mrs \tmp, hcr_el2 | |
| 37 | + and \tmp, \tmp, #HCR_E2H | |
| 38 | + cbz \tmp, \fail | |
| 39 | +.endm | |
| 40 | + | |
| 34 | 41 | /* |
| 35 | 42 | * Allow Non-secure EL1 and EL0 to access physical timer and counter. |
| 36 | 43 | * This is not necessary for VHE, since the host kernel runs in EL2, |
| @@ -43,9 +50,7 @@ · 6 unmodified lines | ||
| 43 | 50 | */ |
| 44 | 51 | .macro __init_el2_timers |
| 45 | 52 | mov x0, #3 // Enable EL1 physical timers |
| 46 | − mrs x1, hcr_el2 | |
| 47 | − and x1, x1, #HCR_E2H | |
| 48 | − cbz x1, .LnVHE_\@ | |
| 53 | + __check_hvhe .LnVHE_\@, x1 | |
| 49 | 54 | lsl x0, x0, #10 |
| 50 | 55 | .LnVHE_\@: |
| 51 | 56 | msr cnthctl_el2, x0 |
| @@ -139,15 +144,14 @@ · 87 unmodified lines | ||
| 139 | 144 | |
| 140 | 145 | /* Coprocessor traps */ |
| 141 | 146 | .macro __init_el2_cptr |
| 142 | − mrs x1, hcr_el2 | |
| 143 | − and x1, x1, #HCR_E2H | |
| 144 | − cbz x1, .LnVHE_\@ | |
| 147 | + __check_hvhe .LnVHE_\@, x1 | |
| 145 | 148 | mov x0, #(CPACR_EL1_FPEN_EL1EN | CPACR_EL1_FPEN_EL0EN) |
| 146 | − b .Lset_cptr_\@ | |
| 149 | + msr cpacr_el1, x0 | |
| 150 | + b .Lskip_set_cptr_\@ | |
| 147 | 151 | .LnVHE_\@: |
| 148 | 152 | mov x0, #0x33ff |
| 149 | −.Lset_cptr_\@: | |
| 150 | 153 | msr cptr_el2, x0 // Disable copro. traps to EL2 |
| 154 | +.Lskip_set_cptr_\@: | |
| 151 | 155 | .endm |
| 152 | 156 | |
| 153 | 157 | /* Disable any fine grained traps */ |
| @@ -268,19 +272,19 @@ · 114 unmodified lines | ||
| 268 | 272 | check_override id_aa64pfr0, ID_AA64PFR0_EL1_SVE_SHIFT, .Linit_sve_\@, .Lskip_sve_\@, x1, x2 |
| 269 | 273 | |
| 270 | 274 | .Linit_sve_\@: /* SVE register access */ |
| 271 | − mrs x0, cptr_el2 // Disable SVE traps | |
| 272 | − mrs x1, hcr_el2 | |
| 273 | − and x1, x1, #HCR_E2H | |
| 274 | − cbz x1, .Lcptr_nvhe_\@ | |
| 275 | + __check_hvhe .Lcptr_nvhe_\@, x1 | |
| 275 | 276 | |
| 276 | − // VHE case | |
| 277 | + // (h)VHE case | |
| 278 | + mrs x0, cpacr_el1 // Disable SVE traps | |
| 277 | 279 | orr x0, x0, #(CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN) |
| 278 | − b .Lset_cptr_\@ | |
| 280 | + msr cpacr_el1, x0 | |
| 281 | + b .Lskip_set_cptr_\@ | |
| 279 | 282 | |
| 280 | 283 | .Lcptr_nvhe_\@: // nVHE case |
| 284 | + mrs x0, cptr_el2 // Disable SVE traps | |
| 281 | 285 | bic x0, x0, #CPTR_EL2_TZ |
| 282 | −.Lset_cptr_\@: | |
| 283 | 286 | msr cptr_el2, x0 |
| 287 | +.Lskip_set_cptr_\@: | |
| 284 | 288 | isb |
| 285 | 289 | mov x1, #ZCR_ELx_LEN_MASK // SVE: Enable full vector |
| 286 | 290 | msr_s SYS_ZCR_EL2, x1 // length for EL1. |
| @@ -289,9 +293,19 @@ · 2 unmodified lines | ||
| 289 | 293 | check_override id_aa64pfr1, ID_AA64PFR1_EL1_SME_SHIFT, .Linit_sme_\@, .Lskip_sme_\@, x1, x2 |
| 290 | 294 | |
| 291 | 295 | .Linit_sme_\@: /* SME register access and priority mapping */ |
| 296 | + __check_hvhe .Lcptr_nvhe_sme_\@, x1 | |
| 297 | + | |
| 298 | + // (h)VHE case | |
| 299 | + mrs x0, cpacr_el1 // Disable SME traps | |
| 300 | + orr x0, x0, #(CPACR_EL1_SMEN_EL0EN | CPACR_EL1_SMEN_EL1EN) | |
| 301 | + msr cpacr_el1, x0 | |
| 302 | + b .Lskip_set_cptr_sme_\@ | |
| 303 | + | |
| 304 | +.Lcptr_nvhe_sme_\@: // nVHE case | |
| 292 | 305 | mrs x0, cptr_el2 // Disable SME traps |
| 293 | 306 | bic x0, x0, #CPTR_EL2_TSM |
| 294 | 307 | msr cptr_el2, x0 |
| 308 | +.Lskip_set_cptr_sme_\@: | |
| 295 | 309 | isb |
| 296 | 310 | |
| 297 | 311 | mrs x1, sctlr_el2 |
| @@ -278,7 +278,7 @@ asmlinkage void __noreturn hyp_panic_bad_stack(void); · 277 unmodified lines | ||
| 278 | 278 | asmlinkage void kvm_unexpected_el2_exception(void); |
| 279 | 279 | struct kvm_cpu_context; |
| 280 | 280 | void handle_trap(struct kvm_cpu_context *host_ctxt); |
| 281 | −asmlinkage void __noreturn kvm_host_psci_cpu_entry(bool is_cpu_on); | |
| 281 | +asmlinkage void __noreturn __kvm_host_psci_cpu_entry(bool is_cpu_on); | |
| 282 | 282 | void __noreturn __pkvm_init_finalise(void); |
| 283 | 283 | void kvm_nvhe_prepare_backtrace(unsigned long fp, unsigned long pc); |
| 284 | 284 | void kvm_patch_vector_branch(struct alt_instr *alt, |
| @@ -571,6 +571,14 @@ static inline bool vcpu_has_feature(struct kvm_vcpu *vcpu, int feature) · 570 unmodified lines | ||
| 571 | 571 | return test_bit(feature, vcpu->arch.features); |
| 572 | 572 | } |
| 573 | 573 | |
| 574 | +static __always_inline void kvm_write_cptr_el2(u64 val) | |
| 575 | +{ | |
| 576 | + if (has_vhe() || has_hvhe()) | |
| 577 | + write_sysreg(val, cpacr_el1); | |
| 578 | + else | |
| 579 | + write_sysreg(val, cptr_el2); | |
| 580 | +} | |
| 581 | + | |
| 574 | 582 | static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu) |
| 575 | 583 | { |
| 576 | 584 | u64 val; |
| @@ -578,8 +586,16 @@ static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu) · 1 unmodified line | ||
| 578 | 586 | if (has_vhe()) { |
| 579 | 587 | val = (CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN | |
| 580 | 588 | CPACR_EL1_ZEN_EL1EN); |
| 589 | + if (cpus_have_final_cap(ARM64_SME)) | |
| 590 | + val |= CPACR_EL1_SMEN_EL1EN; | |
| 581 | 591 | } else if (has_hvhe()) { |
| 582 | 592 | val = (CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN); |
| 593 | + | |
| 594 | + if (!vcpu_has_sve(vcpu) || | |
| 595 | + (vcpu->arch.fp_state != FP_STATE_GUEST_OWNED)) | |
| 596 | + val |= CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN; | |
| 597 | + if (cpus_have_final_cap(ARM64_SME)) | |
| 598 | + val |= CPACR_EL1_SMEN_EL1EN | CPACR_EL1_SMEN_EL0EN; | |
| 583 | 599 | } else { |
| 584 | 600 | val = CPTR_NVHE_EL2_RES1; |
| 585 | 601 | |
| @@ -597,9 +613,6 @@ static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu) · 11 unmodified lines | ||
| 597 | 613 | { |
| 598 | 614 | u64 val = kvm_get_reset_cptr_el2(vcpu); |
| 599 | 615 | |
| 600 | − if (has_vhe() || has_hvhe()) | |
| 601 | − write_sysreg(val, cpacr_el1); | |
| 602 | − else | |
| 603 | − write_sysreg(val, cptr_el2); | |
| 616 | + kvm_write_cptr_el2(val); | |
| 604 | 617 | } |
| 605 | 618 | #endif /* __ARM64_KVM_EMULATE_H__ */ |
| @@ -359,14 +359,6 @@ static inline void prefetchw(const void *ptr) · 358 unmodified lines | ||
| 359 | 359 | asm volatile("prfm pstl1keep, %a0\n" : : "p" (ptr)); |
| 360 | 360 | } |
| 361 | 361 | |
| 362 | −#define ARCH_HAS_SPINLOCK_PREFETCH | |
| 363 | −static inline void spin_lock_prefetch(const void *ptr) | |
| 364 | −{ | |
| 365 | − asm volatile(ARM64_LSE_ATOMIC_INSN( | |
| 366 | − "prfm pstl1strm, %a0", | |
| 367 | − "nop") : : "p" (ptr)); | |
| 368 | −} | |
| 369 | − | |
| 370 | 362 | extern unsigned long __ro_after_init signal_minsigstksz; /* sigframe size */ |
| 371 | 363 | extern void __init minsigstksz_setup(void); |
| 372 | 364 | |
| @@ -679,7 +679,7 @@ static void fpsimd_to_sve(struct task_struct *task) · 678 unmodified lines | ||
| 679 | 679 | void *sst = task->thread.sve_state; |
| 680 | 680 | struct user_fpsimd_state const *fst = &task->thread.uw.fpsimd_state; |
| 681 | 681 | |
| 682 | − if (!system_supports_sve()) | |
| 682 | + if (!system_supports_sve() && !system_supports_sme()) | |
| 683 | 683 | return; |
| 684 | 684 | |
| 685 | 685 | vq = sve_vq_from_vl(thread_get_cur_vl(&task->thread)); |
| @@ -705,7 +705,7 @@ static void sve_to_fpsimd(struct task_struct *task) · 19 unmodified lines | ||
| 705 | 705 | unsigned int i; |
| 706 | 706 | __uint128_t const *p; |
| 707 | 707 | |
| 708 | − if (!system_supports_sve()) | |
| 708 | + if (!system_supports_sve() && !system_supports_sme()) | |
| 709 | 709 | return; |
| 710 | 710 | |
| 711 | 711 | vl = thread_get_cur_vl(&task->thread); |
| @@ -835,7 +835,8 @@ void sve_sync_from_fpsimd_zeropad(struct task_struct *task) · 123 unmodified lines | ||
| 835 | 835 | void *sst = task->thread.sve_state; |
| 836 | 836 | struct user_fpsimd_state const *fst = &task->thread.uw.fpsimd_state; |
| 837 | 837 | |
| 838 | − if (!test_tsk_thread_flag(task, TIF_SVE)) | |
| 838 | + if (!test_tsk_thread_flag(task, TIF_SVE) && | |
| 839 | + !thread_sm_enabled(&task->thread)) | |
| 839 | 840 | return; |
| 840 | 841 | |
| 841 | 842 | vq = sve_vq_from_vl(thread_get_cur_vl(&task->thread)); |
| @@ -909,7 +910,7 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type, · 67 unmodified lines | ||
| 909 | 910 | */ |
| 910 | 911 | task->thread.svcr &= ~(SVCR_SM_MASK | |
| 911 | 912 | SVCR_ZA_MASK); |
| 912 | − clear_thread_flag(TIF_SME); | |
| 913 | + clear_tsk_thread_flag(task, TIF_SME); | |
| 913 | 914 | free_sme = true; |
| 914 | 915 | } |
| 915 | 916 | } |
| @@ -917,6 +918,8 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type, · 1 unmodified line | ||
| 917 | 918 | if (task == current) |
| 918 | 919 | put_cpu_fpsimd_context(); |
| 919 | 920 | |
| 921 | + task_set_vl(task, type, vl); | |
| 922 | + | |
| 920 | 923 | /* |
| 921 | 924 | * Free the changed states if they are not in use, SME will be |
| 922 | 925 | * reallocated to the correct size on next use and we just |
| @@ -931,8 +934,6 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type, · 8 unmodified lines | ||
| 931 | 934 | if (free_sme) |
| 932 | 935 | sme_free(task); |
| 933 | 936 | |
| 934 | − task_set_vl(task, type, vl); | |
| 935 | − | |
| 936 | 937 | out: |
| 937 | 938 | update_tsk_thread_flag(task, vec_vl_inherit_flag(type), |
| 938 | 939 | flags & PR_SVE_VL_INHERIT); |
| @@ -1666,7 +1667,6 @@ void fpsimd_flush_thread(void) · 727 unmodified lines | ||
| 1666 | 1667 | |
| 1667 | 1668 | fpsimd_flush_thread_vl(ARM64_VEC_SME); |
| 1668 | 1669 | current->thread.svcr = 0; |
| 1669 | − sme_smstop(); | |
| 1670 | 1670 | } |
| 1671 | 1671 | |
| 1672 | 1672 | current->thread.fp_type = FP_STATE_FPSIMD; |
| @@ -932,11 +932,13 @@ static int sve_set_common(struct task_struct *target, · 931 unmodified lines | ||
| 932 | 932 | /* |
| 933 | 933 | * Ensure target->thread.sve_state is up to date with target's |
| 934 | 934 | * FPSIMD regs, so that a short copyin leaves trailing |
| 935 | − * registers unmodified. Always enable SVE even if going into | |
| 936 | − * streaming mode. | |
| 935 | + * registers unmodified. Only enable SVE if we are | |
| 936 | + * configuring normal SVE, a system with streaming SVE may not | |
| 937 | + * have normal SVE. | |
| 937 | 938 | */ |
| 938 | 939 | fpsimd_sync_to_sve(target); |
| 939 | − set_tsk_thread_flag(target, TIF_SVE); | |
| 940 | + if (type == ARM64_VEC_SVE) | |
| 941 | + set_tsk_thread_flag(target, TIF_SVE); | |
| 940 | 942 | target->thread.fp_type = FP_STATE_SVE; |
| 941 | 943 | |
| 942 | 944 | BUILD_BUG_ON(SVE_PT_SVE_OFFSET != sizeof(header)); |
| @@ -1180,6 +1182,8 @@ static int zt_set(struct task_struct *target, · 237 unmodified lines | ||
| 1180 | 1182 | if (ret == 0) |
| 1181 | 1183 | target->thread.svcr |= SVCR_ZA_MASK; |
| 1182 | 1184 | |
| 1185 | + fpsimd_flush_task_state(target); | |
| 1186 | + | |
| 1183 | 1187 | return ret; |
| 1184 | 1188 | } |
| 1185 | 1189 | |
| @@ -55,7 +55,7 @@ DECLARE_KVM_NVHE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt); · 54 unmodified lines | ||
| 55 | 55 | |
| 56 | 56 | static bool vgic_present, kvm_arm_initialised; |
| 57 | 57 | |
| 58 | −static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled); | |
| 58 | +static DEFINE_PER_CPU(unsigned char, kvm_hyp_initialized); | |
| 59 | 59 | DEFINE_STATIC_KEY_FALSE(userspace_irqchip_in_use); |
| 60 | 60 | |
| 61 | 61 | bool is_kvm_arm_initialised(void) |
| @@ -1864,18 +1864,24 @@ static void cpu_hyp_reinit(void) · 1802 unmodified lines | ||
| 1864 | 1864 | cpu_hyp_init_features(); |
| 1865 | 1865 | } |
| 1866 | 1866 | |
| 1867 | −static void _kvm_arch_hardware_enable(void *discard) | |
| 1867 | +static void cpu_hyp_init(void *discard) | |
| 1868 | 1868 | { |
| 1869 | − if (!__this_cpu_read(kvm_arm_hardware_enabled)) { | |
| 1869 | + if (!__this_cpu_read(kvm_hyp_initialized)) { | |
| 1870 | 1870 | cpu_hyp_reinit(); |
| 1871 | − __this_cpu_write(kvm_arm_hardware_enabled, 1); | |
| 1871 | + __this_cpu_write(kvm_hyp_initialized, 1); | |
| 1872 | 1872 | } |
| 1873 | 1873 | } |
| 1874 | 1874 | |
| 1875 | −int kvm_arch_hardware_enable(void) | |
| 1875 | +static void cpu_hyp_uninit(void *discard) | |
| 1876 | 1876 | { |
| 1877 | − int was_enabled; | |
| 1877 | + if (__this_cpu_read(kvm_hyp_initialized)) { | |
| 1878 | + cpu_hyp_reset(); | |
| 1879 | + __this_cpu_write(kvm_hyp_initialized, 0); | |
| 1880 | + } | |
| 1881 | +} | |
| 1878 | 1882 | |
| 1883 | +int kvm_arch_hardware_enable(void) | |
| 1884 | +{ | |
| 1879 | 1885 | /* |
| 1880 | 1886 | * Most calls to this function are made with migration |
| 1881 | 1887 | * disabled, but not with preemption disabled. The former is |
| @@ -1884,36 +1890,23 @@ int kvm_arch_hardware_enable(void) · 2 unmodified lines | ||
| 1884 | 1890 | */ |
| 1885 | 1891 | preempt_disable(); |
| 1886 | 1892 | |
| 1887 | − was_enabled = __this_cpu_read(kvm_arm_hardware_enabled); | |
| 1888 | − _kvm_arch_hardware_enable(NULL); | |
| 1893 | + cpu_hyp_init(NULL); | |
| 1889 | 1894 | |
| 1890 | − if (!was_enabled) { | |
| 1891 | − kvm_vgic_cpu_up(); | |
| 1892 | − kvm_timer_cpu_up(); | |
| 1893 | − } | |
| 1895 | + kvm_vgic_cpu_up(); | |
| 1896 | + kvm_timer_cpu_up(); | |
| 1894 | 1897 | |
| 1895 | 1898 | preempt_enable(); |
| 1896 | 1899 | |
| 1897 | 1900 | return 0; |
| 1898 | 1901 | } |
| 1899 | 1902 | |
| 1900 | −static void _kvm_arch_hardware_disable(void *discard) | |
| 1901 | −{ | |
| 1902 | − if (__this_cpu_read(kvm_arm_hardware_enabled)) { | |
| 1903 | − cpu_hyp_reset(); | |
| 1904 | − __this_cpu_write(kvm_arm_hardware_enabled, 0); | |
| 1905 | − } | |
| 1906 | −} | |
| 1907 | − | |
| 1908 | 1903 | void kvm_arch_hardware_disable(void) |
| 1909 | 1904 | { |
| 1910 | − if (__this_cpu_read(kvm_arm_hardware_enabled)) { | |
| 1911 | − kvm_timer_cpu_down(); | |
| 1912 | − kvm_vgic_cpu_down(); | |
| 1913 | − } | |
| 1905 | + kvm_timer_cpu_down(); | |
| 1906 | + kvm_vgic_cpu_down(); | |
| 1914 | 1907 | |
| 1915 | 1908 | if (!is_protected_kvm_enabled()) |
| 1916 | − _kvm_arch_hardware_disable(NULL); | |
| 1909 | + cpu_hyp_uninit(NULL); | |
| 1917 | 1910 | } |
| 1918 | 1911 | |
| 1919 | 1912 | #ifdef CONFIG_CPU_PM |
| @@ -1922,16 +1915,16 @@ static int hyp_init_cpu_pm_notifier(struct notifier_block *self, · 2 unmodified lines | ||
| 1922 | 1915 | void *v) |
| 1923 | 1916 | { |
| 1924 | 1917 | /* |
| 1925 | − * kvm_arm_hardware_enabled is left with its old value over | |
| 1918 | + * kvm_hyp_initialized is left with its old value over | |
| 1926 | 1919 | * PM_ENTER->PM_EXIT. It is used to indicate PM_EXIT should |
| 1927 | 1920 | * re-enable hyp. |
| 1928 | 1921 | */ |
| 1929 | 1922 | switch (cmd) { |
| 1930 | 1923 | case CPU_PM_ENTER: |
| 1931 | − if (__this_cpu_read(kvm_arm_hardware_enabled)) | |
| 1924 | + if (__this_cpu_read(kvm_hyp_initialized)) | |
| 1932 | 1925 | /* |
| 1933 | − * don't update kvm_arm_hardware_enabled here | |
| 1934 | − * so that the hardware will be re-enabled | |
| 1926 | + * don't update kvm_hyp_initialized here | |
| 1927 | + * so that the hyp will be re-enabled | |
| 1935 | 1928 | * when we resume. See below. |
| 1936 | 1929 | */ |
| 1937 | 1930 | cpu_hyp_reset(); |
| @@ -1939,8 +1932,8 @@ static int hyp_init_cpu_pm_notifier(struct notifier_block *self, · 1 unmodified line | ||
| 1939 | 1932 | return NOTIFY_OK; |
| 1940 | 1933 | case CPU_PM_ENTER_FAILED: |
| 1941 | 1934 | case CPU_PM_EXIT: |
| 1942 | − if (__this_cpu_read(kvm_arm_hardware_enabled)) | |
| 1943 | − /* The hardware was enabled before suspend. */ | |
| 1935 | + if (__this_cpu_read(kvm_hyp_initialized)) | |
| 1936 | + /* The hyp was enabled before suspend. */ | |
| 1944 | 1937 | cpu_hyp_reinit(); |
| 1945 | 1938 | |
| 1946 | 1939 | return NOTIFY_OK; |
| @@ -2021,7 +2014,7 @@ static int __init init_subsystems(void) · 74 unmodified lines | ||
| 2021 | 2014 | /* |
| 2022 | 2015 | * Enable hardware so that subsystem initialisation can access EL2. |
| 2023 | 2016 | */ |
| 2024 | − on_each_cpu(_kvm_arch_hardware_enable, NULL, 1); | |
| 2017 | + on_each_cpu(cpu_hyp_init, NULL, 1); | |
| 2025 | 2018 | |
| 2026 | 2019 | /* |
| 2027 | 2020 | * Register CPU lower-power notifier |
| @@ -2059,7 +2052,7 @@ out: · 31 unmodified lines | ||
| 2059 | 2052 | hyp_cpu_pm_exit(); |
| 2060 | 2053 | |
| 2061 | 2054 | if (err || !is_protected_kvm_enabled()) |
| 2062 | − on_each_cpu(_kvm_arch_hardware_disable, NULL, 1); | |
| 2055 | + on_each_cpu(cpu_hyp_uninit, NULL, 1); | |
| 2063 | 2056 | |
| 2064 | 2057 | return err; |
| 2065 | 2058 | } |
| @@ -2097,7 +2090,7 @@ static int __init do_pkvm_init(u32 hyp_va_bits) · 31 unmodified lines | ||
| 2097 | 2090 | * The stub hypercalls are now disabled, so set our local flag to |
| 2098 | 2091 | * prevent a later re-init attempt in kvm_arch_hardware_enable(). |
| 2099 | 2092 | */ |
| 2100 | − __this_cpu_write(kvm_arm_hardware_enabled, 1); | |
| 2093 | + __this_cpu_write(kvm_hyp_initialized, 1); | |
| 2101 | 2094 | preempt_enable(); |
| 2102 | 2095 | |
| 2103 | 2096 | return ret; |
| @@ -457,6 +457,7 @@ static bool handle_ampere1_tcr(struct kvm_vcpu *vcpu) · 456 unmodified lines | ||
| 457 | 457 | */ |
| 458 | 458 | val &= ~(TCR_HD | TCR_HA); |
| 459 | 459 | write_sysreg_el1(val, SYS_TCR); |
| 460 | + __kvm_skip_instr(vcpu); | |
| 460 | 461 | return true; |
| 461 | 462 | } |
| 462 | 463 | |
| @@ -705,7 +705,20 @@ int hyp_ffa_init(void *pages) · 704 unmodified lines | ||
| 705 | 705 | if (res.a0 == FFA_RET_NOT_SUPPORTED) |
| 706 | 706 | return 0; |
| 707 | 707 | |
| 708 | − if (res.a0 != FFA_VERSION_1_0) | |
| 708 | + /* | |
| 709 | + * Firmware returns the maximum supported version of the FF-A | |
| 710 | + * implementation. Check that the returned version is | |
| 711 | + * backwards-compatible with the hyp according to the rules in DEN0077A | |
| 712 | + * v1.1 REL0 13.2.1. | |
| 713 | + * | |
| 714 | + * Of course, things are never simple when dealing with firmware. v1.1 | |
| 715 | + * broke ABI with v1.0 on several structures, which is itself | |
| 716 | + * incompatible with the aforementioned versioning scheme. The | |
| 717 | + * expectation is that v1.x implementations that do not support the v1.0 | |
| 718 | + * ABI return NOT_SUPPORTED rather than a version number, according to | |
| 719 | + * DEN0077A v1.1 REL0 18.6.4. | |
| 720 | + */ | |
| 721 | + if (FFA_MAJOR_VERSION(res.a0) != 1) | |
| 709 | 722 | return -EOPNOTSUPP; |
| 710 | 723 | |
| 711 | 724 | arm_smccc_1_1_smc(FFA_ID_GET, 0, 0, 0, 0, 0, 0, 0, &res); |
| @@ -63,7 +63,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu) · 62 unmodified lines | ||
| 63 | 63 | __activate_traps_fpsimd32(vcpu); |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | − write_sysreg(val, cptr_el2); | |
| 66 | + kvm_write_cptr_el2(val); | |
| 67 | 67 | write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2); |
| 68 | 68 | |
| 69 | 69 | if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) { |
| @@ -77,7 +77,7 @@ CONFIG_EXT3_FS=y · 76 unmodified lines | ||
| 77 | 77 | CONFIG_XFS_FS=y |
| 78 | 78 | CONFIG_XFS_QUOTA=y |
| 79 | 79 | CONFIG_XFS_POSIX_ACL=y |
| 80 | −CONFIG_AUTOFS4_FS=m | |
| 80 | +CONFIG_AUTOFS_FS=m | |
| 81 | 81 | CONFIG_ISO9660_FS=m |
| 82 | 82 | CONFIG_JOLIET=y |
| 83 | 83 | CONFIG_UDF_FS=m |
| @@ -146,7 +146,7 @@ CONFIG_REISERFS_FS_XATTR=y · 145 unmodified lines | ||
| 146 | 146 | CONFIG_REISERFS_FS_POSIX_ACL=y |
| 147 | 147 | CONFIG_REISERFS_FS_SECURITY=y |
| 148 | 148 | CONFIG_XFS_FS=y |
| 149 | −CONFIG_AUTOFS4_FS=m | |
| 149 | +CONFIG_AUTOFS_FS=m | |
| 150 | 150 | CONFIG_ISO9660_FS=m |
| 151 | 151 | CONFIG_JOLIET=y |
| 152 | 152 | CONFIG_UDF_FS=m |
| @@ -127,7 +127,7 @@ CONFIG_REISERFS_FS_XATTR=y · 126 unmodified lines | ||
| 127 | 127 | CONFIG_REISERFS_FS_POSIX_ACL=y |
| 128 | 128 | CONFIG_REISERFS_FS_SECURITY=y |
| 129 | 129 | CONFIG_XFS_FS=y |
| 130 | −CONFIG_AUTOFS4_FS=y | |
| 130 | +CONFIG_AUTOFS_FS=y | |
| 131 | 131 | CONFIG_ISO9660_FS=m |
| 132 | 132 | CONFIG_JOLIET=y |
| 133 | 133 | CONFIG_UDF_FS=m |
| @@ -110,7 +110,7 @@ CONFIG_REISERFS_FS_XATTR=y · 109 unmodified lines | ||
| 110 | 110 | CONFIG_REISERFS_FS_POSIX_ACL=y |
| 111 | 111 | CONFIG_REISERFS_FS_SECURITY=y |
| 112 | 112 | CONFIG_XFS_FS=y |
| 113 | −CONFIG_AUTOFS4_FS=y | |
| 113 | +CONFIG_AUTOFS_FS=y | |
| 114 | 114 | CONFIG_ISO9660_FS=m |
| 115 | 115 | CONFIG_JOLIET=y |
| 116 | 116 | CONFIG_UDF_FS=m |
| @@ -634,7 +634,6 @@ ia64_imva (void *addr) · 633 unmodified lines | ||
| 634 | 634 | |
| 635 | 635 | #define ARCH_HAS_PREFETCH |
| 636 | 636 | #define ARCH_HAS_PREFETCHW |
| 637 | −#define ARCH_HAS_SPINLOCK_PREFETCH | |
| 638 | 637 | #define PREFETCH_STRIDE L1_CACHE_BYTES |
| 639 | 638 | |
| 640 | 639 | static inline void |
| @@ -649,8 +648,6 @@ prefetchw (const void *x) · 8 unmodified lines | ||
| 649 | 648 | ia64_lfetch_excl(ia64_lfhint_none, x); |
| 650 | 649 | } |
| 651 | 650 | |
| 652 | −#define spin_lock_prefetch(x) prefetchw(x) | |
| 653 | − | |
| 654 | 651 | extern unsigned long boot_option_idle_override; |
| 655 | 652 | |
| 656 | 653 | enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_FORCE_MWAIT, |
| @@ -14,6 +14,7 @@ config LOONGARCH · 13 unmodified lines | ||
| 14 | 14 | select ARCH_HAS_CPU_FINALIZE_INIT |
| 15 | 15 | select ARCH_HAS_FORTIFY_SOURCE |
| 16 | 16 | select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS |
| 17 | + select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE | |
| 17 | 18 | select ARCH_HAS_PTE_SPECIAL |
| 18 | 19 | select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST |
| 19 | 20 | select ARCH_INLINE_READ_LOCK if !PREEMPTION |
| @@ -68,6 +68,8 @@ LDFLAGS_vmlinux += -static -n -nostdlib · 67 unmodified lines | ||
| 68 | 68 | ifdef CONFIG_AS_HAS_EXPLICIT_RELOCS |
| 69 | 69 | cflags-y += $(call cc-option,-mexplicit-relocs) |
| 70 | 70 | KBUILD_CFLAGS_KERNEL += $(call cc-option,-mdirect-extern-access) |
| 71 | +KBUILD_AFLAGS_MODULE += $(call cc-option,-mno-relax) $(call cc-option,-Wa$(comma)-mno-relax) | |
| 72 | +KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax) $(call cc-option,-Wa$(comma)-mno-relax) | |
| 71 | 73 | else |
| 72 | 74 | cflags-y += $(call cc-option,-mno-explicit-relocs) |
| 73 | 75 | KBUILD_AFLAGS_KERNEL += -Wa,-mla-global-with-pcrel |
| @@ -111,7 +113,7 @@ KBUILD_CFLAGS += -isystem $(shell $(CC) -print-file-name=include) · 37 unmodified lines | ||
| 111 | 113 | |
| 112 | 114 | KBUILD_LDFLAGS += -m $(ld-emul) |
| 113 | 115 | |
| 114 | −ifdef CONFIG_LOONGARCH | |
| 116 | +ifdef need-compiler | |
| 115 | 117 | CHECKFLAGS += $(shell $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ |
| 116 | 118 | grep -E -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \ |
| 117 | 119 | sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g') |
| @@ -769,7 +769,7 @@ CONFIG_QUOTA=y · 768 unmodified lines | ||
| 769 | 769 | # CONFIG_PRINT_QUOTA_WARNING is not set |
| 770 | 770 | CONFIG_QFMT_V1=m |
| 771 | 771 | CONFIG_QFMT_V2=m |
| 772 | −CONFIG_AUTOFS4_FS=y | |
| 772 | +CONFIG_AUTOFS_FS=y | |
| 773 | 773 | CONFIG_FUSE_FS=m |
| 774 | 774 | CONFIG_OVERLAY_FS=y |
| 775 | 775 | CONFIG_OVERLAY_FS_INDEX=y |
| @@ -218,15 +218,8 @@ static inline void restore_lsx(struct task_struct *t) · 217 unmodified lines | ||
| 218 | 218 | |
| 219 | 219 | static inline void init_lsx_upper(void) |
| 220 | 220 | { |
| 221 | − /* | |
| 222 | − * Check cpu_has_lsx only if it's a constant. This will allow the | |
| 223 | − * compiler to optimise out code for CPUs without LSX without adding | |
| 224 | − * an extra redundant check for CPUs with LSX. | |
| 225 | − */ | |
| 226 | − if (__builtin_constant_p(cpu_has_lsx) && !cpu_has_lsx) | |
| 227 | − return; | |
| 228 | − | |
| 229 | − _init_lsx_upper(); | |
| 221 | + if (cpu_has_lsx) | |
| 222 | + _init_lsx_upper(); | |
| 230 | 223 | } |
| 231 | 224 | |
| 232 | 225 | static inline void restore_lsx_upper(struct task_struct *t) |
| @@ -294,7 +287,7 @@ static inline void restore_lasx_upper(struct task_struct *t) {} · 61 unmodified lines | ||
| 294 | 287 | |
| 295 | 288 | static inline int thread_lsx_context_live(void) |
| 296 | 289 | { |
| 297 | − if (__builtin_constant_p(cpu_has_lsx) && !cpu_has_lsx) | |
| 290 | + if (!cpu_has_lsx) | |
| 298 | 291 | return 0; |
| 299 | 292 | |
| 300 | 293 | return test_thread_flag(TIF_LSX_CTX_LIVE); |
| @@ -302,7 +295,7 @@ static inline int thread_lsx_context_live(void) · 1 unmodified line | ||
| 302 | 295 | |
| 303 | 296 | static inline int thread_lasx_context_live(void) |
| 304 | 297 | { |
| 305 | − if (__builtin_constant_p(cpu_has_lasx) && !cpu_has_lasx) | |
| 298 | + if (!cpu_has_lasx) | |
| 306 | 299 | return 0; |
| 307 | 300 | |
| 308 | 301 | return test_thread_flag(TIF_LASX_CTX_LIVE); |
| @@ -332,9 +332,25 @@ static void __init bootcmdline_init(char **cmdline_p) · 331 unmodified lines | ||
| 332 | 332 | strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); |
| 333 | 333 | |
| 334 | 334 | strlcat(boot_command_line, init_command_line, COMMAND_LINE_SIZE); |
| 335 | + goto out; | |
| 335 | 336 | } |
| 336 | 337 | #endif |
| 337 | 338 | |
| 339 | + /* | |
| 340 | + * Append built-in command line to the bootloader command line if | |
| 341 | + * CONFIG_CMDLINE_EXTEND is enabled. | |
| 342 | + */ | |
| 343 | + if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) && CONFIG_CMDLINE[0]) { | |
| 344 | + strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); | |
| 345 | + strlcat(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); | |
| 346 | + } | |
| 347 | + | |
| 348 | + /* | |
| 349 | + * Use built-in command line if the bootloader command line is empty. | |
| 350 | + */ | |
| 351 | + if (IS_ENABLED(CONFIG_CMDLINE_BOOTLOADER) && !boot_command_line[0]) | |
| 352 | + strscpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); | |
| 353 | + | |
| 338 | 354 | out: |
| 339 | 355 | *cmdline_p = boot_command_line; |
| 340 | 356 | } |
| @@ -108,6 +108,7 @@ SYM_FUNC_START(__clear_user_fast) · 107 unmodified lines | ||
| 108 | 108 | addi.d a3, a2, -8 |
| 109 | 109 | bgeu a0, a3, .Llt8 |
| 110 | 110 | 15: st.d zero, a0, 0 |
| 111 | + addi.d a0, a0, 8 | |
| 111 | 112 | |
| 112 | 113 | .Llt8: |
| 113 | 114 | 16: st.d zero, a2, -8 |
| @@ -188,7 +189,7 @@ SYM_FUNC_START(__clear_user_fast) · 74 unmodified lines | ||
| 188 | 189 | _asm_extable 13b, .L_fixup_handle_0 |
| 189 | 190 | _asm_extable 14b, .L_fixup_handle_1 |
| 190 | 191 | _asm_extable 15b, .L_fixup_handle_0 |
| 191 | − _asm_extable 16b, .L_fixup_handle_1 | |
| 192 | + _asm_extable 16b, .L_fixup_handle_0 | |
| 192 | 193 | _asm_extable 17b, .L_fixup_handle_s0 |
| 193 | 194 | _asm_extable 18b, .L_fixup_handle_s0 |
| 194 | 195 | _asm_extable 19b, .L_fixup_handle_s0 |
| @@ -136,6 +136,7 @@ SYM_FUNC_START(__copy_user_fast) · 135 unmodified lines | ||
| 136 | 136 | bgeu a1, a4, .Llt8 |
| 137 | 137 | 30: ld.d t0, a1, 0 |
| 138 | 138 | 31: st.d t0, a0, 0 |
| 139 | + addi.d a0, a0, 8 | |
| 139 | 140 | |
| 140 | 141 | .Llt8: |
| 141 | 142 | 32: ld.d t0, a3, -8 |
| @@ -246,7 +247,7 @@ SYM_FUNC_START(__copy_user_fast) · 104 unmodified lines | ||
| 246 | 247 | _asm_extable 30b, .L_fixup_handle_0 |
| 247 | 248 | _asm_extable 31b, .L_fixup_handle_0 |
| 248 | 249 | _asm_extable 32b, .L_fixup_handle_0 |
| 249 | − _asm_extable 33b, .L_fixup_handle_1 | |
| 250 | + _asm_extable 33b, .L_fixup_handle_0 | |
| 250 | 251 | _asm_extable 34b, .L_fixup_handle_s0 |
| 251 | 252 | _asm_extable 35b, .L_fixup_handle_s0 |
| 252 | 253 | _asm_extable 36b, .L_fixup_handle_s0 |
| @@ -150,7 +150,7 @@ static inline void move_imm(struct jit_ctx *ctx, enum loongarch_gpr rd, long imm · 149 unmodified lines | ||
| 150 | 150 | * no need to call lu32id to do a new filled operation. |
| 151 | 151 | */ |
| 152 | 152 | imm_51_31 = (imm >> 31) & 0x1fffff; |
| 153 | − if (imm_51_31 != 0 || imm_51_31 != 0x1fffff) { | |
| 153 | + if (imm_51_31 != 0 && imm_51_31 != 0x1fffff) { | |
| 154 | 154 | /* lu32id rd, imm_51_32 */ |
| 155 | 155 | imm_51_32 = (imm >> 32) & 0xfffff; |
| 156 | 156 | emit_insn(ctx, lu32id, rd, imm_51_32); |
| @@ -499,13 +499,13 @@ in_ea: · 498 unmodified lines | ||
| 499 | 499 | dbf %d0,morein |
| 500 | 500 | rts |
| 501 | 501 | |
| 502 | − .section .fixup,#alloc,#execinstr | |
| 502 | + .section .fixup,"ax" | |
| 503 | 503 | .even |
| 504 | 504 | 1: |
| 505 | 505 | jbsr fpsp040_die |
| 506 | 506 | jbra .Lnotkern |
| 507 | 507 | |
| 508 | − .section __ex_table,#alloc | |
| 508 | + .section __ex_table,"a" | |
| 509 | 509 | .align 4 |
| 510 | 510 | |
| 511 | 511 | .long in_ea,1b |
| @@ -379,11 +379,11 @@ _060_real_access: · 378 unmodified lines | ||
| 379 | 379 | |
| 380 | 380 | |
| 381 | 381 | | Execption handling for movs access to illegal memory |
| 382 | − .section .fixup,#alloc,#execinstr | |
| 382 | + .section .fixup,"ax" | |
| 383 | 383 | .even |
| 384 | 384 | 1: moveq #-1,%d1 |
| 385 | 385 | rts |
| 386 | −.section __ex_table,#alloc | |
| 386 | +.section __ex_table,"a" | |
| 387 | 387 | .align 4 |
| 388 | 388 | .long dmrbuae,1b |
| 389 | 389 | .long dmrwuae,1b |
| @@ -26,7 +26,7 @@ ENTRY(relocate_new_kernel) · 25 unmodified lines | ||
| 26 | 26 | lea %pc@(.Lcopy),%a4 |
| 27 | 27 | 2: addl #0x00000000,%a4 /* virt_to_phys() */ |
| 28 | 28 | |
| 29 | − .section ".m68k_fixup","aw" | |
| 29 | + .section .m68k_fixup,"aw" | |
| 30 | 30 | .long M68K_FIXUP_MEMOFFSET, 2b+2 |
| 31 | 31 | .previous |
| 32 | 32 | |
| @@ -49,7 +49,7 @@ ENTRY(relocate_new_kernel) · 16 unmodified lines | ||
| 49 | 49 | lea %pc@(.Lcont040),%a4 |
| 50 | 50 | 5: addl #0x00000000,%a4 /* virt_to_phys() */ |
| 51 | 51 | |
| 52 | − .section ".m68k_fixup","aw" | |
| 52 | + .section .m68k_fixup,"aw" | |
| 53 | 53 | .long M68K_FIXUP_MEMOFFSET, 5b+2 |
| 54 | 54 | .previous |
| 55 | 55 | |
| @@ -153,7 +153,7 @@ CONFIG_QUOTA=y · 152 unmodified lines | ||
| 153 | 153 | CONFIG_QUOTA_NETLINK_INTERFACE=y |
| 154 | 154 | # CONFIG_PRINT_QUOTA_WARNING is not set |
| 155 | 155 | CONFIG_QFMT_V2=m |
| 156 | −CONFIG_AUTOFS4_FS=m | |
| 156 | +CONFIG_AUTOFS_FS=m | |
| 157 | 157 | CONFIG_FUSE_FS=m |
| 158 | 158 | CONFIG_ISO9660_FS=m |
| 159 | 159 | CONFIG_JOLIET=y |
| @@ -178,7 +178,7 @@ CONFIG_EXT3_FS=y · 177 unmodified lines | ||
| 178 | 178 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 179 | 179 | CONFIG_EXT4_FS_SECURITY=y |
| 180 | 180 | CONFIG_REISERFS_FS=m |
| 181 | −CONFIG_AUTOFS4_FS=y | |
| 181 | +CONFIG_AUTOFS_FS=y | |
| 182 | 182 | CONFIG_FUSE_FS=y |
| 183 | 183 | CONFIG_ISO9660_FS=m |
| 184 | 184 | CONFIG_JOLIET=y |
| @@ -245,7 +245,7 @@ CONFIG_QUOTA=y · 244 unmodified lines | ||
| 245 | 245 | CONFIG_QUOTA_NETLINK_INTERFACE=y |
| 246 | 246 | # CONFIG_PRINT_QUOTA_WARNING is not set |
| 247 | 247 | CONFIG_QFMT_V2=m |
| 248 | −CONFIG_AUTOFS4_FS=m | |
| 248 | +CONFIG_AUTOFS_FS=m | |
| 249 | 249 | CONFIG_FUSE_FS=m |
| 250 | 250 | CONFIG_ISO9660_FS=m |
| 251 | 251 | CONFIG_JOLIET=y |
| @@ -95,7 +95,7 @@ CONFIG_EXT3_FS_SECURITY=y · 94 unmodified lines | ||
| 95 | 95 | CONFIG_QUOTA=y |
| 96 | 96 | CONFIG_QFMT_V1=m |
| 97 | 97 | CONFIG_QFMT_V2=m |
| 98 | −CONFIG_AUTOFS4_FS=m | |
| 98 | +CONFIG_AUTOFS_FS=m | |
| 99 | 99 | CONFIG_FUSE_FS=m |
| 100 | 100 | CONFIG_ISO9660_FS=m |
| 101 | 101 | CONFIG_JOLIET=y |
| @@ -76,7 +76,7 @@ CONFIG_REISERFS_FS_POSIX_ACL=y · 75 unmodified lines | ||
| 76 | 76 | CONFIG_REISERFS_FS_SECURITY=y |
| 77 | 77 | CONFIG_XFS_FS=m |
| 78 | 78 | CONFIG_XFS_QUOTA=y |
| 79 | −CONFIG_AUTOFS4_FS=m | |
| 79 | +CONFIG_AUTOFS_FS=m | |
| 80 | 80 | CONFIG_FUSE_FS=m |
| 81 | 81 | CONFIG_ISO9660_FS=m |
| 82 | 82 | CONFIG_JOLIET=y |
| @@ -240,7 +240,7 @@ CONFIG_XFS_POSIX_ACL=y · 239 unmodified lines | ||
| 240 | 240 | CONFIG_BTRFS_FS=m |
| 241 | 241 | CONFIG_QUOTA=y |
| 242 | 242 | CONFIG_QFMT_V2=m |
| 243 | −CONFIG_AUTOFS4_FS=m | |
| 243 | +CONFIG_AUTOFS_FS=m | |
| 244 | 244 | CONFIG_FSCACHE=m |
| 245 | 245 | CONFIG_CACHEFILES=m |
| 246 | 246 | CONFIG_ISO9660_FS=m |
| @@ -296,7 +296,7 @@ CONFIG_XFS_QUOTA=y · 295 unmodified lines | ||
| 296 | 296 | CONFIG_XFS_POSIX_ACL=y |
| 297 | 297 | CONFIG_QUOTA=y |
| 298 | 298 | # CONFIG_PRINT_QUOTA_WARNING is not set |
| 299 | −CONFIG_AUTOFS4_FS=y | |
| 299 | +CONFIG_AUTOFS_FS=y | |
| 300 | 300 | CONFIG_FUSE_FS=m |
| 301 | 301 | CONFIG_ISO9660_FS=m |
| 302 | 302 | CONFIG_JOLIET=y |
| @@ -352,7 +352,7 @@ CONFIG_QUOTA=y · 351 unmodified lines | ||
| 352 | 352 | # CONFIG_PRINT_QUOTA_WARNING is not set |
| 353 | 353 | CONFIG_QFMT_V1=m |
| 354 | 354 | CONFIG_QFMT_V2=m |
| 355 | −CONFIG_AUTOFS4_FS=y | |
| 355 | +CONFIG_AUTOFS_FS=y | |
| 356 | 356 | CONFIG_FUSE_FS=m |
| 357 | 357 | CONFIG_VIRTIO_FS=m |
| 358 | 358 | CONFIG_FSCACHE=m |
| @@ -601,7 +601,7 @@ CONFIG_EXT3_FS=m · 600 unmodified lines | ||
| 601 | 601 | CONFIG_EXT3_FS_POSIX_ACL=y |
| 602 | 602 | CONFIG_EXT3_FS_SECURITY=y |
| 603 | 603 | CONFIG_QUOTA=y |
| 604 | −CONFIG_AUTOFS4_FS=y | |
| 604 | +CONFIG_AUTOFS_FS=y | |
| 605 | 605 | CONFIG_FUSE_FS=m |
| 606 | 606 | CONFIG_ISO9660_FS=m |
| 607 | 607 | CONFIG_JOLIET=y |
| @@ -66,7 +66,7 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y · 65 unmodified lines | ||
| 66 | 66 | CONFIG_EXT4_FS=y |
| 67 | 67 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 68 | 68 | CONFIG_EXT4_FS_SECURITY=y |
| 69 | −CONFIG_AUTOFS4_FS=m | |
| 69 | +CONFIG_AUTOFS_FS=m | |
| 70 | 70 | CONFIG_FUSE_FS=m |
| 71 | 71 | CONFIG_FSCACHE=m |
| 72 | 72 | CONFIG_ISO9660_FS=m |
| @@ -317,7 +317,7 @@ CONFIG_REISERFS_FS_POSIX_ACL=y · 316 unmodified lines | ||
| 317 | 317 | CONFIG_REISERFS_FS_SECURITY=y |
| 318 | 318 | CONFIG_XFS_FS=m |
| 319 | 319 | CONFIG_XFS_QUOTA=y |
| 320 | −CONFIG_AUTOFS4_FS=m | |
| 320 | +CONFIG_AUTOFS_FS=m | |
| 321 | 321 | CONFIG_FUSE_FS=m |
| 322 | 322 | CONFIG_ISO9660_FS=m |
| 323 | 323 | CONFIG_JOLIET=y |
| @@ -58,8 +58,6 @@ · 57 unmodified lines | ||
| 58 | 58 | |
| 59 | 59 | #define cpu_has_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON) |
| 60 | 60 | |
| 61 | −#define ARCH_HAS_SPINLOCK_PREFETCH 1 | |
| 62 | −#define spin_lock_prefetch(x) prefetch(x) | |
| 63 | 61 | #define PREFETCH_STRIDE 128 |
| 64 | 62 | |
| 65 | 63 | #ifdef __OCTEON__ |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | # |
| 3 | 3 | config LIGHTWEIGHT_SPINLOCK_CHECK |
| 4 | 4 | bool "Enable lightweight spinlock checks" |
| 5 | − depends on SMP && !DEBUG_SPINLOCK | |
| 5 | + depends on DEBUG_KERNEL && SMP && !DEBUG_SPINLOCK | |
| 6 | 6 | default y |
| 7 | 7 | help |
| 8 | 8 | Add checks with low performance impact to the spinlock functions |
| @@ -117,7 +117,7 @@ char *strchr(const char *s, int c) · 116 unmodified lines | ||
| 117 | 117 | return NULL; |
| 118 | 118 | } |
| 119 | 119 | |
| 120 | −int puts(const char *s) | |
| 120 | +static int puts(const char *s) | |
| 121 | 121 | { |
| 122 | 122 | const char *nuline = s; |
| 123 | 123 | |
| @@ -172,7 +172,7 @@ static int print_num(unsigned long num, int base) · 48 unmodified lines | ||
| 172 | 172 | return 0; |
| 173 | 173 | } |
| 174 | 174 | |
| 175 | −int printf(const char *fmt, ...) | |
| 175 | +static int printf(const char *fmt, ...) | |
| 176 | 176 | { |
| 177 | 177 | va_list args; |
| 178 | 178 | int i = 0; |
| @@ -204,13 +204,13 @@ void abort(void) · 25 unmodified lines | ||
| 204 | 204 | } |
| 205 | 205 | |
| 206 | 206 | #undef malloc |
| 207 | −void *malloc(size_t size) | |
| 207 | +static void *malloc(size_t size) | |
| 208 | 208 | { |
| 209 | 209 | return malloc_gzip(size); |
| 210 | 210 | } |
| 211 | 211 | |
| 212 | 212 | #undef free |
| 213 | −void free(void *ptr) | |
| 213 | +static void free(void *ptr) | |
| 214 | 214 | { |
| 215 | 215 | return free_gzip(ptr); |
| 216 | 216 | } |
| @@ -278,7 +278,7 @@ static void parse_elf(void *output) · 61 unmodified lines | ||
| 278 | 278 | free(phdrs); |
| 279 | 279 | } |
| 280 | 280 | |
| 281 | −unsigned long decompress_kernel(unsigned int started_wide, | |
| 281 | +asmlinkage unsigned long __visible decompress_kernel(unsigned int started_wide, | |
| 282 | 282 | unsigned int command_line, |
| 283 | 283 | const unsigned int rd_start, |
| 284 | 284 | const unsigned int rd_end) |
| @@ -237,7 +237,7 @@ CONFIG_EXT3_FS_SECURITY=y · 236 unmodified lines | ||
| 237 | 237 | CONFIG_QUOTA=y |
| 238 | 238 | CONFIG_QUOTA_NETLINK_INTERFACE=y |
| 239 | 239 | CONFIG_QFMT_V2=y |
| 240 | −CONFIG_AUTOFS4_FS=y | |
| 240 | +CONFIG_AUTOFS_FS=y | |
| 241 | 241 | CONFIG_ISO9660_FS=y |
| 242 | 242 | CONFIG_JOLIET=y |
| 243 | 243 | CONFIG_VFAT_FS=y |
| @@ -259,7 +259,7 @@ CONFIG_BTRFS_FS=m · 258 unmodified lines | ||
| 259 | 259 | CONFIG_QUOTA=y |
| 260 | 260 | CONFIG_QUOTA_NETLINK_INTERFACE=y |
| 261 | 261 | CONFIG_QFMT_V2=y |
| 262 | −CONFIG_AUTOFS4_FS=y | |
| 262 | +CONFIG_AUTOFS_FS=y | |
| 263 | 263 | CONFIG_FUSE_FS=y |
| 264 | 264 | CONFIG_CUSE=y |
| 265 | 265 | CONFIG_ISO9660_FS=y |
| @@ -14,6 +14,8 @@ · 13 unmodified lines | ||
| 14 | 14 | #define dma_outb outb |
| 15 | 15 | #define dma_inb inb |
| 16 | 16 | |
| 17 | +extern unsigned long pcxl_dma_start; | |
| 18 | + | |
| 17 | 19 | /* |
| 18 | 20 | ** DMA_CHUNK_SIZE is used by the SCSI mid-layer to break up |
| 19 | 21 | ** (or rather not merge) DMAs into manageable chunks. |
| @@ -12,6 +12,10 @@ extern void mcount(void); · 11 unmodified lines | ||
| 12 | 12 | extern unsigned long sys_call_table[]; |
| 13 | 13 | |
| 14 | 14 | extern unsigned long return_address(unsigned int); |
| 15 | +struct ftrace_regs; | |
| 16 | +extern void ftrace_function_trampoline(unsigned long parent, | |
| 17 | + unsigned long self_addr, unsigned long org_sp_gr3, | |
| 18 | + struct ftrace_regs *fregs); | |
| 15 | 19 | |
| 16 | 20 | #ifdef CONFIG_DYNAMIC_FTRACE |
| 17 | 21 | extern void ftrace_caller(void); |
| @@ -7,8 +7,6 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <asm/processor.h> |
| 8 | 8 | #include <asm/spinlock_types.h> |
| 9 | 9 | |
| 10 | −#define SPINLOCK_BREAK_INSN 0x0000c006 /* break 6,6 */ | |
| 11 | − | |
| 12 | 10 | static inline void arch_spin_val_check(int lock_val) |
| 13 | 11 | { |
| 14 | 12 | if (IS_ENABLED(CONFIG_LIGHTWEIGHT_SPINLOCK_CHECK)) |
| @@ -4,6 +4,10 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | #define __ARCH_SPIN_LOCK_UNLOCKED_VAL 0x1a46 |
| 6 | 6 | |
| 7 | +#define SPINLOCK_BREAK_INSN 0x0000c006 /* break 6,6 */ | |
| 8 | + | |
| 9 | +#ifndef __ASSEMBLY__ | |
| 10 | + | |
| 7 | 11 | typedef struct { |
| 8 | 12 | #ifdef CONFIG_PA20 |
| 9 | 13 | volatile unsigned int slock; |
| @@ -27,6 +31,8 @@ typedef struct { · 17 unmodified lines | ||
| 27 | 31 | volatile unsigned int counter; |
| 28 | 32 | } arch_rwlock_t; |
| 29 | 33 | |
| 34 | +#endif /* __ASSEMBLY__ */ | |
| 35 | + | |
| 30 | 36 | #define __ARCH_RW_LOCK_UNLOCKED__ 0x01000000 |
| 31 | 37 | #define __ARCH_RW_LOCK_UNLOCKED { .lock_mutex = __ARCH_SPIN_LOCK_UNLOCKED, \ |
| 32 | 38 | .counter = __ARCH_RW_LOCK_UNLOCKED__ } |
| @@ -74,8 +74,8 @@ · 73 unmodified lines | ||
| 74 | 74 | static DEFINE_SPINLOCK(pdc_lock); |
| 75 | 75 | #endif |
| 76 | 76 | |
| 77 | −unsigned long pdc_result[NUM_PDC_RESULT] __aligned(8); | |
| 78 | −unsigned long pdc_result2[NUM_PDC_RESULT] __aligned(8); | |
| 77 | +static unsigned long pdc_result[NUM_PDC_RESULT] __aligned(8); | |
| 78 | +static unsigned long pdc_result2[NUM_PDC_RESULT] __aligned(8); | |
| 79 | 79 | |
| 80 | 80 | #ifdef CONFIG_64BIT |
| 81 | 81 | #define WIDE_FIRMWARE 0x1 |
| @@ -334,7 +334,7 @@ int __pdc_cpu_rendezvous(void) · 252 unmodified lines | ||
| 334 | 334 | /** |
| 335 | 335 | * pdc_cpu_rendezvous_lock - Lock PDC while transitioning to rendezvous state |
| 336 | 336 | */ |
| 337 | −void pdc_cpu_rendezvous_lock(void) | |
| 337 | +void pdc_cpu_rendezvous_lock(void) __acquires(&pdc_lock) | |
| 338 | 338 | { |
| 339 | 339 | spin_lock(&pdc_lock); |
| 340 | 340 | } |
| @@ -342,7 +342,7 @@ void pdc_cpu_rendezvous_lock(void) · 1 unmodified line | ||
| 342 | 342 | /** |
| 343 | 343 | * pdc_cpu_rendezvous_unlock - Unlock PDC after reaching rendezvous state |
| 344 | 344 | */ |
| 345 | −void pdc_cpu_rendezvous_unlock(void) | |
| 345 | +void pdc_cpu_rendezvous_unlock(void) __releases(&pdc_lock) | |
| 346 | 346 | { |
| 347 | 347 | spin_unlock(&pdc_lock); |
| 348 | 348 | } |
| @@ -53,7 +53,7 @@ static void __hot prepare_ftrace_return(unsigned long *parent, · 52 unmodified lines | ||
| 53 | 53 | |
| 54 | 54 | static ftrace_func_t ftrace_func; |
| 55 | 55 | |
| 56 | −void notrace __hot ftrace_function_trampoline(unsigned long parent, | |
| 56 | +asmlinkage void notrace __hot ftrace_function_trampoline(unsigned long parent, | |
| 57 | 57 | unsigned long self_addr, |
| 58 | 58 | unsigned long org_sp_gr3, |
| 59 | 59 | struct ftrace_regs *fregs) |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/module.h> |
| 15 | 15 | #include <linux/kernel.h> |
| 16 | 16 | #include <linux/syscalls.h> |
| 17 | +#include <linux/libgcc.h> | |
| 17 | 18 | |
| 18 | 19 | #include <linux/string.h> |
| 19 | 20 | EXPORT_SYMBOL(memset); |
| @@ -92,12 +93,6 @@ EXPORT_SYMBOL($$divI_12); · 72 unmodified lines | ||
| 92 | 93 | EXPORT_SYMBOL($$divI_14); |
| 93 | 94 | EXPORT_SYMBOL($$divI_15); |
| 94 | 95 | |
| 95 | −extern void __ashrdi3(void); | |
| 96 | −extern void __ashldi3(void); | |
| 97 | −extern void __lshrdi3(void); | |
| 98 | −extern void __muldi3(void); | |
| 99 | −extern void __ucmpdi2(void); | |
| 100 | − | |
| 101 | 96 | EXPORT_SYMBOL(__ashrdi3); |
| 102 | 97 | EXPORT_SYMBOL(__ashldi3); |
| 103 | 98 | EXPORT_SYMBOL(__lshrdi3); |
| @@ -39,7 +39,7 @@ static struct proc_dir_entry * proc_gsc_root __read_mostly = NULL; · 38 unmodified lines | ||
| 39 | 39 | static unsigned long pcxl_used_bytes __read_mostly; |
| 40 | 40 | static unsigned long pcxl_used_pages __read_mostly; |
| 41 | 41 | |
| 42 | −extern unsigned long pcxl_dma_start; /* Start of pcxl dma mapping area */ | |
| 42 | +unsigned long pcxl_dma_start __ro_after_init; /* pcxl dma mapping area start */ | |
| 43 | 43 | static DEFINE_SPINLOCK(pcxl_res_lock); |
| 44 | 44 | static char *pcxl_res_map; |
| 45 | 45 | static int pcxl_res_hint; |
| @@ -381,7 +381,7 @@ pcxl_dma_init(void) · 335 unmodified lines | ||
| 381 | 381 | pcxl_res_map = (char *)__get_free_pages(GFP_KERNEL, |
| 382 | 382 | get_order(pcxl_res_size)); |
| 383 | 383 | memset(pcxl_res_map, 0, pcxl_res_size); |
| 384 | − proc_gsc_root = proc_mkdir("gsc", NULL); | |
| 384 | + proc_gsc_root = proc_mkdir("bus/gsc", NULL); | |
| 385 | 385 | if (!proc_gsc_root) |
| 386 | 386 | printk(KERN_WARNING |
| 387 | 387 | "pcxl_dma_init: Unable to create gsc /proc dir entry\n"); |
| @@ -417,14 +417,6 @@ void *arch_dma_alloc(struct device *dev, size_t size, · 29 unmodified lines | ||
| 417 | 417 | map_uncached_pages(vaddr, size, paddr); |
| 418 | 418 | *dma_handle = (dma_addr_t) paddr; |
| 419 | 419 | |
| 420 | −#if 0 | |
| 421 | −/* This probably isn't needed to support EISA cards. | |
| 422 | −** ISA cards will certainly only support 24-bit DMA addressing. | |
| 423 | −** Not clear if we can, want, or need to support ISA. | |
| 424 | −*/ | |
| 425 | − if (!dev || *dev->coherent_dma_mask < 0xffffffff) | |
| 426 | − gfp |= GFP_DMA; | |
| 427 | −#endif | |
| 428 | 420 | return (void *)vaddr; |
| 429 | 421 | } |
| 430 | 422 | |
| @@ -354,10 +354,8 @@ static int __init pdt_initcall(void) · 353 unmodified lines | ||
| 354 | 354 | return -ENODEV; |
| 355 | 355 | |
| 356 | 356 | kpdtd_task = kthread_run(pdt_mainloop, NULL, "kpdtd"); |
| 357 | − if (IS_ERR(kpdtd_task)) | |
| 358 | − return PTR_ERR(kpdtd_task); | |
| 359 | 357 | |
| 360 | − return 0; | |
| 358 | + return PTR_ERR_OR_ZERO(kpdtd_task); | |
| 361 | 359 | } |
| 362 | 360 | |
| 363 | 361 | late_initcall(pdt_initcall); |
| @@ -57,7 +57,7 @@ struct rdr_tbl_ent { · 56 unmodified lines | ||
| 57 | 57 | static int perf_processor_interface __read_mostly = UNKNOWN_INTF; |
| 58 | 58 | static int perf_enabled __read_mostly; |
| 59 | 59 | static DEFINE_SPINLOCK(perf_lock); |
| 60 | −struct parisc_device *cpu_device __read_mostly; | |
| 60 | +static struct parisc_device *cpu_device __read_mostly; | |
| 61 | 61 | |
| 62 | 62 | /* RDRs to write for PCX-W */ |
| 63 | 63 | static const int perf_rdrs_W[] = |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <asm/processor.h> |
| 27 | 27 | #include <asm/page.h> |
| 28 | 28 | #include <asm/pdc.h> |
| 29 | +#include <asm/smp.h> | |
| 29 | 30 | #include <asm/pdcpat.h> |
| 30 | 31 | #include <asm/irq.h> /* for struct irq_region */ |
| 31 | 32 | #include <asm/parisc-device.h> |
| @@ -40,11 +40,6 @@ · 39 unmodified lines | ||
| 40 | 40 | |
| 41 | 41 | static char __initdata command_line[COMMAND_LINE_SIZE]; |
| 42 | 42 | |
| 43 | −/* Intended for ccio/sba/cpu statistics under /proc/bus/{runway|gsc} */ | |
| 44 | −struct proc_dir_entry * proc_runway_root __read_mostly = NULL; | |
| 45 | −struct proc_dir_entry * proc_gsc_root __read_mostly = NULL; | |
| 46 | −struct proc_dir_entry * proc_mckinley_root __read_mostly = NULL; | |
| 47 | − | |
| 48 | 43 | static void __init setup_cmdline(char **cmdline_p) |
| 49 | 44 | { |
| 50 | 45 | extern unsigned int boot_args[]; |
| @@ -196,48 +191,6 @@ const struct seq_operations cpuinfo_op = { · 145 unmodified lines | ||
| 196 | 191 | .show = show_cpuinfo |
| 197 | 192 | }; |
| 198 | 193 | |
| 199 | −static void __init parisc_proc_mkdir(void) | |
| 200 | −{ | |
| 201 | − /* | |
| 202 | − ** Can't call proc_mkdir() until after proc_root_init() has been | |
| 203 | − ** called by start_kernel(). In other words, this code can't | |
| 204 | − ** live in arch/.../setup.c because start_parisc() calls | |
| 205 | − ** start_kernel(). | |
| 206 | − */ | |
| 207 | − switch (boot_cpu_data.cpu_type) { | |
| 208 | − case pcxl: | |
| 209 | − case pcxl2: | |
| 210 | − if (NULL == proc_gsc_root) | |
| 211 | − { | |
| 212 | − proc_gsc_root = proc_mkdir("bus/gsc", NULL); | |
| 213 | − } | |
| 214 | − break; | |
| 215 | − case pcxt_: | |
| 216 | − case pcxu: | |
| 217 | − case pcxu_: | |
| 218 | − case pcxw: | |
| 219 | − case pcxw_: | |
| 220 | − case pcxw2: | |
| 221 | − if (NULL == proc_runway_root) | |
| 222 | − { | |
| 223 | − proc_runway_root = proc_mkdir("bus/runway", NULL); | |
| 224 | − } | |
| 225 | − break; | |
| 226 | − case mako: | |
| 227 | − case mako2: | |
| 228 | − if (NULL == proc_mckinley_root) | |
| 229 | − { | |
| 230 | − proc_mckinley_root = proc_mkdir("bus/mckinley", NULL); | |
| 231 | − } | |
| 232 | − break; | |
| 233 | − default: | |
| 234 | − /* FIXME: this was added to prevent the compiler | |
| 235 | − * complaining about missing pcx, pcxs and pcxt | |
| 236 | − * I'm assuming they have neither gsc nor runway */ | |
| 237 | − break; | |
| 238 | − } | |
| 239 | −} | |
| 240 | − | |
| 241 | 194 | static struct resource central_bus = { |
| 242 | 195 | .name = "Central Bus", |
| 243 | 196 | .start = F_EXTEND(0xfff80000), |
| @@ -294,7 +247,6 @@ static int __init parisc_init(void) · 50 unmodified lines | ||
| 294 | 247 | { |
| 295 | 248 | u32 osid = (OS_ID_LINUX << 16); |
| 296 | 249 | |
| 297 | − parisc_proc_mkdir(); | |
| 298 | 250 | parisc_init_resources(); |
| 299 | 251 | do_device_inventory(); /* probe for hardware */ |
| 300 | 252 | |
| @@ -423,7 +423,7 @@ static void check_syscallno_in_delay_branch(struct pt_regs *regs) · 422 unmodified lines | ||
| 423 | 423 | regs->gr[31] -= 8; /* delayed branching */ |
| 424 | 424 | |
| 425 | 425 | /* Get assembler opcode of code in delay branch */ |
| 426 | − uaddr = (unsigned int *) ((regs->gr[31] & ~3) + 4); | |
| 426 | + uaddr = (u32 __user *) ((regs->gr[31] & ~3) + 4); | |
| 427 | 427 | err = get_user(opcode, uaddr); |
| 428 | 428 | if (err) |
| 429 | 429 | return; |
| @@ -27,17 +27,12 @@ · 26 unmodified lines | ||
| 27 | 27 | #include <linux/elf-randomize.h> |
| 28 | 28 | |
| 29 | 29 | /* |
| 30 | − * Construct an artificial page offset for the mapping based on the virtual | |
| 30 | + * Construct an artificial page offset for the mapping based on the physical | |
| 31 | 31 | * address of the kernel file mapping variable. |
| 32 | − * If filp is zero the calculated pgoff value aliases the memory of the given | |
| 33 | − * address. This is useful for io_uring where the mapping shall alias a kernel | |
| 34 | − * address and a userspace adress where both the kernel and the userspace | |
| 35 | − * access the same memory region. | |
| 36 | 32 | */ |
| 37 | −#define GET_FILP_PGOFF(filp, addr) \ | |
| 38 | − ((filp ? (((unsigned long) filp->f_mapping) >> 8) \ | |
| 39 | − & ((SHM_COLOUR-1) >> PAGE_SHIFT) : 0UL) \ | |
| 40 | − + (addr >> PAGE_SHIFT)) | |
| 33 | +#define GET_FILP_PGOFF(filp) \ | |
| 34 | + (filp ? (((unsigned long) filp->f_mapping) >> 8) \ | |
| 35 | + & ((SHM_COLOUR-1) >> PAGE_SHIFT) : 0UL) | |
| 41 | 36 | |
| 42 | 37 | static unsigned long shared_align_offset(unsigned long filp_pgoff, |
| 43 | 38 | unsigned long pgoff) |
| @@ -117,7 +112,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp, · 73 unmodified lines | ||
| 117 | 112 | do_color_align = 0; |
| 118 | 113 | if (filp || (flags & MAP_SHARED)) |
| 119 | 114 | do_color_align = 1; |
| 120 | − filp_pgoff = GET_FILP_PGOFF(filp, addr); | |
| 115 | + filp_pgoff = GET_FILP_PGOFF(filp); | |
| 121 | 116 | |
| 122 | 117 | if (flags & MAP_FIXED) { |
| 123 | 118 | /* Even MAP_FIXED mappings must reside within TASK_SIZE */ |
| @@ -39,6 +39,7 @@ registers). · 38 unmodified lines | ||
| 39 | 39 | #include <asm/assembly.h> |
| 40 | 40 | #include <asm/processor.h> |
| 41 | 41 | #include <asm/cache.h> |
| 42 | +#include <asm/spinlock_types.h> | |
| 42 | 43 | |
| 43 | 44 | #include <linux/linkage.h> |
| 44 | 45 | |
| @@ -66,6 +67,16 @@ registers). · 21 unmodified lines | ||
| 66 | 67 | stw \reg1, 0(%sr2,\reg2) |
| 67 | 68 | .endm |
| 68 | 69 | |
| 70 | + /* raise exception if spinlock content is not zero or | |
| 71 | + * __ARCH_SPIN_LOCK_UNLOCKED_VAL */ | |
| 72 | + .macro spinlock_check spin_val,tmpreg | |
| 73 | +#ifdef CONFIG_LIGHTWEIGHT_SPINLOCK_CHECK | |
| 74 | + ldi __ARCH_SPIN_LOCK_UNLOCKED_VAL, \tmpreg | |
| 75 | + andcm,= \spin_val, \tmpreg, %r0 | |
| 76 | + .word SPINLOCK_BREAK_INSN | |
| 77 | +#endif | |
| 78 | + .endm | |
| 79 | + | |
| 69 | 80 | .text |
| 70 | 81 | |
| 71 | 82 | .import syscall_exit,code |
| @@ -508,7 +519,8 @@ lws_start: · 436 unmodified lines | ||
| 508 | 519 | |
| 509 | 520 | lws_exit_noerror: |
| 510 | 521 | lws_pagefault_enable %r1,%r21 |
| 511 | − stw,ma %r20, 0(%sr2,%r20) | |
| 522 | + ldi __ARCH_SPIN_LOCK_UNLOCKED_VAL, %r21 | |
| 523 | + stw,ma %r21, 0(%sr2,%r20) | |
| 512 | 524 | ssm PSW_SM_I, %r0 |
| 513 | 525 | b lws_exit |
| 514 | 526 | copy %r0, %r21 |
| @@ -521,7 +533,8 @@ lws_wouldblock: · 6 unmodified lines | ||
| 521 | 533 | |
| 522 | 534 | lws_pagefault: |
| 523 | 535 | lws_pagefault_enable %r1,%r21 |
| 524 | − stw,ma %r20, 0(%sr2,%r20) | |
| 536 | + ldi __ARCH_SPIN_LOCK_UNLOCKED_VAL, %r21 | |
| 537 | + stw,ma %r21, 0(%sr2,%r20) | |
| 525 | 538 | ssm PSW_SM_I, %r0 |
| 526 | 539 | ldo 3(%r0),%r28 |
| 527 | 540 | b lws_exit |
| @@ -619,6 +632,7 @@ lws_compare_and_swap: · 91 unmodified lines | ||
| 619 | 632 | |
| 620 | 633 | /* Try to acquire the lock */ |
| 621 | 634 | LDCW 0(%sr2,%r20), %r28 |
| 635 | + spinlock_check %r28, %r21 | |
| 622 | 636 | comclr,<> %r0, %r28, %r0 |
| 623 | 637 | b,n lws_wouldblock |
| 624 | 638 | |
| @@ -772,6 +786,7 @@ cas2_lock_start: · 147 unmodified lines | ||
| 772 | 786 | |
| 773 | 787 | /* Try to acquire the lock */ |
| 774 | 788 | LDCW 0(%sr2,%r20), %r28 |
| 789 | + spinlock_check %r28, %r21 | |
| 775 | 790 | comclr,<> %r0, %r28, %r0 |
| 776 | 791 | b,n lws_wouldblock |
| 777 | 792 | |
| @@ -1001,6 +1016,7 @@ atomic_xchg_start: · 223 unmodified lines | ||
| 1001 | 1016 | |
| 1002 | 1017 | /* Try to acquire the lock */ |
| 1003 | 1018 | LDCW 0(%sr2,%r20), %r28 |
| 1019 | + spinlock_check %r28, %r21 | |
| 1004 | 1020 | comclr,<> %r0, %r28, %r0 |
| 1005 | 1021 | b,n lws_wouldblock |
| 1006 | 1022 | |
| @@ -1199,6 +1215,7 @@ atomic_store_start: · 192 unmodified lines | ||
| 1199 | 1215 | |
| 1200 | 1216 | /* Try to acquire the lock */ |
| 1201 | 1217 | LDCW 0(%sr2,%r20), %r28 |
| 1218 | + spinlock_check %r28, %r21 | |
| 1202 | 1219 | comclr,<> %r0, %r28, %r0 |
| 1203 | 1220 | b,n lws_wouldblock |
| 1204 | 1221 | |
| @@ -1330,7 +1347,7 @@ ENTRY(lws_lock_start) · 125 unmodified lines | ||
| 1330 | 1347 | /* lws locks */ |
| 1331 | 1348 | .rept 256 |
| 1332 | 1349 | /* Keep locks aligned at 16-bytes */ |
| 1333 | − .word 1 | |
| 1350 | + .word __ARCH_SPIN_LOCK_UNLOCKED_VAL | |
| 1334 | 1351 | .word 0 |
| 1335 | 1352 | .word 0 |
| 1336 | 1353 | .word 0 |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/signal.h> |
| 12 | 12 | #include <linux/ratelimit.h> |
| 13 | 13 | #include <linux/uaccess.h> |
| 14 | +#include <linux/sysctl.h> | |
| 14 | 15 | #include <asm/unaligned.h> |
| 15 | 16 | #include <asm/hardirq.h> |
| 16 | 17 | #include <asm/traps.h> |
| @@ -337,7 +338,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) · 320 unmodified lines | ||
| 337 | 338 | : "r19", "r20", "r21", "r22", "r1" ); |
| 338 | 339 | #else |
| 339 | 340 | { |
| 340 | − unsigned long valh=(val>>32),vall=(val&0xffffffffl); | |
| 341 | + unsigned long valh = (val >> 32), vall = (val & 0xffffffffl); | |
| 341 | 342 | __asm__ __volatile__ ( |
| 342 | 343 | " mtsp %4, %%sr1\n" |
| 343 | 344 | " zdep %2, 29, 2, %%r19\n" |
| @@ -473,7 +474,7 @@ void handle_unaligned(struct pt_regs *regs) · 129 unmodified lines | ||
| 473 | 474 | case OPCODE_LDWA_I: |
| 474 | 475 | case OPCODE_LDW_S: |
| 475 | 476 | case OPCODE_LDWA_S: |
| 476 | − ret = emulate_ldw(regs, R3(regs->iir),0); | |
| 477 | + ret = emulate_ldw(regs, R3(regs->iir), 0); | |
| 477 | 478 | break; |
| 478 | 479 | |
| 479 | 480 | case OPCODE_STH: |
| @@ -482,7 +483,7 @@ void handle_unaligned(struct pt_regs *regs) · 2 unmodified lines | ||
| 482 | 483 | |
| 483 | 484 | case OPCODE_STW: |
| 484 | 485 | case OPCODE_STWA: |
| 485 | − ret = emulate_stw(regs, R2(regs->iir),0); | |
| 486 | + ret = emulate_stw(regs, R2(regs->iir), 0); | |
| 486 | 487 | break; |
| 487 | 488 | |
| 488 | 489 | #ifdef CONFIG_64BIT |
| @@ -490,12 +491,12 @@ void handle_unaligned(struct pt_regs *regs) · 1 unmodified line | ||
| 490 | 491 | case OPCODE_LDDA_I: |
| 491 | 492 | case OPCODE_LDD_S: |
| 492 | 493 | case OPCODE_LDDA_S: |
| 493 | − ret = emulate_ldd(regs, R3(regs->iir),0); | |
| 494 | + ret = emulate_ldd(regs, R3(regs->iir), 0); | |
| 494 | 495 | break; |
| 495 | 496 | |
| 496 | 497 | case OPCODE_STD: |
| 497 | 498 | case OPCODE_STDA: |
| 498 | − ret = emulate_std(regs, R2(regs->iir),0); | |
| 499 | + ret = emulate_std(regs, R2(regs->iir), 0); | |
| 499 | 500 | break; |
| 500 | 501 | #endif |
| 501 | 502 | |
| @@ -503,24 +504,24 @@ void handle_unaligned(struct pt_regs *regs) · 1 unmodified line | ||
| 503 | 504 | case OPCODE_FLDWS: |
| 504 | 505 | case OPCODE_FLDWXR: |
| 505 | 506 | case OPCODE_FLDWSR: |
| 506 | − ret = emulate_ldw(regs,FR3(regs->iir),1); | |
| 507 | + ret = emulate_ldw(regs, FR3(regs->iir), 1); | |
| 507 | 508 | break; |
| 508 | 509 | |
| 509 | 510 | case OPCODE_FLDDX: |
| 510 | 511 | case OPCODE_FLDDS: |
| 511 | − ret = emulate_ldd(regs,R3(regs->iir),1); | |
| 512 | + ret = emulate_ldd(regs, R3(regs->iir), 1); | |
| 512 | 513 | break; |
| 513 | 514 | |
| 514 | 515 | case OPCODE_FSTWX: |
| 515 | 516 | case OPCODE_FSTWS: |
| 516 | 517 | case OPCODE_FSTWXR: |
| 517 | 518 | case OPCODE_FSTWSR: |
| 518 | − ret = emulate_stw(regs,FR3(regs->iir),1); | |
| 519 | + ret = emulate_stw(regs, FR3(regs->iir), 1); | |
| 519 | 520 | break; |
| 520 | 521 | |
| 521 | 522 | case OPCODE_FSTDX: |
| 522 | 523 | case OPCODE_FSTDS: |
| 523 | − ret = emulate_std(regs,R3(regs->iir),1); | |
| 524 | + ret = emulate_std(regs, R3(regs->iir), 1); | |
| 524 | 525 | break; |
| 525 | 526 | |
| 526 | 527 | case OPCODE_LDCD_I: |
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | #include <linux/module.h> |
| 3 | +#include <linux/libgcc.h> | |
| 3 | 4 | |
| 4 | 5 | union ull_union { |
| 5 | 6 | unsigned long long ull; |
| @@ -9,7 +10,7 @@ union ull_union { · 3 unmodified lines | ||
| 9 | 10 | } ui; |
| 10 | 11 | }; |
| 11 | 12 | |
| 12 | −int __ucmpdi2(unsigned long long a, unsigned long long b) | |
| 13 | +word_type __ucmpdi2(unsigned long long a, unsigned long long b) | |
| 13 | 14 | { |
| 14 | 15 | union ull_union au = {.ull = a}; |
| 15 | 16 | union ull_union bu = {.ull = b}; |
| @@ -192,31 +192,31 @@ int fixup_exception(struct pt_regs *regs) · 191 unmodified lines | ||
| 192 | 192 | * For implementation see handle_interruption() in traps.c |
| 193 | 193 | */ |
| 194 | 194 | static const char * const trap_description[] = { |
| 195 | − [1] "High-priority machine check (HPMC)", | |
| 196 | − [2] "Power failure interrupt", | |
| 197 | − [3] "Recovery counter trap", | |
| 198 | − [5] "Low-priority machine check", | |
| 199 | − [6] "Instruction TLB miss fault", | |
| 200 | − [7] "Instruction access rights / protection trap", | |
| 201 | − [8] "Illegal instruction trap", | |
| 202 | − [9] "Break instruction trap", | |
| 203 | − [10] "Privileged operation trap", | |
| 204 | − [11] "Privileged register trap", | |
| 205 | − [12] "Overflow trap", | |
| 206 | − [13] "Conditional trap", | |
| 207 | − [14] "FP Assist Exception trap", | |
| 208 | − [15] "Data TLB miss fault", | |
| 209 | − [16] "Non-access ITLB miss fault", | |
| 210 | − [17] "Non-access DTLB miss fault", | |
| 211 | − [18] "Data memory protection/unaligned access trap", | |
| 212 | − [19] "Data memory break trap", | |
| 213 | − [20] "TLB dirty bit trap", | |
| 214 | − [21] "Page reference trap", | |
| 215 | − [22] "Assist emulation trap", | |
| 216 | − [25] "Taken branch trap", | |
| 217 | − [26] "Data memory access rights trap", | |
| 218 | − [27] "Data memory protection ID trap", | |
| 219 | − [28] "Unaligned data reference trap", | |
| 195 | + [1] = "High-priority machine check (HPMC)", | |
| 196 | + [2] = "Power failure interrupt", | |
| 197 | + [3] = "Recovery counter trap", | |
| 198 | + [5] = "Low-priority machine check", | |
| 199 | + [6] = "Instruction TLB miss fault", | |
| 200 | + [7] = "Instruction access rights / protection trap", | |
| 201 | + [8] = "Illegal instruction trap", | |
| 202 | + [9] = "Break instruction trap", | |
| 203 | + [10] = "Privileged operation trap", | |
| 204 | + [11] = "Privileged register trap", | |
| 205 | + [12] = "Overflow trap", | |
| 206 | + [13] = "Conditional trap", | |
| 207 | + [14] = "FP Assist Exception trap", | |
| 208 | + [15] = "Data TLB miss fault", | |
| 209 | + [16] = "Non-access ITLB miss fault", | |
| 210 | + [17] = "Non-access DTLB miss fault", | |
| 211 | + [18] = "Data memory protection/unaligned access trap", | |
| 212 | + [19] = "Data memory break trap", | |
| 213 | + [20] = "TLB dirty bit trap", | |
| 214 | + [21] = "Page reference trap", | |
| 215 | + [22] = "Assist emulation trap", | |
| 216 | + [25] = "Taken branch trap", | |
| 217 | + [26] = "Data memory access rights trap", | |
| 218 | + [27] = "Data memory protection ID trap", | |
| 219 | + [28] = "Unaligned data reference trap", | |
| 220 | 220 | }; |
| 221 | 221 | |
| 222 | 222 | const char *trap_name(unsigned long code) |
| @@ -19,9 +19,6 @@ void notrace set_fixmap(enum fixed_addresses idx, phys_addr_t phys) · 18 unmodified lines | ||
| 19 | 19 | pmd_t *pmd = pmd_offset(pud, vaddr); |
| 20 | 20 | pte_t *pte; |
| 21 | 21 | |
| 22 | − if (pmd_none(*pmd)) | |
| 23 | − pte = pte_alloc_kernel(pmd, vaddr); | |
| 24 | − | |
| 25 | 22 | pte = pte_offset_kernel(pmd, vaddr); |
| 26 | 23 | set_pte_at(&init_mm, vaddr, pte, __mk_pte(phys, PAGE_KERNEL_RWX)); |
| 27 | 24 | flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE); |
| @@ -523,10 +523,6 @@ void mark_rodata_ro(void) · 522 unmodified lines | ||
| 523 | 523 | void *parisc_vmalloc_start __ro_after_init; |
| 524 | 524 | EXPORT_SYMBOL(parisc_vmalloc_start); |
| 525 | 525 | |
| 526 | −#ifdef CONFIG_PA11 | |
| 527 | −unsigned long pcxl_dma_start __ro_after_init; | |
| 528 | −#endif | |
| 529 | − | |
| 530 | 526 | void __init mem_init(void) |
| 531 | 527 | { |
| 532 | 528 | /* Do sanity checks on IPC (compat) structures */ |
| @@ -669,6 +665,39 @@ static void __init gateway_init(void) · 136 unmodified lines | ||
| 669 | 665 | PAGE_SIZE, PAGE_GATEWAY, 1); |
| 670 | 666 | } |
| 671 | 667 | |
| 668 | +static void __init fixmap_init(void) | |
| 669 | +{ | |
| 670 | + unsigned long addr = FIXMAP_START; | |
| 671 | + unsigned long end = FIXMAP_START + FIXMAP_SIZE; | |
| 672 | + pgd_t *pgd = pgd_offset_k(addr); | |
| 673 | + p4d_t *p4d = p4d_offset(pgd, addr); | |
| 674 | + pud_t *pud = pud_offset(p4d, addr); | |
| 675 | + pmd_t *pmd; | |
| 676 | + | |
| 677 | + BUILD_BUG_ON(FIXMAP_SIZE > PMD_SIZE); | |
| 678 | + | |
| 679 | +#if CONFIG_PGTABLE_LEVELS == 3 | |
| 680 | + if (pud_none(*pud)) { | |
| 681 | + pmd = memblock_alloc(PAGE_SIZE << PMD_TABLE_ORDER, | |
| 682 | + PAGE_SIZE << PMD_TABLE_ORDER); | |
| 683 | + if (!pmd) | |
| 684 | + panic("fixmap: pmd allocation failed.\n"); | |
| 685 | + pud_populate(NULL, pud, pmd); | |
| 686 | + } | |
| 687 | +#endif | |
| 688 | + | |
| 689 | + pmd = pmd_offset(pud, addr); | |
| 690 | + do { | |
| 691 | + pte_t *pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE); | |
| 692 | + if (!pte) | |
| 693 | + panic("fixmap: pte allocation failed.\n"); | |
| 694 | + | |
| 695 | + pmd_populate_kernel(&init_mm, pmd, pte); | |
| 696 | + | |
| 697 | + addr += PAGE_SIZE; | |
| 698 | + } while (addr < end); | |
| 699 | +} | |
| 700 | + | |
| 672 | 701 | static void __init parisc_bootmem_free(void) |
| 673 | 702 | { |
| 674 | 703 | unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0, }; |
| @@ -683,6 +712,7 @@ void __init paging_init(void) · 8 unmodified lines | ||
| 683 | 712 | setup_bootmem(); |
| 684 | 713 | pagetable_init(); |
| 685 | 714 | gateway_init(); |
| 715 | + fixmap_init(); | |
| 686 | 716 | flush_cache_all_local(); /* start with known state */ |
| 687 | 717 | flush_tlb_all_local(NULL); |
| 688 | 718 | |
| @@ -27,7 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | */ |
| 28 | 28 | void __iomem *ioremap(unsigned long phys_addr, unsigned long size) |
| 29 | 29 | { |
| 30 | − void __iomem *addr; | |
| 30 | + uintptr_t addr; | |
| 31 | 31 | struct vm_struct *area; |
| 32 | 32 | unsigned long offset, last_addr; |
| 33 | 33 | pgprot_t pgprot; |
| @@ -79,10 +79,9 @@ void __iomem *ioremap(unsigned long phys_addr, unsigned long size) · 45 unmodified lines | ||
| 79 | 79 | if (!area) |
| 80 | 80 | return NULL; |
| 81 | 81 | |
| 82 | − addr = (void __iomem *) area->addr; | |
| 83 | − if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, | |
| 84 | − phys_addr, pgprot)) { | |
| 85 | − vunmap(addr); | |
| 82 | + addr = (uintptr_t) area->addr; | |
| 83 | + if (ioremap_page_range(addr, addr + size, phys_addr, pgprot)) { | |
| 84 | + vunmap(area->addr); | |
| 86 | 85 | return NULL; |
| 87 | 86 | } |
| 88 | 87 | |
| @@ -79,7 +79,7 @@ CONFIG_EXT2_FS_POSIX_ACL=y · 78 unmodified lines | ||
| 79 | 79 | CONFIG_EXT4_FS=y |
| 80 | 80 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 81 | 81 | CONFIG_REISERFS_FS=y |
| 82 | −CONFIG_AUTOFS4_FS=y | |
| 82 | +CONFIG_AUTOFS_FS=y | |
| 83 | 83 | CONFIG_ISO9660_FS=y |
| 84 | 84 | CONFIG_JOLIET=y |
| 85 | 85 | CONFIG_ZISOFS=y |
| @@ -50,7 +50,7 @@ CONFIG_DRM=m · 49 unmodified lines | ||
| 50 | 50 | CONFIG_SOUND=m |
| 51 | 51 | CONFIG_EXT2_FS=y |
| 52 | 52 | CONFIG_EXT4_FS=y |
| 53 | −CONFIG_AUTOFS4_FS=y | |
| 53 | +CONFIG_AUTOFS_FS=y | |
| 54 | 54 | CONFIG_ISO9660_FS=m |
| 55 | 55 | CONFIG_UDF_FS=m |
| 56 | 56 | CONFIG_MSDOS_FS=m |
| @@ -172,7 +172,7 @@ CONFIG_EDAC_CELL=y · 171 unmodified lines | ||
| 172 | 172 | CONFIG_UIO=m |
| 173 | 173 | CONFIG_EXT2_FS=y |
| 174 | 174 | CONFIG_EXT4_FS=y |
| 175 | −CONFIG_AUTOFS4_FS=m | |
| 175 | +CONFIG_AUTOFS_FS=m | |
| 176 | 176 | CONFIG_ISO9660_FS=m |
| 177 | 177 | CONFIG_JOLIET=y |
| 178 | 178 | CONFIG_UDF_FS=m |
| @@ -47,7 +47,7 @@ CONFIG_SERIAL_CPM_CONSOLE=y · 46 unmodified lines | ||
| 47 | 47 | # CONFIG_USB_SUPPORT is not set |
| 48 | 48 | CONFIG_EXT2_FS=y |
| 49 | 49 | CONFIG_EXT4_FS=y |
| 50 | −CONFIG_AUTOFS4_FS=y | |
| 50 | +CONFIG_AUTOFS_FS=y | |
| 51 | 51 | CONFIG_PROC_KCORE=y |
| 52 | 52 | CONFIG_TMPFS=y |
| 53 | 53 | CONFIG_CRAMFS=y |
| @@ -60,7 +60,7 @@ CONFIG_USB_FSL_USB2=y · 59 unmodified lines | ||
| 60 | 60 | CONFIG_USB_G_SERIAL=y |
| 61 | 61 | CONFIG_UIO=y |
| 62 | 62 | CONFIG_EXT2_FS=y |
| 63 | −CONFIG_AUTOFS4_FS=y | |
| 63 | +CONFIG_AUTOFS_FS=y | |
| 64 | 64 | CONFIG_PROC_KCORE=y |
| 65 | 65 | CONFIG_TMPFS=y |
| 66 | 66 | CONFIG_JFFS2_FS=y |
| @@ -143,7 +143,7 @@ CONFIG_EXT2_FS=y · 142 unmodified lines | ||
| 143 | 143 | CONFIG_EXT2_FS_XATTR=y |
| 144 | 144 | CONFIG_EXT2_FS_POSIX_ACL=y |
| 145 | 145 | CONFIG_EXT4_FS=y |
| 146 | −CONFIG_AUTOFS4_FS=y | |
| 146 | +CONFIG_AUTOFS_FS=y | |
| 147 | 147 | CONFIG_ISO9660_FS=y |
| 148 | 148 | CONFIG_UDF_FS=y |
| 149 | 149 | CONFIG_MSDOS_FS=y |
| @@ -254,7 +254,7 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y · 253 unmodified lines | ||
| 254 | 254 | CONFIG_EXT2_FS=y |
| 255 | 255 | CONFIG_EXT4_FS=y |
| 256 | 256 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 257 | −CONFIG_AUTOFS4_FS=m | |
| 257 | +CONFIG_AUTOFS_FS=m | |
| 258 | 258 | CONFIG_FUSE_FS=m |
| 259 | 259 | CONFIG_ISO9660_FS=y |
| 260 | 260 | CONFIG_JOLIET=y |
| @@ -270,7 +270,7 @@ CONFIG_BTRFS_FS=m · 269 unmodified lines | ||
| 270 | 270 | CONFIG_BTRFS_FS_POSIX_ACL=y |
| 271 | 271 | CONFIG_NILFS2_FS=m |
| 272 | 272 | CONFIG_FANOTIFY=y |
| 273 | −CONFIG_AUTOFS4_FS=m | |
| 273 | +CONFIG_AUTOFS_FS=m | |
| 274 | 274 | CONFIG_FUSE_FS=m |
| 275 | 275 | CONFIG_OVERLAY_FS=m |
| 276 | 276 | CONFIG_ISO9660_FS=y |
| @@ -327,7 +327,7 @@ CONFIG_BTRFS_FS=m · 326 unmodified lines | ||
| 327 | 327 | CONFIG_BTRFS_FS_POSIX_ACL=y |
| 328 | 328 | CONFIG_NILFS2_FS=m |
| 329 | 329 | CONFIG_FS_DAX=y |
| 330 | −CONFIG_AUTOFS4_FS=m | |
| 330 | +CONFIG_AUTOFS_FS=m | |
| 331 | 331 | CONFIG_FUSE_FS=m |
| 332 | 332 | CONFIG_OVERLAY_FS=m |
| 333 | 333 | CONFIG_ISO9660_FS=y |
| @@ -185,7 +185,7 @@ CONFIG_JFS_SECURITY=y · 184 unmodified lines | ||
| 185 | 185 | CONFIG_XFS_FS=m |
| 186 | 186 | CONFIG_XFS_POSIX_ACL=y |
| 187 | 187 | CONFIG_FS_DAX=y |
| 188 | −CONFIG_AUTOFS4_FS=m | |
| 188 | +CONFIG_AUTOFS_FS=m | |
| 189 | 189 | CONFIG_ISO9660_FS=y |
| 190 | 190 | CONFIG_UDF_FS=m |
| 191 | 191 | CONFIG_MSDOS_FS=y |
| @@ -969,7 +969,7 @@ CONFIG_XFS_POSIX_ACL=y · 968 unmodified lines | ||
| 969 | 969 | CONFIG_GFS2_FS=m |
| 970 | 970 | CONFIG_FS_DAX=y |
| 971 | 971 | CONFIG_QUOTA_NETLINK_INTERFACE=y |
| 972 | −CONFIG_AUTOFS4_FS=m | |
| 972 | +CONFIG_AUTOFS_FS=m | |
| 973 | 973 | CONFIG_FUSE_FS=m |
| 974 | 974 | CONFIG_ISO9660_FS=y |
| 975 | 975 | CONFIG_JOLIET=y |
| @@ -129,7 +129,7 @@ CONFIG_EXT2_FS=m · 128 unmodified lines | ||
| 129 | 129 | CONFIG_EXT4_FS=y |
| 130 | 130 | CONFIG_QUOTA=y |
| 131 | 131 | CONFIG_QFMT_V2=y |
| 132 | −CONFIG_AUTOFS4_FS=m | |
| 132 | +CONFIG_AUTOFS_FS=m | |
| 133 | 133 | CONFIG_ISO9660_FS=m |
| 134 | 134 | CONFIG_JOLIET=y |
| 135 | 135 | CONFIG_UDF_FS=m |
| @@ -393,7 +393,6 @@ int validate_sp_size(unsigned long sp, struct task_struct *p, · 392 unmodified lines | ||
| 393 | 393 | */ |
| 394 | 394 | #define ARCH_HAS_PREFETCH |
| 395 | 395 | #define ARCH_HAS_PREFETCHW |
| 396 | −#define ARCH_HAS_SPINLOCK_PREFETCH | |
| 397 | 396 | |
| 398 | 397 | static inline void prefetch(const void *x) |
| 399 | 398 | { |
| @@ -411,8 +410,6 @@ static inline void prefetchw(const void *x) · 11 unmodified lines | ||
| 411 | 410 | __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x)); |
| 412 | 411 | } |
| 413 | 412 | |
| 414 | −#define spin_lock_prefetch(x) prefetchw(x) | |
| 415 | − | |
| 416 | 413 | /* asm stubs */ |
| 417 | 414 | extern unsigned long isa300_idle_stop_noloss(unsigned long psscr_val); |
| 418 | 415 | extern unsigned long isa300_idle_stop_mayloss(unsigned long psscr_val); |
| @@ -34,7 +34,7 @@ static inline long find_zero(unsigned long mask) · 33 unmodified lines | ||
| 34 | 34 | return leading_zero_bits >> 3; |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | −static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) | |
| 37 | +static inline unsigned long has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) | |
| 38 | 38 | { |
| 39 | 39 | unsigned long rhs = val | c->low_bits; |
| 40 | 40 | *data = rhs; |
| @@ -375,8 +375,7 @@ _GLOBAL(generic_secondary_smp_init) · 374 unmodified lines | ||
| 375 | 375 | beq 20f |
| 376 | 376 | |
| 377 | 377 | /* start the specified thread */ |
| 378 | − LOAD_REG_ADDR(r5, fsl_secondary_thread_init) | |
| 379 | − ld r4, 0(r5) | |
| 378 | + LOAD_REG_ADDR(r5, DOTSYM(fsl_secondary_thread_init)) | |
| 380 | 379 | bl book3e_start_thread |
| 381 | 380 | |
| 382 | 381 | /* stop the current thread */ |
| @@ -33,6 +33,9 @@ · 32 unmodified lines | ||
| 33 | 33 | * and then arrange for the ftrace function to be called. |
| 34 | 34 | */ |
| 35 | 35 | .macro ftrace_regs_entry allregs |
| 36 | + /* Create a minimal stack frame for representing B */ | |
| 37 | + PPC_STLU r1, -STACK_FRAME_MIN_SIZE(r1) | |
| 38 | + | |
| 36 | 39 | /* Create our stack frame + pt_regs */ |
| 37 | 40 | PPC_STLU r1,-SWITCH_FRAME_SIZE(r1) |
| 38 | 41 | |
| @@ -42,7 +45,7 @@ · 3 unmodified lines | ||
| 42 | 45 | |
| 43 | 46 | #ifdef CONFIG_PPC64 |
| 44 | 47 | /* Save the original return address in A's stack frame */ |
| 45 | − std r0, LRSAVE+SWITCH_FRAME_SIZE(r1) | |
| 48 | + std r0, LRSAVE+SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE(r1) | |
| 46 | 49 | /* Ok to continue? */ |
| 47 | 50 | lbz r3, PACA_FTRACE_ENABLED(r13) |
| 48 | 51 | cmpdi r3, 0 |
| @@ -77,6 +80,8 @@ · 28 unmodified lines | ||
| 77 | 80 | mflr r7 |
| 78 | 81 | /* Save it as pt_regs->nip */ |
| 79 | 82 | PPC_STL r7, _NIP(r1) |
| 83 | + /* Also save it in B's stackframe header for proper unwind */ | |
| 84 | + PPC_STL r7, LRSAVE+SWITCH_FRAME_SIZE(r1) | |
| 80 | 85 | /* Save the read LR in pt_regs->link */ |
| 81 | 86 | PPC_STL r0, _LINK(r1) |
| 82 | 87 | |
| @@ -142,7 +147,7 @@ · 59 unmodified lines | ||
| 142 | 147 | #endif |
| 143 | 148 | |
| 144 | 149 | /* Pop our stack frame */ |
| 145 | − addi r1, r1, SWITCH_FRAME_SIZE | |
| 150 | + addi r1, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE | |
| 146 | 151 | |
| 147 | 152 | #ifdef CONFIG_LIVEPATCH_64 |
| 148 | 153 | /* Based on the cmpd above, if the NIP was altered handle livepatch */ |
| @@ -314,8 +314,7 @@ void __ref vmemmap_free(unsigned long start, unsigned long end, · 313 unmodified lines | ||
| 314 | 314 | start = ALIGN_DOWN(start, page_size); |
| 315 | 315 | if (altmap) { |
| 316 | 316 | alt_start = altmap->base_pfn; |
| 317 | − alt_end = altmap->base_pfn + altmap->reserve + | |
| 318 | − altmap->free + altmap->alloc + altmap->align; | |
| 317 | + alt_end = altmap->base_pfn + altmap->reserve + altmap->free; | |
| 319 | 318 | } |
| 320 | 319 | |
| 321 | 320 | pr_debug("vmemmap_free %lx...%lx\n", start, end); |
| @@ -180,7 +180,7 @@ static void wake_hw_thread(void *info) · 179 unmodified lines | ||
| 180 | 180 | unsigned long inia; |
| 181 | 181 | int cpu = *(const int *)info; |
| 182 | 182 | |
| 183 | − inia = *(unsigned long *)fsl_secondary_thread_init; | |
| 183 | + inia = ppc_function_entry(fsl_secondary_thread_init); | |
| 184 | 184 | book3e_start_thread(cpu_thread_in_core(cpu), inia); |
| 185 | 185 | } |
| 186 | 186 | #endif |
| @@ -26,8 +26,8 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/rtc.h> |
| 27 | 27 | #include <linux/of_address.h> |
| 28 | 28 | |
| 29 | +#include <asm/early_ioremap.h> | |
| 29 | 30 | #include <asm/sections.h> |
| 30 | −#include <asm/io.h> | |
| 31 | 31 | #include <asm/machdep.h> |
| 32 | 32 | #include <asm/time.h> |
| 33 | 33 | #include <asm/nvram.h> |
| @@ -182,7 +182,7 @@ static int __init via_calibrate_decr(void) · 148 unmodified lines | ||
| 182 | 182 | return 0; |
| 183 | 183 | } |
| 184 | 184 | of_node_put(vias); |
| 185 | − via = ioremap(rsrc.start, resource_size(&rsrc)); | |
| 185 | + via = early_ioremap(rsrc.start, resource_size(&rsrc)); | |
| 186 | 186 | if (via == NULL) { |
| 187 | 187 | printk(KERN_ERR "Failed to map VIA for timer calibration !\n"); |
| 188 | 188 | return 0; |
| @@ -207,7 +207,7 @@ static int __init via_calibrate_decr(void) · 18 unmodified lines | ||
| 207 | 207 | |
| 208 | 208 | ppc_tb_freq = (dstart - dend) * 100 / 6; |
| 209 | 209 | |
| 210 | − iounmap(via); | |
| 210 | + early_iounmap((void *)via, resource_size(&rsrc)); | |
| 211 | 211 | |
| 212 | 212 | return 1; |
| 213 | 213 | } |
| @@ -192,7 +192,7 @@ CONFIG_EXT4_FS_POSIX_ACL=y · 191 unmodified lines | ||
| 192 | 192 | CONFIG_EXT4_FS_SECURITY=y |
| 193 | 193 | CONFIG_BTRFS_FS=m |
| 194 | 194 | CONFIG_BTRFS_FS_POSIX_ACL=y |
| 195 | −CONFIG_AUTOFS4_FS=y | |
| 195 | +CONFIG_AUTOFS_FS=y | |
| 196 | 196 | CONFIG_OVERLAY_FS=m |
| 197 | 197 | CONFIG_ISO9660_FS=y |
| 198 | 198 | CONFIG_JOLIET=y |
| @@ -98,7 +98,7 @@ CONFIG_RPMSG_CTRL=y · 97 unmodified lines | ||
| 98 | 98 | CONFIG_RPMSG_VIRTIO=y |
| 99 | 99 | CONFIG_EXT4_FS=y |
| 100 | 100 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 101 | −CONFIG_AUTOFS4_FS=y | |
| 101 | +CONFIG_AUTOFS_FS=y | |
| 102 | 102 | CONFIG_MSDOS_FS=y |
| 103 | 103 | CONFIG_VFAT_FS=y |
| 104 | 104 | CONFIG_TMPFS=y |
| @@ -19,7 +19,7 @@ typedef u64 phys_cpuid_t; · 18 unmodified lines | ||
| 19 | 19 | #define PHYS_CPUID_INVALID INVALID_HARTID |
| 20 | 20 | |
| 21 | 21 | /* ACPI table mapping after acpi_permanent_mmap is set */ |
| 22 | −void *acpi_os_ioremap(acpi_physical_address phys, acpi_size size); | |
| 22 | +void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size); | |
| 23 | 23 | #define acpi_os_ioremap acpi_os_ioremap |
| 24 | 24 | |
| 25 | 25 | #define acpi_strict 1 /* No out-of-spec workarounds on RISC-V */ |
| @@ -37,6 +37,10 @@ static inline void flush_dcache_page(struct page *page) · 36 unmodified lines | ||
| 37 | 37 | #define flush_icache_user_page(vma, pg, addr, len) \ |
| 38 | 38 | flush_icache_mm(vma->vm_mm, 0) |
| 39 | 39 | |
| 40 | +#ifdef CONFIG_64BIT | |
| 41 | +#define flush_cache_vmap(start, end) flush_tlb_kernel_range(start, end) | |
| 42 | +#endif | |
| 43 | + | |
| 40 | 44 | #ifndef CONFIG_SMP |
| 41 | 45 | |
| 42 | 46 | #define flush_icache_all() local_flush_icache_all() |
| @@ -101,9 +101,9 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) · 100 unmodified lines | ||
| 101 | 101 | * Relaxed I/O memory access primitives. These follow the Device memory |
| 102 | 102 | * ordering rules but do not guarantee any ordering relative to Normal memory |
| 103 | 103 | * accesses. These are defined to order the indicated access (either a read or |
| 104 | − * write) with all other I/O memory accesses. Since the platform specification | |
| 105 | − * defines that all I/O regions are strongly ordered on channel 2, no explicit | |
| 106 | − * fences are required to enforce this ordering. | |
| 104 | + * write) with all other I/O memory accesses to the same peripheral. Since the | |
| 105 | + * platform specification defines that all I/O regions are strongly ordered on | |
| 106 | + * channel 0, no explicit fences are required to enforce this ordering. | |
| 107 | 107 | */ |
| 108 | 108 | /* FIXME: These are now the same as asm-generic */ |
| 109 | 109 | #define __io_rbr() do {} while (0) |
| @@ -125,14 +125,14 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) · 15 unmodified lines | ||
| 125 | 125 | #endif |
| 126 | 126 | |
| 127 | 127 | /* |
| 128 | − * I/O memory access primitives. Reads are ordered relative to any | |
| 129 | − * following Normal memory access. Writes are ordered relative to any prior | |
| 130 | − * Normal memory access. The memory barriers here are necessary as RISC-V | |
| 128 | + * I/O memory access primitives. Reads are ordered relative to any following | |
| 129 | + * Normal memory read and delay() loop. Writes are ordered relative to any | |
| 130 | + * prior Normal memory write. The memory barriers here are necessary as RISC-V | |
| 131 | 131 | * doesn't define any ordering between the memory space and the I/O space. |
| 132 | 132 | */ |
| 133 | 133 | #define __io_br() do {} while (0) |
| 134 | −#define __io_ar(v) __asm__ __volatile__ ("fence i,r" : : : "memory") | |
| 135 | −#define __io_bw() __asm__ __volatile__ ("fence w,o" : : : "memory") | |
| 134 | +#define __io_ar(v) ({ __asm__ __volatile__ ("fence i,ir" : : : "memory"); }) | |
| 135 | +#define __io_bw() ({ __asm__ __volatile__ ("fence w,o" : : : "memory"); }) | |
| 136 | 136 | #define __io_aw() mmiowb_set_pending() |
| 137 | 137 | |
| 138 | 138 | #define readb(c) ({ u8 __v; __io_br(); __v = readb_cpu(c); __io_ar(__v); __v; }) |
| @@ -188,6 +188,8 @@ extern struct pt_alloc_ops pt_ops __initdata; · 187 unmodified lines | ||
| 188 | 188 | #define PAGE_KERNEL_IO __pgprot(_PAGE_IOREMAP) |
| 189 | 189 | |
| 190 | 190 | extern pgd_t swapper_pg_dir[]; |
| 191 | +extern pgd_t trampoline_pg_dir[]; | |
| 192 | +extern pgd_t early_pg_dir[]; | |
| 191 | 193 | |
| 192 | 194 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
| 193 | 195 | static inline int pmd_present(pmd_t pmd) |
| @@ -3,12 +3,14 @@ · 2 unmodified lines | ||
| 3 | 3 | |
| 4 | 4 | #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP |
| 5 | 5 | |
| 6 | +extern bool pgtable_l4_enabled, pgtable_l5_enabled; | |
| 7 | + | |
| 6 | 8 | #define IOREMAP_MAX_ORDER (PUD_SHIFT) |
| 7 | 9 | |
| 8 | 10 | #define arch_vmap_pud_supported arch_vmap_pud_supported |
| 9 | 11 | static inline bool arch_vmap_pud_supported(pgprot_t prot) |
| 10 | 12 | { |
| 11 | − return true; | |
| 13 | + return pgtable_l4_enabled || pgtable_l5_enabled; | |
| 12 | 14 | } |
| 13 | 15 | |
| 14 | 16 | #define arch_vmap_pmd_supported arch_vmap_pmd_supported |
| @@ -215,9 +215,9 @@ void __init __acpi_unmap_table(void __iomem *map, unsigned long size) · 214 unmodified lines | ||
| 215 | 215 | early_iounmap(map, size); |
| 216 | 216 | } |
| 217 | 217 | |
| 218 | −void *acpi_os_ioremap(acpi_physical_address phys, acpi_size size) | |
| 218 | +void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size) | |
| 219 | 219 | { |
| 220 | − return memremap(phys, size, MEMREMAP_WB); | |
| 220 | + return (void __iomem *)memremap(phys, size, MEMREMAP_WB); | |
| 221 | 221 | } |
| 222 | 222 | |
| 223 | 223 | #ifdef CONFIG_PCI |
| @@ -17,6 +17,11 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <asm/smp.h> |
| 18 | 18 | #include <asm/pgtable.h> |
| 19 | 19 | |
| 20 | +bool arch_match_cpu_phys_id(int cpu, u64 phys_id) | |
| 21 | +{ | |
| 22 | + return phys_id == cpuid_to_hartid_map(cpu); | |
| 23 | +} | |
| 24 | + | |
| 20 | 25 | /* |
| 21 | 26 | * Returns the hart ID of the given device tree node, or -ENODEV if the node |
| 22 | 27 | * isn't an enabled and valid RISC-V hart node. |
| @@ -18,4 +18,6 @@ void arch_crash_save_vmcoreinfo(void) · 17 unmodified lines | ||
| 18 | 18 | vmcoreinfo_append_str("NUMBER(MODULES_END)=0x%lx\n", MODULES_END); |
| 19 | 19 | #endif |
| 20 | 20 | vmcoreinfo_append_str("NUMBER(KERNEL_LINK_ADDR)=0x%lx\n", KERNEL_LINK_ADDR); |
| 21 | + vmcoreinfo_append_str("NUMBER(va_kernel_pa_offset)=0x%lx\n", | |
| 22 | + kernel_map.va_kernel_pa_offset); | |
| 21 | 23 | } |
| @@ -281,7 +281,7 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf, · 280 unmodified lines | ||
| 281 | 281 | kbuf.buffer = initrd; |
| 282 | 282 | kbuf.bufsz = kbuf.memsz = initrd_len; |
| 283 | 283 | kbuf.buf_align = PAGE_SIZE; |
| 284 | − kbuf.top_down = false; | |
| 284 | + kbuf.top_down = true; | |
| 285 | 285 | kbuf.mem = KEXEC_BUF_MEM_UNKNOWN; |
| 286 | 286 | ret = kexec_add_buffer(&kbuf); |
| 287 | 287 | if (ret) |
| @@ -425,6 +425,7 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi, · 137 unmodified lines | ||
| 425 | 425 | * sym, instead of searching the whole relsec. |
| 426 | 426 | */ |
| 427 | 427 | case R_RISCV_PCREL_HI20: |
| 428 | + case R_RISCV_CALL_PLT: | |
| 428 | 429 | case R_RISCV_CALL: |
| 429 | 430 | *(u64 *)loc = CLEAN_IMM(UITYPE, *(u64 *)loc) | |
| 430 | 431 | ENCODE_UJTYPE_IMM(val - addr); |
| @@ -61,11 +61,6 @@ int riscv_hartid_to_cpuid(unsigned long hartid) · 60 unmodified lines | ||
| 61 | 61 | return -ENOENT; |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | −bool arch_match_cpu_phys_id(int cpu, u64 phys_id) | |
| 65 | −{ | |
| 66 | − return phys_id == cpuid_to_hartid_map(cpu); | |
| 67 | −} | |
| 68 | − | |
| 69 | 64 | static void ipi_stop(void) |
| 70 | 65 | { |
| 71 | 66 | set_cpu_online(smp_processor_id(), false); |
| @@ -26,12 +26,13 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/kfence.h> |
| 27 | 27 | |
| 28 | 28 | #include <asm/fixmap.h> |
| 29 | −#include <asm/tlbflush.h> | |
| 30 | −#include <asm/sections.h> | |
| 31 | −#include <asm/soc.h> | |
| 32 | 29 | #include <asm/io.h> |
| 33 | −#include <asm/ptdump.h> | |
| 34 | 30 | #include <asm/numa.h> |
| 31 | +#include <asm/pgtable.h> | |
| 32 | +#include <asm/ptdump.h> | |
| 33 | +#include <asm/sections.h> | |
| 34 | +#include <asm/soc.h> | |
| 35 | +#include <asm/tlbflush.h> | |
| 35 | 36 | |
| 36 | 37 | #include "../kernel/head.h" |
| 37 | 38 | |
| @@ -214,8 +215,13 @@ static void __init setup_bootmem(void) · 176 unmodified lines | ||
| 214 | 215 | memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); |
| 215 | 216 | |
| 216 | 217 | phys_ram_end = memblock_end_of_DRAM(); |
| 218 | + | |
| 219 | + /* | |
| 220 | + * Make sure we align the start of the memory on a PMD boundary so that | |
| 221 | + * at worst, we map the linear mapping with PMD mappings. | |
| 222 | + */ | |
| 217 | 223 | if (!IS_ENABLED(CONFIG_XIP_KERNEL)) |
| 218 | − phys_ram_base = memblock_start_of_DRAM(); | |
| 224 | + phys_ram_base = memblock_start_of_DRAM() & PMD_MASK; | |
| 219 | 225 | |
| 220 | 226 | /* |
| 221 | 227 | * In 64-bit, any use of __va/__pa before this point is wrong as we |
| @@ -22,7 +22,6 @@ · 21 unmodified lines | ||
| 22 | 22 | * region is not and then we have to go down to the PUD level. |
| 23 | 23 | */ |
| 24 | 24 | |
| 25 | −extern pgd_t early_pg_dir[PTRS_PER_PGD]; | |
| 26 | 25 | pgd_t tmp_pg_dir[PTRS_PER_PGD] __page_aligned_bss; |
| 27 | 26 | p4d_t tmp_p4d[PTRS_PER_P4D] __page_aligned_bss; |
| 28 | 27 | pud_t tmp_pud[PTRS_PER_PUD] __page_aligned_bss; |
| @@ -116,7 +116,6 @@ CONFIG_UNIX=y · 115 unmodified lines | ||
| 116 | 116 | CONFIG_UNIX_DIAG=m |
| 117 | 117 | CONFIG_XFRM_USER=m |
| 118 | 118 | CONFIG_NET_KEY=m |
| 119 | −CONFIG_NET_TC_SKB_EXT=y | |
| 120 | 119 | CONFIG_SMC=m |
| 121 | 120 | CONFIG_SMC_DIAG=m |
| 122 | 121 | CONFIG_INET=y |
| @@ -193,6 +192,7 @@ CONFIG_NFT_REJECT=m · 70 unmodified lines | ||
| 193 | 192 | CONFIG_NFT_COMPAT=m |
| 194 | 193 | CONFIG_NFT_HASH=m |
| 195 | 194 | CONFIG_NFT_FIB_INET=m |
| 195 | +CONFIG_NETFILTER_XTABLES_COMPAT=y | |
| 196 | 196 | CONFIG_NETFILTER_XT_SET=m |
| 197 | 197 | CONFIG_NETFILTER_XT_TARGET_AUDIT=m |
| 198 | 198 | CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m |
| @@ -379,6 +379,7 @@ CONFIG_NET_ACT_SIMP=m · 180 unmodified lines | ||
| 379 | 379 | CONFIG_NET_ACT_SKBEDIT=m |
| 380 | 380 | CONFIG_NET_ACT_CSUM=m |
| 381 | 381 | CONFIG_NET_ACT_GATE=m |
| 382 | +CONFIG_NET_TC_SKB_EXT=y | |
| 382 | 383 | CONFIG_DNS_RESOLVER=y |
| 383 | 384 | CONFIG_OPENVSWITCH=m |
| 384 | 385 | CONFIG_VSOCKETS=m |
| @@ -395,6 +396,7 @@ CONFIG_HOTPLUG_PCI=y · 10 unmodified lines | ||
| 395 | 396 | CONFIG_HOTPLUG_PCI_S390=y |
| 396 | 397 | CONFIG_DEVTMPFS=y |
| 397 | 398 | CONFIG_DEVTMPFS_SAFE=y |
| 399 | +# CONFIG_FW_LOADER is not set | |
| 398 | 400 | CONFIG_CONNECTOR=y |
| 399 | 401 | CONFIG_ZRAM=y |
| 400 | 402 | CONFIG_BLK_DEV_LOOP=m |
| @@ -502,7 +504,6 @@ CONFIG_NLMON=m · 101 unmodified lines | ||
| 502 | 504 | # CONFIG_NET_VENDOR_GOOGLE is not set |
| 503 | 505 | # CONFIG_NET_VENDOR_HUAWEI is not set |
| 504 | 506 | # CONFIG_NET_VENDOR_INTEL is not set |
| 505 | −# CONFIG_NET_VENDOR_WANGXUN is not set | |
| 506 | 507 | # CONFIG_NET_VENDOR_LITEX is not set |
| 507 | 508 | # CONFIG_NET_VENDOR_MARVELL is not set |
| 508 | 509 | CONFIG_MLX4_EN=m |
| @@ -542,6 +543,7 @@ CONFIG_MLX5_CORE_EN=y · 33 unmodified lines | ||
| 542 | 543 | # CONFIG_NET_VENDOR_TI is not set |
| 543 | 544 | # CONFIG_NET_VENDOR_VERTEXCOM is not set |
| 544 | 545 | # CONFIG_NET_VENDOR_VIA is not set |
| 546 | +# CONFIG_NET_VENDOR_WANGXUN is not set | |
| 545 | 547 | # CONFIG_NET_VENDOR_WIZNET is not set |
| 546 | 548 | # CONFIG_NET_VENDOR_XILINX is not set |
| 547 | 549 | CONFIG_PPP=m |
| @@ -624,7 +626,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y · 76 unmodified lines | ||
| 624 | 626 | CONFIG_QUOTA_DEBUG=y |
| 625 | 627 | CONFIG_QFMT_V1=m |
| 626 | 628 | CONFIG_QFMT_V2=m |
| 627 | −CONFIG_AUTOFS4_FS=m | |
| 629 | +CONFIG_AUTOFS_FS=m | |
| 628 | 630 | CONFIG_FUSE_FS=y |
| 629 | 631 | CONFIG_CUSE=m |
| 630 | 632 | CONFIG_VIRTIO_FS=m |
| @@ -646,7 +648,6 @@ CONFIG_TMPFS=y · 15 unmodified lines | ||
| 646 | 648 | CONFIG_TMPFS_POSIX_ACL=y |
| 647 | 649 | CONFIG_TMPFS_INODE64=y |
| 648 | 650 | CONFIG_HUGETLBFS=y |
| 649 | −CONFIG_CONFIGFS_FS=m | |
| 650 | 651 | CONFIG_ECRYPT_FS=m |
| 651 | 652 | CONFIG_CRAMFS=m |
| 652 | 653 | CONFIG_SQUASHFS=m |
| @@ -690,7 +691,6 @@ CONFIG_HARDENED_USERCOPY=y · 37 unmodified lines | ||
| 690 | 691 | CONFIG_FORTIFY_SOURCE=y |
| 691 | 692 | CONFIG_SECURITY_SELINUX=y |
| 692 | 693 | CONFIG_SECURITY_SELINUX_BOOTPARAM=y |
| 693 | −CONFIG_SECURITY_SELINUX_DISABLE=y | |
| 694 | 694 | CONFIG_SECURITY_LOCKDOWN_LSM=y |
| 695 | 695 | CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y |
| 696 | 696 | CONFIG_SECURITY_LANDLOCK=y |
| @@ -744,7 +744,6 @@ CONFIG_CRYPTO_MD4=m · 47 unmodified lines | ||
| 744 | 744 | CONFIG_CRYPTO_MD5=y |
| 745 | 745 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 746 | 746 | CONFIG_CRYPTO_RMD160=m |
| 747 | −CONFIG_CRYPTO_SHA3=m | |
| 748 | 747 | CONFIG_CRYPTO_SM3_GENERIC=m |
| 749 | 748 | CONFIG_CRYPTO_VMAC=m |
| 750 | 749 | CONFIG_CRYPTO_WP512=m |
| @@ -844,6 +843,7 @@ CONFIG_PREEMPT_TRACER=y · 93 unmodified lines | ||
| 844 | 843 | CONFIG_SCHED_TRACER=y |
| 845 | 844 | CONFIG_FTRACE_SYSCALLS=y |
| 846 | 845 | CONFIG_BLK_DEV_IO_TRACE=y |
| 846 | +CONFIG_USER_EVENTS=y | |
| 847 | 847 | CONFIG_HIST_TRIGGERS=y |
| 848 | 848 | CONFIG_FTRACE_STARTUP_TEST=y |
| 849 | 849 | # CONFIG_EVENT_TRACE_STARTUP_TEST is not set |
| @@ -866,6 +866,7 @@ CONFIG_FAIL_MAKE_REQUEST=y · 16 unmodified lines | ||
| 866 | 866 | CONFIG_FAIL_IO_TIMEOUT=y |
| 867 | 867 | CONFIG_FAIL_FUTEX=y |
| 868 | 868 | CONFIG_FAULT_INJECTION_DEBUG_FS=y |
| 869 | +CONFIG_FAULT_INJECTION_CONFIGFS=y | |
| 869 | 870 | CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y |
| 870 | 871 | CONFIG_LKDTM=m |
| 871 | 872 | CONFIG_TEST_MIN_HEAP=y |
| @@ -107,7 +107,6 @@ CONFIG_UNIX=y · 106 unmodified lines | ||
| 107 | 107 | CONFIG_UNIX_DIAG=m |
| 108 | 108 | CONFIG_XFRM_USER=m |
| 109 | 109 | CONFIG_NET_KEY=m |
| 110 | −CONFIG_NET_TC_SKB_EXT=y | |
| 111 | 110 | CONFIG_SMC=m |
| 112 | 111 | CONFIG_SMC_DIAG=m |
| 113 | 112 | CONFIG_INET=y |
| @@ -184,6 +183,7 @@ CONFIG_NFT_REJECT=m · 70 unmodified lines | ||
| 184 | 183 | CONFIG_NFT_COMPAT=m |
| 185 | 184 | CONFIG_NFT_HASH=m |
| 186 | 185 | CONFIG_NFT_FIB_INET=m |
| 186 | +CONFIG_NETFILTER_XTABLES_COMPAT=y | |
| 187 | 187 | CONFIG_NETFILTER_XT_SET=m |
| 188 | 188 | CONFIG_NETFILTER_XT_TARGET_AUDIT=m |
| 189 | 189 | CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m |
| @@ -369,6 +369,7 @@ CONFIG_NET_ACT_SIMP=m · 179 unmodified lines | ||
| 369 | 369 | CONFIG_NET_ACT_SKBEDIT=m |
| 370 | 370 | CONFIG_NET_ACT_CSUM=m |
| 371 | 371 | CONFIG_NET_ACT_GATE=m |
| 372 | +CONFIG_NET_TC_SKB_EXT=y | |
| 372 | 373 | CONFIG_DNS_RESOLVER=y |
| 373 | 374 | CONFIG_OPENVSWITCH=m |
| 374 | 375 | CONFIG_VSOCKETS=m |
| @@ -385,6 +386,7 @@ CONFIG_HOTPLUG_PCI_S390=y · 10 unmodified lines | ||
| 385 | 386 | CONFIG_UEVENT_HELPER=y |
| 386 | 387 | CONFIG_DEVTMPFS=y |
| 387 | 388 | CONFIG_DEVTMPFS_SAFE=y |
| 389 | +# CONFIG_FW_LOADER is not set | |
| 388 | 390 | CONFIG_CONNECTOR=y |
| 389 | 391 | CONFIG_ZRAM=y |
| 390 | 392 | CONFIG_BLK_DEV_LOOP=m |
| @@ -492,7 +494,6 @@ CONFIG_NLMON=m · 101 unmodified lines | ||
| 492 | 494 | # CONFIG_NET_VENDOR_GOOGLE is not set |
| 493 | 495 | # CONFIG_NET_VENDOR_HUAWEI is not set |
| 494 | 496 | # CONFIG_NET_VENDOR_INTEL is not set |
| 495 | −# CONFIG_NET_VENDOR_WANGXUN is not set | |
| 496 | 497 | # CONFIG_NET_VENDOR_LITEX is not set |
| 497 | 498 | # CONFIG_NET_VENDOR_MARVELL is not set |
| 498 | 499 | CONFIG_MLX4_EN=m |
| @@ -532,6 +533,7 @@ CONFIG_MLX5_CORE_EN=y · 33 unmodified lines | ||
| 532 | 533 | # CONFIG_NET_VENDOR_TI is not set |
| 533 | 534 | # CONFIG_NET_VENDOR_VERTEXCOM is not set |
| 534 | 535 | # CONFIG_NET_VENDOR_VIA is not set |
| 536 | +# CONFIG_NET_VENDOR_WANGXUN is not set | |
| 535 | 537 | # CONFIG_NET_VENDOR_WIZNET is not set |
| 536 | 538 | # CONFIG_NET_VENDOR_XILINX is not set |
| 537 | 539 | CONFIG_PPP=m |
| @@ -609,7 +611,7 @@ CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y · 71 unmodified lines | ||
| 609 | 611 | CONFIG_QUOTA_NETLINK_INTERFACE=y |
| 610 | 612 | CONFIG_QFMT_V1=m |
| 611 | 613 | CONFIG_QFMT_V2=m |
| 612 | −CONFIG_AUTOFS4_FS=m | |
| 614 | +CONFIG_AUTOFS_FS=m | |
| 613 | 615 | CONFIG_FUSE_FS=y |
| 614 | 616 | CONFIG_CUSE=m |
| 615 | 617 | CONFIG_VIRTIO_FS=m |
| @@ -673,7 +675,6 @@ CONFIG_SECURITY=y · 57 unmodified lines | ||
| 673 | 675 | CONFIG_SECURITY_NETWORK=y |
| 674 | 676 | CONFIG_SECURITY_SELINUX=y |
| 675 | 677 | CONFIG_SECURITY_SELINUX_BOOTPARAM=y |
| 676 | −CONFIG_SECURITY_SELINUX_DISABLE=y | |
| 677 | 678 | CONFIG_SECURITY_LOCKDOWN_LSM=y |
| 678 | 679 | CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y |
| 679 | 680 | CONFIG_SECURITY_LANDLOCK=y |
| @@ -729,7 +730,6 @@ CONFIG_CRYPTO_MD4=m · 49 unmodified lines | ||
| 729 | 730 | CONFIG_CRYPTO_MD5=y |
| 730 | 731 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 731 | 732 | CONFIG_CRYPTO_RMD160=m |
| 732 | −CONFIG_CRYPTO_SHA3=m | |
| 733 | 733 | CONFIG_CRYPTO_SM3_GENERIC=m |
| 734 | 734 | CONFIG_CRYPTO_VMAC=m |
| 735 | 735 | CONFIG_CRYPTO_WP512=m |
| @@ -793,6 +793,7 @@ CONFIG_STACK_TRACER=y · 57 unmodified lines | ||
| 793 | 793 | CONFIG_SCHED_TRACER=y |
| 794 | 794 | CONFIG_FTRACE_SYSCALLS=y |
| 795 | 795 | CONFIG_BLK_DEV_IO_TRACE=y |
| 796 | +CONFIG_USER_EVENTS=y | |
| 796 | 797 | CONFIG_HIST_TRIGGERS=y |
| 797 | 798 | CONFIG_SAMPLES=y |
| 798 | 799 | CONFIG_SAMPLE_TRACE_PRINTK=m |
| @@ -53,7 +53,6 @@ CONFIG_ZFCP=y · 52 unmodified lines | ||
| 53 | 53 | # CONFIG_HVC_IUCV is not set |
| 54 | 54 | # CONFIG_HW_RANDOM_S390 is not set |
| 55 | 55 | # CONFIG_HMC_DRV is not set |
| 56 | −# CONFIG_S390_UV_UAPI is not set | |
| 57 | 56 | # CONFIG_S390_TAPE is not set |
| 58 | 57 | # CONFIG_VMCP is not set |
| 59 | 58 | # CONFIG_MONWRITER is not set |
| @@ -8,6 +8,8 @@ · 7 unmodified lines | ||
| 8 | 8 | #ifndef _UAPI_S390_PTRACE_H |
| 9 | 9 | #define _UAPI_S390_PTRACE_H |
| 10 | 10 | |
| 11 | +#include <linux/const.h> | |
| 12 | + | |
| 11 | 13 | /* |
| 12 | 14 | * Offsets in the user_regs_struct. They are used for the ptrace |
| 13 | 15 | * system call and in entry.S |
| @@ -459,9 +459,9 @@ static int sthyi_update_cache(u64 *rc) · 458 unmodified lines | ||
| 459 | 459 | * |
| 460 | 460 | * Fills the destination with system information returned by the STHYI |
| 461 | 461 | * instruction. The data is generated by emulation or execution of STHYI, |
| 462 | − * if available. The return value is the condition code that would be | |
| 463 | − * returned, the rc parameter is the return code which is passed in | |
| 464 | − * register R2 + 1. | |
| 462 | + * if available. The return value is either a negative error value or | |
| 463 | + * the condition code that would be returned, the rc parameter is the | |
| 464 | + * return code which is passed in register R2 + 1. | |
| 465 | 465 | */ |
| 466 | 466 | int sthyi_fill(void *dst, u64 *rc) |
| 467 | 467 | { |
| @@ -389,8 +389,8 @@ static int handle_partial_execution(struct kvm_vcpu *vcpu) · 388 unmodified lines | ||
| 389 | 389 | */ |
| 390 | 390 | int handle_sthyi(struct kvm_vcpu *vcpu) |
| 391 | 391 | { |
| 392 | − int reg1, reg2, r = 0; | |
| 393 | − u64 code, addr, cc = 0, rc = 0; | |
| 392 | + int reg1, reg2, cc = 0, r = 0; | |
| 393 | + u64 code, addr, rc = 0; | |
| 394 | 394 | struct sthyi_sctns *sctns = NULL; |
| 395 | 395 | |
| 396 | 396 | if (!test_kvm_facility(vcpu->kvm, 74)) |
| @@ -421,7 +421,10 @@ int handle_sthyi(struct kvm_vcpu *vcpu) · 24 unmodified lines | ||
| 421 | 421 | return -ENOMEM; |
| 422 | 422 | |
| 423 | 423 | cc = sthyi_fill(sctns, &rc); |
| 424 | − | |
| 424 | + if (cc < 0) { | |
| 425 | + free_page((unsigned long)sctns); | |
| 426 | + return cc; | |
| 427 | + } | |
| 425 | 428 | out: |
| 426 | 429 | if (!cc) { |
| 427 | 430 | if (kvm_s390_pv_cpu_is_protected(vcpu)) { |
| @@ -763,6 +763,8 @@ void __init vmem_map_init(void) · 762 unmodified lines | ||
| 763 | 763 | if (static_key_enabled(&cpu_has_bear)) |
| 764 | 764 | set_memory_nx(0, 1); |
| 765 | 765 | set_memory_nx(PAGE_SIZE, 1); |
| 766 | + if (debug_pagealloc_enabled()) | |
| 767 | + set_memory_4k(0, ident_map_size >> PAGE_SHIFT); | |
| 766 | 768 | |
| 767 | 769 | pr_info("Write protected kernel read-only data: %luk\n", |
| 768 | 770 | (unsigned long)(__end_rodata - _stext) >> 10); |
| @@ -61,7 +61,7 @@ CONFIG_USB_STORAGE=y · 60 unmodified lines | ||
| 61 | 61 | CONFIG_EXT2_FS=y |
| 62 | 62 | CONFIG_EXT3_FS=y |
| 63 | 63 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
| 64 | −CONFIG_AUTOFS4_FS=y | |
| 64 | +CONFIG_AUTOFS_FS=y | |
| 65 | 65 | CONFIG_PROC_KCORE=y |
| 66 | 66 | CONFIG_TMPFS=y |
| 67 | 67 | CONFIG_TMPFS_POSIX_ACL=y |
| @@ -105,7 +105,7 @@ CONFIG_EXT2_FS_POSIX_ACL=y · 104 unmodified lines | ||
| 105 | 105 | CONFIG_EXT3_FS=y |
| 106 | 106 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
| 107 | 107 | CONFIG_EXT3_FS_POSIX_ACL=y |
| 108 | −CONFIG_AUTOFS4_FS=y | |
| 108 | +CONFIG_AUTOFS_FS=y | |
| 109 | 109 | CONFIG_ISO9660_FS=y |
| 110 | 110 | CONFIG_MSDOS_FS=y |
| 111 | 111 | CONFIG_VFAT_FS=y |
| @@ -168,7 +168,7 @@ CONFIG_EXT3_FS=y · 167 unmodified lines | ||
| 168 | 168 | CONFIG_EXT4_FS=y |
| 169 | 169 | CONFIG_XFS_FS=y |
| 170 | 170 | CONFIG_BTRFS_FS=y |
| 171 | −CONFIG_AUTOFS4_FS=m | |
| 171 | +CONFIG_AUTOFS_FS=m | |
| 172 | 172 | CONFIG_FUSE_FS=y |
| 173 | 173 | CONFIG_CUSE=m |
| 174 | 174 | CONFIG_FSCACHE=m |
| @@ -60,7 +60,7 @@ CONFIG_EXT2_FS_XATTR=y · 59 unmodified lines | ||
| 60 | 60 | CONFIG_EXT3_FS=y |
| 61 | 61 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
| 62 | 62 | CONFIG_EXT3_FS_POSIX_ACL=y |
| 63 | −CONFIG_AUTOFS4_FS=y | |
| 63 | +CONFIG_AUTOFS_FS=y | |
| 64 | 64 | CONFIG_ISO9660_FS=m |
| 65 | 65 | CONFIG_JOLIET=y |
| 66 | 66 | CONFIG_ZISOFS=y |
| @@ -63,7 +63,7 @@ CONFIG_MMC=y · 62 unmodified lines | ||
| 63 | 63 | CONFIG_EXT2_FS=y |
| 64 | 64 | CONFIG_EXT3_FS=y |
| 65 | 65 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
| 66 | −CONFIG_AUTOFS4_FS=y | |
| 66 | +CONFIG_AUTOFS_FS=y | |
| 67 | 67 | CONFIG_MSDOS_FS=y |
| 68 | 68 | CONFIG_VFAT_FS=y |
| 69 | 69 | CONFIG_PROC_KCORE=y |
| @@ -65,7 +65,7 @@ CONFIG_EXT2_FS=y · 64 unmodified lines | ||
| 65 | 65 | CONFIG_EXT2_FS_XATTR=y |
| 66 | 66 | CONFIG_EXT2_FS_POSIX_ACL=y |
| 67 | 67 | CONFIG_EXT2_FS_SECURITY=y |
| 68 | −CONFIG_AUTOFS4_FS=m | |
| 68 | +CONFIG_AUTOFS_FS=m | |
| 69 | 69 | CONFIG_ISO9660_FS=m |
| 70 | 70 | CONFIG_PROC_KCORE=y |
| 71 | 71 | CONFIG_ROMFS_FS=m |
| @@ -213,7 +213,6 @@ unsigned long __get_wchan(struct task_struct *task); · 212 unmodified lines | ||
| 213 | 213 | */ |
| 214 | 214 | #define ARCH_HAS_PREFETCH |
| 215 | 215 | #define ARCH_HAS_PREFETCHW |
| 216 | −#define ARCH_HAS_SPINLOCK_PREFETCH | |
| 217 | 216 | |
| 218 | 217 | static inline void prefetch(const void *x) |
| 219 | 218 | { |
| @@ -239,8 +238,6 @@ static inline void prefetchw(const void *x) · 19 unmodified lines | ||
| 239 | 238 | : "r" (x)); |
| 240 | 239 | } |
| 241 | 240 | |
| 242 | −#define spin_lock_prefetch(x) prefetchw(x) | |
| 243 | − | |
| 244 | 241 | #define HAVE_ARCH_PICK_MMAP_LAYOUT |
| 245 | 242 | |
| 246 | 243 | int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap); |
| @@ -62,7 +62,7 @@ CONFIG_UML_NET_SLIRP=y · 61 unmodified lines | ||
| 62 | 62 | CONFIG_EXT4_FS=y |
| 63 | 63 | CONFIG_REISERFS_FS=y |
| 64 | 64 | CONFIG_QUOTA=y |
| 65 | −CONFIG_AUTOFS4_FS=m | |
| 65 | +CONFIG_AUTOFS_FS=m | |
| 66 | 66 | CONFIG_ISO9660_FS=m |
| 67 | 67 | CONFIG_JOLIET=y |
| 68 | 68 | CONFIG_PROC_KCORE=y |
| @@ -60,7 +60,7 @@ CONFIG_UML_NET_SLIRP=y · 59 unmodified lines | ||
| 60 | 60 | CONFIG_EXT4_FS=y |
| 61 | 61 | CONFIG_REISERFS_FS=y |
| 62 | 62 | CONFIG_QUOTA=y |
| 63 | −CONFIG_AUTOFS4_FS=m | |
| 63 | +CONFIG_AUTOFS_FS=m | |
| 64 | 64 | CONFIG_ISO9660_FS=m |
| 65 | 65 | CONFIG_JOLIET=y |
| 66 | 66 | CONFIG_PROC_KCORE=y |
| @@ -3,7 +3,6 @@ · 2 unmodified lines | ||
| 3 | 3 | * Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | −#include <linux/minmax.h> | |
| 7 | 6 | #include <unistd.h> |
| 8 | 7 | #include <errno.h> |
| 9 | 8 | #include <fcntl.h> |
| @@ -51,7 +50,7 @@ static struct pollfds all_sigio_fds; · 41 unmodified lines | ||
| 51 | 50 | |
| 52 | 51 | static int write_sigio_thread(void *unused) |
| 53 | 52 | { |
| 54 | − struct pollfds *fds; | |
| 53 | + struct pollfds *fds, tmp; | |
| 55 | 54 | struct pollfd *p; |
| 56 | 55 | int i, n, respond_fd; |
| 57 | 56 | char c; |
| @@ -78,7 +77,9 @@ static int write_sigio_thread(void *unused) · 20 unmodified lines | ||
| 78 | 77 | "write_sigio_thread : " |
| 79 | 78 | "read on socket failed, " |
| 80 | 79 | "err = %d\n", errno); |
| 81 | − swap(current_poll, next_poll); | |
| 80 | + tmp = current_poll; | |
| 81 | + current_poll = next_poll; | |
| 82 | + next_poll = tmp; | |
| 82 | 83 | respond_fd = sigio_private[1]; |
| 83 | 84 | } |
| 84 | 85 | else { |
| @@ -2593,6 +2593,13 @@ config CPU_IBRS_ENTRY · 2592 unmodified lines | ||
| 2593 | 2593 | This mitigates both spectre_v2 and retbleed at great cost to |
| 2594 | 2594 | performance. |
| 2595 | 2595 | |
| 2596 | +config CPU_SRSO | |
| 2597 | + bool "Mitigate speculative RAS overflow on AMD" | |
| 2598 | + depends on CPU_SUP_AMD && X86_64 && RETHUNK | |
| 2599 | + default y | |
| 2600 | + help | |
| 2601 | + Enable the SRSO mitigation needed on AMD Zen1-4 machines. | |
| 2602 | + | |
| 2596 | 2603 | config SLS |
| 2597 | 2604 | bool "Mitigate Straight-Line-Speculation" |
| 2598 | 2605 | depends on CC_HAS_SLS && X86_64 |
| @@ -2603,6 +2610,25 @@ config SLS · 4 unmodified lines | ||
| 2603 | 2610 | against straight line speculation. The kernel image might be slightly |
| 2604 | 2611 | larger. |
| 2605 | 2612 | |
| 2613 | +config GDS_FORCE_MITIGATION | |
| 2614 | + bool "Force GDS Mitigation" | |
| 2615 | + depends on CPU_SUP_INTEL | |
| 2616 | + default n | |
| 2617 | + help | |
| 2618 | + Gather Data Sampling (GDS) is a hardware vulnerability which allows | |
| 2619 | + unprivileged speculative access to data which was previously stored in | |
| 2620 | + vector registers. | |
| 2621 | + | |
| 2622 | + This option is equivalent to setting gather_data_sampling=force on the | |
| 2623 | + command line. The microcode mitigation is used if present, otherwise | |
| 2624 | + AVX is disabled as a mitigation. On affected systems that are missing | |
| 2625 | + the microcode any userspace code that unconditionally uses AVX will | |
| 2626 | + break with this option set. | |
| 2627 | + | |
| 2628 | + Setting this option on systems not vulnerable to GDS has no effect. | |
| 2629 | + | |
| 2630 | + If in doubt, say N. | |
| 2631 | + | |
| 2606 | 2632 | endif |
| 2607 | 2633 | |
| 2608 | 2634 | config ARCH_HAS_ADD_PAGES |
| @@ -63,7 +63,14 @@ void load_stage2_idt(void) · 62 unmodified lines | ||
| 63 | 63 | set_idt_entry(X86_TRAP_PF, boot_page_fault); |
| 64 | 64 | |
| 65 | 65 | #ifdef CONFIG_AMD_MEM_ENCRYPT |
| 66 | − set_idt_entry(X86_TRAP_VC, boot_stage2_vc); | |
| 66 | + /* | |
| 67 | + * Clear the second stage #VC handler in case guest types | |
| 68 | + * needing #VC have not been detected. | |
| 69 | + */ | |
| 70 | + if (sev_status & BIT(1)) | |
| 71 | + set_idt_entry(X86_TRAP_VC, boot_stage2_vc); | |
| 72 | + else | |
| 73 | + set_idt_entry(X86_TRAP_VC, NULL); | |
| 67 | 74 | #endif |
| 68 | 75 | |
| 69 | 76 | load_boot_idt(&boot_idt_desc); |
| @@ -404,13 +404,46 @@ void sev_enable(struct boot_params *bp) · 403 unmodified lines | ||
| 404 | 404 | if (bp) |
| 405 | 405 | bp->cc_blob_address = 0; |
| 406 | 406 | |
| 407 | + /* | |
| 408 | + * Do an initial SEV capability check before snp_init() which | |
| 409 | + * loads the CPUID page and the same checks afterwards are done | |
| 410 | + * without the hypervisor and are trustworthy. | |
| 411 | + * | |
| 412 | + * If the HV fakes SEV support, the guest will crash'n'burn | |
| 413 | + * which is good enough. | |
| 414 | + */ | |
| 415 | + | |
| 416 | + /* Check for the SME/SEV support leaf */ | |
| 417 | + eax = 0x80000000; | |
| 418 | + ecx = 0; | |
| 419 | + native_cpuid(&eax, &ebx, &ecx, &edx); | |
| 420 | + if (eax < 0x8000001f) | |
| 421 | + return; | |
| 422 | + | |
| 423 | + /* | |
| 424 | + * Check for the SME/SEV feature: | |
| 425 | + * CPUID Fn8000_001F[EAX] | |
| 426 | + * - Bit 0 - Secure Memory Encryption support | |
| 427 | + * - Bit 1 - Secure Encrypted Virtualization support | |
| 428 | + * CPUID Fn8000_001F[EBX] | |
| 429 | + * - Bits 5:0 - Pagetable bit position used to indicate encryption | |
| 430 | + */ | |
| 431 | + eax = 0x8000001f; | |
| 432 | + ecx = 0; | |
| 433 | + native_cpuid(&eax, &ebx, &ecx, &edx); | |
| 434 | + /* Check whether SEV is supported */ | |
| 435 | + if (!(eax & BIT(1))) | |
| 436 | + return; | |
| 437 | + | |
| 407 | 438 | /* |
| 408 | 439 | * Setup/preliminary detection of SNP. This will be sanity-checked |
| 409 | 440 | * against CPUID/MSR values later. |
| 410 | 441 | */ |
| 411 | 442 | snp = snp_init(bp); |
| 412 | 443 | |
| 413 | − /* Check for the SME/SEV support leaf */ | |
| 444 | + /* Now repeat the checks with the SNP CPUID table. */ | |
| 445 | + | |
| 446 | + /* Recheck the SME/SEV support leaf */ | |
| 414 | 447 | eax = 0x80000000; |
| 415 | 448 | ecx = 0; |
| 416 | 449 | native_cpuid(&eax, &ebx, &ecx, &edx); |
| @@ -418,7 +451,7 @@ void sev_enable(struct boot_params *bp) · 1 unmodified line | ||
| 418 | 451 | return; |
| 419 | 452 | |
| 420 | 453 | /* |
| 421 | − * Check for the SME/SEV feature: | |
| 454 | + * Recheck for the SME/SEV feature: | |
| 422 | 455 | * CPUID Fn8000_001F[EAX] |
| 423 | 456 | * - Bit 0 - Secure Memory Encryption support |
| 424 | 457 | * - Bit 1 - Secure Encrypted Virtualization support |
| @@ -245,7 +245,7 @@ CONFIG_QUOTA=y · 244 unmodified lines | ||
| 245 | 245 | CONFIG_QUOTA_NETLINK_INTERFACE=y |
| 246 | 246 | # CONFIG_PRINT_QUOTA_WARNING is not set |
| 247 | 247 | CONFIG_QFMT_V2=y |
| 248 | −CONFIG_AUTOFS4_FS=y | |
| 248 | +CONFIG_AUTOFS_FS=y | |
| 249 | 249 | CONFIG_ISO9660_FS=y |
| 250 | 250 | CONFIG_JOLIET=y |
| 251 | 251 | CONFIG_ZISOFS=y |
| @@ -242,7 +242,7 @@ CONFIG_QUOTA=y · 241 unmodified lines | ||
| 242 | 242 | CONFIG_QUOTA_NETLINK_INTERFACE=y |
| 243 | 243 | # CONFIG_PRINT_QUOTA_WARNING is not set |
| 244 | 244 | CONFIG_QFMT_V2=y |
| 245 | −CONFIG_AUTOFS4_FS=y | |
| 245 | +CONFIG_AUTOFS_FS=y | |
| 246 | 246 | CONFIG_ISO9660_FS=y |
| 247 | 247 | CONFIG_JOLIET=y |
| 248 | 248 | CONFIG_ZISOFS=y |
| @@ -285,7 +285,15 @@ SYM_FUNC_END(__switch_to_asm) · 284 unmodified lines | ||
| 285 | 285 | */ |
| 286 | 286 | .pushsection .text, "ax" |
| 287 | 287 | SYM_CODE_START(ret_from_fork_asm) |
| 288 | − UNWIND_HINT_REGS | |
| 288 | + /* | |
| 289 | + * This is the start of the kernel stack; even through there's a | |
| 290 | + * register set at the top, the regset isn't necessarily coherent | |
| 291 | + * (consider kthreads) and one cannot unwind further. | |
| 292 | + * | |
| 293 | + * This ensures stack unwinds of kernel threads terminate in a known | |
| 294 | + * good state. | |
| 295 | + */ | |
| 296 | + UNWIND_HINT_END_OF_STACK | |
| 289 | 297 | ANNOTATE_NOENDBR // copy_thread |
| 290 | 298 | CALL_DEPTH_ACCOUNT |
| 291 | 299 | |
| @@ -295,6 +303,12 @@ SYM_CODE_START(ret_from_fork_asm) · 3 unmodified lines | ||
| 295 | 303 | movq %r12, %rcx /* fn_arg */ |
| 296 | 304 | call ret_from_fork |
| 297 | 305 | |
| 306 | + /* | |
| 307 | + * Set the stack state to what is expected for the target function | |
| 308 | + * -- at this point the register set should be a valid user set | |
| 309 | + * and unwind should work normally. | |
| 310 | + */ | |
| 311 | + UNWIND_HINT_REGS | |
| 298 | 312 | jmp swapgs_restore_regs_and_return_to_usermode |
| 299 | 313 | SYM_CODE_END(ret_from_fork_asm) |
| 300 | 314 | .popsection |
| @@ -299,8 +299,8 @@ static unsigned long vdso_addr(unsigned long start, unsigned len) · 298 unmodified lines | ||
| 299 | 299 | |
| 300 | 300 | /* Round the lowest possible end address up to a PMD boundary. */ |
| 301 | 301 | end = (start + len + PMD_SIZE - 1) & PMD_MASK; |
| 302 | − if (end >= TASK_SIZE_MAX) | |
| 303 | − end = TASK_SIZE_MAX; | |
| 302 | + if (end >= DEFAULT_MAP_WINDOW) | |
| 303 | + end = DEFAULT_MAP_WINDOW; | |
| 304 | 304 | end -= len; |
| 305 | 305 | |
| 306 | 306 | if (end > start) { |
| @@ -107,7 +107,6 @@ static bool cpu_is_self(int cpu) · 106 unmodified lines | ||
| 107 | 107 | static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector, |
| 108 | 108 | bool exclude_self) |
| 109 | 109 | { |
| 110 | − struct hv_send_ipi_ex **arg; | |
| 111 | 110 | struct hv_send_ipi_ex *ipi_arg; |
| 112 | 111 | unsigned long flags; |
| 113 | 112 | int nr_bank = 0; |
| @@ -117,9 +116,8 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector, · 3 unmodified lines | ||
| 117 | 116 | return false; |
| 118 | 117 | |
| 119 | 118 | local_irq_save(flags); |
| 120 | − arg = (struct hv_send_ipi_ex **)this_cpu_ptr(hyperv_pcpu_input_arg); | |
| 119 | + ipi_arg = *this_cpu_ptr(hyperv_pcpu_input_arg); | |
| 121 | 120 | |
| 122 | − ipi_arg = *arg; | |
| 123 | 121 | if (unlikely(!ipi_arg)) |
| 124 | 122 | goto ipi_mask_ex_done; |
| 125 | 123 | |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <asm/apic.h> |
| 15 | 15 | #include <asm/desc.h> |
| 16 | 16 | #include <asm/sev.h> |
| 17 | +#include <asm/ibt.h> | |
| 17 | 18 | #include <asm/hypervisor.h> |
| 18 | 19 | #include <asm/hyperv-tlfs.h> |
| 19 | 20 | #include <asm/mshyperv.h> |
| @@ -471,6 +472,26 @@ void __init hyperv_init(void) · 451 unmodified lines | ||
| 471 | 472 | wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); |
| 472 | 473 | } |
| 473 | 474 | |
| 475 | + /* | |
| 476 | + * Some versions of Hyper-V that provide IBT in guest VMs have a bug | |
| 477 | + * in that there's no ENDBR64 instruction at the entry to the | |
| 478 | + * hypercall page. Because hypercalls are invoked via an indirect call | |
| 479 | + * to the hypercall page, all hypercall attempts fail when IBT is | |
| 480 | + * enabled, and Linux panics. For such buggy versions, disable IBT. | |
| 481 | + * | |
| 482 | + * Fixed versions of Hyper-V always provide ENDBR64 on the hypercall | |
| 483 | + * page, so if future Linux kernel versions enable IBT for 32-bit | |
| 484 | + * builds, additional hypercall page hackery will be required here | |
| 485 | + * to provide an ENDBR32. | |
| 486 | + */ | |
| 487 | +#ifdef CONFIG_X86_KERNEL_IBT | |
| 488 | + if (cpu_feature_enabled(X86_FEATURE_IBT) && | |
| 489 | + *(u32 *)hv_hypercall_pg != gen_endbr()) { | |
| 490 | + setup_clear_cpu_cap(X86_FEATURE_IBT); | |
| 491 | + pr_warn("Hyper-V: Disabling IBT because of Hyper-V bug\n"); | |
| 492 | + } | |
| 493 | +#endif | |
| 494 | + | |
| 474 | 495 | /* |
| 475 | 496 | * hyperv_init() is called before LAPIC is initialized: see |
| 476 | 497 | * apic_intr_mode_init() -> x86_platform.apic_post_init() and |
| @@ -25,6 +25,10 @@ void __init hv_vtl_init_platform(void) · 24 unmodified lines | ||
| 25 | 25 | x86_init.irqs.pre_vector_init = x86_init_noop; |
| 26 | 26 | x86_init.timers.timer_init = x86_init_noop; |
| 27 | 27 | |
| 28 | + /* Avoid searching for BIOS MP tables */ | |
| 29 | + x86_init.mpparse.find_smp_config = x86_init_noop; | |
| 30 | + x86_init.mpparse.get_smp_config = x86_init_uint_noop; | |
| 31 | + | |
| 28 | 32 | x86_platform.get_wallclock = get_rtc_noop; |
| 29 | 33 | x86_platform.set_wallclock = set_rtc_noop; |
| 30 | 34 | x86_platform.get_nmi_reason = hv_get_nmi_reason; |
| @@ -247,7 +247,7 @@ EXPORT_SYMBOL_GPL(hv_ghcb_msr_read); · 246 unmodified lines | ||
| 247 | 247 | static int hv_mark_gpa_visibility(u16 count, const u64 pfn[], |
| 248 | 248 | enum hv_mem_host_visibility visibility) |
| 249 | 249 | { |
| 250 | − struct hv_gpa_range_for_visibility **input_pcpu, *input; | |
| 250 | + struct hv_gpa_range_for_visibility *input; | |
| 251 | 251 | u16 pages_processed; |
| 252 | 252 | u64 hv_status; |
| 253 | 253 | unsigned long flags; |
| @@ -263,9 +263,8 @@ static int hv_mark_gpa_visibility(u16 count, const u64 pfn[], · 9 unmodified lines | ||
| 263 | 263 | } |
| 264 | 264 | |
| 265 | 265 | local_irq_save(flags); |
| 266 | − input_pcpu = (struct hv_gpa_range_for_visibility **) | |
| 267 | − this_cpu_ptr(hyperv_pcpu_input_arg); | |
| 268 | − input = *input_pcpu; | |
| 266 | + input = *this_cpu_ptr(hyperv_pcpu_input_arg); | |
| 267 | + | |
| 269 | 268 | if (unlikely(!input)) { |
| 270 | 269 | local_irq_restore(flags); |
| 271 | 270 | return -EINVAL; |
| @@ -61,7 +61,6 @@ static void hyperv_flush_tlb_multi(const struct cpumask *cpus, · 60 unmodified lines | ||
| 61 | 61 | const struct flush_tlb_info *info) |
| 62 | 62 | { |
| 63 | 63 | int cpu, vcpu, gva_n, max_gvas; |
| 64 | − struct hv_tlb_flush **flush_pcpu; | |
| 65 | 64 | struct hv_tlb_flush *flush; |
| 66 | 65 | u64 status; |
| 67 | 66 | unsigned long flags; |
| @@ -74,10 +73,7 @@ static void hyperv_flush_tlb_multi(const struct cpumask *cpus, · 6 unmodified lines | ||
| 74 | 73 | |
| 75 | 74 | local_irq_save(flags); |
| 76 | 75 | |
| 77 | − flush_pcpu = (struct hv_tlb_flush **) | |
| 78 | − this_cpu_ptr(hyperv_pcpu_input_arg); | |
| 79 | − | |
| 80 | − flush = *flush_pcpu; | |
| 76 | + flush = *this_cpu_ptr(hyperv_pcpu_input_arg); | |
| 81 | 77 | |
| 82 | 78 | if (unlikely(!flush)) { |
| 83 | 79 | local_irq_restore(flags); |
| @@ -178,17 +174,13 @@ static u64 hyperv_flush_tlb_others_ex(const struct cpumask *cpus, · 94 unmodified lines | ||
| 178 | 174 | const struct flush_tlb_info *info) |
| 179 | 175 | { |
| 180 | 176 | int nr_bank = 0, max_gvas, gva_n; |
| 181 | − struct hv_tlb_flush_ex **flush_pcpu; | |
| 182 | 177 | struct hv_tlb_flush_ex *flush; |
| 183 | 178 | u64 status; |
| 184 | 179 | |
| 185 | 180 | if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED)) |
| 186 | 181 | return HV_STATUS_INVALID_PARAMETER; |
| 187 | 182 | |
| 188 | − flush_pcpu = (struct hv_tlb_flush_ex **) | |
| 189 | − this_cpu_ptr(hyperv_pcpu_input_arg); | |
| 190 | − | |
| 191 | − flush = *flush_pcpu; | |
| 183 | + flush = *this_cpu_ptr(hyperv_pcpu_input_arg); | |
| 192 | 184 | |
| 193 | 185 | if (info->mm) { |
| 194 | 186 | /* |
| @@ -19,7 +19,6 @@ · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | int hyperv_flush_guest_mapping(u64 as) |
| 21 | 21 | { |
| 22 | − struct hv_guest_mapping_flush **flush_pcpu; | |
| 23 | 22 | struct hv_guest_mapping_flush *flush; |
| 24 | 23 | u64 status; |
| 25 | 24 | unsigned long flags; |
| @@ -30,10 +29,7 @@ int hyperv_flush_guest_mapping(u64 as) · 4 unmodified lines | ||
| 30 | 29 | |
| 31 | 30 | local_irq_save(flags); |
| 32 | 31 | |
| 33 | − flush_pcpu = (struct hv_guest_mapping_flush **) | |
| 34 | − this_cpu_ptr(hyperv_pcpu_input_arg); | |
| 35 | − | |
| 36 | − flush = *flush_pcpu; | |
| 32 | + flush = *this_cpu_ptr(hyperv_pcpu_input_arg); | |
| 37 | 33 | |
| 38 | 34 | if (unlikely(!flush)) { |
| 39 | 35 | local_irq_restore(flags); |
| @@ -90,7 +86,6 @@ EXPORT_SYMBOL_GPL(hyperv_fill_flush_guest_mapping_list); · 50 unmodified lines | ||
| 90 | 86 | int hyperv_flush_guest_mapping_range(u64 as, |
| 91 | 87 | hyperv_fill_flush_list_func fill_flush_list_func, void *data) |
| 92 | 88 | { |
| 93 | − struct hv_guest_mapping_flush_list **flush_pcpu; | |
| 94 | 89 | struct hv_guest_mapping_flush_list *flush; |
| 95 | 90 | u64 status; |
| 96 | 91 | unsigned long flags; |
| @@ -102,10 +97,8 @@ int hyperv_flush_guest_mapping_range(u64 as, · 5 unmodified lines | ||
| 102 | 97 | |
| 103 | 98 | local_irq_save(flags); |
| 104 | 99 | |
| 105 | − flush_pcpu = (struct hv_guest_mapping_flush_list **) | |
| 106 | − this_cpu_ptr(hyperv_pcpu_input_arg); | |
| 100 | + flush = *this_cpu_ptr(hyperv_pcpu_input_arg); | |
| 107 | 101 | |
| 108 | − flush = *flush_pcpu; | |
| 109 | 102 | if (unlikely(!flush)) { |
| 110 | 103 | local_irq_restore(flags); |
| 111 | 104 | goto fault; |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <asm/mpspec.h> |
| 16 | 16 | #include <asm/x86_init.h> |
| 17 | 17 | #include <asm/cpufeature.h> |
| 18 | +#include <asm/irq_vectors.h> | |
| 18 | 19 | |
| 19 | 20 | #ifdef CONFIG_ACPI_APEI |
| 20 | 21 | # include <asm/pgtable_types.h> |
| @@ -31,6 +32,7 @@ extern int acpi_skip_timer_override; · 10 unmodified lines | ||
| 31 | 32 | extern int acpi_use_timer_override; |
| 32 | 33 | extern int acpi_fix_pin2_polarity; |
| 33 | 34 | extern int acpi_disable_cmcff; |
| 35 | +extern bool acpi_int_src_ovr[NR_IRQS_LEGACY]; | |
| 34 | 36 | |
| 35 | 37 | extern u8 acpi_sci_flags; |
| 36 | 38 | extern u32 acpi_sci_override_gsi; |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | * Defines x86 CPU feature bits |
| 15 | 15 | */ |
| 16 | 16 | #define NCAPINTS 21 /* N 32-bit words worth of info */ |
| 17 | −#define NBUGINTS 1 /* N 32-bit bug flags */ | |
| 17 | +#define NBUGINTS 2 /* N 32-bit bug flags */ | |
| 18 | 18 | |
| 19 | 19 | /* |
| 20 | 20 | * Note: If the comment begins with a quoted string, that string is used |
| @@ -309,6 +309,10 @@ · 288 unmodified lines | ||
| 309 | 309 | #define X86_FEATURE_SMBA (11*32+21) /* "" Slow Memory Bandwidth Allocation */ |
| 310 | 310 | #define X86_FEATURE_BMEC (11*32+22) /* "" Bandwidth Monitoring Event Configuration */ |
| 311 | 311 | |
| 312 | +#define X86_FEATURE_SRSO (11*32+24) /* "" AMD BTB untrain RETs */ | |
| 313 | +#define X86_FEATURE_SRSO_ALIAS (11*32+25) /* "" AMD BTB untrain RETs through aliasing */ | |
| 314 | +#define X86_FEATURE_IBPB_ON_VMEXIT (11*32+26) /* "" Issue an IBPB only on VMEXIT */ | |
| 315 | + | |
| 312 | 316 | /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ |
| 313 | 317 | #define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */ |
| 314 | 318 | #define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */ |
| @@ -442,6 +446,10 @@ · 127 unmodified lines | ||
| 442 | 446 | #define X86_FEATURE_AUTOIBRS (20*32+ 8) /* "" Automatic IBRS */ |
| 443 | 447 | #define X86_FEATURE_NO_SMM_CTL_MSR (20*32+ 9) /* "" SMM_CTL MSR is not present */ |
| 444 | 448 | |
| 449 | +#define X86_FEATURE_SBPB (20*32+27) /* "" Selective Branch Prediction Barrier */ | |
| 450 | +#define X86_FEATURE_IBPB_BRTYPE (20*32+28) /* "" MSR_PRED_CMD[IBPB] flushes all branch type predictions */ | |
| 451 | +#define X86_FEATURE_SRSO_NO (20*32+29) /* "" CPU is not affected by SRSO */ | |
| 452 | + | |
| 445 | 453 | /* |
| 446 | 454 | * BUG word(s) |
| 447 | 455 | */ |
| @@ -483,5 +491,9 @@ · 35 unmodified lines | ||
| 483 | 491 | #define X86_BUG_RETBLEED X86_BUG(27) /* CPU is affected by RETBleed */ |
| 484 | 492 | #define X86_BUG_EIBRS_PBRSB X86_BUG(28) /* EIBRS is vulnerable to Post Barrier RSB Predictions */ |
| 485 | 493 | #define X86_BUG_SMT_RSB X86_BUG(29) /* CPU is vulnerable to Cross-Thread Return Address Predictions */ |
| 494 | +#define X86_BUG_GDS X86_BUG(30) /* CPU is affected by Gather Data Sampling */ | |
| 486 | 495 | |
| 496 | +/* BUG word 2 */ | |
| 497 | +#define X86_BUG_SRSO X86_BUG(1*32 + 0) /* AMD SRSO bug */ | |
| 498 | +#define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* AMD DIV0 speculation bug */ | |
| 487 | 499 | #endif /* _ASM_X86_CPUFEATURES_H */ |
| @@ -37,6 +37,7 @@ KVM_X86_OP(get_segment) · 36 unmodified lines | ||
| 37 | 37 | KVM_X86_OP(get_cpl) |
| 38 | 38 | KVM_X86_OP(set_segment) |
| 39 | 39 | KVM_X86_OP(get_cs_db_l_bits) |
| 40 | +KVM_X86_OP(is_valid_cr0) | |
| 40 | 41 | KVM_X86_OP(set_cr0) |
| 41 | 42 | KVM_X86_OP_OPTIONAL(post_set_cr3) |
| 42 | 43 | KVM_X86_OP(is_valid_cr4) |
| @@ -1566,9 +1566,10 @@ struct kvm_x86_ops { · 1565 unmodified lines | ||
| 1566 | 1566 | void (*set_segment)(struct kvm_vcpu *vcpu, |
| 1567 | 1567 | struct kvm_segment *var, int seg); |
| 1568 | 1568 | void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l); |
| 1569 | + bool (*is_valid_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0); | |
| 1569 | 1570 | void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0); |
| 1570 | 1571 | void (*post_set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3); |
| 1571 | − bool (*is_valid_cr4)(struct kvm_vcpu *vcpu, unsigned long cr0); | |
| 1572 | + bool (*is_valid_cr4)(struct kvm_vcpu *vcpu, unsigned long cr4); | |
| 1572 | 1573 | void (*set_cr4)(struct kvm_vcpu *vcpu, unsigned long cr4); |
| 1573 | 1574 | int (*set_efer)(struct kvm_vcpu *vcpu, u64 efer); |
| 1574 | 1575 | void (*get_idt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); |
| @@ -21,7 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #define FUNCTION_PADDING |
| 22 | 22 | #endif |
| 23 | 23 | |
| 24 | −#if (CONFIG_FUNCTION_ALIGNMENT > 8) && !defined(__DISABLE_EXPORTS) && !defined(BULID_VDSO) | |
| 24 | +#if (CONFIG_FUNCTION_ALIGNMENT > 8) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO) | |
| 25 | 25 | # define __FUNC_ALIGN __ALIGN; FUNCTION_PADDING |
| 26 | 26 | #else |
| 27 | 27 | # define __FUNC_ALIGN __ALIGN |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <asm/cpu.h> |
| 6 | 6 | #include <linux/earlycpio.h> |
| 7 | 7 | #include <linux/initrd.h> |
| 8 | +#include <asm/microcode_amd.h> | |
| 8 | 9 | |
| 9 | 10 | struct ucode_patch { |
| 10 | 11 | struct list_head plist; |
| @@ -48,11 +48,13 @@ extern void __init load_ucode_amd_bsp(unsigned int family); · 47 unmodified lines | ||
| 48 | 48 | extern void load_ucode_amd_ap(unsigned int family); |
| 49 | 49 | extern int __init save_microcode_in_initrd_amd(unsigned int family); |
| 50 | 50 | void reload_ucode_amd(unsigned int cpu); |
| 51 | +extern void amd_check_microcode(void); | |
| 51 | 52 | #else |
| 52 | 53 | static inline void __init load_ucode_amd_bsp(unsigned int family) {} |
| 53 | 54 | static inline void load_ucode_amd_ap(unsigned int family) {} |
| 54 | 55 | static inline int __init |
| 55 | 56 | save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; } |
| 56 | 57 | static inline void reload_ucode_amd(unsigned int cpu) {} |
| 58 | +static inline void amd_check_microcode(void) {} | |
| 57 | 59 | #endif |
| 58 | 60 | #endif /* _ASM_X86_MICROCODE_AMD_H */ |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <linux/types.h> |
| 6 | 6 | #include <linux/nmi.h> |
| 7 | 7 | #include <linux/msi.h> |
| 8 | −#include <asm/io.h> | |
| 8 | +#include <linux/io.h> | |
| 9 | 9 | #include <asm/hyperv-tlfs.h> |
| 10 | 10 | #include <asm/nospec-branch.h> |
| 11 | 11 | #include <asm/paravirt.h> |
| @@ -57,6 +57,7 @@ · 56 unmodified lines | ||
| 57 | 57 | |
| 58 | 58 | #define MSR_IA32_PRED_CMD 0x00000049 /* Prediction Command */ |
| 59 | 59 | #define PRED_CMD_IBPB BIT(0) /* Indirect Branch Prediction Barrier */ |
| 60 | +#define PRED_CMD_SBPB BIT(7) /* Selective Branch Prediction Barrier */ | |
| 60 | 61 | |
| 61 | 62 | #define MSR_PPIN_CTL 0x0000004e |
| 62 | 63 | #define MSR_PPIN 0x0000004f |
| @@ -155,6 +156,15 @@ · 92 unmodified lines | ||
| 155 | 156 | * Not susceptible to Post-Barrier |
| 156 | 157 | * Return Stack Buffer Predictions. |
| 157 | 158 | */ |
| 159 | +#define ARCH_CAP_GDS_CTRL BIT(25) /* | |
| 160 | + * CPU is vulnerable to Gather | |
| 161 | + * Data Sampling (GDS) and | |
| 162 | + * has controls for mitigation. | |
| 163 | + */ | |
| 164 | +#define ARCH_CAP_GDS_NO BIT(26) /* | |
| 165 | + * CPU is not vulnerable to Gather | |
| 166 | + * Data Sampling (GDS). | |
| 167 | + */ | |
| 158 | 168 | |
| 159 | 169 | #define ARCH_CAP_XAPIC_DISABLE BIT(21) /* |
| 160 | 170 | * IA32_XAPIC_DISABLE_STATUS MSR |
| @@ -178,6 +188,8 @@ · 17 unmodified lines | ||
| 178 | 188 | #define RNGDS_MITG_DIS BIT(0) /* SRBDS support */ |
| 179 | 189 | #define RTM_ALLOW BIT(1) /* TSX development mode */ |
| 180 | 190 | #define FB_CLEAR_DIS BIT(3) /* CPU Fill buffer clear disable */ |
| 191 | +#define GDS_MITG_DIS BIT(4) /* Disable GDS mitigation */ | |
| 192 | +#define GDS_MITG_LOCKED BIT(5) /* GDS mitigation locked */ | |
| 181 | 193 | |
| 182 | 194 | #define MSR_IA32_SYSENTER_CS 0x00000174 |
| 183 | 195 | #define MSR_IA32_SYSENTER_ESP 0x00000175 |
| @@ -545,6 +557,7 @@ · 361 unmodified lines | ||
| 545 | 557 | #define MSR_AMD64_DE_CFG 0xc0011029 |
| 546 | 558 | #define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT 1 |
| 547 | 559 | #define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE BIT_ULL(MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT) |
| 560 | +#define MSR_AMD64_DE_CFG_ZEN2_FP_BACKUP_FIX_BIT 9 | |
| 548 | 561 | |
| 549 | 562 | #define MSR_AMD64_BU_CFG2 0xc001102a |
| 550 | 563 | #define MSR_AMD64_IBSFETCHCTL 0xc0011030 |
| @@ -211,7 +211,8 @@ · 210 unmodified lines | ||
| 211 | 211 | * eventually turn into it's own annotation. |
| 212 | 212 | */ |
| 213 | 213 | .macro VALIDATE_UNRET_END |
| 214 | −#if defined(CONFIG_NOINSTR_VALIDATION) && defined(CONFIG_CPU_UNRET_ENTRY) | |
| 214 | +#if defined(CONFIG_NOINSTR_VALIDATION) && \ | |
| 215 | + (defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_SRSO)) | |
| 215 | 216 | ANNOTATE_RETPOLINE_SAFE |
| 216 | 217 | nop |
| 217 | 218 | #endif |
| @@ -289,13 +290,18 @@ · 71 unmodified lines | ||
| 289 | 290 | */ |
| 290 | 291 | .macro UNTRAIN_RET |
| 291 | 292 | #if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_IBPB_ENTRY) || \ |
| 292 | − defined(CONFIG_CALL_DEPTH_TRACKING) | |
| 293 | + defined(CONFIG_CALL_DEPTH_TRACKING) || defined(CONFIG_CPU_SRSO) | |
| 293 | 294 | VALIDATE_UNRET_END |
| 294 | 295 | ALTERNATIVE_3 "", \ |
| 295 | 296 | CALL_ZEN_UNTRAIN_RET, X86_FEATURE_UNRET, \ |
| 296 | 297 | "call entry_ibpb", X86_FEATURE_ENTRY_IBPB, \ |
| 297 | 298 | __stringify(RESET_CALL_DEPTH), X86_FEATURE_CALL_DEPTH |
| 298 | 299 | #endif |
| 300 | + | |
| 301 | +#ifdef CONFIG_CPU_SRSO | |
| 302 | + ALTERNATIVE_2 "", "call srso_untrain_ret", X86_FEATURE_SRSO, \ | |
| 303 | + "call srso_untrain_ret_alias", X86_FEATURE_SRSO_ALIAS | |
| 304 | +#endif | |
| 299 | 305 | .endm |
| 300 | 306 | |
| 301 | 307 | .macro UNTRAIN_RET_FROM_CALL |
| @@ -307,6 +313,11 @@ · 5 unmodified lines | ||
| 307 | 313 | "call entry_ibpb", X86_FEATURE_ENTRY_IBPB, \ |
| 308 | 314 | __stringify(RESET_CALL_DEPTH_FROM_CALL), X86_FEATURE_CALL_DEPTH |
| 309 | 315 | #endif |
| 316 | + | |
| 317 | +#ifdef CONFIG_CPU_SRSO | |
| 318 | + ALTERNATIVE_2 "", "call srso_untrain_ret", X86_FEATURE_SRSO, \ | |
| 319 | + "call srso_untrain_ret_alias", X86_FEATURE_SRSO_ALIAS | |
| 320 | +#endif | |
| 310 | 321 | .endm |
| 311 | 322 | |
| 312 | 323 | |
| @@ -332,6 +343,8 @@ extern retpoline_thunk_t __x86_indirect_jump_thunk_array[]; · 19 unmodified lines | ||
| 332 | 343 | |
| 333 | 344 | extern void __x86_return_thunk(void); |
| 334 | 345 | extern void zen_untrain_ret(void); |
| 346 | +extern void srso_untrain_ret(void); | |
| 347 | +extern void srso_untrain_ret_alias(void); | |
| 335 | 348 | extern void entry_ibpb(void); |
| 336 | 349 | |
| 337 | 350 | #ifdef CONFIG_CALL_THUNKS |
| @@ -479,11 +492,11 @@ void alternative_msr_write(unsigned int msr, u64 val, unsigned int feature) · 141 unmodified lines | ||
| 479 | 492 | : "memory"); |
| 480 | 493 | } |
| 481 | 494 | |
| 495 | +extern u64 x86_pred_cmd; | |
| 496 | + | |
| 482 | 497 | static inline void indirect_branch_prediction_barrier(void) |
| 483 | 498 | { |
| 484 | − u64 val = PRED_CMD_IBPB; | |
| 485 | − | |
| 486 | − alternative_msr_write(MSR_IA32_PRED_CMD, val, X86_FEATURE_USE_IBPB); | |
| 499 | + alternative_msr_write(MSR_IA32_PRED_CMD, x86_pred_cmd, X86_FEATURE_USE_IBPB); | |
| 487 | 500 | } |
| 488 | 501 | |
| 489 | 502 | /* The Intel SPEC CTRL MSR base value cache */ |
| @@ -586,7 +586,6 @@ extern char ignore_fpu_irq; · 585 unmodified lines | ||
| 586 | 586 | |
| 587 | 587 | #define HAVE_ARCH_PICK_MMAP_LAYOUT 1 |
| 588 | 588 | #define ARCH_HAS_PREFETCHW |
| 589 | −#define ARCH_HAS_SPINLOCK_PREFETCH | |
| 590 | 589 | |
| 591 | 590 | #ifdef CONFIG_X86_32 |
| 592 | 591 | # define BASE_PREFETCH "" |
| @@ -620,11 +619,6 @@ static __always_inline void prefetchw(const void *x) · 27 unmodified lines | ||
| 620 | 619 | "m" (*(const char *)x)); |
| 621 | 620 | } |
| 622 | 621 | |
| 623 | −static inline void spin_lock_prefetch(const void *x) | |
| 624 | −{ | |
| 625 | − prefetchw(x); | |
| 626 | −} | |
| 627 | − | |
| 628 | 622 | #define TOP_OF_INIT_STACK ((unsigned long)&init_stack + sizeof(init_stack) - \ |
| 629 | 623 | TOP_OF_KERNEL_STACK_PADDING) |
| 630 | 624 | |
| @@ -682,9 +676,13 @@ extern u16 get_llc_id(unsigned int cpu); · 51 unmodified lines | ||
| 682 | 676 | #ifdef CONFIG_CPU_SUP_AMD |
| 683 | 677 | extern u32 amd_get_nodes_per_socket(void); |
| 684 | 678 | extern u32 amd_get_highest_perf(void); |
| 679 | +extern bool cpu_has_ibpb_brtype_microcode(void); | |
| 680 | +extern void amd_clear_divider(void); | |
| 685 | 681 | #else |
| 686 | 682 | static inline u32 amd_get_nodes_per_socket(void) { return 0; } |
| 687 | 683 | static inline u32 amd_get_highest_perf(void) { return 0; } |
| 684 | +static inline bool cpu_has_ibpb_brtype_microcode(void) { return false; } | |
| 685 | +static inline void amd_clear_divider(void) { } | |
| 688 | 686 | #endif |
| 689 | 687 | |
| 690 | 688 | extern unsigned long arch_align_stack(unsigned long sp); |
| @@ -727,4 +725,6 @@ bool arch_is_platform_page(u64 paddr); · 36 unmodified lines | ||
| 727 | 725 | #define arch_is_platform_page arch_is_platform_page |
| 728 | 726 | #endif |
| 729 | 727 | |
| 728 | +extern bool gds_ucode_mitigated(void); | |
| 729 | + | |
| 730 | 730 | #endif /* _ASM_X86_PROCESSOR_H */ |
| @@ -56,7 +56,7 @@ · 55 unmodified lines | ||
| 56 | 56 | |
| 57 | 57 | #define GDT_ENTRY_INVALID_SEG 0 |
| 58 | 58 | |
| 59 | −#ifdef CONFIG_X86_32 | |
| 59 | +#if defined(CONFIG_X86_32) && !defined(BUILD_VDSO32_64) | |
| 60 | 60 | /* |
| 61 | 61 | * The layout of the per-CPU GDT under Linux: |
| 62 | 62 | * |
| @@ -52,6 +52,7 @@ int acpi_lapic; · 51 unmodified lines | ||
| 52 | 52 | int acpi_ioapic; |
| 53 | 53 | int acpi_strict; |
| 54 | 54 | int acpi_disable_cmcff; |
| 55 | +bool acpi_int_src_ovr[NR_IRQS_LEGACY]; | |
| 55 | 56 | |
| 56 | 57 | /* ACPI SCI override configuration */ |
| 57 | 58 | u8 acpi_sci_flags __initdata; |
| @@ -588,6 +589,9 @@ acpi_parse_int_src_ovr(union acpi_subtable_headers * header, · 530 unmodified lines | ||
| 588 | 589 | |
| 589 | 590 | acpi_table_print_madt_entry(&header->common); |
| 590 | 591 | |
| 592 | + if (intsrc->source_irq < NR_IRQS_LEGACY) | |
| 593 | + acpi_int_src_ovr[intsrc->source_irq] = true; | |
| 594 | + | |
| 591 | 595 | if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) { |
| 592 | 596 | acpi_sci_ioapic_setup(intsrc->source_irq, |
| 593 | 597 | intsrc->inti_flags & ACPI_MADT_POLARITY_MASK, |
| @@ -27,11 +27,6 @@ · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | #include "cpu.h" |
| 29 | 29 | |
| 30 | −static const int amd_erratum_383[]; | |
| 31 | −static const int amd_erratum_400[]; | |
| 32 | −static const int amd_erratum_1054[]; | |
| 33 | −static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum); | |
| 34 | − | |
| 35 | 30 | /* |
| 36 | 31 | * nodes_per_socket: Stores the number of nodes per socket. |
| 37 | 32 | * Refer to Fam15h Models 00-0fh BKDG - CPUID Fn8000_001E_ECX |
| @@ -39,6 +34,83 @@ static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum); · 1 unmodified line | ||
| 39 | 34 | */ |
| 40 | 35 | static u32 nodes_per_socket = 1; |
| 41 | 36 | |
| 37 | +/* | |
| 38 | + * AMD errata checking | |
| 39 | + * | |
| 40 | + * Errata are defined as arrays of ints using the AMD_LEGACY_ERRATUM() or | |
| 41 | + * AMD_OSVW_ERRATUM() macros. The latter is intended for newer errata that | |
| 42 | + * have an OSVW id assigned, which it takes as first argument. Both take a | |
| 43 | + * variable number of family-specific model-stepping ranges created by | |
| 44 | + * AMD_MODEL_RANGE(). | |
| 45 | + * | |
| 46 | + * Example: | |
| 47 | + * | |
| 48 | + * const int amd_erratum_319[] = | |
| 49 | + * AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0x4, 0x2), | |
| 50 | + * AMD_MODEL_RANGE(0x10, 0x8, 0x0, 0x8, 0x0), | |
| 51 | + * AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0)); | |
| 52 | + */ | |
| 53 | + | |
| 54 | +#define AMD_LEGACY_ERRATUM(...) { -1, __VA_ARGS__, 0 } | |
| 55 | +#define AMD_OSVW_ERRATUM(osvw_id, ...) { osvw_id, __VA_ARGS__, 0 } | |
| 56 | +#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \ | |
| 57 | + ((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end)) | |
| 58 | +#define AMD_MODEL_RANGE_FAMILY(range) (((range) >> 24) & 0xff) | |
| 59 | +#define AMD_MODEL_RANGE_START(range) (((range) >> 12) & 0xfff) | |
| 60 | +#define AMD_MODEL_RANGE_END(range) ((range) & 0xfff) | |
| 61 | + | |
| 62 | +static const int amd_erratum_400[] = | |
| 63 | + AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf), | |
| 64 | + AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf)); | |
| 65 | + | |
| 66 | +static const int amd_erratum_383[] = | |
| 67 | + AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf)); | |
| 68 | + | |
| 69 | +/* #1054: Instructions Retired Performance Counter May Be Inaccurate */ | |
| 70 | +static const int amd_erratum_1054[] = | |
| 71 | + AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf)); | |
| 72 | + | |
| 73 | +static const int amd_zenbleed[] = | |
| 74 | + AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0x30, 0x0, 0x4f, 0xf), | |
| 75 | + AMD_MODEL_RANGE(0x17, 0x60, 0x0, 0x7f, 0xf), | |
| 76 | + AMD_MODEL_RANGE(0x17, 0x90, 0x0, 0x91, 0xf), | |
| 77 | + AMD_MODEL_RANGE(0x17, 0xa0, 0x0, 0xaf, 0xf)); | |
| 78 | + | |
| 79 | +static const int amd_div0[] = | |
| 80 | + AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0x00, 0x0, 0x2f, 0xf), | |
| 81 | + AMD_MODEL_RANGE(0x17, 0x50, 0x0, 0x5f, 0xf)); | |
| 82 | + | |
| 83 | +static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) | |
| 84 | +{ | |
| 85 | + int osvw_id = *erratum++; | |
| 86 | + u32 range; | |
| 87 | + u32 ms; | |
| 88 | + | |
| 89 | + if (osvw_id >= 0 && osvw_id < 65536 && | |
| 90 | + cpu_has(cpu, X86_FEATURE_OSVW)) { | |
| 91 | + u64 osvw_len; | |
| 92 | + | |
| 93 | + rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, osvw_len); | |
| 94 | + if (osvw_id < osvw_len) { | |
| 95 | + u64 osvw_bits; | |
| 96 | + | |
| 97 | + rdmsrl(MSR_AMD64_OSVW_STATUS + (osvw_id >> 6), | |
| 98 | + osvw_bits); | |
| 99 | + return osvw_bits & (1ULL << (osvw_id & 0x3f)); | |
| 100 | + } | |
| 101 | + } | |
| 102 | + | |
| 103 | + /* OSVW unavailable or ID unknown, match family-model-stepping range */ | |
| 104 | + ms = (cpu->x86_model << 4) | cpu->x86_stepping; | |
| 105 | + while ((range = *erratum++)) | |
| 106 | + if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) && | |
| 107 | + (ms >= AMD_MODEL_RANGE_START(range)) && | |
| 108 | + (ms <= AMD_MODEL_RANGE_END(range))) | |
| 109 | + return true; | |
| 110 | + | |
| 111 | + return false; | |
| 112 | +} | |
| 113 | + | |
| 42 | 114 | static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) |
| 43 | 115 | { |
| 44 | 116 | u32 gprs[8] = { 0 }; |
| @@ -916,6 +988,47 @@ static void init_amd_zn(struct cpuinfo_x86 *c) · 871 unmodified lines | ||
| 916 | 988 | } |
| 917 | 989 | } |
| 918 | 990 | |
| 991 | +static bool cpu_has_zenbleed_microcode(void) | |
| 992 | +{ | |
| 993 | + u32 good_rev = 0; | |
| 994 | + | |
| 995 | + switch (boot_cpu_data.x86_model) { | |
| 996 | + case 0x30 ... 0x3f: good_rev = 0x0830107a; break; | |
| 997 | + case 0x60 ... 0x67: good_rev = 0x0860010b; break; | |
| 998 | + case 0x68 ... 0x6f: good_rev = 0x08608105; break; | |
| 999 | + case 0x70 ... 0x7f: good_rev = 0x08701032; break; | |
| 1000 | + case 0xa0 ... 0xaf: good_rev = 0x08a00008; break; | |
| 1001 | + | |
| 1002 | + default: | |
| 1003 | + return false; | |
| 1004 | + break; | |
| 1005 | + } | |
| 1006 | + | |
| 1007 | + if (boot_cpu_data.microcode < good_rev) | |
| 1008 | + return false; | |
| 1009 | + | |
| 1010 | + return true; | |
| 1011 | +} | |
| 1012 | + | |
| 1013 | +static void zenbleed_check(struct cpuinfo_x86 *c) | |
| 1014 | +{ | |
| 1015 | + if (!cpu_has_amd_erratum(c, amd_zenbleed)) | |
| 1016 | + return; | |
| 1017 | + | |
| 1018 | + if (cpu_has(c, X86_FEATURE_HYPERVISOR)) | |
| 1019 | + return; | |
| 1020 | + | |
| 1021 | + if (!cpu_has(c, X86_FEATURE_AVX)) | |
| 1022 | + return; | |
| 1023 | + | |
| 1024 | + if (!cpu_has_zenbleed_microcode()) { | |
| 1025 | + pr_notice_once("Zenbleed: please update your microcode for the most optimal fix\n"); | |
| 1026 | + msr_set_bit(MSR_AMD64_DE_CFG, MSR_AMD64_DE_CFG_ZEN2_FP_BACKUP_FIX_BIT); | |
| 1027 | + } else { | |
| 1028 | + msr_clear_bit(MSR_AMD64_DE_CFG, MSR_AMD64_DE_CFG_ZEN2_FP_BACKUP_FIX_BIT); | |
| 1029 | + } | |
| 1030 | +} | |
| 1031 | + | |
| 919 | 1032 | static void init_amd(struct cpuinfo_x86 *c) |
| 920 | 1033 | { |
| 921 | 1034 | early_init_amd(c); |
| @@ -1020,6 +1133,13 @@ static void init_amd(struct cpuinfo_x86 *c) · 98 unmodified lines | ||
| 1020 | 1133 | if (spectre_v2_in_eibrs_mode(spectre_v2_enabled) && |
| 1021 | 1134 | cpu_has(c, X86_FEATURE_AUTOIBRS)) |
| 1022 | 1135 | WARN_ON_ONCE(msr_set_bit(MSR_EFER, _EFER_AUTOIBRS)); |
| 1136 | + | |
| 1137 | + zenbleed_check(c); | |
| 1138 | + | |
| 1139 | + if (cpu_has_amd_erratum(c, amd_div0)) { | |
| 1140 | + pr_notice_once("AMD Zen1 DIV0 bug detected. Disable SMT for full protection.\n"); | |
| 1141 | + setup_force_cpu_bug(X86_BUG_DIV0); | |
| 1142 | + } | |
| 1023 | 1143 | } |
| 1024 | 1144 | |
| 1025 | 1145 | #ifdef CONFIG_X86_32 |
| @@ -1115,73 +1235,6 @@ static const struct cpu_dev amd_cpu_dev = { · 89 unmodified lines | ||
| 1115 | 1235 | |
| 1116 | 1236 | cpu_dev_register(amd_cpu_dev); |
| 1117 | 1237 | |
| 1118 | −/* | |
| 1119 | − * AMD errata checking | |
| 1120 | − * | |
| 1121 | − * Errata are defined as arrays of ints using the AMD_LEGACY_ERRATUM() or | |
| 1122 | − * AMD_OSVW_ERRATUM() macros. The latter is intended for newer errata that | |
| 1123 | − * have an OSVW id assigned, which it takes as first argument. Both take a | |
| 1124 | − * variable number of family-specific model-stepping ranges created by | |
| 1125 | − * AMD_MODEL_RANGE(). | |
| 1126 | − * | |
| 1127 | − * Example: | |
| 1128 | − * | |
| 1129 | − * const int amd_erratum_319[] = | |
| 1130 | − * AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0x4, 0x2), | |
| 1131 | − * AMD_MODEL_RANGE(0x10, 0x8, 0x0, 0x8, 0x0), | |
| 1132 | − * AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0)); | |
| 1133 | − */ | |
| 1134 | − | |
| 1135 | −#define AMD_LEGACY_ERRATUM(...) { -1, __VA_ARGS__, 0 } | |
| 1136 | −#define AMD_OSVW_ERRATUM(osvw_id, ...) { osvw_id, __VA_ARGS__, 0 } | |
| 1137 | −#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \ | |
| 1138 | − ((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end)) | |
| 1139 | −#define AMD_MODEL_RANGE_FAMILY(range) (((range) >> 24) & 0xff) | |
| 1140 | −#define AMD_MODEL_RANGE_START(range) (((range) >> 12) & 0xfff) | |
| 1141 | −#define AMD_MODEL_RANGE_END(range) ((range) & 0xfff) | |
| 1142 | − | |
| 1143 | −static const int amd_erratum_400[] = | |
| 1144 | − AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf), | |
| 1145 | − AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf)); | |
| 1146 | − | |
| 1147 | −static const int amd_erratum_383[] = | |
| 1148 | − AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf)); | |
| 1149 | − | |
| 1150 | −/* #1054: Instructions Retired Performance Counter May Be Inaccurate */ | |
| 1151 | −static const int amd_erratum_1054[] = | |
| 1152 | − AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf)); | |
| 1153 | − | |
| 1154 | −static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) | |
| 1155 | −{ | |
| 1156 | − int osvw_id = *erratum++; | |
| 1157 | − u32 range; | |
| 1158 | − u32 ms; | |
| 1159 | − | |
| 1160 | − if (osvw_id >= 0 && osvw_id < 65536 && | |
| 1161 | − cpu_has(cpu, X86_FEATURE_OSVW)) { | |
| 1162 | − u64 osvw_len; | |
| 1163 | − | |
| 1164 | − rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, osvw_len); | |
| 1165 | − if (osvw_id < osvw_len) { | |
| 1166 | − u64 osvw_bits; | |
| 1167 | − | |
| 1168 | − rdmsrl(MSR_AMD64_OSVW_STATUS + (osvw_id >> 6), | |
| 1169 | − osvw_bits); | |
| 1170 | − return osvw_bits & (1ULL << (osvw_id & 0x3f)); | |
| 1171 | − } | |
| 1172 | − } | |
| 1173 | − | |
| 1174 | − /* OSVW unavailable or ID unknown, match family-model-stepping range */ | |
| 1175 | − ms = (cpu->x86_model << 4) | cpu->x86_stepping; | |
| 1176 | − while ((range = *erratum++)) | |
| 1177 | − if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) && | |
| 1178 | − (ms >= AMD_MODEL_RANGE_START(range)) && | |
| 1179 | − (ms <= AMD_MODEL_RANGE_END(range))) | |
| 1180 | − return true; | |
| 1181 | − | |
| 1182 | − return false; | |
| 1183 | −} | |
| 1184 | − | |
| 1185 | 1238 | static DEFINE_PER_CPU_READ_MOSTLY(unsigned long[4], amd_dr_addr_mask); |
| 1186 | 1239 | |
| 1187 | 1240 | static unsigned int amd_msr_dr_addr_masks[] = { |
| @@ -1235,3 +1288,44 @@ u32 amd_get_highest_perf(void) · 47 unmodified lines | ||
| 1235 | 1288 | return 255; |
| 1236 | 1289 | } |
| 1237 | 1290 | EXPORT_SYMBOL_GPL(amd_get_highest_perf); |
| 1291 | + | |
| 1292 | +static void zenbleed_check_cpu(void *unused) | |
| 1293 | +{ | |
| 1294 | + struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); | |
| 1295 | + | |
| 1296 | + zenbleed_check(c); | |
| 1297 | +} | |
| 1298 | + | |
| 1299 | +void amd_check_microcode(void) | |
| 1300 | +{ | |
| 1301 | + on_each_cpu(zenbleed_check_cpu, NULL, 1); | |
| 1302 | +} | |
| 1303 | + | |
| 1304 | +bool cpu_has_ibpb_brtype_microcode(void) | |
| 1305 | +{ | |
| 1306 | + switch (boot_cpu_data.x86) { | |
| 1307 | + /* Zen1/2 IBPB flushes branch type predictions too. */ | |
| 1308 | + case 0x17: | |
| 1309 | + return boot_cpu_has(X86_FEATURE_AMD_IBPB); | |
| 1310 | + case 0x19: | |
| 1311 | + /* Poke the MSR bit on Zen3/4 to check its presence. */ | |
| 1312 | + if (!wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) { | |
| 1313 | + setup_force_cpu_cap(X86_FEATURE_SBPB); | |
| 1314 | + return true; | |
| 1315 | + } else { | |
| 1316 | + return false; | |
| 1317 | + } | |
| 1318 | + default: | |
| 1319 | + return false; | |
| 1320 | + } | |
| 1321 | +} | |
| 1322 | + | |
| 1323 | +/* | |
| 1324 | + * Issue a DIV 0/1 insn to clear any division data from previous DIV | |
| 1325 | + * operations. | |
| 1326 | + */ | |
| 1327 | +void noinstr amd_clear_divider(void) | |
| 1328 | +{ | |
| 1329 | + asm volatile(ALTERNATIVE("", "div %2\n\t", X86_BUG_DIV0) | |
| 1330 | + :: "a" (0), "d" (0), "r" (1)); | |
| 1331 | +} | |
| @@ -47,6 +47,8 @@ static void __init taa_select_mitigation(void); · 46 unmodified lines | ||
| 47 | 47 | static void __init mmio_select_mitigation(void); |
| 48 | 48 | static void __init srbds_select_mitigation(void); |
| 49 | 49 | static void __init l1d_flush_select_mitigation(void); |
| 50 | +static void __init srso_select_mitigation(void); | |
| 51 | +static void __init gds_select_mitigation(void); | |
| 50 | 52 | |
| 51 | 53 | /* The base value of the SPEC_CTRL MSR without task-specific bits set */ |
| 52 | 54 | u64 x86_spec_ctrl_base; |
| @@ -56,6 +58,9 @@ EXPORT_SYMBOL_GPL(x86_spec_ctrl_base); · 3 unmodified lines | ||
| 56 | 58 | DEFINE_PER_CPU(u64, x86_spec_ctrl_current); |
| 57 | 59 | EXPORT_SYMBOL_GPL(x86_spec_ctrl_current); |
| 58 | 60 | |
| 61 | +u64 x86_pred_cmd __ro_after_init = PRED_CMD_IBPB; | |
| 62 | +EXPORT_SYMBOL_GPL(x86_pred_cmd); | |
| 63 | + | |
| 59 | 64 | static DEFINE_MUTEX(spec_ctrl_mutex); |
| 60 | 65 | |
| 61 | 66 | /* Update SPEC_CTRL MSR and its cached copy unconditionally */ |
| @@ -160,6 +165,8 @@ void __init cpu_select_mitigations(void) · 98 unmodified lines | ||
| 160 | 165 | md_clear_select_mitigation(); |
| 161 | 166 | srbds_select_mitigation(); |
| 162 | 167 | l1d_flush_select_mitigation(); |
| 168 | + srso_select_mitigation(); | |
| 169 | + gds_select_mitigation(); | |
| 163 | 170 | } |
| 164 | 171 | |
| 165 | 172 | /* |
| @@ -645,6 +652,149 @@ static int __init l1d_flush_parse_cmdline(char *str) · 479 unmodified lines | ||
| 645 | 652 | } |
| 646 | 653 | early_param("l1d_flush", l1d_flush_parse_cmdline); |
| 647 | 654 | |
| 655 | +#undef pr_fmt | |
| 656 | +#define pr_fmt(fmt) "GDS: " fmt | |
| 657 | + | |
| 658 | +enum gds_mitigations { | |
| 659 | + GDS_MITIGATION_OFF, | |
| 660 | + GDS_MITIGATION_UCODE_NEEDED, | |
| 661 | + GDS_MITIGATION_FORCE, | |
| 662 | + GDS_MITIGATION_FULL, | |
| 663 | + GDS_MITIGATION_FULL_LOCKED, | |
| 664 | + GDS_MITIGATION_HYPERVISOR, | |
| 665 | +}; | |
| 666 | + | |
| 667 | +#if IS_ENABLED(CONFIG_GDS_FORCE_MITIGATION) | |
| 668 | +static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FORCE; | |
| 669 | +#else | |
| 670 | +static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FULL; | |
| 671 | +#endif | |
| 672 | + | |
| 673 | +static const char * const gds_strings[] = { | |
| 674 | + [GDS_MITIGATION_OFF] = "Vulnerable", | |
| 675 | + [GDS_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode", | |
| 676 | + [GDS_MITIGATION_FORCE] = "Mitigation: AVX disabled, no microcode", | |
| 677 | + [GDS_MITIGATION_FULL] = "Mitigation: Microcode", | |
| 678 | + [GDS_MITIGATION_FULL_LOCKED] = "Mitigation: Microcode (locked)", | |
| 679 | + [GDS_MITIGATION_HYPERVISOR] = "Unknown: Dependent on hypervisor status", | |
| 680 | +}; | |
| 681 | + | |
| 682 | +bool gds_ucode_mitigated(void) | |
| 683 | +{ | |
| 684 | + return (gds_mitigation == GDS_MITIGATION_FULL || | |
| 685 | + gds_mitigation == GDS_MITIGATION_FULL_LOCKED); | |
| 686 | +} | |
| 687 | +EXPORT_SYMBOL_GPL(gds_ucode_mitigated); | |
| 688 | + | |
| 689 | +void update_gds_msr(void) | |
| 690 | +{ | |
| 691 | + u64 mcu_ctrl_after; | |
| 692 | + u64 mcu_ctrl; | |
| 693 | + | |
| 694 | + switch (gds_mitigation) { | |
| 695 | + case GDS_MITIGATION_OFF: | |
| 696 | + rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); | |
| 697 | + mcu_ctrl |= GDS_MITG_DIS; | |
| 698 | + break; | |
| 699 | + case GDS_MITIGATION_FULL_LOCKED: | |
| 700 | + /* | |
| 701 | + * The LOCKED state comes from the boot CPU. APs might not have | |
| 702 | + * the same state. Make sure the mitigation is enabled on all | |
| 703 | + * CPUs. | |
| 704 | + */ | |
| 705 | + case GDS_MITIGATION_FULL: | |
| 706 | + rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); | |
| 707 | + mcu_ctrl &= ~GDS_MITG_DIS; | |
| 708 | + break; | |
| 709 | + case GDS_MITIGATION_FORCE: | |
| 710 | + case GDS_MITIGATION_UCODE_NEEDED: | |
| 711 | + case GDS_MITIGATION_HYPERVISOR: | |
| 712 | + return; | |
| 713 | + }; | |
| 714 | + | |
| 715 | + wrmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); | |
| 716 | + | |
| 717 | + /* | |
| 718 | + * Check to make sure that the WRMSR value was not ignored. Writes to | |
| 719 | + * GDS_MITG_DIS will be ignored if this processor is locked but the boot | |
| 720 | + * processor was not. | |
| 721 | + */ | |
| 722 | + rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl_after); | |
| 723 | + WARN_ON_ONCE(mcu_ctrl != mcu_ctrl_after); | |
| 724 | +} | |
| 725 | + | |
| 726 | +static void __init gds_select_mitigation(void) | |
| 727 | +{ | |
| 728 | + u64 mcu_ctrl; | |
| 729 | + | |
| 730 | + if (!boot_cpu_has_bug(X86_BUG_GDS)) | |
| 731 | + return; | |
| 732 | + | |
| 733 | + if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) { | |
| 734 | + gds_mitigation = GDS_MITIGATION_HYPERVISOR; | |
| 735 | + goto out; | |
| 736 | + } | |
| 737 | + | |
| 738 | + if (cpu_mitigations_off()) | |
| 739 | + gds_mitigation = GDS_MITIGATION_OFF; | |
| 740 | + /* Will verify below that mitigation _can_ be disabled */ | |
| 741 | + | |
| 742 | + /* No microcode */ | |
| 743 | + if (!(x86_read_arch_cap_msr() & ARCH_CAP_GDS_CTRL)) { | |
| 744 | + if (gds_mitigation == GDS_MITIGATION_FORCE) { | |
| 745 | + /* | |
| 746 | + * This only needs to be done on the boot CPU so do it | |
| 747 | + * here rather than in update_gds_msr() | |
| 748 | + */ | |
| 749 | + setup_clear_cpu_cap(X86_FEATURE_AVX); | |
| 750 | + pr_warn("Microcode update needed! Disabling AVX as mitigation.\n"); | |
| 751 | + } else { | |
| 752 | + gds_mitigation = GDS_MITIGATION_UCODE_NEEDED; | |
| 753 | + } | |
| 754 | + goto out; | |
| 755 | + } | |
| 756 | + | |
| 757 | + /* Microcode has mitigation, use it */ | |
| 758 | + if (gds_mitigation == GDS_MITIGATION_FORCE) | |
| 759 | + gds_mitigation = GDS_MITIGATION_FULL; | |
| 760 | + | |
| 761 | + rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); | |
| 762 | + if (mcu_ctrl & GDS_MITG_LOCKED) { | |
| 763 | + if (gds_mitigation == GDS_MITIGATION_OFF) | |
| 764 | + pr_warn("Mitigation locked. Disable failed.\n"); | |
| 765 | + | |
| 766 | + /* | |
| 767 | + * The mitigation is selected from the boot CPU. All other CPUs | |
| 768 | + * _should_ have the same state. If the boot CPU isn't locked | |
| 769 | + * but others are then update_gds_msr() will WARN() of the state | |
| 770 | + * mismatch. If the boot CPU is locked update_gds_msr() will | |
| 771 | + * ensure the other CPUs have the mitigation enabled. | |
| 772 | + */ | |
| 773 | + gds_mitigation = GDS_MITIGATION_FULL_LOCKED; | |
| 774 | + } | |
| 775 | + | |
| 776 | + update_gds_msr(); | |
| 777 | +out: | |
| 778 | + pr_info("%s\n", gds_strings[gds_mitigation]); | |
| 779 | +} | |
| 780 | + | |
| 781 | +static int __init gds_parse_cmdline(char *str) | |
| 782 | +{ | |
| 783 | + if (!str) | |
| 784 | + return -EINVAL; | |
| 785 | + | |
| 786 | + if (!boot_cpu_has_bug(X86_BUG_GDS)) | |
| 787 | + return 0; | |
| 788 | + | |
| 789 | + if (!strcmp(str, "off")) | |
| 790 | + gds_mitigation = GDS_MITIGATION_OFF; | |
| 791 | + else if (!strcmp(str, "force")) | |
| 792 | + gds_mitigation = GDS_MITIGATION_FORCE; | |
| 793 | + | |
| 794 | + return 0; | |
| 795 | +} | |
| 796 | +early_param("gather_data_sampling", gds_parse_cmdline); | |
| 797 | + | |
| 648 | 798 | #undef pr_fmt |
| 649 | 799 | #define pr_fmt(fmt) "Spectre V1 : " fmt |
| 650 | 800 | |
| @@ -1150,19 +1300,21 @@ spectre_v2_user_select_mitigation(void) · 499 unmodified lines | ||
| 1150 | 1300 | } |
| 1151 | 1301 | |
| 1152 | 1302 | /* |
| 1153 | − * If no STIBP, enhanced IBRS is enabled, or SMT impossible, STIBP | |
| 1303 | + * If no STIBP, Intel enhanced IBRS is enabled, or SMT impossible, STIBP | |
| 1154 | 1304 | * is not required. |
| 1155 | 1305 | * |
| 1156 | − * Enhanced IBRS also protects against cross-thread branch target | |
| 1306 | + * Intel's Enhanced IBRS also protects against cross-thread branch target | |
| 1157 | 1307 | * injection in user-mode as the IBRS bit remains always set which |
| 1158 | 1308 | * implicitly enables cross-thread protections. However, in legacy IBRS |
| 1159 | 1309 | * mode, the IBRS bit is set only on kernel entry and cleared on return |
| 1160 | − * to userspace. This disables the implicit cross-thread protection, | |
| 1161 | − * so allow for STIBP to be selected in that case. | |
| 1310 | + * to userspace. AMD Automatic IBRS also does not protect userspace. | |
| 1311 | + * These modes therefore disable the implicit cross-thread protection, | |
| 1312 | + * so allow for STIBP to be selected in those cases. | |
| 1162 | 1313 | */ |
| 1163 | 1314 | if (!boot_cpu_has(X86_FEATURE_STIBP) || |
| 1164 | 1315 | !smt_possible || |
| 1165 | − spectre_v2_in_eibrs_mode(spectre_v2_enabled)) | |
| 1316 | + (spectre_v2_in_eibrs_mode(spectre_v2_enabled) && | |
| 1317 | + !boot_cpu_has(X86_FEATURE_AUTOIBRS))) | |
| 1166 | 1318 | return; |
| 1167 | 1319 | |
| 1168 | 1320 | /* |
| @@ -2185,6 +2337,165 @@ static int __init l1tf_cmdline(char *str) · 1016 unmodified lines | ||
| 2185 | 2337 | } |
| 2186 | 2338 | early_param("l1tf", l1tf_cmdline); |
| 2187 | 2339 | |
| 2340 | +#undef pr_fmt | |
| 2341 | +#define pr_fmt(fmt) "Speculative Return Stack Overflow: " fmt | |
| 2342 | + | |
| 2343 | +enum srso_mitigation { | |
| 2344 | + SRSO_MITIGATION_NONE, | |
| 2345 | + SRSO_MITIGATION_MICROCODE, | |
| 2346 | + SRSO_MITIGATION_SAFE_RET, | |
| 2347 | + SRSO_MITIGATION_IBPB, | |
| 2348 | + SRSO_MITIGATION_IBPB_ON_VMEXIT, | |
| 2349 | +}; | |
| 2350 | + | |
| 2351 | +enum srso_mitigation_cmd { | |
| 2352 | + SRSO_CMD_OFF, | |
| 2353 | + SRSO_CMD_MICROCODE, | |
| 2354 | + SRSO_CMD_SAFE_RET, | |
| 2355 | + SRSO_CMD_IBPB, | |
| 2356 | + SRSO_CMD_IBPB_ON_VMEXIT, | |
| 2357 | +}; | |
| 2358 | + | |
| 2359 | +static const char * const srso_strings[] = { | |
| 2360 | + [SRSO_MITIGATION_NONE] = "Vulnerable", | |
| 2361 | + [SRSO_MITIGATION_MICROCODE] = "Mitigation: microcode", | |
| 2362 | + [SRSO_MITIGATION_SAFE_RET] = "Mitigation: safe RET", | |
| 2363 | + [SRSO_MITIGATION_IBPB] = "Mitigation: IBPB", | |
| 2364 | + [SRSO_MITIGATION_IBPB_ON_VMEXIT] = "Mitigation: IBPB on VMEXIT only" | |
| 2365 | +}; | |
| 2366 | + | |
| 2367 | +static enum srso_mitigation srso_mitigation __ro_after_init = SRSO_MITIGATION_NONE; | |
| 2368 | +static enum srso_mitigation_cmd srso_cmd __ro_after_init = SRSO_CMD_SAFE_RET; | |
| 2369 | + | |
| 2370 | +static int __init srso_parse_cmdline(char *str) | |
| 2371 | +{ | |
| 2372 | + if (!str) | |
| 2373 | + return -EINVAL; | |
| 2374 | + | |
| 2375 | + if (!strcmp(str, "off")) | |
| 2376 | + srso_cmd = SRSO_CMD_OFF; | |
| 2377 | + else if (!strcmp(str, "microcode")) | |
| 2378 | + srso_cmd = SRSO_CMD_MICROCODE; | |
| 2379 | + else if (!strcmp(str, "safe-ret")) | |
| 2380 | + srso_cmd = SRSO_CMD_SAFE_RET; | |
| 2381 | + else if (!strcmp(str, "ibpb")) | |
| 2382 | + srso_cmd = SRSO_CMD_IBPB; | |
| 2383 | + else if (!strcmp(str, "ibpb-vmexit")) | |
| 2384 | + srso_cmd = SRSO_CMD_IBPB_ON_VMEXIT; | |
| 2385 | + else | |
| 2386 | + pr_err("Ignoring unknown SRSO option (%s).", str); | |
| 2387 | + | |
| 2388 | + return 0; | |
| 2389 | +} | |
| 2390 | +early_param("spec_rstack_overflow", srso_parse_cmdline); | |
| 2391 | + | |
| 2392 | +#define SRSO_NOTICE "WARNING: See https://kernel.org/doc/html/latest/admin-guide/hw-vuln/srso.html for mitigation options." | |
| 2393 | + | |
| 2394 | +static void __init srso_select_mitigation(void) | |
| 2395 | +{ | |
| 2396 | + bool has_microcode; | |
| 2397 | + | |
| 2398 | + if (!boot_cpu_has_bug(X86_BUG_SRSO) || cpu_mitigations_off()) | |
| 2399 | + goto pred_cmd; | |
| 2400 | + | |
| 2401 | + /* | |
| 2402 | + * The first check is for the kernel running as a guest in order | |
| 2403 | + * for guests to verify whether IBPB is a viable mitigation. | |
| 2404 | + */ | |
| 2405 | + has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) || cpu_has_ibpb_brtype_microcode(); | |
| 2406 | + if (!has_microcode) { | |
| 2407 | + pr_warn("IBPB-extending microcode not applied!\n"); | |
| 2408 | + pr_warn(SRSO_NOTICE); | |
| 2409 | + } else { | |
| 2410 | + /* | |
| 2411 | + * Enable the synthetic (even if in a real CPUID leaf) | |
| 2412 | + * flags for guests. | |
| 2413 | + */ | |
| 2414 | + setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); | |
| 2415 | + | |
| 2416 | + /* | |
| 2417 | + * Zen1/2 with SMT off aren't vulnerable after the right | |
| 2418 | + * IBPB microcode has been applied. | |
| 2419 | + */ | |
| 2420 | + if ((boot_cpu_data.x86 < 0x19) && | |
| 2421 | + (!cpu_smt_possible() || (cpu_smt_control == CPU_SMT_DISABLED))) | |
| 2422 | + setup_force_cpu_cap(X86_FEATURE_SRSO_NO); | |
| 2423 | + } | |
| 2424 | + | |
| 2425 | + if (retbleed_mitigation == RETBLEED_MITIGATION_IBPB) { | |
| 2426 | + if (has_microcode) { | |
| 2427 | + pr_err("Retbleed IBPB mitigation enabled, using same for SRSO\n"); | |
| 2428 | + srso_mitigation = SRSO_MITIGATION_IBPB; | |
| 2429 | + goto pred_cmd; | |
| 2430 | + } | |
| 2431 | + } | |
| 2432 | + | |
| 2433 | + switch (srso_cmd) { | |
| 2434 | + case SRSO_CMD_OFF: | |
| 2435 | + return; | |
| 2436 | + | |
| 2437 | + case SRSO_CMD_MICROCODE: | |
| 2438 | + if (has_microcode) { | |
| 2439 | + srso_mitigation = SRSO_MITIGATION_MICROCODE; | |
| 2440 | + pr_warn(SRSO_NOTICE); | |
| 2441 | + } | |
| 2442 | + break; | |
| 2443 | + | |
| 2444 | + case SRSO_CMD_SAFE_RET: | |
| 2445 | + if (IS_ENABLED(CONFIG_CPU_SRSO)) { | |
| 2446 | + /* | |
| 2447 | + * Enable the return thunk for generated code | |
| 2448 | + * like ftrace, static_call, etc. | |
| 2449 | + */ | |
| 2450 | + setup_force_cpu_cap(X86_FEATURE_RETHUNK); | |
| 2451 | + | |
| 2452 | + if (boot_cpu_data.x86 == 0x19) | |
| 2453 | + setup_force_cpu_cap(X86_FEATURE_SRSO_ALIAS); | |
| 2454 | + else | |
| 2455 | + setup_force_cpu_cap(X86_FEATURE_SRSO); | |
| 2456 | + srso_mitigation = SRSO_MITIGATION_SAFE_RET; | |
| 2457 | + } else { | |
| 2458 | + pr_err("WARNING: kernel not compiled with CPU_SRSO.\n"); | |
| 2459 | + goto pred_cmd; | |
| 2460 | + } | |
| 2461 | + break; | |
| 2462 | + | |
| 2463 | + case SRSO_CMD_IBPB: | |
| 2464 | + if (IS_ENABLED(CONFIG_CPU_IBPB_ENTRY)) { | |
| 2465 | + if (has_microcode) { | |
| 2466 | + setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); | |
| 2467 | + srso_mitigation = SRSO_MITIGATION_IBPB; | |
| 2468 | + } | |
| 2469 | + } else { | |
| 2470 | + pr_err("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n"); | |
| 2471 | + goto pred_cmd; | |
| 2472 | + } | |
| 2473 | + break; | |
| 2474 | + | |
| 2475 | + case SRSO_CMD_IBPB_ON_VMEXIT: | |
| 2476 | + if (IS_ENABLED(CONFIG_CPU_SRSO)) { | |
| 2477 | + if (!boot_cpu_has(X86_FEATURE_ENTRY_IBPB) && has_microcode) { | |
| 2478 | + setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); | |
| 2479 | + srso_mitigation = SRSO_MITIGATION_IBPB_ON_VMEXIT; | |
| 2480 | + } | |
| 2481 | + } else { | |
| 2482 | + pr_err("WARNING: kernel not compiled with CPU_SRSO.\n"); | |
| 2483 | + goto pred_cmd; | |
| 2484 | + } | |
| 2485 | + break; | |
| 2486 | + | |
| 2487 | + default: | |
| 2488 | + break; | |
| 2489 | + } | |
| 2490 | + | |
| 2491 | + pr_info("%s%s\n", srso_strings[srso_mitigation], (has_microcode ? "" : ", no microcode")); | |
| 2492 | + | |
| 2493 | +pred_cmd: | |
| 2494 | + if ((boot_cpu_has(X86_FEATURE_SRSO_NO) || srso_cmd == SRSO_CMD_OFF) && | |
| 2495 | + boot_cpu_has(X86_FEATURE_SBPB)) | |
| 2496 | + x86_pred_cmd = PRED_CMD_SBPB; | |
| 2497 | +} | |
| 2498 | + | |
| 2188 | 2499 | #undef pr_fmt |
| 2189 | 2500 | #define pr_fmt(fmt) fmt |
| 2190 | 2501 | |
| @@ -2294,7 +2605,8 @@ static ssize_t mmio_stale_data_show_state(char *buf) · 103 unmodified lines | ||
| 2294 | 2605 | |
| 2295 | 2606 | static char *stibp_state(void) |
| 2296 | 2607 | { |
| 2297 | − if (spectre_v2_in_eibrs_mode(spectre_v2_enabled)) | |
| 2608 | + if (spectre_v2_in_eibrs_mode(spectre_v2_enabled) && | |
| 2609 | + !boot_cpu_has(X86_FEATURE_AUTOIBRS)) | |
| 2298 | 2610 | return ""; |
| 2299 | 2611 | |
| 2300 | 2612 | switch (spectre_v2_user_stibp) { |
| @@ -2382,6 +2694,18 @@ static ssize_t retbleed_show_state(char *buf) · 81 unmodified lines | ||
| 2382 | 2694 | return sysfs_emit(buf, "%s\n", retbleed_strings[retbleed_mitigation]); |
| 2383 | 2695 | } |
| 2384 | 2696 | |
| 2697 | +static ssize_t srso_show_state(char *buf) | |
| 2698 | +{ | |
| 2699 | + return sysfs_emit(buf, "%s%s\n", | |
| 2700 | + srso_strings[srso_mitigation], | |
| 2701 | + (cpu_has_ibpb_brtype_microcode() ? "" : ", no microcode")); | |
| 2702 | +} | |
| 2703 | + | |
| 2704 | +static ssize_t gds_show_state(char *buf) | |
| 2705 | +{ | |
| 2706 | + return sysfs_emit(buf, "%s\n", gds_strings[gds_mitigation]); | |
| 2707 | +} | |
| 2708 | + | |
| 2385 | 2709 | static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr, |
| 2386 | 2710 | char *buf, unsigned int bug) |
| 2387 | 2711 | { |
| @@ -2431,6 +2755,12 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr · 43 unmodified lines | ||
| 2431 | 2755 | case X86_BUG_RETBLEED: |
| 2432 | 2756 | return retbleed_show_state(buf); |
| 2433 | 2757 | |
| 2758 | + case X86_BUG_SRSO: | |
| 2759 | + return srso_show_state(buf); | |
| 2760 | + | |
| 2761 | + case X86_BUG_GDS: | |
| 2762 | + return gds_show_state(buf); | |
| 2763 | + | |
| 2434 | 2764 | default: |
| 2435 | 2765 | break; |
| 2436 | 2766 | } |
| @@ -2495,4 +2825,14 @@ ssize_t cpu_show_retbleed(struct device *dev, struct device_attribute *attr, cha · 58 unmodified lines | ||
| 2495 | 2825 | { |
| 2496 | 2826 | return cpu_show_common(dev, attr, buf, X86_BUG_RETBLEED); |
| 2497 | 2827 | } |
| 2828 | + | |
| 2829 | +ssize_t cpu_show_spec_rstack_overflow(struct device *dev, struct device_attribute *attr, char *buf) | |
| 2830 | +{ | |
| 2831 | + return cpu_show_common(dev, attr, buf, X86_BUG_SRSO); | |
| 2832 | +} | |
| 2833 | + | |
| 2834 | +ssize_t cpu_show_gds(struct device *dev, struct device_attribute *attr, char *buf) | |
| 2835 | +{ | |
| 2836 | + return cpu_show_common(dev, attr, buf, X86_BUG_GDS); | |
| 2837 | +} | |
| 2498 | 2838 | #endif |
| @@ -1250,6 +1250,10 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { · 1249 unmodified lines | ||
| 1250 | 1250 | #define RETBLEED BIT(3) |
| 1251 | 1251 | /* CPU is affected by SMT (cross-thread) return predictions */ |
| 1252 | 1252 | #define SMT_RSB BIT(4) |
| 1253 | +/* CPU is affected by SRSO */ | |
| 1254 | +#define SRSO BIT(5) | |
| 1255 | +/* CPU is affected by GDS */ | |
| 1256 | +#define GDS BIT(6) | |
| 1253 | 1257 | |
| 1254 | 1258 | static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { |
| 1255 | 1259 | VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS), |
| @@ -1262,27 +1266,30 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { · 6 unmodified lines | ||
| 1262 | 1266 | VULNBL_INTEL_STEPPINGS(BROADWELL_X, X86_STEPPING_ANY, MMIO), |
| 1263 | 1267 | VULNBL_INTEL_STEPPINGS(BROADWELL, X86_STEPPING_ANY, SRBDS), |
| 1264 | 1268 | VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED), |
| 1265 | − VULNBL_INTEL_STEPPINGS(SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED), | |
| 1269 | + VULNBL_INTEL_STEPPINGS(SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED | GDS), | |
| 1266 | 1270 | VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED), |
| 1267 | − VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED), | |
| 1268 | − VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED), | |
| 1271 | + VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED | GDS), | |
| 1272 | + VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED | GDS), | |
| 1269 | 1273 | VULNBL_INTEL_STEPPINGS(CANNONLAKE_L, X86_STEPPING_ANY, RETBLEED), |
| 1270 | − VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED), | |
| 1271 | − VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPING_ANY, MMIO), | |
| 1272 | − VULNBL_INTEL_STEPPINGS(ICELAKE_X, X86_STEPPING_ANY, MMIO), | |
| 1273 | − VULNBL_INTEL_STEPPINGS(COMETLAKE, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED), | |
| 1274 | + VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS), | |
| 1275 | + VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPING_ANY, MMIO | GDS), | |
| 1276 | + VULNBL_INTEL_STEPPINGS(ICELAKE_X, X86_STEPPING_ANY, MMIO | GDS), | |
| 1277 | + VULNBL_INTEL_STEPPINGS(COMETLAKE, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS), | |
| 1274 | 1278 | VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPINGS(0x0, 0x0), MMIO | RETBLEED), |
| 1275 | − VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED), | |
| 1279 | + VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS), | |
| 1280 | + VULNBL_INTEL_STEPPINGS(TIGERLAKE_L, X86_STEPPING_ANY, GDS), | |
| 1281 | + VULNBL_INTEL_STEPPINGS(TIGERLAKE, X86_STEPPING_ANY, GDS), | |
| 1276 | 1282 | VULNBL_INTEL_STEPPINGS(LAKEFIELD, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED), |
| 1277 | − VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED), | |
| 1283 | + VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS), | |
| 1278 | 1284 | VULNBL_INTEL_STEPPINGS(ATOM_TREMONT, X86_STEPPING_ANY, MMIO | MMIO_SBDS), |
| 1279 | 1285 | VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPING_ANY, MMIO), |
| 1280 | 1286 | VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS), |
| 1281 | 1287 | |
| 1282 | 1288 | VULNBL_AMD(0x15, RETBLEED), |
| 1283 | 1289 | VULNBL_AMD(0x16, RETBLEED), |
| 1284 | − VULNBL_AMD(0x17, RETBLEED | SMT_RSB), | |
| 1290 | + VULNBL_AMD(0x17, RETBLEED | SMT_RSB | SRSO), | |
| 1285 | 1291 | VULNBL_HYGON(0x18, RETBLEED | SMT_RSB), |
| 1292 | + VULNBL_AMD(0x19, SRSO), | |
| 1286 | 1293 | {} |
| 1287 | 1294 | }; |
| 1288 | 1295 | |
| @@ -1406,6 +1413,21 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) · 117 unmodified lines | ||
| 1406 | 1413 | if (cpu_matches(cpu_vuln_blacklist, SMT_RSB)) |
| 1407 | 1414 | setup_force_cpu_bug(X86_BUG_SMT_RSB); |
| 1408 | 1415 | |
| 1416 | + if (!cpu_has(c, X86_FEATURE_SRSO_NO)) { | |
| 1417 | + if (cpu_matches(cpu_vuln_blacklist, SRSO)) | |
| 1418 | + setup_force_cpu_bug(X86_BUG_SRSO); | |
| 1419 | + } | |
| 1420 | + | |
| 1421 | + /* | |
| 1422 | + * Check if CPU is vulnerable to GDS. If running in a virtual machine on | |
| 1423 | + * an affected processor, the VMM may have disabled the use of GATHER by | |
| 1424 | + * disabling AVX2. The only way to do this in HW is to clear XCR0[2], | |
| 1425 | + * which means that AVX will be disabled. | |
| 1426 | + */ | |
| 1427 | + if (cpu_matches(cpu_vuln_blacklist, GDS) && !(ia32_cap & ARCH_CAP_GDS_NO) && | |
| 1428 | + boot_cpu_has(X86_FEATURE_AVX)) | |
| 1429 | + setup_force_cpu_bug(X86_BUG_GDS); | |
| 1430 | + | |
| 1409 | 1431 | if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) |
| 1410 | 1432 | return; |
| 1411 | 1433 | |
| @@ -1962,6 +1984,8 @@ void identify_secondary_cpu(struct cpuinfo_x86 *c) · 550 unmodified lines | ||
| 1962 | 1984 | validate_apic_and_package_id(c); |
| 1963 | 1985 | x86_spec_ctrl_setup_ap(); |
| 1964 | 1986 | update_srbds_msr(); |
| 1987 | + if (boot_cpu_has_bug(X86_BUG_GDS)) | |
| 1988 | + update_gds_msr(); | |
| 1965 | 1989 | |
| 1966 | 1990 | tsx_ap_init(); |
| 1967 | 1991 | } |
| @@ -2287,6 +2311,8 @@ void microcode_check(struct cpuinfo_x86 *prev_info) · 319 unmodified lines | ||
| 2287 | 2311 | |
| 2288 | 2312 | perf_check_microcode(); |
| 2289 | 2313 | |
| 2314 | + amd_check_microcode(); | |
| 2315 | + | |
| 2290 | 2316 | store_cpu_caps(&curr_info); |
| 2291 | 2317 | |
| 2292 | 2318 | if (!memcmp(&prev_info->x86_capability, &curr_info.x86_capability, |
| @@ -83,6 +83,7 @@ void cpu_select_mitigations(void); · 82 unmodified lines | ||
| 83 | 83 | |
| 84 | 84 | extern void x86_spec_ctrl_setup_ap(void); |
| 85 | 85 | extern void update_srbds_msr(void); |
| 86 | +extern void update_gds_msr(void); | |
| 86 | 87 | |
| 87 | 88 | extern enum spectre_v2_mitigation spectre_v2_enabled; |
| 88 | 89 | |
| @@ -1261,10 +1261,10 @@ static void __threshold_remove_blocks(struct threshold_bank *b) · 1260 unmodified lines | ||
| 1261 | 1261 | struct threshold_block *pos = NULL; |
| 1262 | 1262 | struct threshold_block *tmp = NULL; |
| 1263 | 1263 | |
| 1264 | − kobject_del(b->kobj); | |
| 1264 | + kobject_put(b->kobj); | |
| 1265 | 1265 | |
| 1266 | 1266 | list_for_each_entry_safe(pos, tmp, &b->blocks->miscj, miscj) |
| 1267 | − kobject_del(&pos->kobj); | |
| 1267 | + kobject_put(b->kobj); | |
| 1268 | 1268 | } |
| 1269 | 1269 | |
| 1270 | 1270 | static void threshold_remove_bank(struct threshold_bank *bank) |
| @@ -206,6 +206,8 @@ DEFINE_IDTENTRY(exc_divide_error) · 205 unmodified lines | ||
| 206 | 206 | { |
| 207 | 207 | do_error_trap(regs, 0, "divide error", X86_TRAP_DE, SIGFPE, |
| 208 | 208 | FPE_INTDIV, error_get_trap_addr(regs)); |
| 209 | + | |
| 210 | + amd_clear_divider(); | |
| 209 | 211 | } |
| 210 | 212 | |
| 211 | 213 | DEFINE_IDTENTRY(exc_overflow) |
| @@ -697,9 +699,10 @@ static bool try_fixup_enqcmd_gp(void) · 485 unmodified lines | ||
| 697 | 699 | } |
| 698 | 700 | |
| 699 | 701 | static bool gp_try_fixup_and_notify(struct pt_regs *regs, int trapnr, |
| 700 | − unsigned long error_code, const char *str) | |
| 702 | + unsigned long error_code, const char *str, | |
| 703 | + unsigned long address) | |
| 701 | 704 | { |
| 702 | − if (fixup_exception(regs, trapnr, error_code, 0)) | |
| 705 | + if (fixup_exception(regs, trapnr, error_code, address)) | |
| 703 | 706 | return true; |
| 704 | 707 | |
| 705 | 708 | current->thread.error_code = error_code; |
| @@ -759,7 +762,7 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection) · 53 unmodified lines | ||
| 759 | 762 | goto exit; |
| 760 | 763 | } |
| 761 | 764 | |
| 762 | − if (gp_try_fixup_and_notify(regs, X86_TRAP_GP, error_code, desc)) | |
| 765 | + if (gp_try_fixup_and_notify(regs, X86_TRAP_GP, error_code, desc, 0)) | |
| 763 | 766 | goto exit; |
| 764 | 767 | |
| 765 | 768 | if (error_code) |
| @@ -1357,17 +1360,20 @@ DEFINE_IDTENTRY(exc_device_not_available) · 591 unmodified lines | ||
| 1357 | 1360 | |
| 1358 | 1361 | #define VE_FAULT_STR "VE fault" |
| 1359 | 1362 | |
| 1360 | −static void ve_raise_fault(struct pt_regs *regs, long error_code) | |
| 1363 | +static void ve_raise_fault(struct pt_regs *regs, long error_code, | |
| 1364 | + unsigned long address) | |
| 1361 | 1365 | { |
| 1362 | 1366 | if (user_mode(regs)) { |
| 1363 | 1367 | gp_user_force_sig_segv(regs, X86_TRAP_VE, error_code, VE_FAULT_STR); |
| 1364 | 1368 | return; |
| 1365 | 1369 | } |
| 1366 | 1370 | |
| 1367 | − if (gp_try_fixup_and_notify(regs, X86_TRAP_VE, error_code, VE_FAULT_STR)) | |
| 1371 | + if (gp_try_fixup_and_notify(regs, X86_TRAP_VE, error_code, | |
| 1372 | + VE_FAULT_STR, address)) { | |
| 1368 | 1373 | return; |
| 1374 | + } | |
| 1369 | 1375 | |
| 1370 | − die_addr(VE_FAULT_STR, regs, error_code, 0); | |
| 1376 | + die_addr(VE_FAULT_STR, regs, error_code, address); | |
| 1371 | 1377 | } |
| 1372 | 1378 | |
| 1373 | 1379 | /* |
| @@ -1431,7 +1437,7 @@ DEFINE_IDTENTRY(exc_virtualization_exception) · 57 unmodified lines | ||
| 1431 | 1437 | * it successfully, treat it as #GP(0) and handle it. |
| 1432 | 1438 | */ |
| 1433 | 1439 | if (!tdx_handle_virt_exception(regs, &ve)) |
| 1434 | − ve_raise_fault(regs, 0); | |
| 1440 | + ve_raise_fault(regs, 0, ve.gla); | |
| 1435 | 1441 | |
| 1436 | 1442 | cond_local_irq_disable(regs); |
| 1437 | 1443 | } |
| @@ -134,13 +134,27 @@ SECTIONS · 133 unmodified lines | ||
| 134 | 134 | SOFTIRQENTRY_TEXT |
| 135 | 135 | #ifdef CONFIG_RETPOLINE |
| 136 | 136 | __indirect_thunk_start = .; |
| 137 | − *(.text.__x86.*) | |
| 137 | + *(.text.__x86.indirect_thunk) | |
| 138 | + *(.text.__x86.return_thunk) | |
| 138 | 139 | __indirect_thunk_end = .; |
| 139 | 140 | #endif |
| 140 | 141 | STATIC_CALL_TEXT |
| 141 | 142 | |
| 142 | 143 | ALIGN_ENTRY_TEXT_BEGIN |
| 144 | +#ifdef CONFIG_CPU_SRSO | |
| 145 | + *(.text.__x86.rethunk_untrain) | |
| 146 | +#endif | |
| 147 | + | |
| 143 | 148 | ENTRY_TEXT |
| 149 | + | |
| 150 | +#ifdef CONFIG_CPU_SRSO | |
| 151 | + /* | |
| 152 | + * See the comment above srso_untrain_ret_alias()'s | |
| 153 | + * definition. | |
| 154 | + */ | |
| 155 | + . = srso_untrain_ret_alias | (1 << 2) | (1 << 8) | (1 << 14) | (1 << 20); | |
| 156 | + *(.text.__x86.rethunk_safe) | |
| 157 | +#endif | |
| 144 | 158 | ALIGN_ENTRY_TEXT_END |
| 145 | 159 | *(.gnu.warning) |
| 146 | 160 | |
| @@ -509,7 +523,24 @@ INIT_PER_CPU(irq_stack_backing_store); · 362 unmodified lines | ||
| 509 | 523 | #endif |
| 510 | 524 | |
| 511 | 525 | #ifdef CONFIG_RETHUNK |
| 512 | −. = ASSERT((__x86_return_thunk & 0x3f) == 0, "__x86_return_thunk not cacheline-aligned"); | |
| 526 | +. = ASSERT((__ret & 0x3f) == 0, "__ret not cacheline-aligned"); | |
| 527 | +. = ASSERT((srso_safe_ret & 0x3f) == 0, "srso_safe_ret not cacheline-aligned"); | |
| 528 | +#endif | |
| 529 | + | |
| 530 | +#ifdef CONFIG_CPU_SRSO | |
| 531 | +/* | |
| 532 | + * GNU ld cannot do XOR until 2.41. | |
| 533 | + * https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=f6f78318fca803c4907fb8d7f6ded8295f1947b1 | |
| 534 | + * | |
| 535 | + * LLVM lld cannot do XOR until lld-17. | |
| 536 | + * https://github.com/llvm/llvm-project/commit/fae96104d4378166cbe5c875ef8ed808a356f3fb | |
| 537 | + * | |
| 538 | + * Instead do: (A | B) - (A & B) in order to compute the XOR | |
| 539 | + * of the two function addresses: | |
| 540 | + */ | |
| 541 | +. = ASSERT(((ABSOLUTE(srso_untrain_ret_alias) | srso_safe_ret_alias) - | |
| 542 | + (ABSOLUTE(srso_untrain_ret_alias) & srso_safe_ret_alias)) == ((1 << 2) | (1 << 8) | (1 << 14) | (1 << 20)), | |
| 543 | + "SRSO function pair won't alias"); | |
| 513 | 544 | #endif |
| 514 | 545 | |
| 515 | 546 | #endif /* CONFIG_X86_64 */ |
| @@ -729,6 +729,9 @@ void kvm_set_cpu_caps(void) · 728 unmodified lines | ||
| 729 | 729 | F(NULL_SEL_CLR_BASE) | F(AUTOIBRS) | 0 /* PrefetchCtlMsr */ |
| 730 | 730 | ); |
| 731 | 731 | |
| 732 | + if (cpu_feature_enabled(X86_FEATURE_SRSO_NO)) | |
| 733 | + kvm_cpu_cap_set(X86_FEATURE_SRSO_NO); | |
| 734 | + | |
| 732 | 735 | kvm_cpu_cap_init_kvm_defined(CPUID_8000_0022_EAX, |
| 733 | 736 | F(PERFMON_V2) |
| 734 | 737 | ); |
| @@ -637,16 +637,22 @@ bool __kvm_apic_update_irr(u32 *pir, void *regs, int *max_irr) · 636 unmodified lines | ||
| 637 | 637 | *max_irr = -1; |
| 638 | 638 | |
| 639 | 639 | for (i = vec = 0; i <= 7; i++, vec += 32) { |
| 640 | + u32 *p_irr = (u32 *)(regs + APIC_IRR + i * 0x10); | |
| 641 | + | |
| 642 | + irr_val = *p_irr; | |
| 640 | 643 | pir_val = READ_ONCE(pir[i]); |
| 641 | − irr_val = *((u32 *)(regs + APIC_IRR + i * 0x10)); | |
| 644 | + | |
| 642 | 645 | if (pir_val) { |
| 646 | + pir_val = xchg(&pir[i], 0); | |
| 647 | + | |
| 643 | 648 | prev_irr_val = irr_val; |
| 644 | − irr_val |= xchg(&pir[i], 0); | |
| 645 | − *((u32 *)(regs + APIC_IRR + i * 0x10)) = irr_val; | |
| 646 | − if (prev_irr_val != irr_val) { | |
| 647 | − max_updated_irr = | |
| 648 | − __fls(irr_val ^ prev_irr_val) + vec; | |
| 649 | − } | |
| 649 | + do { | |
| 650 | + irr_val = prev_irr_val | pir_val; | |
| 651 | + } while (prev_irr_val != irr_val && | |
| 652 | + !try_cmpxchg(p_irr, &prev_irr_val, irr_val)); | |
| 653 | + | |
| 654 | + if (prev_irr_val != irr_val) | |
| 655 | + max_updated_irr = __fls(irr_val ^ prev_irr_val) + vec; | |
| 650 | 656 | } |
| 651 | 657 | if (irr_val) |
| 652 | 658 | *max_irr = __fls(irr_val) + vec; |
| @@ -660,8 +666,11 @@ EXPORT_SYMBOL_GPL(__kvm_apic_update_irr); · 7 unmodified lines | ||
| 660 | 666 | bool kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir, int *max_irr) |
| 661 | 667 | { |
| 662 | 668 | struct kvm_lapic *apic = vcpu->arch.apic; |
| 669 | + bool irr_updated = __kvm_apic_update_irr(pir, apic->regs, max_irr); | |
| 663 | 670 | |
| 664 | − return __kvm_apic_update_irr(pir, apic->regs, max_irr); | |
| 671 | + if (unlikely(!apic->apicv_active && irr_updated)) | |
| 672 | + apic->irr_pending = true; | |
| 673 | + return irr_updated; | |
| 665 | 674 | } |
| 666 | 675 | EXPORT_SYMBOL_GPL(kvm_apic_update_irr); |
| 667 | 676 | |
| @@ -2417,15 +2417,18 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *svm) · 2416 unmodified lines | ||
| 2417 | 2417 | */ |
| 2418 | 2418 | memset(vcpu->arch.regs, 0, sizeof(vcpu->arch.regs)); |
| 2419 | 2419 | |
| 2420 | − vcpu->arch.regs[VCPU_REGS_RAX] = ghcb_get_rax_if_valid(ghcb); | |
| 2421 | − vcpu->arch.regs[VCPU_REGS_RBX] = ghcb_get_rbx_if_valid(ghcb); | |
| 2422 | − vcpu->arch.regs[VCPU_REGS_RCX] = ghcb_get_rcx_if_valid(ghcb); | |
| 2423 | − vcpu->arch.regs[VCPU_REGS_RDX] = ghcb_get_rdx_if_valid(ghcb); | |
| 2424 | − vcpu->arch.regs[VCPU_REGS_RSI] = ghcb_get_rsi_if_valid(ghcb); | |
| 2420 | + BUILD_BUG_ON(sizeof(svm->sev_es.valid_bitmap) != sizeof(ghcb->save.valid_bitmap)); | |
| 2421 | + memcpy(&svm->sev_es.valid_bitmap, &ghcb->save.valid_bitmap, sizeof(ghcb->save.valid_bitmap)); | |
| 2425 | 2422 | |
| 2426 | − svm->vmcb->save.cpl = ghcb_get_cpl_if_valid(ghcb); | |
| 2423 | + vcpu->arch.regs[VCPU_REGS_RAX] = kvm_ghcb_get_rax_if_valid(svm, ghcb); | |
| 2424 | + vcpu->arch.regs[VCPU_REGS_RBX] = kvm_ghcb_get_rbx_if_valid(svm, ghcb); | |
| 2425 | + vcpu->arch.regs[VCPU_REGS_RCX] = kvm_ghcb_get_rcx_if_valid(svm, ghcb); | |
| 2426 | + vcpu->arch.regs[VCPU_REGS_RDX] = kvm_ghcb_get_rdx_if_valid(svm, ghcb); | |
| 2427 | + vcpu->arch.regs[VCPU_REGS_RSI] = kvm_ghcb_get_rsi_if_valid(svm, ghcb); | |
| 2427 | 2428 | |
| 2428 | − if (ghcb_xcr0_is_valid(ghcb)) { | |
| 2429 | + svm->vmcb->save.cpl = kvm_ghcb_get_cpl_if_valid(svm, ghcb); | |
| 2430 | + | |
| 2431 | + if (kvm_ghcb_xcr0_is_valid(svm)) { | |
| 2429 | 2432 | vcpu->arch.xcr0 = ghcb_get_xcr0(ghcb); |
| 2430 | 2433 | kvm_update_cpuid_runtime(vcpu); |
| 2431 | 2434 | } |
| @@ -2436,84 +2439,88 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *svm) · 4 unmodified lines | ||
| 2436 | 2439 | control->exit_code_hi = upper_32_bits(exit_code); |
| 2437 | 2440 | control->exit_info_1 = ghcb_get_sw_exit_info_1(ghcb); |
| 2438 | 2441 | control->exit_info_2 = ghcb_get_sw_exit_info_2(ghcb); |
| 2442 | + svm->sev_es.sw_scratch = kvm_ghcb_get_sw_scratch_if_valid(svm, ghcb); | |
| 2439 | 2443 | |
| 2440 | 2444 | /* Clear the valid entries fields */ |
| 2441 | 2445 | memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap)); |
| 2442 | 2446 | } |
| 2443 | 2447 | |
| 2448 | +static u64 kvm_ghcb_get_sw_exit_code(struct vmcb_control_area *control) | |
| 2449 | +{ | |
| 2450 | + return (((u64)control->exit_code_hi) << 32) | control->exit_code; | |
| 2451 | +} | |
| 2452 | + | |
| 2444 | 2453 | static int sev_es_validate_vmgexit(struct vcpu_svm *svm) |
| 2445 | 2454 | { |
| 2446 | − struct kvm_vcpu *vcpu; | |
| 2447 | − struct ghcb *ghcb; | |
| 2455 | + struct vmcb_control_area *control = &svm->vmcb->control; | |
| 2456 | + struct kvm_vcpu *vcpu = &svm->vcpu; | |
| 2448 | 2457 | u64 exit_code; |
| 2449 | 2458 | u64 reason; |
| 2450 | 2459 | |
| 2451 | − ghcb = svm->sev_es.ghcb; | |
| 2452 | − | |
| 2453 | 2460 | /* |
| 2454 | 2461 | * Retrieve the exit code now even though it may not be marked valid |
| 2455 | 2462 | * as it could help with debugging. |
| 2456 | 2463 | */ |
| 2457 | − exit_code = ghcb_get_sw_exit_code(ghcb); | |
| 2464 | + exit_code = kvm_ghcb_get_sw_exit_code(control); | |
| 2458 | 2465 | |
| 2459 | 2466 | /* Only GHCB Usage code 0 is supported */ |
| 2460 | − if (ghcb->ghcb_usage) { | |
| 2467 | + if (svm->sev_es.ghcb->ghcb_usage) { | |
| 2461 | 2468 | reason = GHCB_ERR_INVALID_USAGE; |
| 2462 | 2469 | goto vmgexit_err; |
| 2463 | 2470 | } |
| 2464 | 2471 | |
| 2465 | 2472 | reason = GHCB_ERR_MISSING_INPUT; |
| 2466 | 2473 | |
| 2467 | − if (!ghcb_sw_exit_code_is_valid(ghcb) || | |
| 2468 | − !ghcb_sw_exit_info_1_is_valid(ghcb) || | |
| 2469 | − !ghcb_sw_exit_info_2_is_valid(ghcb)) | |
| 2474 | + if (!kvm_ghcb_sw_exit_code_is_valid(svm) || | |
| 2475 | + !kvm_ghcb_sw_exit_info_1_is_valid(svm) || | |
| 2476 | + !kvm_ghcb_sw_exit_info_2_is_valid(svm)) | |
| 2470 | 2477 | goto vmgexit_err; |
| 2471 | 2478 | |
| 2472 | − switch (ghcb_get_sw_exit_code(ghcb)) { | |
| 2479 | + switch (exit_code) { | |
| 2473 | 2480 | case SVM_EXIT_READ_DR7: |
| 2474 | 2481 | break; |
| 2475 | 2482 | case SVM_EXIT_WRITE_DR7: |
| 2476 | − if (!ghcb_rax_is_valid(ghcb)) | |
| 2483 | + if (!kvm_ghcb_rax_is_valid(svm)) | |
| 2477 | 2484 | goto vmgexit_err; |
| 2478 | 2485 | break; |
| 2479 | 2486 | case SVM_EXIT_RDTSC: |
| 2480 | 2487 | break; |
| 2481 | 2488 | case SVM_EXIT_RDPMC: |
| 2482 | − if (!ghcb_rcx_is_valid(ghcb)) | |
| 2489 | + if (!kvm_ghcb_rcx_is_valid(svm)) | |
| 2483 | 2490 | goto vmgexit_err; |
| 2484 | 2491 | break; |
| 2485 | 2492 | case SVM_EXIT_CPUID: |
| 2486 | − if (!ghcb_rax_is_valid(ghcb) || | |
| 2487 | − !ghcb_rcx_is_valid(ghcb)) | |
| 2493 | + if (!kvm_ghcb_rax_is_valid(svm) || | |
| 2494 | + !kvm_ghcb_rcx_is_valid(svm)) | |
| 2488 | 2495 | goto vmgexit_err; |
| 2489 | − if (ghcb_get_rax(ghcb) == 0xd) | |
| 2490 | − if (!ghcb_xcr0_is_valid(ghcb)) | |
| 2496 | + if (vcpu->arch.regs[VCPU_REGS_RAX] == 0xd) | |
| 2497 | + if (!kvm_ghcb_xcr0_is_valid(svm)) | |
| 2491 | 2498 | goto vmgexit_err; |
| 2492 | 2499 | break; |
| 2493 | 2500 | case SVM_EXIT_INVD: |
| 2494 | 2501 | break; |
| 2495 | 2502 | case SVM_EXIT_IOIO: |
| 2496 | − if (ghcb_get_sw_exit_info_1(ghcb) & SVM_IOIO_STR_MASK) { | |
| 2497 | − if (!ghcb_sw_scratch_is_valid(ghcb)) | |
| 2503 | + if (control->exit_info_1 & SVM_IOIO_STR_MASK) { | |
| 2504 | + if (!kvm_ghcb_sw_scratch_is_valid(svm)) | |
| 2498 | 2505 | goto vmgexit_err; |
| 2499 | 2506 | } else { |
| 2500 | − if (!(ghcb_get_sw_exit_info_1(ghcb) & SVM_IOIO_TYPE_MASK)) | |
| 2501 | − if (!ghcb_rax_is_valid(ghcb)) | |
| 2507 | + if (!(control->exit_info_1 & SVM_IOIO_TYPE_MASK)) | |
| 2508 | + if (!kvm_ghcb_rax_is_valid(svm)) | |
| 2502 | 2509 | goto vmgexit_err; |
| 2503 | 2510 | } |
| 2504 | 2511 | break; |
| 2505 | 2512 | case SVM_EXIT_MSR: |
| 2506 | − if (!ghcb_rcx_is_valid(ghcb)) | |
| 2513 | + if (!kvm_ghcb_rcx_is_valid(svm)) | |
| 2507 | 2514 | goto vmgexit_err; |
| 2508 | − if (ghcb_get_sw_exit_info_1(ghcb)) { | |
| 2509 | − if (!ghcb_rax_is_valid(ghcb) || | |
| 2510 | − !ghcb_rdx_is_valid(ghcb)) | |
| 2515 | + if (control->exit_info_1) { | |
| 2516 | + if (!kvm_ghcb_rax_is_valid(svm) || | |
| 2517 | + !kvm_ghcb_rdx_is_valid(svm)) | |
| 2511 | 2518 | goto vmgexit_err; |
| 2512 | 2519 | } |
| 2513 | 2520 | break; |
| 2514 | 2521 | case SVM_EXIT_VMMCALL: |
| 2515 | − if (!ghcb_rax_is_valid(ghcb) || | |
| 2516 | − !ghcb_cpl_is_valid(ghcb)) | |
| 2522 | + if (!kvm_ghcb_rax_is_valid(svm) || | |
| 2523 | + !kvm_ghcb_cpl_is_valid(svm)) | |
| 2517 | 2524 | goto vmgexit_err; |
| 2518 | 2525 | break; |
| 2519 | 2526 | case SVM_EXIT_RDTSCP: |
| @@ -2521,19 +2528,19 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) · 1 unmodified line | ||
| 2521 | 2528 | case SVM_EXIT_WBINVD: |
| 2522 | 2529 | break; |
| 2523 | 2530 | case SVM_EXIT_MONITOR: |
| 2524 | − if (!ghcb_rax_is_valid(ghcb) || | |
| 2525 | − !ghcb_rcx_is_valid(ghcb) || | |
| 2526 | − !ghcb_rdx_is_valid(ghcb)) | |
| 2531 | + if (!kvm_ghcb_rax_is_valid(svm) || | |
| 2532 | + !kvm_ghcb_rcx_is_valid(svm) || | |
| 2533 | + !kvm_ghcb_rdx_is_valid(svm)) | |
| 2527 | 2534 | goto vmgexit_err; |
| 2528 | 2535 | break; |
| 2529 | 2536 | case SVM_EXIT_MWAIT: |
| 2530 | − if (!ghcb_rax_is_valid(ghcb) || | |
| 2531 | − !ghcb_rcx_is_valid(ghcb)) | |
| 2537 | + if (!kvm_ghcb_rax_is_valid(svm) || | |
| 2538 | + !kvm_ghcb_rcx_is_valid(svm)) | |
| 2532 | 2539 | goto vmgexit_err; |
| 2533 | 2540 | break; |
| 2534 | 2541 | case SVM_VMGEXIT_MMIO_READ: |
| 2535 | 2542 | case SVM_VMGEXIT_MMIO_WRITE: |
| 2536 | − if (!ghcb_sw_scratch_is_valid(ghcb)) | |
| 2543 | + if (!kvm_ghcb_sw_scratch_is_valid(svm)) | |
| 2537 | 2544 | goto vmgexit_err; |
| 2538 | 2545 | break; |
| 2539 | 2546 | case SVM_VMGEXIT_NMI_COMPLETE: |
| @@ -2549,11 +2556,9 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) · 9 unmodified lines | ||
| 2549 | 2556 | return 0; |
| 2550 | 2557 | |
| 2551 | 2558 | vmgexit_err: |
| 2552 | − vcpu = &svm->vcpu; | |
| 2553 | − | |
| 2554 | 2559 | if (reason == GHCB_ERR_INVALID_USAGE) { |
| 2555 | 2560 | vcpu_unimpl(vcpu, "vmgexit: ghcb usage %#x is not valid\n", |
| 2556 | − ghcb->ghcb_usage); | |
| 2561 | + svm->sev_es.ghcb->ghcb_usage); | |
| 2557 | 2562 | } else if (reason == GHCB_ERR_INVALID_EVENT) { |
| 2558 | 2563 | vcpu_unimpl(vcpu, "vmgexit: exit code %#llx is not valid\n", |
| 2559 | 2564 | exit_code); |
| @@ -2563,11 +2568,8 @@ vmgexit_err: · 3 unmodified lines | ||
| 2563 | 2568 | dump_ghcb(svm); |
| 2564 | 2569 | } |
| 2565 | 2570 | |
| 2566 | − /* Clear the valid entries fields */ | |
| 2567 | − memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap)); | |
| 2568 | − | |
| 2569 | − ghcb_set_sw_exit_info_1(ghcb, 2); | |
| 2570 | − ghcb_set_sw_exit_info_2(ghcb, reason); | |
| 2571 | + ghcb_set_sw_exit_info_1(svm->sev_es.ghcb, 2); | |
| 2572 | + ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, reason); | |
| 2571 | 2573 | |
| 2572 | 2574 | /* Resume the guest to "return" the error code. */ |
| 2573 | 2575 | return 1; |
| @@ -2586,7 +2588,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm) · 12 unmodified lines | ||
| 2586 | 2588 | */ |
| 2587 | 2589 | if (svm->sev_es.ghcb_sa_sync) { |
| 2588 | 2590 | kvm_write_guest(svm->vcpu.kvm, |
| 2589 | − ghcb_get_sw_scratch(svm->sev_es.ghcb), | |
| 2591 | + svm->sev_es.sw_scratch, | |
| 2590 | 2592 | svm->sev_es.ghcb_sa, |
| 2591 | 2593 | svm->sev_es.ghcb_sa_len); |
| 2592 | 2594 | svm->sev_es.ghcb_sa_sync = false; |
| @@ -2632,12 +2634,11 @@ void pre_sev_run(struct vcpu_svm *svm, int cpu) · 39 unmodified lines | ||
| 2632 | 2634 | static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) |
| 2633 | 2635 | { |
| 2634 | 2636 | struct vmcb_control_area *control = &svm->vmcb->control; |
| 2635 | − struct ghcb *ghcb = svm->sev_es.ghcb; | |
| 2636 | 2637 | u64 ghcb_scratch_beg, ghcb_scratch_end; |
| 2637 | 2638 | u64 scratch_gpa_beg, scratch_gpa_end; |
| 2638 | 2639 | void *scratch_va; |
| 2639 | 2640 | |
| 2640 | − scratch_gpa_beg = ghcb_get_sw_scratch(ghcb); | |
| 2641 | + scratch_gpa_beg = svm->sev_es.sw_scratch; | |
| 2641 | 2642 | if (!scratch_gpa_beg) { |
| 2642 | 2643 | pr_err("vmgexit: scratch gpa not provided\n"); |
| 2643 | 2644 | goto e_scratch; |
| @@ -2708,8 +2709,8 @@ static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) · 64 unmodified lines | ||
| 2708 | 2709 | return 0; |
| 2709 | 2710 | |
| 2710 | 2711 | e_scratch: |
| 2711 | − ghcb_set_sw_exit_info_1(ghcb, 2); | |
| 2712 | − ghcb_set_sw_exit_info_2(ghcb, GHCB_ERR_INVALID_SCRATCH_AREA); | |
| 2712 | + ghcb_set_sw_exit_info_1(svm->sev_es.ghcb, 2); | |
| 2713 | + ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, GHCB_ERR_INVALID_SCRATCH_AREA); | |
| 2713 | 2714 | |
| 2714 | 2715 | return 1; |
| 2715 | 2716 | } |
| @@ -2822,7 +2823,6 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) · 106 unmodified lines | ||
| 2822 | 2823 | struct vcpu_svm *svm = to_svm(vcpu); |
| 2823 | 2824 | struct vmcb_control_area *control = &svm->vmcb->control; |
| 2824 | 2825 | u64 ghcb_gpa, exit_code; |
| 2825 | − struct ghcb *ghcb; | |
| 2826 | 2826 | int ret; |
| 2827 | 2827 | |
| 2828 | 2828 | /* Validate the GHCB */ |
| @@ -2847,20 +2847,18 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) · 18 unmodified lines | ||
| 2847 | 2847 | } |
| 2848 | 2848 | |
| 2849 | 2849 | svm->sev_es.ghcb = svm->sev_es.ghcb_map.hva; |
| 2850 | − ghcb = svm->sev_es.ghcb_map.hva; | |
| 2851 | 2850 | |
| 2852 | − trace_kvm_vmgexit_enter(vcpu->vcpu_id, ghcb); | |
| 2853 | − | |
| 2854 | − exit_code = ghcb_get_sw_exit_code(ghcb); | |
| 2851 | + trace_kvm_vmgexit_enter(vcpu->vcpu_id, svm->sev_es.ghcb); | |
| 2855 | 2852 | |
| 2853 | + sev_es_sync_from_ghcb(svm); | |
| 2856 | 2854 | ret = sev_es_validate_vmgexit(svm); |
| 2857 | 2855 | if (ret) |
| 2858 | 2856 | return ret; |
| 2859 | 2857 | |
| 2860 | − sev_es_sync_from_ghcb(svm); | |
| 2861 | − ghcb_set_sw_exit_info_1(ghcb, 0); | |
| 2862 | − ghcb_set_sw_exit_info_2(ghcb, 0); | |
| 2858 | + ghcb_set_sw_exit_info_1(svm->sev_es.ghcb, 0); | |
| 2859 | + ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, 0); | |
| 2863 | 2860 | |
| 2861 | + exit_code = kvm_ghcb_get_sw_exit_code(control); | |
| 2864 | 2862 | switch (exit_code) { |
| 2865 | 2863 | case SVM_VMGEXIT_MMIO_READ: |
| 2866 | 2864 | ret = setup_vmgexit_scratch(svm, true, control->exit_info_2); |
| @@ -2898,13 +2896,13 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) · 31 unmodified lines | ||
| 2898 | 2896 | break; |
| 2899 | 2897 | case 1: |
| 2900 | 2898 | /* Get AP jump table address */ |
| 2901 | − ghcb_set_sw_exit_info_2(ghcb, sev->ap_jump_table); | |
| 2899 | + ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, sev->ap_jump_table); | |
| 2902 | 2900 | break; |
| 2903 | 2901 | default: |
| 2904 | 2902 | pr_err("svm: vmgexit: unsupported AP jump table request - exit_info_1=%#llx\n", |
| 2905 | 2903 | control->exit_info_1); |
| 2906 | − ghcb_set_sw_exit_info_1(ghcb, 2); | |
| 2907 | − ghcb_set_sw_exit_info_2(ghcb, GHCB_ERR_INVALID_INPUT); | |
| 2904 | + ghcb_set_sw_exit_info_1(svm->sev_es.ghcb, 2); | |
| 2905 | + ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, GHCB_ERR_INVALID_INPUT); | |
| 2908 | 2906 | } |
| 2909 | 2907 | |
| 2910 | 2908 | ret = 1; |
| @@ -1498,7 +1498,9 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) · 1497 unmodified lines | ||
| 1498 | 1498 | |
| 1499 | 1499 | if (sd->current_vmcb != svm->vmcb) { |
| 1500 | 1500 | sd->current_vmcb = svm->vmcb; |
| 1501 | − indirect_branch_prediction_barrier(); | |
| 1501 | + | |
| 1502 | + if (!cpu_feature_enabled(X86_FEATURE_IBPB_ON_VMEXIT)) | |
| 1503 | + indirect_branch_prediction_barrier(); | |
| 1502 | 1504 | } |
| 1503 | 1505 | if (kvm_vcpu_apicv_active(vcpu)) |
| 1504 | 1506 | avic_vcpu_load(vcpu, cpu); |
| @@ -1786,6 +1788,11 @@ static void sev_post_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) · 281 unmodified lines | ||
| 1786 | 1788 | } |
| 1787 | 1789 | } |
| 1788 | 1790 | |
| 1791 | +static bool svm_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |
| 1792 | +{ | |
| 1793 | + return true; | |
| 1794 | +} | |
| 1795 | + | |
| 1789 | 1796 | void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) |
| 1790 | 1797 | { |
| 1791 | 1798 | struct vcpu_svm *svm = to_svm(vcpu); |
| @@ -3986,14 +3993,8 @@ static int svm_vcpu_pre_run(struct kvm_vcpu *vcpu) · 2194 unmodified lines | ||
| 3986 | 3993 | |
| 3987 | 3994 | static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu) |
| 3988 | 3995 | { |
| 3989 | − struct vmcb_control_area *control = &to_svm(vcpu)->vmcb->control; | |
| 3990 | − | |
| 3991 | − /* | |
| 3992 | − * Note, the next RIP must be provided as SRCU isn't held, i.e. KVM | |
| 3993 | − * can't read guest memory (dereference memslots) to decode the WRMSR. | |
| 3994 | − */ | |
| 3995 | − if (control->exit_code == SVM_EXIT_MSR && control->exit_info_1 && | |
| 3996 | − nrips && control->next_rip) | |
| 3996 | + if (to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_MSR && | |
| 3997 | + to_svm(vcpu)->vmcb->control.exit_info_1) | |
| 3997 | 3998 | return handle_fastpath_set_msr_irqoff(vcpu); |
| 3998 | 3999 | |
| 3999 | 4000 | return EXIT_FASTPATH_NONE; |
| @@ -4815,6 +4816,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { · 815 unmodified lines | ||
| 4815 | 4816 | .set_segment = svm_set_segment, |
| 4816 | 4817 | .get_cpl = svm_get_cpl, |
| 4817 | 4818 | .get_cs_db_l_bits = svm_get_cs_db_l_bits, |
| 4819 | + .is_valid_cr0 = svm_is_valid_cr0, | |
| 4818 | 4820 | .set_cr0 = svm_set_cr0, |
| 4819 | 4821 | .post_set_cr3 = sev_post_set_cr3, |
| 4820 | 4822 | .is_valid_cr4 = svm_is_valid_cr4, |
| @@ -190,10 +190,12 @@ struct vcpu_sev_es_state { · 189 unmodified lines | ||
| 190 | 190 | /* SEV-ES support */ |
| 191 | 191 | struct sev_es_save_area *vmsa; |
| 192 | 192 | struct ghcb *ghcb; |
| 193 | + u8 valid_bitmap[16]; | |
| 193 | 194 | struct kvm_host_map ghcb_map; |
| 194 | 195 | bool received_first_sipi; |
| 195 | 196 | |
| 196 | 197 | /* SEV-ES scratch area support */ |
| 198 | + u64 sw_scratch; | |
| 197 | 199 | void *ghcb_sa; |
| 198 | 200 | u32 ghcb_sa_len; |
| 199 | 201 | bool ghcb_sa_sync; |
| @@ -744,4 +746,28 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm); · 544 unmodified lines | ||
| 744 | 746 | void __svm_sev_es_vcpu_run(struct vcpu_svm *svm, bool spec_ctrl_intercepted); |
| 745 | 747 | void __svm_vcpu_run(struct vcpu_svm *svm, bool spec_ctrl_intercepted); |
| 746 | 748 | |
| 749 | +#define DEFINE_KVM_GHCB_ACCESSORS(field) \ | |
| 750 | + static __always_inline bool kvm_ghcb_##field##_is_valid(const struct vcpu_svm *svm) \ | |
| 751 | + { \ | |
| 752 | + return test_bit(GHCB_BITMAP_IDX(field), \ | |
| 753 | + (unsigned long *)&svm->sev_es.valid_bitmap); \ | |
| 754 | + } \ | |
| 755 | + \ | |
| 756 | + static __always_inline u64 kvm_ghcb_get_##field##_if_valid(struct vcpu_svm *svm, struct ghcb *ghcb) \ | |
| 757 | + { \ | |
| 758 | + return kvm_ghcb_##field##_is_valid(svm) ? ghcb->save.field : 0; \ | |
| 759 | + } \ | |
| 760 | + | |
| 761 | +DEFINE_KVM_GHCB_ACCESSORS(cpl) | |
| 762 | +DEFINE_KVM_GHCB_ACCESSORS(rax) | |
| 763 | +DEFINE_KVM_GHCB_ACCESSORS(rcx) | |
| 764 | +DEFINE_KVM_GHCB_ACCESSORS(rdx) | |
| 765 | +DEFINE_KVM_GHCB_ACCESSORS(rbx) | |
| 766 | +DEFINE_KVM_GHCB_ACCESSORS(rsi) | |
| 767 | +DEFINE_KVM_GHCB_ACCESSORS(sw_exit_code) | |
| 768 | +DEFINE_KVM_GHCB_ACCESSORS(sw_exit_info_1) | |
| 769 | +DEFINE_KVM_GHCB_ACCESSORS(sw_exit_info_2) | |
| 770 | +DEFINE_KVM_GHCB_ACCESSORS(sw_scratch) | |
| 771 | +DEFINE_KVM_GHCB_ACCESSORS(xcr0) | |
| 772 | + | |
| 747 | 773 | #endif |
| @@ -224,6 +224,9 @@ SYM_FUNC_START(__svm_vcpu_run) · 223 unmodified lines | ||
| 224 | 224 | */ |
| 225 | 225 | UNTRAIN_RET |
| 226 | 226 | |
| 227 | + /* SRSO */ | |
| 228 | + ALTERNATIVE "", "call entry_ibpb", X86_FEATURE_IBPB_ON_VMEXIT | |
| 229 | + | |
| 227 | 230 | /* |
| 228 | 231 | * Clear all general purpose registers except RSP and RAX to prevent |
| 229 | 232 | * speculative use of the guest's values, even those that are reloaded |
| @@ -303,10 +303,8 @@ SYM_FUNC_START(vmx_do_nmi_irqoff) · 302 unmodified lines | ||
| 303 | 303 | VMX_DO_EVENT_IRQOFF call asm_exc_nmi_kvm_vmx |
| 304 | 304 | SYM_FUNC_END(vmx_do_nmi_irqoff) |
| 305 | 305 | |
| 306 | − | |
| 307 | −.section .text, "ax" | |
| 308 | − | |
| 309 | 306 | #ifndef CONFIG_CC_HAS_ASM_GOTO_OUTPUT |
| 307 | + | |
| 310 | 308 | /** |
| 311 | 309 | * vmread_error_trampoline - Trampoline from inline asm to vmread_error() |
| 312 | 310 | * @field: VMCS field encoding that failed |
| @@ -335,7 +333,7 @@ SYM_FUNC_START(vmread_error_trampoline) · 22 unmodified lines | ||
| 335 | 333 | mov 3*WORD_SIZE(%_ASM_BP), %_ASM_ARG2 |
| 336 | 334 | mov 2*WORD_SIZE(%_ASM_BP), %_ASM_ARG1 |
| 337 | 335 | |
| 338 | − call vmread_error | |
| 336 | + call vmread_error_trampoline2 | |
| 339 | 337 | |
| 340 | 338 | /* Zero out @fault, which will be popped into the result register. */ |
| 341 | 339 | _ASM_MOV $0, 3*WORD_SIZE(%_ASM_BP) |
| @@ -357,6 +355,8 @@ SYM_FUNC_START(vmread_error_trampoline) · 15 unmodified lines | ||
| 357 | 355 | SYM_FUNC_END(vmread_error_trampoline) |
| 358 | 356 | #endif |
| 359 | 357 | |
| 358 | +.section .text, "ax" | |
| 359 | + | |
| 360 | 360 | SYM_FUNC_START(vmx_do_interrupt_irqoff) |
| 361 | 361 | VMX_DO_EVENT_IRQOFF CALL_NOSPEC _ASM_ARG1 |
| 362 | 362 | SYM_FUNC_END(vmx_do_interrupt_irqoff) |
| @@ -441,13 +441,23 @@ do { \ · 440 unmodified lines | ||
| 441 | 441 | pr_warn_ratelimited(fmt); \ |
| 442 | 442 | } while (0) |
| 443 | 443 | |
| 444 | −void vmread_error(unsigned long field, bool fault) | |
| 444 | +noinline void vmread_error(unsigned long field) | |
| 445 | 445 | { |
| 446 | − if (fault) | |
| 446 | + vmx_insn_failed("vmread failed: field=%lx\n", field); | |
| 447 | +} | |
| 448 | + | |
| 449 | +#ifndef CONFIG_CC_HAS_ASM_GOTO_OUTPUT | |
| 450 | +noinstr void vmread_error_trampoline2(unsigned long field, bool fault) | |
| 451 | +{ | |
| 452 | + if (fault) { | |
| 447 | 453 | kvm_spurious_fault(); |
| 448 | − else | |
| 449 | − vmx_insn_failed("vmread failed: field=%lx\n", field); | |
| 454 | + } else { | |
| 455 | + instrumentation_begin(); | |
| 456 | + vmread_error(field); | |
| 457 | + instrumentation_end(); | |
| 458 | + } | |
| 450 | 459 | } |
| 460 | +#endif | |
| 451 | 461 | |
| 452 | 462 | noinline void vmwrite_error(unsigned long field, unsigned long value) |
| 453 | 463 | { |
| @@ -1503,6 +1513,11 @@ void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) · 1049 unmodified lines | ||
| 1503 | 1513 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| 1504 | 1514 | unsigned long old_rflags; |
| 1505 | 1515 | |
| 1516 | + /* | |
| 1517 | + * Unlike CR0 and CR4, RFLAGS handling requires checking if the vCPU | |
| 1518 | + * is an unrestricted guest in order to mark L2 as needing emulation | |
| 1519 | + * if L1 runs L2 as a restricted guest. | |
| 1520 | + */ | |
| 1506 | 1521 | if (is_unrestricted_guest(vcpu)) { |
| 1507 | 1522 | kvm_register_mark_available(vcpu, VCPU_EXREG_RFLAGS); |
| 1508 | 1523 | vmx->rflags = rflags; |
| @@ -3037,6 +3052,15 @@ static void enter_rmode(struct kvm_vcpu *vcpu) · 1528 unmodified lines | ||
| 3037 | 3052 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| 3038 | 3053 | struct kvm_vmx *kvm_vmx = to_kvm_vmx(vcpu->kvm); |
| 3039 | 3054 | |
| 3055 | + /* | |
| 3056 | + * KVM should never use VM86 to virtualize Real Mode when L2 is active, | |
| 3057 | + * as using VM86 is unnecessary if unrestricted guest is enabled, and | |
| 3058 | + * if unrestricted guest is disabled, VM-Enter (from L1) with CR0.PG=0 | |
| 3059 | + * should VM-Fail and KVM should reject userspace attempts to stuff | |
| 3060 | + * CR0.PG=0 when L2 is active. | |
| 3061 | + */ | |
| 3062 | + WARN_ON_ONCE(is_guest_mode(vcpu)); | |
| 3063 | + | |
| 3040 | 3064 | vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_TR], VCPU_SREG_TR); |
| 3041 | 3065 | vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_ES], VCPU_SREG_ES); |
| 3042 | 3066 | vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_DS], VCPU_SREG_DS); |
| @@ -3226,6 +3250,17 @@ void ept_save_pdptrs(struct kvm_vcpu *vcpu) · 183 unmodified lines | ||
| 3226 | 3250 | #define CR3_EXITING_BITS (CPU_BASED_CR3_LOAD_EXITING | \ |
| 3227 | 3251 | CPU_BASED_CR3_STORE_EXITING) |
| 3228 | 3252 | |
| 3253 | +static bool vmx_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |
| 3254 | +{ | |
| 3255 | + if (is_guest_mode(vcpu)) | |
| 3256 | + return nested_guest_cr0_valid(vcpu, cr0); | |
| 3257 | + | |
| 3258 | + if (to_vmx(vcpu)->nested.vmxon) | |
| 3259 | + return nested_host_cr0_valid(vcpu, cr0); | |
| 3260 | + | |
| 3261 | + return true; | |
| 3262 | +} | |
| 3263 | + | |
| 3229 | 3264 | void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) |
| 3230 | 3265 | { |
| 3231 | 3266 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| @@ -3235,7 +3270,7 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) · 3 unmodified lines | ||
| 3235 | 3270 | old_cr0_pg = kvm_read_cr0_bits(vcpu, X86_CR0_PG); |
| 3236 | 3271 | |
| 3237 | 3272 | hw_cr0 = (cr0 & ~KVM_VM_CR0_ALWAYS_OFF); |
| 3238 | − if (is_unrestricted_guest(vcpu)) | |
| 3273 | + if (enable_unrestricted_guest) | |
| 3239 | 3274 | hw_cr0 |= KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST; |
| 3240 | 3275 | else { |
| 3241 | 3276 | hw_cr0 |= KVM_VM_CR0_ALWAYS_ON; |
| @@ -3263,7 +3298,7 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) · 21 unmodified lines | ||
| 3263 | 3298 | } |
| 3264 | 3299 | #endif |
| 3265 | 3300 | |
| 3266 | − if (enable_ept && !is_unrestricted_guest(vcpu)) { | |
| 3301 | + if (enable_ept && !enable_unrestricted_guest) { | |
| 3267 | 3302 | /* |
| 3268 | 3303 | * Ensure KVM has an up-to-date snapshot of the guest's CR3. If |
| 3269 | 3304 | * the below code _enables_ CR3 exiting, vmx_cache_reg() will |
| @@ -3394,7 +3429,7 @@ void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) · 124 unmodified lines | ||
| 3394 | 3429 | * this bit, even if host CR4.MCE == 0. |
| 3395 | 3430 | */ |
| 3396 | 3431 | hw_cr4 = (cr4_read_shadow() & X86_CR4_MCE) | (cr4 & ~X86_CR4_MCE); |
| 3397 | − if (is_unrestricted_guest(vcpu)) | |
| 3432 | + if (enable_unrestricted_guest) | |
| 3398 | 3433 | hw_cr4 |= KVM_VM_CR4_ALWAYS_ON_UNRESTRICTED_GUEST; |
| 3399 | 3434 | else if (vmx->rmode.vm86_active) |
| 3400 | 3435 | hw_cr4 |= KVM_RMODE_VM_CR4_ALWAYS_ON; |
| @@ -3414,7 +3449,7 @@ void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) · 13 unmodified lines | ||
| 3414 | 3449 | vcpu->arch.cr4 = cr4; |
| 3415 | 3450 | kvm_register_mark_available(vcpu, VCPU_EXREG_CR4); |
| 3416 | 3451 | |
| 3417 | − if (!is_unrestricted_guest(vcpu)) { | |
| 3452 | + if (!enable_unrestricted_guest) { | |
| 3418 | 3453 | if (enable_ept) { |
| 3419 | 3454 | if (!is_paging(vcpu)) { |
| 3420 | 3455 | hw_cr4 &= ~X86_CR4_PAE; |
| @@ -4651,7 +4686,8 @@ static int vmx_alloc_ipiv_pid_table(struct kvm *kvm) · 1230 unmodified lines | ||
| 4651 | 4686 | if (kvm_vmx->pid_table) |
| 4652 | 4687 | return 0; |
| 4653 | 4688 | |
| 4654 | − pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, vmx_get_pid_table_order(kvm)); | |
| 4689 | + pages = alloc_pages(GFP_KERNEL_ACCOUNT | __GFP_ZERO, | |
| 4690 | + vmx_get_pid_table_order(kvm)); | |
| 4655 | 4691 | if (!pages) |
| 4656 | 4692 | return -ENOMEM; |
| 4657 | 4693 | |
| @@ -5364,18 +5400,11 @@ static int handle_set_cr0(struct kvm_vcpu *vcpu, unsigned long val) · 706 unmodified lines | ||
| 5364 | 5400 | val = (val & ~vmcs12->cr0_guest_host_mask) | |
| 5365 | 5401 | (vmcs12->guest_cr0 & vmcs12->cr0_guest_host_mask); |
| 5366 | 5402 | |
| 5367 | − if (!nested_guest_cr0_valid(vcpu, val)) | |
| 5368 | − return 1; | |
| 5369 | − | |
| 5370 | 5403 | if (kvm_set_cr0(vcpu, val)) |
| 5371 | 5404 | return 1; |
| 5372 | 5405 | vmcs_writel(CR0_READ_SHADOW, orig_val); |
| 5373 | 5406 | return 0; |
| 5374 | 5407 | } else { |
| 5375 | − if (to_vmx(vcpu)->nested.vmxon && | |
| 5376 | − !nested_host_cr0_valid(vcpu, val)) | |
| 5377 | − return 1; | |
| 5378 | − | |
| 5379 | 5408 | return kvm_set_cr0(vcpu, val); |
| 5380 | 5409 | } |
| 5381 | 5410 | } |
| @@ -8203,6 +8232,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { · 2821 unmodified lines | ||
| 8203 | 8232 | .set_segment = vmx_set_segment, |
| 8204 | 8233 | .get_cpl = vmx_get_cpl, |
| 8205 | 8234 | .get_cs_db_l_bits = vmx_get_cs_db_l_bits, |
| 8235 | + .is_valid_cr0 = vmx_is_valid_cr0, | |
| 8206 | 8236 | .set_cr0 = vmx_set_cr0, |
| 8207 | 8237 | .is_valid_cr4 = vmx_is_valid_cr4, |
| 8208 | 8238 | .set_cr4 = vmx_set_cr4, |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include "vmcs.h" |
| 11 | 11 | #include "../x86.h" |
| 12 | 12 | |
| 13 | −void vmread_error(unsigned long field, bool fault); | |
| 13 | +void vmread_error(unsigned long field); | |
| 14 | 14 | void vmwrite_error(unsigned long field, unsigned long value); |
| 15 | 15 | void vmclear_error(struct vmcs *vmcs, u64 phys_addr); |
| 16 | 16 | void vmptrld_error(struct vmcs *vmcs, u64 phys_addr); |
| @@ -31,6 +31,13 @@ void invept_error(unsigned long ext, u64 eptp, gpa_t gpa); · 14 unmodified lines | ||
| 31 | 31 | * void vmread_error_trampoline(unsigned long field, bool fault); |
| 32 | 32 | */ |
| 33 | 33 | extern unsigned long vmread_error_trampoline; |
| 34 | + | |
| 35 | +/* | |
| 36 | + * The second VMREAD error trampoline, called from the assembly trampoline, | |
| 37 | + * exists primarily to enable instrumentation for the VM-Fail path. | |
| 38 | + */ | |
| 39 | +void vmread_error_trampoline2(unsigned long field, bool fault); | |
| 40 | + | |
| 34 | 41 | #endif |
| 35 | 42 | |
| 36 | 43 | static __always_inline void vmcs_check16(unsigned long field) |
| @@ -101,8 +108,7 @@ static __always_inline unsigned long __vmcs_readl(unsigned long field) · 64 unmodified lines | ||
| 101 | 108 | |
| 102 | 109 | do_fail: |
| 103 | 110 | instrumentation_begin(); |
| 104 | − WARN_ONCE(1, KBUILD_MODNAME ": vmread failed: field=%lx\n", field); | |
| 105 | − pr_warn_ratelimited(KBUILD_MODNAME ": vmread failed: field=%lx\n", field); | |
| 111 | + vmread_error(field); | |
| 106 | 112 | instrumentation_end(); |
| 107 | 113 | return 0; |
| 108 | 114 | |
| @@ -906,6 +906,22 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3) · 905 unmodified lines | ||
| 906 | 906 | } |
| 907 | 907 | EXPORT_SYMBOL_GPL(load_pdptrs); |
| 908 | 908 | |
| 909 | +static bool kvm_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |
| 910 | +{ | |
| 911 | +#ifdef CONFIG_X86_64 | |
| 912 | + if (cr0 & 0xffffffff00000000UL) | |
| 913 | + return false; | |
| 914 | +#endif | |
| 915 | + | |
| 916 | + if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) | |
| 917 | + return false; | |
| 918 | + | |
| 919 | + if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE)) | |
| 920 | + return false; | |
| 921 | + | |
| 922 | + return static_call(kvm_x86_is_valid_cr0)(vcpu, cr0); | |
| 923 | +} | |
| 924 | + | |
| 909 | 925 | void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned long cr0) |
| 910 | 926 | { |
| 911 | 927 | /* |
| @@ -952,20 +968,13 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) · 40 unmodified lines | ||
| 952 | 968 | { |
| 953 | 969 | unsigned long old_cr0 = kvm_read_cr0(vcpu); |
| 954 | 970 | |
| 955 | − cr0 |= X86_CR0_ET; | |
| 956 | − | |
| 957 | −#ifdef CONFIG_X86_64 | |
| 958 | − if (cr0 & 0xffffffff00000000UL) | |
| 971 | + if (!kvm_is_valid_cr0(vcpu, cr0)) | |
| 959 | 972 | return 1; |
| 960 | −#endif | |
| 961 | − | |
| 962 | − cr0 &= ~CR0_RESERVED_BITS; | |
| 963 | 973 | |
| 964 | − if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) | |
| 965 | − return 1; | |
| 974 | + cr0 |= X86_CR0_ET; | |
| 966 | 975 | |
| 967 | − if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE)) | |
| 968 | − return 1; | |
| 976 | + /* Write to CR0 reserved bits are ignored, even on Intel. */ | |
| 977 | + cr0 &= ~CR0_RESERVED_BITS; | |
| 969 | 978 | |
| 970 | 979 | #ifdef CONFIG_X86_64 |
| 971 | 980 | if ((vcpu->arch.efer & EFER_LME) && !is_paging(vcpu) && |
| @@ -1607,7 +1616,7 @@ static bool kvm_is_immutable_feature_msr(u32 msr) · 635 unmodified lines | ||
| 1607 | 1616 | ARCH_CAP_SKIP_VMENTRY_L1DFLUSH | ARCH_CAP_SSB_NO | ARCH_CAP_MDS_NO | \ |
| 1608 | 1617 | ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \ |
| 1609 | 1618 | ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \ |
| 1610 | − ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO) | |
| 1619 | + ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO) | |
| 1611 | 1620 | |
| 1612 | 1621 | static u64 kvm_get_arch_capabilities(void) |
| 1613 | 1622 | { |
| @@ -1664,6 +1673,9 @@ static u64 kvm_get_arch_capabilities(void) · 50 unmodified lines | ||
| 1664 | 1673 | */ |
| 1665 | 1674 | } |
| 1666 | 1675 | |
| 1676 | + if (!boot_cpu_has_bug(X86_BUG_GDS) || gds_ucode_mitigated()) | |
| 1677 | + data |= ARCH_CAP_GDS_NO; | |
| 1678 | + | |
| 1667 | 1679 | return data; |
| 1668 | 1680 | } |
| 1669 | 1681 | |
| @@ -2172,6 +2184,8 @@ fastpath_t handle_fastpath_set_msr_irqoff(struct kvm_vcpu *vcpu) · 502 unmodified lines | ||
| 2172 | 2184 | u64 data; |
| 2173 | 2185 | fastpath_t ret = EXIT_FASTPATH_NONE; |
| 2174 | 2186 | |
| 2187 | + kvm_vcpu_srcu_read_lock(vcpu); | |
| 2188 | + | |
| 2175 | 2189 | switch (msr) { |
| 2176 | 2190 | case APIC_BASE_MSR + (APIC_ICR >> 4): |
| 2177 | 2191 | data = kvm_read_edx_eax(vcpu); |
| @@ -2194,6 +2208,8 @@ fastpath_t handle_fastpath_set_msr_irqoff(struct kvm_vcpu *vcpu) · 16 unmodified lines | ||
| 2194 | 2208 | if (ret != EXIT_FASTPATH_NONE) |
| 2195 | 2209 | trace_kvm_msr_write(msr, data); |
| 2196 | 2210 | |
| 2211 | + kvm_vcpu_srcu_read_unlock(vcpu); | |
| 2212 | + | |
| 2197 | 2213 | return ret; |
| 2198 | 2214 | } |
| 2199 | 2215 | EXPORT_SYMBOL_GPL(handle_fastpath_set_msr_irqoff); |
| @@ -10203,9 +10219,13 @@ static int kvm_check_and_inject_events(struct kvm_vcpu *vcpu, · 8003 unmodified lines | ||
| 10203 | 10219 | if (r < 0) |
| 10204 | 10220 | goto out; |
| 10205 | 10221 | if (r) { |
| 10206 | − kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu), false); | |
| 10207 | − static_call(kvm_x86_inject_irq)(vcpu, false); | |
| 10208 | − WARN_ON(static_call(kvm_x86_interrupt_allowed)(vcpu, true) < 0); | |
| 10222 | + int irq = kvm_cpu_get_interrupt(vcpu); | |
| 10223 | + | |
| 10224 | + if (!WARN_ON_ONCE(irq == -1)) { | |
| 10225 | + kvm_queue_interrupt(vcpu, irq, false); | |
| 10226 | + static_call(kvm_x86_inject_irq)(vcpu, false); | |
| 10227 | + WARN_ON(static_call(kvm_x86_interrupt_allowed)(vcpu, true) < 0); | |
| 10228 | + } | |
| 10209 | 10229 | } |
| 10210 | 10230 | if (kvm_cpu_has_injectable_intr(vcpu)) |
| 10211 | 10231 | static_call(kvm_x86_enable_irq_window)(vcpu); |
| @@ -11460,7 +11480,8 @@ static bool kvm_is_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) · 1248 unmodified lines | ||
| 11460 | 11480 | return false; |
| 11461 | 11481 | } |
| 11462 | 11482 | |
| 11463 | − return kvm_is_valid_cr4(vcpu, sregs->cr4); | |
| 11483 | + return kvm_is_valid_cr4(vcpu, sregs->cr4) && | |
| 11484 | + kvm_is_valid_cr0(vcpu, sregs->cr0); | |
| 11464 | 11485 | } |
| 11465 | 11486 | |
| 11466 | 11487 | static int __set_sregs_common(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs, |
| @@ -13185,7 +13206,7 @@ EXPORT_SYMBOL_GPL(kvm_arch_has_noncoherent_dma); · 1718 unmodified lines | ||
| 13185 | 13206 | |
| 13186 | 13207 | bool kvm_arch_has_irq_bypass(void) |
| 13187 | 13208 | { |
| 13188 | − return true; | |
| 13209 | + return enable_apicv && irq_remapping_cap(IRQ_POSTING_CAP); | |
| 13189 | 13210 | } |
| 13190 | 13211 | |
| 13191 | 13212 | int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons, |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <asm/unwind_hints.h> |
| 12 | 12 | #include <asm/percpu.h> |
| 13 | 13 | #include <asm/frame.h> |
| 14 | +#include <asm/nops.h> | |
| 14 | 15 | |
| 15 | 16 | .section .text.__x86.indirect_thunk |
| 16 | 17 | |
| @@ -131,6 +132,46 @@ SYM_CODE_END(__x86_indirect_jump_thunk_array) · 114 unmodified lines | ||
| 131 | 132 | */ |
| 132 | 133 | #ifdef CONFIG_RETHUNK |
| 133 | 134 | |
| 135 | +/* | |
| 136 | + * srso_untrain_ret_alias() and srso_safe_ret_alias() are placed at | |
| 137 | + * special addresses: | |
| 138 | + * | |
| 139 | + * - srso_untrain_ret_alias() is 2M aligned | |
| 140 | + * - srso_safe_ret_alias() is also in the same 2M page but bits 2, 8, 14 | |
| 141 | + * and 20 in its virtual address are set (while those bits in the | |
| 142 | + * srso_untrain_ret_alias() function are cleared). | |
| 143 | + * | |
| 144 | + * This guarantees that those two addresses will alias in the branch | |
| 145 | + * target buffer of Zen3/4 generations, leading to any potential | |
| 146 | + * poisoned entries at that BTB slot to get evicted. | |
| 147 | + * | |
| 148 | + * As a result, srso_safe_ret_alias() becomes a safe return. | |
| 149 | + */ | |
| 150 | +#ifdef CONFIG_CPU_SRSO | |
| 151 | + .section .text.__x86.rethunk_untrain | |
| 152 | + | |
| 153 | +SYM_START(srso_untrain_ret_alias, SYM_L_GLOBAL, SYM_A_NONE) | |
| 154 | + ANNOTATE_NOENDBR | |
| 155 | + ASM_NOP2 | |
| 156 | + lfence | |
| 157 | + jmp __x86_return_thunk | |
| 158 | +SYM_FUNC_END(srso_untrain_ret_alias) | |
| 159 | +__EXPORT_THUNK(srso_untrain_ret_alias) | |
| 160 | + | |
| 161 | + .section .text.__x86.rethunk_safe | |
| 162 | +#endif | |
| 163 | + | |
| 164 | +/* Needs a definition for the __x86_return_thunk alternative below. */ | |
| 165 | +SYM_START(srso_safe_ret_alias, SYM_L_GLOBAL, SYM_A_NONE) | |
| 166 | +#ifdef CONFIG_CPU_SRSO | |
| 167 | + add $8, %_ASM_SP | |
| 168 | + UNWIND_HINT_FUNC | |
| 169 | +#endif | |
| 170 | + ANNOTATE_UNRET_SAFE | |
| 171 | + ret | |
| 172 | + int3 | |
| 173 | +SYM_FUNC_END(srso_safe_ret_alias) | |
| 174 | + | |
| 134 | 175 | .section .text.__x86.return_thunk |
| 135 | 176 | |
| 136 | 177 | /* |
| @@ -143,7 +184,7 @@ SYM_CODE_END(__x86_indirect_jump_thunk_array) · 6 unmodified lines | ||
| 143 | 184 | * from re-poisioning the BTB prediction. |
| 144 | 185 | */ |
| 145 | 186 | .align 64 |
| 146 | − .skip 64 - (__x86_return_thunk - zen_untrain_ret), 0xcc | |
| 187 | + .skip 64 - (__ret - zen_untrain_ret), 0xcc | |
| 147 | 188 | SYM_START(zen_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE) |
| 148 | 189 | ANNOTATE_NOENDBR |
| 149 | 190 | /* |
| @@ -175,10 +216,10 @@ SYM_START(zen_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE) · 25 unmodified lines | ||
| 175 | 216 | * evicted, __x86_return_thunk will suffer Straight Line Speculation |
| 176 | 217 | * which will be contained safely by the INT3. |
| 177 | 218 | */ |
| 178 | −SYM_INNER_LABEL(__x86_return_thunk, SYM_L_GLOBAL) | |
| 219 | +SYM_INNER_LABEL(__ret, SYM_L_GLOBAL) | |
| 179 | 220 | ret |
| 180 | 221 | int3 |
| 181 | −SYM_CODE_END(__x86_return_thunk) | |
| 222 | +SYM_CODE_END(__ret) | |
| 182 | 223 | |
| 183 | 224 | /* |
| 184 | 225 | * Ensure the TEST decoding / BTB invalidation is complete. |
| @@ -189,11 +230,45 @@ SYM_CODE_END(__x86_return_thunk) · 4 unmodified lines | ||
| 189 | 230 | * Jump back and execute the RET in the middle of the TEST instruction. |
| 190 | 231 | * INT3 is for SLS protection. |
| 191 | 232 | */ |
| 192 | − jmp __x86_return_thunk | |
| 233 | + jmp __ret | |
| 193 | 234 | int3 |
| 194 | 235 | SYM_FUNC_END(zen_untrain_ret) |
| 195 | 236 | __EXPORT_THUNK(zen_untrain_ret) |
| 196 | 237 | |
| 238 | +/* | |
| 239 | + * SRSO untraining sequence for Zen1/2, similar to zen_untrain_ret() | |
| 240 | + * above. On kernel entry, srso_untrain_ret() is executed which is a | |
| 241 | + * | |
| 242 | + * movabs $0xccccccc308c48348,%rax | |
| 243 | + * | |
| 244 | + * and when the return thunk executes the inner label srso_safe_ret() | |
| 245 | + * later, it is a stack manipulation and a RET which is mispredicted and | |
| 246 | + * thus a "safe" one to use. | |
| 247 | + */ | |
| 248 | + .align 64 | |
| 249 | + .skip 64 - (srso_safe_ret - srso_untrain_ret), 0xcc | |
| 250 | +SYM_START(srso_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE) | |
| 251 | + ANNOTATE_NOENDBR | |
| 252 | + .byte 0x48, 0xb8 | |
| 253 | + | |
| 254 | +SYM_INNER_LABEL(srso_safe_ret, SYM_L_GLOBAL) | |
| 255 | + add $8, %_ASM_SP | |
| 256 | + ret | |
| 257 | + int3 | |
| 258 | + int3 | |
| 259 | + int3 | |
| 260 | + lfence | |
| 261 | + call srso_safe_ret | |
| 262 | + int3 | |
| 263 | +SYM_CODE_END(srso_safe_ret) | |
| 264 | +SYM_FUNC_END(srso_untrain_ret) | |
| 265 | +__EXPORT_THUNK(srso_untrain_ret) | |
| 266 | + | |
| 267 | +SYM_FUNC_START(__x86_return_thunk) | |
| 268 | + ALTERNATIVE_2 "jmp __ret", "call srso_safe_ret", X86_FEATURE_SRSO, \ | |
| 269 | + "call srso_safe_ret_alias", X86_FEATURE_SRSO_ALIAS | |
| 270 | + int3 | |
| 271 | +SYM_CODE_END(__x86_return_thunk) | |
| 197 | 272 | EXPORT_SYMBOL(__x86_return_thunk) |
| 198 | 273 | |
| 199 | 274 | #endif /* CONFIG_RETHUNK */ |
| @@ -722,14 +722,9 @@ void submit_bio_noacct(struct bio *bio) · 721 unmodified lines | ||
| 722 | 722 | struct block_device *bdev = bio->bi_bdev; |
| 723 | 723 | struct request_queue *q = bdev_get_queue(bdev); |
| 724 | 724 | blk_status_t status = BLK_STS_IOERR; |
| 725 | − struct blk_plug *plug; | |
| 726 | 725 | |
| 727 | 726 | might_sleep(); |
| 728 | 727 | |
| 729 | − plug = blk_mq_plug(bio); | |
| 730 | − if (plug && plug->nowait) | |
| 731 | − bio->bi_opf |= REQ_NOWAIT; | |
| 732 | − | |
| 733 | 728 | /* |
| 734 | 729 | * For a REQ_NOWAIT based request, return -EOPNOTSUPP |
| 735 | 730 | * if queue does not support NOWAIT. |
| @@ -1059,7 +1054,6 @@ void blk_start_plug_nr_ios(struct blk_plug *plug, unsigned short nr_ios) · 323 unmodified lines | ||
| 1059 | 1054 | plug->rq_count = 0; |
| 1060 | 1055 | plug->multiple_queues = false; |
| 1061 | 1056 | plug->has_elevator = false; |
| 1062 | − plug->nowait = false; | |
| 1063 | 1057 | INIT_LIST_HEAD(&plug->cb_list); |
| 1064 | 1058 | |
| 1065 | 1059 | /* |
| @@ -3301,11 +3301,12 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input, · 3300 unmodified lines | ||
| 3301 | 3301 | if (qos[QOS_MIN] > qos[QOS_MAX]) |
| 3302 | 3302 | goto einval; |
| 3303 | 3303 | |
| 3304 | − if (enable) { | |
| 3304 | + if (enable && !ioc->enabled) { | |
| 3305 | 3305 | blk_stat_enable_accounting(disk->queue); |
| 3306 | 3306 | blk_queue_flag_set(QUEUE_FLAG_RQ_ALLOC_TIME, disk->queue); |
| 3307 | 3307 | ioc->enabled = true; |
| 3308 | − } else { | |
| 3308 | + } else if (!enable && ioc->enabled) { | |
| 3309 | + blk_stat_disable_accounting(disk->queue); | |
| 3309 | 3310 | blk_queue_flag_clear(QUEUE_FLAG_RQ_ALLOC_TIME, disk->queue); |
| 3310 | 3311 | ioc->enabled = false; |
| 3311 | 3312 | } |
| @@ -358,13 +358,14 @@ static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb, · 357 unmodified lines | ||
| 358 | 358 | task_io_account_write(bio->bi_iter.bi_size); |
| 359 | 359 | } |
| 360 | 360 | |
| 361 | + if (iocb->ki_flags & IOCB_NOWAIT) | |
| 362 | + bio->bi_opf |= REQ_NOWAIT; | |
| 363 | + | |
| 361 | 364 | if (iocb->ki_flags & IOCB_HIPRI) { |
| 362 | − bio->bi_opf |= REQ_POLLED | REQ_NOWAIT; | |
| 365 | + bio->bi_opf |= REQ_POLLED; | |
| 363 | 366 | submit_bio(bio); |
| 364 | 367 | WRITE_ONCE(iocb->private, bio); |
| 365 | 368 | } else { |
| 366 | − if (iocb->ki_flags & IOCB_NOWAIT) | |
| 367 | − bio->bi_opf |= REQ_NOWAIT; | |
| 368 | 369 | submit_bio(bio); |
| 369 | 370 | } |
| 370 | 371 | return -EIOCBQUEUED; |
| @@ -173,6 +173,9 @@ static void internal_free_pages_locked(struct ivpu_bo *bo) · 172 unmodified lines | ||
| 173 | 173 | { |
| 174 | 174 | unsigned int i, npages = bo->base.size >> PAGE_SHIFT; |
| 175 | 175 | |
| 176 | + if (ivpu_bo_cache_mode(bo) != DRM_IVPU_BO_CACHED) | |
| 177 | + set_pages_array_wb(bo->pages, bo->base.size >> PAGE_SHIFT); | |
| 178 | + | |
| 176 | 179 | for (i = 0; i < npages; i++) |
| 177 | 180 | put_page(bo->pages[i]); |
| 178 | 181 | |
| @@ -587,6 +590,11 @@ ivpu_bo_alloc_internal(struct ivpu_device *vdev, u64 vpu_addr, u64 size, u32 fla · 408 unmodified lines | ||
| 587 | 590 | if (ivpu_bo_cache_mode(bo) != DRM_IVPU_BO_CACHED) |
| 588 | 591 | drm_clflush_pages(bo->pages, bo->base.size >> PAGE_SHIFT); |
| 589 | 592 | |
| 593 | + if (bo->flags & DRM_IVPU_BO_WC) | |
| 594 | + set_pages_array_wc(bo->pages, bo->base.size >> PAGE_SHIFT); | |
| 595 | + else if (bo->flags & DRM_IVPU_BO_UNCACHED) | |
| 596 | + set_pages_array_uc(bo->pages, bo->base.size >> PAGE_SHIFT); | |
| 597 | + | |
| 590 | 598 | prot = ivpu_bo_pgprot(bo, PAGE_KERNEL); |
| 591 | 599 | bo->kvaddr = vmap(bo->pages, bo->base.size >> PAGE_SHIFT, VM_MAP, prot); |
| 592 | 600 | if (!bo->kvaddr) { |
| @@ -1007,9 +1007,6 @@ static void iort_node_get_rmr_info(struct acpi_iort_node *node, · 1006 unmodified lines | ||
| 1007 | 1007 | for (i = 0; i < node->mapping_count; i++, map++) { |
| 1008 | 1008 | struct acpi_iort_node *parent; |
| 1009 | 1009 | |
| 1010 | − if (!map->id_count) | |
| 1011 | − continue; | |
| 1012 | − | |
| 1013 | 1010 | parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table, |
| 1014 | 1011 | map->output_reference); |
| 1015 | 1012 | if (parent != iommu) |
| @@ -470,6 +470,45 @@ static const struct dmi_system_id asus_laptop[] = { · 469 unmodified lines | ||
| 470 | 470 | { } |
| 471 | 471 | }; |
| 472 | 472 | |
| 473 | +static const struct dmi_system_id tongfang_gm_rg[] = { | |
| 474 | + { | |
| 475 | + .ident = "TongFang GMxRGxx/XMG CORE 15 (M22)/TUXEDO Stellaris 15 Gen4 AMD", | |
| 476 | + .matches = { | |
| 477 | + DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"), | |
| 478 | + }, | |
| 479 | + }, | |
| 480 | + { } | |
| 481 | +}; | |
| 482 | + | |
| 483 | +static const struct dmi_system_id maingear_laptop[] = { | |
| 484 | + { | |
| 485 | + .ident = "MAINGEAR Vector Pro 2 15", | |
| 486 | + .matches = { | |
| 487 | + DMI_MATCH(DMI_SYS_VENDOR, "Micro Electronics Inc"), | |
| 488 | + DMI_MATCH(DMI_PRODUCT_NAME, "MG-VCP2-15A3070T"), | |
| 489 | + } | |
| 490 | + }, | |
| 491 | + { | |
| 492 | + .ident = "MAINGEAR Vector Pro 2 17", | |
| 493 | + .matches = { | |
| 494 | + DMI_MATCH(DMI_SYS_VENDOR, "Micro Electronics Inc"), | |
| 495 | + DMI_MATCH(DMI_PRODUCT_NAME, "MG-VCP2-17A3070T"), | |
| 496 | + }, | |
| 497 | + }, | |
| 498 | + { } | |
| 499 | +}; | |
| 500 | + | |
| 501 | +static const struct dmi_system_id pcspecialist_laptop[] = { | |
| 502 | + { | |
| 503 | + .ident = "PCSpecialist Elimina Pro 16 M", | |
| 504 | + .matches = { | |
| 505 | + DMI_MATCH(DMI_SYS_VENDOR, "PCSpecialist"), | |
| 506 | + DMI_MATCH(DMI_PRODUCT_NAME, "Elimina Pro 16 M"), | |
| 507 | + }, | |
| 508 | + }, | |
| 509 | + { } | |
| 510 | +}; | |
| 511 | + | |
| 473 | 512 | static const struct dmi_system_id lg_laptop[] = { |
| 474 | 513 | { |
| 475 | 514 | .ident = "LG Electronics 17U70P", |
| @@ -493,6 +532,9 @@ struct irq_override_cmp { · 17 unmodified lines | ||
| 493 | 532 | static const struct irq_override_cmp override_table[] = { |
| 494 | 533 | { medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false }, |
| 495 | 534 | { asus_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false }, |
| 535 | + { tongfang_gm_rg, 1, ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_LOW, 1, true }, | |
| 536 | + { maingear_laptop, 1, ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_LOW, 1, true }, | |
| 537 | + { pcspecialist_laptop, 1, ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_LOW, 1, true }, | |
| 496 | 538 | { lg_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false }, |
| 497 | 539 | }; |
| 498 | 540 | |
| @@ -512,6 +554,28 @@ static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity, · 13 unmodified lines | ||
| 512 | 554 | return entry->override; |
| 513 | 555 | } |
| 514 | 556 | |
| 557 | +#ifdef CONFIG_X86 | |
| 558 | + /* | |
| 559 | + * Always use the MADT override info, except for the i8042 PS/2 ctrl | |
| 560 | + * IRQs (1 and 12). For these the DSDT IRQ settings should sometimes | |
| 561 | + * be used otherwise PS/2 keyboards / mice will not work. | |
| 562 | + */ | |
| 563 | + if (gsi != 1 && gsi != 12) | |
| 564 | + return true; | |
| 565 | + | |
| 566 | + /* If the override comes from an INT_SRC_OVR MADT entry, honor it. */ | |
| 567 | + if (acpi_int_src_ovr[gsi]) | |
| 568 | + return true; | |
| 569 | + | |
| 570 | + /* | |
| 571 | + * IRQ override isn't needed on modern AMD Zen systems and | |
| 572 | + * this override breaks active low IRQs on AMD Ryzen 6000 and | |
| 573 | + * newer systems. Skip it. | |
| 574 | + */ | |
| 575 | + if (boot_cpu_has(X86_FEATURE_ZEN)) | |
| 576 | + return false; | |
| 577 | +#endif | |
| 578 | + | |
| 515 | 579 | return true; |
| 516 | 580 | } |
| 517 | 581 | |
| @@ -1714,6 +1714,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) · 1713 unmodified lines | ||
| 1714 | 1714 | {"BSG1160", }, |
| 1715 | 1715 | {"BSG2150", }, |
| 1716 | 1716 | {"CSC3551", }, |
| 1717 | + {"CSC3556", }, | |
| 1717 | 1718 | {"INT33FE", }, |
| 1718 | 1719 | {"INT3515", }, |
| 1719 | 1720 | /* Non-conforming _HID for Cirrus Logic already released */ |
| @@ -6617,6 +6617,7 @@ err_init_binder_device_failed: · 6616 unmodified lines | ||
| 6617 | 6617 | |
| 6618 | 6618 | err_alloc_device_names_failed: |
| 6619 | 6619 | debugfs_remove_recursive(binder_debugfs_dir_entry_root); |
| 6620 | + binder_alloc_shrinker_exit(); | |
| 6620 | 6621 | |
| 6621 | 6622 | return ret; |
| 6622 | 6623 | } |
| @@ -1087,6 +1087,12 @@ int binder_alloc_shrinker_init(void) · 1086 unmodified lines | ||
| 1087 | 1087 | return ret; |
| 1088 | 1088 | } |
| 1089 | 1089 | |
| 1090 | +void binder_alloc_shrinker_exit(void) | |
| 1091 | +{ | |
| 1092 | + unregister_shrinker(&binder_shrinker); | |
| 1093 | + list_lru_destroy(&binder_alloc_lru); | |
| 1094 | +} | |
| 1095 | + | |
| 1090 | 1096 | /** |
| 1091 | 1097 | * check_buffer() - verify that buffer/offset is safe to access |
| 1092 | 1098 | * @alloc: binder_alloc for this proc |
| @@ -129,6 +129,7 @@ extern struct binder_buffer *binder_alloc_new_buf(struct binder_alloc *alloc, · 128 unmodified lines | ||
| 129 | 129 | int pid); |
| 130 | 130 | extern void binder_alloc_init(struct binder_alloc *alloc); |
| 131 | 131 | extern int binder_alloc_shrinker_init(void); |
| 132 | +extern void binder_alloc_shrinker_exit(void); | |
| 132 | 133 | extern void binder_alloc_vma_close(struct binder_alloc *alloc); |
| 133 | 134 | extern struct binder_buffer * |
| 134 | 135 | binder_alloc_prepare_to_free(struct binder_alloc *alloc, |
| @@ -4938,8 +4938,8 @@ void ata_qc_complete(struct ata_queued_cmd *qc) · 4937 unmodified lines | ||
| 4938 | 4938 | if (qc->result_tf.status & ATA_SENSE && |
| 4939 | 4939 | ((ata_is_ncq(qc->tf.protocol) && |
| 4940 | 4940 | dev->flags & ATA_DFLAG_CDL_ENABLED) || |
| 4941 | − (!(ata_is_ncq(qc->tf.protocol) && | |
| 4942 | − ata_id_sense_reporting_enabled(dev->id))))) { | |
| 4941 | + (!ata_is_ncq(qc->tf.protocol) && | |
| 4942 | + ata_id_sense_reporting_enabled(dev->id)))) { | |
| 4943 | 4943 | /* |
| 4944 | 4944 | * Tell SCSI EH to not overwrite scmd->result even if |
| 4945 | 4945 | * this command is finished with result SAM_STAT_GOOD. |
| @@ -1100,7 +1100,14 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) · 1099 unmodified lines | ||
| 1100 | 1100 | } |
| 1101 | 1101 | } else { |
| 1102 | 1102 | sdev->sector_size = ata_id_logical_sector_size(dev->id); |
| 1103 | + /* | |
| 1104 | + * Stop the drive on suspend but do not issue START STOP UNIT | |
| 1105 | + * on resume as this is not necessary and may fail: the device | |
| 1106 | + * will be woken up by ata_port_pm_resume() with a port reset | |
| 1107 | + * and device revalidation. | |
| 1108 | + */ | |
| 1103 | 1109 | sdev->manage_start_stop = 1; |
| 1110 | + sdev->no_start_on_resume = 1; | |
| 1104 | 1111 | } |
| 1105 | 1112 | |
| 1106 | 1113 | /* |
| @@ -529,7 +529,8 @@ static void data_xfer(struct work_struct *work) · 528 unmodified lines | ||
| 529 | 529 | /* dma_request_channel may sleep, so calling from process context */ |
| 530 | 530 | acdev->dma_chan = dma_request_chan(acdev->host->dev, "data"); |
| 531 | 531 | if (IS_ERR(acdev->dma_chan)) { |
| 532 | − dev_err(acdev->host->dev, "Unable to get dma_chan\n"); | |
| 532 | + dev_err_probe(acdev->host->dev, PTR_ERR(acdev->dma_chan), | |
| 533 | + "Unable to get dma_chan\n"); | |
| 533 | 534 | acdev->dma_chan = NULL; |
| 534 | 535 | goto chan_request_fail; |
| 535 | 536 | } |
| @@ -260,7 +260,7 @@ static u8 ns87560_check_status(struct ata_port *ap) · 259 unmodified lines | ||
| 260 | 260 | * LOCKING: |
| 261 | 261 | * Inherited from caller. |
| 262 | 262 | */ |
| 263 | −void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | |
| 263 | +static void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | |
| 264 | 264 | { |
| 265 | 265 | struct ata_ioports *ioaddr = &ap->ioaddr; |
| 266 | 266 | |
| @@ -815,8 +815,8 @@ static int octeon_cf_probe(struct platform_device *pdev) · 814 unmodified lines | ||
| 815 | 815 | irq_handler_t irq_handler = NULL; |
| 816 | 816 | void __iomem *base; |
| 817 | 817 | struct octeon_cf_port *cf_port; |
| 818 | − int rv = -ENOMEM; | |
| 819 | 818 | u32 bus_width; |
| 819 | + int rv; | |
| 820 | 820 | |
| 821 | 821 | node = pdev->dev.of_node; |
| 822 | 822 | if (node == NULL) |
| @@ -893,12 +893,12 @@ static int octeon_cf_probe(struct platform_device *pdev) · 70 unmodified lines | ||
| 893 | 893 | cs0 = devm_ioremap(&pdev->dev, res_cs0->start, |
| 894 | 894 | resource_size(res_cs0)); |
| 895 | 895 | if (!cs0) |
| 896 | − return rv; | |
| 896 | + return -ENOMEM; | |
| 897 | 897 | |
| 898 | 898 | /* allocate host */ |
| 899 | 899 | host = ata_host_alloc(&pdev->dev, 1); |
| 900 | 900 | if (!host) |
| 901 | − return rv; | |
| 901 | + return -ENOMEM; | |
| 902 | 902 | |
| 903 | 903 | ap = host->ports[0]; |
| 904 | 904 | ap->private_data = cf_port; |
| @@ -509,73 +509,30 @@ static void __init cpu_dev_register_generic(void) · 508 unmodified lines | ||
| 509 | 509 | } |
| 510 | 510 | |
| 511 | 511 | #ifdef CONFIG_GENERIC_CPU_VULNERABILITIES |
| 512 | − | |
| 513 | −ssize_t __weak cpu_show_meltdown(struct device *dev, | |
| 514 | − struct device_attribute *attr, char *buf) | |
| 515 | −{ | |
| 516 | − return sysfs_emit(buf, "Not affected\n"); | |
| 517 | −} | |
| 518 | − | |
| 519 | −ssize_t __weak cpu_show_spectre_v1(struct device *dev, | |
| 520 | − struct device_attribute *attr, char *buf) | |
| 521 | −{ | |
| 522 | − return sysfs_emit(buf, "Not affected\n"); | |
| 523 | −} | |
| 524 | − | |
| 525 | −ssize_t __weak cpu_show_spectre_v2(struct device *dev, | |
| 526 | − struct device_attribute *attr, char *buf) | |
| 527 | −{ | |
| 528 | − return sysfs_emit(buf, "Not affected\n"); | |
| 529 | −} | |
| 530 | − | |
| 531 | −ssize_t __weak cpu_show_spec_store_bypass(struct device *dev, | |
| 532 | − struct device_attribute *attr, char *buf) | |
| 533 | −{ | |
| 534 | − return sysfs_emit(buf, "Not affected\n"); | |
| 535 | −} | |
| 536 | − | |
| 537 | −ssize_t __weak cpu_show_l1tf(struct device *dev, | |
| 538 | − struct device_attribute *attr, char *buf) | |
| 539 | −{ | |
| 540 | − return sysfs_emit(buf, "Not affected\n"); | |
| 541 | −} | |
| 542 | − | |
| 543 | −ssize_t __weak cpu_show_mds(struct device *dev, | |
| 544 | − struct device_attribute *attr, char *buf) | |
| 545 | −{ | |
| 546 | − return sysfs_emit(buf, "Not affected\n"); | |
| 547 | −} | |
| 548 | − | |
| 549 | −ssize_t __weak cpu_show_tsx_async_abort(struct device *dev, | |
| 550 | − struct device_attribute *attr, | |
| 551 | − char *buf) | |
| 552 | −{ | |
| 553 | − return sysfs_emit(buf, "Not affected\n"); | |
| 554 | −} | |
| 555 | − | |
| 556 | −ssize_t __weak cpu_show_itlb_multihit(struct device *dev, | |
| 557 | − struct device_attribute *attr, char *buf) | |
| 558 | −{ | |
| 559 | − return sysfs_emit(buf, "Not affected\n"); | |
| 560 | −} | |
| 561 | − | |
| 562 | −ssize_t __weak cpu_show_srbds(struct device *dev, | |
| 512 | +static ssize_t cpu_show_not_affected(struct device *dev, | |
| 563 | 513 | struct device_attribute *attr, char *buf) |
| 564 | 514 | { |
| 565 | 515 | return sysfs_emit(buf, "Not affected\n"); |
| 566 | 516 | } |
| 567 | 517 | |
| 568 | −ssize_t __weak cpu_show_mmio_stale_data(struct device *dev, | |
| 569 | − struct device_attribute *attr, char *buf) | |
| 570 | −{ | |
| 571 | − return sysfs_emit(buf, "Not affected\n"); | |
| 572 | −} | |
| 573 | − | |
| 574 | −ssize_t __weak cpu_show_retbleed(struct device *dev, | |
| 575 | − struct device_attribute *attr, char *buf) | |
| 576 | −{ | |
| 577 | − return sysfs_emit(buf, "Not affected\n"); | |
| 578 | −} | |
| 518 | +#define CPU_SHOW_VULN_FALLBACK(func) \ | |
| 519 | + ssize_t cpu_show_##func(struct device *, \ | |
| 520 | + struct device_attribute *, char *) \ | |
| 521 | + __attribute__((weak, alias("cpu_show_not_affected"))) | |
| 522 | + | |
| 523 | +CPU_SHOW_VULN_FALLBACK(meltdown); | |
| 524 | +CPU_SHOW_VULN_FALLBACK(spectre_v1); | |
| 525 | +CPU_SHOW_VULN_FALLBACK(spectre_v2); | |
| 526 | +CPU_SHOW_VULN_FALLBACK(spec_store_bypass); | |
| 527 | +CPU_SHOW_VULN_FALLBACK(l1tf); | |
| 528 | +CPU_SHOW_VULN_FALLBACK(mds); | |
| 529 | +CPU_SHOW_VULN_FALLBACK(tsx_async_abort); | |
| 530 | +CPU_SHOW_VULN_FALLBACK(itlb_multihit); | |
| 531 | +CPU_SHOW_VULN_FALLBACK(srbds); | |
| 532 | +CPU_SHOW_VULN_FALLBACK(mmio_stale_data); | |
| 533 | +CPU_SHOW_VULN_FALLBACK(retbleed); | |
| 534 | +CPU_SHOW_VULN_FALLBACK(spec_rstack_overflow); | |
| 535 | +CPU_SHOW_VULN_FALLBACK(gds); | |
| 579 | 536 | |
| 580 | 537 | static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); |
| 581 | 538 | static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); |
| @@ -588,6 +545,8 @@ static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL); · 6 unmodified lines | ||
| 588 | 545 | static DEVICE_ATTR(srbds, 0444, cpu_show_srbds, NULL); |
| 589 | 546 | static DEVICE_ATTR(mmio_stale_data, 0444, cpu_show_mmio_stale_data, NULL); |
| 590 | 547 | static DEVICE_ATTR(retbleed, 0444, cpu_show_retbleed, NULL); |
| 548 | +static DEVICE_ATTR(spec_rstack_overflow, 0444, cpu_show_spec_rstack_overflow, NULL); | |
| 549 | +static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL); | |
| 591 | 550 | |
| 592 | 551 | static struct attribute *cpu_root_vulnerabilities_attrs[] = { |
| 593 | 552 | &dev_attr_meltdown.attr, |
| @@ -601,6 +560,8 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] = { · 7 unmodified lines | ||
| 601 | 560 | &dev_attr_srbds.attr, |
| 602 | 561 | &dev_attr_mmio_stale_data.attr, |
| 603 | 562 | &dev_attr_retbleed.attr, |
| 563 | + &dev_attr_spec_rstack_overflow.attr, | |
| 564 | + &dev_attr_gather_data_sampling.attr, | |
| 604 | 565 | NULL |
| 605 | 566 | }; |
| 606 | 567 | |
| @@ -29,6 +29,7 @@ extern u64 pm_runtime_active_time(struct device *dev); · 28 unmodified lines | ||
| 29 | 29 | #define WAKE_IRQ_DEDICATED_MASK (WAKE_IRQ_DEDICATED_ALLOCATED | \ |
| 30 | 30 | WAKE_IRQ_DEDICATED_MANAGED | \ |
| 31 | 31 | WAKE_IRQ_DEDICATED_REVERSE) |
| 32 | +#define WAKE_IRQ_DEDICATED_ENABLED BIT(3) | |
| 32 | 33 | |
| 33 | 34 | struct wake_irq { |
| 34 | 35 | struct device *dev; |
| @@ -194,7 +194,6 @@ err_free: · 193 unmodified lines | ||
| 194 | 194 | return err; |
| 195 | 195 | } |
| 196 | 196 | |
| 197 | − | |
| 198 | 197 | /** |
| 199 | 198 | * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt |
| 200 | 199 | * @dev: Device entry |
| @@ -206,11 +205,6 @@ err_free: · 5 unmodified lines | ||
| 206 | 205 | * Sets up a threaded interrupt handler for a device that has |
| 207 | 206 | * a dedicated wake-up interrupt in addition to the device IO |
| 208 | 207 | * interrupt. |
| 209 | − * | |
| 210 | − * The interrupt starts disabled, and needs to be managed for | |
| 211 | − * the device by the bus code or the device driver using | |
| 212 | − * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*() | |
| 213 | − * functions. | |
| 214 | 208 | */ |
| 215 | 209 | int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) |
| 216 | 210 | { |
| @@ -232,11 +226,6 @@ EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq); · 15 unmodified lines | ||
| 232 | 226 | * the status of WAKE_IRQ_DEDICATED_REVERSE to tell rpm_suspend() |
| 233 | 227 | * to enable dedicated wake-up interrupt after running the runtime suspend |
| 234 | 228 | * callback for @dev. |
| 235 | − * | |
| 236 | − * The interrupt starts disabled, and needs to be managed for | |
| 237 | − * the device by the bus code or the device driver using | |
| 238 | − * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*() | |
| 239 | − * functions. | |
| 240 | 229 | */ |
| 241 | 230 | int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq) |
| 242 | 231 | { |
| @@ -244,44 +233,6 @@ int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq) · 1 unmodified line | ||
| 244 | 233 | } |
| 245 | 234 | EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq_reverse); |
| 246 | 235 | |
| 247 | −/** | |
| 248 | − * dev_pm_enable_wake_irq - Enable device wake-up interrupt | |
| 249 | − * @dev: Device | |
| 250 | − * | |
| 251 | − * Optionally called from the bus code or the device driver for | |
| 252 | − * runtime_resume() to override the PM runtime core managed wake-up | |
| 253 | − * interrupt handling to enable the wake-up interrupt. | |
| 254 | − * | |
| 255 | − * Note that for runtime_suspend()) the wake-up interrupts | |
| 256 | − * should be unconditionally enabled unlike for suspend() | |
| 257 | − * that is conditional. | |
| 258 | − */ | |
| 259 | −void dev_pm_enable_wake_irq(struct device *dev) | |
| 260 | −{ | |
| 261 | − struct wake_irq *wirq = dev->power.wakeirq; | |
| 262 | − | |
| 263 | − if (wirq && (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED)) | |
| 264 | − enable_irq(wirq->irq); | |
| 265 | −} | |
| 266 | −EXPORT_SYMBOL_GPL(dev_pm_enable_wake_irq); | |
| 267 | − | |
| 268 | −/** | |
| 269 | − * dev_pm_disable_wake_irq - Disable device wake-up interrupt | |
| 270 | − * @dev: Device | |
| 271 | − * | |
| 272 | − * Optionally called from the bus code or the device driver for | |
| 273 | − * runtime_suspend() to override the PM runtime core managed wake-up | |
| 274 | − * interrupt handling to disable the wake-up interrupt. | |
| 275 | − */ | |
| 276 | −void dev_pm_disable_wake_irq(struct device *dev) | |
| 277 | −{ | |
| 278 | − struct wake_irq *wirq = dev->power.wakeirq; | |
| 279 | − | |
| 280 | − if (wirq && (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED)) | |
| 281 | − disable_irq_nosync(wirq->irq); | |
| 282 | −} | |
| 283 | −EXPORT_SYMBOL_GPL(dev_pm_disable_wake_irq); | |
| 284 | − | |
| 285 | 236 | /** |
| 286 | 237 | * dev_pm_enable_wake_irq_check - Checks and enables wake-up interrupt |
| 287 | 238 | * @dev: Device |
| @@ -314,8 +265,10 @@ void dev_pm_enable_wake_irq_check(struct device *dev, · 26 unmodified lines | ||
| 314 | 265 | return; |
| 315 | 266 | |
| 316 | 267 | enable: |
| 317 | − if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) | |
| 268 | + if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) { | |
| 318 | 269 | enable_irq(wirq->irq); |
| 270 | + wirq->status |= WAKE_IRQ_DEDICATED_ENABLED; | |
| 271 | + } | |
| 319 | 272 | } |
| 320 | 273 | |
| 321 | 274 | /** |
| @@ -336,8 +289,10 @@ void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable) · 14 unmodified lines | ||
| 336 | 289 | if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) |
| 337 | 290 | return; |
| 338 | 291 | |
| 339 | − if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) | |
| 292 | + if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) { | |
| 293 | + wirq->status &= ~WAKE_IRQ_DEDICATED_ENABLED; | |
| 340 | 294 | disable_irq_nosync(wirq->irq); |
| 295 | + } | |
| 341 | 296 | } |
| 342 | 297 | |
| 343 | 298 | /** |
| @@ -376,7 +331,7 @@ void dev_pm_arm_wake_irq(struct wake_irq *wirq) · 32 unmodified lines | ||
| 376 | 331 | |
| 377 | 332 | if (device_may_wakeup(wirq->dev)) { |
| 378 | 333 | if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED && |
| 379 | − !pm_runtime_status_suspended(wirq->dev)) | |
| 334 | + !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED)) | |
| 380 | 335 | enable_irq(wirq->irq); |
| 381 | 336 | |
| 382 | 337 | enable_irq_wake(wirq->irq); |
| @@ -399,7 +354,7 @@ void dev_pm_disarm_wake_irq(struct wake_irq *wirq) · 16 unmodified lines | ||
| 399 | 354 | disable_irq_wake(wirq->irq); |
| 400 | 355 | |
| 401 | 356 | if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED && |
| 402 | − !pm_runtime_status_suspended(wirq->dev)) | |
| 357 | + !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED)) | |
| 403 | 358 | disable_irq_nosync(wirq->irq); |
| 404 | 359 | } |
| 405 | 360 | } |
| @@ -3675,7 +3675,7 @@ static int rbd_lock(struct rbd_device *rbd_dev) · 3674 unmodified lines | ||
| 3675 | 3675 | ret = ceph_cls_lock(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, |
| 3676 | 3676 | RBD_LOCK_NAME, CEPH_CLS_LOCK_EXCLUSIVE, cookie, |
| 3677 | 3677 | RBD_LOCK_TAG, "", 0); |
| 3678 | − if (ret) | |
| 3678 | + if (ret && ret != -EEXIST) | |
| 3679 | 3679 | return ret; |
| 3680 | 3680 | |
| 3681 | 3681 | __rbd_lock(rbd_dev, cookie); |
| @@ -3849,51 +3849,82 @@ static void wake_lock_waiters(struct rbd_device *rbd_dev, int result) · 167 unmodified lines | ||
| 3849 | 3849 | list_splice_tail_init(&rbd_dev->acquiring_list, &rbd_dev->running_list); |
| 3850 | 3850 | } |
| 3851 | 3851 | |
| 3852 | −static int get_lock_owner_info(struct rbd_device *rbd_dev, | |
| 3853 | − struct ceph_locker **lockers, u32 *num_lockers) | |
| 3852 | +static bool locker_equal(const struct ceph_locker *lhs, | |
| 3853 | + const struct ceph_locker *rhs) | |
| 3854 | +{ | |
| 3855 | + return lhs->id.name.type == rhs->id.name.type && | |
| 3856 | + lhs->id.name.num == rhs->id.name.num && | |
| 3857 | + !strcmp(lhs->id.cookie, rhs->id.cookie) && | |
| 3858 | + ceph_addr_equal_no_type(&lhs->info.addr, &rhs->info.addr); | |
| 3859 | +} | |
| 3860 | + | |
| 3861 | +static void free_locker(struct ceph_locker *locker) | |
| 3862 | +{ | |
| 3863 | + if (locker) | |
| 3864 | + ceph_free_lockers(locker, 1); | |
| 3865 | +} | |
| 3866 | + | |
| 3867 | +static struct ceph_locker *get_lock_owner_info(struct rbd_device *rbd_dev) | |
| 3854 | 3868 | { |
| 3855 | 3869 | struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; |
| 3870 | + struct ceph_locker *lockers; | |
| 3871 | + u32 num_lockers; | |
| 3856 | 3872 | u8 lock_type; |
| 3857 | 3873 | char *lock_tag; |
| 3874 | + u64 handle; | |
| 3858 | 3875 | int ret; |
| 3859 | 3876 | |
| 3860 | − dout("%s rbd_dev %p\n", __func__, rbd_dev); | |
| 3861 | − | |
| 3862 | 3877 | ret = ceph_cls_lock_info(osdc, &rbd_dev->header_oid, |
| 3863 | 3878 | &rbd_dev->header_oloc, RBD_LOCK_NAME, |
| 3864 | − &lock_type, &lock_tag, lockers, num_lockers); | |
| 3865 | − if (ret) | |
| 3866 | − return ret; | |
| 3879 | + &lock_type, &lock_tag, &lockers, &num_lockers); | |
| 3880 | + if (ret) { | |
| 3881 | + rbd_warn(rbd_dev, "failed to get header lockers: %d", ret); | |
| 3882 | + return ERR_PTR(ret); | |
| 3883 | + } | |
| 3867 | 3884 | |
| 3868 | − if (*num_lockers == 0) { | |
| 3885 | + if (num_lockers == 0) { | |
| 3869 | 3886 | dout("%s rbd_dev %p no lockers detected\n", __func__, rbd_dev); |
| 3887 | + lockers = NULL; | |
| 3870 | 3888 | goto out; |
| 3871 | 3889 | } |
| 3872 | 3890 | |
| 3873 | 3891 | if (strcmp(lock_tag, RBD_LOCK_TAG)) { |
| 3874 | 3892 | rbd_warn(rbd_dev, "locked by external mechanism, tag %s", |
| 3875 | 3893 | lock_tag); |
| 3876 | − ret = -EBUSY; | |
| 3877 | − goto out; | |
| 3894 | + goto err_busy; | |
| 3878 | 3895 | } |
| 3879 | 3896 | |
| 3880 | − if (lock_type == CEPH_CLS_LOCK_SHARED) { | |
| 3881 | − rbd_warn(rbd_dev, "shared lock type detected"); | |
| 3882 | − ret = -EBUSY; | |
| 3883 | − goto out; | |
| 3897 | + if (lock_type != CEPH_CLS_LOCK_EXCLUSIVE) { | |
| 3898 | + rbd_warn(rbd_dev, "incompatible lock type detected"); | |
| 3899 | + goto err_busy; | |
| 3884 | 3900 | } |
| 3885 | 3901 | |
| 3886 | − if (strncmp((*lockers)[0].id.cookie, RBD_LOCK_COOKIE_PREFIX, | |
| 3887 | − strlen(RBD_LOCK_COOKIE_PREFIX))) { | |
| 3902 | + WARN_ON(num_lockers != 1); | |
| 3903 | + ret = sscanf(lockers[0].id.cookie, RBD_LOCK_COOKIE_PREFIX " %llu", | |
| 3904 | + &handle); | |
| 3905 | + if (ret != 1) { | |
| 3888 | 3906 | rbd_warn(rbd_dev, "locked by external mechanism, cookie %s", |
| 3889 | − (*lockers)[0].id.cookie); | |
| 3890 | − ret = -EBUSY; | |
| 3891 | − goto out; | |
| 3907 | + lockers[0].id.cookie); | |
| 3908 | + goto err_busy; | |
| 3909 | + } | |
| 3910 | + if (ceph_addr_is_blank(&lockers[0].info.addr)) { | |
| 3911 | + rbd_warn(rbd_dev, "locker has a blank address"); | |
| 3912 | + goto err_busy; | |
| 3892 | 3913 | } |
| 3893 | 3914 | |
| 3915 | + dout("%s rbd_dev %p got locker %s%llu@%pISpc/%u handle %llu\n", | |
| 3916 | + __func__, rbd_dev, ENTITY_NAME(lockers[0].id.name), | |
| 3917 | + &lockers[0].info.addr.in_addr, | |
| 3918 | + le32_to_cpu(lockers[0].info.addr.nonce), handle); | |
| 3919 | + | |
| 3894 | 3920 | out: |
| 3895 | 3921 | kfree(lock_tag); |
| 3896 | − return ret; | |
| 3922 | + return lockers; | |
| 3923 | + | |
| 3924 | +err_busy: | |
| 3925 | + kfree(lock_tag); | |
| 3926 | + ceph_free_lockers(lockers, num_lockers); | |
| 3927 | + return ERR_PTR(-EBUSY); | |
| 3897 | 3928 | } |
| 3898 | 3929 | |
| 3899 | 3930 | static int find_watcher(struct rbd_device *rbd_dev, |
| @@ -3909,8 +3940,10 @@ static int find_watcher(struct rbd_device *rbd_dev, · 9 unmodified lines | ||
| 3909 | 3940 | ret = ceph_osdc_list_watchers(osdc, &rbd_dev->header_oid, |
| 3910 | 3941 | &rbd_dev->header_oloc, &watchers, |
| 3911 | 3942 | &num_watchers); |
| 3912 | − if (ret) | |
| 3943 | + if (ret) { | |
| 3944 | + rbd_warn(rbd_dev, "failed to get watchers: %d", ret); | |
| 3913 | 3945 | return ret; |
| 3946 | + } | |
| 3914 | 3947 | |
| 3915 | 3948 | sscanf(locker->id.cookie, RBD_LOCK_COOKIE_PREFIX " %llu", &cookie); |
| 3916 | 3949 | for (i = 0; i < num_watchers; i++) { |
| @@ -3947,51 +3980,72 @@ out: · 30 unmodified lines | ||
| 3947 | 3980 | static int rbd_try_lock(struct rbd_device *rbd_dev) |
| 3948 | 3981 | { |
| 3949 | 3982 | struct ceph_client *client = rbd_dev->rbd_client->client; |
| 3950 | − struct ceph_locker *lockers; | |
| 3951 | − u32 num_lockers; | |
| 3983 | + struct ceph_locker *locker, *refreshed_locker; | |
| 3952 | 3984 | int ret; |
| 3953 | 3985 | |
| 3954 | 3986 | for (;;) { |
| 3987 | + locker = refreshed_locker = NULL; | |
| 3988 | + | |
| 3955 | 3989 | ret = rbd_lock(rbd_dev); |
| 3956 | − if (ret != -EBUSY) | |
| 3957 | − return ret; | |
| 3990 | + if (!ret) | |
| 3991 | + goto out; | |
| 3992 | + if (ret != -EBUSY) { | |
| 3993 | + rbd_warn(rbd_dev, "failed to lock header: %d", ret); | |
| 3994 | + goto out; | |
| 3995 | + } | |
| 3958 | 3996 | |
| 3959 | 3997 | /* determine if the current lock holder is still alive */ |
| 3960 | − ret = get_lock_owner_info(rbd_dev, &lockers, &num_lockers); | |
| 3961 | − if (ret) | |
| 3962 | − return ret; | |
| 3963 | − | |
| 3964 | − if (num_lockers == 0) | |
| 3998 | + locker = get_lock_owner_info(rbd_dev); | |
| 3999 | + if (IS_ERR(locker)) { | |
| 4000 | + ret = PTR_ERR(locker); | |
| 4001 | + locker = NULL; | |
| 4002 | + goto out; | |
| 4003 | + } | |
| 4004 | + if (!locker) | |
| 3965 | 4005 | goto again; |
| 3966 | 4006 | |
| 3967 | − ret = find_watcher(rbd_dev, lockers); | |
| 4007 | + ret = find_watcher(rbd_dev, locker); | |
| 3968 | 4008 | if (ret) |
| 3969 | 4009 | goto out; /* request lock or error */ |
| 3970 | 4010 | |
| 4011 | + refreshed_locker = get_lock_owner_info(rbd_dev); | |
| 4012 | + if (IS_ERR(refreshed_locker)) { | |
| 4013 | + ret = PTR_ERR(refreshed_locker); | |
| 4014 | + refreshed_locker = NULL; | |
| 4015 | + goto out; | |
| 4016 | + } | |
| 4017 | + if (!refreshed_locker || | |
| 4018 | + !locker_equal(locker, refreshed_locker)) | |
| 4019 | + goto again; | |
| 4020 | + | |
| 3971 | 4021 | rbd_warn(rbd_dev, "breaking header lock owned by %s%llu", |
| 3972 | − ENTITY_NAME(lockers[0].id.name)); | |
| 4022 | + ENTITY_NAME(locker->id.name)); | |
| 3973 | 4023 | |
| 3974 | 4024 | ret = ceph_monc_blocklist_add(&client->monc, |
| 3975 | − &lockers[0].info.addr); | |
| 4025 | + &locker->info.addr); | |
| 3976 | 4026 | if (ret) { |
| 3977 | − rbd_warn(rbd_dev, "blocklist of %s%llu failed: %d", | |
| 3978 | − ENTITY_NAME(lockers[0].id.name), ret); | |
| 4027 | + rbd_warn(rbd_dev, "failed to blocklist %s%llu: %d", | |
| 4028 | + ENTITY_NAME(locker->id.name), ret); | |
| 3979 | 4029 | goto out; |
| 3980 | 4030 | } |
| 3981 | 4031 | |
| 3982 | 4032 | ret = ceph_cls_break_lock(&client->osdc, &rbd_dev->header_oid, |
| 3983 | 4033 | &rbd_dev->header_oloc, RBD_LOCK_NAME, |
| 3984 | − lockers[0].id.cookie, | |
| 3985 | − &lockers[0].id.name); | |
| 3986 | − if (ret && ret != -ENOENT) | |
| 4034 | + locker->id.cookie, &locker->id.name); | |
| 4035 | + if (ret && ret != -ENOENT) { | |
| 4036 | + rbd_warn(rbd_dev, "failed to break header lock: %d", | |
| 4037 | + ret); | |
| 3987 | 4038 | goto out; |
| 4039 | + } | |
| 3988 | 4040 | |
| 3989 | 4041 | again: |
| 3990 | − ceph_free_lockers(lockers, num_lockers); | |
| 4042 | + free_locker(refreshed_locker); | |
| 4043 | + free_locker(locker); | |
| 3991 | 4044 | } |
| 3992 | 4045 | |
| 3993 | 4046 | out: |
| 3994 | − ceph_free_lockers(lockers, num_lockers); | |
| 4047 | + free_locker(refreshed_locker); | |
| 4048 | + free_locker(locker); | |
| 3995 | 4049 | return ret; |
| 3996 | 4050 | } |
| 3997 | 4051 | |
| @@ -4041,11 +4095,8 @@ static int rbd_try_acquire_lock(struct rbd_device *rbd_dev) · 43 unmodified lines | ||
| 4041 | 4095 | |
| 4042 | 4096 | ret = rbd_try_lock(rbd_dev); |
| 4043 | 4097 | if (ret < 0) { |
| 4044 | − rbd_warn(rbd_dev, "failed to lock header: %d", ret); | |
| 4045 | − if (ret == -EBLOCKLISTED) | |
| 4046 | − goto out; | |
| 4047 | − | |
| 4048 | − ret = 1; /* request lock anyway */ | |
| 4098 | + rbd_warn(rbd_dev, "failed to acquire lock: %d", ret); | |
| 4099 | + goto out; | |
| 4049 | 4100 | } |
| 4050 | 4101 | if (ret > 0) { |
| 4051 | 4102 | up_write(&rbd_dev->lock_rwsem); |
| @@ -6579,12 +6630,11 @@ static int rbd_add_acquire_lock(struct rbd_device *rbd_dev) · 2527 unmodified lines | ||
| 6579 | 6630 | cancel_delayed_work_sync(&rbd_dev->lock_dwork); |
| 6580 | 6631 | if (!ret) |
| 6581 | 6632 | ret = -ETIMEDOUT; |
| 6582 | − } | |
| 6583 | 6633 | |
| 6584 | − if (ret) { | |
| 6585 | − rbd_warn(rbd_dev, "failed to acquire exclusive lock: %ld", ret); | |
| 6586 | − return ret; | |
| 6634 | + rbd_warn(rbd_dev, "failed to acquire lock: %ld", ret); | |
| 6587 | 6635 | } |
| 6636 | + if (ret) | |
| 6637 | + return ret; | |
| 6588 | 6638 | |
| 6589 | 6639 | /* |
| 6590 | 6640 | * The lock may have been released by now, unless automatic lock |
| @@ -1847,7 +1847,8 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd) · 1846 unmodified lines | ||
| 1847 | 1847 | if (ublksrv_pid <= 0) |
| 1848 | 1848 | return -EINVAL; |
| 1849 | 1849 | |
| 1850 | − wait_for_completion_interruptible(&ub->completion); | |
| 1850 | + if (wait_for_completion_interruptible(&ub->completion) != 0) | |
| 1851 | + return -EINTR; | |
| 1851 | 1852 | |
| 1852 | 1853 | schedule_delayed_work(&ub->monitor_work, UBLK_DAEMON_MONITOR_PERIOD); |
| 1853 | 1854 | |
| @@ -2125,8 +2126,8 @@ static int ublk_ctrl_del_dev(struct ublk_device **p_ub) · 271 unmodified lines | ||
| 2125 | 2126 | * - the device number is freed already, we will not find this |
| 2126 | 2127 | * device via ublk_get_device_from_id() |
| 2127 | 2128 | */ |
| 2128 | − wait_event_interruptible(ublk_idr_wq, ublk_idr_freed(idx)); | |
| 2129 | − | |
| 2129 | + if (wait_event_interruptible(ublk_idr_wq, ublk_idr_freed(idx))) | |
| 2130 | + return -EINTR; | |
| 2130 | 2131 | return 0; |
| 2131 | 2132 | } |
| 2132 | 2133 | |
| @@ -2323,7 +2324,9 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub, · 190 unmodified lines | ||
| 2323 | 2324 | pr_devel("%s: Waiting for new ubq_daemons(nr: %d) are ready, dev id %d...\n", |
| 2324 | 2325 | __func__, ub->dev_info.nr_hw_queues, header->dev_id); |
| 2325 | 2326 | /* wait until new ubq_daemon sending all FETCH_REQ */ |
| 2326 | − wait_for_completion_interruptible(&ub->completion); | |
| 2327 | + if (wait_for_completion_interruptible(&ub->completion)) | |
| 2328 | + return -EINTR; | |
| 2329 | + | |
| 2327 | 2330 | pr_devel("%s: All new ubq_daemons(nr: %d) are ready, dev id %d\n", |
| 2328 | 2331 | __func__, ub->dev_info.nr_hw_queues, header->dev_id); |
| 2329 | 2332 | |
| @@ -1870,15 +1870,16 @@ static void zram_bio_discard(struct zram *zram, struct bio *bio) · 1869 unmodified lines | ||
| 1870 | 1870 | |
| 1871 | 1871 | static void zram_bio_read(struct zram *zram, struct bio *bio) |
| 1872 | 1872 | { |
| 1873 | − struct bvec_iter iter; | |
| 1874 | − struct bio_vec bv; | |
| 1875 | − unsigned long start_time; | |
| 1873 | + unsigned long start_time = bio_start_io_acct(bio); | |
| 1874 | + struct bvec_iter iter = bio->bi_iter; | |
| 1876 | 1875 | |
| 1877 | − start_time = bio_start_io_acct(bio); | |
| 1878 | − bio_for_each_segment(bv, bio, iter) { | |
| 1876 | + do { | |
| 1879 | 1877 | u32 index = iter.bi_sector >> SECTORS_PER_PAGE_SHIFT; |
| 1880 | 1878 | u32 offset = (iter.bi_sector & (SECTORS_PER_PAGE - 1)) << |
| 1881 | 1879 | SECTOR_SHIFT; |
| 1880 | + struct bio_vec bv = bio_iter_iovec(bio, iter); | |
| 1881 | + | |
| 1882 | + bv.bv_len = min_t(u32, bv.bv_len, PAGE_SIZE - offset); | |
| 1882 | 1883 | |
| 1883 | 1884 | if (zram_bvec_read(zram, &bv, index, offset, bio) < 0) { |
| 1884 | 1885 | atomic64_inc(&zram->stats.failed_reads); |
| @@ -1890,22 +1891,26 @@ static void zram_bio_read(struct zram *zram, struct bio *bio) · 5 unmodified lines | ||
| 1890 | 1891 | zram_slot_lock(zram, index); |
| 1891 | 1892 | zram_accessed(zram, index); |
| 1892 | 1893 | zram_slot_unlock(zram, index); |
| 1893 | − } | |
| 1894 | + | |
| 1895 | + bio_advance_iter_single(bio, &iter, bv.bv_len); | |
| 1896 | + } while (iter.bi_size); | |
| 1897 | + | |
| 1894 | 1898 | bio_end_io_acct(bio, start_time); |
| 1895 | 1899 | bio_endio(bio); |
| 1896 | 1900 | } |
| 1897 | 1901 | |
| 1898 | 1902 | static void zram_bio_write(struct zram *zram, struct bio *bio) |
| 1899 | 1903 | { |
| 1900 | − struct bvec_iter iter; | |
| 1901 | − struct bio_vec bv; | |
| 1902 | − unsigned long start_time; | |
| 1904 | + unsigned long start_time = bio_start_io_acct(bio); | |
| 1905 | + struct bvec_iter iter = bio->bi_iter; | |
| 1903 | 1906 | |
| 1904 | − start_time = bio_start_io_acct(bio); | |
| 1905 | − bio_for_each_segment(bv, bio, iter) { | |
| 1907 | + do { | |
| 1906 | 1908 | u32 index = iter.bi_sector >> SECTORS_PER_PAGE_SHIFT; |
| 1907 | 1909 | u32 offset = (iter.bi_sector & (SECTORS_PER_PAGE - 1)) << |
| 1908 | 1910 | SECTOR_SHIFT; |
| 1911 | + struct bio_vec bv = bio_iter_iovec(bio, iter); | |
| 1912 | + | |
| 1913 | + bv.bv_len = min_t(u32, bv.bv_len, PAGE_SIZE - offset); | |
| 1909 | 1914 | |
| 1910 | 1915 | if (zram_bvec_write(zram, &bv, index, offset, bio) < 0) { |
| 1911 | 1916 | atomic64_inc(&zram->stats.failed_writes); |
| @@ -1916,7 +1921,10 @@ static void zram_bio_write(struct zram *zram, struct bio *bio) · 4 unmodified lines | ||
| 1916 | 1921 | zram_slot_lock(zram, index); |
| 1917 | 1922 | zram_accessed(zram, index); |
| 1918 | 1923 | zram_slot_unlock(zram, index); |
| 1919 | − } | |
| 1924 | + | |
| 1925 | + bio_advance_iter_single(bio, &iter, bv.bv_len); | |
| 1926 | + } while (iter.bi_size); | |
| 1927 | + | |
| 1920 | 1928 | bio_end_io_acct(bio, start_time); |
| 1921 | 1929 | bio_endio(bio); |
| 1922 | 1930 | } |
| @@ -160,7 +160,7 @@ static struct i2c_driver st33zp24_i2c_driver = { · 159 unmodified lines | ||
| 160 | 160 | .of_match_table = of_match_ptr(of_st33zp24_i2c_match), |
| 161 | 161 | .acpi_match_table = ACPI_PTR(st33zp24_i2c_acpi_match), |
| 162 | 162 | }, |
| 163 | − .probe_new = st33zp24_i2c_probe, | |
| 163 | + .probe = st33zp24_i2c_probe, | |
| 164 | 164 | .remove = st33zp24_i2c_remove, |
| 165 | 165 | .id_table = st33zp24_i2c_id |
| 166 | 166 | }; |
| @@ -510,70 +510,6 @@ static int tpm_add_legacy_sysfs(struct tpm_chip *chip) · 509 unmodified lines | ||
| 510 | 510 | return 0; |
| 511 | 511 | } |
| 512 | 512 | |
| 513 | −/* | |
| 514 | − * Some AMD fTPM versions may cause stutter | |
| 515 | − * https://www.amd.com/en/support/kb/faq/pa-410 | |
| 516 | − * | |
| 517 | − * Fixes are available in two series of fTPM firmware: | |
| 518 | − * 6.x.y.z series: 6.0.18.6 + | |
| 519 | − * 3.x.y.z series: 3.57.y.5 + | |
| 520 | − */ | |
| 521 | −#ifdef CONFIG_X86 | |
| 522 | −static bool tpm_amd_is_rng_defective(struct tpm_chip *chip) | |
| 523 | −{ | |
| 524 | − u32 val1, val2; | |
| 525 | − u64 version; | |
| 526 | − int ret; | |
| 527 | − | |
| 528 | − if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) | |
| 529 | − return false; | |
| 530 | − | |
| 531 | − ret = tpm_request_locality(chip); | |
| 532 | − if (ret) | |
| 533 | − return false; | |
| 534 | − | |
| 535 | − ret = tpm2_get_tpm_pt(chip, TPM2_PT_MANUFACTURER, &val1, NULL); | |
| 536 | − if (ret) | |
| 537 | − goto release; | |
| 538 | − if (val1 != 0x414D4400U /* AMD */) { | |
| 539 | − ret = -ENODEV; | |
| 540 | − goto release; | |
| 541 | − } | |
| 542 | − ret = tpm2_get_tpm_pt(chip, TPM2_PT_FIRMWARE_VERSION_1, &val1, NULL); | |
| 543 | − if (ret) | |
| 544 | − goto release; | |
| 545 | − ret = tpm2_get_tpm_pt(chip, TPM2_PT_FIRMWARE_VERSION_2, &val2, NULL); | |
| 546 | − | |
| 547 | −release: | |
| 548 | − tpm_relinquish_locality(chip); | |
| 549 | − | |
| 550 | − if (ret) | |
| 551 | − return false; | |
| 552 | − | |
| 553 | − version = ((u64)val1 << 32) | val2; | |
| 554 | − if ((version >> 48) == 6) { | |
| 555 | − if (version >= 0x0006000000180006ULL) | |
| 556 | − return false; | |
| 557 | − } else if ((version >> 48) == 3) { | |
| 558 | − if (version >= 0x0003005700000005ULL) | |
| 559 | − return false; | |
| 560 | − } else { | |
| 561 | − return false; | |
| 562 | − } | |
| 563 | − | |
| 564 | − dev_warn(&chip->dev, | |
| 565 | − "AMD fTPM version 0x%llx causes system stutter; hwrng disabled\n", | |
| 566 | − version); | |
| 567 | − | |
| 568 | − return true; | |
| 569 | −} | |
| 570 | −#else | |
| 571 | −static inline bool tpm_amd_is_rng_defective(struct tpm_chip *chip) | |
| 572 | −{ | |
| 573 | − return false; | |
| 574 | −} | |
| 575 | −#endif /* CONFIG_X86 */ | |
| 576 | − | |
| 577 | 513 | static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait) |
| 578 | 514 | { |
| 579 | 515 | struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng); |
| @@ -585,10 +521,20 @@ static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait) · 5 unmodified lines | ||
| 585 | 521 | return tpm_get_random(chip, data, max); |
| 586 | 522 | } |
| 587 | 523 | |
| 524 | +static bool tpm_is_hwrng_enabled(struct tpm_chip *chip) | |
| 525 | +{ | |
| 526 | + if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM)) | |
| 527 | + return false; | |
| 528 | + if (tpm_is_firmware_upgrade(chip)) | |
| 529 | + return false; | |
| 530 | + if (chip->flags & TPM_CHIP_FLAG_HWRNG_DISABLED) | |
| 531 | + return false; | |
| 532 | + return true; | |
| 533 | +} | |
| 534 | + | |
| 588 | 535 | static int tpm_add_hwrng(struct tpm_chip *chip) |
| 589 | 536 | { |
| 590 | − if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM) || tpm_is_firmware_upgrade(chip) || | |
| 591 | − tpm_amd_is_rng_defective(chip)) | |
| 537 | + if (!tpm_is_hwrng_enabled(chip)) | |
| 592 | 538 | return 0; |
| 593 | 539 | |
| 594 | 540 | snprintf(chip->hwrng_name, sizeof(chip->hwrng_name), |
| @@ -693,7 +639,7 @@ int tpm_chip_register(struct tpm_chip *chip) · 98 unmodified lines | ||
| 693 | 639 | return 0; |
| 694 | 640 | |
| 695 | 641 | out_hwrng: |
| 696 | − if (IS_ENABLED(CONFIG_HW_RANDOM_TPM) && !tpm_is_firmware_upgrade(chip)) | |
| 642 | + if (tpm_is_hwrng_enabled(chip)) | |
| 697 | 643 | hwrng_unregister(&chip->hwrng); |
| 698 | 644 | out_ppi: |
| 699 | 645 | tpm_bios_log_teardown(chip); |
| @@ -718,8 +664,7 @@ EXPORT_SYMBOL_GPL(tpm_chip_register); · 18 unmodified lines | ||
| 718 | 664 | void tpm_chip_unregister(struct tpm_chip *chip) |
| 719 | 665 | { |
| 720 | 666 | tpm_del_legacy_sysfs(chip); |
| 721 | − if (IS_ENABLED(CONFIG_HW_RANDOM_TPM) && !tpm_is_firmware_upgrade(chip) && | |
| 722 | − !tpm_amd_is_rng_defective(chip)) | |
| 667 | + if (tpm_is_hwrng_enabled(chip)) | |
| 723 | 668 | hwrng_unregister(&chip->hwrng); |
| 724 | 669 | tpm_bios_log_teardown(chip); |
| 725 | 670 | if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip)) |
| @@ -463,6 +463,28 @@ static bool crb_req_canceled(struct tpm_chip *chip, u8 status) · 462 unmodified lines | ||
| 463 | 463 | return (cancel & CRB_CANCEL_INVOKE) == CRB_CANCEL_INVOKE; |
| 464 | 464 | } |
| 465 | 465 | |
| 466 | +static int crb_check_flags(struct tpm_chip *chip) | |
| 467 | +{ | |
| 468 | + u32 val; | |
| 469 | + int ret; | |
| 470 | + | |
| 471 | + ret = crb_request_locality(chip, 0); | |
| 472 | + if (ret) | |
| 473 | + return ret; | |
| 474 | + | |
| 475 | + ret = tpm2_get_tpm_pt(chip, TPM2_PT_MANUFACTURER, &val, NULL); | |
| 476 | + if (ret) | |
| 477 | + goto release; | |
| 478 | + | |
| 479 | + if (val == 0x414D4400U /* AMD */) | |
| 480 | + chip->flags |= TPM_CHIP_FLAG_HWRNG_DISABLED; | |
| 481 | + | |
| 482 | +release: | |
| 483 | + crb_relinquish_locality(chip, 0); | |
| 484 | + | |
| 485 | + return ret; | |
| 486 | +} | |
| 487 | + | |
| 466 | 488 | static const struct tpm_class_ops tpm_crb = { |
| 467 | 489 | .flags = TPM_OPS_AUTO_STARTUP, |
| 468 | 490 | .status = crb_status, |
| @@ -800,6 +822,14 @@ static int crb_acpi_add(struct acpi_device *device) · 331 unmodified lines | ||
| 800 | 822 | chip->acpi_dev_handle = device->handle; |
| 801 | 823 | chip->flags = TPM_CHIP_FLAG_TPM2; |
| 802 | 824 | |
| 825 | + rc = tpm_chip_bootstrap(chip); | |
| 826 | + if (rc) | |
| 827 | + goto out; | |
| 828 | + | |
| 829 | + rc = crb_check_flags(chip); | |
| 830 | + if (rc) | |
| 831 | + goto out; | |
| 832 | + | |
| 803 | 833 | rc = tpm_chip_register(chip); |
| 804 | 834 | |
| 805 | 835 | out: |
| @@ -203,7 +203,7 @@ static SIMPLE_DEV_PM_OPS(i2c_atmel_pm_ops, tpm_pm_suspend, tpm_pm_resume); · 202 unmodified lines | ||
| 203 | 203 | |
| 204 | 204 | static struct i2c_driver i2c_atmel_driver = { |
| 205 | 205 | .id_table = i2c_atmel_id, |
| 206 | − .probe_new = i2c_atmel_probe, | |
| 206 | + .probe = i2c_atmel_probe, | |
| 207 | 207 | .remove = i2c_atmel_remove, |
| 208 | 208 | .driver = { |
| 209 | 209 | .name = I2C_DRIVER_NAME, |
| @@ -716,7 +716,7 @@ static void tpm_tis_i2c_remove(struct i2c_client *client) · 715 unmodified lines | ||
| 716 | 716 | |
| 717 | 717 | static struct i2c_driver tpm_tis_i2c_driver = { |
| 718 | 718 | .id_table = tpm_tis_i2c_table, |
| 719 | − .probe_new = tpm_tis_i2c_probe, | |
| 719 | + .probe = tpm_tis_i2c_probe, | |
| 720 | 720 | .remove = tpm_tis_i2c_remove, |
| 721 | 721 | .driver = { |
| 722 | 722 | .name = "tpm_i2c_infineon", |
| @@ -650,7 +650,7 @@ static SIMPLE_DEV_PM_OPS(i2c_nuvoton_pm_ops, tpm_pm_suspend, tpm_pm_resume); · 649 unmodified lines | ||
| 650 | 650 | |
| 651 | 651 | static struct i2c_driver i2c_nuvoton_driver = { |
| 652 | 652 | .id_table = i2c_nuvoton_id, |
| 653 | − .probe_new = i2c_nuvoton_probe, | |
| 653 | + .probe = i2c_nuvoton_probe, | |
| 654 | 654 | .remove = i2c_nuvoton_remove, |
| 655 | 655 | .driver = { |
| 656 | 656 | .name = "tpm_i2c_nuvoton", |
| @@ -89,7 +89,7 @@ static inline void tpm_tis_iowrite32(u32 b, void __iomem *iobase, u32 addr) · 88 unmodified lines | ||
| 89 | 89 | tpm_tis_flush(iobase); |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | −static int interrupts = -1; | |
| 92 | +static int interrupts; | |
| 93 | 93 | module_param(interrupts, int, 0444); |
| 94 | 94 | MODULE_PARM_DESC(interrupts, "Enable interrupts"); |
| 95 | 95 | |
| @@ -162,12 +162,28 @@ static const struct dmi_system_id tpm_tis_dmi_table[] = { · 66 unmodified lines | ||
| 162 | 162 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L590"), |
| 163 | 163 | }, |
| 164 | 164 | }, |
| 165 | + { | |
| 166 | + .callback = tpm_tis_disable_irq, | |
| 167 | + .ident = "ThinkStation P620", | |
| 168 | + .matches = { | |
| 169 | + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | |
| 170 | + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkStation P620"), | |
| 171 | + }, | |
| 172 | + }, | |
| 173 | + { | |
| 174 | + .callback = tpm_tis_disable_irq, | |
| 175 | + .ident = "TUXEDO InfinityBook S 15/17 Gen7", | |
| 176 | + .matches = { | |
| 177 | + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), | |
| 178 | + DMI_MATCH(DMI_PRODUCT_NAME, "TUXEDO InfinityBook S 15/17 Gen7"), | |
| 179 | + }, | |
| 180 | + }, | |
| 165 | 181 | { |
| 166 | 182 | .callback = tpm_tis_disable_irq, |
| 167 | 183 | .ident = "UPX-TGL", |
| 168 | 184 | .matches = { |
| 169 | 185 | DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), |
| 170 | − DMI_MATCH(DMI_PRODUCT_VERSION, "UPX-TGL"), | |
| 186 | + DMI_MATCH(DMI_PRODUCT_NAME, "UPX-TGL01"), | |
| 171 | 187 | }, |
| 172 | 188 | }, |
| 173 | 189 | {} |
| @@ -366,8 +366,13 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) · 365 unmodified lines | ||
| 366 | 366 | goto out; |
| 367 | 367 | } |
| 368 | 368 | |
| 369 | − size += recv_data(chip, &buf[TPM_HEADER_SIZE], | |
| 370 | − expected - TPM_HEADER_SIZE); | |
| 369 | + rc = recv_data(chip, &buf[TPM_HEADER_SIZE], | |
| 370 | + expected - TPM_HEADER_SIZE); | |
| 371 | + if (rc < 0) { | |
| 372 | + size = rc; | |
| 373 | + goto out; | |
| 374 | + } | |
| 375 | + size += rc; | |
| 371 | 376 | if (size < expected) { |
| 372 | 377 | dev_err(&chip->dev, "Unable to read remainder of result\n"); |
| 373 | 378 | size = -ETIME; |
| @@ -394,7 +394,7 @@ static struct i2c_driver tpm_tis_i2c_driver = { · 393 unmodified lines | ||
| 394 | 394 | .pm = &tpm_tis_pm, |
| 395 | 395 | .of_match_table = of_match_ptr(of_tis_i2c_match), |
| 396 | 396 | }, |
| 397 | − .probe_new = tpm_tis_i2c_probe, | |
| 397 | + .probe = tpm_tis_i2c_probe, | |
| 398 | 398 | .remove = tpm_tis_i2c_remove, |
| 399 | 399 | .id_table = tpm_tis_i2c_id, |
| 400 | 400 | }; |
| @@ -779,7 +779,7 @@ static void tpm_cr50_i2c_remove(struct i2c_client *client) · 778 unmodified lines | ||
| 779 | 779 | static SIMPLE_DEV_PM_OPS(cr50_i2c_pm, tpm_pm_suspend, tpm_pm_resume); |
| 780 | 780 | |
| 781 | 781 | static struct i2c_driver cr50_i2c_driver = { |
| 782 | − .probe_new = tpm_cr50_i2c_probe, | |
| 782 | + .probe = tpm_cr50_i2c_probe, | |
| 783 | 783 | .remove = tpm_cr50_i2c_remove, |
| 784 | 784 | .driver = { |
| 785 | 785 | .name = "cr50_i2c", |
| @@ -444,6 +444,7 @@ config COMMON_CLK_BD718XX · 443 unmodified lines | ||
| 444 | 444 | config COMMON_CLK_FIXED_MMIO |
| 445 | 445 | bool "Clock driver for Memory Mapped Fixed values" |
| 446 | 446 | depends on COMMON_CLK && OF |
| 447 | + depends on HAS_IOMEM | |
| 447 | 448 | help |
| 448 | 449 | Support for Memory Mapped IO Fixed clocks |
| 449 | 450 | |
| @@ -291,7 +291,7 @@ static int imx93_clocks_probe(struct platform_device *pdev) · 290 unmodified lines | ||
| 291 | 291 | anatop_base = devm_of_iomap(dev, np, 0, NULL); |
| 292 | 292 | of_node_put(np); |
| 293 | 293 | if (WARN_ON(IS_ERR(anatop_base))) { |
| 294 | − ret = PTR_ERR(base); | |
| 294 | + ret = PTR_ERR(anatop_base); | |
| 295 | 295 | goto unregister_hws; |
| 296 | 296 | } |
| 297 | 297 | |
| @@ -328,6 +328,14 @@ static const char * const atb_parents[] = { · 327 unmodified lines | ||
| 328 | 328 | "syspll_d5" |
| 329 | 329 | }; |
| 330 | 330 | |
| 331 | +static const char * const sspm_parents[] = { | |
| 332 | + "clk26m", | |
| 333 | + "univpll_d2_d4", | |
| 334 | + "syspll_d2_d2", | |
| 335 | + "univpll_d2_d2", | |
| 336 | + "syspll_d3" | |
| 337 | +}; | |
| 338 | + | |
| 331 | 339 | static const char * const dpi0_parents[] = { |
| 332 | 340 | "clk26m", |
| 333 | 341 | "tvdpll_d2", |
| @@ -507,6 +515,9 @@ static const struct mtk_mux top_muxes[] = { · 173 unmodified lines | ||
| 507 | 515 | /* CLK_CFG_6 */ |
| 508 | 516 | MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_ATB, "atb_sel", |
| 509 | 517 | atb_parents, 0xa0, 0xa4, 0xa8, 0, 2, 7, 0x004, 24), |
| 518 | + MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_MUX_SSPM, "sspm_sel", | |
| 519 | + sspm_parents, 0xa0, 0xa4, 0xa8, 8, 3, 15, 0x004, 25, | |
| 520 | + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT), | |
| 510 | 521 | MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_DPI0, "dpi0_sel", |
| 511 | 522 | dpi0_parents, 0xa0, 0xa4, 0xa8, 16, 4, 23, 0x004, 26), |
| 512 | 523 | MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_SCAM, "scam_sel", |
| @@ -673,10 +684,18 @@ static const struct mtk_gate_regs infra3_cg_regs = { · 160 unmodified lines | ||
| 673 | 684 | GATE_MTK(_id, _name, _parent, &infra2_cg_regs, _shift, \ |
| 674 | 685 | &mtk_clk_gate_ops_setclr) |
| 675 | 686 | |
| 687 | +#define GATE_INFRA2_FLAGS(_id, _name, _parent, _shift, _flag) \ | |
| 688 | + GATE_MTK_FLAGS(_id, _name, _parent, &infra2_cg_regs, \ | |
| 689 | + _shift, &mtk_clk_gate_ops_setclr, _flag) | |
| 690 | + | |
| 676 | 691 | #define GATE_INFRA3(_id, _name, _parent, _shift) \ |
| 677 | 692 | GATE_MTK(_id, _name, _parent, &infra3_cg_regs, _shift, \ |
| 678 | 693 | &mtk_clk_gate_ops_setclr) |
| 679 | 694 | |
| 695 | +#define GATE_INFRA3_FLAGS(_id, _name, _parent, _shift, _flag) \ | |
| 696 | + GATE_MTK_FLAGS(_id, _name, _parent, &infra3_cg_regs, \ | |
| 697 | + _shift, &mtk_clk_gate_ops_setclr, _flag) | |
| 698 | + | |
| 680 | 699 | static const struct mtk_gate infra_clks[] = { |
| 681 | 700 | /* INFRA0 */ |
| 682 | 701 | GATE_INFRA0(CLK_INFRA_PMIC_TMR, "infra_pmic_tmr", "axi_sel", 0), |
| @@ -748,7 +767,11 @@ static const struct mtk_gate infra_clks[] = { · 65 unmodified lines | ||
| 748 | 767 | GATE_INFRA2(CLK_INFRA_UNIPRO_TICK, "infra_unipro_tick", "fufs_sel", 12), |
| 749 | 768 | GATE_INFRA2(CLK_INFRA_UFS_MP_SAP_BCLK, "infra_ufs_mp_sap_bck", "fufs_sel", 13), |
| 750 | 769 | GATE_INFRA2(CLK_INFRA_MD32_BCLK, "infra_md32_bclk", "axi_sel", 14), |
| 770 | + /* infra_sspm is main clock in co-processor, should not be closed in Linux. */ | |
| 771 | + GATE_INFRA2_FLAGS(CLK_INFRA_SSPM, "infra_sspm", "sspm_sel", 15, CLK_IS_CRITICAL), | |
| 751 | 772 | GATE_INFRA2(CLK_INFRA_UNIPRO_MBIST, "infra_unipro_mbist", "axi_sel", 16), |
| 773 | + /* infra_sspm_bus_hclk is main clock in co-processor, should not be closed in Linux. */ | |
| 774 | + GATE_INFRA2_FLAGS(CLK_INFRA_SSPM_BUS_HCLK, "infra_sspm_bus_hclk", "axi_sel", 17, CLK_IS_CRITICAL), | |
| 752 | 775 | GATE_INFRA2(CLK_INFRA_I2C5, "infra_i2c5", "i2c_sel", 18), |
| 753 | 776 | GATE_INFRA2(CLK_INFRA_I2C5_ARBITER, "infra_i2c5_arbiter", "i2c_sel", 19), |
| 754 | 777 | GATE_INFRA2(CLK_INFRA_I2C5_IMM, "infra_i2c5_imm", "i2c_sel", 20), |
| @@ -766,6 +789,10 @@ static const struct mtk_gate infra_clks[] = { · 11 unmodified lines | ||
| 766 | 789 | GATE_INFRA3(CLK_INFRA_MSDC0_SELF, "infra_msdc0_self", "msdc50_0_sel", 0), |
| 767 | 790 | GATE_INFRA3(CLK_INFRA_MSDC1_SELF, "infra_msdc1_self", "msdc50_0_sel", 1), |
| 768 | 791 | GATE_INFRA3(CLK_INFRA_MSDC2_SELF, "infra_msdc2_self", "msdc50_0_sel", 2), |
| 792 | + /* infra_sspm_26m_self is main clock in co-processor, should not be closed in Linux. */ | |
| 793 | + GATE_INFRA3_FLAGS(CLK_INFRA_SSPM_26M_SELF, "infra_sspm_26m_self", "f_f26m_ck", 3, CLK_IS_CRITICAL), | |
| 794 | + /* infra_sspm_32k_self is main clock in co-processor, should not be closed in Linux. */ | |
| 795 | + GATE_INFRA3_FLAGS(CLK_INFRA_SSPM_32K_SELF, "infra_sspm_32k_self", "f_f26m_ck", 4, CLK_IS_CRITICAL), | |
| 769 | 796 | GATE_INFRA3(CLK_INFRA_UFS_AXI, "infra_ufs_axi", "axi_sel", 5), |
| 770 | 797 | GATE_INFRA3(CLK_INFRA_I2C6, "infra_i2c6", "i2c_sel", 6), |
| 771 | 798 | GATE_INFRA3(CLK_INFRA_AP_MSDC0, "infra_ap_msdc0", "msdc50_hclk_sel", 7), |
| @@ -367,9 +367,9 @@ static int meson_clk_pll_enable(struct clk_hw *hw) · 366 unmodified lines | ||
| 367 | 367 | * 3. enable the lock detect module |
| 368 | 368 | */ |
| 369 | 369 | if (MESON_PARM_APPLICABLE(&pll->current_en)) { |
| 370 | − usleep_range(10, 20); | |
| 370 | + udelay(10); | |
| 371 | 371 | meson_parm_write(clk->map, &pll->current_en, 1); |
| 372 | − usleep_range(40, 50); | |
| 372 | + udelay(40); | |
| 373 | 373 | } |
| 374 | 374 | |
| 375 | 375 | if (MESON_PARM_APPLICABLE(&pll->l_detect)) { |
| @@ -3,13 +3,6 @@ · 2 unmodified lines | ||
| 3 | 3 | # Counter devices |
| 4 | 4 | # |
| 5 | 5 | |
| 6 | −menuconfig COUNTER | |
| 7 | − tristate "Counter support" | |
| 8 | − help | |
| 9 | − This enables counter device support through the Generic Counter | |
| 10 | − interface. You only need to enable this, if you also want to enable | |
| 11 | − one or more of the counter device drivers below. | |
| 12 | − | |
| 13 | 6 | config I8254 |
| 14 | 7 | tristate |
| 15 | 8 | select COUNTER |
| @@ -25,6 +18,13 @@ config I8254 · 9 unmodified lines | ||
| 25 | 18 | |
| 26 | 19 | If built as a module its name will be i8254. |
| 27 | 20 | |
| 21 | +menuconfig COUNTER | |
| 22 | + tristate "Counter support" | |
| 23 | + help | |
| 24 | + This enables counter device support through the Generic Counter | |
| 25 | + interface. You only need to enable this, if you also want to enable | |
| 26 | + one or more of the counter device drivers below. | |
| 27 | + | |
| 28 | 28 | if COUNTER |
| 29 | 29 | |
| 30 | 30 | config 104_QUAD_8 |
| @@ -1012,8 +1012,8 @@ static int amd_pstate_update_status(const char *buf, size_t size) · 1011 unmodified lines | ||
| 1012 | 1012 | return 0; |
| 1013 | 1013 | } |
| 1014 | 1014 | |
| 1015 | −static ssize_t show_status(struct kobject *kobj, | |
| 1016 | − struct kobj_attribute *attr, char *buf) | |
| 1015 | +static ssize_t status_show(struct device *dev, | |
| 1016 | + struct device_attribute *attr, char *buf) | |
| 1017 | 1017 | { |
| 1018 | 1018 | ssize_t ret; |
| 1019 | 1019 | |
| @@ -1024,7 +1024,7 @@ static ssize_t show_status(struct kobject *kobj, · 4 unmodified lines | ||
| 1024 | 1024 | return ret; |
| 1025 | 1025 | } |
| 1026 | 1026 | |
| 1027 | −static ssize_t store_status(struct kobject *a, struct kobj_attribute *b, | |
| 1027 | +static ssize_t status_store(struct device *a, struct device_attribute *b, | |
| 1028 | 1028 | const char *buf, size_t count) |
| 1029 | 1029 | { |
| 1030 | 1030 | char *p = memchr(buf, '\n', count); |
| @@ -1043,7 +1043,7 @@ cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq); · 12 unmodified lines | ||
| 1043 | 1043 | cpufreq_freq_attr_ro(amd_pstate_highest_perf); |
| 1044 | 1044 | cpufreq_freq_attr_rw(energy_performance_preference); |
| 1045 | 1045 | cpufreq_freq_attr_ro(energy_performance_available_preferences); |
| 1046 | −define_one_global_rw(status); | |
| 1046 | +static DEVICE_ATTR_RW(status); | |
| 1047 | 1047 | |
| 1048 | 1048 | static struct freq_attr *amd_pstate_attr[] = { |
| 1049 | 1049 | &amd_pstate_max_freq, |
| @@ -1062,7 +1062,7 @@ static struct freq_attr *amd_pstate_epp_attr[] = { · 12 unmodified lines | ||
| 1062 | 1062 | }; |
| 1063 | 1063 | |
| 1064 | 1064 | static struct attribute *pstate_global_attributes[] = { |
| 1065 | − &status.attr, | |
| 1065 | + &dev_attr_status.attr, | |
| 1066 | 1066 | NULL |
| 1067 | 1067 | }; |
| 1068 | 1068 | |
| @@ -120,20 +120,6 @@ static void psci_pd_remove(void) · 119 unmodified lines | ||
| 120 | 120 | } |
| 121 | 121 | } |
| 122 | 122 | |
| 123 | −static bool psci_pd_try_set_osi_mode(void) | |
| 124 | −{ | |
| 125 | − int ret; | |
| 126 | − | |
| 127 | − if (!psci_has_osi_support()) | |
| 128 | − return false; | |
| 129 | − | |
| 130 | − ret = psci_set_osi_mode(true); | |
| 131 | − if (ret) | |
| 132 | − return false; | |
| 133 | − | |
| 134 | − return true; | |
| 135 | −} | |
| 136 | − | |
| 137 | 123 | static void psci_cpuidle_domain_sync_state(struct device *dev) |
| 138 | 124 | { |
| 139 | 125 | /* |
| @@ -152,15 +138,12 @@ static int psci_cpuidle_domain_probe(struct platform_device *pdev) · 12 unmodified lines | ||
| 152 | 138 | { |
| 153 | 139 | struct device_node *np = pdev->dev.of_node; |
| 154 | 140 | struct device_node *node; |
| 155 | − bool use_osi; | |
| 141 | + bool use_osi = psci_has_osi_support(); | |
| 156 | 142 | int ret = 0, pd_count = 0; |
| 157 | 143 | |
| 158 | 144 | if (!np) |
| 159 | 145 | return -ENODEV; |
| 160 | 146 | |
| 161 | − /* If OSI mode is supported, let's try to enable it. */ | |
| 162 | − use_osi = psci_pd_try_set_osi_mode(); | |
| 163 | − | |
| 164 | 147 | /* |
| 165 | 148 | * Parse child nodes for the "#power-domain-cells" property and |
| 166 | 149 | * initialize a genpd/genpd-of-provider pair when it's found. |
| @@ -170,33 +153,37 @@ static int psci_cpuidle_domain_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 170 | 153 | continue; |
| 171 | 154 | |
| 172 | 155 | ret = psci_pd_init(node, use_osi); |
| 173 | − if (ret) | |
| 174 | − goto put_node; | |
| 156 | + if (ret) { | |
| 157 | + of_node_put(node); | |
| 158 | + goto exit; | |
| 159 | + } | |
| 175 | 160 | |
| 176 | 161 | pd_count++; |
| 177 | 162 | } |
| 178 | 163 | |
| 179 | 164 | /* Bail out if not using the hierarchical CPU topology. */ |
| 180 | 165 | if (!pd_count) |
| 181 | − goto no_pd; | |
| 166 | + return 0; | |
| 182 | 167 | |
| 183 | 168 | /* Link genpd masters/subdomains to model the CPU topology. */ |
| 184 | 169 | ret = dt_idle_pd_init_topology(np); |
| 185 | 170 | if (ret) |
| 186 | 171 | goto remove_pd; |
| 187 | 172 | |
| 173 | + /* let's try to enable OSI. */ | |
| 174 | + ret = psci_set_osi_mode(use_osi); | |
| 175 | + if (ret) | |
| 176 | + goto remove_pd; | |
| 177 | + | |
| 188 | 178 | pr_info("Initialized CPU PM domain topology using %s mode\n", |
| 189 | 179 | use_osi ? "OSI" : "PC"); |
| 190 | 180 | return 0; |
| 191 | 181 | |
| 192 | −put_node: | |
| 193 | − of_node_put(node); | |
| 194 | 182 | remove_pd: |
| 183 | + dt_idle_pd_remove_topology(np); | |
| 195 | 184 | psci_pd_remove(); |
| 185 | +exit: | |
| 196 | 186 | pr_err("failed to create CPU PM domains ret=%d\n", ret); |
| 197 | −no_pd: | |
| 198 | − if (use_osi) | |
| 199 | − psci_set_osi_mode(false); | |
| 200 | 187 | return ret; |
| 201 | 188 | } |
| 202 | 189 | |
| @@ -152,6 +152,30 @@ int dt_idle_pd_init_topology(struct device_node *np) · 151 unmodified lines | ||
| 152 | 152 | return 0; |
| 153 | 153 | } |
| 154 | 154 | |
| 155 | +int dt_idle_pd_remove_topology(struct device_node *np) | |
| 156 | +{ | |
| 157 | + struct device_node *node; | |
| 158 | + struct of_phandle_args child, parent; | |
| 159 | + int ret; | |
| 160 | + | |
| 161 | + for_each_child_of_node(np, node) { | |
| 162 | + if (of_parse_phandle_with_args(node, "power-domains", | |
| 163 | + "#power-domain-cells", 0, &parent)) | |
| 164 | + continue; | |
| 165 | + | |
| 166 | + child.np = node; | |
| 167 | + child.args_count = 0; | |
| 168 | + ret = of_genpd_remove_subdomain(&parent, &child); | |
| 169 | + of_node_put(parent.np); | |
| 170 | + if (ret) { | |
| 171 | + of_node_put(node); | |
| 172 | + return ret; | |
| 173 | + } | |
| 174 | + } | |
| 175 | + | |
| 176 | + return 0; | |
| 177 | +} | |
| 178 | + | |
| 155 | 179 | struct device *dt_idle_attach_cpu(int cpu, const char *name) |
| 156 | 180 | { |
| 157 | 181 | struct device *dev; |
| @@ -14,6 +14,8 @@ struct generic_pm_domain *dt_idle_pd_alloc(struct device_node *np, · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | int dt_idle_pd_init_topology(struct device_node *np); |
| 16 | 16 | |
| 17 | +int dt_idle_pd_remove_topology(struct device_node *np); | |
| 18 | + | |
| 17 | 19 | struct device *dt_idle_attach_cpu(int cpu, const char *name); |
| 18 | 20 | |
| 19 | 21 | void dt_idle_detach_cpu(struct device *dev); |
| @@ -36,6 +38,11 @@ static inline int dt_idle_pd_init_topology(struct device_node *np) · 16 unmodified lines | ||
| 36 | 38 | return 0; |
| 37 | 39 | } |
| 38 | 40 | |
| 41 | +static inline int dt_idle_pd_remove_topology(struct device_node *np) | |
| 42 | +{ | |
| 43 | + return 0; | |
| 44 | +} | |
| 45 | + | |
| 39 | 46 | static inline struct device *dt_idle_attach_cpu(int cpu, const char *name) |
| 40 | 47 | { |
| 41 | 48 | return NULL; |
| @@ -2,6 +2,8 @@ · 1 unmodified line | ||
| 2 | 2 | menuconfig CXL_BUS |
| 3 | 3 | tristate "CXL (Compute Express Link) Devices Support" |
| 4 | 4 | depends on PCI |
| 5 | + select FW_LOADER | |
| 6 | + select FW_UPLOAD | |
| 5 | 7 | select PCI_DOE |
| 6 | 8 | help |
| 7 | 9 | CXL is a bus that is electrically compatible with PCI Express, but |
| @@ -82,7 +84,6 @@ config CXL_PMEM · 74 unmodified lines | ||
| 82 | 84 | config CXL_MEM |
| 83 | 85 | tristate "CXL: Memory Expansion" |
| 84 | 86 | depends on CXL_PCI |
| 85 | − select FW_UPLOAD | |
| 86 | 87 | default CXL_BUS |
| 87 | 88 | help |
| 88 | 89 | The CXL.mem protocol allows a device to act as a provider of "System |
| @@ -296,9 +296,8 @@ err_xormap: · 295 unmodified lines | ||
| 296 | 296 | else |
| 297 | 297 | rc = cxl_decoder_autoremove(dev, cxld); |
| 298 | 298 | if (rc) { |
| 299 | − dev_err(dev, "Failed to add decode range [%#llx - %#llx]\n", | |
| 300 | − cxld->hpa_range.start, cxld->hpa_range.end); | |
| 301 | − return 0; | |
| 299 | + dev_err(dev, "Failed to add decode range: %pr", res); | |
| 300 | + return rc; | |
| 302 | 301 | } |
| 303 | 302 | dev_dbg(dev, "add: %s node: %d range [%#llx - %#llx]\n", |
| 304 | 303 | dev_name(&cxld->dev), |
| @@ -121,6 +121,45 @@ static bool cxl_is_security_command(u16 opcode) · 120 unmodified lines | ||
| 121 | 121 | return false; |
| 122 | 122 | } |
| 123 | 123 | |
| 124 | +static void cxl_set_security_cmd_enabled(struct cxl_security_state *security, | |
| 125 | + u16 opcode) | |
| 126 | +{ | |
| 127 | + switch (opcode) { | |
| 128 | + case CXL_MBOX_OP_SANITIZE: | |
| 129 | + set_bit(CXL_SEC_ENABLED_SANITIZE, security->enabled_cmds); | |
| 130 | + break; | |
| 131 | + case CXL_MBOX_OP_SECURE_ERASE: | |
| 132 | + set_bit(CXL_SEC_ENABLED_SECURE_ERASE, | |
| 133 | + security->enabled_cmds); | |
| 134 | + break; | |
| 135 | + case CXL_MBOX_OP_GET_SECURITY_STATE: | |
| 136 | + set_bit(CXL_SEC_ENABLED_GET_SECURITY_STATE, | |
| 137 | + security->enabled_cmds); | |
| 138 | + break; | |
| 139 | + case CXL_MBOX_OP_SET_PASSPHRASE: | |
| 140 | + set_bit(CXL_SEC_ENABLED_SET_PASSPHRASE, | |
| 141 | + security->enabled_cmds); | |
| 142 | + break; | |
| 143 | + case CXL_MBOX_OP_DISABLE_PASSPHRASE: | |
| 144 | + set_bit(CXL_SEC_ENABLED_DISABLE_PASSPHRASE, | |
| 145 | + security->enabled_cmds); | |
| 146 | + break; | |
| 147 | + case CXL_MBOX_OP_UNLOCK: | |
| 148 | + set_bit(CXL_SEC_ENABLED_UNLOCK, security->enabled_cmds); | |
| 149 | + break; | |
| 150 | + case CXL_MBOX_OP_FREEZE_SECURITY: | |
| 151 | + set_bit(CXL_SEC_ENABLED_FREEZE_SECURITY, | |
| 152 | + security->enabled_cmds); | |
| 153 | + break; | |
| 154 | + case CXL_MBOX_OP_PASSPHRASE_SECURE_ERASE: | |
| 155 | + set_bit(CXL_SEC_ENABLED_PASSPHRASE_SECURE_ERASE, | |
| 156 | + security->enabled_cmds); | |
| 157 | + break; | |
| 158 | + default: | |
| 159 | + break; | |
| 160 | + } | |
| 161 | +} | |
| 162 | + | |
| 124 | 163 | static bool cxl_is_poison_command(u16 opcode) |
| 125 | 164 | { |
| 126 | 165 | #define CXL_MBOX_OP_POISON_CMDS 0x43 |
| @@ -677,7 +716,8 @@ static void cxl_walk_cel(struct cxl_memdev_state *mds, size_t size, u8 *cel) · 550 unmodified lines | ||
| 677 | 716 | u16 opcode = le16_to_cpu(cel_entry[i].opcode); |
| 678 | 717 | struct cxl_mem_command *cmd = cxl_mem_find_command(opcode); |
| 679 | 718 | |
| 680 | − if (!cmd && !cxl_is_poison_command(opcode)) { | |
| 719 | + if (!cmd && (!cxl_is_poison_command(opcode) || | |
| 720 | + !cxl_is_security_command(opcode))) { | |
| 681 | 721 | dev_dbg(dev, |
| 682 | 722 | "Opcode 0x%04x unsupported by driver\n", opcode); |
| 683 | 723 | continue; |
| @@ -689,6 +729,9 @@ static void cxl_walk_cel(struct cxl_memdev_state *mds, size_t size, u8 *cel) · 5 unmodified lines | ||
| 689 | 729 | if (cxl_is_poison_command(opcode)) |
| 690 | 730 | cxl_set_poison_cmd_enabled(&mds->poison, opcode); |
| 691 | 731 | |
| 732 | + if (cxl_is_security_command(opcode)) | |
| 733 | + cxl_set_security_cmd_enabled(&mds->security, opcode); | |
| 734 | + | |
| 692 | 735 | dev_dbg(dev, "Opcode 0x%04x enabled\n", opcode); |
| 693 | 736 | } |
| 694 | 737 | } |
| @@ -477,9 +477,28 @@ static struct attribute_group cxl_memdev_pmem_attribute_group = { · 476 unmodified lines | ||
| 477 | 477 | .attrs = cxl_memdev_pmem_attributes, |
| 478 | 478 | }; |
| 479 | 479 | |
| 480 | +static umode_t cxl_memdev_security_visible(struct kobject *kobj, | |
| 481 | + struct attribute *a, int n) | |
| 482 | +{ | |
| 483 | + struct device *dev = kobj_to_dev(kobj); | |
| 484 | + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); | |
| 485 | + struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); | |
| 486 | + | |
| 487 | + if (a == &dev_attr_security_sanitize.attr && | |
| 488 | + !test_bit(CXL_SEC_ENABLED_SANITIZE, mds->security.enabled_cmds)) | |
| 489 | + return 0; | |
| 490 | + | |
| 491 | + if (a == &dev_attr_security_erase.attr && | |
| 492 | + !test_bit(CXL_SEC_ENABLED_SECURE_ERASE, mds->security.enabled_cmds)) | |
| 493 | + return 0; | |
| 494 | + | |
| 495 | + return a->mode; | |
| 496 | +} | |
| 497 | + | |
| 480 | 498 | static struct attribute_group cxl_memdev_security_attribute_group = { |
| 481 | 499 | .name = "security", |
| 482 | 500 | .attrs = cxl_memdev_security_attributes, |
| 501 | + .is_visible = cxl_memdev_security_visible, | |
| 483 | 502 | }; |
| 484 | 503 | |
| 485 | 504 | static const struct attribute_group *cxl_memdev_attribute_groups[] = { |
| @@ -244,6 +244,19 @@ enum poison_cmd_enabled_bits { · 243 unmodified lines | ||
| 244 | 244 | CXL_POISON_ENABLED_MAX |
| 245 | 245 | }; |
| 246 | 246 | |
| 247 | +/* Device enabled security commands */ | |
| 248 | +enum security_cmd_enabled_bits { | |
| 249 | + CXL_SEC_ENABLED_SANITIZE, | |
| 250 | + CXL_SEC_ENABLED_SECURE_ERASE, | |
| 251 | + CXL_SEC_ENABLED_GET_SECURITY_STATE, | |
| 252 | + CXL_SEC_ENABLED_SET_PASSPHRASE, | |
| 253 | + CXL_SEC_ENABLED_DISABLE_PASSPHRASE, | |
| 254 | + CXL_SEC_ENABLED_UNLOCK, | |
| 255 | + CXL_SEC_ENABLED_FREEZE_SECURITY, | |
| 256 | + CXL_SEC_ENABLED_PASSPHRASE_SECURE_ERASE, | |
| 257 | + CXL_SEC_ENABLED_MAX | |
| 258 | +}; | |
| 259 | + | |
| 247 | 260 | /** |
| 248 | 261 | * struct cxl_poison_state - Driver poison state info |
| 249 | 262 | * |
| @@ -323,7 +336,7 @@ struct cxl_mbox_activate_fw { · 73 unmodified lines | ||
| 323 | 336 | |
| 324 | 337 | /* FW state bits */ |
| 325 | 338 | #define CXL_FW_STATE_BITS 32 |
| 326 | −#define CXL_FW_CANCEL BIT(0) | |
| 339 | +#define CXL_FW_CANCEL 0 | |
| 327 | 340 | |
| 328 | 341 | /** |
| 329 | 342 | * struct cxl_fw_state - Firmware upload / activation state |
| @@ -346,6 +359,7 @@ struct cxl_fw_state { · 16 unmodified lines | ||
| 346 | 359 | * struct cxl_security_state - Device security state |
| 347 | 360 | * |
| 348 | 361 | * @state: state of last security operation |
| 362 | + * @enabled_cmds: All security commands enabled in the CEL | |
| 349 | 363 | * @poll: polling for sanitization is enabled, device has no mbox irq support |
| 350 | 364 | * @poll_tmo_secs: polling timeout |
| 351 | 365 | * @poll_dwork: polling work item |
| @@ -353,6 +367,7 @@ struct cxl_fw_state { · 1 unmodified line | ||
| 353 | 367 | */ |
| 354 | 368 | struct cxl_security_state { |
| 355 | 369 | unsigned long state; |
| 370 | + DECLARE_BITMAP(enabled_cmds, CXL_SEC_ENABLED_MAX); | |
| 356 | 371 | bool poll; |
| 357 | 372 | int poll_tmo_secs; |
| 358 | 373 | struct delayed_work poll_dwork; |
| @@ -434,6 +449,7 @@ struct cxl_dev_state { · 75 unmodified lines | ||
| 434 | 449 | * @next_persistent_bytes: persistent capacity change pending device reset |
| 435 | 450 | * @event: event log driver state |
| 436 | 451 | * @poison: poison driver state info |
| 452 | + * @security: security driver state info | |
| 437 | 453 | * @fw: firmware upload / activation state |
| 438 | 454 | * @mbox_send: @dev specific transport for transmitting mailbox commands |
| 439 | 455 | * |
| @@ -211,6 +211,7 @@ config FSL_DMA · 210 unmodified lines | ||
| 211 | 211 | config FSL_EDMA |
| 212 | 212 | tristate "Freescale eDMA engine support" |
| 213 | 213 | depends on OF |
| 214 | + depends on HAS_IOMEM | |
| 214 | 215 | select DMA_ENGINE |
| 215 | 216 | select DMA_VIRTUAL_CHANNELS |
| 216 | 217 | help |
| @@ -280,6 +281,7 @@ config IMX_SDMA · 63 unmodified lines | ||
| 280 | 281 | |
| 281 | 282 | config INTEL_IDMA64 |
| 282 | 283 | tristate "Intel integrated DMA 64-bit support" |
| 284 | + depends on HAS_IOMEM | |
| 283 | 285 | select DMA_ENGINE |
| 284 | 286 | select DMA_VIRTUAL_CHANNELS |
| 285 | 287 | help |
| @@ -384,9 +384,7 @@ static void idxd_wq_disable_cleanup(struct idxd_wq *wq) · 383 unmodified lines | ||
| 384 | 384 | wq->threshold = 0; |
| 385 | 385 | wq->priority = 0; |
| 386 | 386 | wq->enqcmds_retries = IDXD_ENQCMDS_RETRIES; |
| 387 | − clear_bit(WQ_FLAG_DEDICATED, &wq->flags); | |
| 388 | − clear_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags); | |
| 389 | − clear_bit(WQ_FLAG_ATS_DISABLE, &wq->flags); | |
| 387 | + wq->flags = 0; | |
| 390 | 388 | memset(wq->name, 0, WQ_NAME_SIZE); |
| 391 | 389 | wq->max_xfer_bytes = WQ_DEFAULT_MAX_XFER; |
| 392 | 390 | idxd_wq_set_max_batch_size(idxd->data->type, wq, WQ_DEFAULT_MAX_BATCH); |
| @@ -190,7 +190,13 @@ static int mcf_edma_probe(struct platform_device *pdev) · 189 unmodified lines | ||
| 190 | 190 | return -EINVAL; |
| 191 | 191 | } |
| 192 | 192 | |
| 193 | − chans = pdata->dma_channels; | |
| 193 | + if (!pdata->dma_channels) { | |
| 194 | + dev_info(&pdev->dev, "setting default channel number to 64"); | |
| 195 | + chans = 64; | |
| 196 | + } else { | |
| 197 | + chans = pdata->dma_channels; | |
| 198 | + } | |
| 199 | + | |
| 194 | 200 | len = sizeof(*mcf_edma) + sizeof(*mcf_chan) * chans; |
| 195 | 201 | mcf_edma = devm_kzalloc(&pdev->dev, len, GFP_KERNEL); |
| 196 | 202 | if (!mcf_edma) |
| @@ -202,11 +208,6 @@ static int mcf_edma_probe(struct platform_device *pdev) · 5 unmodified lines | ||
| 202 | 208 | mcf_edma->drvdata = &mcf_data; |
| 203 | 209 | mcf_edma->big_endian = 1; |
| 204 | 210 | |
| 205 | − if (!mcf_edma->n_chans) { | |
| 206 | − dev_info(&pdev->dev, "setting default channel number to 64"); | |
| 207 | − mcf_edma->n_chans = 64; | |
| 208 | − } | |
| 209 | − | |
| 210 | 211 | mutex_init(&mcf_edma->fsl_edma_mutex); |
| 211 | 212 | |
| 212 | 213 | mcf_edma->membase = devm_platform_ioremap_resource(pdev, 0); |
| @@ -192,7 +192,7 @@ struct owl_dma_pchan { · 191 unmodified lines | ||
| 192 | 192 | }; |
| 193 | 193 | |
| 194 | 194 | /** |
| 195 | − * struct owl_dma_pchan - Wrapper for DMA ENGINE channel | |
| 195 | + * struct owl_dma_vchan - Wrapper for DMA ENGINE channel | |
| 196 | 196 | * @vc: wrapped virtual channel |
| 197 | 197 | * @pchan: the physical channel utilized by this channel |
| 198 | 198 | * @txd: active transaction on this channel |
| @@ -403,6 +403,12 @@ enum desc_status { · 402 unmodified lines | ||
| 403 | 403 | * of a channel can be BUSY at any time. |
| 404 | 404 | */ |
| 405 | 405 | BUSY, |
| 406 | + /* | |
| 407 | + * Pause was called while descriptor was BUSY. Due to hardware | |
| 408 | + * limitations, only termination is possible for descriptors | |
| 409 | + * that have been paused. | |
| 410 | + */ | |
| 411 | + PAUSED, | |
| 406 | 412 | /* |
| 407 | 413 | * Sitting on the channel work_list but xfer done |
| 408 | 414 | * by PL330 core |
| @@ -2041,7 +2047,7 @@ static inline void fill_queue(struct dma_pl330_chan *pch) · 1632 unmodified lines | ||
| 2041 | 2047 | list_for_each_entry(desc, &pch->work_list, node) { |
| 2042 | 2048 | |
| 2043 | 2049 | /* If already submitted */ |
| 2044 | − if (desc->status == BUSY) | |
| 2050 | + if (desc->status == BUSY || desc->status == PAUSED) | |
| 2045 | 2051 | continue; |
| 2046 | 2052 | |
| 2047 | 2053 | ret = pl330_submit_req(pch->thread, desc); |
| @@ -2326,6 +2332,7 @@ static int pl330_pause(struct dma_chan *chan) · 278 unmodified lines | ||
| 2326 | 2332 | { |
| 2327 | 2333 | struct dma_pl330_chan *pch = to_pchan(chan); |
| 2328 | 2334 | struct pl330_dmac *pl330 = pch->dmac; |
| 2335 | + struct dma_pl330_desc *desc; | |
| 2329 | 2336 | unsigned long flags; |
| 2330 | 2337 | |
| 2331 | 2338 | pm_runtime_get_sync(pl330->ddma.dev); |
| @@ -2335,6 +2342,10 @@ static int pl330_pause(struct dma_chan *chan) · 3 unmodified lines | ||
| 2335 | 2342 | _stop(pch->thread); |
| 2336 | 2343 | spin_unlock(&pl330->lock); |
| 2337 | 2344 | |
| 2345 | + list_for_each_entry(desc, &pch->work_list, node) { | |
| 2346 | + if (desc->status == BUSY) | |
| 2347 | + desc->status = PAUSED; | |
| 2348 | + } | |
| 2338 | 2349 | spin_unlock_irqrestore(&pch->lock, flags); |
| 2339 | 2350 | pm_runtime_mark_last_busy(pl330->ddma.dev); |
| 2340 | 2351 | pm_runtime_put_autosuspend(pl330->ddma.dev); |
| @@ -2425,7 +2436,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, · 84 unmodified lines | ||
| 2425 | 2436 | else if (running && desc == running) |
| 2426 | 2437 | transferred = |
| 2427 | 2438 | pl330_get_current_xferred_count(pch, desc); |
| 2428 | − else if (desc->status == BUSY) | |
| 2439 | + else if (desc->status == BUSY || desc->status == PAUSED) | |
| 2429 | 2440 | /* |
| 2430 | 2441 | * Busy but not running means either just enqueued, |
| 2431 | 2442 | * or finished and not yet marked done |
| @@ -2442,6 +2453,9 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, · 10 unmodified lines | ||
| 2442 | 2453 | case DONE: |
| 2443 | 2454 | ret = DMA_COMPLETE; |
| 2444 | 2455 | break; |
| 2456 | + case PAUSED: | |
| 2457 | + ret = DMA_PAUSED; | |
| 2458 | + break; | |
| 2445 | 2459 | case PREP: |
| 2446 | 2460 | case BUSY: |
| 2447 | 2461 | ret = DMA_IN_PROGRESS; |
| @@ -668,6 +668,8 @@ static int xdma_set_vector_reg(struct xdma_device *xdev, u32 vec_tbl_start, · 667 unmodified lines | ||
| 668 | 668 | val |= irq_start << shift; |
| 669 | 669 | irq_start++; |
| 670 | 670 | irq_num--; |
| 671 | + if (!irq_num) | |
| 672 | + break; | |
| 671 | 673 | } |
| 672 | 674 | |
| 673 | 675 | /* write IRQ register */ |
| @@ -715,7 +717,7 @@ static int xdma_irq_init(struct xdma_device *xdev) · 41 unmodified lines | ||
| 715 | 717 | ret = request_irq(irq, xdma_channel_isr, 0, |
| 716 | 718 | "xdma-c2h-channel", &xdev->c2h_chans[j]); |
| 717 | 719 | if (ret) { |
| 718 | − xdma_err(xdev, "H2C channel%d request irq%d failed: %d", | |
| 720 | + xdma_err(xdev, "C2H channel%d request irq%d failed: %d", | |
| 719 | 721 | j, irq, ret); |
| 720 | 722 | goto failed_init_c2h; |
| 721 | 723 | } |
| @@ -892,7 +894,7 @@ static int xdma_probe(struct platform_device *pdev) · 170 unmodified lines | ||
| 892 | 894 | } |
| 893 | 895 | |
| 894 | 896 | reg_base = devm_ioremap_resource(&pdev->dev, res); |
| 895 | − if (!reg_base) { | |
| 897 | + if (IS_ERR(reg_base)) { | |
| 896 | 898 | xdma_err(xdev, "ioremap failed"); |
| 897 | 899 | goto failed; |
| 898 | 900 | } |
| @@ -166,8 +166,10 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 165 unmodified lines | ||
| 166 | 166 | return -ENOMEM; |
| 167 | 167 | |
| 168 | 168 | shmem = of_parse_phandle(cdev->of_node, "shmem", idx); |
| 169 | − if (!of_device_is_compatible(shmem, "arm,scmi-shmem")) | |
| 169 | + if (!of_device_is_compatible(shmem, "arm,scmi-shmem")) { | |
| 170 | + of_node_put(shmem); | |
| 170 | 171 | return -ENXIO; |
| 172 | + } | |
| 171 | 173 | |
| 172 | 174 | ret = of_address_to_resource(shmem, 0, &res); |
| 173 | 175 | of_node_put(shmem); |
| @@ -818,10 +818,13 @@ static ssize_t scmi_dbg_raw_mode_common_write(struct file *filp, · 817 unmodified lines | ||
| 818 | 818 | * before sending it with a single RAW xfer. |
| 819 | 819 | */ |
| 820 | 820 | if (rd->tx_size < rd->tx_req_size) { |
| 821 | − size_t cnt; | |
| 821 | + ssize_t cnt; | |
| 822 | 822 | |
| 823 | 823 | cnt = simple_write_to_buffer(rd->tx.buf, rd->tx.len, ppos, |
| 824 | 824 | buf, count); |
| 825 | + if (cnt < 0) | |
| 826 | + return cnt; | |
| 827 | + | |
| 825 | 828 | rd->tx_size += cnt; |
| 826 | 829 | if (cnt < count) |
| 827 | 830 | return cnt; |
| @@ -40,6 +40,7 @@ · 39 unmodified lines | ||
| 40 | 40 | /** |
| 41 | 41 | * struct scmi_smc - Structure representing a SCMI smc transport |
| 42 | 42 | * |
| 43 | + * @irq: An optional IRQ for completion | |
| 43 | 44 | * @cinfo: SCMI channel info |
| 44 | 45 | * @shmem: Transmit/Receive shared memory area |
| 45 | 46 | * @shmem_lock: Lock to protect access to Tx/Rx shared memory area. |
| @@ -52,6 +53,7 @@ · 6 unmodified lines | ||
| 52 | 53 | */ |
| 53 | 54 | |
| 54 | 55 | struct scmi_smc { |
| 56 | + int irq; | |
| 55 | 57 | struct scmi_chan_info *cinfo; |
| 56 | 58 | struct scmi_shared_mem __iomem *shmem; |
| 57 | 59 | /* Protect access to shmem area */ |
| @@ -127,7 +129,7 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 69 unmodified lines | ||
| 127 | 129 | struct resource res; |
| 128 | 130 | struct device_node *np; |
| 129 | 131 | u32 func_id; |
| 130 | − int ret, irq; | |
| 132 | + int ret; | |
| 131 | 133 | |
| 132 | 134 | if (!tx) |
| 133 | 135 | return -ENODEV; |
| @@ -137,8 +139,10 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 3 unmodified lines | ||
| 137 | 139 | return -ENOMEM; |
| 138 | 140 | |
| 139 | 141 | np = of_parse_phandle(cdev->of_node, "shmem", 0); |
| 140 | − if (!of_device_is_compatible(np, "arm,scmi-shmem")) | |
| 142 | + if (!of_device_is_compatible(np, "arm,scmi-shmem")) { | |
| 143 | + of_node_put(np); | |
| 141 | 144 | return -ENXIO; |
| 145 | + } | |
| 142 | 146 | |
| 143 | 147 | ret = of_address_to_resource(np, 0, &res); |
| 144 | 148 | of_node_put(np); |
| @@ -167,11 +171,10 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 22 unmodified lines | ||
| 167 | 171 | * completion of a message is signaled by an interrupt rather than by |
| 168 | 172 | * the return of the SMC call. |
| 169 | 173 | */ |
| 170 | − irq = of_irq_get_byname(cdev->of_node, "a2p"); | |
| 171 | − if (irq > 0) { | |
| 172 | − ret = devm_request_irq(dev, irq, smc_msg_done_isr, | |
| 173 | − IRQF_NO_SUSPEND, | |
| 174 | − dev_name(dev), scmi_info); | |
| 174 | + scmi_info->irq = of_irq_get_byname(cdev->of_node, "a2p"); | |
| 175 | + if (scmi_info->irq > 0) { | |
| 176 | + ret = request_irq(scmi_info->irq, smc_msg_done_isr, | |
| 177 | + IRQF_NO_SUSPEND, dev_name(dev), scmi_info); | |
| 175 | 178 | if (ret) { |
| 176 | 179 | dev_err(dev, "failed to setup SCMI smc irq\n"); |
| 177 | 180 | return ret; |
| @@ -193,6 +196,10 @@ static int smc_chan_free(int id, void *p, void *data) · 15 unmodified lines | ||
| 193 | 196 | struct scmi_chan_info *cinfo = p; |
| 194 | 197 | struct scmi_smc *scmi_info = cinfo->transport_info; |
| 195 | 198 | |
| 199 | + /* Ignore any possible further reception on the IRQ path */ | |
| 200 | + if (scmi_info->irq > 0) | |
| 201 | + free_irq(scmi_info->irq, scmi_info); | |
| 202 | + | |
| 196 | 203 | cinfo->transport_info = NULL; |
| 197 | 204 | scmi_info->cinfo = NULL; |
| 198 | 205 | |
| @@ -34,7 +34,6 @@ static struct soc_device_attribute *soc_dev_attr; · 33 unmodified lines | ||
| 34 | 34 | |
| 35 | 35 | static int __init smccc_soc_init(void) |
| 36 | 36 | { |
| 37 | − struct arm_smccc_res res; | |
| 38 | 37 | int soc_id_rev, soc_id_version; |
| 39 | 38 | static char soc_id_str[20], soc_id_rev_str[12]; |
| 40 | 39 | static char soc_id_jep106_id_str[12]; |
| @@ -49,13 +48,13 @@ static int __init smccc_soc_init(void) · 8 unmodified lines | ||
| 49 | 48 | } |
| 50 | 49 | |
| 51 | 50 | if (soc_id_version < 0) { |
| 52 | − pr_err("ARCH_SOC_ID(0) returned error: %lx\n", res.a0); | |
| 51 | + pr_err("Invalid SoC Version: %x\n", soc_id_version); | |
| 53 | 52 | return -EINVAL; |
| 54 | 53 | } |
| 55 | 54 | |
| 56 | 55 | soc_id_rev = arm_smccc_get_soc_id_revision(); |
| 57 | 56 | if (soc_id_rev < 0) { |
| 58 | − pr_err("ARCH_SOC_ID(1) returned error: %lx\n", res.a0); | |
| 57 | + pr_err("Invalid SoC Revision: %x\n", soc_id_rev); | |
| 59 | 58 | return -EINVAL; |
| 60 | 59 | } |
| 61 | 60 | |
| @@ -429,6 +429,7 @@ static int gpio_sim_add_bank(struct fwnode_handle *swnode, struct device *dev) · 428 unmodified lines | ||
| 429 | 429 | gc->set_config = gpio_sim_set_config; |
| 430 | 430 | gc->to_irq = gpio_sim_to_irq; |
| 431 | 431 | gc->free = gpio_sim_free; |
| 432 | + gc->can_sleep = true; | |
| 432 | 433 | |
| 433 | 434 | ret = devm_gpiochip_add_data(dev, gc, chip); |
| 434 | 435 | if (ret) |
| @@ -18,7 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/spinlock.h> |
| 19 | 19 | #include <linux/types.h> |
| 20 | 20 | |
| 21 | −#define WS16C48_EXTENT 10 | |
| 21 | +#define WS16C48_EXTENT 11 | |
| 22 | 22 | #define MAX_NUM_WS16C48 max_num_isa_dev(WS16C48_EXTENT) |
| 23 | 23 | |
| 24 | 24 | static unsigned int base[MAX_NUM_WS16C48]; |
| @@ -1296,6 +1296,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, · 1295 unmodified lines | ||
| 1296 | 1296 | void amdgpu_device_pci_config_reset(struct amdgpu_device *adev); |
| 1297 | 1297 | int amdgpu_device_pci_reset(struct amdgpu_device *adev); |
| 1298 | 1298 | bool amdgpu_device_need_post(struct amdgpu_device *adev); |
| 1299 | +bool amdgpu_sg_display_supported(struct amdgpu_device *adev); | |
| 1299 | 1300 | bool amdgpu_device_pcie_dynamic_switching_supported(void); |
| 1300 | 1301 | bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev); |
| 1301 | 1302 | bool amdgpu_device_aspm_support_quirk(void); |
| @@ -295,7 +295,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p, · 294 unmodified lines | ||
| 295 | 295 | |
| 296 | 296 | if (!p->gang_size) { |
| 297 | 297 | ret = -EINVAL; |
| 298 | − goto free_partial_kdata; | |
| 298 | + goto free_all_kdata; | |
| 299 | 299 | } |
| 300 | 300 | |
| 301 | 301 | for (i = 0; i < p->gang_size; ++i) { |
| @@ -1458,6 +1458,32 @@ bool amdgpu_device_need_post(struct amdgpu_device *adev) · 1457 unmodified lines | ||
| 1458 | 1458 | return true; |
| 1459 | 1459 | } |
| 1460 | 1460 | |
| 1461 | +/* | |
| 1462 | + * On APUs with >= 64GB white flickering has been observed w/ SG enabled. | |
| 1463 | + * Disable S/G on such systems until we have a proper fix. | |
| 1464 | + * https://gitlab.freedesktop.org/drm/amd/-/issues/2354 | |
| 1465 | + * https://gitlab.freedesktop.org/drm/amd/-/issues/2735 | |
| 1466 | + */ | |
| 1467 | +bool amdgpu_sg_display_supported(struct amdgpu_device *adev) | |
| 1468 | +{ | |
| 1469 | + switch (amdgpu_sg_display) { | |
| 1470 | + case -1: | |
| 1471 | + break; | |
| 1472 | + case 0: | |
| 1473 | + return false; | |
| 1474 | + case 1: | |
| 1475 | + return true; | |
| 1476 | + default: | |
| 1477 | + return false; | |
| 1478 | + } | |
| 1479 | + if ((totalram_pages() << (PAGE_SHIFT - 10)) + | |
| 1480 | + (adev->gmc.real_vram_size / 1024) >= 64000000) { | |
| 1481 | + DRM_WARN("Disabling S/G due to >=64GB RAM\n"); | |
| 1482 | + return false; | |
| 1483 | + } | |
| 1484 | + return true; | |
| 1485 | +} | |
| 1486 | + | |
| 1461 | 1487 | /* |
| 1462 | 1488 | * Intel hosts such as Raptor Lake and Sapphire Rapids don't support dynamic |
| 1463 | 1489 | * speed switching. Until we have confirmation from Intel that a specific host |
| @@ -498,11 +498,11 @@ static int psp_sw_init(void *handle) · 497 unmodified lines | ||
| 498 | 498 | return 0; |
| 499 | 499 | |
| 500 | 500 | failed2: |
| 501 | − amdgpu_bo_free_kernel(&psp->fw_pri_bo, | |
| 502 | − &psp->fw_pri_mc_addr, &psp->fw_pri_buf); | |
| 503 | −failed1: | |
| 504 | 501 | amdgpu_bo_free_kernel(&psp->fence_buf_bo, |
| 505 | 502 | &psp->fence_buf_mc_addr, &psp->fence_buf); |
| 503 | +failed1: | |
| 504 | + amdgpu_bo_free_kernel(&psp->fw_pri_bo, | |
| 505 | + &psp->fw_pri_mc_addr, &psp->fw_pri_buf); | |
| 506 | 506 | return ret; |
| 507 | 507 | } |
| 508 | 508 | |
| @@ -471,8 +471,12 @@ static void gfx_v11_0_check_fw_cp_gfx_shadow(struct amdgpu_device *adev) · 470 unmodified lines | ||
| 471 | 471 | case IP_VERSION(11, 0, 3): |
| 472 | 472 | if ((adev->gfx.me_fw_version >= 1505) && |
| 473 | 473 | (adev->gfx.pfp_fw_version >= 1600) && |
| 474 | − (adev->gfx.mec_fw_version >= 512)) | |
| 475 | − adev->gfx.cp_gfx_shadow = true; | |
| 474 | + (adev->gfx.mec_fw_version >= 512)) { | |
| 475 | + if (amdgpu_sriov_vf(adev)) | |
| 476 | + adev->gfx.cp_gfx_shadow = true; | |
| 477 | + else | |
| 478 | + adev->gfx.cp_gfx_shadow = false; | |
| 479 | + } | |
| 476 | 480 | break; |
| 477 | 481 | default: |
| 478 | 482 | adev->gfx.cp_gfx_shadow = false; |
| @@ -46,6 +46,7 @@ MODULE_FIRMWARE("amdgpu/gc_9_4_3_rlc.bin"); · 45 unmodified lines | ||
| 46 | 46 | #define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L |
| 47 | 47 | |
| 48 | 48 | #define GOLDEN_GB_ADDR_CONFIG 0x2a114042 |
| 49 | +#define CP_HQD_PERSISTENT_STATE_DEFAULT 0xbe05301 | |
| 49 | 50 | |
| 50 | 51 | struct amdgpu_gfx_ras gfx_v9_4_3_ras; |
| 51 | 52 | |
| @@ -1736,7 +1737,7 @@ static int gfx_v9_4_3_xcc_q_fini_register(struct amdgpu_ring *ring, · 1684 unmodified lines | ||
| 1736 | 1737 | |
| 1737 | 1738 | WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id), regCP_HQD_IQ_TIMER, 0); |
| 1738 | 1739 | WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id), regCP_HQD_IB_CONTROL, 0); |
| 1739 | − WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id), regCP_HQD_PERSISTENT_STATE, 0); | |
| 1740 | + WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id), regCP_HQD_PERSISTENT_STATE, CP_HQD_PERSISTENT_STATE_DEFAULT); | |
| 1740 | 1741 | WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id), regCP_HQD_PQ_DOORBELL_CONTROL, 0x40000000); |
| 1741 | 1742 | WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id), regCP_HQD_PQ_DOORBELL_CONTROL, 0); |
| 1742 | 1743 | WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id), regCP_HQD_PQ_RPTR, 0); |
| @@ -402,18 +402,15 @@ static void gfxhub_v1_2_xcc_program_invalidation(struct amdgpu_device *adev, · 401 unmodified lines | ||
| 402 | 402 | static int gfxhub_v1_2_xcc_gart_enable(struct amdgpu_device *adev, |
| 403 | 403 | uint32_t xcc_mask) |
| 404 | 404 | { |
| 405 | − uint32_t tmp_mask; | |
| 406 | 405 | int i; |
| 407 | 406 | |
| 408 | − tmp_mask = xcc_mask; | |
| 409 | 407 | /* |
| 410 | 408 | * MC_VM_FB_LOCATION_BASE/TOP is NULL for VF, because they are |
| 411 | 409 | * VF copy registers so vbios post doesn't program them, for |
| 412 | 410 | * SRIOV driver need to program them |
| 413 | 411 | */ |
| 414 | 412 | if (amdgpu_sriov_vf(adev)) { |
| 415 | − for_each_inst(i, tmp_mask) { | |
| 416 | − i = ffs(tmp_mask) - 1; | |
| 413 | + for_each_inst(i, xcc_mask) { | |
| 417 | 414 | WREG32_SOC15_RLC(GC, GET_INST(GC, i), regMC_VM_FB_LOCATION_BASE, |
| 418 | 415 | adev->gmc.vram_start >> 24); |
| 419 | 416 | WREG32_SOC15_RLC(GC, GET_INST(GC, i), regMC_VM_FB_LOCATION_TOP, |
| @@ -137,14 +137,15 @@ static int psp_v13_0_wait_for_bootloader(struct psp_context *psp) · 136 unmodified lines | ||
| 137 | 137 | int ret; |
| 138 | 138 | int retry_loop; |
| 139 | 139 | |
| 140 | + /* Wait for bootloader to signify that it is ready having bit 31 of | |
| 141 | + * C2PMSG_35 set to 1. All other bits are expected to be cleared. | |
| 142 | + * If there is an error in processing command, bits[7:0] will be set. | |
| 143 | + * This is applicable for PSP v13.0.6 and newer. | |
| 144 | + */ | |
| 140 | 145 | for (retry_loop = 0; retry_loop < 10; retry_loop++) { |
| 141 | − /* Wait for bootloader to signify that is | |
| 142 | − ready having bit 31 of C2PMSG_35 set to 1 */ | |
| 143 | − ret = psp_wait_for(psp, | |
| 144 | − SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_35), | |
| 145 | − 0x80000000, | |
| 146 | − 0x80000000, | |
| 147 | − false); | |
| 146 | + ret = psp_wait_for( | |
| 147 | + psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_35), | |
| 148 | + 0x80000000, 0xffffffff, false); | |
| 148 | 149 | |
| 149 | 150 | if (ret == 0) |
| 150 | 151 | return 0; |
| @@ -1543,11 +1543,7 @@ static bool kfd_ignore_crat(void) · 1542 unmodified lines | ||
| 1543 | 1543 | if (ignore_crat) |
| 1544 | 1544 | return true; |
| 1545 | 1545 | |
| 1546 | −#ifndef KFD_SUPPORT_IOMMU_V2 | |
| 1547 | 1546 | ret = true; |
| 1548 | −#else | |
| 1549 | − ret = false; | |
| 1550 | −#endif | |
| 1551 | 1547 | |
| 1552 | 1548 | return ret; |
| 1553 | 1549 | } |
| @@ -302,8 +302,7 @@ static int kfd_dbg_set_queue_workaround(struct queue *q, bool enable) · 301 unmodified lines | ||
| 302 | 302 | if (!q) |
| 303 | 303 | return 0; |
| 304 | 304 | |
| 305 | − if (KFD_GC_VERSION(q->device) < IP_VERSION(11, 0, 0) || | |
| 306 | − KFD_GC_VERSION(q->device) >= IP_VERSION(12, 0, 0)) | |
| 305 | + if (!kfd_dbg_has_cwsr_workaround(q->device)) | |
| 307 | 306 | return 0; |
| 308 | 307 | |
| 309 | 308 | if (enable && q->properties.is_user_cu_masked) |
| @@ -349,7 +348,7 @@ int kfd_dbg_set_mes_debug_mode(struct kfd_process_device *pdd) · 39 unmodified lines | ||
| 349 | 348 | { |
| 350 | 349 | uint32_t spi_dbg_cntl = pdd->spi_dbg_override | pdd->spi_dbg_launch_mode; |
| 351 | 350 | uint32_t flags = pdd->process->dbg_flags; |
| 352 | − bool sq_trap_en = !!spi_dbg_cntl; | |
| 351 | + bool sq_trap_en = !!spi_dbg_cntl || !kfd_dbg_has_cwsr_workaround(pdd->dev); | |
| 353 | 352 | |
| 354 | 353 | if (!kfd_dbg_is_per_vmid_supported(pdd->dev)) |
| 355 | 354 | return 0; |
| @@ -100,6 +100,12 @@ static inline bool kfd_dbg_is_rlc_restore_supported(struct kfd_node *dev) · 99 unmodified lines | ||
| 100 | 100 | KFD_GC_VERSION(dev) == IP_VERSION(10, 1, 1)); |
| 101 | 101 | } |
| 102 | 102 | |
| 103 | +static inline bool kfd_dbg_has_cwsr_workaround(struct kfd_node *dev) | |
| 104 | +{ | |
| 105 | + return KFD_GC_VERSION(dev) >= IP_VERSION(11, 0, 0) && | |
| 106 | + KFD_GC_VERSION(dev) <= IP_VERSION(11, 0, 3); | |
| 107 | +} | |
| 108 | + | |
| 103 | 109 | static inline bool kfd_dbg_has_gws_support(struct kfd_node *dev) |
| 104 | 110 | { |
| 105 | 111 | if ((KFD_GC_VERSION(dev) == IP_VERSION(9, 0, 1) |
| @@ -194,11 +194,6 @@ static void kfd_device_info_init(struct kfd_dev *kfd, · 193 unmodified lines | ||
| 194 | 194 | |
| 195 | 195 | kfd_device_info_set_event_interrupt_class(kfd); |
| 196 | 196 | |
| 197 | − /* Raven */ | |
| 198 | − if (gc_version == IP_VERSION(9, 1, 0) || | |
| 199 | − gc_version == IP_VERSION(9, 2, 2)) | |
| 200 | − kfd->device_info.needs_iommu_device = true; | |
| 201 | − | |
| 202 | 197 | if (gc_version < IP_VERSION(11, 0, 0)) { |
| 203 | 198 | /* Navi2x+, Navi1x+ */ |
| 204 | 199 | if (gc_version == IP_VERSION(10, 3, 6)) |
| @@ -233,10 +228,6 @@ static void kfd_device_info_init(struct kfd_dev *kfd, · 28 unmodified lines | ||
| 233 | 228 | asic_type != CHIP_TONGA) |
| 234 | 229 | kfd->device_info.supports_cwsr = true; |
| 235 | 230 | |
| 236 | − if (asic_type == CHIP_KAVERI || | |
| 237 | − asic_type == CHIP_CARRIZO) | |
| 238 | − kfd->device_info.needs_iommu_device = true; | |
| 239 | − | |
| 240 | 231 | if (asic_type != CHIP_HAWAII && !vf) |
| 241 | 232 | kfd->device_info.needs_pci_atomics = true; |
| 242 | 233 | } |
| @@ -249,7 +240,6 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf) · 6 unmodified lines | ||
| 249 | 240 | uint32_t gfx_target_version = 0; |
| 250 | 241 | |
| 251 | 242 | switch (adev->asic_type) { |
| 252 | −#ifdef KFD_SUPPORT_IOMMU_V2 | |
| 253 | 243 | #ifdef CONFIG_DRM_AMDGPU_CIK |
| 254 | 244 | case CHIP_KAVERI: |
| 255 | 245 | gfx_target_version = 70000; |
| @@ -262,7 +252,6 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf) · 6 unmodified lines | ||
| 262 | 252 | if (!vf) |
| 263 | 253 | f2g = &gfx_v8_kfd2kgd; |
| 264 | 254 | break; |
| 265 | −#endif | |
| 266 | 255 | #ifdef CONFIG_DRM_AMDGPU_CIK |
| 267 | 256 | case CHIP_HAWAII: |
| 268 | 257 | gfx_target_version = 70001; |
| @@ -298,7 +287,6 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf) · 29 unmodified lines | ||
| 298 | 287 | gfx_target_version = 90000; |
| 299 | 288 | f2g = &gfx_v9_kfd2kgd; |
| 300 | 289 | break; |
| 301 | −#ifdef KFD_SUPPORT_IOMMU_V2 | |
| 302 | 290 | /* Raven */ |
| 303 | 291 | case IP_VERSION(9, 1, 0): |
| 304 | 292 | case IP_VERSION(9, 2, 2): |
| @@ -306,7 +294,6 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf) · 1 unmodified line | ||
| 306 | 294 | if (!vf) |
| 307 | 295 | f2g = &gfx_v9_kfd2kgd; |
| 308 | 296 | break; |
| 309 | −#endif | |
| 310 | 297 | /* Vega12 */ |
| 311 | 298 | case IP_VERSION(9, 2, 1): |
| 312 | 299 | gfx_target_version = 90004; |
| @@ -226,8 +226,7 @@ static int add_queue_mes(struct device_queue_manager *dqm, struct queue *q, · 225 unmodified lines | ||
| 226 | 226 | queue_input.paging = false; |
| 227 | 227 | queue_input.tba_addr = qpd->tba_addr; |
| 228 | 228 | queue_input.tma_addr = qpd->tma_addr; |
| 229 | − queue_input.trap_en = KFD_GC_VERSION(q->device) < IP_VERSION(11, 0, 0) || | |
| 230 | − KFD_GC_VERSION(q->device) > IP_VERSION(11, 0, 3); | |
| 229 | + queue_input.trap_en = !kfd_dbg_has_cwsr_workaround(q->device); | |
| 231 | 230 | queue_input.skip_process_ctx_clear = qpd->pqm->process->debug_trap_enabled; |
| 232 | 231 | |
| 233 | 232 | queue_type = convert_to_mes_queue_type(q->properties.type); |
| @@ -1806,8 +1805,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, · 1572 unmodified lines | ||
| 1806 | 1805 | */ |
| 1807 | 1806 | q->properties.is_evicted = !!qpd->evicted; |
| 1808 | 1807 | q->properties.is_dbg_wa = qpd->pqm->process->debug_trap_enabled && |
| 1809 | − KFD_GC_VERSION(q->device) >= IP_VERSION(11, 0, 0) && | |
| 1810 | − KFD_GC_VERSION(q->device) <= IP_VERSION(11, 0, 3); | |
| 1808 | + kfd_dbg_has_cwsr_workaround(q->device); | |
| 1811 | 1809 | |
| 1812 | 1810 | if (qd) |
| 1813 | 1811 | mqd_mgr->restore_mqd(mqd_mgr, &q->mqd, q->mqd_mem_obj, &q->gart_mqd_addr, |
| @@ -2540,18 +2538,12 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_node *dev) · 726 unmodified lines | ||
| 2540 | 2538 | } |
| 2541 | 2539 | |
| 2542 | 2540 | switch (dev->adev->asic_type) { |
| 2543 | − case CHIP_CARRIZO: | |
| 2544 | − device_queue_manager_init_vi(&dqm->asic_ops); | |
| 2545 | − break; | |
| 2546 | − | |
| 2547 | 2541 | case CHIP_KAVERI: |
| 2548 | − device_queue_manager_init_cik(&dqm->asic_ops); | |
| 2549 | − break; | |
| 2550 | − | |
| 2551 | 2542 | case CHIP_HAWAII: |
| 2552 | 2543 | device_queue_manager_init_cik_hawaii(&dqm->asic_ops); |
| 2553 | 2544 | break; |
| 2554 | 2545 | |
| 2546 | + case CHIP_CARRIZO: | |
| 2555 | 2547 | case CHIP_TONGA: |
| 2556 | 2548 | case CHIP_FIJI: |
| 2557 | 2549 | case CHIP_POLARIS10: |
| @@ -1638,9 +1638,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 1637 unmodified lines | ||
| 1638 | 1638 | } |
| 1639 | 1639 | break; |
| 1640 | 1640 | } |
| 1641 | − if (init_data.flags.gpu_vm_support && | |
| 1642 | − (amdgpu_sg_display == 0)) | |
| 1643 | − init_data.flags.gpu_vm_support = false; | |
| 1641 | + if (init_data.flags.gpu_vm_support) | |
| 1642 | + init_data.flags.gpu_vm_support = amdgpu_sg_display_supported(adev); | |
| 1644 | 1643 | |
| 1645 | 1644 | if (init_data.flags.gpu_vm_support) |
| 1646 | 1645 | adev->mode_info.gpu_vm_support = true; |
| @@ -706,7 +706,7 @@ void dm_handle_mst_sideband_msg_ready_event( · 705 unmodified lines | ||
| 706 | 706 | |
| 707 | 707 | if (retry == 3) { |
| 708 | 708 | DRM_ERROR("Failed to ack MST event.\n"); |
| 709 | − return; | |
| 709 | + break; | |
| 710 | 710 | } |
| 711 | 711 | |
| 712 | 712 | drm_dp_mst_hpd_irq_send_new_request(&aconnector->mst_mgr); |
| @@ -1320,7 +1320,7 @@ int compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, · 607 unmodified lines | ||
| 1320 | 1320 | if (computed_streams[i]) |
| 1321 | 1321 | continue; |
| 1322 | 1322 | |
| 1323 | − if (!res_pool->funcs->remove_stream_from_ctx || | |
| 1323 | + if (res_pool->funcs->remove_stream_from_ctx && | |
| 1324 | 1324 | res_pool->funcs->remove_stream_from_ctx(stream->ctx->dc, dc_state, stream) != DC_OK) |
| 1325 | 1325 | return -EINVAL; |
| 1326 | 1326 | |
| @@ -777,7 +777,8 @@ void dce110_edp_wait_for_hpd_ready( · 776 unmodified lines | ||
| 777 | 777 | dal_gpio_destroy_irq(&hpd); |
| 778 | 778 | |
| 779 | 779 | /* ensure that the panel is detected */ |
| 780 | − ASSERT(edp_hpd_high); | |
| 780 | + if (!edp_hpd_high) | |
| 781 | + DC_LOG_DC("%s: wait timed out!\n", __func__); | |
| 781 | 782 | } |
| 782 | 783 | |
| 783 | 784 | void dce110_edp_power_control( |
| @@ -1792,10 +1793,13 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) · 1008 unmodified lines | ||
| 1792 | 1793 | hws->funcs.edp_backlight_control(edp_link_with_sink, false); |
| 1793 | 1794 | } |
| 1794 | 1795 | /*resume from S3, no vbios posting, no need to power down again*/ |
| 1796 | + clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr); | |
| 1797 | + | |
| 1795 | 1798 | power_down_all_hw_blocks(dc); |
| 1796 | 1799 | disable_vga_and_power_gate_all_controllers(dc); |
| 1797 | 1800 | if (edp_link_with_sink && !keep_edp_vdd_on) |
| 1798 | 1801 | dc->hwss.edp_power_control(edp_link_with_sink, false); |
| 1802 | + clk_mgr_optimize_pwr_state(dc, dc->clk_mgr); | |
| 1799 | 1803 | } |
| 1800 | 1804 | bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 1); |
| 1801 | 1805 | } |
| @@ -357,8 +357,11 @@ void dpp3_set_cursor_attributes( · 356 unmodified lines | ||
| 357 | 357 | int cur_rom_en = 0; |
| 358 | 358 | |
| 359 | 359 | if (color_format == CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA || |
| 360 | − color_format == CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA) | |
| 361 | − cur_rom_en = 1; | |
| 360 | + color_format == CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA) { | |
| 361 | + if (cursor_attributes->attribute_flags.bits.ENABLE_CURSOR_DEGAMMA) { | |
| 362 | + cur_rom_en = 1; | |
| 363 | + } | |
| 364 | + } | |
| 362 | 365 | |
| 363 | 366 | REG_UPDATE_3(CURSOR0_CONTROL, |
| 364 | 367 | CUR0_MODE, color_format, |
| @@ -84,7 +84,8 @@ static enum phyd32clk_clock_source get_phy_mux_symclk( · 83 unmodified lines | ||
| 84 | 84 | struct dcn_dccg *dccg_dcn, |
| 85 | 85 | enum phyd32clk_clock_source src) |
| 86 | 86 | { |
| 87 | − if (dccg_dcn->base.ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { | |
| 87 | + if (dccg_dcn->base.ctx->asic_id.chip_family == FAMILY_YELLOW_CARP && | |
| 88 | + dccg_dcn->base.ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { | |
| 88 | 89 | if (src == PHYD32CLKC) |
| 89 | 90 | src = PHYD32CLKF; |
| 90 | 91 | if (src == PHYD32CLKD) |
| @@ -49,7 +49,10 @@ static void dccg32_trigger_dio_fifo_resync( · 48 unmodified lines | ||
| 49 | 49 | uint32_t dispclk_rdivider_value = 0; |
| 50 | 50 | |
| 51 | 51 | REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_RDIVIDER, &dispclk_rdivider_value); |
| 52 | − REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value); | |
| 52 | + | |
| 53 | + /* Not valid for the WDIVIDER to be set to 0 */ | |
| 54 | + if (dispclk_rdivider_value != 0) | |
| 55 | + REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value); | |
| 53 | 56 | } |
| 54 | 57 | |
| 55 | 58 | static void dccg32_get_pixel_rate_div( |
| @@ -1581,9 +1581,9 @@ static int smu_disable_dpms(struct smu_context *smu) · 1580 unmodified lines | ||
| 1581 | 1581 | |
| 1582 | 1582 | /* |
| 1583 | 1583 | * For SMU 13.0.4/11, PMFW will handle the features disablement properly |
| 1584 | − * for gpu reset case. Driver involvement is unnecessary. | |
| 1584 | + * for gpu reset and S0i3 cases. Driver involvement is unnecessary. | |
| 1585 | 1585 | */ |
| 1586 | − if (amdgpu_in_reset(adev)) { | |
| 1586 | + if (amdgpu_in_reset(adev) || adev->in_s0ix) { | |
| 1587 | 1587 | switch (adev->ip_versions[MP1_HWIP][0]) { |
| 1588 | 1588 | case IP_VERSION(13, 0, 4): |
| 1589 | 1589 | case IP_VERSION(13, 0, 11): |
| @@ -331,11 +331,13 @@ static int smu_v13_0_0_check_powerplay_table(struct smu_context *smu) · 330 unmodified lines | ||
| 331 | 331 | struct smu_13_0_0_powerplay_table *powerplay_table = |
| 332 | 332 | table_context->power_play_table; |
| 333 | 333 | struct smu_baco_context *smu_baco = &smu->smu_baco; |
| 334 | +#if 0 | |
| 334 | 335 | PPTable_t *pptable = smu->smu_table.driver_pptable; |
| 335 | 336 | const OverDriveLimits_t * const overdrive_upperlimits = |
| 336 | 337 | &pptable->SkuTable.OverDriveLimitsBasicMax; |
| 337 | 338 | const OverDriveLimits_t * const overdrive_lowerlimits = |
| 338 | 339 | &pptable->SkuTable.OverDriveLimitsMin; |
| 340 | +#endif | |
| 339 | 341 | |
| 340 | 342 | if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_HARDWAREDC) |
| 341 | 343 | smu->dc_controlled_by_gpio = true; |
| @@ -347,18 +349,27 @@ static int smu_v13_0_0_check_powerplay_table(struct smu_context *smu) · 5 unmodified lines | ||
| 347 | 349 | if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_MACO) |
| 348 | 350 | smu_baco->maco_support = true; |
| 349 | 351 | |
| 352 | + /* | |
| 353 | + * We are in the transition to a new OD mechanism. | |
| 354 | + * Disable the OD feature support for SMU13 temporarily. | |
| 355 | + * TODO: get this reverted when new OD mechanism online | |
| 356 | + */ | |
| 357 | +#if 0 | |
| 350 | 358 | if (!overdrive_lowerlimits->FeatureCtrlMask || |
| 351 | 359 | !overdrive_upperlimits->FeatureCtrlMask) |
| 352 | 360 | smu->od_enabled = false; |
| 353 | 361 | |
| 354 | − table_context->thermal_controller_type = | |
| 355 | − powerplay_table->thermal_controller_type; | |
| 356 | − | |
| 357 | 362 | /* |
| 358 | 363 | * Instead of having its own buffer space and get overdrive_table copied, |
| 359 | 364 | * smu->od_settings just points to the actual overdrive_table |
| 360 | 365 | */ |
| 361 | 366 | smu->od_settings = &powerplay_table->overdrive_table; |
| 367 | +#else | |
| 368 | + smu->od_enabled = false; | |
| 369 | +#endif | |
| 370 | + | |
| 371 | + table_context->thermal_controller_type = | |
| 372 | + powerplay_table->thermal_controller_type; | |
| 362 | 373 | |
| 363 | 374 | return 0; |
| 364 | 375 | } |
| @@ -1140,7 +1151,6 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, · 775 unmodified lines | ||
| 1140 | 1151 | (OverDriveTableExternal_t *)smu->smu_table.overdrive_table; |
| 1141 | 1152 | struct smu_13_0_dpm_table *single_dpm_table; |
| 1142 | 1153 | struct smu_13_0_pcie_table *pcie_table; |
| 1143 | − const int link_width[] = {0, 1, 2, 4, 8, 12, 16}; | |
| 1144 | 1154 | uint32_t gen_speed, lane_width; |
| 1145 | 1155 | int i, curr_freq, size = 0; |
| 1146 | 1156 | int32_t min_value, max_value; |
| @@ -1256,7 +1266,7 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, · 109 unmodified lines | ||
| 1256 | 1266 | (pcie_table->pcie_lane[i] == 6) ? "x16" : "", |
| 1257 | 1267 | pcie_table->clk_freq[i], |
| 1258 | 1268 | (gen_speed == DECODE_GEN_SPEED(pcie_table->pcie_gen[i])) && |
| 1259 | − (lane_width == DECODE_LANE_WIDTH(link_width[pcie_table->pcie_lane[i]])) ? | |
| 1269 | + (lane_width == DECODE_LANE_WIDTH(pcie_table->pcie_lane[i])) ? | |
| 1260 | 1270 | "*" : ""); |
| 1261 | 1271 | break; |
| 1262 | 1272 | |
| @@ -1734,7 +1744,7 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu, · 471 unmodified lines | ||
| 1734 | 1744 | gpu_metrics->average_vclk1_frequency = metrics->AverageVclk1Frequency; |
| 1735 | 1745 | gpu_metrics->average_dclk1_frequency = metrics->AverageDclk1Frequency; |
| 1736 | 1746 | |
| 1737 | − gpu_metrics->current_gfxclk = metrics->CurrClock[PPCLK_GFXCLK]; | |
| 1747 | + gpu_metrics->current_gfxclk = gpu_metrics->average_gfxclk_frequency; | |
| 1738 | 1748 | gpu_metrics->current_socclk = metrics->CurrClock[PPCLK_SOCCLK]; |
| 1739 | 1749 | gpu_metrics->current_uclk = metrics->CurrClock[PPCLK_UCLK]; |
| 1740 | 1750 | gpu_metrics->current_vclk0 = metrics->CurrClock[PPCLK_VCLK_0]; |
| @@ -1993,9 +1993,8 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table · 1992 unmodified lines | ||
| 1993 | 1993 | |
| 1994 | 1994 | gpu_metrics->average_socket_power = |
| 1995 | 1995 | SMUQ10_TO_UINT(metrics->SocketPower); |
| 1996 | − /* Energy is reported in 15.625mJ units */ | |
| 1997 | − gpu_metrics->energy_accumulator = | |
| 1998 | − SMUQ10_TO_UINT(metrics->SocketEnergyAcc); | |
| 1996 | + /* Energy counter reported in 15.259uJ (2^-16) units */ | |
| 1997 | + gpu_metrics->energy_accumulator = metrics->SocketEnergyAcc; | |
| 1999 | 1998 | |
| 2000 | 1999 | gpu_metrics->current_gfxclk = |
| 2001 | 2000 | SMUQ10_TO_UINT(metrics->GfxclkFrequency[xcc0]); |
| @@ -323,10 +323,12 @@ static int smu_v13_0_7_check_powerplay_table(struct smu_context *smu) · 322 unmodified lines | ||
| 323 | 323 | struct smu_baco_context *smu_baco = &smu->smu_baco; |
| 324 | 324 | PPTable_t *smc_pptable = table_context->driver_pptable; |
| 325 | 325 | BoardTable_t *BoardTable = &smc_pptable->BoardTable; |
| 326 | +#if 0 | |
| 326 | 327 | const OverDriveLimits_t * const overdrive_upperlimits = |
| 327 | 328 | &smc_pptable->SkuTable.OverDriveLimitsBasicMax; |
| 328 | 329 | const OverDriveLimits_t * const overdrive_lowerlimits = |
| 329 | 330 | &smc_pptable->SkuTable.OverDriveLimitsMin; |
| 331 | +#endif | |
| 330 | 332 | |
| 331 | 333 | if (powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_HARDWAREDC) |
| 332 | 334 | smu->dc_controlled_by_gpio = true; |
| @@ -338,18 +340,22 @@ static int smu_v13_0_7_check_powerplay_table(struct smu_context *smu) · 5 unmodified lines | ||
| 338 | 340 | if (smu_baco->platform_support && (BoardTable->HsrEnabled || BoardTable->VddqOffEnabled)) |
| 339 | 341 | smu_baco->maco_support = true; |
| 340 | 342 | |
| 343 | +#if 0 | |
| 341 | 344 | if (!overdrive_lowerlimits->FeatureCtrlMask || |
| 342 | 345 | !overdrive_upperlimits->FeatureCtrlMask) |
| 343 | 346 | smu->od_enabled = false; |
| 344 | 347 | |
| 345 | − table_context->thermal_controller_type = | |
| 346 | − powerplay_table->thermal_controller_type; | |
| 347 | − | |
| 348 | 348 | /* |
| 349 | 349 | * Instead of having its own buffer space and get overdrive_table copied, |
| 350 | 350 | * smu->od_settings just points to the actual overdrive_table |
| 351 | 351 | */ |
| 352 | 352 | smu->od_settings = &powerplay_table->overdrive_table; |
| 353 | +#else | |
| 354 | + smu->od_enabled = false; | |
| 355 | +#endif | |
| 356 | + | |
| 357 | + table_context->thermal_controller_type = | |
| 358 | + powerplay_table->thermal_controller_type; | |
| 353 | 359 | |
| 354 | 360 | return 0; |
| 355 | 361 | } |
| @@ -2517,9 +2517,11 @@ static irqreturn_t it6505_int_threaded_handler(int unused, void *data) · 2516 unmodified lines | ||
| 2517 | 2517 | }; |
| 2518 | 2518 | int int_status[3], i; |
| 2519 | 2519 | |
| 2520 | − if (it6505->enable_drv_hold || pm_runtime_get_if_in_use(dev) <= 0) | |
| 2520 | + if (it6505->enable_drv_hold || !it6505->powered) | |
| 2521 | 2521 | return IRQ_HANDLED; |
| 2522 | 2522 | |
| 2523 | + pm_runtime_get_sync(dev); | |
| 2524 | + | |
| 2523 | 2525 | int_status[0] = it6505_read(it6505, INT_STATUS_01); |
| 2524 | 2526 | int_status[1] = it6505_read(it6505, INT_STATUS_02); |
| 2525 | 2527 | int_status[2] = it6505_read(it6505, INT_STATUS_03); |
| @@ -774,9 +774,7 @@ static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611, · 773 unmodified lines | ||
| 774 | 774 | dsi->lanes = 4; |
| 775 | 775 | dsi->format = MIPI_DSI_FMT_RGB888; |
| 776 | 776 | dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | |
| 777 | − MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO_NO_HSA | | |
| 778 | − MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP | | |
| 779 | − MIPI_DSI_MODE_NO_EOT_PACKET; | |
| 777 | + MIPI_DSI_MODE_VIDEO_HSE; | |
| 780 | 778 | |
| 781 | 779 | ret = devm_mipi_dsi_attach(dev, dsi); |
| 782 | 780 | if (ret < 0) { |
| @@ -623,7 +623,13 @@ int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct · 622 unmodified lines | ||
| 623 | 623 | int ret; |
| 624 | 624 | |
| 625 | 625 | if (obj->import_attach) { |
| 626 | + /* Reset both vm_ops and vm_private_data, so we don't end up with | |
| 627 | + * vm_ops pointing to our implementation if the dma-buf backend | |
| 628 | + * doesn't set those fields. | |
| 629 | + */ | |
| 626 | 630 | vma->vm_private_data = NULL; |
| 631 | + vma->vm_ops = NULL; | |
| 632 | + | |
| 627 | 633 | ret = dma_buf_mmap(obj->dma_buf, vma, 0); |
| 628 | 634 | |
| 629 | 635 | /* Drop the reference drm_gem_mmap_obj() acquired.*/ |
| @@ -166,6 +166,8 @@ struct i915_vma *intel_dpt_pin(struct i915_address_space *vm) · 165 unmodified lines | ||
| 166 | 166 | i915_vma_get(vma); |
| 167 | 167 | } |
| 168 | 168 | |
| 169 | + dpt->obj->mm.dirty = true; | |
| 170 | + | |
| 169 | 171 | atomic_dec(&i915->gpu_error.pending_fb_pin); |
| 170 | 172 | intel_runtime_pm_put(&i915->runtime_pm, wakeref); |
| 171 | 173 | |
| @@ -261,7 +263,7 @@ intel_dpt_create(struct intel_framebuffer *fb) · 89 unmodified lines | ||
| 261 | 263 | dpt_obj = i915_gem_object_create_stolen(i915, size); |
| 262 | 264 | if (IS_ERR(dpt_obj) && !HAS_LMEM(i915)) { |
| 263 | 265 | drm_dbg_kms(&i915->drm, "Allocating dpt from smem\n"); |
| 264 | − dpt_obj = i915_gem_object_create_internal(i915, size); | |
| 266 | + dpt_obj = i915_gem_object_create_shmem(i915, size); | |
| 265 | 267 | } |
| 266 | 268 | if (IS_ERR(dpt_obj)) |
| 267 | 269 | return ERR_CAST(dpt_obj); |
| @@ -1246,8 +1246,10 @@ static int igt_write_huge(struct drm_i915_private *i915, · 1245 unmodified lines | ||
| 1246 | 1246 | * times in succession a possibility by enlarging the permutation array. |
| 1247 | 1247 | */ |
| 1248 | 1248 | order = i915_random_order(count * count, &prng); |
| 1249 | − if (!order) | |
| 1250 | − return -ENOMEM; | |
| 1249 | + if (!order) { | |
| 1250 | + err = -ENOMEM; | |
| 1251 | + goto out; | |
| 1252 | + } | |
| 1251 | 1253 | |
| 1252 | 1254 | max_page_size = rounddown_pow_of_two(obj->mm.page_sizes.sg); |
| 1253 | 1255 | max = div_u64(max - size, max_page_size); |
| @@ -165,14 +165,60 @@ static u32 preparser_disable(bool state) · 164 unmodified lines | ||
| 165 | 165 | return MI_ARB_CHECK | 1 << 8 | state; |
| 166 | 166 | } |
| 167 | 167 | |
| 168 | −u32 *gen12_emit_aux_table_inv(struct intel_gt *gt, u32 *cs, const i915_reg_t inv_reg) | |
| 168 | +static i915_reg_t gen12_get_aux_inv_reg(struct intel_engine_cs *engine) | |
| 169 | 169 | { |
| 170 | − u32 gsi_offset = gt->uncore->gsi_offset; | |
| 170 | + switch (engine->id) { | |
| 171 | + case RCS0: | |
| 172 | + return GEN12_CCS_AUX_INV; | |
| 173 | + case BCS0: | |
| 174 | + return GEN12_BCS0_AUX_INV; | |
| 175 | + case VCS0: | |
| 176 | + return GEN12_VD0_AUX_INV; | |
| 177 | + case VCS2: | |
| 178 | + return GEN12_VD2_AUX_INV; | |
| 179 | + case VECS0: | |
| 180 | + return GEN12_VE0_AUX_INV; | |
| 181 | + case CCS0: | |
| 182 | + return GEN12_CCS0_AUX_INV; | |
| 183 | + default: | |
| 184 | + return INVALID_MMIO_REG; | |
| 185 | + } | |
| 186 | +} | |
| 187 | + | |
| 188 | +static bool gen12_needs_ccs_aux_inv(struct intel_engine_cs *engine) | |
| 189 | +{ | |
| 190 | + i915_reg_t reg = gen12_get_aux_inv_reg(engine); | |
| 191 | + | |
| 192 | + if (IS_PONTEVECCHIO(engine->i915)) | |
| 193 | + return false; | |
| 194 | + | |
| 195 | + /* | |
| 196 | + * So far platforms supported by i915 having flat ccs do not require | |
| 197 | + * AUX invalidation. Check also whether the engine requires it. | |
| 198 | + */ | |
| 199 | + return i915_mmio_reg_valid(reg) && !HAS_FLAT_CCS(engine->i915); | |
| 200 | +} | |
| 201 | + | |
| 202 | +u32 *gen12_emit_aux_table_inv(struct intel_engine_cs *engine, u32 *cs) | |
| 203 | +{ | |
| 204 | + i915_reg_t inv_reg = gen12_get_aux_inv_reg(engine); | |
| 205 | + u32 gsi_offset = engine->gt->uncore->gsi_offset; | |
| 206 | + | |
| 207 | + if (!gen12_needs_ccs_aux_inv(engine)) | |
| 208 | + return cs; | |
| 171 | 209 | |
| 172 | 210 | *cs++ = MI_LOAD_REGISTER_IMM(1) | MI_LRI_MMIO_REMAP_EN; |
| 173 | 211 | *cs++ = i915_mmio_reg_offset(inv_reg) + gsi_offset; |
| 174 | 212 | *cs++ = AUX_INV; |
| 175 | − *cs++ = MI_NOOP; | |
| 213 | + | |
| 214 | + *cs++ = MI_SEMAPHORE_WAIT_TOKEN | | |
| 215 | + MI_SEMAPHORE_REGISTER_POLL | | |
| 216 | + MI_SEMAPHORE_POLL | | |
| 217 | + MI_SEMAPHORE_SAD_EQ_SDD; | |
| 218 | + *cs++ = 0; | |
| 219 | + *cs++ = i915_mmio_reg_offset(inv_reg) + gsi_offset; | |
| 220 | + *cs++ = 0; | |
| 221 | + *cs++ = 0; | |
| 176 | 222 | |
| 177 | 223 | return cs; |
| 178 | 224 | } |
| @@ -202,8 +248,13 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode) · 23 unmodified lines | ||
| 202 | 248 | { |
| 203 | 249 | struct intel_engine_cs *engine = rq->engine; |
| 204 | 250 | |
| 205 | − if (mode & EMIT_FLUSH) { | |
| 206 | − u32 flags = 0; | |
| 251 | + /* | |
| 252 | + * On Aux CCS platforms the invalidation of the Aux | |
| 253 | + * table requires quiescing memory traffic beforehand | |
| 254 | + */ | |
| 255 | + if (mode & EMIT_FLUSH || gen12_needs_ccs_aux_inv(engine)) { | |
| 256 | + u32 bit_group_0 = 0; | |
| 257 | + u32 bit_group_1 = 0; | |
| 207 | 258 | int err; |
| 208 | 259 | u32 *cs; |
| 209 | 260 | |
| @@ -211,32 +262,40 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode) · 1 unmodified line | ||
| 211 | 262 | if (err) |
| 212 | 263 | return err; |
| 213 | 264 | |
| 214 | − flags |= PIPE_CONTROL_TILE_CACHE_FLUSH; | |
| 215 | − flags |= PIPE_CONTROL_FLUSH_L3; | |
| 216 | − flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; | |
| 217 | − flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; | |
| 265 | + bit_group_0 |= PIPE_CONTROL0_HDC_PIPELINE_FLUSH; | |
| 266 | + | |
| 267 | + /* | |
| 268 | + * When required, in MTL and beyond platforms we | |
| 269 | + * need to set the CCS_FLUSH bit in the pipe control | |
| 270 | + */ | |
| 271 | + if (GRAPHICS_VER_FULL(rq->i915) >= IP_VER(12, 70)) | |
| 272 | + bit_group_0 |= PIPE_CONTROL_CCS_FLUSH; | |
| 273 | + | |
| 274 | + bit_group_1 |= PIPE_CONTROL_TILE_CACHE_FLUSH; | |
| 275 | + bit_group_1 |= PIPE_CONTROL_FLUSH_L3; | |
| 276 | + bit_group_1 |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; | |
| 277 | + bit_group_1 |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; | |
| 218 | 278 | /* Wa_1409600907:tgl,adl-p */ |
| 219 | − flags |= PIPE_CONTROL_DEPTH_STALL; | |
| 220 | − flags |= PIPE_CONTROL_DC_FLUSH_ENABLE; | |
| 221 | − flags |= PIPE_CONTROL_FLUSH_ENABLE; | |
| 279 | + bit_group_1 |= PIPE_CONTROL_DEPTH_STALL; | |
| 280 | + bit_group_1 |= PIPE_CONTROL_DC_FLUSH_ENABLE; | |
| 281 | + bit_group_1 |= PIPE_CONTROL_FLUSH_ENABLE; | |
| 222 | 282 | |
| 223 | − flags |= PIPE_CONTROL_STORE_DATA_INDEX; | |
| 224 | − flags |= PIPE_CONTROL_QW_WRITE; | |
| 283 | + bit_group_1 |= PIPE_CONTROL_STORE_DATA_INDEX; | |
| 284 | + bit_group_1 |= PIPE_CONTROL_QW_WRITE; | |
| 225 | 285 | |
| 226 | − flags |= PIPE_CONTROL_CS_STALL; | |
| 286 | + bit_group_1 |= PIPE_CONTROL_CS_STALL; | |
| 227 | 287 | |
| 228 | 288 | if (!HAS_3D_PIPELINE(engine->i915)) |
| 229 | − flags &= ~PIPE_CONTROL_3D_ARCH_FLAGS; | |
| 289 | + bit_group_1 &= ~PIPE_CONTROL_3D_ARCH_FLAGS; | |
| 230 | 290 | else if (engine->class == COMPUTE_CLASS) |
| 231 | − flags &= ~PIPE_CONTROL_3D_ENGINE_FLAGS; | |
| 291 | + bit_group_1 &= ~PIPE_CONTROL_3D_ENGINE_FLAGS; | |
| 232 | 292 | |
| 233 | 293 | cs = intel_ring_begin(rq, 6); |
| 234 | 294 | if (IS_ERR(cs)) |
| 235 | 295 | return PTR_ERR(cs); |
| 236 | 296 | |
| 237 | − cs = gen12_emit_pipe_control(cs, | |
| 238 | − PIPE_CONTROL0_HDC_PIPELINE_FLUSH, | |
| 239 | − flags, LRC_PPHWSP_SCRATCH_ADDR); | |
| 297 | + cs = gen12_emit_pipe_control(cs, bit_group_0, bit_group_1, | |
| 298 | + LRC_PPHWSP_SCRATCH_ADDR); | |
| 240 | 299 | intel_ring_advance(rq, cs); |
| 241 | 300 | } |
| 242 | 301 | |
| @@ -267,10 +326,9 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode) · 24 unmodified lines | ||
| 267 | 326 | else if (engine->class == COMPUTE_CLASS) |
| 268 | 327 | flags &= ~PIPE_CONTROL_3D_ENGINE_FLAGS; |
| 269 | 328 | |
| 270 | − if (!HAS_FLAT_CCS(rq->engine->i915)) | |
| 271 | − count = 8 + 4; | |
| 272 | − else | |
| 273 | − count = 8; | |
| 329 | + count = 8; | |
| 330 | + if (gen12_needs_ccs_aux_inv(rq->engine)) | |
| 331 | + count += 8; | |
| 274 | 332 | |
| 275 | 333 | cs = intel_ring_begin(rq, count); |
| 276 | 334 | if (IS_ERR(cs)) |
| @@ -285,11 +343,7 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode) · 8 unmodified lines | ||
| 285 | 343 | |
| 286 | 344 | cs = gen8_emit_pipe_control(cs, flags, LRC_PPHWSP_SCRATCH_ADDR); |
| 287 | 345 | |
| 288 | − if (!HAS_FLAT_CCS(rq->engine->i915)) { | |
| 289 | − /* hsdes: 1809175790 */ | |
| 290 | − cs = gen12_emit_aux_table_inv(rq->engine->gt, | |
| 291 | − cs, GEN12_GFX_CCS_AUX_NV); | |
| 292 | − } | |
| 346 | + cs = gen12_emit_aux_table_inv(engine, cs); | |
| 293 | 347 | |
| 294 | 348 | *cs++ = preparser_disable(false); |
| 295 | 349 | intel_ring_advance(rq, cs); |
| @@ -300,21 +354,14 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode) · 4 unmodified lines | ||
| 300 | 354 | |
| 301 | 355 | int gen12_emit_flush_xcs(struct i915_request *rq, u32 mode) |
| 302 | 356 | { |
| 303 | − intel_engine_mask_t aux_inv = 0; | |
| 304 | − u32 cmd, *cs; | |
| 357 | + u32 cmd = 4; | |
| 358 | + u32 *cs; | |
| 305 | 359 | |
| 306 | − cmd = 4; | |
| 307 | 360 | if (mode & EMIT_INVALIDATE) { |
| 308 | 361 | cmd += 2; |
| 309 | 362 | |
| 310 | − if (!HAS_FLAT_CCS(rq->engine->i915) && | |
| 311 | − (rq->engine->class == VIDEO_DECODE_CLASS || | |
| 312 | − rq->engine->class == VIDEO_ENHANCEMENT_CLASS)) { | |
| 313 | − aux_inv = rq->engine->mask & | |
| 314 | − ~GENMASK(_BCS(I915_MAX_BCS - 1), BCS0); | |
| 315 | − if (aux_inv) | |
| 316 | − cmd += 4; | |
| 317 | − } | |
| 363 | + if (gen12_needs_ccs_aux_inv(rq->engine)) | |
| 364 | + cmd += 8; | |
| 318 | 365 | } |
| 319 | 366 | |
| 320 | 367 | cs = intel_ring_begin(rq, cmd); |
| @@ -338,6 +385,10 @@ int gen12_emit_flush_xcs(struct i915_request *rq, u32 mode) · 17 unmodified lines | ||
| 338 | 385 | cmd |= MI_INVALIDATE_TLB; |
| 339 | 386 | if (rq->engine->class == VIDEO_DECODE_CLASS) |
| 340 | 387 | cmd |= MI_INVALIDATE_BSD; |
| 388 | + | |
| 389 | + if (gen12_needs_ccs_aux_inv(rq->engine) && | |
| 390 | + rq->engine->class == COPY_ENGINE_CLASS) | |
| 391 | + cmd |= MI_FLUSH_DW_CCS; | |
| 341 | 392 | } |
| 342 | 393 | |
| 343 | 394 | *cs++ = cmd; |
| @@ -345,14 +396,7 @@ int gen12_emit_flush_xcs(struct i915_request *rq, u32 mode) · 1 unmodified line | ||
| 345 | 396 | *cs++ = 0; /* upper addr */ |
| 346 | 397 | *cs++ = 0; /* value */ |
| 347 | 398 | |
| 348 | − if (aux_inv) { /* hsdes: 1809175790 */ | |
| 349 | − if (rq->engine->class == VIDEO_DECODE_CLASS) | |
| 350 | − cs = gen12_emit_aux_table_inv(rq->engine->gt, | |
| 351 | − cs, GEN12_VD0_AUX_NV); | |
| 352 | − else | |
| 353 | − cs = gen12_emit_aux_table_inv(rq->engine->gt, | |
| 354 | − cs, GEN12_VE0_AUX_NV); | |
| 355 | − } | |
| 399 | + cs = gen12_emit_aux_table_inv(rq->engine, cs); | |
| 356 | 400 | |
| 357 | 401 | if (mode & EMIT_INVALIDATE) |
| 358 | 402 | *cs++ = preparser_disable(false); |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include "intel_gt_regs.h" |
| 14 | 14 | #include "intel_gpu_commands.h" |
| 15 | 15 | |
| 16 | +struct intel_engine_cs; | |
| 16 | 17 | struct intel_gt; |
| 17 | 18 | struct i915_request; |
| 18 | 19 | |
| @@ -46,28 +47,32 @@ u32 *gen8_emit_fini_breadcrumb_rcs(struct i915_request *rq, u32 *cs); · 27 unmodified lines | ||
| 46 | 47 | u32 *gen11_emit_fini_breadcrumb_rcs(struct i915_request *rq, u32 *cs); |
| 47 | 48 | u32 *gen12_emit_fini_breadcrumb_rcs(struct i915_request *rq, u32 *cs); |
| 48 | 49 | |
| 49 | −u32 *gen12_emit_aux_table_inv(struct intel_gt *gt, u32 *cs, const i915_reg_t inv_reg); | |
| 50 | +u32 *gen12_emit_aux_table_inv(struct intel_engine_cs *engine, u32 *cs); | |
| 50 | 51 | |
| 51 | 52 | static inline u32 * |
| 52 | −__gen8_emit_pipe_control(u32 *batch, u32 flags0, u32 flags1, u32 offset) | |
| 53 | +__gen8_emit_pipe_control(u32 *batch, u32 bit_group_0, | |
| 54 | + u32 bit_group_1, u32 offset) | |
| 53 | 55 | { |
| 54 | 56 | memset(batch, 0, 6 * sizeof(u32)); |
| 55 | 57 | |
| 56 | − batch[0] = GFX_OP_PIPE_CONTROL(6) | flags0; | |
| 57 | − batch[1] = flags1; | |
| 58 | + batch[0] = GFX_OP_PIPE_CONTROL(6) | bit_group_0; | |
| 59 | + batch[1] = bit_group_1; | |
| 58 | 60 | batch[2] = offset; |
| 59 | 61 | |
| 60 | 62 | return batch + 6; |
| 61 | 63 | } |
| 62 | 64 | |
| 63 | −static inline u32 *gen8_emit_pipe_control(u32 *batch, u32 flags, u32 offset) | |
| 65 | +static inline u32 *gen8_emit_pipe_control(u32 *batch, | |
| 66 | + u32 bit_group_1, u32 offset) | |
| 64 | 67 | { |
| 65 | − return __gen8_emit_pipe_control(batch, 0, flags, offset); | |
| 68 | + return __gen8_emit_pipe_control(batch, 0, bit_group_1, offset); | |
| 66 | 69 | } |
| 67 | 70 | |
| 68 | −static inline u32 *gen12_emit_pipe_control(u32 *batch, u32 flags0, u32 flags1, u32 offset) | |
| 71 | +static inline u32 *gen12_emit_pipe_control(u32 *batch, u32 bit_group_0, | |
| 72 | + u32 bit_group_1, u32 offset) | |
| 69 | 73 | { |
| 70 | − return __gen8_emit_pipe_control(batch, flags0, flags1, offset); | |
| 74 | + return __gen8_emit_pipe_control(batch, bit_group_0, | |
| 75 | + bit_group_1, offset); | |
| 71 | 76 | } |
| 72 | 77 | |
| 73 | 78 | static inline u32 * |
| @@ -121,6 +121,7 @@ · 120 unmodified lines | ||
| 121 | 121 | #define MI_SEMAPHORE_TARGET(engine) ((engine)<<15) |
| 122 | 122 | #define MI_SEMAPHORE_WAIT MI_INSTR(0x1c, 2) /* GEN8+ */ |
| 123 | 123 | #define MI_SEMAPHORE_WAIT_TOKEN MI_INSTR(0x1c, 3) /* GEN12+ */ |
| 124 | +#define MI_SEMAPHORE_REGISTER_POLL (1 << 16) | |
| 124 | 125 | #define MI_SEMAPHORE_POLL (1 << 15) |
| 125 | 126 | #define MI_SEMAPHORE_SAD_GT_SDD (0 << 12) |
| 126 | 127 | #define MI_SEMAPHORE_SAD_GTE_SDD (1 << 12) |
| @@ -299,6 +300,7 @@ · 172 unmodified lines | ||
| 299 | 300 | #define PIPE_CONTROL_QW_WRITE (1<<14) |
| 300 | 301 | #define PIPE_CONTROL_POST_SYNC_OP_MASK (3<<14) |
| 301 | 302 | #define PIPE_CONTROL_DEPTH_STALL (1<<13) |
| 303 | +#define PIPE_CONTROL_CCS_FLUSH (1<<13) /* MTL+ */ | |
| 302 | 304 | #define PIPE_CONTROL_WRITE_FLUSH (1<<12) |
| 303 | 305 | #define PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH (1<<12) /* gen6+ */ |
| 304 | 306 | #define PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE (1<<11) /* MBZ on ILK */ |
| @@ -332,9 +332,11 @@ · 331 unmodified lines | ||
| 332 | 332 | #define GEN8_PRIVATE_PAT_HI _MMIO(0x40e0 + 4) |
| 333 | 333 | #define GEN10_PAT_INDEX(index) _MMIO(0x40e0 + (index) * 4) |
| 334 | 334 | #define BSD_HWS_PGA_GEN7 _MMIO(0x4180) |
| 335 | −#define GEN12_GFX_CCS_AUX_NV _MMIO(0x4208) | |
| 336 | −#define GEN12_VD0_AUX_NV _MMIO(0x4218) | |
| 337 | −#define GEN12_VD1_AUX_NV _MMIO(0x4228) | |
| 335 | + | |
| 336 | +#define GEN12_CCS_AUX_INV _MMIO(0x4208) | |
| 337 | +#define GEN12_VD0_AUX_INV _MMIO(0x4218) | |
| 338 | +#define GEN12_VE0_AUX_INV _MMIO(0x4238) | |
| 339 | +#define GEN12_BCS0_AUX_INV _MMIO(0x4248) | |
| 338 | 340 | |
| 339 | 341 | #define GEN8_RTCR _MMIO(0x4260) |
| 340 | 342 | #define GEN8_M1TCR _MMIO(0x4264) |
| @@ -342,14 +344,12 @@ · 1 unmodified line | ||
| 342 | 344 | #define GEN8_BTCR _MMIO(0x426c) |
| 343 | 345 | #define GEN8_VTCR _MMIO(0x4270) |
| 344 | 346 | |
| 345 | −#define GEN12_VD2_AUX_NV _MMIO(0x4298) | |
| 346 | −#define GEN12_VD3_AUX_NV _MMIO(0x42a8) | |
| 347 | −#define GEN12_VE0_AUX_NV _MMIO(0x4238) | |
| 348 | − | |
| 349 | 347 | #define BLT_HWS_PGA_GEN7 _MMIO(0x4280) |
| 350 | 348 | |
| 351 | −#define GEN12_VE1_AUX_NV _MMIO(0x42b8) | |
| 349 | +#define GEN12_VD2_AUX_INV _MMIO(0x4298) | |
| 350 | +#define GEN12_CCS0_AUX_INV _MMIO(0x42c8) | |
| 352 | 351 | #define AUX_INV REG_BIT(0) |
| 352 | + | |
| 353 | 353 | #define VEBOX_HWS_PGA_GEN7 _MMIO(0x4380) |
| 354 | 354 | |
| 355 | 355 | #define GEN12_AUX_ERR_DBG _MMIO(0x43f4) |
| @@ -1364,10 +1364,7 @@ gen12_emit_indirect_ctx_rcs(const struct intel_context *ce, u32 *cs) · 1363 unmodified lines | ||
| 1364 | 1364 | IS_DG2_G11(ce->engine->i915)) |
| 1365 | 1365 | cs = gen8_emit_pipe_control(cs, PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE, 0); |
| 1366 | 1366 | |
| 1367 | − /* hsdes: 1809175790 */ | |
| 1368 | − if (!HAS_FLAT_CCS(ce->engine->i915)) | |
| 1369 | − cs = gen12_emit_aux_table_inv(ce->engine->gt, | |
| 1370 | − cs, GEN12_GFX_CCS_AUX_NV); | |
| 1367 | + cs = gen12_emit_aux_table_inv(ce->engine, cs); | |
| 1371 | 1368 | |
| 1372 | 1369 | /* Wa_16014892111 */ |
| 1373 | 1370 | if (IS_MTL_GRAPHICS_STEP(ce->engine->i915, M, STEP_A0, STEP_B0) || |
| @@ -1392,17 +1389,7 @@ gen12_emit_indirect_ctx_xcs(const struct intel_context *ce, u32 *cs) · 18 unmodified lines | ||
| 1392 | 1389 | PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE, |
| 1393 | 1390 | 0); |
| 1394 | 1391 | |
| 1395 | − /* hsdes: 1809175790 */ | |
| 1396 | − if (!HAS_FLAT_CCS(ce->engine->i915)) { | |
| 1397 | − if (ce->engine->class == VIDEO_DECODE_CLASS) | |
| 1398 | − cs = gen12_emit_aux_table_inv(ce->engine->gt, | |
| 1399 | − cs, GEN12_VD0_AUX_NV); | |
| 1400 | − else if (ce->engine->class == VIDEO_ENHANCEMENT_CLASS) | |
| 1401 | − cs = gen12_emit_aux_table_inv(ce->engine->gt, | |
| 1402 | − cs, GEN12_VE0_AUX_NV); | |
| 1403 | − } | |
| 1404 | − | |
| 1405 | − return cs; | |
| 1392 | + return gen12_emit_aux_table_inv(ce->engine, cs); | |
| 1406 | 1393 | } |
| 1407 | 1394 | |
| 1408 | 1395 | static void |
| @@ -491,7 +491,7 @@ void intel_gvt_i2c_handle_aux_ch_write(struct intel_vgpu *vgpu, · 490 unmodified lines | ||
| 491 | 491 | return; |
| 492 | 492 | } |
| 493 | 493 | |
| 494 | − msg_length = REG_FIELD_GET(DP_AUX_CH_CTL_MESSAGE_SIZE_MASK, reg); | |
| 494 | + msg_length = REG_FIELD_GET(DP_AUX_CH_CTL_MESSAGE_SIZE_MASK, value); | |
| 495 | 495 | |
| 496 | 496 | // check the msg in DATA register. |
| 497 | 497 | msg = vgpu_vreg(vgpu, offset + 4); |
| @@ -449,8 +449,11 @@ int i915_active_add_request(struct i915_active *ref, struct i915_request *rq) · 448 unmodified lines | ||
| 449 | 449 | } |
| 450 | 450 | } while (unlikely(is_barrier(active))); |
| 451 | 451 | |
| 452 | − if (!__i915_active_fence_set(active, fence)) | |
| 452 | + fence = __i915_active_fence_set(active, fence); | |
| 453 | + if (!fence) | |
| 453 | 454 | __i915_active_acquire(ref); |
| 455 | + else | |
| 456 | + dma_fence_put(fence); | |
| 454 | 457 | |
| 455 | 458 | out: |
| 456 | 459 | i915_active_release(ref); |
| @@ -469,13 +472,9 @@ __i915_active_set_fence(struct i915_active *ref, · 12 unmodified lines | ||
| 469 | 472 | return NULL; |
| 470 | 473 | } |
| 471 | 474 | |
| 472 | − rcu_read_lock(); | |
| 473 | 475 | prev = __i915_active_fence_set(active, fence); |
| 474 | − if (prev) | |
| 475 | − prev = dma_fence_get_rcu(prev); | |
| 476 | − else | |
| 476 | + if (!prev) | |
| 477 | 477 | __i915_active_acquire(ref); |
| 478 | − rcu_read_unlock(); | |
| 479 | 478 | |
| 480 | 479 | return prev; |
| 481 | 480 | } |
| @@ -1019,10 +1018,11 @@ void i915_request_add_active_barriers(struct i915_request *rq) · 537 unmodified lines | ||
| 1019 | 1018 | * |
| 1020 | 1019 | * Records the new @fence as the last active fence along its timeline in |
| 1021 | 1020 | * this active tracker, moving the tracking callbacks from the previous |
| 1022 | − * fence onto this one. Returns the previous fence (if not already completed), | |
| 1023 | − * which the caller must ensure is executed before the new fence. To ensure | |
| 1024 | − * that the order of fences within the timeline of the i915_active_fence is | |
| 1025 | − * understood, it should be locked by the caller. | |
| 1021 | + * fence onto this one. Gets and returns a reference to the previous fence | |
| 1022 | + * (if not already completed), which the caller must put after making sure | |
| 1023 | + * that it is executed before the new fence. To ensure that the order of | |
| 1024 | + * fences within the timeline of the i915_active_fence is understood, it | |
| 1025 | + * should be locked by the caller. | |
| 1026 | 1026 | */ |
| 1027 | 1027 | struct dma_fence * |
| 1028 | 1028 | __i915_active_fence_set(struct i915_active_fence *active, |
| @@ -1031,7 +1031,23 @@ __i915_active_fence_set(struct i915_active_fence *active, · 2 unmodified lines | ||
| 1031 | 1031 | struct dma_fence *prev; |
| 1032 | 1032 | unsigned long flags; |
| 1033 | 1033 | |
| 1034 | − if (fence == rcu_access_pointer(active->fence)) | |
| 1034 | + /* | |
| 1035 | + * In case of fences embedded in i915_requests, their memory is | |
| 1036 | + * SLAB_FAILSAFE_BY_RCU, then it can be reused right after release | |
| 1037 | + * by new requests. Then, there is a risk of passing back a pointer | |
| 1038 | + * to a new, completely unrelated fence that reuses the same memory | |
| 1039 | + * while tracked under a different active tracker. Combined with i915 | |
| 1040 | + * perf open/close operations that build await dependencies between | |
| 1041 | + * engine kernel context requests and user requests from different | |
| 1042 | + * timelines, this can lead to dependency loops and infinite waits. | |
| 1043 | + * | |
| 1044 | + * As a countermeasure, we try to get a reference to the active->fence | |
| 1045 | + * first, so if we succeed and pass it back to our user then it is not | |
| 1046 | + * released and potentially reused by an unrelated request before the | |
| 1047 | + * user has a chance to set up an await dependency on it. | |
| 1048 | + */ | |
| 1049 | + prev = i915_active_fence_get(active); | |
| 1050 | + if (fence == prev) | |
| 1035 | 1051 | return fence; |
| 1036 | 1052 | |
| 1037 | 1053 | GEM_BUG_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)); |
| @@ -1040,27 +1056,56 @@ __i915_active_fence_set(struct i915_active_fence *active, · 2 unmodified lines | ||
| 1040 | 1056 | * Consider that we have two threads arriving (A and B), with |
| 1041 | 1057 | * C already resident as the active->fence. |
| 1042 | 1058 | * |
| 1043 | − * A does the xchg first, and so it sees C or NULL depending | |
| 1044 | − * on the timing of the interrupt handler. If it is NULL, the | |
| 1045 | − * previous fence must have been signaled and we know that | |
| 1046 | − * we are first on the timeline. If it is still present, | |
| 1047 | − * we acquire the lock on that fence and serialise with the interrupt | |
| 1048 | − * handler, in the process removing it from any future interrupt | |
| 1049 | − * callback. A will then wait on C before executing (if present). | |
| 1050 | − * | |
| 1051 | − * As B is second, it sees A as the previous fence and so waits for | |
| 1052 | − * it to complete its transition and takes over the occupancy for | |
| 1053 | − * itself -- remembering that it needs to wait on A before executing. | |
| 1059 | + * Both A and B have got a reference to C or NULL, depending on the | |
| 1060 | + * timing of the interrupt handler. Let's assume that if A has got C | |
| 1061 | + * then it has locked C first (before B). | |
| 1054 | 1062 | * |
| 1055 | 1063 | * Note the strong ordering of the timeline also provides consistent |
| 1056 | 1064 | * nesting rules for the fence->lock; the inner lock is always the |
| 1057 | 1065 | * older lock. |
| 1058 | 1066 | */ |
| 1059 | 1067 | spin_lock_irqsave(fence->lock, flags); |
| 1060 | − prev = xchg(__active_fence_slot(active), fence); | |
| 1061 | − if (prev) { | |
| 1062 | − GEM_BUG_ON(prev == fence); | |
| 1068 | + if (prev) | |
| 1063 | 1069 | spin_lock_nested(prev->lock, SINGLE_DEPTH_NESTING); |
| 1070 | + | |
| 1071 | + /* | |
| 1072 | + * A does the cmpxchg first, and so it sees C or NULL, as before, or | |
| 1073 | + * something else, depending on the timing of other threads and/or | |
| 1074 | + * interrupt handler. If not the same as before then A unlocks C if | |
| 1075 | + * applicable and retries, starting from an attempt to get a new | |
| 1076 | + * active->fence. Meanwhile, B follows the same path as A. | |
| 1077 | + * Once A succeeds with cmpxch, B fails again, retires, gets A from | |
| 1078 | + * active->fence, locks it as soon as A completes, and possibly | |
| 1079 | + * succeeds with cmpxchg. | |
| 1080 | + */ | |
| 1081 | + while (cmpxchg(__active_fence_slot(active), prev, fence) != prev) { | |
| 1082 | + if (prev) { | |
| 1083 | + spin_unlock(prev->lock); | |
| 1084 | + dma_fence_put(prev); | |
| 1085 | + } | |
| 1086 | + spin_unlock_irqrestore(fence->lock, flags); | |
| 1087 | + | |
| 1088 | + prev = i915_active_fence_get(active); | |
| 1089 | + GEM_BUG_ON(prev == fence); | |
| 1090 | + | |
| 1091 | + spin_lock_irqsave(fence->lock, flags); | |
| 1092 | + if (prev) | |
| 1093 | + spin_lock_nested(prev->lock, SINGLE_DEPTH_NESTING); | |
| 1094 | + } | |
| 1095 | + | |
| 1096 | + /* | |
| 1097 | + * If prev is NULL then the previous fence must have been signaled | |
| 1098 | + * and we know that we are first on the timeline. If it is still | |
| 1099 | + * present then, having the lock on that fence already acquired, we | |
| 1100 | + * serialise with the interrupt handler, in the process of removing it | |
| 1101 | + * from any future interrupt callback. A will then wait on C before | |
| 1102 | + * executing (if present). | |
| 1103 | + * | |
| 1104 | + * As B is second, it sees A as the previous fence and so waits for | |
| 1105 | + * it to complete its transition and takes over the occupancy for | |
| 1106 | + * itself -- remembering that it needs to wait on A before executing. | |
| 1107 | + */ | |
| 1108 | + if (prev) { | |
| 1064 | 1109 | __list_del_entry(&active->cb.node); |
| 1065 | 1110 | spin_unlock(prev->lock); /* serialise with prev->cb_list */ |
| 1066 | 1111 | } |
| @@ -1077,11 +1122,7 @@ int i915_active_fence_set(struct i915_active_fence *active, · 10 unmodified lines | ||
| 1077 | 1122 | int err = 0; |
| 1078 | 1123 | |
| 1079 | 1124 | /* Must maintain timeline ordering wrt previous active requests */ |
| 1080 | − rcu_read_lock(); | |
| 1081 | 1125 | fence = __i915_active_fence_set(active, &rq->fence); |
| 1082 | − if (fence) /* but the previous fence may not belong to that timeline! */ | |
| 1083 | − fence = dma_fence_get_rcu(fence); | |
| 1084 | − rcu_read_unlock(); | |
| 1085 | 1126 | if (fence) { |
| 1086 | 1127 | err = i915_request_await_dma_fence(rq, fence); |
| 1087 | 1128 | dma_fence_put(fence); |
| @@ -1661,6 +1661,11 @@ __i915_request_ensure_parallel_ordering(struct i915_request *rq, · 1660 unmodified lines | ||
| 1661 | 1661 | |
| 1662 | 1662 | request_to_parent(rq)->parallel.last_rq = i915_request_get(rq); |
| 1663 | 1663 | |
| 1664 | + /* | |
| 1665 | + * Users have to put a reference potentially got by | |
| 1666 | + * __i915_active_fence_set() to the returned request | |
| 1667 | + * when no longer needed | |
| 1668 | + */ | |
| 1664 | 1669 | return to_request(__i915_active_fence_set(&timeline->last_request, |
| 1665 | 1670 | &rq->fence)); |
| 1666 | 1671 | } |
| @@ -1707,6 +1712,10 @@ __i915_request_ensure_ordering(struct i915_request *rq, · 40 unmodified lines | ||
| 1707 | 1712 | 0); |
| 1708 | 1713 | } |
| 1709 | 1714 | |
| 1715 | + /* | |
| 1716 | + * Users have to put the reference to prev potentially got | |
| 1717 | + * by __i915_active_fence_set() when no longer needed | |
| 1718 | + */ | |
| 1710 | 1719 | return prev; |
| 1711 | 1720 | } |
| 1712 | 1721 | |
| @@ -1760,6 +1769,8 @@ __i915_request_add_to_timeline(struct i915_request *rq) · 47 unmodified lines | ||
| 1760 | 1769 | prev = __i915_request_ensure_ordering(rq, timeline); |
| 1761 | 1770 | else |
| 1762 | 1771 | prev = __i915_request_ensure_parallel_ordering(rq, timeline); |
| 1772 | + if (prev) | |
| 1773 | + i915_request_put(prev); | |
| 1763 | 1774 | |
| 1764 | 1775 | /* |
| 1765 | 1776 | * Make sure that no request gazumped us - if it was allocated after |
| @@ -310,7 +310,7 @@ static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc) · 309 unmodified lines | ||
| 310 | 310 | dev_warn(ipu_crtc->dev, "8-pixel align hactive %d -> %d\n", |
| 311 | 311 | sig_cfg.mode.hactive, new_hactive); |
| 312 | 312 | |
| 313 | − sig_cfg.mode.hfront_porch = new_hactive - sig_cfg.mode.hactive; | |
| 313 | + sig_cfg.mode.hfront_porch -= new_hactive - sig_cfg.mode.hactive; | |
| 314 | 314 | sig_cfg.mode.hactive = new_hactive; |
| 315 | 315 | } |
| 316 | 316 | |
| @@ -89,7 +89,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit · 88 unmodified lines | ||
| 89 | 89 | * since we've already mapped it once in |
| 90 | 90 | * submit_reloc() |
| 91 | 91 | */ |
| 92 | − if (WARN_ON(!ptr)) | |
| 92 | + if (WARN_ON(IS_ERR_OR_NULL(ptr))) | |
| 93 | 93 | return; |
| 94 | 94 | |
| 95 | 95 | for (i = 0; i < dwords; i++) { |
| @@ -206,7 +206,7 @@ static const struct a6xx_shader_block { · 205 unmodified lines | ||
| 206 | 206 | SHADER(A6XX_SP_LB_3_DATA, 0x800), |
| 207 | 207 | SHADER(A6XX_SP_LB_4_DATA, 0x800), |
| 208 | 208 | SHADER(A6XX_SP_LB_5_DATA, 0x200), |
| 209 | − SHADER(A6XX_SP_CB_BINDLESS_DATA, 0x2000), | |
| 209 | + SHADER(A6XX_SP_CB_BINDLESS_DATA, 0x800), | |
| 210 | 210 | SHADER(A6XX_SP_CB_LEGACY_DATA, 0x280), |
| 211 | 211 | SHADER(A6XX_SP_UAV_DATA, 0x80), |
| 212 | 212 | SHADER(A6XX_SP_INST_TAG, 0x80), |
| @@ -369,8 +369,6 @@ static const struct adreno_info gpulist[] = { · 368 unmodified lines | ||
| 369 | 369 | .hwcg = a640_hwcg, |
| 370 | 370 | }, { |
| 371 | 371 | .rev = ADRENO_REV(6, 9, 0, ANY_ID), |
| 372 | − .revn = 690, | |
| 373 | − .name = "A690", | |
| 374 | 372 | .fw = { |
| 375 | 373 | [ADRENO_FW_SQE] = "a660_sqe.fw", |
| 376 | 374 | [ADRENO_FW_GMU] = "a690_gmu.bin", |
| @@ -149,7 +149,8 @@ bool adreno_cmp_rev(struct adreno_rev rev1, struct adreno_rev rev2); · 148 unmodified lines | ||
| 149 | 149 | |
| 150 | 150 | static inline bool adreno_is_revn(const struct adreno_gpu *gpu, uint32_t revn) |
| 151 | 151 | { |
| 152 | − WARN_ON_ONCE(!gpu->revn); | |
| 152 | + /* revn can be zero, but if not is set at same time as info */ | |
| 153 | + WARN_ON_ONCE(!gpu->info); | |
| 153 | 154 | |
| 154 | 155 | return gpu->revn == revn; |
| 155 | 156 | } |
| @@ -161,14 +162,16 @@ static inline bool adreno_has_gmu_wrapper(const struct adreno_gpu *gpu) · 5 unmodified lines | ||
| 161 | 162 | |
| 162 | 163 | static inline bool adreno_is_a2xx(const struct adreno_gpu *gpu) |
| 163 | 164 | { |
| 164 | − WARN_ON_ONCE(!gpu->revn); | |
| 165 | + /* revn can be zero, but if not is set at same time as info */ | |
| 166 | + WARN_ON_ONCE(!gpu->info); | |
| 165 | 167 | |
| 166 | 168 | return (gpu->revn < 300); |
| 167 | 169 | } |
| 168 | 170 | |
| 169 | 171 | static inline bool adreno_is_a20x(const struct adreno_gpu *gpu) |
| 170 | 172 | { |
| 171 | − WARN_ON_ONCE(!gpu->revn); | |
| 173 | + /* revn can be zero, but if not is set at same time as info */ | |
| 174 | + WARN_ON_ONCE(!gpu->info); | |
| 172 | 175 | |
| 173 | 176 | return (gpu->revn < 210); |
| 174 | 177 | } |
| @@ -307,7 +310,8 @@ static inline int adreno_is_a680(const struct adreno_gpu *gpu) · 132 unmodified lines | ||
| 307 | 310 | |
| 308 | 311 | static inline int adreno_is_a690(const struct adreno_gpu *gpu) |
| 309 | 312 | { |
| 310 | − return adreno_is_revn(gpu, 690); | |
| 313 | + /* The order of args is important here to handle ANY_ID correctly */ | |
| 314 | + return adreno_cmp_rev(ADRENO_REV(6, 9, 0, ANY_ID), gpu->rev); | |
| 311 | 315 | }; |
| 312 | 316 | |
| 313 | 317 | /* check for a615, a616, a618, a619 or any derivatives */ |
| @@ -14,19 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | #define DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE 412500000 |
| 16 | 16 | |
| 17 | −/** | |
| 18 | − * enum dpu_core_perf_data_bus_id - data bus identifier | |
| 19 | − * @DPU_CORE_PERF_DATA_BUS_ID_MNOC: DPU/MNOC data bus | |
| 20 | − * @DPU_CORE_PERF_DATA_BUS_ID_LLCC: MNOC/LLCC data bus | |
| 21 | − * @DPU_CORE_PERF_DATA_BUS_ID_EBI: LLCC/EBI data bus | |
| 22 | − */ | |
| 23 | −enum dpu_core_perf_data_bus_id { | |
| 24 | − DPU_CORE_PERF_DATA_BUS_ID_MNOC, | |
| 25 | − DPU_CORE_PERF_DATA_BUS_ID_LLCC, | |
| 26 | − DPU_CORE_PERF_DATA_BUS_ID_EBI, | |
| 27 | − DPU_CORE_PERF_DATA_BUS_ID_MAX, | |
| 28 | −}; | |
| 29 | − | |
| 30 | 17 | /** |
| 31 | 18 | * struct dpu_core_perf_params - definition of performance parameters |
| 32 | 19 | * @max_per_pipe_ib: maximum instantaneous bandwidth request |
| @@ -51,7 +51,7 @@ · 50 unmodified lines | ||
| 51 | 51 | |
| 52 | 52 | static const u32 fetch_tbl[SSPP_MAX] = {CTL_INVALID_BIT, 16, 17, 18, 19, |
| 53 | 53 | CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, 0, |
| 54 | − 1, 2, 3, CTL_INVALID_BIT, CTL_INVALID_BIT}; | |
| 54 | + 1, 2, 3, 4, 5}; | |
| 55 | 55 | |
| 56 | 56 | static int _mixer_stages(const struct dpu_lm_cfg *mixer, int count, |
| 57 | 57 | enum dpu_lm lm) |
| @@ -198,6 +198,12 @@ static void dpu_hw_ctl_update_pending_flush_sspp(struct dpu_hw_ctl *ctx, · 140 unmodified lines | ||
| 198 | 198 | case SSPP_DMA3: |
| 199 | 199 | ctx->pending_flush_mask |= BIT(25); |
| 200 | 200 | break; |
| 201 | + case SSPP_DMA4: | |
| 202 | + ctx->pending_flush_mask |= BIT(13); | |
| 203 | + break; | |
| 204 | + case SSPP_DMA5: | |
| 205 | + ctx->pending_flush_mask |= BIT(14); | |
| 206 | + break; | |
| 201 | 207 | case SSPP_CURSOR0: |
| 202 | 208 | ctx->pending_flush_mask |= BIT(22); |
| 203 | 209 | break; |
| @@ -1087,8 +1087,6 @@ const struct msm_dsi_phy_cfg dsi_phy_14nm_8953_cfgs = { · 1086 unmodified lines | ||
| 1087 | 1087 | |
| 1088 | 1088 | const struct msm_dsi_phy_cfg dsi_phy_14nm_2290_cfgs = { |
| 1089 | 1089 | .has_phy_lane = true, |
| 1090 | − .regulator_data = dsi_phy_14nm_17mA_regulators, | |
| 1091 | − .num_regulators = ARRAY_SIZE(dsi_phy_14nm_17mA_regulators), | |
| 1092 | 1090 | .ops = { |
| 1093 | 1091 | .enable = dsi_14nm_phy_enable, |
| 1094 | 1092 | .disable = dsi_14nm_phy_disable, |
| @@ -191,6 +191,12 @@ msm_fence_init(struct dma_fence *fence, struct msm_fence_context *fctx) · 190 unmodified lines | ||
| 191 | 191 | |
| 192 | 192 | f->fctx = fctx; |
| 193 | 193 | |
| 194 | + /* | |
| 195 | + * Until this point, the fence was just some pre-allocated memory, | |
| 196 | + * no-one should have taken a reference to it yet. | |
| 197 | + */ | |
| 198 | + WARN_ON(kref_read(&fence->refcount)); | |
| 199 | + | |
| 194 | 200 | dma_fence_init(&f->base, &msm_fence_ops, &fctx->spinlock, |
| 195 | 201 | fctx->context, ++fctx->last_fence); |
| 196 | 202 | } |
| @@ -86,7 +86,19 @@ void __msm_gem_submit_destroy(struct kref *kref) · 85 unmodified lines | ||
| 86 | 86 | } |
| 87 | 87 | |
| 88 | 88 | dma_fence_put(submit->user_fence); |
| 89 | − dma_fence_put(submit->hw_fence); | |
| 89 | + | |
| 90 | + /* | |
| 91 | + * If the submit is freed before msm_job_run(), then hw_fence is | |
| 92 | + * just some pre-allocated memory, not a reference counted fence. | |
| 93 | + * Once the job runs and the hw_fence is initialized, it will | |
| 94 | + * have a refcount of at least one, since the submit holds a ref | |
| 95 | + * to the hw_fence. | |
| 96 | + */ | |
| 97 | + if (kref_read(&submit->hw_fence->refcount) == 0) { | |
| 98 | + kfree(submit->hw_fence); | |
| 99 | + } else { | |
| 100 | + dma_fence_put(submit->hw_fence); | |
| 101 | + } | |
| 90 | 102 | |
| 91 | 103 | put_pid(submit->pid); |
| 92 | 104 | msm_submitqueue_put(submit->queue); |
| @@ -889,7 +901,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 796 unmodified lines | ||
| 889 | 901 | * after the job is armed |
| 890 | 902 | */ |
| 891 | 903 | if ((args->flags & MSM_SUBMIT_FENCE_SN_IN) && |
| 892 | − idr_find(&queue->fence_idr, args->fence)) { | |
| 904 | + (!args->fence || idr_find(&queue->fence_idr, args->fence))) { | |
| 893 | 905 | spin_unlock(&queue->idr_lock); |
| 894 | 906 | idr_preload_end(); |
| 895 | 907 | ret = -EINVAL; |
| @@ -189,6 +189,7 @@ static int _msm_mdss_irq_domain_add(struct msm_mdss *msm_mdss) · 188 unmodified lines | ||
| 189 | 189 | #define UBWC_2_0 0x20000000 |
| 190 | 190 | #define UBWC_3_0 0x30000000 |
| 191 | 191 | #define UBWC_4_0 0x40000000 |
| 192 | +#define UBWC_4_3 0x40030000 | |
| 192 | 193 | |
| 193 | 194 | static void msm_mdss_setup_ubwc_dec_20(struct msm_mdss *msm_mdss) |
| 194 | 195 | { |
| @@ -227,7 +228,10 @@ static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss *msm_mdss) · 32 unmodified lines | ||
| 227 | 228 | writel_relaxed(1, msm_mdss->mmio + UBWC_CTRL_2); |
| 228 | 229 | writel_relaxed(0, msm_mdss->mmio + UBWC_PREDICTION_MODE); |
| 229 | 230 | } else { |
| 230 | − writel_relaxed(2, msm_mdss->mmio + UBWC_CTRL_2); | |
| 231 | + if (data->ubwc_dec_version == UBWC_4_3) | |
| 232 | + writel_relaxed(3, msm_mdss->mmio + UBWC_CTRL_2); | |
| 233 | + else | |
| 234 | + writel_relaxed(2, msm_mdss->mmio + UBWC_CTRL_2); | |
| 231 | 235 | writel_relaxed(1, msm_mdss->mmio + UBWC_PREDICTION_MODE); |
| 232 | 236 | } |
| 233 | 237 | } |
| @@ -271,6 +275,7 @@ static int msm_mdss_enable(struct msm_mdss *msm_mdss) · 37 unmodified lines | ||
| 271 | 275 | msm_mdss_setup_ubwc_dec_30(msm_mdss); |
| 272 | 276 | break; |
| 273 | 277 | case UBWC_4_0: |
| 278 | + case UBWC_4_3: | |
| 274 | 279 | msm_mdss_setup_ubwc_dec_40(msm_mdss); |
| 275 | 280 | break; |
| 276 | 281 | default: |
| @@ -569,6 +574,16 @@ static const struct msm_mdss_data sm8250_data = { · 292 unmodified lines | ||
| 569 | 574 | .macrotile_mode = 1, |
| 570 | 575 | }; |
| 571 | 576 | |
| 577 | +static const struct msm_mdss_data sm8550_data = { | |
| 578 | + .ubwc_version = UBWC_4_0, | |
| 579 | + .ubwc_dec_version = UBWC_4_3, | |
| 580 | + .ubwc_swizzle = 6, | |
| 581 | + .ubwc_static = 1, | |
| 582 | + /* TODO: highest_bank_bit = 2 for LP_DDR4 */ | |
| 583 | + .highest_bank_bit = 3, | |
| 584 | + .macrotile_mode = 1, | |
| 585 | +}; | |
| 586 | + | |
| 572 | 587 | static const struct of_device_id mdss_dt_match[] = { |
| 573 | 588 | { .compatible = "qcom,mdss" }, |
| 574 | 589 | { .compatible = "qcom,msm8998-mdss" }, |
| @@ -585,7 +600,7 @@ static const struct of_device_id mdss_dt_match[] = { · 10 unmodified lines | ||
| 585 | 600 | { .compatible = "qcom,sm8250-mdss", .data = &sm8250_data }, |
| 586 | 601 | { .compatible = "qcom,sm8350-mdss", .data = &sm8250_data }, |
| 587 | 602 | { .compatible = "qcom,sm8450-mdss", .data = &sm8250_data }, |
| 588 | − { .compatible = "qcom,sm8550-mdss", .data = &sm8250_data }, | |
| 603 | + { .compatible = "qcom,sm8550-mdss", .data = &sm8550_data }, | |
| 589 | 604 | {} |
| 590 | 605 | }; |
| 591 | 606 | MODULE_DEVICE_TABLE(of, mdss_dt_match); |
| @@ -967,7 +967,7 @@ nouveau_connector_get_modes(struct drm_connector *connector) · 966 unmodified lines | ||
| 967 | 967 | /* Determine display colour depth for everything except LVDS now, |
| 968 | 968 | * DP requires this before mode_valid() is called. |
| 969 | 969 | */ |
| 970 | − if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && nv_connector->native_mode) | |
| 970 | + if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS) | |
| 971 | 971 | nouveau_connector_detect_depth(connector); |
| 972 | 972 | |
| 973 | 973 | /* Find the native mode if this is a digital panel, if we didn't |
| @@ -26,6 +26,8 @@ · 25 unmodified lines | ||
| 26 | 26 | #include "head.h" |
| 27 | 27 | #include "ior.h" |
| 28 | 28 | |
| 29 | +#include <drm/display/drm_dp.h> | |
| 30 | + | |
| 29 | 31 | #include <subdev/bios.h> |
| 30 | 32 | #include <subdev/bios/init.h> |
| 31 | 33 | #include <subdev/gpio.h> |
| @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp) · 602 unmodified lines | ||
| 634 | 636 | return outp->dp.rates != 0; |
| 635 | 637 | } |
| 636 | 638 | |
| 639 | +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps() | |
| 640 | + * converted to work inside nvkm. This is a temporary holdover until we start | |
| 641 | + * passing the drm_dp_aux device through NVKM | |
| 642 | + */ | |
| 643 | +static int | |
| 644 | +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp) | |
| 645 | +{ | |
| 646 | + struct nvkm_i2c_aux *aux = outp->dp.aux; | |
| 647 | + u8 dpcd_ext[DP_RECEIVER_CAP_SIZE]; | |
| 648 | + int ret; | |
| 649 | + | |
| 650 | + ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE); | |
| 651 | + if (ret < 0) | |
| 652 | + return ret; | |
| 653 | + | |
| 654 | + /* | |
| 655 | + * Prior to DP1.3 the bit represented by | |
| 656 | + * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved. | |
| 657 | + * If it is set DP_DPCD_REV at 0000h could be at a value less than | |
| 658 | + * the true capability of the panel. The only way to check is to | |
| 659 | + * then compare 0000h and 2200h. | |
| 660 | + */ | |
| 661 | + if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] & | |
| 662 | + DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT)) | |
| 663 | + return 0; | |
| 664 | + | |
| 665 | + ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext)); | |
| 666 | + if (ret < 0) | |
| 667 | + return ret; | |
| 668 | + | |
| 669 | + if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) { | |
| 670 | + OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n", | |
| 671 | + outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]); | |
| 672 | + return 0; | |
| 673 | + } | |
| 674 | + | |
| 675 | + if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext))) | |
| 676 | + return 0; | |
| 677 | + | |
| 678 | + memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)); | |
| 679 | + | |
| 680 | + return 0; | |
| 681 | +} | |
| 682 | + | |
| 637 | 683 | void |
| 638 | 684 | nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr) |
| 639 | 685 | { |
| @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr) · 49 unmodified lines | ||
| 689 | 735 | memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr)); |
| 690 | 736 | } |
| 691 | 737 | |
| 692 | − if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) { | |
| 738 | + if (!nvkm_dp_read_dpcd_caps(outp)) { | |
| 693 | 739 | const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 }; |
| 694 | 740 | const u8 *rate; |
| 695 | 741 | int rate_max; |
| @@ -117,6 +117,7 @@ void gk104_grctx_generate_r418800(struct gf100_gr *); · 116 unmodified lines | ||
| 117 | 117 | |
| 118 | 118 | extern const struct gf100_grctx_func gk110_grctx; |
| 119 | 119 | void gk110_grctx_generate_r419eb0(struct gf100_gr *); |
| 120 | +void gk110_grctx_generate_r419f78(struct gf100_gr *); | |
| 120 | 121 | |
| 121 | 122 | extern const struct gf100_grctx_func gk110b_grctx; |
| 122 | 123 | extern const struct gf100_grctx_func gk208_grctx; |
| @@ -906,7 +906,9 @@ static void · 905 unmodified lines | ||
| 906 | 906 | gk104_grctx_generate_r419f78(struct gf100_gr *gr) |
| 907 | 907 | { |
| 908 | 908 | struct nvkm_device *device = gr->base.engine.subdev.device; |
| 909 | − nvkm_mask(device, 0x419f78, 0x00000001, 0x00000000); | |
| 909 | + | |
| 910 | + /* bit 3 set disables loads in fp helper invocations, we need it enabled */ | |
| 911 | + nvkm_mask(device, 0x419f78, 0x00000009, 0x00000000); | |
| 910 | 912 | } |
| 911 | 913 | |
| 912 | 914 | void |
| @@ -820,6 +820,15 @@ gk110_grctx_generate_r419eb0(struct gf100_gr *gr) · 819 unmodified lines | ||
| 820 | 820 | nvkm_mask(device, 0x419eb0, 0x00001000, 0x00001000); |
| 821 | 821 | } |
| 822 | 822 | |
| 823 | +void | |
| 824 | +gk110_grctx_generate_r419f78(struct gf100_gr *gr) | |
| 825 | +{ | |
| 826 | + struct nvkm_device *device = gr->base.engine.subdev.device; | |
| 827 | + | |
| 828 | + /* bit 3 set disables loads in fp helper invocations, we need it enabled */ | |
| 829 | + nvkm_mask(device, 0x419f78, 0x00000008, 0x00000000); | |
| 830 | +} | |
| 831 | + | |
| 823 | 832 | const struct gf100_grctx_func |
| 824 | 833 | gk110_grctx = { |
| 825 | 834 | .main = gf100_grctx_generate_main, |
| @@ -854,4 +863,5 @@ gk110_grctx = { · 28 unmodified lines | ||
| 854 | 863 | .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, |
| 855 | 864 | .r418800 = gk104_grctx_generate_r418800, |
| 856 | 865 | .r419eb0 = gk110_grctx_generate_r419eb0, |
| 866 | + .r419f78 = gk110_grctx_generate_r419f78, | |
| 857 | 867 | }; |
| @@ -103,4 +103,5 @@ gk110b_grctx = { · 102 unmodified lines | ||
| 103 | 103 | .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, |
| 104 | 104 | .r418800 = gk104_grctx_generate_r418800, |
| 105 | 105 | .r419eb0 = gk110_grctx_generate_r419eb0, |
| 106 | + .r419f78 = gk110_grctx_generate_r419f78, | |
| 106 | 107 | }; |
| @@ -568,4 +568,5 @@ gk208_grctx = { · 567 unmodified lines | ||
| 568 | 568 | .dist_skip_table = gf117_grctx_generate_dist_skip_table, |
| 569 | 569 | .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, |
| 570 | 570 | .r418800 = gk104_grctx_generate_r418800, |
| 571 | + .r419f78 = gk110_grctx_generate_r419f78, | |
| 571 | 572 | }; |
| @@ -988,4 +988,5 @@ gm107_grctx = { · 987 unmodified lines | ||
| 988 | 988 | .r406500 = gm107_grctx_generate_r406500, |
| 989 | 989 | .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, |
| 990 | 990 | .r419e00 = gm107_grctx_generate_r419e00, |
| 991 | + .r419f78 = gk110_grctx_generate_r419f78, | |
| 991 | 992 | }; |
| @@ -206,19 +206,6 @@ tu102_gr_av_to_init_veid(struct nvkm_blob *blob, struct gf100_gr_pack **ppack) · 205 unmodified lines | ||
| 206 | 206 | return gk20a_gr_av_to_init_(blob, 64, 0x00100000, ppack); |
| 207 | 207 | } |
| 208 | 208 | |
| 209 | −int | |
| 210 | −tu102_gr_load(struct gf100_gr *gr, int ver, const struct gf100_gr_fwif *fwif) | |
| 211 | −{ | |
| 212 | − int ret; | |
| 213 | − | |
| 214 | − ret = gm200_gr_load(gr, ver, fwif); | |
| 215 | − if (ret) | |
| 216 | − return ret; | |
| 217 | − | |
| 218 | − return gk20a_gr_load_net(gr, "gr/", "sw_veid_bundle_init", ver, tu102_gr_av_to_init_veid, | |
| 219 | − &gr->bundle_veid); | |
| 220 | −} | |
| 221 | − | |
| 222 | 209 | static const struct gf100_gr_fwif |
| 223 | 210 | tu102_gr_fwif[] = { |
| 224 | 211 | { 0, gm200_gr_load, &tu102_gr, &gp108_gr_fecs_acr, &gp108_gr_gpccs_acr }, |
| @@ -569,6 +569,7 @@ static const struct of_device_id s6d7aa0_of_match[] = { · 568 unmodified lines | ||
| 569 | 569 | }, |
| 570 | 570 | { /* sentinel */ } |
| 571 | 571 | }; |
| 572 | +MODULE_DEVICE_TABLE(of, s6d7aa0_of_match); | |
| 572 | 573 | |
| 573 | 574 | static struct mipi_dsi_driver s6d7aa0_driver = { |
| 574 | 575 | .probe = s6d7aa0_probe, |
| @@ -833,12 +833,12 @@ static int vop_plane_atomic_check(struct drm_plane *plane, · 832 unmodified lines | ||
| 833 | 833 | * need align with 2 pixel. |
| 834 | 834 | */ |
| 835 | 835 | if (fb->format->is_yuv && ((new_plane_state->src.x1 >> 16) % 2)) { |
| 836 | − DRM_ERROR("Invalid Source: Yuv format not support odd xpos\n"); | |
| 836 | + DRM_DEBUG_KMS("Invalid Source: Yuv format not support odd xpos\n"); | |
| 837 | 837 | return -EINVAL; |
| 838 | 838 | } |
| 839 | 839 | |
| 840 | 840 | if (fb->format->is_yuv && new_plane_state->rotation & DRM_MODE_REFLECT_Y) { |
| 841 | − DRM_ERROR("Invalid Source: Yuv format does not support this rotation\n"); | |
| 841 | + DRM_DEBUG_KMS("Invalid Source: Yuv format does not support this rotation\n"); | |
| 842 | 842 | return -EINVAL; |
| 843 | 843 | } |
| 844 | 844 | |
| @@ -846,7 +846,7 @@ static int vop_plane_atomic_check(struct drm_plane *plane, · 1 unmodified line | ||
| 846 | 846 | struct vop *vop = to_vop(crtc); |
| 847 | 847 | |
| 848 | 848 | if (!vop->data->afbc) { |
| 849 | − DRM_ERROR("vop does not support AFBC\n"); | |
| 849 | + DRM_DEBUG_KMS("vop does not support AFBC\n"); | |
| 850 | 850 | return -EINVAL; |
| 851 | 851 | } |
| 852 | 852 | |
| @@ -855,15 +855,16 @@ static int vop_plane_atomic_check(struct drm_plane *plane, · 2 unmodified lines | ||
| 855 | 855 | return ret; |
| 856 | 856 | |
| 857 | 857 | if (new_plane_state->src.x1 || new_plane_state->src.y1) { |
| 858 | − DRM_ERROR("AFBC does not support offset display, xpos=%d, ypos=%d, offset=%d\n", | |
| 859 | − new_plane_state->src.x1, | |
| 860 | − new_plane_state->src.y1, fb->offsets[0]); | |
| 858 | + DRM_DEBUG_KMS("AFBC does not support offset display, " \ | |
| 859 | + "xpos=%d, ypos=%d, offset=%d\n", | |
| 860 | + new_plane_state->src.x1, new_plane_state->src.y1, | |
| 861 | + fb->offsets[0]); | |
| 861 | 862 | return -EINVAL; |
| 862 | 863 | } |
| 863 | 864 | |
| 864 | 865 | if (new_plane_state->rotation && new_plane_state->rotation != DRM_MODE_ROTATE_0) { |
| 865 | − DRM_ERROR("No rotation support in AFBC, rotation=%d\n", | |
| 866 | − new_plane_state->rotation); | |
| 866 | + DRM_DEBUG_KMS("No rotation support in AFBC, rotation=%d\n", | |
| 867 | + new_plane_state->rotation); | |
| 867 | 868 | return -EINVAL; |
| 868 | 869 | } |
| 869 | 870 | } |
| @@ -519,7 +519,8 @@ static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo, · 518 unmodified lines | ||
| 519 | 519 | |
| 520 | 520 | if (bo->pin_count) { |
| 521 | 521 | *locked = false; |
| 522 | − *busy = false; | |
| 522 | + if (busy) | |
| 523 | + *busy = false; | |
| 523 | 524 | return false; |
| 524 | 525 | } |
| 525 | 526 | |
| @@ -209,8 +209,7 @@ int vmbus_connect(void) · 208 unmodified lines | ||
| 209 | 209 | * Setup the vmbus event connection for channel interrupt |
| 210 | 210 | * abstraction stuff |
| 211 | 211 | */ |
| 212 | − vmbus_connection.int_page = | |
| 213 | − (void *)hv_alloc_hyperv_zeroed_page(); | |
| 212 | + vmbus_connection.int_page = hv_alloc_hyperv_zeroed_page(); | |
| 214 | 213 | if (vmbus_connection.int_page == NULL) { |
| 215 | 214 | ret = -ENOMEM; |
| 216 | 215 | goto cleanup; |
| @@ -225,8 +224,8 @@ int vmbus_connect(void) · 8 unmodified lines | ||
| 225 | 224 | * Setup the monitor notification facility. The 1st page for |
| 226 | 225 | * parent->child and the 2nd page for child->parent |
| 227 | 226 | */ |
| 228 | − vmbus_connection.monitor_pages[0] = (void *)hv_alloc_hyperv_page(); | |
| 229 | − vmbus_connection.monitor_pages[1] = (void *)hv_alloc_hyperv_page(); | |
| 227 | + vmbus_connection.monitor_pages[0] = hv_alloc_hyperv_page(); | |
| 228 | + vmbus_connection.monitor_pages[1] = hv_alloc_hyperv_page(); | |
| 230 | 229 | if ((vmbus_connection.monitor_pages[0] == NULL) || |
| 231 | 230 | (vmbus_connection.monitor_pages[1] == NULL)) { |
| 232 | 231 | ret = -ENOMEM; |
| @@ -333,15 +332,15 @@ void vmbus_disconnect(void) · 100 unmodified lines | ||
| 333 | 332 | destroy_workqueue(vmbus_connection.work_queue); |
| 334 | 333 | |
| 335 | 334 | if (vmbus_connection.int_page) { |
| 336 | − hv_free_hyperv_page((unsigned long)vmbus_connection.int_page); | |
| 335 | + hv_free_hyperv_page(vmbus_connection.int_page); | |
| 337 | 336 | vmbus_connection.int_page = NULL; |
| 338 | 337 | } |
| 339 | 338 | |
| 340 | 339 | set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[0], 1); |
| 341 | 340 | set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[1], 1); |
| 342 | 341 | |
| 343 | − hv_free_hyperv_page((unsigned long)vmbus_connection.monitor_pages[0]); | |
| 344 | − hv_free_hyperv_page((unsigned long)vmbus_connection.monitor_pages[1]); | |
| 342 | + hv_free_hyperv_page(vmbus_connection.monitor_pages[0]); | |
| 343 | + hv_free_hyperv_page(vmbus_connection.monitor_pages[1]); | |
| 345 | 344 | vmbus_connection.monitor_pages[0] = NULL; |
| 346 | 345 | vmbus_connection.monitor_pages[1] = NULL; |
| 347 | 346 | } |
| @@ -1628,7 +1628,7 @@ static int hv_free_page_report(struct page_reporting_dev_info *pr_dev_info, · 1627 unmodified lines | ||
| 1628 | 1628 | WARN_ON_ONCE(nents > HV_MEMORY_HINT_MAX_GPA_PAGE_RANGES); |
| 1629 | 1629 | WARN_ON_ONCE(sgl->length < (HV_HYP_PAGE_SIZE << page_reporting_order)); |
| 1630 | 1630 | local_irq_save(flags); |
| 1631 | − hint = *(struct hv_memory_hint **)this_cpu_ptr(hyperv_pcpu_input_arg); | |
| 1631 | + hint = *this_cpu_ptr(hyperv_pcpu_input_arg); | |
| 1632 | 1632 | if (!hint) { |
| 1633 | 1633 | local_irq_restore(flags); |
| 1634 | 1634 | return -ENOSPC; |
| @@ -115,12 +115,12 @@ void *hv_alloc_hyperv_zeroed_page(void) · 114 unmodified lines | ||
| 115 | 115 | } |
| 116 | 116 | EXPORT_SYMBOL_GPL(hv_alloc_hyperv_zeroed_page); |
| 117 | 117 | |
| 118 | −void hv_free_hyperv_page(unsigned long addr) | |
| 118 | +void hv_free_hyperv_page(void *addr) | |
| 119 | 119 | { |
| 120 | 120 | if (PAGE_SIZE == HV_HYP_PAGE_SIZE) |
| 121 | − free_page(addr); | |
| 121 | + free_page((unsigned long)addr); | |
| 122 | 122 | else |
| 123 | − kfree((void *)addr); | |
| 123 | + kfree(addr); | |
| 124 | 124 | } |
| 125 | 125 | EXPORT_SYMBOL_GPL(hv_free_hyperv_page); |
| 126 | 126 | |
| @@ -253,7 +253,7 @@ static void hv_kmsg_dump_unregister(void) · 126 unmodified lines | ||
| 253 | 253 | atomic_notifier_chain_unregister(&panic_notifier_list, |
| 254 | 254 | &hyperv_panic_report_block); |
| 255 | 255 | |
| 256 | − hv_free_hyperv_page((unsigned long)hv_panic_page); | |
| 256 | + hv_free_hyperv_page(hv_panic_page); | |
| 257 | 257 | hv_panic_page = NULL; |
| 258 | 258 | } |
| 259 | 259 | |
| @@ -270,7 +270,7 @@ static void hv_kmsg_dump_register(void) · 10 unmodified lines | ||
| 270 | 270 | ret = kmsg_dump_register(&hv_kmsg_dumper); |
| 271 | 271 | if (ret) { |
| 272 | 272 | pr_err("Hyper-V: kmsg dump register error 0x%x\n", ret); |
| 273 | − hv_free_hyperv_page((unsigned long)hv_panic_page); | |
| 273 | + hv_free_hyperv_page(hv_panic_page); | |
| 274 | 274 | hv_panic_page = NULL; |
| 275 | 275 | } |
| 276 | 276 | } |
| @@ -13,9 +13,11 @@ · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | #include <linux/crc16.h> |
| 15 | 15 | #include <linux/debugfs.h> |
| 16 | +#include <linux/delay.h> | |
| 16 | 17 | #include <linux/hid.h> |
| 17 | 18 | #include <linux/hwmon.h> |
| 18 | 19 | #include <linux/jiffies.h> |
| 20 | +#include <linux/ktime.h> | |
| 19 | 21 | #include <linux/module.h> |
| 20 | 22 | #include <linux/mutex.h> |
| 21 | 23 | #include <linux/seq_file.h> |
| @@ -63,6 +65,8 @@ static const char *const aqc_device_names[] = { · 41 unmodified lines | ||
| 63 | 65 | #define CTRL_REPORT_ID 0x03 |
| 64 | 66 | #define AQUAERO_CTRL_REPORT_ID 0x0b |
| 65 | 67 | |
| 68 | +#define CTRL_REPORT_DELAY 200 /* ms */ | |
| 69 | + | |
| 66 | 70 | /* The HID report that the official software always sends |
| 67 | 71 | * after writing values, currently same for all devices |
| 68 | 72 | */ |
| @@ -527,6 +531,9 @@ struct aqc_data { · 458 unmodified lines | ||
| 527 | 531 | int secondary_ctrl_report_size; |
| 528 | 532 | u8 *secondary_ctrl_report; |
| 529 | 533 | |
| 534 | + ktime_t last_ctrl_report_op; | |
| 535 | + int ctrl_report_delay; /* Delay between two ctrl report operations, in ms */ | |
| 536 | + | |
| 530 | 537 | int buffer_size; |
| 531 | 538 | u8 *buffer; |
| 532 | 539 | int checksum_start; |
| @@ -611,17 +618,35 @@ static int aqc_aquastreamxt_convert_fan_rpm(u16 val) · 78 unmodified lines | ||
| 611 | 618 | return 0; |
| 612 | 619 | } |
| 613 | 620 | |
| 621 | +static void aqc_delay_ctrl_report(struct aqc_data *priv) | |
| 622 | +{ | |
| 623 | + /* | |
| 624 | + * If previous read or write is too close to this one, delay the current operation | |
| 625 | + * to give the device enough time to process the previous one. | |
| 626 | + */ | |
| 627 | + if (priv->ctrl_report_delay) { | |
| 628 | + s64 delta = ktime_ms_delta(ktime_get(), priv->last_ctrl_report_op); | |
| 629 | + | |
| 630 | + if (delta < priv->ctrl_report_delay) | |
| 631 | + msleep(priv->ctrl_report_delay - delta); | |
| 632 | + } | |
| 633 | +} | |
| 634 | + | |
| 614 | 635 | /* Expects the mutex to be locked */ |
| 615 | 636 | static int aqc_get_ctrl_data(struct aqc_data *priv) |
| 616 | 637 | { |
| 617 | 638 | int ret; |
| 618 | 639 | |
| 640 | + aqc_delay_ctrl_report(priv); | |
| 641 | + | |
| 619 | 642 | memset(priv->buffer, 0x00, priv->buffer_size); |
| 620 | 643 | ret = hid_hw_raw_request(priv->hdev, priv->ctrl_report_id, priv->buffer, priv->buffer_size, |
| 621 | 644 | HID_FEATURE_REPORT, HID_REQ_GET_REPORT); |
| 622 | 645 | if (ret < 0) |
| 623 | 646 | ret = -ENODATA; |
| 624 | 647 | |
| 648 | + priv->last_ctrl_report_op = ktime_get(); | |
| 649 | + | |
| 625 | 650 | return ret; |
| 626 | 651 | } |
| 627 | 652 | |
| @@ -631,6 +656,8 @@ static int aqc_send_ctrl_data(struct aqc_data *priv) · 3 unmodified lines | ||
| 631 | 656 | int ret; |
| 632 | 657 | u16 checksum; |
| 633 | 658 | |
| 659 | + aqc_delay_ctrl_report(priv); | |
| 660 | + | |
| 634 | 661 | /* Checksum is not needed for Aquaero */ |
| 635 | 662 | if (priv->kind != aquaero) { |
| 636 | 663 | /* Init and xorout value for CRC-16/USB is 0xffff */ |
| @@ -646,12 +673,16 @@ static int aqc_send_ctrl_data(struct aqc_data *priv) · 9 unmodified lines | ||
| 646 | 673 | ret = hid_hw_raw_request(priv->hdev, priv->ctrl_report_id, priv->buffer, priv->buffer_size, |
| 647 | 674 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); |
| 648 | 675 | if (ret < 0) |
| 649 | − return ret; | |
| 676 | + goto record_access_and_ret; | |
| 650 | 677 | |
| 651 | 678 | /* The official software sends this report after every change, so do it here as well */ |
| 652 | 679 | ret = hid_hw_raw_request(priv->hdev, priv->secondary_ctrl_report_id, |
| 653 | 680 | priv->secondary_ctrl_report, priv->secondary_ctrl_report_size, |
| 654 | 681 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); |
| 682 | + | |
| 683 | +record_access_and_ret: | |
| 684 | + priv->last_ctrl_report_op = ktime_get(); | |
| 685 | + | |
| 655 | 686 | return ret; |
| 656 | 687 | } |
| 657 | 688 | |
| @@ -1027,7 +1058,7 @@ static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, · 369 unmodified lines | ||
| 1027 | 1058 | if (ret < 0) |
| 1028 | 1059 | return ret; |
| 1029 | 1060 | |
| 1030 | − *val = aqc_percent_to_pwm(ret); | |
| 1061 | + *val = aqc_percent_to_pwm(*val); | |
| 1031 | 1062 | break; |
| 1032 | 1063 | } |
| 1033 | 1064 | break; |
| @@ -1524,6 +1555,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) · 490 unmodified lines | ||
| 1524 | 1555 | |
| 1525 | 1556 | priv->buffer_size = AQUAERO_CTRL_REPORT_SIZE; |
| 1526 | 1557 | priv->temp_ctrl_offset = AQUAERO_TEMP_CTRL_OFFSET; |
| 1558 | + priv->ctrl_report_delay = CTRL_REPORT_DELAY; | |
| 1527 | 1559 | |
| 1528 | 1560 | priv->temp_label = label_temp_sensors; |
| 1529 | 1561 | priv->virtual_temp_label = label_virtual_temp_sensors; |
| @@ -1547,6 +1579,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) · 17 unmodified lines | ||
| 1547 | 1579 | priv->temp_ctrl_offset = D5NEXT_TEMP_CTRL_OFFSET; |
| 1548 | 1580 | |
| 1549 | 1581 | priv->buffer_size = D5NEXT_CTRL_REPORT_SIZE; |
| 1582 | + priv->ctrl_report_delay = CTRL_REPORT_DELAY; | |
| 1550 | 1583 | |
| 1551 | 1584 | priv->power_cycle_count_offset = D5NEXT_POWER_CYCLES; |
| 1552 | 1585 | |
| @@ -1597,6 +1630,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) · 44 unmodified lines | ||
| 1597 | 1630 | priv->temp_ctrl_offset = OCTO_TEMP_CTRL_OFFSET; |
| 1598 | 1631 | |
| 1599 | 1632 | priv->buffer_size = OCTO_CTRL_REPORT_SIZE; |
| 1633 | + priv->ctrl_report_delay = CTRL_REPORT_DELAY; | |
| 1600 | 1634 | |
| 1601 | 1635 | priv->power_cycle_count_offset = OCTO_POWER_CYCLES; |
| 1602 | 1636 | |
| @@ -1624,6 +1658,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) · 21 unmodified lines | ||
| 1624 | 1658 | priv->temp_ctrl_offset = QUADRO_TEMP_CTRL_OFFSET; |
| 1625 | 1659 | |
| 1626 | 1660 | priv->buffer_size = QUADRO_CTRL_REPORT_SIZE; |
| 1661 | + priv->ctrl_report_delay = CTRL_REPORT_DELAY; | |
| 1627 | 1662 | |
| 1628 | 1663 | priv->flow_pulses_ctrl_offset = QUADRO_FLOW_PULSES_CTRL_OFFSET; |
| 1629 | 1664 | priv->power_cycle_count_offset = QUADRO_POWER_CYCLES; |
| @@ -77,6 +77,13 @@ static DEFINE_MUTEX(nb_smu_ind_mutex); · 76 unmodified lines | ||
| 77 | 77 | #define ZEN_CUR_TEMP_RANGE_SEL_MASK BIT(19) |
| 78 | 78 | #define ZEN_CUR_TEMP_TJ_SEL_MASK GENMASK(17, 16) |
| 79 | 79 | |
| 80 | +/* | |
| 81 | + * AMD's Industrial processor 3255 supports temperature from -40 deg to 105 deg Celsius. | |
| 82 | + * Use the model name to identify 3255 CPUs and set a flag to display negative temperature. | |
| 83 | + * Do not round off to zero for negative Tctl or Tdie values if the flag is set | |
| 84 | + */ | |
| 85 | +#define AMD_I3255_STR "3255" | |
| 86 | + | |
| 80 | 87 | struct k10temp_data { |
| 81 | 88 | struct pci_dev *pdev; |
| 82 | 89 | void (*read_htcreg)(struct pci_dev *pdev, u32 *regval); |
| @@ -86,6 +93,7 @@ struct k10temp_data { · 3 unmodified lines | ||
| 86 | 93 | u32 show_temp; |
| 87 | 94 | bool is_zen; |
| 88 | 95 | u32 ccd_offset; |
| 96 | + bool disp_negative; | |
| 89 | 97 | }; |
| 90 | 98 | |
| 91 | 99 | #define TCTL_BIT 0 |
| @@ -204,12 +212,12 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel, · 112 unmodified lines | ||
| 204 | 212 | switch (channel) { |
| 205 | 213 | case 0: /* Tctl */ |
| 206 | 214 | *val = get_raw_temp(data); |
| 207 | − if (*val < 0) | |
| 215 | + if (*val < 0 && !data->disp_negative) | |
| 208 | 216 | *val = 0; |
| 209 | 217 | break; |
| 210 | 218 | case 1: /* Tdie */ |
| 211 | 219 | *val = get_raw_temp(data) - data->temp_offset; |
| 212 | − if (*val < 0) | |
| 220 | + if (*val < 0 && !data->disp_negative) | |
| 213 | 221 | *val = 0; |
| 214 | 222 | break; |
| 215 | 223 | case 2 ... 13: /* Tccd{1-12} */ |
| @@ -405,6 +413,11 @@ static int k10temp_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 189 unmodified lines | ||
| 405 | 413 | data->pdev = pdev; |
| 406 | 414 | data->show_temp |= BIT(TCTL_BIT); /* Always show Tctl */ |
| 407 | 415 | |
| 416 | + if (boot_cpu_data.x86 == 0x17 && | |
| 417 | + strstr(boot_cpu_data.x86_model_id, AMD_I3255_STR)) { | |
| 418 | + data->disp_negative = true; | |
| 419 | + } | |
| 420 | + | |
| 408 | 421 | if (boot_cpu_data.x86 == 0x15 && |
| 409 | 422 | ((boot_cpu_data.x86_model & 0xf0) == 0x60 || |
| 410 | 423 | (boot_cpu_data.x86_model & 0xf0) == 0x70)) { |
| @@ -955,14 +955,25 @@ static const u16 scale_in[15] = { · 954 unmodified lines | ||
| 955 | 955 | 800, 800 |
| 956 | 956 | }; |
| 957 | 957 | |
| 958 | −static inline long in_from_reg(u8 reg, u8 nr) | |
| 958 | +/* | |
| 959 | + * NCT6798 scaling: | |
| 960 | + * CPUVC, IN1, AVSB, 3VCC, IN0, IN8, IN4, 3VSB, VBAT, VTT, IN5, IN6, IN2, | |
| 961 | + * IN3, IN7 | |
| 962 | + * Additional scales to be added later: IN9 (800), VHIF (1600) | |
| 963 | + */ | |
| 964 | +static const u16 scale_in_6798[15] = { | |
| 965 | + 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 1600, 1600, 1600, 800, | |
| 966 | + 800, 800 | |
| 967 | +}; | |
| 968 | + | |
| 969 | +static inline long in_from_reg(u8 reg, u8 nr, const u16 *scales) | |
| 959 | 970 | { |
| 960 | − return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100); | |
| 971 | + return DIV_ROUND_CLOSEST(reg * scales[nr], 100); | |
| 961 | 972 | } |
| 962 | 973 | |
| 963 | −static inline u8 in_to_reg(u32 val, u8 nr) | |
| 974 | +static inline u8 in_to_reg(u32 val, u8 nr, const u16 *scales) | |
| 964 | 975 | { |
| 965 | − return clamp_val(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0, 255); | |
| 976 | + return clamp_val(DIV_ROUND_CLOSEST(val * 100, scales[nr]), 0, 255); | |
| 966 | 977 | } |
| 967 | 978 | |
| 968 | 979 | /* TSI temperatures are in 8.3 format */ |
| @@ -1673,7 +1684,8 @@ show_in_reg(struct device *dev, struct device_attribute *attr, char *buf) · 704 unmodified lines | ||
| 1673 | 1684 | if (IS_ERR(data)) |
| 1674 | 1685 | return PTR_ERR(data); |
| 1675 | 1686 | |
| 1676 | − return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr)); | |
| 1687 | + return sprintf(buf, "%ld\n", | |
| 1688 | + in_from_reg(data->in[nr][index], nr, data->scale_in)); | |
| 1677 | 1689 | } |
| 1678 | 1690 | |
| 1679 | 1691 | static ssize_t |
| @@ -1691,7 +1703,7 @@ store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf, · 11 unmodified lines | ||
| 1691 | 1703 | if (err < 0) |
| 1692 | 1704 | return err; |
| 1693 | 1705 | mutex_lock(&data->update_lock); |
| 1694 | − data->in[nr][index] = in_to_reg(val, nr); | |
| 1706 | + data->in[nr][index] = in_to_reg(val, nr, data->scale_in); | |
| 1695 | 1707 | err = nct6775_write_value(data, data->REG_IN_MINMAX[index - 1][nr], data->in[nr][index]); |
| 1696 | 1708 | mutex_unlock(&data->update_lock); |
| 1697 | 1709 | return err ? : count; |
| @@ -3462,6 +3474,7 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data, · 1764 unmodified lines | ||
| 3462 | 3474 | mutex_init(&data->update_lock); |
| 3463 | 3475 | data->name = nct6775_device_names[data->kind]; |
| 3464 | 3476 | data->bank = 0xff; /* Force initial bank selection */ |
| 3477 | + data->scale_in = scale_in; | |
| 3465 | 3478 | |
| 3466 | 3479 | switch (data->kind) { |
| 3467 | 3480 | case nct6106: |
| @@ -3977,6 +3990,9 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data, · 509 unmodified lines | ||
| 3977 | 3990 | break; |
| 3978 | 3991 | } |
| 3979 | 3992 | |
| 3993 | + if (data->kind == nct6798 || data->kind == nct6799) | |
| 3994 | + data->scale_in = scale_in_6798; | |
| 3995 | + | |
| 3980 | 3996 | reg_temp = NCT6779_REG_TEMP; |
| 3981 | 3997 | num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP); |
| 3982 | 3998 | if (data->kind == nct6791) { |
| @@ -586,7 +586,7 @@ nct6775_check_fan_inputs(struct nct6775_data *data, struct nct6775_sio_data *sio · 585 unmodified lines | ||
| 586 | 586 | int creb; |
| 587 | 587 | int cred; |
| 588 | 588 | |
| 589 | − cre6 = sio_data->sio_inb(sio_data, 0xe0); | |
| 589 | + cre6 = sio_data->sio_inb(sio_data, 0xe6); | |
| 590 | 590 | |
| 591 | 591 | sio_data->sio_select(sio_data, NCT6775_LD_12); |
| 592 | 592 | cre0 = sio_data->sio_inb(sio_data, 0xe0); |
| @@ -98,6 +98,7 @@ struct nct6775_data { · 97 unmodified lines | ||
| 98 | 98 | u8 bank; /* current register bank */ |
| 99 | 99 | u8 in_num; /* number of in inputs we have */ |
| 100 | 100 | u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */ |
| 101 | + const u16 *scale_in; /* internal scaling factors */ | |
| 101 | 102 | unsigned int rpm[NUM_FAN]; |
| 102 | 103 | u16 fan_min[NUM_FAN]; |
| 103 | 104 | u8 fan_pulses[NUM_FAN]; |
| @@ -725,7 +725,7 @@ static umode_t nct7802_temp_is_visible(struct kobject *kobj, · 724 unmodified lines | ||
| 725 | 725 | if (index >= 38 && index < 46 && !(reg & 0x01)) /* PECI 0 */ |
| 726 | 726 | return 0; |
| 727 | 727 | |
| 728 | − if (index >= 0x46 && (!(reg & 0x02))) /* PECI 1 */ | |
| 728 | + if (index >= 46 && !(reg & 0x02)) /* PECI 1 */ | |
| 729 | 729 | return 0; |
| 730 | 730 | |
| 731 | 731 | return attr->mode; |
| @@ -220,6 +220,20 @@ static int tt_toggle_disable(void) · 219 unmodified lines | ||
| 220 | 220 | } |
| 221 | 221 | |
| 222 | 222 | /* Callbacks for turbo toggle attribute */ |
| 223 | +static umode_t tt_toggle_is_visible(struct kobject *kobj, | |
| 224 | + struct attribute *attr, int n) | |
| 225 | +{ | |
| 226 | + switch (board) { | |
| 227 | + case aok_zoe_a1: | |
| 228 | + case oxp_mini_amd_a07: | |
| 229 | + case oxp_mini_amd_pro: | |
| 230 | + return attr->mode; | |
| 231 | + default: | |
| 232 | + break; | |
| 233 | + } | |
| 234 | + return 0; | |
| 235 | +} | |
| 236 | + | |
| 223 | 237 | static ssize_t tt_toggle_store(struct device *dev, |
| 224 | 238 | struct device_attribute *attr, const char *buf, |
| 225 | 239 | size_t count) |
| @@ -396,7 +410,15 @@ static struct attribute *oxp_ec_attrs[] = { · 170 unmodified lines | ||
| 396 | 410 | NULL |
| 397 | 411 | }; |
| 398 | 412 | |
| 399 | −ATTRIBUTE_GROUPS(oxp_ec); | |
| 413 | +static struct attribute_group oxp_ec_attribute_group = { | |
| 414 | + .is_visible = tt_toggle_is_visible, | |
| 415 | + .attrs = oxp_ec_attrs, | |
| 416 | +}; | |
| 417 | + | |
| 418 | +static const struct attribute_group *oxp_ec_groups[] = { | |
| 419 | + &oxp_ec_attribute_group, | |
| 420 | + NULL | |
| 421 | +}; | |
| 400 | 422 | |
| 401 | 423 | static const struct hwmon_ops oxp_ec_hwmon_ops = { |
| 402 | 424 | .is_visible = oxp_ec_hwmon_is_visible, |
| @@ -415,7 +437,6 @@ static int oxp_platform_probe(struct platform_device *pdev) · 12 unmodified lines | ||
| 415 | 437 | const struct dmi_system_id *dmi_entry; |
| 416 | 438 | struct device *dev = &pdev->dev; |
| 417 | 439 | struct device *hwdev; |
| 418 | − int ret; | |
| 419 | 440 | |
| 420 | 441 | /* |
| 421 | 442 | * Have to check for AMD processor here because DMI strings are the |
| @@ -430,18 +451,6 @@ static int oxp_platform_probe(struct platform_device *pdev) · 8 unmodified lines | ||
| 430 | 451 | |
| 431 | 452 | board = (enum oxp_board)(unsigned long)dmi_entry->driver_data; |
| 432 | 453 | |
| 433 | − switch (board) { | |
| 434 | − case aok_zoe_a1: | |
| 435 | − case oxp_mini_amd_a07: | |
| 436 | − case oxp_mini_amd_pro: | |
| 437 | − ret = devm_device_add_groups(dev, oxp_ec_groups); | |
| 438 | − if (ret) | |
| 439 | − return ret; | |
| 440 | − break; | |
| 441 | − default: | |
| 442 | − break; | |
| 443 | − } | |
| 444 | − | |
| 445 | 454 | hwdev = devm_hwmon_device_register_with_info(dev, "oxpec", NULL, |
| 446 | 455 | &oxp_ec_chip_info, NULL); |
| 447 | 456 | |
| @@ -451,6 +460,7 @@ static int oxp_platform_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 451 | 460 | static struct platform_driver oxp_platform_driver = { |
| 452 | 461 | .driver = { |
| 453 | 462 | .name = "oxp-platform", |
| 463 | + .dev_groups = oxp_ec_groups, | |
| 454 | 464 | }, |
| 455 | 465 | .probe = oxp_platform_probe, |
| 456 | 466 | }; |
| @@ -17,12 +17,13 @@ · 16 unmodified lines | ||
| 17 | 17 | enum chips {pfe1100, pfe3000}; |
| 18 | 18 | |
| 19 | 19 | /* |
| 20 | − * Disable status check for pfe3000 devices, because some devices report | |
| 21 | − * communication error (invalid command) for VOUT_MODE command (0x20) | |
| 22 | − * although correct VOUT_MODE (0x16) is returned: it leads to incorrect | |
| 23 | − * exponent in linear mode. | |
| 20 | + * Disable status check because some devices report communication error | |
| 21 | + * (invalid command) for VOUT_MODE command (0x20) although the correct | |
| 22 | + * VOUT_MODE (0x16) is returned: it leads to incorrect exponent in linear | |
| 23 | + * mode. | |
| 24 | + * This affects both pfe3000 and pfe1100. | |
| 24 | 25 | */ |
| 25 | −static struct pmbus_platform_data pfe3000_plat_data = { | |
| 26 | +static struct pmbus_platform_data pfe_plat_data = { | |
| 26 | 27 | .flags = PMBUS_SKIP_STATUS_CHECK, |
| 27 | 28 | }; |
| 28 | 29 | |
| @@ -94,16 +95,15 @@ static int pfe_pmbus_probe(struct i2c_client *client) · 65 unmodified lines | ||
| 94 | 95 | int model; |
| 95 | 96 | |
| 96 | 97 | model = (int)i2c_match_id(pfe_device_id, client)->driver_data; |
| 98 | + client->dev.platform_data = &pfe_plat_data; | |
| 97 | 99 | |
| 98 | 100 | /* |
| 99 | 101 | * PFE3000-12-069RA devices may not stay in page 0 during device |
| 100 | 102 | * probe which leads to probe failure (read status word failed). |
| 101 | 103 | * So let's set the device to page 0 at the beginning. |
| 102 | 104 | */ |
| 103 | − if (model == pfe3000) { | |
| 104 | − client->dev.platform_data = &pfe3000_plat_data; | |
| 105 | + if (model == pfe3000) | |
| 105 | 106 | i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0); |
| 106 | − } | |
| 107 | 107 | |
| 108 | 108 | return pmbus_do_probe(client, &pfe_driver_info[model]); |
| 109 | 109 | } |
| @@ -2745,9 +2745,8 @@ static const struct pmbus_status_category __maybe_unused pmbus_status_flag_map[] · 2744 unmodified lines | ||
| 2745 | 2745 | }, |
| 2746 | 2746 | }; |
| 2747 | 2747 | |
| 2748 | −static int _pmbus_is_enabled(struct device *dev, u8 page) | |
| 2748 | +static int _pmbus_is_enabled(struct i2c_client *client, u8 page) | |
| 2749 | 2749 | { |
| 2750 | − struct i2c_client *client = to_i2c_client(dev->parent); | |
| 2751 | 2750 | int ret; |
| 2752 | 2751 | |
| 2753 | 2752 | ret = _pmbus_read_byte_data(client, page, PMBUS_OPERATION); |
| @@ -2758,17 +2757,16 @@ static int _pmbus_is_enabled(struct device *dev, u8 page) · 4 unmodified lines | ||
| 2758 | 2757 | return !!(ret & PB_OPERATION_CONTROL_ON); |
| 2759 | 2758 | } |
| 2760 | 2759 | |
| 2761 | −static int __maybe_unused pmbus_is_enabled(struct device *dev, u8 page) | |
| 2760 | +static int __maybe_unused pmbus_is_enabled(struct i2c_client *client, u8 page) | |
| 2762 | 2761 | { |
| 2763 | − struct i2c_client *client = to_i2c_client(dev->parent); | |
| 2764 | 2762 | struct pmbus_data *data = i2c_get_clientdata(client); |
| 2765 | 2763 | int ret; |
| 2766 | 2764 | |
| 2767 | 2765 | mutex_lock(&data->update_lock); |
| 2768 | − ret = _pmbus_is_enabled(dev, page); | |
| 2766 | + ret = _pmbus_is_enabled(client, page); | |
| 2769 | 2767 | mutex_unlock(&data->update_lock); |
| 2770 | 2768 | |
| 2771 | − return !!(ret & PB_OPERATION_CONTROL_ON); | |
| 2769 | + return ret; | |
| 2772 | 2770 | } |
| 2773 | 2771 | |
| 2774 | 2772 | #define to_dev_attr(_dev_attr) \ |
| @@ -2844,7 +2842,7 @@ static int _pmbus_get_flags(struct pmbus_data *data, u8 page, unsigned int *flag · 69 unmodified lines | ||
| 2844 | 2842 | if (status < 0) |
| 2845 | 2843 | return status; |
| 2846 | 2844 | |
| 2847 | − if (_pmbus_is_enabled(dev, page)) { | |
| 2845 | + if (_pmbus_is_enabled(client, page)) { | |
| 2848 | 2846 | if (status & PB_STATUS_OFF) { |
| 2849 | 2847 | *flags |= REGULATOR_ERROR_FAIL; |
| 2850 | 2848 | *event |= REGULATOR_EVENT_FAIL; |
| @@ -2898,7 +2896,10 @@ static int __maybe_unused pmbus_get_flags(struct pmbus_data *data, u8 page, unsi · 47 unmodified lines | ||
| 2898 | 2896 | #if IS_ENABLED(CONFIG_REGULATOR) |
| 2899 | 2897 | static int pmbus_regulator_is_enabled(struct regulator_dev *rdev) |
| 2900 | 2898 | { |
| 2901 | − return pmbus_is_enabled(rdev_get_dev(rdev), rdev_get_id(rdev)); | |
| 2899 | + struct device *dev = rdev_get_dev(rdev); | |
| 2900 | + struct i2c_client *client = to_i2c_client(dev->parent); | |
| 2901 | + | |
| 2902 | + return pmbus_is_enabled(client, rdev_get_id(rdev)); | |
| 2902 | 2903 | } |
| 2903 | 2904 | |
| 2904 | 2905 | static int _pmbus_regulator_on_off(struct regulator_dev *rdev, bool enable) |
| @@ -2945,6 +2946,7 @@ static int pmbus_regulator_get_status(struct regulator_dev *rdev) · 40 unmodified lines | ||
| 2945 | 2946 | struct pmbus_data *data = i2c_get_clientdata(client); |
| 2946 | 2947 | u8 page = rdev_get_id(rdev); |
| 2947 | 2948 | int status, ret; |
| 2949 | + int event; | |
| 2948 | 2950 | |
| 2949 | 2951 | mutex_lock(&data->update_lock); |
| 2950 | 2952 | status = pmbus_get_status(client, page, PMBUS_STATUS_WORD); |
| @@ -2964,7 +2966,7 @@ static int pmbus_regulator_get_status(struct regulator_dev *rdev) · 13 unmodified lines | ||
| 2964 | 2966 | goto unlock; |
| 2965 | 2967 | } |
| 2966 | 2968 | |
| 2967 | − ret = pmbus_regulator_get_error_flags(rdev, &status); | |
| 2969 | + ret = _pmbus_get_flags(data, rdev_get_id(rdev), &status, &event, false); | |
| 2968 | 2970 | if (ret) |
| 2969 | 2971 | goto unlock; |
| 2970 | 2972 | |
| @@ -62,7 +62,6 @@ · 61 unmodified lines | ||
| 62 | 62 | #define AD7192_MODE_STA_MASK BIT(20) /* Status Register transmission Mask */ |
| 63 | 63 | #define AD7192_MODE_CLKSRC(x) (((x) & 0x3) << 18) /* Clock Source Select */ |
| 64 | 64 | #define AD7192_MODE_SINC3 BIT(15) /* SINC3 Filter Select */ |
| 65 | −#define AD7192_MODE_ACX BIT(14) /* AC excitation enable(AD7195 only)*/ | |
| 66 | 65 | #define AD7192_MODE_ENPAR BIT(13) /* Parity Enable */ |
| 67 | 66 | #define AD7192_MODE_CLKDIV BIT(12) /* Clock divide by 2 (AD7190/2 only)*/ |
| 68 | 67 | #define AD7192_MODE_SCYCLE BIT(11) /* Single cycle conversion */ |
| @@ -91,6 +90,7 @@ · 22 unmodified lines | ||
| 91 | 90 | /* Configuration Register Bit Designations (AD7192_REG_CONF) */ |
| 92 | 91 | |
| 93 | 92 | #define AD7192_CONF_CHOP BIT(23) /* CHOP enable */ |
| 93 | +#define AD7192_CONF_ACX BIT(22) /* AC excitation enable(AD7195 only) */ | |
| 94 | 94 | #define AD7192_CONF_REFSEL BIT(20) /* REFIN1/REFIN2 Reference Select */ |
| 95 | 95 | #define AD7192_CONF_CHAN(x) ((x) << 8) /* Channel select */ |
| 96 | 96 | #define AD7192_CONF_CHAN_MASK (0x7FF << 8) /* Channel select mask */ |
| @@ -472,7 +472,7 @@ static ssize_t ad7192_show_ac_excitation(struct device *dev, · 375 unmodified lines | ||
| 472 | 472 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
| 473 | 473 | struct ad7192_state *st = iio_priv(indio_dev); |
| 474 | 474 | |
| 475 | − return sysfs_emit(buf, "%d\n", !!(st->mode & AD7192_MODE_ACX)); | |
| 475 | + return sysfs_emit(buf, "%d\n", !!(st->conf & AD7192_CONF_ACX)); | |
| 476 | 476 | } |
| 477 | 477 | |
| 478 | 478 | static ssize_t ad7192_show_bridge_switch(struct device *dev, |
| @@ -513,13 +513,13 @@ static ssize_t ad7192_set(struct device *dev, · 34 unmodified lines | ||
| 513 | 513 | |
| 514 | 514 | ad_sd_write_reg(&st->sd, AD7192_REG_GPOCON, 1, st->gpocon); |
| 515 | 515 | break; |
| 516 | − case AD7192_REG_MODE: | |
| 516 | + case AD7192_REG_CONF: | |
| 517 | 517 | if (val) |
| 518 | − st->mode |= AD7192_MODE_ACX; | |
| 518 | + st->conf |= AD7192_CONF_ACX; | |
| 519 | 519 | else |
| 520 | − st->mode &= ~AD7192_MODE_ACX; | |
| 520 | + st->conf &= ~AD7192_CONF_ACX; | |
| 521 | 521 | |
| 522 | − ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); | |
| 522 | + ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, st->conf); | |
| 523 | 523 | break; |
| 524 | 524 | default: |
| 525 | 525 | ret = -EINVAL; |
| @@ -579,12 +579,11 @@ static IIO_DEVICE_ATTR(bridge_switch_en, 0644, · 53 unmodified lines | ||
| 579 | 579 | |
| 580 | 580 | static IIO_DEVICE_ATTR(ac_excitation_en, 0644, |
| 581 | 581 | ad7192_show_ac_excitation, ad7192_set, |
| 582 | − AD7192_REG_MODE); | |
| 582 | + AD7192_REG_CONF); | |
| 583 | 583 | |
| 584 | 584 | static struct attribute *ad7192_attributes[] = { |
| 585 | 585 | &iio_dev_attr_filter_low_pass_3db_frequency_available.dev_attr.attr, |
| 586 | 586 | &iio_dev_attr_bridge_switch_en.dev_attr.attr, |
| 587 | − &iio_dev_attr_ac_excitation_en.dev_attr.attr, | |
| 588 | 587 | NULL |
| 589 | 588 | }; |
| 590 | 589 | |
| @@ -595,6 +594,7 @@ static const struct attribute_group ad7192_attribute_group = { · 4 unmodified lines | ||
| 595 | 594 | static struct attribute *ad7195_attributes[] = { |
| 596 | 595 | &iio_dev_attr_filter_low_pass_3db_frequency_available.dev_attr.attr, |
| 597 | 596 | &iio_dev_attr_bridge_switch_en.dev_attr.attr, |
| 597 | + &iio_dev_attr_ac_excitation_en.dev_attr.attr, | |
| 598 | 598 | NULL |
| 599 | 599 | }; |
| 600 | 600 | |
| @@ -124,6 +124,7 @@ static const struct regmap_config ina2xx_regmap_config = { · 123 unmodified lines | ||
| 124 | 124 | enum ina2xx_ids { ina219, ina226 }; |
| 125 | 125 | |
| 126 | 126 | struct ina2xx_config { |
| 127 | + const char *name; | |
| 127 | 128 | u16 config_default; |
| 128 | 129 | int calibration_value; |
| 129 | 130 | int shunt_voltage_lsb; /* nV */ |
| @@ -155,6 +156,7 @@ struct ina2xx_chip_info { · 25 unmodified lines | ||
| 155 | 156 | |
| 156 | 157 | static const struct ina2xx_config ina2xx_config[] = { |
| 157 | 158 | [ina219] = { |
| 159 | + .name = "ina219", | |
| 158 | 160 | .config_default = INA219_CONFIG_DEFAULT, |
| 159 | 161 | .calibration_value = 4096, |
| 160 | 162 | .shunt_voltage_lsb = 10000, |
| @@ -164,6 +166,7 @@ static const struct ina2xx_config ina2xx_config[] = { · 3 unmodified lines | ||
| 164 | 166 | .chip_id = ina219, |
| 165 | 167 | }, |
| 166 | 168 | [ina226] = { |
| 169 | + .name = "ina226", | |
| 167 | 170 | .config_default = INA226_CONFIG_DEFAULT, |
| 168 | 171 | .calibration_value = 2048, |
| 169 | 172 | .shunt_voltage_lsb = 2500, |
| @@ -996,7 +999,7 @@ static int ina2xx_probe(struct i2c_client *client) · 826 unmodified lines | ||
| 996 | 999 | /* Patch the current config register with default. */ |
| 997 | 1000 | val = chip->config->config_default; |
| 998 | 1001 | |
| 999 | − if (id->driver_data == ina226) { | |
| 1002 | + if (type == ina226) { | |
| 1000 | 1003 | ina226_set_average(chip, INA226_DEFAULT_AVG, &val); |
| 1001 | 1004 | ina226_set_int_time_vbus(chip, INA226_DEFAULT_IT, &val); |
| 1002 | 1005 | ina226_set_int_time_vshunt(chip, INA226_DEFAULT_IT, &val); |
| @@ -1015,7 +1018,7 @@ static int ina2xx_probe(struct i2c_client *client) · 12 unmodified lines | ||
| 1015 | 1018 | } |
| 1016 | 1019 | |
| 1017 | 1020 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 1018 | − if (id->driver_data == ina226) { | |
| 1021 | + if (type == ina226) { | |
| 1019 | 1022 | indio_dev->channels = ina226_channels; |
| 1020 | 1023 | indio_dev->num_channels = ARRAY_SIZE(ina226_channels); |
| 1021 | 1024 | indio_dev->info = &ina226_info; |
| @@ -1024,7 +1027,7 @@ static int ina2xx_probe(struct i2c_client *client) · 2 unmodified lines | ||
| 1024 | 1027 | indio_dev->num_channels = ARRAY_SIZE(ina219_channels); |
| 1025 | 1028 | indio_dev->info = &ina219_info; |
| 1026 | 1029 | } |
| 1027 | − indio_dev->name = id->name; | |
| 1030 | + indio_dev->name = id ? id->name : chip->config->name; | |
| 1028 | 1031 | |
| 1029 | 1032 | ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev, |
| 1030 | 1033 | &ina2xx_setup_ops); |
| @@ -916,12 +916,6 @@ static int meson_sar_adc_hw_enable(struct iio_dev *indio_dev) · 915 unmodified lines | ||
| 916 | 916 | goto err_vref; |
| 917 | 917 | } |
| 918 | 918 | |
| 919 | − ret = clk_prepare_enable(priv->core_clk); | |
| 920 | − if (ret) { | |
| 921 | − dev_err(dev, "failed to enable core clk\n"); | |
| 922 | − goto err_core_clk; | |
| 923 | − } | |
| 924 | − | |
| 925 | 919 | regval = FIELD_PREP(MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, 1); |
| 926 | 920 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, |
| 927 | 921 | MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, regval); |
| @@ -948,8 +942,6 @@ err_adc_clk: · 20 unmodified lines | ||
| 948 | 942 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, |
| 949 | 943 | MESON_SAR_ADC_REG3_ADC_EN, 0); |
| 950 | 944 | meson_sar_adc_set_bandgap(indio_dev, false); |
| 951 | − clk_disable_unprepare(priv->core_clk); | |
| 952 | −err_core_clk: | |
| 953 | 945 | regulator_disable(priv->vref); |
| 954 | 946 | err_vref: |
| 955 | 947 | meson_sar_adc_unlock(indio_dev); |
| @@ -977,8 +969,6 @@ static void meson_sar_adc_hw_disable(struct iio_dev *indio_dev) · 21 unmodified lines | ||
| 977 | 969 | |
| 978 | 970 | meson_sar_adc_set_bandgap(indio_dev, false); |
| 979 | 971 | |
| 980 | − clk_disable_unprepare(priv->core_clk); | |
| 981 | − | |
| 982 | 972 | regulator_disable(priv->vref); |
| 983 | 973 | |
| 984 | 974 | if (!ret) |
| @@ -1211,7 +1201,7 @@ static int meson_sar_adc_probe(struct platform_device *pdev) · 226 unmodified lines | ||
| 1211 | 1201 | if (IS_ERR(priv->clkin)) |
| 1212 | 1202 | return dev_err_probe(dev, PTR_ERR(priv->clkin), "failed to get clkin\n"); |
| 1213 | 1203 | |
| 1214 | − priv->core_clk = devm_clk_get(dev, "core"); | |
| 1204 | + priv->core_clk = devm_clk_get_enabled(dev, "core"); | |
| 1215 | 1205 | if (IS_ERR(priv->core_clk)) |
| 1216 | 1206 | return dev_err_probe(dev, PTR_ERR(priv->core_clk), "failed to get core clk\n"); |
| 1217 | 1207 | |
| @@ -1294,15 +1284,26 @@ static int meson_sar_adc_remove(struct platform_device *pdev) · 76 unmodified lines | ||
| 1294 | 1284 | static int meson_sar_adc_suspend(struct device *dev) |
| 1295 | 1285 | { |
| 1296 | 1286 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
| 1287 | + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
| 1297 | 1288 | |
| 1298 | 1289 | meson_sar_adc_hw_disable(indio_dev); |
| 1299 | 1290 | |
| 1291 | + clk_disable_unprepare(priv->core_clk); | |
| 1292 | + | |
| 1300 | 1293 | return 0; |
| 1301 | 1294 | } |
| 1302 | 1295 | |
| 1303 | 1296 | static int meson_sar_adc_resume(struct device *dev) |
| 1304 | 1297 | { |
| 1305 | 1298 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
| 1299 | + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | |
| 1300 | + int ret; | |
| 1301 | + | |
| 1302 | + ret = clk_prepare_enable(priv->core_clk); | |
| 1303 | + if (ret) { | |
| 1304 | + dev_err(dev, "failed to enable core clk\n"); | |
| 1305 | + return ret; | |
| 1306 | + } | |
| 1306 | 1307 | |
| 1307 | 1308 | return meson_sar_adc_hw_enable(indio_dev); |
| 1308 | 1309 | } |
| @@ -253,7 +253,7 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, · 252 unmodified lines | ||
| 253 | 253 | platform_set_drvdata(pdev, indio_dev); |
| 254 | 254 | |
| 255 | 255 | state->ec = ec->ec_dev; |
| 256 | − state->msg = devm_kzalloc(&pdev->dev, | |
| 256 | + state->msg = devm_kzalloc(&pdev->dev, sizeof(*state->msg) + | |
| 257 | 257 | max((u16)sizeof(struct ec_params_motion_sense), |
| 258 | 258 | state->ec->max_response), GFP_KERNEL); |
| 259 | 259 | if (!state->msg) |
| @@ -344,9 +344,12 @@ static int admv1013_update_quad_filters(struct admv1013_state *st) · 343 unmodified lines | ||
| 344 | 344 | |
| 345 | 345 | static int admv1013_update_mixer_vgate(struct admv1013_state *st) |
| 346 | 346 | { |
| 347 | − unsigned int vcm, mixer_vgate; | |
| 347 | + unsigned int mixer_vgate; | |
| 348 | + int vcm; | |
| 348 | 349 | |
| 349 | 350 | vcm = regulator_get_voltage(st->reg); |
| 351 | + if (vcm < 0) | |
| 352 | + return vcm; | |
| 350 | 353 | |
| 351 | 354 | if (vcm < 1800000) |
| 352 | 355 | mixer_vgate = (2389 * vcm / 1000000 + 8100) / 100; |
| @@ -2687,7 +2687,7 @@ unknown_format: · 2686 unmodified lines | ||
| 2687 | 2687 | static int lsm6dsx_get_acpi_mount_matrix(struct device *dev, |
| 2688 | 2688 | struct iio_mount_matrix *orientation) |
| 2689 | 2689 | { |
| 2690 | − return false; | |
| 2690 | + return -EOPNOTSUPP; | |
| 2691 | 2691 | } |
| 2692 | 2692 | |
| 2693 | 2693 | #endif |
| @@ -1888,7 +1888,7 @@ static const struct iio_buffer_setup_ops noop_ring_setup_ops; · 1887 unmodified lines | ||
| 1888 | 1888 | int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) |
| 1889 | 1889 | { |
| 1890 | 1890 | struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); |
| 1891 | − struct fwnode_handle *fwnode; | |
| 1891 | + struct fwnode_handle *fwnode = NULL; | |
| 1892 | 1892 | int ret; |
| 1893 | 1893 | |
| 1894 | 1894 | if (!indio_dev->info) |
| @@ -1899,7 +1899,8 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) · 4 unmodified lines | ||
| 1899 | 1899 | /* If the calling driver did not initialize firmware node, do it here */ |
| 1900 | 1900 | if (dev_fwnode(&indio_dev->dev)) |
| 1901 | 1901 | fwnode = dev_fwnode(&indio_dev->dev); |
| 1902 | − else | |
| 1902 | + /* The default dummy IIO device has no parent */ | |
| 1903 | + else if (indio_dev->dev.parent) | |
| 1903 | 1904 | fwnode = dev_fwnode(indio_dev->dev.parent); |
| 1904 | 1905 | device_set_node(&indio_dev->dev, fwnode); |
| 1905 | 1906 | |
| @@ -190,7 +190,7 @@ static const struct iio_itime_sel_mul bu27008_itimes[] = { · 189 unmodified lines | ||
| 190 | 190 | .address = BU27008_REG_##data##_LO, \ |
| 191 | 191 | .scan_index = BU27008_##color, \ |
| 192 | 192 | .scan_type = { \ |
| 193 | − .sign = 's', \ | |
| 193 | + .sign = 'u', \ | |
| 194 | 194 | .realbits = 16, \ |
| 195 | 195 | .storagebits = 16, \ |
| 196 | 196 | .endianness = IIO_LE, \ |
| @@ -633,7 +633,7 @@ static int bu27008_try_find_new_time_gain(struct bu27008_data *data, int val, · 436 unmodified lines | ||
| 633 | 633 | for (i = 0; i < data->gts.num_itime; i++) { |
| 634 | 634 | new_time_sel = data->gts.itime_table[i].sel; |
| 635 | 635 | ret = iio_gts_find_gain_sel_for_scale_using_time(&data->gts, |
| 636 | − new_time_sel, val, val2 * 1000, gain_sel); | |
| 636 | + new_time_sel, val, val2, gain_sel); | |
| 637 | 637 | if (!ret) |
| 638 | 638 | break; |
| 639 | 639 | } |
| @@ -662,7 +662,7 @@ static int bu27008_set_scale(struct bu27008_data *data, · 22 unmodified lines | ||
| 662 | 662 | goto unlock_out; |
| 663 | 663 | |
| 664 | 664 | ret = iio_gts_find_gain_sel_for_scale_using_time(&data->gts, time_sel, |
| 665 | − val, val2 * 1000, &gain_sel); | |
| 665 | + val, val2, &gain_sel); | |
| 666 | 666 | if (ret) { |
| 667 | 667 | ret = bu27008_try_find_new_time_gain(data, val, val2, &gain_sel); |
| 668 | 668 | if (ret) |
| @@ -677,6 +677,21 @@ unlock_out: · 8 unmodified lines | ||
| 677 | 677 | return ret; |
| 678 | 678 | } |
| 679 | 679 | |
| 680 | +static int bu27008_write_raw_get_fmt(struct iio_dev *indio_dev, | |
| 681 | + struct iio_chan_spec const *chan, | |
| 682 | + long mask) | |
| 683 | +{ | |
| 684 | + | |
| 685 | + switch (mask) { | |
| 686 | + case IIO_CHAN_INFO_SCALE: | |
| 687 | + return IIO_VAL_INT_PLUS_NANO; | |
| 688 | + case IIO_CHAN_INFO_INT_TIME: | |
| 689 | + return IIO_VAL_INT_PLUS_MICRO; | |
| 690 | + default: | |
| 691 | + return -EINVAL; | |
| 692 | + } | |
| 693 | +} | |
| 694 | + | |
| 680 | 695 | static int bu27008_write_raw(struct iio_dev *idev, |
| 681 | 696 | struct iio_chan_spec const *chan, |
| 682 | 697 | int val, int val2, long mask) |
| @@ -756,6 +771,7 @@ static int bu27008_update_scan_mode(struct iio_dev *idev, · 73 unmodified lines | ||
| 756 | 771 | static const struct iio_info bu27008_info = { |
| 757 | 772 | .read_raw = &bu27008_read_raw, |
| 758 | 773 | .write_raw = &bu27008_write_raw, |
| 774 | + .write_raw_get_fmt = &bu27008_write_raw_get_fmt, | |
| 759 | 775 | .read_avail = &bu27008_read_avail, |
| 760 | 776 | .update_scan_mode = bu27008_update_scan_mode, |
| 761 | 777 | .validate_trigger = iio_validate_own_trigger, |
| @@ -575,7 +575,7 @@ static int bu27034_set_scale(struct bu27034_data *data, int chan, · 574 unmodified lines | ||
| 575 | 575 | return -EINVAL; |
| 576 | 576 | |
| 577 | 577 | if (chan == BU27034_CHAN_ALS) { |
| 578 | − if (val == 0 && val2 == 1000) | |
| 578 | + if (val == 0 && val2 == 1000000) | |
| 579 | 579 | return 0; |
| 580 | 580 | |
| 581 | 581 | return -EINVAL; |
| @@ -587,7 +587,7 @@ static int bu27034_set_scale(struct bu27034_data *data, int chan, · 5 unmodified lines | ||
| 587 | 587 | goto unlock_out; |
| 588 | 588 | |
| 589 | 589 | ret = iio_gts_find_gain_sel_for_scale_using_time(&data->gts, time_sel, |
| 590 | − val, val2 * 1000, &gain_sel); | |
| 590 | + val, val2, &gain_sel); | |
| 591 | 591 | if (ret) { |
| 592 | 592 | /* |
| 593 | 593 | * Could not support scale with given time. Need to change time. |
| @@ -624,7 +624,7 @@ static int bu27034_set_scale(struct bu27034_data *data, int chan, · 30 unmodified lines | ||
| 624 | 624 | |
| 625 | 625 | /* Can we provide requested scale with this time? */ |
| 626 | 626 | ret = iio_gts_find_gain_sel_for_scale_using_time( |
| 627 | − &data->gts, new_time_sel, val, val2 * 1000, | |
| 627 | + &data->gts, new_time_sel, val, val2, | |
| 628 | 628 | &gain_sel); |
| 629 | 629 | if (ret) |
| 630 | 630 | continue; |
| @@ -1217,6 +1217,21 @@ static int bu27034_read_raw(struct iio_dev *idev, · 586 unmodified lines | ||
| 1217 | 1217 | } |
| 1218 | 1218 | } |
| 1219 | 1219 | |
| 1220 | +static int bu27034_write_raw_get_fmt(struct iio_dev *indio_dev, | |
| 1221 | + struct iio_chan_spec const *chan, | |
| 1222 | + long mask) | |
| 1223 | +{ | |
| 1224 | + | |
| 1225 | + switch (mask) { | |
| 1226 | + case IIO_CHAN_INFO_SCALE: | |
| 1227 | + return IIO_VAL_INT_PLUS_NANO; | |
| 1228 | + case IIO_CHAN_INFO_INT_TIME: | |
| 1229 | + return IIO_VAL_INT_PLUS_MICRO; | |
| 1230 | + default: | |
| 1231 | + return -EINVAL; | |
| 1232 | + } | |
| 1233 | +} | |
| 1234 | + | |
| 1220 | 1235 | static int bu27034_write_raw(struct iio_dev *idev, |
| 1221 | 1236 | struct iio_chan_spec const *chan, |
| 1222 | 1237 | int val, int val2, long mask) |
| @@ -1267,6 +1282,7 @@ static int bu27034_read_avail(struct iio_dev *idev, · 44 unmodified lines | ||
| 1267 | 1282 | static const struct iio_info bu27034_info = { |
| 1268 | 1283 | .read_raw = &bu27034_read_raw, |
| 1269 | 1284 | .write_raw = &bu27034_write_raw, |
| 1285 | + .write_raw_get_fmt = &bu27034_write_raw_get_fmt, | |
| 1270 | 1286 | .read_avail = &bu27034_read_avail, |
| 1271 | 1287 | }; |
| 1272 | 1288 | |
| @@ -4062,6 +4062,8 @@ static int resolve_prepare_src(struct rdma_id_private *id_priv, · 4061 unmodified lines | ||
| 4062 | 4062 | RDMA_CM_ADDR_QUERY))) |
| 4063 | 4063 | return -EINVAL; |
| 4064 | 4064 | |
| 4065 | + } else { | |
| 4066 | + memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr)); | |
| 4065 | 4067 | } |
| 4066 | 4068 | |
| 4067 | 4069 | if (cma_family(id_priv) != dst_addr->sa_family) { |
| @@ -85,6 +85,8 @@ unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem, · 84 unmodified lines | ||
| 85 | 85 | dma_addr_t mask; |
| 86 | 86 | int i; |
| 87 | 87 | |
| 88 | + umem->iova = va = virt; | |
| 89 | + | |
| 88 | 90 | if (umem->is_odp) { |
| 89 | 91 | unsigned int page_size = BIT(to_ib_umem_odp(umem)->page_shift); |
| 90 | 92 | |
| @@ -100,7 +102,6 @@ unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem, · 9 unmodified lines | ||
| 100 | 102 | */ |
| 101 | 103 | pgsz_bitmap &= GENMASK(BITS_PER_LONG - 1, PAGE_SHIFT); |
| 102 | 104 | |
| 103 | − umem->iova = va = virt; | |
| 104 | 105 | /* The best result is the smallest page size that results in the minimum |
| 105 | 106 | * number of required pages. Compute the largest page size that could |
| 106 | 107 | * work based on VA address bits that don't change. |
| @@ -869,7 +869,10 @@ fail: · 868 unmodified lines | ||
| 869 | 869 | int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata) |
| 870 | 870 | { |
| 871 | 871 | struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp); |
| 872 | + struct bnxt_qplib_qp *qplib_qp = &qp->qplib_qp; | |
| 872 | 873 | struct bnxt_re_dev *rdev = qp->rdev; |
| 874 | + struct bnxt_qplib_nq *scq_nq = NULL; | |
| 875 | + struct bnxt_qplib_nq *rcq_nq = NULL; | |
| 873 | 876 | unsigned int flags; |
| 874 | 877 | int rc; |
| 875 | 878 | |
| @@ -903,6 +906,15 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata) · 27 unmodified lines | ||
| 903 | 906 | ib_umem_release(qp->rumem); |
| 904 | 907 | ib_umem_release(qp->sumem); |
| 905 | 908 | |
| 909 | + /* Flush all the entries of notification queue associated with | |
| 910 | + * given qp. | |
| 911 | + */ | |
| 912 | + scq_nq = qplib_qp->scq->nq; | |
| 913 | + rcq_nq = qplib_qp->rcq->nq; | |
| 914 | + bnxt_re_synchronize_nq(scq_nq); | |
| 915 | + if (scq_nq != rcq_nq) | |
| 916 | + bnxt_re_synchronize_nq(rcq_nq); | |
| 917 | + | |
| 906 | 918 | return 0; |
| 907 | 919 | } |
| 908 | 920 | |
| @@ -1253,6 +1253,8 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 wqe_mode) · 1252 unmodified lines | ||
| 1253 | 1253 | |
| 1254 | 1254 | rc = bnxt_re_setup_chip_ctx(rdev, wqe_mode); |
| 1255 | 1255 | if (rc) { |
| 1256 | + bnxt_unregister_dev(rdev->en_dev); | |
| 1257 | + clear_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags); | |
| 1256 | 1258 | ibdev_err(&rdev->ibdev, "Failed to get chip context\n"); |
| 1257 | 1259 | return -EINVAL; |
| 1258 | 1260 | } |
| @@ -1526,8 +1528,8 @@ static void bnxt_re_remove(struct auxiliary_device *adev) · 267 unmodified lines | ||
| 1526 | 1528 | } |
| 1527 | 1529 | bnxt_re_setup_cc(rdev, false); |
| 1528 | 1530 | ib_unregister_device(&rdev->ibdev); |
| 1529 | − ib_dealloc_device(&rdev->ibdev); | |
| 1530 | 1531 | bnxt_re_dev_uninit(rdev); |
| 1532 | + ib_dealloc_device(&rdev->ibdev); | |
| 1531 | 1533 | skip_remove: |
| 1532 | 1534 | mutex_unlock(&bnxt_re_mutex); |
| 1533 | 1535 | } |
| @@ -381,6 +381,24 @@ static void bnxt_qplib_service_nq(struct tasklet_struct *t) · 380 unmodified lines | ||
| 381 | 381 | spin_unlock_bh(&hwq->lock); |
| 382 | 382 | } |
| 383 | 383 | |
| 384 | +/* bnxt_re_synchronize_nq - self polling notification queue. | |
| 385 | + * @nq - notification queue pointer | |
| 386 | + * | |
| 387 | + * This function will start polling entries of a given notification queue | |
| 388 | + * for all pending entries. | |
| 389 | + * This function is useful to synchronize notification entries while resources | |
| 390 | + * are going away. | |
| 391 | + */ | |
| 392 | + | |
| 393 | +void bnxt_re_synchronize_nq(struct bnxt_qplib_nq *nq) | |
| 394 | +{ | |
| 395 | + int budget = nq->budget; | |
| 396 | + | |
| 397 | + nq->budget = nq->hwq.max_elements; | |
| 398 | + bnxt_qplib_service_nq(&nq->nq_tasklet); | |
| 399 | + nq->budget = budget; | |
| 400 | +} | |
| 401 | + | |
| 384 | 402 | static irqreturn_t bnxt_qplib_nq_irq(int irq, void *dev_instance) |
| 385 | 403 | { |
| 386 | 404 | struct bnxt_qplib_nq *nq = dev_instance; |
| @@ -402,19 +420,19 @@ void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill) · 15 unmodified lines | ||
| 402 | 420 | if (!nq->requested) |
| 403 | 421 | return; |
| 404 | 422 | |
| 405 | − tasklet_disable(&nq->nq_tasklet); | |
| 423 | + nq->requested = false; | |
| 406 | 424 | /* Mask h/w interrupt */ |
| 407 | 425 | bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, false); |
| 408 | 426 | /* Sync with last running IRQ handler */ |
| 409 | 427 | synchronize_irq(nq->msix_vec); |
| 410 | − if (kill) | |
| 411 | − tasklet_kill(&nq->nq_tasklet); | |
| 412 | − | |
| 413 | 428 | irq_set_affinity_hint(nq->msix_vec, NULL); |
| 414 | 429 | free_irq(nq->msix_vec, nq); |
| 415 | 430 | kfree(nq->name); |
| 416 | 431 | nq->name = NULL; |
| 417 | − nq->requested = false; | |
| 432 | + | |
| 433 | + if (kill) | |
| 434 | + tasklet_kill(&nq->nq_tasklet); | |
| 435 | + tasklet_disable(&nq->nq_tasklet); | |
| 418 | 436 | } |
| 419 | 437 | |
| 420 | 438 | void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq) |
| @@ -553,6 +553,7 @@ int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq, · 552 unmodified lines | ||
| 553 | 553 | struct bnxt_qplib_cqe *cqe, |
| 554 | 554 | int num_cqes); |
| 555 | 555 | void bnxt_qplib_flush_cqn_wq(struct bnxt_qplib_qp *qp); |
| 556 | +void bnxt_re_synchronize_nq(struct bnxt_qplib_nq *nq); | |
| 556 | 557 | |
| 557 | 558 | static inline void *bnxt_qplib_get_swqe(struct bnxt_qplib_q *que, u32 *swq_idx) |
| 558 | 559 | { |
| @@ -989,19 +989,18 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill) · 988 unmodified lines | ||
| 989 | 989 | if (!creq->requested) |
| 990 | 990 | return; |
| 991 | 991 | |
| 992 | − tasklet_disable(&creq->creq_tasklet); | |
| 992 | + creq->requested = false; | |
| 993 | 993 | /* Mask h/w interrupts */ |
| 994 | 994 | bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, false); |
| 995 | 995 | /* Sync with last running IRQ-handler */ |
| 996 | 996 | synchronize_irq(creq->msix_vec); |
| 997 | − if (kill) | |
| 998 | − tasklet_kill(&creq->creq_tasklet); | |
| 999 | − | |
| 1000 | 997 | free_irq(creq->msix_vec, rcfw); |
| 1001 | 998 | kfree(creq->irq_name); |
| 1002 | 999 | creq->irq_name = NULL; |
| 1003 | − creq->requested = false; | |
| 1004 | 1000 | atomic_set(&rcfw->rcfw_intr_enabled, 0); |
| 1001 | + if (kill) | |
| 1002 | + tasklet_kill(&creq->creq_tasklet); | |
| 1003 | + tasklet_disable(&creq->creq_tasklet); | |
| 1005 | 1004 | } |
| 1006 | 1005 | |
| 1007 | 1006 | void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw) |
| @@ -819,6 +819,7 @@ static int bnxt_qplib_alloc_dpi_tbl(struct bnxt_qplib_res *res, · 818 unmodified lines | ||
| 819 | 819 | } |
| 820 | 820 | |
| 821 | 821 | memset((u8 *)dpit->tbl, 0xFF, bytes); |
| 822 | + mutex_init(&res->dpi_tbl_lock); | |
| 822 | 823 | dpit->priv_db = dpit->ucreg.bar_reg + dpit->ucreg.offset; |
| 823 | 824 | |
| 824 | 825 | return 0; |
| @@ -12307,6 +12307,7 @@ static void free_cntrs(struct hfi1_devdata *dd) · 12306 unmodified lines | ||
| 12307 | 12307 | |
| 12308 | 12308 | if (dd->synth_stats_timer.function) |
| 12309 | 12309 | del_timer_sync(&dd->synth_stats_timer); |
| 12310 | + cancel_work_sync(&dd->update_cntr_work); | |
| 12310 | 12311 | ppd = (struct hfi1_pportdata *)(dd + 1); |
| 12311 | 12312 | for (i = 0; i < dd->num_pports; i++, ppd++) { |
| 12312 | 12313 | kfree(ppd->cntrs); |
| @@ -2712,13 +2712,13 @@ static int irdma_sc_cq_modify(struct irdma_sc_cq *cq, · 2711 unmodified lines | ||
| 2712 | 2712 | */ |
| 2713 | 2713 | void irdma_check_cqp_progress(struct irdma_cqp_timeout *timeout, struct irdma_sc_dev *dev) |
| 2714 | 2714 | { |
| 2715 | − if (timeout->compl_cqp_cmds != dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]) { | |
| 2716 | − timeout->compl_cqp_cmds = dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]; | |
| 2715 | + u64 completed_ops = atomic64_read(&dev->cqp->completed_ops); | |
| 2716 | + | |
| 2717 | + if (timeout->compl_cqp_cmds != completed_ops) { | |
| 2718 | + timeout->compl_cqp_cmds = completed_ops; | |
| 2717 | 2719 | timeout->count = 0; |
| 2718 | − } else { | |
| 2719 | − if (dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS] != | |
| 2720 | − timeout->compl_cqp_cmds) | |
| 2721 | − timeout->count++; | |
| 2720 | + } else if (timeout->compl_cqp_cmds != dev->cqp->requested_ops) { | |
| 2721 | + timeout->count++; | |
| 2722 | 2722 | } |
| 2723 | 2723 | } |
| 2724 | 2724 | |
| @@ -2761,7 +2761,7 @@ static int irdma_cqp_poll_registers(struct irdma_sc_cqp *cqp, u32 tail, · 36 unmodified lines | ||
| 2761 | 2761 | if (newtail != tail) { |
| 2762 | 2762 | /* SUCCESS */ |
| 2763 | 2763 | IRDMA_RING_MOVE_TAIL(cqp->sq_ring); |
| 2764 | − cqp->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]++; | |
| 2764 | + atomic64_inc(&cqp->completed_ops); | |
| 2765 | 2765 | return 0; |
| 2766 | 2766 | } |
| 2767 | 2767 | udelay(cqp->dev->hw_attrs.max_sleep_count); |
| @@ -3121,8 +3121,8 @@ int irdma_sc_cqp_init(struct irdma_sc_cqp *cqp, · 353 unmodified lines | ||
| 3121 | 3121 | info->dev->cqp = cqp; |
| 3122 | 3122 | |
| 3123 | 3123 | IRDMA_RING_INIT(cqp->sq_ring, cqp->sq_size); |
| 3124 | − cqp->dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS] = 0; | |
| 3125 | − cqp->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS] = 0; | |
| 3124 | + cqp->requested_ops = 0; | |
| 3125 | + atomic64_set(&cqp->completed_ops, 0); | |
| 3126 | 3126 | /* for the cqp commands backlog. */ |
| 3127 | 3127 | INIT_LIST_HEAD(&cqp->dev->cqp_cmd_head); |
| 3128 | 3128 | |
| @@ -3274,7 +3274,7 @@ __le64 *irdma_sc_cqp_get_next_send_wqe_idx(struct irdma_sc_cqp *cqp, u64 scratch · 145 unmodified lines | ||
| 3274 | 3274 | if (ret_code) |
| 3275 | 3275 | return NULL; |
| 3276 | 3276 | |
| 3277 | − cqp->dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS]++; | |
| 3277 | + cqp->requested_ops++; | |
| 3278 | 3278 | if (!*wqe_idx) |
| 3279 | 3279 | cqp->polarity = !cqp->polarity; |
| 3280 | 3280 | wqe = cqp->sq_base[*wqe_idx].elem; |
| @@ -3363,6 +3363,9 @@ int irdma_sc_ccq_get_cqe_info(struct irdma_sc_cq *ccq, · 82 unmodified lines | ||
| 3363 | 3363 | if (polarity != ccq->cq_uk.polarity) |
| 3364 | 3364 | return -ENOENT; |
| 3365 | 3365 | |
| 3366 | + /* Ensure CEQE contents are read after valid bit is checked */ | |
| 3367 | + dma_rmb(); | |
| 3368 | + | |
| 3366 | 3369 | get_64bit_val(cqe, 8, &qp_ctx); |
| 3367 | 3370 | cqp = (struct irdma_sc_cqp *)(unsigned long)qp_ctx; |
| 3368 | 3371 | info->error = (bool)FIELD_GET(IRDMA_CQ_ERROR, temp); |
| @@ -3397,7 +3400,7 @@ int irdma_sc_ccq_get_cqe_info(struct irdma_sc_cq *ccq, · 28 unmodified lines | ||
| 3397 | 3400 | dma_wmb(); /* make sure shadow area is updated before moving tail */ |
| 3398 | 3401 | |
| 3399 | 3402 | IRDMA_RING_MOVE_TAIL(cqp->sq_ring); |
| 3400 | − ccq->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]++; | |
| 3403 | + atomic64_inc(&cqp->completed_ops); | |
| 3401 | 3404 | |
| 3402 | 3405 | return ret_code; |
| 3403 | 3406 | } |
| @@ -4009,13 +4012,17 @@ int irdma_sc_get_next_aeqe(struct irdma_sc_aeq *aeq, · 605 unmodified lines | ||
| 4009 | 4012 | u8 polarity; |
| 4010 | 4013 | |
| 4011 | 4014 | aeqe = IRDMA_GET_CURRENT_AEQ_ELEM(aeq); |
| 4012 | − get_64bit_val(aeqe, 0, &compl_ctx); | |
| 4013 | 4015 | get_64bit_val(aeqe, 8, &temp); |
| 4014 | 4016 | polarity = (u8)FIELD_GET(IRDMA_AEQE_VALID, temp); |
| 4015 | 4017 | |
| 4016 | 4018 | if (aeq->polarity != polarity) |
| 4017 | 4019 | return -ENOENT; |
| 4018 | 4020 | |
| 4021 | + /* Ensure AEQE contents are read after valid bit is checked */ | |
| 4022 | + dma_rmb(); | |
| 4023 | + | |
| 4024 | + get_64bit_val(aeqe, 0, &compl_ctx); | |
| 4025 | + | |
| 4019 | 4026 | print_hex_dump_debug("WQE: AEQ_ENTRY WQE", DUMP_PREFIX_OFFSET, 16, 8, |
| 4020 | 4027 | aeqe, 16, false); |
| 4021 | 4028 | |
| @@ -191,32 +191,30 @@ enum irdma_cqp_op_type { · 190 unmodified lines | ||
| 191 | 191 | IRDMA_OP_MANAGE_VF_PBLE_BP = 25, |
| 192 | 192 | IRDMA_OP_QUERY_FPM_VAL = 26, |
| 193 | 193 | IRDMA_OP_COMMIT_FPM_VAL = 27, |
| 194 | − IRDMA_OP_REQ_CMDS = 28, | |
| 195 | − IRDMA_OP_CMPL_CMDS = 29, | |
| 196 | − IRDMA_OP_AH_CREATE = 30, | |
| 197 | − IRDMA_OP_AH_MODIFY = 31, | |
| 198 | − IRDMA_OP_AH_DESTROY = 32, | |
| 199 | − IRDMA_OP_MC_CREATE = 33, | |
| 200 | − IRDMA_OP_MC_DESTROY = 34, | |
| 201 | − IRDMA_OP_MC_MODIFY = 35, | |
| 202 | − IRDMA_OP_STATS_ALLOCATE = 36, | |
| 203 | − IRDMA_OP_STATS_FREE = 37, | |
| 204 | − IRDMA_OP_STATS_GATHER = 38, | |
| 205 | − IRDMA_OP_WS_ADD_NODE = 39, | |
| 206 | − IRDMA_OP_WS_MODIFY_NODE = 40, | |
| 207 | − IRDMA_OP_WS_DELETE_NODE = 41, | |
| 208 | − IRDMA_OP_WS_FAILOVER_START = 42, | |
| 209 | − IRDMA_OP_WS_FAILOVER_COMPLETE = 43, | |
| 210 | − IRDMA_OP_SET_UP_MAP = 44, | |
| 211 | − IRDMA_OP_GEN_AE = 45, | |
| 212 | − IRDMA_OP_QUERY_RDMA_FEATURES = 46, | |
| 213 | − IRDMA_OP_ALLOC_LOCAL_MAC_ENTRY = 47, | |
| 214 | − IRDMA_OP_ADD_LOCAL_MAC_ENTRY = 48, | |
| 215 | − IRDMA_OP_DELETE_LOCAL_MAC_ENTRY = 49, | |
| 216 | − IRDMA_OP_CQ_MODIFY = 50, | |
| 194 | + IRDMA_OP_AH_CREATE = 28, | |
| 195 | + IRDMA_OP_AH_MODIFY = 29, | |
| 196 | + IRDMA_OP_AH_DESTROY = 30, | |
| 197 | + IRDMA_OP_MC_CREATE = 31, | |
| 198 | + IRDMA_OP_MC_DESTROY = 32, | |
| 199 | + IRDMA_OP_MC_MODIFY = 33, | |
| 200 | + IRDMA_OP_STATS_ALLOCATE = 34, | |
| 201 | + IRDMA_OP_STATS_FREE = 35, | |
| 202 | + IRDMA_OP_STATS_GATHER = 36, | |
| 203 | + IRDMA_OP_WS_ADD_NODE = 37, | |
| 204 | + IRDMA_OP_WS_MODIFY_NODE = 38, | |
| 205 | + IRDMA_OP_WS_DELETE_NODE = 39, | |
| 206 | + IRDMA_OP_WS_FAILOVER_START = 40, | |
| 207 | + IRDMA_OP_WS_FAILOVER_COMPLETE = 41, | |
| 208 | + IRDMA_OP_SET_UP_MAP = 42, | |
| 209 | + IRDMA_OP_GEN_AE = 43, | |
| 210 | + IRDMA_OP_QUERY_RDMA_FEATURES = 44, | |
| 211 | + IRDMA_OP_ALLOC_LOCAL_MAC_ENTRY = 45, | |
| 212 | + IRDMA_OP_ADD_LOCAL_MAC_ENTRY = 46, | |
| 213 | + IRDMA_OP_DELETE_LOCAL_MAC_ENTRY = 47, | |
| 214 | + IRDMA_OP_CQ_MODIFY = 48, | |
| 217 | 215 | |
| 218 | 216 | /* Must be last entry*/ |
| 219 | − IRDMA_MAX_CQP_OPS = 51, | |
| 217 | + IRDMA_MAX_CQP_OPS = 49, | |
| 220 | 218 | }; |
| 221 | 219 | |
| 222 | 220 | /* CQP SQ WQES */ |
| @@ -191,6 +191,7 @@ static void irdma_set_flush_fields(struct irdma_sc_qp *qp, · 190 unmodified lines | ||
| 191 | 191 | case IRDMA_AE_AMP_MWBIND_INVALID_RIGHTS: |
| 192 | 192 | case IRDMA_AE_AMP_MWBIND_BIND_DISABLED: |
| 193 | 193 | case IRDMA_AE_AMP_MWBIND_INVALID_BOUNDS: |
| 194 | + case IRDMA_AE_AMP_MWBIND_VALID_STAG: | |
| 194 | 195 | qp->flush_code = FLUSH_MW_BIND_ERR; |
| 195 | 196 | qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR; |
| 196 | 197 | break; |
| @@ -2075,7 +2076,7 @@ void irdma_cqp_ce_handler(struct irdma_pci_f *rf, struct irdma_sc_cq *cq) · 1878 unmodified lines | ||
| 2075 | 2076 | cqp_request->compl_info.error = info.error; |
| 2076 | 2077 | |
| 2077 | 2078 | if (cqp_request->waiting) { |
| 2078 | − cqp_request->request_done = true; | |
| 2079 | + WRITE_ONCE(cqp_request->request_done, true); | |
| 2079 | 2080 | wake_up(&cqp_request->waitq); |
| 2080 | 2081 | irdma_put_cqp_request(&rf->cqp, cqp_request); |
| 2081 | 2082 | } else { |
| @@ -161,8 +161,8 @@ struct irdma_cqp_request { · 160 unmodified lines | ||
| 161 | 161 | void (*callback_fcn)(struct irdma_cqp_request *cqp_request); |
| 162 | 162 | void *param; |
| 163 | 163 | struct irdma_cqp_compl_info compl_info; |
| 164 | + bool request_done; /* READ/WRITE_ONCE macros operate on it */ | |
| 164 | 165 | bool waiting:1; |
| 165 | − bool request_done:1; | |
| 166 | 166 | bool dynamic:1; |
| 167 | 167 | }; |
| 168 | 168 | |
| @@ -230,6 +230,9 @@ static int irdma_puda_poll_info(struct irdma_sc_cq *cq, · 229 unmodified lines | ||
| 230 | 230 | if (valid_bit != cq_uk->polarity) |
| 231 | 231 | return -ENOENT; |
| 232 | 232 | |
| 233 | + /* Ensure CQE contents are read after valid bit is checked */ | |
| 234 | + dma_rmb(); | |
| 235 | + | |
| 233 | 236 | if (cq->dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) |
| 234 | 237 | ext_valid = (bool)FIELD_GET(IRDMA_CQ_EXTCQE, qword3); |
| 235 | 238 | |
| @@ -243,6 +246,9 @@ static int irdma_puda_poll_info(struct irdma_sc_cq *cq, · 7 unmodified lines | ||
| 243 | 246 | if (polarity != cq_uk->polarity) |
| 244 | 247 | return -ENOENT; |
| 245 | 248 | |
| 249 | + /* Ensure ext CQE contents are read after ext valid bit is checked */ | |
| 250 | + dma_rmb(); | |
| 251 | + | |
| 246 | 252 | IRDMA_RING_MOVE_HEAD_NOCHECK(cq_uk->cq_ring); |
| 247 | 253 | if (!IRDMA_RING_CURRENT_HEAD(cq_uk->cq_ring)) |
| 248 | 254 | cq_uk->polarity = !cq_uk->polarity; |
| @@ -365,6 +365,8 @@ struct irdma_sc_cqp { · 364 unmodified lines | ||
| 365 | 365 | struct irdma_dcqcn_cc_params dcqcn_params; |
| 366 | 366 | __le64 *host_ctx; |
| 367 | 367 | u64 *scratch_array; |
| 368 | + u64 requested_ops; | |
| 369 | + atomic64_t completed_ops; | |
| 368 | 370 | u32 cqp_id; |
| 369 | 371 | u32 sq_size; |
| 370 | 372 | u32 hw_sq_size; |
| @@ -1161,7 +1161,7 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq, · 1160 unmodified lines | ||
| 1161 | 1161 | } |
| 1162 | 1162 | wqe_idx = (u32)FIELD_GET(IRDMA_CQ_WQEIDX, qword3); |
| 1163 | 1163 | info->qp_handle = (irdma_qp_handle)(unsigned long)qp; |
| 1164 | − info->op_type = (u8)FIELD_GET(IRDMA_CQ_SQ, qword3); | |
| 1164 | + info->op_type = (u8)FIELD_GET(IRDMACQ_OP, qword3); | |
| 1165 | 1165 | |
| 1166 | 1166 | if (info->q_type == IRDMA_CQE_QTYPE_RQ) { |
| 1167 | 1167 | u32 array_idx; |
| @@ -1527,6 +1527,9 @@ void irdma_uk_clean_cq(void *q, struct irdma_cq_uk *cq) · 359 unmodified lines | ||
| 1527 | 1527 | if (polarity != temp) |
| 1528 | 1528 | break; |
| 1529 | 1529 | |
| 1530 | + /* Ensure CQE contents are read after valid bit is checked */ | |
| 1531 | + dma_rmb(); | |
| 1532 | + | |
| 1530 | 1533 | get_64bit_val(cqe, 8, &comp_ctx); |
| 1531 | 1534 | if ((void *)(unsigned long)comp_ctx == q) |
| 1532 | 1535 | set_64bit_val(cqe, 8, 0); |
| @@ -481,7 +481,7 @@ void irdma_free_cqp_request(struct irdma_cqp *cqp, · 480 unmodified lines | ||
| 481 | 481 | if (cqp_request->dynamic) { |
| 482 | 482 | kfree(cqp_request); |
| 483 | 483 | } else { |
| 484 | − cqp_request->request_done = false; | |
| 484 | + WRITE_ONCE(cqp_request->request_done, false); | |
| 485 | 485 | cqp_request->callback_fcn = NULL; |
| 486 | 486 | cqp_request->waiting = false; |
| 487 | 487 | |
| @@ -515,7 +515,7 @@ irdma_free_pending_cqp_request(struct irdma_cqp *cqp, · 27 unmodified lines | ||
| 515 | 515 | { |
| 516 | 516 | if (cqp_request->waiting) { |
| 517 | 517 | cqp_request->compl_info.error = true; |
| 518 | − cqp_request->request_done = true; | |
| 518 | + WRITE_ONCE(cqp_request->request_done, true); | |
| 519 | 519 | wake_up(&cqp_request->waitq); |
| 520 | 520 | } |
| 521 | 521 | wait_event_timeout(cqp->remove_wq, |
| @@ -567,11 +567,11 @@ static int irdma_wait_event(struct irdma_pci_f *rf, · 45 unmodified lines | ||
| 567 | 567 | bool cqp_error = false; |
| 568 | 568 | int err_code = 0; |
| 569 | 569 | |
| 570 | − cqp_timeout.compl_cqp_cmds = rf->sc_dev.cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]; | |
| 570 | + cqp_timeout.compl_cqp_cmds = atomic64_read(&rf->sc_dev.cqp->completed_ops); | |
| 571 | 571 | do { |
| 572 | 572 | irdma_cqp_ce_handler(rf, &rf->ccq.sc_cq); |
| 573 | 573 | if (wait_event_timeout(cqp_request->waitq, |
| 574 | − cqp_request->request_done, | |
| 574 | + READ_ONCE(cqp_request->request_done), | |
| 575 | 575 | msecs_to_jiffies(CQP_COMPL_WAIT_TIME_MS))) |
| 576 | 576 | break; |
| 577 | 577 | |
| @@ -565,15 +565,15 @@ static int set_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_rss *rss_ctx, · 564 unmodified lines | ||
| 565 | 565 | return (-EOPNOTSUPP); |
| 566 | 566 | } |
| 567 | 567 | |
| 568 | − if (ucmd->rx_hash_fields_mask & ~(MLX4_IB_RX_HASH_SRC_IPV4 | | |
| 569 | − MLX4_IB_RX_HASH_DST_IPV4 | | |
| 570 | − MLX4_IB_RX_HASH_SRC_IPV6 | | |
| 571 | − MLX4_IB_RX_HASH_DST_IPV6 | | |
| 572 | − MLX4_IB_RX_HASH_SRC_PORT_TCP | | |
| 573 | − MLX4_IB_RX_HASH_DST_PORT_TCP | | |
| 574 | − MLX4_IB_RX_HASH_SRC_PORT_UDP | | |
| 575 | − MLX4_IB_RX_HASH_DST_PORT_UDP | | |
| 576 | − MLX4_IB_RX_HASH_INNER)) { | |
| 568 | + if (ucmd->rx_hash_fields_mask & ~(u64)(MLX4_IB_RX_HASH_SRC_IPV4 | | |
| 569 | + MLX4_IB_RX_HASH_DST_IPV4 | | |
| 570 | + MLX4_IB_RX_HASH_SRC_IPV6 | | |
| 571 | + MLX4_IB_RX_HASH_DST_IPV6 | | |
| 572 | + MLX4_IB_RX_HASH_SRC_PORT_TCP | | |
| 573 | + MLX4_IB_RX_HASH_DST_PORT_TCP | | |
| 574 | + MLX4_IB_RX_HASH_SRC_PORT_UDP | | |
| 575 | + MLX4_IB_RX_HASH_DST_PORT_UDP | | |
| 576 | + MLX4_IB_RX_HASH_INNER)) { | |
| 577 | 577 | pr_debug("RX Hash fields_mask has unsupported mask (0x%llx)\n", |
| 578 | 578 | ucmd->rx_hash_fields_mask); |
| 579 | 579 | return (-EOPNOTSUPP); |
| @@ -1393,7 +1393,7 @@ int mthca_alloc_sqp(struct mthca_dev *dev, · 1392 unmodified lines | ||
| 1393 | 1393 | if (mthca_array_get(&dev->qp_table.qp, mqpn)) |
| 1394 | 1394 | err = -EBUSY; |
| 1395 | 1395 | else |
| 1396 | − mthca_array_set(&dev->qp_table.qp, mqpn, qp->sqp); | |
| 1396 | + mthca_array_set(&dev->qp_table.qp, mqpn, qp); | |
| 1397 | 1397 | spin_unlock_irq(&dev->qp_table.lock); |
| 1398 | 1398 | |
| 1399 | 1399 | if (err) |
| @@ -199,7 +199,8 @@ int rxe_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe) · 198 unmodified lines | ||
| 199 | 199 | |
| 200 | 200 | if (access & ~RXE_ACCESS_SUPPORTED_MW) { |
| 201 | 201 | rxe_err_mw(mw, "access %#x not supported", access); |
| 202 | − return -EOPNOTSUPP; | |
| 202 | + ret = -EOPNOTSUPP; | |
| 203 | + goto err_drop_mr; | |
| 203 | 204 | } |
| 204 | 205 | |
| 205 | 206 | spin_lock_bh(&mw->lock); |
| @@ -83,6 +83,11 @@ static void bcm_aggregate(struct qcom_icc_bcm *bcm) · 82 unmodified lines | ||
| 83 | 83 | |
| 84 | 84 | temp = agg_peak[bucket] * bcm->vote_scale; |
| 85 | 85 | bcm->vote_y[bucket] = bcm_div(temp, bcm->aux_data.unit); |
| 86 | + | |
| 87 | + if (bcm->enable_mask && (bcm->vote_x[bucket] || bcm->vote_y[bucket])) { | |
| 88 | + bcm->vote_x[bucket] = 0; | |
| 89 | + bcm->vote_y[bucket] = bcm->enable_mask; | |
| 90 | + } | |
| 86 | 91 | } |
| 87 | 92 | |
| 88 | 93 | if (bcm->keepalive && bcm->vote_x[QCOM_ICC_BUCKET_AMC] == 0 && |
| @@ -81,6 +81,7 @@ struct qcom_icc_node { · 80 unmodified lines | ||
| 81 | 81 | * @vote_x: aggregated threshold values, represents sum_bw when @type is bw bcm |
| 82 | 82 | * @vote_y: aggregated threshold values, represents peak_bw when @type is bw bcm |
| 83 | 83 | * @vote_scale: scaling factor for vote_x and vote_y |
| 84 | + * @enable_mask: optional mask to send as vote instead of vote_x/vote_y | |
| 84 | 85 | * @dirty: flag used to indicate whether the bcm needs to be committed |
| 85 | 86 | * @keepalive: flag used to indicate whether a keepalive is required |
| 86 | 87 | * @aux_data: auxiliary data used when calculating threshold values and |
| @@ -97,6 +98,7 @@ struct qcom_icc_bcm { · 10 unmodified lines | ||
| 97 | 98 | u64 vote_x[QCOM_ICC_NUM_BUCKETS]; |
| 98 | 99 | u64 vote_y[QCOM_ICC_NUM_BUCKETS]; |
| 99 | 100 | u64 vote_scale; |
| 101 | + u32 enable_mask; | |
| 100 | 102 | bool dirty; |
| 101 | 103 | bool keepalive; |
| 102 | 104 | struct bcm_db aux_data; |
| @@ -1873,6 +1873,7 @@ static struct qcom_icc_node srvc_snoc = { · 1872 unmodified lines | ||
| 1873 | 1873 | |
| 1874 | 1874 | static struct qcom_icc_bcm bcm_acv = { |
| 1875 | 1875 | .name = "ACV", |
| 1876 | + .enable_mask = 0x8, | |
| 1876 | 1877 | .num_nodes = 1, |
| 1877 | 1878 | .nodes = { &ebi }, |
| 1878 | 1879 | }; |
| @@ -1337,6 +1337,7 @@ static struct qcom_icc_node qns_mem_noc_sf_disp = { · 1336 unmodified lines | ||
| 1337 | 1337 | |
| 1338 | 1338 | static struct qcom_icc_bcm bcm_acv = { |
| 1339 | 1339 | .name = "ACV", |
| 1340 | + .enable_mask = 0x8, | |
| 1340 | 1341 | .num_nodes = 1, |
| 1341 | 1342 | .nodes = { &ebi }, |
| 1342 | 1343 | }; |
| @@ -1349,6 +1350,7 @@ static struct qcom_icc_bcm bcm_ce0 = { · 6 unmodified lines | ||
| 1349 | 1350 | |
| 1350 | 1351 | static struct qcom_icc_bcm bcm_cn0 = { |
| 1351 | 1352 | .name = "CN0", |
| 1353 | + .enable_mask = 0x1, | |
| 1352 | 1354 | .keepalive = true, |
| 1353 | 1355 | .num_nodes = 55, |
| 1354 | 1356 | .nodes = { &qnm_gemnoc_cnoc, &qnm_gemnoc_pcie, |
| @@ -1383,6 +1385,7 @@ static struct qcom_icc_bcm bcm_cn0 = { · 28 unmodified lines | ||
| 1383 | 1385 | |
| 1384 | 1386 | static struct qcom_icc_bcm bcm_co0 = { |
| 1385 | 1387 | .name = "CO0", |
| 1388 | + .enable_mask = 0x1, | |
| 1386 | 1389 | .num_nodes = 2, |
| 1387 | 1390 | .nodes = { &qxm_nsp, &qns_nsp_gemnoc }, |
| 1388 | 1391 | }; |
| @@ -1403,6 +1406,7 @@ static struct qcom_icc_bcm bcm_mm0 = { · 14 unmodified lines | ||
| 1403 | 1406 | |
| 1404 | 1407 | static struct qcom_icc_bcm bcm_mm1 = { |
| 1405 | 1408 | .name = "MM1", |
| 1409 | + .enable_mask = 0x1, | |
| 1406 | 1410 | .num_nodes = 12, |
| 1407 | 1411 | .nodes = { &qnm_camnoc_hf, &qnm_camnoc_icp, |
| 1408 | 1412 | &qnm_camnoc_sf, &qnm_mdp, |
| @@ -1445,6 +1449,7 @@ static struct qcom_icc_bcm bcm_sh0 = { · 36 unmodified lines | ||
| 1445 | 1449 | |
| 1446 | 1450 | static struct qcom_icc_bcm bcm_sh1 = { |
| 1447 | 1451 | .name = "SH1", |
| 1452 | + .enable_mask = 0x1, | |
| 1448 | 1453 | .num_nodes = 7, |
| 1449 | 1454 | .nodes = { &alm_gpu_tcu, &alm_sys_tcu, |
| 1450 | 1455 | &qnm_nsp_gemnoc, &qnm_pcie, |
| @@ -1461,6 +1466,7 @@ static struct qcom_icc_bcm bcm_sn0 = { · 10 unmodified lines | ||
| 1461 | 1466 | |
| 1462 | 1467 | static struct qcom_icc_bcm bcm_sn1 = { |
| 1463 | 1468 | .name = "SN1", |
| 1469 | + .enable_mask = 0x1, | |
| 1464 | 1470 | .num_nodes = 4, |
| 1465 | 1471 | .nodes = { &qhm_gic, &qxm_pimem, |
| 1466 | 1472 | &xm_gic, &qns_gemnoc_gc }, |
| @@ -1492,6 +1498,7 @@ static struct qcom_icc_bcm bcm_sn7 = { · 25 unmodified lines | ||
| 1492 | 1498 | |
| 1493 | 1499 | static struct qcom_icc_bcm bcm_acv_disp = { |
| 1494 | 1500 | .name = "ACV", |
| 1501 | + .enable_mask = 0x1, | |
| 1495 | 1502 | .num_nodes = 1, |
| 1496 | 1503 | .nodes = { &ebi_disp }, |
| 1497 | 1504 | }; |
| @@ -1510,6 +1517,7 @@ static struct qcom_icc_bcm bcm_mm0_disp = { · 12 unmodified lines | ||
| 1510 | 1517 | |
| 1511 | 1518 | static struct qcom_icc_bcm bcm_mm1_disp = { |
| 1512 | 1519 | .name = "MM1", |
| 1520 | + .enable_mask = 0x1, | |
| 1513 | 1521 | .num_nodes = 3, |
| 1514 | 1522 | .nodes = { &qnm_mdp_disp, &qnm_rot_disp, |
| 1515 | 1523 | &qns_mem_noc_sf_disp }, |
| @@ -1523,6 +1531,7 @@ static struct qcom_icc_bcm bcm_sh0_disp = { · 7 unmodified lines | ||
| 1523 | 1531 | |
| 1524 | 1532 | static struct qcom_icc_bcm bcm_sh1_disp = { |
| 1525 | 1533 | .name = "SH1", |
| 1534 | + .enable_mask = 0x1, | |
| 1526 | 1535 | .num_nodes = 1, |
| 1527 | 1536 | .nodes = { &qnm_pcie_disp }, |
| 1528 | 1537 | }; |
| @@ -1473,6 +1473,7 @@ static struct qcom_icc_node qns_mem_noc_sf_cam_ife_2 = { · 1472 unmodified lines | ||
| 1473 | 1473 | |
| 1474 | 1474 | static struct qcom_icc_bcm bcm_acv = { |
| 1475 | 1475 | .name = "ACV", |
| 1476 | + .enable_mask = 0x8, | |
| 1476 | 1477 | .num_nodes = 1, |
| 1477 | 1478 | .nodes = { &ebi }, |
| 1478 | 1479 | }; |
| @@ -1485,6 +1486,7 @@ static struct qcom_icc_bcm bcm_ce0 = { · 6 unmodified lines | ||
| 1485 | 1486 | |
| 1486 | 1487 | static struct qcom_icc_bcm bcm_cn0 = { |
| 1487 | 1488 | .name = "CN0", |
| 1489 | + .enable_mask = 0x1, | |
| 1488 | 1490 | .keepalive = true, |
| 1489 | 1491 | .num_nodes = 54, |
| 1490 | 1492 | .nodes = { &qsm_cfg, &qhs_ahb2phy0, |
| @@ -1524,6 +1526,7 @@ static struct qcom_icc_bcm bcm_cn1 = { · 33 unmodified lines | ||
| 1524 | 1526 | |
| 1525 | 1527 | static struct qcom_icc_bcm bcm_co0 = { |
| 1526 | 1528 | .name = "CO0", |
| 1529 | + .enable_mask = 0x1, | |
| 1527 | 1530 | .num_nodes = 2, |
| 1528 | 1531 | .nodes = { &qxm_nsp, &qns_nsp_gemnoc }, |
| 1529 | 1532 | }; |
| @@ -1549,6 +1552,7 @@ static struct qcom_icc_bcm bcm_mm0 = { · 19 unmodified lines | ||
| 1549 | 1552 | |
| 1550 | 1553 | static struct qcom_icc_bcm bcm_mm1 = { |
| 1551 | 1554 | .name = "MM1", |
| 1555 | + .enable_mask = 0x1, | |
| 1552 | 1556 | .num_nodes = 8, |
| 1553 | 1557 | .nodes = { &qnm_camnoc_hf, &qnm_camnoc_icp, |
| 1554 | 1558 | &qnm_camnoc_sf, &qnm_vapss_hcp, |
| @@ -1589,6 +1593,7 @@ static struct qcom_icc_bcm bcm_sh0 = { · 34 unmodified lines | ||
| 1589 | 1593 | |
| 1590 | 1594 | static struct qcom_icc_bcm bcm_sh1 = { |
| 1591 | 1595 | .name = "SH1", |
| 1596 | + .enable_mask = 0x1, | |
| 1592 | 1597 | .num_nodes = 13, |
| 1593 | 1598 | .nodes = { &alm_gpu_tcu, &alm_sys_tcu, |
| 1594 | 1599 | &chm_apps, &qnm_gpu, |
| @@ -1608,6 +1613,7 @@ static struct qcom_icc_bcm bcm_sn0 = { · 13 unmodified lines | ||
| 1608 | 1613 | |
| 1609 | 1614 | static struct qcom_icc_bcm bcm_sn1 = { |
| 1610 | 1615 | .name = "SN1", |
| 1616 | + .enable_mask = 0x1, | |
| 1611 | 1617 | .num_nodes = 3, |
| 1612 | 1618 | .nodes = { &qhm_gic, &xm_gic, |
| 1613 | 1619 | &qns_gemnoc_gc }, |
| @@ -1633,6 +1639,7 @@ static struct qcom_icc_bcm bcm_sn7 = { · 19 unmodified lines | ||
| 1633 | 1639 | |
| 1634 | 1640 | static struct qcom_icc_bcm bcm_acv_disp = { |
| 1635 | 1641 | .name = "ACV", |
| 1642 | + .enable_mask = 0x1, | |
| 1636 | 1643 | .num_nodes = 1, |
| 1637 | 1644 | .nodes = { &ebi_disp }, |
| 1638 | 1645 | }; |
| @@ -1657,12 +1664,14 @@ static struct qcom_icc_bcm bcm_sh0_disp = { · 18 unmodified lines | ||
| 1657 | 1664 | |
| 1658 | 1665 | static struct qcom_icc_bcm bcm_sh1_disp = { |
| 1659 | 1666 | .name = "SH1", |
| 1667 | + .enable_mask = 0x1, | |
| 1660 | 1668 | .num_nodes = 2, |
| 1661 | 1669 | .nodes = { &qnm_mnoc_hf_disp, &qnm_pcie_disp }, |
| 1662 | 1670 | }; |
| 1663 | 1671 | |
| 1664 | 1672 | static struct qcom_icc_bcm bcm_acv_cam_ife_0 = { |
| 1665 | 1673 | .name = "ACV", |
| 1674 | + .enable_mask = 0x0, | |
| 1666 | 1675 | .num_nodes = 1, |
| 1667 | 1676 | .nodes = { &ebi_cam_ife_0 }, |
| 1668 | 1677 | }; |
| @@ -1681,6 +1690,7 @@ static struct qcom_icc_bcm bcm_mm0_cam_ife_0 = { · 12 unmodified lines | ||
| 1681 | 1690 | |
| 1682 | 1691 | static struct qcom_icc_bcm bcm_mm1_cam_ife_0 = { |
| 1683 | 1692 | .name = "MM1", |
| 1693 | + .enable_mask = 0x1, | |
| 1684 | 1694 | .num_nodes = 4, |
| 1685 | 1695 | .nodes = { &qnm_camnoc_hf_cam_ife_0, &qnm_camnoc_icp_cam_ife_0, |
| 1686 | 1696 | &qnm_camnoc_sf_cam_ife_0, &qns_mem_noc_sf_cam_ife_0 }, |
| @@ -1694,6 +1704,7 @@ static struct qcom_icc_bcm bcm_sh0_cam_ife_0 = { · 7 unmodified lines | ||
| 1694 | 1704 | |
| 1695 | 1705 | static struct qcom_icc_bcm bcm_sh1_cam_ife_0 = { |
| 1696 | 1706 | .name = "SH1", |
| 1707 | + .enable_mask = 0x1, | |
| 1697 | 1708 | .num_nodes = 3, |
| 1698 | 1709 | .nodes = { &qnm_mnoc_hf_cam_ife_0, &qnm_mnoc_sf_cam_ife_0, |
| 1699 | 1710 | &qnm_pcie_cam_ife_0 }, |
| @@ -1701,6 +1712,7 @@ static struct qcom_icc_bcm bcm_sh1_cam_ife_0 = { · 1 unmodified line | ||
| 1701 | 1712 | |
| 1702 | 1713 | static struct qcom_icc_bcm bcm_acv_cam_ife_1 = { |
| 1703 | 1714 | .name = "ACV", |
| 1715 | + .enable_mask = 0x0, | |
| 1704 | 1716 | .num_nodes = 1, |
| 1705 | 1717 | .nodes = { &ebi_cam_ife_1 }, |
| 1706 | 1718 | }; |
| @@ -1719,6 +1731,7 @@ static struct qcom_icc_bcm bcm_mm0_cam_ife_1 = { · 12 unmodified lines | ||
| 1719 | 1731 | |
| 1720 | 1732 | static struct qcom_icc_bcm bcm_mm1_cam_ife_1 = { |
| 1721 | 1733 | .name = "MM1", |
| 1734 | + .enable_mask = 0x1, | |
| 1722 | 1735 | .num_nodes = 4, |
| 1723 | 1736 | .nodes = { &qnm_camnoc_hf_cam_ife_1, &qnm_camnoc_icp_cam_ife_1, |
| 1724 | 1737 | &qnm_camnoc_sf_cam_ife_1, &qns_mem_noc_sf_cam_ife_1 }, |
| @@ -1732,6 +1745,7 @@ static struct qcom_icc_bcm bcm_sh0_cam_ife_1 = { · 7 unmodified lines | ||
| 1732 | 1745 | |
| 1733 | 1746 | static struct qcom_icc_bcm bcm_sh1_cam_ife_1 = { |
| 1734 | 1747 | .name = "SH1", |
| 1748 | + .enable_mask = 0x1, | |
| 1735 | 1749 | .num_nodes = 3, |
| 1736 | 1750 | .nodes = { &qnm_mnoc_hf_cam_ife_1, &qnm_mnoc_sf_cam_ife_1, |
| 1737 | 1751 | &qnm_pcie_cam_ife_1 }, |
| @@ -1739,6 +1753,7 @@ static struct qcom_icc_bcm bcm_sh1_cam_ife_1 = { · 1 unmodified line | ||
| 1739 | 1753 | |
| 1740 | 1754 | static struct qcom_icc_bcm bcm_acv_cam_ife_2 = { |
| 1741 | 1755 | .name = "ACV", |
| 1756 | + .enable_mask = 0x0, | |
| 1742 | 1757 | .num_nodes = 1, |
| 1743 | 1758 | .nodes = { &ebi_cam_ife_2 }, |
| 1744 | 1759 | }; |
| @@ -1757,6 +1772,7 @@ static struct qcom_icc_bcm bcm_mm0_cam_ife_2 = { · 12 unmodified lines | ||
| 1757 | 1772 | |
| 1758 | 1773 | static struct qcom_icc_bcm bcm_mm1_cam_ife_2 = { |
| 1759 | 1774 | .name = "MM1", |
| 1775 | + .enable_mask = 0x1, | |
| 1760 | 1776 | .num_nodes = 4, |
| 1761 | 1777 | .nodes = { &qnm_camnoc_hf_cam_ife_2, &qnm_camnoc_icp_cam_ife_2, |
| 1762 | 1778 | &qnm_camnoc_sf_cam_ife_2, &qns_mem_noc_sf_cam_ife_2 }, |
| @@ -1770,6 +1786,7 @@ static struct qcom_icc_bcm bcm_sh0_cam_ife_2 = { · 7 unmodified lines | ||
| 1770 | 1786 | |
| 1771 | 1787 | static struct qcom_icc_bcm bcm_sh1_cam_ife_2 = { |
| 1772 | 1788 | .name = "SH1", |
| 1789 | + .enable_mask = 0x1, | |
| 1773 | 1790 | .num_nodes = 3, |
| 1774 | 1791 | .nodes = { &qnm_mnoc_hf_cam_ife_2, &qnm_mnoc_sf_cam_ife_2, |
| 1775 | 1792 | &qnm_pcie_cam_ife_2 }, |
| @@ -275,10 +275,7 @@ EXPORT_SYMBOL_NS_GPL(iommufd_ctx_has_group, IOMMUFD); · 274 unmodified lines | ||
| 275 | 275 | */ |
| 276 | 276 | void iommufd_device_unbind(struct iommufd_device *idev) |
| 277 | 277 | { |
| 278 | − bool was_destroyed; | |
| 279 | − | |
| 280 | − was_destroyed = iommufd_object_destroy_user(idev->ictx, &idev->obj); | |
| 281 | − WARN_ON(!was_destroyed); | |
| 278 | + iommufd_object_destroy_user(idev->ictx, &idev->obj); | |
| 282 | 279 | } |
| 283 | 280 | EXPORT_SYMBOL_NS_GPL(iommufd_device_unbind, IOMMUFD); |
| 284 | 281 | |
| @@ -814,10 +811,7 @@ EXPORT_SYMBOL_NS_GPL(iommufd_access_create, IOMMUFD); · 529 unmodified lines | ||
| 814 | 811 | */ |
| 815 | 812 | void iommufd_access_destroy(struct iommufd_access *access) |
| 816 | 813 | { |
| 817 | − bool was_destroyed; | |
| 818 | − | |
| 819 | − was_destroyed = iommufd_object_destroy_user(access->ictx, &access->obj); | |
| 820 | − WARN_ON(!was_destroyed); | |
| 814 | + iommufd_object_destroy_user(access->ictx, &access->obj); | |
| 821 | 815 | } |
| 822 | 816 | EXPORT_SYMBOL_NS_GPL(iommufd_access_destroy, IOMMUFD); |
| 823 | 817 | |
| @@ -177,8 +177,19 @@ void iommufd_object_abort_and_destroy(struct iommufd_ctx *ictx, · 176 unmodified lines | ||
| 177 | 177 | struct iommufd_object *obj); |
| 178 | 178 | void iommufd_object_finalize(struct iommufd_ctx *ictx, |
| 179 | 179 | struct iommufd_object *obj); |
| 180 | −bool iommufd_object_destroy_user(struct iommufd_ctx *ictx, | |
| 181 | − struct iommufd_object *obj); | |
| 180 | +void __iommufd_object_destroy_user(struct iommufd_ctx *ictx, | |
| 181 | + struct iommufd_object *obj, bool allow_fail); | |
| 182 | +static inline void iommufd_object_destroy_user(struct iommufd_ctx *ictx, | |
| 183 | + struct iommufd_object *obj) | |
| 184 | +{ | |
| 185 | + __iommufd_object_destroy_user(ictx, obj, false); | |
| 186 | +} | |
| 187 | +static inline void iommufd_object_deref_user(struct iommufd_ctx *ictx, | |
| 188 | + struct iommufd_object *obj) | |
| 189 | +{ | |
| 190 | + __iommufd_object_destroy_user(ictx, obj, true); | |
| 191 | +} | |
| 192 | + | |
| 182 | 193 | struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx, |
| 183 | 194 | size_t size, |
| 184 | 195 | enum iommufd_object_type type); |
| @@ -269,7 +280,7 @@ static inline void iommufd_hw_pagetable_put(struct iommufd_ctx *ictx, · 84 unmodified lines | ||
| 269 | 280 | { |
| 270 | 281 | lockdep_assert_not_held(&hwpt->ioas->mutex); |
| 271 | 282 | if (hwpt->auto_domain) |
| 272 | − iommufd_object_destroy_user(ictx, &hwpt->obj); | |
| 283 | + iommufd_object_deref_user(ictx, &hwpt->obj); | |
| 273 | 284 | else |
| 274 | 285 | refcount_dec(&hwpt->obj.users); |
| 275 | 286 | } |
| @@ -129,14 +129,56 @@ struct iommufd_object *iommufd_get_object(struct iommufd_ctx *ictx, u32 id, · 128 unmodified lines | ||
| 129 | 129 | return obj; |
| 130 | 130 | } |
| 131 | 131 | |
| 132 | +/* | |
| 133 | + * Remove the given object id from the xarray if the only reference to the | |
| 134 | + * object is held by the xarray. The caller must call ops destroy(). | |
| 135 | + */ | |
| 136 | +static struct iommufd_object *iommufd_object_remove(struct iommufd_ctx *ictx, | |
| 137 | + u32 id, bool extra_put) | |
| 138 | +{ | |
| 139 | + struct iommufd_object *obj; | |
| 140 | + XA_STATE(xas, &ictx->objects, id); | |
| 141 | + | |
| 142 | + xa_lock(&ictx->objects); | |
| 143 | + obj = xas_load(&xas); | |
| 144 | + if (xa_is_zero(obj) || !obj) { | |
| 145 | + obj = ERR_PTR(-ENOENT); | |
| 146 | + goto out_xa; | |
| 147 | + } | |
| 148 | + | |
| 149 | + /* | |
| 150 | + * If the caller is holding a ref on obj we put it here under the | |
| 151 | + * spinlock. | |
| 152 | + */ | |
| 153 | + if (extra_put) | |
| 154 | + refcount_dec(&obj->users); | |
| 155 | + | |
| 156 | + if (!refcount_dec_if_one(&obj->users)) { | |
| 157 | + obj = ERR_PTR(-EBUSY); | |
| 158 | + goto out_xa; | |
| 159 | + } | |
| 160 | + | |
| 161 | + xas_store(&xas, NULL); | |
| 162 | + if (ictx->vfio_ioas == container_of(obj, struct iommufd_ioas, obj)) | |
| 163 | + ictx->vfio_ioas = NULL; | |
| 164 | + | |
| 165 | +out_xa: | |
| 166 | + xa_unlock(&ictx->objects); | |
| 167 | + | |
| 168 | + /* The returned object reference count is zero */ | |
| 169 | + return obj; | |
| 170 | +} | |
| 171 | + | |
| 132 | 172 | /* |
| 133 | 173 | * The caller holds a users refcount and wants to destroy the object. Returns |
| 134 | 174 | * true if the object was destroyed. In all cases the caller no longer has a |
| 135 | 175 | * reference on obj. |
| 136 | 176 | */ |
| 137 | −bool iommufd_object_destroy_user(struct iommufd_ctx *ictx, | |
| 138 | − struct iommufd_object *obj) | |
| 177 | +void __iommufd_object_destroy_user(struct iommufd_ctx *ictx, | |
| 178 | + struct iommufd_object *obj, bool allow_fail) | |
| 139 | 179 | { |
| 180 | + struct iommufd_object *ret; | |
| 181 | + | |
| 140 | 182 | /* |
| 141 | 183 | * The purpose of the destroy_rwsem is to ensure deterministic |
| 142 | 184 | * destruction of objects used by external drivers and destroyed by this |
| @@ -144,22 +186,22 @@ bool iommufd_object_destroy_user(struct iommufd_ctx *ictx, · 1 unmodified line | ||
| 144 | 186 | * side of this, such as during ioctl execution. |
| 145 | 187 | */ |
| 146 | 188 | down_write(&obj->destroy_rwsem); |
| 147 | − xa_lock(&ictx->objects); | |
| 148 | − refcount_dec(&obj->users); | |
| 149 | − if (!refcount_dec_if_one(&obj->users)) { | |
| 150 | − xa_unlock(&ictx->objects); | |
| 151 | − up_write(&obj->destroy_rwsem); | |
| 152 | − return false; | |
| 153 | − } | |
| 154 | − __xa_erase(&ictx->objects, obj->id); | |
| 155 | − if (ictx->vfio_ioas && &ictx->vfio_ioas->obj == obj) | |
| 156 | − ictx->vfio_ioas = NULL; | |
| 157 | − xa_unlock(&ictx->objects); | |
| 189 | + ret = iommufd_object_remove(ictx, obj->id, true); | |
| 158 | 190 | up_write(&obj->destroy_rwsem); |
| 159 | 191 | |
| 192 | + if (allow_fail && IS_ERR(ret)) | |
| 193 | + return; | |
| 194 | + | |
| 195 | + /* | |
| 196 | + * If there is a bug and we couldn't destroy the object then we did put | |
| 197 | + * back the caller's refcount and will eventually try to free it again | |
| 198 | + * during close. | |
| 199 | + */ | |
| 200 | + if (WARN_ON(IS_ERR(ret))) | |
| 201 | + return; | |
| 202 | + | |
| 160 | 203 | iommufd_object_ops[obj->type].destroy(obj); |
| 161 | 204 | kfree(obj); |
| 162 | − return true; | |
| 163 | 205 | } |
| 164 | 206 | |
| 165 | 207 | static int iommufd_destroy(struct iommufd_ucmd *ucmd) |
| @@ -167,13 +209,11 @@ static int iommufd_destroy(struct iommufd_ucmd *ucmd) · 1 unmodified line | ||
| 167 | 209 | struct iommu_destroy *cmd = ucmd->cmd; |
| 168 | 210 | struct iommufd_object *obj; |
| 169 | 211 | |
| 170 | − obj = iommufd_get_object(ucmd->ictx, cmd->id, IOMMUFD_OBJ_ANY); | |
| 212 | + obj = iommufd_object_remove(ucmd->ictx, cmd->id, false); | |
| 171 | 213 | if (IS_ERR(obj)) |
| 172 | 214 | return PTR_ERR(obj); |
| 173 | − iommufd_ref_to_users(obj); | |
| 174 | − /* See iommufd_ref_to_users() */ | |
| 175 | − if (!iommufd_object_destroy_user(ucmd->ictx, obj)) | |
| 176 | − return -EBUSY; | |
| 215 | + iommufd_object_ops[obj->type].destroy(obj); | |
| 216 | + kfree(obj); | |
| 177 | 217 | return 0; |
| 178 | 218 | } |
| 179 | 219 | |
| @@ -297,7 +297,7 @@ static void batch_clear_carry(struct pfn_batch *batch, unsigned int keep_pfns) · 296 unmodified lines | ||
| 297 | 297 | batch->pfns[0] = batch->pfns[batch->end - 1] + |
| 298 | 298 | (batch->npfns[batch->end - 1] - keep_pfns); |
| 299 | 299 | batch->npfns[0] = keep_pfns; |
| 300 | − batch->end = 0; | |
| 300 | + batch->end = 1; | |
| 301 | 301 | } |
| 302 | 302 | |
| 303 | 303 | static void batch_skip_carry(struct pfn_batch *batch, unsigned int skip_pfns) |
| @@ -82,6 +82,7 @@ struct bcm6345_l1_chip { · 81 unmodified lines | ||
| 82 | 82 | }; |
| 83 | 83 | |
| 84 | 84 | struct bcm6345_l1_cpu { |
| 85 | + struct bcm6345_l1_chip *intc; | |
| 85 | 86 | void __iomem *map_base; |
| 86 | 87 | unsigned int parent_irq; |
| 87 | 88 | u32 enable_cache[]; |
| @@ -115,17 +116,11 @@ static inline unsigned int cpu_for_irq(struct bcm6345_l1_chip *intc, · 27 unmodified lines | ||
| 115 | 116 | |
| 116 | 117 | static void bcm6345_l1_irq_handle(struct irq_desc *desc) |
| 117 | 118 | { |
| 118 | − struct bcm6345_l1_chip *intc = irq_desc_get_handler_data(desc); | |
| 119 | − struct bcm6345_l1_cpu *cpu; | |
| 119 | + struct bcm6345_l1_cpu *cpu = irq_desc_get_handler_data(desc); | |
| 120 | + struct bcm6345_l1_chip *intc = cpu->intc; | |
| 120 | 121 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 121 | 122 | unsigned int idx; |
| 122 | 123 | |
| 123 | −#ifdef CONFIG_SMP | |
| 124 | − cpu = intc->cpus[cpu_logical_map(smp_processor_id())]; | |
| 125 | −#else | |
| 126 | − cpu = intc->cpus[0]; | |
| 127 | −#endif | |
| 128 | − | |
| 129 | 124 | chained_irq_enter(chip, desc); |
| 130 | 125 | |
| 131 | 126 | for (idx = 0; idx < intc->n_words; idx++) { |
| @@ -253,6 +248,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn, · 121 unmodified lines | ||
| 253 | 248 | if (!cpu) |
| 254 | 249 | return -ENOMEM; |
| 255 | 250 | |
| 251 | + cpu->intc = intc; | |
| 256 | 252 | cpu->map_base = ioremap(res.start, sz); |
| 257 | 253 | if (!cpu->map_base) |
| 258 | 254 | return -ENOMEM; |
| @@ -271,7 +267,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn, · 12 unmodified lines | ||
| 271 | 267 | return -EINVAL; |
| 272 | 268 | } |
| 273 | 269 | irq_set_chained_handler_and_data(cpu->parent_irq, |
| 274 | − bcm6345_l1_irq_handle, intc); | |
| 270 | + bcm6345_l1_irq_handle, cpu); | |
| 275 | 271 | |
| 276 | 272 | return 0; |
| 277 | 273 | } |
| @@ -273,13 +273,23 @@ static void vpe_to_cpuid_unlock(struct its_vpe *vpe, unsigned long flags) · 272 unmodified lines | ||
| 273 | 273 | raw_spin_unlock_irqrestore(&vpe->vpe_lock, flags); |
| 274 | 274 | } |
| 275 | 275 | |
| 276 | +static struct irq_chip its_vpe_irq_chip; | |
| 277 | + | |
| 276 | 278 | static int irq_to_cpuid_lock(struct irq_data *d, unsigned long *flags) |
| 277 | 279 | { |
| 278 | − struct its_vlpi_map *map = get_vlpi_map(d); | |
| 280 | + struct its_vpe *vpe = NULL; | |
| 279 | 281 | int cpu; |
| 280 | 282 | |
| 281 | − if (map) { | |
| 282 | − cpu = vpe_to_cpuid_lock(map->vpe, flags); | |
| 283 | + if (d->chip == &its_vpe_irq_chip) { | |
| 284 | + vpe = irq_data_get_irq_chip_data(d); | |
| 285 | + } else { | |
| 286 | + struct its_vlpi_map *map = get_vlpi_map(d); | |
| 287 | + if (map) | |
| 288 | + vpe = map->vpe; | |
| 289 | + } | |
| 290 | + | |
| 291 | + if (vpe) { | |
| 292 | + cpu = vpe_to_cpuid_lock(vpe, flags); | |
| 283 | 293 | } else { |
| 284 | 294 | /* Physical LPIs are already locked via the irq_desc lock */ |
| 285 | 295 | struct its_device *its_dev = irq_data_get_irq_chip_data(d); |
| @@ -293,10 +303,18 @@ static int irq_to_cpuid_lock(struct irq_data *d, unsigned long *flags) · 7 unmodified lines | ||
| 293 | 303 | |
| 294 | 304 | static void irq_to_cpuid_unlock(struct irq_data *d, unsigned long flags) |
| 295 | 305 | { |
| 296 | − struct its_vlpi_map *map = get_vlpi_map(d); | |
| 306 | + struct its_vpe *vpe = NULL; | |
| 307 | + | |
| 308 | + if (d->chip == &its_vpe_irq_chip) { | |
| 309 | + vpe = irq_data_get_irq_chip_data(d); | |
| 310 | + } else { | |
| 311 | + struct its_vlpi_map *map = get_vlpi_map(d); | |
| 312 | + if (map) | |
| 313 | + vpe = map->vpe; | |
| 314 | + } | |
| 297 | 315 | |
| 298 | − if (map) | |
| 299 | − vpe_to_cpuid_unlock(map->vpe, flags); | |
| 316 | + if (vpe) | |
| 317 | + vpe_to_cpuid_unlock(vpe, flags); | |
| 300 | 318 | } |
| 301 | 319 | |
| 302 | 320 | static struct its_collection *valid_col(struct its_collection *col) |
| @@ -1433,14 +1451,29 @@ static void wait_for_syncr(void __iomem *rdbase) · 1130 unmodified lines | ||
| 1433 | 1451 | cpu_relax(); |
| 1434 | 1452 | } |
| 1435 | 1453 | |
| 1436 | −static void direct_lpi_inv(struct irq_data *d) | |
| 1454 | +static void __direct_lpi_inv(struct irq_data *d, u64 val) | |
| 1437 | 1455 | { |
| 1438 | − struct its_vlpi_map *map = get_vlpi_map(d); | |
| 1439 | 1456 | void __iomem *rdbase; |
| 1440 | 1457 | unsigned long flags; |
| 1441 | − u64 val; | |
| 1442 | 1458 | int cpu; |
| 1443 | 1459 | |
| 1460 | + /* Target the redistributor this LPI is currently routed to */ | |
| 1461 | + cpu = irq_to_cpuid_lock(d, &flags); | |
| 1462 | + raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock); | |
| 1463 | + | |
| 1464 | + rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base; | |
| 1465 | + gic_write_lpir(val, rdbase + GICR_INVLPIR); | |
| 1466 | + wait_for_syncr(rdbase); | |
| 1467 | + | |
| 1468 | + raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock); | |
| 1469 | + irq_to_cpuid_unlock(d, flags); | |
| 1470 | +} | |
| 1471 | + | |
| 1472 | +static void direct_lpi_inv(struct irq_data *d) | |
| 1473 | +{ | |
| 1474 | + struct its_vlpi_map *map = get_vlpi_map(d); | |
| 1475 | + u64 val; | |
| 1476 | + | |
| 1444 | 1477 | if (map) { |
| 1445 | 1478 | struct its_device *its_dev = irq_data_get_irq_chip_data(d); |
| 1446 | 1479 | |
| @@ -1453,15 +1486,7 @@ static void direct_lpi_inv(struct irq_data *d) · 6 unmodified lines | ||
| 1453 | 1486 | val = d->hwirq; |
| 1454 | 1487 | } |
| 1455 | 1488 | |
| 1456 | − /* Target the redistributor this LPI is currently routed to */ | |
| 1457 | − cpu = irq_to_cpuid_lock(d, &flags); | |
| 1458 | − raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock); | |
| 1459 | − rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base; | |
| 1460 | − gic_write_lpir(val, rdbase + GICR_INVLPIR); | |
| 1461 | − | |
| 1462 | − wait_for_syncr(rdbase); | |
| 1463 | − raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock); | |
| 1464 | − irq_to_cpuid_unlock(d, flags); | |
| 1489 | + __direct_lpi_inv(d, val); | |
| 1465 | 1490 | } |
| 1466 | 1491 | |
| 1467 | 1492 | static void lpi_update_config(struct irq_data *d, u8 clr, u8 set) |
| @@ -3953,18 +3978,10 @@ static void its_vpe_send_inv(struct irq_data *d) · 2485 unmodified lines | ||
| 3953 | 3978 | { |
| 3954 | 3979 | struct its_vpe *vpe = irq_data_get_irq_chip_data(d); |
| 3955 | 3980 | |
| 3956 | − if (gic_rdists->has_direct_lpi) { | |
| 3957 | − void __iomem *rdbase; | |
| 3958 | − | |
| 3959 | − /* Target the redistributor this VPE is currently known on */ | |
| 3960 | − raw_spin_lock(&gic_data_rdist_cpu(vpe->col_idx)->rd_lock); | |
| 3961 | − rdbase = per_cpu_ptr(gic_rdists->rdist, vpe->col_idx)->rd_base; | |
| 3962 | − gic_write_lpir(d->parent_data->hwirq, rdbase + GICR_INVLPIR); | |
| 3963 | − wait_for_syncr(rdbase); | |
| 3964 | − raw_spin_unlock(&gic_data_rdist_cpu(vpe->col_idx)->rd_lock); | |
| 3965 | − } else { | |
| 3981 | + if (gic_rdists->has_direct_lpi) | |
| 3982 | + __direct_lpi_inv(d, d->parent_data->hwirq); | |
| 3983 | + else | |
| 3966 | 3984 | its_vpe_send_cmd(vpe, its_send_inv); |
| 3967 | − } | |
| 3968 | 3985 | } |
| 3969 | 3986 | |
| 3970 | 3987 | static void its_vpe_mask_irq(struct irq_data *d) |
| @@ -4727,7 +4744,8 @@ static bool __maybe_unused its_enable_rk3588001(void *data) · 756 unmodified lines | ||
| 4727 | 4744 | { |
| 4728 | 4745 | struct its_node *its = data; |
| 4729 | 4746 | |
| 4730 | − if (!of_machine_is_compatible("rockchip,rk3588")) | |
| 4747 | + if (!of_machine_is_compatible("rockchip,rk3588") && | |
| 4748 | + !of_machine_is_compatible("rockchip,rk3588s")) | |
| 4731 | 4749 | return false; |
| 4732 | 4750 | |
| 4733 | 4751 | its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE; |
| @@ -69,6 +69,8 @@ struct gic_chip_data { · 68 unmodified lines | ||
| 69 | 69 | static void __iomem *t241_dist_base_alias[T241_CHIPS_MAX] __read_mostly; |
| 70 | 70 | static DEFINE_STATIC_KEY_FALSE(gic_nvidia_t241_erratum); |
| 71 | 71 | |
| 72 | +static DEFINE_STATIC_KEY_FALSE(gic_arm64_2941627_erratum); | |
| 73 | + | |
| 72 | 74 | static struct gic_chip_data gic_data __read_mostly; |
| 73 | 75 | static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key); |
| 74 | 76 | |
| @@ -592,10 +594,39 @@ static void gic_irq_nmi_teardown(struct irq_data *d) · 517 unmodified lines | ||
| 592 | 594 | gic_irq_set_prio(d, GICD_INT_DEF_PRI); |
| 593 | 595 | } |
| 594 | 596 | |
| 597 | +static bool gic_arm64_erratum_2941627_needed(struct irq_data *d) | |
| 598 | +{ | |
| 599 | + enum gic_intid_range range; | |
| 600 | + | |
| 601 | + if (!static_branch_unlikely(&gic_arm64_2941627_erratum)) | |
| 602 | + return false; | |
| 603 | + | |
| 604 | + range = get_intid_range(d); | |
| 605 | + | |
| 606 | + /* | |
| 607 | + * The workaround is needed if the IRQ is an SPI and | |
| 608 | + * the target cpu is different from the one we are | |
| 609 | + * executing on. | |
| 610 | + */ | |
| 611 | + return (range == SPI_RANGE || range == ESPI_RANGE) && | |
| 612 | + !cpumask_test_cpu(raw_smp_processor_id(), | |
| 613 | + irq_data_get_effective_affinity_mask(d)); | |
| 614 | +} | |
| 615 | + | |
| 595 | 616 | static void gic_eoi_irq(struct irq_data *d) |
| 596 | 617 | { |
| 597 | 618 | write_gicreg(gic_irq(d), ICC_EOIR1_EL1); |
| 598 | 619 | isb(); |
| 620 | + | |
| 621 | + if (gic_arm64_erratum_2941627_needed(d)) { | |
| 622 | + /* | |
| 623 | + * Make sure the GIC stream deactivate packet | |
| 624 | + * issued by ICC_EOIR1_EL1 has completed before | |
| 625 | + * deactivating through GICD_IACTIVER. | |
| 626 | + */ | |
| 627 | + dsb(sy); | |
| 628 | + gic_poke_irq(d, GICD_ICACTIVER); | |
| 629 | + } | |
| 599 | 630 | } |
| 600 | 631 | |
| 601 | 632 | static void gic_eoimode1_eoi_irq(struct irq_data *d) |
| @@ -606,7 +637,11 @@ static void gic_eoimode1_eoi_irq(struct irq_data *d) · 4 unmodified lines | ||
| 606 | 637 | */ |
| 607 | 638 | if (gic_irq(d) >= 8192 || irqd_is_forwarded_to_vcpu(d)) |
| 608 | 639 | return; |
| 609 | − gic_write_dir(gic_irq(d)); | |
| 640 | + | |
| 641 | + if (!gic_arm64_erratum_2941627_needed(d)) | |
| 642 | + gic_write_dir(gic_irq(d)); | |
| 643 | + else | |
| 644 | + gic_poke_irq(d, GICD_ICACTIVER); | |
| 610 | 645 | } |
| 611 | 646 | |
| 612 | 647 | static int gic_set_type(struct irq_data *d, unsigned int type) |
| @@ -1816,6 +1851,12 @@ static bool gic_enable_quirk_asr8601(void *data) · 1203 unmodified lines | ||
| 1816 | 1851 | return true; |
| 1817 | 1852 | } |
| 1818 | 1853 | |
| 1854 | +static bool gic_enable_quirk_arm64_2941627(void *data) | |
| 1855 | +{ | |
| 1856 | + static_branch_enable(&gic_arm64_2941627_erratum); | |
| 1857 | + return true; | |
| 1858 | +} | |
| 1859 | + | |
| 1819 | 1860 | static const struct gic_quirk gic_quirks[] = { |
| 1820 | 1861 | { |
| 1821 | 1862 | .desc = "GICv3: Qualcomm MSM8996 broken firmware", |
| @@ -1863,6 +1904,25 @@ static const struct gic_quirk gic_quirks[] = { · 41 unmodified lines | ||
| 1863 | 1904 | .mask = 0xffffffff, |
| 1864 | 1905 | .init = gic_enable_quirk_nvidia_t241, |
| 1865 | 1906 | }, |
| 1907 | + { | |
| 1908 | + /* | |
| 1909 | + * GIC-700: 2941627 workaround - IP variant [0,1] | |
| 1910 | + * | |
| 1911 | + */ | |
| 1912 | + .desc = "GICv3: ARM64 erratum 2941627", | |
| 1913 | + .iidr = 0x0400043b, | |
| 1914 | + .mask = 0xff0e0fff, | |
| 1915 | + .init = gic_enable_quirk_arm64_2941627, | |
| 1916 | + }, | |
| 1917 | + { | |
| 1918 | + /* | |
| 1919 | + * GIC-700: 2941627 workaround - IP variant [2] | |
| 1920 | + */ | |
| 1921 | + .desc = "GICv3: ARM64 erratum 2941627", | |
| 1922 | + .iidr = 0x0402043b, | |
| 1923 | + .mask = 0xff0f0fff, | |
| 1924 | + .init = gic_enable_quirk_arm64_2941627, | |
| 1925 | + }, | |
| 1866 | 1926 | { |
| 1867 | 1927 | } |
| 1868 | 1928 | }; |
| @@ -839,7 +839,7 @@ hfcpci_fill_fifo(struct bchannel *bch) · 838 unmodified lines | ||
| 839 | 839 | *z1t = cpu_to_le16(new_z1); /* now send data */ |
| 840 | 840 | if (bch->tx_idx < bch->tx_skb->len) |
| 841 | 841 | return; |
| 842 | − dev_kfree_skb(bch->tx_skb); | |
| 842 | + dev_kfree_skb_any(bch->tx_skb); | |
| 843 | 843 | if (get_next_bframe(bch)) |
| 844 | 844 | goto next_t_frame; |
| 845 | 845 | return; |
| @@ -895,7 +895,7 @@ hfcpci_fill_fifo(struct bchannel *bch) · 49 unmodified lines | ||
| 895 | 895 | } |
| 896 | 896 | bz->za[new_f1].z1 = cpu_to_le16(new_z1); /* for next buffer */ |
| 897 | 897 | bz->f1 = new_f1; /* next frame */ |
| 898 | − dev_kfree_skb(bch->tx_skb); | |
| 898 | + dev_kfree_skb_any(bch->tx_skb); | |
| 899 | 899 | get_next_bframe(bch); |
| 900 | 900 | } |
| 901 | 901 | |
| @@ -1119,7 +1119,7 @@ tx_birq(struct bchannel *bch) · 217 unmodified lines | ||
| 1119 | 1119 | if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len) |
| 1120 | 1120 | hfcpci_fill_fifo(bch); |
| 1121 | 1121 | else { |
| 1122 | − dev_kfree_skb(bch->tx_skb); | |
| 1122 | + dev_kfree_skb_any(bch->tx_skb); | |
| 1123 | 1123 | if (get_next_bframe(bch)) |
| 1124 | 1124 | hfcpci_fill_fifo(bch); |
| 1125 | 1125 | } |
| @@ -2277,7 +2277,7 @@ _hfcpci_softirq(struct device *dev, void *unused) · 1151 unmodified lines | ||
| 2277 | 2277 | return 0; |
| 2278 | 2278 | |
| 2279 | 2279 | if (hc->hw.int_m2 & HFCPCI_IRQ_ENABLE) { |
| 2280 | − spin_lock(&hc->lock); | |
| 2280 | + spin_lock_irq(&hc->lock); | |
| 2281 | 2281 | bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); |
| 2282 | 2282 | if (bch && bch->state == ISDN_P_B_RAW) { /* B1 rx&tx */ |
| 2283 | 2283 | main_rec_hfcpci(bch); |
| @@ -2288,7 +2288,7 @@ _hfcpci_softirq(struct device *dev, void *unused) · 4 unmodified lines | ||
| 2288 | 2288 | main_rec_hfcpci(bch); |
| 2289 | 2289 | tx_birq(bch); |
| 2290 | 2290 | } |
| 2291 | − spin_unlock(&hc->lock); | |
| 2291 | + spin_unlock_irq(&hc->lock); | |
| 2292 | 2292 | } |
| 2293 | 2293 | return 0; |
| 2294 | 2294 | } |
| @@ -247,7 +247,7 @@ extern void dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp); · 246 unmodified lines | ||
| 247 | 247 | extern int dsp_cmx_conf(struct dsp *dsp, u32 conf_id); |
| 248 | 248 | extern void dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb); |
| 249 | 249 | extern void dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb); |
| 250 | −extern void dsp_cmx_send(void *arg); | |
| 250 | +extern void dsp_cmx_send(struct timer_list *arg); | |
| 251 | 251 | extern void dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb); |
| 252 | 252 | extern int dsp_cmx_del_conf_member(struct dsp *dsp); |
| 253 | 253 | extern int dsp_cmx_del_conf(struct dsp_conf *conf); |
| @@ -1614,7 +1614,7 @@ static u16 dsp_count; /* last sample count */ · 1613 unmodified lines | ||
| 1614 | 1614 | static int dsp_count_valid; /* if we have last sample count */ |
| 1615 | 1615 | |
| 1616 | 1616 | void |
| 1617 | −dsp_cmx_send(void *arg) | |
| 1617 | +dsp_cmx_send(struct timer_list *arg) | |
| 1618 | 1618 | { |
| 1619 | 1619 | struct dsp_conf *conf; |
| 1620 | 1620 | struct dsp_conf_member *member; |
| @@ -1195,7 +1195,7 @@ static int __init dsp_init(void) · 1194 unmodified lines | ||
| 1195 | 1195 | } |
| 1196 | 1196 | |
| 1197 | 1197 | /* set sample timer */ |
| 1198 | − timer_setup(&dsp_spl_tl, (void *)dsp_cmx_send, 0); | |
| 1198 | + timer_setup(&dsp_spl_tl, dsp_cmx_send, 0); | |
| 1199 | 1199 | dsp_spl_tl.expires = jiffies + dsp_tics; |
| 1200 | 1200 | dsp_spl_jiffies = dsp_spl_tl.expires; |
| 1201 | 1201 | add_timer(&dsp_spl_tl); |
| @@ -857,7 +857,13 @@ struct smq_policy { · 856 unmodified lines | ||
| 857 | 857 | |
| 858 | 858 | struct background_tracker *bg_work; |
| 859 | 859 | |
| 860 | − bool migrations_allowed; | |
| 860 | + bool migrations_allowed:1; | |
| 861 | + | |
| 862 | + /* | |
| 863 | + * If this is set the policy will try and clean the whole cache | |
| 864 | + * even if the device is not idle. | |
| 865 | + */ | |
| 866 | + bool cleaner:1; | |
| 861 | 867 | }; |
| 862 | 868 | |
| 863 | 869 | /*----------------------------------------------------------------*/ |
| @@ -1138,7 +1144,7 @@ static bool clean_target_met(struct smq_policy *mq, bool idle) · 274 unmodified lines | ||
| 1138 | 1144 | * Cache entries may not be populated. So we cannot rely on the |
| 1139 | 1145 | * size of the clean queue. |
| 1140 | 1146 | */ |
| 1141 | − if (idle) { | |
| 1147 | + if (idle || mq->cleaner) { | |
| 1142 | 1148 | /* |
| 1143 | 1149 | * We'd like to clean everything. |
| 1144 | 1150 | */ |
| @@ -1722,11 +1728,9 @@ static void calc_hotspot_params(sector_t origin_size, · 577 unmodified lines | ||
| 1722 | 1728 | *hotspot_block_size /= 2u; |
| 1723 | 1729 | } |
| 1724 | 1730 | |
| 1725 | −static struct dm_cache_policy *__smq_create(dm_cblock_t cache_size, | |
| 1726 | − sector_t origin_size, | |
| 1727 | − sector_t cache_block_size, | |
| 1728 | − bool mimic_mq, | |
| 1729 | − bool migrations_allowed) | |
| 1731 | +static struct dm_cache_policy * | |
| 1732 | +__smq_create(dm_cblock_t cache_size, sector_t origin_size, sector_t cache_block_size, | |
| 1733 | + bool mimic_mq, bool migrations_allowed, bool cleaner) | |
| 1730 | 1734 | { |
| 1731 | 1735 | unsigned int i; |
| 1732 | 1736 | unsigned int nr_sentinels_per_queue = 2u * NR_CACHE_LEVELS; |
| @@ -1813,6 +1817,7 @@ static struct dm_cache_policy *__smq_create(dm_cblock_t cache_size, · 80 unmodified lines | ||
| 1813 | 1817 | goto bad_btracker; |
| 1814 | 1818 | |
| 1815 | 1819 | mq->migrations_allowed = migrations_allowed; |
| 1820 | + mq->cleaner = cleaner; | |
| 1816 | 1821 | |
| 1817 | 1822 | return &mq->policy; |
| 1818 | 1823 | |
| @@ -1836,21 +1841,24 @@ static struct dm_cache_policy *smq_create(dm_cblock_t cache_size, · 17 unmodified lines | ||
| 1836 | 1841 | sector_t origin_size, |
| 1837 | 1842 | sector_t cache_block_size) |
| 1838 | 1843 | { |
| 1839 | − return __smq_create(cache_size, origin_size, cache_block_size, false, true); | |
| 1844 | + return __smq_create(cache_size, origin_size, cache_block_size, | |
| 1845 | + false, true, false); | |
| 1840 | 1846 | } |
| 1841 | 1847 | |
| 1842 | 1848 | static struct dm_cache_policy *mq_create(dm_cblock_t cache_size, |
| 1843 | 1849 | sector_t origin_size, |
| 1844 | 1850 | sector_t cache_block_size) |
| 1845 | 1851 | { |
| 1846 | − return __smq_create(cache_size, origin_size, cache_block_size, true, true); | |
| 1852 | + return __smq_create(cache_size, origin_size, cache_block_size, | |
| 1853 | + true, true, false); | |
| 1847 | 1854 | } |
| 1848 | 1855 | |
| 1849 | 1856 | static struct dm_cache_policy *cleaner_create(dm_cblock_t cache_size, |
| 1850 | 1857 | sector_t origin_size, |
| 1851 | 1858 | sector_t cache_block_size) |
| 1852 | 1859 | { |
| 1853 | − return __smq_create(cache_size, origin_size, cache_block_size, false, false); | |
| 1860 | + return __smq_create(cache_size, origin_size, cache_block_size, | |
| 1861 | + false, false, true); | |
| 1854 | 1862 | } |
| 1855 | 1863 | |
| 1856 | 1864 | /*----------------------------------------------------------------*/ |
| @@ -2676,6 +2676,7 @@ oom: · 2675 unmodified lines | ||
| 2676 | 2676 | recalc_tags = kvmalloc(recalc_tags_size, GFP_NOIO); |
| 2677 | 2677 | if (!recalc_tags) { |
| 2678 | 2678 | vfree(recalc_buffer); |
| 2679 | + recalc_buffer = NULL; | |
| 2679 | 2680 | goto oom; |
| 2680 | 2681 | } |
| 2681 | 2682 | |
| @@ -3251,8 +3251,7 @@ size_check: · 3250 unmodified lines | ||
| 3251 | 3251 | r = md_start(&rs->md); |
| 3252 | 3252 | if (r) { |
| 3253 | 3253 | ti->error = "Failed to start raid array"; |
| 3254 | − mddev_unlock(&rs->md); | |
| 3255 | − goto bad_md_start; | |
| 3254 | + goto bad_unlock; | |
| 3256 | 3255 | } |
| 3257 | 3256 | |
| 3258 | 3257 | /* If raid4/5/6 journal mode explicitly requested (only possible with journal dev) -> set it */ |
| @@ -3260,8 +3259,7 @@ size_check: · 1 unmodified line | ||
| 3260 | 3259 | r = r5c_journal_mode_set(&rs->md, rs->journal_dev.mode); |
| 3261 | 3260 | if (r) { |
| 3262 | 3261 | ti->error = "Failed to set raid4/5/6 journal mode"; |
| 3263 | − mddev_unlock(&rs->md); | |
| 3264 | − goto bad_journal_mode_set; | |
| 3262 | + goto bad_unlock; | |
| 3265 | 3263 | } |
| 3266 | 3264 | } |
| 3267 | 3265 | |
| @@ -3272,14 +3270,14 @@ size_check: · 4 unmodified lines | ||
| 3272 | 3270 | if (rs_is_raid456(rs)) { |
| 3273 | 3271 | r = rs_set_raid456_stripe_cache(rs); |
| 3274 | 3272 | if (r) |
| 3275 | − goto bad_stripe_cache; | |
| 3273 | + goto bad_unlock; | |
| 3276 | 3274 | } |
| 3277 | 3275 | |
| 3278 | 3276 | /* Now do an early reshape check */ |
| 3279 | 3277 | if (test_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) { |
| 3280 | 3278 | r = rs_check_reshape(rs); |
| 3281 | 3279 | if (r) |
| 3282 | − goto bad_check_reshape; | |
| 3280 | + goto bad_unlock; | |
| 3283 | 3281 | |
| 3284 | 3282 | /* Restore new, ctr requested layout to perform check */ |
| 3285 | 3283 | rs_config_restore(rs, &rs_layout); |
| @@ -3288,7 +3286,7 @@ size_check: · 2 unmodified lines | ||
| 3288 | 3286 | r = rs->md.pers->check_reshape(&rs->md); |
| 3289 | 3287 | if (r) { |
| 3290 | 3288 | ti->error = "Reshape check failed"; |
| 3291 | − goto bad_check_reshape; | |
| 3289 | + goto bad_unlock; | |
| 3292 | 3290 | } |
| 3293 | 3291 | } |
| 3294 | 3292 | } |
| @@ -3299,11 +3297,9 @@ size_check: · 4 unmodified lines | ||
| 3299 | 3297 | mddev_unlock(&rs->md); |
| 3300 | 3298 | return 0; |
| 3301 | 3299 | |
| 3302 | −bad_md_start: | |
| 3303 | −bad_journal_mode_set: | |
| 3304 | −bad_stripe_cache: | |
| 3305 | −bad_check_reshape: | |
| 3300 | +bad_unlock: | |
| 3306 | 3301 | md_stop(&rs->md); |
| 3302 | + mddev_unlock(&rs->md); | |
| 3307 | 3303 | bad: |
| 3308 | 3304 | raid_set_free(rs); |
| 3309 | 3305 | |
| @@ -3314,7 +3310,9 @@ static void raid_dtr(struct dm_target *ti) · 4 unmodified lines | ||
| 3314 | 3310 | { |
| 3315 | 3311 | struct raid_set *rs = ti->private; |
| 3316 | 3312 | |
| 3313 | + mddev_lock_nointr(&rs->md); | |
| 3317 | 3314 | md_stop(&rs->md); |
| 3315 | + mddev_unlock(&rs->md); | |
| 3318 | 3316 | raid_set_free(rs); |
| 3319 | 3317 | } |
| 3320 | 3318 | |
| @@ -6247,6 +6247,8 @@ static void __md_stop(struct mddev *mddev) · 6246 unmodified lines | ||
| 6247 | 6247 | |
| 6248 | 6248 | void md_stop(struct mddev *mddev) |
| 6249 | 6249 | { |
| 6250 | + lockdep_assert_held(&mddev->reconfig_mutex); | |
| 6251 | + | |
| 6250 | 6252 | /* stop the array and free an attached data structures. |
| 6251 | 6253 | * This is called from dm-raid |
| 6252 | 6254 | */ |
| @@ -809,8 +809,11 @@ static void pulse8_ping_eeprom_work_handler(struct work_struct *work) · 808 unmodified lines | ||
| 809 | 809 | |
| 810 | 810 | mutex_lock(&pulse8->lock); |
| 811 | 811 | cmd = MSGCODE_PING; |
| 812 | − pulse8_send_and_wait(pulse8, &cmd, 1, | |
| 813 | − MSGCODE_COMMAND_ACCEPTED, 0); | |
| 812 | + if (pulse8_send_and_wait(pulse8, &cmd, 1, | |
| 813 | + MSGCODE_COMMAND_ACCEPTED, 0)) { | |
| 814 | + dev_warn(pulse8->dev, "failed to ping EEPROM\n"); | |
| 815 | + goto unlock; | |
| 816 | + } | |
| 814 | 817 | |
| 815 | 818 | if (pulse8->vers < 2) |
| 816 | 819 | goto unlock; |
| @@ -813,8 +813,8 @@ static unsigned long tc358746_find_pll_settings(struct tc358746 *tc358746, · 812 unmodified lines | ||
| 813 | 813 | u32 min_delta = 0xffffffff; |
| 814 | 814 | u16 prediv_max = 17; |
| 815 | 815 | u16 prediv_min = 1; |
| 816 | − u16 m_best, mul; | |
| 817 | − u16 p_best, p; | |
| 816 | + u16 m_best = 0, mul; | |
| 817 | + u16 p_best = 1, p; | |
| 818 | 818 | u8 postdiv; |
| 819 | 819 | |
| 820 | 820 | if (fout > 1000 * HZ_PER_MHZ) { |
| @@ -2459,16 +2459,10 @@ static int dvb_register(struct cx23885_tsport *port) · 2458 unmodified lines | ||
| 2459 | 2459 | request_module("%s", info.type); |
| 2460 | 2460 | client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info); |
| 2461 | 2461 | if (!i2c_client_has_driver(client_tuner)) { |
| 2462 | − module_put(client_demod->dev.driver->owner); | |
| 2463 | − i2c_unregister_device(client_demod); | |
| 2464 | − port->i2c_client_demod = NULL; | |
| 2465 | 2462 | goto frontend_detach; |
| 2466 | 2463 | } |
| 2467 | 2464 | if (!try_module_get(client_tuner->dev.driver->owner)) { |
| 2468 | 2465 | i2c_unregister_device(client_tuner); |
| 2469 | − module_put(client_demod->dev.driver->owner); | |
| 2470 | − i2c_unregister_device(client_demod); | |
| 2471 | − port->i2c_client_demod = NULL; | |
| 2472 | 2466 | goto frontend_detach; |
| 2473 | 2467 | } |
| 2474 | 2468 | port->i2c_client_tuner = client_tuner; |
| @@ -2505,16 +2499,10 @@ static int dvb_register(struct cx23885_tsport *port) · 30 unmodified lines | ||
| 2505 | 2499 | request_module("%s", info.type); |
| 2506 | 2500 | client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info); |
| 2507 | 2501 | if (!i2c_client_has_driver(client_tuner)) { |
| 2508 | − module_put(client_demod->dev.driver->owner); | |
| 2509 | − i2c_unregister_device(client_demod); | |
| 2510 | − port->i2c_client_demod = NULL; | |
| 2511 | 2502 | goto frontend_detach; |
| 2512 | 2503 | } |
| 2513 | 2504 | if (!try_module_get(client_tuner->dev.driver->owner)) { |
| 2514 | 2505 | i2c_unregister_device(client_tuner); |
| 2515 | − module_put(client_demod->dev.driver->owner); | |
| 2516 | − i2c_unregister_device(client_demod); | |
| 2517 | − port->i2c_client_demod = NULL; | |
| 2518 | 2506 | goto frontend_detach; |
| 2519 | 2507 | } |
| 2520 | 2508 | port->i2c_client_tuner = client_tuner; |
| @@ -826,7 +826,7 @@ static const struct dev_pm_ops vpu_core_pm_ops = { · 825 unmodified lines | ||
| 826 | 826 | |
| 827 | 827 | static struct vpu_core_resources imx8q_enc = { |
| 828 | 828 | .type = VPU_CORE_TYPE_ENC, |
| 829 | − .fwname = "vpu/vpu_fw_imx8_enc.bin", | |
| 829 | + .fwname = "amphion/vpu/vpu_fw_imx8_enc.bin", | |
| 830 | 830 | .stride = 16, |
| 831 | 831 | .max_width = 1920, |
| 832 | 832 | .max_height = 1920, |
| @@ -841,7 +841,7 @@ static struct vpu_core_resources imx8q_enc = { · 8 unmodified lines | ||
| 841 | 841 | |
| 842 | 842 | static struct vpu_core_resources imx8q_dec = { |
| 843 | 843 | .type = VPU_CORE_TYPE_DEC, |
| 844 | − .fwname = "vpu/vpu_fw_imx8_dec.bin", | |
| 844 | + .fwname = "amphion/vpu/vpu_fw_imx8_dec.bin", | |
| 845 | 845 | .stride = 256, |
| 846 | 846 | .max_width = 8188, |
| 847 | 847 | .max_height = 8188, |
| @@ -46,11 +46,10 @@ static int vpu_mbox_request_channel(struct device *dev, struct vpu_mbox *mbox) · 45 unmodified lines | ||
| 46 | 46 | cl->rx_callback = vpu_mbox_rx_callback; |
| 47 | 47 | |
| 48 | 48 | ch = mbox_request_channel_byname(cl, mbox->name); |
| 49 | − if (IS_ERR(ch)) { | |
| 50 | − dev_err(dev, "Failed to request mbox chan %s, ret : %ld\n", | |
| 51 | − mbox->name, PTR_ERR(ch)); | |
| 52 | − return PTR_ERR(ch); | |
| 53 | − } | |
| 49 | + if (IS_ERR(ch)) | |
| 50 | + return dev_err_probe(dev, PTR_ERR(ch), | |
| 51 | + "Failed to request mbox chan %s\n", | |
| 52 | + mbox->name); | |
| 54 | 53 | |
| 55 | 54 | mbox->ch = ch; |
| 56 | 55 | return 0; |
| @@ -28,7 +28,6 @@ · 27 unmodified lines | ||
| 28 | 28 | #include "mtk_jpeg_core.h" |
| 29 | 29 | #include "mtk_jpeg_dec_parse.h" |
| 30 | 30 | |
| 31 | −#if defined(CONFIG_OF) | |
| 32 | 31 | static struct mtk_jpeg_fmt mtk_jpeg_enc_formats[] = { |
| 33 | 32 | { |
| 34 | 33 | .fourcc = V4L2_PIX_FMT_JPEG, |
| @@ -102,7 +101,6 @@ static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = { · 67 unmodified lines | ||
| 102 | 101 | .flags = MTK_JPEG_FMT_FLAG_CAPTURE, |
| 103 | 102 | }, |
| 104 | 103 | }; |
| 105 | −#endif | |
| 106 | 104 | |
| 107 | 105 | #define MTK_JPEG_ENC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_enc_formats) |
| 108 | 106 | #define MTK_JPEG_DEC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_dec_formats) |
| @@ -1455,7 +1453,6 @@ static const struct dev_pm_ops mtk_jpeg_pm_ops = { · 1346 unmodified lines | ||
| 1455 | 1453 | SET_RUNTIME_PM_OPS(mtk_jpeg_pm_suspend, mtk_jpeg_pm_resume, NULL) |
| 1456 | 1454 | }; |
| 1457 | 1455 | |
| 1458 | −#if defined(CONFIG_OF) | |
| 1459 | 1456 | static int mtk_jpegenc_get_hw(struct mtk_jpeg_ctx *ctx) |
| 1460 | 1457 | { |
| 1461 | 1458 | struct mtk_jpegenc_comp_dev *comp_jpeg; |
| @@ -1951,14 +1948,13 @@ static const struct of_device_id mtk_jpeg_match[] = { · 489 unmodified lines | ||
| 1951 | 1948 | }; |
| 1952 | 1949 | |
| 1953 | 1950 | MODULE_DEVICE_TABLE(of, mtk_jpeg_match); |
| 1954 | −#endif | |
| 1955 | 1951 | |
| 1956 | 1952 | static struct platform_driver mtk_jpeg_driver = { |
| 1957 | 1953 | .probe = mtk_jpeg_probe, |
| 1958 | 1954 | .remove_new = mtk_jpeg_remove, |
| 1959 | 1955 | .driver = { |
| 1960 | 1956 | .name = MTK_JPEG_NAME, |
| 1961 | − .of_match_table = of_match_ptr(mtk_jpeg_match), | |
| 1957 | + .of_match_table = mtk_jpeg_match, | |
| 1962 | 1958 | .pm = &mtk_jpeg_pm_ops, |
| 1963 | 1959 | }, |
| 1964 | 1960 | }; |
| @@ -39,7 +39,6 @@ enum mtk_jpeg_color { · 38 unmodified lines | ||
| 39 | 39 | MTK_JPEG_COLOR_400 = 0x00110000 |
| 40 | 40 | }; |
| 41 | 41 | |
| 42 | −#if defined(CONFIG_OF) | |
| 43 | 42 | static const struct of_device_id mtk_jpegdec_hw_ids[] = { |
| 44 | 43 | { |
| 45 | 44 | .compatible = "mediatek,mt8195-jpgdec-hw", |
| @@ -47,7 +46,6 @@ static const struct of_device_id mtk_jpegdec_hw_ids[] = { · 1 unmodified line | ||
| 47 | 46 | {}, |
| 48 | 47 | }; |
| 49 | 48 | MODULE_DEVICE_TABLE(of, mtk_jpegdec_hw_ids); |
| 50 | −#endif | |
| 51 | 49 | |
| 52 | 50 | static inline int mtk_jpeg_verify_align(u32 val, int align, u32 reg) |
| 53 | 51 | { |
| @@ -653,7 +651,7 @@ static struct platform_driver mtk_jpegdec_hw_driver = { · 599 unmodified lines | ||
| 653 | 651 | .probe = mtk_jpegdec_hw_probe, |
| 654 | 652 | .driver = { |
| 655 | 653 | .name = "mtk-jpegdec-hw", |
| 656 | − .of_match_table = of_match_ptr(mtk_jpegdec_hw_ids), | |
| 654 | + .of_match_table = mtk_jpegdec_hw_ids, | |
| 657 | 655 | }, |
| 658 | 656 | }; |
| 659 | 657 | |
| @@ -46,7 +46,6 @@ static const struct mtk_jpeg_enc_qlt mtk_jpeg_enc_quality[] = { · 45 unmodified lines | ||
| 46 | 46 | {.quality_param = 97, .hardware_value = JPEG_ENC_QUALITY_Q97}, |
| 47 | 47 | }; |
| 48 | 48 | |
| 49 | −#if defined(CONFIG_OF) | |
| 50 | 49 | static const struct of_device_id mtk_jpegenc_drv_ids[] = { |
| 51 | 50 | { |
| 52 | 51 | .compatible = "mediatek,mt8195-jpgenc-hw", |
| @@ -54,7 +53,6 @@ static const struct of_device_id mtk_jpegenc_drv_ids[] = { · 1 unmodified line | ||
| 54 | 53 | {}, |
| 55 | 54 | }; |
| 56 | 55 | MODULE_DEVICE_TABLE(of, mtk_jpegenc_drv_ids); |
| 57 | −#endif | |
| 58 | 56 | |
| 59 | 57 | void mtk_jpeg_enc_reset(void __iomem *base) |
| 60 | 58 | { |
| @@ -377,7 +375,7 @@ static struct platform_driver mtk_jpegenc_hw_driver = { · 316 unmodified lines | ||
| 377 | 375 | .probe = mtk_jpegenc_hw_probe, |
| 378 | 376 | .driver = { |
| 379 | 377 | .name = "mtk-jpegenc-hw", |
| 380 | − .of_match_table = of_match_ptr(mtk_jpegenc_drv_ids), | |
| 378 | + .of_match_table = mtk_jpegenc_drv_ids, | |
| 381 | 379 | }, |
| 382 | 380 | }; |
| 383 | 381 | |
| @@ -233,7 +233,8 @@ void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue, · 232 unmodified lines | ||
| 233 | 233 | kfree(lat_buf->private_data); |
| 234 | 234 | } |
| 235 | 235 | |
| 236 | − cancel_work_sync(&msg_queue->core_work); | |
| 236 | + if (msg_queue->wdma_addr.size) | |
| 237 | + cancel_work_sync(&msg_queue->core_work); | |
| 237 | 238 | } |
| 238 | 239 | |
| 239 | 240 | static void vdec_msg_queue_core_work(struct work_struct *work) |
| @@ -58,7 +58,6 @@ · 57 unmodified lines | ||
| 58 | 58 | #define CAST_OFBSIZE_LO CAST_STATUS18 |
| 59 | 59 | #define CAST_OFBSIZE_HI CAST_STATUS19 |
| 60 | 60 | |
| 61 | −#define MXC_MAX_SLOTS 1 /* TODO use all 4 slots*/ | |
| 62 | 61 | /* JPEG-Decoder Wrapper Slot Registers 0..3 */ |
| 63 | 62 | #define SLOT_BASE 0x10000 |
| 64 | 63 | #define SLOT_STATUS 0x0 |
| @@ -745,87 +745,77 @@ static void notify_src_chg(struct mxc_jpeg_ctx *ctx) · 744 unmodified lines | ||
| 745 | 745 | v4l2_event_queue_fh(&ctx->fh, &ev); |
| 746 | 746 | } |
| 747 | 747 | |
| 748 | −static int mxc_get_free_slot(struct mxc_jpeg_slot_data slot_data[], int n) | |
| 748 | +static int mxc_get_free_slot(struct mxc_jpeg_slot_data *slot_data) | |
| 749 | 749 | { |
| 750 | − int free_slot = 0; | |
| 751 | − | |
| 752 | − while (slot_data[free_slot].used && free_slot < n) | |
| 753 | − free_slot++; | |
| 754 | − | |
| 755 | − return free_slot; /* >=n when there are no more free slots */ | |
| 750 | + if (!slot_data->used) | |
| 751 | + return slot_data->slot; | |
| 752 | + return -1; | |
| 756 | 753 | } |
| 757 | 754 | |
| 758 | −static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg, | |
| 759 | − unsigned int slot) | |
| 755 | +static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg) | |
| 760 | 756 | { |
| 761 | 757 | struct mxc_jpeg_desc *desc; |
| 762 | 758 | struct mxc_jpeg_desc *cfg_desc; |
| 763 | 759 | void *cfg_stm; |
| 764 | 760 | |
| 765 | − if (jpeg->slot_data[slot].desc) | |
| 761 | + if (jpeg->slot_data.desc) | |
| 766 | 762 | goto skip_alloc; /* already allocated, reuse it */ |
| 767 | 763 | |
| 768 | 764 | /* allocate descriptor for decoding/encoding phase */ |
| 769 | 765 | desc = dma_alloc_coherent(jpeg->dev, |
| 770 | 766 | sizeof(struct mxc_jpeg_desc), |
| 771 | − &jpeg->slot_data[slot].desc_handle, | |
| 767 | + &jpeg->slot_data.desc_handle, | |
| 772 | 768 | GFP_ATOMIC); |
| 773 | 769 | if (!desc) |
| 774 | 770 | goto err; |
| 775 | − jpeg->slot_data[slot].desc = desc; | |
| 771 | + jpeg->slot_data.desc = desc; | |
| 776 | 772 | |
| 777 | 773 | /* allocate descriptor for configuration phase (encoder only) */ |
| 778 | 774 | cfg_desc = dma_alloc_coherent(jpeg->dev, |
| 779 | 775 | sizeof(struct mxc_jpeg_desc), |
| 780 | − &jpeg->slot_data[slot].cfg_desc_handle, | |
| 776 | + &jpeg->slot_data.cfg_desc_handle, | |
| 781 | 777 | GFP_ATOMIC); |
| 782 | 778 | if (!cfg_desc) |
| 783 | 779 | goto err; |
| 784 | − jpeg->slot_data[slot].cfg_desc = cfg_desc; | |
| 780 | + jpeg->slot_data.cfg_desc = cfg_desc; | |
| 785 | 781 | |
| 786 | 782 | /* allocate configuration stream */ |
| 787 | 783 | cfg_stm = dma_alloc_coherent(jpeg->dev, |
| 788 | 784 | MXC_JPEG_MAX_CFG_STREAM, |
| 789 | − &jpeg->slot_data[slot].cfg_stream_handle, | |
| 785 | + &jpeg->slot_data.cfg_stream_handle, | |
| 790 | 786 | GFP_ATOMIC); |
| 791 | 787 | if (!cfg_stm) |
| 792 | 788 | goto err; |
| 793 | − jpeg->slot_data[slot].cfg_stream_vaddr = cfg_stm; | |
| 789 | + jpeg->slot_data.cfg_stream_vaddr = cfg_stm; | |
| 794 | 790 | |
| 795 | 791 | skip_alloc: |
| 796 | − jpeg->slot_data[slot].used = true; | |
| 792 | + jpeg->slot_data.used = true; | |
| 797 | 793 | |
| 798 | 794 | return true; |
| 799 | 795 | err: |
| 800 | − dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", slot); | |
| 796 | + dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", jpeg->slot_data.slot); | |
| 801 | 797 | |
| 802 | 798 | return false; |
| 803 | 799 | } |
| 804 | 800 | |
| 805 | −static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg, | |
| 806 | − unsigned int slot) | |
| 801 | +static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg) | |
| 807 | 802 | { |
| 808 | − if (slot >= MXC_MAX_SLOTS) { | |
| 809 | − dev_err(jpeg->dev, "Invalid slot %d, nothing to free.", slot); | |
| 810 | − return; | |
| 811 | − } | |
| 812 | − | |
| 813 | 803 | /* free descriptor for decoding/encoding phase */ |
| 814 | 804 | dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), |
| 815 | − jpeg->slot_data[slot].desc, | |
| 816 | − jpeg->slot_data[slot].desc_handle); | |
| 805 | + jpeg->slot_data.desc, | |
| 806 | + jpeg->slot_data.desc_handle); | |
| 817 | 807 | |
| 818 | 808 | /* free descriptor for encoder configuration phase / decoder DHT */ |
| 819 | 809 | dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), |
| 820 | − jpeg->slot_data[slot].cfg_desc, | |
| 821 | − jpeg->slot_data[slot].cfg_desc_handle); | |
| 810 | + jpeg->slot_data.cfg_desc, | |
| 811 | + jpeg->slot_data.cfg_desc_handle); | |
| 822 | 812 | |
| 823 | 813 | /* free configuration stream */ |
| 824 | 814 | dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM, |
| 825 | − jpeg->slot_data[slot].cfg_stream_vaddr, | |
| 826 | − jpeg->slot_data[slot].cfg_stream_handle); | |
| 815 | + jpeg->slot_data.cfg_stream_vaddr, | |
| 816 | + jpeg->slot_data.cfg_stream_handle); | |
| 827 | 817 | |
| 828 | − jpeg->slot_data[slot].used = false; | |
| 818 | + jpeg->slot_data.used = false; | |
| 829 | 819 | } |
| 830 | 820 | |
| 831 | 821 | static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx, |
| @@ -855,7 +845,7 @@ static void mxc_jpeg_job_finish(struct mxc_jpeg_ctx *ctx, enum vb2_buffer_state · 23 unmodified lines | ||
| 855 | 845 | v4l2_m2m_buf_done(dst_buf, state); |
| 856 | 846 | |
| 857 | 847 | mxc_jpeg_disable_irq(reg, ctx->slot); |
| 858 | − ctx->mxc_jpeg->slot_data[ctx->slot].used = false; | |
| 848 | + jpeg->slot_data.used = false; | |
| 859 | 849 | if (reset) |
| 860 | 850 | mxc_jpeg_sw_reset(reg); |
| 861 | 851 | } |
| @@ -919,7 +909,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) · 57 unmodified lines | ||
| 919 | 909 | goto job_unlock; |
| 920 | 910 | } |
| 921 | 911 | |
| 922 | − if (!jpeg->slot_data[slot].used) | |
| 912 | + if (!jpeg->slot_data.used) | |
| 923 | 913 | goto job_unlock; |
| 924 | 914 | |
| 925 | 915 | dec_ret = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS)); |
| @@ -1179,13 +1169,13 @@ static void mxc_jpeg_config_dec_desc(struct vb2_buffer *out_buf, · 253 unmodified lines | ||
| 1179 | 1169 | struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; |
| 1180 | 1170 | void __iomem *reg = jpeg->base_reg; |
| 1181 | 1171 | unsigned int slot = ctx->slot; |
| 1182 | − struct mxc_jpeg_desc *desc = jpeg->slot_data[slot].desc; | |
| 1183 | − struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data[slot].cfg_desc; | |
| 1184 | − dma_addr_t desc_handle = jpeg->slot_data[slot].desc_handle; | |
| 1185 | − dma_addr_t cfg_desc_handle = jpeg->slot_data[slot].cfg_desc_handle; | |
| 1186 | − dma_addr_t cfg_stream_handle = jpeg->slot_data[slot].cfg_stream_handle; | |
| 1187 | − unsigned int *cfg_size = &jpeg->slot_data[slot].cfg_stream_size; | |
| 1188 | − void *cfg_stream_vaddr = jpeg->slot_data[slot].cfg_stream_vaddr; | |
| 1172 | + struct mxc_jpeg_desc *desc = jpeg->slot_data.desc; | |
| 1173 | + struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc; | |
| 1174 | + dma_addr_t desc_handle = jpeg->slot_data.desc_handle; | |
| 1175 | + dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle; | |
| 1176 | + dma_addr_t cfg_stream_handle = jpeg->slot_data.cfg_stream_handle; | |
| 1177 | + unsigned int *cfg_size = &jpeg->slot_data.cfg_stream_size; | |
| 1178 | + void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr; | |
| 1189 | 1179 | struct mxc_jpeg_src_buf *jpeg_src_buf; |
| 1190 | 1180 | |
| 1191 | 1181 | jpeg_src_buf = vb2_to_mxc_buf(src_buf); |
| @@ -1245,18 +1235,18 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf, · 53 unmodified lines | ||
| 1245 | 1235 | struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; |
| 1246 | 1236 | void __iomem *reg = jpeg->base_reg; |
| 1247 | 1237 | unsigned int slot = ctx->slot; |
| 1248 | − struct mxc_jpeg_desc *desc = jpeg->slot_data[slot].desc; | |
| 1249 | − struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data[slot].cfg_desc; | |
| 1250 | − dma_addr_t desc_handle = jpeg->slot_data[slot].desc_handle; | |
| 1251 | − dma_addr_t cfg_desc_handle = jpeg->slot_data[slot].cfg_desc_handle; | |
| 1252 | − void *cfg_stream_vaddr = jpeg->slot_data[slot].cfg_stream_vaddr; | |
| 1238 | + struct mxc_jpeg_desc *desc = jpeg->slot_data.desc; | |
| 1239 | + struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc; | |
| 1240 | + dma_addr_t desc_handle = jpeg->slot_data.desc_handle; | |
| 1241 | + dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle; | |
| 1242 | + void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr; | |
| 1253 | 1243 | struct mxc_jpeg_q_data *q_data; |
| 1254 | 1244 | enum mxc_jpeg_image_format img_fmt; |
| 1255 | 1245 | int w, h; |
| 1256 | 1246 | |
| 1257 | 1247 | q_data = mxc_jpeg_get_q_data(ctx, src_buf->vb2_queue->type); |
| 1258 | 1248 | |
| 1259 | − jpeg->slot_data[slot].cfg_stream_size = | |
| 1249 | + jpeg->slot_data.cfg_stream_size = | |
| 1260 | 1250 | mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr, |
| 1261 | 1251 | q_data->fmt->fourcc, |
| 1262 | 1252 | q_data->crop.width, |
| @@ -1265,7 +1255,7 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf, · 2 unmodified lines | ||
| 1265 | 1255 | /* chain the config descriptor with the encoding descriptor */ |
| 1266 | 1256 | cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN; |
| 1267 | 1257 | |
| 1268 | − cfg_desc->buf_base0 = jpeg->slot_data[slot].cfg_stream_handle; | |
| 1258 | + cfg_desc->buf_base0 = jpeg->slot_data.cfg_stream_handle; | |
| 1269 | 1259 | cfg_desc->buf_base1 = 0; |
| 1270 | 1260 | cfg_desc->line_pitch = 0; |
| 1271 | 1261 | cfg_desc->stm_bufbase = 0; /* no output expected */ |
| @@ -1408,7 +1398,7 @@ static void mxc_jpeg_device_run_timeout(struct work_struct *work) · 136 unmodified lines | ||
| 1408 | 1398 | unsigned long flags; |
| 1409 | 1399 | |
| 1410 | 1400 | spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags); |
| 1411 | − if (ctx->slot < MXC_MAX_SLOTS && ctx->mxc_jpeg->slot_data[ctx->slot].used) { | |
| 1401 | + if (ctx->mxc_jpeg->slot_data.used) { | |
| 1412 | 1402 | dev_warn(jpeg->dev, "%s timeout, cancel it\n", |
| 1413 | 1403 | ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? "decode" : "encode"); |
| 1414 | 1404 | mxc_jpeg_job_finish(ctx, VB2_BUF_STATE_ERROR, true); |
| @@ -1476,12 +1466,12 @@ static void mxc_jpeg_device_run(void *priv) · 61 unmodified lines | ||
| 1476 | 1466 | mxc_jpeg_enable(reg); |
| 1477 | 1467 | mxc_jpeg_set_l_endian(reg, 1); |
| 1478 | 1468 | |
| 1479 | − ctx->slot = mxc_get_free_slot(jpeg->slot_data, MXC_MAX_SLOTS); | |
| 1480 | − if (ctx->slot >= MXC_MAX_SLOTS) { | |
| 1469 | + ctx->slot = mxc_get_free_slot(&jpeg->slot_data); | |
| 1470 | + if (ctx->slot < 0) { | |
| 1481 | 1471 | dev_err(dev, "No more free slots\n"); |
| 1482 | 1472 | goto end; |
| 1483 | 1473 | } |
| 1484 | − if (!mxc_jpeg_alloc_slot_data(jpeg, ctx->slot)) { | |
| 1474 | + if (!mxc_jpeg_alloc_slot_data(jpeg)) { | |
| 1485 | 1475 | dev_err(dev, "Cannot allocate slot data\n"); |
| 1486 | 1476 | goto end; |
| 1487 | 1477 | } |
| @@ -2101,7 +2091,7 @@ static int mxc_jpeg_open(struct file *file) · 613 unmodified lines | ||
| 2101 | 2091 | } |
| 2102 | 2092 | ctx->fh.ctrl_handler = &ctx->ctrl_handler; |
| 2103 | 2093 | mxc_jpeg_set_default_params(ctx); |
| 2104 | − ctx->slot = MXC_MAX_SLOTS; /* slot not allocated yet */ | |
| 2094 | + ctx->slot = -1; /* slot not allocated yet */ | |
| 2105 | 2095 | INIT_DELAYED_WORK(&ctx->task_timer, mxc_jpeg_device_run_timeout); |
| 2106 | 2096 | |
| 2107 | 2097 | if (mxc_jpeg->mode == MXC_JPEG_DECODE) |
| @@ -2677,6 +2667,11 @@ static int mxc_jpeg_attach_pm_domains(struct mxc_jpeg_dev *jpeg) · 569 unmodified lines | ||
| 2677 | 2667 | dev_err(dev, "No power domains defined for jpeg node\n"); |
| 2678 | 2668 | return jpeg->num_domains; |
| 2679 | 2669 | } |
| 2670 | + if (jpeg->num_domains == 1) { | |
| 2671 | + /* genpd_dev_pm_attach() attach automatically if power domains count is 1 */ | |
| 2672 | + jpeg->num_domains = 0; | |
| 2673 | + return 0; | |
| 2674 | + } | |
| 2680 | 2675 | |
| 2681 | 2676 | jpeg->pd_dev = devm_kmalloc_array(dev, jpeg->num_domains, |
| 2682 | 2677 | sizeof(*jpeg->pd_dev), GFP_KERNEL); |
| @@ -2718,7 +2713,6 @@ static int mxc_jpeg_probe(struct platform_device *pdev) · 35 unmodified lines | ||
| 2718 | 2713 | int ret; |
| 2719 | 2714 | int mode; |
| 2720 | 2715 | const struct of_device_id *of_id; |
| 2721 | − unsigned int slot; | |
| 2722 | 2716 | |
| 2723 | 2717 | of_id = of_match_node(mxc_jpeg_match, dev->of_node); |
| 2724 | 2718 | if (!of_id) |
| @@ -2742,19 +2736,22 @@ static int mxc_jpeg_probe(struct platform_device *pdev) · 17 unmodified lines | ||
| 2742 | 2736 | if (IS_ERR(jpeg->base_reg)) |
| 2743 | 2737 | return PTR_ERR(jpeg->base_reg); |
| 2744 | 2738 | |
| 2745 | − for (slot = 0; slot < MXC_MAX_SLOTS; slot++) { | |
| 2746 | − dec_irq = platform_get_irq(pdev, slot); | |
| 2747 | − if (dec_irq < 0) { | |
| 2748 | − ret = dec_irq; | |
| 2749 | − goto err_irq; | |
| 2750 | − } | |
| 2751 | − ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq, | |
| 2752 | − 0, pdev->name, jpeg); | |
| 2753 | − if (ret) { | |
| 2754 | − dev_err(&pdev->dev, "Failed to request irq %d (%d)\n", | |
| 2755 | − dec_irq, ret); | |
| 2756 | − goto err_irq; | |
| 2757 | − } | |
| 2739 | + ret = of_property_read_u32_index(pdev->dev.of_node, "slot", 0, &jpeg->slot_data.slot); | |
| 2740 | + if (ret) | |
| 2741 | + jpeg->slot_data.slot = 0; | |
| 2742 | + dev_info(&pdev->dev, "choose slot %d\n", jpeg->slot_data.slot); | |
| 2743 | + dec_irq = platform_get_irq(pdev, 0); | |
| 2744 | + if (dec_irq < 0) { | |
| 2745 | + dev_err(&pdev->dev, "Failed to get irq %d\n", dec_irq); | |
| 2746 | + ret = dec_irq; | |
| 2747 | + goto err_irq; | |
| 2748 | + } | |
| 2749 | + ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq, | |
| 2750 | + 0, pdev->name, jpeg); | |
| 2751 | + if (ret) { | |
| 2752 | + dev_err(&pdev->dev, "Failed to request irq %d (%d)\n", | |
| 2753 | + dec_irq, ret); | |
| 2754 | + goto err_irq; | |
| 2758 | 2755 | } |
| 2759 | 2756 | |
| 2760 | 2757 | jpeg->pdev = pdev; |
| @@ -2914,11 +2911,9 @@ static const struct dev_pm_ops mxc_jpeg_pm_ops = { · 153 unmodified lines | ||
| 2914 | 2911 | |
| 2915 | 2912 | static void mxc_jpeg_remove(struct platform_device *pdev) |
| 2916 | 2913 | { |
| 2917 | − unsigned int slot; | |
| 2918 | 2914 | struct mxc_jpeg_dev *jpeg = platform_get_drvdata(pdev); |
| 2919 | 2915 | |
| 2920 | − for (slot = 0; slot < MXC_MAX_SLOTS; slot++) | |
| 2921 | − mxc_jpeg_free_slot_data(jpeg, slot); | |
| 2916 | + mxc_jpeg_free_slot_data(jpeg); | |
| 2922 | 2917 | |
| 2923 | 2918 | pm_runtime_disable(&pdev->dev); |
| 2924 | 2919 | video_unregister_device(jpeg->dec_vdev); |
| @@ -97,7 +97,7 @@ struct mxc_jpeg_ctx { · 96 unmodified lines | ||
| 97 | 97 | struct mxc_jpeg_q_data cap_q; |
| 98 | 98 | struct v4l2_fh fh; |
| 99 | 99 | enum mxc_jpeg_enc_state enc_state; |
| 100 | − unsigned int slot; | |
| 100 | + int slot; | |
| 101 | 101 | unsigned int source_change; |
| 102 | 102 | bool header_parsed; |
| 103 | 103 | struct v4l2_ctrl_handler ctrl_handler; |
| @@ -106,6 +106,7 @@ struct mxc_jpeg_ctx { · 2 unmodified lines | ||
| 106 | 106 | }; |
| 107 | 107 | |
| 108 | 108 | struct mxc_jpeg_slot_data { |
| 109 | + int slot; | |
| 109 | 110 | bool used; |
| 110 | 111 | struct mxc_jpeg_desc *desc; // enc/dec descriptor |
| 111 | 112 | struct mxc_jpeg_desc *cfg_desc; // configuration descriptor |
| @@ -128,7 +129,7 @@ struct mxc_jpeg_dev { · 16 unmodified lines | ||
| 128 | 129 | struct v4l2_device v4l2_dev; |
| 129 | 130 | struct v4l2_m2m_dev *m2m_dev; |
| 130 | 131 | struct video_device *dec_vdev; |
| 131 | − struct mxc_jpeg_slot_data slot_data[MXC_MAX_SLOTS]; | |
| 132 | + struct mxc_jpeg_slot_data slot_data; | |
| 132 | 133 | int num_domains; |
| 133 | 134 | struct device **pd_dev; |
| 134 | 135 | struct device_link **pd_link; |
| @@ -251,8 +251,8 @@ int pkt_session_unset_buffers(struct hfi_session_release_buffer_pkt *pkt, · 250 unmodified lines | ||
| 251 | 251 | |
| 252 | 252 | pkt->extradata_size = 0; |
| 253 | 253 | pkt->shdr.hdr.size = |
| 254 | − struct_size((struct hfi_session_set_buffers_pkt *)0, | |
| 255 | − buffer_info, bd->num_buffers); | |
| 254 | + struct_size_t(struct hfi_session_set_buffers_pkt, | |
| 255 | + buffer_info, bd->num_buffers); | |
| 256 | 256 | } |
| 257 | 257 | |
| 258 | 258 | pkt->response_req = bd->response_required; |
| @@ -370,26 +370,26 @@ extern int hantro_debug; · 369 unmodified lines | ||
| 370 | 370 | pr_err("%s:%d: " fmt, __func__, __LINE__, ##args) |
| 371 | 371 | |
| 372 | 372 | /* Structure access helpers. */ |
| 373 | −static inline struct hantro_ctx *fh_to_ctx(struct v4l2_fh *fh) | |
| 373 | +static __always_inline struct hantro_ctx *fh_to_ctx(struct v4l2_fh *fh) | |
| 374 | 374 | { |
| 375 | 375 | return container_of(fh, struct hantro_ctx, fh); |
| 376 | 376 | } |
| 377 | 377 | |
| 378 | 378 | /* Register accessors. */ |
| 379 | −static inline void vepu_write_relaxed(struct hantro_dev *vpu, | |
| 380 | − u32 val, u32 reg) | |
| 379 | +static __always_inline void vepu_write_relaxed(struct hantro_dev *vpu, | |
| 380 | + u32 val, u32 reg) | |
| 381 | 381 | { |
| 382 | 382 | vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val); |
| 383 | 383 | writel_relaxed(val, vpu->enc_base + reg); |
| 384 | 384 | } |
| 385 | 385 | |
| 386 | −static inline void vepu_write(struct hantro_dev *vpu, u32 val, u32 reg) | |
| 386 | +static __always_inline void vepu_write(struct hantro_dev *vpu, u32 val, u32 reg) | |
| 387 | 387 | { |
| 388 | 388 | vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val); |
| 389 | 389 | writel(val, vpu->enc_base + reg); |
| 390 | 390 | } |
| 391 | 391 | |
| 392 | −static inline u32 vepu_read(struct hantro_dev *vpu, u32 reg) | |
| 392 | +static __always_inline u32 vepu_read(struct hantro_dev *vpu, u32 reg) | |
| 393 | 393 | { |
| 394 | 394 | u32 val = readl(vpu->enc_base + reg); |
| 395 | 395 | |
| @@ -397,27 +397,27 @@ static inline u32 vepu_read(struct hantro_dev *vpu, u32 reg) · 1 unmodified line | ||
| 397 | 397 | return val; |
| 398 | 398 | } |
| 399 | 399 | |
| 400 | −static inline void vdpu_write_relaxed(struct hantro_dev *vpu, | |
| 401 | − u32 val, u32 reg) | |
| 400 | +static __always_inline void vdpu_write_relaxed(struct hantro_dev *vpu, | |
| 401 | + u32 val, u32 reg) | |
| 402 | 402 | { |
| 403 | 403 | vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val); |
| 404 | 404 | writel_relaxed(val, vpu->dec_base + reg); |
| 405 | 405 | } |
| 406 | 406 | |
| 407 | −static inline void vdpu_write(struct hantro_dev *vpu, u32 val, u32 reg) | |
| 407 | +static __always_inline void vdpu_write(struct hantro_dev *vpu, u32 val, u32 reg) | |
| 408 | 408 | { |
| 409 | 409 | vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val); |
| 410 | 410 | writel(val, vpu->dec_base + reg); |
| 411 | 411 | } |
| 412 | 412 | |
| 413 | −static inline void hantro_write_addr(struct hantro_dev *vpu, | |
| 414 | − unsigned long offset, | |
| 415 | − dma_addr_t addr) | |
| 413 | +static __always_inline void hantro_write_addr(struct hantro_dev *vpu, | |
| 414 | + unsigned long offset, | |
| 415 | + dma_addr_t addr) | |
| 416 | 416 | { |
| 417 | 417 | vdpu_write(vpu, addr & 0xffffffff, offset); |
| 418 | 418 | } |
| 419 | 419 | |
| 420 | −static inline u32 vdpu_read(struct hantro_dev *vpu, u32 reg) | |
| 420 | +static __always_inline u32 vdpu_read(struct hantro_dev *vpu, u32 reg) | |
| 421 | 421 | { |
| 422 | 422 | u32 val = readl(vpu->dec_base + reg); |
| 423 | 423 | |
| @@ -425,9 +425,9 @@ static inline u32 vdpu_read(struct hantro_dev *vpu, u32 reg) · 1 unmodified line | ||
| 425 | 425 | return val; |
| 426 | 426 | } |
| 427 | 427 | |
| 428 | −static inline u32 vdpu_read_mask(struct hantro_dev *vpu, | |
| 429 | − const struct hantro_reg *reg, | |
| 430 | − u32 val) | |
| 428 | +static __always_inline u32 vdpu_read_mask(struct hantro_dev *vpu, | |
| 429 | + const struct hantro_reg *reg, | |
| 430 | + u32 val) | |
| 431 | 431 | { |
| 432 | 432 | u32 v; |
| 433 | 433 | |
| @@ -437,18 +437,18 @@ static inline u32 vdpu_read_mask(struct hantro_dev *vpu, · 3 unmodified lines | ||
| 437 | 437 | return v; |
| 438 | 438 | } |
| 439 | 439 | |
| 440 | −static inline void hantro_reg_write(struct hantro_dev *vpu, | |
| 441 | − const struct hantro_reg *reg, | |
| 442 | − u32 val) | |
| 440 | +static __always_inline void hantro_reg_write(struct hantro_dev *vpu, | |
| 441 | + const struct hantro_reg *reg, | |
| 442 | + u32 val) | |
| 443 | 443 | { |
| 444 | − vdpu_write_relaxed(vpu, vdpu_read_mask(vpu, reg, val), reg->base); | |
| 444 | + vdpu_write(vpu, vdpu_read_mask(vpu, reg, val), reg->base); | |
| 445 | 445 | } |
| 446 | 446 | |
| 447 | −static inline void hantro_reg_write_s(struct hantro_dev *vpu, | |
| 448 | − const struct hantro_reg *reg, | |
| 449 | − u32 val) | |
| 447 | +static __always_inline void hantro_reg_write_relaxed(struct hantro_dev *vpu, | |
| 448 | + const struct hantro_reg *reg, | |
| 449 | + u32 val) | |
| 450 | 450 | { |
| 451 | − vdpu_write(vpu, vdpu_read_mask(vpu, reg, val), reg->base); | |
| 451 | + vdpu_write_relaxed(vpu, vdpu_read_mask(vpu, reg, val), reg->base); | |
| 452 | 452 | } |
| 453 | 453 | |
| 454 | 454 | void *hantro_get_ctrl(struct hantro_ctx *ctx, u32 id); |
| @@ -21,11 +21,11 @@ · 20 unmodified lines | ||
| 21 | 21 | val); \ |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | −#define HANTRO_PP_REG_WRITE_S(vpu, reg_name, val) \ | |
| 24 | +#define HANTRO_PP_REG_WRITE_RELAXED(vpu, reg_name, val) \ | |
| 25 | 25 | { \ |
| 26 | − hantro_reg_write_s(vpu, \ | |
| 27 | − &hantro_g1_postproc_regs.reg_name, \ | |
| 28 | − val); \ | |
| 26 | + hantro_reg_write_relaxed(vpu, \ | |
| 27 | + &hantro_g1_postproc_regs.reg_name, \ | |
| 28 | + val); \ | |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | 31 | #define VPU_PP_IN_YUYV 0x0 |
| @@ -72,7 +72,7 @@ static void hantro_postproc_g1_enable(struct hantro_ctx *ctx) · 40 unmodified lines | ||
| 72 | 72 | dma_addr_t dst_dma; |
| 73 | 73 | |
| 74 | 74 | /* Turn on pipeline mode. Must be done first. */ |
| 75 | − HANTRO_PP_REG_WRITE_S(vpu, pipeline_en, 0x1); | |
| 75 | + HANTRO_PP_REG_WRITE(vpu, pipeline_en, 0x1); | |
| 76 | 76 | |
| 77 | 77 | src_pp_fmt = VPU_PP_IN_NV12; |
| 78 | 78 | |
| @@ -242,7 +242,7 @@ static void hantro_postproc_g1_disable(struct hantro_ctx *ctx) · 163 unmodified lines | ||
| 242 | 242 | { |
| 243 | 243 | struct hantro_dev *vpu = ctx->dev; |
| 244 | 244 | |
| 245 | − HANTRO_PP_REG_WRITE_S(vpu, pipeline_en, 0x0); | |
| 245 | + HANTRO_PP_REG_WRITE(vpu, pipeline_en, 0x0); | |
| 246 | 246 | } |
| 247 | 247 | |
| 248 | 248 | static void hantro_postproc_g2_disable(struct hantro_ctx *ctx) |
| @@ -755,6 +755,43 @@ const char *const tegra_mc_error_names[8] = { · 754 unmodified lines | ||
| 755 | 755 | [6] = "SMMU translation error", |
| 756 | 756 | }; |
| 757 | 757 | |
| 758 | +struct icc_node *tegra_mc_icc_xlate(struct of_phandle_args *spec, void *data) | |
| 759 | +{ | |
| 760 | + struct tegra_mc *mc = icc_provider_to_tegra_mc(data); | |
| 761 | + struct icc_node *node; | |
| 762 | + | |
| 763 | + list_for_each_entry(node, &mc->provider.nodes, node_list) { | |
| 764 | + if (node->id == spec->args[0]) | |
| 765 | + return node; | |
| 766 | + } | |
| 767 | + | |
| 768 | + /* | |
| 769 | + * If a client driver calls devm_of_icc_get() before the MC driver | |
| 770 | + * is probed, then return EPROBE_DEFER to the client driver. | |
| 771 | + */ | |
| 772 | + return ERR_PTR(-EPROBE_DEFER); | |
| 773 | +} | |
| 774 | + | |
| 775 | +static int tegra_mc_icc_get(struct icc_node *node, u32 *average, u32 *peak) | |
| 776 | +{ | |
| 777 | + *average = 0; | |
| 778 | + *peak = 0; | |
| 779 | + | |
| 780 | + return 0; | |
| 781 | +} | |
| 782 | + | |
| 783 | +static int tegra_mc_icc_set(struct icc_node *src, struct icc_node *dst) | |
| 784 | +{ | |
| 785 | + return 0; | |
| 786 | +} | |
| 787 | + | |
| 788 | +const struct tegra_mc_icc_ops tegra_mc_icc_ops = { | |
| 789 | + .xlate = tegra_mc_icc_xlate, | |
| 790 | + .aggregate = icc_std_aggregate, | |
| 791 | + .get_bw = tegra_mc_icc_get, | |
| 792 | + .set = tegra_mc_icc_set, | |
| 793 | +}; | |
| 794 | + | |
| 758 | 795 | /* |
| 759 | 796 | * Memory Controller (MC) has few Memory Clients that are issuing memory |
| 760 | 797 | * bandwidth allocation requests to the MC interconnect provider. The MC |
| @@ -1355,6 +1355,7 @@ const struct tegra_mc_soc tegra194_mc_soc = { · 1354 unmodified lines | ||
| 1355 | 1355 | MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM, |
| 1356 | 1356 | .has_addr_hi_reg = true, |
| 1357 | 1357 | .ops = &tegra186_mc_ops, |
| 1358 | + .icc_ops = &tegra_mc_icc_ops, | |
| 1358 | 1359 | .ch_intmask = 0x00000f00, |
| 1359 | 1360 | .global_intstatus_channel_shift = 8, |
| 1360 | 1361 | }; |
| @@ -827,7 +827,7 @@ static int tegra234_mc_icc_set(struct icc_node *src, struct icc_node *dst) · 826 unmodified lines | ||
| 827 | 827 | return 0; |
| 828 | 828 | |
| 829 | 829 | if (!mc->bwmgr_mrq_supported) |
| 830 | − return -EINVAL; | |
| 830 | + return 0; | |
| 831 | 831 | |
| 832 | 832 | if (!mc->bpmp) { |
| 833 | 833 | dev_err(mc->dev, "BPMP reference NULL\n"); |
| @@ -874,7 +874,7 @@ static int tegra234_mc_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, · 40 unmodified lines | ||
| 874 | 874 | struct tegra_mc *mc = icc_provider_to_tegra_mc(p); |
| 875 | 875 | |
| 876 | 876 | if (!mc->bwmgr_mrq_supported) |
| 877 | − return -EINVAL; | |
| 877 | + return 0; | |
| 878 | 878 | |
| 879 | 879 | if (node->id == TEGRA_ICC_MC_CPU_CLUSTER0 || |
| 880 | 880 | node->id == TEGRA_ICC_MC_CPU_CLUSTER1 || |
| @@ -889,27 +889,6 @@ static int tegra234_mc_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, · 8 unmodified lines | ||
| 889 | 889 | return 0; |
| 890 | 890 | } |
| 891 | 891 | |
| 892 | −static struct icc_node* | |
| 893 | −tegra234_mc_of_icc_xlate(struct of_phandle_args *spec, void *data) | |
| 894 | −{ | |
| 895 | − struct tegra_mc *mc = icc_provider_to_tegra_mc(data); | |
| 896 | − unsigned int cl_id = spec->args[0]; | |
| 897 | − struct icc_node *node; | |
| 898 | − | |
| 899 | − list_for_each_entry(node, &mc->provider.nodes, node_list) { | |
| 900 | − if (node->id != cl_id) | |
| 901 | − continue; | |
| 902 | − | |
| 903 | − return node; | |
| 904 | − } | |
| 905 | − | |
| 906 | − /* | |
| 907 | − * If a client driver calls devm_of_icc_get() before the MC driver | |
| 908 | − * is probed, then return EPROBE_DEFER to the client driver. | |
| 909 | − */ | |
| 910 | − return ERR_PTR(-EPROBE_DEFER); | |
| 911 | −} | |
| 912 | − | |
| 913 | 892 | static int tegra234_mc_icc_get_init_bw(struct icc_node *node, u32 *avg, u32 *peak) |
| 914 | 893 | { |
| 915 | 894 | *avg = 0; |
| @@ -919,7 +898,7 @@ static int tegra234_mc_icc_get_init_bw(struct icc_node *node, u32 *avg, u32 *pea · 3 unmodified lines | ||
| 919 | 898 | } |
| 920 | 899 | |
| 921 | 900 | static const struct tegra_mc_icc_ops tegra234_mc_icc_ops = { |
| 922 | − .xlate = tegra234_mc_of_icc_xlate, | |
| 901 | + .xlate = tegra_mc_icc_xlate, | |
| 923 | 902 | .aggregate = tegra234_mc_icc_aggregate, |
| 924 | 903 | .get_bw = tegra234_mc_icc_get_init_bw, |
| 925 | 904 | .set = tegra234_mc_icc_set, |
| @@ -195,7 +195,7 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) · 194 unmodified lines | ||
| 195 | 195 | } |
| 196 | 196 | } |
| 197 | 197 | |
| 198 | − if (option->force_clkreq_0) | |
| 198 | + if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG) | |
| 199 | 199 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, |
| 200 | 200 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); |
| 201 | 201 | else |
| @@ -435,17 +435,10 @@ static void rts5228_init_from_cfg(struct rtsx_pcr *pcr) · 434 unmodified lines | ||
| 435 | 435 | option->ltr_enabled = false; |
| 436 | 436 | } |
| 437 | 437 | } |
| 438 | − | |
| 439 | − if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN | |
| 440 | − | PM_L1_1_EN | PM_L1_2_EN)) | |
| 441 | − option->force_clkreq_0 = false; | |
| 442 | − else | |
| 443 | − option->force_clkreq_0 = true; | |
| 444 | 438 | } |
| 445 | 439 | |
| 446 | 440 | static int rts5228_extra_init_hw(struct rtsx_pcr *pcr) |
| 447 | 441 | { |
| 448 | − struct rtsx_cr_option *option = &pcr->option; | |
| 449 | 442 | |
| 450 | 443 | rtsx_pci_write_register(pcr, RTS5228_AUTOLOAD_CFG1, |
| 451 | 444 | CD_RESUME_EN_MASK, CD_RESUME_EN_MASK); |
| @@ -476,17 +469,6 @@ static int rts5228_extra_init_hw(struct rtsx_pcr *pcr) · 24 unmodified lines | ||
| 476 | 469 | else |
| 477 | 470 | rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); |
| 478 | 471 | |
| 479 | − /* | |
| 480 | − * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced | |
| 481 | − * to drive low, and we forcibly request clock. | |
| 482 | − */ | |
| 483 | − if (option->force_clkreq_0) | |
| 484 | − rtsx_pci_write_register(pcr, PETXCFG, | |
| 485 | − FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); | |
| 486 | − else | |
| 487 | − rtsx_pci_write_register(pcr, PETXCFG, | |
| 488 | − FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); | |
| 489 | − | |
| 490 | 472 | rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); |
| 491 | 473 | |
| 492 | 474 | if (pcr->rtd3_en) { |
| @@ -327,12 +327,11 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr) · 326 unmodified lines | ||
| 327 | 327 | } |
| 328 | 328 | } |
| 329 | 329 | |
| 330 | − | |
| 331 | 330 | /* |
| 332 | 331 | * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced |
| 333 | 332 | * to drive low, and we forcibly request clock. |
| 334 | 333 | */ |
| 335 | − if (option->force_clkreq_0) | |
| 334 | + if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG) | |
| 336 | 335 | rtsx_pci_write_register(pcr, PETXCFG, |
| 337 | 336 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); |
| 338 | 337 | else |
| @@ -517,17 +517,10 @@ static void rts5260_init_from_cfg(struct rtsx_pcr *pcr) · 516 unmodified lines | ||
| 517 | 517 | option->ltr_enabled = false; |
| 518 | 518 | } |
| 519 | 519 | } |
| 520 | − | |
| 521 | − if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN | |
| 522 | − | PM_L1_1_EN | PM_L1_2_EN)) | |
| 523 | − option->force_clkreq_0 = false; | |
| 524 | − else | |
| 525 | − option->force_clkreq_0 = true; | |
| 526 | 520 | } |
| 527 | 521 | |
| 528 | 522 | static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) |
| 529 | 523 | { |
| 530 | − struct rtsx_cr_option *option = &pcr->option; | |
| 531 | 524 | |
| 532 | 525 | /* Set mcu_cnt to 7 to ensure data can be sampled properly */ |
| 533 | 526 | rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07); |
| @@ -546,17 +539,6 @@ static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) · 12 unmodified lines | ||
| 546 | 539 | |
| 547 | 540 | rts5260_init_hw(pcr); |
| 548 | 541 | |
| 549 | − /* | |
| 550 | − * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced | |
| 551 | − * to drive low, and we forcibly request clock. | |
| 552 | − */ | |
| 553 | − if (option->force_clkreq_0) | |
| 554 | − rtsx_pci_write_register(pcr, PETXCFG, | |
| 555 | − FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); | |
| 556 | − else | |
| 557 | − rtsx_pci_write_register(pcr, PETXCFG, | |
| 558 | − FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); | |
| 559 | − | |
| 560 | 542 | rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00); |
| 561 | 543 | |
| 562 | 544 | return 0; |
| @@ -498,17 +498,10 @@ static void rts5261_init_from_cfg(struct rtsx_pcr *pcr) · 497 unmodified lines | ||
| 498 | 498 | option->ltr_enabled = false; |
| 499 | 499 | } |
| 500 | 500 | } |
| 501 | − | |
| 502 | − if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN | |
| 503 | − | PM_L1_1_EN | PM_L1_2_EN)) | |
| 504 | − option->force_clkreq_0 = false; | |
| 505 | − else | |
| 506 | − option->force_clkreq_0 = true; | |
| 507 | 501 | } |
| 508 | 502 | |
| 509 | 503 | static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) |
| 510 | 504 | { |
| 511 | − struct rtsx_cr_option *option = &pcr->option; | |
| 512 | 505 | u32 val; |
| 513 | 506 | |
| 514 | 507 | rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG1, |
| @@ -554,17 +547,6 @@ static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) · 39 unmodified lines | ||
| 554 | 547 | else |
| 555 | 548 | rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); |
| 556 | 549 | |
| 557 | − /* | |
| 558 | − * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced | |
| 559 | − * to drive low, and we forcibly request clock. | |
| 560 | − */ | |
| 561 | − if (option->force_clkreq_0) | |
| 562 | − rtsx_pci_write_register(pcr, PETXCFG, | |
| 563 | − FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); | |
| 564 | − else | |
| 565 | − rtsx_pci_write_register(pcr, PETXCFG, | |
| 566 | − FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); | |
| 567 | − | |
| 568 | 550 | rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); |
| 569 | 551 | |
| 570 | 552 | if (pcr->rtd3_en) { |
| @@ -1326,8 +1326,11 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) · 1325 unmodified lines | ||
| 1326 | 1326 | return err; |
| 1327 | 1327 | } |
| 1328 | 1328 | |
| 1329 | − if (pcr->aspm_mode == ASPM_MODE_REG) | |
| 1329 | + if (pcr->aspm_mode == ASPM_MODE_REG) { | |
| 1330 | 1330 | rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0x30, 0x30); |
| 1331 | + rtsx_pci_write_register(pcr, PETXCFG, | |
| 1332 | + FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); | |
| 1333 | + } | |
| 1331 | 1334 | |
| 1332 | 1335 | /* No CD interrupt if probing driver with card inserted. |
| 1333 | 1336 | * So we need to initialize pcr->card_exist here. |
| @@ -236,7 +236,7 @@ static int sram_reserve_regions(struct sram_dev *sram, struct resource *res) · 235 unmodified lines | ||
| 236 | 236 | } |
| 237 | 237 | if (!label) |
| 238 | 238 | block->label = devm_kasprintf(sram->dev, GFP_KERNEL, |
| 239 | − "%s", dev_name(sram->dev)); | |
| 239 | + "%s", of_node_full_name(child)); | |
| 240 | 240 | else |
| 241 | 241 | block->label = devm_kstrdup(sram->dev, |
| 242 | 242 | label, GFP_KERNEL); |
| @@ -13,6 +13,8 @@ · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | #include <linux/mfd/tps6594.h> |
| 15 | 15 | |
| 16 | +#define TPS6594_DEV_REV_1 0x08 | |
| 17 | + | |
| 16 | 18 | static irqreturn_t tps6594_esm_isr(int irq, void *dev_id) |
| 17 | 19 | { |
| 18 | 20 | struct platform_device *pdev = dev_id; |
| @@ -32,11 +34,26 @@ static int tps6594_esm_probe(struct platform_device *pdev) · 13 unmodified lines | ||
| 32 | 34 | { |
| 33 | 35 | struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent); |
| 34 | 36 | struct device *dev = &pdev->dev; |
| 37 | + unsigned int rev; | |
| 35 | 38 | int irq; |
| 36 | 39 | int ret; |
| 37 | 40 | int i; |
| 38 | 41 | |
| 39 | − for (i = 0 ; i < pdev->num_resources ; i++) { | |
| 42 | + /* | |
| 43 | + * Due to a bug in revision 1 of the PMIC, the GPIO3 used for the | |
| 44 | + * SoC ESM function is used to power the load switch instead. | |
| 45 | + * As a consequence, ESM can not be used on those PMIC. | |
| 46 | + * Check the version and return an error in case of revision 1. | |
| 47 | + */ | |
| 48 | + ret = regmap_read(tps->regmap, TPS6594_REG_DEV_REV, &rev); | |
| 49 | + if (ret) | |
| 50 | + return dev_err_probe(dev, ret, | |
| 51 | + "Failed to read PMIC revision\n"); | |
| 52 | + if (rev == TPS6594_DEV_REV_1) | |
| 53 | + return dev_err_probe(dev, -ENODEV, | |
| 54 | + "ESM not supported for revision 1 PMIC\n"); | |
| 55 | + | |
| 56 | + for (i = 0; i < pdev->num_resources; i++) { | |
| 40 | 57 | irq = platform_get_irq_byname(pdev, pdev->resource[i].name); |
| 41 | 58 | if (irq < 0) |
| 42 | 59 | return dev_err_probe(dev, irq, "Failed to get %s irq\n", |
| @@ -338,13 +338,7 @@ static void moxart_transfer_pio(struct moxart_host *host) · 337 unmodified lines | ||
| 338 | 338 | return; |
| 339 | 339 | } |
| 340 | 340 | for (len = 0; len < remain && len < host->fifo_width;) { |
| 341 | − /* SCR data must be read in big endian. */ | |
| 342 | − if (data->mrq->cmd->opcode == SD_APP_SEND_SCR) | |
| 343 | − *sgp = ioread32be(host->base + | |
| 344 | − REG_DATA_WINDOW); | |
| 345 | − else | |
| 346 | − *sgp = ioread32(host->base + | |
| 347 | − REG_DATA_WINDOW); | |
| 341 | + *sgp = ioread32(host->base + REG_DATA_WINDOW); | |
| 348 | 342 | sgp++; |
| 349 | 343 | len += 4; |
| 350 | 344 | } |
| @@ -29,9 +29,16 @@ struct f_sdhost_priv { · 28 unmodified lines | ||
| 29 | 29 | bool enable_cmd_dat_delay; |
| 30 | 30 | }; |
| 31 | 31 | |
| 32 | +static void *sdhci_f_sdhost_priv(struct sdhci_host *host) | |
| 33 | +{ | |
| 34 | + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
| 35 | + | |
| 36 | + return sdhci_pltfm_priv(pltfm_host); | |
| 37 | +} | |
| 38 | + | |
| 32 | 39 | static void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host) |
| 33 | 40 | { |
| 34 | − struct f_sdhost_priv *priv = sdhci_priv(host); | |
| 41 | + struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host); | |
| 35 | 42 | u32 ctrl = 0; |
| 36 | 43 | |
| 37 | 44 | usleep_range(2500, 3000); |
| @@ -64,7 +71,7 @@ static unsigned int sdhci_f_sdh30_get_min_clock(struct sdhci_host *host) · 26 unmodified lines | ||
| 64 | 71 | |
| 65 | 72 | static void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask) |
| 66 | 73 | { |
| 67 | − struct f_sdhost_priv *priv = sdhci_priv(host); | |
| 74 | + struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host); | |
| 68 | 75 | u32 ctl; |
| 69 | 76 | |
| 70 | 77 | if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0) |
| @@ -95,30 +102,32 @@ static const struct sdhci_ops sdhci_f_sdh30_ops = { · 24 unmodified lines | ||
| 95 | 102 | .set_uhs_signaling = sdhci_set_uhs_signaling, |
| 96 | 103 | }; |
| 97 | 104 | |
| 105 | +static const struct sdhci_pltfm_data sdhci_f_sdh30_pltfm_data = { | |
| 106 | + .ops = &sdhci_f_sdh30_ops, | |
| 107 | + .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | |
| 108 | + | SDHCI_QUIRK_INVERTED_WRITE_PROTECT, | |
| 109 | + .quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE | |
| 110 | + | SDHCI_QUIRK2_TUNING_WORK_AROUND, | |
| 111 | +}; | |
| 112 | + | |
| 98 | 113 | static int sdhci_f_sdh30_probe(struct platform_device *pdev) |
| 99 | 114 | { |
| 100 | 115 | struct sdhci_host *host; |
| 101 | 116 | struct device *dev = &pdev->dev; |
| 102 | − int irq, ctrl = 0, ret = 0; | |
| 117 | + int ctrl = 0, ret = 0; | |
| 103 | 118 | struct f_sdhost_priv *priv; |
| 119 | + struct sdhci_pltfm_host *pltfm_host; | |
| 104 | 120 | u32 reg = 0; |
| 105 | 121 | |
| 106 | − irq = platform_get_irq(pdev, 0); | |
| 107 | − if (irq < 0) | |
| 108 | − return irq; | |
| 109 | − | |
| 110 | − host = sdhci_alloc_host(dev, sizeof(struct f_sdhost_priv)); | |
| 122 | + host = sdhci_pltfm_init(pdev, &sdhci_f_sdh30_pltfm_data, | |
| 123 | + sizeof(struct f_sdhost_priv)); | |
| 111 | 124 | if (IS_ERR(host)) |
| 112 | 125 | return PTR_ERR(host); |
| 113 | 126 | |
| 114 | − priv = sdhci_priv(host); | |
| 127 | + pltfm_host = sdhci_priv(host); | |
| 128 | + priv = sdhci_pltfm_priv(pltfm_host); | |
| 115 | 129 | priv->dev = dev; |
| 116 | 130 | |
| 117 | − host->quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | | |
| 118 | − SDHCI_QUIRK_INVERTED_WRITE_PROTECT; | |
| 119 | − host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE | | |
| 120 | − SDHCI_QUIRK2_TUNING_WORK_AROUND; | |
| 121 | − | |
| 122 | 131 | priv->enable_cmd_dat_delay = device_property_read_bool(dev, |
| 123 | 132 | "fujitsu,cmd-dat-delay-select"); |
| 124 | 133 | |
| @@ -126,18 +135,6 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 126 | 135 | if (ret) |
| 127 | 136 | goto err; |
| 128 | 137 | |
| 129 | − platform_set_drvdata(pdev, host); | |
| 130 | − | |
| 131 | − host->hw_name = "f_sdh30"; | |
| 132 | − host->ops = &sdhci_f_sdh30_ops; | |
| 133 | − host->irq = irq; | |
| 134 | − | |
| 135 | − host->ioaddr = devm_platform_ioremap_resource(pdev, 0); | |
| 136 | − if (IS_ERR(host->ioaddr)) { | |
| 137 | − ret = PTR_ERR(host->ioaddr); | |
| 138 | − goto err; | |
| 139 | − } | |
| 140 | − | |
| 141 | 138 | if (dev_of_node(dev)) { |
| 142 | 139 | sdhci_get_of_property(pdev); |
| 143 | 140 | |
| @@ -204,24 +201,21 @@ err_rst: · 60 unmodified lines | ||
| 204 | 201 | err_clk: |
| 205 | 202 | clk_disable_unprepare(priv->clk_iface); |
| 206 | 203 | err: |
| 207 | − sdhci_free_host(host); | |
| 204 | + sdhci_pltfm_free(pdev); | |
| 205 | + | |
| 208 | 206 | return ret; |
| 209 | 207 | } |
| 210 | 208 | |
| 211 | 209 | static int sdhci_f_sdh30_remove(struct platform_device *pdev) |
| 212 | 210 | { |
| 213 | 211 | struct sdhci_host *host = platform_get_drvdata(pdev); |
| 214 | − struct f_sdhost_priv *priv = sdhci_priv(host); | |
| 215 | − | |
| 216 | − sdhci_remove_host(host, readl(host->ioaddr + SDHCI_INT_STATUS) == | |
| 217 | − 0xffffffff); | |
| 212 | + struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host); | |
| 218 | 213 | |
| 219 | 214 | reset_control_assert(priv->rst); |
| 220 | 215 | clk_disable_unprepare(priv->clk); |
| 221 | 216 | clk_disable_unprepare(priv->clk_iface); |
| 222 | 217 | |
| 223 | − sdhci_free_host(host); | |
| 224 | − platform_set_drvdata(pdev, NULL); | |
| 218 | + sdhci_pltfm_unregister(pdev); | |
| 225 | 219 | |
| 226 | 220 | return 0; |
| 227 | 221 | } |
| @@ -135,7 +135,7 @@ static int fun_exec_op(struct nand_chip *chip, const struct nand_operation *op, · 134 unmodified lines | ||
| 135 | 135 | unsigned int i; |
| 136 | 136 | int ret; |
| 137 | 137 | |
| 138 | − if (op->cs > NAND_MAX_CHIPS) | |
| 138 | + if (op->cs >= NAND_MAX_CHIPS) | |
| 139 | 139 | return -EINVAL; |
| 140 | 140 | |
| 141 | 141 | if (check_only) |
| @@ -1278,7 +1278,6 @@ static int meson_nand_attach_chip(struct nand_chip *nand) · 1277 unmodified lines | ||
| 1278 | 1278 | struct meson_nfc *nfc = nand_get_controller_data(nand); |
| 1279 | 1279 | struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); |
| 1280 | 1280 | struct mtd_info *mtd = nand_to_mtd(nand); |
| 1281 | − int nsectors = mtd->writesize / 1024; | |
| 1282 | 1281 | int raw_writesize; |
| 1283 | 1282 | int ret; |
| 1284 | 1283 | |
| @@ -1304,7 +1303,7 @@ static int meson_nand_attach_chip(struct nand_chip *nand) · 19 unmodified lines | ||
| 1304 | 1303 | nand->options |= NAND_NO_SUBPAGE_WRITE; |
| 1305 | 1304 | |
| 1306 | 1305 | ret = nand_ecc_choose_conf(nand, nfc->data->ecc_caps, |
| 1307 | − mtd->oobsize - 2 * nsectors); | |
| 1306 | + mtd->oobsize - 2); | |
| 1308 | 1307 | if (ret) { |
| 1309 | 1308 | dev_err(nfc->dev, "failed to ECC init\n"); |
| 1310 | 1309 | return -EINVAL; |
| @@ -177,17 +177,17 @@ static void elm_load_syndrome(struct elm_info *info, · 176 unmodified lines | ||
| 177 | 177 | switch (info->bch_type) { |
| 178 | 178 | case BCH8_ECC: |
| 179 | 179 | /* syndrome fragment 0 = ecc[9-12B] */ |
| 180 | − val = cpu_to_be32(*(u32 *) &ecc[9]); | |
| 180 | + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[9]); | |
| 181 | 181 | elm_write_reg(info, offset, val); |
| 182 | 182 | |
| 183 | 183 | /* syndrome fragment 1 = ecc[5-8B] */ |
| 184 | 184 | offset += 4; |
| 185 | − val = cpu_to_be32(*(u32 *) &ecc[5]); | |
| 185 | + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[5]); | |
| 186 | 186 | elm_write_reg(info, offset, val); |
| 187 | 187 | |
| 188 | 188 | /* syndrome fragment 2 = ecc[1-4B] */ |
| 189 | 189 | offset += 4; |
| 190 | − val = cpu_to_be32(*(u32 *) &ecc[1]); | |
| 190 | + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[1]); | |
| 191 | 191 | elm_write_reg(info, offset, val); |
| 192 | 192 | |
| 193 | 193 | /* syndrome fragment 3 = ecc[0B] */ |
| @@ -197,35 +197,35 @@ static void elm_load_syndrome(struct elm_info *info, · 3 unmodified lines | ||
| 197 | 197 | break; |
| 198 | 198 | case BCH4_ECC: |
| 199 | 199 | /* syndrome fragment 0 = ecc[20-52b] bits */ |
| 200 | − val = (cpu_to_be32(*(u32 *) &ecc[3]) >> 4) | | |
| 200 | + val = ((__force u32)cpu_to_be32(*(u32 *)&ecc[3]) >> 4) | | |
| 201 | 201 | ((ecc[2] & 0xf) << 28); |
| 202 | 202 | elm_write_reg(info, offset, val); |
| 203 | 203 | |
| 204 | 204 | /* syndrome fragment 1 = ecc[0-20b] bits */ |
| 205 | 205 | offset += 4; |
| 206 | − val = cpu_to_be32(*(u32 *) &ecc[0]) >> 12; | |
| 206 | + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[0]) >> 12; | |
| 207 | 207 | elm_write_reg(info, offset, val); |
| 208 | 208 | break; |
| 209 | 209 | case BCH16_ECC: |
| 210 | − val = cpu_to_be32(*(u32 *) &ecc[22]); | |
| 210 | + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[22]); | |
| 211 | 211 | elm_write_reg(info, offset, val); |
| 212 | 212 | offset += 4; |
| 213 | − val = cpu_to_be32(*(u32 *) &ecc[18]); | |
| 213 | + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[18]); | |
| 214 | 214 | elm_write_reg(info, offset, val); |
| 215 | 215 | offset += 4; |
| 216 | − val = cpu_to_be32(*(u32 *) &ecc[14]); | |
| 216 | + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[14]); | |
| 217 | 217 | elm_write_reg(info, offset, val); |
| 218 | 218 | offset += 4; |
| 219 | − val = cpu_to_be32(*(u32 *) &ecc[10]); | |
| 219 | + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[10]); | |
| 220 | 220 | elm_write_reg(info, offset, val); |
| 221 | 221 | offset += 4; |
| 222 | − val = cpu_to_be32(*(u32 *) &ecc[6]); | |
| 222 | + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[6]); | |
| 223 | 223 | elm_write_reg(info, offset, val); |
| 224 | 224 | offset += 4; |
| 225 | − val = cpu_to_be32(*(u32 *) &ecc[2]); | |
| 225 | + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[2]); | |
| 226 | 226 | elm_write_reg(info, offset, val); |
| 227 | 227 | offset += 4; |
| 228 | − val = cpu_to_be32(*(u32 *) &ecc[0]) >> 16; | |
| 228 | + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[0]) >> 16; | |
| 229 | 229 | elm_write_reg(info, offset, val); |
| 230 | 230 | break; |
| 231 | 231 | default: |
| @@ -562,9 +562,10 @@ static int rk_nfc_write_page_raw(struct nand_chip *chip, const u8 *buf, · 561 unmodified lines | ||
| 562 | 562 | * BBM OOB1 OOB2 OOB3 |......| PA0 PA1 PA2 PA3 |
| 563 | 563 | * |
| 564 | 564 | * The rk_nfc_ooblayout_free() function already has reserved |
| 565 | − * these 4 bytes with: | |
| 565 | + * these 4 bytes together with 2 bytes for BBM | |
| 566 | + * by reducing it's length: | |
| 566 | 567 | * |
| 567 | − * oob_region->offset = NFC_SYS_DATA_SIZE + 2; | |
| 568 | + * oob_region->length = rknand->metadata_size - NFC_SYS_DATA_SIZE - 2; | |
| 568 | 569 | */ |
| 569 | 570 | if (!i) |
| 570 | 571 | memcpy(rk_nfc_oob_ptr(chip, i), |
| @@ -597,7 +598,7 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf, · 26 unmodified lines | ||
| 597 | 598 | int pages_per_blk = mtd->erasesize / mtd->writesize; |
| 598 | 599 | int ret = 0, i, boot_rom_mode = 0; |
| 599 | 600 | dma_addr_t dma_data, dma_oob; |
| 600 | − u32 reg; | |
| 601 | + u32 tmp; | |
| 601 | 602 | u8 *oob; |
| 602 | 603 | |
| 603 | 604 | nand_prog_page_begin_op(chip, page, 0, NULL, 0); |
| @@ -624,6 +625,13 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf, · 20 unmodified lines | ||
| 624 | 625 | * |
| 625 | 626 | * 0xFF 0xFF 0xFF 0xFF | BBM OOB1 OOB2 OOB3 | ... |
| 626 | 627 | * |
| 628 | + * The code here just swaps the first 4 bytes with the last | |
| 629 | + * 4 bytes without losing any data. | |
| 630 | + * | |
| 631 | + * The chip->oob_poi data layout: | |
| 632 | + * | |
| 633 | + * BBM OOB1 OOB2 OOB3 |......| PA0 PA1 PA2 PA3 | |
| 634 | + * | |
| 627 | 635 | * Configure the ECC algorithm supported by the boot ROM. |
| 628 | 636 | */ |
| 629 | 637 | if ((page < (pages_per_blk * rknand->boot_blks)) && |
| @@ -634,21 +642,17 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf, · 4 unmodified lines | ||
| 634 | 642 | } |
| 635 | 643 | |
| 636 | 644 | for (i = 0; i < ecc->steps; i++) { |
| 637 | − if (!i) { | |
| 638 | − reg = 0xFFFFFFFF; | |
| 639 | − } else { | |
| 645 | + if (!i) | |
| 646 | + oob = chip->oob_poi + (ecc->steps - 1) * NFC_SYS_DATA_SIZE; | |
| 647 | + else | |
| 640 | 648 | oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE; |
| 641 | − reg = oob[0] | oob[1] << 8 | oob[2] << 16 | | |
| 642 | − oob[3] << 24; | |
| 643 | − } | |
| 644 | 649 | |
| 645 | − if (!i && boot_rom_mode) | |
| 646 | − reg = (page & (pages_per_blk - 1)) * 4; | |
| 650 | + tmp = oob[0] | oob[1] << 8 | oob[2] << 16 | oob[3] << 24; | |
| 647 | 651 | |
| 648 | 652 | if (nfc->cfg->type == NFC_V9) |
| 649 | − nfc->oob_buf[i] = reg; | |
| 653 | + nfc->oob_buf[i] = tmp; | |
| 650 | 654 | else |
| 651 | − nfc->oob_buf[i * (oob_step / 4)] = reg; | |
| 655 | + nfc->oob_buf[i * (oob_step / 4)] = tmp; | |
| 652 | 656 | } |
| 653 | 657 | |
| 654 | 658 | dma_data = dma_map_single(nfc->dev, (void *)nfc->page_buf, |
| @@ -811,12 +815,17 @@ static int rk_nfc_read_page_hwecc(struct nand_chip *chip, u8 *buf, int oob_on, · 156 unmodified lines | ||
| 811 | 815 | goto timeout_err; |
| 812 | 816 | } |
| 813 | 817 | |
| 814 | − for (i = 1; i < ecc->steps; i++) { | |
| 815 | − oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE; | |
| 818 | + for (i = 0; i < ecc->steps; i++) { | |
| 819 | + if (!i) | |
| 820 | + oob = chip->oob_poi + (ecc->steps - 1) * NFC_SYS_DATA_SIZE; | |
| 821 | + else | |
| 822 | + oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE; | |
| 823 | + | |
| 816 | 824 | if (nfc->cfg->type == NFC_V9) |
| 817 | 825 | tmp = nfc->oob_buf[i]; |
| 818 | 826 | else |
| 819 | 827 | tmp = nfc->oob_buf[i * (oob_step / 4)]; |
| 828 | + | |
| 820 | 829 | *oob++ = (u8)tmp; |
| 821 | 830 | *oob++ = (u8)(tmp >> 8); |
| 822 | 831 | *oob++ = (u8)(tmp >> 16); |
| @@ -933,12 +942,8 @@ static int rk_nfc_ooblayout_free(struct mtd_info *mtd, int section, · 110 unmodified lines | ||
| 933 | 942 | if (section) |
| 934 | 943 | return -ERANGE; |
| 935 | 944 | |
| 936 | − /* | |
| 937 | − * The beginning of the OOB area stores the reserved data for the NFC, | |
| 938 | − * the size of the reserved data is NFC_SYS_DATA_SIZE bytes. | |
| 939 | − */ | |
| 940 | 945 | oob_region->length = rknand->metadata_size - NFC_SYS_DATA_SIZE - 2; |
| 941 | − oob_region->offset = NFC_SYS_DATA_SIZE + 2; | |
| 946 | + oob_region->offset = 2; | |
| 942 | 947 | |
| 943 | 948 | return 0; |
| 944 | 949 | } |
| @@ -73,7 +73,7 @@ static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand, · 72 unmodified lines | ||
| 73 | 73 | { |
| 74 | 74 | struct nand_device *nand = spinand_to_nand(spinand); |
| 75 | 75 | u8 mbf = 0; |
| 76 | − struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf); | |
| 76 | + struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, spinand->scratchbuf); | |
| 77 | 77 | |
| 78 | 78 | switch (status & STATUS_ECC_MASK) { |
| 79 | 79 | case STATUS_ECC_NO_BITFLIPS: |
| @@ -92,7 +92,7 @@ static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand, · 12 unmodified lines | ||
| 92 | 92 | if (spi_mem_exec_op(spinand->spimem, &op)) |
| 93 | 93 | return nanddev_get_ecc_conf(nand)->strength; |
| 94 | 94 | |
| 95 | − mbf >>= 4; | |
| 95 | + mbf = *(spinand->scratchbuf) >> 4; | |
| 96 | 96 | |
| 97 | 97 | if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf)) |
| 98 | 98 | return nanddev_get_ecc_conf(nand)->strength; |
| @@ -108,7 +108,7 @@ static int w25n02kv_ecc_get_status(struct spinand_device *spinand, · 107 unmodified lines | ||
| 108 | 108 | { |
| 109 | 109 | struct nand_device *nand = spinand_to_nand(spinand); |
| 110 | 110 | u8 mbf = 0; |
| 111 | − struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf); | |
| 111 | + struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, spinand->scratchbuf); | |
| 112 | 112 | |
| 113 | 113 | switch (status & STATUS_ECC_MASK) { |
| 114 | 114 | case STATUS_ECC_NO_BITFLIPS: |
| @@ -126,7 +126,7 @@ static int w25n02kv_ecc_get_status(struct spinand_device *spinand, · 11 unmodified lines | ||
| 126 | 126 | if (spi_mem_exec_op(spinand->spimem, &op)) |
| 127 | 127 | return nanddev_get_ecc_conf(nand)->strength; |
| 128 | 128 | |
| 129 | − mbf >>= 4; | |
| 129 | + mbf = *(spinand->scratchbuf) >> 4; | |
| 130 | 130 | |
| 131 | 131 | if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf)) |
| 132 | 132 | return nanddev_get_ecc_conf(nand)->strength; |
| @@ -361,7 +361,7 @@ static int cypress_nor_determine_addr_mode_by_sr1(struct spi_nor *nor, · 360 unmodified lines | ||
| 361 | 361 | */ |
| 362 | 362 | static int cypress_nor_set_addr_mode_nbytes(struct spi_nor *nor) |
| 363 | 363 | { |
| 364 | − struct spi_mem_op op = {}; | |
| 364 | + struct spi_mem_op op; | |
| 365 | 365 | u8 addr_mode; |
| 366 | 366 | int ret; |
| 367 | 367 | |
| @@ -492,7 +492,7 @@ s25fs256t_post_bfpt_fixup(struct spi_nor *nor, · 124 unmodified lines | ||
| 492 | 492 | const struct sfdp_parameter_header *bfpt_header, |
| 493 | 493 | const struct sfdp_bfpt *bfpt) |
| 494 | 494 | { |
| 495 | − struct spi_mem_op op = {}; | |
| 495 | + struct spi_mem_op op; | |
| 496 | 496 | int ret; |
| 497 | 497 | |
| 498 | 498 | ret = cypress_nor_set_addr_mode_nbytes(nor); |
| @@ -1508,6 +1508,11 @@ static void bond_setup_by_slave(struct net_device *bond_dev, · 1507 unmodified lines | ||
| 1508 | 1508 | |
| 1509 | 1509 | memcpy(bond_dev->broadcast, slave_dev->broadcast, |
| 1510 | 1510 | slave_dev->addr_len); |
| 1511 | + | |
| 1512 | + if (slave_dev->flags & IFF_POINTOPOINT) { | |
| 1513 | + bond_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); | |
| 1514 | + bond_dev->flags |= (IFF_POINTOPOINT | IFF_NOARP); | |
| 1515 | + } | |
| 1511 | 1516 | } |
| 1512 | 1517 | |
| 1513 | 1518 | /* On bonding slaves other than the currently active slave, suppress |
| @@ -5896,7 +5901,9 @@ void bond_setup(struct net_device *bond_dev) · 4382 unmodified lines | ||
| 5896 | 5901 | |
| 5897 | 5902 | bond_dev->hw_features = BOND_VLAN_FEATURES | |
| 5898 | 5903 | NETIF_F_HW_VLAN_CTAG_RX | |
| 5899 | − NETIF_F_HW_VLAN_CTAG_FILTER; | |
| 5904 | + NETIF_F_HW_VLAN_CTAG_FILTER | | |
| 5905 | + NETIF_F_HW_VLAN_STAG_RX | | |
| 5906 | + NETIF_F_HW_VLAN_STAG_FILTER; | |
| 5900 | 5907 | |
| 5901 | 5908 | bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL; |
| 5902 | 5909 | bond_dev->features |= bond_dev->hw_features; |
| @@ -1030,6 +1030,8 @@ static int gs_can_close(struct net_device *netdev) · 1029 unmodified lines | ||
| 1030 | 1030 | usb_kill_anchored_urbs(&dev->tx_submitted); |
| 1031 | 1031 | atomic_set(&dev->active_tx_urbs, 0); |
| 1032 | 1032 | |
| 1033 | + dev->can.state = CAN_STATE_STOPPED; | |
| 1034 | + | |
| 1033 | 1035 | /* reset the device */ |
| 1034 | 1036 | rc = gs_cmd_reset(dev); |
| 1035 | 1037 | if (rc < 0) |
| @@ -1436,7 +1436,9 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev) · 1435 unmodified lines | ||
| 1436 | 1436 | if (IS_ERR(priv->clk)) |
| 1437 | 1437 | return PTR_ERR(priv->clk); |
| 1438 | 1438 | |
| 1439 | − clk_prepare_enable(priv->clk); | |
| 1439 | + ret = clk_prepare_enable(priv->clk); | |
| 1440 | + if (ret) | |
| 1441 | + return ret; | |
| 1440 | 1442 | |
| 1441 | 1443 | priv->clk_mdiv = devm_clk_get_optional(&pdev->dev, "sw_switch_mdiv"); |
| 1442 | 1444 | if (IS_ERR(priv->clk_mdiv)) { |
| @@ -1444,7 +1446,9 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 1444 | 1446 | goto out_clk; |
| 1445 | 1447 | } |
| 1446 | 1448 | |
| 1447 | − clk_prepare_enable(priv->clk_mdiv); | |
| 1449 | + ret = clk_prepare_enable(priv->clk_mdiv); | |
| 1450 | + if (ret) | |
| 1451 | + goto out_clk; | |
| 1448 | 1452 | |
| 1449 | 1453 | ret = bcm_sf2_sw_rst(priv); |
| 1450 | 1454 | if (ret) { |
| @@ -635,10 +635,9 @@ static const struct regmap_range ksz9477_valid_regs[] = { · 634 unmodified lines | ||
| 635 | 635 | regmap_reg_range(0x1030, 0x1030), |
| 636 | 636 | regmap_reg_range(0x1100, 0x1115), |
| 637 | 637 | regmap_reg_range(0x111a, 0x111f), |
| 638 | − regmap_reg_range(0x1122, 0x1127), | |
| 639 | − regmap_reg_range(0x112a, 0x112b), | |
| 640 | − regmap_reg_range(0x1136, 0x1139), | |
| 641 | − regmap_reg_range(0x113e, 0x113f), | |
| 638 | + regmap_reg_range(0x1120, 0x112b), | |
| 639 | + regmap_reg_range(0x1134, 0x113b), | |
| 640 | + regmap_reg_range(0x113c, 0x113f), | |
| 642 | 641 | regmap_reg_range(0x1400, 0x1401), |
| 643 | 642 | regmap_reg_range(0x1403, 0x1403), |
| 644 | 643 | regmap_reg_range(0x1410, 0x1417), |
| @@ -669,10 +668,9 @@ static const struct regmap_range ksz9477_valid_regs[] = { · 24 unmodified lines | ||
| 669 | 668 | regmap_reg_range(0x2030, 0x2030), |
| 670 | 669 | regmap_reg_range(0x2100, 0x2115), |
| 671 | 670 | regmap_reg_range(0x211a, 0x211f), |
| 672 | − regmap_reg_range(0x2122, 0x2127), | |
| 673 | − regmap_reg_range(0x212a, 0x212b), | |
| 674 | − regmap_reg_range(0x2136, 0x2139), | |
| 675 | − regmap_reg_range(0x213e, 0x213f), | |
| 671 | + regmap_reg_range(0x2120, 0x212b), | |
| 672 | + regmap_reg_range(0x2134, 0x213b), | |
| 673 | + regmap_reg_range(0x213c, 0x213f), | |
| 676 | 674 | regmap_reg_range(0x2400, 0x2401), |
| 677 | 675 | regmap_reg_range(0x2403, 0x2403), |
| 678 | 676 | regmap_reg_range(0x2410, 0x2417), |
| @@ -703,10 +701,9 @@ static const struct regmap_range ksz9477_valid_regs[] = { · 24 unmodified lines | ||
| 703 | 701 | regmap_reg_range(0x3030, 0x3030), |
| 704 | 702 | regmap_reg_range(0x3100, 0x3115), |
| 705 | 703 | regmap_reg_range(0x311a, 0x311f), |
| 706 | − regmap_reg_range(0x3122, 0x3127), | |
| 707 | − regmap_reg_range(0x312a, 0x312b), | |
| 708 | − regmap_reg_range(0x3136, 0x3139), | |
| 709 | − regmap_reg_range(0x313e, 0x313f), | |
| 704 | + regmap_reg_range(0x3120, 0x312b), | |
| 705 | + regmap_reg_range(0x3134, 0x313b), | |
| 706 | + regmap_reg_range(0x313c, 0x313f), | |
| 710 | 707 | regmap_reg_range(0x3400, 0x3401), |
| 711 | 708 | regmap_reg_range(0x3403, 0x3403), |
| 712 | 709 | regmap_reg_range(0x3410, 0x3417), |
| @@ -737,10 +734,9 @@ static const struct regmap_range ksz9477_valid_regs[] = { · 24 unmodified lines | ||
| 737 | 734 | regmap_reg_range(0x4030, 0x4030), |
| 738 | 735 | regmap_reg_range(0x4100, 0x4115), |
| 739 | 736 | regmap_reg_range(0x411a, 0x411f), |
| 740 | − regmap_reg_range(0x4122, 0x4127), | |
| 741 | − regmap_reg_range(0x412a, 0x412b), | |
| 742 | − regmap_reg_range(0x4136, 0x4139), | |
| 743 | − regmap_reg_range(0x413e, 0x413f), | |
| 737 | + regmap_reg_range(0x4120, 0x412b), | |
| 738 | + regmap_reg_range(0x4134, 0x413b), | |
| 739 | + regmap_reg_range(0x413c, 0x413f), | |
| 744 | 740 | regmap_reg_range(0x4400, 0x4401), |
| 745 | 741 | regmap_reg_range(0x4403, 0x4403), |
| 746 | 742 | regmap_reg_range(0x4410, 0x4417), |
| @@ -771,10 +767,9 @@ static const struct regmap_range ksz9477_valid_regs[] = { · 24 unmodified lines | ||
| 771 | 767 | regmap_reg_range(0x5030, 0x5030), |
| 772 | 768 | regmap_reg_range(0x5100, 0x5115), |
| 773 | 769 | regmap_reg_range(0x511a, 0x511f), |
| 774 | − regmap_reg_range(0x5122, 0x5127), | |
| 775 | − regmap_reg_range(0x512a, 0x512b), | |
| 776 | − regmap_reg_range(0x5136, 0x5139), | |
| 777 | − regmap_reg_range(0x513e, 0x513f), | |
| 770 | + regmap_reg_range(0x5120, 0x512b), | |
| 771 | + regmap_reg_range(0x5134, 0x513b), | |
| 772 | + regmap_reg_range(0x513c, 0x513f), | |
| 778 | 773 | regmap_reg_range(0x5400, 0x5401), |
| 779 | 774 | regmap_reg_range(0x5403, 0x5403), |
| 780 | 775 | regmap_reg_range(0x5410, 0x5417), |
| @@ -1625,8 +1625,10 @@ static void felix_teardown(struct dsa_switch *ds) · 1624 unmodified lines | ||
| 1625 | 1625 | struct felix *felix = ocelot_to_felix(ocelot); |
| 1626 | 1626 | struct dsa_port *dp; |
| 1627 | 1627 | |
| 1628 | + rtnl_lock(); | |
| 1628 | 1629 | if (felix->tag_proto_ops) |
| 1629 | 1630 | felix->tag_proto_ops->teardown(ds); |
| 1631 | + rtnl_unlock(); | |
| 1630 | 1632 | |
| 1631 | 1633 | dsa_switch_for_each_available_port(dp, ds) |
| 1632 | 1634 | ocelot_deinit_port(ocelot, dp->index); |
| @@ -576,8 +576,11 @@ static struct regmap_config qca8k_regmap_config = { · 575 unmodified lines | ||
| 576 | 576 | .rd_table = &qca8k_readable_table, |
| 577 | 577 | .disable_locking = true, /* Locking is handled by qca8k read/write */ |
| 578 | 578 | .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ |
| 579 | − .max_raw_read = 32, /* mgmt eth can read/write up to 8 registers at time */ | |
| 580 | − .max_raw_write = 32, | |
| 579 | + .max_raw_read = 32, /* mgmt eth can read up to 8 registers at time */ | |
| 580 | + /* ATU regs suffer from a bug where some data are not correctly | |
| 581 | + * written. Disable bulk write to correctly write ATU entry. | |
| 582 | + */ | |
| 583 | + .use_single_write = true, | |
| 581 | 584 | }; |
| 582 | 585 | |
| 583 | 586 | static int |
| @@ -244,7 +244,7 @@ void qca8k_fdb_flush(struct qca8k_priv *priv) · 243 unmodified lines | ||
| 244 | 244 | } |
| 245 | 245 | |
| 246 | 246 | static int qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, |
| 247 | − const u8 *mac, u16 vid) | |
| 247 | + const u8 *mac, u16 vid, u8 aging) | |
| 248 | 248 | { |
| 249 | 249 | struct qca8k_fdb fdb = { 0 }; |
| 250 | 250 | int ret; |
| @@ -261,10 +261,12 @@ static int qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, · 10 unmodified lines | ||
| 261 | 261 | goto exit; |
| 262 | 262 | |
| 263 | 263 | /* Rule exist. Delete first */ |
| 264 | − if (!fdb.aging) { | |
| 264 | + if (fdb.aging) { | |
| 265 | 265 | ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); |
| 266 | 266 | if (ret) |
| 267 | 267 | goto exit; |
| 268 | + } else { | |
| 269 | + fdb.aging = aging; | |
| 268 | 270 | } |
| 269 | 271 | |
| 270 | 272 | /* Add port to fdb portmask */ |
| @@ -291,6 +293,10 @@ static int qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask, · 20 unmodified lines | ||
| 291 | 293 | if (ret < 0) |
| 292 | 294 | goto exit; |
| 293 | 295 | |
| 296 | + ret = qca8k_fdb_read(priv, &fdb); | |
| 297 | + if (ret < 0) | |
| 298 | + goto exit; | |
| 299 | + | |
| 294 | 300 | /* Rule doesn't exist. Why delete? */ |
| 295 | 301 | if (!fdb.aging) { |
| 296 | 302 | ret = -EINVAL; |
| @@ -810,7 +816,11 @@ int qca8k_port_mdb_add(struct dsa_switch *ds, int port, · 513 unmodified lines | ||
| 810 | 816 | const u8 *addr = mdb->addr; |
| 811 | 817 | u16 vid = mdb->vid; |
| 812 | 818 | |
| 813 | − return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid); | |
| 819 | + if (!vid) | |
| 820 | + vid = QCA8K_PORT_VID_DEF; | |
| 821 | + | |
| 822 | + return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid, | |
| 823 | + QCA8K_ATU_STATUS_STATIC); | |
| 814 | 824 | } |
| 815 | 825 | |
| 816 | 826 | int qca8k_port_mdb_del(struct dsa_switch *ds, int port, |
| @@ -821,6 +831,9 @@ int qca8k_port_mdb_del(struct dsa_switch *ds, int port, · 4 unmodified lines | ||
| 821 | 831 | const u8 *addr = mdb->addr; |
| 822 | 832 | u16 vid = mdb->vid; |
| 823 | 833 | |
| 834 | + if (!vid) | |
| 835 | + vid = QCA8K_PORT_VID_DEF; | |
| 836 | + | |
| 824 | 837 | return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); |
| 825 | 838 | } |
| 826 | 839 | |
| @@ -2094,8 +2094,11 @@ static int atl1c_tso_csum(struct atl1c_adapter *adapter, · 2093 unmodified lines | ||
| 2094 | 2094 | real_len = (((unsigned char *)ip_hdr(skb) - skb->data) |
| 2095 | 2095 | + ntohs(ip_hdr(skb)->tot_len)); |
| 2096 | 2096 | |
| 2097 | − if (real_len < skb->len) | |
| 2098 | − pskb_trim(skb, real_len); | |
| 2097 | + if (real_len < skb->len) { | |
| 2098 | + err = pskb_trim(skb, real_len); | |
| 2099 | + if (err) | |
| 2100 | + return err; | |
| 2101 | + } | |
| 2099 | 2102 | |
| 2100 | 2103 | hdr_len = skb_tcp_all_headers(skb); |
| 2101 | 2104 | if (unlikely(skb->len == hdr_len)) { |
| @@ -1641,8 +1641,11 @@ static int atl1e_tso_csum(struct atl1e_adapter *adapter, · 1640 unmodified lines | ||
| 1641 | 1641 | real_len = (((unsigned char *)ip_hdr(skb) - skb->data) |
| 1642 | 1642 | + ntohs(ip_hdr(skb)->tot_len)); |
| 1643 | 1643 | |
| 1644 | − if (real_len < skb->len) | |
| 1645 | − pskb_trim(skb, real_len); | |
| 1644 | + if (real_len < skb->len) { | |
| 1645 | + err = pskb_trim(skb, real_len); | |
| 1646 | + if (err) | |
| 1647 | + return err; | |
| 1648 | + } | |
| 1646 | 1649 | |
| 1647 | 1650 | hdr_len = skb_tcp_all_headers(skb); |
| 1648 | 1651 | if (unlikely(skb->len == hdr_len)) { |
| @@ -2113,8 +2113,11 @@ static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb, · 2112 unmodified lines | ||
| 2113 | 2113 | |
| 2114 | 2114 | real_len = (((unsigned char *)iph - skb->data) + |
| 2115 | 2115 | ntohs(iph->tot_len)); |
| 2116 | − if (real_len < skb->len) | |
| 2117 | − pskb_trim(skb, real_len); | |
| 2116 | + if (real_len < skb->len) { | |
| 2117 | + err = pskb_trim(skb, real_len); | |
| 2118 | + if (err) | |
| 2119 | + return err; | |
| 2120 | + } | |
| 2118 | 2121 | hdr_len = skb_tcp_all_headers(skb); |
| 2119 | 2122 | if (skb->len == hdr_len) { |
| 2120 | 2123 | iph->check = 0; |
| @@ -633,12 +633,13 @@ tx_kick_pending: · 632 unmodified lines | ||
| 633 | 633 | return NETDEV_TX_OK; |
| 634 | 634 | } |
| 635 | 635 | |
| 636 | −static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts) | |
| 636 | +static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int budget) | |
| 637 | 637 | { |
| 638 | 638 | struct bnxt_tx_ring_info *txr = bnapi->tx_ring; |
| 639 | 639 | struct netdev_queue *txq = netdev_get_tx_queue(bp->dev, txr->txq_index); |
| 640 | 640 | u16 cons = txr->tx_cons; |
| 641 | 641 | struct pci_dev *pdev = bp->pdev; |
| 642 | + int nr_pkts = bnapi->tx_pkts; | |
| 642 | 643 | int i; |
| 643 | 644 | unsigned int tx_bytes = 0; |
| 644 | 645 | |
| @@ -688,6 +689,7 @@ next_tx_int: · 43 unmodified lines | ||
| 688 | 689 | dev_kfree_skb_any(skb); |
| 689 | 690 | } |
| 690 | 691 | |
| 692 | + bnapi->tx_pkts = 0; | |
| 691 | 693 | WRITE_ONCE(txr->tx_cons, cons); |
| 692 | 694 | |
| 693 | 695 | __netif_txq_completed_wake(txq, nr_pkts, tx_bytes, |
| @@ -697,17 +699,24 @@ next_tx_int: · 3 unmodified lines | ||
| 697 | 699 | |
| 698 | 700 | static struct page *__bnxt_alloc_rx_page(struct bnxt *bp, dma_addr_t *mapping, |
| 699 | 701 | struct bnxt_rx_ring_info *rxr, |
| 702 | + unsigned int *offset, | |
| 700 | 703 | gfp_t gfp) |
| 701 | 704 | { |
| 702 | 705 | struct device *dev = &bp->pdev->dev; |
| 703 | 706 | struct page *page; |
| 704 | 707 | |
| 705 | − page = page_pool_dev_alloc_pages(rxr->page_pool); | |
| 708 | + if (PAGE_SIZE > BNXT_RX_PAGE_SIZE) { | |
| 709 | + page = page_pool_dev_alloc_frag(rxr->page_pool, offset, | |
| 710 | + BNXT_RX_PAGE_SIZE); | |
| 711 | + } else { | |
| 712 | + page = page_pool_dev_alloc_pages(rxr->page_pool); | |
| 713 | + *offset = 0; | |
| 714 | + } | |
| 706 | 715 | if (!page) |
| 707 | 716 | return NULL; |
| 708 | 717 | |
| 709 | − *mapping = dma_map_page_attrs(dev, page, 0, PAGE_SIZE, bp->rx_dir, | |
| 710 | − DMA_ATTR_WEAK_ORDERING); | |
| 718 | + *mapping = dma_map_page_attrs(dev, page, *offset, BNXT_RX_PAGE_SIZE, | |
| 719 | + bp->rx_dir, DMA_ATTR_WEAK_ORDERING); | |
| 711 | 720 | if (dma_mapping_error(dev, *mapping)) { |
| 712 | 721 | page_pool_recycle_direct(rxr->page_pool, page); |
| 713 | 722 | return NULL; |
| @@ -747,15 +756,16 @@ int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, · 33 unmodified lines | ||
| 747 | 756 | dma_addr_t mapping; |
| 748 | 757 | |
| 749 | 758 | if (BNXT_RX_PAGE_MODE(bp)) { |
| 759 | + unsigned int offset; | |
| 750 | 760 | struct page *page = |
| 751 | − __bnxt_alloc_rx_page(bp, &mapping, rxr, gfp); | |
| 761 | + __bnxt_alloc_rx_page(bp, &mapping, rxr, &offset, gfp); | |
| 752 | 762 | |
| 753 | 763 | if (!page) |
| 754 | 764 | return -ENOMEM; |
| 755 | 765 | |
| 756 | 766 | mapping += bp->rx_dma_offset; |
| 757 | 767 | rx_buf->data = page; |
| 758 | − rx_buf->data_ptr = page_address(page) + bp->rx_offset; | |
| 768 | + rx_buf->data_ptr = page_address(page) + offset + bp->rx_offset; | |
| 759 | 769 | } else { |
| 760 | 770 | u8 *data = __bnxt_alloc_rx_frag(bp, &mapping, gfp); |
| 761 | 771 | |
| @@ -815,7 +825,7 @@ static inline int bnxt_alloc_rx_page(struct bnxt *bp, · 53 unmodified lines | ||
| 815 | 825 | unsigned int offset = 0; |
| 816 | 826 | |
| 817 | 827 | if (BNXT_RX_PAGE_MODE(bp)) { |
| 818 | − page = __bnxt_alloc_rx_page(bp, &mapping, rxr, gfp); | |
| 828 | + page = __bnxt_alloc_rx_page(bp, &mapping, rxr, &offset, gfp); | |
| 819 | 829 | |
| 820 | 830 | if (!page) |
| 821 | 831 | return -ENOMEM; |
| @@ -962,15 +972,15 @@ static struct sk_buff *bnxt_rx_multi_page_skb(struct bnxt *bp, · 140 unmodified lines | ||
| 962 | 972 | return NULL; |
| 963 | 973 | } |
| 964 | 974 | dma_addr -= bp->rx_dma_offset; |
| 965 | − dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, PAGE_SIZE, bp->rx_dir, | |
| 966 | − DMA_ATTR_WEAK_ORDERING); | |
| 967 | − skb = build_skb(page_address(page), PAGE_SIZE); | |
| 975 | + dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, BNXT_RX_PAGE_SIZE, | |
| 976 | + bp->rx_dir, DMA_ATTR_WEAK_ORDERING); | |
| 977 | + skb = build_skb(data_ptr - bp->rx_offset, BNXT_RX_PAGE_SIZE); | |
| 968 | 978 | if (!skb) { |
| 969 | 979 | page_pool_recycle_direct(rxr->page_pool, page); |
| 970 | 980 | return NULL; |
| 971 | 981 | } |
| 972 | 982 | skb_mark_for_recycle(skb); |
| 973 | − skb_reserve(skb, bp->rx_dma_offset); | |
| 983 | + skb_reserve(skb, bp->rx_offset); | |
| 974 | 984 | __skb_put(skb, len); |
| 975 | 985 | |
| 976 | 986 | return skb; |
| @@ -996,8 +1006,8 @@ static struct sk_buff *bnxt_rx_page_skb(struct bnxt *bp, · 19 unmodified lines | ||
| 996 | 1006 | return NULL; |
| 997 | 1007 | } |
| 998 | 1008 | dma_addr -= bp->rx_dma_offset; |
| 999 | − dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, PAGE_SIZE, bp->rx_dir, | |
| 1000 | − DMA_ATTR_WEAK_ORDERING); | |
| 1009 | + dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, BNXT_RX_PAGE_SIZE, | |
| 1010 | + bp->rx_dir, DMA_ATTR_WEAK_ORDERING); | |
| 1001 | 1011 | |
| 1002 | 1012 | if (unlikely(!payload)) |
| 1003 | 1013 | payload = eth_get_headlen(bp->dev, data_ptr, len); |
| @@ -1010,7 +1020,7 @@ static struct sk_buff *bnxt_rx_page_skb(struct bnxt *bp, · 6 unmodified lines | ||
| 1010 | 1020 | |
| 1011 | 1021 | skb_mark_for_recycle(skb); |
| 1012 | 1022 | off = (void *)data_ptr - page_address(page); |
| 1013 | − skb_add_rx_frag(skb, 0, page, off, len, PAGE_SIZE); | |
| 1023 | + skb_add_rx_frag(skb, 0, page, off, len, BNXT_RX_PAGE_SIZE); | |
| 1014 | 1024 | memcpy(skb->data - NET_IP_ALIGN, data_ptr - NET_IP_ALIGN, |
| 1015 | 1025 | payload + NET_IP_ALIGN); |
| 1016 | 1026 | |
| @@ -1141,7 +1151,7 @@ static struct sk_buff *bnxt_rx_agg_pages_skb(struct bnxt *bp, · 124 unmodified lines | ||
| 1141 | 1151 | |
| 1142 | 1152 | skb->data_len += total_frag_len; |
| 1143 | 1153 | skb->len += total_frag_len; |
| 1144 | − skb->truesize += PAGE_SIZE * agg_bufs; | |
| 1154 | + skb->truesize += BNXT_RX_PAGE_SIZE * agg_bufs; | |
| 1145 | 1155 | return skb; |
| 1146 | 1156 | } |
| 1147 | 1157 | |
| @@ -2569,12 +2579,11 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, · 1421 unmodified lines | ||
| 2569 | 2579 | return rx_pkts; |
| 2570 | 2580 | } |
| 2571 | 2581 | |
| 2572 | −static void __bnxt_poll_work_done(struct bnxt *bp, struct bnxt_napi *bnapi) | |
| 2582 | +static void __bnxt_poll_work_done(struct bnxt *bp, struct bnxt_napi *bnapi, | |
| 2583 | + int budget) | |
| 2573 | 2584 | { |
| 2574 | − if (bnapi->tx_pkts) { | |
| 2575 | − bnapi->tx_int(bp, bnapi, bnapi->tx_pkts); | |
| 2576 | − bnapi->tx_pkts = 0; | |
| 2577 | − } | |
| 2585 | + if (bnapi->tx_pkts) | |
| 2586 | + bnapi->tx_int(bp, bnapi, budget); | |
| 2578 | 2587 | |
| 2579 | 2588 | if ((bnapi->events & BNXT_RX_EVENT) && !(bnapi->in_reset)) { |
| 2580 | 2589 | struct bnxt_rx_ring_info *rxr = bnapi->rx_ring; |
| @@ -2603,7 +2612,7 @@ static int bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, · 22 unmodified lines | ||
| 2603 | 2612 | */ |
| 2604 | 2613 | bnxt_db_cq(bp, &cpr->cp_db, cpr->cp_raw_cons); |
| 2605 | 2614 | |
| 2606 | − __bnxt_poll_work_done(bp, bnapi); | |
| 2615 | + __bnxt_poll_work_done(bp, bnapi, budget); | |
| 2607 | 2616 | return rx_pkts; |
| 2608 | 2617 | } |
| 2609 | 2618 | |
| @@ -2734,7 +2743,7 @@ static int __bnxt_poll_cqs(struct bnxt *bp, struct bnxt_napi *bnapi, int budget) · 124 unmodified lines | ||
| 2734 | 2743 | } |
| 2735 | 2744 | |
| 2736 | 2745 | static void __bnxt_poll_cqs_done(struct bnxt *bp, struct bnxt_napi *bnapi, |
| 2737 | − u64 dbr_type) | |
| 2746 | + u64 dbr_type, int budget) | |
| 2738 | 2747 | { |
| 2739 | 2748 | struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring; |
| 2740 | 2749 | int i; |
| @@ -2750,7 +2759,7 @@ static void __bnxt_poll_cqs_done(struct bnxt *bp, struct bnxt_napi *bnapi, · 9 unmodified lines | ||
| 2750 | 2759 | cpr2->had_work_done = 0; |
| 2751 | 2760 | } |
| 2752 | 2761 | } |
| 2753 | − __bnxt_poll_work_done(bp, bnapi); | |
| 2762 | + __bnxt_poll_work_done(bp, bnapi, budget); | |
| 2754 | 2763 | } |
| 2755 | 2764 | |
| 2756 | 2765 | static int bnxt_poll_p5(struct napi_struct *napi, int budget) |
| @@ -2780,7 +2789,8 @@ static int bnxt_poll_p5(struct napi_struct *napi, int budget) · 23 unmodified lines | ||
| 2780 | 2789 | if (cpr->has_more_work) |
| 2781 | 2790 | break; |
| 2782 | 2791 | |
| 2783 | − __bnxt_poll_cqs_done(bp, bnapi, DBR_TYPE_CQ_ARMALL); | |
| 2792 | + __bnxt_poll_cqs_done(bp, bnapi, DBR_TYPE_CQ_ARMALL, | |
| 2793 | + budget); | |
| 2784 | 2794 | cpr->cp_raw_cons = raw_cons; |
| 2785 | 2795 | if (napi_complete_done(napi, work_done)) |
| 2786 | 2796 | BNXT_DB_NQ_ARM_P5(&cpr->cp_db, |
| @@ -2810,7 +2820,7 @@ static int bnxt_poll_p5(struct napi_struct *napi, int budget) · 23 unmodified lines | ||
| 2810 | 2820 | } |
| 2811 | 2821 | raw_cons = NEXT_RAW_CMP(raw_cons); |
| 2812 | 2822 | } |
| 2813 | − __bnxt_poll_cqs_done(bp, bnapi, DBR_TYPE_CQ); | |
| 2823 | + __bnxt_poll_cqs_done(bp, bnapi, DBR_TYPE_CQ, budget); | |
| 2814 | 2824 | if (raw_cons != cpr->cp_raw_cons) { |
| 2815 | 2825 | cpr->cp_raw_cons = raw_cons; |
| 2816 | 2826 | BNXT_DB_NQ_P5(&cpr->cp_db, raw_cons); |
| @@ -2943,8 +2953,8 @@ skip_rx_tpa_free: · 126 unmodified lines | ||
| 2943 | 2953 | rx_buf->data = NULL; |
| 2944 | 2954 | if (BNXT_RX_PAGE_MODE(bp)) { |
| 2945 | 2955 | mapping -= bp->rx_dma_offset; |
| 2946 | − dma_unmap_page_attrs(&pdev->dev, mapping, PAGE_SIZE, | |
| 2947 | − bp->rx_dir, | |
| 2956 | + dma_unmap_page_attrs(&pdev->dev, mapping, | |
| 2957 | + BNXT_RX_PAGE_SIZE, bp->rx_dir, | |
| 2948 | 2958 | DMA_ATTR_WEAK_ORDERING); |
| 2949 | 2959 | page_pool_recycle_direct(rxr->page_pool, data); |
| 2950 | 2960 | } else { |
| @@ -3213,6 +3223,8 @@ static int bnxt_alloc_rx_page_pool(struct bnxt *bp, · 262 unmodified lines | ||
| 3213 | 3223 | pp.napi = &rxr->bnapi->napi; |
| 3214 | 3224 | pp.dev = &bp->pdev->dev; |
| 3215 | 3225 | pp.dma_dir = DMA_BIDIRECTIONAL; |
| 3226 | + if (PAGE_SIZE > BNXT_RX_PAGE_SIZE) | |
| 3227 | + pp.flags |= PP_FLAG_PAGE_FRAG; | |
| 3216 | 3228 | |
| 3217 | 3229 | rxr->page_pool = page_pool_create(&pp); |
| 3218 | 3230 | if (IS_ERR(rxr->page_pool)) { |
| @@ -3989,26 +4001,29 @@ void bnxt_set_ring_params(struct bnxt *bp) · 770 unmodified lines | ||
| 3989 | 4001 | */ |
| 3990 | 4002 | int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode) |
| 3991 | 4003 | { |
| 4004 | + struct net_device *dev = bp->dev; | |
| 4005 | + | |
| 3992 | 4006 | if (page_mode) { |
| 3993 | 4007 | bp->flags &= ~BNXT_FLAG_AGG_RINGS; |
| 3994 | 4008 | bp->flags |= BNXT_FLAG_RX_PAGE_MODE; |
| 3995 | 4009 | |
| 3996 | − if (bp->dev->mtu > BNXT_MAX_PAGE_MODE_MTU) { | |
| 4010 | + if (bp->xdp_prog->aux->xdp_has_frags) | |
| 4011 | + dev->max_mtu = min_t(u16, bp->max_mtu, BNXT_MAX_MTU); | |
| 4012 | + else | |
| 4013 | + dev->max_mtu = | |
| 4014 | + min_t(u16, bp->max_mtu, BNXT_MAX_PAGE_MODE_MTU); | |
| 4015 | + if (dev->mtu > BNXT_MAX_PAGE_MODE_MTU) { | |
| 3997 | 4016 | bp->flags |= BNXT_FLAG_JUMBO; |
| 3998 | 4017 | bp->rx_skb_func = bnxt_rx_multi_page_skb; |
| 3999 | − bp->dev->max_mtu = | |
| 4000 | − min_t(u16, bp->max_mtu, BNXT_MAX_MTU); | |
| 4001 | 4018 | } else { |
| 4002 | 4019 | bp->flags |= BNXT_FLAG_NO_AGG_RINGS; |
| 4003 | 4020 | bp->rx_skb_func = bnxt_rx_page_skb; |
| 4004 | − bp->dev->max_mtu = | |
| 4005 | − min_t(u16, bp->max_mtu, BNXT_MAX_PAGE_MODE_MTU); | |
| 4006 | 4021 | } |
| 4007 | 4022 | bp->rx_dir = DMA_BIDIRECTIONAL; |
| 4008 | 4023 | /* Disable LRO or GRO_HW */ |
| 4009 | − netdev_update_features(bp->dev); | |
| 4024 | + netdev_update_features(dev); | |
| 4010 | 4025 | } else { |
| 4011 | − bp->dev->max_mtu = bp->max_mtu; | |
| 4026 | + dev->max_mtu = bp->max_mtu; | |
| 4012 | 4027 | bp->flags &= ~BNXT_FLAG_RX_PAGE_MODE; |
| 4013 | 4028 | bp->rx_dir = DMA_FROM_DEVICE; |
| 4014 | 4029 | bp->rx_skb_func = bnxt_rx_skb; |
| @@ -9429,6 +9444,8 @@ static void bnxt_enable_napi(struct bnxt *bp) · 5414 unmodified lines | ||
| 9429 | 9444 | cpr->sw_stats.rx.rx_resets++; |
| 9430 | 9445 | bnapi->in_reset = false; |
| 9431 | 9446 | |
| 9447 | + bnapi->tx_pkts = 0; | |
| 9448 | + | |
| 9432 | 9449 | if (bnapi->rx_ring) { |
| 9433 | 9450 | INIT_WORK(&cpr->dim.work, bnxt_dim_work); |
| 9434 | 9451 | cpr->dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; |
| @@ -1005,7 +1005,7 @@ struct bnxt_napi { · 1004 unmodified lines | ||
| 1005 | 1005 | struct bnxt_tx_ring_info *tx_ring; |
| 1006 | 1006 | |
| 1007 | 1007 | void (*tx_int)(struct bnxt *, struct bnxt_napi *, |
| 1008 | − int); | |
| 1008 | + int budget); | |
| 1009 | 1009 | int tx_pkts; |
| 1010 | 1010 | u8 events; |
| 1011 | 1011 | |
| @@ -125,16 +125,20 @@ static void __bnxt_xmit_xdp_redirect(struct bnxt *bp, · 124 unmodified lines | ||
| 125 | 125 | dma_unmap_len_set(tx_buf, len, 0); |
| 126 | 126 | } |
| 127 | 127 | |
| 128 | −void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts) | |
| 128 | +void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int budget) | |
| 129 | 129 | { |
| 130 | 130 | struct bnxt_tx_ring_info *txr = bnapi->tx_ring; |
| 131 | 131 | struct bnxt_rx_ring_info *rxr = bnapi->rx_ring; |
| 132 | 132 | bool rx_doorbell_needed = false; |
| 133 | + int nr_pkts = bnapi->tx_pkts; | |
| 133 | 134 | struct bnxt_sw_tx_bd *tx_buf; |
| 134 | 135 | u16 tx_cons = txr->tx_cons; |
| 135 | 136 | u16 last_tx_cons = tx_cons; |
| 136 | 137 | int i, j, frags; |
| 137 | 138 | |
| 139 | + if (!budget) | |
| 140 | + return; | |
| 141 | + | |
| 138 | 142 | for (i = 0; i < nr_pkts; i++) { |
| 139 | 143 | tx_buf = &txr->tx_buf_ring[tx_cons]; |
| 140 | 144 | |
| @@ -161,6 +165,8 @@ void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts) · 20 unmodified lines | ||
| 161 | 165 | } |
| 162 | 166 | tx_cons = NEXT_TX(tx_cons); |
| 163 | 167 | } |
| 168 | + | |
| 169 | + bnapi->tx_pkts = 0; | |
| 164 | 170 | WRITE_ONCE(txr->tx_cons, tx_cons); |
| 165 | 171 | if (rx_doorbell_needed) { |
| 166 | 172 | tx_buf = &txr->tx_buf_ring[last_tx_cons]; |
| @@ -180,8 +186,8 @@ void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, · 13 unmodified lines | ||
| 180 | 186 | u16 cons, u8 *data_ptr, unsigned int len, |
| 181 | 187 | struct xdp_buff *xdp) |
| 182 | 188 | { |
| 189 | + u32 buflen = BNXT_RX_PAGE_SIZE; | |
| 183 | 190 | struct bnxt_sw_rx_bd *rx_buf; |
| 184 | − u32 buflen = PAGE_SIZE; | |
| 185 | 191 | struct pci_dev *pdev; |
| 186 | 192 | dma_addr_t mapping; |
| 187 | 193 | u32 offset; |
| @@ -297,7 +303,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons, · 109 unmodified lines | ||
| 297 | 303 | rx_buf = &rxr->rx_buf_ring[cons]; |
| 298 | 304 | mapping = rx_buf->mapping - bp->rx_dma_offset; |
| 299 | 305 | dma_unmap_page_attrs(&pdev->dev, mapping, |
| 300 | − PAGE_SIZE, bp->rx_dir, | |
| 306 | + BNXT_RX_PAGE_SIZE, bp->rx_dir, | |
| 301 | 307 | DMA_ATTR_WEAK_ORDERING); |
| 302 | 308 | |
| 303 | 309 | /* if we are unable to allocate a new buffer, abort and reuse */ |
| @@ -480,7 +486,7 @@ bnxt_xdp_build_skb(struct bnxt *bp, struct sk_buff *skb, u8 num_frags, · 176 unmodified lines | ||
| 480 | 486 | } |
| 481 | 487 | xdp_update_skb_shared_info(skb, num_frags, |
| 482 | 488 | sinfo->xdp_frags_size, |
| 483 | − PAGE_SIZE * sinfo->nr_frags, | |
| 489 | + BNXT_RX_PAGE_SIZE * sinfo->nr_frags, | |
| 484 | 490 | xdp_buff_is_frag_pfmemalloc(xdp)); |
| 485 | 491 | return skb; |
| 486 | 492 | } |
| @@ -16,7 +16,7 @@ struct bnxt_sw_tx_bd *bnxt_xmit_bd(struct bnxt *bp, · 15 unmodified lines | ||
| 16 | 16 | struct bnxt_tx_ring_info *txr, |
| 17 | 17 | dma_addr_t mapping, u32 len, |
| 18 | 18 | struct xdp_buff *xdp); |
| 19 | −void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts); | |
| 19 | +void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int budget); | |
| 20 | 20 | bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons, |
| 21 | 21 | struct xdp_buff xdp, struct page *page, u8 **data_ptr, |
| 22 | 22 | unsigned int *len, u8 *event); |
| @@ -1138,7 +1138,8 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter, · 1137 unmodified lines | ||
| 1138 | 1138 | (lancer_chip(adapter) || BE3_chip(adapter) || |
| 1139 | 1139 | skb_vlan_tag_present(skb)) && is_ipv4_pkt(skb)) { |
| 1140 | 1140 | ip = (struct iphdr *)ip_hdr(skb); |
| 1141 | − pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len)); | |
| 1141 | + if (unlikely(pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len)))) | |
| 1142 | + goto tx_drop; | |
| 1142 | 1143 | } |
| 1143 | 1144 | |
| 1144 | 1145 | /* If vlan tag is already inlined in the packet, skip HW VLAN |
| @@ -1186,14 +1186,9 @@ static int enetc_init_port_rss_memory(struct enetc_si *si) · 1185 unmodified lines | ||
| 1186 | 1186 | |
| 1187 | 1187 | static int enetc_pf_register_with_ierb(struct pci_dev *pdev) |
| 1188 | 1188 | { |
| 1189 | − struct device_node *node = pdev->dev.of_node; | |
| 1190 | 1189 | struct platform_device *ierb_pdev; |
| 1191 | 1190 | struct device_node *ierb_node; |
| 1192 | 1191 | |
| 1193 | − /* Don't register with the IERB if the PF itself is disabled */ | |
| 1194 | − if (!node || !of_device_is_available(node)) | |
| 1195 | − return 0; | |
| 1196 | − | |
| 1197 | 1192 | ierb_node = of_find_compatible_node(NULL, NULL, |
| 1198 | 1193 | "fsl,ls1028a-enetc-ierb"); |
| 1199 | 1194 | if (!ierb_node || !of_device_is_available(ierb_node)) |
| @@ -1208,56 +1203,81 @@ static int enetc_pf_register_with_ierb(struct pci_dev *pdev) · 8 unmodified lines | ||
| 1208 | 1203 | return enetc_ierb_register_pf(ierb_pdev, pdev); |
| 1209 | 1204 | } |
| 1210 | 1205 | |
| 1211 | −static int enetc_pf_probe(struct pci_dev *pdev, | |
| 1212 | − const struct pci_device_id *ent) | |
| 1206 | +static struct enetc_si *enetc_psi_create(struct pci_dev *pdev) | |
| 1213 | 1207 | { |
| 1214 | − struct device_node *node = pdev->dev.of_node; | |
| 1215 | − struct enetc_ndev_priv *priv; | |
| 1216 | − struct net_device *ndev; | |
| 1217 | 1208 | struct enetc_si *si; |
| 1218 | − struct enetc_pf *pf; | |
| 1219 | 1209 | int err; |
| 1220 | 1210 | |
| 1221 | − err = enetc_pf_register_with_ierb(pdev); | |
| 1222 | − if (err == -EPROBE_DEFER) | |
| 1223 | − return err; | |
| 1224 | − if (err) | |
| 1225 | − dev_warn(&pdev->dev, | |
| 1226 | − "Could not register with IERB driver: %pe, please update the device tree\n", | |
| 1227 | − ERR_PTR(err)); | |
| 1228 | − | |
| 1229 | − err = enetc_pci_probe(pdev, KBUILD_MODNAME, sizeof(*pf)); | |
| 1230 | − if (err) | |
| 1231 | − return dev_err_probe(&pdev->dev, err, "PCI probing failed\n"); | |
| 1211 | + err = enetc_pci_probe(pdev, KBUILD_MODNAME, sizeof(struct enetc_pf)); | |
| 1212 | + if (err) { | |
| 1213 | + dev_err_probe(&pdev->dev, err, "PCI probing failed\n"); | |
| 1214 | + goto out; | |
| 1215 | + } | |
| 1232 | 1216 | |
| 1233 | 1217 | si = pci_get_drvdata(pdev); |
| 1234 | 1218 | if (!si->hw.port || !si->hw.global) { |
| 1235 | 1219 | err = -ENODEV; |
| 1236 | 1220 | dev_err(&pdev->dev, "could not map PF space, probing a VF?\n"); |
| 1237 | − goto err_map_pf_space; | |
| 1221 | + goto out_pci_remove; | |
| 1238 | 1222 | } |
| 1239 | 1223 | |
| 1240 | 1224 | err = enetc_setup_cbdr(&pdev->dev, &si->hw, ENETC_CBDR_DEFAULT_SIZE, |
| 1241 | 1225 | &si->cbd_ring); |
| 1242 | 1226 | if (err) |
| 1243 | − goto err_setup_cbdr; | |
| 1227 | + goto out_pci_remove; | |
| 1244 | 1228 | |
| 1245 | 1229 | err = enetc_init_port_rfs_memory(si); |
| 1246 | 1230 | if (err) { |
| 1247 | 1231 | dev_err(&pdev->dev, "Failed to initialize RFS memory\n"); |
| 1248 | − goto err_init_port_rfs; | |
| 1232 | + goto out_teardown_cbdr; | |
| 1249 | 1233 | } |
| 1250 | 1234 | |
| 1251 | 1235 | err = enetc_init_port_rss_memory(si); |
| 1252 | 1236 | if (err) { |
| 1253 | 1237 | dev_err(&pdev->dev, "Failed to initialize RSS memory\n"); |
| 1254 | − goto err_init_port_rss; | |
| 1238 | + goto out_teardown_cbdr; | |
| 1255 | 1239 | } |
| 1256 | 1240 | |
| 1257 | − if (node && !of_device_is_available(node)) { | |
| 1258 | − dev_info(&pdev->dev, "device is disabled, skipping\n"); | |
| 1259 | − err = -ENODEV; | |
| 1260 | − goto err_device_disabled; | |
| 1241 | + return si; | |
| 1242 | + | |
| 1243 | +out_teardown_cbdr: | |
| 1244 | + enetc_teardown_cbdr(&si->cbd_ring); | |
| 1245 | +out_pci_remove: | |
| 1246 | + enetc_pci_remove(pdev); | |
| 1247 | +out: | |
| 1248 | + return ERR_PTR(err); | |
| 1249 | +} | |
| 1250 | + | |
| 1251 | +static void enetc_psi_destroy(struct pci_dev *pdev) | |
| 1252 | +{ | |
| 1253 | + struct enetc_si *si = pci_get_drvdata(pdev); | |
| 1254 | + | |
| 1255 | + enetc_teardown_cbdr(&si->cbd_ring); | |
| 1256 | + enetc_pci_remove(pdev); | |
| 1257 | +} | |
| 1258 | + | |
| 1259 | +static int enetc_pf_probe(struct pci_dev *pdev, | |
| 1260 | + const struct pci_device_id *ent) | |
| 1261 | +{ | |
| 1262 | + struct device_node *node = pdev->dev.of_node; | |
| 1263 | + struct enetc_ndev_priv *priv; | |
| 1264 | + struct net_device *ndev; | |
| 1265 | + struct enetc_si *si; | |
| 1266 | + struct enetc_pf *pf; | |
| 1267 | + int err; | |
| 1268 | + | |
| 1269 | + err = enetc_pf_register_with_ierb(pdev); | |
| 1270 | + if (err == -EPROBE_DEFER) | |
| 1271 | + return err; | |
| 1272 | + if (err) | |
| 1273 | + dev_warn(&pdev->dev, | |
| 1274 | + "Could not register with IERB driver: %pe, please update the device tree\n", | |
| 1275 | + ERR_PTR(err)); | |
| 1276 | + | |
| 1277 | + si = enetc_psi_create(pdev); | |
| 1278 | + if (IS_ERR(si)) { | |
| 1279 | + err = PTR_ERR(si); | |
| 1280 | + goto err_psi_create; | |
| 1261 | 1281 | } |
| 1262 | 1282 | |
| 1263 | 1283 | pf = enetc_si_priv(si); |
| @@ -1339,15 +1359,9 @@ err_alloc_si_res: · 75 unmodified lines | ||
| 1339 | 1359 | si->ndev = NULL; |
| 1340 | 1360 | free_netdev(ndev); |
| 1341 | 1361 | err_alloc_netdev: |
| 1342 | −err_init_port_rss: | |
| 1343 | −err_init_port_rfs: | |
| 1344 | −err_device_disabled: | |
| 1345 | 1362 | err_setup_mac_addresses: |
| 1346 | − enetc_teardown_cbdr(&si->cbd_ring); | |
| 1347 | −err_setup_cbdr: | |
| 1348 | −err_map_pf_space: | |
| 1349 | − enetc_pci_remove(pdev); | |
| 1350 | − | |
| 1363 | + enetc_psi_destroy(pdev); | |
| 1364 | +err_psi_create: | |
| 1351 | 1365 | return err; |
| 1352 | 1366 | } |
| 1353 | 1367 | |
| @@ -1370,12 +1384,29 @@ static void enetc_pf_remove(struct pci_dev *pdev) · 16 unmodified lines | ||
| 1370 | 1384 | enetc_free_msix(priv); |
| 1371 | 1385 | |
| 1372 | 1386 | enetc_free_si_resources(priv); |
| 1373 | − enetc_teardown_cbdr(&si->cbd_ring); | |
| 1374 | 1387 | |
| 1375 | 1388 | free_netdev(si->ndev); |
| 1376 | 1389 | |
| 1377 | − enetc_pci_remove(pdev); | |
| 1390 | + enetc_psi_destroy(pdev); | |
| 1391 | +} | |
| 1392 | + | |
| 1393 | +static void enetc_fixup_clear_rss_rfs(struct pci_dev *pdev) | |
| 1394 | +{ | |
| 1395 | + struct device_node *node = pdev->dev.of_node; | |
| 1396 | + struct enetc_si *si; | |
| 1397 | + | |
| 1398 | + /* Only apply quirk for disabled functions. For the ones | |
| 1399 | + * that are enabled, enetc_pf_probe() will apply it. | |
| 1400 | + */ | |
| 1401 | + if (node && of_device_is_available(node)) | |
| 1402 | + return; | |
| 1403 | + | |
| 1404 | + si = enetc_psi_create(pdev); | |
| 1405 | + if (si) | |
| 1406 | + enetc_psi_destroy(pdev); | |
| 1378 | 1407 | } |
| 1408 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PF, | |
| 1409 | + enetc_fixup_clear_rss_rfs); | |
| 1379 | 1410 | |
| 1380 | 1411 | static const struct pci_device_id enetc_pf_id_table[] = { |
| 1381 | 1412 | { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PF) }, |
| @@ -1372,7 +1372,7 @@ fec_enet_hwtstamp(struct fec_enet_private *fep, unsigned ts, · 1371 unmodified lines | ||
| 1372 | 1372 | } |
| 1373 | 1373 | |
| 1374 | 1374 | static void |
| 1375 | −fec_enet_tx_queue(struct net_device *ndev, u16 queue_id) | |
| 1375 | +fec_enet_tx_queue(struct net_device *ndev, u16 queue_id, int budget) | |
| 1376 | 1376 | { |
| 1377 | 1377 | struct fec_enet_private *fep; |
| 1378 | 1378 | struct xdp_frame *xdpf; |
| @@ -1416,6 +1416,14 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id) · 37 unmodified lines | ||
| 1416 | 1416 | if (!skb) |
| 1417 | 1417 | goto tx_buf_done; |
| 1418 | 1418 | } else { |
| 1419 | + /* Tx processing cannot call any XDP (or page pool) APIs if | |
| 1420 | + * the "budget" is 0. Because NAPI is called with budget of | |
| 1421 | + * 0 (such as netpoll) indicates we may be in an IRQ context, | |
| 1422 | + * however, we can't use the page pool from IRQ context. | |
| 1423 | + */ | |
| 1424 | + if (unlikely(!budget)) | |
| 1425 | + break; | |
| 1426 | + | |
| 1419 | 1427 | xdpf = txq->tx_buf[index].xdp; |
| 1420 | 1428 | if (bdp->cbd_bufaddr) |
| 1421 | 1429 | dma_unmap_single(&fep->pdev->dev, |
| @@ -1508,14 +1516,14 @@ tx_buf_done: · 86 unmodified lines | ||
| 1508 | 1516 | writel(0, txq->bd.reg_desc_active); |
| 1509 | 1517 | } |
| 1510 | 1518 | |
| 1511 | −static void fec_enet_tx(struct net_device *ndev) | |
| 1519 | +static void fec_enet_tx(struct net_device *ndev, int budget) | |
| 1512 | 1520 | { |
| 1513 | 1521 | struct fec_enet_private *fep = netdev_priv(ndev); |
| 1514 | 1522 | int i; |
| 1515 | 1523 | |
| 1516 | 1524 | /* Make sure that AVB queues are processed first. */ |
| 1517 | 1525 | for (i = fep->num_tx_queues - 1; i >= 0; i--) |
| 1518 | − fec_enet_tx_queue(ndev, i); | |
| 1526 | + fec_enet_tx_queue(ndev, i, budget); | |
| 1519 | 1527 | } |
| 1520 | 1528 | |
| 1521 | 1529 | static void fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq, |
| @@ -1858,7 +1866,7 @@ static int fec_enet_rx_napi(struct napi_struct *napi, int budget) · 336 unmodified lines | ||
| 1858 | 1866 | |
| 1859 | 1867 | do { |
| 1860 | 1868 | done += fec_enet_rx(ndev, budget - done); |
| 1861 | − fec_enet_tx(ndev); | |
| 1869 | + fec_enet_tx(ndev, budget); | |
| 1862 | 1870 | } while ((done < budget) && fec_enet_collect_events(fep)); |
| 1863 | 1871 | |
| 1864 | 1872 | if (done < budget) { |
| @@ -3916,6 +3924,8 @@ static int fec_enet_xdp_xmit(struct net_device *dev, · 2051 unmodified lines | ||
| 3916 | 3924 | |
| 3917 | 3925 | __netif_tx_lock(nq, cpu); |
| 3918 | 3926 | |
| 3927 | + /* Avoid tx timeout as XDP shares the queue with kernel stack */ | |
| 3928 | + txq_trans_cond_update(nq); | |
| 3919 | 3929 | for (i = 0; i < num_frames; i++) { |
| 3920 | 3930 | if (fec_enet_txq_xmit_frame(fep, txq, frames[i]) < 0) |
| 3921 | 3931 | break; |
| @@ -31,6 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | #include <linux/pci.h> |
| 32 | 32 | #include <linux/pkt_sched.h> |
| 33 | 33 | #include <linux/types.h> |
| 34 | +#include <linux/bitmap.h> | |
| 34 | 35 | #include <net/pkt_cls.h> |
| 35 | 36 | #include <net/pkt_sched.h> |
| 36 | 37 | |
| @@ -101,6 +102,7 @@ enum HNAE3_DEV_CAP_BITS { · 64 unmodified lines | ||
| 101 | 102 | HNAE3_DEV_SUPPORT_FEC_STATS_B, |
| 102 | 103 | HNAE3_DEV_SUPPORT_LANE_NUM_B, |
| 103 | 104 | HNAE3_DEV_SUPPORT_WOL_B, |
| 105 | + HNAE3_DEV_SUPPORT_TM_FLUSH_B, | |
| 104 | 106 | }; |
| 105 | 107 | |
| 106 | 108 | #define hnae3_ae_dev_fd_supported(ae_dev) \ |
| @@ -172,6 +174,9 @@ enum HNAE3_DEV_CAP_BITS { · 65 unmodified lines | ||
| 172 | 174 | #define hnae3_ae_dev_wol_supported(ae_dev) \ |
| 173 | 175 | test_bit(HNAE3_DEV_SUPPORT_WOL_B, (ae_dev)->caps) |
| 174 | 176 | |
| 177 | +#define hnae3_ae_dev_tm_flush_supported(hdev) \ | |
| 178 | + test_bit(HNAE3_DEV_SUPPORT_TM_FLUSH_B, (hdev)->ae_dev->caps) | |
| 179 | + | |
| 175 | 180 | enum HNAE3_PF_CAP_BITS { |
| 176 | 181 | HNAE3_PF_SUPPORT_VLAN_FLTR_MDF_B = 0, |
| 177 | 182 | }; |
| @@ -407,7 +412,7 @@ struct hnae3_ae_dev { · 229 unmodified lines | ||
| 407 | 412 | unsigned long hw_err_reset_req; |
| 408 | 413 | struct hnae3_dev_specs dev_specs; |
| 409 | 414 | u32 dev_version; |
| 410 | − unsigned long caps[BITS_TO_LONGS(HNAE3_DEV_CAPS_MAX_NUM)]; | |
| 415 | + DECLARE_BITMAP(caps, HNAE3_DEV_CAPS_MAX_NUM); | |
| 411 | 416 | void *priv; |
| 412 | 417 | }; |
| 413 | 418 | |
| @@ -156,6 +156,7 @@ static const struct hclge_comm_caps_bit_map hclge_pf_cmd_caps[] = { · 155 unmodified lines | ||
| 156 | 156 | {HCLGE_COMM_CAP_FEC_STATS_B, HNAE3_DEV_SUPPORT_FEC_STATS_B}, |
| 157 | 157 | {HCLGE_COMM_CAP_LANE_NUM_B, HNAE3_DEV_SUPPORT_LANE_NUM_B}, |
| 158 | 158 | {HCLGE_COMM_CAP_WOL_B, HNAE3_DEV_SUPPORT_WOL_B}, |
| 159 | + {HCLGE_COMM_CAP_TM_FLUSH_B, HNAE3_DEV_SUPPORT_TM_FLUSH_B}, | |
| 159 | 160 | }; |
| 160 | 161 | |
| 161 | 162 | static const struct hclge_comm_caps_bit_map hclge_vf_cmd_caps[] = { |
| @@ -171,6 +172,20 @@ static const struct hclge_comm_caps_bit_map hclge_vf_cmd_caps[] = { · 9 unmodified lines | ||
| 171 | 172 | {HCLGE_COMM_CAP_GRO_B, HNAE3_DEV_SUPPORT_GRO_B}, |
| 172 | 173 | }; |
| 173 | 174 | |
| 175 | +static void | |
| 176 | +hclge_comm_capability_to_bitmap(unsigned long *bitmap, __le32 *caps) | |
| 177 | +{ | |
| 178 | + const unsigned int words = HCLGE_COMM_QUERY_CAP_LENGTH; | |
| 179 | + u32 val[HCLGE_COMM_QUERY_CAP_LENGTH]; | |
| 180 | + unsigned int i; | |
| 181 | + | |
| 182 | + for (i = 0; i < words; i++) | |
| 183 | + val[i] = __le32_to_cpu(caps[i]); | |
| 184 | + | |
| 185 | + bitmap_from_arr32(bitmap, val, | |
| 186 | + HCLGE_COMM_QUERY_CAP_LENGTH * BITS_PER_TYPE(u32)); | |
| 187 | +} | |
| 188 | + | |
| 174 | 189 | static void |
| 175 | 190 | hclge_comm_parse_capability(struct hnae3_ae_dev *ae_dev, bool is_pf, |
| 176 | 191 | struct hclge_comm_query_version_cmd *cmd) |
| @@ -179,11 +194,12 @@ hclge_comm_parse_capability(struct hnae3_ae_dev *ae_dev, bool is_pf, · 2 unmodified lines | ||
| 179 | 194 | is_pf ? hclge_pf_cmd_caps : hclge_vf_cmd_caps; |
| 180 | 195 | u32 size = is_pf ? ARRAY_SIZE(hclge_pf_cmd_caps) : |
| 181 | 196 | ARRAY_SIZE(hclge_vf_cmd_caps); |
| 182 | − u32 caps, i; | |
| 197 | + DECLARE_BITMAP(caps, HCLGE_COMM_QUERY_CAP_LENGTH * BITS_PER_TYPE(u32)); | |
| 198 | + u32 i; | |
| 183 | 199 | |
| 184 | − caps = __le32_to_cpu(cmd->caps[0]); | |
| 200 | + hclge_comm_capability_to_bitmap(caps, cmd->caps); | |
| 185 | 201 | for (i = 0; i < size; i++) |
| 186 | − if (hnae3_get_bit(caps, caps_map[i].imp_bit)) | |
| 202 | + if (test_bit(caps_map[i].imp_bit, caps)) | |
| 187 | 203 | set_bit(caps_map[i].local_bit, ae_dev->caps); |
| 188 | 204 | } |
| 189 | 205 | |
| @@ -153,6 +153,7 @@ enum hclge_opcode_type { · 152 unmodified lines | ||
| 153 | 153 | HCLGE_OPC_TM_INTERNAL_STS = 0x0850, |
| 154 | 154 | HCLGE_OPC_TM_INTERNAL_CNT = 0x0851, |
| 155 | 155 | HCLGE_OPC_TM_INTERNAL_STS_1 = 0x0852, |
| 156 | + HCLGE_OPC_TM_FLUSH = 0x0872, | |
| 156 | 157 | |
| 157 | 158 | /* Packet buffer allocate commands */ |
| 158 | 159 | HCLGE_OPC_TX_BUFF_ALLOC = 0x0901, |
| @@ -349,6 +350,7 @@ enum HCLGE_COMM_CAP_BITS { · 190 unmodified lines | ||
| 349 | 350 | HCLGE_COMM_CAP_FEC_STATS_B = 25, |
| 350 | 351 | HCLGE_COMM_CAP_LANE_NUM_B = 27, |
| 351 | 352 | HCLGE_COMM_CAP_WOL_B = 28, |
| 353 | + HCLGE_COMM_CAP_TM_FLUSH_B = 31, | |
| 352 | 354 | }; |
| 353 | 355 | |
| 354 | 356 | enum HCLGE_COMM_API_CAP_BITS { |
| @@ -411,6 +411,9 @@ static struct hns3_dbg_cap_info hns3_dbg_cap[] = { · 410 unmodified lines | ||
| 411 | 411 | }, { |
| 412 | 412 | .name = "support wake on lan", |
| 413 | 413 | .cap_bit = HNAE3_DEV_SUPPORT_WOL_B, |
| 414 | + }, { | |
| 415 | + .name = "support tm flush", | |
| 416 | + .cap_bit = HNAE3_DEV_SUPPORT_TM_FLUSH_B, | |
| 414 | 417 | } |
| 415 | 418 | }; |
| 416 | 419 | |
| @@ -461,9 +464,9 @@ static void hns3_dbg_fill_content(char *content, u16 len, · 44 unmodified lines | ||
| 461 | 464 | if (result) { |
| 462 | 465 | if (item_len < strlen(result[i])) |
| 463 | 466 | break; |
| 464 | − strscpy(pos, result[i], strlen(result[i])); | |
| 467 | + memcpy(pos, result[i], strlen(result[i])); | |
| 465 | 468 | } else { |
| 466 | − strscpy(pos, items[i].name, strlen(items[i].name)); | |
| 469 | + memcpy(pos, items[i].name, strlen(items[i].name)); | |
| 467 | 470 | } |
| 468 | 471 | pos += item_len; |
| 469 | 472 | len -= item_len; |
| @@ -5854,6 +5854,9 @@ void hns3_external_lb_prepare(struct net_device *ndev, bool if_running) · 5853 unmodified lines | ||
| 5854 | 5854 | if (!if_running) |
| 5855 | 5855 | return; |
| 5856 | 5856 | |
| 5857 | + if (test_and_set_bit(HNS3_NIC_STATE_DOWN, &priv->state)) | |
| 5858 | + return; | |
| 5859 | + | |
| 5857 | 5860 | netif_carrier_off(ndev); |
| 5858 | 5861 | netif_tx_disable(ndev); |
| 5859 | 5862 | |
| @@ -5882,7 +5885,16 @@ void hns3_external_lb_restore(struct net_device *ndev, bool if_running) · 22 unmodified lines | ||
| 5882 | 5885 | if (!if_running) |
| 5883 | 5886 | return; |
| 5884 | 5887 | |
| 5885 | − hns3_nic_reset_all_ring(priv->ae_handle); | |
| 5888 | + if (hns3_nic_resetting(ndev)) | |
| 5889 | + return; | |
| 5890 | + | |
| 5891 | + if (!test_bit(HNS3_NIC_STATE_DOWN, &priv->state)) | |
| 5892 | + return; | |
| 5893 | + | |
| 5894 | + if (hns3_nic_reset_all_ring(priv->ae_handle)) | |
| 5895 | + return; | |
| 5896 | + | |
| 5897 | + clear_bit(HNS3_NIC_STATE_DOWN, &priv->state); | |
| 5886 | 5898 | |
| 5887 | 5899 | for (i = 0; i < priv->vector_num; i++) |
| 5888 | 5900 | hns3_vector_enable(&priv->tqp_vector[i]); |
| @@ -52,7 +52,10 @@ static void hclge_tm_info_to_ieee_ets(struct hclge_dev *hdev, · 51 unmodified lines | ||
| 52 | 52 | |
| 53 | 53 | for (i = 0; i < HNAE3_MAX_TC; i++) { |
| 54 | 54 | ets->prio_tc[i] = hdev->tm_info.prio_tc[i]; |
| 55 | − ets->tc_tx_bw[i] = hdev->tm_info.pg_info[0].tc_dwrr[i]; | |
| 55 | + if (i < hdev->tm_info.num_tc) | |
| 56 | + ets->tc_tx_bw[i] = hdev->tm_info.pg_info[0].tc_dwrr[i]; | |
| 57 | + else | |
| 58 | + ets->tc_tx_bw[i] = 0; | |
| 56 | 59 | |
| 57 | 60 | if (hdev->tm_info.tc_info[i].tc_sch_mode == |
| 58 | 61 | HCLGE_SCH_MODE_SP) |
| @@ -123,7 +126,8 @@ static u8 hclge_ets_tc_changed(struct hclge_dev *hdev, struct ieee_ets *ets, · 64 unmodified lines | ||
| 123 | 126 | } |
| 124 | 127 | |
| 125 | 128 | static int hclge_ets_sch_mode_validate(struct hclge_dev *hdev, |
| 126 | − struct ieee_ets *ets, bool *changed) | |
| 129 | + struct ieee_ets *ets, bool *changed, | |
| 130 | + u8 tc_num) | |
| 127 | 131 | { |
| 128 | 132 | bool has_ets_tc = false; |
| 129 | 133 | u32 total_ets_bw = 0; |
| @@ -137,6 +141,13 @@ static int hclge_ets_sch_mode_validate(struct hclge_dev *hdev, · 7 unmodified lines | ||
| 137 | 141 | *changed = true; |
| 138 | 142 | break; |
| 139 | 143 | case IEEE_8021QAZ_TSA_ETS: |
| 144 | + if (i >= tc_num) { | |
| 145 | + dev_err(&hdev->pdev->dev, | |
| 146 | + "tc%u is disabled, cannot set ets bw\n", | |
| 147 | + i); | |
| 148 | + return -EINVAL; | |
| 149 | + } | |
| 150 | + | |
| 140 | 151 | /* The hardware will switch to sp mode if bandwidth is |
| 141 | 152 | * 0, so limit ets bandwidth must be greater than 0. |
| 142 | 153 | */ |
| @@ -176,7 +187,7 @@ static int hclge_ets_validate(struct hclge_dev *hdev, struct ieee_ets *ets, · 33 unmodified lines | ||
| 176 | 187 | if (ret) |
| 177 | 188 | return ret; |
| 178 | 189 | |
| 179 | − ret = hclge_ets_sch_mode_validate(hdev, ets, changed); | |
| 190 | + ret = hclge_ets_sch_mode_validate(hdev, ets, changed, tc_num); | |
| 180 | 191 | if (ret) |
| 181 | 192 | return ret; |
| 182 | 193 | |
| @@ -216,6 +227,10 @@ static int hclge_notify_down_uinit(struct hclge_dev *hdev) · 33 unmodified lines | ||
| 216 | 227 | if (ret) |
| 217 | 228 | return ret; |
| 218 | 229 | |
| 230 | + ret = hclge_tm_flush_cfg(hdev, true); | |
| 231 | + if (ret) | |
| 232 | + return ret; | |
| 233 | + | |
| 219 | 234 | return hclge_notify_client(hdev, HNAE3_UNINIT_CLIENT); |
| 220 | 235 | } |
| 221 | 236 | |
| @@ -227,6 +242,10 @@ static int hclge_notify_init_up(struct hclge_dev *hdev) · 5 unmodified lines | ||
| 227 | 242 | if (ret) |
| 228 | 243 | return ret; |
| 229 | 244 | |
| 245 | + ret = hclge_tm_flush_cfg(hdev, false); | |
| 246 | + if (ret) | |
| 247 | + return ret; | |
| 248 | + | |
| 230 | 249 | return hclge_notify_client(hdev, HNAE3_UP_CLIENT); |
| 231 | 250 | } |
| 232 | 251 | |
| @@ -313,6 +332,7 @@ static int hclge_ieee_setpfc(struct hnae3_handle *h, struct ieee_pfc *pfc) · 80 unmodified lines | ||
| 313 | 332 | struct net_device *netdev = h->kinfo.netdev; |
| 314 | 333 | struct hclge_dev *hdev = vport->back; |
| 315 | 334 | u8 i, j, pfc_map, *prio_tc; |
| 335 | + int last_bad_ret = 0; | |
| 316 | 336 | int ret; |
| 317 | 337 | |
| 318 | 338 | if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) |
| @@ -350,13 +370,28 @@ static int hclge_ieee_setpfc(struct hnae3_handle *h, struct ieee_pfc *pfc) · 31 unmodified lines | ||
| 350 | 370 | if (ret) |
| 351 | 371 | return ret; |
| 352 | 372 | |
| 353 | − ret = hclge_buffer_alloc(hdev); | |
| 354 | − if (ret) { | |
| 355 | − hclge_notify_client(hdev, HNAE3_UP_CLIENT); | |
| 373 | + ret = hclge_tm_flush_cfg(hdev, true); | |
| 374 | + if (ret) | |
| 356 | 375 | return ret; |
| 357 | − } | |
| 358 | 376 | |
| 359 | − return hclge_notify_client(hdev, HNAE3_UP_CLIENT); | |
| 377 | + /* No matter whether the following operations are performed | |
| 378 | + * successfully or not, disabling the tm flush and notify | |
| 379 | + * the network status to up are necessary. | |
| 380 | + * Do not return immediately. | |
| 381 | + */ | |
| 382 | + ret = hclge_buffer_alloc(hdev); | |
| 383 | + if (ret) | |
| 384 | + last_bad_ret = ret; | |
| 385 | + | |
| 386 | + ret = hclge_tm_flush_cfg(hdev, false); | |
| 387 | + if (ret) | |
| 388 | + last_bad_ret = ret; | |
| 389 | + | |
| 390 | + ret = hclge_notify_client(hdev, HNAE3_UP_CLIENT); | |
| 391 | + if (ret) | |
| 392 | + last_bad_ret = ret; | |
| 393 | + | |
| 394 | + return last_bad_ret; | |
| 360 | 395 | } |
| 361 | 396 | |
| 362 | 397 | static int hclge_ieee_setapp(struct hnae3_handle *h, struct dcb_app *app) |
| @@ -111,9 +111,9 @@ static void hclge_dbg_fill_content(char *content, u16 len, · 110 unmodified lines | ||
| 111 | 111 | if (result) { |
| 112 | 112 | if (item_len < strlen(result[i])) |
| 113 | 113 | break; |
| 114 | − strscpy(pos, result[i], strlen(result[i])); | |
| 114 | + memcpy(pos, result[i], strlen(result[i])); | |
| 115 | 115 | } else { |
| 116 | − strscpy(pos, items[i].name, strlen(items[i].name)); | |
| 116 | + memcpy(pos, items[i].name, strlen(items[i].name)); | |
| 117 | 117 | } |
| 118 | 118 | pos += item_len; |
| 119 | 119 | len -= item_len; |
| @@ -693,8 +693,7 @@ static int hclge_dbg_dump_tc(struct hclge_dev *hdev, char *buf, int len) · 573 unmodified lines | ||
| 693 | 693 | for (i = 0; i < HNAE3_MAX_TC; i++) { |
| 694 | 694 | sch_mode_str = ets_weight->tc_weight[i] ? "dwrr" : "sp"; |
| 695 | 695 | pos += scnprintf(buf + pos, len - pos, "%u %4s %3u\n", |
| 696 | − i, sch_mode_str, | |
| 697 | − hdev->tm_info.pg_info[0].tc_dwrr[i]); | |
| 696 | + i, sch_mode_str, ets_weight->tc_weight[i]); | |
| 698 | 697 | } |
| 699 | 698 | |
| 700 | 699 | return 0; |
| @@ -72,6 +72,8 @@ static void hclge_restore_hw_table(struct hclge_dev *hdev); · 71 unmodified lines | ||
| 72 | 72 | static void hclge_sync_promisc_mode(struct hclge_dev *hdev); |
| 73 | 73 | static void hclge_sync_fd_table(struct hclge_dev *hdev); |
| 74 | 74 | static void hclge_update_fec_stats(struct hclge_dev *hdev); |
| 75 | +static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret, | |
| 76 | + int wait_cnt); | |
| 75 | 77 | |
| 76 | 78 | static struct hnae3_ae_algo ae_algo; |
| 77 | 79 | |
| @@ -7558,6 +7560,8 @@ static void hclge_enable_fd(struct hnae3_handle *handle, bool enable) · 7480 unmodified lines | ||
| 7558 | 7560 | |
| 7559 | 7561 | static void hclge_cfg_mac_mode(struct hclge_dev *hdev, bool enable) |
| 7560 | 7562 | { |
| 7563 | +#define HCLGE_LINK_STATUS_WAIT_CNT 3 | |
| 7564 | + | |
| 7561 | 7565 | struct hclge_desc desc; |
| 7562 | 7566 | struct hclge_config_mac_mode_cmd *req = |
| 7563 | 7567 | (struct hclge_config_mac_mode_cmd *)desc.data; |
| @@ -7582,9 +7586,15 @@ static void hclge_cfg_mac_mode(struct hclge_dev *hdev, bool enable) · 18 unmodified lines | ||
| 7582 | 7586 | req->txrx_pad_fcs_loop_en = cpu_to_le32(loop_en); |
| 7583 | 7587 | |
| 7584 | 7588 | ret = hclge_cmd_send(&hdev->hw, &desc, 1); |
| 7585 | − if (ret) | |
| 7589 | + if (ret) { | |
| 7586 | 7590 | dev_err(&hdev->pdev->dev, |
| 7587 | 7591 | "mac enable fail, ret =%d.\n", ret); |
| 7592 | + return; | |
| 7593 | + } | |
| 7594 | + | |
| 7595 | + if (!enable) | |
| 7596 | + hclge_mac_link_status_wait(hdev, HCLGE_LINK_STATUS_DOWN, | |
| 7597 | + HCLGE_LINK_STATUS_WAIT_CNT); | |
| 7588 | 7598 | } |
| 7589 | 7599 | |
| 7590 | 7600 | static int hclge_config_switch_param(struct hclge_dev *hdev, int vfid, |
| @@ -7647,10 +7657,9 @@ static void hclge_phy_link_status_wait(struct hclge_dev *hdev, · 56 unmodified lines | ||
| 7647 | 7657 | } while (++i < HCLGE_PHY_LINK_STATUS_NUM); |
| 7648 | 7658 | } |
| 7649 | 7659 | |
| 7650 | −static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret) | |
| 7660 | +static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret, | |
| 7661 | + int wait_cnt) | |
| 7651 | 7662 | { |
| 7652 | −#define HCLGE_MAC_LINK_STATUS_NUM 100 | |
| 7653 | − | |
| 7654 | 7663 | int link_status; |
| 7655 | 7664 | int i = 0; |
| 7656 | 7665 | int ret; |
| @@ -7663,13 +7672,15 @@ static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret) · 6 unmodified lines | ||
| 7663 | 7672 | return 0; |
| 7664 | 7673 | |
| 7665 | 7674 | msleep(HCLGE_LINK_STATUS_MS); |
| 7666 | − } while (++i < HCLGE_MAC_LINK_STATUS_NUM); | |
| 7675 | + } while (++i < wait_cnt); | |
| 7667 | 7676 | return -EBUSY; |
| 7668 | 7677 | } |
| 7669 | 7678 | |
| 7670 | 7679 | static int hclge_mac_phy_link_status_wait(struct hclge_dev *hdev, bool en, |
| 7671 | 7680 | bool is_phy) |
| 7672 | 7681 | { |
| 7682 | +#define HCLGE_MAC_LINK_STATUS_NUM 100 | |
| 7683 | + | |
| 7673 | 7684 | int link_ret; |
| 7674 | 7685 | |
| 7675 | 7686 | link_ret = en ? HCLGE_LINK_STATUS_UP : HCLGE_LINK_STATUS_DOWN; |
| @@ -7677,7 +7688,8 @@ static int hclge_mac_phy_link_status_wait(struct hclge_dev *hdev, bool en, · 1 unmodified line | ||
| 7677 | 7688 | if (is_phy) |
| 7678 | 7689 | hclge_phy_link_status_wait(hdev, link_ret); |
| 7679 | 7690 | |
| 7680 | − return hclge_mac_link_status_wait(hdev, link_ret); | |
| 7691 | + return hclge_mac_link_status_wait(hdev, link_ret, | |
| 7692 | + HCLGE_MAC_LINK_STATUS_NUM); | |
| 7681 | 7693 | } |
| 7682 | 7694 | |
| 7683 | 7695 | static int hclge_set_app_loopback(struct hclge_dev *hdev, bool en) |
| @@ -10915,9 +10927,12 @@ int hclge_cfg_flowctrl(struct hclge_dev *hdev) · 3231 unmodified lines | ||
| 10915 | 10927 | u32 rx_pause, tx_pause; |
| 10916 | 10928 | u8 flowctl; |
| 10917 | 10929 | |
| 10918 | − if (!phydev->link || !phydev->autoneg) | |
| 10930 | + if (!phydev->link) | |
| 10919 | 10931 | return 0; |
| 10920 | 10932 | |
| 10933 | + if (!phydev->autoneg) | |
| 10934 | + return hclge_mac_pause_setup_hw(hdev); | |
| 10935 | + | |
| 10921 | 10936 | local_advertising = linkmode_adv_to_lcl_adv_t(phydev->advertising); |
| 10922 | 10937 | |
| 10923 | 10938 | if (phydev->pause) |
| @@ -785,6 +785,7 @@ static void hclge_tm_tc_info_init(struct hclge_dev *hdev) · 784 unmodified lines | ||
| 785 | 785 | static void hclge_tm_pg_info_init(struct hclge_dev *hdev) |
| 786 | 786 | { |
| 787 | 787 | #define BW_PERCENT 100 |
| 788 | +#define DEFAULT_BW_WEIGHT 1 | |
| 788 | 789 | |
| 789 | 790 | u8 i; |
| 790 | 791 | |
| @@ -806,7 +807,7 @@ static void hclge_tm_pg_info_init(struct hclge_dev *hdev) · 15 unmodified lines | ||
| 806 | 807 | for (k = 0; k < hdev->tm_info.num_tc; k++) |
| 807 | 808 | hdev->tm_info.pg_info[i].tc_dwrr[k] = BW_PERCENT; |
| 808 | 809 | for (; k < HNAE3_MAX_TC; k++) |
| 809 | − hdev->tm_info.pg_info[i].tc_dwrr[k] = 0; | |
| 810 | + hdev->tm_info.pg_info[i].tc_dwrr[k] = DEFAULT_BW_WEIGHT; | |
| 810 | 811 | } |
| 811 | 812 | } |
| 812 | 813 | |
| @@ -1484,7 +1485,11 @@ int hclge_tm_schd_setup_hw(struct hclge_dev *hdev) · 671 unmodified lines | ||
| 1484 | 1485 | return ret; |
| 1485 | 1486 | |
| 1486 | 1487 | /* Cfg schd mode for each level schd */ |
| 1487 | − return hclge_tm_schd_mode_hw(hdev); | |
| 1488 | + ret = hclge_tm_schd_mode_hw(hdev); | |
| 1489 | + if (ret) | |
| 1490 | + return ret; | |
| 1491 | + | |
| 1492 | + return hclge_tm_flush_cfg(hdev, false); | |
| 1488 | 1493 | } |
| 1489 | 1494 | |
| 1490 | 1495 | static int hclge_pause_param_setup_hw(struct hclge_dev *hdev) |
| @@ -1548,7 +1553,7 @@ static int hclge_bp_setup_hw(struct hclge_dev *hdev, u8 tc) · 57 unmodified lines | ||
| 1548 | 1553 | return 0; |
| 1549 | 1554 | } |
| 1550 | 1555 | |
| 1551 | −static int hclge_mac_pause_setup_hw(struct hclge_dev *hdev) | |
| 1556 | +int hclge_mac_pause_setup_hw(struct hclge_dev *hdev) | |
| 1552 | 1557 | { |
| 1553 | 1558 | bool tx_en, rx_en; |
| 1554 | 1559 | |
| @@ -2113,3 +2118,28 @@ int hclge_tm_get_port_shaper(struct hclge_dev *hdev, · 558 unmodified lines | ||
| 2113 | 2118 | |
| 2114 | 2119 | return 0; |
| 2115 | 2120 | } |
| 2121 | + | |
| 2122 | +int hclge_tm_flush_cfg(struct hclge_dev *hdev, bool enable) | |
| 2123 | +{ | |
| 2124 | + struct hclge_desc desc; | |
| 2125 | + int ret; | |
| 2126 | + | |
| 2127 | + if (!hnae3_ae_dev_tm_flush_supported(hdev)) | |
| 2128 | + return 0; | |
| 2129 | + | |
| 2130 | + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_FLUSH, false); | |
| 2131 | + | |
| 2132 | + desc.data[0] = cpu_to_le32(enable ? HCLGE_TM_FLUSH_EN_MSK : 0); | |
| 2133 | + | |
| 2134 | + ret = hclge_cmd_send(&hdev->hw, &desc, 1); | |
| 2135 | + if (ret) { | |
| 2136 | + dev_err(&hdev->pdev->dev, | |
| 2137 | + "failed to config tm flush, ret = %d\n", ret); | |
| 2138 | + return ret; | |
| 2139 | + } | |
| 2140 | + | |
| 2141 | + if (enable) | |
| 2142 | + msleep(HCLGE_TM_FLUSH_TIME_MS); | |
| 2143 | + | |
| 2144 | + return ret; | |
| 2145 | +} | |
| @@ -33,6 +33,9 @@ enum hclge_opcode_type; · 32 unmodified lines | ||
| 33 | 33 | #define HCLGE_DSCP_MAP_TC_BD_NUM 2 |
| 34 | 34 | #define HCLGE_DSCP_TC_SHIFT(n) (((n) & 1) * 4) |
| 35 | 35 | |
| 36 | +#define HCLGE_TM_FLUSH_TIME_MS 10 | |
| 37 | +#define HCLGE_TM_FLUSH_EN_MSK BIT(0) | |
| 38 | + | |
| 36 | 39 | struct hclge_pg_to_pri_link_cmd { |
| 37 | 40 | u8 pg_id; |
| 38 | 41 | u8 rsvd1[3]; |
| @@ -242,6 +245,7 @@ int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap, · 203 unmodified lines | ||
| 242 | 245 | u8 pfc_bitmap); |
| 243 | 246 | int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx); |
| 244 | 247 | int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr); |
| 248 | +int hclge_mac_pause_setup_hw(struct hclge_dev *hdev); | |
| 245 | 249 | void hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats); |
| 246 | 250 | void hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats); |
| 247 | 251 | int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate); |
| @@ -272,4 +276,5 @@ int hclge_tm_get_port_shaper(struct hclge_dev *hdev, · 24 unmodified lines | ||
| 272 | 276 | struct hclge_tm_shaper_para *para); |
| 273 | 277 | int hclge_up_to_tc_map(struct hclge_dev *hdev); |
| 274 | 278 | int hclge_dscp_to_tc_map(struct hclge_dev *hdev); |
| 279 | +int hclge_tm_flush_cfg(struct hclge_dev *hdev, bool enable); | |
| 275 | 280 | #endif |
| @@ -97,6 +97,8 @@ static int pending_scrq(struct ibmvnic_adapter *, · 96 unmodified lines | ||
| 97 | 97 | static union sub_crq *ibmvnic_next_scrq(struct ibmvnic_adapter *, |
| 98 | 98 | struct ibmvnic_sub_crq_queue *); |
| 99 | 99 | static int ibmvnic_poll(struct napi_struct *napi, int data); |
| 100 | +static int reset_sub_crq_queues(struct ibmvnic_adapter *adapter); | |
| 101 | +static inline void reinit_init_done(struct ibmvnic_adapter *adapter); | |
| 100 | 102 | static void send_query_map(struct ibmvnic_adapter *adapter); |
| 101 | 103 | static int send_request_map(struct ibmvnic_adapter *, dma_addr_t, u32, u8); |
| 102 | 104 | static int send_request_unmap(struct ibmvnic_adapter *, u8); |
| @@ -114,6 +116,7 @@ static void ibmvnic_tx_scrq_clean_buffer(struct ibmvnic_adapter *adapter, · 11 unmodified lines | ||
| 114 | 116 | static void free_long_term_buff(struct ibmvnic_adapter *adapter, |
| 115 | 117 | struct ibmvnic_long_term_buff *ltb); |
| 116 | 118 | static void ibmvnic_disable_irqs(struct ibmvnic_adapter *adapter); |
| 119 | +static void flush_reset_queue(struct ibmvnic_adapter *adapter); | |
| 117 | 120 | |
| 118 | 121 | struct ibmvnic_stat { |
| 119 | 122 | char name[ETH_GSTRING_LEN]; |
| @@ -1505,8 +1508,8 @@ static const char *adapter_state_to_string(enum vnic_state state) · 1385 unmodified lines | ||
| 1505 | 1508 | |
| 1506 | 1509 | static int ibmvnic_login(struct net_device *netdev) |
| 1507 | 1510 | { |
| 1511 | + unsigned long flags, timeout = msecs_to_jiffies(20000); | |
| 1508 | 1512 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); |
| 1509 | − unsigned long timeout = msecs_to_jiffies(20000); | |
| 1510 | 1513 | int retry_count = 0; |
| 1511 | 1514 | int retries = 10; |
| 1512 | 1515 | bool retry; |
| @@ -1527,11 +1530,9 @@ static int ibmvnic_login(struct net_device *netdev) · 14 unmodified lines | ||
| 1527 | 1530 | |
| 1528 | 1531 | if (!wait_for_completion_timeout(&adapter->init_done, |
| 1529 | 1532 | timeout)) { |
| 1530 | − netdev_warn(netdev, "Login timed out, retrying...\n"); | |
| 1531 | − retry = true; | |
| 1532 | − adapter->init_done_rc = 0; | |
| 1533 | − retry_count++; | |
| 1534 | − continue; | |
| 1533 | + netdev_warn(netdev, "Login timed out\n"); | |
| 1534 | + adapter->login_pending = false; | |
| 1535 | + goto partial_reset; | |
| 1535 | 1536 | } |
| 1536 | 1537 | |
| 1537 | 1538 | if (adapter->init_done_rc == ABORTED) { |
| @@ -1573,10 +1574,69 @@ static int ibmvnic_login(struct net_device *netdev) · 35 unmodified lines | ||
| 1573 | 1574 | "SCRQ irq initialization failed\n"); |
| 1574 | 1575 | return rc; |
| 1575 | 1576 | } |
| 1577 | + /* Default/timeout error handling, reset and start fresh */ | |
| 1576 | 1578 | } else if (adapter->init_done_rc) { |
| 1577 | 1579 | netdev_warn(netdev, "Adapter login failed, init_done_rc = %d\n", |
| 1578 | 1580 | adapter->init_done_rc); |
| 1579 | − return -EIO; | |
| 1581 | + | |
| 1582 | +partial_reset: | |
| 1583 | + /* adapter login failed, so free any CRQs or sub-CRQs | |
| 1584 | + * and register again before attempting to login again. | |
| 1585 | + * If we don't do this then the VIOS may think that | |
| 1586 | + * we are already logged in and reject any subsequent | |
| 1587 | + * attempts | |
| 1588 | + */ | |
| 1589 | + netdev_warn(netdev, | |
| 1590 | + "Freeing and re-registering CRQs before attempting to login again\n"); | |
| 1591 | + retry = true; | |
| 1592 | + adapter->init_done_rc = 0; | |
| 1593 | + release_sub_crqs(adapter, true); | |
| 1594 | + /* Much of this is similar logic as ibmvnic_probe(), | |
| 1595 | + * we are essentially re-initializing communication | |
| 1596 | + * with the server. We really should not run any | |
| 1597 | + * resets/failovers here because this is already a form | |
| 1598 | + * of reset and we do not want parallel resets occurring | |
| 1599 | + */ | |
| 1600 | + do { | |
| 1601 | + reinit_init_done(adapter); | |
| 1602 | + /* Clear any failovers we got in the previous | |
| 1603 | + * pass since we are re-initializing the CRQ | |
| 1604 | + */ | |
| 1605 | + adapter->failover_pending = false; | |
| 1606 | + release_crq_queue(adapter); | |
| 1607 | + /* If we don't sleep here then we risk an | |
| 1608 | + * unnecessary failover event from the VIOS. | |
| 1609 | + * This is a known VIOS issue caused by a vnic | |
| 1610 | + * device freeing and registering a CRQ too | |
| 1611 | + * quickly. | |
| 1612 | + */ | |
| 1613 | + msleep(1500); | |
| 1614 | + /* Avoid any resets, since we are currently | |
| 1615 | + * resetting. | |
| 1616 | + */ | |
| 1617 | + spin_lock_irqsave(&adapter->rwi_lock, flags); | |
| 1618 | + flush_reset_queue(adapter); | |
| 1619 | + spin_unlock_irqrestore(&adapter->rwi_lock, | |
| 1620 | + flags); | |
| 1621 | + | |
| 1622 | + rc = init_crq_queue(adapter); | |
| 1623 | + if (rc) { | |
| 1624 | + netdev_err(netdev, "login recovery: init CRQ failed %d\n", | |
| 1625 | + rc); | |
| 1626 | + return -EIO; | |
| 1627 | + } | |
| 1628 | + | |
| 1629 | + rc = ibmvnic_reset_init(adapter, false); | |
| 1630 | + if (rc) | |
| 1631 | + netdev_err(netdev, "login recovery: Reset init failed %d\n", | |
| 1632 | + rc); | |
| 1633 | + /* IBMVNIC_CRQ_INIT will return EAGAIN if it | |
| 1634 | + * fails, since ibmvnic_reset_init will free | |
| 1635 | + * irq's in failure, we won't be able to receive | |
| 1636 | + * new CRQs so we need to keep trying. probe() | |
| 1637 | + * handles this similarly. | |
| 1638 | + */ | |
| 1639 | + } while (rc == -EAGAIN && retry_count++ < retries); | |
| 1580 | 1640 | } |
| 1581 | 1641 | } while (retry); |
| 1582 | 1642 | |
| @@ -1588,12 +1648,22 @@ static int ibmvnic_login(struct net_device *netdev) · 5 unmodified lines | ||
| 1588 | 1648 | |
| 1589 | 1649 | static void release_login_buffer(struct ibmvnic_adapter *adapter) |
| 1590 | 1650 | { |
| 1651 | + if (!adapter->login_buf) | |
| 1652 | + return; | |
| 1653 | + | |
| 1654 | + dma_unmap_single(&adapter->vdev->dev, adapter->login_buf_token, | |
| 1655 | + adapter->login_buf_sz, DMA_TO_DEVICE); | |
| 1591 | 1656 | kfree(adapter->login_buf); |
| 1592 | 1657 | adapter->login_buf = NULL; |
| 1593 | 1658 | } |
| 1594 | 1659 | |
| 1595 | 1660 | static void release_login_rsp_buffer(struct ibmvnic_adapter *adapter) |
| 1596 | 1661 | { |
| 1662 | + if (!adapter->login_rsp_buf) | |
| 1663 | + return; | |
| 1664 | + | |
| 1665 | + dma_unmap_single(&adapter->vdev->dev, adapter->login_rsp_buf_token, | |
| 1666 | + adapter->login_rsp_buf_sz, DMA_FROM_DEVICE); | |
| 1597 | 1667 | kfree(adapter->login_rsp_buf); |
| 1598 | 1668 | adapter->login_rsp_buf = NULL; |
| 1599 | 1669 | } |
| @@ -4830,11 +4900,14 @@ static int send_login(struct ibmvnic_adapter *adapter) · 3230 unmodified lines | ||
| 4830 | 4900 | if (rc) { |
| 4831 | 4901 | adapter->login_pending = false; |
| 4832 | 4902 | netdev_err(adapter->netdev, "Failed to send login, rc=%d\n", rc); |
| 4833 | − goto buf_rsp_map_failed; | |
| 4903 | + goto buf_send_failed; | |
| 4834 | 4904 | } |
| 4835 | 4905 | |
| 4836 | 4906 | return 0; |
| 4837 | 4907 | |
| 4908 | +buf_send_failed: | |
| 4909 | + dma_unmap_single(dev, rsp_buffer_token, rsp_buffer_size, | |
| 4910 | + DMA_FROM_DEVICE); | |
| 4838 | 4911 | buf_rsp_map_failed: |
| 4839 | 4912 | kfree(login_rsp_buffer); |
| 4840 | 4913 | adapter->login_rsp_buf = NULL; |
| @@ -5396,6 +5469,7 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq, · 555 unmodified lines | ||
| 5396 | 5469 | int num_tx_pools; |
| 5397 | 5470 | int num_rx_pools; |
| 5398 | 5471 | u64 *size_array; |
| 5472 | + u32 rsp_len; | |
| 5399 | 5473 | int i; |
| 5400 | 5474 | |
| 5401 | 5475 | /* CHECK: Test/set of login_pending does not need to be atomic |
| @@ -5407,11 +5481,6 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq, · 5 unmodified lines | ||
| 5407 | 5481 | } |
| 5408 | 5482 | adapter->login_pending = false; |
| 5409 | 5483 | |
| 5410 | − dma_unmap_single(dev, adapter->login_buf_token, adapter->login_buf_sz, | |
| 5411 | − DMA_TO_DEVICE); | |
| 5412 | − dma_unmap_single(dev, adapter->login_rsp_buf_token, | |
| 5413 | − adapter->login_rsp_buf_sz, DMA_FROM_DEVICE); | |
| 5414 | − | |
| 5415 | 5484 | /* If the number of queues requested can't be allocated by the |
| 5416 | 5485 | * server, the login response will return with code 1. We will need |
| 5417 | 5486 | * to resend the login buffer with fewer queues requested. |
| @@ -5447,6 +5516,23 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq, · 29 unmodified lines | ||
| 5447 | 5516 | ibmvnic_reset(adapter, VNIC_RESET_FATAL); |
| 5448 | 5517 | return -EIO; |
| 5449 | 5518 | } |
| 5519 | + | |
| 5520 | + rsp_len = be32_to_cpu(login_rsp->len); | |
| 5521 | + if (be32_to_cpu(login->login_rsp_len) < rsp_len || | |
| 5522 | + rsp_len <= be32_to_cpu(login_rsp->off_txsubm_subcrqs) || | |
| 5523 | + rsp_len <= be32_to_cpu(login_rsp->off_rxadd_subcrqs) || | |
| 5524 | + rsp_len <= be32_to_cpu(login_rsp->off_rxadd_buff_size) || | |
| 5525 | + rsp_len <= be32_to_cpu(login_rsp->off_supp_tx_desc)) { | |
| 5526 | + /* This can happen if a login request times out and there are | |
| 5527 | + * 2 outstanding login requests sent, the LOGIN_RSP crq | |
| 5528 | + * could have been for the older login request. So we are | |
| 5529 | + * parsing the newer response buffer which may be incomplete | |
| 5530 | + */ | |
| 5531 | + dev_err(dev, "FATAL: Login rsp offsets/lengths invalid\n"); | |
| 5532 | + ibmvnic_reset(adapter, VNIC_RESET_FATAL); | |
| 5533 | + return -EIO; | |
| 5534 | + } | |
| 5535 | + | |
| 5450 | 5536 | size_array = (u64 *)((u8 *)(adapter->login_rsp_buf) + |
| 5451 | 5537 | be32_to_cpu(adapter->login_rsp_buf->off_rxadd_buff_size)); |
| 5452 | 5538 | /* variable buffer sizes are not supported, so just read the |
| @@ -1839,7 +1839,7 @@ void i40e_dbg_pf_exit(struct i40e_pf *pf) · 1838 unmodified lines | ||
| 1839 | 1839 | void i40e_dbg_init(void) |
| 1840 | 1840 | { |
| 1841 | 1841 | i40e_dbg_root = debugfs_create_dir(i40e_driver_name, NULL); |
| 1842 | − if (!i40e_dbg_root) | |
| 1842 | + if (IS_ERR(i40e_dbg_root)) | |
| 1843 | 1843 | pr_info("init of debugfs failed\n"); |
| 1844 | 1844 | } |
| 1845 | 1845 | |
| @@ -1401,14 +1401,15 @@ static int iavf_add_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx · 1400 unmodified lines | ||
| 1401 | 1401 | if (fsp->flow_type & FLOW_MAC_EXT) |
| 1402 | 1402 | return -EINVAL; |
| 1403 | 1403 | |
| 1404 | + spin_lock_bh(&adapter->fdir_fltr_lock); | |
| 1404 | 1405 | if (adapter->fdir_active_fltr >= IAVF_MAX_FDIR_FILTERS) { |
| 1406 | + spin_unlock_bh(&adapter->fdir_fltr_lock); | |
| 1405 | 1407 | dev_err(&adapter->pdev->dev, |
| 1406 | 1408 | "Unable to add Flow Director filter because VF reached the limit of max allowed filters (%u)\n", |
| 1407 | 1409 | IAVF_MAX_FDIR_FILTERS); |
| 1408 | 1410 | return -ENOSPC; |
| 1409 | 1411 | } |
| 1410 | 1412 | |
| 1411 | − spin_lock_bh(&adapter->fdir_fltr_lock); | |
| 1412 | 1413 | if (iavf_find_fdir_fltr_by_loc(adapter, fsp->location)) { |
| 1413 | 1414 | dev_err(&adapter->pdev->dev, "Failed to add Flow Director filter, it already exists\n"); |
| 1414 | 1415 | spin_unlock_bh(&adapter->fdir_fltr_lock); |
| @@ -1781,7 +1782,9 @@ static int iavf_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd, · 366 unmodified lines | ||
| 1781 | 1782 | case ETHTOOL_GRXCLSRLCNT: |
| 1782 | 1783 | if (!FDIR_FLTR_SUPPORT(adapter)) |
| 1783 | 1784 | break; |
| 1785 | + spin_lock_bh(&adapter->fdir_fltr_lock); | |
| 1784 | 1786 | cmd->rule_cnt = adapter->fdir_active_fltr; |
| 1787 | + spin_unlock_bh(&adapter->fdir_fltr_lock); | |
| 1785 | 1788 | cmd->data = IAVF_MAX_FDIR_FILTERS; |
| 1786 | 1789 | ret = 0; |
| 1787 | 1790 | break; |
| @@ -722,7 +722,9 @@ void iavf_print_fdir_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *f · 721 unmodified lines | ||
| 722 | 722 | bool iavf_fdir_is_dup_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *fltr) |
| 723 | 723 | { |
| 724 | 724 | struct iavf_fdir_fltr *tmp; |
| 725 | + bool ret = false; | |
| 725 | 726 | |
| 727 | + spin_lock_bh(&adapter->fdir_fltr_lock); | |
| 726 | 728 | list_for_each_entry(tmp, &adapter->fdir_list_head, list) { |
| 727 | 729 | if (tmp->flow_type != fltr->flow_type) |
| 728 | 730 | continue; |
| @@ -732,11 +734,14 @@ bool iavf_fdir_is_dup_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr * · 3 unmodified lines | ||
| 732 | 734 | !memcmp(&tmp->ip_data, &fltr->ip_data, |
| 733 | 735 | sizeof(fltr->ip_data)) && |
| 734 | 736 | !memcmp(&tmp->ext_data, &fltr->ext_data, |
| 735 | − sizeof(fltr->ext_data))) | |
| 736 | − return true; | |
| 737 | + sizeof(fltr->ext_data))) { | |
| 738 | + ret = true; | |
| 739 | + break; | |
| 740 | + } | |
| 737 | 741 | } |
| 742 | + spin_unlock_bh(&adapter->fdir_fltr_lock); | |
| 738 | 743 | |
| 739 | − return false; | |
| 744 | + return ret; | |
| 740 | 745 | } |
| 741 | 746 | |
| 742 | 747 | /** |
| @@ -3250,9 +3250,6 @@ static void iavf_adminq_task(struct work_struct *work) · 3249 unmodified lines | ||
| 3250 | 3250 | u32 val, oldval; |
| 3251 | 3251 | u16 pending; |
| 3252 | 3252 | |
| 3253 | − if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) | |
| 3254 | − goto out; | |
| 3255 | − | |
| 3256 | 3253 | if (!mutex_trylock(&adapter->crit_lock)) { |
| 3257 | 3254 | if (adapter->state == __IAVF_REMOVE) |
| 3258 | 3255 | return; |
| @@ -3261,10 +3258,13 @@ static void iavf_adminq_task(struct work_struct *work) · 2 unmodified lines | ||
| 3261 | 3258 | goto out; |
| 3262 | 3259 | } |
| 3263 | 3260 | |
| 3261 | + if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) | |
| 3262 | + goto unlock; | |
| 3263 | + | |
| 3264 | 3264 | event.buf_len = IAVF_MAX_AQ_BUF_SIZE; |
| 3265 | 3265 | event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL); |
| 3266 | 3266 | if (!event.msg_buf) |
| 3267 | − goto out; | |
| 3267 | + goto unlock; | |
| 3268 | 3268 | |
| 3269 | 3269 | do { |
| 3270 | 3270 | ret = iavf_clean_arq_element(hw, &event, &pending); |
| @@ -3279,7 +3279,6 @@ static void iavf_adminq_task(struct work_struct *work) · 8 unmodified lines | ||
| 3279 | 3279 | if (pending != 0) |
| 3280 | 3280 | memset(event.msg_buf, 0, IAVF_MAX_AQ_BUF_SIZE); |
| 3281 | 3281 | } while (pending); |
| 3282 | − mutex_unlock(&adapter->crit_lock); | |
| 3283 | 3282 | |
| 3284 | 3283 | if (iavf_is_reset_in_progress(adapter)) |
| 3285 | 3284 | goto freedom; |
| @@ -3323,6 +3322,8 @@ static void iavf_adminq_task(struct work_struct *work) · 37 unmodified lines | ||
| 3323 | 3322 | |
| 3324 | 3323 | freedom: |
| 3325 | 3324 | kfree(event.msg_buf); |
| 3325 | +unlock: | |
| 3326 | + mutex_unlock(&adapter->crit_lock); | |
| 3326 | 3327 | out: |
| 3327 | 3328 | /* re-enable Admin queue interrupt cause */ |
| 3328 | 3329 | iavf_misc_irq_enable(adapter); |
| @@ -1281,16 +1281,21 @@ ice_cfg_fdir_xtrct_seq(struct ice_pf *pf, struct ethtool_rx_flow_spec *fsp, · 1280 unmodified lines | ||
| 1281 | 1281 | ICE_FLOW_FLD_OFF_INVAL); |
| 1282 | 1282 | } |
| 1283 | 1283 | |
| 1284 | − /* add filter for outer headers */ | |
| 1285 | 1284 | fltr_idx = ice_ethtool_flow_to_fltr(fsp->flow_type & ~FLOW_EXT); |
| 1285 | + | |
| 1286 | + assign_bit(fltr_idx, hw->fdir_perfect_fltr, perfect_filter); | |
| 1287 | + | |
| 1288 | + /* add filter for outer headers */ | |
| 1286 | 1289 | ret = ice_fdir_set_hw_fltr_rule(pf, seg, fltr_idx, |
| 1287 | 1290 | ICE_FD_HW_SEG_NON_TUN); |
| 1288 | − if (ret == -EEXIST) | |
| 1289 | − /* Rule already exists, free memory and continue */ | |
| 1290 | − devm_kfree(dev, seg); | |
| 1291 | − else if (ret) | |
| 1291 | + if (ret == -EEXIST) { | |
| 1292 | + /* Rule already exists, free memory and count as success */ | |
| 1293 | + ret = 0; | |
| 1294 | + goto err_exit; | |
| 1295 | + } else if (ret) { | |
| 1292 | 1296 | /* could not write filter, free memory */ |
| 1293 | 1297 | goto err_exit; |
| 1298 | + } | |
| 1294 | 1299 | |
| 1295 | 1300 | /* make tunneled filter HW entries if possible */ |
| 1296 | 1301 | memcpy(&tun_seg[1], seg, sizeof(*seg)); |
| @@ -1305,18 +1310,13 @@ ice_cfg_fdir_xtrct_seq(struct ice_pf *pf, struct ethtool_rx_flow_spec *fsp, · 8 unmodified lines | ||
| 1305 | 1310 | devm_kfree(dev, tun_seg); |
| 1306 | 1311 | } |
| 1307 | 1312 | |
| 1308 | − if (perfect_filter) | |
| 1309 | − set_bit(fltr_idx, hw->fdir_perfect_fltr); | |
| 1310 | − else | |
| 1311 | − clear_bit(fltr_idx, hw->fdir_perfect_fltr); | |
| 1312 | − | |
| 1313 | 1313 | return ret; |
| 1314 | 1314 | |
| 1315 | 1315 | err_exit: |
| 1316 | 1316 | devm_kfree(dev, tun_seg); |
| 1317 | 1317 | devm_kfree(dev, seg); |
| 1318 | 1318 | |
| 1319 | − return -EOPNOTSUPP; | |
| 1319 | + return ret; | |
| 1320 | 1320 | } |
| 1321 | 1321 | |
| 1322 | 1322 | /** |
| @@ -1914,7 +1914,9 @@ int ice_add_fdir_ethtool(struct ice_vsi *vsi, struct ethtool_rxnfc *cmd) · 591 unmodified lines | ||
| 1914 | 1914 | input->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL; |
| 1915 | 1915 | |
| 1916 | 1916 | /* input struct is added to the HW filter list */ |
| 1917 | − ice_fdir_update_list_entry(pf, input, fsp->location); | |
| 1917 | + ret = ice_fdir_update_list_entry(pf, input, fsp->location); | |
| 1918 | + if (ret) | |
| 1919 | + goto release_lock; | |
| 1918 | 1920 | |
| 1919 | 1921 | ret = ice_fdir_write_all_fltr(pf, input, true); |
| 1920 | 1922 | if (ret) |
| @@ -8813,6 +8813,7 @@ ice_setup_tc(struct net_device *netdev, enum tc_setup_type type, · 8812 unmodified lines | ||
| 8813 | 8813 | { |
| 8814 | 8814 | struct ice_netdev_priv *np = netdev_priv(netdev); |
| 8815 | 8815 | struct ice_pf *pf = np->vsi->back; |
| 8816 | + bool locked = false; | |
| 8816 | 8817 | int err; |
| 8817 | 8818 | |
| 8818 | 8819 | switch (type) { |
| @@ -8822,10 +8823,27 @@ ice_setup_tc(struct net_device *netdev, enum tc_setup_type type, · 3 unmodified lines | ||
| 8822 | 8823 | ice_setup_tc_block_cb, |
| 8823 | 8824 | np, np, true); |
| 8824 | 8825 | case TC_SETUP_QDISC_MQPRIO: |
| 8826 | + if (pf->adev) { | |
| 8827 | + mutex_lock(&pf->adev_mutex); | |
| 8828 | + device_lock(&pf->adev->dev); | |
| 8829 | + locked = true; | |
| 8830 | + if (pf->adev->dev.driver) { | |
| 8831 | + netdev_err(netdev, "Cannot change qdisc when RDMA is active\n"); | |
| 8832 | + err = -EBUSY; | |
| 8833 | + goto adev_unlock; | |
| 8834 | + } | |
| 8835 | + } | |
| 8836 | + | |
| 8825 | 8837 | /* setup traffic classifier for receive side */ |
| 8826 | 8838 | mutex_lock(&pf->tc_mutex); |
| 8827 | 8839 | err = ice_setup_tc_mqprio_qdisc(netdev, type_data); |
| 8828 | 8840 | mutex_unlock(&pf->tc_mutex); |
| 8841 | + | |
| 8842 | +adev_unlock: | |
| 8843 | + if (locked) { | |
| 8844 | + device_unlock(&pf->adev->dev); | |
| 8845 | + mutex_unlock(&pf->adev_mutex); | |
| 8846 | + } | |
| 8829 | 8847 | return err; |
| 8830 | 8848 | default: |
| 8831 | 8849 | return -EOPNOTSUPP; |
| @@ -195,6 +195,10 @@ struct igc_adapter { · 194 unmodified lines | ||
| 195 | 195 | u32 qbv_config_change_errors; |
| 196 | 196 | bool qbv_transition; |
| 197 | 197 | unsigned int qbv_count; |
| 198 | + /* Access to oper_gate_closed, admin_gate_closed and qbv_transition | |
| 199 | + * are protected by the qbv_tx_lock. | |
| 200 | + */ | |
| 201 | + spinlock_t qbv_tx_lock; | |
| 198 | 202 | |
| 199 | 203 | /* OS defined structs */ |
| 200 | 204 | struct pci_dev *pdev; |
| @@ -316,6 +316,33 @@ static void igc_clean_all_tx_rings(struct igc_adapter *adapter) · 315 unmodified lines | ||
| 316 | 316 | igc_clean_tx_ring(adapter->tx_ring[i]); |
| 317 | 317 | } |
| 318 | 318 | |
| 319 | +static void igc_disable_tx_ring_hw(struct igc_ring *ring) | |
| 320 | +{ | |
| 321 | + struct igc_hw *hw = &ring->q_vector->adapter->hw; | |
| 322 | + u8 idx = ring->reg_idx; | |
| 323 | + u32 txdctl; | |
| 324 | + | |
| 325 | + txdctl = rd32(IGC_TXDCTL(idx)); | |
| 326 | + txdctl &= ~IGC_TXDCTL_QUEUE_ENABLE; | |
| 327 | + txdctl |= IGC_TXDCTL_SWFLUSH; | |
| 328 | + wr32(IGC_TXDCTL(idx), txdctl); | |
| 329 | +} | |
| 330 | + | |
| 331 | +/** | |
| 332 | + * igc_disable_all_tx_rings_hw - Disable all transmit queue operation | |
| 333 | + * @adapter: board private structure | |
| 334 | + */ | |
| 335 | +static void igc_disable_all_tx_rings_hw(struct igc_adapter *adapter) | |
| 336 | +{ | |
| 337 | + int i; | |
| 338 | + | |
| 339 | + for (i = 0; i < adapter->num_tx_queues; i++) { | |
| 340 | + struct igc_ring *tx_ring = adapter->tx_ring[i]; | |
| 341 | + | |
| 342 | + igc_disable_tx_ring_hw(tx_ring); | |
| 343 | + } | |
| 344 | +} | |
| 345 | + | |
| 319 | 346 | /** |
| 320 | 347 | * igc_setup_tx_resources - allocate Tx resources (Descriptors) |
| 321 | 348 | * @tx_ring: tx descriptor ring (for a specific queue) to setup |
| @@ -4774,6 +4801,7 @@ static int igc_sw_init(struct igc_adapter *adapter) · 4452 unmodified lines | ||
| 4774 | 4801 | adapter->nfc_rule_count = 0; |
| 4775 | 4802 | |
| 4776 | 4803 | spin_lock_init(&adapter->stats64_lock); |
| 4804 | + spin_lock_init(&adapter->qbv_tx_lock); | |
| 4777 | 4805 | /* Assume MSI-X interrupts, will be checked during IRQ allocation */ |
| 4778 | 4806 | adapter->flags |= IGC_FLAG_HAS_MSIX; |
| 4779 | 4807 | |
| @@ -5058,6 +5086,7 @@ void igc_down(struct igc_adapter *adapter) · 278 unmodified lines | ||
| 5058 | 5086 | /* clear VLAN promisc flag so VFTA will be updated if necessary */ |
| 5059 | 5087 | adapter->flags &= ~IGC_FLAG_VLAN_PROMISC; |
| 5060 | 5088 | |
| 5089 | + igc_disable_all_tx_rings_hw(adapter); | |
| 5061 | 5090 | igc_clean_all_tx_rings(adapter); |
| 5062 | 5091 | igc_clean_all_rx_rings(adapter); |
| 5063 | 5092 | } |
| @@ -6091,15 +6120,15 @@ static int igc_tsn_enable_launchtime(struct igc_adapter *adapter, · 1027 unmodified lines | ||
| 6091 | 6120 | return igc_tsn_offload_apply(adapter); |
| 6092 | 6121 | } |
| 6093 | 6122 | |
| 6094 | −static int igc_tsn_clear_schedule(struct igc_adapter *adapter) | |
| 6123 | +static int igc_qbv_clear_schedule(struct igc_adapter *adapter) | |
| 6095 | 6124 | { |
| 6125 | + unsigned long flags; | |
| 6096 | 6126 | int i; |
| 6097 | 6127 | |
| 6098 | 6128 | adapter->base_time = 0; |
| 6099 | 6129 | adapter->cycle_time = NSEC_PER_SEC; |
| 6100 | 6130 | adapter->taprio_offload_enable = false; |
| 6101 | 6131 | adapter->qbv_config_change_errors = 0; |
| 6102 | − adapter->qbv_transition = false; | |
| 6103 | 6132 | adapter->qbv_count = 0; |
| 6104 | 6133 | |
| 6105 | 6134 | for (i = 0; i < adapter->num_tx_queues; i++) { |
| @@ -6108,10 +6137,28 @@ static int igc_tsn_clear_schedule(struct igc_adapter *adapter) · 2 unmodified lines | ||
| 6108 | 6137 | ring->start_time = 0; |
| 6109 | 6138 | ring->end_time = NSEC_PER_SEC; |
| 6110 | 6139 | ring->max_sdu = 0; |
| 6140 | + } | |
| 6141 | + | |
| 6142 | + spin_lock_irqsave(&adapter->qbv_tx_lock, flags); | |
| 6143 | + | |
| 6144 | + adapter->qbv_transition = false; | |
| 6145 | + | |
| 6146 | + for (i = 0; i < adapter->num_tx_queues; i++) { | |
| 6147 | + struct igc_ring *ring = adapter->tx_ring[i]; | |
| 6148 | + | |
| 6111 | 6149 | ring->oper_gate_closed = false; |
| 6112 | 6150 | ring->admin_gate_closed = false; |
| 6113 | 6151 | } |
| 6114 | 6152 | |
| 6153 | + spin_unlock_irqrestore(&adapter->qbv_tx_lock, flags); | |
| 6154 | + | |
| 6155 | + return 0; | |
| 6156 | +} | |
| 6157 | + | |
| 6158 | +static int igc_tsn_clear_schedule(struct igc_adapter *adapter) | |
| 6159 | +{ | |
| 6160 | + igc_qbv_clear_schedule(adapter); | |
| 6161 | + | |
| 6115 | 6162 | return 0; |
| 6116 | 6163 | } |
| 6117 | 6164 | |
| @@ -6122,6 +6169,7 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter, · 4 unmodified lines | ||
| 6122 | 6169 | struct igc_hw *hw = &adapter->hw; |
| 6123 | 6170 | u32 start_time = 0, end_time = 0; |
| 6124 | 6171 | struct timespec64 now; |
| 6172 | + unsigned long flags; | |
| 6125 | 6173 | size_t n; |
| 6126 | 6174 | int i; |
| 6127 | 6175 | |
| @@ -6189,6 +6237,8 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter, · 61 unmodified lines | ||
| 6189 | 6237 | start_time += e->interval; |
| 6190 | 6238 | } |
| 6191 | 6239 | |
| 6240 | + spin_lock_irqsave(&adapter->qbv_tx_lock, flags); | |
| 6241 | + | |
| 6192 | 6242 | /* Check whether a queue gets configured. |
| 6193 | 6243 | * If not, set the start and end time to be end time. |
| 6194 | 6244 | */ |
| @@ -6213,6 +6263,8 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter, · 18 unmodified lines | ||
| 6213 | 6263 | } |
| 6214 | 6264 | } |
| 6215 | 6265 | |
| 6266 | + spin_unlock_irqrestore(&adapter->qbv_tx_lock, flags); | |
| 6267 | + | |
| 6216 | 6268 | for (i = 0; i < adapter->num_tx_queues; i++) { |
| 6217 | 6269 | struct igc_ring *ring = adapter->tx_ring[i]; |
| 6218 | 6270 | struct net_device *dev = adapter->netdev; |
| @@ -6591,8 +6643,11 @@ static enum hrtimer_restart igc_qbv_scheduling_timer(struct hrtimer *timer) · 372 unmodified lines | ||
| 6591 | 6643 | { |
| 6592 | 6644 | struct igc_adapter *adapter = container_of(timer, struct igc_adapter, |
| 6593 | 6645 | hrtimer); |
| 6646 | + unsigned long flags; | |
| 6594 | 6647 | unsigned int i; |
| 6595 | 6648 | |
| 6649 | + spin_lock_irqsave(&adapter->qbv_tx_lock, flags); | |
| 6650 | + | |
| 6596 | 6651 | adapter->qbv_transition = true; |
| 6597 | 6652 | for (i = 0; i < adapter->num_tx_queues; i++) { |
| 6598 | 6653 | struct igc_ring *tx_ring = adapter->tx_ring[i]; |
| @@ -6605,6 +6660,9 @@ static enum hrtimer_restart igc_qbv_scheduling_timer(struct hrtimer *timer) · 6 unmodified lines | ||
| 6605 | 6660 | } |
| 6606 | 6661 | } |
| 6607 | 6662 | adapter->qbv_transition = false; |
| 6663 | + | |
| 6664 | + spin_unlock_irqrestore(&adapter->qbv_tx_lock, flags); | |
| 6665 | + | |
| 6608 | 6666 | return HRTIMER_NORESTART; |
| 6609 | 6667 | } |
| 6610 | 6668 | |
| @@ -7290,18 +7348,6 @@ void igc_enable_rx_ring(struct igc_ring *ring) · 679 unmodified lines | ||
| 7290 | 7348 | igc_alloc_rx_buffers(ring, igc_desc_unused(ring)); |
| 7291 | 7349 | } |
| 7292 | 7350 | |
| 7293 | −static void igc_disable_tx_ring_hw(struct igc_ring *ring) | |
| 7294 | −{ | |
| 7295 | − struct igc_hw *hw = &ring->q_vector->adapter->hw; | |
| 7296 | − u8 idx = ring->reg_idx; | |
| 7297 | − u32 txdctl; | |
| 7298 | − | |
| 7299 | − txdctl = rd32(IGC_TXDCTL(idx)); | |
| 7300 | − txdctl &= ~IGC_TXDCTL_QUEUE_ENABLE; | |
| 7301 | − txdctl |= IGC_TXDCTL_SWFLUSH; | |
| 7302 | − wr32(IGC_TXDCTL(idx), txdctl); | |
| 7303 | −} | |
| 7304 | − | |
| 7305 | 7351 | void igc_disable_tx_ring(struct igc_ring *ring) |
| 7306 | 7352 | { |
| 7307 | 7353 | igc_disable_tx_ring_hw(ring); |
| @@ -8479,7 +8479,7 @@ static void ixgbe_atr(struct ixgbe_ring *ring, · 8478 unmodified lines | ||
| 8479 | 8479 | struct ixgbe_adapter *adapter = q_vector->adapter; |
| 8480 | 8480 | |
| 8481 | 8481 | if (unlikely(skb_tail_pointer(skb) < hdr.network + |
| 8482 | − VXLAN_HEADROOM)) | |
| 8482 | + vxlan_headroom(0))) | |
| 8483 | 8483 | return; |
| 8484 | 8484 | |
| 8485 | 8485 | /* verify the port is recognized as VXLAN */ |
| @@ -1302,11 +1302,10 @@ static int korina_probe(struct platform_device *pdev) · 1301 unmodified lines | ||
| 1302 | 1302 | else if (of_get_ethdev_address(pdev->dev.of_node, dev) < 0) |
| 1303 | 1303 | eth_hw_addr_random(dev); |
| 1304 | 1304 | |
| 1305 | − clk = devm_clk_get_optional(&pdev->dev, "mdioclk"); | |
| 1305 | + clk = devm_clk_get_optional_enabled(&pdev->dev, "mdioclk"); | |
| 1306 | 1306 | if (IS_ERR(clk)) |
| 1307 | 1307 | return PTR_ERR(clk); |
| 1308 | 1308 | if (clk) { |
| 1309 | − clk_prepare_enable(clk); | |
| 1310 | 1309 | lp->mii_clock_freq = clk_get_rate(clk); |
| 1311 | 1310 | } else { |
| 1312 | 1311 | lp->mii_clock_freq = 200000000; /* max possible input clk */ |
| @@ -98,6 +98,9 @@ int octep_ctrl_mbox_init(struct octep_ctrl_mbox *mbox) · 97 unmodified lines | ||
| 98 | 98 | writeq(OCTEP_CTRL_MBOX_STATUS_INIT, |
| 99 | 99 | OCTEP_CTRL_MBOX_INFO_HOST_STATUS(mbox->barmem)); |
| 100 | 100 | |
| 101 | + mutex_init(&mbox->h2fq_lock); | |
| 102 | + mutex_init(&mbox->f2hq_lock); | |
| 103 | + | |
| 101 | 104 | mbox->h2fq.sz = readl(OCTEP_CTRL_MBOX_H2FQ_SZ(mbox->barmem)); |
| 102 | 105 | mbox->h2fq.hw_prod = OCTEP_CTRL_MBOX_H2FQ_PROD(mbox->barmem); |
| 103 | 106 | mbox->h2fq.hw_cons = OCTEP_CTRL_MBOX_H2FQ_CONS(mbox->barmem); |
| @@ -218,13 +218,54 @@ void npc_config_secret_key(struct rvu *rvu, int blkaddr) · 217 unmodified lines | ||
| 218 | 218 | |
| 219 | 219 | void npc_program_mkex_hash(struct rvu *rvu, int blkaddr) |
| 220 | 220 | { |
| 221 | + struct npc_mcam_kex_hash *mh = rvu->kpu.mkex_hash; | |
| 221 | 222 | struct hw_cap *hwcap = &rvu->hw->cap; |
| 223 | + u8 intf, ld, hdr_offset, byte_len; | |
| 222 | 224 | struct rvu_hwinfo *hw = rvu->hw; |
| 223 | − u8 intf; | |
| 225 | + u64 cfg; | |
| 224 | 226 | |
| 227 | + /* Check if hardware supports hash extraction */ | |
| 225 | 228 | if (!hwcap->npc_hash_extract) |
| 226 | 229 | return; |
| 227 | 230 | |
| 231 | + /* Check if IPv6 source/destination address | |
| 232 | + * should be hash enabled. | |
| 233 | + * Hashing reduces 128bit SIP/DIP fields to 32bit | |
| 234 | + * so that 224 bit X2 key can be used for IPv6 based filters as well, | |
| 235 | + * which in turn results in more number of MCAM entries available for | |
| 236 | + * use. | |
| 237 | + * | |
| 238 | + * Hashing of IPV6 SIP/DIP is enabled in below scenarios | |
| 239 | + * 1. If the silicon variant supports hashing feature | |
| 240 | + * 2. If the number of bytes of IP addr being extracted is 4 bytes ie | |
| 241 | + * 32bit. The assumption here is that if user wants 8bytes of LSB of | |
| 242 | + * IP addr or full 16 bytes then his intention is not to use 32bit | |
| 243 | + * hash. | |
| 244 | + */ | |
| 245 | + for (intf = 0; intf < hw->npc_intfs; intf++) { | |
| 246 | + for (ld = 0; ld < NPC_MAX_LD; ld++) { | |
| 247 | + cfg = rvu_read64(rvu, blkaddr, | |
| 248 | + NPC_AF_INTFX_LIDX_LTX_LDX_CFG(intf, | |
| 249 | + NPC_LID_LC, | |
| 250 | + NPC_LT_LC_IP6, | |
| 251 | + ld)); | |
| 252 | + hdr_offset = FIELD_GET(NPC_HDR_OFFSET, cfg); | |
| 253 | + byte_len = FIELD_GET(NPC_BYTESM, cfg); | |
| 254 | + /* Hashing of IPv6 source/destination address should be | |
| 255 | + * enabled if, | |
| 256 | + * hdr_offset == 8 (offset of source IPv6 address) or | |
| 257 | + * hdr_offset == 24 (offset of destination IPv6) | |
| 258 | + * address) and the number of byte to be | |
| 259 | + * extracted is 4. As per hardware configuration | |
| 260 | + * byte_len should be == actual byte_len - 1. | |
| 261 | + * Hence byte_len is checked against 3 but nor 4. | |
| 262 | + */ | |
| 263 | + if ((hdr_offset == 8 || hdr_offset == 24) && byte_len == 3) | |
| 264 | + mh->lid_lt_ld_hash_en[intf][NPC_LID_LC][NPC_LT_LC_IP6][ld] = true; | |
| 265 | + } | |
| 266 | + } | |
| 267 | + | |
| 268 | + /* Update hash configuration if the field is hash enabled */ | |
| 228 | 269 | for (intf = 0; intf < hw->npc_intfs; intf++) { |
| 229 | 270 | npc_program_mkex_hash_rx(rvu, blkaddr, intf); |
| 230 | 271 | npc_program_mkex_hash_tx(rvu, blkaddr, intf); |
| @@ -70,8 +70,8 @@ static struct npc_mcam_kex_hash npc_mkex_hash_default __maybe_unused = { · 69 unmodified lines | ||
| 70 | 70 | [NIX_INTF_RX] = { |
| 71 | 71 | [NPC_LID_LC] = { |
| 72 | 72 | [NPC_LT_LC_IP6] = { |
| 73 | − true, | |
| 74 | − true, | |
| 73 | + false, | |
| 74 | + false, | |
| 75 | 75 | }, |
| 76 | 76 | }, |
| 77 | 77 | }, |
| @@ -79,8 +79,8 @@ static struct npc_mcam_kex_hash npc_mkex_hash_default __maybe_unused = { · 1 unmodified line | ||
| 79 | 79 | [NIX_INTF_TX] = { |
| 80 | 80 | [NPC_LID_LC] = { |
| 81 | 81 | [NPC_LT_LC_IP6] = { |
| 82 | − true, | |
| 83 | − true, | |
| 82 | + false, | |
| 83 | + false, | |
| 84 | 84 | }, |
| 85 | 85 | }, |
| 86 | 86 | }, |
| @@ -727,7 +727,8 @@ pick_fw_ver: · 726 unmodified lines | ||
| 727 | 727 | |
| 728 | 728 | err = request_firmware_direct(&fw->bin, fw_path, fw->dev.dev); |
| 729 | 729 | if (err) { |
| 730 | − if (ver_maj == PRESTERA_SUPP_FW_MAJ_VER) { | |
| 730 | + if (ver_maj != PRESTERA_PREV_FW_MAJ_VER || | |
| 731 | + ver_min != PRESTERA_PREV_FW_MIN_VER) { | |
| 731 | 732 | ver_maj = PRESTERA_PREV_FW_MAJ_VER; |
| 732 | 733 | ver_min = PRESTERA_PREV_FW_MIN_VER; |
| 733 | 734 | |
| @@ -166,11 +166,11 @@ prestera_util_neigh2nc_key(struct prestera_switch *sw, struct neighbour *n, · 165 unmodified lines | ||
| 166 | 166 | |
| 167 | 167 | static bool __prestera_fi_is_direct(struct fib_info *fi) |
| 168 | 168 | { |
| 169 | − struct fib_nh *fib_nh; | |
| 169 | + struct fib_nh_common *fib_nhc; | |
| 170 | 170 | |
| 171 | 171 | if (fib_info_num_path(fi) == 1) { |
| 172 | − fib_nh = fib_info_nh(fi, 0); | |
| 173 | − if (fib_nh->fib_nh_gw_family == AF_UNSPEC) | |
| 172 | + fib_nhc = fib_info_nhc(fi, 0); | |
| 173 | + if (fib_nhc->nhc_gw_family == AF_UNSPEC) | |
| 174 | 174 | return true; |
| 175 | 175 | } |
| 176 | 176 | |
| @@ -261,7 +261,7 @@ static bool · 84 unmodified lines | ||
| 261 | 261 | __prestera_util_kern_n_is_reachable_v4(u32 tb_id, __be32 *addr, |
| 262 | 262 | struct net_device *dev) |
| 263 | 263 | { |
| 264 | − struct fib_nh *fib_nh; | |
| 264 | + struct fib_nh_common *fib_nhc; | |
| 265 | 265 | struct fib_result res; |
| 266 | 266 | bool reachable; |
| 267 | 267 | |
| @@ -269,8 +269,8 @@ __prestera_util_kern_n_is_reachable_v4(u32 tb_id, __be32 *addr, · 1 unmodified line | ||
| 269 | 269 | |
| 270 | 270 | if (!prestera_util_kern_get_route(&res, tb_id, addr)) |
| 271 | 271 | if (prestera_fi_is_direct(res.fi)) { |
| 272 | − fib_nh = fib_info_nh(res.fi, 0); | |
| 273 | − if (dev == fib_nh->fib_nh_dev) | |
| 272 | + fib_nhc = fib_info_nhc(res.fi, 0); | |
| 273 | + if (dev == fib_nhc->nhc_dev) | |
| 274 | 274 | reachable = true; |
| 275 | 275 | } |
| 276 | 276 | |
| @@ -324,7 +324,7 @@ prestera_kern_fib_info_nhc(struct fib_notifier_info *info, int n) · 47 unmodified lines | ||
| 324 | 324 | if (info->family == AF_INET) { |
| 325 | 325 | fen4_info = container_of(info, struct fib_entry_notifier_info, |
| 326 | 326 | info); |
| 327 | − return &fib_info_nh(fen4_info->fi, n)->nh_common; | |
| 327 | + return fib_info_nhc(fen4_info->fi, n); | |
| 328 | 328 | } else if (info->family == AF_INET6) { |
| 329 | 329 | fen6_info = container_of(info, struct fib6_entry_notifier_info, |
| 330 | 330 | info); |
| @@ -2,6 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | /* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. */ |
| 3 | 3 | |
| 4 | 4 | #include "reporter_vnic.h" |
| 5 | +#include "en_stats.h" | |
| 5 | 6 | #include "devlink.h" |
| 6 | 7 | |
| 7 | 8 | #define VNIC_ENV_GET64(vnic_env_stats, c) \ |
| @@ -36,55 +37,72 @@ int mlx5_reporter_vnic_diagnose_counters(struct mlx5_core_dev *dev, · 28 unmodified lines | ||
| 36 | 37 | if (err) |
| 37 | 38 | return err; |
| 38 | 39 | |
| 39 | − err = devlink_fmsg_u64_pair_put(fmsg, "total_error_queues", | |
| 40 | − VNIC_ENV_GET64(&vnic, total_error_queues)); | |
| 41 | − if (err) | |
| 42 | − return err; | |
| 43 | − | |
| 44 | − err = devlink_fmsg_u64_pair_put(fmsg, "send_queue_priority_update_flow", | |
| 45 | − VNIC_ENV_GET64(&vnic, send_queue_priority_update_flow)); | |
| 46 | − if (err) | |
| 47 | − return err; | |
| 48 | − | |
| 49 | − err = devlink_fmsg_u64_pair_put(fmsg, "comp_eq_overrun", | |
| 50 | − VNIC_ENV_GET64(&vnic, comp_eq_overrun)); | |
| 51 | − if (err) | |
| 52 | − return err; | |
| 53 | − | |
| 54 | − err = devlink_fmsg_u64_pair_put(fmsg, "async_eq_overrun", | |
| 55 | − VNIC_ENV_GET64(&vnic, async_eq_overrun)); | |
| 56 | − if (err) | |
| 57 | − return err; | |
| 58 | − | |
| 59 | − err = devlink_fmsg_u64_pair_put(fmsg, "cq_overrun", | |
| 60 | − VNIC_ENV_GET64(&vnic, cq_overrun)); | |
| 61 | − if (err) | |
| 62 | − return err; | |
| 63 | − | |
| 64 | − err = devlink_fmsg_u64_pair_put(fmsg, "invalid_command", | |
| 65 | − VNIC_ENV_GET64(&vnic, invalid_command)); | |
| 66 | − if (err) | |
| 67 | − return err; | |
| 68 | − | |
| 69 | − err = devlink_fmsg_u64_pair_put(fmsg, "quota_exceeded_command", | |
| 70 | − VNIC_ENV_GET64(&vnic, quota_exceeded_command)); | |
| 71 | − if (err) | |
| 72 | − return err; | |
| 73 | − | |
| 74 | − err = devlink_fmsg_u64_pair_put(fmsg, "nic_receive_steering_discard", | |
| 75 | − VNIC_ENV_GET64(&vnic, nic_receive_steering_discard)); | |
| 76 | − if (err) | |
| 77 | − return err; | |
| 78 | − | |
| 79 | − err = devlink_fmsg_u64_pair_put(fmsg, "generated_pkt_steering_fail", | |
| 80 | − VNIC_ENV_GET64(&vnic, generated_pkt_steering_fail)); | |
| 81 | − if (err) | |
| 82 | − return err; | |
| 83 | − | |
| 84 | − err = devlink_fmsg_u64_pair_put(fmsg, "handled_pkt_steering_fail", | |
| 85 | − VNIC_ENV_GET64(&vnic, handled_pkt_steering_fail)); | |
| 86 | − if (err) | |
| 87 | − return err; | |
| 40 | + if (MLX5_CAP_GEN(dev, vnic_env_queue_counters)) { | |
| 41 | + err = devlink_fmsg_u32_pair_put(fmsg, "total_error_queues", | |
| 42 | + VNIC_ENV_GET(&vnic, total_error_queues)); | |
| 43 | + if (err) | |
| 44 | + return err; | |
| 45 | + | |
| 46 | + err = devlink_fmsg_u32_pair_put(fmsg, "send_queue_priority_update_flow", | |
| 47 | + VNIC_ENV_GET(&vnic, | |
| 48 | + send_queue_priority_update_flow)); | |
| 49 | + if (err) | |
| 50 | + return err; | |
| 51 | + } | |
| 52 | + | |
| 53 | + if (MLX5_CAP_GEN(dev, eq_overrun_count)) { | |
| 54 | + err = devlink_fmsg_u32_pair_put(fmsg, "comp_eq_overrun", | |
| 55 | + VNIC_ENV_GET(&vnic, comp_eq_overrun)); | |
| 56 | + if (err) | |
| 57 | + return err; | |
| 58 | + | |
| 59 | + err = devlink_fmsg_u32_pair_put(fmsg, "async_eq_overrun", | |
| 60 | + VNIC_ENV_GET(&vnic, async_eq_overrun)); | |
| 61 | + if (err) | |
| 62 | + return err; | |
| 63 | + } | |
| 64 | + | |
| 65 | + if (MLX5_CAP_GEN(dev, vnic_env_cq_overrun)) { | |
| 66 | + err = devlink_fmsg_u32_pair_put(fmsg, "cq_overrun", | |
| 67 | + VNIC_ENV_GET(&vnic, cq_overrun)); | |
| 68 | + if (err) | |
| 69 | + return err; | |
| 70 | + } | |
| 71 | + | |
| 72 | + if (MLX5_CAP_GEN(dev, invalid_command_count)) { | |
| 73 | + err = devlink_fmsg_u32_pair_put(fmsg, "invalid_command", | |
| 74 | + VNIC_ENV_GET(&vnic, invalid_command)); | |
| 75 | + if (err) | |
| 76 | + return err; | |
| 77 | + } | |
| 78 | + | |
| 79 | + if (MLX5_CAP_GEN(dev, quota_exceeded_count)) { | |
| 80 | + err = devlink_fmsg_u32_pair_put(fmsg, "quota_exceeded_command", | |
| 81 | + VNIC_ENV_GET(&vnic, quota_exceeded_command)); | |
| 82 | + if (err) | |
| 83 | + return err; | |
| 84 | + } | |
| 85 | + | |
| 86 | + if (MLX5_CAP_GEN(dev, nic_receive_steering_discard)) { | |
| 87 | + err = devlink_fmsg_u64_pair_put(fmsg, "nic_receive_steering_discard", | |
| 88 | + VNIC_ENV_GET64(&vnic, | |
| 89 | + nic_receive_steering_discard)); | |
| 90 | + if (err) | |
| 91 | + return err; | |
| 92 | + } | |
| 93 | + | |
| 94 | + if (MLX5_CAP_GEN(dev, vnic_env_cnt_steering_fail)) { | |
| 95 | + err = devlink_fmsg_u64_pair_put(fmsg, "generated_pkt_steering_fail", | |
| 96 | + VNIC_ENV_GET64(&vnic, | |
| 97 | + generated_pkt_steering_fail)); | |
| 98 | + if (err) | |
| 99 | + return err; | |
| 100 | + | |
| 101 | + err = devlink_fmsg_u64_pair_put(fmsg, "handled_pkt_steering_fail", | |
| 102 | + VNIC_ENV_GET64(&vnic, handled_pkt_steering_fail)); | |
| 103 | + if (err) | |
| 104 | + return err; | |
| 105 | + } | |
| 88 | 106 | |
| 89 | 107 | err = devlink_fmsg_obj_nest_end(fmsg); |
| 90 | 108 | if (err) |
| @@ -1030,9 +1030,6 @@ int mlx5e_tc_tun_encap_dests_set(struct mlx5e_priv *priv, · 1029 unmodified lines | ||
| 1030 | 1030 | int out_index; |
| 1031 | 1031 | int err = 0; |
| 1032 | 1032 | |
| 1033 | − if (!mlx5e_is_eswitch_flow(flow)) | |
| 1034 | − return 0; | |
| 1035 | − | |
| 1036 | 1033 | parse_attr = attr->parse_attr; |
| 1037 | 1034 | esw_attr = attr->esw_attr; |
| 1038 | 1035 | *vf_tun = false; |
| @@ -1464,10 +1461,12 @@ static void mlx5e_invalidate_encap(struct mlx5e_priv *priv, · 425 unmodified lines | ||
| 1464 | 1461 | attr = mlx5e_tc_get_encap_attr(flow); |
| 1465 | 1462 | esw_attr = attr->esw_attr; |
| 1466 | 1463 | |
| 1467 | − if (flow_flag_test(flow, SLOW)) | |
| 1464 | + if (flow_flag_test(flow, SLOW)) { | |
| 1468 | 1465 | mlx5e_tc_unoffload_from_slow_path(esw, flow); |
| 1469 | − else | |
| 1466 | + } else { | |
| 1470 | 1467 | mlx5e_tc_unoffload_fdb_rules(esw, flow, flow->attr); |
| 1468 | + mlx5e_tc_unoffload_flow_post_acts(flow); | |
| 1469 | + } | |
| 1471 | 1470 | |
| 1472 | 1471 | mlx5e_tc_detach_mod_hdr(priv, flow, attr); |
| 1473 | 1472 | attr->modify_hdr = NULL; |
| @@ -323,8 +323,11 @@ struct sk_buff *mlx5e_xsk_skb_from_cqe_linear(struct mlx5e_rq *rq, · 322 unmodified lines | ||
| 323 | 323 | net_prefetch(mxbuf->xdp.data); |
| 324 | 324 | |
| 325 | 325 | prog = rcu_dereference(rq->xdp_prog); |
| 326 | − if (likely(prog && mlx5e_xdp_handle(rq, prog, mxbuf))) | |
| 326 | + if (likely(prog && mlx5e_xdp_handle(rq, prog, mxbuf))) { | |
| 327 | + if (likely(__test_and_clear_bit(MLX5E_RQ_FLAG_XDP_XMIT, rq->flags))) | |
| 328 | + wi->flags |= BIT(MLX5E_WQE_FRAG_SKIP_RELEASE); | |
| 327 | 329 | return NULL; /* page/packet was consumed by XDP */ |
| 330 | + } | |
| 328 | 331 | |
| 329 | 332 | /* XDP_PASS: copy the data from the UMEM to a new SKB. The frame reuse |
| 330 | 333 | * will be handled by mlx5e_free_rx_wqe. |
| @@ -808,9 +808,9 @@ static void setup_fte_upper_proto_match(struct mlx5_flow_spec *spec, struct upsp · 807 unmodified lines | ||
| 808 | 808 | } |
| 809 | 809 | |
| 810 | 810 | if (upspec->sport) { |
| 811 | − MLX5_SET(fte_match_set_lyr_2_4, spec->match_criteria, udp_dport, | |
| 811 | + MLX5_SET(fte_match_set_lyr_2_4, spec->match_criteria, udp_sport, | |
| 812 | 812 | upspec->sport_mask); |
| 813 | − MLX5_SET(fte_match_set_lyr_2_4, spec->match_value, udp_dport, upspec->sport); | |
| 813 | + MLX5_SET(fte_match_set_lyr_2_4, spec->match_value, udp_sport, upspec->sport); | |
| 814 | 814 | } |
| 815 | 815 | } |
| 816 | 816 | |
| @@ -58,7 +58,9 @@ static int mlx5e_ipsec_remove_trailer(struct sk_buff *skb, struct xfrm_state *x) · 57 unmodified lines | ||
| 58 | 58 | |
| 59 | 59 | trailer_len = alen + plen + 2; |
| 60 | 60 | |
| 61 | − pskb_trim(skb, skb->len - trailer_len); | |
| 61 | + ret = pskb_trim(skb, skb->len - trailer_len); | |
| 62 | + if (unlikely(ret)) | |
| 63 | + return ret; | |
| 62 | 64 | if (skb->protocol == htons(ETH_P_IP)) { |
| 63 | 65 | ipv4hdr->tot_len = htons(ntohs(ipv4hdr->tot_len) - trailer_len); |
| 64 | 66 | ip_send_check(ipv4hdr); |
| @@ -188,7 +188,6 @@ static void mlx5e_tls_debugfs_init(struct mlx5e_tls *tls, · 187 unmodified lines | ||
| 188 | 188 | |
| 189 | 189 | int mlx5e_ktls_init(struct mlx5e_priv *priv) |
| 190 | 190 | { |
| 191 | − struct mlx5_crypto_dek_pool *dek_pool; | |
| 192 | 191 | struct mlx5e_tls *tls; |
| 193 | 192 | |
| 194 | 193 | if (!mlx5e_is_ktls_device(priv->mdev)) |
| @@ -199,12 +198,6 @@ int mlx5e_ktls_init(struct mlx5e_priv *priv) · 4 unmodified lines | ||
| 199 | 198 | return -ENOMEM; |
| 200 | 199 | tls->mdev = priv->mdev; |
| 201 | 200 | |
| 202 | − dek_pool = mlx5_crypto_dek_pool_create(priv->mdev, MLX5_ACCEL_OBJ_TLS_KEY); | |
| 203 | − if (IS_ERR(dek_pool)) { | |
| 204 | − kfree(tls); | |
| 205 | − return PTR_ERR(dek_pool); | |
| 206 | − } | |
| 207 | − tls->dek_pool = dek_pool; | |
| 208 | 201 | priv->tls = tls; |
| 209 | 202 | |
| 210 | 203 | mlx5e_tls_debugfs_init(tls, priv->dfs_root); |
| @@ -222,7 +215,6 @@ void mlx5e_ktls_cleanup(struct mlx5e_priv *priv) · 11 unmodified lines | ||
| 222 | 215 | debugfs_remove_recursive(tls->debugfs.dfs); |
| 223 | 216 | tls->debugfs.dfs = NULL; |
| 224 | 217 | |
| 225 | − mlx5_crypto_dek_pool_destroy(tls->dek_pool); | |
| 226 | 218 | kfree(priv->tls); |
| 227 | 219 | priv->tls = NULL; |
| 228 | 220 | } |
| @@ -908,28 +908,51 @@ static void mlx5e_tls_tx_debugfs_init(struct mlx5e_tls *tls, · 907 unmodified lines | ||
| 908 | 908 | |
| 909 | 909 | int mlx5e_ktls_init_tx(struct mlx5e_priv *priv) |
| 910 | 910 | { |
| 911 | + struct mlx5_crypto_dek_pool *dek_pool; | |
| 911 | 912 | struct mlx5e_tls *tls = priv->tls; |
| 913 | + int err; | |
| 914 | + | |
| 915 | + if (!mlx5e_is_ktls_device(priv->mdev)) | |
| 916 | + return 0; | |
| 917 | + | |
| 918 | + /* DEK pool could be used by either or both of TX and RX. But we have to | |
| 919 | + * put the creation here to avoid syndrome when doing devlink reload. | |
| 920 | + */ | |
| 921 | + dek_pool = mlx5_crypto_dek_pool_create(priv->mdev, MLX5_ACCEL_OBJ_TLS_KEY); | |
| 922 | + if (IS_ERR(dek_pool)) | |
| 923 | + return PTR_ERR(dek_pool); | |
| 924 | + tls->dek_pool = dek_pool; | |
| 912 | 925 | |
| 913 | 926 | if (!mlx5e_is_ktls_tx(priv->mdev)) |
| 914 | 927 | return 0; |
| 915 | 928 | |
| 916 | 929 | priv->tls->tx_pool = mlx5e_tls_tx_pool_init(priv->mdev, &priv->tls->sw_stats); |
| 917 | − if (!priv->tls->tx_pool) | |
| 918 | − return -ENOMEM; | |
| 930 | + if (!priv->tls->tx_pool) { | |
| 931 | + err = -ENOMEM; | |
| 932 | + goto err_tx_pool_init; | |
| 933 | + } | |
| 919 | 934 | |
| 920 | 935 | mlx5e_tls_tx_debugfs_init(tls, tls->debugfs.dfs); |
| 921 | 936 | |
| 922 | 937 | return 0; |
| 938 | + | |
| 939 | +err_tx_pool_init: | |
| 940 | + mlx5_crypto_dek_pool_destroy(dek_pool); | |
| 941 | + return err; | |
| 923 | 942 | } |
| 924 | 943 | |
| 925 | 944 | void mlx5e_ktls_cleanup_tx(struct mlx5e_priv *priv) |
| 926 | 945 | { |
| 927 | 946 | if (!mlx5e_is_ktls_tx(priv->mdev)) |
| 928 | − return; | |
| 947 | + goto dek_pool_destroy; | |
| 929 | 948 | |
| 930 | 949 | debugfs_remove_recursive(priv->tls->debugfs.dfs_tx); |
| 931 | 950 | priv->tls->debugfs.dfs_tx = NULL; |
| 932 | 951 | |
| 933 | 952 | mlx5e_tls_tx_pool_cleanup(priv->tls->tx_pool); |
| 934 | 953 | priv->tls->tx_pool = NULL; |
| 954 | + | |
| 955 | +dek_pool_destroy: | |
| 956 | + if (mlx5e_is_ktls_device(priv->mdev)) | |
| 957 | + mlx5_crypto_dek_pool_destroy(priv->tls->dek_pool); | |
| 935 | 958 | } |
| @@ -161,6 +161,7 @@ static int macsec_fs_tx_create_crypto_table_groups(struct mlx5e_flow_table *ft) · 160 unmodified lines | ||
| 161 | 161 | |
| 162 | 162 | if (!in) { |
| 163 | 163 | kfree(ft->g); |
| 164 | + ft->g = NULL; | |
| 164 | 165 | return -ENOMEM; |
| 165 | 166 | } |
| 166 | 167 | |
| @@ -135,6 +135,16 @@ static void arfs_del_rules(struct mlx5e_flow_steering *fs); · 134 unmodified lines | ||
| 135 | 135 | |
| 136 | 136 | int mlx5e_arfs_disable(struct mlx5e_flow_steering *fs) |
| 137 | 137 | { |
| 138 | + /* Moving to switchdev mode, fs->arfs is freed by mlx5e_nic_profile | |
| 139 | + * cleanup_rx callback and it is not recreated when | |
| 140 | + * mlx5e_uplink_rep_profile is loaded as mlx5e_create_flow_steering() | |
| 141 | + * is not called by the uplink_rep profile init_rx callback. Thus, if | |
| 142 | + * ntuple is set, moving to switchdev flow will enter this function | |
| 143 | + * with fs->arfs nullified. | |
| 144 | + */ | |
| 145 | + if (!mlx5e_fs_get_arfs(fs)) | |
| 146 | + return 0; | |
| 147 | + | |
| 138 | 148 | arfs_del_rules(fs); |
| 139 | 149 | |
| 140 | 150 | return arfs_disable(fs); |
| @@ -1036,7 +1036,23 @@ static int mlx5e_modify_rq_state(struct mlx5e_rq *rq, int curr_state, int next_s · 1035 unmodified lines | ||
| 1036 | 1036 | return err; |
| 1037 | 1037 | } |
| 1038 | 1038 | |
| 1039 | −static int mlx5e_rq_to_ready(struct mlx5e_rq *rq, int curr_state) | |
| 1039 | +static void mlx5e_flush_rq_cq(struct mlx5e_rq *rq) | |
| 1040 | +{ | |
| 1041 | + struct mlx5_cqwq *cqwq = &rq->cq.wq; | |
| 1042 | + struct mlx5_cqe64 *cqe; | |
| 1043 | + | |
| 1044 | + if (test_bit(MLX5E_RQ_STATE_MINI_CQE_ENHANCED, &rq->state)) { | |
| 1045 | + while ((cqe = mlx5_cqwq_get_cqe_enahnced_comp(cqwq))) | |
| 1046 | + mlx5_cqwq_pop(cqwq); | |
| 1047 | + } else { | |
| 1048 | + while ((cqe = mlx5_cqwq_get_cqe(cqwq))) | |
| 1049 | + mlx5_cqwq_pop(cqwq); | |
| 1050 | + } | |
| 1051 | + | |
| 1052 | + mlx5_cqwq_update_db_record(cqwq); | |
| 1053 | +} | |
| 1054 | + | |
| 1055 | +int mlx5e_flush_rq(struct mlx5e_rq *rq, int curr_state) | |
| 1040 | 1056 | { |
| 1041 | 1057 | struct net_device *dev = rq->netdev; |
| 1042 | 1058 | int err; |
| @@ -1046,6 +1062,10 @@ static int mlx5e_rq_to_ready(struct mlx5e_rq *rq, int curr_state) · 3 unmodified lines | ||
| 1046 | 1062 | netdev_err(dev, "Failed to move rq 0x%x to reset\n", rq->rqn); |
| 1047 | 1063 | return err; |
| 1048 | 1064 | } |
| 1065 | + | |
| 1066 | + mlx5e_free_rx_descs(rq); | |
| 1067 | + mlx5e_flush_rq_cq(rq); | |
| 1068 | + | |
| 1049 | 1069 | err = mlx5e_modify_rq_state(rq, MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY); |
| 1050 | 1070 | if (err) { |
| 1051 | 1071 | netdev_err(dev, "Failed to move rq 0x%x to ready\n", rq->rqn); |
| @@ -1055,13 +1075,6 @@ static int mlx5e_rq_to_ready(struct mlx5e_rq *rq, int curr_state) · 3 unmodified lines | ||
| 1055 | 1075 | return 0; |
| 1056 | 1076 | } |
| 1057 | 1077 | |
| 1058 | −int mlx5e_flush_rq(struct mlx5e_rq *rq, int curr_state) | |
| 1059 | −{ | |
| 1060 | − mlx5e_free_rx_descs(rq); | |
| 1061 | − | |
| 1062 | − return mlx5e_rq_to_ready(rq, curr_state); | |
| 1063 | −} | |
| 1064 | − | |
| 1065 | 1078 | static int mlx5e_modify_rq_vsd(struct mlx5e_rq *rq, bool vsd) |
| 1066 | 1079 | { |
| 1067 | 1080 | struct mlx5_core_dev *mdev = rq->mdev; |
| @@ -5253,6 +5266,7 @@ void mlx5e_destroy_q_counters(struct mlx5e_priv *priv) · 4185 unmodified lines | ||
| 5253 | 5266 | static int mlx5e_nic_init(struct mlx5_core_dev *mdev, |
| 5254 | 5267 | struct net_device *netdev) |
| 5255 | 5268 | { |
| 5269 | + const bool take_rtnl = netdev->reg_state == NETREG_REGISTERED; | |
| 5256 | 5270 | struct mlx5e_priv *priv = netdev_priv(netdev); |
| 5257 | 5271 | struct mlx5e_flow_steering *fs; |
| 5258 | 5272 | int err; |
| @@ -5281,9 +5295,19 @@ static int mlx5e_nic_init(struct mlx5_core_dev *mdev, · 22 unmodified lines | ||
| 5281 | 5295 | mlx5_core_err(mdev, "TLS initialization failed, %d\n", err); |
| 5282 | 5296 | |
| 5283 | 5297 | mlx5e_health_create_reporters(priv); |
| 5298 | + | |
| 5299 | + /* If netdev is already registered (e.g. move from uplink to nic profile), | |
| 5300 | + * RTNL lock must be held before triggering netdev notifiers. | |
| 5301 | + */ | |
| 5302 | + if (take_rtnl) | |
| 5303 | + rtnl_lock(); | |
| 5304 | + | |
| 5284 | 5305 | /* update XDP supported features */ |
| 5285 | 5306 | mlx5e_set_xdp_feature(netdev); |
| 5286 | 5307 | |
| 5308 | + if (take_rtnl) | |
| 5309 | + rtnl_unlock(); | |
| 5310 | + | |
| 5287 | 5311 | return 0; |
| 5288 | 5312 | } |
| 5289 | 5313 | |
| @@ -1012,7 +1012,7 @@ static int mlx5e_init_rep_rx(struct mlx5e_priv *priv) · 1011 unmodified lines | ||
| 1012 | 1012 | err = mlx5e_open_drop_rq(priv, &priv->drop_rq); |
| 1013 | 1013 | if (err) { |
| 1014 | 1014 | mlx5_core_err(mdev, "open drop rq failed, %d\n", err); |
| 1015 | − return err; | |
| 1015 | + goto err_rx_res_free; | |
| 1016 | 1016 | } |
| 1017 | 1017 | |
| 1018 | 1018 | err = mlx5e_rx_res_init(priv->rx_res, priv->mdev, 0, |
| @@ -1046,6 +1046,7 @@ err_destroy_rx_res: · 27 unmodified lines | ||
| 1046 | 1046 | mlx5e_rx_res_destroy(priv->rx_res); |
| 1047 | 1047 | err_close_drop_rq: |
| 1048 | 1048 | mlx5e_close_drop_rq(&priv->drop_rq); |
| 1049 | +err_rx_res_free: | |
| 1049 | 1050 | mlx5e_rx_res_free(priv->rx_res); |
| 1050 | 1051 | priv->rx_res = NULL; |
| 1051 | 1052 | err_free_fs: |
| @@ -1159,6 +1160,10 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv) · 107 unmodified lines | ||
| 1159 | 1160 | return err; |
| 1160 | 1161 | } |
| 1161 | 1162 | |
| 1163 | + err = mlx5e_rep_neigh_init(rpriv); | |
| 1164 | + if (err) | |
| 1165 | + goto err_neigh_init; | |
| 1166 | + | |
| 1162 | 1167 | if (rpriv->rep->vport == MLX5_VPORT_UPLINK) { |
| 1163 | 1168 | err = mlx5e_init_uplink_rep_tx(rpriv); |
| 1164 | 1169 | if (err) |
| @@ -1175,6 +1180,8 @@ err_ht_init: · 10 unmodified lines | ||
| 1175 | 1180 | if (rpriv->rep->vport == MLX5_VPORT_UPLINK) |
| 1176 | 1181 | mlx5e_cleanup_uplink_rep_tx(rpriv); |
| 1177 | 1182 | err_init_tx: |
| 1183 | + mlx5e_rep_neigh_cleanup(rpriv); | |
| 1184 | +err_neigh_init: | |
| 1178 | 1185 | mlx5e_destroy_tises(priv); |
| 1179 | 1186 | return err; |
| 1180 | 1187 | } |
| @@ -1188,22 +1195,17 @@ static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv) · 7 unmodified lines | ||
| 1188 | 1195 | if (rpriv->rep->vport == MLX5_VPORT_UPLINK) |
| 1189 | 1196 | mlx5e_cleanup_uplink_rep_tx(rpriv); |
| 1190 | 1197 | |
| 1198 | + mlx5e_rep_neigh_cleanup(rpriv); | |
| 1191 | 1199 | mlx5e_destroy_tises(priv); |
| 1192 | 1200 | } |
| 1193 | 1201 | |
| 1194 | 1202 | static void mlx5e_rep_enable(struct mlx5e_priv *priv) |
| 1195 | 1203 | { |
| 1196 | − struct mlx5e_rep_priv *rpriv = priv->ppriv; | |
| 1197 | − | |
| 1198 | 1204 | mlx5e_set_netdev_mtu_boundaries(priv); |
| 1199 | − mlx5e_rep_neigh_init(rpriv); | |
| 1200 | 1205 | } |
| 1201 | 1206 | |
| 1202 | 1207 | static void mlx5e_rep_disable(struct mlx5e_priv *priv) |
| 1203 | 1208 | { |
| 1204 | − struct mlx5e_rep_priv *rpriv = priv->ppriv; | |
| 1205 | − | |
| 1206 | − mlx5e_rep_neigh_cleanup(rpriv); | |
| 1207 | 1209 | } |
| 1208 | 1210 | |
| 1209 | 1211 | static int mlx5e_update_rep_rx(struct mlx5e_priv *priv) |
| @@ -1253,7 +1255,6 @@ static int uplink_rep_async_event(struct notifier_block *nb, unsigned long event · 43 unmodified lines | ||
| 1253 | 1255 | |
| 1254 | 1256 | static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv) |
| 1255 | 1257 | { |
| 1256 | − struct mlx5e_rep_priv *rpriv = priv->ppriv; | |
| 1257 | 1258 | struct net_device *netdev = priv->netdev; |
| 1258 | 1259 | struct mlx5_core_dev *mdev = priv->mdev; |
| 1259 | 1260 | u16 max_mtu; |
| @@ -1275,7 +1276,6 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv) · 15 unmodified lines | ||
| 1275 | 1276 | mlx5_notifier_register(mdev, &priv->events_nb); |
| 1276 | 1277 | mlx5e_dcbnl_initialize(priv); |
| 1277 | 1278 | mlx5e_dcbnl_init_app(priv); |
| 1278 | − mlx5e_rep_neigh_init(rpriv); | |
| 1279 | 1279 | mlx5e_rep_bridge_init(priv); |
| 1280 | 1280 | |
| 1281 | 1281 | netdev->wanted_features |= NETIF_F_HW_TC; |
| @@ -1290,7 +1290,6 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv) · 8 unmodified lines | ||
| 1290 | 1290 | |
| 1291 | 1291 | static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv) |
| 1292 | 1292 | { |
| 1293 | − struct mlx5e_rep_priv *rpriv = priv->ppriv; | |
| 1294 | 1293 | struct mlx5_core_dev *mdev = priv->mdev; |
| 1295 | 1294 | |
| 1296 | 1295 | rtnl_lock(); |
| @@ -1300,7 +1299,6 @@ static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv) · 3 unmodified lines | ||
| 1300 | 1299 | rtnl_unlock(); |
| 1301 | 1300 | |
| 1302 | 1301 | mlx5e_rep_bridge_cleanup(priv); |
| 1303 | − mlx5e_rep_neigh_cleanup(rpriv); | |
| 1304 | 1302 | mlx5e_dcbnl_delete_app(priv); |
| 1305 | 1303 | mlx5_notifier_unregister(mdev, &priv->events_nb); |
| 1306 | 1304 | mlx5e_rep_tc_disable(priv); |
| @@ -1725,6 +1725,19 @@ verify_attr_actions(u32 actions, struct netlink_ext_ack *extack) · 1724 unmodified lines | ||
| 1725 | 1725 | return 0; |
| 1726 | 1726 | } |
| 1727 | 1727 | |
| 1728 | +static bool | |
| 1729 | +has_encap_dests(struct mlx5_flow_attr *attr) | |
| 1730 | +{ | |
| 1731 | + struct mlx5_esw_flow_attr *esw_attr = attr->esw_attr; | |
| 1732 | + int out_index; | |
| 1733 | + | |
| 1734 | + for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++) | |
| 1735 | + if (esw_attr->dests[out_index].flags & MLX5_ESW_DEST_ENCAP) | |
| 1736 | + return true; | |
| 1737 | + | |
| 1738 | + return false; | |
| 1739 | +} | |
| 1740 | + | |
| 1728 | 1741 | static int |
| 1729 | 1742 | post_process_attr(struct mlx5e_tc_flow *flow, |
| 1730 | 1743 | struct mlx5_flow_attr *attr, |
| @@ -1737,9 +1750,11 @@ post_process_attr(struct mlx5e_tc_flow *flow, · 6 unmodified lines | ||
| 1737 | 1750 | if (err) |
| 1738 | 1751 | goto err_out; |
| 1739 | 1752 | |
| 1740 | − err = mlx5e_tc_tun_encap_dests_set(flow->priv, flow, attr, extack, &vf_tun); | |
| 1741 | − if (err) | |
| 1742 | − goto err_out; | |
| 1753 | + if (mlx5e_is_eswitch_flow(flow) && has_encap_dests(attr)) { | |
| 1754 | + err = mlx5e_tc_tun_encap_dests_set(flow->priv, flow, attr, extack, &vf_tun); | |
| 1755 | + if (err) | |
| 1756 | + goto err_out; | |
| 1757 | + } | |
| 1743 | 1758 | |
| 1744 | 1759 | if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) { |
| 1745 | 1760 | err = mlx5e_tc_attach_mod_hdr(flow->priv, flow, attr); |
| @@ -1928,9 +1943,7 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv, · 182 unmodified lines | ||
| 1928 | 1943 | { |
| 1929 | 1944 | struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; |
| 1930 | 1945 | struct mlx5_flow_attr *attr = flow->attr; |
| 1931 | − struct mlx5_esw_flow_attr *esw_attr; | |
| 1932 | 1946 | |
| 1933 | − esw_attr = attr->esw_attr; | |
| 1934 | 1947 | mlx5e_put_flow_tunnel_id(flow); |
| 1935 | 1948 | |
| 1936 | 1949 | remove_unready_flow(flow); |
| @@ -1951,12 +1964,6 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv, · 14 unmodified lines | ||
| 1951 | 1964 | |
| 1952 | 1965 | mlx5_tc_ct_match_del(get_ct_priv(priv), &flow->attr->ct_attr); |
| 1953 | 1966 | |
| 1954 | − if (esw_attr->int_port) | |
| 1955 | − mlx5e_tc_int_port_put(mlx5e_get_int_port_priv(priv), esw_attr->int_port); | |
| 1956 | − | |
| 1957 | − if (esw_attr->dest_int_port) | |
| 1958 | − mlx5e_tc_int_port_put(mlx5e_get_int_port_priv(priv), esw_attr->dest_int_port); | |
| 1959 | − | |
| 1960 | 1967 | if (flow_flag_test(flow, L3_TO_L2_DECAP)) |
| 1961 | 1968 | mlx5e_detach_decap(priv, flow); |
| 1962 | 1969 | |
| @@ -4253,6 +4260,7 @@ static void · 2290 unmodified lines | ||
| 4253 | 4260 | mlx5_free_flow_attr_actions(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr *attr) |
| 4254 | 4261 | { |
| 4255 | 4262 | struct mlx5_core_dev *counter_dev = get_flow_counter_dev(flow); |
| 4263 | + struct mlx5_esw_flow_attr *esw_attr; | |
| 4256 | 4264 | |
| 4257 | 4265 | if (!attr) |
| 4258 | 4266 | return; |
| @@ -4270,6 +4278,18 @@ mlx5_free_flow_attr_actions(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr *a · 11 unmodified lines | ||
| 4270 | 4278 | mlx5e_tc_detach_mod_hdr(flow->priv, flow, attr); |
| 4271 | 4279 | } |
| 4272 | 4280 | |
| 4281 | + if (mlx5e_is_eswitch_flow(flow)) { | |
| 4282 | + esw_attr = attr->esw_attr; | |
| 4283 | + | |
| 4284 | + if (esw_attr->int_port) | |
| 4285 | + mlx5e_tc_int_port_put(mlx5e_get_int_port_priv(flow->priv), | |
| 4286 | + esw_attr->int_port); | |
| 4287 | + | |
| 4288 | + if (esw_attr->dest_int_port) | |
| 4289 | + mlx5e_tc_int_port_put(mlx5e_get_int_port_priv(flow->priv), | |
| 4290 | + esw_attr->dest_int_port); | |
| 4291 | + } | |
| 4292 | + | |
| 4273 | 4293 | mlx5_tc_ct_delete_flow(get_ct_priv(flow->priv), attr); |
| 4274 | 4294 | |
| 4275 | 4295 | free_branch_attr(flow, attr->branch_true); |
| @@ -64,7 +64,7 @@ void mlx5_esw_bridge_debugfs_init(struct net_device *br_netdev, struct mlx5_esw_ · 63 unmodified lines | ||
| 64 | 64 | |
| 65 | 65 | bridge->debugfs_dir = debugfs_create_dir(br_netdev->name, |
| 66 | 66 | bridge->br_offloads->debugfs_root); |
| 67 | − debugfs_create_file("fdb", 0444, bridge->debugfs_dir, bridge, | |
| 67 | + debugfs_create_file("fdb", 0400, bridge->debugfs_dir, bridge, | |
| 68 | 68 | &mlx5_esw_bridge_debugfs_fops); |
| 69 | 69 | } |
| 70 | 70 | |
| @@ -60,7 +60,7 @@ static struct devlink_port *mlx5_esw_dl_port_alloc(struct mlx5_eswitch *esw, u16 · 59 unmodified lines | ||
| 60 | 60 | } else if (mlx5_core_is_ec_vf_vport(esw->dev, vport_num)) { |
| 61 | 61 | memcpy(dl_port->attrs.switch_id.id, ppid.id, ppid.id_len); |
| 62 | 62 | dl_port->attrs.switch_id.id_len = ppid.id_len; |
| 63 | − devlink_port_attrs_pci_vf_set(dl_port, controller_num, pfnum, | |
| 63 | + devlink_port_attrs_pci_vf_set(dl_port, 0, pfnum, | |
| 64 | 64 | vport_num - 1, false); |
| 65 | 65 | } |
| 66 | 66 | return dl_port; |
| @@ -1436,7 +1436,6 @@ esw_chains_create(struct mlx5_eswitch *esw, struct mlx5_flow_table *miss_fdb) · 1435 unmodified lines | ||
| 1436 | 1436 | |
| 1437 | 1437 | esw_init_chains_offload_flags(esw, &attr.flags); |
| 1438 | 1438 | attr.ns = MLX5_FLOW_NAMESPACE_FDB; |
| 1439 | − attr.fs_base_prio = FDB_TC_OFFLOAD; | |
| 1440 | 1439 | attr.max_grp_num = esw->params.large_group_num; |
| 1441 | 1440 | attr.default_ft = miss_fdb; |
| 1442 | 1441 | attr.mapping = esw->offloads.reg_c0_obj_pool; |
| @@ -2779,9 +2778,9 @@ static int mlx5_esw_offloads_set_ns_peer(struct mlx5_eswitch *esw, · 1336 unmodified lines | ||
| 2779 | 2778 | struct mlx5_eswitch *peer_esw, |
| 2780 | 2779 | bool pair) |
| 2781 | 2780 | { |
| 2782 | − u8 peer_idx = mlx5_get_dev_index(peer_esw->dev); | |
| 2781 | + u16 peer_vhca_id = MLX5_CAP_GEN(peer_esw->dev, vhca_id); | |
| 2782 | + u16 vhca_id = MLX5_CAP_GEN(esw->dev, vhca_id); | |
| 2783 | 2783 | struct mlx5_flow_root_namespace *peer_ns; |
| 2784 | − u8 idx = mlx5_get_dev_index(esw->dev); | |
| 2785 | 2784 | struct mlx5_flow_root_namespace *ns; |
| 2786 | 2785 | int err; |
| 2787 | 2786 | |
| @@ -2789,18 +2788,18 @@ static int mlx5_esw_offloads_set_ns_peer(struct mlx5_eswitch *esw, · 1 unmodified line | ||
| 2789 | 2788 | ns = esw->dev->priv.steering->fdb_root_ns; |
| 2790 | 2789 | |
| 2791 | 2790 | if (pair) { |
| 2792 | − err = mlx5_flow_namespace_set_peer(ns, peer_ns, peer_idx); | |
| 2791 | + err = mlx5_flow_namespace_set_peer(ns, peer_ns, peer_vhca_id); | |
| 2793 | 2792 | if (err) |
| 2794 | 2793 | return err; |
| 2795 | 2794 | |
| 2796 | − err = mlx5_flow_namespace_set_peer(peer_ns, ns, idx); | |
| 2795 | + err = mlx5_flow_namespace_set_peer(peer_ns, ns, vhca_id); | |
| 2797 | 2796 | if (err) { |
| 2798 | − mlx5_flow_namespace_set_peer(ns, NULL, peer_idx); | |
| 2797 | + mlx5_flow_namespace_set_peer(ns, NULL, peer_vhca_id); | |
| 2799 | 2798 | return err; |
| 2800 | 2799 | } |
| 2801 | 2800 | } else { |
| 2802 | − mlx5_flow_namespace_set_peer(ns, NULL, peer_idx); | |
| 2803 | − mlx5_flow_namespace_set_peer(peer_ns, NULL, idx); | |
| 2801 | + mlx5_flow_namespace_set_peer(ns, NULL, peer_vhca_id); | |
| 2802 | + mlx5_flow_namespace_set_peer(peer_ns, NULL, vhca_id); | |
| 2804 | 2803 | } |
| 2805 | 2804 | |
| 2806 | 2805 | return 0; |
| @@ -4196,7 +4195,7 @@ int mlx5_devlink_port_fn_migratable_set(struct devlink_port *port, bool enable, · 1389 unmodified lines | ||
| 4196 | 4195 | } |
| 4197 | 4196 | |
| 4198 | 4197 | hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability); |
| 4199 | − MLX5_SET(cmd_hca_cap_2, hca_caps, migratable, 1); | |
| 4198 | + MLX5_SET(cmd_hca_cap_2, hca_caps, migratable, enable); | |
| 4200 | 4199 | |
| 4201 | 4200 | err = mlx5_vport_set_other_func_cap(esw->dev, hca_caps, vport->vport, |
| 4202 | 4201 | MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE2); |
| @@ -140,7 +140,7 @@ static void mlx5_cmd_stub_modify_header_dealloc(struct mlx5_flow_root_namespace · 139 unmodified lines | ||
| 140 | 140 | |
| 141 | 141 | static int mlx5_cmd_stub_set_peer(struct mlx5_flow_root_namespace *ns, |
| 142 | 142 | struct mlx5_flow_root_namespace *peer_ns, |
| 143 | − u8 peer_idx) | |
| 143 | + u16 peer_vhca_id) | |
| 144 | 144 | { |
| 145 | 145 | return 0; |
| 146 | 146 | } |
| @@ -94,7 +94,7 @@ struct mlx5_flow_cmds { · 93 unmodified lines | ||
| 94 | 94 | |
| 95 | 95 | int (*set_peer)(struct mlx5_flow_root_namespace *ns, |
| 96 | 96 | struct mlx5_flow_root_namespace *peer_ns, |
| 97 | − u8 peer_idx); | |
| 97 | + u16 peer_vhca_id); | |
| 98 | 98 | |
| 99 | 99 | int (*create_ns)(struct mlx5_flow_root_namespace *ns); |
| 100 | 100 | int (*destroy_ns)(struct mlx5_flow_root_namespace *ns); |
| @@ -889,7 +889,7 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root, · 888 unmodified lines | ||
| 889 | 889 | struct fs_node *iter = list_entry(start, struct fs_node, list); |
| 890 | 890 | struct mlx5_flow_table *ft = NULL; |
| 891 | 891 | |
| 892 | − if (!root || root->type == FS_TYPE_PRIO_CHAINS) | |
| 892 | + if (!root) | |
| 893 | 893 | return NULL; |
| 894 | 894 | |
| 895 | 895 | list_for_each_advance_continue(iter, &root->children, reverse) { |
| @@ -905,20 +905,42 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root, · 9 unmodified lines | ||
| 905 | 905 | return ft; |
| 906 | 906 | } |
| 907 | 907 | |
| 908 | −/* If reverse is false then return the first flow table in next priority of | |
| 909 | − * prio in the tree, else return the last flow table in the previous priority | |
| 910 | − * of prio in the tree. | |
| 908 | +static struct fs_node *find_prio_chains_parent(struct fs_node *parent, | |
| 909 | + struct fs_node **child) | |
| 910 | +{ | |
| 911 | + struct fs_node *node = NULL; | |
| 912 | + | |
| 913 | + while (parent && parent->type != FS_TYPE_PRIO_CHAINS) { | |
| 914 | + node = parent; | |
| 915 | + parent = parent->parent; | |
| 916 | + } | |
| 917 | + | |
| 918 | + if (child) | |
| 919 | + *child = node; | |
| 920 | + | |
| 921 | + return parent; | |
| 922 | +} | |
| 923 | + | |
| 924 | +/* If reverse is false then return the first flow table next to the passed node | |
| 925 | + * in the tree, else return the last flow table before the node in the tree. | |
| 926 | + * If skip is true, skip the flow tables in the same prio_chains prio. | |
| 911 | 927 | */ |
| 912 | −static struct mlx5_flow_table *find_closest_ft(struct fs_prio *prio, bool reverse) | |
| 928 | +static struct mlx5_flow_table *find_closest_ft(struct fs_node *node, bool reverse, | |
| 929 | + bool skip) | |
| 913 | 930 | { |
| 931 | + struct fs_node *prio_chains_parent = NULL; | |
| 914 | 932 | struct mlx5_flow_table *ft = NULL; |
| 915 | 933 | struct fs_node *curr_node; |
| 916 | 934 | struct fs_node *parent; |
| 917 | 935 | |
| 918 | − parent = prio->node.parent; | |
| 919 | − curr_node = &prio->node; | |
| 936 | + if (skip) | |
| 937 | + prio_chains_parent = find_prio_chains_parent(node, NULL); | |
| 938 | + parent = node->parent; | |
| 939 | + curr_node = node; | |
| 920 | 940 | while (!ft && parent) { |
| 921 | − ft = find_closest_ft_recursive(parent, &curr_node->list, reverse); | |
| 941 | + if (parent != prio_chains_parent) | |
| 942 | + ft = find_closest_ft_recursive(parent, &curr_node->list, | |
| 943 | + reverse); | |
| 922 | 944 | curr_node = parent; |
| 923 | 945 | parent = curr_node->parent; |
| 924 | 946 | } |
| @@ -926,15 +948,15 @@ static struct mlx5_flow_table *find_closest_ft(struct fs_prio *prio, bool revers · 1 unmodified line | ||
| 926 | 948 | } |
| 927 | 949 | |
| 928 | 950 | /* Assuming all the tree is locked by mutex chain lock */ |
| 929 | −static struct mlx5_flow_table *find_next_chained_ft(struct fs_prio *prio) | |
| 951 | +static struct mlx5_flow_table *find_next_chained_ft(struct fs_node *node) | |
| 930 | 952 | { |
| 931 | − return find_closest_ft(prio, false); | |
| 953 | + return find_closest_ft(node, false, true); | |
| 932 | 954 | } |
| 933 | 955 | |
| 934 | 956 | /* Assuming all the tree is locked by mutex chain lock */ |
| 935 | −static struct mlx5_flow_table *find_prev_chained_ft(struct fs_prio *prio) | |
| 957 | +static struct mlx5_flow_table *find_prev_chained_ft(struct fs_node *node) | |
| 936 | 958 | { |
| 937 | − return find_closest_ft(prio, true); | |
| 959 | + return find_closest_ft(node, true, true); | |
| 938 | 960 | } |
| 939 | 961 | |
| 940 | 962 | static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft, |
| @@ -946,7 +968,7 @@ static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft, · 5 unmodified lines | ||
| 946 | 968 | next_ns = flow_act->action & MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS; |
| 947 | 969 | fs_get_obj(prio, next_ns ? ft->ns->node.parent : ft->node.parent); |
| 948 | 970 | |
| 949 | − return find_next_chained_ft(prio); | |
| 971 | + return find_next_chained_ft(&prio->node); | |
| 950 | 972 | } |
| 951 | 973 | |
| 952 | 974 | static int connect_fts_in_prio(struct mlx5_core_dev *dev, |
| @@ -970,21 +992,55 @@ static int connect_fts_in_prio(struct mlx5_core_dev *dev, · 17 unmodified lines | ||
| 970 | 992 | return 0; |
| 971 | 993 | } |
| 972 | 994 | |
| 995 | +static struct mlx5_flow_table *find_closet_ft_prio_chains(struct fs_node *node, | |
| 996 | + struct fs_node *parent, | |
| 997 | + struct fs_node **child, | |
| 998 | + bool reverse) | |
| 999 | +{ | |
| 1000 | + struct mlx5_flow_table *ft; | |
| 1001 | + | |
| 1002 | + ft = find_closest_ft(node, reverse, false); | |
| 1003 | + | |
| 1004 | + if (ft && parent == find_prio_chains_parent(&ft->node, child)) | |
| 1005 | + return ft; | |
| 1006 | + | |
| 1007 | + return NULL; | |
| 1008 | +} | |
| 1009 | + | |
| 973 | 1010 | /* Connect flow tables from previous priority of prio to ft */ |
| 974 | 1011 | static int connect_prev_fts(struct mlx5_core_dev *dev, |
| 975 | 1012 | struct mlx5_flow_table *ft, |
| 976 | 1013 | struct fs_prio *prio) |
| 977 | 1014 | { |
| 1015 | + struct fs_node *prio_parent, *parent = NULL, *child, *node; | |
| 978 | 1016 | struct mlx5_flow_table *prev_ft; |
| 1017 | + int err = 0; | |
| 1018 | + | |
| 1019 | + prio_parent = find_prio_chains_parent(&prio->node, &child); | |
| 1020 | + | |
| 1021 | + /* return directly if not under the first sub ns of prio_chains prio */ | |
| 1022 | + if (prio_parent && !list_is_first(&child->list, &prio_parent->children)) | |
| 1023 | + return 0; | |
| 979 | 1024 | |
| 980 | − prev_ft = find_prev_chained_ft(prio); | |
| 981 | − if (prev_ft) { | |
| 1025 | + prev_ft = find_prev_chained_ft(&prio->node); | |
| 1026 | + while (prev_ft) { | |
| 982 | 1027 | struct fs_prio *prev_prio; |
| 983 | 1028 | |
| 984 | 1029 | fs_get_obj(prev_prio, prev_ft->node.parent); |
| 985 | − return connect_fts_in_prio(dev, prev_prio, ft); | |
| 1030 | + err = connect_fts_in_prio(dev, prev_prio, ft); | |
| 1031 | + if (err) | |
| 1032 | + break; | |
| 1033 | + | |
| 1034 | + if (!parent) { | |
| 1035 | + parent = find_prio_chains_parent(&prev_prio->node, &child); | |
| 1036 | + if (!parent) | |
| 1037 | + break; | |
| 1038 | + } | |
| 1039 | + | |
| 1040 | + node = child; | |
| 1041 | + prev_ft = find_closet_ft_prio_chains(node, parent, &child, true); | |
| 986 | 1042 | } |
| 987 | − return 0; | |
| 1043 | + return err; | |
| 988 | 1044 | } |
| 989 | 1045 | |
| 990 | 1046 | static int update_root_ft_create(struct mlx5_flow_table *ft, struct fs_prio |
| @@ -1123,7 +1179,7 @@ static int connect_flow_table(struct mlx5_core_dev *dev, struct mlx5_flow_table · 132 unmodified lines | ||
| 1123 | 1179 | if (err) |
| 1124 | 1180 | return err; |
| 1125 | 1181 | |
| 1126 | − next_ft = first_ft ? first_ft : find_next_chained_ft(prio); | |
| 1182 | + next_ft = first_ft ? first_ft : find_next_chained_ft(&prio->node); | |
| 1127 | 1183 | err = connect_fwd_rules(dev, ft, next_ft); |
| 1128 | 1184 | if (err) |
| 1129 | 1185 | return err; |
| @@ -1198,7 +1254,7 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa · 68 unmodified lines | ||
| 1198 | 1254 | |
| 1199 | 1255 | tree_init_node(&ft->node, del_hw_flow_table, del_sw_flow_table); |
| 1200 | 1256 | next_ft = unmanaged ? ft_attr->next_ft : |
| 1201 | − find_next_chained_ft(fs_prio); | |
| 1257 | + find_next_chained_ft(&fs_prio->node); | |
| 1202 | 1258 | ft->def_miss_action = ns->def_miss_action; |
| 1203 | 1259 | ft->ns = ns; |
| 1204 | 1260 | err = root->cmds->create_flow_table(root, ft, ft_attr, next_ft); |
| @@ -2195,13 +2251,20 @@ EXPORT_SYMBOL(mlx5_del_flow_rules); · 990 unmodified lines | ||
| 2195 | 2251 | /* Assuming prio->node.children(flow tables) is sorted by level */ |
| 2196 | 2252 | static struct mlx5_flow_table *find_next_ft(struct mlx5_flow_table *ft) |
| 2197 | 2253 | { |
| 2254 | + struct fs_node *prio_parent, *child; | |
| 2198 | 2255 | struct fs_prio *prio; |
| 2199 | 2256 | |
| 2200 | 2257 | fs_get_obj(prio, ft->node.parent); |
| 2201 | 2258 | |
| 2202 | 2259 | if (!list_is_last(&ft->node.list, &prio->node.children)) |
| 2203 | 2260 | return list_next_entry(ft, node.list); |
| 2204 | − return find_next_chained_ft(prio); | |
| 2261 | + | |
| 2262 | + prio_parent = find_prio_chains_parent(&prio->node, &child); | |
| 2263 | + | |
| 2264 | + if (prio_parent && list_is_first(&child->list, &prio_parent->children)) | |
| 2265 | + return find_closest_ft(&prio->node, false, false); | |
| 2266 | + | |
| 2267 | + return find_next_chained_ft(&prio->node); | |
| 2205 | 2268 | } |
| 2206 | 2269 | |
| 2207 | 2270 | static int update_root_ft_destroy(struct mlx5_flow_table *ft) |
| @@ -3621,7 +3684,7 @@ void mlx5_destroy_match_definer(struct mlx5_core_dev *dev, · 1413 unmodified lines | ||
| 3621 | 3684 | |
| 3622 | 3685 | int mlx5_flow_namespace_set_peer(struct mlx5_flow_root_namespace *ns, |
| 3623 | 3686 | struct mlx5_flow_root_namespace *peer_ns, |
| 3624 | − u8 peer_idx) | |
| 3687 | + u16 peer_vhca_id) | |
| 3625 | 3688 | { |
| 3626 | 3689 | if (peer_ns && ns->mode != peer_ns->mode) { |
| 3627 | 3690 | mlx5_core_err(ns->dev, |
| @@ -3629,7 +3692,7 @@ int mlx5_flow_namespace_set_peer(struct mlx5_flow_root_namespace *ns, · 1 unmodified line | ||
| 3629 | 3692 | return -EINVAL; |
| 3630 | 3693 | } |
| 3631 | 3694 | |
| 3632 | − return ns->cmds->set_peer(ns, peer_ns, peer_idx); | |
| 3695 | + return ns->cmds->set_peer(ns, peer_ns, peer_vhca_id); | |
| 3633 | 3696 | } |
| 3634 | 3697 | |
| 3635 | 3698 | /* This function should be called only at init stage of the namespace. |
| @@ -303,7 +303,7 @@ const struct mlx5_flow_cmds *mlx5_fs_cmd_get_fw_cmds(void); · 302 unmodified lines | ||
| 303 | 303 | |
| 304 | 304 | int mlx5_flow_namespace_set_peer(struct mlx5_flow_root_namespace *ns, |
| 305 | 305 | struct mlx5_flow_root_namespace *peer_ns, |
| 306 | − u8 peer_idx); | |
| 306 | + u16 peer_vhca_id); | |
| 307 | 307 | |
| 308 | 308 | int mlx5_flow_namespace_set_mode(struct mlx5_flow_namespace *ns, |
| 309 | 309 | enum mlx5_flow_steering_mode mode); |
| @@ -574,7 +574,7 @@ static int __mlx5_lag_modify_definers_destinations(struct mlx5_lag *ldev, · 573 unmodified lines | ||
| 574 | 574 | for (i = 0; i < ldev->ports; i++) { |
| 575 | 575 | for (j = 0; j < ldev->buckets; j++) { |
| 576 | 576 | idx = i * ldev->buckets + j; |
| 577 | − if (ldev->v2p_map[i] == ports[i]) | |
| 577 | + if (ldev->v2p_map[idx] == ports[idx]) | |
| 578 | 578 | continue; |
| 579 | 579 | |
| 580 | 580 | dest.vport.vhca_id = MLX5_CAP_GEN(ldev->pf[ports[idx] - 1].dev, |
| @@ -227,10 +227,15 @@ static void mlx5_timestamp_overflow(struct work_struct *work) · 226 unmodified lines | ||
| 227 | 227 | clock = container_of(timer, struct mlx5_clock, timer); |
| 228 | 228 | mdev = container_of(clock, struct mlx5_core_dev, clock); |
| 229 | 229 | |
| 230 | + if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) | |
| 231 | + goto out; | |
| 232 | + | |
| 230 | 233 | write_seqlock_irqsave(&clock->lock, flags); |
| 231 | 234 | timecounter_read(&timer->tc); |
| 232 | 235 | mlx5_update_clock_info_page(mdev); |
| 233 | 236 | write_sequnlock_irqrestore(&clock->lock, flags); |
| 237 | + | |
| 238 | +out: | |
| 234 | 239 | schedule_delayed_work(&timer->overflow_work, timer->overflow_period); |
| 235 | 240 | } |
| 236 | 241 | |
| @@ -178,7 +178,7 @@ mlx5_chains_create_table(struct mlx5_fs_chains *chains, · 177 unmodified lines | ||
| 178 | 178 | if (!mlx5_chains_ignore_flow_level_supported(chains) || |
| 179 | 179 | (chain == 0 && prio == 1 && level == 0)) { |
| 180 | 180 | ft_attr.level = chains->fs_base_level; |
| 181 | − ft_attr.prio = chains->fs_base_prio; | |
| 181 | + ft_attr.prio = chains->fs_base_prio + prio - 1; | |
| 182 | 182 | ns = (chains->ns == MLX5_FLOW_NAMESPACE_FDB) ? |
| 183 | 183 | mlx5_get_fdb_sub_ns(chains->dev, chain) : |
| 184 | 184 | mlx5_get_flow_namespace(chains->dev, chains->ns); |
| @@ -1506,6 +1506,7 @@ void mlx5_uninit_one(struct mlx5_core_dev *dev) · 1505 unmodified lines | ||
| 1506 | 1506 | if (!test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) { |
| 1507 | 1507 | mlx5_core_warn(dev, "%s: interface is down, NOP\n", |
| 1508 | 1508 | __func__); |
| 1509 | + mlx5_devlink_params_unregister(priv_to_devlink(dev)); | |
| 1509 | 1510 | mlx5_cleanup_once(dev); |
| 1510 | 1511 | goto out; |
| 1511 | 1512 | } |
| @@ -1988,7 +1989,7 @@ static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev, · 476 unmodified lines | ||
| 1988 | 1989 | |
| 1989 | 1990 | mlx5_enter_error_state(dev, false); |
| 1990 | 1991 | mlx5_error_sw_reset(dev); |
| 1991 | − mlx5_unload_one(dev, true); | |
| 1992 | + mlx5_unload_one(dev, false); | |
| 1992 | 1993 | mlx5_drain_health_wq(dev); |
| 1993 | 1994 | mlx5_pci_disable_device(dev); |
| 1994 | 1995 | |
| @@ -361,7 +361,7 @@ static inline bool mlx5_core_is_ec_vf_vport(const struct mlx5_core_dev *dev, u16 · 360 unmodified lines | ||
| 361 | 361 | |
| 362 | 362 | static inline int mlx5_vport_to_func_id(const struct mlx5_core_dev *dev, u16 vport, bool ec_vf_func) |
| 363 | 363 | { |
| 364 | − return ec_vf_func ? vport - mlx5_core_ec_vf_vport_base(dev) | |
| 364 | + return ec_vf_func ? vport - mlx5_core_ec_vf_vport_base(dev) + 1 | |
| 365 | 365 | : vport; |
| 366 | 366 | } |
| 367 | 367 | |
| @@ -285,8 +285,7 @@ static u16 mlx5_get_max_vfs(struct mlx5_core_dev *dev) · 284 unmodified lines | ||
| 285 | 285 | host_total_vfs = MLX5_GET(query_esw_functions_out, out, |
| 286 | 286 | host_params_context.host_total_vfs); |
| 287 | 287 | kvfree(out); |
| 288 | − if (host_total_vfs) | |
| 289 | − return host_total_vfs; | |
| 288 | + return host_total_vfs; | |
| 290 | 289 | } |
| 291 | 290 | |
| 292 | 291 | done: |
| @@ -2079,7 +2079,7 @@ mlx5dr_action_create_dest_vport(struct mlx5dr_domain *dmn, · 2078 unmodified lines | ||
| 2079 | 2079 | |
| 2080 | 2080 | peer_vport = vhca_id_valid && mlx5_core_is_pf(dmn->mdev) && |
| 2081 | 2081 | (vhca_id != dmn->info.caps.gvmi); |
| 2082 | − vport_dmn = peer_vport ? dmn->peer_dmn[vhca_id] : dmn; | |
| 2082 | + vport_dmn = peer_vport ? xa_load(&dmn->peer_dmn_xa, vhca_id) : dmn; | |
| 2083 | 2083 | if (!vport_dmn) { |
| 2084 | 2084 | mlx5dr_dbg(dmn, "No peer vport domain for given vhca_id\n"); |
| 2085 | 2085 | return NULL; |
| @@ -564,11 +564,12 @@ int mlx5dr_cmd_create_reformat_ctx(struct mlx5_core_dev *mdev, · 563 unmodified lines | ||
| 564 | 564 | |
| 565 | 565 | err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out)); |
| 566 | 566 | if (err) |
| 567 | − return err; | |
| 567 | + goto err_free_in; | |
| 568 | 568 | |
| 569 | 569 | *reformat_id = MLX5_GET(alloc_packet_reformat_context_out, out, packet_reformat_id); |
| 570 | − kvfree(in); | |
| 571 | 570 | |
| 571 | +err_free_in: | |
| 572 | + kvfree(in); | |
| 572 | 573 | return err; |
| 573 | 574 | } |
| 574 | 575 | |
| @@ -475,6 +475,7 @@ mlx5dr_domain_create(struct mlx5_core_dev *mdev, enum mlx5dr_domain_type type) · 474 unmodified lines | ||
| 475 | 475 | mutex_init(&dmn->info.rx.mutex); |
| 476 | 476 | mutex_init(&dmn->info.tx.mutex); |
| 477 | 477 | xa_init(&dmn->definers_xa); |
| 478 | + xa_init(&dmn->peer_dmn_xa); | |
| 478 | 479 | |
| 479 | 480 | if (dr_domain_caps_init(mdev, dmn)) { |
| 480 | 481 | mlx5dr_err(dmn, "Failed init domain, no caps\n"); |
| @@ -507,6 +508,7 @@ mlx5dr_domain_create(struct mlx5_core_dev *mdev, enum mlx5dr_domain_type type) · 26 unmodified lines | ||
| 507 | 508 | uninit_caps: |
| 508 | 509 | dr_domain_caps_uninit(dmn); |
| 509 | 510 | def_xa_destroy: |
| 511 | + xa_destroy(&dmn->peer_dmn_xa); | |
| 510 | 512 | xa_destroy(&dmn->definers_xa); |
| 511 | 513 | kfree(dmn); |
| 512 | 514 | return NULL; |
| @@ -547,6 +549,7 @@ int mlx5dr_domain_destroy(struct mlx5dr_domain *dmn) · 34 unmodified lines | ||
| 547 | 549 | dr_domain_uninit_csum_recalc_fts(dmn); |
| 548 | 550 | dr_domain_uninit_resources(dmn); |
| 549 | 551 | dr_domain_caps_uninit(dmn); |
| 552 | + xa_destroy(&dmn->peer_dmn_xa); | |
| 550 | 553 | xa_destroy(&dmn->definers_xa); |
| 551 | 554 | mutex_destroy(&dmn->info.tx.mutex); |
| 552 | 555 | mutex_destroy(&dmn->info.rx.mutex); |
| @@ -556,17 +559,21 @@ int mlx5dr_domain_destroy(struct mlx5dr_domain *dmn) · 3 unmodified lines | ||
| 556 | 559 | |
| 557 | 560 | void mlx5dr_domain_set_peer(struct mlx5dr_domain *dmn, |
| 558 | 561 | struct mlx5dr_domain *peer_dmn, |
| 559 | − u8 peer_idx) | |
| 562 | + u16 peer_vhca_id) | |
| 560 | 563 | { |
| 564 | + struct mlx5dr_domain *peer; | |
| 565 | + | |
| 561 | 566 | mlx5dr_domain_lock(dmn); |
| 562 | 567 | |
| 563 | − if (dmn->peer_dmn[peer_idx]) | |
| 564 | − refcount_dec(&dmn->peer_dmn[peer_idx]->refcount); | |
| 568 | + peer = xa_load(&dmn->peer_dmn_xa, peer_vhca_id); | |
| 569 | + if (peer) | |
| 570 | + refcount_dec(&peer->refcount); | |
| 565 | 571 | |
| 566 | − dmn->peer_dmn[peer_idx] = peer_dmn; | |
| 572 | + WARN_ON(xa_err(xa_store(&dmn->peer_dmn_xa, peer_vhca_id, peer_dmn, GFP_KERNEL))); | |
| 567 | 573 | |
| 568 | − if (dmn->peer_dmn[peer_idx]) | |
| 569 | − refcount_inc(&dmn->peer_dmn[peer_idx]->refcount); | |
| 574 | + peer = xa_load(&dmn->peer_dmn_xa, peer_vhca_id); | |
| 575 | + if (peer) | |
| 576 | + refcount_inc(&peer->refcount); | |
| 570 | 577 | |
| 571 | 578 | mlx5dr_domain_unlock(dmn); |
| 572 | 579 | } |
| @@ -82,7 +82,7 @@ dr_ptrn_alloc_pattern(struct mlx5dr_ptrn_mgr *mgr, · 81 unmodified lines | ||
| 82 | 82 | u32 chunk_size; |
| 83 | 83 | u32 index; |
| 84 | 84 | |
| 85 | − chunk_size = ilog2(num_of_actions); | |
| 85 | + chunk_size = ilog2(roundup_pow_of_two(num_of_actions)); | |
| 86 | 86 | /* HW modify action index granularity is at least 64B */ |
| 87 | 87 | chunk_size = max_t(u32, chunk_size, DR_CHUNK_SIZE_8); |
| 88 | 88 | |
| @@ -1652,17 +1652,18 @@ dr_ste_v0_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value, · 1651 unmodified lines | ||
| 1652 | 1652 | struct mlx5dr_domain *dmn = sb->dmn; |
| 1653 | 1653 | struct mlx5dr_domain *vport_dmn; |
| 1654 | 1654 | u8 *bit_mask = sb->bit_mask; |
| 1655 | + struct mlx5dr_domain *peer; | |
| 1655 | 1656 | bool source_gvmi_set; |
| 1656 | 1657 | |
| 1657 | 1658 | DR_STE_SET_TAG(src_gvmi_qp, tag, source_qp, misc, source_sqn); |
| 1658 | 1659 | |
| 1659 | 1660 | if (sb->vhca_id_valid) { |
| 1661 | + peer = xa_load(&dmn->peer_dmn_xa, id); | |
| 1660 | 1662 | /* Find port GVMI based on the eswitch_owner_vhca_id */ |
| 1661 | 1663 | if (id == dmn->info.caps.gvmi) |
| 1662 | 1664 | vport_dmn = dmn; |
| 1663 | − else if (id < MLX5_MAX_PORTS && dmn->peer_dmn[id] && | |
| 1664 | − (id == dmn->peer_dmn[id]->info.caps.gvmi)) | |
| 1665 | − vport_dmn = dmn->peer_dmn[id]; | |
| 1665 | + else if (peer && (id == peer->info.caps.gvmi)) | |
| 1666 | + vport_dmn = peer; | |
| 1666 | 1667 | else |
| 1667 | 1668 | return -EINVAL; |
| 1668 | 1669 | |
| @@ -1984,16 +1984,17 @@ static int dr_ste_v1_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value, · 1983 unmodified lines | ||
| 1984 | 1984 | struct mlx5dr_domain *dmn = sb->dmn; |
| 1985 | 1985 | struct mlx5dr_domain *vport_dmn; |
| 1986 | 1986 | u8 *bit_mask = sb->bit_mask; |
| 1987 | + struct mlx5dr_domain *peer; | |
| 1987 | 1988 | |
| 1988 | 1989 | DR_STE_SET_TAG(src_gvmi_qp_v1, tag, source_qp, misc, source_sqn); |
| 1989 | 1990 | |
| 1990 | 1991 | if (sb->vhca_id_valid) { |
| 1992 | + peer = xa_load(&dmn->peer_dmn_xa, id); | |
| 1991 | 1993 | /* Find port GVMI based on the eswitch_owner_vhca_id */ |
| 1992 | 1994 | if (id == dmn->info.caps.gvmi) |
| 1993 | 1995 | vport_dmn = dmn; |
| 1994 | − else if (id < MLX5_MAX_PORTS && dmn->peer_dmn[id] && | |
| 1995 | − (id == dmn->peer_dmn[id]->info.caps.gvmi)) | |
| 1996 | − vport_dmn = dmn->peer_dmn[id]; | |
| 1996 | + else if (peer && (id == peer->info.caps.gvmi)) | |
| 1997 | + vport_dmn = peer; | |
| 1997 | 1998 | else |
| 1998 | 1999 | return -EINVAL; |
| 1999 | 2000 | |
| @@ -935,7 +935,6 @@ struct mlx5dr_domain_info { · 934 unmodified lines | ||
| 935 | 935 | }; |
| 936 | 936 | |
| 937 | 937 | struct mlx5dr_domain { |
| 938 | − struct mlx5dr_domain *peer_dmn[MLX5_MAX_PORTS]; | |
| 939 | 938 | struct mlx5_core_dev *mdev; |
| 940 | 939 | u32 pdn; |
| 941 | 940 | struct mlx5_uars_page *uar; |
| @@ -956,6 +955,7 @@ struct mlx5dr_domain { · 14 unmodified lines | ||
| 956 | 955 | struct list_head dbg_tbl_list; |
| 957 | 956 | struct mlx5dr_dbg_dump_info dump_info; |
| 958 | 957 | struct xarray definers_xa; |
| 958 | + struct xarray peer_dmn_xa; | |
| 959 | 959 | /* memory management statistics */ |
| 960 | 960 | u32 num_buddies[DR_ICM_TYPE_MAX]; |
| 961 | 961 | }; |
| @@ -781,14 +781,14 @@ restore_fte: · 780 unmodified lines | ||
| 781 | 781 | |
| 782 | 782 | static int mlx5_cmd_dr_set_peer(struct mlx5_flow_root_namespace *ns, |
| 783 | 783 | struct mlx5_flow_root_namespace *peer_ns, |
| 784 | − u8 peer_idx) | |
| 784 | + u16 peer_vhca_id) | |
| 785 | 785 | { |
| 786 | 786 | struct mlx5dr_domain *peer_domain = NULL; |
| 787 | 787 | |
| 788 | 788 | if (peer_ns) |
| 789 | 789 | peer_domain = peer_ns->fs_dr_domain.dr_domain; |
| 790 | 790 | mlx5dr_domain_set_peer(ns->fs_dr_domain.dr_domain, |
| 791 | − peer_domain, peer_idx); | |
| 791 | + peer_domain, peer_vhca_id); | |
| 792 | 792 | return 0; |
| 793 | 793 | } |
| 794 | 794 | |
| @@ -49,7 +49,7 @@ int mlx5dr_domain_sync(struct mlx5dr_domain *domain, u32 flags); · 48 unmodified lines | ||
| 49 | 49 | |
| 50 | 50 | void mlx5dr_domain_set_peer(struct mlx5dr_domain *dmn, |
| 51 | 51 | struct mlx5dr_domain *peer_dmn, |
| 52 | − u8 peer_idx); | |
| 52 | + u16 peer_vhca_id); | |
| 53 | 53 | |
| 54 | 54 | struct mlx5dr_table * |
| 55 | 55 | mlx5dr_table_create(struct mlx5dr_domain *domain, u32 level, u32 flags, |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/ethtool.h> |
| 9 | 9 | #include <linux/filter.h> |
| 10 | 10 | #include <linux/mm.h> |
| 11 | +#include <linux/pci.h> | |
| 11 | 12 | |
| 12 | 13 | #include <net/checksum.h> |
| 13 | 14 | #include <net/ip6_checksum.h> |
| @@ -2345,9 +2346,12 @@ int mana_attach(struct net_device *ndev) · 2331 unmodified lines | ||
| 2345 | 2346 | static int mana_dealloc_queues(struct net_device *ndev) |
| 2346 | 2347 | { |
| 2347 | 2348 | struct mana_port_context *apc = netdev_priv(ndev); |
| 2349 | + unsigned long timeout = jiffies + 120 * HZ; | |
| 2348 | 2350 | struct gdma_dev *gd = apc->ac->gdma_dev; |
| 2349 | 2351 | struct mana_txq *txq; |
| 2352 | + struct sk_buff *skb; | |
| 2350 | 2353 | int i, err; |
| 2354 | + u32 tsleep; | |
| 2351 | 2355 | |
| 2352 | 2356 | if (apc->port_is_up) |
| 2353 | 2357 | return -EINVAL; |
| @@ -2363,15 +2367,40 @@ static int mana_dealloc_queues(struct net_device *ndev) · 9 unmodified lines | ||
| 2363 | 2367 | * to false, but it doesn't matter since mana_start_xmit() drops any |
| 2364 | 2368 | * new packets due to apc->port_is_up being false. |
| 2365 | 2369 | * |
| 2366 | − * Drain all the in-flight TX packets | |
| 2370 | + * Drain all the in-flight TX packets. | |
| 2371 | + * A timeout of 120 seconds for all the queues is used. | |
| 2372 | + * This will break the while loop when h/w is not responding. | |
| 2373 | + * This value of 120 has been decided here considering max | |
| 2374 | + * number of queues. | |
| 2367 | 2375 | */ |
| 2376 | + | |
| 2368 | 2377 | for (i = 0; i < apc->num_queues; i++) { |
| 2369 | 2378 | txq = &apc->tx_qp[i].txq; |
| 2370 | − | |
| 2371 | − while (atomic_read(&txq->pending_sends) > 0) | |
| 2372 | − usleep_range(1000, 2000); | |
| 2379 | + tsleep = 1000; | |
| 2380 | + while (atomic_read(&txq->pending_sends) > 0 && | |
| 2381 | + time_before(jiffies, timeout)) { | |
| 2382 | + usleep_range(tsleep, tsleep + 1000); | |
| 2383 | + tsleep <<= 1; | |
| 2384 | + } | |
| 2385 | + if (atomic_read(&txq->pending_sends)) { | |
| 2386 | + err = pcie_flr(to_pci_dev(gd->gdma_context->dev)); | |
| 2387 | + if (err) { | |
| 2388 | + netdev_err(ndev, "flr failed %d with %d pkts pending in txq %u\n", | |
| 2389 | + err, atomic_read(&txq->pending_sends), | |
| 2390 | + txq->gdma_txq_id); | |
| 2391 | + } | |
| 2392 | + break; | |
| 2393 | + } | |
| 2373 | 2394 | } |
| 2374 | 2395 | |
| 2396 | + for (i = 0; i < apc->num_queues; i++) { | |
| 2397 | + txq = &apc->tx_qp[i].txq; | |
| 2398 | + while ((skb = skb_dequeue(&txq->pending_skbs))) { | |
| 2399 | + mana_unmap_skb(skb, apc); | |
| 2400 | + dev_kfree_skb_any(skb); | |
| 2401 | + } | |
| 2402 | + atomic_set(&txq->pending_sends, 0); | |
| 2403 | + } | |
| 2375 | 2404 | /* We're 100% sure the queues can no longer be woken up, because |
| 2376 | 2405 | * we're sure now mana_poll_tx_cq() can't be running. |
| 2377 | 2406 | */ |
| @@ -1817,6 +1817,7 @@ static int ionic_change_mtu(struct net_device *netdev, int new_mtu) · 1816 unmodified lines | ||
| 1817 | 1817 | static void ionic_tx_timeout_work(struct work_struct *ws) |
| 1818 | 1818 | { |
| 1819 | 1819 | struct ionic_lif *lif = container_of(ws, struct ionic_lif, tx_timeout_work); |
| 1820 | + int err; | |
| 1820 | 1821 | |
| 1821 | 1822 | if (test_bit(IONIC_LIF_F_FW_RESET, lif->state)) |
| 1822 | 1823 | return; |
| @@ -1829,8 +1830,11 @@ static void ionic_tx_timeout_work(struct work_struct *ws) · 6 unmodified lines | ||
| 1829 | 1830 | |
| 1830 | 1831 | mutex_lock(&lif->queue_lock); |
| 1831 | 1832 | ionic_stop_queues_reconfig(lif); |
| 1832 | − ionic_start_queues_reconfig(lif); | |
| 1833 | + err = ionic_start_queues_reconfig(lif); | |
| 1833 | 1834 | mutex_unlock(&lif->queue_lock); |
| 1835 | + | |
| 1836 | + if (err) | |
| 1837 | + dev_err(lif->ionic->dev, "%s: Restarting queues failed\n", __func__); | |
| 1834 | 1838 | } |
| 1835 | 1839 | |
| 1836 | 1840 | static void ionic_tx_timeout(struct net_device *netdev, unsigned int txqueue) |
| @@ -2800,17 +2804,22 @@ static int ionic_cmb_reconfig(struct ionic_lif *lif, · 963 unmodified lines | ||
| 2800 | 2804 | if (err) { |
| 2801 | 2805 | dev_err(lif->ionic->dev, |
| 2802 | 2806 | "CMB restore failed: %d\n", err); |
| 2803 | − goto errout; | |
| 2807 | + goto err_out; | |
| 2804 | 2808 | } |
| 2805 | 2809 | } |
| 2806 | 2810 | |
| 2807 | − ionic_start_queues_reconfig(lif); | |
| 2808 | − } else { | |
| 2809 | − /* This was detached in ionic_stop_queues_reconfig() */ | |
| 2810 | − netif_device_attach(lif->netdev); | |
| 2811 | + err = ionic_start_queues_reconfig(lif); | |
| 2812 | + if (err) { | |
| 2813 | + dev_err(lif->ionic->dev, | |
| 2814 | + "CMB reconfig failed: %d\n", err); | |
| 2815 | + goto err_out; | |
| 2816 | + } | |
| 2811 | 2817 | } |
| 2812 | 2818 | |
| 2813 | −errout: | |
| 2819 | +err_out: | |
| 2820 | + /* This was detached in ionic_stop_queues_reconfig() */ | |
| 2821 | + netif_device_attach(lif->netdev); | |
| 2822 | + | |
| 2814 | 2823 | return err; |
| 2815 | 2824 | } |
| 2816 | 2825 | |
| @@ -193,6 +193,22 @@ void qed_hw_remove(struct qed_dev *cdev); · 192 unmodified lines | ||
| 193 | 193 | */ |
| 194 | 194 | struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn); |
| 195 | 195 | |
| 196 | +/** | |
| 197 | + * qed_ptt_acquire_context(): Allocate a PTT window honoring the context | |
| 198 | + * atomicy. | |
| 199 | + * | |
| 200 | + * @p_hwfn: HW device data. | |
| 201 | + * @is_atomic: Hint from the caller - if the func can sleep or not. | |
| 202 | + * | |
| 203 | + * Context: The function should not sleep in case is_atomic == true. | |
| 204 | + * Return: struct qed_ptt. | |
| 205 | + * | |
| 206 | + * Should be called at the entry point to the driver | |
| 207 | + * (at the beginning of an exported function). | |
| 208 | + */ | |
| 209 | +struct qed_ptt *qed_ptt_acquire_context(struct qed_hwfn *p_hwfn, | |
| 210 | + bool is_atomic); | |
| 211 | + | |
| 196 | 212 | /** |
| 197 | 213 | * qed_ptt_release(): Release PTT Window. |
| 198 | 214 | * |
| @@ -693,13 +693,14 @@ static void _qed_fcoe_get_pstats(struct qed_hwfn *p_hwfn, · 692 unmodified lines | ||
| 693 | 693 | } |
| 694 | 694 | |
| 695 | 695 | static int qed_fcoe_get_stats(struct qed_hwfn *p_hwfn, |
| 696 | − struct qed_fcoe_stats *p_stats) | |
| 696 | + struct qed_fcoe_stats *p_stats, | |
| 697 | + bool is_atomic) | |
| 697 | 698 | { |
| 698 | 699 | struct qed_ptt *p_ptt; |
| 699 | 700 | |
| 700 | 701 | memset(p_stats, 0, sizeof(*p_stats)); |
| 701 | 702 | |
| 702 | − p_ptt = qed_ptt_acquire(p_hwfn); | |
| 703 | + p_ptt = qed_ptt_acquire_context(p_hwfn, is_atomic); | |
| 703 | 704 | |
| 704 | 705 | if (!p_ptt) { |
| 705 | 706 | DP_ERR(p_hwfn, "Failed to acquire ptt\n"); |
| @@ -973,19 +974,27 @@ static int qed_fcoe_destroy_conn(struct qed_dev *cdev, · 267 unmodified lines | ||
| 973 | 974 | QED_SPQ_MODE_EBLOCK, NULL); |
| 974 | 975 | } |
| 975 | 976 | |
| 977 | +static int qed_fcoe_stats_context(struct qed_dev *cdev, | |
| 978 | + struct qed_fcoe_stats *stats, | |
| 979 | + bool is_atomic) | |
| 980 | +{ | |
| 981 | + return qed_fcoe_get_stats(QED_AFFIN_HWFN(cdev), stats, is_atomic); | |
| 982 | +} | |
| 983 | + | |
| 976 | 984 | static int qed_fcoe_stats(struct qed_dev *cdev, struct qed_fcoe_stats *stats) |
| 977 | 985 | { |
| 978 | − return qed_fcoe_get_stats(QED_AFFIN_HWFN(cdev), stats); | |
| 986 | + return qed_fcoe_stats_context(cdev, stats, false); | |
| 979 | 987 | } |
| 980 | 988 | |
| 981 | 989 | void qed_get_protocol_stats_fcoe(struct qed_dev *cdev, |
| 982 | − struct qed_mcp_fcoe_stats *stats) | |
| 990 | + struct qed_mcp_fcoe_stats *stats, | |
| 991 | + bool is_atomic) | |
| 983 | 992 | { |
| 984 | 993 | struct qed_fcoe_stats proto_stats; |
| 985 | 994 | |
| 986 | 995 | /* Retrieve FW statistics */ |
| 987 | 996 | memset(&proto_stats, 0, sizeof(proto_stats)); |
| 988 | − if (qed_fcoe_stats(cdev, &proto_stats)) { | |
| 997 | + if (qed_fcoe_stats_context(cdev, &proto_stats, is_atomic)) { | |
| 989 | 998 | DP_VERBOSE(cdev, QED_MSG_STORAGE, |
| 990 | 999 | "Failed to collect FCoE statistics\n"); |
| 991 | 1000 | return; |
| @@ -28,8 +28,20 @@ int qed_fcoe_alloc(struct qed_hwfn *p_hwfn); · 27 unmodified lines | ||
| 28 | 28 | void qed_fcoe_setup(struct qed_hwfn *p_hwfn); |
| 29 | 29 | |
| 30 | 30 | void qed_fcoe_free(struct qed_hwfn *p_hwfn); |
| 31 | +/** | |
| 32 | + * qed_get_protocol_stats_fcoe(): Fills provided statistics | |
| 33 | + * struct with statistics. | |
| 34 | + * | |
| 35 | + * @cdev: Qed dev pointer. | |
| 36 | + * @stats: Points to struct that will be filled with statistics. | |
| 37 | + * @is_atomic: Hint from the caller - if the func can sleep or not. | |
| 38 | + * | |
| 39 | + * Context: The function should not sleep in case is_atomic == true. | |
| 40 | + * Return: Void. | |
| 41 | + */ | |
| 31 | 42 | void qed_get_protocol_stats_fcoe(struct qed_dev *cdev, |
| 32 | − struct qed_mcp_fcoe_stats *stats); | |
| 43 | + struct qed_mcp_fcoe_stats *stats, | |
| 44 | + bool is_atomic); | |
| 33 | 45 | #else /* CONFIG_QED_FCOE */ |
| 34 | 46 | static inline int qed_fcoe_alloc(struct qed_hwfn *p_hwfn) |
| 35 | 47 | { |
| @@ -40,7 +52,8 @@ static inline void qed_fcoe_setup(struct qed_hwfn *p_hwfn) {} · 4 unmodified lines | ||
| 40 | 52 | static inline void qed_fcoe_free(struct qed_hwfn *p_hwfn) {} |
| 41 | 53 | |
| 42 | 54 | static inline void qed_get_protocol_stats_fcoe(struct qed_dev *cdev, |
| 43 | − struct qed_mcp_fcoe_stats *stats) | |
| 55 | + struct qed_mcp_fcoe_stats *stats, | |
| 56 | + bool is_atomic) | |
| 44 | 57 | { |
| 45 | 58 | } |
| 46 | 59 | #endif /* CONFIG_QED_FCOE */ |
| @@ -23,7 +23,10 @@ · 22 unmodified lines | ||
| 23 | 23 | #include "qed_reg_addr.h" |
| 24 | 24 | #include "qed_sriov.h" |
| 25 | 25 | |
| 26 | −#define QED_BAR_ACQUIRE_TIMEOUT 1000 | |
| 26 | +#define QED_BAR_ACQUIRE_TIMEOUT_USLEEP_CNT 1000 | |
| 27 | +#define QED_BAR_ACQUIRE_TIMEOUT_USLEEP 1000 | |
| 28 | +#define QED_BAR_ACQUIRE_TIMEOUT_UDELAY_CNT 100000 | |
| 29 | +#define QED_BAR_ACQUIRE_TIMEOUT_UDELAY 10 | |
| 27 | 30 | |
| 28 | 31 | /* Invalid values */ |
| 29 | 32 | #define QED_BAR_INVALID_OFFSET (cpu_to_le32(-1)) |
| @@ -84,12 +87,22 @@ void qed_ptt_pool_free(struct qed_hwfn *p_hwfn) · 54 unmodified lines | ||
| 84 | 87 | } |
| 85 | 88 | |
| 86 | 89 | struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn) |
| 90 | +{ | |
| 91 | + return qed_ptt_acquire_context(p_hwfn, false); | |
| 92 | +} | |
| 93 | + | |
| 94 | +struct qed_ptt *qed_ptt_acquire_context(struct qed_hwfn *p_hwfn, bool is_atomic) | |
| 87 | 95 | { |
| 88 | 96 | struct qed_ptt *p_ptt; |
| 89 | − unsigned int i; | |
| 97 | + unsigned int i, count; | |
| 98 | + | |
| 99 | + if (is_atomic) | |
| 100 | + count = QED_BAR_ACQUIRE_TIMEOUT_UDELAY_CNT; | |
| 101 | + else | |
| 102 | + count = QED_BAR_ACQUIRE_TIMEOUT_USLEEP_CNT; | |
| 90 | 103 | |
| 91 | 104 | /* Take the free PTT from the list */ |
| 92 | − for (i = 0; i < QED_BAR_ACQUIRE_TIMEOUT; i++) { | |
| 105 | + for (i = 0; i < count; i++) { | |
| 93 | 106 | spin_lock_bh(&p_hwfn->p_ptt_pool->lock); |
| 94 | 107 | |
| 95 | 108 | if (!list_empty(&p_hwfn->p_ptt_pool->free_list)) { |
| @@ -105,7 +118,12 @@ struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn) · 9 unmodified lines | ||
| 105 | 118 | } |
| 106 | 119 | |
| 107 | 120 | spin_unlock_bh(&p_hwfn->p_ptt_pool->lock); |
| 108 | − usleep_range(1000, 2000); | |
| 121 | + | |
| 122 | + if (is_atomic) | |
| 123 | + udelay(QED_BAR_ACQUIRE_TIMEOUT_UDELAY); | |
| 124 | + else | |
| 125 | + usleep_range(QED_BAR_ACQUIRE_TIMEOUT_USLEEP, | |
| 126 | + QED_BAR_ACQUIRE_TIMEOUT_USLEEP * 2); | |
| 109 | 127 | } |
| 110 | 128 | |
| 111 | 129 | DP_NOTICE(p_hwfn, "PTT acquire timeout - failed to allocate PTT\n"); |
| @@ -999,13 +999,14 @@ static void _qed_iscsi_get_pstats(struct qed_hwfn *p_hwfn, · 998 unmodified lines | ||
| 999 | 999 | } |
| 1000 | 1000 | |
| 1001 | 1001 | static int qed_iscsi_get_stats(struct qed_hwfn *p_hwfn, |
| 1002 | − struct qed_iscsi_stats *stats) | |
| 1002 | + struct qed_iscsi_stats *stats, | |
| 1003 | + bool is_atomic) | |
| 1003 | 1004 | { |
| 1004 | 1005 | struct qed_ptt *p_ptt; |
| 1005 | 1006 | |
| 1006 | 1007 | memset(stats, 0, sizeof(*stats)); |
| 1007 | 1008 | |
| 1008 | − p_ptt = qed_ptt_acquire(p_hwfn); | |
| 1009 | + p_ptt = qed_ptt_acquire_context(p_hwfn, is_atomic); | |
| 1009 | 1010 | if (!p_ptt) { |
| 1010 | 1011 | DP_ERR(p_hwfn, "Failed to acquire ptt\n"); |
| 1011 | 1012 | return -EAGAIN; |
| @@ -1336,9 +1337,16 @@ static int qed_iscsi_destroy_conn(struct qed_dev *cdev, · 324 unmodified lines | ||
| 1336 | 1337 | QED_SPQ_MODE_EBLOCK, NULL); |
| 1337 | 1338 | } |
| 1338 | 1339 | |
| 1340 | +static int qed_iscsi_stats_context(struct qed_dev *cdev, | |
| 1341 | + struct qed_iscsi_stats *stats, | |
| 1342 | + bool is_atomic) | |
| 1343 | +{ | |
| 1344 | + return qed_iscsi_get_stats(QED_AFFIN_HWFN(cdev), stats, is_atomic); | |
| 1345 | +} | |
| 1346 | + | |
| 1339 | 1347 | static int qed_iscsi_stats(struct qed_dev *cdev, struct qed_iscsi_stats *stats) |
| 1340 | 1348 | { |
| 1341 | − return qed_iscsi_get_stats(QED_AFFIN_HWFN(cdev), stats); | |
| 1349 | + return qed_iscsi_stats_context(cdev, stats, false); | |
| 1342 | 1350 | } |
| 1343 | 1351 | |
| 1344 | 1352 | static int qed_iscsi_change_mac(struct qed_dev *cdev, |
| @@ -1358,13 +1366,14 @@ static int qed_iscsi_change_mac(struct qed_dev *cdev, · 13 unmodified lines | ||
| 1358 | 1366 | } |
| 1359 | 1367 | |
| 1360 | 1368 | void qed_get_protocol_stats_iscsi(struct qed_dev *cdev, |
| 1361 | − struct qed_mcp_iscsi_stats *stats) | |
| 1369 | + struct qed_mcp_iscsi_stats *stats, | |
| 1370 | + bool is_atomic) | |
| 1362 | 1371 | { |
| 1363 | 1372 | struct qed_iscsi_stats proto_stats; |
| 1364 | 1373 | |
| 1365 | 1374 | /* Retrieve FW statistics */ |
| 1366 | 1375 | memset(&proto_stats, 0, sizeof(proto_stats)); |
| 1367 | − if (qed_iscsi_stats(cdev, &proto_stats)) { | |
| 1376 | + if (qed_iscsi_stats_context(cdev, &proto_stats, is_atomic)) { | |
| 1368 | 1377 | DP_VERBOSE(cdev, QED_MSG_STORAGE, |
| 1369 | 1378 | "Failed to collect ISCSI statistics\n"); |
| 1370 | 1379 | return; |
| @@ -39,11 +39,14 @@ void qed_iscsi_free(struct qed_hwfn *p_hwfn); · 38 unmodified lines | ||
| 39 | 39 | * |
| 40 | 40 | * @cdev: Qed dev pointer. |
| 41 | 41 | * @stats: Points to struct that will be filled with statistics. |
| 42 | + * @is_atomic: Hint from the caller - if the func can sleep or not. | |
| 42 | 43 | * |
| 44 | + * Context: The function should not sleep in case is_atomic == true. | |
| 43 | 45 | * Return: Void. |
| 44 | 46 | */ |
| 45 | 47 | void qed_get_protocol_stats_iscsi(struct qed_dev *cdev, |
| 46 | − struct qed_mcp_iscsi_stats *stats); | |
| 48 | + struct qed_mcp_iscsi_stats *stats, | |
| 49 | + bool is_atomic); | |
| 47 | 50 | #else /* IS_ENABLED(CONFIG_QED_ISCSI) */ |
| 48 | 51 | static inline int qed_iscsi_alloc(struct qed_hwfn *p_hwfn) |
| 49 | 52 | { |
| @@ -56,7 +59,8 @@ static inline void qed_iscsi_free(struct qed_hwfn *p_hwfn) {} · 6 unmodified lines | ||
| 56 | 59 | |
| 57 | 60 | static inline void |
| 58 | 61 | qed_get_protocol_stats_iscsi(struct qed_dev *cdev, |
| 59 | − struct qed_mcp_iscsi_stats *stats) {} | |
| 62 | + struct qed_mcp_iscsi_stats *stats, | |
| 63 | + bool is_atomic) {} | |
| 60 | 64 | #endif /* IS_ENABLED(CONFIG_QED_ISCSI) */ |
| 61 | 65 | |
| 62 | 66 | #endif |
| @@ -1863,7 +1863,8 @@ static void __qed_get_vport_stats(struct qed_hwfn *p_hwfn, · 1862 unmodified lines | ||
| 1863 | 1863 | } |
| 1864 | 1864 | |
| 1865 | 1865 | static void _qed_get_vport_stats(struct qed_dev *cdev, |
| 1866 | − struct qed_eth_stats *stats) | |
| 1866 | + struct qed_eth_stats *stats, | |
| 1867 | + bool is_atomic) | |
| 1867 | 1868 | { |
| 1868 | 1869 | u8 fw_vport = 0; |
| 1869 | 1870 | int i; |
| @@ -1872,10 +1873,11 @@ static void _qed_get_vport_stats(struct qed_dev *cdev, · 2 unmodified lines | ||
| 1872 | 1873 | |
| 1873 | 1874 | for_each_hwfn(cdev, i) { |
| 1874 | 1875 | struct qed_hwfn *p_hwfn = &cdev->hwfns[i]; |
| 1875 | − struct qed_ptt *p_ptt = IS_PF(cdev) ? qed_ptt_acquire(p_hwfn) | |
| 1876 | − : NULL; | |
| 1876 | + struct qed_ptt *p_ptt; | |
| 1877 | 1877 | bool b_get_port_stats; |
| 1878 | 1878 | |
| 1879 | + p_ptt = IS_PF(cdev) ? qed_ptt_acquire_context(p_hwfn, is_atomic) | |
| 1880 | + : NULL; | |
| 1879 | 1881 | if (IS_PF(cdev)) { |
| 1880 | 1882 | /* The main vport index is relative first */ |
| 1881 | 1883 | if (qed_fw_vport(p_hwfn, 0, &fw_vport)) { |
| @@ -1900,6 +1902,13 @@ out: · 18 unmodified lines | ||
| 1900 | 1902 | } |
| 1901 | 1903 | |
| 1902 | 1904 | void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats) |
| 1905 | +{ | |
| 1906 | + qed_get_vport_stats_context(cdev, stats, false); | |
| 1907 | +} | |
| 1908 | + | |
| 1909 | +void qed_get_vport_stats_context(struct qed_dev *cdev, | |
| 1910 | + struct qed_eth_stats *stats, | |
| 1911 | + bool is_atomic) | |
| 1903 | 1912 | { |
| 1904 | 1913 | u32 i; |
| 1905 | 1914 | |
| @@ -1908,7 +1917,7 @@ void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats) · 2 unmodified lines | ||
| 1908 | 1917 | return; |
| 1909 | 1918 | } |
| 1910 | 1919 | |
| 1911 | − _qed_get_vport_stats(cdev, stats); | |
| 1920 | + _qed_get_vport_stats(cdev, stats, is_atomic); | |
| 1912 | 1921 | |
| 1913 | 1922 | if (!cdev->reset_stats) |
| 1914 | 1923 | return; |
| @@ -1960,7 +1969,7 @@ void qed_reset_vport_stats(struct qed_dev *cdev) · 45 unmodified lines | ||
| 1960 | 1969 | if (!cdev->reset_stats) { |
| 1961 | 1970 | DP_INFO(cdev, "Reset stats not allocated\n"); |
| 1962 | 1971 | } else { |
| 1963 | − _qed_get_vport_stats(cdev, cdev->reset_stats); | |
| 1972 | + _qed_get_vport_stats(cdev, cdev->reset_stats, false); | |
| 1964 | 1973 | cdev->reset_stats->common.link_change_count = 0; |
| 1965 | 1974 | } |
| 1966 | 1975 | } |
| @@ -249,8 +249,32 @@ qed_sp_eth_rx_queues_update(struct qed_hwfn *p_hwfn, · 248 unmodified lines | ||
| 249 | 249 | enum spq_mode comp_mode, |
| 250 | 250 | struct qed_spq_comp_cb *p_comp_data); |
| 251 | 251 | |
| 252 | +/** | |
| 253 | + * qed_get_vport_stats(): Fills provided statistics | |
| 254 | + * struct with statistics. | |
| 255 | + * | |
| 256 | + * @cdev: Qed dev pointer. | |
| 257 | + * @stats: Points to struct that will be filled with statistics. | |
| 258 | + * | |
| 259 | + * Return: Void. | |
| 260 | + */ | |
| 252 | 261 | void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats); |
| 253 | 262 | |
| 263 | +/** | |
| 264 | + * qed_get_vport_stats_context(): Fills provided statistics | |
| 265 | + * struct with statistics. | |
| 266 | + * | |
| 267 | + * @cdev: Qed dev pointer. | |
| 268 | + * @stats: Points to struct that will be filled with statistics. | |
| 269 | + * @is_atomic: Hint from the caller - if the func can sleep or not. | |
| 270 | + * | |
| 271 | + * Context: The function should not sleep in case is_atomic == true. | |
| 272 | + * Return: Void. | |
| 273 | + */ | |
| 274 | +void qed_get_vport_stats_context(struct qed_dev *cdev, | |
| 275 | + struct qed_eth_stats *stats, | |
| 276 | + bool is_atomic); | |
| 277 | + | |
| 254 | 278 | void qed_reset_vport_stats(struct qed_dev *cdev); |
| 255 | 279 | |
| 256 | 280 | /** |
| @@ -3092,7 +3092,7 @@ void qed_get_protocol_stats(struct qed_dev *cdev, · 3091 unmodified lines | ||
| 3092 | 3092 | |
| 3093 | 3093 | switch (type) { |
| 3094 | 3094 | case QED_MCP_LAN_STATS: |
| 3095 | − qed_get_vport_stats(cdev, ð_stats); | |
| 3095 | + qed_get_vport_stats_context(cdev, ð_stats, true); | |
| 3096 | 3096 | stats->lan_stats.ucast_rx_pkts = |
| 3097 | 3097 | eth_stats.common.rx_ucast_pkts; |
| 3098 | 3098 | stats->lan_stats.ucast_tx_pkts = |
| @@ -3100,10 +3100,10 @@ void qed_get_protocol_stats(struct qed_dev *cdev, · 1 unmodified line | ||
| 3100 | 3100 | stats->lan_stats.fcs_err = -1; |
| 3101 | 3101 | break; |
| 3102 | 3102 | case QED_MCP_FCOE_STATS: |
| 3103 | − qed_get_protocol_stats_fcoe(cdev, &stats->fcoe_stats); | |
| 3103 | + qed_get_protocol_stats_fcoe(cdev, &stats->fcoe_stats, true); | |
| 3104 | 3104 | break; |
| 3105 | 3105 | case QED_MCP_ISCSI_STATS: |
| 3106 | − qed_get_protocol_stats_iscsi(cdev, &stats->iscsi_stats); | |
| 3106 | + qed_get_protocol_stats_iscsi(cdev, &stats->iscsi_stats, true); | |
| 3107 | 3107 | break; |
| 3108 | 3108 | default: |
| 3109 | 3109 | DP_VERBOSE(cdev, QED_MSG_SP, |
| @@ -40,15 +40,16 @@ · 39 unmodified lines | ||
| 40 | 40 | */ |
| 41 | 41 | struct ef4_loopback_payload { |
| 42 | 42 | char pad[2]; /* Ensures ip is 4-byte aligned */ |
| 43 | − struct ethhdr header; | |
| 44 | − struct iphdr ip; | |
| 45 | − struct udphdr udp; | |
| 46 | − __be16 iteration; | |
| 47 | − char msg[64]; | |
| 43 | + struct_group_attr(packet, __packed, | |
| 44 | + struct ethhdr header; | |
| 45 | + struct iphdr ip; | |
| 46 | + struct udphdr udp; | |
| 47 | + __be16 iteration; | |
| 48 | + char msg[64]; | |
| 49 | + ); | |
| 48 | 50 | } __packed __aligned(4); |
| 49 | −#define EF4_LOOPBACK_PAYLOAD_LEN (sizeof(struct ef4_loopback_payload) - \ | |
| 50 | − offsetof(struct ef4_loopback_payload, \ | |
| 51 | − header)) | |
| 51 | +#define EF4_LOOPBACK_PAYLOAD_LEN \ | |
| 52 | + sizeof_field(struct ef4_loopback_payload, packet) | |
| 52 | 53 | |
| 53 | 54 | /* Loopback test source MAC address */ |
| 54 | 55 | static const u8 payload_source[ETH_ALEN] __aligned(2) = { |
| @@ -299,7 +300,7 @@ void ef4_loopback_rx_packet(struct ef4_nic *efx, · 244 unmodified lines | ||
| 299 | 300 | |
| 300 | 301 | payload = &state->payload; |
| 301 | 302 | |
| 302 | − memcpy(&received.header, buf_ptr, | |
| 303 | + memcpy(&received.packet, buf_ptr, | |
| 303 | 304 | min_t(int, pkt_len, EF4_LOOPBACK_PAYLOAD_LEN)); |
| 304 | 305 | received.ip.saddr = payload->ip.saddr; |
| 305 | 306 | if (state->offload_csum) |
| @@ -370,7 +371,7 @@ void ef4_loopback_rx_packet(struct ef4_nic *efx, · 64 unmodified lines | ||
| 370 | 371 | buf_ptr, pkt_len, 0); |
| 371 | 372 | netif_err(efx, drv, efx->net_dev, "expected packet:\n"); |
| 372 | 373 | print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1, |
| 373 | − &state->payload.header, EF4_LOOPBACK_PAYLOAD_LEN, | |
| 374 | + &state->payload.packet, EF4_LOOPBACK_PAYLOAD_LEN, | |
| 374 | 375 | 0); |
| 375 | 376 | } |
| 376 | 377 | #endif |
| @@ -440,6 +441,8 @@ static int ef4_begin_loopback(struct ef4_tx_queue *tx_queue) · 63 unmodified lines | ||
| 440 | 441 | payload->ip.saddr = htonl(INADDR_LOOPBACK | (i << 2)); |
| 441 | 442 | /* Strip off the leading padding */ |
| 442 | 443 | skb_pull(skb, offsetof(struct ef4_loopback_payload, header)); |
| 444 | + /* Strip off the trailing padding */ | |
| 445 | + skb_trim(skb, EF4_LOOPBACK_PAYLOAD_LEN); | |
| 443 | 446 | |
| 444 | 447 | /* Ensure everything we've written is visible to the |
| 445 | 448 | * interrupt handler. */ |
| @@ -43,15 +43,16 @@ · 42 unmodified lines | ||
| 43 | 43 | */ |
| 44 | 44 | struct efx_loopback_payload { |
| 45 | 45 | char pad[2]; /* Ensures ip is 4-byte aligned */ |
| 46 | − struct ethhdr header; | |
| 47 | − struct iphdr ip; | |
| 48 | − struct udphdr udp; | |
| 49 | − __be16 iteration; | |
| 50 | − char msg[64]; | |
| 46 | + struct_group_attr(packet, __packed, | |
| 47 | + struct ethhdr header; | |
| 48 | + struct iphdr ip; | |
| 49 | + struct udphdr udp; | |
| 50 | + __be16 iteration; | |
| 51 | + char msg[64]; | |
| 52 | + ); | |
| 51 | 53 | } __packed __aligned(4); |
| 52 | −#define EFX_LOOPBACK_PAYLOAD_LEN (sizeof(struct efx_loopback_payload) - \ | |
| 53 | − offsetof(struct efx_loopback_payload, \ | |
| 54 | − header)) | |
| 54 | +#define EFX_LOOPBACK_PAYLOAD_LEN \ | |
| 55 | + sizeof_field(struct efx_loopback_payload, packet) | |
| 55 | 56 | |
| 56 | 57 | /* Loopback test source MAC address */ |
| 57 | 58 | static const u8 payload_source[ETH_ALEN] __aligned(2) = { |
| @@ -297,7 +298,7 @@ void efx_loopback_rx_packet(struct efx_nic *efx, · 239 unmodified lines | ||
| 297 | 298 | |
| 298 | 299 | payload = &state->payload; |
| 299 | 300 | |
| 300 | − memcpy(&received.header, buf_ptr, | |
| 301 | + memcpy(&received.packet, buf_ptr, | |
| 301 | 302 | min_t(int, pkt_len, EFX_LOOPBACK_PAYLOAD_LEN)); |
| 302 | 303 | received.ip.saddr = payload->ip.saddr; |
| 303 | 304 | if (state->offload_csum) |
| @@ -368,7 +369,7 @@ void efx_loopback_rx_packet(struct efx_nic *efx, · 64 unmodified lines | ||
| 368 | 369 | buf_ptr, pkt_len, 0); |
| 369 | 370 | netif_err(efx, drv, efx->net_dev, "expected packet:\n"); |
| 370 | 371 | print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1, |
| 371 | − &state->payload.header, EFX_LOOPBACK_PAYLOAD_LEN, | |
| 372 | + &state->payload.packet, EFX_LOOPBACK_PAYLOAD_LEN, | |
| 372 | 373 | 0); |
| 373 | 374 | } |
| 374 | 375 | #endif |
| @@ -438,6 +439,8 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue) · 63 unmodified lines | ||
| 438 | 439 | payload->ip.saddr = htonl(INADDR_LOOPBACK | (i << 2)); |
| 439 | 440 | /* Strip off the leading padding */ |
| 440 | 441 | skb_pull(skb, offsetof(struct efx_loopback_payload, header)); |
| 442 | + /* Strip off the trailing padding */ | |
| 443 | + skb_trim(skb, EFX_LOOPBACK_PAYLOAD_LEN); | |
| 441 | 444 | |
| 442 | 445 | /* Ensure everything we've written is visible to the |
| 443 | 446 | * interrupt handler. */ |
| @@ -43,15 +43,16 @@ · 42 unmodified lines | ||
| 43 | 43 | */ |
| 44 | 44 | struct efx_loopback_payload { |
| 45 | 45 | char pad[2]; /* Ensures ip is 4-byte aligned */ |
| 46 | − struct ethhdr header; | |
| 47 | − struct iphdr ip; | |
| 48 | − struct udphdr udp; | |
| 49 | − __be16 iteration; | |
| 50 | − char msg[64]; | |
| 46 | + struct_group_attr(packet, __packed, | |
| 47 | + struct ethhdr header; | |
| 48 | + struct iphdr ip; | |
| 49 | + struct udphdr udp; | |
| 50 | + __be16 iteration; | |
| 51 | + char msg[64]; | |
| 52 | + ); | |
| 51 | 53 | } __packed __aligned(4); |
| 52 | −#define EFX_LOOPBACK_PAYLOAD_LEN (sizeof(struct efx_loopback_payload) - \ | |
| 53 | − offsetof(struct efx_loopback_payload, \ | |
| 54 | − header)) | |
| 54 | +#define EFX_LOOPBACK_PAYLOAD_LEN \ | |
| 55 | + sizeof_field(struct efx_loopback_payload, packet) | |
| 55 | 56 | |
| 56 | 57 | /* Loopback test source MAC address */ |
| 57 | 58 | static const u8 payload_source[ETH_ALEN] __aligned(2) = { |
| @@ -297,7 +298,7 @@ void efx_siena_loopback_rx_packet(struct efx_nic *efx, · 239 unmodified lines | ||
| 297 | 298 | |
| 298 | 299 | payload = &state->payload; |
| 299 | 300 | |
| 300 | − memcpy(&received.header, buf_ptr, | |
| 301 | + memcpy(&received.packet, buf_ptr, | |
| 301 | 302 | min_t(int, pkt_len, EFX_LOOPBACK_PAYLOAD_LEN)); |
| 302 | 303 | received.ip.saddr = payload->ip.saddr; |
| 303 | 304 | if (state->offload_csum) |
| @@ -368,7 +369,7 @@ void efx_siena_loopback_rx_packet(struct efx_nic *efx, · 64 unmodified lines | ||
| 368 | 369 | buf_ptr, pkt_len, 0); |
| 369 | 370 | netif_err(efx, drv, efx->net_dev, "expected packet:\n"); |
| 370 | 371 | print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1, |
| 371 | − &state->payload.header, EFX_LOOPBACK_PAYLOAD_LEN, | |
| 372 | + &state->payload.packet, EFX_LOOPBACK_PAYLOAD_LEN, | |
| 372 | 373 | 0); |
| 373 | 374 | } |
| 374 | 375 | #endif |
| @@ -438,6 +439,8 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue) · 63 unmodified lines | ||
| 438 | 439 | payload->ip.saddr = htonl(INADDR_LOOPBACK | (i << 2)); |
| 439 | 440 | /* Strip off the leading padding */ |
| 440 | 441 | skb_pull(skb, offsetof(struct efx_loopback_payload, header)); |
| 442 | + /* Strip off the trailing padding */ | |
| 443 | + skb_trim(skb, EFX_LOOPBACK_PAYLOAD_LEN); | |
| 441 | 444 | |
| 442 | 445 | /* Ensure everything we've written is visible to the |
| 443 | 446 | * interrupt handler. */ |
| @@ -1851,6 +1851,17 @@ static int netsec_of_probe(struct platform_device *pdev, · 1850 unmodified lines | ||
| 1851 | 1851 | return err; |
| 1852 | 1852 | } |
| 1853 | 1853 | |
| 1854 | + /* | |
| 1855 | + * SynQuacer is physically configured with TX and RX delays | |
| 1856 | + * but the standard firmware claimed otherwise for a long | |
| 1857 | + * time, ignore it. | |
| 1858 | + */ | |
| 1859 | + if (of_machine_is_compatible("socionext,developer-box") && | |
| 1860 | + priv->phy_interface != PHY_INTERFACE_MODE_RGMII_ID) { | |
| 1861 | + dev_warn(&pdev->dev, "Outdated firmware reports incorrect PHY mode, overriding\n"); | |
| 1862 | + priv->phy_interface = PHY_INTERFACE_MODE_RGMII_ID; | |
| 1863 | + } | |
| 1864 | + | |
| 1854 | 1865 | priv->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0); |
| 1855 | 1866 | if (!priv->phy_np) { |
| 1856 | 1867 | dev_err(&pdev->dev, "missing required property 'phy-handle'\n"); |
| @@ -234,7 +234,8 @@ static int tegra_mgbe_probe(struct platform_device *pdev) · 233 unmodified lines | ||
| 234 | 234 | res.addr = mgbe->regs; |
| 235 | 235 | res.irq = irq; |
| 236 | 236 | |
| 237 | − mgbe->clks = devm_kzalloc(&pdev->dev, sizeof(*mgbe->clks), GFP_KERNEL); | |
| 237 | + mgbe->clks = devm_kcalloc(&pdev->dev, ARRAY_SIZE(mgbe_clks), | |
| 238 | + sizeof(*mgbe->clks), GFP_KERNEL); | |
| 238 | 239 | if (!mgbe->clks) |
| 239 | 240 | return -ENOMEM; |
| 240 | 241 | |
| @@ -240,13 +240,15 @@ void stmmac_dwmac4_set_mac_addr(void __iomem *ioaddr, const u8 addr[6], · 239 unmodified lines | ||
| 240 | 240 | void stmmac_dwmac4_set_mac(void __iomem *ioaddr, bool enable) |
| 241 | 241 | { |
| 242 | 242 | u32 value = readl(ioaddr + GMAC_CONFIG); |
| 243 | + u32 old_val = value; | |
| 243 | 244 | |
| 244 | 245 | if (enable) |
| 245 | 246 | value |= GMAC_CONFIG_RE | GMAC_CONFIG_TE; |
| 246 | 247 | else |
| 247 | 248 | value &= ~(GMAC_CONFIG_TE | GMAC_CONFIG_RE); |
| 248 | 249 | |
| 249 | − writel(value, ioaddr + GMAC_CONFIG); | |
| 250 | + if (value != old_val) | |
| 251 | + writel(value, ioaddr + GMAC_CONFIG); | |
| 250 | 252 | } |
| 251 | 253 | |
| 252 | 254 | void stmmac_dwmac4_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, |
| @@ -1567,12 +1567,16 @@ static int temac_probe(struct platform_device *pdev) · 1566 unmodified lines | ||
| 1567 | 1567 | } |
| 1568 | 1568 | |
| 1569 | 1569 | /* Error handle returned DMA RX and TX interrupts */ |
| 1570 | − if (lp->rx_irq < 0) | |
| 1571 | − return dev_err_probe(&pdev->dev, lp->rx_irq, | |
| 1570 | + if (lp->rx_irq <= 0) { | |
| 1571 | + rc = lp->rx_irq ?: -EINVAL; | |
| 1572 | + return dev_err_probe(&pdev->dev, rc, | |
| 1572 | 1573 | "could not get DMA RX irq\n"); |
| 1573 | − if (lp->tx_irq < 0) | |
| 1574 | − return dev_err_probe(&pdev->dev, lp->tx_irq, | |
| 1574 | + } | |
| 1575 | + if (lp->tx_irq <= 0) { | |
| 1576 | + rc = lp->tx_irq ?: -EINVAL; | |
| 1577 | + return dev_err_probe(&pdev->dev, rc, | |
| 1575 | 1578 | "could not get DMA TX irq\n"); |
| 1579 | + } | |
| 1576 | 1580 | |
| 1577 | 1581 | if (temac_np) { |
| 1578 | 1582 | /* Retrieve the MAC address */ |
| @@ -273,16 +273,15 @@ static int ipa_filter_reset(struct ipa *ipa, bool modem) · 272 unmodified lines | ||
| 273 | 273 | if (ret) |
| 274 | 274 | return ret; |
| 275 | 275 | |
| 276 | − ret = ipa_filter_reset_table(ipa, true, false, modem); | |
| 277 | − if (ret) | |
| 276 | + ret = ipa_filter_reset_table(ipa, false, true, modem); | |
| 277 | + if (ret || !ipa_table_hash_support(ipa)) | |
| 278 | 278 | return ret; |
| 279 | 279 | |
| 280 | − ret = ipa_filter_reset_table(ipa, false, true, modem); | |
| 280 | + ret = ipa_filter_reset_table(ipa, true, false, modem); | |
| 281 | 281 | if (ret) |
| 282 | 282 | return ret; |
| 283 | − ret = ipa_filter_reset_table(ipa, true, true, modem); | |
| 284 | 283 | |
| 285 | − return ret; | |
| 284 | + return ipa_filter_reset_table(ipa, true, true, modem); | |
| 286 | 285 | } |
| 287 | 286 | |
| 288 | 287 | /* The AP routes and modem routes are each contiguous within the |
| @@ -291,12 +290,13 @@ static int ipa_filter_reset(struct ipa *ipa, bool modem) · 2 unmodified lines | ||
| 291 | 290 | * */ |
| 292 | 291 | static int ipa_route_reset(struct ipa *ipa, bool modem) |
| 293 | 292 | { |
| 293 | + bool hash_support = ipa_table_hash_support(ipa); | |
| 294 | 294 | u32 modem_route_count = ipa->modem_route_count; |
| 295 | 295 | struct gsi_trans *trans; |
| 296 | 296 | u16 first; |
| 297 | 297 | u16 count; |
| 298 | 298 | |
| 299 | − trans = ipa_cmd_trans_alloc(ipa, 4); | |
| 299 | + trans = ipa_cmd_trans_alloc(ipa, hash_support ? 4 : 2); | |
| 300 | 300 | if (!trans) { |
| 301 | 301 | dev_err(&ipa->pdev->dev, |
| 302 | 302 | "no transaction for %s route reset\n", |
| @@ -313,10 +313,12 @@ static int ipa_route_reset(struct ipa *ipa, bool modem) · 10 unmodified lines | ||
| 313 | 313 | } |
| 314 | 314 | |
| 315 | 315 | ipa_table_reset_add(trans, false, false, false, first, count); |
| 316 | − ipa_table_reset_add(trans, false, true, false, first, count); | |
| 317 | − | |
| 318 | 316 | ipa_table_reset_add(trans, false, false, true, first, count); |
| 319 | − ipa_table_reset_add(trans, false, true, true, first, count); | |
| 317 | + | |
| 318 | + if (hash_support) { | |
| 319 | + ipa_table_reset_add(trans, false, true, false, first, count); | |
| 320 | + ipa_table_reset_add(trans, false, true, true, first, count); | |
| 321 | + } | |
| 320 | 322 | |
| 321 | 323 | gsi_trans_commit_wait(trans); |
| 322 | 324 | |
| @@ -743,7 +743,7 @@ static bool macsec_post_decrypt(struct sk_buff *skb, struct macsec_secy *secy, u · 742 unmodified lines | ||
| 743 | 743 | u64_stats_update_begin(&rxsc_stats->syncp); |
| 744 | 744 | rxsc_stats->stats.InPktsLate++; |
| 745 | 745 | u64_stats_update_end(&rxsc_stats->syncp); |
| 746 | − secy->netdev->stats.rx_dropped++; | |
| 746 | + DEV_STATS_INC(secy->netdev, rx_dropped); | |
| 747 | 747 | return false; |
| 748 | 748 | } |
| 749 | 749 | |
| @@ -767,7 +767,7 @@ static bool macsec_post_decrypt(struct sk_buff *skb, struct macsec_secy *secy, u · 17 unmodified lines | ||
| 767 | 767 | rxsc_stats->stats.InPktsNotValid++; |
| 768 | 768 | u64_stats_update_end(&rxsc_stats->syncp); |
| 769 | 769 | this_cpu_inc(rx_sa->stats->InPktsNotValid); |
| 770 | − secy->netdev->stats.rx_errors++; | |
| 770 | + DEV_STATS_INC(secy->netdev, rx_errors); | |
| 771 | 771 | return false; |
| 772 | 772 | } |
| 773 | 773 | |
| @@ -1069,7 +1069,7 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb) · 295 unmodified lines | ||
| 1069 | 1069 | u64_stats_update_begin(&secy_stats->syncp); |
| 1070 | 1070 | secy_stats->stats.InPktsNoTag++; |
| 1071 | 1071 | u64_stats_update_end(&secy_stats->syncp); |
| 1072 | − macsec->secy.netdev->stats.rx_dropped++; | |
| 1072 | + DEV_STATS_INC(macsec->secy.netdev, rx_dropped); | |
| 1073 | 1073 | continue; |
| 1074 | 1074 | } |
| 1075 | 1075 | |
| @@ -1179,7 +1179,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) · 103 unmodified lines | ||
| 1179 | 1179 | u64_stats_update_begin(&secy_stats->syncp); |
| 1180 | 1180 | secy_stats->stats.InPktsBadTag++; |
| 1181 | 1181 | u64_stats_update_end(&secy_stats->syncp); |
| 1182 | − secy->netdev->stats.rx_errors++; | |
| 1182 | + DEV_STATS_INC(secy->netdev, rx_errors); | |
| 1183 | 1183 | goto drop_nosa; |
| 1184 | 1184 | } |
| 1185 | 1185 | |
| @@ -1196,7 +1196,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) · 10 unmodified lines | ||
| 1196 | 1196 | u64_stats_update_begin(&rxsc_stats->syncp); |
| 1197 | 1197 | rxsc_stats->stats.InPktsNotUsingSA++; |
| 1198 | 1198 | u64_stats_update_end(&rxsc_stats->syncp); |
| 1199 | − secy->netdev->stats.rx_errors++; | |
| 1199 | + DEV_STATS_INC(secy->netdev, rx_errors); | |
| 1200 | 1200 | if (active_rx_sa) |
| 1201 | 1201 | this_cpu_inc(active_rx_sa->stats->InPktsNotUsingSA); |
| 1202 | 1202 | goto drop_nosa; |
| @@ -1230,7 +1230,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) · 27 unmodified lines | ||
| 1230 | 1230 | u64_stats_update_begin(&rxsc_stats->syncp); |
| 1231 | 1231 | rxsc_stats->stats.InPktsLate++; |
| 1232 | 1232 | u64_stats_update_end(&rxsc_stats->syncp); |
| 1233 | − macsec->secy.netdev->stats.rx_dropped++; | |
| 1233 | + DEV_STATS_INC(macsec->secy.netdev, rx_dropped); | |
| 1234 | 1234 | goto drop; |
| 1235 | 1235 | } |
| 1236 | 1236 | } |
| @@ -1271,7 +1271,7 @@ deliver: · 34 unmodified lines | ||
| 1271 | 1271 | if (ret == NET_RX_SUCCESS) |
| 1272 | 1272 | count_rx(dev, len); |
| 1273 | 1273 | else |
| 1274 | − macsec->secy.netdev->stats.rx_dropped++; | |
| 1274 | + DEV_STATS_INC(macsec->secy.netdev, rx_dropped); | |
| 1275 | 1275 | |
| 1276 | 1276 | rcu_read_unlock(); |
| 1277 | 1277 | |
| @@ -1308,7 +1308,7 @@ nosci: · 30 unmodified lines | ||
| 1308 | 1308 | u64_stats_update_begin(&secy_stats->syncp); |
| 1309 | 1309 | secy_stats->stats.InPktsNoSCI++; |
| 1310 | 1310 | u64_stats_update_end(&secy_stats->syncp); |
| 1311 | − macsec->secy.netdev->stats.rx_errors++; | |
| 1311 | + DEV_STATS_INC(macsec->secy.netdev, rx_errors); | |
| 1312 | 1312 | continue; |
| 1313 | 1313 | } |
| 1314 | 1314 | |
| @@ -1327,7 +1327,7 @@ nosci: · 12 unmodified lines | ||
| 1327 | 1327 | secy_stats->stats.InPktsUnknownSCI++; |
| 1328 | 1328 | u64_stats_update_end(&secy_stats->syncp); |
| 1329 | 1329 | } else { |
| 1330 | − macsec->secy.netdev->stats.rx_dropped++; | |
| 1330 | + DEV_STATS_INC(macsec->secy.netdev, rx_dropped); | |
| 1331 | 1331 | } |
| 1332 | 1332 | } |
| 1333 | 1333 | |
| @@ -3422,7 +3422,7 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb, · 2088 unmodified lines | ||
| 3422 | 3422 | |
| 3423 | 3423 | if (!secy->operational) { |
| 3424 | 3424 | kfree_skb(skb); |
| 3425 | − dev->stats.tx_dropped++; | |
| 3425 | + DEV_STATS_INC(dev, tx_dropped); | |
| 3426 | 3426 | return NETDEV_TX_OK; |
| 3427 | 3427 | } |
| 3428 | 3428 | |
| @@ -3430,7 +3430,7 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb, · 1 unmodified line | ||
| 3430 | 3430 | skb = macsec_encrypt(skb, dev); |
| 3431 | 3431 | if (IS_ERR(skb)) { |
| 3432 | 3432 | if (PTR_ERR(skb) != -EINPROGRESS) |
| 3433 | − dev->stats.tx_dropped++; | |
| 3433 | + DEV_STATS_INC(dev, tx_dropped); | |
| 3434 | 3434 | return NETDEV_TX_OK; |
| 3435 | 3435 | } |
| 3436 | 3436 | |
| @@ -3667,9 +3667,9 @@ static void macsec_get_stats64(struct net_device *dev, · 230 unmodified lines | ||
| 3667 | 3667 | |
| 3668 | 3668 | dev_fetch_sw_netstats(s, dev->tstats); |
| 3669 | 3669 | |
| 3670 | − s->rx_dropped = dev->stats.rx_dropped; | |
| 3671 | − s->tx_dropped = dev->stats.tx_dropped; | |
| 3672 | − s->rx_errors = dev->stats.rx_errors; | |
| 3670 | + s->rx_dropped = atomic_long_read(&dev->stats.__rx_dropped); | |
| 3671 | + s->tx_dropped = atomic_long_read(&dev->stats.__tx_dropped); | |
| 3672 | + s->rx_errors = atomic_long_read(&dev->stats.__rx_errors); | |
| 3673 | 3673 | } |
| 3674 | 3674 | |
| 3675 | 3675 | static int macsec_get_iflink(const struct net_device *dev) |
| @@ -1746,6 +1746,7 @@ static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = { · 1745 unmodified lines | ||
| 1746 | 1746 | [IFLA_MACVLAN_MACADDR_COUNT] = { .type = NLA_U32 }, |
| 1747 | 1747 | [IFLA_MACVLAN_BC_QUEUE_LEN] = { .type = NLA_U32 }, |
| 1748 | 1748 | [IFLA_MACVLAN_BC_QUEUE_LEN_USED] = { .type = NLA_REJECT }, |
| 1749 | + [IFLA_MACVLAN_BC_CUTOFF] = { .type = NLA_S32 }, | |
| 1749 | 1750 | }; |
| 1750 | 1751 | |
| 1751 | 1752 | int macvlan_link_register(struct rtnl_link_ops *ops) |
| @@ -459,21 +459,27 @@ static int at803x_set_wol(struct phy_device *phydev, · 458 unmodified lines | ||
| 459 | 459 | phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i], |
| 460 | 460 | mac[(i * 2) + 1] | (mac[(i * 2)] << 8)); |
| 461 | 461 | |
| 462 | − /* Enable WOL function */ | |
| 463 | − ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL, | |
| 464 | − 0, AT803X_WOL_EN); | |
| 465 | − if (ret) | |
| 466 | − return ret; | |
| 462 | + /* Enable WOL function for 1588 */ | |
| 463 | + if (phydev->drv->phy_id == ATH8031_PHY_ID) { | |
| 464 | + ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, | |
| 465 | + AT803X_PHY_MMD3_WOL_CTRL, | |
| 466 | + 0, AT803X_WOL_EN); | |
| 467 | + if (ret) | |
| 468 | + return ret; | |
| 469 | + } | |
| 467 | 470 | /* Enable WOL interrupt */ |
| 468 | 471 | ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL); |
| 469 | 472 | if (ret) |
| 470 | 473 | return ret; |
| 471 | 474 | } else { |
| 472 | − /* Disable WoL function */ | |
| 473 | − ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL, | |
| 474 | − AT803X_WOL_EN, 0); | |
| 475 | − if (ret) | |
| 476 | − return ret; | |
| 475 | + /* Disable WoL function for 1588 */ | |
| 476 | + if (phydev->drv->phy_id == ATH8031_PHY_ID) { | |
| 477 | + ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, | |
| 478 | + AT803X_PHY_MMD3_WOL_CTRL, | |
| 479 | + AT803X_WOL_EN, 0); | |
| 480 | + if (ret) | |
| 481 | + return ret; | |
| 482 | + } | |
| 477 | 483 | /* Disable WOL interrupt */ |
| 478 | 484 | ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0); |
| 479 | 485 | if (ret) |
| @@ -508,11 +514,11 @@ static void at803x_get_wol(struct phy_device *phydev, · 28 unmodified lines | ||
| 508 | 514 | wol->supported = WAKE_MAGIC; |
| 509 | 515 | wol->wolopts = 0; |
| 510 | 516 | |
| 511 | − value = phy_read_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL); | |
| 517 | + value = phy_read(phydev, AT803X_INTR_ENABLE); | |
| 512 | 518 | if (value < 0) |
| 513 | 519 | return; |
| 514 | 520 | |
| 515 | − if (value & AT803X_WOL_EN) | |
| 521 | + if (value & AT803X_INTR_ENABLE_WOL) | |
| 516 | 522 | wol->wolopts |= WAKE_MAGIC; |
| 517 | 523 | } |
| 518 | 524 | |
| @@ -858,9 +864,6 @@ static int at803x_probe(struct phy_device *phydev) · 339 unmodified lines | ||
| 858 | 864 | if (phydev->drv->phy_id == ATH8031_PHY_ID) { |
| 859 | 865 | int ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG); |
| 860 | 866 | int mode_cfg; |
| 861 | − struct ethtool_wolinfo wol = { | |
| 862 | − .wolopts = 0, | |
| 863 | − }; | |
| 864 | 867 | |
| 865 | 868 | if (ccr < 0) |
| 866 | 869 | return ccr; |
| @@ -877,12 +880,14 @@ static int at803x_probe(struct phy_device *phydev) · 10 unmodified lines | ||
| 877 | 880 | break; |
| 878 | 881 | } |
| 879 | 882 | |
| 880 | − /* Disable WOL by default */ | |
| 881 | − ret = at803x_set_wol(phydev, &wol); | |
| 882 | − if (ret < 0) { | |
| 883 | − phydev_err(phydev, "failed to disable WOL on probe: %d\n", ret); | |
| 883 | + /* Disable WoL in 1588 register which is enabled | |
| 884 | + * by default | |
| 885 | + */ | |
| 886 | + ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, | |
| 887 | + AT803X_PHY_MMD3_WOL_CTRL, | |
| 888 | + AT803X_WOL_EN, 0); | |
| 889 | + if (ret) | |
| 884 | 890 | return ret; |
| 885 | − } | |
| 886 | 891 | } |
| 887 | 892 | |
| 888 | 893 | return 0; |
| @@ -2059,8 +2064,6 @@ static struct phy_driver at803x_driver[] = { · 1170 unmodified lines | ||
| 2059 | 2064 | .flags = PHY_POLL_CABLE_TEST, |
| 2060 | 2065 | .config_init = at803x_config_init, |
| 2061 | 2066 | .link_change_notify = at803x_link_change_notify, |
| 2062 | − .set_wol = at803x_set_wol, | |
| 2063 | − .get_wol = at803x_get_wol, | |
| 2064 | 2067 | .suspend = at803x_suspend, |
| 2065 | 2068 | .resume = at803x_resume, |
| 2066 | 2069 | /* PHY_BASIC_FEATURES */ |
| @@ -328,6 +328,13 @@ static int mv3310_power_up(struct phy_device *phydev) · 327 unmodified lines | ||
| 328 | 328 | ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL, |
| 329 | 329 | MV_V2_PORT_CTRL_PWRDOWN); |
| 330 | 330 | |
| 331 | + /* Sometimes, the power down bit doesn't clear immediately, and | |
| 332 | + * a read of this register causes the bit not to clear. Delay | |
| 333 | + * 100us to allow the PHY to come out of power down mode before | |
| 334 | + * the next access. | |
| 335 | + */ | |
| 336 | + udelay(100); | |
| 337 | + | |
| 331 | 338 | if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310 || |
| 332 | 339 | priv->firmware_ver < 0x00030000) |
| 333 | 340 | return ret; |
| @@ -534,7 +534,7 @@ static int tap_open(struct inode *inode, struct file *file) · 533 unmodified lines | ||
| 534 | 534 | q->sock.state = SS_CONNECTED; |
| 535 | 535 | q->sock.file = file; |
| 536 | 536 | q->sock.ops = &tap_socket_ops; |
| 537 | − sock_init_data_uid(&q->sock, &q->sk, inode->i_uid); | |
| 537 | + sock_init_data_uid(&q->sock, &q->sk, current_fsuid()); | |
| 538 | 538 | q->sk.sk_write_space = tap_sock_write_space; |
| 539 | 539 | q->sk.sk_destruct = tap_sock_destruct; |
| 540 | 540 | q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP; |
| @@ -2135,6 +2135,15 @@ static void team_setup_by_port(struct net_device *dev, · 2134 unmodified lines | ||
| 2135 | 2135 | dev->mtu = port_dev->mtu; |
| 2136 | 2136 | memcpy(dev->broadcast, port_dev->broadcast, port_dev->addr_len); |
| 2137 | 2137 | eth_hw_addr_inherit(dev, port_dev); |
| 2138 | + | |
| 2139 | + if (port_dev->flags & IFF_POINTOPOINT) { | |
| 2140 | + dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); | |
| 2141 | + dev->flags |= (IFF_POINTOPOINT | IFF_NOARP); | |
| 2142 | + } else if ((port_dev->flags & (IFF_BROADCAST | IFF_MULTICAST)) == | |
| 2143 | + (IFF_BROADCAST | IFF_MULTICAST)) { | |
| 2144 | + dev->flags |= (IFF_BROADCAST | IFF_MULTICAST); | |
| 2145 | + dev->flags &= ~(IFF_POINTOPOINT | IFF_NOARP); | |
| 2146 | + } | |
| 2138 | 2147 | } |
| 2139 | 2148 | |
| 2140 | 2149 | static int team_dev_type_check_change(struct net_device *dev, |
| @@ -1594,7 +1594,7 @@ static bool tun_can_build_skb(struct tun_struct *tun, struct tun_file *tfile, · 1593 unmodified lines | ||
| 1594 | 1594 | if (zerocopy) |
| 1595 | 1595 | return false; |
| 1596 | 1596 | |
| 1597 | − if (SKB_DATA_ALIGN(len + TUN_RX_PAD) + | |
| 1597 | + if (SKB_DATA_ALIGN(len + TUN_RX_PAD + XDP_PACKET_HEADROOM) + | |
| 1598 | 1598 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) > PAGE_SIZE) |
| 1599 | 1599 | return false; |
| 1600 | 1600 | |
| @@ -3469,7 +3469,7 @@ static int tun_chr_open(struct inode *inode, struct file * file) · 1868 unmodified lines | ||
| 3469 | 3469 | tfile->socket.file = file; |
| 3470 | 3470 | tfile->socket.ops = &tun_socket_ops; |
| 3471 | 3471 | |
| 3472 | − sock_init_data_uid(&tfile->socket, &tfile->sk, inode->i_uid); | |
| 3472 | + sock_init_data_uid(&tfile->socket, &tfile->sk, current_fsuid()); | |
| 3473 | 3473 | |
| 3474 | 3474 | tfile->sk.sk_write_space = tun_sock_write_space; |
| 3475 | 3475 | tfile->sk.sk_sndbuf = INT_MAX; |
| @@ -618,9 +618,23 @@ static const struct usb_device_id products[] = { · 617 unmodified lines | ||
| 618 | 618 | .match_flags = USB_DEVICE_ID_MATCH_INT_INFO |
| 619 | 619 | | USB_DEVICE_ID_MATCH_DEVICE, |
| 620 | 620 | .idVendor = 0x04DD, |
| 621 | + .idProduct = 0x8005, /* A-300 */ | |
| 622 | + ZAURUS_FAKE_INTERFACE, | |
| 623 | + .driver_info = 0, | |
| 624 | +}, { | |
| 625 | + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | |
| 626 | + | USB_DEVICE_ID_MATCH_DEVICE, | |
| 627 | + .idVendor = 0x04DD, | |
| 621 | 628 | .idProduct = 0x8006, /* B-500/SL-5600 */ |
| 622 | 629 | ZAURUS_MASTER_INTERFACE, |
| 623 | 630 | .driver_info = 0, |
| 631 | +}, { | |
| 632 | + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | |
| 633 | + | USB_DEVICE_ID_MATCH_DEVICE, | |
| 634 | + .idVendor = 0x04DD, | |
| 635 | + .idProduct = 0x8006, /* B-500/SL-5600 */ | |
| 636 | + ZAURUS_FAKE_INTERFACE, | |
| 637 | + .driver_info = 0, | |
| 624 | 638 | }, { |
| 625 | 639 | .match_flags = USB_DEVICE_ID_MATCH_INT_INFO |
| 626 | 640 | | USB_DEVICE_ID_MATCH_DEVICE, |
| @@ -628,6 +642,13 @@ static const struct usb_device_id products[] = { · 1 unmodified line | ||
| 628 | 642 | .idProduct = 0x8007, /* C-700 */ |
| 629 | 643 | ZAURUS_MASTER_INTERFACE, |
| 630 | 644 | .driver_info = 0, |
| 645 | +}, { | |
| 646 | + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | |
| 647 | + | USB_DEVICE_ID_MATCH_DEVICE, | |
| 648 | + .idVendor = 0x04DD, | |
| 649 | + .idProduct = 0x8007, /* C-700 */ | |
| 650 | + ZAURUS_FAKE_INTERFACE, | |
| 651 | + .driver_info = 0, | |
| 631 | 652 | }, { |
| 632 | 653 | .match_flags = USB_DEVICE_ID_MATCH_INT_INFO |
| 633 | 654 | | USB_DEVICE_ID_MATCH_DEVICE, |
| @@ -4224,8 +4224,6 @@ static void lan78xx_disconnect(struct usb_interface *intf) · 4223 unmodified lines | ||
| 4224 | 4224 | if (!dev) |
| 4225 | 4225 | return; |
| 4226 | 4226 | |
| 4227 | − set_bit(EVENT_DEV_DISCONNECT, &dev->flags); | |
| 4228 | − | |
| 4229 | 4227 | netif_napi_del(&dev->napi); |
| 4230 | 4228 | |
| 4231 | 4229 | udev = interface_to_usbdev(intf); |
| @@ -4233,6 +4231,8 @@ static void lan78xx_disconnect(struct usb_interface *intf) · 1 unmodified line | ||
| 4233 | 4231 | |
| 4234 | 4232 | unregister_netdev(net); |
| 4235 | 4233 | |
| 4234 | + timer_shutdown_sync(&dev->stat_monitor); | |
| 4235 | + set_bit(EVENT_DEV_DISCONNECT, &dev->flags); | |
| 4236 | 4236 | cancel_delayed_work_sync(&dev->wq); |
| 4237 | 4237 | |
| 4238 | 4238 | phydev = net->phydev; |
| @@ -4247,9 +4247,6 @@ static void lan78xx_disconnect(struct usb_interface *intf) · 8 unmodified lines | ||
| 4247 | 4247 | |
| 4248 | 4248 | usb_scuttle_anchored_urbs(&dev->deferred); |
| 4249 | 4249 | |
| 4250 | − if (timer_pending(&dev->stat_monitor)) | |
| 4251 | − del_timer_sync(&dev->stat_monitor); | |
| 4252 | − | |
| 4253 | 4250 | lan78xx_unbind(dev, intf); |
| 4254 | 4251 | |
| 4255 | 4252 | lan78xx_free_tx_resources(dev); |
| @@ -1423,6 +1423,7 @@ static const struct usb_device_id products[] = { · 1422 unmodified lines | ||
| 1423 | 1423 | {QMI_QUIRK_SET_DTR(0x2c7c, 0x0191, 4)}, /* Quectel EG91 */ |
| 1424 | 1424 | {QMI_QUIRK_SET_DTR(0x2c7c, 0x0195, 4)}, /* Quectel EG95 */ |
| 1425 | 1425 | {QMI_FIXED_INTF(0x2c7c, 0x0296, 4)}, /* Quectel BG96 */ |
| 1426 | + {QMI_QUIRK_SET_DTR(0x2c7c, 0x030e, 4)}, /* Quectel EM05GV2 */ | |
| 1426 | 1427 | {QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)}, /* Fibocom NL678 series */ |
| 1427 | 1428 | {QMI_FIXED_INTF(0x0489, 0xe0b4, 0)}, /* Foxconn T77W968 LTE */ |
| 1428 | 1429 | {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/ |
| @@ -289,9 +289,23 @@ static const struct usb_device_id products [] = { · 288 unmodified lines | ||
| 289 | 289 | .match_flags = USB_DEVICE_ID_MATCH_INT_INFO |
| 290 | 290 | | USB_DEVICE_ID_MATCH_DEVICE, |
| 291 | 291 | .idVendor = 0x04DD, |
| 292 | + .idProduct = 0x8005, /* A-300 */ | |
| 293 | + ZAURUS_FAKE_INTERFACE, | |
| 294 | + .driver_info = (unsigned long)&bogus_mdlm_info, | |
| 295 | +}, { | |
| 296 | + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | |
| 297 | + | USB_DEVICE_ID_MATCH_DEVICE, | |
| 298 | + .idVendor = 0x04DD, | |
| 292 | 299 | .idProduct = 0x8006, /* B-500/SL-5600 */ |
| 293 | 300 | ZAURUS_MASTER_INTERFACE, |
| 294 | 301 | .driver_info = ZAURUS_PXA_INFO, |
| 302 | +}, { | |
| 303 | + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | |
| 304 | + | USB_DEVICE_ID_MATCH_DEVICE, | |
| 305 | + .idVendor = 0x04DD, | |
| 306 | + .idProduct = 0x8006, /* B-500/SL-5600 */ | |
| 307 | + ZAURUS_FAKE_INTERFACE, | |
| 308 | + .driver_info = (unsigned long)&bogus_mdlm_info, | |
| 295 | 309 | }, { |
| 296 | 310 | .match_flags = USB_DEVICE_ID_MATCH_INT_INFO |
| 297 | 311 | | USB_DEVICE_ID_MATCH_DEVICE, |
| @@ -299,6 +313,13 @@ static const struct usb_device_id products [] = { · 1 unmodified line | ||
| 299 | 313 | .idProduct = 0x8007, /* C-700 */ |
| 300 | 314 | ZAURUS_MASTER_INTERFACE, |
| 301 | 315 | .driver_info = ZAURUS_PXA_INFO, |
| 316 | +}, { | |
| 317 | + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | |
| 318 | + | USB_DEVICE_ID_MATCH_DEVICE, | |
| 319 | + .idVendor = 0x04DD, | |
| 320 | + .idProduct = 0x8007, /* C-700 */ | |
| 321 | + ZAURUS_FAKE_INTERFACE, | |
| 322 | + .driver_info = (unsigned long)&bogus_mdlm_info, | |
| 302 | 323 | }, { |
| 303 | 324 | .match_flags = USB_DEVICE_ID_MATCH_INT_INFO |
| 304 | 325 | | USB_DEVICE_ID_MATCH_DEVICE, |
| @@ -4219,6 +4219,8 @@ static int virtnet_probe(struct virtio_device *vdev) · 4218 unmodified lines | ||
| 4219 | 4219 | if (vi->has_rss || vi->has_rss_hash_report) |
| 4220 | 4220 | virtnet_init_default_rss(vi); |
| 4221 | 4221 | |
| 4222 | + _virtnet_set_queues(vi, vi->curr_queue_pairs); | |
| 4223 | + | |
| 4222 | 4224 | /* serialize netdev register + virtio_device_ready() with ndo_open() */ |
| 4223 | 4225 | rtnl_lock(); |
| 4224 | 4226 | |
| @@ -4257,8 +4259,6 @@ static int virtnet_probe(struct virtio_device *vdev) · 32 unmodified lines | ||
| 4257 | 4259 | goto free_unregister_netdev; |
| 4258 | 4260 | } |
| 4259 | 4261 | |
| 4260 | − virtnet_set_queues(vi, vi->curr_queue_pairs); | |
| 4261 | − | |
| 4262 | 4262 | /* Assume link up if device can't report link status, |
| 4263 | 4263 | otherwise get link status from config. */ |
| 4264 | 4264 | netif_carrier_off(dev); |
| @@ -623,6 +623,32 @@ static int vxlan_fdb_append(struct vxlan_fdb *f, · 622 unmodified lines | ||
| 623 | 623 | return 1; |
| 624 | 624 | } |
| 625 | 625 | |
| 626 | +static bool vxlan_parse_gpe_proto(struct vxlanhdr *hdr, __be16 *protocol) | |
| 627 | +{ | |
| 628 | + struct vxlanhdr_gpe *gpe = (struct vxlanhdr_gpe *)hdr; | |
| 629 | + | |
| 630 | + /* Need to have Next Protocol set for interfaces in GPE mode. */ | |
| 631 | + if (!gpe->np_applied) | |
| 632 | + return false; | |
| 633 | + /* "The initial version is 0. If a receiver does not support the | |
| 634 | + * version indicated it MUST drop the packet. | |
| 635 | + */ | |
| 636 | + if (gpe->version != 0) | |
| 637 | + return false; | |
| 638 | + /* "When the O bit is set to 1, the packet is an OAM packet and OAM | |
| 639 | + * processing MUST occur." However, we don't implement OAM | |
| 640 | + * processing, thus drop the packet. | |
| 641 | + */ | |
| 642 | + if (gpe->oam_flag) | |
| 643 | + return false; | |
| 644 | + | |
| 645 | + *protocol = tun_p_to_eth_p(gpe->next_protocol); | |
| 646 | + if (!*protocol) | |
| 647 | + return false; | |
| 648 | + | |
| 649 | + return true; | |
| 650 | +} | |
| 651 | + | |
| 626 | 652 | static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb, |
| 627 | 653 | unsigned int off, |
| 628 | 654 | struct vxlanhdr *vh, size_t hdrlen, |
| @@ -649,26 +675,24 @@ static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb, · 20 unmodified lines | ||
| 649 | 675 | return vh; |
| 650 | 676 | } |
| 651 | 677 | |
| 652 | −static struct sk_buff *vxlan_gro_receive(struct sock *sk, | |
| 653 | − struct list_head *head, | |
| 654 | − struct sk_buff *skb) | |
| 678 | +static struct vxlanhdr *vxlan_gro_prepare_receive(struct sock *sk, | |
| 679 | + struct list_head *head, | |
| 680 | + struct sk_buff *skb, | |
| 681 | + struct gro_remcsum *grc) | |
| 655 | 682 | { |
| 656 | − struct sk_buff *pp = NULL; | |
| 657 | 683 | struct sk_buff *p; |
| 658 | 684 | struct vxlanhdr *vh, *vh2; |
| 659 | 685 | unsigned int hlen, off_vx; |
| 660 | − int flush = 1; | |
| 661 | 686 | struct vxlan_sock *vs = rcu_dereference_sk_user_data(sk); |
| 662 | 687 | __be32 flags; |
| 663 | − struct gro_remcsum grc; | |
| 664 | 688 | |
| 665 | − skb_gro_remcsum_init(&grc); | |
| 689 | + skb_gro_remcsum_init(grc); | |
| 666 | 690 | |
| 667 | 691 | off_vx = skb_gro_offset(skb); |
| 668 | 692 | hlen = off_vx + sizeof(*vh); |
| 669 | 693 | vh = skb_gro_header(skb, hlen, off_vx); |
| 670 | 694 | if (unlikely(!vh)) |
| 671 | − goto out; | |
| 695 | + return NULL; | |
| 672 | 696 | |
| 673 | 697 | skb_gro_postpull_rcsum(skb, vh, sizeof(struct vxlanhdr)); |
| 674 | 698 | |
| @@ -676,12 +700,12 @@ static struct sk_buff *vxlan_gro_receive(struct sock *sk, · 1 unmodified line | ||
| 676 | 700 | |
| 677 | 701 | if ((flags & VXLAN_HF_RCO) && (vs->flags & VXLAN_F_REMCSUM_RX)) { |
| 678 | 702 | vh = vxlan_gro_remcsum(skb, off_vx, vh, sizeof(struct vxlanhdr), |
| 679 | − vh->vx_vni, &grc, | |
| 703 | + vh->vx_vni, grc, | |
| 680 | 704 | !!(vs->flags & |
| 681 | 705 | VXLAN_F_REMCSUM_NOPARTIAL)); |
| 682 | 706 | |
| 683 | 707 | if (!vh) |
| 684 | − goto out; | |
| 708 | + return NULL; | |
| 685 | 709 | } |
| 686 | 710 | |
| 687 | 711 | skb_gro_pull(skb, sizeof(struct vxlanhdr)); /* pull vxlan header */ |
| @@ -698,12 +722,48 @@ static struct sk_buff *vxlan_gro_receive(struct sock *sk, · 10 unmodified lines | ||
| 698 | 722 | } |
| 699 | 723 | } |
| 700 | 724 | |
| 701 | − pp = call_gro_receive(eth_gro_receive, head, skb); | |
| 702 | − flush = 0; | |
| 725 | + return vh; | |
| 726 | +} | |
| 703 | 727 | |
| 704 | −out: | |
| 728 | +static struct sk_buff *vxlan_gro_receive(struct sock *sk, | |
| 729 | + struct list_head *head, | |
| 730 | + struct sk_buff *skb) | |
| 731 | +{ | |
| 732 | + struct sk_buff *pp = NULL; | |
| 733 | + struct gro_remcsum grc; | |
| 734 | + int flush = 1; | |
| 735 | + | |
| 736 | + if (vxlan_gro_prepare_receive(sk, head, skb, &grc)) { | |
| 737 | + pp = call_gro_receive(eth_gro_receive, head, skb); | |
| 738 | + flush = 0; | |
| 739 | + } | |
| 705 | 740 | skb_gro_flush_final_remcsum(skb, pp, flush, &grc); |
| 741 | + return pp; | |
| 742 | +} | |
| 743 | + | |
| 744 | +static struct sk_buff *vxlan_gpe_gro_receive(struct sock *sk, | |
| 745 | + struct list_head *head, | |
| 746 | + struct sk_buff *skb) | |
| 747 | +{ | |
| 748 | + const struct packet_offload *ptype; | |
| 749 | + struct sk_buff *pp = NULL; | |
| 750 | + struct gro_remcsum grc; | |
| 751 | + struct vxlanhdr *vh; | |
| 752 | + __be16 protocol; | |
| 753 | + int flush = 1; | |
| 706 | 754 | |
| 755 | + vh = vxlan_gro_prepare_receive(sk, head, skb, &grc); | |
| 756 | + if (vh) { | |
| 757 | + if (!vxlan_parse_gpe_proto(vh, &protocol)) | |
| 758 | + goto out; | |
| 759 | + ptype = gro_find_receive_by_type(protocol); | |
| 760 | + if (!ptype) | |
| 761 | + goto out; | |
| 762 | + pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb); | |
| 763 | + flush = 0; | |
| 764 | + } | |
| 765 | +out: | |
| 766 | + skb_gro_flush_final_remcsum(skb, pp, flush, &grc); | |
| 707 | 767 | return pp; |
| 708 | 768 | } |
| 709 | 769 | |
| @@ -715,6 +775,21 @@ static int vxlan_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff) · 5 unmodified lines | ||
| 715 | 775 | return eth_gro_complete(skb, nhoff + sizeof(struct vxlanhdr)); |
| 716 | 776 | } |
| 717 | 777 | |
| 778 | +static int vxlan_gpe_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff) | |
| 779 | +{ | |
| 780 | + struct vxlanhdr *vh = (struct vxlanhdr *)(skb->data + nhoff); | |
| 781 | + const struct packet_offload *ptype; | |
| 782 | + int err = -ENOSYS; | |
| 783 | + __be16 protocol; | |
| 784 | + | |
| 785 | + if (!vxlan_parse_gpe_proto(vh, &protocol)) | |
| 786 | + return err; | |
| 787 | + ptype = gro_find_complete_by_type(protocol); | |
| 788 | + if (ptype) | |
| 789 | + err = ptype->callbacks.gro_complete(skb, nhoff + sizeof(struct vxlanhdr)); | |
| 790 | + return err; | |
| 791 | +} | |
| 792 | + | |
| 718 | 793 | static struct vxlan_fdb *vxlan_fdb_alloc(struct vxlan_dev *vxlan, const u8 *mac, |
| 719 | 794 | __u16 state, __be32 src_vni, |
| 720 | 795 | __u16 ndm_flags) |
| @@ -1525,35 +1600,6 @@ out: · 804 unmodified lines | ||
| 1525 | 1600 | unparsed->vx_flags &= ~VXLAN_GBP_USED_BITS; |
| 1526 | 1601 | } |
| 1527 | 1602 | |
| 1528 | −static bool vxlan_parse_gpe_hdr(struct vxlanhdr *unparsed, | |
| 1529 | − __be16 *protocol, | |
| 1530 | − struct sk_buff *skb, u32 vxflags) | |
| 1531 | −{ | |
| 1532 | − struct vxlanhdr_gpe *gpe = (struct vxlanhdr_gpe *)unparsed; | |
| 1533 | − | |
| 1534 | − /* Need to have Next Protocol set for interfaces in GPE mode. */ | |
| 1535 | − if (!gpe->np_applied) | |
| 1536 | − return false; | |
| 1537 | − /* "The initial version is 0. If a receiver does not support the | |
| 1538 | − * version indicated it MUST drop the packet. | |
| 1539 | − */ | |
| 1540 | − if (gpe->version != 0) | |
| 1541 | − return false; | |
| 1542 | − /* "When the O bit is set to 1, the packet is an OAM packet and OAM | |
| 1543 | − * processing MUST occur." However, we don't implement OAM | |
| 1544 | − * processing, thus drop the packet. | |
| 1545 | − */ | |
| 1546 | − if (gpe->oam_flag) | |
| 1547 | − return false; | |
| 1548 | − | |
| 1549 | − *protocol = tun_p_to_eth_p(gpe->next_protocol); | |
| 1550 | − if (!*protocol) | |
| 1551 | − return false; | |
| 1552 | − | |
| 1553 | − unparsed->vx_flags &= ~VXLAN_GPE_USED_BITS; | |
| 1554 | − return true; | |
| 1555 | −} | |
| 1556 | − | |
| 1557 | 1603 | static bool vxlan_set_mac(struct vxlan_dev *vxlan, |
| 1558 | 1604 | struct vxlan_sock *vs, |
| 1559 | 1605 | struct sk_buff *skb, __be32 vni) |
| @@ -1655,8 +1701,9 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) · 95 unmodified lines | ||
| 1655 | 1701 | * used by VXLAN extensions if explicitly requested. |
| 1656 | 1702 | */ |
| 1657 | 1703 | if (vs->flags & VXLAN_F_GPE) { |
| 1658 | − if (!vxlan_parse_gpe_hdr(&unparsed, &protocol, skb, vs->flags)) | |
| 1704 | + if (!vxlan_parse_gpe_proto(&unparsed, &protocol)) | |
| 1659 | 1705 | goto drop; |
| 1706 | + unparsed.vx_flags &= ~VXLAN_GPE_USED_BITS; | |
| 1660 | 1707 | raw_proto = true; |
| 1661 | 1708 | } |
| 1662 | 1709 | |
| @@ -2516,7 +2563,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, · 853 unmodified lines | ||
| 2516 | 2563 | } |
| 2517 | 2564 | |
| 2518 | 2565 | ndst = &rt->dst; |
| 2519 | − err = skb_tunnel_check_pmtu(skb, ndst, VXLAN_HEADROOM, | |
| 2566 | + err = skb_tunnel_check_pmtu(skb, ndst, vxlan_headroom(flags & VXLAN_F_GPE), | |
| 2520 | 2567 | netif_is_any_bridge_port(dev)); |
| 2521 | 2568 | if (err < 0) { |
| 2522 | 2569 | goto tx_error; |
| @@ -2577,7 +2624,8 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, · 54 unmodified lines | ||
| 2577 | 2624 | goto out_unlock; |
| 2578 | 2625 | } |
| 2579 | 2626 | |
| 2580 | − err = skb_tunnel_check_pmtu(skb, ndst, VXLAN6_HEADROOM, | |
| 2627 | + err = skb_tunnel_check_pmtu(skb, ndst, | |
| 2628 | + vxlan_headroom((flags & VXLAN_F_GPE) | VXLAN_F_IPV6), | |
| 2581 | 2629 | netif_is_any_bridge_port(dev)); |
| 2582 | 2630 | if (err < 0) { |
| 2583 | 2631 | goto tx_error; |
| @@ -2989,14 +3037,12 @@ static int vxlan_change_mtu(struct net_device *dev, int new_mtu) · 405 unmodified lines | ||
| 2989 | 3037 | struct vxlan_rdst *dst = &vxlan->default_dst; |
| 2990 | 3038 | struct net_device *lowerdev = __dev_get_by_index(vxlan->net, |
| 2991 | 3039 | dst->remote_ifindex); |
| 2992 | − bool use_ipv6 = !!(vxlan->cfg.flags & VXLAN_F_IPV6); | |
| 2993 | 3040 | |
| 2994 | 3041 | /* This check is different than dev->max_mtu, because it looks at |
| 2995 | 3042 | * the lowerdev->mtu, rather than the static dev->max_mtu |
| 2996 | 3043 | */ |
| 2997 | 3044 | if (lowerdev) { |
| 2998 | − int max_mtu = lowerdev->mtu - | |
| 2999 | − (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM); | |
| 3045 | + int max_mtu = lowerdev->mtu - vxlan_headroom(vxlan->cfg.flags); | |
| 3000 | 3046 | if (new_mtu > max_mtu) |
| 3001 | 3047 | return -EINVAL; |
| 3002 | 3048 | } |
| @@ -3379,8 +3425,13 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6, · 376 unmodified lines | ||
| 3379 | 3425 | tunnel_cfg.encap_rcv = vxlan_rcv; |
| 3380 | 3426 | tunnel_cfg.encap_err_lookup = vxlan_err_lookup; |
| 3381 | 3427 | tunnel_cfg.encap_destroy = NULL; |
| 3382 | − tunnel_cfg.gro_receive = vxlan_gro_receive; | |
| 3383 | − tunnel_cfg.gro_complete = vxlan_gro_complete; | |
| 3428 | + if (vs->flags & VXLAN_F_GPE) { | |
| 3429 | + tunnel_cfg.gro_receive = vxlan_gpe_gro_receive; | |
| 3430 | + tunnel_cfg.gro_complete = vxlan_gpe_gro_complete; | |
| 3431 | + } else { | |
| 3432 | + tunnel_cfg.gro_receive = vxlan_gro_receive; | |
| 3433 | + tunnel_cfg.gro_complete = vxlan_gro_complete; | |
| 3434 | + } | |
| 3384 | 3435 | |
| 3385 | 3436 | setup_udp_tunnel_sock(net, sock, &tunnel_cfg); |
| 3386 | 3437 | |
| @@ -3644,11 +3695,11 @@ static void vxlan_config_apply(struct net_device *dev, · 257 unmodified lines | ||
| 3644 | 3695 | struct vxlan_dev *vxlan = netdev_priv(dev); |
| 3645 | 3696 | struct vxlan_rdst *dst = &vxlan->default_dst; |
| 3646 | 3697 | unsigned short needed_headroom = ETH_HLEN; |
| 3647 | − bool use_ipv6 = !!(conf->flags & VXLAN_F_IPV6); | |
| 3648 | 3698 | int max_mtu = ETH_MAX_MTU; |
| 3699 | + u32 flags = conf->flags; | |
| 3649 | 3700 | |
| 3650 | 3701 | if (!changelink) { |
| 3651 | − if (conf->flags & VXLAN_F_GPE) | |
| 3702 | + if (flags & VXLAN_F_GPE) | |
| 3652 | 3703 | vxlan_raw_setup(dev); |
| 3653 | 3704 | else |
| 3654 | 3705 | vxlan_ether_setup(dev); |
| @@ -3673,8 +3724,7 @@ static void vxlan_config_apply(struct net_device *dev, · 18 unmodified lines | ||
| 3673 | 3724 | |
| 3674 | 3725 | dev->needed_tailroom = lowerdev->needed_tailroom; |
| 3675 | 3726 | |
| 3676 | − max_mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : | |
| 3677 | − VXLAN_HEADROOM); | |
| 3727 | + max_mtu = lowerdev->mtu - vxlan_headroom(flags); | |
| 3678 | 3728 | if (max_mtu < ETH_MIN_MTU) |
| 3679 | 3729 | max_mtu = ETH_MIN_MTU; |
| 3680 | 3730 | |
| @@ -3685,10 +3735,9 @@ static void vxlan_config_apply(struct net_device *dev, · 4 unmodified lines | ||
| 3685 | 3735 | if (dev->mtu > max_mtu) |
| 3686 | 3736 | dev->mtu = max_mtu; |
| 3687 | 3737 | |
| 3688 | − if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA) | |
| 3689 | − needed_headroom += VXLAN6_HEADROOM; | |
| 3690 | − else | |
| 3691 | − needed_headroom += VXLAN_HEADROOM; | |
| 3738 | + if (flags & VXLAN_F_COLLECT_METADATA) | |
| 3739 | + flags |= VXLAN_F_IPV6; | |
| 3740 | + needed_headroom += vxlan_headroom(flags); | |
| 3692 | 3741 | dev->needed_headroom = needed_headroom; |
| 3693 | 3742 | |
| 3694 | 3743 | memcpy(&vxlan->cfg, conf, sizeof(*conf)); |
| @@ -713,6 +713,12 @@ static struct vxlan_vni_node *vxlan_vni_alloc(struct vxlan_dev *vxlan, · 712 unmodified lines | ||
| 713 | 713 | return vninode; |
| 714 | 714 | } |
| 715 | 715 | |
| 716 | +static void vxlan_vni_free(struct vxlan_vni_node *vninode) | |
| 717 | +{ | |
| 718 | + free_percpu(vninode->stats); | |
| 719 | + kfree(vninode); | |
| 720 | +} | |
| 721 | + | |
| 716 | 722 | static int vxlan_vni_add(struct vxlan_dev *vxlan, |
| 717 | 723 | struct vxlan_vni_group *vg, |
| 718 | 724 | u32 vni, union vxlan_addr *group, |
| @@ -740,7 +746,7 @@ static int vxlan_vni_add(struct vxlan_dev *vxlan, · 21 unmodified lines | ||
| 740 | 746 | &vninode->vnode, |
| 741 | 747 | vxlan_vni_rht_params); |
| 742 | 748 | if (err) { |
| 743 | − kfree(vninode); | |
| 749 | + vxlan_vni_free(vninode); | |
| 744 | 750 | return err; |
| 745 | 751 | } |
| 746 | 752 | |
| @@ -763,8 +769,7 @@ static void vxlan_vni_node_rcu_free(struct rcu_head *rcu) · 16 unmodified lines | ||
| 763 | 769 | struct vxlan_vni_node *v; |
| 764 | 770 | |
| 765 | 771 | v = container_of(rcu, struct vxlan_vni_node, rcu); |
| 766 | − free_percpu(v->stats); | |
| 767 | − kfree(v); | |
| 772 | + vxlan_vni_free(v); | |
| 768 | 773 | } |
| 769 | 774 | |
| 770 | 775 | static int vxlan_vni_del(struct vxlan_dev *vxlan, |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #include "allowedips.h" |
| 7 | 7 | #include "peer.h" |
| 8 | 8 | |
| 9 | −enum { MAX_ALLOWEDIPS_BITS = 128 }; | |
| 9 | +enum { MAX_ALLOWEDIPS_DEPTH = 129 }; | |
| 10 | 10 | |
| 11 | 11 | static struct kmem_cache *node_cache; |
| 12 | 12 | |
| @@ -42,7 +42,7 @@ static void push_rcu(struct allowedips_node **stack, · 29 unmodified lines | ||
| 42 | 42 | struct allowedips_node __rcu *p, unsigned int *len) |
| 43 | 43 | { |
| 44 | 44 | if (rcu_access_pointer(p)) { |
| 45 | − if (WARN_ON(IS_ENABLED(DEBUG) && *len >= MAX_ALLOWEDIPS_BITS)) | |
| 45 | + if (WARN_ON(IS_ENABLED(DEBUG) && *len >= MAX_ALLOWEDIPS_DEPTH)) | |
| 46 | 46 | return; |
| 47 | 47 | stack[(*len)++] = rcu_dereference_raw(p); |
| 48 | 48 | } |
| @@ -55,7 +55,7 @@ static void node_free_rcu(struct rcu_head *rcu) · 6 unmodified lines | ||
| 55 | 55 | |
| 56 | 56 | static void root_free_rcu(struct rcu_head *rcu) |
| 57 | 57 | { |
| 58 | − struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS] = { | |
| 58 | + struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_DEPTH] = { | |
| 59 | 59 | container_of(rcu, struct allowedips_node, rcu) }; |
| 60 | 60 | unsigned int len = 1; |
| 61 | 61 | |
| @@ -68,7 +68,7 @@ static void root_free_rcu(struct rcu_head *rcu) · 6 unmodified lines | ||
| 68 | 68 | |
| 69 | 69 | static void root_remove_peer_lists(struct allowedips_node *root) |
| 70 | 70 | { |
| 71 | − struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS] = { root }; | |
| 71 | + struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_DEPTH] = { root }; | |
| 72 | 72 | unsigned int len = 1; |
| 73 | 73 | |
| 74 | 74 | while (len > 0 && (node = stack[--len])) { |
| @@ -593,16 +593,20 @@ bool __init wg_allowedips_selftest(void) · 592 unmodified lines | ||
| 593 | 593 | wg_allowedips_remove_by_peer(&t, a, &mutex); |
| 594 | 594 | test_negative(4, a, 192, 168, 0, 1); |
| 595 | 595 | |
| 596 | − /* These will hit the WARN_ON(len >= MAX_ALLOWEDIPS_BITS) in free_node | |
| 596 | + /* These will hit the WARN_ON(len >= MAX_ALLOWEDIPS_DEPTH) in free_node | |
| 597 | 597 | * if something goes wrong. |
| 598 | 598 | */ |
| 599 | − for (i = 0; i < MAX_ALLOWEDIPS_BITS; ++i) { | |
| 600 | − part = cpu_to_be64(~(1LLU << (i % 64))); | |
| 601 | − memset(&ip, 0xff, 16); | |
| 602 | − memcpy((u8 *)&ip + (i < 64) * 8, &part, 8); | |
| 599 | + for (i = 0; i < 64; ++i) { | |
| 600 | + part = cpu_to_be64(~0LLU << i); | |
| 601 | + memset(&ip, 0xff, 8); | |
| 602 | + memcpy((u8 *)&ip + 8, &part, 8); | |
| 603 | + wg_allowedips_insert_v6(&t, &ip, 128, a, &mutex); | |
| 604 | + memcpy(&ip, &part, 8); | |
| 605 | + memset((u8 *)&ip + 8, 0, 8); | |
| 603 | 606 | wg_allowedips_insert_v6(&t, &ip, 128, a, &mutex); |
| 604 | 607 | } |
| 605 | − | |
| 608 | + memset(&ip, 0, 16); | |
| 609 | + wg_allowedips_insert_v6(&t, &ip, 128, a, &mutex); | |
| 606 | 610 | wg_allowedips_free(&t, &mutex); |
| 607 | 611 | |
| 608 | 612 | wg_allowedips_init(&t); |
| @@ -376,7 +376,6 @@ static void ath11k_ahb_ext_irq_enable(struct ath11k_base *ab) · 375 unmodified lines | ||
| 376 | 376 | struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; |
| 377 | 377 | |
| 378 | 378 | if (!irq_grp->napi_enabled) { |
| 379 | − dev_set_threaded(&irq_grp->napi_ndev, true); | |
| 380 | 379 | napi_enable(&irq_grp->napi); |
| 381 | 380 | irq_grp->napi_enabled = true; |
| 382 | 381 | } |
| @@ -466,7 +466,6 @@ void ath11k_pcic_ext_irq_enable(struct ath11k_base *ab) · 465 unmodified lines | ||
| 466 | 466 | struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; |
| 467 | 467 | |
| 468 | 468 | if (!irq_grp->napi_enabled) { |
| 469 | − dev_set_threaded(&irq_grp->napi_ndev, true); | |
| 470 | 469 | napi_enable(&irq_grp->napi); |
| 471 | 470 | irq_grp->napi_enabled = true; |
| 472 | 471 | } |
| @@ -2144,8 +2144,7 @@ int ath12k_wmi_send_scan_start_cmd(struct ath12k *ar, · 2143 unmodified lines | ||
| 2144 | 2144 | struct wmi_tlv *tlv; |
| 2145 | 2145 | void *ptr; |
| 2146 | 2146 | int i, ret, len; |
| 2147 | − u32 *tmp_ptr; | |
| 2148 | − u8 extraie_len_with_pad = 0; | |
| 2147 | + u32 *tmp_ptr, extraie_len_with_pad = 0; | |
| 2149 | 2148 | struct ath12k_wmi_hint_short_ssid_arg *s_ssid = NULL; |
| 2150 | 2149 | struct ath12k_wmi_hint_bssid_arg *hint_bssid = NULL; |
| 2151 | 2150 | |
| @@ -36,11 +36,6 @@ ath6kl_core-y += wmi.o · 35 unmodified lines | ||
| 36 | 36 | ath6kl_core-y += core.o |
| 37 | 37 | ath6kl_core-y += recovery.o |
| 38 | 38 | |
| 39 | −# FIXME: temporarily silence -Wdangling-pointer on non W=1+ builds | |
| 40 | −ifndef KBUILD_EXTRA_WARN | |
| 41 | −CFLAGS_htc_mbox.o += $(call cc-disable-warning, dangling-pointer) | |
| 42 | −endif | |
| 43 | − | |
| 44 | 39 | ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o |
| 45 | 40 | ath6kl_core-$(CONFIG_ATH6KL_TRACING) += trace.o |
| 46 | 41 | |
| @@ -1456,6 +1456,10 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp, · 1455 unmodified lines | ||
| 1456 | 1456 | params_size -= BRCMF_SCAN_PARAMS_V2_FIXED_SIZE; |
| 1457 | 1457 | params_size += BRCMF_SCAN_PARAMS_FIXED_SIZE; |
| 1458 | 1458 | params_v1 = kzalloc(params_size, GFP_KERNEL); |
| 1459 | + if (!params_v1) { | |
| 1460 | + err = -ENOMEM; | |
| 1461 | + goto exit_params; | |
| 1462 | + } | |
| 1459 | 1463 | params_v1->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION); |
| 1460 | 1464 | brcmf_scan_params_v2_to_v1(¶ms->params_v2_le, ¶ms_v1->params_le); |
| 1461 | 1465 | kfree(params); |
| @@ -1473,6 +1477,7 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp, · 11 unmodified lines | ||
| 1473 | 1477 | bphy_err(drvr, "error (%d)\n", err); |
| 1474 | 1478 | } |
| 1475 | 1479 | |
| 1480 | +exit_params: | |
| 1476 | 1481 | kfree(params); |
| 1477 | 1482 | exit: |
| 1478 | 1483 | return err; |
| @@ -398,7 +398,12 @@ struct brcmf_scan_params_le { · 397 unmodified lines | ||
| 398 | 398 | * fixed parameter portion is assumed, otherwise |
| 399 | 399 | * ssid in the fixed portion is ignored |
| 400 | 400 | */ |
| 401 | − __le16 channel_list[1]; /* list of chanspecs */ | |
| 401 | + union { | |
| 402 | + __le16 padding; /* Reserve space for at least 1 entry for abort | |
| 403 | + * which uses an on stack brcmf_scan_params_le | |
| 404 | + */ | |
| 405 | + DECLARE_FLEX_ARRAY(__le16, channel_list); /* chanspecs */ | |
| 406 | + }; | |
| 402 | 407 | }; |
| 403 | 408 | |
| 404 | 409 | struct brcmf_scan_params_v2_le { |
| @@ -577,7 +577,7 @@ struct tx_msg { · 576 unmodified lines | ||
| 577 | 577 | struct tib_structure tib; |
| 578 | 578 | struct phy_header phy; |
| 579 | 579 | struct mac_header mac; |
| 580 | − UCHAR var[1]; | |
| 580 | + UCHAR var[]; | |
| 581 | 581 | }; |
| 582 | 582 | |
| 583 | 583 | /****** ECF Receive Control Structure (RCS) Area at Shared RAM offset 0x0800 */ |
| @@ -128,12 +128,12 @@ mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev) · 127 unmodified lines | ||
| 128 | 128 | case MT_EE_5GHZ: |
| 129 | 129 | dev->mphy.cap.has_5ghz = true; |
| 130 | 130 | break; |
| 131 | − case MT_EE_2GHZ: | |
| 132 | − dev->mphy.cap.has_2ghz = true; | |
| 133 | − break; | |
| 134 | 131 | case MT_EE_DBDC: |
| 135 | 132 | dev->dbdc_support = true; |
| 136 | 133 | fallthrough; |
| 134 | + case MT_EE_2GHZ: | |
| 135 | + dev->mphy.cap.has_2ghz = true; | |
| 136 | + break; | |
| 137 | 137 | default: |
| 138 | 138 | dev->mphy.cap.has_2ghz = true; |
| 139 | 139 | dev->mphy.cap.has_5ghz = true; |
| @@ -2524,7 +2524,7 @@ static int cmac_dma_init(struct rtw89_dev *rtwdev, u8 mac_idx) · 2523 unmodified lines | ||
| 2524 | 2524 | u32 reg; |
| 2525 | 2525 | int ret; |
| 2526 | 2526 | |
| 2527 | − if (chip_id != RTL8852A && chip_id != RTL8852B) | |
| 2527 | + if (chip_id != RTL8852B) | |
| 2528 | 2528 | return 0; |
| 2529 | 2529 | |
| 2530 | 2530 | ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); |
| @@ -396,7 +396,7 @@ static void xenvif_get_requests(struct xenvif_queue *queue, · 395 unmodified lines | ||
| 396 | 396 | struct gnttab_map_grant_ref *gop = queue->tx_map_ops + *map_ops; |
| 397 | 397 | struct xen_netif_tx_request *txp = first; |
| 398 | 398 | |
| 399 | − nr_slots = shinfo->nr_frags + 1; | |
| 399 | + nr_slots = shinfo->nr_frags + frag_overflow + 1; | |
| 400 | 400 | |
| 401 | 401 | copy_count(skb) = 0; |
| 402 | 402 | XENVIF_TX_CB(skb)->split_mask = 0; |
| @@ -462,8 +462,8 @@ static void xenvif_get_requests(struct xenvif_queue *queue, · 59 unmodified lines | ||
| 462 | 462 | } |
| 463 | 463 | } |
| 464 | 464 | |
| 465 | − for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; | |
| 466 | − shinfo->nr_frags++, gop++) { | |
| 465 | + for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS; | |
| 466 | + shinfo->nr_frags++, gop++, nr_slots--) { | |
| 467 | 467 | index = pending_index(queue->pending_cons++); |
| 468 | 468 | pending_idx = queue->pending_ring[index]; |
| 469 | 469 | xenvif_tx_create_map_op(queue, pending_idx, txp, |
| @@ -476,12 +476,12 @@ static void xenvif_get_requests(struct xenvif_queue *queue, · 6 unmodified lines | ||
| 476 | 476 | txp++; |
| 477 | 477 | } |
| 478 | 478 | |
| 479 | − if (frag_overflow) { | |
| 479 | + if (nr_slots > 0) { | |
| 480 | 480 | |
| 481 | 481 | shinfo = skb_shinfo(nskb); |
| 482 | 482 | frags = shinfo->frags; |
| 483 | 483 | |
| 484 | − for (shinfo->nr_frags = 0; shinfo->nr_frags < frag_overflow; | |
| 484 | + for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; | |
| 485 | 485 | shinfo->nr_frags++, txp++, gop++) { |
| 486 | 486 | index = pending_index(queue->pending_cons++); |
| 487 | 487 | pending_idx = queue->pending_ring[index]; |
| @@ -492,6 +492,11 @@ static void xenvif_get_requests(struct xenvif_queue *queue, · 4 unmodified lines | ||
| 492 | 492 | } |
| 493 | 493 | |
| 494 | 494 | skb_shinfo(skb)->frag_list = nskb; |
| 495 | + } else if (nskb) { | |
| 496 | + /* A frag_list skb was allocated but it is no longer needed | |
| 497 | + * because enough slots were converted to copy ops above. | |
| 498 | + */ | |
| 499 | + kfree_skb(nskb); | |
| 495 | 500 | } |
| 496 | 501 | |
| 497 | 502 | (*copy_ops) = cop - queue->tx_copy_ops; |
| @@ -3933,6 +3933,12 @@ void nvme_remove_namespaces(struct nvme_ctrl *ctrl) · 3932 unmodified lines | ||
| 3933 | 3933 | */ |
| 3934 | 3934 | nvme_mpath_clear_ctrl_paths(ctrl); |
| 3935 | 3935 | |
| 3936 | + /* | |
| 3937 | + * Unquiesce io queues so any pending IO won't hang, especially | |
| 3938 | + * those submitted from scan work | |
| 3939 | + */ | |
| 3940 | + nvme_unquiesce_io_queues(ctrl); | |
| 3941 | + | |
| 3936 | 3942 | /* prevent racing with ns scanning */ |
| 3937 | 3943 | flush_work(&ctrl->scan_work); |
| 3938 | 3944 | |
| @@ -3942,10 +3948,8 @@ void nvme_remove_namespaces(struct nvme_ctrl *ctrl) · 3 unmodified lines | ||
| 3942 | 3948 | * removing the namespaces' disks; fail all the queues now to avoid |
| 3943 | 3949 | * potentially having to clean up the failed sync later. |
| 3944 | 3950 | */ |
| 3945 | − if (ctrl->state == NVME_CTRL_DEAD) { | |
| 3951 | + if (ctrl->state == NVME_CTRL_DEAD) | |
| 3946 | 3952 | nvme_mark_namespaces_dead(ctrl); |
| 3947 | − nvme_unquiesce_io_queues(ctrl); | |
| 3948 | − } | |
| 3949 | 3953 | |
| 3950 | 3954 | /* this is a no-op when called from the controller reset handler */ |
| 3951 | 3955 | nvme_change_ctrl_state(ctrl, NVME_CTRL_DELETING_NOIO); |
| @@ -786,11 +786,9 @@ int nvme_ns_chr_uring_cmd_iopoll(struct io_uring_cmd *ioucmd, · 785 unmodified lines | ||
| 786 | 786 | if (!(ioucmd->flags & IORING_URING_CMD_POLLED)) |
| 787 | 787 | return 0; |
| 788 | 788 | |
| 789 | − rcu_read_lock(); | |
| 790 | 789 | req = READ_ONCE(ioucmd->cookie); |
| 791 | 790 | if (req && blk_rq_is_poll(req)) |
| 792 | 791 | ret = blk_rq_poll(req, iob, poll_flags); |
| 793 | − rcu_read_unlock(); | |
| 794 | 792 | return ret; |
| 795 | 793 | } |
| 796 | 794 | #ifdef CONFIG_NVME_MULTIPATH |
| @@ -3402,7 +3402,8 @@ static const struct pci_device_id nvme_id_table[] = { · 3401 unmodified lines | ||
| 3402 | 3402 | { PCI_DEVICE(0x1d97, 0x2263), /* SPCC */ |
| 3403 | 3403 | .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, |
| 3404 | 3404 | { PCI_DEVICE(0x144d, 0xa80b), /* Samsung PM9B1 256G and 512G */ |
| 3405 | − .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, | |
| 3405 | + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES | | |
| 3406 | + NVME_QUIRK_BOGUS_NID, }, | |
| 3406 | 3407 | { PCI_DEVICE(0x144d, 0xa809), /* Samsung MZALQ256HBJD 256G */ |
| 3407 | 3408 | .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, |
| 3408 | 3409 | { PCI_DEVICE(0x144d, 0xa802), /* Samsung SM953 */ |
| @@ -883,6 +883,7 @@ static int nvme_rdma_configure_io_queues(struct nvme_rdma_ctrl *ctrl, bool new) · 882 unmodified lines | ||
| 883 | 883 | goto out_cleanup_tagset; |
| 884 | 884 | |
| 885 | 885 | if (!new) { |
| 886 | + nvme_start_freeze(&ctrl->ctrl); | |
| 886 | 887 | nvme_unquiesce_io_queues(&ctrl->ctrl); |
| 887 | 888 | if (!nvme_wait_freeze_timeout(&ctrl->ctrl, NVME_IO_TIMEOUT)) { |
| 888 | 889 | /* |
| @@ -891,6 +892,7 @@ static int nvme_rdma_configure_io_queues(struct nvme_rdma_ctrl *ctrl, bool new) · 2 unmodified lines | ||
| 891 | 892 | * to be safe. |
| 892 | 893 | */ |
| 893 | 894 | ret = -ENODEV; |
| 895 | + nvme_unfreeze(&ctrl->ctrl); | |
| 894 | 896 | goto out_wait_freeze_timed_out; |
| 895 | 897 | } |
| 896 | 898 | blk_mq_update_nr_hw_queues(ctrl->ctrl.tagset, |
| @@ -940,7 +942,6 @@ static void nvme_rdma_teardown_io_queues(struct nvme_rdma_ctrl *ctrl, · 43 unmodified lines | ||
| 940 | 942 | bool remove) |
| 941 | 943 | { |
| 942 | 944 | if (ctrl->ctrl.queue_count > 1) { |
| 943 | − nvme_start_freeze(&ctrl->ctrl); | |
| 944 | 945 | nvme_quiesce_io_queues(&ctrl->ctrl); |
| 945 | 946 | nvme_sync_io_queues(&ctrl->ctrl); |
| 946 | 947 | nvme_rdma_stop_io_queues(ctrl); |
| @@ -1868,6 +1868,7 @@ static int nvme_tcp_configure_io_queues(struct nvme_ctrl *ctrl, bool new) · 1867 unmodified lines | ||
| 1868 | 1868 | goto out_cleanup_connect_q; |
| 1869 | 1869 | |
| 1870 | 1870 | if (!new) { |
| 1871 | + nvme_start_freeze(ctrl); | |
| 1871 | 1872 | nvme_unquiesce_io_queues(ctrl); |
| 1872 | 1873 | if (!nvme_wait_freeze_timeout(ctrl, NVME_IO_TIMEOUT)) { |
| 1873 | 1874 | /* |
| @@ -1876,6 +1877,7 @@ static int nvme_tcp_configure_io_queues(struct nvme_ctrl *ctrl, bool new) · 2 unmodified lines | ||
| 1876 | 1877 | * to be safe. |
| 1877 | 1878 | */ |
| 1878 | 1879 | ret = -ENODEV; |
| 1880 | + nvme_unfreeze(ctrl); | |
| 1879 | 1881 | goto out_wait_freeze_timed_out; |
| 1880 | 1882 | } |
| 1881 | 1883 | blk_mq_update_nr_hw_queues(ctrl->tagset, |
| @@ -1980,7 +1982,6 @@ static void nvme_tcp_teardown_io_queues(struct nvme_ctrl *ctrl, · 98 unmodified lines | ||
| 1980 | 1982 | if (ctrl->queue_count <= 1) |
| 1981 | 1983 | return; |
| 1982 | 1984 | nvme_quiesce_admin_queue(ctrl); |
| 1983 | − nvme_start_freeze(ctrl); | |
| 1984 | 1985 | nvme_quiesce_io_queues(ctrl); |
| 1985 | 1986 | nvme_sync_io_queues(ctrl); |
| 1986 | 1987 | nvme_tcp_stop_io_queues(ctrl); |
| @@ -121,6 +121,8 @@ module_param(sba_reserve_agpgart, int, 0444); · 120 unmodified lines | ||
| 121 | 121 | MODULE_PARM_DESC(sba_reserve_agpgart, "Reserve half of IO pdir as AGPGART"); |
| 122 | 122 | #endif |
| 123 | 123 | |
| 124 | +struct proc_dir_entry *proc_runway_root __ro_after_init; | |
| 125 | +struct proc_dir_entry *proc_mckinley_root __ro_after_init; | |
| 124 | 126 | |
| 125 | 127 | /************************************ |
| 126 | 128 | ** SBA register read and write support |
| @@ -1968,11 +1970,15 @@ static int __init sba_driver_callback(struct parisc_device *dev) · 1841 unmodified lines | ||
| 1968 | 1970 | #ifdef CONFIG_PROC_FS |
| 1969 | 1971 | switch (dev->id.hversion) { |
| 1970 | 1972 | case PLUTO_MCKINLEY_PORT: |
| 1973 | + if (!proc_mckinley_root) | |
| 1974 | + proc_mckinley_root = proc_mkdir("bus/mckinley", NULL); | |
| 1971 | 1975 | root = proc_mckinley_root; |
| 1972 | 1976 | break; |
| 1973 | 1977 | case ASTRO_RUNWAY_PORT: |
| 1974 | 1978 | case IKE_MERCED_PORT: |
| 1975 | 1979 | default: |
| 1980 | + if (!proc_runway_root) | |
| 1981 | + proc_runway_root = proc_mkdir("bus/runway", NULL); | |
| 1976 | 1982 | root = proc_runway_root; |
| 1977 | 1983 | break; |
| 1978 | 1984 | } |
| @@ -28,7 +28,6 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/sysctl.h> |
| 29 | 29 | |
| 30 | 30 | #include <asm/io.h> |
| 31 | −#include <asm/dma.h> | |
| 32 | 31 | #include <linux/uaccess.h> |
| 33 | 32 | #include <asm/superio.h> |
| 34 | 33 | |
| @@ -226,9 +225,9 @@ static int parport_PS2_supported(struct parport *pb) · 191 unmodified lines | ||
| 226 | 225 | |
| 227 | 226 | /* --- Initialisation code -------------------------------- */ |
| 228 | 227 | |
| 229 | −struct parport *parport_gsc_probe_port(unsigned long base, | |
| 228 | +static struct parport *parport_gsc_probe_port(unsigned long base, | |
| 230 | 229 | unsigned long base_hi, int irq, |
| 231 | − int dma, struct parisc_device *padev) | |
| 230 | + struct parisc_device *padev) | |
| 232 | 231 | { |
| 233 | 232 | struct parport_gsc_private *priv; |
| 234 | 233 | struct parport_operations *ops; |
| @@ -250,12 +249,9 @@ struct parport *parport_gsc_probe_port(unsigned long base, · 15 unmodified lines | ||
| 250 | 249 | } |
| 251 | 250 | priv->ctr = 0xc; |
| 252 | 251 | priv->ctr_writable = 0xff; |
| 253 | − priv->dma_buf = NULL; | |
| 254 | − priv->dma_handle = 0; | |
| 255 | 252 | p->base = base; |
| 256 | 253 | p->base_hi = base_hi; |
| 257 | 254 | p->irq = irq; |
| 258 | − p->dma = dma; | |
| 259 | 255 | p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT; |
| 260 | 256 | p->ops = ops; |
| 261 | 257 | p->private_data = priv; |
| @@ -286,17 +282,9 @@ struct parport *parport_gsc_probe_port(unsigned long base, · 24 unmodified lines | ||
| 286 | 282 | if (p->irq == PARPORT_IRQ_AUTO) { |
| 287 | 283 | p->irq = PARPORT_IRQ_NONE; |
| 288 | 284 | } |
| 289 | − if (p->irq != PARPORT_IRQ_NONE) { | |
| 285 | + if (p->irq != PARPORT_IRQ_NONE) | |
| 290 | 286 | pr_cont(", irq %d", p->irq); |
| 291 | 287 | |
| 292 | − if (p->dma == PARPORT_DMA_AUTO) { | |
| 293 | − p->dma = PARPORT_DMA_NONE; | |
| 294 | − } | |
| 295 | − } | |
| 296 | − if (p->dma == PARPORT_DMA_AUTO) /* To use DMA, giving the irq | |
| 297 | − is mandatory (see above) */ | |
| 298 | − p->dma = PARPORT_DMA_NONE; | |
| 299 | − | |
| 300 | 288 | pr_cont(" ["); |
| 301 | 289 | #define printmode(x) \ |
| 302 | 290 | do { \ |
| @@ -321,7 +309,6 @@ do { \ · 18 unmodified lines | ||
| 321 | 309 | pr_warn("%s: irq %d in use, resorting to polled operation\n", |
| 322 | 310 | p->name, p->irq); |
| 323 | 311 | p->irq = PARPORT_IRQ_NONE; |
| 324 | − p->dma = PARPORT_DMA_NONE; | |
| 325 | 312 | } |
| 326 | 313 | } |
| 327 | 314 | |
| @@ -369,8 +356,7 @@ static int __init parport_init_chip(struct parisc_device *dev) · 41 unmodified lines | ||
| 369 | 356 | pr_info("%s: enhanced parport-modes not supported\n", __func__); |
| 370 | 357 | } |
| 371 | 358 | |
| 372 | − p = parport_gsc_probe_port(port, 0, dev->irq, | |
| 373 | − /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, dev); | |
| 359 | + p = parport_gsc_probe_port(port, 0, dev->irq, dev); | |
| 374 | 360 | if (p) |
| 375 | 361 | parport_count++; |
| 376 | 362 | dev_set_drvdata(&dev->dev, p); |
| @@ -382,16 +368,10 @@ static void __exit parport_remove_chip(struct parisc_device *dev) · 5 unmodified lines | ||
| 382 | 368 | { |
| 383 | 369 | struct parport *p = dev_get_drvdata(&dev->dev); |
| 384 | 370 | if (p) { |
| 385 | − struct parport_gsc_private *priv = p->private_data; | |
| 386 | 371 | struct parport_operations *ops = p->ops; |
| 387 | 372 | parport_remove_port(p); |
| 388 | − if (p->dma != PARPORT_DMA_NONE) | |
| 389 | − free_dma(p->dma); | |
| 390 | 373 | if (p->irq != PARPORT_IRQ_NONE) |
| 391 | 374 | free_irq(p->irq, p); |
| 392 | − if (priv->dma_buf) | |
| 393 | − dma_free_coherent(&priv->dev->dev, PAGE_SIZE, | |
| 394 | − priv->dma_buf, priv->dma_handle); | |
| 395 | 375 | kfree (p->private_data); |
| 396 | 376 | parport_put_port(p); |
| 397 | 377 | kfree (ops); /* hope no-one cached it */ |
| @@ -63,8 +63,6 @@ struct parport_gsc_private { · 62 unmodified lines | ||
| 63 | 63 | int writeIntrThreshold; |
| 64 | 64 | |
| 65 | 65 | /* buffer suitable for DMA, if DMA enabled */ |
| 66 | − char *dma_buf; | |
| 67 | − dma_addr_t dma_handle; | |
| 68 | 66 | struct pci_dev *dev; |
| 69 | 67 | }; |
| 70 | 68 | |
| @@ -199,9 +197,4 @@ extern void parport_gsc_inc_use_count(void); · 128 unmodified lines | ||
| 199 | 197 | |
| 200 | 198 | extern void parport_gsc_dec_use_count(void); |
| 201 | 199 | |
| 202 | −extern struct parport *parport_gsc_probe_port(unsigned long base, | |
| 203 | − unsigned long base_hi, | |
| 204 | − int irq, int dma, | |
| 205 | − struct parisc_device *padev); | |
| 206 | − | |
| 207 | 200 | #endif /* __DRIVERS_PARPORT_PARPORT_GSC_H */ |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/pci.h> |
| 12 | 12 | #include <linux/errno.h> |
| 13 | 13 | #include <linux/ioport.h> |
| 14 | +#include <linux/of.h> | |
| 14 | 15 | #include <linux/proc_fs.h> |
| 15 | 16 | #include <linux/slab.h> |
| 16 | 17 | |
| @@ -332,6 +333,7 @@ void __weak pcibios_bus_add_device(struct pci_dev *pdev) { } · 315 unmodified lines | ||
| 332 | 333 | */ |
| 333 | 334 | void pci_bus_add_device(struct pci_dev *dev) |
| 334 | 335 | { |
| 336 | + struct device_node *dn = dev->dev.of_node; | |
| 335 | 337 | int retval; |
| 336 | 338 | |
| 337 | 339 | /* |
| @@ -344,7 +346,7 @@ void pci_bus_add_device(struct pci_dev *dev) · 6 unmodified lines | ||
| 344 | 346 | pci_proc_attach_device(dev); |
| 345 | 347 | pci_bridge_d3_update(dev); |
| 346 | 348 | |
| 347 | − dev->match_driver = true; | |
| 349 | + dev->match_driver = !dn || of_device_is_available(dn); | |
| 348 | 350 | retval = device_attach(&dev->dev); |
| 349 | 351 | if (retval < 0 && retval != -EPROBE_DEFER) |
| 350 | 352 | pci_warn(dev, "device attach failed (%d)\n", retval); |
| @@ -179,7 +179,6 @@ config PCI_MVEBU · 178 unmodified lines | ||
| 179 | 179 | depends on MVEBU_MBUS |
| 180 | 180 | depends on ARM |
| 181 | 181 | depends on OF |
| 182 | − depends on BROKEN | |
| 183 | 182 | select PCI_BRIDGE_EMUL |
| 184 | 183 | help |
| 185 | 184 | Add support for Marvell EBU PCIe controller. This PCIe controller |
| @@ -485,20 +485,15 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp) · 484 unmodified lines | ||
| 485 | 485 | if (ret) |
| 486 | 486 | goto err_remove_edma; |
| 487 | 487 | |
| 488 | − if (dw_pcie_link_up(pci)) { | |
| 489 | − dw_pcie_print_link_status(pci); | |
| 490 | − } else { | |
| 488 | + if (!dw_pcie_link_up(pci)) { | |
| 491 | 489 | ret = dw_pcie_start_link(pci); |
| 492 | 490 | if (ret) |
| 493 | 491 | goto err_remove_edma; |
| 494 | − | |
| 495 | − if (pci->ops && pci->ops->start_link) { | |
| 496 | − ret = dw_pcie_wait_for_link(pci); | |
| 497 | − if (ret) | |
| 498 | − goto err_stop_link; | |
| 499 | − } | |
| 500 | 492 | } |
| 501 | 493 | |
| 494 | + /* Ignore errors, the link may come up later */ | |
| 495 | + dw_pcie_wait_for_link(pci); | |
| 496 | + | |
| 502 | 497 | bridge->sysdata = pp; |
| 503 | 498 | |
| 504 | 499 | ret = pci_host_probe(bridge); |
| @@ -644,20 +644,9 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index) · 643 unmodified lines | ||
| 644 | 644 | dw_pcie_writel_atu(pci, dir, index, PCIE_ATU_REGION_CTRL2, 0); |
| 645 | 645 | } |
| 646 | 646 | |
| 647 | −void dw_pcie_print_link_status(struct dw_pcie *pci) | |
| 648 | −{ | |
| 649 | − u32 offset, val; | |
| 650 | − | |
| 651 | − offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); | |
| 652 | − val = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA); | |
| 653 | − | |
| 654 | − dev_info(pci->dev, "PCIe Gen.%u x%u link up\n", | |
| 655 | − FIELD_GET(PCI_EXP_LNKSTA_CLS, val), | |
| 656 | − FIELD_GET(PCI_EXP_LNKSTA_NLW, val)); | |
| 657 | −} | |
| 658 | − | |
| 659 | 647 | int dw_pcie_wait_for_link(struct dw_pcie *pci) |
| 660 | 648 | { |
| 649 | + u32 offset, val; | |
| 661 | 650 | int retries; |
| 662 | 651 | |
| 663 | 652 | /* Check if the link is up or not */ |
| @@ -673,7 +662,12 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci) · 9 unmodified lines | ||
| 673 | 662 | return -ETIMEDOUT; |
| 674 | 663 | } |
| 675 | 664 | |
| 676 | − dw_pcie_print_link_status(pci); | |
| 665 | + offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); | |
| 666 | + val = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA); | |
| 667 | + | |
| 668 | + dev_info(pci->dev, "PCIe Gen.%u x%u link up\n", | |
| 669 | + FIELD_GET(PCI_EXP_LNKSTA_CLS, val), | |
| 670 | + FIELD_GET(PCI_EXP_LNKSTA_NLW, val)); | |
| 677 | 671 | |
| 678 | 672 | return 0; |
| 679 | 673 | } |
| @@ -429,7 +429,6 @@ void dw_pcie_setup(struct dw_pcie *pci); · 428 unmodified lines | ||
| 429 | 429 | void dw_pcie_iatu_detect(struct dw_pcie *pci); |
| 430 | 430 | int dw_pcie_edma_detect(struct dw_pcie *pci); |
| 431 | 431 | void dw_pcie_edma_remove(struct dw_pcie *pci); |
| 432 | −void dw_pcie_print_link_status(struct dw_pcie *pci); | |
| 433 | 432 | |
| 434 | 433 | static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val) |
| 435 | 434 | { |
| @@ -498,6 +498,7 @@ static void enable_slot(struct acpiphp_slot *slot, bool bridge) · 497 unmodified lines | ||
| 498 | 498 | acpiphp_native_scan_bridge(dev); |
| 499 | 499 | } |
| 500 | 500 | } else { |
| 501 | + LIST_HEAD(add_list); | |
| 501 | 502 | int max, pass; |
| 502 | 503 | |
| 503 | 504 | acpiphp_rescan_slot(slot); |
| @@ -511,10 +512,15 @@ static void enable_slot(struct acpiphp_slot *slot, bool bridge) · 7 unmodified lines | ||
| 511 | 512 | if (pass && dev->subordinate) { |
| 512 | 513 | check_hotplug_bridge(slot, dev); |
| 513 | 514 | pcibios_resource_survey_bus(dev->subordinate); |
| 515 | + if (pci_is_root_bus(bus)) | |
| 516 | + __pci_bus_size_bridges(dev->subordinate, &add_list); | |
| 514 | 517 | } |
| 515 | 518 | } |
| 516 | 519 | } |
| 517 | − pci_assign_unassigned_bridge_resources(bus->self); | |
| 520 | + if (pci_is_root_bus(bus)) | |
| 521 | + __pci_bus_assign_resources(bus, &add_list, NULL); | |
| 522 | + else | |
| 523 | + pci_assign_unassigned_bridge_resources(bus->self); | |
| 518 | 524 | } |
| 519 | 525 | |
| 520 | 526 | acpiphp_sanitize_bus(bus); |
| @@ -34,11 +34,6 @@ int pci_set_of_node(struct pci_dev *dev) · 33 unmodified lines | ||
| 34 | 34 | if (!node) |
| 35 | 35 | return 0; |
| 36 | 36 | |
| 37 | − if (!of_device_is_available(node)) { | |
| 38 | − of_node_put(node); | |
| 39 | − return -ENODEV; | |
| 40 | − } | |
| 41 | − | |
| 42 | 37 | device_set_node(&dev->dev, of_fwnode_handle(node)); |
| 43 | 38 | return 0; |
| 44 | 39 | } |
| @@ -184,7 +184,7 @@ static int hisi_inno_phy_probe(struct platform_device *pdev) · 183 unmodified lines | ||
| 184 | 184 | phy_set_drvdata(phy, &priv->ports[i]); |
| 185 | 185 | i++; |
| 186 | 186 | |
| 187 | − if (i > INNO_PHY_PORT_NUM) { | |
| 187 | + if (i >= INNO_PHY_PORT_NUM) { | |
| 188 | 188 | dev_warn(dev, "Support %d ports in maximum\n", i); |
| 189 | 189 | of_node_put(child); |
| 190 | 190 | break; |
| @@ -169,7 +169,7 @@ static int mtk_dp_phy_probe(struct platform_device *pdev) · 168 unmodified lines | ||
| 169 | 169 | |
| 170 | 170 | regs = *(struct regmap **)dev->platform_data; |
| 171 | 171 | if (!regs) |
| 172 | − return dev_err_probe(dev, EINVAL, | |
| 172 | + return dev_err_probe(dev, -EINVAL, | |
| 173 | 173 | "No data passed, requires struct regmap**\n"); |
| 174 | 174 | |
| 175 | 175 | dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL); |
| @@ -253,7 +253,7 @@ static int mtk_hdmi_pll_calc(struct mtk_hdmi_phy *hdmi_phy, struct clk_hw *hw, · 252 unmodified lines | ||
| 253 | 253 | for (i = 0; i < ARRAY_SIZE(txpredivs); i++) { |
| 254 | 254 | ns_hdmipll_ck = 5 * tmds_clk * txposdiv * txpredivs[i]; |
| 255 | 255 | if (ns_hdmipll_ck >= 5 * GIGA && |
| 256 | − ns_hdmipll_ck <= 1 * GIGA) | |
| 256 | + ns_hdmipll_ck <= 12 * GIGA) | |
| 257 | 257 | break; |
| 258 | 258 | } |
| 259 | 259 | if (i == (ARRAY_SIZE(txpredivs) - 1) && |
| @@ -110,11 +110,13 @@ struct phy_override_seq { · 109 unmodified lines | ||
| 110 | 110 | /** |
| 111 | 111 | * struct qcom_snps_hsphy - snps hs phy attributes |
| 112 | 112 | * |
| 113 | + * @dev: device structure | |
| 114 | + * | |
| 113 | 115 | * @phy: generic phy |
| 114 | 116 | * @base: iomapped memory space for snps hs phy |
| 115 | 117 | * |
| 116 | − * @cfg_ahb_clk: AHB2PHY interface clock | |
| 117 | − * @ref_clk: phy reference clock | |
| 118 | + * @num_clks: number of clocks | |
| 119 | + * @clks: array of clocks | |
| 118 | 120 | * @phy_reset: phy reset control |
| 119 | 121 | * @vregs: regulator supplies bulk data |
| 120 | 122 | * @phy_initialized: if PHY has been initialized correctly |
| @@ -122,11 +124,13 @@ struct phy_override_seq { · 1 unmodified line | ||
| 122 | 124 | * @update_seq_cfg: tuning parameters for phy init |
| 123 | 125 | */ |
| 124 | 126 | struct qcom_snps_hsphy { |
| 127 | + struct device *dev; | |
| 128 | + | |
| 125 | 129 | struct phy *phy; |
| 126 | 130 | void __iomem *base; |
| 127 | 131 | |
| 128 | − struct clk *cfg_ahb_clk; | |
| 129 | − struct clk *ref_clk; | |
| 132 | + int num_clks; | |
| 133 | + struct clk_bulk_data *clks; | |
| 130 | 134 | struct reset_control *phy_reset; |
| 131 | 135 | struct regulator_bulk_data vregs[SNPS_HS_NUM_VREGS]; |
| 132 | 136 | |
| @@ -135,6 +139,34 @@ struct qcom_snps_hsphy { · 2 unmodified lines | ||
| 135 | 139 | struct phy_override_seq update_seq_cfg[NUM_HSPHY_TUNING_PARAMS]; |
| 136 | 140 | }; |
| 137 | 141 | |
| 142 | +static int qcom_snps_hsphy_clk_init(struct qcom_snps_hsphy *hsphy) | |
| 143 | +{ | |
| 144 | + struct device *dev = hsphy->dev; | |
| 145 | + | |
| 146 | + hsphy->num_clks = 2; | |
| 147 | + hsphy->clks = devm_kcalloc(dev, hsphy->num_clks, sizeof(*hsphy->clks), GFP_KERNEL); | |
| 148 | + if (!hsphy->clks) | |
| 149 | + return -ENOMEM; | |
| 150 | + | |
| 151 | + /* | |
| 152 | + * TODO: Currently no device tree instantiation of the PHY is using the clock. | |
| 153 | + * This needs to be fixed in order for this code to be able to use devm_clk_bulk_get(). | |
| 154 | + */ | |
| 155 | + hsphy->clks[0].id = "cfg_ahb"; | |
| 156 | + hsphy->clks[0].clk = devm_clk_get_optional(dev, "cfg_ahb"); | |
| 157 | + if (IS_ERR(hsphy->clks[0].clk)) | |
| 158 | + return dev_err_probe(dev, PTR_ERR(hsphy->clks[0].clk), | |
| 159 | + "failed to get cfg_ahb clk\n"); | |
| 160 | + | |
| 161 | + hsphy->clks[1].id = "ref"; | |
| 162 | + hsphy->clks[1].clk = devm_clk_get(dev, "ref"); | |
| 163 | + if (IS_ERR(hsphy->clks[1].clk)) | |
| 164 | + return dev_err_probe(dev, PTR_ERR(hsphy->clks[1].clk), | |
| 165 | + "failed to get ref clk\n"); | |
| 166 | + | |
| 167 | + return 0; | |
| 168 | +} | |
| 169 | + | |
| 138 | 170 | static inline void qcom_snps_hsphy_write_mask(void __iomem *base, u32 offset, |
| 139 | 171 | u32 mask, u32 val) |
| 140 | 172 | { |
| @@ -165,22 +197,13 @@ static int qcom_snps_hsphy_suspend(struct qcom_snps_hsphy *hsphy) · 24 unmodified lines | ||
| 165 | 197 | 0, USB2_AUTO_RESUME); |
| 166 | 198 | } |
| 167 | 199 | |
| 168 | − clk_disable_unprepare(hsphy->cfg_ahb_clk); | |
| 169 | 200 | return 0; |
| 170 | 201 | } |
| 171 | 202 | |
| 172 | 203 | static int qcom_snps_hsphy_resume(struct qcom_snps_hsphy *hsphy) |
| 173 | 204 | { |
| 174 | − int ret; | |
| 175 | − | |
| 176 | 205 | dev_dbg(&hsphy->phy->dev, "Resume QCOM SNPS PHY, mode\n"); |
| 177 | 206 | |
| 178 | − ret = clk_prepare_enable(hsphy->cfg_ahb_clk); | |
| 179 | − if (ret) { | |
| 180 | − dev_err(&hsphy->phy->dev, "failed to enable cfg ahb clock\n"); | |
| 181 | − return ret; | |
| 182 | − } | |
| 183 | − | |
| 184 | 207 | return 0; |
| 185 | 208 | } |
| 186 | 209 | |
| @@ -191,8 +214,7 @@ static int __maybe_unused qcom_snps_hsphy_runtime_suspend(struct device *dev) · 4 unmodified lines | ||
| 191 | 214 | if (!hsphy->phy_initialized) |
| 192 | 215 | return 0; |
| 193 | 216 | |
| 194 | − qcom_snps_hsphy_suspend(hsphy); | |
| 195 | − return 0; | |
| 217 | + return qcom_snps_hsphy_suspend(hsphy); | |
| 196 | 218 | } |
| 197 | 219 | |
| 198 | 220 | static int __maybe_unused qcom_snps_hsphy_runtime_resume(struct device *dev) |
| @@ -202,8 +224,7 @@ static int __maybe_unused qcom_snps_hsphy_runtime_resume(struct device *dev) · 3 unmodified lines | ||
| 202 | 224 | if (!hsphy->phy_initialized) |
| 203 | 225 | return 0; |
| 204 | 226 | |
| 205 | − qcom_snps_hsphy_resume(hsphy); | |
| 206 | − return 0; | |
| 227 | + return qcom_snps_hsphy_resume(hsphy); | |
| 207 | 228 | } |
| 208 | 229 | |
| 209 | 230 | static int qcom_snps_hsphy_set_mode(struct phy *phy, enum phy_mode mode, |
| @@ -374,16 +395,16 @@ static int qcom_snps_hsphy_init(struct phy *phy) · 164 unmodified lines | ||
| 374 | 395 | if (ret) |
| 375 | 396 | return ret; |
| 376 | 397 | |
| 377 | − ret = clk_prepare_enable(hsphy->cfg_ahb_clk); | |
| 398 | + ret = clk_bulk_prepare_enable(hsphy->num_clks, hsphy->clks); | |
| 378 | 399 | if (ret) { |
| 379 | − dev_err(&phy->dev, "failed to enable cfg ahb clock, %d\n", ret); | |
| 400 | + dev_err(&phy->dev, "failed to enable clocks, %d\n", ret); | |
| 380 | 401 | goto poweroff_phy; |
| 381 | 402 | } |
| 382 | 403 | |
| 383 | 404 | ret = reset_control_assert(hsphy->phy_reset); |
| 384 | 405 | if (ret) { |
| 385 | 406 | dev_err(&phy->dev, "failed to assert phy_reset, %d\n", ret); |
| 386 | − goto disable_ahb_clk; | |
| 407 | + goto disable_clks; | |
| 387 | 408 | } |
| 388 | 409 | |
| 389 | 410 | usleep_range(100, 150); |
| @@ -391,7 +412,7 @@ static int qcom_snps_hsphy_init(struct phy *phy) · 1 unmodified line | ||
| 391 | 412 | ret = reset_control_deassert(hsphy->phy_reset); |
| 392 | 413 | if (ret) { |
| 393 | 414 | dev_err(&phy->dev, "failed to de-assert phy_reset, %d\n", ret); |
| 394 | − goto disable_ahb_clk; | |
| 415 | + goto disable_clks; | |
| 395 | 416 | } |
| 396 | 417 | |
| 397 | 418 | qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_CFG0, |
| @@ -448,8 +469,8 @@ static int qcom_snps_hsphy_init(struct phy *phy) · 50 unmodified lines | ||
| 448 | 469 | |
| 449 | 470 | return 0; |
| 450 | 471 | |
| 451 | −disable_ahb_clk: | |
| 452 | − clk_disable_unprepare(hsphy->cfg_ahb_clk); | |
| 472 | +disable_clks: | |
| 473 | + clk_bulk_disable_unprepare(hsphy->num_clks, hsphy->clks); | |
| 453 | 474 | poweroff_phy: |
| 454 | 475 | regulator_bulk_disable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs); |
| 455 | 476 | |
| @@ -461,7 +482,7 @@ static int qcom_snps_hsphy_exit(struct phy *phy) · 5 unmodified lines | ||
| 461 | 482 | struct qcom_snps_hsphy *hsphy = phy_get_drvdata(phy); |
| 462 | 483 | |
| 463 | 484 | reset_control_assert(hsphy->phy_reset); |
| 464 | − clk_disable_unprepare(hsphy->cfg_ahb_clk); | |
| 485 | + clk_bulk_disable_unprepare(hsphy->num_clks, hsphy->clks); | |
| 465 | 486 | regulator_bulk_disable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs); |
| 466 | 487 | hsphy->phy_initialized = false; |
| 467 | 488 | |
| @@ -554,14 +575,15 @@ static int qcom_snps_hsphy_probe(struct platform_device *pdev) · 86 unmodified lines | ||
| 554 | 575 | if (!hsphy) |
| 555 | 576 | return -ENOMEM; |
| 556 | 577 | |
| 578 | + hsphy->dev = dev; | |
| 579 | + | |
| 557 | 580 | hsphy->base = devm_platform_ioremap_resource(pdev, 0); |
| 558 | 581 | if (IS_ERR(hsphy->base)) |
| 559 | 582 | return PTR_ERR(hsphy->base); |
| 560 | 583 | |
| 561 | − hsphy->ref_clk = devm_clk_get(dev, "ref"); | |
| 562 | − if (IS_ERR(hsphy->ref_clk)) | |
| 563 | − return dev_err_probe(dev, PTR_ERR(hsphy->ref_clk), | |
| 564 | − "failed to get ref clk\n"); | |
| 584 | + ret = qcom_snps_hsphy_clk_init(hsphy); | |
| 585 | + if (ret) | |
| 586 | + return dev_err_probe(dev, ret, "failed to initialize clocks\n"); | |
| 565 | 587 | |
| 566 | 588 | hsphy->phy_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL); |
| 567 | 589 | if (IS_ERR(hsphy->phy_reset)) { |
| @@ -11,7 +11,6 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/dmi.h> |
| 12 | 12 | #include <linux/io.h> |
| 13 | 13 | #include <linux/ioport.h> |
| 14 | −#include <linux/slab.h> | |
| 15 | 14 | |
| 16 | 15 | #include "pmc.h" |
| 17 | 16 | |
| @@ -135,12 +134,10 @@ static const struct dmi_system_id fwbug_list[] = { · 117 unmodified lines | ||
| 135 | 134 | */ |
| 136 | 135 | static void amd_pmc_skip_nvme_smi_handler(u32 s2idle_bug_mmio) |
| 137 | 136 | { |
| 138 | − struct resource *res; | |
| 139 | 137 | void __iomem *addr; |
| 140 | 138 | u8 val; |
| 141 | 139 | |
| 142 | − res = request_mem_region_muxed(s2idle_bug_mmio, 1, "amd_pmc_pm80"); | |
| 143 | − if (!res) | |
| 140 | + if (!request_mem_region_muxed(s2idle_bug_mmio, 1, "amd_pmc_pm80")) | |
| 144 | 141 | return; |
| 145 | 142 | |
| 146 | 143 | addr = ioremap(s2idle_bug_mmio, 1); |
| @@ -152,8 +149,7 @@ static void amd_pmc_skip_nvme_smi_handler(u32 s2idle_bug_mmio) · 5 unmodified lines | ||
| 152 | 149 | |
| 153 | 150 | iounmap(addr); |
| 154 | 151 | cleanup_resource: |
| 155 | − release_resource(res); | |
| 156 | − kfree(res); | |
| 152 | + release_mem_region(s2idle_bug_mmio, 1); | |
| 157 | 153 | } |
| 158 | 154 | |
| 159 | 155 | void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev) |
| @@ -106,6 +106,27 @@ int apmf_get_static_slider_granular(struct amd_pmf_dev *pdev, · 105 unmodified lines | ||
| 106 | 106 | data, sizeof(*data)); |
| 107 | 107 | } |
| 108 | 108 | |
| 109 | +int apmf_os_power_slider_update(struct amd_pmf_dev *pdev, u8 event) | |
| 110 | +{ | |
| 111 | + struct os_power_slider args; | |
| 112 | + struct acpi_buffer params; | |
| 113 | + union acpi_object *info; | |
| 114 | + int err = 0; | |
| 115 | + | |
| 116 | + args.size = sizeof(args); | |
| 117 | + args.slider_event = event; | |
| 118 | + | |
| 119 | + params.length = sizeof(args); | |
| 120 | + params.pointer = (void *)&args; | |
| 121 | + | |
| 122 | + info = apmf_if_call(pdev, APMF_FUNC_OS_POWER_SLIDER_UPDATE, ¶ms); | |
| 123 | + if (!info) | |
| 124 | + err = -EIO; | |
| 125 | + | |
| 126 | + kfree(info); | |
| 127 | + return err; | |
| 128 | +} | |
| 129 | + | |
| 109 | 130 | static void apmf_sbios_heartbeat_notify(struct work_struct *work) |
| 110 | 131 | { |
| 111 | 132 | struct amd_pmf_dev *dev = container_of(work, struct amd_pmf_dev, heart_beat.work); |
| @@ -289,7 +310,7 @@ int apmf_acpi_init(struct amd_pmf_dev *pmf_dev) · 177 unmodified lines | ||
| 289 | 310 | |
| 290 | 311 | ret = apmf_get_system_params(pmf_dev); |
| 291 | 312 | if (ret) { |
| 292 | − dev_err(pmf_dev->dev, "APMF apmf_get_system_params failed :%d\n", ret); | |
| 313 | + dev_dbg(pmf_dev->dev, "APMF apmf_get_system_params failed :%d\n", ret); | |
| 293 | 314 | goto out; |
| 294 | 315 | } |
| 295 | 316 | |
| @@ -72,7 +72,11 @@ static int amd_pmf_pwr_src_notify_call(struct notifier_block *nb, unsigned long · 71 unmodified lines | ||
| 72 | 72 | return NOTIFY_DONE; |
| 73 | 73 | } |
| 74 | 74 | |
| 75 | − amd_pmf_set_sps_power_limits(pmf); | |
| 75 | + if (is_apmf_func_supported(pmf, APMF_FUNC_STATIC_SLIDER_GRANULAR)) | |
| 76 | + amd_pmf_set_sps_power_limits(pmf); | |
| 77 | + | |
| 78 | + if (is_apmf_func_supported(pmf, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) | |
| 79 | + amd_pmf_power_slider_update_event(pmf); | |
| 76 | 80 | |
| 77 | 81 | return NOTIFY_OK; |
| 78 | 82 | } |
| @@ -297,7 +301,8 @@ static void amd_pmf_init_features(struct amd_pmf_dev *dev) · 218 unmodified lines | ||
| 297 | 301 | int ret; |
| 298 | 302 | |
| 299 | 303 | /* Enable Static Slider */ |
| 300 | − if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { | |
| 304 | + if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR) || | |
| 305 | + is_apmf_func_supported(dev, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) { | |
| 301 | 306 | amd_pmf_init_sps(dev); |
| 302 | 307 | dev->pwr_src_notifier.notifier_call = amd_pmf_pwr_src_notify_call; |
| 303 | 308 | power_supply_reg_notifier(&dev->pwr_src_notifier); |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #define APMF_FUNC_SBIOS_HEARTBEAT 4 |
| 22 | 22 | #define APMF_FUNC_AUTO_MODE 5 |
| 23 | 23 | #define APMF_FUNC_SET_FAN_IDX 7 |
| 24 | +#define APMF_FUNC_OS_POWER_SLIDER_UPDATE 8 | |
| 24 | 25 | #define APMF_FUNC_STATIC_SLIDER_GRANULAR 9 |
| 25 | 26 | #define APMF_FUNC_DYN_SLIDER_AC 11 |
| 26 | 27 | #define APMF_FUNC_DYN_SLIDER_DC 12 |
| @@ -44,6 +45,14 @@ · 17 unmodified lines | ||
| 44 | 45 | #define GET_STT_LIMIT_APU 0x20 |
| 45 | 46 | #define GET_STT_LIMIT_HS2 0x21 |
| 46 | 47 | |
| 48 | +/* OS slider update notification */ | |
| 49 | +#define DC_BEST_PERF 0 | |
| 50 | +#define DC_BETTER_PERF 1 | |
| 51 | +#define DC_BATTERY_SAVER 3 | |
| 52 | +#define AC_BEST_PERF 4 | |
| 53 | +#define AC_BETTER_PERF 5 | |
| 54 | +#define AC_BETTER_BATTERY 6 | |
| 55 | + | |
| 47 | 56 | /* Fan Index for Auto Mode */ |
| 48 | 57 | #define FAN_INDEX_AUTO 0xFFFFFFFF |
| 49 | 58 | |
| @@ -193,6 +202,11 @@ struct amd_pmf_static_slider_granular { · 143 unmodified lines | ||
| 193 | 202 | struct apmf_sps_prop_granular prop[POWER_SOURCE_MAX][POWER_MODE_MAX]; |
| 194 | 203 | }; |
| 195 | 204 | |
| 205 | +struct os_power_slider { | |
| 206 | + u16 size; | |
| 207 | + u8 slider_event; | |
| 208 | +} __packed; | |
| 209 | + | |
| 196 | 210 | struct fan_table_control { |
| 197 | 211 | bool manual; |
| 198 | 212 | unsigned long fan_id; |
| @@ -383,6 +397,7 @@ int amd_pmf_send_cmd(struct amd_pmf_dev *dev, u8 message, bool get, u32 arg, u32 · 184 unmodified lines | ||
| 383 | 397 | int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev); |
| 384 | 398 | int amd_pmf_get_power_source(void); |
| 385 | 399 | int apmf_install_handler(struct amd_pmf_dev *pmf_dev); |
| 400 | +int apmf_os_power_slider_update(struct amd_pmf_dev *dev, u8 flag); | |
| 386 | 401 | |
| 387 | 402 | /* SPS Layer */ |
| 388 | 403 | int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf); |
| @@ -393,6 +408,7 @@ void amd_pmf_deinit_sps(struct amd_pmf_dev *dev); · 4 unmodified lines | ||
| 393 | 408 | int apmf_get_static_slider_granular(struct amd_pmf_dev *pdev, |
| 394 | 409 | struct apmf_static_slider_granular_output *output); |
| 395 | 410 | bool is_pprof_balanced(struct amd_pmf_dev *pmf); |
| 411 | +int amd_pmf_power_slider_update_event(struct amd_pmf_dev *dev); | |
| 396 | 412 | |
| 397 | 413 | |
| 398 | 414 | int apmf_update_fan_idx(struct amd_pmf_dev *pdev, bool manual, u32 idx); |
| @@ -174,14 +174,78 @@ int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf) · 173 unmodified lines | ||
| 174 | 174 | return mode; |
| 175 | 175 | } |
| 176 | 176 | |
| 177 | +int amd_pmf_power_slider_update_event(struct amd_pmf_dev *dev) | |
| 178 | +{ | |
| 179 | + u8 flag = 0; | |
| 180 | + int mode; | |
| 181 | + int src; | |
| 182 | + | |
| 183 | + mode = amd_pmf_get_pprof_modes(dev); | |
| 184 | + if (mode < 0) | |
| 185 | + return mode; | |
| 186 | + | |
| 187 | + src = amd_pmf_get_power_source(); | |
| 188 | + | |
| 189 | + if (src == POWER_SOURCE_AC) { | |
| 190 | + switch (mode) { | |
| 191 | + case POWER_MODE_PERFORMANCE: | |
| 192 | + flag |= BIT(AC_BEST_PERF); | |
| 193 | + break; | |
| 194 | + case POWER_MODE_BALANCED_POWER: | |
| 195 | + flag |= BIT(AC_BETTER_PERF); | |
| 196 | + break; | |
| 197 | + case POWER_MODE_POWER_SAVER: | |
| 198 | + flag |= BIT(AC_BETTER_BATTERY); | |
| 199 | + break; | |
| 200 | + default: | |
| 201 | + dev_err(dev->dev, "unsupported platform profile\n"); | |
| 202 | + return -EOPNOTSUPP; | |
| 203 | + } | |
| 204 | + | |
| 205 | + } else if (src == POWER_SOURCE_DC) { | |
| 206 | + switch (mode) { | |
| 207 | + case POWER_MODE_PERFORMANCE: | |
| 208 | + flag |= BIT(DC_BEST_PERF); | |
| 209 | + break; | |
| 210 | + case POWER_MODE_BALANCED_POWER: | |
| 211 | + flag |= BIT(DC_BETTER_PERF); | |
| 212 | + break; | |
| 213 | + case POWER_MODE_POWER_SAVER: | |
| 214 | + flag |= BIT(DC_BATTERY_SAVER); | |
| 215 | + break; | |
| 216 | + default: | |
| 217 | + dev_err(dev->dev, "unsupported platform profile\n"); | |
| 218 | + return -EOPNOTSUPP; | |
| 219 | + } | |
| 220 | + } | |
| 221 | + | |
| 222 | + apmf_os_power_slider_update(dev, flag); | |
| 223 | + | |
| 224 | + return 0; | |
| 225 | +} | |
| 226 | + | |
| 177 | 227 | static int amd_pmf_profile_set(struct platform_profile_handler *pprof, |
| 178 | 228 | enum platform_profile_option profile) |
| 179 | 229 | { |
| 180 | 230 | struct amd_pmf_dev *pmf = container_of(pprof, struct amd_pmf_dev, pprof); |
| 231 | + int ret = 0; | |
| 181 | 232 | |
| 182 | 233 | pmf->current_profile = profile; |
| 183 | 234 | |
| 184 | − return amd_pmf_set_sps_power_limits(pmf); | |
| 235 | + /* Notify EC about the slider position change */ | |
| 236 | + if (is_apmf_func_supported(pmf, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) { | |
| 237 | + ret = amd_pmf_power_slider_update_event(pmf); | |
| 238 | + if (ret) | |
| 239 | + return ret; | |
| 240 | + } | |
| 241 | + | |
| 242 | + if (is_apmf_func_supported(pmf, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { | |
| 243 | + ret = amd_pmf_set_sps_power_limits(pmf); | |
| 244 | + if (ret) | |
| 245 | + return ret; | |
| 246 | + } | |
| 247 | + | |
| 248 | + return 0; | |
| 185 | 249 | } |
| 186 | 250 | |
| 187 | 251 | int amd_pmf_init_sps(struct amd_pmf_dev *dev) |
| @@ -189,10 +253,13 @@ int amd_pmf_init_sps(struct amd_pmf_dev *dev) · 1 unmodified line | ||
| 189 | 253 | int err; |
| 190 | 254 | |
| 191 | 255 | dev->current_profile = PLATFORM_PROFILE_BALANCED; |
| 192 | − amd_pmf_load_defaults_sps(dev); | |
| 193 | 256 | |
| 194 | − /* update SPS balanced power mode thermals */ | |
| 195 | − amd_pmf_set_sps_power_limits(dev); | |
| 257 | + if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { | |
| 258 | + amd_pmf_load_defaults_sps(dev); | |
| 259 | + | |
| 260 | + /* update SPS balanced power mode thermals */ | |
| 261 | + amd_pmf_set_sps_power_limits(dev); | |
| 262 | + } | |
| 196 | 263 | |
| 197 | 264 | dev->pprof.profile_get = amd_pmf_profile_get; |
| 198 | 265 | dev->pprof.profile_set = amd_pmf_profile_set; |
| @@ -738,13 +738,23 @@ static ssize_t kbd_rgb_mode_store(struct device *dev, · 737 unmodified lines | ||
| 738 | 738 | struct device_attribute *attr, |
| 739 | 739 | const char *buf, size_t count) |
| 740 | 740 | { |
| 741 | − u32 cmd, mode, r, g, b, speed; | |
| 741 | + u32 cmd, mode, r, g, b, speed; | |
| 742 | 742 | int err; |
| 743 | 743 | |
| 744 | 744 | if (sscanf(buf, "%d %d %d %d %d %d", &cmd, &mode, &r, &g, &b, &speed) != 6) |
| 745 | 745 | return -EINVAL; |
| 746 | 746 | |
| 747 | − cmd = !!cmd; | |
| 747 | + /* B3 is set and B4 is save to BIOS */ | |
| 748 | + switch (cmd) { | |
| 749 | + case 0: | |
| 750 | + cmd = 0xb3; | |
| 751 | + break; | |
| 752 | + case 1: | |
| 753 | + cmd = 0xb4; | |
| 754 | + break; | |
| 755 | + default: | |
| 756 | + return -EINVAL; | |
| 757 | + } | |
| 748 | 758 | |
| 749 | 759 | /* These are the known usable modes across all TUF/ROG */ |
| 750 | 760 | if (mode >= 12 || mode == 9) |
| @@ -85,6 +85,8 @@ static const struct key_entry huawei_wmi_keymap[] = { · 84 unmodified lines | ||
| 85 | 85 | { KE_IGNORE, 0x293, { KEY_KBDILLUMTOGGLE } }, |
| 86 | 86 | { KE_IGNORE, 0x294, { KEY_KBDILLUMUP } }, |
| 87 | 87 | { KE_IGNORE, 0x295, { KEY_KBDILLUMUP } }, |
| 88 | + // Ignore Ambient Light Sensoring | |
| 89 | + { KE_KEY, 0x2c1, { KEY_RESERVED } }, | |
| 88 | 90 | { KE_END, 0 } |
| 89 | 91 | }; |
| 90 | 92 | |
| @@ -150,6 +150,12 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = { · 149 unmodified lines | ||
| 150 | 150 | DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go"), |
| 151 | 151 | }, |
| 152 | 152 | }, |
| 153 | + { | |
| 154 | + .matches = { | |
| 155 | + DMI_MATCH(DMI_SYS_VENDOR, "HP"), | |
| 156 | + DMI_MATCH(DMI_PRODUCT_NAME, "HP Elite Dragonfly G2 Notebook PC"), | |
| 157 | + }, | |
| 158 | + }, | |
| 153 | 159 | { } |
| 154 | 160 | }; |
| 155 | 161 | |
| @@ -620,7 +626,7 @@ static bool button_array_present(struct platform_device *device) · 464 unmodified lines | ||
| 620 | 626 | static int intel_hid_probe(struct platform_device *device) |
| 621 | 627 | { |
| 622 | 628 | acpi_handle handle = ACPI_HANDLE(&device->dev); |
| 623 | − unsigned long long mode; | |
| 629 | + unsigned long long mode, dummy; | |
| 624 | 630 | struct intel_hid_priv *priv; |
| 625 | 631 | acpi_status status; |
| 626 | 632 | int err; |
| @@ -692,18 +698,15 @@ static int intel_hid_probe(struct platform_device *device) · 65 unmodified lines | ||
| 692 | 698 | if (err) |
| 693 | 699 | goto err_remove_notify; |
| 694 | 700 | |
| 695 | − if (priv->array) { | |
| 696 | − unsigned long long dummy; | |
| 701 | + intel_button_array_enable(&device->dev, true); | |
| 697 | 702 | |
| 698 | − intel_button_array_enable(&device->dev, true); | |
| 699 | − | |
| 700 | − /* Call button load method to enable HID power button */ | |
| 701 | − if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN, | |
| 702 | − &dummy)) { | |
| 703 | − dev_warn(&device->dev, | |
| 704 | − "failed to enable HID power button\n"); | |
| 705 | − } | |
| 706 | − } | |
| 703 | + /* | |
| 704 | + * Call button load method to enable HID power button | |
| 705 | + * Always do this since it activates events on some devices without | |
| 706 | + * a button array too. | |
| 707 | + */ | |
| 708 | + if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN, &dummy)) | |
| 709 | + dev_warn(&device->dev, "failed to enable HID power button\n"); | |
| 707 | 710 | |
| 708 | 711 | device_init_wakeup(&device->dev, true); |
| 709 | 712 | /* |
| @@ -335,8 +335,8 @@ static struct pci_dev *_isst_if_get_pci_dev(int cpu, int bus_no, int dev, int fn · 334 unmodified lines | ||
| 335 | 335 | |
| 336 | 336 | node = dev_to_node(&_pci_dev->dev); |
| 337 | 337 | if (node == NUMA_NO_NODE) { |
| 338 | − pr_info("Fail to get numa node for CPU:%d bus:%d dev:%d fn:%d\n", | |
| 339 | − cpu, bus_no, dev, fn); | |
| 338 | + pr_info_once("Fail to get numa node for CPU:%d bus:%d dev:%d fn:%d\n", | |
| 339 | + cpu, bus_no, dev, fn); | |
| 340 | 340 | continue; |
| 341 | 341 | } |
| 342 | 342 | |
| @@ -24,6 +24,10 @@ static bool ec_trigger __read_mostly; · 23 unmodified lines | ||
| 24 | 24 | module_param(ec_trigger, bool, 0444); |
| 25 | 25 | MODULE_PARM_DESC(ec_trigger, "Enable EC triggering work-around to force emitting tablet mode events"); |
| 26 | 26 | |
| 27 | +static bool force; | |
| 28 | +module_param(force, bool, 0444); | |
| 29 | +MODULE_PARM_DESC(force, "Force loading on boards without a convertible DMI chassis-type"); | |
| 30 | + | |
| 27 | 31 | static const struct dmi_system_id ec_trigger_quirk_dmi_table[] = { |
| 28 | 32 | { |
| 29 | 33 | /* Lenovo Yoga 7 14ARB7 */ |
| @@ -35,6 +39,20 @@ static const struct dmi_system_id ec_trigger_quirk_dmi_table[] = { · 5 unmodified lines | ||
| 35 | 39 | { } |
| 36 | 40 | }; |
| 37 | 41 | |
| 42 | +static const struct dmi_system_id allowed_chasis_types_dmi_table[] = { | |
| 43 | + { | |
| 44 | + .matches = { | |
| 45 | + DMI_EXACT_MATCH(DMI_CHASSIS_TYPE, "31" /* Convertible */), | |
| 46 | + }, | |
| 47 | + }, | |
| 48 | + { | |
| 49 | + .matches = { | |
| 50 | + DMI_EXACT_MATCH(DMI_CHASSIS_TYPE, "32" /* Detachable */), | |
| 51 | + }, | |
| 52 | + }, | |
| 53 | + { } | |
| 54 | +}; | |
| 55 | + | |
| 38 | 56 | struct lenovo_ymc_private { |
| 39 | 57 | struct input_dev *input_dev; |
| 40 | 58 | struct acpi_device *ec_acpi_dev; |
| @@ -111,6 +129,13 @@ static int lenovo_ymc_probe(struct wmi_device *wdev, const void *ctx) · 70 unmodified lines | ||
| 111 | 129 | struct input_dev *input_dev; |
| 112 | 130 | int err; |
| 113 | 131 | |
| 132 | + if (!dmi_check_system(allowed_chasis_types_dmi_table)) { | |
| 133 | + if (force) | |
| 134 | + dev_info(&wdev->dev, "Force loading Lenovo YMC support\n"); | |
| 135 | + else | |
| 136 | + return -ENODEV; | |
| 137 | + } | |
| 138 | + | |
| 114 | 139 | ec_trigger |= dmi_check_system(ec_trigger_quirk_dmi_table); |
| 115 | 140 | |
| 116 | 141 | priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL); |
| @@ -62,10 +62,6 @@ · 61 unmodified lines | ||
| 62 | 62 | #define MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET 0x37 |
| 63 | 63 | #define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET 0x3a |
| 64 | 64 | #define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET 0x3b |
| 65 | −#define MLXPLAT_CPLD_LPC_REG_DBG1_OFFSET 0x3c | |
| 66 | −#define MLXPLAT_CPLD_LPC_REG_DBG2_OFFSET 0x3d | |
| 67 | −#define MLXPLAT_CPLD_LPC_REG_DBG3_OFFSET 0x3e | |
| 68 | −#define MLXPLAT_CPLD_LPC_REG_DBG4_OFFSET 0x3f | |
| 69 | 65 | #define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET 0x40 |
| 70 | 66 | #define MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET 0x41 |
| 71 | 67 | #define MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET 0x42 |
| @@ -126,6 +122,10 @@ · 54 unmodified lines | ||
| 126 | 122 | #define MLXPLAT_CPLD_LPC_REG_LC_SD_EVENT_OFFSET 0xaa |
| 127 | 123 | #define MLXPLAT_CPLD_LPC_REG_LC_SD_MASK_OFFSET 0xab |
| 128 | 124 | #define MLXPLAT_CPLD_LPC_REG_LC_PWR_ON 0xb2 |
| 125 | +#define MLXPLAT_CPLD_LPC_REG_DBG1_OFFSET 0xb6 | |
| 126 | +#define MLXPLAT_CPLD_LPC_REG_DBG2_OFFSET 0xb7 | |
| 127 | +#define MLXPLAT_CPLD_LPC_REG_DBG3_OFFSET 0xb8 | |
| 128 | +#define MLXPLAT_CPLD_LPC_REG_DBG4_OFFSET 0xb9 | |
| 129 | 129 | #define MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET 0xc2 |
| 130 | 130 | #define MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT 0xc3 |
| 131 | 131 | #define MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET 0xc7 |
| @@ -222,7 +222,7 @@ · 90 unmodified lines | ||
| 222 | 222 | MLXPLAT_CPLD_AGGR_MASK_LC_SDWN) |
| 223 | 223 | #define MLXPLAT_CPLD_LOW_AGGR_MASK_LOW 0xc1 |
| 224 | 224 | #define MLXPLAT_CPLD_LOW_AGGR_MASK_ASIC2 BIT(2) |
| 225 | −#define MLXPLAT_CPLD_LOW_AGGR_MASK_PWR_BUT BIT(4) | |
| 225 | +#define MLXPLAT_CPLD_LOW_AGGR_MASK_PWR_BUT GENMASK(5, 4) | |
| 226 | 226 | #define MLXPLAT_CPLD_LOW_AGGR_MASK_I2C BIT(6) |
| 227 | 227 | #define MLXPLAT_CPLD_PSU_MASK GENMASK(1, 0) |
| 228 | 228 | #define MLXPLAT_CPLD_PWR_MASK GENMASK(1, 0) |
| @@ -237,7 +237,7 @@ · 8 unmodified lines | ||
| 237 | 237 | #define MLXPLAT_CPLD_GWP_MASK GENMASK(0, 0) |
| 238 | 238 | #define MLXPLAT_CPLD_EROT_MASK GENMASK(1, 0) |
| 239 | 239 | #define MLXPLAT_CPLD_PWR_BUTTON_MASK BIT(0) |
| 240 | −#define MLXPLAT_CPLD_LATCH_RST_MASK BIT(5) | |
| 240 | +#define MLXPLAT_CPLD_LATCH_RST_MASK BIT(6) | |
| 241 | 241 | #define MLXPLAT_CPLD_THERMAL1_PDB_MASK BIT(3) |
| 242 | 242 | #define MLXPLAT_CPLD_THERMAL2_PDB_MASK BIT(4) |
| 243 | 243 | #define MLXPLAT_CPLD_INTRUSION_MASK BIT(6) |
| @@ -2356,7 +2356,7 @@ mlxplat_mlxcpld_l1_switch_pwr_events_handler(void *handle, enum mlxreg_hotplug_k · 2112 unmodified lines | ||
| 2356 | 2356 | u8 action) |
| 2357 | 2357 | { |
| 2358 | 2358 | dev_info(&mlxplat_dev->dev, "System shutdown due to short press of power button"); |
| 2359 | − kernel_halt(); | |
| 2359 | + kernel_power_off(); | |
| 2360 | 2360 | return 0; |
| 2361 | 2361 | } |
| 2362 | 2362 | |
| @@ -2475,7 +2475,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_l1_switch_events_items[] = { · 112 unmodified lines | ||
| 2475 | 2475 | .reg = MLXPLAT_CPLD_LPC_REG_PWRB_OFFSET, |
| 2476 | 2476 | .mask = MLXPLAT_CPLD_PWR_BUTTON_MASK, |
| 2477 | 2477 | .count = ARRAY_SIZE(mlxplat_mlxcpld_l1_switch_pwr_events_items_data), |
| 2478 | − .inversed = 0, | |
| 2478 | + .inversed = 1, | |
| 2479 | 2479 | .health = false, |
| 2480 | 2480 | }, |
| 2481 | 2481 | { |
| @@ -2484,7 +2484,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_l1_switch_events_items[] = { · 2 unmodified lines | ||
| 2484 | 2484 | .reg = MLXPLAT_CPLD_LPC_REG_BRD_OFFSET, |
| 2485 | 2485 | .mask = MLXPLAT_CPLD_L1_CHA_HEALTH_MASK, |
| 2486 | 2486 | .count = ARRAY_SIZE(mlxplat_mlxcpld_l1_switch_health_events_items_data), |
| 2487 | − .inversed = 0, | |
| 2487 | + .inversed = 1, | |
| 2488 | 2488 | .health = false, |
| 2489 | 2489 | .ind = 8, |
| 2490 | 2490 | }, |
| @@ -3677,7 +3677,7 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = { · 1186 unmodified lines | ||
| 3677 | 3677 | { |
| 3678 | 3678 | .label = "latch_reset", |
| 3679 | 3679 | .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, |
| 3680 | − .mask = GENMASK(7, 0) & ~BIT(5), | |
| 3680 | + .mask = GENMASK(7, 0) & ~BIT(6), | |
| 3681 | 3681 | .mode = 0200, |
| 3682 | 3682 | }, |
| 3683 | 3683 | { |
| @@ -6238,8 +6238,6 @@ static void mlxplat_i2c_mux_topolgy_exit(struct mlxplat_priv *priv) · 2554 unmodified lines | ||
| 6238 | 6238 | if (priv->pdev_mux[i]) |
| 6239 | 6239 | platform_device_unregister(priv->pdev_mux[i]); |
| 6240 | 6240 | } |
| 6241 | − | |
| 6242 | − mlxplat_post_exit(); | |
| 6243 | 6241 | } |
| 6244 | 6242 | |
| 6245 | 6243 | static int mlxplat_i2c_main_complition_notify(void *handle, int id) |
| @@ -6369,6 +6367,7 @@ static void __exit mlxplat_exit(void) · 123 unmodified lines | ||
| 6369 | 6367 | pm_power_off = NULL; |
| 6370 | 6368 | mlxplat_pre_exit(priv); |
| 6371 | 6369 | mlxplat_i2c_main_exit(priv); |
| 6370 | + mlxplat_post_exit(); | |
| 6372 | 6371 | } |
| 6373 | 6372 | module_exit(mlxplat_exit); |
| 6374 | 6373 | |
| @@ -27,15 +27,15 @@ · 26 unmodified lines | ||
| 27 | 27 | #include <linux/seq_file.h> |
| 28 | 28 | #include <linux/string.h> |
| 29 | 29 | |
| 30 | −static const char *const SM_ECO_NAME = "eco"; | |
| 31 | −static const char *const SM_COMFORT_NAME = "comfort"; | |
| 32 | −static const char *const SM_SPORT_NAME = "sport"; | |
| 33 | −static const char *const SM_TURBO_NAME = "turbo"; | |
| 34 | − | |
| 35 | −static const char *const FM_AUTO_NAME = "auto"; | |
| 36 | −static const char *const FM_SILENT_NAME = "silent"; | |
| 37 | −static const char *const FM_BASIC_NAME = "basic"; | |
| 38 | −static const char *const FM_ADVANCED_NAME = "advanced"; | |
| 30 | +#define SM_ECO_NAME "eco" | |
| 31 | +#define SM_COMFORT_NAME "comfort" | |
| 32 | +#define SM_SPORT_NAME "sport" | |
| 33 | +#define SM_TURBO_NAME "turbo" | |
| 34 | + | |
| 35 | +#define FM_AUTO_NAME "auto" | |
| 36 | +#define FM_SILENT_NAME "silent" | |
| 37 | +#define FM_BASIC_NAME "basic" | |
| 38 | +#define FM_ADVANCED_NAME "advanced" | |
| 39 | 39 | |
| 40 | 40 | static const char * const ALLOWED_FW_0[] __initconst = { |
| 41 | 41 | "14C1EMS1.012", |
| @@ -208,7 +208,7 @@ static ssize_t set_device_state(const char *buf, size_t count, u8 mask) · 207 unmodified lines | ||
| 208 | 208 | return -EINVAL; |
| 209 | 209 | |
| 210 | 210 | if (quirks->ec_read_only) |
| 211 | − return -EOPNOTSUPP; | |
| 211 | + return 0; | |
| 212 | 212 | |
| 213 | 213 | /* read current device state */ |
| 214 | 214 | result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata); |
| @@ -838,15 +838,15 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str, · 623 unmodified lines | ||
| 838 | 838 | static void msi_init_rfkill(struct work_struct *ignored) |
| 839 | 839 | { |
| 840 | 840 | if (rfk_wlan) { |
| 841 | − rfkill_set_sw_state(rfk_wlan, !wlan_s); | |
| 841 | + msi_rfkill_set_state(rfk_wlan, !wlan_s); | |
| 842 | 842 | rfkill_wlan_set(NULL, !wlan_s); |
| 843 | 843 | } |
| 844 | 844 | if (rfk_bluetooth) { |
| 845 | − rfkill_set_sw_state(rfk_bluetooth, !bluetooth_s); | |
| 845 | + msi_rfkill_set_state(rfk_bluetooth, !bluetooth_s); | |
| 846 | 846 | rfkill_bluetooth_set(NULL, !bluetooth_s); |
| 847 | 847 | } |
| 848 | 848 | if (rfk_threeg) { |
| 849 | − rfkill_set_sw_state(rfk_threeg, !threeg_s); | |
| 849 | + msi_rfkill_set_state(rfk_threeg, !threeg_s); | |
| 850 | 850 | rfkill_threeg_set(NULL, !threeg_s); |
| 851 | 851 | } |
| 852 | 852 | } |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #define IRQ_RESOURCE_NONE 0 |
| 22 | 22 | #define IRQ_RESOURCE_GPIO 1 |
| 23 | 23 | #define IRQ_RESOURCE_APIC 2 |
| 24 | +#define IRQ_RESOURCE_AUTO 3 | |
| 24 | 25 | |
| 25 | 26 | enum smi_bus_type { |
| 26 | 27 | SMI_I2C, |
| @@ -52,6 +53,18 @@ static int smi_get_irq(struct platform_device *pdev, struct acpi_device *adev, · 25 unmodified lines | ||
| 52 | 53 | int ret; |
| 53 | 54 | |
| 54 | 55 | switch (inst->flags & IRQ_RESOURCE_TYPE) { |
| 56 | + case IRQ_RESOURCE_AUTO: | |
| 57 | + ret = acpi_dev_gpio_irq_get(adev, inst->irq_idx); | |
| 58 | + if (ret > 0) { | |
| 59 | + dev_dbg(&pdev->dev, "Using gpio irq\n"); | |
| 60 | + break; | |
| 61 | + } | |
| 62 | + ret = platform_get_irq(pdev, inst->irq_idx); | |
| 63 | + if (ret > 0) { | |
| 64 | + dev_dbg(&pdev->dev, "Using platform irq\n"); | |
| 65 | + break; | |
| 66 | + } | |
| 67 | + break; | |
| 55 | 68 | case IRQ_RESOURCE_GPIO: |
| 56 | 69 | ret = acpi_dev_gpio_irq_get(adev, inst->irq_idx); |
| 57 | 70 | break; |
| @@ -307,10 +320,23 @@ static const struct smi_node int3515_data = { · 249 unmodified lines | ||
| 307 | 320 | |
| 308 | 321 | static const struct smi_node cs35l41_hda = { |
| 309 | 322 | .instances = { |
| 310 | − { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, | |
| 311 | − { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, | |
| 312 | − { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, | |
| 313 | − { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, | |
| 323 | + { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, | |
| 324 | + { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, | |
| 325 | + { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, | |
| 326 | + { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, | |
| 327 | + {} | |
| 328 | + }, | |
| 329 | + .bus_type = SMI_AUTO_DETECT, | |
| 330 | +}; | |
| 331 | + | |
| 332 | +static const struct smi_node cs35l56_hda = { | |
| 333 | + .instances = { | |
| 334 | + { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, | |
| 335 | + { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, | |
| 336 | + { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, | |
| 337 | + { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, | |
| 338 | + /* a 5th entry is an alias address, not a real device */ | |
| 339 | + { "cs35l56-hda_dummy_dev" }, | |
| 314 | 340 | {} |
| 315 | 341 | }, |
| 316 | 342 | .bus_type = SMI_AUTO_DETECT, |
| @@ -324,6 +350,7 @@ static const struct acpi_device_id smi_acpi_ids[] = { · 7 unmodified lines | ||
| 324 | 350 | { "BSG1160", (unsigned long)&bsg1160_data }, |
| 325 | 351 | { "BSG2150", (unsigned long)&bsg2150_data }, |
| 326 | 352 | { "CSC3551", (unsigned long)&cs35l41_hda }, |
| 353 | + { "CSC3556", (unsigned long)&cs35l56_hda }, | |
| 327 | 354 | { "INT3515", (unsigned long)&int3515_data }, |
| 328 | 355 | /* Non-conforming _HID for Cirrus Logic already released */ |
| 329 | 356 | { "CLSA0100", (unsigned long)&cs35l41_hda }, |
| @@ -719,12 +719,12 @@ static ssize_t cert_to_password_store(struct kobject *kobj, · 718 unmodified lines | ||
| 719 | 719 | /* Format: 'Password,Signature' */ |
| 720 | 720 | auth_str = kasprintf(GFP_KERNEL, "%s,%s", passwd, setting->signature); |
| 721 | 721 | if (!auth_str) { |
| 722 | − kfree(passwd); | |
| 722 | + kfree_sensitive(passwd); | |
| 723 | 723 | return -ENOMEM; |
| 724 | 724 | } |
| 725 | 725 | ret = tlmi_simple_call(LENOVO_CERT_TO_PASSWORD_GUID, auth_str); |
| 726 | 726 | kfree(auth_str); |
| 727 | − kfree(passwd); | |
| 727 | + kfree_sensitive(passwd); | |
| 728 | 728 | |
| 729 | 729 | return ret ?: count; |
| 730 | 730 | } |
| @@ -27,11 +27,12 @@ struct ts_dmi_data { · 26 unmodified lines | ||
| 27 | 27 | /* NOTE: Please keep all entries sorted alphabetically */ |
| 28 | 28 | |
| 29 | 29 | static const struct property_entry archos_101_cesium_educ_props[] = { |
| 30 | − PROPERTY_ENTRY_U32("touchscreen-size-x", 1280), | |
| 31 | − PROPERTY_ENTRY_U32("touchscreen-size-y", 1850), | |
| 32 | − PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"), | |
| 30 | + PROPERTY_ENTRY_U32("touchscreen-size-x", 1850), | |
| 31 | + PROPERTY_ENTRY_U32("touchscreen-size-y", 1280), | |
| 32 | + PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), | |
| 33 | 33 | PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), |
| 34 | 34 | PROPERTY_ENTRY_U32("silead,max-fingers", 10), |
| 35 | + PROPERTY_ENTRY_BOOL("silead,home-button"), | |
| 35 | 36 | PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-archos-101-cesium-educ.fw"), |
| 36 | 37 | { } |
| 37 | 38 | }; |
| @@ -818,7 +818,7 @@ static int rapl_read_data_raw(struct rapl_domain *rd, · 817 unmodified lines | ||
| 818 | 818 | return -EINVAL; |
| 819 | 819 | |
| 820 | 820 | ra.reg = rd->regs[rpi->id]; |
| 821 | − if (!ra.reg) | |
| 821 | + if (!ra.reg.val) | |
| 822 | 822 | return -EINVAL; |
| 823 | 823 | |
| 824 | 824 | /* non-hardware data are collected by the polling thread */ |
| @@ -830,7 +830,7 @@ static int rapl_read_data_raw(struct rapl_domain *rd, · 5 unmodified lines | ||
| 830 | 830 | ra.mask = rpi->mask; |
| 831 | 831 | |
| 832 | 832 | if (rd->rp->priv->read_raw(get_rid(rd->rp), &ra)) { |
| 833 | − pr_debug("failed to read reg 0x%llx for %s:%s\n", ra.reg, rd->rp->name, rd->name); | |
| 833 | + pr_debug("failed to read reg 0x%llx for %s:%s\n", ra.reg.val, rd->rp->name, rd->name); | |
| 834 | 834 | return -EIO; |
| 835 | 835 | } |
| 836 | 836 | |
| @@ -920,7 +920,7 @@ static int rapl_check_unit_core(struct rapl_domain *rd) · 83 unmodified lines | ||
| 920 | 920 | ra.mask = ~0; |
| 921 | 921 | if (rd->rp->priv->read_raw(get_rid(rd->rp), &ra)) { |
| 922 | 922 | pr_err("Failed to read power unit REG 0x%llx on %s:%s, exit.\n", |
| 923 | − ra.reg, rd->rp->name, rd->name); | |
| 923 | + ra.reg.val, rd->rp->name, rd->name); | |
| 924 | 924 | return -ENODEV; |
| 925 | 925 | } |
| 926 | 926 | |
| @@ -948,7 +948,7 @@ static int rapl_check_unit_atom(struct rapl_domain *rd) · 21 unmodified lines | ||
| 948 | 948 | ra.mask = ~0; |
| 949 | 949 | if (rd->rp->priv->read_raw(get_rid(rd->rp), &ra)) { |
| 950 | 950 | pr_err("Failed to read power unit REG 0x%llx on %s:%s, exit.\n", |
| 951 | − ra.reg, rd->rp->name, rd->name); | |
| 951 | + ra.reg.val, rd->rp->name, rd->name); | |
| 952 | 952 | return -ENODEV; |
| 953 | 953 | } |
| 954 | 954 | |
| @@ -1135,7 +1135,7 @@ static int rapl_check_unit_tpmi(struct rapl_domain *rd) · 180 unmodified lines | ||
| 1135 | 1135 | ra.mask = ~0; |
| 1136 | 1136 | if (rd->rp->priv->read_raw(get_rid(rd->rp), &ra)) { |
| 1137 | 1137 | pr_err("Failed to read power unit REG 0x%llx on %s:%s, exit.\n", |
| 1138 | − ra.reg, rd->rp->name, rd->name); | |
| 1138 | + ra.reg.val, rd->rp->name, rd->name); | |
| 1139 | 1139 | return -ENODEV; |
| 1140 | 1140 | } |
| 1141 | 1141 | |
| @@ -1411,8 +1411,8 @@ static int rapl_get_domain_unit(struct rapl_domain *rd) · 269 unmodified lines | ||
| 1411 | 1411 | struct rapl_defaults *defaults = get_defaults(rd->rp); |
| 1412 | 1412 | int ret; |
| 1413 | 1413 | |
| 1414 | − if (!rd->regs[RAPL_DOMAIN_REG_UNIT]) { | |
| 1415 | − if (!rd->rp->priv->reg_unit) { | |
| 1414 | + if (!rd->regs[RAPL_DOMAIN_REG_UNIT].val) { | |
| 1415 | + if (!rd->rp->priv->reg_unit.val) { | |
| 1416 | 1416 | pr_err("No valid Unit register found\n"); |
| 1417 | 1417 | return -ENODEV; |
| 1418 | 1418 | } |
| @@ -34,28 +34,32 @@ static struct rapl_if_priv *rapl_msr_priv; · 33 unmodified lines | ||
| 34 | 34 | |
| 35 | 35 | static struct rapl_if_priv rapl_msr_priv_intel = { |
| 36 | 36 | .type = RAPL_IF_MSR, |
| 37 | − .reg_unit = MSR_RAPL_POWER_UNIT, | |
| 38 | − .regs[RAPL_DOMAIN_PACKAGE] = { | |
| 39 | − MSR_PKG_POWER_LIMIT, MSR_PKG_ENERGY_STATUS, MSR_PKG_PERF_STATUS, 0, MSR_PKG_POWER_INFO }, | |
| 40 | − .regs[RAPL_DOMAIN_PP0] = { | |
| 41 | − MSR_PP0_POWER_LIMIT, MSR_PP0_ENERGY_STATUS, 0, MSR_PP0_POLICY, 0 }, | |
| 42 | − .regs[RAPL_DOMAIN_PP1] = { | |
| 43 | − MSR_PP1_POWER_LIMIT, MSR_PP1_ENERGY_STATUS, 0, MSR_PP1_POLICY, 0 }, | |
| 44 | − .regs[RAPL_DOMAIN_DRAM] = { | |
| 45 | − MSR_DRAM_POWER_LIMIT, MSR_DRAM_ENERGY_STATUS, MSR_DRAM_PERF_STATUS, 0, MSR_DRAM_POWER_INFO }, | |
| 46 | − .regs[RAPL_DOMAIN_PLATFORM] = { | |
| 47 | − MSR_PLATFORM_POWER_LIMIT, MSR_PLATFORM_ENERGY_STATUS, 0, 0, 0}, | |
| 37 | + .reg_unit.msr = MSR_RAPL_POWER_UNIT, | |
| 38 | + .regs[RAPL_DOMAIN_PACKAGE][RAPL_DOMAIN_REG_LIMIT].msr = MSR_PKG_POWER_LIMIT, | |
| 39 | + .regs[RAPL_DOMAIN_PACKAGE][RAPL_DOMAIN_REG_STATUS].msr = MSR_PKG_ENERGY_STATUS, | |
| 40 | + .regs[RAPL_DOMAIN_PACKAGE][RAPL_DOMAIN_REG_PERF].msr = MSR_PKG_PERF_STATUS, | |
| 41 | + .regs[RAPL_DOMAIN_PACKAGE][RAPL_DOMAIN_REG_INFO].msr = MSR_PKG_POWER_INFO, | |
| 42 | + .regs[RAPL_DOMAIN_PP0][RAPL_DOMAIN_REG_LIMIT].msr = MSR_PP0_POWER_LIMIT, | |
| 43 | + .regs[RAPL_DOMAIN_PP0][RAPL_DOMAIN_REG_STATUS].msr = MSR_PP0_ENERGY_STATUS, | |
| 44 | + .regs[RAPL_DOMAIN_PP0][RAPL_DOMAIN_REG_POLICY].msr = MSR_PP0_POLICY, | |
| 45 | + .regs[RAPL_DOMAIN_PP1][RAPL_DOMAIN_REG_LIMIT].msr = MSR_PP1_POWER_LIMIT, | |
| 46 | + .regs[RAPL_DOMAIN_PP1][RAPL_DOMAIN_REG_STATUS].msr = MSR_PP1_ENERGY_STATUS, | |
| 47 | + .regs[RAPL_DOMAIN_PP1][RAPL_DOMAIN_REG_POLICY].msr = MSR_PP1_POLICY, | |
| 48 | + .regs[RAPL_DOMAIN_DRAM][RAPL_DOMAIN_REG_LIMIT].msr = MSR_DRAM_POWER_LIMIT, | |
| 49 | + .regs[RAPL_DOMAIN_DRAM][RAPL_DOMAIN_REG_STATUS].msr = MSR_DRAM_ENERGY_STATUS, | |
| 50 | + .regs[RAPL_DOMAIN_DRAM][RAPL_DOMAIN_REG_PERF].msr = MSR_DRAM_PERF_STATUS, | |
| 51 | + .regs[RAPL_DOMAIN_DRAM][RAPL_DOMAIN_REG_INFO].msr = MSR_DRAM_POWER_INFO, | |
| 52 | + .regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_LIMIT].msr = MSR_PLATFORM_POWER_LIMIT, | |
| 53 | + .regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_STATUS].msr = MSR_PLATFORM_ENERGY_STATUS, | |
| 48 | 54 | .limits[RAPL_DOMAIN_PACKAGE] = BIT(POWER_LIMIT2), |
| 49 | 55 | .limits[RAPL_DOMAIN_PLATFORM] = BIT(POWER_LIMIT2), |
| 50 | 56 | }; |
| 51 | 57 | |
| 52 | 58 | static struct rapl_if_priv rapl_msr_priv_amd = { |
| 53 | 59 | .type = RAPL_IF_MSR, |
| 54 | − .reg_unit = MSR_AMD_RAPL_POWER_UNIT, | |
| 55 | − .regs[RAPL_DOMAIN_PACKAGE] = { | |
| 56 | − 0, MSR_AMD_PKG_ENERGY_STATUS, 0, 0, 0 }, | |
| 57 | − .regs[RAPL_DOMAIN_PP0] = { | |
| 58 | − 0, MSR_AMD_CORE_ENERGY_STATUS, 0, 0, 0 }, | |
| 60 | + .reg_unit.msr = MSR_AMD_RAPL_POWER_UNIT, | |
| 61 | + .regs[RAPL_DOMAIN_PACKAGE][RAPL_DOMAIN_REG_STATUS].msr = MSR_AMD_PKG_ENERGY_STATUS, | |
| 62 | + .regs[RAPL_DOMAIN_PP0][RAPL_DOMAIN_REG_STATUS].msr = MSR_AMD_CORE_ENERGY_STATUS, | |
| 59 | 63 | }; |
| 60 | 64 | |
43 more lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 180 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 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 15 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 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 59 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 23 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 29 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 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 108 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 8 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 90 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 22 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 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 16 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 11 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 15 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 20 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 12 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 36 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 138 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 40 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 48 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 10 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 9 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 41 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 155 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 45 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 21 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 18 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 17 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 15 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 119 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 18 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 17 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 17 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 16 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 22 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 9 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 99 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 19 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 8 lines aren’t shown here.
This diff is large: its 18 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 21 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 173 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 167 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 12 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 157 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 9 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 9 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 22 lines aren’t shown here.
This diff is large: its 22 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 38 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 42 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 23 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 7 lines aren’t shown here.
This diff is large: its 31 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 10 lines aren’t shown here.
This diff is large: its 50 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 15 lines aren’t shown here.
This diff is large: its 192 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 35 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 19 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 14 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 14 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 375 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 97 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 11 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 42 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 33 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 72 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 19 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 23 lines aren’t shown here.
This diff is large: its 25 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 107 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 61 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 13 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 262 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 8 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 13 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 236 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 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 18 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 9 lines aren’t shown here.
This diff is large: its 61 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 12 lines aren’t shown here.
This diff is large: its 187 lines aren’t shown here.
This diff is large: its 24 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 9 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 21 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 42 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 30 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 86 lines aren’t shown here.
This diff is large: its 498 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 176 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 274 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 96 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 77 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 43 lines aren’t shown here.
This diff is large: its 107 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 61 lines aren’t shown here.
This diff is large: its 38 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 116 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 54 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 17 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 7 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 69 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 31 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 16 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 69 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 17 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 10 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 117 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 18 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 125 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 24 lines aren’t shown here.
This diff is large: its 12 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 95 lines aren’t shown here.
This diff is large: its 27 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 13 lines aren’t shown here.
This diff is large: its 109 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 211 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.
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 9 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 33 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 7 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.