[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVM] Disallow soft resets in the BIOS.
# HG changeset patch # User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx> # Date 1173272832 0 # Node ID fbbf1f07fefe38807c21a4b8398dd1b5341a1260 # Parent dad3d143c3b0319ed6265a89879c3e11308b1c1f [HVM] Disallow soft resets in the BIOS. They aren't safe if the guest has brought up PV device drivers. Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx> --- tools/firmware/rombios/rombios.c | 102 ++++++++++++++++++++++++--------------- 1 files changed, 65 insertions(+), 37 deletions(-) diff -r dad3d143c3b0 -r fbbf1f07fefe tools/firmware/rombios/rombios.c --- a/tools/firmware/rombios/rombios.c Wed Mar 07 11:17:03 2007 +0000 +++ b/tools/firmware/rombios/rombios.c Wed Mar 07 13:07:12 2007 +0000 @@ -890,7 +890,7 @@ static void int15_function(); static void int15_function(); static void int16_function(); static void int17_function(); -static void int19_function(); +static void int18_function(); static void int1a_function(); static void int70_function(); static void int74_function(); @@ -1837,6 +1837,38 @@ keyboard_panic(status) } //-------------------------------------------------------------------------- +// machine_reset +//-------------------------------------------------------------------------- + void +machine_reset() +{ + /* Frob the keyboard reset line to reset the processor */ + outb(0x64, 0x60); /* Map the flags register at data port (0x60) */ + outb(0x60, 0x14); /* Set the flags to system|disable */ + outb(0x64, 0xfe); /* Pulse output 0 (system reset) low */ + BX_PANIC("Couldn't reset the machine\n"); +} + +//-------------------------------------------------------------------------- +// clobber_entry_point +// Because PV drivers in HVM guests detach some of the emulated devices, +// it is not safe to do a soft reboot by just dropping to real mode and +// jumping at ffff:0000. -- the boot drives might have disappeared! +// This rather foul function overwrites(!) the BIOS entry point +// to point at machine-reset, which will cause the Xen tools to +// rebuild the whole machine from scratch. +//-------------------------------------------------------------------------- + void +clobber_entry_point() +{ + /* The instruction at the entry point is one byte (0xea) for the + * jump opcode, then two bytes of address, then two of segment. + * Overwrite the address bytes.*/ + write_word(0xffff, 0x0001, machine_reset); +} + + +//-------------------------------------------------------------------------- // shutdown_status_panic // called when the shutdown statsu is not implemented, displays the status //-------------------------------------------------------------------------- @@ -7626,7 +7658,7 @@ int17_function(regs, ds, iret_addr) } void -int19_function(seq_nr) +int18_function(seq_nr) Bit16u seq_nr; { Bit16u ebda_seg=read_word(0x0040,0x000E); @@ -7702,8 +7734,8 @@ ASM_START push cx push dx - mov dl, _int19_function.bootdrv + 2[bp] - mov ax, _int19_function.bootseg + 2[bp] + mov dl, _int18_function.bootdrv + 2[bp] + mov ax, _int18_function.bootseg + 2[bp] mov es, ax ;; segment mov bx, #0x0000 ;; offset mov ah, #0x02 ;; function 2, read diskette sector @@ -7714,7 +7746,7 @@ ASM_START int #0x13 ;; read sector jnc int19_load_done mov ax, #0x0001 - mov _int19_function.status + 2[bp], ax + mov _int18_function.status + 2[bp], ax int19_load_done: pop dx @@ -7789,13 +7821,13 @@ ASM_START ;; Build an iret stack frame that will take us to the boot vector. ;; iret pops ip, then cs, then flags, so push them in the opposite order. pushf - mov ax, _int19_function.bootseg + 0[bp] + mov ax, _int18_function.bootseg + 0[bp] push ax - mov ax, _int19_function.bootip + 0[bp] + mov ax, _int18_function.bootip + 0[bp] push ax ;; Set the magic number in ax and the boot drive in dl. mov ax, #0xaa55 - mov dl, _int19_function.bootdrv + 0[bp] + mov dl, _int18_function.bootdrv + 0[bp] ;; Zero some of the other registers. xor bx, bx mov ds, bx @@ -8272,6 +8304,8 @@ int18_handler: ;; Boot Failure recovery: mov ss, ax ;; Get the boot sequence number out of the IPL memory + ;; The first time we do this it will have been set to -1 so + ;; we will start from device 0. mov bx, #IPL_SEG mov ds, bx ;; Set segment mov bx, IPL_SEQUENCE_OFFSET ;; BX is now the sequence number @@ -8279,43 +8313,33 @@ int18_handler: ;; Boot Failure recovery: mov IPL_SEQUENCE_OFFSET, bx ;; Write it back mov ds, ax ;; and reset the segment to zero. - ;; Carry on in the INT 19h handler, using the new sequence number + ;; Call the C code for the next boot device push bx - - jmp int19_next_boot + call _int18_function + + ;; Boot failed: invoke the boot recovery function... + int #0x18 ;---------- ;- INT19h - ;---------- int19_relocated: ;; Boot function, relocated - - ;; int19 was beginning to be really complex, so now it - ;; just calls a C function that does the work - - push bp - mov bp, sp - - ;; Reset SS and SP + ;; + ;; *** Warning: INT 19h resets the whole machine *** + ;; + ;; Because PV drivers in HVM guests detach some of the emulated devices, + ;; it is not safe to do a soft reboot by just dropping to real mode and + ;; invoking INT 19h -- the boot drives might have disappeared! + ;; If the user asks for a soft reboot, the only thing we can do is + ;; reset the whole machine. When it comes back up, the normal BIOS + ;; boot sequence will start, which is more or less the required behaviour. + ;; + ;; Reset SP and SS mov ax, #0xfffe mov sp, ax xor ax, ax mov ss, ax - - ;; Start from the first boot device (0, in AX) - mov bx, #IPL_SEG - mov ds, bx ;; Set segment to write to the IPL memory - mov IPL_SEQUENCE_OFFSET, ax ;; Save the sequence number - mov ds, ax ;; and reset the segment. - - push ax - -int19_next_boot: - - ;; Call the C code for the next boot device - call _int19_function - - ;; Boot failed: invoke the boot recovery function - int #0x18 + call _machine_reset ;---------- ;- INT1Ch - @@ -9609,6 +9633,8 @@ normal_post: call _log_bios_start + call _clobber_entry_point + ;; set all interrupts to default handler mov bx, #0x0000 ;; offset index mov cx, #0x0100 ;; counter (256 interrupts) @@ -9857,8 +9883,10 @@ post_default_ints: call _tcpa_calling_int19h /* specs: 8.2.3 step 1 */ call _tcpa_add_event_separators /* specs: 8.2.3 step 2 */ #endif - int #0x19 - //JMP_EP(0x0064) ; INT 19h location + + ;; Start the boot sequence. See the comments in int19_relocated + ;; for why we use INT 18h instead of INT 19h here. + int #0x18 #if BX_TCGBIOS call _tcpa_returned_int19h /* specs: 8.2.3 step 3/7 */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |