On Fri, Feb 22, 2019 at 4:13 PM Waldemar Kozaczuk <[email protected]>
wrote:

> This patch makes OSv boot without requiring ACPI
> to be present which for example is the case on firecracker.
>
> We simply treat failure to find ACPI root pointer
> as an indicator that ACPI is not available and
> mark it off as such. Also if ACPI is off we power OSv off
> using non-ACPI method and skip probing panic driver as it
> relies on ACPI as well.
>
> Lastly we skip MADT table parsing if APCI is off and
> for now assume there is single vCPU only. Eventually
> we should parse vCPU information from MP table as
> an alternative.
>
> Signed-off-by: Waldemar Kozaczuk <[email protected]>
> ---
>  arch/x64/power.cc  | 30 +++++++++++++++++++++---------
>  arch/x64/smp.cc    | 20 +++++++++++++++++++-
>  drivers/acpi.cc    | 19 +++++++++++++++++++
>  drivers/acpi.hh    |  1 +
>  drivers/pvpanic.cc |  4 ++++
>  5 files changed, 64 insertions(+), 10 deletions(-)
>
> diff --git a/arch/x64/power.cc b/arch/x64/power.cc
> index 81849335..61d56bcc 100644
> --- a/arch/x64/power.cc
> +++ b/arch/x64/power.cc
> @@ -15,6 +15,8 @@ extern "C" {
>  #include "acpi.h"
>  }
>
> +#include <drivers/acpi.hh>
> +
>  namespace osv {
>
>  void halt(void)
> @@ -27,15 +29,25 @@ void halt(void)
>
>  void poweroff(void)
>  {
> -    ACPI_STATUS status = AcpiEnterSleepStatePrep(ACPI_STATE_S5);
> -    if (ACPI_FAILURE(status)) {
> -        debug("AcpiEnterSleepStatePrep failed: %s\n",
> AcpiFormatException(status));
> -        halt();
> -    }
> -    status = AcpiEnterSleepState(ACPI_STATE_S5);
> -    if (ACPI_FAILURE(status)) {
> -        debug("AcpiEnterSleepState failed: %s\n",
> AcpiFormatException(status));
> -        halt();
> +    if (acpi::is_enabled()) {
> +        ACPI_STATUS status = AcpiEnterSleepStatePrep(ACPI_STATE_S5);
> +        if (ACPI_FAILURE(status)) {
> +            debug("AcpiEnterSleepStatePrep failed: %s\n",
> AcpiFormatException(status));
> +            halt();
> +        }
> +        status = AcpiEnterSleepState(ACPI_STATE_S5);
> +        if (ACPI_FAILURE(status)) {
> +            debug("AcpiEnterSleepState failed: %s\n",
> AcpiFormatException(status));
> +            halt();
> +        }
> +    } else {
> +        // On hypervisors that do not support ACPI like firecracker we
> +        // resort to a reset using the 8042 PS/2 Controller ("keyboard
> controller")
> +        // as a way to shutdown the VM
> +        //TODO: Figure out if there is another method we could try
> +        // first to to power off on non-firecracker platforms
> +        // without using ACPI
> +        processor::outb(0xfe, 0x64);
>

I'll commit this patch for now, but I'm guessing this will have to change
later. The firecracker guys don't seem to love this behavior either:
https://github.com/firecracker-microvm/firecracker/issues/598


>      }
>
>      // We shouldn't get here on x86.
> diff --git a/arch/x64/smp.cc b/arch/x64/smp.cc
> index 073ef206..2869d6e2 100644
> --- a/arch/x64/smp.cc
> +++ b/arch/x64/smp.cc
> @@ -15,6 +15,7 @@
>  extern "C" {
>  #include "acpi.h"
>  }
> +#include <drivers/acpi.hh>
>  #include <boost/intrusive/parent_from_member.hpp>
>  #include <osv/debug.hh>
>  #include <osv/sched.hh>
> @@ -72,9 +73,26 @@ void parse_madt()
>      debug(fmt("%d CPUs detected\n") % nr_cpus);
>  }
>
> +void parse_mp_table()
> +{
> +    //TODO: This a nasty hack to support single vCPU. Eventually we should
> +    // parse out equivalent information about all vCPUs from MP table. For
> +    // details please see
> https://wiki.osdev.org/Symmetric_Multiprocessing#Finding_information_using_MP_Table
> +    auto c = new sched::cpu(0);
> +    c->arch.apic_id = 0;
> +    c->arch.initstack.next = smp_stack_free;
> +    smp_stack_free = &c->arch.initstack;
> +    sched::cpus.push_back(c);
> +}
> +
>  void smp_init()
>  {
> -    parse_madt();
> +    if (acpi::is_enabled()) {
> +        parse_madt();
> +    } else {
> +        parse_mp_table();
> +    }
> +
>      sched::current_cpu = sched::cpus[0];
>      for (auto c : sched::cpus) {
>          c->incoming_wakeups =
> aligned_array_new<sched::cpu::incoming_wakeup_queue>(sched::cpus.size());
> diff --git a/drivers/acpi.cc b/drivers/acpi.cc
> index 506ca68f..4a38a32e 100644
> --- a/drivers/acpi.cc
> +++ b/drivers/acpi.cc
> @@ -539,8 +539,21 @@ namespace acpi {
>
>  static ACPI_TABLE_DESC TableArray[ACPI_MAX_INIT_TABLES];
>
> +static bool enabled = false;
> +
> +bool is_enabled() {
> +    return enabled;
> +}
> +
>  void early_init()
>  {
> +    ACPI_SIZE rsdp;
> +    auto st = AcpiFindRootPointer(&rsdp);
> +    if (ACPI_FAILURE(st)) {
> +        acpi_w("Warning: Failed to find ACPI root pointer!\n");
> +        return;
> +    }
> +
>      ACPI_STATUS status;
>
>      status = AcpiInitializeTables(TableArray, ACPI_MAX_INIT_TABLES, TRUE);
> @@ -569,6 +582,8 @@ void early_init()
>          acpi_e("AcpiLoadTables failed: %s\n",
> AcpiFormatException(status));
>          return;
>      }
> +
> +    enabled = true;
>  }
>
>  UINT32 acpi_poweroff(void *unused)
> @@ -581,6 +596,10 @@ UINT32 acpi_poweroff(void *unused)
>  // The following function comes from the documentation example page 262
>  void init()
>  {
> +    if (!enabled) {
> +        return;
> +    }
> +
>      ACPI_STATUS status;
>
>
> diff --git a/drivers/acpi.hh b/drivers/acpi.hh
> index 8373745b..10f82f58 100644
> --- a/drivers/acpi.hh
> +++ b/drivers/acpi.hh
> @@ -12,6 +12,7 @@
>  namespace acpi {
>
>  void init();
> +bool is_enabled();
>
>  }
>
> diff --git a/drivers/pvpanic.cc b/drivers/pvpanic.cc
> index 2f114fb3..e643b5a0 100644
> --- a/drivers/pvpanic.cc
> +++ b/drivers/pvpanic.cc
> @@ -21,6 +21,10 @@ static u32 port;
>
>  void probe_and_setup()
>  {
> +    if (!acpi::is_enabled()) {
> +        return;
> +    }
> +
>      ACPI_BUFFER results;
>      ACPI_OBJECT obj;
>      ACPI_STATUS status;
> --
> 2.19.1
>
> --
> 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].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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].
For more options, visit https://groups.google.com/d/optout.

Reply via email to