From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932164AbbJMU61 (ORCPT ); Tue, 13 Oct 2015 16:58:27 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:59910 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752721AbbJMU6Q (ORCPT ); Tue, 13 Oct 2015 16:58:16 -0400 Message-ID: <1444769883.31451.1.camel@decadent.org.uk> Subject: Linux 3.2.72 From: Ben Hutchings To: linux-kernel@vger.kernel.org, Andrew Morton , torvalds@linux-foundation.org, Jiri Slaby , stable@vger.kernel.org Cc: lwn@lwn.net Date: Tue, 13 Oct 2015 21:58:03 +0100 Content-Type: multipart/signed; micalg="pgp-sha512"; protocol="application/pgp-signature"; boundary="=-TmS+nNz1jtzwiEHCe3Mc" X-Mailer: Evolution 3.18.0-2 Mime-Version: 1.0 X-SA-Exim-Connect-IP: 192.168.4.247 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --=-TmS+nNz1jtzwiEHCe3Mc Content-Type: multipart/mixed; boundary="=-/MQt7REM5T0IIpl/L0xm" --=-/MQt7REM5T0IIpl/L0xm Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: base64 SSdtIGFubm91bmNpbmcgdGhlIHJlbGVhc2Ugb2YgdGhlIDMuMi43MiBrZXJuZWwuCgpBbGwgdXNl cnMgb2YgdGhlIDMuMiBrZXJuZWwgc2VyaWVzIHNob3VsZCB1cGdyYWRlLgoKVGhlIHVwZGF0ZWQg My4yLnkgZ2l0IHRyZWUgY2FuIGJlIGZvdW5kIGF0OgrCoMKgwqDCoMKgwqDCoMKgaHR0cHM6Ly9n aXQua2VybmVsLm9yZy9wdWIvc2NtL2xpbnV4L2tlcm5lbC9naXQvc3RhYmxlL2xpbnV4LXN0YWJs ZS5naXQgbGludXgtMy4yLnkKYW5kIGNhbiBiZSBicm93c2VkIGF0IHRoZSBub3JtYWwga2VybmVs Lm9yZyBnaXQgd2ViIGJyb3dzZXI6CsKgwqDCoMKgwqDCoMKgwqBodHRwczovL2dpdC5rZXJuZWwu b3JnLz9wPWxpbnV4L2tlcm5lbC9naXQvc3RhYmxlL2xpbnV4LXN0YWJsZS5naXQKClRoZSBkaWZm IGZyb20gMy4yLjcxIGlzIGF0dGFjaGVkIHRvIHRoaXMgbWVzc2FnZS4KCkJlbi4KCi0tLS0tLS0t LS0tLQoKwqBNYWtlZmlsZcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqAyICstCsKgYXJjaC9h cm0vTWFrZWZpbGXCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqB8wqDCoMKgOCArCsKgYXJjaC9hcm0va2VybmVsL3NpZ25hbC5jwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgMTkgKy0KwqBhcmNo L21pcHMvaW5jbHVkZS9hc20vcGd0YWJsZS5owqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqB8wqDCoDMxICsrKwrCoGFyY2gvbWlwcy9rZXJuZWwvbWlwcy1tdC1mcGFmZi5jwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDUgKy0KwqBhcmNoL3BhcmlzYy9rZXJuZWwvaXJx LmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDgg Ky0KwqBhcmNoL3Bvd2VycGMvcGxhdGZvcm1zL3Bvd2VybnYvcGNpLmPCoMKgwqDCoMKgwqDCoMKg wqDCoMKgfMKgwqDCoDQgKy0KwqBhcmNoL3Bvd2VycGMvc3lzZGV2L2ZzbF9tc2kuY8KgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqA1ICstCsKgYXJjaC9wb3dlcnBjL3N5 c2Rldi9tcGljX3Bhc2VtaV9tc2kuY8KgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDUgKy0KwqBh cmNoL3Bvd2VycGMvc3lzZGV2L21waWNfdTNtc2kuY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoHzCoMKgwqA1ICstCsKgYXJjaC9wb3dlcnBjL3N5c2Rldi9wcGM0eHhfbXNpLmPCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgNSArLQrCoGFyY2gvczM5MC9rZXJuZWwvY29t cGF0X3NpZ25hbC5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqAzMCArKy0KwqBh cmNoL3NwYXJjL2luY2x1ZGUvYXNtL3Zpc2FzbS5owqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqB8wqDCoDE0ICstCsKgYXJjaC9zcGFyYy9saWIvVklTc2F2ZS5TwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgNjcgKy0tLS0tLQrCoGFyY2gveDg2 L2NyeXB0by9naGFzaC1jbG11bG5pLWludGVsX2dsdWUuY8KgwqDCoMKgwqB8wqDCoMKgMSArCsKg YXJjaC94ODYvaW5jbHVkZS9hc20vZGVzYy5owqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoHzCoMKgMTUgLS0KwqBhcmNoL3g4Ni9pbmNsdWRlL2FzbS9tbXUuaMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqAzICstCsKgYXJjaC94ODYv aW5jbHVkZS9hc20vbW11X2NvbnRleHQuaMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqA0 OSArKysrLQrCoGFyY2gveDg2L2luY2x1ZGUvYXNtL21zci1pbmRleC5owqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgfMKgwqDCoDEgKwrCoGFyY2gveDg2L2tlcm5lbC9jcHUvY29tbW9uLmPC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqA0ICstCsKgYXJjaC94 ODYva2VybmVsL2VudHJ5XzY0LlPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqB8wqDCoDExICsKwqBhcmNoL3g4Ni9rZXJuZWwvbGR0LmPCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfCAyNjcgKysrKysrKysrKysrKystLS0t LS0tLS0tLQrCoGFyY2gveDg2L2tlcm5lbC9wYXJhdmlydC5jwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqAxNiArLQrCoGFyY2gveDg2L2tlcm5lbC9wcm9jZXNz XzY0LmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqA0ICstCsKg YXJjaC94ODYva2VybmVsL3N0ZXAuY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgfMKgwqDCoDggKy0KwqBhcmNoL3g4Ni9rZXJuZWwvdHNjLmPCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqAxNyArLQrC oGFyY2gveDg2L2t2bS9tbXUuY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoDQ1IC0tLS0tCsKgYXJjaC94ODYva3ZtL3g4Ni5jwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzC oMKgwqAyICsKwqBhcmNoL3g4Ni9tYXRoLWVtdS9mcHVfZW50cnkuY8KgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqAzICstCsKgYXJjaC94ODYvbWF0aC1lbXUvZnB1X3N5 c3RlbS5owqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgMjEgKy0KwqBhcmNo L3g4Ni9tYXRoLWVtdS9nZXRfYWRkcmVzcy5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqB8wqDCoMKgMyArLQrCoGFyY2gveDg2L3Bvd2VyL2NwdS5jwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDMgKy0KwqBkcml2ZXJzL2F1 eGRpc3BsYXkva3MwMTA4LmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg fMKgwqDCoDEgKwrCoGRyaXZlcnMvYmFzZS9kZXZyZXMuY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgNCArLQrCoGRyaXZlcnMvYmFzZS9w bGF0Zm9ybS5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg fMKgwqDCoDggKy0KwqBkcml2ZXJzL2NyeXB0by9peHA0eHhfY3J5cHRvLmPCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDEgLQrCoGRyaXZlcnMvZ3B1L2RybS9pOTE1L2k5 MTVfZ2VtX2V4ZWNidWZmZXIuY8KgwqDCoMKgwqB8wqDCoMKgMiArLQrCoGRyaXZlcnMvZ3B1L2Ry bS9yYWRlb24vcmFkZW9uX2NvbWJpb3MuY8KgwqDCoMKgwqDCoMKgwqB8wqDCoMKgOCArCsKgZHJp dmVycy9ncHUvZHJtL3JhZGVvbi9yYWRlb25fY29ubmVjdG9ycy5jwqDCoMKgwqDCoHzCoMKgwqA1 ICsKwqBkcml2ZXJzL2luZmluaWJhbmQvY29yZS91dmVyYnMuaMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoHzCoMKgwqAzICstCsKgZHJpdmVycy9pbmZpbmliYW5kL2NvcmUvdXZlcmJzX2Nt ZC5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgMTAgKy0KwqBkcml2ZXJzL2luZmluaWJhbmQv Y29yZS91dmVyYnNfbWFpbi5jwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoDQzICsrLS0KwqBkcml2 ZXJzL2luZmluaWJhbmQvaHcvbWx4NC9haC5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqB8wqDCoMKgNiArLQrCoGRyaXZlcnMvaW5maW5pYmFuZC9ody9xaWIvcWliLmjCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqA0ICsKwqBkcml2ZXJzL2luZmluaWJhbmQvaHcv cWliL3FpYl9rZXlzLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDQgKwrCoGRyaXZlcnMv aW5maW5pYmFuZC9ody9xaWIvcWliX3ZlcmJzLmPCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgMTQg Ky0KwqBkcml2ZXJzL2luZmluaWJhbmQvaHcvcWliL3FpYl92ZXJicy5owqDCoMKgwqDCoMKgwqDC oMKgwqB8wqDCoMKgMiArCsKgZHJpdmVycy9pbnB1dC9ldmRldi5jwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgMTMgKy0KwqBkcml2ZXJzL21h Y2ludG9zaC93aW5kZmFybV9jb3JlLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDC oDIgKy0KwqBkcml2ZXJzL21kL21kLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDQgKy0KwqBkcml2ZXJzL21kL3Bl cnNpc3RlbnQtZGF0YS9kbS1idHJlZS1pbnRlcm5hbC5oIHzCoMKgwqA2ICsKwqBkcml2ZXJzL21k L3BlcnNpc3RlbnQtZGF0YS9kbS1idHJlZS1yZW1vdmUuY8KgwqDCoHzCoMKgMTIgKy0KwqBkcml2 ZXJzL21kL3BlcnNpc3RlbnQtZGF0YS9kbS1idHJlZS1zcGluZS5jwqDCoMKgwqB8wqDCoDM3ICsr KysKwqBkcml2ZXJzL21kL3BlcnNpc3RlbnQtZGF0YS9kbS1idHJlZS5jwqDCoMKgwqDCoMKgwqDC oMKgwqB8wqDCoMKgNyArLQrCoGRyaXZlcnMvbWQvcmFpZDEuY8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoDEwICstCsKgZHJpdmVy cy9tZWRpYS9yYy9yYy1tYWluLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqB8wqDCoMKgMyAtCsKgZHJpdmVycy9uZXQvYm9uZGluZy9ib25kX21haW4uY8KgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqAyMCArKwrCoGRyaXZlcnMvbmV0L3ZpcnRpb19u ZXQuY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKg NCArLQrCoGRyaXZlcnMvbmV0L3dpcmVsZXNzL3J0bHdpZmkvcnRsODE5MmN1L3N3LmPCoMKgwqDC oHzCoMKgwqAyICsKwqBkcml2ZXJzL29mL2FkZHJlc3MuY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqA2ICstCsKgZHJpdmVycy9wY2kv YWNjZXNzLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqB8wqDCoDYxICsrKysrLQrCoGRyaXZlcnMvcGNpL3F1aXJrcy5jwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqAxNCArLQrCoGRyaXZl cnMvc2NzaS9saWJmYy9mY19mY3AuY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqB8wqDCoDE5ICstCsKgZHJpdmVycy9zY3NpL2xpYmlzY3NpLmPCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoDI1ICstLQrCoGRyaXZlcnMvc3Bp L3NwaS1weGEyeHguY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqB8wqDCoMKgNCArCsKgZHJpdmVycy90YXJnZXQvaXNjc2kvaXNjc2lfdGFyZ2V0LmPCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgMiArLQrCoGRyaXZlcnMvdGFyZ2V0L3RhcmdldF9jb3Jl X2RldmljZS5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqAxMyArLQrCoGRyaXZlcnMvdHR5 L3NlcmlhbC84MjUwX3BucC5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKg wqDCoDYgKwrCoGRyaXZlcnMvdXNiL2NvcmUvY29uZmlnLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqA1ICstCsKgZHJpdmVycy91c2IvZ2FkZ2V0L202 NjU5Mi11ZGMuY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDIgKy0KwqBk cml2ZXJzL3VzYi9ob3N0L2VoY2ktZnNsLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgfMKgwqDCoDQgKwrCoGRyaXZlcnMvdXNiL2hvc3QvZWhjaS1odWIuY8KgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgNyArCsKgZHJpdmVycy91c2Iv aG9zdC9laGNpLXN5c2ZzLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDC oDE0ICstCsKgZHJpdmVycy91c2IvaG9zdC9laGNpLmjCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoDEyICsrCsKgZHJpdmVycy91c2IvaG9zdC9mc2wt bXBoLWRyLW9mLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgNCArCsKgZHJp dmVycy91c2IvaG9zdC94aGNpLW1lbS5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoHzCoMKgwqA2ICstCsKgZHJpdmVycy91c2IvaG9zdC94aGNpLXJpbmcuY8KgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqAxNSArLQrCoGRyaXZlcnMvdXNiL2hv c3QveGhjaS5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg fMKgwqDCoDMgKy0KwqBkcml2ZXJzL3VzYi9zZXJpYWwvZnRkaV9zaW8uY8KgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqA0ICsKwqBkcml2ZXJzL3VzYi9zZXJpYWwvZnRk aV9zaW9faWRzLmjCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDggKwrCoGRyaXZl cnMvdXNiL3NlcmlhbC9vcHRpb24uY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqB8wqDCoDI0ICsrKwrCoGRyaXZlcnMvdXNiL3NlcmlhbC9zaWVycmEuY8KgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgMSArCsKgZHJpdmVycy91c2Ivc2Vy aWFsL3doaXRlaGVhdC5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgMzEg KysrCsKgZHJpdmVycy94ZW4vZ250ZGV2LmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoDM0ICsrLS0KwqBmcy9idHJmcy9leHRlbnRfaW8u Y8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzC oMKgNjcgKysrKysrLQrCoGZzL2J0cmZzL2lub2RlLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqAzICstCsKgZnMvY2Vw aC9zdXBlci5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoHzCoMKgwqA4ICstCsKgZnMvY2lmcy9jaWZzZW5jcnlwdC5jwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgNTIgKysr Ky0KwqBmcy9jaWZzL2NpZnNmcy5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgNCArLQrCoGZzL2RjYWNoZS5jwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgfMKgwqAxMCArCsKgZnMvZWNyeXB0ZnMvZGVudHJ5LmPCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoDMyICstLQrCoGZzL2V4 dDQvc3VwZXIuY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgNCArLQrCoGZzL2dmczIvc3VwZXIuY8KgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDC oMKgNiArLQrCoGZzL2hmcy9ibm9kZS5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDkgKy0KwqBmcy9oZnMvYnJl Yy5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqB8wqDCoDIwICstCsKgZnMvaGZzL3N1cGVyLmPCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKg NCArLQrCoGZzL2hmc3BsdXMvYm5vZGUuY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgMyAtCsKgZnMvaGZzcGx1cy9vcHRpb25z LmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8 wqDCoMKgNCArLQrCoGZzL2hvc3Rmcy9ob3N0ZnNfa2Vybi5jwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDIgKy0KwqBmcy9qYmQyL2NoZWNrcG9p bnQuY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oHzCoMKgMzkgKysrLQrCoGZzL2piZDIvY29tbWl0LmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqA0ICstCsKgZnMvamJk Mi9qb3VybmFsLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqB8wqDCoDM0ICsrKy0KwqBmcy9uYW1laS5jwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8 wqDCoDI5ICsrLQrCoGZzL25mcy9uZnM0cHJvYy5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDIgKy0KwqBmcy9vY2ZzMi9k bG0vZGxtbWFzdGVyLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgfMKgwqDCoDcgKy0KwqBmcy9vY2ZzMi9kbG0vZGxtcmVjb3ZlcnkuY8KgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqA2ICstCsKgZnMvb2NmczIvZGxtZ2x1 ZS5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoHzCoMKgMTAgKy0KwqBmcy9vY2ZzMi9zdXBlci5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgNCArLQrCoGZzL3By b2MvdGFza19tbXUuY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqB8wqDCoDI4ICsrLQrCoGZzL3hmcy94ZnNfYW9wcy5jwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDMg Ky0KwqBmcy94ZnMveGZzX2F0dHJfbGVhZi5owqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoDExICstCsKgZnMveGZzL3hmc19zdXBlci5jwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKg wqA0ICstCsKgaW5jbHVkZS9saW51eC9mc2xfZGV2aWNlcy5owqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqAxICsKwqBpbmNsdWRlL2xpbnV4L2piZDIuaMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqAz ICstCsKgaW5jbHVkZS9saW51eC9wY2kuaMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDIgKwrCoGluY2x1ZGUvbGludXgvc2VxX2Zp bGUuaMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoDM1 ICsrKysKwqBpbmNsdWRlL25ldC9pcC5owqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgMSArCsKgaW5jbHVkZS9uZXQvaXA2 X2ZpYi5owqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oHzCoMKgwqAyICstCsKgaXBjL21zZy5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgMTggKy0KwqBp cGMvc2VtLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqA0MCArKy0tCsKgaXBjL3NobS5jwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoHzCoMKgMTMgKy0KwqBpcGMvdXRpbC5jwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDC oMKgOCArLQrCoGtlcm5lbC9jZ3JvdXAuY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgNyArLQrCoGtlcm5lbC9ldmVu dHMvY29yZS5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgfMKgwqAxMiArLQrCoG5ldC9LY29uZmlnwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDIgKy0K wqBuZXQvY29yZS9kYXRhZ3JhbS5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoDQ2ICsrKystCsKgbmV0L2NvcmUvZmliX3J1bGVzLmPC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDC oDE0ICstCsKgbmV0L2NvcmUvcGt0Z2VuLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgNCArLQrCoG5ldC9pcHY0L2RhdGFn cmFtLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoHzCoMKgMTYgKy0KwqBuZXQvaXB2Ni9NYWtlZmlsZcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqAzICstCsKgbmV0L2lw djYvYWRkcmNvbmYuY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgfMKgwqAxNyArLQrCoG5ldC9pcHY2L2RhdGFncmFtLmPCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgMjAgKy0KwqBu ZXQvaXB2Ni9pcDZfZmliLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgfMKgwqAyNSArLS0KwqBuZXQvaXB2Ni9pcDZtci5jwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDC oMKgMiArLQrCoG5ldC9pcHY2L25kaXNjLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqA0ICstCsKgbmV0L2lwdjYvcm91 dGUuY8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgfMKgwqDCoDggKy0KwqBuZXQva2V5L2FmX2tleS5jwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoDQ2ICsrLS0t CsKgbmV0L21hYzgwMjExL3R4LmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgMyAtCsKgbmV0L3Jkcy9jb25uZWN0aW9uLmPC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDC oMKgNiArCsKgbmV0L3Jkcy9pbmZvLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgMiArLQrCoG5ldC9zY3RwL291 dHB1dC5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgfMKgwqDCoDQgKy0KwqBuZXQvc2N0cC9zbV9zaWRlZWZmZWN0LmPCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDIgKy0KwqBuZXQvc3Vu cnBjL3hwcnRzb2NrLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgfMKgwqDCoDIgKwrCoG5ldC90aXBjL3NvY2tldC5jwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDCoDIgKwrCoHNj cmlwdHMva2NvbmZpZy9zdHJlYW1saW5lX2NvbmZpZy5wbMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8 wqDCoMKgMiArLQrCoHNlY3VyaXR5L3NlbGludXgvaG9va3MuY8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgMiArLQrCoHNvdW5kL2FybS9LY29uZmln wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgfMKgwqAxNSArLQrCoHNvdW5kL3NvYy9weGEvS2NvbmZpZ8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgMiAtCsKgdG9vbHMvcGVyZi9N YWtlZmlsZcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgfMKgwqDCoDQgKy0KwqB0b29scy9wZXJmL3V0aWwvaGVhZGVyLmPCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqAyMiArLQrCoDE1MCBmaWxlcyBj aGFuZ2VkLCAxMzg1IGluc2VydGlvbnMoKyksIDY4MSBkZWxldGlvbnMoLSkKCkFkcmllbiBTY2hp bGRrbmVjaHQgKDEpOgrCoMKgwqDCoMKgwqBydGx3aWZpOiBydGw4MTkyY3U6IEFkZCBuZXcgZGV2 aWNlIElECgpBbGV4ZWkgUG90YXNobmlrICgxKToKwqDCoMKgwqDCoMKgdGFyZ2V0L2lzY3NpOiBG aXggZG91YmxlIGZyZWUgb2YgYSBUVVIgZm9sbG93ZWQgYnkgYSBzb2xpY2l0ZWQgTk9QT1VUCgpB bmRyZXkgUnlhYmluaW4gKDEpOgrCoMKgwqDCoMKgwqBjcnlwdG86IGdoYXNoLWNsbXVsbmk6IHNw ZWNpZnkgY29udGV4dCBzaXplIGZvciBnaGFzaCBhc3luYyBhbGdvcml0aG0KCkFuZHkgTHV0b21p cnNraSAoMyk6CsKgwqDCoMKgwqDCoHg4Ni9sZHQ6IE1ha2UgbW9kaWZ5X2xkdCBzeW5jaHJvbm91 cwrCoMKgwqDCoMKgwqB4ODYvbGR0OiBGdXJ0aGVyIGZpeCBGUFUgZW11bGF0aW9uCsKgwqDCoMKg wqDCoHg4Ni9wYXJhdmlydDogUmVwbGFjZSB0aGUgcGFyYXZpcnQgbm9wIHdpdGggYSBib25hIGZp ZGUgZW1wdHkgZnVuY3Rpb24KCkFyZCBCaWVzaGV1dmVsICgxKToKwqDCoMKgwqDCoMKgQVJNOiA4 NDI5LzE6IGRpc2FibGUgR0NDIFNSQSBvcHRpbWl6YXRpb24KCkFybmFsZG8gQ2FydmFsaG8gZGUg TWVsbyAoMSk6CsKgwqDCoMKgwqDCoHBlcmYgaGVhZGVyOiBGaXh1cCByZWFkaW5nIG9mIEhFQURF Ul9OUkNQVVMgZmVhdHVyZQoKQmFydCBWYW4gQXNzY2hlICgxKToKwqDCoMKgwqDCoMKgbGliZmM6 IEZpeCBmY19mY3BfY2xlYW51cF9lYWNoX2NtZCgpCgpCZW4gSHV0Y2hpbmdzICgzKToKwqDCoMKg wqDCoMKgaXB2NjogRml4IGJ1aWxkIGZhaWx1cmUgd2hlbiBDT05GSUdfSU5FVCBkaXNhYmxlZArC oMKgwqDCoMKgwqBSZXZlcnQgInNjdHA6IEZpeCByYWNlIGJldHdlZW4gT09UQiByZXNwb25jZSBh bmQgcm91dGUgcmVtb3ZhbCIKwqDCoMKgwqDCoMKgTGludXggMy4yLjcyCgpCZW5qYW1pbiBSYW5k YXp6byAoMSk6CsKgwqDCoMKgwqDCoG1kOiB1c2Uga3phbGxvYygpIHdoZW4gYml0bWFwIGlzIGRp c2FibGVkCgpCam9ybiBIZWxnYWFzICgxKToKwqDCoMKgwqDCoMKgUENJOiBGaXggVEk4MTZYIGNs YXNzIGNvZGUgcXVpcmsKCkJvYiBDb3BlbGFuZCAoMSk6CsKgwqDCoMKgwqDCoG1hYzgwMjExOiBl bmFibGUgYXNzb2MgY2hlY2sgZm9yIG1lc2ggaW50ZXJmYWNlcwoKQ2hyaXMgV2lsc29uICgxKToK wqDCoMKgwqDCoMKgZHJtL2k5MTU6IEFsd2F5cyBtYXJrIHRoZSBvYmplY3QgYXMgZGlydHkgd2hl biB1c2VkIGJ5IHRoZSBHUFUKCkNocmlzdG9waCBIZWxsd2lnICgxKToKwqDCoMKgwqDCoMKgSUIv dXZlcmJzOiByZWplY3QgaW52YWxpZCBvciB1bmtub3duIG9wY29kZXMKCkRhbiBDYXJwZW50ZXIg KDIpOgrCoMKgwqDCoMKgwqByZHM6IGZpeCBhbiBpbnRlZ2VyIG92ZXJmbG93IHRlc3QgaW4gcmRz X2luZm9fZ2V0c29ja29wdCgpCsKgwqDCoMKgwqDCoHVzYjogZ2FkZ2V0OiBtNjY1OTItdWRjOiBm b3JldmVyIGxvb3AgaW4gc2V0X2ZlYXR1cmUoKQoKRGF2aWQgQWhlcm4gKDEpOgrCoMKgwqDCoMKg wqBuZXQ6IEZpeCBSQ1Ugc3BsYXQgaW4gYWZfa2V5CgpEYXZpZCBEYW5leSAoMik6CsKgwqDCoMKg wqDCoE1JUFM6IE1ha2Ugc2V0X3B0ZSgpIFNNUCBzYWZlLgrCoMKgwqDCoMKgwqBvZi9hZGRyZXNz OiBEb24ndCBsb29wIGZvcmV2ZXIgaW4gb2ZfZmluZF9tYXRjaGluZ19ub2RlX2J5X2FkZHJlc3Mo KS4KCkRhdmlkIEjDpHJkZW1hbiAoMSk6CsKgwqDCoMKgwqDCoHJjLWNvcmU6IGZpeCByZW1vdmUg dWV2ZW50IGdlbmVyYXRpb24KCkRhdmlkIEplZmZlcnkgKDEpOgrCoMKgwqDCoMKgwqB4ZnM6IHJl dHVybiBlcnJvcnMgZnJvbSBwYXJ0aWFsIEkvTyBmYWlsdXJlcyB0byBmaWxlcwoKRGF2aWQgUy4g TWlsbGVyICgxKToKwqDCoMKgwqDCoMKgc3BhcmM2NDogRml4IHVzZXJzcGFjZSBGUFUgcmVnaXN0 ZXIgY29ycnVwdGlvbnMuCgpEYXZpZCBWcmFiZWwgKDEpOgrCoMKgwqDCoMKgwqB4ZW4vZ250ZGV2 OiBjb252ZXJ0IHByaXYtPmxvY2sgdG8gYSBtdXRleAoKRGF2aWQgV29vZGhvdXNlICgxKToKwqDC oMKgwqDCoMKgeDg2L3BsYXRmb3JtOiBGaXggR2VvZGUgTFggdGltZWtlZXBpbmcgaW4gdGhlIGdl bmVyaWMgeDg2IGJ1aWxkCgpEaXJrIEJlaG1lICgxKToKwqDCoMKgwqDCoMKgVVNCOiBzaWVycmE6 IGFkZCAxMTk5OjY4QUIgZGV2aWNlIElECgpFcmljIER1bWF6ZXQgKDEpOgrCoMKgwqDCoMKgwqBp cHY2OiBsb2NrIHNvY2tldCBpbiBpcDZfZGF0YWdyYW1fY29ubmVjdCgpCgpFcmljIFcuIEJpZWRl cm1hbiAoMik6CsKgwqDCoMKgwqDCoGRjYWNoZTogSGFuZGxlIGVzY2FwZWQgcGF0aHMgaW4gcHJl cGVuZF9wYXRoCsKgwqDCoMKgwqDCoHZmczogVGVzdCBmb3IgYW5kIGhhbmRsZSBwYXRocyB0aGF0 IGFyZSB1bnJlYWNoYWJsZSBmcm9tIHRoZWlyIG1udF9yb290CgpGZWxpeCBGaWV0a2F1ICgxKToK wqDCoMKgwqDCoMKgTUlQUzogRml4IHNjaGVkX2dldGFmZmluaXR5IHdpdGggTVQgRlBBRkYgZW5h YmxlZAoKRmlsaXBlIE1hbmFuYSAoMSk6CsKgwqDCoMKgwqDCoEJ0cmZzOiBmaXggcmVhZCBjb3Jy dXB0aW9uIG9mIGNvbXByZXNzZWQgYW5kIHNoYXJlZCBleHRlbnRzCgpHcmFudCBMaWtlbHkgKDEp OgrCoMKgwqDCoMKgwqBkcml2ZXJjb3JlOiBGaXggdW5yZWdpc3RyYXRpb24gcGF0aCBvZiBwbGF0 Zm9ybSBkZXZpY2VzCgpIZWxnZSBEZWxsZXIgKDEpOgrCoMKgwqDCoMKgwqBwYXJpc2M6IEZpbHRl ciBvdXQgc3B1cmlvdXMgaW50ZXJydXB0cyBpbiBQQS1SSVNDIGlycSBoYW5kbGVyCgpIZXJiZXJ0 IFh1ICg0KToKwqDCoMKgwqDCoMKgY3J5cHRvOiBpeHA0eHggLSBSZW1vdmUgYm9ndXMgQlVHX09O IG9uIHNjYXR0ZXJlZCBkc3QgYnVmZmVyCsKgwqDCoMKgwqDCoG5ldDogQ2xvbmUgc2tiIGJlZm9y ZSBzZXR0aW5nIHBlZWtlZCBmbGFnCsKgwqDCoMKgwqDCoG5ldDogRml4IHNrYl9zZXRfcGVla2Vk IHVzZS1hZnRlci1mcmVlIGJ1ZwrCoMKgwqDCoMKgwqBuZXQ6IEZpeCBza2IgY3N1bSByYWNlcyB3 aGVuIHBlZWtpbmcKCkhlcnRvbiBSLiBLcnplc2luc2tpICgxKToKwqDCoMKgwqDCoMKgaXBjLHNl bTogZml4IHVzZSBhZnRlciBmcmVlIG9uIElQQ19STUlEIGFmdGVyIGEgdGFzayB1c2luZyBzYW1l IHNlbWFwaG9yZSBzZXQgZXhpdHMKCkhpbi1UYWsgTGV1bmcgKDIpOgrCoMKgwqDCoMKgwqBoZnMs aGZzcGx1czogY2FjaGUgcGFnZXMgY29ycmVjdGx5IGJldHdlZW4gYm5vZGVfY3JlYXRlIGFuZCBi bm9kZV9mcmVlCsKgwqDCoMKgwqDCoGhmczogZml4IEItdHJlZSBjb3JydXB0aW9uIGFmdGVyIGlu c2VydGlvbiBhdCBwb3NpdGlvbiAwCgpKYW4gS2FyYSAoMyk6CsKgwqDCoMKgwqDCoGpiZDI6IHBy b3RlY3QgYWxsIGxvZyB0YWlsIHVwZGF0ZXMgd2l0aCBqX2NoZWNrcG9pbnRfbXV0ZXgKwqDCoMKg wqDCoMKgeGZzOiBGaXggeGZzX2F0dHJfbGVhZmJsb2NrIGRlZmluaXRpb24KwqDCoMKgwqDCoMKg amJkMjogYXZvaWQgaW5maW5pdGUgbG9vcCB3aGVuIGRlc3Ryb3lpbmcgYWJvcnRlZCBqb3VybmFs CgpKYXNvbiBXYW5nICgxKToKwqDCoMKgwqDCoMKgdmlydGlvLW5ldDogZHJvcCBORVRJRl9GX0ZS QUdMSVNUCgpKZWZmIE1haG9uZXkgKDEpOgrCoMKgwqDCoMKgwqBidHJmczogc2tpcCB3YWl0aW5n IG9uIG9yZGVyZWQgcmFuZ2UgZm9yIHNwZWNpYWwgZmlsZXMKCkplZmZlcnkgTWlsbGVyICgxKToK wqDCoMKgwqDCoMKgQWRkIHJhZGVvbiBzdXNwZW5kL3Jlc3VtZSBxdWlyayBmb3IgSFAgQ29tcGFx IGRjNTc1MC4KCkpvZSBUaG9ybmJlciAoMSk6CsKgwqDCoMKgwqDCoGRtIGJ0cmVlOiBhZGQgcmVm IGNvdW50aW5nIG9wcyBmb3IgdGhlIGxlYXZlcyBvZiB0b3AgbGV2ZWwgYnRyZWVzCgpKb2hhbiBI b3ZvbGQgKDEpOgrCoMKgwqDCoMKgwqBVU0I6IHdoaXRlaGVhdDogZml4IHBvdGVudGlhbCBudWxs LWRlcmVmIGF0IHByb2JlCgpKb2huIFNvbmkgSm9zZSAoMSk6CsKgwqDCoMKgwqDCoGxpYmlzY3Np OiBGaXggaG9zdCBidXN5IGJsb2NraW5nIGR1cmluZyBjb25uZWN0aW9uIHRlYXJkb3duCgpKb3Nl cGggUWkgKDIpOgrCoMKgwqDCoMKgwqBvY2ZzMjogZml4IEJVRyBpbiBvY2ZzMl9kb3duY29udmVy dF90aHJlYWRfZG9fd29yaygpCsKgwqDCoMKgwqDCoG9jZnMyL2RsbTogZml4IGRlYWRsb2NrIHdo ZW4gZGlzcGF0Y2ggYXNzZXJ0IG1hc3RlcgoKSnVlcmdlbiBHcm9zcyAoMik6CsKgwqDCoMKgwqDC oHg4Ni9sZHQ6IENvcnJlY3QgTERUIGFjY2VzcyBpbiBzaW5nbGUgc3RlcHBpbmcgbG9naWMKwqDC oMKgwqDCoMKgeDg2L2xkdDogQ29ycmVjdCBGUFUgZW11bGF0aW9uIGFjY2VzcyB0byBMRFQKCktl ZXMgQ29vayAoMSk6CsKgwqDCoMKgwqDCoGZzOiBjcmVhdGUgYW5kIHVzZSBzZXFfc2hvd19vcHRp b24gZm9yIGVzY2FwaW5nCgpLaXJpbGwgQS4gU2h1dGVtb3YgKDEpOgrCoMKgwqDCoMKgwqBwZXJm IHRvb2xzOiBGaXggYnVpbGQgd2l0aCBwZXJsIDUuMTgKCktvbnN0YW50aW4gS2hsZWJuaWtvdiAo MSk6CsKgwqDCoMKgwqDCoHBhZ2VtYXA6IGhpZGUgcGh5c2ljYWwgYWRkcmVzc2VzIGZyb20gbm9u LXByaXZpbGVnZWQgdXNlcnMKCkxpbnVzIFRvcnZhbGRzICgxKToKwqDCoMKgwqDCoMKgSW5pdGlh bGl6ZSBtc2cvc2htIElQQyBvYmplY3RzIGJlZm9yZSBkb2luZyBpcGNfYWRkaWQoKQoKTGl1Llpo YW8gKDEpOgrCoMKgwqDCoMKgwqBVU0I6IG9wdGlvbjogYWRkIFpURSBQSURzCgpNYWNpZWogUy4g U3ptaWdpZXJvICgxKToKwqDCoMKgwqDCoMKgc2VyaWFsOiA4MjUwOiBiaW5kIHRvIEFMaSBGYXN0 IEluZnJhcmVkIENvbnRyb2xsZXIgKEFMSTUxMjMpCgpNYW5mcmVkIFNwcmF1bCAoMSk6CsKgwqDC oMKgwqDCoGlwYy9zZW0uYzogZnVsbHkgaW5pdGlhbGl6ZSBzZW1fYXJyYXkgYmVmb3JlIG1ha2lu ZyBpdCB2aXNpYmxlCgpNYXJjZWxvIExlaXRuZXIgKDEpOgrCoMKgwqDCoMKgwqBpcHY2OiBhZGRy Y29uZjogdmFsaWRhdGUgbmV3IE1UVSBiZWZvcmUgYXBwbHlpbmcgaXQKCk1hcmVrIE1hcmN6eWtv d3NraS1Hw7NyZWNraSAoMSk6CsKgwqDCoMKgwqDCoHhlbi9nbnRkZXZ0OiBGaXggcmFjZSBjb25k aXRpb24gaW4gZ250ZGV2X3JlbGVhc2UoKQoKTWFyZWsgVmFzdXQgKDEpOgrCoMKgwqDCoMKgwqBy dGx3aWZpOiBydGw4MTkyY3U6IEFkZCBuZXcgZGV2aWNlIElECgpNYXJrIFJ1c3RhZCAoMik6CsKg wqDCoMKgwqDCoFBDSTogQWRkIGRldl9mbGFncyBiaXQgdG8gYWNjZXNzIFZQRCB0aHJvdWdoIGZ1 bmN0aW9uIDAKwqDCoMKgwqDCoMKgUENJOiBBZGQgVlBEIGZ1bmN0aW9uIDAgcXVpcmsgZm9yIElu dGVsIEV0aGVybmV0IGRldmljZXMKCk1hcnRpbiBTY2h3aWRlZnNreSAoMSk6CsKgwqDCoMKgwqDC oHMzOTAvY29tcGF0OiBjb3JyZWN0IHVjX3NpZ21hc2sgb2YgdGhlIGNvbXBhdCBzaWduYWwgZnJh bWUKCk1hc2FoaXJvIFlhbWFkYSAoMSk6CsKgwqDCoMKgwqDCoGRldnJlczogZml4IGRldnJlc19n ZXQoKQoKTWF0aGlhcyBOeW1hbiAoNCk6CsKgwqDCoMKgwqDCoHhoY2k6IGZpeCBvZmYgYnkgb25l IGVycm9yIGluIFRSQiBETUEgYWRkcmVzcyBib3VuZGFyeSBjaGVjawrCoMKgwqDCoMKgwqB1c2I6 IFVzZSB0aGUgVVNCX1NTX01VTFQoKSBtYWNybyB0byBnZXQgdGhlIGJ1cnN0IG11bHRpcGxpZXIu CsKgwqDCoMKgwqDCoHhoY2k6IGdpdmUgY29tbWFuZCBhYm9ydGlvbiBvbmUgbW9yZSBjaGFuY2Ug YmVmb3JlIGtpbGxpbmcgeGhjaQrCoMKgwqDCoMKgwqB4aGNpOiBjaGFuZ2UgeGhjaSAxLjAgb25s eSByZXN0cmljdGlvbnMgdG8gc3VwcG9ydCB4aGNpIDEuMQoKTWF0dGhpanMgS29vaWptYW4gKDEp OgrCoMKgwqDCoMKgwqBVU0I6IGZ0ZGlfc2lvOiBBZGRlZCBjdXN0b20gUElEIGZvciBDdXN0b21X YXJlIHByb2R1Y3RzCgpNaWNoYWwgS3ViZcSNZWsgKDIpOgrCoMKgwqDCoMKgwqBpcHY2OiBwcmV2 ZW50IGZpYjZfcnVuX2djKCkgY29udGVudGlvbgrCoMKgwqDCoMKgwqBpcHY2OiB1cGRhdGUgaXA2 X3J0X2xhc3RfZ2MgZXZlcnkgdGltZSBHQyBpcyBydW4KCk1pa2UgTWFyY2luaXN6eW4gKDEpOgrC oMKgwqDCoMKgwqBJQi9xaWI6IENoYW5nZSBsa2V5IHRhYmxlIGFsbG9jYXRpb24gdG8gc3VwcG9y dCBtb3JlIE1ScwoKTmVpbEJyb3duICgyKToKwqDCoMKgwqDCoMKgbWQvcmFpZDE6IGV4dGVuZCBz cGlubG9jayB0byBwcm90ZWN0IHJhaWQxX2VuZF9yZWFkX3JlcXVlc3QgYWdhaW5zdCBpbmNvbnNp c3RlbmNpZXMKwqDCoMKgwqDCoMKgTkZTdjQ6IGRvbid0IHNldCBTRVRBVFRSIGZvciBPX1JET05M WXxPX0VYQ0wKCk5pa2hpbCBCYWRvbGEgKDEpOgrCoMKgwqDCoMKgwqBkcml2ZXJzOiB1c2I6IGZz bDogV29ya2Fyb3VuZCBmb3IgVVNCIGVycmF0dW0tQTAwNTI3NQoKTm9hIE9zaGVyb3ZpY2ggKDEp OgrCoMKgwqDCoMKgwqBJQi9tbHg0OiBVc2UgY29ycmVjdCBTTCBvbiBBSCBxdWVyeSB1bmRlciBS b0NFCgpPbGVnIE5lc3Rlcm92ICgxKToKwqDCoMKgwqDCoMKgbmV0OiBwa3RnZW46IGZpeCByYWNl IGJldHdlZW4gcGt0Z2VuX3RocmVhZF93b3JrZXIoKSBhbmQga3RocmVhZF9zdG9wKCkKClBhb2xv IEJvbnppbmkgKDEpOgrCoMKgwqDCoMKgwqBLVk06IHg4NjogdHJhcCBBTUQgTVNScyBmb3IgdGhl IFRTZWcgYmFzZSBhbmQgbWFzawoKUGF1bCBCb2xsZSAoMSk6CsKgwqDCoMKgwqDCoHdpbmRmYXJt OiBkZWNyZW1lbnQgY2xpZW50IGNvdW50IHdoZW4gdW5yZWdpc3RlcmluZwoKUGF1bCBNYWNrZXJy YXMgKDEpOgrCoMKgwqDCoMKgwqBwb3dlcnBjL01TSTogRml4IHJhY2UgY29uZGl0aW9uIGluIHRl YXJpbmcgZG93biBNU0kgaW50ZXJydXB0cwoKUGV0ZXIgQ2hlbiAoMSk6CsKgwqDCoMKgwqDCoHVz YjogaG9zdDogZWhjaS1zeXM6IGRlbGV0ZSB1c2VsZXNzIGJ1c190b19oY2QgY29udmVyc2lvbgoK UGV0ZXIgU2VpZGVyZXIgKDEpOgrCoMKgwqDCoMKgwqBjaWZzOiB1c2Ugc2VydmVyIHRpbWVzdGFt cCBmb3IgbnRsbXYyIGF1dGhlbnRpY2F0aW9uCgpQZXRlciBaaWpsc3RyYSAoMSk6CsKgwqDCoMKg wqDCoHBlcmY6IEZpeCBmYXN5bmMgaGFuZGxpbmcgb24gaW5oZXJpdGVkIGV2ZW50cwoKUmljaGFy ZCBMYWluZyAoMSk6CsKgwqDCoMKgwqDCoG5ldC9pcHY2OiBDb3JyZWN0IFBJTTYgbXJ0X2xvY2sg aGFuZGxpbmcKClJpY2hhcmQgV2VpbmJlcmdlciAoMSk6CsKgwqDCoMKgwqDCoGxvY2FsbW9kY29u ZmlnOiBVc2UgS2J1aWxkIGZpbGVzIHRvbwoKUm9iZXJ0IEphcnptaWsgKDEpOgrCoMKgwqDCoMKg wqBBU29DOiBmaXggYnJva2VuIHB4YSBTb0Mgc3VwcG9ydAoKUm9nZXIgUXVhZHJvcyAoMSk6CsKg wqDCoMKgwqDCoHVzYjogeGhjaTogQ2xlYXIgWEhDSV9TVEFURV9EWUlORyBvbiBzdGFydAoKUm9s YW5kIERyZWllciAoMSk6CsKgwqDCoMKgwqDCoHRhcmdldDogUkVQT1JUIExVTlMgc2hvdWxkIHJl dHVybiBMVU4gMCBldmVuIGZvciBkeW5hbWljIEFDTHMKClJ1c3NlbGwgS2luZyAoMSk6CsKgwqDC oMKgwqDCoEFSTTogZml4IFRodW1iMiBzaWduYWwgaGFuZGxpbmcgd2hlbiBBUk12NiBpcyBlbmFi bGVkCgpTYXNoYSBMZXZpbiAoMSk6CsKgwqDCoMKgwqDCoFJEUzogdmVyaWZ5IHRoZSB1bmRlcmx5 aW5nIHRyYW5zcG9ydCBleGlzdHMgYmVmb3JlIGNyZWF0aW5nIGEgY29ubmVjdGlvbgoKU3RlcGhl biBDaGFuZGxlciBQYXVsICgxKToKwqDCoMKgwqDCoMKgRFJNIC0gcmFkZW9uOiBEb24ndCBsaW5r IHRyYWluIERpc3BsYXlQb3J0IG9uIEhQRCB1bnRpbCB3ZSBnZXQgdGhlIGRwY2QKClN0ZXBoZW4g U21hbGxleSAoMSk6CsKgwqDCoMKgwqDCoG5ldC90aXBjOiBpbml0aWFsaXplIHNlY3VyaXR5IHN0 YXRlIGZvciBuZXcgY29ubmVjdGlvbiBzb2NrZXQKClN1ZGlwIE11a2hlcmplZSAoMSk6CsKgwqDC oMKgwqDCoGF1eGRpc3BsYXk6IGtzMDEwODogZml4IHJlZmNvdW50CgpULkouIFB1cnRlbGwgKDEp OgrCoMKgwqDCoMKgwqBBUk06IDc4ODAvMTogQ2xlYXIgdGhlIElUIHN0YXRlIGluZGVwZW5kZW50 IG9mIHRoZSBUaHVtYi0yIG1vZGUKClRha2FzaGkgSXdhaSAoMSk6CsKgwqDCoMKgwqDCoElucHV0 OiBldmRldiAtIGRvIG5vdCByZXBvcnQgZXJyb3JzIGZvcm0gZmx1c2goKQoKVGFuLCBKdWkgTmVl ICgxKToKwqDCoMKgwqDCoMKgc3BpOiBzcGktcHhhMnh4OiBDaGVjayBzdGF0dXMgcmVnaXN0ZXIg dG8gZGV0ZXJtaW5lIGlmIFNTU1JfVElOVCBpcyBkaXNhYmxlZAoKVGhvbWFzIEdyYWYgKDEpOgrC oMKgwqDCoMKgwqBwa3RnZW46IFJlcXVpcmUgQ09ORklHX0lORVQgZHVlIHRvIHVzZSBvZiBJUHY0 IGNoZWNrc3VtIGZ1bmN0aW9uCgpUcm9uZCBNeWtsZWJ1c3QgKDEpOgrCoMKgwqDCoMKgwqBTVU5S UEM6IHhzX3Jlc2V0X3RyYW5zcG9ydCBtdXN0IG1hcmsgdGhlIGNvbm5lY3Rpb24gYXMgZGlzY29u bmVjdGVkCgpUeWxlciBIaWNrcyAoMSk6CsKgwqDCoMKgwqDCoGVDcnlwdGZzOiBJbnZhbGlkYXRl IGRjYWNoZSBlbnRyaWVzIHdoZW4gbG93ZXIgaV9ubGluayBpcyB6ZXJvCgpXaWxzb24gS29rICgx KToKwqDCoMKgwqDCoMKgZmliX3J1bGVzOiBmaXggZmliIHJ1bGUgZHVtcHMgYWNyb3NzIG11bHRp cGxlIHNrYnMKClhpYW8gR3Vhbmdyb25nICgxKToKwqDCoMKgwqDCoMKgS1ZNOiBNTVU6IGZpeCB2 YWxpZGF0aW9uIG9mIG1taW8gcGFnZSBmYXVsdAoKWWlzaGFpIEhhZGFzICgxKToKwqDCoMKgwqDC oMKgSUIvdXZlcmJzOiBGaXggcmFjZSBiZXR3ZWVuIGliX3V2ZXJic19vcGVuIGFuZCByZW1vdmVf b25lCgpkaW5ndGlhbmhvbmcgKDEpOgrCoMKgwqDCoMKgwqBib25kaW5nOiBjb3JyZWN0IHRoZSBN QUMgYWRkcmVzcyBmb3IgImZvbGxvdyIgZmFpbF9vdmVyX21hYyBwb2xpY3kKCmx1Y2llbiAoMSk6 CsKgwqDCoMKgwqDCoHNjdHA6IGRvbm90IHJlc2V0IHRoZSBvdmVyYWxsX2Vycm9yX2NvdW50IGlu IFNIVVRET1dOX1JFQ0VJVkUgc3RhdGUKCi0tIApCZW4gSHV0Y2hpbmdzCkFudGhvbnkncyBMYXcg b2YgRm9yY2U6IERvbid0IGZvcmNlIGl0LCBnZXQgYSBsYXJnZXIgaGFtbWVyLm== --=-/MQt7REM5T0IIpl/L0xm Content-Type: text/x-diff; charset="UTF-8"; name="linux-3.2.72.patch" Content-Disposition: attachment; filename="linux-3.2.72.patch" Content-Transfer-Encoding: quoted-printable diff --git a/Makefile b/Makefile index 9d5fea7..77ac417 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION =3D 3 PATCHLEVEL =3D 2 -SUBLEVEL =3D 71 +SUBLEVEL =3D 72 EXTRAVERSION =3D NAME =3D Saber-toothed Squirrel =20 diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 362c7ca..4a93374 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -53,6 +53,14 @@ endif =20 comma =3D , =20 +# +# The Scalar Replacement of Aggregates (SRA) optimization pass in GCC 4.9 = and +# later may result in code being generated that handles signed short and s= igned +# char struct members incorrectly. So disable it. +# (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D65932) +# +KBUILD_CFLAGS +=3D $(call cc-option,-fno-ipa-sra) + # This selects which instruction set is used. # Note that GCC does not numerically define an architecture version # macro, but instead defines a whole series of macros which makes diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 9e617bd..c1d9c77 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -486,12 +486,23 @@ setup_return(struct pt_regs *regs, struct k_sigaction= *ka, */ thumb =3D handler & 1; =20 +#if __LINUX_ARM_ARCH__ >=3D 6 + /* + * Clear the If-Then Thumb-2 execution state. ARM spec + * requires this to be all 000s in ARM mode. Snapdragon + * S4/Krait misbehaves on a Thumb=3D>ARM signal transition + * without this. + * + * We must do this whenever we are running on a Thumb-2 + * capable CPU, which includes ARMv6T2. However, we elect + * to do this whenever we're on an ARMv6 or later CPU for + * simplicity. + */ + cpsr &=3D ~PSR_IT_MASK; +#endif + if (thumb) { cpsr |=3D PSR_T_BIT; -#if __LINUX_ARM_ARCH__ >=3D 7 - /* clear the If-Then Thumb-2 execution state */ - cpsr &=3D ~PSR_IT_MASK; -#endif } else cpsr &=3D ~PSR_T_BIT; } diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtabl= e.h index b2202a6..95bcedb 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -153,8 +153,39 @@ static inline void set_pte(pte_t *ptep, pte_t pteval) * Make sure the buddy is global too (if it's !none, * it better already be global) */ +#ifdef CONFIG_SMP + /* + * For SMP, multiple CPUs can race, so we need to do + * this atomically. + */ +#ifdef CONFIG_64BIT +#define LL_INSN "lld" +#define SC_INSN "scd" +#else /* CONFIG_32BIT */ +#define LL_INSN "ll" +#define SC_INSN "sc" +#endif + unsigned long page_global =3D _PAGE_GLOBAL; + unsigned long tmp; + + __asm__ __volatile__ ( + " .set push\n" + " .set noreorder\n" + "1: " LL_INSN " %[tmp], %[buddy]\n" + " bnez %[tmp], 2f\n" + " or %[tmp], %[tmp], %[global]\n" + " " SC_INSN " %[tmp], %[buddy]\n" + " beqz %[tmp], 1b\n" + " nop\n" + "2:\n" + " .set pop" + : [buddy] "+m" (buddy->pte), + [tmp] "=3D&r" (tmp) + : [global] "r" (page_global)); +#else /* !CONFIG_SMP */ if (pte_none(*buddy)) pte_val(*buddy) =3D pte_val(*buddy) | _PAGE_GLOBAL; +#endif /* CONFIG_SMP */ } #endif } diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fp= aff.c index 802e616..c7e2684 100644 --- a/arch/mips/kernel/mips-mt-fpaff.c +++ b/arch/mips/kernel/mips-mt-fpaff.c @@ -154,7 +154,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid,= unsigned int len, unsigned long __user *user_mask_ptr) { unsigned int real_len; - cpumask_t mask; + cpumask_t allowed, mask; int retval; struct task_struct *p; =20 @@ -173,7 +173,8 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid,= unsigned int len, if (retval) goto out_unlock; =20 - cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map); + cpumask_or(&allowed, &p->thread.user_cpus_allowed, &p->cpus_allowed); + cpumask_and(&mask, &allowed, cpu_active_mask); =20 out_unlock: read_unlock(&tasklist_lock); diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index c0b1aff..88934b3 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -336,8 +336,8 @@ void do_cpu_irq_mask(struct pt_regs *regs) struct pt_regs *old_regs; unsigned long eirr_val; int irq, cpu =3D smp_processor_id(); -#ifdef CONFIG_SMP struct irq_desc *desc; +#ifdef CONFIG_SMP cpumask_t dest; #endif =20 @@ -350,8 +350,12 @@ void do_cpu_irq_mask(struct pt_regs *regs) goto set_out; irq =3D eirr_to_irq(eirr_val); =20 -#ifdef CONFIG_SMP + /* Filter out spurious interrupts, mostly from serial port at bootup */ desc =3D irq_to_desc(irq); + if (unlikely(!desc->action)) + goto set_out; + +#ifdef CONFIG_SMP cpumask_copy(&dest, desc->irq_data.affinity); if (irqd_is_per_cpu(&desc->irq_data) && !cpu_isset(smp_processor_id(), dest)) { diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/= powernv/pci.c index 85bb66d..15a05ca 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -130,6 +130,7 @@ static void pnv_teardown_msi_irqs(struct pci_dev *pdev) struct pci_controller *hose =3D pci_bus_to_host(pdev->bus); struct pnv_phb *phb =3D hose->private_data; struct msi_desc *entry; + irq_hw_number_t hwirq; =20 if (WARN_ON(!phb)) return; @@ -137,9 +138,10 @@ static void pnv_teardown_msi_irqs(struct pci_dev *pdev= ) list_for_each_entry(entry, &pdev->msi_list, list) { if (entry->irq =3D=3D NO_IRQ) continue; + hwirq =3D virq_to_hw(entry->irq); irq_set_msi_desc(entry->irq, NULL); - pnv_put_msi(phb, virq_to_hw(entry->irq)); irq_dispose_mapping(entry->irq); + pnv_put_msi(phb, hwirq); } } #endif /* CONFIG_PCI_MSI */ diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index e5c344d3..8ebbdc6 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -106,15 +106,16 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pde= v) { struct msi_desc *entry; struct fsl_msi *msi_data; + irq_hw_number_t hwirq; =20 list_for_each_entry(entry, &pdev->msi_list, list) { if (entry->irq =3D=3D NO_IRQ) continue; + hwirq =3D virq_to_hw(entry->irq); msi_data =3D irq_get_chip_data(entry->irq); irq_set_msi_desc(entry->irq, NULL); - msi_bitmap_free_hwirqs(&msi_data->bitmap, - virq_to_hw(entry->irq), 1); irq_dispose_mapping(entry->irq); + msi_bitmap_free_hwirqs(&msi_data->bitmap, hwirq, 1); } =20 return; diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mp= ic_pasemi_msi.c index 38e6238..e873616 100644 --- a/arch/powerpc/sysdev/mpic_pasemi_msi.c +++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c @@ -74,6 +74,7 @@ static int pasemi_msi_check_device(struct pci_dev *pdev, = int nvec, int type) static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev) { struct msi_desc *entry; + irq_hw_number_t hwirq; =20 pr_debug("pasemi_msi_teardown_msi_irqs, pdev %p\n", pdev); =20 @@ -81,10 +82,10 @@ static void pasemi_msi_teardown_msi_irqs(struct pci_dev= *pdev) if (entry->irq =3D=3D NO_IRQ) continue; =20 + hwirq =3D virq_to_hw(entry->irq); irq_set_msi_desc(entry->irq, NULL); - msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, - virq_to_hw(entry->irq), ALLOC_CHUNK); irq_dispose_mapping(entry->irq); + msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq, ALLOC_CHUNK); } =20 return; diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3= msi.c index 9a7aa0e..dfc3486 100644 --- a/arch/powerpc/sysdev/mpic_u3msi.c +++ b/arch/powerpc/sysdev/mpic_u3msi.c @@ -124,15 +124,16 @@ static int u3msi_msi_check_device(struct pci_dev *pde= v, int nvec, int type) static void u3msi_teardown_msi_irqs(struct pci_dev *pdev) { struct msi_desc *entry; + irq_hw_number_t hwirq; =20 list_for_each_entry(entry, &pdev->msi_list, list) { if (entry->irq =3D=3D NO_IRQ) continue; =20 + hwirq =3D virq_to_hw(entry->irq); irq_set_msi_desc(entry->irq, NULL); - msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, - virq_to_hw(entry->irq), 1); irq_dispose_mapping(entry->irq); + msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq, 1); } =20 return; diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/sysdev/ppc4xx_= msi.c index 1c2d7af..4aae9c8 100644 --- a/arch/powerpc/sysdev/ppc4xx_msi.c +++ b/arch/powerpc/sysdev/ppc4xx_msi.c @@ -114,16 +114,17 @@ void ppc4xx_teardown_msi_irqs(struct pci_dev *dev) { struct msi_desc *entry; struct ppc4xx_msi *msi_data =3D &ppc4xx_msi; + irq_hw_number_t hwirq; =20 dev_dbg(&dev->dev, "PCIE-MSI: tearing down msi irqs\n"); =20 list_for_each_entry(entry, &dev->msi_list, list) { if (entry->irq =3D=3D NO_IRQ) continue; + hwirq =3D virq_to_hw(entry->irq); irq_set_msi_desc(entry->irq, NULL); - msi_bitmap_free_hwirqs(&msi_data->bitmap, - virq_to_hw(entry->irq), 1); irq_dispose_mapping(entry->irq); + msi_bitmap_free_hwirqs(&msi_data->bitmap, hwirq, 1); } } =20 diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_sig= nal.c index 9fdd05d5..8831a40 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -52,6 +52,19 @@ typedef struct __u32 gprs_high[NUM_GPRS]; } rt_sigframe32; =20 +static inline void sigset_to_sigset32(unsigned long *set64, + compat_sigset_word *set32) +{ + set32[0] =3D (compat_sigset_word) set64[0]; + set32[1] =3D (compat_sigset_word)(set64[0] >> 32); +} + +static inline void sigset32_to_sigset(compat_sigset_word *set32, + unsigned long *set64) +{ + set64[0] =3D (unsigned long) set32[0] | ((unsigned long) set32[1] << 32); +} + int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) { int err; @@ -361,12 +374,14 @@ asmlinkage long sys32_sigreturn(void) { struct pt_regs *regs =3D task_pt_regs(current); sigframe32 __user *frame =3D (sigframe32 __user *)regs->gprs[15]; + compat_sigset_t cset; sigset_t set; =20 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) goto badframe; - if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32)) + if (__copy_from_user(&cset.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32)= ) goto badframe; + sigset32_to_sigset(cset.sig, set.sig); sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); if (restore_sigregs32(regs, &frame->sregs)) @@ -383,6 +398,7 @@ asmlinkage long sys32_rt_sigreturn(void) { struct pt_regs *regs =3D task_pt_regs(current); rt_sigframe32 __user *frame =3D (rt_sigframe32 __user *)regs->gprs[15]; + compat_sigset_t cset; sigset_t set; stack_t st; __u32 ss_sp; @@ -391,8 +407,9 @@ asmlinkage long sys32_rt_sigreturn(void) =20 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) goto badframe; - if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) + if (__copy_from_user(&cset, &frame->uc.uc_sigmask, sizeof(cset))) goto badframe; + sigset32_to_sigset(cset.sig, set.sig); sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); if (restore_sigregs32(regs, &frame->uc.uc_mcontext)) @@ -464,13 +481,16 @@ static int setup_frame32(int sig, struct k_sigaction = *ka, sigset_t *set, struct pt_regs * regs) { sigframe32 __user *frame =3D get_sigframe(ka, regs, sizeof(sigframe32)); + compat_sigset_t cset; + if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32))) goto give_sigsegv; =20 if (frame =3D=3D (void __user *) -1UL) goto give_sigsegv; =20 - if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32)) + sigset_to_sigset32(set->sig, cset.sig); + if (__copy_to_user(&frame->sc.oldmask, &cset.sig, _SIGMASK_COPY_SIZE32)) goto give_sigsegv; =20 if (save_sigregs32(regs, &frame->sregs)) @@ -524,6 +544,7 @@ give_sigsegv: static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *in= fo, sigset_t *set, struct pt_regs * regs) { + compat_sigset_t cset; int err =3D 0; rt_sigframe32 __user *frame =3D get_sigframe(ka, regs, sizeof(rt_sigframe= 32)); if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32))) @@ -536,6 +557,7 @@ static int setup_rt_frame32(int sig, struct k_sigaction= *ka, siginfo_t *info, goto give_sigsegv; =20 /* Create the ucontext. */ + sigset_to_sigset32(set->sig, cset.sig); err |=3D __put_user(UC_EXTENDED, &frame->uc.uc_flags); err |=3D __put_user(0, &frame->uc.uc_link); err |=3D __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); @@ -544,7 +566,7 @@ static int setup_rt_frame32(int sig, struct k_sigaction= *ka, siginfo_t *info, err |=3D __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); err |=3D save_sigregs32(regs, &frame->uc.uc_mcontext); err |=3D save_sigregs_gprs_high(regs, frame->gprs_high); - err |=3D __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + err |=3D __copy_to_user(&frame->uc.uc_sigmask, &cset, sizeof(cset)); if (err) goto give_sigsegv; =20 diff --git a/arch/sparc/include/asm/visasm.h b/arch/sparc/include/asm/visas= m.h index 39ca301..3a8c2af 100644 --- a/arch/sparc/include/asm/visasm.h +++ b/arch/sparc/include/asm/visasm.h @@ -28,18 +28,12 @@ * Must preserve %o5 between VISEntryHalf and VISExitHalf */ =20 #define VISEntryHalf \ - rd %fprs, %o5; \ - andcc %o5, FPRS_FEF, %g0; \ - be,pt %icc, 297f; \ - sethi %hi(298f), %g7; \ - sethi %hi(VISenterhalf), %g1; \ - jmpl %g1 + %lo(VISenterhalf), %g0; \ - or %g7, %lo(298f), %g7; \ - clr %o5; \ -297: wr %o5, FPRS_FEF, %fprs; \ -298: + VISEntry =20 #define VISExitHalf \ + VISExit + +#define VISExitHalfFast \ wr %o5, 0, %fprs; =20 #ifndef __ASSEMBLY__ diff --git a/arch/sparc/lib/VISsave.S b/arch/sparc/lib/VISsave.S index b320ae9..a063d84 100644 --- a/arch/sparc/lib/VISsave.S +++ b/arch/sparc/lib/VISsave.S @@ -44,9 +44,8 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3 =20 stx %g3, [%g6 + TI_GSR] 2: add %g6, %g1, %g3 - cmp %o5, FPRS_DU - be,pn %icc, 6f - sll %g1, 3, %g1 + mov FPRS_DU | FPRS_DL | FPRS_FEF, %o5 + sll %g1, 3, %g1 stb %o5, [%g3 + TI_FPSAVED] rd %gsr, %g2 add %g6, %g1, %g3 @@ -80,65 +79,3 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3 .align 32 80: jmpl %g7 + %g0, %g0 nop - -6: ldub [%g3 + TI_FPSAVED], %o5 - or %o5, FPRS_DU, %o5 - add %g6, TI_FPREGS+0x80, %g2 - stb %o5, [%g3 + TI_FPSAVED] - - sll %g1, 5, %g1 - add %g6, TI_FPREGS+0xc0, %g3 - wr %g0, FPRS_FEF, %fprs - membar #Sync - stda %f32, [%g2 + %g1] ASI_BLK_P - stda %f48, [%g3 + %g1] ASI_BLK_P - membar #Sync - ba,pt %xcc, 80f - nop - - .align 32 -80: jmpl %g7 + %g0, %g0 - nop - - .align 32 -VISenterhalf: - ldub [%g6 + TI_FPDEPTH], %g1 - brnz,a,pn %g1, 1f - cmp %g1, 1 - stb %g0, [%g6 + TI_FPSAVED] - stx %fsr, [%g6 + TI_XFSR] - clr %o5 - jmpl %g7 + %g0, %g0 - wr %g0, FPRS_FEF, %fprs - -1: bne,pn %icc, 2f - srl %g1, 1, %g1 - ba,pt %xcc, vis1 - sub %g7, 8, %g7 -2: addcc %g6, %g1, %g3 - sll %g1, 3, %g1 - andn %o5, FPRS_DU, %g2 - stb %g2, [%g3 + TI_FPSAVED] - - rd %gsr, %g2 - add %g6, %g1, %g3 - stx %g2, [%g3 + TI_GSR] - add %g6, %g1, %g2 - stx %fsr, [%g2 + TI_XFSR] - sll %g1, 5, %g1 -3: andcc %o5, FPRS_DL, %g0 - be,pn %icc, 4f - add %g6, TI_FPREGS, %g2 - - add %g6, TI_FPREGS+0x40, %g3 - membar #Sync - stda %f0, [%g2 + %g1] ASI_BLK_P - stda %f16, [%g3 + %g1] ASI_BLK_P - membar #Sync - ba,pt %xcc, 4f - nop - - .align 32 -4: and %o5, FPRS_DU, %o5 - jmpl %g7 + %g0, %g0 - wr %o5, FPRS_FEF, %fprs diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/g= hash-clmulni-intel_glue.c index f781251..4827b23 100644 --- a/arch/x86/crypto/ghash-clmulni-intel_glue.c +++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c @@ -291,6 +291,7 @@ static struct ahash_alg ghash_async_alg =3D { .cra_name =3D "ghash", .cra_driver_name =3D "ghash-clmulni", .cra_priority =3D 400, + .cra_ctxsize =3D sizeof(struct ghash_async_ctx), .cra_flags =3D CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC, .cra_blocksize =3D GHASH_BLOCK_SIZE, .cra_type =3D &crypto_ahash_type, diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index 3225868..382ce8a 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h @@ -277,21 +277,6 @@ static inline void clear_LDT(void) set_ldt(NULL, 0); } =20 -/* - * load one particular LDT into the current CPU - */ -static inline void load_LDT_nolock(mm_context_t *pc) -{ - set_ldt(pc->ldt, pc->size); -} - -static inline void load_LDT(mm_context_t *pc) -{ - preempt_disable(); - load_LDT_nolock(pc); - preempt_enable(); -} - static inline unsigned long get_desc_base(const struct desc_struct *desc) { return (unsigned)(desc->base0 | ((desc->base1) << 16) | ((desc->base2) <<= 24)); diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h index 5f55e69..926f672 100644 --- a/arch/x86/include/asm/mmu.h +++ b/arch/x86/include/asm/mmu.h @@ -9,8 +9,7 @@ * we put the segment information here. */ typedef struct { - void *ldt; - int size; + struct ldt_struct *ldt; =20 #ifdef CONFIG_X86_64 /* True if mm supports a task running in 32 bit compatibility mode. */ diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_= context.h index 6902152..ce4ea94 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -16,6 +16,51 @@ static inline void paravirt_activate_mm(struct mm_struct= *prev, #endif /* !CONFIG_PARAVIRT */ =20 /* + * ldt_structs can be allocated, used, and freed, but they are never + * modified while live. + */ +struct ldt_struct { + /* + * Xen requires page-aligned LDTs with special permissions. This is + * needed to prevent us from installing evil descriptors such as + * call gates. On native, we could merge the ldt_struct and LDT + * allocations, but it's not worth trying to optimize. + */ + struct desc_struct *entries; + int size; +}; + +static inline void load_mm_ldt(struct mm_struct *mm) +{ + struct ldt_struct *ldt; + + /* smp_read_barrier_depends synchronizes with barrier in install_ldt */ + ldt =3D ACCESS_ONCE(mm->context.ldt); + smp_read_barrier_depends(); + + /* + * Any change to mm->context.ldt is followed by an IPI to all + * CPUs with the mm active. The LDT will not be freed until + * after the IPI is handled by all such CPUs. This means that, + * if the ldt_struct changes before we return, the values we see + * will be safe, and the new values will be loaded before we run + * any user code. + * + * NB: don't try to convert this to use RCU without extreme care. + * We would still need IRQs off, because we don't want to change + * the local LDT after an IPI loaded a newer value than the one + * that we can see. + */ + + if (unlikely(ldt)) + set_ldt(ldt->entries, ldt->size); + else + clear_LDT(); + + DEBUG_LOCKS_WARN_ON(preemptible()); +} + +/* * Used for LDT copy/destruction. */ int init_new_context(struct task_struct *tsk, struct mm_struct *mm); @@ -52,7 +97,7 @@ static inline void switch_mm(struct mm_struct *prev, stru= ct mm_struct *next, * load the LDT, if the LDT is different: */ if (unlikely(prev->context.ldt !=3D next->context.ldt)) - load_LDT_nolock(&next->context); + load_mm_ldt(next); } #ifdef CONFIG_SMP else { @@ -65,7 +110,7 @@ static inline void switch_mm(struct mm_struct *prev, str= uct mm_struct *next, * to make sure to use no freed page tables. */ load_cr3(next->pgd); - load_LDT_nolock(&next->context); + load_mm_ldt(next); } } #endif diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-in= dex.h index 5538b13..3d48aa4 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -159,6 +159,7 @@ /* C1E active bits in int pending message */ #define K8_INTP_C1E_ACTIVE_MASK 0x18000000 #define MSR_K8_TSEG_ADDR 0xc0010112 +#define MSR_K8_TSEG_MASK 0xc0010113 #define K8_MTRRFIXRANGE_DRAM_ENABLE 0x00040000 /* MtrrFixDramEn bit */ #define K8_MTRRFIXRANGE_DRAM_MODIFY 0x00080000 /* MtrrFixDramModEn bit */ #define K8_MTRR_RDMEM_WRMEM_MASK 0x18181818 /* Mask: RdMem|WrMem */ diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 6284d6d..0cbdebf 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1225,7 +1225,7 @@ void __cpuinit cpu_init(void) load_sp0(t, ¤t->thread); set_tss_desc(cpu, t); load_TR_desc(); - load_LDT(&init_mm.context); + load_mm_ldt(&init_mm); =20 clear_all_debug_regs(); dbg_restore_debug_regs(); @@ -1273,7 +1273,7 @@ void __cpuinit cpu_init(void) load_sp0(t, thread); set_tss_desc(cpu, t); load_TR_desc(); - load_LDT(&init_mm.context); + load_mm_ldt(&init_mm); =20 t->x86_tss.io_bitmap_base =3D offsetof(struct tss_struct, io_bitmap); =20 diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 8d15c69..f6daf3c 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -1504,7 +1504,18 @@ END(error_exit) /* runs on exception stack */ ENTRY(nmi) INTR_FRAME + /* + * Fix up the exception frame if we're on Xen. + * PARAVIRT_ADJUST_EXCEPTION_FRAME is guaranteed to push at most + * one value to the stack on native, so it may clobber the rdx + * scratch slot, but it won't clobber any of the important + * slots past it. + * + * Xen is a different story, because the Xen frame itself overlaps + * the "NMI executing" variable. + */ PARAVIRT_ADJUST_EXCEPTION_FRAME + pushq_cfi $-1 subq $ORIG_RAX-R15, %rsp CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index 0a8e65e..1dd3230 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include =20 @@ -21,82 +22,87 @@ #include #include =20 -#ifdef CONFIG_SMP +/* context.lock is held for us, so we don't need any locking. */ static void flush_ldt(void *current_mm) { - if (current->active_mm =3D=3D current_mm) - load_LDT(¤t->active_mm->context); + mm_context_t *pc; + + if (current->active_mm !=3D current_mm) + return; + + pc =3D ¤t->active_mm->context; + set_ldt(pc->ldt->entries, pc->ldt->size); } -#endif =20 -static int alloc_ldt(mm_context_t *pc, int mincount, int reload) +/* The caller must call finalize_ldt_struct on the result. LDT starts zero= ed. */ +static struct ldt_struct *alloc_ldt_struct(int size) { - void *oldldt, *newldt; - int oldsize; - - if (mincount <=3D pc->size) - return 0; - oldsize =3D pc->size; - mincount =3D (mincount + (PAGE_SIZE / LDT_ENTRY_SIZE - 1)) & - (~(PAGE_SIZE / LDT_ENTRY_SIZE - 1)); - if (mincount * LDT_ENTRY_SIZE > PAGE_SIZE) - newldt =3D vmalloc(mincount * LDT_ENTRY_SIZE); + struct ldt_struct *new_ldt; + int alloc_size; + + if (size > LDT_ENTRIES) + return NULL; + + new_ldt =3D kmalloc(sizeof(struct ldt_struct), GFP_KERNEL); + if (!new_ldt) + return NULL; + + BUILD_BUG_ON(LDT_ENTRY_SIZE !=3D sizeof(struct desc_struct)); + alloc_size =3D size * LDT_ENTRY_SIZE; + + /* + * Xen is very picky: it requires a page-aligned LDT that has no + * trailing nonzero bytes in any page that contains LDT descriptors. + * Keep it simple: zero the whole allocation and never allocate less + * than PAGE_SIZE. + */ + if (alloc_size > PAGE_SIZE) + new_ldt->entries =3D vzalloc(alloc_size); else - newldt =3D (void *)__get_free_page(GFP_KERNEL); - - if (!newldt) - return -ENOMEM; + new_ldt->entries =3D kzalloc(PAGE_SIZE, GFP_KERNEL); =20 - if (oldsize) - memcpy(newldt, pc->ldt, oldsize * LDT_ENTRY_SIZE); - oldldt =3D pc->ldt; - memset(newldt + oldsize * LDT_ENTRY_SIZE, 0, - (mincount - oldsize) * LDT_ENTRY_SIZE); + if (!new_ldt->entries) { + kfree(new_ldt); + return NULL; + } =20 - paravirt_alloc_ldt(newldt, mincount); + new_ldt->size =3D size; + return new_ldt; +} =20 -#ifdef CONFIG_X86_64 - /* CHECKME: Do we really need this ? */ - wmb(); -#endif - pc->ldt =3D newldt; - wmb(); - pc->size =3D mincount; - wmb(); - - if (reload) { -#ifdef CONFIG_SMP - preempt_disable(); - load_LDT(pc); - if (!cpumask_equal(mm_cpumask(current->mm), - cpumask_of(smp_processor_id()))) - smp_call_function(flush_ldt, current->mm, 1); - preempt_enable(); -#else - load_LDT(pc); -#endif - } - if (oldsize) { - paravirt_free_ldt(oldldt, oldsize); - if (oldsize * LDT_ENTRY_SIZE > PAGE_SIZE) - vfree(oldldt); - else - put_page(virt_to_page(oldldt)); - } - return 0; +/* After calling this, the LDT is immutable. */ +static void finalize_ldt_struct(struct ldt_struct *ldt) +{ + paravirt_alloc_ldt(ldt->entries, ldt->size); } =20 -static inline int copy_ldt(mm_context_t *new, mm_context_t *old) +/* context.lock is held */ +static void install_ldt(struct mm_struct *current_mm, + struct ldt_struct *ldt) { - int err =3D alloc_ldt(new, old->size, 0); - int i; + /* Synchronizes with smp_read_barrier_depends in load_mm_ldt. */ + barrier(); + ACCESS_ONCE(current_mm->context.ldt) =3D ldt; + + /* Activate the LDT for all CPUs using current_mm. */ + smp_call_function_many(mm_cpumask(current_mm), flush_ldt, current_mm, + true); + local_irq_disable(); + flush_ldt(current_mm); + local_irq_enable(); +} =20 - if (err < 0) - return err; +static void free_ldt_struct(struct ldt_struct *ldt) +{ + if (likely(!ldt)) + return; =20 - for (i =3D 0; i < old->size; i++) - write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE); - return 0; + paravirt_free_ldt(ldt->entries, ldt->size); + if (ldt->size * LDT_ENTRY_SIZE > PAGE_SIZE) + vfree(ldt->entries); + else + kfree(ldt->entries); + kfree(ldt); } =20 /* @@ -105,17 +111,37 @@ static inline int copy_ldt(mm_context_t *new, mm_cont= ext_t *old) */ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { + struct ldt_struct *new_ldt; struct mm_struct *old_mm; int retval =3D 0; =20 mutex_init(&mm->context.lock); - mm->context.size =3D 0; old_mm =3D current->mm; - if (old_mm && old_mm->context.size > 0) { - mutex_lock(&old_mm->context.lock); - retval =3D copy_ldt(&mm->context, &old_mm->context); - mutex_unlock(&old_mm->context.lock); + if (!old_mm) { + mm->context.ldt =3D NULL; + return 0; + } + + mutex_lock(&old_mm->context.lock); + if (!old_mm->context.ldt) { + mm->context.ldt =3D NULL; + goto out_unlock; } + + new_ldt =3D alloc_ldt_struct(old_mm->context.ldt->size); + if (!new_ldt) { + retval =3D -ENOMEM; + goto out_unlock; + } + + memcpy(new_ldt->entries, old_mm->context.ldt->entries, + new_ldt->size * LDT_ENTRY_SIZE); + finalize_ldt_struct(new_ldt); + + mm->context.ldt =3D new_ldt; + +out_unlock: + mutex_unlock(&old_mm->context.lock); return retval; } =20 @@ -126,53 +152,47 @@ int init_new_context(struct task_struct *tsk, struct = mm_struct *mm) */ void destroy_context(struct mm_struct *mm) { - if (mm->context.size) { -#ifdef CONFIG_X86_32 - /* CHECKME: Can this ever happen ? */ - if (mm =3D=3D current->active_mm) - clear_LDT(); -#endif - paravirt_free_ldt(mm->context.ldt, mm->context.size); - if (mm->context.size * LDT_ENTRY_SIZE > PAGE_SIZE) - vfree(mm->context.ldt); - else - put_page(virt_to_page(mm->context.ldt)); - mm->context.size =3D 0; - } + free_ldt_struct(mm->context.ldt); + mm->context.ldt =3D NULL; } =20 static int read_ldt(void __user *ptr, unsigned long bytecount) { - int err; + int retval; unsigned long size; struct mm_struct *mm =3D current->mm; =20 - if (!mm->context.size) - return 0; + mutex_lock(&mm->context.lock); + + if (!mm->context.ldt) { + retval =3D 0; + goto out_unlock; + } + if (bytecount > LDT_ENTRY_SIZE * LDT_ENTRIES) bytecount =3D LDT_ENTRY_SIZE * LDT_ENTRIES; =20 - mutex_lock(&mm->context.lock); - size =3D mm->context.size * LDT_ENTRY_SIZE; + size =3D mm->context.ldt->size * LDT_ENTRY_SIZE; if (size > bytecount) size =3D bytecount; =20 - err =3D 0; - if (copy_to_user(ptr, mm->context.ldt, size)) - err =3D -EFAULT; - mutex_unlock(&mm->context.lock); - if (err < 0) - goto error_return; + if (copy_to_user(ptr, mm->context.ldt->entries, size)) { + retval =3D -EFAULT; + goto out_unlock; + } + if (size !=3D bytecount) { - /* zero-fill the rest */ - if (clear_user(ptr + size, bytecount - size) !=3D 0) { - err =3D -EFAULT; - goto error_return; + /* Zero-fill the rest and pretend we read bytecount bytes. */ + if (clear_user(ptr + size, bytecount - size)) { + retval =3D -EFAULT; + goto out_unlock; } } - return bytecount; -error_return: - return err; + retval =3D bytecount; + +out_unlock: + mutex_unlock(&mm->context.lock); + return retval; } =20 static int read_default_ldt(void __user *ptr, unsigned long bytecount) @@ -196,6 +216,8 @@ static int write_ldt(void __user *ptr, unsigned long by= tecount, int oldmode) struct desc_struct ldt; int error; struct user_desc ldt_info; + int oldsize, newsize; + struct ldt_struct *new_ldt, *old_ldt; =20 error =3D -EINVAL; if (bytecount !=3D sizeof(ldt_info)) @@ -214,34 +236,39 @@ static int write_ldt(void __user *ptr, unsigned long = bytecount, int oldmode) goto out; } =20 - mutex_lock(&mm->context.lock); - if (ldt_info.entry_number >=3D mm->context.size) { - error =3D alloc_ldt(¤t->mm->context, - ldt_info.entry_number + 1, 1); - if (error < 0) - goto out_unlock; - } - - /* Allow LDTs to be cleared by the user. */ - if (ldt_info.base_addr =3D=3D 0 && ldt_info.limit =3D=3D 0) { - if (oldmode || LDT_empty(&ldt_info)) { - memset(&ldt, 0, sizeof(ldt)); - goto install; + if ((oldmode && !ldt_info.base_addr && !ldt_info.limit) || + LDT_empty(&ldt_info)) { + /* The user wants to clear the entry. */ + memset(&ldt, 0, sizeof(ldt)); + } else { + if (!IS_ENABLED(CONFIG_X86_16BIT) && !ldt_info.seg_32bit) { + error =3D -EINVAL; + goto out; } + + fill_ldt(&ldt, &ldt_info); + if (oldmode) + ldt.avl =3D 0; } =20 - if (!IS_ENABLED(CONFIG_X86_16BIT) && !ldt_info.seg_32bit) { - error =3D -EINVAL; + mutex_lock(&mm->context.lock); + + old_ldt =3D mm->context.ldt; + oldsize =3D old_ldt ? old_ldt->size : 0; + newsize =3D max((int)(ldt_info.entry_number + 1), oldsize); + + error =3D -ENOMEM; + new_ldt =3D alloc_ldt_struct(newsize); + if (!new_ldt) goto out_unlock; - } =20 - fill_ldt(&ldt, &ldt_info); - if (oldmode) - ldt.avl =3D 0; + if (old_ldt) + memcpy(new_ldt->entries, old_ldt->entries, oldsize * LDT_ENTRY_SIZE); + new_ldt->entries[ldt_info.entry_number] =3D ldt; + finalize_ldt_struct(new_ldt); =20 - /* Install the new entry ... */ -install: - write_ldt_entry(mm->context.ldt, ldt_info.entry_number, &ldt); + install_ldt(mm, new_ldt); + free_ldt_struct(old_ldt); error =3D 0; =20 out_unlock: diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 84c938f..af5b675 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -38,10 +38,18 @@ #include #include =20 -/* nop stub */ -void _paravirt_nop(void) -{ -} +/* + * nop stub, which must not clobber anything *including the stack* to + * avoid confusing the entry prologues. + */ +extern void _paravirt_nop(void); +asm (".pushsection .entry.text, \"ax\"\n" + ".global _paravirt_nop\n" + "_paravirt_nop:\n\t" + "ret\n\t" + ".size _paravirt_nop, . - _paravirt_nop\n\t" + ".type _paravirt_nop, @function\n\t" + ".popsection"); =20 /* identity function, which can be inlined */ u32 _paravirt_ident_32(u32 x) diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index e361095..7e94abd 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -218,11 +218,11 @@ void __show_regs(struct pt_regs *regs, int all) void release_thread(struct task_struct *dead_task) { if (dead_task->mm) { - if (dead_task->mm->context.size) { + if (dead_task->mm->context.ldt) { printk("WARNING: dead process %8s still has LDT? <%p/%d>\n", dead_task->comm, dead_task->mm->context.ldt, - dead_task->mm->context.size); + dead_task->mm->context.ldt->size); BUG(); } } diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c index d4f278e..bfe6a14 100644 --- a/arch/x86/kernel/step.c +++ b/arch/x86/kernel/step.c @@ -5,6 +5,7 @@ #include #include #include +#include =20 unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_re= gs *regs) { @@ -27,13 +28,14 @@ unsigned long convert_ip_to_linear(struct task_struct *= child, struct pt_regs *re struct desc_struct *desc; unsigned long base; =20 - seg &=3D ~7UL; + seg >>=3D 3; =20 mutex_lock(&child->mm->context.lock); - if (unlikely((seg >> 3) >=3D child->mm->context.size)) + if (unlikely(!child->mm->context.ldt || + seg >=3D child->mm->context.ldt->size)) addr =3D -1L; /* bogus selector, access would fault */ else { - desc =3D child->mm->context.ldt + seg; + desc =3D &child->mm->context.ldt->entries[seg]; base =3D get_desc_base(desc); =20 /* 16-bit code segment? */ diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 9f3706e..e8177b1 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -18,6 +18,7 @@ #include #include #include +#include =20 unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */ EXPORT_SYMBOL(cpu_khz); @@ -802,15 +803,17 @@ EXPORT_SYMBOL_GPL(mark_tsc_unstable); =20 static void __init check_system_tsc_reliable(void) { -#ifdef CONFIG_MGEODE_LX - /* RTSC counts during suspend */ +#if defined(CONFIG_MGEODEGX1) || defined(CONFIG_MGEODE_LX) || defined(CONF= IG_X86_GENERIC) + if (is_geode_lx()) { + /* RTSC counts during suspend */ #define RTSC_SUSP 0x100 - unsigned long res_low, res_high; + unsigned long res_low, res_high; =20 - rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high); - /* Geode_LX - the OLPC CPU has a very reliable TSC */ - if (res_low & RTSC_SUSP) - tsc_clocksource_reliable =3D 1; + rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high); + /* Geode_LX - the OLPC CPU has a very reliable TSC */ + if (res_low & RTSC_SUSP) + tsc_clocksource_reliable =3D 1; + } #endif if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) tsc_clocksource_reliable =3D 1; diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 4a949c7..cac7b2b 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -326,12 +326,6 @@ static u64 __get_spte_lockless(u64 *sptep) { return ACCESS_ONCE(*sptep); } - -static bool __check_direct_spte_mmio_pf(u64 spte) -{ - /* It is valid if the spte is zapped. */ - return spte =3D=3D 0ull; -} #else union split_spte { struct { @@ -436,23 +430,6 @@ retry: =20 return spte.spte; } - -static bool __check_direct_spte_mmio_pf(u64 spte) -{ - union split_spte sspte =3D (union split_spte)spte; - u32 high_mmio_mask =3D shadow_mmio_mask >> 32; - - /* It is valid if the spte is zapped. */ - if (spte =3D=3D 0ull) - return true; - - /* It is valid if the spte is being zapped. */ - if (sspte.spte_low =3D=3D 0ull && - (sspte.spte_high & high_mmio_mask) =3D=3D high_mmio_mask) - return true; - - return false; -} #endif =20 static bool spte_has_volatile_bits(u64 spte) @@ -2895,21 +2872,6 @@ static bool quickly_check_mmio_pf(struct kvm_vcpu *v= cpu, u64 addr, bool direct) return vcpu_match_mmio_gva(vcpu, addr); } =20 - -/* - * On direct hosts, the last spte is only allows two states - * for mmio page fault: - * - It is the mmio spte - * - It is zapped or it is being zapped. - * - * This function completely checks the spte when the last spte - * is not the mmio spte. - */ -static bool check_direct_spte_mmio_pf(u64 spte) -{ - return __check_direct_spte_mmio_pf(spte); -} - static u64 walk_shadow_page_get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr) { struct kvm_shadow_walk_iterator iterator; @@ -2951,13 +2913,6 @@ int handle_mmio_page_fault_common(struct kvm_vcpu *v= cpu, u64 addr, bool direct) } =20 /* - * It's ok if the gva is remapped by other cpus on shadow guest, - * it's a BUG if the gfn is not a mmio page. - */ - if (direct && !check_direct_spte_mmio_pf(spte)) - return -1; - - /* * If the page table is zapped by other cpus, let CPU fault again on * the address. */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index bb179cc..0e3289b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1885,6 +1885,8 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr= , u64 *pdata) case MSR_IA32_LASTINTFROMIP: case MSR_IA32_LASTINTTOIP: case MSR_K8_SYSCFG: + case MSR_K8_TSEG_ADDR: + case MSR_K8_TSEG_MASK: case MSR_K7_HWCR: case MSR_VM_HSAVE_PA: case MSR_P6_PERFCTR0: diff --git a/arch/x86/math-emu/fpu_entry.c b/arch/x86/math-emu/fpu_entry.c index 7718541..dab1f8b 100644 --- a/arch/x86/math-emu/fpu_entry.c +++ b/arch/x86/math-emu/fpu_entry.c @@ -28,7 +28,6 @@ #include =20 #include -#include #include #include =20 @@ -184,7 +183,7 @@ void math_emulate(struct math_emu_info *info) math_abort(FPU_info, SIGILL); } =20 - code_descriptor =3D LDT_DESCRIPTOR(FPU_CS); + code_descriptor =3D FPU_get_ldt_descriptor(FPU_CS); if (SEG_D_SIZE(code_descriptor)) { /* The above test may be wrong, the book is not clear */ /* Segmented 32 bit protected mode */ diff --git a/arch/x86/math-emu/fpu_system.h b/arch/x86/math-emu/fpu_system.= h index 2c61441..d342fce 100644 --- a/arch/x86/math-emu/fpu_system.h +++ b/arch/x86/math-emu/fpu_system.h @@ -16,9 +16,24 @@ #include #include =20 -/* s is always from a cpu register, and the cpu does bounds checking - * during register load --> no further bounds checks needed */ -#define LDT_DESCRIPTOR(s) (((struct desc_struct *)current->mm->context.ldt= )[(s) >> 3]) +#include +#include + +static inline struct desc_struct FPU_get_ldt_descriptor(unsigned seg) +{ + static struct desc_struct zero_desc; + struct desc_struct ret =3D zero_desc; + +#ifdef CONFIG_MODIFY_LDT_SYSCALL + seg >>=3D 3; + mutex_lock(¤t->mm->context.lock); + if (current->mm->context.ldt && seg < current->mm->context.ldt->size) + ret =3D current->mm->context.ldt->entries[seg]; + mutex_unlock(¤t->mm->context.lock); +#endif + return ret; +} + #define SEG_D_SIZE(x) ((x).b & (3 << 21)) #define SEG_G_BIT(x) ((x).b & (1 << 23)) #define SEG_GRANULARITY(x) (((x).b & (1 << 23)) ? 4096 : 1) diff --git a/arch/x86/math-emu/get_address.c b/arch/x86/math-emu/get_addres= s.c index 6ef5e99..8300db7 100644 --- a/arch/x86/math-emu/get_address.c +++ b/arch/x86/math-emu/get_address.c @@ -20,7 +20,6 @@ #include =20 #include -#include =20 #include "fpu_system.h" #include "exception.h" @@ -158,7 +157,7 @@ static long pm_address(u_char FPU_modrm, u_char segment= , addr->selector =3D PM_REG_(segment); } =20 - descriptor =3D LDT_DESCRIPTOR(PM_REG_(segment)); + descriptor =3D FPU_get_ldt_descriptor(addr->selector); base_address =3D SEG_BASE_ADDR(descriptor); address =3D base_address + offset; limit =3D base_address diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index 43c9f6a..bc21909 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -21,6 +21,7 @@ #include #include #include +#include =20 #ifdef CONFIG_X86_32 static struct saved_context saved_context; @@ -147,7 +148,7 @@ static void fix_processor_context(void) syscall_init(); /* This sets MSR_*STAR and related */ #endif load_TR_desc(); /* This does ltr */ - load_LDT(¤t->active_mm->context); /* This does lldt */ + load_mm_ldt(current->active_mm); /* This does lldt */ } =20 /** diff --git a/drivers/auxdisplay/ks0108.c b/drivers/auxdisplay/ks0108.c index 5b93852..0d75285 100644 --- a/drivers/auxdisplay/ks0108.c +++ b/drivers/auxdisplay/ks0108.c @@ -139,6 +139,7 @@ static int __init ks0108_init(void) =20 ks0108_pardevice =3D parport_register_device(ks0108_parport, KS0108_NAME, NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); + parport_put_port(ks0108_parport); if (ks0108_pardevice =3D=3D NULL) { printk(KERN_ERR KS0108_NAME ": ERROR: " "parport didn't register new device\n"); diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 65cd748..cc956a4 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -254,10 +254,10 @@ void * devres_get(struct device *dev, void *new_res, if (!dr) { add_dr(dev, &new_dr->node); dr =3D new_dr; - new_dr =3D NULL; + new_res =3D NULL; } spin_unlock_irqrestore(&dev->devres_lock, flags); - devres_free(new_dr); + devres_free(new_res); =20 return dr->data; } diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 7a24895..ba8f361 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -311,9 +311,7 @@ int platform_device_add(struct platform_device *pdev) failed: while (--i >=3D 0) { struct resource *r =3D &pdev->resource[i]; - unsigned long type =3D resource_type(r); - - if (type =3D=3D IORESOURCE_MEM || type =3D=3D IORESOURCE_IO) + if (r->parent) release_resource(r); } =20 @@ -338,9 +336,7 @@ void platform_device_del(struct platform_device *pdev) =20 for (i =3D 0; i < pdev->num_resources; i++) { struct resource *r =3D &pdev->resource[i]; - unsigned long type =3D resource_type(r); - - if (type =3D=3D IORESOURCE_MEM || type =3D=3D IORESOURCE_IO) + if (r->parent) release_resource(r); } } diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.= c index 4c20c5b..8e9a8f0 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c @@ -914,7 +914,6 @@ static int ablk_perform(struct ablkcipher_request *req,= int encrypt) crypt->mode |=3D NPE_OP_NOT_IN_PLACE; /* This was never tested by Intel * for more than one dst buffer, I think. */ - BUG_ON(req->dst->length < nbytes); req_ctx->dst =3D NULL; if (!chainup_buffers(dev, req->dst, nbytes, &dst_hook, flags, DMA_FROM_DEVICE)) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i= 915/i915_gem_execbuffer.c index a0b69ae0..9b9f447 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -950,13 +950,13 @@ i915_gem_execbuffer_move_to_active(struct list_head *= objects, u32 old_write =3D obj->base.write_domain; =20 =20 + obj->dirty =3D 1; /* be paranoid */ obj->base.read_domains =3D obj->base.pending_read_domains; obj->base.write_domain =3D obj->base.pending_write_domain; obj->fenced_gpu_access =3D obj->pending_fenced_gpu_access; =20 i915_gem_object_move_to_active(obj, ring, seqno); if (obj->base.write_domain) { - obj->dirty =3D 1; obj->pending_gpu_write =3D true; list_move_tail(&obj->gpu_write_list, &ring->gpu_write_list); diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/rade= on/radeon_combios.c index 21e689d..87a677e 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -3399,6 +3399,14 @@ void radeon_combios_asic_init(struct drm_device *dev= ) rdev->pdev->subsystem_device =3D=3D 0x30ae) return; =20 + /* quirk for rs4xx HP Compaq dc5750 Small Form Factor to make it resume + * - it hangs on resume inside the dynclk 1 table. + */ + if (rdev->family =3D=3D CHIP_RS480 && + rdev->pdev->subsystem_vendor =3D=3D 0x103c && + rdev->pdev->subsystem_device =3D=3D 0x280a) + return; + /* DYN CLK 1 */ table =3D combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE); if (table) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/r= adeon/radeon_connectors.c index 683cede1..6303fc8 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -82,6 +82,11 @@ void radeon_connector_hotplug(struct drm_connector *conn= ector) if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); } else if (radeon_dp_needs_link_train(radeon_connector)) { + /* Don't try to start link training before we + * have the dpcd */ + if (!radeon_dp_getdpcd(radeon_connector)) + return; + /* set it to OFF so that drm_helper_connector_dpms() * won't return immediately since the current state * is ON at this point. diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uve= rbs.h index 5bcb2af..228af18 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h @@ -69,7 +69,7 @@ */ =20 struct ib_uverbs_device { - struct kref ref; + atomic_t refcount; int num_comp_vectors; struct completion comp; struct device *dev; @@ -78,6 +78,7 @@ struct ib_uverbs_device { struct cdev cdev; struct rb_root xrcd_tree; struct mutex xrcd_tree_mutex; + struct kobject kobj; }; =20 struct ib_uverbs_event_file { diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core= /uverbs_cmd.c index a8445b8..3be21aa 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -1979,6 +1979,12 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *f= ile, next->send_flags =3D user_wr->send_flags; =20 if (is_ud) { + if (next->opcode !=3D IB_WR_SEND && + next->opcode !=3D IB_WR_SEND_WITH_IMM) { + ret =3D -EINVAL; + goto out_put; + } + next->wr.ud.ah =3D idr_read_ah(user_wr->wr.ud.ah, file->ucontext); if (!next->wr.ud.ah) { @@ -2015,9 +2021,11 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *f= ile, user_wr->wr.atomic.compare_add; next->wr.atomic.swap =3D user_wr->wr.atomic.swap; next->wr.atomic.rkey =3D user_wr->wr.atomic.rkey; + case IB_WR_SEND: break; default: - break; + ret =3D -EINVAL; + goto out_put; } } =20 diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/cor= e/uverbs_main.c index 9379b97..f07c6e3 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -117,14 +117,18 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs= _file *file, static void ib_uverbs_add_one(struct ib_device *device); static void ib_uverbs_remove_one(struct ib_device *device); =20 -static void ib_uverbs_release_dev(struct kref *ref) +static void ib_uverbs_release_dev(struct kobject *kobj) { struct ib_uverbs_device *dev =3D - container_of(ref, struct ib_uverbs_device, ref); + container_of(kobj, struct ib_uverbs_device, kobj); =20 - complete(&dev->comp); + kfree(dev); } =20 +static struct kobj_type ib_uverbs_dev_ktype =3D { + .release =3D ib_uverbs_release_dev, +}; + static void ib_uverbs_release_event_file(struct kref *ref) { struct ib_uverbs_event_file *file =3D @@ -273,13 +277,19 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverb= s_file *file, return context->device->dealloc_ucontext(context); } =20 +static void ib_uverbs_comp_dev(struct ib_uverbs_device *dev) +{ + complete(&dev->comp); +} + static void ib_uverbs_release_file(struct kref *ref) { struct ib_uverbs_file *file =3D container_of(ref, struct ib_uverbs_file, ref); =20 module_put(file->device->ib_dev->owner); - kref_put(&file->device->ref, ib_uverbs_release_dev); + if (atomic_dec_and_test(&file->device->refcount)) + ib_uverbs_comp_dev(file->device); =20 kfree(file); } @@ -621,9 +631,7 @@ static int ib_uverbs_open(struct inode *inode, struct f= ile *filp) int ret; =20 dev =3D container_of(inode->i_cdev, struct ib_uverbs_device, cdev); - if (dev) - kref_get(&dev->ref); - else + if (!atomic_inc_not_zero(&dev->refcount)) return -ENXIO; =20 if (!try_module_get(dev->ib_dev->owner)) { @@ -644,6 +652,7 @@ static int ib_uverbs_open(struct inode *inode, struct f= ile *filp) mutex_init(&file->mutex); =20 filp->private_data =3D file; + kobject_get(&dev->kobj); =20 return nonseekable_open(inode, filp); =20 @@ -651,13 +660,16 @@ err_module: module_put(dev->ib_dev->owner); =20 err: - kref_put(&dev->ref, ib_uverbs_release_dev); + if (atomic_dec_and_test(&dev->refcount)) + ib_uverbs_comp_dev(dev); + return ret; } =20 static int ib_uverbs_close(struct inode *inode, struct file *filp) { struct ib_uverbs_file *file =3D filp->private_data; + struct ib_uverbs_device *dev =3D file->device; =20 ib_uverbs_cleanup_ucontext(file, file->ucontext); =20 @@ -665,6 +677,7 @@ static int ib_uverbs_close(struct inode *inode, struct = file *filp) kref_put(&file->async_file->ref, ib_uverbs_release_event_file); =20 kref_put(&file->ref, ib_uverbs_release_file); + kobject_put(&dev->kobj); =20 return 0; } @@ -760,10 +773,11 @@ static void ib_uverbs_add_one(struct ib_device *devic= e) if (!uverbs_dev) return; =20 - kref_init(&uverbs_dev->ref); + atomic_set(&uverbs_dev->refcount, 1); init_completion(&uverbs_dev->comp); uverbs_dev->xrcd_tree =3D RB_ROOT; mutex_init(&uverbs_dev->xrcd_tree_mutex); + kobject_init(&uverbs_dev->kobj, &ib_uverbs_dev_ktype); =20 spin_lock(&map_lock); devnum =3D find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES); @@ -790,6 +804,7 @@ static void ib_uverbs_add_one(struct ib_device *device) cdev_init(&uverbs_dev->cdev, NULL); uverbs_dev->cdev.owner =3D THIS_MODULE; uverbs_dev->cdev.ops =3D device->mmap ? &uverbs_mmap_fops : &uverbs_fops; + uverbs_dev->cdev.kobj.parent =3D &uverbs_dev->kobj; kobject_set_name(&uverbs_dev->cdev.kobj, "uverbs%d", uverbs_dev->devnum); if (cdev_add(&uverbs_dev->cdev, base, 1)) goto err_cdev; @@ -820,9 +835,10 @@ err_cdev: clear_bit(devnum, overflow_map); =20 err: - kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); + if (atomic_dec_and_test(&uverbs_dev->refcount)) + ib_uverbs_comp_dev(uverbs_dev); wait_for_completion(&uverbs_dev->comp); - kfree(uverbs_dev); + kobject_put(&uverbs_dev->kobj); return; } =20 @@ -842,9 +858,10 @@ static void ib_uverbs_remove_one(struct ib_device *dev= ice) else clear_bit(uverbs_dev->devnum - IB_UVERBS_MAX_DEVICES, overflow_map); =20 - kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); + if (atomic_dec_and_test(&uverbs_dev->refcount)) + ib_uverbs_comp_dev(uverbs_dev); wait_for_completion(&uverbs_dev->comp); - kfree(uverbs_dev); + kobject_put(&uverbs_dev->kobj); } =20 static char *uverbs_devnode(struct device *dev, mode_t *mode) diff --git a/drivers/infiniband/hw/mlx4/ah.c b/drivers/infiniband/hw/mlx4/a= h.c index 4b8f9c4..5426ccf 100644 --- a/drivers/infiniband/hw/mlx4/ah.c +++ b/drivers/infiniband/hw/mlx4/ah.c @@ -169,9 +169,13 @@ int mlx4_ib_query_ah(struct ib_ah *ibah, struct ib_ah_= attr *ah_attr) enum rdma_link_layer ll; =20 memset(ah_attr, 0, sizeof *ah_attr); - ah_attr->sl =3D be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 28; ah_attr->port_num =3D be32_to_cpu(ah->av.ib.port_pd) >> 24; ll =3D rdma_port_get_link_layer(ibah->device, ah_attr->port_num); + if (ll =3D=3D IB_LINK_LAYER_ETHERNET) + ah_attr->sl =3D be32_to_cpu(ah->av.eth.sl_tclass_flowlabel) >> 29; + else + ah_attr->sl =3D be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 28; + ah_attr->dlid =3D ll =3D=3D IB_LINK_LAYER_INFINIBAND ? be16_to_cpu(ah->av= .ib.dlid) : 0; if (ah->av.ib.stat_rate) ah_attr->static_rate =3D ah->av.ib.stat_rate - MLX4_STAT_RATE_OFFSET; diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qi= b.h index 4c2b079..c0b72a6 100644 --- a/drivers/infiniband/hw/qib/qib.h +++ b/drivers/infiniband/hw/qib/qib.h @@ -1421,6 +1421,10 @@ extern struct mutex qib_mutex; qib_get_unit_name((dd)->unit), ##__VA_ARGS__); \ } while (0) =20 +#define qib_dev_warn(dd, fmt, ...) \ + dev_warn(&(dd)->pcidev->dev, "%s: " fmt, \ + qib_get_unit_name((dd)->unit), ##__VA_ARGS__) + #define qib_dev_porterr(dd, port, fmt, ...) \ do { \ dev_err(&(dd)->pcidev->dev, "%s: IB%u:%u " fmt, \ diff --git a/drivers/infiniband/hw/qib/qib_keys.c b/drivers/infiniband/hw/q= ib/qib_keys.c index 8fd19a4..ca6e6cf 100644 --- a/drivers/infiniband/hw/qib/qib_keys.c +++ b/drivers/infiniband/hw/qib/qib_keys.c @@ -69,6 +69,10 @@ int qib_alloc_lkey(struct qib_lkey_table *rkt, struct qi= b_mregion *mr) * unrestricted LKEY. */ rkt->gen++; + /* + * bits are capped in qib_verbs.c to insure enough bits + * for generation number + */ mr->lkey =3D (r << (32 - ib_qib_lkey_table_size)) | ((((1 << (24 - ib_qib_lkey_table_size)) - 1) & rkt->gen) << 8); diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/= qib/qib_verbs.c index a894762..c51a6f9 100644 --- a/drivers/infiniband/hw/qib/qib_verbs.c +++ b/drivers/infiniband/hw/qib/qib_verbs.c @@ -40,6 +40,7 @@ #include #include #include +#include =20 #include "qib.h" #include "qib_common.h" @@ -2035,10 +2036,16 @@ int qib_register_ib_device(struct qib_devdata *dd) * the LKEY). The remaining bits act as a generation number or tag. */ spin_lock_init(&dev->lk_table.lock); + /* insure generation is at least 4 bits see keys.c */ + if (ib_qib_lkey_table_size > MAX_LKEY_TABLE_BITS) { + qib_dev_warn(dd, "lkey bits %u too large, reduced to %u\n", + ib_qib_lkey_table_size, MAX_LKEY_TABLE_BITS); + ib_qib_lkey_table_size =3D MAX_LKEY_TABLE_BITS; + } dev->lk_table.max =3D 1 << ib_qib_lkey_table_size; lk_tab_size =3D dev->lk_table.max * sizeof(*dev->lk_table.table); dev->lk_table.table =3D (struct qib_mregion **) - __get_free_pages(GFP_KERNEL, get_order(lk_tab_size)); + vmalloc(lk_tab_size); if (dev->lk_table.table =3D=3D NULL) { ret =3D -ENOMEM; goto err_lk; @@ -2208,7 +2215,7 @@ err_tx: sizeof(struct qib_pio_header), dev->pio_hdrs, dev->pio_hdrs_phys); err_hdrs: - free_pages((unsigned long) dev->lk_table.table, get_order(lk_tab_size)); + vfree(dev->lk_table.table); err_lk: kfree(dev->qp_table); err_qpt: @@ -2262,7 +2269,6 @@ void qib_unregister_ib_device(struct qib_devdata *dd) sizeof(struct qib_pio_header), dev->pio_hdrs, dev->pio_hdrs_phys); lk_tab_size =3D dev->lk_table.max * sizeof(*dev->lk_table.table); - free_pages((unsigned long) dev->lk_table.table, - get_order(lk_tab_size)); + vfree(dev->lk_table.table); kfree(dev->qp_table); } diff --git a/drivers/infiniband/hw/qib/qib_verbs.h b/drivers/infiniband/hw/= qib/qib_verbs.h index 0c19ef0..66f7f62 100644 --- a/drivers/infiniband/hw/qib/qib_verbs.h +++ b/drivers/infiniband/hw/qib/qib_verbs.h @@ -622,6 +622,8 @@ struct qib_qpn_table { struct qpn_map map[QPNMAP_ENTRIES]; }; =20 +#define MAX_LKEY_TABLE_BITS 23 + struct qib_lkey_table { spinlock_t lock; /* protect changes in this struct */ u32 next; /* next unused index (speeds search) */ diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 4cf2534..f55a3cf 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -126,19 +126,14 @@ static int evdev_flush(struct file *file, fl_owner_t = id) { struct evdev_client *client =3D file->private_data; struct evdev *evdev =3D client->evdev; - int retval; =20 - retval =3D mutex_lock_interruptible(&evdev->mutex); - if (retval) - return retval; + mutex_lock(&evdev->mutex); =20 - if (!evdev->exist) - retval =3D -ENODEV; - else - retval =3D input_flush_device(&evdev->handle, file); + if (evdev->exist) + input_flush_device(&evdev->handle, file); =20 mutex_unlock(&evdev->mutex); - return retval; + return 0; } =20 static void evdev_free(struct device *dev) diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm= _core.c index ce88979..004fa10 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c @@ -421,7 +421,7 @@ int wf_unregister_client(struct notifier_block *nb) { mutex_lock(&wf_lock); blocking_notifier_chain_unregister(&wf_client_list, nb); - wf_client_count++; + wf_client_count--; if (wf_client_count =3D=3D 0) wf_stop_thread(); mutex_unlock(&wf_lock); diff --git a/drivers/md/md.c b/drivers/md/md.c index ea8a181..d7e9242 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5384,9 +5384,9 @@ static int get_bitmap_file(struct mddev * mddev, void= __user * arg) int err =3D -ENOMEM; =20 if (md_allow_write(mddev)) - file =3D kmalloc(sizeof(*file), GFP_NOIO); + file =3D kzalloc(sizeof(*file), GFP_NOIO); else - file =3D kmalloc(sizeof(*file), GFP_KERNEL); + file =3D kzalloc(sizeof(*file), GFP_KERNEL); =20 if (!file) goto out; diff --git a/drivers/md/persistent-data/dm-btree-internal.h b/drivers/md/pe= rsistent-data/dm-btree-internal.h index acba54e..f8458ca 100644 --- a/drivers/md/persistent-data/dm-btree-internal.h +++ b/drivers/md/persistent-data/dm-btree-internal.h @@ -134,4 +134,10 @@ int lower_bound(struct btree_node *n, uint64_t key); =20 extern struct dm_block_validator btree_node_validator; =20 +/* + * Value type for upper levels of multi-level btrees. + */ +extern void init_le64_type(struct dm_transaction_manager *tm, + struct dm_btree_value_type *vt); + #endif /* DM_BTREE_INTERNAL_H */ diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/pers= istent-data/dm-btree-remove.c index 6e79c11..294eb5b 100644 --- a/drivers/md/persistent-data/dm-btree-remove.c +++ b/drivers/md/persistent-data/dm-btree-remove.c @@ -544,14 +544,6 @@ static int remove_raw(struct shadow_spine *s, struct d= m_btree_info *info, return r; } =20 -static struct dm_btree_value_type le64_type =3D { - .context =3D NULL, - .size =3D sizeof(__le64), - .inc =3D NULL, - .dec =3D NULL, - .equal =3D NULL -}; - int dm_btree_remove(struct dm_btree_info *info, dm_block_t root, uint64_t *keys, dm_block_t *new_root) { @@ -559,12 +551,14 @@ int dm_btree_remove(struct dm_btree_info *info, dm_bl= ock_t root, int index =3D 0, r =3D 0; struct shadow_spine spine; struct btree_node *n; + struct dm_btree_value_type le64_vt; =20 + init_le64_type(info->tm, &le64_vt); init_shadow_spine(&spine, info); for (level =3D 0; level < info->levels; level++) { r =3D remove_raw(&spine, info, (level =3D=3D last_level ? - &info->value_type : &le64_type), + &info->value_type : &le64_vt), root, keys[level], (unsigned *)&index); if (r < 0) break; diff --git a/drivers/md/persistent-data/dm-btree-spine.c b/drivers/md/persi= stent-data/dm-btree-spine.c index 2f0805c..f6cb762 100644 --- a/drivers/md/persistent-data/dm-btree-spine.c +++ b/drivers/md/persistent-data/dm-btree-spine.c @@ -242,3 +242,40 @@ int shadow_root(struct shadow_spine *s) { return s->root; } + +static void le64_inc(void *context, void *value_le) +{ + struct dm_transaction_manager *tm =3D context; + __le64 v_le; + + memcpy(&v_le, value_le, sizeof(v_le)); + dm_tm_inc(tm, le64_to_cpu(v_le)); +} + +static void le64_dec(void *context, void *value_le) +{ + struct dm_transaction_manager *tm =3D context; + __le64 v_le; + + memcpy(&v_le, value_le, sizeof(v_le)); + dm_tm_dec(tm, le64_to_cpu(v_le)); +} + +static int le64_equal(void *context, void *value1_le, void *value2_le) +{ + __le64 v1_le, v2_le; + + memcpy(&v1_le, value1_le, sizeof(v1_le)); + memcpy(&v2_le, value2_le, sizeof(v2_le)); + return v1_le =3D=3D v2_le; +} + +void init_le64_type(struct dm_transaction_manager *tm, + struct dm_btree_value_type *vt) +{ + vt->context =3D tm; + vt->size =3D sizeof(__le64); + vt->inc =3D le64_inc; + vt->dec =3D le64_dec; + vt->equal =3D le64_equal; +} diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-= data/dm-btree.c index 18f37e0..62f297a 100644 --- a/drivers/md/persistent-data/dm-btree.c +++ b/drivers/md/persistent-data/dm-btree.c @@ -647,12 +647,7 @@ static int insert(struct dm_btree_info *info, dm_block= _t root, struct btree_node *n; struct dm_btree_value_type le64_type; =20 - le64_type.context =3D NULL; - le64_type.size =3D sizeof(__le64); - le64_type.inc =3D NULL; - le64_type.dec =3D NULL; - le64_type.equal =3D NULL; - + init_le64_type(info->tm, &le64_type); init_shadow_spine(&spine, info); =20 for (level =3D 0; level < (info->levels - 1); level++) { diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 6e7b002..a5f284d 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1208,6 +1208,7 @@ static void error(struct mddev *mddev, struct md_rdev= *rdev) { char b[BDEVNAME_SIZE]; struct r1conf *conf =3D mddev->private; + unsigned long flags; =20 /* * If it is not operational, then we have already marked it as dead @@ -1227,14 +1228,13 @@ static void error(struct mddev *mddev, struct md_rd= ev *rdev) return; } set_bit(Blocked, &rdev->flags); + spin_lock_irqsave(&conf->device_lock, flags); if (test_and_clear_bit(In_sync, &rdev->flags)) { - unsigned long flags; - spin_lock_irqsave(&conf->device_lock, flags); mddev->degraded++; set_bit(Faulty, &rdev->flags); - spin_unlock_irqrestore(&conf->device_lock, flags); } else set_bit(Faulty, &rdev->flags); + spin_unlock_irqrestore(&conf->device_lock, flags); /* * if recovery is running, make sure it aborts. */ @@ -1292,7 +1292,10 @@ static int raid1_spare_active(struct mddev *mddev) * Find all failed disks within the RAID1 configuration=20 * and mark them readable. * Called under mddev lock, so rcu protection not needed. + * device_lock used to avoid races with raid1_end_read_request + * which expects 'In_sync' flags and ->degraded to be consistent. */ + spin_lock_irqsave(&conf->device_lock, flags); for (i =3D 0; i < conf->raid_disks; i++) { struct md_rdev *rdev =3D conf->mirrors[i].rdev; if (rdev @@ -1302,7 +1305,6 @@ static int raid1_spare_active(struct mddev *mddev) sysfs_notify_dirent_safe(rdev->sysfs_state); } } - spin_lock_irqsave(&conf->device_lock, flags); mddev->degraded -=3D count; spin_unlock_irqrestore(&conf->device_lock, flags); =20 diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index a47ba33..2be51c8 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -945,9 +945,6 @@ static int rc_dev_uevent(struct device *device, struct = kobj_uevent_env *env) { struct rc_dev *dev =3D to_rc_dev(device); =20 - if (!dev || !dev->input_dev) - return -ENODEV; - if (dev->rc_map.name) ADD_HOTPLUG_VAR("NAME=3D%s", dev->rc_map.name); if (dev->driver_name) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_mai= n.c index 5af2a8f..9145834c 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -861,6 +861,23 @@ static void bond_mc_swap(struct bonding *bond, struct = slave *new_active, } } =20 +static struct slave *bond_get_old_active(struct bonding *bond, + struct slave *new_active) +{ + struct slave *slave; + int i; + + bond_for_each_slave(bond, slave, i) { + if (slave =3D=3D new_active) + continue; + + if (!compare_ether_addr(bond->dev->dev_addr, slave->dev->dev_addr)) + return slave; + } + + return NULL; +} + /* * bond_do_fail_over_mac * @@ -898,6 +915,9 @@ static void bond_do_fail_over_mac(struct bonding *bond, write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); =20 + if (!old_active) + old_active =3D bond_get_old_active(bond, new_active); + if (old_active) { memcpy(tmp_mac, new_active->dev->dev_addr, ETH_ALEN); memcpy(saddr.sa_data, old_active->dev->dev_addr, diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index f13a673..715e5c4 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -981,9 +981,9 @@ static int virtnet_probe(struct virtio_device *vdev) /* Do we support "hardware" checksums? */ if (virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) { /* This opens up the world of extra features. */ - dev->hw_features |=3D NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; + dev->hw_features |=3D NETIF_F_HW_CSUM | NETIF_F_SG; if (csum) - dev->features |=3D NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; + dev->features |=3D NETIF_F_HW_CSUM | NETIF_F_SG; =20 if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) { dev->hw_features |=3D NETIF_F_TSO | NETIF_F_UFO diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wire= less/rtlwifi/rtl8192cu/sw.c index ec347d2..e813eff 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -313,6 +313,8 @@ static struct usb_device_id rtl8192c_usb_ids[] =3D { {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ + {RTL_USB_DEVICE(0x0846, 0x9043, rtl92cu_hal_cfg)}, /*NG WNA1000Mv2*/ + {RTL_USB_DEVICE(0x0b05, 0x17ba, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/ {RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/ {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ diff --git a/drivers/of/address.c b/drivers/of/address.c index 53a613f..39016a0 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -604,10 +604,10 @@ struct device_node *of_find_matching_node_by_address(= struct device_node *from, struct resource res; =20 while (dn) { - if (of_address_to_resource(dn, 0, &res)) - continue; - if (res.start =3D=3D base_address) + if (!of_address_to_resource(dn, 0, &res) && + res.start =3D=3D base_address) return dn; + dn =3D of_find_matching_node(dn, matches); } =20 diff --git a/drivers/pci/access.c b/drivers/pci/access.c index fdaa42a..fac01f8 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -355,6 +355,56 @@ static const struct pci_vpd_ops pci_vpd_pci22_ops =3D = { .release =3D pci_vpd_pci22_release, }; =20 +static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t cou= nt, + void *arg) +{ + struct pci_dev *tdev =3D pci_get_slot(dev->bus, PCI_SLOT(dev->devfn)); + ssize_t ret; + + if (!tdev) + return -ENODEV; + + ret =3D pci_read_vpd(tdev, pos, count, arg); + pci_dev_put(tdev); + return ret; +} + +static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t co= unt, + const void *arg) +{ + struct pci_dev *tdev =3D pci_get_slot(dev->bus, PCI_SLOT(dev->devfn)); + ssize_t ret; + + if (!tdev) + return -ENODEV; + + ret =3D pci_write_vpd(tdev, pos, count, arg); + pci_dev_put(tdev); + return ret; +} + +static const struct pci_vpd_ops pci_vpd_f0_ops =3D { + .read =3D pci_vpd_f0_read, + .write =3D pci_vpd_f0_write, + .release =3D pci_vpd_pci22_release, +}; + +static int pci_vpd_f0_dev_check(struct pci_dev *dev) +{ + struct pci_dev *tdev =3D pci_get_slot(dev->bus, PCI_SLOT(dev->devfn)); + int ret =3D 0; + + if (!tdev) + return -ENODEV; + if (!tdev->vpd || !tdev->multifunction || + dev->class !=3D tdev->class || dev->vendor !=3D tdev->vendor || + dev->device !=3D tdev->device) + ret =3D -ENODEV; + + pci_dev_put(tdev); + return ret; +} + int pci_vpd_pci22_init(struct pci_dev *dev) { struct pci_vpd_pci22 *vpd; @@ -363,12 +413,21 @@ int pci_vpd_pci22_init(struct pci_dev *dev) cap =3D pci_find_capability(dev, PCI_CAP_ID_VPD); if (!cap) return -ENODEV; + if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) { + int ret =3D pci_vpd_f0_dev_check(dev); + + if (ret) + return ret; + } vpd =3D kzalloc(sizeof(*vpd), GFP_ATOMIC); if (!vpd) return -ENOMEM; =20 vpd->base.len =3D PCI_VPD_PCI22_SIZE; - vpd->base.ops =3D &pci_vpd_pci22_ops; + if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) + vpd->base.ops =3D &pci_vpd_f0_ops; + else + vpd->base.ops =3D &pci_vpd_pci22_ops; mutex_init(&vpd->lock); vpd->cap =3D cap; vpd->busy =3D false; diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 481b184..93be760 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1941,6 +1941,15 @@ static void __devinit quirk_netmos(struct pci_dev *d= ev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos); =20 +static void quirk_f0_vpd_link(struct pci_dev *dev) +{ + if ((dev->class >> 8) !=3D PCI_CLASS_NETWORK_ETHERNET || + !dev->multifunction || !PCI_FUNC(dev->devfn)) + return; + dev->dev_flags |=3D PCI_DEV_FLAGS_VPD_REF_F0; +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_f0_vpd_link= ); + static void __devinit quirk_e100_interrupt(struct pci_dev *dev) { u16 command, pmcsr; @@ -2875,8 +2884,9 @@ static void __devinit fixup_ti816x_class(struct pci_d= ev* dev) { /* TI 816x devices do not have class code set when in PCIe boot mode */ if (dev->class =3D=3D PCI_CLASS_NOT_DEFINED) { - dev_info(&dev->dev, "Setting PCI class for 816x PCIe device\n"); - dev->class =3D PCI_CLASS_MULTIMEDIA_VIDEO; + dev->class =3D PCI_CLASS_MULTIMEDIA_VIDEO << 8; + dev_info(&dev->dev, "PCI class overridden (%#08x -> %#08x)\n", + PCI_CLASS_NOT_DEFINED, dev->class); } } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_TI, 0xb800, fixup_ti816x_class); diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index 221875e..735b324 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -1029,11 +1029,26 @@ restart: fc_fcp_pkt_hold(fsp); spin_unlock_irqrestore(&si->scsi_queue_lock, flags); =20 - if (!fc_fcp_lock_pkt(fsp)) { + spin_lock_bh(&fsp->scsi_pkt_lock); + if (!(fsp->state & FC_SRB_COMPL)) { + fsp->state |=3D FC_SRB_COMPL; + /* + * TODO: dropping scsi_pkt_lock and then reacquiring + * again around fc_fcp_cleanup_cmd() is required, + * since fc_fcp_cleanup_cmd() calls into + * fc_seq_set_resp() and that func preempts cpu using + * schedule. May be schedule and related code should be + * removed instead of unlocking here to avoid scheduling + * while atomic bug. + */ + spin_unlock_bh(&fsp->scsi_pkt_lock); + fc_fcp_cleanup_cmd(fsp, error); + + spin_lock_bh(&fsp->scsi_pkt_lock); fc_io_compl(fsp); - fc_fcp_unlock_pkt(fsp); } + spin_unlock_bh(&fsp->scsi_pkt_lock); =20 fc_fcp_pkt_release(fsp); spin_lock_irqsave(&si->scsi_queue_lock, flags); diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 2794a30..8771c03 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -2906,10 +2906,10 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls= _conn) { struct iscsi_conn *conn =3D cls_conn->dd_data; struct iscsi_session *session =3D conn->session; - unsigned long flags; =20 del_timer_sync(&conn->transport_timer); =20 + mutex_lock(&session->eh_mutex); spin_lock_bh(&session->lock); conn->c_stage =3D ISCSI_CONN_CLEANUP_WAIT; if (session->leadconn =3D=3D conn) { @@ -2921,28 +2921,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_= conn) } spin_unlock_bh(&session->lock); =20 - /* - * Block until all in-progress commands for this connection - * time out or fail. - */ - for (;;) { - spin_lock_irqsave(session->host->host_lock, flags); - if (!session->host->host_busy) { /* OK for ERL =3D=3D 0 */ - spin_unlock_irqrestore(session->host->host_lock, flags); - break; - } - spin_unlock_irqrestore(session->host->host_lock, flags); - msleep_interruptible(500); - iscsi_conn_printk(KERN_INFO, conn, "iscsi conn_destroy(): " - "host_busy %d host_failed %d\n", - session->host->host_busy, - session->host->host_failed); - /* - * force eh_abort() to unblock - */ - wake_up(&conn->ehwait); - } - /* flush queued up work because we free the connection below */ iscsi_suspend_tx(conn); =20 @@ -2955,6 +2933,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_c= onn) if (session->leadconn =3D=3D conn) session->leadconn =3D NULL; spin_unlock_bh(&session->lock); + mutex_unlock(&session->eh_mutex); =20 iscsi_destroy_conn(cls_conn); } diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index dc25bee..2ecc2d6 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -799,6 +799,10 @@ static irqreturn_t ssp_int(int irq, void *dev_id) if (!(sccr1_reg & SSCR1_TIE)) mask &=3D ~SSSR_TFS; =20 + /* Ignore RX timeout interrupt if it is disabled */ + if (!(sccr1_reg & SSCR1_TINTE)) + mask &=3D ~SSSR_TINT; + if (!(status & mask)) return IRQ_NONE; =20 diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/isc= si_target.c index 59fb984..7c33cbb 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -979,7 +979,7 @@ static int iscsit_handle_scsi_cmd( if (cmd->targ_xfer_tag =3D=3D 0xFFFFFFFF) cmd->targ_xfer_tag =3D conn->sess->targ_xfer_tag++; spin_unlock_bh(&conn->sess->ttt_lock); - } else if (hdr->flags & ISCSI_FLAG_CMD_WRITE) + } else cmd->targ_xfer_tag =3D 0xFFFFFFFF; cmd->cmd_sn =3D hdr->cmdsn; cmd->exp_stat_sn =3D hdr->exp_statsn; diff --git a/drivers/target/target_core_device.c b/drivers/target/target_co= re_device.c index 6993961..c3cf95e 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -668,11 +668,8 @@ int target_report_luns(struct se_task *se_task) * coming via a target_core_mod PASSTHROUGH op, and not through * a $FABRIC_MOD. In that case, report LUN=3D0 only. */ - if (!se_sess) { - int_to_scsilun(0, (struct scsi_lun *)&buf[offset]); - lun_count =3D 1; + if (!se_sess) goto done; - } =20 spin_lock_irq(&se_sess->se_node_acl->device_list_lock); for (i =3D 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { @@ -699,6 +696,14 @@ int target_report_luns(struct se_task *se_task) * See SPC3 r07, page 159. */ done: + /* + * If no LUNs are accessible, report virtual LUN 0. + */ + if (lun_count =3D=3D 0) { + int_to_scsilun(0, (struct scsi_lun *)&buf[offset]); + lun_count =3D 1; + } + lun_count *=3D 8; buf[0] =3D ((lun_count >> 24) & 0xff); buf[1] =3D ((lun_count >> 16) & 0xff); diff --git a/drivers/tty/serial/8250_pnp.c b/drivers/tty/serial/8250_pnp.c index a2f2365..add2096 100644 --- a/drivers/tty/serial/8250_pnp.c +++ b/drivers/tty/serial/8250_pnp.c @@ -42,6 +42,12 @@ static const struct pnp_device_id pnp_dev_table[] =3D { { "AEI1240", 0 }, /* Rockwell 56K ACF II Fax+Data+Voice Modem */ { "AKY1021", 0 /*SPCI_FL_NO_SHIRQ*/ }, + /* + * ALi Fast Infrared Controller + * Native driver (ali-ircc) is broken so at least + * it can be used with irtty-sir. + */ + { "ALI5123", 0 }, /* AZT3005 PnP SOUND DEVICE */ { "AZT4001", 0 }, /* Best Data Products Inc. Smart One 336F PnP Modem */ diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 0276db3..478d71b 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -114,7 +114,7 @@ static void usb_parse_ss_endpoint_companion(struct devi= ce *ddev, int cfgno, cfgno, inum, asnum, ep->desc.bEndpointAddress); ep->ss_ep_comp.bmAttributes =3D 16; } else if (usb_endpoint_xfer_isoc(&ep->desc) && - desc->bmAttributes > 2) { + USB_SS_MULT(desc->bmAttributes) > 3) { dev_warn(ddev, "Isoc endpoint has Mult of %d in " "config %d interface %d altsetting %d ep %d: " "setting to 3\n", desc->bmAttributes + 1, @@ -123,7 +123,8 @@ static void usb_parse_ss_endpoint_companion(struct devi= ce *ddev, int cfgno, } =20 if (usb_endpoint_xfer_isoc(&ep->desc)) - max_tx =3D (desc->bMaxBurst + 1) * (desc->bmAttributes + 1) * + max_tx =3D (desc->bMaxBurst + 1) * + (USB_SS_MULT(desc->bmAttributes)) * usb_endpoint_maxp(&ep->desc); else if (usb_endpoint_xfer_int(&ep->desc)) max_tx =3D usb_endpoint_maxp(&ep->desc) * diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-ud= c.c index 9aa1cbb..9716d61 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -1052,7 +1052,7 @@ static void set_feature(struct m66592 *m66592, struct= usb_ctrlrequest *ctrl) tmp =3D m66592_read(m66592, M66592_INTSTS0) & M66592_CTSQ; udelay(1); - } while (tmp !=3D M66592_CS_IDST || timeout-- > 0); + } while (tmp !=3D M66592_CS_IDST && timeout-- > 0); =20 if (tmp =3D=3D M66592_CS_IDST) m66592_bset(m66592, diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index da487fd..cf995d4 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -272,6 +272,10 @@ static void ehci_fsl_usb_setup(struct ehci_hcd *ehci) out_be32(non_ehci + FSL_SOC_USB_SNOOP2, 0x80000000 | SNOOP_SIZE_2GB); #endif =20 + /* Deal with USB erratum A-005275 */ + if (pdata->has_fsl_erratum_a005275 =3D=3D 1) + ehci->has_fsl_hs_errata =3D 1; + if ((pdata->operating_mode =3D=3D FSL_USB2_DR_HOST) || (pdata->operating_mode =3D=3D FSL_USB2_DR_OTG)) ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0); diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 4527b90..313a47d 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -1049,6 +1049,13 @@ static int ehci_hub_control ( */ ehci->reset_done [wIndex] =3D jiffies + msecs_to_jiffies (50); + + /* + * Force full-speed connect for FSL high-speed + * erratum; disable HS Chirp by setting PFSC bit + */ + if (ehci_has_fsl_hs_errata(ehci)) + temp |=3D (1 << PORTSC_FSL_PFSC); } ehci_writel(ehci, temp, status_reg); break; diff --git a/drivers/usb/host/ehci-sysfs.c b/drivers/usb/host/ehci-sysfs.c index 14ced00..ddaaead 100644 --- a/drivers/usb/host/ehci-sysfs.c +++ b/drivers/usb/host/ehci-sysfs.c @@ -29,7 +29,7 @@ static ssize_t show_companion(struct device *dev, int count =3D PAGE_SIZE; char *ptr =3D buf; =20 - ehci =3D hcd_to_ehci(bus_to_hcd(dev_get_drvdata(dev))); + ehci =3D hcd_to_ehci(dev_get_drvdata(dev)); nports =3D HCS_N_PORTS(ehci->hcs_params); =20 for (index =3D 0; index < nports; ++index) { @@ -54,7 +54,7 @@ static ssize_t store_companion(struct device *dev, struct ehci_hcd *ehci; int portnum, new_owner; =20 - ehci =3D hcd_to_ehci(bus_to_hcd(dev_get_drvdata(dev))); + ehci =3D hcd_to_ehci(dev_get_drvdata(dev)); new_owner =3D PORT_OWNER; /* Owned by companion */ if (sscanf(buf, "%d", &portnum) !=3D 1) return -EINVAL; @@ -85,7 +85,7 @@ static ssize_t show_uframe_periodic_max(struct device *de= v, struct ehci_hcd *ehci; int n; =20 - ehci =3D hcd_to_ehci(bus_to_hcd(dev_get_drvdata(dev))); + ehci =3D hcd_to_ehci(dev_get_drvdata(dev)); n =3D scnprintf(buf, PAGE_SIZE, "%d\n", ehci->uframe_periodic_max); return n; } @@ -102,7 +102,7 @@ static ssize_t store_uframe_periodic_max(struct device = *dev, unsigned long flags; ssize_t ret; =20 - ehci =3D hcd_to_ehci(bus_to_hcd(dev_get_drvdata(dev))); + ehci =3D hcd_to_ehci(dev_get_drvdata(dev)); if (kstrtouint(buf, 0, &uframe_periodic_max) < 0) return -EINVAL; =20 @@ -167,6 +167,9 @@ static inline int create_sysfs_files(struct ehci_hcd *e= hci) struct device *controller =3D ehci_to_hcd(ehci)->self.controller; int i =3D 0; =20 + if (dev_get_drvdata(controller) !=3D ehci_to_hcd(ehci)) + return 0; + /* with integrated TT there is no companion! */ if (!ehci_is_TDI(ehci)) i =3D device_create_file(controller, &dev_attr_companion); @@ -182,6 +185,9 @@ static inline void remove_sysfs_files(struct ehci_hcd *= ehci) { struct device *controller =3D ehci_to_hcd(ehci)->self.controller; =20 + if (dev_get_drvdata(controller) !=3D ehci_to_hcd(ehci)) + return; + /* with integrated TT there is no companion! */ if (!ehci_is_TDI(ehci)) device_remove_file(controller, &dev_attr_companion); diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index b65912d..bd8adbb 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -136,6 +136,7 @@ struct ehci_hcd { /* one per controller */ /* SILICON QUIRKS */ unsigned no_selective_suspend:1; unsigned has_fsl_port_bug:1; /* FreeScale */ + unsigned has_fsl_hs_errata:1; /* Freescale HS quirk */ unsigned big_endian_mmio:1; unsigned big_endian_desc:1; unsigned big_endian_capbase:1; @@ -612,6 +613,17 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int po= rtsc) #define ehci_has_fsl_portno_bug(e) (0) #endif =20 +#define PORTSC_FSL_PFSC 24 /* Port Force Full-Speed Connect */ + +#if defined(CONFIG_PPC_85xx) +/* Some Freescale processors have an erratum (USB A-005275) in which + * incoming packets get corrupted in HS mode + */ +#define ehci_has_fsl_hs_errata(e) ((e)->has_fsl_hs_errata) +#else +#define ehci_has_fsl_hs_errata(e) (0) +#endif + /* * While most USB host controllers implement their registers in * little-endian format, a minority (celleb companion chip) implement diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr= -of.c index 5a42cf0..ac19ee5 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -166,6 +166,10 @@ static int __devinit fsl_usb2_mph_dr_of_probe(struct p= latform_device *ofdev) =20 prop =3D of_get_property(np, "phy_type", NULL); pdata->phy_mode =3D determine_usb_phy(prop); + if (of_get_property(np, "fsl,usb-erratum-a005275", NULL)) + pdata->has_fsl_erratum_a005275 =3D 1; + else + pdata->has_fsl_erratum_a005275 =3D 0; =20 for (i =3D 0; i < ARRAY_SIZE(dev_data->drivers); i++) { if (!dev_data->drivers[i]) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index d5d2af5..ab023b1 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1403,10 +1403,10 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, * use Event Data TRBs, and we don't chain in a link TRB on short * transfers, we're basically dividing by 1. * - * xHCI 1.0 specification indicates that the Average TRB Length should - * be set to 8 for control endpoints. + * xHCI 1.0 and 1.1 specification indicates that the Average TRB Length + * should be set to 8 for control endpoints. */ - if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version =3D=3D 0x10= 0) + if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version >=3D 0x100) ep_ctx->tx_info |=3D cpu_to_le32(AVG_TRB_LENGTH_FOR_EP(8)); else ep_ctx->tx_info |=3D diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index a47e29a..dc8e5a8 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -85,7 +85,7 @@ dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, return 0; /* offset in TRBs */ segment_offset =3D trb - seg->trbs; - if (segment_offset > TRBS_PER_SEGMENT) + if (segment_offset >=3D TRBS_PER_SEGMENT) return 0; return seg->dma + (segment_offset * sizeof(*trb)); } @@ -350,6 +350,15 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) ret =3D handshake(xhci, &xhci->op_regs->cmd_ring, CMD_RING_RUNNING, 0, 5 * 1000 * 1000); if (ret < 0) { + /* we are about to kill xhci, give it one more chance */ + xhci_write_64(xhci, temp_64 | CMD_RING_ABORT, + &xhci->op_regs->cmd_ring); + udelay(1000); + ret =3D handshake(xhci, &xhci->op_regs->cmd_ring, + CMD_RING_RUNNING, 0, 3 * 1000 * 1000); + if (ret =3D=3D 0) + return 0; + xhci_err(xhci, "Stopped the command ring failed, " "maybe the host is dead\n"); xhci->xhc_state |=3D XHCI_STATE_DYING; @@ -3423,8 +3432,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t m= em_flags, if (start_cycle =3D=3D 0) field |=3D 0x1; =20 - /* xHCI 1.0 6.4.1.2.1: Transfer Type field */ - if (xhci->hci_version =3D=3D 0x100) { + /* xHCI 1.0/1.1 6.4.1.2.1: Transfer Type field */ + if (xhci->hci_version >=3D 0x100) { if (urb->transfer_buffer_length > 0) { if (setup->bRequestType & USB_DIR_IN) field |=3D TRB_TX_TYPE(TRB_DATA_IN); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 950a8cc..2f51dec 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -141,7 +141,8 @@ static int xhci_start(struct xhci_hcd *xhci) "waited %u microseconds.\n", XHCI_MAX_HALT_USEC); if (!ret) - xhci->xhc_state &=3D ~XHCI_STATE_HALTED; + xhci->xhc_state &=3D ~(XHCI_STATE_HALTED | XHCI_STATE_DYING); + return ret; } =20 diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8257d3b..4ffaa9d 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -629,6 +629,10 @@ static struct usb_device_id id_table_combined [] =3D { { USB_DEVICE(FTDI_VID, FTDI_NT_ORIONLXM_PID), .driver_info =3D (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FTDI_VID, FTDI_SYNAPSE_SS200_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX2_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX2WI_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX3_PID) }, /* * ELV devices: */ diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_si= o_ids.h index e4a57bb..7d11642 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -568,6 +568,14 @@ */ #define FTDI_SYNAPSE_SS200_PID 0x9090 /* SS200 - SNAP Stick 200 */ =20 +/* + * CustomWare / ShipModul NMEA multiplexers product ids (FTDI_VID) + */ +#define FTDI_CUSTOMWARE_MINIPLEX_PID 0xfd48 /* MiniPlex first generation N= MEA Multiplexer */ +#define FTDI_CUSTOMWARE_MINIPLEX2_PID 0xfd49 /* MiniPlex-USB and MiniPlex-= 2 series */ +#define FTDI_CUSTOMWARE_MINIPLEX2WI_PID 0xfd4a /* MiniPlex-2Wi */ +#define FTDI_CUSTOMWARE_MINIPLEX3_PID 0xfd4b /* MiniPlex-3 series */ + =20 /********************************/ /** third-party VID/PID combos **/ diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 64ea95d..7e6d2ec 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -276,6 +276,10 @@ static void option_instat_callback(struct urb *urb); #define ZTE_PRODUCT_MF622 0x0001 #define ZTE_PRODUCT_MF628 0x0015 #define ZTE_PRODUCT_MF626 0x0031 +#define ZTE_PRODUCT_ZM8620_X 0x0396 +#define ZTE_PRODUCT_ME3620_MBIM 0x0426 +#define ZTE_PRODUCT_ME3620_X 0x1432 +#define ZTE_PRODUCT_ME3620_L 0x1433 #define ZTE_PRODUCT_CDMA_TECH 0xfffe #define ZTE_PRODUCT_AC8710 0xfff1 #define ZTE_PRODUCT_AC2726 0xfff5 @@ -547,6 +551,18 @@ static const struct option_blacklist_info zte_mc2716_z= _blacklist =3D { .sendsetup =3D BIT(1) | BIT(2) | BIT(3), }; =20 +static const struct option_blacklist_info zte_me3620_mbim_blacklist =3D { + .reserved =3D BIT(2) | BIT(3) | BIT(4), +}; + +static const struct option_blacklist_info zte_me3620_xl_blacklist =3D { + .reserved =3D BIT(3) | BIT(4) | BIT(5), +}; + +static const struct option_blacklist_info zte_zm8620_x_blacklist =3D { + .reserved =3D BIT(3) | BIT(4) | BIT(5), +}; + static const struct option_blacklist_info huawei_cdc12_blacklist =3D { .reserved =3D BIT(1) | BIT(2), }; @@ -1578,6 +1594,14 @@ static const struct usb_device_id option_ids[] =3D { .driver_info =3D (kernel_ulong_t)&zte_ad3812_z_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, = 0xff, 0xff), .driver_info =3D (kernel_ulong_t)&zte_mc2716_z_blacklist }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_L), + .driver_info =3D (kernel_ulong_t)&zte_me3620_xl_blacklist }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_MBIM), + .driver_info =3D (kernel_ulong_t)&zte_me3620_mbim_blacklist }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_X), + .driver_info =3D (kernel_ulong_t)&zte_me3620_xl_blacklist }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ZM8620_X), + .driver_info =3D (kernel_ulong_t)&zte_zm8620_x_blacklist }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index db9e54a..f34c0dd 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -303,6 +303,7 @@ static const struct usb_device_id id_table[] =3D { { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68AA, 0xFF, 0xFF, 0xFF), .driver_info =3D (kernel_ulong_t)&direct_ip_interface_blacklist }, + { USB_DEVICE(0x1199, 0x68AB) }, /* Sierra Wireless AR8550 */ /* AT&T Direct IP LTE modems */ { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68AA, 0xFF, 0xFF, 0xFF), .driver_info =3D (kernel_ulong_t)&direct_ip_interface_blacklist diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.= c index 5481809..75670b5 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -143,6 +143,8 @@ static int whiteheat_firmware_download(struct usb_seri= al *serial, static int whiteheat_firmware_attach(struct usb_serial *serial); =20 /* function prototypes for the Connect Tech WhiteHEAT serial converter */ +static int whiteheat_probe(struct usb_serial *serial, + const struct usb_device_id *id); static int whiteheat_attach(struct usb_serial *serial); static void whiteheat_release(struct usb_serial *serial); static int whiteheat_open(struct tty_struct *tty, @@ -188,6 +190,7 @@ static struct usb_serial_driver whiteheat_device =3D { .usb_driver =3D &whiteheat_driver, .id_table =3D id_table_std, .num_ports =3D 4, + .probe =3D whiteheat_probe, .attach =3D whiteheat_attach, .release =3D whiteheat_release, .open =3D whiteheat_open, @@ -387,6 +390,34 @@ static int whiteheat_firmware_attach(struct usb_serial= *serial) /*************************************************************************= **** * Connect Tech's White Heat serial driver functions *************************************************************************= ****/ + +static int whiteheat_probe(struct usb_serial *serial, + const struct usb_device_id *id) +{ + struct usb_host_interface *iface_desc; + struct usb_endpoint_descriptor *endpoint; + size_t num_bulk_in =3D 0; + size_t num_bulk_out =3D 0; + size_t min_num_bulk; + unsigned int i; + + iface_desc =3D serial->interface->cur_altsetting; + + for (i =3D 0; i < iface_desc->desc.bNumEndpoints; i++) { + endpoint =3D &iface_desc->endpoint[i].desc; + if (usb_endpoint_is_bulk_in(endpoint)) + ++num_bulk_in; + if (usb_endpoint_is_bulk_out(endpoint)) + ++num_bulk_out; + } + + min_num_bulk =3D COMMAND_PORT + 1; + if (num_bulk_in < min_num_bulk || num_bulk_out < min_num_bulk) + return -ENODEV; + + return 0; +} + static int whiteheat_attach(struct usb_serial *serial) { struct usb_serial_port *command_port; diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 080b186..5027662 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -60,7 +60,7 @@ static int use_ptemod; struct gntdev_priv { struct list_head maps; /* lock protects maps from concurrent changes */ - spinlock_t lock; + struct mutex lock; struct mm_struct *mm; struct mmu_notifier mn; }; @@ -395,7 +395,7 @@ static void mn_invl_range_start(struct mmu_notifier *mn= , unsigned long mstart, mend; int err; =20 - spin_lock(&priv->lock); + mutex_lock(&priv->lock); list_for_each_entry(map, &priv->maps, next) { if (!map->vma) continue; @@ -414,7 +414,7 @@ static void mn_invl_range_start(struct mmu_notifier *mn= , (mend - mstart) >> PAGE_SHIFT); WARN_ON(err); } - spin_unlock(&priv->lock); + mutex_unlock(&priv->lock); } =20 static void mn_invl_page(struct mmu_notifier *mn, @@ -431,7 +431,7 @@ static void mn_release(struct mmu_notifier *mn, struct grant_map *map; int err; =20 - spin_lock(&priv->lock); + mutex_lock(&priv->lock); list_for_each_entry(map, &priv->maps, next) { if (!map->vma) continue; @@ -441,7 +441,7 @@ static void mn_release(struct mmu_notifier *mn, err =3D unmap_grant_pages(map, /* offset */ 0, map->count); WARN_ON(err); } - spin_unlock(&priv->lock); + mutex_unlock(&priv->lock); } =20 struct mmu_notifier_ops gntdev_mmu_ops =3D { @@ -462,7 +462,7 @@ static int gntdev_open(struct inode *inode, struct file= *flip) return -ENOMEM; =20 INIT_LIST_HEAD(&priv->maps); - spin_lock_init(&priv->lock); + mutex_init(&priv->lock); =20 if (use_ptemod) { priv->mm =3D get_task_mm(current); @@ -493,11 +493,13 @@ static int gntdev_release(struct inode *inode, struct= file *flip) =20 pr_debug("priv %p\n", priv); =20 + mutex_lock(&priv->lock); while (!list_empty(&priv->maps)) { map =3D list_entry(priv->maps.next, struct grant_map, next); list_del(&map->next); gntdev_put_map(map); } + mutex_unlock(&priv->lock); =20 if (use_ptemod) mmu_notifier_unregister(&priv->mn, priv->mm); @@ -535,10 +537,10 @@ static long gntdev_ioctl_map_grant_ref(struct gntdev_= priv *priv, return err; } =20 - spin_lock(&priv->lock); + mutex_lock(&priv->lock); gntdev_add_map(priv, map); op.index =3D map->index << PAGE_SHIFT; - spin_unlock(&priv->lock); + mutex_unlock(&priv->lock); =20 if (copy_to_user(u, &op, sizeof(op)) !=3D 0) return -EFAULT; @@ -557,13 +559,13 @@ static long gntdev_ioctl_unmap_grant_ref(struct gntde= v_priv *priv, return -EFAULT; pr_debug("priv %p, del %d+%d\n", priv, (int)op.index, (int)op.count); =20 - spin_lock(&priv->lock); + mutex_lock(&priv->lock); map =3D gntdev_find_map_index(priv, op.index >> PAGE_SHIFT, op.count); if (map) { list_del(&map->next); err =3D 0; } - spin_unlock(&priv->lock); + mutex_unlock(&priv->lock); if (map) gntdev_put_map(map); return err; @@ -608,7 +610,7 @@ static long gntdev_ioctl_notify(struct gntdev_priv *pri= v, void __user *u) if (op.action & ~(UNMAP_NOTIFY_CLEAR_BYTE|UNMAP_NOTIFY_SEND_EVENT)) return -EINVAL; =20 - spin_lock(&priv->lock); + mutex_lock(&priv->lock); =20 list_for_each_entry(map, &priv->maps, next) { uint64_t begin =3D map->index << PAGE_SHIFT; @@ -631,7 +633,7 @@ static long gntdev_ioctl_notify(struct gntdev_priv *pri= v, void __user *u) map->notify.event =3D op.event_channel_port; rc =3D 0; unlock_out: - spin_unlock(&priv->lock); + mutex_unlock(&priv->lock); return rc; } =20 @@ -676,7 +678,7 @@ static int gntdev_mmap(struct file *flip, struct vm_are= a_struct *vma) pr_debug("map %d+%d at %lx (pgoff %lx)\n", index, count, vma->vm_start, vma->vm_pgoff); =20 - spin_lock(&priv->lock); + mutex_lock(&priv->lock); map =3D gntdev_find_map_index(priv, index, count); if (!map) goto unlock_out; @@ -711,7 +713,7 @@ static int gntdev_mmap(struct file *flip, struct vm_are= a_struct *vma) map->flags |=3D GNTMAP_readonly; } =20 - spin_unlock(&priv->lock); + mutex_unlock(&priv->lock); =20 if (use_ptemod) { err =3D apply_to_page_range(vma->vm_mm, vma->vm_start, @@ -739,11 +741,11 @@ static int gntdev_mmap(struct file *flip, struct vm_a= rea_struct *vma) return 0; =20 unlock_out: - spin_unlock(&priv->lock); + mutex_unlock(&priv->lock); return err; =20 out_unlock_put: - spin_unlock(&priv->lock); + mutex_unlock(&priv->lock); out_put_map: if (use_ptemod) map->vma =3D NULL; diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 05937a8..9a837a8 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -2444,7 +2444,8 @@ static int submit_extent_page(int rw, struct extent_i= o_tree *tree, bio_end_io_t end_io_func, int mirror_num, unsigned long prev_bio_flags, - unsigned long bio_flags) + unsigned long bio_flags, + bool force_bio_submit) { int ret =3D 0; struct bio *bio; @@ -2463,6 +2464,7 @@ static int submit_extent_page(int rw, struct extent_i= o_tree *tree, sector; =20 if (prev_bio_flags !=3D bio_flags || !contig || + force_bio_submit || (tree->ops && tree->ops->merge_bio_hook && tree->ops->merge_bio_hook(page, offset, page_size, bio, bio_flags)) || @@ -2519,7 +2521,8 @@ static int __extent_read_full_page(struct extent_io_t= ree *tree, struct page *page, get_extent_t *get_extent, struct bio **bio, int mirror_num, - unsigned long *bio_flags) + unsigned long *bio_flags, + u64 *prev_em_start) { struct inode *inode =3D page->mapping->host; u64 start =3D (u64)page->index << PAGE_CACHE_SHIFT; @@ -2575,6 +2578,8 @@ static int __extent_read_full_page(struct extent_io_t= ree *tree, } } while (cur <=3D end) { + bool force_bio_submit =3D false; + if (cur >=3D last_byte) { char *userpage; struct extent_state *cached =3D NULL; @@ -2621,6 +2626,49 @@ static int __extent_read_full_page(struct extent_io_= tree *tree, block_start =3D em->block_start; if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) block_start =3D EXTENT_MAP_HOLE; + + /* + * If we have a file range that points to a compressed extent + * and it's followed by a consecutive file range that points to + * to the same compressed extent (possibly with a different + * offset and/or length, so it either points to the whole extent + * or only part of it), we must make sure we do not submit a + * single bio to populate the pages for the 2 ranges because + * this makes the compressed extent read zero out the pages + * belonging to the 2nd range. Imagine the following scenario: + * + * File layout + * [0 - 8K] [8K - 24K] + * | | + * | | + * points to extent X, points to extent X, + * offset 4K, length of 8K offset 0, length 16K + * + * [extent X, compressed length =3D 4K uncompressed length =3D 16K] + * + * If the bio to read the compressed extent covers both ranges, + * it will decompress extent X into the pages belonging to the + * first range and then it will stop, zeroing out the remaining + * pages that belong to the other range that points to extent X. + * So here we make sure we submit 2 bios, one for the first + * range and another one for the third range. Both will target + * the same physical extent from disk, but we can't currently + * make the compressed bio endio callback populate the pages + * for both ranges because each compressed bio is tightly + * coupled with a single extent map, and each range can have + * an extent map with a different offset value relative to the + * uncompressed data of our extent and different lengths. This + * is a corner case so we prioritize correctness over + * non-optimal behavior (submitting 2 bios for the same extent). + */ + if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags) && + prev_em_start && *prev_em_start !=3D (u64)-1 && + *prev_em_start !=3D em->orig_start) + force_bio_submit =3D true; + + if (prev_em_start) + *prev_em_start =3D em->orig_start; + free_extent_map(em); em =3D NULL; =20 @@ -2675,7 +2723,8 @@ static int __extent_read_full_page(struct extent_io_t= ree *tree, bdev, bio, pnr, end_bio_extent_readpage, mirror_num, *bio_flags, - this_bio_flag); + this_bio_flag, + force_bio_submit); nr++; *bio_flags =3D this_bio_flag; } @@ -2701,7 +2750,7 @@ int extent_read_full_page(struct extent_io_tree *tree= , struct page *page, int ret; =20 ret =3D __extent_read_full_page(tree, page, get_extent, &bio, mirror_num, - &bio_flags); + &bio_flags, NULL); if (bio) ret =3D submit_one_bio(READ, bio, mirror_num, bio_flags); return ret; @@ -2960,7 +3009,7 @@ static int __extent_writepage(struct page *page, stru= ct writeback_control *wbc, sector, iosize, pg_offset, bdev, &epd->bio, max_nr, end_bio_extent_writepage, - 0, 0, 0); + 0, 0, 0, false); if (ret) SetPageError(page); } @@ -3219,6 +3268,7 @@ int extent_readpages(struct extent_io_tree *tree, struct bio *bio =3D NULL; unsigned page_idx; unsigned long bio_flags =3D 0; + u64 prev_em_start =3D (u64)-1; =20 for (page_idx =3D 0; page_idx < nr_pages; page_idx++) { struct page *page =3D list_entry(pages->prev, struct page, lru); @@ -3228,7 +3278,8 @@ int extent_readpages(struct extent_io_tree *tree, if (!add_to_page_cache_lru(page, mapping, page->index, GFP_NOFS)) { __extent_read_full_page(tree, page, get_extent, - &bio, 0, &bio_flags); + &bio, 0, &bio_flags, + &prev_em_start); } page_cache_release(page); } @@ -3998,6 +4049,7 @@ int read_extent_buffer_pages(struct extent_io_tree *t= ree, unsigned long num_pages; struct bio *bio =3D NULL; unsigned long bio_flags =3D 0; + u64 prev_em_start =3D (u64)-1; =20 if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags)) return 0; @@ -4053,7 +4105,8 @@ int read_extent_buffer_pages(struct extent_io_tree *t= ree, ClearPageError(page); err =3D __extent_read_full_page(tree, page, get_extent, &bio, - mirror_num, &bio_flags); + mirror_num, &bio_flags, + &prev_em_start); if (err) ret =3D err; } else { diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 622d322..cb10cb9 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -3518,7 +3518,8 @@ void btrfs_evict_inode(struct inode *inode) goto no_delete; } /* do we really want it for ->i_nlink > 0 and zero btrfs_root_refs? */ - btrfs_wait_ordered_range(inode, 0, (u64)-1); + if (!special_file(inode->i_mode)) + btrfs_wait_ordered_range(inode, 0, (u64)-1); =20 if (root->fs_info->log_root_recovering) { BUG_ON(!list_empty(&BTRFS_I(inode)->i_orphan)); diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 3c981db..8bfafe5 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -361,8 +361,10 @@ static int ceph_show_options(struct seq_file *m, struc= t vfsmount *mnt) if (opt->flags & CEPH_OPT_NOCRC) seq_puts(m, ",nocrc"); =20 - if (opt->name) - seq_printf(m, ",name=3D%s", opt->name); + if (opt->name) { + seq_puts(m, ",name=3D"); + seq_escape(m, opt->name, ", \t\n\\"); + } if (opt->key) seq_puts(m, ",secret=3D"); =20 @@ -405,7 +407,7 @@ static int ceph_show_options(struct seq_file *m, struct= vfsmount *mnt) if (fsopt->max_readdir_bytes !=3D CEPH_MAX_READDIR_BYTES_DEFAULT) seq_printf(m, ",readdir_max_bytes=3D%d", fsopt->max_readdir_bytes); if (strcmp(fsopt->snapdir_name, CEPH_SNAPDIRNAME_DEFAULT)) - seq_printf(m, ",snapdirname=3D%s", fsopt->snapdir_name); + seq_show_option(m, "snapdirname", fsopt->snapdir_name); return 0; } =20 diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index b4675bd..af95386 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -388,6 +388,48 @@ find_domain_name(struct cifs_ses *ses, const struct nl= s_table *nls_cp) return 0; } =20 +/* Server has provided av pairs/target info in the type 2 challenge + * packet and we have plucked it and stored within smb session. + * We parse that blob here to find the server given timestamp + * as part of ntlmv2 authentication (or local current time as + * default in case of failure) + */ +static __le64 +find_timestamp(struct cifs_ses *ses) +{ + unsigned int attrsize; + unsigned int type; + unsigned int onesize =3D sizeof(struct ntlmssp2_name); + unsigned char *blobptr; + unsigned char *blobend; + struct ntlmssp2_name *attrptr; + + if (!ses->auth_key.len || !ses->auth_key.response) + return 0; + + blobptr =3D ses->auth_key.response; + blobend =3D blobptr + ses->auth_key.len; + + while (blobptr + onesize < blobend) { + attrptr =3D (struct ntlmssp2_name *) blobptr; + type =3D le16_to_cpu(attrptr->type); + if (type =3D=3D NTLMSSP_AV_EOL) + break; + blobptr +=3D 2; /* advance attr type */ + attrsize =3D le16_to_cpu(attrptr->length); + blobptr +=3D 2; /* advance attr size */ + if (blobptr + attrsize > blobend) + break; + if (type =3D=3D NTLMSSP_AV_TIMESTAMP) { + if (attrsize =3D=3D sizeof(u64)) + return *((__le64 *)blobptr); + } + blobptr +=3D attrsize; /* advance attr value */ + } + + return cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); +} + static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, const struct nls_table *nls_cp) { @@ -544,6 +586,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls= _table *nls_cp) struct ntlmv2_resp *buf; char ntlmv2_hash[16]; unsigned char *tiblob =3D NULL; /* target info blob */ + __le64 rsp_timestamp; =20 if (ses->server->secType =3D=3D RawNTLMSSP) { if (!ses->domainName) { @@ -561,6 +604,12 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nl= s_table *nls_cp) } } =20 + /* Must be within 5 minutes of the server (or in range +/-2h + * in case of Mac OS X), so simply carry over server timestamp + * (as Windows 7 does) + */ + rsp_timestamp =3D find_timestamp(ses); + baselen =3D CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp); tilen =3D ses->auth_key.len; tiblob =3D ses->auth_key.response; @@ -578,7 +627,8 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls= _table *nls_cp) (ses->auth_key.response + CIFS_SESS_KEY_SIZE); buf->blob_signature =3D cpu_to_le32(0x00000101); buf->reserved =3D 0; - buf->time =3D cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); + buf->time =3D rsp_timestamp; + get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); buf->reserved2 =3D 0; =20 diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 25bb97f..d955b8e 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -381,10 +381,10 @@ cifs_show_options(struct seq_file *s, struct vfsmount= *m) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) seq_printf(s, ",multiuser"); else if (tcon->ses->user_name) - seq_printf(s, ",username=3D%s", tcon->ses->user_name); + seq_show_option(s, "username", tcon->ses->user_name); =20 if (tcon->ses->domainName) - seq_printf(s, ",domain=3D%s", tcon->ses->domainName); + seq_show_option(s, "domain", tcon->ses->domainName); =20 if (srcaddr->sa_family !=3D AF_UNSPEC) { struct sockaddr_in *saddr4; diff --git a/fs/dcache.c b/fs/dcache.c index 8a35300..46265f5 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2452,6 +2452,8 @@ static int prepend_path(const struct path *path, { struct dentry *dentry =3D path->dentry; struct vfsmount *vfsmnt =3D path->mnt; + char *orig_buffer =3D *buffer; + int orig_len =3D *buflen; bool slash =3D false; int error =3D 0; =20 @@ -2459,6 +2461,14 @@ static int prepend_path(const struct path *path, struct dentry * parent; =20 if (dentry =3D=3D vfsmnt->mnt_root || IS_ROOT(dentry)) { + /* Escaped? */ + if (dentry !=3D vfsmnt->mnt_root) { + *buffer =3D orig_buffer; + *buflen =3D orig_len; + slash =3D false; + error =3D 3; + goto global_root; + } /* Global root? */ if (vfsmnt->mnt_parent =3D=3D vfsmnt) { goto global_root; diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c index 534c1d4..eba8f1d 100644 --- a/fs/ecryptfs/dentry.c +++ b/fs/ecryptfs/dentry.c @@ -55,26 +55,26 @@ static int ecryptfs_d_revalidate(struct dentry *dentry,= struct nameidata *nd) =20 lower_dentry =3D ecryptfs_dentry_to_lower(dentry); lower_mnt =3D ecryptfs_dentry_to_lower_mnt(dentry); - if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate) - goto out; - if (nd) { - dentry_save =3D nd->path.dentry; - vfsmount_save =3D nd->path.mnt; - nd->path.dentry =3D lower_dentry; - nd->path.mnt =3D lower_mnt; - } - rc =3D lower_dentry->d_op->d_revalidate(lower_dentry, nd); - if (nd) { - nd->path.dentry =3D dentry_save; - nd->path.mnt =3D vfsmount_save; + if (lower_dentry->d_op && lower_dentry->d_op->d_revalidate) { + if (nd) { + dentry_save =3D nd->path.dentry; + vfsmount_save =3D nd->path.mnt; + nd->path.dentry =3D lower_dentry; + nd->path.mnt =3D lower_mnt; + } + rc =3D lower_dentry->d_op->d_revalidate(lower_dentry, nd); + if (nd) { + nd->path.dentry =3D dentry_save; + nd->path.mnt =3D vfsmount_save; + } } if (dentry->d_inode) { - struct inode *lower_inode =3D - ecryptfs_inode_to_lower(dentry->d_inode); + struct inode *inode =3D dentry->d_inode; =20 - fsstack_copy_attr_all(dentry->d_inode, lower_inode); + fsstack_copy_attr_all(inode, ecryptfs_inode_to_lower(inode)); + if (!inode->i_nlink) + return 0; } -out: return rc; } =20 diff --git a/fs/ext4/super.c b/fs/ext4/super.c index be4db0e..e2cf43b 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1018,10 +1018,10 @@ static inline void ext4_show_quota_options(struct s= eq_file *seq, } =20 if (sbi->s_qf_names[USRQUOTA]) - seq_printf(seq, ",usrjquota=3D%s", sbi->s_qf_names[USRQUOTA]); + seq_show_option(seq, "usrjquota", sbi->s_qf_names[USRQUOTA]); =20 if (sbi->s_qf_names[GRPQUOTA]) - seq_printf(seq, ",grpjquota=3D%s", sbi->s_qf_names[GRPQUOTA]); + seq_show_option(seq, "grpjquota", sbi->s_qf_names[GRPQUOTA]); =20 if (test_opt(sb, USRQUOTA)) seq_puts(seq, ",usrquota"); diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 71e4209..be2ece5 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -1298,11 +1298,11 @@ static int gfs2_show_options(struct seq_file *s, st= ruct vfsmount *mnt) if (is_ancestor(mnt->mnt_root, sdp->sd_master_dir)) seq_printf(s, ",meta"); if (args->ar_lockproto[0]) - seq_printf(s, ",lockproto=3D%s", args->ar_lockproto); + seq_show_option(s, "lockproto", args->ar_lockproto); if (args->ar_locktable[0]) - seq_printf(s, ",locktable=3D%s", args->ar_locktable); + seq_show_option(s, "locktable", args->ar_locktable); if (args->ar_hostdata[0]) - seq_printf(s, ",hostdata=3D%s", args->ar_hostdata); + seq_show_option(s, "hostdata", args->ar_hostdata); if (args->ar_spectator) seq_printf(s, ",spectator"); if (args->ar_localflocks) diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c index cdb41a1..8daea16 100644 --- a/fs/hfs/bnode.c +++ b/fs/hfs/bnode.c @@ -287,7 +287,6 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_= btree *tree, u32 cnid) page_cache_release(page); goto fail; } - page_cache_release(page); node->page[i] =3D page; } =20 @@ -397,11 +396,11 @@ node_error: =20 void hfs_bnode_free(struct hfs_bnode *node) { - //int i; + int i; =20 - //for (i =3D 0; i < node->tree->pages_per_bnode; i++) - // if (node->page[i]) - // page_cache_release(node->page[i]); + for (i =3D 0; i < node->tree->pages_per_bnode; i++) + if (node->page[i]) + page_cache_release(node->page[i]); kfree(node); } =20 diff --git a/fs/hfs/brec.c b/fs/hfs/brec.c index 92fb358..db240c5 100644 --- a/fs/hfs/brec.c +++ b/fs/hfs/brec.c @@ -132,13 +132,16 @@ skip: hfs_bnode_write(node, entry, data_off + key_len, entry_len); hfs_bnode_dump(node); =20 - if (new_node) { - /* update parent key if we inserted a key - * at the start of the first node - */ - if (!rec && new_node !=3D node) - hfs_brec_update_parent(fd); + /* + * update parent key if we inserted a key + * at the start of the node and it is not the new node + */ + if (!rec && new_node !=3D node) { + hfs_bnode_read_key(node, fd->search_key, data_off + size); + hfs_brec_update_parent(fd); + } =20 + if (new_node) { hfs_bnode_put(fd->bnode); if (!new_node->parent) { hfs_btree_inc_height(tree); @@ -167,9 +170,6 @@ skip: goto again; } =20 - if (!rec) - hfs_brec_update_parent(fd); - return 0; } =20 @@ -366,6 +366,8 @@ again: if (IS_ERR(parent)) return PTR_ERR(parent); __hfs_brec_find(parent, fd); + if (fd->record < 0) + return -ENOENT; hfs_bnode_dump(parent); rec =3D fd->record; =20 diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 1b55f70..cac813d 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -138,9 +138,9 @@ static int hfs_show_options(struct seq_file *seq, struc= t vfsmount *mnt) struct hfs_sb_info *sbi =3D HFS_SB(mnt->mnt_sb); =20 if (sbi->s_creator !=3D cpu_to_be32(0x3f3f3f3f)) - seq_printf(seq, ",creator=3D%.4s", (char *)&sbi->s_creator); + seq_show_option_n(seq, "creator", (char *)&sbi->s_creator, 4); if (sbi->s_type !=3D cpu_to_be32(0x3f3f3f3f)) - seq_printf(seq, ",type=3D%.4s", (char *)&sbi->s_type); + seq_show_option_n(seq, "type", (char *)&sbi->s_type, 4); seq_printf(seq, ",uid=3D%u,gid=3D%u", sbi->s_uid, sbi->s_gid); if (sbi->s_file_umask !=3D 0133) seq_printf(seq, ",file_umask=3D%o", sbi->s_file_umask); diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 1c42cc5..a1e9109 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -454,7 +454,6 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_= btree *tree, u32 cnid) page_cache_release(page); goto fail; } - page_cache_release(page); node->page[i] =3D page; } =20 @@ -566,13 +565,11 @@ node_error: =20 void hfs_bnode_free(struct hfs_bnode *node) { -#if 0 int i; =20 for (i =3D 0; i < node->tree->pages_per_bnode; i++) if (node->page[i]) page_cache_release(node->page[i]); -#endif kfree(node); } =20 diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c index bb62a5882..c8d6b4f 100644 --- a/fs/hfsplus/options.c +++ b/fs/hfsplus/options.c @@ -211,9 +211,9 @@ int hfsplus_show_options(struct seq_file *seq, struct v= fsmount *mnt) struct hfsplus_sb_info *sbi =3D HFSPLUS_SB(mnt->mnt_sb); =20 if (sbi->creator !=3D HFSPLUS_DEF_CR_TYPE) - seq_printf(seq, ",creator=3D%.4s", (char *)&sbi->creator); + seq_show_option_n(seq, "creator", (char *)&sbi->creator, 4); if (sbi->type !=3D HFSPLUS_DEF_CR_TYPE) - seq_printf(seq, ",type=3D%.4s", (char *)&sbi->type); + seq_show_option_n(seq, "type", (char *)&sbi->type, 4); seq_printf(seq, ",umask=3D%o,uid=3D%u,gid=3D%u", sbi->umask, sbi->uid, sbi->gid); if (sbi->part >=3D 0) diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 2f72da5..104e4d9 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -265,7 +265,7 @@ static int hostfs_show_options(struct seq_file *seq, st= ruct vfsmount *vfs) size_t offset =3D strlen(root_ino) + 1; =20 if (strlen(root_path) > offset) - seq_printf(seq, ",%s", root_path + offset); + seq_show_option(seq, root_path + offset, NULL); =20 return 0; } diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 39c7059..e84393f 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c @@ -509,14 +509,15 @@ int jbd2_cleanup_journal_tail(journal_t *journal) * journal_clean_one_cp_list * * Find all the written-back checkpoint buffers in the given list and - * release them. + * release them. If 'destroy' is set, clean all buffers unconditionally. * * Called with the journal locked. * Called with j_list_lock held. * Returns number of bufers reaped (for debug) */ =20 -static int journal_clean_one_cp_list(struct journal_head *jh, int *release= d) +static int journal_clean_one_cp_list(struct journal_head *jh, bool destroy= , + int *released) { struct journal_head *last_jh; struct journal_head *next_jh =3D jh; @@ -532,7 +533,10 @@ static int journal_clean_one_cp_list(struct journal_he= ad *jh, int *released) next_jh =3D jh->b_cpnext; /* Use trylock because of the ranking */ if (jbd_trylock_bh_state(jh2bh(jh))) { - ret =3D __try_to_free_cp_buf(jh); + if (!destroy) + ret =3D __try_to_free_cp_buf(jh); + else + ret =3D __jbd2_journal_remove_checkpoint(jh) + 1; if (ret) { freed++; if (ret =3D=3D 2) { @@ -558,13 +562,14 @@ static int journal_clean_one_cp_list(struct journal_h= ead *jh, int *released) * journal_clean_checkpoint_list * * Find all the written-back checkpoint buffers in the journal and release= them. + * If 'destroy' is set, release all buffers unconditionally. * * Called with the journal locked. * Called with j_list_lock held. * Returns number of buffers reaped (for debug) */ =20 -int __jbd2_journal_clean_checkpoint_list(journal_t *journal) +int __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy) { transaction_t *transaction, *last_transaction, *next_transaction; int ret =3D 0; @@ -580,7 +585,7 @@ int __jbd2_journal_clean_checkpoint_list(journal_t *jou= rnal) transaction =3D next_transaction; next_transaction =3D transaction->t_cpnext; ret +=3D journal_clean_one_cp_list(transaction-> - t_checkpoint_list, &released); + t_checkpoint_list, destroy, &released); /* * This function only frees up some memory if possible so we * dont have an obligation to finish processing. Bail out if @@ -596,7 +601,7 @@ int __jbd2_journal_clean_checkpoint_list(journal_t *jou= rnal) * we can possibly see not yet submitted buffers on io_list */ ret +=3D journal_clean_one_cp_list(transaction-> - t_checkpoint_io_list, &released); + t_checkpoint_io_list, destroy, &released); if (need_resched()) goto out; } while (transaction !=3D last_transaction); @@ -605,6 +610,28 @@ out: } =20 /* + * Remove buffers from all checkpoint lists as journal is aborted and we j= ust + * need to free memory + */ +void jbd2_journal_destroy_checkpoint(journal_t *journal) +{ + /* + * We loop because __jbd2_journal_clean_checkpoint_list() may abort + * early due to a need of rescheduling. + */ + while (1) { + spin_lock(&journal->j_list_lock); + if (!journal->j_checkpoint_transactions) { + spin_unlock(&journal->j_list_lock); + break; + } + __jbd2_journal_clean_checkpoint_list(journal, true); + spin_unlock(&journal->j_list_lock); + cond_resched(); + } +} + +/* * journal_remove_checkpoint: called after a buffer has been committed * to disk (either by being write-back flushed to disk, or being * committed to the log). diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index bccb605..45ae6ec 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -340,6 +340,7 @@ void jbd2_journal_commit_transaction(journal_t *journal= ) /* Do we need to erase the effects of a prior jbd2_journal_flush? */ if (journal->j_flags & JBD2_FLUSHED) { jbd_debug(3, "super block updated\n"); + mutex_lock(&journal->j_checkpoint_mutex); /* * We hold j_checkpoint_mutex so tail cannot change under us. * We don't need any special data guarantees for writing sb @@ -350,6 +351,7 @@ void jbd2_journal_commit_transaction(journal_t *journal= ) journal->j_tail_sequence, journal->j_tail, WRITE_SYNC); + mutex_unlock(&journal->j_checkpoint_mutex); } else { jbd_debug(3, "superblock not updated\n"); } @@ -433,7 +435,7 @@ void jbd2_journal_commit_transaction(journal_t *journal= ) * frees some memory */ spin_lock(&journal->j_list_lock); - __jbd2_journal_clean_checkpoint_list(journal); + __jbd2_journal_clean_checkpoint_list(journal, false); spin_unlock(&journal->j_list_lock); =20 jbd_debug(3, "JBD2: commit phase 1\n"); diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 9532dac..7b7607e 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -1242,6 +1242,8 @@ static int journal_reset(journal_t *journal) journal->j_errno); journal->j_flags |=3D JBD2_FLUSHED; } else { + /* Lock here to make assertions happy... */ + mutex_lock(&journal->j_checkpoint_mutex); /* * Update log tail information. We use WRITE_FUA since new * transaction will start reusing journal space and so we @@ -1252,6 +1254,7 @@ static int journal_reset(journal_t *journal) journal->j_tail_sequence, journal->j_tail, WRITE_FUA); + mutex_unlock(&journal->j_checkpoint_mutex); } return jbd2_journal_start_thread(journal); } @@ -1314,6 +1317,7 @@ int jbd2_journal_update_sb_log_tail(journal_t *journa= l, tid_t tail_tid, journal_superblock_t *sb =3D journal->j_superblock; int ret; =20 + BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex)); jbd_debug(1, "JBD2: updating superblock (start %lu, seq %u)\n", tail_block, tail_tid); =20 @@ -1344,6 +1348,7 @@ static void jbd2_mark_journal_empty(journal_t *journa= l) { journal_superblock_t *sb =3D journal->j_superblock; =20 + BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex)); read_lock(&journal->j_state_lock); jbd_debug(1, "JBD2: Marking journal as empty (seq %d)\n", journal->j_tail_sequence); @@ -1566,8 +1571,17 @@ int jbd2_journal_destroy(journal_t *journal) while (journal->j_checkpoint_transactions !=3D NULL) { spin_unlock(&journal->j_list_lock); mutex_lock(&journal->j_checkpoint_mutex); - jbd2_log_do_checkpoint(journal); + err =3D jbd2_log_do_checkpoint(journal); mutex_unlock(&journal->j_checkpoint_mutex); + /* + * If checkpointing failed, just free the buffers to avoid + * looping forever + */ + if (err) { + jbd2_journal_destroy_checkpoint(journal); + spin_lock(&journal->j_list_lock); + break; + } spin_lock(&journal->j_list_lock); } =20 @@ -1577,9 +1591,11 @@ int jbd2_journal_destroy(journal_t *journal) spin_unlock(&journal->j_list_lock); =20 if (journal->j_sb_buffer) { - if (!is_journal_aborted(journal)) + if (!is_journal_aborted(journal)) { + mutex_lock(&journal->j_checkpoint_mutex); jbd2_mark_journal_empty(journal); - else + mutex_unlock(&journal->j_checkpoint_mutex); + } else err =3D -EIO; brelse(journal->j_sb_buffer); } @@ -1828,10 +1844,13 @@ int jbd2_journal_flush(journal_t *journal) if (is_journal_aborted(journal)) return -EIO; =20 + mutex_lock(&journal->j_checkpoint_mutex); if (!err) { err =3D jbd2_cleanup_journal_tail(journal); - if (err < 0) + if (err < 0) { + mutex_unlock(&journal->j_checkpoint_mutex); goto out; + } err =3D 0; } =20 @@ -1841,6 +1860,7 @@ int jbd2_journal_flush(journal_t *journal) * commits of data to the journal will restore the current * s_start value. */ jbd2_mark_journal_empty(journal); + mutex_unlock(&journal->j_checkpoint_mutex); write_lock(&journal->j_state_lock); J_ASSERT(!journal->j_running_transaction); J_ASSERT(!journal->j_committing_transaction); @@ -1882,8 +1902,12 @@ int jbd2_journal_wipe(journal_t *journal, int write) write ? "Clearing" : "Ignoring"); =20 err =3D jbd2_journal_skip_recovery(journal); - if (write) + if (write) { + /* Lock to make assertions happy... */ + mutex_lock(&journal->j_checkpoint_mutex); jbd2_mark_journal_empty(journal); + mutex_unlock(&journal->j_checkpoint_mutex); + } =20 no_recovery: return err; diff --git a/fs/namei.c b/fs/namei.c index c8b13a9..2c22655 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -398,6 +398,24 @@ void path_put(struct path *path) } EXPORT_SYMBOL(path_put); =20 +/** + * path_connected - Verify that a path->dentry is below path->mnt.mnt_root + * @path: nameidate to verify + * + * Rename can sometimes move a file or directory outside of a bind + * mount, path_connected allows those cases to be detected. + */ +static bool path_connected(const struct path *path) +{ + struct vfsmount *mnt =3D path->mnt; + + /* Only bind mounts can have disconnected paths */ + if (mnt->mnt_root =3D=3D mnt->mnt_sb->s_root) + return true; + + return is_subdir(path->dentry, mnt->mnt_root); +} + /* * Path walking has 2 modes, rcu-walk and ref-walk (see * Documentation/filesystems/path-lookup.txt). In situations when we can'= t @@ -933,6 +951,8 @@ static int follow_dotdot_rcu(struct nameidata *nd) goto failed; nd->path.dentry =3D parent; nd->seq =3D seq; + if (unlikely(!path_connected(&nd->path))) + goto failed; break; } if (!follow_up_rcu(&nd->path)) @@ -1027,7 +1047,7 @@ static void follow_mount(struct path *path) } } =20 -static void follow_dotdot(struct nameidata *nd) +static int follow_dotdot(struct nameidata *nd) { if (!nd->root.mnt) set_root(nd); @@ -1043,6 +1063,10 @@ static void follow_dotdot(struct nameidata *nd) /* rare case of legitimate dget_parent()... */ nd->path.dentry =3D dget_parent(nd->path.dentry); dput(old); + if (unlikely(!path_connected(&nd->path))) { + path_put(&nd->path); + return -ENOENT; + } break; } if (!follow_up(&nd->path)) @@ -1050,6 +1074,7 @@ static void follow_dotdot(struct nameidata *nd) } follow_mount(&nd->path); nd->inode =3D nd->path.dentry->d_inode; + return 0; } =20 /* @@ -1241,7 +1266,7 @@ static inline int handle_dots(struct nameidata *nd, i= nt type) if (follow_dotdot_rcu(nd)) return -ECHILD; } else - follow_dotdot(nd); + return follow_dotdot(nd); } return 0; } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index e83786f..609a951 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1793,7 +1793,7 @@ static int _nfs4_do_open(struct inode *dir, struct de= ntry *dentry, fmode_t fmode if (server->caps & NFS_CAP_POSIX_LOCK) set_bit(NFS_STATE_POSIX_LOCKS, &state->flags); =20 - if (opendata->o_arg.open_flags & O_EXCL) { + if ((opendata->o_arg.open_flags & (O_CREAT|O_EXCL)) =3D=3D (O_CREAT|O_EXC= L)) { nfs4_exclusive_attrset(opendata, sattr); =20 nfs_fattr_init(opendata->o_res.f_attr); diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 7ba6ac1..8e48ba5 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -1411,6 +1411,7 @@ int dlm_master_request_handler(struct o2net_msg *msg,= u32 len, void *data, int found, ret; int set_maybe; int dispatch_assert =3D 0; + int dispatched =3D 0; =20 if (!dlm_grab(dlm)) return DLM_MASTER_RESP_NO; @@ -1617,13 +1618,16 @@ send_response: mlog(ML_ERROR, "failed to dispatch assert master work\n"); response =3D DLM_MASTER_RESP_ERROR; dlm_lockres_put(res); + } else { + dispatched =3D 1; } } else { if (res) dlm_lockres_put(res); } =20 - dlm_put(dlm); + if (!dispatched) + dlm_put(dlm); return response; } =20 @@ -2041,7 +2045,6 @@ int dlm_dispatch_assert_master(struct dlm_ctxt *dlm, =20 =20 /* queue up work for dlm_assert_master_worker */ - dlm_grab(dlm); /* get an extra ref for the work item */ dlm_init_work_item(dlm, item, dlm_assert_master_worker, NULL); item->u.am.lockres =3D res; /* already have a ref */ /* can optionally ignore node numbers higher than this node */ diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index d15b071..0e5013e 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -1689,6 +1689,7 @@ int dlm_master_requery_handler(struct o2net_msg *msg,= u32 len, void *data, unsigned int hash; int master =3D DLM_LOCK_RES_OWNER_UNKNOWN; u32 flags =3D DLM_ASSERT_MASTER_REQUERY; + int dispatched =3D 0; =20 if (!dlm_grab(dlm)) { /* since the domain has gone away on this @@ -1710,6 +1711,8 @@ int dlm_master_requery_handler(struct o2net_msg *msg,= u32 len, void *data, mlog_errno(-ENOMEM); /* retry!? */ BUG(); + } else { + dispatched =3D 1; } } else /* put.. incase we are not the master */ dlm_lockres_put(res); @@ -1717,7 +1720,8 @@ int dlm_master_requery_handler(struct o2net_msg *msg,= u32 len, void *data, } spin_unlock(&dlm->spinlock); =20 - dlm_put(dlm); + if (!dispatched) + dlm_put(dlm); return master; } =20 diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 231eab2..b5e457c 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -3968,9 +3968,13 @@ static void ocfs2_downconvert_thread_do_work(struct = ocfs2_super *osb) osb->dc_work_sequence =3D osb->dc_wake_sequence; =20 processed =3D osb->blocked_lock_count; - while (processed) { - BUG_ON(list_empty(&osb->blocked_lock_list)); - + /* + * blocked lock processing in this loop might call iput which can + * remove items off osb->blocked_lock_list. Downconvert up to + * 'processed' number of locks, but stop short if we had some + * removed in ocfs2_mark_lockres_freeing when downconverting. + */ + while (processed && !list_empty(&osb->blocked_lock_list)) { lockres =3D list_entry(osb->blocked_lock_list.next, struct ocfs2_lock_res, l_blocked_list); list_del_init(&lockres->l_blocked_list); diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 4994f8b..5fe6b1e 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -1583,8 +1583,8 @@ static int ocfs2_show_options(struct seq_file *s, str= uct vfsmount *mnt) seq_printf(s, ",localflocks,"); =20 if (osb->osb_cluster_stack[0]) - seq_printf(s, ",cluster_stack=3D%.*s", OCFS2_STACK_LABEL_LEN, - osb->osb_cluster_stack); + seq_show_option_n(s, "cluster_stack", osb->osb_cluster_stack, + OCFS2_STACK_LABEL_LEN); if (opts & OCFS2_MOUNT_USRQUOTA) seq_printf(s, ",usrquota"); if (opts & OCFS2_MOUNT_GRPQUOTA) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index d1bd6a9..de404f2 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -11,6 +11,7 @@ #include #include #include +#include =20 #include #include @@ -606,6 +607,7 @@ const struct file_operations proc_clear_refs_operations= =3D { struct pagemapread { int pos, len; /* units: PM_ENTRY_BYTES, not bytes */ u64 *buffer; + bool show_pfn; }; =20 #define PM_ENTRY_BYTES sizeof(u64) @@ -654,14 +656,14 @@ static u64 swap_pte_to_pagemap_entry(pte_t pte) return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT); } =20 -static u64 pte_to_pagemap_entry(pte_t pte) +static u64 pte_to_pagemap_entry(struct pagemapread *pm, pte_t pte) { u64 pme =3D 0; if (is_swap_pte(pte)) pme =3D PM_PFRAME(swap_pte_to_pagemap_entry(pte)) | PM_PSHIFT(PAGE_SHIFT) | PM_SWAP; else if (pte_present(pte)) - pme =3D PM_PFRAME(pte_pfn(pte)) + pme =3D (pm->show_pfn ? PM_PFRAME(pte_pfn(pte)) : 0) | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT; return pme; } @@ -693,7 +695,7 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long = addr, unsigned long end, if (vma && (vma->vm_start <=3D addr) && !is_vm_hugetlb_page(vma)) { pte =3D pte_offset_map(pmd, addr); - pfn =3D pte_to_pagemap_entry(*pte); + pfn =3D pte_to_pagemap_entry(pm, *pte); /* unmap before userspace copy */ pte_unmap(pte); } @@ -708,11 +710,11 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned lon= g addr, unsigned long end, } =20 #ifdef CONFIG_HUGETLB_PAGE -static u64 huge_pte_to_pagemap_entry(pte_t pte, int offset) +static u64 huge_pte_to_pagemap_entry(struct pagemapread *pm, pte_t pte, in= t offset) { u64 pme =3D 0; if (pte_present(pte)) - pme =3D PM_PFRAME(pte_pfn(pte) + offset) + pme =3D (pm->show_pfn ? PM_PFRAME(pte_pfn(pte) + offset) : 0) | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT; return pme; } @@ -728,7 +730,7 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned l= ong hmask, =20 for (; addr !=3D end; addr +=3D PAGE_SIZE) { int offset =3D (addr & ~hmask) >> PAGE_SHIFT; - pfn =3D huge_pte_to_pagemap_entry(*pte, offset); + pfn =3D huge_pte_to_pagemap_entry(pm, *pte, offset); err =3D add_to_pagemap(addr, pfn, pm); if (err) return err; @@ -792,6 +794,10 @@ static ssize_t pagemap_read(struct file *file, char __= user *buf, if (!count) goto out_task; =20 + /* do not disclose physical addresses: attack vector */ + pm.show_pfn =3D !security_capable(&init_user_ns, file->f_cred,=20 + CAP_SYS_ADMIN); + pm.len =3D (PAGEMAP_WALK_SIZE >> PAGE_SHIFT); pm.buffer =3D kmalloc(pm.len * PM_ENTRY_BYTES, GFP_TEMPORARY); ret =3D -ENOMEM; @@ -864,19 +870,9 @@ out: return ret; } =20 -static int pagemap_open(struct inode *inode, struct file *file) -{ - /* do not disclose physical addresses to unprivileged - userspace (closes a rowhammer attack vector) */ - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - return 0; -} - const struct file_operations proc_pagemap_operations =3D { .llseek =3D mem_lseek, /* borrow this */ .read =3D pagemap_read, - .open =3D pagemap_open, }; #endif /* CONFIG_PROC_PAGE_MONITOR */ =20 diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index b367581..c2b06d4 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -365,7 +365,8 @@ xfs_end_bio( xfs_ioend_t *ioend =3D bio->bi_private; =20 ASSERT(atomic_read(&bio->bi_cnt) >=3D 1); - ioend->io_error =3D test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : error; + if (!ioend->io_error && !test_bit(BIO_UPTODATE, &bio->bi_flags)) + ioend->io_error =3D error; =20 /* Toss bio and pass work off to an xfsdatad thread */ bio->bi_private =3D NULL; diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h index 9c7d22f..c782906 100644 --- a/fs/xfs/xfs_attr_leaf.h +++ b/fs/xfs/xfs_attr_leaf.h @@ -111,8 +111,15 @@ typedef struct xfs_attr_leaf_name_remote { typedef struct xfs_attr_leafblock { xfs_attr_leaf_hdr_t hdr; /* constant-structure header block */ xfs_attr_leaf_entry_t entries[1]; /* sorted on key, not name */ - xfs_attr_leaf_name_local_t namelist; /* grows from bottom of buf */ - xfs_attr_leaf_name_remote_t valuelist; /* grows from bottom of buf */ + /* + * The rest of the block contains the following structures after the + * leaf entries, growing from the bottom up. The variables are never + * referenced and definining them can actually make gcc optimize away + * accesses to the 'entries' array above index 0 so don't do that. + * + * xfs_attr_leaf_name_local_t namelist; + * xfs_attr_leaf_name_remote_t valuelist; + */ } xfs_attr_leafblock_t; =20 /* diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 8a89949..90ccd1c 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -533,9 +533,9 @@ xfs_showargs( seq_printf(m, "," MNTOPT_LOGBSIZE "=3D%dk", mp->m_logbsize >> 10); =20 if (mp->m_logname) - seq_printf(m, "," MNTOPT_LOGDEV "=3D%s", mp->m_logname); + seq_show_option(m, MNTOPT_LOGDEV, mp->m_logname); if (mp->m_rtname) - seq_printf(m, "," MNTOPT_RTDEV "=3D%s", mp->m_rtname); + seq_show_option(m, MNTOPT_RTDEV, mp->m_rtname); =20 if (mp->m_dalign > 0) seq_printf(m, "," MNTOPT_SUNIT "=3D%d", diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index fffdf00..2fe0d22 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -83,6 +83,7 @@ struct fsl_usb2_platform_data { =20 unsigned suspended:1; unsigned already_suspended:1; + unsigned has_fsl_erratum_a005275:1; =20 /* register save area for suspend/resume */ u32 pm_command; diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 4920c55..fbfd0c4 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -980,8 +980,9 @@ int __jbd2_update_log_tail(journal_t *journal, tid_t ti= d, unsigned long block); extern void jbd2_journal_commit_transaction(journal_t *); =20 /* Checkpoint list management */ -int __jbd2_journal_clean_checkpoint_list(journal_t *journal); +int __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy)= ; int __jbd2_journal_remove_checkpoint(struct journal_head *); +void jbd2_journal_destroy_checkpoint(journal_t *journal); void __jbd2_journal_insert_checkpoint(struct journal_head *, transaction_t= *); =20 =20 diff --git a/include/linux/pci.h b/include/linux/pci.h index fe76a74..f0c4495 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -176,6 +176,8 @@ enum pci_dev_flags { PCI_DEV_FLAGS_NO_D3 =3D (__force pci_dev_flags_t) 2, /* Provide indication device is assigned by a Virtual Machine Manager */ PCI_DEV_FLAGS_ASSIGNED =3D (__force pci_dev_flags_t) 4, + /* Get VPD from function 0 VPD */ + PCI_DEV_FLAGS_VPD_REF_F0 =3D (__force pci_dev_flags_t) (1 << 8), }; =20 enum pci_irq_reroute_variant { diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index 0b69a46..8803d6e 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -122,6 +122,41 @@ void *__seq_open_private(struct file *, const struct s= eq_operations *, int); int seq_open_private(struct file *, const struct seq_operations *, int); int seq_release_private(struct inode *, struct file *); =20 +/** + * seq_show_options - display mount options with appropriate escapes. + * @m: the seq_file handle + * @name: the mount option name + * @value: the mount option name's value, can be NULL + */ +static inline void seq_show_option(struct seq_file *m, const char *name, + const char *value) +{ + seq_putc(m, ','); + seq_escape(m, name, ",=3D \t\n\\"); + if (value) { + seq_putc(m, '=3D'); + seq_escape(m, value, ", \t\n\\"); + } +} + +/** + * seq_show_option_n - display mount options with appropriate escapes + * where @value must be a specific length. + * @m: the seq_file handle + * @name: the mount option name + * @value: the mount option name's value, cannot be NULL + * @length: the length of @value to display + * + * This is a macro since this uses "length" to define the size of the + * stack buffer. + */ +#define seq_show_option_n(m, name, value, length) { \ + char val_buf[length + 1]; \ + strncpy(val_buf, value, length); \ + val_buf[length] =3D '\0'; \ + seq_show_option(m, name, val_buf); \ +} + #define SEQ_START_TOKEN ((void *)1) =20 /* diff --git a/include/net/ip.h b/include/net/ip.h index 1ee535b..2c7c5a9 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -138,6 +138,7 @@ static inline struct sk_buff *ip_finish_skb(struct sock= *sk, struct flowi4 *fl4) } =20 /* datagram.c */ +int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int ad= dr_len); extern int ip4_datagram_connect(struct sock *sk,=20 struct sockaddr *uaddr, int addr_len); =20 diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 5735a0f..3907358 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -217,7 +217,7 @@ extern void inet6_rt_notify(int event, struct rt6_inf= o *rt, struct nl_info *info); =20 extern void fib6_run_gc(unsigned long expires, - struct net *net); + struct net *net, bool force); =20 extern void fib6_gc_cleanup(void); =20 diff --git a/ipc/msg.c b/ipc/msg.c index 25f1a61..391e3e0 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -198,6 +198,15 @@ static int newque(struct ipc_namespace *ns, struct ipc= _params *params) return retval; } =20 + msq->q_stime =3D msq->q_rtime =3D 0; + msq->q_ctime =3D get_seconds(); + msq->q_cbytes =3D msq->q_qnum =3D 0; + msq->q_qbytes =3D ns->msg_ctlmnb; + msq->q_lspid =3D msq->q_lrpid =3D 0; + INIT_LIST_HEAD(&msq->q_messages); + INIT_LIST_HEAD(&msq->q_receivers); + INIT_LIST_HEAD(&msq->q_senders); + /* * ipc_addid() locks msq */ @@ -208,15 +217,6 @@ static int newque(struct ipc_namespace *ns, struct ipc= _params *params) return id; } =20 - msq->q_stime =3D msq->q_rtime =3D 0; - msq->q_ctime =3D get_seconds(); - msq->q_cbytes =3D msq->q_qnum =3D 0; - msq->q_qbytes =3D ns->msg_ctlmnb; - msq->q_lspid =3D msq->q_lrpid =3D 0; - INIT_LIST_HEAD(&msq->q_messages); - INIT_LIST_HEAD(&msq->q_receivers); - INIT_LIST_HEAD(&msq->q_senders); - msg_unlock(msq); =20 return msq->q_perm.id; diff --git a/ipc/sem.c b/ipc/sem.c index 5215a81..b31c3ef 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -314,14 +314,6 @@ static int newary(struct ipc_namespace *ns, struct ipc= _params *params) return retval; } =20 - id =3D ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni); - if (id < 0) { - security_sem_free(sma); - ipc_rcu_putref(sma); - return id; - } - ns->used_sems +=3D nsems; - sma->sem_base =3D (struct sem *) &sma[1]; =20 for (i =3D 0; i < nsems; i++) @@ -332,6 +324,15 @@ static int newary(struct ipc_namespace *ns, struct ipc= _params *params) INIT_LIST_HEAD(&sma->list_id); sma->sem_nsems =3D nsems; sma->sem_ctime =3D get_seconds(); + + id =3D ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni); + if (id < 0) { + security_sem_free(sma); + ipc_rcu_putref(sma); + return id; + } + ns->used_sems +=3D nsems; + sem_unlock(sma); =20 return sma->sem_perm.id; @@ -1606,16 +1607,27 @@ void exit_sem(struct task_struct *tsk) rcu_read_lock(); un =3D list_entry_rcu(ulp->list_proc.next, struct sem_undo, list_proc); - if (&un->list_proc =3D=3D &ulp->list_proc) - semid =3D -1; - else - semid =3D un->semid; + if (&un->list_proc =3D=3D &ulp->list_proc) { + /* + * We must wait for freeary() before freeing this ulp, + * in case we raced with last sem_undo. There is a small + * possibility where we exit while freeary() didn't + * finish unlocking sem_undo_list. + */ + spin_unlock_wait(&ulp->lock); + rcu_read_unlock(); + break; + } + spin_lock(&ulp->lock); + semid =3D un->semid; + spin_unlock(&ulp->lock); rcu_read_unlock(); =20 + /* exit_sem raced with IPC_RMID, nothing to do */ if (semid =3D=3D -1) - break; + continue; =20 - sma =3D sem_lock_check(tsk->nsproxy->ipc_ns, un->semid); + sma =3D sem_lock_check(tsk->nsproxy->ipc_ns, semid); =20 /* exit_sem raced with IPC_RMID, nothing to do */ if (IS_ERR(sma)) diff --git a/ipc/shm.c b/ipc/shm.c index 326a20b..16b1f9e 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -498,12 +498,6 @@ static int newseg(struct ipc_namespace *ns, struct ipc= _params *params) if (IS_ERR(file)) goto no_file; =20 - id =3D ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni); - if (id < 0) { - error =3D id; - goto no_id; - } - shp->shm_cprid =3D task_tgid_vnr(current); shp->shm_lprid =3D 0; shp->shm_atim =3D shp->shm_dtim =3D 0; @@ -512,6 +506,13 @@ static int newseg(struct ipc_namespace *ns, struct ipc= _params *params) shp->shm_nattch =3D 0; shp->shm_file =3D file; shp->shm_creator =3D current; + + id =3D ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni); + if (id < 0) { + error =3D id; + goto no_id; + } + /* * shmid gets reported as "inode#" in /proc/pid/maps. * proc-ps tools use this. Changing this will break them. diff --git a/ipc/util.c b/ipc/util.c index 75261a3..e4c9377 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -264,6 +264,10 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_per= m* new, int size) rcu_read_lock(); spin_lock(&new->lock); =20 + current_euid_egid(&euid, &egid); + new->cuid =3D new->uid =3D euid; + new->gid =3D new->cgid =3D egid; + err =3D idr_get_new(&ids->ipcs_idr, new, &id); if (err) { spin_unlock(&new->lock); @@ -273,10 +277,6 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_per= m* new, int size) =20 ids->in_use++; =20 - current_euid_egid(&euid, &egid); - new->cuid =3D new->uid =3D euid; - new->gid =3D new->cgid =3D egid; - new->seq =3D ids->seq++; if(ids->seq > ids->seq_max) ids->seq =3D 0; diff --git a/kernel/cgroup.c b/kernel/cgroup.c index eafb6dd..ec64a18 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -1053,15 +1053,16 @@ static int cgroup_show_options(struct seq_file *seq= , struct vfsmount *vfs) =20 mutex_lock(&cgroup_mutex); for_each_subsys(root, ss) - seq_printf(seq, ",%s", ss->name); + seq_show_option(seq, ss->name, NULL); if (test_bit(ROOT_NOPREFIX, &root->flags)) seq_puts(seq, ",noprefix"); if (strlen(root->release_agent_path)) - seq_printf(seq, ",release_agent=3D%s", root->release_agent_path); + seq_show_option(seq, "release_agent", + root->release_agent_path); if (clone_children(&root->top_cgroup)) seq_puts(seq, ",clone_children"); if (strlen(root->name)) - seq_printf(seq, ",name=3D%s", root->name); + seq_show_option(seq, "name", root->name); mutex_unlock(&cgroup_mutex); return 0; } diff --git a/kernel/events/core.c b/kernel/events/core.c index 4277095..f475286 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -3942,12 +3942,20 @@ static const struct file_operations perf_fops =3D { * to user-space before waking everybody up. */ =20 +static inline struct fasync_struct **perf_event_fasync(struct perf_event *= event) +{ + /* only the parent has fasync state */ + if (event->parent) + event =3D event->parent; + return &event->fasync; +} + void perf_event_wakeup(struct perf_event *event) { ring_buffer_wakeup(event); =20 if (event->pending_kill) { - kill_fasync(&event->fasync, SIGIO, event->pending_kill); + kill_fasync(perf_event_fasync(event), SIGIO, event->pending_kill); event->pending_kill =3D 0; } } @@ -4924,7 +4932,7 @@ static int __perf_event_overflow(struct perf_event *e= vent, else perf_event_output(event, data, regs); =20 - if (event->fasync && event->pending_kill) { + if (*perf_event_fasync(event) && event->pending_kill) { event->pending_wakeup =3D 1; irq_work_queue(&event->pending); } diff --git a/net/Kconfig b/net/Kconfig index a073148..946e17a 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -250,7 +250,7 @@ menu "Network testing" =20 config NET_PKTGEN tristate "Packet Generator (USE WITH CAUTION)" - depends on PROC_FS + depends on INET && PROC_FS ---help--- This module will inject preconfigured packets, at a configurable rate, out of a given interface. It is used for network interface diff --git a/net/core/datagram.c b/net/core/datagram.c index 6f54d0a..a496313 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -128,6 +128,35 @@ out_noerr: goto out; } =20 +static struct sk_buff *skb_set_peeked(struct sk_buff *skb) +{ + struct sk_buff *nskb; + + if (skb->peeked) + return skb; + + /* We have to unshare an skb before modifying it. */ + if (!skb_shared(skb)) + goto done; + + nskb =3D skb_clone(skb, GFP_ATOMIC); + if (!nskb) + return ERR_PTR(-ENOMEM); + + skb->prev->next =3D nskb; + skb->next->prev =3D nskb; + nskb->prev =3D skb->prev; + nskb->next =3D skb->next; + + consume_skb(skb); + skb =3D nskb; + +done: + skb->peeked =3D 1; + + return skb; +} + /** * __skb_recv_datagram - Receive a datagram skbuff * @sk: socket @@ -160,7 +189,9 @@ out_noerr: struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags, int *peeked, int *err) { + struct sk_buff_head *queue =3D &sk->sk_receive_queue; struct sk_buff *skb; + unsigned long cpu_flags; long timeo; /* * Caller is allowed not to check sk->sk_err before skb_recv_datagram() @@ -179,15 +210,17 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, = unsigned flags, * Look at current nfs client by the way... * However, this function was correct in any case. 8) */ - unsigned long cpu_flags; - struct sk_buff_head *queue =3D &sk->sk_receive_queue; - spin_lock_irqsave(&queue->lock, cpu_flags); skb =3D skb_peek(queue); if (skb) { *peeked =3D skb->peeked; if (flags & MSG_PEEK) { - skb->peeked =3D 1; + + skb =3D skb_set_peeked(skb); + error =3D PTR_ERR(skb); + if (IS_ERR(skb)) + goto unlock_err; + atomic_inc(&skb->users); } else __skb_unlink(skb, queue); @@ -206,6 +239,8 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, un= signed flags, =20 return NULL; =20 +unlock_err: + spin_unlock_irqrestore(&queue->lock, cpu_flags); no_packet: *err =3D error; return NULL; @@ -656,7 +691,8 @@ __sum16 __skb_checksum_complete_head(struct sk_buff *sk= b, int len) if (likely(!sum)) { if (unlikely(skb->ip_summed =3D=3D CHECKSUM_COMPLETE)) netdev_rx_csum_fault(skb->dev); - skb->ip_summed =3D CHECKSUM_UNNECESSARY; + if (!skb_shared(skb)) + skb->ip_summed =3D CHECKSUM_UNNECESSARY; } return sum; } diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 6af54f2..c7caf3e 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -594,15 +594,17 @@ static int dump_rules(struct sk_buff *skb, struct net= link_callback *cb, { int idx =3D 0; struct fib_rule *rule; + int err =3D 0; =20 rcu_read_lock(); list_for_each_entry_rcu(rule, &ops->rules_list, list) { if (idx < cb->args[1]) goto skip; =20 - if (fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, RTM_NEWRULE, - NLM_F_MULTI, ops) < 0) + err =3D fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, RTM_NEWRULE, + NLM_F_MULTI, ops); + if (err < 0) break; skip: idx++; @@ -611,7 +613,7 @@ skip: cb->args[1] =3D idx; rules_ops_put(ops); =20 - return skb->len; + return err; } =20 static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *c= b) @@ -627,7 +629,9 @@ static int fib_nl_dumprule(struct sk_buff *skb, struct = netlink_callback *cb) if (ops =3D=3D NULL) return -EAFNOSUPPORT; =20 - return dump_rules(skb, cb, ops); + dump_rules(skb, cb, ops); + + return skb->len; } =20 rcu_read_lock(); diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 9dd65a9..7879b2f 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -3481,8 +3481,10 @@ static int pktgen_thread_worker(void *arg) pktgen_rem_thread(t); =20 /* Wait for kthread_stop */ - while (!kthread_should_stop()) { + for (;;) { set_current_state(TASK_INTERRUPTIBLE); + if (kthread_should_stop()) + break; schedule(); } __set_current_state(TASK_RUNNING); diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c index ec07510..ffb8b6e 100644 --- a/net/ipv4/datagram.c +++ b/net/ipv4/datagram.c @@ -20,7 +20,7 @@ #include #include =20 -int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr= _len) +int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int ad= dr_len) { struct inet_sock *inet =3D inet_sk(sk); struct sockaddr_in *usin =3D (struct sockaddr_in *) uaddr; @@ -39,8 +39,6 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr= *uaddr, int addr_len) =20 sk_dst_reset(sk); =20 - lock_sock(sk); - oif =3D sk->sk_bound_dev_if; saddr =3D inet->inet_saddr; if (ipv4_is_multicast(usin->sin_addr.s_addr)) { @@ -81,7 +79,17 @@ int ip4_datagram_connect(struct sock *sk, struct sockadd= r *uaddr, int addr_len) sk_dst_set(sk, &rt->dst); err =3D 0; out: - release_sock(sk); return err; } +EXPORT_SYMBOL(__ip4_datagram_connect); + +int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr= _len) +{ + int res; + + lock_sock(sk); + res =3D __ip4_datagram_connect(sk, uaddr, addr_len); + release_sock(sk); + return res; +} EXPORT_SYMBOL(ip4_datagram_connect); diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile index 4b20d56..8b25fbb 100644 --- a/net/ipv6/Makefile +++ b/net/ipv6/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_NETFILTER) +=3D netfilter/ obj-$(CONFIG_IPV6_SIT) +=3D sit.o obj-$(CONFIG_IPV6_TUNNEL) +=3D ip6_tunnel.o =20 -obj-y +=3D addrconf_core.o exthdrs_core.o output_core.o +obj-y +=3D addrconf_core.o exthdrs_core.o +obj-$(CONFIG_INET) +=3D output_core.o =20 obj-$(subst m,y,$(CONFIG_IPV6)) +=3D inet6_hashtables.o diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 3afdd78..006867d 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -4321,6 +4321,21 @@ int addrconf_sysctl_forward(ctl_table *ctl, int writ= e, return ret; } =20 +static +int addrconf_sysctl_mtu(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct inet6_dev *idev =3D ctl->extra1; + int min_mtu =3D IPV6_MIN_MTU; + struct ctl_table lctl; + + lctl =3D *ctl; + lctl.extra1 =3D &min_mtu; + lctl.extra2 =3D idev ? &idev->dev->mtu : NULL; + + return proc_dointvec_minmax(&lctl, write, buffer, lenp, ppos); +} + static void dev_disable_change(struct inet6_dev *idev) { if (!idev || !idev->dev) @@ -4421,7 +4436,7 @@ static struct addrconf_sysctl_table .data =3D &ipv6_devconf.mtu6, .maxlen =3D sizeof(int), .mode =3D 0644, - .proc_handler =3D proc_dointvec, + .proc_handler =3D addrconf_sysctl_mtu, }, { .procname =3D "accept_ra", diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 33719b7..67f3632 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -38,7 +38,7 @@ static inline int ipv6_mapped_addr_any(const struct in6_a= ddr *a) return (ipv6_addr_v4mapped(a) && (a->s6_addr32[3] =3D=3D 0)); } =20 -int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr= _len) +static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr,= int addr_len) { struct sockaddr_in6 *usin =3D (struct sockaddr_in6 *) uaddr; struct inet_sock *inet =3D inet_sk(sk); @@ -54,7 +54,7 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr= *uaddr, int addr_len) if (usin->sin6_family =3D=3D AF_INET) { if (__ipv6_only_sock(sk)) return -EAFNOSUPPORT; - err =3D ip4_datagram_connect(sk, uaddr, addr_len); + err =3D __ip4_datagram_connect(sk, uaddr, addr_len); goto ipv4_connected; } =20 @@ -97,9 +97,9 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr= *uaddr, int addr_len) sin.sin_addr.s_addr =3D daddr->s6_addr32[3]; sin.sin_port =3D usin->sin6_port; =20 - err =3D ip4_datagram_connect(sk, - (struct sockaddr*) &sin, - sizeof(sin)); + err =3D __ip4_datagram_connect(sk, + (struct sockaddr *) &sin, + sizeof(sin)); =20 ipv4_connected: if (err) @@ -203,6 +203,16 @@ out: return err; } =20 +int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr= _len) +{ + int res; + + lock_sock(sk); + res =3D __ip6_datagram_connect(sk, uaddr, addr_len); + release_sock(sk); + return res; +} + void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port, u32 info, u8 *payload) { diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index ad62afc..785e62d 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -1473,27 +1473,28 @@ static int fib6_age(struct rt6_info *rt, void *arg) =20 static DEFINE_SPINLOCK(fib6_gc_lock); =20 -void fib6_run_gc(unsigned long expires, struct net *net) +void fib6_run_gc(unsigned long expires, struct net *net, bool force) { - if (expires !=3D ~0UL) { + unsigned long now; + + if (force) { spin_lock_bh(&fib6_gc_lock); - gc_args.timeout =3D expires ? (int)expires : - net->ipv6.sysctl.ip6_rt_gc_interval; - } else { - if (!spin_trylock_bh(&fib6_gc_lock)) { - mod_timer(&net->ipv6.ip6_fib_timer, jiffies + HZ); - return; - } - gc_args.timeout =3D net->ipv6.sysctl.ip6_rt_gc_interval; + } else if (!spin_trylock_bh(&fib6_gc_lock)) { + mod_timer(&net->ipv6.ip6_fib_timer, jiffies + HZ); + return; } + gc_args.timeout =3D expires ? (int)expires : + net->ipv6.sysctl.ip6_rt_gc_interval; =20 gc_args.more =3D icmp6_dst_gc(); =20 fib6_clean_all(net, fib6_age, 0, NULL); + now =3D jiffies; + net->ipv6.ip6_rt_last_gc =3D now; =20 if (gc_args.more) mod_timer(&net->ipv6.ip6_fib_timer, - round_jiffies(jiffies + round_jiffies(now + net->ipv6.sysctl.ip6_rt_gc_interval)); else del_timer(&net->ipv6.ip6_fib_timer); @@ -1502,7 +1503,7 @@ void fib6_run_gc(unsigned long expires, struct net *n= et) =20 static void fib6_gc_timer_cb(unsigned long arg) { - fib6_run_gc(0, (struct net *)arg); + fib6_run_gc(0, (struct net *)arg, true); } =20 static int __net_init fib6_net_init(struct net *net) diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index f96c96f..99ee86d 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -550,7 +550,7 @@ static void ipmr_mfc_seq_stop(struct seq_file *seq, voi= d *v) =20 if (it->cache =3D=3D &mrt->mfc6_unres_queue) spin_unlock_bh(&mfc_unres_lock); - else if (it->cache =3D=3D mrt->mfc6_cache_array) + else if (it->cache =3D=3D &mrt->mfc6_cache_array[it->ct]) read_unlock(&mrt_lock); } =20 diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 884d45f..39836da 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1743,11 +1743,11 @@ static int ndisc_netdev_event(struct notifier_block= *this, unsigned long event, switch (event) { case NETDEV_CHANGEADDR: neigh_changeaddr(&nd_tbl, dev); - fib6_run_gc(~0UL, net); + fib6_run_gc(0, net, false); break; case NETDEV_DOWN: neigh_ifdown(&nd_tbl, dev); - fib6_run_gc(~0UL, net); + fib6_run_gc(0, net, false); break; case NETDEV_NOTIFY_PEERS: ndisc_send_unsol_na(dev); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d89d1a6..3a8776d 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1159,7 +1159,6 @@ static void icmp6_clean_all(int (*func)(struct rt6_in= fo *rt, void *arg), =20 static int ip6_dst_gc(struct dst_ops *ops) { - unsigned long now =3D jiffies; struct net *net =3D container_of(ops, struct net, ipv6.ip6_dst_ops); int rt_min_interval =3D net->ipv6.sysctl.ip6_rt_gc_min_interval; int rt_max_size =3D net->ipv6.sysctl.ip6_rt_max_size; @@ -1169,13 +1168,12 @@ static int ip6_dst_gc(struct dst_ops *ops) int entries; =20 entries =3D dst_entries_get_fast(ops); - if (time_after(rt_last_gc + rt_min_interval, now) && + if (time_after(rt_last_gc + rt_min_interval, jiffies) && entries <=3D rt_max_size) goto out; =20 net->ipv6.ip6_rt_gc_expire++; - fib6_run_gc(net->ipv6.ip6_rt_gc_expire, net); - net->ipv6.ip6_rt_last_gc =3D now; + fib6_run_gc(net->ipv6.ip6_rt_gc_expire, net, entries > rt_max_size); entries =3D dst_entries_get_slow(ops); if (entries < ops->gc_thresh) net->ipv6.ip6_rt_gc_expire =3D rt_gc_timeout>>1; @@ -2726,7 +2724,7 @@ int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int wri= te, net =3D (struct net *)ctl->extra1; delay =3D net->ipv6.sysctl.flush_delay; proc_dointvec(ctl, write, buffer, lenp, ppos); - fib6_run_gc(delay <=3D 0 ? ~0UL : (unsigned long)delay, net); + fib6_run_gc(delay <=3D 0 ? 0 : (unsigned long)delay, net, delay > 0); return 0; } =20 diff --git a/net/key/af_key.c b/net/key/af_key.c index dc8d7ef..8636f10 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -220,7 +220,7 @@ static int pfkey_broadcast_one(struct sk_buff *skb, str= uct sk_buff **skb2, #define BROADCAST_ONE 1 #define BROADCAST_REGISTERED 2 #define BROADCAST_PROMISC_ONLY 4 -static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, +static int pfkey_broadcast(struct sk_buff *skb, int broadcast_flags, struct sock *one_sk, struct net *net) { @@ -246,7 +246,7 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t a= llocation, * socket. */ if (pfk->promisc) - pfkey_broadcast_one(skb, &skb2, allocation, sk); + pfkey_broadcast_one(skb, &skb2, GFP_ATOMIC, sk); =20 /* the exact target will be processed later */ if (sk =3D=3D one_sk) @@ -261,7 +261,7 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t a= llocation, continue; } =20 - err2 =3D pfkey_broadcast_one(skb, &skb2, allocation, sk); + err2 =3D pfkey_broadcast_one(skb, &skb2, GFP_ATOMIC, sk); =20 /* Error is cleare after succecful sending to at least one * registered KM */ @@ -271,7 +271,7 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t a= llocation, rcu_read_unlock(); =20 if (one_sk !=3D NULL) - err =3D pfkey_broadcast_one(skb, &skb2, allocation, one_sk); + err =3D pfkey_broadcast_one(skb, &skb2, GFP_KERNEL, one_sk); =20 kfree_skb(skb2); kfree_skb(skb); @@ -294,7 +294,7 @@ static int pfkey_do_dump(struct pfkey_sock *pfk) hdr =3D (struct sadb_msg *) pfk->dump.skb->data; hdr->sadb_msg_seq =3D 0; hdr->sadb_msg_errno =3D rc; - pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, + pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE, &pfk->sk, sock_net(&pfk->sk)); pfk->dump.skb =3D NULL; } @@ -335,7 +335,7 @@ static int pfkey_error(const struct sadb_msg *orig, int= err, struct sock *sk) hdr->sadb_msg_len =3D (sizeof(struct sadb_msg) / sizeof(uint64_t)); =20 - pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ONE, sk, sock_net(sk)); + pfkey_broadcast(skb, BROADCAST_ONE, sk, sock_net(sk)); =20 return 0; } @@ -1361,7 +1361,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_bu= ff *skb, const struct sadb_ =20 xfrm_state_put(x); =20 - pfkey_broadcast(resp_skb, GFP_KERNEL, BROADCAST_ONE, sk, net); + pfkey_broadcast(resp_skb, BROADCAST_ONE, sk, net); =20 return 0; } @@ -1449,7 +1449,7 @@ static int key_notify_sa(struct xfrm_state *x, const = struct km_event *c) hdr->sadb_msg_seq =3D c->seq; hdr->sadb_msg_pid =3D c->pid; =20 - pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xs_net(x)); + pfkey_broadcast(skb, BROADCAST_ALL, NULL, xs_net(x)); =20 return 0; } @@ -1566,7 +1566,7 @@ static int pfkey_get(struct sock *sk, struct sk_buff = *skb, const struct sadb_msg out_hdr->sadb_msg_reserved =3D 0; out_hdr->sadb_msg_seq =3D hdr->sadb_msg_seq; out_hdr->sadb_msg_pid =3D hdr->sadb_msg_pid; - pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, sock_net(sk)); + pfkey_broadcast(out_skb, BROADCAST_ONE, sk, sock_net(sk)); =20 return 0; } @@ -1667,7 +1667,7 @@ static int pfkey_register(struct sock *sk, struct sk_= buff *skb, const struct sad return -ENOBUFS; } =20 - pfkey_broadcast(supp_skb, GFP_KERNEL, BROADCAST_REGISTERED, sk, sock_net(= sk)); + pfkey_broadcast(supp_skb, BROADCAST_REGISTERED, sk, sock_net(sk)); =20 return 0; } @@ -1686,7 +1686,7 @@ static int unicast_flush_resp(struct sock *sk, const = struct sadb_msg *ihdr) hdr->sadb_msg_errno =3D (uint8_t) 0; hdr->sadb_msg_len =3D (sizeof(struct sadb_msg) / sizeof(uint64_t)); =20 - return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ONE, sk, sock_net(sk)); + return pfkey_broadcast(skb, BROADCAST_ONE, sk, sock_net(sk)); } =20 static int key_notify_sa_flush(const struct km_event *c) @@ -1707,7 +1707,7 @@ static int key_notify_sa_flush(const struct km_event = *c) hdr->sadb_msg_len =3D (sizeof(struct sadb_msg) / sizeof(uint64_t)); hdr->sadb_msg_reserved =3D 0; =20 - pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); + pfkey_broadcast(skb, BROADCAST_ALL, NULL, c->net); =20 return 0; } @@ -1768,7 +1768,7 @@ static int dump_sa(struct xfrm_state *x, int count, v= oid *ptr) out_hdr->sadb_msg_pid =3D pfk->dump.msg_pid; =20 if (pfk->dump.skb) - pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, + pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE, &pfk->sk, sock_net(&pfk->sk)); pfk->dump.skb =3D out_skb; =20 @@ -1829,7 +1829,7 @@ static int pfkey_promisc(struct sock *sk, struct sk_b= uff *skb, const struct sadb new_hdr->sadb_msg_errno =3D 0; } =20 - pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ALL, NULL, sock_net(sk)); + pfkey_broadcast(skb, BROADCAST_ALL, NULL, sock_net(sk)); return 0; } =20 @@ -2160,7 +2160,7 @@ static int key_notify_policy(struct xfrm_policy *xp, = int dir, const struct km_ev out_hdr->sadb_msg_errno =3D 0; out_hdr->sadb_msg_seq =3D c->seq; out_hdr->sadb_msg_pid =3D c->pid; - pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xp_net(xp)); + pfkey_broadcast(out_skb, BROADCAST_ALL, NULL, xp_net(xp)); return 0; =20 } @@ -2386,7 +2386,7 @@ static int key_pol_get_resp(struct sock *sk, struct x= frm_policy *xp, const struc out_hdr->sadb_msg_errno =3D 0; out_hdr->sadb_msg_seq =3D hdr->sadb_msg_seq; out_hdr->sadb_msg_pid =3D hdr->sadb_msg_pid; - pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, xp_net(xp)); + pfkey_broadcast(out_skb, BROADCAST_ONE, sk, xp_net(xp)); err =3D 0; =20 out: @@ -2639,7 +2639,7 @@ static int dump_sp(struct xfrm_policy *xp, int dir, i= nt count, void *ptr) out_hdr->sadb_msg_pid =3D pfk->dump.msg_pid; =20 if (pfk->dump.skb) - pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, + pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE, &pfk->sk, sock_net(&pfk->sk)); pfk->dump.skb =3D out_skb; =20 @@ -2690,7 +2690,7 @@ static int key_notify_policy_flush(const struct km_ev= ent *c) hdr->sadb_msg_satype =3D SADB_SATYPE_UNSPEC; hdr->sadb_msg_len =3D (sizeof(struct sadb_msg) / sizeof(uint64_t)); hdr->sadb_msg_reserved =3D 0; - pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); + pfkey_broadcast(skb_out, BROADCAST_ALL, NULL, c->net); return 0; =20 } @@ -2756,7 +2756,7 @@ static int pfkey_process(struct sock *sk, struct sk_b= uff *skb, const struct sadb void *ext_hdrs[SADB_EXT_MAX]; int err; =20 - pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, + pfkey_broadcast(skb_clone(skb, GFP_KERNEL), BROADCAST_PROMISC_ONLY, NULL, sock_net(sk)); =20 memset(ext_hdrs, 0, sizeof(ext_hdrs)); @@ -2962,7 +2962,7 @@ static int key_notify_sa_expire(struct xfrm_state *x,= const struct km_event *c) out_hdr->sadb_msg_seq =3D 0; out_hdr->sadb_msg_pid =3D 0; =20 - pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, xs_net(x= )); + pfkey_broadcast(out_skb, BROADCAST_REGISTERED, NULL, xs_net(x)); return 0; } =20 @@ -3134,7 +3134,7 @@ static int pfkey_send_acquire(struct xfrm_state *x, s= truct xfrm_tmpl *t, struct xfrm_ctx->ctx_len); } =20 - return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, xs_ne= t(x)); + return pfkey_broadcast(skb, BROADCAST_REGISTERED, NULL, xs_net(x)); } =20 static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, @@ -3332,7 +3332,7 @@ static int pfkey_send_new_mapping(struct xfrm_state *= x, xfrm_address_t *ipaddr, n_port->sadb_x_nat_t_port_port =3D sport; n_port->sadb_x_nat_t_port_reserved =3D 0; =20 - return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, xs_ne= t(x)); + return pfkey_broadcast(skb, BROADCAST_REGISTERED, NULL, xs_net(x)); } =20 #ifdef CONFIG_NET_KEY_MIGRATE @@ -3524,7 +3524,7 @@ static int pfkey_send_migrate(const struct xfrm_selec= tor *sel, u8 dir, u8 type, } =20 /* broadcast migrate message to sockets */ - pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, &init_net); + pfkey_broadcast(skb, BROADCAST_ALL, NULL, &init_net); =20 return 0; =20 diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 65df296..91826b6 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -278,9 +278,6 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx= ) if (tx->sdata->vif.type =3D=3D NL80211_IFTYPE_WDS) return TX_CONTINUE; =20 - if (tx->sdata->vif.type =3D=3D NL80211_IFTYPE_MESH_POINT) - return TX_CONTINUE; - if (tx->flags & IEEE80211_TX_PS_BUFFERED) return TX_CONTINUE; =20 diff --git a/net/rds/connection.c b/net/rds/connection.c index 9e07c75..be3eecd 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -178,6 +178,12 @@ static struct rds_connection *__rds_conn_create(__be32= laddr, __be32 faddr, } } =20 + if (trans =3D=3D NULL) { + kmem_cache_free(rds_conn_slab, conn); + conn =3D ERR_PTR(-ENODEV); + goto out; + } + conn->c_trans =3D trans; =20 ret =3D trans->conn_alloc(conn, gfp); diff --git a/net/rds/info.c b/net/rds/info.c index f1c016c..a4adb39 100644 --- a/net/rds/info.c +++ b/net/rds/info.c @@ -176,7 +176,7 @@ int rds_info_getsockopt(struct socket *sock, int optnam= e, char __user *optval, =20 /* check for all kinds of wrapping and the like */ start =3D (unsigned long)optval; - if (len < 0 || len + PAGE_SIZE - 1 < len || start + len < start) { + if (len < 0 || len > INT_MAX - PAGE_SIZE + 1 || start + len < start) { ret =3D -EINVAL; goto out; } diff --git a/net/sctp/output.c b/net/sctp/output.c index 6d56eec..c3b8549 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -587,9 +587,7 @@ out: return err; no_route: kfree_skb(nskb); - - if (asoc) - IP_INC_STATS(&init_net, IPSTATS_MIB_OUTNOROUTES); + IP_INC_STATS(&init_net, IPSTATS_MIB_OUTNOROUTES); =20 /* FIXME: Returning the 'err' will effect all the associations * associated with a socket, although only one of the paths of the diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 76388b0..581c06a 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -681,7 +681,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, * outstanding data and rely on the retransmission limit be reached * to shutdown the association. */ - if (t->asoc->state !=3D SCTP_STATE_SHUTDOWN_PENDING) + if (t->asoc->state < SCTP_STATE_SHUTDOWN_PENDING) t->asoc->overall_error_count =3D 0; =20 /* Clear the hb_sent flag to signal that we had a good diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index d77a4f0..3a82fec 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -811,6 +811,7 @@ static void xs_reset_transport(struct sock_xprt *transp= ort) { struct socket *sock =3D transport->sock; struct sock *sk =3D transport->inet; + struct rpc_xprt *xprt =3D &transport->xprt; =20 if (sk =3D=3D NULL) return; @@ -824,6 +825,7 @@ static void xs_reset_transport(struct sock_xprt *transp= ort) sk->sk_user_data =3D NULL; =20 xs_restore_old_callbacks(transport, sk); + xprt_clear_connected(xprt); write_unlock_bh(&sk->sk_callback_lock); =20 sk->sk_no_check =3D 0; diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 058941e..580ecf2 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -1541,6 +1541,8 @@ static int accept(struct socket *sock, struct socket = *new_sock, int flags) u32 new_ref =3D new_tport->ref; struct tipc_msg *msg =3D buf_msg(buf); =20 + security_sk_clone(sock->sk, new_sock->sk); + lock_sock(new_sk); =20 /* diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streaml= ine_config.pl index 3346f42..4a19a7f 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -125,7 +125,7 @@ my $ksource =3D $ARGV[0]; my $kconfig =3D $ARGV[1]; my $lsmod_file =3D $ENV{'LSMOD'}; =20 -my @makefiles =3D `find $ksource -name Makefile 2>/dev/null`; +my @makefiles =3D `find $ksource -name Makefile -or -name Kbuild 2>/dev/nu= ll`; chomp @makefiles; =20 my %depends; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 0cd7097a..c279f2f 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1011,7 +1011,7 @@ static void selinux_write_opts(struct seq_file *m, seq_puts(m, prefix); if (has_comma) seq_putc(m, '\"'); - seq_puts(m, opts->mnt_opts[i]); + seq_escape(m, opts->mnt_opts[i], "\"\n\\"); if (has_comma) seq_putc(m, '\"'); } diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig index 885683a..e040621 100644 --- a/sound/arm/Kconfig +++ b/sound/arm/Kconfig @@ -9,6 +9,14 @@ menuconfig SND_ARM Drivers that are implemented on ASoC can be found in "ALSA for SoC audio support" section. =20 +config SND_PXA2XX_LIB + tristate + select SND_AC97_CODEC if SND_PXA2XX_LIB_AC97 + select SND_DMAENGINE_PCM + +config SND_PXA2XX_LIB_AC97 + bool + if SND_ARM =20 config SND_ARMAACI @@ -21,13 +29,6 @@ config SND_PXA2XX_PCM tristate select SND_PCM =20 -config SND_PXA2XX_LIB - tristate - select SND_AC97_CODEC if SND_PXA2XX_LIB_AC97 - -config SND_PXA2XX_LIB_AC97 - bool - config SND_PXA2XX_AC97 tristate "AC97 driver for the Intel PXA2xx chip" depends on ARCH_PXA diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index a0f7d3c..23deb67 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -1,7 +1,6 @@ config SND_PXA2XX_SOC tristate "SoC Audio for the Intel PXA2xx chip" depends on ARCH_PXA - select SND_ARM select SND_PXA2XX_LIB help Say Y or M if you want to add support for codecs attached to @@ -15,7 +14,6 @@ config SND_PXA2XX_AC97 config SND_PXA2XX_SOC_AC97 tristate select AC97_BUS - select SND_ARM select SND_PXA2XX_LIB_AC97 select SND_SOC_AC97_BUS =20 diff --git a/tools/perf/Makefile b/tools/perf/Makefile index e45d2b1..6c871c0 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -739,10 +739,10 @@ $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)P= ERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG=3D'"$(ETC_PERFCO= NFIG_SQ)"' $< =20 $(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines= /trace-event-perl.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redunda= nt-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $< + $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redunda= nt-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-unde= f -Wno-switch-default $< =20 $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-U= til/Context.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redunda= nt-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $= < + $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redunda= nt-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs -= Wno-undef -Wno-switch-default $< =20 $(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engin= es/trace-event-python.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redun= dant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $< diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 2cd88c1..7a75ecb 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -796,25 +796,19 @@ static void print_cpudesc(struct perf_header *ph, int= fd, FILE *fp) static void print_nrcpus(struct perf_header *ph, int fd, FILE *fp) { ssize_t ret; - u32 nr; + u32 nr[2]; =20 ret =3D read(fd, &nr, sizeof(nr)); if (ret !=3D (ssize_t)sizeof(nr)) - nr =3D -1; /* interpreted as error */ + nr[0] =3D nr[1] =3D -1; /* interpreted as error */ =20 - if (ph->needs_swap) - nr =3D bswap_32(nr); - - fprintf(fp, "# nrcpus online : %u\n", nr); - - ret =3D read(fd, &nr, sizeof(nr)); - if (ret !=3D (ssize_t)sizeof(nr)) - nr =3D -1; /* interpreted as error */ - - if (ph->needs_swap) - nr =3D bswap_32(nr); + if (ph->needs_swap) { + nr[0] =3D bswap_32(nr[0]); + nr[1] =3D bswap_32(nr[1]); + } =20 - fprintf(fp, "# nrcpus avail : %u\n", nr); + fprintf(fp, "# nrcpus online : %u\n", nr[1]); + fprintf(fp, "# nrcpus avail : %u\n", nr[0]); } =20 static void print_version(struct perf_header *ph, int fd, FILE *fp) =0D --=-/MQt7REM5T0IIpl/L0xm-- --=-TmS+nNz1jtzwiEHCe3Mc Content-Type: application/pgp-signature; name="signature.asc" Content-Description: This is a digitally signed message part -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIVAwUAVh1wW+e/yOyVhhEJAQoqBw//eVf1tT+xAHQrDWRtQT/GNPGRKLMfzv1V JXrg761Ld92hpgQHRlLB/lUX2xO6Z++2wrJDwv35CPVRKG3o8mH6oXgFwwWJOjCy kVR8AV5tTc3DDPb7vHM4wopIVoqJxC4zn/+QNqXjwnN1zcBnvW4otZojmvedTIjV Q9GHq6v9oOFWjolcj4UzaR+nyjU7W7bzFEcoBnBjNcQY+wBJngfW2vGDxW6wzcpw e++0u6lQpk0gCAE3XIzDiyqkKVd8o0y43Pw8IhCiBer5a6eIBCJHmWPbtWglSis0 60dQiOcASn5Q5Qi+cRRd/lO36yKUMFZ8QZOc3nC79AkknS1GwtmLYW+vanxz9lOF A/9hP+lCQgLXiMahejJFu1ev7OgxHYp74ZpcOhagTzblps68r4AJTZ9LUhjmrbDV 3wUmn4TtbCoRrD/ULf+IMy6B+135Y54xz98Xp3lkbXWkpTxJLdSpU3b7Ec/HGEmC llxWb6d7UbCKlX5E5nnnX8rsXri+dBfHborcv3FG01EpjekABs8zZ+x9lo3Tc9uT 6Ev3Q46mpIIJVDV9wPf+bSkwl9xbqw1u76SeWHf3FSJbmWUi2IH4kyfoBNvf9DCe K2SCA2DkU0uVTfrP2kYPo+6CTFyjK0SFQPdAxlVOqtfPWCJFsVM6JpTESDesBKsk Ub+lLloQrA4= =J4l/ -----END PGP SIGNATURE----- --=-TmS+nNz1jtzwiEHCe3Mc--