Fix 5.10 crash on arm64 and update toa.spec. Cherry-pick related commits(a5830ce..f94d2b5) from openEuler-22.03-LTS branch and squash into one commit. Signed-off-by: jiaoff <jiaofenfang@uniontech.com> Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com> (cherry picked from commit e2ca26badf3bd502dd8ab16c4c5a226431bf739f)
264 lines
6.9 KiB
Diff
264 lines
6.9 KiB
Diff
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
|
|
|