From patchwork Fri Aug 4 02:20:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sky Liu X-Patchwork-Id: 9880297 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 77E8460311 for ; Fri, 4 Aug 2017 02:23:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 71698289A0 for ; Fri, 4 Aug 2017 02:23:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 662BE289A3; Fri, 4 Aug 2017 02:23:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.6 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 564D2289A0 for ; Fri, 4 Aug 2017 02:22:59 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ddSEG-0000as-FN; Fri, 04 Aug 2017 02:20:44 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ddSEF-0000aH-BF for xen-devel@lists.xen.org; Fri, 04 Aug 2017 02:20:43 +0000 Received: from [193.109.254.147] by server-9.bemta-6.messagelabs.com id 2B/D8-03406-AF9D3895; Fri, 04 Aug 2017 02:20:42 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrLIsWRWlGSWpSXmKPExsXiVRvsrPvrZnO kwb1OZoslHxezODB6HN39mymAMYo1My8pvyKBNWPu7P+MBZvCK46+PcnWwLjfvouRi0NIYAKj xMKZnUwgDovASxaJhasngTkSAv2sEpeapzB3MXICOUkS375tY4GwKyQm7fgOZgsJKEtMX/mDH WJUI5PEzddLWEESbAIaEmunHGQDsUUEpCWufb7MCFLELNDDLNE15QVYkbBAqkTH6U9ACQ6g3a oSkxc5gYR5BSwlZi9aBLVYXmJi7zRGEJtTwEqi6dobdojFlhJ//j9nmcAosICRYRWjRnFqUVl qka6xgV5SUWZ6RkluYmaOrqGBmV5uanFxYnpqTmJSsV5yfu4mRmBwMQDBDsa/awMPMUpyMCmJ 8lYfa4oU4kvKT6nMSCzOiC8qzUktPsQow8GhJMErBQxWIcGi1PTUirTMHGCYw6QlOHiURHhv3 gBK8xYXJOYWZ6ZDpE4xWnJsWL3+CxPHpAPbgeSrCf+/MQmx5OXnpUqJ8y4HaRAAacgozYMbB4 vFS4yyUsK8jEAHCvEUpBblZpagyr9iFOdgVBLmlQe5iiczrwRu6yugg5iADvpT1whyUEkiQkq qgbGHT+PyxzkWgcrH9noZ+C15N+XBea0u+64uD6NtejlPMl3ZdO/M5o7tXPhq1foHEVbvpWL1 Tn9gEVR9fOj4dx05GWf1ZTs9dH5tTp5yKX8Sx6eLa8+2h+i4/NmrbS1u+m2hpVHg3eIUp7+rX 20o1dO/Fdg3K9Agopv3ftjVrObQZwK17SExE5RYijMSDbWYi4oTAYDckXbAAgAA X-Env-Sender: blackskygg@gmail.com X-Msg-Ref: server-3.tower-27.messagelabs.com!1501813240!109987034!1 X-Originating-IP: [74.125.83.67] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 9.4.25; banners=-,-,- X-VirusChecked: Checked Received: (qmail 13659 invoked from network); 4 Aug 2017 02:20:41 -0000 Received: from mail-pg0-f67.google.com (HELO mail-pg0-f67.google.com) (74.125.83.67) by server-3.tower-27.messagelabs.com with AES128-GCM-SHA256 encrypted SMTP; 4 Aug 2017 02:20:41 -0000 Received: by mail-pg0-f67.google.com with SMTP id y129so418610pgy.3 for ; Thu, 03 Aug 2017 19:20:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=5v+ee099c4EyY9i/r0zAb80hIa8IZyLbWO+f9m0duEU=; b=ptS2uVDLVuuBF4XOOmZIUSbvgf3tyIVg+g7iN9aTTH10SXDJ7CLz96V2P2rN5Tn6AD 5oB3Bief8iCGou/ew+tZbIylCV0QcdiDMchscVnrBxR3RQ8niRPGlhGJEL1S7mLe0TMr n6MA+m8YLpu7bZKezZJ4MyPvRab0xxhea3tdofihZVN8TMhJahpS38WzfMY96aLs8N6w i7eW8zYxP80TSVS04tSqRfTF6g6l9U+K/Anu4nQ/rgaBrUc+BlJtZzanVA6uWf9y4i1p uvbny6+FwLEUWpxXxfcuApAXF7FGH1AvB7LxGhz6b1FZvXo010/EuP2cA6H8s+TLp/IW Y/wA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=5v+ee099c4EyY9i/r0zAb80hIa8IZyLbWO+f9m0duEU=; b=ruWSCr+IDBXhrFczq62ktzMeE5RcVwV1w3Y3V6/Z5v/8vpfVIL9zkDdF1QE/Q8ijup sA07WvuWzUDI63wJ9MljJCnen/b7yDQMM8WDVLOoYohV2+d2QXr8jpVKj9VKkW6BApZ7 xdaFmhlSieaKetPmt7X6JHnI0iC6KZP2oI6faJqZaP8ZSh6PygtbC9F/JQGmFR8ci3KH IDAVUtD3dFCy638tb3zqIFGAkpiYdnR2U6fg15TRpQ0igWAfsnAv6C7tRaJOaib24lPi u6WZyAbiPtLMK5qwufhPlXq/oS1U3545dTsrt002CGZL4GZ5jQbcrKFh62ZIzowxPw0o ogmA== X-Gm-Message-State: AIVw110z7p5EjflncZw5p3v/tAn6wCJZfZJnCHK5wWR6wzet79/xQM9L k0wXfBoEYynvIwNB6zA= X-Received: by 10.98.63.204 with SMTP id z73mr809560pfj.278.1501813239640; Thu, 03 Aug 2017 19:20:39 -0700 (PDT) Received: from localhost.localdomain ([118.189.148.187]) by smtp.gmail.com with ESMTPSA id v62sm403738pfb.170.2017.08.03.19.20.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 03 Aug 2017 19:20:38 -0700 (PDT) From: Zhongze Liu To: xen-devel@lists.xen.org Date: Fri, 4 Aug 2017 10:20:23 +0800 Message-Id: <20170804022025.25293-3-blackskygg@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170804022025.25293-1-blackskygg@gmail.com> References: <20170804022025.25293-1-blackskygg@gmail.com> Cc: Stefano Stabellini , Wei Liu , Zhongze Liu , George Dunlap , Andrew Cooper , Ian Jackson , Tim Deegan , Julien Grall , Jan Beulich Subject: [Xen-devel] [RFC PATCH 2/4] libxl:xl: add parsing code to parse "libxl_static_sshm" from xl config files X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add the parsing utils for the newly introduced libxl_static_sshm struct to the libxl/libxlu_* family. And add realated parsing code in xl to parse the struct from xl config files. This is for the proposal "Allow setting up shared memory areas between VMs from xl config file" (see [1]). [1] https://lists.xenproject.org/archives/html/xen-devel/2017-07/msg03047.html Signed-off-by: Zhongze Liu --- Cc: Andrew Cooper Cc: George Dunlap Cc: Ian Jackson Cc: Jan Beulich Cc: Konrad Rzeszutek Wilk Cc: Stefano Stabellini Cc: Tim Deegan Cc: Wei Liu Cc: Julien Grall Cc: xen-devel@lists.xen.org --- tools/libxl/Makefile | 2 +- tools/libxl/libxlu_sshm.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++ tools/libxl/libxlutil.h | 6 ++ tools/xl/xl_parse.c | 24 ++++- 4 files changed, 258 insertions(+), 2 deletions(-) create mode 100644 tools/libxl/libxlu_sshm.c diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile index 082af8f716..3b63fb2cad 100644 --- a/tools/libxl/Makefile +++ b/tools/libxl/Makefile @@ -175,7 +175,7 @@ AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h _libxl_list.h _paths.h \ AUTOSRCS= libxlu_cfg_y.c libxlu_cfg_l.c AUTOSRCS += _libxl_save_msgs_callout.c _libxl_save_msgs_helper.c LIBXLU_OBJS = libxlu_cfg_y.o libxlu_cfg_l.o libxlu_cfg.o \ - libxlu_disk_l.o libxlu_disk.o libxlu_vif.o libxlu_pci.o + libxlu_disk_l.o libxlu_disk.o libxlu_vif.o libxlu_pci.o libxlu_sshm.o $(LIBXLU_OBJS): CFLAGS += $(CFLAGS_libxenctrl) # For xentoollog.h $(TEST_PROG_OBJS) _libxl.api-for-check: CFLAGS += $(CFLAGS_libxentoollog) diff --git a/tools/libxl/libxlu_sshm.c b/tools/libxl/libxlu_sshm.c new file mode 100644 index 0000000000..2f2e6f3866 --- /dev/null +++ b/tools/libxl/libxlu_sshm.c @@ -0,0 +1,228 @@ +#include "libxl_osdeps.h" /* must come before any other headers */ +#include "libxlu_internal.h" + +#include + +#define PARAM_RE(EXPR) "^\\s*" EXPR "\\s*(,|$)" +#define WORD_RE "([_a-zA-Z0-9]+)" +#define EQU_RE PARAM_RE(WORD_RE "\\s*=\\s*" WORD_RE) + +#define PAGE_SIZE_MASK ((uint64_t)0xfff) + +#define RET_INVAL(msg, curr_str) do { \ + xlu__sshm_err(cfg, msg, curr_str); \ + rc = EINVAL; \ + goto out; \ + } while(0) + +/* set a member in libxl_static_shm and report an error if it's respecified, + * @curr_str indicates the head of the remaining string. */ +#define SET_VAL(var, name, type, value, curr_str) do { \ + if ((var) != LIBXL_SSHM_##type##_UNKNOWN && (var) != value) { \ + RET_INVAL("\"" name "\" respecified", curr_str); \ + } \ + (var) = value; \ + } while(0) + + +static void xlu__sshm_err(XLU_Config *cfg, const char *msg, + const char *curr_str) { + fprintf(cfg->report, + "%s: config parsing error in shared_memory: %s at '%s'\n", + cfg->config_source, msg, curr_str); +} + +static int parse_prot(XLU_Config *cfg, char *str, libxl_sshm_prot *prot) +{ + int rc; + libxl_sshm_prot new_prot; + + if (!strcmp(str, "rw")) { + new_prot = LIBXL_SSHM_PROT_RW; + } else { + RET_INVAL("invalid permission flags", str); + } + + SET_VAL(*prot, "permission flags", PROT, new_prot, str); + + rc = 0; + + out: + return rc; +} + +static int parse_cachepolicy(XLU_Config *cfg, char *str, + libxl_sshm_cachepolicy *policy) +{ + int rc; + libxl_sshm_cachepolicy new_policy; + + if (!strcmp(str, "ARM_normal")) { + new_policy = LIBXL_SSHM_CACHEPOLICY_ARM_NORMAL; + } else if (!strcmp(str, "x86_normal")) { + new_policy = LIBXL_SSHM_CACHEPOLICY_X86_NORMAL; + } else { + RET_INVAL("invalid cache policy", str); + } + + SET_VAL(*policy, "cache policy", CACHEPOLICY, new_policy, str); + rc = 0; + + out: + return rc; +} + +/* handle key = value pairs */ +static int handle_equ(XLU_Config *cfg, char *key, char *val, + libxl_static_shm *sshm) +{ + int rc; + + if (!strcmp(key, "id")) { + if (strlen(val) > LIBXL_SSHM_ID_MAXLEN) { RET_INVAL("id too long", val); } + if (sshm->id && !strcmp(sshm->id, val)) { + RET_INVAL("id respecified", val); + } + + if (NULL == (sshm->id = strdup(val))) { + fprintf(stderr, "sshm parser out of memory\n"); + rc = ENOMEM; + goto out; + } + } else if (!strcmp(key, "role")) { + libxl_sshm_role new_role; + + if (!strcmp("master", val)) { + new_role = LIBXL_SSHM_ROLE_MASTER; + } else if (!strcmp("slave", val)) { + new_role = LIBXL_SSHM_ROLE_SLAVE; + } else { + RET_INVAL("invalid role", val); + } + + SET_VAL(sshm->role, "role", ROLE, new_role, val); + } else if (!strcmp(key, "begin") || + !strcmp(key, "end") || + !strcmp(key, "offset")) { + char *endptr; + int base = 10; + uint64_t new_addr; + + /* Could be in hex form. Note that we don't need to check the length here, + * for val[] is NULL-terminated */ + if ('0' == val[0] && 'x' == val[1]) { base = 16; } + new_addr = strtoull(val, &endptr, base); + if (ERANGE == errno || *endptr) { + RET_INVAL("invalid begin/end/offset", val); + } + if (new_addr & PAGE_SIZE_MASK) + RET_INVAL("begin/end/offset is not a multiple of 4K", val); + + /* begin or end */ + if ('b' == key[0]) { + SET_VAL(sshm->begin, "beginning address", RANGE, new_addr, val); + } else if('e' == key[0]){ + SET_VAL(sshm->end, "ending address", RANGE, new_addr, val); + } else { + SET_VAL(sshm->offset, "offset", RANGE, new_addr, val); + } + } else if (!strcmp(key, "prot")) { + rc = parse_prot(cfg, val, &sshm->prot); + if (rc) { goto out; } + } else if (!strcmp(key, "cache_policy")) { + rc = parse_cachepolicy(cfg, val, &sshm->cache_policy); + if (rc) { goto out; } + } else { + RET_INVAL("invalid option", key); + } + + rc = 0; + + out: + return rc; +} + +int xlu_sshm_parse(XLU_Config *cfg, const char *spec, + libxl_static_shm *sshm) +{ + int rc; + regex_t equ_rec; + char *buf2 = NULL, *ptr = NULL; + regmatch_t pmatch[3]; + + rc = regcomp(&equ_rec, EQU_RE, REG_EXTENDED); + if (rc) { + fprintf(stderr, "sshm parser failed to initialize\n"); + goto out; + } + + if (NULL == (buf2 = ptr = strdup(spec))) { + fprintf(stderr, "sshm parser out of memory\n"); + rc = ENOMEM; + goto out; + } + + /* main parsing loop */ + while (true) { + if (!*ptr) { break; } + if (regexec(&equ_rec, ptr, 3, pmatch, 0)) + RET_INVAL("unrecognized token", ptr); + + ptr[pmatch[1].rm_eo] = '\0'; + ptr[pmatch[2].rm_eo] = '\0'; + rc = handle_equ(cfg, ptr + pmatch[1].rm_so, + ptr + pmatch[2].rm_so, sshm); + if (rc) { goto out; } + + ptr += pmatch[0].rm_eo; + } + + if (*ptr) { RET_INVAL("invalid syntax", ptr); } + + /* do some early checks and set defaults */ + if (!sshm->id) { + RET_INVAL("id not specified", spec); + } + if (LIBXL_SSHM_ROLE_UNKNOWN == sshm->role) { + sshm->role = LIBXL_SSHM_ROLE_SLAVE; + } + if (LIBXL_SSHM_PROT_UNKNOWN == sshm->prot) { + sshm->prot = LIBXL_SSHM_PROT_RW; + } + if (LIBXL_SSHM_RANGE_UNKNOWN == sshm->begin) { + RET_INVAL("begin address not specified", spec); + } + if (LIBXL_SSHM_RANGE_UNKNOWN == sshm->end) { + RET_INVAL("end address not specified", spec); + } + if (sshm->begin > sshm->end) { + RET_INVAL("begin address larger that end address", spec); + } + if (LIBXL_SSHM_ROLE_SLAVE != sshm->role && + LIBXL_SSHM_RANGE_UNKNOWN != sshm->offset) { + RET_INVAL("offset is only applicable to slave domains", spec); + sshm->offset = 0; + } + if (LIBXL_SSHM_RANGE_UNKNOWN == sshm->offset) { + sshm->offset = 0; + } + if (LIBXL_SSHM_ROLE_MASTER != sshm->role && + LIBXL_SSHM_CACHEPOLICY_UNKNOWN != sshm->cache_policy) { + RET_INVAL("cache_policy is only applicable to master domains", spec); + } + + rc = 0; + + out: + if (buf2) { free(buf2); } + regfree(&equ_rec); + return rc; +} + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libxl/libxlutil.h b/tools/libxl/libxlutil.h index e81b644c01..ee39cb5bdc 100644 --- a/tools/libxl/libxlutil.h +++ b/tools/libxl/libxlutil.h @@ -118,6 +118,12 @@ int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str); int xlu_vif_parse_rate(XLU_Config *cfg, const char *rate, libxl_device_nic *nic); +/* + * static shared memory specification parsing + */ +int xlu_sshm_parse(XLU_Config *cfg, const char *spec, + libxl_static_shm *sshm); + #endif /* LIBXLUTIL_H */ /* diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c index 5c2bf17222..82d955b8b9 100644 --- a/tools/xl/xl_parse.c +++ b/tools/xl/xl_parse.c @@ -813,7 +813,7 @@ void parse_config_data(const char *config_source, long l, vcpus = 0; XLU_Config *config; XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms, - *usbctrls, *usbdevs, *p9devs; + *usbctrls, *usbdevs, *p9devs, *sshms; XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian, *dtdevs, *mca_caps; int num_ioports, num_irqs, num_iomem, num_cpus, num_viridian, num_mca_caps; @@ -1392,6 +1392,28 @@ void parse_config_data(const char *config_source, } } + if (!xlu_cfg_get_list (config, "static_shm", &sshms, 0, 0)) { + d_config->num_sshms = 0; + d_config->sshms = NULL; + while ((buf = xlu_cfg_get_listitem (sshms, d_config->num_sshms)) != NULL) { + libxl_static_shm *sshm; + char *buf2 = strdup(buf); + int ret; + + sshm = ARRAY_EXTEND_INIT_NODEVID(d_config->sshms, + d_config->num_sshms, + libxl_static_shm_init); + ret = xlu_sshm_parse(config, buf2, sshm); + if (ret) { + fprintf(stderr, + "xl: Invalid argument for static_shm: %s", buf2); + exit(EXIT_FAILURE); + } + + free(buf2); + } + } + if (!xlu_cfg_get_list(config, "p9", &p9devs, 0, 0)) { libxl_device_p9 *p9; char *security_model = NULL;