From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=0.2 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED autolearn=no autolearn_force=no version=3.4.4 Received: (qmail 3549 invoked from network); 16 Nov 2022 20:14:09 -0000 Received: from 9front.inri.net (168.235.81.73) by inbox.vuxu.org with ESMTPUTF8; 16 Nov 2022 20:14:09 -0000 Received: from mail-pj1-f43.google.com ([209.85.216.43]) by 9front; Wed Nov 16 15:10:38 -0500 2022 Received: by mail-pj1-f43.google.com with SMTP id m6-20020a17090a5a4600b00212f8dffec9so3572553pji.0 for <9front@9front.org>; Wed, 16 Nov 2022 12:10:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mforney.org; s=google; h=content-transfer-encoding:mime-version:to:subject:date:from :message-id:from:to:cc:subject:date:message-id:reply-to; bh=vbVggoJVfMkHMGa8oMyamrxGoHGLyYjnua+pUCWviqc=; b=PeEs6PFeSA8Y4H+alKhY7rBwsLLsI0WiGSZSMxCyMKb7gnUGeipfAVXeC23C7HnhFN 6Oz/GyHizV3LGuB30EaNWIz2EAXpq6r7N2P/yW15KzfoAVM2pYvtlnAlOETFFj4bzajs d252KyDkm7YrWXqG4GWkZcBQMp5hB9z3Usy4vlfVbaxG0E+ooCwWR80n+mJQMJwH3OMu m5hRlMJHRXvHREcbJ+/wVdQC0MoXAlcn5lUT8yYzDtGD8CWUbUZX//Nld6qAO4IU3Ky+ hXrJTL/oCOfp8lbZd7sePbqs7AeO23lQNHrAg7Cv6kgb/uZhNpDcYgZpj6zYIjxngZEs K2kw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:to:subject:date:from :message-id:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=vbVggoJVfMkHMGa8oMyamrxGoHGLyYjnua+pUCWviqc=; b=FxgE10fHKAGbLWDgyITB5rn2YLSIvNBn2vi6xWKByqoZ+VZK8c9NvOIOew0RqPI95S wfb8hmHyCxaxbWjGtDh7stoAzQJYWguhoUPFtUDEvEtt/aI+kESaeb7ZnwbbtdmwDtDK EhlcMLYkzaoXdXyd5FNqJjoOzBoKOSi9LMoxvBX3zMLTi6xCfnO7ehDyZkWmd5uCs36Z ZOgxgknEBXQ9MHG3ENtjFip9BYporqNwh1V4ub5g0ptnAQHozS0aTsCGltIkvAWuqmFg k3tX32B45uvZ1NMiURer4oP1kP1lBZGZ+jTG/aP/qe/6/mHah4uIHd9lwkDtQhUwD9ua hhZQ== X-Gm-Message-State: ANoB5pnMGXxRJ896qDZEhZSDoxhzun7bxDx7cROLO7XUJwoY5bSP7iNO K8eJiAxpSGjmftpR1MU5BZ1D30hoeXqvj5d1uPQ= X-Google-Smtp-Source: AA0mqf6zf+WvY/VUlHeFs03yzQzxolkyeVphnjcJSRtvBPBgpbJAGb3zHeqjM6yydoB/uISu0xt/bA== X-Received: by 2002:a17:90a:470e:b0:20a:61a4:9389 with SMTP id h14-20020a17090a470e00b0020a61a49389mr5281159pjg.20.1668629433835; Wed, 16 Nov 2022 12:10:33 -0800 (PST) Return-Path: Received: from t14.hsd1.ca.comcast.net ([98.45.132.135]) by smtp.gmail.com with ESMTPSA id i13-20020a056a00004d00b0056286c552ecsm11251321pfk.184.2022.11.16.12.10.33 for <9front@9front.org> (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 16 Nov 2022 12:10:33 -0800 (PST) Message-ID: <058CCCF199316D00FB1ABF63EBD3B3A8@mforney.org> From: Michael Forney Date: Wed, 16 Nov 2022 19:40:49 +0000 To: 9front@9front.org MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: shared agile just-in-time API Subject: [9front] [PATCH] boot/efi: delay GetMemoryMap until right before ExitBootServices Reply-To: 9front@9front.org Precedence: bulk The UEFI specification suggests calling GetMemoryMap immediately before ExitBootServices to ensure that the loader has the current memory map. The firmware is able to enforce this since we have to pass a "MapKey" from the last GetMemoryMap to ExitBootServices. The T14 AMD gen 1 firmware is quite strict about this, and even a call to OutputString will invalidate the MapKey. This causes ExitBootServices to fail, and we enter 9front with boot services still running. This causes all sorts of problems including leaving the IOMMU enabled, breaking 9front's PCI drivers. To fix this, move memconf() to unload(), right before ExitBootServices. To retain the ability to override the memory map, check if *e820 is already set and if so, ignore the output of GetMemoryMap except for the MapKey. --- Still some room for improvement around the *conf helper functions, but I think this is fine for now. I also wonder what we should be doing if GetMemoryMap fails. If we don't have any potentially valid MapKey, how could ExitBootServices succeed? Perhaps we could make unload return an error string on failure, and pass it back from bootkern so that we can inform the user that something is wrong. diff a854bb07cd792a52c5e75aabca76c22b7dd18fc6 eb07ce3baa9705a30ecf3cd6b31ff851e24cb3d1 --- a/sys/src/boot/efi/efi.c +++ b/sys/src/boot/efi/efi.c @@ -36,12 +36,6 @@ eficall(ST->BootServices->Stall, (UINTN)us); } -void -unload(void) -{ - eficall(ST->BootServices->ExitBootServices, IH, MK); -} - static void memconf(char **cfg) { @@ -72,6 +66,8 @@ entvers = 1; if(eficall(ST->BootServices->GetMemoryMap, &mapsize, mapbuf, &MK, &entsize, &entvers)) return; + if(cfg == nil) + return; s = *cfg; for(p = mapbuf; mapsize >= entsize; p += entsize, mapsize -= entsize){ @@ -93,7 +89,6 @@ *s = '\0'; if(s > *cfg){ s[-1] = '\n'; - print(*cfg); *cfg = s; } } @@ -276,9 +271,15 @@ void eficonfig(char **cfg) { - memconf(cfg); acpiconf(cfg); screenconf(cfg); +} + +void +unload(char **cfg) +{ + memconf(cfg); + eficall(ST->BootServices->ExitBootServices, IH, MK); } EFI_STATUS --- a/sys/src/boot/efi/fns.h +++ b/sys/src/boot/efi/fns.h @@ -16,7 +16,7 @@ void (*close)(void *f); int readn(void *f, void *data, int len); -void unload(void); +void unload(char **cfg); int getc(void); void putc(int c); --- a/sys/src/boot/efi/sub.c +++ b/sys/src/boot/efi/sub.c @@ -156,6 +156,23 @@ char *confend; +static int +hasconf(char *s) +{ + char *p; + int n; + + n = strlen(s); + for(p = BOOTARGS; n <= confend - p; p++){ + if(memcmp(p, s, n) == 0) + return 1; + p = strchr(p, '\n'); + if(p == nil) + break; + } + return 0; +} + static char* getconf(char *s, char *buf) { @@ -364,7 +381,7 @@ close(f); print("boot\n"); - unload(); + unload(hasconf("*e820=") ? nil : &confend); jump(e);