* [PATCH v7 2/5] PCI/TPH: Add requester/completer type helpers
2026-06-11 16:11 [PATCH v7 0/5] vfio/dma-buf: add TPH support for peer-to-peer access Zhiping Zhang
@ 2026-06-11 16:11 ` Zhiping Zhang
2026-06-12 16:46 ` sashiko-bot
2026-06-12 16:52 ` Alex Williamson
0 siblings, 2 replies; 6+ messages in thread
From: Zhiping Zhang @ 2026-06-11 16:11 UTC (permalink / raw)
To: netdev; +Cc: kvm, linux-rdma, linux-pci, dri-devel, Zhiping Zhang,
Bjorn Helgaas
Add pcie_tph_enabled_req_type() so drivers can query the enabled TPH
requester mode without reaching into pci_dev internals.
Add pcie_tph_completer_type() so drivers that publish TPH metadata for
a device acting as a completer can gate on the "TPH Completer
Supported" field of Device Capabilities 2 (bits 13:12,
PCI_EXP_DEVCAP2_TPH_COMP_MASK) rather than reusing requester-side
state. Fold the reserved 0b10 encoding into NONE so callers only see
the defined values.
This keeps pci_dev::tph_req_type and the completer-capability decode
inside the PCI/TPH code and provides !CONFIG_PCIE_TPH stubs for
callers.
Signed-off-by: Zhiping Zhang <zhipingz@meta.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/pci/tph.c | 43 +++++++++++++++++++++++++++++++++++++++++
include/linux/pci-tph.h | 8 ++++++++
2 files changed, 51 insertions(+)
diff --git a/drivers/pci/tph.c b/drivers/pci/tph.c
index 91145e8d9d95..4fe076bba953 100644
--- a/drivers/pci/tph.c
+++ b/drivers/pci/tph.c
@@ -174,6 +174,49 @@ u32 pcie_tph_get_st_table_loc(struct pci_dev *pdev)
}
EXPORT_SYMBOL(pcie_tph_get_st_table_loc);
+/**
+ * pcie_tph_enabled_req_type - Return the device's enabled TPH requester type
+ * @pdev: PCI device to query
+ *
+ * Return: PCI_TPH_REQ_DISABLE, PCI_TPH_REQ_TPH_ONLY or PCI_TPH_REQ_EXT_TPH.
+ */
+u8 pcie_tph_enabled_req_type(struct pci_dev *pdev)
+{
+ return pdev->tph_req_type;
+}
+EXPORT_SYMBOL(pcie_tph_enabled_req_type);
+
+/**
+ * pcie_tph_completer_type - Return the device's TPH Completer support
+ * @pdev: PCI device to query
+ *
+ * Reads the "TPH Completer Supported" field (bits 13:12) of Device
+ * Capabilities 2. The reserved 0b10 encoding is folded into
+ * "not supported" so callers only need to compare against the three
+ * defined values.
+ *
+ * Return: one of %PCI_EXP_DEVCAP2_TPH_COMP_NONE,
+ * %PCI_EXP_DEVCAP2_TPH_COMP_TPH_ONLY or
+ * %PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH.
+ */
+u8 pcie_tph_completer_type(struct pci_dev *pdev)
+{
+ u32 reg;
+
+ if (pcie_capability_read_dword(pdev, PCI_EXP_DEVCAP2, ®))
+ return PCI_EXP_DEVCAP2_TPH_COMP_NONE;
+
+ switch (FIELD_GET(PCI_EXP_DEVCAP2_TPH_COMP_MASK, reg)) {
+ case PCI_EXP_DEVCAP2_TPH_COMP_TPH_ONLY:
+ return PCI_EXP_DEVCAP2_TPH_COMP_TPH_ONLY;
+ case PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH:
+ return PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH;
+ default:
+ return PCI_EXP_DEVCAP2_TPH_COMP_NONE;
+ }
+}
+EXPORT_SYMBOL(pcie_tph_completer_type);
+
/*
* Return the size of ST table. If ST table is not in TPH Requester Extended
* Capability space, return 0. Otherwise return the ST Table Size + 1.
diff --git a/include/linux/pci-tph.h b/include/linux/pci-tph.h
index be68cd17f2f8..7743af6fe432 100644
--- a/include/linux/pci-tph.h
+++ b/include/linux/pci-tph.h
@@ -9,6 +9,8 @@
#ifndef LINUX_PCI_TPH_H
#define LINUX_PCI_TPH_H
+#include <linux/pci_regs.h>
+
/*
* According to the ECN for PCI Firmware Spec, Steering Tag can be different
* depending on the memory type: Volatile Memory or Persistent Memory. When a
@@ -30,6 +32,8 @@ void pcie_disable_tph(struct pci_dev *pdev);
int pcie_enable_tph(struct pci_dev *pdev, int mode);
u16 pcie_tph_get_st_table_size(struct pci_dev *pdev);
u32 pcie_tph_get_st_table_loc(struct pci_dev *pdev);
+u8 pcie_tph_enabled_req_type(struct pci_dev *pdev);
+u8 pcie_tph_completer_type(struct pci_dev *pdev);
#else
static inline int pcie_tph_set_st_entry(struct pci_dev *pdev,
unsigned int index, u16 tag)
@@ -41,6 +45,10 @@ static inline int pcie_tph_get_cpu_st(struct pci_dev *dev,
static inline void pcie_disable_tph(struct pci_dev *pdev) { }
static inline int pcie_enable_tph(struct pci_dev *pdev, int mode)
{ return -EINVAL; }
+static inline u8 pcie_tph_enabled_req_type(struct pci_dev *pdev)
+{ return PCI_TPH_REQ_DISABLE; }
+static inline u8 pcie_tph_completer_type(struct pci_dev *pdev)
+{ return PCI_EXP_DEVCAP2_TPH_COMP_NONE; }
#endif
#endif /* LINUX_PCI_TPH_H */
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v7 2/5] PCI/TPH: Add requester/completer type helpers
[not found] <20260610193158.2614209-3-zhipingz@meta.com>
@ 2026-06-11 20:25 ` sashiko-bot
2026-06-11 23:06 ` Zhiping Zhang
0 siblings, 1 reply; 6+ messages in thread
From: sashiko-bot @ 2026-06-11 20:25 UTC (permalink / raw)
To: Zhiping Zhang; +Cc: kvm, linux-pci, dri-devel
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [Medium] pcie_tph_completer_type() incorrectly returns PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH when reading from a disconnected or hot-removed device.
Pre-existing issues:
- [High] The internal get_rp_completer_type() function was not updated to use the new pcie_tph_completer_type() helper, meaning it can still return the reserved 0b10 value, which can corrupt the device's TPH Requester Enable state.
--
commit e3087f1c41da11f8e5258fd8b874372276270977
Author: Zhiping Zhang <zhipingz@meta.com>
PCI/TPH: Add requester/completer type helpers
Add pcie_tph_enabled_req_type() and pcie_tph_completer_type() so drivers can
query the enabled TPH requester mode and completer support safely. Fold the
reserved 0b10 encoding into NONE so callers only see defined values.
> diff --git a/drivers/pci/tph.c b/drivers/pci/tph.c
> index 91145e8d9d951..4fe076bba953a 100644
> --- a/drivers/pci/tph.c
> +++ b/drivers/pci/tph.c
[ ... ]
> +u8 pcie_tph_completer_type(struct pci_dev *pdev)
> +{
> + u32 reg;
> +
> + if (pcie_capability_read_dword(pdev, PCI_EXP_DEVCAP2, ®))
> + return PCI_EXP_DEVCAP2_TPH_COMP_NONE;
> +
> + switch (FIELD_GET(PCI_EXP_DEVCAP2_TPH_COMP_MASK, reg)) {
[Severity: Medium]
If the device is hot-removed, pcie_capability_read_dword() returns success (0)
but can leave reg as 0xFFFFFFFF (PCI_ERROR_RESPONSE due to master abort).
Will FIELD_GET(PCI_EXP_DEVCAP2_TPH_COMP_MASK, reg) then extract 0b11 (3),
matching PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH, causing the helper to falsely
advertise that a disconnected device supports Extended TPH? Should this logic
check if reg is ~0?
> + case PCI_EXP_DEVCAP2_TPH_COMP_TPH_ONLY:
> + return PCI_EXP_DEVCAP2_TPH_COMP_TPH_ONLY;
> + case PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH:
> + return PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH;
> + default:
> + return PCI_EXP_DEVCAP2_TPH_COMP_NONE;
> + }
> +}
> +EXPORT_SYMBOL(pcie_tph_completer_type);
[Severity: High]
This is a pre-existing issue, but the internal get_rp_completer_type() function
was not updated to use this new pcie_tph_completer_type() helper.
Because it still returns the raw extracted Completer Supported field, it can
return the reserved 0b10 value without applying the safety folding introduced
here:
drivers/pci/tph.c:get_rp_completer_type() {
...
return FIELD_GET(PCI_EXP_DEVCAP2_TPH_COMP_MASK, reg);
}
If the device supports EXT_TPH (3) and the Root Port returns the reserved value
(2), could this incorrectly propagate the reserved value?
drivers/pci/tph.c:pcie_enable_tph() {
...
pdev->tph_req_type = min(pdev->tph_req_type, rp_req_type);
...
}
This would then write the reserved value (2) into the hardware's TPH Control
register, misconfiguring the device:
drivers/pci/tph.c:pcie_enable_tph() {
...
reg &= ~PCI_TPH_CTRL_REQ_EN_MASK;
reg |= FIELD_PREP(PCI_TPH_CTRL_REQ_EN_MASK, pdev->tph_req_type);
pci_write_config_dword(pdev, pdev->tph_cap + PCI_TPH_CTRL, reg);
...
}
Should get_rp_completer_type() be updated to use the new helper?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260610193158.2614209-1-zhipingz@meta.com?part=2
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v7 2/5] PCI/TPH: Add requester/completer type helpers
2026-06-11 20:25 ` [PATCH v7 2/5] PCI/TPH: Add requester/completer type helpers sashiko-bot
@ 2026-06-11 23:06 ` Zhiping Zhang
0 siblings, 0 replies; 6+ messages in thread
From: Zhiping Zhang @ 2026-06-11 23:06 UTC (permalink / raw)
To: sashiko-reviews; +Cc: kvm, linux-pci, dri-devel
On Thu, Jun 11, 2026 at 1:26 PM <sashiko-bot@kernel.org> wrote:
>
> >
> > diff --git a/drivers/pci/tph.c b/drivers/pci/tph.c
> > index 91145e8d9d951..4fe076bba953a 100644
> > --- a/drivers/pci/tph.c
> > +++ b/drivers/pci/tph.c
> [ ... ]
> > +u8 pcie_tph_completer_type(struct pci_dev *pdev)
> > +{
> > + u32 reg;
> > +
> > + if (pcie_capability_read_dword(pdev, PCI_EXP_DEVCAP2, ®))
> > + return PCI_EXP_DEVCAP2_TPH_COMP_NONE;
> > +
> > + switch (FIELD_GET(PCI_EXP_DEVCAP2_TPH_COMP_MASK, reg)) {
>
> [Severity: Medium]
> If the device is hot-removed, pcie_capability_read_dword() returns success (0)
> but can leave reg as 0xFFFFFFFF (PCI_ERROR_RESPONSE due to master abort).
>
will fix this one with check like below before the switch statement:
+ if (PCI_POSSIBLE_ERROR(reg))
+ return PCI_EXP_DEVCAP2_TPH_COMP_NONE;
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v7 2/5] PCI/TPH: Add requester/completer type helpers
2026-06-11 16:11 ` [PATCH v7 2/5] PCI/TPH: Add requester/completer type helpers Zhiping Zhang
@ 2026-06-12 16:46 ` sashiko-bot
2026-06-12 16:52 ` Alex Williamson
1 sibling, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-06-12 16:46 UTC (permalink / raw)
To: Zhiping Zhang; +Cc: dri-devel, kvm, linux-pci
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] pcie_tph_completer_type() does not check for PCI_ERROR_RESPONSE (~0U), leading to a false positive Extended TPH capability if the device is disconnected or in a low power state.
--
commit f9aeb32b2542c39fb3d9466efa934427ab4660a5
Author: Zhiping Zhang <zhipingz@meta.com>
PCI/TPH: Add requester/completer type helpers
This commit adds pcie_tph_enabled_req_type() and pcie_tph_completer_type()
helpers to allow drivers to query TPH enabled requester modes and completer
support without accessing pci_dev internals directly.
> diff --git a/drivers/pci/tph.c b/drivers/pci/tph.c
> index 91145e8d9d951..4fe076bba953a 100644
> --- a/drivers/pci/tph.c
> +++ b/drivers/pci/tph.c
[ ... ]
> @@ -174,6 +174,49 @@ u32 pcie_tph_get_st_table_loc(struct pci_dev *pdev)
[ ... ]
> +u8 pcie_tph_completer_type(struct pci_dev *pdev)
> +{
> + u32 reg;
> +
> + if (pcie_capability_read_dword(pdev, PCI_EXP_DEVCAP2, ®))
> + return PCI_EXP_DEVCAP2_TPH_COMP_NONE;
> +
> + switch (FIELD_GET(PCI_EXP_DEVCAP2_TPH_COMP_MASK, reg)) {
> + case PCI_EXP_DEVCAP2_TPH_COMP_TPH_ONLY:
> + return PCI_EXP_DEVCAP2_TPH_COMP_TPH_ONLY;
> + case PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH:
> + return PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH;
[Severity: Medium]
Will this return a false positive if the device is disconnected or in a low
power state?
When reading the PCI config space of an unplugged or unresponsive device,
the host bridge typically returns all 1s (0xFFFFFFFF) and the config read
returns 0 (success).
If pcie_capability_read_dword() succeeds but sets reg to 0xFFFFFFFF,
FIELD_GET() will extract 0b11 (3) from bits 13:12. This matches
PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH, causing the switch statement to
incorrectly return that the device supports Extended TPH.
Could this trick drivers querying capabilities during teardown or error
recovery into believing a removed device supports Extended TPH? Using
PCI_POSSIBLE_ERROR() to check the register value before evaluating the bits
might prevent this.
> + default:
> + return PCI_EXP_DEVCAP2_TPH_COMP_NONE;
> + }
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260611161546.4075580-1-zhipingz@meta.com?part=2
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v7 2/5] PCI/TPH: Add requester/completer type helpers
2026-06-11 16:11 ` [PATCH v7 2/5] PCI/TPH: Add requester/completer type helpers Zhiping Zhang
2026-06-12 16:46 ` sashiko-bot
@ 2026-06-12 16:52 ` Alex Williamson
2026-06-13 22:22 ` Zhiping Zhang
1 sibling, 1 reply; 6+ messages in thread
From: Alex Williamson @ 2026-06-12 16:52 UTC (permalink / raw)
To: Zhiping Zhang
Cc: netdev, kvm, linux-rdma, linux-pci, dri-devel, Bjorn Helgaas,
alex
On Thu, 11 Jun 2026 09:11:17 -0700
Zhiping Zhang <zhipingz@meta.com> wrote:
> Add pcie_tph_enabled_req_type() so drivers can query the enabled TPH
> requester mode without reaching into pci_dev internals.
>
> Add pcie_tph_completer_type() so drivers that publish TPH metadata for
> a device acting as a completer can gate on the "TPH Completer
> Supported" field of Device Capabilities 2 (bits 13:12,
> PCI_EXP_DEVCAP2_TPH_COMP_MASK) rather than reusing requester-side
> state. Fold the reserved 0b10 encoding into NONE so callers only see
> the defined values.
>
> This keeps pci_dev::tph_req_type and the completer-capability decode
> inside the PCI/TPH code and provides !CONFIG_PCIE_TPH stubs for
> callers.
>
> Signed-off-by: Zhiping Zhang <zhipingz@meta.com>
> Acked-by: Bjorn Helgaas <bhelgaas@google.com>
This is carrying forward an ack for v6, where half the interface here
was dropped and changed shape. Thanks,
Alex
> ---
> drivers/pci/tph.c | 43 +++++++++++++++++++++++++++++++++++++++++
> include/linux/pci-tph.h | 8 ++++++++
> 2 files changed, 51 insertions(+)
>
> diff --git a/drivers/pci/tph.c b/drivers/pci/tph.c
> index 91145e8d9d95..4fe076bba953 100644
> --- a/drivers/pci/tph.c
> +++ b/drivers/pci/tph.c
> @@ -174,6 +174,49 @@ u32 pcie_tph_get_st_table_loc(struct pci_dev *pdev)
> }
> EXPORT_SYMBOL(pcie_tph_get_st_table_loc);
>
> +/**
> + * pcie_tph_enabled_req_type - Return the device's enabled TPH requester type
> + * @pdev: PCI device to query
> + *
> + * Return: PCI_TPH_REQ_DISABLE, PCI_TPH_REQ_TPH_ONLY or PCI_TPH_REQ_EXT_TPH.
> + */
> +u8 pcie_tph_enabled_req_type(struct pci_dev *pdev)
> +{
> + return pdev->tph_req_type;
> +}
> +EXPORT_SYMBOL(pcie_tph_enabled_req_type);
> +
> +/**
> + * pcie_tph_completer_type - Return the device's TPH Completer support
> + * @pdev: PCI device to query
> + *
> + * Reads the "TPH Completer Supported" field (bits 13:12) of Device
> + * Capabilities 2. The reserved 0b10 encoding is folded into
> + * "not supported" so callers only need to compare against the three
> + * defined values.
> + *
> + * Return: one of %PCI_EXP_DEVCAP2_TPH_COMP_NONE,
> + * %PCI_EXP_DEVCAP2_TPH_COMP_TPH_ONLY or
> + * %PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH.
> + */
> +u8 pcie_tph_completer_type(struct pci_dev *pdev)
> +{
> + u32 reg;
> +
> + if (pcie_capability_read_dword(pdev, PCI_EXP_DEVCAP2, ®))
> + return PCI_EXP_DEVCAP2_TPH_COMP_NONE;
> +
> + switch (FIELD_GET(PCI_EXP_DEVCAP2_TPH_COMP_MASK, reg)) {
> + case PCI_EXP_DEVCAP2_TPH_COMP_TPH_ONLY:
> + return PCI_EXP_DEVCAP2_TPH_COMP_TPH_ONLY;
> + case PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH:
> + return PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH;
> + default:
> + return PCI_EXP_DEVCAP2_TPH_COMP_NONE;
> + }
> +}
> +EXPORT_SYMBOL(pcie_tph_completer_type);
> +
> /*
> * Return the size of ST table. If ST table is not in TPH Requester Extended
> * Capability space, return 0. Otherwise return the ST Table Size + 1.
> diff --git a/include/linux/pci-tph.h b/include/linux/pci-tph.h
> index be68cd17f2f8..7743af6fe432 100644
> --- a/include/linux/pci-tph.h
> +++ b/include/linux/pci-tph.h
> @@ -9,6 +9,8 @@
> #ifndef LINUX_PCI_TPH_H
> #define LINUX_PCI_TPH_H
>
> +#include <linux/pci_regs.h>
> +
> /*
> * According to the ECN for PCI Firmware Spec, Steering Tag can be different
> * depending on the memory type: Volatile Memory or Persistent Memory. When a
> @@ -30,6 +32,8 @@ void pcie_disable_tph(struct pci_dev *pdev);
> int pcie_enable_tph(struct pci_dev *pdev, int mode);
> u16 pcie_tph_get_st_table_size(struct pci_dev *pdev);
> u32 pcie_tph_get_st_table_loc(struct pci_dev *pdev);
> +u8 pcie_tph_enabled_req_type(struct pci_dev *pdev);
> +u8 pcie_tph_completer_type(struct pci_dev *pdev);
> #else
> static inline int pcie_tph_set_st_entry(struct pci_dev *pdev,
> unsigned int index, u16 tag)
> @@ -41,6 +45,10 @@ static inline int pcie_tph_get_cpu_st(struct pci_dev *dev,
> static inline void pcie_disable_tph(struct pci_dev *pdev) { }
> static inline int pcie_enable_tph(struct pci_dev *pdev, int mode)
> { return -EINVAL; }
> +static inline u8 pcie_tph_enabled_req_type(struct pci_dev *pdev)
> +{ return PCI_TPH_REQ_DISABLE; }
> +static inline u8 pcie_tph_completer_type(struct pci_dev *pdev)
> +{ return PCI_EXP_DEVCAP2_TPH_COMP_NONE; }
> #endif
>
> #endif /* LINUX_PCI_TPH_H */
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v7 2/5] PCI/TPH: Add requester/completer type helpers
2026-06-12 16:52 ` Alex Williamson
@ 2026-06-13 22:22 ` Zhiping Zhang
0 siblings, 0 replies; 6+ messages in thread
From: Zhiping Zhang @ 2026-06-13 22:22 UTC (permalink / raw)
To: Alex Williamson
Cc: netdev, kvm, linux-rdma, linux-pci, dri-devel, Bjorn Helgaas
On Fri, Jun 12, 2026 at 9:53 AM Alex Williamson <alex@shazbot.org> wrote:
>
> >
> On Thu, 11 Jun 2026 09:11:17 -0700
> Zhiping Zhang <zhipingz@meta.com> wrote:
>
> > Add pcie_tph_enabled_req_type() so drivers can query the enabled TPH
> > requester mode without reaching into pci_dev internals.
> >
> > Add pcie_tph_completer_type() so drivers that publish TPH metadata for
> > a device acting as a completer can gate on the "TPH Completer
> > Supported" field of Device Capabilities 2 (bits 13:12,
> > PCI_EXP_DEVCAP2_TPH_COMP_MASK) rather than reusing requester-side
> > state. Fold the reserved 0b10 encoding into NONE so callers only see
> > the defined values.
> >
> > This keeps pci_dev::tph_req_type and the completer-capability decode
> > inside the PCI/TPH code and provides !CONFIG_PCIE_TPH stubs for
> > callers.
> >
> > Signed-off-by: Zhiping Zhang <zhipingz@meta.com>
> > Acked-by: Bjorn Helgaas <bhelgaas@google.com>
>
> This is carrying forward an ack for v6, where half the interface here
> was dropped and changed shape. Thanks,
>
> Alex
>
Good catch, will drop in v8 and request from Bjorn on the new shape.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-06-13 22:23 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260610193158.2614209-3-zhipingz@meta.com>
2026-06-11 20:25 ` [PATCH v7 2/5] PCI/TPH: Add requester/completer type helpers sashiko-bot
2026-06-11 23:06 ` Zhiping Zhang
2026-06-11 16:11 [PATCH v7 0/5] vfio/dma-buf: add TPH support for peer-to-peer access Zhiping Zhang
2026-06-11 16:11 ` [PATCH v7 2/5] PCI/TPH: Add requester/completer type helpers Zhiping Zhang
2026-06-12 16:46 ` sashiko-bot
2026-06-12 16:52 ` Alex Williamson
2026-06-13 22:22 ` Zhiping Zhang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox