From patchwork Tue May 19 05:46:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver O'Halloran X-Patchwork-Id: 1292951 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (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 49R4jK0Mw0z9sVj for ; Tue, 19 May 2020 15:50: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=IxS7oG0A; 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 49R4jJ6l78zDqWL for ; Tue, 19 May 2020 15:50:12 +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::444; helo=mail-pf1-x444.google.com; envelope-from=oohall@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=IxS7oG0A; dkim-atps=neutral Received: from mail-pf1-x444.google.com (mail-pf1-x444.google.com [IPv6:2607:f8b0:4864:20::444]) (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 49R4dv2bJYzDqtK for ; Tue, 19 May 2020 15:47:15 +1000 (AEST) Received: by mail-pf1-x444.google.com with SMTP id y198so4442310pfb.4 for ; Mon, 18 May 2020 22:47:15 -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=htyJyqekQkxdqEj67f/Al584bex1Bo5S8gJbJse7UCw=; b=IxS7oG0AI0XXXdP47tKESK9yx2226Dm0GrZiJJeexMeUHdXohUYss7wj6X/kqj4ATQ 3NCNsa+iYsieuPcEJZn/TAULgG5I97plrnxSblLyLVW8u7FcAcolXUcwJQmDr5Snu5xM v3U4G021hlbt0pHUqbxmuUfl5CiVyPMF2U6RZqkfOad6UY1V29K3fHrm1RleqCM4dGdL 15qx5ExIsVVbhELKiY507KclmfDtDXeP5yBF04Sm+E822jzwiduj4ARHV/6kyYM4xDIm 3cDvKXFNxxjBF3aaqdmxkEQR4NpH02Ii/ftFUWrE3lD2cofn5TopV30NKtjjAuQkbpG5 Bqqw== 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=htyJyqekQkxdqEj67f/Al584bex1Bo5S8gJbJse7UCw=; b=L2wjCsK0arSlJXmzsdVVdTqs1aKIYb/2SRiPxX0BMe45XAEhIfvWBEszTiMTFDdjaO oDjiVyWIm0G6COyryPlFuKm5fDVvA/ZS6n/NmpxyLEm3E8jDFEhS94Ieay148gAt95PP zXKTz3LsmkXnsD5aZW7y9ZuzFhu9aYDQ0OSdIaPvYhAhpXipD/KYZJArRUlo11ir01XT EhKpYibPdebDc9dtkUM5k2h4nid9Xg9qW25+PCzaV+o8w4dlnLY0cWNlJLTfIsXPhjn6 av3aLXUG7lOhY4sUOO/IrEVYhe2DfWsq7uBgUs0oUyubGXoM9XJxVsdgUzM6lUBSwdgL RvnQ== X-Gm-Message-State: AOAM530szRnCyOfPMnsawfCvNYn9c8TnXx4NGfjnXRUjxe+N0vF/1LIA ctzEJX/8m4izXh6Rnf+kIhQQnXBA X-Google-Smtp-Source: ABdhPJwIm3xEm6YGQ+/uoJ+/S7RdMZmHz5vBTdShtFSkKmp/nzqG+pX6QxIPnd19vSa4H5Ao4hRACw== X-Received: by 2002:a62:16d5:: with SMTP id 204mr18136223pfw.10.1589867232360; Mon, 18 May 2020 22:47:12 -0700 (PDT) Received: from 192-168-1-12.tpgi.com.au ([203.221.252.191]) by smtp.gmail.com with ESMTPSA id p12sm2798358pgj.22.2020.05.18.22.47.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 May 2020 22:47:11 -0700 (PDT) From: Oliver O'Halloran To: skiboot@lists.ozlabs.org Date: Tue, 19 May 2020 15:46:26 +1000 Message-Id: <20200519054633.113238-6-oohall@gmail.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200519054633.113238-1-oohall@gmail.com> References: <20200519054633.113238-1-oohall@gmail.com> MIME-Version: 1.0 Subject: [Skiboot] [RFC PATCH 05/12] core/console: Add a seperate ABI memcons struct 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 renames the existing memcons structure to memcons_desc and adds a new memcons structure that is used internally by skiboot. There's two main reasons for doing this: a) The memcons_desc may be DMA mapped as writable so the FSP/BMC can write to it to implement the "input" portion of the in-memory console. As a result we should not be blindling trusting the buffer pointers from the descriptor and we should validate the offsets are correct. b) Skiboot can be running little endian so we to handle the endian conversions which can get a bit unwieldly. Seperating the external desctriptor (which is ABI) and the internal console state helps to address both issues. We can rely on the internal state since it can never be tampered with externally, and we can use the internal state to regenerate the external descriptor as-needed. Signed-off-by: Oliver O'Halloran --- core/console.c | 39 ++++++++++++++++++++++---------- include/console.h | 22 +++++++++++++++++- platforms/ibm-fsp/common.c | 6 ++--- platforms/ibm-fsp/hostservices.c | 2 +- 4 files changed, 52 insertions(+), 17 deletions(-) diff --git a/core/console.c b/core/console.c index a1ec687cb67e..8be7ee578b18 100644 --- a/core/console.c +++ b/core/console.c @@ -17,6 +17,12 @@ static char *con_buf = (char *)INMEM_CON_START; static size_t con_in; + +/* + * Skiboot is both the producer and consumer of the memcons. On the consumer + * side we need to keep track of how much of the log buffer has been written + * out to the console which is what con_out is for. + */ static size_t con_out; static bool con_wrapped; @@ -29,7 +35,7 @@ static struct opal_con_ops *opal_con_driver = &dummy_opal_con; static struct lock con_lock = LOCK_UNLOCKED; /* This is mapped via TCEs so we keep it alone in a page */ -struct memcons memcons __section(".data.memcons") = { +struct memcons_desc memcons_desc __section(".data.memcons") = { .magic = CPU_TO_BE64(MEMCONS_MAGIC), .obuf_phys = CPU_TO_BE64(INMEM_CON_START), .ibuf_phys = CPU_TO_BE64(INMEM_CON_START + INMEM_CON_OUT_LEN), @@ -37,6 +43,15 @@ struct memcons memcons __section(".data.memcons") = { .ibuf_size = CPU_TO_BE32(INMEM_CON_IN_LEN), }; +struct memcons memcons = { + .desc = &memcons_desc, + .obuf = (char *) INMEM_CON_START, + .obuf_size = INMEM_CON_OUT_LEN, + + .ibuf = (char *) (INMEM_CON_START + INMEM_CON_OUT_LEN), + .ibuf_size = INMEM_CON_IN_LEN, +}; + static bool dummy_console_enabled(void) { #ifdef FORCE_DUMMY_CONSOLE @@ -187,7 +202,7 @@ static void inmem_write(char c) } /* - * We must always re-generate memcons.out_pos because + * We must always re-generate memcons.desc->out_pos because * under some circumstances, the console script will * use a broken putmemproc that does RMW on the full * 8 bytes containing out_pos and in_prod, thus corrupting @@ -197,7 +212,7 @@ static void inmem_write(char c) if (con_wrapped) opos |= MEMCONS_OUT_POS_WRAP; lwsync(); - memcons.out_pos = cpu_to_be32(opos); + memcons.desc->out_pos = cpu_to_be32(opos); } static void write_char(char c) @@ -205,8 +220,8 @@ static void write_char(char c) inmem_write(c); /* If head reaches tail, push tail around & drop chars */ - if (con_out == memcons.out_pos) - con_out = (memcons.out_pos + 1) % memcons.obuf_size; + if (con_out == memcons.desc->out_pos) + con_out = (memcons.desc->out_pos + 1) % memcons.desc->obuf_size; } ssize_t console_write(bool flush_to_drivers, const void *buf, size_t count) @@ -240,12 +255,12 @@ ssize_t write(int fd __unused, const void *buf, size_t count) static size_t inmem_read(char *buf, size_t req) { size_t read = 0; - char *ibuf = (char *)be64_to_cpu(memcons.ibuf_phys); + char *ibuf = (char *)be64_to_cpu(memcons.desc->ibuf_phys); - while (req && be32_to_cpu(memcons.in_prod) != be32_to_cpu(memcons.in_cons)) { - *(buf++) = ibuf[be32_to_cpu(memcons.in_cons)]; + while (req && be32_to_cpu(memcons.desc->in_prod) != be32_to_cpu(memcons.desc->in_cons)) { + *(buf++) = ibuf[be32_to_cpu(memcons.desc->in_cons)]; lwsync(); - memcons.in_cons = cpu_to_be32((be32_to_cpu(memcons.in_cons) + 1) % INMEM_CON_IN_LEN); + memcons.desc->in_cons = cpu_to_be32((be32_to_cpu(memcons.desc->in_cons) + 1) % INMEM_CON_IN_LEN); req--; read++; } @@ -335,7 +350,7 @@ void init_opal_console(void) void memcons_add_properties(void) { - dt_add_property_u64(opal_node, "ibm,opal-memcons", (u64) &memcons); + dt_add_property_u64(opal_node, "ibm,opal-memcons", (u64) &memcons_desc); } /* @@ -407,7 +422,7 @@ static void dummy_console_poll(void *data __unused) bool has_data = false; lock(&con_lock); - if (memcons.in_prod != memcons.in_cons) + if (memcons.desc->in_prod != memcons.desc->in_cons) has_data = true; if (has_data) opal_update_pending_evt(OPAL_EVENT_CONSOLE_INPUT, @@ -421,7 +436,7 @@ void dummy_console_add_nodes(void) { struct dt_property *p; - add_opal_console_node(0, "raw", be32_to_cpu(memcons.obuf_size)); + add_opal_console_node(0, "raw", be32_to_cpu(memcons.desc->obuf_size)); /* Mambo might have left a crap one, clear it */ p = __dt_find_property(dt_chosen, "linux,stdout-path"); diff --git a/include/console.h b/include/console.h index 6abd04b77d78..280f920aba44 100644 --- a/include/console.h +++ b/include/console.h @@ -12,21 +12,41 @@ * facility or FSP. * * (This is v3 of the format, the previous one sucked) + * + * NB: This might be writable from the BMC! Don't blindly trust the contents. */ -struct memcons { +struct memcons_desc { __be64 magic; #define MEMCONS_MAGIC 0x6630696567726173LL __be64 obuf_phys; __be64 ibuf_phys; __be32 obuf_size; __be32 ibuf_size; + + /* Output ring buffer write head. OPAL is the producer */ __be32 out_pos; #define MEMCONS_OUT_POS_WRAP 0x80000000u #define MEMCONS_OUT_POS_MASK 0x00ffffffu + + /* Input ring buffer offsets. OPAL is the consumer */ __be32 in_prod; __be32 in_cons; }; +/* internal version of the above, trustworthy, native endian, etc */ +struct memcons { + struct memcons_desc *desc; + + char *obuf; + uint32_t obuf_size; + + char *ibuf; + uint32_t ibuf_size; + + uint32_t out_pos; + bool has_wrapped; +}; + extern struct memcons memcons; #define INMEM_CON_IN_LEN 16 diff --git a/platforms/ibm-fsp/common.c b/platforms/ibm-fsp/common.c index 4a723b25b064..6a20dc7ac36a 100644 --- a/platforms/ibm-fsp/common.c +++ b/platforms/ibm-fsp/common.c @@ -21,13 +21,13 @@ static void map_debug_areas(void) /* Our memcons is in a section of its own and already * aligned to 4K. The buffers are mapped as a whole */ - fsp_tce_map(PSI_DMA_MEMCONS, &memcons, 0x1000); + fsp_tce_map(PSI_DMA_MEMCONS, memcons.desc, 0x1000); fsp_tce_map(PSI_DMA_LOG_BUF, (void*)INMEM_CON_START, INMEM_CON_LEN); debug_descriptor.memcons_tce = cpu_to_be32(PSI_DMA_MEMCONS); - t = be64_to_cpu(memcons.obuf_phys) - INMEM_CON_START + PSI_DMA_LOG_BUF; + t = be64_to_cpu(memcons.desc->obuf_phys) - INMEM_CON_START + PSI_DMA_LOG_BUF; debug_descriptor.memcons_obuf_tce = cpu_to_be32(t); - t = be64_to_cpu(memcons.ibuf_phys) - INMEM_CON_START + PSI_DMA_LOG_BUF; + t = be64_to_cpu(memcons.desc->ibuf_phys) - INMEM_CON_START + PSI_DMA_LOG_BUF; debug_descriptor.memcons_ibuf_tce = cpu_to_be32(t); t = PSI_DMA_TRACE_BASE; diff --git a/platforms/ibm-fsp/hostservices.c b/platforms/ibm-fsp/hostservices.c index 81fd6bdd3695..c0effc3e4067 100644 --- a/platforms/ibm-fsp/hostservices.c +++ b/platforms/ibm-fsp/hostservices.c @@ -177,7 +177,7 @@ static bool hbrt_con_wrapped; #define HBRT_CON_IN_LEN 0 #define HBRT_CON_OUT_LEN (HBRT_CON_LEN - HBRT_CON_IN_LEN) -static struct memcons hbrt_memcons __section(".data.memcons") = { +static struct memcons_desc hbrt_memcons __section(".data.memcons") = { .magic = CPU_TO_BE64(MEMCONS_MAGIC), .obuf_phys = CPU_TO_BE64(HBRT_CON_START), .ibuf_phys = CPU_TO_BE64(HBRT_CON_START + HBRT_CON_OUT_LEN),