From nobody Mon Feb 9 16:51:25 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=suse.com ARC-Seal: i=1; a=rsa-sha256; t=1603703650; cv=none; d=zohomail.com; s=zohoarc; b=n6QVWIHhXZC6k40ZR4yCq5zXoQxOZFf+Bj7XJoDBgRp2JE4qP5hQ1RZ557KaCBNomBDY2p2Fj3JYySthA19mSfApcmLITes/5aEhFH7CIxs/E3mdNCLU/cU0FQNTeYzC4ZfX6hdCDoBeTe4KCz0k8ND3NM9QDXxrp79Zc5fBDR0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1603703650; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=wzVfNJp5CakgtQPXKcxiHB74zrzQZ4Nkcj6JZDwDa6k=; b=eC+maw+99BJQOLlOwiFSDSB+EHW0pOzaFs1wlFf7zG8JUlmgzj9zPL3/Jjx6esfT2W/xqqRPrZOLlrNJAjIWH2gA8tEV+wKJlEAd+0eMcteFWVH5Bj1sAkXj/AtVj8Ys9SXkUoEqwNmOUNphJkmbM3x+hkuKl9m3XCjjH9SJnv4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1603703650703889.4663308398843; Mon, 26 Oct 2020 02:14:10 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.12094.31771 (Exim 4.92) (envelope-from ) id 1kWyZc-0005YX-CE; Mon, 26 Oct 2020 09:13:52 +0000 Received: by outflank-mailman (output) from mailman id 12094.31771; Mon, 26 Oct 2020 09:13:52 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kWyZc-0005YM-7e; Mon, 26 Oct 2020 09:13:52 +0000 Received: by outflank-mailman (input) for mailman id 12094; Mon, 26 Oct 2020 09:13:50 +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 1kWyZa-0004f1-SN for xen-devel@lists.xenproject.org; Mon, 26 Oct 2020 09:13:50 +0000 Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id f9b3da22-e431-4730-8a0f-bb74a709d485; Mon, 26 Oct 2020 09:13:21 +0000 (UTC) Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 6BF8CB243; Mon, 26 Oct 2020 09:13:20 +0000 (UTC) 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 1kWyZa-0004f1-SN for xen-devel@lists.xenproject.org; Mon, 26 Oct 2020 09:13:50 +0000 Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id f9b3da22-e431-4730-8a0f-bb74a709d485; Mon, 26 Oct 2020 09:13:21 +0000 (UTC) Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 6BF8CB243; Mon, 26 Oct 2020 09:13:20 +0000 (UTC) X-Outflank-Mailman: Message body and most headers restored to incoming version 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: f9b3da22-e431-4730-8a0f-bb74a709d485 X-Virus-Scanned: by amavisd-new at test-mx.suse.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1603703600; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wzVfNJp5CakgtQPXKcxiHB74zrzQZ4Nkcj6JZDwDa6k=; b=NL/En86Zerx/XqAPLdxbToE9TgYiblPWaYJYlvTQW/RutFLZdUPGjUNGDbRYDww7CLqc7r X2yqGr+HsQeFQdmmqvJebYLtfoEo0/6ClP/pPX9+Irr9DTLuodyTR9hf7mFBCBOhSVbTNl ZZq/IZykawDZMb56HpOMdFrv1W4coS0= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Andrew Cooper , George Dunlap , Ian Jackson , Jan Beulich , Julien Grall , Stefano Stabellini , Wei Liu Subject: [PATCH 08/12] xen/hypfs: support dynamic hypfs nodes Date: Mon, 26 Oct 2020 10:13:12 +0100 Message-Id: <20201026091316.25680-9-jgross@suse.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201026091316.25680-1-jgross@suse.com> References: <20201026091316.25680-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) Content-Type: text/plain; charset="utf-8" Add a getsize() function pointer to struct hypfs_funcs for being able to have dynamically filled entries without the need to take the hypfs lock each time the contents are being generated. For directories add a findentry callback to the vector and modify hypfs_get_entry_rel() to use it. Add a HYPFS_VARDIR_INIT() macro for intializing such a directory statically, taking a struct hypfs_funcs pointer as parameter additional to those of HYPFS_DIR_INIT(). Modify HYPFS_VARSIZE_INIT() to take the function vector pointer as an additional parameter as this will be needed for dynamical entries. Move DIRENTRY_SIZE() macro to hypfs.h as it will be needed by the read function of a directory with dynamically generated entries. For being able to let the generic hypfs coding continue to work on normal struct hypfs_entry entities even for dynamical nodes add some infrastructure for allocating a working area for the current hypfs request in order to store needed information for traversing the tree. This area is anchored in a percpu pointer and can be retrieved by any level of the dynamic entries. It will be freed automatically when dropping the hypfs lock. Signed-off-by: Juergen Gross --- xen/common/hypfs.c | 124 +++++++++++++++++++++++++--------------- xen/include/xen/hypfs.h | 39 +++++++++---- 2 files changed, 108 insertions(+), 55 deletions(-) diff --git a/xen/common/hypfs.c b/xen/common/hypfs.c index 97260bd4a3..4c226a06b4 100644 --- a/xen/common/hypfs.c +++ b/xen/common/hypfs.c @@ -19,28 +19,29 @@ CHECK_hypfs_dirlistentry; #endif =20 -#define DIRENTRY_NAME_OFF offsetof(struct xen_hypfs_dirlistentry, name) -#define DIRENTRY_SIZE(name_len) \ - (DIRENTRY_NAME_OFF + \ - ROUNDUP((name_len) + 1, alignof(struct xen_hypfs_direntry))) - struct hypfs_funcs hypfs_dir_funcs =3D { .read =3D hypfs_read_dir, + .getsize =3D hypfs_getsize, + .findentry =3D hypfs_dir_findentry, }; struct hypfs_funcs hypfs_leaf_ro_funcs =3D { .read =3D hypfs_read_leaf, + .getsize =3D hypfs_getsize, }; struct hypfs_funcs hypfs_leaf_wr_funcs =3D { .read =3D hypfs_read_leaf, .write =3D hypfs_write_leaf, + .getsize =3D hypfs_getsize, }; struct hypfs_funcs hypfs_bool_wr_funcs =3D { .read =3D hypfs_read_leaf, .write =3D hypfs_write_bool, + .getsize =3D hypfs_getsize, }; struct hypfs_funcs hypfs_custom_wr_funcs =3D { .read =3D hypfs_read_leaf, .write =3D hypfs_write_custom, + .getsize =3D hypfs_getsize, }; =20 static DEFINE_RWLOCK(hypfs_lock); @@ -50,6 +51,7 @@ enum hypfs_lock_state { hypfs_write_locked }; static DEFINE_PER_CPU(enum hypfs_lock_state, hypfs_locked); +static DEFINE_PER_CPU(void *, hypfs_dyndata); =20 HYPFS_DIR_INIT(hypfs_root, ""); =20 @@ -71,9 +73,12 @@ static void hypfs_write_lock(void) =20 static void hypfs_unlock(void) { - enum hypfs_lock_state locked =3D this_cpu(hypfs_locked); + unsigned int cpu =3D smp_processor_id(); + enum hypfs_lock_state locked =3D per_cpu(hypfs_locked, cpu); + + XFREE(per_cpu(hypfs_dyndata, cpu)); =20 - this_cpu(hypfs_locked) =3D hypfs_unlocked; + per_cpu(hypfs_locked, cpu) =3D hypfs_unlocked; =20 switch ( locked ) { @@ -88,6 +93,23 @@ static void hypfs_unlock(void) } } =20 +void *hypfs_alloc_dyndata(unsigned long size, unsigned long align) +{ + unsigned int cpu =3D smp_processor_id(); + + ASSERT(per_cpu(hypfs_locked, cpu) !=3D hypfs_unlocked); + ASSERT(per_cpu(hypfs_dyndata, cpu) =3D=3D NULL); + + per_cpu(hypfs_dyndata, cpu) =3D _xzalloc(size, align); + + return per_cpu(hypfs_dyndata, cpu); +} + +void *hypfs_get_dyndata(void) +{ + return this_cpu(hypfs_dyndata); +} + static int add_entry(struct hypfs_entry_dir *parent, struct hypfs_entry *n= ew) { int ret =3D -ENOENT; @@ -122,7 +144,7 @@ static int add_entry(struct hypfs_entry_dir *parent, st= ruct hypfs_entry *new) { unsigned int sz =3D strlen(new->name); =20 - parent->e.size +=3D DIRENTRY_SIZE(sz); + parent->e.size +=3D HYPFS_DIRENTRY_SIZE(sz); } =20 hypfs_unlock(); @@ -171,15 +193,34 @@ static int hypfs_get_path_user(char *buf, return 0; } =20 +struct hypfs_entry *hypfs_dir_findentry(struct hypfs_entry_dir *dir, + const char *name, + unsigned int name_len) +{ + struct hypfs_entry *entry; + + list_for_each_entry ( entry, &dir->dirlist, list ) + { + int cmp =3D strncmp(name, entry->name, name_len); + + if ( cmp < 0 ) + return ERR_PTR(-ENOENT); + + if ( !cmp && strlen(entry->name) =3D=3D name_len ) + return entry; + } + + return ERR_PTR(-ENOENT); +} + static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir, const char *path) { const char *end; struct hypfs_entry *entry; unsigned int name_len; - bool again =3D true; =20 - while ( again ) + for ( ;; ) { if ( dir->e.type !=3D XEN_HYPFS_TYPE_DIR ) return ERR_PTR(-ENOENT); @@ -192,28 +233,12 @@ static struct hypfs_entry *hypfs_get_entry_rel(struct= hypfs_entry_dir *dir, end =3D strchr(path, '\0'); name_len =3D end - path; =20 - again =3D false; + entry =3D dir->e.funcs->findentry(dir, path, name_len); + if ( IS_ERR(entry) || !*end ) + return entry; =20 - list_for_each_entry ( entry, &dir->dirlist, list ) - { - int cmp =3D strncmp(path, entry->name, name_len); - struct hypfs_entry_dir *d =3D container_of(entry, - struct hypfs_entry_di= r, e); - - if ( cmp < 0 ) - return ERR_PTR(-ENOENT); - if ( !cmp && strlen(entry->name) =3D=3D name_len ) - { - if ( !*end ) - return entry; - - again =3D true; - dir =3D d; - path =3D end + 1; - - break; - } - } + path =3D end + 1; + dir =3D container_of(entry, struct hypfs_entry_dir, e); } =20 return ERR_PTR(-ENOENT); @@ -227,12 +252,17 @@ static struct hypfs_entry *hypfs_get_entry(const char= *path) return hypfs_get_entry_rel(&hypfs_root, path + 1); } =20 +unsigned int hypfs_getsize(const struct hypfs_entry *entry) +{ + return entry->size; +} + int hypfs_read_dir(const struct hypfs_entry *entry, XEN_GUEST_HANDLE_PARAM(void) uaddr) { const struct hypfs_entry_dir *d; const struct hypfs_entry *e; - unsigned int size =3D entry->size; + unsigned int size =3D entry->funcs->getsize(entry); =20 ASSERT(this_cpu(hypfs_locked) !=3D hypfs_unlocked); =20 @@ -242,18 +272,18 @@ int hypfs_read_dir(const struct hypfs_entry *entry, { struct xen_hypfs_dirlistentry direntry; unsigned int e_namelen =3D strlen(e->name); - unsigned int e_len =3D DIRENTRY_SIZE(e_namelen); + unsigned int e_len =3D HYPFS_DIRENTRY_SIZE(e_namelen); =20 direntry.e.pad =3D 0; direntry.e.type =3D e->type; direntry.e.encoding =3D e->encoding; - direntry.e.content_len =3D e->size; + direntry.e.content_len =3D e->funcs->getsize(e); direntry.e.max_write_len =3D e->max_size; direntry.off_next =3D list_is_last(&e->list, &d->dirlist) ? 0 : e_= len; if ( copy_to_guest(uaddr, &direntry, 1) ) return -EFAULT; =20 - if ( copy_to_guest_offset(uaddr, DIRENTRY_NAME_OFF, + if ( copy_to_guest_offset(uaddr, HYPFS_DIRENTRY_NAME_OFF, e->name, e_namelen + 1) ) return -EFAULT; =20 @@ -275,22 +305,25 @@ int hypfs_read_leaf(const struct hypfs_entry *entry, =20 l =3D container_of(entry, const struct hypfs_entry_leaf, e); =20 - return copy_to_guest(uaddr, l->u.content, entry->size) ? -EFAULT: 0; + return copy_to_guest(uaddr, l->u.content, entry->funcs->getsize(entry)= ) ? + -EFAULT : 0; } =20 static int hypfs_read(const struct hypfs_entry *entry, XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ul= en) { struct xen_hypfs_direntry e; + unsigned int size; long ret =3D -EINVAL; =20 if ( ulen < sizeof(e) ) goto out; =20 + size =3D entry->funcs->getsize(entry); e.pad =3D 0; e.type =3D entry->type; e.encoding =3D entry->encoding; - e.content_len =3D entry->size; + e.content_len =3D size; e.max_write_len =3D entry->max_size; =20 ret =3D -EFAULT; @@ -298,7 +331,7 @@ static int hypfs_read(const struct hypfs_entry *entry, goto out; =20 ret =3D -ENOBUFS; - if ( ulen < entry->size + sizeof(e) ) + if ( ulen < size + sizeof(e) ) goto out; =20 guest_handle_add_offset(uaddr, sizeof(e)); @@ -314,14 +347,15 @@ int hypfs_write_leaf(struct hypfs_entry_leaf *leaf, { char *buf; int ret; + struct hypfs_entry *e =3D &leaf->e; =20 ASSERT(this_cpu(hypfs_locked) =3D=3D hypfs_write_locked); =20 - if ( ulen > leaf->e.max_size ) + if ( ulen > e->max_size ) return -ENOSPC; =20 - if ( leaf->e.type !=3D XEN_HYPFS_TYPE_STRING && - leaf->e.type !=3D XEN_HYPFS_TYPE_BLOB && ulen !=3D leaf->e.size ) + if ( e->type !=3D XEN_HYPFS_TYPE_STRING && + e->type !=3D XEN_HYPFS_TYPE_BLOB && ulen !=3D e->funcs->getsize(e= ) ) return -EDOM; =20 buf =3D xmalloc_array(char, ulen); @@ -333,14 +367,14 @@ int hypfs_write_leaf(struct hypfs_entry_leaf *leaf, goto out; =20 ret =3D -EINVAL; - if ( leaf->e.type =3D=3D XEN_HYPFS_TYPE_STRING && - leaf->e.encoding =3D=3D XEN_HYPFS_ENC_PLAIN && + if ( e->type =3D=3D XEN_HYPFS_TYPE_STRING && + e->encoding =3D=3D XEN_HYPFS_ENC_PLAIN && memchr(buf, 0, ulen) !=3D (buf + ulen - 1) ) goto out; =20 ret =3D 0; memcpy(leaf->u.write_ptr, buf, ulen); - leaf->e.size =3D ulen; + e->size =3D ulen; =20 out: xfree(buf); @@ -354,7 +388,7 @@ int hypfs_write_bool(struct hypfs_entry_leaf *leaf, =20 ASSERT(this_cpu(hypfs_locked) =3D=3D hypfs_write_locked); ASSERT(leaf->e.type =3D=3D XEN_HYPFS_TYPE_BOOL && - leaf->e.size =3D=3D sizeof(bool) && + leaf->e.funcs->getsize(&leaf->e) =3D=3D sizeof(bool) && leaf->e.max_size =3D=3D sizeof(bool) ); =20 if ( ulen !=3D leaf->e.max_size ) diff --git a/xen/include/xen/hypfs.h b/xen/include/xen/hypfs.h index 77916ebb58..c8999b5381 100644 --- a/xen/include/xen/hypfs.h +++ b/xen/include/xen/hypfs.h @@ -2,11 +2,13 @@ #define __XEN_HYPFS_H__ =20 #ifdef CONFIG_HYPFS +#include #include #include #include =20 struct hypfs_entry_leaf; +struct hypfs_entry_dir; struct hypfs_entry; =20 struct hypfs_funcs { @@ -14,6 +16,9 @@ struct hypfs_funcs { XEN_GUEST_HANDLE_PARAM(void) uaddr); int (*write)(struct hypfs_entry_leaf *leaf, XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen); + unsigned int (*getsize)(const struct hypfs_entry *entry); + struct hypfs_entry *(*findentry)(struct hypfs_entry_dir *dir, + const char *name, unsigned int name_l= en); }; =20 extern struct hypfs_funcs hypfs_dir_funcs; @@ -45,7 +50,12 @@ struct hypfs_entry_dir { struct list_head dirlist; }; =20 -#define HYPFS_DIR_INIT(var, nam) \ +#define HYPFS_DIRENTRY_NAME_OFF offsetof(struct xen_hypfs_dirlistentry, na= me) +#define HYPFS_DIRENTRY_SIZE(name_len) \ + (HYPFS_DIRENTRY_NAME_OFF + \ + ROUNDUP((name_len) + 1, alignof(struct xen_hypfs_direntry))) + +#define HYPFS_VARDIR_INIT(var, nam, fn) \ struct hypfs_entry_dir __read_mostly var =3D { \ .e.type =3D XEN_HYPFS_TYPE_DIR, \ .e.encoding =3D XEN_HYPFS_ENC_PLAIN, \ @@ -53,22 +63,25 @@ struct hypfs_entry_dir { .e.size =3D 0, \ .e.max_size =3D 0, \ .e.list =3D LIST_HEAD_INIT(var.e.list), \ - .e.funcs =3D &hypfs_dir_funcs, \ + .e.funcs =3D (fn), \ .dirlist =3D LIST_HEAD_INIT(var.dirlist), \ } =20 -#define HYPFS_VARSIZE_INIT(var, typ, nam, msz) \ - struct hypfs_entry_leaf __read_mostly var =3D { \ - .e.type =3D (typ), \ - .e.encoding =3D XEN_HYPFS_ENC_PLAIN, \ - .e.name =3D (nam), \ - .e.max_size =3D (msz), \ - .e.funcs =3D &hypfs_leaf_ro_funcs, \ +#define HYPFS_DIR_INIT(var, nam) \ + HYPFS_VARDIR_INIT(var, nam, &hypfs_dir_funcs) + +#define HYPFS_VARSIZE_INIT(var, typ, nam, msz, fn) \ + struct hypfs_entry_leaf __read_mostly var =3D { \ + .e.type =3D (typ), \ + .e.encoding =3D XEN_HYPFS_ENC_PLAIN, \ + .e.name =3D (nam), \ + .e.max_size =3D (msz), \ + .e.funcs =3D (fn), \ } =20 /* Content and size need to be set via hypfs_string_set_reference(). */ #define HYPFS_STRING_INIT(var, nam) \ - HYPFS_VARSIZE_INIT(var, XEN_HYPFS_TYPE_STRING, nam, 0) + HYPFS_VARSIZE_INIT(var, XEN_HYPFS_TYPE_STRING, nam, 0, &hypfs_leaf_ro_= funcs) =20 /* * Set content and size of a XEN_HYPFS_TYPE_STRING node. The node will poi= nt @@ -131,6 +144,12 @@ int hypfs_write_bool(struct hypfs_entry_leaf *leaf, XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen= ); int hypfs_write_custom(struct hypfs_entry_leaf *leaf, XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ul= en); +unsigned int hypfs_getsize(const struct hypfs_entry *entry); +struct hypfs_entry *hypfs_dir_findentry(struct hypfs_entry_dir *dir, + const char *name, + unsigned int name_len); +void *hypfs_alloc_dyndata(unsigned long size, unsigned long align); +void *hypfs_get_dyndata(void); #endif =20 #endif /* __XEN_HYPFS_H__ */ --=20 2.26.2