diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h
index 683596797b51..e23908d98764 100644
--- a/fsdev/file-op-9p.h
+++ b/fsdev/file-op-9p.h
@@ -147,6 +147,8 @@ struct FileOperations
     int (*fchmod)(FsContext *, int, V9fsFidOpenState *, FsCred *);
     ssize_t (*fgetxattr)(FsContext *, int, V9fsFidOpenState *,
                          const char *, void *, size_t);
+    ssize_t (*flistxattr)(FsContext *, int, V9fsFidOpenState *,
+                          void *, size_t);
     void *opaque;
 };
 
diff --git a/hw/9pfs/9p-handle.c b/hw/9pfs/9p-handle.c
index 3153acff663c..d17d9a8ff008 100644
--- a/hw/9pfs/9p-handle.c
+++ b/hw/9pfs/9p-handle.c
@@ -502,6 +502,15 @@ static ssize_t handle_llistxattr(FsContext *ctx, V9fsPath *fs_path,
     return ret;
 }
 
+static ssize_t handle_flistxattr(FsContext *ctx, int fid_type,
+                                 V9fsFidOpenState *fs, void *value, size_t size)
+{
+    int fd;
+
+    fd = v9fs_get_fd_fid(fid_type, fs);
+    return flistxattr(fd, value, size);
+}
+
 static int handle_lsetxattr(FsContext *ctx, V9fsPath *fs_path, const char *name,
                             void *value, size_t size, int flags)
 {
@@ -747,4 +756,5 @@ FileOperations handle_ops = {
     .fchown       = handle_fchown,
     .fchmod       = handle_fchmod,
     .fgetxattr    = handle_fgetxattr,
+    .flistxattr   = handle_flistxattr,
 };
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index 206849a3ed83..3a1caeccdf00 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -1122,6 +1122,15 @@ static ssize_t local_llistxattr(FsContext *ctx, V9fsPath *fs_path,
     return v9fs_list_xattr(ctx, -1, path, value, size);
 }
 
+static ssize_t local_flistxattr(FsContext *ctx, int fid_type,
+                                V9fsFidOpenState *fs, void *value, size_t size)
+{
+    int fd;
+
+    fd = v9fs_get_fd_fid(fid_type, fs);
+    return v9fs_list_xattr(ctx, fd, NULL, value, size);
+}
+
 static int local_lsetxattr(FsContext *ctx, V9fsPath *fs_path, const char *name,
                            void *value, size_t size, int flags)
 {
@@ -1368,4 +1377,5 @@ FileOperations local_ops = {
     .fchown = local_fchown,
     .fchmod = local_fchmod,
     .fgetxattr = local_fgetxattr,
+    .flistxattr = local_flistxattr,
 };
diff --git a/hw/9pfs/9p-proxy.c b/hw/9pfs/9p-proxy.c
index 074799027873..94ee76f1fbf6 100644
--- a/hw/9pfs/9p-proxy.c
+++ b/hw/9pfs/9p-proxy.c
@@ -1029,6 +1029,15 @@ static ssize_t proxy_llistxattr(FsContext *ctx, V9fsPath *fs_path,
     return retval;
 }
 
+static ssize_t proxy_flistxattr(FsContext *ctx, int fid_type,
+                                V9fsFidOpenState *fs, void *value, size_t size)
+{
+    int fd;
+
+    fd = v9fs_get_fd_fid(fid_type, fs);
+    return flistxattr(fd, value, size);
+}
+
 static int proxy_lsetxattr(FsContext *ctx, V9fsPath *fs_path, const char *name,
                            void *value, size_t size, int flags)
 {
@@ -1263,4 +1272,5 @@ FileOperations proxy_ops = {
     .fchown       = proxy_fchown,
     .fchmod       = proxy_fchmod,
     .fgetxattr    = proxy_fgetxattr,
+    .flistxattr   = proxy_flistxattr,
 };
diff --git a/hw/9pfs/9p-synth.c b/hw/9pfs/9p-synth.c
index 24505fc2f621..9cd098914d08 100644
--- a/hw/9pfs/9p-synth.c
+++ b/hw/9pfs/9p-synth.c
@@ -479,6 +479,13 @@ static ssize_t synth_llistxattr(FsContext *ctx, V9fsPath *path,
     return -1;
 }
 
+static ssize_t synth_flistxattr(FsContext *ctx, int fid_type,
+                                V9fsFidOpenState *fs, void *value, size_t size)
+{
+    errno = ENOTSUP;
+    return -1;
+}
+
 static int synth_lsetxattr(FsContext *ctx, V9fsPath *path,
                                 const char *name, void *value,
                                 size_t size, int flags)
@@ -607,4 +614,5 @@ FileOperations synth_ops = {
     .fchown       = synth_fchown,
     .fchmod       = synth_fchmod,
     .fgetxattr    = synth_fgetxattr,
+    .flistxattr   = synth_flistxattr,
 };
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index 435100f85be3..14aee2e749d8 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -3125,6 +3125,16 @@ static int v9fs_do_getxattr(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name,
     }
 }
 
+static int v9fs_do_listxattr(V9fsPDU *pdu, V9fsFidState *fidp, void *value,
+                             size_t size)
+{
+    if (fid_has_file(fidp)) {
+        return v9fs_co_flistxattr(pdu, fidp, value, size);
+    } else {
+        return v9fs_co_llistxattr(pdu, &fidp->path, value, size);
+    }
+}
+
 static void v9fs_xattrwalk(void *opaque)
 {
     int64_t size;
@@ -3163,7 +3173,7 @@ static void v9fs_xattrwalk(void *opaque)
         /*
          * listxattr request. Get the size first
          */
-        size = v9fs_co_llistxattr(pdu, &xattr_fidp->path, NULL, 0);
+        size = v9fs_do_listxattr(pdu, xattr_fidp, NULL, 0);
         if (size < 0) {
             err = size;
             clunk_fid(s, xattr_fidp->fid);
@@ -3175,9 +3185,9 @@ static void v9fs_xattrwalk(void *opaque)
         xattr_fidp->fs.xattr.len = size;
         if (size) {
             xattr_fidp->fs.xattr.value = g_malloc(size);
-            err = v9fs_co_llistxattr(pdu, &xattr_fidp->path,
-                                     xattr_fidp->fs.xattr.value,
-                                     xattr_fidp->fs.xattr.len);
+            err = v9fs_do_listxattr(pdu, xattr_fidp,
+                                    xattr_fidp->fs.xattr.value,
+                                    xattr_fidp->fs.xattr.len);
             if (err < 0) {
                 clunk_fid(s, xattr_fidp->fid);
                 goto out;
diff --git a/hw/9pfs/coth.h b/hw/9pfs/coth.h
index 2e507939d01d..ddb061d91ed3 100644
--- a/hw/9pfs/coth.h
+++ b/hw/9pfs/coth.h
@@ -100,5 +100,6 @@ extern int v9fs_co_fchown(V9fsPDU *, V9fsFidState *, uid_t, gid_t);
 extern int v9fs_co_fchmod(V9fsPDU *, V9fsFidState *, mode_t);
 extern int v9fs_co_fgetxattr(V9fsPDU *, V9fsFidState *, V9fsString *, void *,
                              size_t);
+extern int v9fs_co_flistxattr(V9fsPDU *, V9fsFidState *, void *, size_t);
 
 #endif
diff --git a/hw/9pfs/coxattr.c b/hw/9pfs/coxattr.c
index 72e3f38fb371..f4944e6abae3 100644
--- a/hw/9pfs/coxattr.c
+++ b/hw/9pfs/coxattr.c
@@ -37,6 +37,26 @@ int v9fs_co_llistxattr(V9fsPDU *pdu, V9fsPath *path, void *value, size_t size)
     return err;
 }
 
+int v9fs_co_flistxattr(V9fsPDU *pdu, V9fsFidState *fidp, void *value,
+                       size_t size)
+{
+    int err;
+    V9fsState *s = pdu->s;
+
+    if (v9fs_request_cancelled(pdu)) {
+        return -EINTR;
+    }
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->flistxattr(&s->ctx, fidp->fid_type, &fidp->fs, value,
+                                     size);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
+
 int v9fs_co_lgetxattr(V9fsPDU *pdu, V9fsPath *path,
                       V9fsString *xattr_name,
                       void *value, size_t size)
