Thanks for the comment :) Please see my reply in the comments.

On 27.11.19 15:43, Nadav Har'El wrote:
Hi, thanks for the patch! I have some questions:

On Wed, Nov 27, 2019 at 3:46 PM 'YuChen Qian' via OSv Development <[email protected] <mailto:[email protected]>> wrote:

    The original keyboard reset does not wait a for short period, so
    we see
    the triple fault being triggered even if the keyboard reset is
    successful sometimes. Added a wait there to make sure the keyboard
    reset
    completes before triggering the triple fault.


Out of curiosity, what is the downside of not waiting, and trying another reboot method even if the previous one will have eventually worked?
Isn't the end-result the same - that it will reboot?
Is the risk that the machine will reboot for a second time right after the first one?
The end result will be the same, but it is generally better to wait for a little while and make sure the keyboard reset actually worked. We see triple faults being triggered randomly even when the keyboard reset works. Linux kernel also waits a little (arch/x86/kernel/reboot.c).


    Added PCI reset, and enabled ACPI reset. ACPI reset does not work
    currently on kvm and qemu, but nevertheless we should try it first.

    Signed-off-by: YuChen Qian <[email protected]
    <mailto:[email protected]>>
    Reviewed-by: Hendrik Borghorst <[email protected]
    <mailto:[email protected]>>
    Reviewed-by: Marius Hillenbrand <[email protected]
    <mailto:[email protected]>>
    Cc-Team: kaos-brimstone <[email protected]
    <mailto:[email protected]>>

    CR: https://code.amazon.com/reviews/CR-14659421
    ---
     arch/x64/power.cc | 30 +++++++++++++++++++++++-------
     1 file changed, 23 insertions(+), 7 deletions(-)

    diff --git a/arch/x64/power.cc b/arch/x64/power.cc
    index 61d56bcc..d62ed84e 100644
    --- a/arch/x64/power.cc
    +++ b/arch/x64/power.cc
    @@ -54,16 +54,32 @@ void poweroff(void)
         halt();
     }

    +void pci_reboot(void) {


Please make these functions "static", so they are not visible from outside this source file (there is no reason why they should be).
Thanks for pointing that out :) I will submit a new patch.

    +    u8 v = processor::inb(0x0cf9) & ~6;
    +    processor::outb(v|2, 0x0cf9); // request hard reset
    +    usleep(50);
    +    processor::outb(v|6, 0x0cf9); // actually do the reset

    +    usleep(50);


Nice, I wasn't familiar with this method before.

Is it really necessary to write 0x2 once, wait, and then write 0x2 | 0x4 ("6") in a second write? Won't a single write of 6 - once - work, as the (virtual) hardware realizes that both 0x4 (do a reset) and 0x2 (make it a hardware reset) bits are turned on?
I think, it is better to look at the Intel spec for this question. The reset control register is located at offset CF9h. Bit 0 is reserved, bit 1 is used for system reset (SYS_RST), bit 2 is used for reset cpu (RST_CPU), bit 3 is used for full reset (FULL_RST), and bit4-7 are also reserved.

"If SYS_RST is 0 when RST_CPU goes from 0 to 1, then the PMC will force INIT# active for 16 PCI clocks. /If SYS_RST is 1 when RST_CPU goes from 0 to 1, then the PMC will force PCI reset active for about 1 ms, however the PMU_SLP_S3_B and PMU_SLP_S4_B signals assertion is dependent on the value of the FULL_RST./

The RST_CPU bit will cause either a hard or soft reset to the CPU depending on the state of the SYS_RST The software will cause the reset by setting bit 2 from a 0 to a 1."

In other words, we need to first set the SYS_RST to 1, and then set the RST_CPU to 1 (which forces a hard reset). The wait probably matters more on real hardware.

Linux also implemented this reset method similarly, in arch/x86/kernel/reboot.c


    +}
    +
    +void kbd_reboot(void) {
    +    while (processor::inb(0x64) & 0x02); // clear all keyboard
    buffers
    +    processor::outb(0xfe, 0x64);
    +    usleep(50);
    +}
    +
     void reboot(void)
     {
    -    // It would be nice if AcpiReset() worked, but it doesn't
    seem to work
    -    // (on qemu & kvm), so let's resort to other techniques,
    which appear
    -    // to work. Hopefully one of them will work on any hypervisor.
    -    // Method 1: "fast reset" via System Control Port A (port 0x92)
    -    processor::outb(1, 0x92);
    +    // Method 1: AcpiReset, does not work on qemu or kvm now
    because the reset
    +    // register is not supported. Nevertheless, we should try it
    first
    +    AcpiReset();
         // Method 2: Reset using the 8042 PS/2 Controller ("keyboard
    controller")
    -    processor::outb(0xfe, 0x64);
    -    // Method 3: Cause triple fault by loading a broken IDT and
    triggering an
    +    kbd_reboot();
    +    // Method 3: PCI reboot
    +    pci_reboot();
    +    // Method 4: "fast reset" via System Control Port A (port 0x92)
    +    processor::outb(1, 0x92);


I'm curious why you moved this, which was the first method we tried until now, to be the fourth. What's
the downside of doing it first?
Yes, there is no downside. I will submit a new patch with the original order.


    +    // Method 5: Cause triple fault by loading a broken IDT and
    triggering an
         // interrupt.
         processor::lidt(processor::desc_ptr(0, 0));
         __asm__ __volatile__("int3");
-- 2.17.1




    Amazon Development Center Germany GmbH
    Krausenstr. 38
    10117 Berlin
    Geschaeftsfuehrung: Christian Schlaeger, Ralf Herbrich
    Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
    Sitz: Berlin
    Ust-ID: DE 289 237 879



-- You received this message because you are subscribed to the Google
    Groups "OSv Development" group.
    To unsubscribe from this group and stop receiving emails from it,
    send an email to [email protected]
    <mailto:osv-dev%[email protected]>.
    To view this discussion on the web visit
    
https://groups.google.com/d/msgid/osv-dev/20191127134607.15293-1-yuchenq%40amazon.de.


--
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/c395dc69-cc94-42aa-9527-76c019978829%40amazon.com.

Reply via email to