diff mbox

[SeaBIOS] SeaBIOS error with Juniper FreeBSD kernel

Message ID 87y5zc9mzu.fsf@nemi.mork.no
State New
Headers show

Commit Message

Bjørn Mork Aug. 2, 2011, 9:33 a.m. UTC
"Kevin O'Connor" <kevin@koconnor.net> writes:
> On Mon, Aug 01, 2011 at 03:49:11PM +0200, Bjørn Mork wrote:
>> I just confirmed the issue running
>> 
>>  "JUNOS 11.1R3.5 built 2011-06-25 00:17:21 UTC"
>> 
>> which is as new as it officially gets at the moment.
> [...]
>> Also confirmed that 11.1R3.5 is working with SeaBIOS modified as
>> follows:
> [...]
>> -    void *finaltable = malloc_high(structure_table_length);
>> +    void *finaltable = malloc_fseg(structure_table_length);
>
> I'm not really sure how best to handle this.  The smbios table can be
> larger than the current space reserved for the f-segment (when there
> are a large number of CPUs).
>
> Some ideas:
>
> There is actually space in the f-segment that is unused, but not given
> to the malloc_fseg pool.  That space could be given to the pool -
> though the available space will still vary depending on the code size.
>
> It's also possible to relocate the 32bit "run-time" code to high
> memory which would then free up more space in the f-segment (at the
> cost of some high memory being reserved from the OS).  As above,
> though, the f-segment is still fundamentally limited by the 16bit code
> size.
>
> Also, it's possible the code could try to use the f-segment if there
> are less than say 16 cpus and use high memory when more cpus are
> present.

How about a variant over the last suggestion: Don't actually care bout
the number of CPUs, but just fall back to malloc_high if malloc_fseg
fails?

The attached patch works-for-me, and boots JUNOS as long as the number
of CPUs is low enough for malloc_fseg to succeed.


Bjørn

Comments

Kevin O'Connor Aug. 2, 2011, 12:41 p.m. UTC | #1
On Tue, Aug 02, 2011 at 11:33:09AM +0200, Bjørn Mork wrote:
> "Kevin O'Connor" <kevin@koconnor.net> writes:
> > Also, it's possible the code could try to use the f-segment if there
> > are less than say 16 cpus and use high memory when more cpus are
> > present.
> 
> How about a variant over the last suggestion: Don't actually care bout
> the number of CPUs, but just fall back to malloc_high if malloc_fseg
> fails?

This could make testing painful - small changes in the code could
cause a different table layout that is OS visible.  I'd prefer a more
strict cutoff.  Though, I suppose the cutoff could be by the table
size itself instead of by number of CPUs.

-Kevin
Bjørn Mork Aug. 3, 2011, 12:42 p.m. UTC | #2
"Kevin O'Connor" <kevin@koconnor.net> writes:
> On Tue, Aug 02, 2011 at 11:33:09AM +0200, Bjørn Mork wrote:
>> "Kevin O'Connor" <kevin@koconnor.net> writes:
>> > Also, it's possible the code could try to use the f-segment if there
>> > are less than say 16 cpus and use high memory when more cpus are
>> > present.
>> 
>> How about a variant over the last suggestion: Don't actually care bout
>> the number of CPUs, but just fall back to malloc_high if malloc_fseg
>> fails?
>
> This could make testing painful - small changes in the code could
> cause a different table layout that is OS visible.  I'd prefer a more
> strict cutoff.  Though, I suppose the cutoff could be by the table
> size itself instead of by number of CPUs.

This is of course your call to make...

But I must admit that I fail to see the advantage.  I agree that having
the table moved around depending on some variable is a problem.  Which
variable doesn't really matter. At least I don't see a fixed cutoff size
as any more predictable than a f-segment allocation failure, given that
I have no clue as to what SMBIOS table size is to be expected.  Maybe go
for the number of CPUs then.  But what if additional data is added to
the table, making f-segment allocation fail?  Then you will end up with
three different results depending on small changes instead of two:

 1) nCPU <= 16 and f-segment allocation OK: SMBIOS in f-segment
 2) nCPU > 16: SMBIOS in high mem
 3) nCPU <= 16 and f-segment allocation failed: no SMBIOS table

I don't think that makes testing any less painful...

Anyway, I would appreciate if some solution was found which allowed
JUNOS to boot with an unmodified SeaBIOS with SMBIOS enabled, as long as
the number of CPUs is limited.


Bjørn
Avi Kivity Aug. 3, 2011, 1:31 p.m. UTC | #3
On 08/03/2011 03:42 PM, Bjørn Mork wrote:
> Anyway, I would appreciate if some solution was found which allowed
> JUNOS to boot with an unmodified SeaBIOS with SMBIOS enabled, as long as
> the number of CPUs is limited.
>
>

Is fixing JUNOS out of the question?

AFAICT, Seabios complies with all relevant standards.
Bjørn Mork Aug. 3, 2011, 1:48 p.m. UTC | #4
Avi Kivity <avi@redhat.com> writes:
> On 08/03/2011 03:42 PM, Bjørn Mork wrote:
>> Anyway, I would appreciate if some solution was found which allowed
>> JUNOS to boot with an unmodified SeaBIOS with SMBIOS enabled, as long as
>> the number of CPUs is limited.
>>
>>
>
> Is fixing JUNOS out of the question?

Yes, I would say so.  The ability to run it on non-Juniper hardware is
undocumented and unsupported to the degree that the functionality
probably rather would be removed than fixed to support something like
SeaBIOS.

> AFAICT, Seabios complies with all relevant standards.

Yes, I have no reason to believe otherwise.  But still it does behave
sufficiently different from other BIOSes for low CPU count machines to
fail in this particular case.

I see this as another end of the discussion about whether Linux should
try to configure PC hardware in the same manner as Windows, as that is
the configuration which will be tested by hardware vendors.  Most OS
vendors will test their systems with the big proprietary BIOSes and not
with SeaBIOS.

Does that make sense?


Bjørn
Avi Kivity Aug. 3, 2011, 2:03 p.m. UTC | #5
On 08/03/2011 04:48 PM, Bjørn Mork wrote:
> >
> >  Is fixing JUNOS out of the question?
>
> Yes, I would say so.  The ability to run it on non-Juniper hardware is
> undocumented and unsupported to the degree that the functionality
> probably rather would be removed than fixed to support something like
> SeaBIOS.
>
> >  AFAICT, Seabios complies with all relevant standards.
>
> Yes, I have no reason to believe otherwise.  But still it does behave
> sufficiently different from other BIOSes for low CPU count machines to
> fail in this particular case.
>
> I see this as another end of the discussion about whether Linux should
> try to configure PC hardware in the same manner as Windows, as that is
> the configuration which will be tested by hardware vendors.  Most OS
> vendors will test their systems with the big proprietary BIOSes and not
> with SeaBIOS.
>
> Does that make sense?

It does, I wasn't sure if you're working on behalf of Juniper or not.

I guess the options are:
  - build time switch
  - run time switch, controlled by qemu via fwcfg
  - run time decision based on size
  - do nothing
Kevin O'Connor Aug. 3, 2011, 11:48 p.m. UTC | #6
On Wed, Aug 03, 2011 at 02:42:15PM +0200, Bjørn Mork wrote:
>But what if additional data is added to
> the table, making f-segment allocation fail?  Then you will end up with
> three different results depending on small changes instead of two:
> 
>  1) nCPU <= 16 and f-segment allocation OK: SMBIOS in f-segment
>  2) nCPU > 16: SMBIOS in high mem
>  3) nCPU <= 16 and f-segment allocation failed: no SMBIOS table

If a reasonable limit is placed on the size of the SMBIOS table then
in practice the allocation will always succeed.

All of the f-segment allocations with the exception of the mptable are
small.  The mptable allocation should probably have an upper bound
placed on it as well.  There's currently 2048 bytes reserved for
malloc_fseg (CONFIG_MAX_BIOSTABLE), and the current smbios uses 263
bytes with one cpu and 938 bytes with 16 cpus (memory size may also
change size slightly).

-Kevin
diff mbox

Patch

From 66522176f711bbf609e10100fb713fc3ed6101c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
Date: Thu, 7 Jul 2011 17:45:32 +0200
Subject: [PATCH] SMBIOS: use malloc_fseg() to avoid boot error on JUNOS
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Falling back to using malloc_high if malloc_fseg fails to
support large tables e.g. due to a high number of cpus.

The SMBIOS table must be allocated from low memory to prevent
this bug when booting JUNOS:

kernel trap 12 with interrupts disabled
instruction pointer     = 0x8:0xc053a6ae
stack pointer           = 0x10:0xc09dce7c
frame pointer           = 0x10:0xc09dced4
code segment            = base 0x0, limit 0xfffff, type 0x1b
                        = DPL 0, pres 1, def32 1, gran 1
processor eflags        = interrupt enabled, IOPL = 0
current process         = Idle
interrupt mask          = net tty bio cam
trap number             = 30
dog: ERROR - reset of uninitialized watchdog
panic: unknown/reserved trap
(null)(c087aa20,c087aa20,c07ebef2,c09dcd90,5) at0
(null)(c07ebef2,1e,c09dced4,0,0) at0
(null)(c09dce3c,0,c09dcdf4,c051c108) at0
(null)(c09d0010,c09d0010,10,0,c) at0
(null)(9e0010,10,c0100010,0,9e1000) at0
(null)(2) at0
(null)(c07ecd92,f,c07d33a6,c09dcf54,ffffffff) at0
(null)(c09dcfd4,f,3,8,0) at0
(null)(9e1000,0,0,0,0) at0
(null)() at0
dog: ERROR - reset of uninitialized watchdog
dog: ERROR - reset of uninitialized watchdog
Uptime: 0s

Signed-off-by: Bjørn Mork <bjorn@mork.no>
---
 src/smbios.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/src/smbios.c b/src/smbios.c
index 8df0f2d..5ca85cd 100644
--- a/src/smbios.c
+++ b/src/smbios.c
@@ -17,7 +17,10 @@  smbios_entry_point_init(u16 max_structure_size,
                         u16 number_of_structures)
 {
     struct smbios_entry_point *ep = malloc_fseg(sizeof(*ep));
-    void *finaltable = malloc_high(structure_table_length);
+    void *finaltable = malloc_fseg(structure_table_length);
+    /* fall back to malloc_high() if the table is too big */
+    if (!finaltable)
+	finaltable = malloc_high(structure_table_length);
     if (!ep || !finaltable) {
         warn_noalloc();
         free(ep);
-- 
1.7.2.5