* [PATCH 1/8] habanalabs/gaudi: fix print format for div_sel
@ 2022-07-31 10:50 Oded Gabbay
2022-07-31 10:50 ` [PATCH 2/8] habanalabs/gaudi: read div_sel value from firmware Oded Gabbay
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Oded Gabbay @ 2022-07-31 10:50 UTC (permalink / raw)
To: linux-kernel; +Cc: Ohad Sharabi
From: Ohad Sharabi <osharabi@habana.ai>
Print format was for int (%d) while variable is u32.
Signed-off-by: Ohad Sharabi <osharabi@habana.ai>
Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
---
drivers/misc/habanalabs/gaudi/gaudi.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c
index 4d11efed3e64..866dc4b891d6 100644
--- a/drivers/misc/habanalabs/gaudi/gaudi.c
+++ b/drivers/misc/habanalabs/gaudi/gaudi.c
@@ -939,9 +939,7 @@ static int gaudi_fetch_psoc_frequency(struct hl_device *hdev)
else
freq = pll_clk / (div_fctr + 1);
} else {
- dev_warn(hdev->dev,
- "Received invalid div select value: %d",
- div_sel);
+ dev_warn(hdev->dev, "Received invalid div select value: %#x", div_sel);
freq = 0;
}
}
--
2.25.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/8] habanalabs/gaudi: read div_sel value from firmware
2022-07-31 10:50 [PATCH 1/8] habanalabs/gaudi: fix print format for div_sel Oded Gabbay
@ 2022-07-31 10:50 ` Oded Gabbay
2022-07-31 10:50 ` [PATCH 3/8] habanalabs: fix command submission sanity check Oded Gabbay
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Oded Gabbay @ 2022-07-31 10:50 UTC (permalink / raw)
To: linux-kernel; +Cc: Ohad Sharabi
From: Ohad Sharabi <osharabi@habana.ai>
Even when running with unsecured f/w, we should read the PLL div_sel
value from the f/w as this register is always privileged.
Signed-off-by: Ohad Sharabi <osharabi@habana.ai>
Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
---
drivers/misc/habanalabs/gaudi/gaudi.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c
index 866dc4b891d6..7f52935dc603 100644
--- a/drivers/misc/habanalabs/gaudi/gaudi.c
+++ b/drivers/misc/habanalabs/gaudi/gaudi.c
@@ -899,12 +899,13 @@ static int gaudi_early_fini(struct hl_device *hdev)
*/
static int gaudi_fetch_psoc_frequency(struct hl_device *hdev)
{
- struct asic_fixed_properties *prop = &hdev->asic_prop;
u32 nr = 0, nf = 0, od = 0, div_fctr = 0, pll_clk, div_sel;
+ struct asic_fixed_properties *prop = &hdev->asic_prop;
u16 pll_freq_arr[HL_PLL_NUM_OUTPUTS], freq;
int rc;
- if (hdev->asic_prop.fw_security_enabled) {
+ if ((hdev->fw_components & FW_TYPE_LINUX) &&
+ (prop->fw_app_cpu_boot_dev_sts0 & CPU_BOOT_DEV_STS0_PLL_INFO_EN)) {
struct gaudi_device *gaudi = hdev->asic_specific;
if (!(gaudi->hw_cap_initialized & HW_CAP_CPU_Q))
--
2.25.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/8] habanalabs: fix command submission sanity check
2022-07-31 10:50 [PATCH 1/8] habanalabs/gaudi: fix print format for div_sel Oded Gabbay
2022-07-31 10:50 ` [PATCH 2/8] habanalabs/gaudi: read div_sel value from firmware Oded Gabbay
@ 2022-07-31 10:50 ` Oded Gabbay
2022-07-31 10:50 ` [PATCH 4/8] habanalabs: avoid returning a valid handle if map_block() fails Oded Gabbay
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Oded Gabbay @ 2022-07-31 10:50 UTC (permalink / raw)
To: linux-kernel; +Cc: Tal Cohen
From: Tal Cohen <talcohen@habana.ai>
When a CS is submitted, the ioctl handler checks the CS
flags and performs a sanity check, according to its value.
As new CS flags are added, the sanity check needs to be updated
according to the new flags.
Signed-off-by: Tal Cohen <talcohen@habana.ai>
Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
---
.../misc/habanalabs/common/command_submission.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/misc/habanalabs/common/command_submission.c b/drivers/misc/habanalabs/common/command_submission.c
index 90a4574cbe2d..304e4f3b0e7e 100644
--- a/drivers/misc/habanalabs/common/command_submission.c
+++ b/drivers/misc/habanalabs/common/command_submission.c
@@ -12,7 +12,9 @@
#include <linux/slab.h>
#define HL_CS_FLAGS_TYPE_MASK (HL_CS_FLAGS_SIGNAL | HL_CS_FLAGS_WAIT | \
- HL_CS_FLAGS_COLLECTIVE_WAIT)
+ HL_CS_FLAGS_COLLECTIVE_WAIT | HL_CS_FLAGS_RESERVE_SIGNALS_ONLY | \
+ HL_CS_FLAGS_UNRESERVE_SIGNALS_ONLY)
+
#define MAX_TS_ITER_NUM 10
@@ -1253,6 +1255,7 @@ static int hl_cs_sanity_checks(struct hl_fpriv *hpriv, union hl_cs_args *args)
u32 cs_type_flags, num_chunks;
enum hl_device_status status;
enum hl_cs_type cs_type;
+ bool is_sync_stream;
if (!hl_device_operational(hdev, &status)) {
return -EBUSY;
@@ -1276,9 +1279,10 @@ static int hl_cs_sanity_checks(struct hl_fpriv *hpriv, union hl_cs_args *args)
cs_type = hl_cs_get_cs_type(cs_type_flags);
num_chunks = args->in.num_chunks_execute;
- if (unlikely((cs_type == CS_TYPE_SIGNAL || cs_type == CS_TYPE_WAIT ||
- cs_type == CS_TYPE_COLLECTIVE_WAIT) &&
- !hdev->supports_sync_stream)) {
+ is_sync_stream = (cs_type == CS_TYPE_SIGNAL || cs_type == CS_TYPE_WAIT ||
+ cs_type == CS_TYPE_COLLECTIVE_WAIT);
+
+ if (unlikely(is_sync_stream && !hdev->supports_sync_stream)) {
dev_err(hdev->dev, "Sync stream CS is not supported\n");
return -EINVAL;
}
@@ -1288,7 +1292,7 @@ static int hl_cs_sanity_checks(struct hl_fpriv *hpriv, union hl_cs_args *args)
dev_err(hdev->dev, "Got execute CS with 0 chunks, context %d\n", ctx->asid);
return -EINVAL;
}
- } else if (num_chunks != 1) {
+ } else if (is_sync_stream && num_chunks != 1) {
dev_err(hdev->dev,
"Sync stream CS mandates one chunk only, context %d\n",
ctx->asid);
--
2.25.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 4/8] habanalabs: avoid returning a valid handle if map_block() fails
2022-07-31 10:50 [PATCH 1/8] habanalabs/gaudi: fix print format for div_sel Oded Gabbay
2022-07-31 10:50 ` [PATCH 2/8] habanalabs/gaudi: read div_sel value from firmware Oded Gabbay
2022-07-31 10:50 ` [PATCH 3/8] habanalabs: fix command submission sanity check Oded Gabbay
@ 2022-07-31 10:50 ` Oded Gabbay
2022-07-31 10:50 ` [PATCH 5/8] habanalabs: fix vma fields assignments order in hl_hw_block_mmap() Oded Gabbay
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Oded Gabbay @ 2022-07-31 10:50 UTC (permalink / raw)
To: linux-kernel; +Cc: Tomer Tayar
From: Tomer Tayar <ttayar@habana.ai>
map_block() sets the block id handle even if get_hw_block_id() fails,
and in this case it uses block id 0 which might be a valid id.
Modify it to set the handle only if get_hw_block_id() succeeds.
Signed-off-by: Tomer Tayar <ttayar@habana.ai>
Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
---
drivers/misc/habanalabs/common/memory.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/habanalabs/common/memory.c b/drivers/misc/habanalabs/common/memory.c
index 61bc1bfe984a..0698c3c363bd 100644
--- a/drivers/misc/habanalabs/common/memory.c
+++ b/drivers/misc/habanalabs/common/memory.c
@@ -1418,18 +1418,23 @@ static int unmap_device_va(struct hl_ctx *ctx, struct hl_mem_in *args,
return rc;
}
-static int map_block(struct hl_device *hdev, u64 address, u64 *handle,
- u32 *size)
+static int map_block(struct hl_device *hdev, u64 address, u64 *handle, u32 *size)
{
- u32 block_id = 0;
+ u32 block_id;
int rc;
+ *handle = 0;
+ if (size)
+ *size = 0;
+
rc = hdev->asic_funcs->get_hw_block_id(hdev, address, size, &block_id);
+ if (rc)
+ return rc;
*handle = block_id | HL_MMAP_TYPE_BLOCK;
*handle <<= PAGE_SHIFT;
- return rc;
+ return 0;
}
static void hw_block_vm_close(struct vm_area_struct *vma)
--
2.25.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 5/8] habanalabs: fix vma fields assignments order in hl_hw_block_mmap()
2022-07-31 10:50 [PATCH 1/8] habanalabs/gaudi: fix print format for div_sel Oded Gabbay
` (2 preceding siblings ...)
2022-07-31 10:50 ` [PATCH 4/8] habanalabs: avoid returning a valid handle if map_block() fails Oded Gabbay
@ 2022-07-31 10:50 ` Oded Gabbay
2022-07-31 10:50 ` [PATCH 6/8] habanalabs: add a missing lock for in_reset indication Oded Gabbay
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Oded Gabbay @ 2022-07-31 10:50 UTC (permalink / raw)
To: linux-kernel; +Cc: Tomer Tayar
From: Tomer Tayar <ttayar@habana.ai>
In hl_hw_block_mmap(), the vma's 'vm_private_data' and 'vm_ops' fields
are assigned before filling the content of the private data.
In between there is a call to the ASIC hw_block_mmap() function, and if
it fails, the vma close function will be called with a bad private data
value.
Fix the order of assignments to avoid this issue.
In hl_hw_block_mmap() the vma's 'vm_private_data and vm_ops are assigned
before setting the
Signed-off-by: Tomer Tayar <ttayar@habana.ai>
Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
---
drivers/misc/habanalabs/common/memory.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/misc/habanalabs/common/memory.c b/drivers/misc/habanalabs/common/memory.c
index 0698c3c363bd..a027fa88889b 100644
--- a/drivers/misc/habanalabs/common/memory.c
+++ b/drivers/misc/habanalabs/common/memory.c
@@ -1492,23 +1492,22 @@ int hl_hw_block_mmap(struct hl_fpriv *hpriv, struct vm_area_struct *vma)
if (!lnode)
return -ENOMEM;
- vma->vm_ops = &hw_block_vm_ops;
- vma->vm_private_data = lnode;
-
- hl_ctx_get(ctx);
-
rc = hdev->asic_funcs->hw_block_mmap(hdev, vma, block_id, block_size);
if (rc) {
- hl_ctx_put(ctx);
kfree(lnode);
return rc;
}
+ hl_ctx_get(ctx);
+
lnode->ctx = ctx;
lnode->vaddr = vma->vm_start;
lnode->size = block_size;
lnode->id = block_id;
+ vma->vm_private_data = lnode;
+ vma->vm_ops = &hw_block_vm_ops;
+
mutex_lock(&ctx->hw_block_list_lock);
list_add_tail(&lnode->node, &ctx->hw_block_mem_list);
mutex_unlock(&ctx->hw_block_list_lock);
--
2.25.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 6/8] habanalabs: add a missing lock for in_reset indication
2022-07-31 10:50 [PATCH 1/8] habanalabs/gaudi: fix print format for div_sel Oded Gabbay
` (3 preceding siblings ...)
2022-07-31 10:50 ` [PATCH 5/8] habanalabs: fix vma fields assignments order in hl_hw_block_mmap() Oded Gabbay
@ 2022-07-31 10:50 ` Oded Gabbay
2022-07-31 10:50 ` [PATCH 7/8] habanalabs/uapi: move defines to better place inside file Oded Gabbay
2022-07-31 10:50 ` [PATCH 8/8] habanalabs: move common function out of debugfs.c Oded Gabbay
6 siblings, 0 replies; 8+ messages in thread
From: Oded Gabbay @ 2022-07-31 10:50 UTC (permalink / raw)
To: linux-kernel; +Cc: Tomer Tayar
From: Tomer Tayar <ttayar@habana.ai>
Add a missing lock in hl_device_resume() when it assigns a value to the
'in_reset' indication.
Signed-off-by: Tomer Tayar <ttayar@habana.ai>
Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
---
drivers/misc/habanalabs/common/device.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c
index 90e346727a7c..6a98aae90f49 100644
--- a/drivers/misc/habanalabs/common/device.c
+++ b/drivers/misc/habanalabs/common/device.c
@@ -1091,7 +1091,9 @@ int hl_device_resume(struct hl_device *hdev)
/* 'in_reset' was set to true during suspend, now we must clear it in order
* for hard reset to be performed
*/
+ spin_lock(&hdev->reset_info.lock);
hdev->reset_info.in_reset = 0;
+ spin_unlock(&hdev->reset_info.lock);
rc = hl_device_reset(hdev, HL_DRV_RESET_HARD);
if (rc) {
--
2.25.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 7/8] habanalabs/uapi: move defines to better place inside file
2022-07-31 10:50 [PATCH 1/8] habanalabs/gaudi: fix print format for div_sel Oded Gabbay
` (4 preceding siblings ...)
2022-07-31 10:50 ` [PATCH 6/8] habanalabs: add a missing lock for in_reset indication Oded Gabbay
@ 2022-07-31 10:50 ` Oded Gabbay
2022-07-31 10:50 ` [PATCH 8/8] habanalabs: move common function out of debugfs.c Oded Gabbay
6 siblings, 0 replies; 8+ messages in thread
From: Oded Gabbay @ 2022-07-31 10:50 UTC (permalink / raw)
To: linux-kernel
Cosmetic change to move the eventfd events defines to a better
location in the file, closer to other INFO IOCTL defines.
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
---
include/uapi/misc/habanalabs.h | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/include/uapi/misc/habanalabs.h b/include/uapi/misc/habanalabs.h
index 83ca6f40f4ba..0da8894ab94a 100644
--- a/include/uapi/misc/habanalabs.h
+++ b/include/uapi/misc/habanalabs.h
@@ -707,6 +707,21 @@ enum hl_server_type {
HL_SERVER_GAUDI2_HLS2 = 5
};
+/*
+ * Notifier event values - for the notification mechanism and the HL_INFO_GET_EVENTS command
+ *
+ * HL_NOTIFIER_EVENT_TPC_ASSERT - Indicates TPC assert event
+ * HL_NOTIFIER_EVENT_UNDEFINED_OPCODE - Indicates undefined operation code
+ * HL_NOTIFIER_EVENT_DEVICE_RESET - Indicates device requires a reset
+ * HL_NOTIFIER_EVENT_CS_TIMEOUT - Indicates CS timeout error
+ * HL_NOTIFIER_EVENT_DEVICE_UNAVAILABLE - Indicates device is unavailable
+ */
+#define HL_NOTIFIER_EVENT_TPC_ASSERT (1ULL << 0)
+#define HL_NOTIFIER_EVENT_UNDEFINED_OPCODE (1ULL << 1)
+#define HL_NOTIFIER_EVENT_DEVICE_RESET (1ULL << 2)
+#define HL_NOTIFIER_EVENT_CS_TIMEOUT (1ULL << 3)
+#define HL_NOTIFIER_EVENT_DEVICE_UNAVAILABLE (1ULL << 4)
+
/* Opcode for management ioctl
*
* HW_IP_INFO - Receive information about different IP blocks in the
@@ -1883,21 +1898,6 @@ struct hl_debug_args {
__u32 ctx_id;
};
-/*
- * Notifier event values - for the notification mechanism and the HL_INFO_GET_EVENTS command
- *
- * HL_NOTIFIER_EVENT_TPC_ASSERT - Indicates TPC assert event
- * HL_NOTIFIER_EVENT_UNDEFINED_OPCODE - Indicates undefined operation code
- * HL_NOTIFIER_EVENT_DEVICE_RESET - Indicates device requires a reset
- * HL_NOTIFIER_EVENT_CS_TIMEOUT - Indicates CS timeout error
- * HL_NOTIFIER_EVENT_DEVICE_UNAVAILABLE - Indicates device is unavailable
- */
-#define HL_NOTIFIER_EVENT_TPC_ASSERT (1ULL << 0)
-#define HL_NOTIFIER_EVENT_UNDEFINED_OPCODE (1ULL << 1)
-#define HL_NOTIFIER_EVENT_DEVICE_RESET (1ULL << 2)
-#define HL_NOTIFIER_EVENT_CS_TIMEOUT (1ULL << 3)
-#define HL_NOTIFIER_EVENT_DEVICE_UNAVAILABLE (1ULL << 4)
-
/*
* Various information operations such as:
* - H/W IP information
--
2.25.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 8/8] habanalabs: move common function out of debugfs.c
2022-07-31 10:50 [PATCH 1/8] habanalabs/gaudi: fix print format for div_sel Oded Gabbay
` (5 preceding siblings ...)
2022-07-31 10:50 ` [PATCH 7/8] habanalabs/uapi: move defines to better place inside file Oded Gabbay
@ 2022-07-31 10:50 ` Oded Gabbay
6 siblings, 0 replies; 8+ messages in thread
From: Oded Gabbay @ 2022-07-31 10:50 UTC (permalink / raw)
To: linux-kernel; +Cc: kernel test robot
A common function that is called from multiple places can't be
located in degugfs.c because that file is only compiled if
debugfs is enabled in the kernel config file.
This can lead to undefined symbol compilation error.
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
---
drivers/misc/habanalabs/common/debugfs.c | 25 ------------------------
drivers/misc/habanalabs/common/device.c | 24 +++++++++++++++++++++++
2 files changed, 24 insertions(+), 25 deletions(-)
diff --git a/drivers/misc/habanalabs/common/debugfs.c b/drivers/misc/habanalabs/common/debugfs.c
index c297248748d3..69fd3ed7680a 100644
--- a/drivers/misc/habanalabs/common/debugfs.c
+++ b/drivers/misc/habanalabs/common/debugfs.c
@@ -586,31 +586,6 @@ static ssize_t mmu_ack_error_value_write(struct file *file,
return -EINVAL;
}
-void hl_engine_data_sprintf(struct engines_data *e, const char *fmt, ...)
-{
- va_list args;
- int str_size;
-
- va_start(args, fmt);
- /* Calculate formatted string length. Assuming each string is null terminated, hence
- * increment result by 1
- */
- str_size = vsnprintf(NULL, 0, fmt, args) + 1;
- va_end(args);
-
- if ((e->actual_size + str_size) < e->allocated_buf_size) {
- va_start(args, fmt);
- vsnprintf(e->buf + e->actual_size, str_size, fmt, args);
- va_end(args);
- }
-
- /* Need to update the size even when not updating destination buffer to get the exact size
- * of all input strings
- */
- e->actual_size += str_size;
-
-}
-
static int engines_show(struct seq_file *s, void *data)
{
struct hl_debugfs_entry *entry = s->private;
diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c
index 6a98aae90f49..ab2497b6d164 100644
--- a/drivers/misc/habanalabs/common/device.c
+++ b/drivers/misc/habanalabs/common/device.c
@@ -267,6 +267,30 @@ int hl_access_dev_mem(struct hl_device *hdev, enum pci_region region_type,
return 0;
}
+void hl_engine_data_sprintf(struct engines_data *e, const char *fmt, ...)
+{
+ va_list args;
+ int str_size;
+
+ va_start(args, fmt);
+ /* Calculate formatted string length. Assuming each string is null terminated, hence
+ * increment result by 1
+ */
+ str_size = vsnprintf(NULL, 0, fmt, args) + 1;
+ va_end(args);
+
+ if ((e->actual_size + str_size) < e->allocated_buf_size) {
+ va_start(args, fmt);
+ vsnprintf(e->buf + e->actual_size, str_size, fmt, args);
+ va_end(args);
+ }
+
+ /* Need to update the size even when not updating destination buffer to get the exact size
+ * of all input strings
+ */
+ e->actual_size += str_size;
+}
+
enum hl_device_status hl_device_status(struct hl_device *hdev)
{
enum hl_device_status status;
--
2.25.1
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2022-07-31 10:51 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-31 10:50 [PATCH 1/8] habanalabs/gaudi: fix print format for div_sel Oded Gabbay
2022-07-31 10:50 ` [PATCH 2/8] habanalabs/gaudi: read div_sel value from firmware Oded Gabbay
2022-07-31 10:50 ` [PATCH 3/8] habanalabs: fix command submission sanity check Oded Gabbay
2022-07-31 10:50 ` [PATCH 4/8] habanalabs: avoid returning a valid handle if map_block() fails Oded Gabbay
2022-07-31 10:50 ` [PATCH 5/8] habanalabs: fix vma fields assignments order in hl_hw_block_mmap() Oded Gabbay
2022-07-31 10:50 ` [PATCH 6/8] habanalabs: add a missing lock for in_reset indication Oded Gabbay
2022-07-31 10:50 ` [PATCH 7/8] habanalabs/uapi: move defines to better place inside file Oded Gabbay
2022-07-31 10:50 ` [PATCH 8/8] habanalabs: move common function out of debugfs.c Oded Gabbay
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome