From patchwork Fri May 10 15:19:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 163871 Delivered-To: patch@linaro.org Received: by 2002:a05:6e02:142:0:0:0:0 with SMTP id j2csp2519119ilr; Fri, 10 May 2019 08:26:57 -0700 (PDT) X-Google-Smtp-Source: APXvYqzdC/yBG0aizfCCmkHXlGxpDrlxVbEoMeWvWc9cP1VqhUZCoylXKu5dxaXHop2logQW/WpK X-Received: by 2002:a17:906:378c:: with SMTP id n12mr9303941ejc.246.1557502016817; Fri, 10 May 2019 08:26:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1557502016; cv=none; d=google.com; s=arc-20160816; b=Z72ppbQVRtA9aSLkn1k/LWCfGXJfuz+mtIlEhT7MJ/qusA/J0FOrzZKZhS9QrrfOIh FAvxfCq3U7R791LVvMS/ToJ0s491OfA5PiijIb3HL/PLVQjBDHKi1KxtMe9rMpuv568a WFtfk+fa/rUYRelUVpUunMLYYh5OEgLEsIcNTULqgRpuRtVwGbsP2DHr7K6sR6XuTPor xibvT1PoA32JUXBFgXBkcGwvXwS1CirK8mWNSDmaHSnZw5PaWJs5/Ka8oPdKR/3lFti3 IHyfYm6CaUoT9l5mrJp2WgStIF8uAjIYnYevWWuEZcMHYbvUr1EaW6iQf2m34xTABKaJ E1dg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=7ZAIu4sKS6YB4WebUUhTxA56tE0hF5se6ULN034aZNQ=; b=vi/hGWPA5IBMG7UE0lkM+UZbfthhXsaVuKjv1MdNwyGbGSXlLFUcRJpGaBimGYtZjt 5tAmOdXbSS+4lGIFPmC87QesHNxHfjrkUPMRWpCg+fzwnrmkwlxh7tc0cxtkWBzPiouf mCTi6b0VBDyd5rLUbY1YecOycu+YSZaoxZNol0ybHH8aWDS1lnUj5kO44aaxlayD5ELO 4RQ7nKKYcm84oiu2vQ1v8XusQ5HBOLH3e/mtLw5kpUS4ULxgssz9nWal6I75nhxdPYaA FLOj8jHUfwKr4BmsZVElwao6WqmydMAZpbKU2no2CoiZMt4QMV4Zgt5Mpzh1RYoVvWE3 UhCQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b="WzX5/Kg3"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id s30si4155976eda.229.2019.05.10.08.26.56 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 10 May 2019 08:26:56 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b="WzX5/Kg3"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1]:45072 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hP7QF-0005Yl-Lu for patch@linaro.org; Fri, 10 May 2019 11:26:55 -0400 Received: from eggs.gnu.org ([209.51.188.92]:55922) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hP7JO-0007Oi-MZ for qemu-devel@nongnu.org; Fri, 10 May 2019 11:19:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hP7JN-0008By-CD for qemu-devel@nongnu.org; Fri, 10 May 2019 11:19:50 -0400 Received: from mail-pf1-x42b.google.com ([2607:f8b0:4864:20::42b]:46643) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hP7JN-00088E-4S for qemu-devel@nongnu.org; Fri, 10 May 2019 11:19:49 -0400 Received: by mail-pf1-x42b.google.com with SMTP id y11so3385952pfm.13 for ; Fri, 10 May 2019 08:19:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=7ZAIu4sKS6YB4WebUUhTxA56tE0hF5se6ULN034aZNQ=; b=WzX5/Kg3wXGGAAVo4Q5/PLRYl3vm580BE/g9KL3k/ouTDQOpiKB6T9XBcmZeFCy/1X WcLldaII9Gyjk1PcYLTKMKKSKZTe8+1xo0gaxyobfTrF2fLDI7xalsVOLeJEP2ewcaYA n/CYwb2ltPliqWgFePK4/Cr5u4CHXaMe2B79eRMfkBIz5ZBsOdgmfKxCmQ5ofrB8QG9t n+C3LYTzZLwv9Ku96lJ13FT0VGp2IR+CYTudPQxrJ2YFw5pEP0IBzLgzzk/iwRzDY2+h LX581NsUX1zvQUyL5S1EXb0LD1kFBwEGFk+eyXZWH7M4pFPcYdaXurt4y+1Ti0iK2NG3 O0pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7ZAIu4sKS6YB4WebUUhTxA56tE0hF5se6ULN034aZNQ=; b=fHfQxcNYUdyNdu5we/GtcVYoMuQpa8BMO4xSj16TAWpUV1anqBq3kMwLDBo6cSjTbI UWxa4OU5fMiOqNmjjbSrK9mndiaECojWn2hzzolKLYSVQQCKrJd6371BN8tGI0rYAWOM 7hPWgBOMin6JVB1Zv5U/JYhky3js09OP9M9Tj3obulnmFBGUSTJj75CplSQuDlanlyJK 8xBDpWAjFNc4RDNIIpwt1G49pC5OO66PfjBiw5T3kGwq1c2MXPcfMoGWPi7+LRXh1Qua 0xen6+cSbZShSycUPG57KygE4QyzzAaKctOHuhFQzs6W1G9UfFu3ubYEChlGHHEMMMmq WtSQ== X-Gm-Message-State: APjAAAVd0jWLzi5Alx3kdccVj+oyz2fw2YXKD0iF/6QPzspORuUi93Wk XlhMzHsDWgvQvHyGh1phxc/Oic+YHnY= X-Received: by 2002:a62:2703:: with SMTP id n3mr14915651pfn.199.1557501587657; Fri, 10 May 2019 08:19:47 -0700 (PDT) Received: from localhost.localdomain (97-113-13-231.tukw.qwest.net. [97.113.13.231]) by smtp.gmail.com with ESMTPSA id 19sm5920517pgz.24.2019.05.10.08.19.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 10 May 2019 08:19:46 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Fri, 10 May 2019 08:19:18 -0700 Message-Id: <20190510151944.22981-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190510151944.22981-1-richard.henderson@linaro.org> References: <20190510151944.22981-1-richard.henderson@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::42b Subject: [Qemu-devel] [PULL 01/27] tcg: Add CPUClass::tlb_fill X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" This hook will replace the (user-only mode specific) handle_mmu_fault hook, and the (system mode specific) tlb_fill function. The handle_mmu_fault hook was written as if there was a valid way to recover from an mmu fault, and had 3 possible return states. In reality, the only valid action is to raise an exception, return to the main loop, and deliver the SIGSEGV to the guest. Note that all of the current implementations of handle_mmu_fault for guests which support linux-user do in fact only ever return 1, which is the signal to return to the main loop. Using the hook for system mode requires that all targets be converted, so for now the hook is (optionally) used only from user-only mode. Reviewed-by: Alistair Francis Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson --- include/qom/cpu.h | 9 +++++++++ accel/tcg/user-exec.c | 39 ++++++++++++++------------------------- 2 files changed, 23 insertions(+), 25 deletions(-) -- 2.17.1 diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 08abcbd3fe..c1f267b4e0 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -118,6 +118,12 @@ struct TranslationBlock; * will need to do more. If this hook is not implemented then the * default is to call @set_pc(tb->pc). * @handle_mmu_fault: Callback for handling an MMU fault. + * @tlb_fill: Callback for handling a softmmu tlb miss or user-only + * address fault. For system mode, if the access is valid, call + * tlb_set_page and return true; if the access is invalid, and + * probe is true, return false; otherwise raise an exception and + * do not return. For user-only mode, always raise an exception + * and do not return. * @get_phys_page_debug: Callback for obtaining a physical address. * @get_phys_page_attrs_debug: Callback for obtaining a physical address and the * associated memory transaction attributes to use for the access. @@ -191,6 +197,9 @@ typedef struct CPUClass { void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb); int (*handle_mmu_fault)(CPUState *cpu, vaddr address, int size, int rw, int mmu_index); + bool (*tlb_fill)(CPUState *cpu, vaddr address, int size, + MMUAccessType access_type, int mmu_idx, + bool probe, uintptr_t retaddr); hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr); hwaddr (*get_phys_page_attrs_debug)(CPUState *cpu, vaddr addr, MemTxAttrs *attrs); diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index 0789984fe6..199f88c826 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -65,6 +65,7 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info, CPUClass *cc; int ret; unsigned long address = (unsigned long)info->si_addr; + MMUAccessType access_type; /* We must handle PC addresses from two different sources: * a call return address and a signal frame address. @@ -147,35 +148,23 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info, are still valid segv ones */ address = h2g_nocheck(address); - cc = CPU_GET_CLASS(cpu); - /* see if it is an MMU fault */ - g_assert(cc->handle_mmu_fault); - ret = cc->handle_mmu_fault(cpu, address, 0, is_write, MMU_USER_IDX); - - if (ret == 0) { - /* The MMU fault was handled without causing real CPU fault. - * Retain helper_retaddr for a possible second fault. - */ - return 1; - } - - /* All other paths lead to cpu_exit; clear helper_retaddr - * for next execution. + /* + * There is no way the target can handle this other than raising + * an exception. Undo signal and retaddr state prior to longjmp. */ + sigprocmask(SIG_SETMASK, old_set, NULL); helper_retaddr = 0; - if (ret < 0) { - return 0; /* not an MMU fault */ + cc = CPU_GET_CLASS(cpu); + if (cc->tlb_fill) { + access_type = is_write ? MMU_DATA_STORE : MMU_DATA_LOAD; + cc->tlb_fill(cpu, address, 0, access_type, MMU_USER_IDX, false, pc); + g_assert_not_reached(); + } else { + ret = cc->handle_mmu_fault(cpu, address, 0, is_write, MMU_USER_IDX); + g_assert(ret > 0); + cpu_loop_exit_restore(cpu, pc); } - - /* Now we have a real cpu fault. */ - cpu_restore_state(cpu, pc, true); - - sigprocmask(SIG_SETMASK, old_set, NULL); - cpu_loop_exit(cpu); - - /* never comes here */ - return 1; } #if defined(__i386__)