]> xenbits.xensource.com Git - xcp/xen-api-libs.git/commitdiff
CP-1635: Cpuid module to obtain CPU information
authorRob Hoes <rob.hoes@citrix.com>
Wed, 17 Feb 2010 10:14:40 +0000 (10:14 +0000)
committerRob Hoes <rob.hoes@citrix.com>
Wed, 17 Feb 2010 10:14:40 +0000 (10:14 +0000)
This module obtains the vendor/model/family/stepping as well as feature information from the CPU, and determines whether CPU feature masks can be applied.

Signed-off-by: Rob Hoes <rob.hoes@citrix.com>
.hgignore
Makefile.in
cpuid/META.in
cpuid/Makefile
cpuid/cpuid.ml
cpuid/cpuid.mli

index d42d65abe795d3bd6b0c5d550ddcd73b45e09b2c..daa8cd25ca175cb1b03c75bc8b5cd585fb2fa4c0 100644 (file)
--- a/.hgignore
+++ b/.hgignore
@@ -14,3 +14,4 @@ autom4te\.cache/
 ^config\.log$
 ^config\.status$
 ^configure$
+doc/*
index a56c9959111d19d8ba139129a8e1f084b4219cf7..b810b7252c95663bf53b5ea51d5b124316055906 100644 (file)
@@ -31,6 +31,7 @@ ifeq ($(HAVE_DEVICE_MAPPER),1)
 endif
        $(MAKE) -C forking_executioner
        $(MAKE) -C mlvm
+       $(MAKE) -C cpuid
 
 .PHONY: allxen
 allxen:
@@ -67,6 +68,7 @@ ifeq ($(HAVE_DEVICE_MAPPER),1)
 endif
        $(MAKE) -C forking_executioner install
        $(MAKE) -C mlvm install
+       $(MAKE) -C cpuid install
 
 installxen:
 ifeq ($(HAVE_XEN),1)
@@ -102,6 +104,7 @@ ifeq ($(HAVE_DEVICE_MAPPER),1)
 endif
        $(MAKE) -C forking_executioner uninstall
        $(MAKE) -C mlvm uninstall
+       $(MAKE) -C cpuid uninstall
 
 uninstallxen:
 ifeq ($(HAVE_XEN),1)
@@ -160,6 +163,7 @@ doc:
        $(MAKE) -C mmap doc
        $(MAKE) -C forking_executioner doc
        $(MAKE) -C mlvm doc
+       $(MAKE) -C cpuid doc
 
 .PHONY: clean
 clean:
@@ -179,6 +183,7 @@ clean:
        make -C doc clean
        make -C forking_executioner clean
        make -C mlvm clean
+       make -C cpuid clean
 
 cleanxen:
        $(MAKE) -C mmap clean
index 7a549ec0a985987887a7d9f8d5463fdf2aa3e1cc..c5ced2f4a444ca4dbcc5ef945510dfffe14bda8a 100644 (file)
@@ -1,5 +1,5 @@
 version = "@VERSION@"
 description = "Cpuid extension"
-requires = "stdext xc xen-utils"
+requires = ""
 archive(byte) = "cpuid.cma"
 archive(native) = "cpuid.cmxa"
index 8c4752826e8785ac0f6666e5d23049b4bc991fbf..f62642f8f2ca8fd2de6ffb9761a6df10f2020beb 100644 (file)
@@ -1,8 +1,8 @@
 CC = gcc
-CFLAGS = -Wall -fPIC -O2 -I/usr/lib/ocaml -I$(XEN_ROOT)/usr/include
+CFLAGS = -Wall -fPIC -O2 -I/opt/xensource/lib/ocaml -I$(XEN_ROOT)/usr/include
 OCAMLC = ocamlc -g
 OCAMLOPT = ocamlopt
-INCLUDES = -I ../stdext -I ../xc -I ../xen-utils
+INCLUDES = -I ../stdext
 
 LDFLAGS = -cclib -L./
 
@@ -65,8 +65,8 @@ uninstall:
 
 .PHONY: doc
 doc: $(INTF)
-       python ../doc/doc.py $(DOCDIR) "cpuid" "package" "$(OBJS)" "." "stdext xc xen-utils" ""
+       python ../doc/doc.py $(DOCDIR) "cpuid" "package" "$(OBJS)" "." "stdext" ""
        
 clean:
-       rm -f *.o *.so *.a *.cmo *.cmi *.cma *.cmx *.cmxa *.annot $(LIBS) $(PROGRAMS) *~ *.rej
+       rm -f *.o *.so *.a *.cmo *.cmi *.cma *.cmx *.cmxa *.annot $(LIBS) $(PROGRAMS)
 
index ee692d9cb7a7e981f07f322f4c5e29ea7ef04160..fe6937243a278b0853ac6ae8eb01a9f815676433 100644 (file)
@@ -23,7 +23,6 @@ exception ManufacturersDiffer
 (* === Types and conversion === *)
 
 type manufacturer = AMD | Intel | Unknown
-and maskability = No | Base | Full
 and features =
        {
                base_ecx: int32;
@@ -39,7 +38,7 @@ and cpu_info =
                stepping: int32;
                features: features;
                physical_features: features;
-               maskable: maskability;
+               maskable: bool;
        }
 
 let features_to_string f =
@@ -110,73 +109,39 @@ let read_features () =
 (* Does this Intel CPU support "FlexMigration"? 
  * It's not sensibly documented, so check by model *)
 let has_flexmigration family model stepping = 
-       if family <> 0x6l then
-               No
-       else if model = 0x1dl || (model = 0x17l && stepping >= 4l) then
-               Base
-       else if (model = 0x1al && stepping > 2l) ||
-               model = 0x1el || model = 0x25l || model = 0x2cl ||
-               model = 0x2el || model = 0x2fl then
-               Full
-       else
-               No
+       family > 0x6l || (model > 0x17l || (model = 0x17l && stepping >= 4l))
 
 (* Does this AMD CPU have Extended Migration Technology? 
  * Known good on Barcelona and better; did exist on some older CPUs 
  * but not really documented which ones *)
 let has_emt family = 
-       if family >= 0x10l then
-               Full
-       else
-               No
+       family >= 0x10l
        
 let is_maskable manufacturer family model stepping =
        match manufacturer with 
-       | Unknown -> No
-       | Intel -> has_flexmigration family model stepping
-       | AMD -> has_emt family
-
-let get_features_from_xen () =
-       let features = 
-         try Xc.with_intf (fun xc -> Xc.get_boot_cpufeatures xc) 
-         with _ -> 0l, 0l, 0l, 0l, 0l, 0l, 0l, 0l 
-       in
-       match features with
-       | base_ecx, base_edx, ext_ecx, ext_edx,
-               masked_base_ecx, masked_base_edx, masked_ext_ecx, masked_ext_edx ->     
-               {
-                       base_ecx = masked_base_ecx;
-                       base_edx = masked_base_edx;
-                       ext_ecx = masked_ext_ecx;
-                       ext_edx = masked_ext_edx
-               },
-               {
-                       base_ecx = base_ecx;
-                       base_edx = base_edx;
-                       ext_ecx = ext_ecx;
-                       ext_edx = ext_edx
-               }
-               
-let get_current_mask () =
-       let masks = Xen_cmdline.list_cpuid_masks () in
-       let get_mask m =
-               if List.mem_assoc m masks = false then
-                       0xffffffffl
-               else
-                       Int32.of_string (List.assoc m masks)
-       in
-       {
-               base_ecx = get_mask "cpuid_mask_ecx";
-               base_edx = get_mask "cpuid_mask_edx";
-               ext_ecx = get_mask "cpuid_mask_ext_ecx";
-               ext_edx = get_mask "cpuid_mask_ext_edx"
-       }
-       
+       | Unknown -> false
+       | Intel ->
+               if has_flexmigration family model stepping then true
+               else false
+       | AMD ->
+               if has_emt family then true
+               else false
+
+let get_physical_features features =
+       let features_file = "/var/xapi/features" in
+       try
+               let data = Unixext.read_whole_file_to_string features_file in
+               string_to_features data
+       with _ ->
+               let data = features_to_string features in
+               Unixext.write_string_to_file features_file data;
+               features
+
 let read_cpu_info () =
        let manufacturer = read_manufacturer () in
        let family = read_family () in
        let model = read_model () in
-       let features, phy_features = get_features_from_xen () in
+       let features = read_features () in
        let stepping = read_stepping () in
        {
                manufacturer = manufacturer;
@@ -184,43 +149,39 @@ let read_cpu_info () =
                model = model;
                stepping = stepping;
                features = features;
-               physical_features = phy_features;
+               physical_features = get_physical_features features;
                maskable = is_maskable manufacturer family model stepping;
        }
        
 (* === Masking checks === *)
 
-let mask_features features mask =
-       {
-               base_ecx = logand features.base_ecx mask.base_ecx;
-               base_edx = logand features.base_edx mask.base_edx;
-               ext_ecx = logand features.ext_ecx mask.ext_ecx;
-               ext_edx = logand features.ext_edx mask.ext_edx;
-       }
-
 let assert_maskability cpu manufacturer features = 
        (* Manufacturers need to be the same *)
        if manufacturer != cpu.manufacturer then 
                raise ManufacturersDiffer;
-       (* Check whether the features can be obtained by masking the physical features *)
-       let base = (logand cpu.physical_features.base_ecx features.base_ecx) = features.base_ecx 
-               && (logand cpu.physical_features.base_edx features.base_edx) = features.base_edx in
-       match cpu.maskable with
-       | No ->
+       (* Check whether masking is supported on the CPU *)
+       if not cpu.maskable then 
                begin match cpu.manufacturer with 
                | Unknown -> raise (MaskingNotSupported "Unknown CPU manufacturer")
                | Intel -> raise (MaskingNotSupported "CPU does not have FlexMigration")
                | AMD -> raise (MaskingNotSupported "CPU does not have Extended Migration Technology")
+               end;
+       (* Check whether the features can be obtained by masking the physical features *)
+       let possible = (logand cpu.physical_features.base_ecx features.base_ecx) = features.base_ecx 
+               && (logand cpu.physical_features.base_edx features.base_edx) = features.base_edx
+               && begin match manufacturer with 
+               | Intel ->
+                       (* Intel can't mask extented features but doesn't (yet) need to *)
+                       cpu.physical_features.ext_ecx = features.ext_ecx
+                               && cpu.physical_features.ext_edx = features.ext_edx
+               | AMD ->
+                       (logand cpu.physical_features.ext_ecx features.ext_ecx) = features.ext_ecx 
+                               && (logand cpu.physical_features.ext_edx features.ext_edx) = features.ext_edx
+               | _ -> false
                end
-       | Base ->
-               if not (base && cpu.physical_features.ext_ecx = features.ext_ecx
-                       && cpu.physical_features.ext_edx = features.ext_edx) then
-                       raise (InvalidFeatureString "CPU features cannot be masked to obtain \
-                               given features (only base features can be masked)")
-       | Full ->
-               if not (base && (logand cpu.physical_features.ext_ecx features.ext_ecx) = features.ext_ecx 
-                       && (logand cpu.physical_features.ext_edx features.ext_edx) = features.ext_edx) then
-                       raise (InvalidFeatureString "CPU features cannot be masked to obtain given features")
+       in
+       if not possible then
+               raise (InvalidFeatureString "CPU features cannot be masked to obtain given features")
 
 let xen_masking_string cpu features = 
        let rec stringify reglist = 
index 871ca115ede67b975aae006aecf79077201883a1..7f9e800c85f506afbc26e0099644e40f05787cbf 100644 (file)
@@ -21,12 +21,6 @@ type manufacturer =
 | Intel                (** Intel *)
 | Unknown      (** Other manufacturer *)
 
-(** Indicates whether CPUID features can be masked. *)
-and maskability =
-| No           (** No masking possible *)
-| Base         (** Only base features can be masked *)
-| Full         (** Both base and extended features can be masked *)
-
 (** CPU feature bit vector. *)
 and features
 
@@ -39,7 +33,7 @@ and cpu_info =
                stepping: int32;                                (** Stepping number of the CPU *)
                features: features;                             (** Feature bit vector of the CPU *)
                physical_features: features;    (** Physical Feature bit vector of the CPU *)
-               maskable: maskability;                  (** Indicates whether the CPU supports
+               maskable: bool;                                 (** Boolean indicating whether the CPU supports
                                                                                Intel FlexMigration or AMD Extended Migration,
                                                                                or cannot be masked *)
        }
@@ -60,11 +54,8 @@ val read_cpu_info : unit -> cpu_info
 
 (** {2 Masking Checks} *)
 
-(** Apply a mask to given features. *)
-val mask_features : features -> features -> features
-
-(** Check that this CPU can be masked to fit the pool. Raises exception
- *  indicating the reason if this is not possible. *)
+(** Check that this CPU can be masked to fit the pool. Raises {!CannotMaskCpu} 
+ *  including a reason string if this is not possible. *)
 val assert_maskability : cpu_info -> manufacturer -> features -> unit
 
 (** Return the CPU masking string to add to the Xen command-line,