From patchwork Mon Mar 23 19:11:05 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Williamson X-Patchwork-Id: 13811 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n2NJC7sT028021 for ; Mon, 23 Mar 2009 19:12:08 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759343AbZCWTLW (ORCPT ); Mon, 23 Mar 2009 15:11:22 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1757660AbZCWTLW (ORCPT ); Mon, 23 Mar 2009 15:11:22 -0400 Received: from g4t0016.houston.hp.com ([15.201.24.19]:12291 "EHLO g4t0016.houston.hp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759287AbZCWTLV (ORCPT ); Mon, 23 Mar 2009 15:11:21 -0400 Received: from g5t0029.atlanta.hp.com (g5t0029.atlanta.hp.com [16.228.8.141]) by g4t0016.houston.hp.com (Postfix) with ESMTP id 9820E1420A; Mon, 23 Mar 2009 19:11:19 +0000 (UTC) Received: from ldl.fc.hp.com (ldl.fc.hp.com [15.11.146.30]) by g5t0029.atlanta.hp.com (Postfix) with ESMTP id 5D8DA10028; Mon, 23 Mar 2009 19:11:19 +0000 (UTC) Received: from localhost (ldl.fc.hp.com [127.0.0.1]) by ldl.fc.hp.com (Postfix) with ESMTP id 08AEE39C071; Mon, 23 Mar 2009 13:11:19 -0600 (MDT) X-Virus-Scanned: Debian amavisd-new at ldl.fc.hp.com Received: from ldl.fc.hp.com ([127.0.0.1]) by localhost (ldl.fc.hp.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id aFpJmzk+etvd; Mon, 23 Mar 2009 13:11:16 -0600 (MDT) Received: from [10.91.73.10] (lart.fc.hp.com [15.11.146.31]) by ldl.fc.hp.com (Postfix) with ESMTP id 9015739C007; Mon, 23 Mar 2009 13:11:16 -0600 (MDT) Subject: [PATCH 1/2] qemu: Allow SMBIOS entries to be loaded and provided to the VM BIOS From: Alex Williamson To: qemu-devel Cc: kvm , Alex Williamson In-Reply-To: <1237835133.7276.1107.camel@lappy> References: <1237835133.7276.1107.camel@lappy> Organization: OSLO R&D Date: Mon, 23 Mar 2009 13:11:05 -0600 Message-Id: <1237835465.15558.4.camel@lappy> Mime-Version: 1.0 X-Mailer: Evolution 2.24.3 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Create a new -smbios options that takes binary SMBIOS entries to provide to the VM BIOS. The binary can be easily generated using something like: dmidecode -t 1 -u | grep $'^\t\t[^"]' | xargs -n1 | \ perl -lne 'printf "%c", hex($_)' > smbios_type_1.bin For some inventory tools, this makes the VM report the system information for the host. One entry per binary file, multiple files can be chained together as: -smbios file1,file2,... or specified independently: -smbios file1 -smbios file2 Signed-off-by: Alex Williamson --- -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/hw/acpi.c b/hw/acpi.c index 52f50a0..0bd93bf 100644 --- a/hw/acpi.c +++ b/hw/acpi.c @@ -915,3 +915,69 @@ out: } return -1; } + +char *smbios_entries; +size_t smbios_entries_len; + +int smbios_entry_add(const char *t) +{ + struct stat s; + char file[1024], *p, *f, *n; + int fd, r; + size_t len, off; + + f = (char *)t; + do { + n = strchr(f, ','); + if (n) { + strncpy(file, f, (n - f)); + file[n - f] = '\0'; + f = n + 1; + } else { + strcpy(file, f); + f += strlen(file); + } + + fd = open(file, O_RDONLY); + if (fd < 0) + return -1; + + if (fstat(fd, &s) < 0) { + close(fd); + return -1; + } + + if (!smbios_entries) { + smbios_entries_len = sizeof(uint16_t); + smbios_entries = qemu_mallocz(smbios_entries_len); + } + + len = s.st_size; + smbios_entries = qemu_realloc(smbios_entries, smbios_entries_len + + len + sizeof(uint16_t)); + p = smbios_entries + smbios_entries_len; + + *(uint16_t *)p = cpu_to_le32(len); + p += sizeof(uint16_t); + + off = 0; + do { + r = read(fd, p + off, len); + if (r > 0) { + off += r; + len -= r; + } else if ((r < 0 && errno != EINTR) || r == 0) { + close(fd); + return -1; + } + } while (len); + + close(fd); + + smbios_entries_len += s.st_size + sizeof(uint16_t); + (*(uint16_t *)smbios_entries) = + cpu_to_le32(le32_to_cpu(*(uint16_t *)smbios_entries) + 1); + } while (*f); + + return 0; +} diff --git a/hw/pc.c b/hw/pc.c index 69f25f3..ec65e33 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -51,6 +51,7 @@ #define ACPI_DATA_SIZE 0x10000 #define BIOS_CFG_IOPORT 0x510 #define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0) +#define FW_CFG_SMBIOS_ENTRIES (FW_CFG_ARCH_LOCAL + 1) #define MAX_IDE_BUS 2 @@ -442,6 +443,8 @@ static void bochs_bios_init(void) fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES, (uint8_t *)acpi_tables, acpi_tables_len); + fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES, (uint8_t *)smbios_entries, + smbios_entries_len); } /* Generate an initial boot sector which sets state and jump to diff --git a/hw/pc.h b/hw/pc.h index 5b378d4..6c200b3 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -106,12 +106,15 @@ int ioport_get_a20(void); extern int acpi_enabled; extern char *acpi_tables; extern size_t acpi_tables_len; +extern char *smbios_entries; +extern size_t smbios_entries_len; i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, qemu_irq sci_irq); void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr); void acpi_bios_init(void); int acpi_table_add(const char *table_desc); +int smbios_entry_add(const char *smbios_entry); /* hpet.c */ extern int no_hpet; diff --git a/vl.c b/vl.c index b62a2d4..372b83c 100644 --- a/vl.c +++ b/vl.c @@ -4061,6 +4061,7 @@ static void help(int exitcode) "-no-hpet disable HPET\n" "-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,data=file1[:file2]...]\n" " ACPI table description\n" + "-smbios file1[,file2] SMBIOS entry\n" #endif "Linux boot specific:\n" "-kernel bzImage use 'bzImage' as kernel image\n" @@ -4201,6 +4202,7 @@ enum { QEMU_OPTION_no_acpi, QEMU_OPTION_no_hpet, QEMU_OPTION_acpitable, + QEMU_OPTION_smbios, /* Linux boot specific: */ QEMU_OPTION_kernel, @@ -4322,6 +4324,7 @@ static const QEMUOption qemu_options[] = { { "no-acpi", 0, QEMU_OPTION_no_acpi }, { "no-hpet", 0, QEMU_OPTION_no_hpet }, { "acpitable", HAS_ARG, QEMU_OPTION_acpitable }, + { "smbios", HAS_ARG, QEMU_OPTION_smbios }, #endif /* Linux boot specific: */ @@ -5152,6 +5155,12 @@ int main(int argc, char **argv, char **envp) exit(1); } break; + case QEMU_OPTION_smbios: + if(smbios_entry_add(optarg) < 0) { + fprintf(stderr, "Wrong smbios provided\n"); + exit(1); + } + break; #endif #ifdef USE_KQEMU case QEMU_OPTION_no_kqemu: