From patchwork Mon Aug 24 03:31:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cyril Bur X-Patchwork-Id: 509904 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.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4208A140271 for ; Mon, 24 Aug 2015 13:32:33 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 1B5261A1D9D for ; Mon, 24 Aug 2015 13:32:33 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from e23smtp08.au.ibm.com (e23smtp08.au.ibm.com [202.81.31.141]) (using TLSv1 with cipher CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 716971A1D63 for ; Mon, 24 Aug 2015 13:32:25 +1000 (AEST) Received: from /spool/local by e23smtp08.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 24 Aug 2015 13:32:23 +1000 Received: from d23dlp01.au.ibm.com (202.81.31.203) by e23smtp08.au.ibm.com (202.81.31.205) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 24 Aug 2015 13:32:22 +1000 X-Helo: d23dlp01.au.ibm.com X-MailFrom: cyril.bur@au1.ibm.com X-RcptTo: skiboot@lists.ozlabs.org Received: from d23relay10.au.ibm.com (d23relay10.au.ibm.com [9.190.26.77]) by d23dlp01.au.ibm.com (Postfix) with ESMTP id 2F5C32CE8055 for ; Mon, 24 Aug 2015 13:32:22 +1000 (EST) Received: from d23av03.au.ibm.com (d23av03.au.ibm.com [9.190.234.97]) by d23relay10.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t7O3WDWE47448268 for ; Mon, 24 Aug 2015 13:32:22 +1000 Received: from d23av03.au.ibm.com (localhost [127.0.0.1]) by d23av03.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t7O3Vn8w024456 for ; Mon, 24 Aug 2015 13:31:49 +1000 Received: from ozlabs.au.ibm.com (ozlabs.au.ibm.com [9.192.253.14]) by d23av03.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t7O3VnsR023773 for ; Mon, 24 Aug 2015 13:31:49 +1000 Received: from camb691.ozlabs.ibm.com (haven.au.ibm.com [9.192.254.114]) by ozlabs.au.ibm.com (Postfix) with ESMTP id 84EB0A01D9 for ; Mon, 24 Aug 2015 13:31:25 +1000 (AEST) From: Cyril Bur To: skiboot@lists.ozlabs.org Date: Mon, 24 Aug 2015 13:31:17 +1000 Message-Id: <1440387077-14597-2-git-send-email-cyril.bur@au1.ibm.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1440387077-14597-1-git-send-email-cyril.bur@au1.ibm.com> References: <1440387077-14597-1-git-send-email-cyril.bur@au1.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15082403-0029-0000-0000-000002106B93 Subject: [Skiboot] [PATCH 2/2] external/gard: Check the validity of the flash X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" If the GUARD partition has been corrupted such that ECC checks fail and not even the first gard record can be read then the gard tool will be unable to do anything. If this happens it is possible that hostboot will have a similar problem. The only sane thing to do at is point is probably to wipe the GUARD partition. This patch adds a check for this case and provides the user with the option to wipe the entirety of the GUARD partition to attempt recovery. Signed-off-by: Cyril Bur --- external/gard/gard.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/external/gard/gard.c b/external/gard/gard.c index d84e098..7b0ea2b 100644 --- a/external/gard/gard.c +++ b/external/gard/gard.c @@ -566,6 +566,56 @@ static int do_clear(struct gard_ctx *ctx, int argc, char **argv) return rc; } +int check_gard_partition(struct gard_ctx *ctx) +{ + int rc; + struct gard_record gard; + char msg[2]; + + if (ctx->gard_data_len == 0 || ctx->gard_data_len % sizeof(struct gard_record) != 0) + /* Just warn for now */ + fprintf(stderr, "The %s partition doesn't appear to be an exact multiple of" + "gard records in size: %lu vs %u (or partition is zero in length)\n", + FLASH_GARD_PART, sizeof(struct gard_record), ctx->gard_data_len); + + /* + * Attempt to read the first record, nothing can really operate if the + * first record is dead. There (currently) isn't a way to validate more + * than ECC correctness. + */ + rc = blocklevel_read(ctx->bl, ctx->gard_data_pos, &gard, sizeof(gard)); + if (rc == FLASH_ERR_ECC_INVALID) { + fprintf(stderr, "The data at the GUARD partition does not appear to be valid gard data\n"); + fprintf(stderr, "Clear the entire GUARD partition? [y/N]\n"); + if (fgets(msg, sizeof(msg), stdin) == NULL) { + fprintf(stderr, "Couldn't read from standard input\n"); + return -1; + } + if (msg[0] == 'y') { + rc = blocklevel_erase(ctx->bl, ctx->gard_data_pos, ctx->gard_data_len); + if (rc) { + fprintf(stderr, "Couldn't erase flash partition. Bailing out\n"); + return rc; + } + + memset(&gard, INT_MAX, sizeof(gard)); + + rc = blocklevel_smart_write(ctx->bl, ctx->gard_data_pos, &gard, sizeof(gard)); + if (rc) { + fprintf(stderr, "Couldn't create a sane first gard record. Bailing out\n"); + return rc; + } + } + /* + * else leave rc as is so that the main bails out, not going to be + * able to do sensible anyway + */ + } + return rc; +} + + + __attribute__ ((unused)) static int do_nop(struct gard_ctx *ctx, int argc, char **argv) { @@ -718,11 +768,11 @@ int main(int argc, char **argv) ctx->gard_data_len = ctx->f_size; } - if (ctx->gard_data_len == 0 || ctx->gard_data_len % sizeof(struct gard_record) != 0) - /* Just warn for now */ - fprintf(stderr, "The %s partition doesn't appear to be an exact multiple of" - "gard records in size: %lu vs %u (or partition is zero in length)\n", - FLASH_GARD_PART, sizeof(struct gard_record), ctx->gard_data_len); + rc = check_gard_partition(ctx); + if (rc) { + fprintf(stderr, "Does not appear to be sane gard data\n"); + goto out; + } for (i = 0; i < ARRAY_SIZE(actions); i++) { if (!strcmp(actions[i].name, action)) {