From patchwork Sat May 2 11:36:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1281671 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49DqCP5txDz9sRf for ; Sat, 2 May 2020 23:07:13 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=Z83qApVU; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 49DqCP4MmzzDrKh for ; Sat, 2 May 2020 23:07:13 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::1042; helo=mail-pj1-x1042.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=Z83qApVU; dkim-atps=neutral Received: from mail-pj1-x1042.google.com (mail-pj1-x1042.google.com [IPv6:2607:f8b0:4864:20::1042]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 49DnDM0mtBzDqXX for ; Sat, 2 May 2020 21:37:55 +1000 (AEST) Received: by mail-pj1-x1042.google.com with SMTP id y6so1174744pjc.4 for ; Sat, 02 May 2020 04:37:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8CbCTGoKulhknpMM4/rxzAfwQwKGJTesi/bshjkXojI=; b=Z83qApVUBKCtbtkzywHgfxWapn9K75r0LnWcETRTkUQp8/SMhXukt6U16nji5bh2OR AdOrwpvkUlookCMIUJxLR6WAJRKIhOSQepmcZdRk4xSHSCKvXd6A5iTyxil6h1+YzwCJ bXFGghowCAZh56M/PS7/iQiZxhH0PJsnXveLY87rccPRL55MzRNIQFVZPVzmMRh2pf9t 1ZWRUJxzyVVdPX7KIUWulzZ7SCJpy0stHF28Vb7fSX+i7WM5HBGsZiTx9+2gCURphv04 9dkWbvfkwg56RL977hTSrMcJ+ZH8Oxc3vn/DuEk/Dcz9Z3eCPOzU32Tuchp4OI/hNwoi s16A== 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=8CbCTGoKulhknpMM4/rxzAfwQwKGJTesi/bshjkXojI=; b=lZGNqtJxGChXtqJqse6O+zhPE0MbRP5CPp2W45n2Er9nljGWCw9tNQ8sD0ctPNpTg0 ++uoT+lC3eIE88hYpy0yZy7Jvomp+YPP/hVjGitgxAmoYS+v3kCyrPJUnWPbksg1BLjc F2MmDJjBTm8pmMQQdtavBYXk2RfGJUlzxuqcYpG9owLde57BhrBoSUc6ETScDqj118JE 36Yf7+ywpg8yorvnmxLaZJImC48IarwhSZKteTxln8AHnBY37PwlgugUX06UvnT+dOs1 EzAFKZrf7rH8euMzIwCVGgEozwDFNHuLPG0t1pZ3gKlnVoeuP8jPxh/ixFrIDnaDlp3r yLNA== X-Gm-Message-State: AGi0PuY7Kgolqw9WMMDO3sARL9O4ysw8pc+35LXu3qB0I7dIvoH0J8tS Pr07rDgdYvliRE71PA3YXzhroAoS X-Google-Smtp-Source: APiQypJPfe90ACuZ0Kp3uPSdTl5M+4frhtDjL1cKVnuoRqn6sXQBRtgwucc8UdklFbHXfbOnCCFgvw== X-Received: by 2002:a17:902:50d:: with SMTP id 13mr8853339plf.170.1588419470865; Sat, 02 May 2020 04:37:50 -0700 (PDT) Received: from bobo.ozlabs.ibm.com ([203.220.177.17]) by smtp.gmail.com with ESMTPSA id e135sm4367513pfh.37.2020.05.02.04.37.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 02 May 2020 04:37:50 -0700 (PDT) From: Nicholas Piggin To: skiboot@lists.ozlabs.org Date: Sat, 2 May 2020 21:36:47 +1000 Message-Id: <20200502113649.176329-8-npiggin@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200502113649.176329-1-npiggin@gmail.com> References: <20200502113649.176329-1-npiggin@gmail.com> MIME-Version: 1.0 Subject: [Skiboot] [RFC PATCH 7/9] Runtime virtual memory for OPAL V4 X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This patch removes the real-mode switch from the V4 entry, and allows skiboot to run in virtual mode. When vm_map is used to access addresses outside the global mappings, MSR[DR] is disabled, although MSR[IR] remains on (is this wise? It's not a common configuration for Linux). Signed-off-by: Nicholas Piggin --- core/mem_region.c | 35 +++++++++++++++++++++++++---------- core/opal.c | 20 +++++++++++++++----- core/vm.c | 24 +++++++++++++++++++----- include/cpu.h | 1 + 4 files changed, 60 insertions(+), 20 deletions(-) diff --git a/core/mem_region.c b/core/mem_region.c index 69f24d630..c7a689255 100644 --- a/core/mem_region.c +++ b/core/mem_region.c @@ -168,16 +168,20 @@ static void mem_poison(struct free_hdr *f) unsigned long start = (unsigned long)(f + 1); unsigned long *t = tailer(f); size_t poison_size = (unsigned long)t - start; - void *mem; /* We only poison up to a limit, as otherwise boot is * kinda slow */ if (poison_size > POISON_MEM_REGION_LIMIT) poison_size = POISON_MEM_REGION_LIMIT; - mem = vm_map(start, poison_size, true); - memset(mem, POISON_MEM_REGION_WITH, poison_size); - vm_unmap(start, poison_size); + if (cpu_in_os()) { + memset((void *)start, POISON_MEM_REGION_WITH, poison_size); + } else { + void *mem; + mem = vm_map(start, poison_size, true); + memset(mem, POISON_MEM_REGION_WITH, poison_size); + vm_unmap(start, poison_size); + } } #endif @@ -211,9 +215,14 @@ static void init_allocatable_region(struct mem_region *region) f->hdr.prev_free = false; list_add(®ion->free_list, &f->list); - t = vm_map((unsigned long)tailer(f), sizeof(long), true); - *t = num_longs; - vm_unmap((unsigned long)tailer(f), sizeof(long)); + if (cpu_in_os()) { + t = tailer(f); + *t = num_longs; + } else { + t = vm_map((unsigned long)tailer(f), sizeof(long), true); + *t = num_longs; + vm_unmap((unsigned long)tailer(f), sizeof(long)); + } #if POISON_MEM_REGION == 1 mem_poison(f); @@ -277,9 +286,15 @@ static void make_free(struct mem_region *region, struct free_hdr *f, no_unmap: /* Fix up tailer. */ - t = vm_map((unsigned long)tailer(f), sizeof(long), true); - *t = f->hdr.num_longs; - vm_unmap((unsigned long)tailer(f), sizeof(long)); + if (cpu_in_os()) { + t = tailer(f); + *t = f->hdr.num_longs; + } else { + t = vm_map((unsigned long)tailer(f), sizeof(long), true); + *t = f->hdr.num_longs; + vm_unmap((unsigned long)tailer(f), sizeof(long)); + } + } /* Can we fit this many longs with this alignment in this free block? */ diff --git a/core/opal.c b/core/opal.c index 27ce7a375..7fb4fae86 100644 --- a/core/opal.c +++ b/core/opal.c @@ -398,6 +398,8 @@ static int64_t opal_v4_le_entry(uint64_t token, uint64_t r4, uint64_t r5, { struct cpu_thread *cpu; opal_call_fn *fn; + bool was_vm_setup; + uint64_t old_opal_call_msr; uint64_t msr; uint32_t pir; uint64_t r16; @@ -406,14 +408,20 @@ static int64_t opal_v4_le_entry(uint64_t token, uint64_t r4, uint64_t r5, msr = mfmsr(); assert(!(msr & MSR_EE)); - if (msr & (MSR_IR|MSR_DR)) - mtmsrd(msr & ~(MSR_IR|MSR_DR), 0); - pir = mfspr(SPR_PIR); r16 = (uint64_t)__this_cpu; __this_cpu = &cpu_stacks[pir].cpu; cpu = this_cpu(); + old_opal_call_msr = cpu->opal_call_msr; + cpu->opal_call_msr = msr; + + was_vm_setup = this_cpu()->vm_setup; + if (msr & (MSR_IR|MSR_DR)) + this_cpu()->vm_setup = true; + else + this_cpu()->vm_setup = false; + cpu->in_opal_call++; if (cpu->in_opal_call == 1) { cpu->current_token = token; @@ -453,11 +461,13 @@ out: assert(cpu->in_opal_call > 0); cpu->in_opal_call--; - if (msr != mfmsr()) - mtmsrd(msr, 0); + this_cpu()->vm_setup = was_vm_setup; + cpu->opal_call_msr = old_opal_call_msr; __this_cpu = (struct cpu_thread *)r16; + assert(mfmsr() == msr); + return ret; } diff --git a/core/vm.c b/core/vm.c index 236a0e70b..b2830fccf 100644 --- a/core/vm.c +++ b/core/vm.c @@ -491,9 +491,18 @@ void *vm_map(unsigned long addr, unsigned long len, bool rw) assert(!c->vm_local_map_inuse); c->vm_local_map_inuse = true; - if (c->vm_setup) { + if (cpu_in_os() && c->vm_setup) { + assert(c->opal_call_msr & (MSR_IR|MSR_DR)); + newaddr = addr; + mtmsr(c->opal_call_msr & ~MSR_DR); + c->vm_setup = false; + } else if (!c->vm_setup) { + newaddr = addr; + } else { struct vm_map *new = &c->vm_local_map; + assert(!cpu_in_os()); + newaddr = LOCAL_EA_BEGIN + LOCAL_EA_PERCPU * c->pir; new->name = "local"; @@ -504,9 +513,6 @@ void *vm_map(unsigned long addr, unsigned long len, bool rw) new->writeable = rw; new->executable = false; new->ci = false; - - } else { - newaddr = addr; } return (void *)newaddr + offset; @@ -527,10 +533,18 @@ void vm_unmap(unsigned long addr, unsigned long len) assert(c->vm_local_map_inuse); c->vm_local_map_inuse = false; - if (c->vm_setup) { + if (cpu_in_os() && (c->opal_call_msr & (MSR_IR|MSR_DR))) { + assert(!c->vm_setup); + c->vm_setup = true; + mtmsr(c->opal_call_msr); + } else if (!c->vm_setup) { + return; + } else { struct vm_map *vmm; unsigned long ea; + assert(!cpu_in_os()); + newaddr = LOCAL_EA_BEGIN + LOCAL_EA_PERCPU * c->pir; vmm = &c->vm_local_map; diff --git a/include/cpu.h b/include/cpu.h index b769024d1..bbfbf7ca9 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -59,6 +59,7 @@ struct cpu_thread { enum cpu_thread_state state; struct dt_node *node; struct trace_info *trace; + uint64_t opal_call_msr; uint64_t save_r1; void *icp_regs; uint32_t in_opal_call;