On Sat, Nov 28, 2015 at 07:12:47AM +0000, Xulei (Stone) wrote:
Hi, Recently, i use a script to continuously reset a VM and i found my VM frequently halts at "Attempting to allocate VGA stack via pmm call". After analyzing, i think it may be a problem of SeaBIOS.
From the log(attached below), we can see handle_post() executes twice and this makes the destination address of "Relocating init" change when the 2nd reset command comes. This also influences on the source address of "Copying MPTABLE". At last, the VM will be stuck at attempting to allocate VGA stack via pmm call.
Could you offer me a solution to fix this problem?
==============bad SeaBIOS log====== SeaBIOS (version rel-1.8.1-0-g4adadbd-20151127_220019-UVP) No Xen hypervisor found. Running on QEMU (i440fx) Running on KVM RamSize: 0xc0000000 [cmos] Now vcpu cpu_id = 0 Relocating init from 0x000dbb30 to 0xbffad2c0 (size 76928) Found QEMU fw_cfg SeaBIOS (version rel-1.8.1-0-g4adadbd-20151127_220019-UVP) <<========= handle_post() execute again?
If seabios resets before it sets HaveRunPost then it probably wont work well, as it will rerun the POST code without resetting the global variables it has modified.
Unfortunately, it's not clear to me that we can simply move the setting of HaveRunPost to an earlier point, as the handle_resume() code would need to be audited to ensure it can run even if POST hasn't completed.
I move HaveRunPost = 1 in the very early point of POST phase (begin at handle_post()), so that when the 2nd reset comes, HaveRunPost is already 1 which makes entry_post jmps to handle_resume() instead of handle_post(). As we know, handle_resume() will reset all global variables.
Can you tell me is this solution ok? or, does this have some side effects?
Sorry, i've tested and this seems not work. Let HaveRunPost = 1 at begin of handle_post(), will lead the VM to loop forever in the resume phase. It seems the memcpy() in qemu_prep_reset()can not clear HaveRunPost at this time.
Ah! I'm confused! I don't know where is the right place to let HaveRunPost = 1?
I move HaveRunPost = 1 to handle_post() (after make_bios_writable()), and I have tested for 1 day with continuously resetting, it seems works well! Does following patch have some side effects?
f65091856d257f2c232263ac4bbc29457f356efe src/post.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/post.c b/src/post.c index 49c22b8..f381385 100644 --- a/src/post.c +++ b/src/post.c @@ -41,9 +41,7 @@ ivt_init(void) { dprintf(3, "init ivt\n");
- // Setup reset-vector entry point (controls legacy reboots). - HaveRunPost = 1; - rtc_write(CMOS_RESET_CODE, 0);
// Initialize all vectors to the default handler. int i; @@ -335,6 +333,10 @@ handle_post(void) // Allow writes to modify bios area (0xf0000) make_bios_writable();
+ // Setup reset-vector entry point (controls legacy reboots). + HaveRunPost = 1; + rtc_write(CMOS_RESET_CODE, 0); + // Now that memory is read/writable - start post process. dopost(); }
So, it looks like a fix for this will take some further analysis.
-Kevin