From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jordan Crouse Subject: [RFC PATCH v1 02/15] iommu/arm-smmu: Add split pagetable support for arm-smmu-v2 Date: Fri, 1 Mar 2019 12:38:24 -0700 Message-ID: <1551469117-3404-3-git-send-email-jcrouse@codeaurora.org> References: <1551469117-3404-1-git-send-email-jcrouse@codeaurora.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1551469117-3404-1-git-send-email-jcrouse-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: freedreno-bounces-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org Sender: "Freedreno" To: freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org Cc: jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Joerg Roedel , Will Deacon , linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org, dianders-uWgjrcJnOmJ4cg9Nei1l7Q@public.gmane.org, hoegsberg-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org, Robin Murphy , linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org, baolu.lu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org List-Id: linux-arm-msm@vger.kernel.org QWRkIHN1cHBvcnQgZm9yIGEgc3BsaXQgcGFnZXRhYmxlIChUVEJSMC9UVEJSMSkgc2NoZW1lIGZv cgphcm0tc21tdS12Mi4gSWYgc3BsaXQgcGFnZXRhYmxlcyBhcmUgZW5hYmxlZCwgY3JlYXRlIGEK cGFnZXRhYmxlIGZvciBUVEJSMSBhbmQgc2V0IHVwIHRoZSBzaWduIGV4dGVuc2lvbiBiaXQgc28K dGhhdCBhbGwgSU9WQXMgd2l0aCB0aGF0IGJpdCBzZXQgYXJlIG1hcHBlZCBhbmQgdHJhbnNsYXRl ZApmcm9tIHRoZSBUVEJSMSBwYWdldGFibGUuCgpTaWduZWQtb2ZmLWJ5OiBKb3JkYW4gQ3JvdXNl IDxqY3JvdXNlQGNvZGVhdXJvcmEub3JnPgotLS0KCiBkcml2ZXJzL2lvbW11L2FybS1zbW11LXJl Z3MuaCAgfCAgMTggKysrKysKIGRyaXZlcnMvaW9tbXUvYXJtLXNtbXUuYyAgICAgICB8IDE0OSAr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrLS0tLQogZHJpdmVycy9pb21tdS9p by1wZ3RhYmxlLWFybS5jIHwgICAzICstCiAzIGZpbGVzIGNoYW5nZWQsIDE1NCBpbnNlcnRpb25z KCspLCAxNiBkZWxldGlvbnMoLSkKCmRpZmYgLS1naXQgYS9kcml2ZXJzL2lvbW11L2FybS1zbW11 LXJlZ3MuaCBiL2RyaXZlcnMvaW9tbXUvYXJtLXNtbXUtcmVncy5oCmluZGV4IGExMjI2ZTQuLjU2 Zjk3MDkgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvaW9tbXUvYXJtLXNtbXUtcmVncy5oCisrKyBiL2Ry aXZlcnMvaW9tbXUvYXJtLXNtbXUtcmVncy5oCkBAIC0xOTMsNyArMTkzLDI1IEBAIGVudW0gYXJt X3NtbXVfczJjcl9wcml2Y2ZnIHsKICNkZWZpbmUgUkVTVU1FX1JFVFJZCQkJKDAgPDwgMCkKICNk ZWZpbmUgUkVTVU1FX1RFUk1JTkFURQkJKDEgPDwgMCkKIAorI2RlZmluZSBUVEJDUl9FUEQxCQkJ KDEgPDwgMjMpCisjZGVmaW5lIFRUQkNSX1QxU1pfU0hJRlQJCTE2CisjZGVmaW5lIFRUQkNSX0lS R04xX1NISUZUCQkyNAorI2RlZmluZSBUVEJDUl9PUkdOMV9TSElGVAkJMjYKKyNkZWZpbmUgVFRC Q1JfUkdOX1dCV0EJCQkxCisjZGVmaW5lIFRUQkNSX1NIMV9TSElGVAkJCTI4CisjZGVmaW5lIFRU QkNSX1NIX0lTCQkJMworCisjZGVmaW5lIFRUQkNSX1RHMV8xNksJCQkoMSA8PCAzMCkKKyNkZWZp bmUgVFRCQ1JfVEcxXzRLCQkJKDIgPDwgMzApCisjZGVmaW5lIFRUQkNSX1RHMV82NEsJCQkoMyA8 PCAzMCkKKwogI2RlZmluZSBUVEJDUjJfU0VQX1NISUZUCQkxNQorI2RlZmluZSBUVEJDUjJfU0VQ XzMxCQkJKDB4MCA8PCBUVEJDUjJfU0VQX1NISUZUKQorI2RlZmluZSBUVEJDUjJfU0VQXzM1CQkJ KDB4MSA8PCBUVEJDUjJfU0VQX1NISUZUKQorI2RlZmluZSBUVEJDUjJfU0VQXzM5CQkJKDB4MiA8 PCBUVEJDUjJfU0VQX1NISUZUKQorI2RlZmluZSBUVEJDUjJfU0VQXzQxCQkJKDB4MyA8PCBUVEJD UjJfU0VQX1NISUZUKQorI2RlZmluZSBUVEJDUjJfU0VQXzQzCQkJKDB4NCA8PCBUVEJDUjJfU0VQ X1NISUZUKQorI2RlZmluZSBUVEJDUjJfU0VQXzQ3CQkJKDB4NSA8PCBUVEJDUjJfU0VQX1NISUZU KQogI2RlZmluZSBUVEJDUjJfU0VQX1VQU1RSRUFNCQkoMHg3IDw8IFRUQkNSMl9TRVBfU0hJRlQp CiAjZGVmaW5lIFRUQkNSMl9BUwkJCSgxIDw8IDQpCiAKZGlmZiAtLWdpdCBhL2RyaXZlcnMvaW9t bXUvYXJtLXNtbXUuYyBiL2RyaXZlcnMvaW9tbXUvYXJtLXNtbXUuYwppbmRleCBhZjE4YTdlLi4w NWViMTI2IDEwMDY0NAotLS0gYS9kcml2ZXJzL2lvbW11L2FybS1zbW11LmMKKysrIGIvZHJpdmVy cy9pb21tdS9hcm0tc21tdS5jCkBAIC0xNTEsNiArMTUxLDcgQEAgc3RydWN0IGFybV9zbW11X2Ni IHsKIAl1MzIJCQkJdGNyWzJdOwogCXUzMgkJCQltYWlyWzJdOwogCXN0cnVjdCBhcm1fc21tdV9j ZmcJCSpjZmc7CisJdTY0CQkJCXNwbGl0X3RhYmxlX21hc2s7CiB9OwogCiBzdHJ1Y3QgYXJtX3Nt bXVfbWFzdGVyX2NmZyB7CkBAIC0yMDgsNiArMjA5LDcgQEAgc3RydWN0IGFybV9zbW11X2Rldmlj ZSB7CiAJdW5zaWduZWQgbG9uZwkJCXZhX3NpemU7CiAJdW5zaWduZWQgbG9uZwkJCWlwYV9zaXpl OwogCXVuc2lnbmVkIGxvbmcJCQlwYV9zaXplOworCXVuc2lnbmVkIGxvbmcJCQl1YnNfc2l6ZTsK IAl1bnNpZ25lZCBsb25nCQkJcGdzaXplX2JpdG1hcDsKIAogCXUzMgkJCQludW1fZ2xvYmFsX2ly cXM7CkBAIC0yNTIsMTMgKzI1NCwxNCBAQCBlbnVtIGFybV9zbW11X2RvbWFpbl9zdGFnZSB7CiAK IHN0cnVjdCBhcm1fc21tdV9kb21haW4gewogCXN0cnVjdCBhcm1fc21tdV9kZXZpY2UJCSpzbW11 OwotCXN0cnVjdCBpb19wZ3RhYmxlX29wcwkJKnBndGJsX29wczsKKwlzdHJ1Y3QgaW9fcGd0YWJs ZV9vcHMJCSpwZ3RibF9vcHNbMl07CiAJY29uc3Qgc3RydWN0IGlvbW11X2dhdGhlcl9vcHMJKnRs Yl9vcHM7CiAJc3RydWN0IGFybV9zbW11X2NmZwkJY2ZnOwogCWVudW0gYXJtX3NtbXVfZG9tYWlu X3N0YWdlCXN0YWdlOwogCWJvb2wJCQkJbm9uX3N0cmljdDsKIAlzdHJ1Y3QgbXV0ZXgJCQlpbml0 X211dGV4OyAvKiBQcm90ZWN0cyBzbW11IHBvaW50ZXIgKi8KIAlzcGlubG9ja190CQkJY2JfbG9j azsgLyogU2VyaWFsaXNlcyBBVFMxKiBvcHMgYW5kIFRMQiBzeW5jcyAqLworCXUzMiBhdHRyaWJ1 dGVzOwogCXN0cnVjdCBpb21tdV9kb21haW4JCWRvbWFpbjsKIH07CiAKQEAgLTYxOCw2ICs2MjEs NjkgQEAgc3RhdGljIGlycXJldHVybl90IGFybV9zbW11X2dsb2JhbF9mYXVsdChpbnQgaXJxLCB2 b2lkICpkZXYpCiAJcmV0dXJuIElSUV9IQU5ETEVEOwogfQogCitzdGF0aWMgdm9pZCBhcm1fc21t dV9pbml0X3R0YnIxKHN0cnVjdCBhcm1fc21tdV9kb21haW4gKnNtbXVfZG9tYWluLAorCQlzdHJ1 Y3QgaW9fcGd0YWJsZV9jZmcgKnBndGJsX2NmZykKK3sKKwlzdHJ1Y3QgYXJtX3NtbXVfZGV2aWNl ICpzbW11ID0gc21tdV9kb21haW4tPnNtbXU7CisJc3RydWN0IGFybV9zbW11X2NmZyAqY2ZnID0g JnNtbXVfZG9tYWluLT5jZmc7CisJc3RydWN0IGFybV9zbW11X2NiICpjYiA9ICZzbW11X2RvbWFp bi0+c21tdS0+Y2JzW2NmZy0+Y2JuZHhdOworCWludCBwZ3NpemUgPSAxIDw8IF9fZmZzKHBndGJs X2NmZy0+cGdzaXplX2JpdG1hcCk7CisKKwkvKiBFbmFibGUgc3BlY3VsYXRpdmUgd2Fsa3MgdGhy b3VnaCB0aGUgVFRCUjEgKi8KKwljYi0+dGNyWzBdICY9IH5UVEJDUl9FUEQxOworCisJY2ItPnRj clswXSB8PSBUVEJDUl9TSF9JUyA8PCBUVEJDUl9TSDFfU0hJRlQ7CisJY2ItPnRjclswXSB8PSBU VEJDUl9SR05fV0JXQSA8PCBUVEJDUl9JUkdOMV9TSElGVDsKKwljYi0+dGNyWzBdIHw9IFRUQkNS X1JHTl9XQldBIDw8IFRUQkNSX09SR04xX1NISUZUOworCisJc3dpdGNoIChwZ3NpemUpIHsKKwlj YXNlIFNaXzRLOgorCQljYi0+dGNyWzBdIHw9IFRUQkNSX1RHMV80SzsKKwkJYnJlYWs7CisJY2Fz ZSBTWl8xNks6CisJCWNiLT50Y3JbMF0gfD0gVFRCQ1JfVEcxXzE2SzsKKwkJYnJlYWs7CisJY2Fz ZSBTWl82NEs6CisJCWNiLT50Y3JbMF0gfD0gVFRCQ1JfVEcxXzY0SzsKKwkJYnJlYWs7CisJfQor CisJY2ItPnRjclswXSB8PSAoNjRVTEwgLSBzbW11LT52YV9zaXplKSA8PCBUVEJDUl9UMVNaX1NI SUZUOworCisJLyogQ2xlYXIgdGhlIGV4aXN0aW5nIFNFUCBjb25maWd1cmF0aW9uICovCisJY2It PnRjclsxXSAmPSB+VFRCQ1IyX1NFUF9VUFNUUkVBTTsKKworCS8qIFNldCB1cCB0aGUgc2lnbiBl eHRlbmQgYml0ICovCisJc3dpdGNoIChzbW11LT52YV9zaXplKSB7CisJY2FzZSAzMjoKKwkJY2It PnRjclsxXSB8PSBUVEJDUjJfU0VQXzMxOworCQljYi0+c3BsaXRfdGFibGVfbWFzayA9ICgxVUxM IDw8IDMxKTsKKwkJYnJlYWs7CisJY2FzZSAzNjoKKwkJY2ItPnRjclsxXSB8PSBUVEJDUjJfU0VQ XzM1OworCQljYi0+c3BsaXRfdGFibGVfbWFzayA9ICgxVUxMIDw8IDM1KTsKKwkJYnJlYWs7CisJ Y2FzZSA0MDoKKwkJY2ItPnRjclsxXSB8PSBUVEJDUjJfU0VQXzM5OworCQljYi0+c3BsaXRfdGFi bGVfbWFzayA9ICgxVUxMIDw8IDM5KTsKKwkJYnJlYWs7CisJY2FzZSA0MjoKKwkJY2ItPnRjclsx XSB8PSBUVEJDUjJfU0VQXzQxOworCQljYi0+c3BsaXRfdGFibGVfbWFzayA9ICgxVUxMIDw8IDQx KTsKKwkJYnJlYWs7CisJY2FzZSA0NDoKKwkJY2ItPnRjclsxXSB8PSBUVEJDUjJfU0VQXzQzOwor CQljYi0+c3BsaXRfdGFibGVfbWFzayA9ICgxVUxMIDw8IDQzKTsKKwkJYnJlYWs7CisJY2FzZSA0 ODoKKwkJY2ItPnRjclsxXSB8PSBUVEJDUjJfU0VQX1VQU1RSRUFNOworCQljYi0+c3BsaXRfdGFi bGVfbWFzayA9ICgxVUxMIDw8IDQ4KTsKKwl9CisKKwljYi0+dHRiclsxXSA9IHBndGJsX2NmZy0+ YXJtX2xwYWVfczFfY2ZnLnR0YnJbMF07CisJY2ItPnR0YnJbMV0gfD0gKHU2NCljZmctPmFzaWQg PDwgVFRCUm5fQVNJRF9TSElGVDsKK30KKwogc3RhdGljIHZvaWQgYXJtX3NtbXVfaW5pdF9jb250 ZXh0X2Jhbmsoc3RydWN0IGFybV9zbW11X2RvbWFpbiAqc21tdV9kb21haW4sCiAJCQkJICAgICAg IHN0cnVjdCBpb19wZ3RhYmxlX2NmZyAqcGd0YmxfY2ZnKQogewpAQCAtNjUwLDggKzcxNiwxMiBA QCBzdGF0aWMgdm9pZCBhcm1fc21tdV9pbml0X2NvbnRleHRfYmFuayhzdHJ1Y3QgYXJtX3NtbXVf ZG9tYWluICpzbW11X2RvbWFpbiwKIAkJfSBlbHNlIHsKIAkJCWNiLT50dGJyWzBdID0gcGd0Ymxf Y2ZnLT5hcm1fbHBhZV9zMV9jZmcudHRiclswXTsKIAkJCWNiLT50dGJyWzBdIHw9ICh1NjQpY2Zn LT5hc2lkIDw8IFRUQlJuX0FTSURfU0hJRlQ7Ci0JCQljYi0+dHRiclsxXSA9IHBndGJsX2NmZy0+ YXJtX2xwYWVfczFfY2ZnLnR0YnJbMV07Ci0JCQljYi0+dHRiclsxXSB8PSAodTY0KWNmZy0+YXNp ZCA8PCBUVEJSbl9BU0lEX1NISUZUOworCisJCQkvKgorCQkJICogU2V0IFRUQlIxIHRvIGVtcHR5 IGJ5IGRlZmF1bHQgLSBpdCB3aWxsIGdldAorCQkJICogcHJvZ3JhbW1lZCBsYXRlciBpZiBpdCBp cyBlbmFibGVkCisJCQkgKi8KKwkJCWNiLT50dGJyWzFdID0gKHU2NCljZmctPmFzaWQgPDwgVFRC Um5fQVNJRF9TSElGVDsKIAkJfQogCX0gZWxzZSB7CiAJCWNiLT50dGJyWzBdID0gcGd0YmxfY2Zn LT5hcm1fbHBhZV9zMl9jZmcudnR0YnI7CkBAIC03NjAsMTEgKzgzMCwxMyBAQCBzdGF0aWMgaW50 IGFybV9zbW11X2luaXRfZG9tYWluX2NvbnRleHQoc3RydWN0IGlvbW11X2RvbWFpbiAqZG9tYWlu LAogewogCWludCBpcnEsIHN0YXJ0LCByZXQgPSAwOwogCXVuc2lnbmVkIGxvbmcgaWFzLCBvYXM7 Ci0Jc3RydWN0IGlvX3BndGFibGVfb3BzICpwZ3RibF9vcHM7CisJc3RydWN0IGlvX3BndGFibGVf b3BzICpwZ3RibF9vcHNbMl07CiAJc3RydWN0IGlvX3BndGFibGVfY2ZnIHBndGJsX2NmZzsKIAll bnVtIGlvX3BndGFibGVfZm10IGZtdDsKIAlzdHJ1Y3QgYXJtX3NtbXVfZG9tYWluICpzbW11X2Rv bWFpbiA9IHRvX3NtbXVfZG9tYWluKGRvbWFpbik7CiAJc3RydWN0IGFybV9zbW11X2NmZyAqY2Zn ID0gJnNtbXVfZG9tYWluLT5jZmc7CisJYm9vbCBzcGxpdF90YWJsZXMgPQorCQkoc21tdV9kb21h aW4tPmF0dHJpYnV0ZXMgJiAoMSA8PCBET01BSU5fQVRUUl9TUExJVF9UQUJMRVMpKTsKIAogCW11 dGV4X2xvY2soJnNtbXVfZG9tYWluLT5pbml0X211dGV4KTsKIAlpZiAoc21tdV9kb21haW4tPnNt bXUpCkBAIC03OTQsOCArODY2LDExIEBAIHN0YXRpYyBpbnQgYXJtX3NtbXVfaW5pdF9kb21haW5f Y29udGV4dChzdHJ1Y3QgaW9tbXVfZG9tYWluICpkb21haW4sCiAJICoKIAkgKiBOb3RlIHRoYXQg eW91IGNhbid0IGFjdHVhbGx5IHJlcXVlc3Qgc3RhZ2UtMiBtYXBwaW5ncy4KIAkgKi8KLQlpZiAo IShzbW11LT5mZWF0dXJlcyAmIEFSTV9TTU1VX0ZFQVRfVFJBTlNfUzEpKQorCWlmICghKHNtbXUt PmZlYXR1cmVzICYgQVJNX1NNTVVfRkVBVF9UUkFOU19TMSkpIHsKIAkJc21tdV9kb21haW4tPnN0 YWdlID0gQVJNX1NNTVVfRE9NQUlOX1MyOworCQkvKiBGSVhNRTogZmFpbCBpbnN0ZWFkPyAqLwor CQlzcGxpdF90YWJsZXMgPSBmYWxzZTsKKwl9CiAJaWYgKCEoc21tdS0+ZmVhdHVyZXMgJiBBUk1f U01NVV9GRUFUX1RSQU5TX1MyKSkKIAkJc21tdV9kb21haW4tPnN0YWdlID0gQVJNX1NNTVVfRE9N QUlOX1MxOwogCkBAIC04MTIsOCArODg3LDExIEBAIHN0YXRpYyBpbnQgYXJtX3NtbXVfaW5pdF9k b21haW5fY29udGV4dChzdHJ1Y3QgaW9tbXVfZG9tYWluICpkb21haW4sCiAJaWYgKElTX0VOQUJM RUQoQ09ORklHX0lPTU1VX0lPX1BHVEFCTEVfQVJNVjdTKSAmJgogCSAgICAhSVNfRU5BQkxFRChD T05GSUdfNjRCSVQpICYmICFJU19FTkFCTEVEKENPTkZJR19BUk1fTFBBRSkgJiYKIAkgICAgKHNt bXUtPmZlYXR1cmVzICYgQVJNX1NNTVVfRkVBVF9GTVRfQUFSQ0gzMl9TKSAmJgotCSAgICAoc21t dV9kb21haW4tPnN0YWdlID09IEFSTV9TTU1VX0RPTUFJTl9TMSkpCisJICAgIChzbW11X2RvbWFp bi0+c3RhZ2UgPT0gQVJNX1NNTVVfRE9NQUlOX1MxKSkgeworCQkvKiBGSVhNRTogZmFpbCBpbnN0 ZWFkPyAqLworCQlzcGxpdF90YWJsZXMgPSBmYWxzZTsKIAkJY2ZnLT5mbXQgPSBBUk1fU01NVV9D VFhfRk1UX0FBUkNIMzJfUzsKKwl9CiAJaWYgKChJU19FTkFCTEVEKENPTkZJR182NEJJVCkgfHwg Y2ZnLT5mbXQgPT0gQVJNX1NNTVVfQ1RYX0ZNVF9OT05FKSAmJgogCSAgICAoc21tdS0+ZmVhdHVy ZXMgJiAoQVJNX1NNTVVfRkVBVF9GTVRfQUFSQ0g2NF82NEsgfAogCQkJICAgICAgIEFSTV9TTU1V X0ZFQVRfRk1UX0FBUkNINjRfMTZLIHwKQEAgLTkwMyw4ICs5ODEsOCBAQCBzdGF0aWMgaW50IGFy bV9zbW11X2luaXRfZG9tYWluX2NvbnRleHQoc3RydWN0IGlvbW11X2RvbWFpbiAqZG9tYWluLAog CQlwZ3RibF9jZmcucXVpcmtzIHw9IElPX1BHVEFCTEVfUVVJUktfTk9OX1NUUklDVDsKIAogCXNt bXVfZG9tYWluLT5zbW11ID0gc21tdTsKLQlwZ3RibF9vcHMgPSBhbGxvY19pb19wZ3RhYmxlX29w cyhmbXQsICZwZ3RibF9jZmcsIHNtbXVfZG9tYWluKTsKLQlpZiAoIXBndGJsX29wcykgeworCXBn dGJsX29wc1swXSA9IGFsbG9jX2lvX3BndGFibGVfb3BzKGZtdCwgJnBndGJsX2NmZywgc21tdV9k b21haW4pOworCWlmICghcGd0Ymxfb3BzWzBdKSB7CiAJCXJldCA9IC1FTk9NRU07CiAJCWdvdG8g b3V0X2NsZWFyX3NtbXU7CiAJfQpAQCAtOTE2LDYgKzk5NCwyMiBAQCBzdGF0aWMgaW50IGFybV9z bW11X2luaXRfZG9tYWluX2NvbnRleHQoc3RydWN0IGlvbW11X2RvbWFpbiAqZG9tYWluLAogCiAJ LyogSW5pdGlhbGlzZSB0aGUgY29udGV4dCBiYW5rIHdpdGggb3VyIHBhZ2UgdGFibGUgY2ZnICov CiAJYXJtX3NtbXVfaW5pdF9jb250ZXh0X2Jhbmsoc21tdV9kb21haW4sICZwZ3RibF9jZmcpOwor CisJcGd0Ymxfb3BzWzFdID0gTlVMTDsKKworCWlmIChzcGxpdF90YWJsZXMpIHsKKwkJLyogRklY TUU6IEkgdGhpbmsgaXQgaXMgc2FmZSB0byByZXVzZSBwZ3RibF9jZmcgaGVyZSAqLworCQlwZ3Ri bF9vcHNbMV0gPSBhbGxvY19pb19wZ3RhYmxlX29wcyhmbXQsICZwZ3RibF9jZmcsCisJCQlzbW11 X2RvbWFpbik7CisJCWlmICghcGd0Ymxfb3BzWzFdKSB7CisJCQlmcmVlX2lvX3BndGFibGVfb3Bz KHBndGJsX29wc1swXSk7CisJCQlyZXQgPSAtRU5PTUVNOworCQkJZ290byBvdXRfY2xlYXJfc21t dTsKKwkJfQorCisJCWFybV9zbW11X2luaXRfdHRicjEoc21tdV9kb21haW4sICZwZ3RibF9jZmcp OworCX0KKwogCWFybV9zbW11X3dyaXRlX2NvbnRleHRfYmFuayhzbW11LCBjZmctPmNibmR4KTsK IAogCS8qCkBAIC05MzQsNyArMTAyOCw5IEBAIHN0YXRpYyBpbnQgYXJtX3NtbXVfaW5pdF9kb21h aW5fY29udGV4dChzdHJ1Y3QgaW9tbXVfZG9tYWluICpkb21haW4sCiAJbXV0ZXhfdW5sb2NrKCZz bW11X2RvbWFpbi0+aW5pdF9tdXRleCk7CiAKIAkvKiBQdWJsaXNoIHBhZ2UgdGFibGUgb3BzIGZv ciBtYXAvdW5tYXAgKi8KLQlzbW11X2RvbWFpbi0+cGd0Ymxfb3BzID0gcGd0Ymxfb3BzOworCXNt bXVfZG9tYWluLT5wZ3RibF9vcHNbMF0gPSBwZ3RibF9vcHNbMF07CisJc21tdV9kb21haW4tPnBn dGJsX29wc1sxXSA9IHBndGJsX29wc1sxXTsKKwogCXJldHVybiAwOwogCiBvdXRfY2xlYXJfc21t dToKQEAgLTk3MCw3ICsxMDY2LDkgQEAgc3RhdGljIHZvaWQgYXJtX3NtbXVfZGVzdHJveV9kb21h aW5fY29udGV4dChzdHJ1Y3QgaW9tbXVfZG9tYWluICpkb21haW4pCiAJCWRldm1fZnJlZV9pcnEo c21tdS0+ZGV2LCBpcnEsIGRvbWFpbik7CiAJfQogCi0JZnJlZV9pb19wZ3RhYmxlX29wcyhzbW11 X2RvbWFpbi0+cGd0Ymxfb3BzKTsKKwlmcmVlX2lvX3BndGFibGVfb3BzKHNtbXVfZG9tYWluLT5w Z3RibF9vcHNbMF0pOworCWZyZWVfaW9fcGd0YWJsZV9vcHMoc21tdV9kb21haW4tPnBndGJsX29w c1sxXSk7CisKIAlfX2FybV9zbW11X2ZyZWVfYml0bWFwKHNtbXUtPmNvbnRleHRfbWFwLCBjZmct PmNibmR4KTsKIAogCWFybV9zbW11X3JwbV9wdXQoc21tdSk7CkBAIC0xMjg1LDEwICsxMzgzLDIz IEBAIHN0YXRpYyBpbnQgYXJtX3NtbXVfYXR0YWNoX2RldihzdHJ1Y3QgaW9tbXVfZG9tYWluICpk b21haW4sIHN0cnVjdCBkZXZpY2UgKmRldikKIAlyZXR1cm4gcmV0OwogfQogCitzdGF0aWMgc3Ry dWN0IGlvX3BndGFibGVfb3BzICoKK2FybV9zbW11X2dldF9wZ3RibF9vcHMoc3RydWN0IGlvbW11 X2RvbWFpbiAqZG9tYWluLCB1bnNpZ25lZCBsb25nIGlvdmEpCit7CisJc3RydWN0IGFybV9zbW11 X2RvbWFpbiAqc21tdV9kb21haW4gPSB0b19zbW11X2RvbWFpbihkb21haW4pOworCXN0cnVjdCBh cm1fc21tdV9jZmcgKmNmZyA9ICZzbW11X2RvbWFpbi0+Y2ZnOworCXN0cnVjdCBhcm1fc21tdV9j YiAqY2IgPSAmc21tdV9kb21haW4tPnNtbXUtPmNic1tjZmctPmNibmR4XTsKKworCWlmIChpb3Zh ICYgY2ItPnNwbGl0X3RhYmxlX21hc2spCisJCXJldHVybiBzbW11X2RvbWFpbi0+cGd0Ymxfb3Bz WzFdOworCisJcmV0dXJuIHNtbXVfZG9tYWluLT5wZ3RibF9vcHNbMF07Cit9CisKIHN0YXRpYyBp bnQgYXJtX3NtbXVfbWFwKHN0cnVjdCBpb21tdV9kb21haW4gKmRvbWFpbiwgdW5zaWduZWQgbG9u ZyBpb3ZhLAogCQkJcGh5c19hZGRyX3QgcGFkZHIsIHNpemVfdCBzaXplLCBpbnQgcHJvdCkKIHsK LQlzdHJ1Y3QgaW9fcGd0YWJsZV9vcHMgKm9wcyA9IHRvX3NtbXVfZG9tYWluKGRvbWFpbiktPnBn dGJsX29wczsKKwlzdHJ1Y3QgaW9fcGd0YWJsZV9vcHMgKm9wcyA9IGFybV9zbW11X2dldF9wZ3Ri bF9vcHMoZG9tYWluLCBpb3ZhKTsKIAlzdHJ1Y3QgYXJtX3NtbXVfZGV2aWNlICpzbW11ID0gdG9f c21tdV9kb21haW4oZG9tYWluKS0+c21tdTsKIAlpbnQgcmV0OwogCkBAIC0xMzA1LDcgKzE0MTYs NyBAQCBzdGF0aWMgaW50IGFybV9zbW11X21hcChzdHJ1Y3QgaW9tbXVfZG9tYWluICpkb21haW4s IHVuc2lnbmVkIGxvbmcgaW92YSwKIHN0YXRpYyBzaXplX3QgYXJtX3NtbXVfdW5tYXAoc3RydWN0 IGlvbW11X2RvbWFpbiAqZG9tYWluLCB1bnNpZ25lZCBsb25nIGlvdmEsCiAJCQkgICAgIHNpemVf dCBzaXplKQogewotCXN0cnVjdCBpb19wZ3RhYmxlX29wcyAqb3BzID0gdG9fc21tdV9kb21haW4o ZG9tYWluKS0+cGd0Ymxfb3BzOworCXN0cnVjdCBpb19wZ3RhYmxlX29wcyAqb3BzID0gYXJtX3Nt bXVfZ2V0X3BndGJsX29wcyhkb21haW4sIGlvdmEpOwogCXN0cnVjdCBhcm1fc21tdV9kZXZpY2Ug KnNtbXUgPSB0b19zbW11X2RvbWFpbihkb21haW4pLT5zbW11OwogCXNpemVfdCByZXQ7CiAKQEAg LTEzNDksNyArMTQ2MCw3IEBAIHN0YXRpYyBwaHlzX2FkZHJfdCBhcm1fc21tdV9pb3ZhX3RvX3Bo eXNfaGFyZChzdHJ1Y3QgaW9tbXVfZG9tYWluICpkb21haW4sCiAJc3RydWN0IGFybV9zbW11X2Rv bWFpbiAqc21tdV9kb21haW4gPSB0b19zbW11X2RvbWFpbihkb21haW4pOwogCXN0cnVjdCBhcm1f c21tdV9kZXZpY2UgKnNtbXUgPSBzbW11X2RvbWFpbi0+c21tdTsKIAlzdHJ1Y3QgYXJtX3NtbXVf Y2ZnICpjZmcgPSAmc21tdV9kb21haW4tPmNmZzsKLQlzdHJ1Y3QgaW9fcGd0YWJsZV9vcHMgKm9w cz0gc21tdV9kb21haW4tPnBndGJsX29wczsKKwlzdHJ1Y3QgaW9fcGd0YWJsZV9vcHMgKm9wcyA9 IGFybV9zbW11X2dldF9wZ3RibF9vcHMoZG9tYWluLCBpb3ZhKTsKIAlzdHJ1Y3QgZGV2aWNlICpk ZXYgPSBzbW11LT5kZXY7CiAJdm9pZCBfX2lvbWVtICpjYl9iYXNlOwogCXUzMiB0bXA7CkBAIC0x Mzk3LDcgKzE1MDgsNyBAQCBzdGF0aWMgcGh5c19hZGRyX3QgYXJtX3NtbXVfaW92YV90b19waHlz KHN0cnVjdCBpb21tdV9kb21haW4gKmRvbWFpbiwKIAkJCQkJZG1hX2FkZHJfdCBpb3ZhKQogewog CXN0cnVjdCBhcm1fc21tdV9kb21haW4gKnNtbXVfZG9tYWluID0gdG9fc21tdV9kb21haW4oZG9t YWluKTsKLQlzdHJ1Y3QgaW9fcGd0YWJsZV9vcHMgKm9wcyA9IHNtbXVfZG9tYWluLT5wZ3RibF9v cHM7CisJc3RydWN0IGlvX3BndGFibGVfb3BzICpvcHMgPSBhcm1fc21tdV9nZXRfcGd0Ymxfb3Bz KGRvbWFpbiwgaW92YSk7CiAKIAlpZiAoZG9tYWluLT50eXBlID09IElPTU1VX0RPTUFJTl9JREVO VElUWSkKIAkJcmV0dXJuIGlvdmE7CkBAIC0xNTg0LDYgKzE2OTUsMTEgQEAgc3RhdGljIGludCBh cm1fc21tdV9kb21haW5fZ2V0X2F0dHIoc3RydWN0IGlvbW11X2RvbWFpbiAqZG9tYWluLAogCQlj YXNlIERPTUFJTl9BVFRSX05FU1RJTkc6CiAJCQkqKGludCAqKWRhdGEgPSAoc21tdV9kb21haW4t PnN0YWdlID09IEFSTV9TTU1VX0RPTUFJTl9ORVNURUQpOwogCQkJcmV0dXJuIDA7CisJCWNhc2Ug RE9NQUlOX0FUVFJfU1BMSVRfVEFCTEVTOgorCQkJKigoaW50ICopZGF0YSkgPQorCQkJCSEhKHNt bXVfZG9tYWluLT5hdHRyaWJ1dGVzICYKKwkJCQkgICAoMSA8PCBET01BSU5fQVRUUl9TUExJVF9U QUJMRVMpKTsKKwkJCXJldHVybiAwOwogCQlkZWZhdWx0OgogCQkJcmV0dXJuIC1FTk9ERVY7CiAJ CX0KQEAgLTE2MjQsNiArMTc0MCwxMSBAQCBzdGF0aWMgaW50IGFybV9zbW11X2RvbWFpbl9zZXRf YXR0cihzdHJ1Y3QgaW9tbXVfZG9tYWluICpkb21haW4sCiAJCQllbHNlCiAJCQkJc21tdV9kb21h aW4tPnN0YWdlID0gQVJNX1NNTVVfRE9NQUlOX1MxOwogCQkJYnJlYWs7CisJCWNhc2UgRE9NQUlO X0FUVFJfU1BMSVRfVEFCTEVTOgorCQkJaWYgKCooKGludCAqKWRhdGEpKQorCQkJCXNtbXVfZG9t YWluLT5hdHRyaWJ1dGVzIHw9CisJCQkJCSgxIDw8IERPTUFJTl9BVFRSX1NQTElUX1RBQkxFUyk7 CisJCQlicmVhazsKIAkJZGVmYXVsdDoKIAkJCXJldCA9IC1FTk9ERVY7CiAJCX0KZGlmZiAtLWdp dCBhL2RyaXZlcnMvaW9tbXUvaW8tcGd0YWJsZS1hcm0uYyBiL2RyaXZlcnMvaW9tbXUvaW8tcGd0 YWJsZS1hcm0uYwppbmRleCAyMzdjYWNkLi5kYzlmYjJlIDEwMDY0NAotLS0gYS9kcml2ZXJzL2lv bW11L2lvLXBndGFibGUtYXJtLmMKKysrIGIvZHJpdmVycy9pb21tdS9pby1wZ3RhYmxlLWFybS5j CkBAIC00NzUsOCArNDc1LDcgQEAgc3RhdGljIGludCBhcm1fbHBhZV9tYXAoc3RydWN0IGlvX3Bn dGFibGVfb3BzICpvcHMsIHVuc2lnbmVkIGxvbmcgaW92YSwKIAlpZiAoIShpb21tdV9wcm90ICYg KElPTU1VX1JFQUQgfCBJT01NVV9XUklURSkpKQogCQlyZXR1cm4gMDsKIAotCWlmIChXQVJOX09O KGlvdmEgPj0gKDFVTEwgPDwgZGF0YS0+aW9wLmNmZy5pYXMpIHx8Ci0JCSAgICBwYWRkciA+PSAo MVVMTCA8PCBkYXRhLT5pb3AuY2ZnLm9hcykpKQorCWlmIChXQVJOX09OKHBhZGRyID49ICgxVUxM IDw8IGRhdGEtPmlvcC5jZmcub2FzKSkpCiAJCXJldHVybiAtRVJBTkdFOwogCiAJcHJvdCA9IGFy bV9scGFlX3Byb3RfdG9fcHRlKGRhdGEsIGlvbW11X3Byb3QpOwotLSAKMi43LjQKCl9fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCkZyZWVkcmVubyBtYWlsaW5n IGxpc3QKRnJlZWRyZW5vQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVk ZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2ZyZWVkcmVubw== From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.0 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BEF8CC10F03 for ; Fri, 1 Mar 2019 19:39:03 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 744252087E for ; Fri, 1 Mar 2019 19:39:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="AKQEoHh4"; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="PaNzoZEn"; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="COkqdvRm" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 744252087E Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=nGFDjV4W2Ys6lxE48Mhmd3AY2A1jW9CQIkw510Qm0KQ=; b=AKQEoHh4pZlgl7gx46WLAX6Bxy 603XfD+Q4y2pZnkRd0V/rLbCUT7X2Z/m1MKd5tOtfnaS24jpKwpa+0VQKEkLGEqCEuwPEz7b8eKB4 9IXAGWQd/OFMO7XSnt1VePEzqhY6dxRl23AejXbZnw+Jgl9LlkX2q/nmbIm93mzu6+Es+Ht/Q0d6y UzdrHXtuTujLm5CqR5mXsRQU2V4z7bZCcxB2qkX95pVvRb8S5l4mjHot0sOXyj6jaYgbeGT1xRPQ5 FWN8oMJe3V7gj0Fqkdt+bMqe7+UG+S8QzaazB35TSa3iVKLRFnPNFONJ/b3Q9MrDsNGd3bgF9ubJd lYc6MSXA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gznzm-0007yR-Oe; Fri, 01 Mar 2019 19:38:58 +0000 Received: from smtp.codeaurora.org ([198.145.29.96]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gznzc-0007ny-JI for linux-arm-kernel@lists.infradead.org; Fri, 01 Mar 2019 19:38:50 +0000 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 46B33611DC; Fri, 1 Mar 2019 19:38:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1551469128; bh=V6MfMAXITZU/8gyMiBYwzyA04UAGqKDKUEwDoOD04uY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PaNzoZEnevXuWBXXQfIyKksOHRpFcmaLSwB9pHYjSYFsXtrGLv7Inxu6NZhHZw5W3 PfBBITMqU0+UTyGvoBBtaNYnPILsYhW1hcphISHikY7w92734LWL1uNSKaBU0xEYHa m+ru0KIonFUW0krXyP7CW3wxxumKTYVst6ByLz50= Received: from jcrouse1-lnx.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jcrouse@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 229AF61155; Fri, 1 Mar 2019 19:38:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1551469126; bh=V6MfMAXITZU/8gyMiBYwzyA04UAGqKDKUEwDoOD04uY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=COkqdvRmuN78G8ucOvn3AvcKgXxeRoJOQzzEuo2plbyCWeADH3Tlzp0YdUyD7ggbp 8R6MmYMgyE14D5SnqISAwVYVssoptnnCe9k2kSgmOas2lXDo57QCwOucFJisd+ci3p XaXfoVwgrCjoixuJeq3hiCH21KPisxXl/QOPmiX0= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 229AF61155 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=jcrouse@codeaurora.org From: Jordan Crouse To: freedreno@lists.freedesktop.org Subject: [RFC PATCH v1 02/15] iommu/arm-smmu: Add split pagetable support for arm-smmu-v2 Date: Fri, 1 Mar 2019 12:38:24 -0700 Message-Id: <1551469117-3404-3-git-send-email-jcrouse@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1551469117-3404-1-git-send-email-jcrouse@codeaurora.org> References: <1551469117-3404-1-git-send-email-jcrouse@codeaurora.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190301_113848_675707_8F4A7F09 X-CRM114-Status: GOOD ( 20.78 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jean-philippe.brucker@arm.com, linux-arm-msm@vger.kernel.org, Joerg Roedel , Will Deacon , linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org, dianders@chromimum.org, hoegsberg@google.com, Robin Murphy , linux-arm-kernel@lists.infradead.org, baolu.lu@linux.intel.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add support for a split pagetable (TTBR0/TTBR1) scheme for arm-smmu-v2. If split pagetables are enabled, create a pagetable for TTBR1 and set up the sign extension bit so that all IOVAs with that bit set are mapped and translated from the TTBR1 pagetable. Signed-off-by: Jordan Crouse --- drivers/iommu/arm-smmu-regs.h | 18 +++++ drivers/iommu/arm-smmu.c | 149 +++++++++++++++++++++++++++++++++++++---- drivers/iommu/io-pgtable-arm.c | 3 +- 3 files changed, 154 insertions(+), 16 deletions(-) diff --git a/drivers/iommu/arm-smmu-regs.h b/drivers/iommu/arm-smmu-regs.h index a1226e4..56f9709 100644 --- a/drivers/iommu/arm-smmu-regs.h +++ b/drivers/iommu/arm-smmu-regs.h @@ -193,7 +193,25 @@ enum arm_smmu_s2cr_privcfg { #define RESUME_RETRY (0 << 0) #define RESUME_TERMINATE (1 << 0) +#define TTBCR_EPD1 (1 << 23) +#define TTBCR_T1SZ_SHIFT 16 +#define TTBCR_IRGN1_SHIFT 24 +#define TTBCR_ORGN1_SHIFT 26 +#define TTBCR_RGN_WBWA 1 +#define TTBCR_SH1_SHIFT 28 +#define TTBCR_SH_IS 3 + +#define TTBCR_TG1_16K (1 << 30) +#define TTBCR_TG1_4K (2 << 30) +#define TTBCR_TG1_64K (3 << 30) + #define TTBCR2_SEP_SHIFT 15 +#define TTBCR2_SEP_31 (0x0 << TTBCR2_SEP_SHIFT) +#define TTBCR2_SEP_35 (0x1 << TTBCR2_SEP_SHIFT) +#define TTBCR2_SEP_39 (0x2 << TTBCR2_SEP_SHIFT) +#define TTBCR2_SEP_41 (0x3 << TTBCR2_SEP_SHIFT) +#define TTBCR2_SEP_43 (0x4 << TTBCR2_SEP_SHIFT) +#define TTBCR2_SEP_47 (0x5 << TTBCR2_SEP_SHIFT) #define TTBCR2_SEP_UPSTREAM (0x7 << TTBCR2_SEP_SHIFT) #define TTBCR2_AS (1 << 4) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index af18a7e..05eb126 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -151,6 +151,7 @@ struct arm_smmu_cb { u32 tcr[2]; u32 mair[2]; struct arm_smmu_cfg *cfg; + u64 split_table_mask; }; struct arm_smmu_master_cfg { @@ -208,6 +209,7 @@ struct arm_smmu_device { unsigned long va_size; unsigned long ipa_size; unsigned long pa_size; + unsigned long ubs_size; unsigned long pgsize_bitmap; u32 num_global_irqs; @@ -252,13 +254,14 @@ enum arm_smmu_domain_stage { struct arm_smmu_domain { struct arm_smmu_device *smmu; - struct io_pgtable_ops *pgtbl_ops; + struct io_pgtable_ops *pgtbl_ops[2]; const struct iommu_gather_ops *tlb_ops; struct arm_smmu_cfg cfg; enum arm_smmu_domain_stage stage; bool non_strict; struct mutex init_mutex; /* Protects smmu pointer */ spinlock_t cb_lock; /* Serialises ATS1* ops and TLB syncs */ + u32 attributes; struct iommu_domain domain; }; @@ -618,6 +621,69 @@ static irqreturn_t arm_smmu_global_fault(int irq, void *dev) return IRQ_HANDLED; } +static void arm_smmu_init_ttbr1(struct arm_smmu_domain *smmu_domain, + struct io_pgtable_cfg *pgtbl_cfg) +{ + struct arm_smmu_device *smmu = smmu_domain->smmu; + struct arm_smmu_cfg *cfg = &smmu_domain->cfg; + struct arm_smmu_cb *cb = &smmu_domain->smmu->cbs[cfg->cbndx]; + int pgsize = 1 << __ffs(pgtbl_cfg->pgsize_bitmap); + + /* Enable speculative walks through the TTBR1 */ + cb->tcr[0] &= ~TTBCR_EPD1; + + cb->tcr[0] |= TTBCR_SH_IS << TTBCR_SH1_SHIFT; + cb->tcr[0] |= TTBCR_RGN_WBWA << TTBCR_IRGN1_SHIFT; + cb->tcr[0] |= TTBCR_RGN_WBWA << TTBCR_ORGN1_SHIFT; + + switch (pgsize) { + case SZ_4K: + cb->tcr[0] |= TTBCR_TG1_4K; + break; + case SZ_16K: + cb->tcr[0] |= TTBCR_TG1_16K; + break; + case SZ_64K: + cb->tcr[0] |= TTBCR_TG1_64K; + break; + } + + cb->tcr[0] |= (64ULL - smmu->va_size) << TTBCR_T1SZ_SHIFT; + + /* Clear the existing SEP configuration */ + cb->tcr[1] &= ~TTBCR2_SEP_UPSTREAM; + + /* Set up the sign extend bit */ + switch (smmu->va_size) { + case 32: + cb->tcr[1] |= TTBCR2_SEP_31; + cb->split_table_mask = (1ULL << 31); + break; + case 36: + cb->tcr[1] |= TTBCR2_SEP_35; + cb->split_table_mask = (1ULL << 35); + break; + case 40: + cb->tcr[1] |= TTBCR2_SEP_39; + cb->split_table_mask = (1ULL << 39); + break; + case 42: + cb->tcr[1] |= TTBCR2_SEP_41; + cb->split_table_mask = (1ULL << 41); + break; + case 44: + cb->tcr[1] |= TTBCR2_SEP_43; + cb->split_table_mask = (1ULL << 43); + break; + case 48: + cb->tcr[1] |= TTBCR2_SEP_UPSTREAM; + cb->split_table_mask = (1ULL << 48); + } + + cb->ttbr[1] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0]; + cb->ttbr[1] |= (u64)cfg->asid << TTBRn_ASID_SHIFT; +} + static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, struct io_pgtable_cfg *pgtbl_cfg) { @@ -650,8 +716,12 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, } else { cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0]; cb->ttbr[0] |= (u64)cfg->asid << TTBRn_ASID_SHIFT; - cb->ttbr[1] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1]; - cb->ttbr[1] |= (u64)cfg->asid << TTBRn_ASID_SHIFT; + + /* + * Set TTBR1 to empty by default - it will get + * programmed later if it is enabled + */ + cb->ttbr[1] = (u64)cfg->asid << TTBRn_ASID_SHIFT; } } else { cb->ttbr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vttbr; @@ -760,11 +830,13 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, { int irq, start, ret = 0; unsigned long ias, oas; - struct io_pgtable_ops *pgtbl_ops; + struct io_pgtable_ops *pgtbl_ops[2]; struct io_pgtable_cfg pgtbl_cfg; enum io_pgtable_fmt fmt; struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct arm_smmu_cfg *cfg = &smmu_domain->cfg; + bool split_tables = + (smmu_domain->attributes & (1 << DOMAIN_ATTR_SPLIT_TABLES)); mutex_lock(&smmu_domain->init_mutex); if (smmu_domain->smmu) @@ -794,8 +866,11 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, * * Note that you can't actually request stage-2 mappings. */ - if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1)) + if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1)) { smmu_domain->stage = ARM_SMMU_DOMAIN_S2; + /* FIXME: fail instead? */ + split_tables = false; + } if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S2)) smmu_domain->stage = ARM_SMMU_DOMAIN_S1; @@ -812,8 +887,11 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, if (IS_ENABLED(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) && !IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_ARM_LPAE) && (smmu->features & ARM_SMMU_FEAT_FMT_AARCH32_S) && - (smmu_domain->stage == ARM_SMMU_DOMAIN_S1)) + (smmu_domain->stage == ARM_SMMU_DOMAIN_S1)) { + /* FIXME: fail instead? */ + split_tables = false; cfg->fmt = ARM_SMMU_CTX_FMT_AARCH32_S; + } if ((IS_ENABLED(CONFIG_64BIT) || cfg->fmt == ARM_SMMU_CTX_FMT_NONE) && (smmu->features & (ARM_SMMU_FEAT_FMT_AARCH64_64K | ARM_SMMU_FEAT_FMT_AARCH64_16K | @@ -903,8 +981,8 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT; smmu_domain->smmu = smmu; - pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain); - if (!pgtbl_ops) { + pgtbl_ops[0] = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain); + if (!pgtbl_ops[0]) { ret = -ENOMEM; goto out_clear_smmu; } @@ -916,6 +994,22 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, /* Initialise the context bank with our page table cfg */ arm_smmu_init_context_bank(smmu_domain, &pgtbl_cfg); + + pgtbl_ops[1] = NULL; + + if (split_tables) { + /* FIXME: I think it is safe to reuse pgtbl_cfg here */ + pgtbl_ops[1] = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, + smmu_domain); + if (!pgtbl_ops[1]) { + free_io_pgtable_ops(pgtbl_ops[0]); + ret = -ENOMEM; + goto out_clear_smmu; + } + + arm_smmu_init_ttbr1(smmu_domain, &pgtbl_cfg); + } + arm_smmu_write_context_bank(smmu, cfg->cbndx); /* @@ -934,7 +1028,9 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, mutex_unlock(&smmu_domain->init_mutex); /* Publish page table ops for map/unmap */ - smmu_domain->pgtbl_ops = pgtbl_ops; + smmu_domain->pgtbl_ops[0] = pgtbl_ops[0]; + smmu_domain->pgtbl_ops[1] = pgtbl_ops[1]; + return 0; out_clear_smmu: @@ -970,7 +1066,9 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) devm_free_irq(smmu->dev, irq, domain); } - free_io_pgtable_ops(smmu_domain->pgtbl_ops); + free_io_pgtable_ops(smmu_domain->pgtbl_ops[0]); + free_io_pgtable_ops(smmu_domain->pgtbl_ops[1]); + __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); arm_smmu_rpm_put(smmu); @@ -1285,10 +1383,23 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) return ret; } +static struct io_pgtable_ops * +arm_smmu_get_pgtbl_ops(struct iommu_domain *domain, unsigned long iova) +{ + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); + struct arm_smmu_cfg *cfg = &smmu_domain->cfg; + struct arm_smmu_cb *cb = &smmu_domain->smmu->cbs[cfg->cbndx]; + + if (iova & cb->split_table_mask) + return smmu_domain->pgtbl_ops[1]; + + return smmu_domain->pgtbl_ops[0]; +} + static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t size, int prot) { - struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops; + struct io_pgtable_ops *ops = arm_smmu_get_pgtbl_ops(domain, iova); struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu; int ret; @@ -1305,7 +1416,7 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) { - struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops; + struct io_pgtable_ops *ops = arm_smmu_get_pgtbl_ops(domain, iova); struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu; size_t ret; @@ -1349,7 +1460,7 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain, struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct arm_smmu_device *smmu = smmu_domain->smmu; struct arm_smmu_cfg *cfg = &smmu_domain->cfg; - struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops; + struct io_pgtable_ops *ops = arm_smmu_get_pgtbl_ops(domain, iova); struct device *dev = smmu->dev; void __iomem *cb_base; u32 tmp; @@ -1397,7 +1508,7 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) { struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); - struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops; + struct io_pgtable_ops *ops = arm_smmu_get_pgtbl_ops(domain, iova); if (domain->type == IOMMU_DOMAIN_IDENTITY) return iova; @@ -1584,6 +1695,11 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, case DOMAIN_ATTR_NESTING: *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED); return 0; + case DOMAIN_ATTR_SPLIT_TABLES: + *((int *)data) = + !!(smmu_domain->attributes & + (1 << DOMAIN_ATTR_SPLIT_TABLES)); + return 0; default: return -ENODEV; } @@ -1624,6 +1740,11 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain, else smmu_domain->stage = ARM_SMMU_DOMAIN_S1; break; + case DOMAIN_ATTR_SPLIT_TABLES: + if (*((int *)data)) + smmu_domain->attributes |= + (1 << DOMAIN_ATTR_SPLIT_TABLES); + break; default: ret = -ENODEV; } diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 237cacd..dc9fb2e 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -475,8 +475,7 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova, if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE))) return 0; - if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias) || - paddr >= (1ULL << data->iop.cfg.oas))) + if (WARN_ON(paddr >= (1ULL << data->iop.cfg.oas))) return -ERANGE; prot = arm_lpae_prot_to_pte(data, iommu_prot); -- 2.7.4 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A0D1CC43381 for ; Fri, 1 Mar 2019 19:38:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 57B9020838 for ; Fri, 1 Mar 2019 19:38:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="iWv1Safy"; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="COkqdvRm" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727109AbfCATi4 (ORCPT ); Fri, 1 Mar 2019 14:38:56 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:38598 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725962AbfCATiu (ORCPT ); Fri, 1 Mar 2019 14:38:50 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 68C5861344; Fri, 1 Mar 2019 19:38:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1551469129; bh=V6MfMAXITZU/8gyMiBYwzyA04UAGqKDKUEwDoOD04uY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iWv1Safy7w4zbWh+qAO8ScqpGVl2GNTZCD6bz5hyKLElAVBhEOwZ8wOxs5x7I9fhu opH75HGBHuYjcUV66mMaPFI6lhBJD1m092xgTqdQHkVD3EN+kFdrWFzj67XA47Jztw ufoKOjc/Ziyap955lym1kBzL6P7bkDo15nNkxbHk= Received: from jcrouse1-lnx.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jcrouse@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 229AF61155; Fri, 1 Mar 2019 19:38:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1551469126; bh=V6MfMAXITZU/8gyMiBYwzyA04UAGqKDKUEwDoOD04uY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=COkqdvRmuN78G8ucOvn3AvcKgXxeRoJOQzzEuo2plbyCWeADH3Tlzp0YdUyD7ggbp 8R6MmYMgyE14D5SnqISAwVYVssoptnnCe9k2kSgmOas2lXDo57QCwOucFJisd+ci3p XaXfoVwgrCjoixuJeq3hiCH21KPisxXl/QOPmiX0= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 229AF61155 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=jcrouse@codeaurora.org From: Jordan Crouse To: freedreno@lists.freedesktop.org Cc: jean-philippe.brucker@arm.com, linux-arm-msm@vger.kernel.org, dianders@chromimum.org, hoegsberg@google.com, baolu.lu@linux.intel.com, linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org, Robin Murphy , Will Deacon , Joerg Roedel , linux-arm-kernel@lists.infradead.org Subject: [RFC PATCH v1 02/15] iommu/arm-smmu: Add split pagetable support for arm-smmu-v2 Date: Fri, 1 Mar 2019 12:38:24 -0700 Message-Id: <1551469117-3404-3-git-send-email-jcrouse@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1551469117-3404-1-git-send-email-jcrouse@codeaurora.org> References: <1551469117-3404-1-git-send-email-jcrouse@codeaurora.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add support for a split pagetable (TTBR0/TTBR1) scheme for arm-smmu-v2. If split pagetables are enabled, create a pagetable for TTBR1 and set up the sign extension bit so that all IOVAs with that bit set are mapped and translated from the TTBR1 pagetable. Signed-off-by: Jordan Crouse --- drivers/iommu/arm-smmu-regs.h | 18 +++++ drivers/iommu/arm-smmu.c | 149 +++++++++++++++++++++++++++++++++++++---- drivers/iommu/io-pgtable-arm.c | 3 +- 3 files changed, 154 insertions(+), 16 deletions(-) diff --git a/drivers/iommu/arm-smmu-regs.h b/drivers/iommu/arm-smmu-regs.h index a1226e4..56f9709 100644 --- a/drivers/iommu/arm-smmu-regs.h +++ b/drivers/iommu/arm-smmu-regs.h @@ -193,7 +193,25 @@ enum arm_smmu_s2cr_privcfg { #define RESUME_RETRY (0 << 0) #define RESUME_TERMINATE (1 << 0) +#define TTBCR_EPD1 (1 << 23) +#define TTBCR_T1SZ_SHIFT 16 +#define TTBCR_IRGN1_SHIFT 24 +#define TTBCR_ORGN1_SHIFT 26 +#define TTBCR_RGN_WBWA 1 +#define TTBCR_SH1_SHIFT 28 +#define TTBCR_SH_IS 3 + +#define TTBCR_TG1_16K (1 << 30) +#define TTBCR_TG1_4K (2 << 30) +#define TTBCR_TG1_64K (3 << 30) + #define TTBCR2_SEP_SHIFT 15 +#define TTBCR2_SEP_31 (0x0 << TTBCR2_SEP_SHIFT) +#define TTBCR2_SEP_35 (0x1 << TTBCR2_SEP_SHIFT) +#define TTBCR2_SEP_39 (0x2 << TTBCR2_SEP_SHIFT) +#define TTBCR2_SEP_41 (0x3 << TTBCR2_SEP_SHIFT) +#define TTBCR2_SEP_43 (0x4 << TTBCR2_SEP_SHIFT) +#define TTBCR2_SEP_47 (0x5 << TTBCR2_SEP_SHIFT) #define TTBCR2_SEP_UPSTREAM (0x7 << TTBCR2_SEP_SHIFT) #define TTBCR2_AS (1 << 4) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index af18a7e..05eb126 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -151,6 +151,7 @@ struct arm_smmu_cb { u32 tcr[2]; u32 mair[2]; struct arm_smmu_cfg *cfg; + u64 split_table_mask; }; struct arm_smmu_master_cfg { @@ -208,6 +209,7 @@ struct arm_smmu_device { unsigned long va_size; unsigned long ipa_size; unsigned long pa_size; + unsigned long ubs_size; unsigned long pgsize_bitmap; u32 num_global_irqs; @@ -252,13 +254,14 @@ enum arm_smmu_domain_stage { struct arm_smmu_domain { struct arm_smmu_device *smmu; - struct io_pgtable_ops *pgtbl_ops; + struct io_pgtable_ops *pgtbl_ops[2]; const struct iommu_gather_ops *tlb_ops; struct arm_smmu_cfg cfg; enum arm_smmu_domain_stage stage; bool non_strict; struct mutex init_mutex; /* Protects smmu pointer */ spinlock_t cb_lock; /* Serialises ATS1* ops and TLB syncs */ + u32 attributes; struct iommu_domain domain; }; @@ -618,6 +621,69 @@ static irqreturn_t arm_smmu_global_fault(int irq, void *dev) return IRQ_HANDLED; } +static void arm_smmu_init_ttbr1(struct arm_smmu_domain *smmu_domain, + struct io_pgtable_cfg *pgtbl_cfg) +{ + struct arm_smmu_device *smmu = smmu_domain->smmu; + struct arm_smmu_cfg *cfg = &smmu_domain->cfg; + struct arm_smmu_cb *cb = &smmu_domain->smmu->cbs[cfg->cbndx]; + int pgsize = 1 << __ffs(pgtbl_cfg->pgsize_bitmap); + + /* Enable speculative walks through the TTBR1 */ + cb->tcr[0] &= ~TTBCR_EPD1; + + cb->tcr[0] |= TTBCR_SH_IS << TTBCR_SH1_SHIFT; + cb->tcr[0] |= TTBCR_RGN_WBWA << TTBCR_IRGN1_SHIFT; + cb->tcr[0] |= TTBCR_RGN_WBWA << TTBCR_ORGN1_SHIFT; + + switch (pgsize) { + case SZ_4K: + cb->tcr[0] |= TTBCR_TG1_4K; + break; + case SZ_16K: + cb->tcr[0] |= TTBCR_TG1_16K; + break; + case SZ_64K: + cb->tcr[0] |= TTBCR_TG1_64K; + break; + } + + cb->tcr[0] |= (64ULL - smmu->va_size) << TTBCR_T1SZ_SHIFT; + + /* Clear the existing SEP configuration */ + cb->tcr[1] &= ~TTBCR2_SEP_UPSTREAM; + + /* Set up the sign extend bit */ + switch (smmu->va_size) { + case 32: + cb->tcr[1] |= TTBCR2_SEP_31; + cb->split_table_mask = (1ULL << 31); + break; + case 36: + cb->tcr[1] |= TTBCR2_SEP_35; + cb->split_table_mask = (1ULL << 35); + break; + case 40: + cb->tcr[1] |= TTBCR2_SEP_39; + cb->split_table_mask = (1ULL << 39); + break; + case 42: + cb->tcr[1] |= TTBCR2_SEP_41; + cb->split_table_mask = (1ULL << 41); + break; + case 44: + cb->tcr[1] |= TTBCR2_SEP_43; + cb->split_table_mask = (1ULL << 43); + break; + case 48: + cb->tcr[1] |= TTBCR2_SEP_UPSTREAM; + cb->split_table_mask = (1ULL << 48); + } + + cb->ttbr[1] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0]; + cb->ttbr[1] |= (u64)cfg->asid << TTBRn_ASID_SHIFT; +} + static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, struct io_pgtable_cfg *pgtbl_cfg) { @@ -650,8 +716,12 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, } else { cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0]; cb->ttbr[0] |= (u64)cfg->asid << TTBRn_ASID_SHIFT; - cb->ttbr[1] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1]; - cb->ttbr[1] |= (u64)cfg->asid << TTBRn_ASID_SHIFT; + + /* + * Set TTBR1 to empty by default - it will get + * programmed later if it is enabled + */ + cb->ttbr[1] = (u64)cfg->asid << TTBRn_ASID_SHIFT; } } else { cb->ttbr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vttbr; @@ -760,11 +830,13 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, { int irq, start, ret = 0; unsigned long ias, oas; - struct io_pgtable_ops *pgtbl_ops; + struct io_pgtable_ops *pgtbl_ops[2]; struct io_pgtable_cfg pgtbl_cfg; enum io_pgtable_fmt fmt; struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct arm_smmu_cfg *cfg = &smmu_domain->cfg; + bool split_tables = + (smmu_domain->attributes & (1 << DOMAIN_ATTR_SPLIT_TABLES)); mutex_lock(&smmu_domain->init_mutex); if (smmu_domain->smmu) @@ -794,8 +866,11 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, * * Note that you can't actually request stage-2 mappings. */ - if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1)) + if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1)) { smmu_domain->stage = ARM_SMMU_DOMAIN_S2; + /* FIXME: fail instead? */ + split_tables = false; + } if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S2)) smmu_domain->stage = ARM_SMMU_DOMAIN_S1; @@ -812,8 +887,11 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, if (IS_ENABLED(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) && !IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_ARM_LPAE) && (smmu->features & ARM_SMMU_FEAT_FMT_AARCH32_S) && - (smmu_domain->stage == ARM_SMMU_DOMAIN_S1)) + (smmu_domain->stage == ARM_SMMU_DOMAIN_S1)) { + /* FIXME: fail instead? */ + split_tables = false; cfg->fmt = ARM_SMMU_CTX_FMT_AARCH32_S; + } if ((IS_ENABLED(CONFIG_64BIT) || cfg->fmt == ARM_SMMU_CTX_FMT_NONE) && (smmu->features & (ARM_SMMU_FEAT_FMT_AARCH64_64K | ARM_SMMU_FEAT_FMT_AARCH64_16K | @@ -903,8 +981,8 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT; smmu_domain->smmu = smmu; - pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain); - if (!pgtbl_ops) { + pgtbl_ops[0] = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain); + if (!pgtbl_ops[0]) { ret = -ENOMEM; goto out_clear_smmu; } @@ -916,6 +994,22 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, /* Initialise the context bank with our page table cfg */ arm_smmu_init_context_bank(smmu_domain, &pgtbl_cfg); + + pgtbl_ops[1] = NULL; + + if (split_tables) { + /* FIXME: I think it is safe to reuse pgtbl_cfg here */ + pgtbl_ops[1] = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, + smmu_domain); + if (!pgtbl_ops[1]) { + free_io_pgtable_ops(pgtbl_ops[0]); + ret = -ENOMEM; + goto out_clear_smmu; + } + + arm_smmu_init_ttbr1(smmu_domain, &pgtbl_cfg); + } + arm_smmu_write_context_bank(smmu, cfg->cbndx); /* @@ -934,7 +1028,9 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, mutex_unlock(&smmu_domain->init_mutex); /* Publish page table ops for map/unmap */ - smmu_domain->pgtbl_ops = pgtbl_ops; + smmu_domain->pgtbl_ops[0] = pgtbl_ops[0]; + smmu_domain->pgtbl_ops[1] = pgtbl_ops[1]; + return 0; out_clear_smmu: @@ -970,7 +1066,9 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) devm_free_irq(smmu->dev, irq, domain); } - free_io_pgtable_ops(smmu_domain->pgtbl_ops); + free_io_pgtable_ops(smmu_domain->pgtbl_ops[0]); + free_io_pgtable_ops(smmu_domain->pgtbl_ops[1]); + __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); arm_smmu_rpm_put(smmu); @@ -1285,10 +1383,23 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) return ret; } +static struct io_pgtable_ops * +arm_smmu_get_pgtbl_ops(struct iommu_domain *domain, unsigned long iova) +{ + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); + struct arm_smmu_cfg *cfg = &smmu_domain->cfg; + struct arm_smmu_cb *cb = &smmu_domain->smmu->cbs[cfg->cbndx]; + + if (iova & cb->split_table_mask) + return smmu_domain->pgtbl_ops[1]; + + return smmu_domain->pgtbl_ops[0]; +} + static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t size, int prot) { - struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops; + struct io_pgtable_ops *ops = arm_smmu_get_pgtbl_ops(domain, iova); struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu; int ret; @@ -1305,7 +1416,7 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) { - struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops; + struct io_pgtable_ops *ops = arm_smmu_get_pgtbl_ops(domain, iova); struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu; size_t ret; @@ -1349,7 +1460,7 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain, struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct arm_smmu_device *smmu = smmu_domain->smmu; struct arm_smmu_cfg *cfg = &smmu_domain->cfg; - struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops; + struct io_pgtable_ops *ops = arm_smmu_get_pgtbl_ops(domain, iova); struct device *dev = smmu->dev; void __iomem *cb_base; u32 tmp; @@ -1397,7 +1508,7 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) { struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); - struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops; + struct io_pgtable_ops *ops = arm_smmu_get_pgtbl_ops(domain, iova); if (domain->type == IOMMU_DOMAIN_IDENTITY) return iova; @@ -1584,6 +1695,11 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, case DOMAIN_ATTR_NESTING: *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED); return 0; + case DOMAIN_ATTR_SPLIT_TABLES: + *((int *)data) = + !!(smmu_domain->attributes & + (1 << DOMAIN_ATTR_SPLIT_TABLES)); + return 0; default: return -ENODEV; } @@ -1624,6 +1740,11 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain, else smmu_domain->stage = ARM_SMMU_DOMAIN_S1; break; + case DOMAIN_ATTR_SPLIT_TABLES: + if (*((int *)data)) + smmu_domain->attributes |= + (1 << DOMAIN_ATTR_SPLIT_TABLES); + break; default: ret = -ENODEV; } diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 237cacd..dc9fb2e 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -475,8 +475,7 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova, if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE))) return 0; - if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias) || - paddr >= (1ULL << data->iop.cfg.oas))) + if (WARN_ON(paddr >= (1ULL << data->iop.cfg.oas))) return -ERANGE; prot = arm_lpae_prot_to_pte(data, iommu_prot); -- 2.7.4