On Tue, Mar 5, 2019 at 2:33 PM Waldek Kozaczuk <[email protected]> wrote:

> Nadav,
>
> Thanks for reviewing the other patches
>

Thank you, for doing this work!


> . It looks like we are down to this single one to have full support of OSv
> on firecracker.
>

I committed this patch too, but something appears to have been broken with
the command line handling. For example:

$  scripts/build image=rogue
$ scripts/firecracker.py -v

/home/nyh/osv.tmp2/osv$ scripts/firecracker.py -c2 -V
2019-03-05T14:47:40.768877: Start
2019-03-05T14:47:40.771144: Firecracker ready
2019-03-05T14:47:40.773686: Configured VM
2019-03-05T14:47:40.775023: Added disk
2019-03-05T14:47:40.776185: Created OSv VM with cmdline: --verbose --nopci
/usr/games/rogue
2019-03-05T14:47:40.782907: Booted OSv VM
2019-03-05T14:47:40.782938: Waiting for firecracker process to terminate
OSv v0.52.0-48-g47ae2b65
2 CPUs detected
Firmware vendor: Unknown
bsd: initializing - done
VFS: mounting ramfs at /
VFS: mounting devfs at /dev
net: initializing - done
Detected virtio-mmio device: (2,0)
virtio-blk: Add blk device instances 0 as vblk0, devsize=0
random: intel drng, rdrand registered as a source.
random: <Software, Yarrow> initialized
VFS: unmounting /dev
VFS: mounting rofs at /rofs
failed to mount /rofs, error = No error information
VFS: mounting zfs at /zfs
zfs: mounting osv/zfs from device /dev/vblk0.1
VFS: mounting devfs at /dev
VFS: mounting procfs at /proc
program zpool.so returned 1
BSD shrinker: event handler list found: 0xffffa00000f16f00
    BSD shrinker found: 1
BSD shrinker: unlocked, running
2019-03-05T14:47:40.839064594 [anonymous-instance:WARN:vmm/src/lib.rs:1080]
Guest-boot-time =  62091 us 62 ms,  69244 CPU us 69 CPU ms
*root=/dev/vda: No such file or directory*
program exited with status 1
VFS: unmounting /dev
VFS: unmounting /proc
VFS: unmounting /
Powering off.
2019-03-05T14:47:40.848183837 [anonymous-instance:ERROR:vmm/src/lib.rs:1320]
Failed to log metrics while stopping: Logger was not initialized.
2019-03-05T14:47:40.862006: End


I don't where this message comes from, I am guessing that something got
broken in the command line and OSv tried to run the string "root=/dev/vda"
as the command line instead of the desired command line (/usr/games/rogue)?
Using build fs=ramfs does not help, so it seems the new virtio stuff is
working, just something in the command line got broken?


> Waldek
>
> On Saturday, March 2, 2019 at 1:30:52 AM UTC-5, Waldek Kozaczuk wrote:
>>
>> Adds logic to parse information about CPUs on
>> system where ACPI is not available. It does it
>> by parsing so called MP table. If MP table
>> not found assumes single vCPU.
>>
>> Signed-off-by: Waldemar Kozaczuk <[email protected]>
>> ---
>>  arch/x64/smp.cc | 125 ++++++++++++++++++++++++++++++++++++++++++------
>>  1 file changed, 111 insertions(+), 14 deletions(-)
>>
>> diff --git a/arch/x64/smp.cc b/arch/x64/smp.cc
>> index 2869d6e2..3386bd90 100644
>> --- a/arch/x64/smp.cc
>> +++ b/arch/x64/smp.cc
>> @@ -39,6 +39,16 @@ volatile unsigned smp_processors = 1;
>>
>>  using boost::intrusive::get_parent_from_member;
>>
>> +static void register_cpu(unsigned cpu_id, u32 apic_id, u32 acpi_id = 0)
>> +{
>> +    auto c = new sched::cpu(cpu_id);
>> +    c->arch.apic_id = apic_id;
>> +    c->arch.acpi_id = acpi_id;
>> +    c->arch.initstack.next = smp_stack_free;
>> +    smp_stack_free = &c->arch.initstack;
>> +    sched::cpus.push_back(c);
>> +}
>> +
>>  void parse_madt()
>>  {
>>      char madt_sig[] = ACPI_SIG_MADT;
>> @@ -57,12 +67,7 @@ void parse_madt()
>>              if (!(lapic->LapicFlags & ACPI_MADT_ENABLED)) {
>>                  break;
>>              }
>> -            auto c = new sched::cpu(nr_cpus++);
>> -            c->arch.apic_id = lapic->Id;
>> -            c->arch.acpi_id = lapic->ProcessorId;
>> -            c->arch.initstack.next = smp_stack_free;
>> -            smp_stack_free = &c->arch.initstack;
>> -            sched::cpus.push_back(c);
>> +            register_cpu(nr_cpus++, lapic->Id, lapic->ProcessorId);
>>              break;
>>          }
>>          default:
>> @@ -73,16 +78,108 @@ void parse_madt()
>>      debug(fmt("%d CPUs detected\n") % nr_cpus);
>>  }
>>
>> +#define MPF_IDENTIFIER (('_'<<24) | ('P'<<16) | ('M'<<8) | '_')
>> +struct mpf_structure {
>> +    char signature[4];
>> +    uint32_t configuration_table;
>> +    uint8_t length;    // In 16 bytes (e.g. 1 = 16 bytes, 2 = 32 bytes)
>> +    uint8_t specification_revision;
>> +    uint8_t checksum;  // This value should make all bytes in the table
>> equal 0 when added together
>> +    uint8_t default_configuration; // If this is not zero then
>> configuration_table should be
>> +                                   // ignored and a default
>> configuration should be loaded instead
>> +    uint32_t features; // If bit 7 is then the IMCR is present and PIC
>> mode is being used, otherwise
>> +                       // virtual wire mode is; all other bits are
>> reserved
>> +} __attribute__((packed));
>> +
>> +#define MP_TABLE_IDENTIFIER (('P'<<24) | ('M'<<16) | ('C'<<8) | 'P')
>> +struct mp_table {
>> +    char signature[4]; // "PCMP"
>> +    uint16_t length;
>> +    uint8_t mp_specification_revision;
>> +    uint8_t checksum;  // Again, the byte should be all bytes in the
>> table add up to 0
>> +    char oem_id[8];
>> +    char product_id[12];
>> +    uint32_t oem_table;
>> +    uint16_t oem_table_size;
>> +    uint16_t entry_count;   // This value represents how many entries
>> are following this table
>> +    uint32_t lapic_address; // This is the memory mapped address of the
>> local APICs
>> +    uint16_t extended_table_length;
>> +    uint8_t extended_table_checksum;
>> +    uint8_t reserved;
>> +} __attribute__((packed));
>> +
>> +struct mp_processor {
>> +    uint8_t type;  // Always 0
>> +    uint8_t local_apic_id;
>> +    uint8_t local_apic_version;
>> +    uint8_t flags; // If bit 0 is clear then the processor must be
>> ignored
>> +                   // If bit 1 is set then the processor is the
>> bootstrap processor
>> +    uint32_t signature;
>> +    uint32_t feature_flags;
>> +    uint64_t reserved;
>> +} __attribute__((packed));
>> +
>> +static mp_table *find_mp_table(unsigned long base, long length)
>> +{
>> +    // First find MP floating pointer structure in the physical memory
>> +    // region specified by the base and length
>> +    void *addr = mmu::phys_to_virt(base);
>> +    while (length > 0) {
>> +       if (*static_cast<uint32_t *>(addr) == MPF_IDENTIFIER) {
>> +           // We found the MP floating pointer structure
>> +           auto mpf_struct = static_cast<mpf_structure*>(addr);
>> +           // Now let us dereference physical address of MP table
>> itself,
>> +           // check signature and return its virtual address
>> +           void *mp_table_addr =
>> mmu::phys_to_virt(mpf_struct->configuration_table);
>> +           if (*static_cast<uint32_t *>(mp_table_addr) ==
>> MP_TABLE_IDENTIFIER) {
>> +               return static_cast<mp_table*>(mp_table_addr);
>> +           }
>> +           else {
>> +               return nullptr;
>> +           }
>> +       }
>> +
>> +       addr += 16;
>> +       length -= 16;
>> +    }
>> +    return nullptr;
>> +}
>> +
>> +#define LAST_KB_IN_BASE_MEMORY_ADDR  639 * 0x400
>> +#define FIRST_KB_IN_BASE_MEMORY_ADDR 0x0
>> +#define NON_PROCESSOR_ENTRY_SIZE     8
>>  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);
>> +    // Parse information about all vCPUs from MP table. For details
>> please see
>> +    //
>> https://wiki.osdev.org/Symmetric_Multiprocessing#Finding_information_using_MP_Table
>> +    // or
>> http://www.osdever.net/tutorials/view/multiprocessing-support-for-hobby-oses-explained
>> +    mp_table *table = find_mp_table(LAST_KB_IN_BASE_MEMORY_ADDR, 0x400);
>> +    if (!table) {
>> +        table = find_mp_table(FIRST_KB_IN_BASE_MEMORY_ADDR, 0x400);
>> +    }
>> +
>> +    unsigned nr_cpus = 0;
>> +    if (table) {
>> +        void *mp_entries = static_cast<void*>(table) + sizeof(mp_table);
>> +        int entries_size = table->length - sizeof(mp_table);
>> +
>> +        while (entries_size > 0) {
>> +            int entry_size = NON_PROCESSOR_ENTRY_SIZE;
>> +            auto proc_desc = static_cast<mp_processor*>(mp_entries);
>> +            if (proc_desc->type == 0) {
>> +                register_cpu(nr_cpus++, proc_desc->local_apic_id);
>> +                entry_size = sizeof(mp_processor);
>> +            }
>> +            entries_size -= entry_size;
>> +            mp_entries += entry_size;
>> +        }
>> +    }
>> +
>> +    if (!nr_cpus) { // No MP table was found or no cpu was found in
>> there -> assume uni-processor
>> +        register_cpu(nr_cpus++, 0);
>> +    }
>> +
>> +    debug(fmt("%d CPUs detected\n") % nr_cpus);
>>  }
>>
>>  void smp_init()
>> --
>> 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