public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Jonathan Kim <jonathan.kim@amd.com>,
	Alice Wong <shiwei.wong@amd.com>,
	Eric Huang <jinhuieric.huang@amd.com>,
	Alex Deucher <alexander.deucher@amd.com>,
	Sasha Levin <sashal@kernel.org>,
	christian.koenig@amd.com, Xinhui.Pan@amd.com, airlied@gmail.com,
	daniel@ffwll.ch, Felix.Kuehling@amd.com, guchun.chen@amd.com,
	shashank.sharma@amd.com, Jack.Xiao@amd.com, lijo.lazar@amd.com,
	shaoyun.liu@amd.com, arvind.yadav@amd.com,
	amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
Subject: [PATCH AUTOSEL 6.7 52/88] drm/amdkfd: fix mes set shader debugger process management
Date: Mon, 22 Jan 2024 09:51:25 -0500	[thread overview]
Message-ID: <20240122145608.990137-52-sashal@kernel.org> (raw)
In-Reply-To: <20240122145608.990137-1-sashal@kernel.org>

From: Jonathan Kim <jonathan.kim@amd.com>

[ Upstream commit bd33bb1409b494558a2935f7bbc7842def957fcd ]

MES provides the driver a call to explicitly flush stale process memory
within the MES to avoid a race condition that results in a fatal
memory violation.

When SET_SHADER_DEBUGGER is called, the driver passes a memory address
that represents a process context address MES uses to keep track of
future per-process calls.

Normally, MES will purge its process context list when the last queue
has been removed.  The driver, however, can call SET_SHADER_DEBUGGER
regardless of whether a queue has been added or not.

If SET_SHADER_DEBUGGER has been called with no queues as the last call
prior to process termination, the passed process context address will
still reside within MES.

On a new process call to SET_SHADER_DEBUGGER, the driver may end up
passing an identical process context address value (based on per-process
gpu memory address) to MES but is now pointing to a new allocated buffer
object during KFD process creation.  Since the MES is unaware of this,
access of the passed address points to the stale object within MES and
triggers a fatal memory violation.

The solution is for KFD to explicitly flush the process context address
from MES on process termination.

Note that the flush call and the MES debugger calls use the same MES
interface but are separated as KFD calls to avoid conflicting with each
other.

Signed-off-by: Jonathan Kim <jonathan.kim@amd.com>
Tested-by: Alice Wong <shiwei.wong@amd.com>
Reviewed-by: Eric Huang <jinhuieric.huang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c       | 31 +++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h       | 10 +++---
 .../amd/amdkfd/kfd_process_queue_manager.c    |  1 +
 drivers/gpu/drm/amd/include/mes_v11_api_def.h |  3 +-
 4 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
index 9ddbf1494326..30c010836658 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -886,6 +886,11 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev,
 	op_input.op = MES_MISC_OP_SET_SHADER_DEBUGGER;
 	op_input.set_shader_debugger.process_context_addr = process_context_addr;
 	op_input.set_shader_debugger.flags.u32all = flags;
+
+	/* use amdgpu mes_flush_shader_debugger instead */
+	if (op_input.set_shader_debugger.flags.process_ctx_flush)
+		return -EINVAL;
+
 	op_input.set_shader_debugger.spi_gdbg_per_vmid_cntl = spi_gdbg_per_vmid_cntl;
 	memcpy(op_input.set_shader_debugger.tcp_watch_cntl, tcp_watch_cntl,
 			sizeof(op_input.set_shader_debugger.tcp_watch_cntl));
@@ -905,6 +910,32 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev,
 	return r;
 }
 
+int amdgpu_mes_flush_shader_debugger(struct amdgpu_device *adev,
+				     uint64_t process_context_addr)
+{
+	struct mes_misc_op_input op_input = {0};
+	int r;
+
+	if (!adev->mes.funcs->misc_op) {
+		DRM_ERROR("mes flush shader debugger is not supported!\n");
+		return -EINVAL;
+	}
+
+	op_input.op = MES_MISC_OP_SET_SHADER_DEBUGGER;
+	op_input.set_shader_debugger.process_context_addr = process_context_addr;
+	op_input.set_shader_debugger.flags.process_ctx_flush = true;
+
+	amdgpu_mes_lock(&adev->mes);
+
+	r = adev->mes.funcs->misc_op(&adev->mes, &op_input);
+	if (r)
+		DRM_ERROR("failed to set_shader_debugger\n");
+
+	amdgpu_mes_unlock(&adev->mes);
+
+	return r;
+}
+
 static void
 amdgpu_mes_ring_to_queue_props(struct amdgpu_device *adev,
 			       struct amdgpu_ring *ring,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
index a27b424ffe00..c2c88b772361 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
@@ -291,9 +291,10 @@ struct mes_misc_op_input {
 			uint64_t process_context_addr;
 			union {
 				struct {
-					uint64_t single_memop : 1;
-					uint64_t single_alu_op : 1;
-					uint64_t reserved: 30;
+					uint32_t single_memop : 1;
+					uint32_t single_alu_op : 1;
+					uint32_t reserved: 29;
+					uint32_t process_ctx_flush: 1;
 				};
 				uint32_t u32all;
 			} flags;
@@ -369,7 +370,8 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev,
 				const uint32_t *tcp_watch_cntl,
 				uint32_t flags,
 				bool trap_en);
-
+int amdgpu_mes_flush_shader_debugger(struct amdgpu_device *adev,
+				uint64_t process_context_addr);
 int amdgpu_mes_add_ring(struct amdgpu_device *adev, int gang_id,
 			int queue_type, int idx,
 			struct amdgpu_mes_ctx_data *ctx_data,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
index 77f493262e05..8e55e78fce4e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -87,6 +87,7 @@ void kfd_process_dequeue_from_device(struct kfd_process_device *pdd)
 		return;
 
 	dev->dqm->ops.process_termination(dev->dqm, &pdd->qpd);
+	amdgpu_mes_flush_shader_debugger(dev->adev, pdd->proc_ctx_gpu_addr);
 	pdd->already_dequeued = true;
 }
 
diff --git a/drivers/gpu/drm/amd/include/mes_v11_api_def.h b/drivers/gpu/drm/amd/include/mes_v11_api_def.h
index b1db2b190187..e07e93167a82 100644
--- a/drivers/gpu/drm/amd/include/mes_v11_api_def.h
+++ b/drivers/gpu/drm/amd/include/mes_v11_api_def.h
@@ -571,7 +571,8 @@ struct SET_SHADER_DEBUGGER {
 		struct {
 			uint32_t single_memop : 1;  /* SQ_DEBUG.single_memop */
 			uint32_t single_alu_op : 1; /* SQ_DEBUG.single_alu_op */
-			uint32_t reserved : 30;
+			uint32_t reserved : 29;
+			uint32_t process_ctx_flush : 1;
 		};
 		uint32_t u32all;
 	} flags;
-- 
2.43.0


  parent reply	other threads:[~2024-01-22 14:59 UTC|newest]

Thread overview: 89+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-22 14:50 [PATCH AUTOSEL 6.7 01/88] f2fs: fix to check return value of f2fs_reserve_new_block() Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 02/88] ALSA: hda: Refer to correct stream index at loops Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 03/88] ASoC: doc: Fix undefined SND_SOC_DAPM_NOPM argument Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 04/88] drm: Fix color LUT rounding Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 05/88] fast_dput(): handle underflows gracefully Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 06/88] reiserfs: Avoid touching renamed directory if parent does not change Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 07/88] ocfs2: " Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 08/88] drm/msm/a690: Fix reg values for a690 Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 09/88] RDMA/IPoIB: Fix error code return in ipoib_mcast_join Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 10/88] ASoC: SOF: icp3-dtrace: Fix wrong kfree() usage Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 11/88] drm/panel-edp: Add override_edid_mode quirk for generic edp Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 12/88] drm/bridge: anx7625: Fix Set HPD irq detect window to 2ms Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 13/88] drm/amd/display: Fix tiled display misalignment Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 14/88] media: renesas: vsp1: Fix references to pad config Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 15/88] f2fs: fix write pointers on zoned device after roll forward Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 16/88] ASoC: amd: Add new dmi entries for acp5x platform Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 17/88] drm/amd/display: initialize all the dpm level's stutter latency Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 18/88] drm/amd/display: Fix MST PBN/X.Y value calculations Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 19/88] drm/amd/display: Fix disable_otg_wa logic Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 20/88] drm/amd/display: Fix Replay Desync Error IRQ handler Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 21/88] drm/amd/display: add support for DTO genarated dscclk Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 22/88] drm/amd/display: Fix writeback_info never got updated Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 23/88] drm/amd/display: Fix writeback_info is not removed Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 24/88] drm/drm_file: fix use of uninitialized variable Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 25/88] drm/framebuffer: Fix " Sasha Levin
2024-01-22 14:50 ` [PATCH AUTOSEL 6.7 26/88] drm/mipi-dsi: Fix detach call without attach Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 27/88] media: stk1160: Fixed high volume of stk1160_dbg messages Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 28/88] media: rockchip: rga: fix swizzling for RGB formats Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 29/88] PCI: add INTEL_HDA_ARL to pci_ids.h Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 30/88] ALSA: hda: Intel: add HDA_ARL PCI ID support Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 31/88] ALSA: hda: intel-dspcfg: add filters for ARL-S and ARL Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 32/88] drm/msm/dp: Add DisplayPort controller for SM8650 Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 33/88] media: uvcvideo: Fix power line control for a Chicony camera Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 34/88] media: uvcvideo: Fix power line control for SunplusIT camera Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 35/88] media: rkisp1: Drop IRQF_SHARED Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 36/88] media: rkisp1: Fix IRQ handler return values Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 37/88] media: rkisp1: Store IRQ lines Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 38/88] media: rkisp1: Fix IRQ disable race issue Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 39/88] media: rkisp1: resizer: Stop manual allocation of v4l2_subdev_state Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 40/88] hwmon: (nct6775) Fix fan speed set failure in automatic mode Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 41/88] hwmon: (pc87360) Bounds check data->innr usage Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 42/88] hwmon: (hp-wmi-sensors) Fix failure to load on EliteDesk 800 G6 Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 43/88] f2fs: fix to tag gcing flag on page during block migration Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 44/88] drm/exynos: Call drm_atomic_helper_shutdown() at shutdown/unbind time Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 45/88] IB/ipoib: Fix mcast list locking Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 46/88] media: amphion: remove mutext lock in condition of wait_event Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 47/88] media: ddbridge: fix an error code problem in ddb_probe Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 48/88] media: ov2740: Fix hts value Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 49/88] media: i2c: imx335: Fix hblank min/max values Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 50/88] drm/amd/display: For prefetch mode > 0, extend prefetch if possible Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 51/88] drm/amd/display: Force p-state disallow if leaving no plane config Sasha Levin
2024-01-22 14:51 ` Sasha Levin [this message]
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 53/88] drm/msm/dpu: enable writeback on SM8350 Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 54/88] drm/msm/dpu: enable writeback on SM8450 Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 55/88] drm/msm/dpu: Ratelimit framedone timeout msgs Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 56/88] drm/msm/dpu: fix writeback programming for YUV cases Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 57/88] drm/msm/dpu: Add mutex lock in control vblank irq Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 58/88] drm/amdgpu: fix ftrace event amdgpu_bo_move always move on same heap Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 59/88] clk: hi3620: Fix memory leak in hi3620_mmc_clk_init() Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 60/88] clk: mmp: pxa168: Fix memory leak in pxa168_clk_init() Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 61/88] watchdog: starfive: add lock annotations to fix context imbalances Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 62/88] watchdog: it87_wdt: Keep WDTCTRL bit 3 unmodified for IT8784/IT8786 Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 63/88] accel/habanalabs: add support for Gaudi2C device Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 64/88] accel/habanalabs: fix EQ heartbeat mechanism Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 65/88] accel/habanalabs/gaudi2: fix undef opcode reporting Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 66/88] drm/amd/display: make flip_timestamp_in_us a 64-bit variable Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 67/88] drm/amd/display: fix usb-c connector_type Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 68/88] drm/amd/display: Fix lightup regression with DP2 single display configs Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 69/88] drm/amd/display: Only clear symclk otg flag for HDMI Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 70/88] clk: imx: scu: Fix memory leak in __imx_clk_gpr_scu() Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 71/88] clk: imx: clk-imx8qxp: fix LVDS bypass, pixel and phy clocks Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 72/88] ALSA: hda/tas2781: add fixup for Lenovo 14ARB7 Sasha Levin
2024-01-22 18:10   ` Gergo Koteles
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 73/88] drm/amdgpu: Fix ecc irq enable/disable unpaired Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 74/88] drm/amd/display: Fix minor issues in BW Allocation Phase2 Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 75/88] drm/amdgpu: Let KFD sync with VM fences Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 76/88] drm/amd/display: Fixing stream allocation regression Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 77/88] Re-revert "drm/amd/display: Enable Replay for static screen use cases" Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 78/88] drm/amdgpu: Fix possible NULL dereference in amdgpu_ras_query_error_status_helper() Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 79/88] drm/amdgpu: Fix variable 'mca_funcs' dereferenced before NULL check in 'amdgpu_mca_smu_get_mca_entry()' Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 80/88] drm/amdgpu: Fix '*fw' from request_firmware() not released in 'amdgpu_ucode_request()' Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 81/88] drm/amdgpu: Drop 'fence' check in 'to_amdgpu_amdkfd_fence()' Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 82/88] drm/amdkfd: Fix iterator used outside loop in 'kfd_add_peer_prop()' Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 83/88] Revert "drm/amdkfd: Relocate TBA/TMA to opposite side of VM hole" Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 84/88] drm/amdgpu: apply the RV2 system aperture fix to RN/CZN as well Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 85/88] ALSA: hda/conexant: Fix headset auto detect fail in cx8070 and SN6140 Sasha Levin
2024-01-22 14:51 ` [PATCH AUTOSEL 6.7 86/88] ksmbd: set v2 lease version on lease upgrade Sasha Levin
2024-01-22 14:52 ` [PATCH AUTOSEL 6.7 87/88] ksmbd: fix potential circular locking issue in smb2_set_ea() Sasha Levin
2024-01-22 14:52 ` [PATCH AUTOSEL 6.7 88/88] ksmbd: send lease break notification on FILE_RENAME_INFORMATION Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240122145608.990137-52-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=Felix.Kuehling@amd.com \
    --cc=Jack.Xiao@amd.com \
    --cc=Xinhui.Pan@amd.com \
    --cc=airlied@gmail.com \
    --cc=alexander.deucher@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=arvind.yadav@amd.com \
    --cc=christian.koenig@amd.com \
    --cc=daniel@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=guchun.chen@amd.com \
    --cc=jinhuieric.huang@amd.com \
    --cc=jonathan.kim@amd.com \
    --cc=lijo.lazar@amd.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=shaoyun.liu@amd.com \
    --cc=shashank.sharma@amd.com \
    --cc=shiwei.wong@amd.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox