The branch main has been updated by olce:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=7f005c6699f429c2f762b4dd8fb39b3bcf5378e2

commit 7f005c6699f429c2f762b4dd8fb39b3bcf5378e2
Author:     Olivier Certner <o...@freebsd.org>
AuthorDate: 2025-03-03 21:10:25 +0000
Commit:     Olivier Certner <o...@freebsd.org>
CommitDate: 2025-03-11 13:54:09 +0000

    libsa: smbios: Use 64-bit entry point if table below 4GB on non-EFI boot
    
    On amd64, boot blocks and the non-EFI loader are 32-bit compiled as
    clients of BTX, so cannot access addresses beyond 4GB.  However, the
    64-bit entry point may refer to a structure table below 4GB, which we
    want to use if the BIOS does not provide a 32-bit entry point.  The
    situation is similar for powerpc64.
    
    Consequently, always compile-in support for the 64-bit entry point, but
    ensure that it is not selected on 32-bit-compiled boot loaders if the
    structure table it points to grows beyond 4GB (as it is then not
    accessible).
    
    PR:             284460
    Reviewed by:    markj
    MFC after:      2 weeks
    Relnotes:       yes
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D49288
---
 stand/libsa/smbios.c | 37 ++++++++++++++-----------------------
 1 file changed, 14 insertions(+), 23 deletions(-)

diff --git a/stand/libsa/smbios.c b/stand/libsa/smbios.c
index 2477c0ccf2d3..e0531eab01da 100644
--- a/stand/libsa/smbios.c
+++ b/stand/libsa/smbios.c
@@ -29,11 +29,6 @@
 
 #define PTOV(x)                ptov(x)
 
-/* Only enable 64-bit entry point if it makes sense */
-#if __SIZEOF_POINTER__ > 4
-#define        SMBIOS_64BIT_EP 1
-#endif
-
 /*
  * Detect SMBIOS and export information about the SMBIOS into the
  * environment.
@@ -145,9 +140,7 @@ SMBIOS_GET64(const caddr_t base, int off)
 
 struct smbios_attr {
        int             probed;
-#ifdef SMBIOS_64BIT_EP
        int             is_64bit_ep;
-#endif
        caddr_t         addr;
        size_t          length;
        size_t          count;
@@ -184,7 +177,6 @@ smbios_sigsearch(const caddr_t addr, const uint32_t len)
 
        /* Search on 16-byte boundaries. */
        for (cp = addr; cp < addr + len; cp += SMBIOS_STEP) {
-#ifdef SMBIOS_64BIT_EP
                /* v3.0, 64-bit Entry point */
                if (strncmp(cp, SMBIOS3_SIG, sizeof(SMBIOS3_SIG) - 1) == 0 &&
                    /*
@@ -195,10 +187,19 @@ smbios_sigsearch(const caddr_t addr, const uint32_t len)
                     */
                    SMBIOS_GET8(cp, 0x0a) != 0 &&
                    smbios_checksum(cp, SMBIOS_GET8(cp, 0x06)) == 0) {
+#ifdef __ILP32__
+                       uint64_t end_addr;
+
+                       end_addr = SMBIOS_GET64(cp, 0x10) + /* Start address. */
+                           SMBIOS_GET32(cp, 0x0c); /* Maximum size. */
+                       /* Is the table (or part of it) located above 4G? */
+                       if (end_addr >= (uint64_t)1 << 32)
+                               /* Can't access it with 32-bit addressing. */
+                               continue;
+#endif
                        smbios.is_64bit_ep = 1;
                        return (cp);
                }
-#endif
 
                /* v2.1, 32-bit Entry point */
                if (strncmp(cp, SMBIOS_SIG, sizeof(SMBIOS_SIG) - 1) == 0 &&
@@ -207,13 +208,9 @@ smbios_sigsearch(const caddr_t addr, const uint32_t len)
                    smbios_checksum(cp + 0x10, 0x0f) == 0) {
                        /*
                         * Note that we saw this entry point, but don't return
-                        * it right now on SMBIOS_64BIT_EP as we favor the 
64-bit
-                        * one if present.
+                        * it right now as we favor the 64-bit one if present.
                         */
                        v2_p = cp;
-#ifndef SMBIOS_64BIT_EP
-                       break;
-#endif
                }
        }
        return (v2_p);
@@ -586,7 +583,6 @@ smbios_probe(const caddr_t addr)
        if (saddr == NULL)
                return;
 
-#ifdef SMBIOS_64BIT_EP
        if (smbios.is_64bit_ep) {
                /* Structure Table Length */
                smbios.length = SMBIOS_GET32(saddr, 0x0c);
@@ -601,9 +597,7 @@ smbios_probe(const caddr_t addr)
                smbios.ver = 0;
                maj_off = 0x07;
                min_off = 0x08;
-       } else
-#endif
-       {
+       } else {
                /* Structure Table Length */
                smbios.length = SMBIOS_GET16(saddr, 0x16);
                /* Structure Table Address */
@@ -661,11 +655,8 @@ smbios_detect(const caddr_t addr)
            dmi < smbios.addr + smbios.length && i < smbios.count; i++)
                dmi = smbios_parse_table(dmi);
 
-       setenv("smbios.entry_point_type",
-#ifdef SMBIOS_64BIT_EP
-           smbios.is_64bit_ep ? "v3 (64-bit)" :
-#endif
-           "v2.1 (32-bit)", 1);
+       setenv("smbios.entry_point_type", smbios.is_64bit_ep ?
+           "v3 (64-bit)" : "v2.1 (32-bit)", 1);
        sprintf(buf, "%d.%d", smbios.major, smbios.minor);
        setenv("smbios.version", buf, 1);
        if (smbios.enabled_memory > 0 || smbios.old_enabled_memory > 0) {

Reply via email to