From: Suzuki K Poulose <suzuki.poulose@arm.com> To: kvmarm@lists.linux.dev Cc: kvm@vger.kernel.org, linux-coco@lists.linux.dev, linux-arm-kernel@lists.infradead.org, maz@kernel.org, alexandru.elisei@arm.com, joey.gouly@arm.com, steven.price@arm.com, james.morse@arm.com, oliver.upton@linux.dev, yuzenghui@huawei.com, andrew.jones@linux.dev, eric.auger@redhat.com, Djordje Kovacevic <djordje.kovacevic@arm.com>, Suzuki K Poulose <suzuki.poulose@arm.com> Subject: [kvm-unit-tests PATCH 20/33] arm: realm: Add tests for in realm SEA Date: Fri, 12 Apr 2024 11:33:55 +0100 [thread overview] Message-ID: <20240412103408.2706058-21-suzuki.poulose@arm.com> (raw) In-Reply-To: <20240412103408.2706058-1-suzuki.poulose@arm.com> From: Djordje Kovacevic <djordje.kovacevic@arm.com> The RMM/Host could inject Synchronous External Aborts in to the Realm for various reasons. RMM injects the SEA for : * Instruction/Data fetch from an IPA that is in RIPAS_EMPTY state * Instruction fetch from an Unprotected IPA. Trigger these conditions from within the Realm and verify that the SEAs are received. Signed-off-by: Djordje Kovacevic <djordje.kovacevic@arm.com> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> --- arm/Makefile.arm64 | 1 + arm/realm-sea.c | 143 +++++++++++++++++++++++++++++++++++++++++++++ arm/unittests.cfg | 6 ++ 3 files changed, 150 insertions(+) create mode 100644 arm/realm-sea.c diff --git a/arm/Makefile.arm64 b/arm/Makefile.arm64 index 5a9943c8..b3e085d3 100644 --- a/arm/Makefile.arm64 +++ b/arm/Makefile.arm64 @@ -59,6 +59,7 @@ tests += $(TEST_DIR)/cache.$(exe) tests += $(TEST_DIR)/debug.$(exe) tests += $(TEST_DIR)/fpu.$(exe) tests += $(TEST_DIR)/realm-rsi.$(exe) +tests += $(TEST_DIR)/realm-sea.$(exe) include $(SRCDIR)/$(TEST_DIR)/Makefile.common diff --git a/arm/realm-sea.c b/arm/realm-sea.c new file mode 100644 index 00000000..5ef3e2a4 --- /dev/null +++ b/arm/realm-sea.c @@ -0,0 +1,143 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 Arm Limited. + * All rights reserved. + */ +#include <libcflat.h> +#include <vmalloc.h> +#include <asm/ptrace.h> +#include <asm/thread_info.h> +#include <asm/mmu.h> +#include <asm/rsi.h> +#include <linux/compiler.h> +#include <alloc_page.h> +#include <asm/pgtable.h> + +typedef void (*empty_fn)(void); + +static bool test_passed; + +/* + * The virtual address of the page that the test has made the access to + * in order to cause the I/DAbort with I/DFSC = Synchronous External Abort. + */ +static void* target_page_va; + +/* + * Ensure that the @va is the executable location from EL1: + * - SCTLR_EL1.WXN must be off. + * - Disable the access from EL0 (controlled by AP[1] in PTE). + */ +static void enable_instruction_fetch(void* va) +{ + unsigned long sctlr = read_sysreg(sctlr_el1); + if (sctlr & SCTLR_EL1_WXN) { + sctlr &= ~SCTLR_EL1_WXN; + write_sysreg(sctlr, sctlr_el1); + isb(); + flush_tlb_all(); + } + + mmu_clear_user(current_thread_info()->pgtable, (u64)va); +} + +static void data_abort_handler(struct pt_regs *regs, unsigned int esr) +{ + if ((esr & ESR_EL1_FSC_MASK) == ESR_EL1_FSC_EXTABT) + test_passed = true; + + report_info("esr = %x", esr); + /* + * Advance the PC to complete the test. + */ + regs->pc += 4; +} + +static void data_access_to_empty(void) +{ + test_passed = false; + target_page_va = alloc_page(); + phys_addr_t empty_ipa = virt_to_phys(target_page_va); + + arm_set_memory_shared(empty_ipa, SZ_4K); + + install_exception_handler(EL1H_SYNC, ESR_EL1_EC_DABT_EL1, data_abort_handler); + READ_ONCE(((char*)target_page_va)[0x55]); + install_exception_handler(EL1H_SYNC, ESR_EL1_EC_DABT_EL1, NULL); + + report(test_passed, " "); +} + +static void instruction_abort_handler(struct pt_regs *regs, unsigned int esr) +{ + if (((esr & ESR_EL1_FSC_MASK) == ESR_EL1_FSC_EXTABT) && + (regs->pc == (u64)target_page_va)) + test_passed = true; + + report_info("esr = %x", esr); + /* + * Simulate the RET instruction to complete the test. + */ + regs->pc = regs->regs[30]; +} + +static void instr_fetch_from_empty(void) +{ + phys_addr_t empty_ipa; + + test_passed = false; + target_page_va = alloc_page(); + enable_instruction_fetch(target_page_va); + + empty_ipa = virt_to_phys((void*)target_page_va); + + arm_set_memory_shared(empty_ipa, SZ_4K); + + install_exception_handler(EL1H_SYNC, ESR_EL1_EC_IABT_EL1, instruction_abort_handler); + /* + * This should cause the IAbort with IFSC = SEA + */ + ((empty_fn)target_page_va)(); + install_exception_handler(EL1H_SYNC, ESR_EL1_EC_IABT_EL1, NULL); + + report(test_passed, " "); +} + +static void instr_fetch_from_unprotected(void) +{ + test_passed = false; + /* + * The test will attempt to execute an instruction from the start of + * the unprotected IPA space. + */ + target_page_va = vmap(PTE_NS_SHARED, SZ_4K); + enable_instruction_fetch(target_page_va); + + install_exception_handler(EL1H_SYNC, ESR_EL1_EC_IABT_EL1, instruction_abort_handler); + /* + * This should cause the IAbort with IFSC = SEA + */ + ((empty_fn)target_page_va)(); + install_exception_handler(EL1H_SYNC, ESR_EL1_EC_IABT_EL1, NULL); + + report(test_passed, " "); +} + +int main(int argc, char **argv) +{ + report_prefix_push("in_realm_sea"); + + report_prefix_push("data_access_to_empty"); + data_access_to_empty(); + report_prefix_pop(); + + report_prefix_push("instr_fetch_from_empty"); + instr_fetch_from_empty(); + report_prefix_pop(); + + report_prefix_push("instr_fetch_from_unprotected"); + instr_fetch_from_unprotected(); + report_prefix_pop(); + + return report_summary(); +} diff --git a/arm/unittests.cfg b/arm/unittests.cfg index 3cf6b719..e2821c26 100644 --- a/arm/unittests.cfg +++ b/arm/unittests.cfg @@ -311,3 +311,9 @@ smp = 2 groups = nodefault realms accel = kvm arch = arm64 + +[realm-sea] +file = realm-sea.flat +groups = nodefault realms +accel = kvm +arch = arm64 -- 2.34.1
WARNING: multiple messages have this Message-ID (diff)
From: Suzuki K Poulose <suzuki.poulose@arm.com> To: kvmarm@lists.linux.dev Cc: kvm@vger.kernel.org, linux-coco@lists.linux.dev, linux-arm-kernel@lists.infradead.org, maz@kernel.org, alexandru.elisei@arm.com, joey.gouly@arm.com, steven.price@arm.com, james.morse@arm.com, oliver.upton@linux.dev, yuzenghui@huawei.com, andrew.jones@linux.dev, eric.auger@redhat.com, Djordje Kovacevic <djordje.kovacevic@arm.com>, Suzuki K Poulose <suzuki.poulose@arm.com> Subject: [kvm-unit-tests PATCH 20/33] arm: realm: Add tests for in realm SEA Date: Fri, 12 Apr 2024 11:33:55 +0100 [thread overview] Message-ID: <20240412103408.2706058-21-suzuki.poulose@arm.com> (raw) In-Reply-To: <20240412103408.2706058-1-suzuki.poulose@arm.com> From: Djordje Kovacevic <djordje.kovacevic@arm.com> The RMM/Host could inject Synchronous External Aborts in to the Realm for various reasons. RMM injects the SEA for : * Instruction/Data fetch from an IPA that is in RIPAS_EMPTY state * Instruction fetch from an Unprotected IPA. Trigger these conditions from within the Realm and verify that the SEAs are received. Signed-off-by: Djordje Kovacevic <djordje.kovacevic@arm.com> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> --- arm/Makefile.arm64 | 1 + arm/realm-sea.c | 143 +++++++++++++++++++++++++++++++++++++++++++++ arm/unittests.cfg | 6 ++ 3 files changed, 150 insertions(+) create mode 100644 arm/realm-sea.c diff --git a/arm/Makefile.arm64 b/arm/Makefile.arm64 index 5a9943c8..b3e085d3 100644 --- a/arm/Makefile.arm64 +++ b/arm/Makefile.arm64 @@ -59,6 +59,7 @@ tests += $(TEST_DIR)/cache.$(exe) tests += $(TEST_DIR)/debug.$(exe) tests += $(TEST_DIR)/fpu.$(exe) tests += $(TEST_DIR)/realm-rsi.$(exe) +tests += $(TEST_DIR)/realm-sea.$(exe) include $(SRCDIR)/$(TEST_DIR)/Makefile.common diff --git a/arm/realm-sea.c b/arm/realm-sea.c new file mode 100644 index 00000000..5ef3e2a4 --- /dev/null +++ b/arm/realm-sea.c @@ -0,0 +1,143 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 Arm Limited. + * All rights reserved. + */ +#include <libcflat.h> +#include <vmalloc.h> +#include <asm/ptrace.h> +#include <asm/thread_info.h> +#include <asm/mmu.h> +#include <asm/rsi.h> +#include <linux/compiler.h> +#include <alloc_page.h> +#include <asm/pgtable.h> + +typedef void (*empty_fn)(void); + +static bool test_passed; + +/* + * The virtual address of the page that the test has made the access to + * in order to cause the I/DAbort with I/DFSC = Synchronous External Abort. + */ +static void* target_page_va; + +/* + * Ensure that the @va is the executable location from EL1: + * - SCTLR_EL1.WXN must be off. + * - Disable the access from EL0 (controlled by AP[1] in PTE). + */ +static void enable_instruction_fetch(void* va) +{ + unsigned long sctlr = read_sysreg(sctlr_el1); + if (sctlr & SCTLR_EL1_WXN) { + sctlr &= ~SCTLR_EL1_WXN; + write_sysreg(sctlr, sctlr_el1); + isb(); + flush_tlb_all(); + } + + mmu_clear_user(current_thread_info()->pgtable, (u64)va); +} + +static void data_abort_handler(struct pt_regs *regs, unsigned int esr) +{ + if ((esr & ESR_EL1_FSC_MASK) == ESR_EL1_FSC_EXTABT) + test_passed = true; + + report_info("esr = %x", esr); + /* + * Advance the PC to complete the test. + */ + regs->pc += 4; +} + +static void data_access_to_empty(void) +{ + test_passed = false; + target_page_va = alloc_page(); + phys_addr_t empty_ipa = virt_to_phys(target_page_va); + + arm_set_memory_shared(empty_ipa, SZ_4K); + + install_exception_handler(EL1H_SYNC, ESR_EL1_EC_DABT_EL1, data_abort_handler); + READ_ONCE(((char*)target_page_va)[0x55]); + install_exception_handler(EL1H_SYNC, ESR_EL1_EC_DABT_EL1, NULL); + + report(test_passed, " "); +} + +static void instruction_abort_handler(struct pt_regs *regs, unsigned int esr) +{ + if (((esr & ESR_EL1_FSC_MASK) == ESR_EL1_FSC_EXTABT) && + (regs->pc == (u64)target_page_va)) + test_passed = true; + + report_info("esr = %x", esr); + /* + * Simulate the RET instruction to complete the test. + */ + regs->pc = regs->regs[30]; +} + +static void instr_fetch_from_empty(void) +{ + phys_addr_t empty_ipa; + + test_passed = false; + target_page_va = alloc_page(); + enable_instruction_fetch(target_page_va); + + empty_ipa = virt_to_phys((void*)target_page_va); + + arm_set_memory_shared(empty_ipa, SZ_4K); + + install_exception_handler(EL1H_SYNC, ESR_EL1_EC_IABT_EL1, instruction_abort_handler); + /* + * This should cause the IAbort with IFSC = SEA + */ + ((empty_fn)target_page_va)(); + install_exception_handler(EL1H_SYNC, ESR_EL1_EC_IABT_EL1, NULL); + + report(test_passed, " "); +} + +static void instr_fetch_from_unprotected(void) +{ + test_passed = false; + /* + * The test will attempt to execute an instruction from the start of + * the unprotected IPA space. + */ + target_page_va = vmap(PTE_NS_SHARED, SZ_4K); + enable_instruction_fetch(target_page_va); + + install_exception_handler(EL1H_SYNC, ESR_EL1_EC_IABT_EL1, instruction_abort_handler); + /* + * This should cause the IAbort with IFSC = SEA + */ + ((empty_fn)target_page_va)(); + install_exception_handler(EL1H_SYNC, ESR_EL1_EC_IABT_EL1, NULL); + + report(test_passed, " "); +} + +int main(int argc, char **argv) +{ + report_prefix_push("in_realm_sea"); + + report_prefix_push("data_access_to_empty"); + data_access_to_empty(); + report_prefix_pop(); + + report_prefix_push("instr_fetch_from_empty"); + instr_fetch_from_empty(); + report_prefix_pop(); + + report_prefix_push("instr_fetch_from_unprotected"); + instr_fetch_from_unprotected(); + report_prefix_pop(); + + return report_summary(); +} diff --git a/arm/unittests.cfg b/arm/unittests.cfg index 3cf6b719..e2821c26 100644 --- a/arm/unittests.cfg +++ b/arm/unittests.cfg @@ -311,3 +311,9 @@ smp = 2 groups = nodefault realms accel = kvm arch = arm64 + +[realm-sea] +file = realm-sea.flat +groups = nodefault realms +accel = kvm +arch = arm64 -- 2.34.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2024-04-12 10:34 UTC|newest] Thread overview: 102+ messages / expand[flat|nested] mbox.gz Atom feed top 2024-04-12 10:33 [kvm-unit-tests PATCH 00/33] Support for Arm Confidential Compute Architecture Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-10 16:17 ` Itaru Kitayama 2024-04-10 16:17 ` Itaru Kitayama 2024-04-15 8:59 ` Suzuki K Poulose 2024-04-15 8:59 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 01/33] arm: Add necessary header files in asm/pgtable.h Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 02/33] arm: Detect FDT overlap with uninitialised data Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 03/33] arm64: Expand SMCCC arguments and return values Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 04/33] arm: Make physical address mask dynamic Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 05/33] arm64: Introduce NS_SHARED PTE attribute Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 06/33] arm: Move io_init after vm initialization Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 07/33] arm: realm: Add RSI interface header Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 08/33] arm: realm: Make uart available before MMU is enabled Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-22 11:58 ` Alexandru Elisei 2024-04-22 11:58 ` Alexandru Elisei 2024-04-22 12:09 ` Suzuki K Poulose 2024-04-22 12:09 ` Suzuki K Poulose 2024-04-22 12:23 ` Alexandru Elisei 2024-04-22 12:23 ` Alexandru Elisei 2024-04-22 12:36 ` Alexandru Elisei 2024-04-22 12:36 ` Alexandru Elisei 2024-04-22 13:09 ` Suzuki K Poulose 2024-04-22 13:09 ` Suzuki K Poulose 2024-04-22 15:38 ` Alexandru Elisei 2024-04-22 15:38 ` Alexandru Elisei 2024-04-22 16:05 ` Suzuki K Poulose 2024-04-22 16:05 ` Suzuki K Poulose 2024-04-22 16:15 ` Alexandru Elisei 2024-04-22 16:15 ` Alexandru Elisei 2024-04-26 11:15 ` Suzuki K Poulose 2024-04-26 11:15 ` Suzuki K Poulose 2024-04-26 13:51 ` Alexandru Elisei 2024-04-26 13:51 ` Alexandru Elisei 2024-04-12 10:33 ` [kvm-unit-tests PATCH 09/33] arm: realm: Realm initialisation Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 10/33] arm: realm: Add support for changing the state of memory Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 11/33] arm: realm: Set RIPAS state for RAM Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 12/33] arm: realm: Early memory setup Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 13/33] arm: realm: Add RSI version test Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 14/33] arm: selftest: realm: skip pabt test when running in a realm Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-22 15:48 ` Alexandru Elisei 2024-04-22 15:48 ` Alexandru Elisei 2024-04-12 10:33 ` [kvm-unit-tests PATCH 15/33] arm: realm: add hvc and RSI_HOST_CALL tests Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 16/33] arm64: add ESR_ELx EC.SVE Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 17/33] arm64: enable SVE at startup Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 18/33] arm: realm: Add test for FPU/SIMD context save/restore Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-05-10 15:28 ` Andrew Jones 2024-05-10 15:28 ` Andrew Jones 2024-05-14 10:27 ` Suzuki K Poulose 2024-05-14 10:27 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 19/33] arm64: selftest: add realm SVE VL test Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose [this message] 2024-04-12 10:33 ` [kvm-unit-tests PATCH 20/33] arm: realm: Add tests for in realm SEA Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 21/33] lib/alloc_page: Add shared page allocation support Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 22/33] arm: gic-v3-its: Use shared pages wherever needed Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 23/33] arm: realm: Enable memory encryption Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:33 ` [kvm-unit-tests PATCH 24/33] qcbor: Add QCBOR as a submodule Suzuki K Poulose 2024-04-12 10:33 ` Suzuki K Poulose 2024-04-12 10:34 ` [kvm-unit-tests PATCH 25/33] arm: Add build steps for QCBOR library Suzuki K Poulose 2024-04-12 10:34 ` Suzuki K Poulose 2024-04-12 10:34 ` [kvm-unit-tests PATCH 26/33] arm: Add a library to verify tokens using the " Suzuki K Poulose 2024-04-12 10:34 ` Suzuki K Poulose 2024-04-12 10:34 ` [kvm-unit-tests PATCH 27/33] arm: realm: add RSI interface for attestation measurements Suzuki K Poulose 2024-04-12 10:34 ` Suzuki K Poulose 2024-04-12 10:34 ` [kvm-unit-tests PATCH 28/33] arm: realm: Add helpers to decode RSI return codes Suzuki K Poulose 2024-04-12 10:34 ` Suzuki K Poulose 2024-04-12 10:34 ` [kvm-unit-tests PATCH 29/33] arm: realm: Add Realm attestation tests Suzuki K Poulose 2024-04-12 10:34 ` Suzuki K Poulose 2024-04-12 10:34 ` [kvm-unit-tests PATCH 30/33] " Suzuki K Poulose 2024-04-12 10:34 ` Suzuki K Poulose 2024-04-12 10:34 ` [kvm-unit-tests PATCH 31/33] arm: realm: Add a test for shared memory Suzuki K Poulose 2024-04-12 10:34 ` Suzuki K Poulose 2024-04-12 10:34 ` [kvm-unit-tests PATCH 32/33] arm: Add memtest support Suzuki K Poulose 2024-04-12 10:34 ` Suzuki K Poulose 2024-04-12 10:34 ` [kvm-unit-tests PATCH 33/33] NOT-FOR-MERGING: add run-realm-tests Suzuki K Poulose 2024-04-12 10:34 ` Suzuki K Poulose 2024-04-16 14:28 ` [kvm-unit-tests PATCH 00/33] Support for Arm Confidential Compute Architecture Jean-Philippe Brucker 2024-04-16 14:28 ` Jean-Philippe Brucker 2024-05-10 15:23 ` Andrew Jones 2024-05-10 15:23 ` Andrew Jones
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=20240412103408.2706058-21-suzuki.poulose@arm.com \ --to=suzuki.poulose@arm.com \ --cc=alexandru.elisei@arm.com \ --cc=andrew.jones@linux.dev \ --cc=djordje.kovacevic@arm.com \ --cc=eric.auger@redhat.com \ --cc=james.morse@arm.com \ --cc=joey.gouly@arm.com \ --cc=kvm@vger.kernel.org \ --cc=kvmarm@lists.linux.dev \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-coco@lists.linux.dev \ --cc=maz@kernel.org \ --cc=oliver.upton@linux.dev \ --cc=steven.price@arm.com \ --cc=yuzenghui@huawei.com \ /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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.