From patchwork Fri Jun 18 10:45:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?RWR3aW4gVMO2csO2aw==?= X-Patchwork-Id: 12331007 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80ADBC48BDF for ; Fri, 18 Jun 2021 10:46:45 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4AD8C61003 for ; Fri, 18 Jun 2021 10:46:45 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4AD8C61003 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from list by lists.xenproject.org with outflank-mailman.144450.265859 (Exim 4.92) (envelope-from ) id 1luC0t-0003M1-1G; Fri, 18 Jun 2021 10:46:15 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 144450.265859; Fri, 18 Jun 2021 10:46:15 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1luC0s-0003Lu-UH; Fri, 18 Jun 2021 10:46:14 +0000 Received: by outflank-mailman (input) for mailman id 144450; Fri, 18 Jun 2021 10:46:14 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1luC0r-0003Lo-Rg for xen-devel@lists.xenproject.org; Fri, 18 Jun 2021 10:46:14 +0000 Received: from esa6.hc3370-68.iphmx.com (unknown [216.71.155.175]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 2421318e-c52e-47bf-8410-e2cc398a69e3; Fri, 18 Jun 2021 10:46:11 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 2421318e-c52e-47bf-8410-e2cc398a69e3 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1624013170; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=9vOeCeFfOggb0WwAvbYfKTPJrxgP0fgM+hFpQdUu6Cw=; b=HDKGAFjkNJUkowY4Elyywh5zx4dnCXXH2K21RoZrWnKTngCGfWlquxKy wLzupSVJsuI+52z16zt6LCxIB2uCx9weGm6xDikAEcmJc0bM3ASGXlL7Y iCRIf5v1Euj6HR76EAA6FZyALpOrP14Hhuwg5antk8wzVE/dut7JIO57D 4=; Authentication-Results: esa6.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: hoguw0MVsLT8mcdRJCBigjaePAd3Wh3nqUxuzzyqPRAv/ydvVp8VL373AnyMKpeobLEcFpeSbd vqJedRcA1OXgjgUCI8Ko3h7khmAoPWsYkSIe5ThfXsFaydOVXtRF7TvpyUXOWZEDb8R2b2+NIE ppFkKEiLNiCpFaDLa8R4zFkhC5HWFj8gKjbKgQHHkCByrLotjczxWRf48y5svWfb/84YL/Ga84 11GA6vs8tMrFA0SLPENTPe6LYuaZChXJFQpajc/KrCjxXzSEUZfRHE/LG67SqmIdwVWkmMoEyB Qec= X-SBRS: 5.1 X-MesageID: 46518866 X-Ironport-Server: esa6.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED IronPort-HdrOrdr: A9a23:KfGBEqNtJL/JGcBcTs2jsMiBIKoaSvp037Eqv3oedfUzSL3+qy nOpoV+6faaslYssR0b9exoW5PwJE80l6QFgrX5VI3KNGKN1VdARLsSi7cKqAeAJ8SRzIFgPN 9bAspDNOE= X-IronPort-AV: E=Sophos;i="5.83,283,1616472000"; d="scan'208";a="46518866" From: =?utf-8?b?RWR3aW4gVMO2csO2aw==?= To: CC: =?utf-8?b?RWR3aW4gVMO2csO2aw==?= , "Christian Lindig" , David Scott , "Ian Jackson" , Wei Liu , Andrew Cooper Subject: [PATCH] tools/ocaml/libs/xc: add OCaml stubs to query CPU policy Date: Fri, 18 Jun 2021 11:45:15 +0100 Message-ID: <5fdb7b4cdee69af8e2b9d77b56b1027a8799cf04.1624012999.git.edvin.torok@citrix.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Introduces following functions in Xenctrl and associated types: get_system_cpu_policy cpu_policy_to_featureset, string_of_xen_cpu_policy_index These are wrappers around the existing C functions in xenctrl.h, that will be used by xenopsd initially. -Wno-declaration-after-statement is disabled to allow mixing declarations and code to simplify writing the stubs by using variable length arrays on the stack instead of allocating/freeing memory (which would require additional error-handling logic). Signed-off-by: Edwin Török Signed-off-by: Edwin Török > Acked-by: Christian Lindig > --- tools/ocaml/libs/xc/Makefile | 2 +- tools/ocaml/libs/xc/xenctrl.ml | 37 ++++++ tools/ocaml/libs/xc/xenctrl.mli | 71 ++++++++++ tools/ocaml/libs/xc/xenctrl_stubs.c | 195 ++++++++++++++++++++++++++++ 4 files changed, 304 insertions(+), 1 deletion(-) diff --git a/tools/ocaml/libs/xc/Makefile b/tools/ocaml/libs/xc/Makefile index b6da4fdbaf..64dca99613 100644 --- a/tools/ocaml/libs/xc/Makefile +++ b/tools/ocaml/libs/xc/Makefile @@ -3,7 +3,7 @@ XEN_ROOT=$(TOPLEVEL)/../.. include $(TOPLEVEL)/common.make CFLAGS += -I../mmap $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) -CFLAGS += $(APPEND_CFLAGS) +CFLAGS += $(APPEND_CFLAGS) -Wno-declaration-after-statement OCAMLINCLUDE += -I ../mmap OBJS = xenctrl diff --git a/tools/ocaml/libs/xc/xenctrl.ml b/tools/ocaml/libs/xc/xenctrl.ml index a5588c643f..fa2cea5091 100644 --- a/tools/ocaml/libs/xc/xenctrl.ml +++ b/tools/ocaml/libs/xc/xenctrl.ml @@ -286,6 +286,43 @@ external version_capabilities: handle -> string = type featureset_index = Featureset_raw | Featureset_host | Featureset_pv | Featureset_hvm external get_cpu_featureset : handle -> featureset_index -> int64 array = "stub_xc_get_cpu_featureset" +(* order must match the order in Val_cpuid_leaf *) +type xen_cpuid_leaf = { + leaf: int64; + subleaf: int64; + a: int64; + b: int64; + c: int64; + d: int64; +} + +(* order must match the order in Val_msr_entry *) +type xen_msr_entry = { + idx: int64; + flags: int64; + value: int64; (* val is a keyword, using 'value' *) +} + +type xen_cpu_policy = { + leaves: xen_cpuid_leaf array; + msrs: xen_msr_entry array; +} + +(* must match XEN_SYSCTL_cpu_policy* order in xen/include/public/sysctl.h *) +type xen_cpu_policy_index = Cpu_policy_raw | Cpu_policy_host | Cpu_policy_pv_max | Cpu_policy_hvm_max | Cpu_policy_pv_default | Cpu_policy_hvm_default + +let string_of_xen_cpu_policy_index = function + | Cpu_policy_raw -> "Raw" + | Cpu_policy_host -> "Host" + | Cpu_policy_pv_max -> "PV Max" + | Cpu_policy_hvm_max -> "HVM Max" + | Cpu_policy_pv_default -> "PV default" + | Cpu_policy_hvm_default -> "HVM default" + +external get_system_cpu_policy: handle -> xen_cpu_policy_index -> xen_cpu_policy = "stub_xc_get_system_cpu_policy" + +external cpu_policy_to_featureset: handle -> xen_cpu_policy -> int64 array = "stub_xc_policy_to_featureset" + external watchdog : handle -> int -> int32 -> int = "stub_xc_watchdog" diff --git a/tools/ocaml/libs/xc/xenctrl.mli b/tools/ocaml/libs/xc/xenctrl.mli index 6e94940a8a..605adeeec9 100644 --- a/tools/ocaml/libs/xc/xenctrl.mli +++ b/tools/ocaml/libs/xc/xenctrl.mli @@ -223,6 +223,77 @@ external version_capabilities : handle -> string type featureset_index = Featureset_raw | Featureset_host | Featureset_pv | Featureset_hvm external get_cpu_featureset : handle -> featureset_index -> int64 array = "stub_xc_get_cpu_featureset" +(** CPUID takes a leaf (EAX) and optional subleaf (ECX) as input and + returns feature information bitset in 4 registers (EAX, EBX, ECX, EDX). + This record captures one such invocation of CPUID. + + CPU manuals contain tables explaining the available leaves/subleaves and feature bits: + + https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html + Intel® 64 and IA-32 architectures software developer's manual volume 2A: Instruction set reference + Chapter 3.2, Table 3-8 + + https://developer.amd.com/resources/developer-guides-manuals/ + AMD64 Architecture Programmer’s Manual Volume 3: General Purpose and System Instructions + Appendix D Instruction Subsets and CPUID Feature Flags + *) +type xen_cpuid_leaf = { + leaf: int64; (** initial EAX value *) + subleaf: int64; (** initial ECX value *) + a: int64; (** EAX result *) + b: int64; (** EBX result *) + c: int64; (** ECX result *) + d: int64; (** EDX result *) +} + +(** CPU Model Specific Registers control various aspects of CPU behaviour. + + RDMSR takes ECX as input and returns its result in EDX:EAX. + This record captures one invocation of RDMSR. + + CPU manuals document the available MSRs and feature bits + + https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html + Intel® 64 and IA-32 architectures software developer's manual volume 4: Model-specific registers + Chapter 2, "Model-Specific Registers (MSRs)" + + https://developer.amd.com/resources/developer-guides-manuals/ + AMD64 Architecture Programmer’s Manual Volume 2: System Programming + Appendix A "MSR Cross-Reference" + *) +type xen_msr_entry = { + idx: int64; (** MSR register - ECX input *) + flags: int64; (** reserved, must be zero *) + value: int64; (** EDX:EAX output *) +} + +(** Xen CPU policy contains the CPUID features and MSRs visible in a domain. + The order of leaves and MSRs is not important, but entries cannot be duplicated. + *) +type xen_cpu_policy = { + leaves: xen_cpuid_leaf array; (** Array of CPUID leaves/ *) + msrs: xen_msr_entry array; (** Array of MSRs *) +} + +(** Xen CPU policy to query or set *) +type xen_cpu_policy_index = + | Cpu_policy_raw (** as seen on boot *) + | Cpu_policy_host (** features implemented by the host *) + | Cpu_policy_pv_max (** maximum PV features that we can accept in a migration: either implemented natively or emulated *) + | Cpu_policy_hvm_max (** maximum HVM features that we can accept in a migration: either implemented natively or emulated *) + | Cpu_policy_pv_default (** default PV features for newly booted VMs *) + | Cpu_policy_hvm_default (** default HVM features for newly booted VMs *) + +(** [string_of_xen_cpu_policy_index policy_index] is the name of the [policy_index] policy *) +val string_of_xen_cpu_policy_index : xen_cpu_policy_index -> string + +(** [get_system_cpu_policy xenctrlhandle policy_index] retrieves the [policy_index] policy from the running hypervisor *) +external get_system_cpu_policy: handle -> xen_cpu_policy_index -> xen_cpu_policy = "stub_xc_get_system_cpu_policy" + +(** [cpu_policy_to_featureset xenctrlhandle policy] converts [policy] to a featureset for backwards compatibility + (e.g. accepting incoming migrations in xenopsd from a non-policy-aware xenopsd) *) +external cpu_policy_to_featureset: handle -> xen_cpu_policy -> int64 array = "stub_xc_policy_to_featureset" + external pages_to_kib : int64 -> int64 = "stub_pages_to_kib" val pages_to_mib : int64 -> int64 external watchdog : handle -> int -> int32 -> int diff --git a/tools/ocaml/libs/xc/xenctrl_stubs.c b/tools/ocaml/libs/xc/xenctrl_stubs.c index d05d7bb30e..4a230de8b7 100644 --- a/tools/ocaml/libs/xc/xenctrl_stubs.c +++ b/tools/ocaml/libs/xc/xenctrl_stubs.c @@ -34,6 +34,9 @@ #include #include +#include +#include + #include "mmap_stubs.h" #define PAGE_SHIFT 12 @@ -1216,6 +1219,198 @@ CAMLprim value stub_xc_watchdog(value xch, value domid, value timeout) CAMLreturn(Val_int(ret)); } +static CAMLprim value Val_cpuid_leaf(const xen_cpuid_leaf_t *leaf) +{ + CAMLparam0(); + CAMLlocal1(result); + result = caml_alloc_tuple(6); + Store_field(result, 0, caml_copy_int64(leaf->leaf)); + Store_field(result, 1, caml_copy_int64(leaf->subleaf)); + Store_field(result, 2, caml_copy_int64(leaf->a)); + Store_field(result, 3, caml_copy_int64(leaf->b)); + Store_field(result, 4, caml_copy_int64(leaf->c)); + Store_field(result, 5, caml_copy_int64(leaf->d)); + + CAMLreturn(result); +} + +static CAMLprim void cpuid_leaf_of_val(xen_cpuid_leaf_t *leaf, value v) +{ + CAMLparam1(v); + leaf->leaf = Int64_val(Field(v, 0)); + leaf->subleaf = Int64_val(Field(v, 1)); + leaf->a = Int64_val(Field(v, 2)); + leaf->b = Int64_val(Field(v, 3)); + leaf->c = Int64_val(Field(v, 4)); + leaf->d = Int64_val(Field(v, 5)); + + CAMLreturn0; +} + +static CAMLprim value Val_msr_entry(const xen_msr_entry_t *msr) +{ + CAMLparam0(); + CAMLlocal1(result); + result = caml_alloc_tuple(3); + Store_field(result, 0, caml_copy_int64(msr->idx)); + Store_field(result, 1, caml_copy_int64(msr->flags)); + Store_field(result, 2, caml_copy_int64(msr->val)); + CAMLreturn(result); +} + +#if 0 +static CAMLprim void msr_entry_of_val(xen_msr_entry_t *msr, value v) +{ + CAMLparam1(v); + msr->idx = Int64_val(Field(v, 0)); + msr->flags = Int64_val(Field(v, 1)); + msr->val = Int64_val(Field(v, 2)); + CAMLreturn0; +} +#endif + +static CAMLprim value Val_leaves(const xen_cpuid_leaf_t *leaves, uint32_t nr_leaves) +{ + CAMLparam0(); + CAMLlocal1(result); + uint32_t i; + + result = caml_alloc(nr_leaves, 0); + for (i=0;i