Linux kernel Hyper-V and Virtual-PC detection
Posted by momokuri on 2012 12月 02 in Linux
Recent kernel detect MS Hyper-V and use VMBUS technology for disk access.
It works fine on Hyper-V VMM but kernel mis-detect Virtual-PC on Windows 7.
Because there is not VMBUS technology in Virtual-PC, so kernel cannot find root disk and fails to boot.
Kernel should detect Virtual-PC than Hyper-V.
It is known that Hyper-V has a bios vendor name 'VRTUAL' now but it is easily changable.
Patch is as follows:
/drivers/ata/ata_piix.c
static int prefer_ms_hyperv = 1; module_param(prefer_ms_hyperv, int, 0); static void piix_ignore_devices_quirk(struct ata_host *host) { #if IS_ENABLED(CONFIG_HYPERV_STORAGE) static const struct dmi_system_id ignore_hyperv[] = { { /* On Hyper-V hypervisors the disks are exposed on * both the emulated SATA controller and on the * paravirtualised drivers. The CD/DVD devices * are only exposed on the emulated controller. * Request we ignore ATA devices on this host. */ .ident = "Hyper-V Virtual Machine", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), + /* DMI_MATCH(DMI_BIOS_VENDOR, "VRTUAL"), */ }, }, { } /* terminate list */ }; + static const struct dmi_system_id find_virtual_pc[] = { + { + .ident = "Microsoft Virtual-PC", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "Microsoft Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), + DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), + }, + }, + { } /* terminate list */ + }; const struct dmi_system_id *dmi = dmi_first_match(ignore_hyperv); if (dmi && prefer_ms_hyperv) { - host->flags |= ATA_HOST_IGNORE_ATA; - dev_info(host->dev, "%s detected, ATA device ignore set\n", - dmi->ident); + if (!dmi_first_match(find_virtual_pc)) { + host->flags |= ATA_HOST_IGNORE_ATA; + dev_info(host->dev, "%s detected, ATA device ignore set\n", + dmi->ident); + } } #endif }The patch is not tested and just a concept to fix problem. You can escape the problem with kernel option 'ata_piix.prefer_ms_hyperv=0'.
This entry was posted by momokuri and filed under Linux.