diff --git a/0004-fix-crash.patch b/0004-fix-crash.patch new file mode 100644 index 0000000..34d8d3d --- /dev/null +++ b/0004-fix-crash.patch @@ -0,0 +1,263 @@ +diff -Nur a/src/Makefile b/src/Makefile +--- a/src/Makefile 2022-07-26 16:03:59.605586984 +0800 ++++ b/src/Makefile 2022-08-03 17:32:16.825278169 +0800 +@@ -12,7 +12,7 @@ + debug: + make CONFIG_TOA=m -C /lib/modules/${kerver}/build M=`pwd` modules EXTRA_CFLAGS="-DTOA_DBG_MSG" + clean: +- rm -f .*.cmd *.o *.ko *.mod.c modules.order Module.symvers ++ rm -f .*.cmd *.o *.ko *.mod.c modules.order Module.symvers *.mod + rm -rf .tmp_versions + install: + test -d "$(DESTDIR)/lib/modules/${kerver}/extra/net/toa" \ +diff -Nur a/src/toa.c b/src/toa.c +--- a/src/toa.c 2022-07-26 16:03:59.605586984 +0800 ++++ b/src/toa.c 2022-08-03 17:29:42.024204449 +0800 +@@ -45,21 +45,11 @@ + } + + #if defined(CONFIG_ARM64) +-/* +- * ARM64 interface +- * Lookup the page table entry for a virtual address. Return a pointer +- * to the entry and the level of the mapping. +- * +- * Note: We return pud and pmd either when the entry is marked large +- * or when the present bit is not set. Otherwise we would return a +- * pointer to a nonexisting mapping. +- */ +-static pte_t *lookup_address(unsigned long address, unsigned int *level) ++static pmd_t *toa_get_pmd(unsigned long address) + { + pgd_t *pgdp; + pud_t *pudp, pud; +- pmd_t *pmdp, pmd; +- pte_t *ptep; ++ pmd_t *pmdp; + unsigned long addr = address; + + unsigned long init_mm = kallsyms_lookup_name_fun("init_mm"); +@@ -79,12 +69,62 @@ + return NULL; + + pmdp = pmd_offset(pudp, addr); ++ ++ return pmdp; ++} ++ ++static int toa_mkwrite(unsigned long vma) ++{ ++ pmd_t *pmdp, pmd; ++ pte_t *ptep, pte; ++ ++ pmdp = toa_get_pmd(vma); ++ if (NULL == pmdp) ++ return 1; ++ + pmd = READ_ONCE(*pmdp); + if (pmd_none(pmd)) +- return NULL; ++ return 1; ++ ++ if (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT)) { ++ set_pmd(pmdp, __pmd(pmd_val(pmd) & ~PMD_SECT_RDONLY)); ++ } else { ++ ptep = pte_offset_kernel(pmdp, vma); ++ pte = READ_ONCE(*ptep); ++ if (pte_none(pte)) { ++ return 1; ++ } ++ set_pte(ptep, pte_mkwrite(pte)); ++ } ++ ++ return 0; ++} ++ ++static void toa_wrprotect(unsigned long vma) ++{ ++ pmd_t *pmdp, pmd; ++ pte_t *ptep, pte; ++ ++ pmdp = toa_get_pmd(vma); ++ if (NULL == pmdp) ++ return; ++ ++ pmd = READ_ONCE(*pmdp); ++ if (pmd_none(pmd)) ++ return; ++ ++ if (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT)) { ++ set_pmd(pmdp, __pmd(pmd_val(pmd) | PMD_SECT_RDONLY)); ++ } else { ++ ptep = pte_offset_kernel(pmdp, vma); ++ pte = READ_ONCE(*ptep); ++ if (pte_none(pte)) { ++ return; ++ } ++ set_pte(ptep, pte_wrprotect(pte)); ++ } + +- ptep = pte_offset_kernel(pmdp, addr); +- return ptep; ++ return; + } + #endif + +@@ -360,8 +400,12 @@ + static inline int + hook_toa_functions(void) + { ++#if defined(CONFIG_ARM64) ++ int err = 0; ++#else + unsigned int level; + pte_t *pte; ++#endif + + /* hook inet_getname for ipv4 */ + struct proto_ops *inet_stream_ops_p = +@@ -379,15 +423,22 @@ + (struct inet_connection_sock_af_ops *)&ipv6_specific; + #endif + ++#if defined(CONFIG_ARM64) ++ err |= toa_mkwrite((unsigned long)&inet_stream_ops_p->getname); ++ err |= toa_mkwrite((unsigned long)&ipv4_specific_p->syn_recv_sock); ++#ifdef CONFIG_IP_VS_TOA_IPV6 ++ err |= toa_mkwrite((unsigned long)&inet6_stream_ops_p->getname); ++ err |= toa_mkwrite((unsigned long)&ipv6_specific_p->syn_recv_sock); ++#endif ++ if (0 == err) { ++ flush_tlb_all(); ++ } else { ++ return 1; ++ } ++#else + pte = lookup_address((unsigned long )inet_stream_ops_p, &level); + if (pte == NULL) + return 1; +- +-#if defined(CONFIG_ARM64) +- *pte = pte_mkwrite(*pte); +- __sync_icache_dcache(*pte); +- flush_tlb_all(); +-#else + if (pte->pte & ~_PAGE_RW) { + pte->pte |= _PAGE_RW; + } +@@ -396,8 +447,8 @@ + smp_processor_id(), inet_getname, inet_getname_toa);*/ + + inet_stream_ops_p->getname = inet_getname_toa; +- TOA_INFO("CPU [%u] hooked inet_getname <%p> --> <%p>\n", +- smp_processor_id(), inet_getname, inet_stream_ops_p->getname); ++ TOA_INFO("CPU [%u] hooked inet_getname <%p> --> <%p>, <%p>\n", ++ smp_processor_id(), inet_getname, inet_stream_ops_p->getname, inet_getname_toa); + + #ifdef CONFIG_IP_VS_TOA_IPV6 + inet6_stream_ops_p->getname = inet6_getname_toa; +@@ -406,9 +457,10 @@ + #endif + + ipv4_specific_p->syn_recv_sock = tcp_v4_syn_recv_sock_toa; +- TOA_INFO("CPU [%u] hooked tcp_v4_syn_recv_sock <%p> --> <%p>\n", ++ TOA_INFO("CPU [%u] hooked tcp_v4_syn_recv_sock <%p> --> <%p>, <%p>\n", + smp_processor_id(), tcp_v4_syn_recv_sock, +- ipv4_specific_p->syn_recv_sock); ++ ipv4_specific_p->syn_recv_sock, ++ tcp_v4_syn_recv_sock_toa); + + #ifdef CONFIG_IP_VS_TOA_IPV6 + ipv6_specific_p->syn_recv_sock = tcp_v6_syn_recv_sock_toa; +@@ -417,15 +469,18 @@ + ipv6_specific_p->syn_recv_sock); + #endif + +- pte = lookup_address((unsigned long )inet_stream_ops_p, &level); +- if (pte == NULL) +- return 1; +- + #if defined(CONFIG_ARM64) +- *pte = pte_wrprotect(*pte); +- __sync_icache_dcache(*pte); ++ toa_wrprotect((unsigned long)&inet_stream_ops_p->getname); ++ toa_wrprotect((unsigned long)&ipv4_specific_p->syn_recv_sock); ++#ifdef CONFIG_IP_VS_TOA_IPV6 ++ toa_wrprotect((unsigned long)&inet6_stream_ops_p->getname); ++ toa_wrprotect((unsigned long)&ipv6_specific_p->syn_recv_sock); ++#endif + flush_tlb_all(); + #else ++ pte = lookup_address((unsigned long )inet_stream_ops_p, &level); ++ if (pte == NULL) ++ return 1; + pte->pte |= pte->pte &~_PAGE_RW; + #endif + +@@ -436,8 +491,12 @@ + static int + unhook_toa_functions(void) + { ++#if defined(CONFIG_ARM64) ++ int err = 0; ++#else + unsigned int level; + pte_t *pte; ++#endif + + /* unhook inet_getname for ipv4 */ + struct proto_ops *inet_stream_ops_p = +@@ -455,15 +514,22 @@ + (struct inet_connection_sock_af_ops *)&ipv6_specific; + #endif + ++#if defined(CONFIG_ARM64) ++ err |= toa_mkwrite((unsigned long)&inet_stream_ops_p->getname); ++ err |= toa_mkwrite((unsigned long)&ipv4_specific_p->syn_recv_sock); ++#ifdef CONFIG_IP_VS_TOA_IPV6 ++ err |= toa_mkwrite((unsigned long)&inet6_stream_ops_p->getname); ++ err |= toa_mkwrite((unsigned long)&ipv6_specific_p->syn_recv_sock); ++#endif ++ if (0 == err) { ++ flush_tlb_all(); ++ } else { ++ return 1; ++ } ++#else + pte = lookup_address((unsigned long )inet_stream_ops_p, &level); + if (pte == NULL) + return 1; +- +-#if defined(CONFIG_ARM64) +- *pte = pte_mkwrite(*pte); +- __sync_icache_dcache(*pte); +- flush_tlb_all(); +-#else + if (pte->pte & ~_PAGE_RW) { + pte->pte |= _PAGE_RW; + } +@@ -491,15 +557,18 @@ + smp_processor_id()); + #endif + +- pte = lookup_address((unsigned long )inet_stream_ops_p, &level); +- if (pte == NULL) +- return 1; +- + #if defined(CONFIG_ARM64) +- *pte = pte_wrprotect(*pte); +- __sync_icache_dcache(*pte); ++ toa_wrprotect((unsigned long)&inet_stream_ops_p->getname); ++ toa_wrprotect((unsigned long)&ipv4_specific_p->syn_recv_sock); ++#ifdef CONFIG_IP_VS_TOA_IPV6 ++ toa_wrprotect((unsigned long)&inet6_stream_ops_p->getname); ++ toa_wrprotect((unsigned long)&ipv6_specific_p->syn_recv_sock); ++#endif + flush_tlb_all(); + #else ++ pte = lookup_address((unsigned long )inet_stream_ops_p, &level); ++ if (pte == NULL) ++ return 1; + pte->pte |= pte->pte &~_PAGE_RW; + #endif + diff --git a/toa.spec b/toa.spec index b098ffc..3a28cbd 100644 --- a/toa.spec +++ b/toa.spec @@ -5,7 +5,7 @@ Name: TCP_option_address Summary: Intel(R) Ethernet Adaptive Virtual Function Driver Version: 1.0.0 -Release: 1 +Release: 3 #Release: 0.%{krelver} Vendor: Huawei License: GPL-2.0 @@ -15,6 +15,7 @@ Source0: TCP_option_address.tar.gz Patch0001: 0001-support-arm64.patch Patch0002: 0002-fix-build-error.patch Patch0003: 0003-patch-for-5_10.patch +Patch0004: 0004-fix-crash.patch Requires: kernel, findutils, gawk, bash @@ -104,5 +105,11 @@ else fi %changelog +* Wed Aug 03 2022 jiaofenfang - 1.0.0-3 +- fix crash on the arm64 + +* Sat Jul 30 2022 jiaofenfang - 1.0.0-2 +- fix 5.10 crash on the arm64 + * Mon Jan 24 2022 jiaofenfang - 1.0.0-1 - Package init