From patchwork Tue Jan 26 13:42:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yanan Wang X-Patchwork-Id: 12046627 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,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 97F40C433E0 for ; Tue, 26 Jan 2021 13:45:56 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 279EA2223D for ; Tue, 26 Jan 2021 13:45:56 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 279EA2223D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+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=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version: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=u1pxHozGXLzp5hBxaZNx8vg9Ioga/KQvMjPF/yX7Y5Y=; b=Z2tU6BN5yvm4Y74XvID1Q6q9n fWSmBZthGFSxL7zow5IJTeml8rBWTCxd+Macce03tYzfzPy+sBGkPjvFgaqli4QBxgu15IubIPHIL OP0C0cahiiv8fXs29zhh0axcerb45M4KcD4iVsyEKAYFLw5uVBGQxifUxY/2fWmsX48I7syDkafvj iB2x2CirtpX4AuOMqVX48iNewSoWOWa044RHOjIaUSAxnVPvO77AH6eeaKvjCIJcIr4dPzpr1ITn9 k+vwDh8ZM0ghqZCQdMGDi2t3yqTQKumKg1ISQ3wMivfa2eJ6oTpsQoJxuIPHQHm47FV572YwM5Knf 75q9EHuAg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l4Ocr-00023P-Ed; Tue, 26 Jan 2021 13:43:21 +0000 Received: from szxga07-in.huawei.com ([45.249.212.35]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l4Obq-0001hn-VW for linux-arm-kernel@lists.infradead.org; Tue, 26 Jan 2021 13:42:22 +0000 Received: from DGGEMS406-HUB.china.huawei.com (unknown [172.30.72.58]) by szxga07-in.huawei.com (SkyGuard) with ESMTP id 4DQ7DK2k0Kz7bPZ; Tue, 26 Jan 2021 21:41:05 +0800 (CST) Received: from DESKTOP-TMVL5KK.china.huawei.com (10.174.187.128) by DGGEMS406-HUB.china.huawei.com (10.3.19.206) with Microsoft SMTP Server id 14.3.498.0; Tue, 26 Jan 2021 21:42:09 +0800 From: Yanan Wang To: , , , , Marc Zyngier , Will Deacon , Catalin Marinas Subject: [RFC PATCH v1 4/5] KVM: arm64: Add handling of coalescing tables into a block mapping Date: Tue, 26 Jan 2021 21:42:01 +0800 Message-ID: <20210126134202.381996-5-wangyanan55@huawei.com> X-Mailer: git-send-email 2.8.4.windows.1 In-Reply-To: <20210126134202.381996-1-wangyanan55@huawei.com> References: <20210126134202.381996-1-wangyanan55@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.174.187.128] X-CFilter-Loop: Reflected X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210126_084220_119217_7382FE69 X-CRM114-Status: GOOD ( 16.13 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Suzuki K Poulose , Yanan Wang , yezengruan@huawei.com, James Morse , yuzenghui@huawei.com, wanghaibin.wang@huawei.com, zhukeqian1@huawei.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org If migration of a VM with hugepages is canceled midway, KVM will adjust the stage-2 table mappings back to block mappings. We currently use BBM to replace the table entry with a block entry. Take adjustment of 1G block mapping as an example, with BBM procedures, we have to invalidate the old table entry of level 1 first, flush TLB and unmap the old table mappings, right before installing the new block entry. So there will be a bit long period when the table entry of level 1 is invalid before installation of block entry, if other vCPUs access any guest page within the 1G range during this period and find the table entry invalid, they will all exit from guest with an translation fault. Actually, these translation faults are not necessary, because the block mapping will be built later. Besides, KVM will try to build 1G block mappings for these translation faults, and will perform cache maintenance operations, page table walk, etc. Approaches of TTRem level 1,2 ensure that there will be not a moment when the old table entry is invalid before installation of the new block entry, so no unnecessary translation faults will be caused. But level-2 method will possibly lead to a TLB conflict which is bothering, so we use nT both at level-1 and level-2 case to avoid handling TLB conflict aborts. Signed-off-by: Yanan Wang --- arch/arm64/kvm/hyp/pgtable.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index c8b959e3951b..ab1c94985ed0 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -49,6 +49,8 @@ KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \ KVM_PTE_LEAF_ATTR_HI_S2_XN) +#define KVM_PTE_LEAF_BLOCK_S2_NT BIT(16) + struct kvm_pgtable_walk_data { struct kvm_pgtable *pgt; struct kvm_pgtable_walker *walker; @@ -502,6 +504,39 @@ static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level, return 0; } +static int stage2_coalesce_tables_into_block(u64 addr, u32 level, + kvm_pte_t *ptep, + struct stage2_map_data *data) +{ + u32 ttrem_level = data->ttrem_level; + u64 granule = kvm_granule_size(level), phys = data->phys; + kvm_pte_t new = kvm_init_valid_leaf_pte(phys, data->attr, level); + + switch (ttrem_level) { + case TTREM_LEVEL0: + kvm_set_invalid_pte(ptep); + + /* + * Invalidate the whole stage-2, as we may have numerous leaf + * entries below us which would otherwise need invalidating + * individually. + */ + kvm_call_hyp(__kvm_tlb_flush_vmid, data->mmu); + smp_store_release(ptep, new); + data->phys += granule; + return 0; + case TTREM_LEVEL1: + case TTREM_LEVEL2: + WRITE_ONCE(*ptep, new | KVM_PTE_LEAF_BLOCK_S2_NT); + kvm_call_hyp(__kvm_tlb_flush_vmid, data->mmu); + WRITE_ONCE(*ptep, new & ~KVM_PTE_LEAF_BLOCK_S2_NT); + data->phys += granule; + return 0; + } + + return -EINVAL; +} + static int stage2_map_walk_table_pre(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, struct stage2_map_data *data)