Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2216424/?format=api
{ "id": 2216424, "url": "http://patchwork.ozlabs.org/api/patches/2216424/?format=api", "web_url": "http://patchwork.ozlabs.org/project/opensbi/patch/20260326115517.2156-2-dave.patel@riscstar.com/", "project": { "id": 67, "url": "http://patchwork.ozlabs.org/api/projects/67/?format=api", "name": "OpenSBI development", "link_name": "opensbi", "list_id": "opensbi.lists.infradead.org", "list_email": "opensbi@lists.infradead.org", "web_url": "https://github.com/riscv/opensbi", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "https://github.com/riscv/opensbi/commit/{}" }, "msgid": "<20260326115517.2156-2-dave.patel@riscstar.com>", "list_archive_url": null, "date": "2026-03-26T11:55:15", "name": "[v2,1/3] lib: sbi: Add RISC-V vector context save/restore support (eager switching)", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "403c69f3dfa84c484be5bf841d2c8b0234ede7a7", "submitter": { "id": 92617, "url": "http://patchwork.ozlabs.org/api/people/92617/?format=api", "name": "Dave Patel", "email": "dave.patel@riscstar.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/opensbi/patch/20260326115517.2156-2-dave.patel@riscstar.com/mbox/", "series": [ { "id": 497579, "url": "http://patchwork.ozlabs.org/api/series/497579/?format=api", "web_url": "http://patchwork.ozlabs.org/project/opensbi/list/?series=497579", "date": "2026-03-26T11:55:16", "name": "[v2,1/3] lib: sbi: Add RISC-V vector context save/restore support (eager switching)", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/497579/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2216424/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2216424/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n secure) header.d=lists.infradead.org header.i=@lists.infradead.org\n header.a=rsa-sha256 header.s=bombadil.20210309 header.b=p3S3/veQ;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=riscstar-com.20230601.gappssmtp.com\n header.i=@riscstar-com.20230601.gappssmtp.com header.a=rsa-sha256\n header.s=20230601 header.b=epwrgRyL;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=none (no SPF record) smtp.mailfrom=lists.infradead.org\n (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org;\n envelope-from=opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from bombadil.infradead.org (bombadil.infradead.org\n [IPv6:2607:7c80:54:3::133])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fhMgd3gs3z1yGP\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 26 Mar 2026 22:56:26 +1100 (AEDT)", "from localhost ([::1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1w5jJx-00000005O21-1Ynj;\n\tThu, 26 Mar 2026 11:56:17 +0000", "from mail-wr1-x42c.google.com ([2a00:1450:4864:20::42c])\n\tby bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1w5jJq-00000005Nzi-3hUK\n\tfor opensbi@lists.infradead.org;\n\tThu, 26 Mar 2026 11:56:13 +0000", "by mail-wr1-x42c.google.com with SMTP id\n ffacd0b85a97d-43b87970468so845586f8f.3\n for <opensbi@lists.infradead.org>;\n Thu, 26 Mar 2026 04:56:10 -0700 (PDT)", "from localhost.localdomain ([78.41.211.48])\n by smtp.gmail.com with ESMTPSA id\n ffacd0b85a97d-43b9194311asm8932438f8f.10.2026.03.26.04.56.07\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Thu, 26 Mar 2026 04:56:08 -0700 (PDT)" ], "DKIM-Signature": [ "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=lists.infradead.org; s=bombadil.20210309; h=Sender:\n\tContent-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:\n\tList-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:\n\tMessage-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:\n\tResent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:\n\tList-Owner; bh=JH0bygWS5Ozl+S9unqN6zwXXSvG5ltksWtDK6FQfvp0=; b=p3S3/veQp0zkxT\n\tWQ1EHWPgIL+SKJHhxfc3wJxjuz2X/M2yC66O2xYH5MvWJDF4EHxi345bB3fq67gM5STIB3BiRoKpe\n\t7UVY8nPVpsMB0EKvfgugeFRIPjjkCfB5cK0bZsrJmKW+HViVuqbLIod5/3U+ze+KteIeNhX5e0WJE\n\tQhESy0g2XYT3ygpxNKXkiOyPAwi169ttXRrGxKFnOVkwzVM/03hweY1ITXGuAofZ5S6cLavQyscm6\n\tUzgVLR6ZAIfiDSjonk9yfWvRHhcuNRpETwYjdbFkdE7u/k+dPtdoCR1+g0Drjq4QNn2mJeHz2NJxT\n\tRcGa52yYJZqMcdFyulhg==;", "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=riscstar-com.20230601.gappssmtp.com; s=20230601; t=1774526169;\n x=1775130969; darn=lists.infradead.org;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=hTia2gaspIkVn1xUnbC0Gk/iOJecqJvZko+OkOjjbHA=;\n b=epwrgRyL5OcnIJFZ471xjNz7tL7bw/u2hThjUM1uKUmotrKH4liT7LfXlu2dR21q3T\n jv5JC4rywzRJ39bfgLQBfXs5LnIe/4Y47+V2UpLHMKoLn6p4Yuzu+GzLLKMq58fFxmyC\n o+BrJdIGBMcRAOJSRkypfEr/OhUaXoVi3Xjcl/w5tvFoAw42SPGFK07yCZSXdaHTtYpi\n WY5d3SA3GeEa/LH5oNwnzE/vJ5PJT0/NMAqAXgrJ3RCPxqbnd2fWcG3J5mHCzYnt3WAk\n 93khGufUX7aB0LnEEYfgsgM7zHN2JaQBJHMlrcv65C7T+GjhrNZSaUe46wPaT3tm9f/H\n 0OAA==" ], "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1774526169; x=1775130969;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=hTia2gaspIkVn1xUnbC0Gk/iOJecqJvZko+OkOjjbHA=;\n b=ZuFjSTdROvwN4/EvPINPt6JZdM+umDPpG/qLwPme4aXUM8x3weZKMf+2kPKdMo+mOG\n Dhx8VXsZhxEyFyC5PF3Mxrtz0CdapElXOnlq2Gsy5RfsqWgPbGH/CrIby1kiOyPHBRzC\n oKnxQrBzyK9MDKC0zyJv1vS+QAkfEIj9Wu2pX/SMF/EhbI8TsthnoPeV4XU/NMtnnmq0\n 3+NrIHBy4tMvbRormCrotf7YwDN26WDXfnCvgbHBCOLrfIL9jBgE5TdlA1635c2UWEYu\n Qf5F8dKbe9AMRpr1/o89TFt/ZFT8zXvtWTiQ5u3QK7xIPzkrwFM6KJOPalj064ftAjjf\n jjiw==", "X-Forwarded-Encrypted": "i=1;\n AJvYcCVWF9DSTDiJ2l8adodmBDt9Y9HumniHURWkSsXbwx8LYMG1KPrw9oIISWvg2ogKfMXHICxU1HJq@lists.infradead.org", "X-Gm-Message-State": "AOJu0YwO7XUv52SA3rYeQByc6Y4+qsx8ulN5n7Tc8bwTjpqXrCHw8T7a\n\tv2zAWeqXJ2AOrOuik4XOB30f2zvfXxoHaqWSzWv1Z3M5aE/aevprxkI7YfbesyoLLSQ=", "X-Gm-Gg": "ATEYQzyegCXcxelB5ZEoS73H58H8PCJ8LZjTZ2nAYgYimLVCUsJ4jTYB329v4+7twIx\n\tB+R8agtY4RWEqJ9Y4dvKEmc8Hzmp0eXv94hoQ/qRMQ7K9BmzuV/LhFkeV8mwKBuejpk3asLfFSr\n\tMd72HQkPcCZbSXMTfnEAlUNwr44sA+nUStVOOQMlq44ta/oH2gKIBQhSh3Pdy9VHoVmLBY5mpKG\n\tLdFGvg2XWCpl2b2Q9cn10fn1gN/dnhDLKpcjRQmqNdmLC18SFFXyIuFUvFASusBJkwFj7Zl7x45\n\tcU5uWoAgQyN8JTLS20KCW84G0ksUt9w8vLqsAoPrBH2d38FlNtMzbu6H1lprPEoB4E/izoa239B\n\tB8PD6Km0tq3CUM+2AbvpFBl4Ryr6392J8EBSo0hDpkJmdFCDtq4jIvtqZkewZckwMMDJbc3eVsb\n\tQQwAr6XkB58kOTwxUPqfk3wZBj+IhJGf30SM27ng8u/qZK87tK", "X-Received": "by 2002:a05:6000:2484:b0:43b:433f:48a9 with SMTP id\n ffacd0b85a97d-43b88a3cf15mr11253480f8f.15.1774526168830;\n Thu, 26 Mar 2026 04:56:08 -0700 (PDT)", "From": "dave.patel@riscstar.com", "To": "Samuel Holland <samuel.holland@sifive.com>", "Cc": "Scott Bambrough <scott@riscstar.com>,\n\tRobin Randhawa <robin.randhawa@sifive.com>,\n\tAnup Patel <anup.patel@qti.qualcomm.com>,\n\tDave Patel <dave.patel@riscstar.com>,\n\tRay Mao <raymond.mao@riscstar.com>,\n\tAnup Patel <anuppate@qti.qualcomm.com>,\n\tDhaval <dhaval@rivosinc.com>,\n\tPeter Lin <peter.lin@sifive.com>,\n\topensbi@lists.infradead.org", "Subject": "[PATCH v2 1/3] lib: sbi: Add RISC-V vector context save/restore\n support (eager switching)", "Date": "Thu, 26 Mar 2026 11:55:15 +0000", "Message-ID": "<20260326115517.2156-2-dave.patel@riscstar.com>", "X-Mailer": "git-send-email 2.43.0", "In-Reply-To": "<20260326115517.2156-1-dave.patel@riscstar.com>", "References": "<20260326115517.2156-1-dave.patel@riscstar.com>", "MIME-Version": "1.0", "X-CRM114-Version": "20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ", "X-CRM114-CacheID": "sfid-20260326_045610_956954_CDD00E72 ", "X-CRM114-Status": "GOOD ( 15.56 )", "X-Spam-Score": "-1.9 (-)", "X-Spam-Report": "Spam detection software,\n running on the system \"bombadil.infradead.org\",\n has NOT identified this incoming email as spam. The original\n message has been attached to this so you can view it or label\n similar future email. If you have any questions, see\n the administrator of that system for details.\n Content preview: From: Dave Patel <dave.patel@riscstar.com> Add support for\n saving and restoring RISC-V vector extension state in OpenSBI. This\n introduces\n a per-hart vector context structure and helper routines to perform full\n context\n save and restore.\n Content analysis details: (-1.9 points, 5.0 required)\n pts rule name description\n ---- ----------------------\n --------------------------------------------------\n -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no\n trust\n [2a00:1450:4864:20:0:0:0:42c listed in]\n [list.dnswl.org]\n 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record\n -0.0 SPF_PASS SPF: sender matches SPF record\n -0.1 DKIM_VALID Message has at least one valid DKIM or DK\n signature\n 0.1 DKIM_SIGNED Message has a DKIM or DK signature,\n not necessarily valid\n -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1%\n [score: 0.0000]", "X-BeenThere": "opensbi@lists.infradead.org", "X-Mailman-Version": "2.1.34", "Precedence": "list", "List-Id": "<opensbi.lists.infradead.org>", "List-Unsubscribe": "<http://lists.infradead.org/mailman/options/opensbi>,\n <mailto:opensbi-request@lists.infradead.org?subject=unsubscribe>", "List-Archive": "<http://lists.infradead.org/pipermail/opensbi/>", "List-Post": "<mailto:opensbi@lists.infradead.org>", "List-Help": "<mailto:opensbi-request@lists.infradead.org?subject=help>", "List-Subscribe": "<http://lists.infradead.org/mailman/listinfo/opensbi>,\n <mailto:opensbi-request@lists.infradead.org?subject=subscribe>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Sender": "\"opensbi\" <opensbi-bounces@lists.infradead.org>", "Errors-To": "opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org" }, "content": "From: Dave Patel <dave.patel@riscstar.com>\n\nAdd support for saving and restoring RISC-V vector extension state in OpenSBI.\nThis introduces a per-hart vector context structure and helper routines to\nperform full context save and restore.\n\nThe vector context includes vl, vtype, vcsr CSRs along with storage for all\n32 vector registers. The register state is saved and restored using byte-wise\nvector load/store instructions (vse8.v/vle8.v), making the implementation\nindependent of current SEW/LMUL configuration.\n\nThe implementation follows an eager context switching model where the entire\nvector state is saved and restored on every context switch. This provides a\nsimple and deterministic mechanism without requiring lazy trap-based\nmanagement.\n\nNotes:\n- The SBI_MAX_VLENB is configured using CONFIG_SBI_MAX_VLENB.\n\nSigned-off-by: Dave Patel <dave.patel@riscstar.com>\n---\n include/sbi/sbi_vector.h | 35 ++++++++++\n lib/sbi/objects.mk | 7 ++\n lib/sbi/sbi_vector.c | 146 +++++++++++++++++++++++++++++++++++++++\n 3 files changed, 188 insertions(+)\n create mode 100644 include/sbi/sbi_vector.h\n create mode 100644 lib/sbi/sbi_vector.c\n\n--\n2.43.0", "diff": "diff --git a/include/sbi/sbi_vector.h b/include/sbi/sbi_vector.h\nnew file mode 100644\nindex 00000000..ae151406\n--- /dev/null\n+++ b/include/sbi/sbi_vector.h\n@@ -0,0 +1,35 @@\n+/* SPDX-License-Identifier: GPL-2.0\n+ *\n+ * Copyright (c) 2026 RISCstar Solutions.\n+ *\n+ * Authors:\n+ * Dave Patel <dave.patel@riscstar.com>\n+ */\n+\n+#ifndef __SBI_VECTOR_H__\n+#define __SBI_VECTOR_H__\n+\n+#include <sbi/sbi_types.h>\n+\n+#ifdef CONFIG_SBI_MAX_VLENB\n+#define SBI_MAX_VLENB CONFIG_SBI_MAX_VLENB\n+#else\n+#define SBI_MAX_VLENB 256\n+#endif\n+\n+struct sbi_vector_context {\n+ unsigned long vl;\n+ unsigned long vtype;\n+ unsigned long vcsr;\n+ unsigned long vstart;\n+\n+ /* size depends on VLEN */\n+ uint8_t vregs[32 * SBI_MAX_VLENB];\n+};\n+\n+struct sbi_vector_context *sbi_current_vector_context(void);\n+void sbi_vector_save(struct sbi_vector_context *dst);\n+void sbi_vector_restore(const struct sbi_vector_context *src);\n+\n+#endif //__SBI_VECTOR_H__\n+\ndiff --git a/lib/sbi/objects.mk b/lib/sbi/objects.mk\nindex ea816e92..9fd378d0 100644\n--- a/lib/sbi/objects.mk\n+++ b/lib/sbi/objects.mk\n@@ -106,3 +106,10 @@ libsbi-objs-y += sbi_trap_v_ldst.o\n libsbi-objs-y += sbi_unpriv.o\n libsbi-objs-y += sbi_expected_trap.o\n libsbi-objs-y += sbi_cppc.o\n+\n+RISCV_EXTS := $(patsubst rv32%,%,$(patsubst rv64%,%,$(PLATFORM_RISCV_ISA)))\n+$(info RESULT = $(findstring v,$(RISCV_EXTS)))\n+\n+ifneq ($(findstring v,$(RISCV_EXTS)),)\n+libsbi-objs-y += sbi_vector.o\n+endif\ndiff --git a/lib/sbi/sbi_vector.c b/lib/sbi/sbi_vector.c\nnew file mode 100644\nindex 00000000..e14b658c\n--- /dev/null\n+++ b/lib/sbi/sbi_vector.c\n@@ -0,0 +1,146 @@\n+/* SPDX-License-Identifier: GPL-2.0\n+ *\n+ * Copyright (c) 2026 RISCstar Solutions.\n+ *\n+ * Authors:\n+ * Dave Patel <dave.patel@riscstar.com>\n+ */\n+\n+#include <sbi/sbi_domain.h>\n+#include <sbi/riscv_encoding.h>\n+#include <sbi/riscv_asm.h>\n+#include <sbi/sbi_vector.h>\n+\n+static inline unsigned long vector_vlenb(void)\n+{\n+ unsigned long vlenb;\n+ asm volatile (\"csrr %0, vlenb\" : \"=r\"(vlenb));\n+ return vlenb;\n+}\n+\n+void sbi_vector_save(struct sbi_vector_context *dst)\n+{\n+ if (!dst)\n+ return;\n+\n+ uint8_t *base = dst->vregs;\n+ unsigned long vlenb;\n+\n+ /* Save CSRs */\n+ asm volatile(\"csrr %0, vtype\" : \"=r\"(dst->vtype));\n+ asm volatile(\"csrr %0, vl\" : \"=r\"(dst->vl));\n+ asm volatile(\"csrr %0, vcsr\" : \"=r\"(dst->vcsr));\n+ asm volatile(\"csrr %0, vstart\" : \"=r\"(dst->vstart));\n+\n+ /*\n+ * Set a known vector configuration before accessing registers.\n+ * This ensures the hardware is in a consistent state for save.\n+ */\n+ {\n+ unsigned long tmp;\n+ asm volatile(\"vsetvl %0, %1, %2\"\n+ : \"=r\"(tmp)\n+ : \"r\"(dst->vl), \"r\"(dst->vtype));\n+ }\n+\n+ vlenb = vector_vlenb();\n+\n+#define SAVE_VREG(i) \\\n+ asm volatile(\"vse8.v v\" #i \", (%0)\" :: \"r\"(base + (i) * vlenb) : \"memory\")\n+\n+ SAVE_VREG(0);\n+ SAVE_VREG(1);\n+ SAVE_VREG(2);\n+ SAVE_VREG(3);\n+ SAVE_VREG(4);\n+ SAVE_VREG(5);\n+ SAVE_VREG(6);\n+ SAVE_VREG(7);\n+ SAVE_VREG(8);\n+ SAVE_VREG(9);\n+ SAVE_VREG(10);\n+ SAVE_VREG(11);\n+ SAVE_VREG(12);\n+ SAVE_VREG(13);\n+ SAVE_VREG(14);\n+ SAVE_VREG(15);\n+ SAVE_VREG(16);\n+ SAVE_VREG(17);\n+ SAVE_VREG(18);\n+ SAVE_VREG(19);\n+ SAVE_VREG(20);\n+ SAVE_VREG(21);\n+ SAVE_VREG(22);\n+ SAVE_VREG(23);\n+ SAVE_VREG(24);\n+ SAVE_VREG(25);\n+ SAVE_VREG(26);\n+ SAVE_VREG(27);\n+ SAVE_VREG(28);\n+ SAVE_VREG(29);\n+ SAVE_VREG(30);\n+ SAVE_VREG(31);\n+\n+#undef SAVE_VREG\n+}\n+\n+void sbi_vector_restore(const struct sbi_vector_context *src)\n+{\n+ if (!src)\n+ return;\n+\n+ const uint8_t *base = src->vregs;\n+ unsigned long vlenb = vector_vlenb();\n+\n+ /* Restore CSRs first */\n+ asm volatile(\"csrw vtype, %0\" :: \"r\"(src->vtype));\n+ asm volatile(\"csrw vl, %0\" :: \"r\"(src->vl));\n+ asm volatile(\"csrw vcsr, %0\" :: \"r\"(src->vcsr));\n+ asm volatile(\"csrw vstart, %0\" :: \"r\"(src->vstart));\n+\n+ /* Re-establish vector state */\n+ {\n+ unsigned long tmp;\n+ asm volatile(\"vsetvl %0, %1, %2\"\n+ : \"=r\"(tmp)\n+ : \"r\"(src->vl), \"r\"(src->vtype));\n+ }\n+\n+#define RESTORE_VREG(i) \\\n+ asm volatile(\"vle8.v v\" #i \", (%0)\" :: \"r\"(base + (i) * vlenb) : \"memory\")\n+\n+ RESTORE_VREG(0);\n+ RESTORE_VREG(1);\n+ RESTORE_VREG(2);\n+ RESTORE_VREG(3);\n+ RESTORE_VREG(4);\n+ RESTORE_VREG(5);\n+ RESTORE_VREG(6);\n+ RESTORE_VREG(7);\n+ RESTORE_VREG(8);\n+ RESTORE_VREG(9);\n+ RESTORE_VREG(10);\n+ RESTORE_VREG(11);\n+ RESTORE_VREG(12);\n+ RESTORE_VREG(13);\n+ RESTORE_VREG(14);\n+ RESTORE_VREG(15);\n+ RESTORE_VREG(16);\n+ RESTORE_VREG(17);\n+ RESTORE_VREG(18);\n+ RESTORE_VREG(19);\n+ RESTORE_VREG(20);\n+ RESTORE_VREG(21);\n+ RESTORE_VREG(22);\n+ RESTORE_VREG(23);\n+ RESTORE_VREG(24);\n+ RESTORE_VREG(25);\n+ RESTORE_VREG(26);\n+ RESTORE_VREG(27);\n+ RESTORE_VREG(28);\n+ RESTORE_VREG(29);\n+ RESTORE_VREG(30);\n+ RESTORE_VREG(31);\n+\n+#undef RESTORE_VREG\n+}\n", "prefixes": [ "v2", "1/3" ] }