SMBIOS OEM type numbers to pass-through can be provided through a new config file option -
smbios-oem-types-pt which takes a comma seperated list of OEM type numbers.
return add;
}
-static int decode_smbios_structures(struct smstructs_info *smstructs, struct hvm_sminfo_table *va_sm, int is_dmtf)
+static uint8_t is_oem_type_pt_requested(uint8_t oem_type_to_check, uint8_t *oem_types, uint8_t oem_types_count)
+{
+ uint8_t count;
+
+ for ( count = 0; count < oem_types_count; count++ ) {
+ if ( oem_type_to_check == oem_types[count] )
+ return 1;
+ }
+
+ return 0;
+}
+
+static int decode_smbios_structures(struct smstructs_info *smstructs, struct hvm_sminfo_table *va_sm,
+ uint8_t *oem_types, uint8_t oem_types_count)
{
uint16_t idx;
uint8_t *ptr = smstructs->addr;
tail += 2;
/* is this one we care about? - DMTF defined or vendor specific */
- if (is_dmtf) {
- switch (ptr[SMBIOS_STRUCT_TYPE]) {
- case SMBIOS_TYPE_BIOS_INF0:
- case SMBIOS_TYPE_SYSTEM_INFO:
- case SMBIOS_TYPE_ENCLOSURE:
- case SMBIOS_TYPE_OEM_STRINGS:
- /* copy over the table - if we run out of room we will just take what we have */
- copied = copy_smbios_structure(va_sm, ptr, tail - ptr);
- if (copied == 0) {
- return 0;
- }
- /* TODO: in the future may want other DMTF structures Portable Battery (type 22) or System
- Power Supply (type 39) */
- break;
- default:
- break;
+ switch (ptr[SMBIOS_STRUCT_TYPE]) {
+ case SMBIOS_TYPE_BIOS_INF0:
+ case SMBIOS_TYPE_SYSTEM_INFO:
+ case SMBIOS_TYPE_ENCLOSURE:
+ case SMBIOS_TYPE_OEM_STRINGS:
+ /* copy over the table - if we run out of room we will just take what we have */
+ copied = copy_smbios_structure(va_sm, ptr, tail - ptr);
+ if (copied == 0) {
+ return 0;
}
- }
- else {
- /* TODO: in the future may want to load the vendor specific tables (range 128 - 255) here */
+ /* TODO: in the future may want other DMTF structures Portable Battery (type 22) or System
+ Power Supply (type 39) */
+ break;
+ case SMBIOS_TYPE_VENDOR_MIN ... SMBIOS_TYPE_VENDOR_MAX:
+ if ( is_oem_type_pt_requested(ptr[SMBIOS_STRUCT_TYPE], oem_types, oem_types_count) > 0 ) {
+ copied = copy_smbios_structure(va_sm, ptr, tail - ptr);
+ if (copied == 0) {
+ return 0;
+ }
+ }
+ break;
+ default:
+ break;
}
/* test for terminating structure */
return 0;
}
-int hvm_smbios_decode(struct hvm_sminfo_table *va_sm)
+static uint8_t parse_smbios_oem_types(char *smbios_oem_types, uint8_t *oem_types, uint8_t oem_types_count)
+{
+ uint8_t count = 0;
+ uint32_t oem_type_num;
+ char *token = NULL;
+ char *str = strdup(smbios_oem_types);
+
+ if ( str == NULL )
+ return 0;
+
+ token = strtok(str, ",");
+ while ( token != NULL ) {
+ oem_type_num = strtoull(token, NULL, 10);
+ if ( oem_type_num >= SMBIOS_TYPE_VENDOR_MIN && oem_type_num <= SMBIOS_TYPE_VENDOR_MAX ) {
+ if ( oem_types_count <= count ) {
+ XG_LOG("SMBIOS OEM types string too long!\n");
+ free(str);
+ return 0;
+ }
+ if ( is_oem_type_pt_requested(oem_type_num, oem_types, count) == 0 ) {
+ oem_types[count] = (uint8_t)oem_type_num;
+ count++;
+ }
+ }
+ token = strtok(NULL, ",");
+ }
+
+ free(str);
+ return count;
+}
+
+static uint8_t copy_smbios_oem_types_pt_info(struct hvm_sminfo_table *va_sm, uint8_t *oem_types, uint8_t oem_types_count)
+{
+ uint8_t *location;
+ uint32_t size = oem_types_count * sizeof(uint8_t);
+
+ location = (uint8_t*)va_sm + sizeof(struct hvm_sminfo_table) + va_sm->total_length;
+ ((struct hvm_smoem_types_header*)location)->sm_oem_types_length = size;
+ location += sizeof(struct hvm_smoem_types_header);
+ memcpy(location, oem_types, size);
+
+ va_sm->total_length += sizeof(struct hvm_smoem_types_header) + size;
+ return 0;
+}
+
+int hvm_smbios_decode(struct hvm_sminfo_table *va_sm, char *smbios_oem_types)
{
struct smstructs_info smstructs;
uint32_t count, length;
uint8_t sum;
int rc;
+ uint8_t req_oem_types_count = 0, oem_types[SMBIOS_TYPE_VENDOR_MAX-SMBIOS_TYPE_VENDOR_MIN+1];
/* invalidate the table */
memset(va_sm, 0, sizeof(struct hvm_sminfo_table));
return rc;
}
+ if ( (smbios_oem_types != NULL) && (strlen(smbios_oem_types) > 0) ) {
+ memset(oem_types, 0, sizeof(oem_types));
+ req_oem_types_count = parse_smbios_oem_types(smbios_oem_types, oem_types,
+ SMBIOS_TYPE_VENDOR_MAX-SMBIOS_TYPE_VENDOR_MIN+1);
+ if ( req_oem_types_count > 0 ) {
+ rc = copy_smbios_oem_types_pt_info(va_sm, oem_types, req_oem_types_count);
+ if ( rc != 0 ) {
+ XG_LOG("Failed to copy SMBIOS OEM types PT info!\n");
+ return rc;
+ }
+ }
+ }
+
/* process the primary SMBIOS tables like the system and bios information, if anything
fails don't pass anything to the HVM */
- rc = decode_smbios_structures(&smstructs, va_sm, 1);
- if (rc == 0) {
- /* store current count and try adding any secondary structures like battery, power supply, and vendor specific */
- count = va_sm->sm_count;
- length = va_sm->total_length;
- rc = decode_smbios_structures(&smstructs, va_sm, 0);
- if (rc != 0) {
- /* revert to what we had from the primary decode and return success with what we have */
- va_sm->sm_count = count;
- va_sm->total_length = length;
- rc = 0;
- }
- }
-
+ rc = decode_smbios_structures(&smstructs, va_sm, oem_types, req_oem_types_count);
helper_unmmap(smstructs.addr, smstructs.length);
if (rc == 0) {
(** build a hvm domain *)
external hvm_build : handle -> domid -> int -> string -> int
- -> bool -> bool -> bool -> bool -> bool -> bool -> bool -> int -> nativeint
+ -> bool -> bool -> bool -> bool -> bool -> string -> bool -> bool -> int -> nativeint
= "stub_xc_hvm_build_bytecode" "stub_xc_hvm_build_native"
(** build a hvm domain from memory *)
external hvm_build_mem : handle -> domid -> int -> string -> nativeint
- -> int -> bool -> bool -> bool -> bool -> bool -> bool -> bool -> int -> nativeint
+ -> int -> bool -> bool -> bool -> bool -> bool -> string -> bool -> bool -> int -> nativeint
= "stub_xc_hvm_build_mem_bytecode" "stub_xc_hvm_build_mem_native"
(** resume an uncooperative domain *)
Nativeint.to_string console_mfn; proto ]
)
-let hvm_build_real domid memsize image vcpus pae apic acpi nx smbios_pt acpi_pt viridian store_port =
+let hvm_build_real domid memsize image vcpus pae apic acpi nx smbios_pt smbios_oem_types_pt acpi_pt viridian store_port =
with_xenguest (fun xc ->
let store_mfn = Xenguest.hvm_build xc domid memsize image
- vcpus pae apic acpi nx smbios_pt acpi_pt viridian store_port in
+ vcpus pae apic acpi nx smbios_pt smbios_oem_types_pt
+ acpi_pt viridian store_port in
Nativeint.to_string store_mfn
)
(** fake operations *)
let linux_build_fake domid memsize image ramdisk cmdline features flags store_port console_port = "10 10 x86-32"
-let hvm_build_fake domid memsize image vcpus pae apic acpi nx smbios_pt acpi_pt viridian store_port = "2901"
+let hvm_build_fake domid memsize image vcpus pae apic acpi nx smbios_pt smbios_oem_types_pt acpi_pt viridian store_port = "2901"
let domain_save_fake fd domid x y flags hvm = Unix.sleep 1; ignore (suspend_callback domid); ""
let domain_restore_fake fd domid store_port console_port hvm pae viridian = "10 10"
(** operation vector *)
type ops = {
linux_build: int -> int -> string -> string option -> string -> string -> int -> int -> int -> string;
- hvm_build: int -> int -> string -> int -> bool -> bool -> bool -> bool -> bool -> bool -> bool -> int -> string;
+ hvm_build: int -> int -> string -> int -> bool -> bool -> bool -> bool -> bool -> string -> bool -> bool -> int -> string;
domain_save: Unix.file_descr -> int -> int -> int -> Xenguest.suspend_flags list -> bool -> string;
domain_restore: Unix.file_descr -> int -> int -> int -> bool -> bool -> bool -> string;
}
add_param "acpi" "true to enable ACPI for HVM";
add_param "nx" "true to enable NX for HVM";
add_param "smbios_pt" "true to enable SMBIOS pass-through for HVM";
+ add_param "smbios_oem_types_pt" "comma seperated oem type numbers to pass-through";
add_param "acpi_pt" "true to enable ACPI pass-through for HVM";
add_param "viridian" "true to enable Viridian enlightenments";
add_param "fork" "true to fork a background thread to capture stdout and stderr";
| Some "hvm_build" ->
debug "hvm_build mode selected";
require [ "domid"; "memsize"; "image"; "vcpus"; "pae";
- "apic"; "acpi"; "nx"; "smbios_pt"; "acpi_pt"; "viridian"; "store_port" ];
+ "apic"; "acpi"; "nx"; "smbios_pt"; "smbios_oem_types_pt"; "acpi_pt"; "viridian"; "store_port" ];
let domid = int_of_string (get_param "domid")
and memsize = int_of_string (get_param "memsize")
and image = get_param "image"
and apic = bool_of_string (get_param "apic")
and nx = bool_of_string (get_param "nx")
and smbios_pt = bool_of_string (get_param "smbios_pt")
+ and smbios_oem_types_pt = get_param "smbios_oem_types_pt"
and acpi_pt = bool_of_string (get_param "acpi_pt")
and viridian = bool_of_string (get_param "viridian")
and store_port = int_of_string (get_param "store_port") in
- with_logging (fun () -> ops.hvm_build domid memsize image vcpus pae apic acpi nx smbios_pt acpi_pt viridian store_port)
+ with_logging (fun () -> ops.hvm_build domid memsize image vcpus pae apic acpi nx smbios_pt smbios_oem_types_pt
+ acpi_pt viridian store_port)
| Some "test" ->
debug "test mode selected";
with_logging (fun () -> ignore(Unix.system "/tmp/test"); "result")
}
#ifdef HVM_SMINFO_EXTENSIONS
-extern int hvm_smbios_decode(struct hvm_sminfo_table *va_sm);
+extern int hvm_smbios_decode(struct hvm_sminfo_table *va_sm, char *smbios_oem_types_pt);
#endif
#ifdef HVM_ACINFO_EXTENSIONS
#endif
static int hvm_build_set_params(int handle, int domid,
- int apic, int acpi, int pae, int nx, int smbios_pt, int acpi_pt,
- int viridian, int vcpus, int store_evtchn, unsigned long *store_mfn)
+ int apic, int acpi, int pae, int nx, int smbios_pt, char *smbios_oem_types_pt,
+ int acpi_pt, int viridian, int vcpus, int store_evtchn, unsigned long *store_mfn)
{
struct hvm_info_table *va_hvm;
uint8_t *va_map, sum;
if (smbios_pt) {
#ifdef HVM_SMINFO_EXTENSIONS
/* call routine to decode and load SMBIOS tables */
- if (hvm_smbios_decode((struct hvm_sminfo_table *)va_map) != 0) {
+ if (hvm_smbios_decode((struct hvm_sminfo_table *)va_map, smbios_oem_types_pt) != 0) {
/* trace a warning and proceed - decoder invalidates table correctly */
XG_LOG("xenguest helper: %s decoding failed - pass through functionality will be disabled.", "SMBIOS");
}
value memsize, value image_name,
value vcpus, value pae, value apic,
value acpi, value nx,
- value smbios_pt, value acpi_pt,
+ value smbios_pt, value smbios_oem_types_pt,
+ value acpi_pt,
value viridian, value store_evtchn)
{
CAMLparam5(xc_handle, domid, memsize, image_name, vcpus);
CAMLxparam5(pae, apic, acpi, nx, smbios_pt);
- CAMLxparam3(acpi_pt, viridian, store_evtchn);
+ CAMLxparam4(smbios_oem_types_pt, acpi_pt, viridian, store_evtchn);
CAMLlocal1(ret);
char *image_name_c = strdup(String_val(image_name));
r = hvm_build_set_params(_H(xc_handle), _D(domid),
Bool_val(apic), Bool_val(acpi),
Bool_val(pae), Bool_val(nx),
- Bool_val(smbios_pt), Bool_val(acpi_pt),
+ Bool_val(smbios_pt), String_val(smbios_oem_types_pt),
+ Bool_val(acpi_pt),
Bool_val(viridian), Int_val(vcpus),
Int_val(store_evtchn), &store_mfn);
if (r)
return stub_xc_hvm_build_native(argv[0], argv[1], argv[2], argv[3],
argv[4], argv[5], argv[6], argv[7],
argv[8], argv[9], argv[10], argv[11],
- argv[12]);
+ argv[12], argv[13]);
}
CAMLprim value stub_xc_hvm_build_mem_native(value xc_handle, value domid,
value memsize, value image_buffer,
value image_size, value vcpus,
value pae, value apic, value acpi,
- value nx, value smbios_pt, value acpi_pt,
+ value nx, value smbios_pt,
+ value smbios_oem_types_pt, value acpi_pt,
value viridian, value store_evtchn)
{
CAMLparam5(xc_handle, domid, memsize, image_buffer, image_size);
CAMLxparam5(vcpus, pae, apic, acpi, nx);
- CAMLxparam4(smbios_pt, acpi_pt, viridian, store_evtchn);
+ CAMLxparam5(smbios_pt, smbios_oem_types_pt, acpi_pt, viridian, store_evtchn);
CAMLlocal1(ret);
unsigned long store_mfn;
unsigned long c_image_size;
r = hvm_build_set_params(_H(xc_handle), _D(domid),
Bool_val(apic), Bool_val(acpi),
Bool_val(pae), Bool_val(nx),
- Bool_val(smbios_pt), Bool_val(acpi_pt),
+ Bool_val(smbios_pt), String_val(smbios_oem_types_pt),
+ Bool_val(acpi_pt),
Bool_val(viridian), Int_val(vcpus),
Int_val(store_evtchn), &store_mfn);
if (r)
return stub_xc_hvm_build_mem_native(argv[0], argv[1], argv[2], argv[3],
argv[4], argv[5], argv[6], argv[7],
argv[8], argv[9], argv[10], argv[11],
- argv[12], argv[13]);
+ argv[12], argv[13], argv[14]);
}
extern void qemu_flip_buffer(int domid, int next_active);
acpi: bool;
nx: bool;
smbios_pt: bool;
+ smbios_oem_types_pt: string;
acpi_pt: bool;
viridian: bool;
shadow_multiplier: float;
(** build hvm type of domain *)
let build_hvm ~xc ~xs ~mem_max_kib ~mem_target_kib ~video_ram_mib ~shadow_multiplier ~vcpus
- ~kernel ~pae ~apic ~acpi ~nx ~smbios_pt ~acpi_pt ~viridian ~timeoffset
+ ~kernel ~pae ~apic ~acpi ~nx ~smbios_pt ~smbios_oem_types_pt ~acpi_pt ~viridian ~timeoffset
~timer_mode ~hpet ~vpt_align domid =
assert_file_is_readable kernel;
"-acpi"; string_of_bool acpi;
"-nx"; string_of_bool nx;
"-smbios_pt"; string_of_bool smbios_pt;
+ "-smbios_oem_types_pt"; smbios_oem_types_pt;
"-acpi_pt"; string_of_bool acpi_pt;
"-viridian"; string_of_bool viridian;
"-fork"; "true";
~video_ram_mib:hvminfo.videoram
~shadow_multiplier:hvminfo.shadow_multiplier ~vcpus:info.vcpus
~kernel:info.kernel ~pae:hvminfo.pae ~apic:hvminfo.apic ~acpi:hvminfo.acpi
- ~nx:hvminfo.nx ~smbios_pt:hvminfo.smbios_pt ~acpi_pt:hvminfo.acpi_pt ~viridian:hvminfo.viridian ~timeoffset:hvminfo.timeoffset
+ ~nx:hvminfo.nx ~smbios_pt:hvminfo.smbios_pt ~smbios_oem_types_pt:hvminfo.smbios_oem_types_pt
+ ~acpi_pt:hvminfo.acpi_pt ~viridian:hvminfo.viridian ~timeoffset:hvminfo.timeoffset
~timer_mode:hvminfo.timer_mode ~hpet:hvminfo.hpet ~vpt_align:hvminfo.vpt_align domid
| BuildPV pvinfo ->
build_linux ~xc ~xs ~mem_max_kib:info.memory_max ~mem_target_kib:info.memory_target
acpi: bool;
nx: bool;
smbios_pt: bool;
+ smbios_oem_types_pt: string;
acpi_pt: bool;
viridian: bool;
shadow_multiplier: float;
-> mem_target_kib:Int64.t -> video_ram_mib:int option -> shadow_multiplier:float
-> vcpus:int -> kernel:string
-> pae:bool -> apic:bool -> acpi:bool -> nx:bool
- -> smbios_pt:bool -> acpi_pt:bool -> viridian:bool
+ -> smbios_pt:bool -> smbios_oem_types_pt:string -> acpi_pt:bool -> viridian:bool
-> timeoffset:string -> timer_mode:int option -> hpet:int option -> vpt_align:int option -> domid
-> domarch
Domain.acpi = cfg.acpi;
Domain.nx = cfg.nx;
Domain.smbios_pt = cfg.smbios_pt;
+ Domain.smbios_oem_types_pt = cfg.smbios_oem_types_pt;
Domain.acpi_pt = cfg.acpi_pt;
Domain.viridian = cfg.viridian;
Domain.shadow_multiplier = 1.;
platform: (string * string) list;
timeoffset: string option;
smbios_pt: bool;
+ smbios_oem_types_pt: string;
acpi_pt: bool;
diskinfo_pt: bool;
viridian: bool;
| "viridian" -> string_of_bool cfg.viridian
| "videoram" -> string_of_int_option cfg.videoram
| "smbios-pt" -> string_of_bool cfg.smbios_pt
+ | "smbios-oem-types-pt" -> cfg.smbios_oem_types_pt
| "acpi-pt" -> string_of_bool cfg.acpi_pt
| "diskinfo-pt" -> string_of_bool cfg.diskinfo_pt
| "boot" -> cfg.boot
| "viridian" -> { cfg with viridian = bool_of_string value }
| "videoram" -> { cfg with videoram = int_option_of_string value }
| "smbios-pt" -> { cfg with smbios_pt = bool_of_string value }
+ | "smbios-oem-types-pt" -> { cfg with smbios_oem_types_pt = value }
| "acpi-pt" -> { cfg with acpi_pt = bool_of_string value }
| "diskinfo-pt" -> { cfg with diskinfo_pt = bool_of_string value }
| "boot" -> { cfg with boot = value }
apic = false;
nx = false;
smbios_pt = false;
+ smbios_oem_types_pt = "";
acpi_pt = false;
diskinfo_pt = false;
viridian = false;
kernel cmdline ramdisk vcpus domid in
printf "built domain: %u\n" domid
-let build_hvm ~xc ~xs ~kernel ~domid ~vcpus ~mem_max_kib ~mem_target_kib ~pae ~apic ~acpi ~nx ~smbios_pt ~acpi_pt ~viridian =
+let build_hvm ~xc ~xs ~kernel ~domid ~vcpus ~mem_max_kib ~mem_target_kib ~pae ~apic ~acpi ~nx
+ ~smbios_pt ~smbios_oem_types_pt ~acpi_pt ~viridian =
let (_: Domain.domarch) = Domain.build_hvm xc xs mem_max_kib mem_target_kib None 1.
- vcpus kernel pae apic acpi nx smbios_pt acpi_pt viridian
+ vcpus kernel pae apic acpi nx smbios_pt smbios_oem_types_pt
+ acpi_pt viridian
"0" None None None domid in
printf "built hvm domain: %u\n" domid
and apic = ref false
and nx = ref false
and smbios_pt = ref false
+ and smbios_oem_types_pt = ref ""
and acpi_pt = ref false
and viridian = ref false
and verbose = ref false
"-apic", Arg.Set apic, "set APIC to true";
"-nx", Arg.Set nx, "set NX to true";
"-smbios_pt", Arg.Set smbios_pt, "set SMBIOS PT to true";
+ "-smbios_oem_types_pt", Arg.Set_string smbios_oem_types_pt, "set SMBIOS oem type numbers to pass-through";
"-acpi_pt", Arg.Set acpi_pt, "set ACPI PT to true";
"-viridian", Arg.Set viridian, "set VIRIDIAN to true";
]
) cmd;
!domid, !backend_domid, !hvm, !vcpus, !vcpu, !kernel,
!ramdisk, !cmdline, Int64.of_int !mem_max_kib, Int64.of_int !mem_mib,
- !pae, !apic, !acpi, !nx, !smbios_pt, !acpi_pt, !viridian, !verbose, !file,
+ !pae, !apic, !acpi, !nx, !smbios_pt, !smbios_oem_types_pt,
+ !acpi_pt, !viridian, !verbose, !file,
!mode, !phystype, !physpath, !virtpath, !dev_type, !devid, !mac, !pci,
!reason, !sysrq, !script, !sync, !netty, !weight, !cap, !bitmap, !cooperative,
!boot, !ioport_start, !ioport_end, !iomem_start, !iomem_end, !irq,
let domid, backend_domid, hvm, vcpus, vcpu, kernel, ramdisk, cmdline,
- mem_max_kib, mem_mib, pae, apic, acpi, nx, smbios_pt, acpi_pt, viridian, verbose, file, mode,
+ mem_max_kib, mem_mib, pae, apic, acpi, nx, smbios_pt, smbios_oem_types_pt,
+ acpi_pt, viridian, verbose, file, mode,
phystype, physpath, virtpath, dev_type, devid, mac, pci, reason, sysrq,
script, sync, netty, weight, cap, bitmap, cooperative,
boot, ioport_start, ioport_end, iomem_start, iomem_end, irq,
| "build_hvm" ->
assert_domid (); assert_vcpus ();
with_xc_and_xs (fun xc xs -> build_hvm ~xc ~xs ~kernel ~vcpus ~mem_max_kib ~mem_target_kib ~pae
- ~apic ~acpi ~nx ~smbios_pt ~acpi_pt ~viridian ~domid)
+ ~apic ~acpi ~nx ~smbios_pt ~smbios_oem_types_pt
+ ~acpi_pt ~viridian ~domid)
| "setmaxmem" ->
assert_domid ();
with_xc (fun xc -> Xc.domain_setmaxmem xc domid mem_max_kib) (* call takes pages *)
apic = true|false -- specify the guest is using apic
nx = true|false -- specify the guest is using nx
smbios-pt = true|false -- specify the guest is using smbios pass-through
+smbios-oem-types-pt = comma seperated oem type numbers -- specify the smbios oem type numbers to pass-through
acpi-pt = true|false -- specify the guest is using acpi pass-through
diskinfo-pt = true|false -- specify the guest is using SCSI disk info pass-through