From 661b7b749fb65c055ccbc19c485a28c39560ebe8 Mon Sep 17 00:00:00 2001 From: liuzh Date: Thu, 7 Nov 2024 16:22:30 +0800 Subject: [PATCH 1/8] Update HAOC patch and spec for 6.6.0-50.0.0 --- 0005-haoc-kernel.patch | 25836 +++++++++++++++++++++++++-------------- haoc-kernel.spec | 6917 ++++++++++- 2 files changed, 23653 insertions(+), 9100 deletions(-) diff --git a/0005-haoc-kernel.patch b/0005-haoc-kernel.patch index 2d9484f..b8fd07e 100644 --- a/0005-haoc-kernel.patch +++ b/0005-haoc-kernel.patch @@ -1,238 +1,247 @@ -From 099672494b5fbd626031f313bbdbc42d1eb3f02d Mon Sep 17 00:00:00 2001 -From: liuzh -Date: Wed, 22 May 2024 16:36:55 +0800 -Subject: [PATCH] Squashed commit of the following: +From b84a30c244472627ddbf03ce5f3af67bdcc888ad Mon Sep 17 00:00:00 2001 +From: Liu Zhehui +Date: Wed, 6 Nov 2024 15:28:01 +0800 +Subject: [PATCH] Publish k1 code on 6.6.0-50.0.0 -commit 909ad06b3bf629d9af4e143347c1d1ef8a3a5808 -Author: liuzh -Date: Wed May 22 16:23:13 2024 +0800 - - fix mte_sync_tags() parameters after rebase to 6.6.0-27.0.0. - -commit 1cbf51371b0539a45f816419b2da82cf36162b4a -Author: ljl -Date: Mon Mar 25 08:01:32 2024 +0000 - - IEE SI: Removed redundant codes. - -commit 0178bfc79ad1769a36f4165348a671d2182cff55 -Author: zhangsy -Date: Mon Mar 25 11:01:11 2024 +0800 - - Fix bugs on qemu when opening CONFIG_CREDP. - -commit 8e714f6e8f2ace5a6fc900b4bce6b03c83c41870 -Author: ljl -Date: Thu Mar 21 04:44:26 2024 +0000 - - IEE SI: Remove PAN operations as BTLB BUG is already fixed. - -commit 7b5fc74cb99e377d3bc59da81612cd6f3dd8a4d8 -Author: ljl -Date: Wed Mar 20 18:31:47 2024 +0800 - - IEE SI: Migration of iee rwx gate. - -commit aad2c7e89c9c4ad8ff0fb3ee53cd1b974144a283 -Author: liuzh -Date: Mon Mar 18 15:32:43 2024 +0800 - - modify slub.c set_track_prepare() - -commit 7452bac06ec09bf8321dfdbfb8b6a429d2cd8637 -Author: zhangsy -Date: Thu Mar 21 11:26:19 2024 +0800 - - Set pgd of lm Privileged. - -commit 33934cfc3eed798a3a687bf86c6bd92697e68ba9 -Author: zhangsy -Date: Tue Mar 19 17:14:32 2024 +0800 - - Delete some redundant code and put trans_pgd into IEE. - -commit 2bfe9008a72f8b8ac237bc7a5f99f9d40e84c247 -Author: zhangshiyang17@mails.ucas.ac.cn -Date: Mon Mar 18 11:47:50 2024 +0000 - - Fix bugs on physical when opening CONFIG_IEE and CONFIG_PTP. - -commit dafa2df600757511ce3e8f178e05e28adabdf39b -Author: zhangsy -Date: Mon Mar 18 10:40:42 2024 +0800 - - Fix bugs on qemu when opening CONFIG_IEE and CONFIG_PTP. - -commit 9231a9f6b34c62090b5f202c9c64a52bfdac7a73 -Author: zhangsy -Date: Thu Mar 14 16:34:53 2024 +0800 - - Fix compiling bugs of CONFIG_PTP. - -commit 6469df3bcce32896c2cb297d3cd7ead82c33f35d -Author: zhangsy -Date: Thu Mar 14 11:10:00 2024 +0800 - - Fix bugs on qemu when opening CONFIG_IEE and CONFIG_INTERRUPTABLE. - -commit 5f1773dada622a3514c9ed6aa72dd50e918f2664 -Author: zhangsy -Date: Wed Mar 13 17:31:39 2024 +0800 - - Fix bugs on qemu when opening CONFIG_IEE. - -commit 73f433a093fa84cffa5e11e86bed6f17c9b30a39 -Author: liuzh -Date: Tue Mar 12 15:32:29 2024 +0800 - - fix the map of IEE_SI_TEXT. - -commit 9b92deb4b2338093d9b04f4b81f162855b31c983 -Author: liuzh -Date: Sun Mar 10 16:11:13 2024 +0800 - - modified to be able to compile. - can start the kernel with qemu and successfully reach `start_kernel()`. - -commit e892ec4790d72e9433b48b0221e7e6dc4c361dd9 -Author: liuzh -Date: Thu Mar 7 14:27:45 2024 +0800 - - fix some conflicts - -commit fdec7e39345e81e867e01258487f88801b790b02 -Author: liuzh -Date: Wed Mar 6 12:31:11 2024 +0800 - - migrate openeuler-commit code. (need some fix before compiling) +internal branch: OLK-6.6-tmp +internal commit: 0ba70cc4 --- - Makefile | 3 +- - arch/arm64/Kconfig | 18 + - arch/arm64/include/asm/assembler.h | 67 + - arch/arm64/include/asm/daifflags.h | 16 + - arch/arm64/include/asm/efi.h | 4 + - arch/arm64/include/asm/fixmap.h | 3 + - arch/arm64/include/asm/hw_breakpoint.h | 12 + - arch/arm64/include/asm/iee-access.h | 36 + - arch/arm64/include/asm/iee-cred.h | 150 ++ - arch/arm64/include/asm/iee-def.h | 74 + - arch/arm64/include/asm/iee-si.h | 64 + - arch/arm64/include/asm/iee-slab.h | 23 + - arch/arm64/include/asm/iee-token.h | 40 + - arch/arm64/include/asm/iee.h | 10 + - arch/arm64/include/asm/kernel-pgtable.h | 21 + - arch/arm64/include/asm/koi.h | 335 +++++ - arch/arm64/include/asm/memory.h | 24 + - arch/arm64/include/asm/mmu_context.h | 20 + - arch/arm64/include/asm/pgalloc.h | 4 + - arch/arm64/include/asm/pgtable-hwdef.h | 11 + - arch/arm64/include/asm/pgtable.h | 304 +++- - arch/arm64/include/asm/pointer_auth.h | 5 + - arch/arm64/include/asm/sysreg.h | 58 + - arch/arm64/include/asm/tlb.h | 9 + - arch/arm64/include/asm/tlbflush.h | 58 +- - arch/arm64/kernel/Makefile | 2 + - arch/arm64/kernel/armv8_deprecated.c | 16 + - arch/arm64/kernel/asm-offsets.c | 11 + - arch/arm64/kernel/cpu_errata.c | 12 + - arch/arm64/kernel/cpufeature.c | 79 + - arch/arm64/kernel/debug-monitors.c | 4 + - arch/arm64/kernel/entry-common.c | 4 + - arch/arm64/kernel/entry.S | 611 ++++++++ - arch/arm64/kernel/fpsimd.c | 4 + - arch/arm64/kernel/head.S | 56 + - arch/arm64/kernel/hibernate.c | 14 + - arch/arm64/kernel/hw_breakpoint.c | 99 ++ - arch/arm64/kernel/iee/Makefile | 1 + - arch/arm64/kernel/iee/iee-func.c | 187 +++ - arch/arm64/kernel/iee/iee-gate.S | 174 +++ - arch/arm64/kernel/iee/iee.c | 1360 +++++++++++++++++ - arch/arm64/kernel/koi/Makefile | 1 + - arch/arm64/kernel/koi/koi.c | 1327 +++++++++++++++++ - arch/arm64/kernel/mte.c | 5 + - arch/arm64/kernel/process.c | 19 +- - arch/arm64/kernel/proton-pack.c | 8 + - arch/arm64/kernel/setup.c | 33 + - arch/arm64/kernel/traps.c | 26 + - arch/arm64/kernel/vmlinux.lds.S | 61 + - arch/arm64/mm/context.c | 91 +- - arch/arm64/mm/fault.c | 9 + - arch/arm64/mm/fixmap.c | 74 +- - arch/arm64/mm/init.c | 34 + - arch/arm64/mm/mmu.c | 1780 +++++++++++++++++++---- - arch/arm64/mm/pgd.c | 39 + - arch/arm64/mm/proc.S | 28 + - arch/arm64/mm/trans_pgd.c | 46 + - drivers/firmware/efi/arm-runtime.c | 4 + - drivers/firmware/efi/memmap.c | 20 + - drivers/tty/serial/earlycon.c | 4 + - drivers/usb/early/ehci-dbgp.c | 4 + - fs/coredump.c | 8 + - fs/exec.c | 20 + - fs/nfs/flexfilelayout/flexfilelayout.c | 9 + - fs/nfs/nfs4idmap.c | 9 + - fs/nfsd/auth.c | 38 + - fs/nfsd/nfs4callback.c | 12 +- - fs/nfsd/nfs4recover.c | 9 + - fs/nfsd/nfsfh.c | 9 + - fs/open.c | 26 + - fs/overlayfs/dir.c | 9 + - fs/overlayfs/super.c | 12 + - fs/smb/client/cifs_spnego.c | 9 + - fs/smb/client/cifsacl.c | 9 + - include/asm-generic/early_ioremap.h | 3 + - include/asm-generic/fixmap.h | 18 + - include/asm-generic/pgalloc.h | 54 + - include/asm-generic/vmlinux.lds.h | 24 +- - include/linux/cred.h | 45 +- - include/linux/efi.h | 9 + - include/linux/iee-func.h | 27 + - include/linux/module.h | 1 + - include/linux/sched.h | 19 + - init/main.c | 28 +- - kernel/cred.c | 182 +++ - kernel/exit.c | 8 + - kernel/fork.c | 316 ++-- - kernel/groups.c | 7 + - kernel/kthread.c | 13 + - kernel/smpboot.c | 9 + - kernel/sys.c | 107 ++ - kernel/umh.c | 10 + - kernel/user_namespace.c | 18 + - mm/Kconfig | 12 + - mm/damon/ops-common.c | 1 + - mm/debug_vm_pgtable.c | 24 + - mm/early_ioremap.c | 57 + - mm/huge_memory.c | 30 +- - mm/init-mm.c | 17 + - mm/memory.c | 14 + - mm/slub.c | 198 ++- - mm/sparse-vmemmap.c | 21 + - mm/vmalloc.c | 2 +- - net/dns_resolver/dns_key.c | 9 + - security/commoncap.c | 169 +++ - security/keys/keyctl.c | 23 + - security/keys/process_keys.c | 53 + - security/security.c | 15 + - 109 files changed, 8945 insertions(+), 397 deletions(-) + .gitignore | 4 + + Makefile | 4 +- + arch/arm64/Kconfig | 35 + + arch/arm64/configs/openeuler_defconfig | 8 +- + arch/arm64/include/asm/assembler.h | 67 + + arch/arm64/include/asm/daifflags.h | 16 + + arch/arm64/include/asm/efi.h | 4 + + arch/arm64/include/asm/fixmap.h | 3 + + arch/arm64/include/asm/hw_breakpoint.h | 12 + + arch/arm64/include/asm/iee-access.h | 47 + + arch/arm64/include/asm/iee-cred.h | 150 ++ + arch/arm64/include/asm/iee-def.h | 37 + + arch/arm64/include/asm/iee-key.h | 154 ++ + arch/arm64/include/asm/iee-selinuxp.h | 27 + + arch/arm64/include/asm/iee-si.h | 65 + + arch/arm64/include/asm/iee-slab.h | 23 + + arch/arm64/include/asm/iee-token.h | 34 + + arch/arm64/include/asm/iee.h | 10 + + arch/arm64/include/asm/kernel-pgtable.h | 21 + + arch/arm64/include/asm/koi.h | 531 +++++ + arch/arm64/include/asm/memory.h | 28 + + arch/arm64/include/asm/mmu_context.h | 20 + + arch/arm64/include/asm/pgalloc.h | 4 + + arch/arm64/include/asm/pgtable-hwdef.h | 11 + + arch/arm64/include/asm/pgtable.h | 191 +- + arch/arm64/include/asm/pgtable_slab.h | 8 + + arch/arm64/include/asm/pointer_auth.h | 5 + + arch/arm64/include/asm/stack_slab.h | 8 + + arch/arm64/include/asm/sysreg.h | 58 + + arch/arm64/include/asm/tlb.h | 20 + + arch/arm64/include/asm/tlbflush.h | 58 +- + arch/arm64/kernel/Makefile | 2 + + arch/arm64/kernel/armv8_deprecated.c | 16 + + arch/arm64/kernel/asm-offsets.c | 13 + + arch/arm64/kernel/cpu_errata.c | 12 + + arch/arm64/kernel/cpufeature.c | 79 + + arch/arm64/kernel/debug-monitors.c | 4 + + arch/arm64/kernel/entry-common.c | 4 + + arch/arm64/kernel/entry.S | 625 +++++- + arch/arm64/kernel/fpsimd.c | 4 + + arch/arm64/kernel/head.S | 5 + + arch/arm64/kernel/hibernate.c | 9 + + arch/arm64/kernel/hw_breakpoint.c | 99 + + arch/arm64/kernel/iee/Makefile | 5 + + arch/arm64/kernel/iee/iee-func.c | 720 +++++++ + arch/arm64/kernel/iee/iee-gate.S | 314 +++ + arch/arm64/kernel/iee/iee-key.c | 12 + + arch/arm64/kernel/iee/iee-pgtable.c | 402 ++++ + arch/arm64/kernel/iee/iee-selinuxp.c | 36 + + arch/arm64/kernel/iee/iee.c | 1734 ++++++++++++++++ + arch/arm64/kernel/iee/pgtable_slab.c | 97 + + arch/arm64/kernel/iee/stack_slab.c | 19 + + arch/arm64/kernel/irq.c | 4 +- + arch/arm64/kernel/koi/Makefile | 1 + + arch/arm64/kernel/koi/koi.c | 1688 ++++++++++++++++ + arch/arm64/kernel/mte.c | 5 + + arch/arm64/kernel/process.c | 13 +- + arch/arm64/kernel/proton-pack.c | 8 + + arch/arm64/kernel/setup.c | 34 + + arch/arm64/kernel/traps.c | 26 + + arch/arm64/kernel/vmlinux.lds.S | 60 + + arch/arm64/mm/context.c | 125 +- + arch/arm64/mm/fault.c | 13 + + arch/arm64/mm/fixmap.c | 74 +- + arch/arm64/mm/init.c | 36 + + arch/arm64/mm/mmu.c | 1786 +++++++++++++++-- + arch/arm64/mm/pgd.c | 30 + + arch/arm64/mm/proc.S | 8 + + arch/arm64/mm/trans_pgd.c | 36 + + block/sed-opal.c | 8 + + certs/blacklist.c | 8 + + certs/system_keyring.c | 18 + + crypto/af_alg.c | 16 + + crypto/asymmetric_keys/asymmetric_type.c | 21 + + crypto/asymmetric_keys/public_key.c | 16 + + crypto/asymmetric_keys/signature.c | 10 + + drivers/firmware/efi/arm-runtime.c | 4 + + drivers/firmware/efi/memmap.c | 20 + + drivers/md/Makefile | 1 + + drivers/md/dm-crypt.c | 20 + + drivers/md/dm-verity-verify-sig.c | 8 + + drivers/nvdimm/security.c | 24 + + drivers/rtc/rtc-test.c | 2 +- + drivers/tty/serial/earlycon.c | 4 + + drivers/usb/early/ehci-dbgp.c | 4 + + fs/coredump.c | 8 + + fs/crypto/keyring.c | 13 + + fs/crypto/keysetup_v1.c | 12 + + fs/ecryptfs/ecryptfs_kernel.h | 4 + + fs/ecryptfs/keystore.c | 52 + + fs/ecryptfs/main.c | 4 + + fs/exec.c | 23 + + fs/nfs/flexfilelayout/flexfilelayout.c | 9 + + fs/nfs/nfs4idmap.c | 24 + + fs/nfsd/auth.c | 38 + + fs/nfsd/nfs4callback.c | 12 +- + fs/nfsd/nfs4recover.c | 9 + + fs/nfsd/nfsfh.c | 9 + + fs/open.c | 26 + + fs/overlayfs/dir.c | 9 + + fs/overlayfs/super.c | 12 + + fs/smb/client/cifs_spnego.c | 30 + + fs/smb/client/cifsacl.c | 52 + + fs/smb/client/connect.c | 8 + + fs/smb/client/sess.c | 4 + + fs/smb/client/smb2pdu.c | 4 + + fs/ubifs/auth.c | 8 + + fs/verity/signature.c | 4 + + include/asm-generic/early_ioremap.h | 3 + + include/asm-generic/fixmap.h | 18 + + include/asm-generic/pgalloc.h | 7 + + include/asm-generic/tlb.h | 7 + + include/asm-generic/vmlinux.lds.h | 34 +- + include/keys/asymmetric-subtype.h | 4 + + include/keys/asymmetric-type.h | 8 + + include/keys/request_key_auth-type.h | 4 + + include/linux/cred.h | 46 +- + include/linux/efi.h | 9 + + include/linux/iee-flag.h | 116 ++ + include/linux/iee-func.h | 35 + + include/linux/key.h | 83 + + include/linux/mm.h | 103 + + include/linux/mm_types.h | 39 + + include/linux/module.h | 1 + + include/linux/sched.h | 19 + + init/main.c | 31 +- + kernel/cred.c | 186 ++ + kernel/exit.c | 7 + + kernel/fork.c | 286 +-- + kernel/groups.c | 7 + + kernel/kthread.c | 11 + + kernel/module/main.c | 105 +- + kernel/sys.c | 107 + + kernel/umh.c | 10 + + kernel/user_namespace.c | 18 + + lib/digsig.c | 8 + + mm/Kconfig | 5 + + mm/damon/ops-common.c | 1 + + mm/debug_vm_pgtable.c | 32 + + mm/early_ioremap.c | 57 + + mm/huge_memory.c | 10 +- + mm/hugetlb_vmemmap.c | 2 +- + mm/init-mm.c | 16 + + mm/memory.c | 71 + + mm/mmap.c | 8 + + mm/mmu_gather.c | 117 ++ + mm/pgtable-generic.c | 28 + + mm/slab.h | 27 + + mm/slab_common.c | 35 + + mm/slub.c | 407 +++- + mm/sparse-vmemmap.c | 12 + + mm/vmalloc.c | 2 +- + net/ceph/ceph_common.c | 4 + + net/ceph/crypto.c | 4 + + net/dns_resolver/dns_key.c | 24 + + net/dns_resolver/dns_query.c | 18 + + net/rxrpc/af_rxrpc.c | 4 + + net/rxrpc/conn_event.c | 5 + + net/rxrpc/key.c | 16 + + net/rxrpc/rxkad.c | 41 + + net/rxrpc/security.c | 8 + + net/rxrpc/sendmsg.c | 4 + + net/rxrpc/server_key.c | 8 + + security/commoncap.c | 169 ++ + security/integrity/evm/evm_crypto.c | 12 + + security/keys/big_key.c | 16 + + security/keys/dh.c | 8 + + security/keys/encrypted-keys/encrypted.c | 28 + + .../keys/encrypted-keys/masterkey_trusted.c | 5 + + security/keys/gc.c | 52 + + security/keys/internal.h | 8 + + security/keys/key.c | 233 ++- + security/keys/keyctl.c | 91 + + security/keys/keyring.c | 264 +++ + security/keys/proc.c | 28 + + security/keys/process_keys.c | 88 + + security/keys/request_key.c | 16 + + security/keys/request_key_auth.c | 20 + + security/keys/trusted-keys/trusted_core.c | 8 + + security/keys/user_defined.c | 10 + + security/security.c | 15 + + security/selinux/hooks.c | 60 + + security/selinux/ima.c | 20 + + security/selinux/include/security.h | 8 + + security/selinux/selinuxfs.c | 66 + + security/selinux/ss/services.c | 56 + + security/selinux/status.c | 32 + + security/smack/smack_lsm.c | 12 + + 188 files changed, 13637 insertions(+), 345 deletions(-) create mode 100644 arch/arm64/include/asm/iee-access.h create mode 100644 arch/arm64/include/asm/iee-cred.h create mode 100644 arch/arm64/include/asm/iee-def.h + create mode 100644 arch/arm64/include/asm/iee-key.h + create mode 100644 arch/arm64/include/asm/iee-selinuxp.h create mode 100644 arch/arm64/include/asm/iee-si.h create mode 100644 arch/arm64/include/asm/iee-slab.h create mode 100644 arch/arm64/include/asm/iee-token.h create mode 100644 arch/arm64/include/asm/iee.h create mode 100644 arch/arm64/include/asm/koi.h + create mode 100644 arch/arm64/include/asm/pgtable_slab.h + create mode 100644 arch/arm64/include/asm/stack_slab.h create mode 100644 arch/arm64/kernel/iee/Makefile create mode 100644 arch/arm64/kernel/iee/iee-func.c create mode 100644 arch/arm64/kernel/iee/iee-gate.S + create mode 100644 arch/arm64/kernel/iee/iee-key.c + create mode 100644 arch/arm64/kernel/iee/iee-pgtable.c + create mode 100644 arch/arm64/kernel/iee/iee-selinuxp.c create mode 100644 arch/arm64/kernel/iee/iee.c + create mode 100644 arch/arm64/kernel/iee/pgtable_slab.c + create mode 100644 arch/arm64/kernel/iee/stack_slab.c create mode 100644 arch/arm64/kernel/koi/Makefile create mode 100644 arch/arm64/kernel/koi/koi.c + create mode 100644 include/linux/iee-flag.h create mode 100644 include/linux/iee-func.h +diff --git a/.gitignore b/.gitignore +index d1a8ab3f98aa..f87d7b8380ab 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -51,6 +51,7 @@ + *.tar + *.xz + *.zst ++*.log + Module.symvers + modules.order + +@@ -169,3 +170,6 @@ sphinx_*/ + + # Rust analyzer configuration + /rust-project.json ++ ++#command ++command.txt diff --git a/Makefile b/Makefile -index 8e6d9b894b1e..20c367b5957d 100644 +index ee377cec01f3..d36eeeb0c9a8 100644 --- a/Makefile +++ b/Makefile @@ -554,7 +554,7 @@ LINUXINCLUDE := \ @@ -244,19 +253,20 @@ index 8e6d9b894b1e..20c367b5957d 100644 KBUILD_CFLAGS := KBUILD_CFLAGS += -std=gnu11 -@@ -563,6 +563,7 @@ KBUILD_CFLAGS += -funsigned-char +@@ -563,6 +563,8 @@ KBUILD_CFLAGS += -funsigned-char KBUILD_CFLAGS += -fno-common KBUILD_CFLAGS += -fno-PIE KBUILD_CFLAGS += -fno-strict-aliasing +KBUILD_CFLAGS += -march=armv8.1-a ++#KBUILD_CFLAGS += -fPIC KBUILD_CPPFLAGS := -D__KERNEL__ KBUILD_RUSTFLAGS := $(rust_common_flags) \ diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig -index 2a875546bdc7..7448afc90c0a 100644 +index 501ec560a939..ae30b4c5d549 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig -@@ -1730,6 +1730,24 @@ config UNMAP_KERNEL_AT_EL0 +@@ -1731,6 +1731,41 @@ config UNMAP_KERNEL_AT_EL0 If unsure, say Y. @@ -277,10 +287,67 @@ index 2a875546bdc7..7448afc90c0a 100644 +config CREDP + depends on IEE + def_bool y ++ ++# Config for kernel module isolation ++config KOI ++ depends on ARM64 ++ depends on ARM64_VA_BITS_48 ++ depends on ARM64_4K_PAGES ++ def_bool y ++ ++config IEE_SELINUX_P ++ depends on IEE ++ depends on SECURITY_SELINUX ++ def_bool y ++ ++# Config for key isolation ++config KEYP ++ depends on IEE ++ def_bool y + config MITIGATE_SPECTRE_BRANCH_HISTORY bool "Mitigate Spectre style attacks against branch history" if EXPERT default y +diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig +index 61f3e4e34e64..7d3d2fc3d972 100644 +--- a/arch/arm64/configs/openeuler_defconfig ++++ b/arch/arm64/configs/openeuler_defconfig +@@ -1377,7 +1377,7 @@ CONFIG_NETFILTER_NETLINK_ACCT=m + CONFIG_NETFILTER_NETLINK_QUEUE=m + CONFIG_NETFILTER_NETLINK_LOG=m + CONFIG_NETFILTER_NETLINK_OSF=m +-CONFIG_NF_CONNTRACK=m ++CONFIG_NF_CONNTRACK=y + CONFIG_NF_LOG_SYSLOG=m + CONFIG_NETFILTER_CONNCOUNT=m + CONFIG_NF_CONNTRACK_MARK=y +@@ -1408,7 +1408,7 @@ CONFIG_NF_CT_NETLINK=m + CONFIG_NF_CT_NETLINK_TIMEOUT=m + CONFIG_NF_CT_NETLINK_HELPER=m + CONFIG_NETFILTER_NETLINK_GLUE_CT=y +-CONFIG_NF_NAT=m ++CONFIG_NF_NAT=y + CONFIG_NF_NAT_AMANDA=m + CONFIG_NF_NAT_FTP=m + CONFIG_NF_NAT_IRC=m +@@ -1612,7 +1612,7 @@ CONFIG_IP_VS_PE_SIP=m + # + # IP: Netfilter Configuration + # +-CONFIG_NF_DEFRAG_IPV4=m ++CONFIG_NF_DEFRAG_IPV4=y + CONFIG_NF_SOCKET_IPV4=m + CONFIG_NF_TPROXY_IPV4=m + CONFIG_NF_TABLES_IPV4=y +@@ -1684,7 +1684,7 @@ CONFIG_IP6_NF_TARGET_MASQUERADE=m + CONFIG_IP6_NF_TARGET_NPT=m + # end of IPv6: Netfilter Configuration + +-CONFIG_NF_DEFRAG_IPV6=m ++CONFIG_NF_DEFRAG_IPV6=y + CONFIG_NF_TABLES_BRIDGE=m + # CONFIG_NFT_BRIDGE_META is not set + CONFIG_NFT_BRIDGE_REJECT=m diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index 38b23786aeb4..6af10d509c2e 100644 --- a/arch/arm64/include/asm/assembler.h @@ -499,13 +566,14 @@ index 84055329cd8b..f72d89bb9a32 100644 struct perf_event_attr; diff --git a/arch/arm64/include/asm/iee-access.h b/arch/arm64/include/asm/iee-access.h new file mode 100644 -index 000000000000..79604c21a510 +index 000000000000..cfa76c140bee --- /dev/null +++ b/arch/arm64/include/asm/iee-access.h -@@ -0,0 +1,36 @@ +@@ -0,0 +1,47 @@ +#ifndef _LINUX_IEE_ACCESS_H +#define _LINUX_IEE_ACCESS_H + ++#include +#include +#include + @@ -522,6 +590,11 @@ index 000000000000..79604c21a510 + iee_rw_gate(IEE_MEMSET, ptr, data, n); +} + ++void iee_memcpy(void *dst, void *src, size_t n) ++{ ++ iee_rw_gate(IEE_MEMCPY, dst, src, n); ++} ++ +void iee_set_track(struct track *ptr, struct track *data) +{ + iee_rw_gate(IEE_OP_SET_TRACK, ptr, data); @@ -532,9 +605,14 @@ index 000000000000..79604c21a510 + iee_rw_gate(IEE_OP_SET_FREEPTR, pptr, ptr); +} + -+void iee_write_entry_task(struct task_struct *tsk) ++void iee_copy_pte_range(pte_t *new_dst, pte_t *old_dst, pte_t *src_pte, struct vm_area_struct *src_vma, unsigned long dst_vm_flags, pte_t *end_pte) ++{ ++ iee_rw_gate(IEE_COPY_PTE_RANGE, new_dst, old_dst, src_pte, src_vma, dst_vm_flags, end_pte); ++} ++ ++void iee_split_huge_pmd(pmd_t *pmdp, pte_t *pgtable) +{ -+ iee_rw_gate(IEE_WRITE_ENTRY_TASK, tsk); ++ iee_rw_gate(IEE_SPLIT_HUGE_PMD, pmdp, pgtable); +} +#endif + @@ -699,72 +777,12 @@ index 000000000000..b8c3bb53f98a \ No newline at end of file diff --git a/arch/arm64/include/asm/iee-def.h b/arch/arm64/include/asm/iee-def.h new file mode 100644 -index 000000000000..76e59259e4d1 +index 000000000000..2d2b4301ebb3 --- /dev/null +++ b/arch/arm64/include/asm/iee-def.h -@@ -0,0 +1,74 @@ -+// Function Identifiers with Parameters Description -+ -+#define IEE_WRITE_IN_BYTE 0 // Parameters: void *ptr, __u64 data, int length -+#define IEE_OP_SET_PTE 1 // Parameters: pte_t *ptep, pte_t pte -+#define IEE_OP_SET_PMD 2 // Parameters: pmd_t *pmdp, pmd_t pmd -+#define IEE_OP_SET_PUD 3 // Parameters: pud_t *pudp, pud_t pud -+#define IEE_OP_SET_P4D 4 // Parameters: p4d_t *p4dp, p4d_t p4d -+#define IEE_OP_SET_BM_PTE 5 // Parameters: pte_t *ptep, pte_t pte -+#define IEE_OP_SET_SWAPPER_PGD 6 // Parameters: pgd_t *pgdp, pgd_t pgd -+#define IEE_OP_SET_TRAMP_PGD 7 // Parameters: pgd_t *pgdp, pgd_t pgd -+#define IEE_OP_SET_CMPXCHG 8 // Parameters: pte_t *ptep, pteval_t old_pteval, pteval_t new_pteval -+#define IEE_OP_SET_XCHG 9 // Parameters: pte_t *ptep, pteval_t pteval -+#define IEE_OP_COPY_CRED 10 // Parameters: struct cred *old, struct cred *new -+#define IEE_OP_SET_CRED_UID 11 // Parameters: struct cred *cred, kuid_t uid -+#define IEE_OP_SET_CRED_GID 12 // Parameters: struct cred *cred, kgid_t gid -+#define IEE_OP_SET_CRED_SUID 13 // Parameters: struct cred *cred, kuid_t suid -+#define IEE_OP_SET_CRED_SGID 14 // Parameters: struct cred *cred, kgid_t sgid -+#define IEE_OP_SET_CRED_EUID 15 // Parameters: struct cred *cred, kuid_t euid -+#define IEE_OP_SET_CRED_EGID 16 // Parameters: struct cred *cred, kgid_t egid -+#define IEE_OP_SET_CRED_FSUID 17 // Parameters: struct cred *cred, kuid_t fsuid -+#define IEE_OP_SET_CRED_FSGID 18 // Parameters: struct cred *cred, kgid_t fsgid -+#define IEE_OP_SET_CRED_USER 19 // Parameters: struct cred *cred, struct user_struct *user -+#define IEE_OP_SET_CRED_USER_NS 20 // Parameters: struct cred *cred, struct user_namespace *user_ns -+#define IEE_OP_SET_CRED_GROUP_INFO 21 // Parameters: struct cred *cred, struct group_info *group_info -+#define IEE_OP_SET_CRED_SECUREBITS 22 // Parameters: struct cred *cred, unsigned securebits -+#define IEE_OP_SET_CRED_CAP_INHER 23 // Parameters: struct cred *cred, kernel_cap_t cap_inheritable -+#define IEE_OP_SET_CRED_CAP_PERM 24 // Parameters: struct cred *cred, kernel_cap_t cap_permitted -+#define IEE_OP_SET_CRED_CAP_EFFECT 25 // Parameters: struct cred *cred, kernel_cap_t cap_effective -+#define IEE_OP_SET_CRED_CAP_BSET 26 // Parameters: struct cred *cred, kernel_cap_t cap_bset -+#define IEE_OP_SET_CRED_CAP_AMBIENT 27 // Parameters: struct cred *cred, kernel_cap_t cap_ambient -+#define IEE_OP_SET_CRED_JIT_KEYRING 28 // Parameters: struct cred *cred, unsigned char jit_keyring -+#define IEE_OP_SET_CRED_SESS_KEYRING 29 // Parameters: struct cred *cred, struct key *session_keyring -+#define IEE_OP_SET_CRED_PROC_KEYRING 30 // Parameters: struct cred *cred, struct key *process_keyring -+#define IEE_OP_SET_CRED_THREAD_KEYRING 31 // Parameters: struct cred *cred, struct key *thread_keyring -+#define IEE_OP_SET_CRED_REQ_KEYRING 32 // Parameters: struct cred *cred, struct key *request_key_auth -+#define IEE_OP_SET_CRED_NON_RCU 33 // Parameters: struct cred *cred, int non_rcu -+#define IEE_OP_SET_CRED_ATSET_USAGE 34 // Parameters: struct cred *cred, int i -+#define IEE_OP_SET_CRED_ATOP_USAGE 35 // Parameters: struct cred *cred, int flag -+#define IEE_OP_SET_CRED_SECURITY 36 // Parameters: struct cred *cred, void *security -+#define IEE_OP_SET_CRED_RCU 37 // Parameters: struct cred *cred, struct rcu_head *rcu -+#define IEE_MEMSET 38 // Parameters: void *ptr, int data, size_t n -+#define IEE_OP_SET_TRACK 39 // Parameters: struct track *ptr, struct track *data -+#define IEE_OP_SET_FREEPTR 40 // Parameters: void **pptr, void *ptr -+#define IEE_OP_SET_PTE_U 41 // Parameters: pte_t *ptep, pte_t pte -+#define IEE_OP_SET_PTE_P 42 // Parameters: pte_t *ptep, pte_t pte -+#define IEE_SET_TOKEN_MM 43 // Parameters: struct task_token *token, struct mm_struct *mm -+#define IEE_SET_TOKEN_PGD 44 // Parameters: struct task_token *token, pgd_t *pgd -+#define IEE_INIT_TOKEN 45 // Parameters: struct task_struct *tsk, void *kernel_stack, void *iee_stack -+#define IEE_FREE_TOKEN 46 // Parameters: struct task_struct *tsk -+#define IEE_READ_TOKEN_STACK 47 // Parameters: struct task_struct *tsk -+#define IEE_WRITE_ENTRY_TASK 48 // Parameters: struct task_struct *tsk -+#define IEE_OP_SET_CRED_UCOUNTS 49 // Parameters: struct cred *cred, struct ucounts *ucounts -+#ifdef CONFIG_KOI -+#define IEE_READ_KOI_STACK 50 // Parameters: struct task_struct *tsk -+#define IEE_WRITE_KOI_STACK 51 // Parameters: struct task_struct *tsk, unsigned long koi_stack -+#define IEE_READ_TOKEN_TTBR1 52 // Parameters: struct task_struct *tsk -+#define IEE_WRITE_TOKEN_TTBR1 53 // Parameters: struct task_struct *tsk, unsigned long current_ttbr1 -+#define IEE_READ_KOI_KERNEL_STACK 54 // Parameters: struct task_struct *tsk -+#define IEE_WRITE_KOI_KERNEL_STACK 55 // Parameters: struct task_struct *tsk, unsigned long kernel_stack -+#define IEE_READ_KOI_STACK_BASE 56 // Parameters: struct task_struct *tsk -+#define IEE_WRITE_KOI_STACK_BASE 57 // Parameters: struct task_struct *tsk, unsigned long koi_stack_base -+#endif +@@ -0,0 +1,37 @@ ++#ifndef _LINUX_IEE_DEF_H ++#define _LINUX_IEE_DEF_H + +/* Add new IEE ops here */ + @@ -773,17 +791,235 @@ index 000000000000..76e59259e4d1 +#define AT_SUB_AND_TEST 3 +/* Atomic ops for atomic_t */ + ++#define REFCOUNT_INC 1 ++#define REFCOUNT_SET 2 ++#define REFCOUNT_DEC_AND_TEST 3 ++#define REFCOUNT_INC_NOT_ZERO 4 ++ ++#define SET_BIT_OP 1 ++#define TEST_AND_CLEAR_BIT 2 ++#define TEST_AND_SET_BIT 3 ++ +#ifdef CONFIG_KOI +#define IEE_SWITCH_TO_KERNEL 7 +#define IEE_SWITCH_TO_KOI 8 +#endif ++ ++#if defined(CONFIG_KOI) && defined(CONFIG_IEE) ++#define IEE_READ_KOI_STACK 24 ++#define IEE_WRITE_KOI_STACK 25 ++#define IEE_READ_TOKEN_TTBR1 26 ++#define IEE_WRITE_TOKEN_TTBR1 27 ++#define IEE_READ_KOI_KERNEL_STACK 28 ++#define IEE_WRITE_KOI_KERNEL_STACK 29 ++#define IEE_READ_KOI_STACK_BASE 30 ++#define IEE_WRITE_KOI_STACK_BASE 31 ++#define IEE_SET_KOI_PGD 32 ++#endif ++ ++#endif +\ No newline at end of file +diff --git a/arch/arm64/include/asm/iee-key.h b/arch/arm64/include/asm/iee-key.h +new file mode 100644 +index 000000000000..eb116bb7604a +--- /dev/null ++++ b/arch/arm64/include/asm/iee-key.h +@@ -0,0 +1,154 @@ ++#ifndef _LINUX_IEE_KEY_H ++#define _LINUX_IEE_KEY_H ++ ++#include ++#include ++ ++extern unsigned long long iee_rw_gate(int flag, ...); ++ ++#ifdef CONFIG_KEYP ++static void __maybe_unused iee_set_key_union(struct key *key, struct key_union *key_union) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_UNION, key, key_union); ++} ++ ++static void __maybe_unused iee_set_key_struct(struct key *key, struct key_struct *key_struct) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_STRUCT, key, key_struct); ++} ++ ++static void __maybe_unused iee_set_key_payload(struct key *key, union key_payload *key_payload) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_PAYLOAD, key, key_payload); ++} ++ ++static void __maybe_unused iee_write_key_payload(struct key *key, union key_payload payload) ++{ ++ iee_rw_gate(IEE_OP_WRITE_KEY_PAYLOAD, key, payload); ++} ++ ++extern bool iee_set_key_usage(struct key *key, int n, int flag); ++ ++static void __maybe_unused iee_set_key_serial(struct key *key, key_serial_t serial) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_SERIAL, key, serial); ++} ++ ++#ifdef CONFIG_KEY_NOTIFICATIONS ++static void __maybe_unused iee_set_key_watchers(struct key *key, struct watch_list *watchers) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_WATCHERS, key, watchers); ++} ++#endif ++ ++static void __maybe_unused iee_set_key_user(struct key *key, struct key_user *user) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_USERS, key, user); ++} ++ ++static void __maybe_unused iee_set_key_security(struct key *key, void *security) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_SECURITY, key, security); ++} ++ ++static void __maybe_unused iee_set_key_expiry(struct key *key, time64_t expiry) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_EXPIRY, key, expiry); ++} ++ ++static void __maybe_unused iee_set_key_revoked_at(struct key *key, time64_t revoked_at) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_REVOKED_AT, key, revoked_at); ++} ++ ++static void __maybe_unused iee_set_key_last_used_at(struct key *key, time64_t last_used_at) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_LAST_USED_AT, key, last_used_at); ++} ++ ++static void __maybe_unused iee_set_key_uid(struct key *key, kuid_t uid) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_UID, key, uid); ++} ++ ++static void __maybe_unused iee_set_key_gid(struct key *key, kgid_t gid) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_GID, key, gid); ++} ++ ++static void __maybe_unused iee_set_key_perm(struct key *key, key_perm_t perm) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_PERM, key, perm); ++} ++ ++static void __maybe_unused iee_set_key_quotalen(struct key *key, unsigned short quotalen) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_QUOTALEN, key, quotalen); ++} ++ ++static void __maybe_unused iee_set_key_datalen(struct key *key, unsigned short datalen) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_DATALEN, key, datalen); ++} ++ ++static void __maybe_unused iee_set_key_state(struct key *key, short state) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_STATE, key, state); ++} ++ ++#ifdef KEY_DEBUGGING ++static void __maybe_unused iee_set_key_magic(struct key *key, unsigned magic) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_MAGIC, key, magic); ++} ++#endif ++ ++static void __maybe_unused iee_set_key_flags(struct key *key, unsigned long flags) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_FLAGS, key, flags); ++} ++ ++static void __maybe_unused iee_set_key_index_key(struct key *key, struct keyring_index_key index_key) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_INDEX_KEY, key, index_key); ++} ++ ++static void __maybe_unused iee_set_key_hash(struct key *key, unsigned long hash) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_HASH, key, hash); ++} ++ ++static void __maybe_unused iee_set_key_len_desc(struct key *key, unsigned long len_desc) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_LEN_DESC, key, len_desc); ++} ++ ++static void __maybe_unused iee_set_key_type(struct key *key, struct key_type *type) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_TYPE, key, type); ++} ++ ++static void __maybe_unused iee_set_key_domain_tag(struct key *key, struct key_tag *domain_tag) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_TAG, key, domain_tag); ++} ++ ++static void __maybe_unused iee_set_key_description(struct key *key, char *description) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_DESCRIPTION, key, description); ++} ++ ++static void __maybe_unused iee_set_key_restrict_link(struct key *key, struct key_restriction *restrict_link) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_RESTRICT_LINK, key, restrict_link); ++} ++ ++static bool __maybe_unused iee_set_key_flag_bit(struct key *key, long nr, int flag) ++{ ++ bool ret; ++ ret = iee_rw_gate(IEE_OP_SET_KEY_FLAG_BIT, key, nr, flag); ++ return ret; ++} ++#endif ++ ++#endif +\ No newline at end of file +diff --git a/arch/arm64/include/asm/iee-selinuxp.h b/arch/arm64/include/asm/iee-selinuxp.h +new file mode 100644 +index 000000000000..4ea3e614c049 +--- /dev/null ++++ b/arch/arm64/include/asm/iee-selinuxp.h +@@ -0,0 +1,27 @@ ++#ifndef _LINUX_IEE_SELINUX_P_H ++#define _LINUX_IEE_SELINUX_P_H ++ ++#include ++#include ++#include "security.h" ++#include "ss/services.h" ++ ++static inline struct mutex* iee_get_selinux_policy_lock(void) ++{ ++ return (struct mutex*)(selinux_state.policy_mutex.owner.counter); ++} ++ ++static inline struct mutex* iee_get_selinux_status_lock(void) ++{ ++ return (struct mutex*)(selinux_state.status_lock.owner.counter); ++} ++ ++/* APIs for modifying selinux_state */ ++extern void iee_set_selinux_status_pg(struct page* new_page); ++extern void iee_set_sel_policy_cap(unsigned int idx, int cap); ++extern void iee_sel_rcu_assign_policy(struct selinux_policy* new_policy, ++ struct selinux_policy* iee_new_policy); ++ ++extern struct kmem_cache *policy_jar; ++ ++#endif \ No newline at end of file diff --git a/arch/arm64/include/asm/iee-si.h b/arch/arm64/include/asm/iee-si.h new file mode 100644 -index 000000000000..e67d81db66a5 +index 000000000000..8d2f7566e272 --- /dev/null +++ b/arch/arm64/include/asm/iee-si.h -@@ -0,0 +1,64 @@ +@@ -0,0 +1,65 @@ +#ifndef _LINUX_IEE_SI_H +#define _LINUX_IEE_SI_H + @@ -792,6 +1028,7 @@ index 000000000000..e67d81db66a5 +#define __iee_si_data __section(".iee.si_data") + +/* Used for copying globals that iee rwx gate needs. */ ++extern unsigned long iee_base_swapper_pg_dir; +extern unsigned long iee_base_idmap_pg_dir; +extern unsigned long iee_base_reserved_pg_dir; +extern unsigned long iee_base__bp_harden_el1_vectors; @@ -801,7 +1038,7 @@ index 000000000000..e67d81db66a5 +/* The following are __init functions used for iee si initialization. */ +extern void iee_si_prepare_data(void); + -+extern unsigned long __iee_si_start[]; ++extern unsigned long __iee_si_text_start[]; +// Handler function for sensitive inst +u64 iee_si_handler(int flag, ...); +/* @@ -881,14 +1118,15 @@ index 000000000000..4f3c17c7da00 \ No newline at end of file diff --git a/arch/arm64/include/asm/iee-token.h b/arch/arm64/include/asm/iee-token.h new file mode 100644 -index 000000000000..152474e1a187 +index 000000000000..d1b2cdaa0c03 --- /dev/null +++ b/arch/arm64/include/asm/iee-token.h -@@ -0,0 +1,40 @@ +@@ -0,0 +1,34 @@ +#ifndef _LINUX_IEE_TOKEN_H +#define _LINUX_IEE_TOKEN_H + +#include ++#include + +extern unsigned long long iee_rw_gate(int flag, ...); +struct task_token; @@ -896,31 +1134,24 @@ index 000000000000..152474e1a187 +struct mm_struct; + +#ifdef CONFIG_IEE -+void iee_set_token_mm(struct task_struct *tsk, struct mm_struct *mm) -+{ -+ iee_rw_gate(IEE_SET_TOKEN_MM, tsk, mm); -+} -+ +void iee_set_token_pgd(struct task_struct *tsk, pgd_t *pgd) +{ + iee_rw_gate(IEE_SET_TOKEN_PGD, tsk, pgd); +} + -+void iee_init_token(struct task_struct *tsk, void *kernel_stack, void *iee_stack) ++void iee_init_token(struct task_struct *tsk, void *iee_stack, void *tmp_page) +{ -+ iee_rw_gate(IEE_INIT_TOKEN, tsk, kernel_stack, iee_stack); ++ iee_rw_gate(IEE_INIT_TOKEN, tsk, iee_stack, tmp_page); +} + -+void iee_free_token(struct task_struct *tsk) ++void iee_invalidate_token(struct task_struct *tsk) +{ -+ iee_rw_gate(IEE_FREE_TOKEN, tsk); ++ iee_rw_gate(IEE_INVALIDATE_TOKEN, tsk); +} + -+unsigned long iee_read_token_stack(struct task_struct *tsk) ++void iee_validate_token(struct task_struct *tsk) +{ -+ unsigned long ret; -+ ret = iee_rw_gate(IEE_READ_TOKEN_STACK, tsk); -+ return ret; ++ iee_rw_gate(IEE_VALIDATE_TOKEN, tsk); +} +#endif + @@ -974,10 +1205,10 @@ index 85d26143faa5..e7a3081ce285 100644 #endif /* __ASM_KERNEL_PGTABLE_H */ diff --git a/arch/arm64/include/asm/koi.h b/arch/arm64/include/asm/koi.h new file mode 100644 -index 000000000000..48d9a1378a1d +index 000000000000..a3b0ce0f8019 --- /dev/null +++ b/arch/arm64/include/asm/koi.h -@@ -0,0 +1,335 @@ +@@ -0,0 +1,531 @@ +#include "linux/mm.h" +#include "asm/current.h" +#include "asm/pgtable-hwdef.h" @@ -988,6 +1219,7 @@ index 000000000000..48d9a1378a1d +#include "linux/printk.h" +#include "linux/slab.h" +#include "linux/string.h" ++#include +#include +#include "linux/hashtable.h" +#include "linux/module.h" @@ -999,6 +1231,8 @@ index 000000000000..48d9a1378a1d +#include "asm/iee-def.h" +#endif + ++#ifdef CONFIG_KOI ++ +#define HASH_TABLE_BIT 10 +#define HASH_TABLE_LEN (1 << HASH_TABLE_BIT) +#define HASH_KEY_MASK ((1 << HASH_TABLE_BIT) - 1) @@ -1042,6 +1276,8 @@ index 000000000000..48d9a1378a1d + spinlock_t spin_lock; + // used to protect addr hashtable + spinlock_t addr_htbl_spin_lock; ++ bool is_valid; ++ spinlock_t mod_lock; +}; +//describe the global shared var +struct shared_variable_descriptor { @@ -1055,10 +1291,13 @@ index 000000000000..48d9a1378a1d + +int koi_do_switch_to_kernel_pgtbl(void); + ++int koi_share_kstack(struct module *mod); ++ +int koi_copy_pagetable(struct mm_struct *ko_mm, pgd_t *koi_pg_dir, -+ unsigned long addr, unsigned long end); ++ unsigned long addr, unsigned long end, pteval_t prot); + +void koi_create_pagetable(struct module *mod); ++void koi_destroy_pagetable(struct module *mod); + +void koi_map_kostack(struct module *mod); +unsigned long koi_mem_alloc(struct module *mod, unsigned long orig_addr, @@ -1069,16 +1308,17 @@ index 000000000000..48d9a1378a1d +void koi_mem_free_callback(struct module *mod, unsigned long addr, + unsigned long size, void (*func)(void *)); +void koi_map_mem(struct module *mod, unsigned long addr, unsigned long size); ++void koi_unmap_mem(struct module *mod, unsigned long addr, unsigned long size); +void koi_mem_free_to_user(struct module *mod, unsigned long addr, + unsigned long size); + +unsigned long koi_ttbr_ctor(struct module *mod); -+extern void koi_do_switch_to_kernel_stack(void); -+extern void koi_do_switch_to_ko_stack(void); ++ ++// unsigned long koi_get_token_addr(struct task_struct *tsk); + +#define switch_pgtable(ttbr1) \ + do { \ -+ write_sysreg(ttbr1, ttbr1_el1); \ ++ write_sysreg((ttbr1), ttbr1_el1); \ + isb(); \ + asm volatile(ALTERNATIVE("nop; nop; nop", \ + "ic iallu; dsb nsh; isb", \ @@ -1097,11 +1337,11 @@ index 000000000000..48d9a1378a1d + "mov %1, sp\n" \ + : "=r"(flags), "=r"(cur_sp) \ + :); \ -+ if (!on_irq_stack(cur_sp, NULL)) { \ -+ koi_do_switch_to_ko_stack(); \ ++ if (!on_irq_stack(cur_sp, (unsigned long)NULL)) { \ + ko_ttbr1 = koi_ttbr_ctor(THIS_MODULE); \ + token = (struct task_token *)((unsigned long)current + \ -+ koi_offset); \ ++ (unsigned long) \ ++ koi_offset); \ + token->current_ttbr1 = ko_ttbr1 & (~TTBR_ASID_MASK); \ + } else { \ + ko_ttbr1 = koi_ttbr_ctor(THIS_MODULE); \ @@ -1125,17 +1365,15 @@ index 000000000000..48d9a1378a1d + "msr daifset, #2\n" \ + "isb\n" \ + "mov %1, sp\n" \ -+ "mov %2, ttbr0_el1\n" \ -+ : "=r"(flags), "=r"(cur_sp), "=r"(asid) \ ++ : "=r"(flags), "=r"(cur_sp) \ + :); \ -+ asid &= ~USER_ASID_FLAG; \ ++ asid = read_sysreg(ttbr0_el1) & (~USER_ASID_FLAG); \ + asid &= TTBR_ASID_MASK; \ -+ switch_pgtable(koi_swapper_ttbr1); \ -+ if (!on_irq_stack(cur_sp, NULL)) { \ ++ switch_pgtable((koi_swapper_ttbr1 | asid)); \ ++ if (!on_irq_stack(cur_sp, (unsigned long)NULL)) { \ + token = (struct task_token *)((unsigned long)current + \ -+ koi_offset); \ ++ (unsigned long)koi_offset); \ + token->current_ttbr1 = koi_swapper_ttbr1; \ -+ koi_do_switch_to_kernel_stack(); \ + } else { \ + ptr = SHIFT_PERCPU_PTR(koi_irq_current_ttbr1, \ + __kern_my_cpu_offset()); \ @@ -1157,8 +1395,7 @@ index 000000000000..48d9a1378a1d + "mov %1, sp\n" \ + : "=r"(flags), "=r"(cur_sp) \ + :); \ -+ if (!on_irq_stack(cur_sp, NULL)) { \ -+ koi_do_switch_to_ko_stack(); \ ++ if (!on_irq_stack(cur_sp, (unsigned long)NULL)) { \ + ko_ttbr1 = koi_ttbr_ctor(THIS_MODULE); \ + iee_rw_gate(IEE_WRITE_TOKEN_TTBR1, current, \ + ko_ttbr1 &(~TTBR_ASID_MASK)); \ @@ -1185,11 +1422,10 @@ index 000000000000..48d9a1378a1d + "mov %1, sp\n" \ + : "=r"(flags), "=r"(cur_sp) \ + :); \ -+ iee_rwx_gate_entry(IEE_SWITCH_TO_KERNEL); \ -+ if (!on_irq_stack(cur_sp, NULL)) { \ ++ iee_rwx_gate_entry(IEE_SWITCH_TO_KERNEL); \ ++ if (!on_irq_stack(cur_sp, (unsigned long)NULL)) { \ + iee_rw_gate(IEE_WRITE_TOKEN_TTBR1, current, \ + koi_swapper_ttbr1); \ -+ koi_do_switch_to_kernel_stack(); \ + } else { \ + ptr = SHIFT_PERCPU_PTR(koi_irq_current_ttbr1, \ + __kern_my_cpu_offset()); \ @@ -1224,16 +1460,41 @@ index 000000000000..48d9a1378a1d + + addr = kzalloc(size, flags); + koi_copy_pagetable(target->ko_mm, target->pgdp, (unsigned long)addr, -+ (unsigned long)addr + PAGE_SIZE * cnt); ++ (unsigned long)addr + PAGE_SIZE * cnt, 0); + koi_switch_to_ko(); + return addr; +} ++ ++static __maybe_unused noinline void *koi_kzalloc_node_wrapper(struct module *mod, size_t size, gfp_t flags, int node) { ++ int cnt = (size + PAGE_SIZE - 1) / PAGE_SIZE; ++ void *addr = NULL; ++ struct koi_mem_hash_node *target = NULL; ++ koi_switch_to_kernel(); ++ ++ rcu_read_lock(); ++ hash_for_each_possible_rcu(koi_mem_htbl, target, node, (unsigned long)mod) { ++ if (target->mod == mod) ++ break; ++ } ++ rcu_read_unlock(); ++ if (target == NULL) { ++ printk(KERN_ERR "mem node for module: %s not found\n", mod->name); ++ goto ret; ++ } ++ addr = kzalloc_node(cnt * PAGE_SIZE, flags, node); ++ koi_copy_pagetable(target->ko_mm, target->pgdp, (unsigned long)addr, ++ (unsigned long)addr + PAGE_SIZE * cnt, 0); ++ret: ++ koi_switch_to_ko(); ++ return (void *)addr; ++} ++ +//kmalloc function in driver space -+static __maybe_unused __always_inline void * ++static __maybe_unused void * +koi_kmalloc_wrapper(struct module *mod, size_t size, gfp_t flags) +{ + int cnt = (size + PAGE_SIZE - 1) / PAGE_SIZE; -+ void *addr; ++ void *addr = NULL; + struct koi_mem_hash_node *target = NULL; + koi_switch_to_kernel(); + @@ -1246,14 +1507,15 @@ index 000000000000..48d9a1378a1d + } + rcu_read_unlock(); + if (target == NULL) { -+ printk("mem node for module: %s not found\n", mod->name); -+ return 0; ++ printk(KERN_ERR"mem node for module: %s not found\n", mod->name); ++ goto ret; + } + + addr = kmalloc(cnt * PAGE_SIZE, flags); + koi_copy_pagetable(target->ko_mm, target->pgdp, (unsigned long)addr, -+ (unsigned long)addr + PAGE_SIZE * cnt); -+ koi_switch_to_ko(); ++ (unsigned long)addr + PAGE_SIZE * cnt, 0); ++ret: ++ koi_switch_to_ko(); + return (void *)addr; +} +//vmalloc function in driver space @@ -1279,7 +1541,7 @@ index 000000000000..48d9a1378a1d + } + addr = vmalloc(cnt * PAGE_SIZE); + koi_copy_pagetable(target->ko_mm, target->pgdp, (unsigned long)addr, -+ (unsigned long)addr + PAGE_SIZE * cnt); ++ (unsigned long)addr + PAGE_SIZE * cnt, 0); + koi_switch_to_ko(); + return addr; +} @@ -1309,13 +1571,178 @@ index 000000000000..48d9a1378a1d + n = (kpage * PAGE_SIZE) / size; + addr = kmalloc_array(n, size, flags); + koi_copy_pagetable(target->ko_mm, target->pgdp, (unsigned long)addr, -+ (unsigned long)addr + PAGE_SIZE * kpage); ++ (unsigned long)addr + PAGE_SIZE * kpage, 0); + koi_switch_to_ko(); + return addr; +} ++ ++static __maybe_unused noinline void *koi_kcalloc_wrapper(struct module *mod, size_t n, size_t size, gfp_t flags) { ++ return koi_kmalloc_array_wrapper(mod, n, size, flags | __GFP_ZERO); ++} ++#endif ++ ++#ifdef CONFIG_KOI ++ ++#define koi_copy_to_user_wrapper(to, from, n) \ ++({ \ ++ koi_switch_to_kernel(); \ ++ long long ret = copy_to_user(to, from, n); \ ++ koi_switch_to_ko(); \ ++ ret; \ ++}) ++ ++#define koi_copy_from_user_wrapper(to, from, n) \ ++({ \ ++ koi_switch_to_kernel(); \ ++ long long ret = copy_from_user(to, from, n); \ ++ koi_switch_to_ko(); \ ++ ret; \ ++}) ++ ++#define koi_kasprintf_wrapper(gfp, fmt, args...)\ ++ ({ \ ++ koi_switch_to_kernel(); \ ++ void *ret = kasprintf(gfp, fmt, ##args); \ ++ koi_map_mem(THIS_MODULE, (unsigned long)ret, sizeof(void *)); \ ++ koi_switch_to_ko(); \ ++ ret;\ ++ }) ++ ++#define koi_scnprintf_wrapper(buf, size, fmt, args...) \ ++ ({ \ ++ int ret; \ ++ koi_switch_to_kernel(); \ ++ ret = scnprintf(buf, size, fmt, ##args); \ ++ koi_switch_to_ko(); \ ++ ret; \ ++ }) ++ ++#define koi_sscanf_wrapper(buf, fmt, args...) \ ++ ({ \ ++ int ret; \ ++ koi_switch_to_kernel(); \ ++ ret = sscanf(buf, fmt, ##args); \ ++ koi_switch_to_ko(); \ ++ ret; \ ++ }) ++ ++#define koi_rcu_read_lock_wrapper() \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ rcu_read_lock(); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_rcu_read_unlock_wrapper() \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ rcu_read_unlock(); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_mutex_lock_wrapper(lock) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ mutex_lock(lock); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_mutex_unlock_wrapper(lock) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ mutex_unlock(lock); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_mutex_init_wrapper(lock) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ mutex_init(lock); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_spin_lock_wrapper(lock) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ spin_lock(lock); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_spin_unlock_wrapper(lock) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ spin_unlock(lock); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_spin_lock_irq_wrapper(lock) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ spin_lock_irq(lock); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++ ++#define koi_spin_unlock_irq_wrapper(lock) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ spin_unlock_irq(lock); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_spin_lock_irqsave_wrapper(lock, flags) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ spin_lock_irqsave(lock, flags); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++ ++#define koi_spin_lock_irqrestore_wrapper(lock, flags) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ spin_lock_irqrestore(lock, flags); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#else ++ ++#define koi_copy_to_user_wrapper copy_to_user ++ ++#define koi_copy_from_user_wrapper copy_from_user ++ ++#define koi_kasprintf_wrapper kasprintf ++ ++#define koi_scnprintf_wrapper scnprintf ++ ++#define koi_sscanf_wrapper sscanf ++ ++#define koi_rcu_read_lock_wrapper rcu_read_lock ++ ++#define koi_rcu_read_unlock_wrapper rcu_read_unlock ++ ++#define koi_mutex_lock_wrapper mutex_lock ++ ++#define koi_mutex_unlock_wrapper mutex_unlock ++ ++#define koi_mutex_init_wrapper mutex_init ++ ++#define koi_spin_lock_irq_wrapper spin_lock_irq ++ ++#define koi_spin_unlock_irq_wrapper spin_unlock_irq ++ ++#define koi_spin_lock_wrapper spin_lock ++ ++#define koi_spin_unlock_wrapper spin_unlock ++ ++#define koi_spin_lock_irqsave_wrapper spin_lock_irqsave ++ ++#define koi_spin_lock_irqrestore_wrapper spin_lock_irqrestore ++ ++#endif \ No newline at end of file diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h -index fde4186cc387..6309e5514a16 100644 +index fde4186cc387..c9e9a5a288bc 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -190,6 +190,13 @@ extern u64 vabits_actual; @@ -1332,12 +1759,12 @@ index fde4186cc387..6309e5514a16 100644 /* PHYS_OFFSET - the physical address of the start of memory. */ #define PHYS_OFFSET ({ VM_BUG_ON(memstart_addr & 1); memstart_addr; }) -@@ -310,6 +317,23 @@ extern phys_addr_t __phys_addr_symbol(unsigned long x); +@@ -310,6 +317,27 @@ extern phys_addr_t __phys_addr_symbol(unsigned long x); #define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET) | PAGE_OFFSET) #define __phys_to_kimg(x) ((unsigned long)((x) + kimage_voffset)) +#ifdef CONFIG_KOI -+#define KOI_OFFSET ((unsigned long)BIT(vabits_actual - 2)) ++#define KOI_OFFSET (((unsigned long)BIT(vabits_actual - 2)) - LOGICAL_RANDOM) +#endif + +#ifdef CONFIG_IEE @@ -1353,6 +1780,10 @@ index fde4186cc387..6309e5514a16 100644 +#define SET_NG(x) __pgprot(pgprot_val(x) | PTE_NG) +#endif + ++#if defined(CONFIG_IEE) || defined (CONFIG_KOI) ++#define SET_NG(x) __pgprot(pgprot_val(x) | PTE_NG) ++#define SET_INVALID(x) __pgprot(pgprot_val(x) & (~PTE_VALID)) ++#endif /* * Convert a page to/from a physical address */ @@ -1463,7 +1894,7 @@ index e4944d517c99..7f60e568c964 100644 * TTBR. */ diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h -index 8d68d00de0a4..6f8d5b85bfd7 100644 +index e4d6593dfa66..85b4af2c2122 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -34,6 +34,9 @@ @@ -1476,273 +1907,171 @@ index 8d68d00de0a4..6f8d5b85bfd7 100644 #ifdef CONFIG_TRANSPARENT_HUGEPAGE #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE -@@ -156,6 +159,30 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys) +@@ -156,6 +159,14 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys) #define pud_access_permitted(pud, write) \ (pte_access_permitted(pud_pte(pud), (write))) +#ifdef CONFIG_PTP -+static inline bool in_tramp_pgdir(void *addr); ++extern bool in_tramp_pgdir(void *addr); +extern unsigned long long iee_rw_gate(int flag, ...); -+ -+static void iee_set_tramp_pgd_pre_init(pgd_t *pgdp, pgd_t pgd) -+{ -+ iee_rw_gate(IEE_OP_SET_TRAMP_PGD, pgdp, pgd); -+} -+ -+static noinline pteval_t iee_set_xchg_relaxed(pte_t *ptep, pteval_t pteval) -+{ -+ pteval_t ret; -+ ret = iee_rw_gate(IEE_OP_SET_XCHG, ptep, pteval); -+ return (pteval_t)ret; -+} -+ -+static noinline pteval_t iee_set_cmpxchg_relaxed(pte_t *ptep, pteval_t old_pteval, pteval_t new_pteval) -+{ -+ pteval_t ret; -+ ret = iee_rw_gate(IEE_OP_SET_CMPXCHG, ptep, old_pteval, new_pteval); -+ return (pteval_t)ret; -+} ++extern void iee_set_tramp_pgd_pre_init(pgd_t *pgdp, pgd_t pgd); ++extern pteval_t iee_set_xchg_relaxed(pte_t *ptep, pteval_t pteval); ++extern pteval_t iee_set_cmpxchg_relaxed(pte_t *ptep, pteval_t old_pteval, pteval_t new_pteval); +#endif + static inline pte_t clear_pte_bit(pte_t pte, pgprot_t prot) { pte_val(pte) &= ~pgprot_val(prot); -@@ -262,6 +289,64 @@ static inline pte_t pte_mkdevmap(pte_t pte) +@@ -260,19 +271,35 @@ static inline pte_t pte_mkdevmap(pte_t pte) + return set_pte_bit(pte, __pgprot(PTE_DEVMAP | PTE_SPECIAL)); + } ++#ifdef CONFIG_PTP ++extern void iee_set_bm_pte(pte_t *ptep, pte_t pte); ++extern void iee_set_fixmap_pte_pre_init(pte_t *ptep, pte_t pte); ++#endif ++ ++#ifdef CONFIG_IEE ++extern void __set_pte(pte_t *ptep, pte_t pte); ++#else static inline void __set_pte(pte_t *ptep, pte_t pte) { +#ifdef CONFIG_KOI -+ if (!pte_none(pte)) { ++ if (pte_valid(pte)) { + pte = __pte(pte_val(pte) | PTE_NG); + } -+#endif -+#ifdef CONFIG_PTP -+ iee_rw_gate(IEE_OP_SET_PTE, ptep, pte); -+ dsb(ishst); -+ isb(); -+#else -+ WRITE_ONCE(*ptep, pte); -+ -+ /* -+ * Only if the new pte is valid and kernel, otherwise TLB maintenance -+ * or update_mmu_cache() have the necessary barriers. -+ */ -+ if (pte_valid_not_user(pte)) { -+ dsb(ishst); -+ isb(); -+ } -+#endif -+} -+ -+ -+#ifdef CONFIG_PTP -+static inline void iee_set_bm_pte(pte_t *ptep, pte_t pte) -+{ -+ // If it is pre init, write once. -+ // Else, write once will cause exception. So it is safe. -+ unsigned long flags; -+ unsigned long res; -+ local_irq_save(flags); -+ asm volatile("at s1e1r, %0"::"r"(__phys_to_iee(__pa_symbol(ptep)))); -+ isb(); -+ res = read_sysreg(par_el1); -+ local_irq_restore(flags); -+ if(res & 0x1) -+ WRITE_ONCE(*ptep,pte); -+ else -+ iee_rw_gate(IEE_OP_SET_BM_PTE, ptep, pte); -+ -+ /* -+ * Only if the new pte is valid and kernel, otherwise TLB maintenance -+ * or update_mmu_cache() have the necessary barriers. -+ */ -+ if (pte_valid_not_user(pte)) { -+ dsb(ishst); -+ isb(); -+ } -+} -+ -+static inline void iee_set_fixmap_pte_pre_init(pte_t *ptep, pte_t pte) -+{ -+#ifdef CONFIG_KOI -+ if (!pte_none(pte)) { -+ pte = __pte(pte_val(pte) | PTE_NG); -+ } +#endif WRITE_ONCE(*ptep, pte); - - /* -@@ -273,6 +358,7 @@ static inline void __set_pte(pte_t *ptep, pte_t pte) +- +- /* +- * Only if the new pte is valid and kernel, otherwise TLB maintenance +- * or update_mmu_cache() have the necessary barriers. +- */ + if (pte_valid_not_user(pte)) { + dsb(ishst); isb(); } } ++#endif ++ ++#ifdef CONFIG_IEE ++extern void iee_set_stack_pte(pte_t *ptep, int order, int use_block_pmd, unsigned long lm_addr); ++extern void iee_unset_stack_pte(pte_t *ptep, int order, int use_block_pmd, unsigned long lm_addr); ++extern void iee_set_sensitive_pte(pte_t *lm_ptep, pte_t *iee_ptep, int order, int use_block_pmd); ++extern void iee_unset_sensitive_pte(pte_t *lm_ptep, pte_t *iee_ptep, int order, int use_block_pmd); +#endif static inline pte_t __ptep_get(pte_t *ptep) { -@@ -546,6 +632,95 @@ static inline void __set_pte_at(struct mm_struct *mm, - __set_pte(ptep, pte); +@@ -361,8 +388,15 @@ static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr) + return pfn_pte(pte_pfn(pte) + nr, pte_pgprot(pte)); } -+#ifdef CONFIG_IEE -+static inline void iee_set_pte_upage(pte_t *ptep, pte_t pte) -+{ +-static inline void __set_ptes(struct mm_struct *mm, +- unsigned long __always_unused addr, +#ifdef CONFIG_PTP -+ iee_rw_gate(IEE_OP_SET_PTE_U, ptep, pte); -+ dsb(ishst); -+ isb(); -+#else -+ WRITE_ONCE(*ptep, pte); -+ if (pte_valid_not_user(pte)) { -+ dsb(ishst); -+ isb(); -+ } ++extern void iee_set_pte_pre_init(pte_t *ptep, pte_t pte); ++extern void iee_set_pte_at(struct mm_struct *mm, unsigned long addr, ++ pte_t *ptep, pte_t pte); ++extern void iee_set_pte_at_delayed(struct mm_struct *mm, unsigned long addr, ++ pte_t *ptep, pte_t pte); +#endif -+} + -+static inline void iee_set_pte_ppage(pte_t *ptep, pte_t pte) -+{ ++static inline void __set_ptes(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte, unsigned int nr) + { + page_table_check_ptes_set(mm, ptep, pte, nr); +@@ -546,6 +580,44 @@ static inline void __set_pte_at(struct mm_struct *mm, + __set_pte(ptep, pte); + } + +#ifdef CONFIG_PTP -+ iee_rw_gate(IEE_OP_SET_PTE_P, ptep, pte); -+#else -+ WRITE_ONCE(*ptep, pte); -+#endif -+ if (pte_valid_not_user(pte)) { -+ dsb(ishst); -+ isb(); -+ } -+} -+#endif ++extern void set_pmd(pmd_t *pmdp, pmd_t pmd); ++extern void set_pud(pud_t *pudp, pud_t pud); + -+#ifdef CONFIG_PTP -+static inline void set_pmd(pmd_t *pmdp, pmd_t pmd); -+static inline void __set_pmd_at(struct mm_struct *mm, unsigned long addr, -+ pmd_t *pmdp, pmd_t pmd) ++static inline void __set_pmd_at(struct mm_struct *mm, ++ unsigned long __always_unused addr, ++ pmd_t *pmdp, pmd_t pmd, unsigned int nr) +{ -+ if (pte_present(pmd_pte(pmd)) && pte_user_exec(pmd_pte(pmd)) && !pte_special(pmd_pte(pmd))) -+ __sync_icache_dcache(pmd_pte(pmd)); -+ -+ /* -+ * If the PTE would provide user space access to the tags associated -+ * with it then ensure that the MTE tags are synchronised. Although -+ * pte_access_permitted() returns false for exec only mappings, they -+ * don't expose tags (instruction fetches don't check tags). -+ */ -+ if (system_supports_mte() && pte_access_permitted(pmd_pte(pmd), false) && -+ !pte_special(pmd_pte(pmd)) && pte_tagged(pmd_pte(pmd))) -+ mte_sync_tags(pmd_pte(pmd), PMD_SIZE >> PAGE_SHIFT); -+ ++ __sync_cache_and_tags(pmd_pte(pmd), nr); + __check_safe_pte_update(mm, (pte_t *)pmdp, pmd_pte(pmd)); -+ + set_pmd(pmdp, pmd); +} + -+static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, -+ pmd_t *pmdp, pmd_t pmd) ++static inline void __set_pud_at(struct mm_struct *mm, ++ unsigned long __always_unused addr, ++ pud_t *pudp, pud_t pud, unsigned int nr) +{ -+ page_table_check_pmd_set(mm, pmdp, pmd); -+ return __set_pmd_at(mm, addr, pmdp, pmd); ++ __sync_cache_and_tags(pud_pte(pud), nr); ++ __check_safe_pte_update(mm, (pte_t *)pudp, pud_pte(pud)); ++ set_pud(pudp, pud); +} + -+static inline void set_pud(pud_t *pudp, pud_t pud); -+static inline void __set_pud_at(struct mm_struct *mm, unsigned long addr, -+ pud_t *pudp, pud_t pud) ++static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, ++ pmd_t *pmdp, pmd_t pmd) +{ -+ if (pte_present(pud_pte(pud)) && pte_user_exec(pud_pte(pud)) && !pte_special(pud_pte(pud))) -+ __sync_icache_dcache(pud_pte(pud)); -+ -+ /* -+ * If the PTE would provide user space access to the tags associated -+ * with it then ensure that the MTE tags are synchronised. Although -+ * pte_access_permitted() returns false for exec only mappings, they -+ * don't expose tags (instruction fetches don't check tags). -+ */ -+ if (system_supports_mte() && pte_access_permitted(pud_pte(pud), false) && -+ !pte_special(pud_pte(pud)) && pte_tagged(pud_pte(pud))) -+ mte_sync_tags(pud_pte(pud), PUD_SIZE >> PAGE_SHIFT); -+ -+ __check_safe_pte_update(mm, (pte_t *)pudp, pud_pte(pud)); -+ -+ set_pud(pudp, pud); ++ page_table_check_pmd_set(mm, pmdp, pmd); ++ return __set_pmd_at(mm, addr, pmdp, pmd, ++ PMD_SIZE >> PAGE_SHIFT); +} + +static inline void set_pud_at(struct mm_struct *mm, unsigned long addr, + pud_t *pudp, pud_t pud) +{ + page_table_check_pud_set(mm, pudp, pud); -+ return __set_pud_at(mm, addr, pudp, pud); ++ return __set_pud_at(mm, addr, pudp, pud, ++ PUD_SIZE >> PAGE_SHIFT); +} +#else static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp, pmd_t pmd) { -@@ -561,7 +736,7 @@ static inline void set_pud_at(struct mm_struct *mm, unsigned long addr, +@@ -561,6 +633,7 @@ static inline void set_pud_at(struct mm_struct *mm, unsigned long addr, return __set_pte_at(mm, addr, (pte_t *)pudp, pud_pte(pud), PUD_SIZE >> PAGE_SHIFT); } -- +#endif + #define __p4d_to_phys(p4d) __pte_to_phys(p4d_pte(p4d)) #define __phys_to_p4d_val(phys) __phys_to_pte_val(phys) - -@@ -640,7 +815,14 @@ static inline bool in_swapper_pgdir(void *addr) +@@ -640,6 +713,14 @@ static inline bool in_swapper_pgdir(void *addr) ((unsigned long)swapper_pg_dir & PAGE_MASK); } --static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) +#ifdef CONFIG_PTP -+static inline bool in_tramp_pgdir(void *addr) -+{ -+ return ((unsigned long)addr & PAGE_MASK) == -+ ((unsigned long)tramp_pg_dir & PAGE_MASK); -+} ++extern bool in_tramp_pgdir(void *addr); ++extern void iee_set_fixmap_pmd_pre_init(pmd_t *pmdp, pmd_t pmd); ++#endif + -+static inline void iee_set_fixmap_pmd_pre_init(pmd_t *pmdp, pmd_t pmd) ++#ifdef CONFIG_IEE ++extern void set_pmd(pmd_t *pmdp, pmd_t pmd); ++#else + static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) { #ifdef __PAGETABLE_PMD_FOLDED - if (in_swapper_pgdir(pmdp)) { -@@ -648,7 +830,6 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) +@@ -648,14 +729,19 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) return; } #endif /* __PAGETABLE_PMD_FOLDED */ - - WRITE_ONCE(*pmdp, pmd); - - if (pmd_valid(pmd)) { -@@ -656,6 +837,32 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) - isb(); - } - } -+#endif -+ -+static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) -+{ -+#ifdef __PAGETABLE_PMD_FOLDED -+ if (in_swapper_pgdir(pmdp)) { -+ set_swapper_pgd((pgd_t *)pmdp, __pgd(pmd_val(pmd))); -+ return; -+ } -+#endif /* __PAGETABLE_PMD_FOLDED */ +#ifdef CONFIG_KOI + pmdval_t val = pmd_val(pmd); + if (pmd_valid(pmd) && !(val & PMD_TABLE_BIT)) { + pmd = __pmd(val | PMD_SECT_NG); + } +#endif -+#ifdef CONFIG_PTP -+ iee_rw_gate(IEE_OP_SET_PMD, pmdp, pmd); -+#else -+ WRITE_ONCE(*pmdp, pmd); + WRITE_ONCE(*pmdp, pmd); +- + if (pmd_valid(pmd)) { + dsb(ishst); + isb(); + } + } +#endif -+ if (pmd_valid(pmd)) { -+ dsb(ishst); -+ isb(); -+ } -+} static inline void pmd_clear(pmd_t *pmdp) { -@@ -675,6 +882,12 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd) +@@ -675,6 +761,12 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd) /* Find an entry in the third-level page table. */ #define pte_offset_phys(dir,addr) (pmd_page_paddr(READ_ONCE(*(dir))) + pte_index(addr) * sizeof(pte_t)) @@ -1755,39 +2084,26 @@ index 8d68d00de0a4..6f8d5b85bfd7 100644 #define pte_set_fixmap(addr) ((pte_t *)set_fixmap_offset(FIX_PTE, addr)) #define pte_set_fixmap_offset(pmd, addr) pte_set_fixmap(pte_offset_phys(pmd, addr)) #define pte_clear_fixmap() clear_fixmap(FIX_PTE) -@@ -703,7 +916,9 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd) +@@ -703,6 +795,14 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd) #define pud_user(pud) pte_user(pud_pte(pud)) #define pud_user_exec(pud) pte_user_exec(pud_pte(pud)) --static inline void set_pud(pud_t *pudp, pud_t pud) + +#ifdef CONFIG_PTP -+static inline void iee_set_fixmap_pud_pre_init(pud_t *pudp, pud_t pud) ++extern void iee_set_fixmap_pud_pre_init(pud_t *pudp, pud_t pud); ++#endif ++ ++#ifdef CONFIG_IEE ++extern void set_pud(pud_t *pudp, pud_t pud); ++#else + static inline void set_pud(pud_t *pudp, pud_t pud) { #ifdef __PAGETABLE_PUD_FOLDED - if (in_swapper_pgdir(pudp)) { -@@ -711,7 +926,6 @@ static inline void set_pud(pud_t *pudp, pud_t pud) +@@ -711,14 +811,20 @@ static inline void set_pud(pud_t *pudp, pud_t pud) return; } #endif /* __PAGETABLE_PUD_FOLDED */ - - WRITE_ONCE(*pudp, pud); - - if (pud_valid(pud)) { -@@ -719,6 +933,33 @@ static inline void set_pud(pud_t *pudp, pud_t pud) - isb(); - } - } -+#endif -+ -+static inline void set_pud(pud_t *pudp, pud_t pud) -+{ -+#ifdef __PAGETABLE_PUD_FOLDED -+ if (in_swapper_pgdir(pudp)) { -+ set_swapper_pgd((pgd_t *)pudp, __pgd(pud_val(pud))); -+ return; -+ } -+#endif /* __PAGETABLE_PUD_FOLDED */ +#ifdef CONFIG_KOI + pudval_t val = pud_val(pud); + if (pud_valid(pud) && !(val & PUD_TABLE_BIT)) { @@ -1795,20 +2111,18 @@ index 8d68d00de0a4..6f8d5b85bfd7 100644 + pud = __pud(val | PMD_SECT_NG); + } +#endif -+#ifdef CONFIG_PTP -+ iee_rw_gate(IEE_OP_SET_PUD, pudp, pud); -+#else -+ WRITE_ONCE(*pudp, pud); + WRITE_ONCE(*pudp, pud); +- + if (pud_valid(pud)) { + dsb(ishst); + isb(); + } + } +#endif -+ if (pud_valid(pud)) { -+ dsb(ishst); -+ isb(); -+ } -+} static inline void pud_clear(pud_t *pudp) { -@@ -738,6 +979,12 @@ static inline pmd_t *pud_pgtable(pud_t pud) +@@ -738,6 +844,12 @@ static inline pmd_t *pud_pgtable(pud_t pud) /* Find an entry in the second-level page table. */ #define pmd_offset_phys(dir, addr) (pud_page_paddr(READ_ONCE(*(dir))) + pmd_index(addr) * sizeof(pmd_t)) @@ -1821,12 +2135,15 @@ index 8d68d00de0a4..6f8d5b85bfd7 100644 #define pmd_set_fixmap(addr) ((pmd_t *)set_fixmap_offset(FIX_PMD, addr)) #define pmd_set_fixmap_offset(pud, addr) pmd_set_fixmap(pmd_offset_phys(pud, addr)) #define pmd_clear_fixmap() clear_fixmap(FIX_PMD) -@@ -769,15 +1016,26 @@ static inline pmd_t *pud_pgtable(pud_t pud) +@@ -769,10 +881,15 @@ static inline pmd_t *pud_pgtable(pud_t pud) #define p4d_none(p4d) (!p4d_val(p4d)) #define p4d_bad(p4d) (!(p4d_val(p4d) & 2)) #define p4d_present(p4d) (p4d_val(p4d)) +#define p4d_valid(p4d) pte_valid(p4d_pte(p4d)) ++#ifdef CONFIG_IEE ++extern void set_p4d(p4d_t *p4dp, p4d_t p4d); ++#else static inline void set_p4d(p4d_t *p4dp, p4d_t p4d) { - if (in_swapper_pgdir(p4dp)) { @@ -1835,21 +2152,15 @@ index 8d68d00de0a4..6f8d5b85bfd7 100644 set_swapper_pgd((pgd_t *)p4dp, __pgd(p4d_val(p4d))); return; } - -+#ifdef CONFIG_PTP -+ if(in_tramp_pgdir(p4dp)) -+ { -+ iee_set_tramp_pgd_pre_init((pgd_t *)p4dp, __pgd(p4d_val(p4d))); -+ return; -+ } -+ iee_rw_gate(IEE_OP_SET_P4D, p4dp, p4d); -+#else - WRITE_ONCE(*p4dp, p4d); -+#endif +@@ -781,6 +898,7 @@ static inline void set_p4d(p4d_t *p4dp, p4d_t p4d) dsb(ishst); isb(); } -@@ -800,6 +1058,12 @@ static inline pud_t *p4d_pgtable(p4d_t p4d) ++#endif + + static inline void p4d_clear(p4d_t *p4dp) + { +@@ -800,6 +918,12 @@ static inline pud_t *p4d_pgtable(p4d_t p4d) /* Find an entry in the first-level page table. */ #define pud_offset_phys(dir, addr) (p4d_page_paddr(READ_ONCE(*(dir))) + pud_index(addr) * sizeof(pud_t)) @@ -1862,7 +2173,7 @@ index 8d68d00de0a4..6f8d5b85bfd7 100644 #define pud_set_fixmap(addr) ((pud_t *)set_fixmap_offset(FIX_PUD, addr)) #define pud_set_fixmap_offset(p4d, addr) pud_set_fixmap(pud_offset_phys(p4d, addr)) #define pud_clear_fixmap() clear_fixmap(FIX_PUD) -@@ -826,6 +1090,10 @@ static inline pud_t *p4d_pgtable(p4d_t p4d) +@@ -826,6 +950,10 @@ static inline pud_t *p4d_pgtable(p4d_t p4d) #define pgd_ERROR(e) \ pr_err("%s:%d: bad pgd %016llx.\n", __FILE__, __LINE__, pgd_val(e)) @@ -1873,8 +2184,14 @@ index 8d68d00de0a4..6f8d5b85bfd7 100644 #define pgd_set_fixmap(addr) ((pgd_t *)set_fixmap_offset(FIX_PGD, addr)) #define pgd_clear_fixmap() clear_fixmap(FIX_PGD) -@@ -912,8 +1180,13 @@ static inline int __ptep_test_and_clear_young(struct vm_area_struct *vma, +@@ -910,10 +1038,19 @@ static inline int __ptep_test_and_clear_young(struct vm_area_struct *vma, + + pte = __ptep_get(ptep); do { ++ #ifdef CONFIG_KOI ++ if (pte_valid(pte)) ++ pte = __pte(pte_val(pte) | PTE_NG); ++ #endif old_pte = pte; pte = pte_mkold(pte); + #ifdef CONFIG_PTP @@ -1887,7 +2204,7 @@ index 8d68d00de0a4..6f8d5b85bfd7 100644 } while (pte_val(pte) != pte_val(old_pte)); return pte_young(pte); -@@ -952,8 +1225,12 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma, +@@ -952,8 +1089,12 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma, static inline pte_t __ptep_get_and_clear(struct mm_struct *mm, unsigned long address, pte_t *ptep) { @@ -1901,7 +2218,7 @@ index 8d68d00de0a4..6f8d5b85bfd7 100644 page_table_check_pte_clear(mm, pte); return pte; -@@ -995,7 +1272,12 @@ static inline pte_t __get_and_clear_full_ptes(struct mm_struct *mm, +@@ -995,7 +1136,12 @@ static inline pte_t __get_and_clear_full_ptes(struct mm_struct *mm, static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm, unsigned long address, pmd_t *pmdp) { @@ -1914,8 +2231,15 @@ index 8d68d00de0a4..6f8d5b85bfd7 100644 page_table_check_pmd_clear(mm, pmd); -@@ -1012,8 +1294,12 @@ static inline void ___ptep_set_wrprotect(struct mm_struct *mm, +@@ -1010,10 +1156,19 @@ static inline void ___ptep_set_wrprotect(struct mm_struct *mm, + pte_t old_pte; + do { ++ #ifdef CONFIG_KOI ++ if (pte_valid(pte)) { ++ pte = __pte(pte_val(pte) | PTE_NG); ++ } ++ #endif old_pte = pte; pte = pte_wrprotect(pte); + #ifdef CONFIG_PTP @@ -1927,10 +2251,16 @@ index 8d68d00de0a4..6f8d5b85bfd7 100644 } while (pte_val(pte) != pte_val(old_pte)); } -@@ -1049,7 +1335,11 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma, +@@ -1089,7 +1244,17 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp, pmd_t pmd) { page_table_check_pmd_set(vma->vm_mm, pmdp, pmd); ++ #ifdef CONFIG_KOI ++ pmdval_t val = pmd_val(pmd); ++ if (pmd_valid(pmd) && !(val & PMD_TABLE_BIT)) { ++ pmd = __pmd(val | PMD_SECT_NG); ++ } ++ #endif + #ifdef CONFIG_PTP + return __pmd((pmdval_t)iee_set_xchg_relaxed((pte_t *)&pmd_val(*pmdp), (pmdval_t)pmd_val(pmd))); + #else @@ -1939,6 +2269,21 @@ index 8d68d00de0a4..6f8d5b85bfd7 100644 } #endif +diff --git a/arch/arm64/include/asm/pgtable_slab.h b/arch/arm64/include/asm/pgtable_slab.h +new file mode 100644 +index 000000000000..0674582a1948 +--- /dev/null ++++ b/arch/arm64/include/asm/pgtable_slab.h +@@ -0,0 +1,8 @@ ++#ifndef _LINUX_PGTABLE_SLAB_H ++#define _LINUX_PGTABLE_SLAB_H ++ ++extern void __init iee_pgtable_init(void); ++extern void *get_iee_pgtable_page(gfp_t gfpflags); ++extern void free_iee_pgtable_page(void *obj); ++ ++#endif +\ No newline at end of file diff --git a/arch/arm64/include/asm/pointer_auth.h b/arch/arm64/include/asm/pointer_auth.h index d2e0306e65d3..8352e92d4536 100644 --- a/arch/arm64/include/asm/pointer_auth.h @@ -1957,6 +2302,20 @@ index d2e0306e65d3..8352e92d4536 100644 isb(); } +diff --git a/arch/arm64/include/asm/stack_slab.h b/arch/arm64/include/asm/stack_slab.h +new file mode 100644 +index 000000000000..0a478828421e +--- /dev/null ++++ b/arch/arm64/include/asm/stack_slab.h +@@ -0,0 +1,8 @@ ++#ifndef _LINUX_STACK_SLAB_H ++#define _LINUX_STACK_SLAB_H ++ ++extern void __init iee_stack_init(void); ++extern void *get_iee_stack(void); ++extern void free_iee_stack(void *obj); ++ ++#endif diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 42358b8d678e..1e2d11e57fe3 100644 --- a/arch/arm64/include/asm/sysreg.h @@ -2027,29 +2386,43 @@ index 42358b8d678e..1e2d11e57fe3 100644 u64 par; \ asm(ALTERNATIVE("nop", "dmb sy", ARM64_WORKAROUND_1508412)); \ diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h -index 2c29239d05c3..955f99317790 100644 +index 2c29239d05c3..989c6d23632c 100644 --- a/arch/arm64/include/asm/tlb.h +++ b/arch/arm64/include/asm/tlb.h -@@ -11,8 +11,17 @@ +@@ -11,11 +11,31 @@ #include #include +#ifdef CONFIG_PTP +#include ++#include "pgtable_slab.h" +#endif + static inline void __tlb_remove_table(void *_table) { -+#ifdef CONFIG_PTP -+ unsigned long iee_addr = __phys_to_iee(page_to_phys((struct page *)_table)); -+ set_iee_page_invalid(iee_addr); -+ iee_set_logical_mem_rw((unsigned long)page_address((struct page *)_table)); -+#endif free_page_and_swap_cache((struct page *)_table); } ++#ifdef CONFIG_PTP ++static inline void __iee_tlb_remove_table(void *_table) ++{ ++ struct page *page = (struct page *)_table; ++ ++ if (!is_huge_zero_page(page)) ++ { ++ if (page_ref_dec_return(page) == 1) ++ { ++ free_iee_pgtable_page((void *)page_to_virt(page)); ++ } ++ } ++} ++#endif ++ + #define tlb_flush tlb_flush + static void tlb_flush(struct mmu_gather *tlb); + diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h -index 831c314d75ff..7775628528c6 100644 +index 831c314d75ff..d447a0e35a7c 100644 --- a/arch/arm64/include/asm/tlbflush.h +++ b/arch/arm64/include/asm/tlbflush.h @@ -49,6 +49,7 @@ @@ -2082,11 +2455,37 @@ index 831c314d75ff..7775628528c6 100644 } static inline void flush_tlb_page_nosync(struct vm_area_struct *vma, -@@ -366,6 +375,45 @@ static inline void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch) +@@ -366,6 +375,7 @@ static inline void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch) * 2. If there is 1 page remaining, flush it through non-range operations. Range * operations can only span an even number of pages. */ +#if defined(CONFIG_IEE) || defined(CONFIG_KOI) + #define __flush_tlb_range_op(op, start, pages, stride, \ + asid, tlb_level, tlbi_user) \ + do { \ +@@ -378,6 +388,8 @@ do { \ + pages == 1) { \ + addr = __TLBI_VADDR(start, asid); \ + __tlbi_level(op, addr, tlb_level); \ ++ if (!arm64_kernel_unmapped_at_el0()) /* added for IEE */ \ ++ __tlbi_level(op, addr | USER_ASID_FLAG, tlb_level); \ + if (tlbi_user) \ + __tlbi_user_level(op, addr, tlb_level); \ + start += stride; \ +@@ -390,6 +402,8 @@ do { \ + addr = __TLBI_VADDR_RANGE(start, asid, scale, \ + num, tlb_level); \ + __tlbi(r##op, addr); \ ++ if (!arm64_kernel_unmapped_at_el0()) /* added for IEE */ \ ++ __tlbi(r##op, addr | USER_ASID_FLAG); \ + if (tlbi_user) \ + __tlbi_user(r##op, addr); \ + start += __TLBI_RANGE_PAGES(num, scale) << PAGE_SHIFT; \ +@@ -399,6 +413,42 @@ do { \ + } \ + } while (0) + ++#else +#define __flush_tlb_range_op(op, start, pages, stride, \ + asid, tlb_level, tlbi_user) \ +do { \ @@ -2099,8 +2498,6 @@ index 831c314d75ff..7775628528c6 100644 + pages % 2 == 1) { \ + addr = __TLBI_VADDR(start, asid); \ + __tlbi_level(op, addr, tlb_level); \ -+ if (!arm64_kernel_unmapped_at_el0()) /* added for IEE */ \ -+ __tlbi_level(op, addr | USER_ASID_FLAG, tlb_level); \ + if (tlbi_user) \ + __tlbi_user_level(op, addr, tlb_level); \ + start += stride; \ @@ -2113,8 +2510,6 @@ index 831c314d75ff..7775628528c6 100644 + addr = __TLBI_VADDR_RANGE(start, asid, scale, \ + num, tlb_level); \ + __tlbi(r##op, addr); \ -+ if (!arm64_kernel_unmapped_at_el0()) /* added for IEE */ \ -+ __tlbi(r##op, addr | USER_ASID_FLAG); \ + if (tlbi_user) \ + __tlbi_user(r##op, addr); \ + start += __TLBI_RANGE_PAGES(num, scale) << PAGE_SHIFT; \ @@ -2124,14 +2519,6 @@ index 831c314d75ff..7775628528c6 100644 + } \ +} while (0) + -+#else - #define __flush_tlb_range_op(op, start, pages, stride, \ - asid, tlb_level, tlbi_user) \ - do { \ -@@ -399,6 +447,8 @@ do { \ - } \ - } while (0) - +#endif //if defined(CONFIG_IEE) || defined(CONFIG_KOI) + #define __flush_s2_tlb_range_op(op, start, pages, stride, tlb_level) \ @@ -2160,7 +2547,7 @@ index 831c314d75ff..7775628528c6 100644 dsb(ish); isb(); diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile -index 21ef9c21a400..44eb76cc54d7 100644 +index 4ce58887302a..81dd446dc8a3 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -36,6 +36,8 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \ @@ -2173,7 +2560,7 @@ index 21ef9c21a400..44eb76cc54d7 100644 sys_compat.o obj-$(CONFIG_AARCH32_EL0) += sigreturn32.o diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c -index fd0f291e215e..c008e46b5fc0 100644 +index 87ac0b9c0b4f..f135db1d9965 100644 --- a/arch/arm64/kernel/armv8_deprecated.c +++ b/arch/arm64/kernel/armv8_deprecated.c @@ -306,11 +306,19 @@ static int cp15barrier_handler(struct pt_regs *regs, u32 instr) @@ -2217,27 +2604,29 @@ index fd0f291e215e..c008e46b5fc0 100644 static int __a32_setend_handler(struct pt_regs *regs, u32 big_endian) diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c -index e997ad275afb..e105f633355a 100644 +index e997ad275afb..f584b457a0f4 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c -@@ -97,6 +97,17 @@ int main(void) - DEFINE(FREGS_DIRECT_TRAMP, offsetof(struct ftrace_regs, direct_tramp)); - #endif +@@ -99,6 +99,19 @@ int main(void) DEFINE(FREGS_SIZE, sizeof(struct ftrace_regs)); + BLANK(); + #endif +#ifdef CONFIG_IEE + DEFINE(iee_from_token_offset, offsetof(struct task_token, iee_stack)); ++ DEFINE(tmp_page_from_token_offset, offsetof(struct task_token, tmp_page)); + DEFINE(kernel_from_token_offset, offsetof(struct task_token, kernel_stack)); + DEFINE(mm_from_task_offset, offsetof(struct task_struct, mm)); +#endif +#ifdef CONFIG_KOI + DEFINE(koi_kernel_from_token_offset, offsetof(struct task_token, koi_kernel_stack)); -+ DEFINE(koi_from_token_offset, offsetof(struct task_token, koi_stack)); -+ DEFINE(ttbr1_from_token_offset, offsetof(struct task_token, current_ttbr1)); -+ DEFINE(koi_stack_base_from_token_offset, offsetof(struct task_token, koi_stack_base)); ++ DEFINE(koi_from_token_offset, offsetof(struct task_token, koi_stack)); ++ DEFINE(ttbr1_from_token_offset, offsetof(struct task_token, current_ttbr1)); ++ DEFINE(koi_stack_base_from_token_offset, offsetof(struct task_token, koi_stack_base)); +#endif - BLANK(); - #endif ++ BLANK(); #ifdef CONFIG_AARCH32_EL0 + DEFINE(COMPAT_SIGFRAME_REGS_OFFSET, offsetof(struct a32_sigframe, uc.uc_mcontext.arm_r0)); + DEFINE(COMPAT_RT_SIGFRAME_REGS_OFFSET, offsetof(struct a32_rt_sigframe, sig.uc.uc_mcontext.arm_r0)); diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 46813132a09f..412006aa323c 100644 --- a/arch/arm64/kernel/cpu_errata.c @@ -2279,7 +2668,7 @@ index 46813132a09f..412006aa323c 100644 #ifdef CONFIG_HISILICON_ERRATUM_HIP08_RU_PREFETCH diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c -index 74e445251b51..ebc1e776b175 100644 +index a7b4ccd7983e..3c27722b6bfe 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -94,6 +94,10 @@ @@ -2293,7 +2682,7 @@ index 74e445251b51..ebc1e776b175 100644 /* Kernel representation of AT_HWCAP and AT_HWCAP2 */ static DECLARE_BITMAP(elf_hwcap, MAX_CPU_FEATURES) __read_mostly; -@@ -1612,7 +1616,11 @@ static void cpu_emulate_effective_ctr(const struct arm64_cpu_capabilities *__unu +@@ -1616,7 +1620,11 @@ static void cpu_emulate_effective_ctr(const struct arm64_cpu_capabilities *__unu * value. */ if (!(read_cpuid_cachetype() & BIT(CTR_EL0_IDC_SHIFT))) @@ -2305,7 +2694,7 @@ index 74e445251b51..ebc1e776b175 100644 } static bool has_cache_dic(const struct arm64_cpu_capabilities *entry, -@@ -1873,7 +1881,11 @@ static inline void __cpu_enable_hw_dbm(void) +@@ -1877,7 +1885,11 @@ static inline void __cpu_enable_hw_dbm(void) { u64 tcr = read_sysreg(tcr_el1) | TCR_HD; @@ -2317,7 +2706,7 @@ index 74e445251b51..ebc1e776b175 100644 isb(); local_flush_tlb_all(); } -@@ -2056,7 +2068,9 @@ static void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused) +@@ -2060,7 +2072,9 @@ static void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused) */ WARN_ON_ONCE(in_interrupt()); @@ -2327,7 +2716,7 @@ index 74e445251b51..ebc1e776b175 100644 set_pstate_pan(1); } #endif /* CONFIG_ARM64_PAN */ -@@ -2121,7 +2135,11 @@ static bool has_generic_auth(const struct arm64_cpu_capabilities *entry, +@@ -2125,7 +2139,11 @@ static bool has_generic_auth(const struct arm64_cpu_capabilities *entry, static void cpu_enable_e0pd(struct arm64_cpu_capabilities const *cap) { if (this_cpu_has_cap(ARM64_HAS_E0PD)) @@ -2339,7 +2728,7 @@ index 74e445251b51..ebc1e776b175 100644 } #endif /* CONFIG_ARM64_E0PD */ -@@ -2214,7 +2232,11 @@ static void nmi_enable(const struct arm64_cpu_capabilities *__unused) +@@ -2220,7 +2238,11 @@ static void nmi_enable(const struct arm64_cpu_capabilities *__unused) * avoid leaving things masked. */ _allint_clear(); @@ -2351,7 +2740,7 @@ index 74e445251b51..ebc1e776b175 100644 isb(); } #endif -@@ -2229,7 +2251,11 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused) +@@ -2235,7 +2257,11 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused) * So, be strict and forbid other BRs using other registers to * jump onto a PACIxSP instruction: */ @@ -2363,7 +2752,7 @@ index 74e445251b51..ebc1e776b175 100644 isb(); } #endif /* CONFIG_ARM64_BTI */ -@@ -2237,7 +2263,11 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused) +@@ -2243,7 +2269,11 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused) #ifdef CONFIG_ARM64_MTE static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) { @@ -2375,7 +2764,7 @@ index 74e445251b51..ebc1e776b175 100644 mte_cpu_setup(); -@@ -2271,7 +2301,11 @@ static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, in +@@ -2277,7 +2307,11 @@ static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, in static void cpu_trap_el0_impdef(const struct arm64_cpu_capabilities *__unused) { @@ -2387,7 +2776,7 @@ index 74e445251b51..ebc1e776b175 100644 } static void cpu_enable_dit(const struct arm64_cpu_capabilities *__unused) -@@ -2281,7 +2315,11 @@ static void cpu_enable_dit(const struct arm64_cpu_capabilities *__unused) +@@ -2287,7 +2321,11 @@ static void cpu_enable_dit(const struct arm64_cpu_capabilities *__unused) static void cpu_enable_mops(const struct arm64_cpu_capabilities *__unused) { @@ -2399,7 +2788,7 @@ index 74e445251b51..ebc1e776b175 100644 } /* Internal helper functions to match cpu capability type */ -@@ -3475,6 +3513,43 @@ static void __init setup_system_capabilities(void) +@@ -3513,6 +3551,43 @@ static void __init setup_system_capabilities(void) enable_cpu_capabilities(SCOPE_ALL & ~SCOPE_BOOT_CPU); } @@ -2420,13 +2809,13 @@ index 74e445251b51..ebc1e776b175 100644 + // pr_info("IEE: testing iee_exec_entry afsr0...\n"); + // iee_rwx_gate_entry(IEE_WRITE_AFSR0); + #ifdef CONFIG_KOI -+ write_sysreg(read_sysreg(ttbr0_el1)+0x3000000000000, ttbr0_el1); + pr_info("IEE: current TTBR1_EL1:%llx, TTBR0:%llx\n", read_sysreg(ttbr1_el1), read_sysreg(ttbr0_el1)); + pr_info("IEE: testing iee_exec_entry switch to koi...\n"); -+ iee_rwx_gate_entry(IEE_SWITCH_TO_KOI, phys_to_ttbr(__pa_symbol(swapper_pg_dir))); ++ iee_rwx_gate_entry(IEE_SWITCH_TO_KOI, phys_to_ttbr(__pa_symbol(swapper_pg_dir)) | 3UL << 48); + pr_info("IEE: current TTBR1_EL1:%llx, TTBR0:%llx\n", read_sysreg(ttbr1_el1), read_sysreg(ttbr0_el1)); + pr_info("IEE: testing iee_exec_entry switch to kernel...\n"); + iee_rwx_gate_entry(IEE_SWITCH_TO_KERNEL); ++ pr_info("IEE: current TTBR1_EL1:%llx, TTBR0:%llx\n", read_sysreg(ttbr1_el1), read_sysreg(ttbr0_el1)); + #endif +} + @@ -2443,7 +2832,7 @@ index 74e445251b51..ebc1e776b175 100644 void __init setup_cpu_features(void) { u32 cwg; -@@ -3502,6 +3577,10 @@ void __init setup_cpu_features(void) +@@ -3540,6 +3615,10 @@ void __init setup_cpu_features(void) if (!cwg) pr_warn("No Cache Writeback Granule information, assuming %d\n", ARCH_DMA_MINALIGN); @@ -2490,10 +2879,10 @@ index 08274e4317b2..0d259e355c90 100644 regs->lockdep_hardirqs = lockdep_hardirqs_enabled(); diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S -index 7fcbee0f6c0e..dee813ee6aad 100644 +index 7fcbee0f6c0e..8ee531918781 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S -@@ -29,12 +29,391 @@ +@@ -29,12 +29,400 @@ #include #include @@ -2512,6 +2901,7 @@ index 7fcbee0f6c0e..dee813ee6aad 100644 .endr .endm ++ +#ifdef CONFIG_KOI +#ifdef CONFIG_IEE +/* @@ -2588,12 +2978,17 @@ index 7fcbee0f6c0e..dee813ee6aad 100644 + str x17, [sp, #16] + stp x30, x29, [sp] + -+ // current sp stores in x1 -+ add x1, x1, #176 ++ // current sp stores in x2 ++ add x2, x1, #176 + // current sp_el0 stores in x0 ++ mov x1, x0 ++ adrp x0, iee_offset ++ ldr x0, [x0, #:lo12:iee_offset] + bl _iee_write_koi_kernel_stack + -+ mrs x0, sp_el0 ++ adrp x0, iee_offset ++ ldr x0, [x0, #:lo12:iee_offset] ++ mrs x1, sp_el0 + bl _iee_read_koi_stack + + ldr x17, [sp, #16] @@ -2629,11 +3024,15 @@ index 7fcbee0f6c0e..dee813ee6aad 100644 + stp x30, x29, [sp] + str x17, [sp, #16] + -+ mrs x0, sp_el0 -+ add x1, sp, #192 ++ adrp x0, iee_offset ++ ldr x0, [x0, #:lo12:iee_offset] ++ mrs x1, sp_el0 ++ add x2, sp, #192 + bl _iee_write_koi_stack + -+ mrs x0, sp_el0 ++ adrp x0, iee_offset ++ ldr x0, [x0, #:lo12:iee_offset] ++ mrs x1, sp_el0 + bl _iee_read_koi_kernel_stack + + ldr x17, [sp, #16] @@ -2756,7 +3155,7 @@ index 7fcbee0f6c0e..dee813ee6aad 100644 + ret +SYM_FUNC_END(koi_switch_to_kernel_stack) +#endif -+ ++.pushsection ".koi.text", "ax" +SYM_FUNC_START(koi_switch_to_ko_pgtbl) + stp x0, x1, [sp, #16 * 1] + stp x2, x3, [sp, #16 * 2] @@ -2784,7 +3183,6 @@ index 7fcbee0f6c0e..dee813ee6aad 100644 + and x2, x2, #~(THREAD_SIZE - 1) + cbnz x2, 1f + -+ bl koi_switch_to_ko_stack +1: +#ifndef CONFIG_IEE + msr ttbr1_el1, x19 @@ -2812,7 +3210,6 @@ index 7fcbee0f6c0e..dee813ee6aad 100644 + ret +SYM_FUNC_END(koi_switch_to_ko_pgtbl) + -+.pushsection ".koi.text", "ax" +SYM_FUNC_START(koi_switch_to_kernel_pgtbl) + sub sp, sp, #160 + stp x0, x1, [sp, #16 * 0] @@ -2844,7 +3241,7 @@ index 7fcbee0f6c0e..dee813ee6aad 100644 + ldr x1, [x1, #:lo12:koi_offset] + add x0, x0, x1 + mov x16, sp -+ ldr x17, [x0, koi_stack_base_from_token_offset] ++ ldr x17, [x0, #koi_stack_base_from_token_offset] + eor x17, x17, x16 + and x17, x17, #~(THREAD_SIZE - 1) + cbnz x17, 0f @@ -2853,7 +3250,9 @@ index 7fcbee0f6c0e..dee813ee6aad 100644 + mrs x17, pan + // disable pan + msr pan, 0x0 -+ mrs x0, sp_el0 ++ adrp x0, iee_offset ++ ldr x0, [x0, #:lo12:iee_offset] ++ mrs x1, sp_el0 + bl _iee_read_koi_stack_base + // restore pan + msr pan, x17 @@ -2863,7 +3262,6 @@ index 7fcbee0f6c0e..dee813ee6aad 100644 + and x0, x0, #~(THREAD_SIZE - 1) + cbnz x0, 0f +#endif -+ bl koi_switch_to_kernel_stack +0: + + ldp x0, x1, [sp, #16 * 0] @@ -2885,54 +3283,41 @@ index 7fcbee0f6c0e..dee813ee6aad 100644 .macro kernel_ventry, el:req, ht:req, regsize:req, label:req .align 7 .Lventry_start\@: -@@ -151,6 +530,17 @@ alternative_else_nop_endif - #endif - .endm +@@ -53,6 +441,15 @@ + .Lskip_tramp_vectors_cleanup\@: + .endif -+#ifdef CONFIG_IEE -+// SP_EL0 check failed. -+SYM_FUNC_START_LOCAL(sp_el0_check_failed) -+ mov x0, sp -+ mov x1, #BAD_SP_EL0 -+ mrs x2, esr_el1 -+ bl iee_bad_mode -+ ASM_BUG() -+SYM_FUNC_END(sp_el0_check_failed) ++#ifdef CONFIG_KOI ++ .if \el == 1 ++ msr tpidrro_el0, x30 ++ bl koi_switch_to_kernel_pgtbl ++ mrs x30, tpidrro_el0 ++ msr tpidrro_el0, xzr ++ .endif +#endif + - /* Clear the MTE asynchronous tag check faults */ - .macro clear_mte_async_tcf thread_sctlr - #ifdef CONFIG_ARM64_MTE -@@ -224,6 +614,14 @@ alternative_cb_end - ldr_this_cpu tsk, __entry_task, x20 - msr sp_el0, tsk + sub sp, sp, #PT_REGS_SIZE + #ifdef CONFIG_VMAP_STACK + /* +@@ -320,6 +717,17 @@ alternative_else_nop_endif + msr_s SYS_ICC_PMR_EL1, x20 -+#ifdef CONFIG_IEE -+ // tsk check. -+ ldr_this_cpu x19, __entry_task, x20 -+ mrs x20, sp_el0 -+ cmp x19, x20 -+ b.ne sp_el0_check_failed + .Lskip_pmr_save\@: +#endif + - /* - * Ensure MDSCR_EL1.SS is clear, since we can unmask debug exceptions - * when scheduling. -@@ -276,6 +674,13 @@ alternative_else_nop_endif ++#ifndef CONFIG_IEE ++#ifdef CONFIG_KOI ++ // set tcr_el1 to choose asid from ttbr1_el1 or ttbr0_el1 ++ .if \el == 0 ++ mrs x0, tcr_el1 ++ orr x0, x0 ,#0x0000000000400000 ++ msr tcr_el1,x0 ++ .endif ++#endif + #endif - scs_load_current - .else -+#ifdef CONFIG_IEE -+ // tsk check. -+ ldr_this_cpu x19, __entry_task, x20 -+ mrs x20, sp_el0 -+ cmp x19, x20 -+ b.ne sp_el0_check_failed -+#endif - add x21, sp, #PT_REGS_SIZE - get_current_task tsk - .endif /* \el == 0 */ -@@ -333,9 +738,11 @@ alternative_else_nop_endif + /* +@@ -333,9 +741,11 @@ alternative_else_nop_endif .endm .macro kernel_exit, el @@ -2944,7 +3329,7 @@ index 7fcbee0f6c0e..dee813ee6aad 100644 #ifdef CONFIG_ARM64_PSEUDO_NMI alternative_if_not ARM64_HAS_GIC_PRIO_MASKING -@@ -411,6 +818,41 @@ alternative_else_nop_endif +@@ -411,6 +821,41 @@ alternative_else_nop_endif msr elr_el1, x21 // set up the return data msr spsr_el1, x22 @@ -2986,7 +3371,39 @@ index 7fcbee0f6c0e..dee813ee6aad 100644 ldp x0, x1, [sp, #16 * 0] ldp x2, x3, [sp, #16 * 1] ldp x4, x5, [sp, #16 * 2] -@@ -569,12 +1011,167 @@ SYM_CODE_START_LOCAL(__bad_stack) +@@ -451,13 +896,30 @@ alternative_if ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD + dsb nsh + alternative_else_nop_endif + eret ++ ++#ifdef CONFIG_IEE ++5: ++ // ELR_EL1 check fail ++ mov x0, sp ++ mov x1, #BAD_ELR_EL1 ++ mrs x2, esr_el1 ++ bl iee_bad_mode ++ ASM_BUG() ++#endif ++ + .else + ldr lr, [sp, #S_LR] + add sp, sp, #PT_REGS_SIZE // restore sp + + /* Ensure any device/NC reads complete */ + alternative_insn nop, "dmb sy", ARM64_WORKAROUND_1508412 +- ++#ifdef CONFIG_KOI ++ sub sp, sp, #176 ++ stp x30, x19, [sp, #16 * 0] ++ bl koi_switch_to_ko_pgtbl ++ ldp x30, x19, [sp, #16 * 0] ++ add sp, sp, #176 ++#endif + eret + .endif + sb +@@ -569,12 +1031,167 @@ SYM_CODE_START_LOCAL(__bad_stack) SYM_CODE_END(__bad_stack) #endif /* CONFIG_VMAP_STACK */ @@ -2999,7 +3416,7 @@ index 7fcbee0f6c0e..dee813ee6aad 100644 + ldr x1, =__iee_si_no_irq + cmp x1, x22 + b.hi 1148f -+ ldr x1, =__iee_si_end ++ ldr x1, =__iee_si_text_end + cmp x1, x22 + b.lo 1148f + /* ELR check fail */ @@ -3154,34 +3571,22 @@ index 7fcbee0f6c0e..dee813ee6aad 100644 .if \el == 0 b ret_to_user .else -@@ -844,6 +1441,13 @@ SYM_FUNC_START(cpu_switch_to) - ldr lr, [x8] - mov sp, x9 - msr sp_el0, x1 -+#ifdef CONFIG_IEE -+ // tsk check. -+ ldr_this_cpu x8, __entry_task, x9 -+ mrs x9, sp_el0 -+ cmp x8, x9 -+ b.ne sp_el0_check_failed -+#endif - ptrauth_keys_install_kernel x1, x8, x9, x10 - scs_save x0 - scs_load_current -@@ -1033,6 +1637,13 @@ SYM_CODE_START(__sdei_asm_handler) - mrs x28, sp_el0 - ldr_this_cpu dst=x0, sym=__entry_task, tmp=x1 - msr sp_el0, x0 -+#ifdef CONFIG_IEE -+ // tsk check. -+ ldr_this_cpu x0, __entry_task, x1 -+ mrs x1, sp_el0 -+ cmp x0, x1 -+ b.ne sp_el0_check_failed +@@ -606,9 +1223,15 @@ SYM_CODE_END(el\el\ht\()_\regsize\()_\label) + entry_handler 0, t, 32, fiq + entry_handler 0, t, 32, error + ++#ifdef CONFIG_KOI ++.pushsection ".koi.text", "ax" ++#endif + SYM_CODE_START_LOCAL(ret_to_kernel) + kernel_exit 1 + SYM_CODE_END(ret_to_kernel) ++#ifdef CONFIG_KOI ++.popsection +#endif - /* If we interrupted the kernel point to the previous stack/frame. */ - and x0, x3, #0xc + SYM_CODE_START_LOCAL(ret_to_user) + ldr x19, [tsk, #TSK_TI_FLAGS] // re-check for single-step diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 5cdfcc9e3e54..c0af965bd92e 100644 --- a/arch/arm64/kernel/fpsimd.c @@ -3199,84 +3604,18 @@ index 5cdfcc9e3e54..c0af965bd92e 100644 } diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S -index 6517bf2644a0..5c75e069d877 100644 +index 6517bf2644a0..3d0716d59c0b 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S -@@ -464,6 +464,42 @@ SYM_FUNC_END(create_kernel_mapping) - set_this_cpu_offset \tmp1 - .endm - -+#ifdef CONFIG_IEE -+ .macro init_cpu_task_checked tsk, tmp1, tmp2 -+ msr sp_el0, \tsk -+ // tsk check. -+ adrp x29, __per_cpu_offset -+ mrs \tmp1, sp_el0 -+ ldr \tmp2, [\tmp1, #TSK_TI_CPU] /* cpu number */ -+1: -+ cmp \tmp2, #0 -+ b.eq 2f -+ add x29, x29, #8 -+ sub \tmp2, \tmp2, #1 -+ b 1b -+2: -+ ldr \tmp2, [x29, #:lo12:__per_cpu_offset] /* cpu offset */ -+ adr_l x29, __entry_task -+ ldr x29, [x29, \tmp2] -+ cmp x29, \tmp1 -+ b.ne sp_el0_check_failed -+ -+ ldr \tmp1, [\tsk, #TSK_STACK] -+ add sp, \tmp1, #THREAD_SIZE -+ sub sp, sp, #PT_REGS_SIZE -+ -+ stp xzr, xzr, [sp, #S_STACKFRAME] -+ add x29, sp, #S_STACKFRAME -+ -+ scs_load_current -+ -+ adr_l \tmp1, __per_cpu_offset -+ ldr w\tmp2, [\tsk, #TSK_TI_CPU] -+ ldr \tmp1, [\tmp1, \tmp2, lsl #3] -+ set_this_cpu_offset \tmp1 -+ .endm -+#endif -+ - /* - * The following fragment of code is executed with the MMU enabled. - * -@@ -661,6 +697,18 @@ SYM_FUNC_START_LOCAL(secondary_startup) +@@ -661,6 +661,7 @@ SYM_FUNC_START_LOCAL(secondary_startup) SYM_FUNC_END(secondary_startup) .text -+#ifdef CONFIG_IEE -+// SP_EL0 check failed. -+SYM_FUNC_START_LOCAL(sp_el0_check_failed) -+ 1: -+ nop -+ nop -+ nop -+ nop -+ b 1f -+SYM_FUNC_END(sp_el0_check_failed) -+#endif + SYM_FUNC_START_LOCAL(__secondary_switched) mov x0, x20 bl set_cpu_boot_mode_flag -@@ -677,7 +725,11 @@ SYM_FUNC_START_LOCAL(__secondary_switched) - ldr x2, [x0, #CPU_BOOT_TASK] - cbz x2, __secondary_too_slow - -+#ifdef CONFIG_IEE -+ init_cpu_task_checked x2, x1, x3 -+#else - init_cpu_task x2, x1, x3 -+#endif - - #ifdef CONFIG_ARM64_PTR_AUTH - ptrauth_keys_init_cpu x2, x3, x4, x5 -@@ -746,6 +798,10 @@ SYM_FUNC_START(__enable_mmu) +@@ -746,6 +747,10 @@ SYM_FUNC_START(__enable_mmu) cmp x3, #ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MAX b.gt __no_granule_support phys_to_ttbr x2, x2 @@ -3288,7 +3627,7 @@ index 6517bf2644a0..5c75e069d877 100644 load_ttbr1 x1, x1, x3 diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c -index 02870beb271e..1c14428a3ed4 100644 +index 02870beb271e..76d86b3d71b1 100644 --- a/arch/arm64/kernel/hibernate.c +++ b/arch/arm64/kernel/hibernate.c @@ -34,6 +34,10 @@ @@ -3302,24 +3641,13 @@ index 02870beb271e..1c14428a3ed4 100644 /* * Hibernate core relies on this value being 0 on resume, and marks it * __nosavedata assuming it will keep the resume kernel's '0' value. This -@@ -197,12 +201,22 @@ static int create_safe_exec_page(void *src_start, size_t length, - phys_addr_t trans_ttbr0; - unsigned long t0sz; - int rc; -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr; -+ #endif - - if (!page) - return -ENOMEM; +@@ -203,6 +207,11 @@ static int create_safe_exec_page(void *src_start, size_t length, memcpy(page, src_start, length); caches_clean_inval_pou((unsigned long)page, (unsigned long)page + length); + + #ifdef CONFIG_PTP -+ iee_addr = __phys_to_iee(__pa(page_address(page))); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)page_address(page)); ++ set_iee_page((unsigned long)page_address(page),0); + #endif + rc = trans_pgd_idmap_page(&trans_info, &trans_ttbr0, &t0sz, page); @@ -3474,18 +3802,22 @@ index d39a8787edf2..b5ac4b7670bc 100644 slot = &slots[i]; diff --git a/arch/arm64/kernel/iee/Makefile b/arch/arm64/kernel/iee/Makefile new file mode 100644 -index 000000000000..123c68c5cc4e +index 000000000000..1d4436f06af4 --- /dev/null +++ b/arch/arm64/kernel/iee/Makefile -@@ -0,0 +1 @@ -+obj-$(CONFIG_IEE) += iee.o iee-gate.o iee-func.o +@@ -0,0 +1,5 @@ ++ccflags-$(CONFIG_IEE_SELINUX_P) := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include ++ ++obj-$(CONFIG_IEE) += iee.o iee-gate.o iee-func.o iee-pgtable.o stack_slab.o pgtable_slab.o iee-key.o ++ ++obj-$(CONFIG_IEE_SELINUX_P) += iee-selinuxp.o \ No newline at end of file diff --git a/arch/arm64/kernel/iee/iee-func.c b/arch/arm64/kernel/iee/iee-func.c new file mode 100644 -index 000000000000..7764dbd41555 +index 000000000000..76538e75edd2 --- /dev/null +++ b/arch/arm64/kernel/iee/iee-func.c -@@ -0,0 +1,187 @@ +@@ -0,0 +1,720 @@ +#include "asm/pgtable.h" +#include +#include @@ -3493,118 +3825,555 @@ index 000000000000..7764dbd41555 +#include +#include + -+void set_iee_page_valid(unsigned long addr) ++extern s64 iee_offset; ++extern void iee_memset(void *ptr, int data, size_t n); ++extern void iee_split_huge_pmd(pmd_t *pmdp, pte_t *pgtable); ++#ifdef CONFIG_PTP ++extern phys_addr_t __init early_pgtable_alloc(int shift); ++#endif ++ ++static inline void iee_set_token(pte_t *ptep, void *new, unsigned long order) +{ -+ pgd_t *pgdir = swapper_pg_dir; -+ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++#ifdef CONFIG_PTP ++ pgd_t *pgdir; ++ pgd_t *pgdp; ++ p4d_t *p4dp; ++ pud_t *pudp; ++ pmd_t *pmdp; ++ int use_block_pmd = 0; + -+ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ pgdir = swapper_pg_dir; ++ pgdp = pgd_offset_pgd(pgdir, (unsigned long)new); ++ p4dp = p4d_offset(pgdp, (unsigned long)new); ++ pudp = pud_offset(p4dp, (unsigned long)new); ++ pmdp = pmd_offset(pudp, (unsigned long)new); + -+ pud_t *pudp = pud_offset(p4dp, addr); ++ // Handling cont mapping. ++ if(pmd_val(*pmdp) & PTE_CONT) ++ { ++ // The beginning of cont mapping. ++ int i; ++ pmd_t *pmdp = pmd_offset(pudp, (unsigned long)new & CONT_PMD_MASK); ++ for(i = 0; i < CONT_PMDS; i++) ++ { ++ set_pmd(pmdp,__pmd(pmd_val(*pmdp) & ~PTE_CONT)); ++ pmdp++; ++ } ++ } + -+ pmd_t *pmdp = pmd_offset(pudp, addr); ++ // Use Block Descriptor. ++ if(pmd_leaf(*pmdp)) ++ { ++ #ifndef CONFIG_PTP ++ struct page *page = pmd_page(*pmdp); ++ #endif ++ pte_t *pgtable = pte_alloc_one_kernel(&init_mm); + -+ pte_t *ptep = pte_offset_kernel(pmdp, addr); -+ pte_t pte = READ_ONCE(*ptep); ++ if (!pgtable) ++ panic("Alloc pgtable error.\n"); + -+ if((addr < (PAGE_OFFSET + IEE_OFFSET)) | (addr > (PAGE_OFFSET + BIT(vabits_actual - 1)))) -+ return; ++ iee_split_huge_pmd(pmdp, pgtable); + -+ pte = __pte(pte_val(pte) | 0x1); -+ set_pte(ptep, pte); -+ flush_tlb_kernel_range(addr, addr+PAGE_SIZE); -+ isb(); -+} ++ spinlock_t *ptl = pmd_lock(&init_mm, pmdp); ++ if(pmd_leaf(READ_ONCE(*pmdp))) ++ { ++ smp_wmb(); ++ pmd_populate_kernel(&init_mm, pmdp, pgtable); ++ pgtable = NULL; ++ } ++ spin_unlock(ptl); + -+void set_iee_page_invalid(unsigned long addr) -+{ -+ pgd_t *pgdir = swapper_pg_dir; -+ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ if(pgtable) ++ { ++ #ifdef CONFIG_PTP ++ iee_memset(pgtable, 0, PAGE_SIZE); ++ #endif ++ pte_free_kernel(&init_mm, pgtable); ++ } ++ } ++ else if(pmd_leaf(*pmdp)) ++ { ++ use_block_pmd = 1; ++ } + -+ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ iee_rw_gate(IEE_SET_TOKEN, ptep, new, order, use_block_pmd); ++#else ++ int i; ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, new); ++ p4d_t *p4dp = p4d_offset(pgdp, new); ++ pud_t *pudp = pud_offset(p4dp, new); ++ pmd_t *pmdp; ++ pte_t *lm_ptep; ++ pte_t *iee_ptep; ++ unsigned long iee_addr; ++ int use_block_pmd = 0; + -+ pud_t *pudp = pud_offset(p4dp, addr); ++ pmdp = pmd_offset(pudp, new); + -+ pmd_t *pmdp = pmd_offset(pudp, addr); ++ // Handling cont mapping. ++ if(pmd_val(*pmdp) & PTE_CONT) ++ { ++ // The beginning of cont mapping. ++ int i; ++ pmd_t *pmdp = pmd_offset(pudp, (unsigned long)new & CONT_PMD_MASK); ++ for(i = 0; i < CONT_PMDS; i++) ++ { ++ set_pmd(pmdp,__pmd(pmd_val(*pmdp) & ~PTE_CONT)); ++ pmdp++; ++ } ++ } + -+ pte_t *ptep = pte_offset_kernel(pmdp, addr); -+ pte_t pte = READ_ONCE(*ptep); ++ // Use Block Descriptor. ++ if(pmd_leaf(*pmdp) && order < 9) ++ { ++ struct page *page = pmd_page(*pmdp); ++ pte_t *pgtable = pte_alloc_one_kernel(&init_mm); ++ int i; ++ pte_t *ptep = pgtable; + -+ if((addr < (PAGE_OFFSET + IEE_OFFSET)) | (addr > (PAGE_OFFSET + BIT(vabits_actual - 1)))) -+ return; ++ if (!pgtable) ++ panic("Alloc pgtable error.\n"); + -+ pte = __pte(pte_val(pte) & ~0x1); -+ set_pte(ptep, pte); -+ flush_tlb_kernel_range(addr, addr+PAGE_SIZE); -+ isb(); -+} ++ for (i = 0; i < PMD_SIZE / PAGE_SIZE; i++, ptep++) { ++ pte_t entry; ++ pgprot_t pgprot = PAGE_KERNEL; ++ pgprot = __pgprot(pgprot_val(pgprot) | PTE_CONT); + -+void iee_set_logical_mem_ro(unsigned long addr) -+{ -+ pgd_t *pgdir = swapper_pg_dir; -+ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ entry = mk_pte(page + i, pgprot); ++ set_pte(ptep, entry); ++ } + -+ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ spin_lock(&init_mm.page_table_lock); ++ if(pmd_leaf(READ_ONCE(*pmdp))) ++ { ++ smp_wmb(); ++ pmd_populate_kernel(&init_mm, pmdp, pgtable); ++ pgtable = NULL; ++ } ++ spin_unlock(&init_mm.page_table_lock); + -+ pud_t *pudp = pud_offset(p4dp, addr); ++ if(pgtable) ++ { ++ pte_free_kernel(&init_mm, pgtable); ++ } ++ } ++ else if(pmd_leaf(*pmdp)) ++ { ++ use_block_pmd = 1; ++ } + -+ pmd_t *pmdp = pmd_offset(pudp, addr); ++ if(use_block_pmd) ++ lm_ptep = (pte_t *)pmdp; ++ else ++ lm_ptep = pte_offset_kernel(pmdp, new); + -+ pte_t *ptep = pte_offset_kernel(pmdp, addr); -+ pte_t pte = READ_ONCE(*ptep); ++ // Handling cont mapping. ++ if(pte_val(*lm_ptep) & PTE_CONT) ++ { ++ // The beginning of cont mapping. ++ int i; ++ pte_t *ptep = pte_offset_kernel(pmdp, (unsigned long)new & CONT_PTE_MASK); ++ if(order < CONFIG_ARM64_CONT_PTE_SHIFT) ++ { ++ for(i = 0; i < CONT_PTES; i++) ++ { ++ set_pte(ptep,__pte(pte_val(*ptep) & ~PTE_CONT)); ++ ptep++; ++ } ++ } ++ } ++ ++ iee_addr = ((unsigned long)new + (unsigned long)iee_offset); ++ pgdp = pgd_offset_pgd(pgdir, iee_addr); ++ p4dp = p4d_offset(pgdp, iee_addr); ++ pudp = pud_offset(p4dp, iee_addr); ++ pmdp = pmd_offset(pudp, iee_addr); ++ iee_ptep = pte_offset_kernel(pmdp, iee_addr); ++ ++ if(use_block_pmd) ++ { ++ pmd_t *pmdp = (pmd_t *)lm_ptep; ++ pmd_t pmd = READ_ONCE(*pmdp); ++ pmd = __pmd((pmd_val(pmd) | PMD_SECT_RDONLY) & ~PTE_DBM); ++ WRITE_ONCE(*pmdp, pmd); ++ for(i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(((pte_val(pte) | 0x1) & ~PTE_ADDR_MASK) | __phys_to_pte_val(__pa(new))); ++ WRITE_ONCE(*ptep, pte); ++ pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) | 0x1); ++ WRITE_ONCE(*iee_ptep, pte); ++ ptep++; ++ iee_ptep++; ++ new += PAGE_SIZE; ++ } ++ } ++ else ++ { ++ for(i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(((pte_val(pte) | 0x1) & ~PTE_ADDR_MASK) | __phys_to_pte_val(__pa(new))); ++ WRITE_ONCE(*ptep, pte); ++ pte = READ_ONCE(*lm_ptep); ++ pte = __pte((pte_val(pte) | PTE_RDONLY) & ~PTE_DBM); ++ WRITE_ONCE(*lm_ptep, pte); ++ pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) | 0x1); ++ WRITE_ONCE(*iee_ptep, pte); ++ ptep++; ++ lm_ptep++; ++ iee_ptep++; ++ new += PAGE_SIZE; ++ } ++ } ++#endif ++ dsb(ishst); ++ isb(); ++} + -+ if(addr < PAGE_OFFSET) -+ return; ++static inline void iee_unset_token(pte_t *ptep, void *token_addr, void *token_page, unsigned long order) ++{ ++#ifdef CONFIG_PTP ++ iee_rw_gate(IEE_UNSET_TOKEN, ptep, token_addr, token_page, order); ++#else ++ int i; ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, token_page); ++ p4d_t *p4dp = p4d_offset(pgdp, token_page); ++ pud_t *pudp = pud_offset(p4dp, token_page); ++ pmd_t *pmdp = pmd_offset(pudp, token_page); ++ pte_t *lm_ptep; ++ pte_t *iee_ptep; ++ unsigned long iee_addr; ++ int use_block_pmd = 0; + -+ pte = __pte((pte_val(pte) | PTE_RDONLY) & ~PTE_DBM); -+ set_pte(ptep, pte); -+ flush_tlb_kernel_range(addr, addr+PAGE_SIZE); ++ // Use Block Descriptor. ++ if(pmd_leaf(*pmdp)) ++ { ++ use_block_pmd = 1; ++ lm_ptep = (pte_t *)pmdp; ++ } ++ else ++ lm_ptep = pte_offset_kernel(pmdp, token_page); ++ ++ iee_addr = ((unsigned long)token_page + (unsigned long)iee_offset); ++ pgdp = pgd_offset_pgd(pgdir, iee_addr); ++ p4dp = p4d_offset(pgdp, iee_addr); ++ pudp = pud_offset(p4dp, iee_addr); ++ pmdp = pmd_offset(pudp, iee_addr); ++ iee_ptep = pte_offset_kernel(pmdp, iee_addr); ++ ++ if(use_block_pmd) ++ { ++ pmd_t *pmdp = (pmd_t *)lm_ptep; ++ pmd_t pmd = READ_ONCE(*pmdp); ++ pmd = __pmd(pmd_val(pmd) | PTE_DBM); ++ WRITE_ONCE(*pmdp, pmd); ++ for(i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(((pte_val(pte) & ~((unsigned long)0x1)) & ~PTE_ADDR_MASK) | __phys_to_pte_val(__pa(token_addr - IEE_OFFSET))); ++ WRITE_ONCE(*ptep, pte); ++ pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) & ~0x1); ++ WRITE_ONCE(*iee_ptep, pte); ++ ptep++; ++ iee_ptep++; ++ token_addr += PAGE_SIZE; ++ token_page += PAGE_SIZE; ++ } ++ } ++ else ++ { ++ for(i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(((pte_val(pte) & ~((unsigned long)0x1)) & ~PTE_ADDR_MASK) | __phys_to_pte_val(__pa(token_addr - IEE_OFFSET))); ++ WRITE_ONCE(*ptep, pte); ++ pte = READ_ONCE(*lm_ptep); ++ pte = __pte(pte_val(pte) | PTE_DBM); ++ WRITE_ONCE(*lm_ptep, pte); ++ pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) & ~0x1); ++ WRITE_ONCE(*iee_ptep, pte); ++ ptep++; ++ lm_ptep++; ++ iee_ptep++; ++ token_addr += PAGE_SIZE; ++ token_page += PAGE_SIZE; ++ } ++ } ++#endif ++ dsb(ishst); + isb(); +} + -+void iee_set_logical_mem_rw(unsigned long addr) ++// Input is the lm vaddr of sensitive data. ++void set_iee_page(unsigned long addr, int order) +{ + pgd_t *pgdir = swapper_pg_dir; + pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); -+ + p4d_t *p4dp = p4d_offset(pgdp, addr); -+ + pud_t *pudp = pud_offset(p4dp, addr); ++ pmd_t *pmdp; ++ pte_t *lm_ptep; ++ pte_t *iee_ptep; ++ unsigned long iee_addr; ++ int use_block_pmd = 0; + -+ pmd_t *pmdp = pmd_offset(pudp, addr); ++ pmdp = pmd_offset(pudp, addr); + -+ pte_t *ptep = pte_offset_kernel(pmdp, addr); -+ pte_t pte = READ_ONCE(*ptep); ++ // Handling cont mapping. ++ if(pmd_val(*pmdp) & PTE_CONT) ++ { ++ // The beginning of cont mapping. ++ int i; ++ pmd_t *pmdp = pmd_offset(pudp, addr & CONT_PMD_MASK); ++ for(i = 0; i < CONT_PMDS; i++) ++ { ++ set_pmd(pmdp,__pmd(pmd_val(*pmdp) & ~PTE_CONT)); ++ pmdp++; ++ } ++ } + -+ if((addr < PAGE_OFFSET) | (addr > (PAGE_OFFSET + BIT(vabits_actual - 2)))) -+ return; -+ -+ pte = __pte(pte_val(pte) | PTE_DBM); -+ set_pte(ptep, pte); -+ flush_tlb_kernel_range(addr, addr+PAGE_SIZE); -+ isb(); -+} ++ // Use Block Descriptor. ++ if(pmd_leaf(*pmdp) && order < 9) ++ { ++ #ifndef CONFIG_PTP ++ struct page *page = pmd_page(*pmdp); ++ #endif ++ pte_t *pgtable = pte_alloc_one_kernel(&init_mm); + -+void iee_set_token_page_valid(void *token, void *new) -+{ -+ pgd_t *pgdir = swapper_pg_dir; -+ pgd_t *pgdp = pgd_offset_pgd(pgdir, (unsigned long)token); ++ if (!pgtable) ++ panic("Alloc pgtable error.\n"); + -+ p4d_t *p4dp = p4d_offset(pgdp, (unsigned long)token); ++ #ifdef CONFIG_PTP ++ iee_split_huge_pmd(pmdp, pgtable); ++ #else ++ { ++ int i; ++ pte_t *ptep = pgtable; ++ for (i = 0; i < PMD_SIZE / PAGE_SIZE; i++, ptep++) { ++ pte_t entry; ++ pgprot_t pgprot = PAGE_KERNEL; ++ pgprot = __pgprot(pgprot_val(pgprot) | PTE_CONT); ++ ++ entry = mk_pte(page + i, pgprot); ++ set_pte(ptep, entry); ++ } ++ } ++ #endif + -+ pud_t *pudp = pud_offset(p4dp, (unsigned long)token); ++ spinlock_t *ptl = pmd_lock(&init_mm, pmdp); ++ if(pmd_leaf(READ_ONCE(*pmdp))) ++ { ++ smp_wmb(); ++ pmd_populate_kernel(&init_mm, pmdp, pgtable); ++ pgtable = NULL; ++ } ++ spin_unlock(ptl); + -+ pmd_t *pmdp = pmd_offset(pudp, (unsigned long)token); ++ if(pgtable) ++ { ++ #ifdef CONFIG_PTP ++ iee_memset(pgtable, 0, PAGE_SIZE); ++ #endif ++ pte_free_kernel(&init_mm, pgtable); ++ } ++ } ++ else if(pmd_leaf(*pmdp)) ++ { ++ use_block_pmd = 1; ++ } + -+ pte_t *ptep = pte_offset_kernel(pmdp, (unsigned long)token); ++ if(use_block_pmd) ++ lm_ptep = (pte_t *)pmdp; ++ else ++ lm_ptep = pte_offset_kernel(pmdp, addr); ++ ++ // Handling cont mapping. ++ if(pte_val(*lm_ptep) & PTE_CONT) ++ { ++ // The beginning of cont mapping. ++ int i; ++ pte_t *ptep = pte_offset_kernel(pmdp, addr & CONT_PTE_MASK); ++ if(order < CONFIG_ARM64_CONT_PTE_SHIFT) ++ { ++ for(i = 0; i < CONT_PTES; i++) ++ { ++ set_pte(ptep,__pte(pte_val(*ptep) & ~PTE_CONT)); ++ ptep++; ++ } ++ } ++ } ++ ++ iee_addr = ((unsigned long)addr + (unsigned long)iee_offset); ++ pgdp = pgd_offset_pgd(pgdir, iee_addr); ++ p4dp = p4d_offset(pgdp, iee_addr); ++ pudp = pud_offset(p4dp, iee_addr); ++ pmdp = pmd_offset(pudp, iee_addr); ++ iee_ptep = pte_offset_kernel(pmdp, iee_addr); ++ iee_set_sensitive_pte(lm_ptep, iee_ptep, order, use_block_pmd); ++ flush_tlb_kernel_range(addr, addr+PAGE_SIZE*(1 << order)); ++ isb(); ++} ++ ++// Input is the lm vaddr of sensitive data. ++void unset_iee_page(unsigned long addr, int order) ++{ ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ pud_t *pudp = pud_offset(p4dp, addr); ++ pmd_t *pmdp = pmd_offset(pudp, addr); ++ pte_t *lm_ptep; ++ pte_t *iee_ptep; ++ unsigned long iee_addr; ++ int use_block_pmd = 0; ++ ++ // Use Block Descriptor. ++ if(pmd_leaf(*pmdp)) ++ { ++ use_block_pmd = 1; ++ lm_ptep = (pte_t *)pmdp; ++ } ++ else ++ lm_ptep = pte_offset_kernel(pmdp, addr); ++ ++ iee_addr = ((unsigned long)addr + (unsigned long)iee_offset); ++ pgdp = pgd_offset_pgd(pgdir, iee_addr); ++ p4dp = p4d_offset(pgdp, iee_addr); ++ pudp = pud_offset(p4dp, iee_addr); ++ pmdp = pmd_offset(pudp, iee_addr); ++ iee_ptep = pte_offset_kernel(pmdp, iee_addr); ++ iee_unset_sensitive_pte(lm_ptep, iee_ptep, order, use_block_pmd); ++ flush_tlb_kernel_range(addr, addr+PAGE_SIZE*(1 << order)); ++ flush_tlb_kernel_range(iee_addr, iee_addr+PAGE_SIZE*(1 << order)); ++ isb(); ++} ++ ++void set_iee_page_valid(unsigned long addr) ++{ ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ ++ pud_t *pudp = pud_offset(p4dp, addr); ++ ++ pmd_t *pmdp = pmd_offset(pudp, addr); ++ ++ pte_t *ptep = pte_offset_kernel(pmdp, addr); + pte_t pte = READ_ONCE(*ptep); -+ pte = __pte(((pte_val(pte) | 0x1) & ~PTE_ADDR_MASK) | __phys_to_pte_val(__pa(new))); ++ ++ if((addr < (PAGE_OFFSET + IEE_OFFSET)) | (addr > (PAGE_OFFSET + BIT(vabits_actual - 1)))) ++ return; ++ ++ pte = __pte(pte_val(pte) | PTE_VALID); + set_pte(ptep, pte); -+ flush_tlb_kernel_range((unsigned long)token, (unsigned long)(token+PAGE_SIZE)); ++} ++ ++void iee_set_logical_mem_ro(unsigned long addr) ++{ ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ pud_t *pudp = pud_offset(p4dp, addr); ++ pmd_t *pmdp; ++ pte_t *ptep; ++ pte_t pte; ++ ++ pmdp = pmd_offset(pudp, addr); ++ ++ // Handling cont mapping. ++ if(pmd_val(*pmdp) & PTE_CONT) ++ { ++ // The beginning of cont mapping. ++ int i; ++ pmd_t *pmdp = pmd_offset(pudp, addr & CONT_PMD_MASK); ++ for(i = 0; i < CONT_PMDS; i++) ++ { ++ set_pmd(pmdp,__pmd(pmd_val(*pmdp) & ~PTE_CONT)); ++ pmdp++; ++ } ++ } ++ ++ // Use Block Descriptor. ++ if(pmd_leaf(*pmdp)) ++ { ++ #ifndef CONFIG_PTP ++ struct page *page = pmd_page(*pmdp); ++ #endif ++ pte_t *pgtable = pte_alloc_one_kernel(&init_mm); ++ ++ if (!pgtable) ++ panic("Alloc pgtable error.\n"); ++ ++ #ifdef CONFIG_PTP ++ iee_split_huge_pmd(pmdp, pgtable); ++ #else ++ { ++ int i; ++ pte_t *ptep = pgtable; ++ for (i = 0; i < PMD_SIZE / PAGE_SIZE; i++, ptep++) { ++ pte_t entry; ++ pgprot_t pgprot = PAGE_KERNEL; ++ pgprot = __pgprot(pgprot_val(pgprot) | PTE_CONT); ++ ++ entry = mk_pte(page + i, pgprot); ++ set_pte(ptep, entry); ++ } ++ } ++ #endif ++ ++ spinlock_t *ptl = pmd_lock(&init_mm, pmdp); ++ if(pmd_leaf(READ_ONCE(*pmdp))) ++ { ++ smp_wmb(); ++ pmd_populate_kernel(&init_mm, pmdp, pgtable); ++ pgtable = NULL; ++ } ++ spin_unlock(ptl); ++ ++ if(pgtable) ++ { ++ #ifdef CONFIG_PTP ++ iee_memset(pgtable, 0, PAGE_SIZE); ++ #endif ++ pte_free_kernel(&init_mm, pgtable); ++ } ++ } ++ ++ ptep = pte_offset_kernel(pmdp, addr); ++ ++ // Handling cont mapping. ++ if(pte_val(*ptep) & PTE_CONT) ++ { ++ // The beginning of cont mapping. ++ int i; ++ pte_t *ptep = pte_offset_kernel(pmdp, addr & CONT_PTE_MASK); ++ for(i = 0; i < CONT_PTES; i++) ++ { ++ set_pte(ptep,__pte(pte_val(*ptep) & ~PTE_CONT)); ++ ptep++; ++ } ++ } ++ ++ pte = READ_ONCE(*ptep); ++ ++ if(addr < PAGE_OFFSET) ++ return; ++ ++ pte = __pte((pte_val(pte) | PTE_RDONLY) & ~PTE_DBM); ++ set_pte(ptep, pte); ++ flush_tlb_kernel_range(addr, addr+PAGE_SIZE); + isb(); +} + -+void iee_set_token_page_invalid(void *token) ++void iee_set_token_page_valid(void *token, void *new, unsigned int order) +{ + pgd_t *pgdir = swapper_pg_dir; + pgd_t *pgdp = pgd_offset_pgd(pgdir, (unsigned long)token); @@ -3616,77 +4385,281 @@ index 000000000000..7764dbd41555 + pmd_t *pmdp = pmd_offset(pudp, (unsigned long)token); + + pte_t *ptep = pte_offset_kernel(pmdp, (unsigned long)token); -+ pte_t pte = READ_ONCE(*ptep); -+ pte = __pte(((pte_val(pte) & ~((unsigned long)0x1)) & ~PTE_ADDR_MASK) | __phys_to_pte_val(__pa(token - IEE_OFFSET))); -+ set_pte(ptep, pte); -+ flush_tlb_kernel_range((unsigned long)token, (unsigned long)(token+PAGE_SIZE)); ++ iee_set_token(ptep, new, order); ++ ++ flush_tlb_kernel_range((unsigned long)token, (unsigned long)(token + (PAGE_SIZE * (1 << order)))); ++ flush_tlb_kernel_range((unsigned long)new, (unsigned long)(new + (PAGE_SIZE * (1 << order)))); ++ + isb(); +} + -+void iee_set_kernel_ppage(unsigned long addr) ++void iee_set_token_page_invalid(void *token_addr, void *token_page, unsigned long order) +{ ++ unsigned long iee_addr = ((unsigned long)token_page + (unsigned long)iee_offset); + pgd_t *pgdir = swapper_pg_dir; -+ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, (unsigned long)token_addr); ++ p4d_t *p4dp = p4d_offset(pgdp, (unsigned long)token_addr); ++ pud_t *pudp = pud_offset(p4dp, (unsigned long)token_addr); ++ pmd_t *pmdp = pmd_offset(pudp, (unsigned long)token_addr); ++ pte_t *ptep = pte_offset_kernel(pmdp, (unsigned long)token_addr); + -+ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ if(token_page == NULL) ++ panic("Token of task_struct was unset.\n"); + -+ pud_t *pudp = pud_offset(p4dp, addr); ++ iee_unset_token(ptep, token_addr, token_page, order); + -+ pmd_t *pmdp = pmd_offset(pudp, addr); ++ flush_tlb_kernel_range((unsigned long)token_addr, (unsigned long)(token_addr + (PAGE_SIZE * (1 << order)))); ++ flush_tlb_kernel_range((unsigned long)token_page, (unsigned long)(token_page + (PAGE_SIZE * (1 << order)))); ++ flush_tlb_kernel_range(iee_addr, iee_addr + (PAGE_SIZE * (1 << order))); ++ isb(); ++} + -+ pte_t *ptep = pte_offset_kernel(pmdp, addr); ++void unset_iee_stack_page(unsigned long addr, int order) ++{ ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ pud_t *pudp = pud_offset(p4dp, addr); ++ pmd_t *pmdp = pmd_offset(pudp, addr); ++ pte_t *ptep; ++ int use_block_pmd = 0; + -+ int i; -+ for(i = 0; i < 4; i++) ++ // Use Block Descriptor. ++ if(pmd_leaf(*pmdp)) + { -+ pte_t pte = READ_ONCE(*ptep); -+ pte = __pte(pte_val(pte) & ~PTE_USER & ~PTE_NG); -+ iee_set_pte_ppage(ptep, pte); -+ ptep++; ++ use_block_pmd = 1; ++ ptep = (pte_t *)pmdp; + } -+ flush_tlb_kernel_range(addr, addr+4*PAGE_SIZE); ++ else ++ ptep = pte_offset_kernel(pmdp, addr); ++ ++ iee_unset_stack_pte(ptep, order, use_block_pmd, addr); ++ flush_tlb_kernel_range(addr+iee_offset, addr+iee_offset+(1 << order)*PAGE_SIZE); + isb(); +} + -+void iee_set_kernel_upage(unsigned long addr) ++void set_iee_stack_page(unsigned long addr, int order) +{ + pgd_t *pgdir = swapper_pg_dir; + pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); -+ + p4d_t *p4dp = p4d_offset(pgdp, addr); -+ p4d_t p4d = READ_ONCE(*p4dp); -+ + pud_t *pudp = pud_offset(p4dp, addr); ++ pmd_t *pmdp; ++ pte_t *ptep; ++ int use_block_pmd = 0; + -+ pmd_t *pmdp = pmd_offset(pudp, addr); ++ pmdp = pmd_offset(pudp, addr); + -+ pte_t *ptep = pte_offset_kernel(pmdp, addr); ++ // Handling cont mapping. ++ if(pmd_val(*pmdp) & PTE_CONT) ++ { ++ // The beginning of cont mapping. ++ int i; ++ pmd_t *pmdp = pmd_offset(pudp, addr & CONT_PMD_MASK); ++ for(i = 0; i < CONT_PMDS; i++) ++ { ++ set_pmd(pmdp,__pmd(pmd_val(*pmdp) & ~PTE_CONT)); ++ pmdp++; ++ } ++ } + -+ int i; -+ for(i = 0; i < 4; i++) ++ // Use Block Descriptor. ++ if(pmd_leaf(*pmdp) && order < 9) + { -+ pte_t pte = READ_ONCE(*ptep); -+ pte = __pte(pte_val(pte) | PTE_USER | PTE_NG); -+ iee_set_pte_upage(ptep, pte); -+ ptep++; ++ #ifndef CONFIG_PTP ++ struct page *page = pmd_page(*pmdp); ++ #endif ++ pte_t *pgtable = pte_alloc_one_kernel(&init_mm); ++ ++ if (!pgtable) ++ panic("Alloc pgtable error.\n"); ++ ++ #ifdef CONFIG_PTP ++ iee_split_huge_pmd(pmdp, pgtable); ++ #else ++ { ++ int i; ++ pte_t *ptep = pgtable; ++ for (i = 0; i < PMD_SIZE / PAGE_SIZE; i++, ptep++) { ++ pte_t entry; ++ pgprot_t pgprot = PAGE_KERNEL; ++ pgprot = __pgprot(pgprot_val(pgprot) | PTE_CONT); ++ ++ entry = mk_pte(page + i, pgprot); ++ set_pte(ptep, entry); ++ } ++ } ++ #endif ++ ++ spinlock_t *ptl = pmd_lock(&init_mm, pmdp); ++ if(pmd_leaf(READ_ONCE(*pmdp))) ++ { ++ smp_wmb(); ++ pmd_populate_kernel(&init_mm, pmdp, pgtable); ++ pgtable = NULL; ++ } ++ spin_unlock(ptl); ++ ++ if(pgtable) ++ { ++ #ifdef CONFIG_PTP ++ iee_memset(pgtable, 0, PAGE_SIZE); ++ #endif ++ pte_free_kernel(&init_mm, pgtable); ++ } + } -+ flush_tlb_kernel_range(addr, addr+4*PAGE_SIZE); ++ else if(pmd_leaf(*pmdp)) ++ { ++ use_block_pmd = 1; ++ } ++ ++ if(use_block_pmd) ++ ptep = (pte_t *)pmdp; ++ else ++ ptep = pte_offset_kernel(pmdp, addr); ++ ++ // Handling cont mapping. ++ if(pte_val(*ptep) & PTE_CONT) ++ { ++ // The beginning of cont mapping. ++ int i; ++ pte_t *ptep = pte_offset_kernel(pmdp, addr & CONT_PTE_MASK); ++ if(order < CONFIG_ARM64_CONT_PTE_SHIFT) ++ { ++ for(i = 0; i < CONT_PTES; i++) ++ { ++ set_pte(ptep,__pte(pte_val(*ptep) & ~PTE_CONT)); ++ ptep++; ++ } ++ } ++ } ++ ++ iee_set_stack_pte(ptep, order, use_block_pmd, addr); ++ flush_tlb_kernel_range(addr, addr+(1 << order)*PAGE_SIZE); + isb(); +} \ No newline at end of file diff --git a/arch/arm64/kernel/iee/iee-gate.S b/arch/arm64/kernel/iee/iee-gate.S new file mode 100644 -index 000000000000..6de99a018bde +index 000000000000..24a80378191d --- /dev/null +++ b/arch/arm64/kernel/iee/iee-gate.S -@@ -0,0 +1,174 @@ +@@ -0,0 +1,314 @@ +#include +#include +#include +#include ++#include ++#include + +#ifdef CONFIG_IEE + ++SYM_FUNC_START(iee_read_tmp_page) ++ /* save daif, close irq */ ++ mrs x13, daif ++ msr daifset, #0x2 ++ isb ++ /* disable PAN */ ++ msr pan, #0x0 ++ adrp x12, iee_offset ++ ldr x12, [x12, #:lo12:iee_offset] ++ add x11, x0, x12 /* x11 -> task_token(IEE) */ ++ ldr x0, [x11, #tmp_page_from_token_offset] ++ /* enable PAN */ ++ msr pan, #0x1 ++ /* restore daif */ ++ msr daif, x13 ++ ret ++SYM_FUNC_END(iee_read_tmp_page) ++ ++SYM_FUNC_START(iee_read_freeptr) ++ /* save daif, close irq */ ++ mrs x13, daif ++ msr daifset, #0x2 ++ isb ++ /* disable PAN */ ++ msr pan, #0x0 ++ adrp x12, iee_offset ++ ldr x12, [x12, #:lo12:iee_offset] ++ add x0, x0, x12 ++ ldr x0, [x0] ++ /* enable PAN */ ++ msr pan, #0x1 ++ /* restore daif */ ++ msr daif, x13 ++ ret ++SYM_FUNC_END(iee_read_freeptr) ++ ++SYM_FUNC_START(iee_read_token_stack) ++ /* save daif, close irq */ ++ mrs x13, daif ++ msr daifset, #0x2 ++ isb ++ /* disable PAN */ ++ msr pan, #0x0 ++ adrp x12, iee_offset ++ ldr x12, [x12, #:lo12:iee_offset] ++ add x11, x0, x12 /* x11 -> task_token(IEE) */ ++ ldr x0, [x11, #iee_from_token_offset] ++ /* enable PAN */ ++ msr pan, #0x1 ++ /* restore daif */ ++ msr daif, x13 ++ ret ++SYM_FUNC_END(iee_read_token_stack) ++ ++SYM_FUNC_START(iee_set_xchg_relaxed) ++ /* save daif, close irq */ ++ mrs x13, daif ++ msr daifset, #0x2 ++ isb ++ /* disable PAN */ ++ msr pan, #0x0 ++ /* begin */ ++ adrp x2, iee_offset ++ ldr x2, [x2, #:lo12:iee_offset] ++ add x0, x0, x2 ++ prfm pstl1strm, [x0] ++12: ++ ldxr x3, [x0] ++ stxr w4, x1, [x0] ++ cbnz w4, 12b ++ mov x0, x3 ++ /* end */ ++ /* enable PAN */ ++ msr pan, #0x1 ++ /* restore daif */ ++ msr daif, x13 ++ ret ++SYM_FUNC_END(iee_set_xchg_relaxed) ++ ++SYM_FUNC_START(iee_set_cmpxchg_relaxed) ++ /* save daif, close irq */ ++ mrs x13, daif ++ msr daifset, #0x2 ++ isb ++ /* disable PAN */ ++ msr pan, #0x0 ++ /* begin */ ++ adrp x9, iee_offset ++ ldr x9, [x9, #:lo12:iee_offset] ++ add x3, x0, x9 ++ prfm pstl1strm, [x3] ++11: ++ ldxr x0, [x3] ++ eor x4, x0, x1 ++ cbnz w4, 13f ++ stxr w4, x2, [x3] ++ cbnz w4, 11b ++13: ++ /* end */ ++ /* enable PAN */ ++ msr pan, #0x1 ++ /* restore daif */ ++ msr daif, x13 ++ ret ++SYM_FUNC_END(iee_set_cmpxchg_relaxed) ++ +SYM_FUNC_START(iee_rw_gate) + /* save daif, close irq */ + mrs x13, daif @@ -3703,21 +4676,20 @@ index 000000000000..6de99a018bde + msr daif, x13 + ret +SYM_FUNC_END(iee_rw_gate) -+#if defined(CONFIG_CREDP) || defined(CONFIG_KOI) ++#if defined(CONFIG_CREDP) || defined(CONFIG_KOI) || (CONFIG_KEYP) +EXPORT_SYMBOL(iee_rw_gate) +#endif + + .pushsection ".iee.text.header", "ax" + +SYM_FUNC_START(iee_protected_rw_gate) -+ mrs x9, pan + /* disable PAN */ + msr pan, #0x0 + /* switch to iee stack */ + mrs x9, sp_el0 /* x9 -> task_struct */ -+ adrp x12, iee_offset -+ ldr x12, [x12, #:lo12:iee_offset] -+ add x11, x9, x12 /* x11 -> task_token(IEE) */ ++ adrp x7, iee_offset ++ ldr x7, [x7, #:lo12:iee_offset] ++ add x11, x9, x7 /* x11 -> task_token(IEE) */ + // store kernel stack + mov x10, sp + str x10, [x11, #kernel_from_token_offset] @@ -3729,15 +4701,20 @@ index 000000000000..6de99a018bde + /* restore daif */ + msr daif, x13 + sub sp, sp, #16 -+ stp x29, x30, [sp] ++ stp x11, x30, [sp] +#else -+ sub sp, sp, #16 ++ sub sp, sp, #32 ++ stp x11, x7, [sp, #16] + stp x13, x30, [sp] +#endif + /* call iee func */ -+ bl iee_dispatch ++ adrp x12, iee_funcs ++ add x12, x12, x0, lsl #3 ++ ldr x12, [x12, #:lo12:iee_funcs] ++ mov x0, x7 ++ blr x12 +#ifdef CONFIG_IEE_INTERRUPTABLE -+ ldp x29, x30, [sp] ++ ldp x11, x30, [sp] + add sp, sp, #16 + /* store and disable daif */ + mrs x13, daif @@ -3745,16 +4722,10 @@ index 000000000000..6de99a018bde + isb +#else + ldp x13, x30, [sp] -+ add sp, sp, #16 ++ ldp x11, x7, [sp, #16] ++ add sp, sp, #32 +#endif + /* switch to kernel stack */ -+ mrs x9, sp_el0 /* x9 -> task_struct(VA) */ -+ adrp x12, iee_offset -+ ldr x12, [x12, #:lo12:iee_offset] -+ add x11, x9, x12 /* x11 -> task_token(IEE) */ -+ // store iee stack -+ mov x10, sp -+ str x10, [x11, #iee_from_token_offset] + // load kernel stack + ldr x10, [x11, #kernel_from_token_offset] + mov sp, x10 @@ -3789,29 +4760,42 @@ index 000000000000..6de99a018bde + + b iee_rwx_gate_tramp +SYM_FUNC_END(iee_rwx_gate_entry) ++#ifdef CONFIG_KOI ++EXPORT_SYMBOL(iee_rwx_gate_entry) ++#endif + .popsection + ++#define USER_ASID_FLAG (UL(1) << 48) ++ + .pushsection ".iee.si_text", "awx" + +SYM_FUNC_START(iee_rwx_gate_tramp) + /* Check tcr val. */ + mrs x10, tcr_el1 -+ adrp x12, iee_si_tcr // tcr val shall be const after init ++ adrp x12, iee_si_tcr // tcr value shall be const after init + ldr x12, [x12, #:lo12:iee_si_tcr] + cbz x12, 1f + cmp x12, x10 + b.ne 3f +1: + mov x13, sp ++ /* if called by koi, skip stack switch */ ++#ifdef CONFIG_KOI ++ cmp x0, #IEE_SWITCH_TO_KERNEL ++ b.eq 4f ++ cmp x0, #IEE_SWITCH_TO_KOI ++ b.eq 5f ++#endif ++ + /* If iee hasn't been initialized, skip stack switch. */ -+ ldr x11, =iee_init_done -+ ldr x10, [x11] ++ adrp x11, iee_init_done ++ ldr x10, [x11, #:lo12:iee_init_done] + cbz x10, 2f + + /* Switch to iee stack */ + mrs x9, sp_el0 // x9 -> task_struct -+ adrp x12, iee_offset -+ ldr x12, [x12, #:lo12:iee_offset] ++ adrp x12, iee_si_offset ++ ldr x12, [x12, #:lo12:iee_si_offset] + add x11, x9, x12 // x11 -> task_token(IEE) + // load iee stack + ldr x10, [x11, #iee_from_token_offset] @@ -3831,6 +4815,27 @@ index 000000000000..6de99a018bde + mrs x2, esr_el1 + bl iee_bad_mode + ASM_BUG() ++#ifdef CONFIG_KOI ++/* Handle KOI switch gates. */ ++4: ++ /* IEE_SWITCH_TO_KERNEL */ ++ mrs x9, ttbr1_el1 ++ bic x9, x9, #USER_ASID_FLAG // Set new ASID to even ++ adrp x11, iee_base_swapper_pg_dir ++ ldr x11, [x11, #:lo12:iee_base_swapper_pg_dir] ++ ubfx x10, x9, #48, #16 // x10 -> new TTBR1 ASID ++ bfi x11, x10, #48, #16 ++ b 6f ++5: ++ /* IEE_SWITCH_TO_KOI */ ++ tbz x1, #48, 3b // KOI ASID shall be odd. ++ mov x11, x1 ++6: ++ msr ttbr1_el1, x11 ++ isb ++ stp x15, x13, [sp, #-32]! ++ b iee_rwx_gate_exit ++#endif +SYM_FUNC_END(iee_rwx_gate_tramp) + + .popsection @@ -3854,9479 +4859,15248 @@ index 000000000000..6de99a018bde + .popsection + +#endif -diff --git a/arch/arm64/kernel/iee/iee.c b/arch/arm64/kernel/iee/iee.c +diff --git a/arch/arm64/kernel/iee/iee-key.c b/arch/arm64/kernel/iee/iee-key.c new file mode 100644 -index 000000000000..6b9f7d40df67 +index 000000000000..a801f9fdebf0 --- /dev/null -+++ b/arch/arm64/kernel/iee/iee.c -@@ -0,0 +1,1360 @@ -+#include "linux/sched.h" -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_IEE -+extern struct cred init_cred; -+extern s64 memstart_addr; -+ -+void __iee_code _iee_set_swapper_pgd(pgd_t *pgdp, pgd_t pgd); -+void __iee_code _iee_set_tramp_pgd_pre_init(pgd_t *pgdp, pgd_t pgd); -+void __iee_code _iee_set_pte(pte_t *ptep, pte_t pte); -+void __iee_code _iee_set_pmd(pmd_t *pmdp, pmd_t pmd); -+void __iee_code _iee_set_pud(pud_t *pudp, pud_t pud); -+void __iee_code _iee_set_p4d(p4d_t *p4dp, p4d_t p4d); -+void __iee_code _iee_set_bm_pte(pte_t *ptep, pte_t pte); -+pteval_t __iee_code _iee_set_xchg_relaxed(pte_t *ptep, pteval_t pteval); -+pteval_t __iee_code _iee_set_cmpxchg_relaxed(pte_t *ptep, pteval_t old_pteval, pteval_t new_pteval); -+void __iee_code _iee_write_in_byte(void *ptr, __u64 data, int length); -+void __iee_code _iee_set_cred_uid(struct cred *cred, kuid_t uid); -+void __iee_code _iee_set_cred_gid(struct cred *cred, kgid_t gid); -+void __iee_code _iee_copy_cred(struct cred *old, struct cred *new); -+void __iee_code _iee_set_cred_suid(struct cred *cred, kuid_t suid); -+void __iee_code _iee_set_cred_sgid(struct cred *cred, kgid_t sgid); -+void __iee_code _iee_set_cred_euid(struct cred *cred, kuid_t euid); -+void __iee_code _iee_set_cred_egid(struct cred *cred, kgid_t egid); -+void __iee_code _iee_set_cred_fsuid(struct cred *cred, kuid_t fsuid); -+void __iee_code _iee_set_cred_fsgid(struct cred *cred, kgid_t fsgid); -+void __iee_code _iee_set_cred_user(struct cred *cred, struct user_struct *user); -+void __iee_code _iee_set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns); -+void __iee_code _iee_set_cred_ucounts(struct cred *cred, struct ucounts *ucounts); -+void __iee_code _iee_set_cred_group_info(struct cred *cred, struct group_info *group_info); -+void __iee_code _iee_set_cred_securebits(struct cred *cred, unsigned securebits); -+void __iee_code _iee_set_cred_cap_inheritable(struct cred *cred, kernel_cap_t cap_inheritable); -+void __iee_code _iee_set_cred_cap_permitted(struct cred *cred, kernel_cap_t cap_permitted); -+void __iee_code _iee_set_cred_cap_effective(struct cred *cred, kernel_cap_t cap_effective); -+void __iee_code _iee_set_cred_cap_bset(struct cred *cred, kernel_cap_t cap_bset); -+void __iee_code _iee_set_cred_cap_ambient(struct cred *cred, kernel_cap_t cap_ambient); -+void __iee_code _iee_set_cred_jit_keyring(struct cred *cred, unsigned char jit_keyring); -+void __iee_code _iee_set_cred_session_keyring(struct cred *cred, struct key *session_keyring); -+void __iee_code _iee_set_cred_process_keyring(struct cred *cred, struct key *process_keyring); -+void __iee_code _iee_set_cred_thread_keyring(struct cred *cred, struct key *thread_keyring); -+void __iee_code _iee_set_cred_request_key_auth(struct cred *cred, struct key *request_key_auth); -+void __iee_code _iee_set_cred_non_rcu(struct cred *cred, int non_rcu); -+void __iee_code _iee_set_cred_atomic_set_usage(struct cred *cred, int i); -+bool __iee_code _iee_set_cred_atomic_op_usage(struct cred *cred, int flag, int nr); -+void __iee_code _iee_set_cred_security(struct cred *cred, void *security); -+void __iee_code _iee_set_cred_rcu(struct cred *cred, struct rcu_head *rcu); -+void __iee_code _iee_memset(void *ptr, int data, size_t n); -+void __iee_code _iee_set_track(struct track *ptr, struct track *data); -+void __iee_code _iee_set_freeptr(freeptr_t *pptr, freeptr_t ptr); -+void __iee_code _iee_set_pte_upage(pte_t *ptep, pte_t pte); -+void __iee_code _iee_set_pte_ppage(pte_t *ptep, pte_t pte); -+void __iee_code _iee_set_token_mm(struct task_struct *tsk, struct mm_struct *mm); -+void __iee_code _iee_set_token_pgd(struct task_struct *tsk, pgd_t *pgd); -+void __iee_code _iee_init_token(struct task_struct *tsk, void *kernel_stack, void *iee_stack); -+void __iee_code _iee_free_token(struct task_struct *tsk); -+unsigned long __iee_code _iee_read_token_stack(struct task_struct *tsk); -+void __iee_code _iee_write_entry_task(struct task_struct *tsk); -+#ifdef CONFIG_KOI -+unsigned long __iee_code _iee_read_koi_stack(struct task_struct *tsk); -+void __iee_code _iee_write_koi_stack(struct task_struct *tsk, unsigned long koi_stack); -+unsigned long __iee_code _iee_read_token_ttbr1(struct task_struct *tsk); -+void __iee_code _iee_write_token_ttbr1(struct task_struct *tsk, unsigned long current_ttbr1); -+unsigned long __iee_code _iee_read_koi_kernel_stack(struct task_struct *tsk); -+void __iee_code _iee_write_koi_kernel_stack(struct task_struct *tsk, unsigned long kernel_stack); -+unsigned long __iee_code _iee_read_koi_stack_base(struct task_struct *tsk); -+void __iee_code _iee_write_koi_stack_base(struct task_struct *tsk, unsigned long koi_stack_base); -+#endif -+ -+/* wrapper functions */ -+void __iee_code iee_wrapper_write_in_byte(va_list args) { -+ void *ptr = va_arg(args, void *); -+ __u64 data = va_arg(args, __u64); -+ int length = va_arg(args, int); -+ _iee_write_in_byte(ptr, data, length); -+} -+ -+void __iee_code iee_wrapper_set_pte(va_list args) { -+ pte_t *ptep = va_arg(args, pte_t *); -+ pte_t pte = va_arg(args, pte_t); -+ _iee_set_pte(ptep, pte); -+} ++++ b/arch/arm64/kernel/iee/iee-key.c +@@ -0,0 +1,12 @@ ++#include ++#include ++#include + -+void __iee_code iee_wrapper_set_pmd(va_list args) { -+ pmd_t *pmdp = va_arg(args, pmd_t *); -+ pmd_t pmd = va_arg(args, pmd_t); -+ _iee_set_pmd(pmdp, pmd); -+} ++extern unsigned long long iee_rw_gate(int flag, ...); + -+void __iee_code iee_wrapper_set_p4d(va_list args) { -+ p4d_t *p4dp = va_arg(args, p4d_t *); -+ p4d_t p4d = va_arg(args, p4d_t); -+ _iee_set_p4d(p4dp, p4d); ++#ifdef CONFIG_KEYP ++void iee_write_key_payload_rcu_data0(struct key *key, void *rcu_data0) ++{ ++ iee_rw_gate(IEE_OP_WRITE_KEY_PAYLOAD_RCU_DATA0, key, rcu_data0); +} ++#endif +\ No newline at end of file +diff --git a/arch/arm64/kernel/iee/iee-pgtable.c b/arch/arm64/kernel/iee/iee-pgtable.c +new file mode 100644 +index 000000000000..bd43af6d4eb3 +--- /dev/null ++++ b/arch/arm64/kernel/iee/iee-pgtable.c +@@ -0,0 +1,402 @@ ++#include ++#include ++#include ++#include + -+void __iee_code iee_wrapper_set_pud(va_list args) { -+ pud_t *pudp = va_arg(args, pud_t *); -+ pud_t pud = va_arg(args, pud_t); -+ _iee_set_pud(pudp, pud); -+} ++#ifdef CONFIG_PTP + -+void __iee_code iee_wrapper_set_bm_pte(va_list args) { -+ pte_t *ptep = va_arg(args, pte_t *); -+ pte_t pte = va_arg(args, pte_t); -+ _iee_set_bm_pte(ptep, pte); ++void iee_set_tramp_pgd_pre_init(pgd_t *pgdp, pgd_t pgd) ++{ ++ iee_rw_gate(IEE_OP_SET_TRAMP_PGD, pgdp, pgd); +} + -+void __iee_code iee_wrapper_set_swapper_pgd(va_list args) { -+ pgd_t *pgdp = va_arg(args, pgd_t *); -+ pgd_t pgd = va_arg(args, pgd_t); -+ _iee_set_swapper_pgd(pgdp, pgd); -+} ++inline void iee_set_bm_pte(pte_t *ptep, pte_t pte) ++{ ++ // If it is pre init, write once. ++ // Else, write once will cause exception. So it is safe. ++ unsigned long flags; ++ unsigned long res; ++ local_irq_save(flags); ++ asm volatile("at s1e1r, %0"::"r"(__phys_to_iee(__pa_symbol(ptep)))); ++ isb(); ++ res = read_sysreg(par_el1); ++ local_irq_restore(flags); ++#ifdef CONFIG_KOI ++ if (pte_valid(pte)) ++ pte = __pte(pte_val(pte) | PTE_NG); ++#endif ++ if(res & 0x1) ++ WRITE_ONCE(*ptep,pte); ++ else ++ iee_rw_gate(IEE_OP_SET_BM_PTE, ptep, pte); + -+void __iee_code iee_wrapper_set_tramp_pgd(va_list args) { -+ pgd_t *pgdp = va_arg(args, pgd_t *); -+ pgd_t pgd = va_arg(args, pgd_t); -+ _iee_set_tramp_pgd_pre_init(pgdp, pgd); ++ /* ++ * Only if the new pte is valid and kernel, otherwise TLB maintenance ++ * or update_mmu_cache() have the necessary barriers. ++ */ ++ if (pte_valid_not_user(pte)) { ++ dsb(ishst); ++ isb(); ++ } +} + -+pteval_t __iee_code iee_wrapper_set_xchg(va_list args) { -+ pteval_t ret; -+ pte_t *ptep = va_arg(args, pte_t *); -+ pteval_t pteval = va_arg(args, pteval_t); -+ ret = _iee_set_xchg_relaxed(ptep, pteval); -+ return (u64)ret; -+} ++inline void iee_set_fixmap_pte_pre_init(pte_t *ptep, pte_t pte) ++{ ++#ifdef CONFIG_KOI ++ if (pte_valid(pte)) { ++ pte = __pte(pte_val(pte) | PTE_NG); ++ } ++#endif ++ WRITE_ONCE(*ptep, pte); + -+pteval_t __iee_code iee_wrapper_set_cmpxchg(va_list args) { -+ pteval_t ret; -+ pte_t *ptep = va_arg(args, pte_t *); -+ pteval_t old_pteval = va_arg(args, pteval_t); -+ pteval_t new_pteval = va_arg(args, pteval_t); -+ ret = _iee_set_cmpxchg_relaxed(ptep, old_pteval, new_pteval); -+ return (u64)ret; ++ /* ++ * Only if the new pte is valid and kernel, otherwise TLB maintenance ++ * or update_mmu_cache() have the necessary barriers. ++ */ ++ if (pte_valid_not_user(pte)) { ++ dsb(ishst); ++ isb(); ++ } +} + -+void __iee_code iee_wrapper_set_cred_uid(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ kuid_t uid = va_arg(args, kuid_t); -+ _iee_set_cred_uid(cred, uid); -+} ++inline void iee_set_pte_at(struct mm_struct *mm, unsigned long addr, ++ pte_t *ptep, pte_t pte) ++{ ++ __sync_cache_and_tags(pte, 1); ++ __check_safe_pte_update(mm, ptep, pte); + -+void __iee_code iee_wrapper_set_cred_gid(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ kgid_t gid = va_arg(args, kgid_t); -+ _iee_set_cred_gid(cred, gid); ++ iee_set_pte_pre_init(ptep, pte); +} + -+void __iee_code iee_wrapper_copy_cred(va_list args) { -+ struct cred *old = va_arg(args, struct cred *); -+ struct cred *new = va_arg(args, struct cred *); -+ _iee_copy_cred(old, new); ++inline void iee_set_pte_at_delayed(struct mm_struct *mm, unsigned long addr, ++ pte_t *ptep, pte_t pte) ++{ ++ __sync_cache_and_tags(pte, 1); ++ __check_safe_pte_update(mm, ptep, pte); +} + -+void __iee_code iee_wrapper_set_cred_suid(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ kuid_t suid = va_arg(args, kuid_t); -+ _iee_set_cred_suid(cred, suid); ++inline bool in_tramp_pgdir(void *addr) ++{ ++ return ((unsigned long)addr & PAGE_MASK) == ++ ((unsigned long)tramp_pg_dir & PAGE_MASK); +} + -+void __iee_code iee_wrapper_set_cred_sgid(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ kgid_t sgid = va_arg(args, kgid_t); -+ _iee_set_cred_sgid(cred, sgid); -+} ++inline void iee_set_fixmap_pmd_pre_init(pmd_t *pmdp, pmd_t pmd) ++{ ++#ifdef __PAGETABLE_PMD_FOLDED ++ if (in_swapper_pgdir(pmdp)) { ++ set_swapper_pgd((pgd_t *)pmdp, __pgd(pmd_val(pmd))); ++ return; ++ } ++#endif /* __PAGETABLE_PMD_FOLDED */ ++#ifdef CONFIG_KOI ++ pmdval_t val = pmd_val(pmd); ++ if (pmd_valid(pmd) && !(val & PMD_TABLE_BIT)) { ++ pmd = __pmd(val | PMD_SECT_NG); ++ } ++#endif ++ WRITE_ONCE(*pmdp, pmd); + -+void __iee_code iee_wrapper_set_cred_euid(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ kuid_t euid = va_arg(args, kuid_t); -+ _iee_set_cred_euid(cred, euid); ++ if (pmd_valid(pmd)) { ++ dsb(ishst); ++ isb(); ++ } +} + -+void __iee_code iee_wrapper_set_cred_egid(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ kgid_t egid = va_arg(args, kgid_t); -+ _iee_set_cred_egid(cred, egid); -+} ++inline void iee_set_fixmap_pud_pre_init(pud_t *pudp, pud_t pud) ++{ ++#ifdef __PAGETABLE_PUD_FOLDED ++ if (in_swapper_pgdir(pudp)) { ++ set_swapper_pgd((pgd_t *)pudp, __pgd(pud_val(pud))); ++ return; ++ } ++#endif /* __PAGETABLE_PUD_FOLDED */ ++#ifdef CONFIG_KOI ++ pudval_t val = pud_val(pud); ++ if (pud_valid(pud) && !(val & PUD_TABLE_BIT)) { ++ // There is no PUD_SEC_NG, so we use PMD_SECT_NG instead. ++ pud = __pud(val | PMD_SECT_NG); ++ } ++#endif ++ WRITE_ONCE(*pudp, pud); + -+void __iee_code iee_wrapper_set_cred_fsuid(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ kuid_t fsuid = va_arg(args, kuid_t); -+ _iee_set_cred_fsuid(cred, fsuid); ++ if (pud_valid(pud)) { ++ dsb(ishst); ++ isb(); ++ } +} + -+void __iee_code iee_wrapper_set_cred_fsgid(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ kgid_t fsgid = va_arg(args, kgid_t); -+ _iee_set_cred_fsgid(cred, fsgid); -+} ++#endif //#ifdef CONFIG_PTP + -+void __iee_code iee_wrapper_set_cred_user(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ struct user_struct *user = va_arg(args, struct user_struct *); -+ _iee_set_cred_user(cred, user); ++inline void __set_pte(pte_t *ptep, pte_t pte) ++{ ++#ifdef CONFIG_KOI ++ if (pte_valid(pte)) { ++ pte = __pte(pte_val(pte) | PTE_NG); ++ } ++#endif ++#ifdef CONFIG_PTP ++ iee_rw_gate(IEE_OP_SET_PTE, ptep, pte); ++ dsb(ishst); ++ isb(); ++#else ++ WRITE_ONCE(*ptep, pte); ++ if (pte_valid_not_user(pte)) { ++ dsb(ishst); ++ isb(); ++ } ++#endif +} + -+void __iee_code iee_wrapper_set_cred_user_ns(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ struct user_namespace *user_ns = va_arg(args, struct user_namespace *); -+ _iee_set_cred_user_ns(cred, user_ns); ++inline void set_pmd(pmd_t *pmdp, pmd_t pmd) ++{ ++#ifdef __PAGETABLE_PMD_FOLDED ++ if (in_swapper_pgdir(pmdp)) { ++ set_swapper_pgd((pgd_t *)pmdp, __pgd(pmd_val(pmd))); ++ return; ++ } ++#endif /* __PAGETABLE_PMD_FOLDED */ ++#ifdef CONFIG_KOI ++ pmdval_t val = pmd_val(pmd); ++ if (pmd_valid(pmd) && !(val & PMD_TABLE_BIT)) { ++ pmd = __pmd(val | PMD_SECT_NG); ++ } ++#endif ++#ifdef CONFIG_PTP ++ iee_rw_gate(IEE_OP_SET_PMD, pmdp, pmd); ++#else ++ WRITE_ONCE(*pmdp, pmd); ++#endif ++ if (pmd_valid(pmd)) { ++ dsb(ishst); ++ isb(); ++ } +} + -+void __iee_code iee_wrapper_set_cred_ucounts(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ struct ucounts *ucounts = va_arg(args, struct ucounts *); -+ _iee_set_cred_ucounts(cred, ucounts); ++inline void set_pud(pud_t *pudp, pud_t pud) ++{ ++#ifdef __PAGETABLE_PUD_FOLDED ++ if (in_swapper_pgdir(pudp)) { ++ set_swapper_pgd((pgd_t *)pudp, __pgd(pud_val(pud))); ++ return; ++ } ++#endif /* __PAGETABLE_PUD_FOLDED */ ++#ifdef CONFIG_KOI ++ pudval_t val = pud_val(pud); ++ if (pud_valid(pud) && !(val & PUD_TABLE_BIT)) { ++ // There is no PUD_SEC_NG, so we use PMD_SECT_NG instead. ++ pud = __pud(val | PMD_SECT_NG); ++ } ++#endif ++#ifdef CONFIG_PTP ++ iee_rw_gate(IEE_OP_SET_PUD, pudp, pud); ++#else ++ WRITE_ONCE(*pudp, pud); ++#endif ++ if (pud_valid(pud)) { ++ dsb(ishst); ++ isb(); ++ } +} + -+void __iee_code iee_wrapper_set_cred_group_info(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ struct group_info *group_info = va_arg(args, struct group_info *); -+ _iee_set_cred_group_info(cred, group_info); -+} ++inline void set_p4d(p4d_t *p4dp, p4d_t p4d) ++{ ++ if (in_swapper_pgdir(p4dp)) ++ { ++ set_swapper_pgd((pgd_t *)p4dp, __pgd(p4d_val(p4d))); ++ return; ++ } + -+void __iee_code iee_wrapper_set_cred_securebits(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ unsigned securebits = va_arg(args, unsigned); -+ _iee_set_cred_securebits(cred, securebits); ++#ifdef CONFIG_PTP ++ if(in_tramp_pgdir(p4dp)) ++ { ++ iee_set_tramp_pgd_pre_init((pgd_t *)p4dp, __pgd(p4d_val(p4d))); ++ return; ++ } ++ iee_rw_gate(IEE_OP_SET_P4D, p4dp, p4d); ++#else ++ WRITE_ONCE(*p4dp, p4d); ++#endif ++ dsb(ishst); ++ isb(); +} + -+void __iee_code iee_wrapper_set_cred_cap_inheritable(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ kernel_cap_t cap_inheritable = va_arg(args, kernel_cap_t); -+ _iee_set_cred_cap_inheritable(cred, cap_inheritable); -+} ++#ifdef CONFIG_IEE ++inline void iee_set_stack_pte(pte_t *ptep, int order, int use_block_pmd, unsigned long lm_addr) ++{ ++#ifdef CONFIG_PTP ++ iee_rw_gate(IEE_OP_SET_PTE_U, ptep, order, use_block_pmd, lm_addr); ++#else ++ int i; ++ unsigned long iee_addr = lm_addr + iee_offset; ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, iee_addr); ++ p4d_t *p4dp = p4d_offset(pgdp, iee_addr); ++ pud_t *pudp = pud_offset(p4dp, iee_addr); ++ pmd_t *pmdp = pmd_offset(pudp, iee_addr); ++ pte_t *iee_ptep = pte_offset_kernel(pmdp, iee_addr); ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) | PTE_VALID); ++ WRITE_ONCE(*iee_ptep, pte); ++ iee_ptep++; ++ } + -+void __iee_code iee_wrapper_set_cred_cap_permitted(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ kernel_cap_t cap_permitted = va_arg(args, kernel_cap_t); -+ _iee_set_cred_cap_permitted(cred, cap_permitted); ++ if(use_block_pmd) ++ { ++ pmd_t *pmdp = (pmd_t *)ptep; ++ pmd_t pmd = READ_ONCE(*pmdp); ++ pmd = __pmd(pmd_val(pmd) & ~PTE_VALID); ++ WRITE_ONCE(*pmdp, pmd); ++ } ++ else ++ { ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(pte_val(pte) & ~PTE_VALID); ++ WRITE_ONCE(*ptep, pte); ++ ptep++; ++ } ++ } ++#endif ++ dsb(ishst); ++ isb(); +} + -+void __iee_code iee_wrapper_set_cred_cap_effective(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ kernel_cap_t cap_effective = va_arg(args, kernel_cap_t); -+ _iee_set_cred_cap_effective(cred, cap_effective); -+} ++inline void iee_unset_stack_pte(pte_t *ptep, int order, int use_block_pmd, unsigned long lm_addr) ++{ ++#ifdef CONFIG_PTP ++ iee_rw_gate(IEE_OP_SET_PTE_P, ptep, order, use_block_pmd, lm_addr); ++#else ++ int i; ++ unsigned long iee_addr = lm_addr + iee_offset; ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, iee_addr); ++ p4d_t *p4dp = p4d_offset(pgdp, iee_addr); ++ pud_t *pudp = pud_offset(p4dp, iee_addr); ++ pmd_t *pmdp = pmd_offset(pudp, iee_addr); ++ pte_t *iee_ptep = pte_offset_kernel(pmdp, iee_addr); ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) & ~PTE_VALID); ++ WRITE_ONCE(*iee_ptep, pte); ++ iee_ptep++; ++ } + -+void __iee_code iee_wrapper_set_cred_cap_bset(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ kernel_cap_t cap_bset = va_arg(args, kernel_cap_t); -+ _iee_set_cred_cap_bset(cred, cap_bset); ++ if(use_block_pmd) ++ { ++ pmd_t *pmdp = (pmd_t *)ptep; ++ pmd_t pmd = READ_ONCE(*pmdp); ++ pmd = __pmd(pmd_val(pmd) | PTE_VALID); ++ WRITE_ONCE(*pmdp, pmd); ++ } ++ else ++ { ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(pte_val(pte) | PTE_VALID); ++ #ifdef CONFIG_KOI ++ if (pte_valid(pte)) ++ pte = __pte(pte_val(pte) | PTE_NG); ++ #endif ++ WRITE_ONCE(*ptep, pte); ++ ptep++; ++ } ++ } ++#endif ++ dsb(ishst); ++ isb(); +} + -+void __iee_code iee_wrapper_set_cred_cap_ambient(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ kernel_cap_t cap_ambient = va_arg(args, kernel_cap_t); -+ _iee_set_cred_cap_ambient(cred, cap_ambient); ++inline void iee_set_sensitive_pte(pte_t *lm_ptep, pte_t *iee_ptep, int order, int use_block_pmd) ++{ ++#ifdef CONFIG_PTP ++ iee_rw_gate(IEE_SET_SENSITIVE_PTE, lm_ptep, iee_ptep, order, use_block_pmd); ++#else ++ int i; ++ if(use_block_pmd) ++ { ++ pmd_t pmd = __pmd(pte_val(READ_ONCE(*lm_ptep))); ++ pmd = __pmd((pmd_val(pmd) | PMD_SECT_RDONLY) & ~PTE_DBM); ++ WRITE_ONCE(*lm_ptep, __pte(pmd_val(pmd))); ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*iee_ptep); ++ #ifdef CONFIG_KOI ++ pte = __pte(pte_val(pte) | PTE_VALID | PTE_NG); ++ #else ++ pte = __pte(pte_val(pte) | PTE_VALID); ++ #endif ++ WRITE_ONCE(*iee_ptep, pte); ++ iee_ptep++; ++ } ++ } ++ else ++ { ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*lm_ptep); ++ pte = __pte((pte_val(pte) | PTE_RDONLY) & ~PTE_DBM); ++ #ifdef CONFIG_KOI ++ if (pte_valid(pte)) ++ pte = __pte(pte_val(pte) | PTE_NG); ++ #endif ++ WRITE_ONCE(*lm_ptep, pte); ++ pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) | PTE_VALID); ++ #ifdef CONFIG_KOI ++ if (pte_valid(pte)) ++ pte = __pte(pte_val(pte) | PTE_NG); ++ #endif ++ WRITE_ONCE(*iee_ptep, pte); ++ lm_ptep++; ++ iee_ptep++; ++ } ++ } ++#endif ++ dsb(ishst); ++ isb(); +} + -+void __iee_code iee_wrapper_set_cred_jit_keyring(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ unsigned long jit_keyring = va_arg(args, unsigned long); -+ _iee_set_cred_jit_keyring(cred, (unsigned char)jit_keyring); -+} -+ -+void __iee_code iee_wrapper_set_cred_session_keyring(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ struct key *session_keyring = va_arg(args, struct key *); -+ _iee_set_cred_session_keyring(cred, session_keyring); -+} -+ -+void __iee_code iee_wrapper_set_cred_process_keyring(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ struct key *process_keyring = va_arg(args, struct key *); -+ _iee_set_cred_process_keyring(cred, process_keyring); -+} -+ -+void __iee_code iee_wrapper_set_cred_thread_keyring(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ struct key *thread_keyring = va_arg(args, struct key *); -+ _iee_set_cred_thread_keyring(cred, thread_keyring); -+} -+ -+void __iee_code iee_wrapper_set_cred_request_key_auth(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ struct key *request_key_auth = va_arg(args, struct key *); -+ _iee_set_cred_request_key_auth(cred, request_key_auth); -+} -+ -+void __iee_code iee_wrapper_set_cred_non_rcu(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ int non_rcu = va_arg(args, int); -+ _iee_set_cred_non_rcu(cred, non_rcu); -+} -+ -+void __iee_code iee_wrapper_set_cred_atomic_set_usage(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ int i = va_arg(args, int); -+ _iee_set_cred_atomic_set_usage(cred, i); -+} -+ -+u64 __iee_code iee_wrapper_set_cred_atomic_op_usage(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ int flag = va_arg(args, int); -+ int nr = va_arg(args, int); -+ return (u64)_iee_set_cred_atomic_op_usage(cred, flag, nr); -+} -+ -+void __iee_code iee_wrapper_set_cred_security(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ void *security = va_arg(args, void *); -+ _iee_set_cred_security(cred, security); -+} -+ -+void __iee_code iee_wrapper_set_cred_rcu(va_list args) { -+ struct cred *cred = va_arg(args, struct cred *); -+ struct rcu_head *rcu = va_arg(args, struct rcu_head *); -+ _iee_set_cred_rcu(cred, rcu); -+} -+ -+void __iee_code iee_wrapper_memset(va_list args) { -+ void *ptr = va_arg(args, void *); -+ int data = va_arg(args, int); -+ size_t n = va_arg(args, size_t); -+ _iee_memset(ptr, data, n); -+} -+ -+void __iee_code iee_wrapper_set_track(va_list args) { -+ struct track *ptr = va_arg(args, struct track *); -+ struct track *data = va_arg(args, struct track *); -+ _iee_set_track(ptr, data); -+} -+ -+void __iee_code iee_wrapper_set_freeptr(va_list args) { -+ freeptr_t *pptr = va_arg(args, freeptr_t *); -+ freeptr_t ptr = va_arg(args, freeptr_t); -+ _iee_set_freeptr(pptr, ptr); -+} -+ -+void __iee_code iee_wrapper_set_pte_upage(va_list args) { -+ pte_t *ptep = va_arg(args, pte_t *); -+ pte_t pte = va_arg(args, pte_t); -+ _iee_set_pte_upage(ptep, pte); ++inline void iee_unset_sensitive_pte(pte_t *lm_ptep, pte_t *iee_ptep, int order, int use_block_pmd) ++{ ++#ifdef CONFIG_PTP ++ iee_rw_gate(IEE_UNSET_SENSITIVE_PTE, lm_ptep, iee_ptep, order, use_block_pmd); ++#else ++ int i; ++ if(use_block_pmd) ++ { ++ pmd_t pmd = __pmd(pte_val(READ_ONCE(*lm_ptep))); ++ pmd = __pmd(pmd_val(pmd) | PTE_DBM); ++ WRITE_ONCE(*lm_ptep, __pte(pmd_val(pmd))); ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) & ~PTE_VALID); ++ WRITE_ONCE(*iee_ptep, pte); ++ iee_ptep++; ++ } ++ } ++ else ++ { ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*lm_ptep); ++ pte = __pte(pte_val(pte) | PTE_DBM); ++ WRITE_ONCE(*lm_ptep, pte); ++ pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) & ~PTE_VALID); ++ WRITE_ONCE(*iee_ptep, pte); ++ lm_ptep++; ++ iee_ptep++; ++ } ++ } ++#endif ++ dsb(ishst); ++ isb(); +} ++#endif //#ifdef CONFIG_IEE +diff --git a/arch/arm64/kernel/iee/iee-selinuxp.c b/arch/arm64/kernel/iee/iee-selinuxp.c +new file mode 100644 +index 000000000000..394f99f3f574 +--- /dev/null ++++ b/arch/arm64/kernel/iee/iee-selinuxp.c +@@ -0,0 +1,36 @@ ++#include + -+void __iee_code iee_wrapper_set_pte_ppage(va_list args) { -+ pte_t *ptep = va_arg(args, pte_t *); -+ pte_t pte = va_arg(args, pte_t); -+ _iee_set_pte_ppage(ptep, pte); -+} ++extern unsigned long long iee_rw_gate(int flag, ...); + -+void __iee_code iee_wrapper_set_token_mm(va_list args) { -+ struct task_struct *tsk = va_arg(args, struct task_struct *); -+ struct mm_struct *mm = va_arg(args, struct mm_struct *); -+ _iee_set_token_mm(tsk, mm); ++#ifdef CONFIG_IEE_SELINUX_P ++inline void iee_set_selinux_status_pg(struct page* new_page) ++{ ++ iee_rw_gate(IEE_SEL_SET_STATUS_PG, new_page); +} + -+void __iee_code iee_wrapper_set_token_pgd(va_list args) { -+ struct task_struct *tsk = va_arg(args, struct task_struct *); -+ pgd_t *pgd = va_arg(args, pgd_t *); -+ _iee_set_token_pgd(tsk, pgd); ++inline void enforcing_set(bool value) ++{ ++ iee_rw_gate(IEE_SEL_SET_ENFORCING, value); +} + -+void __iee_code iee_wrapper_init_token(va_list args) { -+ struct task_struct *tsk = va_arg(args, struct task_struct *); -+ void *kernel_stack = va_arg(args, void *); -+ void *iee_stack = va_arg(args, void *); -+ _iee_init_token(tsk, kernel_stack, iee_stack); ++inline void selinux_mark_initialized(void) ++{ ++ iee_rw_gate(IEE_SEL_SET_INITIALIZED); +} + -+void __iee_code iee_wrapper_free_token(va_list args) { -+ struct task_struct *tsk = va_arg(args, struct task_struct *); -+ _iee_free_token(tsk); ++inline void iee_set_sel_policy_cap(unsigned int idx, int cap) ++{ ++ iee_rw_gate(IEE_SEL_SET_POLICY_CAP, idx, cap); +} + -+u64 __iee_code iee_wrapper_read_token_stack(va_list args) { -+ struct task_struct *tsk = va_arg(args, struct task_struct *); -+ return (u64)_iee_read_token_stack(tsk); ++/* ++ * Please make sure param iee_new_policy is from policy_jar memcache. ++ * Need to free new_policy after calling this func as it's only used to ++ * trans data from kernel. ++ */ ++inline void iee_sel_rcu_assign_policy(struct selinux_policy* new_policy, ++ struct selinux_policy* iee_new_policy) ++{ ++ iee_rw_gate(IEE_SEL_RCU_ASSIGN_POLICY, new_policy, iee_new_policy); +} ++#endif +diff --git a/arch/arm64/kernel/iee/iee.c b/arch/arm64/kernel/iee/iee.c +new file mode 100644 +index 000000000000..2c7882d4f5be +--- /dev/null ++++ b/arch/arm64/kernel/iee/iee.c +@@ -0,0 +1,1734 @@ ++#include "linux/sched.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+void __iee_code iee_wrapper_write_entry_task(va_list args) { -+ struct task_struct *tsk = va_arg(args, struct task_struct *); -+ _iee_write_entry_task(tsk); -+} ++#define is_cow_mapping(flags) (((flags) & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE) + ++#ifdef CONFIG_IEE ++extern struct cred init_cred; ++extern s64 memstart_addr; ++extern unsigned long highest_memmap_pfn; ++ ++struct watch_list; ++ ++void __iee_code _iee_set_swapper_pgd(unsigned long iee_offset, pgd_t *pgdp, pgd_t pgd); ++void __iee_code _iee_set_tramp_pgd(unsigned long iee_offset, pgd_t *pgdp, pgd_t pgd); ++void __iee_code _iee_set_pte(unsigned long iee_offset, pte_t *ptep, pte_t pte); ++void __iee_code _iee_set_pmd(unsigned long iee_offset, pmd_t *pmdp, pmd_t pmd); ++void __iee_code _iee_set_pud(unsigned long iee_offset, pud_t *pudp, pud_t pud); ++void __iee_code _iee_set_p4d(unsigned long iee_offset, p4d_t *p4dp, p4d_t p4d); ++void __iee_code _iee_set_bm_pte(unsigned long iee_offset, pte_t *ptep, pte_t pte); ++void __iee_code _iee_write_in_byte(unsigned long iee_offset, void *ptr, __u64 data, int length); ++void __iee_code _iee_set_cred_uid(unsigned long iee_offset, struct cred *cred, kuid_t uid); ++void __iee_code _iee_set_cred_gid(unsigned long iee_offset, struct cred *cred, kgid_t gid); ++void __iee_code _iee_copy_cred(unsigned long iee_offset, struct cred *old, struct cred *new); ++void __iee_code _iee_set_cred_suid(unsigned long iee_offset, struct cred *cred, kuid_t suid); ++void __iee_code _iee_set_cred_sgid(unsigned long iee_offset, struct cred *cred, kgid_t sgid); ++void __iee_code _iee_set_cred_euid(unsigned long iee_offset, struct cred *cred, kuid_t euid); ++void __iee_code _iee_set_cred_egid(unsigned long iee_offset, struct cred *cred, kgid_t egid); ++void __iee_code _iee_set_cred_fsuid(unsigned long iee_offset, struct cred *cred, kuid_t fsuid); ++void __iee_code _iee_set_cred_fsgid(unsigned long iee_offset, struct cred *cred, kgid_t fsgid); ++void __iee_code _iee_set_cred_user(unsigned long iee_offset, struct cred *cred, struct user_struct *user); ++void __iee_code _iee_set_cred_user_ns(unsigned long iee_offset, struct cred *cred, struct user_namespace *user_ns); ++void __iee_code _iee_set_cred_group_info(unsigned long iee_offset, struct cred *cred, struct group_info *group_info); ++void __iee_code _iee_set_cred_securebits(unsigned long iee_offset, struct cred *cred, unsigned securebits); ++void __iee_code _iee_set_cred_cap_inheritable(unsigned long iee_offset, struct cred *cred, kernel_cap_t cap_inheritable); ++void __iee_code _iee_set_cred_cap_permitted(unsigned long iee_offset, struct cred *cred, kernel_cap_t cap_permitted); ++void __iee_code _iee_set_cred_cap_effective(unsigned long iee_offset, struct cred *cred, kernel_cap_t cap_effective); ++void __iee_code _iee_set_cred_cap_bset(unsigned long iee_offset, struct cred *cred, kernel_cap_t cap_bset); ++void __iee_code _iee_set_cred_cap_ambient(unsigned long iee_offset, struct cred *cred, kernel_cap_t cap_ambient); ++void __iee_code _iee_set_cred_jit_keyring(unsigned long iee_offset, struct cred *cred, unsigned char jit_keyring); ++void __iee_code _iee_set_cred_session_keyring(unsigned long iee_offset, struct cred *cred, struct key *session_keyring); ++void __iee_code _iee_set_cred_process_keyring(unsigned long iee_offset, struct cred *cred, struct key *process_keyring); ++void __iee_code _iee_set_cred_thread_keyring(unsigned long iee_offset, struct cred *cred, struct key *thread_keyring); ++void __iee_code _iee_set_cred_request_key_auth(unsigned long iee_offset, struct cred *cred, struct key *request_key_auth); ++void __iee_code _iee_set_cred_non_rcu(unsigned long iee_offset, struct cred *cred, int non_rcu); ++void __iee_code _iee_set_cred_atomic_set_usage(unsigned long iee_offset, struct cred *cred, int i); ++bool __iee_code _iee_set_cred_atomic_op_usage(unsigned long iee_offset, struct cred *cred, int flag, int nr); ++void __iee_code _iee_set_cred_security(unsigned long iee_offset, struct cred *cred, void *security); ++void __iee_code _iee_set_cred_rcu(unsigned long iee_offset, struct cred *cred, struct rcu_head *rcu); ++void __iee_code _iee_memset(unsigned long iee_offset, void *ptr, int data, size_t n); ++void __iee_code _iee_set_track(unsigned long iee_offset, struct track *ptr, struct track *data); ++void __iee_code _iee_set_freeptr(unsigned long iee_offset, void **pptr, void *ptr); ++void __iee_code _iee_set_stack_pte(unsigned long iee_offset, pte_t *ptep, int order, int use_block_pmd, unsigned long lm_addr); ++void __iee_code _iee_unset_stack_pte(unsigned long iee_offset, pte_t *ptep, int order, int use_block_pmd, unsigned long lm_addr); ++void __iee_code _iee_set_token_pgd(unsigned long iee_offset, struct task_struct *tsk, pgd_t *pgd); ++void __iee_code _iee_init_token(unsigned long iee_offset, struct task_struct *tsk, void *iee_stack, void *tmp_page); ++void __iee_code _iee_invalidate_token(unsigned long iee_offset, struct task_struct *tsk); ++void __iee_code _iee_validate_token(unsigned long iee_offset, struct task_struct *tsk); ++void __iee_code _iee_set_sensitive_pte(unsigned long iee_offset, pte_t *lm_ptep, pte_t *iee_ptep, int order, int use_block_pmd); ++void __iee_code _iee_unset_sensitive_pte(unsigned long iee_offset, pte_t *lm_ptep, pte_t *iee_ptep, int order, int use_block_pmd); ++void __iee_code _iee_set_token(unsigned long iee_offset, pte_t *ptep, void *new, unsigned long order, int use_block_pmd); ++void __iee_code _iee_unset_token(unsigned long iee_offset, pte_t *ptep, void *token_addr, void *token_page, unsigned long order); ++void __iee_code _iee_copy_pte_range(unsigned long iee_offset, pte_t *new_dst, pte_t *old_dst, pte_t *src_pte, struct vm_area_struct *src_vma, unsigned long dst_vm_flags, pte_t *end_pte); ++void __iee_code _iee_split_huge_pmd(unsigned long iee_offset, pmd_t *pmdp, pte_t *pgtable); ++void __iee_code _iee_set_cred_ucounts(unsigned long iee_offset, struct cred *cred, struct ucounts *ucounts); ++void __iee_code _iee_set_key_union(unsigned long iee_offset, struct key *key, struct key_union *key_union); ++void __iee_code _iee_set_key_struct(unsigned long iee_offset, struct key *key, struct key_struct *key_struct); ++void __iee_code _iee_set_key_payload(unsigned long iee_offset, struct key *key, union key_payload *key_payload); ++void __iee_code _iee_write_key_payload(unsigned long iee_offset, struct key *key, union key_payload payload); ++void __iee_code _iee_memcpy(unsigned long iee_offset, void *dst, void *src, size_t n); ++void __iee_code _iee_write_key_payload_rcu_data0(unsigned long iee_offset, struct key *key, void *rcu_data0); ++bool __iee_code _iee_set_key_usage(unsigned long iee_offset, struct key *key, int n, int flag); ++void __iee_code _iee_set_key_serial(unsigned long iee_offset, struct key *key, key_serial_t serial); ++void __iee_code _iee_set_key_watchers(unsigned long iee_offset, struct key *key, struct watch_list *watchers); ++void __iee_code _iee_set_key_user(unsigned long iee_offset, struct key *key, struct key_user *user); ++void __iee_code _iee_set_key_security(unsigned long iee_offset, struct key *key, void *security); ++void __iee_code _iee_set_key_expiry(unsigned long iee_offset, struct key *key, time64_t expiry); ++void __iee_code _iee_set_key_revoked_at(unsigned long iee_offset, struct key *key, time64_t revoked_at); ++void __iee_code _iee_set_key_last_used_at(unsigned long iee_offset, struct key *key, time64_t last_used_at); ++void __iee_code _iee_set_key_uid(unsigned long iee_offset, struct key *key, kuid_t uid); ++void __iee_code _iee_set_key_gid(unsigned long iee_offset, struct key *key, kgid_t gid); ++void __iee_code _iee_set_key_perm(unsigned long iee_offset, struct key *key, key_perm_t perm); ++void __iee_code _iee_set_key_quotalen(unsigned long iee_offset, struct key *key, unsigned short quotalen); ++void __iee_code _iee_set_key_datalen(unsigned long iee_offset, struct key *key, unsigned short datalen); ++void __iee_code _iee_set_key_state(unsigned long iee_offset, struct key *key, short state); ++void __iee_code _iee_set_key_magic(unsigned long iee_offset, struct key *key, unsigned magic); ++void __iee_code _iee_set_key_flags(unsigned long iee_offset, struct key *key, unsigned long flags); ++void __iee_code _iee_set_key_index_key(unsigned long iee_offset, struct key *key, struct keyring_index_key index_key); ++void __iee_code _iee_set_key_hash(unsigned long iee_offset, struct key *key, unsigned long hash); ++void __iee_code _iee_set_key_len_desc(unsigned long iee_offset, struct key *key, unsigned long len_desc); ++void __iee_code _iee_set_key_type(unsigned long iee_offset, struct key *key, struct key_type *type); ++void __iee_code _iee_set_key_domain_tag(unsigned long iee_offset, struct key *key, struct key_tag *domain_tag); ++void __iee_code _iee_set_key_description(unsigned long iee_offset, struct key *key, char *description); ++void __iee_code _iee_set_key_restrict_link(unsigned long iee_offset, struct key *key, struct key_restriction *restrict_link); ++bool __iee_code _iee_set_key_flag_bit(unsigned long iee_offset, struct key *key, long nr, int flag); +#ifdef CONFIG_KOI -+u64 __iee_code iee_wrapper_read_koi_stack(va_list args) { -+ struct task_struct *tsk = va_arg(args, struct task_struct *); -+ return (u64)_iee_read_koi_stack(tsk); -+} -+ -+void __iee_code iee_wrapper_write_koi_stack(va_list args) { -+ struct task_struct *tsk = va_arg(args, struct task_struct *); -+ unsigned long koi_stack = va_arg(args, unsigned long); -+ _iee_write_koi_stack(tsk, koi_stack); -+} -+ -+u64 __iee_code iee_wrapper_read_token_ttbr1(va_list args) { -+ struct task_struct *tsk = va_arg(args, struct task_struct *); -+ return (u64)_iee_read_token_ttbr1(tsk); -+} -+ -+void __iee_code iee_wrapper_write_token_ttbr1(va_list args) { -+ struct task_struct *tsk = va_arg(args, struct task_struct *); -+ unsigned long current_ttbr1 = va_arg(args, unsigned long); -+ _iee_write_token_ttbr1(tsk, current_ttbr1); -+} -+ -+u64 __iee_code iee_wrapper_read_koi_kernel_stack(va_list args) { -+ struct task_struct *tsk = va_arg(args, struct task_struct *); -+ return (u64)_iee_read_koi_kernel_stack(tsk); -+} ++unsigned long __iee_code _iee_read_koi_stack(unsigned long iee_offset, struct task_struct *tsk); ++void __iee_code _iee_write_koi_stack(unsigned long iee_offset, struct task_struct *tsk, unsigned long koi_stack); ++unsigned long __iee_code _iee_read_token_ttbr1(unsigned long iee_offset, struct task_struct *tsk); ++void __iee_code _iee_write_token_ttbr1(unsigned long iee_offset, struct task_struct *tsk, unsigned long current_ttbr1); ++unsigned long __iee_code _iee_read_koi_kernel_stack(unsigned long iee_offset, struct task_struct *tsk); ++void __iee_code _iee_write_koi_kernel_stack(unsigned long iee_offset, struct task_struct *tsk, unsigned long kernel_stack); ++unsigned long __iee_code _iee_read_koi_stack_base(unsigned long iee_offset, struct task_struct *tsk); ++void __iee_code _iee_write_koi_stack_base(unsigned long iee_offset, struct task_struct *tsk, unsigned long koi_stack_base); ++void __iee_code _iee_set_koi_pgd(unsigned long iee_offset, unsigned long koi_pgd_addr); ++#endif + -+void __iee_code iee_wrapper_write_koi_kernel_stack(va_list args) { -+ struct task_struct *tsk = va_arg(args, struct task_struct *); -+ unsigned long kernel_stack = va_arg(args, unsigned long); -+ _iee_write_koi_kernel_stack(tsk, kernel_stack); -+} ++#ifdef CONFIG_IEE_SELINUX_P ++#include ++void __iee_code _iee_set_selinux_status_pg(unsigned long iee_offset, struct page* new_page); ++void __iee_code _iee_set_selinux_enforcing(unsigned long iee_offset, bool value); ++void __iee_code _iee_mark_selinux_initialized(unsigned long iee_offset); ++void __iee_code _iee_set_sel_policy_cap(unsigned long iee_offset, unsigned int idx, int cap); ++void __iee_code _iee_sel_rcu_assign_policy(unsigned long iee_offset, ++ struct selinux_policy* new_policy, struct selinux_policy* iee_new_policy); ++#endif + -+u64 __iee_code iee_wrapper_read_koi_stack_base(va_list args) { -+ struct task_struct *tsk = va_arg(args, struct task_struct *); -+ return (u64)_iee_read_koi_stack_base(tsk); -+} ++static void inline _iee_set_pte_single(pte_t *ptep, pte_t pte, unsigned long iee_offset); ++static pteval_t inline _iee_set_cmpxchg_relaxed(pte_t *ptep, pteval_t old_pteval, pteval_t new_pteval, unsigned long iee_offset); + -+void __iee_code iee_wrapper_write_koi_stack_base(va_list args) { -+ struct task_struct *tsk = va_arg(args, struct task_struct *); -+ unsigned long koi_stack_base = va_arg(args, unsigned long); -+ _iee_write_koi_stack_base(tsk, koi_stack_base); -+} -+#endif +// Define the function pointer type for wrapper functions. +// Each function pointer conforms to a standardized calling convention +// using a variable argument list (va_list) as its parameter. +// This allows dynamic invocation of different functions with various arguments. -+typedef void (*iee_wrapper_func)(va_list args); -+iee_wrapper_func iee_wrappers[] = { -+ iee_wrapper_write_in_byte, -+ iee_wrapper_set_pte, -+ iee_wrapper_set_pmd, -+ iee_wrapper_set_pud, -+ iee_wrapper_set_p4d, -+ iee_wrapper_set_bm_pte, -+ iee_wrapper_set_swapper_pgd, -+ iee_wrapper_set_tramp_pgd, -+ (iee_wrapper_func)iee_wrapper_set_cmpxchg, -+ (iee_wrapper_func)iee_wrapper_set_xchg, -+ iee_wrapper_copy_cred, -+ iee_wrapper_set_cred_uid, -+ iee_wrapper_set_cred_gid, -+ iee_wrapper_set_cred_suid, -+ iee_wrapper_set_cred_sgid, -+ iee_wrapper_set_cred_euid, -+ iee_wrapper_set_cred_egid, -+ iee_wrapper_set_cred_fsuid, -+ iee_wrapper_set_cred_fsgid, -+ iee_wrapper_set_cred_user, -+ iee_wrapper_set_cred_user_ns, -+ iee_wrapper_set_cred_group_info, -+ iee_wrapper_set_cred_securebits, -+ iee_wrapper_set_cred_cap_inheritable, -+ iee_wrapper_set_cred_cap_permitted, -+ iee_wrapper_set_cred_cap_effective, -+ iee_wrapper_set_cred_cap_bset, -+ iee_wrapper_set_cred_cap_ambient, -+ iee_wrapper_set_cred_jit_keyring, -+ iee_wrapper_set_cred_session_keyring, -+ iee_wrapper_set_cred_process_keyring, -+ iee_wrapper_set_cred_thread_keyring, -+ iee_wrapper_set_cred_request_key_auth, -+ iee_wrapper_set_cred_non_rcu, -+ iee_wrapper_set_cred_atomic_set_usage, -+ (iee_wrapper_func)iee_wrapper_set_cred_atomic_op_usage, -+ iee_wrapper_set_cred_security, -+ iee_wrapper_set_cred_rcu, -+ iee_wrapper_memset, -+ iee_wrapper_set_track, -+ iee_wrapper_set_freeptr, -+ iee_wrapper_set_pte_upage, -+ iee_wrapper_set_pte_ppage, -+ iee_wrapper_set_token_mm, -+ iee_wrapper_set_token_pgd, -+ iee_wrapper_init_token, -+ iee_wrapper_free_token, -+ (iee_wrapper_func)iee_wrapper_read_token_stack, -+ iee_wrapper_write_entry_task, -+ iee_wrapper_set_cred_ucounts, ++typedef void (*iee_func)(void); ++iee_func iee_funcs[] = { ++ (iee_func)_iee_write_in_byte, ++ (iee_func)_iee_set_pte, ++ (iee_func)_iee_set_pmd, ++ (iee_func)_iee_set_pud, ++ (iee_func)_iee_set_p4d, ++ (iee_func)_iee_set_bm_pte, ++ (iee_func)_iee_set_swapper_pgd, ++ (iee_func)_iee_set_tramp_pgd, ++ (iee_func)_iee_memset, ++ (iee_func)_iee_set_track, ++ (iee_func)_iee_set_freeptr, ++ (iee_func)_iee_set_stack_pte, ++ (iee_func)_iee_unset_stack_pte, ++ (iee_func)_iee_set_token_pgd, ++ (iee_func)_iee_init_token, ++ (iee_func)_iee_invalidate_token, ++ (iee_func)_iee_set_sensitive_pte, ++ (iee_func)_iee_unset_sensitive_pte, ++ (iee_func)_iee_set_token, ++ (iee_func)_iee_unset_token, ++ (iee_func)_iee_copy_pte_range, ++ (iee_func)_iee_split_huge_pmd, ++ (iee_func)_iee_validate_token, ++ (iee_func)_iee_memcpy, +#ifdef CONFIG_KOI -+ (iee_wrapper_func)iee_wrapper_read_koi_stack, -+ iee_wrapper_write_koi_stack, -+ (iee_wrapper_func)iee_wrapper_read_token_ttbr1, -+ iee_wrapper_write_token_ttbr1, -+ (iee_wrapper_func)iee_wrapper_read_koi_kernel_stack, -+ iee_wrapper_write_koi_kernel_stack, -+ (iee_wrapper_func)iee_wrapper_read_koi_stack_base, -+ iee_wrapper_write_koi_stack_base ++ (iee_func)_iee_read_koi_stack, ++ (iee_func)_iee_write_koi_stack, ++ (iee_func)_iee_read_token_ttbr1, ++ (iee_func)_iee_write_token_ttbr1, ++ (iee_func)_iee_read_koi_kernel_stack, ++ (iee_func)_iee_write_koi_kernel_stack, ++ (iee_func)_iee_read_koi_stack_base, ++ (iee_func)_iee_write_koi_stack_base, ++ (iee_func)_iee_set_koi_pgd, +#endif -+}; -+ -+u64 __iee_code iee_dispatch(int flag, ...){ -+ va_list pArgs; -+ -+ va_start(pArgs, flag); -+ -+ switch(flag) -+ { -+ case IEE_OP_SET_CMPXCHG: -+ { -+ pteval_t ret = iee_wrapper_set_cmpxchg(pArgs); -+ va_end(pArgs); -+ return (u64)ret; -+ } -+ case IEE_OP_SET_XCHG: -+ { -+ pteval_t ret = iee_wrapper_set_xchg(pArgs); -+ va_end(pArgs); -+ return (u64)ret; -+ } -+ case IEE_OP_SET_CRED_ATOP_USAGE: -+ { -+ u64 ret = iee_wrapper_set_cred_atomic_op_usage(pArgs); -+ va_end(pArgs); -+ return ret; -+ } -+ case IEE_READ_TOKEN_STACK: -+ { -+ u64 ret = iee_wrapper_read_token_stack(pArgs); -+ va_end(pArgs); -+ return ret; -+ } -+#ifdef CONFIG_KOI -+ case IEE_READ_KOI_STACK: -+ { -+ u64 ret = iee_wrapper_read_koi_stack(pArgs); -+ va_end(pArgs); -+ return ret; -+ } -+ case IEE_READ_TOKEN_TTBR1: -+ { -+ u64 ret = iee_wrapper_read_token_ttbr1(pArgs); -+ va_end(pArgs); -+ return ret; -+ } -+ case IEE_READ_KOI_KERNEL_STACK: -+ { -+ u64 ret = iee_wrapper_read_koi_kernel_stack(pArgs); -+ va_end(pArgs); -+ return ret; -+ } -+ case IEE_READ_KOI_STACK_BASE: -+ { -+ u64 ret = iee_wrapper_read_koi_stack_base(pArgs); -+ va_end(pArgs); -+ return ret; -+ } ++#ifdef CONFIG_CREDP ++ (iee_func)_iee_copy_cred, ++ (iee_func)_iee_set_cred_uid, ++ (iee_func)_iee_set_cred_gid, ++ (iee_func)_iee_set_cred_suid, ++ (iee_func)_iee_set_cred_sgid, ++ (iee_func)_iee_set_cred_euid, ++ (iee_func)_iee_set_cred_egid, ++ (iee_func)_iee_set_cred_fsuid, ++ (iee_func)_iee_set_cred_fsgid, ++ (iee_func)_iee_set_cred_user, ++ (iee_func)_iee_set_cred_user_ns, ++ (iee_func)_iee_set_cred_group_info, ++ (iee_func)_iee_set_cred_securebits, ++ (iee_func)_iee_set_cred_cap_inheritable, ++ (iee_func)_iee_set_cred_cap_permitted, ++ (iee_func)_iee_set_cred_cap_effective, ++ (iee_func)_iee_set_cred_cap_bset, ++ (iee_func)_iee_set_cred_cap_ambient, ++ (iee_func)_iee_set_cred_jit_keyring, ++ (iee_func)_iee_set_cred_session_keyring, ++ (iee_func)_iee_set_cred_process_keyring, ++ (iee_func)_iee_set_cred_thread_keyring, ++ (iee_func)_iee_set_cred_request_key_auth, ++ (iee_func)_iee_set_cred_non_rcu, ++ (iee_func)_iee_set_cred_atomic_set_usage, ++ (iee_func)_iee_set_cred_atomic_op_usage, ++ (iee_func)_iee_set_cred_security, ++ (iee_func)_iee_set_cred_rcu, ++ (iee_func)_iee_set_cred_ucounts, +#endif -+ default: -+ { -+ #ifndef CONFIG_KOI -+ if((flag < IEE_WRITE_IN_BYTE) | (flag > IEE_OP_SET_CRED_UCOUNTS)) -+ panic("Invalid iee flag.\n"); -+ #else -+ if((flag < IEE_WRITE_IN_BYTE) | (flag > IEE_WRITE_KOI_STACK_BASE)) -+ panic("Invalid iee flag.\n"); -+ #endif -+ iee_wrappers[flag](pArgs); -+ break; -+ } -+ } -+ -+ va_end(pArgs); -+ return 0; -+} ++#ifdef CONFIG_KEYP ++ (iee_func)_iee_set_key_union, ++ (iee_func)_iee_set_key_struct, ++ (iee_func)_iee_set_key_payload, ++ (iee_func)_iee_write_key_payload, ++ (iee_func)_iee_write_key_payload_rcu_data0, ++ (iee_func)_iee_set_key_usage, ++ (iee_func)_iee_set_key_serial, ++ (iee_func)_iee_set_key_watchers, ++ (iee_func)_iee_set_key_user, ++ (iee_func)_iee_set_key_security, ++ (iee_func)_iee_set_key_expiry, ++ (iee_func)_iee_set_key_revoked_at, ++ (iee_func)_iee_set_key_last_used_at, ++ (iee_func)_iee_set_key_uid, ++ (iee_func)_iee_set_key_gid, ++ (iee_func)_iee_set_key_perm, ++ (iee_func)_iee_set_key_quotalen, ++ (iee_func)_iee_set_key_datalen, ++ (iee_func)_iee_set_key_state, ++ (iee_func)_iee_set_key_magic, ++ (iee_func)_iee_set_key_flags, ++ (iee_func)_iee_set_key_index_key, ++ (iee_func)_iee_set_key_hash, ++ (iee_func)_iee_set_key_len_desc, ++ (iee_func)_iee_set_key_type, ++ (iee_func)_iee_set_key_domain_tag, ++ (iee_func)_iee_set_key_description, ++ (iee_func)_iee_set_key_restrict_link, ++ (iee_func)_iee_set_key_flag_bit, ++#endif ++#ifdef CONFIG_IEE_SELINUX_P ++ (iee_func)_iee_set_selinux_status_pg, ++ (iee_func)_iee_set_selinux_enforcing, ++ (iee_func)_iee_mark_selinux_initialized, ++ (iee_func)_iee_set_sel_policy_cap, ++ (iee_func)_iee_sel_rcu_assign_policy, ++#endif ++ NULL ++}; + +#ifdef CONFIG_KOI -+unsigned long __iee_code _iee_read_koi_stack(struct task_struct *tsk) ++unsigned long __iee_code _iee_read_koi_stack(unsigned long iee_offset, struct task_struct *tsk) +{ -+ struct task_token *token = (struct task_token *)__phys_to_iee(__pa(tsk)); ++ struct task_token *token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); + return (unsigned long)token->koi_stack; +} + -+void __iee_code _iee_write_koi_stack(struct task_struct *tsk, unsigned long koi_stack) ++void __iee_code _iee_write_koi_stack(unsigned long iee_offset, struct task_struct *tsk, unsigned long koi_stack) +{ -+ struct task_token *token = (struct task_token *)__phys_to_iee(__pa(tsk)); ++ struct task_token *token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); + token->koi_stack = koi_stack; +} + -+unsigned long __iee_code _iee_read_token_ttbr1(struct task_struct *tsk) ++unsigned long __iee_code _iee_read_token_ttbr1(unsigned long iee_offset, struct task_struct *tsk) +{ -+ struct task_token *token = (struct task_token *)__phys_to_iee(__pa(tsk)); ++ struct task_token *token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); + return token->current_ttbr1; +} + -+void __iee_code _iee_write_token_ttbr1(struct task_struct *tsk, unsigned long current_ttbr1) ++void __iee_code _iee_write_token_ttbr1(unsigned long iee_offset, struct task_struct *tsk, unsigned long current_ttbr1) +{ -+ struct task_token *token = (struct task_token *)__phys_to_iee(__pa(tsk)); ++ struct task_token *token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); + token->current_ttbr1 = current_ttbr1; +} + -+unsigned long __iee_code _iee_read_koi_kernel_stack(struct task_struct *tsk) ++unsigned long __iee_code _iee_read_koi_kernel_stack(unsigned long iee_offset, struct task_struct *tsk) +{ -+ struct task_token *token = (struct task_token *)__phys_to_iee(__pa(tsk)); ++ struct task_token *token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); + return token->koi_kernel_stack; +} + -+void __iee_code _iee_write_koi_kernel_stack(struct task_struct *tsk, unsigned long kernel_stack) ++void __iee_code _iee_write_koi_kernel_stack(unsigned long iee_offset, struct task_struct *tsk, unsigned long kernel_stack) +{ -+ struct task_token *token = (struct task_token *)__phys_to_iee(__pa(tsk)); ++ struct task_token *token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); + token->koi_kernel_stack = kernel_stack; +} + -+unsigned long __iee_code _iee_read_koi_stack_base(struct task_struct *tsk) ++unsigned long __iee_code _iee_read_koi_stack_base(unsigned long iee_offset, struct task_struct *tsk) +{ -+ struct task_token *token = (struct task_token *)__phys_to_iee(__pa(tsk)); ++ struct task_token *token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); + return (unsigned long)token->koi_stack_base; +} + -+void __iee_code _iee_write_koi_stack_base(struct task_struct *tsk, unsigned long koi_stack_base) ++void __iee_code _iee_write_koi_stack_base(unsigned long iee_offset, struct task_struct *tsk, unsigned long koi_stack_base) +{ -+ struct task_token *token = (struct task_token *)__phys_to_iee(__pa(tsk)); ++ struct task_token *token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); + token->koi_stack_base = koi_stack_base; +} -+#endif + -+// Protect the __entry_task. -+__attribute__((aligned(PAGE_SIZE))) DECLARE_PER_CPU(struct task_struct *[PAGE_SIZE/sizeof(struct task_struct *)], __entry_task); -+void __iee_code _iee_write_entry_task(struct task_struct *tsk) ++static inline void iee_set_koi_pgd_writeable(unsigned long koi_pgd_addr, unsigned long iee_si_addr) +{ -+ // Add check of tsk. -+ struct task_token *token = (struct task_token *)__phys_to_iee(__pa(tsk)); -+ -+ unsigned long flags; -+ unsigned long res; -+ struct task_struct **entry_addr; -+ local_irq_save(flags); -+ asm volatile("at s1e1r, %0"::"r"(token)); -+ isb(); -+ res = read_sysreg(par_el1); -+ local_irq_restore(flags); -+ -+ // If it is logical map, that means it is not a token. -+ if(__phys_to_iee(res & PTE_ADDR_MASK) == (((unsigned long)token) & PTE_ADDR_MASK)) -+ panic("Trying to forge a token.\n"); -+ -+ if(!token->valid) -+ panic("Trying to write a wrong task into __entry_task.\n"); -+ entry_addr = (struct task_struct **)__phys_to_iee(__pa(SHIFT_PERCPU_PTR(__entry_task,__kern_my_cpu_offset()))); -+ *entry_addr = tsk; ++ pgd_t *pgdir = (pgd_t *)koi_pgd_addr; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, iee_si_addr); ++ p4d_t *p4dp = p4d_offset(pgdp, iee_si_addr); ++ pud_t *pudp = pud_offset(p4dp, iee_si_addr); ++ pmd_t *pmdp = pmd_offset(pudp, iee_si_addr); ++ pte_t *ptep = pte_offset_kernel(pmdp, iee_si_addr); ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(pte_val(pte) | PTE_DBM); ++ WRITE_ONCE(*((pte_t *)(__phys_to_iee(__pa(ptep)))), pte); +} -+ -+unsigned long __iee_code _iee_read_token_stack(struct task_struct *tsk) ++/* ++ * Set IEE SI codes U RWX here to avoid IEE DEP checking fault. ++ * Mark koi pgd in the same time. ++ */ ++void __iee_code _iee_set_koi_pgd(unsigned long iee_offset, unsigned long koi_pgd_addr) +{ -+ struct task_token *token = (struct task_token *)__phys_to_iee(__pa(tsk)); -+ return (unsigned long)token->iee_stack; ++ // IEE SI codes are 2 pages starting at __iee_si_text_start. ++ unsigned long iee_si_addr = (unsigned long)__iee_si_text_start; ++ iee_set_koi_pgd_writeable(koi_pgd_addr, iee_si_addr); ++ iee_si_addr += PAGE_SIZE; ++ iee_set_koi_pgd_writeable(koi_pgd_addr, iee_si_addr); ++ // Use DBM=0, AP[7]=0 to mark this page as a koi pgd in IEE. +} ++#endif + -+void __iee_code _iee_free_token(struct task_struct *tsk) ++#ifdef CONFIG_IEE_SELINUX_P ++void __iee_code _iee_set_selinux_status_pg(unsigned long iee_offset, struct page* new_page) +{ -+ _iee_memset(tsk, 0, sizeof(struct task_token)); ++ struct page** iee_addr = (struct page**)__phys_to_iee(__pa_symbol(&(selinux_state.status_page))); ++ *iee_addr = new_page; +} + -+#ifdef CONFIG_KOI -+extern unsigned long koi_swapper_ttbr1; -+#endif -+void __iee_code _iee_init_token(struct task_struct *tsk, void *kernel_stack, void *iee_stack) ++void __iee_code _iee_set_selinux_enforcing(unsigned long iee_offset, bool value) +{ -+ struct task_token *token = (struct task_token *)__phys_to_iee(__pa(tsk)); -+ token->kernel_stack = kernel_stack; -+ token->iee_stack = iee_stack; -+ token->valid = true; -+#ifdef CONFIG_KOI -+ token->koi_kernel_stack = NULL; -+ token->koi_stack = NULL; -+ token->koi_stack_base = NULL; -+ token->current_ttbr1 = 0; -+#endif ++ *(bool*)__phys_to_iee(__pa_symbol(&(selinux_state.enforcing))) = value; +} + -+void __iee_code _iee_set_token_mm(struct task_struct *tsk, struct mm_struct *mm) ++void __iee_code _iee_mark_selinux_initialized(unsigned long iee_offset) +{ -+ struct task_token *token = (struct task_token *)__phys_to_iee(__pa(tsk)); -+ token->mm = mm; ++ smp_store_release(((bool*)__phys_to_iee(__pa_symbol(&(selinux_state.initialized)))), true); ++ printk("IEE: Mark selinux initialized."); +} + -+void __iee_code _iee_set_token_pgd(struct task_struct *tsk, pgd_t *pgd) ++void __iee_code _iee_set_sel_policy_cap(unsigned long iee_offset, unsigned int idx, int cap) +{ -+ struct task_token *token = (struct task_token *)__phys_to_iee(__pa(tsk)); -+ token->pgd = pgd; ++ *(bool*)__phys_to_iee(__pa_symbol(&(selinux_state.policycap[idx]))) = cap; +} + -+void __iee_code _iee_set_freeptr(freeptr_t *pptr, freeptr_t ptr) ++/* ++ * Please make sure param iee_new_policy is from policy_jar memcache. ++ * Need to free new_policy after calling this func as it's only used to ++ * trans data from kernel. ++ */ ++void __iee_code _iee_sel_rcu_assign_policy(unsigned long iee_offset, struct selinux_policy* new_policy, ++ struct selinux_policy* iee_new_policy) +{ -+ pptr = (freeptr_t *)__phys_to_iee(__pa(pptr)); -+ *pptr = ptr; ++ /* TODO: Verify informations from incoming policy. */ ++ // /* Make sure iee_new_policy is from policy_jar memcache. */ ++ // struct slab* policy_pg = (struct slab*)pfn_to_page(__pa(iee_new_policy) >> PAGE_SHIFT); ++ // if (policy_pg->slab_cache != policy_jar) ++ // printk("IEE SELINUXP ERROR: new policy is not from iee memcache."); ++ /* Copy data from kernel to new allocated policy struct inside iee. */ ++ struct selinux_policy* iee_addr = (struct selinux_policy *)((unsigned long)iee_new_policy + iee_offset); ++ memcpy(iee_addr, new_policy, sizeof(struct selinux_policy)); ++ ++ rcu_assign_pointer(*((struct selinux_policy**)__phys_to_iee(__pa_symbol(&(selinux_state.policy)))), ++ iee_new_policy); ++ printk("IEE: assigned rcu pointer selinux_state.policy."); +} ++#endif + -+#pragma GCC push_options -+#pragma GCC optimize("O0") -+void __iee_code _iee_memset(void *ptr, int data, size_t n) ++bool __iee_code _iee_set_key_flag_bit(unsigned long iee_offset, struct key *key, long nr, int flag) +{ -+ char *_ptr = (char *)__phys_to_iee(__pa(ptr)); -+ -+ while (n--) -+ *_ptr++ = data; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ switch(flag) ++ { ++ case SET_BIT_OP: ++ { ++ set_bit(nr, &key->flags); ++ break; ++ } ++ case TEST_AND_CLEAR_BIT: ++ { ++ return test_and_clear_bit(nr, &key->flags); ++ } ++ case TEST_AND_SET_BIT: ++ { ++ return test_and_set_bit(nr, &key->flags); ++ } ++ } ++ return 0; +} + -+void __iee_code _iee_memcpy(void *dst, void *src, size_t n) ++void __iee_code _iee_set_key_restrict_link(unsigned long iee_offset, struct key *key, struct key_restriction *restrict_link) +{ -+ char *_dst = (char *)__phys_to_iee(__pa(dst)); -+ char *_src = (char *)src; -+ -+ while(n--) -+ *_dst++ = *_src++; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->restrict_link = restrict_link; +} -+#pragma GCC pop_options + -+void __iee_code _iee_set_track(struct track *ptr, struct track *data) ++void __iee_code _iee_set_key_magic(unsigned long iee_offset, struct key *key, unsigned magic) +{ -+ _iee_memcpy(ptr, data, sizeof(struct track)); ++ #ifdef KEY_DEBUGGING ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->magic = magic; ++ #endif +} + -+void __iee_code _iee_set_cred_rcu(struct cred *cred, struct rcu_head *rcu) ++void __iee_code _iee_set_key_flags(unsigned long iee_offset, struct key *key, unsigned long flags) +{ -+ if(cred == &init_cred) -+ cred = (struct cred *)__phys_to_iee(__pa_symbol(cred)); -+ else -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ #ifdef CONFIG_CREDP -+ *((struct rcu_head **)(&(cred->rcu.func))) = rcu; -+ #endif ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->flags = flags; +} + -+void __iee_code _iee_set_cred_security(struct cred *cred, void *security) ++void __iee_code _iee_set_key_index_key(unsigned long iee_offset, struct key *key, struct keyring_index_key index_key) +{ -+ if(cred == &init_cred) -+ cred = (struct cred *)__phys_to_iee(__pa_symbol(cred)); -+ else -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->security = security; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->index_key = index_key; +} + -+bool __iee_code _iee_set_cred_atomic_op_usage(struct cred *cred, int flag, int nr) ++void __iee_code _iee_set_key_hash(unsigned long iee_offset, struct key *key, unsigned long hash) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ switch (flag) -+ { -+ case AT_ADD: { -+ atomic_long_add(nr, &cred->usage); -+ return 0; -+ } -+ case AT_INC_NOT_ZERO: { -+ return atomic_long_inc_not_zero(&cred->usage); -+ } -+ case AT_SUB_AND_TEST: { -+ return atomic_long_sub_and_test(nr, &cred->usage); -+ } -+ } -+ return 0; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->hash = hash; +} + -+void __iee_code _iee_set_cred_atomic_set_usage(struct cred *cred, int i) ++void __iee_code _iee_set_key_len_desc(unsigned long iee_offset, struct key *key, unsigned long len_desc) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ atomic_long_set(&cred->usage,i); ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->len_desc = len_desc; +} + -+void __iee_code _iee_set_cred_non_rcu(struct cred *cred, int non_rcu) ++void __iee_code _iee_set_key_type(unsigned long iee_offset, struct key *key, struct key_type *type) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->non_rcu = non_rcu; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->type = type; +} + -+void __iee_code _iee_set_cred_session_keyring(struct cred *cred, struct key *session_keyring) ++void __iee_code _iee_set_key_domain_tag(unsigned long iee_offset, struct key *key, struct key_tag *domain_tag) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->session_keyring = session_keyring; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->domain_tag = domain_tag; +} + -+void __iee_code _iee_set_cred_process_keyring(struct cred *cred, struct key *process_keyring) ++void __iee_code _iee_set_key_description(unsigned long iee_offset, struct key *key, char *description) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->process_keyring = process_keyring; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->description = description; +} + -+void __iee_code _iee_set_cred_thread_keyring(struct cred *cred, struct key *thread_keyring) ++void __iee_code _iee_set_key_uid(unsigned long iee_offset, struct key *key, kuid_t uid) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->thread_keyring = thread_keyring; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->uid = uid; +} + -+void __iee_code _iee_set_cred_request_key_auth(struct cred *cred, struct key *request_key_auth) ++void __iee_code _iee_set_key_gid(unsigned long iee_offset, struct key *key, kgid_t gid) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->request_key_auth = request_key_auth; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->gid = gid; +} + -+void __iee_code _iee_set_cred_jit_keyring(struct cred *cred, unsigned char jit_keyring) ++void __iee_code _iee_set_key_perm(unsigned long iee_offset, struct key *key, key_perm_t perm) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->jit_keyring = jit_keyring; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->perm = perm; +} + -+void __iee_code _iee_set_cred_cap_inheritable(struct cred *cred, kernel_cap_t cap_inheritable) ++void __iee_code _iee_set_key_quotalen(unsigned long iee_offset, struct key *key, unsigned short quotalen) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->cap_inheritable = cap_inheritable; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->quotalen = quotalen; +} + -+void __iee_code _iee_set_cred_cap_permitted(struct cred *cred, kernel_cap_t cap_permitted) ++void __iee_code _iee_set_key_datalen(unsigned long iee_offset, struct key *key, unsigned short datalen) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->cap_permitted = cap_permitted; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->datalen = datalen; +} + -+void __iee_code _iee_set_cred_cap_effective(struct cred *cred, kernel_cap_t cap_effective) ++void __iee_code _iee_set_key_state(unsigned long iee_offset, struct key *key, short state) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->cap_effective = cap_effective; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ WRITE_ONCE(key->state, state); +} + -+void __iee_code _iee_set_cred_cap_bset(struct cred *cred, kernel_cap_t cap_bset) ++void __iee_code _iee_set_key_user(unsigned long iee_offset, struct key *key, struct key_user *user) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->cap_bset = cap_bset; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->user = user; +} + -+void __iee_code _iee_set_cred_cap_ambient(struct cred *cred, kernel_cap_t cap_ambient) ++void __iee_code _iee_set_key_security(unsigned long iee_offset, struct key *key, void *security) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->cap_ambient = cap_ambient; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->security = security; +} + -+void __iee_code _iee_set_cred_securebits(struct cred *cred, unsigned securebits) ++void __iee_code _iee_set_key_expiry(unsigned long iee_offset, struct key *key, time64_t expiry) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->securebits = securebits; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->expiry = expiry; +} + -+void __iee_code _iee_set_cred_group_info(struct cred *cred, struct group_info *group_info) ++void __iee_code _iee_set_key_revoked_at(unsigned long iee_offset, struct key *key, time64_t revoked_at) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->group_info = group_info; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->revoked_at = revoked_at; +} + -+void __iee_code _iee_set_cred_ucounts(struct cred *cred, struct ucounts *ucounts) ++void __iee_code _iee_set_key_last_used_at(unsigned long iee_offset, struct key *key, time64_t last_used_at) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->ucounts = ucounts; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->last_used_at = last_used_at; +} + -+void __iee_code _iee_set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns) ++bool __iee_code _iee_set_key_usage(unsigned long iee_offset, struct key *key, int n, int flag) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->user_ns = user_ns; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ switch(flag) ++ { ++ case REFCOUNT_INC: ++ { ++ refcount_inc(&key->usage); ++ break; ++ } ++ case REFCOUNT_SET: ++ { ++ refcount_set(&key->usage, n); ++ break; ++ } ++ case REFCOUNT_DEC_AND_TEST: ++ { ++ return refcount_dec_and_test(&key->usage); ++ } ++ case REFCOUNT_INC_NOT_ZERO: ++ { ++ return refcount_inc_not_zero(&key->usage); ++ } ++ } ++ return 0; +} + -+void __iee_code _iee_set_cred_user(struct cred *cred, struct user_struct *user) ++void __iee_code _iee_set_key_serial(unsigned long iee_offset, struct key *key, key_serial_t serial) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->user = user; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->serial = serial; +} + -+void __iee_code _iee_set_cred_fsgid(struct cred *cred, kgid_t fsgid) ++void __iee_code _iee_set_key_watchers(unsigned long iee_offset, struct key *key, struct watch_list *watchers) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->fsgid = fsgid; ++ #ifdef CONFIG_KEY_NOTIFICATIONS ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->watchers = watchers; ++ #endif +} + -+void __iee_code _iee_set_cred_fsuid(struct cred *cred, kuid_t fsuid) ++void __iee_code _iee_write_key_payload_rcu_data0(unsigned long iee_offset, struct key *key, void *rcu_data0) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->fsuid = fsuid; ++ union key_payload *key_payload = (union key_payload *)__phys_to_iee(__pa(key->name_link.next)); ++ WRITE_ONCE(key_payload->rcu_data0, rcu_data0); +} + -+void __iee_code _iee_set_cred_egid(struct cred *cred, kgid_t egid) ++void __iee_code _iee_write_key_payload(unsigned long iee_offset, struct key *key, union key_payload payload) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->egid = egid; ++ union key_payload *key_payload = (union key_payload *)__phys_to_iee(__pa(key->name_link.next)); ++ *key_payload = payload; +} + -+void __iee_code _iee_set_cred_euid(struct cred *cred, kuid_t euid) ++void __iee_code _iee_set_key_union(unsigned long iee_offset, struct key *key, struct key_union *key_union) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->euid = euid; -+} -+ -+void __iee_code _iee_set_cred_sgid(struct cred *cred, kgid_t sgid) -+{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->sgid = sgid; -+} -+ -+void __iee_code _iee_set_cred_suid(struct cred *cred, kuid_t suid) -+{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->suid = suid; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->graveyard_link.next = (struct list_head *)key_union; +} + -+void __iee_code _iee_copy_cred(struct cred *old, struct cred *new) ++void __iee_code _iee_set_key_struct(unsigned long iee_offset, struct key *key, struct key_struct *key_struct) +{ -+ #ifdef CONFIG_CREDP -+ struct rcu_head *rcu = (struct rcu_head *)(new->rcu.func); -+ struct cred *_new = (struct cred *)__phys_to_iee(__pa(new)); -+ _iee_memcpy(new,old,sizeof(struct cred)); -+ *(struct rcu_head **)(&(_new->rcu.func)) = rcu; -+ *(struct rcu_head *)(_new->rcu.func) = *(struct rcu_head *)(old->rcu.func); -+ #endif ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->name_link.prev = (struct list_head *)key_struct; +} + -+void __iee_code _iee_set_cred_gid(struct cred *cred, kgid_t gid) ++void __iee_code _iee_set_key_payload(unsigned long iee_offset, struct key *key, union key_payload *key_payload) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->gid = gid; ++ key = (struct key *)((unsigned long)key + iee_offset); ++ key->name_link.next = (struct list_head *)key_payload; +} + -+void __iee_code _iee_set_cred_uid(struct cred *cred, kuid_t uid) ++void __iee_code _iee_split_huge_pmd(unsigned long iee_offset, pmd_t *pmdp, pte_t *pgtable) +{ -+ cred = (struct cred *)__phys_to_iee(__pa(cred)); -+ cred->uid = uid; ++ int i; ++ struct page *page = pmd_page(*pmdp); ++ pte_t *ptep = (pte_t *)((unsigned long)pgtable + (unsigned long)iee_offset); ++ ++ for (i = 0; i < PMD_SIZE / PAGE_SIZE; i++, ptep++) { ++ pte_t entry; ++ pgprot_t pgprot = PAGE_KERNEL; ++ #ifdef CONFIG_KOI ++ pgprot = __pgprot(pgprot_val(pgprot) | PTE_CONT | PTE_NG); ++ #else ++ pgprot = __pgprot(pgprot_val(pgprot) | PTE_CONT); ++ #endif ++ entry = mk_pte(page + i, pgprot); ++ WRITE_ONCE(*ptep, entry); ++ } +} + -+void __iee_code _iee_write_in_byte(void *ptr, __u64 data, int length) ++void __iee_code _iee_copy_pte_range(unsigned long iee_offset, pte_t *new_dst, pte_t *old_dst, pte_t *src_pte, struct vm_area_struct *src_vma, unsigned long dst_vm_flags, pte_t *end_pte) +{ -+ ptr = (void *)__phys_to_iee(__pa(ptr)); -+ switch(length) { -+ case 8: { -+ *(__u64 *)ptr = data; -+ break; -+ } -+ case 4: { -+ *(__u32 *)ptr = (__u32)data; -+ break; ++ pte_t pte, tmp; ++ swp_entry_t entry; ++ tmp = __pte(0); ++ while(src_pte < end_pte) ++ { ++ if (!pte_none(*src_pte) && unlikely(!pte_present(*src_pte))) ++ { ++ pte = *src_pte; ++ entry = pte_to_swp_entry(pte); ++ if (likely(!non_swap_entry(entry))) ++ ; ++ else if(is_migration_entry(entry)) ++ { ++ if (is_readable_migration_entry(entry) && ++ is_cow_mapping(dst_vm_flags)) ++ { ++ entry = make_readable_migration_entry(swp_offset(entry)); ++ pte = swp_entry_to_pte(entry); ++ if (pte_swp_soft_dirty(*src_pte)) ++ pte = pte_swp_mksoft_dirty(pte); ++ if (pte_swp_uffd_wp(*src_pte)) ++ pte = pte_swp_mkuffd_wp(pte); ++ _iee_set_pte_single(src_pte, pte, iee_offset); ++ } ++ } ++ else if (is_device_private_entry(entry)) ++ { ++ if (is_writable_device_private_entry(entry) && ++ is_cow_mapping(dst_vm_flags)) { ++ entry = make_readable_device_private_entry( ++ swp_offset(entry)); ++ pte = swp_entry_to_pte(entry); ++ if (pte_swp_uffd_wp(*src_pte)) ++ pte = pte_swp_mkuffd_wp(pte); ++ _iee_set_pte_single(src_pte, pte, iee_offset); ++ } ++ } + } -+ case 2: { -+ *(__u16 *)ptr = (__u16)data; -+ break; ++ else if(!pte_none(*src_pte) && likely(pte_present(*src_pte))) ++ { ++ struct page *page = NULL; ++ #ifdef CONFIG_ARCH_HAS_PTE_SPECIAL ++ if (likely(!pte_special(*src_pte))) ++ if (unlikely(pte_pfn(*src_pte) > highest_memmap_pfn)) ++ page = NULL; ++ else ++ page = pte_page(*src_pte); ++ #else ++ if((!unlikely(src_vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) || ((src_vma->vm_flags & VM_MIXEDMAP) && pfn_valid(pte_pfn(*src_pte))) || (!(src_vma->vm_flags & VM_MIXEDMAP) && !(pfn == src_vma->vm_pgoff + off) && is_cow_mapping(src_vma->vm_flags))) && !is_zero_pfn(pte_pfn(*src_pte)) && !unlikely(pte_pfn(*src_pte) > highest_memmap_pfn)) ++ page = pte_page(*src_pte); ++ #endif ++ if(!(page && folio_test_anon(page_folio(page))) || likely(!PageAnonExclusive(page) || !(likely(!is_device_private_page(page) && unlikely(folio_needs_cow_for_dma(src_vma, page_folio(page))))))) ++ { ++ if (is_cow_mapping(src_vma->vm_flags) && pte_write(*src_pte)) ++ { ++ pte_t old_pte, new_pte; ++ ++ new_pte = READ_ONCE(*src_pte); ++ do { ++ old_pte = new_pte; ++ new_pte = pte_wrprotect(new_pte); ++ _iee_set_cmpxchg_relaxed(src_pte, pte_val(old_pte), pte_val(new_pte), iee_offset); ++ } while (pte_val(new_pte) != pte_val(old_pte)); ++ } ++ } + } -+ case 1: { -+ *(__u8 *)ptr = (__u8)data; -+ break; ++ if(!pte_none(*new_dst)) ++ { ++ _iee_set_pte_single(old_dst, *new_dst, iee_offset); ++ WRITE_ONCE(*new_dst, __pte(0)); + } ++ old_dst++; ++ src_pte++; ++ new_dst++; + } +} + -+pteval_t __iee_code _iee_set_xchg_relaxed(pte_t *ptep, pteval_t pteval) -+{ -+ pteval_t ret = xchg_relaxed((pteval_t *)(__phys_to_iee(__pa(ptep))), pteval); -+ return ret; -+} -+ -+pteval_t __iee_code _iee_set_cmpxchg_relaxed(pte_t *ptep, pteval_t old_pteval, pteval_t new_pteval) -+{ -+ pteval_t pteval = cmpxchg_relaxed((pteval_t *)(__phys_to_iee(__pa(ptep))), old_pteval, new_pteval); -+ return pteval; -+} -+ -+/* Check if addr is allocated in IEE page */ -+static inline bool check_addr_in_iee_valid(unsigned long addr) -+{ -+ unsigned long flags; -+ unsigned long res; -+ local_irq_save(flags); -+ asm volatile("at s1e1r, %0"::"r"(addr)); -+ isb(); -+ res = read_sysreg(par_el1); -+ local_irq_restore(flags); -+ -+ // If it is not logical map, that means it is a token. -+ if(__phys_to_iee(res & PTE_ADDR_MASK) != addr) -+ return false; -+ -+ return !(res & 0x1); -+} -+ -+void __iee_code _iee_set_tramp_pgd_pre_init(pgd_t *pgdp, pgd_t pgd) ++void __iee_code _iee_set_sensitive_pte(unsigned long iee_offset, pte_t *lm_ptep, pte_t *iee_ptep, int order, int use_block_pmd) +{ -+ WRITE_ONCE(*((pgd_t *)(__phys_to_iee(__pa_symbol(pgdp)))), pgd); -+} ++ int i; + -+void __iee_code _iee_set_swapper_pgd(pgd_t *pgdp, pgd_t pgd) -+{ -+ if(!(pgd_val(pgd) & PMD_SECT_VALID)) ++ lm_ptep = (pte_t *)((unsigned long)lm_ptep + iee_offset); ++ iee_ptep = (pte_t *)((unsigned long)iee_ptep + iee_offset); ++ if(use_block_pmd) + { -+ WRITE_ONCE(*((pgd_t *)(__phys_to_iee(__pa_symbol(pgdp)))), pgd); -+ return; ++ pmd_t pmd = __pmd(pte_val(READ_ONCE(*lm_ptep))); ++ pmd = __pmd((pmd_val(pmd) | PMD_SECT_RDONLY) & ~PTE_DBM); ++ WRITE_ONCE(*lm_ptep, __pte(pmd_val(pmd))); ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) | PTE_VALID); ++ WRITE_ONCE(*iee_ptep, pte); ++ iee_ptep++; ++ } + } -+ -+ if ((pgd_val(pgd) & PMD_TABLE_BIT) && !check_addr_in_iee_valid(__phys_to_iee(__pgd_to_phys(pgd)))) -+ panic("You can't use non-iee-pgtable\n"); -+ -+ if((pgdp >= pgd_offset_pgd((pgd_t *)swapper_pg_dir, PAGE_OFFSET + BIT(vabits_actual - 2))) && (pgdp < pgd_offset_pgd((pgd_t *)swapper_pg_dir, PAGE_OFFSET + BIT(vabits_actual - 1))) && !(pgd_val(pgd) & PGD_APT)) -+ panic("Set IEE pgd U page.\n"); -+ -+ WRITE_ONCE(*((pgd_t *)(__phys_to_iee(__pa_symbol(pgdp)))), pgd); -+} -+ -+void __iee_code _iee_set_p4d(p4d_t *p4dp, p4d_t p4d) -+{ -+ if(!(p4d_val(p4d) & PMD_SECT_VALID)) ++ else + { -+ WRITE_ONCE(*((p4d_t *)(__phys_to_iee(__pa(p4dp)))), p4d); -+ return; ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*lm_ptep); ++ pte = __pte((pte_val(pte) | PTE_RDONLY) & ~PTE_DBM); ++ WRITE_ONCE(*lm_ptep, pte); ++ pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) | PTE_VALID); ++ WRITE_ONCE(*iee_ptep, pte); ++ lm_ptep++; ++ iee_ptep++; ++ } + } -+ -+ if ((p4d_val(p4d) & PMD_TABLE_BIT) && !check_addr_in_iee_valid(__phys_to_iee(__p4d_to_phys(p4d)))) -+ panic("You can't use non-iee-pgtable\n"); -+ -+ WRITE_ONCE(*((p4d_t *)(__phys_to_iee(__pa(p4dp)))), p4d); +} + -+void __iee_code _iee_set_pud(pud_t *pudp, pud_t pud) ++void __iee_code _iee_unset_sensitive_pte(unsigned long iee_offset, pte_t *lm_ptep, pte_t *iee_ptep, int order, int use_block_pmd) +{ -+ if(!(pud_val(pud) & PMD_SECT_VALID)) ++ int i; ++ ++ lm_ptep = (pte_t *)((unsigned long)lm_ptep + iee_offset); ++ iee_ptep = (pte_t *)((unsigned long)iee_ptep + iee_offset); ++ if(use_block_pmd) + { -+ WRITE_ONCE(*((pud_t *)(__phys_to_iee(__pa(pudp)))), pud); -+ return; ++ pmd_t pmd = __pmd(pte_val(READ_ONCE(*lm_ptep))); ++ pmd = __pmd(pmd_val(pmd) | PTE_DBM); ++ WRITE_ONCE(*lm_ptep, __pte(pmd_val(pmd))); ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) & ~PTE_VALID); ++ WRITE_ONCE(*iee_ptep, pte); ++ iee_ptep++; ++ } + } -+ -+ if ((pud_val(pud) & PMD_TABLE_BIT) && !check_addr_in_iee_valid(__phys_to_iee(__pud_to_phys(pud)))) -+ panic("You can't use non-iee-pgtable\n"); -+ -+ WRITE_ONCE(*((pud_t *)(__phys_to_iee(__pa(pudp)))), pud); -+} -+ -+// Return true if the modify does not break DEP. -+static inline bool check_pmd_dep(char *addr, pmd_t pmd) -+{ -+ // DEP for kernel code and readonly data -+ // _text: .text start addr, __init_begin: .rodata end addr -+ if (addr >= _stext && addr < _etext) ++ else + { -+ if ((PTE_WRITE & pmd_val(pmd)) || // DBM == 1 --> writable -+ !(PTE_RDONLY & pmd_val(pmd))) // DBM == 0 && AP[2] = 0 --> writable ++ for(i = 0; i < (1 << order); i++) + { -+ panic("Can't make kernel's text/readonly page as writable!\n" -+ "addr = 0x%16llx, pmd_val = 0x%16llx", -+ (u64)addr, pmd_val(pmd)); ++ pte_t pte = READ_ONCE(*lm_ptep); ++ pte = __pte(pte_val(pte) | PTE_DBM); ++ WRITE_ONCE(*lm_ptep, pte); ++ pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) & ~PTE_VALID); ++ WRITE_ONCE(*iee_ptep, pte); ++ lm_ptep++; ++ iee_ptep++; + } + } -+ return true; +} + -+// Return true if the pmd table is a part of kernel page table. -+// TODO : Optimize to get lower overhead. -+static inline bool is_kernel_pmd_table(pmd_t *pmdp, pmd_t pmd) ++void __iee_code _iee_set_token(unsigned long iee_offset, pte_t *ptep, void *new, unsigned long order, int use_block_pmd) +{ -+ int i = 0,j = 0; -+ for(i = 0; i < PAGE_SIZE/sizeof(pgd_t); i++) ++ int i; ++ pgd_t *pgdir; ++ pgd_t *pgdp; ++ p4d_t *p4dp; ++ pud_t *pudp; ++ pmd_t *pmdp; ++ pte_t *lm_ptep; ++ pte_t *iee_ptep; ++ unsigned long iee_addr; ++ ++ pgdir = swapper_pg_dir; ++ ++ pgdp = pgd_offset_pgd(pgdir, (unsigned long)new); ++ p4dp = p4d_offset(pgdp, (unsigned long)new); ++ pudp = pud_offset(p4dp, (unsigned long)new); ++ pmdp = pmd_offset(pudp, (unsigned long)new); ++ if(use_block_pmd) ++ lm_ptep = (pte_t *)pmdp; ++ else ++ lm_ptep = pte_offset_kernel(pmdp, (unsigned long)new); ++ // Handling cont mapping. ++ if(pte_val(*lm_ptep) & PTE_CONT) + { -+ pgd_t *pgdp = (pgd_t *)swapper_pg_dir + i; -+ if((pgd_val(*pgdp) & PMD_SECT_VALID) && (pgd_val(*pgdp) & PMD_TABLE_BIT)) ++ // The beginning of cont mapping. ++ int i; ++ pte_t *ptep = (pte_t *)((unsigned long)pte_offset_kernel(pmdp, (unsigned long)new & CONT_PTE_MASK) + iee_offset); ++ if(order < CONFIG_ARM64_CONT_PTE_SHIFT) + { -+ for(j = 0; j < PAGE_SIZE/sizeof(pud_t); j++) ++ for(i = 0; i < CONT_PTES; i++) + { -+ pud_t *pudp = (pud_t *)__va(__pgd_to_phys(*pgdp)) + i; -+ if((pud_val(*pudp) & PMD_SECT_VALID) && (pud_val(*pudp) & PMD_TABLE_BIT)) -+ { -+ pmd_t *current_pmdp = __va(__pud_to_phys(*pudp)); -+ if((unsigned long)current_pmdp == ((unsigned long)pmdp & PAGE_MASK)) -+ return true; -+ } ++ WRITE_ONCE(*ptep,__pte(pte_val(*ptep) & ~PTE_CONT)); ++ ptep++; + } + } + } -+ return false; -+} -+ -+// Return true if it is mapped to a physical range containing IEE page. -+// TODO : Optimize to get lower overhead. -+static inline bool check_addr_range_in_iee_valid(pmd_t pmd) -+{ -+ int i = 0; -+ unsigned long addr = __phys_to_iee(__pmd_to_phys(pmd)); -+ for(i = 0; i < PAGE_SIZE/sizeof(pmd_t); i++) ++ ++ iee_addr = ((unsigned long)new + (unsigned long)iee_offset); ++ pgdp = pgd_offset_pgd(pgdir, iee_addr); ++ p4dp = p4d_offset(pgdp, iee_addr); ++ pudp = pud_offset(p4dp, iee_addr); ++ pmdp = pmd_offset(pudp, iee_addr); ++ iee_ptep = pte_offset_kernel(pmdp, iee_addr); ++ ++ ptep = (pte_t *)((unsigned long)ptep + iee_offset); ++ lm_ptep = (pte_t *)((unsigned long)lm_ptep + iee_offset); ++ iee_ptep = (pte_t *)((unsigned long)iee_ptep + iee_offset); ++ if(use_block_pmd) + { -+ if(check_addr_in_iee_valid(addr + PAGE_SIZE * i)) -+ return true; ++ pmd_t *pmdp = (pmd_t *)lm_ptep; ++ pmd_t pmd = READ_ONCE(*pmdp); ++ pmd = __pmd((pmd_val(pmd) | PMD_SECT_RDONLY) & ~PTE_DBM); ++ WRITE_ONCE(*pmdp, pmd); ++ for(i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(((pte_val(pte) | PTE_VALID) & ~PTE_ADDR_MASK) | __phys_to_pte_val(__pa(new))); ++ WRITE_ONCE(*ptep, pte); ++ pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) | PTE_VALID); ++ WRITE_ONCE(*iee_ptep, pte); ++ ptep++; ++ iee_ptep++; ++ new += PAGE_SIZE; ++ } + } -+ return false; -+} -+ -+void __iee_code _iee_set_pmd(pmd_t *pmdp, pmd_t pmd) -+{ -+ char * addr = (char *)__phys_to_kimg(__pmd_to_phys(pmd)); -+ -+ if(!(pmd_val(pmd) & PMD_SECT_VALID)) ++ else + { -+ WRITE_ONCE(*((pmd_t *)(__phys_to_iee(__pa(pmdp)))), pmd); -+ return; ++ for(i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(((pte_val(pte) | PTE_VALID) & ~PTE_ADDR_MASK) | __phys_to_pte_val(__pa(new))); ++ WRITE_ONCE(*ptep, pte); ++ pte = READ_ONCE(*lm_ptep); ++ pte = __pte((pte_val(pte) | PTE_RDONLY) & ~PTE_DBM); ++ WRITE_ONCE(*lm_ptep, pte); ++ pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) | PTE_VALID); ++ WRITE_ONCE(*iee_ptep, pte); ++ ptep++; ++ lm_ptep++; ++ iee_ptep++; ++ new += PAGE_SIZE; ++ } + } -+ -+ // Check if the pte table is legally allocated. -+ if ((pmd_val(pmd) & PMD_TABLE_BIT) && !check_addr_in_iee_valid(__phys_to_iee(__pmd_to_phys(pmd)))) -+ panic("You can't use non-iee-pgtable\n"); -+ -+ // Avoid mapping a huge pmd as U page. -+ if(!(pmd_val(pmd) & PMD_TABLE_BIT) && (pmd_val(pmd) & PMD_SECT_USER) && is_kernel_pmd_table(pmdp, pmd)) -+ panic("Set a block descriptor in kernel space U page.\n"); -+ -+ // Avoid mapping a huge pmd to IEE physical page. -+ if(!(pmd_val(pmd) & PMD_TABLE_BIT) && check_addr_range_in_iee_valid(pmd)) -+ panic("Mapping IEE physical page to a huge pmd.\n"); -+ -+ if(!check_pmd_dep(addr, pmd)) -+ return; -+ -+ WRITE_ONCE(*((pmd_t *)(__phys_to_iee(__pa(pmdp)))), pmd); +} + -+// Return true if the pte table is a part of kernel page table. -+// TODO : Optimize to get lower overhead. -+static inline bool is_kernel_pte_table(pte_t *ptep, pte_t pte) ++void __iee_code _iee_unset_token(unsigned long iee_offset, pte_t *ptep, void *token_addr, void *token_page, unsigned long order) +{ -+ return false; -+} ++ int i; ++ pgd_t *pgdir; ++ pgd_t *pgdp; ++ p4d_t *p4dp; ++ pud_t *pudp; ++ pmd_t *pmdp; ++ pte_t *lm_ptep; ++ pte_t *iee_ptep; ++ unsigned long iee_addr; ++ int use_block_pmd = 0; + -+// Return true if it does not change the privilage or add new U page in kernel. -+static inline bool check_privilage_safe(pte_t *ptep, pte_t pte) -+{ -+ if(!(pte_val(pte) & PTE_VALID)) -+ return true; ++ pgdir = swapper_pg_dir; ++ ++ pgdp = pgd_offset_pgd(pgdir, (unsigned long)token_page); ++ p4dp = p4d_offset(pgdp, (unsigned long)token_page); ++ pudp = pud_offset(p4dp, (unsigned long)token_page); ++ pmdp = pmd_offset(pudp, (unsigned long)token_page); ++ // Use Block Descriptor. ++ if(pmd_leaf(*pmdp)) ++ { ++ use_block_pmd = 1; ++ lm_ptep = (pte_t *)pmdp; ++ } ++ else ++ lm_ptep = pte_offset_kernel(pmdp, (unsigned long)token_page); + -+ if((pte_val(*ptep) & PTE_VALID)) ++ iee_addr = ((unsigned long)token_page + (unsigned long)iee_offset); ++ pgdp = pgd_offset_pgd(pgdir, iee_addr); ++ p4dp = p4d_offset(pgdp, iee_addr); ++ pudp = pud_offset(p4dp, iee_addr); ++ pmdp = pmd_offset(pudp, iee_addr); ++ iee_ptep = pte_offset_kernel(pmdp, iee_addr); ++ ++ ptep = (pte_t *)((unsigned long)ptep + iee_offset); ++ lm_ptep = (pte_t *)((unsigned long)lm_ptep + iee_offset); ++ iee_ptep = (pte_t *)((unsigned long)iee_ptep + iee_offset); ++ if(use_block_pmd) + { -+ if((pte_val(*ptep) & PTE_USER) != (pte_val(pte) & PTE_USER)) -+ panic("Incorrectly change privilage.\n"); ++ pmd_t *pmdp = (pmd_t *)lm_ptep; ++ pmd_t pmd = READ_ONCE(*pmdp); ++ pmd = __pmd(pmd_val(pmd) | PTE_DBM); ++ WRITE_ONCE(*pmdp, pmd); ++ for(i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(((pte_val(pte) & ~PTE_VALID) & ~PTE_ADDR_MASK) | __phys_to_pte_val(__pa(token_addr - IEE_OFFSET))); ++ WRITE_ONCE(*ptep, pte); ++ pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) & ~PTE_VALID); ++ WRITE_ONCE(*iee_ptep, pte); ++ ptep++; ++ iee_ptep++; ++ token_addr += PAGE_SIZE; ++ token_page += PAGE_SIZE; ++ } + } + else + { -+ if((pte_val(pte) & PTE_USER) && is_kernel_pte_table(ptep, pte)) -+ panic("Add new U page in kernel space.\n"); ++ for(i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(((pte_val(pte) & ~PTE_VALID) & ~PTE_ADDR_MASK) | __phys_to_pte_val(__pa(token_addr - IEE_OFFSET))); ++ WRITE_ONCE(*ptep, pte); ++ pte = READ_ONCE(*lm_ptep); ++ pte = __pte(pte_val(pte) | PTE_DBM); ++ WRITE_ONCE(*lm_ptep, pte); ++ pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) & ~PTE_VALID); ++ WRITE_ONCE(*iee_ptep, pte); ++ ptep++; ++ lm_ptep++; ++ iee_ptep++; ++ token_addr += PAGE_SIZE; ++ token_page += PAGE_SIZE; ++ } + } -+ return true; +} + -+// TODO : When adding a new executable page, check it for DEP. -+static inline bool safely_adding_new_exec_page(pte_t *ptep, pte_t pte) ++void __iee_code _iee_invalidate_token(unsigned long iee_offset, struct task_struct *tsk) +{ -+ return true; ++ struct task_token *token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); ++ token->pgd = NULL; ++ token->valid = false; ++ token->kernel_stack = NULL; +} + -+// Return true if it is only changing prot of a pte. -+static inline bool is_changing_pte_prot(pte_t *ptep, pte_t pte) ++void __iee_code _iee_validate_token(unsigned long iee_offset, struct task_struct *tsk) +{ -+ if(((pte_val(*ptep) ^ pte_val(pte)) & PTE_ADDR_MASK) == 0) -+ return true; -+ else -+ return false; ++ struct task_token *token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); ++ token->valid = true; +} + -+// Return true if the modify does not break DEP. -+static inline bool check_pte_dep(char *addr, pte_t pte) ++#ifdef CONFIG_KOI ++extern unsigned long koi_swapper_ttbr1; ++#endif ++void __iee_code _iee_init_token(unsigned long iee_offset, struct task_struct *tsk, void *iee_stack, void *tmp_page) +{ -+ // DEP for kernel code and readonly data -+ // _text: .text start addr, __init_begin: .rodata end addr -+ if (addr >= _stext && addr < _etext) -+ { -+ if ((PTE_WRITE & pte_val(pte)) // DBM == 1 --> writable -+ || !(PTE_RDONLY & pte_val(pte))) // DBM == 0 && AP[2] = 0 --> writable -+ { -+ panic("Can't make kernel's text/readonly page as writable!\n" -+ "addr = 0x%16llx, pte_val = 0x%16llx", -+ (u64)addr, pte_val(pte)); -+ } -+ } -+ return true; ++ struct task_token *token; ++ ++ token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); ++ token->iee_stack = iee_stack; ++ token->tmp_page = tmp_page; ++#ifdef CONFIG_KOI ++ token->koi_kernel_stack = NULL; ++ token->koi_stack = NULL; ++ token->koi_stack_base = NULL; ++ token->current_ttbr1 = 0; ++#endif +} + -+void __iee_code _iee_set_pte(pte_t *ptep, pte_t pte) ++void __iee_code _iee_set_token_pgd(unsigned long iee_offset, struct task_struct *tsk, pgd_t *pgd) +{ -+ char * addr = (char *)__phys_to_kimg(__pte_to_phys(pte)); ++ struct task_token *token; + -+ if(!(pte_val(pte) & PTE_VALID)) ++ token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); ++ token->pgd = pgd; ++} ++ ++void __iee_code _iee_set_freeptr(unsigned long iee_offset, void **pptr, void *ptr) ++{ ++ pptr = (void **)((unsigned long)pptr + (unsigned long)iee_offset); ++ *pptr = ptr; ++} ++ ++#pragma GCC push_options ++#pragma GCC optimize("O0") ++void __iee_code _iee_memset(unsigned long iee_offset, void *ptr, int data, size_t n) ++{ ++ char *_ptr; ++ ++ _ptr = (char *)((unsigned long)ptr + (unsigned long)iee_offset); ++ ++ while (n--) ++ *_ptr++ = data; ++} ++ ++void __iee_code _iee_memcpy(unsigned long iee_offset, void *dst, void *src, size_t n) ++{ ++ char *_dst, *_src; ++ ++ _dst = (char *)((unsigned long)dst + (unsigned long)iee_offset); ++ _src = (char *)src; ++ ++ while(n--) ++ *_dst++ = *_src++; ++} ++#pragma GCC pop_options ++ ++void __iee_code _iee_set_track(unsigned long iee_offset, struct track *ptr, struct track *data) ++{ ++ _iee_memcpy(iee_offset, ptr, data, sizeof(struct track)); ++} ++ ++void __iee_code _iee_set_cred_rcu(unsigned long iee_offset, struct cred *cred, struct rcu_head *rcu) ++{ ++ if(cred == &init_cred) ++ cred = (struct cred *)__phys_to_iee(__pa_symbol(cred)); ++ else ++ cred = (struct cred *)((unsigned long)cred + (unsigned long)iee_offset); ++ #ifdef CONFIG_CREDP ++ *((struct rcu_head **)(&(cred->rcu.func))) = rcu; ++ #endif ++} ++ ++void __iee_code _iee_set_cred_security(unsigned long iee_offset, struct cred *cred, void *security) ++{ ++ if(cred == &init_cred) ++ cred = (struct cred *)__phys_to_iee(__pa_symbol(cred)); ++ else ++ cred = (struct cred *)((unsigned long)cred + (unsigned long)iee_offset); ++ cred->security = security; ++} ++ ++bool __iee_code _iee_set_cred_atomic_op_usage(unsigned long iee_offset, struct cred *cred, int flag, int nr) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ switch (flag) + { -+ WRITE_ONCE(*((pte_t *)(__phys_to_iee(__pa(ptep)))), pte); -+ return; ++ case AT_ADD: { ++ atomic_long_add(nr, &cred->usage); ++ return 0; ++ } ++ case AT_INC_NOT_ZERO: { ++ return atomic_long_inc_not_zero(&cred->usage); ++ } ++ case AT_SUB_AND_TEST: { ++ return atomic_long_sub_and_test(nr, &cred->usage); + } ++ } ++ return 0; ++} + -+ // Avoid modify privilage unsafely. -+ if(!check_privilage_safe(ptep, pte)) -+ panic("You are modify privilage unsafely.\n"); ++void __iee_code _iee_set_cred_atomic_set_usage(unsigned long iee_offset, struct cred *cred, int i) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ atomic_long_set(&cred->usage,i); ++} + -+ // Avoid mapping a new executable page. -+ if(!safely_adding_new_exec_page(ptep, pte)) -+ panic("You are adding a new executable page unsafely.\n"); ++void __iee_code _iee_set_cred_non_rcu(unsigned long iee_offset, struct cred *cred, int non_rcu) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->non_rcu = non_rcu; ++} + -+ // Avoid mapping a new VA to IEE PA. -+ if(!is_changing_pte_prot(ptep, pte) && -+ check_addr_in_iee_valid(__phys_to_iee(__pte_to_phys(pte)))) -+ panic("You are remmaping IEE page to other VA.\n"); ++void __iee_code _iee_set_cred_session_keyring(unsigned long iee_offset, struct cred *cred, struct key *session_keyring) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->session_keyring = session_keyring; ++} + -+ // Avoid mapping a writable VA to kernel code PA. -+ if(!check_pte_dep(addr, pte)) -+ return; ++void __iee_code _iee_set_cred_process_keyring(unsigned long iee_offset, struct cred *cred, struct key *process_keyring) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->process_keyring = process_keyring; ++} + -+ WRITE_ONCE(*((pte_t *)(__phys_to_iee(__pa(ptep)))), pte); ++void __iee_code _iee_set_cred_thread_keyring(unsigned long iee_offset, struct cred *cred, struct key *thread_keyring) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->thread_keyring = thread_keyring; +} + -+// Return true if it only sets U page and modify NG. -+static inline bool is_setting_upage(pte_t *ptep, pte_t pte) ++void __iee_code _iee_set_cred_request_key_auth(unsigned long iee_offset, struct cred *cred, struct key *request_key_auth) +{ -+ if(((pte_val(*ptep) ^ pte_val(pte)) & ~(PTE_USER | PTE_NG)) != 0) -+ panic("Incorrectly setting U page.\n"); -+ if((pte_val(pte) & PTE_USER) != PTE_USER) -+ panic("Using error interface to set P page.\n"); -+ return true; ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->request_key_auth = request_key_auth; +} + -+void __iee_code _iee_set_pte_upage(pte_t *ptep, pte_t pte) ++void __iee_code _iee_set_cred_jit_keyring(unsigned long iee_offset, struct cred *cred, unsigned char jit_keyring) +{ -+ // Check if it only change the prot. -+ if(!is_setting_upage(ptep,pte)) -+ panic("Incorrectly setting U page.\n"); ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->jit_keyring = jit_keyring; ++} + -+ WRITE_ONCE(*((pte_t *)(__phys_to_iee(__pa(ptep)))), pte); ++void __iee_code _iee_set_cred_cap_inheritable(unsigned long iee_offset, struct cred *cred, kernel_cap_t cap_inheritable) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->cap_inheritable = cap_inheritable; +} + -+// Return true if it only sets P page and modify NG. -+static inline bool is_setting_ppage(pte_t *ptep, pte_t pte) ++void __iee_code _iee_set_cred_cap_permitted(unsigned long iee_offset, struct cred *cred, kernel_cap_t cap_permitted) +{ -+ if(((pte_val(*ptep) ^ pte_val(pte)) & ~(PTE_USER | PTE_NG)) != 0) -+ panic("Incorrectly setting P page.\n"); -+ if((pte_val(pte) & PTE_USER) != 0) -+ panic("Using error interface to set U page.\n"); -+ return true; ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->cap_permitted = cap_permitted; +} + -+void __iee_code _iee_set_pte_ppage(pte_t *ptep, pte_t pte) ++void __iee_code _iee_set_cred_cap_effective(unsigned long iee_offset, struct cred *cred, kernel_cap_t cap_effective) +{ -+ // Check if it only change the prot. -+ if(!is_setting_ppage(ptep,pte)) -+ panic("Incorrectly setting P page.\n"); ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->cap_effective = cap_effective; ++} + -+ WRITE_ONCE(*((pte_t *)(__phys_to_iee(__pa(ptep)))), pte); ++void __iee_code _iee_set_cred_cap_bset(unsigned long iee_offset, struct cred *cred, kernel_cap_t cap_bset) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->cap_bset = cap_bset; +} + -+void __iee_code _iee_set_bm_pte(pte_t *ptep, pte_t pte) ++void __iee_code _iee_set_cred_cap_ambient(unsigned long iee_offset, struct cred *cred, kernel_cap_t cap_ambient) +{ -+ WRITE_ONCE(*((pte_t *)(__phys_to_iee(__pa_symbol(ptep)))), pte); ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->cap_ambient = cap_ambient; +} + -+/* Data in iee_si_base is visible to all pgd while iee_si_data is private. */ -+unsigned long iee_base_idmap_pg_dir __iee_si_data; -+unsigned long iee_base_reserved_pg_dir __iee_si_data; -+unsigned long iee_base__bp_harden_el1_vectors __iee_si_data; -+bool iee_init_done __iee_si_data; -+unsigned long iee_si_tcr __iee_si_data; ++void __iee_code _iee_set_cred_securebits(unsigned long iee_offset, struct cred *cred, unsigned securebits) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->securebits = securebits; ++} + -+static u64 __iee_si_code inline iee_si_mask(unsigned long mask, unsigned long new_val, unsigned long old_val) ++void __iee_code _iee_set_cred_group_info(unsigned long iee_offset, struct cred *cred, struct group_info *group_info) +{ -+ return (new_val & mask) | (old_val & ~mask); ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->group_info = group_info; +} -+/* -+ * handler function for requests of executing sensitive instrutions. -+ */ -+u64 __iee_si_code iee_si_handler(int flag, ...) ++ ++void __iee_code _iee_set_cred_ucounts(unsigned long iee_offset, struct cred *cred, struct ucounts *ucounts) +{ -+ va_list pArgs; -+ u64 old_val, new_val; ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->ucounts = ucounts; ++} + -+ // BUG_ON(flag > IEE_WRITE_MDSCR); -+ va_start(pArgs, flag); -+ switch (flag) { -+ case IEE_SI_TEST: -+ break; -+ case IEE_WRITE_SCTLR: { -+ old_val = read_sysreg(sctlr_el1); -+ new_val = va_arg(pArgs, u64); -+ new_val = iee_si_mask(IEE_SCTLR_MASK, new_val, old_val); -+ write_sysreg(new_val, sctlr_el1); -+ break; -+ } -+ case IEE_WRITE_TTBR0: -+ case IEE_CONTEXT_SWITCH: { -+ u64 new_asid, new_phys, old_phys, token_phys; -+ struct task_struct *tsk; -+ struct task_token *token; -+ new_val = va_arg(pArgs, u64); -+ new_phys = (new_val & PAGE_MASK) & ~TTBR_ASID_MASK; -+ new_asid = new_val >> 48; ++void __iee_code _iee_set_cred_user_ns(unsigned long iee_offset, struct cred *cred, struct user_namespace *user_ns) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->user_ns = user_ns; ++} + -+ // Check ASID first -+ if (new_phys == iee_base_reserved_pg_dir){ -+ if (new_asid != 1) -+ panic("IEE SI warning: reserved_pg_dir ASID invalid: %llx:%llx", new_asid, new_val); -+ } -+ // Already reserved asid 1 for iee rwx gate. -+ else if (new_asid == 0){ -+ new_val |= FIELD_PREP(TTBR_ASID_MASK, 1); -+ printk("IEE SI: Modify ASID of %llx to 1.", new_val); -+ } -+ // TO DO: operations to protect idmap_pg_dir -+ else if (new_phys == iee_base_idmap_pg_dir) -+ { -+ // printk("IEE SI: switch to idmap_pg_dir.); -+ } -+ else if (new_asid % 2 ==0) -+ panic("IEE SI warning: TTBR0 ASID invalid: %llx:%llx", new_asid, new_val); ++void __iee_code _iee_set_cred_user(unsigned long iee_offset, struct cred *cred, struct user_struct *user) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->user = user; ++} + -+ /* Skip verification if iee hasn't been initialized. */ -+ if (iee_init_done){ -+ // Verify current sp_el0 with iee token info -+ asm volatile("mrs %x0, sp_el0":"=r"(tsk)); -+ token = (struct task_token *)__phys_to_iee(__pa(tsk)); -+ -+ /* -+ * token->pgd != NULL means it is a user task, then we need to check whether current ttbr0 is correct. -+ */ -+ if (token->pgd){ -+ old_val = read_sysreg(ttbr0_el1); -+ // When TTBR0 is reserved_pg_dir then no checking is available. -+ if (old_val != iee_base_reserved_pg_dir){ -+ old_phys = (old_val & PAGE_MASK) & ~TTBR_ASID_MASK; -+ token_phys = __pa(token->pgd); -+ if (old_phys != token_phys) -+ panic("IEE SI warning: Pgd set error. old ttbr0:%lx, token ttbr0:%lx, token pgd:%lx", -+ (unsigned long)old_phys, (unsigned long)token_phys, (unsigned long)(token->pgd)); -+ } -+ } -+ } -+ // all checks are done. -+ write_sysreg(new_val, ttbr0_el1); -+ -+ // SET ASID in TTBR1 when context switch -+ if (flag == IEE_CONTEXT_SWITCH){ -+ new_val = (read_sysreg(ttbr1_el1) & ~TTBR_ASID_MASK) | FIELD_PREP(TTBR_ASID_MASK, new_asid-1); -+ write_sysreg(new_val, ttbr1_el1); -+ } -+ break; -+ } -+ case IEE_WRITE_VBAR: { -+ u64 el1_vector; -+ new_val = va_arg(pArgs, u64); -+ el1_vector = iee_base__bp_harden_el1_vectors; -+ if(new_val == el1_vector || new_val == el1_vector+SZ_2K || -+ new_val == el1_vector+SZ_2K*2 || new_val == el1_vector+SZ_2K*3) -+ write_sysreg(new_val, vbar_el1); -+ break; -+ } -+ case IEE_WRITE_TCR: { -+ old_val = read_sysreg(tcr_el1); -+ new_val = va_arg(pArgs, u64); -+ new_val = iee_si_mask(IEE_TCR_MASK, new_val, old_val); -+ write_sysreg(new_val, tcr_el1); -+ break; -+ } -+ case IEE_WRITE_MDSCR: { -+ old_val = read_sysreg(mdscr_el1); -+ new_val = va_arg(pArgs, u64); -+ new_val = iee_si_mask(IEE_MDSCR_MASK, new_val, old_val); -+ write_sysreg(new_val, mdscr_el1); -+ break; -+ } -+ } -+ va_end(pArgs); -+ return 0; ++void __iee_code _iee_set_cred_fsgid(unsigned long iee_offset, struct cred *cred, kgid_t fsgid) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->fsgid = fsgid; +} -+/* -+ * TODO: scan a page to check whether it contains sensitive instructions -+ * return 1 when finding sensitive inst, 0 on safe page. -+ */ -+int iee_si_scan_page(unsigned long addr); -+#endif -\ No newline at end of file -diff --git a/arch/arm64/kernel/koi/Makefile b/arch/arm64/kernel/koi/Makefile -new file mode 100644 -index 000000000000..9be8710b714a ---- /dev/null -+++ b/arch/arm64/kernel/koi/Makefile -@@ -0,0 +1 @@ -+obj-y += koi.o -\ No newline at end of file -diff --git a/arch/arm64/kernel/koi/koi.c b/arch/arm64/kernel/koi/koi.c -new file mode 100644 -index 000000000000..716ba16ab358 ---- /dev/null -+++ b/arch/arm64/kernel/koi/koi.c -@@ -0,0 +1,1327 @@ -+#include "asm/koi.h" -+#include "linux/compiler_attributes.h" -+#include "linux/compiler_types.h" -+#include "asm/barrier.h" -+#include "asm-generic/bug.h" -+#include "asm-generic/errno-base.h" -+#include "asm-generic/memory_model.h" -+#include "asm-generic/pgtable-nop4d.h" -+#include "asm-generic/rwonce.h" -+#include "asm/pgalloc.h" -+#include "asm/memory.h" -+#include "linux/bitfield.h" -+#include "linux/compiler.h" -+#include "linux/types.h" -+#include "linux/spinlock.h" -+#include "linux/spinlock_types.h" -+#include "linux/kernel.h" -+#include "linux/rculist.h" -+#include "linux/rcupdate.h" -+#include "linux/list.h" -+#include "asm/current.h" -+#include "linux/compiler_types.h" -+#include "asm-generic/barrier.h" -+#include "asm-generic/rwonce.h" -+#include "asm-generic/pgalloc.h" -+#include "asm/cpufeature.h" -+#include "asm/kvm_hyp.h" -+#include "asm/mmu.h" -+#include "asm/mmu_context.h" -+#include "asm/page-def.h" -+#include "asm/pgalloc.h" -+#include "asm/pgtable-hwdef.h" -+#include "asm/pgtable-types.h" -+#include "asm/pgtable.h" -+#include "asm/string.h" -+#include "asm/sysreg.h" -+#include "linux/bitfield.h" -+#include "linux/compiler.h" -+#include "linux/export.h" -+#include "linux/gfp.h" -+#include "linux/huge_mm.h" -+#include "linux/kallsyms.h" -+#include "linux/kconfig.h" -+#include "linux/kern_levels.h" -+#include "linux/kernel.h" -+#include "linux/list.h" -+#include "linux/lockdep.h" -+#include "linux/mm.h" -+#include "linux/mm_types.h" -+#include "linux/pgtable.h" -+#include "linux/printk.h" -+#include "linux/rculist.h" -+#include "linux/rcupdate.h" -+#include "linux/rmap.h" -+#include "linux/sched.h" -+#include "linux/stddef.h" -+#include "linux/string.h" -+#include "linux/swap.h" -+#include "linux/swapops.h" -+#include "linux/types.h" -+#include "linux/slab.h" -+#include "linux/string.h" -+#include "linux/hashtable.h" + -+#define __koi_code __section(".koi.text") -+#define __koi_data __section(".data..koi") ++void __iee_code _iee_set_cred_fsuid(unsigned long iee_offset, struct cred *cred, kuid_t fsuid) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->fsuid = fsuid; ++} + -+extern unsigned long __koi_code_start[]; -+extern unsigned long __koi_code_end[]; -+extern unsigned long __koi_data_start[]; -+extern unsigned long __koi_data_end[]; -+#ifdef CONFIG_IEE -+extern unsigned long __iee_si_base_start[]; -+extern unsigned long __iee_exec_entry_start[]; -+extern unsigned long __iee_exec_entry_end[]; -+#endif ++void __iee_code _iee_set_cred_egid(unsigned long iee_offset, struct cred *cred, kgid_t egid) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->egid = egid; ++} + -+__koi_data unsigned long koi_swapper_ttbr1 = 0; -+EXPORT_SYMBOL(koi_swapper_ttbr1); -+#define KOI_SWAPPER_MASK 0x0000fffffffffff0 ++void __iee_code _iee_set_cred_euid(unsigned long iee_offset, struct cred *cred, kuid_t euid) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->euid = euid; ++} + -+__attribute__((aligned(PAGE_SIZE))) -+DEFINE_PER_CPU(unsigned long[PAGE_SIZE / sizeof(unsigned long)], -+ koi_irq_current_ttbr1); -+EXPORT_SYMBOL(koi_irq_current_ttbr1); ++void __iee_code _iee_set_cred_sgid(unsigned long iee_offset, struct cred *cred, kgid_t sgid) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->sgid = sgid; ++} + -+extern void koi_switch_to_ko_stack(unsigned long stack_top); -+extern void init_ko_mm(struct mm_struct *ko_mm, pgd_t *pgdp); -+extern void koi_check_and_switch_context(struct mm_struct *mm); -+extern int koi_add_page_mapping(unsigned long dst, unsigned long src); -+extern unsigned long _iee_read_token_ttbr1(struct task_struct *tsk); -+/** -+*struct koi_mem_list - maintain a linked list of free memory in the kernel -+*@addr: stating address of this memory -+*@size: the size of the memory -+*@list: the head of the koi_mem_list -+*@rcu: for rcu -+*/ -+struct koi_mem_list { -+ unsigned long addr; -+ unsigned long size; -+ struct list_head list; -+ struct rcu_head rcu; -+}; -+//mapping parameter pointer to copy -+struct koi_addr_map { -+ unsigned long buffer_addr; -+ unsigned long orig_addr; -+ int offset; -+ struct hlist_node node; -+ struct rcu_head rcu; -+}; ++void __iee_code _iee_set_cred_suid(unsigned long iee_offset, struct cred *cred, kuid_t suid) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->suid = suid; ++} + -+DEFINE_HASHTABLE(koi_mem_htbl, HASH_TABLE_BIT); -+EXPORT_SYMBOL(koi_mem_htbl); -+DEFINE_SPINLOCK(koi_mem_htbl_spin_lock); -+EXPORT_SYMBOL(koi_mem_htbl_spin_lock); ++void __iee_code _iee_copy_cred(unsigned long iee_offset, struct cred *old, struct cred *new) ++{ ++ #ifdef CONFIG_CREDP ++ struct rcu_head *rcu = (struct rcu_head *)(new->rcu.func); ++ struct cred *_new = (struct cred *)__phys_to_iee(__pa(new)); ++ _iee_memcpy(iee_offset, new, old, sizeof(struct cred)); ++ *(struct rcu_head **)(&(_new->rcu.func)) = rcu; ++ *(struct rcu_head *)(_new->rcu.func) = *(struct rcu_head *)(old->rcu.func); ++ #endif ++} + -+EXPORT_SYMBOL(koi_do_switch_to_ko_stack); -+EXPORT_SYMBOL(koi_do_switch_to_kernel_stack); ++void __iee_code _iee_set_cred_gid(unsigned long iee_offset, struct cred *cred, kgid_t gid) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->gid = gid; ++} + -+extern unsigned long long iee_rw_gate(int flag, ...); ++void __iee_code _iee_set_cred_uid(unsigned long iee_offset, struct cred *cred, kuid_t uid) ++{ ++ cred = (struct cred *)__phys_to_iee(__pa(cred)); ++ cred->uid = uid; ++} + -+/** -+* koi_ttbr_ctor - return ttbr1 for the given driver module -+*/ -+unsigned long koi_ttbr_ctor(struct module *mod) ++void __iee_code _iee_write_in_byte(unsigned long iee_offset, void *ptr, __u64 data, int length) +{ -+ struct koi_mem_hash_node *ko; -+ struct mm_struct *ko_mm; -+ unsigned long ttbr1; -+ unsigned long asid; -+ int bkt; -+ rcu_read_lock(); -+ hash_for_each_rcu (koi_mem_htbl, bkt, ko, node) { -+ if (ko->mod == mod) { -+ ko_mm = ko->ko_mm; ++ ptr = (void *)((unsigned long)ptr + (unsigned long)iee_offset); ++ switch(length) { ++ case 8: { ++ *(__u64 *)ptr = data; ++ break; ++ } ++ case 4: { ++ *(__u32 *)ptr = (__u32)data; ++ break; ++ } ++ case 2: { ++ *(__u16 *)ptr = (__u16)data; ++ break; ++ } ++ case 1: { ++ *(__u8 *)ptr = (__u8)data; + break; + } + } -+ rcu_read_unlock(); -+ if (!ko_mm) { -+ printk(KERN_ERR "cannot found module %s in koi_mem_htbl", -+ mod->name); -+ return 0; -+ } -+ asm volatile("mrs %0, ttbr0_el1\n":"=r"(asid):); -+ asid &= TTBR_ASID_MASK; -+ ttbr1 = ko->ko_ttbr1 | asid; -+ // koi_check_and_switch_context(ko_mm); -+ // asid = ASID(ko_mm); -+ // ttbr1 = ko->ko_ttbr1 | FIELD_PREP(TTBR_ASID_MASK, asid); -+ return ttbr1; +} -+EXPORT_SYMBOL(koi_ttbr_ctor); -+//release the hash node -+static __maybe_unused void koi_mem_hash_node_free(struct rcu_head *rcu) ++ ++static pteval_t inline _iee_set_cmpxchg_relaxed(pte_t *ptep, pteval_t old_pteval, pteval_t new_pteval, unsigned long iee_offset) +{ -+ struct koi_mem_hash_node *node = -+ container_of(rcu, struct koi_mem_hash_node, rcu); -+ kfree(node); ++ pteval_t pteval = cmpxchg_relaxed((pteval_t *)((unsigned long)ptep + iee_offset), old_pteval, new_pteval); ++ return pteval; +} -+//release free memory linked list nodes -+static void koi_mem_node_free(struct rcu_head *rcu) ++ ++/* Check if addr is allocated in IEE page */ ++static inline bool check_addr_in_iee_valid(unsigned long addr) +{ -+ struct koi_mem_list *mem_node = -+ container_of(rcu, struct koi_mem_list, rcu); -+ kfree(mem_node); ++ pgd_t *pgdir = swapper_pg_dir; ++ ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ pud_t *pudp; ++ pmd_t *pmdp; ++ pte_t *ptep; ++ ++ if(!(p4d_val(READ_ONCE(*p4dp)) & PTE_VALID)) ++ return false; ++ ++ pudp = pud_offset(p4dp, addr); ++ ++ if(!(pud_val(READ_ONCE(*pudp)) & PTE_VALID)) ++ return false; ++ ++ pmdp = pmd_offset(pudp, addr); ++ ++ if(!(pmd_val(READ_ONCE(*pmdp)) & PTE_VALID)) ++ return false; ++ ++ ptep = pte_offset_kernel(pmdp, addr); ++ ++ return (pte_val(READ_ONCE(*ptep)) & PTE_VALID); +} -+//release the node in koi_addr_map -+static void koi_addr_map_node_free(struct rcu_head *rcu) ++ ++void __iee_code _iee_set_tramp_pgd(unsigned long iee_offset, pgd_t *pgdp, pgd_t pgd) +{ -+ struct koi_addr_map *addr_map_node = -+ container_of(rcu, struct koi_addr_map, rcu); -+ kfree(addr_map_node); ++ WRITE_ONCE(*((pgd_t *)(__phys_to_iee(__pa_symbol(pgdp)))), pgd); +} + -+#ifndef CONFIG_IEE -+/* -+ * This function is used to switch to ko's pgtable. -+ */ -+__koi_code noinline unsigned long koi_do_switch_to_ko_pgtbl(void) ++void __iee_code _iee_set_swapper_pgd(unsigned long iee_offset, pgd_t *pgdp, pgd_t pgd) +{ -+ struct koi_mem_hash_node *ko; -+ // struct mm_struct *ko_mm; -+ unsigned long addr; -+ unsigned long ttbr1, asid; -+ unsigned long *ptr; -+ struct task_token *token_addr = -+ (struct task_token *)((unsigned long)current + -+ (unsigned long)koi_offset); -+ int bkt; -+ asm volatile(" mrs %0, elr_el1\n" : "=r"(addr)); -+ ptr = SHIFT_PERCPU_PTR(koi_irq_current_ttbr1, __kern_my_cpu_offset()); -+ rcu_read_lock(); -+ hash_for_each_rcu (koi_mem_htbl, bkt, ko, node) { -+ if (ko->mod->init_layout.base != NULL) { -+ if (addr >= (unsigned long)ko->mod->init_layout.base && -+ addr < (unsigned long)(ko->mod->init_layout.base + -+ ko->mod->init_layout.size)) { -+ if (token_addr->current_ttbr1 == ko->ko_ttbr1 || -+ *ptr == ko->ko_ttbr1) { -+ // ko_mm = ko->ko_mm; -+ // koi_check_and_switch_context(ko_mm); -+ // asid = ASID(ko_mm); -+ // ttbr1 = ko->ko_ttbr1; -+ // ttbr1 |= FIELD_PREP(TTBR_ASID_MASK, asid); -+ asm volatile("mrs %0, ttbr0_el1\n":"=r"(asid):); -+ asid &= TTBR_ASID_MASK; -+ ttbr1 = ko->ko_ttbr1 | asid; -+ rcu_read_unlock(); -+ return ttbr1; -+ } -+ rcu_read_unlock(); -+ return 0; -+ } -+ } -+ if (addr >= (unsigned long)ko->mod->core_layout.base && -+ addr < (unsigned long)ko->mod->core_layout.base + -+ ko->mod->core_layout.size) { -+ if (token_addr->current_ttbr1 == ko->ko_ttbr1 || -+ *ptr == ko->ko_ttbr1) { -+ // ko_mm = ko->ko_mm; -+ // koi_check_and_switch_context(ko_mm); -+ // asid = ASID(ko_mm); -+ // ttbr1 = ko->ko_ttbr1; -+ // ttbr1 |= FIELD_PREP(TTBR_ASID_MASK, asid); -+ asm volatile("mrs %0, ttbr0_el1\n":"=r"(asid):); -+ asid &= TTBR_ASID_MASK; -+ ttbr1 = ko->ko_ttbr1 | asid; -+ rcu_read_unlock(); -+ return ttbr1; -+ } -+ rcu_read_unlock(); -+ return 0; -+ } ++ if(!(pgd_val(pgd) & PMD_SECT_VALID)) ++ { ++ WRITE_ONCE(*((pgd_t *)(__phys_to_iee(__pa_symbol(pgdp)))), pgd); ++ return; + } -+ rcu_read_unlock(); -+ return 0; ++ ++ if ((pgd_val(pgd) & PMD_TABLE_BIT) && !check_addr_in_iee_valid(__phys_to_iee(__pgd_to_phys(pgd)))) ++ panic("You can't use non-iee-pgtable\n"); ++ ++ if((pgdp >= pgd_offset_pgd((pgd_t *)swapper_pg_dir, PAGE_OFFSET + BIT(vabits_actual - 2))) && (pgdp < pgd_offset_pgd((pgd_t *)swapper_pg_dir, PAGE_OFFSET + BIT(vabits_actual - 1))) && !(pgd_val(pgd) & PGD_APT)) ++ panic("Set IEE pgd U page.\n"); ++ ++ WRITE_ONCE(*((pgd_t *)(__phys_to_iee(__pa_symbol(pgdp)))), pgd); +} -+/** -+* koi_do_switch_to_kernel_pgtbl - switch to kernel pagetable -+*/ -+__koi_code noinline int koi_do_switch_to_kernel_pgtbl(void) ++ ++void __iee_code _iee_set_p4d(unsigned long iee_offset, p4d_t *p4dp, p4d_t p4d) +{ -+ unsigned long curr_ttbr1, asid; -+ // if (!cpu_online(smp_processor_id())) -+ // return 0; -+ asm volatile(" mrs %0, ttbr1_el1\n" : "=r"(curr_ttbr1)); -+ if ((curr_ttbr1 & KOI_SWAPPER_MASK) == -+ (koi_swapper_ttbr1 & KOI_SWAPPER_MASK)) { -+ return 0; -+ } -+ if (((curr_ttbr1 & TTBR_ASID_MASK) >> 48) <= 1) { -+ return 0; ++ if(!(p4d_val(p4d) & PMD_SECT_VALID)) ++ { ++ WRITE_ONCE(*((p4d_t *)((unsigned long)p4dp + (unsigned long)iee_offset)), p4d); ++ return; + } -+ asm volatile("mrs %0, ttbr0_el1\n":"=r"(asid):); -+ asid &= ~USER_ASID_FLAG; -+ asid &= TTBR_ASID_MASK; -+ write_sysreg(koi_swapper_ttbr1 | asid, ttbr1_el1); -+ isb(); -+ asm volatile(ALTERNATIVE("nop; nop; nop", "ic iallu; dsb nsh; isb", -+ ARM64_WORKAROUND_CAVIUM_27456)); -+ return 1; ++ ++ if ((p4d_val(p4d) & PMD_TABLE_BIT) && !check_addr_in_iee_valid(__phys_to_iee(__p4d_to_phys(p4d)))) ++ panic("You can't use non-iee-pgtable\n"); ++ ++ WRITE_ONCE(*((p4d_t *)((unsigned long)p4dp + (unsigned long)iee_offset)), p4d); +} -+#else -+__koi_code noinline unsigned long koi_do_switch_to_ko_pgtbl(void) ++ ++void __iee_code _iee_set_pud(unsigned long iee_offset, pud_t *pudp, pud_t pud) +{ -+ struct koi_mem_hash_node *ko; -+ struct mm_struct *ko_mm; -+ unsigned long addr, ttbr1, asid, pan_flag, current_ttbr1; -+ unsigned long *ptr; -+ int bkt; -+ asm volatile("mrs %0, pan\n" -+ "msr pan, 0x0\n" -+ : "=r"(pan_flag) -+ :); -+ current_ttbr1 = _iee_read_token_ttbr1(current); -+ asm volatile("msr pan, %0\n" : : "r"(pan_flag)); -+ ptr = SHIFT_PERCPU_PTR(koi_irq_current_ttbr1, __kern_my_cpu_offset()); -+ if (current_ttbr1 == 0 && *ptr == 0) -+ return 0; -+ asm volatile(" mrs %0, elr_el1\n" : "=r"(addr)); -+ rcu_read_lock(); -+ hash_for_each_rcu (koi_mem_htbl, bkt, ko, node) { -+ if (ko->mod->init_layout.base != NULL) { -+ if (addr >= (unsigned long)ko->mod->init_layout.base && -+ addr < (unsigned long)(ko->mod->init_layout.base + -+ ko->mod->init_layout.size)) { -+ rcu_read_unlock(); -+ if (current_ttbr1 == ko->ko_ttbr1 || *ptr == ko->ko_ttbr1) { -+ // ko_mm = ko->ko_mm; -+ // koi_check_and_switch_context(ko_mm); -+ // asid = ASID(ko_mm); -+ // ttbr1 = ko->ko_ttbr1; -+ // ttbr1 |= FIELD_PREP(TTBR_ASID_MASK, -+ // asid); -+ return ko->ko_ttbr1; -+ } -+ return 0; -+ } -+ } -+ if (addr >= (unsigned long)ko->mod->core_layout.base && -+ addr < (unsigned long)ko->mod->core_layout.base + -+ ko->mod->core_layout.size) { -+ rcu_read_unlock(); -+ if (current_ttbr1 == ko->ko_ttbr1 || *ptr == ko->ko_ttbr1) { -+ // ko_mm = ko->ko_mm; -+ // koi_check_and_switch_context(ko_mm); -+ // asid = ASID(ko_mm); -+ // ttbr1 = ko->ko_ttbr1; -+ // ttbr1 |= FIELD_PREP(TTBR_ASID_MASK, asid); -+ return ko->ko_ttbr1; -+ } -+ return 0; -+ } ++ if(!(pud_val(pud) & PMD_SECT_VALID)) ++ { ++ WRITE_ONCE(*((pud_t *)((unsigned long)pudp + (unsigned long)iee_offset)), pud); ++ return; + } -+ rcu_read_unlock(); -+ return 0; ++ ++ if ((pud_val(pud) & PMD_TABLE_BIT) && !check_addr_in_iee_valid(__phys_to_iee(__pud_to_phys(pud)))) ++ panic("You can't use non-iee-pgtable\n"); ++ ++ WRITE_ONCE(*((pud_t *)((unsigned long)pudp + (unsigned long)iee_offset)), pud); +} + -+__koi_code noinline int koi_do_switch_to_kernel_pgtbl(void) ++// Return true if the modify does not break DEP. ++static inline bool check_pmd_dep(char *addr, pmd_t pmd) +{ -+ unsigned long curr_ttbr1; -+ // if (!cpu_online(smp_processor_id())) -+ // return 0; -+ asm volatile(" mrs %0, ttbr1_el1\n" : "=r"(curr_ttbr1)); -+ if ((curr_ttbr1 & KOI_SWAPPER_MASK) == -+ (koi_swapper_ttbr1 & KOI_SWAPPER_MASK)) { -+ return 0; -+ } -+ if (((curr_ttbr1 & TTBR_ASID_MASK) >> 48) <= 1) { -+ return 0; ++ // DEP for kernel code and readonly data ++ // _text: .text start addr, __init_begin: .rodata end addr ++ if (addr >= _stext && addr < _etext) ++ { ++ if ((PTE_WRITE & pmd_val(pmd)) || // DBM == 1 --> writable ++ !(PTE_RDONLY & pmd_val(pmd))) // DBM == 0 && AP[2] = 0 --> writable ++ { ++ panic("Can't make kernel's text/readonly page as writable!\n" ++ "addr = 0x%16llx, pmd_val = 0x%16llx", ++ (u64)addr, pmd_val(pmd)); ++ } + } -+ iee_rwx_gate_entry(IEE_SWITCH_TO_KERNEL); -+ return 1; -+} -+#endif -+/** -+* koi_save_ttbr - save ttbr of each driver module -+* @mod: driver module -+* @pgdp:pointer to driver module top page table,pgd -+*/ -+static void koi_save_ttbr(struct module *mod, pgd_t *pgdp, -+ struct koi_mem_hash_node *node) -+{ -+ phys_addr_t ttbr1 = phys_to_ttbr(virt_to_phys(pgdp)); -+ if (system_supports_cnp()) -+ ttbr1 |= TTBR_CNP_BIT; -+ node->ko_ttbr1 = ttbr1; ++ return true; +} -+/** -+*kio_normal_page - to obtain the pointer of the corresponding struct page structure -+*from a given page table entry(pte) -+*/ -+struct page *koi_normal_page(pte_t pte) -+{ -+ unsigned long pfn = pte_pfn(pte); + -+ if (IS_ENABLED(CONFIG_ARCH_HAS_PTE_SPECIAL)) { -+ if (likely(!pte_special(pte))) -+ goto check_pfn; -+ if (is_zero_pfn(pfn)) { -+ printk(KERN_ERR "zero pfn found! pte=0x%16lx\n", pte); -+ return NULL; -+ } -+ if (pte_devmap(pte)) { -+ printk(KERN_ERR "pte for dev found! pte=0x%16lx\n", -+ pte); -+ return NULL; ++// Return true if the pmd table is a part of kernel page table. ++// TODO : Optimize to get lower overhead. ++static inline bool is_kernel_pmd_table(pmd_t *pmdp, pmd_t pmd) ++{ ++ int i = 0,j = 0; ++ for(i = 0; i < PAGE_SIZE/sizeof(pgd_t); i++) ++ { ++ pgd_t *pgdp = (pgd_t *)swapper_pg_dir + i; ++ if((pgd_val(*pgdp) & PMD_SECT_VALID) && (pgd_val(*pgdp) & PMD_TABLE_BIT)) ++ { ++ for(j = 0; j < PAGE_SIZE/sizeof(pud_t); j++) ++ { ++ pud_t *pudp = (pud_t *)__va(__pgd_to_phys(*pgdp)) + i; ++ if((pud_val(*pudp) & PMD_SECT_VALID) && (pud_val(*pudp) & PMD_TABLE_BIT)) ++ { ++ pmd_t *current_pmdp = __va(__pud_to_phys(*pudp)); ++ if((unsigned long)current_pmdp == ((unsigned long)pmdp & PAGE_MASK)) ++ return true; ++ } ++ } + } -+ return NULL; + } -+ -+check_pfn: -+ return pfn_to_page(pfn); ++ return false; +} + -+/** -+ * Copy one pte. Returns 0 if succeeded, or -EAGAIN if one preallocated page -+ * is required to copy this pte. -+*/ -+static inline int koi_copy_present_pte(pte_t *dst_pte, pte_t *src_pte, -+ unsigned long addr, -+ struct page **prealloc) ++// Return true if it is mapped to a physical range containing IEE page. ++// TODO : Optimize to get lower overhead. ++static inline bool check_addr_range_in_iee_valid(pmd_t pmd) +{ -+ pte_t pte = *src_pte; -+ struct page *page; ++ int i = 0; ++ unsigned long addr = __phys_to_iee(__pmd_to_phys(pmd)); ++ pgd_t *pgdir = swapper_pg_dir; + -+ page = koi_normal_page(pte); -+ if (!page) { -+ printk(KERN_ERR "pte_page unavailable. Impossible.....\n"); -+ return -1; -+ } ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ pud_t *pudp; ++ pmd_t *pmdp; ++ pte_t *ptep; + -+ set_pte(dst_pte, pte); -+ return 0; -+} -+/** -+* copy huge pmd from kernel space to driver space. -+*/ -+static int koi_copy_huge_pmd(struct mm_struct *ko_mm, pmd_t *dst_pmd, -+ pmd_t *src_pmd, unsigned long addr) -+{ -+ spinlock_t *src_ptl; -+ pmd_t pmd; -+ int ret = -ENOMEM; ++ if(!(p4d_val(READ_ONCE(*p4dp)) & PTE_VALID)) ++ return false; + -+ src_ptl = pmd_lockptr(&init_mm, src_pmd); -+ spin_lock_bh(src_ptl); ++ pudp = pud_offset(p4dp, addr); + -+ ret = -EAGAIN; -+ pmd = *src_pmd; ++ if(!(pud_val(READ_ONCE(*pudp)) & PTE_VALID)) ++ return false; + -+ set_pte((pte_t *)dst_pmd, pmd_pte(pmd)); -+ ret = 0; -+ spin_unlock_bh(src_ptl); -+ return ret; -+} ++ pmdp = pmd_offset(pudp, addr); + -+int __koi_pte_alloc(struct mm_struct *mm, pmd_t *pmd) -+{ -+ spinlock_t *ptl; -+ pgtable_t new = pte_alloc_one(mm); -+ if (!new) -+ return -ENOMEM; ++ if(!(pmd_val(READ_ONCE(*pmdp)) & PTE_VALID)) ++ return false; + -+ /* -+ * Ensure all pte setup (eg. pte page lock and page clearing) are -+ * visible before the pte is made visible to other CPUs by being -+ * put into page tables. -+ * -+ * The other side of the story is the pointer chasing in the page -+ * table walking code (when walking the page table without locking; -+ * ie. most of the time). Fortunately, these data accesses consist -+ * of a chain of data-dependent loads, meaning most CPUs (alpha -+ * being the notable exception) will already guarantee loads are -+ * seen in-order. See the alpha page table accessors for the -+ * smp_rmb() barriers in page table walking code. -+ */ -+ smp_wmb(); /* Could be smp_wmb__xxx(before|after)_spin_lock */ ++ ptep = pte_offset_kernel(pmdp, addr); + -+ ptl = pmd_lockptr(mm, pmd); -+ spin_lock_bh(ptl); -+ if (likely(pmd_none(*pmd))) { /* Has another populated it ? */ -+ #ifdef CONFIG_PTP -+ pte_t *pte = (pte_t *)page_address(new); -+ unsigned long iee_addr = __phys_to_iee(__pa(pte)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)pte); -+ #endif -+ mm_inc_nr_ptes(mm); -+ pmd_populate(mm, pmd, new); -+ new = NULL; ++ for(i = 0; i < PAGE_SIZE/sizeof(pte_t); i++) ++ { ++ if(pte_val(READ_ONCE(*ptep)) & PTE_VALID) ++ return true; ++ ptep++; + } -+ spin_unlock_bh(ptl); -+ if (new) -+ pte_free(mm, new); -+ return 0; ++ return false; +} + -+#define koi_pte_alloc(mm, pmd) (unlikely(pmd_none(*(pmd))) && __koi_pte_alloc(mm, pmd)) -+ -+#define koi_pte_offset_map_lock(mm, pmd, address, ptlp) \ -+({ \ -+ spinlock_t *__ptl = pte_lockptr(mm, pmd); \ -+ pte_t *__pte = pte_offset_map(pmd, address); \ -+ *(ptlp) = __ptl; \ -+ spin_lock_bh(__ptl); \ -+ __pte; \ -+}) -+ -+#define koi_pte_alloc_map_lock(mm, pmd, address, ptlp) \ -+ (koi_pte_alloc(mm, pmd) ? \ -+ NULL : koi_pte_offset_map_lock(mm, pmd, address, ptlp)) -+ -+/** -+*koi_copy_pte_range - copy pte from kernel space to driver space -+*/ -+static int koi_copy_pte_range(struct mm_struct *ko_mm, pmd_t *dst_pmd, -+ pmd_t *src_pmd, unsigned long addr, -+ unsigned long end) ++void __iee_code _iee_set_pmd(unsigned long iee_offset, pmd_t *pmdp, pmd_t pmd) +{ -+ pte_t *src_pte, *dst_pte; -+ spinlock_t *src_ptl, *dst_ptl; -+ int ret = 0; -+ struct page *prealloc = NULL; -+again: -+ dst_pte = koi_pte_alloc_map_lock(ko_mm, dst_pmd, addr, &dst_ptl); -+ if (!dst_pte) { -+ ret = -ENOMEM; -+ goto out; ++ char * addr = (char *)__phys_to_kimg(__pmd_to_phys(pmd)); ++ ++ if(!(pmd_val(pmd) & PMD_SECT_VALID)) ++ { ++ WRITE_ONCE(*((pmd_t *)((unsigned long)pmdp + (unsigned long)iee_offset)), pmd); ++ return; + } -+ src_pte = pte_offset_map(src_pmd, addr); -+ src_ptl = pte_lockptr(&init_mm, src_pmd); -+ spin_lock_bh(src_ptl); -+ arch_enter_lazy_mmu_mode(); + -+ do { -+ if (pte_none(*src_pte)) -+ continue; -+ if (unlikely(!pte_present(*src_pte))) { -+ continue; -+ } -+ /* koi_copy_present_pte() will clear `*prealloc` if consumed */ -+ ret = koi_copy_present_pte(dst_pte, src_pte, addr, &prealloc); -+ if (unlikely(ret == -EAGAIN)) -+ break; -+ if (unlikely(prealloc)) { -+ put_page(prealloc); -+ prealloc = NULL; -+ } -+ } while (dst_pte++, src_pte++, addr += PAGE_SIZE, addr != end); -+ arch_leave_lazy_mmu_mode(); -+ spin_unlock_bh(src_ptl); -+ spin_unlock_bh(dst_ptl); ++ // Check if the pte table is legally allocated. ++ if ((pmd_val(pmd) & PMD_TABLE_BIT) && !check_addr_in_iee_valid(__phys_to_iee(__pmd_to_phys(pmd)))) ++ panic("You can't use non-iee-pgtable\n"); + -+ if (ret) { -+ WARN_ON_ONCE(ret != -EAGAIN); -+ ret = 0; -+ } -+ if (addr != end) -+ goto again; -+out: -+ if (unlikely(prealloc)) -+ put_page(prealloc); -+ return ret; -+} ++ // Avoid mapping a huge pmd as U page. ++ // if(!(pmd_val(pmd) & PMD_TABLE_BIT) && (pmd_val(pmd) & PMD_SECT_USER) && is_kernel_pmd_table(pmdp, pmd)) ++ // panic("Set a block descriptor in kernel space U page.\n"); + -+int __koi_pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) -+{ -+ spinlock_t *ptl; -+ pmd_t *new = pmd_alloc_one(mm, address); -+ if (!new) -+ return -ENOMEM; ++ // Avoid mapping a huge pmd to IEE physical page. ++ // if(!(pmd_val(pmd) & PMD_TABLE_BIT) && check_addr_range_in_iee_valid(pmd)) ++ // panic("Mapping IEE physical page to a huge pmd.\n"); + -+ smp_wmb(); /* See comment in __pte_alloc */ ++ if(!check_pmd_dep(addr, pmd)) ++ return; + -+ ptl = pud_lockptr(mm, pud); -+ spin_lock_bh(ptl); -+ if (!pud_present(*pud)) { -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr = __phys_to_iee(__pa(new)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)new); -+ #endif -+ mm_inc_nr_pmds(mm); -+ pud_populate(mm, pud, new); -+ } else /* Another has populated it */ -+ pmd_free(mm, new); -+ spin_unlock_bh(ptl); -+ return 0; ++ WRITE_ONCE(*((pmd_t *)((unsigned long)pmdp + (unsigned long)iee_offset)), pmd); +} + -+static inline pmd_t *koi_pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) ++// Return true if the pte table is a part of kernel page table. ++// TODO : Optimize to get lower overhead. ++static inline bool is_kernel_pte_table(pte_t *ptep, pte_t pte) +{ -+ return (unlikely(pud_none(*pud)) && __koi_pmd_alloc(mm, pud, address))? -+ NULL: pmd_offset(pud, address); ++ return false; +} + -+/** -+*kio_copy_pmd_range - copy pmd from kernel to driver space -+*/ -+static inline int koi_copy_pmd_range(struct mm_struct *ko_mm, pud_t *dst_pud, -+ pud_t *src_pud, unsigned long addr, -+ unsigned long end) ++// Return true if it does not change the privilage or add new U page in kernel. ++static inline bool check_privilage_safe(pte_t *ptep, pte_t pte) +{ -+ pmd_t *src_pmd, *dst_pmd; -+ unsigned long next; -+ int err; -+ -+ dst_pmd = koi_pmd_alloc(ko_mm, dst_pud, addr); -+ if (!dst_pmd) { -+ return -ENOMEM; ++ if(!(pte_val(pte) & PTE_VALID)) ++ return true; ++ ++ if((pte_val(*ptep) & PTE_VALID)) ++ { ++ if((pte_val(*ptep) & PTE_USER) != (pte_val(pte) & PTE_USER)) ++ panic("Incorrectly change privilage.\n"); + } -+ src_pmd = pmd_offset(src_pud, addr); -+ do { -+ next = pmd_addr_end(addr, end); -+ // CONFIG_TRANSPARENT_HUGEPAGE is enabled, so we must add copy_huge_pmd -+ if (is_swap_pmd(*src_pmd) || pmd_trans_huge(*src_pmd) || -+ (pmd_devmap(*src_pmd))) { -+ err = koi_copy_huge_pmd(ko_mm, dst_pmd, src_pmd, addr); -+ if (err == -ENOMEM) -+ return -ENOMEM; -+ if (!err) -+ continue; -+ } -+ if (pmd_none_or_clear_bad(src_pmd)) { -+ continue; -+ } -+ if (koi_copy_pte_range(ko_mm, dst_pmd, src_pmd, addr, next)) -+ return -ENOMEM; -+ } while (dst_pmd++, src_pmd++, addr = next, addr != end); -+ return 0; ++ else ++ { ++ if((pte_val(pte) & PTE_USER) && is_kernel_pte_table(ptep, pte)) ++ panic("Add new U page in kernel space.\n"); ++ } ++ return true; +} + -+int __koi_pud_alloc(struct mm_struct *mm, p4d_t *p4d, unsigned long address) ++// TODO : When adding a new executable page, check it for DEP. ++static inline bool safely_adding_new_exec_page(pte_t *ptep, pte_t pte) +{ -+ pud_t *new = pud_alloc_one(mm, address); -+ if (!new) -+ return -ENOMEM; -+ -+ smp_wmb(); /* See comment in __pte_alloc */ -+ -+ spin_lock_bh(&mm->page_table_lock); -+ if (!p4d_present(*p4d)) { -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr = __phys_to_iee(__pa(new)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)new); -+ #endif -+ mm_inc_nr_puds(mm); -+ p4d_populate(mm, p4d, new); -+ } else /* Another has populated it */ -+ pud_free(mm, new); -+ spin_unlock_bh(&mm->page_table_lock); -+ return 0; ++ return true; +} + -+static inline pud_t *koi_pud_alloc(struct mm_struct *mm, p4d_t *p4d, -+ unsigned long address) ++// Return true if it is only changing prot of a pte. ++static inline bool is_changing_pte_prot(pte_t *ptep, pte_t pte) +{ -+ return (unlikely(p4d_none(*p4d)) && __koi_pud_alloc(mm, p4d, address)) ? -+ NULL : pud_offset(p4d, address); ++ if(((pte_val(*ptep) ^ pte_val(pte)) & PTE_ADDR_MASK) == 0) ++ return true; ++ else ++ return false; +} + -+/** -+*koi_copy_pud_range - copy pud from kernel to driver -+*/ -+static inline int koi_copy_pud_range(struct mm_struct *ko_mm, p4d_t *dst_p4d, -+ p4d_t *src_p4d, unsigned long addr, -+ unsigned long end) ++// Return true if the modify does not break DEP. ++static inline bool check_pte_dep(char *addr, pte_t pte) +{ -+ pud_t *src_pud, *dst_pud; -+ unsigned long next; -+ dst_pud = koi_pud_alloc(ko_mm, dst_p4d, addr); -+ if (!dst_pud) -+ return -ENOMEM; -+ src_pud = pud_offset(src_p4d, addr); -+ do { -+ next = pud_addr_end(addr, end); -+ if (pud_trans_huge(*src_pud) || pud_devmap(*src_pud)) { -+ continue; -+ /* fall through */ ++ // DEP for kernel code and readonly data ++ // _text: .text start addr, __init_begin: .rodata end addr ++ if (addr >= _stext && addr < _etext) ++ { ++ if ((PTE_WRITE & pte_val(pte)) // DBM == 1 --> writable ++ || !(PTE_RDONLY & pte_val(pte))) // DBM == 0 && AP[2] = 0 --> writable ++ { ++ panic("Can't make kernel's text/readonly page as writable!\n" ++ "addr = 0x%16llx, pte_val = 0x%16llx", ++ (u64)addr, pte_val(pte)); + } -+ if (pud_none_or_clear_bad(src_pud)) -+ continue; -+ if (koi_copy_pmd_range(ko_mm, dst_pud, src_pud, addr, next)) -+ return -ENOMEM; -+ } while (dst_pud++, src_pud++, addr = next, addr != end); -+ return 0; ++ } ++ return true; +} + -+/** -+* koi_copy_p4d_range - map the kernel pagetable to the driver space level by level -+* @ko_mm: the mm_struct of driver module -+* @dst_pgd: destination pgd -+* @src_pgd: source pgd -+* @addr: the start of address -+* @end: the end of address -+*/ -+static inline int koi_copy_p4d_range(struct mm_struct *ko_mm, pgd_t *dst_pgd, -+ pgd_t *src_pgd, unsigned long addr, -+ unsigned long end) ++void __iee_code _iee_set_pte(unsigned long iee_offset, pte_t *ptep, pte_t pte) +{ -+ p4d_t *src_p4d, *dst_p4d; -+ unsigned long next; -+ dst_p4d = p4d_alloc(ko_mm, dst_pgd, addr); -+ if (!dst_p4d) -+ return -ENOMEM; -+ src_p4d = p4d_offset(src_pgd, addr); -+ do { -+ next = p4d_addr_end(addr, end); -+ if (p4d_none_or_clear_bad(src_p4d)) -+ continue; -+ if (koi_copy_pud_range(ko_mm, dst_p4d, src_p4d, addr, next)) { -+ return -ENOMEM; -+ } -+ } while (dst_p4d++, src_p4d++, addr = next, addr != end); -+ return 0; -+} ++ char * addr = (char *)__phys_to_kimg(__pte_to_phys(pte)); + -+/** -+*int koi_copy_pagetable - map the address range from "addr" to "end" to the driver pagetable -+*@ko_mm: the mm_struct of the driver module -+*@koi_pg_dir: koi_pg_dir, related to the driver module, the entry for driver pagetable -+*@addr: the starting address of mapping zone -+*@end: the end address of mapping zone -+*/ -+int koi_copy_pagetable(struct mm_struct *ko_mm, pgd_t *koi_pg_dir, -+ unsigned long addr, unsigned long end) -+{ -+ int ret = 0; -+ unsigned long next; ++ if(!(pte_val(pte) & PTE_VALID)) ++ { ++ WRITE_ONCE(*((pte_t *)((unsigned long)ptep + (unsigned long)iee_offset)), pte); ++ return; ++ } + -+ pgd_t *src_pgd, *dst_pgd; ++ // Avoid modify privilage unsafely. ++ if(!check_privilage_safe(ptep, pte)) ++ panic("You are modify privilage unsafely.\n"); + -+ src_pgd = pgd_offset_pgd(swapper_pg_dir, addr); -+ dst_pgd = pgd_offset_pgd(koi_pg_dir, addr); -+ do { -+ next = pgd_addr_end(addr, end); -+ if (pgd_none_or_clear_bad(src_pgd)) -+ continue; -+ if (unlikely(koi_copy_p4d_range(ko_mm, dst_pgd, src_pgd, addr, -+ next))) { -+ ret = -ENOMEM; -+ break; -+ } -+ } while (dst_pgd++, src_pgd++, addr = next, addr != end); ++ // Avoid mapping a new executable page. ++ if(!safely_adding_new_exec_page(ptep, pte)) ++ panic("You are adding a new executable page unsafely.\n"); + -+ return ret; ++ // Avoid mapping a new VA to IEE PA. ++ if(!is_changing_pte_prot(ptep, pte) && ++ check_addr_in_iee_valid(__phys_to_iee(__pte_to_phys(pte)))) ++ panic("You are remmaping IEE page to other VA.\n"); ++ ++ // Avoid mapping a writable VA to kernel code PA. ++ if(!check_pte_dep(addr, pte)) ++ return; ++#ifdef CONFIG_KOI ++ if (pte_valid(pte)) ++ pte = __pte(pte_val(pte) | PTE_NG); ++#endif ++ WRITE_ONCE(*((pte_t *)((unsigned long)ptep + (unsigned long)iee_offset)), pte); +} + -+void koi_set_rdonly(unsigned long addr, pgd_t *pgdir) ++static void inline _iee_set_pte_single(pte_t *ptep, pte_t pte, unsigned long iee_offset) +{ -+ p4d_t *p4dp; -+ pud_t *pudp; -+ pmd_t *pmdp; -+ pte_t *ptep; -+ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); -+ if (pgd_none(*pgdp) || pgd_bad(*pgdp)) { -+ return; -+ } ++ char * addr = (char *)__phys_to_kimg(__pte_to_phys(pte)); + -+ p4dp = p4d_offset(pgdp, addr); -+ if (p4d_none(*p4dp) || p4d_bad(*p4dp)) { ++ if(!(pte_val(pte) & PTE_VALID)) ++ { ++ WRITE_ONCE(*((pte_t *)((unsigned long)ptep + (unsigned long)iee_offset)), pte); + return; + } + -+ pudp = pud_offset(p4dp, addr); -+ if (pud_none(*pudp) || pud_bad(*pudp)) { -+ return; -+ } -+ pmdp = pmd_offset(pudp, addr); -+ if (pmd_none(*pmdp) || pmd_bad(*pmdp)) { -+ return; -+ } ++ // Avoid modify privilage unsafely. ++ if(!check_privilage_safe(ptep, pte)) ++ panic("You are modify privilage unsafely.\n"); + -+ ptep = pte_offset_kernel(pmdp, addr); -+ if (pte_none(*ptep)) { -+ printk(KERN_ERR "ptep 0x%llx not available\n", ptep); ++ // Avoid mapping a new executable page. ++ if(!safely_adding_new_exec_page(ptep, pte)) ++ panic("You are adding a new executable page unsafely.\n"); ++ ++ // Avoid mapping a new VA to IEE PA. ++ if(!is_changing_pte_prot(ptep, pte) && ++ check_addr_in_iee_valid(__phys_to_iee(__pte_to_phys(pte)))) ++ panic("You are remmaping IEE page to other VA.\n"); ++ ++ // Avoid mapping a writable VA to kernel code PA. ++ if(!check_pte_dep(addr, pte)) + return; -+ } -+ set_pte(ptep, __pte(pte_val(*ptep) | PTE_RDONLY)); -+ printk(KERN_ERR "set_readonly successfully\n"); -+ return; ++ ++ WRITE_ONCE(*((pte_t *)((unsigned long)ptep + (unsigned long)iee_offset)), pte); +} + -+/** -+* koi_create_pagetable - create pagetable for driver -+* @mod: driver module -+* 1.create a new koi_mem_hash_node new_node -+* 2.create page table return the pgd address, init the new_node->pgdp -+* 3.create and init the new_node->ko_mm -+* 4.map swapper_ttbr1 to the newly created pagetable -+* 5.map the interrupt vector table to the newly created pagetable -+* 6.map the init_layout of the module -+* 7.map the core_layout of the module -+* 8.map switch_to_kernel_pgtable into driver view -+* 9.map share memory -+*/ -+void koi_create_pagetable(struct module *mod) ++void __iee_code _iee_set_stack_pte(unsigned long iee_offset, pte_t *ptep, int order, int use_block_pmd, unsigned long lm_addr) +{ -+ int ret = 0, cpu; -+ unsigned long vbar, addr, ttbr1; -+ pgd_t *pgdp; -+ unsigned long *ptr; -+ struct koi_mem_list *new_mem_node; -+ struct koi_mem_hash_node *new_node = -+ kzalloc(sizeof(struct koi_mem_hash_node), GFP_KERNEL); -+ if (!new_node) { -+ printk(KERN_ERR "NULL new_node\n"); -+ return; -+ }; -+ if (koi_swapper_ttbr1 == 0) { -+ pgdp = lm_alias(swapper_pg_dir); -+ ttbr1 = phys_to_ttbr(virt_to_phys(pgdp)); -+ if (system_supports_cnp() && -+ !WARN_ON(pgdp != lm_alias(swapper_pg_dir))) -+ ttbr1 |= TTBR_CNP_BIT; -+#ifdef CONFIG_IEE -+ ttbr1 |= FIELD_PREP(TTBR_ASID_MASK, 1); -+#endif -+ koi_swapper_ttbr1 = ttbr1; -+ // __WRITE_ONCE(koi_swapper_ttbr1, ttbr1); -+ // koi_set_rdonly(&koi_swapper_ttbr1, swapper_pg_dir); ++ int i; ++ unsigned long iee_addr = lm_addr + iee_offset; ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, iee_addr); ++ p4d_t *p4dp = p4d_offset(pgdp, iee_addr); ++ pud_t *pudp = pud_offset(p4dp, iee_addr); ++ pmd_t *pmdp = pmd_offset(pudp, iee_addr); ++ pte_t *iee_ptep = (pte_t *)(((unsigned long)pte_offset_kernel(pmdp, iee_addr)) + iee_offset); ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) | PTE_VALID); ++ WRITE_ONCE(*iee_ptep, pte); ++ iee_ptep++; + } -+ new_node->pgdp = koi_pgd_alloc(); -+ new_node->ko_mm = -+ kzalloc(sizeof(struct mm_struct) + -+ sizeof(unsigned long) * BITS_TO_LONGS(NR_CPUS), -+ GFP_KERNEL); -+ init_ko_mm(new_node->ko_mm, new_node->pgdp); -+ new_node->mod = mod; -+ koi_save_ttbr(mod, new_node->pgdp, new_node); -+ printk(KERN_ERR "copying koi_data, start=0x%16llx, end=0x%16llx\n", -+ (unsigned long)__koi_data_start, (unsigned long)__koi_data_end); -+ // copy koi_swapper_ttbr1, which records page dir base for kernel view -+ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, -+ (unsigned long)__koi_data_start, -+ (unsigned long)__koi_data_end); -+ asm volatile("mrs %0, VBAR_EL1\n" : "=r"(vbar) :); -+ -+ // copy interrupt vectors -+ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, vbar & PAGE_MASK, -+ (vbar + PAGE_SIZE) & PAGE_MASK); -+ -+ // copy module init_layout, which contains init data and text in driver -+ ret = koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, -+ (unsigned long)mod->init_layout.base, -+ (unsigned long)mod->init_layout.base + -+ mod->init_layout.size); -+ if (ret != 0) -+ printk(KERN_ERR -+ "\033[33mError occur when copying init_layout, Eno:%d\033[0m\n", -+ ret); -+ -+ // copy module core_layout, which contains non-init data and text in driver -+ ret = koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, -+ (unsigned long)mod->core_layout.base, -+ (unsigned long)mod->core_layout.base + -+ mod->core_layout.size); -+ if (ret != 0) -+ printk(KERN_ERR -+ "\033[33mError occur when copying core_layout, Eno: %d\033[0m\n", -+ ret); -+ -+ // mapping switch_to_kernel_pgtable into driver view, which is used to switch to kernel view when entering INT -+ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, -+ (unsigned long)__koi_code_start, -+ (unsigned long)__koi_code_end); + -+ for_each_possible_cpu (cpu) { -+ ptr = per_cpu(irq_stack_ptr, cpu); -+ printk(KERN_ERR -+ "\033[33mirq_stack_ptr on cpu %d addr=0x%16llx, end=0x%16llx\033[0m\n", -+ cpu, (unsigned long)ptr, -+ (unsigned long)ptr + IRQ_STACK_SIZE); -+ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, -+ (unsigned long)ptr, -+ (unsigned long)ptr + IRQ_STACK_SIZE); ++ ptep = (pte_t *)((unsigned long)ptep + iee_offset); ++ if(use_block_pmd) ++ { ++ pmd_t *pmdp = (pmd_t *)ptep; ++ pmd_t pmd = READ_ONCE(*pmdp); ++ pmd = __pmd(pmd_val(pmd) & ~PTE_VALID); ++ WRITE_ONCE(*pmdp, pmd); + } -+ -+ for_each_possible_cpu (cpu) { -+ ptr = per_cpu(koi_irq_current_ttbr1, cpu); -+ printk(KERN_ERR -+ "\033[33mirq_current_ptr on cpu %d addr=0x%16llx, end=0x%16llx\033[0m\n", -+ cpu, (unsigned long)ptr, (unsigned long)ptr + PAGE_SIZE); -+ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, -+ (unsigned long)ptr, -+ (unsigned long)ptr + PAGE_SIZE); ++ else ++ { ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(pte_val(pte) & ~PTE_VALID); ++ WRITE_ONCE(*ptep, pte); ++ ptep++; ++ } + } ++} + -+#ifdef CONFIG_IEE -+ // mapping iee_rwx_gate_entry and iee_si_base to ko's pagetable -+ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, -+ (unsigned long)__iee_si_base_start, -+ (unsigned long)__iee_exec_entry_end); -+#endif -+ -+ // alloc 16KB memory for new ko, and add it into hashtable -+ addr = (unsigned long)kmalloc(THREAD_SIZE, GFP_KERNEL); -+ if ((void *)addr == NULL) { -+ printk(KERN_ERR "alloc buffer error\n"); ++void __iee_code _iee_unset_stack_pte(unsigned long iee_offset, pte_t *ptep, int order, int use_block_pmd, unsigned long lm_addr) ++{ ++ int i; ++ unsigned long iee_addr = lm_addr + iee_offset; ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, iee_addr); ++ p4d_t *p4dp = p4d_offset(pgdp, iee_addr); ++ pud_t *pudp = pud_offset(p4dp, iee_addr); ++ pmd_t *pmdp = pmd_offset(pudp, iee_addr); ++ pte_t *iee_ptep = (pte_t *)(((unsigned long)pte_offset_kernel(pmdp, iee_addr)) + iee_offset); ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*iee_ptep); ++ pte = __pte(pte_val(pte) & ~PTE_VALID); ++ WRITE_ONCE(*iee_ptep, pte); ++ iee_ptep++; + } -+ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, addr, -+ addr + THREAD_SIZE); + -+ new_mem_node = kmalloc(sizeof(struct koi_mem_list), GFP_KERNEL); -+ if (new_mem_node == NULL) { -+ printk(KERN_ERR "alloc new_mem_node error\n"); ++ ptep = (pte_t *)((unsigned long)ptep + iee_offset); ++ if(use_block_pmd) ++ { ++ pmd_t *pmdp = (pmd_t *)ptep; ++ pmd_t pmd = READ_ONCE(*pmdp); ++ pmd = __pmd(pmd_val(pmd) | PTE_VALID); ++ WRITE_ONCE(*pmdp, pmd); + } -+ new_mem_node->addr = addr; -+ new_mem_node->size = THREAD_SIZE; ++ else ++ { ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(pte_val(pte) | PTE_VALID); ++ WRITE_ONCE(*ptep, pte); ++ ptep++; ++ } ++ } ++} + -+ new_node->mem_list_head = -+ (struct list_head)LIST_HEAD_INIT(new_node->mem_list_head); -+ hash_init(new_node->addr_htbl); -+ spin_lock_init(&new_node->addr_htbl_spin_lock); -+ spin_lock_init(&new_node->spin_lock); ++void __iee_code _iee_set_bm_pte(unsigned long iee_offset, pte_t *ptep, pte_t pte) ++{ ++#ifdef CONFIG_KOI ++ if (pte_valid(pte)) ++ pte = __pte(pte_val(pte) | PTE_NG); ++#endif ++ WRITE_ONCE(*((pte_t *)(__phys_to_iee(__pa_symbol(ptep)))), pte); ++} + -+ spin_lock(&new_node->spin_lock); -+ list_add_rcu(&new_mem_node->list, &new_node->mem_list_head); -+ spin_unlock(&new_node->spin_lock); ++/* Data in iee_si_base is visible to all pgd while iee_si_data is private. */ ++unsigned long iee_base_swapper_pg_dir __iee_si_data; ++unsigned long iee_base_idmap_pg_dir __iee_si_data; ++unsigned long iee_base_reserved_pg_dir __iee_si_data; ++unsigned long iee_base__bp_harden_el1_vectors __iee_si_data; ++bool iee_init_done __iee_si_data; ++unsigned long iee_si_tcr __iee_si_data; ++s64 iee_si_offset __iee_si_data; + -+ spin_lock(&koi_mem_htbl_spin_lock); -+ hash_add_rcu(koi_mem_htbl, &new_node->node, -+ (unsigned long)new_node->mod); -+ spin_unlock(&koi_mem_htbl_spin_lock); -+} -+/** -+* koi_mem_alloc -+*@mod: driver module -+*@orig_addr: the starting address of the parameter in kernel -+*@size: the size of the parameter -+*/ -+unsigned long koi_mem_alloc(struct module *mod, unsigned long orig_addr, -+ unsigned long size) ++static u64 __iee_si_code inline iee_si_mask(unsigned long mask, unsigned long new_val, unsigned long old_val) +{ -+ struct koi_mem_hash_node *target = NULL; -+ struct koi_mem_list *mem_node; -+ struct koi_addr_map *new_addr_node; -+ unsigned long addr = 0, flags; -+ struct koi_mem_list *new_mem_node; -+ rcu_read_lock(); -+ hash_for_each_possible_rcu (koi_mem_htbl, target, node, -+ (unsigned long)mod) { -+ if (target->mod == mod) { -+ break; -+ } -+ } -+ rcu_read_unlock(); -+ if (target == NULL) { -+ printk(KERN_ERR "mem node for module: %s not found\n", -+ mod->name); -+ return 0; -+ } -+ spin_lock_irqsave(&target->spin_lock, flags); -+ list_for_each_entry_rcu (mem_node, &target->mem_list_head, list) { -+ if (mem_node->size >= size) { -+ addr = mem_node->addr; -+ mem_node->size -= size; -+ if (mem_node->size == 0) { -+ list_del_rcu(&mem_node->list); -+ } else { -+ new_mem_node = -+ kmalloc(sizeof(struct koi_mem_list), -+ GFP_ATOMIC); -+ new_mem_node->addr = addr + size; -+ new_mem_node->size = mem_node->size; -+ list_replace_rcu(&mem_node->list, -+ &new_mem_node->list); -+ } -+ call_rcu(&mem_node->rcu, koi_mem_node_free); -+ } -+ } -+ spin_unlock_irqrestore(&target->spin_lock, flags); -+ if (!addr) { -+ addr = (unsigned long)kmalloc(THREAD_SIZE, GFP_KERNEL); -+ if ((void *)addr == NULL) { -+ return 0; -+ } -+ koi_copy_pagetable(target->ko_mm, target->pgdp, addr, -+ addr + THREAD_SIZE); -+ mem_node = kmalloc(sizeof(struct koi_mem_list), GFP_KERNEL); -+ if (!mem_node) { -+ printk(KERN_ERR "NULL mem_node\n"); -+ } -+ if (size > THREAD_SIZE) { -+ return 0; -+ } -+ mem_node->addr = addr + size; -+ mem_node->size = THREAD_SIZE - size; -+ spin_lock_irqsave(&target->spin_lock, flags); -+ list_add_tail_rcu(&mem_node->list, &target->mem_list_head); -+ spin_unlock_irqrestore(&target->spin_lock, flags); -+ } -+ -+ new_addr_node = kzalloc(sizeof(struct koi_addr_map), GFP_KERNEL); -+ new_addr_node->buffer_addr = addr; -+ new_addr_node->orig_addr = orig_addr; -+ spin_lock_irqsave(&target->addr_htbl_spin_lock, flags); -+ hash_add_rcu(target->addr_htbl, &new_addr_node->node, -+ new_addr_node->buffer_addr); -+ spin_unlock_irqrestore(&target->addr_htbl_spin_lock, flags); -+ return addr; ++ return (new_val & mask) | (old_val & ~mask); +} -+EXPORT_SYMBOL(koi_mem_alloc); -+// find the parameter pointer corresponding to the copy -+noinline void *koi_mem_lookup(struct module *mod, unsigned long addr) ++/* ++ * handler function for requests of executing sensitive instrutions. ++ */ ++u64 __iee_si_code iee_si_handler(int flag, ...) +{ -+ struct koi_mem_hash_node *target = NULL; -+ struct koi_addr_map *addr_map_node; -+ unsigned long orig_addr = addr; -+ rcu_read_lock(); -+ hash_for_each_possible_rcu (koi_mem_htbl, target, node, -+ (unsigned long)mod) { -+ if (target->mod == mod) { -+ break; -+ } -+ } -+ rcu_read_unlock(); -+ if (target == NULL) { -+ printk(KERN_ERR "mem node for module: %s not found\n", -+ mod->name); -+ return NULL; -+ } ++ va_list pArgs; ++ u64 old_val, new_val; + -+ rcu_read_lock(); -+ hash_for_each_possible_rcu (target->addr_htbl, addr_map_node, node, -+ orig_addr) { -+ if (addr_map_node->buffer_addr == addr) { ++ // BUG_ON(flag > IEE_WRITE_MDSCR); ++ va_start(pArgs, flag); ++ switch (flag) { ++ case IEE_SI_TEST: + break; -+ } -+ } -+ rcu_read_unlock(); -+ if (addr_map_node) { -+ return (void *)(addr_map_node->orig_addr); -+ } else { -+ return NULL; -+ } -+} -+EXPORT_SYMBOL(koi_mem_lookup); -+/** -+* kio_mem_free - recycle a copy of the copied parameters and synchronize the parameters -+* @mod: driver module -+* @addr: the starting addr of parameter -+* @size: the size of the parameter -+* @is_const: const pointers or not -+* @count: contry the number of parameters -+*/ -+noinline void koi_mem_free(struct module *mod, unsigned long addr, -+ unsigned long size, bool is_const, int count, ...) -+{ -+ struct koi_mem_hash_node *target = NULL; -+ struct koi_mem_list *mem_node; -+ struct list_head *pos = NULL; -+ struct koi_addr_map *addr_map_node; -+ unsigned long orig_size = size; -+ unsigned long orig_addr = addr; -+ va_list valist; -+ int i; -+ unsigned int offset; -+ unsigned long flags; -+ rcu_read_lock(); -+ hash_for_each_possible_rcu (koi_mem_htbl, target, node, -+ (unsigned long)mod) { -+ if (target->mod == mod) { -+ break; -+ } -+ } -+ rcu_read_unlock(); -+ if (target == NULL) { -+ printk(KERN_ERR "mem node for module: %s not found\n", -+ mod->name); -+ return; -+ } -+ -+ rcu_read_lock(); -+ hash_for_each_possible_rcu (target->addr_htbl, addr_map_node, node, -+ orig_addr) { -+ if (addr_map_node->buffer_addr == orig_addr) { -+ break; -+ } -+ } -+ rcu_read_unlock(); -+ va_start(valist, count); -+ for (i = 0; i < count; i++) { -+ offset = va_arg(valist, int); -+ *(unsigned long *)(addr_map_node->buffer_addr + offset) = -+ *(unsigned long *)(addr_map_node->orig_addr + offset); -+ } -+ va_end(valist); -+ memcpy((void *)addr_map_node->orig_addr, -+ (void *)addr_map_node->buffer_addr, orig_size); ++ case IEE_WRITE_SCTLR: { ++ old_val = read_sysreg(sctlr_el1); ++ new_val = va_arg(pArgs, u64); ++ new_val = iee_si_mask(IEE_SCTLR_MASK, new_val, old_val); ++ write_sysreg(new_val, sctlr_el1); ++ break; ++ } ++ case IEE_WRITE_TTBR0: ++ case IEE_CONTEXT_SWITCH: { ++ u64 new_asid, new_phys, old_phys, token_phys; ++ struct task_struct *tsk; ++ struct task_token *token; ++ new_val = va_arg(pArgs, u64); ++ new_phys = (new_val & PAGE_MASK) & ~TTBR_ASID_MASK; ++ new_asid = new_val >> 48; + -+ spin_lock_irqsave(&target->addr_htbl_spin_lock, flags); -+ hlist_del_init_rcu(&addr_map_node->node); -+ call_rcu(&addr_map_node->rcu, koi_addr_map_node_free); -+ spin_unlock_irqrestore(&target->addr_htbl_spin_lock, flags); ++ // Check ASID first ++ if (new_phys == iee_base_reserved_pg_dir){ ++ if (new_asid != 1) ++ panic("IEE SI warning: reserved_pg_dir ASID invalid: %llx:%llx", new_asid, new_val); ++ } ++ // Already reserved asid 1 for iee rwx gate. ++ else if (new_asid == 0){ ++ new_val |= FIELD_PREP(TTBR_ASID_MASK, 1); ++ printk("IEE SI: Modify ASID of %llx to 1.", new_val); ++ } ++ // TO DO: operations to protect idmap_pg_dir ++ else if (new_phys == iee_base_idmap_pg_dir) ++ { ++ // printk("IEE SI: switch to idmap_pg_dir.); ++ } ++ else if (new_asid % 2 ==0) ++ panic("IEE SI warning: TTBR0 ASID invalid: %llx:%llx", new_asid, new_val); + -+ spin_lock_irqsave(&target->spin_lock, flags); -+ list_for_each_entry_rcu (mem_node, &target->mem_list_head, list) { -+ if (mem_node->addr + mem_node->size == addr) { -+ pos = mem_node->list.prev; -+ addr = mem_node->addr; -+ size += mem_node->size; -+ list_del_rcu(&mem_node->list); -+ call_rcu(&mem_node->rcu, koi_mem_node_free); -+ } else if (addr + size == mem_node->addr) { -+ if (!pos) -+ pos = mem_node->list.prev; -+ size += mem_node->size; -+ list_del_rcu(&mem_node->list); -+ call_rcu(&mem_node->rcu, koi_mem_node_free); -+ } else if (addr + size < mem_node->addr) { -+ if (!pos) -+ pos = mem_node->list.prev; -+ break; -+ } -+ } -+ mem_node = kzalloc(sizeof(struct koi_mem_list), GFP_ATOMIC); -+ mem_node->addr = addr; -+ mem_node->size = size; -+ if (pos) -+ list_add_rcu(&mem_node->list, pos); -+ else -+ list_add_tail_rcu(&mem_node->list, &target->mem_list_head); -+ spin_unlock_irqrestore(&target->spin_lock, flags); ++ /* Skip verification if iee hasn't been initialized. */ ++ if (iee_init_done){ ++ // Verify current sp_el0 with iee token info ++ asm volatile("mrs %x0, sp_el0":"=r"(tsk)); ++ token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); ++ ++ /* ++ * token->pgd != NULL means it is a user task, then we need to check whether current ttbr0 is correct. ++ */ ++ if (token->pgd){ ++ old_val = read_sysreg(ttbr0_el1); ++ // When TTBR0 is reserved_pg_dir then no checking is available. ++ if (old_val != iee_base_reserved_pg_dir){ ++ old_phys = (old_val & PAGE_MASK) & ~TTBR_ASID_MASK; ++ token_phys = __pa(token->pgd); ++ if (old_phys != token_phys) ++ panic("IEE SI warning: Pgd set error. old ttbr0:%lx, token ttbr0:%lx, token pgd:%lx", ++ (unsigned long)old_phys, (unsigned long)token_phys, (unsigned long)(token->pgd)); ++ } ++ } ++ } ++ // all checks are done. ++ write_sysreg(new_val, ttbr0_el1); ++ ++ // SET ASID in TTBR1 when context switch ++ if (flag == IEE_CONTEXT_SWITCH){ ++ new_val = (read_sysreg(ttbr1_el1) & ~TTBR_ASID_MASK) | FIELD_PREP(TTBR_ASID_MASK, new_asid-1); ++ write_sysreg(new_val, ttbr1_el1); ++ } ++ break; ++ } ++ case IEE_WRITE_VBAR: { ++ u64 el1_vector; ++ new_val = va_arg(pArgs, u64); ++ el1_vector = iee_base__bp_harden_el1_vectors; ++ if(new_val == el1_vector || new_val == el1_vector+SZ_2K || ++ new_val == el1_vector+SZ_2K*2 || new_val == el1_vector+SZ_2K*3) ++ write_sysreg(new_val, vbar_el1); ++ break; ++ } ++ case IEE_WRITE_TCR: { ++ old_val = read_sysreg(tcr_el1); ++ new_val = va_arg(pArgs, u64); ++ new_val = iee_si_mask(IEE_TCR_MASK, new_val, old_val); ++ write_sysreg(new_val, tcr_el1); ++ break; ++ } ++ } ++ va_end(pArgs); ++ return 0; +} -+EXPORT_SYMBOL(koi_mem_free); -+/** -+* koi_mem_free_callback - used to recycle the copy of parameter. -+*@addr: the address of the parameter -+*@(*func)(void*): callback func, used to release the copy of the parameter pointer -+*/ -+noinline void koi_mem_free_callback(struct module *mod, unsigned long addr, -+ unsigned long size, void (*func)(void *)) -+{ -+ struct koi_mem_hash_node *target = NULL; -+ struct koi_mem_list *mem_node; -+ struct list_head *pos = NULL; -+ struct koi_addr_map *addr_map_node; -+ unsigned long flags; -+ unsigned long orig_size = size; -+ unsigned long orig_addr = addr; -+ rcu_read_lock(); -+ hash_for_each_possible_rcu (koi_mem_htbl, target, node, -+ (unsigned long)mod) { -+ if (target->mod == mod) { -+ break; -+ } -+ } -+ rcu_read_unlock(); -+ if (target == NULL) { -+ printk("mem node for module: %s not found\n", mod->name); -+ return; -+ } ++/* ++ * TODO: scan a page to check whether it contains sensitive instructions ++ * return 1 when finding sensitive inst, 0 on safe page. ++ */ ++int iee_si_scan_page(unsigned long addr); ++#endif +\ No newline at end of file +diff --git a/arch/arm64/kernel/iee/pgtable_slab.c b/arch/arm64/kernel/iee/pgtable_slab.c +new file mode 100644 +index 000000000000..1f98d639a315 +--- /dev/null ++++ b/arch/arm64/kernel/iee/pgtable_slab.c +@@ -0,0 +1,97 @@ ++#include ++#include + -+ rcu_read_lock(); -+ hash_for_each_possible_rcu (target->addr_htbl, addr_map_node, node, -+ orig_addr) { -+ if (addr_map_node->buffer_addr == orig_addr) { -+ break; -+ } -+ } -+ rcu_read_unlock(); -+ if (addr_map_node != NULL) { -+ memcpy((void *)addr_map_node->orig_addr, -+ (void *)addr_map_node->buffer_addr, orig_size); -+ func((void *)addr_map_node->orig_addr); -+ } else { -+ printk("Cannot find addr_map_node in addr_htbl, maybe addr is in kernel space!!\n"); -+ func((void *)orig_addr); -+ } ++#define PGTABLE_INIT_ORDER 7 ++struct kmem_cache *pgtable_jar; ++struct kmem_cache *ptdesc_jar; ++extern void iee_set_freeptr(void **pptr, void *ptr); ++unsigned long pgtable_jar_offset; + -+ spin_lock_irqsave(&target->addr_htbl_spin_lock, flags); -+ if (addr_map_node != NULL) { -+ hlist_del_init_rcu(&addr_map_node->node); -+ call_rcu(&addr_map_node->rcu, koi_addr_map_node_free); -+ } -+ spin_unlock_irqrestore(&target->addr_htbl_spin_lock, flags); -+ spin_lock_irqsave(&target->spin_lock, flags); -+ list_for_each_entry_rcu (mem_node, &target->mem_list_head, list) { -+ if (mem_node->addr + mem_node->size == addr) { -+ pos = mem_node->list.prev; -+ addr = mem_node->addr; -+ size += mem_node->size; -+ list_del_rcu(&mem_node->list); -+ call_rcu(&mem_node->rcu, koi_mem_node_free); -+ } else if (addr + size == mem_node->addr) { -+ if (!pos) -+ pos = mem_node->list.prev; -+ size += mem_node->size; -+ list_del_rcu(&mem_node->list); -+ call_rcu(&mem_node->rcu, koi_mem_node_free); -+ } else if (addr + size < mem_node->addr) { -+ if (!pos) -+ pos = mem_node->list.prev; -+ break; -+ } -+ } -+ mem_node = kzalloc(sizeof(struct koi_mem_list), GFP_ATOMIC); -+ mem_node->addr = addr; -+ mem_node->size = size; -+ if (pos) -+ list_add_rcu(&mem_node->list, pos); -+ else -+ list_add_tail_rcu(&mem_node->list, &target->mem_list_head); -+ spin_unlock_irqrestore(&target->spin_lock, flags); ++#ifdef CONFIG_PTP ++extern void early_pgtable_jar_alloc(struct kmem_cache *pgtable_jar); ++void __init iee_pmd_pgtable_init(pud_t *pud) { ++ struct page *page; ++ struct ptdesc_t *tmp; ++ pmd_t *orig_pmd = pud_pgtable(*pud); ++ pmd_t *pmd; ++ int i; ++ ++ for (i = 0; i < PTRS_PER_PMD; i++) { ++ pmd = orig_pmd + i; ++ if (pmd_none(*pmd) || pmd_bad(*pmd)) ++ continue; ++ page = pmd_page(*pmd); ++ tmp = kmem_cache_alloc(ptdesc_jar, GFP_KERNEL | __GFP_ZERO); ++ spin_lock_init(&tmp->ptl); ++ ((struct slab_t *)page)->slab_cache = (struct kmem_cache *)tmp; ++ ((struct ptdesc_t *)(((struct slab_t *)page)->slab_cache))->slab = (struct slab_t *)page; ++ } +} -+EXPORT_SYMBOL(koi_mem_free_callback); + -+void koi_map_mem(struct module *mod, unsigned long addr, unsigned long size) ++void __init iee_pud_pgtable_init(p4d_t *p4d) { ++ struct page *page; ++ struct ptdesc_t *tmp; ++ pud_t *orig_pud = p4d_pgtable(*p4d); ++ pud_t *pud; ++ int i; ++ ++ for (i = 0; i < PTRS_PER_PUD; i++) { ++ pud = orig_pud + i; ++ if (pud_none(*pud) || pud_bad(*pud)) ++ continue; ++ iee_pmd_pgtable_init(pud); ++ page = pud_page(*pud); ++ tmp = kmem_cache_alloc(ptdesc_jar, GFP_KERNEL | __GFP_ZERO); ++ spin_lock_init(&tmp->ptl); ++ ((struct slab_t *)page)->slab_cache = (struct kmem_cache *)tmp; ++ ((struct ptdesc_t *)(((struct slab_t *)page)->slab_cache))->slab = (struct slab_t *)page; ++ } ++} ++ ++void __init iee_pgtable_init(void) +{ -+ struct koi_mem_hash_node *target = NULL; -+ rcu_read_lock(); -+ hash_for_each_possible_rcu (koi_mem_htbl, target, node, -+ (unsigned long)mod) { -+ if (target->mod == mod) -+ break; -+ } -+ rcu_read_unlock(); ++ int i; ++ pgd_t *pgd; ++ struct page* page; ++ struct ptdesc_t *tmp; + -+ if (target == NULL) { -+ printk(KERN_ERR "mem node for module: %s not found\n", -+ mod->name); -+ return; -+ } -+ koi_copy_pagetable(target->ko_mm, target->pgdp, addr & PAGE_MASK, -+ (addr + size + PAGE_SIZE) & PAGE_MASK); ++ ptdesc_jar = kmem_cache_create("ptdesc_jar", sizeof(struct ptdesc_t), 0, SLAB_PANIC|SLAB_RED_ZONE, NULL); ++ pgtable_jar = kmem_cache_create("pgtable_jar", PAGE_SIZE, PAGE_SIZE, ++ SLAB_PANIC, NULL); ++ for(i = 0; i < ((1 << (PGTABLE_INIT_ORDER))/nr_cpu_ids); i++) ++ { ++ early_pgtable_jar_alloc(pgtable_jar); ++ } ++ for (i = 0; i < PTRS_PER_PGD; i++) { ++ pgd = swapper_pg_dir + i; ++ if (p4d_none_or_clear_bad((p4d_t *)pgd)) ++ continue; ++ iee_pud_pgtable_init((p4d_t *)pgd); ++ page = pgd_page(*pgd); ++ tmp = kmem_cache_alloc(ptdesc_jar, GFP_KERNEL | __GFP_ZERO); ++ spin_lock_init(&tmp->ptl); ++ ((struct slab_t *)page)->slab_cache = (struct kmem_cache *)tmp; ++ ((struct ptdesc_t *)(((struct slab_t *)page)->slab_cache))->slab = (struct slab_t *)page; ++ } +} -+EXPORT_SYMBOL(koi_map_mem); -+/** -+* koi_mem_free_to_user - function 'copy_to_user' in driver space -+*/ -+void koi_mem_free_to_user(struct module *mod, unsigned long addr, -+ unsigned long size) ++#else ++void __init iee_pgtable_init(void) +{ -+ struct koi_mem_hash_node *target = NULL; -+ struct koi_mem_list *mem_node; -+ struct list_head *pos = NULL; -+ struct koi_addr_map *addr_map_node; -+ unsigned long flags; -+ unsigned long orig_size = size; -+ unsigned long orig_addr = addr; -+ rcu_read_lock(); -+ hash_for_each_possible_rcu (koi_mem_htbl, target, node, -+ (unsigned long)mod) { -+ if (target->mod == mod) { -+ break; -+ } -+ } -+ rcu_read_unlock(); -+ if (target == NULL) { -+ printk(KERN_ERR "mem node for module: %s not found\n", -+ mod->name); -+ return; -+ } -+ -+ rcu_read_lock(); -+ hash_for_each_possible_rcu (target->addr_htbl, addr_map_node, node, -+ orig_addr) { -+ if (addr_map_node->buffer_addr == orig_addr) { -+ break; -+ } -+ } -+ rcu_read_unlock(); -+ if (copy_to_user((void *)addr_map_node->orig_addr, -+ (void *)addr_map_node->buffer_addr, orig_size)) { -+ return; -+ } ++ ; ++} ++#endif + -+ spin_lock_irqsave(&target->addr_htbl_spin_lock, flags); -+ hlist_del_init_rcu(&addr_map_node->node); -+ call_rcu(&addr_map_node->rcu, koi_addr_map_node_free); -+ spin_unlock_irqrestore(&target->addr_htbl_spin_lock, flags); -+ spin_lock_irqsave(&target->spin_lock, flags); -+ list_for_each_entry_rcu (mem_node, &target->mem_list_head, list) { -+ if (mem_node->addr + mem_node->size == addr) { -+ pos = mem_node->list.prev; -+ addr = mem_node->addr; -+ size += mem_node->size; -+ list_del_rcu(&mem_node->list); -+ call_rcu(&mem_node->rcu, koi_mem_node_free); -+ } else if (addr + size == mem_node->addr) { -+ if (!pos) -+ pos = mem_node->list.prev; -+ size += mem_node->size; -+ list_del_rcu(&mem_node->list); -+ call_rcu(&mem_node->rcu, koi_mem_node_free); -+ } else if (addr + size < mem_node->addr) { -+ if (!pos) -+ pos = mem_node->list.prev; -+ break; -+ } -+ } -+ mem_node = kzalloc(sizeof(struct koi_mem_list), GFP_ATOMIC); -+ mem_node->addr = addr; -+ mem_node->size = size; -+ if (pos) -+ list_add_rcu(&mem_node->list, pos); -+ else -+ list_add_tail_rcu(&mem_node->list, &target->mem_list_head); -+ spin_unlock_irqrestore(&target->spin_lock, flags); ++void *get_iee_pgtable_page(gfp_t gfpflags) ++{ ++ struct page *page; ++ void *res = kmem_cache_alloc(pgtable_jar, gfpflags); ++ iee_set_freeptr((void **)((unsigned long)res + pgtable_jar_offset), NULL); ++ page = virt_to_page(res); ++ page_ref_inc(page); ++ return res; +} -+EXPORT_SYMBOL(koi_mem_free_to_user); -+// map the driver stack to kernel -+void koi_map_kostack(struct module *mod) ++ ++void free_iee_pgtable_page(void *obj) +{ -+ struct koi_mem_hash_node *target = NULL; -+ void *koi_stack; -+ unsigned long cur_sp; -+ asm volatile("mov %0, sp\n" : "=r"(cur_sp) :); -+ if (on_irq_stack(cur_sp, NULL)) { -+ return; -+ } -+#ifndef CONFIG_IEE -+ unsigned long res, alloc_token; -+ struct task_token *token_addr = -+ (struct task_token *)((unsigned long)current + -+ (unsigned long)koi_offset); -+ if (token_addr->koi_stack_base != NULL) -+ return; -+#else -+ koi_stack = iee_rw_gate(IEE_READ_KOI_STACK, current); -+ if (koi_stack != NULL) -+ return; -+#endif -+ koi_stack = -+ (void *)__get_free_pages(THREADINFO_GFP & ~__GFP_ACCOUNT, 3); -+ free_pages(koi_stack + 4 * PAGE_SIZE, 2); -+ printk(KERN_ERR "alloc dstack start=0x%16llx, end=0x%16llx\n", -+ koi_stack, koi_stack + THREAD_SIZE); -+#ifndef CONFIG_IEE -+ token_addr->koi_stack = -+ (struct pt_regs *)(THREAD_SIZE + (unsigned long)koi_stack) - 1; -+ token_addr->koi_stack_base = koi_stack; -+#else -+ iee_rw_gate( -+ IEE_WRITE_KOI_STACK, current, -+ (unsigned long)((struct pt_regs *)(THREAD_SIZE + -+ (unsigned long)koi_stack) - -+ 1)); -+ iee_rw_gate(IEE_WRITE_KOI_STACK_BASE, current, -+ (unsigned long)koi_stack); -+#endif -+ rcu_read_lock(); -+ hash_for_each_possible_rcu (koi_mem_htbl, target, node, -+ (unsigned long)mod) { -+ if (target->mod == mod) { -+ break; -+ } -+ } -+ rcu_read_unlock(); -+ if (target == NULL) { -+ printk(KERN_ERR "mem node for module: %s not found\n", -+ mod->name); -+ return; -+ } -+ koi_copy_pagetable(target->ko_mm, target->pgdp, -+ (unsigned long)koi_stack, -+ (unsigned long)koi_stack + THREAD_SIZE); -+ printk(KERN_ERR "create ko stack: 0x%16llx\n", -+ (unsigned long)koi_stack); ++ kmem_cache_free(pgtable_jar, obj); +} -+EXPORT_SYMBOL(koi_map_kostack); \ No newline at end of file -diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c -index cea96ee75d22..cbddc8e464e4 100644 ---- a/arch/arm64/kernel/mte.c -+++ b/arch/arm64/kernel/mte.c -@@ -79,8 +79,13 @@ int memcmp_pages(struct page *page1, struct page *page2) - static inline void __mte_enable_kernel(const char *mode, unsigned long tcf) - { - /* Enable MTE Sync Mode for EL1. */ -+#ifdef CONFIG_IEE -+ sysreg_clear_set_iee_si(sctlr_el1, SCTLR_EL1_TCF_MASK, -+ SYS_FIELD_PREP(SCTLR_EL1, TCF, tcf)); -+#else - sysreg_clear_set(sctlr_el1, SCTLR_EL1_TCF_MASK, - SYS_FIELD_PREP(SCTLR_EL1, TCF, tcf)); -+#endif - isb(); - - pr_info_once("MTE: enabled in %s mode at EL1\n", mode); -diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c -index 068e5bb2661b..c98bc1a24fc7 100644 ---- a/arch/arm64/kernel/process.c -+++ b/arch/arm64/kernel/process.c -@@ -467,11 +467,24 @@ static void ssbs_thread_switch(struct task_struct *next) - * This is *only* for exception entry from EL0, and is not valid until we - * __switch_to() a user task. - */ -+#ifdef CONFIG_IEE -+// Put __entry_task in a isolated page to protect it. -+__attribute__((aligned(PAGE_SIZE))) DEFINE_PER_CPU(struct task_struct *[PAGE_SIZE/sizeof(struct task_struct *)], __entry_task); -+extern void iee_write_entry_task(struct task_struct *tsk); -+#else - DEFINE_PER_CPU(struct task_struct *, __entry_task); -+#endif - - static void entry_task_switch(struct task_struct *next) - { -+ #ifdef CONFIG_IEE -+ if(next == &init_task) -+ iee_write_entry_task((struct task_struct *)__va(__pa_symbol(next))); -+ else -+ iee_write_entry_task(next); -+ #else - __this_cpu_write(__entry_task, next); -+ #endif - } - - /* -@@ -506,11 +519,15 @@ static void erratum_1418040_new_exec(void) - */ - void update_sctlr_el1(u64 sctlr) - { -- /* -+ /* - * EnIA must not be cleared while in the kernel as this is necessary for - * in-kernel PAC. It will be cleared on kernel exit if needed. - */ -+ #ifdef CONFIG_IEE -+ sysreg_clear_set_iee_si(sctlr_el1, SCTLR_USER_MASK & ~SCTLR_ELx_ENIA, sctlr); -+ #else - sysreg_clear_set(sctlr_el1, SCTLR_USER_MASK & ~SCTLR_ELx_ENIA, sctlr); -+ #endif - - /* ISB required for the kernel uaccess routines when setting TCF0. */ - isb(); -diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c -index 58a97861bfc5..c7839247327d 100644 ---- a/arch/arm64/kernel/proton-pack.c -+++ b/arch/arm64/kernel/proton-pack.c -@@ -551,7 +551,11 @@ static enum mitigation_state spectre_v4_enable_hw_mitigation(void) - return state; - - if (spectre_v4_mitigations_off()) { -+#ifdef CONFIG_IEE -+ sysreg_clear_set_iee_si(sctlr_el1, 0, SCTLR_ELx_DSSBS); -+#else - sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_DSSBS); -+#endif - set_pstate_ssbs(1); - return SPECTRE_VULNERABLE; - } -@@ -975,7 +979,11 @@ static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot) - if (arm64_kernel_unmapped_at_el0()) - return; - -+#ifdef CONFIG_IEE -+ iee_rwx_gate_entry(IEE_WRITE_vbar_el1, v); -+#else - write_sysreg(v, vbar_el1); -+#endif - isb(); - } - -diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c -index 95cb22c083c8..df73a583a733 100644 ---- a/arch/arm64/kernel/setup.c -+++ b/arch/arm64/kernel/setup.c -@@ -33,6 +33,11 @@ - #include - #include - -+#ifdef CONFIG_IEE -+#include -+#include -+#endif +diff --git a/arch/arm64/kernel/iee/stack_slab.c b/arch/arm64/kernel/iee/stack_slab.c +new file mode 100644 +index 000000000000..c52a11d67415 +--- /dev/null ++++ b/arch/arm64/kernel/iee/stack_slab.c +@@ -0,0 +1,19 @@ ++#include ++#include + - #include - #include - #include -@@ -335,10 +340,30 @@ u64 cpu_logical_map(unsigned int cpu) - return __cpu_logical_map[cpu]; - } - -+#ifdef CONFIG_IEE -+/* used for secure modification of vbar*/ -+extern char __bp_harden_el1_vectors[]; -+/* prepare iee rwx gate for senario of ttbr1=init_pg_dir */ -+static void __init iee_si_init_early(void) ++struct kmem_cache *iee_stack_jar; ++ ++void __init iee_stack_init(void) +{ -+ /* prepare data used for iee rwx gate. */ -+ iee_base_idmap_pg_dir = phys_to_ttbr(__pa_symbol(idmap_pg_dir)); -+ iee_base_reserved_pg_dir = phys_to_ttbr(__pa_symbol(reserved_pg_dir)) -+ | FIELD_PREP(TTBR_ASID_MASK, 1); -+ iee_base__bp_harden_el1_vectors = (unsigned long)__bp_harden_el1_vectors; -+ iee_si_tcr = 0; ++ iee_stack_jar = kmem_cache_create("iee_stack_jar", (PAGE_SIZE << 3), (PAGE_SIZE << 3), SLAB_PANIC, NULL); +} -+#endif + - void __init __no_sanitize_address setup_arch(char **cmdline_p) - { - setup_initial_init_mm(_stext, _etext, _edata, _end); - -+ #ifdef CONFIG_IEE -+ init_new_context(&init_task, &init_mm); -+ atomic64_set(&init_mm.context.id, (1UL << get_cpu_asid_bits()) | INIT_ASID); -+ #endif ++void *get_iee_stack(void) ++{ ++ return kmem_cache_alloc(iee_stack_jar, GFP_KERNEL) + iee_offset; ++} + - *cmdline_p = boot_command_line; ++void free_iee_stack(void *obj) ++{ ++ kmem_cache_free(iee_stack_jar, obj - iee_offset); ++} +diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c +index b1f2a9b49039..7b86a1047278 100644 +--- a/arch/arm64/kernel/irq.c ++++ b/arch/arm64/kernel/irq.c +@@ -31,7 +31,9 @@ + DEFINE_PER_CPU(struct nmi_ctx, nmi_contexts); - kaslr_init(); -@@ -371,6 +396,14 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p) - */ - local_daif_restore(DAIF_PROCCTX_NOIRQ); + DEFINE_PER_CPU(unsigned long *, irq_stack_ptr); +- ++#ifdef CONFIG_KOI ++EXPORT_SYMBOL(irq_stack_ptr); ++#endif -+#ifdef CONFIG_IEE -+ /* -+ * Map iee si codes to init_pg_dir to run the following -+ * cpu_uninstall_idmap() which writes ttbr0. -+ */ -+ iee_si_init_early(); -+#endif -+ - /* - * TTBR0 is only used for the identity mapping at this stage. Make it - * point to zero page to avoid speculatively fetching new entries. -diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c -index b7b7afb4a8c7..168a9390d6e9 100644 ---- a/arch/arm64/kernel/traps.c -+++ b/arch/arm64/kernel/traps.c -@@ -902,6 +902,32 @@ const char *esr_get_class_string(unsigned long esr) - return esr_class_str[ESR_ELx_EC(esr)]; - } + DECLARE_PER_CPU(unsigned long *, irq_shadow_call_stack_ptr); -+#ifdef CONFIG_IEE -+extern void arm64_enter_nmi(struct pt_regs *regs); -+static const char *handler[]= { -+ "SP_EL0", -+ "ELR_EL1", -+ "TCR_EL1", -+ "TTBR0 ASID" -+ "IEE_SI" -+}; +diff --git a/arch/arm64/kernel/koi/Makefile b/arch/arm64/kernel/koi/Makefile +new file mode 100644 +index 000000000000..9be8710b714a +--- /dev/null ++++ b/arch/arm64/kernel/koi/Makefile +@@ -0,0 +1 @@ ++obj-y += koi.o +\ No newline at end of file +diff --git a/arch/arm64/kernel/koi/koi.c b/arch/arm64/kernel/koi/koi.c +new file mode 100644 +index 000000000000..aece03f85564 +--- /dev/null ++++ b/arch/arm64/kernel/koi/koi.c +@@ -0,0 +1,1688 @@ ++#include "asm/koi.h" ++#include "linux/compiler_attributes.h" ++#include "linux/compiler_types.h" ++#include "asm/barrier.h" ++#include "asm-generic/bug.h" ++#include "asm-generic/errno-base.h" ++#include "asm-generic/memory_model.h" ++#include "asm-generic/pgtable-nop4d.h" ++#include "asm-generic/rwonce.h" ++#include "asm/pgalloc.h" ++#include "asm/memory.h" ++#include "linux/bitfield.h" ++#include "linux/compiler.h" ++#include "linux/types.h" ++#include "linux/module.h" ++#include "linux/spinlock.h" ++#include "linux/spinlock_types.h" ++#include "linux/kernel.h" ++#include "linux/rculist.h" ++#include "linux/rcupdate.h" ++#include "linux/list.h" ++#include "asm/current.h" ++#include "linux/compiler_types.h" ++#include "asm-generic/barrier.h" ++#include "asm-generic/rwonce.h" ++#include "asm-generic/pgalloc.h" ++#include "asm/cpufeature.h" ++#include "asm/kvm_hyp.h" ++#include "asm/mmu.h" ++#include "asm/mmu_context.h" ++#include "asm/page-def.h" ++#include "asm/pgalloc.h" ++#include "asm/pgtable-hwdef.h" ++#include "asm/pgtable-types.h" ++#include "asm/pgtable.h" ++#include "asm/string.h" ++#include "asm/sysreg.h" ++#include "linux/bitfield.h" ++#include "linux/compiler.h" ++#include "linux/export.h" ++#include "linux/gfp.h" ++#include "linux/huge_mm.h" ++#include "linux/kallsyms.h" ++#include "linux/kconfig.h" ++#include "linux/kern_levels.h" ++#include "linux/kernel.h" ++#include "linux/list.h" ++#include "linux/lockdep.h" ++#include "linux/mm.h" ++#include "linux/mm_types.h" ++#include "linux/pgtable.h" ++#include "linux/printk.h" ++#include "linux/rculist.h" ++#include "linux/rcupdate.h" ++#include "linux/rmap.h" ++#include "linux/sched.h" ++#include "linux/stddef.h" ++#include "linux/string.h" ++#include "linux/swap.h" ++#include "linux/swapops.h" ++#include "linux/types.h" ++#include "linux/slab.h" ++#include "linux/string.h" ++#include "linux/hashtable.h" + -+asmlinkage void notrace iee_bad_mode(struct pt_regs *regs, int reason, unsigned int esr) -+{ -+ arm64_enter_nmi(regs); ++// #define DEBUG + -+ console_verbose(); ++#ifdef DEBUG ++#define debug_printk(...) printk(KERN_ERR __VA_ARGS__) ++#else ++#define debug_printk(...) ++#endif + -+ pr_crit("IEE : Bad mode in %s check detected on CPU%d, code 0x%08x -- %s\n", -+ handler[reason], smp_processor_id(), esr, -+ esr_get_class_string(esr)); ++#define __koi_code __section(".koi.text") ++#define __koi_data __section(".data..koi") + -+ __show_regs(regs); -+ local_daif_mask(); -+ panic("bad mode"); -+} -+#endif ++#define KOI_FLAG_MASK 0xffff000000000fff + - /* - * bad_el0_sync handles unexpected, but potentially recoverable synchronous - * exceptions taken from EL0. -diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S -index 3cd7e76cc562..287eaba7a15b 100644 ---- a/arch/arm64/kernel/vmlinux.lds.S -+++ b/arch/arm64/kernel/vmlinux.lds.S -@@ -134,6 +134,52 @@ jiffies = jiffies_64; - #define UNWIND_DATA_SECTIONS - #endif - ++extern unsigned long __koi_code_start[]; ++extern unsigned long __koi_code_end[]; ++extern unsigned long __koi_data_start[]; ++extern unsigned long __koi_data_end[]; +#ifdef CONFIG_IEE -+#define IEE_TEXT \ -+ . = ALIGN(PAGE_SIZE); \ -+ __iee_code_start = .; \ -+ *(.iee.text.header) \ -+ *(.iee.text) \ -+ . = ALIGN(PAGE_SIZE); \ -+ __iee_code_end = .; -+#else -+#define IEE_TEXT ++extern unsigned long __iee_si_data_start[]; ++extern unsigned long __iee_si_text_start[]; +#endif + -+#ifdef CONFIG_IEE -+#define IEE_SI_TEXT \ -+ . = ALIGN(PAGE_SIZE); \ -+ __iee_si_data_start = .; \ -+ *(.iee.si_data) \ -+ . = ALIGN(PAGE_SIZE); \ -+ __iee_exec_entry_start = .; \ -+ __iee_si_no_irq = . + (16); \ -+ *(.iee.exec_entry) \ -+ . = ALIGN(PAGE_SIZE); \ -+ __iee_si_start = .; \ -+ *(.iee.si_text) \ -+ . = ALIGN(PAGE_SIZE); \ -+ . += PAGE_SIZE - (24); \ -+ __iee_si_end = . + (24); \ -+ __iee_exec_exit = .; \ -+ *(.iee.exec_exit) \ -+ . = ALIGN(PAGE_SIZE); -+ -+#else -+#define IEE_SI_TEXT -+#endif ++__koi_data unsigned long koi_swapper_ttbr1 = 0; ++EXPORT_SYMBOL(koi_swapper_ttbr1); ++#define KOI_SWAPPER_MASK 0x0000fffffffffff0 + -+#ifdef CONFIG_KOI -+#define KOI_TEXT \ -+ . = ALIGN(PAGE_SIZE); \ -+ __koi_code_start = .; \ -+ *(.koi.text) \ -+ . = ALIGN(PAGE_SIZE); \ -+ __koi_code_end = .; -+#else -+#define KOI_TEXT -+#endif ++__attribute__((aligned(PAGE_SIZE))) ++DEFINE_PER_CPU(unsigned long[PAGE_SIZE / sizeof(unsigned long)], ++ koi_irq_current_ttbr1); ++EXPORT_SYMBOL(koi_irq_current_ttbr1); + - /* - * The size of the PE/COFF section that covers the kernel image, which - * runs from _stext to _edata, must be a round multiple of the PE/COFF -@@ -176,10 +222,13 @@ SECTIONS - SOFTIRQENTRY_TEXT - ENTRY_TEXT - TEXT_TEXT -+ IEE_TEXT - SCHED_TEXT - LOCK_TEXT - KPROBES_TEXT - HYPERVISOR_TEXT -+ IEE_SI_TEXT -+ KOI_TEXT - *(.gnu.warning) - } - -@@ -318,6 +367,18 @@ SECTIONS - . += INIT_DIR_SIZE; - init_pg_end = .; - -+ #ifdef CONFIG_IEE -+ . = ALIGN(PAGE_SIZE*8); -+ init_iee_stack_begin = .; -+ . += PAGE_SIZE*4; -+ init_iee_stack_end = .; ++extern void koi_switch_to_ko_stack(unsigned long stack_top); ++extern void init_ko_mm(struct mm_struct *ko_mm, pgd_t *pgdp); ++extern void koi_check_and_switch_context(struct mm_struct *mm); ++extern void koi_add_page_mapping(unsigned long dst, unsigned long src); ++extern unsigned long _iee_read_token_ttbr1(unsigned long iee_offset, ++ struct task_struct *tsk); ++/** ++*struct koi_mem_list - maintain a linked list of free memory in the kernel ++*@addr: stating address of this memory ++*@size: the size of the memory ++*@list: the head of the koi_mem_list ++*@rcu: for rcu ++*/ ++struct koi_mem_list { ++ unsigned long addr; ++ unsigned long size; ++ struct list_head list; ++ struct rcu_head rcu; ++}; ++//mapping parameter pointer to copy ++struct koi_addr_map { ++ unsigned long buffer_addr; ++ unsigned long orig_addr; ++ int offset; ++ struct hlist_node node; ++ struct rcu_head rcu; ++}; + -+ . = ALIGN(PAGE_SIZE); -+ init_iee_si_stack_begin = .; -+ . += PAGE_SIZE*4; -+ init_iee_si_stack_end = .; -+ #endif ++DEFINE_HASHTABLE(koi_mem_htbl, HASH_TABLE_BIT); ++EXPORT_SYMBOL(koi_mem_htbl); ++DEFINE_SPINLOCK(koi_mem_htbl_spin_lock); ++EXPORT_SYMBOL(koi_mem_htbl_spin_lock); + - . = ALIGN(SEGMENT_ALIGN); - __pecoff_data_size = ABSOLUTE(. - __initdata_begin); - _end = .; -diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c -index 188197590fc9..97e1f86046cf 100644 ---- a/arch/arm64/mm/context.c -+++ b/arch/arm64/mm/context.c -@@ -17,6 +17,10 @@ - #include - #include - -+#ifdef CONFIG_IEE -+#include -+#endif ++// EXPORT_SYMBOL(koi_do_switch_to_kernel_stack); ++// EXPORT_SYMBOL(koi_do_switch_to_ko_stack); + - static u32 asid_bits; - static DEFINE_RAW_SPINLOCK(cpu_asid_lock); - -@@ -39,7 +43,11 @@ static unsigned long *pinned_asid_map; - #define asid2ctxid(asid, genid) ((asid) | (genid)) - - /* Get the ASIDBits supported by the current CPU */ -+#ifdef CONFIG_IEE -+u32 get_cpu_asid_bits(void) -+#else - static u32 get_cpu_asid_bits(void) -+#endif - { - u32 asid; - int fld = cpuid_feature_extract_unsigned_field(read_cpuid(ID_AA64MMFR0_EL1), -@@ -212,6 +220,38 @@ static u64 new_context(struct mm_struct *mm) - return asid2ctxid(asid, generation); - } - -+#ifdef CONFIG_KOI -+/* -+ * This function is used to check and allocate ASID for ko's pgd -+ * The mm MUST point to the isolated kos' mm_struct, other behaviours are undefined. -+ */ -+void koi_check_and_switch_context(struct mm_struct *mm) { -+ u64 asid = atomic64_read(&mm->context.id); -+ u64 old_active_asid; -+ unsigned long flags; -+ unsigned int cpu; -+ -+ old_active_asid = atomic64_read(this_cpu_ptr(&active_asids)); -+ if (old_active_asid && asid_gen_match(asid) && atomic64_cmpxchg_relaxed(this_cpu_ptr(&active_asids), old_active_asid, asid)) { -+ return; ++/** ++* koi_ttbr_ctor - return ttbr1 for the given driver module ++*/ ++unsigned long koi_ttbr_ctor(struct module *mod) ++{ ++ struct koi_mem_hash_node *ko; ++ struct mm_struct *ko_mm; ++ unsigned long ttbr1; ++ unsigned long asid; ++ int bkt; ++ rcu_read_lock(); ++ hash_for_each_rcu (koi_mem_htbl, bkt, ko, node) { ++ if (ko->mod == mod) { ++ ko_mm = ko->ko_mm; ++ break; ++ } + } -+ -+ raw_spin_lock_irqsave(&cpu_asid_lock, flags); -+ asid = atomic64_read(&mm->context.id); -+ if (!asid_gen_match(asid)) { -+ asid = new_context(mm); -+ atomic64_set(&mm->context.id, asid); ++ rcu_read_unlock(); ++ if (!ko_mm) { ++ printk(KERN_ERR "cannot found module %s in koi_mem_htbl", ++ mod->name); ++ return 0; + } ++ koi_check_and_switch_context(ko_mm); ++ asid = ASID(ko_mm) | USER_ASID_FLAG; ++ ttbr1 = ko->ko_ttbr1 | FIELD_PREP(TTBR_ASID_MASK, asid); ++ return ttbr1; ++} ++EXPORT_SYMBOL(koi_ttbr_ctor); ++//release the hash node ++static __maybe_unused void koi_mem_hash_node_free(struct rcu_head *rcu) ++{ ++ struct koi_mem_hash_node *node = ++ container_of(rcu, struct koi_mem_hash_node, rcu); ++ kfree(node); ++} ++//release free memory linked list nodes ++static void koi_mem_node_free(struct rcu_head *rcu) ++{ ++ struct koi_mem_list *mem_node = ++ container_of(rcu, struct koi_mem_list, rcu); ++ kfree(mem_node); ++} ++//release the node in koi_addr_map ++static void koi_addr_map_node_free(struct rcu_head *rcu) ++{ ++ struct koi_addr_map *addr_map_node = ++ container_of(rcu, struct koi_addr_map, rcu); ++ kfree(addr_map_node); ++} + -+ cpu = smp_processor_id(); -+ if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) -+ local_flush_tlb_all(); ++static __koi_code noinline unsigned int koi_ldtrh_wrapper(unsigned long src_addr) ++{ ++ unsigned int ret; ++ asm volatile("ldtrh w0, [%1]\n" : "=r"(ret) : "r"(src_addr)); ++ return ret; ++} + -+ atomic64_set(this_cpu_ptr(&active_asids), asid); -+ raw_spin_unlock_irqrestore(&cpu_asid_lock, flags); ++static __koi_code noinline unsigned long koi_ldtr_wrapper(unsigned long src_addr) ++{ ++ unsigned long ret; ++ asm volatile("ldtr x0, [%1]\n" : "=r"(ret) : "r"(src_addr)); ++ return ret; +} -+#endif + - void check_and_switch_context(struct mm_struct *mm) - { - unsigned long flags; -@@ -348,7 +388,9 @@ asmlinkage void post_ttbr_update_workaround(void) - - void cpu_do_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm) - { -+ #ifndef CONFIG_IEE - unsigned long ttbr1 = read_sysreg(ttbr1_el1); -+ #endif - unsigned long asid = ASID(mm); - unsigned long ttbr0 = phys_to_ttbr(pgd_phys); - -@@ -360,14 +402,28 @@ void cpu_do_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm) - if (IS_ENABLED(CONFIG_ARM64_SW_TTBR0_PAN)) - ttbr0 |= FIELD_PREP(TTBR_ASID_MASK, asid); - -- /* Set ASID in TTBR1 since TCR.A1 is set */ -+ #ifdef CONFIG_IEE -+ ttbr0 |= FIELD_PREP(TTBR_ASID_MASK, asid+1); -+ iee_rwx_gate_entry(IEE_CONTEXT_SWITCH, ttbr0); -+ // TODO : if defined CONFIG_IEE and defined CONFIG_KOI -+ #else -+ /* Set ASID in TTBR0 since TCR.A1 is set 0*/ ++static __koi_code noinline void koi_sttr_wrapper(unsigned long src, ++ unsigned long dst_addr) ++{ ++ asm volatile("sttr x0, [x1]\n" : :); ++} + -+ #ifdef CONFIG_KOI -+ ttbr0 |= FIELD_PREP(TTBR_ASID_MASK, asid+1); -+ ttbr1 &= ~TTBR_ASID_MASK; -+ ttbr1 |= FIELD_PREP(TTBR_ASID_MASK, asid); -+ #else - ttbr1 &= ~TTBR_ASID_MASK; - ttbr1 |= FIELD_PREP(TTBR_ASID_MASK, asid); -- -+ -+ #endif - cpu_set_reserved_ttbr0_nosync(); - write_sysreg(ttbr1, ttbr1_el1); - write_sysreg(ttbr0, ttbr0_el1); - isb(); -+ #endif ++static __koi_code noinline void koi_sttrh_wrapper(unsigned int src, ++ unsigned long dst_addr) ++{ ++ asm volatile("sttrh w0, [x1]\n" : :); ++} + - post_ttbr_update_workaround(); - } - -@@ -375,11 +431,21 @@ static int asids_update_limit(void) - { - unsigned long num_available_asids = NUM_USER_ASIDS; - -- if (arm64_kernel_unmapped_at_el0()) { -- num_available_asids /= 2; -- if (pinned_asid_map) -- set_kpti_asid_bits(pinned_asid_map); -- } -+ #if defined(CONFIG_IEE) || defined(CONFIG_KOI) -+ num_available_asids /= 2; -+ if (pinned_asid_map) { -+ unsigned int len = BITS_TO_LONGS(NUM_USER_ASIDS) * sizeof(unsigned long); -+ memset(pinned_asid_map, 0xaa, len); -+ __set_bit(INIT_ASID, pinned_asid_map); ++#ifndef CONFIG_IEE ++/* ++ * This function is used to switch to ko's pgtable. ++ */ ++__koi_code noinline unsigned long koi_do_switch_to_ko_pgtbl(void) ++{ ++ struct koi_mem_hash_node *ko; ++ // struct mm_struct *ko_mm; ++ unsigned long addr; ++ unsigned long ttbr1, asid; ++ unsigned long *ptr; ++ struct task_token *token_addr = ++ (struct task_token *)((unsigned long)current + ++ (unsigned long)koi_offset); ++ int bkt; ++ unsigned long flags; ++ asm volatile(" mrs %0, elr_el1\n" : "=r"(addr)); ++ ptr = SHIFT_PERCPU_PTR(koi_irq_current_ttbr1, __kern_my_cpu_offset()); ++ rcu_read_lock(); ++ hash_for_each_rcu (koi_mem_htbl, bkt, ko, node) { ++ spin_lock_irqsave(&ko->mod_lock, flags); ++ if (!ko->is_valid) { ++ spin_unlock_irqrestore(&ko->mod_lock, flags); ++ goto out; ++ } ++ if (ko->mod != NULL && ko->mod->mem[MOD_INIT_TEXT].base != NULL) { ++ if (addr >= (unsigned long)ko->mod->mem[MOD_INIT_TEXT].base && ++ addr < (unsigned long)ko->mod->mem[MOD_INIT_TEXT].base + ko->mod->mem[MOD_INIT_TEXT].size) { ++ spin_unlock_irqrestore(&ko->mod_lock, flags); ++ if (token_addr->current_ttbr1 == ko->ko_ttbr1 || ++ *ptr == ko->ko_ttbr1) { ++ // ko_mm = ko->ko_mm; ++ // koi_check_and_switch_context(ko_mm); ++ // asid = ASID(ko_mm); ++ // ttbr1 = ko->ko_ttbr1; ++ // ttbr1 |= FIELD_PREP(TTBR_ASID_MASK, asid); ++ asm volatile("mrs %0, ttbr0_el1\n" ++ : "=r"(asid) ++ :); ++ asid &= TTBR_ASID_MASK; ++ ttbr1 = ko->ko_ttbr1 | asid; ++ rcu_read_unlock(); ++ return ttbr1; ++ } ++ goto out; ++ } ++ } ++ if (addr >= (unsigned long)ko->mod->mem[MOD_TEXT].base && ++ addr < (unsigned long)ko->mod->mem[MOD_TEXT].base + ko->mod->mem[MOD_TEXT].size) { ++ spin_unlock_irqrestore(&ko->mod_lock, flags); ++ if (token_addr->current_ttbr1 == ko->ko_ttbr1 || ++ *ptr == ko->ko_ttbr1) { ++ // ko_mm = ko->ko_mm; ++ // koi_check_and_switch_context(ko_mm); ++ // asid = ASID(ko_mm); ++ // ttbr1 = ko->ko_ttbr1; ++ // ttbr1 |= FIELD_PREP(TTBR_ASID_MASK, asid); ++ asm volatile("mrs %0, ttbr0_el1\n" ++ : "=r"(asid) ++ :); ++ asid &= TTBR_ASID_MASK; ++ ttbr1 = ko->ko_ttbr1 | asid; ++ rcu_read_unlock(); ++ return ttbr1; ++ } ++ goto out; ++ } ++ spin_unlock_irqrestore(&ko->mod_lock, flags); ++ } ++out: ++ rcu_read_unlock(); ++ return 0; ++} ++/** ++* koi_do_switch_to_kernel_pgtbl - switch to kernel pagetable ++*/ ++__koi_code noinline int koi_do_switch_to_kernel_pgtbl(void) ++{ ++ unsigned long curr_ttbr1, asid; ++ // if (!cpu_online(smp_processor_id())) ++ // return 0; ++ asm volatile(" mrs %0, ttbr1_el1\n" : "=r"(curr_ttbr1)); ++ if ((curr_ttbr1 & KOI_SWAPPER_MASK) == ++ (koi_swapper_ttbr1 & KOI_SWAPPER_MASK)) { ++ return 0; ++ } ++ // if (((curr_ttbr1 & TTBR_ASID_MASK) >> 48) <= 1) { ++ // return 0; ++ // } ++ asm volatile("mrs %0, ttbr0_el1\n" : "=r"(asid) :); ++ asid &= ~USER_ASID_FLAG; ++ asid &= TTBR_ASID_MASK; ++ write_sysreg(koi_swapper_ttbr1 | asid, ttbr1_el1); ++ isb(); ++ asm volatile(ALTERNATIVE("nop; nop; nop", "ic iallu; dsb nsh; isb", ++ ARM64_WORKAROUND_CAVIUM_27456)); ++ return 1; ++} ++#else ++__koi_code noinline unsigned long koi_do_switch_to_ko_pgtbl(void) ++{ ++ struct koi_mem_hash_node *ko; ++ unsigned long addr, pan_flag, current_ttbr1, asid, ttbr1, flags; ++ unsigned long *ptr; ++ struct mm_struct *ko_mm; ++ int bkt; ++ asm volatile("mrs %0, pan\n" ++ "msr pan, 0x0\n" ++ : "=r"(pan_flag) ++ :); ++ current_ttbr1 = _iee_read_token_ttbr1(iee_offset, current); ++ asm volatile("msr pan, %0\n" : : "r"(pan_flag)); ++ ptr = SHIFT_PERCPU_PTR(koi_irq_current_ttbr1, __kern_my_cpu_offset()); ++ if (current_ttbr1 == 0 && *ptr == 0) ++ return 0; ++ asm volatile(" mrs %0, elr_el1\n" : "=r"(addr)); ++ rcu_read_lock(); ++ hash_for_each_rcu (koi_mem_htbl, bkt, ko, node) { ++ spin_lock_irqsave(&ko->mod_lock, flags); ++ if (!ko->is_valid) { ++ spin_unlock_irqrestore(&ko->mod_lock, flags); ++ goto out; ++ } ++ if (ko->mod != NULL && ko->mod->mem[MOD_INIT_TEXT].base != NULL) { ++ if (addr >= (unsigned long)ko->mod->mem[MOD_INIT_TEXT].base && ++ addr < (unsigned long)ko->mod->mem[MOD_INIT_TEXT].base + ko->mod->mem[MOD_INIT_TEXT].size) { ++ spin_unlock_irqrestore(&ko->mod_lock, flags); ++ if (current_ttbr1 == ko->ko_ttbr1 || *ptr == ko->ko_ttbr1) { ++ asm volatile("mrs %0, ttbr0_el1\n" ++ : "=r"(asid) ++ :); ++ asid &= TTBR_ASID_MASK; ++ ttbr1 = ko->ko_ttbr1 | asid; ++ rcu_read_unlock(); ++ return ttbr1; ++ } ++ goto out; ++ } + } -+ #else -+ if (arm64_kernel_unmapped_at_el0()) { -+ num_available_asids /= 2; -+ if (pinned_asid_map) -+ set_kpti_asid_bits(pinned_asid_map); -+ } -+ #endif -+ - /* - * Expect allocation after rollover to fail if we don't have at least - * one more ASID than CPUs. ASID #0 is reserved for init_mm. -@@ -400,6 +466,10 @@ arch_initcall(asids_update_limit); - - static int asids_init(void) - { -+ #if defined(CONFIG_IEE) || defined(CONFIG_KOI) -+ unsigned int len; -+ #endif ++ if (addr >= (unsigned long)ko->mod->mem[MOD_TEXT].base && ++ addr < (unsigned long)ko->mod->mem[MOD_TEXT].base + ko->mod->mem[MOD_TEXT].size) { ++ spin_unlock_irqrestore(&ko->mod_lock, flags); ++ if (current_ttbr1 == ko->ko_ttbr1 || *ptr == ko->ko_ttbr1) { ++ asm volatile("mrs %0, ttbr0_el1\n" ++ : "=r"(asid) ++ :); ++ asid &= TTBR_ASID_MASK; ++ ttbr1 = ko->ko_ttbr1 | asid; ++ rcu_read_unlock(); ++ return ttbr1; ++ } ++ goto out; ++ } ++ spin_unlock_irqrestore(&ko->mod_lock, flags); ++ } ++out: ++ rcu_read_unlock(); ++ return 0; ++} + - asid_bits = get_cpu_asid_bits(); - atomic64_set(&asid_generation, ASID_FIRST_VERSION); - asid_map = bitmap_zalloc(NUM_USER_ASIDS, GFP_KERNEL); -@@ -410,6 +480,11 @@ static int asids_init(void) - pinned_asid_map = bitmap_zalloc(NUM_USER_ASIDS, GFP_KERNEL); - nr_pinned_asids = 0; - -+ #if defined(CONFIG_IEE) || defined(CONFIG_KOI) -+ len = BITS_TO_LONGS(NUM_USER_ASIDS) * sizeof(unsigned long); -+ memset(asid_map, 0xaa, len); -+ __set_bit(INIT_ASID, asid_map); -+ #else - /* - * We cannot call set_reserved_asid_bits() here because CPU - * caps are not finalized yet, so it is safer to assume KPTI -@@ -417,6 +492,8 @@ static int asids_init(void) - */ - if (IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0)) - set_kpti_asid_bits(asid_map); -+ #endif ++__koi_code noinline int koi_do_switch_to_kernel_pgtbl(void) ++{ ++ unsigned long curr_ttbr1, asid, error_addr; ++ // if (!cpu_online(smp_processor_id())) ++ // return 0; ++ asm volatile(" mrs %0, ttbr1_el1\n" : "=r"(curr_ttbr1)); ++ if ((curr_ttbr1 & KOI_SWAPPER_MASK) == ++ (koi_swapper_ttbr1 & KOI_SWAPPER_MASK)) { ++ return 0; ++ } ++ // if (((curr_ttbr1 & TTBR_ASID_MASK) >> 48) <= 1) { ++ // return 0; ++ // } ++ error_addr = read_sysreg(elr_el1); ++ if ((error_addr >= (unsigned long)__iee_si_data_start) && ++ (error_addr <= (unsigned long)__iee_si_text_start)) { ++ unsigned long esr = read_sysreg(esr_el1); ++ asm volatile("mrs %0, ttbr1_el1\n" : "=r"(asid) :); ++ asid &= ~USER_ASID_FLAG; ++ asid &= TTBR_ASID_MASK; ++ write_sysreg(koi_swapper_ttbr1 | asid, ttbr1_el1); ++ isb(); ++ printk(KERN_ERR ++ "IEE SI: Error on switch to kernel. ELR_EL1:0x%llx, ESR_EL1:0x%llx, TTBR1:0x%llx", ++ error_addr, esr, curr_ttbr1); ++ } else { ++ iee_rwx_gate_entry(IEE_SWITCH_TO_KERNEL); ++ } ++ return 1; ++} ++#endif ++/** ++* koi_save_ttbr - save ttbr of each driver module ++* @mod: driver module ++* @pgdp:pointer to driver module top page table,pgd ++*/ ++static void koi_save_ttbr(struct module *mod, pgd_t *pgdp, ++ struct koi_mem_hash_node *node) ++{ ++ phys_addr_t ttbr1 = phys_to_ttbr(virt_to_phys(pgdp)); ++ if (system_supports_cnp()) ++ ttbr1 |= TTBR_CNP_BIT; ++ node->ko_ttbr1 = ttbr1; ++} + - return 0; - } - early_initcall(asids_init); -diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c -index 4ea07caba71c..de1d57c2b30f 100644 ---- a/arch/arm64/mm/fault.c -+++ b/arch/arm64/mm/fault.c -@@ -261,7 +261,11 @@ int __ptep_set_access_flags(struct vm_area_struct *vma, - pteval ^= PTE_RDONLY; - pteval |= pte_val(entry); - pteval ^= PTE_RDONLY; -+ #ifdef CONFIG_PTP -+ pteval = iee_set_cmpxchg_relaxed(ptep, old_pteval, pteval); -+ #else - pteval = cmpxchg_relaxed(&pte_val(*ptep), old_pteval, pteval); -+ #endif - } while (pteval != old_pteval); - - /* Invalidate a stale read-only entry */ -@@ -376,8 +380,13 @@ static void do_tag_recovery(unsigned long addr, unsigned long esr, - * It will be done lazily on the other CPUs when they will hit a - * tag fault. - */ -+ #ifdef CONFIG_IEE -+ sysreg_clear_set_iee_si(sctlr_el1, SCTLR_EL1_TCF_MASK, -+ SYS_FIELD_PREP_ENUM(SCTLR_EL1, TCF, NONE)); -+ #else - sysreg_clear_set(sctlr_el1, SCTLR_EL1_TCF_MASK, - SYS_FIELD_PREP_ENUM(SCTLR_EL1, TCF, NONE)); -+ #endif - isb(); - } - -diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c -index bfc02568805a..580ecb596d2d 100644 ---- a/arch/arm64/mm/fixmap.c -+++ b/arch/arm64/mm/fixmap.c -@@ -32,6 +32,22 @@ static pte_t bm_pte[NR_BM_PTE_TABLES][PTRS_PER_PTE] __page_aligned_bss; - static pmd_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss __maybe_unused; - static pud_t bm_pud[PTRS_PER_PUD] __page_aligned_bss __maybe_unused; - ++/** ++ * Copy one pte. Returns 0 if succeeded, or -EAGAIN if one preallocated page ++ * is required to copy this pte. ++*/ ++static inline int koi_copy_present_pte(struct mm_struct *ko_mm, pte_t *dst_pte, ++ pte_t *src_pte, unsigned long addr) ++{ ++ pte_t pte = *src_pte; ++ struct page *page; ++ ++ debug_printk("addr=0x%16llx, dst_pte=0x%16llx\n", addr, dst_pte); +#ifdef CONFIG_IEE -+void *bm_pte_addr = (void *)bm_pte; -+void *bm_pmd_addr = (void *)bm_pmd; -+void *bm_pud_addr = (void *)bm_pud; ++ if ((pte_val(pte) & PTE_USER) && (pte_val(pte) & PTE_DBM) && ++ !(pte_val(pte) & PTE_PXN)) { ++ set_pte(dst_pte, __pte(pte_val(pte) & (~PTE_DBM) | PTE_RDONLY)); ++ } else { ++#endif ++ set_pte(dst_pte, pte); ++#ifdef CONFIG_IEE ++ } +#endif ++ return 0; ++} ++/** ++* copy huge pmd from kernel space to driver space. ++*/ ++static int koi_copy_huge_pmd(struct mm_struct *ko_mm, pmd_t *dst_pmd, ++ pmd_t *src_pmd, unsigned long addr, pteval_t prot) ++{ ++ spinlock_t *src_ptl, *dst_ptl; ++ pmd_t pmd; ++ int ret = -ENOMEM; ++ debug_printk( ++ "hugepmd: src_pmd=0x%16llx, dst_pmd=0x%16llx, src_pmd_val=0x%16llx, dst_pmd_val=0x%16llx, addr=0x%16llx\n", ++ src_pmd, dst_pmd, pmd_val(*src_pmd), pmd_val(*dst_pmd), addr); ++ dst_ptl = pmd_lockptr(ko_mm, dst_pmd); ++ src_ptl = pmd_lockptr(&init_mm, src_pmd); ++ spin_lock_bh(dst_ptl); ++ spin_lock_bh(src_ptl); + -+#ifdef CONFIG_PTP -+extern void __iee_p4d_populate_pre_init(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot); -+extern void __iee_pud_populate_pre_init(pud_t *pudp, phys_addr_t pmdp, pudval_t prot); -+extern void __iee_pmd_populate_pre_init(pmd_t *pmdp, phys_addr_t ptep, -+ pmdval_t prot); ++ set_pmd(dst_pmd, __pmd(pmd_val(*src_pmd) | prot)); ++ ret = 0; ++ spin_unlock_bh(src_ptl); ++ spin_unlock_bh(dst_ptl); ++ return ret; ++} + -+extern void iee_set_p4d_pre_init(p4d_t *p4dp, p4d_t p4d); -+#define set_pgd_init(pgdptr, pgdval) iee_set_p4d_pre_init((p4d_t *)(pgdptr), (p4d_t) { pgdval }) -+#endif ++int __koi_pte_alloc(struct mm_struct *mm, pmd_t *pmd) ++{ ++ spinlock_t *ptl; ++ // pgtable_t new = alloc_page(GFP_PGTABLE_KERNEL); ++ pte_t *new = pte_alloc_one_kernel(mm); ++ printk(KERN_ERR "alloc new=0x%16llx\n", new); ++ if (!new) ++ return -ENOMEM; + - static inline pte_t *fixmap_pte(unsigned long addr) - { - return &bm_pte[BM_PTE_TABLE_IDX(addr)][pte_index(addr)]; -@@ -44,7 +60,11 @@ static void __init early_fixmap_init_pte(pmd_t *pmdp, unsigned long addr) - - if (pmd_none(pmd)) { - ptep = bm_pte[BM_PTE_TABLE_IDX(addr)]; -+ #ifdef CONFIG_PTP -+ __iee_pmd_populate_pre_init(pmdp, __pa_symbol(ptep), PMD_TYPE_TABLE); -+ #else - __pmd_populate(pmdp, __pa_symbol(ptep), PMD_TYPE_TABLE); -+ #endif - } - } - -@@ -55,8 +75,13 @@ static void __init early_fixmap_init_pmd(pud_t *pudp, unsigned long addr, - pud_t pud = READ_ONCE(*pudp); - pmd_t *pmdp; - -- if (pud_none(pud)) -+ if (pud_none(pud)) { -+ #ifdef CONFIG_PTP -+ __iee_pud_populate_pre_init(pudp, __pa_symbol(bm_pmd), PUD_TYPE_TABLE); -+ #else - __pud_populate(pudp, __pa_symbol(bm_pmd), PUD_TYPE_TABLE); -+ #endif ++ /* ++ * Ensure all pte setup (eg. pte page lock and page clearing) are ++ * visible before the pte is made visible to other CPUs by being ++ * put into page tables. ++ * ++ * The other side of the story is the pointer chasing in the page ++ * table walking code (when walking the page table without locking; ++ * ie. most of the time). Fortunately, these data accesses consist ++ * of a chain of data-dependent loads, meaning most CPUs (alpha ++ * being the notable exception) will already guarantee loads are ++ * seen in-order. See the alpha page table accessors for the ++ * smp_rmb() barriers in page table walking code. ++ */ ++ smp_wmb(); /* Could be smp_wmb__xxx(before|after)_spin_lock */ ++ ++ ptl = pmd_lockptr(mm, pmd); ++ spin_lock_bh(ptl); ++ if (likely(pmd_none(*pmd))) { /* Has another populated it ? */ ++ mm_inc_nr_ptes(mm); ++ pmd_populate_kernel(mm, pmd, new); ++ new = NULL; + } - - pmdp = pmd_offset_kimg(pudp, addr); - do { -@@ -82,8 +107,13 @@ static void __init early_fixmap_init_pud(p4d_t *p4dp, unsigned long addr, - BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES)); - } - -- if (p4d_none(p4d)) -+ if (p4d_none(p4d)) { -+ #ifdef CONFIG_PTP -+ __iee_p4d_populate_pre_init(p4dp, __pa_symbol(bm_pud), P4D_TYPE_TABLE); -+ #else - __p4d_populate(p4dp, __pa_symbol(bm_pud), P4D_TYPE_TABLE); -+ #endif ++ spin_unlock_bh(ptl); ++ if (new) { ++ pte_free_kernel(mm, new); + } - - pudp = pud_offset_kimg(p4dp, addr); - early_fixmap_init_pmd(pudp, addr, end); -@@ -106,6 +136,27 @@ void __init early_fixmap_init(void) - early_fixmap_init_pud(p4dp, addr, end); - } - -+#ifdef CONFIG_PTP -+extern void iee_set_pte_pre_init(pte_t *ptep, pte_t pte); -+void __iee_set_fixmap_pre_init(enum fixed_addresses idx, -+ phys_addr_t phys, pgprot_t flags) -+{ -+ unsigned long addr = __fix_to_virt(idx); -+ pte_t *ptep; ++ return 0; ++} + -+ BUG_ON(idx <= FIX_HOLE || idx >= __end_of_fixed_addresses); ++#define koi_pte_alloc(mm, pmd) \ ++ (unlikely(pmd_none(*(pmd))) && __koi_pte_alloc(mm, pmd)) + -+ ptep = fixmap_pte(addr); ++#define koi_pte_offset_map_lock(mm, pmd, address, ptlp) \ ++ ({ \ ++ spinlock_t *__ptl = pte_lockptr(mm, pmd); \ ++ pte_t *__pte = pte_offset_kernel(pmd, address); \ ++ *(ptlp) = __ptl; \ ++ spin_lock_bh(__ptl); \ ++ __pte; \ ++ }) + -+ if (pgprot_val(flags)) { -+ iee_set_pte_pre_init(ptep, pfn_pte(phys >> PAGE_SHIFT, flags)); -+ } else { -+ iee_set_pte_pre_init(ptep, __pte(0)); -+ flush_tlb_kernel_range(addr, addr+PAGE_SIZE); ++#define koi_pte_alloc_map_lock(mm, pmd, address, ptlp) \ ++ (koi_pte_alloc(mm, pmd) ? \ ++ NULL : \ ++ koi_pte_offset_map_lock(mm, pmd, address, ptlp)) ++ ++/** ++*koi_copy_pte_range - copy pte from kernel space to driver space ++*/ ++static int koi_copy_pte_range(struct mm_struct *ko_mm, pmd_t *dst_pmd, ++ pmd_t *src_pmd, unsigned long addr, ++ unsigned long end, pteval_t prot) ++{ ++ pte_t *src_pte, *dst_pte; ++ spinlock_t *src_ptl, *dst_ptl; ++ ++ int ret = 0; ++again: ++ dst_pte = koi_pte_alloc_map_lock(ko_mm, dst_pmd, addr, &dst_ptl); ++ if (!dst_pte) { ++ ret = -ENOMEM; ++ goto unlock; ++ } ++ src_pte = pte_offset_kernel(src_pmd, addr); ++ src_ptl = pte_lockptr(&init_mm, src_pmd); ++ spin_lock_bh(src_ptl); ++ do { ++ if (pte_none(*src_pte)) ++ continue; ++ if (unlikely(!pte_present(*src_pte))) { ++ printk(KERN_ERR ++ "present pte found: addr=0x%16llx, end=0x%16llx\n", ++ addr, end); ++ continue; ++ } ++ if (pte_valid(*dst_pte)) { ++ continue; ++ } ++ /* koi_copy_present_pte() will clear `*prealloc` if consumed */ ++ ret = koi_copy_present_pte(ko_mm, dst_pte, src_pte, addr); ++ debug_printk( ++ "dst_pte=0x%16llx, dst_pte_val=0x%16llx, src_pte=0x%16llx, src_pte_val=0x%16llx, addr=0x%16llx\n", ++ dst_pte, pte_val(*dst_pte), src_pte, pte_val(*src_pte), ++ addr); ++ if (unlikely(ret == -EAGAIN)) ++ break; ++ } while (dst_pte++, src_pte++, addr += PAGE_SIZE, addr != end); ++ spin_unlock_bh(src_ptl); ++ spin_unlock_bh(dst_ptl); ++ ++ if (ret) { ++ WARN_ON_ONCE(ret != -EAGAIN); ++ ret = 0; + } ++ if (addr != end) ++ goto again; ++ ++ return ret; ++unlock: ++ spin_unlock_bh(dst_ptl); ++ return ret; +} -+#endif + - /* - * Unusually, this is also called in IRQ context (ghes_iounmap_irq) so if we - * ever need to use IPIs for TLB broadcasting, then we're in trouble here. -@@ -121,9 +172,17 @@ void __set_fixmap(enum fixed_addresses idx, - ptep = fixmap_pte(addr); - - if (pgprot_val(flags)) { -+ #ifdef CONFIG_PTP -+ iee_set_bm_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags)); -+ #else - __set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags)); -+ #endif - } else { -+ #ifdef CONFIG_PTP -+ iee_set_bm_pte(ptep, __pte(0)); -+ #else - __pte_clear(&init_mm, addr, ptep); -+ #endif - flush_tlb_kernel_range(addr, addr+PAGE_SIZE); - } - } -@@ -179,8 +238,13 @@ void __init fixmap_copy(pgd_t *pgdir) - * live in the carveout for the swapper_pg_dir. We can simply - * re-use the existing dir for the fixmap. - */ -+ #ifdef CONFIG_PTP -+ set_pgd_init(pgd_offset_pgd(pgdir, FIXADDR_TOT_START), -+ READ_ONCE(*pgd_offset_k(FIXADDR_TOT_START))); -+ #else - set_pgd(pgd_offset_pgd(pgdir, FIXADDR_TOT_START), - READ_ONCE(*pgd_offset_k(FIXADDR_TOT_START))); -+ #endif - } else if (CONFIG_PGTABLE_LEVELS > 3) { - pgd_t *bm_pgdp; - p4d_t *bm_p4dp; -@@ -194,9 +258,15 @@ void __init fixmap_copy(pgd_t *pgdir) - BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES)); - bm_pgdp = pgd_offset_pgd(pgdir, FIXADDR_TOT_START); - bm_p4dp = p4d_offset(bm_pgdp, FIXADDR_TOT_START); -+ #ifdef CONFIG_PTP -+ bm_pudp = pud_set_fixmap_offset_init(bm_p4dp, FIXADDR_TOT_START); -+ __iee_pud_populate_pre_init(bm_pudp, __pa(lm_alias(bm_pmd)), PMD_TYPE_TABLE); -+ pud_clear_fixmap_init(); -+ #else - bm_pudp = pud_set_fixmap_offset(bm_p4dp, FIXADDR_TOT_START); - pud_populate(&init_mm, bm_pudp, lm_alias(bm_pmd)); - pud_clear_fixmap(); -+ #endif - } else { - BUG(); - } -diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c -index 8c8d7653ba84..4190f5c10d68 100644 ---- a/arch/arm64/mm/init.c -+++ b/arch/arm64/mm/init.c -@@ -55,8 +55,19 @@ - * that cannot be mistaken for a real physical address. - */ - s64 memstart_addr __ro_after_init = -1; -+#if defined(CONFIG_IEE) || defined(CONFIG_KOI) -+s64 memstart_addr_init __ro_after_init = -1; -+#endif -+#ifdef CONFIG_KOI -+s64 koi_offset __ro_after_init = -1; -+EXPORT_SYMBOL(koi_offset); -+#endif -+#ifdef CONFIG_IEE -+s64 iee_offset __ro_after_init = -1; -+#endif - EXPORT_SYMBOL(memstart_addr); - -+ - /* - * If the corresponding config options are enabled, we create both ZONE_DMA - * and ZONE_DMA32. By default ZONE_DMA covers the 32-bit addressable memory -@@ -421,7 +432,11 @@ early_param("memmap", parse_memmap_opt); - - void __init arm64_memblock_init(void) - { -+ #if defined(CONFIG_IEE) || defined(CONFIG_KOI) -+ s64 linear_region_size = BIT(vabits_actual - 2); -+ #else - s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual); -+ #endif - - /* - * Corner case: 52-bit VA capable systems running KVM in nVHE mode may -@@ -438,13 +453,24 @@ void __init arm64_memblock_init(void) - } - - /* Remove memory above our supported physical address size */ -+ #ifdef CONFIG_IEE -+ // If config iee, phys size can not be above 0x400000000000 -+ if(__pa_symbol(_end) > BIT_ULL(vabits_actual - 2)) -+ panic("Image on too high phys mem.\n"); -+ else -+ memblock_remove(BIT_ULL(vabits_actual - 2), ULLONG_MAX); -+ #else - memblock_remove(1ULL << PHYS_MASK_SHIFT, ULLONG_MAX); -+ #endif - - /* - * Select a suitable value for the base of physical memory. - */ - memstart_addr = round_down(memblock_start_of_DRAM(), - ARM64_MEMSTART_ALIGN); -+ #if defined(CONFIG_IEE) || defined(CONFIG_KOI) -+ memstart_addr_init = memstart_addr; -+ #endif - - if ((memblock_end_of_DRAM() - memstart_addr) > linear_region_size) - pr_warn("Memory doesn't fit in the linear mapping, VA_BITS too small\n"); -@@ -531,6 +557,14 @@ void __init arm64_memblock_init(void) - ((range * memstart_offset_seed) >> 16); - } - } -+ -+ #ifdef CONFIG_KOI -+ koi_offset = memstart_addr - memstart_addr_init + KOI_OFFSET; -+ #endif -+ #ifdef CONFIG_IEE -+ iee_offset = memstart_addr - memstart_addr_init + ((unsigned long)BIT(vabits_actual - 2)); -+ #endif -+ //printk(KERN_ERR "koi_offset: 0x%16llx\n", koi_offset); - - /* - * Register the kernel text, kernel data, initrd, and initial -diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c -index 4142a75a414e..094f3798441d 100644 ---- a/arch/arm64/mm/mmu.c -+++ b/arch/arm64/mm/mmu.c -@@ -6,6 +6,7 @@ - * Copyright (C) 2012 ARM Ltd. - */ - -+#include "asm/pgtable.h" - #include - #include - #include -@@ -40,6 +41,11 @@ - #include - #include - #include -+#ifdef CONFIG_IEE -+#include -+#include -+#include -+#endif - - #define NO_BLOCK_MAPPINGS BIT(0) - #define NO_CONT_MAPPINGS BIT(1) -@@ -76,8 +82,282 @@ EXPORT_SYMBOL(empty_zero_page); - static DEFINE_SPINLOCK(swapper_pgdir_lock); - static DEFINE_MUTEX(fixmap_lock); - -+#ifdef CONFIG_IEE -+extern struct cred init_cred; -+ -+extern unsigned long init_iee_stack_begin[]; -+extern unsigned long init_iee_stack_end[]; -+extern unsigned long __iee_si_data_start[]; -+extern unsigned long __iee_exec_entry_start[]; -+extern unsigned long __iee_si_start[]; -+extern unsigned long __iee_si_end[]; ++int __koi_pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) ++{ ++ spinlock_t *ptl; ++ // struct page* page = alloc_page(GFP_PGTABLE_KERNEL); ++ // pmd_t *new = (pmd_t *)page_address(page); ++ pmd_t *new = pmd_alloc_one(mm, address); ++ if (!new) ++ return -ENOMEM; + -+extern void *bm_pte_addr; -+extern void *bm_pmd_addr; -+extern void *bm_pud_addr; ++ smp_wmb(); /* See comment in __pte_alloc */ + -+#ifdef CONFIG_PTP ++ ptl = pud_lockptr(mm, pud); ++ spin_lock_bh(ptl); ++ if (!pud_present(*pud)) { ++ mm_inc_nr_pmds(mm); ++ pud_populate(mm, pud, new); ++ } else { /* Another has populated it */ ++ pmd_free(mm, new); ++ // free_page((unsigned long)new); ++ } ++ spin_unlock_bh(ptl); ++ return 0; ++} + -+/* Funcs to set pgtable before iee initialized. */ -+static void iee_set_swapper_pgd_pre_init(pgd_t *pgdp, pgd_t pgd) ++static inline pmd_t *koi_pmd_alloc(struct mm_struct *mm, pud_t *pud, ++ unsigned long address) +{ -+ pgd_t *fixmap_pgdp; -+ -+ spin_lock(&swapper_pgdir_lock); -+ fixmap_pgdp = pgd_set_fixmap_init(__pa_symbol(pgdp)); -+ WRITE_ONCE(*fixmap_pgdp, pgd); -+ /* -+ * We need dsb(ishst) here to ensure the page-table-walker sees -+ * our new entry before set_p?d() returns. The fixmap's -+ * flush_tlb_kernel_range() via clear_fixmap() does this for us. -+ */ -+ pgd_clear_fixmap_init(); -+ spin_unlock(&swapper_pgdir_lock); ++ return (unlikely(pud_none(*pud)) && __koi_pmd_alloc(mm, pud, address)) ? ++ NULL : ++ pmd_offset(pud, address); +} + -+void iee_set_p4d_pre_init(p4d_t *p4dp, p4d_t p4d) ++/** ++*kio_copy_pmd_range - copy pmd from kernel to driver space ++*/ ++static inline int koi_copy_pmd_range(struct mm_struct *ko_mm, pud_t *dst_pud, ++ pud_t *src_pud, unsigned long addr, ++ unsigned long end, pteval_t prot) +{ -+ if (in_swapper_pgdir(p4dp)) { -+ iee_set_swapper_pgd_pre_init((pgd_t *)p4dp, __pgd(p4d_val(p4d))); -+ return; ++ pmd_t *src_pmd, *dst_pmd; ++ unsigned long next, flag; ++ int err; ++ debug_printk( ++ "copy_pud_range src_pud=0x%16llx, dst_pud=0x%16llx, addr=0x%16llx, end=0x%16llx\n", ++ src_pud, dst_pud, addr, end); ++ dst_pmd = koi_pmd_alloc(ko_mm, dst_pud, addr); ++ if (!dst_pmd) { ++ return -ENOMEM; + } -+ -+ WRITE_ONCE(*p4dp, p4d); -+ dsb(ishst); -+ isb(); ++ src_pmd = pmd_offset(src_pud, addr); ++ do { ++ next = pmd_addr_end(addr, end); ++ flag = pmd_val(*src_pmd) & KOI_FLAG_MASK; ++ // debug_printk("src_pmd=0x%16llx, dst_pmd=0x%16llx, addr=0x%16llx\n", src_pmd, dst_pmd, next); ++ // CONFIG_TRANSPARENT_HUGEPAGE is enabled, so we must add copy_huge_pmd ++ if (pmd_none(*src_pmd)) ++ continue; ++ if (!(pmd_val(*src_pmd) & PMD_TABLE_BIT)) { ++ // if src_pmd is huge page ++ debug_printk( ++ "src_pmd=0x%16llx, dst_pmd=0x%16llx, addr=0x%16llx\n", ++ src_pmd, dst_pmd, addr); ++ err = koi_copy_huge_pmd(ko_mm, dst_pmd, src_pmd, addr, prot); ++ if (err == -ENOMEM) ++ return -ENOMEM; ++ continue; ++ } ++ if (koi_copy_pte_range(ko_mm, dst_pmd, src_pmd, addr, next, prot)) ++ return -ENOMEM; ++ set_pmd(dst_pmd, __pmd((pmd_val(*dst_pmd) & (~KOI_FLAG_MASK)) | flag)); ++ debug_printk( ++ "src_pmd_val=0x%16llx, dst_pmd_val=0x%16llx, addr=0x%16llx\n", ++ pmd_val(*src_pmd), pmd_val(*dst_pmd), addr); ++ } while (dst_pmd++, src_pmd++, addr = next, addr != end); ++ return 0; +} + -+static inline void iee_set_pud_pre_init(pud_t *pudp, pud_t pud) ++int __koi_pud_alloc(struct mm_struct *mm, p4d_t *p4d, unsigned long address) +{ -+#ifdef __PAGETABLE_PUD_FOLDED -+ if (in_swapper_pgdir(pudp)) { -+ iee_set_swapper_pgd_pre_init((pgd_t *)pudp, __pgd(pud_val(pud))); -+ return; -+ } -+#endif /* __PAGETABLE_PUD_FOLDED */ -+#ifdef CONFIG_KOI -+ pudval_t val = pud_val(pud); -+ if (pud_valid(pud) && !(val & PUD_TABLE_BIT)) { -+ // There is no PUD_SEC_NG, so we use PMD_SECT_NG instead. -+ pud = __pud(val | PMD_SECT_NG); -+ } -+#endif -+ WRITE_ONCE(*pudp, pud); ++ // pud_t *new = pud_alloc_one(mm, address); + -+ if (pud_valid(pud)) { -+ dsb(ishst); -+ isb(); ++ // struct page *page = alloc_page(GFP_PGTABLE_KERNEL); ++ // pud_t *new = (pud_t *)page_address(page); ++ pud_t *new = pud_alloc_one(mm, address); ++ printk(KERN_ERR "pud alloc pud=0x%16llx\n", new); ++ if (!new) ++ return -ENOMEM; ++ ++ smp_wmb(); /* See comment in __pte_alloc */ ++ ++ spin_lock_bh(&mm->page_table_lock); ++ if (!p4d_present(*p4d)) { ++ mm_inc_nr_puds(mm); ++ p4d_populate(mm, p4d, new); ++ } else {/* Another has populated it */ ++ pud_free(mm, new); ++ // free_page((unsigned long)new); + } ++ spin_unlock_bh(&mm->page_table_lock); ++ return 0; +} + -+static inline void iee_set_pmd_pre_init(pmd_t *pmdp, pmd_t pmd) ++static inline pud_t *koi_pud_alloc(struct mm_struct *mm, p4d_t *p4d, ++ unsigned long address) +{ -+#ifdef __PAGETABLE_PMD_FOLDED -+ if (in_swapper_pgdir(pmdp)) { -+ iee_set_swapper_pgd_pre_init((pgd_t *)pmdp, __pgd(pmd_val(pmd))); -+ return; -+ } -+#endif /* __PAGETABLE_PMD_FOLDED */ -+#ifdef CONFIG_KOI -+ pmdval_t val = pmd_val(pmd); -+ if (pmd_valid(pmd) && !(val & PMD_TABLE_BIT)) { -+ pmd = __pmd(val | PMD_SECT_NG); -+ } -+#endif -+ WRITE_ONCE(*pmdp, pmd); ++ return (unlikely(p4d_none(*p4d)) && __koi_pud_alloc(mm, p4d, address)) ? ++ NULL : ++ pud_offset(p4d, address); ++} + -+ if (pmd_valid(pmd)) { -+ dsb(ishst); -+ isb(); -+ } -+} -+ -+ -+void __iee_p4d_populate_pre_init(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot) ++static int koi_copy_huge_pud(struct mm_struct *ko_mm, pud_t *dst_pud, ++ pud_t *src_pud, unsigned long addr, pteval_t prot) +{ -+ iee_set_p4d_pre_init(p4dp, __p4d(__phys_to_p4d_val(pudp) | prot)); ++ spinlock_t *src_ptl, *dst_ptl; ++ // pmd_t pmd; ++ int ret = -ENOMEM; ++ debug_printk("src_pud=0x%16llx, dst_pud=0x%16llx, addr=0x%16llx\n", ++ src_pud, dst_pud, addr); ++ dst_ptl = pud_lockptr(ko_mm, dst_pud); ++ src_ptl = pud_lockptr(&init_mm, src_pud); ++ spin_lock_bh(dst_ptl); ++ spin_lock_bh(src_ptl); ++ set_pte((pte_t *)dst_pud, __pte(pud_val(*src_pud) | prot)); ++ spin_unlock_bh(src_ptl); ++ spin_unlock_bh(dst_ptl); ++ ret = 0; ++ return ret; +} + -+void __iee_pud_populate_pre_init(pud_t *pudp, phys_addr_t pmdp, pudval_t prot) ++/** ++*koi_copy_pud_range - copy pud from kernel to driver ++*/ ++static inline int koi_copy_pud_range(struct mm_struct *ko_mm, p4d_t *dst_p4d, ++ p4d_t *src_p4d, unsigned long addr, ++ unsigned long end, pteval_t prot) +{ -+ iee_set_pud_pre_init(pudp, __pud(__phys_to_pud_val(pmdp) | prot)); ++ pud_t *src_pud, *dst_pud; ++ unsigned long next, flag; ++ dst_pud = koi_pud_alloc(ko_mm, dst_p4d, addr); ++ if (!dst_pud) ++ return -ENOMEM; ++ src_pud = pud_offset(src_p4d, addr); ++ do { ++ next = pud_addr_end(addr, end); ++ flag = pud_val(*src_pud) & KOI_FLAG_MASK; ++ debug_printk( ++ "src_pud=0x%16llx, dst_pud=0x%16llx, addr=0x%16llx\n", ++ src_pud, dst_pud, next); ++ if (pud_none(*src_pud)) { ++ continue; ++ } ++ if (!(pud_val(*src_pud) & PMD_TABLE_BIT)) { ++ // indicates that the src_pud maps to a huge page ++ koi_copy_huge_pud(ko_mm, dst_pud, src_pud, addr, prot); ++ continue; ++ } ++ // if (pud_trans_huge(*src_pud) || pud_devmap(*src_pud)) { ++ // debug_printk("pud_trans_huge=%d, pud_devmap=%d, src_pud=0x%16llx\n", pud_trans_huge(*src_pud) , pud_devmap(*src_pud), src_pud); ++ // continue; ++ // /* fall through */ ++ // } ++ if (koi_copy_pmd_range(ko_mm, dst_pud, src_pud, addr, next, prot)) ++ return -ENOMEM; ++ set_pud(dst_pud, __pud((pud_val(*dst_pud) & (~KOI_FLAG_MASK)) | flag)); ++ } while (dst_pud++, src_pud++, addr = next, addr != end); ++ return 0; +} + -+void __iee_pmd_populate_pre_init(pmd_t *pmdp, phys_addr_t ptep, -+ pmdval_t prot) ++/** ++* koi_copy_p4d_range - map the kernel pagetable to the driver space level by level ++* @ko_mm: the mm_struct of driver module ++* @dst_pgd: destination pgd ++* @src_pgd: source pgd ++* @addr: the start of address ++* @end: the end of address ++*/ ++static inline int koi_copy_p4d_range(struct mm_struct *ko_mm, pgd_t *dst_pgd, ++ pgd_t *src_pgd, unsigned long addr, ++ unsigned long end, pteval_t prot) +{ -+ iee_set_pmd_pre_init(pmdp, __pmd(__phys_to_pmd_val(ptep) | prot)); ++ p4d_t *src_p4d, *dst_p4d; ++ unsigned long next; ++ dst_p4d = p4d_alloc(ko_mm, dst_pgd, addr); ++ if (!dst_p4d) ++ return -ENOMEM; ++ src_p4d = p4d_offset(src_pgd, addr); ++ do { ++ next = p4d_addr_end(addr, end); ++ if (p4d_none(*src_p4d) || p4d_bad(*src_p4d)) ++ continue; ++ debug_printk( ++ "dst_p4d=0x%16llx, dst_p4d_val=0x%16llx\n", ++ dst_p4d, p4d_val(*dst_p4d)); ++ if (koi_copy_pud_range(ko_mm, dst_p4d, src_p4d, addr, next, prot)) { ++ return -ENOMEM; ++ } ++ } while (dst_p4d++, src_p4d++, addr = next, addr != end); ++ return 0; +} ++int koi_share_kstack(struct module *mod) ++{ ++ unsigned long kstack_start; ++ struct koi_mem_hash_node *target = NULL; ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) { ++ break; ++ } ++ } ++ kstack_start = (unsigned long)current->stack; + -+/* Funcs to set fixmap before iee initialized. */ -+bool pgattr_change_is_safe(u64 old, u64 new); -+static int iee_pud_set_huge_fixmap(pud_t *pudp, phys_addr_t phys, pgprot_t prot) ++ return koi_copy_pagetable(target->ko_mm, target->pgdp, kstack_start, ++ kstack_start + THREAD_SIZE, (0)); ++} ++EXPORT_SYMBOL(koi_share_kstack); ++/** ++*int koi_copy_pagetable - map the address range from "addr" to "end" to the driver pagetable ++*@ko_mm: the mm_struct of the driver module ++*@koi_pg_dir: koi_pg_dir, related to the driver module, the entry for driver pagetable ++*@addr: the starting address of mapping zone ++*@end: the end address of mapping zone ++*/ ++int koi_copy_pagetable(struct mm_struct *ko_mm, pgd_t *koi_pg_dir, ++ unsigned long addr, unsigned long end, pteval_t prot) +{ -+ pud_t new_pud = pfn_pud(__phys_to_pfn(phys), mk_pud_sect_prot(prot)); ++ int ret = 0; ++ unsigned long next; + -+ /* Only allow permission changes for now */ -+ if (!pgattr_change_is_safe(READ_ONCE(pud_val(*pudp)), -+ pud_val(new_pud))) -+ return 0; ++ pgd_t *src_pgd, *dst_pgd; ++ unsigned long flag; ++ src_pgd = pgd_offset_pgd(swapper_pg_dir, addr); ++ dst_pgd = pgd_offset_pgd(koi_pg_dir, addr); ++ do { ++ flag = pgd_val(*src_pgd) & KOI_FLAG_MASK; ++ next = pgd_addr_end(addr, end); ++ if (pgd_none(*src_pgd) || pgd_bad(*src_pgd)) ++ continue; ++ if (unlikely(koi_copy_p4d_range(ko_mm, dst_pgd, src_pgd, addr, ++ next, prot))) { ++ ret = -ENOMEM; ++ break; ++ } ++ set_pgd(dst_pgd, __pgd((pgd_val(*dst_pgd) & (~KOI_FLAG_MASK)) | flag)); ++ } while (dst_pgd++, src_pgd++, addr = next, addr != end); + -+ VM_BUG_ON(phys & ~PUD_MASK); -+ iee_set_fixmap_pud_pre_init(pudp, new_pud); -+ return 1; ++ return ret; +} -+ -+static int iee_pmd_set_huge_fixmap(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot) ++EXPORT_SYMBOL(koi_copy_pagetable); ++void koi_set_rdonly(unsigned long addr, pgd_t *pgdir) +{ -+ pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), mk_pmd_sect_prot(prot)); ++ p4d_t *p4dp; ++ pud_t *pudp; ++ pmd_t *pmdp; ++ pte_t *ptep; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ if (pgd_none(*pgdp) || pgd_bad(*pgdp)) { ++ return; ++ } + -+ /* Only allow permission changes for now */ -+ if (!pgattr_change_is_safe(READ_ONCE(pmd_val(*pmdp)), -+ pmd_val(new_pmd))) -+ return 0; ++ p4dp = p4d_offset(pgdp, addr); ++ if (p4d_none(*p4dp) || p4d_bad(*p4dp)) { ++ return; ++ } + -+ VM_BUG_ON(phys & ~PMD_MASK); -+ iee_set_fixmap_pmd_pre_init(pmdp, new_pmd); -+ return 1; ++ pudp = pud_offset(p4dp, addr); ++ if (pud_none(*pudp) || pud_bad(*pudp)) { ++ return; ++ } ++ pmdp = pmd_offset(pudp, addr); ++ if (pmd_none(*pmdp) || pmd_bad(*pmdp)) { ++ return; ++ } ++ ++ ptep = pte_offset_kernel(pmdp, addr); ++ if (pte_none(*ptep)) { ++ // printk(KERN_ERR "ptep 0x%16llx not available\n", ptep); ++ return; ++ } ++ set_pte(ptep, __pte(pte_val(*ptep) | PTE_RDONLY)); ++ // printk(KERN_ERR "set_readonly successfully\n"); ++ return; +} + -+static inline void __iee_pmd_populate_fixmap(pmd_t *pmdp, phys_addr_t ptep, -+ pmdval_t prot) -+{ -+ iee_set_fixmap_pmd_pre_init(pmdp, __pmd(__phys_to_pmd_val(ptep) | prot)); ++void koi_set_upage(struct module *mod, unsigned long addr, unsigned long size) { ++ struct koi_mem_hash_node *target = NULL; ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) { ++ break; ++ } ++ } ++ ++ koi_copy_pagetable(target->ko_mm, target->pgdp, addr & PAGE_MASK, ++ (addr + size + PAGE_SIZE) & PAGE_MASK, PTE_USER); +} ++EXPORT_SYMBOL(koi_set_upage); + -+static inline void __iee_pud_populate_fixmap(pud_t *pudp, phys_addr_t pmdp, pudval_t prot) ++void koi_unmap_pte_table(struct mm_struct *ko_mm, pmd_t *pmd, ++ unsigned long addr, unsigned long end) +{ -+ iee_set_fixmap_pud_pre_init(pudp, __pud(__phys_to_pud_val(pmdp) | prot)); ++ pte_t *pte; ++ if (!pmd) ++ return; ++ debug_printk("pmd=0x%16llx, addr=0x%16llx, end=0x%16llx\n", pmd, addr, ++ end); ++ ++ // struct page *page = pte_page(*pte); ++ // printk(KERN_ERR "pte=0x%16llx, pte_val=0x%16llx\n", pte, pte_val(*pte)); ++ // debug_printk("free pte table 0x%16llx, pmd=0x%16llx, page=0x%16llx, pmd points to page=0x%16llx\n", pte, pmd, page, pte_page(pmd_pte(*pmd))); ++ // printk(KERN_ERR "pmd_pfn=0x%16llx, pte_pfn=0x%16llx\n", pmd_pfn(*pmd), pte_pfn(*pte)); ++ // pte_free(ko_mm, pte_page(pmd_pte(*pmd))); ++ do { ++ pte = pte_offset_kernel(pmd, addr); ++ debug_printk("pte=0x%16llx, pte_val=0x%16llx\n", pte, ++ pte_val(*pte)); ++ set_pte(pte, __pte(0)); ++ } while (addr += PAGE_SIZE, addr != end); +} -+#endif /* END CONFIG_PTP*/ + -+void iee_set_pte_pre_init(pte_t *ptep, pte_t pte) ++void koi_unmap_pmd_range(struct mm_struct *ko_mm, pud_t *pud, ++ unsigned long addr, unsigned long end) +{ -+#ifdef CONFIG_KOI -+ if (!pte_none(pte)) { -+ pte = __pte(pte_val(pte) | PTE_NG); -+ } -+#endif -+ WRITE_ONCE(*ptep, pte); -+ -+ /* -+ * Only if the new pte is valid and kernel, otherwise TLB maintenance -+ * or update_mmu_cache() have the necessary barriers. -+ */ -+ if (pte_valid_not_user(pte)) { -+ dsb(ishst); -+ isb(); -+ } ++ pmd_t *pmd, *orig_pmd; ++ unsigned long next; ++ if (!pud) ++ return; ++ orig_pmd = pmd_offset(pud, addr); ++ pmd = orig_pmd; ++ debug_printk("pud=0x%16llx, addr=0x%16llx, end=0x%16llx\n", pud, addr, ++ end); ++ // printk(KERN_ERR "pud_pfn=0x%16llx, pmd_pfn=0x%16llx\n", pud_pfn(*pud), pmd_pfn(*pmd)); ++ do { ++ debug_printk(KERN_ERR "pmd=0x%16llx, pmd_val=0x%16llx\n", pmd, pmd_val(*pmd)); ++ next = pmd_addr_end(addr, end); ++ if (pmd_none(*pmd)) ++ continue; ++ if (pmd_bad(*pmd)) { ++ set_pmd(pmd, __pmd(0)); ++ continue; ++ } ++ koi_unmap_pte_table(ko_mm, pmd, addr, next); ++ } while (pmd++, addr = next, addr != end); +} + -+static void __init iee_set_token_page_valid_pre_init(void *token, void *new) ++void koi_unmap_pud_range(struct mm_struct *ko_mm, p4d_t *p4d, ++ unsigned long addr, unsigned long end) +{ -+ pgd_t *pgdir = swapper_pg_dir; -+ pgd_t *pgdp = pgd_offset_pgd(pgdir, (unsigned long)token); -+ -+ p4d_t *p4dp = p4d_offset(pgdp, (unsigned long)token); -+ -+ pud_t *pudp = pud_offset(p4dp, (unsigned long)token); -+ -+ pmd_t *pmdp = pmd_offset(pudp, (unsigned long)token); -+ -+ pte_t *ptep = pte_offset_kernel(pmdp, (unsigned long)token); -+ pte_t pte = READ_ONCE(*ptep); -+ pte = __pte(((pte_val(pte) | 0x1) & ~PTE_ADDR_MASK) | __phys_to_pte_val(__pa(new))); -+ iee_set_pte_pre_init(ptep, pte); -+ flush_tlb_kernel_range((unsigned long)token, (unsigned long)(token+PAGE_SIZE)); -+ isb(); ++ pud_t *pud, *orig_pud; ++ unsigned long next; ++ if (!p4d) ++ return; ++ orig_pud = pud_offset(p4d, addr); ++ pud = orig_pud; ++ debug_printk("p4d=0x%16llx, addr=0x%16llx, end=0x%16llx\n", p4d, addr, ++ end); ++ do { ++ // printk(KERN_ERR "pud=0x%16llx, pud_val=0x%16llx\n", pud, pud_val(*pud)); ++ next = pud_addr_end(addr, end); ++ if (pud_none(*pud)) ++ continue; ++ if (pud_bad(*pud)) { ++ set_pud(pud, __pud(0)); ++ continue; ++ } ++ koi_unmap_pmd_range(ko_mm, pud, addr, next); ++ } while (pud++, addr = next, addr != end); ++ debug_printk("free pud 0x%16llx, p4d=0x%16llx, orig_pud=0x%16llx\n", ++ pud, p4d, orig_pud); ++ // pud_free(ko_mm, (unsigned long)orig_pud & PAGE_MASK); +} -+#endif /* END CONFIG_IEE*/ + -+#if defined(CONFIG_KOI) && !defined(CONFIG_IEE) -+int koi_add_page_mapping(unsigned long dst, unsigned long src) ++void koi_unmap_p4d_range(struct mm_struct *ko_mm, pgd_t *pgd, ++ unsigned long addr, unsigned long end) +{ -+ pgd_t *src_pgdp, *dst_pgdp; -+ p4d_t *src_p4dp, *dst_p4dp; -+ pud_t *src_pudp, *dst_pudp; -+ pmd_t *src_pmdp, *dst_pmdp; -+ pte_t *src_ptep, *dst_ptep; ++ p4d_t *p4d, *orig_p4d; ++ unsigned long next; ++ if (!pgd) ++ return; ++ debug_printk("pgd=0x%16llx, addr=0x%16llx, end=0x%16llx\n", pgd, addr, ++ end); ++ orig_p4d = p4d_offset(pgd, addr); ++ p4d = orig_p4d; ++ do { ++ next = p4d_addr_end(addr, end); ++ debug_printk(KERN_ERR "p4d=0x%16llx, p4d_val=0x%16llx, p4d_none=%d\n", p4d, p4d_val(*p4d), p4d_none(*p4d)); ++ if (p4d_none_or_clear_bad(p4d)) { ++ // printk(KERN_ERR "p4d none=%d, p4d_bad=%d\n", p4d_none(*p4d), p4d_bad(*p4d)); ++ continue; ++ } ++ koi_unmap_pud_range(ko_mm, p4d, addr, next); ++ } while (p4d++, addr = next, addr != end); ++} + -+ src_pgdp = pgd_offset_pgd(swapper_pg_dir, src); -+ dst_pgdp = pgd_offset_pgd(swapper_pg_dir, dst); -+ -+ src_p4dp = p4d_offset(src_pgdp, src); -+ dst_p4dp = p4d_alloc(&init_mm, dst_pgdp, dst); -+ if (!dst_p4dp) { -+ return -ENOMEM; -+ } -+ src_pudp = pud_offset(src_p4dp, src); -+ dst_pudp = pud_alloc(&init_mm, dst_p4dp, dst); -+ if (!dst_pudp) { -+ return -ENOMEM; -+ } -+ if (pud_val(*src_pudp) & PMD_TABLE_BIT) { -+ src_pmdp = pmd_offset(src_pudp, src); -+ dst_pmdp = pmd_alloc(&init_mm, dst_pudp, dst); -+ if (!dst_pmdp) { -+ return -ENOMEM; -+ } -+ if (pmd_val(*src_pmdp) & PMD_TABLE_BIT) { -+ src_ptep = pte_offset_kernel(src_pmdp, src); -+ dst_ptep = pte_alloc_map(&init_mm, dst_pmdp, dst); -+ set_pte(dst_ptep, *src_ptep); -+ } else { -+ set_pte((pte_t *)dst_pmdp, pmd_pte(*src_pmdp)); -+ } -+ } else { -+ set_pte((pte_t *)dst_pudp, pud_pte(*src_pudp)); -+ } -+ ++void koi_unmap_pagetable(struct mm_struct *ko_mm, pgd_t *ko_pg_dir, ++ unsigned long addr, unsigned long end) ++{ ++ unsigned long next; ++ pgd_t *pgd = pgd_offset_pgd(ko_pg_dir, addr); ++ debug_printk("freepagetable addr=0x%16llx, end=0x%16llx\n", addr, end); ++ do { ++ next = pgd_addr_end(addr, end); ++ // printk(KERN_ERR "pgd=0x%16llx, pgd_val=0x%16llx\n", pgd, pgd_val(*pgd)); ++ if (pgd_none_or_clear_bad(pgd)) { ++ // printk(KERN_ERR "pgd none\n"); ++ continue; ++ } ++ koi_unmap_p4d_range(ko_mm, pgd, addr, next); ++ } while (pgd++, addr = next, addr != end); ++} + -+ flush_tlb_kernel_range(dst, dst+PAGE_SIZE); -+ isb(); -+ return 0; ++void koi_remove_pte_range(struct mm_struct *ko_mm, pgd_t *ko_pg_dir, pmd_t *pmd) ++{ ++ pte_t *pte = (pte_t *)pmd_page_vaddr(*pmd); ++ debug_printk( ++ "pte=0x%16llx, page=0x%16llx, pmd=0x%16llx, pmd_val=0x%16llx\n", ++ pte, pte_page(pmd_pte(*pmd)), pmd, pmd_val(*pmd)); ++ // printk(KERN_ERR "pte=0x%16llx, pte_val=0x%16llx, pte_page=0x%16llx\n", pte, pte_val(*pte), pte_page(*pte)); ++ printk(KERN_ERR "free orig_pte=0x%16llx\n", pte); ++ pte_free_kernel(ko_mm, pte); ++ // __free_page((unsigned long)pte_page(pmd_pte(*pmd))); ++ // free_page((unsigned long)pte); ++} ++ ++void koi_remove_pmd_range(struct mm_struct *ko_mm, pgd_t *ko_pg_dir, pud_t *pud) ++{ ++ pmd_t *orig_pmd = pud_pgtable(*pud); ++ pmd_t *pmd; ++ int i; ++ for (i = 0; i < PTRS_PER_PMD; i++) { ++ pmd = orig_pmd + i; ++ if (pmd_none(*pmd) || pmd_bad(*pmd)) ++ continue; ++ debug_printk("pmd=0x%16llx, pmd_val=0x%16llx\n", pmd, ++ pmd_val(*pmd)); ++ koi_remove_pte_range(ko_mm, ko_pg_dir, pmd); ++ } ++ debug_printk("free pmd=0x%16llx, page=0x%16llx\n", orig_pmd, ++ pte_page(pud_pte(*pud))); ++ printk(KERN_ERR "free orig_pmd=0x%16llx\n", orig_pmd); ++ pmd_free(ko_mm, orig_pmd); ++ // free_page((unsigned long)orig_pmd); +} + -+void koi_remove_page_mapping(unsigned long addr) { -+ pgd_t *src_pgdp; -+ p4d_t *src_p4dp; -+ pud_t *src_pudp; -+ pmd_t *src_pmdp; -+ pte_t *src_ptep; ++void koi_remove_pud_range(struct mm_struct *ko_mm, pgd_t *ko_pg_dir, p4d_t *p4d) ++{ ++ pud_t *orig_pud = p4d_pgtable(*p4d); ++ pud_t *pud; ++ int i; ++ for (i = 0; i < PTRS_PER_PUD; i++) { ++ pud = orig_pud + i; ++ if (pud_none(*pud) || pud_bad(*pud)) ++ continue; ++ debug_printk("pud=0x%16llx, pud_val=0x%16llx\n", pud, ++ pud_val(*pud)); ++ koi_remove_pmd_range(ko_mm, ko_pg_dir, pud); ++ } ++ debug_printk("free pud=0x%16llx, page=0x%16llx\n", orig_pud, ++ pte_page(p4d_pte(*p4d))); ++ printk(KERN_ERR "free orig_pud=0x%16llx\n", orig_pud); ++ pud_free(ko_mm, orig_pud); ++ // free_page((unsigned long)orig_pud); ++} + -+ src_pgdp = pgd_offset_pgd(swapper_pg_dir, addr); -+ if (pgd_none(*src_pgdp) || pgd_bad(*src_pgdp)) -+ return; -+ src_p4dp = p4d_offset(src_pgdp, addr); -+ if (p4d_none(*src_p4dp) || p4d_bad(*src_p4dp)) -+ return; -+ src_pudp = pud_offset(src_p4dp, addr); -+ if (pud_none(*src_pudp)) -+ return; -+ if (pud_val(*src_pudp) & PMD_TABLE_BIT) { -+ src_pmdp = pmd_offset(src_pudp, addr); -+ if (pmd_none(*src_pmdp)) -+ return; -+ if (pmd_val(*src_pmdp) & PMD_TABLE_BIT) { -+ src_ptep = pte_offset_kernel(src_pmdp, addr); -+ if(!pte_none(*src_ptep)) -+ pte_clear(&init_mm, addr, src_ptep); -+ } else { -+ pmd_clear(src_pmdp); -+ } -+ } else { -+ pud_clear(src_pudp); -+ } -+ -+ flush_tlb_kernel_range(addr, addr+PAGE_SIZE); -+ isb(); ++void koi_remove_pagetable(struct mm_struct *ko_mm, pgd_t *ko_pg_dir) ++{ ++ pgd_t *pgd; ++ int i; ++ for (i = 0; i < PTRS_PER_PGD; i++) { ++ pgd = ko_pg_dir + i; ++ if (p4d_none(*(p4d_t *)pgd) || p4d_bad(*(p4d_t *)pgd)) ++ continue; ++ debug_printk("pgd=0x%16llx, pgd_val=0x%16llx\n", pgd, ++ pgd_val(*pgd)); ++ koi_remove_pud_range(ko_mm, ko_pg_dir, (p4d_t *)pgd); ++ } ++ debug_printk("free pgd=0x%16llx\n", ko_pg_dir); ++ pgd_free(ko_mm, ko_pg_dir); ++ flush_tlb_all(); +} -+#endif + - void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd) - { -+ #ifdef CONFIG_PTP -+ spin_lock(&swapper_pgdir_lock); ++void koi_destroy_pagetable(struct module *mod) ++{ ++ // int cpu; ++ // unsigned long *ptr; ++ struct koi_mem_hash_node *target = NULL; ++ struct koi_mem_list *mem_node; ++ struct koi_addr_map *addr_map_node; ++ unsigned long bkt; ++ unsigned long vbar; ++ unsigned long flags; ++ asm volatile("mrs %0, VBAR_EL1\n" : "=r"(vbar) :); ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) { ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ if (target == NULL) { ++ // printk(KERN_ERR "mem node for module: %s not found, maybe destroyed before?\n", ++ // mod->name); ++ return; ++ } ++ spin_lock_irqsave(&target->mod_lock, flags); ++ target->is_valid = false; ++ spin_unlock_irqrestore(&target->mod_lock, flags); ++ ++ spin_lock_irqsave(&koi_mem_htbl_spin_lock, flags); ++ hash_del_rcu(&target->node); ++ call_rcu(&target->rcu, koi_mem_hash_node_free); ++ spin_unlock_irqrestore(&koi_mem_htbl_spin_lock, flags); ++ ++ // free addr_htbl ++ spin_lock(&target->addr_htbl_spin_lock); ++ hash_for_each_rcu (target->addr_htbl, bkt, addr_map_node, node) { ++ hash_del_rcu(&addr_map_node->node); ++ call_rcu(&addr_map_node->rcu, koi_addr_map_node_free); ++ } ++ spin_unlock(&target->addr_htbl_spin_lock); ++ // free free mem list ++ spin_lock(&target->spin_lock); ++ list_for_each_entry_rcu (mem_node, &target->mem_list_head, list) { ++ list_del_rcu(&mem_node->list); ++ call_rcu(&mem_node->rcu, koi_mem_node_free); ++ } ++ spin_unlock(&target->spin_lock); ++ ++ koi_remove_pagetable(target->ko_mm, target->ko_mm->pgd); ++ kfree(target->ko_mm); ++} ++ ++/** ++* koi_create_pagetable - create pagetable for driver ++* @mod: driver module ++* 1.create a new koi_mem_hash_node new_node ++* 2.create page table return the pgd address, init the new_node->pgdp ++* 3.create and init the new_node->ko_mm ++* 4.map swapper_ttbr1 to the newly created pagetable ++* 5.map the interrupt vector table to the newly created pagetable ++* 6.map the init_layout of the module ++* 7.map the core_layout of the module ++* 8.map switch_to_kernel_pgtable into driver view ++* 9.map share memory ++*/ ++void koi_create_pagetable(struct module *mod) ++{ ++ int ret = 0, cpu; ++ unsigned long vbar, addr, ttbr1; ++ pgd_t *pgdp; ++ unsigned long *ptr; ++ struct koi_mem_list *new_mem_node; ++ struct koi_mem_hash_node *new_node = ++ kzalloc(sizeof(struct koi_mem_hash_node), GFP_KERNEL); ++ if (!new_node) { ++ // printk(KERN_ERR "NULL new_node\n"); ++ return; ++ }; ++ if (koi_swapper_ttbr1 == 0) { ++ pgdp = lm_alias(swapper_pg_dir); ++ ttbr1 = phys_to_ttbr(virt_to_phys(pgdp)); ++ if (system_supports_cnp() && ++ !WARN_ON(pgdp != lm_alias(swapper_pg_dir))) ++ ttbr1 |= TTBR_CNP_BIT; ++ ++ koi_swapper_ttbr1 = ttbr1; ++ // __WRITE_ONCE(koi_swapper_ttbr1, ttbr1); ++ // koi_set_rdonly(&koi_swapper_ttbr1, swapper_pg_dir); ++ } ++ new_node->pgdp = koi_pgd_alloc(); ++ new_node->ko_mm = ++ kzalloc(sizeof(struct mm_struct) + ++ sizeof(unsigned long) * BITS_TO_LONGS(NR_CPUS), ++ GFP_KERNEL); ++ init_ko_mm(new_node->ko_mm, new_node->pgdp); ++ new_node->mod = mod; ++ koi_save_ttbr(mod, new_node->pgdp, new_node); ++ debug_printk("copying koi_data, start=0x%16llx, end=0x%16llx\n", ++ (unsigned long)__koi_data_start, ++ (unsigned long)__koi_data_end); ++ // copy koi_swapper_ttbr1, which records page dir base for kernel view ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, ++ (unsigned long)__koi_data_start, ++ (unsigned long)__koi_data_end, (0)); ++ asm volatile("mrs %0, VBAR_EL1\n" : "=r"(vbar) :); ++ ++ // copy interrupt vectors ++ printk(KERN_ERR ++ "\033[33mcopying interrupt vectors, start=0x%16llx, end=0x%16llx, vbar=0x%16llx\033[0m\n", ++ vbar & PAGE_MASK, (vbar + PAGE_SIZE) & PAGE_MASK, vbar); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, vbar & PAGE_MASK, ++ (vbar + PAGE_SIZE) & PAGE_MASK, (0)); ++ ++ for_each_mod_mem_type(type) { ++ printk(KERN_ERR "\033[33mcopying mem range, start=0x%16llx, end=0x%16llx\033[0m\n", ++ (unsigned long)mod->mem[type].base, ++ (unsigned long)mod->mem[type].base + mod->mem[type].size); ++ if (!mod->mem[type].base || !mod->mem[type].size) { ++ continue; ++ } ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, (unsigned long)mod->mem[type].base, (unsigned long)mod->mem[type].base + mod->mem[type].size, (0)); ++ if (ret != 0) ++ printk(KERN_ERR ++ "\033[33mError occured when copying range from 0x%llx to 0x%llx, Eno:%d\033[0m\n", ++ (unsigned long)mod->mem[type].base, ++ (unsigned long)mod->mem[type].base + mod->mem[type].size, ++ ret); ++ } ++ ++ // mapping switch_to_kernel_pgtable into driver view, which is used to switch to kernel view when entering INT ++ printk(KERN_ERR "\033[33mcopying koi_code_range, start=0x%16llx, end=0x%16llx\033[0m\n", ++ (unsigned long)__koi_code_start, ++ (unsigned long)__koi_code_end); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, ++ (unsigned long)__koi_code_start, ++ (unsigned long)__koi_code_end, (0)); ++ ++ for_each_possible_cpu (cpu) { ++ ptr = per_cpu(irq_stack_ptr, cpu); ++ debug_printk( ++ "\033[33mirq_stack_ptr on cpu %d addr=0x%16llx, end=0x%16llx\033[0m\n", ++ cpu, (unsigned long)ptr, ++ (unsigned long)ptr + IRQ_STACK_SIZE); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, ++ (unsigned long)ptr, ++ (unsigned long)ptr + IRQ_STACK_SIZE, (0)); ++ } ++ ++ for_each_possible_cpu (cpu) { ++ ptr = per_cpu(koi_irq_current_ttbr1, cpu); ++ debug_printk( ++ "\033[33mirq_current_ptr on cpu %d addr=0x%16llx, end=0x%16llx\033[0m\n", ++ cpu, (unsigned long)ptr, ++ (unsigned long)ptr + PAGE_SIZE); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, ++ (unsigned long)ptr, ++ (unsigned long)ptr + PAGE_SIZE, (0)); ++ } ++ ++#ifdef CONFIG_IEE ++ debug_printk("\033[33miee_si addr=0x%16llx, end=0x%16llx\033[0m\n", ++ (unsigned long)__iee_si_data_start, ++ (unsigned long)__iee_si_text_start); ++ // mapping iee_rwx_gate_entry and iee_si_base to ko's pagetable ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, ++ (unsigned long)__iee_si_data_start, ++ (unsigned long)__iee_si_text_start, (0)); ++ debug_printk("\033[33miee_si mapping finished\n"); ++#endif ++ ++ // alloc 16KB memory for new ko, and add it into hashtable ++ addr = (unsigned long)kmalloc(THREAD_SIZE, GFP_KERNEL); ++ if ((void *)addr == NULL) { ++ printk(KERN_ERR "alloc buffer error\n"); ++ } ++ debug_printk( ++ "\033[33mcopying buffer, start=0x%16llx, end=0x%16llx\033[0m\n", ++ addr, addr + THREAD_SIZE); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, addr, ++ addr + THREAD_SIZE, (0)); ++#ifdef CONFIG_IEE ++ iee_rw_gate(IEE_SET_KOI_PGD, new_node->ko_mm->pgd); ++#endif ++ new_mem_node = kmalloc(sizeof(struct koi_mem_list), GFP_KERNEL); ++ if (new_mem_node == NULL) { ++ printk(KERN_ERR "alloc new_mem_node error\n"); ++ } ++ new_mem_node->addr = addr; ++ new_mem_node->size = THREAD_SIZE; ++ ++ new_node->mem_list_head = ++ (struct list_head)LIST_HEAD_INIT(new_node->mem_list_head); ++ hash_init(new_node->addr_htbl); ++ spin_lock_init(&new_node->addr_htbl_spin_lock); ++ spin_lock_init(&new_node->spin_lock); ++ spin_lock_init(&new_node->mod_lock); ++ new_node->is_valid = true; ++ ++ spin_lock(&new_node->spin_lock); ++ list_add_rcu(&new_mem_node->list, &new_node->mem_list_head); ++ spin_unlock(&new_node->spin_lock); ++ ++ spin_lock(&koi_mem_htbl_spin_lock); ++ hash_add_rcu(koi_mem_htbl, &new_node->node, ++ (unsigned long)new_node->mod); ++ spin_unlock(&koi_mem_htbl_spin_lock); ++ ++ // printk(KERN_DEBUG "mod=0x%16llx, end=0x16llx\n", mod, (unsigned long)mod + sizeof(struct module)); ++ printk(KERN_ERR "[KOI] create pagetable pgd=0x%16llx for module %s\n", new_node->pgdp, mod->name); ++ // printk(KERN_ERR "koi mm=0x%16llx\n", (unsigned long)(new_node->ko_mm)); ++} ++/** ++* koi_mem_alloc ++*@mod: driver module ++*@orig_addr: the starting address of the parameter in kernel ++*@size: the size of the parameter ++*/ ++unsigned long koi_mem_alloc(struct module *mod, unsigned long orig_addr, ++ unsigned long size) ++{ ++ struct koi_mem_hash_node *target = NULL; ++ struct koi_mem_list *mem_node; ++ struct koi_addr_map *new_addr_node; ++ unsigned long addr = 0, flags; ++ struct koi_mem_list *new_mem_node; ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) { ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ if (target == NULL) { ++ printk(KERN_ERR "mem node for module: %s not found\n", ++ mod->name); ++ return 0; ++ } ++ spin_lock_irqsave(&target->spin_lock, flags); ++ list_for_each_entry_rcu (mem_node, &target->mem_list_head, list) { ++ if (mem_node->size >= size) { ++ addr = mem_node->addr; ++ mem_node->size -= size; ++ if (mem_node->size == 0) { ++ list_del_rcu(&mem_node->list); ++ } else { ++ new_mem_node = ++ kmalloc(sizeof(struct koi_mem_list), ++ GFP_ATOMIC); ++ new_mem_node->addr = addr + size; ++ new_mem_node->size = mem_node->size; ++ list_replace_rcu(&mem_node->list, ++ &new_mem_node->list); ++ } ++ call_rcu(&mem_node->rcu, koi_mem_node_free); ++ } ++ } ++ spin_unlock_irqrestore(&target->spin_lock, flags); ++ if (!addr) { ++ addr = (unsigned long)kmalloc(THREAD_SIZE, GFP_KERNEL); ++ if ((void *)addr == NULL) { ++ return 0; ++ } ++ koi_copy_pagetable(target->ko_mm, target->pgdp, addr, ++ addr + THREAD_SIZE, (0)); ++ mem_node = kmalloc(sizeof(struct koi_mem_list), GFP_KERNEL); ++ if (!mem_node) { ++ printk(KERN_ERR "NULL mem_node\n"); ++ } ++ if (size > THREAD_SIZE) { ++ return 0; ++ } ++ mem_node->addr = addr + size; ++ mem_node->size = THREAD_SIZE - size; ++ spin_lock_irqsave(&target->spin_lock, flags); ++ list_add_tail_rcu(&mem_node->list, &target->mem_list_head); ++ spin_unlock_irqrestore(&target->spin_lock, flags); ++ } ++ ++ new_addr_node = kzalloc(sizeof(struct koi_addr_map), GFP_KERNEL); ++ new_addr_node->buffer_addr = addr; ++ new_addr_node->orig_addr = orig_addr; ++ spin_lock_irqsave(&target->addr_htbl_spin_lock, flags); ++ hash_add_rcu(target->addr_htbl, &new_addr_node->node, ++ new_addr_node->buffer_addr); ++ spin_unlock_irqrestore(&target->addr_htbl_spin_lock, flags); ++ return addr; ++} ++EXPORT_SYMBOL(koi_mem_alloc); ++// find the parameter pointer corresponding to the copy ++noinline void *koi_mem_lookup(struct module *mod, unsigned long addr) ++{ ++ struct koi_mem_hash_node *target = NULL; ++ struct koi_addr_map *addr_map_node; ++ unsigned long orig_addr = addr; ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) { ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ if (target == NULL) { ++ printk(KERN_ERR "mem node for module: %s not found\n", ++ mod->name); ++ return NULL; ++ } ++ ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (target->addr_htbl, addr_map_node, node, ++ orig_addr) { ++ if (addr_map_node->buffer_addr == addr) { ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ if (addr_map_node) { ++ return (void *)(addr_map_node->orig_addr); ++ } else { ++ return NULL; ++ } ++} ++EXPORT_SYMBOL(koi_mem_lookup); ++/** ++* kio_mem_free - recycle a copy of the copied parameters and synchronize the parameters ++* @mod: driver module ++* @addr: the starting addr of parameter ++* @size: the size of the parameter ++* @is_const: const pointers or not ++* @count: contry the number of parameters ++*/ ++noinline void koi_mem_free(struct module *mod, unsigned long addr, ++ unsigned long size, bool is_const, int count, ...) ++{ ++ struct koi_mem_hash_node *target = NULL; ++ struct koi_mem_list *mem_node; ++ struct list_head *pos = NULL; ++ struct koi_addr_map *addr_map_node; ++ unsigned long orig_size = size; ++ unsigned long orig_addr = addr; ++ va_list valist; ++ int i; ++ unsigned int offset; ++ unsigned long flags; ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) { ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ if (target == NULL) { ++ printk(KERN_ERR "mem node for module: %s not found\n", ++ mod->name); ++ return; ++ } ++ ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (target->addr_htbl, addr_map_node, node, ++ orig_addr) { ++ if (addr_map_node->buffer_addr == orig_addr) { ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ va_start(valist, count); ++ for (i = 0; i < count; i++) { ++ offset = va_arg(valist, int); ++ *(unsigned long *)(addr_map_node->buffer_addr + offset) = ++ *(unsigned long *)(addr_map_node->orig_addr + offset); ++ } ++ va_end(valist); ++ memcpy((void *)addr_map_node->orig_addr, ++ (void *)addr_map_node->buffer_addr, orig_size); ++ ++ spin_lock_irqsave(&target->addr_htbl_spin_lock, flags); ++ hlist_del_init_rcu(&addr_map_node->node); ++ call_rcu(&addr_map_node->rcu, koi_addr_map_node_free); ++ spin_unlock_irqrestore(&target->addr_htbl_spin_lock, flags); ++ ++ spin_lock_irqsave(&target->spin_lock, flags); ++ list_for_each_entry_rcu (mem_node, &target->mem_list_head, list) { ++ if (mem_node->addr + mem_node->size == addr) { ++ pos = mem_node->list.prev; ++ addr = mem_node->addr; ++ size += mem_node->size; ++ list_del_rcu(&mem_node->list); ++ call_rcu(&mem_node->rcu, koi_mem_node_free); ++ } else if (addr + size == mem_node->addr) { ++ if (!pos) ++ pos = mem_node->list.prev; ++ size += mem_node->size; ++ list_del_rcu(&mem_node->list); ++ call_rcu(&mem_node->rcu, koi_mem_node_free); ++ } else if (addr + size < mem_node->addr) { ++ if (!pos) ++ pos = mem_node->list.prev; ++ break; ++ } ++ } ++ mem_node = kzalloc(sizeof(struct koi_mem_list), GFP_ATOMIC); ++ mem_node->addr = addr; ++ mem_node->size = size; ++ if (pos) ++ list_add_rcu(&mem_node->list, pos); ++ else ++ list_add_tail_rcu(&mem_node->list, &target->mem_list_head); ++ spin_unlock_irqrestore(&target->spin_lock, flags); ++} ++EXPORT_SYMBOL(koi_mem_free); ++/** ++* koi_mem_free_callback - used to recycle the copy of parameter. ++*@addr: the address of the parameter ++*@(*func)(void*): callback func, used to release the copy of the parameter pointer ++*/ ++noinline void koi_mem_free_callback(struct module *mod, unsigned long addr, ++ unsigned long size, void (*func)(void *)) ++{ ++ struct koi_mem_hash_node *target = NULL; ++ struct koi_mem_list *mem_node; ++ struct list_head *pos = NULL; ++ struct koi_addr_map *addr_map_node; ++ unsigned long flags; ++ unsigned long orig_size = size; ++ unsigned long orig_addr = addr; ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) { ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ if (target == NULL) { ++ // printk("mem node for module: %s not found\n", mod->name); ++ return; ++ } ++ ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (target->addr_htbl, addr_map_node, node, ++ orig_addr) { ++ if (addr_map_node->buffer_addr == orig_addr) { ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ if (addr_map_node != NULL) { ++ memcpy((void *)addr_map_node->orig_addr, ++ (void *)addr_map_node->buffer_addr, orig_size); ++ func((void *)addr_map_node->orig_addr); ++ } else { ++ printk("Cannot find addr_map_node in addr_htbl, maybe addr is in kernel space!!\n"); ++ func((void *)orig_addr); ++ } ++ ++ spin_lock_irqsave(&target->addr_htbl_spin_lock, flags); ++ if (addr_map_node != NULL) { ++ hlist_del_init_rcu(&addr_map_node->node); ++ call_rcu(&addr_map_node->rcu, koi_addr_map_node_free); ++ } ++ spin_unlock_irqrestore(&target->addr_htbl_spin_lock, flags); ++ spin_lock_irqsave(&target->spin_lock, flags); ++ list_for_each_entry_rcu (mem_node, &target->mem_list_head, list) { ++ if (mem_node->addr + mem_node->size == addr) { ++ pos = mem_node->list.prev; ++ addr = mem_node->addr; ++ size += mem_node->size; ++ list_del_rcu(&mem_node->list); ++ call_rcu(&mem_node->rcu, koi_mem_node_free); ++ } else if (addr + size == mem_node->addr) { ++ if (!pos) ++ pos = mem_node->list.prev; ++ size += mem_node->size; ++ list_del_rcu(&mem_node->list); ++ call_rcu(&mem_node->rcu, koi_mem_node_free); ++ } else if (addr + size < mem_node->addr) { ++ if (!pos) ++ pos = mem_node->list.prev; ++ break; ++ } ++ } ++ mem_node = kzalloc(sizeof(struct koi_mem_list), GFP_ATOMIC); ++ mem_node->addr = addr; ++ mem_node->size = size; ++ if (pos) ++ list_add_rcu(&mem_node->list, pos); ++ else ++ list_add_tail_rcu(&mem_node->list, &target->mem_list_head); ++ spin_unlock_irqrestore(&target->spin_lock, flags); ++} ++EXPORT_SYMBOL(koi_mem_free_callback); ++ ++void koi_map_mem(struct module *mod, unsigned long addr, unsigned long size) ++{ ++ struct koi_mem_hash_node *target = NULL; ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) ++ break; ++ } ++ rcu_read_unlock(); ++ ++ if (target == NULL) { ++ printk(KERN_ERR "mem node for module: %s not found\n", ++ mod->name); ++ return; ++ } ++ koi_copy_pagetable(target->ko_mm, target->pgdp, addr & PAGE_MASK, ++ (addr + size + PAGE_SIZE) & PAGE_MASK, (0)); ++ flush_tlb_kernel_range(addr & PAGE_MASK, ++ (addr + size + PAGE_SIZE) & PAGE_MASK); ++} ++EXPORT_SYMBOL(koi_map_mem); ++ ++void koi_unmap_mem(struct module *mod, unsigned long addr, unsigned long size) ++{ ++ struct koi_mem_hash_node *target = NULL; ++ if (!addr || ! size) { ++ return; ++ } ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) ++ break; ++ } ++ rcu_read_unlock(); ++ ++ if (target == NULL) { ++ printk(KERN_ERR "[KOI UNMAP] mem node for module: %s not found\n", ++ mod->name); ++ return; ++ } ++ koi_unmap_pagetable(target->ko_mm, target->pgdp, addr & PAGE_MASK, ++ (addr + size + PAGE_SIZE) & PAGE_MASK); ++ flush_tlb_kernel_range(addr & PAGE_MASK, ++ (addr + size + PAGE_SIZE) & PAGE_MASK); ++} ++EXPORT_SYMBOL(koi_unmap_mem); ++/** ++* koi_mem_free_to_user - function 'copy_to_user' in driver space ++*/ ++void koi_mem_free_to_user(struct module *mod, unsigned long addr, ++ unsigned long size) ++{ ++ struct koi_mem_hash_node *target = NULL; ++ struct koi_mem_list *mem_node; ++ struct list_head *pos = NULL; ++ struct koi_addr_map *addr_map_node; ++ unsigned long flags; ++ unsigned long orig_size = size; ++ unsigned long orig_addr = addr; ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) { ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ if (target == NULL) { ++ printk(KERN_ERR "mem node for module: %s not found\n", ++ mod->name); ++ return; ++ } ++ ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (target->addr_htbl, addr_map_node, node, ++ orig_addr) { ++ if (addr_map_node->buffer_addr == orig_addr) { ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ if (copy_to_user((void *)addr_map_node->orig_addr, ++ (void *)addr_map_node->buffer_addr, orig_size)) { ++ return; ++ } ++ ++ spin_lock_irqsave(&target->addr_htbl_spin_lock, flags); ++ hlist_del_init_rcu(&addr_map_node->node); ++ call_rcu(&addr_map_node->rcu, koi_addr_map_node_free); ++ spin_unlock_irqrestore(&target->addr_htbl_spin_lock, flags); ++ spin_lock_irqsave(&target->spin_lock, flags); ++ list_for_each_entry_rcu (mem_node, &target->mem_list_head, list) { ++ if (mem_node->addr + mem_node->size == addr) { ++ pos = mem_node->list.prev; ++ addr = mem_node->addr; ++ size += mem_node->size; ++ list_del_rcu(&mem_node->list); ++ call_rcu(&mem_node->rcu, koi_mem_node_free); ++ } else if (addr + size == mem_node->addr) { ++ if (!pos) ++ pos = mem_node->list.prev; ++ size += mem_node->size; ++ list_del_rcu(&mem_node->list); ++ call_rcu(&mem_node->rcu, koi_mem_node_free); ++ } else if (addr + size < mem_node->addr) { ++ if (!pos) ++ pos = mem_node->list.prev; ++ break; ++ } ++ } ++ mem_node = kzalloc(sizeof(struct koi_mem_list), GFP_ATOMIC); ++ mem_node->addr = addr; ++ mem_node->size = size; ++ if (pos) ++ list_add_rcu(&mem_node->list, pos); ++ else ++ list_add_tail_rcu(&mem_node->list, &target->mem_list_head); ++ spin_unlock_irqrestore(&target->spin_lock, flags); ++} ++EXPORT_SYMBOL(koi_mem_free_to_user); ++// map the driver stack to kernel ++void koi_map_kostack(struct module *mod) ++{ ++} ++EXPORT_SYMBOL(koi_map_kostack); ++ ++#ifndef CONFIG_IEE ++void koi_init_token(struct task_struct *tsk) ++{ ++ struct task_token *token_addr = ++ (struct task_token *)(__phys_to_virt(__pa(tsk)) + KOI_OFFSET); ++ ++ token_addr->koi_kernel_stack = NULL; ++ // token_addr->koi_stack = NULL; ++ // token_addr->koi_stack_base = NULL; ++ token_addr->current_ttbr1 = 0; ++} ++ ++#endif +\ No newline at end of file +diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c +index cea96ee75d22..cbddc8e464e4 100644 +--- a/arch/arm64/kernel/mte.c ++++ b/arch/arm64/kernel/mte.c +@@ -79,8 +79,13 @@ int memcmp_pages(struct page *page1, struct page *page2) + static inline void __mte_enable_kernel(const char *mode, unsigned long tcf) + { + /* Enable MTE Sync Mode for EL1. */ ++#ifdef CONFIG_IEE ++ sysreg_clear_set_iee_si(sctlr_el1, SCTLR_EL1_TCF_MASK, ++ SYS_FIELD_PREP(SCTLR_EL1, TCF, tcf)); ++#else + sysreg_clear_set(sctlr_el1, SCTLR_EL1_TCF_MASK, + SYS_FIELD_PREP(SCTLR_EL1, TCF, tcf)); ++#endif + isb(); + + pr_info_once("MTE: enabled in %s mode at EL1\n", mode); +diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c +index 068e5bb2661b..e545a2df805f 100644 +--- a/arch/arm64/kernel/process.c ++++ b/arch/arm64/kernel/process.c +@@ -471,7 +471,14 @@ DEFINE_PER_CPU(struct task_struct *, __entry_task); + + static void entry_task_switch(struct task_struct *next) + { ++ #if defined(CONFIG_IEE) || defined (CONFIG_KOI) ++ if(next == &init_task) ++ __this_cpu_write(__entry_task, (struct task_struct *)__va(__pa_symbol(next))); ++ else ++ __this_cpu_write(__entry_task, next); ++ #else + __this_cpu_write(__entry_task, next); ++ #endif + } + + /* +@@ -506,11 +513,15 @@ static void erratum_1418040_new_exec(void) + */ + void update_sctlr_el1(u64 sctlr) + { +- /* ++ /* + * EnIA must not be cleared while in the kernel as this is necessary for + * in-kernel PAC. It will be cleared on kernel exit if needed. + */ ++ #ifdef CONFIG_IEE ++ sysreg_clear_set_iee_si(sctlr_el1, SCTLR_USER_MASK & ~SCTLR_ELx_ENIA, sctlr); ++ #else + sysreg_clear_set(sctlr_el1, SCTLR_USER_MASK & ~SCTLR_ELx_ENIA, sctlr); ++ #endif + + /* ISB required for the kernel uaccess routines when setting TCF0. */ + isb(); +diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c +index 58a97861bfc5..c7839247327d 100644 +--- a/arch/arm64/kernel/proton-pack.c ++++ b/arch/arm64/kernel/proton-pack.c +@@ -551,7 +551,11 @@ static enum mitigation_state spectre_v4_enable_hw_mitigation(void) + return state; + + if (spectre_v4_mitigations_off()) { ++#ifdef CONFIG_IEE ++ sysreg_clear_set_iee_si(sctlr_el1, 0, SCTLR_ELx_DSSBS); ++#else + sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_DSSBS); ++#endif + set_pstate_ssbs(1); + return SPECTRE_VULNERABLE; + } +@@ -975,7 +979,11 @@ static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot) + if (arm64_kernel_unmapped_at_el0()) + return; + ++#ifdef CONFIG_IEE ++ iee_rwx_gate_entry(IEE_WRITE_vbar_el1, v); ++#else + write_sysreg(v, vbar_el1); ++#endif + isb(); + } + +diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c +index d82fd6902ea8..84f4fce0b8bc 100644 +--- a/arch/arm64/kernel/setup.c ++++ b/arch/arm64/kernel/setup.c +@@ -33,6 +33,11 @@ + #include + #include + ++#ifdef CONFIG_IEE ++#include ++#include ++#endif ++ + #include + #include + #include +@@ -336,10 +341,31 @@ u64 cpu_logical_map(unsigned int cpu) + return __cpu_logical_map[cpu]; + } + ++#ifdef CONFIG_IEE ++/* used for secure modification of vbar*/ ++extern char __bp_harden_el1_vectors[]; ++/* prepare iee rwx gate for senario of ttbr1=init_pg_dir */ ++static void __init iee_si_init_early(void) ++{ ++ /* prepare data used for iee rwx gate. */ ++ iee_base_swapper_pg_dir = phys_to_ttbr(__pa_symbol(swapper_pg_dir)); ++ iee_base_idmap_pg_dir = phys_to_ttbr(__pa_symbol(idmap_pg_dir)); ++ iee_base_reserved_pg_dir = phys_to_ttbr(__pa_symbol(reserved_pg_dir)) ++ | FIELD_PREP(TTBR_ASID_MASK, 1); ++ iee_base__bp_harden_el1_vectors = (unsigned long)__bp_harden_el1_vectors; ++ iee_si_tcr = 0; ++} ++#endif ++ + void __init __no_sanitize_address setup_arch(char **cmdline_p) + { + setup_initial_init_mm(_stext, _etext, _edata, _end); + ++ #ifdef CONFIG_IEE ++ init_new_context(&init_task, &init_mm); ++ atomic64_set(&init_mm.context.id, (1UL << get_cpu_asid_bits()) | INIT_ASID); ++ #endif ++ + *cmdline_p = boot_command_line; + + kaslr_init(); +@@ -375,6 +401,14 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p) + */ + local_daif_restore(DAIF_PROCCTX_NOIRQ); + ++#ifdef CONFIG_IEE ++ /* ++ * Map iee si codes to init_pg_dir to run the following ++ * cpu_uninstall_idmap() which writes ttbr0. ++ */ ++ iee_si_init_early(); ++#endif ++ + /* + * TTBR0 is only used for the identity mapping at this stage. Make it + * point to zero page to avoid speculatively fetching new entries. +diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c +index b7b7afb4a8c7..168a9390d6e9 100644 +--- a/arch/arm64/kernel/traps.c ++++ b/arch/arm64/kernel/traps.c +@@ -902,6 +902,32 @@ const char *esr_get_class_string(unsigned long esr) + return esr_class_str[ESR_ELx_EC(esr)]; + } + ++#ifdef CONFIG_IEE ++extern void arm64_enter_nmi(struct pt_regs *regs); ++static const char *handler[]= { ++ "SP_EL0", ++ "ELR_EL1", ++ "TCR_EL1", ++ "TTBR0 ASID" ++ "IEE_SI" ++}; ++ ++asmlinkage void notrace iee_bad_mode(struct pt_regs *regs, int reason, unsigned int esr) ++{ ++ arm64_enter_nmi(regs); ++ ++ console_verbose(); ++ ++ pr_crit("IEE : Bad mode in %s check detected on CPU%d, code 0x%08x -- %s\n", ++ handler[reason], smp_processor_id(), esr, ++ esr_get_class_string(esr)); ++ ++ __show_regs(regs); ++ local_daif_mask(); ++ panic("bad mode"); ++} ++#endif ++ + /* + * bad_el0_sync handles unexpected, but potentially recoverable synchronous + * exceptions taken from EL0. +diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S +index 3cd7e76cc562..8f074828f706 100644 +--- a/arch/arm64/kernel/vmlinux.lds.S ++++ b/arch/arm64/kernel/vmlinux.lds.S +@@ -134,6 +134,51 @@ jiffies = jiffies_64; + #define UNWIND_DATA_SECTIONS + #endif + ++#ifdef CONFIG_IEE ++#define IEE_TEXT \ ++ . = ALIGN(PAGE_SIZE); \ ++ __iee_code_start = .; \ ++ *(.iee.text.header) \ ++ *(.iee.text) \ ++ . = ALIGN(PAGE_SIZE); \ ++ __iee_code_end = .; ++#else ++#define IEE_TEXT ++#endif ++ ++#ifdef CONFIG_IEE ++#define IEE_SI_TEXT \ ++ . = ALIGN(PAGE_SIZE); \ ++ __iee_si_data_start = .; \ ++ *(.iee.si_data) \ ++ . = ALIGN(PAGE_SIZE); \ ++ __iee_exec_entry_start = .; \ ++ __iee_si_no_irq = . + (16); \ ++ *(.iee.exec_entry) \ ++ . = ALIGN(PAGE_SIZE); \ ++ __iee_si_text_start = .; \ ++ *(.iee.si_text) \ ++ . = ALIGN(PAGE_SIZE); \ ++ . += PAGE_SIZE - (24); \ ++ __iee_si_text_end = . + (24); \ ++ *(.iee.exec_exit) \ ++ . = ALIGN(PAGE_SIZE); ++ ++#else ++#define IEE_SI_TEXT ++#endif ++ ++#ifdef CONFIG_KOI ++#define KOI_TEXT \ ++ . = ALIGN(PAGE_SIZE); \ ++ __koi_code_start = .; \ ++ *(.koi.text) \ ++ . = ALIGN(PAGE_SIZE); \ ++ __koi_code_end = .; ++#else ++#define KOI_TEXT ++#endif ++ + /* + * The size of the PE/COFF section that covers the kernel image, which + * runs from _stext to _edata, must be a round multiple of the PE/COFF +@@ -176,10 +221,13 @@ SECTIONS + SOFTIRQENTRY_TEXT + ENTRY_TEXT + TEXT_TEXT ++ IEE_TEXT + SCHED_TEXT + LOCK_TEXT + KPROBES_TEXT + HYPERVISOR_TEXT ++ IEE_SI_TEXT ++ KOI_TEXT + *(.gnu.warning) + } + +@@ -318,6 +366,18 @@ SECTIONS + . += INIT_DIR_SIZE; + init_pg_end = .; + ++ #ifdef CONFIG_IEE ++ . = ALIGN(PAGE_SIZE*8); ++ init_iee_stack_begin = .; ++ . += PAGE_SIZE*4; ++ init_iee_stack_end = .; ++ ++ . = ALIGN(PAGE_SIZE); ++ init_iee_si_stack_begin = .; ++ . += PAGE_SIZE*4; ++ init_iee_si_stack_end = .; ++ #endif ++ + . = ALIGN(SEGMENT_ALIGN); + __pecoff_data_size = ABSOLUTE(. - __initdata_begin); + _end = .; +diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c +index 188197590fc9..b6d8a7d0aeca 100644 +--- a/arch/arm64/mm/context.c ++++ b/arch/arm64/mm/context.c +@@ -17,6 +17,10 @@ + #include + #include + ++#ifdef CONFIG_IEE ++#include ++#endif ++ + static u32 asid_bits; + static DEFINE_RAW_SPINLOCK(cpu_asid_lock); + +@@ -39,7 +43,11 @@ static unsigned long *pinned_asid_map; + #define asid2ctxid(asid, genid) ((asid) | (genid)) + + /* Get the ASIDBits supported by the current CPU */ ++#ifdef CONFIG_IEE ++u32 get_cpu_asid_bits(void) ++#else + static u32 get_cpu_asid_bits(void) ++#endif + { + u32 asid; + int fld = cpuid_feature_extract_unsigned_field(read_cpuid(ID_AA64MMFR0_EL1), +@@ -96,6 +104,16 @@ static void set_reserved_asid_bits(void) + set_kpti_asid_bits(asid_map); + else + bitmap_clear(asid_map, 0, NUM_USER_ASIDS); ++ #ifdef CONFIG_IEE ++ unsigned int len = BITS_TO_LONGS(NUM_USER_ASIDS) * sizeof(unsigned long); ++ memset(asid_map, 0xaa, len); ++ __set_bit(INIT_ASID, asid_map); ++ #else ++ #ifdef CONFIG_KOI ++ unsigned int len = BITS_TO_LONGS(NUM_USER_ASIDS) * sizeof(unsigned long); ++ memset(asid_map, 0xaa, len); ++ #endif ++ #endif + } + + #define asid_gen_match(asid) \ +@@ -212,6 +230,38 @@ static u64 new_context(struct mm_struct *mm) + return asid2ctxid(asid, generation); + } + ++#ifdef CONFIG_KOI ++/* ++ * This function is used to check and allocate ASID for ko's pgd ++ * The mm MUST point to the isolated kos' mm_struct, other behaviours are undefined. ++ */ ++void koi_check_and_switch_context(struct mm_struct *mm) { ++ u64 asid = atomic64_read(&mm->context.id); ++ u64 old_active_asid; ++ unsigned long flags; ++ unsigned int cpu; ++ ++ old_active_asid = atomic64_read(this_cpu_ptr(&active_asids)); ++ if (old_active_asid && asid_gen_match(asid) && atomic64_cmpxchg_relaxed(this_cpu_ptr(&active_asids), old_active_asid, asid)) { ++ return; ++ } ++ ++ raw_spin_lock_irqsave(&cpu_asid_lock, flags); ++ asid = atomic64_read(&mm->context.id); ++ if (!asid_gen_match(asid)) { ++ asid = new_context(mm); ++ atomic64_set(&mm->context.id, asid); ++ } ++ ++ cpu = smp_processor_id(); ++ if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) ++ local_flush_tlb_all(); ++ ++ atomic64_set(this_cpu_ptr(&active_asids), asid); ++ raw_spin_unlock_irqrestore(&cpu_asid_lock, flags); ++} ++#endif ++ + void check_and_switch_context(struct mm_struct *mm) + { + unsigned long flags; +@@ -348,7 +398,9 @@ asmlinkage void post_ttbr_update_workaround(void) + + void cpu_do_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm) + { ++ #ifndef CONFIG_IEE + unsigned long ttbr1 = read_sysreg(ttbr1_el1); ++ #endif + unsigned long asid = ASID(mm); + unsigned long ttbr0 = phys_to_ttbr(pgd_phys); + +@@ -360,14 +412,28 @@ void cpu_do_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm) + if (IS_ENABLED(CONFIG_ARM64_SW_TTBR0_PAN)) + ttbr0 |= FIELD_PREP(TTBR_ASID_MASK, asid); + +- /* Set ASID in TTBR1 since TCR.A1 is set */ ++ #ifdef CONFIG_IEE ++ ttbr0 |= FIELD_PREP(TTBR_ASID_MASK, asid+1); ++ iee_rwx_gate_entry(IEE_CONTEXT_SWITCH, ttbr0); ++ // TODO : if defined CONFIG_IEE and defined CONFIG_KOI ++ #else ++ /* Set ASID in TTBR0 since TCR.A1 is set 0*/ ++ ++ #ifdef CONFIG_KOI ++ ttbr0 |= FIELD_PREP(TTBR_ASID_MASK, asid+1); ++ ttbr1 &= ~TTBR_ASID_MASK; ++ ttbr1 |= FIELD_PREP(TTBR_ASID_MASK, asid); ++ #else + ttbr1 &= ~TTBR_ASID_MASK; + ttbr1 |= FIELD_PREP(TTBR_ASID_MASK, asid); +- ++ ++ #endif + cpu_set_reserved_ttbr0_nosync(); + write_sysreg(ttbr1, ttbr1_el1); + write_sysreg(ttbr0, ttbr0_el1); + isb(); ++ #endif ++ + post_ttbr_update_workaround(); + } + +@@ -375,11 +441,28 @@ static int asids_update_limit(void) + { + unsigned long num_available_asids = NUM_USER_ASIDS; + +- if (arm64_kernel_unmapped_at_el0()) { +- num_available_asids /= 2; +- if (pinned_asid_map) +- set_kpti_asid_bits(pinned_asid_map); ++ if (arm64_kernel_unmapped_at_el0()) { ++ num_available_asids /= 2; ++ if (pinned_asid_map) ++ set_kpti_asid_bits(pinned_asid_map); + } ++ #if defined(CONFIG_IEE) ++ num_available_asids /= 2; ++ if (pinned_asid_map) { ++ unsigned int len = BITS_TO_LONGS(NUM_USER_ASIDS) * sizeof(unsigned long); ++ memset(pinned_asid_map, 0xaa, len); ++ __set_bit(INIT_ASID, pinned_asid_map); ++ } ++ #else ++ #ifdef CONFIG_KOI ++ num_available_asids /= 2; ++ if (pinned_asid_map) { ++ unsigned int len = BITS_TO_LONGS(NUM_USER_ASIDS) * sizeof(unsigned long); ++ memset(pinned_asid_map, 0xaa, len); ++ } ++ #endif ++ #endif ++ + /* + * Expect allocation after rollover to fail if we don't have at least + * one more ASID than CPUs. ASID #0 is reserved for init_mm. +@@ -400,6 +483,10 @@ arch_initcall(asids_update_limit); + + static int asids_init(void) + { ++ #if defined(CONFIG_IEE) || defined(CONFIG_KOI) ++ unsigned int len; ++ #endif ++ + asid_bits = get_cpu_asid_bits(); + atomic64_set(&asid_generation, ASID_FIRST_VERSION); + asid_map = bitmap_zalloc(NUM_USER_ASIDS, GFP_KERNEL); +@@ -410,13 +497,25 @@ static int asids_init(void) + pinned_asid_map = bitmap_zalloc(NUM_USER_ASIDS, GFP_KERNEL); + nr_pinned_asids = 0; + +- /* +- * We cannot call set_reserved_asid_bits() here because CPU +- * caps are not finalized yet, so it is safer to assume KPTI +- * and reserve kernel ASID's from beginning. +- */ +- if (IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0)) +- set_kpti_asid_bits(asid_map); ++ #ifdef CONFIG_IEE ++ len = BITS_TO_LONGS(NUM_USER_ASIDS) * sizeof(unsigned long); ++ memset(asid_map, 0xaa, len); ++ __set_bit(INIT_ASID, asid_map); ++ #else ++ #ifdef CONFIG_KOI ++ len = BITS_TO_LONGS(NUM_USER_ASIDS) * sizeof(unsigned long); ++ memset(asid_map, 0xaa, len); ++ #else ++ /* ++ * We cannot call set_reserved_asid_bits() here because CPU ++ * caps are not finalized yet, so it is safer to assume KPTI ++ * and reserve kernel ASID's from beginning. ++ */ ++ if (IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0)) ++ set_kpti_asid_bits(asid_map); ++ #endif ++ #endif ++ + return 0; + } + early_initcall(asids_init); +diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c +index 4ea07caba71c..909c75bf9e41 100644 +--- a/arch/arm64/mm/fault.c ++++ b/arch/arm64/mm/fault.c +@@ -261,7 +261,15 @@ int __ptep_set_access_flags(struct vm_area_struct *vma, + pteval ^= PTE_RDONLY; + pteval |= pte_val(entry); + pteval ^= PTE_RDONLY; ++ #ifdef CONFIG_KOI ++ if (pteval & PTE_VALID) ++ pteval |= PTE_NG; ++ #endif ++ #ifdef CONFIG_PTP ++ pteval = iee_set_cmpxchg_relaxed(ptep, old_pteval, pteval); ++ #else + pteval = cmpxchg_relaxed(&pte_val(*ptep), old_pteval, pteval); ++ #endif + } while (pteval != old_pteval); + + /* Invalidate a stale read-only entry */ +@@ -376,8 +384,13 @@ static void do_tag_recovery(unsigned long addr, unsigned long esr, + * It will be done lazily on the other CPUs when they will hit a + * tag fault. + */ ++ #ifdef CONFIG_IEE ++ sysreg_clear_set_iee_si(sctlr_el1, SCTLR_EL1_TCF_MASK, ++ SYS_FIELD_PREP_ENUM(SCTLR_EL1, TCF, NONE)); ++ #else + sysreg_clear_set(sctlr_el1, SCTLR_EL1_TCF_MASK, + SYS_FIELD_PREP_ENUM(SCTLR_EL1, TCF, NONE)); ++ #endif + isb(); + } + +diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c +index bfc02568805a..580ecb596d2d 100644 +--- a/arch/arm64/mm/fixmap.c ++++ b/arch/arm64/mm/fixmap.c +@@ -32,6 +32,22 @@ static pte_t bm_pte[NR_BM_PTE_TABLES][PTRS_PER_PTE] __page_aligned_bss; + static pmd_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss __maybe_unused; + static pud_t bm_pud[PTRS_PER_PUD] __page_aligned_bss __maybe_unused; + ++#ifdef CONFIG_IEE ++void *bm_pte_addr = (void *)bm_pte; ++void *bm_pmd_addr = (void *)bm_pmd; ++void *bm_pud_addr = (void *)bm_pud; ++#endif ++ ++#ifdef CONFIG_PTP ++extern void __iee_p4d_populate_pre_init(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot); ++extern void __iee_pud_populate_pre_init(pud_t *pudp, phys_addr_t pmdp, pudval_t prot); ++extern void __iee_pmd_populate_pre_init(pmd_t *pmdp, phys_addr_t ptep, ++ pmdval_t prot); ++ ++extern void iee_set_p4d_pre_init(p4d_t *p4dp, p4d_t p4d); ++#define set_pgd_init(pgdptr, pgdval) iee_set_p4d_pre_init((p4d_t *)(pgdptr), (p4d_t) { pgdval }) ++#endif ++ + static inline pte_t *fixmap_pte(unsigned long addr) + { + return &bm_pte[BM_PTE_TABLE_IDX(addr)][pte_index(addr)]; +@@ -44,7 +60,11 @@ static void __init early_fixmap_init_pte(pmd_t *pmdp, unsigned long addr) + + if (pmd_none(pmd)) { + ptep = bm_pte[BM_PTE_TABLE_IDX(addr)]; ++ #ifdef CONFIG_PTP ++ __iee_pmd_populate_pre_init(pmdp, __pa_symbol(ptep), PMD_TYPE_TABLE); ++ #else + __pmd_populate(pmdp, __pa_symbol(ptep), PMD_TYPE_TABLE); ++ #endif + } + } + +@@ -55,8 +75,13 @@ static void __init early_fixmap_init_pmd(pud_t *pudp, unsigned long addr, + pud_t pud = READ_ONCE(*pudp); + pmd_t *pmdp; + +- if (pud_none(pud)) ++ if (pud_none(pud)) { ++ #ifdef CONFIG_PTP ++ __iee_pud_populate_pre_init(pudp, __pa_symbol(bm_pmd), PUD_TYPE_TABLE); ++ #else + __pud_populate(pudp, __pa_symbol(bm_pmd), PUD_TYPE_TABLE); ++ #endif ++ } + + pmdp = pmd_offset_kimg(pudp, addr); + do { +@@ -82,8 +107,13 @@ static void __init early_fixmap_init_pud(p4d_t *p4dp, unsigned long addr, + BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES)); + } + +- if (p4d_none(p4d)) ++ if (p4d_none(p4d)) { ++ #ifdef CONFIG_PTP ++ __iee_p4d_populate_pre_init(p4dp, __pa_symbol(bm_pud), P4D_TYPE_TABLE); ++ #else + __p4d_populate(p4dp, __pa_symbol(bm_pud), P4D_TYPE_TABLE); ++ #endif ++ } + + pudp = pud_offset_kimg(p4dp, addr); + early_fixmap_init_pmd(pudp, addr, end); +@@ -106,6 +136,27 @@ void __init early_fixmap_init(void) + early_fixmap_init_pud(p4dp, addr, end); + } + ++#ifdef CONFIG_PTP ++extern void iee_set_pte_pre_init(pte_t *ptep, pte_t pte); ++void __iee_set_fixmap_pre_init(enum fixed_addresses idx, ++ phys_addr_t phys, pgprot_t flags) ++{ ++ unsigned long addr = __fix_to_virt(idx); ++ pte_t *ptep; ++ ++ BUG_ON(idx <= FIX_HOLE || idx >= __end_of_fixed_addresses); ++ ++ ptep = fixmap_pte(addr); ++ ++ if (pgprot_val(flags)) { ++ iee_set_pte_pre_init(ptep, pfn_pte(phys >> PAGE_SHIFT, flags)); ++ } else { ++ iee_set_pte_pre_init(ptep, __pte(0)); ++ flush_tlb_kernel_range(addr, addr+PAGE_SIZE); ++ } ++} ++#endif ++ + /* + * Unusually, this is also called in IRQ context (ghes_iounmap_irq) so if we + * ever need to use IPIs for TLB broadcasting, then we're in trouble here. +@@ -121,9 +172,17 @@ void __set_fixmap(enum fixed_addresses idx, + ptep = fixmap_pte(addr); + + if (pgprot_val(flags)) { ++ #ifdef CONFIG_PTP ++ iee_set_bm_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags)); ++ #else + __set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags)); ++ #endif + } else { ++ #ifdef CONFIG_PTP ++ iee_set_bm_pte(ptep, __pte(0)); ++ #else + __pte_clear(&init_mm, addr, ptep); ++ #endif + flush_tlb_kernel_range(addr, addr+PAGE_SIZE); + } + } +@@ -179,8 +238,13 @@ void __init fixmap_copy(pgd_t *pgdir) + * live in the carveout for the swapper_pg_dir. We can simply + * re-use the existing dir for the fixmap. + */ ++ #ifdef CONFIG_PTP ++ set_pgd_init(pgd_offset_pgd(pgdir, FIXADDR_TOT_START), ++ READ_ONCE(*pgd_offset_k(FIXADDR_TOT_START))); ++ #else + set_pgd(pgd_offset_pgd(pgdir, FIXADDR_TOT_START), + READ_ONCE(*pgd_offset_k(FIXADDR_TOT_START))); ++ #endif + } else if (CONFIG_PGTABLE_LEVELS > 3) { + pgd_t *bm_pgdp; + p4d_t *bm_p4dp; +@@ -194,9 +258,15 @@ void __init fixmap_copy(pgd_t *pgdir) + BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES)); + bm_pgdp = pgd_offset_pgd(pgdir, FIXADDR_TOT_START); + bm_p4dp = p4d_offset(bm_pgdp, FIXADDR_TOT_START); ++ #ifdef CONFIG_PTP ++ bm_pudp = pud_set_fixmap_offset_init(bm_p4dp, FIXADDR_TOT_START); ++ __iee_pud_populate_pre_init(bm_pudp, __pa(lm_alias(bm_pmd)), PMD_TYPE_TABLE); ++ pud_clear_fixmap_init(); ++ #else + bm_pudp = pud_set_fixmap_offset(bm_p4dp, FIXADDR_TOT_START); + pud_populate(&init_mm, bm_pudp, lm_alias(bm_pmd)); + pud_clear_fixmap(); ++ #endif + } else { + BUG(); + } +diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c +index 66a7fff9f373..fa3726fb793d 100644 +--- a/arch/arm64/mm/init.c ++++ b/arch/arm64/mm/init.c +@@ -56,8 +56,20 @@ + * that cannot be mistaken for a real physical address. + */ + s64 memstart_addr __ro_after_init = -1; ++#if defined(CONFIG_IEE) || defined(CONFIG_KOI) ++s64 memstart_addr_init __ro_after_init = -1; ++#endif ++#ifdef CONFIG_KOI ++s64 koi_offset __ro_after_init = -1; ++EXPORT_SYMBOL(koi_offset); ++#endif ++#ifdef CONFIG_IEE ++s64 iee_offset __ro_after_init = -1; ++extern s64 iee_si_offset; ++#endif + EXPORT_SYMBOL(memstart_addr); + ++ + /* + * If the corresponding config options are enabled, we create both ZONE_DMA + * and ZONE_DMA32. By default ZONE_DMA covers the 32-bit addressable memory +@@ -422,7 +434,11 @@ early_param("memmap", parse_memmap_opt); + + void __init arm64_memblock_init(void) + { ++ #if defined(CONFIG_IEE) || defined(CONFIG_KOI) ++ s64 linear_region_size = BIT(vabits_actual - 2); ++ #else + s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual); ++ #endif + + /* + * Corner case: 52-bit VA capable systems running KVM in nVHE mode may +@@ -439,13 +455,24 @@ void __init arm64_memblock_init(void) + } + + /* Remove memory above our supported physical address size */ ++ #ifdef CONFIG_IEE ++ // If config iee, phys size can not be above 0x400000000000 ++ if(__pa_symbol(_end) > BIT_ULL(vabits_actual - 2)) ++ panic("Image on too high phys mem.\n"); ++ else ++ memblock_remove(BIT_ULL(vabits_actual - 2), ULLONG_MAX); ++ #else + memblock_remove(1ULL << PHYS_MASK_SHIFT, ULLONG_MAX); ++ #endif + + /* + * Select a suitable value for the base of physical memory. + */ + memstart_addr = round_down(memblock_start_of_DRAM(), + ARM64_MEMSTART_ALIGN); ++ #if defined(CONFIG_IEE) || defined(CONFIG_KOI) ++ memstart_addr_init = memstart_addr; ++ #endif + + if ((memblock_end_of_DRAM() - memstart_addr) > linear_region_size) + pr_warn("Memory doesn't fit in the linear mapping, VA_BITS too small\n"); +@@ -532,6 +559,15 @@ void __init arm64_memblock_init(void) + ((range * memstart_offset_seed) >> 16); + } + } ++ ++ #ifdef CONFIG_KOI ++ koi_offset = memstart_addr - memstart_addr_init + ((unsigned long)BIT(vabits_actual - 2)); ++ #endif ++ #ifdef CONFIG_IEE ++ iee_offset = memstart_addr - memstart_addr_init + ((unsigned long)BIT(vabits_actual - 2)); ++ iee_si_offset = iee_offset; ++ #endif ++ //printk(KERN_ERR "koi_offset: 0x%16llx\n", koi_offset); + + /* + * Register the kernel text, kernel data, initrd, and initial +diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c +index 31f04f19b635..753fa8d887f3 100644 +--- a/arch/arm64/mm/mmu.c ++++ b/arch/arm64/mm/mmu.c +@@ -6,6 +6,7 @@ + * Copyright (C) 2012 ARM Ltd. + */ + ++#include "asm/pgtable.h" + #include + #include + #include +@@ -41,6 +42,14 @@ + #include + #include + #include ++#ifdef CONFIG_IEE ++#include ++#include ++#include ++#endif ++#ifdef CONFIG_PTP ++#include ++#endif + + #define NO_BLOCK_MAPPINGS BIT(0) + #define NO_CONT_MAPPINGS BIT(1) +@@ -77,8 +86,249 @@ EXPORT_SYMBOL(empty_zero_page); + static DEFINE_SPINLOCK(swapper_pgdir_lock); + static DEFINE_MUTEX(fixmap_lock); + ++#ifdef CONFIG_IEE ++extern struct cred init_cred; ++ ++extern unsigned long __iee_si_data_start[]; ++extern unsigned long __iee_exec_entry_start[]; ++extern unsigned long __iee_si_text_start[]; ++extern unsigned long __iee_si_text_end[]; ++ ++extern void *bm_pte_addr; ++extern void *bm_pmd_addr; ++extern void *bm_pud_addr; ++ ++void *init_token_page_vaddr; ++ ++#ifdef CONFIG_PTP ++ ++/* Funcs to set pgtable before iee initialized. */ ++static void iee_set_swapper_pgd_pre_init(pgd_t *pgdp, pgd_t pgd) ++{ ++ pgd_t *fixmap_pgdp; ++ ++ spin_lock(&swapper_pgdir_lock); ++ fixmap_pgdp = pgd_set_fixmap_init(__pa_symbol(pgdp)); ++ WRITE_ONCE(*fixmap_pgdp, pgd); ++ /* ++ * We need dsb(ishst) here to ensure the page-table-walker sees ++ * our new entry before set_p?d() returns. The fixmap's ++ * flush_tlb_kernel_range() via clear_fixmap() does this for us. ++ */ ++ pgd_clear_fixmap_init(); ++ spin_unlock(&swapper_pgdir_lock); ++} ++ ++void iee_set_p4d_pre_init(p4d_t *p4dp, p4d_t p4d) ++{ ++ if (in_swapper_pgdir(p4dp)) { ++ iee_set_swapper_pgd_pre_init((pgd_t *)p4dp, __pgd(p4d_val(p4d))); ++ return; ++ } ++ ++ WRITE_ONCE(*p4dp, p4d); ++ dsb(ishst); ++ isb(); ++} ++ ++static inline void iee_set_pud_pre_init(pud_t *pudp, pud_t pud) ++{ ++#ifdef __PAGETABLE_PUD_FOLDED ++ if (in_swapper_pgdir(pudp)) { ++ iee_set_swapper_pgd_pre_init((pgd_t *)pudp, __pgd(pud_val(pud))); ++ return; ++ } ++#endif /* __PAGETABLE_PUD_FOLDED */ ++#ifdef CONFIG_KOI ++ pudval_t val = pud_val(pud); ++ if (pud_valid(pud) && !(val & PUD_TABLE_BIT)) { ++ // There is no PUD_SEC_NG, so we use PMD_SECT_NG instead. ++ pud = __pud(val | PMD_SECT_NG); ++ } ++#endif ++ WRITE_ONCE(*pudp, pud); ++ ++ if (pud_valid(pud)) { ++ dsb(ishst); ++ isb(); ++ } ++} ++ ++static inline void iee_set_pmd_pre_init(pmd_t *pmdp, pmd_t pmd) ++{ ++#ifdef __PAGETABLE_PMD_FOLDED ++ if (in_swapper_pgdir(pmdp)) { ++ iee_set_swapper_pgd_pre_init((pgd_t *)pmdp, __pgd(pmd_val(pmd))); ++ return; ++ } ++#endif /* __PAGETABLE_PMD_FOLDED */ ++#ifdef CONFIG_KOI ++ pmdval_t val = pmd_val(pmd); ++ if (pmd_valid(pmd) && !(val & PMD_TABLE_BIT)) { ++ pmd = __pmd(val | PMD_SECT_NG); ++ } ++#endif ++ WRITE_ONCE(*pmdp, pmd); ++ ++ if (pmd_valid(pmd)) { ++ dsb(ishst); ++ isb(); ++ } ++} ++ ++ ++void __iee_p4d_populate_pre_init(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot) ++{ ++ iee_set_p4d_pre_init(p4dp, __p4d(__phys_to_p4d_val(pudp) | prot)); ++} ++ ++void __iee_pud_populate_pre_init(pud_t *pudp, phys_addr_t pmdp, pudval_t prot) ++{ ++ iee_set_pud_pre_init(pudp, __pud(__phys_to_pud_val(pmdp) | prot)); ++} ++ ++void __iee_pmd_populate_pre_init(pmd_t *pmdp, phys_addr_t ptep, ++ pmdval_t prot) ++{ ++ iee_set_pmd_pre_init(pmdp, __pmd(__phys_to_pmd_val(ptep) | prot)); ++} ++ ++/* Funcs to set fixmap before iee initialized. */ ++bool pgattr_change_is_safe(u64 old, u64 new); ++static int iee_pud_set_huge_fixmap(pud_t *pudp, phys_addr_t phys, pgprot_t prot) ++{ ++ pud_t new_pud = pfn_pud(__phys_to_pfn(phys), mk_pud_sect_prot(prot)); ++ ++ /* Only allow permission changes for now */ ++ if (!pgattr_change_is_safe(READ_ONCE(pud_val(*pudp)), ++ pud_val(new_pud))) ++ return 0; ++ ++ VM_BUG_ON(phys & ~PUD_MASK); ++ iee_set_fixmap_pud_pre_init(pudp, new_pud); ++ return 1; ++} ++ ++static int iee_pmd_set_huge_fixmap(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot) ++{ ++ pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), mk_pmd_sect_prot(prot)); ++ ++ /* Only allow permission changes for now */ ++ if (!pgattr_change_is_safe(READ_ONCE(pmd_val(*pmdp)), ++ pmd_val(new_pmd))) ++ return 0; ++ ++ VM_BUG_ON(phys & ~PMD_MASK); ++ iee_set_fixmap_pmd_pre_init(pmdp, new_pmd); ++ return 1; ++} ++ ++static inline void __iee_pmd_populate_fixmap(pmd_t *pmdp, phys_addr_t ptep, ++ pmdval_t prot) ++{ ++ iee_set_fixmap_pmd_pre_init(pmdp, __pmd(__phys_to_pmd_val(ptep) | prot)); ++} ++ ++static inline void __iee_pud_populate_fixmap(pud_t *pudp, phys_addr_t pmdp, pudval_t prot) ++{ ++ iee_set_fixmap_pud_pre_init(pudp, __pud(__phys_to_pud_val(pmdp) | prot)); ++} ++#endif /* END CONFIG_PTP*/ ++ ++void iee_set_pte_pre_init(pte_t *ptep, pte_t pte) ++{ ++#ifdef CONFIG_KOI ++ if (pte_valid(pte)) { ++ pte = __pte(pte_val(pte) | PTE_NG); ++ } ++#endif ++ WRITE_ONCE(*ptep, pte); ++ ++ /* ++ * Only if the new pte is valid and kernel, otherwise TLB maintenance ++ * or update_mmu_cache() have the necessary barriers. ++ */ ++ if (pte_valid_not_user(pte)) { ++ dsb(ishst); ++ isb(); ++ } ++} ++ ++static void __init iee_set_token_page_valid_pre_init(void *token, void *new) ++{ ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, (unsigned long)token); ++ ++ p4d_t *p4dp = p4d_offset(pgdp, (unsigned long)token); ++ ++ pud_t *pudp = pud_offset(p4dp, (unsigned long)token); ++ ++ pmd_t *pmdp = pmd_offset(pudp, (unsigned long)token); ++ ++ pte_t *ptep = pte_offset_kernel(pmdp, (unsigned long)token); ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(((pte_val(pte) | 0x1) & ~PTE_ADDR_MASK) | __phys_to_pte_val(__pa(new))); ++ #ifdef CONFIG_PTP ++ iee_set_pte_pre_init(ptep, pte); ++ #else ++ set_pte(ptep, pte); ++ #endif ++ flush_tlb_kernel_range((unsigned long)token, (unsigned long)(token+PAGE_SIZE)); ++ isb(); ++} ++#endif /* END CONFIG_IEE*/ ++ ++#if defined(CONFIG_KOI) && !defined(CONFIG_IEE) ++ ++void koi_add_page_mapping(void *token, void *new) ++{ ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, (unsigned long)token); ++ ++ p4d_t *p4dp = p4d_offset(pgdp, (unsigned long)token); ++ ++ pud_t *pudp = pud_offset(p4dp, (unsigned long)token); ++ ++ pmd_t *pmdp = pmd_offset(pudp, (unsigned long)token); ++ ++ pte_t *ptep = pte_offset_kernel(pmdp, (unsigned long)token); ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(((pte_val(pte) | 0x1) & ~PTE_ADDR_MASK) | __phys_to_pte_val(__pa(new))); ++ set_pte(ptep, pte); ++ dsb(ishst); ++ isb(); ++ ++ flush_tlb_kernel_range((unsigned long)new, (unsigned long)new+PAGE_SIZE); ++ flush_tlb_kernel_range((unsigned long)token, (unsigned long)token+PAGE_SIZE); ++ isb(); ++} ++ ++void koi_remove_page_mapping(unsigned long token) { ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, token); ++ ++ p4d_t *p4dp = p4d_offset(pgdp, token); ++ ++ pud_t *pudp = pud_offset(p4dp, token); ++ ++ pmd_t *pmdp = pmd_offset(pudp, token); ++ ++ pte_t *ptep = pte_offset_kernel(pmdp, token); ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(((pte_val(pte) & ~((unsigned long)0x1)) & ~PTE_ADDR_MASK) | __phys_to_pte_val(__pa(token - KOI_OFFSET))); ++ set_pte(ptep, pte); ++ flush_tlb_kernel_range(token, token+PAGE_SIZE); ++ isb(); ++} ++#endif ++ + void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd) + { ++ #ifdef CONFIG_PTP ++ spin_lock(&swapper_pgdir_lock); + iee_rw_gate(IEE_OP_SET_SWAPPER_PGD, pgdp, pgd); + spin_unlock(&swapper_pgdir_lock); + #else - pgd_t *fixmap_pgdp; + pgd_t *fixmap_pgdp; + + spin_lock(&swapper_pgdir_lock); +@@ -91,6 +341,7 @@ void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd) + */ + pgd_clear_fixmap(); + spin_unlock(&swapper_pgdir_lock); ++ #endif + } + + pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, +@@ -104,6 +355,34 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, + } + EXPORT_SYMBOL(phys_mem_access_prot); + ++#ifdef CONFIG_PTP ++phys_addr_t __init early_pgtable_alloc(int shift) ++{ ++ phys_addr_t phys; ++ void *ptr; ++ ++ phys = memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE); ++ if (!phys) ++ panic("Failed to allocate page table page\n"); ++ ++ /* ++ * The FIX_{PGD,PUD,PMD} slots may be in active use, but the FIX_PTE ++ * slot will be free, so we can (ab)use the FIX_PTE slot to initialise ++ * any level of table. ++ */ ++ ptr = pte_set_fixmap_init(phys); ++ ++ memset(ptr, 0, PAGE_SIZE); ++ ++ /* ++ * Implicit barriers also ensure the zeroed page is visible to the page ++ * table walker ++ */ ++ pte_clear_fixmap_init(); ++ ++ return phys; ++} ++#else + static phys_addr_t __init early_pgtable_alloc(int shift) + { + phys_addr_t phys; +@@ -119,7 +398,11 @@ static phys_addr_t __init early_pgtable_alloc(int shift) + * slot will be free, so we can (ab)use the FIX_PTE slot to initialise + * any level of table. + */ ++ #ifdef CONFIG_PTP ++ ptr = pte_set_fixmap_init(phys); ++ #else + ptr = pte_set_fixmap(phys); ++ #endif + + memset(ptr, 0, PAGE_SIZE); + +@@ -127,10 +410,15 @@ static phys_addr_t __init early_pgtable_alloc(int shift) + * Implicit barriers also ensure the zeroed page is visible to the page + * table walker + */ ++ #ifdef CONFIG_PTP ++ pte_clear_fixmap_init(); ++ #else + pte_clear_fixmap(); ++ #endif + + return phys; + } ++#endif + + bool pgattr_change_is_safe(u64 old, u64 new) + { +@@ -179,7 +467,11 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end, + do { + pte_t old_pte = __ptep_get(ptep); + ++ #ifdef CONFIG_PTP ++ iee_set_fixmap_pte_pre_init(ptep, pfn_pte(__phys_to_pfn(phys), prot)); ++ #else + __set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot)); ++ #endif + + /* + * After the PTE entry has been populated once, we +@@ -212,7 +504,11 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr, + pmdval |= PMD_TABLE_PXN; + BUG_ON(!pgtable_alloc); + pte_phys = pgtable_alloc(PAGE_SHIFT); ++ #ifdef CONFIG_PTP ++ __iee_pmd_populate_fixmap(pmdp, pte_phys, pmdval); ++ #else + __pmd_populate(pmdp, pte_phys, pmdval); ++ #endif + pmd = READ_ONCE(*pmdp); + } + BUG_ON(pmd_bad(pmd)); +@@ -247,9 +543,17 @@ static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end, + next = pmd_addr_end(addr, end); + + /* try section mapping first */ ++ #ifdef CONFIG_IEE ++ if (!((pmd_val(old_pmd) & PTE_VALID) && (pmd_val(old_pmd) & PTE_TABLE_BIT)) && (((addr | next | phys) & ~PMD_MASK) == 0 && (flags & NO_BLOCK_MAPPINGS) == 0)) { ++ #else + if (((addr | next | phys) & ~PMD_MASK) == 0 && + (flags & NO_BLOCK_MAPPINGS) == 0) { ++ #endif ++ #ifdef CONFIG_PTP ++ iee_pmd_set_huge_fixmap(pmdp, phys, prot); ++ #else + pmd_set_huge(pmdp, phys, prot); ++ #endif + + /* + * After the PMD entry has been populated once, we +@@ -290,7 +594,11 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr, + pudval |= PUD_TABLE_PXN; + BUG_ON(!pgtable_alloc); + pmd_phys = pgtable_alloc(PMD_SHIFT); +- __pud_populate(pudp, pmd_phys, pudval); ++ #ifdef CONFIG_PTP ++ __iee_pud_populate_fixmap(pudp, pmd_phys, PUD_TYPE_TABLE); ++ #else ++ __pud_populate(pudp, pmd_phys, PUD_TYPE_TABLE); ++ #endif + pud = READ_ONCE(*pudp); + } + BUG_ON(pud_bad(pud)); +@@ -343,10 +651,21 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end, + /* + * For 4K granule only, attempt to put down a 1GB block + */ ++ #ifdef CONFIG_IEE ++ alloc_init_cont_pmd(pudp, addr, next, phys, prot, ++ pgtable_alloc, flags); ++ ++ BUG_ON(pud_val(old_pud) != 0 && ++ pud_val(old_pud) != READ_ONCE(pud_val(*pudp))); ++ #else + if (pud_sect_supported() && + ((addr | next | phys) & ~PUD_MASK) == 0 && + (flags & NO_BLOCK_MAPPINGS) == 0) { ++ #ifdef CONFIG_PTP ++ iee_pud_set_huge_fixmap(pudp, phys, prot); ++ #else + pud_set_huge(pudp, phys, prot); ++ #endif + + /* + * After the PUD entry has been populated once, we +@@ -361,6 +680,7 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end, + BUG_ON(pud_val(old_pud) != 0 && + pud_val(old_pud) != READ_ONCE(pud_val(*pudp))); + } ++ #endif + phys += next - addr; + } while (pudp++, addr = next, addr != end); + +@@ -375,6 +695,10 @@ static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys, + { + unsigned long addr, end, next; + pgd_t *pgdp = pgd_offset_pgd(pgdir, virt); ++ #ifdef CONFIG_IEE ++ p4d_t *p4dp; ++ p4d_t p4d; ++ #endif + + /* + * If the virtual and physical address don't have the same offset +@@ -391,10 +715,14 @@ static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys, + next = pgd_addr_end(addr, end); + alloc_init_pud(pgdp, addr, next, phys, prot, pgtable_alloc, + flags); ++ #ifdef CONFIG_IEE ++ p4dp = p4d_offset(pgdp, addr); ++ p4d = READ_ONCE(*p4dp); ++ __p4d_populate(p4dp, __p4d_to_phys(p4d), (PGD_APT | PUD_TYPE_TABLE)); ++ #endif + phys += next - addr; + } while (pgdp++, addr = next, addr != end); + } +- + static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys, + unsigned long virt, phys_addr_t size, + pgprot_t prot, +@@ -414,90 +742,364 @@ void create_kpti_ng_temp_pgd(pgd_t *pgdir, phys_addr_t phys, unsigned long virt, + phys_addr_t (*pgtable_alloc)(int), int flags); + #endif + +-static phys_addr_t __pgd_pgtable_alloc(int shift) ++#ifdef CONFIG_PTP ++static int __init iee_pud_set_huge_pre_init(pud_t *pudp, phys_addr_t phys, pgprot_t prot) + { +- void *ptr = (void *)__get_free_page(GFP_PGTABLE_KERNEL); +- BUG_ON(!ptr); ++ pud_t new_pud = pfn_pud(__phys_to_pfn(phys), mk_pud_sect_prot(prot)); + +- /* Ensure the zeroed page is visible to the page table walker */ +- dsb(ishst); +- return __pa(ptr); ++ /* Only allow permission changes for now */ ++ if (!pgattr_change_is_safe(READ_ONCE(pud_val(*pudp)), ++ pud_val(new_pud))) ++ return 0; ++ ++ VM_BUG_ON(phys & ~PUD_MASK); ++ iee_set_pud_pre_init(pudp, new_pud); ++ return 1; + } + +-static phys_addr_t pgd_pgtable_alloc(int shift) ++static int __init iee_pmd_set_huge_pre_init(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot) + { +- phys_addr_t pa = __pgd_pgtable_alloc(shift); +- struct ptdesc *ptdesc = page_ptdesc(phys_to_page(pa)); ++ pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), mk_pmd_sect_prot(prot)); + +- /* +- * Call proper page table ctor in case later we need to +- * call core mm functions like apply_to_page_range() on +- * this pre-allocated page table. +- * +- * We don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK if pmd is +- * folded, and if so pagetable_pte_ctor() becomes nop. +- */ +- if (shift == PAGE_SHIFT) +- BUG_ON(!pagetable_pte_ctor(ptdesc)); +- else if (shift == PMD_SHIFT) +- BUG_ON(!pagetable_pmd_ctor(ptdesc)); ++ /* Only allow permission changes for now */ ++ if (!pgattr_change_is_safe(READ_ONCE(pmd_val(*pmdp)), ++ pmd_val(new_pmd))) ++ return 0; + +- return pa; ++ VM_BUG_ON(phys & ~PMD_MASK); ++ iee_set_pmd_pre_init(pmdp, new_pmd); ++ return 1; + } + +-/* +- * This function can only be used to modify existing table entries, +- * without allocating new levels of table. Note that this permits the +- * creation of new section or page entries. +- */ +-void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt, +- phys_addr_t size, pgprot_t prot) ++static __init void iee_init_pte_pre_init(pmd_t *pmdp, unsigned long addr, unsigned long end, ++ phys_addr_t phys, pgprot_t prot) + { +- if (virt < PAGE_OFFSET) { +- pr_warn("BUG: not creating mapping for %pa at 0x%016lx - outside kernel range\n", +- &phys, virt); +- return; +- } +- __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, +- NO_CONT_MAPPINGS); +-} ++ pte_t *ptep; + +-void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, +- unsigned long virt, phys_addr_t size, +- pgprot_t prot, bool page_mappings_only) +-{ +- int flags = 0; ++ ptep = pte_set_fixmap_offset_init(pmdp, addr); ++ do { ++ pte_t old_pte = READ_ONCE(*ptep); + +- BUG_ON(mm == &init_mm); ++ iee_set_pte_pre_init(ptep, pfn_pte(__phys_to_pfn(phys), prot)); + +- if (page_mappings_only) +- flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; ++ /* ++ * After the PTE entry has been populated once, we ++ * only allow updates to the permission attributes. ++ */ ++ BUG_ON(!pgattr_change_is_safe(pte_val(old_pte), ++ READ_ONCE(pte_val(*ptep)))); + +- __create_pgd_mapping(mm->pgd, phys, virt, size, prot, +- pgd_pgtable_alloc, flags); ++ phys += PAGE_SIZE; ++ } while (ptep++, addr += PAGE_SIZE, addr != end); ++ ++ pte_clear_fixmap_init(); + } + +-static void update_mapping_prot(phys_addr_t phys, unsigned long virt, +- phys_addr_t size, pgprot_t prot) ++static __init void iee_alloc_init_cont_pte_pre_init(pmd_t *pmdp, unsigned long addr, ++ unsigned long end, phys_addr_t phys, ++ pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(int), ++ int flags) + { +- if (virt < PAGE_OFFSET) { +- pr_warn("BUG: not updating mapping for %pa at 0x%016lx - outside kernel range\n", +- &phys, virt); +- return; ++ unsigned long next; ++ pmd_t pmd = READ_ONCE(*pmdp); ++ ++ BUG_ON(pmd_sect(pmd)); ++ if (pmd_none(pmd)) { ++ pmdval_t pmdval = PMD_TYPE_TABLE | PMD_TABLE_UXN; ++ phys_addr_t pte_phys; ++ ++ if (flags & NO_EXEC_MAPPINGS) ++ pmdval |= PMD_TABLE_PXN; ++ BUG_ON(!pgtable_alloc); ++ pte_phys = pgtable_alloc(PAGE_SHIFT); ++ __iee_pmd_populate_pre_init(pmdp, pte_phys, pmdval); ++ pmd = READ_ONCE(*pmdp); + } ++ BUG_ON(pmd_bad(pmd)); + +- __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, +- NO_CONT_MAPPINGS); ++ do { ++ pgprot_t __prot = prot; + +- /* flush the TLBs after updating live kernel mappings */ +- flush_tlb_kernel_range(virt, virt + size); ++ next = pte_cont_addr_end(addr, end); ++ ++ /* use a contiguous mapping if the range is suitably aligned */ ++ if ((((addr | next | phys) & ~CONT_PTE_MASK) == 0) && ++ (flags & NO_CONT_MAPPINGS) == 0) ++ __prot = __pgprot(pgprot_val(prot) | PTE_CONT); ++ ++ iee_init_pte_pre_init(pmdp, addr, next, phys, __prot); ++ ++ phys += next - addr; ++ } while (addr = next, addr != end); ++} ++ ++static __init void iee_init_pmd_pre_init(pud_t *pudp, unsigned long addr, unsigned long end, ++ phys_addr_t phys, pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(int), int flags) ++{ ++ unsigned long next; ++ pmd_t *pmdp; ++ ++ pmdp = pmd_set_fixmap_offset_init(pudp, addr); ++ do { ++ pmd_t old_pmd = READ_ONCE(*pmdp); ++ ++ next = pmd_addr_end(addr, end); ++ ++ /* try section mapping first */ ++ if (((addr | next | phys) & ~PMD_MASK) == 0 && ++ (flags & NO_BLOCK_MAPPINGS) == 0) { ++ iee_pmd_set_huge_pre_init(pmdp, phys, prot); ++ ++ /* ++ * After the PMD entry has been populated once, we ++ * only allow updates to the permission attributes. ++ */ ++ BUG_ON(!pgattr_change_is_safe(pmd_val(old_pmd), ++ READ_ONCE(pmd_val(*pmdp)))); ++ } else { ++ iee_alloc_init_cont_pte_pre_init(pmdp, addr, next, phys, prot, ++ pgtable_alloc, flags); ++ ++ BUG_ON(pmd_val(old_pmd) != 0 && ++ pmd_val(old_pmd) != READ_ONCE(pmd_val(*pmdp))); ++ } ++ phys += next - addr; ++ } while (pmdp++, addr = next, addr != end); ++ ++ pmd_clear_fixmap_init(); ++} ++ ++static __init void iee_alloc_init_cont_pmd_pre_init(pud_t *pudp, unsigned long addr, ++ unsigned long end, phys_addr_t phys, ++ pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(int), int flags) ++{ ++ unsigned long next; ++ pud_t pud = READ_ONCE(*pudp); ++ ++ /* ++ * Check for initial section mappings in the pgd/pud. ++ */ ++ BUG_ON(pud_sect(pud)); ++ if (pud_none(pud)) { ++ pudval_t pudval = PUD_TYPE_TABLE | PUD_TABLE_UXN; ++ phys_addr_t pmd_phys; ++ ++ if (flags & NO_EXEC_MAPPINGS) ++ pudval |= PUD_TABLE_PXN; ++ BUG_ON(!pgtable_alloc); ++ pmd_phys = pgtable_alloc(PMD_SHIFT); ++ __iee_pud_populate_pre_init(pudp, pmd_phys, pudval); ++ pud = READ_ONCE(*pudp); ++ } ++ BUG_ON(pud_bad(pud)); ++ ++ do { ++ pgprot_t __prot = prot; ++ ++ next = pmd_cont_addr_end(addr, end); ++ ++ /* use a contiguous mapping if the range is suitably aligned */ ++ if ((((addr | next | phys) & ~CONT_PMD_MASK) == 0) && ++ (flags & NO_CONT_MAPPINGS) == 0) ++ __prot = __pgprot(pgprot_val(prot) | PTE_CONT); ++ ++ iee_init_pmd_pre_init(pudp, addr, next, phys, __prot, pgtable_alloc, flags); ++ ++ phys += next - addr; ++ } while (addr = next, addr != end); ++} ++ ++static __init void iee_alloc_init_pud_pre_init(pgd_t *pgdp, unsigned long addr, unsigned long end, ++ phys_addr_t phys, pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(int), ++ int flags) ++{ ++ unsigned long next; ++ pud_t *pudp; ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ p4d_t p4d = READ_ONCE(*p4dp); ++ ++ if (p4d_none(p4d)) { ++ p4dval_t p4dval = P4D_TYPE_TABLE | P4D_TABLE_UXN; ++ phys_addr_t pud_phys; ++ ++ if (flags & NO_EXEC_MAPPINGS) ++ p4dval |= P4D_TABLE_PXN; ++ BUG_ON(!pgtable_alloc); ++ pud_phys = pgtable_alloc(PUD_SHIFT); ++ __iee_p4d_populate_pre_init(p4dp, pud_phys, p4dval); ++ p4d = READ_ONCE(*p4dp); ++ } ++ BUG_ON(p4d_bad(p4d)); ++ ++ pudp = pud_set_fixmap_offset_init(p4dp, addr); ++ do { ++ pud_t old_pud = READ_ONCE(*pudp); ++ ++ next = pud_addr_end(addr, end); ++ ++ /* ++ * For 4K granule only, attempt to put down a 1GB block ++ */ ++ iee_alloc_init_cont_pmd_pre_init(pudp, addr, next, phys, prot, ++ pgtable_alloc, flags); ++ ++ BUG_ON(pud_val(old_pud) != 0 && ++ pud_val(old_pud) != READ_ONCE(pud_val(*pudp))); ++ phys += next - addr; ++ } while (pudp++, addr = next, addr != end); ++ ++ pud_clear_fixmap_init(); ++} ++ ++static __init void __iee_create_pgd_mapping_locked_pre_init(pgd_t *pgdir, phys_addr_t phys, ++ unsigned long virt, phys_addr_t size, ++ pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(int), ++ int flags) ++{ ++ unsigned long addr, end, next; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, virt); ++ p4d_t *p4dp; ++ p4d_t p4d; ++ ++ /* ++ * If the virtual and physical address don't have the same offset ++ * within a page, we cannot map the region as the caller expects. ++ */ ++ if (WARN_ON((phys ^ virt) & ~PAGE_MASK)) ++ return; ++ ++ phys &= PAGE_MASK; ++ addr = virt & PAGE_MASK; ++ end = PAGE_ALIGN(virt + size); ++ ++ do { ++ next = pgd_addr_end(addr, end); ++ iee_alloc_init_pud_pre_init(pgdp, addr, next, phys, prot, pgtable_alloc, ++ flags); ++ p4dp = p4d_offset(pgdp, addr); ++ p4d = READ_ONCE(*p4dp); ++ __iee_p4d_populate_pre_init(p4dp, __p4d_to_phys(p4d), (PGD_APT | PUD_TYPE_TABLE)); ++ phys += next - addr; ++ } while (pgdp++, addr = next, addr != end); ++} ++ ++static __init void __iee_create_pgd_mapping_pre_init(pgd_t *pgdir, phys_addr_t phys, ++ unsigned long virt, phys_addr_t size, ++ pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(int), ++ int flags) ++{ ++ mutex_lock(&fixmap_lock); ++ __iee_create_pgd_mapping_locked_pre_init(pgdir, phys, virt, size, prot, ++ pgtable_alloc, flags); ++ mutex_unlock(&fixmap_lock); ++} ++#endif ++ ++static phys_addr_t __pgd_pgtable_alloc(int shift) ++{ ++ #ifdef CONFIG_PTP ++ void *ptr = get_iee_pgtable_page(GFP_PGTABLE_KERNEL); ++ #else ++ void *ptr = (void *)__get_free_page(GFP_PGTABLE_KERNEL); ++ #endif ++ BUG_ON(!ptr); ++ ++ /* Ensure the zeroed page is visible to the page table walker */ ++ dsb(ishst); ++ return __pa(ptr); ++} ++ ++static phys_addr_t pgd_pgtable_alloc(int shift) ++{ ++ phys_addr_t pa = __pgd_pgtable_alloc(shift); ++ struct ptdesc *ptdesc = page_ptdesc(phys_to_page(pa)); ++ ++ /* ++ * Call proper page table ctor in case later we need to ++ * call core mm functions like apply_to_page_range() on ++ * this pre-allocated page table. ++ * ++ * We don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK if pmd is ++ * folded, and if so pagetable_pte_ctor() becomes nop. ++ */ ++ if (shift == PAGE_SHIFT) ++ BUG_ON(!pagetable_pte_ctor(ptdesc)); ++ else if (shift == PMD_SHIFT) ++ BUG_ON(!pagetable_pmd_ctor(ptdesc)); ++ ++ return pa; ++} ++ ++/* ++ * This function can only be used to modify existing table entries, ++ * without allocating new levels of table. Note that this permits the ++ * creation of new section or page entries. ++ */ ++void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt, ++ phys_addr_t size, pgprot_t prot) ++{ ++ if (virt < PAGE_OFFSET) { ++ pr_warn("BUG: not creating mapping for %pa at 0x%016lx - outside kernel range\n", ++ &phys, virt); ++ return; ++ } ++ ++ #ifdef CONFIG_PTP ++ __iee_create_pgd_mapping_pre_init(init_mm.pgd, phys, virt, size, prot, NULL, ++ NO_CONT_MAPPINGS); ++ #else ++ __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, ++ NO_CONT_MAPPINGS); ++ #endif ++} ++ ++void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, ++ unsigned long virt, phys_addr_t size, ++ pgprot_t prot, bool page_mappings_only) ++{ ++ int flags = 0; ++ ++ BUG_ON(mm == &init_mm); ++ ++ if (page_mappings_only) ++ flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; ++ ++ __create_pgd_mapping(mm->pgd, phys, virt, size, prot, ++ pgd_pgtable_alloc, flags); ++} ++ ++static void update_mapping_prot(phys_addr_t phys, unsigned long virt, ++ phys_addr_t size, pgprot_t prot) ++{ ++ if (virt < PAGE_OFFSET) { ++ pr_warn("BUG: not updating mapping for %pa at 0x%016lx - outside kernel range\n", ++ &phys, virt); ++ return; ++ } ++ ++ __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, ++ NO_CONT_MAPPINGS); ++ ++ /* flush the TLBs after updating live kernel mappings */ ++ flush_tlb_kernel_range(virt, virt + size); + } + + static void __init __map_memblock(pgd_t *pgdp, phys_addr_t start, + phys_addr_t end, pgprot_t prot, int flags) + { ++ #ifdef CONFIG_PTP ++ __iee_create_pgd_mapping_pre_init(pgdp, start, __phys_to_virt(start), end - start, ++ prot, early_pgtable_alloc, flags); ++ #else + __create_pgd_mapping(pgdp, start, __phys_to_virt(start), end - start, + prot, early_pgtable_alloc, flags); ++ #endif + } + + void __init mark_linear_text_alias_ro(void) +@@ -645,157 +1247,815 @@ void mark_rodata_ro(void) + debug_checkwx(); + } + +-static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end, +- pgprot_t prot, struct vm_struct *vma, +- int flags, unsigned long vm_flags) ++static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end, ++ pgprot_t prot, struct vm_struct *vma, ++ int flags, unsigned long vm_flags) ++{ ++ phys_addr_t pa_start = __pa_symbol(va_start); ++ unsigned long size = va_end - va_start; ++ ++ BUG_ON(!PAGE_ALIGNED(pa_start)); ++ BUG_ON(!PAGE_ALIGNED(size)); ++ ++ #ifdef CONFIG_PTP ++ __iee_create_pgd_mapping_pre_init(pgdp, pa_start, (unsigned long)va_start, size, prot, ++ early_pgtable_alloc, flags); ++ #else ++ __create_pgd_mapping(pgdp, pa_start, (unsigned long)va_start, size, prot, ++ early_pgtable_alloc, flags); ++ #endif ++ ++ if (!(vm_flags & VM_NO_GUARD)) ++ size += PAGE_SIZE; ++ ++ vma->addr = va_start; ++ vma->phys_addr = pa_start; ++ vma->size = size; ++ vma->flags = VM_MAP | vm_flags; ++ vma->caller = __builtin_return_address(0); ++ ++ vm_area_add_early(vma); ++} ++ ++static pgprot_t kernel_exec_prot(void) ++{ ++ return rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC; ++} ++ ++#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 ++static int __init map_entry_trampoline(void) ++{ ++ int i; ++ ++ pgprot_t prot = kernel_exec_prot(); ++ phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start); ++ ++ /* The trampoline is always mapped and can therefore be global */ ++ pgprot_val(prot) &= ~PTE_NG; ++ ++ /* Map only the text into the trampoline page table */ ++ memset(tramp_pg_dir, 0, PGD_SIZE); ++ #ifdef CONFIG_PTP ++ iee_set_logical_mem_ro((unsigned long)tramp_pg_dir); ++ #endif ++ __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, ++ entry_tramp_text_size(), prot, ++ __pgd_pgtable_alloc, NO_BLOCK_MAPPINGS); ++ ++ /* Map both the text and data into the kernel page table */ ++ for (i = 0; i < DIV_ROUND_UP(entry_tramp_text_size(), PAGE_SIZE); i++) ++ __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i, ++ pa_start + i * PAGE_SIZE, prot); ++ ++ if (IS_ENABLED(CONFIG_RELOCATABLE)) ++ __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i, ++ pa_start + i * PAGE_SIZE, PAGE_KERNEL_RO); ++ ++ return 0; ++} ++core_initcall(map_entry_trampoline); ++#endif ++ ++/* ++ * Open coded check for BTI, only for use to determine configuration ++ * for early mappings for before the cpufeature code has run. ++ */ ++static bool arm64_early_this_cpu_has_bti(void) ++{ ++ u64 pfr1; ++ ++ if (!IS_ENABLED(CONFIG_ARM64_BTI_KERNEL)) ++ return false; ++ ++ pfr1 = __read_sysreg_by_encoding(SYS_ID_AA64PFR1_EL1); ++ return cpuid_feature_extract_unsigned_field(pfr1, ++ ID_AA64PFR1_EL1_BT_SHIFT); ++} ++ ++#ifdef CONFIG_IEE ++/* Set PMD APTable of iee si codes as (1,1) to revert it to ROX P pages when HPD1=0. */ ++static void __init iee_si_set_pmd_APtable(unsigned long addr, pgd_t *pgdir) ++{ ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ ++ #ifdef CONFIG_PTP ++ pud_t *pudp = pud_set_fixmap_offset_init(p4dp, addr); ++ ++ pmd_t *pmdp = pmd_set_fixmap_offset_init(pudp, addr); ++ ++ pmd_t pmd = READ_ONCE(*pmdp); ++ ++ __iee_pmd_populate_pre_init(pmdp, __pmd_to_phys(pmd), PGD_APT_RO | PGD_APT | PMD_TYPE_TABLE); ++ ++ pud_clear_fixmap_init(); ++ pmd_clear_fixmap_init(); ++ #else ++ pud_t *pudp = pud_set_fixmap_offset(p4dp, addr); ++ ++ pmd_t *pmdp = pmd_set_fixmap_offset(pudp, addr); ++ ++ pmd_t pmd = READ_ONCE(*pmdp); ++ ++ __pmd_populate(pmdp, __pmd_to_phys(pmd), PGD_APT_RO | PGD_APT | PMD_TYPE_TABLE); ++ ++ pud_clear_fixmap(); ++ pmd_clear_fixmap(); ++ #endif ++} ++/* Set PMD APTable of iee si codes as (1,1) to revert it to ROX P pages when HPD1=0. */ ++static void __init mark_iee_si_pmd_APtable(pgd_t *pgdir) ++{ ++ unsigned long addr = (unsigned long)__iee_si_text_start; ++ iee_si_set_pmd_APtable(addr, pgdir); ++ // iee rwx gate exit may be mapped by another pmd. ++ iee_si_set_pmd_APtable(addr + PAGE_SIZE, pgdir); ++} ++#endif ++ ++/* ++ * Create fine-grained mappings for the kernel. ++ */ ++static void __init map_kernel(pgd_t *pgdp) ++{ ++ static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_inittext, ++ vmlinux_initdata, vmlinux_data; ++ ++ #ifdef CONFIG_IEE ++ static struct vm_struct vmlinux_iee_code, vmlinux_iee_data, vmlinux_iee_gate, vmlinux_text_end; ++ #endif ++ ++ /* ++ * External debuggers may need to write directly to the text ++ * mapping to install SW breakpoints. Allow this (only) when ++ * explicitly requested with rodata=off. ++ */ ++ pgprot_t text_prot = kernel_exec_prot(); ++ ++ /* ++ * If we have a CPU that supports BTI and a kernel built for ++ * BTI then mark the kernel executable text as guarded pages ++ * now so we don't have to rewrite the page tables later. ++ */ ++ if (arm64_early_this_cpu_has_bti()) ++ text_prot = __pgprot_modify(text_prot, PTE_GP, PTE_GP); ++ ++ /* ++ * Only rodata will be remapped with different permissions later on, ++ * all other segments are allowed to use contiguous mappings. ++ */ ++ #ifdef CONFIG_IEE ++ map_kernel_segment(pgdp, _stext, __iee_si_data_start, text_prot, &vmlinux_text, ++ 0, VM_NO_GUARD); ++ /* Set iee si data RW. */ ++ map_kernel_segment(pgdp, __iee_si_data_start, __iee_exec_entry_start, SET_NG(PAGE_KERNEL), ++ &vmlinux_iee_data, NO_CONT_MAPPINGS | NO_BLOCK_MAPPINGS, VM_NO_GUARD); ++ /* Set iee entry codes NG. */ ++ map_kernel_segment(pgdp, __iee_exec_entry_start, __iee_si_text_start, SET_NG(text_prot), &vmlinux_iee_gate, ++ NO_CONT_MAPPINGS | NO_BLOCK_MAPPINGS, VM_NO_GUARD); ++ /* Map __iee_si_text_start - __iee_si_text_end as U RWX pages and set PMD APTABLE = (1,1). */ ++ map_kernel_segment(pgdp, __iee_si_text_start, __iee_si_text_end, SET_NG((PAGE_KERNEL_EXEC)), ++ &vmlinux_iee_code, NO_CONT_MAPPINGS | NO_BLOCK_MAPPINGS, VM_NO_GUARD); ++ mark_iee_si_pmd_APtable(pgdp); ++ ++ map_kernel_segment(pgdp, __iee_si_text_end, _etext, text_prot, &vmlinux_text_end, 0, ++ VM_NO_GUARD); ++ ++ map_kernel_segment(pgdp, __start_rodata, __inittext_begin, PAGE_KERNEL, ++ &vmlinux_rodata, NO_CONT_MAPPINGS | NO_BLOCK_MAPPINGS, VM_NO_GUARD); ++ map_kernel_segment(pgdp, __inittext_begin, __inittext_end, text_prot, ++ &vmlinux_inittext, 0, VM_NO_GUARD); ++ map_kernel_segment(pgdp, __initdata_begin, __initdata_end, PAGE_KERNEL, ++ &vmlinux_initdata, 0, VM_NO_GUARD); ++ map_kernel_segment(pgdp, _data, _end, PAGE_KERNEL, &vmlinux_data, NO_CONT_MAPPINGS | NO_BLOCK_MAPPINGS, 0); ++ #else ++ map_kernel_segment(pgdp, _stext, _etext, text_prot, &vmlinux_text, 0, ++ VM_NO_GUARD); ++ map_kernel_segment(pgdp, __start_rodata, __inittext_begin, PAGE_KERNEL, ++ &vmlinux_rodata, NO_CONT_MAPPINGS, VM_NO_GUARD); ++ map_kernel_segment(pgdp, __inittext_begin, __inittext_end, text_prot, ++ &vmlinux_inittext, 0, VM_NO_GUARD); ++ map_kernel_segment(pgdp, __initdata_begin, __initdata_end, PAGE_KERNEL, ++ &vmlinux_initdata, 0, VM_NO_GUARD); ++ map_kernel_segment(pgdp, _data, _end, PAGE_KERNEL, &vmlinux_data, 0, 0); ++ #endif ++ ++ ++ fixmap_copy(pgdp); ++ kasan_copy_shadow(pgdp); ++} ++ ++static void __init create_idmap(void) ++{ ++ u64 start = __pa_symbol(__idmap_text_start); ++ u64 size = __pa_symbol(__idmap_text_end) - start; ++ pgd_t *pgd = idmap_pg_dir; ++ u64 pgd_phys; ++ ++ /* check if we need an additional level of translation */ ++ if (VA_BITS < 48 && idmap_t0sz < (64 - VA_BITS_MIN)) { ++ pgd_phys = early_pgtable_alloc(PAGE_SHIFT); ++ set_pgd(&idmap_pg_dir[start >> VA_BITS], ++ __pgd(pgd_phys | P4D_TYPE_TABLE)); ++ pgd = __va(pgd_phys); ++ } ++ #ifdef CONFIG_PTP ++ __iee_create_pgd_mapping_pre_init(pgd, start, start, size, PAGE_KERNEL_ROX, ++ early_pgtable_alloc, 0); ++ #else ++ __create_pgd_mapping(pgd, start, start, size, PAGE_KERNEL_ROX, ++ early_pgtable_alloc, 0); ++ #endif ++ ++ if (IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0)) { ++ extern u32 __idmap_kpti_flag; ++ u64 pa = __pa_symbol(&__idmap_kpti_flag); ++ ++ /* ++ * The KPTI G-to-nG conversion code needs a read-write mapping ++ * of its synchronization flag in the ID map. ++ */ ++ #ifdef CONFIG_PTP ++ __iee_create_pgd_mapping_pre_init(pgd, pa, pa, sizeof(u32), PAGE_KERNEL, ++ early_pgtable_alloc, 0); ++ #else ++ __create_pgd_mapping(pgd, pa, pa, sizeof(u32), PAGE_KERNEL, ++ early_pgtable_alloc, 0); ++ #endif ++ } ++} ++ ++#ifdef CONFIG_IEE ++static void set_init_iee_stack_page(unsigned long addr) ++{ ++ unsigned long iee_addr = __phys_to_iee(__pa_symbol(addr)); ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ p4d_t p4d = READ_ONCE(*p4dp); ++ ++ pud_t *pudp = pud_offset(p4dp, addr); ++ ++ pmd_t *pmdp = pmd_offset(pudp, addr); ++ ++ pte_t *ptep = pte_offset_kernel(pmdp, addr); ++ ++ int i; ++ for(i = 0; i < 4; i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(pte_val(pte) & ~PTE_VALID); ++ set_pte(ptep, pte); ++ ptep++; ++ } ++ ++ pgdp = pgd_offset_pgd(pgdir, iee_addr); ++ ++ p4dp = p4d_offset(pgdp, iee_addr); ++ p4d = READ_ONCE(*p4dp); ++ ++ pudp = pud_offset(p4dp, iee_addr); ++ ++ pmdp = pmd_offset(pudp, iee_addr); ++ ++ ptep = pte_offset_kernel(pmdp, iee_addr); ++ ++ for(i = 0; i < 4; i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(pte_val(pte) | PTE_VALID); ++ set_pte(ptep, pte); ++ ptep++; ++ } ++ flush_tlb_kernel_range(addr, addr+4*PAGE_SIZE); ++ isb(); ++} ++ ++static void __create_pgd_mapping_for_iee_locked(pgd_t *pgdir, phys_addr_t phys, ++ unsigned long virt, phys_addr_t size, ++ pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(int), ++ int flags) ++{ ++ unsigned long addr, end, next; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, virt); ++ p4d_t *p4dp; ++ p4d_t p4d; ++ ++ /* ++ * If the virtual and physical address don't have the same offset ++ * within a page, we cannot map the region as the caller expects. ++ */ ++ if (WARN_ON((phys ^ virt) & ~PAGE_MASK)) ++ return; ++ ++ phys &= PAGE_MASK; ++ addr = virt & PAGE_MASK; ++ end = PAGE_ALIGN(virt + size); ++ ++ do { ++ next = pgd_addr_end(addr, end); ++ #ifdef CONFIG_PTP ++ iee_alloc_init_pud_pre_init(pgdp, addr, next, phys, prot, pgtable_alloc, ++ flags); ++ #else ++ alloc_init_pud(pgdp, addr, next, phys, prot, pgtable_alloc, ++ flags); ++ #endif ++ p4dp = p4d_offset(pgdp, addr); ++ p4d = READ_ONCE(*p4dp); ++ #ifdef CONFIG_PTP ++ __iee_p4d_populate_pre_init(p4dp, __p4d_to_phys(p4d), (PGD_APT | PGD_PXN | PGD_UXN | PUD_TYPE_TABLE)); ++ #else ++ __p4d_populate(p4dp, __p4d_to_phys(p4d), (PGD_APT | PGD_PXN | PGD_UXN | PUD_TYPE_TABLE)); ++ #endif ++ phys += next - addr; ++ } while (pgdp++, addr = next, addr != end); ++} ++ ++static void __create_pgd_mapping_for_iee(pgd_t *pgdir, phys_addr_t phys, ++ unsigned long virt, phys_addr_t size, ++ pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(int), ++ int flags) ++{ ++ mutex_lock(&fixmap_lock); ++ __create_pgd_mapping_for_iee_locked(pgdir, phys, virt, size, prot, ++ pgtable_alloc, flags); ++ mutex_unlock(&fixmap_lock); ++} ++ ++static void __init __map_memblock_for_iee(pgd_t *pgdp, phys_addr_t start, ++ phys_addr_t end, pgprot_t prot, int flags) ++{ ++ #ifdef CONFIG_PTP ++ __create_pgd_mapping_for_iee(pgdp, start, __phys_to_iee(start), end - start, ++ prot, early_pgtable_alloc, flags); ++ #else ++ __create_pgd_mapping_for_iee(pgdp, start, __phys_to_iee(start), end - start, ++ prot, early_pgtable_alloc, flags); ++ #endif ++} ++ ++static void __init map_iee(pgd_t *pgdp) ++{ ++ static const u64 direct_map_end = _PAGE_END(VA_BITS_MIN); ++ phys_addr_t kernel_start = __pa_symbol(_stext); ++ phys_addr_t kernel_end = __pa_symbol(__init_begin); ++ phys_addr_t start, end; ++ phys_addr_t early_kfence_pool; ++ int flags = NO_EXEC_MAPPINGS; ++ u64 i; ++ ++ flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; ++ ++ /* ++ * Setting hierarchical PXNTable attributes on table entries covering ++ * the linear region is only possible if it is guaranteed that no table ++ * entries at any level are being shared between the linear region and ++ * the vmalloc region. Check whether this is true for the PGD level, in ++ * which case it is guaranteed to be true for all other levels as well. ++ */ ++ BUILD_BUG_ON(pgd_index(direct_map_end - 1) == pgd_index(direct_map_end)); ++ ++ early_kfence_pool = arm64_kfence_alloc_pool(); ++ ++ /* ++ * Take care not to create a writable alias for the ++ * read-only text and rodata sections of the kernel image. ++ * So temporarily mark them as NOMAP to skip mappings in ++ * the following for-loop ++ */ ++ memblock_mark_nomap(kernel_start, kernel_end - kernel_start); ++ ++ /* map all the memory banks */ ++ for_each_mem_range(i, &start, &end) { ++ if (start >= end) ++ break; ++ /* ++ * The linear map must allow allocation tags reading/writing ++ * if MTE is present. Otherwise, it has the same attributes as ++ * PAGE_KERNEL. ++ */ ++ __map_memblock_for_iee(pgdp, start, end, SET_NG(SET_INVALID(SET_UPAGE(PAGE_KERNEL))), flags); ++ } ++ ++ /* ++ * Map the linear alias of the [_text, __init_begin) interval ++ * as non-executable now, and remove the write permission in ++ * mark_linear_text_alias_ro() below (which will be called after ++ * alternative patching has completed). This makes the contents ++ * of the region accessible to subsystems such as hibernate, ++ * but protects it from inadvertent modification or execution. ++ * Note that contiguous mappings cannot be remapped in this way, ++ * so we should avoid them here. ++ */ ++ __map_memblock_for_iee(pgdp, kernel_start, kernel_end, ++ SET_NG(SET_INVALID(SET_UPAGE(PAGE_KERNEL))), flags); ++ memblock_clear_nomap(kernel_start, kernel_end - kernel_start); ++ arm64_kfence_map_pool(early_kfence_pool, pgdp); ++} ++ ++/* ++ * Change page access permission, whereas not handling huge pages. ++ * Only used on IEE init functions. ++ */ ++static void __init iee_si_set_page_attr(unsigned long addr, pteval_t attr) ++{ ++ unsigned long flag; ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ ++ pud_t *pudp = pud_offset(p4dp, addr); ++ ++ pmd_t *pmdp = pmd_offset(pudp, addr); ++ ++ pte_t *ptep = pte_offset_kernel(pmdp, addr); ++ pte_t pte = READ_ONCE(*ptep); ++ ++ if(attr & PTE_RDONLY) ++ pte = __pte((pte_val(pte) | PTE_RDONLY) & ~PTE_DBM); ++ pte = __pte(pte_val(pte) | attr); ++ #ifdef CONFIG_PTP ++ // Write pgtable in IEE directly. ++ flag = local_daif_save(); ++ asm volatile ("msr pan, #0"); ++ WRITE_ONCE(*((pte_t *)(__phys_to_iee(__pa(ptep)))), pte); ++ asm volatile ("msr pan, #1"); ++ local_daif_restore(flag); ++ #else ++ WRITE_ONCE(*ptep, pte); ++ #endif ++} ++ ++/* Prepare data used for iee rwx gates. These data are setted only once. */ ++void __init iee_si_prepare_data(void) ++{ ++ unsigned long va; ++ // Record current TCR val after system init. ++ iee_si_tcr = read_sysreg(tcr_el1) & ~(SYS_TCR_IEE_SI); ++ // CNP maybe enable. ++ if (system_supports_cnp()) { ++ iee_base_swapper_pg_dir |= TTBR_CNP_BIT; ++ } ++ // Mark iee data as RO and move it to iee after setting up. ++ va = (unsigned long)__iee_si_data_start; ++ iee_si_set_page_attr(va, PTE_RDONLY); ++ // iee_si_set_page_attr(lm_alias(va)+iee_offset, 0x1 | PTE_RDONLY); ++ // Set iee sensitive inst code page U RWX here to hide it from kernel. ++ va = (unsigned long)__iee_si_text_start; ++ iee_si_set_page_attr(va, PTE_USER); ++ va = (unsigned long)__iee_si_text_start + PAGE_SIZE; ++ iee_si_set_page_attr(va, PTE_USER); ++ flush_tlb_all(); ++} ++ ++#endif ++ ++#ifdef CONFIG_PTP ++// Attention : Using set_xxx without adding offset. ++static void __init set_iee_valid_pre_init(unsigned long addr) ++{ ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ ++ pud_t *pudp = pud_offset(p4dp, addr); ++ ++ pmd_t *pmdp = pmd_offset(pudp, addr); ++ ++ pte_t *ptep = pte_offset_kernel(pmdp, addr); ++ pte_t pte = READ_ONCE(*ptep); ++ ++ if((addr < (PAGE_OFFSET + IEE_OFFSET)) | (addr > (PAGE_OFFSET + BIT(vabits_actual - 1)))) ++ return; ++ ++ pte = __pte(pte_val(pte) | 0x1); ++ iee_set_pte_pre_init(ptep, pte); ++ flush_tlb_kernel_range(addr, addr+PAGE_SIZE); ++ isb(); ++} ++ ++static void __init move_pte_table_into_iee(pmd_t *pmdp, unsigned long addr, unsigned long end) ++{ ++ pmd_t pmd = READ_ONCE(*pmdp); ++ unsigned long iee_addr = __phys_to_iee(__pmd_to_phys(pmd)); ++ set_iee_valid_pre_init(iee_addr); ++} ++ ++static void __init move_pmd_table_into_iee(pud_t *pudp, unsigned long addr, unsigned long end) ++{ ++ unsigned long next; ++ pud_t pud = READ_ONCE(*pudp); ++ pmd_t *pmdp; ++ pmd_t pmd; ++ unsigned long iee_addr = __phys_to_iee(__pud_to_phys(pud)); ++ set_iee_valid_pre_init(iee_addr); ++ ++ pmdp = pmd_offset(pudp, addr); ++ do { ++ next = pmd_addr_end(addr, end); ++ pmd = READ_ONCE(*pmdp); ++ if((pmd_val(pmd) & PMD_TABLE_BIT) == 0) ++ { ++ continue; ++ } ++ else ++ { ++ move_pte_table_into_iee(pmdp, addr, next); ++ } ++ } while (pmdp++, addr = next, addr != end); ++} ++ ++static void __init move_pud_table_into_iee(pgd_t *pgdp, unsigned long addr, unsigned long end) ++{ ++ unsigned long next; ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ p4d_t p4d = READ_ONCE(*p4dp); ++ pud_t *pudp; ++ pud_t pud; ++ unsigned long iee_addr = __phys_to_iee(__p4d_to_phys(p4d)); ++ set_iee_valid_pre_init(iee_addr); ++ ++ pudp = pud_offset(p4dp, addr); ++ do { ++ next = pud_addr_end(addr, end); ++ pud = READ_ONCE(*pudp); ++ if ((pud_val(pud) & PUD_TABLE_BIT) == 0) ++ { ++ continue; ++ } ++ else ++ { ++ move_pmd_table_into_iee(pudp, addr, next); ++ } ++ } while (pudp++, addr = next, addr != end); ++} ++ ++static void __init init_iee_for_one_region(pgd_t *pgdir, unsigned long va_start, unsigned long va_end) + { +- phys_addr_t pa_start = __pa_symbol(va_start); +- unsigned long size = va_end - va_start; +- +- BUG_ON(!PAGE_ALIGNED(pa_start)); +- BUG_ON(!PAGE_ALIGNED(size)); +- +- __create_pgd_mapping(pgdp, pa_start, (unsigned long)va_start, size, prot, +- early_pgtable_alloc, flags); +- +- if (!(vm_flags & VM_NO_GUARD)) +- size += PAGE_SIZE; ++ unsigned long addr, end, next; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, va_start); + +- vma->addr = va_start; +- vma->phys_addr = pa_start; +- vma->size = size; +- vma->flags = VM_MAP | vm_flags; +- vma->caller = __builtin_return_address(0); ++ addr = va_start & PAGE_MASK; ++ end = PAGE_ALIGN(va_end); + +- vm_area_add_early(vma); ++ do { ++ next = pgd_addr_end(addr, end); ++ move_pud_table_into_iee(pgdp, addr, next); ++ } while (pgdp++, addr = next, addr != end); + } + +-static pgprot_t kernel_exec_prot(void) ++static void __init init_iee(void) + { +- return rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC; ++ unsigned long iee_addr; ++ phys_addr_t start, end; ++ u64 i; ++ pgd_t *pgdp; ++ ++ #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 ++ // handling 1-level tramp page table tramp_pg_dir ++ iee_addr = (unsigned long)__phys_to_iee(__pa_symbol(tramp_pg_dir)); ++ set_iee_valid_pre_init(iee_addr); ++ #endif ++ // handling 1-level page table swapper_pg_dir ++ pgdp = swapper_pg_dir; ++ iee_addr = (unsigned long)__phys_to_iee(__pa_symbol(swapper_pg_dir)); ++ set_iee_valid_pre_init(iee_addr); ++ // handling 2/3/4-level page table for kernel ++ init_iee_for_one_region(pgdp, (unsigned long)_text, (unsigned long)_etext); ++ init_iee_for_one_region(pgdp, (unsigned long)__start_rodata, (unsigned long)__inittext_begin); ++ init_iee_for_one_region(pgdp, (unsigned long)__inittext_begin, (unsigned long)__inittext_end); ++ init_iee_for_one_region(pgdp, (unsigned long)__initdata_begin, (unsigned long)__initdata_end); ++ init_iee_for_one_region(pgdp, (unsigned long)_data, (unsigned long)_end); ++ // handling 2/3/4-level page table for fixmap i.e. remap bm_xxx ++ iee_addr = (unsigned long)__phys_to_iee(__pa_symbol(bm_pte_addr)); ++ set_iee_valid_pre_init(iee_addr); ++ iee_addr = (unsigned long)__phys_to_iee(__pa_symbol(bm_pmd_addr)); ++ set_iee_valid_pre_init(iee_addr); ++ iee_addr = (unsigned long)__phys_to_iee(__pa_symbol(bm_pud_addr)); ++ set_iee_valid_pre_init(iee_addr); ++ // handling 2/3/4-level page table for logical mem and iee ++ for_each_mem_range(i, &start, &end) { ++ if (start >= end) ++ break; ++ /* ++ * The linear map must allow allocation tags reading/writing ++ * if MTE is present. Otherwise, it has the same attributes as ++ * PAGE_KERNEL. ++ */ ++ init_iee_for_one_region(pgdp, (unsigned long)__va(start), (unsigned long)__va(end)); ++ init_iee_for_one_region(pgdp, (unsigned long)__phys_to_iee(start), (unsigned long)__phys_to_iee(end)); ++ } + } + +-#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 +-static int __init map_entry_trampoline(void) ++static void set_init_iee_stack_page_pre_init(unsigned long addr) + { +- int i; ++ unsigned long iee_addr = __phys_to_iee(__pa_symbol(addr)); ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); + +- pgprot_t prot = kernel_exec_prot(); +- phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start); ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ p4d_t p4d = READ_ONCE(*p4dp); + +- /* The trampoline is always mapped and can therefore be global */ +- pgprot_val(prot) &= ~PTE_NG; ++ pud_t *pudp = pud_offset(p4dp, addr); + +- /* Map only the text into the trampoline page table */ +- memset(tramp_pg_dir, 0, PGD_SIZE); +- __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, +- entry_tramp_text_size(), prot, +- __pgd_pgtable_alloc, NO_BLOCK_MAPPINGS); ++ pmd_t *pmdp = pmd_offset(pudp, addr); + +- /* Map both the text and data into the kernel page table */ +- for (i = 0; i < DIV_ROUND_UP(entry_tramp_text_size(), PAGE_SIZE); i++) +- __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i, +- pa_start + i * PAGE_SIZE, prot); ++ pte_t *ptep = pte_offset_kernel(pmdp, addr); + +- if (IS_ENABLED(CONFIG_RELOCATABLE)) +- __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i, +- pa_start + i * PAGE_SIZE, PAGE_KERNEL_RO); ++ int i; ++ for(i = 0; i < 4; i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(pte_val(pte) & ~PTE_VALID); ++ iee_set_pte_pre_init(ptep, pte); ++ ptep++; ++ } + +- return 0; +-} +-core_initcall(map_entry_trampoline); +-#endif ++ pgdp = pgd_offset_pgd(pgdir, iee_addr); + +-/* +- * Open coded check for BTI, only for use to determine configuration +- * for early mappings for before the cpufeature code has run. +- */ +-static bool arm64_early_this_cpu_has_bti(void) +-{ +- u64 pfr1; ++ p4dp = p4d_offset(pgdp, iee_addr); ++ p4d = READ_ONCE(*p4dp); + +- if (!IS_ENABLED(CONFIG_ARM64_BTI_KERNEL)) +- return false; ++ pudp = pud_offset(p4dp, iee_addr); + +- pfr1 = __read_sysreg_by_encoding(SYS_ID_AA64PFR1_EL1); +- return cpuid_feature_extract_unsigned_field(pfr1, +- ID_AA64PFR1_EL1_BT_SHIFT); ++ pmdp = pmd_offset(pudp, iee_addr); ++ ++ ptep = pte_offset_kernel(pmdp, iee_addr); ++ ++ for(i = 0; i < 4; i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(pte_val(pte) | PTE_VALID); ++ iee_set_pte_pre_init(ptep, pte); ++ ptep++; ++ } ++ flush_tlb_kernel_range(addr, addr+4*PAGE_SIZE); ++ isb(); + } + +-/* +- * Create fine-grained mappings for the kernel. +- */ +-static void __init map_kernel(pgd_t *pgdp) ++static void __init iee_set_pte_table_ro(pmd_t *pmdp, unsigned long addr, unsigned long end) + { +- static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_inittext, +- vmlinux_initdata, vmlinux_data; ++ pmd_t pmd = READ_ONCE(*pmdp); ++ unsigned long logical_addr = (unsigned long)__va(__pmd_to_phys(pmd)); ++ iee_set_logical_mem_ro(logical_addr); ++} + +- /* +- * External debuggers may need to write directly to the text +- * mapping to install SW breakpoints. Allow this (only) when +- * explicitly requested with rodata=off. +- */ +- pgprot_t text_prot = kernel_exec_prot(); ++static void __init iee_set_pmd_table_ro(pud_t *pudp, unsigned long addr, unsigned long end) ++{ ++ unsigned long next; ++ pud_t pud = READ_ONCE(*pudp); ++ pmd_t *pmdp; ++ pmd_t pmd; ++ unsigned long logical_addr = (unsigned long)__va(__pud_to_phys(pud)); ++ iee_set_logical_mem_ro(logical_addr); + +- /* +- * If we have a CPU that supports BTI and a kernel built for +- * BTI then mark the kernel executable text as guarded pages +- * now so we don't have to rewrite the page tables later. +- */ +- if (arm64_early_this_cpu_has_bti()) +- text_prot = __pgprot_modify(text_prot, PTE_GP, PTE_GP); ++ pmdp = pmd_offset(pudp, addr); ++ do { ++ next = pmd_addr_end(addr, end); ++ pmd = READ_ONCE(*pmdp); ++ if((pmd_val(pmd) & PMD_TABLE_BIT) == 0) ++ { ++ continue; ++ } ++ else ++ { ++ iee_set_pte_table_ro(pmdp, addr, next); ++ } ++ } while (pmdp++, addr = next, addr != end); ++} + +- /* +- * Only rodata will be remapped with different permissions later on, +- * all other segments are allowed to use contiguous mappings. +- */ +- map_kernel_segment(pgdp, _stext, _etext, text_prot, &vmlinux_text, 0, +- VM_NO_GUARD); +- map_kernel_segment(pgdp, __start_rodata, __inittext_begin, PAGE_KERNEL, +- &vmlinux_rodata, NO_CONT_MAPPINGS, VM_NO_GUARD); +- map_kernel_segment(pgdp, __inittext_begin, __inittext_end, text_prot, +- &vmlinux_inittext, 0, VM_NO_GUARD); +- map_kernel_segment(pgdp, __initdata_begin, __initdata_end, PAGE_KERNEL, +- &vmlinux_initdata, 0, VM_NO_GUARD); +- map_kernel_segment(pgdp, _data, _end, PAGE_KERNEL, &vmlinux_data, 0, 0); ++static void __init iee_set_pud_table_ro(pgd_t *pgdp, unsigned long addr, unsigned long end) ++{ ++ unsigned long next; ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ p4d_t p4d = READ_ONCE(*p4dp); ++ pud_t *pudp; ++ pud_t pud; ++ unsigned long logical_addr = (unsigned long)__va(__p4d_to_phys(p4d)); ++ iee_set_logical_mem_ro(logical_addr); + +- fixmap_copy(pgdp); +- kasan_copy_shadow(pgdp); ++ pudp = pud_offset(p4dp, addr); ++ do { ++ next = pud_addr_end(addr, end); ++ pud = READ_ONCE(*pudp); ++ if ((pud_val(pud) & PUD_TABLE_BIT) == 0) ++ { ++ continue; ++ } ++ else ++ { ++ iee_set_pmd_table_ro(pudp, addr, next); ++ } ++ } while (pudp++, addr = next, addr != end); + } + +-static void __init create_idmap(void) ++static void __init iee_mark_pgtable_for_one_region_ro(pgd_t *pgdir, unsigned long va_start, unsigned long va_end) + { +- u64 start = __pa_symbol(__idmap_text_start); +- u64 size = __pa_symbol(__idmap_text_end) - start; +- pgd_t *pgd = idmap_pg_dir; +- u64 pgd_phys; ++ unsigned long addr, end, next; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, va_start); + +- /* check if we need an additional level of translation */ +- if (VA_BITS < 48 && idmap_t0sz < (64 - VA_BITS_MIN)) { +- pgd_phys = early_pgtable_alloc(PAGE_SHIFT); +- set_pgd(&idmap_pg_dir[start >> VA_BITS], +- __pgd(pgd_phys | P4D_TYPE_TABLE)); +- pgd = __va(pgd_phys); +- } +- __create_pgd_mapping(pgd, start, start, size, PAGE_KERNEL_ROX, +- early_pgtable_alloc, 0); ++ addr = va_start & PAGE_MASK; ++ end = PAGE_ALIGN(va_end); + +- if (IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0)) { +- extern u32 __idmap_kpti_flag; +- u64 pa = __pa_symbol(&__idmap_kpti_flag); ++ do { ++ next = pgd_addr_end(addr, end); ++ iee_set_pud_table_ro(pgdp, addr, next); ++ } while (pgdp++, addr = next, addr != end); ++} + ++// Mark pgtable outside as RO. ++void __init iee_mark_all_lm_pgtable_ro(void) ++{ ++ unsigned long logical_addr; ++ phys_addr_t start, end; ++ u64 i; ++ pgd_t *pgdp; ++ ++ // handling static allocated page table ++ #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 ++ // handling 1-level tramp page table tramp_pg_dir ++ logical_addr = (unsigned long)__va(__pa_symbol(tramp_pg_dir)); ++ iee_set_logical_mem_ro(logical_addr); ++ #endif ++ // handling 1-level page table swapper_pg_dir ++ pgdp = swapper_pg_dir; ++ iee_set_logical_mem_ro((unsigned long)swapper_pg_dir); ++ logical_addr = (unsigned long)__va(__pa_symbol(swapper_pg_dir)); ++ iee_set_logical_mem_ro(logical_addr); ++ ++ // handling 2/3/4-level page table for kernel ++ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)_text, (unsigned long)_etext); ++ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)__start_rodata, (unsigned long)__inittext_begin); ++ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)__inittext_begin, (unsigned long)__inittext_end); ++ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)__initdata_begin, (unsigned long)__initdata_end); ++ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)_data, (unsigned long)_end); ++ ++ // handling 2/3/4-level page table for fixmap i.e. remap bm_xxx ++ logical_addr = (unsigned long)__va(__pa_symbol(bm_pte_addr)); ++ iee_set_logical_mem_ro(logical_addr); ++ ++ iee_set_logical_mem_ro((unsigned long)bm_pmd_addr); ++ logical_addr = (unsigned long)__va(__pa_symbol(bm_pmd_addr)); ++ iee_set_logical_mem_ro(logical_addr); ++ ++ iee_set_logical_mem_ro((unsigned long)bm_pud_addr); ++ logical_addr = (unsigned long)__va(__pa_symbol(bm_pud_addr)); ++ iee_set_logical_mem_ro(logical_addr); ++ ++ // handling 2/3/4-level page table for logical mem and iee ++ for_each_mem_range(i, &start, &end) { ++ if (start >= end) ++ break; + /* +- * The KPTI G-to-nG conversion code needs a read-write mapping +- * of its synchronization flag in the ID map. ++ * The linear map must allow allocation tags reading/writing ++ * if MTE is present. Otherwise, it has the same attributes as ++ * PAGE_KERNEL. + */ +- __create_pgd_mapping(pgd, pa, pa, sizeof(u32), PAGE_KERNEL, +- early_pgtable_alloc, 0); ++ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)__va(start), (unsigned long)__va(end)); ++ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)__phys_to_iee(start), (unsigned long)__phys_to_iee(end)); + } + } ++#endif ++ ++#ifdef CONFIG_KOI ++static void map_koi(pgd_t *pgdp); ++extern s64 koi_offset; ++#endif + + void __init paging_init(void) + { ++ #ifdef CONFIG_IEE ++ unsigned long SP_EL0; ++ void *new; ++ void *init_token; ++ struct task_token *token; ++ unsigned long tcr; ++ ++ // Check if cpu has PAN and HPDS. ++ if(!cpuid_feature_extract_unsigned_field(read_cpuid(ID_AA64MMFR1_EL1), ++ ID_AA64MMFR1_EL1_PAN_SHIFT)) ++ panic("Architecture doesn't support PAN, please disable CONFIG_IEE.\n"); ++ ++ if(!cpuid_feature_extract_unsigned_field(read_cpuid(ID_AA64MMFR1_EL1), ++ ID_AA64MMFR1_EL1_HPDS_SHIFT)) ++ panic("Architecture doesn't support HPDS, please disable CONFIG_IEE.\n"); ++ #endif ++ ++ // Avoid using iee code to modify pgtable before iee initialized. ++ #ifdef CONFIG_PTP ++ pgd_t *pgdp = pgd_set_fixmap_init(__pa_symbol(swapper_pg_dir)); ++ #else + pgd_t *pgdp = pgd_set_fixmap(__pa_symbol(swapper_pg_dir)); ++ #endif ++ ++ + extern pgd_t init_idmap_pg_dir[]; + + idmap_t0sz = 63UL - __fls(__pa_symbol(_end) | GENMASK(VA_BITS_MIN - 1, 0)); +@@ -803,7 +2063,21 @@ void __init paging_init(void) + map_kernel(pgdp); + map_mem(pgdp); + ++ // Map the whole physical mem into IEE, but set invalid. ++#ifdef CONFIG_IEE ++ map_iee(pgdp); ++#else ++#ifdef CONFIG_KOI ++ map_koi(pgdp); ++#endif ++#endif ++ ++ // Avoid using iee code to modify pgtable before iee initialized. ++ #ifdef CONFIG_PTP ++ pgd_clear_fixmap_init(); ++ #else + pgd_clear_fixmap(); ++ #endif + + cpu_replace_ttbr1(lm_alias(swapper_pg_dir), init_idmap_pg_dir); + init_mm.pgd = swapper_pg_dir; +@@ -814,6 +2088,83 @@ void __init paging_init(void) + memblock_allow_resize(); + + create_idmap(); ++ ++ #ifdef CONFIG_IEE ++ // test iee_exec_entry ++ iee_rwx_gate_entry(IEE_SI_TEST); ++ // Initialize init iee stack. ++ #ifdef CONFIG_PTP ++ set_init_iee_stack_page_pre_init((unsigned long)init_iee_stack_begin); ++ #else ++ set_init_iee_stack_page((unsigned long)init_iee_stack_begin); ++ #endif ++ #endif ++ ++ // Init token for init_task. ++ #ifdef CONFIG_IEE ++ // Change SP_EL0 from Image VA to Logical VA. ++ SP_EL0 = (unsigned long)__va(__pa_symbol(&init_task)); ++ write_sysreg(SP_EL0, sp_el0); ++ init_task.cpus_ptr = &(((struct task_struct *)(__va(__pa_symbol(&init_task))))->cpus_mask); ++ init_task.children.prev = (__va(__pa_symbol(init_task.children.prev))); ++ init_task.children.next = (__va(__pa_symbol(init_task.children.next))); ++ // Alloc a page for init_token. ++ new = __va(early_pgtable_alloc(0)); ++ init_token_page_vaddr = new; ++ init_token = (void *)__phys_to_iee(__pa_symbol(&init_task)); ++ // Use lm to write token before IEE initialized. ++ token = (struct task_token *)((unsigned long)new + (((unsigned long)&init_task) & ~PAGE_MASK)); ++ token->pgd = NULL; ++ token->iee_stack = __phys_to_iee(__pa_symbol((void *)init_iee_stack_end)); ++ token->valid = true; ++ iee_set_token_page_valid_pre_init(init_token, new); ++ #endif ++ ++ #ifdef CONFIG_PTP ++ // Map the existing pgtable into IEE, set valid. ++ init_iee(); ++ #endif ++ ++ #ifdef CONFIG_IEE ++ sysreg_clear_set(sctlr_el1, 0, SCTLR_EL1_SPAN); ++ #endif ++ ++ // IEE ready. ++ // Pgtable writing before uses logical memory and after uses IEE memory. ++ ++ #ifdef CONFIG_IEE ++ // Set HPD1 as 1. ++ tcr = read_sysreg(tcr_el1); ++ tcr |= ((unsigned long)0x1 << 42); ++ write_sysreg(tcr, tcr_el1); ++ isb(); ++ ++ // Flush tlb to enable IEE. ++ flush_tlb_all(); ++ ++ // mark that iee is prepared. ++ iee_init_done = true; ++#else ++#ifdef CONFIG_KOI ++ unsigned long SP_EL0 = __va(__pa_symbol(&init_task)); ++ write_sysreg(SP_EL0, sp_el0); ++ init_task.cpus_ptr = &(((struct task_struct *)(__va(__pa_symbol(&init_task))))->cpus_mask); ++ init_task.children.prev = (__va(__pa_symbol(init_task.children.prev))); ++ init_task.children.next = (__va(__pa_symbol(init_task.children.next))); ++ // create a new page for token ++ void *alloc_token = __va(early_pgtable_alloc(0)); ++ // get the address of token ++ void *token_addr = __phys_to_virt(__pa_symbol(&init_task)) + KOI_OFFSET; ++ // add memory mapping for token ++ koi_add_page_mapping(token_addr, (void *)alloc_token); ++ // printk(KERN_ERR "token_addr=0x%16llx, alloc_token=0x%16llx, init_task=0x%16llx, virt=0x%16llx\n", token_addr, alloc_token, &init_task, __phys_to_virt(__pa_symbol(&init_task))); ++ struct task_token *token = (struct task_token *)((unsigned long)alloc_token + (((unsigned long)&init_task) & ~PAGE_MASK)); ++ token->koi_kernel_stack = NULL; ++ token->koi_stack = NULL; ++ token->koi_stack_base = NULL; ++ token->current_ttbr1 = 0; ++#endif ++#endif + } + + #ifdef CONFIG_MEMORY_HOTPLUG +@@ -1261,6 +2612,9 @@ int pmd_free_pte_page(pmd_t *pmdp, unsigned long addr) + table = pte_offset_kernel(pmdp, addr); + pmd_clear(pmdp); + __flush_tlb_kernel_pgtable(addr); ++ #ifdef CONFIG_PTP ++ iee_memset(table, 0, PAGE_SIZE); ++ #endif + pte_free_kernel(NULL, table); + return 1; + } +@@ -1521,3 +2875,93 @@ void ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, pte + { + set_pte_at(vma->vm_mm, addr, ptep, pte); + } ++ ++#if !defined(CONFIG_IEE) && defined (CONFIG_KOI) ++static void __create_pgd_mapping_for_koi(pgd_t *pgdir, phys_addr_t phys, ++ unsigned long virt, phys_addr_t size, ++ pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(int), ++ int flags) ++{ ++ unsigned long addr, end, next; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, virt); ++ ++ /* ++ * If the virtual and physical address don't have the same offset ++ * within a page, we cannot map the region as the caller expects. ++ */ ++ if (WARN_ON((phys ^ virt) & ~PAGE_MASK)) ++ return; ++ ++ phys &= PAGE_MASK; ++ addr = virt & PAGE_MASK; ++ end = PAGE_ALIGN(virt + size); ++ ++ do { ++ next = pgd_addr_end(addr, end); ++ alloc_init_pud(pgdp, addr, next, phys, prot, pgtable_alloc, ++ flags); ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ p4d_t p4d = READ_ONCE(*p4dp); ++ __p4d_populate(p4dp, __p4d_to_phys(p4d), PUD_TYPE_TABLE); ++ phys += next - addr; ++ } while (pgdp++, addr = next, addr != end); ++} ++ ++static void __init __map_memblock_for_koi(pgd_t *pgdp, phys_addr_t start, ++ phys_addr_t end, pgprot_t prot, int flags) ++{ ++ __create_pgd_mapping_for_koi(pgdp, start, __phys_to_virt(start) + KOI_OFFSET, end - start, ++ prot, early_pgtable_alloc, flags); ++} ++ ++static void __init map_koi(pgd_t *pgdp) ++{ ++ phys_addr_t kernel_start = __pa_symbol(_text); ++ phys_addr_t kernel_end = __pa_symbol(__init_begin); ++ phys_addr_t start, end; ++ int flags = 0; ++ u64 i; ++ ++ flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; ++ ++ /* ++ * Take care not to create a writable alias for the ++ * read-only text and rodata sections of the kernel image. ++ * So temporarily mark them as NOMAP to skip mappings in ++ * the following for-loop ++ */ ++ memblock_mark_nomap(kernel_start, kernel_end - kernel_start); ++#ifdef CONFIG_KEXEC_CORE ++ if (crashk_res.end) ++ memblock_mark_nomap(crashk_res.start, ++ resource_size(&crashk_res)); ++#endif ++ ++ /* map all the memory banks */ ++ for_each_mem_range(i, &start, &end) { ++ if (start >= end) ++ break; ++ /* ++ * The linear map must allow allocation tags reading/writing ++ * if MTE is present. Otherwise, it has the same attributes as ++ * PAGE_KERNEL. ++ */ ++ __map_memblock_for_koi(pgdp, start, end, SET_NG(SET_INVALID(PAGE_KERNEL)), flags); ++ } ++#ifdef CONFIG_KEXEC_CORE ++ /* ++ * Use page-level mappings here so that we can shrink the region ++ * in page granularity and put back unused memory to buddy system ++ * through /sys/kernel/kexec_crash_size interface. ++ */ ++ if (crashk_res.end) { ++ __map_memblock_for_koi(pgdp, crashk_res.start, crashk_res.end + 1, ++ SET_NG(SET_INVALID(PAGE_KERNEL)), ++ NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS); ++ memblock_clear_nomap(crashk_res.start, ++ resource_size(&crashk_res)); ++ } ++#endif ++} ++#endif +\ No newline at end of file +diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c +index 4a64089e5771..b99b35a5190f 100644 +--- a/arch/arm64/mm/pgd.c ++++ b/arch/arm64/mm/pgd.c +@@ -15,14 +15,38 @@ + #include + #include + ++#ifdef CONFIG_PTP ++#include ++#endif ++ + static struct kmem_cache *pgd_cache __ro_after_init; + ++#ifdef CONFIG_KOI ++pgd_t *koi_pgd_alloc(void) ++{ ++ pgd_t *pgd; ++#ifdef CONFIG_PTP ++ pgd = (pgd_t *)get_iee_pgtable_page(GFP_PGTABLE_KERNEL); ++#else ++ pgd = (pgd_t *)__get_free_page(GFP_PGTABLE_KERNEL); ++#endif ++ return pgd; ++} ++#endif ++ + pgd_t *pgd_alloc(struct mm_struct *mm) + { + gfp_t gfp = GFP_PGTABLE_USER; + + if (PGD_SIZE == PAGE_SIZE) ++#ifdef CONFIG_PTP ++ { ++ pgd_t* new = (pgd_t *)get_iee_pgtable_page(gfp); ++ return new; ++ } ++#else + return (pgd_t *)__get_free_page(gfp); ++#endif + else + return kmem_cache_alloc(pgd_cache, gfp); + } +@@ -30,7 +54,13 @@ pgd_t *pgd_alloc(struct mm_struct *mm) + void pgd_free(struct mm_struct *mm, pgd_t *pgd) + { + if (PGD_SIZE == PAGE_SIZE) ++#ifdef CONFIG_PTP ++ { ++ free_iee_pgtable_page((void *)pgd); ++ } ++#else + free_page((unsigned long)pgd); ++#endif + else + kmem_cache_free(pgd_cache, pgd); + } +diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S +index 14fdf645edc8..4fad195becff 100644 +--- a/arch/arm64/mm/proc.S ++++ b/arch/arm64/mm/proc.S +@@ -22,6 +22,8 @@ + #include + #include + ++ ++ + #ifdef CONFIG_ARM64_64K_PAGES + #define TCR_TG_FLAGS TCR_TG0_64K | TCR_TG1_64K + #elif defined(CONFIG_ARM64_16K_PAGES) +@@ -190,6 +192,7 @@ SYM_TYPED_FUNC_START(idmap_cpu_replace_ttbr1) + __idmap_cpu_set_reserved_ttbr1 x1, x3 + + offset_ttbr1 x0, x3 ++ + msr ttbr1_el1, x0 + isb + +@@ -452,6 +455,11 @@ SYM_FUNC_START(__cpu_setup) + orr tcr, tcr, #TCR_HA // hardware Access flag update + 1: + #endif /* CONFIG_ARM64_HW_AFDBM */ ++ ++#ifdef CONFIG_IEE ++ orr tcr, tcr, #TCR_HPD1 // Hierarchical permission disables ++#endif ++ + msr mair_el1, mair + msr tcr_el1, tcr + +diff --git a/arch/arm64/mm/trans_pgd.c b/arch/arm64/mm/trans_pgd.c +index 5139a28130c0..729b6f5a9314 100644 +--- a/arch/arm64/mm/trans_pgd.c ++++ b/arch/arm64/mm/trans_pgd.c +@@ -25,6 +25,9 @@ + #include + #include + #include ++#ifdef CONFIG_PTP ++#include ++#endif + + static void *trans_alloc(struct trans_pgd_info *info) + { +@@ -65,10 +68,16 @@ static int copy_pte(struct trans_pgd_info *info, pmd_t *dst_pmdp, + pte_t *src_ptep; + pte_t *dst_ptep; + unsigned long addr = start; ++ #ifdef CONFIG_PTP ++ unsigned long iee_addr; ++ #endif + + dst_ptep = trans_alloc(info); + if (!dst_ptep) + return -ENOMEM; ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)dst_ptep,0); ++ #endif + pmd_populate_kernel(NULL, dst_pmdp, dst_ptep); + dst_ptep = pte_offset_kernel(dst_pmdp, start); + +@@ -87,11 +96,17 @@ static int copy_pmd(struct trans_pgd_info *info, pud_t *dst_pudp, + pmd_t *dst_pmdp; + unsigned long next; + unsigned long addr = start; ++ #ifdef CONFIG_PTP ++ unsigned long iee_addr; ++ #endif + + if (pud_none(READ_ONCE(*dst_pudp))) { + dst_pmdp = trans_alloc(info); + if (!dst_pmdp) + return -ENOMEM; ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)dst_pmdp,0); ++ #endif + pud_populate(NULL, dst_pudp, dst_pmdp); + } + dst_pmdp = pmd_offset(dst_pudp, start); +@@ -123,11 +138,17 @@ static int copy_pud(struct trans_pgd_info *info, p4d_t *dst_p4dp, + pud_t *src_pudp; + unsigned long next; + unsigned long addr = start; ++ #ifdef CONFIG_PTP ++ unsigned long iee_addr; ++ #endif + + if (p4d_none(READ_ONCE(*dst_p4dp))) { + dst_pudp = trans_alloc(info); + if (!dst_pudp) + return -ENOMEM; ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)dst_pudp,0); ++ #endif + p4d_populate(NULL, dst_p4dp, dst_pudp); + } + dst_pudp = pud_offset(dst_p4dp, start); +@@ -212,6 +233,10 @@ int trans_pgd_create_copy(struct trans_pgd_info *info, pgd_t **dst_pgdp, + return -ENOMEM; + } + ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)trans_pgd,0); ++ #endif ++ + rc = copy_page_tables(info, trans_pgd, start, end); + if (!rc) + *dst_pgdp = trans_pgd; +@@ -238,6 +263,9 @@ int trans_pgd_idmap_page(struct trans_pgd_info *info, phys_addr_t *trans_ttbr0, + int bits_mapped = PAGE_SHIFT - 4; + unsigned long level_mask, prev_level_entry, *levels[4]; + int this_level, index, level_lsb, level_msb; ++ #ifdef CONFIG_PTP ++ unsigned long iee_addr; ++ #endif + + dst_addr &= PAGE_MASK; + prev_level_entry = pte_val(pfn_pte(pfn, PAGE_KERNEL_ROX)); +@@ -247,12 +275,20 @@ int trans_pgd_idmap_page(struct trans_pgd_info *info, phys_addr_t *trans_ttbr0, + if (!levels[this_level]) + return -ENOMEM; + ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)levels[this_level],0); ++ #endif ++ + level_lsb = ARM64_HW_PGTABLE_LEVEL_SHIFT(this_level); + level_msb = min(level_lsb + bits_mapped, max_msb); + level_mask = GENMASK_ULL(level_msb, level_lsb); + + index = (dst_addr & level_mask) >> level_lsb; ++ #ifdef CONFIG_PTP ++ set_pte((pte_t *)(levels[this_level] + index), __pte(prev_level_entry)); ++ #else + *(levels[this_level] + index) = prev_level_entry; ++ #endif + + pfn = virt_to_pfn(levels[this_level]); + prev_level_entry = pte_val(pfn_pte(pfn, +diff --git a/block/sed-opal.c b/block/sed-opal.c +index 1a1cb35bf4b7..7149485a808c 100644 +--- a/block/sed-opal.c ++++ b/block/sed-opal.c +@@ -316,7 +316,11 @@ static int read_sed_opal_key(const char *key_name, u_char *buffer, int buflen) + return PTR_ERR(kref); + + key = key_ref_to_ptr(kref); ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(key)); ++ #else + down_read(&key->sem); ++ #endif + ret = key_validate(key); + if (ret == 0) { + if (buflen > key->datalen) +@@ -324,7 +328,11 @@ static int read_sed_opal_key(const char *key_name, u_char *buffer, int buflen) - spin_lock(&swapper_pgdir_lock); -@@ -90,6 +370,7 @@ void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd) + ret = key->type->read(key, (char *)buffer, buflen); + } ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + + key_ref_put(kref); + +diff --git a/certs/blacklist.c b/certs/blacklist.c +index 675dd7a8f07a..4db9c6cb7732 100644 +--- a/certs/blacklist.c ++++ b/certs/blacklist.c +@@ -19,6 +19,10 @@ + #include + #include "blacklist.h" + ++#ifdef CONFIG_KEYP ++#include ++#endif ++ + /* + * According to crypto/asymmetric_keys/x509_cert_parser.c:x509_note_pkey_algo(), + * the size of the currently longest supported hash algorithm is 512 bits, +@@ -91,7 +95,11 @@ static int blacklist_key_instantiate(struct key *key, + #endif + + /* Sets safe default permissions for keys loaded by user space. */ ++ #ifdef CONFIG_KEYP ++ iee_set_key_perm(key, BLACKLIST_KEY_PERM); ++ #else + key->perm = BLACKLIST_KEY_PERM; ++ #endif + + /* + * Skips the authentication step for builtin hashes, they are not +diff --git a/certs/system_keyring.c b/certs/system_keyring.c +index a803524044bd..eab10ce55564 100644 +--- a/certs/system_keyring.c ++++ b/certs/system_keyring.c +@@ -96,9 +96,15 @@ int restrict_link_by_builtin_and_secondary_trusted( + /* If we have a secondary trusted keyring, then that contains a link + * through to the builtin keyring and the search will follow that link. */ - pgd_clear_fixmap(); - spin_unlock(&swapper_pgdir_lock); ++ #ifdef CONFIG_KEYP ++ if (type == &key_type_keyring && ++ dest_keyring == secondary_trusted_keys && ++ payload == (union key_payload *)(builtin_trusted_keys->name_link.next)) ++ #else + if (type == &key_type_keyring && + dest_keyring == secondary_trusted_keys && + payload == &builtin_trusted_keys->payload) + #endif - } + /* Allow the builtin keyring to be added to the secondary */ + return 0; - pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, -@@ -118,7 +399,11 @@ static phys_addr_t __init early_pgtable_alloc(int shift) - * slot will be free, so we can (ab)use the FIX_PTE slot to initialise - * any level of table. +@@ -125,9 +131,15 @@ int restrict_link_by_digsig_builtin_and_secondary(struct key *dest_keyring, + /* If we have a secondary trusted keyring, then that contains a link + * through to the builtin keyring and the search will follow that link. */ ++ #ifdef CONFIG_KEYP ++ if (type == &key_type_keyring && ++ dest_keyring == secondary_trusted_keys && ++ payload == (union key_payload *)(builtin_trusted_keys->name_link.next)) ++ #else + if (type == &key_type_keyring && + dest_keyring == secondary_trusted_keys && + payload == &builtin_trusted_keys->payload) ++ #endif + /* Allow the builtin keyring to be added to the secondary */ + return 0; + +@@ -212,9 +224,15 @@ int restrict_link_by_builtin_secondary_and_machine( + const union key_payload *payload, + struct key *restrict_key) + { ++ #ifdef CONFIG_KEYP ++ if (machine_trusted_keys && type == &key_type_keyring && ++ dest_keyring == secondary_trusted_keys && ++ payload == (union key_payload *)(machine_trusted_keys->name_link.next)) ++ #else + if (machine_trusted_keys && type == &key_type_keyring && + dest_keyring == secondary_trusted_keys && + payload == &machine_trusted_keys->payload) ++ #endif + /* Allow the machine keyring to be added to the secondary */ + return 0; + +diff --git a/crypto/af_alg.c b/crypto/af_alg.c +index 68cc9290cabe..6d4415de9ee4 100644 +--- a/crypto/af_alg.c ++++ b/crypto/af_alg.c +@@ -304,7 +304,11 @@ static int alg_setkey_by_key_serial(struct alg_sock *ask, sockptr_t optval, + if (IS_ERR(key)) + return PTR_ERR(key); + ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(key)); ++ #else + down_read(&key->sem); ++ #endif + + ret = ERR_PTR(-ENOPROTOOPT); + if (!strcmp(key->type->name, "user") || +@@ -319,21 +323,33 @@ static int alg_setkey_by_key_serial(struct alg_sock *ask, sockptr_t optval, + } + + if (IS_ERR(ret)) { ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + return PTR_ERR(ret); + } + + key_data = sock_kmalloc(&ask->sk, key_datalen, GFP_KERNEL); + if (!key_data) { ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + return -ENOMEM; + } + + memcpy(key_data, ret, key_datalen); + ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + + err = type->setkey(ask->private, key_data, key_datalen); +diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c +index 43af5fa510c0..40dd58a69617 100644 +--- a/crypto/asymmetric_keys/asymmetric_type.c ++++ b/crypto/asymmetric_keys/asymmetric_type.c +@@ -16,6 +16,9 @@ + #include + #include + #include "asymmetric_keys.h" ++#ifdef CONFIG_KEYP ++#include ++#endif + + + const char *const key_being_used_for[NR__KEY_BEING_USED_FOR] = { +@@ -467,6 +470,18 @@ static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep) + static void asymmetric_key_destroy(struct key *key) + { + struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); ++ #ifdef CONFIG_KEYP ++ struct asymmetric_key_ids *kids = ((union key_payload *)(key->name_link.next))->data[asym_key_ids]; ++ void *data = ((union key_payload *)(key->name_link.next))->data[asym_crypto]; ++ void *auth = ((union key_payload *)(key->name_link.next))->data[asym_auth]; ++ ++ union key_payload key_payload = *((union key_payload *)(key->name_link.next)); ++ key_payload.data[asym_crypto] = NULL; ++ key_payload.data[asym_subtype] = NULL; ++ key_payload.data[asym_key_ids] = NULL; ++ key_payload.data[asym_auth] = NULL; ++ iee_write_key_payload(key, key_payload); ++ #else + struct asymmetric_key_ids *kids = key->payload.data[asym_key_ids]; + void *data = key->payload.data[asym_crypto]; + void *auth = key->payload.data[asym_auth]; +@@ -475,6 +490,7 @@ static void asymmetric_key_destroy(struct key *key) + key->payload.data[asym_subtype] = NULL; + key->payload.data[asym_key_ids] = NULL; + key->payload.data[asym_auth] = NULL; ++ #endif + + if (subtype) { + subtype->destroy(data, auth); +@@ -580,8 +596,13 @@ int asymmetric_key_eds_op(struct kernel_pkey_params *params, + if (key->type != &key_type_asymmetric) + return -EINVAL; + subtype = asymmetric_key_subtype(key); ++ #ifdef CONFIG_KEYP ++ if (!subtype || ++ !((union key_payload *)(key->name_link.next))->data[0]) ++ #else + if (!subtype || + !key->payload.data[0]) ++ #endif + return -EINVAL; + if (!subtype->eds_op) + return -ENOTSUPP; +diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c +index 1dcab27986a6..490ba98995c1 100644 +--- a/crypto/asymmetric_keys/public_key.c ++++ b/crypto/asymmetric_keys/public_key.c +@@ -30,7 +30,11 @@ MODULE_LICENSE("GPL"); + static void public_key_describe(const struct key *asymmetric_key, + struct seq_file *m) + { ++ #ifdef CONFIG_KEYP ++ struct public_key *key = ((union key_payload *)(asymmetric_key->name_link.next))->data[asym_crypto]; ++ #else + struct public_key *key = asymmetric_key->payload.data[asym_crypto]; ++ #endif + + if (key) + seq_printf(m, "%s.%s", key->id_type, key->pkey_algo); +@@ -158,7 +162,11 @@ static int software_key_query(const struct kernel_pkey_params *params, + struct kernel_pkey_query *info) + { + struct crypto_akcipher *tfm; ++ #ifdef CONFIG_KEYP ++ struct public_key *pkey = ((union key_payload *)(params->key->name_link.next))->data[asym_crypto]; ++ #else + struct public_key *pkey = params->key->payload.data[asym_crypto]; ++ #endif + char alg_name[CRYPTO_MAX_ALG_NAME]; + struct crypto_sig *sig; + u8 *key, *ptr; +@@ -273,7 +281,11 @@ static int software_key_query(const struct kernel_pkey_params *params, + static int software_key_eds_op(struct kernel_pkey_params *params, + const void *in, void *out) + { ++ #ifdef CONFIG_KEYP ++ const struct public_key *pkey = ((union key_payload *)(params->key->name_link.next))->data[asym_crypto]; ++ #else + const struct public_key *pkey = params->key->payload.data[asym_crypto]; ++ #endif + char alg_name[CRYPTO_MAX_ALG_NAME]; + struct crypto_akcipher *tfm; + struct crypto_sig *sig; +@@ -453,7 +465,11 @@ EXPORT_SYMBOL_GPL(public_key_verify_signature); + static int public_key_verify_signature_2(const struct key *key, + const struct public_key_signature *sig) + { ++ #ifdef CONFIG_KEYP ++ const struct public_key *pk = ((union key_payload *)(key->name_link.next))->data[asym_crypto]; ++ #else + const struct public_key *pk = key->payload.data[asym_crypto]; ++ #endif + return public_key_verify_signature(pk, sig); + } + +diff --git a/crypto/asymmetric_keys/signature.c b/crypto/asymmetric_keys/signature.c +index 2deff81f8af5..696fa2c4e708 100644 +--- a/crypto/asymmetric_keys/signature.c ++++ b/crypto/asymmetric_keys/signature.c +@@ -51,8 +51,13 @@ int query_asymmetric_key(const struct kernel_pkey_params *params, + if (key->type != &key_type_asymmetric) + return -EINVAL; + subtype = asymmetric_key_subtype(key); ++ #ifdef CONFIG_KEYP ++ if (!subtype || ++ !((union key_payload *)(key->name_link.next))->data[0]) ++ #else + if (!subtype || + !key->payload.data[0]) ++ #endif + return -EINVAL; + if (!subtype->query) + return -ENOTSUPP; +@@ -145,8 +150,13 @@ int verify_signature(const struct key *key, + if (key->type != &key_type_asymmetric) + return -EINVAL; + subtype = asymmetric_key_subtype(key); ++ #ifdef CONFIG_KEYP ++ if (!subtype || ++ !((union key_payload *)(key->name_link.next))->data[0]) ++ #else + if (!subtype || + !key->payload.data[0]) ++ #endif + return -EINVAL; + if (!subtype->verify_signature) + return -ENOTSUPP; +diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c +index 83092d93f36a..fb12e7d0660a 100644 +--- a/drivers/firmware/efi/arm-runtime.c ++++ b/drivers/firmware/efi/arm-runtime.c +@@ -94,7 +94,11 @@ static int __init arm_enable_runtime_services(void) + return 0; + } + + #ifdef CONFIG_PTP -+ ptr = pte_set_fixmap_init(phys); -+ #else - ptr = pte_set_fixmap(phys); ++ efi_memmap_unmap_after_init(); ++ #else + efi_memmap_unmap(); + #endif - memset(ptr, 0, PAGE_SIZE); + mapsize = efi.memmap.desc_size * efi.memmap.nr_map; + +diff --git a/drivers/firmware/efi/memmap.c b/drivers/firmware/efi/memmap.c +index 77dd20f9df31..ea8ebecaa153 100644 +--- a/drivers/firmware/efi/memmap.c ++++ b/drivers/firmware/efi/memmap.c +@@ -96,6 +96,26 @@ void __init efi_memmap_unmap(void) + clear_bit(EFI_MEMMAP, &efi.flags); + } + ++#ifdef CONFIG_PTP ++void __init efi_memmap_unmap_after_init(void) ++{ ++ if (!efi_enabled(EFI_MEMMAP)) ++ return; ++ ++ if (!(efi.memmap.flags & EFI_MEMMAP_LATE)) { ++ unsigned long size; ++ ++ size = efi.memmap.desc_size * efi.memmap.nr_map; ++ early_iounmap_after_init((__force void __iomem *)efi.memmap.map, size); ++ } else { ++ memunmap(efi.memmap.map); ++ } ++ ++ efi.memmap.map = NULL; ++ clear_bit(EFI_MEMMAP, &efi.flags); ++} ++#endif ++ + /** + * efi_memmap_init_late - Map efi.memmap with memremap() + * @phys_addr: Physical address of the new EFI memory map +diff --git a/drivers/md/Makefile b/drivers/md/Makefile +index 84291e38dca8..b3af9d419b6e 100644 +--- a/drivers/md/Makefile ++++ b/drivers/md/Makefile +@@ -71,6 +71,7 @@ obj-$(CONFIG_DM_PERSISTENT_DATA) += persistent-data/ + obj-$(CONFIG_DM_MIRROR) += dm-mirror.o dm-log.o dm-region-hash.o + obj-$(CONFIG_DM_LOG_USERSPACE) += dm-log-userspace.o + obj-$(CONFIG_DM_ZERO) += dm-zero.o ++obj-$(CONFIG_DM_ZERO_KOI) += dm-zero_koi.o + obj-$(CONFIG_DM_RAID) += dm-raid.o + obj-$(CONFIG_DM_THIN_PROVISIONING) += dm-thin-pool.o + obj-$(CONFIG_DM_VERITY) += dm-verity.o +diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c +index aa6bb5b4704b..ecf777e5d176 100644 +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -2512,7 +2512,11 @@ static int set_key_encrypted(struct crypt_config *cc, struct key *key) + { + const struct encrypted_key_payload *ekp; -@@ -126,11 +411,16 @@ static phys_addr_t __init early_pgtable_alloc(int shift) - * Implicit barriers also ensure the zeroed page is visible to the page - * table walker - */ -+ #ifdef CONFIG_PTP -+ pte_clear_fixmap_init(); ++ #ifdef CONFIG_KEYP ++ ekp = ((union key_payload *)(key->name_link.next))->data[0]; + #else - pte_clear_fixmap(); + ekp = key->payload.data[0]; + #endif + if (!ekp) + return -EKEYREVOKED; - return phys; - } - -+ - bool pgattr_change_is_safe(u64 old, u64 new) +@@ -2528,7 +2532,11 @@ static int set_key_trusted(struct crypt_config *cc, struct key *key) { - /* -@@ -178,7 +468,11 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end, - do { - pte_t old_pte = __ptep_get(ptep); + const struct trusted_key_payload *tkp; -+ #ifdef CONFIG_PTP -+ iee_set_fixmap_pte_pre_init(ptep, pfn_pte(__phys_to_pfn(phys), prot)); -+ #else - __set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot)); -+ #endif ++ #ifdef CONFIG_KEYP ++ tkp = ((union key_payload *)(key->name_link.next))->data[0]; ++ #else + tkp = key->payload.data[0]; ++ #endif + if (!tkp) + return -EKEYREVOKED; - /* - * After the PTE entry has been populated once, we -@@ -211,7 +505,11 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr, - pmdval |= PMD_TABLE_PXN; - BUG_ON(!pgtable_alloc); - pte_phys = pgtable_alloc(PAGE_SHIFT); -+ #ifdef CONFIG_PTP -+ __iee_pmd_populate_fixmap(pmdp, pte_phys, pmdval); -+ #else - __pmd_populate(pmdp, pte_phys, pmdval); -+ #endif - pmd = READ_ONCE(*pmdp); +@@ -2590,17 +2598,29 @@ static int crypt_set_keyring_key(struct crypt_config *cc, const char *key_string + return PTR_ERR(key); } - BUG_ON(pmd_bad(pmd)); -@@ -248,7 +546,11 @@ static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end, - /* try section mapping first */ - if (((addr | next | phys) & ~PMD_MASK) == 0 && - (flags & NO_BLOCK_MAPPINGS) == 0) { -+ #ifdef CONFIG_PTP -+ iee_pmd_set_huge_fixmap(pmdp, phys, prot); -+ #else - pmd_set_huge(pmdp, phys, prot); -+ #endif - /* - * After the PMD entry has been populated once, we -@@ -289,7 +591,11 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr, - pudval |= PUD_TABLE_PXN; - BUG_ON(!pgtable_alloc); - pmd_phys = pgtable_alloc(PMD_SHIFT); -- __pud_populate(pudp, pmd_phys, pudval); -+ #ifdef CONFIG_PTP -+ __iee_pud_populate_fixmap(pudp, pmd_phys, PUD_TYPE_TABLE); ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(key)); ++ #else + down_read(&key->sem); ++ #endif + + ret = set_key(cc, key); + if (ret < 0) { ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); + #else -+ __pud_populate(pudp, pmd_phys, PUD_TYPE_TABLE); + up_read(&key->sem); + #endif - pud = READ_ONCE(*pudp); + key_put(key); + kfree_sensitive(new_key_string); + return ret; } - BUG_ON(pud_bad(pud)); -@@ -345,7 +651,11 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end, - if (pud_sect_supported() && - ((addr | next | phys) & ~PUD_MASK) == 0 && - (flags & NO_BLOCK_MAPPINGS) == 0) { -+ #ifdef CONFIG_PTP -+ iee_pud_set_huge_fixmap(pudp, phys, prot); -+ #else - pud_set_huge(pudp, phys, prot); -+ #endif - /* - * After the PUD entry has been populated once, we -@@ -374,6 +684,10 @@ static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys, - { - unsigned long addr, end, next; - pgd_t *pgdp = pgd_offset_pgd(pgdir, virt); -+ #ifdef CONFIG_IEE -+ p4d_t *p4dp; -+ p4d_t p4d; ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + + /* clear the flag since following operations may invalidate previously valid key */ +diff --git a/drivers/md/dm-verity-verify-sig.c b/drivers/md/dm-verity-verify-sig.c +index 4836508ea50c..d52d5bccc190 100644 +--- a/drivers/md/dm-verity-verify-sig.c ++++ b/drivers/md/dm-verity-verify-sig.c +@@ -40,7 +40,11 @@ static int verity_verify_get_sig_from_key(const char *key_desc, + if (IS_ERR(key)) + return PTR_ERR(key); + ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(key)); ++ #else + down_read(&key->sem); + #endif - /* - * If the virtual and physical address don't have the same offset -@@ -390,10 +704,14 @@ static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys, - next = pgd_addr_end(addr, end); - alloc_init_pud(pgdp, addr, next, phys, prot, pgtable_alloc, - flags); -+ #ifdef CONFIG_IEE -+ p4dp = p4d_offset(pgdp, addr); -+ p4d = READ_ONCE(*p4dp); -+ __p4d_populate(p4dp, __p4d_to_phys(p4d), (PGD_APT | PUD_TYPE_TABLE)); -+ #endif - phys += next - addr; - } while (pgdp++, addr = next, addr != end); - } -- - static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys, - unsigned long virt, phys_addr_t size, - pgprot_t prot, -@@ -413,162 +731,844 @@ void create_kpti_ng_temp_pgd(pgd_t *pgdir, phys_addr_t phys, unsigned long virt, - phys_addr_t (*pgtable_alloc)(int), int flags); - #endif - --static phys_addr_t __pgd_pgtable_alloc(int shift) -+#ifdef CONFIG_PTP -+static int __init iee_pud_set_huge_pre_init(pud_t *pudp, phys_addr_t phys, pgprot_t prot) - { -- void *ptr = (void *)__get_free_page(GFP_PGTABLE_KERNEL); -- BUG_ON(!ptr); -+ pud_t new_pud = pfn_pud(__phys_to_pfn(phys), mk_pud_sect_prot(prot)); + ukp = user_key_payload_locked(key); + if (!ukp) { +@@ -58,7 +62,11 @@ static int verity_verify_get_sig_from_key(const char *key_desc, + memcpy(sig_opts->sig, ukp->data, sig_opts->sig_size); -- /* Ensure the zeroed page is visible to the page table walker */ -- dsb(ishst); -- return __pa(ptr); -+ /* Only allow permission changes for now */ -+ if (!pgattr_change_is_safe(READ_ONCE(pud_val(*pudp)), -+ pud_val(new_pud))) -+ return 0; -+ -+ VM_BUG_ON(phys & ~PUD_MASK); -+ iee_set_pud_pre_init(pudp, new_pud); -+ return 1; - } + end: ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); --static phys_addr_t pgd_pgtable_alloc(int shift) -+static int __init iee_pmd_set_huge_pre_init(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot) + return ret; +diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c +index a03e3c45f297..71bccea085e9 100644 +--- a/drivers/nvdimm/security.c ++++ b/drivers/nvdimm/security.c +@@ -28,7 +28,11 @@ static void *key_data(struct key *key) { -- phys_addr_t pa = __pgd_pgtable_alloc(shift); -- struct ptdesc *ptdesc = page_ptdesc(phys_to_page(pa)); -- -- /* -- * Call proper page table ctor in case later we need to -- * call core mm functions like apply_to_page_range() on -- * this pre-allocated page table. -- * -- * We don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK if pmd is -- * folded, and if so pagetable_pte_ctor() becomes nop. -- */ -- if (shift == PAGE_SHIFT) -- BUG_ON(!pagetable_pte_ctor(ptdesc)); -- else if (shift == PMD_SHIFT) -- BUG_ON(!pagetable_pmd_ctor(ptdesc)); -+ pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), mk_pmd_sect_prot(prot)); + struct encrypted_key_payload *epayload = dereference_key_locked(key); -- return pa; --} -+ /* Only allow permission changes for now */ -+ if (!pgattr_change_is_safe(READ_ONCE(pmd_val(*pmdp)), -+ pmd_val(new_pmd))) -+ return 0; ++ #ifdef CONFIG_KEYP ++ lockdep_assert_held_read(&KEY_SEM(key)); ++ #else + lockdep_assert_held_read(&key->sem); ++ #endif --/* -- * This function can only be used to modify existing table entries, -- * without allocating new levels of table. Note that this permits the -- * creation of new section or page entries. -- */ --void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt, -- phys_addr_t size, pgprot_t prot) --{ -- if (virt < PAGE_OFFSET) { -- pr_warn("BUG: not creating mapping for %pa at 0x%016lx - outside kernel range\n", -- &phys, virt); -- return; -- } -- __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, -- NO_CONT_MAPPINGS); -+ VM_BUG_ON(phys & ~PMD_MASK); -+ iee_set_pmd_pre_init(pmdp, new_pmd); -+ return 1; + return epayload->decrypted_data; } +@@ -38,7 +42,11 @@ static void nvdimm_put_key(struct key *key) + if (!key) + return; --void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, -- unsigned long virt, phys_addr_t size, -- pgprot_t prot, bool page_mappings_only) -+static __init void iee_init_pte_pre_init(pmd_t *pmdp, unsigned long addr, unsigned long end, -+ phys_addr_t phys, pgprot_t prot) - { -- int flags = 0; -- -- BUG_ON(mm == &init_mm); -+ pte_t *ptep; - -- if (page_mappings_only) -- flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; -+ ptep = pte_set_fixmap_offset_init(pmdp, addr); -+ do { -+ pte_t old_pte = READ_ONCE(*ptep); - -- __create_pgd_mapping(mm->pgd, phys, virt, size, prot, -- pgd_pgtable_alloc, flags); --} -+ iee_set_pte_pre_init(ptep, pfn_pte(__phys_to_pfn(phys), prot)); - --static void update_mapping_prot(phys_addr_t phys, unsigned long virt, -- phys_addr_t size, pgprot_t prot) --{ -- if (virt < PAGE_OFFSET) { -- pr_warn("BUG: not updating mapping for %pa at 0x%016lx - outside kernel range\n", -- &phys, virt); -- return; -- } -+ /* -+ * After the PTE entry has been populated once, we -+ * only allow updates to the permission attributes. -+ */ -+ BUG_ON(!pgattr_change_is_safe(pte_val(old_pte), -+ READ_ONCE(pte_val(*ptep)))); - -- __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, -- NO_CONT_MAPPINGS); -+ phys += PAGE_SIZE; -+ } while (ptep++, addr += PAGE_SIZE, addr != end); - -- /* flush the TLBs after updating live kernel mappings */ -- flush_tlb_kernel_range(virt, virt + size); -+ pte_clear_fixmap_init(); ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); } --static void __init __map_memblock(pgd_t *pgdp, phys_addr_t start, -- phys_addr_t end, pgprot_t prot, int flags) -+static __init void iee_alloc_init_cont_pte_pre_init(pmd_t *pmdp, unsigned long addr, -+ unsigned long end, phys_addr_t phys, -+ pgprot_t prot, -+ phys_addr_t (*pgtable_alloc)(int), -+ int flags) - { -- __create_pgd_mapping(pgdp, start, __phys_to_virt(start), end - start, -- prot, early_pgtable_alloc, flags); --} -+ unsigned long next; -+ pmd_t pmd = READ_ONCE(*pmdp); +@@ -65,10 +73,18 @@ static struct key *nvdimm_request_key(struct nvdimm *nvdimm) + } else { + struct encrypted_key_payload *epayload; --void __init mark_linear_text_alias_ro(void) --{ -- /* -- * Remove the write permissions from the linear alias of .text/.rodata -- */ -- update_mapping_prot(__pa_symbol(_stext), (unsigned long)lm_alias(_stext), -- (unsigned long)__init_begin - (unsigned long)_stext, -- PAGE_KERNEL_RO); --} -+ BUG_ON(pmd_sect(pmd)); -+ if (pmd_none(pmd)) { -+ pmdval_t pmdval = PMD_TYPE_TABLE | PMD_TABLE_UXN; -+ phys_addr_t pte_phys; ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(key)); ++ #else + down_read(&key->sem); ++ #endif + epayload = dereference_key_locked(key); + if (epayload->decrypted_datalen != NVDIMM_PASSPHRASE_LEN) { ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + key = NULL; + } +@@ -107,10 +123,18 @@ static struct key *nvdimm_lookup_user_key(struct nvdimm *nvdimm, --#ifdef CONFIG_KFENCE -+ if (flags & NO_EXEC_MAPPINGS) -+ pmdval |= PMD_TABLE_PXN; -+ BUG_ON(!pgtable_alloc); -+ pte_phys = pgtable_alloc(PAGE_SHIFT); -+ __iee_pmd_populate_pre_init(pmdp, pte_phys, pmdval); -+ pmd = READ_ONCE(*pmdp); -+ } -+ BUG_ON(pmd_bad(pmd)); + dev_dbg(dev, "%s: key found: %#x\n", __func__, key_serial(key)); + ++ #ifdef CONFIG_KEYP ++ down_read_nested(&KEY_SEM(key), subclass); ++ #else + down_read_nested(&key->sem, subclass); ++ #endif + epayload = dereference_key_locked(key); + if (epayload->decrypted_datalen != NVDIMM_PASSPHRASE_LEN) { ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + key = NULL; + } +diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c +index 7e0d8fb26465..950ee6396659 100644 +--- a/drivers/rtc/rtc-test.c ++++ b/drivers/rtc/rtc-test.c +@@ -198,4 +198,4 @@ MODULE_DESCRIPTION("RTC test driver/device"); + MODULE_LICENSE("GPL v2"); + + module_init(test_init); +-module_exit(test_exit); ++module_exit(test_exit); +\ No newline at end of file +diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c +index a5fbb6ed38ae..81428783b9da 100644 +--- a/drivers/tty/serial/earlycon.c ++++ b/drivers/tty/serial/earlycon.c +@@ -40,7 +40,11 @@ static void __iomem * __init earlycon_map(resource_size_t paddr, size_t size) + { + void __iomem *base; + #ifdef CONFIG_FIX_EARLYCON_MEM ++ #ifdef CONFIG_PTP ++ __iee_set_fixmap_pre_init(FIX_EARLYCON_MEM_BASE, paddr & PAGE_MASK, FIXMAP_PAGE_IO); ++ #else + set_fixmap_io(FIX_EARLYCON_MEM_BASE, paddr & PAGE_MASK); ++ #endif + base = (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE); + base += paddr & ~PAGE_MASK; + #else +diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c +index 45b42d8f6453..b71072d6957e 100644 +--- a/drivers/usb/early/ehci-dbgp.c ++++ b/drivers/usb/early/ehci-dbgp.c +@@ -879,7 +879,11 @@ int __init early_dbgp_init(char *s) + * FIXME I don't have the bar size so just guess PAGE_SIZE is more + * than enough. 1K is the biggest I have seen. + */ ++ #ifdef CONFIG_PTP ++ __iee_set_fixmap_pre_init(FIX_DBGP_BASE, bar_val & PAGE_MASK, FIXMAP_PAGE_NOCACHE); ++ #else + set_fixmap_nocache(FIX_DBGP_BASE, bar_val & PAGE_MASK); ++ #endif + ehci_bar = (void __iomem *)__fix_to_virt(FIX_DBGP_BASE); + ehci_bar += bar_val & ~PAGE_MASK; + dbgp_printk("ehci_bar: %p\n", ehci_bar); +diff --git a/fs/coredump.c b/fs/coredump.c +index 9d235fa14ab9..72be355903ca 100644 +--- a/fs/coredump.c ++++ b/fs/coredump.c +@@ -53,6 +53,10 @@ --bool __ro_after_init kfence_early_init = !!CONFIG_KFENCE_SAMPLE_INTERVAL; -+ do { -+ pgprot_t __prot = prot; + #include --/* early_param() will be parsed before map_mem() below. */ --static int __init parse_kfence_early_init(char *arg) --{ -- int val; -+ next = pte_cont_addr_end(addr, end); ++#ifdef CONFIG_CREDP ++#include ++#endif ++ + static bool dump_vma_snapshot(struct coredump_params *cprm); + static void free_vma_snapshot(struct coredump_params *cprm); -- if (get_option(&arg, &val)) -- kfence_early_init = !!val; -+ /* use a contiguous mapping if the range is suitably aligned */ -+ if ((((addr | next | phys) & ~CONT_PTE_MASK) == 0) && -+ (flags & NO_CONT_MAPPINGS) == 0) -+ __prot = __pgprot(pgprot_val(prot) | PTE_CONT); +@@ -564,7 +568,11 @@ void do_coredump(const kernel_siginfo_t *siginfo) + */ + if (__get_dumpable(cprm.mm_flags) == SUID_DUMP_ROOT) { + /* Setuid core dump mode */ ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(cred,GLOBAL_ROOT_UID); ++ #else + cred->fsuid = GLOBAL_ROOT_UID; /* Dump root private */ ++ #endif + need_suid_safe = true; + } --#if IS_ENABLED(CONFIG_KFENCE_MUST_EARLY_INIT) -- kfence_must_early_init = (val == -1) ? true : false; --#endif -+ iee_init_pte_pre_init(pmdp, addr, next, phys, __prot); +diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c +index 7cbb1fd872ac..a8425a83aabf 100644 +--- a/fs/crypto/keyring.c ++++ b/fs/crypto/keyring.c +@@ -590,8 +590,13 @@ static void fscrypt_provisioning_key_describe(const struct key *key, + { + seq_puts(m, key->description); + if (key_is_positive(key)) { ++ #ifdef CONFIG_KEYP ++ const struct fscrypt_provisioning_key_payload *payload = ++ ((union key_payload *)(key->name_link.next))->data[0]; ++ #else + const struct fscrypt_provisioning_key_payload *payload = + key->payload.data[0]; ++ #endif -- return 0; -+ phys += next - addr; -+ } while (addr = next, addr != end); - } --early_param("kfence.sample_interval", parse_kfence_early_init); + seq_printf(m, ": %u [%u]", key->datalen, payload->type); + } +@@ -599,7 +604,11 @@ static void fscrypt_provisioning_key_describe(const struct key *key, --static phys_addr_t __init arm64_kfence_alloc_pool(void) -+static __init void iee_init_pmd_pre_init(pud_t *pudp, unsigned long addr, unsigned long end, -+ phys_addr_t phys, pgprot_t prot, -+ phys_addr_t (*pgtable_alloc)(int), int flags) + static void fscrypt_provisioning_key_destroy(struct key *key) { -- phys_addr_t kfence_pool; -+ unsigned long next; -+ pmd_t *pmdp; ++ #ifdef CONFIG_KEYP ++ kfree_sensitive(((union key_payload *)(key->name_link.next))->data[0]); ++ #else + kfree_sensitive(key->payload.data[0]); ++ #endif + } -- if (!kfence_early_init) -- return 0; -+ pmdp = pmd_set_fixmap_offset_init(pudp, addr); -+ do { -+ pmd_t old_pmd = READ_ONCE(*pmdp); + static struct key_type key_type_fscrypt_provisioning = { +@@ -641,7 +650,11 @@ static int get_keyring_key(u32 key_id, u32 type, -- kfence_pool = memblock_phys_alloc(KFENCE_POOL_SIZE, PAGE_SIZE); -- if (!kfence_pool) { -- pr_err("failed to allocate kfence pool\n"); -- kfence_early_init = false; -- return 0; -- } -+ next = pmd_addr_end(addr, end); + if (key->type != &key_type_fscrypt_provisioning) + goto bad_key; ++ #ifdef CONFIG_KEYP ++ payload = ((union key_payload *)(key->name_link.next))->data[0]; ++ #else + payload = key->payload.data[0]; ++ #endif -- /* Temporarily mark as NOMAP. */ -- memblock_mark_nomap(kfence_pool, KFENCE_POOL_SIZE); -+ /* try section mapping first */ -+ if (((addr | next | phys) & ~PMD_MASK) == 0 && -+ (flags & NO_BLOCK_MAPPINGS) == 0) { -+ iee_pmd_set_huge_pre_init(pmdp, phys, prot); -+ -+ /* -+ * After the PMD entry has been populated once, we -+ * only allow updates to the permission attributes. -+ */ -+ BUG_ON(!pgattr_change_is_safe(pmd_val(old_pmd), -+ READ_ONCE(pmd_val(*pmdp)))); -+ } else { -+ iee_alloc_init_cont_pte_pre_init(pmdp, addr, next, phys, prot, -+ pgtable_alloc, flags); -+ -+ BUG_ON(pmd_val(old_pmd) != 0 && -+ pmd_val(old_pmd) != READ_ONCE(pmd_val(*pmdp))); -+ } -+ phys += next - addr; -+ } while (pmdp++, addr = next, addr != end); -+ -+ pmd_clear_fixmap_init(); -+} -+ -+static __init void iee_alloc_init_cont_pmd_pre_init(pud_t *pudp, unsigned long addr, -+ unsigned long end, phys_addr_t phys, -+ pgprot_t prot, -+ phys_addr_t (*pgtable_alloc)(int), int flags) -+{ -+ unsigned long next; -+ pud_t pud = READ_ONCE(*pudp); -+ -+ /* -+ * Check for initial section mappings in the pgd/pud. -+ */ -+ BUG_ON(pud_sect(pud)); -+ if (pud_none(pud)) { -+ pudval_t pudval = PUD_TYPE_TABLE | PUD_TABLE_UXN; -+ phys_addr_t pmd_phys; -+ -+ if (flags & NO_EXEC_MAPPINGS) -+ pudval |= PUD_TABLE_PXN; -+ BUG_ON(!pgtable_alloc); -+ pmd_phys = pgtable_alloc(PMD_SHIFT); -+ __iee_pud_populate_pre_init(pudp, pmd_phys, pudval); -+ pud = READ_ONCE(*pudp); -+ } -+ BUG_ON(pud_bad(pud)); -+ -+ do { -+ pgprot_t __prot = prot; -+ -+ next = pmd_cont_addr_end(addr, end); -+ -+ /* use a contiguous mapping if the range is suitably aligned */ -+ if ((((addr | next | phys) & ~CONT_PMD_MASK) == 0) && -+ (flags & NO_CONT_MAPPINGS) == 0) -+ __prot = __pgprot(pgprot_val(prot) | PTE_CONT); -+ -+ iee_init_pmd_pre_init(pudp, addr, next, phys, __prot, pgtable_alloc, flags); -+ -+ phys += next - addr; -+ } while (addr = next, addr != end); -+} -+ -+static __init void iee_alloc_init_pud_pre_init(pgd_t *pgdp, unsigned long addr, unsigned long end, -+ phys_addr_t phys, pgprot_t prot, -+ phys_addr_t (*pgtable_alloc)(int), -+ int flags) -+{ -+ unsigned long next; -+ pud_t *pudp; -+ p4d_t *p4dp = p4d_offset(pgdp, addr); -+ p4d_t p4d = READ_ONCE(*p4dp); -+ -+ if (p4d_none(p4d)) { -+ p4dval_t p4dval = P4D_TYPE_TABLE | P4D_TABLE_UXN; -+ phys_addr_t pud_phys; -+ -+ if (flags & NO_EXEC_MAPPINGS) -+ p4dval |= P4D_TABLE_PXN; -+ BUG_ON(!pgtable_alloc); -+ pud_phys = pgtable_alloc(PUD_SHIFT); -+ __iee_p4d_populate_pre_init(p4dp, pud_phys, p4dval); -+ p4d = READ_ONCE(*p4dp); -+ } -+ BUG_ON(p4d_bad(p4d)); -+ -+ pudp = pud_set_fixmap_offset_init(p4dp, addr); -+ do { -+ pud_t old_pud = READ_ONCE(*pudp); -+ -+ next = pud_addr_end(addr, end); -+ -+ /* -+ * For 4K granule only, attempt to put down a 1GB block -+ */ -+ if (pud_sect_supported() && -+ ((addr | next | phys) & ~PUD_MASK) == 0 && -+ (flags & NO_BLOCK_MAPPINGS) == 0) { -+ iee_pud_set_huge_pre_init(pudp, phys, prot); -+ -+ /* -+ * After the PUD entry has been populated once, we -+ * only allow updates to the permission attributes. -+ */ -+ BUG_ON(!pgattr_change_is_safe(pud_val(old_pud), -+ READ_ONCE(pud_val(*pudp)))); -+ } else { -+ iee_alloc_init_cont_pmd_pre_init(pudp, addr, next, phys, prot, -+ pgtable_alloc, flags); -+ -+ BUG_ON(pud_val(old_pud) != 0 && -+ pud_val(old_pud) != READ_ONCE(pud_val(*pudp))); -+ } -+ phys += next - addr; -+ } while (pudp++, addr = next, addr != end); -+ -+ pud_clear_fixmap_init(); -+} -+ -+static __init void __iee_create_pgd_mapping_locked_pre_init(pgd_t *pgdir, phys_addr_t phys, -+ unsigned long virt, phys_addr_t size, -+ pgprot_t prot, -+ phys_addr_t (*pgtable_alloc)(int), -+ int flags) -+{ -+ unsigned long addr, end, next; -+ pgd_t *pgdp = pgd_offset_pgd(pgdir, virt); -+ p4d_t *p4dp; -+ p4d_t p4d; -+ -+ /* -+ * If the virtual and physical address don't have the same offset -+ * within a page, we cannot map the region as the caller expects. -+ */ -+ if (WARN_ON((phys ^ virt) & ~PAGE_MASK)) -+ return; -+ -+ phys &= PAGE_MASK; -+ addr = virt & PAGE_MASK; -+ end = PAGE_ALIGN(virt + size); -+ -+ do { -+ next = pgd_addr_end(addr, end); -+ iee_alloc_init_pud_pre_init(pgdp, addr, next, phys, prot, pgtable_alloc, -+ flags); -+ p4dp = p4d_offset(pgdp, addr); -+ p4d = READ_ONCE(*p4dp); -+ __iee_p4d_populate_pre_init(p4dp, __p4d_to_phys(p4d), (PGD_APT | PUD_TYPE_TABLE)); -+ phys += next - addr; -+ } while (pgdp++, addr = next, addr != end); -+} -+ -+static __init void __iee_create_pgd_mapping_pre_init(pgd_t *pgdir, phys_addr_t phys, -+ unsigned long virt, phys_addr_t size, -+ pgprot_t prot, -+ phys_addr_t (*pgtable_alloc)(int), -+ int flags) -+{ -+ mutex_lock(&fixmap_lock); -+ __iee_create_pgd_mapping_locked_pre_init(pgdir, phys, virt, size, prot, -+ pgtable_alloc, flags); -+ mutex_unlock(&fixmap_lock); -+} -+#endif -+ -+static phys_addr_t __pgd_pgtable_alloc(int shift) -+{ -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr; + /* Don't allow fscrypt v1 keys to be used as v2 keys and vice versa. */ + if (payload->type != type) +diff --git a/fs/crypto/keysetup_v1.c b/fs/crypto/keysetup_v1.c +index 75dabd9b27f9..9d0cc6ef8e48 100644 +--- a/fs/crypto/keysetup_v1.c ++++ b/fs/crypto/keysetup_v1.c +@@ -109,7 +109,11 @@ find_and_lock_process_key(const char *prefix, + if (IS_ERR(key)) + return key; + ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(key)); ++ #else + down_read(&key->sem); + #endif -+ void *ptr = (void *)__get_free_page(GFP_PGTABLE_KERNEL); -+ BUG_ON(!ptr); -+ -+ #ifdef CONFIG_PTP -+ iee_addr = __phys_to_iee(__pa(ptr)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)ptr); + ukp = user_key_payload_locked(key); + + if (!ukp) /* was the key revoked before we acquired its semaphore? */ +@@ -136,7 +140,11 @@ find_and_lock_process_key(const char *prefix, + return key; + + invalid: ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); + #endif -+ -+ /* Ensure the zeroed page is visible to the page table walker */ -+ dsb(ishst); -+ return __pa(ptr); -+} -+ -+static phys_addr_t pgd_pgtable_alloc(int shift) -+{ -+ phys_addr_t pa = __pgd_pgtable_alloc(shift); -+ struct ptdesc *ptdesc = page_ptdesc(phys_to_page(pa)); -+ -+ /* -+ * Call proper page table ctor in case later we need to -+ * call core mm functions like apply_to_page_range() on -+ * this pre-allocated page table. -+ * -+ * We don't select ARCH_ENABLE_SPLIT_PMD_PTLOCK if pmd is -+ * folded, and if so pagetable_pte_ctor() becomes nop. -+ */ -+ if (shift == PAGE_SHIFT) -+ BUG_ON(!pagetable_pte_ctor(ptdesc)); -+ else if (shift == PMD_SHIFT) -+ BUG_ON(!pagetable_pmd_ctor(ptdesc)); -+ -+ return pa; -+} -+ -+/* -+ * This function can only be used to modify existing table entries, -+ * without allocating new levels of table. Note that this permits the -+ * creation of new section or page entries. -+ */ -+void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt, -+ phys_addr_t size, pgprot_t prot) -+{ -+ if (virt < PAGE_OFFSET) { -+ pr_warn("BUG: not creating mapping for %pa at 0x%016lx - outside kernel range\n", -+ &phys, virt); -+ return; -+ } -+ -+ #ifdef CONFIG_PTP -+ __iee_create_pgd_mapping_pre_init(init_mm.pgd, phys, virt, size, prot, NULL, -+ NO_CONT_MAPPINGS); + key_put(key); + return ERR_PTR(-ENOKEY); + } +@@ -315,7 +323,11 @@ int fscrypt_setup_v1_file_key_via_subscribed_keyrings(struct fscrypt_info *ci) + return PTR_ERR(key); + + err = fscrypt_setup_v1_file_key(ci, payload->raw); ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); + #else -+ __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, -+ NO_CONT_MAPPINGS); + up_read(&key->sem); + #endif -+} -+ -+void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, -+ unsigned long virt, phys_addr_t size, -+ pgprot_t prot, bool page_mappings_only) -+{ -+ int flags = 0; -+ -+ BUG_ON(mm == &init_mm); -+ -+ if (page_mappings_only) -+ flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; -+ -+ __create_pgd_mapping(mm->pgd, phys, virt, size, prot, -+ pgd_pgtable_alloc, flags); -+} -+ -+static void update_mapping_prot(phys_addr_t phys, unsigned long virt, -+ phys_addr_t size, pgprot_t prot) -+{ -+ if (virt < PAGE_OFFSET) { -+ pr_warn("BUG: not updating mapping for %pa at 0x%016lx - outside kernel range\n", -+ &phys, virt); -+ return; -+ } -+ -+ __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, -+ NO_CONT_MAPPINGS); + key_put(key); + return err; + } +diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h +index f2ed0c0266cb..1a24f8dcff5c 100644 +--- a/fs/ecryptfs/ecryptfs_kernel.h ++++ b/fs/ecryptfs/ecryptfs_kernel.h +@@ -82,7 +82,11 @@ ecryptfs_get_encrypted_key_payload_data(struct key *key) + if (key->type != &key_type_encrypted) + return NULL; + ++ #ifdef CONFIG_KEYP ++ payload = ((union key_payload *)(key->name_link.next))->data[0]; ++ #else + payload = key->payload.data[0]; ++ #endif + if (!payload) + return ERR_PTR(-EKEYREVOKED); + +diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c +index 7f9f68c00ef6..a4859a7d3b5d 100644 +--- a/fs/ecryptfs/keystore.c ++++ b/fs/ecryptfs/keystore.c +@@ -512,7 +512,11 @@ ecryptfs_find_global_auth_tok_for_sig( + goto out_invalid_auth_tok; + } + ++ #ifdef CONFIG_KEYP ++ down_write(&(KEY_SEM(walker->global_auth_tok_key))); ++ #else + down_write(&(walker->global_auth_tok_key->sem)); ++ #endif + rc = ecryptfs_verify_auth_tok_from_key( + walker->global_auth_tok_key, auth_tok); + if (rc) +@@ -525,7 +529,11 @@ ecryptfs_find_global_auth_tok_for_sig( + rc = -ENOENT; + goto out; + out_invalid_auth_tok_unlock: ++ #ifdef CONFIG_KEYP ++ up_write(&(KEY_SEM(walker->global_auth_tok_key))); ++ #else + up_write(&(walker->global_auth_tok_key->sem)); ++ #endif + out_invalid_auth_tok: + printk(KERN_WARNING "Invalidating auth tok with sig = [%s]\n", sig); + walker->flags |= ECRYPTFS_AUTH_TOK_INVALID; +@@ -846,7 +854,11 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, + mutex_unlock(s->tfm_mutex); + out: + if (auth_tok_key) { ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + } + skcipher_request_free(s->skcipher_req); +@@ -1088,7 +1100,11 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, + (*filename) = NULL; + } + if (auth_tok_key) { ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + } + skcipher_request_free(s->skcipher_req); +@@ -1625,10 +1641,18 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, + goto out; + } + } ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM((*auth_tok_key))); ++ #else + down_write(&(*auth_tok_key)->sem); ++ #endif + rc = ecryptfs_verify_auth_tok_from_key(*auth_tok_key, auth_tok); + if (rc) { ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM((*auth_tok_key))); ++ #else + up_write(&(*auth_tok_key)->sem); ++ #endif + key_put(*auth_tok_key); + (*auth_tok_key) = NULL; + goto out; +@@ -1901,7 +1925,11 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, + memcpy(&(candidate_auth_tok->token.private_key), + &(matching_auth_tok->token.private_key), + sizeof(struct ecryptfs_private_key)); ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + rc = decrypt_pki_encrypted_session_key(candidate_auth_tok, + crypt_stat); +@@ -1909,12 +1937,20 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, + memcpy(&(candidate_auth_tok->token.password), + &(matching_auth_tok->token.password), + sizeof(struct ecryptfs_password)); ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + rc = decrypt_passphrase_encrypted_session_key( + candidate_auth_tok, crypt_stat); + } else { ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + rc = -EINVAL; + } +@@ -1976,7 +2012,11 @@ pki_encrypt_session_key(struct key *auth_tok_key, + crypt_stat->cipher, + crypt_stat->key_size), + crypt_stat, &payload, &payload_len); ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + if (rc) { + ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n"); +@@ -2040,7 +2080,11 @@ write_tag_1_packet(char *dest, size_t *remaining_bytes, + memcpy(key_rec->enc_key, + auth_tok->session_key.encrypted_key, + auth_tok->session_key.encrypted_key_size); ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + goto encrypted_session_key_set; + } +@@ -2438,7 +2482,11 @@ ecryptfs_generate_key_packet_set(char *dest_base, + &max, auth_tok, + crypt_stat, key_rec, + &written); ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + if (rc) { + ecryptfs_printk(KERN_WARNING, "Error " +@@ -2467,7 +2515,11 @@ ecryptfs_generate_key_packet_set(char *dest_base, + } + (*len) += written; + } else { ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + ecryptfs_printk(KERN_WARNING, "Unsupported " + "authentication token type\n"); +diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c +index 2dc927ba067f..39c6f1d1438c 100644 +--- a/fs/ecryptfs/main.c ++++ b/fs/ecryptfs/main.c +@@ -202,7 +202,11 @@ static int ecryptfs_init_global_auth_toks( + goto out; + } else { + global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID; ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(global_auth_tok->global_auth_tok_key)); ++ #else + up_write(&(global_auth_tok->global_auth_tok_key)->sem); ++ #endif + } + } + out: +diff --git a/fs/exec.c b/fs/exec.c +index a4725461a443..7691f803c9fa 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -76,6 +76,14 @@ + + #include + ++#ifdef CONFIG_CREDP ++#include ++#endif + -+ /* flush the TLBs after updating live kernel mappings */ -+ flush_tlb_kernel_range(virt, virt + size); -+} ++#ifdef CONFIG_IEE ++#include ++#endif + -+static void __init __map_memblock(pgd_t *pgdp, phys_addr_t start, -+ phys_addr_t end, pgprot_t prot, int flags) -+{ + static int bprm_creds_from_file(struct linux_binprm *bprm); + + int suid_dumpable = 0; +@@ -725,7 +733,11 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) + free_pgd_range(&tlb, old_start, old_end, new_end, + next ? next->vm_start : USER_PGTABLES_CEILING); + } + #ifdef CONFIG_PTP -+ __iee_create_pgd_mapping_pre_init(pgdp, start, __phys_to_virt(start), end - start, -+ prot, early_pgtable_alloc, flags); ++ iee_tlb_finish_mmu(&tlb); + #else -+ __create_pgd_mapping(pgdp, start, __phys_to_virt(start), end - start, -+ prot, early_pgtable_alloc, flags); + tlb_finish_mmu(&tlb); + #endif -+} -+ -+void __init mark_linear_text_alias_ro(void) -+{ -+ /* -+ * Remove the write permissions from the linear alias of .text/.rodata -+ */ -+ update_mapping_prot(__pa_symbol(_stext), (unsigned long)lm_alias(_stext), -+ (unsigned long)__init_begin - (unsigned long)_stext, -+ PAGE_KERNEL_RO); -+} -+ -+#ifdef CONFIG_KFENCE -+ -+bool __ro_after_init kfence_early_init = !!CONFIG_KFENCE_SAMPLE_INTERVAL; -+ -+/* early_param() will be parsed before map_mem() below. */ -+static int __init parse_kfence_early_init(char *arg) -+{ -+ int val; -+ -+ if (get_option(&arg, &val)) -+ kfence_early_init = !!val; -+ -+#if IS_ENABLED(CONFIG_KFENCE_MUST_EARLY_INIT) -+ kfence_must_early_init = (val == -1) ? true : false; + + vma_prev(&vmi); + /* Shrink the vma to just the new range */ +@@ -1005,6 +1017,9 @@ static int exec_mmap(struct mm_struct *mm) + if (!IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM)) + local_irq_enable(); + activate_mm(active_mm, mm); ++ #ifdef CONFIG_IEE ++ iee_set_token_pgd(tsk, mm->pgd); ++ #endif + if (IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM)) + local_irq_enable(); + lru_gen_add_mm(mm); +@@ -1624,12 +1639,20 @@ static void bprm_fill_uid(struct linux_binprm *bprm, struct file *file) + + if (mode & S_ISUID) { + bprm->per_clear |= PER_CLEAR_ON_SETID; ++ #ifdef CONFIG_CREDP ++ iee_set_cred_euid(bprm->cred, vfsuid_into_kuid(vfsuid)); ++ #else + bprm->cred->euid = vfsuid_into_kuid(vfsuid); ++ #endif + } + + if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { + bprm->per_clear |= PER_CLEAR_ON_SETID; ++ #ifdef CONFIG_CREDP ++ iee_set_cred_egid(bprm->cred, vfsgid_into_kgid(vfsgid)); ++ #else + bprm->cred->egid = vfsgid_into_kgid(vfsgid); ++ #endif + } + } + +diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c +index 3e724cb7ef01..e32e136e4271 100644 +--- a/fs/nfs/flexfilelayout/flexfilelayout.c ++++ b/fs/nfs/flexfilelayout/flexfilelayout.c +@@ -15,6 +15,10 @@ + + #include + ++#ifdef CONFIG_CREDP ++#include +#endif + -+ return 0; -+} -+early_param("kfence.sample_interval", parse_kfence_early_init); -+ -+static phys_addr_t __init arm64_kfence_alloc_pool(void) -+{ -+ phys_addr_t kfence_pool; -+ -+ if (!kfence_early_init) -+ return 0; -+ -+ kfence_pool = memblock_phys_alloc(KFENCE_POOL_SIZE, PAGE_SIZE); -+ if (!kfence_pool) { -+ pr_err("failed to allocate kfence pool\n"); -+ kfence_early_init = false; -+ return 0; -+ } -+ -+ /* Temporarily mark as NOMAP. */ -+ memblock_mark_nomap(kfence_pool, KFENCE_POOL_SIZE); -+ -+ return kfence_pool; -+} -+ -+static void __init arm64_kfence_map_pool(phys_addr_t kfence_pool, pgd_t *pgdp) -+{ -+ if (!kfence_pool) -+ return; -+ -+ /* KFENCE pool needs page-level mapping. */ -+ __map_memblock(pgdp, kfence_pool, kfence_pool + KFENCE_POOL_SIZE, -+ pgprot_tagged(PAGE_KERNEL), -+ NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS); -+ memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE); -+ __kfence_pool = phys_to_virt(kfence_pool); -+} -+#else /* CONFIG_KFENCE */ -+ -+static inline phys_addr_t arm64_kfence_alloc_pool(void) { return 0; } -+static inline void arm64_kfence_map_pool(phys_addr_t kfence_pool, pgd_t *pgdp) { } -+ -+#endif /* CONFIG_KFENCE */ -+ -+static void __init map_mem(pgd_t *pgdp) -+{ -+ static const u64 direct_map_end = _PAGE_END(VA_BITS_MIN); -+ phys_addr_t kernel_start = __pa_symbol(_stext); -+ phys_addr_t kernel_end = __pa_symbol(__init_begin); -+ phys_addr_t start, end; -+ phys_addr_t early_kfence_pool; -+ int flags = NO_EXEC_MAPPINGS; -+ u64 i; -+ -+ /* -+ * Setting hierarchical PXNTable attributes on table entries covering -+ * the linear region is only possible if it is guaranteed that no table -+ * entries at any level are being shared between the linear region and -+ * the vmalloc region. Check whether this is true for the PGD level, in -+ * which case it is guaranteed to be true for all other levels as well. -+ */ -+ BUILD_BUG_ON(pgd_index(direct_map_end - 1) == pgd_index(direct_map_end)); -+ -+ early_kfence_pool = arm64_kfence_alloc_pool(); -+ -+ if (can_set_direct_map()) -+ flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; + #include "flexfilelayout.h" + #include "../nfs4session.h" + #include "../nfs4idmap.h" +@@ -502,8 +506,13 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh, + rc = -ENOMEM; + if (!kcred) + goto out_err_free; ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(kcred,uid); ++ iee_set_cred_fsgid(kcred,gid); ++ #else + kcred->fsuid = uid; + kcred->fsgid = gid; ++ #endif + cred = RCU_INITIALIZER(kcred); + + if (lgr->range.iomode == IOMODE_READ) +diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c +index 25a7c771cfd8..c11c2e78e782 100644 +--- a/fs/nfs/nfs4idmap.c ++++ b/fs/nfs/nfs4idmap.c +@@ -48,6 +48,13 @@ + #include + #include + ++#ifdef CONFIG_CREDP ++#include ++#endif ++#ifdef CONFIG_KEYP ++#include ++#endif + -+ #ifdef CONFIG_IEE -+ flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; + #include "internal.h" + #include "netns.h" + #include "nfs4idmap.h" +@@ -225,9 +232,18 @@ int nfs_idmap_init(void) + if (ret < 0) + goto failed_reg_legacy; + ++ #ifdef CONFIG_KEYP ++ iee_set_key_flag_bit(keyring, KEY_FLAG_ROOT_CAN_CLEAR, SET_BIT_OP); ++ #else + set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); + #endif -+ /* -+ * Take care not to create a writable alias for the -+ * read-only text and rodata sections of the kernel image. -+ * So temporarily mark them as NOMAP to skip mappings in -+ * the following for-loop -+ */ -+ memblock_mark_nomap(kernel_start, kernel_end - kernel_start); -+ -+ /* map all the memory banks */ -+ for_each_mem_range(i, &start, &end) { -+ if (start >= end) -+ break; -+ /* -+ * The linear map must allow allocation tags reading/writing -+ * if MTE is present. Otherwise, it has the same attributes as -+ * PAGE_KERNEL. -+ */ -+ __map_memblock(pgdp, start, end, pgprot_tagged(PAGE_KERNEL), -+ flags); -+ } ++ #ifdef CONFIG_CREDP ++ iee_set_cred_thread_keyring(cred,keyring); ++ iee_set_cred_jit_keyring(cred,KEY_REQKEY_DEFL_THREAD_KEYRING); ++ #else + cred->thread_keyring = keyring; + cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; ++ #endif + id_resolver_cache = cred; + return 0; -- return kfence_pool; -+ /* -+ * Map the linear alias of the [_stext, __init_begin) interval -+ * as non-executable now, and remove the write permission in -+ * mark_linear_text_alias_ro() below (which will be called after -+ * alternative patching has completed). This makes the contents -+ * of the region accessible to subsystems such as hibernate, -+ * but protects it from inadvertent modification or execution. -+ * Note that contiguous mappings cannot be remapped in this way, -+ * so we should avoid them here. -+ */ -+ #ifdef CONFIG_IEE -+ __map_memblock(pgdp, kernel_start, kernel_end, -+ PAGE_KERNEL, flags); +@@ -296,7 +312,11 @@ static struct key *nfs_idmap_request_key(const char *name, size_t namelen, + mutex_unlock(&idmap->idmap_mutex); + } + if (!IS_ERR(rkey)) ++ #ifdef CONFIG_KEYP ++ iee_set_key_flag_bit(rkey, KEY_FLAG_ROOT_CAN_INVAL, SET_BIT_OP); ++ #else + set_bit(KEY_FLAG_ROOT_CAN_INVAL, &rkey->flags); ++ #endif + + kfree(desc); + return rkey; +@@ -321,7 +341,11 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen, + } + + rcu_read_lock(); ++ #ifdef CONFIG_KEYP ++ iee_set_key_perm(rkey, rkey->perm | KEY_USR_VIEW); + #else -+ __map_memblock(pgdp, kernel_start, kernel_end, -+ PAGE_KERNEL, NO_CONT_MAPPINGS); + rkey->perm |= KEY_USR_VIEW; + #endif -+ memblock_clear_nomap(kernel_start, kernel_end - kernel_start); -+ arm64_kfence_map_pool(early_kfence_pool, pgdp); -+} -+ -+void mark_rodata_ro(void) -+{ -+ unsigned long section_size; -+ -+ /* -+ * mark .rodata as read only. Use __init_begin rather than __end_rodata -+ * to cover NOTES and EXCEPTION_TABLE. -+ */ -+ section_size = (unsigned long)__init_begin - (unsigned long)__start_rodata; -+ update_mapping_prot(__pa_symbol(__start_rodata), (unsigned long)__start_rodata, -+ section_size, PAGE_KERNEL_RO); -+ -+ debug_checkwx(); -+} -+ -+static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end, -+ pgprot_t prot, struct vm_struct *vma, -+ int flags, unsigned long vm_flags) -+{ -+ phys_addr_t pa_start = __pa_symbol(va_start); -+ unsigned long size = va_end - va_start; -+ -+ BUG_ON(!PAGE_ALIGNED(pa_start)); -+ BUG_ON(!PAGE_ALIGNED(size)); -+ -+ #ifdef CONFIG_PTP -+ __iee_create_pgd_mapping_pre_init(pgdp, pa_start, (unsigned long)va_start, size, prot, -+ early_pgtable_alloc, flags); + + ret = key_validate(rkey); + if (ret < 0) +diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c +index e6beaaf4f170..e89385fd81f1 100644 +--- a/fs/nfsd/auth.c ++++ b/fs/nfsd/auth.c +@@ -2,6 +2,9 @@ + /* Copyright (C) 1995, 1996 Olaf Kirch */ + + #include ++#ifdef CONFIG_CREDP ++#include ++#endif + #include "nfsd.h" + #include "auth.h" + +@@ -32,22 +35,40 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) + if (!new) + return -ENOMEM; + ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(new,rqstp->rq_cred.cr_uid); ++ iee_set_cred_fsgid(new,rqstp->rq_cred.cr_gid); + #else -+ __create_pgd_mapping(pgdp, pa_start, (unsigned long)va_start, size, prot, -+ early_pgtable_alloc, flags); + new->fsuid = rqstp->rq_cred.cr_uid; + new->fsgid = rqstp->rq_cred.cr_gid; + #endif + + rqgi = rqstp->rq_cred.cr_group_info; + + if (flags & NFSEXP_ALLSQUASH) { ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(new,exp->ex_anon_uid); ++ iee_set_cred_fsgid(new,exp->ex_anon_gid); ++ #else + new->fsuid = exp->ex_anon_uid; + new->fsgid = exp->ex_anon_gid; ++ #endif + gi = groups_alloc(0); + if (!gi) + goto oom; + } else if (flags & NFSEXP_ROOTSQUASH) { + if (uid_eq(new->fsuid, GLOBAL_ROOT_UID)) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(new,exp->ex_anon_uid); ++ #else + new->fsuid = exp->ex_anon_uid; ++ #endif + if (gid_eq(new->fsgid, GLOBAL_ROOT_GID)) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsgid(new,exp->ex_anon_gid); ++ #else + new->fsgid = exp->ex_anon_gid; ++ #endif + + gi = groups_alloc(rqgi->ngroups); + if (!gi) +@@ -67,18 +88,35 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) + } + + if (uid_eq(new->fsuid, INVALID_UID)) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(new,exp->ex_anon_uid); ++ #else + new->fsuid = exp->ex_anon_uid; ++ #endif + if (gid_eq(new->fsgid, INVALID_GID)) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsgid(new,exp->ex_anon_gid); ++ #else + new->fsgid = exp->ex_anon_gid; ++ #endif + + set_groups(new, gi); + put_group_info(gi); + + if (!uid_eq(new->fsuid, GLOBAL_ROOT_UID)) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_cap_effective(new,cap_drop_nfsd_set(new->cap_effective)); ++ #else + new->cap_effective = cap_drop_nfsd_set(new->cap_effective); ++ #endif + else ++ #ifdef CONFIG_CREDP ++ iee_set_cred_cap_effective(new,cap_raise_nfsd_set(new->cap_effective, ++ new->cap_permitted)); ++ #else + new->cap_effective = cap_raise_nfsd_set(new->cap_effective, + new->cap_permitted); ++ #endif + put_cred(override_creds(new)); + put_cred(new); + return 0; +diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c +index 49a88dde9631..4fde340b8471 100644 +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -41,6 +41,9 @@ + #include "trace.h" + #include "xdr4cb.h" + #include "xdr4.h" ++#ifdef CONFIG_CREDP ++#include ++#endif + + #define NFSDDBG_FACILITY NFSDDBG_PROC + +@@ -946,8 +949,13 @@ static const struct cred *get_backchannel_cred(struct nfs4_client *clp, struct r + if (!kcred) + return NULL; + +- kcred->fsuid = ses->se_cb_sec.uid; +- kcred->fsgid = ses->se_cb_sec.gid; ++ #ifdef CONFIG_CREDP ++ iee_set_cred_uid(kcred,ses->se_cb_sec.uid); ++ iee_set_cred_gid(kcred,ses->se_cb_sec.gid); ++ #else ++ kcred->uid = ses->se_cb_sec.uid; ++ kcred->gid = ses->se_cb_sec.gid; ++ #endif + return kcred; + } + } +diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c +index 4395577825a7..8c34cfe01075 100644 +--- a/fs/nfsd/nfs4recover.c ++++ b/fs/nfsd/nfs4recover.c +@@ -44,6 +44,10 @@ + #include + #include + ++#ifdef CONFIG_CREDP ++#include ++#endif + -+ if (!(vm_flags & VM_NO_GUARD)) -+ size += PAGE_SIZE; -+ -+ vma->addr = va_start; -+ vma->phys_addr = pa_start; -+ vma->size = size; -+ vma->flags = VM_MAP | vm_flags; -+ vma->caller = __builtin_return_address(0); -+ -+ vm_area_add_early(vma); -+} -+ -+static pgprot_t kernel_exec_prot(void) -+{ -+ return rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC; -+} -+ -+#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 -+static int __init map_entry_trampoline(void) -+{ -+ int i; -+ -+ pgprot_t prot = kernel_exec_prot(); -+ phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start); -+ -+ /* The trampoline is always mapped and can therefore be global */ -+ pgprot_val(prot) &= ~PTE_NG; -+ -+ /* Map only the text into the trampoline page table */ -+ memset(tramp_pg_dir, 0, PGD_SIZE); -+ #ifdef CONFIG_PTP -+ iee_set_logical_mem_ro((unsigned long)tramp_pg_dir); + #include "nfsd.h" + #include "state.h" + #include "vfs.h" +@@ -78,8 +82,13 @@ nfs4_save_creds(const struct cred **original_creds) + if (!new) + return -ENOMEM; + ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(new,GLOBAL_ROOT_UID); ++ iee_set_cred_fsgid(new,GLOBAL_ROOT_GID); ++ #else + new->fsuid = GLOBAL_ROOT_UID; + new->fsgid = GLOBAL_ROOT_GID; + #endif -+ __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, -+ entry_tramp_text_size(), prot, -+ __pgd_pgtable_alloc, NO_BLOCK_MAPPINGS); -+ -+ /* Map both the text and data into the kernel page table */ -+ for (i = 0; i < DIV_ROUND_UP(entry_tramp_text_size(), PAGE_SIZE); i++) -+ __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i, -+ pa_start + i * PAGE_SIZE, prot); -+ -+ if (IS_ENABLED(CONFIG_RELOCATABLE)) -+ __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i, -+ pa_start + i * PAGE_SIZE, PAGE_KERNEL_RO); -+ -+ return 0; -+} -+core_initcall(map_entry_trampoline); + *original_creds = override_creds(new); + put_cred(new); + return 0; +diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c +index c2495d98c189..779471a0aa66 100644 +--- a/fs/nfsd/nfsfh.c ++++ b/fs/nfsd/nfsfh.c +@@ -16,6 +16,10 @@ + #include "auth.h" + #include "trace.h" + ++#ifdef CONFIG_CREDP ++#include +#endif + -+/* -+ * Open coded check for BTI, only for use to determine configuration -+ * for early mappings for before the cpufeature code has run. -+ */ -+static bool arm64_early_this_cpu_has_bti(void) -+{ -+ u64 pfr1; -+ -+ if (!IS_ENABLED(CONFIG_ARM64_BTI_KERNEL)) -+ return false; -+ -+ pfr1 = __read_sysreg_by_encoding(SYS_ID_AA64PFR1_EL1); -+ return cpuid_feature_extract_unsigned_field(pfr1, -+ ID_AA64PFR1_EL1_BT_SHIFT); -+} -+ -+#ifdef CONFIG_IEE -+/* Set PMD APTable of iee si codes as (1,1) to revert it to ROX P pages when HPD1=0. */ -+static void __init iee_si_set_pmd_APtable(unsigned long addr, pgd_t *pgdir) -+{ -+ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); -+ -+ p4d_t *p4dp = p4d_offset(pgdp, addr); -+ -+ #ifdef CONFIG_PTP -+ pud_t *pudp = pud_set_fixmap_offset_init(p4dp, addr); -+ -+ pmd_t *pmdp = pmd_set_fixmap_offset_init(pudp, addr); -+ -+ pmd_t pmd = READ_ONCE(*pmdp); -+ -+ __iee_pmd_populate_pre_init(pmdp, __pmd_to_phys(pmd), PGD_APT_RO | PGD_APT | PMD_TYPE_TABLE); -+ -+ pud_clear_fixmap_init(); -+ pmd_clear_fixmap_init(); -+ #else -+ pud_t *pudp = pud_set_fixmap_offset(p4dp, addr); -+ -+ pmd_t *pmdp = pmd_set_fixmap_offset(pudp, addr); -+ -+ pmd_t pmd = READ_ONCE(*pmdp); -+ -+ __pmd_populate(pmdp, __pmd_to_phys(pmd), PGD_APT_RO | PGD_APT | PMD_TYPE_TABLE); -+ -+ pud_clear_fixmap(); -+ pmd_clear_fixmap(); -+ #endif -+} -+/* Set PMD APTable of iee si codes as (1,1) to revert it to ROX P pages when HPD1=0. */ -+static void __init mark_iee_si_pmd_APtable(pgd_t *pgdir) -+{ -+ unsigned long addr = (unsigned long)__iee_si_start; -+ iee_si_set_pmd_APtable(addr, pgdir); -+ // iee rwx gate exit may be mapped by another pmd. -+ iee_si_set_pmd_APtable(addr + PAGE_SIZE, pgdir); -+} + #define NFSDDBG_FACILITY NFSDDBG_FH + + +@@ -223,9 +227,14 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) + error = nfserrno(-ENOMEM); + goto out; + } ++ #ifdef CONFIG_CREDP ++ iee_set_cred_cap_effective(new,cap_raise_nfsd_set(new->cap_effective, ++ new->cap_permitted)); ++ #else + new->cap_effective = + cap_raise_nfsd_set(new->cap_effective, + new->cap_permitted); ++ #endif + put_cred(override_creds(new)); + put_cred(new); + } else { +diff --git a/fs/open.c b/fs/open.c +index 59db720693f9..dbbca8701fd1 100644 +--- a/fs/open.c ++++ b/fs/open.c +@@ -35,6 +35,11 @@ + #include + #include + ++#ifdef CONFIG_CREDP ++#include +#endif + -+/* -+ * Create fine-grained mappings for the kernel. -+ */ -+static void __init map_kernel(pgd_t *pgdp) -+{ -+ static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_inittext, -+ vmlinux_initdata, vmlinux_data; -+ -+ #ifdef CONFIG_IEE -+ static struct vm_struct vmlinux_iee_code, vmlinux_iee_data, vmlinux_iee_gate, vmlinux_text_end; -+ #endif -+ -+ /* -+ * External debuggers may need to write directly to the text -+ * mapping to install SW breakpoints. Allow this (only) when -+ * explicitly requested with rodata=off. -+ */ -+ pgprot_t text_prot = kernel_exec_prot(); -+ -+ /* -+ * If we have a CPU that supports BTI and a kernel built for -+ * BTI then mark the kernel executable text as guarded pages -+ * now so we don't have to rewrite the page tables later. -+ */ -+ if (arm64_early_this_cpu_has_bti()) -+ text_prot = __pgprot_modify(text_prot, PTE_GP, PTE_GP); + -+ /* -+ * Only rodata will be remapped with different permissions later on, -+ * all other segments are allowed to use contiguous mappings. -+ */ -+ #ifdef CONFIG_IEE -+ map_kernel_segment(pgdp, _stext, __iee_si_data_start, text_prot, &vmlinux_text, -+ 0, VM_NO_GUARD); -+ /* Set iee si data RW. */ -+ map_kernel_segment(pgdp, __iee_si_data_start, __iee_exec_entry_start, SET_NG(PAGE_KERNEL), -+ &vmlinux_iee_data, NO_CONT_MAPPINGS | NO_BLOCK_MAPPINGS, VM_NO_GUARD); -+ /* Set iee entry codes NG. */ -+ map_kernel_segment(pgdp, __iee_exec_entry_start, __iee_si_start, SET_NG(text_prot), &vmlinux_iee_gate, -+ NO_CONT_MAPPINGS | NO_BLOCK_MAPPINGS, VM_NO_GUARD); -+ /* Map __iee_si_start - __iee_si_end as U RWX pages and set PMD APTABLE = (1,1). */ -+ map_kernel_segment(pgdp, __iee_si_start, __iee_si_end, SET_NG((PAGE_KERNEL_EXEC)), -+ &vmlinux_iee_code, NO_CONT_MAPPINGS | NO_BLOCK_MAPPINGS, VM_NO_GUARD); -+ mark_iee_si_pmd_APtable(pgdp); -+ -+ map_kernel_segment(pgdp, __iee_si_end, _etext, text_prot, &vmlinux_text_end, 0, -+ VM_NO_GUARD); -+ -+ map_kernel_segment(pgdp, __start_rodata, __inittext_begin, PAGE_KERNEL, -+ &vmlinux_rodata, NO_CONT_MAPPINGS | NO_BLOCK_MAPPINGS, VM_NO_GUARD); -+ map_kernel_segment(pgdp, __inittext_begin, __inittext_end, text_prot, -+ &vmlinux_inittext, 0, VM_NO_GUARD); -+ map_kernel_segment(pgdp, __initdata_begin, __initdata_end, PAGE_KERNEL, -+ &vmlinux_initdata, 0, VM_NO_GUARD); -+ map_kernel_segment(pgdp, _data, _end, PAGE_KERNEL, &vmlinux_data, NO_CONT_MAPPINGS | NO_BLOCK_MAPPINGS, 0); + #include "internal.h" + + int do_truncate(struct mnt_idmap *idmap, struct dentry *dentry, +@@ -414,17 +419,34 @@ static const struct cred *access_override_creds(void) + * routine. + */ + ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(override_cred,override_cred->uid); ++ iee_set_cred_fsgid(override_cred,override_cred->gid); + #else -+ map_kernel_segment(pgdp, _stext, _etext, text_prot, &vmlinux_text, 0, -+ VM_NO_GUARD); -+ map_kernel_segment(pgdp, __start_rodata, __inittext_begin, PAGE_KERNEL, -+ &vmlinux_rodata, NO_CONT_MAPPINGS, VM_NO_GUARD); -+ map_kernel_segment(pgdp, __inittext_begin, __inittext_end, text_prot, -+ &vmlinux_inittext, 0, VM_NO_GUARD); -+ map_kernel_segment(pgdp, __initdata_begin, __initdata_end, PAGE_KERNEL, -+ &vmlinux_initdata, 0, VM_NO_GUARD); -+ map_kernel_segment(pgdp, _data, _end, PAGE_KERNEL, &vmlinux_data, 0, 0); + override_cred->fsuid = override_cred->uid; + override_cred->fsgid = override_cred->gid; + #endif + + if (!issecure(SECURE_NO_SETUID_FIXUP)) { + /* Clear the capabilities if we switch to a non-root user */ + kuid_t root_uid = make_kuid(override_cred->user_ns, 0); + if (!uid_eq(override_cred->uid, root_uid)) ++ #ifdef CONFIG_CREDP ++ do { ++ kernel_cap_t tmp_cap = override_cred->cap_effective; ++ tmp_cap.val = 0; ++ iee_set_cred_cap_effective(override_cred, tmp_cap); ++ } while (0); ++ #else + cap_clear(override_cred->cap_effective); ++ #endif + else ++ #ifdef CONFIG_CREDP ++ iee_set_cred_cap_effective(override_cred,override_cred->cap_permitted); ++ #else + override_cred->cap_effective = + override_cred->cap_permitted; ++ #endif + } + + /* +@@ -444,7 +466,11 @@ static const struct cred *access_override_creds(void) + * expecting RCU freeing. But normal thread-synchronous + * cred accesses will keep things non-RCY. + */ ++ #ifdef CONFIG_CREDP ++ iee_set_cred_non_rcu(override_cred,1); ++ #else + override_cred->non_rcu = 1; ++ #endif + + old_cred = override_creds(override_cred); + +diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c +index 54602f0bed8b..58534612dc64 100644 +--- a/fs/overlayfs/dir.c ++++ b/fs/overlayfs/dir.c +@@ -16,6 +16,10 @@ + #include + #include "overlayfs.h" + ++#ifdef CONFIG_CREDP ++#include ++#endif + -+ -+ fixmap_copy(pgdp); -+ kasan_copy_shadow(pgdp); -+} -+ -+static void __init create_idmap(void) -+{ -+ u64 start = __pa_symbol(__idmap_text_start); -+ u64 size = __pa_symbol(__idmap_text_end) - start; -+ pgd_t *pgd = idmap_pg_dir; -+ u64 pgd_phys; -+ -+ /* check if we need an additional level of translation */ -+ if (VA_BITS < 48 && idmap_t0sz < (64 - VA_BITS_MIN)) { -+ pgd_phys = early_pgtable_alloc(PAGE_SHIFT); -+ set_pgd(&idmap_pg_dir[start >> VA_BITS], -+ __pgd(pgd_phys | P4D_TYPE_TABLE)); -+ pgd = __va(pgd_phys); + static unsigned short ovl_redirect_max = 256; + module_param_named(redirect_max, ovl_redirect_max, ushort, 0644); + MODULE_PARM_DESC(redirect_max, +@@ -590,8 +594,13 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode, + * create a new inode, so just use the ovl mounter's + * fs{u,g}id. + */ ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(override_cred,inode->i_uid); ++ iee_set_cred_fsgid(override_cred,inode->i_gid); ++ #else + override_cred->fsuid = inode->i_uid; + override_cred->fsgid = inode->i_gid; ++ #endif + err = security_dentry_create_files_as(dentry, + attr->mode, &dentry->d_name, old_cred, + override_cred); +diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c +index 2c056d737c27..9ede99ddb04b 100644 +--- a/fs/overlayfs/super.c ++++ b/fs/overlayfs/super.c +@@ -21,6 +21,10 @@ + #include "overlayfs.h" + #include "params.h" + ++#ifdef CONFIG_CREDP ++#include ++#endif ++ + MODULE_AUTHOR("Miklos Szeredi "); + MODULE_DESCRIPTION("Overlay filesystem"); + MODULE_LICENSE("GPL"); +@@ -1485,7 +1489,15 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc) + sb->s_export_op = &ovl_export_fid_operations; + + /* Never override disk quota limits or use reserved space */ ++ #ifdef CONFIG_CREDP ++ { ++ kernel_cap_t tmp = cred->cap_effective; ++ cap_lower(tmp, CAP_SYS_RESOURCE); ++ iee_set_cred_cap_effective(cred, tmp); + } -+ #ifdef CONFIG_PTP -+ __iee_create_pgd_mapping_pre_init(pgd, start, start, size, PAGE_KERNEL_ROX, -+ early_pgtable_alloc, 0); + #else -+ __create_pgd_mapping(pgd, start, start, size, PAGE_KERNEL_ROX, -+ early_pgtable_alloc, 0); + cap_lower(cred->cap_effective, CAP_SYS_RESOURCE); + #endif + + sb->s_magic = OVERLAYFS_SUPER_MAGIC; + sb->s_xattr = ofs->config.userxattr ? ovl_user_xattr_handlers : +diff --git a/fs/smb/client/cifs_spnego.c b/fs/smb/client/cifs_spnego.c +index af7849e5974f..d913a255265f 100644 +--- a/fs/smb/client/cifs_spnego.c ++++ b/fs/smb/client/cifs_spnego.c +@@ -18,6 +18,13 @@ + #include "cifs_spnego.h" + #include "cifs_debug.h" + #include "cifsproto.h" ++#ifdef CONFIG_CREDP ++#include ++#endif ++#ifdef CONFIG_KEYP ++#include ++#endif + -+ if (IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0)) { -+ extern u32 __idmap_kpti_flag; -+ u64 pa = __pa_symbol(&__idmap_kpti_flag); + static const struct cred *spnego_cred; + + /* create a new cifs key */ +@@ -33,7 +40,13 @@ cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep) + goto error; + + /* attach the data */ ++ #ifdef CONFIG_KEYP ++ union key_payload key_payload = *((union key_payload *)(key->name_link.next)); ++ key_payload.data[0] = payload; ++ iee_write_key_payload(key, key_payload); ++ #else + key->payload.data[0] = payload; ++ #endif + ret = 0; + + error: +@@ -43,7 +56,11 @@ cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep) + static void + cifs_spnego_key_destroy(struct key *key) + { ++ #ifdef CONFIG_KEYP ++ kfree(((union key_payload *)(key->name_link.next))->data[0]); ++ #else + kfree(key->payload.data[0]); ++ #endif + } + + +@@ -163,7 +180,11 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo, + + #ifdef CONFIG_CIFS_DEBUG2 + if (cifsFYI && !IS_ERR(spnego_key)) { ++ #ifdef CONFIG_KEYP ++ struct cifs_spnego_msg *msg = ((union key_payload *)(spnego_key->name_link.next))->data[0]; ++ #else + struct cifs_spnego_msg *msg = spnego_key->payload.data[0]; ++ #endif + cifs_dump_mem("SPNEGO reply blob:", msg->data, min(1024U, + msg->secblob_len + msg->sesskey_len)); + } +@@ -211,9 +232,18 @@ init_cifs_spnego(void) + * instruct request_key() to use this special keyring as a cache for + * the results it looks up + */ ++ #ifdef CONFIG_KEYP ++ iee_set_key_flag_bit(keyring, KEY_FLAG_ROOT_CAN_CLEAR, SET_BIT_OP); ++ #else + set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); ++ #endif ++ #ifdef CONFIG_CREDP ++ iee_set_cred_thread_keyring(cred,keyring); ++ iee_set_cred_jit_keyring(cred,KEY_REQKEY_DEFL_THREAD_KEYRING); ++ #else + cred->thread_keyring = keyring; + cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; ++ #endif + spnego_cred = cred; + + cifs_dbg(FYI, "cifs spnego keyring: %d\n", key_serial(keyring)); +diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c +index f5b6df82e857..7684cf4639e1 100644 +--- a/fs/smb/client/cifsacl.c ++++ b/fs/smb/client/cifsacl.c +@@ -26,6 +26,14 @@ + #include "cifs_fs_sb.h" + #include "cifs_unicode.h" + ++#ifdef CONFIG_CREDP ++#include ++#endif ++#ifdef CONFIG_KEYP ++#include ++#include ++#endif + -+ /* -+ * The KPTI G-to-nG conversion code needs a read-write mapping -+ * of its synchronization flag in the ID map. -+ */ -+ #ifdef CONFIG_PTP -+ __iee_create_pgd_mapping_pre_init(pgd, pa, pa, sizeof(u32), PAGE_KERNEL, -+ early_pgtable_alloc, 0); + /* security id for everyone/world system group */ + static const struct cifs_sid sid_everyone = { + 1, 1, {0, 0, 0, 0, 0, 1}, {0} }; +@@ -78,16 +86,33 @@ cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep) + * dereference payload.data! + */ + if (prep->datalen <= sizeof(key->payload)) { ++ #ifdef CONFIG_KEYP ++ union key_payload key_payload = *((union key_payload *)(key->name_link.next)); ++ key_payload.data[0] = NULL; ++ iee_write_key_payload(key, key_payload); ++ iee_memcpy(((union key_payload *)(key->name_link.next)), prep->data, prep->datalen); + #else -+ __create_pgd_mapping(pgd, pa, pa, sizeof(u32), PAGE_KERNEL, -+ early_pgtable_alloc, 0); + key->payload.data[0] = NULL; + memcpy(&key->payload, prep->data, prep->datalen); + #endif -+ } -+} + } else { + payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL); + if (!payload) + return -ENOMEM; ++ #ifdef CONFIG_KEYP ++ union key_payload key_payload = *((union key_payload *)(key->name_link.next)); ++ key_payload.data[0] = payload; ++ iee_write_key_payload(key, key_payload); ++ #else + key->payload.data[0] = payload; ++ #endif + } + ++ #ifdef CONFIG_KEYP ++ iee_set_key_datalen(key, prep->datalen); ++ #else + key->datalen = prep->datalen; ++ #endif + return 0; + } + +@@ -95,7 +120,11 @@ static inline void + cifs_idmap_key_destroy(struct key *key) + { + if (key->datalen > sizeof(key->payload)) ++ #ifdef CONFIG_KEYP ++ kfree(((union key_payload *)(key->name_link.next))->data[0]); ++ #else + kfree(key->payload.data[0]); ++ #endif + } + + static struct key_type cifs_idmap_key_type = { +@@ -311,9 +340,15 @@ id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid) + * there are no subauthorities and the host has 8-byte pointers, then + * it could be. + */ ++ #ifdef CONFIG_KEYP ++ ksid = sidkey->datalen <= sizeof(sidkey->payload) ? ++ (struct cifs_sid *)(sidkey->name_link.next) : ++ (struct cifs_sid *)((union key_payload *)(sidkey->name_link.next))->data[0]; ++ #else + ksid = sidkey->datalen <= sizeof(sidkey->payload) ? + (struct cifs_sid *)&sidkey->payload : + (struct cifs_sid *)sidkey->payload.data[0]; ++ #endif + + ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32)); + if (ksid_size > sidkey->datalen) { +@@ -422,14 +457,22 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, + if (sidtype == SIDOWNER) { + kuid_t uid; + uid_t id; ++ #ifdef CONFIG_KEYP ++ memcpy(&id, &((union key_payload *)(sidkey->name_link.next))->data[0], sizeof(uid_t)); ++ #else + memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t)); ++ #endif + uid = make_kuid(&init_user_ns, id); + if (uid_valid(uid)) + fuid = uid; + } else { + kgid_t gid; + gid_t id; ++ #ifdef CONFIG_KEYP ++ memcpy(&id, &((union key_payload *)(sidkey->name_link.next))->data[0], sizeof(gid_t)); ++ #else + memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t)); ++ #endif + gid = make_kgid(&init_user_ns, id); + if (gid_valid(gid)) + fgid = gid; +@@ -490,9 +533,18 @@ init_cifs_idmap(void) + + /* instruct request_key() to use this special keyring as a cache for + * the results it looks up */ ++ #ifdef CONFIG_KEYP ++ iee_set_key_flag_bit(keyring, KEY_FLAG_ROOT_CAN_CLEAR, SET_BIT_OP); ++ #else + set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); ++ #endif ++ #ifdef CONFIG_CREDP ++ iee_set_cred_thread_keyring(cred,keyring); ++ iee_set_cred_jit_keyring(cred,KEY_REQKEY_DEFL_THREAD_KEYRING); ++ #else + cred->thread_keyring = keyring; + cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; ++ #endif + root_cred = cred; + + cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring)); +diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c +index e325e06357ff..e43723e8cd0f 100644 +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -2150,7 +2150,11 @@ cifs_set_cifscreds(struct smb3_fs_context *ctx, struct cifs_ses *ses) + is_domain = 1; + } + ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(key)); ++ #else + down_read(&key->sem); ++ #endif + upayload = user_key_payload_locked(key); + if (IS_ERR_OR_NULL(upayload)) { + rc = upayload ? PTR_ERR(upayload) : -EINVAL; +@@ -2228,7 +2232,11 @@ cifs_set_cifscreds(struct smb3_fs_context *ctx, struct cifs_ses *ses) + strscpy(ctx->workstation_name, ses->workstation_name, sizeof(ctx->workstation_name)); + + out_key_put: ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + out_err: + kfree(desc); +diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c +index 3216f786908f..3160e70b820f 100644 +--- a/fs/smb/client/sess.c ++++ b/fs/smb/client/sess.c +@@ -1591,7 +1591,11 @@ sess_auth_kerberos(struct sess_data *sess_data) + goto out; + } + ++ #ifdef CONFIG_KEYP ++ msg = ((union key_payload *)(spnego_key->name_link.next))->data[0]; ++ #else + msg = spnego_key->payload.data[0]; ++ #endif + /* + * check version field to make sure that cifs.upcall is + * sending us a response in an expected form +diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c +index 83a03201bb86..4d090ca58257 100644 +--- a/fs/smb/client/smb2pdu.c ++++ b/fs/smb/client/smb2pdu.c +@@ -1629,7 +1629,11 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data) + goto out; + } + ++ #ifdef CONFIG_KEYP ++ msg = ((union key_payload *)(spnego_key->name_link.next))->data[0]; ++ #else + msg = spnego_key->payload.data[0]; ++ #endif + /* + * check version field to make sure that cifs.upcall is + * sending us a response in an expected form +diff --git a/fs/ubifs/auth.c b/fs/ubifs/auth.c +index e564d5ff8781..2d3ca5951fa2 100644 +--- a/fs/ubifs/auth.c ++++ b/fs/ubifs/auth.c +@@ -284,7 +284,11 @@ int ubifs_init_authentication(struct ubifs_info *c) + return PTR_ERR(keyring_key); + } + ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(keyring_key)); ++ #else + down_read(&keyring_key->sem); ++ #endif + + if (keyring_key->type != &key_type_logon) { + ubifs_err(c, "key type must be logon"); +@@ -351,7 +355,11 @@ int ubifs_init_authentication(struct ubifs_info *c) + if (err) + crypto_free_shash(c->hash_tfm); + out: ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(keyring_key)); ++ #else + up_read(&keyring_key->sem); ++ #endif + key_put(keyring_key); + + return err; +diff --git a/fs/verity/signature.c b/fs/verity/signature.c +index 90c07573dd77..e076cb6fbc84 100644 +--- a/fs/verity/signature.c ++++ b/fs/verity/signature.c +@@ -62,7 +62,11 @@ int fsverity_verify_signature(const struct fsverity_info *vi, + return 0; + } + ++ #ifdef CONFIG_KEYP ++ if (((struct key_struct *)(fsverity_keyring->name_link.prev))->keys.nr_leaves_on_tree == 0) { ++ #else + if (fsverity_keyring->keys.nr_leaves_on_tree == 0) { ++ #endif + /* + * The ".fs-verity" keyring is empty, due to builtin signatures + * being supported by the kernel but not actually being used. +diff --git a/include/asm-generic/early_ioremap.h b/include/asm-generic/early_ioremap.h +index 9d0479f50f97..f501e0f965f8 100644 +--- a/include/asm-generic/early_ioremap.h ++++ b/include/asm-generic/early_ioremap.h +@@ -17,6 +17,9 @@ extern void *early_memremap_ro(resource_size_t phys_addr, + extern void *early_memremap_prot(resource_size_t phys_addr, + unsigned long size, unsigned long prot_val); + extern void early_iounmap(void __iomem *addr, unsigned long size); ++#ifdef CONFIG_PTP ++extern void early_iounmap_after_init(void __iomem *addr, unsigned long size); ++#endif + extern void early_memunmap(void *addr, unsigned long size); + + #if defined(CONFIG_GENERIC_EARLY_IOREMAP) && defined(CONFIG_MMU) +diff --git a/include/asm-generic/fixmap.h b/include/asm-generic/fixmap.h +index 8cc7b09c1bc7..83158589a545 100644 +--- a/include/asm-generic/fixmap.h ++++ b/include/asm-generic/fixmap.h +@@ -70,6 +70,24 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr) + __set_fixmap(idx, 0, FIXMAP_PAGE_CLEAR) + #endif + ++#ifdef CONFIG_PTP ++#ifndef clear_fixmap_init ++#define clear_fixmap_init(idx) \ ++ __iee_set_fixmap_pre_init(idx, 0, FIXMAP_PAGE_CLEAR) ++#endif + -+#ifdef CONFIG_IEE -+static void __create_pgd_mapping_for_iee_locked(pgd_t *pgdir, phys_addr_t phys, -+ unsigned long virt, phys_addr_t size, -+ pgprot_t prot, -+ phys_addr_t (*pgtable_alloc)(int), -+ int flags) -+{ -+ unsigned long addr, end, next; -+ pgd_t *pgdp = pgd_offset_pgd(pgdir, virt); -+ p4d_t *p4dp; -+ p4d_t p4d; ++#define __iee_set_fixmap_offset_pre_init(idx, phys, flags) \ ++({ \ ++ unsigned long ________addr; \ ++ __iee_set_fixmap_pre_init(idx, phys, flags); \ ++ ________addr = fix_to_virt(idx) + ((phys) & (PAGE_SIZE - 1)); \ ++ ________addr; \ ++}) + -+ /* -+ * If the virtual and physical address don't have the same offset -+ * within a page, we cannot map the region as the caller expects. -+ */ -+ if (WARN_ON((phys ^ virt) & ~PAGE_MASK)) -+ return; ++#define iee_set_fixmap_offset_pre_init(idx, phys) \ ++ __iee_set_fixmap_offset_pre_init(idx, phys, FIXMAP_PAGE_NORMAL) ++#endif + -+ phys &= PAGE_MASK; -+ addr = virt & PAGE_MASK; -+ end = PAGE_ALIGN(virt + size); + /* Return a pointer with offset calculated */ + #define __set_fixmap_offset(idx, phys, flags) \ + ({ \ +diff --git a/include/asm-generic/pgalloc.h b/include/asm-generic/pgalloc.h +index c75d4a753849..1d86942b242c 100644 +--- a/include/asm-generic/pgalloc.h ++++ b/include/asm-generic/pgalloc.h +@@ -7,6 +7,10 @@ + #define GFP_PGTABLE_KERNEL (GFP_KERNEL | __GFP_ZERO) + #define GFP_PGTABLE_USER (GFP_PGTABLE_KERNEL | __GFP_ACCOUNT) + ++#ifdef CONFIG_PTP ++#include ++#endif + -+ do { -+ next = pgd_addr_end(addr, end); -+ #ifdef CONFIG_PTP -+ iee_alloc_init_pud_pre_init(pgdp, addr, next, phys, prot, pgtable_alloc, -+ flags); -+ #else -+ alloc_init_pud(pgdp, addr, next, phys, prot, pgtable_alloc, -+ flags); -+ #endif -+ p4dp = p4d_offset(pgdp, addr); -+ p4d = READ_ONCE(*p4dp); -+ #ifdef CONFIG_PTP -+ __iee_p4d_populate_pre_init(p4dp, __p4d_to_phys(p4d), (PGD_APT | PGD_PXN | PGD_UXN | PUD_TYPE_TABLE)); -+ #else -+ __p4d_populate(p4dp, __p4d_to_phys(p4d), (PGD_APT | PGD_PXN | PGD_UXN | PUD_TYPE_TABLE)); -+ #endif -+ phys += next - addr; -+ } while (pgdp++, addr = next, addr != end); -+} + /** + * __pte_alloc_one_kernel - allocate memory for a PTE-level kernel page table + * @mm: the mm_struct of the current context +@@ -23,6 +27,7 @@ static inline pte_t *__pte_alloc_one_kernel(struct mm_struct *mm) + + if (!ptdesc) + return NULL; + -+static void __create_pgd_mapping_for_iee(pgd_t *pgdir, phys_addr_t phys, -+ unsigned long virt, phys_addr_t size, -+ pgprot_t prot, -+ phys_addr_t (*pgtable_alloc)(int), -+ int flags) -+{ -+ mutex_lock(&fixmap_lock); -+ __create_pgd_mapping_for_iee_locked(pgdir, phys, virt, size, prot, -+ pgtable_alloc, flags); -+ mutex_unlock(&fixmap_lock); + return ptdesc_address(ptdesc); } --static void __init arm64_kfence_map_pool(phys_addr_t kfence_pool, pgd_t *pgdp) -+static void __init __map_memblock_for_iee(pgd_t *pgdp, phys_addr_t start, -+ phys_addr_t end, pgprot_t prot, int flags) - { -- if (!kfence_pool) -- return; -- -- /* KFENCE pool needs page-level mapping. */ -- __map_memblock(pgdp, kfence_pool, kfence_pool + KFENCE_POOL_SIZE, -- pgprot_tagged(PAGE_KERNEL), -- NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS); -- memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE); -- __kfence_pool = phys_to_virt(kfence_pool); -+ #ifdef CONFIG_PTP -+ __create_pgd_mapping_for_iee(pgdp, start, __phys_to_iee(start), end - start, -+ prot, early_pgtable_alloc, flags); -+ #else -+ __create_pgd_mapping_for_iee(pgdp, start, __phys_to_iee(start), end - start, -+ prot, early_pgtable_alloc, flags); -+ #endif +@@ -106,6 +111,7 @@ static inline void pte_free(struct mm_struct *mm, struct page *pte_page) + struct ptdesc *ptdesc = page_ptdesc(pte_page); + + pagetable_pte_dtor(ptdesc); ++ + pagetable_free(ptdesc); } --#else /* CONFIG_KFENCE */ --static inline phys_addr_t arm64_kfence_alloc_pool(void) { return 0; } --static inline void arm64_kfence_map_pool(phys_addr_t kfence_pool, pgd_t *pgdp) { } -- --#endif /* CONFIG_KFENCE */ -- --static void __init map_mem(pgd_t *pgdp) -+static void __init map_iee(pgd_t *pgdp) - { - static const u64 direct_map_end = _PAGE_END(VA_BITS_MIN); - phys_addr_t kernel_start = __pa_symbol(_stext); -@@ -578,6 +1578,8 @@ static void __init map_mem(pgd_t *pgdp) - int flags = NO_EXEC_MAPPINGS; - u64 i; +@@ -149,6 +155,7 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) -+ flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; + BUG_ON((unsigned long)pmd & (PAGE_SIZE-1)); + pagetable_pmd_dtor(ptdesc); + - /* - * Setting hierarchical PXNTable attributes on table entries covering - * the linear region is only possible if it is guaranteed that no table -@@ -589,9 +1591,6 @@ static void __init map_mem(pgd_t *pgdp) - - early_kfence_pool = arm64_kfence_alloc_pool(); + pagetable_free(ptdesc); + } + #endif +diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h +index 22384baee10e..9a6de5467a1c 100644 +--- a/include/asm-generic/tlb.h ++++ b/include/asm-generic/tlb.h +@@ -209,6 +209,9 @@ struct mmu_table_batch { + ((PAGE_SIZE - sizeof(struct mmu_table_batch)) / sizeof(void *)) + + extern void tlb_remove_table(struct mmu_gather *tlb, void *table); ++#ifdef CONFIG_PTP ++extern void iee_tlb_remove_table(struct mmu_gather *tlb, void *table); ++#endif -- if (can_set_direct_map()) -- flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; -- - /* - * Take care not to create a writable alias for the - * read-only text and rodata sections of the kernel image. -@@ -609,12 +1608,11 @@ static void __init map_mem(pgd_t *pgdp) - * if MTE is present. Otherwise, it has the same attributes as - * PAGE_KERNEL. - */ -- __map_memblock(pgdp, start, end, pgprot_tagged(PAGE_KERNEL), -- flags); -+ __map_memblock_for_iee(pgdp, start, end, SET_NG(SET_INVALID(SET_UPAGE(PAGE_KERNEL))), flags); - } + #else /* !CONFIG_MMU_GATHER_HAVE_TABLE_FREE */ - /* -- * Map the linear alias of the [_stext, __init_begin) interval -+ * Map the linear alias of the [_text, __init_begin) interval - * as non-executable now, and remove the write permission in - * mark_linear_text_alias_ro() below (which will be called after - * alternative patching has completed). This makes the contents -@@ -623,178 +1621,384 @@ static void __init map_mem(pgd_t *pgdp) - * Note that contiguous mappings cannot be remapped in this way, - * so we should avoid them here. - */ -- __map_memblock(pgdp, kernel_start, kernel_end, -- PAGE_KERNEL, NO_CONT_MAPPINGS); -+ __map_memblock_for_iee(pgdp, kernel_start, kernel_end, -+ SET_NG(SET_INVALID(SET_UPAGE(PAGE_KERNEL))), flags); - memblock_clear_nomap(kernel_start, kernel_end - kernel_start); - arm64_kfence_map_pool(early_kfence_pool, pgdp); - } +@@ -493,7 +496,11 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) --void mark_rodata_ro(void) -+/* -+ * Change page access permission, whereas not handling huge pages. -+ * Only used on IEE init functions. -+ */ -+static void __init iee_si_set_page_attr(unsigned long addr, pteval_t attr) + static inline void tlb_remove_ptdesc(struct mmu_gather *tlb, void *pt) { -- unsigned long section_size; -+ unsigned long flag; -+ pgd_t *pgdir = swapper_pg_dir; -+ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ #ifdef CONFIG_PTP ++ iee_tlb_remove_table(tlb, pt); ++ #else + tlb_remove_table(tlb, pt); ++ #endif + } -- /* -- * mark .rodata as read only. Use __init_begin rather than __end_rodata -- * to cover NOTES and EXCEPTION_TABLE. -- */ -- section_size = (unsigned long)__init_begin - (unsigned long)__start_rodata; -- update_mapping_prot(__pa_symbol(__start_rodata), (unsigned long)__start_rodata, -- section_size, PAGE_KERNEL_RO); -+ p4d_t *p4dp = p4d_offset(pgdp, addr); + /* Like tlb_remove_ptdesc, but for page-like page directories. */ +diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h +index 174d865ce46e..0d945cdd78e0 100644 +--- a/include/asm-generic/vmlinux.lds.h ++++ b/include/asm-generic/vmlinux.lds.h +@@ -379,6 +379,17 @@ + KEEP(*(.dtb.init.rodata)) \ + __dtb_end = .; -- debug_checkwx(); -+ pud_t *pudp = pud_offset(p4dp, addr); -+ -+ pmd_t *pmdp = pmd_offset(pudp, addr); -+ -+ pte_t *ptep = pte_offset_kernel(pmdp, addr); -+ pte_t pte = READ_ONCE(*ptep); -+ -+ if(attr & PTE_RDONLY) -+ pte = __pte((pte_val(pte) | PTE_RDONLY) & ~PTE_DBM); -+ pte = __pte(pte_val(pte) | attr); -+ #ifdef CONFIG_PTP -+ // Write pgtable in IEE directly. -+ flag = local_daif_save(); -+ asm volatile ("msr pan, #0"); -+ WRITE_ONCE(*((pte_t *)(__phys_to_iee(__pa(ptep)))), pte); -+ asm volatile ("msr pan, #1"); -+ local_daif_restore(flag); -+ #else -+ WRITE_ONCE(*ptep, pte); -+ #endif -+} ++#ifdef CONFIG_KOI ++#define KOI_DATA() \ ++ . = ALIGN(PAGE_SIZE); \ ++ __koi_data_start = .; \ ++ *(.data..koi) \ ++ . = ALIGN(PAGE_SIZE); \ ++ __koi_data_end = .; ++#else ++#define KOI_DATA() ++#endif + -+/* Prepare data used for iee rwx gates. These data are setted only once. */ -+void __init iee_si_prepare_data(void) -+{ -+ unsigned long va; -+ // Record current TCR val after system init. -+ iee_si_tcr = read_sysreg(tcr_el1) & ~(SYS_TCR_IEE_SI); -+ // Mark iee data as RO and move it to iee after setting up. -+ va = (unsigned long)__iee_si_data_start; -+ iee_si_set_page_attr(va, PTE_RDONLY); -+ iee_si_set_page_attr(lm_alias(va)+iee_offset, 0x1 | PTE_RDONLY); -+ // Set iee sensitive inst code page U RWX here to hide it from kernel. -+ va = (unsigned long)__iee_si_start; -+ iee_si_set_page_attr(va, PTE_USER); -+ va = (unsigned long)__iee_si_start + PAGE_SIZE; -+ iee_si_set_page_attr(va, PTE_USER); -+ flush_tlb_all(); - } + /* + * .data section + */ +@@ -403,8 +414,8 @@ + BRANCH_PROFILE() \ + TRACE_PRINTKS() \ + BPF_RAW_TP() \ +- TRACEPOINT_STR() +- ++ TRACEPOINT_STR() \ ++ KOI_DATA() + /* + * Data section helpers + */ +@@ -1126,6 +1137,23 @@ + * They will fit only a subset of the architectures + */ --static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end, -- pgprot_t prot, struct vm_struct *vma, -- int flags, unsigned long vm_flags) ++#ifdef CONFIG_CREDP ++ #define CRED_DATA \ ++ . = ALIGN(PAGE_SIZE); \ ++ *(.iee.cred) \ ++ . = ALIGN(PAGE_SIZE); ++#else ++ #define CRED_DATA +#endif + -+#ifdef CONFIG_PTP -+// Attention : Using set_xxx without adding offset. -+static void __init set_iee_valid_pre_init(unsigned long addr) - { -- phys_addr_t pa_start = __pa_symbol(va_start); -- unsigned long size = va_end - va_start; -+ pgd_t *pgdir = swapper_pg_dir; -+ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); - -- BUG_ON(!PAGE_ALIGNED(pa_start)); -- BUG_ON(!PAGE_ALIGNED(size)); -+ p4d_t *p4dp = p4d_offset(pgdp, addr); - -- __create_pgd_mapping(pgdp, pa_start, (unsigned long)va_start, size, prot, -- early_pgtable_alloc, flags); -+ pud_t *pudp = pud_offset(p4dp, addr); ++#ifdef CONFIG_IEE_SELINUX_P ++ #define IEE_SELINUX_DATA \ ++ . = ALIGN(PAGE_SIZE); \ ++ *(.iee.selinux) \ ++ . = ALIGN(PAGE_SIZE); ++#else ++ #define IEE_SELINUX_DATA ++#endif -- if (!(vm_flags & VM_NO_GUARD)) -- size += PAGE_SIZE; -+ pmd_t *pmdp = pmd_offset(pudp, addr); + /* + * Writeable data. +@@ -1143,6 +1171,8 @@ + . = ALIGN(PAGE_SIZE); \ + .data : AT(ADDR(.data) - LOAD_OFFSET) { \ + INIT_TASK_DATA(inittask) \ ++ CRED_DATA \ ++ IEE_SELINUX_DATA \ + NOSAVE_DATA \ + PAGE_ALIGNED_DATA(pagealigned) \ + CACHELINE_ALIGNED_DATA(cacheline) \ +diff --git a/include/keys/asymmetric-subtype.h b/include/keys/asymmetric-subtype.h +index d55171f640a0..1293c5a1c624 100644 +--- a/include/keys/asymmetric-subtype.h ++++ b/include/keys/asymmetric-subtype.h +@@ -54,7 +54,11 @@ struct asymmetric_key_subtype { + static inline + struct asymmetric_key_subtype *asymmetric_key_subtype(const struct key *key) + { ++ #ifdef CONFIG_KEYP ++ return ((union key_payload *)(key->name_link.next))->data[asym_subtype]; ++ #else + return key->payload.data[asym_subtype]; ++ #endif + } -- vma->addr = va_start; -- vma->phys_addr = pa_start; -- vma->size = size; -- vma->flags = VM_MAP | vm_flags; -- vma->caller = __builtin_return_address(0); -+ pte_t *ptep = pte_offset_kernel(pmdp, addr); -+ pte_t pte = READ_ONCE(*ptep); + #endif /* _KEYS_ASYMMETRIC_SUBTYPE_H */ +diff --git a/include/keys/asymmetric-type.h b/include/keys/asymmetric-type.h +index 69a13e1e5b2e..6cd556bfb216 100644 +--- a/include/keys/asymmetric-type.h ++++ b/include/keys/asymmetric-type.h +@@ -69,13 +69,21 @@ extern struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1, + static inline + const struct asymmetric_key_ids *asymmetric_key_ids(const struct key *key) + { ++ #ifdef CONFIG_KEYP ++ return ((union key_payload *)(key->name_link.next))->data[asym_key_ids]; ++ #else + return key->payload.data[asym_key_ids]; ++ #endif + } -- vm_area_add_early(vma); -+ if((addr < (PAGE_OFFSET + IEE_OFFSET)) | (addr > (PAGE_OFFSET + BIT(vabits_actual - 1)))) -+ return; -+ -+ pte = __pte(pte_val(pte) | 0x1); -+ iee_set_pte_pre_init(ptep, pte); -+ flush_tlb_kernel_range(addr, addr+PAGE_SIZE); -+ isb(); + static inline + const struct public_key *asymmetric_key_public_key(const struct key *key) + { ++ #ifdef CONFIG_KEYP ++ return ((union key_payload *)(key->name_link.next))->data[asym_crypto]; ++ #else + return key->payload.data[asym_crypto]; ++ #endif } --static pgprot_t kernel_exec_prot(void) -+static void __init move_pte_table_into_iee(pmd_t *pmdp, unsigned long addr, unsigned long end) + extern struct key *find_asymmetric_key(struct key *keyring, +diff --git a/include/keys/request_key_auth-type.h b/include/keys/request_key_auth-type.h +index 36b89a933310..63d5d9f66cb4 100644 +--- a/include/keys/request_key_auth-type.h ++++ b/include/keys/request_key_auth-type.h +@@ -26,7 +26,11 @@ struct request_key_auth { + + static inline struct request_key_auth *get_request_key_auth(const struct key *key) { -- return rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC; -+ pmd_t pmd = READ_ONCE(*pmdp); -+ unsigned long iee_addr = __phys_to_iee(__pmd_to_phys(pmd)); -+ set_iee_valid_pre_init(iee_addr); ++ #ifdef CONFIG_KEYP ++ return ((union key_payload *)(key->name_link.next))->data[0]; ++ #else + return key->payload.data[0]; ++ #endif } --#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 --static int __init map_entry_trampoline(void) -+static void __init move_pmd_table_into_iee(pud_t *pudp, unsigned long addr, unsigned long end) - { -- int i; -+ unsigned long next; -+ pud_t pud = READ_ONCE(*pudp); -+ pmd_t *pmdp; -+ pmd_t pmd; -+ unsigned long iee_addr = __phys_to_iee(__pud_to_phys(pud)); -+ set_iee_valid_pre_init(iee_addr); -- pgprot_t prot = kernel_exec_prot(); -- phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start); -+ pmdp = pmd_offset(pudp, addr); -+ do { -+ next = pmd_addr_end(addr, end); -+ pmd = READ_ONCE(*pmdp); -+ if((pmd_val(pmd) & PMD_TABLE_BIT) == 0) -+ { -+ continue; -+ } -+ else -+ { -+ move_pte_table_into_iee(pmdp, addr, next); -+ } -+ } while (pmdp++, addr = next, addr != end); -+} +diff --git a/include/linux/cred.h b/include/linux/cred.h +index e01c6d094a30..c7b3fe009f66 100644 +--- a/include/linux/cred.h ++++ b/include/linux/cred.h +@@ -18,6 +18,11 @@ + #include + #include + ++#ifdef CONFIG_CREDP ++#include ++#include ++#endif ++ + struct cred; + struct inode; + +@@ -153,6 +158,22 @@ struct cred { + KABI_RESERVE(4) + } __randomize_layout; -- /* The trampoline is always mapped and can therefore be global */ -- pgprot_val(prot) &= ~PTE_NG; -+static void __init move_pud_table_into_iee(pgd_t *pgdp, unsigned long addr, unsigned long end) ++#ifdef CONFIG_CREDP ++extern unsigned long long iee_rw_gate(int flag, ...); ++static void iee_set_cred_non_rcu(struct cred *cred, int non_rcu) +{ -+ unsigned long next; -+ p4d_t *p4dp = p4d_offset(pgdp, addr); -+ p4d_t p4d = READ_ONCE(*p4dp); -+ pud_t *pudp; -+ pud_t pud; -+ unsigned long iee_addr = __phys_to_iee(__p4d_to_phys(p4d)); -+ set_iee_valid_pre_init(iee_addr); - -- /* Map only the text into the trampoline page table */ -- memset(tramp_pg_dir, 0, PGD_SIZE); -- __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, -- entry_tramp_text_size(), prot, -- __pgd_pgtable_alloc, NO_BLOCK_MAPPINGS); -+ pudp = pud_offset(p4dp, addr); -+ do { -+ next = pud_addr_end(addr, end); -+ pud = READ_ONCE(*pudp); -+ if ((pud_val(pud) & PUD_TABLE_BIT) == 0) -+ { -+ continue; -+ } -+ else -+ { -+ move_pmd_table_into_iee(pudp, addr, next); -+ } -+ } while (pudp++, addr = next, addr != end); ++ iee_rw_gate(IEE_OP_SET_CRED_NON_RCU,cred,non_rcu); ++ *(int *)(&(((struct rcu_head *)(cred->rcu.func))->next)) = non_rcu; +} - -- /* Map both the text and data into the kernel page table */ -- for (i = 0; i < DIV_ROUND_UP(entry_tramp_text_size(), PAGE_SIZE); i++) -- __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i, -- pa_start + i * PAGE_SIZE, prot); -+static void __init init_iee_for_one_region(pgd_t *pgdir, unsigned long va_start, unsigned long va_end) ++ ++static bool iee_set_cred_atomic_op_usage(struct cred *cred, int flag, int nr) +{ -+ unsigned long addr, end, next; -+ pgd_t *pgdp = pgd_offset_pgd(pgdir, va_start); ++ bool ret; ++ ret = iee_rw_gate(IEE_OP_SET_CRED_ATOP_USAGE,cred,flag,nr); ++ return ret; ++} ++#endif ++ + extern void __put_cred(struct cred *); + extern void exit_creds(struct task_struct *); + extern int copy_creds(struct task_struct *, unsigned long); +@@ -189,7 +210,11 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred) + */ + static inline struct cred *get_new_cred_many(struct cred *cred, int nr) + { ++ #ifdef CONFIG_CREDP ++ iee_set_cred_atomic_op_usage(cred, AT_ADD, nr); ++ #else + atomic_long_add(nr, &cred->usage); ++ #endif + return cred; + } -- if (IS_ENABLED(CONFIG_RELOCATABLE)) -- __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i, -- pa_start + i * PAGE_SIZE, PAGE_KERNEL_RO); -+ addr = va_start & PAGE_MASK; -+ end = PAGE_ALIGN(va_end); +@@ -202,7 +227,7 @@ static inline struct cred *get_new_cred_many(struct cred *cred, int nr) + */ + static inline struct cred *get_new_cred(struct cred *cred) + { +- return get_new_cred_many(cred, 1); ++ return get_new_cred_many(cred, 1); // XXXzgc atomic_inc -> get_new_cred_many + } -- return 0; -+ do { -+ next = pgd_addr_end(addr, end); -+ move_pud_table_into_iee(pgdp, addr, next); -+ } while (pgdp++, addr = next, addr != end); + /** +@@ -224,7 +249,11 @@ static inline const struct cred *get_cred_many(const struct cred *cred, int nr) + struct cred *nonconst_cred = (struct cred *) cred; + if (!cred) + return cred; ++ #ifdef CONFIG_CREDP ++ iee_set_cred_non_rcu(nonconst_cred,0); ++ #else + nonconst_cred->non_rcu = 0; ++ #endif + return get_new_cred_many(nonconst_cred, nr); } --core_initcall(map_entry_trampoline); --#endif --/* -- * Open coded check for BTI, only for use to determine configuration -- * for early mappings for before the cpufeature code has run. -- */ --static bool arm64_early_this_cpu_has_bti(void) -+static void __init init_iee(void) - { -- u64 pfr1; -+ unsigned long iee_addr; -+ phys_addr_t start, end; -+ u64 i; -+ pgd_t *pgdp; +@@ -247,9 +276,19 @@ static inline const struct cred *get_cred_rcu(const struct cred *cred) + struct cred *nonconst_cred = (struct cred *) cred; + if (!cred) + return NULL; ++ #ifdef CONFIG_CREDP ++ if (!iee_set_cred_atomic_op_usage(nonconst_cred,AT_INC_NOT_ZERO,0)) ++ return NULL; ++ #else + if (!atomic_long_inc_not_zero(&nonconst_cred->usage)) + return NULL; ++ #endif + -+ #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 -+ // handling 1-level tramp page table tramp_pg_dir -+ iee_addr = (unsigned long)__phys_to_iee(__pa_symbol(tramp_pg_dir)); -+ set_iee_valid_pre_init(iee_addr); ++ #ifdef CONFIG_CREDP ++ iee_set_cred_non_rcu(nonconst_cred,0); ++ #else + nonconst_cred->non_rcu = 0; + #endif -+ // handling 1-level page table swapper_pg_dir -+ pgdp = swapper_pg_dir; -+ iee_addr = (unsigned long)__phys_to_iee(__pa_symbol(swapper_pg_dir)); -+ set_iee_valid_pre_init(iee_addr); -+ // handling 2/3/4-level page table for kernel -+ init_iee_for_one_region(pgdp, (unsigned long)_text, (unsigned long)_etext); -+ init_iee_for_one_region(pgdp, (unsigned long)__start_rodata, (unsigned long)__inittext_begin); -+ init_iee_for_one_region(pgdp, (unsigned long)__inittext_begin, (unsigned long)__inittext_end); -+ init_iee_for_one_region(pgdp, (unsigned long)__initdata_begin, (unsigned long)__initdata_end); -+ init_iee_for_one_region(pgdp, (unsigned long)_data, (unsigned long)_end); -+ // handling 2/3/4-level page table for fixmap i.e. remap bm_xxx -+ iee_addr = (unsigned long)__phys_to_iee(__pa_symbol(bm_pte_addr)); -+ set_iee_valid_pre_init(iee_addr); -+ iee_addr = (unsigned long)__phys_to_iee(__pa_symbol(bm_pmd_addr)); -+ set_iee_valid_pre_init(iee_addr); -+ iee_addr = (unsigned long)__phys_to_iee(__pa_symbol(bm_pud_addr)); -+ set_iee_valid_pre_init(iee_addr); -+ // handling 2/3/4-level page table for logical mem and iee -+ for_each_mem_range(i, &start, &end) { -+ if (start >= end) -+ break; -+ /* -+ * The linear map must allow allocation tags reading/writing -+ * if MTE is present. Otherwise, it has the same attributes as -+ * PAGE_KERNEL. -+ */ -+ init_iee_for_one_region(pgdp, (unsigned long)__va(start), (unsigned long)__va(end)); -+ init_iee_for_one_region(pgdp, (unsigned long)__phys_to_iee(start), (unsigned long)__phys_to_iee(end)); -+ } -+} + return cred; + } -- if (!IS_ENABLED(CONFIG_ARM64_BTI_KERNEL)) -- return false; -+static void iee_set_kernel_upage_pre_init(unsigned long addr) -+{ -+ pgd_t *pgdir = swapper_pg_dir; -+ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); +@@ -270,8 +309,13 @@ static inline void put_cred_many(const struct cred *_cred, int nr) + struct cred *cred = (struct cred *) _cred; -- pfr1 = __read_sysreg_by_encoding(SYS_ID_AA64PFR1_EL1); -- return cpuid_feature_extract_unsigned_field(pfr1, -- ID_AA64PFR1_EL1_BT_SHIFT); -+ p4d_t *p4dp = p4d_offset(pgdp, addr); -+ p4d_t p4d = READ_ONCE(*p4dp); + if (cred) { ++ #ifdef CONFIG_CREDP ++ if (iee_set_cred_atomic_op_usage(cred,AT_SUB_AND_TEST,nr)) ++ __put_cred(cred); ++ #else + if (atomic_long_sub_and_test(nr, &cred->usage)) + __put_cred(cred); ++ #endif + } + } + +diff --git a/include/linux/efi.h b/include/linux/efi.h +index 9ed79128458c..970cc4f7068b 100644 +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -740,6 +740,15 @@ extern int __init __efi_memmap_init(struct efi_memory_map_data *data); + extern int __init efi_memmap_init_early(struct efi_memory_map_data *data); + extern int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size); + extern void __init efi_memmap_unmap(void); ++#ifdef CONFIG_PTP ++extern void __init efi_memmap_unmap_after_init(void); ++#endif ++extern int __init efi_memmap_install(struct efi_memory_map_data *data); ++extern int __init efi_memmap_split_count(efi_memory_desc_t *md, ++ struct range *range); ++extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap, ++ void *buf, struct efi_mem_range *mem); ++extern void __init efi_print_memmap(void); + + #ifdef CONFIG_EFI_ESRT + extern void __init efi_esrt_init(void); +diff --git a/include/linux/iee-flag.h b/include/linux/iee-flag.h +new file mode 100644 +index 000000000000..a6d70ef1d446 +--- /dev/null ++++ b/include/linux/iee-flag.h +@@ -0,0 +1,116 @@ ++#ifndef _LINUX_IEE_FLAG_H ++#define _LINUX_IEE_FLAG_H ++ ++// Function Identifiers with Parameters Description ++enum { ++ IEE_WRITE_IN_BYTE=0, // Parameters: void *ptr, __u64 data, int length ++ IEE_OP_SET_PTE, // Parameters: pte_t *ptep, pte_t pte ++ IEE_OP_SET_PMD, // Parameters: pmd_t *pmdp, pmd_t pmd ++ IEE_OP_SET_PUD, // Parameters: pud_t *pudp, pud_t pud ++ IEE_OP_SET_P4D, // Parameters: p4d_t *p4dp, p4d_t p4d ++ IEE_OP_SET_BM_PTE, // Parameters: pte_t *ptep, pte_t pte ++ IEE_OP_SET_SWAPPER_PGD, // Parameters: pgd_t *pgdp, pgd_t pgd ++ IEE_OP_SET_TRAMP_PGD, // Parameters: pgd_t *pgdp, pgd_t pgd ++ IEE_MEMSET, // Parameters: void *ptr, int data, size_t n ++ IEE_OP_SET_TRACK, // Parameters: struct track *ptr, struct track *data ++ IEE_OP_SET_FREEPTR, // Parameters: void **pptr, void *ptr ++ IEE_OP_SET_PTE_U, // Parameters: pte_t *ptep ++ IEE_OP_SET_PTE_P, // Parameters: pte_t *ptep ++ IEE_SET_TOKEN_PGD, // Parameters: struct task_token *token, pgd_t *pgd ++ IEE_INIT_TOKEN, // Parameters: struct task_struct *tsk, void *kernel_stack, void *iee_stack ++ IEE_INVALIDATE_TOKEN, // Parameters: struct task_struct *tsk ++ IEE_SET_SENSITIVE_PTE, // Parameters: pte_t *lm_ptep, pte_t *iee_ptep ++ IEE_UNSET_SENSITIVE_PTE, // Parameters: pte_t *lm_ptep, pte_t *iee_ptep ++ IEE_SET_TOKEN, // Parameters: pte_t *ptep, void *new, unsigned long order ++ IEE_UNSET_TOKEN, // Parameters: pte_t *ptep, void *token_addr, void *token_page, unsigned long order ++ IEE_COPY_PTE_RANGE, // Parameters: pte_t *new_dst, pte_t *old_dst, pte_t *src_pte, struct vm_area_struct *src_vma, ++ // unsigned long dst_vm_flags, pte_t *end_pte ++ IEE_SPLIT_HUGE_PMD, ++ IEE_VALIDATE_TOKEN, ++ IEE_MEMCPY, ++#ifdef CONFIG_KOI ++ _IEE_READ_KOI_STACK, // Parameters: struct task_struct *tsk ++ _IEE_WRITE_KOI_STACK, // Parameters: struct task_struct *tsk, unsigned long koi_stack ++ _IEE_READ_TOKEN_TTBR1, // Parameters: struct task_struct *tsk ++ _IEE_WRITE_TOKEN_TTBR1, // Parameters: struct task_struct *tsk, unsigned long current_ttbr1 ++ _IEE_READ_KOI_KERNEL_STACK, // Parameters: struct task_struct *tsk ++ _IEE_WRITE_KOI_KERNEL_STACK, // Parameters: struct task_struct *tsk, unsigned long kernel_stack ++ _IEE_READ_KOI_STACK_BASE, // Parameters: struct task_struct *tsk ++ _IEE_WRITE_KOI_STACK_BASE, // Parameters: struct task_struct *tsk, unsigned long koi_stack_base ++ _IEE_SET_KOI_PGD, // Parameters: unsigned long koi_pgd_addr ++#endif ++#ifdef CONFIG_CREDP ++ IEE_OP_COPY_CRED, // Parameters: struct cred *old, struct cred *new ++ IEE_OP_SET_CRED_UID, // Parameters: struct cred *cred, kuid_t uid ++ IEE_OP_SET_CRED_GID, // Parameters: struct cred *cred, kgid_t gid ++ IEE_OP_SET_CRED_SUID, // Parameters: struct cred *cred, kuid_t suid ++ IEE_OP_SET_CRED_SGID, // Parameters: struct cred *cred, kgid_t sgid ++ IEE_OP_SET_CRED_EUID, // Parameters: struct cred *cred, kuid_t euid ++ IEE_OP_SET_CRED_EGID, // Parameters: struct cred *cred, kgid_t egid ++ IEE_OP_SET_CRED_FSUID, // Parameters: struct cred *cred, kuid_t fsuid ++ IEE_OP_SET_CRED_FSGID, // Parameters: struct cred *cred, kgid_t fsgid ++ IEE_OP_SET_CRED_USER, // Parameters: struct cred *cred, struct user_struct *user ++ IEE_OP_SET_CRED_USER_NS, // Parameters: struct cred *cred, struct user_namespace *user_ns ++ IEE_OP_SET_CRED_GROUP_INFO, // Parameters: struct cred *cred, struct group_info *group_info ++ IEE_OP_SET_CRED_SECUREBITS, // Parameters: struct cred *cred, unsigned securebits ++ IEE_OP_SET_CRED_CAP_INHER, // Parameters: struct cred *cred, kernel_cap_t cap_inheritable ++ IEE_OP_SET_CRED_CAP_PERM, // Parameters: struct cred *cred, kernel_cap_t cap_permitted ++ IEE_OP_SET_CRED_CAP_EFFECT, // Parameters: struct cred *cred, kernel_cap_t cap_effective ++ IEE_OP_SET_CRED_CAP_BSET, // Parameters: struct cred *cred, kernel_cap_t cap_bset ++ IEE_OP_SET_CRED_CAP_AMBIENT, // Parameters: struct cred *cred, kernel_cap_t cap_ambient ++ IEE_OP_SET_CRED_JIT_KEYRING, // Parameters: struct cred *cred, unsigned char jit_keyring ++ IEE_OP_SET_CRED_SESS_KEYRING, // Parameters: struct cred *cred, struct key *session_keyring ++ IEE_OP_SET_CRED_PROC_KEYRING, // Parameters: struct cred *cred, struct key *process_keyring ++ IEE_OP_SET_CRED_THREAD_KEYRING, // Parameters: struct cred *cred, struct key *thread_keyring ++ IEE_OP_SET_CRED_REQ_KEYRING, // Parameters: struct cred *cred, struct key *request_key_auth ++ IEE_OP_SET_CRED_NON_RCU, // Parameters: struct cred *cred, int non_rcu ++ IEE_OP_SET_CRED_ATSET_USAGE, // Parameters: struct cred *cred, int i ++ IEE_OP_SET_CRED_ATOP_USAGE, // Parameters: struct cred *cred, int flag ++ IEE_OP_SET_CRED_SECURITY, // Parameters: struct cred *cred, void *security ++ IEE_OP_SET_CRED_RCU, // Parameters: struct cred *cred, struct rcu_head *rcu ++ IEE_OP_SET_CRED_UCOUNTS, // Parameters: struct cred *cred, struct ucounts *ucounts ++// IEE_OP_COMMIT_CRED, // Parameters: struct cred *cred ++// IEE_OP_COPY_CRED_KERNEL, // Parameters: struct cred *old, struct cred *new ++#endif ++#ifdef CONFIG_KEYP ++ IEE_OP_SET_KEY_UNION, ++ IEE_OP_SET_KEY_STRUCT, ++ IEE_OP_SET_KEY_PAYLOAD, ++ IEE_OP_WRITE_KEY_PAYLOAD, ++ IEE_OP_WRITE_KEY_PAYLOAD_RCU_DATA0, ++ IEE_OP_SET_KEY_USAGE, ++ IEE_OP_SET_KEY_SERIAL, ++ IEE_OP_SET_KEY_WATCHERS, ++ IEE_OP_SET_KEY_USERS, ++ IEE_OP_SET_KEY_SECURITY, ++ IEE_OP_SET_KEY_EXPIRY, ++ IEE_OP_SET_KEY_REVOKED_AT, ++ IEE_OP_SET_KEY_LAST_USED_AT, ++ IEE_OP_SET_KEY_UID, ++ IEE_OP_SET_KEY_GID, ++ IEE_OP_SET_KEY_PERM, ++ IEE_OP_SET_KEY_QUOTALEN, ++ IEE_OP_SET_KEY_DATALEN, ++ IEE_OP_SET_KEY_STATE, ++ IEE_OP_SET_KEY_MAGIC, ++ IEE_OP_SET_KEY_FLAGS, ++ IEE_OP_SET_KEY_INDEX_KEY, ++ IEE_OP_SET_KEY_HASH, ++ IEE_OP_SET_KEY_LEN_DESC, ++ IEE_OP_SET_KEY_TYPE, ++ IEE_OP_SET_KEY_TAG, ++ IEE_OP_SET_KEY_DESCRIPTION, ++ IEE_OP_SET_KEY_RESTRICT_LINK, ++ IEE_OP_SET_KEY_FLAG_BIT, ++#endif ++#ifdef CONFIG_IEE_SELINUX_P ++ IEE_SEL_SET_STATUS_PG, // Parameters: struct page* new_page ++ IEE_SEL_SET_ENFORCING, // Parameters: bool value ++ IEE_SEL_SET_INITIALIZED, ++ IEE_SEL_SET_POLICY_CAP, // Parameters: unsigned int idx, int cap ++ IEE_SEL_RCU_ASSIGN_POLICY, // Parameters: struct selinux_policy* new_policy, struct selinux_policy* iee_new_policy ++#endif ++ IEE_FLAG_END ++}; ++ ++#endif +\ No newline at end of file +diff --git a/include/linux/iee-func.h b/include/linux/iee-func.h +new file mode 100644 +index 000000000000..a3e4909a650f +--- /dev/null ++++ b/include/linux/iee-func.h +@@ -0,0 +1,35 @@ ++#ifndef _LINUX_IEE_FUNC_H ++#define _LINUX_IEE_FUNC_H ++ ++#ifdef CONFIG_IEE ++#define HUGE_PMD_ORDER 9 ++#define TASK_ORDER 4 ++extern unsigned long init_iee_stack_begin[]; ++extern unsigned long init_iee_stack_end[]; ++extern void *init_token_page_vaddr; + -+ pud_t *pudp = pud_offset(p4dp, addr); ++extern unsigned long long iee_rw_gate(int flag, ...); ++extern u32 get_cpu_asid_bits(void); ++extern unsigned long arm64_mm_context_get(struct mm_struct *mm); ++extern void set_iee_page(unsigned long addr, int order); ++extern void unset_iee_page(unsigned long addr, int order); ++extern void set_iee_page_valid(unsigned long addr); ++extern void iee_set_logical_mem_ro(unsigned long addr); ++extern void __init iee_mark_all_lm_pgtable_ro(void); ++extern void iee_set_token_pgd(struct task_struct *tsk, pgd_t *pgd); ++extern void iee_init_token(struct task_struct *tsk, void *iee_stack, void *tmp_page); ++extern void iee_invalidate_token(struct task_struct *tsk); ++extern void iee_validate_token(struct task_struct *tsk); ++extern unsigned long iee_read_token_stack(struct task_struct *tsk); ++extern void iee_set_token_page_valid(void *token, void *new, unsigned int order); ++extern void iee_set_token_page_invalid(void *token_addr, void *token_page, unsigned long order); ++extern void unset_iee_stack_page(unsigned long addr, int order); ++extern void set_iee_stack_page(unsigned long addr, int order); ++extern void iee_write_in_byte(void *ptr, u64 data, int length); ++extern void *iee_read_tmp_page(struct task_struct *tsk); ++extern void *iee_read_freeptr(void *ptr); ++extern void iee_set_stack_freeptr(unsigned long addr, void *free_ptr); ++extern void iee_memset(void *ptr, int data, size_t n); ++#endif + -+ pmd_t *pmdp = pmd_offset(pudp, addr); ++#endif +\ No newline at end of file +diff --git a/include/linux/key.h b/include/linux/key.h +index 938d7ecfb495..7cde506953cd 100644 +--- a/include/linux/key.h ++++ b/include/linux/key.h +@@ -280,6 +280,39 @@ struct key { + struct key_restriction *restrict_link; + }; + ++#ifdef CONFIG_IEE ++struct key_union { ++ union { ++ struct list_head graveyard_link; ++ struct rb_node serial_node; ++ }; ++ struct rw_semaphore sem; ++ struct key *key; ++}; + -+ pte_t *ptep = pte_offset_kernel(pmdp, addr); ++struct key_struct { ++ struct { ++ /* Keyring bits */ ++ struct list_head name_link; ++ struct assoc_array keys; ++ }; ++ struct key *key; ++}; ++#endif + -+ int i; -+ for(i = 0; i < 4; i++) -+ { -+ pte_t pte = READ_ONCE(*ptep); -+ pte = __pte(pte_val(pte) | PTE_USER | PTE_NG); -+ iee_set_pte_pre_init(ptep, pte); -+ ptep++; -+ } -+ flush_tlb_kernel_range(addr, addr+4*PAGE_SIZE); -+ isb(); - } - --/* -- * Create fine-grained mappings for the kernel. -- */ --static void __init map_kernel(pgd_t *pgdp) -+static void __init iee_set_pte_table_ro(pmd_t *pmdp, unsigned long addr, unsigned long end) - { -- static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_inittext, -- vmlinux_initdata, vmlinux_data; -+ pmd_t pmd = READ_ONCE(*pmdp); -+ unsigned long logical_addr = (unsigned long)__va(__pmd_to_phys(pmd)); -+ iee_set_logical_mem_ro(logical_addr); -+} - -- /* -- * External debuggers may need to write directly to the text -- * mapping to install SW breakpoints. Allow this (only) when -- * explicitly requested with rodata=off. -- */ -- pgprot_t text_prot = kernel_exec_prot(); -+static void __init iee_set_pmd_table_ro(pud_t *pudp, unsigned long addr, unsigned long end) ++#ifdef CONFIG_KEYP ++#define KEY_SEM(KEY) (((struct key_union *)(KEY->graveyard_link.next))->sem) ++#include ++#include ++extern unsigned long long iee_rw_gate(int flag, ...); ++static bool iee_set_key_usage(struct key *key, int n, int flag) +{ -+ unsigned long next; -+ pud_t pud = READ_ONCE(*pudp); -+ pmd_t *pmdp; -+ pmd_t pmd; -+ unsigned long logical_addr = (unsigned long)__va(__pud_to_phys(pud)); -+ iee_set_logical_mem_ro(logical_addr); - -- /* -- * If we have a CPU that supports BTI and a kernel built for -- * BTI then mark the kernel executable text as guarded pages -- * now so we don't have to rewrite the page tables later. -- */ -- if (arm64_early_this_cpu_has_bti()) -- text_prot = __pgprot_modify(text_prot, PTE_GP, PTE_GP); -+ pmdp = pmd_offset(pudp, addr); -+ do { -+ next = pmd_addr_end(addr, end); -+ pmd = READ_ONCE(*pmdp); -+ if((pmd_val(pmd) & PMD_TABLE_BIT) == 0) -+ { -+ continue; -+ } -+ else -+ { -+ iee_set_pte_table_ro(pmdp, addr, next); -+ } -+ } while (pmdp++, addr = next, addr != end); ++ bool ret; ++ ret = iee_rw_gate(IEE_OP_SET_KEY_USAGE, key, n, flag); ++ return ret; +} ++#endif ++ + extern struct key *key_alloc(struct key_type *type, + const char *desc, + kuid_t uid, kgid_t gid, +@@ -305,7 +338,11 @@ extern void key_remove_domain(struct key_tag *domain_tag); -- /* -- * Only rodata will be remapped with different permissions later on, -- * all other segments are allowed to use contiguous mappings. -- */ -- map_kernel_segment(pgdp, _stext, _etext, text_prot, &vmlinux_text, 0, -- VM_NO_GUARD); -- map_kernel_segment(pgdp, __start_rodata, __inittext_begin, PAGE_KERNEL, -- &vmlinux_rodata, NO_CONT_MAPPINGS, VM_NO_GUARD); -- map_kernel_segment(pgdp, __inittext_begin, __inittext_end, text_prot, -- &vmlinux_inittext, 0, VM_NO_GUARD); -- map_kernel_segment(pgdp, __initdata_begin, __initdata_end, PAGE_KERNEL, -- &vmlinux_initdata, 0, VM_NO_GUARD); -- map_kernel_segment(pgdp, _data, _end, PAGE_KERNEL, &vmlinux_data, 0, 0); -+static void __init iee_set_pud_table_ro(pgd_t *pgdp, unsigned long addr, unsigned long end) -+{ -+ unsigned long next; -+ p4d_t *p4dp = p4d_offset(pgdp, addr); -+ p4d_t p4d = READ_ONCE(*p4dp); -+ pud_t *pudp; -+ pud_t pud; -+ unsigned long logical_addr = (unsigned long)__va(__p4d_to_phys(p4d)); -+ iee_set_logical_mem_ro(logical_addr); - -- fixmap_copy(pgdp); -- kasan_copy_shadow(pgdp); -+ pudp = pud_offset(p4dp, addr); -+ do { -+ next = pud_addr_end(addr, end); -+ pud = READ_ONCE(*pudp); -+ if ((pud_val(pud) & PUD_TABLE_BIT) == 0) -+ { -+ continue; -+ } -+ else -+ { -+ iee_set_pmd_table_ro(pudp, addr, next); -+ } -+ } while (pudp++, addr = next, addr != end); - } - --static void __init create_idmap(void) -+static void __init iee_mark_pgtable_for_one_region_ro(pgd_t *pgdir, unsigned long va_start, unsigned long va_end) + static inline struct key *__key_get(struct key *key) { -- u64 start = __pa_symbol(__idmap_text_start); -- u64 size = __pa_symbol(__idmap_text_end) - start; -- pgd_t *pgd = idmap_pg_dir; -- u64 pgd_phys; -+ unsigned long addr, end, next; -+ pgd_t *pgdp = pgd_offset_pgd(pgdir, va_start); - -- /* check if we need an additional level of translation */ -- if (VA_BITS < 48 && idmap_t0sz < (64 - VA_BITS_MIN)) { -- pgd_phys = early_pgtable_alloc(PAGE_SHIFT); -- set_pgd(&idmap_pg_dir[start >> VA_BITS], -- __pgd(pgd_phys | P4D_TYPE_TABLE)); -- pgd = __va(pgd_phys); -- } -- __create_pgd_mapping(pgd, start, start, size, PAGE_KERNEL_ROX, -- early_pgtable_alloc, 0); -+ addr = va_start & PAGE_MASK; -+ end = PAGE_ALIGN(va_end); ++ #ifdef CONFIG_KEYP ++ iee_set_key_usage(key, 0, REFCOUNT_INC); ++ #else + refcount_inc(&key->usage); ++ #endif + return key; + } -- if (IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0)) { -- extern u32 __idmap_kpti_flag; -- u64 pa = __pa_symbol(&__idmap_kpti_flag); -+ do { -+ next = pgd_addr_end(addr, end); -+ iee_set_pud_table_ro(pgdp, addr, next); -+ } while (pgdp++, addr = next, addr != end); -+} +@@ -478,17 +515,63 @@ static inline bool key_is_negative(const struct key *key) + return key_read_state(key) < 0; + } -+static void __init iee_mark_all_lm_pgtable_ro(void) -+{ -+ unsigned long logical_addr; -+ phys_addr_t start, end; -+ u64 i; -+ pgd_t *pgdp; -+ -+ // handling static allocated page table -+ #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 -+ // handling 1-level tramp page table tramp_pg_dir -+ logical_addr = (unsigned long)__va(__pa_symbol(tramp_pg_dir)); -+ iee_set_logical_mem_ro(logical_addr); -+ #endif -+ // handling 1-level page table swapper_pg_dir -+ pgdp = swapper_pg_dir; -+ iee_set_logical_mem_ro((unsigned long)swapper_pg_dir); -+ logical_addr = (unsigned long)__va(__pa_symbol(swapper_pg_dir)); -+ iee_set_logical_mem_ro(logical_addr); ++#ifdef CONFIG_KEYP ++extern void iee_write_key_payload_rcu_data0(struct key *key, void *rcu_data0); + -+ // handling 2/3/4-level page table for kernel -+ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)_text, (unsigned long)_etext); -+ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)__start_rodata, (unsigned long)__inittext_begin); -+ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)__inittext_begin, (unsigned long)__inittext_end); -+ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)__initdata_begin, (unsigned long)__initdata_end); -+ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)_data, (unsigned long)_end); ++#define dereference_key_rcu(KEY) \ ++ (rcu_dereference(((union key_payload *)(KEY->name_link.next))->rcu_data0)) + -+ // handling 2/3/4-level page table for fixmap i.e. remap bm_xxx -+ logical_addr = (unsigned long)__va(__pa_symbol(bm_pte_addr)); -+ iee_set_logical_mem_ro(logical_addr); ++#ifdef CONFIG_KEYP ++#define dereference_key_locked(KEY) \ ++ (rcu_dereference_protected(((union key_payload *)(KEY->name_link.next))->rcu_data0, \ ++ rwsem_is_locked(&KEY_SEM(((struct key *)(KEY)))))) ++#else ++#define dereference_key_locked(KEY) \ ++ (rcu_dereference_protected(((union key_payload *)(KEY->name_link.next))->rcu_data0, \ ++ rwsem_is_locked(&((struct key *)(KEY))->sem))) ++#endif + -+ iee_set_logical_mem_ro((unsigned long)bm_pmd_addr); -+ logical_addr = (unsigned long)__va(__pa_symbol(bm_pmd_addr)); -+ iee_set_logical_mem_ro(logical_addr); ++#define iee_smp_store_release(p, v, KEY) \ ++do { \ ++ compiletime_assert_atomic_type(*p); \ ++ barrier(); \ ++ iee_write_key_payload_rcu_data0(KEY, v); \ ++} while (0) + -+ iee_set_logical_mem_ro((unsigned long)bm_pud_addr); -+ logical_addr = (unsigned long)__va(__pa_symbol(bm_pud_addr)); -+ iee_set_logical_mem_ro(logical_addr); ++#define iee_rcu_assign_pointer(p, v, KEY) \ ++do { \ ++ uintptr_t _r_a_p__v = (uintptr_t)(v); \ ++ rcu_check_sparse(p, __rcu); \ ++ \ ++ if (__builtin_constant_p(v) && (_r_a_p__v) == (uintptr_t)NULL) \ ++ iee_write_key_payload_rcu_data0(KEY, (typeof(p))(_r_a_p__v)); \ ++ else \ ++ iee_smp_store_release(&p, RCU_INITIALIZER((typeof(p))_r_a_p__v), KEY); \ ++} while (0) + -+ // handling 2/3/4-level page table for logical mem and iee -+ for_each_mem_range(i, &start, &end) { -+ if (start >= end) -+ break; - /* -- * The KPTI G-to-nG conversion code needs a read-write mapping -- * of its synchronization flag in the ID map. -+ * The linear map must allow allocation tags reading/writing -+ * if MTE is present. Otherwise, it has the same attributes as -+ * PAGE_KERNEL. - */ -- __create_pgd_mapping(pgd, pa, pa, sizeof(u32), PAGE_KERNEL, -- early_pgtable_alloc, 0); -+ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)__va(start), (unsigned long)__va(end)); -+ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)__phys_to_iee(start), (unsigned long)__phys_to_iee(end)); - } - } ++#define rcu_assign_keypointer(KEY, PAYLOAD) \ ++do { \ ++ iee_rcu_assign_pointer(((union key_payload *)(KEY->name_link.next))->rcu_data0, (PAYLOAD), KEY); \ ++} while (0) ++#else + #define dereference_key_rcu(KEY) \ + (rcu_dereference((KEY)->payload.rcu_data0)) + ++#ifdef CONFIG_KEYP ++#define dereference_key_locked(KEY) \ ++ (rcu_dereference_protected((KEY)->payload.rcu_data0, \ ++ rwsem_is_locked(&KEY_SEM(((struct key *)(KEY)))))) ++#else + #define dereference_key_locked(KEY) \ + (rcu_dereference_protected((KEY)->payload.rcu_data0, \ + rwsem_is_locked(&((struct key *)(KEY))->sem))) +#endif -+ -+#ifdef CONFIG_KOI -+extern s64 koi_offset; + + #define rcu_assign_keypointer(KEY, PAYLOAD) \ + do { \ + rcu_assign_pointer((KEY)->payload.rcu_data0, (PAYLOAD)); \ + } while (0) +#endif - void __init paging_init(void) - { -+ #ifdef CONFIG_IEE -+ unsigned long SP_EL0; -+ void *new; -+ void *init_token; -+ struct task_token *token; -+ unsigned long tcr; + /* + * the userspace interface +diff --git a/include/linux/mm.h b/include/linux/mm.h +index ffdd46c1108a..e938f50f2d7f 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -32,6 +32,77 @@ + #include + #include + ++#ifdef CONFIG_PTP ++#include ++struct slab_t { ++ unsigned long __page_flags; ++ ++#if defined(CONFIG_SLAB) ++ ++ void *slab_cache; ++ union { ++ struct { ++ struct list_head slab_list; ++ void *freelist; /* array of free object indexes */ ++ void *s_mem; /* first object */ ++ }; ++ struct rcu_head rcu_head; ++ }; ++ unsigned int active; ++ ++#elif defined(CONFIG_SLUB) ++ ++ void *slab_cache; ++ union { ++ struct { ++ union { ++ struct list_head slab_list; ++#ifdef CONFIG_SLUB_CPU_PARTIAL ++ struct { ++ struct slab_t *next; ++ int slabs; /* Nr of slabs left */ ++ }; ++#endif ++ }; ++ /* Double-word boundary */ ++ union { ++ struct { ++ void *freelist; /* first free object */ ++ union { ++ unsigned long counters; ++ struct { ++ unsigned inuse:16; ++ unsigned objects:15; ++ unsigned frozen:1; ++ }; ++ }; ++ }; ++#ifdef system_has_freelist_aba ++ union { ++ struct { ++ void *freelist; ++ unsigned long counter; ++ }; ++ u64 full; ++ }; ++#endif ++ }; ++ }; ++ struct rcu_head rcu_head; ++ }; ++ unsigned int __unused; + -+ // Check if cpu has PAN and HPDS. -+ if(!cpuid_feature_extract_unsigned_field(read_cpuid(ID_AA64MMFR1_EL1), -+ ID_AA64MMFR1_EL1_PAN_SHIFT)) -+ panic("Architecture doesn't support PAN, please disable CONFIG_IEE.\n"); -+ -+ if(!cpuid_feature_extract_unsigned_field(read_cpuid(ID_AA64MMFR1_EL1), -+ ID_AA64MMFR1_EL1_HPDS_SHIFT)) -+ panic("Architecture doesn't support HPDS, please disable CONFIG_IEE.\n"); -+ #endif ++#else ++#error "Unexpected slab allocator configured" ++#endif + -+ // Avoid using iee code to modify pgtable before iee initialized. ++ atomic_t __page_refcount; ++#ifdef CONFIG_MEMCG ++ unsigned long memcg_data; ++#endif ++}; ++#endif ++ + struct mempolicy; + struct anon_vma; + struct anon_vma_chain; +@@ -2938,7 +3009,11 @@ static inline bool pagetable_is_reserved(struct ptdesc *pt) + */ + static inline struct ptdesc *pagetable_alloc(gfp_t gfp, unsigned int order) + { + #ifdef CONFIG_PTP -+ pgd_t *pgdp = pgd_set_fixmap_init(__pa_symbol(swapper_pg_dir)); ++ struct page *page = virt_to_page(get_iee_pgtable_page(gfp | __GFP_COMP)); + #else - pgd_t *pgdp = pgd_set_fixmap(__pa_symbol(swapper_pg_dir)); + struct page *page = alloc_pages(gfp | __GFP_COMP, order); + #endif -+ -+ - extern pgd_t init_idmap_pg_dir[]; - idmap_t0sz = 63UL - __fls(__pa_symbol(_end) | GENMASK(VA_BITS_MIN - 1, 0)); -@@ -802,7 +2006,17 @@ void __init paging_init(void) - map_kernel(pgdp); - map_mem(pgdp); + return page_ptdesc(page); + } +@@ -2954,7 +3029,11 @@ static inline void pagetable_free(struct ptdesc *pt) + { + struct page *page = ptdesc_page(pt); -+ // Map the whole physical mem into IEE, but set invalid. -+ #ifdef CONFIG_IEE -+ map_iee(pgdp); -+ #endif -+ -+ // Avoid using iee code to modify pgtable before iee initialized. + #ifdef CONFIG_PTP -+ pgd_clear_fixmap_init(); ++ free_iee_pgtable_page((void *)page_address(page)); + #else - pgd_clear_fixmap(); + __free_pages(page, compound_order(page)); + #endif + } - cpu_replace_ttbr1(lm_alias(swapper_pg_dir), init_idmap_pg_dir); - init_mm.pgd = swapper_pg_dir; -@@ -813,6 +2027,80 @@ void __init paging_init(void) - memblock_allow_resize(); + #if USE_SPLIT_PTE_PTLOCKS +@@ -2965,7 +3044,11 @@ void ptlock_free(struct ptdesc *ptdesc); - create_idmap(); -+ -+ #ifdef CONFIG_IEE -+ // test iee_exec_entry -+ iee_rwx_gate_entry(IEE_SI_TEST); -+ // Initialize init iee stack. + static inline spinlock_t *ptlock_ptr(struct ptdesc *ptdesc) + { + #ifdef CONFIG_PTP -+ iee_set_kernel_upage_pre_init((unsigned long)init_iee_stack_begin); -+ iee_set_kernel_upage_pre_init((unsigned long)__va(__pa_symbol(init_iee_stack_begin))); ++ return ((struct ptdesc_t *)(((struct slab_t *)ptdesc)->slab_cache))->ptl; + #else -+ iee_set_kernel_upage((unsigned long)init_iee_stack_begin); -+ iee_set_kernel_upage((unsigned long)__va(__pa_symbol(init_iee_stack_begin))); + return ptdesc->ptl; + #endif + } + #else /* ALLOC_SPLIT_PTLOCKS */ + static inline void ptlock_cache_init(void) +@@ -2983,7 +3066,11 @@ static inline void ptlock_free(struct ptdesc *ptdesc) + + static inline spinlock_t *ptlock_ptr(struct ptdesc *ptdesc) + { ++ #ifdef CONFIG_PTP ++ return &(((struct ptdesc_t *)(((struct slab_t *)ptdesc)->slab_cache))->ptl); ++ #else + return &ptdesc->ptl; + #endif -+ -+ // Init token for init_task. -+ #ifdef CONFIG_IEE -+ // Change SP_EL0 from Image VA to Logical VA. -+ SP_EL0 = (unsigned long)__va(__pa_symbol(&init_task)); -+ write_sysreg(SP_EL0, sp_el0); -+ init_task.cpus_ptr = &(((struct task_struct *)(__va(__pa_symbol(&init_task))))->cpus_mask); -+ init_task.children.prev = (__va(__pa_symbol(init_task.children.prev))); -+ init_task.children.next = (__va(__pa_symbol(init_task.children.next))); -+ // Set init_task into __entry_task before per_cpu init. -+ *(struct task_struct **)__entry_task = __va(__pa_symbol(&init_task)); -+ // Alloc a page for init_token. -+ new = __va(early_pgtable_alloc(0)); -+ init_token = (void *)__phys_to_iee(__pa_symbol(&init_task)); + } + #endif /* ALLOC_SPLIT_PTLOCKS */ + +@@ -3001,7 +3088,11 @@ static inline bool ptlock_init(struct ptdesc *ptdesc) + * It can happen if arch try to use slab for page table allocation: + * slab code uses page->slab_cache, which share storage with page->ptl. + */ + #ifdef CONFIG_PTP -+ iee_set_token_page_valid_pre_init(init_token, new); ++ VM_BUG_ON_PAGE(*(unsigned long *)&(((struct ptdesc_t *)(((struct slab_t *)ptdesc)->slab_cache))->ptl), ptdesc_page(ptdesc)); + #else -+ iee_set_token_page_valid(init_token, new); + VM_BUG_ON_PAGE(*(unsigned long *)&ptdesc->ptl, ptdesc_page(ptdesc)); + #endif -+ // Use lm to write token before IEE initialized. -+ token = (struct task_token *)((unsigned long)new + (((unsigned long)&init_task) & ~PAGE_MASK)); -+ token->mm = &init_mm; -+ token->pgd = NULL; -+ token->iee_stack = (void *)init_iee_stack_end; -+ token->valid = true; + if (!ptlock_alloc(ptdesc)) + return false; + spin_lock_init(ptlock_ptr(ptdesc)); +@@ -3100,7 +3191,11 @@ static inline spinlock_t *pmd_lockptr(struct mm_struct *mm, pmd_t *pmd) + static inline bool pmd_ptlock_init(struct ptdesc *ptdesc) + { + #ifdef CONFIG_TRANSPARENT_HUGEPAGE ++ #ifdef CONFIG_PTP ++ (((struct ptdesc_t *)(((struct slab_t *)ptdesc)->slab_cache))->pmd_huge_pte) = NULL; ++ #else + ptdesc->pmd_huge_pte = NULL; + #endif -+ + #endif + return ptlock_init(ptdesc); + } +@@ -3108,12 +3203,20 @@ static inline bool pmd_ptlock_init(struct ptdesc *ptdesc) + static inline void pmd_ptlock_free(struct ptdesc *ptdesc) + { + #ifdef CONFIG_TRANSPARENT_HUGEPAGE + #ifdef CONFIG_PTP -+ // Map the existing pgtable into IEE, set valid. -+ init_iee(); ++ VM_BUG_ON_PAGE((((struct ptdesc_t *)(((struct slab_t *)ptdesc)->slab_cache))->pmd_huge_pte), ptdesc_page(ptdesc)); ++ #else + VM_BUG_ON_PAGE(ptdesc->pmd_huge_pte, ptdesc_page(ptdesc)); + #endif + #endif + ptlock_free(ptdesc); + } + ++#ifdef CONFIG_PTP ++#define pmd_huge_pte(mm, pmd) (((struct ptdesc_t *)(((struct slab_t *)pmd_ptdesc(pmd))->slab_cache))->pmd_huge_pte) ++#else + #define pmd_huge_pte(mm, pmd) (pmd_ptdesc(pmd)->pmd_huge_pte) ++#endif + + #else + +diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h +index fdc047bdbc49..df8d03ea6955 100644 +--- a/include/linux/mm_types.h ++++ b/include/linux/mm_types.h +@@ -483,6 +483,42 @@ struct ptdesc { + #endif + }; + ++#ifdef CONFIG_IEE ++struct ptdesc_t { ++ unsigned long __page_flags; ++ ++ union { ++ struct rcu_head pt_rcu_head; ++ struct list_head pt_list; ++ struct { ++ unsigned long _pt_pad_1; ++ pgtable_t pmd_huge_pte; ++ }; ++ }; ++ unsigned long __page_mapping; + -+ #ifdef CONFIG_IEE -+ sysreg_clear_set(sctlr_el1, 0, SCTLR_EL1_SPAN); -+ #endif ++ union { ++ struct mm_struct *pt_mm; ++ atomic_t pt_frag_refcount; ++ }; + -+ #ifdef CONFIG_PTP -+ // IEE ready. -+ // Pgtable writing before uses logical memory and after uses IEE memory. ++ union { ++ unsigned long _pt_pad_2; ++#if ALLOC_SPLIT_PTLOCKS ++ spinlock_t *ptl; ++#else ++ spinlock_t ptl; ++#endif ++ }; ++ unsigned int __page_type; ++ atomic_t _refcount; ++#ifdef CONFIG_MEMCG ++ unsigned long pt_memcg_data; ++#endif ++ struct slab_t *slab; ++}; ++#endif ++ + #define TABLE_MATCH(pg, pt) \ + static_assert(offsetof(struct page, pg) == offsetof(struct ptdesc, pt)) + TABLE_MATCH(flags, __page_flags); +@@ -1182,6 +1218,9 @@ struct mmu_gather; + extern void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm); + extern void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm); + extern void tlb_finish_mmu(struct mmu_gather *tlb); ++#ifdef CONFIG_PTP ++extern void iee_tlb_finish_mmu(struct mmu_gather *tlb); ++#endif + + struct vm_fault; + +diff --git a/include/linux/module.h b/include/linux/module.h +index 990f9d66d2f1..169021fc8501 100644 +--- a/include/linux/module.h ++++ b/include/linux/module.h +@@ -609,6 +609,7 @@ struct module { + KABI_RESERVE(2) + KABI_RESERVE(3) + KABI_RESERVE(4) ++ + } ____cacheline_aligned __randomize_layout; + #ifndef MODULE_ARCH_INIT + #define MODULE_ARCH_INIT {} +diff --git a/include/linux/sched.h b/include/linux/sched.h +index 7b1c53f71ee4..3b42a96a4ae0 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -773,6 +773,24 @@ struct task_struct_resvd { + struct task_struct *task; + }; + ++#if defined(CONFIG_IEE) || defined(CONFIG_KOI) ++struct task_token { ++#ifdef CONFIG_IEE ++ pgd_t *pgd; /* Logical VA */ ++ void *iee_stack; /* VA */ ++ void *tmp_page; ++ bool valid; ++ void *kernel_stack; /* VA */ ++#endif ++#ifdef CONFIG_KOI ++ void *koi_kernel_stack; /* VA */ ++ void *koi_stack; /* VA */ ++ void *koi_stack_base; /* VA */ ++ unsigned long current_ttbr1; ++#endif ++}; ++#endif ++ + struct task_struct { + #ifdef CONFIG_THREAD_INFO_IN_TASK + /* +@@ -795,6 +813,7 @@ struct task_struct { + randomized_struct_fields_start + + void *stack; ++ + refcount_t usage; + /* Per task flags (PF_*), defined further below: */ + unsigned int flags; +diff --git a/init/main.c b/init/main.c +index 8fdfa69dba0f..9c6aeae0ea66 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -102,6 +102,14 @@ + #include + #include + ++#ifdef CONFIG_IEE ++#include ++#include ++#include ++#include ++#include ++#endif ++ + #include + #include + #include +@@ -112,6 +120,10 @@ + + #include + ++#ifdef CONFIG_PTP ++extern void *bm_pte_addr; ++#endif + + static int kernel_init(void *); + + /* +@@ -933,6 +945,10 @@ void start_kernel(void) + sort_main_extable(); + trap_init(); + mm_core_init(); ++ #ifdef CONFIG_IEE ++ iee_stack_init(); ++ iee_pgtable_init(); ++ #endif + poking_init(); + ftrace_init(); + +@@ -1073,6 +1089,16 @@ void start_kernel(void) + arch_post_acpi_subsys_init(); + kcsan_init(); + ++ // Later IEE settings. ++ #ifdef CONFIG_IEE ++ set_iee_stack_page((unsigned long)__va(__pa_symbol(init_iee_stack_begin)), 2); ++ set_iee_page((unsigned long)init_token_page_vaddr, 0); + // Set the logical va of existing pgtable readonly. ++ #ifdef CONFIG_PTP + iee_mark_all_lm_pgtable_ro(); + #endif ++ #endif + -+ // Set the init token readonly. -+ #ifdef CONFIG_IEE -+ set_iee_page_valid(__phys_to_iee(__pa(new))); -+ iee_set_logical_mem_ro((unsigned long)new); -+ -+ // Set HPD1 as 1. -+ tcr = read_sysreg(tcr_el1); -+ tcr |= ((unsigned long)0x1 << 42); -+ write_sysreg(tcr, tcr_el1); -+ isb(); + /* Do the rest non-__init'ed, we're now alive */ + arch_call_rest_init(); + +@@ -1444,6 +1470,9 @@ static int __ref kernel_init(void *unused) + wait_for_completion(&kthreadd_done); + + kernel_init_freeable(); ++ #ifdef CONFIG_PTP ++ iee_set_logical_mem_ro((unsigned long)bm_pte_addr); ++ #endif + /* need to finish all async __init code before freeing the memory */ + async_synchronize_full(); + +@@ -1460,7 +1489,7 @@ static int __ref kernel_init(void *unused) + * to finalize PTI. + */ + pti_finalize(); +- ++ + system_state = SYSTEM_RUNNING; + numa_default_policy(); + +diff --git a/kernel/cred.c b/kernel/cred.c +index c033a201c808..ba57e19a26b8 100644 +--- a/kernel/cred.c ++++ b/kernel/cred.c +@@ -20,6 +20,11 @@ + #include + #include + ++#ifdef CONFIG_CREDP ++#include ++#include ++#endif + -+ // Flush tlb to enable IEE. -+ flush_tlb_all(); + #if 0 + #define kdebug(FMT, ...) \ + printk("[%-5.5s%5u] " FMT "\n", \ +@@ -33,7 +38,14 @@ do { \ + } while (0) + #endif + ++#ifdef CONFIG_IEE ++struct kmem_cache *cred_jar; ++#ifdef CONFIG_CREDP ++static struct kmem_cache *rcu_jar; ++#endif ++#else + static struct kmem_cache *cred_jar; ++#endif + + /* init to 2 - one for init_task, one to ensure it is never freed */ + static struct group_info init_groups = { .usage = REFCOUNT_INIT(2) }; +@@ -41,6 +53,32 @@ static struct group_info init_groups = { .usage = REFCOUNT_INIT(2) }; + /* + * The initial credentials for the initial task + */ ++#ifdef CONFIG_CREDP ++struct cred init_cred __section(".iee.cred") = { ++ .usage = ATOMIC_INIT(4), ++#ifdef CONFIG_DEBUG_CREDENTIALS ++ .subscribers = ATOMIC_INIT(2), ++ .magic = CRED_MAGIC, ++#endif ++ .uid = GLOBAL_ROOT_UID, ++ .gid = GLOBAL_ROOT_GID, ++ .suid = GLOBAL_ROOT_UID, ++ .sgid = GLOBAL_ROOT_GID, ++ .euid = GLOBAL_ROOT_UID, ++ .egid = GLOBAL_ROOT_GID, ++ .fsuid = GLOBAL_ROOT_UID, ++ .fsgid = GLOBAL_ROOT_GID, ++ .securebits = SECUREBITS_DEFAULT, ++ .cap_inheritable = CAP_EMPTY_SET, ++ .cap_permitted = CAP_FULL_SET, ++ .cap_effective = CAP_FULL_SET, ++ .cap_bset = CAP_FULL_SET, ++ .user = INIT_USER, ++ .user_ns = &init_user_ns, ++ .group_info = &init_groups, ++ .ucounts = &init_ucounts, ++}; ++#else + struct cred init_cred = { + .usage = ATOMIC_INIT(4), + .uid = GLOBAL_ROOT_UID, +@@ -61,13 +99,43 @@ struct cred init_cred = { + .group_info = &init_groups, + .ucounts = &init_ucounts, + }; ++#endif + -+ // mark that iee is prepared. -+ iee_init_done = true; -+ #endif - } - - #ifdef CONFIG_MEMORY_HOTPLUG -diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c -index 4a64089e5771..894bda11c389 100644 ---- a/arch/arm64/mm/pgd.c -+++ b/arch/arm64/mm/pgd.c -@@ -15,14 +15,44 @@ - #include - #include - -+#ifdef CONFIG_PTP -+#include ++static inline void set_cred_subscribers(struct cred *cred, int n) ++{ ++#ifdef CONFIG_DEBUG_CREDENTIALS ++ atomic_set(&cred->subscribers, n); +#endif ++} + - static struct kmem_cache *pgd_cache __ro_after_init; - -+#ifdef CONFIG_KOI -+pgd_t *koi_pgd_alloc(void) ++static inline int read_cred_subscribers(const struct cred *cred) +{ -+ pgd_t *pgd; -+#ifdef CONFIG_PTP -+ pgd = (pgd_t *)__get_free_page(GFP_PGTABLE_KERNEL); -+ unsigned long iee_addr = __phys_to_iee(__pa(pgd)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)pgd); ++#ifdef CONFIG_DEBUG_CREDENTIALS ++ return atomic_read(&cred->subscribers); +#else -+ pgd = (pgd_t *)__get_free_page(GFP_PGTABLE_KERNEL); ++ return 0; +#endif -+ return pgd; +} -+#endif + - pgd_t *pgd_alloc(struct mm_struct *mm) ++static inline void alter_cred_subscribers(const struct cred *_cred, int n) ++{ ++#ifdef CONFIG_DEBUG_CREDENTIALS ++ struct cred *cred = (struct cred *) _cred; ++ ++ atomic_add(n, &cred->subscribers); ++#endif ++} + + /* + * The RCU callback to actually dispose of a set of credentials + */ + static void put_cred_rcu(struct rcu_head *rcu) { - gfp_t gfp = GFP_PGTABLE_USER; ++ #ifdef CONFIG_CREDP ++ struct cred *cred = *(struct cred **)(rcu + 1); ++ #else + struct cred *cred = container_of(rcu, struct cred, rcu); ++ #endif - if (PGD_SIZE == PAGE_SIZE) -+#ifdef CONFIG_PTP -+ { -+ pgd_t* new = (pgd_t *)__get_free_page(gfp); -+ unsigned long iee_addr = __phys_to_iee(__pa(new)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)new); -+ return new; -+ } -+#else - return (pgd_t *)__get_free_page(gfp); -+#endif - else - return kmem_cache_alloc(pgd_cache, gfp); + kdebug("put_cred_rcu(%p)", cred); + +@@ -86,6 +154,9 @@ static void put_cred_rcu(struct rcu_head *rcu) + if (cred->ucounts) + put_ucounts(cred->ucounts); + put_user_ns(cred->user_ns); ++ #ifdef CONFIG_CREDP ++ kmem_cache_free(rcu_jar, (struct rcu_head *)(cred->rcu.func)); ++ #endif + kmem_cache_free(cred_jar, cred); } -@@ -30,7 +60,16 @@ pgd_t *pgd_alloc(struct mm_struct *mm) - void pgd_free(struct mm_struct *mm, pgd_t *pgd) - { - if (PGD_SIZE == PAGE_SIZE) -+#ifdef CONFIG_PTP -+ { -+ unsigned long iee_addr = __phys_to_iee(__pa(pgd)); -+ set_iee_page_invalid(iee_addr); -+ iee_set_logical_mem_rw((unsigned long)pgd); -+ free_page((unsigned long)pgd); -+ } -+#else - free_page((unsigned long)pgd); -+#endif + +@@ -104,10 +175,22 @@ void __put_cred(struct cred *cred) + BUG_ON(cred == current->cred); + BUG_ON(cred == current->real_cred); + ++ #ifdef CONFIG_CREDP ++ if (*(int *)(&(((struct rcu_head *)(cred->rcu.func))->next))) ++ #else + if (cred->non_rcu) ++ #endif ++ #ifdef CONFIG_CREDP ++ put_cred_rcu((struct rcu_head *)(cred->rcu.func)); ++ #else + put_cred_rcu(&cred->rcu); ++ #endif else - kmem_cache_free(pgd_cache, pgd); ++ #ifdef CONFIG_CREDP ++ call_rcu((struct rcu_head *)(cred->rcu.func), put_cred_rcu); ++ #else + call_rcu(&cred->rcu, put_cred_rcu); ++ #endif } -diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S -index 14fdf645edc8..230b2b883a51 100644 ---- a/arch/arm64/mm/proc.S -+++ b/arch/arm64/mm/proc.S -@@ -22,6 +22,8 @@ - #include - #include + EXPORT_SYMBOL(__put_cred); -+ -+ - #ifdef CONFIG_ARM64_64K_PAGES - #define TCR_TG_FLAGS TCR_TG0_64K | TCR_TG1_64K - #elif defined(CONFIG_ARM64_16K_PAGES) -@@ -105,6 +107,19 @@ SYM_FUNC_START(cpu_do_suspend) - ret - SYM_FUNC_END(cpu_do_suspend) +@@ -178,7 +261,18 @@ struct cred *cred_alloc_blank(void) + if (!new) + return NULL; ++ #ifdef CONFIG_CREDP ++ iee_set_cred_rcu(new,kmem_cache_zalloc(rcu_jar, GFP_KERNEL)); ++ *(struct cred **)(((struct rcu_head *)(new->rcu.func)) + 1) = new; ++ iee_set_cred_atomic_set_usage(new,1); ++ #else + atomic_long_set(&new->usage, 1); ++ #endif + -+#ifdef CONFIG_IEE -+// SP_EL0 check failed. -+SYM_FUNC_START_LOCAL(sp_el0_check_failed) -+1: -+ nop -+ nop -+ nop -+ nop -+ b 1f -+SYM_FUNC_END(sp_el0_check_failed) -+#endif ++ #ifdef CONFIG_DEBUG_CREDENTIALS ++ new->magic = CRED_MAGIC; ++ #endif + - /** - * cpu_do_resume - restore CPU register context - * -@@ -148,6 +163,13 @@ SYM_FUNC_START(cpu_do_resume) - msr sctlr_el1, x12 - set_this_cpu_offset x13 - msr sp_el0, x14 -+#ifdef CONFIG_IEE -+ // tsk check. -+ ldr_this_cpu x2, __entry_task, x3 -+ mrs x3, sp_el0 -+ cmp x2, x3 -+ b.ne sp_el0_check_failed -+#endif - /* - * Restore oslsr_el1 by writing oslar_el1 - */ -@@ -190,6 +212,7 @@ SYM_TYPED_FUNC_START(idmap_cpu_replace_ttbr1) - __idmap_cpu_set_reserved_ttbr1 x1, x3 + if (security_cred_alloc_blank(new, GFP_KERNEL_ACCOUNT) < 0) + goto error; - offset_ttbr1 x0, x3 -+ - msr ttbr1_el1, x0 - isb +@@ -213,13 +307,25 @@ struct cred *prepare_creds(void) + if (!new) + return NULL; -@@ -452,6 +475,11 @@ SYM_FUNC_START(__cpu_setup) - orr tcr, tcr, #TCR_HA // hardware Access flag update - 1: - #endif /* CONFIG_ARM64_HW_AFDBM */ ++ #ifdef CONFIG_CREDP ++ iee_set_cred_rcu(new,kmem_cache_alloc(rcu_jar, GFP_KERNEL)); ++ *(struct cred **)(((struct rcu_head *)(new->rcu.func)) + 1) = new; ++ #endif + -+#ifdef CONFIG_IEE -+ orr tcr, tcr, #TCR_HPD1 // Hierarchical permission disables -+#endif + kdebug("prepare_creds() alloc %p", new); + + old = task->cred; ++ #ifdef CONFIG_CREDP ++ iee_copy_cred(old,new); + - msr mair_el1, mair - msr tcr_el1, tcr ++ iee_set_cred_non_rcu(new,0); ++ iee_set_cred_atomic_set_usage(new,1); ++ #else + memcpy(new, old, sizeof(struct cred)); -diff --git a/arch/arm64/mm/trans_pgd.c b/arch/arm64/mm/trans_pgd.c -index 5139a28130c0..15d2a3faa048 100644 ---- a/arch/arm64/mm/trans_pgd.c -+++ b/arch/arm64/mm/trans_pgd.c -@@ -25,6 +25,9 @@ - #include - #include - #include -+#ifdef CONFIG_PTP -+#include + new->non_rcu = 0; + atomic_long_set(&new->usage, 1); ++ #endif + get_group_info(new->group_info); + get_uid(new->user); + get_user_ns(new->user_ns); +@@ -232,10 +338,18 @@ struct cred *prepare_creds(void) + #endif + + #ifdef CONFIG_SECURITY ++#ifdef CONFIG_CREDP ++ iee_set_cred_security(new,NULL); ++#else + new->security = NULL; +#endif + #endif - static void *trans_alloc(struct trans_pgd_info *info) - { -@@ -65,10 +68,18 @@ static int copy_pte(struct trans_pgd_info *info, pmd_t *dst_pmdp, - pte_t *src_ptep; - pte_t *dst_ptep; - unsigned long addr = start; -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr; ++ #ifdef CONFIG_CREDP ++ iee_set_cred_ucounts(new, get_ucounts(new->ucounts)); ++ #else + new->ucounts = get_ucounts(new->ucounts); + #endif + if (!new->ucounts) + goto error; - dst_ptep = trans_alloc(info); - if (!dst_ptep) - return -ENOMEM; -+ #ifdef CONFIG_PTP -+ iee_addr = __phys_to_iee(__pa(dst_ptep)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)dst_ptep); +@@ -265,15 +379,30 @@ struct cred *prepare_exec_creds(void) + #ifdef CONFIG_KEYS + /* newly exec'd tasks don't get a thread keyring */ + key_put(new->thread_keyring); ++ #ifdef CONFIG_CREDP ++ iee_set_cred_thread_keyring(new,NULL); ++ #else + new->thread_keyring = NULL; + #endif - pmd_populate_kernel(NULL, dst_pmdp, dst_ptep); - dst_ptep = pte_offset_kernel(dst_pmdp, start); -@@ -87,11 +98,19 @@ static int copy_pmd(struct trans_pgd_info *info, pud_t *dst_pudp, - pmd_t *dst_pmdp; - unsigned long next; - unsigned long addr = start; -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr; + /* inherit the session keyring; new process keyring */ + key_put(new->process_keyring); ++ #ifdef CONFIG_CREDP ++ iee_set_cred_process_keyring(new,NULL); ++ #else + new->process_keyring = NULL; + #endif + #endif - if (pud_none(READ_ONCE(*dst_pudp))) { - dst_pmdp = trans_alloc(info); - if (!dst_pmdp) - return -ENOMEM; -+ #ifdef CONFIG_PTP -+ iee_addr = __phys_to_iee(__pa(dst_pmdp)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)dst_pmdp); -+ #endif - pud_populate(NULL, dst_pudp, dst_pmdp); - } - dst_pmdp = pmd_offset(dst_pudp, start); -@@ -123,11 +142,19 @@ static int copy_pud(struct trans_pgd_info *info, p4d_t *dst_p4dp, - pud_t *src_pudp; - unsigned long next; - unsigned long addr = start; -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr; ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(new,new->euid); ++ iee_set_cred_suid(new,new->euid); ++ iee_set_cred_fsgid(new,new->egid); ++ iee_set_cred_sgid(new,new->egid); ++ #else + new->suid = new->fsuid = new->euid; + new->sgid = new->fsgid = new->egid; + #endif - if (p4d_none(READ_ONCE(*dst_p4dp))) { - dst_pudp = trans_alloc(info); - if (!dst_pudp) - return -ENOMEM; -+ #ifdef CONFIG_PTP -+ iee_addr = __phys_to_iee(__pa(dst_pudp)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)dst_pudp); + return new; + } +@@ -327,7 +456,11 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) + * had one */ + if (new->thread_keyring) { + key_put(new->thread_keyring); ++ #ifdef CONFIG_CREDP ++ iee_set_cred_thread_keyring(new,NULL); ++ #else + new->thread_keyring = NULL; + #endif - p4d_populate(NULL, dst_p4dp, dst_pudp); + if (clone_flags & CLONE_THREAD) + install_thread_keyring_to_cred(new); } - dst_pudp = pud_offset(dst_p4dp, start); -@@ -212,6 +239,12 @@ int trans_pgd_create_copy(struct trans_pgd_info *info, pgd_t **dst_pgdp, - return -ENOMEM; +@@ -337,7 +470,11 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) + */ + if (!(clone_flags & CLONE_THREAD)) { + key_put(new->process_keyring); ++ #ifdef CONFIG_CREDP ++ iee_set_cred_process_keyring(new,NULL); ++ #else + new->process_keyring = NULL; ++ #endif } + #endif -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr = __phys_to_iee(__pa(trans_pgd)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)trans_pgd); +@@ -594,7 +731,11 @@ int set_cred_ucounts(struct cred *new) + if (!(new_ucounts = alloc_ucounts(new->user_ns, new->uid))) + return -EAGAIN; + ++ #ifdef CONFIG_CREDP ++ iee_set_cred_ucounts(new, new_ucounts); ++ #else + new->ucounts = new_ucounts; + #endif -+ - rc = copy_page_tables(info, trans_pgd, start, end); - if (!rc) - *dst_pgdp = trans_pgd; -@@ -238,6 +271,9 @@ int trans_pgd_idmap_page(struct trans_pgd_info *info, phys_addr_t *trans_ttbr0, - int bits_mapped = PAGE_SHIFT - 4; - unsigned long level_mask, prev_level_entry, *levels[4]; - int this_level, index, level_lsb, level_msb; -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr; + put_ucounts(old_ucounts); + + return 0; +@@ -606,8 +747,21 @@ int set_cred_ucounts(struct cred *new) + void __init cred_init(void) + { + /* allocate a slab in which we can store credentials */ ++ #ifdef CONFIG_CREDP + cred_jar = kmem_cache_create("cred_jar", sizeof(struct cred), 0, ++ SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT|SLAB_RED_ZONE, NULL); ++ rcu_jar = kmem_cache_create("rcu_jar", sizeof(struct rcu_head) + sizeof(struct cred *), 0, + SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, NULL); ++ // Map init_cred ++ *((struct rcu_head **)(&(init_cred.rcu.func))) = (struct rcu_head *)kmem_cache_zalloc(rcu_jar, GFP_KERNEL); ++ *(struct cred **)(((struct rcu_head *)(init_cred.rcu.func)) + 1) = &init_cred; ++ set_iee_page_valid(__phys_to_iee(__pa_symbol(&init_cred))); ++ iee_set_logical_mem_ro((unsigned long)&init_cred); ++ iee_set_logical_mem_ro((unsigned long)__va(__pa_symbol(&init_cred))); ++ #else ++ cred_jar = kmem_cache_create("cred_jar", sizeof(struct cred), 0, ++ SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, NULL); + #endif + } - dst_addr &= PAGE_MASK; - prev_level_entry = pte_val(pfn_pte(pfn, PAGE_KERNEL_ROX)); -@@ -247,12 +283,22 @@ int trans_pgd_idmap_page(struct trans_pgd_info *info, phys_addr_t *trans_ttbr0, - if (!levels[this_level]) - return -ENOMEM; + /** +@@ -638,29 +792,56 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) + if (!new) + return NULL; -+ #ifdef CONFIG_PTP -+ iee_addr = __phys_to_iee(__pa(levels[this_level])); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)levels[this_level]); -+ #endif ++ #ifdef CONFIG_CREDP ++ iee_set_cred_rcu(new,kmem_cache_alloc(rcu_jar, GFP_KERNEL)); ++ *(struct cred **)(((struct rcu_head *)(new->rcu.func)) + 1) = new; ++ #endif + - level_lsb = ARM64_HW_PGTABLE_LEVEL_SHIFT(this_level); - level_msb = min(level_lsb + bits_mapped, max_msb); - level_mask = GENMASK_ULL(level_msb, level_lsb); - - index = (dst_addr & level_mask) >> level_lsb; -+ #ifdef CONFIG_PTP -+ set_pte((pte_t *)(levels[this_level] + index), __pte(prev_level_entry)); -+ #else - *(levels[this_level] + index) = prev_level_entry; -+ #endif + kdebug("prepare_kernel_cred() alloc %p", new); - pfn = virt_to_pfn(levels[this_level]); - prev_level_entry = pte_val(pfn_pte(pfn, -diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c -index 83092d93f36a..fb12e7d0660a 100644 ---- a/drivers/firmware/efi/arm-runtime.c -+++ b/drivers/firmware/efi/arm-runtime.c -@@ -94,7 +94,11 @@ static int __init arm_enable_runtime_services(void) - return 0; - } + old = get_task_cred(daemon); -+ #ifdef CONFIG_PTP -+ efi_memmap_unmap_after_init(); ++ #ifdef CONFIG_CREDP ++ iee_copy_cred(old,new); ++ iee_set_cred_non_rcu(new,0); ++ iee_set_cred_atomic_set_usage(new,1); + #else - efi_memmap_unmap(); + *new = *old; + new->non_rcu = 0; + atomic_long_set(&new->usage, 1); + #endif + get_uid(new->user); + get_user_ns(new->user_ns); + get_group_info(new->group_info); - mapsize = efi.memmap.desc_size * efi.memmap.nr_map; - -diff --git a/drivers/firmware/efi/memmap.c b/drivers/firmware/efi/memmap.c -index a1180461a445..4c64b6f15717 100644 ---- a/drivers/firmware/efi/memmap.c -+++ b/drivers/firmware/efi/memmap.c -@@ -105,6 +105,26 @@ void __init efi_memmap_unmap(void) - clear_bit(EFI_MEMMAP, &efi.flags); - } + #ifdef CONFIG_KEYS ++#ifdef CONFIG_CREDP ++ iee_set_cred_session_keyring(new,NULL); ++ iee_set_cred_process_keyring(new,NULL); ++ iee_set_cred_thread_keyring(new,NULL); ++ iee_set_cred_request_key_auth(new,NULL); ++ iee_set_cred_jit_keyring(new,KEY_REQKEY_DEFL_THREAD_KEYRING); ++#else + new->session_keyring = NULL; + new->process_keyring = NULL; + new->thread_keyring = NULL; + new->request_key_auth = NULL; + new->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; + #endif ++#endif -+#ifdef CONFIG_PTP -+void __init efi_memmap_unmap_after_init(void) -+{ -+ if (!efi_enabled(EFI_MEMMAP)) -+ return; -+ -+ if (!(efi.memmap.flags & EFI_MEMMAP_LATE)) { -+ unsigned long size; -+ -+ size = efi.memmap.desc_size * efi.memmap.nr_map; -+ early_iounmap_after_init((__force void __iomem *)efi.memmap.map, size); -+ } else { -+ memunmap(efi.memmap.map); -+ } -+ -+ efi.memmap.map = NULL; -+ clear_bit(EFI_MEMMAP, &efi.flags); -+} + #ifdef CONFIG_SECURITY ++#ifdef CONFIG_CREDP ++ iee_set_cred_security(new,NULL); ++#else + new->security = NULL; + #endif +#endif -+ - /** - * efi_memmap_init_late - Map efi.memmap with memremap() - * @phys_addr: Physical address of the new EFI memory map -diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c -index a5fbb6ed38ae..81428783b9da 100644 ---- a/drivers/tty/serial/earlycon.c -+++ b/drivers/tty/serial/earlycon.c -@@ -40,7 +40,11 @@ static void __iomem * __init earlycon_map(resource_size_t paddr, size_t size) - { - void __iomem *base; - #ifdef CONFIG_FIX_EARLYCON_MEM -+ #ifdef CONFIG_PTP -+ __iee_set_fixmap_pre_init(FIX_EARLYCON_MEM_BASE, paddr & PAGE_MASK, FIXMAP_PAGE_IO); ++ #ifdef CONFIG_CREDP ++ iee_set_cred_ucounts(new, get_ucounts(new->ucounts)); + #else - set_fixmap_io(FIX_EARLYCON_MEM_BASE, paddr & PAGE_MASK); + new->ucounts = get_ucounts(new->ucounts); + #endif - base = (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE); - base += paddr & ~PAGE_MASK; - #else -diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c -index 45b42d8f6453..b71072d6957e 100644 ---- a/drivers/usb/early/ehci-dbgp.c -+++ b/drivers/usb/early/ehci-dbgp.c -@@ -879,7 +879,11 @@ int __init early_dbgp_init(char *s) - * FIXME I don't have the bar size so just guess PAGE_SIZE is more - * than enough. 1K is the biggest I have seen. - */ -+ #ifdef CONFIG_PTP -+ __iee_set_fixmap_pre_init(FIX_DBGP_BASE, bar_val & PAGE_MASK, FIXMAP_PAGE_NOCACHE); + if (!new->ucounts) + goto error; + +@@ -727,8 +908,13 @@ int set_create_files_as(struct cred *new, struct inode *inode) + { + if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid)) + return -EINVAL; ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(new,inode->i_uid); ++ iee_set_cred_fsgid(new,inode->i_gid); + #else - set_fixmap_nocache(FIX_DBGP_BASE, bar_val & PAGE_MASK); + new->fsuid = inode->i_uid; + new->fsgid = inode->i_gid; + #endif - ehci_bar = (void __iomem *)__fix_to_virt(FIX_DBGP_BASE); - ehci_bar += bar_val & ~PAGE_MASK; - dbgp_printk("ehci_bar: %p\n", ehci_bar); -diff --git a/fs/coredump.c b/fs/coredump.c -index 9d235fa14ab9..72be355903ca 100644 ---- a/fs/coredump.c -+++ b/fs/coredump.c -@@ -53,6 +53,10 @@ + return security_kernel_create_files_as(new, inode); + } + EXPORT_SYMBOL(set_create_files_as); +diff --git a/kernel/exit.c b/kernel/exit.c +index 3540b2c9b1b6..e71d3d9290e9 100644 +--- a/kernel/exit.c ++++ b/kernel/exit.c +@@ -74,6 +74,10 @@ + #include + #include + ++#ifdef CONFIG_IEE ++#include ++#endif ++ + /* + * The default value should be high enough to not crash a system that randomly + * crashes its kernel from time to time, but low enough to at least not permit +@@ -560,6 +564,9 @@ static void exit_mm(void) + smp_mb__after_spinlock(); + local_irq_disable(); + current->mm = NULL; ++ #ifdef CONFIG_IEE ++ iee_set_token_pgd(current, NULL); ++ #endif + membarrier_update_current_mm(NULL); + enter_lazy_tlb(mm, current); + local_irq_enable(); +diff --git a/kernel/fork.c b/kernel/fork.c +index 27d605c64b45..9e01499a25a1 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -115,6 +115,11 @@ + #define CREATE_TRACE_POINTS + #include + ++#ifdef CONFIG_IEE ++#include ++#include ++#endif ++ + /* + * Minimum number of threads to boot the kernel + */ +@@ -128,14 +133,14 @@ + /* + * Protected counters by write_lock_irq(&tasklist_lock) + */ +-unsigned long total_forks; /* Handle normal Linux uptimes. */ +-int nr_threads; /* The idle threads do not count.. */ ++unsigned long total_forks; /* Handle normal Linux uptimes. */ ++int nr_threads; /* The idle threads do not count.. */ - #include +-static int max_threads; /* tunable limit on nr_threads */ ++static int max_threads; /* tunable limit on nr_threads */ -+#ifdef CONFIG_CREDP -+#include +-#define NAMED_ARRAY_INDEX(x) [x] = __stringify(x) ++#define NAMED_ARRAY_INDEX(x) [x] = __stringify(x) + +-static const char * const resident_page_types[] = { ++static const char *const resident_page_types[] = { + NAMED_ARRAY_INDEX(MM_FILEPAGES), + NAMED_ARRAY_INDEX(MM_ANONPAGES), + NAMED_ARRAY_INDEX(MM_SWAPENTS), +@@ -144,7 +149,7 @@ static const char * const resident_page_types[] = { + + DEFINE_PER_CPU(unsigned long, process_counts) = 0; + +-__cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */ ++__cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */ + + #ifdef CONFIG_PROVE_RCU + int lockdep_tasklist_lock_is_held(void) +@@ -159,7 +164,7 @@ int nr_processes(void) + int cpu; + int total = 0; + +- for_each_possible_cpu(cpu) ++ for_each_possible_cpu (cpu) + total += per_cpu(process_counts, cpu); + + return total; +@@ -170,7 +175,11 @@ void __weak arch_release_task_struct(struct task_struct *tsk) + } + + #ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR ++#if defined(CONFIG_IEE) || defined(CONFIG_KOI) ++struct kmem_cache *task_struct_cachep; ++#else + static struct kmem_cache *task_struct_cachep; +#endif -+ - static bool dump_vma_snapshot(struct coredump_params *cprm); - static void free_vma_snapshot(struct coredump_params *cprm); -@@ -564,7 +568,11 @@ void do_coredump(const kernel_siginfo_t *siginfo) + static inline struct task_struct *alloc_task_struct_node(int node) + { +@@ -190,7 +199,7 @@ static inline void free_task_struct(struct task_struct *tsk) + * Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a + * kmemcache based allocator. + */ +-# if THREAD_SIZE >= PAGE_SIZE || defined(CONFIG_VMAP_STACK) ++#if THREAD_SIZE >= PAGE_SIZE || defined(CONFIG_VMAP_STACK) + + # ifdef CONFIG_VMAP_STACK + /* +@@ -311,8 +320,8 @@ static int alloc_thread_stack_node(struct task_struct *tsk, int node) + * so memcg accounting is performed manually on assigning/releasing + * stacks to tasks. Drop __GFP_ACCOUNT. */ - if (__get_dumpable(cprm.mm_flags) == SUID_DUMP_ROOT) { - /* Setuid core dump mode */ -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(cred,GLOBAL_ROOT_UID); -+ #else - cred->fsuid = GLOBAL_ROOT_UID; /* Dump root private */ -+ #endif - need_suid_safe = true; - } +- stack = __vmalloc_node_range(THREAD_SIZE, THREAD_ALIGN, +- VMALLOC_START, VMALLOC_END, ++ stack = __vmalloc_node_range(THREAD_SIZE, THREAD_ALIGN, VMALLOC_START, ++ VMALLOC_END, + THREADINFO_GFP & ~__GFP_ACCOUNT, + PAGE_KERNEL, + 0, node, __builtin_return_address(0)); +@@ -410,9 +419,10 @@ static void free_thread_stack(struct task_struct *tsk) -diff --git a/fs/exec.c b/fs/exec.c -index 04fb89656cc3..3689c5f008ba 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -76,6 +76,14 @@ + void thread_stack_cache_init(void) + { +- thread_stack_cache = kmem_cache_create_usercopy("thread_stack", +- THREAD_SIZE, THREAD_SIZE, 0, 0, +- THREAD_SIZE, NULL); ++ thread_stack_cache = ++ kmem_cache_create_usercopy("thread_stack", THREAD_SIZE, ++ THREAD_SIZE, 0, 0, THREAD_SIZE, ++ NULL); + BUG_ON(thread_stack_cache == NULL); + } - #include +@@ -502,7 +512,8 @@ struct vm_area_struct *vm_area_alloc(struct mm_struct *mm) -+#ifdef CONFIG_CREDP -+#include + struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig) + { +- struct vm_area_struct *new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); ++ struct vm_area_struct *new = ++ kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); + + if (!new) + return NULL; +@@ -602,6 +613,10 @@ void put_task_stack(struct task_struct *tsk) + } + #endif + ++#ifdef CONFIG_KOI ++extern s64 koi_offset; +#endif + + void free_task(struct task_struct *tsk) + { + #ifdef CONFIG_SECCOMP +@@ -633,6 +648,21 @@ void free_task(struct task_struct *tsk) + if (dynamic_affinity_enabled()) + sched_prefer_cpus_free(tsk); + #endif +#ifdef CONFIG_IEE -+#include ++ iee_invalidate_token(tsk); ++#ifdef CONFIG_KOI ++ // Free koi stack. ++ unsigned long koi_stack = iee_rw_gate(IEE_READ_KOI_STACK_BASE, tsk); ++ if (koi_stack != 0) ++ free_pages(koi_stack, 2); ++#endif ++#else ++#ifdef CONFIG_KOI ++ struct task_token *token = (struct task_token *)((unsigned long)tsk + koi_offset); ++ memset(token, 0, sizeof(struct task_token)); ++#endif +#endif + - static int bprm_creds_from_file(struct linux_binprm *bprm); + #ifdef CONFIG_QOS_SCHED_SMART_GRID + if (smart_grid_enabled()) + sched_grid_qos_free(tsk); +@@ -657,7 +687,7 @@ static void dup_mm_exe_file(struct mm_struct *mm, struct mm_struct *oldmm) - int suid_dumpable = 0; -@@ -1005,6 +1013,10 @@ static int exec_mmap(struct mm_struct *mm) - if (!IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM)) - local_irq_enable(); - activate_mm(active_mm, mm); -+ #ifdef CONFIG_IEE -+ iee_set_token_mm(tsk, mm); -+ iee_set_token_pgd(tsk, mm->pgd); -+ #endif - if (IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM)) - local_irq_enable(); - lru_gen_add_mm(mm); -@@ -1618,12 +1630,20 @@ static void bprm_fill_uid(struct linux_binprm *bprm, struct file *file) + #ifdef CONFIG_MMU + static __latent_entropy int dup_mmap(struct mm_struct *mm, +- struct mm_struct *oldmm) ++ struct mm_struct *oldmm) + { + struct vm_area_struct *mpnt, *tmp; + int retval; +@@ -773,7 +803,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, + flush_dcache_mmap_lock(mapping); + /* insert tmp into the share list, just after mpnt */ + vma_interval_tree_insert_after(tmp, mpnt, +- &mapping->i_mmap); ++ &mapping->i_mmap); + flush_dcache_mmap_unlock(mapping); + i_mmap_unlock_write(mapping); + } +@@ -842,7 +872,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) + mmap_write_unlock(oldmm); + return 0; + } +-#define mm_alloc_pgd(mm) (0) ++#define mm_alloc_pgd(mm) (0) + #define mm_free_pgd(mm) + #endif /* CONFIG_MMU */ - if (mode & S_ISUID) { - bprm->per_clear |= PER_CLEAR_ON_SETID; -+ #ifdef CONFIG_CREDP -+ iee_set_cred_euid(bprm->cred, vfsuid_into_kuid(vfsuid)); -+ #else - bprm->cred->euid = vfsuid_into_kuid(vfsuid); -+ #endif - } +@@ -850,20 +880,22 @@ static void check_mm(struct mm_struct *mm) + { + int i; - if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { - bprm->per_clear |= PER_CLEAR_ON_SETID; -+ #ifdef CONFIG_CREDP -+ iee_set_cred_egid(bprm->cred, vfsgid_into_kgid(vfsgid)); -+ #else - bprm->cred->egid = vfsgid_into_kgid(vfsgid); -+ #endif +- BUILD_BUG_ON_MSG(ARRAY_SIZE(resident_page_types) != NR_MM_COUNTERS, +- "Please make sure 'struct resident_page_types[]' is updated as well"); ++ BUILD_BUG_ON_MSG( ++ ARRAY_SIZE(resident_page_types) != NR_MM_COUNTERS, ++ "Please make sure 'struct resident_page_types[]' is updated as well"); + + for (i = 0; i < NR_MM_COUNTERS; i++) { + long x = mm_counter_sum(mm, i); + + if (unlikely(x)) +- pr_alert("BUG: Bad rss-counter state mm:%p type:%s val:%ld\n", +- mm, resident_page_types[i], x); ++ pr_alert( ++ "BUG: Bad rss-counter state mm:%p type:%s val:%ld\n", ++ mm, resident_page_types[i], x); } - } -diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c -index 3e724cb7ef01..e32e136e4271 100644 ---- a/fs/nfs/flexfilelayout/flexfilelayout.c -+++ b/fs/nfs/flexfilelayout/flexfilelayout.c -@@ -15,6 +15,10 @@ + if (mm_pgtables_bytes(mm)) + pr_alert("BUG: non-zero pgtables_bytes on freeing mm: %ld\n", +- mm_pgtables_bytes(mm)); ++ mm_pgtables_bytes(mm)); - #include + #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS + VM_BUG_ON_MM(mm->pmd_huge_pte, mm); +@@ -1014,14 +1046,6 @@ void __put_task_struct(struct task_struct *tsk) + } + EXPORT_SYMBOL_GPL(__put_task_struct); -+#ifdef CONFIG_CREDP -+#include -+#endif -+ - #include "flexfilelayout.h" - #include "../nfs4session.h" - #include "../nfs4idmap.h" -@@ -502,8 +506,13 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh, - rc = -ENOMEM; - if (!kcred) - goto out_err_free; -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(kcred,uid); -+ iee_set_cred_fsgid(kcred,gid); -+ #else - kcred->fsuid = uid; - kcred->fsgid = gid; -+ #endif - cred = RCU_INITIALIZER(kcred); +-void __put_task_struct_rcu_cb(struct rcu_head *rhp) +-{ +- struct task_struct *task = container_of(rhp, struct task_struct, rcu); +- +- __put_task_struct(task); +-} +-EXPORT_SYMBOL_GPL(__put_task_struct_rcu_cb); +- + void __init __weak arch_task_cache_init(void) { } - if (lgr->range.iomode == IOMODE_READ) -diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c -index 25a7c771cfd8..b15ab8e33e0e 100644 ---- a/fs/nfs/nfs4idmap.c -+++ b/fs/nfs/nfs4idmap.c -@@ -48,6 +48,10 @@ - #include - #include + /* +@@ -1039,8 +1063,8 @@ static void set_max_threads(unsigned int max_threads_suggested) + if (fls64(nr_pages) + fls64(PAGE_SIZE) > 64) + threads = MAX_THREADS; + else +- threads = div64_u64((u64) nr_pages * (u64) PAGE_SIZE, +- (u64) THREAD_SIZE * 8UL); ++ threads = div64_u64((u64)nr_pages * (u64)PAGE_SIZE, ++ (u64)THREAD_SIZE * 8UL); -+#ifdef CONFIG_CREDP -+#include -+#endif -+ - #include "internal.h" - #include "netns.h" - #include "nfs4idmap.h" -@@ -226,8 +230,13 @@ int nfs_idmap_init(void) - goto failed_reg_legacy; + if (threads > max_threads_suggested) + threads = max_threads_suggested; +@@ -1075,17 +1099,24 @@ void __init fork_init(void) + int i; + #ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR + #ifndef ARCH_MIN_TASKALIGN +-#define ARCH_MIN_TASKALIGN 0 ++#define ARCH_MIN_TASKALIGN 0 + #endif + int align = max_t(int, L1_CACHE_BYTES, ARCH_MIN_TASKALIGN); + unsigned long useroffset, usersize; - set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); -+ #ifdef CONFIG_CREDP -+ iee_set_cred_thread_keyring(cred,keyring); -+ iee_set_cred_jit_keyring(cred,KEY_REQKEY_DEFL_THREAD_KEYRING); + /* create a slab on which task_structs can be allocated */ + task_struct_whitelist(&useroffset, &usersize); ++ #ifdef CONFIG_IEE + task_struct_cachep = kmem_cache_create_usercopy("task_struct", + arch_task_struct_size, align, +- SLAB_PANIC|SLAB_ACCOUNT, ++ SLAB_PANIC|SLAB_ACCOUNT|SLAB_RED_ZONE, + useroffset, usersize, NULL); + #else - cred->thread_keyring = keyring; - cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; ++ task_struct_cachep = ++ kmem_cache_create_usercopy("task_struct", arch_task_struct_size, ++ align, SLAB_PANIC | SLAB_ACCOUNT, ++ useroffset, usersize, NULL); + #endif - id_resolver_cache = cred; - return 0; + #endif -diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c -index e6beaaf4f170..e89385fd81f1 100644 ---- a/fs/nfsd/auth.c -+++ b/fs/nfsd/auth.c -@@ -2,6 +2,9 @@ - /* Copyright (C) 1995, 1996 Olaf Kirch */ + /* do the arch specific task caches init */ +@@ -1093,8 +1124,8 @@ void __init fork_init(void) - #include -+#ifdef CONFIG_CREDP -+#include -+#endif - #include "nfsd.h" - #include "auth.h" + set_max_threads(MAX_THREADS); -@@ -32,22 +35,40 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) - if (!new) - return -ENOMEM; +- init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2; +- init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2; ++ init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads / 2; ++ init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads / 2; + init_task.signal->rlim[RLIMIT_SIGPENDING] = + init_task.signal->rlim[RLIMIT_NPROC]; -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(new,rqstp->rq_cred.cr_uid); -+ iee_set_cred_fsgid(new,rqstp->rq_cred.cr_gid); -+ #else - new->fsuid = rqstp->rq_cred.cr_uid; - new->fsgid = rqstp->rq_cred.cr_gid; -+ #endif +@@ -1107,8 +1138,8 @@ void __init fork_init(void) + set_userns_rlimit_max(&init_user_ns, UCOUNT_RLIMIT_MEMLOCK, RLIM_INFINITY); - rqgi = rqstp->rq_cred.cr_group_info; + #ifdef CONFIG_VMAP_STACK +- cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "fork:vm_stack_cache", +- NULL, free_vm_stack_cache); ++ cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "fork:vm_stack_cache", NULL, ++ free_vm_stack_cache); + #endif - if (flags & NFSEXP_ALLSQUASH) { -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(new,exp->ex_anon_uid); -+ iee_set_cred_fsgid(new,exp->ex_anon_gid); -+ #else - new->fsuid = exp->ex_anon_uid; - new->fsgid = exp->ex_anon_gid; -+ #endif - gi = groups_alloc(0); - if (!gi) - goto oom; - } else if (flags & NFSEXP_ROOTSQUASH) { - if (uid_eq(new->fsuid, GLOBAL_ROOT_UID)) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(new,exp->ex_anon_uid); -+ #else - new->fsuid = exp->ex_anon_uid; -+ #endif - if (gid_eq(new->fsgid, GLOBAL_ROOT_GID)) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsgid(new,exp->ex_anon_gid); -+ #else - new->fsgid = exp->ex_anon_gid; -+ #endif + scs_init(); +@@ -1118,7 +1149,7 @@ void __init fork_init(void) + } - gi = groups_alloc(rqgi->ngroups); - if (!gi) -@@ -67,18 +88,35 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) - } + int __weak arch_dup_task_struct(struct task_struct *dst, +- struct task_struct *src) ++ struct task_struct *src) + { + *dst = *src; + return 0; +@@ -1129,14 +1160,14 @@ void set_task_stack_end_magic(struct task_struct *tsk) + unsigned long *stackend; - if (uid_eq(new->fsuid, INVALID_UID)) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(new,exp->ex_anon_uid); -+ #else - new->fsuid = exp->ex_anon_uid; -+ #endif - if (gid_eq(new->fsgid, INVALID_GID)) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsgid(new,exp->ex_anon_gid); -+ #else - new->fsgid = exp->ex_anon_gid; -+ #endif + stackend = end_of_stack(tsk); +- *stackend = STACK_END_MAGIC; /* for overflow detection */ ++ *stackend = STACK_END_MAGIC; /* for overflow detection */ + } - set_groups(new, gi); - put_group_info(gi); + static bool dup_resvd_task_struct(struct task_struct *dst, + struct task_struct *orig, int node) + { +- dst->_resvd = kzalloc_node(sizeof(struct task_struct_resvd), +- GFP_KERNEL, node); ++ dst->_resvd = kzalloc_node(sizeof(struct task_struct_resvd), GFP_KERNEL, ++ node); + if (!dst->_resvd) + return false; - if (!uid_eq(new->fsuid, GLOBAL_ROOT_UID)) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_effective(new,cap_drop_nfsd_set(new->cap_effective)); -+ #else - new->cap_effective = cap_drop_nfsd_set(new->cap_effective); -+ #endif - else -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_effective(new,cap_raise_nfsd_set(new->cap_effective, -+ new->cap_permitted)); -+ #else - new->cap_effective = cap_raise_nfsd_set(new->cap_effective, - new->cap_permitted); -+ #endif - put_cred(override_creds(new)); - put_cred(new); - return 0; -diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c -index 4039ffcf90ba..6e0dfa01e01e 100644 ---- a/fs/nfsd/nfs4callback.c -+++ b/fs/nfsd/nfs4callback.c -@@ -41,6 +41,9 @@ - #include "trace.h" - #include "xdr4cb.h" - #include "xdr4.h" -+#ifdef CONFIG_CREDP -+#include -+#endif +@@ -1309,7 +1340,7 @@ static void mm_init_uprobes_state(struct mm_struct *mm) + } - #define NFSDDBG_FACILITY NFSDDBG_PROC + static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p, +- struct user_namespace *user_ns) ++ struct user_namespace *user_ns) + { + mt_init_flags(&mm->mm_mt, MM_MT_FLAGS); + mt_set_external_lock(&mm->mm_mt, &mm->mmap_lock); +@@ -1426,8 +1457,8 @@ EXPORT_SYMBOL_GPL(mmput); + #ifdef CONFIG_MMU + static void mmput_async_fn(struct work_struct *work) + { +- struct mm_struct *mm = container_of(work, struct mm_struct, +- async_put_work); ++ struct mm_struct *mm = ++ container_of(work, struct mm_struct, async_put_work); -@@ -946,8 +949,13 @@ static const struct cred *get_backchannel_cred(struct nfs4_client *clp, struct r - if (!kcred) - return NULL; + __mmput(mm); + } +@@ -1603,13 +1634,12 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) + struct mm_struct *mm; + int err; -- kcred->fsuid = ses->se_cb_sec.uid; -- kcred->fsgid = ses->se_cb_sec.gid; -+ #ifdef CONFIG_CREDP -+ iee_set_cred_uid(kcred,ses->se_cb_sec.uid); -+ iee_set_cred_gid(kcred,ses->se_cb_sec.gid); -+ #else -+ kcred->uid = ses->se_cb_sec.uid; -+ kcred->gid = ses->se_cb_sec.gid; -+ #endif - return kcred; +- err = down_read_killable(&task->signal->exec_update_lock); ++ err = down_read_killable(&task->signal->exec_update_lock); + if (err) + return ERR_PTR(err); + + mm = get_task_mm(task); +- if (mm && mm != current->mm && +- !ptrace_may_access(task, mode)) { ++ if (mm && mm != current->mm && !ptrace_may_access(task, mode)) { + mmput(mm); + mm = ERR_PTR(-EACCES); } +@@ -1632,7 +1662,7 @@ static void complete_vfork_done(struct task_struct *tsk) } -diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c -index 3509e73abe1f..798fe0352841 100644 ---- a/fs/nfsd/nfs4recover.c -+++ b/fs/nfsd/nfs4recover.c -@@ -44,6 +44,10 @@ - #include - #include - -+#ifdef CONFIG_CREDP -+#include -+#endif -+ - #include "nfsd.h" - #include "state.h" - #include "vfs.h" -@@ -78,8 +82,13 @@ nfs4_save_creds(const struct cred **original_creds) - if (!new) - return -ENOMEM; -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(new,GLOBAL_ROOT_UID); -+ iee_set_cred_fsgid(new,GLOBAL_ROOT_GID); -+ #else - new->fsuid = GLOBAL_ROOT_UID; - new->fsgid = GLOBAL_ROOT_GID; -+ #endif - *original_creds = override_creds(new); - put_cred(new); - return 0; -diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c -index 355bf0db3235..6cb276dde4e9 100644 ---- a/fs/nfsd/nfsfh.c -+++ b/fs/nfsd/nfsfh.c -@@ -16,6 +16,10 @@ - #include "auth.h" - #include "trace.h" + static int wait_for_vfork_done(struct task_struct *child, +- struct completion *vfork) ++ struct completion *vfork) + { + unsigned int state = TASK_UNINTERRUPTIBLE|TASK_KILLABLE|TASK_FREEZABLE; + int killed; +@@ -1683,8 +1713,8 @@ static void mm_release(struct task_struct *tsk, struct mm_struct *mm) + * not set up a proper pointer then tough luck. + */ + put_user(0, tsk->clear_child_tid); +- do_futex(tsk->clear_child_tid, FUTEX_WAKE, +- 1, NULL, NULL, 0, 0); ++ do_futex(tsk->clear_child_tid, FUTEX_WAKE, 1, NULL, ++ NULL, 0, 0); + } + tsk->clear_child_tid = NULL; + } +@@ -1768,6 +1798,9 @@ static int copy_mm(unsigned long clone_flags, struct task_struct *tsk) + #endif -+#ifdef CONFIG_CREDP -+#include + tsk->mm = NULL; ++#ifdef CONFIG_IEE ++ iee_set_token_pgd(tsk, NULL); +#endif -+ - #define NFSDDBG_FACILITY NFSDDBG_FH + tsk->active_mm = NULL; + + /* +@@ -1799,6 +1832,9 @@ static int copy_mm(unsigned long clone_flags, struct task_struct *tsk) + } + tsk->mm = mm; ++#ifdef CONFIG_IEE ++ iee_set_token_pgd(tsk, mm->pgd); ++#endif + tsk->active_mm = mm; + sched_mm_cid_fork(tsk); + return 0; +@@ -2016,8 +2052,8 @@ static inline void init_task_pid_links(struct task_struct *task) + INIT_HLIST_NODE(&task->pid_links[type]); + } -@@ -223,9 +227,14 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) - error = nfserrno(-ENOMEM); - goto out; - } -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_effective(new,cap_raise_nfsd_set(new->cap_effective, -+ new->cap_permitted)); -+ #else - new->cap_effective = - cap_raise_nfsd_set(new->cap_effective, - new->cap_permitted); -+ #endif - put_cred(override_creds(new)); - put_cred(new); - } else { -diff --git a/fs/open.c b/fs/open.c -index 54723fceb776..d83901dc50ff 100644 ---- a/fs/open.c -+++ b/fs/open.c -@@ -35,6 +35,11 @@ - #include - #include +-static inline void +-init_task_pid(struct task_struct *task, enum pid_type type, struct pid *pid) ++static inline void init_task_pid(struct task_struct *task, enum pid_type type, ++ struct pid *pid) + { + if (type == PIDTYPE_PID) + task->thread_pid = pid; +@@ -2278,6 +2314,12 @@ static void copy_oom_score_adj(u64 clone_flags, struct task_struct *tsk) + mutex_unlock(&oom_adj_mutex); + } -+#ifdef CONFIG_CREDP -+#include ++#if defined(CONFIG_KOI) && !defined(CONFIG_IEE) ++extern s64 koi_offset; ++extern void koi_init_token(struct task_struct *tsk); +#endif + + - #include "internal.h" - - int do_truncate(struct mnt_idmap *idmap, struct dentry *dentry, -@@ -414,17 +419,34 @@ static const struct cred *access_override_creds(void) - * routine. + #ifdef CONFIG_RV + static void rv_task_fork(struct task_struct *p) + { +@@ -2315,10 +2357,12 @@ __latent_entropy struct task_struct *copy_process( + * Don't allow sharing the root directory with processes in a different + * namespace */ +- if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS)) ++ if ((clone_flags & (CLONE_NEWNS | CLONE_FS)) == ++ (CLONE_NEWNS | CLONE_FS)) + return ERR_PTR(-EINVAL); -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(override_cred,override_cred->uid); -+ iee_set_cred_fsgid(override_cred,override_cred->gid); -+ #else - override_cred->fsuid = override_cred->uid; - override_cred->fsgid = override_cred->gid; -+ #endif - - if (!issecure(SECURE_NO_SETUID_FIXUP)) { - /* Clear the capabilities if we switch to a non-root user */ - kuid_t root_uid = make_kuid(override_cred->user_ns, 0); - if (!uid_eq(override_cred->uid, root_uid)) -+ #ifdef CONFIG_CREDP -+ do { -+ kernel_cap_t tmp_cap = override_cred->cap_effective; -+ tmp_cap.val = 0; -+ iee_set_cred_cap_effective(override_cred, tmp_cap); -+ } while (0); -+ #else - cap_clear(override_cred->cap_effective); -+ #endif - else -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_effective(override_cred,override_cred->cap_permitted); -+ #else - override_cred->cap_effective = - override_cred->cap_permitted; -+ #endif - } +- if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS)) ++ if ((clone_flags & (CLONE_NEWUSER | CLONE_FS)) == ++ (CLONE_NEWUSER | CLONE_FS)) + return ERR_PTR(-EINVAL); /* -@@ -444,7 +466,11 @@ static const struct cred *access_override_creds(void) - * expecting RCU freeing. But normal thread-synchronous - * cred accesses will keep things non-RCY. +@@ -2343,7 +2387,7 @@ __latent_entropy struct task_struct *copy_process( + * from creating siblings. */ -+ #ifdef CONFIG_CREDP -+ iee_set_cred_non_rcu(override_cred,1); -+ #else - override_cred->non_rcu = 1; -+ #endif - - old_cred = override_creds(override_cred); - -diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c -index 033fc0458a3d..2afa31ead2b5 100644 ---- a/fs/overlayfs/dir.c -+++ b/fs/overlayfs/dir.c -@@ -16,6 +16,10 @@ - #include - #include "overlayfs.h" + if ((clone_flags & CLONE_PARENT) && +- current->signal->flags & SIGNAL_UNKILLABLE) ++ current->signal->flags & SIGNAL_UNKILLABLE) + return ERR_PTR(-EINVAL); -+#ifdef CONFIG_CREDP -+#include + /* +@@ -2388,6 +2432,13 @@ __latent_entropy struct task_struct *copy_process( + p = dup_task_struct(current, node); + if (!p) + goto fork_out; ++#ifdef CONFIG_IEE ++ iee_validate_token(p); ++#else ++#ifdef CONFIG_KOI ++ koi_init_token(p); +#endif -+ - static unsigned short ovl_redirect_max = 256; - module_param_named(redirect_max, ovl_redirect_max, ushort, 0644); - MODULE_PARM_DESC(redirect_max, -@@ -593,8 +597,13 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode, - * create a new inode, so just use the ovl mounter's - * fs{u,g}id. - */ -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(override_cred,inode->i_uid); -+ iee_set_cred_fsgid(override_cred,inode->i_gid); -+ #else - override_cred->fsuid = inode->i_uid; - override_cred->fsgid = inode->i_gid; -+ #endif - err = security_dentry_create_files_as(dentry, - attr->mode, &dentry->d_name, old_cred, - override_cred); -diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c -index 2c056d737c27..9ede99ddb04b 100644 ---- a/fs/overlayfs/super.c -+++ b/fs/overlayfs/super.c -@@ -21,6 +21,10 @@ - #include "overlayfs.h" - #include "params.h" - -+#ifdef CONFIG_CREDP -+#include +#endif -+ - MODULE_AUTHOR("Miklos Szeredi "); - MODULE_DESCRIPTION("Overlay filesystem"); - MODULE_LICENSE("GPL"); -@@ -1485,7 +1489,15 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc) - sb->s_export_op = &ovl_export_fid_operations; + p->flags &= ~PF_KTHREAD; + if (args->kthread) + p->flags |= PF_KTHREAD; +@@ -2409,7 +2460,8 @@ __latent_entropy struct task_struct *copy_process( + /* + * Clear TID on mm_release()? + */ +- p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? args->child_tid : NULL; ++ p->clear_child_tid = ++ (clone_flags & CLONE_CHILD_CLEARTID) ? args->child_tid : NULL; - /* Never override disk quota limits or use reserved space */ -+ #ifdef CONFIG_CREDP -+ { -+ kernel_cap_t tmp = cred->cap_effective; -+ cap_lower(tmp, CAP_SYS_RESOURCE); -+ iee_set_cred_cap_effective(cred, tmp); -+ } -+ #else - cap_lower(cred->cap_effective, CAP_SYS_RESOURCE); -+ #endif + ftrace_graph_init_task(p); - sb->s_magic = OVERLAYFS_SUPER_MAGIC; - sb->s_xattr = ofs->config.userxattr ? ovl_user_xattr_handlers : -diff --git a/fs/smb/client/cifs_spnego.c b/fs/smb/client/cifs_spnego.c -index af7849e5974f..4ac2f0e65955 100644 ---- a/fs/smb/client/cifs_spnego.c -+++ b/fs/smb/client/cifs_spnego.c -@@ -18,6 +18,10 @@ - #include "cifs_spnego.h" - #include "cifs_debug.h" - #include "cifsproto.h" -+#ifdef CONFIG_CREDP -+#include -+#endif -+ - static const struct cred *spnego_cred; +@@ -2520,10 +2572,10 @@ __latent_entropy struct task_struct *copy_process( + #endif + #ifdef CONFIG_TRACE_IRQFLAGS + memset(&p->irqtrace, 0, sizeof(p->irqtrace)); +- p->irqtrace.hardirq_disable_ip = _THIS_IP_; +- p->irqtrace.softirq_enable_ip = _THIS_IP_; +- p->softirqs_enabled = 1; +- p->softirq_context = 0; ++ p->irqtrace.hardirq_disable_ip = _THIS_IP_; ++ p->irqtrace.softirq_enable_ip = _THIS_IP_; ++ p->softirqs_enabled = 1; ++ p->softirq_context = 0; + #endif - /* create a new cifs key */ -@@ -212,8 +216,13 @@ init_cifs_spnego(void) - * the results it looks up + p->pagefault_disabled = 0; +@@ -2536,8 +2588,8 @@ __latent_entropy struct task_struct *copy_process( + p->blocked_on = NULL; /* not blocked yet */ + #endif + #ifdef CONFIG_BCACHE +- p->sequential_io = 0; +- p->sequential_io_avg = 0; ++ p->sequential_io = 0; ++ p->sequential_io_avg = 0; + #endif + #ifdef CONFIG_BPF_SYSCALL + RCU_INIT_POINTER(p->bpf_storage, NULL); +@@ -2624,7 +2676,7 @@ __latent_entropy struct task_struct *copy_process( + /* + * sigaltstack should be cleared when sharing the same VM */ - set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); -+ #ifdef CONFIG_CREDP -+ iee_set_cred_thread_keyring(cred,keyring); -+ iee_set_cred_jit_keyring(cred,KEY_REQKEY_DEFL_THREAD_KEYRING); -+ #else - cred->thread_keyring = keyring; - cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; -+ #endif - spnego_cred = cred; - - cifs_dbg(FYI, "cifs spnego keyring: %d\n", key_serial(keyring)); -diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c -index f5b6df82e857..9f0ff045836d 100644 ---- a/fs/smb/client/cifsacl.c -+++ b/fs/smb/client/cifsacl.c -@@ -26,6 +26,10 @@ - #include "cifs_fs_sb.h" - #include "cifs_unicode.h" +- if ((clone_flags & (CLONE_VM|CLONE_VFORK)) == CLONE_VM) ++ if ((clone_flags & (CLONE_VM | CLONE_VFORK)) == CLONE_VM) + sas_ss_reset(p); -+#ifdef CONFIG_CREDP -+#include -+#endif -+ - /* security id for everyone/world system group */ - static const struct cifs_sid sid_everyone = { - 1, 1, {0, 0, 0, 0, 0, 1}, {0} }; -@@ -491,8 +495,13 @@ init_cifs_idmap(void) - /* instruct request_key() to use this special keyring as a cache for - * the results it looks up */ - set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); -+ #ifdef CONFIG_CREDP -+ iee_set_cred_thread_keyring(cred,keyring); -+ iee_set_cred_jit_keyring(cred,KEY_REQKEY_DEFL_THREAD_KEYRING); -+ #else - cred->thread_keyring = keyring; - cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; -+ #endif - root_cred = cred; + /* +@@ -2703,7 +2755,7 @@ __latent_entropy struct task_struct *copy_process( + write_lock_irq(&tasklist_lock); - cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring)); -diff --git a/include/asm-generic/early_ioremap.h b/include/asm-generic/early_ioremap.h -index 9d0479f50f97..f501e0f965f8 100644 ---- a/include/asm-generic/early_ioremap.h -+++ b/include/asm-generic/early_ioremap.h -@@ -17,6 +17,9 @@ extern void *early_memremap_ro(resource_size_t phys_addr, - extern void *early_memremap_prot(resource_size_t phys_addr, - unsigned long size, unsigned long prot_val); - extern void early_iounmap(void __iomem *addr, unsigned long size); -+#ifdef CONFIG_PTP -+extern void early_iounmap_after_init(void __iomem *addr, unsigned long size); -+#endif - extern void early_memunmap(void *addr, unsigned long size); + /* CLONE_PARENT re-uses the old parent */ +- if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) { ++ if (clone_flags & (CLONE_PARENT | CLONE_THREAD)) { + p->real_parent = current->real_parent; + p->parent_exec_id = current->parent_exec_id; + if (clone_flags & CLONE_THREAD) +@@ -2767,8 +2819,9 @@ __latent_entropy struct task_struct *copy_process( + * tasklist_lock with adding child to the process tree + * for propagate_has_child_subreaper optimization. + */ +- p->signal->has_child_subreaper = p->real_parent->signal->has_child_subreaper || +- p->real_parent->signal->is_child_subreaper; ++ p->signal->has_child_subreaper = ++ p->real_parent->signal->has_child_subreaper || ++ p->real_parent->signal->is_child_subreaper; + list_add_tail(&p->sibling, &p->real_parent->children); + list_add_tail_rcu(&p->tasks, &init_task.tasks); + attach_pid(p, PIDTYPE_TGID); +@@ -2919,8 +2972,8 @@ struct task_struct * __init fork_idle(int cpu) + */ + struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node) + { +- unsigned long flags = CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD| +- CLONE_IO; ++ unsigned long flags = CLONE_FS | CLONE_FILES | CLONE_SIGHAND | ++ CLONE_THREAD | CLONE_IO; + struct kernel_clone_args args = { + .flags = ((lower_32_bits(flags) | CLONE_VM | + CLONE_UNTRACED) & ~CSIGNAL), +@@ -3084,8 +3137,8 @@ SYSCALL_DEFINE0(fork) + SYSCALL_DEFINE0(vfork) + { + struct kernel_clone_args args = { +- .flags = CLONE_VFORK | CLONE_VM, +- .exit_signal = SIGCHLD, ++ .flags = CLONE_VFORK | CLONE_VM, ++ .exit_signal = SIGCHLD, + }; - #if defined(CONFIG_GENERIC_EARLY_IOREMAP) && defined(CONFIG_MMU) -diff --git a/include/asm-generic/fixmap.h b/include/asm-generic/fixmap.h -index 8cc7b09c1bc7..83158589a545 100644 ---- a/include/asm-generic/fixmap.h -+++ b/include/asm-generic/fixmap.h -@@ -70,6 +70,24 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr) - __set_fixmap(idx, 0, FIXMAP_PAGE_CLEAR) + return kernel_clone(&args); +@@ -3095,35 +3148,30 @@ SYSCALL_DEFINE0(vfork) + #ifdef __ARCH_WANT_SYS_CLONE + #ifdef CONFIG_CLONE_BACKWARDS + SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, +- int __user *, parent_tidptr, +- unsigned long, tls, +- int __user *, child_tidptr) ++ int __user *, parent_tidptr, unsigned long, tls, int __user *, ++ child_tidptr) + #elif defined(CONFIG_CLONE_BACKWARDS2) + SYSCALL_DEFINE5(clone, unsigned long, newsp, unsigned long, clone_flags, +- int __user *, parent_tidptr, +- int __user *, child_tidptr, +- unsigned long, tls) +-#elif defined(CONFIG_CLONE_BACKWARDS3) +-SYSCALL_DEFINE6(clone, unsigned long, clone_flags, unsigned long, newsp, +- int, stack_size, +- int __user *, parent_tidptr, +- int __user *, child_tidptr, ++ int __user *, parent_tidptr, int __user *, child_tidptr, + unsigned long, tls) ++#elif defined(CONFIG_CLONE_BACKWARDS3) ++SYSCALL_DEFINE6(clone, unsigned long, clone_flags, unsigned long, newsp, int, ++ stack_size, int __user *, parent_tidptr, int __user *, ++ child_tidptr, unsigned long, tls) + #else + SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, +- int __user *, parent_tidptr, +- int __user *, child_tidptr, +- unsigned long, tls) ++ int __user *, parent_tidptr, int __user *, child_tidptr, ++ unsigned long, tls) #endif + { + struct kernel_clone_args args = { +- .flags = (lower_32_bits(clone_flags) & ~CSIGNAL), +- .pidfd = parent_tidptr, +- .child_tid = child_tidptr, +- .parent_tid = parent_tidptr, +- .exit_signal = (lower_32_bits(clone_flags) & CSIGNAL), +- .stack = newsp, +- .tls = tls, ++ .flags = (lower_32_bits(clone_flags) & ~CSIGNAL), ++ .pidfd = parent_tidptr, ++ .child_tid = child_tidptr, ++ .parent_tid = parent_tidptr, ++ .exit_signal = (lower_32_bits(clone_flags) & CSIGNAL), ++ .stack = newsp, ++ .tls = tls, + }; -+#ifdef CONFIG_PTP -+#ifndef clear_fixmap_init -+#define clear_fixmap_init(idx) \ -+ __iee_set_fixmap_pre_init(idx, 0, FIXMAP_PAGE_CLEAR) -+#endif -+ -+#define __iee_set_fixmap_offset_pre_init(idx, phys, flags) \ -+({ \ -+ unsigned long ________addr; \ -+ __iee_set_fixmap_pre_init(idx, phys, flags); \ -+ ________addr = fix_to_virt(idx) + ((phys) & (PAGE_SIZE - 1)); \ -+ ________addr; \ -+}) -+ -+#define iee_set_fixmap_offset_pre_init(idx, phys) \ -+ __iee_set_fixmap_offset_pre_init(idx, phys, FIXMAP_PAGE_NORMAL) -+#endif -+ - /* Return a pointer with offset calculated */ - #define __set_fixmap_offset(idx, phys, flags) \ - ({ \ -diff --git a/include/asm-generic/pgalloc.h b/include/asm-generic/pgalloc.h -index c75d4a753849..506ff9662e02 100644 ---- a/include/asm-generic/pgalloc.h -+++ b/include/asm-generic/pgalloc.h -@@ -7,6 +7,10 @@ - #define GFP_PGTABLE_KERNEL (GFP_KERNEL | __GFP_ZERO) - #define GFP_PGTABLE_USER (GFP_PGTABLE_KERNEL | __GFP_ACCOUNT) + return kernel_clone(&args); +@@ -3179,21 +3227,21 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs, + return -EINVAL; -+#ifdef CONFIG_PTP -+#include -+#endif -+ - /** - * __pte_alloc_one_kernel - allocate memory for a PTE-level kernel page table - * @mm: the mm_struct of the current context -@@ -23,6 +27,13 @@ static inline pte_t *__pte_alloc_one_kernel(struct mm_struct *mm) + *kargs = (struct kernel_clone_args){ +- .flags = args.flags, +- .pidfd = u64_to_user_ptr(args.pidfd), +- .child_tid = u64_to_user_ptr(args.child_tid), +- .parent_tid = u64_to_user_ptr(args.parent_tid), +- .exit_signal = args.exit_signal, +- .stack = args.stack, +- .stack_size = args.stack_size, +- .tls = args.tls, +- .set_tid_size = args.set_tid_size, +- .cgroup = args.cgroup, ++ .flags = args.flags, ++ .pidfd = u64_to_user_ptr(args.pidfd), ++ .child_tid = u64_to_user_ptr(args.child_tid), ++ .parent_tid = u64_to_user_ptr(args.parent_tid), ++ .exit_signal = args.exit_signal, ++ .stack = args.stack, ++ .stack_size = args.stack_size, ++ .tls = args.tls, ++ .set_tid_size = args.set_tid_size, ++ .cgroup = args.cgroup, + }; - if (!ptdesc) - return NULL; -+ -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr = __phys_to_iee(__pa(ptdesc_address(ptdesc))); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)ptdesc_address(ptdesc)); -+ #endif -+ - return ptdesc_address(ptdesc); - } + if (args.set_tid && +- copy_from_user(kset_tid, u64_to_user_ptr(args.set_tid), +- (kargs->set_tid_size * sizeof(pid_t)))) ++ copy_from_user(kset_tid, u64_to_user_ptr(args.set_tid), ++ (kargs->set_tid_size * sizeof(pid_t)))) + return -EFAULT; -@@ -46,6 +57,11 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm) - */ - static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) - { -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr = __phys_to_iee(__pa(pte)); -+ set_iee_page_invalid(iee_addr); -+ iee_set_logical_mem_rw((unsigned long)pte); -+ #endif - pagetable_free(virt_to_ptdesc(pte)); + kargs->set_tid = kset_tid; +@@ -3288,7 +3336,8 @@ SYSCALL_DEFINE2(clone3, struct clone_args __user *, uargs, size_t, size) } + #endif -@@ -73,6 +89,13 @@ static inline pgtable_t __pte_alloc_one(struct mm_struct *mm, gfp_t gfp) - return NULL; +-void walk_process_tree(struct task_struct *top, proc_visitor visitor, void *data) ++void walk_process_tree(struct task_struct *top, proc_visitor visitor, ++ void *data) + { + struct task_struct *leader, *parent, *child; + int res; +@@ -3296,8 +3345,8 @@ void walk_process_tree(struct task_struct *top, proc_visitor visitor, void *data + read_lock(&tasklist_lock); + leader = top = top->group_leader; + down: +- for_each_thread(leader, parent) { +- list_for_each_entry(child, &parent->children, sibling) { ++ for_each_thread (leader, parent) { ++ list_for_each_entry (child, &parent->children, sibling) { + res = visitor(child, data); + if (res) { + if (res < 0) +@@ -3305,8 +3354,7 @@ void walk_process_tree(struct task_struct *top, proc_visitor visitor, void *data + leader = child; + goto down; + } +-up: +- ; ++ up:; + } } -+ #ifdef CONFIG_PTP -+ pte_t *pte = (pte_t *)page_address(ptdesc_page(ptdesc)); -+ unsigned long iee_addr = __phys_to_iee(__pa(pte)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)pte); -+ #endif -+ - return ptdesc_page(ptdesc); +@@ -3383,11 +3431,11 @@ void __init proc_caches_init(void) + */ + static int check_unshare_flags(unsigned long unshare_flags) + { +- if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND| +- CLONE_VM|CLONE_FILES|CLONE_SYSVSEM| +- CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET| +- CLONE_NEWUSER|CLONE_NEWPID|CLONE_NEWCGROUP| +- CLONE_NEWTIME)) ++ if (unshare_flags & ++ ~(CLONE_THREAD | CLONE_FS | CLONE_NEWNS | CLONE_SIGHAND | CLONE_VM | ++ CLONE_FILES | CLONE_SYSVSEM | CLONE_NEWUTS | CLONE_NEWIPC | ++ CLONE_NEWNET | CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWCGROUP | ++ CLONE_NEWTIME)) + return -EINVAL; + /* + * Not implemented, but pretend it works if there is nothing +@@ -3498,7 +3546,7 @@ int ksys_unshare(unsigned long unshare_flags) + * to a new ipc namespace, the semaphore arrays from the old + * namespace are unreachable. + */ +- if (unshare_flags & (CLONE_NEWIPC|CLONE_SYSVSEM)) ++ if (unshare_flags & (CLONE_NEWIPC | CLONE_SYSVSEM)) + do_sysvsem = 1; + err = unshare_fs(unshare_flags, &new_fs); + if (err) +@@ -3509,8 +3557,8 @@ int ksys_unshare(unsigned long unshare_flags) + err = unshare_userns(unshare_flags, &new_cred); + if (err) + goto bad_unshare_cleanup_fd; +- err = unshare_nsproxy_namespaces(unshare_flags, &new_nsproxy, +- new_cred, new_fs); ++ err = unshare_nsproxy_namespaces(unshare_flags, &new_nsproxy, new_cred, ++ new_fs); + if (err) + goto bad_unshare_cleanup_cred; + +@@ -3607,8 +3655,8 @@ int unshare_files(void) + return 0; } -@@ -103,9 +126,20 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm) - */ - static inline void pte_free(struct mm_struct *mm, struct page *pte_page) +-int sysctl_max_threads(struct ctl_table *table, int write, +- void *buffer, size_t *lenp, loff_t *ppos) ++int sysctl_max_threads(struct ctl_table *table, int write, void *buffer, ++ size_t *lenp, loff_t *ppos) + { + struct ctl_table t; + int ret; +diff --git a/kernel/groups.c b/kernel/groups.c +index 9b43da22647d..8045812e8a3c 100644 +--- a/kernel/groups.c ++++ b/kernel/groups.c +@@ -11,6 +11,9 @@ + #include + #include + #include ++#ifdef CONFIG_CREDP ++#include ++#endif + + struct group_info *groups_alloc(int gidsetsize) { -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr; -+ #endif -+ - struct ptdesc *ptdesc = page_ptdesc(pte_page); - - pagetable_pte_dtor(ptdesc); -+ -+ #ifdef CONFIG_PTP -+ iee_addr = __phys_to_iee(__pa(page_address(pte_page))); -+ set_iee_page_invalid(iee_addr); -+ iee_set_logical_mem_rw((unsigned long)page_address(pte_page)); +@@ -119,7 +122,11 @@ void set_groups(struct cred *new, struct group_info *group_info) + { + put_group_info(new->group_info); + get_group_info(group_info); ++ #ifdef CONFIG_CREDP ++ iee_set_cred_group_info(new,group_info); ++ #else + new->group_info = group_info; + #endif -+ - pagetable_free(ptdesc); } -@@ -145,10 +179,21 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) - #ifndef __HAVE_ARCH_PMD_FREE - static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) - { -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr; -+ #endif -+ - struct ptdesc *ptdesc = virt_to_ptdesc(pmd); + EXPORT_SYMBOL(set_groups); +diff --git a/kernel/kthread.c b/kernel/kthread.c +index 980e6b325b7d..4208d4740ceb 100644 +--- a/kernel/kthread.c ++++ b/kernel/kthread.c +@@ -30,6 +30,10 @@ + #include + #include - BUG_ON((unsigned long)pmd & (PAGE_SIZE-1)); - pagetable_pmd_dtor(ptdesc); -+ -+ #ifdef CONFIG_PTP -+ iee_addr = __phys_to_iee(__pa(pmd)); -+ set_iee_page_invalid(iee_addr); -+ iee_set_logical_mem_rw((unsigned long)pmd); -+ #endif ++#ifdef CONFIG_IEE ++#include ++#endif + - pagetable_free(ptdesc); - } - #endif -@@ -190,7 +235,16 @@ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) - static inline void __pud_free(struct mm_struct *mm, pud_t *pud) - { -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr; + static DEFINE_SPINLOCK(kthread_create_lock); + static LIST_HEAD(kthread_create_list); +@@ -1457,6 +1461,9 @@ void kthread_use_mm(struct mm_struct *mm) + tsk->active_mm = mm; + tsk->mm = mm; + membarrier_update_current_mm(mm); ++ #ifdef CONFIG_IEE ++ iee_set_token_pgd(tsk, mm->pgd); + #endif -+ - BUG_ON((unsigned long)pud & (PAGE_SIZE-1)); -+ #ifdef CONFIG_PTP -+ iee_addr = __phys_to_iee(__pa(pud)); -+ set_iee_page_invalid(iee_addr); -+ iee_set_logical_mem_rw((unsigned long)pud); + switch_mm_irqs_off(active_mm, mm, tsk); + local_irq_enable(); + task_unlock(tsk); +@@ -1501,7 +1508,11 @@ void kthread_unuse_mm(struct mm_struct *mm) + local_irq_disable(); + tsk->mm = NULL; + membarrier_update_current_mm(NULL); ++ #ifdef CONFIG_IEE ++ iee_set_token_pgd(tsk, NULL); + #endif - pagetable_free(virt_to_ptdesc(pud)); - } - -diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h -index 200853042fc7..9d733afced53 100644 ---- a/include/asm-generic/vmlinux.lds.h -+++ b/include/asm-generic/vmlinux.lds.h -@@ -346,6 +346,17 @@ - KEEP(*(.dtb.init.rodata)) \ - __dtb_end = .; + mmgrab_lazy_tlb(mm); ++ + /* active_mm is still 'mm' */ + enter_lazy_tlb(mm, tsk); + local_irq_enable(); +diff --git a/kernel/module/main.c b/kernel/module/main.c +index 14a51af2fbea..f810f005d90a 100644 +--- a/kernel/module/main.c ++++ b/kernel/module/main.c +@@ -63,6 +63,10 @@ + #define CREATE_TRACE_POINTS + #include +#ifdef CONFIG_KOI -+#define KOI_DATA() \ -+ . = ALIGN(PAGE_SIZE); \ -+ __koi_data_start = .; \ -+ *(.data..koi) \ -+ . = ALIGN(PAGE_SIZE); \ -+ __koi_data_end = .; -+#else -+#define KOI_DATA() ++#include "asm/koi.h" +#endif + /* - * .data section - */ -@@ -370,8 +381,8 @@ - BRANCH_PROFILE() \ - TRACE_PRINTKS() \ - BPF_RAW_TP() \ -- TRACEPOINT_STR() + * Mutex protects: + * 1) List of modules (also safely readable with preempt_disable), +@@ -769,7 +773,11 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, + /* Store the name and taints of the last unloaded module for diagnostic purposes */ + strscpy(last_unloaded_module.name, mod->name, sizeof(last_unloaded_module.name)); + strscpy(last_unloaded_module.taints, module_flags(mod, buf, false), sizeof(last_unloaded_module.taints)); - -+ TRACEPOINT_STR() \ -+ KOI_DATA() - /* - * Data section helpers - */ -@@ -1093,6 +1104,14 @@ - * They will fit only a subset of the architectures - */ - -+#ifdef CONFIG_CREDP -+ #define CRED_DATA \ -+ . = ALIGN(PAGE_SIZE); \ -+ *(.iee.cred) \ -+ . = ALIGN(PAGE_SIZE); -+#else -+ #define CRED_DATA ++#ifdef CONFIG_KOI ++ koi_destroy_pagetable(mod); ++ ++ printk(KERN_ERR "pagetable destroyed\n"); +#endif - - /* - * Writeable data. -@@ -1110,6 +1129,7 @@ - . = ALIGN(PAGE_SIZE); \ - .data : AT(ADDR(.data) - LOAD_OFFSET) { \ - INIT_TASK_DATA(inittask) \ -+ CRED_DATA \ - NOSAVE_DATA \ - PAGE_ALIGNED_DATA(pagealigned) \ - CACHELINE_ALIGNED_DATA(cacheline) \ -diff --git a/include/linux/cred.h b/include/linux/cred.h -index e01c6d094a30..cceb4842b619 100644 ---- a/include/linux/cred.h -+++ b/include/linux/cred.h -@@ -18,6 +18,10 @@ - #include - #include - -+#ifdef CONFIG_CREDP -+#include + free_module(mod); + /* someone could wait for the module in add_unformed_module() */ + wake_up_all(&module_wq); +@@ -2590,6 +2598,11 @@ static noinline int do_init_module(struct module *mod) + module_enable_ro(mod, true); + mod_tree_remove_init(mod); + module_arch_freeing_init(mod); ++#ifdef CONFIG_KOI ++ for_class_mod_mem_type(type, init) { ++ koi_unmap_mem(mod, (unsigned long)mod->mem[type].base, mod->mem[type].size); ++ } +#endif -+ - struct cred; - struct inode; + for_class_mod_mem_type(type, init) { + mod->mem[type].base = NULL; + mod->mem[type].size = 0; +@@ -2636,6 +2649,11 @@ static noinline int do_init_module(struct module *mod) + MODULE_STATE_GOING, mod); + klp_module_going(mod); + ftrace_release_mod(mod); ++#ifdef CONFIG_KOI ++ koi_destroy_pagetable(mod); ++ ++ printk(KERN_ERR "[KOI] pagetable for module: %s destroyed\n", mod->name); ++#endif + free_module(mod); + wake_up_all(&module_wq); -@@ -153,6 +157,22 @@ struct cred { - KABI_RESERVE(4) - } __randomize_layout; +@@ -2840,6 +2858,32 @@ static int early_mod_check(struct load_info *info, int flags) + return err; + } -+#ifdef CONFIG_CREDP -+extern unsigned long long iee_rw_gate(int flag, ...); -+static void iee_set_cred_non_rcu(struct cred *cred, int non_rcu) ++#ifdef CONFIG_KOI ++void shared_variable_dfs(struct mm_struct *ko_mm, pgd_t *ko_pg_dir, struct shared_variable_descriptor *desc, unsigned int *get_val_id, unsigned int *from_id_get_ad, unsigned int i, unsigned long addr) +{ -+ iee_rw_gate(IEE_OP_SET_CRED_NON_RCU,cred,non_rcu); -+ *(int *)(&(((struct rcu_head *)(cred->rcu.func))->next)) = non_rcu; ++ unsigned int j; ++ unsigned int new_desc_num; ++ unsigned long *ptr; ++ for(j=0; iasync_probe_requested = async_probe; ++#ifdef CONFIG_KOI ++ /* ++ * find the shared_vars_section and get the shared var list ++ */ ++ ndx = find_sec(info, ".shared_vars_section"); ++ if (ndx){ ++ koi_create_pagetable(mod); ++ target = NULL; ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) { ++ break; ++ } ++ } ++ rcu_read_unlock(); + ++ if (target == NULL) { ++ printk("[Error] shared_vars_section detected, But mem node for module: %s not found\n", mod->name); ++ koi_destroy_pagetable(mod); ++ goto bug_cleanup; ++ } + - extern void __put_cred(struct cred *); - extern void exit_creds(struct task_struct *); - extern int copy_creds(struct task_struct *, unsigned long); -@@ -189,7 +209,11 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred) - */ - static inline struct cred *get_new_cred_many(struct cred *cred, int nr) - { -+ #ifdef CONFIG_CREDP -+ iee_set_cred_atomic_op_usage(cred, AT_ADD, nr); -+ #else - atomic_long_add(nr, &cred->usage); -+ #endif - return cred; - } ++ ko_mm = target->ko_mm; ++ ko_pg_dir = target->pgdp; ++ ++ desc = (struct shared_variable_descriptor *)info->sechdrs[ndx].sh_addr; ++ ++ num_desc = info->sechdrs[ndx].sh_size / sizeof(struct shared_variable_descriptor); ++ get_val_id = kmalloc(DRIVER_ISOLATION_MAX_VAL, GFP_KERNEL); ++ from_id_get_ad = kmalloc(DRIVER_ISOLATION_MAX_VAL, GFP_KERNEL); ++ ++ for (j = 0; j < num_desc; j++) { ++ unsigned int desc_id = desc[j].id; ++ get_val_id[j] = desc_id; ++ from_id_get_ad[desc_id] = j; ++ } ++ ++ for (i = 0; i < num_desc; i++) { ++ if (desc[i].type == 0) { ++ addr = kallsyms_lookup_name(desc[i].name); ++ koi_copy_pagetable(ko_mm, ko_pg_dir, addr & PAGE_MASK, (addr + desc[i].size + PAGE_SIZE) & PAGE_MASK, 0); ++ shared_variable_dfs(ko_mm, ko_pg_dir, desc, get_val_id, from_id_get_ad, i, addr); ++ } ++ } ++ kfree(get_val_id); ++ kfree(from_id_get_ad); ++ } ++#endif + /* Module is ready to execute: parsing args may do that. */ + after_dashes = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, + -32768, 32767, mod, +diff --git a/kernel/sys.c b/kernel/sys.c +index 44b575990333..fbc47f83af50 100644 +--- a/kernel/sys.c ++++ b/kernel/sys.c +@@ -75,6 +75,10 @@ + #include + #include -@@ -202,7 +226,7 @@ static inline struct cred *get_new_cred_many(struct cred *cred, int nr) - */ - static inline struct cred *get_new_cred(struct cred *cred) - { -- return get_new_cred_many(cred, 1); -+ return get_new_cred_many(cred, 1); // XXXzgc atomic_inc -> get_new_cred_many - } ++#ifdef CONFIG_CREDP ++#include ++#endif ++ + #include "uid16.h" - /** -@@ -224,7 +248,11 @@ static inline const struct cred *get_cred_many(const struct cred *cred, int nr) - struct cred *nonconst_cred = (struct cred *) cred; - if (!cred) - return cred; -+ #ifdef CONFIG_CREDP -+ iee_set_cred_non_rcu(nonconst_cred,0); -+ #else - nonconst_cred->non_rcu = 0; -+ #endif - return get_new_cred_many(nonconst_cred, nr); - } + #ifndef SET_UNALIGN_CTL +@@ -395,7 +399,11 @@ long __sys_setregid(gid_t rgid, gid_t egid) + if (gid_eq(old->gid, krgid) || + gid_eq(old->egid, krgid) || + ns_capable_setid(old->user_ns, CAP_SETGID)) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_gid(new,krgid); ++ #else + new->gid = krgid; ++ #endif + else + goto error; + } +@@ -404,15 +412,27 @@ long __sys_setregid(gid_t rgid, gid_t egid) + gid_eq(old->egid, kegid) || + gid_eq(old->sgid, kegid) || + ns_capable_setid(old->user_ns, CAP_SETGID)) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_egid(new,kegid); ++ #else + new->egid = kegid; ++ #endif + else + goto error; + } -@@ -247,9 +275,19 @@ static inline const struct cred *get_cred_rcu(const struct cred *cred) - struct cred *nonconst_cred = (struct cred *) cred; - if (!cred) - return NULL; + if (rgid != (gid_t) -1 || + (egid != (gid_t) -1 && !gid_eq(kegid, old->gid))) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_sgid(new,new->egid); ++ #else + new->sgid = new->egid; ++ #endif + #ifdef CONFIG_CREDP -+ if (!iee_set_cred_atomic_op_usage(nonconst_cred,AT_INC_NOT_ZERO,0)) -+ return NULL; ++ iee_set_cred_fsgid(new,new->egid); + #else - if (!atomic_long_inc_not_zero(&nonconst_cred->usage)) - return NULL; + new->fsgid = new->egid; + #endif -+ + + retval = security_task_fix_setgid(new, old, LSM_SETID_RE); + if (retval < 0) +@@ -454,9 +474,25 @@ long __sys_setgid(gid_t gid) + + retval = -EPERM; + if (ns_capable_setid(old->user_ns, CAP_SETGID)) ++ #ifdef CONFIG_CREDP ++ { ++ iee_set_cred_fsgid(new,kgid); ++ iee_set_cred_sgid(new,kgid); ++ iee_set_cred_egid(new,kgid); ++ iee_set_cred_gid(new,kgid); ++ } ++ #else + new->gid = new->egid = new->sgid = new->fsgid = kgid; ++ #endif + else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid)) ++ #ifdef CONFIG_CREDP ++ { ++ iee_set_cred_fsgid(new,kgid); ++ iee_set_cred_egid(new,kgid); ++ } ++ #else + new->egid = new->fsgid = kgid; ++ #endif + else + goto error; + +@@ -488,7 +524,11 @@ static int set_user(struct cred *new) + return -EAGAIN; + + free_uid(new->user); + #ifdef CONFIG_CREDP -+ iee_set_cred_non_rcu(nonconst_cred,0); ++ iee_set_cred_user(new,new_user); + #else - nonconst_cred->non_rcu = 0; + new->user = new_user; + #endif - return cred; + return 0; } -@@ -270,8 +308,13 @@ static inline void put_cred_many(const struct cred *_cred, int nr) - struct cred *cred = (struct cred *) _cred; +@@ -549,7 +589,11 @@ long __sys_setreuid(uid_t ruid, uid_t euid) - if (cred) { + retval = -EPERM; + if (ruid != (uid_t) -1) { + #ifdef CONFIG_CREDP -+ if (iee_set_cred_atomic_op_usage(cred,AT_SUB_AND_TEST,nr)) -+ __put_cred(cred); ++ iee_set_cred_uid(new,kruid); + #else - if (atomic_long_sub_and_test(nr, &cred->usage)) - __put_cred(cred); + new->uid = kruid; + #endif + if (!uid_eq(old->uid, kruid) && + !uid_eq(old->euid, kruid) && + !ns_capable_setid(old->user_ns, CAP_SETUID)) +@@ -557,7 +601,11 @@ long __sys_setreuid(uid_t ruid, uid_t euid) } - } - -diff --git a/include/linux/efi.h b/include/linux/efi.h -index 9ed79128458c..970cc4f7068b 100644 ---- a/include/linux/efi.h -+++ b/include/linux/efi.h -@@ -740,6 +740,15 @@ extern int __init __efi_memmap_init(struct efi_memory_map_data *data); - extern int __init efi_memmap_init_early(struct efi_memory_map_data *data); - extern int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size); - extern void __init efi_memmap_unmap(void); -+#ifdef CONFIG_PTP -+extern void __init efi_memmap_unmap_after_init(void); -+#endif -+extern int __init efi_memmap_install(struct efi_memory_map_data *data); -+extern int __init efi_memmap_split_count(efi_memory_desc_t *md, -+ struct range *range); -+extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap, -+ void *buf, struct efi_mem_range *mem); -+extern void __init efi_print_memmap(void); - - #ifdef CONFIG_EFI_ESRT - extern void __init efi_esrt_init(void); -diff --git a/include/linux/iee-func.h b/include/linux/iee-func.h -new file mode 100644 -index 000000000000..79171de67c2a ---- /dev/null -+++ b/include/linux/iee-func.h -@@ -0,0 +1,27 @@ -+#ifndef _LINUX_IEE_FUNC_H -+#define _LINUX_IEE_FUNC_H -+ -+#ifdef CONFIG_IEE -+// Declare the __entry_task. -+__attribute__((aligned(PAGE_SIZE))) DECLARE_PER_CPU(struct task_struct *[PAGE_SIZE/sizeof(struct task_struct *)], __entry_task); -+ -+extern unsigned long long iee_rw_gate(int flag, ...); -+extern u32 get_cpu_asid_bits(void); -+extern unsigned long arm64_mm_context_get(struct mm_struct *mm); -+extern void set_iee_page_valid(unsigned long addr); -+extern void set_iee_page_invalid(unsigned long addr); -+extern void iee_set_logical_mem_ro(unsigned long addr); -+extern void iee_set_logical_mem_rw(unsigned long addr); -+extern void iee_set_token_mm(struct task_struct *tsk, struct mm_struct *mm); -+extern void iee_set_token_pgd(struct task_struct *tsk, pgd_t *pgd); -+extern void iee_init_token(struct task_struct *tsk, void *kernel_stack, void *iee_stack); -+extern void iee_free_token(struct task_struct *tsk); -+extern unsigned long iee_read_token_stack(struct task_struct *tsk); -+extern void iee_set_token_page_valid(void *token, void *new); -+extern void iee_set_token_page_invalid(void *token); -+extern void iee_set_kernel_ppage(unsigned long addr); -+extern void iee_set_kernel_upage(unsigned long addr); -+extern void iee_write_in_byte(void *ptr, u64 data, int length); -+#endif -+ -+#endif -\ No newline at end of file -diff --git a/include/linux/module.h b/include/linux/module.h -index 4db2878d9e42..ef8d51994017 100644 ---- a/include/linux/module.h -+++ b/include/linux/module.h -@@ -606,6 +606,7 @@ struct module { - KABI_RESERVE(2) - KABI_RESERVE(3) - KABI_RESERVE(4) -+ - } ____cacheline_aligned __randomize_layout; - #ifndef MODULE_ARCH_INIT - #define MODULE_ARCH_INIT {} -diff --git a/include/linux/sched.h b/include/linux/sched.h -index f40411aa7b70..297becfbc8e3 100644 ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -773,6 +773,24 @@ struct task_struct_resvd { - struct task_struct *task; - }; -+#if defined(CONFIG_IEE) || defined(CONFIG_KOI) -+struct task_token { -+#ifdef CONFIG_IEE -+ struct mm_struct *mm; /* VA */ -+ pgd_t *pgd; /* Logical VA */ -+ void *iee_stack; /* VA */ -+ bool valid; -+ void *kernel_stack; /* VA */ -+#endif -+#ifdef CONFIG_KOI -+ void *koi_kernel_stack; /* VA */ -+ void *koi_stack; /* VA */ -+ void *koi_stack_base; /* VA */ -+ unsigned long current_ttbr1; -+#endif -+}; -+#endif -+ - struct task_struct { - #ifdef CONFIG_THREAD_INFO_IN_TASK - /* -@@ -795,6 +813,7 @@ struct task_struct { - randomized_struct_fields_start - - void *stack; -+ - refcount_t usage; - /* Per task flags (PF_*), defined further below: */ - unsigned int flags; -diff --git a/init/main.c b/init/main.c -index 803332dd3d90..0f8d6e2744c2 100644 ---- a/init/main.c -+++ b/init/main.c -@@ -102,6 +102,12 @@ - #include - #include - -+#ifdef CONFIG_IEE -+#include -+#include -+#include -+#endif -+ - #include - #include - #include -@@ -112,6 +118,10 @@ + if (euid != (uid_t) -1) { ++ #ifdef CONFIG_CREDP ++ iee_set_cred_euid(new,keuid); ++ #else + new->euid = keuid; ++ #endif + if (!uid_eq(old->uid, keuid) && + !uid_eq(old->euid, keuid) && + !uid_eq(old->suid, keuid) && +@@ -572,8 +620,16 @@ long __sys_setreuid(uid_t ruid, uid_t euid) + } + if (ruid != (uid_t) -1 || + (euid != (uid_t) -1 && !uid_eq(keuid, old->uid))) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_suid(new,new->euid); ++ #else + new->suid = new->euid; ++ #endif ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(new,new->euid); ++ #else + new->fsuid = new->euid; ++ #endif - #include + retval = security_task_fix_setuid(new, old, LSM_SETID_RE); + if (retval < 0) +@@ -626,7 +682,12 @@ long __sys_setuid(uid_t uid) -+#ifdef CONFIG_PTP -+extern void *bm_pte_addr; -+#endif -+ - static int kernel_init(void *); + retval = -EPERM; + if (ns_capable_setid(old->user_ns, CAP_SETUID)) { ++ #ifdef CONFIG_CREDP ++ iee_set_cred_uid(new,kuid); ++ iee_set_cred_suid(new,kuid); ++ #else + new->suid = new->uid = kuid; ++ #endif + if (!uid_eq(kuid, old->uid)) { + retval = set_user(new); + if (retval < 0) +@@ -636,7 +697,12 @@ long __sys_setuid(uid_t uid) + goto error; + } - /* -@@ -880,6 +890,9 @@ void start_kernel(void) - { - char *command_line; - char *after_dashes; -+ #ifdef CONFIG_IEE -+ unsigned int cpu; ++ #ifdef CONFIG_CREDP ++ iee_set_cred_euid(new,kuid); ++ iee_set_cred_fsuid(new,kuid); ++ #else + new->fsuid = new->euid = kuid; + #endif - set_task_stack_end_magic(&init_task); - smp_setup_processor_id(); -@@ -904,6 +917,16 @@ void start_kernel(void) - setup_command_line(command_line); - setup_nr_cpu_ids(); - setup_per_cpu_areas(); -+ #ifdef CONFIG_IEE -+ for_each_possible_cpu(cpu) -+ { -+ // Map the __entry_task to IEE. -+ set_iee_page_valid((unsigned long)__phys_to_iee(__pa(SHIFT_PERCPU_PTR(__entry_task,__per_cpu_offset[cpu])))); -+ // Set the __entry_task of cpu 0 readonly in lm. -+ if(cpu == smp_processor_id()) -+ iee_set_logical_mem_ro((unsigned long)SHIFT_PERCPU_PTR(__entry_task,__per_cpu_offset[cpu])); -+ } + retval = security_task_fix_setuid(new, old, LSM_SETID_ID); + if (retval < 0) +@@ -710,7 +776,11 @@ long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) + return -ENOMEM; + + if (ruid != (uid_t) -1) { ++ #ifdef CONFIG_CREDP ++ iee_set_cred_uid(new,kruid); ++ #else + new->uid = kruid; ++ #endif + if (!uid_eq(kruid, old->uid)) { + retval = set_user(new); + if (retval < 0) +@@ -718,10 +788,22 @@ long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) + } + } + if (euid != (uid_t) -1) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_euid(new,keuid); ++ #else + new->euid = keuid; ++ #endif + if (suid != (uid_t) -1) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_suid(new,ksuid); ++ #else + new->suid = ksuid; ++ #endif ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(new,new->euid); ++ #else + new->fsuid = new->euid; + #endif - smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ - boot_cpu_hotplug_init(); -@@ -1446,6 +1469,9 @@ static int __ref kernel_init(void *unused) - wait_for_completion(&kthreadd_done); + retval = security_task_fix_setuid(new, old, LSM_SETID_RES); + if (retval < 0) +@@ -810,12 +892,29 @@ long __sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid) + return -ENOMEM; - kernel_init_freeable(); -+ #ifdef CONFIG_PTP -+ iee_set_logical_mem_ro((unsigned long)bm_pte_addr); + if (rgid != (gid_t) -1) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_gid(new,krgid); ++ #else + new->gid = krgid; ++ #endif + if (egid != (gid_t) -1) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_egid(new,kegid); ++ #else + new->egid = kegid; ++ #endif + if (sgid != (gid_t) -1) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_sgid(new,ksgid); ++ #else + new->sgid = ksgid; ++ #endif ++ ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsgid(new,new->egid); ++ #else + new->fsgid = new->egid; + #endif - /* need to finish all async __init code before freeing the memory */ - async_synchronize_full(); -@@ -1462,7 +1488,7 @@ static int __ref kernel_init(void *unused) - * to finalize PTI. - */ - pti_finalize(); -- -+ - system_state = SYSTEM_RUNNING; - numa_default_policy(); + retval = security_task_fix_setgid(new, old, LSM_SETID_RES); + if (retval < 0) +@@ -882,7 +981,11 @@ long __sys_setfsuid(uid_t uid) + uid_eq(kuid, old->suid) || uid_eq(kuid, old->fsuid) || + ns_capable_setid(old->user_ns, CAP_SETUID)) { + if (!uid_eq(kuid, old->fsuid)) { ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(new,kuid); ++ #else + new->fsuid = kuid; ++ #endif + if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0) + goto change_okay; + } +@@ -926,7 +1029,11 @@ long __sys_setfsgid(gid_t gid) + gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) || + ns_capable_setid(old->user_ns, CAP_SETGID)) { + if (!gid_eq(kgid, old->fsgid)) { ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsgid(new,kgid); ++ #else + new->fsgid = kgid; ++ #endif + if (security_task_fix_setgid(new,old,LSM_SETID_FS) == 0) + goto change_okay; + } +diff --git a/kernel/umh.c b/kernel/umh.c +index 1b13c5d34624..32f5c88e10bf 100644 +--- a/kernel/umh.c ++++ b/kernel/umh.c +@@ -32,6 +32,10 @@ -diff --git a/kernel/cred.c b/kernel/cred.c -index c033a201c808..2e44530976d5 100644 ---- a/kernel/cred.c -+++ b/kernel/cred.c -@@ -20,6 +20,11 @@ - #include - #include + #include +#ifdef CONFIG_CREDP +#include -+#include +#endif + - #if 0 - #define kdebug(FMT, ...) \ - printk("[%-5.5s%5u] " FMT "\n", \ -@@ -34,6 +39,9 @@ do { \ - #endif + static kernel_cap_t usermodehelper_bset = CAP_FULL_SET; + static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET; + static DEFINE_SPINLOCK(umh_sysctl_lock); +@@ -91,9 +95,15 @@ static int call_usermodehelper_exec_async(void *data) + goto out; - static struct kmem_cache *cred_jar; -+#ifdef CONFIG_CREDP -+static struct kmem_cache *rcu_jar; -+#endif + spin_lock(&umh_sysctl_lock); ++ #ifdef CONFIG_CREDP ++ iee_set_cred_cap_bset(new,cap_intersect(usermodehelper_bset, new->cap_bset)); ++ iee_set_cred_cap_inheritable(new,cap_intersect(usermodehelper_inheritable, ++ new->cap_inheritable)); ++ #else + new->cap_bset = cap_intersect(usermodehelper_bset, new->cap_bset); + new->cap_inheritable = cap_intersect(usermodehelper_inheritable, + new->cap_inheritable); ++ #endif + spin_unlock(&umh_sysctl_lock); + + if (sub_info->init) { +diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c +index 1d8e47bed3f1..9f1921025539 100644 +--- a/kernel/user_namespace.c ++++ b/kernel/user_namespace.c +@@ -22,6 +22,10 @@ + #include + #include - /* init to 2 - one for init_task, one to ensure it is never freed */ - static struct group_info init_groups = { .usage = REFCOUNT_INIT(2) }; -@@ -41,6 +49,32 @@ static struct group_info init_groups = { .usage = REFCOUNT_INIT(2) }; - /* - * The initial credentials for the initial task - */ +#ifdef CONFIG_CREDP -+struct cred init_cred __section(".iee.cred") = { -+ .usage = ATOMIC_INIT(4), -+#ifdef CONFIG_DEBUG_CREDENTIALS -+ .subscribers = ATOMIC_INIT(2), -+ .magic = CRED_MAGIC, -+#endif -+ .uid = GLOBAL_ROOT_UID, -+ .gid = GLOBAL_ROOT_GID, -+ .suid = GLOBAL_ROOT_UID, -+ .sgid = GLOBAL_ROOT_GID, -+ .euid = GLOBAL_ROOT_UID, -+ .egid = GLOBAL_ROOT_GID, -+ .fsuid = GLOBAL_ROOT_UID, -+ .fsgid = GLOBAL_ROOT_GID, -+ .securebits = SECUREBITS_DEFAULT, -+ .cap_inheritable = CAP_EMPTY_SET, -+ .cap_permitted = CAP_FULL_SET, -+ .cap_effective = CAP_FULL_SET, -+ .cap_bset = CAP_FULL_SET, -+ .user = INIT_USER, -+ .user_ns = &init_user_ns, -+ .group_info = &init_groups, -+ .ucounts = &init_ucounts, -+}; -+#else - struct cred init_cred = { - .usage = ATOMIC_INIT(4), - .uid = GLOBAL_ROOT_UID, -@@ -61,13 +95,43 @@ struct cred init_cred = { - .group_info = &init_groups, - .ucounts = &init_ucounts, - }; -+#endif -+ -+static inline void set_cred_subscribers(struct cred *cred, int n) -+{ -+#ifdef CONFIG_DEBUG_CREDENTIALS -+ atomic_set(&cred->subscribers, n); ++#include +#endif -+} + -+static inline int read_cred_subscribers(const struct cred *cred) -+{ -+#ifdef CONFIG_DEBUG_CREDENTIALS -+ return atomic_read(&cred->subscribers); -+#else -+ return 0; + static struct kmem_cache *user_ns_cachep __read_mostly; + static DEFINE_MUTEX(userns_state_mutex); + +@@ -45,6 +49,19 @@ static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns) + /* Start with the same capabilities as init but useless for doing + * anything as the capabilities are bound to the new user namespace. + */ ++ #ifdef CONFIG_CREDP ++ iee_set_cred_securebits(cred,SECUREBITS_DEFAULT); ++ iee_set_cred_cap_inheritable(cred,CAP_EMPTY_SET); ++ iee_set_cred_cap_permitted(cred,CAP_FULL_SET); ++ iee_set_cred_cap_effective(cred,CAP_FULL_SET); ++ iee_set_cred_cap_ambient(cred,CAP_EMPTY_SET); ++ iee_set_cred_cap_bset(cred,CAP_FULL_SET); ++#ifdef CONFIG_KEYS ++ key_put(cred->request_key_auth); ++ iee_set_cred_request_key_auth(cred,NULL); +#endif -+} ++ iee_set_cred_user_ns(cred,user_ns); ++ #else + cred->securebits = SECUREBITS_DEFAULT; + cred->cap_inheritable = CAP_EMPTY_SET; + cred->cap_permitted = CAP_FULL_SET; +@@ -57,6 +74,7 @@ static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns) + #endif + /* tgcred will be cleared in our caller bc CLONE_THREAD won't be set */ + cred->user_ns = user_ns; ++ #endif + } + + static unsigned long enforced_nproc_rlimit(void) +diff --git a/lib/digsig.c b/lib/digsig.c +index 04b5e55ed95f..0a10a459bdaa 100644 +--- a/lib/digsig.c ++++ b/lib/digsig.c +@@ -81,7 +81,11 @@ static int digsig_verify_rsa(struct key *key, + const struct user_key_payload *ukp; + struct pubkey_hdr *pkh; + ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(key)); ++ #else + down_read(&key->sem); ++ #endif + ukp = user_key_payload_locked(key); + + if (!ukp) { +@@ -176,7 +180,11 @@ static int digsig_verify_rsa(struct key *key, + while (--i >= 0) + mpi_free(pkey[i]); + err1: ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + + return err; + } +diff --git a/mm/Kconfig b/mm/Kconfig +index 782c43f08e8f..7706340f189c 100644 +--- a/mm/Kconfig ++++ b/mm/Kconfig +@@ -530,6 +530,11 @@ config NUMA_KEEP_MEMINFO + config MEMORY_ISOLATION + bool + ++# Configs for pgtable isolation ++config PTP ++ depends on IEE ++ def_bool y + -+static inline void alter_cred_subscribers(const struct cred *_cred, int n) -+{ -+#ifdef CONFIG_DEBUG_CREDENTIALS -+ struct cred *cred = (struct cred *) _cred; + # IORESOURCE_SYSTEM_RAM regions in the kernel resource tree that are marked + # IORESOURCE_EXCLUSIVE cannot be mapped to user space, for example, via + # /dev/mem. +diff --git a/mm/damon/ops-common.c b/mm/damon/ops-common.c +index d25d99cb5f2b..2ea51f559d4e 100644 +--- a/mm/damon/ops-common.c ++++ b/mm/damon/ops-common.c +@@ -44,6 +44,7 @@ void damon_ptep_mkold(pte_t *pte, struct vm_area_struct *vma, unsigned long addr + if (!folio) + return; + + -+ atomic_add(n, &cred->subscribers); -+#endif -+} + if (ptep_clear_young_notify(vma, addr, pte)) + folio_set_young(folio); - /* - * The RCU callback to actually dispose of a set of credentials - */ - static void put_cred_rcu(struct rcu_head *rcu) - { -+ #ifdef CONFIG_CREDP -+ struct cred *cred = *(struct cred **)(rcu + 1); +diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c +index 68af76ca8bc9..2789784777dd 100644 +--- a/mm/debug_vm_pgtable.c ++++ b/mm/debug_vm_pgtable.c +@@ -437,7 +437,11 @@ static void __init pmd_huge_tests(struct pgtable_debug_args *args) + * X86 defined pmd_set_huge() verifies that the given + * PMD is not a populated non-leaf entry. + */ ++ #ifdef CONFIG_PTP ++ set_pmd(args->pmdp, __pmd(0)); ++ #else + WRITE_ONCE(*args->pmdp, __pmd(0)); ++ #endif + WARN_ON(!pmd_set_huge(args->pmdp, __pfn_to_phys(args->fixed_pmd_pfn), args->page_prot)); + WARN_ON(!pmd_clear_huge(args->pmdp)); + pmd = READ_ONCE(*args->pmdp); +@@ -457,7 +461,11 @@ static void __init pud_huge_tests(struct pgtable_debug_args *args) + * X86 defined pud_set_huge() verifies that the given + * PUD is not a populated non-leaf entry. + */ ++ #ifdef CONFIG_PTP ++ set_pud(args->pudp, __pud(0)); + #else - struct cred *cred = container_of(rcu, struct cred, rcu); + WRITE_ONCE(*args->pudp, __pud(0)); + #endif + WARN_ON(!pud_set_huge(args->pudp, __pfn_to_phys(args->fixed_pud_pfn), args->page_prot)); + WARN_ON(!pud_clear_huge(args->pudp)); + pud = READ_ONCE(*args->pudp); +@@ -496,6 +504,12 @@ static void __init pud_clear_tests(struct pgtable_debug_args *args) - kdebug("put_cred_rcu(%p)", cred); - -@@ -86,6 +150,9 @@ static void put_cred_rcu(struct rcu_head *rcu) - if (cred->ucounts) - put_ucounts(cred->ucounts); - put_user_ns(cred->user_ns); -+ #ifdef CONFIG_CREDP -+ kmem_cache_free(rcu_jar, (struct rcu_head *)(cred->rcu.func)); + pr_debug("Validating PUD clear\n"); + WARN_ON(pud_none(pud)); ++ pud = __pud(pud_val(pud) | RANDOM_ORVALUE); ++ #ifdef CONFIG_PTP ++ set_pud(args->pudp, pud); ++ #else ++ WRITE_ONCE(*args->pudp, pud); + #endif - kmem_cache_free(cred_jar, cred); - } - -@@ -104,10 +171,22 @@ void __put_cred(struct cred *cred) - BUG_ON(cred == current->cred); - BUG_ON(cred == current->real_cred); + pud_clear(args->pudp); + pud = READ_ONCE(*args->pudp); + WARN_ON(!pud_none(pud)); +@@ -532,6 +546,12 @@ static void __init p4d_clear_tests(struct pgtable_debug_args *args) -+ #ifdef CONFIG_CREDP -+ if (*(int *)(&(((struct rcu_head *)(cred->rcu.func))->next))) + pr_debug("Validating P4D clear\n"); + WARN_ON(p4d_none(p4d)); ++ p4d = __p4d(p4d_val(p4d) | RANDOM_ORVALUE); ++ #ifdef CONFIG_PTP ++ set_p4d(args->p4dp, p4d); + #else - if (cred->non_rcu) ++ WRITE_ONCE(*args->p4dp, p4d); + #endif -+ #ifdef CONFIG_CREDP -+ put_cred_rcu((struct rcu_head *)(cred->rcu.func)); -+ #else - put_cred_rcu(&cred->rcu); -+ #endif - else -+ #ifdef CONFIG_CREDP -+ call_rcu((struct rcu_head *)(cred->rcu.func), put_cred_rcu); -+ #else - call_rcu(&cred->rcu, put_cred_rcu); -+ #endif - } - EXPORT_SYMBOL(__put_cred); + p4d_clear(args->p4dp); + p4d = READ_ONCE(*args->p4dp); + WARN_ON(!p4d_none(p4d)); +@@ -565,6 +585,12 @@ static void __init pgd_clear_tests(struct pgtable_debug_args *args) -@@ -178,7 +257,18 @@ struct cred *cred_alloc_blank(void) - if (!new) - return NULL; + pr_debug("Validating PGD clear\n"); + WARN_ON(pgd_none(pgd)); ++ pgd = __pgd(pgd_val(pgd) | RANDOM_ORVALUE); ++ #ifdef CONFIG_PTP ++ set_pgd(args->pgdp, pgd); ++ #else ++ WRITE_ONCE(*args->pgdp, pgd); ++ #endif + pgd_clear(args->pgdp); + pgd = READ_ONCE(*args->pgdp); + WARN_ON(!pgd_none(pgd)); +@@ -630,6 +656,12 @@ static void __init pmd_clear_tests(struct pgtable_debug_args *args) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_rcu(new,kmem_cache_zalloc(rcu_jar, GFP_KERNEL)); -+ *(struct cred **)(((struct rcu_head *)(new->rcu.func)) + 1) = new; -+ iee_set_cred_atomic_set_usage(new,1); + pr_debug("Validating PMD clear\n"); + WARN_ON(pmd_none(pmd)); ++ pmd = __pmd(pmd_val(pmd) | RANDOM_ORVALUE); ++ #ifdef CONFIG_PTP ++ set_pmd(args->pmdp, pmd); + #else - atomic_long_set(&new->usage, 1); ++ WRITE_ONCE(*args->pmdp, pmd); + #endif + pmd_clear(args->pmdp); + pmd = READ_ONCE(*args->pmdp); + WARN_ON(!pmd_none(pmd)); +diff --git a/mm/early_ioremap.c b/mm/early_ioremap.c +index ce06b2884789..a039c7a50ec5 100644 +--- a/mm/early_ioremap.c ++++ b/mm/early_ioremap.c +@@ -147,7 +147,11 @@ __early_ioremap(resource_size_t phys_addr, unsigned long size, pgprot_t prot) + if (after_paging_init) + __late_set_fixmap(idx, phys_addr, prot); + else ++ #ifdef CONFIG_PTP ++ __iee_set_fixmap_pre_init(idx, phys_addr, prot); ++ #else + __early_set_fixmap(idx, phys_addr, prot); ++ #endif + phys_addr += PAGE_SIZE; + --idx; + --nrpages; +@@ -199,13 +203,66 @@ void __init early_iounmap(void __iomem *addr, unsigned long size) + if (after_paging_init) + __late_clear_fixmap(idx); + else ++ #ifdef CONFIG_PTP ++ __iee_set_fixmap_pre_init(idx, 0, FIXMAP_PAGE_CLEAR); ++ #else + __early_set_fixmap(idx, 0, FIXMAP_PAGE_CLEAR); ++ #endif + --idx; + --nrpages; + } + prev_map[slot] = NULL; + } + ++#ifdef CONFIG_PTP ++void __init early_iounmap_after_init(void __iomem *addr, unsigned long size) ++{ ++ unsigned long virt_addr; ++ unsigned long offset; ++ unsigned int nrpages; ++ enum fixed_addresses idx; ++ int i, slot; + -+ #ifdef CONFIG_DEBUG_CREDENTIALS -+ new->magic = CRED_MAGIC; -+ #endif ++ slot = -1; ++ for (i = 0; i < FIX_BTMAPS_SLOTS; i++) { ++ if (prev_map[i] == addr) { ++ slot = i; ++ break; ++ } ++ } + - if (security_cred_alloc_blank(new, GFP_KERNEL_ACCOUNT) < 0) - goto error; - -@@ -213,13 +303,25 @@ struct cred *prepare_creds(void) - if (!new) - return NULL; - -+ #ifdef CONFIG_CREDP -+ iee_set_cred_rcu(new,kmem_cache_alloc(rcu_jar, GFP_KERNEL)); -+ *(struct cred **)(((struct rcu_head *)(new->rcu.func)) + 1) = new; -+ #endif ++ if (WARN(slot < 0, "early_iounmap(%p, %08lx) not found slot\n", ++ addr, size)) ++ return; + - kdebug("prepare_creds() alloc %p", new); ++ if (WARN(prev_size[slot] != size, ++ "early_iounmap(%p, %08lx) [%d] size not consistent %08lx\n", ++ addr, size, slot, prev_size[slot])) ++ return; ++ ++ WARN(early_ioremap_debug, "early_iounmap(%p, %08lx) [%d]\n", ++ addr, size, slot); ++ ++ virt_addr = (unsigned long)addr; ++ if (WARN_ON(virt_addr < fix_to_virt(FIX_BTMAP_BEGIN))) ++ return; ++ ++ offset = offset_in_page(virt_addr); ++ nrpages = PAGE_ALIGN(offset + size) >> PAGE_SHIFT; ++ ++ idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot; ++ while (nrpages > 0) { ++ if (after_paging_init) ++ __late_clear_fixmap(idx); ++ else ++ __early_set_fixmap(idx, 0, FIXMAP_PAGE_CLEAR); ++ --idx; ++ --nrpages; ++ } ++ prev_map[slot] = NULL; ++} ++#endif ++ + /* Remap an IO device */ + void __init __iomem * + early_ioremap(resource_size_t phys_addr, unsigned long size) +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index eafe846739f4..406ee5134569 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -40,6 +40,10 @@ + #include + #include - old = task->cred; -+ #ifdef CONFIG_CREDP -+ iee_copy_cred(old,new); ++#ifdef CONFIG_PTP ++#include ++#endif + -+ iee_set_cred_non_rcu(new,0); -+ iee_set_cred_atomic_set_usage(new,1); -+ #else - memcpy(new, old, sizeof(struct cred)); + #include + #include + #include "internal.h" +@@ -2551,7 +2555,8 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma, + old_pmd = pmdp_huge_clear_flush(vma, haddr, pmd); - new->non_rcu = 0; - atomic_long_set(&new->usage, 1); -+ #endif - get_group_info(new->group_info); - get_uid(new->user); - get_user_ns(new->user_ns); -@@ -232,10 +334,18 @@ struct cred *prepare_creds(void) - #endif + pgtable = pgtable_trans_huge_withdraw(mm, pmd); +- pmd_populate(mm, &_pmd, pgtable); ++ //pmd_populate(mm, &_pmd, pgtable); ++ _pmd = __pmd(__phys_to_pmd_val(page_to_phys(pgtable)) | PMD_TYPE_TABLE); - #ifdef CONFIG_SECURITY -+#ifdef CONFIG_CREDP -+ iee_set_cred_security(new,NULL); -+#else - new->security = NULL; -+#endif - #endif + pte = pte_offset_map(&_pmd, haddr); + VM_BUG_ON(!pte); +@@ -2721,7 +2726,8 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, + * This's critical for some architectures (Power). + */ + pgtable = pgtable_trans_huge_withdraw(mm, pmd); +- pmd_populate(mm, &_pmd, pgtable); ++ //pmd_populate(mm, &_pmd, pgtable); ++ _pmd = __pmd(__phys_to_pmd_val(page_to_phys(pgtable)) | PMD_TYPE_TABLE); -+ #ifdef CONFIG_CREDP -+ iee_set_cred_ucounts(new, get_ucounts(new->ucounts)); -+ #else - new->ucounts = get_ucounts(new->ucounts); -+ #endif - if (!new->ucounts) - goto error; + pte = pte_offset_map(&_pmd, haddr); + VM_BUG_ON(!pte); +diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c +index 149ab629855c..93b6a7ebde82 100644 +--- a/mm/hugetlb_vmemmap.c ++++ b/mm/hugetlb_vmemmap.c +@@ -83,7 +83,7 @@ static int split_vmemmap_huge_pmd(pmd_t *pmd, unsigned long start) -@@ -265,15 +375,30 @@ struct cred *prepare_exec_creds(void) - #ifdef CONFIG_KEYS - /* newly exec'd tasks don't get a thread keyring */ - key_put(new->thread_keyring); -+ #ifdef CONFIG_CREDP -+ iee_set_cred_thread_keyring(new,NULL); -+ #else - new->thread_keyring = NULL; -+ #endif + if (!head) + return 0; +- ++ + pgtable = pte_alloc_one_kernel(&init_mm); + if (!pgtable) + return -ENOMEM; +diff --git a/mm/init-mm.c b/mm/init-mm.c +index 24c809379274..4539eb8e7cce 100644 +--- a/mm/init-mm.c ++++ b/mm/init-mm.c +@@ -55,3 +55,19 @@ void setup_initial_init_mm(void *start_code, void *end_code, + init_mm.end_data = (unsigned long)end_data; + init_mm.brk = (unsigned long)brk; + } ++ ++#ifdef CONFIG_KOI ++/* ++ * This is used to init ko_mm when creating pgtable for a ko to be isolated ++ * the ko_mm belongs to a specific ko, pgdp is allocated by koi_pgd_alloc ++ */ ++void init_ko_mm(struct mm_struct *ko_mm, pgd_t *pgdp) { ++ ko_mm->pgd = pgdp; ++ ko_mm->mm_users = (atomic_t)ATOMIC_INIT(2); ++ ko_mm->mm_count = (atomic_t)ATOMIC_INIT(1); ++ ko_mm->mmap_lock = (struct rw_semaphore)__RWSEM_INITIALIZER(ko_mm->mmap_lock); ++ ko_mm->page_table_lock = __SPIN_LOCK_UNLOCKED(ko_mm.page_table_lock); ++ ko_mm->arg_lock = __SPIN_LOCK_UNLOCKED(ko_mm->arg_lock); ++ ko_mm->mmlist = (struct list_head)LIST_HEAD_INIT(ko_mm->mmlist); ++} ++#endif +diff --git a/mm/memory.c b/mm/memory.c +index e248b8338417..e291818c8ed0 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -80,6 +80,11 @@ + #include + #include - /* inherit the session keyring; new process keyring */ - key_put(new->process_keyring); -+ #ifdef CONFIG_CREDP -+ iee_set_cred_process_keyring(new,NULL); -+ #else - new->process_keyring = NULL; -+ #endif - #endif ++#ifdef CONFIG_PTP ++#include ++extern void iee_copy_pte_range(pte_t *new_dst, pte_t *old_dst, pte_t *src_pte, struct vm_area_struct *src_vma, unsigned long dst_vm_flags, pte_t *end_pte); ++#endif ++ + #include -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(new,new->euid); -+ iee_set_cred_suid(new,new->euid); -+ iee_set_cred_fsgid(new,new->egid); -+ iee_set_cred_sgid(new,new->egid); -+ #else - new->suid = new->fsuid = new->euid; - new->sgid = new->fsgid = new->egid; -+ #endif + #include +@@ -809,7 +814,11 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, + /* Mark the swap entry as shared. */ + if (pte_swp_exclusive(orig_pte)) { + pte = pte_swp_clear_exclusive(orig_pte); ++ #ifdef CONFIG_PTP ++ iee_set_pte_at_delayed(src_mm, addr, src_pte, pte); ++ #else + set_pte_at(src_mm, addr, src_pte, pte); ++ #endif + } + rss[MM_SWAPENTS]++; + } else if (is_migration_entry(entry)) { +@@ -831,7 +840,11 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, + pte = pte_swp_mksoft_dirty(pte); + if (pte_swp_uffd_wp(orig_pte)) + pte = pte_swp_mkuffd_wp(pte); ++ #ifdef CONFIG_PTP ++ iee_set_pte_at_delayed(src_mm, addr, src_pte, pte); ++ #else + set_pte_at(src_mm, addr, src_pte, pte); ++ #endif + } + } else if (is_device_private_entry(entry)) { + page = pfn_swap_entry_to_page(entry); +@@ -865,7 +878,11 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, + pte = swp_entry_to_pte(entry); + if (pte_swp_uffd_wp(orig_pte)) + pte = pte_swp_mkuffd_wp(pte); ++ #ifdef CONFIG_PTP ++ iee_set_pte_at_delayed(src_mm, addr, src_pte, pte); ++ #else + set_pte_at(src_mm, addr, src_pte, pte); ++ #endif + } + } else if (is_device_exclusive_entry(entry)) { + /* +@@ -882,13 +899,22 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, + pte_marker marker = copy_pte_marker(entry, dst_vma); - return new; - } -@@ -327,7 +452,11 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) - * had one */ - if (new->thread_keyring) { - key_put(new->thread_keyring); -+ #ifdef CONFIG_CREDP -+ iee_set_cred_thread_keyring(new,NULL); -+ #else - new->thread_keyring = NULL; -+ #endif - if (clone_flags & CLONE_THREAD) - install_thread_keyring_to_cred(new); - } -@@ -337,7 +466,11 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) - */ - if (!(clone_flags & CLONE_THREAD)) { - key_put(new->process_keyring); -+ #ifdef CONFIG_CREDP -+ iee_set_cred_process_keyring(new,NULL); + if (marker) ++ #ifdef CONFIG_PTP ++ iee_set_pte_at(dst_mm, addr, dst_pte, ++ make_pte_marker(marker)); + #else - new->process_keyring = NULL; + set_pte_at(dst_mm, addr, dst_pte, + make_pte_marker(marker)); + #endif + return 0; } - #endif - -@@ -594,7 +727,11 @@ int set_cred_ucounts(struct cred *new) - if (!(new_ucounts = alloc_ucounts(new->user_ns, new->uid))) - return -EAGAIN; - -+ #ifdef CONFIG_CREDP -+ iee_set_cred_ucounts(new, new_ucounts); + if (!userfaultfd_wp(dst_vma)) + pte = pte_swp_clear_uffd_wp(pte); ++ #ifdef CONFIG_PTP ++ iee_set_pte_at(dst_mm, addr, dst_pte, pte); + #else - new->ucounts = new_ucounts; + set_pte_at(dst_mm, addr, dst_pte, pte); + #endif - put_ucounts(old_ucounts); - return 0; -@@ -606,8 +743,21 @@ int set_cred_ucounts(struct cred *new) - void __init cred_init(void) - { - /* allocate a slab in which we can store credentials */ -+ #ifdef CONFIG_CREDP - cred_jar = kmem_cache_create("cred_jar", sizeof(struct cred), 0, -+ SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT|SLAB_RED_ZONE, NULL); -+ rcu_jar = kmem_cache_create("rcu_jar", sizeof(struct rcu_head) + sizeof(struct cred *), 0, - SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, NULL); -+ // Map init_cred -+ *((struct rcu_head **)(&(init_cred.rcu.func))) = (struct rcu_head *)kmem_cache_zalloc(rcu_jar, GFP_KERNEL); -+ *(struct cred **)(((struct rcu_head *)(init_cred.rcu.func)) + 1) = &init_cred; -+ set_iee_page_valid(__phys_to_iee(__pa_symbol(&init_cred))); -+ iee_set_logical_mem_ro((unsigned long)&init_cred); -+ iee_set_logical_mem_ro((unsigned long)__va(__pa_symbol(&init_cred))); -+ #else -+ cred_jar = kmem_cache_create("cred_jar", sizeof(struct cred), 0, -+ SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, NULL); -+ #endif } - /** -@@ -638,29 +788,56 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) - if (!new) - return NULL; - -+ #ifdef CONFIG_CREDP -+ iee_set_cred_rcu(new,kmem_cache_alloc(rcu_jar, GFP_KERNEL)); -+ *(struct cred **)(((struct rcu_head *)(new->rcu.func)) + 1) = new; -+ #endif -+ - kdebug("prepare_kernel_cred() alloc %p", new); - - old = get_task_cred(daemon); - -+ #ifdef CONFIG_CREDP -+ iee_copy_cred(old,new); -+ iee_set_cred_non_rcu(new,0); -+ iee_set_cred_atomic_set_usage(new,1); +@@ -936,7 +962,11 @@ copy_present_page(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma + if (userfaultfd_pte_wp(dst_vma, ptep_get(src_pte))) + /* Uffd-wp needs to be delivered to dest pte as well */ + pte = pte_mkuffd_wp(pte); ++ #ifdef CONFIG_PTP ++ iee_set_pte_at(dst_vma->vm_mm, addr, dst_pte, pte); + #else - *new = *old; - new->non_rcu = 0; - atomic_long_set(&new->usage, 1); + set_pte_at(dst_vma->vm_mm, addr, dst_pte, pte); + #endif - get_uid(new->user); - get_user_ns(new->user_ns); - get_group_info(new->group_info); - - #ifdef CONFIG_KEYS -+#ifdef CONFIG_CREDP -+ iee_set_cred_session_keyring(new,NULL); -+ iee_set_cred_process_keyring(new,NULL); -+ iee_set_cred_thread_keyring(new,NULL); -+ iee_set_cred_request_key_auth(new,NULL); -+ iee_set_cred_jit_keyring(new,KEY_REQKEY_DEFL_THREAD_KEYRING); -+#else - new->session_keyring = NULL; - new->process_keyring = NULL; - new->thread_keyring = NULL; - new->request_key_auth = NULL; - new->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; - #endif -+#endif + return 0; + } - #ifdef CONFIG_SECURITY -+#ifdef CONFIG_CREDP -+ iee_set_cred_security(new,NULL); -+#else - new->security = NULL; - #endif -+#endif -+ #ifdef CONFIG_CREDP -+ iee_set_cred_ucounts(new, get_ucounts(new->ucounts)); -+ #else - new->ucounts = get_ucounts(new->ucounts); -+ #endif - if (!new->ucounts) - goto error; +@@ -960,7 +990,21 @@ static __always_inline void __copy_present_ptes(struct vm_area_struct *dst_vma, + if (!userfaultfd_wp(dst_vma)) + pte = pte_clear_uffd_wp(pte); -@@ -727,8 +904,13 @@ int set_create_files_as(struct cred *new, struct inode *inode) - { - if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid)) - return -EINVAL; -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(new,inode->i_uid); -+ iee_set_cred_fsgid(new,inode->i_gid); ++ #ifdef CONFIG_PTP ++ page_table_check_ptes_set(dst_vma->vm_mm, dst_pte, pte, nr); ++ __sync_cache_and_tags(pte, nr); ++ ++ for (;;) { ++ __check_safe_pte_update(dst_vma->vm_mm, dst_pte, pte); ++ iee_set_pte_at(dst_vma->vm_mm, addr, dst_pte, pte); ++ if (--nr == 0) ++ break; ++ dst_pte++; ++ pte = pte_advance_pfn(pte, 1); ++ } + #else - new->fsuid = inode->i_uid; - new->fsgid = inode->i_gid; + set_ptes(dst_vma->vm_mm, addr, dst_pte, pte, nr); + #endif - return security_kernel_create_files_as(new, inode); } - EXPORT_SYMBOL(set_create_files_as); -diff --git a/kernel/exit.c b/kernel/exit.c -index 21a59a6e1f2e..d21a109f0497 100644 ---- a/kernel/exit.c -+++ b/kernel/exit.c -@@ -74,6 +74,10 @@ - #include - #include -+#ifdef CONFIG_IEE -+#include -+#endif -+ /* - * The default value should be high enough to not crash a system that randomly - * crashes its kernel from time to time, but low enough to at least not permit -@@ -558,6 +562,10 @@ static void exit_mm(void) - smp_mb__after_spinlock(); - local_irq_disable(); - current->mm = NULL; -+ #ifdef CONFIG_IEE -+ iee_set_token_mm(current, NULL); -+ iee_set_token_pgd(current, NULL); +@@ -1087,6 +1131,12 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma, + swp_entry_t entry = (swp_entry_t){0}; + struct folio *prealloc = NULL; + int nr; ++ #ifdef CONFIG_PTP ++ unsigned long orig_addr; ++ pmd_t pmd; ++ pte_t *old_dst; ++ void *new; + #endif - membarrier_update_current_mm(NULL); - enter_lazy_tlb(mm, current); - local_irq_enable(); -diff --git a/kernel/fork.c b/kernel/fork.c -index e033388b11bd..c93e18a4f0b3 100644 ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -115,6 +115,10 @@ - #define CREATE_TRACE_POINTS - #include -+#ifdef CONFIG_IEE -+#include + again: + progress = 0; +@@ -1105,6 +1155,13 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma, + ret = -ENOMEM; + goto out; + } ++#ifdef CONFIG_PTP ++ orig_addr = addr; ++ new = (void *)iee_read_tmp_page(get_current()); ++ pmd = READ_ONCE(*dst_pmd); ++ dst_pte = (pte_t *)new + pte_index(addr); ++ old_dst = pte_offset_map(&pmd, addr); +#endif -+ - /* - * Minimum number of threads to boot the kernel - */ -@@ -128,14 +132,14 @@ - /* - * Protected counters by write_lock_irq(&tasklist_lock) - */ --unsigned long total_forks; /* Handle normal Linux uptimes. */ --int nr_threads; /* The idle threads do not count.. */ -+unsigned long total_forks; /* Handle normal Linux uptimes. */ -+int nr_threads; /* The idle threads do not count.. */ - --static int max_threads; /* tunable limit on nr_threads */ -+static int max_threads; /* tunable limit on nr_threads */ - --#define NAMED_ARRAY_INDEX(x) [x] = __stringify(x) -+#define NAMED_ARRAY_INDEX(x) [x] = __stringify(x) - --static const char * const resident_page_types[] = { -+static const char *const resident_page_types[] = { - NAMED_ARRAY_INDEX(MM_FILEPAGES), - NAMED_ARRAY_INDEX(MM_ANONPAGES), - NAMED_ARRAY_INDEX(MM_SWAPENTS), -@@ -144,7 +148,7 @@ static const char * const resident_page_types[] = { - - DEFINE_PER_CPU(unsigned long, process_counts) = 0; - --__cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */ -+__cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */ - - #ifdef CONFIG_PROVE_RCU - int lockdep_tasklist_lock_is_held(void) -@@ -159,7 +163,7 @@ int nr_processes(void) - int cpu; - int total = 0; - -- for_each_possible_cpu(cpu) -+ for_each_possible_cpu (cpu) - total += per_cpu(process_counts, cpu); - - return total; -@@ -190,7 +194,7 @@ static inline void free_task_struct(struct task_struct *tsk) - * Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a - * kmemcache based allocator. - */ --# if THREAD_SIZE >= PAGE_SIZE || defined(CONFIG_VMAP_STACK) -+#if THREAD_SIZE >= PAGE_SIZE || defined(CONFIG_VMAP_STACK) + src_pte = pte_offset_map_nolock(src_mm, src_pmd, addr, &src_ptl); + if (!src_pte) { + pte_unmap_unlock(dst_pte, dst_ptl); +@@ -1183,6 +1240,12 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma, + } while (dst_pte += nr, src_pte += nr, addr += PAGE_SIZE * nr, + addr != end); - # ifdef CONFIG_VMAP_STACK - /* -@@ -311,8 +315,8 @@ static int alloc_thread_stack_node(struct task_struct *tsk, int node) - * so memcg accounting is performed manually on assigning/releasing - * stacks to tasks. Drop __GFP_ACCOUNT. - */ -- stack = __vmalloc_node_range(THREAD_SIZE, THREAD_ALIGN, -- VMALLOC_START, VMALLOC_END, -+ stack = __vmalloc_node_range(THREAD_SIZE, THREAD_ALIGN, VMALLOC_START, -+ VMALLOC_END, - THREADINFO_GFP & ~__GFP_ACCOUNT, - PAGE_KERNEL, - 0, node, __builtin_return_address(0)); -@@ -410,9 +414,10 @@ static void free_thread_stack(struct task_struct *tsk) ++ #ifdef CONFIG_PTP ++ iee_copy_pte_range(orig_dst_pte, old_dst, orig_src_pte, src_vma, dst_vma->vm_flags, src_pte); ++ orig_dst_pte = pte_offset_map(&pmd, orig_addr); ++ dst_pte = pte_offset_map(&pmd, addr); ++ #endif ++ + arch_leave_lazy_mmu_mode(); + pte_unmap_unlock(orig_src_pte, src_ptl); + add_mm_rss_vec(dst_mm, rss); +@@ -6624,12 +6687,20 @@ bool ptlock_alloc(struct ptdesc *ptdesc) + ptl = kmem_cache_alloc(page_ptl_cachep, GFP_KERNEL); + if (!ptl) + return false; ++ #ifdef CONFIG_PTP ++ ((struct ptdesc_t *)(((struct slab *)ptdesc)->slab_cache)->ptl) = ptl; ++ #else + ptdesc->ptl = ptl; ++ #endif + return true; + } - void thread_stack_cache_init(void) + void ptlock_free(struct ptdesc *ptdesc) { -- thread_stack_cache = kmem_cache_create_usercopy("thread_stack", -- THREAD_SIZE, THREAD_SIZE, 0, 0, -- THREAD_SIZE, NULL); -+ thread_stack_cache = -+ kmem_cache_create_usercopy("thread_stack", THREAD_SIZE, -+ THREAD_SIZE, 0, 0, THREAD_SIZE, -+ NULL); - BUG_ON(thread_stack_cache == NULL); ++ #ifdef CONFIG_PTP ++ kmem_cache_free(page_ptl_cachep, ((struct ptdesc_t *)(((struct slab *)ptdesc)->slab_cache)->ptl)); ++ #else + kmem_cache_free(page_ptl_cachep, ptdesc->ptl); ++ #endif + } + #endif +diff --git a/mm/mmap.c b/mm/mmap.c +index 07ffb6c37b96..02d1f6f54e36 100644 +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -2375,7 +2375,11 @@ static void unmap_region(struct mm_struct *mm, struct ma_state *mas, + free_pgtables(&tlb, mas, vma, prev ? prev->vm_end : FIRST_USER_ADDRESS, + next ? next->vm_start : USER_PGTABLES_CEILING, + mm_wr_locked); ++ #ifdef CONFIG_PTP ++ iee_tlb_finish_mmu(&tlb); ++ #else + tlb_finish_mmu(&tlb); ++ #endif } -@@ -502,7 +507,8 @@ struct vm_area_struct *vm_area_alloc(struct mm_struct *mm) - - struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig) - { -- struct vm_area_struct *new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); -+ struct vm_area_struct *new = -+ kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); + /* +@@ -3286,7 +3290,11 @@ void exit_mmap(struct mm_struct *mm) + mas_set(&mas, vma->vm_end); + free_pgtables(&tlb, &mas, vma, FIRST_USER_ADDRESS, + USER_PGTABLES_CEILING, true); ++ #ifdef CONFIG_PTP ++ iee_tlb_finish_mmu(&tlb); ++ #else + tlb_finish_mmu(&tlb); ++ #endif - if (!new) - return NULL; -@@ -602,8 +608,15 @@ void put_task_stack(struct task_struct *tsk) + /* + * Walk the list again, actually closing and freeing it, with preemption +diff --git a/mm/mmu_gather.c b/mm/mmu_gather.c +index 99b3e9408aa0..16c79de60435 100644 +--- a/mm/mmu_gather.c ++++ b/mm/mmu_gather.c +@@ -347,6 +347,71 @@ void tlb_remove_table(struct mmu_gather *tlb, void *table) + tlb_table_flush(tlb); } - #endif -+#ifdef CONFIG_KOI -+extern s64 koi_offset; ++#ifdef CONFIG_PTP ++static void __iee_tlb_remove_table_free(struct mmu_table_batch *batch) ++{ ++ int i; ++ ++ for (i = 0; i < batch->nr; i++) ++ __iee_tlb_remove_table(batch->tables[i]); ++ ++ free_page((unsigned long)batch); ++} ++ ++#ifdef CONFIG_MMU_GATHER_RCU_TABLE_FREE ++static void iee_tlb_remove_table_rcu(struct rcu_head *head) ++{ ++ __iee_tlb_remove_table_free(container_of(head, struct mmu_table_batch, rcu)); ++} ++ ++static void iee_tlb_remove_table_free(struct mmu_table_batch *batch) ++{ ++ call_rcu(&batch->rcu, iee_tlb_remove_table_rcu); ++} ++#else ++static void iee_tlb_remove_table_free(struct mmu_table_batch *batch) ++{ ++ __iee_tlb_remove_table_free(batch); ++} +#endif + - void free_task(struct task_struct *tsk) ++static void iee_tlb_remove_table_one(void *table) ++{ ++ tlb_remove_table_sync_one(); ++ __iee_tlb_remove_table(table); ++} ++ ++static void iee_tlb_table_flush(struct mmu_gather *tlb) ++{ ++ struct mmu_table_batch **batch = &tlb->batch; ++ ++ if (*batch) { ++ tlb_table_invalidate(tlb); ++ iee_tlb_remove_table_free(*batch); ++ *batch = NULL; ++ } ++} ++ ++void iee_tlb_remove_table(struct mmu_gather *tlb, void *table) ++{ ++ struct mmu_table_batch **batch = &tlb->batch; ++ ++ if (*batch == NULL) { ++ *batch = (struct mmu_table_batch *)__get_free_page(GFP_NOWAIT | __GFP_NOWARN); ++ if (*batch == NULL) { ++ tlb_table_invalidate(tlb); ++ iee_tlb_remove_table_one(table); ++ return; ++ } ++ (*batch)->nr = 0; ++ } ++ ++ (*batch)->tables[(*batch)->nr++] = table; ++ if ((*batch)->nr == MAX_TABLE_BATCH) ++ iee_tlb_table_flush(tlb); ++} ++#endif ++ + static inline void tlb_table_init(struct mmu_gather *tlb) { -+ #ifdef CONFIG_IEE -+ void *iee_stack; + tlb->batch = NULL; +@@ -469,3 +534,55 @@ void tlb_finish_mmu(struct mmu_gather *tlb) + #endif + dec_tlb_flush_pending(tlb->mm); + } ++ ++#ifdef CONFIG_PTP ++static void iee_tlb_flush_mmu_free(struct mmu_gather *tlb) ++{ ++ iee_tlb_table_flush(tlb); ++#ifndef CONFIG_MMU_GATHER_NO_GATHER ++ tlb_batch_pages_flush(tlb); ++#endif ++} ++ ++void iee_tlb_flush_mmu(struct mmu_gather *tlb) ++{ ++ tlb_flush_mmu_tlbonly(tlb); ++ iee_tlb_flush_mmu_free(tlb); ++} ++ ++void iee_tlb_finish_mmu(struct mmu_gather *tlb) ++{ ++ /* ++ * If there are parallel threads are doing PTE changes on same range ++ * under non-exclusive lock (e.g., mmap_lock read-side) but defer TLB ++ * flush by batching, one thread may end up seeing inconsistent PTEs ++ * and result in having stale TLB entries. So flush TLB forcefully ++ * if we detect parallel PTE batching threads. ++ * ++ * However, some syscalls, e.g. munmap(), may free page tables, this ++ * needs force flush everything in the given range. Otherwise this ++ * may result in having stale TLB entries for some architectures, ++ * e.g. aarch64, that could specify flush what level TLB. ++ */ ++ if (mm_tlb_flush_nested(tlb->mm)) { ++ /* ++ * The aarch64 yields better performance with fullmm by ++ * avoiding multiple CPUs spamming TLBI messages at the ++ * same time. ++ * ++ * On x86 non-fullmm doesn't yield significant difference ++ * against fullmm. ++ */ ++ tlb->fullmm = 1; ++ __tlb_reset_range(tlb); ++ tlb->freed_tables = 1; ++ } ++ ++ iee_tlb_flush_mmu(tlb); ++ ++#ifndef CONFIG_MMU_GATHER_NO_GATHER ++ tlb_batch_list_free(tlb); ++#endif ++ dec_tlb_flush_pending(tlb->mm); ++} ++#endif +\ No newline at end of file +diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c +index 4fcd959dcc4d..bedc3522ddc3 100644 +--- a/mm/pgtable-generic.c ++++ b/mm/pgtable-generic.c +@@ -169,9 +169,17 @@ void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, + + /* FIFO */ + if (!pmd_huge_pte(mm, pmdp)) ++ #ifdef CONFIG_PTP ++ INIT_LIST_HEAD(&(((struct ptdesc_t *)(((struct slab_t *)pgtable)->slab_cache))->pt_list)); ++ #else + INIT_LIST_HEAD(&pgtable->lru); ++ #endif + else ++ #ifdef CONFIG_PTP ++ list_add(&(((struct ptdesc_t *)(((struct slab_t *)pgtable)->slab_cache))->pt_list), &(((struct ptdesc_t *)(((struct slab_t *)(pmd_huge_pte(mm, pmdp)))->slab_cache))->pt_list)); ++ #else + list_add(&pgtable->lru, &pmd_huge_pte(mm, pmdp)->lru); ++ #endif + pmd_huge_pte(mm, pmdp) = pgtable; + } + #endif +@@ -186,10 +194,22 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp) + + /* FIFO */ + pgtable = pmd_huge_pte(mm, pmdp); ++ #ifdef CONFIG_PTP ++ struct ptdesc_t *ptdesc = list_first_entry_or_null(&(((struct ptdesc_t *)(((struct slab_t *)pgtable)->slab_cache))->pt_list), struct ptdesc_t, pt_list); ++ if(ptdesc) ++ pmd_huge_pte(mm, pmdp) = (struct page *)ptdesc->slab; ++ else ++ pmd_huge_pte(mm, pmdp) = NULL; ++ #else + pmd_huge_pte(mm, pmdp) = list_first_entry_or_null(&pgtable->lru, + struct page, lru); + #endif - #ifdef CONFIG_SECCOMP - WARN_ON_ONCE(tsk->seccomp.filter); + if (pmd_huge_pte(mm, pmdp)) ++ #ifdef CONFIG_PTP ++ list_del(&(((struct ptdesc_t *)(((struct slab_t *)pgtable)->slab_cache))->pt_list)); ++ #else + list_del(&pgtable->lru); ++ #endif + return pgtable; + } #endif -@@ -633,6 +646,45 @@ void free_task(struct task_struct *tsk) - if (dynamic_affinity_enabled()) - sched_prefer_cpus_free(tsk); +@@ -238,7 +258,11 @@ static void pte_free_now(struct rcu_head *head) + { + struct page *page; + ++ #ifdef CONFIG_PTP ++ page = (struct page *)((container_of(head, struct ptdesc_t, pt_rcu_head))->slab); ++ #else + page = container_of(head, struct page, rcu_head); ++ #endif + pte_free(NULL /* mm not passed and not used */, (pgtable_t)page); + } + +@@ -247,7 +271,11 @@ void pte_free_defer(struct mm_struct *mm, pgtable_t pgtable) + struct page *page; + + page = pgtable; ++ #ifdef CONFIG_PTP ++ call_rcu(&(((struct ptdesc_t *)(((struct slab_t *)page)->slab_cache))->pt_rcu_head), pte_free_now); ++ #else + call_rcu(&page->rcu_head, pte_free_now); ++ #endif + } + #endif /* pte_free_defer */ + #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ +diff --git a/mm/slab.h b/mm/slab.h +index 3d07fb428393..69e3f4787ee1 100644 +--- a/mm/slab.h ++++ b/mm/slab.h +@@ -26,6 +26,24 @@ typedef u64 freelist_full_t; + #undef system_has_freelist_aba #endif + +#ifdef CONFIG_IEE -+ // Free iee stack. -+ iee_stack = (void *)iee_read_token_stack(tsk); -+ if (iee_stack) { -+ iee_set_kernel_ppage( -+ (unsigned long)(iee_stack - PAGE_SIZE * 4)); -+ free_pages((unsigned long)(iee_stack - PAGE_SIZE * 4), 3); -+ } -+ // Free task_token. -+ // Empty the token -+ iee_free_token(tsk); -+ -+#ifdef CONFIG_KOI -+ // Free koi stack. -+ unsigned long koi_stack = iee_rw_gate(IEE_READ_KOI_STACK_BASE, current); -+ if (koi_stack != 0) -+ free_pages(koi_stack, 2); ++extern struct kmem_cache *iee_stack_jar; ++extern struct kmem_cache *cred_jar; ++extern struct kmem_cache *key_jar; ++extern struct kmem_cache *pgtable_jar; ++extern struct kmem_cache *ptdesc_jar; ++extern struct kmem_cache *key_union_jar; ++extern struct kmem_cache *key_struct_jar; ++extern struct kmem_cache *key_payload_jar; ++extern void iee_memset(void *ptr, int data, size_t n); +#endif -+#else -+#ifdef CONFIG_KOI -+// free koi stack -+ struct task_token *token = (struct task_token *)((unsigned long)current + koi_offset); -+ unsigned long flags; -+ local_irq_save(flags); -+ asm volatile( -+ "at s1e1r, %0\n" -+ "isb\n" -+ : -+ :"r"(token)); -+ unsigned long res = read_sysreg(par_el1); -+ local_irq_restore(flags); -+ if (!(res & 0x1)) { -+ unsigned long koi_stack = token->koi_stack_base; -+ if (koi_stack != 0) -+ free_pages(koi_stack, 2); -+ } ++#if defined(CONFIG_KOI) || defined(CONFIG_IEE) ++extern struct kmem_cache *task_struct_cachep; +#endif ++#ifdef CONFIG_IEE_SELINUX_P ++extern struct kmem_cache *policy_jar; +#endif + - #ifdef CONFIG_QOS_SCHED_SMART_GRID - if (smart_grid_enabled()) - sched_grid_qos_free(tsk); -@@ -657,7 +709,7 @@ static void dup_mm_exe_file(struct mm_struct *mm, struct mm_struct *oldmm) + /* + * Freelist pointer and counter to cmpxchg together, avoids the typical ABA + * problems with cmpxchg of just a pointer. +@@ -843,6 +861,15 @@ static inline void cache_random_seq_destroy(struct kmem_cache *cachep) { } - #ifdef CONFIG_MMU - static __latent_entropy int dup_mmap(struct mm_struct *mm, -- struct mm_struct *oldmm) -+ struct mm_struct *oldmm) + static inline bool slab_want_init_on_alloc(gfp_t flags, struct kmem_cache *c) { - struct vm_area_struct *mpnt, *tmp; - int retval; -@@ -773,7 +825,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, - flush_dcache_mmap_lock(mapping); - /* insert tmp into the share list, just after mpnt */ - vma_interval_tree_insert_after(tmp, mpnt, -- &mapping->i_mmap); -+ &mapping->i_mmap); - flush_dcache_mmap_unlock(mapping); - i_mmap_unlock_write(mapping); - } -@@ -842,7 +894,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) - mmap_write_unlock(oldmm); - return 0; - } --#define mm_alloc_pgd(mm) (0) -+#define mm_alloc_pgd(mm) (0) - #define mm_free_pgd(mm) - #endif /* CONFIG_MMU */ ++ #ifdef CONFIG_IEE ++ if(c == iee_stack_jar) ++ return false; ++ #endif ++ #ifdef CONFIG_PTP ++ if(c == pgtable_jar) ++ return false; ++ #endif ++ + if (static_branch_maybe(CONFIG_INIT_ON_ALLOC_DEFAULT_ON, + &init_on_alloc)) { + if (c->ctor) +diff --git a/mm/slab_common.c b/mm/slab_common.c +index 8d431193c273..c755e7320111 100644 +--- a/mm/slab_common.c ++++ b/mm/slab_common.c +@@ -145,6 +145,24 @@ int slab_unmergeable(struct kmem_cache *s) + if (s->ctor) + return 1; -@@ -850,20 +902,22 @@ static void check_mm(struct mm_struct *mm) - { - int i; ++ #ifdef CONFIG_IEE ++ if(strcmp(s->name, "iee_stack_jar") == 0) ++ return 1; ++ #endif ++ #ifdef CONFIG_PTP ++ if(strcmp(s->name, "pgtable_jar") == 0) ++ return 1; ++ #endif ++ #ifdef CONFIG_KEYP ++ if((strcmp(s->name, "key_jar") == 0) || (strcmp(s->name, "key_payload_jar") == 0)) ++ return 1; ++ #endif ++ #ifdef CONFIG_IEE_SELINUX_P ++ if(strcmp(s->name, "policy_jar") == 0) ++ return 1; ++ #endif ++ ++ + #ifdef CONFIG_HARDENED_USERCOPY + if (s->usersize) + return 1; +@@ -170,6 +188,23 @@ struct kmem_cache *find_mergeable(unsigned int size, unsigned int align, + if (ctor) + return NULL; -- BUILD_BUG_ON_MSG(ARRAY_SIZE(resident_page_types) != NR_MM_COUNTERS, -- "Please make sure 'struct resident_page_types[]' is updated as well"); -+ BUILD_BUG_ON_MSG( -+ ARRAY_SIZE(resident_page_types) != NR_MM_COUNTERS, -+ "Please make sure 'struct resident_page_types[]' is updated as well"); ++ #ifdef CONFIG_IEE ++ if(strcmp(name, "iee_stack_jar") == 0) ++ return NULL; ++ #endif ++ #ifdef CONFIG_PTP ++ if(strcmp(name, "pgtable_jar") == 0) ++ return NULL; ++ #endif ++ #ifdef CONFIG_KEYP ++ if((strcmp(name, "key_jar") == 0) || (strcmp(name, "key_payload_jar") == 0)) ++ return NULL; ++ #endif ++ #ifdef CONFIG_PTP ++ if(strcmp(name, "policy_jar") == 0) ++ return NULL; ++ #endif ++ + size = ALIGN(size, sizeof(void *)); + align = calculate_alignment(flags, align, size); + size = ALIGN(size, align); +diff --git a/mm/slub.c b/mm/slub.c +index bcbfd720b574..3f05ad78eaf1 100644 +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -42,11 +42,27 @@ + #include + #include - for (i = 0; i < NR_MM_COUNTERS; i++) { - long x = mm_counter_sum(mm, i); ++#ifdef CONFIG_IEE ++#include ++#include ++#include ++#endif ++#ifdef CONFIG_PTP ++#include ++extern unsigned long pgtable_jar_offset; ++#endif ++ + #include + #include - if (unlikely(x)) -- pr_alert("BUG: Bad rss-counter state mm:%p type:%s val:%ld\n", -- mm, resident_page_types[i], x); -+ pr_alert( -+ "BUG: Bad rss-counter state mm:%p type:%s val:%ld\n", -+ mm, resident_page_types[i], x); - } + #include "internal.h" - if (mm_pgtables_bytes(mm)) - pr_alert("BUG: non-zero pgtables_bytes on freeing mm: %ld\n", -- mm_pgtables_bytes(mm)); -+ mm_pgtables_bytes(mm)); ++#ifdef CONFIG_KOI ++extern void koi_add_page_mapping(unsigned long dst, unsigned long src); ++extern void koi_remove_page_mapping(unsigned long addr); ++#endif ++ ++ + /* + * Lock order: + * 1. slab_mutex (Global Mutex) +@@ -317,6 +333,7 @@ static inline bool kmem_cache_has_cpu_partial(struct kmem_cache *s) + /* + * Tracking user of a slab. + */ ++#ifndef CONFIG_IEE + #define TRACK_ADDRS_COUNT 16 + struct track { + unsigned long addr; /* Called from address */ +@@ -329,6 +346,7 @@ struct track { + }; - #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS - VM_BUG_ON_MM(mm->pmd_huge_pte, mm); -@@ -1014,14 +1068,6 @@ void __put_task_struct(struct task_struct *tsk) - } - EXPORT_SYMBOL_GPL(__put_task_struct); + enum track_item { TRACK_ALLOC, TRACK_FREE }; ++#endif --void __put_task_struct_rcu_cb(struct rcu_head *rhp) --{ -- struct task_struct *task = container_of(rhp, struct task_struct, rcu); -- -- __put_task_struct(task); --} --EXPORT_SYMBOL_GPL(__put_task_struct_rcu_cb); -- - void __init __weak arch_task_cache_init(void) { } + #ifdef SLAB_SUPPORTS_SYSFS + static int sysfs_slab_add(struct kmem_cache *); +@@ -379,7 +397,9 @@ static struct workqueue_struct *flushwq; + * freeptr_t represents a SLUB freelist pointer, which might be encoded + * and not dereferenceable if CONFIG_SLAB_FREELIST_HARDENED is enabled. + */ ++#ifndef CONFIG_IEE + typedef struct { unsigned long v; } freeptr_t; ++#endif /* -@@ -1039,8 +1085,8 @@ static void set_max_threads(unsigned int max_threads_suggested) - if (fls64(nr_pages) + fls64(PAGE_SIZE) > 64) - threads = MAX_THREADS; - else -- threads = div64_u64((u64) nr_pages * (u64) PAGE_SIZE, -- (u64) THREAD_SIZE * 8UL); -+ threads = div64_u64((u64)nr_pages * (u64)PAGE_SIZE, -+ (u64)THREAD_SIZE * 8UL); + * Returns freelist pointer (ptr). With hardening, this is obfuscated +@@ -419,7 +439,14 @@ static inline void *get_freepointer(struct kmem_cache *s, void *object) - if (threads > max_threads_suggested) - threads = max_threads_suggested; -@@ -1075,17 +1121,24 @@ void __init fork_init(void) - int i; - #ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR - #ifndef ARCH_MIN_TASKALIGN --#define ARCH_MIN_TASKALIGN 0 -+#define ARCH_MIN_TASKALIGN 0 + object = kasan_reset_tag(object); + ptr_addr = (unsigned long)object + s->offset; ++ #ifdef CONFIG_IEE ++ if(s == iee_stack_jar) ++ p.v = (unsigned long)iee_read_freeptr(ptr_addr); ++ else ++ p = *(freeptr_t *)(ptr_addr); ++ #else + p = *(freeptr_t *)(ptr_addr); ++ #endif + return freelist_ptr_decode(s, p, ptr_addr); + } + +@@ -464,7 +491,19 @@ static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp) #endif - int align = max_t(int, L1_CACHE_BYTES, ARCH_MIN_TASKALIGN); - unsigned long useroffset, usersize; - /* create a slab on which task_structs can be allocated */ - task_struct_whitelist(&useroffset, &usersize); + freeptr_addr = (unsigned long)kasan_reset_tag((void *)freeptr_addr); + #ifdef CONFIG_IEE - task_struct_cachep = kmem_cache_create_usercopy("task_struct", - arch_task_struct_size, align, -- SLAB_PANIC|SLAB_ACCOUNT, -+ SLAB_PANIC|SLAB_ACCOUNT|SLAB_RED_ZONE, - useroffset, usersize, NULL); ++ if((s == iee_stack_jar) || (IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) || (IS_ENABLED(CONFIG_PTP) && (s == pgtable_jar)) || ++ (IS_ENABLED(CONFIG_KEYP) && (s == key_payload_jar)) || (IS_ENABLED(CONFIG_KEYP) && (s == key_jar))) ++ iee_set_freeptr((freeptr_t *)freeptr_addr, freelist_ptr_encode(s, fp, freeptr_addr)); ++#ifdef CONFIG_IEE_SELINUX_P ++ else if (s == policy_jar) ++ iee_set_freeptr((freeptr_t *)freeptr_addr, freelist_ptr_encode(s, fp, freeptr_addr)); ++#endif ++ else ++ *(freeptr_t *)freeptr_addr = freelist_ptr_encode(s, fp, freeptr_addr); + #else -+ task_struct_cachep = -+ kmem_cache_create_usercopy("task_struct", arch_task_struct_size, -+ align, SLAB_PANIC | SLAB_ACCOUNT, -+ useroffset, usersize, NULL); + *(freeptr_t *)freeptr_addr = freelist_ptr_encode(s, fp, freeptr_addr); + #endif + } + + /* Loop over all objects in a slab */ +@@ -809,7 +848,34 @@ static void set_track_update(struct kmem_cache *s, void *object, + depot_stack_handle_t handle) + { + struct track *p = get_track(s, object, alloc); ++#ifdef CONFIG_IEE ++ struct track tmp; ++#endif + ++#ifdef CONFIG_IEE ++ if(IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) ++ { ++ tmp = *p; ++ #ifdef CONFIG_STACKDEPOT ++ tmp.handle = handle; ++ #endif ++ tmp.addr = addr; ++ tmp.cpu = smp_processor_id(); ++ tmp.pid = current->pid; ++ tmp.when = jiffies; ++ iee_set_track(p,&tmp); ++ } ++ else ++ { ++ #ifdef CONFIG_STACKDEPOT ++ p->handle = handle; ++ #endif ++ p->addr = addr; ++ p->cpu = smp_processor_id(); ++ p->pid = current->pid; ++ p->when = jiffies; ++ } ++#else + #ifdef CONFIG_STACKDEPOT + p->handle = handle; #endif +@@ -817,6 +883,7 @@ static void set_track_update(struct kmem_cache *s, void *object, + p->cpu = smp_processor_id(); + p->pid = current->pid; + p->when = jiffies; ++#endif + } - /* do the arch specific task caches init */ -@@ -1093,8 +1146,8 @@ void __init fork_init(void) + static __always_inline void set_track(struct kmem_cache *s, void *object, +@@ -835,7 +902,14 @@ static void init_tracking(struct kmem_cache *s, void *object) + return; - set_max_threads(MAX_THREADS); + p = get_track(s, object, TRACK_ALLOC); ++ #ifdef CONFIG_IEE ++ if(IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) ++ iee_memset(p, 0, 2*sizeof(struct track)); ++ else ++ memset(p, 0, 2*sizeof(struct track)); ++ #else + memset(p, 0, 2*sizeof(struct track)); ++ #endif + } -- init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2; -- init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2; -+ init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads / 2; -+ init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads / 2; - init_task.signal->rlim[RLIMIT_SIGPENDING] = - init_task.signal->rlim[RLIMIT_NPROC]; + static void print_track(const char *s, struct track *t, unsigned long pr_time) +@@ -1045,7 +1119,14 @@ static void init_object(struct kmem_cache *s, void *object, u8 val) + unsigned int poison_size = s->object_size; -@@ -1107,8 +1160,8 @@ void __init fork_init(void) - set_userns_rlimit_max(&init_user_ns, UCOUNT_RLIMIT_MEMLOCK, RLIM_INFINITY); + if (s->flags & SLAB_RED_ZONE) { ++ #ifdef CONFIG_IEE ++ if(IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) ++ iee_memset(p - s->red_left_pad, val, s->red_left_pad); ++ else ++ memset(p - s->red_left_pad, val, s->red_left_pad); ++ #else + memset(p - s->red_left_pad, val, s->red_left_pad); ++ #endif - #ifdef CONFIG_VMAP_STACK -- cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "fork:vm_stack_cache", -- NULL, free_vm_stack_cache); -+ cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "fork:vm_stack_cache", NULL, -+ free_vm_stack_cache); - #endif + if (slub_debug_orig_size(s) && val == SLUB_RED_ACTIVE) { + /* +@@ -1058,12 +1139,34 @@ static void init_object(struct kmem_cache *s, void *object, u8 val) + } - scs_init(); -@@ -1118,7 +1171,7 @@ void __init fork_init(void) + if (s->flags & __OBJECT_POISON) { ++ #ifdef CONFIG_IEE ++ if(IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) ++ { ++ iee_memset(p, POISON_FREE, poison_size - 1); ++ iee_memset(&p[poison_size - 1], POISON_END, 1); ++ } ++ else ++ { ++ memset(p, POISON_FREE, poison_size - 1); ++ p[poison_size - 1] = POISON_END; ++ } ++ #else + memset(p, POISON_FREE, poison_size - 1); + p[poison_size - 1] = POISON_END; ++ #endif + } + +- if (s->flags & SLAB_RED_ZONE) ++ if (s->flags & SLAB_RED_ZONE) { ++ #ifdef CONFIG_IEE ++ if(IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) ++ iee_memset(p + poison_size, val, s->inuse - poison_size); ++ else ++ memset(p + poison_size, val, s->inuse - poison_size); ++ #else + memset(p + poison_size, val, s->inuse - poison_size); ++ #endif ++ ++ } } - int __weak arch_dup_task_struct(struct task_struct *dst, -- struct task_struct *src) -+ struct task_struct *src) - { - *dst = *src; - return 0; -@@ -1129,14 +1182,14 @@ void set_task_stack_end_magic(struct task_struct *tsk) - unsigned long *stackend; + static void restore_bytes(struct kmem_cache *s, char *message, u8 data, +@@ -1433,7 +1536,14 @@ void setup_slab_debug(struct kmem_cache *s, struct slab *slab, void *addr) + return; - stackend = end_of_stack(tsk); -- *stackend = STACK_END_MAGIC; /* for overflow detection */ -+ *stackend = STACK_END_MAGIC; /* for overflow detection */ + metadata_access_enable(); ++ #ifdef CONFIG_IEE ++ if(IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) ++ iee_memset(kasan_reset_tag(addr), POISON_INUSE, slab_size(slab)); ++ else ++ memset(kasan_reset_tag(addr), POISON_INUSE, slab_size(slab)); ++ #else + memset(kasan_reset_tag(addr), POISON_INUSE, slab_size(slab)); ++ #endif + metadata_access_disable(); } - static bool dup_resvd_task_struct(struct task_struct *dst, - struct task_struct *orig, int node) - { -- dst->_resvd = kzalloc_node(sizeof(struct task_struct_resvd), -- GFP_KERNEL, node); -+ dst->_resvd = kzalloc_node(sizeof(struct task_struct_resvd), GFP_KERNEL, -+ node); - if (!dst->_resvd) - return false; +@@ -1984,6 +2094,21 @@ static bool shuffle_freelist(struct kmem_cache *s, struct slab *slab) + cur = setup_object(s, cur); + slab->freelist = cur; -@@ -1309,7 +1362,7 @@ static void mm_init_uprobes_state(struct mm_struct *mm) - } ++ #ifdef CONFIG_IEE ++ if(s == task_struct_cachep) ++ { ++ int i; ++ void *pstack; ++ void *obj; ++ for(i = 0; i < freelist_count; i++) ++ { ++ pstack = get_iee_stack(); ++ obj = start + s->random_seq[i]; ++ iee_init_token((struct task_struct *)obj, pstack + PAGE_SIZE * 4, (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 0)); ++ } ++ } ++ #endif ++ + for (idx = 1; idx < slab->objects; idx++) { + next = next_freelist_entry(s, &pos, start, page_limit, + freelist_count); +@@ -2015,6 +2140,9 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) + void *start, *p, *next; + int idx; + bool shuffle; ++ #if defined(CONFIG_IEE) || defined(CONFIG_KOI) ++ unsigned int order; ++ #endif - static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p, -- struct user_namespace *user_ns) -+ struct user_namespace *user_ns) - { - mt_init_flags(&mm->mm_mt, MM_MT_FLAGS); - mt_set_external_lock(&mm->mm_mt, &mm->mmap_lock); -@@ -1425,8 +1478,8 @@ EXPORT_SYMBOL_GPL(mmput); - #ifdef CONFIG_MMU - static void mmput_async_fn(struct work_struct *work) - { -- struct mm_struct *mm = container_of(work, struct mm_struct, -- async_put_work); -+ struct mm_struct *mm = -+ container_of(work, struct mm_struct, async_put_work); + flags &= gfp_allowed_mask; + +@@ -2028,15 +2156,45 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) + if ((alloc_gfp & __GFP_DIRECT_RECLAIM) && oo_order(oo) > oo_order(s->min)) + alloc_gfp = (alloc_gfp | __GFP_NOMEMALLOC) & ~__GFP_RECLAIM; + ++ #ifdef CONFIG_IEE ++ if(IS_ENABLED(CONFIG_PTP) && (s == pgtable_jar)) ++ alloc_gfp |= __GFP_ZERO; ++ #ifdef CONFIG_IEE_SELINUX_P ++ if(s == policy_jar) ++ alloc_gfp |= __GFP_ZERO; ++ #endif ++ #endif ++ #ifdef CONFIG_KEYP ++ if(s == key_jar) ++ alloc_gfp |= __GFP_ZERO; ++ #endif + slab = alloc_slab_page(alloc_gfp, node, oo); ++ #if defined(CONFIG_IEE) || defined(CONFIG_KOI) ++ order = oo_order(oo); ++ #endif + if (unlikely(!slab)) { + oo = s->min; + alloc_gfp = flags; ++ #ifdef CONFIG_IEE ++ if(IS_ENABLED(CONFIG_PTP) && (s == pgtable_jar)) ++ alloc_gfp |= __GFP_ZERO; ++ #ifdef CONFIG_IEE_SELINUX_P ++ if(s == policy_jar) ++ alloc_gfp |= __GFP_ZERO; ++ #endif ++ #endif ++ #ifdef CONFIG_KEYP ++ if(s == key_jar) ++ alloc_gfp |= __GFP_ZERO; ++ #endif + /* + * Allocation may have failed due to fragmentation. + * Try a lower order alloc if possible + */ + slab = alloc_slab_page(alloc_gfp, node, oo); ++ #if defined(CONFIG_IEE) || defined(CONFIG_KOI) ++ order = oo_order(oo); ++ #endif + if (unlikely(!slab)) + return NULL; + stat(s, ORDER_FALLBACK); +@@ -2046,9 +2204,71 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) + slab->inuse = 0; + slab->frozen = 0; + ++ #ifdef CONFIG_IEE ++ if(IS_ENABLED(CONFIG_PTP) && (s == pgtable_jar)) ++ { ++ int i; ++ struct page *page = folio_page(slab_folio(slab), 0); ++ for(i = 0; i < (0x1 << order); i++) ++ { ++ set_page_refcounted(page + i); ++ (slab+i)->slab_cache = kmem_cache_alloc(ptdesc_jar, GFP_KERNEL); ++ ((struct ptdesc_t *)((slab+i)->slab_cache))->slab = (struct slab_t *)(slab+i); ++ __folio_set_slab((struct folio *)(slab+i)); ++ } ++ set_iee_page((unsigned long)page_address(page), order); ++ } ++ ++ if(IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) ++ { ++ set_iee_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order); ++ } ++ ++ if(IS_ENABLED(CONFIG_KEYP) && ((s == key_jar) || (s == key_payload_jar))) ++ { ++ set_iee_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order); ++ } ++ ++ #ifdef CONFIG_IEE_SELINUX_P ++ if(s == policy_jar) ++ { ++ set_iee_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order); ++ } ++ #endif ++ ++ if(s == iee_stack_jar) ++ { ++ set_iee_stack_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order); ++ } ++ ++ // If the page belongs to a task_struct, alloc token for it and set iee&lm va. ++ if(s == task_struct_cachep) ++ { ++ void *token_addr = (void *)__phys_to_iee(page_to_phys(folio_page(slab_folio(slab), 0))); ++ void *alloc_token = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order); ++ iee_set_token_page_valid(token_addr, alloc_token, order); ++ } ++ #else ++ #ifdef CONFIG_KOI ++ if (s == task_struct_cachep) { ++ int i; ++ for (i = 0; i < (0x1 << order); i++) { ++ unsigned long token_addr = __phys_to_virt(page_to_phys(folio_page(slab_folio(slab), i))) + (unsigned long)KOI_OFFSET; ++ unsigned long alloc_token = __get_free_page(GFP_KERNEL | __GFP_ZERO); ++ koi_add_page_mapping(token_addr, alloc_token); ++ } ++ } ++ #endif ++ #endif ++ + account_slab(slab, oo_order(oo), s, flags); - __mmput(mm); - } -@@ -1602,13 +1655,12 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) - struct mm_struct *mm; - int err; ++ #ifdef CONFIG_PTP ++ if(!(s == pgtable_jar)) ++ slab->slab_cache = s; ++ #else + slab->slab_cache = s; ++ #endif -- err = down_read_killable(&task->signal->exec_update_lock); -+ err = down_read_killable(&task->signal->exec_update_lock); - if (err) - return ERR_PTR(err); + kasan_poison_slab(slab); - mm = get_task_mm(task); -- if (mm && mm != current->mm && -- !ptrace_may_access(task, mode)) { -+ if (mm && mm != current->mm && !ptrace_may_access(task, mode)) { - mmput(mm); - mm = ERR_PTR(-EACCES); - } -@@ -1631,7 +1683,7 @@ static void complete_vfork_done(struct task_struct *tsk) +@@ -2098,6 +2318,98 @@ static void __free_slab(struct kmem_cache *s, struct slab *slab) + __folio_clear_slab(folio); + mm_account_reclaimed_pages(pages); + unaccount_slab(slab, order, s); ++ ++ #ifdef CONFIG_IEE ++ if(IS_ENABLED(CONFIG_PTP) && (s == pgtable_jar)) ++ { ++ int i; ++ unset_iee_page((unsigned long)page_address(folio_page(folio, 0)), order); ++ for(i = 0; i < (0x1 << order); i++) ++ { ++ set_page_count(folio_page(folio, i), 0); ++ } ++ } ++ ++ if(IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) ++ { ++ unset_iee_page((unsigned long)page_address(folio_page(folio, 0)), order); ++ } ++ ++ if(IS_ENABLED(CONFIG_KEYP) && ((s == key_jar) || (s == key_payload_jar))) ++ { ++ unset_iee_page((unsigned long)page_address(folio_page(folio, 0)), order); ++ } ++ ++ #ifdef CONFIG_IEE_SELINUX_P ++ if(s == policy_jar) ++ { ++ unset_iee_page((unsigned long)page_address(folio_page(folio, 0)), order); ++ } ++ #endif ++ ++ if(s == iee_stack_jar) ++ { ++ unset_iee_stack_page((unsigned long)page_address(folio_page(folio, 0)), order); ++ } ++ ++ // If the page containing this token is empty, free it and restore iee&lm va. ++ if(s == task_struct_cachep) ++ { ++ // Free stack. ++ int i; ++ void *start = fixup_red_left(s, page_address(folio_page(folio, 0))); ++ void *obj; ++ void *iee_stack; ++ void *tmp_page; ++ void *token_addr; ++ for(i = 0; i < oo_objects(s->oo); i++) ++ { ++ obj = start + s->random_seq[i]; ++ tmp_page = iee_read_tmp_page((struct task_struct *)obj); ++ free_pages((unsigned long)tmp_page, 0); ++ iee_stack = (void *)iee_read_token_stack((struct task_struct *)obj); ++ if (iee_stack) { ++ free_iee_stack((void *)(iee_stack - PAGE_SIZE * 4)); ++ } ++ } ++ // Free token. ++ token_addr = (void *)__phys_to_iee(page_to_phys(folio_page(folio, 0))); ++ { ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, (unsigned long)token_addr); ++ p4d_t *p4dp = p4d_offset(pgdp, (unsigned long)token_addr); ++ pud_t *pudp = pud_offset(p4dp, (unsigned long)token_addr); ++ pmd_t *pmdp = pmd_offset(pudp, (unsigned long)token_addr); ++ pte_t *ptep = pte_offset_kernel(pmdp, (unsigned long)token_addr); ++ void *token_page = page_address(pte_page(*ptep)); ++ iee_set_token_page_invalid(token_addr, token_page, order); ++ free_pages((unsigned long)token_page, order); ++ } ++ } ++ #else ++ #ifdef CONFIG_KOI ++ if(s == task_struct_cachep) ++ { ++ int i; ++ for(i = 0; i < (0x1 << order); i++) ++ { ++ unsigned long token_addr = __phys_to_virt(page_to_phys(folio_page(folio, i))) + (unsigned long)KOI_OFFSET; ++ unsigned long flags; ++ local_irq_save(flags); ++ asm volatile("at s1e1r, %0"::"r"(token_addr)); ++ isb(); ++ unsigned long res = read_sysreg(par_el1); ++ local_irq_restore(flags); ++ if(!(res & 0x1)) ++ { ++ koi_remove_page_mapping(token_addr); ++ free_page((unsigned long)__va(res & PTE_ADDR_MASK)); ++ } ++ } ++ } ++ #endif ++ #endif ++ + __free_pages(&folio->page, order); } - static int wait_for_vfork_done(struct task_struct *child, -- struct completion *vfork) -+ struct completion *vfork) - { - unsigned int state = TASK_UNINTERRUPTIBLE|TASK_KILLABLE|TASK_FREEZABLE; - int killed; -@@ -1682,8 +1734,8 @@ static void mm_release(struct task_struct *tsk, struct mm_struct *mm) - * not set up a proper pointer then tough luck. - */ - put_user(0, tsk->clear_child_tid); -- do_futex(tsk->clear_child_tid, FUTEX_WAKE, -- 1, NULL, NULL, 0, 0); -+ do_futex(tsk->clear_child_tid, FUTEX_WAKE, 1, NULL, -+ NULL, 0, 0); - } - tsk->clear_child_tid = NULL; - } -@@ -1767,6 +1819,10 @@ static int copy_mm(unsigned long clone_flags, struct task_struct *tsk) - #endif - - tsk->mm = NULL; -+#ifdef CONFIG_IEE -+ iee_set_token_mm(tsk, NULL); -+ iee_set_token_pgd(tsk, NULL); -+#endif - tsk->active_mm = NULL; - - /* -@@ -1798,6 +1854,10 @@ static int copy_mm(unsigned long clone_flags, struct task_struct *tsk) +@@ -2118,6 +2430,23 @@ static void free_slab(struct kmem_cache *s, struct slab *slab) + check_object(s, slab, p, SLUB_RED_INACTIVE); } - tsk->mm = mm; -+#ifdef CONFIG_IEE -+ iee_set_token_mm(tsk, mm); -+ iee_set_token_pgd(tsk, mm->pgd); -+#endif - tsk->active_mm = mm; - sched_mm_cid_fork(tsk); - return 0; -@@ -2015,8 +2075,8 @@ static inline void init_task_pid_links(struct task_struct *task) - INIT_HLIST_NODE(&task->pid_links[type]); - } - --static inline void --init_task_pid(struct task_struct *task, enum pid_type type, struct pid *pid) -+static inline void init_task_pid(struct task_struct *task, enum pid_type type, -+ struct pid *pid) - { - if (type == PIDTYPE_PID) - task->thread_pid = pid; -@@ -2277,6 +2337,12 @@ static void copy_oom_score_adj(u64 clone_flags, struct task_struct *tsk) - mutex_unlock(&oom_adj_mutex); ++ #ifdef CONFIG_PTP ++ struct page *page = folio_page(slab_folio(slab), 0); ++ int order = compound_order(page); ++ if(s == pgtable_jar) ++ { ++ int i; ++ kmem_cache_free(ptdesc_jar, slab->slab_cache); ++ slab->slab_cache = s; ++ for(i = 1; i < (0x1 << order); i++) ++ { ++ kmem_cache_free(ptdesc_jar, (slab+i)->slab_cache); ++ set_compound_head(page+i,page); ++ __folio_clear_slab((struct folio *)(slab+i)); ++ } ++ } ++ #endif ++ + if (unlikely(s->flags & SLAB_TYPESAFE_BY_RCU)) + call_rcu(&slab->rcu_head, rcu_free_slab); + else +@@ -4285,6 +4614,35 @@ static void early_kmem_cache_node_alloc(int node) + __add_partial(n, slab, DEACTIVATE_TO_HEAD); } -+#if defined(CONFIG_KOI) && !defined(CONFIG_IEE) -+extern s64 koi_offset; -+extern int koi_add_page_mapping(unsigned long dst, unsigned long src); -+#endif ++#ifdef CONFIG_PTP ++void early_pgtable_jar_alloc(struct kmem_cache *pgtable_jar) ++{ ++ struct slab *slab; ++ int node = 0; ++ int i = 0; ++ ++ for(i = 0; i < nr_cpu_ids; i++) ++ { ++ node = cpupid_to_nid(i); ++ slab = new_slab(pgtable_jar, GFP_NOWAIT | __GFP_ZERO, node); + ++ BUG_ON(!slab); ++ if (slab_nid(slab) != node) { ++ pr_err("SLUB: Unable to allocate memory from node %d\n", node); ++ pr_err("SLUB: Allocating a useless per node structure in order to be able to continue\n"); ++ } + - #ifdef CONFIG_RV - static void rv_task_fork(struct task_struct *p) ++ slab->inuse = 0; ++ ++ /* ++ * No locks need to be taken here as it has just been ++ * initialized and there is no concurrent access. ++ */ ++ __add_partial(get_node(pgtable_jar, slab_nid(slab)), slab, DEACTIVATE_TO_HEAD); ++ } ++} ++#endif ++ + static void free_kmem_cache_nodes(struct kmem_cache *s) { -@@ -2309,15 +2375,21 @@ __latent_entropy struct task_struct *copy_process( - struct file *pidfile = NULL; - const u64 clone_flags = args->flags; - struct nsproxy *nsp = current->nsproxy; + int node; +@@ -4479,6 +4837,31 @@ static int calculate_sizes(struct kmem_cache *s) + s->reciprocal_size = reciprocal_value(size); + order = calculate_order(size); + + #ifdef CONFIG_IEE -+ gfp_t gfp; -+ void *pstack; ++ if(strcmp(s->name, "task_struct") == 0) ++ order = HUGE_PMD_ORDER; ++ if(strcmp(s->name, "iee_stack_jar") == 0) ++ order = HUGE_PMD_ORDER; ++ #endif ++ #ifdef CONFIG_PTP ++ if(strcmp(s->name, "pgtable_jar") == 0) ++ order = HUGE_PMD_ORDER; ++ #endif ++ #ifdef CONFIG_CREDP ++ if(strcmp(s->name, "cred_jar") == 0) ++ order = HUGE_PMD_ORDER; + #endif ++ #ifdef CONFIG_KEYP ++ if(strcmp(s->name, "key_jar") == 0) ++ order = HUGE_PMD_ORDER; ++ if(strcmp(s->name, "key_payload_jar") == 0) ++ order = HUGE_PMD_ORDER; ++ #endif ++ #ifdef CONFIG_IEE_SELINUX_P ++ if(strcmp(s->name, "policy_jar") == 0) ++ order = HUGE_PMD_ORDER; ++ #endif ++ + if ((int)order < 0) + return 0; - /* - * Don't allow sharing the root directory with processes in a different - * namespace - */ -- if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS)) -+ if ((clone_flags & (CLONE_NEWNS | CLONE_FS)) == -+ (CLONE_NEWNS | CLONE_FS)) - return ERR_PTR(-EINVAL); +@@ -4540,6 +4923,23 @@ static int kmem_cache_open(struct kmem_cache *s, slab_flags_t flags) + s->min_partial = min_t(unsigned long, MAX_PARTIAL, ilog2(s->size) / 2); + s->min_partial = max_t(unsigned long, MIN_PARTIAL, s->min_partial); -- if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS)) -+ if ((clone_flags & (CLONE_NEWUSER | CLONE_FS)) == -+ (CLONE_NEWUSER | CLONE_FS)) - return ERR_PTR(-EINVAL); ++ #ifdef CONFIG_IEE ++ if(strcmp(s->name, "task_struct") == 0) ++ s->min_partial *= (1 << TASK_ORDER); ++ if(strcmp(s->name, "iee_stack_jar") == 0) ++ s->min_partial *= (1 << TASK_ORDER); ++ #endif ++ #ifdef CONFIG_PTP ++ if(strcmp(s->name, "pgtable_jar") == 0) ++ s->min_partial = (1 << HUGE_PMD_ORDER); ++ #endif ++ #ifdef CONFIG_KEYP ++ if(strcmp(s->name, "key_jar") == 0) ++ s->min_partial = (1 << TASK_ORDER); ++ if(strcmp(s->name, "key_payload_jar") == 0) ++ s->min_partial = (1 << TASK_ORDER); ++ #endif ++ + set_cpu_partial(s); - /* -@@ -2342,7 +2414,7 @@ __latent_entropy struct task_struct *copy_process( - * from creating siblings. - */ - if ((clone_flags & CLONE_PARENT) && -- current->signal->flags & SIGNAL_UNKILLABLE) -+ current->signal->flags & SIGNAL_UNKILLABLE) - return ERR_PTR(-EINVAL); + #ifdef CONFIG_NUMA +@@ -5113,6 +5513,11 @@ int __kmem_cache_create(struct kmem_cache *s, slab_flags_t flags) + if (err) + return err; - /* -@@ -2387,6 +2459,15 @@ __latent_entropy struct task_struct *copy_process( - p = dup_task_struct(current, node); - if (!p) - goto fork_out; -+ #ifdef CONFIG_IEE -+ // Alloc iee stack. -+ gfp = GFP_KERNEL; -+ pstack = (void *)__get_free_pages(gfp, 3); -+ iee_set_kernel_upage((unsigned long)pstack); -+ // Init token. -+ iee_init_token(p, NULL, pstack + PAGE_SIZE * 4); ++ #ifdef CONFIG_PTP ++ if(strcmp(s->name, "pgtable_jar") == 0) ++ pgtable_jar_offset = s->offset; + #endif + - p->flags &= ~PF_KTHREAD; - if (args->kthread) - p->flags |= PF_KTHREAD; -@@ -2408,7 +2489,8 @@ __latent_entropy struct task_struct *copy_process( - /* - * Clear TID on mm_release()? - */ -- p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? args->child_tid : NULL; -+ p->clear_child_tid = -+ (clone_flags & CLONE_CHILD_CLEARTID) ? args->child_tid : NULL; + /* Mutex is not taken during early boot */ + if (slab_state <= UP) + return 0; +diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c +index a2cbe44c48e1..6b118447f197 100644 +--- a/mm/sparse-vmemmap.c ++++ b/mm/sparse-vmemmap.c +@@ -28,6 +28,10 @@ + #include + #include - ftrace_graph_init_task(p); ++#ifdef CONFIG_PTP ++#include ++#endif ++ + #include + #include -@@ -2519,10 +2601,10 @@ __latent_entropy struct task_struct *copy_process( - #endif - #ifdef CONFIG_TRACE_IRQFLAGS - memset(&p->irqtrace, 0, sizeof(p->irqtrace)); -- p->irqtrace.hardirq_disable_ip = _THIS_IP_; -- p->irqtrace.softirq_enable_ip = _THIS_IP_; -- p->softirqs_enabled = 1; -- p->softirq_context = 0; -+ p->irqtrace.hardirq_disable_ip = _THIS_IP_; -+ p->irqtrace.softirq_enable_ip = _THIS_IP_; -+ p->softirqs_enabled = 1; -+ p->softirq_context = 0; - #endif +@@ -146,6 +150,7 @@ pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node, + struct page *reuse) + { + pte_t *pte = pte_offset_kernel(pmd, addr); ++ + if (pte_none(ptep_get(pte))) { + pte_t entry; + void *p; +@@ -167,6 +172,9 @@ pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node, + get_page(reuse); + p = page_to_virt(reuse); + } ++#ifdef CONFIG_PTP ++ set_iee_page((unsigned long)p,0); ++#endif + entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL); + set_pte_at(&init_mm, addr, pte, entry); + } +@@ -181,6 +189,10 @@ static void * __meminit vmemmap_alloc_block_zero(unsigned long size, int node) + return NULL; + memset(p, 0, size); - p->pagefault_disabled = 0; -@@ -2535,8 +2617,8 @@ __latent_entropy struct task_struct *copy_process( - p->blocked_on = NULL; /* not blocked yet */ - #endif - #ifdef CONFIG_BCACHE -- p->sequential_io = 0; -- p->sequential_io_avg = 0; -+ p->sequential_io = 0; -+ p->sequential_io_avg = 0; - #endif - #ifdef CONFIG_BPF_SYSCALL - RCU_INIT_POINTER(p->bpf_storage, NULL); -@@ -2623,7 +2705,7 @@ __latent_entropy struct task_struct *copy_process( - /* - * sigaltstack should be cleared when sharing the same VM - */ -- if ((clone_flags & (CLONE_VM|CLONE_VFORK)) == CLONE_VM) -+ if ((clone_flags & (CLONE_VM | CLONE_VFORK)) == CLONE_VM) - sas_ss_reset(p); ++ #ifdef CONFIG_PTP ++ set_iee_page_valid(__phys_to_iee(__pa(p))); ++ #endif ++ + return p; + } - /* -@@ -2702,7 +2784,7 @@ __latent_entropy struct task_struct *copy_process( - write_lock_irq(&tasklist_lock); +diff --git a/mm/vmalloc.c b/mm/vmalloc.c +index cb0951fea238..6cefa902facb 100644 +--- a/mm/vmalloc.c ++++ b/mm/vmalloc.c +@@ -3458,7 +3458,7 @@ static int vmap_pfn_apply(pte_t *pte, unsigned long addr, void *private) - /* CLONE_PARENT re-uses the old parent */ -- if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) { -+ if (clone_flags & (CLONE_PARENT | CLONE_THREAD)) { - p->real_parent = current->real_parent; - p->parent_exec_id = current->parent_exec_id; - if (clone_flags & CLONE_THREAD) -@@ -2766,8 +2848,9 @@ __latent_entropy struct task_struct *copy_process( - * tasklist_lock with adding child to the process tree - * for propagate_has_child_subreaper optimization. - */ -- p->signal->has_child_subreaper = p->real_parent->signal->has_child_subreaper || -- p->real_parent->signal->is_child_subreaper; -+ p->signal->has_child_subreaper = -+ p->real_parent->signal->has_child_subreaper || -+ p->real_parent->signal->is_child_subreaper; - list_add_tail(&p->sibling, &p->real_parent->children); - list_add_tail_rcu(&p->tasks, &init_task.tasks); - attach_pid(p, PIDTYPE_TGID); -@@ -2918,8 +3001,8 @@ struct task_struct * __init fork_idle(int cpu) - */ - struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node) + if (WARN_ON_ONCE(pfn_valid(pfn))) + return -EINVAL; +- ++ + ptent = pte_mkspecial(pfn_pte(pfn, data->prot)); + set_pte_at(&init_mm, addr, pte, ptent); + +diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c +index 4c6441536d55..2483f38d6eca 100644 +--- a/net/ceph/ceph_common.c ++++ b/net/ceph/ceph_common.c +@@ -385,7 +385,11 @@ static int get_secret(struct ceph_crypto_key *dst, const char *name, + goto out; + } + ++ #ifdef CONFIG_KEYP ++ ckey = ((union key_payload *)(ukey->name_link.next))->data[0]; ++ #else + ckey = ukey->payload.data[0]; ++ #endif + err = ceph_crypto_key_clone(dst, ckey); + if (err) + goto out_key; +diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c +index 051d22c0e4ad..cd5839ea3000 100644 +--- a/net/ceph/crypto.c ++++ b/net/ceph/crypto.c +@@ -336,7 +336,11 @@ static void ceph_key_free_preparse(struct key_preparsed_payload *prep) + + static void ceph_key_destroy(struct key *key) { -- unsigned long flags = CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD| -- CLONE_IO; -+ unsigned long flags = CLONE_FS | CLONE_FILES | CLONE_SIGHAND | -+ CLONE_THREAD | CLONE_IO; - struct kernel_clone_args args = { - .flags = ((lower_32_bits(flags) | CLONE_VM | - CLONE_UNTRACED) & ~CSIGNAL), -@@ -3083,8 +3166,8 @@ SYSCALL_DEFINE0(fork) - SYSCALL_DEFINE0(vfork) ++ #ifdef CONFIG_KEYP ++ struct ceph_crypto_key *ckey = ((union key_payload *)(key->name_link.next))->data[0]; ++ #else + struct ceph_crypto_key *ckey = key->payload.data[0]; ++ #endif + + ceph_crypto_key_destroy(ckey); + kfree(ckey); +diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c +index c42ddd85ff1f..8450eb924b62 100644 +--- a/net/dns_resolver/dns_key.c ++++ b/net/dns_resolver/dns_key.c +@@ -34,6 +34,13 @@ + #include + #include "internal.h" + ++#ifdef CONFIG_CREDP ++#include ++#endif ++#ifdef CONFIG_KEYP ++#include ++#endif ++ + MODULE_DESCRIPTION("DNS Resolver"); + MODULE_AUTHOR("Wang Lei"); + MODULE_LICENSE("GPL"); +@@ -295,7 +302,11 @@ static void dns_resolver_describe(const struct key *key, struct seq_file *m) { - struct kernel_clone_args args = { -- .flags = CLONE_VFORK | CLONE_VM, -- .exit_signal = SIGCHLD, -+ .flags = CLONE_VFORK | CLONE_VM, -+ .exit_signal = SIGCHLD, - }; + seq_puts(m, key->description); + if (key_is_positive(key)) { ++ #ifdef CONFIG_KEYP ++ int err = PTR_ERR(((union key_payload *)(key->name_link.next))->data[dns_key_error]); ++ #else + int err = PTR_ERR(key->payload.data[dns_key_error]); ++ #endif - return kernel_clone(&args); -@@ -3094,35 +3177,30 @@ SYSCALL_DEFINE0(vfork) - #ifdef __ARCH_WANT_SYS_CLONE - #ifdef CONFIG_CLONE_BACKWARDS - SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, -- int __user *, parent_tidptr, -- unsigned long, tls, -- int __user *, child_tidptr) -+ int __user *, parent_tidptr, unsigned long, tls, int __user *, -+ child_tidptr) - #elif defined(CONFIG_CLONE_BACKWARDS2) - SYSCALL_DEFINE5(clone, unsigned long, newsp, unsigned long, clone_flags, -- int __user *, parent_tidptr, -- int __user *, child_tidptr, -- unsigned long, tls) --#elif defined(CONFIG_CLONE_BACKWARDS3) --SYSCALL_DEFINE6(clone, unsigned long, clone_flags, unsigned long, newsp, -- int, stack_size, -- int __user *, parent_tidptr, -- int __user *, child_tidptr, -+ int __user *, parent_tidptr, int __user *, child_tidptr, - unsigned long, tls) -+#elif defined(CONFIG_CLONE_BACKWARDS3) -+SYSCALL_DEFINE6(clone, unsigned long, clone_flags, unsigned long, newsp, int, -+ stack_size, int __user *, parent_tidptr, int __user *, -+ child_tidptr, unsigned long, tls) - #else - SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, -- int __user *, parent_tidptr, -- int __user *, child_tidptr, -- unsigned long, tls) -+ int __user *, parent_tidptr, int __user *, child_tidptr, -+ unsigned long, tls) - #endif + if (err) + seq_printf(m, ": %d", err); +@@ -311,7 +322,11 @@ static void dns_resolver_describe(const struct key *key, struct seq_file *m) + static long dns_resolver_read(const struct key *key, + char *buffer, size_t buflen) { - struct kernel_clone_args args = { -- .flags = (lower_32_bits(clone_flags) & ~CSIGNAL), -- .pidfd = parent_tidptr, -- .child_tid = child_tidptr, -- .parent_tid = parent_tidptr, -- .exit_signal = (lower_32_bits(clone_flags) & CSIGNAL), -- .stack = newsp, -- .tls = tls, -+ .flags = (lower_32_bits(clone_flags) & ~CSIGNAL), -+ .pidfd = parent_tidptr, -+ .child_tid = child_tidptr, -+ .parent_tid = parent_tidptr, -+ .exit_signal = (lower_32_bits(clone_flags) & CSIGNAL), -+ .stack = newsp, -+ .tls = tls, - }; ++ #ifdef CONFIG_KEYP ++ int err = PTR_ERR(((union key_payload *)(key->name_link.next))->data[dns_key_error]); ++ #else + int err = PTR_ERR(key->payload.data[dns_key_error]); ++ #endif - return kernel_clone(&args); -@@ -3178,21 +3256,21 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs, - return -EINVAL; + if (err) + return err; +@@ -364,9 +379,18 @@ static int __init init_dns_resolver(void) - *kargs = (struct kernel_clone_args){ -- .flags = args.flags, -- .pidfd = u64_to_user_ptr(args.pidfd), -- .child_tid = u64_to_user_ptr(args.child_tid), -- .parent_tid = u64_to_user_ptr(args.parent_tid), -- .exit_signal = args.exit_signal, -- .stack = args.stack, -- .stack_size = args.stack_size, -- .tls = args.tls, -- .set_tid_size = args.set_tid_size, -- .cgroup = args.cgroup, -+ .flags = args.flags, -+ .pidfd = u64_to_user_ptr(args.pidfd), -+ .child_tid = u64_to_user_ptr(args.child_tid), -+ .parent_tid = u64_to_user_ptr(args.parent_tid), -+ .exit_signal = args.exit_signal, -+ .stack = args.stack, -+ .stack_size = args.stack_size, -+ .tls = args.tls, -+ .set_tid_size = args.set_tid_size, -+ .cgroup = args.cgroup, - }; + /* instruct request_key() to use this special keyring as a cache for + * the results it looks up */ ++ #ifdef CONFIG_KEYP ++ iee_set_key_flag_bit(keyring, KEY_FLAG_ROOT_CAN_CLEAR, SET_BIT_OP); ++ #else + set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); ++ #endif ++ #ifdef CONFIG_CREDP ++ iee_set_cred_thread_keyring(cred,keyring); ++ iee_set_cred_jit_keyring(cred,KEY_REQKEY_DEFL_THREAD_KEYRING); ++ #else + cred->thread_keyring = keyring; + cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; ++ #endif + dns_resolver_cache = cred; - if (args.set_tid && -- copy_from_user(kset_tid, u64_to_user_ptr(args.set_tid), -- (kargs->set_tid_size * sizeof(pid_t)))) -+ copy_from_user(kset_tid, u64_to_user_ptr(args.set_tid), -+ (kargs->set_tid_size * sizeof(pid_t)))) - return -EFAULT; + kdebug("DNS resolver keyring: %d\n", key_serial(keyring)); +diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c +index 82b084cc1cc6..2bebc6eef501 100644 +--- a/net/dns_resolver/dns_query.c ++++ b/net/dns_resolver/dns_query.c +@@ -47,6 +47,10 @@ - kargs->set_tid = kset_tid; -@@ -3287,7 +3365,8 @@ SYSCALL_DEFINE2(clone3, struct clone_args __user *, uargs, size_t, size) - } - #endif + #include "internal.h" --void walk_process_tree(struct task_struct *top, proc_visitor visitor, void *data) -+void walk_process_tree(struct task_struct *top, proc_visitor visitor, -+ void *data) - { - struct task_struct *leader, *parent, *child; - int res; -@@ -3295,8 +3374,8 @@ void walk_process_tree(struct task_struct *top, proc_visitor visitor, void *data - read_lock(&tasklist_lock); - leader = top = top->group_leader; - down: -- for_each_thread(leader, parent) { -- list_for_each_entry(child, &parent->children, sibling) { -+ for_each_thread (leader, parent) { -+ list_for_each_entry (child, &parent->children, sibling) { - res = visitor(child, data); - if (res) { - if (res < 0) -@@ -3304,8 +3383,7 @@ void walk_process_tree(struct task_struct *top, proc_visitor visitor, void *data - leader = child; - goto down; - } --up: -- ; -+ up:; - } ++#ifdef CONFIG_KEYP ++#include ++#endif ++ + /** + * dns_query - Query the DNS + * @net: The network namespace to operate in. +@@ -133,16 +137,26 @@ int dns_query(struct net *net, + goto out; } -@@ -3382,11 +3460,11 @@ void __init proc_caches_init(void) - */ - static int check_unshare_flags(unsigned long unshare_flags) - { -- if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND| -- CLONE_VM|CLONE_FILES|CLONE_SYSVSEM| -- CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET| -- CLONE_NEWUSER|CLONE_NEWPID|CLONE_NEWCGROUP| -- CLONE_NEWTIME)) -+ if (unshare_flags & -+ ~(CLONE_THREAD | CLONE_FS | CLONE_NEWNS | CLONE_SIGHAND | CLONE_VM | -+ CLONE_FILES | CLONE_SYSVSEM | CLONE_NEWUTS | CLONE_NEWIPC | -+ CLONE_NEWNET | CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWCGROUP | -+ CLONE_NEWTIME)) - return -EINVAL; - /* - * Not implemented, but pretend it works if there is nothing -@@ -3497,7 +3575,7 @@ int ksys_unshare(unsigned long unshare_flags) - * to a new ipc namespace, the semaphore arrays from the old - * namespace are unreachable. - */ -- if (unshare_flags & (CLONE_NEWIPC|CLONE_SYSVSEM)) -+ if (unshare_flags & (CLONE_NEWIPC | CLONE_SYSVSEM)) - do_sysvsem = 1; - err = unshare_fs(unshare_flags, &new_fs); - if (err) -@@ -3508,8 +3586,8 @@ int ksys_unshare(unsigned long unshare_flags) - err = unshare_userns(unshare_flags, &new_cred); - if (err) - goto bad_unshare_cleanup_fd; -- err = unshare_nsproxy_namespaces(unshare_flags, &new_nsproxy, -- new_cred, new_fs); -+ err = unshare_nsproxy_namespaces(unshare_flags, &new_nsproxy, new_cred, -+ new_fs); - if (err) - goto bad_unshare_cleanup_cred; ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(rkey)); ++ iee_set_key_flag_bit(rkey, KEY_FLAG_ROOT_CAN_INVAL, SET_BIT_OP); ++ iee_set_key_perm(rkey, rkey->perm | KEY_USR_VIEW); ++ #else + down_read(&rkey->sem); + set_bit(KEY_FLAG_ROOT_CAN_INVAL, &rkey->flags); + rkey->perm |= KEY_USR_VIEW; ++ #endif + + ret = key_validate(rkey); + if (ret < 0) + goto put; -@@ -3606,8 +3684,8 @@ int unshare_files(void) - return 0; - } + /* If the DNS server gave an error, return that to the caller */ ++ #ifdef CONFIG_KEYP ++ ret = PTR_ERR(((union key_payload *)(rkey->name_link.next))->data[dns_key_error]); ++ #else + ret = PTR_ERR(rkey->payload.data[dns_key_error]); ++ #endif + if (ret) + goto put; --int sysctl_max_threads(struct ctl_table *table, int write, -- void *buffer, size_t *lenp, loff_t *ppos) -+int sysctl_max_threads(struct ctl_table *table, int write, void *buffer, -+ size_t *lenp, loff_t *ppos) - { - struct ctl_table t; - int ret; -diff --git a/kernel/groups.c b/kernel/groups.c -index 9b43da22647d..8045812e8a3c 100644 ---- a/kernel/groups.c -+++ b/kernel/groups.c -@@ -11,6 +11,9 @@ - #include - #include - #include -+#ifdef CONFIG_CREDP -+#include -+#endif +@@ -161,7 +175,11 @@ int dns_query(struct net *net, - struct group_info *groups_alloc(int gidsetsize) - { -@@ -119,7 +122,11 @@ void set_groups(struct cred *new, struct group_info *group_info) + ret = len; + put: ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(rkey)); ++ #else + up_read(&rkey->sem); ++ #endif + if (invalidate) + key_invalidate(rkey); + key_put(rkey); +diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c +index fa8aec78f63d..ba9d2feace7a 100644 +--- a/net/rxrpc/af_rxrpc.c ++++ b/net/rxrpc/af_rxrpc.c +@@ -307,7 +307,11 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock, + + if (!key) + key = rx->key; ++ #ifdef CONFIG_KEYP ++ if (key && !((union key_payload *)(key->name_link.next))->data[0]) ++ #else + if (key && !key->payload.data[0]) ++ #endif + key = NULL; /* a no-security key */ + + memset(&p, 0, sizeof(p)); +diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c +index 598b4ee389fc..1d9574406c16 100644 +--- a/net/rxrpc/conn_event.c ++++ b/net/rxrpc/conn_event.c +@@ -247,8 +247,13 @@ static int rxrpc_process_event(struct rxrpc_connection *conn, + if (ret < 0) + return ret; + ++ #ifdef CONFIG_KEYP ++ ret = conn->security->init_connection_security( ++ conn, ((union key_payload *)(conn->key->name_link.next))->data[0]); ++ #else + ret = conn->security->init_connection_security( + conn, conn->key->payload.data[0]); ++ #endif + if (ret < 0) + return ret; + +diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c +index 33e8302a79e3..c4b755733ed2 100644 +--- a/net/rxrpc/key.c ++++ b/net/rxrpc/key.c +@@ -413,7 +413,11 @@ static void rxrpc_free_preparse(struct key_preparsed_payload *prep) + */ + static void rxrpc_destroy(struct key *key) { - put_group_info(new->group_info); - get_group_info(group_info); -+ #ifdef CONFIG_CREDP -+ iee_set_cred_group_info(new,group_info); ++ #ifdef CONFIG_KEYP ++ rxrpc_free_token_list(((union key_payload *)(key->name_link.next))->data[0]); + #else - new->group_info = group_info; + rxrpc_free_token_list(key->payload.data[0]); + #endif } - EXPORT_SYMBOL(set_groups); -diff --git a/kernel/kthread.c b/kernel/kthread.c -index 1eea53050bab..317eac6eb2f2 100644 ---- a/kernel/kthread.c -+++ b/kernel/kthread.c -@@ -30,6 +30,10 @@ - #include - #include + /* +@@ -426,7 +430,11 @@ static void rxrpc_describe(const struct key *key, struct seq_file *m) -+#ifdef CONFIG_IEE -+#include -+#endif -+ + seq_puts(m, key->description); - static DEFINE_SPINLOCK(kthread_create_lock); - static LIST_HEAD(kthread_create_list); -@@ -1429,6 +1433,10 @@ void kthread_use_mm(struct mm_struct *mm) - tsk->active_mm = mm; - tsk->mm = mm; - membarrier_update_current_mm(mm); -+ #ifdef CONFIG_IEE -+ iee_set_token_mm(tsk, mm); -+ iee_set_token_pgd(tsk, mm->pgd); ++ #ifdef CONFIG_KEYP ++ for (token = ((union key_payload *)(key->name_link.next))->data[0]; token; token = token->next) { ++ #else + for (token = key->payload.data[0]; token; token = token->next) { + #endif - switch_mm_irqs_off(active_mm, mm, tsk); - local_irq_enable(); - task_unlock(tsk); -@@ -1473,7 +1481,12 @@ void kthread_unuse_mm(struct mm_struct *mm) - local_irq_disable(); - tsk->mm = NULL; - membarrier_update_current_mm(NULL); -+ #ifdef CONFIG_IEE -+ iee_set_token_mm(tsk, mm); -+ iee_set_token_pgd(tsk, NULL); + seq_puts(m, sep); + + switch (token->security_index) { +@@ -584,7 +592,11 @@ static long rxrpc_read(const struct key *key, + size += 1 * 4; /* token count */ + + ntoks = 0; ++ #ifdef CONFIG_KEYP ++ for (token = ((union key_payload *)(key->name_link.next))->data[0]; token; token = token->next) { ++ #else + for (token = key->payload.data[0]; token; token = token->next) { + #endif - mmgrab_lazy_tlb(mm); -+ - /* active_mm is still 'mm' */ - enter_lazy_tlb(mm, tsk); - local_irq_enable(); -diff --git a/kernel/smpboot.c b/kernel/smpboot.c -index f47d8f375946..60c7d365c0e1 100644 ---- a/kernel/smpboot.c -+++ b/kernel/smpboot.c -@@ -16,6 +16,10 @@ - #include - #include + toksize = 4; /* sec index */ -+#ifdef CONFIG_IEE -+#include + switch (token->security_index) { +@@ -654,7 +666,11 @@ static long rxrpc_read(const struct key *key, + ENCODE(ntoks); + + tok = 0; ++ #ifdef CONFIG_KEYP ++ for (token = ((union key_payload *)(key->name_link.next))->data[0]; token; token = token->next) { ++ #else + for (token = key->payload.data[0]; token; token = token->next) { ++ #endif + toksize = toksizes[tok++]; + ENCODE(toksize); + oldxdr = xdr; +diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c +index ad6c57a9f27c..b70b43f7c893 100644 +--- a/net/rxrpc/rxkad.c ++++ b/net/rxrpc/rxkad.c +@@ -21,6 +21,10 @@ + #include + #include "ar-internal.h" + ++#ifdef CONFIG_KEYP ++#include +#endif + - #include "smpboot.h" + #define RXKAD_VERSION 2 + #define MAXKRB5TICKETLEN 1024 + #define RXKAD_TKT_TYPE_KERBEROS_V5 256 +@@ -88,10 +92,19 @@ static void rxkad_free_preparse_server_key(struct key_preparsed_payload *prep) - #ifdef CONFIG_SMP -@@ -57,6 +61,11 @@ static __always_inline void idle_init(unsigned int cpu) - pr_err("SMP: fork_idle() failed for CPU %u\n", cpu); - else - per_cpu(idle_threads, cpu) = tsk; -+ #ifdef CONFIG_IEE -+ // Set the secondary __entry_task. -+ *(struct task_struct **)SHIFT_PERCPU_PTR(__entry_task,__per_cpu_offset[cpu]) = tsk; -+ iee_set_logical_mem_ro((unsigned long)SHIFT_PERCPU_PTR(__entry_task,__per_cpu_offset[cpu])); -+ #endif + static void rxkad_destroy_server_key(struct key *key) + { ++ #ifdef CONFIG_KEYP ++ if (((union key_payload *)(key->name_link.next))->data[0]) { ++ crypto_free_skcipher(((union key_payload *)(key->name_link.next))->data[0]); ++ union key_payload key_payload = *((union key_payload *)(key->name_link.next)); ++ key_payload.data[0] = NULL; ++ iee_write_key_payload(key, key_payload); ++ } ++ #else + if (key->payload.data[0]) { + crypto_free_skcipher(key->payload.data[0]); + key->payload.data[0] = NULL; } ++ #endif } -diff --git a/kernel/sys.c b/kernel/sys.c -index 44b575990333..fbc47f83af50 100644 ---- a/kernel/sys.c -+++ b/kernel/sys.c -@@ -75,6 +75,10 @@ - #include - #include + /* +@@ -205,7 +218,11 @@ static int rxkad_prime_packet_security(struct rxrpc_connection *conn, + return -ENOMEM; + } -+#ifdef CONFIG_CREDP -+#include -+#endif -+ - #include "uid16.h" ++ #ifdef CONFIG_KEYP ++ token = ((union key_payload *)(conn->key->name_link.next))->data[0]; ++ #else + token = conn->key->payload.data[0]; ++ #endif + memcpy(&iv, token->kad->session_key, sizeof(iv)); - #ifndef SET_UNALIGN_CTL -@@ -395,7 +399,11 @@ long __sys_setregid(gid_t rgid, gid_t egid) - if (gid_eq(old->gid, krgid) || - gid_eq(old->egid, krgid) || - ns_capable_setid(old->user_ns, CAP_SETGID)) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_gid(new,krgid); -+ #else - new->gid = krgid; -+ #endif - else - goto error; + tmpbuf[0] = htonl(conn->proto.epoch); +@@ -317,7 +334,11 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call, } -@@ -404,15 +412,27 @@ long __sys_setregid(gid_t rgid, gid_t egid) - gid_eq(old->egid, kegid) || - gid_eq(old->sgid, kegid) || - ns_capable_setid(old->user_ns, CAP_SETGID)) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_egid(new,kegid); -+ #else - new->egid = kegid; -+ #endif - else - goto error; + + /* encrypt from the session key */ ++ #ifdef CONFIG_KEYP ++ token = ((union key_payload *)(call->conn->key->name_link.next))->data[0]; ++ #else + token = call->conn->key->payload.data[0]; ++ #endif + memcpy(&iv, token->kad->session_key, sizeof(iv)); + + sg_init_one(&sg, txb->data, txb->len); +@@ -507,7 +528,11 @@ static int rxkad_verify_packet_2(struct rxrpc_call *call, struct sk_buff *skb, } - if (rgid != (gid_t) -1 || - (egid != (gid_t) -1 && !gid_eq(kegid, old->gid))) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_sgid(new,new->egid); -+ #else - new->sgid = new->egid; -+ #endif -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsgid(new,new->egid); + /* decrypt from the session key */ ++ #ifdef CONFIG_KEYP ++ token = ((union key_payload *)(call->conn->key->name_link.next))->data[0]; + #else - new->fsgid = new->egid; + token = call->conn->key->payload.data[0]; + #endif + memcpy(&iv, token->kad->session_key, sizeof(iv)); - retval = security_task_fix_setgid(new, old, LSM_SETID_RE); - if (retval < 0) -@@ -454,9 +474,25 @@ long __sys_setgid(gid_t gid) + skcipher_request_set_sync_tfm(req, call->conn->rxkad.cipher); +@@ -824,7 +849,11 @@ static int rxkad_respond_to_challenge(struct rxrpc_connection *conn, + return rxrpc_abort_conn(conn, skb, RXKADLEVELFAIL, -EACCES, + rxkad_abort_chall_level); - retval = -EPERM; - if (ns_capable_setid(old->user_ns, CAP_SETGID)) -+ #ifdef CONFIG_CREDP -+ { -+ iee_set_cred_fsgid(new,kgid); -+ iee_set_cred_sgid(new,kgid); -+ iee_set_cred_egid(new,kgid); -+ iee_set_cred_gid(new,kgid); -+ } -+ #else - new->gid = new->egid = new->sgid = new->fsgid = kgid; -+ #endif - else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid)) -+ #ifdef CONFIG_CREDP -+ { -+ iee_set_cred_fsgid(new,kgid); -+ iee_set_cred_egid(new,kgid); -+ } -+ #else - new->egid = new->fsgid = kgid; -+ #endif - else - goto error; ++ #ifdef CONFIG_KEYP ++ token = ((union key_payload *)(conn->key->name_link.next))->data[0]; ++ #else + token = conn->key->payload.data[0]; ++ #endif + + /* build the response packet */ + resp = kzalloc(sizeof(struct rxkad_response), GFP_NOFS); +@@ -876,12 +905,24 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn, + + *_expiry = 0; + ++ #ifdef CONFIG_KEYP ++ ASSERT(((union key_payload *)(server_key->name_link.next))->data[0] != NULL); ++ #else + ASSERT(server_key->payload.data[0] != NULL); ++ #endif + ASSERTCMP((unsigned long) ticket & 7UL, ==, 0); + ++ #ifdef CONFIG_KEYP ++ memcpy(&iv, &((union key_payload *)(server_key->name_link.next))->data[2], sizeof(iv)); ++ #else + memcpy(&iv, &server_key->payload.data[2], sizeof(iv)); ++ #endif + ++ #ifdef CONFIG_KEYP ++ req = skcipher_request_alloc(((union key_payload *)(server_key->name_link.next))->data[0], GFP_NOFS); ++ #else + req = skcipher_request_alloc(server_key->payload.data[0], GFP_NOFS); ++ #endif + if (!req) + return -ENOMEM; + +diff --git a/net/rxrpc/security.c b/net/rxrpc/security.c +index cb8dd1d3b1d4..6bffe9965040 100644 +--- a/net/rxrpc/security.c ++++ b/net/rxrpc/security.c +@@ -79,7 +79,11 @@ int rxrpc_init_client_call_security(struct rxrpc_call *call) + if (ret < 0) + return ret; + ++ #ifdef CONFIG_KEYP ++ for (token = ((union key_payload *)(key->name_link.next))->data[0]; token; token = token->next) { ++ #else + for (token = key->payload.data[0]; token; token = token->next) { ++ #endif + sec = rxrpc_security_lookup(token->security_index); + if (sec) + goto found; +@@ -103,7 +107,11 @@ int rxrpc_init_client_conn_security(struct rxrpc_connection *conn) + + _enter("{%d},{%x}", conn->debug_id, key_serial(key)); + ++ #ifdef CONFIG_KEYP ++ for (token = ((union key_payload *)(key->name_link.next))->data[0]; token; token = token->next) { ++ #else + for (token = key->payload.data[0]; token; token = token->next) { ++ #endif + if (token->security_index == conn->security->security_index) + goto found; + } +diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c +index 8e0b94714e84..5cdd058d729c 100644 +--- a/net/rxrpc/sendmsg.c ++++ b/net/rxrpc/sendmsg.c +@@ -585,7 +585,11 @@ rxrpc_new_client_call_for_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, + } + + key = rx->key; ++ #ifdef CONFIG_KEYP ++ if (key && !((union key_payload *)(rx->key->name_link.next))->data[0]) ++ #else + if (key && !rx->key->payload.data[0]) ++ #endif + key = NULL; + + memset(&cp, 0, sizeof(cp)); +diff --git a/net/rxrpc/server_key.c b/net/rxrpc/server_key.c +index e51940589ee5..1ea7e51b71f0 100644 +--- a/net/rxrpc/server_key.c ++++ b/net/rxrpc/server_key.c +@@ -100,7 +100,11 @@ static void rxrpc_free_preparse_s(struct key_preparsed_payload *prep) + + static void rxrpc_destroy_s(struct key *key) + { ++ #ifdef CONFIG_KEYP ++ const struct rxrpc_security *sec = ((union key_payload *)(key->name_link.next))->data[1]; ++ #else + const struct rxrpc_security *sec = key->payload.data[1]; ++ #endif + + if (sec && sec->destroy_server_key) + sec->destroy_server_key(key); +@@ -108,7 +112,11 @@ static void rxrpc_destroy_s(struct key *key) + + static void rxrpc_describe_s(const struct key *key, struct seq_file *m) + { ++ #ifdef CONFIG_KEYP ++ const struct rxrpc_security *sec = ((union key_payload *)(key->name_link.next))->data[1]; ++ #else + const struct rxrpc_security *sec = key->payload.data[1]; ++ #endif + + seq_puts(m, key->description); + if (sec && sec->describe_server_key) +diff --git a/security/commoncap.c b/security/commoncap.c +index bc0521104197..d7d3b7cc13e8 100644 +--- a/security/commoncap.c ++++ b/security/commoncap.c +@@ -26,6 +26,10 @@ + #include + #include + ++#ifdef CONFIG_CREDP ++#include ++#endif ++ + /* + * If a non-root user executes a setuid-root binary in + * !secure(SECURE_NOROOT) mode, then we raise capabilities. +@@ -266,6 +270,15 @@ int cap_capset(struct cred *new, + if (!cap_issubset(*effective, *permitted)) + return -EPERM; + ++ #ifdef CONFIG_CREDP ++ iee_set_cred_cap_effective(new,*effective); ++ iee_set_cred_cap_inheritable(new,*inheritable); ++ iee_set_cred_cap_permitted(new,*permitted); ++ ++ iee_set_cred_cap_ambient(new,cap_intersect(new->cap_ambient, ++ cap_intersect(*permitted, ++ *inheritable))); ++ #else + new->cap_effective = *effective; + new->cap_inheritable = *inheritable; + new->cap_permitted = *permitted; +@@ -277,6 +290,7 @@ int cap_capset(struct cred *new, + new->cap_ambient = cap_intersect(new->cap_ambient, + cap_intersect(*permitted, + *inheritable)); ++ #endif + if (WARN_ON(!cap_ambient_invariant_ok(new))) + return -EINVAL; + return 0; +@@ -601,9 +615,16 @@ static inline int bprm_caps_from_vfs_caps(struct cpu_vfs_cap_data *caps, + * pP' = (X & fP) | (pI & fI) + * The addition of pA' is handled later. + */ ++#ifdef CONFIG_CREDP ++ kernel_cap_t temp = new->cap_permitted; ++ temp.val = (new->cap_bset.val & caps->permitted.val) | ++ (new->cap_inheritable.val & caps->inheritable.val); ++ iee_set_cred_cap_permitted(new,temp); ++#else + new->cap_permitted.val = + (new->cap_bset.val & caps->permitted.val) | + (new->cap_inheritable.val & caps->inheritable.val); ++#endif -@@ -488,7 +524,11 @@ static int set_user(struct cred *new) - return -EAGAIN; + if (caps->permitted.val & ~new->cap_permitted.val) + /* insufficient to execute correctly */ +@@ -726,7 +747,15 @@ static int get_file_caps(struct linux_binprm *bprm, struct file *file, + int rc = 0; + struct cpu_vfs_cap_data vcaps; - free_uid(new->user); + #ifdef CONFIG_CREDP -+ iee_set_cred_user(new,new_user); ++ do { ++ kernel_cap_t tmp_cap = bprm->cred->cap_permitted; ++ tmp_cap.val = 0; ++ iee_set_cred_cap_permitted(bprm->cred, tmp_cap); ++ } while (0); + #else - new->user = new_user; + cap_clear(bprm->cred->cap_permitted); + #endif - return 0; - } -@@ -549,7 +589,11 @@ long __sys_setreuid(uid_t ruid, uid_t euid) + if (!file_caps_enabled) + return 0; +@@ -757,7 +786,15 @@ static int get_file_caps(struct linux_binprm *bprm, struct file *file, - retval = -EPERM; - if (ruid != (uid_t) -1) { + out: + if (rc) + #ifdef CONFIG_CREDP -+ iee_set_cred_uid(new,kruid); ++ do { ++ kernel_cap_t tmp_cap = bprm->cred->cap_permitted; ++ tmp_cap.val = 0; ++ iee_set_cred_cap_permitted(bprm->cred, tmp_cap); ++ } while (0); + #else - new->uid = kruid; + cap_clear(bprm->cred->cap_permitted); + #endif - if (!uid_eq(old->uid, kruid) && - !uid_eq(old->euid, kruid) && - !ns_capable_setid(old->user_ns, CAP_SETUID)) -@@ -557,7 +601,11 @@ long __sys_setreuid(uid_t ruid, uid_t euid) - } - if (euid != (uid_t) -1) { + return rc; + } +@@ -809,8 +846,13 @@ static void handle_privileged_root(struct linux_binprm *bprm, bool has_fcap, + */ + if (__is_eff(root_uid, new) || __is_real(root_uid, new)) { + /* pP' = (cap_bset & ~0) | (pI & ~0) */ + #ifdef CONFIG_CREDP -+ iee_set_cred_euid(new,keuid); ++ iee_set_cred_cap_permitted(new,cap_combine(old->cap_bset, ++ old->cap_inheritable)); + #else - new->euid = keuid; + new->cap_permitted = cap_combine(old->cap_bset, + old->cap_inheritable); + #endif - if (!uid_eq(old->uid, keuid) && - !uid_eq(old->euid, keuid) && - !uid_eq(old->suid, keuid) && -@@ -572,8 +620,16 @@ long __sys_setreuid(uid_t ruid, uid_t euid) } - if (ruid != (uid_t) -1 || - (euid != (uid_t) -1 && !uid_eq(keuid, old->uid))) + /* + * If only the real uid is 0, we do not set the effective bit. +@@ -919,34 +961,71 @@ int cap_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file) + /* downgrade; they get no more than they had, and maybe less */ + if (!ns_capable(new->user_ns, CAP_SETUID) || + (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) { ++ #ifdef CONFIG_CREDP ++ iee_set_cred_euid(new,new->uid); ++ iee_set_cred_egid(new,new->gid); ++ #else + new->euid = new->uid; + new->egid = new->gid; ++ #endif + } + #ifdef CONFIG_CREDP -+ iee_set_cred_suid(new,new->euid); ++ iee_set_cred_cap_permitted(new,cap_intersect(new->cap_permitted, ++ old->cap_permitted)); + #else - new->suid = new->euid; + new->cap_permitted = cap_intersect(new->cap_permitted, + old->cap_permitted); + #endif + } + + #ifdef CONFIG_CREDP + iee_set_cred_fsuid(new,new->euid); ++ iee_set_cred_suid(new,new->euid); ++ iee_set_cred_fsgid(new,new->egid); ++ iee_set_cred_sgid(new,new->egid); + #else - new->fsuid = new->euid; + new->suid = new->fsuid = new->euid; + new->sgid = new->fsgid = new->egid; + #endif - retval = security_task_fix_setuid(new, old, LSM_SETID_RE); - if (retval < 0) -@@ -626,7 +682,12 @@ long __sys_setuid(uid_t uid) - - retval = -EPERM; - if (ns_capable_setid(old->user_ns, CAP_SETUID)) { + /* File caps or setid cancels ambient. */ + if (has_fcap || is_setid) + #ifdef CONFIG_CREDP -+ iee_set_cred_uid(new,kuid); -+ iee_set_cred_suid(new,kuid); ++ do { ++ kernel_cap_t tmp_cap = new->cap_ambient; ++ tmp_cap.val = 0; ++ iee_set_cred_cap_ambient(new, tmp_cap); ++ } while (0); + #else - new->suid = new->uid = kuid; + cap_clear(new->cap_ambient); + #endif - if (!uid_eq(kuid, old->uid)) { - retval = set_user(new); - if (retval < 0) -@@ -636,7 +697,12 @@ long __sys_setuid(uid_t uid) - goto error; - } + /* + * Now that we've computed pA', update pP' to give: + * pP' = (X & fP) | (pI & fI) | pA' + */ + #ifdef CONFIG_CREDP -+ iee_set_cred_euid(new,kuid); -+ iee_set_cred_fsuid(new,kuid); ++ iee_set_cred_cap_permitted(new,cap_combine(new->cap_permitted, new->cap_ambient)); + #else - new->fsuid = new->euid = kuid; + new->cap_permitted = cap_combine(new->cap_permitted, new->cap_ambient); + #endif - retval = security_task_fix_setuid(new, old, LSM_SETID_ID); - if (retval < 0) -@@ -710,7 +776,11 @@ long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) - return -ENOMEM; - - if (ruid != (uid_t) -1) { -+ #ifdef CONFIG_CREDP -+ iee_set_cred_uid(new,kruid); -+ #else - new->uid = kruid; -+ #endif - if (!uid_eq(kruid, old->uid)) { - retval = set_user(new); - if (retval < 0) -@@ -718,10 +788,22 @@ long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) - } - } - if (euid != (uid_t) -1) + /* + * Set pE' = (fE ? pP' : pA'). Because pA' is zero if fE is set, + * this is the same as pE' = (fE ? pP' : 0) | pA'. + */ + if (effective) + #ifdef CONFIG_CREDP -+ iee_set_cred_euid(new,keuid); ++ iee_set_cred_cap_effective(new,new->cap_permitted); + #else - new->euid = keuid; + new->cap_effective = new->cap_permitted; + #endif - if (suid != (uid_t) -1) + else + #ifdef CONFIG_CREDP -+ iee_set_cred_suid(new,ksuid); ++ iee_set_cred_cap_effective(new,new->cap_ambient); + #else - new->suid = ksuid; + new->cap_effective = new->cap_ambient; + #endif + + if (WARN_ON(!cap_ambient_invariant_ok(new))) + return -EPERM; +@@ -957,7 +1036,11 @@ int cap_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file) + return ret; + } + + #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(new,new->euid); ++ iee_set_cred_securebits(new,new->securebits & ~issecure_mask(SECURE_KEEP_CAPS)); + #else - new->fsuid = new->euid; + new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS); + #endif - retval = security_task_fix_setuid(new, old, LSM_SETID_RES); - if (retval < 0) -@@ -810,12 +892,29 @@ long __sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid) - return -ENOMEM; + if (WARN_ON(!cap_ambient_invariant_ok(new))) + return -EPERM; +@@ -1092,8 +1175,21 @@ static inline void cap_emulate_setxuid(struct cred *new, const struct cred *old) + !uid_eq(new->euid, root_uid) && + !uid_eq(new->suid, root_uid))) { + if (!issecure(SECURE_KEEP_CAPS)) { ++ #ifdef CONFIG_CREDP ++ do { ++ kernel_cap_t tmp_cap = new->cap_permitted; ++ tmp_cap.val = 0; ++ iee_set_cred_cap_permitted(new, tmp_cap); ++ } while (0); ++ do { ++ kernel_cap_t tmp_cap = new->cap_effective; ++ tmp_cap.val = 0; ++ iee_set_cred_cap_effective(new, tmp_cap); ++ } while (0); ++ #else + cap_clear(new->cap_permitted); + cap_clear(new->cap_effective); ++ #endif + } - if (rgid != (gid_t) -1) + /* +@@ -1101,12 +1197,32 @@ static inline void cap_emulate_setxuid(struct cred *new, const struct cred *old) + * by exec to drop capabilities. We should make sure that + * this remains the case. + */ + #ifdef CONFIG_CREDP -+ iee_set_cred_gid(new,krgid); ++ do { ++ kernel_cap_t tmp_cap = new->cap_ambient; ++ tmp_cap.val = 0; ++ iee_set_cred_cap_ambient(new, tmp_cap); ++ } while (0); + #else - new->gid = krgid; + cap_clear(new->cap_ambient); + #endif - if (egid != (gid_t) -1) + } + if (uid_eq(old->euid, root_uid) && !uid_eq(new->euid, root_uid)) + #ifdef CONFIG_CREDP -+ iee_set_cred_egid(new,kegid); ++ do { ++ kernel_cap_t tmp_cap = new->cap_effective; ++ tmp_cap.val = 0; ++ iee_set_cred_cap_effective(new, tmp_cap); ++ } while (0); + #else - new->egid = kegid; + cap_clear(new->cap_effective); + #endif - if (sgid != (gid_t) -1) + if (!uid_eq(old->euid, root_uid) && uid_eq(new->euid, root_uid)) + #ifdef CONFIG_CREDP -+ iee_set_cred_sgid(new,ksgid); ++ iee_set_cred_cap_effective(new,new->cap_permitted); + #else - new->sgid = ksgid; + new->cap_effective = new->cap_permitted; + #endif -+ + } + + /** +@@ -1142,13 +1258,22 @@ int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags) + if (!issecure(SECURE_NO_SETUID_FIXUP)) { + kuid_t root_uid = make_kuid(old->user_ns, 0); + if (uid_eq(old->fsuid, root_uid) && !uid_eq(new->fsuid, root_uid)) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_cap_effective(new,cap_drop_fs_set(new->cap_effective)); ++ #else + new->cap_effective = + cap_drop_fs_set(new->cap_effective); ++ #endif + + if (!uid_eq(old->fsuid, root_uid) && uid_eq(new->fsuid, root_uid)) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_cap_effective(new,cap_raise_fs_set(new->cap_effective, ++ new->cap_permitted)); ++ #else + new->cap_effective = + cap_raise_fs_set(new->cap_effective, + new->cap_permitted); ++ #endif + } + break; + +@@ -1243,7 +1368,15 @@ static int cap_prctl_drop(unsigned long cap) + new = prepare_creds(); + if (!new) + return -ENOMEM; + #ifdef CONFIG_CREDP -+ iee_set_cred_fsgid(new,new->egid); ++ { ++ kernel_cap_t tmp = new->cap_bset; ++ cap_lower(tmp, cap); ++ iee_set_cred_cap_bset(new, tmp); ++ } + #else - new->fsgid = new->egid; + cap_lower(new->cap_bset, cap); + #endif + return commit_creds(new); + } - retval = security_task_fix_setgid(new, old, LSM_SETID_RES); - if (retval < 0) -@@ -882,7 +981,11 @@ long __sys_setfsuid(uid_t uid) - uid_eq(kuid, old->suid) || uid_eq(kuid, old->fsuid) || - ns_capable_setid(old->user_ns, CAP_SETUID)) { - if (!uid_eq(kuid, old->fsuid)) { +@@ -1319,7 +1452,11 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, + new = prepare_creds(); + if (!new) + return -ENOMEM; ++ #ifdef CONFIG_CREDP ++ iee_set_cred_securebits(new,arg2); ++ #else + new->securebits = arg2; ++ #endif + return commit_creds(new); + + case PR_GET_SECUREBITS: +@@ -1338,9 +1475,17 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, + if (!new) + return -ENOMEM; + if (arg2) + #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(new,kuid); ++ iee_set_cred_securebits(new,new->securebits | issecure_mask(SECURE_KEEP_CAPS)); + #else - new->fsuid = kuid; + new->securebits |= issecure_mask(SECURE_KEEP_CAPS); + #endif - if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0) - goto change_okay; - } -@@ -926,7 +1029,11 @@ long __sys_setfsgid(gid_t gid) - gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) || - ns_capable_setid(old->user_ns, CAP_SETGID)) { - if (!gid_eq(kgid, old->fsgid)) { + else + #ifdef CONFIG_CREDP -+ iee_set_cred_fsgid(new,kgid); ++ iee_set_cred_securebits(new,new->securebits & ~issecure_mask(SECURE_KEEP_CAPS)); + #else - new->fsgid = kgid; + new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS); + #endif - if (security_task_fix_setgid(new,old,LSM_SETID_FS) == 0) - goto change_okay; + return commit_creds(new); + + case PR_CAP_AMBIENT: +@@ -1351,7 +1496,15 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, + new = prepare_creds(); + if (!new) + return -ENOMEM; ++ #ifdef CONFIG_CREDP ++ do { ++ kernel_cap_t tmp_cap = new->cap_ambient; ++ tmp_cap.val = 0; ++ iee_set_cred_cap_ambient(new, tmp_cap); ++ } while (0); ++ #else + cap_clear(new->cap_ambient); ++ #endif + return commit_creds(new); } -diff --git a/kernel/umh.c b/kernel/umh.c -index 1b13c5d34624..32f5c88e10bf 100644 ---- a/kernel/umh.c -+++ b/kernel/umh.c -@@ -32,6 +32,10 @@ - #include +@@ -1375,9 +1528,25 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, + if (!new) + return -ENOMEM; + if (arg2 == PR_CAP_AMBIENT_RAISE) ++ #ifdef CONFIG_CREDP ++ { ++ kernel_cap_t tmp = new->cap_ambient; ++ cap_raise(tmp, arg3); ++ iee_set_cred_cap_ambient(new, tmp); ++ } ++ #else + cap_raise(new->cap_ambient, arg3); ++ #endif + else ++ #ifdef CONFIG_CREDP ++ { ++ kernel_cap_t tmp = new->cap_ambient; ++ cap_lower(tmp, arg3); ++ iee_set_cred_cap_ambient(new, tmp); ++ } ++ #else + cap_lower(new->cap_ambient, arg3); ++ #endif + return commit_creds(new); + } -+#ifdef CONFIG_CREDP -+#include -+#endif -+ - static kernel_cap_t usermodehelper_bset = CAP_FULL_SET; - static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET; - static DEFINE_SPINLOCK(umh_sysctl_lock); -@@ -91,9 +95,15 @@ static int call_usermodehelper_exec_async(void *data) - goto out; +diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c +index 720e5913832f..41ecdd75961a 100644 +--- a/security/integrity/evm/evm_crypto.c ++++ b/security/integrity/evm/evm_crypto.c +@@ -466,14 +466,26 @@ int evm_init_key(void) + if (IS_ERR(evm_key)) + return -ENOENT; - spin_lock(&umh_sysctl_lock); -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_bset(new,cap_intersect(usermodehelper_bset, new->cap_bset)); -+ iee_set_cred_cap_inheritable(new,cap_intersect(usermodehelper_inheritable, -+ new->cap_inheritable)); ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(evm_key)); + #else - new->cap_bset = cap_intersect(usermodehelper_bset, new->cap_bset); - new->cap_inheritable = cap_intersect(usermodehelper_inheritable, - new->cap_inheritable); + down_read(&evm_key->sem); ++ #endif ++ #ifdef CONFIG_KEYP ++ ekp = ((union key_payload *)(evm_key->name_link.next))->data[0]; ++ #else + ekp = evm_key->payload.data[0]; + #endif - spin_unlock(&umh_sysctl_lock); - - if (sub_info->init) { -diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c -index 1d8e47bed3f1..9f1921025539 100644 ---- a/kernel/user_namespace.c -+++ b/kernel/user_namespace.c -@@ -22,6 +22,10 @@ - #include - #include -+#ifdef CONFIG_CREDP -+#include -+#endif -+ - static struct kmem_cache *user_ns_cachep __read_mostly; - static DEFINE_MUTEX(userns_state_mutex); + rc = evm_set_key(ekp->decrypted_data, ekp->decrypted_datalen); -@@ -45,6 +49,19 @@ static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns) - /* Start with the same capabilities as init but useless for doing - * anything as the capabilities are bound to the new user namespace. - */ -+ #ifdef CONFIG_CREDP -+ iee_set_cred_securebits(cred,SECUREBITS_DEFAULT); -+ iee_set_cred_cap_inheritable(cred,CAP_EMPTY_SET); -+ iee_set_cred_cap_permitted(cred,CAP_FULL_SET); -+ iee_set_cred_cap_effective(cred,CAP_FULL_SET); -+ iee_set_cred_cap_ambient(cred,CAP_EMPTY_SET); -+ iee_set_cred_cap_bset(cred,CAP_FULL_SET); -+#ifdef CONFIG_KEYS -+ key_put(cred->request_key_auth); -+ iee_set_cred_request_key_auth(cred,NULL); -+#endif -+ iee_set_cred_user_ns(cred,user_ns); + /* burn the original key contents */ + memset(ekp->decrypted_data, 0, ekp->decrypted_datalen); ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(evm_key)); + #else - cred->securebits = SECUREBITS_DEFAULT; - cred->cap_inheritable = CAP_EMPTY_SET; - cred->cap_permitted = CAP_FULL_SET; -@@ -57,6 +74,7 @@ static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns) - #endif - /* tgcred will be cleared in our caller bc CLONE_THREAD won't be set */ - cred->user_ns = user_ns; + up_read(&evm_key->sem); + #endif + key_put(evm_key); + return rc; } +diff --git a/security/keys/big_key.c b/security/keys/big_key.c +index c3367622c683..bc6a097f2f87 100644 +--- a/security/keys/big_key.c ++++ b/security/keys/big_key.c +@@ -164,7 +164,11 @@ void big_key_free_preparse(struct key_preparsed_payload *prep) + */ + void big_key_revoke(struct key *key) + { ++ #ifdef CONFIG_KEYP ++ struct big_key_payload *payload = to_big_key_payload(*((union key_payload *)(key->name_link.next))); ++ #else + struct big_key_payload *payload = to_big_key_payload(key->payload); ++ #endif - static unsigned long enforced_nproc_rlimit(void) -diff --git a/mm/Kconfig b/mm/Kconfig -index 45d4139c959c..eb9d41768c15 100644 ---- a/mm/Kconfig -+++ b/mm/Kconfig -@@ -530,6 +530,18 @@ config NUMA_KEEP_MEMINFO - config MEMORY_ISOLATION - bool + /* clear the quota */ + key_payload_reserve(key, 0); +@@ -177,7 +181,11 @@ void big_key_revoke(struct key *key) + */ + void big_key_destroy(struct key *key) + { ++ #ifdef CONFIG_KEYP ++ struct big_key_payload *payload = to_big_key_payload(*((union key_payload *)(key->name_link.next))); ++ #else + struct big_key_payload *payload = to_big_key_payload(key->payload); ++ #endif -+# Config for kernel module isolation -+config KOI -+ depends on ARM64 -+ depends on ARM64_VA_BITS_48 -+ depends on ARM64_4K_PAGES -+ def_bool n -+ -+# Configs for pgtable isolation -+config PTP -+ depends on IEE -+ def_bool y -+ - # IORESOURCE_SYSTEM_RAM regions in the kernel resource tree that are marked - # IORESOURCE_EXCLUSIVE cannot be mapped to user space, for example, via - # /dev/mem. -diff --git a/mm/damon/ops-common.c b/mm/damon/ops-common.c -index d25d99cb5f2b..2ea51f559d4e 100644 ---- a/mm/damon/ops-common.c -+++ b/mm/damon/ops-common.c -@@ -44,6 +44,7 @@ void damon_ptep_mkold(pte_t *pte, struct vm_area_struct *vma, unsigned long addr - if (!folio) - return; + if (payload->length > BIG_KEY_FILE_THRESHOLD) { + path_put(&payload->path); +@@ -210,7 +218,11 @@ int big_key_update(struct key *key, struct key_preparsed_payload *prep) + */ + void big_key_describe(const struct key *key, struct seq_file *m) + { ++ #ifdef CONFIG_KEYP ++ struct big_key_payload *payload = to_big_key_payload(*((union key_payload *)(key->name_link.next))); ++ #else + struct big_key_payload *payload = to_big_key_payload(key->payload); ++ #endif -+ - if (ptep_clear_young_notify(vma, addr, pte)) - folio_set_young(folio); + seq_puts(m, key->description); -diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c -index 13f0d1192707..60dc95c5b286 100644 ---- a/mm/debug_vm_pgtable.c -+++ b/mm/debug_vm_pgtable.c -@@ -452,7 +452,11 @@ static void __init pmd_huge_tests(struct pgtable_debug_args *args) - * X86 defined pmd_set_huge() verifies that the given - * PMD is not a populated non-leaf entry. - */ -+ #ifdef CONFIG_PTP -+ set_pmd(args->pmdp, __pmd(0)); +@@ -226,7 +238,11 @@ void big_key_describe(const struct key *key, struct seq_file *m) + */ + long big_key_read(const struct key *key, char *buffer, size_t buflen) + { ++ #ifdef CONFIG_KEYP ++ struct big_key_payload *payload = to_big_key_payload(*((union key_payload *)(key->name_link.next))); + #else - WRITE_ONCE(*args->pmdp, __pmd(0)); + struct big_key_payload *payload = to_big_key_payload(key->payload); + #endif - WARN_ON(!pmd_set_huge(args->pmdp, __pfn_to_phys(args->fixed_pmd_pfn), args->page_prot)); - WARN_ON(!pmd_clear_huge(args->pmdp)); - pmd = READ_ONCE(*args->pmdp); -@@ -472,7 +476,11 @@ static void __init pud_huge_tests(struct pgtable_debug_args *args) - * X86 defined pud_set_huge() verifies that the given - * PUD is not a populated non-leaf entry. - */ -+ #ifdef CONFIG_PTP -+ set_pud(args->pudp, __pud(0)); + size_t datalen = payload->length; + long ret; + +diff --git a/security/keys/dh.c b/security/keys/dh.c +index da64c358474b..f00a3e0c2c87 100644 +--- a/security/keys/dh.c ++++ b/security/keys/dh.c +@@ -32,7 +32,11 @@ static ssize_t dh_data_from_key(key_serial_t keyid, const void **data) + + ret = -EOPNOTSUPP; + if (key->type == &key_type_user) { ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(key)); ++ #else + down_read(&key->sem); ++ #endif + status = key_validate(key); + if (status == 0) { + const struct user_key_payload *payload; +@@ -49,7 +53,11 @@ static ssize_t dh_data_from_key(key_serial_t keyid, const void **data) + ret = -ENOMEM; + } + } ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + } + + key_put(key); +diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c +index 1e313982af02..ef5e8f4f03f0 100644 +--- a/security/keys/encrypted-keys/encrypted.c ++++ b/security/keys/encrypted-keys/encrypted.c +@@ -314,11 +314,19 @@ static struct key *request_user_key(const char *master_desc, const u8 **master_k + if (IS_ERR(ukey)) + goto error; + ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(ukey)); + #else - WRITE_ONCE(*args->pudp, __pud(0)); + down_read(&ukey->sem); + #endif - WARN_ON(!pud_set_huge(args->pudp, __pfn_to_phys(args->fixed_pud_pfn), args->page_prot)); - WARN_ON(!pud_clear_huge(args->pudp)); - pud = READ_ONCE(*args->pudp); -@@ -511,7 +519,11 @@ static void __init pud_clear_tests(struct pgtable_debug_args *args) - - pr_debug("Validating PUD clear\n"); - pud = __pud(pud_val(pud) | RANDOM_ORVALUE); -+ #ifdef CONFIG_PTP -+ set_pud(args->pudp, pud); + upayload = user_key_payload_locked(ukey); + if (!upayload) { + /* key was revoked before we acquired its semaphore */ ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(ukey)); ++ #else + up_read(&ukey->sem); ++ #endif + key_put(ukey); + ukey = ERR_PTR(-EKEYREVOKED); + goto error; +@@ -729,7 +737,11 @@ static int encrypted_key_decrypt(struct encrypted_key_payload *epayload, + if (ret < 0) + pr_err("encrypted_key: failed to decrypt key (%d)\n", ret); + out: ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(mkey)); + #else - WRITE_ONCE(*args->pudp, pud); + up_read(&mkey->sem); + #endif - pud_clear(args->pudp); - pud = READ_ONCE(*args->pudp); - WARN_ON(!pud_none(pud)); -@@ -548,7 +560,11 @@ static void __init p4d_clear_tests(struct pgtable_debug_args *args) - - pr_debug("Validating P4D clear\n"); - p4d = __p4d(p4d_val(p4d) | RANDOM_ORVALUE); -+ #ifdef CONFIG_PTP -+ set_p4d(args->p4dp, p4d); + key_put(mkey); + memzero_explicit(derived_key, sizeof(derived_key)); + return ret; +@@ -874,7 +886,11 @@ static void encrypted_rcu_free(struct rcu_head *rcu) + */ + static int encrypted_update(struct key *key, struct key_preparsed_payload *prep) + { ++ #ifdef CONFIG_KEYP ++ struct encrypted_key_payload *epayload = ((union key_payload *)(key->name_link.next))->data[0]; + #else - WRITE_ONCE(*args->p4dp, p4d); + struct encrypted_key_payload *epayload = key->payload.data[0]; + #endif - p4d_clear(args->p4dp); - p4d = READ_ONCE(*args->p4dp); - WARN_ON(!p4d_none(p4d)); -@@ -582,7 +598,11 @@ static void __init pgd_clear_tests(struct pgtable_debug_args *args) + struct encrypted_key_payload *new_epayload; + char *buf; + char *new_master_desc = NULL; +@@ -974,7 +990,11 @@ static long encrypted_read(const struct key *key, char *buffer, + goto out; + } - pr_debug("Validating PGD clear\n"); - pgd = __pgd(pgd_val(pgd) | RANDOM_ORVALUE); -+ #ifdef CONFIG_PTP -+ set_pgd(args->pgdp, pgd); ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(mkey)); + #else - WRITE_ONCE(*args->pgdp, pgd); + up_read(&mkey->sem); + #endif - pgd_clear(args->pgdp); - pgd = READ_ONCE(*args->pgdp); - WARN_ON(!pgd_none(pgd)); -@@ -650,7 +670,11 @@ static void __init pmd_clear_tests(struct pgtable_debug_args *args) + key_put(mkey); + memzero_explicit(derived_key, sizeof(derived_key)); - pr_debug("Validating PMD clear\n"); - pmd = __pmd(pmd_val(pmd) | RANDOM_ORVALUE); -+ #ifdef CONFIG_PTP -+ set_pmd(args->pmdp, pmd); +@@ -983,7 +1003,11 @@ static long encrypted_read(const struct key *key, char *buffer, + + return asciiblob_len; + out: ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(mkey)); + #else - WRITE_ONCE(*args->pmdp, pmd); + up_read(&mkey->sem); ++ #endif + key_put(mkey); + memzero_explicit(derived_key, sizeof(derived_key)); + return ret; +@@ -994,7 +1018,11 @@ static long encrypted_read(const struct key *key, char *buffer, + */ + static void encrypted_destroy(struct key *key) + { ++ #ifdef CONFIG_KEYP ++ kfree_sensitive(((union key_payload *)(key->name_link.next))->data[0]); ++ #else + kfree_sensitive(key->payload.data[0]); + #endif - pmd_clear(args->pmdp); - pmd = READ_ONCE(*args->pmdp); - WARN_ON(!pmd_none(pmd)); -diff --git a/mm/early_ioremap.c b/mm/early_ioremap.c -index ce06b2884789..a039c7a50ec5 100644 ---- a/mm/early_ioremap.c -+++ b/mm/early_ioremap.c -@@ -147,7 +147,11 @@ __early_ioremap(resource_size_t phys_addr, unsigned long size, pgprot_t prot) - if (after_paging_init) - __late_set_fixmap(idx, phys_addr, prot); - else -+ #ifdef CONFIG_PTP -+ __iee_set_fixmap_pre_init(idx, phys_addr, prot); -+ #else - __early_set_fixmap(idx, phys_addr, prot); -+ #endif - phys_addr += PAGE_SIZE; - --idx; - --nrpages; -@@ -199,13 +203,66 @@ void __init early_iounmap(void __iomem *addr, unsigned long size) - if (after_paging_init) - __late_clear_fixmap(idx); - else -+ #ifdef CONFIG_PTP -+ __iee_set_fixmap_pre_init(idx, 0, FIXMAP_PAGE_CLEAR); -+ #else - __early_set_fixmap(idx, 0, FIXMAP_PAGE_CLEAR); -+ #endif - --idx; - --nrpages; - } - prev_map[slot] = NULL; } -+#ifdef CONFIG_PTP -+void __init early_iounmap_after_init(void __iomem *addr, unsigned long size) -+{ -+ unsigned long virt_addr; -+ unsigned long offset; -+ unsigned int nrpages; -+ enum fixed_addresses idx; -+ int i, slot; -+ -+ slot = -1; -+ for (i = 0; i < FIX_BTMAPS_SLOTS; i++) { -+ if (prev_map[i] == addr) { -+ slot = i; -+ break; -+ } -+ } -+ -+ if (WARN(slot < 0, "early_iounmap(%p, %08lx) not found slot\n", -+ addr, size)) -+ return; -+ -+ if (WARN(prev_size[slot] != size, -+ "early_iounmap(%p, %08lx) [%d] size not consistent %08lx\n", -+ addr, size, slot, prev_size[slot])) -+ return; -+ -+ WARN(early_ioremap_debug, "early_iounmap(%p, %08lx) [%d]\n", -+ addr, size, slot); -+ -+ virt_addr = (unsigned long)addr; -+ if (WARN_ON(virt_addr < fix_to_virt(FIX_BTMAP_BEGIN))) -+ return; -+ -+ offset = offset_in_page(virt_addr); -+ nrpages = PAGE_ALIGN(offset + size) >> PAGE_SHIFT; -+ -+ idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot; -+ while (nrpages > 0) { -+ if (after_paging_init) -+ __late_clear_fixmap(idx); -+ else -+ __early_set_fixmap(idx, 0, FIXMAP_PAGE_CLEAR); -+ --idx; -+ --nrpages; -+ } -+ prev_map[slot] = NULL; -+} -+#endif -+ - /* Remap an IO device */ - void __init __iomem * - early_ioremap(resource_size_t phys_addr, unsigned long size) -diff --git a/mm/huge_memory.c b/mm/huge_memory.c -index 763bb25e4f99..80bb2c0abeda 100644 ---- a/mm/huge_memory.c -+++ b/mm/huge_memory.c -@@ -39,6 +39,10 @@ - #include - #include + struct key_type key_type_encrypted = { +diff --git a/security/keys/encrypted-keys/masterkey_trusted.c b/security/keys/encrypted-keys/masterkey_trusted.c +index e6d22ce77e98..13803e0f1a8f 100644 +--- a/security/keys/encrypted-keys/masterkey_trusted.c ++++ b/security/keys/encrypted-keys/masterkey_trusted.c +@@ -34,8 +34,13 @@ struct key *request_trusted_key(const char *trusted_desc, + if (IS_ERR(tkey)) + goto error; -+#ifdef CONFIG_PTP -+#include ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(tkey)); ++ tpayload = ((union key_payload *)(tkey->name_link.next))->data[0]; ++ #else + down_read(&tkey->sem); + tpayload = tkey->payload.data[0]; ++ #endif + *master_key = tpayload->key; + *master_keylen = tpayload->key_len; + error: +diff --git a/security/keys/gc.c b/security/keys/gc.c +index eaddaceda14e..d1a8e1e6bf22 100644 +--- a/security/keys/gc.c ++++ b/security/keys/gc.c +@@ -10,6 +10,11 @@ + #include + #include "internal.h" + ++#ifdef CONFIG_KEYP ++#include ++extern void iee_memset(void *ptr, int data, size_t n); +#endif + - #include - #include - #include "internal.h" -@@ -2489,6 +2493,10 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma, - unsigned long addr; - pte_t *pte; - int i; -+ #ifdef CONFIG_PTP -+ pte_t *ptep; -+ unsigned long iee_addr; -+ #endif + /* + * Delay between key revocation/expiry in seconds + */ +@@ -135,18 +140,30 @@ void key_gc_keytype(struct key_type *ktype) + static noinline void key_gc_unused_keys(struct list_head *keys) + { + while (!list_empty(keys)) { ++ #ifdef CONFIG_KEYP ++ struct key *key = list_entry(keys->next, struct key_union, graveyard_link)->key; ++ #else + struct key *key = + list_entry(keys->next, struct key, graveyard_link); ++ #endif + short state = key->state; - /* - * Leave pmd empty until pte is filled note that it is fine to delay -@@ -2501,7 +2509,14 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma, - old_pmd = pmdp_huge_clear_flush(vma, haddr, pmd); ++ #ifdef CONFIG_KEYP ++ list_del(&(((struct key_union *)(key->graveyard_link.next))->graveyard_link)); ++ #else + list_del(&key->graveyard_link); ++ #endif - pgtable = pgtable_trans_huge_withdraw(mm, pmd); -- pmd_populate(mm, &_pmd, pgtable); -+ #ifdef CONFIG_PTP -+ ptep = (pte_t *)page_address(pgtable); -+ iee_addr = __phys_to_iee(__pa(ptep)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)ptep); -+ #endif -+ //pmd_populate(mm, &_pmd, pgtable); -+ _pmd = __pmd(__phys_to_pmd_val(page_to_phys(pgtable)) | PMD_TYPE_TABLE); + kdebug("- %u", key->serial); + key_check(key); - pte = pte_offset_map(&_pmd, haddr); - VM_BUG_ON(!pte); -@@ -2534,6 +2549,10 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, - unsigned long addr; - pte_t *pte; - int i; -+ #ifdef CONFIG_PTP -+ pte_t *ptep; -+ unsigned long iee_addr; -+ #endif + #ifdef CONFIG_KEY_NOTIFICATIONS + remove_watch_list(key->watchers, key->serial); ++ #ifdef CONFIG_KEYP ++ iee_set_key_watchers(key, NULL); ++ #else + key->watchers = NULL; ++ #endif + #endif - VM_BUG_ON(haddr & ~HPAGE_PMD_MASK); - VM_BUG_ON_VMA(vma->vm_start > haddr, vma); -@@ -2671,7 +2690,14 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, - * This's critical for some architectures (Power). + /* Throw away the key data if the key is instantiated */ +@@ -171,7 +188,15 @@ static noinline void key_gc_unused_keys(struct list_head *keys) + key_put_tag(key->domain_tag); + kfree(key->description); + ++ #ifdef CONFIG_KEYP ++ kmem_cache_free(key_union_jar,(struct key_union *)(key->graveyard_link.next)); ++ kmem_cache_free(key_struct_jar, (struct key_struct *)(key->name_link.prev)); ++ kmem_cache_free(key_payload_jar, (union key_payload *)(key->name_link.next)); ++ iee_memset(key, 0, sizeof(*key)); ++ barrier_data(key); ++ #else + memzero_explicit(key, sizeof(*key)); ++ #endif + kmem_cache_free(key_jar, key); + } + } +@@ -223,7 +248,11 @@ static void key_garbage_collector(struct work_struct *work) + + continue_scanning: + while (cursor) { ++ #ifdef CONFIG_KEYP ++ key = rb_entry(cursor, struct key_union, serial_node)->key; ++ #else + key = rb_entry(cursor, struct key, serial_node); ++ #endif + cursor = rb_next(cursor); + + if (refcount_read(&key->usage) == 0) +@@ -232,8 +261,13 @@ static void key_garbage_collector(struct work_struct *work) + if (unlikely(gc_state & KEY_GC_REAPING_DEAD_1)) { + if (key->type == key_gc_dead_keytype) { + gc_state |= KEY_GC_FOUND_DEAD_KEY; ++ #ifdef CONFIG_KEYP ++ iee_set_key_flag_bit(key, KEY_FLAG_DEAD, SET_BIT_OP); ++ iee_set_key_perm(key, 0); ++ #else + set_bit(KEY_FLAG_DEAD, &key->flags); + key->perm = 0; ++ #endif + goto skip_dead_key; + } else if (key->type == &key_type_keyring && + key->restrict_link) { +@@ -339,10 +373,18 @@ static void key_garbage_collector(struct work_struct *work) */ - pgtable = pgtable_trans_huge_withdraw(mm, pmd); -- pmd_populate(mm, &_pmd, pgtable); -+ #ifdef CONFIG_PTP -+ ptep = (pte_t *)page_to_virt(pgtable); -+ iee_addr = __phys_to_iee(__pa(ptep)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)ptep); + found_unreferenced_key: + kdebug("unrefd key %d", key->serial); ++ #ifdef CONFIG_KEYP ++ rb_erase(&(((struct key_union *)(key->graveyard_link.next))->serial_node), &key_serial_tree); ++ #else + rb_erase(&key->serial_node, &key_serial_tree); + #endif -+ //pmd_populate(mm, &_pmd, pgtable); -+ _pmd = __pmd(__phys_to_pmd_val(page_to_phys(pgtable)) | PMD_TYPE_TABLE); + spin_unlock(&key_serial_lock); - pte = pte_offset_map(&_pmd, haddr); - VM_BUG_ON(!pte); -diff --git a/mm/init-mm.c b/mm/init-mm.c -index 24c809379274..07d060fca6f0 100644 ---- a/mm/init-mm.c -+++ b/mm/init-mm.c -@@ -55,3 +55,20 @@ void setup_initial_init_mm(void *start_code, void *end_code, - init_mm.end_data = (unsigned long)end_data; - init_mm.brk = (unsigned long)brk; ++ #ifdef CONFIG_KEYP ++ list_add_tail(&(((struct key_union *)(key->graveyard_link.next))->graveyard_link), &graveyard); ++ #else + list_add_tail(&key->graveyard_link, &graveyard); ++ #endif + gc_state |= KEY_GC_REAP_AGAIN; + goto maybe_resched; + +@@ -370,11 +412,21 @@ static void key_garbage_collector(struct work_struct *work) + destroy_dead_key: + spin_unlock(&key_serial_lock); + kdebug("destroy key %d", key->serial); ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(key)); ++ iee_set_key_type(key, &key_type_dead); ++ #else + down_write(&key->sem); + key->type = &key_type_dead; ++ #endif + if (key_gc_dead_keytype->destroy) + key_gc_dead_keytype->destroy(key); ++ #ifdef CONFIG_KEYP ++ iee_memset((key->name_link.next), KEY_DESTROY, sizeof(key->payload)); ++ up_write(&KEY_SEM(key)); ++ #else + memset(&key->payload, KEY_DESTROY, sizeof(key->payload)); + up_write(&key->sem); ++ #endif + goto maybe_resched; } -+ -+#ifdef CONFIG_KOI -+/* -+ * This is used to init ko_mm when creating pgtable for a ko to be isolated -+ * the ko_mm belongs to a specific ko, pgdp is allocated by koi_pgd_alloc -+ */ -+void init_ko_mm(struct mm_struct *ko_mm, pgd_t *pgdp) { -+ ko_mm->mm_rb = RB_ROOT; -+ ko_mm->pgd = pgdp; -+ ko_mm->mm_users = (atomic_t)ATOMIC_INIT(2); -+ ko_mm->mm_count = (atomic_t)ATOMIC_INIT(1); -+ ko_mm->mmap_lock = (struct rw_semaphore)__RWSEM_INITIALIZER(ko_mm->mmap_lock); -+ ko_mm->page_table_lock = __SPIN_LOCK_UNLOCKED(ko_mm.page_table_lock); -+ ko_mm->arg_lock = __SPIN_LOCK_UNLOCKED(ko_mm->arg_lock); -+ ko_mm->mmlist = (struct list_head)LIST_HEAD_INIT(ko_mm->mmlist); -+} +diff --git a/security/keys/internal.h b/security/keys/internal.h +index ec2ec335b613..00d76f89179c 100644 +--- a/security/keys/internal.h ++++ b/security/keys/internal.h +@@ -83,12 +83,20 @@ extern unsigned key_quota_maxbytes; + + + extern struct kmem_cache *key_jar; ++#ifdef CONFIG_KEYP ++extern struct kmem_cache *key_union_jar; ++extern struct kmem_cache *key_struct_jar; ++extern struct kmem_cache *key_payload_jar; +#endif -diff --git a/mm/memory.c b/mm/memory.c -index 4ef917a182f9..28da89a19e30 100644 ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -80,6 +80,10 @@ - #include - #include + extern struct rb_root key_serial_tree; + extern spinlock_t key_serial_lock; + extern struct mutex key_construction_mutex; + extern wait_queue_head_t request_key_conswq; + + extern void key_set_index_key(struct keyring_index_key *index_key); ++#ifdef CONFIG_KEYP ++extern void iee_key_set_index_key(struct keyring_index_key *index_key); ++#endif + extern struct key_type *key_type_lookup(const char *type); + extern void key_type_put(struct key_type *ktype); + +diff --git a/security/keys/key.c b/security/keys/key.c +index 35db23d05302..831c21329488 100644 +--- a/security/keys/key.c ++++ b/security/keys/key.c +@@ -17,7 +17,18 @@ + #include + #include "internal.h" -+#ifdef CONFIG_PTP -+#include ++#ifdef CONFIG_KEYP ++#include ++#include ++extern void iee_memset(void *ptr, int data, size_t n); +#endif + - #include + struct kmem_cache *key_jar; ++#ifdef CONFIG_KEYP ++struct kmem_cache *key_union_jar; ++struct kmem_cache *key_struct_jar; ++struct kmem_cache *key_payload_jar; ++#endif + struct rb_root key_serial_tree; /* tree of keys indexed by serial */ + DEFINE_SPINLOCK(key_serial_lock); - #include -@@ -5872,6 +5876,11 @@ int __pud_alloc(struct mm_struct *mm, p4d_t *p4d, unsigned long address) +@@ -139,9 +150,16 @@ static inline void key_alloc_serial(struct key *key) + /* propose a random serial number and look for a hole for it in the + * serial number tree */ + do { ++ #ifdef CONFIG_KEYP ++ key_serial_t tmp; ++ get_random_bytes(&tmp, sizeof(key->serial)); ++ ++ iee_set_key_serial(key, tmp >> 1); ++ #else + get_random_bytes(&key->serial, sizeof(key->serial)); - spin_lock(&mm->page_table_lock); - if (!p4d_present(*p4d)) { -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr = __phys_to_iee(__pa(new)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)new); + key->serial >>= 1; /* negative numbers are not permitted */ + #endif - mm_inc_nr_puds(mm); - smp_wmb(); /* See comment in pmd_install() */ - p4d_populate(mm, p4d, new); -@@ -5896,6 +5905,11 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) + } while (key->serial < 3); - ptl = pud_lock(mm, pud); - if (!pud_present(*pud)) { -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr = __phys_to_iee(__pa(new)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)new); + spin_lock(&key_serial_lock); +@@ -152,7 +170,11 @@ static inline void key_alloc_serial(struct key *key) + + while (*p) { + parent = *p; ++ #ifdef CONFIG_KEYP ++ xkey = rb_entry(parent, struct key_union, serial_node)->key; ++ #else + xkey = rb_entry(parent, struct key, serial_node); + #endif - mm_inc_nr_pmds(mm); - smp_wmb(); /* See comment in pmd_install() */ - pud_populate(mm, pud, new); -diff --git a/mm/slub.c b/mm/slub.c -index ee3e32cdb7fd..20a45a7feed5 100644 ---- a/mm/slub.c -+++ b/mm/slub.c -@@ -42,6 +42,11 @@ - #include - #include -+#ifdef CONFIG_IEE -+#include -+#include -+#endif -+ - #include - #include + if (key->serial < xkey->serial) + p = &(*p)->rb_left; +@@ -163,8 +185,13 @@ static inline void key_alloc_serial(struct key *key) + } -@@ -317,6 +322,7 @@ static inline bool kmem_cache_has_cpu_partial(struct kmem_cache *s) - /* - * Tracking user of a slab. - */ -+#ifndef CONFIG_IEE - #define TRACK_ADDRS_COUNT 16 - struct track { - unsigned long addr; /* Called from address */ -@@ -329,6 +335,7 @@ struct track { - }; + /* we've found a suitable hole - arrange for this key to occupy it */ ++ #ifdef CONFIG_KEYP ++ rb_link_node(&(((struct key_union *)(key->graveyard_link.next))->serial_node), parent, p); ++ rb_insert_color(&(((struct key_union *)(key->graveyard_link.next))->serial_node), &key_serial_tree); ++ #else + rb_link_node(&key->serial_node, parent, p); + rb_insert_color(&key->serial_node, &key_serial_tree); ++ #endif - enum track_item { TRACK_ALLOC, TRACK_FREE }; -+#endif + spin_unlock(&key_serial_lock); + return; +@@ -175,7 +202,11 @@ static inline void key_alloc_serial(struct key *key) + for (;;) { + key->serial++; + if (key->serial < 3) { ++ #ifdef CONFIG_KEYP ++ iee_set_key_serial(key, 3); ++ #else + key->serial = 3; ++ #endif + goto attempt_insertion; + } - #ifdef SLAB_SUPPORTS_SYSFS - static int sysfs_slab_add(struct kmem_cache *); -@@ -379,7 +386,9 @@ static struct workqueue_struct *flushwq; - * freeptr_t represents a SLUB freelist pointer, which might be encoded - * and not dereferenceable if CONFIG_SLAB_FREELIST_HARDENED is enabled. - */ -+#ifndef CONFIG_IEE - typedef struct { unsigned long v; } freeptr_t; -+#endif +@@ -183,7 +214,11 @@ static inline void key_alloc_serial(struct key *key) + if (!parent) + goto attempt_insertion; - /* - * Returns freelist pointer (ptr). With hardening, this is obfuscated -@@ -464,7 +473,14 @@ static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp) - #endif ++ #ifdef CONFIG_KEYP ++ xkey = rb_entry(parent, struct key_union, serial_node)->key; ++ #else + xkey = rb_entry(parent, struct key, serial_node); ++ #endif + if (key->serial < xkey->serial) + goto attempt_insertion; + } +@@ -231,6 +266,9 @@ struct key *key_alloc(struct key_type *type, const char *desc, + struct key *key; + size_t desclen, quotalen; + int ret; ++ #ifdef CONFIG_KEYP ++ unsigned long kflags; ++ #endif + + key = ERR_PTR(-EINVAL); + if (!desc || !*desc) +@@ -274,17 +312,72 @@ struct key *key_alloc(struct key_type *type, const char *desc, + } - freeptr_addr = (unsigned long)kasan_reset_tag((void *)freeptr_addr); -+ #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_CREDP) && strcmp(s->name, "cred_jar") == 0) -+ iee_set_freeptr((freeptr_t *)freeptr_addr, freelist_ptr_encode(s, fp, freeptr_addr)); -+ else -+ *(freeptr_t *)freeptr_addr = freelist_ptr_encode(s, fp, freeptr_addr); + /* allocate and initialise the key and its description */ ++ #ifdef CONFIG_KEYP ++ key = kmem_cache_alloc(key_jar, GFP_KERNEL); + #else - *(freeptr_t *)freeptr_addr = freelist_ptr_encode(s, fp, freeptr_addr); + key = kmem_cache_zalloc(key_jar, GFP_KERNEL); + #endif - } - - /* Loop over all objects in a slab */ -@@ -809,7 +825,34 @@ static void set_track_update(struct kmem_cache *s, void *object, - depot_stack_handle_t handle) - { - struct track *p = get_track(s, object, alloc); -+#ifdef CONFIG_IEE -+ struct track tmp; + if (!key) + goto no_memory_2; +- ++ #ifdef CONFIG_KEYP ++ struct key_union *key_union = kmem_cache_zalloc(key_union_jar, GFP_KERNEL); ++ key_union->key = key; ++ struct key_struct *key_struct = kmem_cache_zalloc(key_struct_jar, GFP_KERNEL); ++ key_struct->key = key; ++ iee_set_key_union(key, key_union); ++ iee_set_key_struct(key, key_struct); ++ iee_set_key_payload(key, kmem_cache_alloc(key_payload_jar, GFP_KERNEL)); ++ #endif ++ ++ #ifdef CONFIG_KEYP ++ struct keyring_index_key tmp = key->index_key; ++ tmp.desc_len = desclen; ++ tmp.description = kmemdup(desc, desclen + 1, GFP_KERNEL); ++ iee_set_key_index_key(key, tmp); ++ #else + key->index_key.desc_len = desclen; + key->index_key.description = kmemdup(desc, desclen + 1, GFP_KERNEL); ++ #endif + if (!key->index_key.description) + goto no_memory_3; ++ #ifdef CONFIG_KEYP ++ tmp = key->index_key; ++ tmp.type = type; ++ iee_set_key_index_key(key, tmp); ++ iee_key_set_index_key(&key->index_key); ++ #else + key->index_key.type = type; + key_set_index_key(&key->index_key); ++ #endif ++ ++ #ifdef CONFIG_KEYP ++ iee_set_key_usage(key, 1, REFCOUNT_SET); ++ init_rwsem(&KEY_SEM(key)); ++ lockdep_set_class(&KEY_SEM(key), &type->lock_class); ++ iee_set_key_user(key, user); ++ iee_set_key_quotalen(key, quotalen); ++ iee_set_key_datalen(key, type->def_datalen); ++ iee_set_key_uid(key, uid); ++ iee_set_key_gid(key, gid); ++ iee_set_key_perm(key, perm); ++ iee_set_key_restrict_link(key, restrict_link); ++ iee_set_key_last_used_at(key, ktime_get_real_seconds()); ++ ++ kflags = key->flags; ++ if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) ++ kflags |= 1 << KEY_FLAG_IN_QUOTA; ++ if (flags & KEY_ALLOC_BUILT_IN) ++ kflags |= 1 << KEY_FLAG_BUILTIN; ++ if (flags & KEY_ALLOC_UID_KEYRING) ++ kflags |= 1 << KEY_FLAG_UID_KEYRING; ++ if (flags & KEY_ALLOC_SET_KEEP) ++ kflags |= 1 << KEY_FLAG_KEEP; ++ iee_set_key_flags(key, kflags); + ++#ifdef KEY_DEBUGGING ++ iee_set_key_magic(key, KEY_DEBUG_MAGIC); +#endif - -+#ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_CREDP) && strcmp(s->name, "cred_jar") == 0) -+ { -+ tmp = *p; -+ #ifdef CONFIG_STACKDEPOT -+ tmp.handle = handle; -+ #endif -+ tmp.addr = addr; -+ tmp.cpu = smp_processor_id(); -+ tmp.pid = current->pid; -+ tmp.when = jiffies; -+ iee_set_track(p,&tmp); -+ } -+ else -+ { -+ #ifdef CONFIG_STACKDEPOT -+ p->handle = handle; -+ #endif -+ p->addr = addr; -+ p->cpu = smp_processor_id(); -+ p->pid = current->pid; -+ p->when = jiffies; -+ } -+#else - #ifdef CONFIG_STACKDEPOT - p->handle = handle; ++ #else + refcount_set(&key->usage, 1); + init_rwsem(&key->sem); + lockdep_set_class(&key->sem, &type->lock_class); +@@ -310,6 +403,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, + #ifdef KEY_DEBUGGING + key->magic = KEY_DEBUG_MAGIC; #endif -@@ -817,6 +860,7 @@ static void set_track_update(struct kmem_cache *s, void *object, - p->cpu = smp_processor_id(); - p->pid = current->pid; - p->when = jiffies; -+#endif - } ++ #endif - static __always_inline void set_track(struct kmem_cache *s, void *object, -@@ -835,7 +879,14 @@ static void init_tracking(struct kmem_cache *s, void *object) - return; + /* let the security module know about the key */ + ret = security_key_alloc(key, cred, flags); +@@ -326,6 +420,12 @@ struct key *key_alloc(struct key_type *type, const char *desc, + + security_error: + kfree(key->description); ++ #ifdef CONFIG_KEYP ++ kmem_cache_free(key_union_jar,(struct key_union *)(key->graveyard_link.next)); ++ kmem_cache_free(key_struct_jar, (struct key_struct *)(key->name_link.prev)); ++ kmem_cache_free(key_payload_jar, (union key_payload *)(key->name_link.next)); ++ iee_memset(key, 0, sizeof(struct key)); ++ #endif + kmem_cache_free(key_jar, key); + if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) { + spin_lock(&user->lock); +@@ -338,6 +438,12 @@ struct key *key_alloc(struct key_type *type, const char *desc, + goto error; + + no_memory_3: ++ #ifdef CONFIG_KEYP ++ kmem_cache_free(key_union_jar,(struct key_union *)(key->graveyard_link.next)); ++ kmem_cache_free(key_struct_jar, (struct key_struct *)(key->name_link.prev)); ++ kmem_cache_free(key_payload_jar, (union key_payload *)(key->name_link.next)); ++ iee_memset(key, 0, sizeof(struct key)); ++ #endif + kmem_cache_free(key_jar, key); + no_memory_2: + if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) { +@@ -391,14 +497,22 @@ int key_payload_reserve(struct key *key, size_t datalen) + } + else { + key->user->qnbytes += delta; ++ #ifdef CONFIG_KEYP ++ iee_set_key_quotalen(key, key->quotalen + delta); ++ #else + key->quotalen += delta; ++ #endif + } + spin_unlock(&key->user->lock); + } - p = get_track(s, object, TRACK_ALLOC); -+ #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_CREDP) && strcmp(s->name, "cred_jar") == 0) -+ iee_memset(p, 0, 2*sizeof(struct track)); -+ else -+ memset(p, 0, 2*sizeof(struct track)); + /* change the recorded data length if that didn't generate an error */ + if (ret == 0) ++ #ifdef CONFIG_KEYP ++ iee_set_key_datalen(key, datalen); ++ #else + key->datalen = datalen; ++ #endif + + return ret; + } +@@ -412,8 +526,14 @@ static void mark_key_instantiated(struct key *key, int reject_error) + /* Commit the payload before setting the state; barrier versus + * key_read_state(). + */ ++ #ifdef CONFIG_KEYP ++ compiletime_assert_atomic_type(key->state); ++ barrier(); ++ iee_set_key_state(key, (reject_error < 0) ? reject_error : KEY_IS_POSITIVE); + #else - memset(p, 0, 2*sizeof(struct track)); + smp_store_release(&key->state, + (reject_error < 0) ? reject_error : KEY_IS_POSITIVE); + #endif } - static void print_track(const char *s, struct track *t, unsigned long pr_time) -@@ -1045,7 +1096,14 @@ static void init_object(struct kmem_cache *s, void *object, u8 val) - unsigned int poison_size = s->object_size; + /* +@@ -449,13 +569,22 @@ static int __key_instantiate_and_link(struct key *key, + mark_key_instantiated(key, 0); + notify_key(key, NOTIFY_KEY_INSTANTIATED, 0); - if (s->flags & SLAB_RED_ZONE) { -+ #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_CREDP) && strcmp(s->name, "cred_jar") == 0) -+ iee_memset(p - s->red_left_pad, val, s->red_left_pad); -+ else -+ memset(p - s->red_left_pad, val, s->red_left_pad); -+ #else - memset(p - s->red_left_pad, val, s->red_left_pad); -+ #endif ++ #ifdef CONFIG_KEYP ++ if (iee_set_key_flag_bit(key, KEY_FLAG_USER_CONSTRUCT, TEST_AND_CLEAR_BIT)) ++ awaken = 1; ++ #else + if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) + awaken = 1; ++ #endif - if (slub_debug_orig_size(s) && val == SLUB_RED_ACTIVE) { - /* -@@ -1058,12 +1116,34 @@ static void init_object(struct kmem_cache *s, void *object, u8 val) + /* and link it into the destination keyring */ + if (keyring) { + if (test_bit(KEY_FLAG_KEEP, &keyring->flags)) ++ #ifdef CONFIG_KEYP ++ iee_set_key_flag_bit(key, KEY_FLAG_KEEP, SET_BIT_OP); ++ #else + set_bit(KEY_FLAG_KEEP, &key->flags); ++ #endif + + __key_link(keyring, key, _edit); + } +@@ -464,8 +593,14 @@ static int __key_instantiate_and_link(struct key *key, + if (authkey) + key_invalidate(authkey); + +- if (prep->expiry != TIME64_MAX) ++ if (prep->expiry != TIME64_MAX) { ++ #ifdef CONFIG_KEYP ++ iee_set_key_expiry(key, prep->expiry); ++ #else + key_set_expiry(key, prep->expiry); ++ #endif ++ key_schedule_gc(prep->expiry + key_gc_delay); ++ } + } } - if (s->flags & __OBJECT_POISON) { -+ #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_CREDP) && strcmp(s->name, "cred_jar") == 0) -+ { -+ iee_memset(p, POISON_FREE, poison_size - 1); -+ iee_memset(&p[poison_size - 1], POISON_END, 1); -+ } -+ else -+ { -+ memset(p, POISON_FREE, poison_size - 1); -+ p[poison_size - 1] = POISON_END; -+ } +@@ -605,10 +740,20 @@ int key_reject_and_link(struct key *key, + atomic_inc(&key->user->nikeys); + mark_key_instantiated(key, -error); + notify_key(key, NOTIFY_KEY_INSTANTIATED, -error); ++ #ifdef CONFIG_KEYP ++ iee_set_key_expiry(key, ktime_get_real_seconds() + timeout); + #else - memset(p, POISON_FREE, poison_size - 1); - p[poison_size - 1] = POISON_END; + key_set_expiry(key, ktime_get_real_seconds() + timeout); + #endif - } ++ key_schedule_gc(key->expiry + key_gc_delay); -- if (s->flags & SLAB_RED_ZONE) -+ if (s->flags & SLAB_RED_ZONE) { -+ #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_CREDP) && strcmp(s->name, "cred_jar") == 0) -+ iee_memset(p + poison_size, val, s->inuse - poison_size); -+ else -+ memset(p + poison_size, val, s->inuse - poison_size); ++ #ifdef CONFIG_KEYP ++ if (iee_set_key_flag_bit(key, KEY_FLAG_USER_CONSTRUCT, TEST_AND_CLEAR_BIT)) ++ awaken = 1; + #else - memset(p + poison_size, val, s->inuse - poison_size); + if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) + awaken = 1; + #endif -+ -+ } + + ret = 0; + +@@ -647,8 +792,13 @@ void key_put(struct key *key) + if (key) { + key_check(key); + ++ #ifdef CONFIG_KEYP ++ if (iee_set_key_usage(key, 0, REFCOUNT_DEC_AND_TEST)) ++ schedule_work(&key_gc_work); ++ #else + if (refcount_dec_and_test(&key->usage)) + schedule_work(&key_gc_work); ++ #endif + } } + EXPORT_SYMBOL(key_put); +@@ -666,7 +816,11 @@ struct key *key_lookup(key_serial_t id) + /* search the tree for the specified key */ + n = key_serial_tree.rb_node; + while (n) { ++ #ifdef CONFIG_KEYP ++ key = rb_entry(n, struct key_union, serial_node)->key; ++ #else + key = rb_entry(n, struct key, serial_node); ++ #endif - static void restore_bytes(struct kmem_cache *s, char *message, u8 data, -@@ -1433,7 +1513,14 @@ void setup_slab_debug(struct kmem_cache *s, struct slab *slab, void *addr) - return; + if (id < key->serial) + n = n->rb_left; +@@ -684,8 +838,13 @@ struct key *key_lookup(key_serial_t id) + /* A key is allowed to be looked up only if someone still owns a + * reference to it - otherwise it's awaiting the gc. + */ ++ #ifdef CONFIG_KEYP ++ if (!iee_set_key_usage(key, 0, REFCOUNT_INC_NOT_ZERO)) ++ goto not_found; ++ #else + if (!refcount_inc_not_zero(&key->usage)) + goto not_found; ++ #endif - metadata_access_enable(); -+ #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_CREDP) && strcmp(s->name, "cred_jar") == 0) -+ iee_memset(kasan_reset_tag(addr), POISON_INUSE, slab_size(slab)); -+ else -+ memset(kasan_reset_tag(addr), POISON_INUSE, slab_size(slab)); + error: + spin_unlock(&key_serial_lock); +@@ -723,13 +882,27 @@ void key_set_timeout(struct key *key, unsigned timeout) + time64_t expiry = TIME64_MAX; + + /* make the changes with the locks held to prevent races */ ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(key)); + #else - memset(kasan_reset_tag(addr), POISON_INUSE, slab_size(slab)); + down_write(&key->sem); + #endif - metadata_access_disable(); - } -@@ -2015,6 +2102,9 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) - void *start, *p, *next; - int idx; - bool shuffle; -+ #ifdef CONFIG_IEE -+ unsigned int order; + if (timeout > 0) + expiry = ktime_get_real_seconds() + timeout; ++ ++ #ifdef CONFIG_KEYP ++ iee_set_key_expiry(key, expiry); ++ #else + key_set_expiry(key, expiry); + #endif ++ key_schedule_gc(key->expiry + key_gc_delay); - flags &= gfp_allowed_mask; ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(key)); ++ #else + up_write(&key->sem); ++ #endif + } + EXPORT_SYMBOL_GPL(key_set_timeout); -@@ -2029,6 +2119,9 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) - alloc_gfp = (alloc_gfp | __GFP_NOMEMALLOC) & ~__GFP_RECLAIM; +@@ -762,7 +935,11 @@ static inline key_ref_t __key_update(key_ref_t key_ref, + if (!key->type->update) + goto error; - slab = alloc_slab_page(alloc_gfp, node, oo); -+ #ifdef CONFIG_IEE -+ order = oo_order(oo); ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(key)); ++ #else + down_write(&key->sem); + #endif - if (unlikely(!slab)) { - oo = s->min; - alloc_gfp = flags; -@@ -2037,6 +2130,9 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) - * Try a lower order alloc if possible - */ - slab = alloc_slab_page(alloc_gfp, node, oo); -+ #ifdef CONFIG_IEE -+ order = oo_order(oo); -+ #endif - if (unlikely(!slab)) - return NULL; - stat(s, ORDER_FALLBACK); -@@ -2046,6 +2142,45 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) - slab->inuse = 0; - slab->frozen = 0; -+ #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_CREDP) && strcmp(s->name, "cred_jar") == 0) -+ { -+ int i; -+ for(i = 0; i < (0x1 << order); i++) -+ { -+ unsigned long iee_addr = __phys_to_iee(page_to_phys(folio_page(slab_folio(slab), i))); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)page_address(folio_page(slab_folio(slab), i))); -+ } -+ } -+ -+ // If the page belongs to a task_struct, alloc token for it and set iee&lm va. -+ if(strcmp(s->name, "task_struct") == 0) -+ { -+ int i; -+ for(i = 0; i < (0x1 << order); i++) -+ { -+ void *token_addr = (void *)__phys_to_iee(page_to_phys(folio_page(slab_folio(slab), i))); -+ // Get lm va of the page. -+ void *alloc_token = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); -+ iee_set_token_page_valid(token_addr, alloc_token); -+ set_iee_page_valid(__phys_to_iee(__pa(alloc_token))); -+ iee_set_logical_mem_ro((unsigned long)alloc_token); -+ } -+ } -+ #else -+ #ifdef CONFIG_KOI -+ if (strcmp(s->name, "task_struct") == 0) { -+ int i; -+ for (i = 0; i < (0x1 << order); i++) { -+ void *token_addr = __phys_to_virt(page_to_phys(page + i)) + koi_offset; -+ void *alloc_token = __get_free_page(GFP_KERNEL | __GFP_ZERO); -+ koi_add_page_mapping(token_addr, alloc_token); -+ } -+ } -+ #endif + ret = key->type->update(key, prep); + if (ret == 0) { +@@ -771,7 +948,11 @@ static inline key_ref_t __key_update(key_ref_t key_ref, + notify_key(key, NOTIFY_KEY_UPDATED, 0); + } + ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(key)); ++ #else + up_write(&key->sem); + #endif -+ - account_slab(slab, oo_order(oo), s, flags); - slab->slab_cache = s; -@@ -2098,6 +2233,67 @@ static void __free_slab(struct kmem_cache *s, struct slab *slab) - __folio_clear_slab(folio); - mm_account_reclaimed_pages(pages); - unaccount_slab(slab, order, s); -+ -+ #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_CREDP) && strcmp(s->name, "cred_jar") == 0) -+ { -+ int i; -+ for(i = 0; i < (0x1 << order); i++) -+ { -+ unsigned long iee_addr = __phys_to_iee(page_to_phys(folio_page(folio, i))); -+ set_iee_page_invalid(iee_addr); -+ iee_set_logical_mem_rw((unsigned long)page_address(folio_page(folio, i))); -+ } -+ } -+ // If the page containing this token is empty, free it and restore iee&lm va. -+ if(strcmp(s->name, "task_struct") == 0) -+ { -+ int i; -+ for(i = 0; i < (0x1 << order); i++) -+ { -+ void *token_addr = (void *)__phys_to_iee(page_to_phys(folio_page(folio, i))); -+ unsigned long flags; -+ unsigned long res; -+ local_irq_save(flags); -+ asm volatile("at s1e1r, %0"::"r"(token_addr)); -+ isb(); -+ res = read_sysreg(par_el1); -+ local_irq_restore(flags); -+ if(!(res & 0x1)) -+ { -+ // Get lm va of the page. -+ void *token_page = __va(res & PTE_ADDR_MASK); -+ iee_set_token_page_invalid(token_addr); -+ set_iee_page_invalid(__phys_to_iee(__pa(token_page))); -+ iee_set_logical_mem_rw((unsigned long)token_page); -+ free_page((unsigned long)token_page); -+ } -+ } -+ } -+ #else -+ #ifdef CONFIG_KOI -+ if(strcmp(s->name, "task_struct") == 0) -+ { -+ int i; -+ for(i = 0; i < (0x1 << order); i++) -+ { -+ void *token_addr = __phys_to_virt(page_to_phys(page + i)) + koi_offset; -+ unsigned long flags; -+ local_irq_save(flags); -+ asm volatile("at s1e1r, %0"::"r"(token_addr)); -+ isb(); -+ unsigned long res = read_sysreg(par_el1); -+ local_irq_restore(flags); -+ if(!(res & 0x1)) -+ { -+ koi_remove_page_mapping(token_addr); -+ free_page(__va(res & PTE_ADDR_MASK)); -+ } + if (ret < 0) + goto error; +@@ -1087,7 +1268,11 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) + goto error; + } + ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(key)); ++ #else + down_write(&key->sem); ++ #endif + + ret = key->type->update(key, &prep); + if (ret == 0) { +@@ -1096,7 +1281,11 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) + notify_key(key, NOTIFY_KEY_UPDATED, 0); + } + ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(key)); ++ #else + up_write(&key->sem); ++ #endif + + error: + if (key->type->preparse) +@@ -1125,6 +1314,23 @@ void key_revoke(struct key *key) + * authorisation key whilst holding the sem on a key we've just + * instantiated + */ ++ #ifdef CONFIG_KEYP ++ down_write_nested(&KEY_SEM(key), 1); ++ if (!iee_set_key_flag_bit(key, KEY_FLAG_REVOKED, TEST_AND_SET_BIT)) { ++ notify_key(key, NOTIFY_KEY_REVOKED, 0); ++ if (key->type->revoke) ++ key->type->revoke(key); ++ ++ /* set the death time to no more than the expiry time */ ++ time = ktime_get_real_seconds(); ++ if (key->revoked_at == 0 || key->revoked_at > time) { ++ iee_set_key_revoked_at(key, time); ++ key_schedule_gc(key->revoked_at + key_gc_delay); + } + } -+ #endif -+ #endif + - __free_pages(&folio->page, order); ++ up_write(&KEY_SEM(key)); ++ #else + down_write_nested(&key->sem, 1); + if (!test_and_set_bit(KEY_FLAG_REVOKED, &key->flags)) { + notify_key(key, NOTIFY_KEY_REVOKED, 0); +@@ -1140,6 +1346,7 @@ void key_revoke(struct key *key) + } + + up_write(&key->sem); ++ #endif } + EXPORT_SYMBOL(key_revoke); -diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c -index a2cbe44c48e1..7cf05d293312 100644 ---- a/mm/sparse-vmemmap.c -+++ b/mm/sparse-vmemmap.c -@@ -28,6 +28,10 @@ - #include - #include +@@ -1157,12 +1364,21 @@ void key_invalidate(struct key *key) + key_check(key); -+#ifdef CONFIG_PTP -+#include + if (!test_bit(KEY_FLAG_INVALIDATED, &key->flags)) { ++ #ifdef CONFIG_KEYP ++ down_write_nested(&KEY_SEM(key), 1); ++ if (!iee_set_key_flag_bit(key, KEY_FLAG_INVALIDATED, TEST_AND_SET_BIT)) { ++ notify_key(key, NOTIFY_KEY_INVALIDATED, 0); ++ key_schedule_gc_links(); ++ } ++ up_write(&KEY_SEM(key)); ++ #else + down_write_nested(&key->sem, 1); + if (!test_and_set_bit(KEY_FLAG_INVALIDATED, &key->flags)) { + notify_key(key, NOTIFY_KEY_INVALIDATED, 0); + key_schedule_gc_links(); + } + up_write(&key->sem); ++ #endif + } + } + EXPORT_SYMBOL(key_invalidate); +@@ -1186,9 +1402,17 @@ int generic_key_instantiate(struct key *key, struct key_preparsed_payload *prep) + ret = key_payload_reserve(key, prep->quotalen); + if (ret == 0) { + rcu_assign_keypointer(key, prep->payload.data[0]); ++ #ifdef CONFIG_KEYP ++ union key_payload key_payload = *((union key_payload *)(key->name_link.next)); ++ key_payload.data[1] = prep->payload.data[1]; ++ key_payload.data[2] = prep->payload.data[2]; ++ key_payload.data[3] = prep->payload.data[3]; ++ iee_write_key_payload(key, key_payload); ++ #else + key->payload.data[1] = prep->payload.data[1]; + key->payload.data[2] = prep->payload.data[2]; + key->payload.data[3] = prep->payload.data[3]; ++ #endif + prep->payload.data[0] = NULL; + prep->payload.data[1] = NULL; + prep->payload.data[2] = NULL; +@@ -1262,6 +1486,11 @@ void __init key_init(void) + /* allocate a slab in which we can store keys */ + key_jar = kmem_cache_create("key_jar", sizeof(struct key), + 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); ++ #ifdef CONFIG_KEYP ++ key_union_jar = kmem_cache_create("key_union_jar", sizeof(struct key_union), 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); ++ key_struct_jar = kmem_cache_create("key_struct_jar", sizeof(struct key_struct), 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); ++ key_payload_jar = kmem_cache_create("key_payload_jar", sizeof(union key_payload)*2, 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); ++ #endif + + /* add the special key types */ + list_add_tail(&key_type_keyring.link, &key_types_list); +diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c +index aa1dc43b16dd..e92df31642d5 100644 +--- a/security/keys/keyctl.c ++++ b/security/keys/keyctl.c +@@ -23,6 +23,12 @@ + #include + #include + #include "internal.h" ++#ifdef CONFIG_CREDP ++#include ++#endif ++#ifdef CONFIG_KEYP ++#include +#endif -+ - #include - #include -@@ -146,6 +150,9 @@ pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node, - struct page *reuse) + #define KEY_MAX_DESC_SIZE 4096 + +@@ -804,11 +810,19 @@ static long __keyctl_read_key(struct key *key, char *buffer, size_t buflen) { - pte_t *pte = pte_offset_kernel(pmd, addr); -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr; + long ret; + ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(key)); ++ #else + down_read(&key->sem); + #endif - if (pte_none(ptep_get(pte))) { - pte_t entry; - void *p; -@@ -167,6 +174,11 @@ pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node, - get_page(reuse); - p = page_to_virt(reuse); + ret = key_validate(key); + if (ret == 0) + ret = key->type->read(key, buffer, buflen); ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + return ret; + } + +@@ -978,7 +992,11 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group) + + /* make the changes with the locks held to prevent chown/chown races */ + ret = -EACCES; ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(key)); ++ #else + down_write(&key->sem); ++ #endif + + { + bool is_privileged_op = false; +@@ -1036,19 +1054,32 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group) } -+#ifdef CONFIG_PTP -+ iee_addr = __phys_to_iee(__pa(p)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)p); -+#endif - entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL); - set_pte_at(&init_mm, addr, pte, entry); + + zapowner = key->user; ++ #ifdef CONFIG_KEYP ++ iee_set_key_user(key, newowner); ++ iee_set_key_uid(key, uid); ++ #else + key->user = newowner; + key->uid = uid; ++ #endif } -@@ -176,11 +188,20 @@ pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node, - static void * __meminit vmemmap_alloc_block_zero(unsigned long size, int node) - { - void *p = vmemmap_alloc_block(size, node); -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr; + + /* change the GID */ + if (group != (gid_t) -1) ++ #ifdef CONFIG_KEYP ++ iee_set_key_gid(key, gid); ++ #else + key->gid = gid; ++ #endif + + notify_key(key, NOTIFY_KEY_SETATTR, 0); + ret = 0; + + error_put: ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(key)); ++ #else + up_write(&key->sem); ++ #endif + key_put(key); + if (zapowner) + key_user_put(zapowner); +@@ -1090,16 +1121,28 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm) + + /* make the changes with the locks held to prevent chown/chmod races */ + ret = -EACCES; ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(key)); ++ #else + down_write(&key->sem); + #endif - if (!p) - return NULL; - memset(p, 0, size); + /* if we're not the sysadmin, we can only change a key that we own */ + if (uid_eq(key->uid, current_fsuid()) || capable(CAP_SYS_ADMIN)) { ++ #ifdef CONFIG_KEYP ++ iee_set_key_perm(key, perm); ++ #else + key->perm = perm; ++ #endif + notify_key(key, NOTIFY_KEY_SETATTR, 0); + ret = 0; + } -+ #ifdef CONFIG_PTP -+ iee_addr = __phys_to_iee(__pa(p)); -+ set_iee_page_valid(iee_addr); -+ iee_set_logical_mem_ro((unsigned long)p); ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(key)); ++ #else + up_write(&key->sem); + #endif -+ - return p; - } + key_put(key); + error: + return ret; +@@ -1155,7 +1198,11 @@ static int keyctl_change_reqkey_auth(struct key *key) + return -ENOMEM; -diff --git a/mm/vmalloc.c b/mm/vmalloc.c -index e6058942a084..27a006728009 100644 ---- a/mm/vmalloc.c -+++ b/mm/vmalloc.c -@@ -3431,7 +3431,7 @@ static int vmap_pfn_apply(pte_t *pte, unsigned long addr, void *private) + key_put(new->request_key_auth); ++ #ifdef CONFIG_CREDP ++ iee_set_cred_request_key_auth(new,key_get(key)); ++ #else + new->request_key_auth = key_get(key); ++ #endif - if (WARN_ON_ONCE(pfn_valid(pfn))) - return -EINVAL; -- -+ - ptent = pte_mkspecial(pfn_pte(pfn, data->prot)); - set_pte_at(&init_mm, addr, pte, ptent); + return commit_creds(new); + } +@@ -1196,7 +1243,11 @@ static long keyctl_instantiate_key_common(key_serial_t id, + if (!instkey) + goto error; -diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c -index c42ddd85ff1f..4714b4f2be08 100644 ---- a/net/dns_resolver/dns_key.c -+++ b/net/dns_resolver/dns_key.c -@@ -34,6 +34,10 @@ - #include - #include "internal.h" ++ #ifdef CONFIG_KEYP ++ rka = ((union key_payload *)(instkey->name_link.next))->data[0]; ++ #else + rka = instkey->payload.data[0]; ++ #endif + if (rka->target_key->serial != id) + goto error; -+#ifdef CONFIG_CREDP -+#include -+#endif -+ - MODULE_DESCRIPTION("DNS Resolver"); - MODULE_AUTHOR("Wang Lei"); - MODULE_LICENSE("GPL"); -@@ -365,8 +369,13 @@ static int __init init_dns_resolver(void) - /* instruct request_key() to use this special keyring as a cache for - * the results it looks up */ - set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); -+ #ifdef CONFIG_CREDP -+ iee_set_cred_thread_keyring(cred,keyring); -+ iee_set_cred_jit_keyring(cred,KEY_REQKEY_DEFL_THREAD_KEYRING); +@@ -1358,7 +1409,11 @@ long keyctl_reject_key(key_serial_t id, unsigned timeout, unsigned error, + if (!instkey) + goto error; + ++ #ifdef CONFIG_KEYP ++ rka = ((union key_payload *)(instkey->name_link.next))->data[0]; + #else - cred->thread_keyring = keyring; - cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; + rka = instkey->payload.data[0]; + #endif - dns_resolver_cache = cred; + if (rka->target_key->serial != id) + goto error; - kdebug("DNS resolver keyring: %d\n", key_serial(keyring)); -diff --git a/security/commoncap.c b/security/commoncap.c -index bc0521104197..d7d3b7cc13e8 100644 ---- a/security/commoncap.c -+++ b/security/commoncap.c -@@ -26,6 +26,10 @@ - #include - #include +@@ -1432,7 +1487,11 @@ long keyctl_set_reqkey_keyring(int reqkey_defl) + } -+#ifdef CONFIG_CREDP -+#include -+#endif -+ - /* - * If a non-root user executes a setuid-root binary in - * !secure(SECURE_NOROOT) mode, then we raise capabilities. -@@ -266,6 +270,15 @@ int cap_capset(struct cred *new, - if (!cap_issubset(*effective, *permitted)) - return -EPERM; + set: ++ #ifdef CONFIG_CREDP ++ iee_set_cred_jit_keyring(new,reqkey_defl); ++ #else + new->jit_keyring = reqkey_defl; ++ #endif + commit_creds(new); + return old_setting; + error: +@@ -1644,9 +1703,17 @@ long keyctl_session_to_parent(void) + cred = cred_alloc_blank(); + if (!cred) + goto error_keyring; ++ #ifdef CONFIG_CREDP ++ newwork = (struct rcu_head *)(cred->rcu.func); ++ #else + newwork = &cred->rcu; ++ #endif + #ifdef CONFIG_CREDP -+ iee_set_cred_cap_effective(new,*effective); -+ iee_set_cred_cap_inheritable(new,*inheritable); -+ iee_set_cred_cap_permitted(new,*permitted); -+ -+ iee_set_cred_cap_ambient(new,cap_intersect(new->cap_ambient, -+ cap_intersect(*permitted, -+ *inheritable))); ++ iee_set_cred_session_keyring(cred,key_ref_to_ptr(keyring_r)); + #else - new->cap_effective = *effective; - new->cap_inheritable = *inheritable; - new->cap_permitted = *permitted; -@@ -277,6 +290,7 @@ int cap_capset(struct cred *new, - new->cap_ambient = cap_intersect(new->cap_ambient, - cap_intersect(*permitted, - *inheritable)); + cred->session_keyring = key_ref_to_ptr(keyring_r); + #endif - if (WARN_ON(!cap_ambient_invariant_ok(new))) - return -EINVAL; - return 0; -@@ -601,9 +615,16 @@ static inline int bprm_caps_from_vfs_caps(struct cpu_vfs_cap_data *caps, - * pP' = (X & fP) | (pI & fI) - * The addition of pA' is handled later. - */ -+#ifdef CONFIG_CREDP -+ kernel_cap_t temp = new->cap_permitted; -+ temp.val = (new->cap_bset.val & caps->permitted.val) | -+ (new->cap_inheritable.val & caps->inheritable.val); -+ iee_set_cred_cap_permitted(new,temp); -+#else - new->cap_permitted.val = - (new->cap_bset.val & caps->permitted.val) | - (new->cap_inheritable.val & caps->inheritable.val); -+#endif + keyring_r = NULL; + init_task_work(newwork, key_change_session_keyring); - if (caps->permitted.val & ~new->cap_permitted.val) - /* insufficient to execute correctly */ -@@ -726,7 +747,15 @@ static int get_file_caps(struct linux_binprm *bprm, struct file *file, - int rc = 0; - struct cpu_vfs_cap_data vcaps; +@@ -1705,7 +1772,11 @@ long keyctl_session_to_parent(void) + write_unlock_irq(&tasklist_lock); + rcu_read_unlock(); + if (oldwork) ++ #ifdef CONFIG_CREDP ++ put_cred(*(struct cred **)(oldwork + 1)); ++ #else + put_cred(container_of(oldwork, struct cred, rcu)); ++ #endif + if (newwork) + put_cred(cred); + return ret; +@@ -1814,25 +1885,45 @@ long keyctl_watch_key(key_serial_t id, int watch_queue_fd, int watch_id) + if (ret < 0) + goto err_watch; -+ #ifdef CONFIG_CREDP -+ do { -+ kernel_cap_t tmp_cap = bprm->cred->cap_permitted; -+ tmp_cap.val = 0; -+ iee_set_cred_cap_permitted(bprm->cred, tmp_cap); -+ } while (0); ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(key)); ++ #else + down_write(&key->sem); ++ #endif + if (!key->watchers) { ++ #ifdef CONFIG_KEYP ++ iee_set_key_watchers(key, wlist); ++ #else + key->watchers = wlist; ++ #endif + wlist = NULL; + } + + ret = add_watch_to_object(watch, key->watchers); ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(key)); ++ #else + up_write(&key->sem); ++ #endif + + if (ret == 0) + watch = NULL; + } else { + ret = -EBADSLT; + if (key->watchers) { ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(key)); ++ #else + down_write(&key->sem); ++ #endif + ret = remove_watch_from_object(key->watchers, + wqueue, key_serial(key), + false); ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(key)); ++ #else + up_write(&key->sem); ++ #endif + } + } + +diff --git a/security/keys/keyring.c b/security/keys/keyring.c +index f331725d5a37..1da67fd7e4f1 100644 +--- a/security/keys/keyring.c ++++ b/security/keys/keyring.c +@@ -21,6 +21,11 @@ + #include + #include "internal.h" + ++#ifdef CONFIG_KEYP ++#include ++extern void iee_memcpy(void *dst, void *src, size_t n); ++#endif ++ + /* + * When plumbing the depths of the key tree, this sets a hard limit + * set on how deep we're willing to go. +@@ -112,7 +117,11 @@ static void keyring_publish_name(struct key *keyring) + keyring->description[0] && + keyring->description[0] != '.') { + write_lock(&keyring_name_lock); ++ #ifdef CONFIG_KEYP ++ list_add_tail(&(((struct key_struct *)(keyring->name_link.prev))->name_link), &ns->keyring_name_list); ++ #else + list_add_tail(&keyring->name_link, &ns->keyring_name_list); ++ #endif + write_unlock(&keyring_name_lock); + } + } +@@ -140,7 +149,11 @@ static void keyring_free_preparse(struct key_preparsed_payload *prep) + static int keyring_instantiate(struct key *keyring, + struct key_preparsed_payload *prep) + { ++ #ifdef CONFIG_KEYP ++ assoc_array_init(&((struct key_struct *)(keyring->name_link.prev))->keys); + #else - cap_clear(bprm->cred->cap_permitted); + assoc_array_init(&keyring->keys); + #endif + /* make the keyring available by name if it has one */ + keyring_publish_name(keyring); + return 0; +@@ -207,6 +220,57 @@ static void hash_key_type_and_desc(struct keyring_index_key *index_key) + index_key->hash = hash; + } - if (!file_caps_enabled) - return 0; -@@ -757,7 +786,15 @@ static int get_file_caps(struct linux_binprm *bprm, struct file *file, ++#ifdef CONFIG_KEYP ++static void iee_hash_key_type_and_desc(struct keyring_index_key *index_key) ++{ ++ const unsigned level_shift = ASSOC_ARRAY_LEVEL_STEP; ++ const unsigned long fan_mask = ASSOC_ARRAY_FAN_MASK; ++ const char *description = index_key->description; ++ unsigned long hash, type; ++ u32 piece; ++ u64 acc; ++ int n, desc_len = index_key->desc_len; ++ ++ type = (unsigned long)index_key->type; ++ acc = mult_64x32_and_fold(type, desc_len + 13); ++ acc = mult_64x32_and_fold(acc, 9207); ++ piece = (unsigned long)index_key->domain_tag; ++ acc = mult_64x32_and_fold(acc, piece); ++ acc = mult_64x32_and_fold(acc, 9207); ++ ++ for (;;) { ++ n = desc_len; ++ if (n <= 0) ++ break; ++ if (n > 4) ++ n = 4; ++ piece = 0; ++ memcpy(&piece, description, n); ++ description += n; ++ desc_len -= n; ++ acc = mult_64x32_and_fold(acc, piece); ++ acc = mult_64x32_and_fold(acc, 9207); ++ } ++ ++ /* Fold the hash down to 32 bits if need be. */ ++ hash = acc; ++ if (ASSOC_ARRAY_KEY_CHUNK_SIZE == 32) ++ hash ^= acc >> 32; ++ ++ /* Squidge all the keyrings into a separate part of the tree to ++ * ordinary keys by making sure the lowest level segment in the hash is ++ * zero for keyrings and non-zero otherwise. ++ */ ++ if (index_key->type != &key_type_keyring && (hash & fan_mask) == 0) ++ hash |= (hash >> (ASSOC_ARRAY_KEY_CHUNK_SIZE - level_shift)) | 1; ++ else if (index_key->type == &key_type_keyring && (hash & fan_mask) != 0) ++ hash = (hash + (hash << level_shift)) & ~fan_mask; ++ struct keyring_index_key tmp = *index_key; ++ tmp.hash = hash; ++ iee_set_key_index_key(container_of(index_key, struct key, index_key), tmp); ++} ++#endif ++ + /* + * Finalise an index key to include a part of the description actually in the + * index key, to set the domain tag and to calculate the hash. +@@ -228,6 +292,34 @@ void key_set_index_key(struct keyring_index_key *index_key) + hash_key_type_and_desc(index_key); + } - out: - if (rc) -+ #ifdef CONFIG_CREDP -+ do { -+ kernel_cap_t tmp_cap = bprm->cred->cap_permitted; -+ tmp_cap.val = 0; -+ iee_set_cred_cap_permitted(bprm->cred, tmp_cap); -+ } while (0); ++#ifdef CONFIG_KEYP ++void iee_key_set_index_key(struct keyring_index_key *index_key) ++{ ++ static struct key_tag default_domain_tag = { .usage = REFCOUNT_INIT(1), }; ++ size_t n = min_t(size_t, index_key->desc_len, sizeof(index_key->desc)); ++ struct keyring_index_key tmp; ++ ++ iee_memcpy(index_key->desc, index_key->description, n); ++ ++ if (!index_key->domain_tag) { ++ if (index_key->type->flags & KEY_TYPE_NET_DOMAIN) ++ { ++ tmp = *index_key; ++ tmp.domain_tag = current->nsproxy->net_ns->key_domain; ++ iee_set_key_index_key(container_of(index_key, struct key, index_key), tmp); ++ } ++ else ++ { ++ tmp = *index_key; ++ tmp.domain_tag = &default_domain_tag; ++ iee_set_key_index_key(container_of(index_key, struct key, index_key), tmp); ++ } ++ } ++ ++ iee_hash_key_type_and_desc(index_key); ++} ++#endif ++ + /** + * key_put_tag - Release a ref on a tag. + * @tag: The tag to release. +@@ -414,9 +506,15 @@ static void keyring_destroy(struct key *keyring) + if (keyring->description) { + write_lock(&keyring_name_lock); + ++ #ifdef CONFIG_KEYP ++ if(((struct key_struct *)(keyring->name_link.prev))->name_link.next != NULL && ++ !list_empty(&(((struct key_struct *)(keyring->name_link.prev))->name_link))) ++ list_del(&(((struct key_struct *)(keyring->name_link.prev))->name_link)); + #else - cap_clear(bprm->cred->cap_permitted); + if (keyring->name_link.next != NULL && + !list_empty(&keyring->name_link)) + list_del(&keyring->name_link); + #endif - return rc; + write_unlock(&keyring_name_lock); + } +@@ -428,7 +526,11 @@ static void keyring_destroy(struct key *keyring) + kfree(keyres); + } + ++ #ifdef CONFIG_KEYP ++ assoc_array_destroy(&((struct key_struct *)(keyring->name_link.prev))->keys, &keyring_assoc_array_ops); ++ #else + assoc_array_destroy(&keyring->keys, &keyring_assoc_array_ops); ++ #endif } -@@ -809,8 +846,13 @@ static void handle_privileged_root(struct linux_binprm *bprm, bool has_fcap, - */ - if (__is_eff(root_uid, new) || __is_real(root_uid, new)) { - /* pP' = (cap_bset & ~0) | (pI & ~0) */ -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_permitted(new,cap_combine(old->cap_bset, -+ old->cap_inheritable)); + + /* +@@ -442,8 +544,13 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m) + seq_puts(m, "[anon]"); + + if (key_is_positive(keyring)) { ++ #ifdef CONFIG_KEYP ++ if (((struct key_struct *)(keyring->name_link.prev))->keys.nr_leaves_on_tree != 0) ++ seq_printf(m, ": %lu", ((struct key_struct *)(keyring->name_link.prev))->keys.nr_leaves_on_tree); + #else - new->cap_permitted = cap_combine(old->cap_bset, - old->cap_inheritable); + if (keyring->keys.nr_leaves_on_tree != 0) + seq_printf(m, ": %lu", keyring->keys.nr_leaves_on_tree); + #endif + else + seq_puts(m, ": empty"); } - /* - * If only the real uid is 0, we do not set the effective bit. -@@ -919,34 +961,71 @@ int cap_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file) - /* downgrade; they get no more than they had, and maybe less */ - if (!ns_capable(new->user_ns, CAP_SETUID) || - (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) { -+ #ifdef CONFIG_CREDP -+ iee_set_cred_euid(new,new->uid); -+ iee_set_cred_egid(new,new->gid); -+ #else - new->euid = new->uid; - new->egid = new->gid; -+ #endif - } -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_permitted(new,cap_intersect(new->cap_permitted, -+ old->cap_permitted)); +@@ -494,8 +601,13 @@ static long keyring_read(const struct key *keyring, + ctx.buffer = (key_serial_t *)buffer; + ctx.buflen = buflen; + ctx.count = 0; ++ #ifdef CONFIG_KEYP ++ ret = assoc_array_iterate(&((struct key_struct *)(keyring->name_link.prev))->keys, ++ keyring_read_iterator, &ctx); + #else - new->cap_permitted = cap_intersect(new->cap_permitted, - old->cap_permitted); + ret = assoc_array_iterate(&keyring->keys, + keyring_read_iterator, &ctx); + #endif + if (ret < 0) { + kleave(" = %ld [iterate]", ret); + return ret; +@@ -503,7 +615,11 @@ static long keyring_read(const struct key *keyring, } -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(new,new->euid); -+ iee_set_cred_suid(new,new->euid); -+ iee_set_cred_fsgid(new,new->egid); -+ iee_set_cred_sgid(new,new->egid); + /* Return the size of the buffer needed */ ++ #ifdef CONFIG_KEYP ++ ret = ((struct key_struct *)(keyring->name_link.prev))->keys.nr_leaves_on_tree * sizeof(key_serial_t); + #else - new->suid = new->fsuid = new->euid; - new->sgid = new->fsgid = new->egid; + ret = keyring->keys.nr_leaves_on_tree * sizeof(key_serial_t); + #endif - - /* File caps or setid cancels ambient. */ - if (has_fcap || is_setid) -+ #ifdef CONFIG_CREDP -+ do { -+ kernel_cap_t tmp_cap = new->cap_ambient; -+ tmp_cap.val = 0; -+ iee_set_cred_cap_ambient(new, tmp_cap); -+ } while (0); + if (ret <= buflen) + kleave("= %ld [ok]", ret); + else +@@ -648,12 +764,22 @@ static int search_keyring(struct key *keyring, struct keyring_search_context *ct + if (ctx->match_data.lookup_type == KEYRING_SEARCH_LOOKUP_DIRECT) { + const void *object; + ++ #ifdef CONFIG_KEYP ++ object = assoc_array_find(&((struct key_struct *)(keyring->name_link.prev))->keys, ++ &keyring_assoc_array_ops, ++ &ctx->index_key); + #else - cap_clear(new->cap_ambient); + object = assoc_array_find(&keyring->keys, + &keyring_assoc_array_ops, + &ctx->index_key); + #endif - - /* - * Now that we've computed pA', update pP' to give: - * pP' = (X & fP) | (pI & fI) | pA' - */ -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_permitted(new,cap_combine(new->cap_permitted, new->cap_ambient)); + return object ? ctx->iterator(object, ctx) : 0; + } ++ #ifdef CONFIG_KEYP ++ return assoc_array_iterate(&((struct key_struct *)(keyring->name_link.prev))->keys, ctx->iterator, ctx); + #else - new->cap_permitted = cap_combine(new->cap_permitted, new->cap_ambient); + return assoc_array_iterate(&keyring->keys, ctx->iterator, ctx); + #endif + } - /* - * Set pE' = (fE ? pP' : pA'). Because pA' is zero if fE is set, - * this is the same as pE' = (fE ? pP' : 0) | pA'. - */ - if (effective) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_effective(new,new->cap_permitted); + /* +@@ -729,7 +855,11 @@ static bool search_nested_keyrings(struct key *keyring, + if (!(ctx->flags & KEYRING_SEARCH_RECURSE)) + goto not_this_keyring; + ++ #ifdef CONFIG_KEYP ++ ptr = READ_ONCE(((struct key_struct *)(keyring->name_link.prev))->keys.root); ++ #else + ptr = READ_ONCE(keyring->keys.root); ++ #endif + if (!ptr) + goto not_this_keyring; + +@@ -856,10 +986,17 @@ static bool search_nested_keyrings(struct key *keyring, + key = key_ref_to_ptr(ctx->result); + key_check(key); + if (!(ctx->flags & KEYRING_SEARCH_NO_UPDATE_TIME)) { ++ #ifdef CONFIG_KEYP ++ iee_set_key_last_used_at(key, ctx->now); ++ iee_set_key_last_used_at(keyring, ctx->now); ++ while (sp > 0) ++ iee_set_key_last_used_at(stack[--sp].keyring, ctx->now); + #else - new->cap_effective = new->cap_permitted; + key->last_used_at = ctx->now; + keyring->last_used_at = ctx->now; + while (sp > 0) + stack[--sp].keyring->last_used_at = ctx->now; + #endif - else -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_effective(new,new->cap_ambient); + } + kleave(" = true"); + return true; +@@ -1056,7 +1193,11 @@ int keyring_restrict(key_ref_t keyring_ref, const char *type, + goto error; + } + ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(keyring)); ++ #else + down_write(&keyring->sem); ++ #endif + down_write(&keyring_serialise_restrict_sem); + + if (keyring->restrict_link) { +@@ -1064,12 +1205,20 @@ int keyring_restrict(key_ref_t keyring_ref, const char *type, + } else if (keyring_detect_restriction_cycle(keyring, restrict_link)) { + ret = -EDEADLK; + } else { ++ #ifdef CONFIG_KEYP ++ iee_set_key_restrict_link(keyring, restrict_link); + #else - new->cap_effective = new->cap_ambient; + keyring->restrict_link = restrict_link; + #endif - - if (WARN_ON(!cap_ambient_invariant_ok(new))) - return -EPERM; -@@ -957,7 +1036,11 @@ int cap_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file) - return ret; + notify_key(keyring, NOTIFY_KEY_SETATTR, 0); } -+ #ifdef CONFIG_CREDP -+ iee_set_cred_securebits(new,new->securebits & ~issecure_mask(SECURE_KEEP_CAPS)); + up_write(&keyring_serialise_restrict_sem); ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(keyring)); + #else - new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS); + up_write(&keyring->sem); + #endif - if (WARN_ON(!cap_ambient_invariant_ok(new))) - return -EPERM; -@@ -1092,8 +1175,21 @@ static inline void cap_emulate_setxuid(struct cred *new, const struct cred *old) - !uid_eq(new->euid, root_uid) && - !uid_eq(new->suid, root_uid))) { - if (!issecure(SECURE_KEEP_CAPS)) { -+ #ifdef CONFIG_CREDP -+ do { -+ kernel_cap_t tmp_cap = new->cap_permitted; -+ tmp_cap.val = 0; -+ iee_set_cred_cap_permitted(new, tmp_cap); -+ } while (0); -+ do { -+ kernel_cap_t tmp_cap = new->cap_effective; -+ tmp_cap.val = 0; -+ iee_set_cred_cap_effective(new, tmp_cap); -+ } while (0); -+ #else - cap_clear(new->cap_permitted); - cap_clear(new->cap_effective); -+ #endif - } + if (ret < 0) { + key_put(restrict_link->key); +@@ -1109,8 +1258,13 @@ key_ref_t find_key_to_update(key_ref_t keyring_ref, + kenter("{%d},{%s,%s}", + keyring->serial, index_key->type->name, index_key->description); - /* -@@ -1101,12 +1197,32 @@ static inline void cap_emulate_setxuid(struct cred *new, const struct cred *old) - * by exec to drop capabilities. We should make sure that - * this remains the case. - */ -+ #ifdef CONFIG_CREDP -+ do { -+ kernel_cap_t tmp_cap = new->cap_ambient; -+ tmp_cap.val = 0; -+ iee_set_cred_cap_ambient(new, tmp_cap); -+ } while (0); ++ #ifdef CONFIG_KEYP ++ object = assoc_array_find(&((struct key_struct *)(keyring->name_link.prev))->keys, &keyring_assoc_array_ops, ++ index_key); ++ #else + object = assoc_array_find(&keyring->keys, &keyring_assoc_array_ops, + index_key); ++ #endif + + if (object) + goto found; +@@ -1154,7 +1308,13 @@ struct key *find_keyring_by_name(const char *name, bool uid_keyring) + /* Search this hash bucket for a keyring with a matching name that + * grants Search permission and that hasn't been revoked + */ ++ #ifdef CONFIG_KEYP ++ for(keyring = list_first_entry(&ns->keyring_name_list, struct key_struct, name_link)->key; ++ !(&(((struct key_struct *)(keyring->name_link.prev))->name_link) == (&ns->keyring_name_list)); ++ keyring = list_entry(((struct key_struct *)(keyring->name_link.prev))->name_link.next, struct key_struct, name_link)->key) { ++ #else + list_for_each_entry(keyring, &ns->keyring_name_list, name_link) { ++ #endif + if (!kuid_has_mapping(ns, keyring->user->uid)) + continue; + +@@ -1177,9 +1337,15 @@ struct key *find_keyring_by_name(const char *name, bool uid_keyring) + /* we've got a match but we might end up racing with + * key_cleanup() if the keyring is currently 'dead' + * (ie. it has a zero usage count) */ ++ #ifdef CONFIG_KEYP ++ if (!iee_set_key_usage(keyring, 0, REFCOUNT_INC_NOT_ZERO)) ++ continue; ++ iee_set_key_last_used_at(keyring, ktime_get_real_seconds()); + #else - cap_clear(new->cap_ambient); + if (!refcount_inc_not_zero(&keyring->usage)) + continue; + keyring->last_used_at = ktime_get_real_seconds(); + #endif + goto out; } - if (uid_eq(old->euid, root_uid) && !uid_eq(new->euid, root_uid)) -+ #ifdef CONFIG_CREDP -+ do { -+ kernel_cap_t tmp_cap = new->cap_effective; -+ tmp_cap.val = 0; -+ iee_set_cred_cap_effective(new, tmp_cap); -+ } while (0); + +@@ -1238,13 +1404,21 @@ static int keyring_detect_cycle(struct key *A, struct key *B) + */ + int __key_link_lock(struct key *keyring, + const struct keyring_index_key *index_key) ++ #ifdef CONFIG_KEYP ++ __acquires(&KEY_SEM(keyring)) ++ #else + __acquires(&keyring->sem) ++ #endif + __acquires(&keyring_serialise_link_lock) + { + if (keyring->type != &key_type_keyring) + return -ENOTDIR; + ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(keyring)); ++ #else + down_write(&keyring->sem); ++ #endif + + /* Serialise link/link calls to prevent parallel calls causing a cycle + * when linking two keyring in opposite orders. +@@ -1260,8 +1434,13 @@ int __key_link_lock(struct key *keyring, + */ + int __key_move_lock(struct key *l_keyring, struct key *u_keyring, + const struct keyring_index_key *index_key) ++ #ifdef CONFIG_KEYP ++ __acquires(&KEY_SEM(l_keyring)) ++ __acquires(&KEY_SEM(u_keyring)) ++ #else + __acquires(&l_keyring->sem) + __acquires(&u_keyring->sem) ++ #endif + __acquires(&keyring_serialise_link_lock) + { + if (l_keyring->type != &key_type_keyring || +@@ -1273,11 +1452,21 @@ int __key_move_lock(struct key *l_keyring, struct key *u_keyring, + * move operation. + */ + if (l_keyring < u_keyring) { ++ #ifdef CNOFIG_KEYP ++ down_write(&KEY_SEM(l_keyring)); ++ down_write_nested(&KEY_SEM(u_keyring), 1); + #else - cap_clear(new->cap_effective); + down_write(&l_keyring->sem); + down_write_nested(&u_keyring->sem, 1); + #endif - if (!uid_eq(old->euid, root_uid) && uid_eq(new->euid, root_uid)) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_effective(new,new->cap_permitted); + } else { ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(u_keyring)); ++ down_write_nested(&KEY_SEM(l_keyring), 1); + #else - new->cap_effective = new->cap_permitted; + down_write(&u_keyring->sem); + down_write_nested(&l_keyring->sem, 1); + #endif + } + + /* Serialise link/link calls to prevent parallel calls causing a cycle +@@ -1314,10 +1503,17 @@ int __key_link_begin(struct key *keyring, + /* Create an edit script that will insert/replace the key in the + * keyring tree. + */ ++ #ifdef CONFIG_KEYP ++ edit = assoc_array_insert(&((struct key_struct *)(keyring->name_link.prev))->keys, ++ &keyring_assoc_array_ops, ++ index_key, ++ NULL); ++ #else + edit = assoc_array_insert(&keyring->keys, + &keyring_assoc_array_ops, + index_key, + NULL); ++ #endif + if (IS_ERR(edit)) { + ret = PTR_ERR(edit); + goto error; +@@ -1385,7 +1581,11 @@ void __key_link(struct key *keyring, struct key *key, + void __key_link_end(struct key *keyring, + const struct keyring_index_key *index_key, + struct assoc_array_edit *edit) ++ #ifdef CONFIG_KEYP ++ __releases(&KEY_SEM(keyring)) ++ #else + __releases(&keyring->sem) ++ #endif + __releases(&keyring_serialise_link_lock) + { + BUG_ON(index_key->type == NULL); +@@ -1398,7 +1598,11 @@ void __key_link_end(struct key *keyring, + } + assoc_array_cancel_edit(edit); + } ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(keyring)); ++ #else + up_write(&keyring->sem); ++ #endif + + if (index_key->type == &key_type_keyring) + mutex_unlock(&keyring_serialise_link_lock); +@@ -1411,8 +1615,13 @@ static int __key_link_check_restriction(struct key *keyring, struct key *key) + { + if (!keyring->restrict_link || !keyring->restrict_link->check) + return 0; ++ #ifdef CONFIG_KEYP ++ return keyring->restrict_link->check(keyring, key->type, ((union key_payload *)(key->name_link.next)), ++ keyring->restrict_link->key); ++ #else + return keyring->restrict_link->check(keyring, key->type, &key->payload, + keyring->restrict_link->key); ++ #endif + } + + /** +@@ -1472,12 +1681,20 @@ EXPORT_SYMBOL(key_link); + * Lock a keyring for unlink. + */ + static int __key_unlink_lock(struct key *keyring) ++ #ifdef CONFIG_KEYP ++ __acquires(&KEY_SEM(keyring)) ++ #else + __acquires(&keyring->sem) ++ #endif + { + if (keyring->type != &key_type_keyring) + return -ENOTDIR; + ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(keyring)); ++ #else + down_write(&keyring->sem); ++ #endif + return 0; + } + +@@ -1491,8 +1708,13 @@ static int __key_unlink_begin(struct key *keyring, struct key *key, + + BUG_ON(*_edit != NULL); + ++ #ifdef CONFIG_KEYP ++ edit = assoc_array_delete(&((struct key_struct *)(keyring->name_link.prev))->keys, &keyring_assoc_array_ops, ++ &key->index_key); ++ #else + edit = assoc_array_delete(&keyring->keys, &keyring_assoc_array_ops, + &key->index_key); ++ #endif + if (IS_ERR(edit)) + return PTR_ERR(edit); + +@@ -1521,11 +1743,19 @@ static void __key_unlink(struct key *keyring, struct key *key, + static void __key_unlink_end(struct key *keyring, + struct key *key, + struct assoc_array_edit *edit) ++ #ifdef CONFIG_KEYP ++ __releases(&KEY_SEM(keyring)) ++ #else + __releases(&keyring->sem) ++ #endif + { + if (edit) + assoc_array_cancel_edit(edit); ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(keyring)); ++ #else + up_write(&keyring->sem); ++ #endif } /** -@@ -1142,13 +1258,22 @@ int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags) - if (!issecure(SECURE_NO_SETUID_FIXUP)) { - kuid_t root_uid = make_kuid(old->user_ns, 0); - if (uid_eq(old->fsuid, root_uid) && !uid_eq(new->fsuid, root_uid)) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_effective(new,cap_drop_fs_set(new->cap_effective)); -+ #else - new->cap_effective = - cap_drop_fs_set(new->cap_effective); -+ #endif +@@ -1655,9 +1885,15 @@ int keyring_clear(struct key *keyring) + if (keyring->type != &key_type_keyring) + return -ENOTDIR; - if (!uid_eq(old->fsuid, root_uid) && uid_eq(new->fsuid, root_uid)) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_effective(new,cap_raise_fs_set(new->cap_effective, -+ new->cap_permitted)); -+ #else - new->cap_effective = - cap_raise_fs_set(new->cap_effective, - new->cap_permitted); -+ #endif - } - break; ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(keyring)); ++ ++ edit = assoc_array_clear(&((struct key_struct *)(keyring->name_link.prev))->keys, &keyring_assoc_array_ops); ++ #else + down_write(&keyring->sem); -@@ -1243,7 +1368,15 @@ static int cap_prctl_drop(unsigned long cap) - new = prepare_creds(); - if (!new) - return -ENOMEM; -+ #ifdef CONFIG_CREDP -+ { -+ kernel_cap_t tmp = new->cap_bset; -+ cap_lower(tmp, cap); -+ iee_set_cred_cap_bset(new, tmp); -+ } + edit = assoc_array_clear(&keyring->keys, &keyring_assoc_array_ops); ++ #endif + if (IS_ERR(edit)) { + ret = PTR_ERR(edit); + } else { +@@ -1668,7 +1904,11 @@ int keyring_clear(struct key *keyring) + ret = 0; + } + ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(keyring)); + #else - cap_lower(new->cap_bset, cap); + up_write(&keyring->sem); + #endif - return commit_creds(new); + return ret; } + EXPORT_SYMBOL(keyring_clear); +@@ -1682,7 +1922,11 @@ static void keyring_revoke(struct key *keyring) + { + struct assoc_array_edit *edit; -@@ -1319,7 +1452,11 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, - new = prepare_creds(); - if (!new) - return -ENOMEM; -+ #ifdef CONFIG_CREDP -+ iee_set_cred_securebits(new,arg2); -+ #else - new->securebits = arg2; -+ #endif - return commit_creds(new); - - case PR_GET_SECUREBITS: -@@ -1338,9 +1475,17 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, - if (!new) - return -ENOMEM; - if (arg2) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_securebits(new,new->securebits | issecure_mask(SECURE_KEEP_CAPS)); -+ #else - new->securebits |= issecure_mask(SECURE_KEEP_CAPS); -+ #endif - else -+ #ifdef CONFIG_CREDP -+ iee_set_cred_securebits(new,new->securebits & ~issecure_mask(SECURE_KEEP_CAPS)); -+ #else - new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS); -+ #endif - return commit_creds(new); - - case PR_CAP_AMBIENT: -@@ -1351,7 +1496,15 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, - new = prepare_creds(); - if (!new) - return -ENOMEM; -+ #ifdef CONFIG_CREDP -+ do { -+ kernel_cap_t tmp_cap = new->cap_ambient; -+ tmp_cap.val = 0; -+ iee_set_cred_cap_ambient(new, tmp_cap); -+ } while (0); -+ #else - cap_clear(new->cap_ambient); -+ #endif - return commit_creds(new); - } ++ #ifdef CONFIG_KEYP ++ edit = assoc_array_clear(&((struct key_struct *)(keyring->name_link.prev))->keys, &keyring_assoc_array_ops); ++ #else + edit = assoc_array_clear(&keyring->keys, &keyring_assoc_array_ops); ++ #endif + if (!IS_ERR(edit)) { + if (edit) + assoc_array_apply_edit(edit); +@@ -1728,8 +1972,13 @@ void keyring_gc(struct key *keyring, time64_t limit) + + /* scan the keyring looking for dead keys */ + rcu_read_lock(); ++ #ifdef CONFIG_KEYP ++ result = assoc_array_iterate(&((struct key_struct *)(keyring->name_link.prev))->keys, ++ keyring_gc_check_iterator, &limit); ++ #else + result = assoc_array_iterate(&keyring->keys, + keyring_gc_check_iterator, &limit); ++ #endif + rcu_read_unlock(); + if (result == true) + goto do_gc; +@@ -1739,10 +1988,17 @@ void keyring_gc(struct key *keyring, time64_t limit) + return; + + do_gc: ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(keyring)); ++ assoc_array_gc(&((struct key_struct *)(keyring->name_link.prev))->keys, &keyring_assoc_array_ops, ++ keyring_gc_select_iterator, &limit); ++ up_write(&KEY_SEM(keyring)); ++ #else + down_write(&keyring->sem); + assoc_array_gc(&keyring->keys, &keyring_assoc_array_ops, + keyring_gc_select_iterator, &limit); + up_write(&keyring->sem); ++ #endif + kleave(" [gc]"); + } -@@ -1375,9 +1528,25 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, - if (!new) - return -ENOMEM; - if (arg2 == PR_CAP_AMBIENT_RAISE) -+ #ifdef CONFIG_CREDP -+ { -+ kernel_cap_t tmp = new->cap_ambient; -+ cap_raise(tmp, arg3); -+ iee_set_cred_cap_ambient(new, tmp); -+ } -+ #else - cap_raise(new->cap_ambient, arg3); -+ #endif - else -+ #ifdef CONFIG_CREDP -+ { -+ kernel_cap_t tmp = new->cap_ambient; -+ cap_lower(tmp, arg3); -+ iee_set_cred_cap_ambient(new, tmp); -+ } -+ #else - cap_lower(new->cap_ambient, arg3); -+ #endif - return commit_creds(new); - } +@@ -1781,7 +2037,11 @@ void keyring_restriction_gc(struct key *keyring, struct key_type *dead_type) + } -diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c -index 19be69fa4d05..6cb164dfc19b 100644 ---- a/security/keys/keyctl.c -+++ b/security/keys/keyctl.c -@@ -23,6 +23,9 @@ - #include - #include - #include "internal.h" -+#ifdef CONFIG_CREDP -+#include -+#endif + /* Lock the keyring to ensure that a link is not in progress */ ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(keyring)); ++ #else + down_write(&keyring->sem); ++ #endif - #define KEY_MAX_DESC_SIZE 4096 + keyres = keyring->restrict_link; -@@ -1155,7 +1158,11 @@ static int keyctl_change_reqkey_auth(struct key *key) - return -ENOMEM; +@@ -1791,7 +2051,11 @@ void keyring_restriction_gc(struct key *keyring, struct key_type *dead_type) + keyres->key = NULL; + keyres->keytype = NULL; - key_put(new->request_key_auth); -+ #ifdef CONFIG_CREDP -+ iee_set_cred_request_key_auth(new,key_get(key)); ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(keyring)); + #else - new->request_key_auth = key_get(key); + up_write(&keyring->sem); + #endif - return commit_creds(new); + kleave(" [restriction gc]"); } -@@ -1432,7 +1439,11 @@ long keyctl_set_reqkey_keyring(int reqkey_defl) +diff --git a/security/keys/proc.c b/security/keys/proc.c +index 4f4e2c1824f1..5f72240ddd96 100644 +--- a/security/keys/proc.c ++++ b/security/keys/proc.c +@@ -67,7 +67,11 @@ static struct rb_node *key_serial_next(struct seq_file *p, struct rb_node *n) + + n = rb_next(n); + while (n) { ++ #ifdef CONFIG_KEYP ++ struct key *key = rb_entry(n, struct key_union, serial_node)->key; ++ #else + struct key *key = rb_entry(n, struct key, serial_node); ++ #endif + if (kuid_has_mapping(user_ns, key->user->uid)) + break; + n = rb_next(n); +@@ -82,7 +86,11 @@ static struct key *find_ge_key(struct seq_file *p, key_serial_t id) + struct key *minkey = NULL; + + while (n) { ++ #ifdef CONFIG_KEYP ++ struct key *key = rb_entry(n, struct key_union, serial_node)->key; ++ #else + struct key *key = rb_entry(n, struct key, serial_node); ++ #endif + if (id < key->serial) { + if (!minkey || minkey->serial > key->serial) + minkey = key; +@@ -102,10 +110,18 @@ static struct key *find_ge_key(struct seq_file *p, key_serial_t id) + for (;;) { + if (kuid_has_mapping(user_ns, minkey->user->uid)) + return minkey; ++ #ifdef CONFIG_KEYP ++ n = rb_next(&(((struct key_union *)(minkey->graveyard_link.next))->serial_node)); ++ #else + n = rb_next(&minkey->serial_node); ++ #endif + if (!n) + return NULL; ++ #ifdef CONFIG_KEYP ++ minkey = rb_entry(n, struct key_union, serial_node)->key; ++ #else + minkey = rb_entry(n, struct key, serial_node); ++ #endif } + } - set: -+ #ifdef CONFIG_CREDP -+ iee_set_cred_jit_keyring(new,reqkey_defl); +@@ -123,12 +139,20 @@ static void *proc_keys_start(struct seq_file *p, loff_t *_pos) + if (!key) + return NULL; + *_pos = key->serial; ++ #ifdef CONFIG_KEYP ++ return &(((struct key_union *)(key->graveyard_link.next))->serial_node); + #else - new->jit_keyring = reqkey_defl; + return &key->serial_node; + #endif - commit_creds(new); - return old_setting; - error: -@@ -1644,9 +1655,17 @@ long keyctl_session_to_parent(void) - cred = cred_alloc_blank(); - if (!cred) - goto error_keyring; -+ #ifdef CONFIG_CREDP -+ newwork = (struct rcu_head *)(cred->rcu.func); + } + + static inline key_serial_t key_node_serial(struct rb_node *n) + { ++ #ifdef CONFIG_KEYP ++ struct key *key = rb_entry(n, struct key_union, serial_node)->key; + #else - newwork = &cred->rcu; + struct key *key = rb_entry(n, struct key, serial_node); + #endif + return key->serial; + } -+ #ifdef CONFIG_CREDP -+ iee_set_cred_session_keyring(cred,key_ref_to_ptr(keyring_r)); +@@ -153,7 +177,11 @@ static void proc_keys_stop(struct seq_file *p, void *v) + static int proc_keys_show(struct seq_file *m, void *v) + { + struct rb_node *_p = v; ++ #ifdef CONFIG_KEYP ++ struct key *key = rb_entry(_p, struct key_union, serial_node)->key; + #else - cred->session_keyring = key_ref_to_ptr(keyring_r); + struct key *key = rb_entry(_p, struct key, serial_node); + #endif - keyring_r = NULL; - init_task_work(newwork, key_change_session_keyring); - -@@ -1705,7 +1724,11 @@ long keyctl_session_to_parent(void) - write_unlock_irq(&tasklist_lock); - rcu_read_unlock(); - if (oldwork) -+ #ifdef CONFIG_CREDP -+ put_cred(*(struct cred **)(oldwork + 1)); -+ #else - put_cred(container_of(oldwork, struct cred, rcu)); -+ #endif - if (newwork) - put_cred(cred); - return ret; + unsigned long flags; + key_ref_t key_ref, skey_ref; + time64_t now, expiry; diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c -index b5d5333ab330..aaa2a2347d84 100644 +index b5d5333ab330..bff026c9abbf 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c -@@ -19,6 +19,10 @@ +@@ -19,6 +19,13 @@ #include #include "internal.h" +#ifdef CONFIG_CREDP +#include +#endif ++#ifdef CONFIG_KEYP ++#include ++#endif + /* Session keyring create vs join semaphore */ static DEFINE_MUTEX(key_session_mutex); -@@ -232,7 +236,11 @@ int install_thread_keyring_to_cred(struct cred *new) +@@ -232,7 +239,11 @@ int install_thread_keyring_to_cred(struct cred *new) if (IS_ERR(keyring)) return PTR_ERR(keyring); @@ -13338,7 +20112,7 @@ index b5d5333ab330..aaa2a2347d84 100644 return 0; } -@@ -279,7 +287,11 @@ int install_process_keyring_to_cred(struct cred *new) +@@ -279,7 +290,11 @@ int install_process_keyring_to_cred(struct cred *new) if (IS_ERR(keyring)) return PTR_ERR(keyring); @@ -13350,7 +20124,7 @@ index b5d5333ab330..aaa2a2347d84 100644 return 0; } -@@ -338,7 +350,11 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring) +@@ -338,7 +353,11 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring) /* install the keyring */ old = cred->session_keyring; @@ -13362,7 +20136,93 @@ index b5d5333ab330..aaa2a2347d84 100644 if (old) key_put(old); -@@ -911,7 +927,11 @@ long join_session_keyring(const char *name) +@@ -378,9 +397,15 @@ void key_fsuid_changed(struct cred *new_cred) + { + /* update the ownership of the thread keyring */ + if (new_cred->thread_keyring) { ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(new_cred->thread_keyring)); ++ iee_set_key_uid(new_cred->thread_keyring, new_cred->fsuid); ++ up_write(&KEY_SEM(new_cred->thread_keyring)); ++ #else + down_write(&new_cred->thread_keyring->sem); + new_cred->thread_keyring->uid = new_cred->fsuid; + up_write(&new_cred->thread_keyring->sem); ++ #endif + } + } + +@@ -391,9 +416,15 @@ void key_fsgid_changed(struct cred *new_cred) + { + /* update the ownership of the thread keyring */ + if (new_cred->thread_keyring) { ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM(new_cred->thread_keyring)); ++ iee_set_key_gid(new_cred->thread_keyring, new_cred->fsgid); ++ up_write(&KEY_SEM(new_cred->thread_keyring)); ++ #else + down_write(&new_cred->thread_keyring->sem); + new_cred->thread_keyring->gid = new_cred->fsgid; + up_write(&new_cred->thread_keyring->sem); ++ #endif + } + } + +@@ -557,7 +588,11 @@ key_ref_t search_process_keyrings_rcu(struct keyring_search_context *ctx) + const struct cred *cred = ctx->cred; + + if (key_validate(cred->request_key_auth) == 0) { ++ #ifdef CONFIG_KEYP ++ rka = ((union key_payload *)(ctx->cred->request_key_auth->name_link.next))->data[0]; ++ #else + rka = ctx->cred->request_key_auth->payload.data[0]; ++ #endif + + //// was search_process_keyrings() [ie. recursive] + ctx->cred = rka->cred; +@@ -725,17 +760,29 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, + if (!ctx.cred->request_key_auth) + goto error; + ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(ctx.cred->request_key_auth)); ++ #else + down_read(&ctx.cred->request_key_auth->sem); ++ #endif + if (test_bit(KEY_FLAG_REVOKED, + &ctx.cred->request_key_auth->flags)) { + key_ref = ERR_PTR(-EKEYREVOKED); + key = NULL; + } else { ++ #ifdef CONFIG_KEYP ++ rka = ((union key_payload *)(ctx.cred->request_key_auth->name_link.next))->data[0]; ++ #else + rka = ctx.cred->request_key_auth->payload.data[0]; ++ #endif + key = rka->dest_keyring; + __key_get(key); + } ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(ctx.cred->request_key_auth)); ++ #else + up_read(&ctx.cred->request_key_auth->sem); ++ #endif + if (!key) + goto error; + key_ref = make_key_ref(key, 1); +@@ -804,7 +851,11 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, + if (ret < 0) + goto invalid_key; + ++ #ifdef CONFIG_KEYP ++ iee_set_key_last_used_at(key, ktime_get_real_seconds()); ++ #else + key->last_used_at = ktime_get_real_seconds(); ++ #endif + + error: + put_cred(ctx.cred); +@@ -911,7 +962,11 @@ long join_session_keyring(const char *name) void key_change_session_keyring(struct callback_head *twork) { const struct cred *old = current_cred(); @@ -13374,7 +20234,7 @@ index b5d5333ab330..aaa2a2347d84 100644 if (unlikely(current->flags & PF_EXITING)) { put_cred(new); -@@ -925,6 +945,38 @@ void key_change_session_keyring(struct callback_head *twork) +@@ -925,6 +980,38 @@ void key_change_session_keyring(struct callback_head *twork) return; } @@ -13410,19 +20270,188 @@ index b5d5333ab330..aaa2a2347d84 100644 + iee_set_cred_thread_keyring(new,key_get(old->thread_keyring)); + iee_set_cred_process_keyring(new,key_get(old->process_keyring)); + #else - new-> uid = old-> uid; - new-> euid = old-> euid; - new-> suid = old-> suid; -@@ -948,6 +1000,7 @@ void key_change_session_keyring(struct callback_head *twork) - new->jit_keyring = old->jit_keyring; - new->thread_keyring = key_get(old->thread_keyring); - new->process_keyring = key_get(old->process_keyring); + new-> uid = old-> uid; + new-> euid = old-> euid; + new-> suid = old-> suid; +@@ -948,6 +1035,7 @@ void key_change_session_keyring(struct callback_head *twork) + new->jit_keyring = old->jit_keyring; + new->thread_keyring = key_get(old->thread_keyring); + new->process_keyring = key_get(old->process_keyring); ++ #endif + + security_transfer_creds(new, old); + +diff --git a/security/keys/request_key.c b/security/keys/request_key.c +index a7673ad86d18..d281459651af 100644 +--- a/security/keys/request_key.c ++++ b/security/keys/request_key.c +@@ -17,6 +17,10 @@ + #include "internal.h" + #include + ++#ifdef CONFIG_KEYP ++#include ++#endif ++ + #define key_negative_timeout 60 /* default timeout on a negative key's existence */ + + static struct key *check_cached_key(struct keyring_search_context *ctx) +@@ -285,13 +289,21 @@ static int construct_get_dest_keyring(struct key **_dest_keyring) + case KEY_REQKEY_DEFL_REQUESTOR_KEYRING: + if (cred->request_key_auth) { + authkey = cred->request_key_auth; ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(authkey)); ++ #else + down_read(&authkey->sem); ++ #endif + rka = get_request_key_auth(authkey); + if (!test_bit(KEY_FLAG_REVOKED, + &authkey->flags)) + dest_keyring = + key_get(rka->dest_keyring); ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(authkey)); ++ #else + up_read(&authkey->sem); ++ #endif + if (dest_keyring) { + do_perm_check = false; + break; +@@ -398,7 +410,11 @@ static int construct_alloc_key(struct keyring_search_context *ctx, + if (IS_ERR(key)) + goto alloc_failed; + ++ #ifdef CONFIG_KEYP ++ iee_set_key_flag_bit(key, KEY_FLAG_USER_CONSTRUCT, SET_BIT_OP); ++ #else + set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); ++ #endif + + if (dest_keyring) { + ret = __key_link_lock(dest_keyring, &key->index_key); +diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c +index 8f33cd170e42..ddf86b3a2ecb 100644 +--- a/security/keys/request_key_auth.c ++++ b/security/keys/request_key_auth.c +@@ -145,7 +145,11 @@ static void request_key_auth_revoke(struct key *key) + */ + static void request_key_auth_destroy(struct key *key) + { ++ #ifdef CONFIG_KEYP ++ struct request_key_auth *rka = rcu_access_pointer(((union key_payload *)(key->name_link.next))->rcu_data0); ++ #else + struct request_key_auth *rka = rcu_access_pointer(key->payload.rcu_data0); ++ #endif + + kenter("{%d}", key->serial); + if (rka) { +@@ -184,22 +188,38 @@ struct key *request_key_auth_new(struct key *target, const char *op, + * another process */ + if (cred->request_key_auth) { + /* it is - use that instantiation context here too */ ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(cred->request_key_auth)); ++ #else + down_read(&cred->request_key_auth->sem); ++ #endif + + /* if the auth key has been revoked, then the key we're + * servicing is already instantiated */ + if (test_bit(KEY_FLAG_REVOKED, + &cred->request_key_auth->flags)) { ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(cred->request_key_auth)); ++ #else + up_read(&cred->request_key_auth->sem); ++ #endif + ret = -EKEYREVOKED; + goto error_free_rka; + } + ++ #ifdef CONFIG_KEYP ++ irka = ((union key_payload *)(cred->request_key_auth->name_link.next))->data[0]; ++ #else + irka = cred->request_key_auth->payload.data[0]; ++ #endif + rka->cred = get_cred(irka->cred); + rka->pid = irka->pid; + ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(cred->request_key_auth)); ++ #else + up_read(&cred->request_key_auth->sem); ++ #endif + } + else { + /* it isn't - use this process as the context */ +diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c +index fee1ab2c734d..5ef67deb1df0 100644 +--- a/security/keys/trusted-keys/trusted_core.c ++++ b/security/keys/trusted-keys/trusted_core.c +@@ -233,7 +233,11 @@ static int trusted_update(struct key *key, struct key_preparsed_payload *prep) + + if (key_is_negative(key)) + return -ENOKEY; ++ #ifdef CONFIG_KEYP ++ p = ((union key_payload *)(key->name_link.next))->data[0]; ++ #else + p = key->payload.data[0]; ++ #endif + if (!p->migratable) + return -EPERM; + if (datalen <= 0 || datalen > 32767 || !prep->data) +@@ -307,7 +311,11 @@ static long trusted_read(const struct key *key, char *buffer, + */ + static void trusted_destroy(struct key *key) + { ++ #ifdef CONFIG_KEYP ++ kfree_sensitive(((union key_payload *)(key->name_link.next))->data[0]); ++ #else + kfree_sensitive(key->payload.data[0]); + #endif + } - security_transfer_creds(new, old); + struct key_type key_type_trusted = { +diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c +index 749e2a4dcb13..a0a5e9ca620f 100644 +--- a/security/keys/user_defined.c ++++ b/security/keys/user_defined.c +@@ -14,6 +14,8 @@ + #include + #include "internal.h" + ++#include ++ + static int logon_vet_description(const char *desc); + + /* +@@ -109,7 +111,11 @@ int user_update(struct key *key, struct key_preparsed_payload *prep) + return ret; + /* attach the new data, displacing the old */ ++ #ifdef CONFIG_KEYP ++ iee_set_key_expiry(key, prep->expiry); ++ #else + key->expiry = prep->expiry; ++ #endif + if (key_is_positive(key)) + zap = dereference_key_locked(key); + rcu_assign_keypointer(key, prep->payload.data[0]); +@@ -145,7 +151,11 @@ EXPORT_SYMBOL(user_revoke); + */ + void user_destroy(struct key *key) + { ++ #ifdef CONFIG_KEYP ++ struct user_key_payload *upayload = ((union key_payload *)(key->name_link.next))->data[0]; ++ #else + struct user_key_payload *upayload = key->payload.data[0]; ++ #endif + + kfree_sensitive(upayload); + } diff --git a/security/security.c b/security/security.c -index 407b51719f79..74ffd7ea3f37 100644 +index b6144833c7a8..ca5d99847f77 100644 --- a/security/security.c +++ b/security/security.c @@ -30,6 +30,9 @@ @@ -13466,7 +20495,628 @@ index 407b51719f79..74ffd7ea3f37 100644 + #endif } + /** +diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c +index d4a99d98ec77..70e5ca8c80df 100644 +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -104,9 +104,22 @@ + #include "audit.h" + #include "avc_ss.h" + ++#ifdef CONFIG_IEE_SELINUX_P ++#include ++#include ++#endif ++ ++#ifdef CONFIG_KEYP ++#include ++#endif ++ + #define SELINUX_INODE_INIT_XATTRS 1 + ++#ifdef CONFIG_IEE_SELINUX_P ++struct selinux_state selinux_state __section(".iee.selinux"); ++#else + struct selinux_state selinux_state; ++#endif + + /* SECMARK reference count */ + static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0); +@@ -6585,7 +6598,11 @@ static int selinux_key_alloc(struct key *k, const struct cred *cred, + else + ksec->sid = tsec->sid; + ++ #ifdef CONFIG_KEYP ++ iee_set_key_security(k, ksec); ++ #else + k->security = ksec; ++ #endif + return 0; + } + +@@ -6593,7 +6610,11 @@ static void selinux_key_free(struct key *k) + { + struct key_security_struct *ksec = k->security; + ++ #ifdef CONFIG_KEYP ++ iee_set_key_security(k, NULL); ++ #else + k->security = NULL; ++ #endif + kfree(ksec); + } + +@@ -7284,15 +7305,54 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = { + #endif + }; + ++#ifdef CONFIG_IEE_SELINUX_P ++struct kmem_cache *policy_jar; ++ ++static void policy_cache_init(void) ++{ ++ struct selinux_policy* unused; ++ policy_jar = kmem_cache_create("policy_jar", sizeof(struct selinux_policy), 0, ++ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); ++ /* Test this cache */ ++ unused = kmem_cache_alloc(policy_jar, GFP_KERNEL); ++ kmem_cache_free(policy_jar, unused); ++ ++ printk("IEE SELINUXP: policy cache created."); ++} ++#endif ++ + static __init int selinux_init(void) + { + pr_info("SELinux: Initializing.\n"); + + memset(&selinux_state, 0, sizeof(selinux_state)); ++#ifdef CONFIG_IEE_SELINUX_P ++ WRITE_ONCE(selinux_state.enforcing, selinux_enforcing_boot); ++#else + enforcing_set(selinux_enforcing_boot); ++#endif + selinux_avc_init(); ++ ++#ifdef CONFIG_IEE_SELINUX_P ++ /* Put selinux_status inside IEE. */ ++ /* Prepare mutex lock and write the ptr to mutex->owner. */ ++ struct mutex* status_lock = kzalloc(GFP_KERNEL, sizeof(struct mutex)); ++ struct mutex* policy_mutex = kzalloc(GFP_KERNEL, sizeof(struct mutex)); ++ mutex_init(status_lock); ++ mutex_init(policy_mutex); ++ selinux_state.status_lock.owner.counter = (s64)status_lock; ++ selinux_state.policy_mutex.owner.counter = (s64)policy_mutex; ++ ++ /* Setting lm addr to be RO, IEE addr valid. */ ++ set_iee_page_valid(__phys_to_iee(__pa_symbol(&selinux_state))); ++ iee_set_logical_mem_ro((unsigned long)&selinux_state); ++ iee_set_logical_mem_ro((unsigned long)__va(__pa_symbol(&selinux_state))); ++ printk("IEE SELINUXP: Succeeded on preparing selinux_state."); ++ policy_cache_init(); ++#else + mutex_init(&selinux_state.status_lock); + mutex_init(&selinux_state.policy_mutex); ++#endif + + /* Set the security state for the initial task. */ + cred_init_security(); +diff --git a/security/selinux/ima.c b/security/selinux/ima.c +index aa34da9b0aeb..022b3ce8d740 100644 +--- a/security/selinux/ima.c ++++ b/security/selinux/ima.c +@@ -12,6 +12,10 @@ + #include "security.h" + #include "ima.h" + ++#ifdef CONFIG_IEE_SELINUX_P ++#include ++#endif ++ + /* + * selinux_ima_collect_state - Read selinux configuration settings + * +@@ -74,7 +78,11 @@ void selinux_ima_measure_state_locked(void) + size_t policy_len; + int rc = 0; + ++#ifdef CONFIG_IEE_SELINUX_P ++ lockdep_assert_held(iee_get_selinux_policy_lock()); ++#else + lockdep_assert_held(&selinux_state.policy_mutex); ++#endif + + state_str = selinux_ima_collect_state(); + if (!state_str) { +@@ -112,9 +120,21 @@ void selinux_ima_measure_state_locked(void) + */ + void selinux_ima_measure_state(void) + { ++#ifdef CONFIG_IEE_SELINUX_P ++ lockdep_assert_not_held(iee_get_selinux_policy_lock()); ++#else + lockdep_assert_not_held(&selinux_state.policy_mutex); ++#endif + ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_lock(iee_get_selinux_policy_lock()); ++#else + mutex_lock(&selinux_state.policy_mutex); ++#endif + selinux_ima_measure_state_locked(); ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_unlock(iee_get_selinux_policy_lock()); ++#else + mutex_unlock(&selinux_state.policy_mutex); ++#endif + } +diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h +index a9de89af8fdc..2eee89071a56 100644 +--- a/security/selinux/include/security.h ++++ b/security/selinux/include/security.h +@@ -113,11 +113,15 @@ static inline bool selinux_initialized(void) + return smp_load_acquire(&selinux_state.initialized); + } + ++#ifdef CONFIG_IEE_SELINUX_P ++extern void selinux_mark_initialized(void); ++#else + static inline void selinux_mark_initialized(void) + { + /* do a synchronized write to avoid race conditions */ + smp_store_release(&selinux_state.initialized, true); + } ++#endif + + #ifdef CONFIG_SECURITY_SELINUX_DEVELOP + static inline bool enforcing_enabled(void) +@@ -125,10 +129,14 @@ static inline bool enforcing_enabled(void) + return READ_ONCE(selinux_state.enforcing); + } + ++#ifdef CONFIG_IEE_SELINUX_P ++extern void enforcing_set(bool value); ++#else + static inline void enforcing_set(bool value) + { + WRITE_ONCE(selinux_state.enforcing, value); + } ++#endif + #else + static inline bool enforcing_enabled(void) + { +diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c +index 2c23a5a28608..f89b4fef4919 100644 +--- a/security/selinux/selinuxfs.c ++++ b/security/selinux/selinuxfs.c +@@ -43,6 +43,10 @@ + #include "conditional.h" + #include "ima.h" + ++#ifdef CONFIG_IEE_SELINUX_P ++#include ++#endif ++ + enum sel_inos { + SEL_ROOT_INO = 2, + SEL_LOAD, /* load policy */ +@@ -371,7 +375,11 @@ static int sel_open_policy(struct inode *inode, struct file *filp) + + BUG_ON(filp->private_data); + ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_lock(iee_get_selinux_policy_lock()); ++#else + mutex_lock(&selinux_state.policy_mutex); ++#endif + + rc = avc_has_perm(current_sid(), SECINITSID_SECURITY, + SECCLASS_SECURITY, SECURITY__READ_POLICY, NULL); +@@ -401,11 +409,19 @@ static int sel_open_policy(struct inode *inode, struct file *filp) + + filp->private_data = plm; + ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_unlock(iee_get_selinux_policy_lock()); ++#else + mutex_unlock(&selinux_state.policy_mutex); ++#endif + + return 0; + err: ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_unlock(iee_get_selinux_policy_lock()); ++#else + mutex_unlock(&selinux_state.policy_mutex); ++#endif + + if (plm) + vfree(plm->data); +@@ -587,7 +603,11 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, + ssize_t length; + void *data = NULL; + ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_lock(iee_get_selinux_policy_lock()); ++#else + mutex_lock(&selinux_state.policy_mutex); ++#endif + + length = avc_has_perm(current_sid(), SECINITSID_SECURITY, + SECCLASS_SECURITY, SECURITY__LOAD_POLICY, NULL); +@@ -630,13 +650,31 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, + from_kuid(&init_user_ns, audit_get_loginuid(current)), + audit_get_sessionid(current)); + out: ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_unlock(iee_get_selinux_policy_lock()); ++#else + mutex_unlock(&selinux_state.policy_mutex); ++#endif + vfree(data); + return length; + } + ++// #ifdef CONFIG_IEE_SELINUX_P ++// /* Do sel_write_load twice to test free process of policy. */ ++// static ssize_t sel_write_load_test(struct file *file, const char __user *buf, ++// size_t count, loff_t *ppos) ++// { ++// sel_write_load(file, buf, count, ppos); ++// return sel_write_load(file, buf, count, ppos); ++// } ++// #endif ++ + static const struct file_operations sel_load_ops = { ++// #ifdef CONFIG_IEE_SELINUX_P ++// .write = sel_write_load_test, ++// #else + .write = sel_write_load, ++// #endif + .llseek = generic_file_llseek, + }; + +@@ -1214,7 +1252,11 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf, + unsigned index = file_inode(filep)->i_ino & SEL_INO_MASK; + const char *name = filep->f_path.dentry->d_name.name; + ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_lock(iee_get_selinux_policy_lock()); ++#else + mutex_lock(&selinux_state.policy_mutex); ++#endif + + ret = -EINVAL; + if (index >= fsi->bool_num || strcmp(name, +@@ -1233,14 +1275,22 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf, + } + length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing, + fsi->bool_pending_values[index]); ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_unlock(iee_get_selinux_policy_lock()); ++#else + mutex_unlock(&selinux_state.policy_mutex); ++#endif + ret = simple_read_from_buffer(buf, count, ppos, page, length); + out_free: + free_page((unsigned long)page); + return ret; + + out_unlock: ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_unlock(iee_get_selinux_policy_lock()); ++#else + mutex_unlock(&selinux_state.policy_mutex); ++#endif + goto out_free; + } + +@@ -1265,7 +1315,11 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf, + if (IS_ERR(page)) + return PTR_ERR(page); + ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_lock(iee_get_selinux_policy_lock()); ++#else + mutex_lock(&selinux_state.policy_mutex); ++#endif + + length = avc_has_perm(current_sid(), SECINITSID_SECURITY, + SECCLASS_SECURITY, SECURITY__SETBOOL, +@@ -1289,7 +1343,11 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf, + length = count; + + out: ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_unlock(iee_get_selinux_policy_lock()); ++#else + mutex_unlock(&selinux_state.policy_mutex); ++#endif + kfree(page); + return length; + } +@@ -1320,7 +1378,11 @@ static ssize_t sel_commit_bools_write(struct file *filep, + if (IS_ERR(page)) + return PTR_ERR(page); + ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_lock(iee_get_selinux_policy_lock()); ++#else + mutex_lock(&selinux_state.policy_mutex); ++#endif + + length = avc_has_perm(current_sid(), SECINITSID_SECURITY, + SECCLASS_SECURITY, SECURITY__SETBOOL, +@@ -1341,7 +1403,11 @@ static ssize_t sel_commit_bools_write(struct file *filep, + length = count; + + out: ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_unlock(iee_get_selinux_policy_lock()); ++#else + mutex_unlock(&selinux_state.policy_mutex); ++#endif + kfree(page); + return length; + } +diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c +index 379ac7b5c709..6d5cb766116a 100644 +--- a/security/selinux/ss/services.c ++++ b/security/selinux/ss/services.c +@@ -68,6 +68,10 @@ + #include "policycap_names.h" + #include "ima.h" + ++#ifdef CONFIG_IEE_SELINUX_P ++#include ++#endif ++ + struct selinux_policy_convert_data { + struct convert_context_args args; + struct sidtab_convert_params sidtab_params; +@@ -2108,9 +2112,14 @@ static void security_load_policycaps(struct selinux_policy *policy) + + p = &policy->policydb; + ++#ifdef CONFIG_IEE_SELINUX_P ++ for (i = 0; i < ARRAY_SIZE(selinux_state.policycap); i++) ++ iee_set_sel_policy_cap(i, ebitmap_get_bit(&p->policycaps, i)); ++#else + for (i = 0; i < ARRAY_SIZE(selinux_state.policycap); i++) + WRITE_ONCE(selinux_state.policycap[i], + ebitmap_get_bit(&p->policycaps, i)); ++#endif + + for (i = 0; i < ARRAY_SIZE(selinux_policycap_names); i++) + pr_info("SELinux: policy capability %s=%d\n", +@@ -2173,6 +2182,9 @@ void selinux_policy_commit(struct selinux_load_state *load_state) + { + struct selinux_state *state = &selinux_state; + struct selinux_policy *oldpolicy, *newpolicy = load_state->policy; ++#ifdef CONFIG_IEE_SELINUX_P ++ struct selinux_policy *temppolicy; ++#endif + unsigned long flags; + u32 seqno; + +@@ -2197,10 +2209,20 @@ void selinux_policy_commit(struct selinux_load_state *load_state) + /* Install the new policy. */ + if (oldpolicy) { + sidtab_freeze_begin(oldpolicy->sidtab, &flags); ++#ifdef CONFIG_IEE_SELINUX_P ++ iee_sel_rcu_assign_policy(newpolicy, kmem_cache_alloc(policy_jar, GFP_KERNEL)); ++ kfree(newpolicy); ++#else + rcu_assign_pointer(state->policy, newpolicy); ++#endif + sidtab_freeze_end(oldpolicy->sidtab, &flags); + } else { ++#ifdef CONFIG_IEE_SELINUX_P ++ iee_sel_rcu_assign_policy(newpolicy, kmem_cache_alloc(policy_jar, GFP_KERNEL)); ++ kfree(newpolicy); ++#else + rcu_assign_pointer(state->policy, newpolicy); ++#endif + } + + /* Load the policycaps from the new policy */ +@@ -2218,7 +2240,20 @@ void selinux_policy_commit(struct selinux_load_state *load_state) + + /* Free the old policy */ + synchronize_rcu(); ++#ifdef CONFIG_IEE_SELINUX_P ++ /* ++ * Normal free process includes setting freed objects pointers to be NULL, however it ++ * would be hard as old policy is already inside IEE. So Make a kernel copy of the old ++ * policy to free objects it points to. ++ */ ++ if (oldpolicy){ ++ temppolicy = kmemdup(oldpolicy, sizeof(*temppolicy), GFP_KERNEL); ++ selinux_policy_free(temppolicy); ++ kfree(oldpolicy); ++ } ++#else + selinux_policy_free(oldpolicy); ++#endif + kfree(load_state->convert_data); + + /* Notify others of the policy change */ +@@ -3016,6 +3051,9 @@ int security_set_bools(u32 len, int *values) + { + struct selinux_state *state = &selinux_state; + struct selinux_policy *newpolicy, *oldpolicy; ++#ifdef CONFIG_IEE_SELINUX_P ++ struct selinux_policy *temppolicy; ++#endif + int rc; + u32 i, seqno = 0; + +@@ -3068,8 +3106,13 @@ int security_set_bools(u32 len, int *values) + newpolicy->latest_granting = oldpolicy->latest_granting + 1; + seqno = newpolicy->latest_granting; + ++#ifdef CONFIG_IEE_SELINUX_P ++ iee_sel_rcu_assign_policy(newpolicy, kmem_cache_alloc(policy_jar, GFP_KERNEL)); ++ kfree(newpolicy); ++#else + /* Install the new policy */ + rcu_assign_pointer(state->policy, newpolicy); ++#endif + + /* + * Free the conditional portions of the old policydb +@@ -3077,7 +3120,20 @@ int security_set_bools(u32 len, int *values) + * structure itself but not what it references. + */ + synchronize_rcu(); ++#ifdef CONFIG_IEE_SELINUX_P ++ /* ++ * Normal free process includes setting freed objects pointers to be NULL, however it ++ * would be hard as old policy is already inside IEE. So Make a kernel copy of the old ++ * policy to free objects it points to. ++ */ ++ temppolicy = kmemdup(oldpolicy, sizeof(*temppolicy), GFP_KERNEL); ++ if (!temppolicy) ++ return -ENOMEM; ++ selinux_policy_cond_free(temppolicy); ++ kfree(oldpolicy); ++#else + selinux_policy_cond_free(oldpolicy); ++#endif + + /* Notify others of the policy change */ + selinux_notify_policy_change(seqno); +diff --git a/security/selinux/status.c b/security/selinux/status.c +index dffca22ce6f7..642965684325 100644 +--- a/security/selinux/status.c ++++ b/security/selinux/status.c +@@ -13,6 +13,10 @@ + #include "avc.h" + #include "security.h" + ++#ifdef CONFIG_IEE_SELINUX_P ++#include ++#endif ++ + /* + * The selinux_status_page shall be exposed to userspace applications + * using mmap interface on /selinux/status. +@@ -44,9 +48,17 @@ struct page *selinux_kernel_status_page(void) + struct selinux_kernel_status *status; + struct page *result = NULL; + ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_lock(iee_get_selinux_status_lock()); ++#else + mutex_lock(&selinux_state.status_lock); ++#endif + if (!selinux_state.status_page) { ++ #ifdef CONFIG_IEE_SELINUX_P ++ iee_set_selinux_status_pg(alloc_page(GFP_KERNEL|__GFP_ZERO)); ++ #else + selinux_state.status_page = alloc_page(GFP_KERNEL|__GFP_ZERO); ++ #endif + + if (selinux_state.status_page) { + status = page_address(selinux_state.status_page); +@@ -66,7 +78,11 @@ struct page *selinux_kernel_status_page(void) + } + } + result = selinux_state.status_page; ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_unlock(iee_get_selinux_status_lock()); ++#else + mutex_unlock(&selinux_state.status_lock); ++#endif + + return result; + } +@@ -80,7 +96,11 @@ void selinux_status_update_setenforce(bool enforcing) + { + struct selinux_kernel_status *status; + ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_lock(iee_get_selinux_status_lock()); ++#else + mutex_lock(&selinux_state.status_lock); ++#endif + if (selinux_state.status_page) { + status = page_address(selinux_state.status_page); + +@@ -92,7 +112,11 @@ void selinux_status_update_setenforce(bool enforcing) + smp_wmb(); + status->sequence++; + } ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_unlock(iee_get_selinux_status_lock()); ++#else + mutex_unlock(&selinux_state.status_lock); ++#endif + } + + /* +@@ -105,7 +129,11 @@ void selinux_status_update_policyload(u32 seqno) + { + struct selinux_kernel_status *status; + ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_lock(iee_get_selinux_status_lock()); ++#else + mutex_lock(&selinux_state.status_lock); ++#endif + if (selinux_state.status_page) { + status = page_address(selinux_state.status_page); + +@@ -118,5 +146,9 @@ void selinux_status_update_policyload(u32 seqno) + smp_wmb(); + status->sequence++; + } ++#ifdef CONFIG_IEE_SELINUX_P ++ mutex_unlock(iee_get_selinux_status_lock()); ++#else + mutex_unlock(&selinux_state.status_lock); ++#endif + } +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 4625674f0e95..cbd843db9d41 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -45,6 +45,10 @@ + #include + #include "smack.h" + ++#ifdef CONFIG_KEYP ++#include ++#endif ++ + #define TRANS_TRUE "TRUE" + #define TRANS_TRUE_SIZE 4 + +@@ -4411,7 +4415,11 @@ static int smack_key_alloc(struct key *key, const struct cred *cred, + { + struct smack_known *skp = smk_of_task(smack_cred(cred)); + ++ #ifdef CONFIG_KEYP ++ iee_set_key_security(key, skp); ++ #else + key->security = skp; ++ #endif + return 0; + } + +@@ -4423,7 +4431,11 @@ static int smack_key_alloc(struct key *key, const struct cred *cred, + */ + static void smack_key_free(struct key *key) + { ++ #ifdef CONFIG_KEYP ++ iee_set_key_security(key, NULL); ++ #else + key->security = NULL; ++ #endif + } + /** -- -2.34.1 +2.43.0 diff --git a/haoc-kernel.spec b/haoc-kernel.spec index 27d305c..48c9a65 100644 --- a/haoc-kernel.spec +++ b/haoc-kernel.spec @@ -1,4 +1,4 @@ -%define with_signmodules 1 +%define with_signmodules 0 %define with_kabichk 0 # Default without toolchain_clang @@ -40,9 +40,9 @@ rm -f test_openEuler_sign.ko test_openEuler_sign.ko.sig %global upstream_version 6.6 %global upstream_sublevel 0 -%global devel_release 27 +%global devel_release 50 %global maintenance_release .0.0 -%global pkg_release .32 +%global pkg_release .56 %global openeuler_lts 1 %global openeuler_major 2403 @@ -88,7 +88,7 @@ rm -f test_openEuler_sign.ko test_openEuler_sign.ko.sig %define with_perf %{?_without_perf: 0} %{?!_without_perf: 1} Name: haoc-kernel -Version: 6.6.0 +Version: %{upstream_version}.%{upstream_sublevel} Release: %{devel_release}%{?maintenance_release}%{?pkg_release} Summary: Linux Kernel License: GPLv2 @@ -356,7 +356,6 @@ Applypatches() Applypatches series.conf %{_builddir}/kernel-%{version}/linux-%{KernelVer} %endif -# haoc-kernel patch %patch0005 -p1 # riscv-kernel patch @@ -388,6 +387,10 @@ cp -a tools/perf tools/python3-perf %build cd linux-%{KernelVer} +# Workaround for flask.h and av_permissions.h +gcc scripts/selinux/genheaders/genheaders.c -o scripts/selinux/genheaders/genheaders -Iinclude/uapi -Iinclude -Isecurity/selinux/include +scripts/selinux/genheaders/genheaders security/selinux/flask.h security/selinux/av_permissions.h + perl -p -i -e "s/^EXTRAVERSION.*/EXTRAVERSION = -%{release}.%{_target_cpu}/" Makefile perl -p -i -e "s/^OPENEULER_LTS.*/OPENEULER_LTS = %{openeuler_lts}/" Makefile.oever perl -p -i -e "s/^OPENEULER_MAJOR.*/OPENEULER_MAJOR = %{openeuler_major}/" Makefile.oever @@ -713,6 +716,12 @@ find $RPM_BUILD_ROOT/usr/include -name "\.*" -exec rm -rf {} \; rm -f $(find arch/$Arch/boot -name "*.dtb") %endif +# deal with riscv SoC dtb search path +%ifarch riscv64 + mkdir -p $RPM_BUILD_ROOT/boot/dtb-%{KernelVer}/thead + mv $(find $RPM_BUILD_ROOT/boot/dtb-%{KernelVer}/ -name "th1520*.dtb") $RPM_BUILD_ROOT/boot/dtb-%{KernelVer}/thead +%endif + # deal with vdso %ifnarch ppc64le %{make} -s ARCH=%{Arch} INSTALL_MOD_PATH=$RPM_BUILD_ROOT vdso_install KERNELRELEASE=%{KernelVer} @@ -1083,8 +1092,6902 @@ fi %endif %changelog -* Thu May 23 2024 Liu Zhehui - 6.6.0-27.0.0.32 -- update HAOC patch and spec for 6.6.0-27.0.0 +* Thu Nov 7 2024 Liu Zhehui - 6.6.0-50.0.0.56 +- add some optimization, update haoc to 6.6.0-50.0.0 +* Wed Nov 06 2024 ZhangPeng - 6.6.0-50.0.0.55 +- !12979 ext4: fix timer use-after-free on failed mount +- ext4: fix timer use-after-free on failed mount +- !12980 ext4: no need to continue when the number of entries is 1 +- ext4: no need to continue when the number of entries is 1 +- !12983 CVE-2024-49968 +- ext4: fix error message when rejecting the default hash +- ext4: filesystems without casefold feature cannot be mounted with siphash +- !12981 ext4: drop ppath from ext4_ext_replay_update_ex() to avoid double-free +- ext4: drop ppath from ext4_ext_replay_update_ex() to avoid double-free +- !12982 ext4: fix i_data_sem unlock order in ext4_ind_migrate() +- ext4: fix i_data_sem unlock order in ext4_ind_migrate() +- !12978 exfat: fix memory leak in exfat_load_bitmap() +- exfat: fix memory leak in exfat_load_bitmap() +- !12977 ext4: fix access to uninitialised lock in fc replay path +- ext4: fix access to uninitialised lock in fc replay path +- !13018 nebula-matrix: fix ci build warning when use clang +- Net: nebula_matrix: fix ci build warning +- !12866 fix CVE-2024-50041 +- i40e: Fix macvlan leak by synchronizing access to mac_filter_hash +- !12595 scsi: fnic: Move flush_work initialization out of if block +- scsi: fnic: Move flush_work initialization out of if block +- !13004 CVE-2024-50064 +- zram: don't free statically defined names +- zram: free secondary algorithms names +- !13044 Some patches of RDMA/hns from Linux to OLK-6.6 +- RDMA/hns: Fix cpu stuck caused by printings during reset +- RDMA/hns: Use dev_* printings in hem code instead of ibdev_* +- RDMA/hns: Modify debugfs name +- RDMA/hns: Fix flush cqe error when racing with destroy qp +- RDMA/hns: Fix an AEQE overflow error caused by untimely update of eq_db_ci +- Revert "RDMA/hns: Fix flush cqe error when racing with destroy qp" +- Revert "RDMA/hns: Fix missing spin_lock_init() for qp flush lock" +- !13049 ext4: some dependencies of CVE-2024-47701 +- ext4: explicitly exit when ext4_find_inline_entry returns an error +- ext4: ext4_search_dir should return a proper error +- !12682 smb: client: fix UAF in async decryption +- smb: client: fix UAF in async decryption +- !13023 l2tp: prevent possible tunnel refcount underflow +- l2tp: prevent possible tunnel refcount underflow +- !13025 wifi: mwifiex: Fix memcpy() field-spanning write warning in mwifiex_cmd_802_11_scan_ext() +- wifi: mwifiex: Fix memcpy() field-spanning write warning in mwifiex_cmd_802_11_scan_ext() +- !13024 wifi: cfg80211: Set correct chandef when starting CAC +- wifi: cfg80211: Set correct chandef when starting CAC +- !12993 igb: Do not bring the device up after non-fatal error +- igb: Do not bring the device up after non-fatal error +- !12988 mm/mremap: fix move_normal_pmd/retract_page_tables race +- mm/mremap: fix move_normal_pmd/retract_page_tables race +- !12800 cachefiles: fix dentry leak in cachefiles_open_file() +- cachefiles: fix dentry leak in cachefiles_open_file() +- !12900 ext4: fix double brelse() the buffer of the extents path +- ext4: fix double brelse() the buffer of the extents path +- !12896 ext4: aovid use-after-free in ext4_ext_insert_extent() +- ext4: aovid use-after-free in ext4_ext_insert_extent() +- !12960 ext4: update orig_path in ext4_find_extent() +- ext4: update orig_path in ext4_find_extent() +- !13012 drm/amd/display: Revert "drm/amd/display: Fix potential index out of bounds in color transformation function" +- drm/amd/display: Revert "drm/amd/display: Fix potential index out of bounds in color transformation function" +- !12909 btrfs: fix uninitialized pointer free on read_alloc_one_name() error +- btrfs: fix uninitialized pointer free on read_alloc_one_name() error +- !12906 io_uring: fix CVE-2024-50060 +- io_uring: check if we need to reschedule during overflow flush +- io_uring: always lock __io_cqring_overflow_flush +- !12892 ext4: avoid use-after-free in ext4_ext_show_leaf() +- ext4: avoid use-after-free in ext4_ext_show_leaf() +- !12957 rseq/mm_cid: change the mm_cid macro default status and keep KABI consistent +- rseq/mm_cid: change the mm_cid macro default status and keep KABI consistent +- !12377 ep93xx: clock: Fix off by one in ep93xx_div_recalc_rate() +- ep93xx: clock: Fix off by one in ep93xx_div_recalc_rate() +- !12497 drm/stm: Avoid use-after-free issues with crtc and plane +- drm/stm: Avoid use-after-free issues with crtc and plane +- !12775 vt: prevent kernel-infoleak in con_font_get() +- vt: prevent kernel-infoleak in con_font_get() +- !12883 CVE-2024-50016 +- drm/amd/display: Avoid overflow assignment in link_dp_cts +- !12774 net: microchip: vcap api: Fix memory leaks in vcap_api_encode_rule_test() +- net: microchip: vcap api: Fix memory leaks in vcap_api_encode_rule_test() +- !12776 drm/amd/display: Check stream before comparing them +- drm/amd/display: Check stream before comparing them +- !12940 virtCCA feature: GPU supports maximum 1G page table mapping +- virtcca feature : GPU supports maximum 1G page table mapping. +- !12952 drm/amd/display: Add null check for top_pipe_to_program in commit_planes_for_stream +- drm/amd/display: Add null check for top_pipe_to_program in commit_planes_for_stream +- !12942 fix CVE-2024-47704 +- drm/amd/display: Check link_res->hpo_dp_link_enc before using it +- drm/amd/display: Check link_res->hpo_dp_link_enc before using it +- !12953 mm: gup: stop abusing try_grab_folio +- mm: gup: stop abusing try_grab_folio +- !9209 [OLK-6.6] perf/x86/zhaoxin/uncore: update KX-7000 support +- perf/x86/zhaoxin/uncore: update KX-7000 support +- !9191 [OLK-6.6] x86/cpu: Remove pointless evaluation of x86_coreid_bits +- x86/cpu: Remove pointless evaluation of x86_coreid_bits +- !9156 [OLK-6.6] USB: Fix kernel NULL pointer when unbind UHCI form vfio-pci +- USB:Fix kernel NULL pointer when unbind UHCI form vfio-pci +- !7927 [OLK-6.6] fix intel-lkp compilation issues for DMA patch +- x86/cpu/zhaoxin: kx-40000: Apply the static modifier to some symbols +- x86/cpu/zhaoxin: Encapsulate access to kh40000_dma_direct_ops within function +- x86/cpu/zhaoxin: Encapsulate access to global variables within functions +- x86/cpu/zhaoxin: Adjust the configuration options for zhaoxin-kx40000.c +- x86/cpu/zhaoxin: kx40000: fix bitwise warning issue +- !7874 [OLK-6.6] iommu/dma: Move iova_reserve_domain_addr to header dma-iommu.h +- iommu/dma: Move iova_reserve_domain_addr to header dma-iommu.h +- !12835 Net: nebula-matrix: fix ci build warning +- Net: nebula_matrix: fix ci build warning +- !12550 fs/inode: Prevent dump_mapping() accessing invalid dentry.d_name.name +- fs/inode: Prevent dump_mapping() accessing invalid dentry.d_name.name +- !12871 Fix CVE-2024-47703 +- selftests/bpf: Add return value checks for failed tests +- bpf: Fix kabi breakage in struct bpf_insn_access_aux +- bpf: Fix kabi breakage in struct bpf_func_state +- bpf: Fix compare error in function retval_range_within +- bpf, lsm: Add check for BPF LSM return value +- bpf, lsm: Add disabled BPF LSM hook list +- bpf: enforce precise retval range on program exit +- bpf: enforce exact retval range on subprog/callback exit +- !12712 drm: omapdrm: Add missing check for alloc_ordered_workqueue +- drm: omapdrm: Add missing check for alloc_ordered_workqueue +- !12838 ocfs2: reserve space for inline xattr before attaching reflink tree +- ocfs2: reserve space for inline xattr before attaching reflink tree +- !12372 fix CVE-2024-49954 +- static_call: Replace pointless WARN_ON() in static_call_module_notify() +- !12358 fix CVE-2024-49852 +- scsi: elx: libefc: Fix potential use after free in efc_nport_vport_del() +- !12822 i3c: master: svc: Fix use after free vulnerability in svc_i3c_master Driver Due to Race Condition +- i3c: master: svc: Fix use after free vulnerability in svc_i3c_master Driver Due to Race Condition +- !12918 Input: adp5589-keys - fix NULL pointer dereference +- Input: adp5589-keys - fix NULL pointer dereference +- !12874 tipc: guard against string buffer overrun +- tipc: guard against string buffer overrun +- !12916 serial: protect uart_port_dtr_rts() in uart_shutdown() too +- serial: protect uart_port_dtr_rts() in uart_shutdown() too +- !12843 v4 CVE-2024-50063 +- selftests/bpf: Add test for lsm tail call +- bpf: Fix kabi breakage in struct bpf_map +- bpf: Prevent tail call between progs attached to different hooks +- !12932 gso: fix udp gso fraglist segmentation after pull from frag_list +- gso: fix udp gso fraglist segmentation after pull from frag_list +- !12933 tcp: fix mptcp DSS corruption due to large pmtu xmit +- tcp: fix mptcp DSS corruption due to large pmtu xmit +- !12922 ocfs2: fix possible null-ptr-deref in ocfs2_set_buffer_uptodate +- ocfs2: fix possible null-ptr-deref in ocfs2_set_buffer_uptodate +- !12913 drm/msm/adreno: Assign msm_gpu->pdev earlier to avoid nullptrs +- drm/msm/adreno: Assign msm_gpu->pdev earlier to avoid nullptrs +- !12888 drm/amd/display: Add NULL check for clk_mgr and clk_mgr->funcs in dcn30_init_hw +- drm/amd/display: Add NULL check for clk_mgr and clk_mgr->funcs in dcn30_init_hw +- !12769 uprobes: fix kernel info leak via "[uprobes +- uprobes: fix kernel info leak via "[uprobes]" vma +- !12717 wifi: ath12k: fix array out-of-bound access in SoC stats +- wifi: ath12k: fix array out-of-bound access in SoC stats +- !12742 net/xen-netback: prevent UAF in xenvif_flush_hash() +- net/xen-netback: prevent UAF in xenvif_flush_hash() +- !12738 r8169: add tally counter fields added with RTL8125 +- r8169: add tally counter fields added with RTL8125 +- !12805 ext4: fix slab-use-after-free in ext4_split_extent_at() +- ext4: fix slab-use-after-free in ext4_split_extent_at() +- !12637 kthread: unpark only parked kthread +- kthread: unpark only parked kthread +- !12473 scsi: wd33c93: Don't use stale scsi_pointer value +- scsi: wd33c93: Don't use stale scsi_pointer value +- !12688 security/keys: fix slab-out-of-bounds in key_task_permission +- security/keys: fix slab-out-of-bounds in key_task_permission +- !12791 slip: make slhc_remember() more robust against malicious packets +- slip: make slhc_remember() more robust against malicious packets +- !12607 virtcca compile warning clean and coda bugfix +- virtcca bugfix: compile warning clean +- virtcca bugfix: clear device msi address +- virtcca bugfix: compile warning clean +- !12773 v4 add vdpa support for x86 and enable vdpa migration. +- vdpa: add support for x86 and open vdpa migration build config +- virtio_blk: remove the broken zone revalidation support +- !12759 CVE-2024-50055 +- driver core: bus: Fix double free in driver API bus_register() +- !12772 MPTCP Upstream part 16 +- selftests: mptcp: diag: avoid extra waiting +- configs/debug: add NET debug config +- MAINTAINERS: update Geliang's email address +- !12771 MPTCP Upstream part 15 +- selftests: mptcp: diag: change timeout_poll to 30 +- selftests: mptcp: join: change capture/checksum as bool +- selftests: mptcp: simult flows: define missing vars +- selftests: mptcp: netlink: drop duplicate var ret +- !12834 [OLK-6.6] drivers: load Yunsilicon ethernet driver when xsc_pci probing +- drivers: load Yunsilicon ethernet driver when xsc_pci probing +- !12817 media: venus: fix use after free bug in venus_remove due to race condition +- media: venus: fix use after free bug in venus_remove due to race condition +- !12599 iommufd: Require drivers to supply the cache_invalidate_user ops +- iommufd: Require drivers to supply the cache_invalidate_user ops +- !12793 uprobe: avoid out-of-bounds memory access of fetching args +- uprobe: avoid out-of-bounds memory access of fetching args +- !12821 v4 openeuler_defconfig: Disable CONFIG_DEBUG_INFO_BTF_MODULES +- openeuler_defconfig: Disable CONFIG_DEBUG_INFO_BTF_MODULES +- !12829 drm/amd/display: Check null-initialized variables +- drm/amd/display: Check null-initialized variables +- !12826 media: i2c: ar0521: Use cansleep version of gpiod_set_value() +- media: i2c: ar0521: Use cansleep version of gpiod_set_value() +- !12827 drm/amd/display: Check null pointers before using them +- drm/amd/display: Check null pointers before using them +- !12767 x86/bugs: Use code segment selector for VERW operand +- x86/bugs: Use code segment selector for VERW operand +- !12506 ocfs2: cancel dqi_sync_work before freeing oinfo +- ocfs2: cancel dqi_sync_work before freeing oinfo +- !12482 device-dax: correct pgoff align in dax_set_mapping() +- device-dax: correct pgoff align in dax_set_mapping() +- !12795 platform/x86: ISST: Fix the KASAN report slab-out-of-bounds bug +- platform/x86: ISST: Fix the KASAN report slab-out-of-bounds bug +- !12816 v2 bpf lts backport +- Fix kabi breakage in struct bpf_map +- bpf: Optimize the free of inner map +- !12747 parport: Proper fix for array out-of-bounds access +- parport: Proper fix for array out-of-bounds access +- !12780 drivers: misc: uacce: bugfix for MAX_ORDER +- drivers: misc: uacce: bugfix for MAX_ORDER +- !12718 thermal: core: Reference count the zone in thermal_zone_get_by_id() +- thermal: core: Reference count the zone in thermal_zone_get_by_id() +- !12707 drm/amd/display: Add NULL check for function pointer in dcn32_set_output_transfer_func +- drm/amd/display: Add NULL check for function pointer in dcn32_set_output_transfer_func +- !12768 Bluetooth: hci_conn: Fix UAF in hci_enhanced_setup_sync +- Bluetooth: hci_conn: Fix UAF in hci_enhanced_setup_sync +- !12674 net/mlx5e: Fix NULL deref in mlx5e_tir_builder_alloc() +- net/mlx5e: Fix NULL deref in mlx5e_tir_builder_alloc() +- !12736 drm/amd/display: Fix system hang while resume with TBT monitor +- drm/amd/display: Fix system hang while resume with TBT monitor +- !12604 drm/amd/display: Check null pointer before dereferencing se +- drm/amd/display: Check null pointer before dereferencing se +- !12591 cpufreq: amd-pstate: add check for cpufreq_cpu_get's return value +- cpufreq: amd-pstate: add check for cpufreq_cpu_get's return value +- !12465 drm/amd/display: Initialize get_bytes_per_element's default to 1 +- drm/amd/display: Initialize get_bytes_per_element's default to 1 +- !12755 pinctrl: stm32: check devm_kasprintf() returned value +- pinctrl: stm32: check devm_kasprintf() returned value +- !12715 MPTCP Upstream part 14 +- mptcp: check the protocol in mptcp_sk() with DEBUG_NET +- mptcp: check the protocol in tcp_sk() with DEBUG_NET +- mptcp: token kunit: set protocol +- !12711 btrfs: fix uninitialized pointer free in add_inode_ref() +- btrfs: fix uninitialized pointer free in add_inode_ref() +- !12728 Backport "ima: Avoid blocking in RCU read-side critical section" +- ima: Avoid blocking in RCU read-side critical section +- Revert "ima: Avoid blocking in RCU read-side critical section" +- !12516 fix CVE-2024-47742 +- firmware_loader: Block path traversal +- !12710 fix CVE-2024-49924 +- fbdev: pxafb: Fix possible use after free in pxafb_task() +- !12729 CVE-2024-50059 +- ntb: ntb_hw_switchtec: Fix use after free vulnerability in switchtec_ntb_remove due to race condition +- !12720 drivers/crypto/ccp: fix a build error +- drivers/crypto/ccp: fix a build error +- !12666 block: fix integer overflow in BLKSECDISCARD +- block: fix integer overflow in BLKSECDISCARD +- !12608 blk_iocost: fix more out of bound shifts +- blk_iocost: fix more out of bound shifts +- !12656 CVE-2024-49955 +- ACPI: battery: Fix possible crash when unregistering a battery hook +- ACPI: battery: Simplify battery hook locking +- !12662 drm/amd/display: fix double free issue during amdgpu module unload +- drm/amd/display: fix double free issue during amdgpu module unload +- !12698 mm: memcg: don't periodically flush stats when memcg is disabled +- mm: writeback: ratelimit stat flush from mem_cgroup_wb_stats +- mm: memcg: don't periodically flush stats when memcg is disabled +- !12345 [OLK-6.6] drivers: update Yunsilicon driver to version rel_2406_rc16 +- drivers: update Yunsilicon driver to version 2406_rc16 +- !12617 drm/amd/display: Handle null 'stream_status' in 'planes_changed_for_existing_stream' +- drm/amd/display: Handle null 'stream_status' in 'planes_changed_for_existing_stream' +- !12545 Fix TX fifo corruption in patch [3 +- serial: sc16is7xx: fix TX fifo corruption +- kfifo: add kfifo_out_linear{,_ptr}() +- serial: sc16is7xx: refactor FIFO access functions to increase commonality +- !12648 net: do not delay dst_entries_add() in dst_release() +- net: do not delay dst_entries_add() in dst_release() +- !12553 Fix CVE-2024-49996 +- cifs: Fix buffer overflow when parsing NFS reparse points +- smb: client: fix parsing of device numbers + +* Wed Oct 30 2024 jchzhou - 6.6.0-48.0.0.54 +- create & package symvers-kernelver.gz unconditionally to fix ISO installation +faliures like in issue #I7MARC + +* Wed Oct 30 2024 ZhangPeng - 6.6.0-48.0.0.53 +- !12565 KEYS: prevent NULL pointer dereference in find_asymmetric_key() +- KEYS: prevent NULL pointer dereference in find_asymmetric_key() +- !12498 nbd: fix race between timeout and normal completion +- nbd: fix race between timeout and normal completion +- !10861 [OLK-6.6] perf/x86/uncore: Add support for Hygon family 18h model 4h-7h and 10h DF PMU +- perf/x86/uncore: Add DF PMU support for Hygon family 18h model 4h-7h and 10h +- !12673 ocfs2: remove unreasonable unlock in ocfs2_read_blocks +- ocfs2: remove unreasonable unlock in ocfs2_read_blocks +- !12653 usb: typec: tipd: Free IRQ only if it was requested before +- usb: typec: tipd: Free IRQ only if it was requested before +- !12632 ALSA: asihpi: Fix potential OOB array access +- ALSA: asihpi: Fix potential OOB array access +- !12635 bpf: lsm: Set bpf_lsm_blob_sizes.lbs_task to 0 +- bpf: lsm: Set bpf_lsm_blob_sizes.lbs_task to 0 +- !12491 LoongArch: fix some 3C6000&LS7A related problems +- LoongArch: Add workaround for 3C6000 about io wr/rd +- Loongarch: Dynamic enable writecombine +- acpi: mcfg quirk: Increased multi-chip support for the 3C6000 +- pci/quirks: LS7A2000 enable msi +- !12331 LoongArch: prevent LS7A Bus Master clearing on kexec +- LoongArch: prevent LS7A Bus Master clearing on kexec +- !12321 LoongArch: backport 3 patches from upstream +- LoongArch: Define __ARCH_WANT_NEW_STAT in unistd.h +- LoongArch: Add writecombine support for DMW-based ioremap() +- LoongArch: Change SHMLBA from SZ_64K to PAGE_SIZE +- !12557 ntfs3: Change to non-blocking allocation in ntfs_d_hash +- ntfs3: Change to non-blocking allocation in ntfs_d_hash +- !12554 NFSv4: Prevent NULL-pointer dereference in nfs42_complete_copies() +- NFSv4: Prevent NULL-pointer dereference in nfs42_complete_copies() +- !12444 nilfs2: fix potential oob read in nilfs_btree_check_delete() +- nilfs2: fix potential oob read in nilfs_btree_check_delete() +- !12631 some bugfixs for khuegpaged +- mm: khugepaged: fix the incorrect statistics when collapsing large file folios +- mm: khugepaged: fix the arguments order in khugepaged_collapse_file trace point +- selftests: mm: support shmem mTHP collapse testing +- mm: khugepaged: support shmem mTHP collapse +- mm: khugepaged: support shmem mTHP copy +- mm: khugepaged: use the number of pages in the folio to check the reference count +- mm: khugepaged: expand the is_refcount_suitable() to support file folios +- khugepaged: use a folio throughout hpage_collapse_scan_file() +- khugepaged: use a folio throughout collapse_file() +- khugepaged: remove hpage from collapse_file() +- khugepaged: pass a folio to __collapse_huge_page_copy() +- khugepaged: remove hpage from collapse_huge_page() +- khugepaged: convert alloc_charge_hpage to alloc_charge_folio +- khugepaged: inline hpage_collapse_alloc_folio() +- !12634 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.53-6.6.54 LTS Patches +- Revert: "dm-verity: restart or panic on an I/O error" +- spi: atmel-quadspi: Fix wrong register value written to MR +- x86/tdx: Fix "in-kernel MMIO" check +- thunderbolt: Fix NULL pointer dereference in tb_port_update_credits() +- thunderbolt: Fix minimum allocated USB 3.x and PCIe bandwidth +- thunderbolt: Send uevent after asymmetric/symmetric switch +- wifi: brcmfmac: add linefeed at end of file +- iio: magnetometer: ak8975: Fix 'Unexpected device' error +- perf/arm-cmn: Fail DTC counter allocation correctly +- usb: yurex: Fix inconsistent locking bug in yurex_read() +- Documentation: KVM: fix warning in "make htmldocs" +- i2c: isch: Add missed 'else' +- i2c: aspeed: Update the stop sw state when the bus recovery occurs +- mm/damon/vaddr: protect vma traversal in __damon_va_thre_regions() with rcu read lock +- module: Fix KCOV-ignored file name +- spi: fspi: add support for imx8ulp +- mm: only enforce minimum stack gap size if it's sensible +- lockdep: fix deadlock issue between lockdep and rcu +- dm-verity: restart or panic on an I/O error +- bpf: lsm: Set bpf_lsm_blob_sizes.lbs_task to 0 +- thunderbolt: Improve DisplayPort tunnel setup process to be more robust +- thunderbolt: Configure asymmetric link if needed and bandwidth allows +- thunderbolt: Add support for asymmetric link +- thunderbolt: Introduce tb_switch_depth() +- thunderbolt: Introduce tb_for_each_upstream_port_on_path() +- thunderbolt: Introduce tb_port_path_direction_downstream() +- thunderbolt: Change bandwidth reservations to comply USB4 v2 +- thunderbolt: Make is_gen4_link() available to the rest of the driver +- thunderbolt: Use weight constants in tb_usb3_consumed_bandwidth() +- thunderbolt: Use constants for path weight and priority +- thunderbolt: Create multiple DisplayPort tunnels if there are more DP IN/OUT pairs +- thunderbolt: Expose tb_tunnel_xxx() log macros to the rest of the driver +- thunderbolt: Use tb_tunnel_dbg() where possible to make logging more consistent +- thunderbolt: Fix debug log when DisplayPort adapter not available for pairing +- dt-bindings: spi: nxp-fspi: add imx8ulp support +- dt-bindings: spi: nxp-fspi: support i.MX93 and i.MX95 +- btrfs: reorder btrfs_inode to fill gaps +- btrfs: subpage: fix the bitmap dump which can cause bitmap corruption +- lib/bitmap: add bitmap_{read,write}() +- x86/entry: Remove unwanted instrumentation in common_interrupt() +- x86/idtentry: Incorporate definitions/declarations of the FRED entries +- serial: don't use uninitialized value in uart_poll_init() +- tty: serial: kgdboc: Fix 8250_* kgdb over serial +- pps: add an error check in parport_attach +- pps: remove usage of the deprecated ida_simple_xx() API +- usb: xhci: fix loss of data on Cadence xHC +- xhci: Add a quirk for writing ERST in high-low order +- USB: misc: yurex: fix race between read and write +- usb: yurex: Replace snprintf() with the safer scnprintf() variant +- soc: versatile: realview: fix soc_dev leak during device remove +- soc: versatile: realview: fix memory leak during device remove +- ARM: dts: imx6ul-geam: fix fsl,pins property in tscgrp pinctrl +- spi: fspi: involve lut_num for struct nxp_fspi_devtype_data +- padata: use integer wrap around to prevent deadlock on seq_nr overflow +- cpuidle: riscv-sbi: Use scoped device node handling to fix missing of_node_put +- icmp: change the order of rate limits +- EDAC/igen6: Fix conversion of system address to physical memory address +- fs: Fix file_set_fowner LSM hook inconsistencies +- vfs: fix race between evice_inodes() and find_inode()&iput() +- arm64: dts: rockchip: Correct the Pinebook Pro battery design capacity +- arm64: dts: qcom: sa8775p: Mark APPS and PCIe SMMUs as DMA coherent +- arm64: dts: rockchip: Raise Pinebook Pro's panel backlight PWM frequency +- arm64: esr: Define ESR_ELx_EC_* constants as UL +- hwrng: cctrng - Add missing clk_disable_unprepare in cctrng_resume +- hwrng: bcm2835 - Add missing clk_disable_unprepare in bcm2835_rng_init +- hwrng: mtk - Use devm_pm_runtime_enable +- f2fs: fix to check atomic_file in f2fs ioctl interfaces +- f2fs: Require FMODE_WRITE for atomic write ioctls +- f2fs: avoid potential int overflow in sanity_check_area_boundary() +- f2fs: prevent possible int overflow in dir_block_index() +- f2fs: fix several potential integer overflows in file offsets +- btrfs: always update fstrim_range on failure in FITRIM ioctl +- btrfs: tree-checker: fix the wrong output of data backref objectid +- debugobjects: Fix conditions in fill_pool() +- wifi: mt76: mt7615: check devm_kasprintf() returned value +- wifi: rtw88: 8822c: Fix reported RX band width +- wifi: rtw88: 8821cu: Remove VID/PID 0bda:c82c +- wifi: mt76: mt7915: check devm_kasprintf() returned value +- wifi: mt76: mt7921: Check devm_kasprintf() returned value +- perf/x86/intel/pt: Fix sampling synchronization +- efistub/tpm: Use ACPI reclaim memory for event log to avoid corruption +- ACPI: resource: Add another DMI match for the TongFang GMxXGxx +- ACPI: sysfs: validate return type of _STR method +- drbd: Add NULL check for net_conf to prevent dereference in state validation +- drbd: Fix atomicity violation in drbd_uuid_set_bm() +- crypto: ccp - Properly unregister /dev/sev on sev PLATFORM_STATUS failure +- serial: qcom-geni: fix fifo polling timeout +- xhci: Set quirky xHC PCI hosts to D3 _after_ stopping and freeing them. +- tty: rp2: Fix reset with non forgiving PCIe host bridges +- firmware_loader: Block path traversal +- bus: mhi: host: pci_generic: Fix the name for the Telit FE990A +- bus: integrator-lm: fix OF node leak in probe() +- usb: dwc2: drd: fix clock gating on USB role switch +- usb: cdnsp: Fix incorrect usb_request status +- USB: class: CDC-ACM: fix race between get_serial and set_serial +- USB: misc: cypress_cy7c63: check for short transfer +- USB: appledisplay: close race between probe and completion handler +- arm64: dts: mediatek: mt8195-cherry: Mark USB 3.0 on xhci1 as disabled +- usbnet: fix cyclical race on disconnect with work queue +- wifi: rtw88: Fix USB/SDIO devices not transmitting beacons +- can: esd_usb: Remove CAN_CTRLMODE_3_SAMPLES for CAN-USB/3-FD +- scsi: mac_scsi: Disallow bus errors during PDMA send +- scsi: mac_scsi: Refactor polling loop +- scsi: mac_scsi: Revise printk(KERN_DEBUG ...) messages +- scsi: ufs: qcom: Update MODE_MAX cfg_bw value +- scsi: sd: Fix off-by-one error in sd_read_block_characteristics() +- ata: libata-scsi: Fix ata_msense_control() CDL page reporting +- ksmbd: handle caseless file creation +- ksmbd: allow write with FILE_APPEND_DATA +- ksmbd: make __dir_empty() compatible with POSIX +- fs: Create a generic is_dot_dotdot() utility +- powerpc/atomic: Use YZ constraints for DS-form instructions +- KEYS: prevent NULL pointer dereference in find_asymmetric_key() +- drm/amd/display: Validate backlight caps are sane +- drm/amd/display: Round calculated vtotal +- drm/amd/display: Add HDMI DSC native YCbCr422 support +- drm/amd/display: Skip Recompute DSC Params if no Stream on Link +- KVM: Use dedicated mutex to protect kvm_usage_count to avoid deadlock +- KVM: x86: Move x2APIC ICR helper above kvm_apic_write_nodecode() +- KVM: x86: Enforce x2APIC's must-be-zero reserved ICR bits +- KVM: arm64: Add memory length checks and remove inline in do_ffa_mem_xfer +- Input: i8042 - add another board name for TUXEDO Stellaris Gen5 AMD line +- Input: i8042 - add TUXEDO Stellaris 15 Slim Gen6 AMD to i8042 quirk table +- Input: i8042 - add TUXEDO Stellaris 16 Gen5 AMD to i8042 quirk table +- Input: adp5588-keys - fix check on return code +- iommufd: Protect against overflow of ALIGN() during iova allocation +- Revert "media: tuners: fix error return code of hybrid_tuner_request_state()" +- soc: versatile: integrator: fix OF node leak in probe() error path +- soc: fsl: cpm1: tsa: Fix tsa_write8() +- ASoC: rt5682: Return devm_of_clk_add_hw_provider to transfer the error +- Revert "soc: qcom: smd-rpm: Match rpmsg channel instead of compatible" +- PCI: xilinx-nwl: Fix off-by-one in INTx IRQ handler +- PCI: Use an error code with PCIe failed link retraining +- PCI: Correct error reporting with PCIe failed link retraining +- PCI: imx6: Fix missing call to phy_power_off() in error handling +- PCI: dra7xx: Fix threaded IRQ request for "dra7xx-pcie-main" IRQ +- PCI: Clear the LBMS bit after a link retrain +- PCI: Revert to the original speed after PCIe failed link retraining +- Remove *.orig pattern from .gitignore +- io_uring/sqpoll: do not put cpumask on stack +- io_uring/sqpoll: retain test for whether the CPU is valid +- xen: move checks for e820 conflicts further up +- Revert "net: libwx: fix alloc msix vectors failed" +- drm/vmwgfx: Prevent unmapping active read buffers +- drm/amd/display: Fix Synaptics Cascaded Panamera DSC Determination +- mm: call the security_mmap_file() LSM hook in remap_file_pages() +- io_uring: check for presence of task_work rather than TIF_NOTIFY_SIGNAL +- io_uring/sqpoll: do not allow pinning outside of cpuset +- netfilter: nf_tables: use rcu chain hook list iterator from netlink dump path +- netfilter: ctnetlink: compile ctnetlink_label_size with CONFIG_NF_CONNTRACK_EVENTS +- netfilter: nf_tables: Keep deleted flowtable hooks until after RCU +- net: stmmac: set PP_FLAG_DMA_SYNC_DEV only if XDP is enabled +- virtio_net: Fix mismatched buf address when unmapping for small packets +- bonding: Fix unnecessary warnings and logs from bond_xdp_get_xmit_slave() +- net: qrtr: Update packets cloning when broadcasting +- tcp: check skb is non-NULL in tcp_rto_delta_us() +- net: ipv6: select DST_CACHE from IPV6_RPL_LWTUNNEL +- net: seeq: Fix use after free vulnerability in ether3 Driver Due to Race Condition +- net: xilinx: axienet: Fix packet counting +- net: xilinx: axienet: Schedule NAPI in two steps +- Revert "dm: requeue IO if mapping table not yet available" +- ep93xx: clock: Fix off by one in ep93xx_div_recalc_rate() +- vhost_vdpa: assign irq bypass producer token correctly +- cxl/pci: Fix to record only non-zero ranges +- interconnect: icc-clk: Add missed num_nodes initialization +- coresight: tmc: sg: Do not leak sg_table +- serial: 8250: omap: Cleanup on error in request_irq +- driver core: Fix a potential null-ptr-deref in module_add_driver() +- dt-bindings: iio: asahi-kasei,ak8975: drop incorrect AK09116 compatible +- iio: magnetometer: ak8975: drop incorrect AK09116 compatible +- iio: magnetometer: ak8975: Convert enum->pointer for data in the match tables +- iio: chemical: bme680: Fix read/write ops to device by adding mutexes +- ABI: testing: fix admv8818 attr description +- driver core: Fix error handling in driver API device_rename() +- iio: adc: ad7606: fix standby gpio state to match the documentation +- iio: adc: ad7606: fix oversampling gpio array +- nvme-multipath: system fails to create generic nvme device +- spi: atmel-quadspi: Avoid overwriting delay register settings +- spi: spi-fsl-lpspi: Undo runtime PM changes at driver exit time +- spi: atmel-quadspi: Undo runtime PM changes at driver exit time +- f2fs: get rid of online repaire on corrupted directory +- f2fs: clean up w/ dotdot_name +- f2fs: prevent atomic file from being dirtied before commit +- f2fs: compress: don't redirty sparse cluster during {,de}compress +- f2fs: compress: do sanity check on cluster when CONFIG_F2FS_CHECK_FS is on +- f2fs: fix to avoid use-after-free in f2fs_stop_gc_thread() +- f2fs: support .shutdown in f2fs_sops +- f2fs: atomic: fix to truncate pagecache before on-disk metadata truncation +- f2fs: fix to wait page writeback before setting gcing flag +- f2fs: Create COW inode from parent dentry for atomic write +- f2fs: fix to avoid racing in between read and OPU dio write +- f2fs: reduce expensive checkpoint trigger frequency +- f2fs: atomic: fix to avoid racing w/ GC +- crypto: powerpc/p10-aes-gcm - Disable CRYPTO_AES_GCM_P10 +- crypto: caam - Pad SG length when allocating hash edesc +- ntb: Force physically contiguous allocation of rx ring buffers +- ntb_perf: Fix printk format +- RDMA/irdma: fix error message in irdma_modify_qp_roce() +- RDMA/cxgb4: Added NULL check for lookup_atid +- riscv: Fix fp alignment bug in perf_callchain_user() +- RDMA/mlx5: Obtain upper net device only when needed +- watchdog: imx_sc_wdt: Don't disable WDT in suspend +- RDMA/mlx5: Limit usage of over-sized mkeys from the MR cache +- RDMA/erdma: Return QP state in erdma_query_qp +- PCI: kirin: Fix buffer overflow in kirin_pcie_parse_port() +- IB/core: Fix ib_cache_setup_one error flow cleanup +- pinctrl: mvebu: Fix devinit_dove_pinctrl_probe function +- nfsd: fix refcount leak when file is unhashed after being found +- nfsd: remove unneeded EEXIST error check in nfsd_do_file_acquire +- clk: rockchip: rk3588: Fix 32k clock name for pmu_24m_32k_100m_src_p +- clk: starfive: Use pm_runtime_resume_and_get to fix pm_runtime_get_sync() usage +- clk: ti: dra7-atl: Fix leak of of_nodes +- RDMA/rtrs-clt: Reset cid to con_num - 1 to stay in bounds +- RDMA/rtrs: Reset hb_missed_cnt after receiving other traffic from peer +- media: mediatek: vcodec: Fix H264 stateless decoder smatch warning +- media: mediatek: vcodec: Fix VP8 stateless decoder smatch warning +- media: mediatek: vcodec: Fix H264 multi stateless decoder smatch warning +- clk: at91: sama7g5: Allocate only the needed amount of memory for PLLs +- pinctrl: single: fix missing error code in pcs_probe() +- RDMA/iwcm: Fix WARNING:at_kernel/workqueue.c:#check_flush_dependency +- media: platform: rzg2l-cru: rzg2l-csi2: Add missing MODULE_DEVICE_TABLE +- PCI: xilinx-nwl: Clean up clock on probe failure/removal +- PCI: xilinx-nwl: Fix register misspelling +- nvdimm: Fix devs leaks in scan_labels() +- x86/PCI: Check pcie_find_root_port() return for NULL +- leds: pca995x: Fix device child node usage in pca995x_probe() +- leds: pca995x: Use device_for_each_child_node() to access device child nodes +- leds: leds-pca995x: Add support for NXP PCA9956B +- clk: qcom: dispcc-sm8250: use special function for Lucid 5LPE PLL +- clk: qcom: ipq5332: Register gcc_qdss_tsctr_clk_src +- PCI: keystone: Fix if-statement expression in ks_pcie_quirk() +- firewire: core: correct range of block for case of switch statement +- PCI: Wait for Link before restoring Downstream Buses +- drivers: media: dvb-frontends/rtl2830: fix an out-of-bounds write error +- Input: ilitek_ts_i2c - add report id message validation +- Input: ilitek_ts_i2c - avoid wrong input subsystem sync +- pinctrl: ti: ti-iodelay: Fix some error handling paths +- pinctrl: ti: iodelay: Use scope based of_node_put() cleanups +- pinctrl: Use device_get_match_data() +- pinctrl: ti: ti-iodelay: Convert to platform remove callback returning void +- leds: bd2606mvv: Fix device child node usage in bd2606mvv_probe() +- clk: qcom: dispcc-sm8550: use rcg2_shared_ops for ESC RCGs +- clk: qcom: dispcc-sm8650: Update the GDSC flags +- clk: qcom: dispcc-sm8550: use rcg2_ops for mdss_dptx1_aux_clk_src +- clk: qcom: dispcc-sm8550: fix several supposed typos +- clk: rockchip: Set parent rate for DCLK_VOP clock on RK3228 +- remoteproc: imx_rproc: Initialize workqueue earlier +- remoteproc: imx_rproc: Correct ddr alias for i.MX8M +- clk: imx: imx8qxp: Parent should be initialized earlier than the clock +- clk: imx: imx8qxp: Register dc0_bypass0_clk before disp clk +- clk: imx: imx8mp: fix clock tree update of TF-A managed clocks +- clk: imx: fracn-gppll: fix fractional part of PLL getting lost +- clk: imx: composite-7ulp: Check the PCC present bit +- clk: imx: composite-93: keep root clock on when mcore enabled +- clk: imx: composite-8m: Enable gate clk with mcore_booted +- clk: imx: composite-8m: Less function calls in __imx8m_clk_hw_composite() after error detection +- clk: imx: imx6ul: fix default parent for enet*_ref_sel +- clk: imx: clk-audiomix: Correct parent clock for earc_phy and audpll +- nilfs2: fix potential oob read in nilfs_btree_check_delete() +- nilfs2: determine empty node blocks as corrupted +- nilfs2: fix potential null-ptr-deref in nilfs_btree_insert() +- ext4: check stripe size compatibility on remount as well +- ext4: avoid OOB when system.data xattr changes underneath the filesystem +- ext4: return error on ext4_find_inline_entry +- ext4: avoid negative min_clusters in find_group_orlov() +- ext4: avoid potential buffer_head leak in __ext4_new_inode() +- ext4: avoid buffer_head leak in ext4_mark_inode_used() +- smackfs: Use rcu_assign_pointer() to ensure safe assignment in smk_set_cipso +- ext4: clear EXT4_GROUP_INFO_WAS_TRIMMED_BIT even mount with discard +- kthread: fix task state in kthread worker if being frozen +- xz: cleanup CRC32 edits from 2018 +- bpf: correctly handle malformed BPF_CORE_TYPE_ID_LOCAL relos +- samples/bpf: Fix compilation errors with cf-protection option +- selftests/bpf: Fix error compiling tc_redirect.c with musl libc +- selftests/bpf: Fix compile if backtrace support missing in libc +- selftests/bpf: Fix redefinition errors compiling lwt_reroute.c +- selftests/bpf: Fix flaky selftest lwt_redirect/lwt_reroute +- selftests/bpf: Fix C++ compile error from missing _Bool type +- selftests/bpf: Fix error compiling test_lru_map.c +- selftests/bpf: Fix arg parsing in veristat, test_progs +- selftests/bpf: Fix errors compiling cg_storage_multi.h with musl libc +- selftests/bpf: Fix errors compiling decap_sanity.c with musl libc +- selftests/bpf: Fix errors compiling lwt_redirect.c with musl libc +- selftests/bpf: Fix compiling core_reloc.c with musl-libc +- selftests/bpf: Fix compiling tcp_rtt.c with musl-libc +- selftests/bpf: Fix compiling flow_dissector.c with musl-libc +- selftests/bpf: Fix compiling kfree_skb.c with musl-libc +- selftests/bpf: Fix compiling parse_tcp_hdr_opt.c with musl-libc +- selftests/bpf: Fix include of +- selftests/bpf: Add a cgroup prog bpf_get_ns_current_pid_tgid() test +- selftests/bpf: Refactor out some functions in ns_current_pid_tgid test +- selftests/bpf: Replace CHECK with ASSERT_* in ns_current_pid_tgid test +- selftests/bpf: Fix missing BUILD_BUG_ON() declaration +- selftests/bpf: Fix missing UINT_MAX definitions in benchmarks +- selftests/bpf: Fix missing ARRAY_SIZE() definition in bench.c +- selftests/bpf: Drop unneeded error.h includes +- selftests/bpf: Implement get_hw_ring_size function to retrieve current and max interface size +- selftests/bpf: Fix error compiling bpf_iter_setsockopt.c with musl libc +- selftests/bpf: Fix compile error from rlim_t in sk_storage_map.c +- selftests/bpf: Use pid_t consistently in test_progs.c +- tools/runqslower: Fix LDFLAGS and add LDLIBS support +- selftests/bpf: Fix wrong binary in Makefile log output +- selftests/bpf: Add CFLAGS per source file and runner +- bpf: Temporarily define BPF_NO_PRESEVE_ACCESS_INDEX for GCC +- bpf: Disable some `attribute ignored' warnings in GCC +- bpf: Use -Wno-error in certain tests when building with GCC +- selftests/bpf: Fix error linking uprobe_multi on mips +- selftests/bpf: Workaround strict bpf_lsm return value check. +- tpm: Clean up TPM space after command failure +- xen/swiotlb: fix allocated size +- xen/swiotlb: add alignment check for dma buffers +- xen: tolerate ACPI NVS memory overlapping with Xen allocated memory +- xen: add capability to remap non-RAM pages to different PFNs +- xen: move max_pfn in xen_memory_setup() out of function scope +- xen: introduce generic helper checking for memory map conflicts +- minmax: avoid overly complex min()/max() macro arguments in xen +- ata: libata: Clear DID_TIME_OUT for ATA PT commands with sense data +- HID: wacom: Do not warn about dropped packets for first packet +- HID: wacom: Support sequence numbers smaller than 16-bit +- xen: use correct end address of kernel for conflict checking +- drivers:drm:exynos_drm_gsc:Fix wrong assignment in gsc_bind() +- drm/msm: fix %s null argument error +- drm/msm/dsi: correct programming sequence for SM8350 / SM8450 +- ipmi: docs: don't advertise deprecated sysfs entries +- drm/msm/a5xx: workaround early ring-buffer emptiness check +- drm/msm/a5xx: fix races in preemption evaluation stage +- drm/msm/a5xx: properly clear preemption records on resume +- drm/msm/a5xx: disable preemption in submits by default +- drm/msm: Fix incorrect file name output in adreno_request_fw() +- powerpc/vdso: Inconditionally use CFUNC macro +- powerpc/8xx: Fix kernel vs user address comparison +- powerpc/8xx: Fix initial memory mapping +- drm/mediatek: Use spin_lock_irqsave() for CRTC event lock +- drm/mediatek: Fix missing configuration flags in mtk_crtc_ddp_config() +- jfs: fix out-of-bounds in dbNextAG() and diAlloc() +- scsi: elx: libefc: Fix potential use after free in efc_nport_vport_del() +- drm/vc4: hdmi: Handle error case of pm_runtime_resume_and_get +- drm/bridge: lontium-lt8912b: Validate mode in drm_bridge_funcs::mode_valid() +- drm/radeon/evergreen_cs: fix int overflow errors in cs track offsets +- drm/rockchip: dw_hdmi: Fix reading EDID when using a forced mode +- drm/rockchip: vop: Allow 4096px width scaling +- drm/amd/amdgpu: Properly tune the size of struct +- scsi: NCR5380: Check for phase match during PDMA fixup +- scsi: smartpqi: revert propagate-the-multipath-failure-to-SML-quickly +- drm/radeon: properly handle vbios fake edid sizing +- drm/amdgpu: properly handle vbios fake edid sizing +- drm/stm: ltdc: check memory returned by devm_kzalloc() +- drm/stm: Fix an error handling path in stm_drm_platform_probe() +- pmdomain: core: Harden inter-column space in debug summary +- iommu/arm-smmu-qcom: apply num_context_bank fixes for SDM630 / SDM660 +- iommu/arm-smmu-qcom: Work around SDM845 Adreno SMMU w/ 16K pages +- iommu/arm-smmu-qcom: hide last LPASS SMMU context bank from linux +- mtd: rawnand: mtk: Fix init error path +- mtd: rawnand: mtk: Factorize out the logic cleaning mtk chips +- mtd: rawnand: mtk: Use for_each_child_of_node_scoped() +- rcu/nocb: Fix RT throttling hrtimer armed from offline CPU +- mtd: powernv: Add check devm_kasprintf() returned value +- iommu/amd: Do not set the D bit on AMD v2 table entries +- fbdev: hpfb: Fix an error handling path in hpfb_dio_probe() +- power: supply: max17042_battery: Fix SOC threshold calc w/ no current sense +- power: supply: axp20x_battery: Remove design from min and max voltage +- hwmon: (ntc_thermistor) fix module autoloading +- mtd: slram: insert break after errors in parsing the map +- hwmon: (max16065) Fix alarm attributes +- hwmon: (max16065) Remove use of i2c_match_id() +- hwmon: (max16065) Fix overflows seen when writing limits +- ASoC: loongson: fix error release +- m68k: Fix kernel_clone_args.flags in m68k_clone() +- ALSA: hda: cs35l41: fix module autoloading +- selftests/ftrace: Add required dependency for kprobe tests +- ASoC: tas2781-i2c: Get the right GPIO line +- ASoC: tas2781-i2c: Drop weird GPIO code +- ASoC: tas2781: Use of_property_read_reg() +- ASoC: tas2781: remove unused acpi_subysystem_id +- ASoC: rt5682s: Return devm_of_clk_add_hw_provider to transfer the error +- x86/mm: Use IPIs to synchronize LAM enablement +- arm64: dts: mediatek: mt8195: Correct clock order for dp_intf* +- clocksource/drivers/qcom: Add missing iounmap() on errors in msm_dt_timer_init() +- reset: k210: fix OF node leak in probe() error path +- reset: berlin: fix OF node leak in probe() error path +- ARM: versatile: fix OF node leak in CPUs prepare +- ARM: dts: imx7d-zii-rmu2: fix Ethernet PHY pinctrl property +- ARM: dts: microchip: sama7g5: Fix RTT clock +- spi: bcmbca-hsspi: Fix missing pm_runtime_disable() +- arm64: dts: ti: k3-j721e-beagleboneai64: Fix reversed C6x carveout locations +- arm64: dts: ti: k3-j721e-sk: Fix reversed C6x carveout locations +- arm64: dts: rockchip: Correct vendor prefix for Hardkernel ODROID-M1 +- ARM: dts: microchip: sam9x60: Fix rtc/rtt clocks +- arm64: dts: renesas: r9a07g044: Correct GICD and GICR sizes +- arm64: dts: renesas: r9a07g054: Correct GICD and GICR sizes +- arm64: dts: renesas: r9a07g043u: Correct GICD and GICR sizes +- regulator: Return actual error in of_regulator_bulk_get_all() +- spi: ppc4xx: Avoid returning 0 when failed to parse and map IRQ +- firmware: arm_scmi: Fix double free in OPTEE transport +- arm64: dts: mediatek: mt8186: Fix supported-hw mask for GPU OPPs +- arm64: dts: exynos: exynos7885-jackpotlte: Correct RAM amount to 4GB +- spi: ppc4xx: handle irq_of_parse_and_map() errors +- block: fix potential invalid pointer dereference in blk_add_partition +- block: print symbolic error name instead of error code +- io_uring/io-wq: inherit cpuset of cgroup in io worker +- io_uring/io-wq: do not allow pinning outside of cpuset +- block, bfq: fix procress reference leakage for bfqq in merge chain +- block, bfq: fix uaf for accessing waker_bfqq after splitting +- erofs: fix incorrect symlink detection in fast symlink +- cachefiles: Fix non-taking of sb_writers around set/removexattr +- block, bfq: don't break merge chain in bfq_split_bfqq() +- block, bfq: choose the last bfqq from merge chain in bfq_setup_cooperator() +- block, bfq: fix possible UAF for bfqq->bic with merge chain +- nbd: fix race between timeout and normal completion +- ublk: move zone report data out of request pdu +- ipv6: avoid possible NULL deref in rt6_uncached_list_flush_dev() +- net: tipc: avoid possible garbage value +- net: ipv6: rpl_iptunnel: Fix memory leak in rpl_input +- r8169: disable ALDPS per default for RTL8125 +- net: enetc: Use IRQF_NO_AUTOEN flag in request_irq() +- bareudp: Pull inner IP header on xmit. +- bareudp: Pull inner IP header in bareudp_udp_encap_recv(). +- Bluetooth: btusb: Fix not handling ZPL/short-transfer +- can: m_can: m_can_close(): stop clocks after device has been shut down +- can: m_can: enable NAPI before enabling interrupts +- sock_map: Add a cond_resched() in sock_hash_free() +- Bluetooth: hci_sync: Ignore errors from HCI_OP_REMOTE_NAME_REQ_CANCEL +- Bluetooth: hci_core: Fix sending MGMT_EV_CONNECT_FAILED +- wifi: wilc1000: fix potential RCU dereference issue in wilc_parse_join_bss_param +- wifi: mac80211: use two-phase skb reclamation in ieee80211_do_stop() +- wifi: cfg80211: fix two more possible UBSAN-detected off-by-one errors +- wifi: mt76: mt7996: fix uninitialized TLV data +- wifi: mt76: mt7996: ensure 4-byte alignment for beacon commands +- wifi: mt76: mt7915: fix rx filter setting for bfee functionality +- wifi: cfg80211: fix UBSAN noise in cfg80211_wext_siwscan() +- wifi: mt76: mt7603: fix mixed declarations and code +- crypto: hisilicon/qm - inject error before stopping queue +- pm:cpupower: Add missing powercap_set_enabled() stub function +- x86/sgx: Fix deadlock in SGX NUMA node search +- wifi: mt76: mt7996: fix EHT beamforming capability check +- wifi: mt76: mt7996: fix HE and EHT beamforming capabilities +- wifi: mt76: mt7996: fix wmm set of station interface to 3 +- wifi: mt76: mt7996: fix traffic delay when switching back to working channel +- wifi: mt76: mt7996: use hweight16 to get correct tx antenna +- wifi: mt76: mt7915: fix oops on non-dbdc mt7986 +- cpufreq: ti-cpufreq: Introduce quirks to handle syscon fails appropriately +- perf/arm-cmn: Ensure dtm_idx is big enough +- perf/arm-cmn: Fix CCLA register offset +- perf/arm-cmn: Refactor node ID handling. Again. +- perf/arm-cmn: Improve debugfs pretty-printing for large configs +- perf/arm-cmn: Rework DTC counters (again) +- netfilter: nf_tables: remove annotation to access set timeout while holding lock +- netfilter: nf_tables: reject expiration higher than timeout +- netfilter: nf_tables: reject element expiration with no timeout +- netfilter: nf_tables: elements with timeout below CONFIG_HZ never expire +- ACPI: CPPC: Fix MASK_VAL() usage +- can: j1939: use correct function name in comment +- kselftest/arm64: Actually test SME vector length changes via sigreturn +- padata: Honor the caller's alignment in case of chunk_size 0 +- wifi: iwlwifi: mvm: increase the time between ranging measurements +- wifi: iwlwifi: config: label 'gl' devices as discrete +- wifi: iwlwifi: remove AX101, AX201 and AX203 support from LNL +- wifi: mac80211: don't use rate mask for offchannel TX either +- kselftest/arm64: signal: fix/refactor SVE vector length enumeration +- powercap: intel_rapl: Fix off by one in get_rpi() +- ARM: 9410/1: vfp: Use asm volatile in fmrx/fmxr macros +- mount: handle OOM on mnt_warn_timestamp_expiry +- RISC-V: KVM: Fix to allow hpmcounter31 from the guest +- RISC-V: KVM: Allow legacy PMU access from guest +- RISC-V: KVM: Fix sbiret init before forwarding to userspace +- wifi: rtw88: remove CPT execution branch never used +- arm64: signal: Fix some under-bracketed UAPI macros +- wifi: ath12k: fix invalid AMPDU factor calculation in ath12k_peer_assoc_h_he() +- wifi: ath12k: match WMI BSS chan info structure with firmware definition +- wifi: ath12k: fix BSS chan info request WMI command +- wifi: ath9k: Remove error checks when creating debugfs entries +- wifi: brcmfmac: introducing fwil query functions +- wifi: brcmfmac: export firmware interface functions +- ACPI: PMIC: Remove unneeded check in tps68470_pmic_opregion_probe() +- crypto: xor - fix template benchmarking +- wifi: rtw88: always wait for both firmware loading attempts +- EDAC/synopsys: Fix error injection on Zynq UltraScale+ +- EDAC/synopsys: Fix ECC status and IRQ control race condition +- !12612 Hygon model 4h~fh and 10h ATL issue fix +- EDAC/amd64: Don't use the ATL for Hygon model 4h~fh and 10h processors +- !12464 f2fs: fix to don't set SB_RDONLY in f2fs_handle_critical_error() +- f2fs: fix to don't set SB_RDONLY in f2fs_handle_critical_error() +- !12584 drm/amd/display: Add null check for set_output_gamma in dcn30_set_output_transfer_func +- drm/amd/display: Add null check for set_output_gamma in dcn30_set_output_transfer_func +- !12461 NFSD: Limit the number of concurrent async COPY operations +- NFSD: Limit the number of concurrent async COPY operations +- !12559 fix CVE-2024-49900 +- jfs: Fix uninit-value access of new_ea in ea_buffer +- !12462 drm/amd/display: Fix index out of bounds in DCN30 degamma hardware format translation +- drm/amd/display: Fix index out of bounds in DCN30 degamma hardware format translation +- !12455 drm/amd/display: Add NULL check for function pointer in dcn20_set_output_transfer_func +- drm/amd/display: Add NULL check for function pointer in dcn20_set_output_transfer_func +- !12448 drm/amd/display: Add null check for head_pipe in dcn201_acquire_free_pipe_for_layer +- drm/amd/display: Add null check for head_pipe in dcn201_acquire_free_pipe_for_layer +- !12443 drm/amd/display: Fix index out of bounds in DCN30 color transformation +- drm/amd/display: Fix index out of bounds in DCN30 color transformation +- !12533 drm/amd/display: Add null check for head_pipe in dcn32_acquire_idle_pipe_for_head_pipe_in_layer +- drm/amd/display: Add null check for head_pipe in dcn32_acquire_idle_pipe_for_head_pipe_in_layer +- !12065 Fix VMAPP/VMOVP races +- irqchip/gic-v4: Fix ordering between vmapp and vpe locks +- irqchip/gic-v4: Make sure a VPE is locked when VMAPP is issued +- irqchip/gic-v4: Substitute vmovp_lock for a per-VM lock +- irqchip/gic-v4: Always configure affinity on VPE activation +- !12400 drivers: media: dvb-frontends/rtl2832: fix an out-of-bounds write error +- drivers: media: dvb-frontends/rtl2832: fix an out-of-bounds write error +- !12429 jfs: Fix uaf in dbFreeBits +- jfs: Fix uaf in dbFreeBits +- !12428 jfs: check if leafidx greater than num leaves per dmap tree +- jfs: check if leafidx greater than num leaves per dmap tree +- !12426 btrfs: fix a NULL pointer dereference when failed to start a new trasacntion +- btrfs: fix a NULL pointer dereference when failed to start a new trasacntion +- !12427 btrfs: wait for fixup workers before stopping cleaner kthread during umount +- btrfs: wait for fixup workers before stopping cleaner kthread during umount +- !12524 netfilter: nf_reject_ipv6: fix nf_reject_ip6_tcphdr_put() +- netfilter: nf_reject_ipv6: fix nf_reject_ip6_tcphdr_put() +- !12515 drm/amd/display: Validate function returns +- drm/amd/display: Validate function returns +- !12365 x86/ioapic: Handle allocation failures gracefully +- x86/ioapic: Handle allocation failures gracefully +- !12361 cpufreq: Avoid a bad reference count on CPU node +- cpufreq: Avoid a bad reference count on CPU node +- !12476 fix CVE-2024-40965 +- i2c: lpi2c: Avoid calling clk_get_rate during transfer +- clk: Provide !COMMON_CLK dummy for devm_clk_rate_exclusive_get() +- clk: Add a devm variant of clk_rate_exclusive_get() +- !12300 [OLK-6.6] AMD Address Translation Library (ATL) patches +- RAS/AMD/ATL: Fix MI300 bank hash +- RAS/AMD/ATL: Use system settings for MI300 DRAM to normalized address translation +- RAS/AMD/ATL: Fix array overflow in get_logical_coh_st_fabric_id_mi300() +- RAS/AMD/ATL: Fix bit overflow in denorm_addr_df4_np2() +- RAS: Avoid build errors when CONFIG_DEBUG_FS=n +- RAS/AMD/FMPM: Use atl internal.h for INVALID_SPA +- RAS/AMD/FMPM: Safely handle saved records of various sizes +- RAS/AMD/FMPM: Avoid NULL ptr deref in get_saved_records() +- RAS/AMD/FMPM: Fix off by one when unwinding on error +- RAS/AMD/FMPM: Add debugfs interface to print record entries +- RAS/AMD/FMPM: Save SPA values +- RAS: Introduce a FRU memory poison manager +- RAS/AMD/ATL: Implement DF 4.5 NP2 denormalization +- RAS/AMD/ATL: Validate address map when information is gathered +- RAS/AMD/ATL: Expand helpers for adding and removing base and hole +- RAS/AMD/ATL: Read DRAM hole base early +- RAS/AMD/ATL: Add amd_atl pr_fmt() prefix +- EDAC/amd64: Use new AMD Address Translation Library +- RAS: Export helper to get ras_debugfs_dir +- RAS/AMD/ATL: Add MI300 row retirement support +- RAS/AMD/ATL: Add MI300 DRAM to normalized address translation support +- RAS/AMD/ATL: Add MI300 support +- RAS: Introduce AMD Address Translation Library +- !12440 CVE-2024-35964 +- Bluetooth: ISO: Fix not validating setsockopt user input +- !12438 CVE-2024-35949 +- btrfs: make sure that WRITTEN is set on all metadata blocks +- !12410 iommu/arm-smmu: Use the correct type in nvidia_smmu_context_fault() +- iommu/arm-smmu: Use the correct type in nvidia_smmu_context_fault() +- !12389 mm/swapfile: skip HugeTLB pages for unuse_vma +- mm/swapfile: skip HugeTLB pages for unuse_vma +- !12363 md: use RCU lock to protect traversal in md_spares_need_change() +- md: use RCU lock to protect traversal in md_spares_need_change() +- !12351 i2c: stm32f7: Do not prepare/unprepare clock during runtime suspend/resume +- i2c: stm32f7: Do not prepare/unprepare clock during runtime suspend/resume +- !12394 tracing/timerlat: Fix a race during cpuhp processing +- tracing/timerlat: Fix a race during cpuhp processing +- !12397 tracing/timerlat: Drop interface_lock in stop_kthread() +- tracing/timerlat: Drop interface_lock in stop_kthread() +- !12399 wifi: mt76: mt7996: fix NULL pointer dereference in mt7996_mcu_sta_bfer_he +- wifi: mt76: mt7996: fix NULL pointer dereference in mt7996_mcu_sta_bfer_he +- !12390 RDMA/hns: Fix missing spin_lock_init() for qp flush lock +- RDMA/hns: Fix missing spin_lock_init() for qp flush lock +- !12273 drm/amdgpu: fix mc_data out-of-bounds read warning +- drm/amdgpu: fix mc_data out-of-bounds read warning +- !12263 drm/amd/display: Avoid overflow from uint32_t to uint8_t +- drm/amd/display: Avoid overflow from uint32_t to uint8_t +- !12288 [OLK-6.6] AMD Turin perf vendor event patches +- perf vendor events amd: Add Zen 5 mapping +- perf vendor events amd: Add Zen 5 metrics +- perf vendor events amd: Add Zen 5 uncore events +- perf vendor events amd: Add Zen 5 core events +- tracing: Add the ::microcode field to the mce_record tracepoint +- tracing: Add the ::ppin field to the mce_record tracepoint +- x86/mce: Clean up TP_printk() output line of the 'mce_record' tracepoint +- !12322 LoongArch: fix dma-direct.h not found +- LoongArch: fix dma-direct.h not found +- !12293 nfsd: return -EINVAL when namelen is 0 +- nfsd: return -EINVAL when namelen is 0 +- !12335 ntb: intel: Fix the NULL vs IS_ERR() bug for debugfs_create_dir() +- ntb: intel: Fix the NULL vs IS_ERR() bug for debugfs_create_dir() +- !12338 drm/amd/display: Add NULL pointer check for kzalloc +- drm/amd/display: Add NULL pointer check for kzalloc +- !12317 nfsd: call cache_put if xdr_reserve_space returns NULL +- nfsd: call cache_put if xdr_reserve_space returns NULL +- !12066 drm/amd/display: added NULL check at start of dc_validate_stream +- drm/amd/display: added NULL check at start of dc_validate_stream + +* Wed Oct 23 2024 ZhangPeng - 6.6.0-47.0.0.52 +- !12168 crypto: stm32/cryp - call finalize with bh disabled +- crypto: stm32/cryp - call finalize with bh disabled +- !11502 Virtcca feature: modify vfio/msi/iommu driver to enable confidential device assignment +- virtcca feature: msi place modify +- virtcca feature: fix msi iova map +- virtcca feature: extract the function to the virtcca_coda.c file +- virtcca feature: read or write msi forwarding to the secure world +- virtcca feature: read or write bar space forwarding to the secure world +- virtcca feature: read or write config space forwarding to secure world +- virtcca feature: activate confidential vm to set security device s_s2ttbr +- virtcca feature: set device security properties +- virtcca feature: secure device page fault +- virtcca feature: vfio driver dma map +- virtcca feature: bind the kvm handle of cvm with smmu domain +- virtcca feature: vfio attach the device list to secure world +- !12304 btrfs: fix race setting file private on concurrent lseek using same fd +- btrfs: fix race setting file private on concurrent lseek using same fd +- !12314 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.52-6.6.53 LTS Patches +- USB: serial: pl2303: add device id for Macrosilicon MS3020 +- can: mcp251xfd: move mcp251xfd_timestamp_start()/stop() into mcp251xfd_chip_start/stop() +- can: mcp251xfd: properly indent labels +- x86/mm: Switch to new Intel CPU model defines +- nvme-pci: qdepth 1 quirk +- gpiolib: cdev: Ignore reconfiguration without direction +- Revert "wifi: cfg80211: check wiphy mutex is held for wdev mutex" +- netfilter: nf_tables: missing iterator type in lookup walk +- netfilter: nft_set_pipapo: walk over current view on netlink dump +- netfilter: nft_socket: Fix a NULL vs IS_ERR() bug in nft_socket_cgroup_subtree_level() +- netfilter: nft_socket: make cgroupsv2 matching work with namespaces +- powercap/intel_rapl: Add support for AMD family 1Ah +- drm: Expand max DRM device number to full MINORBITS +- accel: Use XArray instead of IDR for minors +- drm: Use XArray instead of IDR for minors +- spi: spidev: Add missing spi_device_id for jg10309-01 +- block: Fix where bio IO priority gets set +- tools: hv: rm .*.cmd when make clean +- x86/hyperv: Set X86_FEATURE_TSC_KNOWN_FREQ when Hyper-V provides frequency +- smb: client: fix hang in wait_for_response() for negproto +- spi: bcm63xx: Enable module autoloading +- drm: komeda: Fix an issue related to normalized zpos +- ALSA: hda: add HDMI codec ID for Intel PTL +- ASoC: amd: yc: Add a quirk for MSI Bravo 17 (D7VEK) +- spi: spidev: Add an entry for elgin,jg10309-01 +- ASoC: fix module autoloading +- ASoC: tda7419: fix module autoloading +- ASoC: google: fix module autoloading +- ASoC: intel: fix module autoloading +- ASoC: Intel: soc-acpi-cht: Make Lenovo Yoga Tab 3 X90F DMI match less strict +- can: mcp251xfd: mcp251xfd_ring_init(): check TX-coalescing configuration +- wifi: iwlwifi: clear trans->state earlier upon error +- wifi: mac80211: free skb on error path in ieee80211_beacon_get_ap() +- wifi: iwlwifi: mvm: pause TCM when the firmware is stopped +- wifi: iwlwifi: mvm: fix iwl_mvm_max_scan_ie_fw_cmd_room() +- wifi: iwlwifi: mvm: fix iwl_mvm_scan_fits() calculation +- wifi: iwlwifi: lower message level for FW buffer destination +- LoongArch: Define ARCH_IRQ_INIT_FLAGS as IRQ_NOPROBE +- net: ftgmac100: Ensure tx descriptor updates are visible +- platform/x86: x86-android-tablets: Make Lenovo Yoga Tab 3 X90F DMI match less strict +- microblaze: don't treat zero reserved memory regions as error +- hwmon: (asus-ec-sensors) remove VRM temp X570-E GAMING +- pinctrl: at91: make it work with current gpiolib +- scsi: lpfc: Fix overflow build issue +- ALSA: hda/realtek - FIxed ALC285 headphone no sound +- ALSA: hda/realtek - Fixed ALC256 headphone no sound +- ASoC: allow module autoloading for table board_ids +- ASoC: allow module autoloading for table db1200_pids +- ASoC: mediatek: mt8188: Mark AFE_DAC_CON0 register as volatile +- ASoC: SOF: mediatek: Add missing board compatible +- !12151 nfc: pn533: Add poll mod list filling check +- nfc: pn533: Add poll mod list filling check +- !12141 drm/vmwgfx: Fix prime with external buffers +- drm/vmwgfx: Fix prime with external buffers +- !12129 bpf: Remove tst_run from lwt_seg6local_prog_ops. +- bpf: Remove tst_run from lwt_seg6local_prog_ops. +- !12296 drivers/perf: Fix ali_drw_pmu driver interrupt status clearing +- drivers/perf: Fix ali_drw_pmu driver interrupt status clearing +- !12200 CVE-2024-38608 +- net/mlx5e: Fix netif state handling +- net/mlx5e: Add wrapping for auxiliary_driver ops and remove unused args +- !12201 netfilter: nf_tables: use timestamp to check for set element timeout +- netfilter: nf_tables: use timestamp to check for set element timeout +- !12295 i3c: mipi-i3c-hci: Error out instead on BUG_ON() in IBI DMA setup +- i3c: mipi-i3c-hci: Error out instead on BUG_ON() in IBI DMA setup +- !12306 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.51-6.6.52 LTS Patches +- riscv: dts: starfive: add assigned-clock* to limit frquency +- pinctrl: meteorlake: Add Arrow Lake-H/U ACPI ID +- cifs: Fix signature miscalculation +- ASoC: codecs: avoid possible garbage value in peb2466_reg_read() +- drm/i915/guc: prevent a possible int overflow in wq offsets +- spi: geni-qcom: Fix incorrect free_irq() sequence +- spi: geni-qcom: Undo runtime PM changes at driver exit time +- drm/amd/amdgpu: apply command submission parser for JPEG v1 +- drm/amdgpu/atomfirmware: Silence UBSAN warning +- drm/nouveau/fb: restore init() for ramgp102 +- drm/syncobj: Fix syncobj leak in drm_syncobj_eventfd_ioctl +- soundwire: stream: Revert "soundwire: stream: fix programming slave ports for non-continous port maps" +- spi: nxp-fspi: fix the KASAN report out-of-bounds bug +- tracing/osnoise: Fix build when timerlat is not enabled +- net: dsa: felix: ignore pending status of TAS module when it's disabled +- selftests: net: csum: Fix checksums for packets with non-zero padding +- net: ftgmac100: Enable TX interrupt to avoid TX timeout +- octeontx2-af: Modify SMQ flush sequence to drop packets +- fou: fix initialization of grc +- net/mlx5: Verify support for scheduling element and TSAR type +- net/mlx5: Correct TASR typo into TSAR +- net/mlx5: Add missing masks and QoS bit masks for scheduling elements +- net/mlx5: Explicitly set scheduling element and TSAR type +- net/mlx5e: Add missing link mode to ptys2ext_ethtool_map +- IB/mlx5: Rename 400G_8X speed to comply to naming convention +- net/mlx5e: Add missing link modes to ptys2ethtool_map +- net/mlx5: Update the list of the PCI supported devices +- igb: Always call igb_xdp_ring_update_tail() under Tx lock +- ice: fix VSI lists confusion when adding VLANs +- ice: fix accounting for filters shared by multiple VSIs +- ice: Fix lldp packets dropping after changing the number of channels +- hwmon: (pmbus) Conditionally clear individual status bits for pmbus rev >= 1.2 +- selftests/bpf: Support SOCK_STREAM in unix_inet_redir_to_connected() +- cxl/core: Fix incorrect vendor debug UUID define +- eeprom: digsy_mtc: Fix 93xx46 driver probe failure +- drm/amd/display: Fix FEC_READY write on DP LT +- drm/amd/display: Disable error correction if it's not supported +- arm64: dts: rockchip: fix PMIC interrupt pin in pinctrl for ROCK Pi E +- net: xilinx: axienet: Fix race in axienet_stop +- mm: avoid leaving partial pfn mappings around in error case +- x86/hyperv: fix kexec crash due to VP assist page corruption +- dm-integrity: fix a race condition when accessing recalc_sector +- net: tighten bad gso csum offset check in virtio_net_hdr +- minmax: reduce min/max macro expansion in atomisp driver +- arm64: dts: rockchip: override BIOS_DISABLE signal via GPIO hog on RK3399 Puma +- arm64: dts: rockchip: fix eMMC/SPI corruption when audio has been used on RK3399 Puma +- selftests: mptcp: join: restrict fullmesh endp on 1st sf +- platform/x86: panasonic-laptop: Allocate 1 entry extra in the sinf array +- NFS: Avoid unnecessary rescanning of the per-server delegation list +- NFSv4: Fix clearing of layout segments in layoutreturn +- smb/server: fix return value of smb2_open() +- Input: i8042 - add Fujitsu Lifebook E756 to i8042 quirk table +- drm/msm/adreno: Fix error return if missing firmware-name +- platform/surface: aggregator_registry: Add support for Surface Laptop Go 3 +- platform/surface: aggregator_registry: Add Support for Surface Pro 10 +- scripts: kconfig: merge_config: config files: add a trailing newline +- HID: multitouch: Add support for GT7868Q +- Input: synaptics - enable SMBus for HP Elitebook 840 G2 +- Input: ads7846 - ratelimit the spi_sync error message +- btrfs: update target inode's ctime on unlink +- wifi: mt76: mt7921: fix NULL pointer access in mt7921_ipv6_addr_change +- powerpc/mm: Fix boot warning with hugepages and CONFIG_DEBUG_VIRTUAL +- net: phy: vitesse: repair vsc73xx autonegotiation +- drm: panel-orientation-quirks: Add quirk for Ayn Loki Max +- drm: panel-orientation-quirks: Add quirk for Ayn Loki Zero +- net: ethernet: use ip_hdrlen() instead of bit shift +- usbnet: ipheth: fix carrier detection in modes 1 and 4 +- usbnet: ipheth: do not stop RX on failing RX callback +- usbnet: ipheth: drop RX URBs with no payload +- usbnet: ipheth: remove extraneous rx URB length check +- ksmbd: override fsids for smb2_query_info() +- ksmbd: override fsids for share path check +- nvmem: u-boot-env: error if NVMEM device is too small +- nvmem: u-boot-env: improve coding style +- nvmem: u-boot-env: use nvmem device helpers +- nvmem: u-boot-env: use nvmem_add_one_cell() nvmem subsystem helper +- nvmem: core: add nvmem_dev_size() helper +- iio: adc: ad7124: fix DT configuration parsing +- iio: adc: ad7124: Switch from of specific to fwnode based property handling +- device property: Introduce device_for_each_child_node_scoped() +- device property: Add cleanup.h based fwnode_handle_put() scope based cleanup. +- !12301 bpf: Fix use-after-free in bpf_uprobe_multi_link_attach() +- bpf: Fix use-after-free in bpf_uprobe_multi_link_attach() +- !12291 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.50-6.6.51 LTS Patches +- Bluetooth: hci_sync: Fix UAF on hci_abort_conn_sync +- Bluetooth: hci_sync: Fix UAF on create_le_conn_complete +- Bluetooth: hci_sync: Fix UAF in hci_acl_create_conn_sync +- spi: spi-fsl-lpspi: Fix off-by-one in prescale max +- x86/mm: Fix PTI for i386 some more +- membarrier: riscv: Add full memory barrier in switch_mm() +- ublk_drv: fix NULL pointer dereference in ublk_ctrl_start_recovery() +- riscv: Do not restrict memory size because of linear mapping on nommu +- riscv: Fix toolchain vector detection +- gpio: modepin: Enable module autoloading +- gpio: rockchip: fix OF node leak in probe() +- drm/i915/fence: Mark debug_fence_free() with __maybe_unused +- drm/i915/fence: Mark debug_fence_init_onstack() with __maybe_unused +- clk: qcom: gcc-sm8550: Don't park the USB RCG at registration time +- clk: qcom: gcc-sm8550: Don't use parking clk_ops for QUPs +- ASoC: sunxi: sun4i-i2s: fix LRCLK polarity in i2s mode +- ASoc: SOF: topology: Clear SOF link platform name upon unload +- nvme-pci: allocate tagset on reset if necessary +- ASoC: tegra: Fix CBB error during probe() +- powerpc/vdso: Don't discard rela sections +- powerpc/64e: Define mmu_pte_psize static +- powerpc/64e: split out nohash Book3E 64-bit code +- powerpc/64e: remove unused IBM HTW code +- clk: qcom: ipq9574: Update the alpha PLL type for GPLLs +- crypto: starfive - Fix nent assignment in rsa dec +- crypto: starfive - Align rsa input data to 32-bit +- ata: libata-scsi: Check ATA_QCFLAG_RTF_FILLED before using result_tf +- ata: libata-scsi: Remove redundant sense_buffer memsets +- drm/amdgpu: handle gfx12 in amdgpu_display_verify_sizes +- drm/amd: Add gfx12 swizzle mode defs +- can: mcp251xfd: rx: add workaround for erratum DS80000789E 6 of mcp2518fd +- can: mcp251xfd: clarify the meaning of timestamp +- can: mcp251xfd: rx: prepare to workaround broken RX FIFO head index erratum +- can: mcp251xfd: mcp251xfd_handle_rxif_ring_uinc(): factor out in separate function +- ACPI: processor: Fix memory leaks in error paths of processor_add() +- ACPI: processor: Return an error if acpi_processor_get_info() fails in processor_add() +- workqueue: Improve scalability of workqueue watchdog touch +- workqueue: wq_watchdog_touch is always called with valid CPU +- Revert "mm: skip CMA pages when they are not available" +- mm/vmscan: use folio_migratetype() instead of get_pageblock_migratetype() +- uprobes: Use kzalloc to allocate xol area +- clocksource/drivers/timer-of: Remove percpu irq related code +- clocksource/drivers/imx-tpm: Fix next event not taking effect sometime +- clocksource/drivers/imx-tpm: Fix return -ETIME when delta exceeds INT_MAX +- Drivers: hv: vmbus: Fix rescind handling in uio_hv_generic +- nvmem: Fix return type of devm_nvmem_device_get() in kerneldoc +- usb: dwc3: Avoid waking up gadget during startxfer +- usb: cdns2: Fix controller reset issue +- usb: dwc3: core: update LC timer as per USB Spec V3.2 +- iio: adc: ad7124: fix chip ID mismatch +- iio: adc: ad7606: remove frstdata check for serial mode +- iio: adc: ad7124: fix config comparison +- iio: fix scale application in iio_convert_raw_to_processed_unlocked +- iio: buffer-dmaengine: fix releasing dma channel on error +- staging: iio: frequency: ad9834: Validate frequency parameter value +- intel: legacy: Partial revert of field get conversion +- tcp: process the 3rd ACK with sk_socket for TFO/MPTCP +- cpufreq: amd-pstate: fix the highest frequency issue which limits performance +- cpufreq: amd-pstate: Enable amd-pstate preferred core support +- ACPI: CPPC: Add helper to get the highest performance value +- riscv: Use accessors to page table entries instead of direct dereference +- riscv: mm: Only compile pgtable.c if MMU +- mm: Introduce pudp/p4dp/pgdp_get() functions +- riscv: Use WRITE_ONCE() when setting page table entries +- NFSv4: Add missing rescheduling points in nfs_client_return_marked_delegations +- ata: pata_macio: Use WARN instead of BUG +- spi: spi-fsl-lpspi: limit PRESCALE bit in TCR register +- MIPS: cevt-r4k: Don't call get_c0_compare_int if timer irq is installed +- lib/generic-radix-tree.c: Fix rare race in __genradix_ptr_alloc() +- of/irq: Prevent device address out-of-bounds read in interrupt map walk +- usbnet: ipheth: race between ipheth_close and error handling +- s390/vmlinux.lds.S: Move ro_after_init section behind rodata section +- btrfs: initialize location to fix -Wmaybe-uninitialized in btrfs_lookup_dentry() +- kselftests: dmabuf-heaps: Ensure the driver name is null-terminated +- i3c: mipi-i3c-hci: Error out instead on BUG_ON() in IBI DMA setup +- i3c: master: svc: resend target address when get NACK +- vfs: Fix potential circular locking through setxattr() and removexattr() +- regmap: maple: work around gcc-14.1 false-positive warning +- LoongArch: Use correct API to map cmdline in relocate_kernel() +- net: dpaa: avoid on-stack arrays of NR_CPUS elements +- Bluetooth: btnxpuart: Fix Null pointer dereference in btnxpuart_flush() +- tcp: Don't drop SYN+ACK for simultaneous connect(). +- riscv: set trap vector earlier +- cxl/region: Verify target positions using the ordered target list +- btrfs: replace BUG_ON with ASSERT in walk_down_proc() +- fs/ntfs3: Check more cases when directory is corrupted +- smp: Add missing destroy_work_on_stack() call in smp_call_on_cpu() +- drm/amdgpu: reject gang submit on reserved VMIDs +- dma-mapping: benchmark: Don't starve others when doing the test +- ext4: fix possible tid_t sequence overflows +- drm/amdgpu: Set no_hw_access when VF request full GPU fails +- libbpf: Add NULL checks to bpf_object__{prev_map,next_map} +- ASoc: TAS2781: replace beXX_to_cpup with get_unaligned_beXX for potentially broken alignment +- hwmon: (nct6775-core) Fix underflows seen when writing limit attributes +- crypto: qat - fix unintentional re-enabling of error interrupts +- scsi: pm80xx: Set phy->enable_completion only when we wait for it +- virtio_ring: fix KMSAN error for premapped mode +- devres: Initialize an uninitialized struct member +- cgroup: Protect css->cgroup write under css_set_lock +- iommu/vt-d: Handle volatile descriptor status read +- dm init: Handle minors larger than 255 +- ASoC: topology: Properly initialize soc_enum values +- phy: zynqmp: Take the phy mutex in xlate +- firmware: cs_dsp: Don't allow writes to read-only controls +- xen: privcmd: Fix possible access to a freed kirqfd instance +- selftests: net: enable bind tests +- net: dsa: vsc73xx: fix possible subblocks range of CAPT block +- net: bridge: br_fdb_external_learn_add(): always set EXT_LEARN +- r8152: fix the firmware doesn't work +- fou: Fix null-ptr-deref in GRO. +- bareudp: Fix device stats updates. +- bpf, net: Fix a potential race in do_sock_getsockopt() +- net/socket: Break down __sys_getsockopt +- net/socket: Break down __sys_setsockopt +- bpf: Add sockptr support for setsockopt +- bpf: Add sockptr support for getsockopt +- usbnet: modern method to get random MAC +- ice: do not bring the VSI up, if it was down before the XDP setup +- ice: protect XDP configuration with a mutex +- igc: Unlock on error in igc_io_resume() +- Bluetooth: MGMT: Fix not generating command complete for MGMT_OP_DISCONNECT +- Bluetooth: hci_sync: Introduce hci_cmd_sync_run/hci_cmd_sync_run_once +- Bluetooth: hci_sync: Attempt to dequeue connection attempt +- Bluetooth: hci_sync: Add helper functions to manipulate cmd_sync queue +- Bluetooth: hci_conn: Fix UAF Write in __hci_acl_create_connection_sync +- Bluetooth: Remove pending ACL connection attempts +- Bluetooth: hci_conn: Only do ACL connections sequentially +- Bluetooth: hci_event: Use HCI error defines instead of magic values +- Bluetooth: qca: If memdump doesn't work, re-enable IBS +- can: kvaser_pciefd: Use a single write when releasing RX buffers +- can: kvaser_pciefd: Move reset of DMA RX buffers to the end of the ISR +- can: kvaser_pciefd: Rename board_irq to pci_irq +- can: kvaser_pciefd: Remove unnecessary comment +- can: kvaser_pciefd: Skip redundant NULL pointer check in ISR +- regulator: core: Stub devm_regulator_bulk_get_const() if !CONFIG_REGULATOR +- platform/x86: dell-smbios: Fix error path in dell_smbios_init() +- ice: Add netif_device_attach/detach into PF reset flow +- igb: Fix not clearing TimeSync interrupts for 82580 +- cifs: Fix FALLOC_FL_ZERO_RANGE to preflush buffered part of target region +- rust: kbuild: fix export of bss symbols +- rust: Use awk instead of recent xargs +- can: mcp251xfd: fix ring configuration when switching from CAN-CC to CAN-FD mode +- can: m_can: Release irq on error in m_can_open +- drm/amdgpu: check for LINEAR_ALIGNED correctly in check_tiling_flags_gfx6 +- pcmcia: Use resource_size function on resource object +- media: qcom: camss: Add check for v4l2_fwnode_endpoint_parse +- Input: ili210x - use kvmalloc() to allocate buffer for firmware update +- PCI: keystone: Add workaround for Errata #i2037 (AM65x SR 1.0) +- ice: Check all ice_vsi_rebuild() errors in function +- vfio/spapr: Always clear TCEs before unsetting the window +- media: vivid: don't set HDMI TX controls if there are no HDMI outputs +- drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts +- drm/amdgpu: Fix smatch static checker warning +- drm/amd/display: Check HDCP returned status +- usb: uas: set host status byte on data completion error +- wifi: brcmsmac: advertise MFP_CAPABLE to enable WPA3 +- leds: spi-byte: Call of_node_put() on error path +- media: vivid: fix wrong sizeimage value for mplane +- riscv: kprobes: Use patch_text_nosync() for insn slots +- fs/ntfs3: One more reason to mark inode bad +- wifi: iwlwifi: mvm: use IWL_FW_CHECK for link ID check +- netfilter: nf_conncount: fix wrong variable type +- iommu: sun50i: clear bypass register +- x86/kmsan: Fix hook for unaligned accesses +- af_unix: Remove put_pid()/put_cred() in copy_peercred(). +- irqchip/armada-370-xp: Do not allow mapping IRQ 0 and 1 +- accel/habanalabs/gaudi2: unsecure edma max outstanding register +- bpf, verifier: Correct tail_call_reachable for bpf prog +- smack: unix sockets: fix accept()ed socket label +- wifi: ath12k: fix uninitialize symbol error on ath12k_peer_assoc_h_he() +- ALSA: hda: Add input value sanity checks to HDMI channel map controls +- ALSA: control: Apply sanity check of input values for user elements +- drm/i915: Do not attempt to load the GSC multiple times +- nilfs2: fix state management in error path of log writing function +- sched: sch_cake: fix bulk flow accounting logic for host fairness +- ila: call nf_unregister_net_hooks() sooner +- tcp_bpf: fix return value of tcp_bpf_sendmsg() +- Revert "drm/amdgpu: align pp_power_profile_mode with kernel docs" +- x86/apic: Make x2apic_disable() work correctly +- x86/fpu: Avoid writing LBR bit to IA32_XSS unless supported +- net: mctp-serial: Fix missing escapes on transmit +- tracing/timerlat: Add interface_lock around clearing of kthread in stop_kthread() +- tracing: Avoid possible softlockup in tracing_iter_reset() +- tracing/timerlat: Only clear timer if a kthread exists +- mm: vmalloc: ensure vmap_block is initialised before adding to queue +- kexec_file: fix elfcorehdr digest exclusion when CONFIG_CRASH_HOTPLUG=y +- clk: qcom: clk-alpha-pll: Fix the trion pll postdiv set rate API +- clk: qcom: clk-alpha-pll: Fix the pll post div mask +- clk: starfive: jh7110-sys: Add notifier for PLL0 clock +- fuse: fix memory leak in fuse_create_open +- fuse: use unsigned type for getxattr/listxattr size truncation +- fuse: update stats for pages in dropped aux writeback list +- mmc: cqhci: Fix checking of CQHCI_HALT state +- mmc: sdhci-of-aspeed: fix module autoloading +- mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K +- mmc: core: apply SD quirks earlier during probe +- Bluetooth: MGMT: Ignore keys being loaded with invalid type +- Revert "Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE" +- rust: macros: provide correct provenance when constructing THIS_MODULE +- rust: types: Make Opaque::get const +- nvme-pci: Add sleep quirk for Samsung 990 Evo +- x86/kaslr: Expose and use the end of the physical memory address space +- irqchip/gic-v2m: Fix refcount leak in gicv2m_of_init() +- x86/tdx: Fix data leak in mmio_read() +- ksmbd: Unlock on in ksmbd_tcp_set_interfaces() +- ALSA: hda/realtek: Support mute LED on HP Laptop 14-dq2xxx +- ALSA: hda/realtek: add patch for internal mic in Lenovo V145 +- ALSA: hda/conexant: Add pincfg quirk to enable top speakers on Sirius devices +- KVM: SVM: Don't advertise Bus Lock Detect to guest if SVM support is missing +- KVM: SVM: fix emulation of msr reads/writes of MSR_FS_BASE and MSR_GS_BASE +- net: microchip: vcap: Fix use-after-free error in kunit test +- !12289 CVE-2024-46691 +- usb: typec: ucsi: Move unregister out of atomic section +- !12223 [sync] PR-11910: ext4: dax: Fix inconsistent isize during writing +- ext4: dax: keep orphan list before truncate overflow allocated blocks +- ext4: dax: fix overflowing extents beyond inode size when partially writing +- !12146 mm: page_cache_ra_order: Restore 'PF_MEMALLOC_NOFS' flag in 'fallback' branch +- mm: page_cache_ra_order: Restore 'PF_MEMALLOC_NOFS' flag in 'fallback' branch +- !12090 USB: usbtmc: prevent kernel-usb-infoleak +- USB: usbtmc: prevent kernel-usb-infoleak +- !12286 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.49-6.6.50 LTS Patches +- i2c: Use IS_REACHABLE() for substituting empty ACPI functions +- virtio_net: Fix napi_skb_cache_put warning +- media: uvcvideo: Enforce alignment of frame and interval +- drm/amd/display: Check BIOS images before it is used +- drm/amd/display: use preferred link settings for dp signal only +- drm/amd/display: Correct the defined value for AMDGPU_DMUB_NOTIFICATION_MAX +- drm/amd/display: added NULL check at start of dc_validate_stream +- drm/amd/display: Don't use fsleep for PSR exit waits on dmub replay +- drm/amdgpu: add lock in kfd_process_dequeue_from_device +- drm/amdgpu: add lock in amdgpu_gart_invalidate_tlb +- drm/amdgpu: add skip_hw_access checks for sriov +- block: remove the blk_flush_integrity call in blk_integrity_unregister +- f2fs: fix to do sanity check on blocks for inline_data inode +- wifi: cfg80211: make hash table duplicates more survivable +- dmaengine: altera-msgdma: properly free descriptor in msgdma_free_descriptor +- dmaengine: altera-msgdma: use irq variant of spin_lock/unlock while invoking callbacks +- gfs2: Revert "Add quota_change type" +- crypto: stm32/cryp - call finalize with bh disabled +- drm/meson: plane: Add error handling +- platform/chrome: cros_ec_lpc: MEC access can use an AML mutex +- smack: tcp: ipv4, fix incorrect labeling +- regmap: spi: Fix potential off-by-one when calculating reserved size +- drm/amdgu: fix Unintentional integer overflow for mall size +- net: remove NULL-pointer net parameter in ip_metrics_convert +- fsnotify: clear PARENT_WATCHED flags lazily +- usb: typec: ucsi: Fix null pointer dereference in trace +- usbip: Don't submit special requests twice +- media: v4l2-cci: Always assign *val +- rcu/nocb: Remove buggy bypass lock contention mitigation +- pwm: xilinx: Fix u32 overflow issue in 32-bit width PWM mode. +- ionic: fix potential irq name truncation +- RDMA/efa: Properly handle unexpected AQ completions +- soc: qcom: smem: Add qcom_smem_bust_hwspin_lock_by_host() +- hwspinlock: Introduce hwspin_lock_bust() +- wifi: mac80211: check ieee80211_bss_info_change_notify() against MLD +- PCI: al: Check IORESOURCE_BUS existence during probe +- cpufreq: scmi: Avoid overflow of target_freq in fast switch +- wifi: iwlwifi: remove fw_running op +- drm/amdgpu: update type of buf size to u32 for eeprom functions +- drm/kfd: Correct pinned buffer handling at kfd restore and validate process +- wifi: rtw89: ser: avoid multiple deinit on same CAM +- drm/amd/pm: check negtive return for table entries +- drm/amd/pm: check specific index for smu13 +- drm/amd/pm: check specific index for aldebaran +- drm/amdgpu/pm: Check input value for CUSTOM profile mode setting on legacy SOCs +- wifi: ath11k: initialize 'ret' in ath11k_qmi_load_file_target_mem() +- wifi: ath12k: initialize 'ret' in ath12k_qmi_load_file_target_mem() +- drm/amdkfd: Reconcile the definition and use of oem_id in struct kfd_topology_device +- drm/amdgpu: fix mc_data out-of-bounds read warning +- drm/amdgpu: Fix out-of-bounds read of df_v1_7_channel_number +- drm/amdkfd: Check debug trap enable before write dbg_ev_file +- drm/amdgpu: Fix the uninitialized variable warning +- drm/amdgpu/pm: Fix uninitialized variable agc_btc_response +- drm/amdgpu/pm: Fix uninitialized variable warning for smu10 +- drm/amd/pm: fix uninitialized variable warnings for vangogh_ppt +- drm/amd/amdgpu: Check tbo resource pointer +- drm/amd/display: Fix Coverity INTEGER_OVERFLOW within decide_fallback_link_setting_max_bw_policy +- drm/amd/display: Spinlock before reading event +- drm/amd/display: Fix Coverity INTEGER_OVERFLOW within dal_gpio_service_create +- drm/amd/display: Fix Coverity INTERGER_OVERFLOW within construct_integrated_info +- drm/amd/display: Check num_valid_sets before accessing reader_wm_sets[] +- drm/amd/display: Stop amdgpu_dm initialize when stream nums greater than 6 +- drm/amdgpu: avoid reading vf2pf info size from FB +- drm/amd/pm: fix uninitialized variable warnings for vega10_hwmgr +- drm/amd/pm: fix warning using uninitialized value of max_vid_step +- drm/amd/pm: fix uninitialized variable warning for smu8_hwmgr +- drm/amd/pm: fix uninitialized variable warning +- drm/amdgpu/pm: Check the return value of smum_send_msg_to_smc +- drm/amdgpu: fix overflowed array index read warning +- drm/amdgpu: Fix uninitialized variable warning in amdgpu_afmt_acr +- selftests: mptcp: join: stop transfer when check is done (part 2.2) +- selftests: mptcp: join: disable get and dump addr checks +- selftests: mptcp: join: test for flush/re-add endpoints +- selftests: mptcp: join: check re-adding init endp with != id +- selftests: mptcp: join: check re-using ID of unused ADD_ADDR +- selftests: mptcp: add explicit test case for remove/readd +- selftests: mptcp: join: cannot rm sf if closed +- selftests: mptcp: declare event macros in mptcp_lib +- selftests: mptcp: userspace pm get addr tests +- selftests: mptcp: dump userspace addrs list +- mptcp: pm: fix RM_ADDR ID for the initial subflow +- mptcp: make pm_remove_addrs_and_subflows static +- ASoC: codecs: ES8326: button detect issue +- ASoC: amd: yc: Support mic on Lenovo Thinkpad E14 Gen 6 +- net: usb: qmi_wwan: add MeiG Smart SRM825L +- dma-debug: avoid deadlock between dma debug vs printk and netconsole +- i2c: Fix conditional for substituting empty ACPI functions +- ASoC: amd: yc: Support mic on HP 14-em0002la +- smb: client: fix FSCTL_GET_REPARSE_POINT against NetApp +- net/mlx5: DR, Fix 'stack guard page was hit' error in dr_rule +- ALSA: seq: ump: Explicitly reset RPN with Null RPN +- ALSA: seq: ump: Transmit RPN/NRPN message at each MSB/LSB data reception +- ALSA: seq: ump: Use the common RPN/bank conversion context +- ALSA: ump: Explicitly reset RPN with Null RPN +- ALSA: ump: Transmit RPN/NRPN message at each MSB/LSB data reception +- ALSA: hda/conexant: Mute speakers at suspend / shutdown +- ALSA: hda/generic: Add a helper to mute speakers at suspend/shutdown +- btrfs: tree-checker: validate dref root and objectid +- scsi: ufs: core: Bypass quick recovery if force reset is needed +- scsi: ufs: core: Check LSDBS cap when !mcq +- drm: panel-orientation-quirks: Add quirk for OrangePi Neo +- drm/fb-helper: Don't schedule_work() to flush frame buffer during panic() +- !12281 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.48-6.6.49 LTS Patches +- apparmor: fix policy_unpack_test on big endian systems +- arm64: dts: freescale: imx93-tqma9352-mba93xxla: fix typo +- arm64: dts: freescale: imx93-tqma9352: fix CMA alloc-ranges +- arm64: dts: imx93: update default value for snps,clk-csr +- arm64: dts: imx93: add nvmem property for eqos +- arm64: dts: imx93: add nvmem property for fec1 +- arm64: dts: imx8mp-beacon-kit: Fix Stereo Audio on WM8962 +- ARM: dts: omap3-n900: correct the accelerometer orientation +- usb: cdnsp: fix for Link TRB with TC +- usb: cdnsp: fix incorrect index in cdnsp_get_hw_deq function +- usb: core: sysfs: Unmerge @usb3_hardware_lpm_attr_group in remove_power_attributes() +- usb: dwc3: st: add missing depopulate in probe error path +- usb: dwc3: core: Prevent USB core invalid event buffer address access +- usb: dwc3: omap: add missing depopulate in probe error path +- ARM: dts: imx6dl-yapp43: Increase LED current to match the yapp4 HW design +- USB: serial: option: add MeiG Smart SRM825L +- scsi: sd: Ignore command SYNCHRONIZE CACHE error if format in progress +- firmware: qcom: scm: Mark get_wq_ctx() as atomic call +- cdc-acm: Add DISABLE_ECHO quirk for GE HealthCare UI Controller +- soc: qcom: pmic_glink: Fix race during initialization +- soc: qcom: pmic_glink: Actually communicate when remote goes down +- soc: qcom: cmd-db: Map shared memory as WC, not WB +- nfc: pn533: Add poll mod list filling check +- net: busy-poll: use ktime_get_ns() instead of local_clock() +- drm/amd/display: avoid using null object of framebuffer +- sctp: fix association labeling in the duplicate COOKIE-ECHO case +- gtp: fix a potential NULL pointer dereference +- bonding: change ipsec_lock from spin lock to mutex +- bonding: extract the use of real_device into local variable +- bonding: implement xdo_dev_state_free and call it after deletion +- selftests: forwarding: local_termination: Down ports on cleanup +- selftests: forwarding: no_forwarding: Down ports on cleanup +- netfilter: nf_tables_ipv6: consider network offset in netdev/egress validation +- wifi: iwlwifi: fw: fix wgds rev 3 exact size +- netfilter: nf_tables: restore IP sanity checks for netdev/egress +- iommu: Do not return 0 from map_pages if it doesn't do anything +- Bluetooth: hci_core: Fix not handling hibernation actions +- Bluetooth: btnxpuart: Fix random crash seen while removing driver +- Bluetooth: btnxpuart: Handle FW Download Abort scenario +- Bluetooth: btnxpuart: Resolve TX timeout error in power save stress test +- dmaengine: dw: Add memory bus width verification +- dmaengine: dw: Add peripheral bus width verification +- phy: xilinx: phy-zynqmp: Fix SGMII linkup failure on resume +- dmaengine: dw-edma: Do not enable watermark interrupts for HDMA +- dmaengine: dw-edma: Fix unmasking STOP and ABORT interrupts for HDMA +- soundwire: stream: fix programming slave ports for non-continous port maps +- phy: fsl-imx8mq-usb: fix tuning parameter name +- iommufd: Do not allow creating areas without READ or WRITE +- cifs: Fix FALLOC_FL_PUNCH_HOLE support +- mm: Fix missing folio invalidation calls during truncation +- ovl: ovl_parse_param_lowerdir: Add missed ' +- pinctrl: starfive: jh7110: Correct the level trigger configuration of iev register +- pinctrl: mediatek: common-v2: Fix broken bias-disable for PULL_PU_PD_RSEL_TYPE +- ASoC: SOF: amd: Fix for acp init sequence +- ASoC: amd: acp: fix module autoloading +- thermal: of: Fix OF node leak in of_thermal_zone_find() error paths +- thermal: of: Fix OF node leak in thermal_of_trips_init() error path +- of: Introduce for_each_*_child_of_node_scoped() to automate of_node_put() handling +- usb: typec: fix up incorrectly backported "usb: typec: tcpm: unregister existing source caps before re-registration" +- drm/vmwgfx: Fix prime with external buffers +- drm/amdgpu/swsmu: always force a state reprogram on init +- drm/amdgpu: align pp_power_profile_mode with kernel docs +- selftests: mptcp: join: check re-re-adding ID 0 endp +- selftests: mptcp: join: no extra msg if no counter +- selftests: mptcp: join: check removing ID 0 endpoint +- mptcp: pm: ADD_ADDR 0 is not a new address +- mptcp: pm: fix ID 0 endp usage after multiple re-creations +- mptcp: pm: do not remove already closed subflows +- mptcp: pm: send ACK on an active subflow +- mptcp: pm: reset MPC endp ID when re-added +- mptcp: pm: skip connecting to already established sf +- mptcp: pm: reuse ID 0 after delete and re-add +- mptcp: sched: check both backup in retrans +- mptcp: close subflow when receiving TCP+FIN +- net: mana: Fix race of mana_hwc_post_rx_wqe and new hwc response +- wifi: mwifiex: duplicate static structs used in driver instances +- wifi: wfx: repair open network AP mode +- of: Add cleanup.h based auto release via __free(device_node) markings +- pinctrl: single: fix potential NULL dereference in pcs_get_function() +- pinctrl: rockchip: correct RK3328 iomux width flag for GPIO2-B pins +- btrfs: run delayed iputs when flushing delalloc +- LoongArch: Remove the unused dma-direct.h +- ALSA: seq: Skip event type filtering for UMP events +- !12276 mm: mem_reliable: Initialize reliable_nr_page when mm_init() +- mm: mem_reliable: Initialize reliable_nr_page when mm_init() +- !12178 net: stmmac: move the EST lock to struct stmmac_priv +- net: stmmac: move the EST lock to struct stmmac_priv +- !12181 net: ena: Add validation for completion descriptors consistency +- net: ena: Add validation for completion descriptors consistency +- !12255 drm/amd/display: Ensure index calculation will not overflow +- drm/amd/display: Ensure index calculation will not overflow +- !12214 platform/x86: panasonic-laptop: Fix SINF array out of bounds accesses +- platform/x86: panasonic-laptop: Fix SINF array out of bounds accesses +- !12147 wifi: iwlwifi: mvm: don't wait for tx queues if firmware is dead +- wifi: iwlwifi: mvm: don't wait for tx queues if firmware is dead +- !9955 [OLK-6.6]HYGON: CSV3 patch series part 1 (Secure memory management and initialization for CSV3) +- crypto: ccp: Add SET_SMR/SET_SMCR commands for CSV3 +- x86/mm: Manage CSV3 guest's private memory by CMA +- crypto: ccp: Define CSV3 key management command id +- KVM: SEV: Pin SEV guest memory out of CMA area +- !12253 RDMA/hns: Fix flush cqe error when racing with destroy qp +- RDMA/hns: Fix flush cqe error when racing with destroy qp +- !12217 v2 RDMA/hns: Fix new mmaped pages during resetting +- RDMA/hns: Fix new mmaped pages during resetting +- !12216 ACPI/IORT: Add PMCG platform information for HiSilicon HIP10/11 +- ACPI/IORT: Add PMCG platform information for HiSilicon HIP10/11 +- !12209 net/hinic3: fix version showed in ethtool +- net/hinic3: fix version showed in ethtool +- !12218 KVM: x86: Acquire kvm->srcu when handling KVM_SET_VCPU_EVENTS +- KVM: x86: Acquire kvm->srcu when handling KVM_SET_VCPU_EVENTS +- !11667 Adds Nebula S1000 series network snic driver +- Net:nbl_core: Add nbl_core-driver for nebula-matrix S1055AS series smart NIC. +- !12036 KVM: arm64: Add new HiSi CPU type for supporting DVMBM +- KVM: arm64: Add new HiSi CPU type for supporting DVMBM +- !12112 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.47-6.6.48 LTS Patches +- Revert "s390/dasd: Establish DMA alignment" +- ksmbd: fix race condition between destroy_previous_session() and smb2 operations() +- drm/amdgpu/vcn: not pause dpg for unified queue +- drm/amdgpu/vcn: identify unified queue in sw init +- selftests/bpf: Add a test to verify previous stacksafe() fix +- ALSA: timer: Relax start tick time check for slave timer elements +- igc: Fix qbv tx latency by setting gtxoffset +- drm/panel: nt36523: Set 120Hz fps for xiaomi,elish panels +- drm/msm/mdss: specify cfg bandwidth for SDM670 +- hwmon: (ltc2992) Fix memory leak in ltc2992_parse_dt() +- Revert "drm/amd/display: Validate hw_points_num before using it" +- Revert "usb: gadget: uvc: cleanup request when not in correct state" +- selftests: mptcp: join: check re-using ID of closed subflow +- selftests: mptcp: join: validate fullmesh endp on 1st sf +- mptcp: pm: fullmesh: select the right ID later +- mptcp: pm: only in-kernel cannot have entries with ID 0 +- mptcp: pm: check add_addr_accept_max before accepting new ADD_ADDR +- mptcp: pm: only mark 'subflow' endp as available +- mptcp: pm: remove mptcp_pm_remove_subflow() +- mptcp: pm: re-using ID of unused flushed subflows +- mptcp: pm: re-using ID of unused removed subflows +- mptcp: pm: re-using ID of unused removed ADD_ADDR +- nouveau/firmware: use dma non-coherent allocator +- pmdomain: imx: wait SSAR when i.MX93 power domain on +- pmdomain: imx: scu-pd: Remove duplicated clocks +- mmc: dw_mmc: allow biu and ciu clocks to defer +- mmc: mtk-sd: receive cmd8 data when hs400 tuning fail +- KVM: arm64: Make ICC_*SGI*_EL1 undef in the absence of a vGICv3 +- cxgb4: add forgotten u64 ivlan cast before shift +- Input: i8042 - use new forcenorestore quirk to replace old buggy quirk combination +- Input: i8042 - add forcenorestore quirk to leave controller untouched even on s3 +- HID: wacom: Defer calculation of resolution until resolution_code is known +- MIPS: Loongson64: Set timer mode in cpu-probe +- net: dsa: microchip: fix PTP config failure when using multiple ports +- drm/amdgpu: Validate TA binary size +- ksmbd: the buffer of smb2 query dir response has at least 1 byte +- scsi: core: Fix the return value of scsi_logical_block_count() +- smb: client: ignore unhandled reparse tags +- drm/msm: fix the highest_bank_bit for sc7180 +- drm/msm/mdss: Handle the reg bus ICC path +- drm/msm/mdss: Rename path references to mdp_path +- drm/msm/mdss: switch mdss to use devm_of_icc_get() +- drm/msm/dpu: take plane rotation into account for wide planes +- drm/msm/dpu: try multirect based on mdp clock limits +- drm/msm/dpu: cleanup FB if dpu_format_populate_layout fails +- drm/msm/dp: reset the link phy params before link training +- drm/msm/dpu: move dpu_encoder's connector assignment to atomic_enable() +- drm/msm/dpu: capture snapshot on the first commit_done timeout +- drm/msm/dpu: split dpu_encoder_wait_for_event into two functions +- drm/msm/dpu: drop MSM_ENC_VBLANK support +- drm/msm/dpu: use drmm-managed allocation for dpu_encoder_phys +- drm/msm/dp: fix the max supported bpp logic +- drm/msm/dpu: don't play tricks with debug macros +- net: ovs: fix ovs_drop_reasons error +- net: xilinx: axienet: Fix dangling multicast addresses +- net: xilinx: axienet: Always disable promiscuous mode +- octeontx2-af: Fix CPT AF register offset calculation +- netfilter: flowtable: validate vlan header +- udp: fix receiving fraglist GSO packets +- igb: cope with large MAX_SKB_FRAGS +- dpaa2-switch: Fix error checking in dpaa2_switch_seed_bp() +- ice: fix truesize operations for PAGE_SIZE >= 8192 +- ice: fix ICE_LAST_OFFSET formula +- ice: fix page reuse when PAGE_SIZE is over 8k +- bonding: fix xfrm state handling when clearing active slave +- bonding: fix xfrm real_dev null pointer dereference +- bonding: fix null pointer deref in bond_ipsec_offload_ok +- bonding: fix bond_ipsec_offload_ok return type +- ip6_tunnel: Fix broken GRO +- netfilter: nft_counter: Synchronize nft_counter_reset() against reader. +- netfilter: nft_counter: Disable BH in nft_counter_offload_stats(). +- net: mctp: test: Use correct skb for route input check +- selftests: udpgro: report error when receive failed +- tc-testing: don't access non-existent variable on exception +- net: mscc: ocelot: serialize access to the injection/extraction groups +- net: mscc: ocelot: fix QoS class for injected packets with "ocelot-8021q" +- net: mscc: ocelot: use ocelot_xmit_get_vlan_info() also for FDMA and register injection +- Bluetooth: SMP: Fix assumption of Central always being Initiator +- Bluetooth: hci_core: Fix LE quote calculation +- drm/amdkfd: reserve the BO before validating it +- ALSA: hda/tas2781: Use correct endian conversion +- platform/surface: aggregator: Fix warning when controller is destroyed in probe +- drm/amd/amdgpu: command submission parser for JPEG +- drm/amd/display: fix cursor offset on rotation 180 +- drm/amd/display: Enable otg synchronization logic for DCN321 +- drm/amd/display: Adjust cursor position +- btrfs: send: allow cloning non-aligned extent if it ends at i_size +- btrfs: replace sb::s_blocksize by fs_info::sectorsize +- mm/vmalloc: fix page mapping if vm_area_alloc_pages() with high order fallback to order 0 +- selftests: memfd_secret: don't build memfd_secret test on unsupported arches +- selftests/mm: log run_vmtests.sh results in TAP format +- tools/testing/selftests/mm/run_vmtests.sh: lower the ptrace permissions +- dm suspend: return -ERESTARTSYS instead of -EINTR +- riscv: entry: always initialize regs->a0 to -ENOSYS +- i2c: stm32f7: Add atomic_xfer method to driver +- jfs: define xtree root and page independently +- nvme: fix namespace removal list +- EDAC/skx_common: Allow decoding of SGX addresses +- ionic: check cmd_regs before copying in or out +- ionic: use pci_is_enabled not open code +- hrtimer: Prevent queuing of hrtimer without a function callback +- drm/amdgpu: fix dereference null return value for the function amdgpu_vm_pt_parent +- nvme: use srcu for iterating namespace list +- selftests/bpf: Fix a few tests for GCC related warnings. +- nvmet-rdma: fix possible bad dereference when freeing rsps +- irqchip/gic-v3-its: Remove BUG_ON in its_vpe_irq_domain_alloc +- usb: dwc3: core: Skip setting event buffers for host only controllers +- platform/x86: lg-laptop: fix %s null argument warning +- clocksource: Make watchdog and suspend-timing multiplication overflow safe +- irqchip/renesas-rzg2l: Do not set TIEN and TINT source at the same time +- s390/iucv: fix receive buffer virtual vs physical address confusion +- openrisc: Call setup_memory() earlier in the init sequence +- NFS: avoid infinite loop in pnfs_update_layout. +- nvmet-tcp: do not continue for invalid icreq +- rtc: nct3018y: fix possible NULL dereference +- firmware: cirrus: cs_dsp: Initialize debugfs_root to invalid +- Bluetooth: bnep: Fix out-of-bound access +- nvme: clear caller pointer on identify failure +- usb: gadget: fsl: Increase size of name buffer for endpoints +- f2fs: fix to do sanity check in update_sit_entry +- btrfs: delete pointless BUG_ON check on quota root in btrfs_qgroup_account_extent() +- btrfs: change BUG_ON to assertion in tree_move_down() +- btrfs: send: handle unexpected inode in header process_recorded_refs() +- btrfs: send: handle unexpected data in header buffer in begin_cmd() +- btrfs: handle invalid root reference found in may_destroy_subvol() +- btrfs: push errors up from add_async_extent() +- btrfs: tests: allocate dummy fs_info and root in test_find_delalloc() +- btrfs: change BUG_ON to assertion when checking for delayed_node root +- btrfs: defrag: change BUG_ON to assertion in btrfs_defrag_leaves() +- btrfs: delayed-inode: drop pointless BUG_ON in __btrfs_remove_delayed_item() +- powerpc/boot: Only free if realloc() succeeds +- powerpc/boot: Handle allocation failure in simple_realloc() +- f2fs: stop checkpoint when get a out-of-bounds segment +- rxrpc: Don't pick values out of the wire header when setting up security +- parisc: Use irq_enter_rcu() to fix warning at kernel/context_tracking.c:367 +- memory: stm32-fmc2-ebi: check regmap_read return value +- x86: Increase brk randomness entropy for 64-bit systems +- md: clean up invalid BUG_ON in md_ioctl +- netlink: hold nlk->cb_mutex longer in __netlink_dump_start() +- tick: Move got_idle_tick away from common flags +- clocksource/drivers/arm_global_timer: Guard against division by zero +- accel/habanalabs: fix debugfs files permissions +- virtiofs: forbid newlines in tags +- hrtimer: Select housekeeping CPU during migration +- gpio: sysfs: extend the critical section for unregistering sysfs devices +- drm/lima: set gp bus_stop bit before hard reset +- net/sun3_82586: Avoid reading past buffer in debug output +- wifi: iwlwifi: mvm: avoid garbage iPN +- media: drivers/media/dvb-core: copy user arrays safely +- scsi: lpfc: Initialize status local variable in lpfc_sli4_repost_sgl_list() +- fs: binfmt_elf_efpic: don't use missing interpreter's properties +- media: pci: cx23885: check cx23885_vdev_init() return +- kernfs: fix false-positive WARN(nr_mmapped) in kernfs_drain_open_files +- riscv: blacklist assembly symbols for kprobe +- quota: Remove BUG_ON from dqget() +- wifi: ath12k: Add missing qmi_txn_cancel() calls +- fuse: fix UAF in rcu pathwalks +- afs: fix __afs_break_callback() / afs_drop_open_mmap() race +- btrfs: zlib: fix and simplify the inline extent decompression +- ext4: do not trim the group with corrupted block bitmap +- nvmet-trace: avoid dereferencing pointer too early +- EDAC/skx_common: Filter out the invalid address +- gfs2: Refcounting fix in gfs2_thaw_super +- Bluetooth: hci_conn: Check non NULL function before calling for HFP offload +- evm: don't copy up 'security.evm' xattr +- drm/rockchip: vop2: clear afbc en and transform bit for cluster window at linear mode +- ionic: no fw read when PCI reset failed +- ionic: prevent pci disable of already disabled device +- powerpc/pseries/papr-sysparm: Validate buffer object lengths +- hwmon: (pc87360) Bounds check data->innr usage +- ASoC: SOF: ipc4: check return value of snd_sof_ipc_msg_data +- powerpc/xics: Check return value of kasprintf in icp_native_map_one_cpu +- memory: tegra: Skip SID programming if SID registers aren't set +- drm/msm: Reduce fallout of fence signaling vs reclaim hangs +- arm64: Fix KASAN random tag seed initialization +- powerpc/topology: Check if a core is online +- cpu/SMT: Enable SMT only if a core is online +- rust: fix the default format for CONFIG_{RUSTC,BINDGEN}_VERSION_TEXT +- rust: suppress error messages from CONFIG_{RUSTC,BINDGEN}_VERSION_TEXT +- rust: work around `bindgen` 0.69.0 issue +- hwmon: (ltc2992) Avoid division by zero +- IB/hfi1: Fix potential deadlock on &irq_src_lock and &dd->uctxt_lock +- clk: visconti: Add bounds-checking coverage for struct visconti_pll_provider +- wifi: iwlwifi: check for kmemdup() return value in iwl_parse_tlv_firmware() +- wifi: iwlwifi: fw: Fix debugfs command sending +- wifi: iwlwifi: abort scan when rfkill on but device enabled +- gfs2: setattr_chown: Add missing initialization +- wifi: mac80211: flush STA queues on unauthorization +- scsi: spi: Fix sshdr use +- ASoC: SOF: Intel: hda-dsp: Make sure that no irq handler is pending before suspend +- iommu/arm-smmu-qcom: Add SDM670 MDSS compatible +- media: qcom: venus: fix incorrect return value +- drm/tegra: Zero-initialize iosys_map +- binfmt_misc: cleanup on filesystem umount +- accel/habanalabs: fix bug in timestamp interrupt handling +- accel/habanalabs: export dma-buf only if size/offset multiples of PAGE_SIZE +- accel/habanalabs/gaudi2: unsecure tpc count registers +- media: s5p-mfc: Fix potential deadlock on condlock +- staging: ks7010: disable bh on tx_dev_lock +- drm/amd/display: Validate hw_points_num before using it +- usb: gadget: uvc: cleanup request when not in correct state +- wifi: mt76: fix race condition related to checking tx queue fill status +- staging: iio: resolver: ad2s1210: fix use before initialization +- wifi: ath11k: fix ath11k_mac_op_remain_on_channel() stack usage +- media: radio-isa: use dev_name to fill in bus_info +- drm/amdkfd: Move dma unmapping after TLB flush +- i3c: mipi-i3c-hci: Do not unmap region not mapped for transfer +- i3c: mipi-i3c-hci: Remove BUG() when Ring Abort request times out +- wifi: ath12k: fix WARN_ON during ath12k_mac_update_vif_chan +- drm/bridge: tc358768: Attempt to fix DSI horizontal timings +- s390/smp,mcck: fix early IPI handling +- RDMA/rtrs: Fix the problem of variable not initialized fully +- i2c: riic: avoid potential division by zero +- cgroup: Avoid extra dereference in css_populate_dir() +- wifi: cw1200: Avoid processing an invalid TIM IE +- sched/topology: Handle NUMA_NO_NODE in sched_numa_find_nth_cpu() +- net: ethernet: mtk_wed: check update_wo_rx_stats in mtk_wed_update_rx_stats() +- rcu: Eliminate rcu_gp_slow_unregister() false positive +- rcu: Dump memory object info if callback function is invalid +- mm: Remove kmem_valid_obj() +- wifi: iwlwifi: mvm: fix recovery flow in CSA +- wifi: mac80211: fix BA session teardown race +- wifi: cfg80211: check wiphy mutex is held for wdev mutex +- wifi: mac80211: lock wiphy in IP address notifier +- ASoC: cs35l45: Checks index of cs35l45_irqs[] +- ssb: Fix division by zero issue in ssb_calc_clock_rate +- drm/amdgpu: access RLC_SPM_MC_CNTL through MMIO in SRIOV runtime +- drm/amd/amdgpu/imu_v11_0: Increase buffer size to ensure all possible values can be stored +- drm/amd/pm: fix error flow in sensor fetching +- ALSA: hda/realtek: Fix noise from speakers on Lenovo IdeaPad 3 15IAU7 +- gpio: mlxbf3: Support shutdown() function +- netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests +- netfilter: nf_tables: Introduce nf_tables_getobj_single +- netfilter: nf_tables: Carry reset boolean in nft_obj_dump_ctx +- netfilter: nf_tables: nft_obj_filter fits into cb->ctx +- netfilter: nf_tables: Carry s_idx in nft_obj_dump_ctx +- netfilter: nf_tables: A better name for nft_obj_filter +- netfilter: nf_tables: Unconditionally allocate nft_obj_filter +- netfilter: nf_tables: Drop pointless memset in nf_tables_dump_obj +- netfilter: nf_tables: Audit log dump reset after the fact +- netfilter: nf_queue: drop packets with cloned unconfirmed conntracks +- netfilter: flowtable: initialise extack before use +- netfilter: allow ipv6 fragments to arrive on different devices +- tcp: Update window clamping condition +- mptcp: correct MPTCP_SUBFLOW_ATTR_SSN_OFFSET reserved size +- mlxbf_gige: disable RX filters until RX path initialized +- net: ethernet: mtk_wed: fix use-after-free panic in mtk_wed_setup_tc_block_cb() +- net: dsa: vsc73xx: check busy flag in MDIO operations +- net: dsa: vsc73xx: use read_poll_timeout instead delay loop +- net: dsa: vsc73xx: pass value in phy_write operation +- net: axienet: Fix register defines comment description +- atm: idt77252: prevent use after free in dequeue_rx() +- net/mlx5e: Correctly report errors for ethtool rx flows +- igc: Fix reset adapter logics when tx mode change +- igc: Fix qbv_config_change_errors logics +- igc: Fix packet still tx after gate close by reducing i226 MAC retry buffer +- bpf: Fix updating attached freplace prog in prog_array map +- s390/uv: Panic for set and remove shared access UVC errors +- drm/amdgpu/jpeg4: properly set atomics vmid field +- drm/amdgpu/jpeg2: properly set atomics vmid field +- memcg_write_event_control(): fix a user-triggerable oops +- drm/amdgpu: Actually check flags for all context ops. +- btrfs: tree-checker: add dev extent item checks +- btrfs: zoned: properly take lock to read/update block group's zoned variables +- btrfs: tree-checker: reject BTRFS_FT_UNKNOWN dir type +- mm/memory-failure: use raw_spinlock_t in struct memory_failure_cpu +- selinux: add the processing of the failure of avc_add_xperms_decision() +- selinux: fix potential counting error in avc_add_xperms_decision() +- wifi: brcmfmac: cfg80211: Handle SSID based pmksa deletion +- net: mana: Fix RX buf alloc_size alignment and atomic op panic +- i2c: qcom-geni: Add missing geni_icc_disable in geni_i2c_runtime_resume +- btrfs: rename bitmap_set_bits() -> btrfs_bitmap_set_bits() +- dm persistent data: fix memory allocation failure +- dm resume: don't return EINVAL when signalled +- arm64: ACPI: NUMA: initialize all values of acpi_early_node_map to NUMA_NO_NODE +- ACPI: EC: Evaluate _REG outside the EC scope more carefully +- ACPICA: Add a depth argument to acpi_execute_reg_methods() +- riscv: change XIP's kernel_map.size to be size of the entire kernel +- KVM: s390: fix validity interception issue when gisa is switched off +- s390/dasd: fix error recovery leading to data corruption on ESE devices +- ALSA: hda/tas2781: fix wrong calibrated data order +- thunderbolt: Mark XDomain as unplugged when router is removed +- xhci: Fix Panther point NULL pointer deref at full-speed re-enumeration +- ALSA: usb-audio: Support Yamaha P-125 quirk entry +- ALSA: usb-audio: Add delay quirk for VIVO USB-C-XE710 HEADSET +- char: xillybus: Refine workqueue handling +- char: xillybus: Don't destroy workqueue from work item running on it +- selinux: revert our use of vma_is_initial_heap() +- Revert "usb: typec: tcpm: clear pd_event queue in PORT_RESET" +- Revert "misc: fastrpc: Restrict untrusted app to attach to privileged PD" +- Revert "ACPI: EC: Evaluate orphan _REG under EC device" +- tty: atmel_serial: use the correct RTS flag. +- !12087 arm64: acpi: Harden get_cpu_for_acpi_id() against missing CPU entry +- arm64: acpi: Harden get_cpu_for_acpi_id() against missing CPU entry +- !6996 sched/fair: Optimize performance by inlining cpu_util_without() and cpu_util() +- sched/fair: Optimize performance by inlining cpu_util_without() and cpu_util() +- !12080 btrfs: clean up our handling of refs == 0 in snapshot delete +- btrfs: clean up our handling of refs == 0 in snapshot delete +- !12052 drm/amdgpu: the warning dereferencing obj for nbio_v7_4 +- drm/amdgpu: the warning dereferencing obj for nbio_v7_4 +- !12082 userfaultfd: don't BUG_ON() if khugepaged yanks our page table +- userfaultfd: don't BUG_ON() if khugepaged yanks our page table +- !12077 ELF: fix kernel.randomize_va_space double read +- ELF: fix kernel.randomize_va_space double read +- !12068 usb: gadget: aspeed_udc: validate endpoint index for ast udc +- usb: gadget: aspeed_udc: validate endpoint index for ast udc +- !12057 netfilter: nft_socket: fix sk refcount leaks +- netfilter: nft_socket: fix sk refcount leaks +- !11954 drm/amdgpu: fix the waring dereferencing hive +- drm/amdgpu: fix the waring dereferencing hive +- !12059 mptcp: pm: Fix uaf in __timer_delete_sync +- mptcp: pm: Fix uaf in __timer_delete_sync +- !12058 net: dpaa: Pad packets to ETH_ZLEN +- net: dpaa: Pad packets to ETH_ZLEN +- !12076 drm/bridge: tc358767: Check if fully initialized before signalling HPD event via IRQ +- drm/bridge: tc358767: Check if fully initialized before signalling HPD event via IRQ +- !11966 drm/amd/pm: Fix negative array index read +- drm/amd/pm: Fix negative array index read + +' for pr_err +* Thu Oct 10 2024 ZhangPeng - 6.6.0-46.0.0.51 +- !12061 net/mlx5: Fix bridge mode operations when there are no VFs +- net/mlx5: Fix bridge mode operations when there are no VFs +- !12074 drm/amd/display: Check index for aux_rd_interval before using +- drm/amd/display: Check index for aux_rd_interval before using +- !12063 cpufreq: intel_pstate: Revise global turbo disable check +- cpufreq: intel_pstate: Revise global turbo disable check +- !12051 um: line: always fill *error_out in setup_one_line() +- um: line: always fill *error_out in setup_one_line() +- !12023 ASoC: meson: axg-card: fix 'use-after-free' +- ASoC: meson: axg-card: fix 'use-after-free' +- !12022 drm/amd/display: Check gpio_id before used as array index +- drm/amd/display: Check gpio_id before used as array index +- !12049 drm/amd/display: Skip inactive planes within ModeSupportAndSystemConfiguration +- drm/amd/display: Skip inactive planes within ModeSupportAndSystemConfiguration +- !11949 mptcp: pm: only decrement add_addr_accepted for MPJ req +- mptcp: pm: only decrement add_addr_accepted for MPJ req +- !11763 [OLK-6.6] Intel: Backport to support Intel IFS(In Field Scan) SBAF on GNR +- platform/x86/intel/ifs: Fix SBAF title underline length +- trace: platform/x86/intel/ifs: Add SBAF trace support +- platform/x86/intel/ifs: Add SBAF test support +- platform/x86/intel/ifs: Add SBAF test image loading support +- platform/x86/intel/ifs: Refactor MSR usage in IFS test code +- selftests: ifs: verify IFS ARRAY BIST functionality +- selftests: ifs: verify IFS scan test functionality +- selftests: ifs: verify test image loading functionality +- selftests: ifs: verify test interfaces are created by the driver +- platform/x86/intel/ifs: Disable irq during one load stage +- platform/x86/intel/ifs: trace: display batch num in hex +- platform/x86/intel/ifs: Classify error scenarios correctly +- platform/x86/intel/ifs: Remove unnecessary initialization of 'ret' +- platform/x86/intel/ifs: Add an entry rendezvous for SAF +- platform/x86/intel/ifs: Replace the exit rendezvous with an entry rendezvous for ARRAY_BIST +- platform/x86/intel/ifs: Add current batch number to trace output +- platform/x86/intel/ifs: Trace on all HT threads when executing a test +- !12039 drm/amd/display: Stop amdgpu_dm initialize when link nums greater than max_links +- drm/amd/display: Stop amdgpu_dm initialize when link nums greater than max_links +- !12033 sysctl: always initialize i_uid/i_gid +- sysctl: always initialize i_uid/i_gid +- !12014 dma-buf: heaps: Fix off-by-one in CMA heap fault handler +- dma-buf: heaps: Fix off-by-one in CMA heap fault handler +- !12009 rtmutex: Drop rt_mutex::wait_lock before scheduling +- rtmutex: Drop rt_mutex::wait_lock before scheduling +- !11617 v2 Fix VSYNC referencing an unmapped VPE on GIC v4.0/v4.1 +- irqchip/gic-v3-its: Fix VSYNC referencing an unmapped VPE on GIC v4.0 +- irqchip/gic-v3-its: Fix VSYNC referencing an unmapped VPE on GIC v4.1 +- !12016 perf/x86/intel: Limit the period on Haswell +- perf/x86/intel: Limit the period on Haswell +- !12017 cppc_cpufreq: Fix possible null pointer dereference +- cppc_cpufreq: Fix possible null pointer dereference +- !11995 drm/amd/display: Assign linear_pitch_alignment even for VM +- drm/amd/display: Assign linear_pitch_alignment even for VM +- !11796 bpf: Take return from set_memory_rox() into account with bpf_jit_binary_lock_ro() +- bpf: Take return from set_memory_rox() into account with bpf_jit_binary_lock_ro() +- !12004 spi: rockchip: Resolve unbalanced runtime PM / system PM handling +- spi: rockchip: Resolve unbalanced runtime PM / system PM handling +- !12000 nvmet-tcp: fix kernel crash if commands allocation fails +- nvmet-tcp: fix kernel crash if commands allocation fails +- !11969 drm/amd/display: Run DC_LOG_DC after checking link->link_enc +- drm/amd/display: Run DC_LOG_DC after checking link->link_enc +- !11963 serial: sc16is7xx: fix invalid FIFO access with special register set +- serial: sc16is7xx: fix invalid FIFO access with special register set +- !11985 Fix CVE-2024-46845 +- tracing/osnoise: Fix build when timerlat is not enabled +- tracing/timerlat: Only clear timer if a kthread exists +- !11909 ksmbd: unset the binding mark of a reused connection +- ksmbd: unset the binding mark of a reused connection +- !11983 wifi: ath12k: fix firmware crash due to invalid peer nss +- wifi: ath12k: fix firmware crash due to invalid peer nss +- !11984 drm/amd/display: Add array index check for hdcp ddc access +- drm/amd/display: Add array index check for hdcp ddc access +- !11989 drm/amd/display: Fix index may exceed array range within fpu_update_bw_bounding_box +- drm/amd/display: Fix index may exceed array range within fpu_update_bw_bounding_box +- !11992 scsi: lpfc: Handle mailbox timeouts in lpfc_get_sfp_info +- scsi: lpfc: Handle mailbox timeouts in lpfc_get_sfp_info +- !11979 CVE-2024-46814 +- drm/amd/display: Check msg_id before processing transcation +- !11960 scsi: ufs: core: Remove SCSI host only if added +- scsi: ufs: core: Remove SCSI host only if added +- !11944 drm/amdgpu: Fix the warning division or modulo by zero +- drm/amdgpu: Fix the warning division or modulo by zero +- !11971 sched: Support to enable/disable dynamic_affinity +- sched: Support to enable/disable dynamic_affinity +- !11951 net: phy: Fix missing of_node_put() for leds +- net: phy: Fix missing of_node_put() for leds +- !11956 Fix CVE-2024-44958 6.6 +- sched/smt: Fix unbalance sched_smt_present dec/inc +- sched/smt: Introduce sched_smt_present_inc/dec() helper +- !11945 btrfs: don't BUG_ON on ENOMEM from btrfs_lookup_extent_info() in walk_down_proc() +- btrfs: don't BUG_ON on ENOMEM from btrfs_lookup_extent_info() in walk_down_proc() +- !11919 btrfs: fix race between direct IO write and fsync when using same fd +- btrfs: fix race between direct IO write and fsync when using same fd +- !11920 hwmon: (lm95234) Fix underflows seen when writing limit attributes +- hwmon: (lm95234) Fix underflows seen when writing limit attributes +- !11820 powerpc/qspinlock: Fix deadlock in MCS queue +- powerpc/qspinlock: Fix deadlock in MCS queue +- !11915 ethtool: check device is present when getting link settings +- ethtool: check device is present when getting link settings +- !11936 btrfs: remove NULL transaction support for btrfs_lookup_extent_info() +- btrfs: remove NULL transaction support for btrfs_lookup_extent_info() +- !11929 Merge some hns RoCE patches from the mainline to OLK-6.6 +- RDMA/hns: Fix the overflow risk of hem_list_calc_ba_range() +- RDMA/hns: Fix Use-After-Free of rsv_qp on HIP08 +- Revert "RDMA/hns: Fix Use-After-Free of rsv_qp" +- Revert "RDMA/hns: Fix the overflow risk of hem_list_calc_ba_range()" +- !11912 smb: client: fix double put of @cfile in smb2_set_path_size() +- smb: client: fix double put of @cfile in smb2_set_path_size() +- !11908 HID: amd_sfh: free driver_data after destroying hid device +- HID: amd_sfh: free driver_data after destroying hid device +- !11926 nilfs2: protect references to superblock parameters exposed in sysfs +- nilfs2: protect references to superblock parameters exposed in sysfs +- !11927 hwmon: (hp-wmi-sensors) Check if WMI event data exists +- hwmon: (hp-wmi-sensors) Check if WMI event data exists +- !11844 fix CVE-2024-46771 +- can: bcm: Clear bo->bcm_proc_read after remove_proc_entry(). +- can: bcm: Remove proc entry when dev is unregistered. +- !11885 pci/hotplug/pnv_php: Fix hotplug driver crash on Powernv +- pci/hotplug/pnv_php: Fix hotplug driver crash on Powernv +- !11795 i2c: tegra: Do not mark ACPI devices as irq safe +- i2c: tegra: Do not mark ACPI devices as irq safe +- !11804 drm/amdgpu: Fix out-of-bounds write warning +- drm/amdgpu: Fix out-of-bounds write warning +- !11901 scsi: aacraid: Fix double-free on probe failure +- scsi: aacraid: Fix double-free on probe failure +- !11859 char: xillybus: Check USB endpoints when probing device +- char: xillybus: Check USB endpoints when probing device +- !11865 pktgen: use cpus_read_lock() in pg_net_init() +- pktgen: use cpus_read_lock() in pg_net_init() +- !11876 btrfs: handle errors from btrfs_dec_ref() properly +- btrfs: handle errors from btrfs_dec_ref() properly +- !11893 tracing/osnoise: Use a cpumask to know what threads are kthreads +- tracing/osnoise: Use a cpumask to know what threads are kthreads +- !11840 userfaultfd: fix checks for huge PMDs +- userfaultfd: fix checks for huge PMDs +- !11891 wifi: rtw88: usb: schedule rx work after everything is set up +- wifi: rtw88: usb: schedule rx work after everything is set up +- !11860 VMCI: Fix use-after-free when removing resource in vmci_resource_remove() +- VMCI: Fix use-after-free when removing resource in vmci_resource_remove() +- !11870 NFSD: Reset cb_seq_status after NFS4ERR_DELAY +- NFSD: Reset cb_seq_status after NFS4ERR_DELAY +- !11874 fix CVE-2024-46701 +- libfs: fix infinite directory reads for offset dir +- fs: fix kabi kroken in struct offset_ctx +- libfs: Convert simple directory offsets to use a Maple Tree +- test_maple_tree: testing the cyclic allocation +- maple_tree: Add mtree_alloc_cyclic() +- libfs: Add simple_offset_empty() +- libfs: Define a minimum directory offset +- libfs: Re-arrange locking in offset_iterate_dir() +- !11689 smb: client: fix double put of @cfile in smb2_rename_path() +- smb: client: fix double put of @cfile in smb2_rename_path() +- !11883 usb: dwc3: st: fix probed platform device ref count on probe error path +- usb: dwc3: st: fix probed platform device ref count on probe error path +- !11884 PCI: Add missing bridge lock to pci_bus_lock() +- PCI: Add missing bridge lock to pci_bus_lock() +- !11862 hwmon: (w83627ehf) Fix underflows seen when writing limit attributes +- hwmon: (w83627ehf) Fix underflows seen when writing limit attributes +- !11758 smb/client: avoid dereferencing rdata=NULL in smb2_new_read_req() +- smb/client: avoid dereferencing rdata=NULL in smb2_new_read_req() +- !11857 arm64/mpam: Fix redefined reference of 'mpam_detect_is_enabled' +- arm64/mpam: Fix redefined reference of 'mpam_detect_is_enabled' +- !11823 mmc: mmc_test: Fix NULL dereference on allocation failure +- mmc: mmc_test: Fix NULL dereference on allocation failure +- !11819 uio_hv_generic: Fix kernel NULL pointer dereference in hv_uio_rescind +- uio_hv_generic: Fix kernel NULL pointer dereference in hv_uio_rescind +- !11495 ext4: Fix race in buffer_head read fault injection +- ext4: Fix race in buffer_head read fault injection +- !11845 bpf: verifier: prevent userspace memory access +- bpf: verifier: prevent userspace memory access +- !11748 ASoC: dapm: Fix UAF for snd_soc_pcm_runtime object +- ASoC: dapm: Fix UAF for snd_soc_pcm_runtime object +- !11624 Fix iBMA bug and change version +- BMA: Fix edma driver initialization problem and change the version number. +- !11850 misc: fastrpc: Fix double free of 'buf' in error path +- misc: fastrpc: Fix double free of 'buf' in error path +- !11655 drm/amd/display: Check denominator pbn_div before used +- drm/amd/display: Check denominator pbn_div before used +- !11686 udf: Avoid excessive partition lengths +- udf: Avoid excessive partition lengths +- !11685 binder: fix UAF caused by offsets overwrite +- binder: fix UAF caused by offsets overwrite +- !11798 CVE-2024-46784 +- net: mana: Fix error handling in mana_create_txq/rxq's NAPI cleanup +- net: mana: Fix doorbell out of order violation and avoid unnecessary doorbell rings +- !11814 selinux,smack: don't bypass permissions check in inode_setsecctx hook +- selinux,smack: don't bypass permissions check in inode_setsecctx hook +- !11811 apparmor: fix possible NULL pointer dereference +- apparmor: fix possible NULL pointer dereference +- !11681 net/mlx5e: SHAMPO, Fix incorrect page release +- net/mlx5e: SHAMPO, Fix incorrect page release +- !11679 wifi: mwifiex: Do not return unused priv in mwifiex_get_priv_by_id() +- wifi: mwifiex: Do not return unused priv in mwifiex_get_priv_by_id() +- !11672 netem: fix return value if duplicate enqueue fails +- netem: fix return value if duplicate enqueue fails +- !11783 mm: hwpoison: two more poison recovery +- mm: support poison recovery from copy_present_page() +- mm: support poison recovery from do_cow_fault() +- !11787 nilfs2: fix missing cleanup on rollforward recovery error +- nilfs2: fix missing cleanup on rollforward recovery error +- !11744 powerpc/rtas: Prevent Spectre v1 gadget construction in sys_rtas() +- powerpc/rtas: Prevent Spectre v1 gadget construction in sys_rtas() +- !11766 drm/amd/display: Check denominator crb_pipes before used +- drm/amd/display: Check denominator crb_pipes before used +- !11790 efi/libstub: add checking validity of memory regions +- efi/libstub: add checking validity of memory regions +- !11802 can: mcp251x: fix deadlock if an interrupt occurs during mcp251x_open +- can: mcp251x: fix deadlock if an interrupt occurs during mcp251x_open +- !11747 [OLK 6.6] some bugfixes for hns3 +- net: hns3: fix concurrent setting vlan filter issue +- net: hns3: fix snprintf() is printing too much problem +- net: hns3: make sure ptp clock is unregister and freed if hclge_ptp_get_cycle returns an error +- net: hns3: fix spelling mistake "reg_um" -> "reg_num" +- net: hns3: fixed hclge_fetch_pf_reg accesses bar space out of bounds issue +- net: hns3:support enable or disable pfc strom prevent +- net: hns3: fix wrong use of semaphore up + +* Wed Sep 25 2024 ZhangPeng - 6.6.0-44.0.0.50 +- !11769 tools: move alignment-related macros to new +- tools: move alignment-related macros to new +- !11753 driver: iio: add missing checks on iio_info's callback access +- driver: iio: add missing checks on iio_info's callback access +- !11740 hwmon: (adc128d818) Fix underflows seen when writing limit attributes +- hwmon: (adc128d818) Fix underflows seen when writing limit attributes +- !11733 Input: MT - limit max slots +- Input: MT - limit max slots +- !11757 arm64/mpam: Check mpam_detect_is_enabled() before accessing MPAM registers +- arm64/mpam: Check mpam_detect_is_enabled() before accessing MPAM registers +- Revert "arm64: head.S: Initialise MPAM EL2 registers and disable traps" +- !11543 Fix CVE-2024-45025 +- fix bitmap corruption on close_range() with CLOSE_RANGE_UNSHARE +- bitmap: introduce generic optimized bitmap_size() +- fs/ntfs3: add prefix to bitmap_size() and use BITS_TO_U64() +- s390/cio: rename bitmap_size() -> idset_bitmap_size() +- !11713 btrfs: fix qgroup reserve leaks in cow_file_range +- btrfs: fix qgroup reserve leaks in cow_file_range +- !11725 Squashfs: sanity check symbolic link size +- Squashfs: sanity check symbolic link size +- !11715 btrfs: replace BUG_ON() with error handling at update_ref_for_cow() +- btrfs: replace BUG_ON() with error handling at update_ref_for_cow() +- !11714 CVE-2024-46751 +- btrfs: don't BUG_ON() when 0 reference count at btrfs_lookup_extent_info() +- btrfs: reduce nesting for extent processing at btrfs_lookup_extent_info() +- btrfs: remove superfluous metadata check at btrfs_lookup_extent_info() +- !11717 CVE-2024-43904 +- drm/amd/display: Add null checks for 'stream' and 'plane' before dereferencing +- !11718 CVE-2024-41008 +- drm/amdgpu: change vm->task_info handling +- !11691 sch/netem: fix use after free in netem_dequeue +- sch/netem: fix use after free in netem_dequeue +- !11719 rtla/osnoise: Prevent NULL dereference in error handling +- rtla/osnoise: Prevent NULL dereference in error handling +- !11626 smb/server: fix potential null-ptr-deref of lease_ctx_info in smb2_open() +- smb/server: fix potential null-ptr-deref of lease_ctx_info in smb2_open() +- !11651 large folio: Performance and bugfix +- mm: remove invalidate_inode_page() +- mm: convert isolate_page() to mf_isolate_folio() +- mm: convert soft_offline_in_use_page() to use a folio +- mm: use mapping_evict_folio() in truncate_error_page() +- mm: convert __do_fault() to use a folio +- mm: make mapping_evict_folio() the preferred way to evict clean folios +- tmpfs: fault in smaller chunks if large folio allocation not allowed +- mm,tmpfs: consider end of file write in shmem_is_huge +- mm: shmem: move shmem_huge_global_enabled() into shmem_allowable_huge_orders() +- mm: shmem: rename shmem_is_huge() to shmem_huge_global_enabled() +- mm: shmem: simplify the suitable huge orders validation for tmpfs +- !11644 drm/amdgpu: fix dereference after null check +- drm/amdgpu: fix dereference after null check +- !11675 【OLK 6.6】net: hns3: some bugfixes for hns3 driver +- net: hns3: Resolved the issue that the debugfs query result is inconsistent. +- net: hns3: fixed reset failure issues caused by the incorrect reset type +- net: hns3: fix missing features due to dev->features configuration too early +- net: hns3: fix a deadlock problem when config TC during resetting +- net: hns3: add sync command to sync io-pgtable +- net: hns3: default enable tx bounce buffer when smmu enabled +- net: hns3: don't add the len of vlan head if skb_vlan_pop failed +- net: hns3: void array out of bound when loop tnl_num +- net: hns3: use correct release function during uninitialization +- net: hns3: delete redundant enabling actions for Layer 2 fowarding +- !11721 v3 mm/migration: do not folio copy in MIGRATE_SYNC_NO_COPY mode +- mm/migration: do not folio copy in MIGRATE_SYNC_NO_COPY mode +- !8819 Add support for Hygon model 7h processors +- perf/x86/uncore: Add L3 PMU support for Hygon family 18h model 7h +- EDAC/amd64: Add support for Hygon family 18h model 7h +- x86/amd_nb: Add support for Hygon family 18h model 7h +- !11157 [OLK-6.6] Support Hygon Trusted Key Management run on CSV Guest +- drivers/crypto/ccp: add ioctl API to pin TKM hugepage +- driver/crypto/ccp: fix vtkm without C-bit when host SME deactivate +- drivers/crypto/ccp: support TKM run on CSV +- drivers/crypto/ccp: remove multi-level pointers processing for vpsp +- !11669 cgroup-psi-add-PSI_STATE_LAST-for-kabi-reserve +- cgroup/psi: add PSI_STATE_LAST for kabi reserve +- !11666 drm/amd/pm: fix the Out-of-bounds read warning +- drm/amd/pm: fix the Out-of-bounds read warning +- !11607 tty: serial: fsl_lpuart: mark last busy before uart_add_one_port +- tty: serial: fsl_lpuart: mark last busy before uart_add_one_port +- !11646 net: hns3: fix a deadlock problem when config TC during resetting +- net: hns3: fix a deadlock problem when config TC during resetting +- !11648 vsock: fix recursive ->recvmsg calls +- vsock: fix recursive ->recvmsg calls +- !11656 fix CVE-2024-46714 +- drm/amd/display: Skip wbscl_set_scaler_filter if filter is null +- !11631 fix CVE-2024-46723 +- drm/amdgpu: fix ucode out-of-bounds read warning +- !11642 HID: cougar: fix slab-out-of-bounds Read in cougar_report_fixup +- HID: cougar: fix slab-out-of-bounds Read in cougar_report_fixup +- !11638 Fix CVE-2024-44991 +- tcp: do not export tcp_twsk_purge() +- tcp: prevent concurrent execution of tcp_sk_exit_batch +- tcp/dccp: do not care about families in inet_twsk_purge() +- tcp/dccp: bypass empty buckets in inet_twsk_purge() +- !11608 v3 arm64: perf: Add support for event counting threshold +- perf: arm_pmuv3: Avoid assigning fixed cycle counter with threshold +- arm: perf: Fix ARCH=arm build with GCC +- Revert "perf/arm_dmc620: Remove duplicate format attribute #defines" +- Documentation: arm64: Document the PMU event counting threshold feature +- arm64: perf: Add support for event counting threshold +- arm: pmu: Move error message and -EOPNOTSUPP to individual PMUs +- perf/arm_dmc620: Remove duplicate format attribute #defines +- arm: pmu: Share user ABI format mechanism with SPE +- arm64: perf: Include threshold control fields in PMEVTYPER mask +- arm: perf: Convert remaining fields to use GENMASK +- arm: perf: Use GENMASK for PMMIR fields +- arm: perf/kvm: Use GENMASK for ARMV8_PMU_PMCR_N +- arm: perf: Remove inlines from arm_pmuv3.c +- drivers: perf: arm_pmuv3: Add new macro PMUV3_INIT_MAP_EVENT() +- KVM: arm64: PMU: Add a helper to read a vCPU's PMCR_EL0 +- KVM: arm64: Add PMU event filter bits required if EL3 is implemented +- KVM: arm64: Make PMEVTYPER_EL0.NSH RES0 if EL2 isn't advertised +- drivers: perf: arm_pmuv3: Drop some unused arguments from armv8_pmu_init() +- drivers: perf: arm_pmuv3: Read PMMIR_EL1 unconditionally +- !11629 CVE-2024-46785 +- eventfs: Use list_del_rcu() for SRCU protected list variable +- !11641 mm: set hugepage to false when anon mthp allocation +- mm: set hugepage to false when anon mthp allocation +- !11559 mm/ksm: fix possible UAF of stable_node +- mm/ksm: fix possible UAF of stable_node +- !11613 Input: uinput - reject requests with unreasonable number of slots +- Input: uinput - reject requests with unreasonable number of slots +- !11460 mptcp: pm: avoid possible UaF when selecting endp +- mptcp: pm: avoid possible UaF when selecting endp +- !11598 net/mlx5e: Take state lock during tx timeout reporter +- net/mlx5e: Take state lock during tx timeout reporter +- !11618 RDMA/hns: Fix ah error counter in sw stat not increasing +- RDMA/hns: Fix ah error counter in sw stat not increasing +- !11554 Some patches of RDMA from Linux to openEuler-6.6 +- RDMA/hns: Fix restricted __le16 degrades to integer issue +- RDMA/hns: Optimize hem allocation performance +- RDMA/hns: Fix 1bit-ECC recovery address in non-4K OS +- RDMA/hns: Fix VF triggering PF reset in abnormal interrupt handler +- RDMA/hns: Fix spin_unlock_irqrestore() called with IRQs enabled +- !11566 v2 tracefs: Use generic inode RCU for synchronizing freeing +- tracefs: Use generic inode RCU for synchronizing freeing +- !11609 fscache: delete fscache_cookie_lru_timer when fscache exits to avoid UAF +- fscache: delete fscache_cookie_lru_timer when fscache exits to avoid UAF +- !11474 fs/netfs/fscache_cookie: add missing "n_accesses" check +- fs/netfs/fscache_cookie: add missing "n_accesses" check +- !11563 iommu: Restore lost return in iommu_report_device_fault() +- iommu: Restore lost return in iommu_report_device_fault() +- !11569 support poison recover from migrate folio +- fs: hugetlbfs: support poisoned recover from hugetlbfs_migrate_folio() +- mm: migrate: support poisoned recover from migrate folio +- mm: migrate: split folio_migrate_mapping() +- mm: add folio_mc_copy() +- mm: move memory_failure_queue() into copy_mc_[user]_highpage() +- mm: migrate: remove migrate_folio_extra() +- mm: migrate_device: unify migrate folio for MIGRATE_SYNC_NO_COPY +- mm: migrate: simplify __buffer_migrate_folio() +- !8822 Add support for Hygon model 10h processors +- ALSA: hda: Add support for Hygon family 18h model 10h HD-Audio +- hwmon/k10temp: Add support for Hygon family 18h model 10h +- EDAC/amd64: Add support for Hygon family 18h model 10h +- x86/amd_nb: Add support for Hygon family 18h model 10h +- x86/cpu: Get LLC ID for Hygon family 18h model 10h +- !11594 gtp: pull network headers in gtp_dev_xmit() +- gtp: pull network headers in gtp_dev_xmit() +- !11573 btrfs: fix a use-after-free when hitting errors inside btrfs_submit_chunk() +- btrfs: fix a use-after-free when hitting errors inside btrfs_submit_chunk() +- !11585 vfs: Don't evict inode under the inode lru traversing context +- vfs: Don't evict inode under the inode lru traversing context +- !11461 bnxt_en: Fix double DMA unmapping for XDP_REDIRECT +- bnxt_en: Fix double DMA unmapping for XDP_REDIRECT + +* Wed Sep 18 2024 ZhangPeng - 6.6.0-42.0.0.49 +- !11556 bpf: Fix a kernel verifier crash in stacksafe() +- bpf: Fix a kernel verifier crash in stacksafe() +- !11496 virtcca feature:Fix warnings +- virtcca feature: fix warnings +- !11531 [OLK-6.6]Some updates for HiSilicon PCIe PMU +- drivers/perf: hisi_pcie: Export supported Root Ports [bdf_min, bdf_max] +- drivers/perf: hisi_pcie: Fix TLP headers bandwidth counting +- drivers/perf: hisi_pcie: Record hardware counts correctly +- !11546 ata: libata: Fix memory leak for error path in ata_host_alloc() +- ata: libata: Fix memory leak for error path in ata_host_alloc() +- !11551 mm/memory_hotplug: prevent accessing by index=-1 +- mm/memory_hotplug: prevent accessing by index=-1 +- !11522 ipv6: prevent UAF in ip6_send_skb() +- ipv6: prevent UAF in ip6_send_skb() +- !11518 ipv6: fix possible UAF in ip6_finish_output2() +- ipv6: fix possible UAF in ip6_finish_output2() +- !11515 net: dsa: mv88e6xxx: Fix out-of-bound access +- net: dsa: mv88e6xxx: Fix out-of-bound access +- !11513 ipv6: prevent possible UAF in ip6_xmit() +- ipv6: prevent possible UAF in ip6_xmit() +- !11503 mm: mTHP user controls to pagecache large folio +- mm/huge_memory: allow to enable 64K anouymous mapping align alone +- mm/huge_memory: mTHP user controls to pagecache large folio +- !5453 Add GM Driver Support for Hygon platform(Cryptographic Coprocessor,OLK-6.6) +- hct: fix fork issue when use hct in virtual machine +- hct: support 1024 processes simutaneously in the hct-mdev mode. +- hct: change the maximum number of supported ccps from 16 to 48. +- hct: fix build issue when the module mdev is disabled. +- hct: supporting memory encryption in host and wb set in vm +- hct: add mediated ccp driver support for hygon crypto technology. +- crypto: ccp: support sm2 on Hygon generation 4th CPU +- crypto: ccp: remove repeated sm4-hs mode +- crypto: ccp: Process multiple VQ commands once for SM4/SM4-CTR ccp. +- crypto: ccp: Process multiple VQ commands once for SM3 ccp. +- crypto: ccp: Modify value of COMMANDS_PER_QUEUE from 16 to 8192. +- crypto: ccp: fix bug that SM2 encryption of long data causes kernel crash +- crypto: ccp: fix sm2 test failed in testmgr because of missing DER coding +- crypto: ccp: Fix a problem that vq thread may stuck when do multi process test. +- crypto: ccp: Only handle interrupts by completion. +- crypto: ccp: It prompt ILLEGAL_MEM_ADDR when using PSPCCP. +- crypto: ccp: fix sm2 not return due to wrong complete callback parameter +- crypto: ccp: Support SM4 algorithm for hygon ccp. +- crypto: ccp: Support SM3 algorithm for hygon ccp. +- crypto: ccp: Support SM2 algorithm for hygon ccp. +- !11485 Bugfix introduced when support folio +- mm/shmem: replace HPAGE_PMD_ORDER with PMD_ORDER in shmem_alloc_folio() +- mm: huge_memory: add memory reliable count in __discard_anon_folio_pmd_locked() +- mm: limit order to 0 when allocated from dynamic pool +- !11469 OLK-6.6 Revert gpiolib bugfix +- gpiolib: acpi: Fix failed in acpi_gpiochip_find() by adding parent node match +- Revert "gpiolib: acpi: Fix failed in acpi_gpiochip_find() by adding parent node match" +- !11464 mm/ksm: fix ksm_zero_pages accounting +- mm_types: Fix kabi breakage in struct mm_struct +- mm/ksm: fix ksm_zero_pages accounting +- !11411 f2fs: fix null reference error when checking end of zone +- f2fs: fix null reference error when checking end of zone +- !11465 【olk 6.6】net: hns3: some bugfixes for netdev +- net: hns3: fix kernel crash when 1588 is sent on HIP08 devices +- net: hns3: initialize reset_timer before hclgevf_misc_irq_init() +- net: hns3: don't auto enable misc vector +- !11454 nfs: fix memory leak in error path of nfs4_do_reclaim +- nfs: fix memory leak in error path of nfs4_do_reclaim +- !11421 Some fixes About cpuset partition +- cgroup/cpuset: Clear effective_xcpus on cpus_allowed clearing only if cpus.exclusive not set +- cgroup/cpuset: fix panic caused by partcmd_update +- cgroup/cpuset: Fix remote root partition creation problem +- cgroup/cpuset: Optimize isolated partition only generate_sched_domains() calls +- !11455 v2 CVE-2024-44972 +- btrfs: fix invalid mapping of extent xarray state +- btrfs: do not clear page dirty inside extent_write_locked_range() + +* Fri Sep 06 2024 ZhangPeng - 6.6.0-41.0.0.48 +- !11443 v2 drm/amd/display: Fix null pointer deref in dcn20_resource.c +- drm/amd/display: Fix null pointer deref in dcn20_resource.c +- !11433 ext4: Track data blocks freeing operation in journal +- ext4: Track data blocks freeing operation in journal +- !11063 virtcca feature: secure smmu init +- virtcca feature: secure smmu doc +- virtcca feature: secure smmu init +- !11206 kprobe support %pd/%pD type +- selftests/ftrace: Fix required features for VFS type test case +- selftests/ftrace: add fprobe test cases for VFS type "%pd" and "%pD" +- selftests/ftrace: add kprobe test cases for VFS type "%pd" and "%pD" +- Documentation: tracing: add new type '%pd' and '%pD' for kprobe +- tracing/probes: support '%pD' type for print struct file's name +- tracing/probes: support '%pd' type for print struct dentry's name +- !10875 Incorporate some bonding patches as follows(OLK-6.6) +- RDMA/hns: Fix concurrency issue between bond work and bond event +- RDMA/hns: Fix UAF in clear bond printing +- RDMA/hns: Encapsulate upper event and lowerstate event handlers +- RDMA/hns: Register notifier block of bonding events in bond_grp +- !11304 iomap: fault in smaller chunks for non-large folio mappings +- iomap: fault in smaller chunks for non-large folio mappings +- !11397 fuse: Initialize beyond-EOF page contents before setting uptodate +- fuse: Initialize beyond-EOF page contents before setting uptodate +- !11303 【OLK-6.6】ROH sync patch from OLK-5.10 +- roh/core: Avoid null pointer access and optimize code. +- Revert "RDMA/hns: Support RDMA_CM in ROH mode" +- RDMA/hns: Support getting GRH for UD in RoH mode when NLP = 0 +- roh/core: Support macvlan in roh. +- roh/hns3: Add ROH client case in hclgevf_init_client_instance. +- roh/hns3: Fix IMP reset vlan unusable. +- !11363 kcm: Serialise kcm_sendmsg() for the same socket. +- kcm: Serialise kcm_sendmsg() for the same socket. +- !11381 mm/dynamic_pool: use batch to add free pages to dpool +- mm/dynamic_pool: use batch to add free pages to dpool +- !11355 ext4: Fix wrong da count caused by concurrent racing on extent tree +- ext4: Fix wrong da count caused by concurrent racing on extent tree +- !11335 Revert SPI bugfixs +- spi: hisi-kunpeng: Add validation for the minimum value of speed_hz +- spi: hisi-kunpeng: Add verification for the max_frequency provided by the firmware +- Revert "spi: hisi-kunpeng: Add validation for the minimum value of speed_hz" +- Revert "spi: Add verification for the max_frequency provided by the firmware" +- !11336 nfsd: map the EBADMSG to nfserr_io to avoid warning +- nfsd: map the EBADMSG to nfserr_io to avoid warning +- !11342 large folios swap-in: handle refault cases first +- mm: remove folio_test_anon(folio)==false path in __folio_add_anon_rmap() +- mm: use folio_add_new_anon_rmap() if folio_test_anon(folio)==false +- mm: extend rmap flags arguments for folio_add_new_anon_rmap +- mm: rmap: abstract updating per-node and per-memcg stats +- mm: swap: reuse exclusive folio directly instead of wp page faults +- mm: swap: entirely map large folios found in swapcache +- mm: swap: make should_try_to_free_swap() support large-folio +- mm: introduce arch_do_swap_page_nr() which allows restore metadata for nr pages +- mm: introduce pte_move_swp_offset() helper which can move offset bidirectionally +- mm: remove the implementation of swap_free() and always use swap_free_nr() +- mm: swap: introduce swap_free_nr() for batched swap_free() +- mm: remove page_add_new_anon_rmap and lru_cache_add_inactive_or_unevictable +- mm: userswap: page_add_new_anon_rmap() -> folio_add_new_anon_rmap() +- mm: convert collapse_huge_page() to use a folio +- mm: convert migrate_vma_insert_page() to use a folio +- mm: remove references to page_add_new_anon_rmap in comments +- mm: remove stale example from comment +- mm: remove some calls to page_add_new_anon_rmap() +- mm: convert unuse_pte() to use a folio throughout +- mm: convert ksm_might_need_to_copy() to work on folios +- mm: memory: use a folio in validate_page_before_insert() +- mm: ksm: use more folio api in ksm_might_need_to_copy() +- !11328 jbd2: avoid mount failed when commit block is partial submitted +- jbd2: avoid mount failed when commit block is partial submitted +- !11222 nfs: pass explicit offset/count to trace events +- nfs: pass explicit offset/count to trace events +- !11321 NFSD: simplify error paths in nfsd_svc() +- NFSD: simplify error paths in nfsd_svc() +- !11314 nvme-fabrics: use reserved tag for reg read/write command +- nvme-fabrics: use reserved tag for reg read/write command +- !11119 virtcca compile warning clean +- virtcca bugfix: compile warning clean +- !10762 CVE-2024-41016 +- ocfs2: strict bound check before memcmp in ocfs2_xattr_find_entry() +- ocfs2: add bounds checking to ocfs2_xattr_find_entry() +- !11300 v3 mm/shmem: mTHP support for anon shmem +- mm: shmem: rename mTHP shmem counters +- mm: add docs for per-order mTHP split counters +- mm: add per-order mTHP split counters +- mm: shmem: fix incorrect aligned index when checking conflicts +- mm: shmem: avoid allocating huge pages larger than MAX_PAGECACHE_ORDER for shmem +- mm: thp: support "THPeligible" semantics for mTHP with anonymous shmem +- mm/shmem: fix input and output inconsistencies +- mm: shmem: add mTHP counters for anonymous shmem +- mm: shmem: add mTHP size alignment in shmem_get_unmapped_area +- mm: shmem: add mTHP support for anonymous shmem +- mm: shmem: add multi-size THP sysfs interface for anonymous shmem +- mm: shmem: add THP validation for PMD-mapped THP related statistics +- mm: memory: extend finish_fault() to support large folio +- mm: shmem: Merge shmem_alloc_hugefolio() with shmem_alloc_folio() +- mm: use update_mmu_tlb_range() to simplify code +- mm: implement update_mmu_tlb() using update_mmu_tlb_range() +- mm: add update_mmu_tlb_range() +- shmem: move the shmem_mapping assert into shmem_get_folio_gfp +- shmem: set a_ops earlier in shmem_symlink +- shmem,percpu_counter: add _limited_add(fbc, limit, amount) +- shmem: _add_to_page_cache() before shmem_inode_acct_blocks() +- shmem: move memcg charge out of shmem_add_to_page_cache() +- shmem: shmem_acct_blocks() and shmem_inode_acct_blocks() +- shmem: trivial tidyups, removing extra blank lines, etc +- shmem: factor shmem_falloc_wait() out of shmem_fault() +- shmem: remove vma arg from shmem_get_folio_gfp() +- shmem: shrink shmem_inode_info: dir_offsets in a union +- !11270 nvme: apple: fix device reference counting +- nvme: apple: fix device reference counting +- !11279 ice: Don't process extts if PTP is disabled +- ice: Don't process extts if PTP is disabled +- !11280 ice: Fix improper extts handling +- ice: Fix improper extts handling +- !11233 CVE-2024-43892 +- memcg: protect concurrent access to mem_cgroup_idr +- !11229 tracing: Have format file honor EVENT_FILE_FL_FREED +- tracing: Have format file honor EVENT_FILE_FL_FREED +- !11228 Bluetooth: MGMT: Add error handling to pair_device() +- Bluetooth: MGMT: Add error handling to pair_device() +- !10698 wifi: mac80211: Avoid address calculations via out of bounds array indexing +- wifi: mac80211: Avoid address calculations via out of bounds array indexing +- !11158 usb: vhci-hcd: Do not drop references before new references are gained +- usb: vhci-hcd: Do not drop references before new references are gained +- !11040 mm: lazyfree THP support +- mm/huge_memory.c: fix used-uninitialized +- mm/vmscan: avoid split lazyfree THP during shrink_folio_list() +- mm/rmap: integrate PMD-mapped folio splitting into pagewalk loop +- mm/rmap: remove duplicated exit code in pagewalk loop +- mm: arm64: fix the out-of-bounds issue in contpte_clear_young_dirty_ptes +- mm/madvise: optimize lazyfreeing with mTHP in madvise_free +- mm/memory: add any_dirty optional pointer to folio_pte_batch() +- mm/arm64: override clear_young_dirty_ptes() batch helper +- mm/madvise: introduce clear_young_dirty_ptes() batch helper +- mm: add pmd_folio() +- mm: make HPAGE_PXD_* macros even if !THP +- mm/Kconfig: CONFIG_PGTABLE_HAS_HUGE_LEAVES + +* Tue Aug 27 2024 ZhangPeng - 6.6.0-39.0.0.47 +- !11156 v3 Fix CVE-2024-43869 +- perf: Fix kabi broken of struct perf_event +- perf: Fix event leak upon exec and file release +- !11168 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.46-47 LTS Patches +- Revert "ata: libata-scsi: Honor the D_SENSE bit for CK_COND=1 and no error" +- media: Revert "media: dvb-usb: Fix unexpected infinite loop in dvb_usb_read_remote_control()" +- KVM: arm64: Don't pass a TLBI level hint when zapping table entries +- KVM: arm64: Don't defer TLB invalidation when zapping table entries +- mm/debug_vm_pgtable: drop RANDOM_ORVALUE trick +- Revert "Input: bcm5974 - check endpoint type before starting traffic" +- Revert "jfs: fix shift-out-of-bounds in dbJoin" +- binfmt_flat: Fix corruption when not offsetting data start +- ALSA: usb: Fix UBSAN warning in parse_audio_unit() +- fs/ntfs3: Do copy_to_user out of run_lock +- jfs: Fix shift-out-of-bounds in dbDiscardAG +- jfs: fix null ptr deref in dtInsertEntry +- fou: remove warn in gue_gro_receive on unsupported protocol +- f2fs: fix to cover read extent cache access with lock +- f2fs: fix to do sanity check on F2FS_INLINE_DATA flag in inode during GC +- bpf, net: Use DEV_STAT_INC() +- ext4: sanity check for NULL pointer after ext4_force_shutdown +- ext4: convert ext4_da_do_write_end() to take a folio +- mm/page_table_check: support userfault wr-protect entries +- nfc: llcp: fix nfc_llcp_setsockopt() unsafe copies +- net: add copy_safe_from_sockptr() helper +- mISDN: fix MISDN_TIME_STAMP handling +- fs: Annotate struct file_handle with __counted_by() and use struct_size() +- bpf: Avoid kfree_rcu() under lock in bpf_lpm_trie. +- bpf: Replace bpf_lpm_trie_key 0-length array with flexible array +- pppoe: Fix memory leak in pppoe_sendmsg() +- net: sctp: fix skb leak in sctp_inq_free() +- net:rds: Fix possible deadlock in rds_message_put +- quota: Detect loops in quota tree +- Input: bcm5974 - check endpoint type before starting traffic +- net: tls, add test to capture error on large splice +- erofs: avoid debugging output for (de)compressed data +- reiserfs: fix uninit-value in comp_keys +- Squashfs: fix variable overflow triggered by sysbot +- squashfs: squashfs_read_data need to check if the length is 0 +- jfs: fix shift-out-of-bounds in dbJoin +- net: don't dump stack on queue timeout +- jfs: fix log->bdev_handle null ptr deref in lbmStartIO +- wifi: mac80211: fix change_address deadlock during unregister +- wifi: mac80211: take wiphy lock for MAC addr change +- tcp_metrics: optimize tcp_metrics_flush_all() +- genirq/cpuhotplug: Retry with cpu_online_mask when migration fails +- genirq/cpuhotplug: Skip suspended interrupts when restoring affinity +- nvme/pci: Add APST quirk for Lenovo N60z laptop +- nfsd: make svc_stat per-network namespace instead of global +- nfsd: remove nfsd_stats, make th_cnt a global counter +- nfsd: make all of the nfsd stats per-network namespace +- nfsd: expose /proc/net/sunrpc/nfsd in net namespaces +- nfsd: rename NFSD_NET_* to NFSD_STATS_* +- sunrpc: use the struct net as the svc proc private +- sunrpc: remove ->pg_stats from svc_program +- sunrpc: pass in the sv_stats struct through svc_create_pooled +- nfsd: stop setting ->pg_stats for unused stats +- sunrpc: don't change ->sv_stats if it doesn't exist +- NFSD: Fix frame size warning in svc_export_parse() +- NFSD: Rewrite synopsis of nfsd_percpu_counters_init() +- LoongArch: Define __ARCH_WANT_NEW_STAT in unistd.h +- btrfs: fix double inode unlock for direct IO sync writes +- Revert "selftests: mptcp: simult flows: mark 'unbalanced' tests as flaky" +- selftests: mptcp: join: test both signal & subflow +- selftests: mptcp: join: ability to invert ADD_ADDR check +- mptcp: pm: do not ignore 'subflow' if 'signal' flag is also set +- mptcp: pm: don't try to create sf if alloc failed +- mptcp: pm: reduce indentation blocks +- nouveau: set placement to original placement on uvmm validate. +- mm/hugetlb: fix potential race in __update_and_free_hugetlb_folio() +- tools headers arm64: Sync arm64's cputype.h with the kernel sources +- ipv6: fix source address selection with route leak +- btrfs: fix corruption after buffer fault in during direct IO append write +- mm: huge_memory: use !CONFIG_64BIT to relax huge page alignment on 32 bit machines +- mm: huge_memory: don't force huge page alignment on 32 bit +- Revert "drm/amd/display: Add NULL check for 'afb' before dereferencing in amdgpu_dm_plane_handle_cursor_update" +- block: use the right type for stub rq_integrity_vec() +- mptcp: pm: deny endp with signal + subflow + port +- selftests: mptcp: fix error path +- mptcp: fully established after ADD_ADDR echo on MPJ +- drm/radeon: Remove __counted_by from StateArray.states[] +- drm/mgag200: Bind I2C lifetime to DRM device +- drm/mgag200: Set DDC timeout in milliseconds +- drm/lima: Mark simple_ondemand governor as softdep +- drm/dp_mst: Skip CSN if topology probing is not done yet +- drm/bridge: analogix_dp: properly handle zero sized AUX transactions +- x86/mtrr: Check if fixed MTRRs exist before saving them +- x86/paravirt: Fix incorrect virt spinlock setting on bare metal +- selftests: mm: add s390 to ARCH check +- eventfs: Use SRCU for freeing eventfs_inodes +- eventfs: Don't return NULL in eventfs_create_dir() +- smb3: fix setting SecurityFlags when encryption is required +- padata: Fix possible divide-by-0 panic in padata_mt_helper() +- tracing: Fix overflow in get_free_elt() +- power: supply: axp288_charger: Round constant_charge_voltage writes down +- power: supply: axp288_charger: Fix constant_charge_voltage writes +- power: supply: qcom_battmgr: return EAGAIN when firmware service is not up +- LoongArch: Enable general EFI poweroff method +- genirq/irqdesc: Honor caller provided affinity in alloc_desc() +- irqchip/xilinx: Fix shift out of bounds +- kcov: properly check for softirq context +- ASoC: amd: yc: Add quirk entry for OMEN by HP Gaming Laptop 16-n0xxx +- parisc: fix a possible DMA corruption +- parisc: fix unaligned accesses in BPF +- serial: core: check uartclk for zero to avoid divide by zero +- timekeeping: Fix bogus clock_was_set() invocation in do_adjtimex() +- ntp: Safeguard against time_constant overflow +- tracefs: Fix inode allocation +- driver core: Fix uevent_show() vs driver detach race +- clocksource: Fix brown-bag boolean thinko in cs_watchdog_read() +- clocksource: Scale the watchdog read retries automatically +- vhost-vdpa: switch to use vmf_insert_pfn() in the fault handler +- tick/broadcast: Move per CPU pointer access into the atomic section +- scsi: ufs: core: Fix hba->last_dme_cmd_tstamp timestamp updating logic +- scsi: ufs: core: Do not set link to OFF state while waking up from hibernation +- scsi: mpi3mr: Avoid IOMMU page faults on REPORT ZONES +- usb: gadget: u_audio: Check return codes from usb_ep_enable and config_ep_by_speed. +- usb: gadget: u_serial: Set start_delayed during suspend +- usb: gadget: midi2: Fix the response for FB info with block 0xff +- usb: gadget: core: Check for unset descriptor +- USB: serial: debug: do not echo input by default +- usb: vhci-hcd: Do not drop references before new references are gained +- ALSA: hda/hdmi: Yet more pin fix for HP EliteDesk 800 G4 +- ALSA: hda/realtek: Add Framework Laptop 13 (Intel Core Ultra) to quirks +- ALSA: hda: Add HP MP9 G4 Retail System AMS to force connect list +- ALSA: line6: Fix racy access to midibuf +- drm/client: fix null pointer dereference in drm_client_modeset_probe +- drm/i915/gem: Adjust vma offset for framebuffer mmap offset +- drm/amdgpu: Forward soft recovery errors to userspace +- drm/amd/display: Skip Recompute DSC Params if no Stream on Link +- drm/i915/gem: Fix Virtual Memory mapping boundaries calculation +- module: make waiting for a concurrent module loader interruptible +- module: warn about excessively long module waits +- cifs: cifs_inval_name_dfs_link_error: correct the check for fullpath +- ASoC: meson: axg-fifo: fix irq scheduling issue with PREEMPT_RT +- ALSA: usb-audio: Re-add ScratchAmp quirk entries +- spi: spi-fsl-lpspi: Fix scldiv calculation +- i2c: qcom-geni: Add missing geni_icc_disable in geni_i2c_runtime_resume +- i2c: qcom-geni: Add missing clk_disable_unprepare in geni_i2c_runtime_resume +- kprobes: Fix to check symbol prefixes correctly +- bpf: kprobe: remove unused declaring of bpf_kprobe_override +- i2c: smbus: Send alert notifications to all devices if source not found +- ASoC: SOF: Remove libraries from topology lookups +- spi: spidev: Add missing spi_device_id for bh2228fv +- ASoC: sti: add missing probe entry for player and reader +- ASoC: codecs: wsa884x: Correct Soundwire ports mask +- ASoC: codecs: wsa884x: parse port-mapping information +- ASoC: codecs: wsa883x: Correct Soundwire ports mask +- ASoC: codecs: wsa883x: parse port-mapping information +- ASoC: codecs: wsa881x: Correct Soundwire ports mask +- ASoC: codecs: wcd938x-sdw: Correct Soundwire ports mask +- i2c: smbus: Improve handling of stuck alerts +- arm64: cputype: Add Cortex-A725 definitions +- arm64: cputype: Add Cortex-X1C definitions +- arm64: cputype: Add Cortex-X925 definitions +- arm64: cputype: Add Cortex-A720 definitions +- arm64: cputype: Add Cortex-X3 definitions +- arm64: cputype: Add Neoverse-V3 definitions +- arm64: cputype: Add Cortex-X4 definitions +- arm64: barrier: Restore spec_bar() macro +- arm64: Add Neoverse-V2 part +- net: drop bad gso csum_start and offset in virtio_net_hdr +- irqchip/loongarch-cpu: Fix return value of lpic_gsi_to_irq() +- irqchip/meson-gpio: Convert meson_gpio_irq_controller::lock to 'raw_spinlock_t' +- scsi: mpt3sas: Avoid IOMMU page faults on REPORT ZONES +- SUNRPC: Fix a race to wake a sync task +- s390/sclp: Prevent release of buffer in I/O +- jbd2: avoid memleak in jbd2_journal_write_metadata_buffer +- ext4: fix uninitialized variable in ext4_inlinedir_to_tree +- media: xc2028: avoid use-after-free in load_firmware_cb() +- media: uvcvideo: Fix the bandwdith quirk on USB 3.x +- media: uvcvideo: Ignore empty TS packets +- drm/amd/display: Add null checker before passing variables +- drm/amd/display: Add NULL check for 'afb' before dereferencing in amdgpu_dm_plane_handle_cursor_update +- media: amphion: Remove lock in s_ctrl callback +- drm/amd/pm: Fix the null pointer dereference for vega10_hwmgr +- drm/amdgpu: Add lock around VF RLCG interface +- drm/admgpu: fix dereferencing null pointer context +- drm/amdgpu/pm: Fix the null pointer dereference in apply_state_adjust_rules +- drm/amdgpu: Fix the null pointer dereference to ras_manager +- drm/amdgpu/pm: Fix the null pointer dereference for smu7 +- drm/amdgpu/pm: Fix the param type of set_power_profile_mode +- drm/amdgpu: fix potential resource leak warning +- drm/amd/display: Add delay to improve LTTPR UHBR interop +- Bluetooth: btnxpuart: Shutdown timer and prevent rearming when driver unloading +- btrfs: fix bitmap leak when loading free space cache on duplicate entry +- net: stmmac: qcom-ethqos: enable SGMII loopback during DMA reset on sa8775p-ride-r3 +- can: mcp251xfd: tef: update workaround for erratum DS80000789E 6 of mcp2518fd +- can: mcp251xfd: tef: prepare to workaround broken TEF FIFO tail index erratum +- wifi: nl80211: don't give key data to userspace +- udf: prevent integer overflow in udf_bitmap_free_blocks() +- PCI: Add Edimax Vendor ID to pci_ids.h +- af_unix: Don't retry after unix_state_lock_nested() in unix_stream_connect(). +- selftests/bpf: Fix send_signal test with nested CONFIG_PARAVIRT +- net/mlx5e: SHAMPO, Fix invalid WQ linked list unlink +- wifi: ath12k: fix memory leak in ath12k_dp_rx_peer_frag_setup() +- wifi: nl80211: disallow setting special AP channel widths +- xen: privcmd: Switch from mutex to spinlock for irqfds +- ACPI: SBS: manage alarm sysfs attribute through psy core +- ACPI: battery: create alarm sysfs attribute atomically +- clocksource/drivers/sh_cmt: Address race condition for clock events +- rcu: Fix rcu_barrier() VS post CPUHP_TEARDOWN_CPU invocation +- block: change rq_integrity_vec to respect the iterator +- md/raid5: avoid BUG_ON() while continue reshape after reassembling +- rcutorture: Fix rcu_torture_fwd_cb_cr() data race +- hwmon: corsair-psu: add USB id of HX1200i Series 2023 psu +- gpio: prevent potential speculation leaks in gpio_device_get_desc() +- net: fec: Stop PPS on driver remove +- net: bcmgenet: Properly overlay PHY and MAC Wake-on-LAN capabilities +- l2tp: fix lockdep splat +- net: dsa: bcm_sf2: Fix a possible memory leak in bcm_sf2_mdio_register() +- net/smc: add the max value of fallback reason count +- Bluetooth: hci_sync: avoid dup filtering when passive scanning with adv monitor +- Bluetooth: l2cap: always unlock channel in l2cap_conless_channel() +- ice: Fix reset handler +- net: linkwatch: use system_unbound_wq +- net: bridge: mcast: wait for previous gc cycles when removing port +- sctp: Fix null-ptr-deref in reuseport_add_sock(). +- wifi: ath12k: fix soft lockup on suspend +- wifi: ath12k: add CE and ext IRQ flag to indicate irq_handler +- wifi: ath12k: rename the sc naming convention to ab +- smb: client: handle lack of FSCTL_GET_REPARSE_POINT support +- x86/mm: Fix pti_clone_entry_text() for i386 +- x86/mm: Fix pti_clone_pgtable() alignment assumption +- jump_label: Fix the fix, brown paper bags galore +- platform/x86/intel/ifs: Initialize union ifs_status to zero +- !11100 exec: Fix ToCToU between perm check and set-uid/gid usage +- exec: Fix ToCToU between perm check and set-uid/gid usage +- !11106 CVE-2024-43868 +- riscv/purgatory: align riscv_kernel_entry +- riscv: Use SYM_*() assembly macros instead of deprecated ones +- !11094 v4 Backport bugfix of folio from v6.11 +- ext4: Fix WARNON in generic write begin path for iomap mode +- mm/huge_memory: fix comment errors of thp_mapping_align +- mm/slub: mark racy accesses on slab->slabs +- mm/slub: mark racy access on slab->freelist +- mm/swapfile: mark racy access on si->highest_bit +- mm/mmap: simplify vma link and unlink +- mm/readahead: limit page cache size in page_cache_ra_order() +- readahead: use ilog2 instead of a while loop in page_cache_ra_order() +- filemap: Convert generic_perform_write() to support large folios +- mm/huge_memory: avoid PMD-size page cache if needed +- mm: simplify folio_migrate_mapping() +- mm: refactor folio_undo_large_rmappable() +- mm: fix crashes from deferred split racing folio migration +- mm: page_alloc: allowing mTHP compaction to capture the freed page directly +- mm/migrate: fix deadlock in migrate_pages_batch() on large folios +- mm: fix khugepaged activation policy +- mm/huge_memory: mark racy access onhuge_anon_orders_always +- mm/migrate: putback split folios when numa hint migration fails +- mm/migrate: make migrate_pages_batch() stats consistent +- !11125 mm/memory-failure: fix handling of dissolved but not taken off from buddy pages +- mm/memory-failure: fix handling of dissolved but not taken off from buddy pages +- !11077 IMA: Support the measurement extending of TSI TMM +- IMA: Support the measurement extending of TSI TMM +- !11108 cpufreq: CPPC: Eliminate the impact of cpc_read() latency error +- cpufreq: CPPC: Eliminate the impact of cpc_read() latency error +- !11081 Backport LTS conflicting patches +- ALSA: hda/realtek: Fix conflicting quirk for PCI SSID 17aa:3820 +- vfio/pci: Restore zero affected bus reset devices warning +- cxl/region: check interleave capability +- EDAC/amd64: Convert PCIBIOS_* return codes to errnos +- ALSA: hda/realtek: Enable headset mic on IdeaPad 330-17IKB 81DM +- vfio/pci: Init the count variable in collecting hot-reset devices +- vfio/pci: Collect hot-reset devices to local buffer +- platform/chrome: cros_ec: Handle events during suspend after resume completion +- !10998 PCI: endpoint: pci-epf-test: Make use of cached 'epc_features' in pci_epf_test_core_init() +- PCI: endpoint: pci-epf-test: Make use of cached 'epc_features' in pci_epf_test_core_init() +- !10942 add support for arm virtcca attestation +- cvm_tsi: add support virtcca attestation +- !11043 [OLK-6.6] drivers: add GPU Peer Memory support +- drivers: Fix kabi check failure +- drivers: Add GDR(GPU Direct RDMA) support +- !11044 ext4: some bugfixs for large iomap&folio +- iomap: improve iomap_folio_mkwrite_iter and ifs_clear_range_dirty +- iomap: optimize setting uptodate bit +- iomap: reduce unnecessary state_lock when setting ifs uptodate and dirty bits +- iomap: don't mark blocks uptodate after partial zeroing +- ext4: ext4_iomap_map_blocks: Fix null pointer deference in nojournal mode +- xfs: reserve blocks for truncating large realtime inode +- xfs: hoist multi-fsb allocation unit detection to a helper +- !11018 net: usb: qmi_wwan: fix memory leak for not ip packets +- net: usb: qmi_wwan: fix memory leak for not ip packets +- !10927 block: Fix lockdep warning in blk_mq_mark_tag_wait +- block: Fix lockdep warning in blk_mq_mark_tag_wait +- !11004 kvm: s390: Reject memory region operations for ucontrol VMs +- kvm: s390: Reject memory region operations for ucontrol VMs +- !10969 bpf, arm64: Fix trampoline for BPF_TRAMP_F_CALL_ORIG +- bpf, arm64: Fix trampoline for BPF_TRAMP_F_CALL_ORIG +- !10407 Intel: Backport SPR/EMR CXL and HBM perfmon support to kernel 6.6 +- perf/x86/intel/uncore: Support HBM and CXL PMON counters +- perf/x86/uncore: Cleanup unused unit structure +- perf/x86/uncore: Apply the unit control RB tree to PCI uncore units +- perf/x86/uncore: Apply the unit control RB tree to MSR uncore units +- perf/x86/uncore: Apply the unit control RB tree to MMIO uncore units +- perf/x86/uncore: Retrieve the unit ID from the unit control RB tree +- perf/x86/uncore: Support per PMU cpumask +- perf/x86/uncore: Save the unit control address of all units +- !10411 Intel: Backport 3 core PMU bugfixes to kernel 6.6 +- perf/x86/intel: Correct incorrect 'or' operation for PMU capabilities +- perf/x86/intel: Fix broken fixed event constraints extension +- perf/x86/intel: Add a distinct name for Granite Rapids +- perf/x86/intel: Hide Topdown metrics events if the feature is not enumerated +- perf/x86/intel: Add common intel_pmu_init_hybrid() +- perf/x86/intel: Clean up the hybrid CPU type handling code +- perf/x86/intel: Apply the common initialization code for ADL +- perf/x86/intel: Factor out the initialization code for ADL e-core +- perf/x86/intel: Factor out the initialization code for SPR +- perf/x86/intel: Use the common uarch name for the shared functions +- !10911 Fix CVE-2024-40966 +- tty: fix kabi breakage in struct tty_operations +- tty: add the option to have a tty reject a new ldisc +- !10918 【OLK 6.6】net: hns3: use the user's cfg after reset +- net: hns3: use the user's cfg after reset +- !10907 v2 perf/x86: Fix smp_processor_id()-in-preemptible warnings +- perf/x86: Fix smp_processor_id()-in-preemptible warnings +- !10585 Fix the issue that vm can't access to host with virtio-net +- vhost: move smp_rmb() into vhost_get_avail_idx() +- vhost: correct misleading printing information +- !10812 ima: dont disable digest_list if the file is not processed +- ima: dont disable digest_list if the file is not processed +- !10819 [OLK-6.6] Support Hygon Trusted Key Management virtualization +- drivers/crypto/ccp: memmove is used instead of memcpy in overlapped memmory for tkm +- drivers/crypto/ccp: Eliminate dependence of the kvm module on the ccp module +- drivers/crypto/ccp: Allow VM without a configured vid to use TKM +- drivers/crypto/ccp: support tkm key isolation +- arch/x86/kvm: Support tkm virtualization +- arch/x86/kvm: Support psp virtualization +- drivers/crypto/ccp: Add psp mutex enable ioctl support +- drivers/crypto/ccp: concurrent psp access support between user and kernel space +- !6863 sdei_watchdog: don't update last_check_time when no watchdog_hardlockup_check is performed +- sdei_watchdog: do not update last_check_time when no watchdog_hardlockup_check is performed +- !10899 selftests/bpf: Add netlink helper library +- selftests/bpf: Add netlink helper library +- !10690 [OLK-6.6] Support Trusted computing(TC) feature for hygon CPU +- crypto: command co-processor: Add config to openeuler_defconfig +- linux: tcm: add Hygon TCM2 driver +- linux: tpm: add Hygon TPM2 driver +- crypto: tdm: Support dynamic protection for SCT and IDT by HYGON TDM +- crypto: tdm: Add Hygon TDM driver +- crypto: command co-processor: Add another mailbox interrupt support for PSP sending command to X86 +- crypto: ccp: Add a new interface for X86 sending command to PSP +- !10720 v2 s390/pkey: Wipe copies of clear-key structures on failure +- s390/pkey: Wipe copies of clear-key structures on failure + +* Wed Aug 14 2024 Mingzheng Xing - 6.6.0-38.0.0.46 +- riscv kernel upgrade to 6.6.0-38.0.0 +- bugfix for sg2042 accessing kernel page tables +- revert sg2042 high memory +- revert sg2042 kexec image +- add support th1520 modules: + pinctrl, eMMC, gpio, usb, pwm, ethernet, th1520 perf, ADC, clock, + mailbox, reset, qspi, pvt, gpio, dma, mmc, cpufreq, rtc, dwmac, + light-event, rpmsg, i2c, i2s, light-aon, light-aon-pd, codec, gpu. + +- th1520: riscv: dtb: Add gpu node +- riscv: config: Disable RISCV_ISA_V in openEuler +- th1520: riscv: config: disable RISCV_ISA_V in th1520_defconfig +- riscv: config: Set NVMe driver builtin +- th1520: riscv: config: Enable PowerVR GPU +- th1520: riscv: Add GPU to th1520_defconfig +- th1520: riscv: config: Enable th1520 support +- sg2042: riscv: config: Enable sg2042 support +- sg2042: riscv: config: Add sg2042_defconfig +- riscv: Use accessors to page table entries instead of direct dereference +- riscv: mm: Only compile pgtable.c if MMU +- mm: Introduce pudp/p4dp/pgdp_get() functions +- riscv: Use WRITE_ONCE() when setting page table entries +- Merge patch series "membarrier: riscv: Core serializing command" +- membarrier: riscv: Add full memory barrier in switch_mm() +- stmmac: bitmain: use DWMAC_SOPHGO module config +- pcie: whitelist and support mellanox connectx-2 +- riscv: input: Fixup input_event +- drm: Fix HDMI hot-plug problem +- gpu/drm: hdmi: Add hdmi debounce to enhance hdmi plugin/out stable +- audio: th1520: fixup compile warning of i2s driver +- DPU: fix bugs of DPU and resolve compilation warnings +- riscv: binrpm: Add dtbs install +- th1520: gpu: Add driver for PowerVR Rogue GPU +- dmaengine: dw-axi-dmac: Add support for Xuantie TH1520 DMA +- arch:rsicv:select ARCH_HAS_DMA_WRITE_COMBINE +- configs: enable rtw88 for 8723ds +- drivers: pinctrl: correct th1520 audio i2c1 bit mapping table +- driver:padctrl:correct th1520 gpio_1 24/25 cfg +- dts: th1520: add adc vref-supply regulator +- dts: th1520: add cpu thermal node and device thermal node +- drivers: event: add macro definition to control SW_PANIC event +- chore: use thead instead of xuantie +- chore: use xuantie instead of thead +- riscv: ptrace: Fix ptrace using uninitialized riscv_v_vsize +- audio: th1520: enable soundcard feature +- audio: th1520: support audiosys pinctrl feature +- dts: th1520: fix interrupt number config error in dts +- th1520: defconfig: add configs to align the functionality and performance of previous related versions +- DPU: add DPU driver for Lichee-Pi-4A board +- dts: th1520: add npu device node +- codec: audio: add codec driver for Lichee-Pi-4A board +- drivers: cpufreq: add cpufreq driver. +- riscv: dts: Introduce lichee-pi-4a fixed regulator support. +- th1520: defconfig: to remove unnecessary configs for th1520 +- i2s: remove debug message +- riscv:dts: fix the aon gpio range configuration error +- riscv:dts: fix spi/qspi1 cs pin duplicate configuration error +- riscv:dts: fix the gpio range configuration error +- drivers: regulator: add th1520 AON virtual regulator control support. +- dt-bindings: add AON resource id headfile +- drivers: pmdomain: support th1520 Power domain control. +- i2s: add i2s driver for XuanTie TH1520 SoC +- configs: xuantie: correct definition of SoC Architecture +- configs: enable th1520 xgene rtc and rtc prescale in th1520_defconfig +- riscv: mm: update T-Head memory type definitions +- i2c: designware: add support for hcnt/lcnt got from dt +- add 902 share mem log +- th1520_defconfig: add usb config +- refine thead,th1520-usb.yaml +- drivers: usb: dwc3: add usb_mode usb_speed param for mode speed change when insmod ko +- drivers: usb: add dwc3-thead.c +- th1520.dtsi: refine usb dts +- configs: enable th1520 event and watchdog +- riscv:dts:thead: Add TH1520 event and watchdog device node +- dt-bindings:wdt: Add Documentation for THEAD TH1520 pmic watchdog +- drivers/watchdog: Add THEAD TH1520 pmic watchdog driver +- dt-bindings:event: Add Documentation for THEAD TH1520 event driver +- drivers/soc/event: Add THEAD TH1520 event driver +- Open I2C config +- fix rpmsg addr cast warning +- fix lp32 compile warnoing for rpmsg +- fix proc log warning +- fix rpmsg warning +- add c906 audio support +- Kconfig: Enable APM X-Gene RTC for XuanTie TH1520 +- drivers/rtc/rtc-xgene: Add "snps,dw-apb-rtc" into the "compatible" +- riscv: dts: thead: Add XuanTie TH1520 RTC device node +- dt-bindings: rtc: Add optional property "prescaler" in APM X-Gene RTC Document +- drivers/rtc/rtc-xgene: Add prescaler support in APM X-Gene RTC driver +- th1520: defconfig: to add th1520_defconfig +- net:stmmac: increase timeout for dma reset +- stmmac:dwmac-thead: add support for suspend/resume feature +- net:dwmac-thead: dd ptp clk set and enable +- configs: Enable th1520 mailbox. +- drivers:ipc: update th1520 rpc msg version 2 +- firmware: thead: c910_aon: add th1520 Aon protocol driver +- mmc:sdhci-of-dwcmshc: th1520 add delay line in different mode and sdio rxclk delay +- mmc:sdhci-of-dwcmshc: th1520 larger tuning max loop count to 128 +- dts: th1520: enable sdio1 for wifi card in lichee-pi-4a +- mmc:sdhci-of-dwcmshc: th1520 sdhci add fix io voltage 1v8 +- mmc:sdhci-of-dwcmshc: th1520 resolve accss rpmb error in hs400 +- drivers/dmac: add pm suspend/resume for dma driver +- audio: th1520: add dma chan str for dmaengine +- riscv: dts: thead: Add THEAD TH1520 dmac1 and dmac2 device node +- STR: fix pca953x resume bug +- drivers/iio/adc: add sysfs_remove_file when adc driver removed +- drivers/pvt: add mr75203 driver pm feature and correct temperature coefficient +- riscv: dts: thead: Add THEAD TH1520 SPI/QSPI device node +- dt-bindings: spi/qspi: Add Documentation for THEAD TH1520 SPI/QSPI +- drivers/spi: Add THEAD TH1520 QSPI driver +- reset: th1520: to support npu/fce reset feature +- riscv: dts: Add th1520 reset device tree +- dt-bindings: reset: Document th1520 reset control +- reset: Add th1520 reset driver support +- riscv: dts: thead: Add XuanTie TH1520 Mailbox device node +- mailbox: add XuanTie TH1520 Mailbox IPC driver +- dt-bindings: mailbox: Add a binding file for XuanTie TH1520 Mailbox +- riscv: dts: thead: to add th1520 clk nodes +- drivers: clk: to add thead th1520 clk driver +- configs: enable th1520 clk +- dt-bindings: adc: Add Documentation for THEAD TH1520 ADC +- riscv: dts: thead: Add THEAD TH1520 ADC device node +- drivers/iio/adc: Add THEAD TH1520 ADC driver +- riscv: dts: thead: Enable Lichee Pi 4A USB +- riscv: dts: thead: Add Lichee Pi 4A IO expansions +- riscv: dts: thead: Add TH1520 USB nodes +- riscv: dts: thead: Add TH1520 I2C nodes +- usb: dwc3: add T-HEAD TH1520 usb driver +- dt-bindings: usb: Add T-HEAD TH1520 USB controller +- riscv: dts: thead: Add BeagleV Ahead SDIO0 pins +- riscv: dts: thead: Add Lichee Pi 4A SDIO0 pins +- riscv: dts: thead: Add TH1520 ethernet nodes +- net: stmmac: add glue layer for T-HEAD TH1520 SoC +- dt-bindings: net: add T-HEAD dwmac support +- dt-bindings: net: snps,dwmac: allow dwmac-3.70a to set pbl properties +- gpio: dwapb: Use generic request, free and set_config +- riscv: dts: thead: Enable Lichee Pi 4A PWM fan +- riscv: dts: thead: Add TH1520 PVT node +- riscv: dts: thead: Add TH1520 PWM node +- pwm: add T-HEAD PWM driver +- dt-bindings: pwm: Add T-HEAD PWM controller +- perf vendor events riscv: add T-HEAD C9xx JSON file +- riscv: dts: thead: th1520: Add PMU event node +- chore: dtb_install in /boot +- remove compression for riscv Image +- riscv: dts: thead: Enable LicheePi 4A eMMC and microSD +- riscv: dts: thead: Enable BeagleV Ahead eMMC and microSD +- riscv: dts: thead: Add TH1520 mmc controllers and sdhci clock +- riscv: defconfig: Enable mmc and dma drivers for T-Head TH1520 +- mmc: sdhci-of-dwcmshc: Add support for T-Head TH1520 +- mmc: sdhci: add __sdhci_execute_tuning() to header +- dt-bindings: mmc: sdhci-of-dwcmhsc: Add T-Head TH1520 support +- fix: remove linux/array_size.h for pinctrl-th1520 +- riscv: dtb: thead: Add BeagleV Ahead LEDs +- riscv: dts: thead: Add TH1520 pinctrl settings for UART0 +- riscv: dts: thead: Add Lichee Pi 4M GPIO line names +- riscv: dts: thead: Adjust TH1520 GPIO labels +- riscv: dts: thead: Add TH1520 GPIO ranges +- riscv: dts: thead: Add TH1520 pin control nodes +- pinctrl: Add driver for the T-Head TH1520 SoC +- dt-bindings: pinctrl: Add thead,th1520-pinctrl bindings +- riscv: Enable TEE driver +- sg2042: drivers: rtc: disable BMC RTC device +- sg2042: dts: add i2c-rtc ds1307 device node for single chip +- sg2042: riscv:dts:modify dw gpio clock name +- sg2042: drivers:pci:remove the err log of parsing pci +- sg2042: driver: ipmi: support KVM and IPMI SI for BMC +- sg2042: perf cpumap: Make counter as unsigned ints +- sg2042: kernel: schedule: Fix set_task_cpu() bug +- sg2042: mm: Modify __find_max_addr for memory hole +- sg2042: riscv: kernel: Optimize apply_relocate_add() +- sg2042: riscv: mm: Clear compilation warning about last_cpupid +- sg2042: kernel: tick: filter unnecessary printing +- sg2042: kernel: Adjust the log level of the tick_switch_to_oneshot function +- sg2042: drm/amd/display: Support DRM_AMD_DC_FP on RISC-V +- sg2042: riscv: Factor out riscv-march-y to a separate Makefile +- sg2042: riscv: Add support for kernel-mode FPU +- sg2042: mango pci hack:broadcast when no MSI source known +- sg2042: nvidia hda: force msi +- sg2042: radeon hack: force 64-bit msi to fit top intc +- sg2042: amdgpu: disable rebar +- sg2042: ttm: disallow cached mapping +- sg2042: driver: soc: Add sophgo sg2042 soc support +- sg2042: drivers: pcie: Create msi-x whitelist,turn on msi-x for top intr +- sg2042: driver: pcie: Add sophgo sg2042 soc support +- sg2042: driver: net: Add sophgo sg2042 soc support +- sg2042: driver: mtd: Add sophgo sg2042 soc support +- sg2042: driver: mmc: Add sophgo sg2042 soc support +- sg2042: driver: reset: Add sophgo sg2042 soc support +- sg2042: driver: pinctrl: Add sophgo sg2042 soc support +- sg2042: driver: clk: Add sophgo sg2042 soc support +- sg2042: riscv: spinlock: Fix deadlock issue +- sg2042: riscv: add smp_cond_load_acquire() +- sg2042: riscv: add ioremap_wc for gpu +- sg2042: riscv: changing T-Head PBMT attributes +- sg2042: riscv: errata: thead: Make cache clean to flush +- sg2042: riscv: use VA+PA variant of CMO macros for DMA page preparation +- sg2042: riscv: use VA+PA variant of CMO macros for DMA synchorization +- sg2042: riscv: errata: cmo: add CMO macro variant with both VA and PA +- sg2042: riscv: errata: Replace thead cache clean with flush +- sg2042: riscv: Kconfig: Set vector as default no +- sg2042: riscv: Add sophgo sg2042 soc support + +* Tue Aug 13 2024 ZhangPeng - 6.6.0-38.0.0.45 +- !10843 netfilter: nf_tables: prefer nft_chain_validate +- netfilter: nf_tables: prefer nft_chain_validate +- !10893 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.45 LTS Patches +- selftests: mptcp: join: check backup support in signal endp +- selftests: mptcp: join: validate backup in MPJ +- selftests: mptcp: always close input's FD if opened +- mptcp: fix duplicate data handling +- mptcp: pm: only set request_bkup flag when sending MP_PRIO +- mptcp: fix bad RCVPRUNED mib accounting +- mptcp: mib: count MPJ with backup flag +- mptcp: fix NL PM announced address accounting +- mptcp: distinguish rcv vs sent backup flag in requests +- mptcp: fix user-space PM announced address accounting +- r8169: don't increment tx_dropped in case of NETDEV_TX_BUSY +- net: usb: sr9700: fix uninitialized variable use in sr_mdio_read +- drm/i915: Fix possible int overflow in skl_ddi_calculate_wrpll() +- drm/virtio: Fix type of dma-fence context variable +- drm/vmwgfx: Fix a deadlock in dma buf fence polling +- Revert "ALSA: firewire-lib: operate for period elapse event in process context" +- Revert "ALSA: firewire-lib: obsolete workqueue for period update" +- ALSA: seq: ump: Optimize conversions from SysEx to UMP +- ALSA: hda/realtek: Add quirk for Acer Aspire E5-574G +- ALSA: usb-audio: Correct surround channels in UAC1 channel map +- mptcp: sched: check both directions for backup +- protect the fetch of ->fd[fd] in do_dup2() from mispredictions +- btrfs: do not subtract delalloc from avail bytes +- btrfs: zoned: fix zone_unusable accounting on making block group read-write again +- HID: wacom: Modify pen IDs +- platform/chrome: cros_ec_proto: Lock device when updating MKBP version +- arm64: jump_label: Ensure patched jump_labels are visible to all CPUs +- riscv: Fix linear mapping checks for non-contiguous memory regions +- riscv/mm: Add handling for VM_FAULT_SIGSEGV in mm_fault_error() +- perf: riscv: Fix selecting counters in legacy mode +- riscv: remove unused functions in traps_misaligned.c +- ipv6: fix ndisc_is_useropt() handling for PIO +- igc: Fix double reset adapter triggered from a single taprio cmd +- net/mlx5e: Add a check for the return value from mlx5_port_set_eth_ptys +- net/mlx5e: Fix CT entry update leaks of modify header context +- net/mlx5e: Require mlx5 tc classifier action support for IPsec prio capability +- net/mlx5: Fix missing lock on sync reset reload +- net/mlx5: Lag, don't use the hardcoded value of the first port +- net/mlx5: Fix error handling in irq_pool_request_irq +- net/mlx5: Always drain health in shutdown callback +- netfilter: iptables: Fix potential null-ptr-deref in ip6table_nat_table_init(). +- netfilter: iptables: Fix null-ptr-deref in iptable_nat_table_init(). +- ALSA: hda: Conditionally use snooping for AMD HDMI +- net: phy: micrel: Fix the KSZ9131 MDI-X status issue +- net: mvpp2: Don't re-use loop iterator +- drm/i915/hdcp: Fix HDCP2_STREAM_STATUS macro +- net/iucv: fix use after free in iucv_sock_close() +- ice: add missing WRITE_ONCE when clearing ice_rx_ring::xdp_prog +- ice: replace synchronize_rcu with synchronize_net +- ice: don't busy wait for Rx queue disable in ice_qp_dis() +- ice: respect netif readiness in AF_XDP ZC related ndo's +- i915/perf: Remove code to update PWR_CLK_STATE for gen12 +- rtnetlink: Don't ignore IFLA_TARGET_NETNSID when ifname is specified in rtnl_dellink(). +- net: axienet: start napi before enabling Rx/Tx +- tcp: Adjust clamping window for applications specifying SO_RCVBUF +- tcp: annotate data-races around tp->window_clamp +- Bluetooth: hci_sync: Fix suspending with wrong filter policy +- Bluetooth: btintel: Fail setup on error +- ALSA: hda: conexant: Fix headset auto detect fail in the polling mode +- net: phy: realtek: add support for RTL8366S Gigabit PHY +- wifi: cfg80211: fix reporting failed MLO links status with cfg80211_connect_done +- sched: act_ct: take care of padding in struct zones_ht_key +- drm/vmwgfx: Trigger a modeset when the screen moves +- drm/vmwgfx: Fix overlay when using Screen Targets +- drm/nouveau: prime: fix refcount underflow +- perf tool: fix dereferencing NULL al->maps +- HID: amd_sfh: Move sensor discovery before HID device initialization +- ARM: 9406/1: Fix callchain_trace() return value +- MIPS: dts: loongson: Fix ls2k1000-rtc interrupt +- MIPS: dts: loongson: Fix liointc IRQ polarity +- MIPS: Loongson64: DTS: Fix PCIe port nodes for ls7a +- perf: imx_perf: fix counter start and config sequence +- dmaengine: fsl-edma: change the memory access from local into remote mode in i.MX 8QM +- dmaengine: fsl-edma: clean up unused "fsl,imx8qm-adma" compatible string +- dmaengine: fsl-edma: add i.MX8ULP edma support +- dmaengine: fsl-edma: add address for channel mux register in fsl_edma_chan +- f2fs: assign CURSEG_ALL_DATA_ATGC if blkaddr is valid +- f2fs: fix to avoid use SSR allocate when do defragment +- mm/page_alloc: fix pcp->count race between drain_pages_zone() vs __rmqueue_pcplist() +- fbdev: vesafb: Detect VGA compatibility from screen info's VESA attributes +- firmware/sysfb: Update screen_info for relocated EFI framebuffers +- video: Provide screen_info_get_pci_dev() to find screen_info's PCI device +- video: Add helpers for decoding screen_info +- fbdev/vesafb: Replace references to global screen_info by local pointer +- PCI: Add pci_get_base_class() helper +- KVM: nVMX: Check for pending posted interrupts when looking for nested events +- KVM: nVMX: Add a helper to get highest pending from Posted Interrupt vector +- KVM: VMX: Move posted interrupt descriptor out of VMX code +- KVM: VMX: Split off vmx_onhyperv.{ch} from hyperv.{ch} +- leds: triggers: Flush pending brightness before activating trigger +- leds: trigger: Call synchronize_rcu() before calling trig->activate() +- leds: trigger: Store brightness set by led_trigger_event() +- leds: trigger: Remove unused function led_trigger_rename_static() +- cpufreq: qcom-nvmem: fix memory leaks in probe error paths +- cpufreq: qcom-nvmem: Simplify driver data allocation +- sysctl: allow to change limits for posix messages queues +- sysctl: allow change system v ipc sysctls inside ipc namespace +- thermal/drivers/broadcom: Fix race between removal and clock disable +- thermal: bcm2835: Convert to platform remove callback returning void +- arm64: dts: qcom: sdm845: Disable SS instance in Parkmode for USB +- arm64: dts: qcom: sdm845: switch USB QMP PHY to new style of bindings +- arm64: dts: qcom: sdm845: switch USB+DP QMP PHY to new style of bindings +- arm64: dts: qcom: ipq8074: Disable SS instance in Parkmode for USB +- arm64: dts: qcom: msm8998: Disable SS instance in Parkmode for USB +- arm64: dts: qcom: msm8998: switch USB QMP PHY to new style of bindings +- arm64: dts: qcom: sc7280: Disable SuperSpeed instances in park mode +- arm64: dts: qcom: sc7280: switch USB+DP QMP PHY to new style of bindings +- arm64: dts: qcom: sc7180: Disable SuperSpeed instances in park mode +- arm64: dts: qcom: sc7180: switch USB+DP QMP PHY to new style of bindings +- !10823 mm/userfaultfd: reset ptes when close() for wr-protected ones +- mm/userfaultfd: reset ptes when close() for wr-protected ones +- !10824 dmaengine: idxd: Fix possible Use-After-Free in irq_process_work_list +- dmaengine: idxd: Fix possible Use-After-Free in irq_process_work_list +- !10855 CVE-2024-36971 +- net: fix kabi breakage in struct dst_ops +- net: fix __dst_negative_advice() race +- !10863 v2 ext4: flexibly control whether to enable dioread_nolock by default +- ext4: flexibly control whether to enable dioread_nolock by default +- !10796 Revert "ARM: spectre-v2: turn off the mitigation via boot cmdline param" +- Revert "ARM: spectre-v2: turn off the mitigation via boot cmdline param" +- !10795 Revert "security: restrict init parameters by configuration" +- Revert "security: restrict init parameters by configuration" +- !10794 revert kaslr arm32 support +- Revert "asm-generic: add .data.rel.ro sections to __ro_after_init" +- Revert "arm-soc: exynos: replace open coded VA->PA conversions" +- Revert "arm-soc: mvebu: replace open coded VA->PA conversion" +- Revert "arm-soc: various: replace open coded VA->PA calculation of pen_release" +- Revert "ARM: kernel: switch to relative exception tables" +- Revert "ARM: kernel: make vmlinux buildable as a PIE executable" +- Revert "ARM: kernel: use PC-relative symbol references in MMU switch code" +- Revert "ARM: kernel: use PC relative symbol references in suspend/resume code" +- Revert "ARM: mm: export default vmalloc base address" +- Revert "ARM: kernel: refer to swapper_pg_dir via its symbol" +- Revert "arm: vectors: use local symbol names for vector entry points" +- Revert "ARM: kernel: implement randomization of the kernel load address" +- Revert "ARM: decompressor: explicitly map decompressor binary cacheable" +- Revert "ARM: decompressor: add KASLR support" +- Revert "No idea why this broke ..." +- Revert "arm32: kaslr: When boot with vxboot, we must adjust dtb address before kaslr_early_init, and store dtb address after init." +- Revert "arm32: kaslr: pop visibility when compile decompress boot code as we need relocate BSS by GOT." +- Revert "arm32: kaslr: print kaslr offset when kernel panic" +- Revert "arm32: kaslr: Fix the bug of symbols relocation" +- Revert "arm32: kaslr: Fix clock_gettime and gettimeofday performance degradation when configure CONFIG_RANDOMIZE_BASE" +- !10615 USB: core: Fix duplicate endpoint bug by clearing reserved bits in the descriptor +- USB: core: Fix duplicate endpoint bug by clearing reserved bits in the descriptor +- !10834 v2 wifi: cfg80211: restrict NL80211_ATTR_TXQ_QUANTUM values +- wifi: cfg80211: restrict NL80211_ATTR_TXQ_QUANTUM values +- !10816 sched/cputime: Fix mul_u64_u64_div_u64() precision for cputime +- sched/cputime: Fix mul_u64_u64_div_u64() precision for cputime +- !10805 dummy_struct_ops selftest failed +- Revert "[Backport] selftests/bpf: adjust dummy_st_ops_success to detect additional error" +- Revert "[Backport] selftests/bpf: dummy_st_ops should reject 0 for non-nullable params" +- !10345 blk-wbt: don't throttle swap writes in direct reclaim +- blk-wbt: don't throttle swap writes in direct reclaim +- !10772 s390/pkey: Use kfree_sensitive() to fix Coccinelle warnings +- s390/pkey: Use kfree_sensitive() to fix Coccinelle warnings +- !10722 btrfs: zoned: fix use-after-free in do_zone_finish() +- btrfs: zoned: fix use-after-free in do_zone_finish() + +* Wed Aug 07 2024 ZhangPeng - 6.6.0-37.0.0.44 +- !10793 perf util: Add a function for replacing characters in a string +- perf util: Add a function for replacing characters in a string +- !10635 nvme: avoid double free special payload +- nvme: avoid double free special payload +- !10757 CVE-2024-41045 +- bpf: Defer work in bpf_timer_cancel_and_free +- bpf: replace bpf_timer_cancel_and_free with a generic helper +- bpf: replace bpf_timer_set_callback with a generic helper +- !10729 Backport vmalloc 2 bugfix +- mm: vmalloc: fix lockdep warning +- mm/vmalloc: eliminated the lock contention from twice to once +- !10746 irqchip/mbigen: Fix mbigen node address layout +- irqchip/mbigen: Fix mbigen node address layout +- !10533 backport mainline patchs +- cpufreq: Allow drivers to advertise boost enabled +- irqdomain: Fixed unbalanced fwnode get and put +- !10518 xfs: add bounds checking to xlog_recover_process_data +- xfs: add bounds checking to xlog_recover_process_data +- !10622 leds: mlxreg: Use devm_mutex_init() for mutex initialization +- leds: mlxreg: Use devm_mutex_init() for mutex initialization +- !10677 gve: Account for stopped queues when reading NIC stats +- gve: Account for stopped queues when reading NIC stats +- !10639 s390/mm: Fix VM_FAULT_HWPOISON handling in do_exception() +- s390/mm: Fix VM_FAULT_HWPOISON handling in do_exception() +- !10653 virtcca cvm feature patches +- gicv3: add lpi support for cvm guest +- config: modify arm64 defconfig for virtcca cvm feature +- mm: enable swiotlb alloc for cvm share mem +- pmu: enable pmu phys irq inject for cvm +- kvm: add virtcca cvm host feature +- !10658 CVE-2024-35860 +- bpf: Fix a potential use-after-free in bpf_link_free() +- Fix kabi breakage in struct bpf_link and bpf_link_ops +- bpf: support deferring bpf_link dealloc to after RCU grace period +- !10649 xfs: don't walk off the end of a directory data block +- xfs: don't walk off the end of a directory data block +- !10556 smart_grid: introducing rebuild_affinity_domain +- smart_grid: introducing rebuild_affinity_domain +- !10631 sched/deadline: Fix task_struct reference leak +- sched/deadline: Fix task_struct reference leak +- !10319 block: propagate partition scanning errors to the BLKRRPART ioctl +- block: propagate partition scanning errors to the BLKRRPART ioctl +- !10500 fix CVE-2024-42155 +- s390/pkey: Wipe copies of protected- and secure-keys +- !10657 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.40-6.6.44 LTS Patches +- fs: don't allow non-init s_user_ns for filesystems without FS_USERNS_MOUNT +- nvme-pci: add missing condition check for existence of mapped data +- io_uring: fix io_match_task must_hold +- iommu: sprd: Avoid NULL deref in sprd_iommu_hw_en +- s390/cpum_cf: Fix endless loop in CF_DIAG event stop +- s390/pci: Allow allocation of more than 1 MSI interrupt +- s390/pci: Refactor arch_setup_msi_irqs() +- ceph: fix incorrect kmalloc size of pagevec mempool +- ASoC: Intel: use soc_intel_is_byt_cr() only when IOSF_MBI is reachable +- spi: spidev: add correct compatible for Rohm BH2228FV +- ASoC: sof: amd: fix for firmware reload failure in Vangogh platform +- nvme-pci: Fix the instructions for disabling power management +- spi: microchip-core: ensure TX and RX FIFOs are empty at start of a transfer +- spi: microchip-core: fix init function not setting the master and motorola modes +- spi: microchip-core: switch to use modern name +- spi: microchip-core: only disable SPI controller when register value change requires it +- spi: microchip-core: defer asserting chip select until just before write to TX FIFO +- spi: microchip-core: fix the issues in the isr +- ASoC: SOF: imx8m: Fix DSP control regmap retrieval +- auxdisplay: ht16k33: Drop reference after LED registration +- lirc: rc_dev_get_from_fd(): fix file leak +- powerpc: fix a file leak in kvm_vcpu_ioctl_enable_cap() +- apparmor: Fix null pointer deref when receiving skb during sock creation +- mISDN: Fix a use after free in hfcmulti_tx() +- bpf: Fix a segment issue when downgrading gso_size +- net: nexthop: Initialize all fields in dumped nexthops +- net: stmmac: Correct byte order of perfect_match +- tipc: Return non-zero value from tipc_udp_addr2str() on error +- netfilter: nft_set_pipapo_avx2: disable softinterrupts +- ice: Fix recipe read procedure +- net: bonding: correctly annotate RCU in bond_should_notify_peers() +- ipv4: Fix incorrect source address in Record Route option +- MIPS: SMP-CPS: Fix address for GCR_ACCESS register for CM3 and later +- tools/resolve_btfids: Fix comparison of distinct pointer types warning in resolve_btfids +- bpf, events: Use prog to emit ksymbol event for main program +- dma: fix call order in dmam_free_coherent +- af_unix: Disable MSG_OOB handling for sockets in sockmap/sockhash +- libbpf: Fix no-args func prototype BTF dumping syntax +- selftests/bpf: fexit_sleep: Fix stack allocation for arm64 +- kbuild: avoid build error when single DTB is turned into composite DTB +- f2fs: fix to update user block counts in block_operations() +- watchdog: rzg2l_wdt: Check return status of pm_runtime_put() +- watchdog: rzg2l_wdt: Use pm_runtime_resume_and_get() +- f2fs: fix start segno of large section +- um: time-travel: fix signal blocking race/hang +- um: time-travel: fix time-travel-start option +- phy: zynqmp: Enable reference clock correctly +- phy: cadence-torrent: Check return value on register read +- dmaengine: ti: k3-udma: Fix BCHAN count with UHC and HC channels +- jfs: Fix array-index-out-of-bounds in diFree +- kdb: Use the passed prompt in kdb_position_cursor() +- kdb: address -Wformat-security warnings +- f2fs: fix to truncate preallocated blocks in f2fs_file_open() +- s390/mm: Fix VM_FAULT_HWPOISON handling in do_exception() +- PCI/DPC: Fix use-after-free on concurrent DPC and hot-removal +- PCI: Introduce cleanup helpers for device reference counts and locks +- wifi: mac80211: track capability/opmode NSS separately +- mm/mglru: fix ineffective protection calculation +- nilfs2: handle inconsistent state in nilfs_btnode_create_block() +- minmax: scsi: fix mis-use of 'clamp()' in sr.c +- Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x13d3:0x3591 +- Bluetooth: btusb: Add RTL8852BE device 0489:e125 to device tables +- video: logo: Drop full path of the input filename in generated file +- lib/build_OID_registry: don't mention the full path of the script in output +- rbd: don't assume RBD_LOCK_STATE_LOCKED for exclusive mappings +- rbd: rename RBD_LOCK_STATE_RELEASING and releasing_wait +- drm/panfrost: Mark simple_ondemand governor as softdep +- drm/etnaviv: don't block scheduler when GPU is still active +- MIPS: Loongson64: Test register availability before use +- MIPS: Loongson64: reset: Prioritise firmware service +- MIPS: Loongson64: Remove memory node for builtin-dtb +- MIPS: Loongson64: env: Hook up Loongsson-2K +- MIPS: dts: loongson: Fix GMAC phy node +- MIPS: ip30: ip30-console: Add missing include +- MIPS: dts: loongson: Add ISA node +- remoteproc: imx_rproc: Fix refcount mistake in imx_rproc_addr_init +- remoteproc: imx_rproc: Skip over memory region when node value is NULL +- remoteproc: stm32_rproc: Fix mailbox interrupts queuing +- rbd: don't assume rbd_is_lock_owner() for exclusive mappings +- dm-verity: fix dm_is_verity_target() when dm-verity is builtin +- selftests/sigaltstack: Fix ppc64 GCC build +- RDMA/iwcm: Fix a use-after-free related to destroying CM IDs +- platform: mips: cpu_hwmon: Disable driver on unsupported hardware +- watchdog/perf: properly initialize the turbo mode timestamp and rearm counter +- rtc: abx80x: Fix return value of nvmem callback on read +- rtc: isl1208: Fix return value of nvmem callbacks +- drm/i915/dp: Don't switch the LTTPR mode on an active link +- drm/i915/dp: Reset intel_dp->link_trained before retraining the link +- drm/amd/amdgpu: Fix uninitialized variable warnings +- drm/amdgpu: reset vm state machine after gpu reset(vram lost) +- drm/dp_mst: Fix all mstb marked as not probed after suspend/resume +- drm/udl: Remove DRM_CONNECTOR_POLL_HPD +- drm/amdgpu/sdma5.2: Update wptr registers as well as doorbell +- drm/i915/gt: Do not consider preemption during execlists_dequeue for gen8 +- perf/x86/intel/pt: Fix a topa_entry base address calculation +- perf/x86/intel/pt: Fix topa_entry base length +- perf/x86/intel/ds: Fix non 0 retire latency on Raptorlake +- perf/x86/intel/uncore: Fix the bits of the CHA extended umask for SPR +- perf stat: Fix the hard-coded metrics calculation on the hybrid +- perf: Fix event leak upon exit +- scsi: qla2xxx: validate nvme_local_port correctly +- scsi: qla2xxx: Complete command early within lock +- scsi: qla2xxx: Fix flash read failure +- scsi: qla2xxx: Reduce fabric scan duplicate code +- scsi: qla2xxx: Use QP lock to search for bsg +- scsi: qla2xxx: Fix for possible memory corruption +- scsi: qla2xxx: Unable to act on RSCN for port online +- scsi: qla2xxx: During vport delete send async logout explicitly +- scsi: lpfc: Allow DEVICE_RECOVERY mode after RSCN receipt if in PRLI_ISSUE state +- rtc: cmos: Fix return value of nvmem callbacks +- mm/numa_balancing: teach mpol_to_str about the balancing mode +- irqchip/imx-irqsteer: Handle runtime power management correctly +- irqdomain: Fixed unbalanced fwnode get and put +- devres: Fix memory leakage caused by driver API devm_free_percpu() +- devres: Fix devm_krealloc() wasting memory +- ice: Add a per-VF limit on number of FDIR filters +- gve: Fix an edge case for TSO skb validity check +- kobject_uevent: Fix OOB access within zap_modalias_env() +- ASoC: amd: yc: Support mic on Lenovo Thinkpad E16 Gen 2 +- ASoC: SOF: ipc4-topology: Preserve the DMA Link ID for ChainDMA on unprepare +- kbuild: Fix '-S -c' in x86 stack protector scripts +- decompress_bunzip2: fix rare decompression failure +- mm: fix old/young bit handling in the faulting path +- block: fix deadlock between sd_remove & sd_release +- ubi: eba: properly rollback inside self_check_eba +- clk: davinci: da8xx-cfgchip: Initialize clk_init_data before use +- f2fs: use meta inode for GC of COW file +- f2fs: use meta inode for GC of atomic file +- f2fs: fix return value of f2fs_convert_inline_inode() +- f2fs: fix to don't dirty inode for readonly filesystem +- f2fs: fix to force buffered IO on inline_data inode +- ASoC: fsl: fsl_qmc_audio: Check devm_kasprintf() returned value +- scsi: qla2xxx: Return ENOBUFS if sg_cnt is more than one for ELS cmds +- fs/ntfs3: Update log->page_{mask,bits} if log->page_size changed +- efi/libstub: Zero initialize heap allocated struct screen_info +- hostfs: fix dev_t handling +- dev/parport: fix the array out-of-bounds risk +- binder: fix hang of unregistered readers +- PCI: rockchip: Use GPIOD_OUT_LOW flag while requesting ep_gpio +- PCI: dw-rockchip: Fix initial PERST# GPIO value +- PCI: hv: Return zero, not garbage, when reading PCI_INTERRUPT_PIN +- parisc: Fix warning at drivers/pci/msi/msi.h:121 +- hwrng: amd - Convert PCIBIOS_* return codes to errnos +- tools/memory-model: Fix bug in lock.cat +- ALSA: usb-audio: Add a quirk for Sonix HD USB Camera +- ALSA: usb-audio: Move HD Webcam quirk to the right place +- ALSA: usb-audio: Fix microphone sound on HD webcam. +- ALSA: ump: Force 1 Group for MIDI1 FBs +- ALSA: ump: Don't update FB name for static blocks +- KVM: nVMX: Request immediate exit iff pending nested event needs injection +- KVM: VMX: Split out the non-virtualization part of vmx_interrupt_blocked() +- media: ivsc: csi: don't count privacy on as error +- media: uvcvideo: Fix integer overflow calculating timestamp +- jbd2: avoid infinite transaction commit loop +- jbd2: precompute number of transaction descriptor blocks +- jbd2: make jbd2_journal_get_max_txn_bufs() internal +- media: imx-pxp: Fix ERR_PTR dereference in pxp_probe() +- media: ivsc: csi: add separate lock for v4l2 control handler +- leds: mt6360: Fix memory leak in mt6360_init_isnk_properties() +- md/md-bitmap: fix writing non bitmap pages +- leds: ss4200: Convert PCIBIOS_* return codes to errnos +- drivers: soc: xilinx: check return status of get_api_version() +- wifi: rtw88: usb: Fix disconnection after beacon loss +- wifi: mwifiex: Fix interface type change +- selftests/landlock: Add cred_transfer test +- trace/pid_list: Change gfp flags in pid_list_fill_irq() +- io_uring: tighten task exit cancellations +- ext4: make sure the first directory block is not a hole +- ext4: check dot and dotdot of dx_root before making dir indexed +- m68k: amiga: Turn off Warp1260 interrupts during boot +- udf: Avoid using corrupted block bitmap buffer +- task_work: Introduce task_work_cancel() again +- task_work: s/task_work_cancel()/task_work_cancel_func()/ +- cifs: mount with "unix" mount option for SMB1 incorrectly handled +- cifs: fix reconnect with SMB1 UNIX Extensions +- cifs: fix potential null pointer use in destroy_workqueue in init_cifs error path +- apparmor: use kvfree_sensitive to free data->data +- drm/amd/display: Check for NULL pointer +- scsi: qla2xxx: Fix optrom version displayed in FDMI +- drm/gma500: fix null pointer dereference in psb_intel_lvds_get_modes +- drm/gma500: fix null pointer dereference in cdv_intel_lvds_get_modes +- io_uring/io-wq: limit retrying worker initialisation +- ext2: Verify bitmap and itable block numbers before using them +- hfs: fix to initialize fields of hfs_inode_info after hfs_alloc_inode() +- ata: libata-scsi: Honor the D_SENSE bit for CK_COND=1 and no error +- ata: libata-scsi: Do not overwrite valid sense data when CK_COND=1 +- media: venus: fix use after free in vdec_close +- char: tpm: Fix possible memory leak in tpm_bios_measurements_open() +- ata: libata-scsi: Fix offsets for the fixed format sense data +- fuse: verify {g,u}id mount options correctly +- sched/fair: set_load_weight() must also call reweight_task() for SCHED_IDLE tasks +- NFSD: Support write delegations in LAYOUTGET +- ipv6: take care of scope when choosing the src addr +- ipv4: fix source address selection with route leak +- kernel: rerun task_work while freezing in get_signal() +- btrfs: fix extent map use-after-free when adding pages to compressed bio +- af_packet: Handle outgoing VLAN packets without hardware offloading +- net: netconsole: Disable target before netpoll cleanup +- tick/broadcast: Make takeover of broadcast hrtimer reliable +- dt-bindings: thermal: correct thermal zone node name limit +- exfat: fix potential deadlock on __exfat_get_dentry_set +- x86/efistub: Revert to heap allocated boot_params for PE entrypoint +- x86/efistub: Avoid returning EFI_SUCCESS on error +- mm/mglru: fix overshooting shrinker memory +- mm: mmap_lock: replace get_memcg_path_buf() with on-stack buffer +- mm/mglru: fix div-by-zero in vmpressure_calc_level() +- mm/hugetlb: fix possible recursive locking detected warning +- hugetlb: force allocating surplus hugepages on mempolicy allowed nodes +- landlock: Don't lose track of restrictions on cred_transfer +- LoongArch: Check TIF_LOAD_WATCH to enable user space watchpoint +- sbitmap: use READ_ONCE to access map->word +- s390/dasd: fix error checks in dasd_copy_pair_store() +- powerpc/8xx: fix size given to set_huge_pte_at() +- fs/ntfs3: Keep runs for $MFT::$ATTR_DATA and $MFT::$ATTR_BITMAP +- fs/ntfs3: Missed error return +- fs/ntfs3: Fix the format of the "nocase" mount option +- rtc: interface: Add RTC offset to alarm after fix-up +- nilfs2: avoid undefined behavior in nilfs_cnt32_ge macro +- fs/proc/task_mmu: properly detect PM_MMAP_EXCLUSIVE per page of PMD-mapped THPs +- fs/proc/task_mmu: don't indicate PM_MMAP_EXCLUSIVE without PM_PRESENT +- fs/proc/task_mmu.c: add_to_pagemap: remove useless parameter addr +- fs/proc/task_mmu: indicate PM_FILE for PMD-mapped file THP +- pinctrl: renesas: r8a779g0: Fix TPU suffixes +- pinctrl: renesas: r8a779g0: Fix TCLK suffixes +- pinctrl: renesas: r8a779g0: FIX PWM suffixes +- pinctrl: renesas: r8a779g0: Fix IRQ suffixes +- pinctrl: renesas: r8a779g0: Fix (H)SCIF3 suffixes +- pinctrl: renesas: r8a779g0: Fix (H)SCIF1 suffixes +- pinctrl: renesas: r8a779g0: Fix FXR_TXEN[AB] suffixes +- pinctrl: renesas: r8a779g0: Fix CANFD5 suffix +- fs/ntfs3: Fix field-spanning write in INDEX_HDR +- fs/ntfs3: Drop stray '' (backslash) in formatting string +- fs/ntfs3: Correct undo if ntfs_create_inode failed +- fs/ntfs3: Replace inode_trylock with inode_lock +- pinctrl: freescale: mxs: Fix refcount of child +- pinctrl: ti: ti-iodelay: fix possible memory leak when pinctrl_enable() fails +- pinctrl: ti: ti-iodelay: Drop if block with always false condition +- pinctrl: single: fix possible memory leak when pinctrl_enable() fails +- pinctrl: core: fix possible memory leak when pinctrl_enable() fails +- pinctrl: rockchip: update rk3308 iomux routes +- fs/ntfs3: Add missing .dirty_folio in address_space_operations +- fs/ntfs3: Fix getting file type +- fs/ntfs3: Missed NI_FLAG_UPDATE_PARENT setting +- fs/ntfs3: Deny getting attr data block in compressed frame +- fs/ntfs3: Fix transform resident to nonresident for compressed files +- fs/ntfs3: Merge synonym COMPRESSION_UNIT and NTFS_LZNT_CUNIT +- net: dsa: b53: Limit chip-wide jumbo frame config to CPU ports +- net: dsa: mv88e6xxx: Limit chip-wide frame size config to CPU ports +- ipv4: Fix incorrect TOS in fibmatch route get reply +- ipv4: Fix incorrect TOS in route get reply +- net: flow_dissector: use DEBUG_NET_WARN_ON_ONCE +- gve: Fix XDP TX completion handling when counters overflow +- ipvs: properly dereference pe in ip_vs_add_service +- netfilter: nf_set_pipapo: fix initial map fill +- netfilter: nft_set_pipapo: constify lookup fn args where possible +- netfilter: ctnetlink: use helper function to calculate expect ID +- bnxt_re: Fix imm_data endianness +- RDMA: Fix netdev tracker in ib_device_set_netdev +- RDMA/core: Remove NULL check before dev_{put, hold} +- iommu/vt-d: Fix identity map bounds in si_domain_init() +- macintosh/therm_windtunnel: fix module unload. +- powerpc/xmon: Fix disassembly CPU feature checks +- PCI: dwc: Fix index 0 incorrectly being interpreted as a free ATU slot +- PCI: qcom-ep: Disable resources unconditionally during PERST# assert +- MIPS: Octeron: remove source file executable bit +- clk: en7523: fix rate divider for slic and spi clocks +- clk: qcom: Park shared RCGs upon registration +- clk: qcom: kpss-xcc: Return of_clk_add_hw_provider to transfer the error +- crypto: qat - extend scope of lock in adf_cfg_add_key_value_param() +- nvmem: rockchip-otp: set add_legacy_fixed_of_cells config option +- net: missing check virtio +- vhost/vsock: always initialize seqpacket_allow +- PCI: endpoint: Fix error handling in epf_ntb_epc_cleanup() +- PCI: endpoint: Clean up error handling in vpci_scan_bus() +- ASoC: amd: Adjust error handling in case of absent codec device +- Input: elan_i2c - do not leave interrupt disabled on suspend failure +- RDMA/device: Return error earlier if port in not valid +- mtd: make mtd_test.c a separate module +- ASoC: max98088: Check for clk_prepare_enable() error +- powerpc/prom: Add CPU info to hardware description string later +- hwrng: core - Fix wrong quality calculation at hw rng registration +- scsi: lpfc: Fix a possible null pointer dereference +- ASoC: qcom: Adjust issues in case of DT error in asoc_qcom_lpass_cpu_platform_probe() +- RDMA/rxe: Don't set BTH_ACK_MASK for UC or UD QPs +- RDMA/mlx5: Use sq timestamp as QP timestamp when RoCE is disabled +- RDMA/mlx4: Fix truncated output warning in alias_GUID.c +- RDMA/mlx4: Fix truncated output warning in mad.c +- Input: qt1050 - handle CHIP_ID reading error +- interconnect: qcom: qcm2290: Fix mas_snoc_bimc RPM master ID +- clk: qcom: gpucc-sa8775p: Update wait_val fields for GPU GDSC's +- clk: qcom: gpucc-sa8775p: Park RCG's clk source at XO during disable +- clk: qcom: gpucc-sa8775p: Remove the CLK_IS_CRITICAL and ALWAYS_ON flags +- clk: qcom: gcc-sa8775p: Update the GDSC wait_val fields and flags +- clk: qcom: gpucc-sm8350: Park RCG's clk source at XO during disable +- RDMA/cache: Release GID table even if leak is detected +- usb: typec-mux: nb7vpq904m: unregister typec switch on probe error and remove +- ASoC: cs35l56: Accept values greater than 0 as IRQ numbers +- ASoc: tas2781: Enable RCA-based playback without DSP firmware download +- RDMA/mlx5: Set mkeys for dmabuf at PAGE_SIZE +- coresight: Fix ref leak when of_coresight_parse_endpoint() fails +- KVM: PPC: Book3S HV: Fix the get_one_reg of SDAR +- KVM: PPC: Book3S HV: Fix the set_one_reg for MMCR3 +- iio: frequency: adrf6780: rm clk provider include +- clk: qcom: camcc-sc7280: Add parent dependency to all camera GDSCs +- clk: qcom: gcc-sc7280: Update force mem core bit for UFS ICE clock +- scsi: ufs: mcq: Fix missing argument 'hba' in MCQ_OPR_OFFSET_n +- PCI: rcar: Demote WARN() to dev_warn_ratelimited() in rcar_pcie_wakeup() +- PCI: keystone: Fix NULL pointer dereference in case of DT error in ks_pcie_setup_rc_app_regs() +- PCI: keystone: Don't enable BAR 0 for AM654x +- PCI: keystone: Relocate ks_pcie_set/clear_dbi_mode() +- PCI: Fix resource double counting on remove & rescan +- iio: Fix the sorting functionality in iio_gts_build_avail_time_table +- SUNRPC: Fixup gss_status tracepoint error output +- sparc64: Fix incorrect function signature and add prototype for prom_cif_init +- leds: flash: leds-qcom-flash: Test the correct variable in init +- ext4: avoid writing unitialized memory to disk in EA inodes +- ext4: don't track ranges in fast_commit if inode has inlined data +- NFSv4.1 another fix for EXCHGID4_FLAG_USE_PNFS_DS for DS server +- SUNRPC: avoid soft lockup when transmitting UDP to reachable server. +- xprtrdma: Fix rpcrdma_reqs_reset() +- mfd: omap-usb-tll: Use struct_size to allocate tll +- mfd: rsmu: Split core code into separate module +- perf intel-pt: Fix exclude_guest setting +- perf intel-pt: Fix aux_watermark calculation for 64-bit size +- media: venus: flush all buffers in output plane streamoff +- drm/mediatek/dp: Fix spurious kfree() +- drm/mediatek/dp: switch to ->edid_read callback +- ext4: fix infinite loop when replaying fast_commit +- drm/mediatek: Remove less-than-zero comparison of an unsigned value +- Revert "leds: led-core: Fix refcount leak in of_led_get()" +- drm/qxl: Add check for drm_cvt_mode +- drm/etnaviv: fix DMA direction handling for cached RW buffers +- perf report: Fix condition in sort__sym_cmp() +- perf pmus: Fixes always false when compare duplicates aliases +- perf test: Make test_arm_callgraph_fp.sh more robust +- drm/msm/dpu: drop validity checks for clear_pending_flush() ctl op +- drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC +- leds: trigger: Unregister sysfs attributes before calling deactivate() +- media: imx-jpeg: Drop initial source change event if capture has been setup +- drm/mediatek: Add OVL compatible name for MT8195 +- drm/mediatek: Turn off the layers with zero width or height +- drm/mediatek: Fix destination alpha error in OVL +- drm/mediatek: Fix XRGB setting error in Mixer +- drm/mediatek: Fix XRGB setting error in OVL +- drm/mediatek: Use 8-bit alpha in ETHDR +- drm/mediatek: Add missing plane settings when async update +- media: renesas: vsp1: Store RPF partition configuration per RPF instance +- media: renesas: vsp1: Fix _irqsave and _irq mix +- media: rcar-csi2: Cleanup subdevice in remove() +- media: rcar-csi2: Disable runtime_pm in probe error +- media: rcar-vin: Fix YUYV8_1X16 handling for CSI-2 +- drm: zynqmp_kms: Fix AUX bus not getting unregistered +- drm: zynqmp_dpsub: Fix an error handling path in zynqmp_dpsub_probe() +- media: uvcvideo: Override default flags +- media: uvcvideo: Add quirk for invalid dev_sof in Logitech C920 +- media: uvcvideo: Quirk for invalid dev_sof in Logitech C922 +- media: uvcvideo: Disable autosuspend for Insta360 Link +- media: i2c: imx219: fix msr access command sequence +- saa7134: Unchecked i2c_transfer function result fixed +- ipmi: ssif_bmc: prevent integer overflow on 32bit systems +- x86/shstk: Make return uprobe work with shadow stack +- media: mediatek: vcodec: Handle invalid decoder vsi +- s390/uv: Don't call folio_wait_writeback() without a folio reference +- s390/mm: Convert gmap_make_secure to use a folio +- s390/mm: Convert make_page_secure to use a folio +- media: v4l: async: Fix NULL pointer dereference in adding ancillary links +- media: i2c: Fix imx412 exposure control +- media: imon: Fix race getting ictx->lock +- media: pci: ivtv: Add check for DMA map result +- drm/bridge: it6505: fix hibernate to resume no display issue +- drm/bridge: Fixed a DP link training bug +- drm/panel: boe-tv101wum-nl6: Check for errors on the NOP in prepare() +- drm/panel: boe-tv101wum-nl6: If prepare fails, disable GPIO before regulators +- drm/panel: himax-hx8394: Handle errors from mipi_dsi_dcs_set_display_on() better +- drm/amdgpu: Remove GC HW IP 9.3.0 from noretry=1 +- drm/amdgpu: Check if NBIO funcs are NULL in amdgpu_device_baco_exit +- drm/amdgpu: Fix memory range calculation +- drm/amd/pm: Fix aldebaran pcie speed reporting +- drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_generic_write_seq() +- drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_dcs_write_seq() +- drm/amdkfd: Fix CU Masking for GFX 9.4.3 +- drm/arm/komeda: Fix komeda probe failing if there are no links in the secondary pipeline +- drm/rockchip: vop2: Fix the port mux of VP2 +- net: bridge: mst: Check vlan state for egress decision +- xdp: fix invalid wait context of page_pool_destroy() +- Bluetooth: btnxpuart: Add handling for boot-signature timeout errors +- Bluetooth: btintel: Refactor btintel_set_ppag() +- Bluetooth: hci_bcm4377: Use correct unit for timeouts +- selftests: forwarding: devlink_lib: Wait for udev events after reloading +- bpf: Eliminate remaining "make W=1" warnings in kernel/bpf/btf.o +- bna: adjust 'name' buf size of bna_tcb and bna_ccb structures +- bpf: annotate BTF show functions with __printf +- selftests/resctrl: Fix closing IMC fds on error and open-code R+W instead of loops +- selftests/resctrl: Convert perror() to ksft_perror() or ksft_print_msg() +- selftests/resctrl: Move run_benchmark() to a more fitting file +- selftests/bpf: Close obj in error path in xdp_adjust_tail +- selftests/bpf: Null checks for links in bpf_tcp_ca +- selftests/bpf: Close fd in error path in drop_on_reuseport +- locking/rwsem: Add __always_inline annotation to __down_write_common() and inlined callers +- wifi: virt_wifi: don't use strlen() in const context +- gss_krb5: Fix the error handling path for crypto_sync_skcipher_setkey +- wifi: virt_wifi: avoid reporting connection success with wrong SSID +- xfrm: call xfrm_dev_policy_delete when kill policy +- xfrm: fix netdev reference count imbalance +- wifi: rtw89: Fix array index mistake in rtw89_sta_info_get_iter() +- perf/x86/intel/cstate: Fix Alderlake/Raptorlake/Meteorlake +- perf: Fix default aux_watermark calculation +- perf: Prevent passing zero nr_pages to rb_alloc_aux() +- perf: Fix perf_aux_size() for greater-than 32-bit size +- perf/x86/intel/pt: Fix pt_topa_entry_for_page() address calculation +- bpftool: Mount bpffs when pinmaps path not under the bpffs +- wifi: rtl8xxxu: 8188f: Limit TX power index +- wifi: rtw89: 8852b: fix definition of KIP register number +- netfilter: nf_tables: rise cap on SELinux secmark context +- ipvs: Avoid unnecessary calls to skb_is_gso_sctp +- libbpf: Checking the btf_type kind when fixing variable offsets +- net: fec: Fix FEC_ECR_EN1588 being cleared on link-down +- net: fec: Refactor: #define magic constants +- udf: Fix bogus checksum computation in udf_rename() +- wifi: cfg80211: handle 2x996 RU allocation in cfg80211_calculate_bitrate_he() +- wifi: cfg80211: fix typo in cfg80211_calculate_bitrate_he() +- wifi: ath11k: fix wrong handling of CCMP256 and GCMP ciphers +- jump_label: Fix concurrency issues in static_key_slow_dec() +- perf/x86: Serialize set_attr_rdpmc() +- mlxsw: spectrum_acl: Fix ACL scale regression and firmware errors +- mlxsw: spectrum_acl_erp: Fix object nesting warning +- lib: objagg: Fix general protection fault +- udf: Fix lock ordering in udf_evict_inode() +- selftests/bpf: Check length of recv in test_sockmap +- net/smc: set rmb's SG_MAX_SINGLE_ALLOC limitation only when CONFIG_ARCH_NO_SG_CHAIN is defined +- tcp: fix races in tcp_v[46]_err() +- tcp: fix race in tcp_write_err() +- tcp: add tcp_done_with_error() helper +- wifi: ath12k: fix wrong definition of CE ring's base address +- wifi: ath11k: fix wrong definition of CE ring's base address +- wifi: ath11k: Update Qualcomm Innovation Center, Inc. copyrights +- wifi: ath12k: fix firmware crash during reo reinject +- wifi: ath12k: fix invalid memory access while processing fragmented packets +- wifi: ath12k: change DMA direction while mapping reinjected packets +- net: esp: cleanup esp_output_tail_tcp() in case of unsupported ESPINTCP +- selftests/bpf: Fix prog numbers in test_sockmap +- bpftool: Un-const bpf_func_info to fix it for llvm 17 and newer +- wifi: ath12k: Fix tx completion ring (WBM2SW) setup failure +- wifi: ath12k: Correct 6 GHz frequency value in rx status +- wifi: brcmsmac: LCN PHY code is used for BCM4313 2G-only device +- firmware: turris-mox-rwtm: Initialize completion before mailbox +- firmware: turris-mox-rwtm: Fix checking return value of wait_for_completion_timeout() +- firmware: turris-mox-rwtm: Do not complete if there are no waiters +- vmlinux.lds.h: catch .bss..L* sections into BSS") +- ARM: spitz: fix GPIO assignment for backlight +- m68k: cmpxchg: Fix return value for default case in __arch_xchg() +- cpufreq/amd-pstate: Fix the scaling_max_freq setting on shared memory CPPC systems +- arm64: dts: qcom: sm6350: Add missing qcom,non-secure-domain property +- arm64: dts: rockchip: fixes PHY reset for Lunzn Fastrhino R68S +- arm64: dts: rockchip: disable display subsystem for Lunzn Fastrhino R6xS +- arm64: dts: rockchip: remove unused usb2 nodes for Lunzn Fastrhino R6xS +- arm64: dts: rockchip: fix pmu_io supply for Lunzn Fastrhino R6xS +- arm64: dts: rockchip: fix usb regulator for Lunzn Fastrhino R6xS +- arm64: dts: rockchip: fix regulator name for Lunzn Fastrhino R6xS +- arm64: dts: rockchip: Add missing power-domains for rk356x vop_mmu +- x86/xen: Convert comma to semicolon +- arm64: dts: imx8mp: Fix pgc vpu locations +- arm64: dts: imx8mp: add HDMI power-domains +- arm64: dts: imx8mp: Fix pgc_mlmix location +- arm64: dts: imx8mp: Add NPU Node +- m68k: atari: Fix TT bootup freeze / unexpected (SCU) interrupt messages +- arm64: dts: renesas: r9a07g054: Add missing hypervisor virtual timer IRQ +- arm64: dts: renesas: r9a07g044: Add missing hypervisor virtual timer IRQ +- arm64: dts: renesas: r9a07g043u: Add missing hypervisor virtual timer IRQ +- arm64: dts: renesas: r8a779g0: Add missing hypervisor virtual timer IRQ +- arm64: dts: renesas: r8a779f0: Add missing hypervisor virtual timer IRQ +- arm64: dts: renesas: r8a779a0: Add missing hypervisor virtual timer IRQ +- arm64: dts: rockchip: Fix mic-in-differential usage on rk3568-evb1-v10 +- arm64: dts: rockchip: Fix mic-in-differential usage on rk3566-roc-pc +- arm64: dts: rockchip: Drop invalid mic-in-differential on rk3568-rock-3a +- arm64: dts: amlogic: setup hdmi system clock +- arm64: dts: amlogic: add power domain to hdmitx +- arm64: dts: amlogic: gx: correct hdmi clocks +- arm64: dts: mediatek: mt8183-kukui-jacuzzi: Add ports node for anx7625 +- arm64: dts: mediatek: mt8183-kukui: Fix the value of `dlg,jack-det-rate` mismatch +- arm64: dts: mediatek: mt7622: fix "emmc" pinctrl mux +- arm64: dts: mediatek: mt8192-asurada: Add off-on-delay-us for pp3300_mipibrdg +- arm64: dts: mediatek: mt8183-kukui: Drop bogus output-enable property +- arm64: dts: mediatek: mt8195: Fix GPU thermal zone name for SVS +- ARM: dts: imx6qdl-kontron-samx6i: fix PCIe reset polarity +- ARM: dts: imx6qdl-kontron-samx6i: fix SPI0 chip selects +- ARM: dts: imx6qdl-kontron-samx6i: fix board reset +- ARM: dts: imx6qdl-kontron-samx6i: fix PHY reset +- ARM: dts: imx6qdl-kontron-samx6i: fix phy-mode +- arm64: dts: amlogic: sm1: fix spdif compatibles +- arm64: dts: rockchip: Increase VOP clk rate on RK3328 +- soc: qcom: pdr: fix parsing of domains lists +- soc: qcom: pdr: protect locator_addr with the main mutex +- soc: qcom: icc-bwmon: Fix refcount imbalance seen during bwmon_remove +- arm64: dts: qcom: qdu1000: Add secure qfprom node +- arm64: dts: qcom: qdu1000-idp: drop unused LLCC multi-ch-bit-off +- arm64: dts: ti: k3-am62-verdin: Drop McASP AFIFOs +- arm64: dts: ti: k3-am625-beagleplay: Drop McASP AFIFOs +- arm64: dts: ti: k3-am62x: Drop McASP AFIFOs +- memory: fsl_ifc: Make FSL_IFC config visible and selectable +- OPP: ti: Fix ti_opp_supply_probe wrong return values +- cpufreq: ti-cpufreq: Handle deferred probe with dev_err_probe() +- arm64: dts: qcom: qrb4210-rb2: make L9A always-on +- ARM: dts: stm32: Add arm,no-tick-in-suspend to STM32MP15xx STGEN timer +- ARM: dts: sunxi: remove duplicated entries in makefile +- soc: xilinx: rename cpu_number1 to dummy_cpu_number +- arm64: dts: qcom: sa8775p: mark ethernet devices as DMA-coherent +- arm64: dts: qcom: msm8996: specify UFS core_clk frequencies +- arm64: dts: rockchip: Update WIFi/BT related nodes on rk3308-rock-pi-s +- arm64: dts: rockchip: Add mdio and ethernet-phy nodes to rk3308-rock-pi-s +- arm64: dts: rockchip: Add pinctrl for UART0 to rk3308-rock-pi-s +- arm64: dts: rockchip: Add sdmmc related properties on rk3308-rock-pi-s +- soc: qcom: rpmh-rsc: Ensure irqs aren't disabled by rpmh_rsc_send_data() callers +- soc: qcom: pmic_glink: Handle the return value of pmic_glink_init +- arm64: dts: qcom: msm8998: enable adreno_smmu by default +- arm64: dts: qcom: sdm850-lenovo-yoga-c630: fix IPA firmware path +- arm64: dts: qcom: msm8996-xiaomi-common: drop excton from the USB PHY +- arm64: dts: qcom: sm8450: add power-domain to UFS PHY +- arm64: dts: qcom: sm8350: add power-domain to UFS PHY +- arm64: dts: qcom: sm8250: add power-domain to UFS PHY +- arm64: dts: qcom: sm8250: switch UFS QMP PHY to new style of bindings +- arm64: dts: qcom: sm6350: add power-domain to UFS PHY +- arm64: dts: qcom: sm6115: add power-domain to UFS PHY +- arm64: dts: qcom: sdm845: add power-domain to UFS PHY +- arm64: dts: qcom: sc8180x: add power-domain to UFS PHY +- arm64: dts: qcom: sc8180x: switch UFS QMP PHY to new style of bindings +- arm64: dts: qcom: sc8180x: Correct PCIe slave ports +- hwmon: (max6697) Fix swapped temp{1,8} critical alarms +- hwmon: (max6697) Fix underflow when writing limit attributes +- pwm: atmel-tcb: Fix race condition and convert to guards +- drm/meson: fix canvas release in bind function +- nvmet-auth: fix nvmet_auth hash error handling +- pwm: stm32: Always do lazy disabling +- md: Don't wait for MD_RECOVERY_NEEDED for HOT_REMOVE_DISK ioctl +- block/mq-deadline: Fix the tag reservation code +- block: Call .limit_depth() after .hctx has been set +- hwmon: (adt7475) Fix default duty on fan is disabled +- x86/platform/iosf_mbi: Convert PCIBIOS_* return codes to errnos +- x86/pci/xen: Fix PCIBIOS_* return code handling +- x86/pci/intel_mid_pci: Fix PCIBIOS_* return code handling +- x86/of: Return consistent error type from x86_of_pci_irq_enable() +- hfsplus: fix to avoid false alarm of circular locking +- x86/kconfig: Add as-instr64 macro to properly evaluate AS_WRUSS +- block: initialize integrity buffer to zero before writing it to media +- ubd: untagle discard vs write zeroes not support handling +- ubd: refactor the interrupt handler +- platform/chrome: cros_ec_debugfs: fix wrong EC message version +- md: fix deadlock between mddev_suspend and flush bio +- rcu/tasks: Fix stale task snaphot for Tasks Trace +- EDAC, i10nm: make skx_common.o a separate module +- spi: atmel-quadspi: Add missing check for clk_prepare +- spi: spi-microchip-core: Fix the number of chip selects supported +- powerpc/configs: Update defconfig with now user-visible CONFIG_FSL_IFC +- ALSA: seq: ump: Skip useless ports for static blocks +- ALSA: pcm_dmaengine: Don't synchronize DMA channel when DMA is paused +- arm64: dts: qcom: sdm630: Disable SS instance in Parkmode for USB +- arm64: dts: qcom: ipq6018: Disable SS instance in Parkmode for USB +- arm64: dts: qcom: sm6350: Disable SS instance in Parkmode for USB +- arm64: dts: qcom: msm8996: Disable SS instance in Parkmode for USB +- arm64: dts: qcom: qrb4210-rb2: switch I2C2 to i2c-gpio +- ALSA: hda/realtek: Fix the speaker output on Samsung Galaxy Book Pro 360 +- ALSA: hda/realtek: Enable headset mic on Positivo SU C1400 +- usb: gadget: midi2: Fix incorrect default MIDI2 protocol setup +- jfs: don't walk off the end of ealist +- ocfs2: add bounds checking to ocfs2_check_dir_entry() +- cachefiles: fix slab-use-after-free in cachefiles_withdraw_cookie() +- cachefiles: fix slab-use-after-free in fscache_withdraw_volume() +- netfs, fscache: export fscache_put_volume() and add fscache_try_get_volume() +- wifi: iwlwifi: mvm: don't wake up rx_sync_waitq upon RFKILL +- wifi: mac80211: disable softirqs for queued frame handling +- wifi: cfg80211: wext: set ssids=NULL for passive scans +- of/irq: Disable "interrupt-map" parsing for PASEMI Nemo +- mm: page_ref: remove folio_try_get_rcu() +- ARM: 9324/1: fix get_user() broken with veneer +- cifs: fix noisy message on copy_file_range +- ALSA: hda: Use imply for suggesting CONFIG_SERIAL_MULTI_INSTANTIATE +- spi: mux: set ctlr->bits_per_word_mask +- selftests/bpf: Extend tcx tests to cover late tcx_entry release +- hfsplus: fix uninit-value in copy_name +- selftests/vDSO: fix clang build errors and warnings +- selftest/timerns: fix clang build failures for abs() calls +- ASoC: SOF: Intel: hda-pcm: Limit the maximum number of periods by MAX_BDL_ENTRIES +- ksmbd: return FILE_DEVICE_DISK instead of super magic +- spi: imx: Don't expect DMA for i.MX{25,35,50,51,53} cspi devices +- riscv: stacktrace: fix usage of ftrace_graph_ret_addr() +- drivers/perf: riscv: Reset the counter to hpmevent mapping while starting cpus +- wifi: iwlwifi: properly set WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK +- fs: better handle deep ancestor chains in is_subdir() +- drm/radeon: check bo_va->bo is non-NULL before using it +- drm/amd/display: Fix refresh rate range for some panel +- drm/amd/display: Account for cursor prefetch BW in DML1 mode support +- drm/amd/display: Add refresh rate range check +- erofs: ensure m_llen is reset to 0 if metadata is invalid +- Bluetooth: btnxpuart: Enable Power Save feature on startup +- tee: optee: ffa: Fix missing-field-initializers warning +- scsi: libsas: Fix exp-attached device scan after probe failure scanned in again after probe failed +- powerpc/pseries: Whitelist dtl slub object for copying to userspace +- net: mac802154: Fix racy device stats updates by DEV_STATS_INC() and DEV_STATS_ADD() +- net: usb: qmi_wwan: add Telit FN912 compositions +- ASoC: amd: yc: Fix non-functional mic on ASUS M5602RA +- ALSA: dmaengine_pcm: terminate dmaengine before synchronize +- ALSA: hda/relatek: Enable Mute LED on HP Laptop 15-gw0xxx +- ALSA: PCM: Allow resume only for suspended streams +- ibmvnic: Add tx check to prevent skb leak +- btrfs: qgroup: fix quota root leak after quota disable failure +- platform/x86: lg-laptop: Use ACPI device handle when evaluating WMAB/WMBB +- platform/x86: lg-laptop: Change ACPI device id +- platform/x86: lg-laptop: Remove LGEX0815 hotkey handling +- platform/x86: wireless-hotkey: Add support for LG Airplane Button +- platform/mellanox: nvsw-sn2201: Add check for platform_device_add_resources +- s390/sclp: Fix sclp_init() cleanup on failure +- octeontx2-pf: Fix coverity and klockwork issues in octeon PF driver +- gpio: pca953x: fix pca953x_irq_bus_sync_unlock race +- can: kvaser_usb: fix return value for hif_usb_send_regout +- Input: ads7846 - use spi_device_id table +- nvme: fix NVME_NS_DEAC may incorrectly identifying the disk as EXT_LBA. +- ASoC: rt722-sdca-sdw: add debounce time for type detection +- ASoC: SOF: sof-audio: Skip unprepare for in-use widgets on error rollback +- ASoC: ti: omap-hdmi: Fix too long driver name +- ASoC: ti: davinci-mcasp: Set min period size using FIFO config +- ALSA: dmaengine: Synchronize dma channel after drop() +- bytcr_rt5640 : inverse jack detect for Archos 101 cesium +- Input: xpad - add support for ASUS ROG RAIKIRI PRO +- ASoC: rt722-sdca-sdw: add silence detection register as volatile +- Input: i8042 - add Ayaneo Kun to i8042 quirk table +- Input: elantech - fix touchpad state on resume for Lenovo N24 +- mips: fix compat_sys_lseek syscall +- ALSA: hda: cs35l56: Select SERIAL_MULTI_INSTANTIATE +- drm/amdgpu: Indicate CU havest info to CP +- selftests: openvswitch: Set value to nla flags. +- cpumask: limit FORCE_NR_CPUS to just the UP case +- spi: Fix OCTAL mode support +- ALSA: hda/realtek: Add more codec ID to no shutup pins list +- drm/vmwgfx: Fix missing HYPERVISOR_GUEST dependency +- KVM: PPC: Book3S HV: Prevent UAF in kvm_spapr_tce_attach_iommu_group() +- ALSA: hda/realtek: Support Lenovo Thinkbook 16P Gen 5 +- ALSA: hda: cs35l56: Fix lifecycle of codec pointer +- nvmet: always initialize cqe.result +- nvme: avoid double free special payload +- drm/mediatek: Call drm_atomic_helper_shutdown() at shutdown time +- drm: panel-orientation-quirks: Add quirk for Aya Neo KUN +- drm/exynos: dp: drop driver owner initialization +- iomap: Fix iomap_adjust_read_range for plen calculation +- mei: demote client disconnect warning on suspend to debug +- fs/file: fix the check in find_next_fd() +- nfs: don't invalidate dentries on transient errors +- nfs: Avoid flushing many pages with NFS_FILE_SYNC +- nfs: propagate readlink errors in nfs_symlink_filler +- HID: Ignore battery for ELAN touchscreens 2F2C and 4116 +- input: Add support for "Do Not Disturb" +- input: Add event code for accessibility key +- kconfig: remove wrong expr_trans_bool() +- kconfig: gconf: give a proper initial state to the Save button +- ila: block BH in ila_output() +- net: ipv6: rpl_iptunnel: block BH in rpl_output() and rpl_input() +- Input: silead - Always support 10 fingers +- of/irq: Factor out parsing of interrupt-map parent phandle+args from of_irq_parse_raw() +- selftests/futex: pass _GNU_SOURCE without a value to the compiler +- selftests/openat2: Fix build warnings on ppc64 +- selftests: cachestat: Fix build warnings on ppc64 +- wifi: mac80211: fix UBSAN noise in ieee80211_prep_hw_scan() +- wifi: iwlwifi: mvm: Fix scan abort handling with HW rfkill +- wifi: iwlwifi: mvm: properly set 6 GHz channel direct probe option +- wifi: iwlwifi: mvm: handle BA session teardown in RF-kill +- wifi: iwlwifi: mvm: Handle BIGTK cipher in kek_kck cmd +- wifi: iwlwifi: mvm: remove stale STA link data during restart +- wifi: iwlwifi: mvm: d3: fix WoWLAN command version lookup +- wifi: cfg80211: fix 6 GHz scan request building +- wifi: mac80211: handle tasklet frames before stopping +- wifi: mac80211: apply mcast rate only if interface is up +- wifi: mac80211: mesh: init nonpeer_pm to active by default in mesh sdata +- tools/power/cpupower: Fix Pstate frequency reporting on AMD Family 1Ah CPUs +- ACPI: EC: Avoid returning AE_OK on errors in address space handler +- ACPI: EC: Abort address space access upon error +- efi/libstub: zboot.lds: Discard .discard sections +- scsi: qedf: Set qed_slowpath_params to zero before use +- scsi: qedf: Wait for stag work during unload +- scsi: qedf: Don't process stag work during unload and recovery +- scsi: sr: Fix unintentional arithmetic wraparound +- scsi: core: alua: I/O errors for ALUA state transitions +- filelock: Remove locks reliably when fcntl/close race is detected +- i2c: rcar: fix error code in probe() +- kbuild: Make ld-version.sh more robust against version string changes +- x86/bhi: Avoid warning in #DB handler due to BHI mitigation +- x86/entry/64: Remove obsolete comment on tracing vs. SYSRET +- x86/entry: Rename ignore_sysret() +- i2c: rcar: clear NO_RXDMA flag after resetting +- i2c: testunit: avoid re-issued work after read message +- i2c: rcar: ensure Gen3+ reset does not disturb local targets +- i2c: rcar: introduce Gen4 devices +- i2c: rcar: reset controller is mandatory for Gen3+ +- i2c: mark HostNotify target address as used +- i2c: rcar: bring hardware to known state when probing +- btrfs: tree-checker: add type and sequence check for inline backrefs +- ext4: avoid ptr null pointer dereference +- nilfs2: fix kernel bug on rename operation of broken directory +- selftests/net: fix gro.c compilation failure due to non-existent opt_ipproto_off +- mm/damon/core: merge regions aggressively when max_nr_regions is unmet +- mm/shmem: disable PMD-sized page cache if needed +- misc: fastrpc: Restrict untrusted app to attach to privileged PD +- misc: fastrpc: Fix ownership reassignment of remote heap +- misc: fastrpc: Fix memory leak in audio daemon attach operation +- misc: fastrpc: Copy the complete capability structure to user +- misc: fastrpc: Avoid updating PD type for capability request +- misc: fastrpc: Fix DSP capabilities request +- wireguard: send: annotate intentional data race in checking empty queue +- wireguard: queueing: annotate intentional data race in cpu round robin +- wireguard: allowedips: avoid unaligned 64-bit memory accesses +- wireguard: selftests: use acpi=off instead of -no-acpi for recent QEMU +- cpufreq: Allow drivers to advertise boost enabled +- cpufreq: ACPI: Mark boost policy as enabled when setting boost +- ACPI: processor_idle: Fix invalid comparison with insertion sort for latency +- libceph: fix race between delayed_work() and ceph_monc_stop() +- pmdomain: qcom: rpmhpd: Skip retention level for Power Domains +- Fix userfaultfd_api to return EINVAL as expected +- ALSA: hda/realtek: Limit mic boost on VAIO PRO PX +- ALSA: hda/realtek: Enable Mute LED on HP 250 G7 +- ALSA: hda/realtek: add quirk for Clevo V5[46]0TU +- tty: serial: ma35d1: Add a NULL check for of_node +- platform/x86: toshiba_acpi: Fix array out-of-bounds access +- nvmem: core: only change name to fram for current attribute +- nvmem: meson-efuse: Fix return value of nvmem callbacks +- nvmem: rmem: Fix return value of rmem_read() +- arm64: dts: qcom: sc8280xp-x13s: fix touchscreen power on +- arm64: dts: qcom: sa8775p: Correct IRQ number of EL2 non-secure physical timer +- iio: trigger: Fix condition for own trigger +- ksmbd: discard write access to the directory open +- mm/filemap: make MAX_PAGECACHE_ORDER acceptable to xarray +- mm/filemap: skip to create PMD-sized page cache if needed +- mm: vmalloc: check if a hash-index is in cpu_possible_mask +- s390/mm: Add NULL pointer check to crst_table_free() base_crst_free() +- xhci: always resume roothubs if xHC was reset during resume +- hpet: Support 32-bit userspace +- misc: microchip: pci1xxxx: Fix return value of nvmem callbacks +- USB: core: Fix duplicate endpoint bug by clearing reserved bits in the descriptor +- usb: gadget: configfs: Prevent OOB read/write in usb_string_copy() +- usb: dwc3: pci: add support for the Intel Panther Lake +- USB: Add USB_QUIRK_NO_SET_INTF quirk for START BP-850k +- USB: serial: mos7840: fix crash on resume +- USB: serial: option: add Rolling RW350-GL variants +- USB: serial: option: add Netprisma LCUK54 series modules +- USB: serial: option: add support for Foxconn T99W651 +- USB: serial: option: add Fibocom FM350-GL +- USB: serial: option: add Telit FN912 rmnet compositions +- USB: serial: option: add Telit generic core-dump composition +- net: ks8851: Fix potential TX stall after interface reopen +- net: ks8851: Fix deadlock with the SPI chip variant +- Revert "sched/fair: Make sure to try to detach at least one movable task" +- cifs: fix setting SecurityFlags to true +- octeontx2-af: fix issue with IPv4 match for RSS +- octeontx2-af: fix issue with IPv6 ext match for RSS +- octeontx2-af: fix detection of IP layer +- octeontx2-af: fix a issue with cpt_lf_alloc mailbox +- octeontx2-af: replace cpt slot with lf id on reg write +- i40e: fix: remove needless retries of NVM update +- ARM: davinci: Convert comma to semicolon +- ASoC: SOF: Intel: hda: fix null deref on system suspend entry +- firmware: cs_dsp: Prevent buffer overrun when processing V2 alg headers +- firmware: cs_dsp: Validate payload length before processing block +- firmware: cs_dsp: Return error if block header overflows file +- arm64: dts: qcom: sc8180x: Fix LLCC reg property again +- s390: Mark psw in __load_psw_mask() as __unitialized +- net, sunrpc: Remap EPERM in case of connection failure in xs_tcp_setup_socket +- ethtool: netlink: do not return SQI value if link is down +- net: ethernet: mtk-star-emac: set mac_managed_pm when probing +- bpf: Fail bpf_timer_cancel when callback is being cancelled +- bpf: replace bpf_timer_init with a generic helper +- bpf: make timer data struct more generic +- bpf: fix order of args in call to bpf_map_kvcalloc +- i40e: Fix XDP program unloading while removing the driver +- octeontx2-af: Fix incorrect value output on error path in rvu_check_rsrc_availability() +- net: phy: microchip: lan87xx: reinit PHY after cable test +- tcp: fix incorrect undo caused by DSACK of TLP retransmit +- net: bcmasp: Fix error code in probe() +- vfs: don't mod negative dentry count when on shrinker list +- fs/dcache: Re-use value stored to dentry->d_flags instead of re-reading +- dsa: lan9303: Fix mapping between DSA port number and PHY address +- cachefiles: add missing lock protection when polling +- cachefiles: cyclic allocation of msg_id to avoid reuse +- cachefiles: wait for ondemand_object_worker to finish when dropping object +- cachefiles: cancel all requests for the object that is being dropped +- cachefiles: stop sending new request when dropping object +- cachefiles: propagate errors from vfs_getxattr() to avoid infinite loop +- scsi: ufs: core: Fix ufshcd_abort_one racing issue +- scsi: ufs: core: Fix ufshcd_clear_cmd racing issue +- mm: prevent derefencing NULL ptr in pfn_section_valid() +- Compiler Attributes: Add __uninitialized macro +- !10610 wifi: cfg80211: wext: add extra SIOCSIWSCAN data check +- wifi: cfg80211: wext: add extra SIOCSIWSCAN data check +- !10599 ppp: reject claimed-as-LCP but actually malformed packets +- ppp: reject claimed-as-LCP but actually malformed packets +- !10539 tun: add missing verification for short frame +- tun: add missing verification for short frame +- !10538 tap: add missing verification for short frame +- tap: add missing verification for short frame +- !10555 skmsg: Skip zero length skb in sk_msg_recvmsg +- skmsg: Skip zero length skb in sk_msg_recvmsg +- !10596 net: ethernet: lantiq_etop: fix double free in detach +- net: ethernet: lantiq_etop: fix double free in detach +- !10517 mm/dynamic_pool: two bugfix about THP and migration +- mm/dynamic_pool: check page_from_dynamic_pool() on migration +- mm/dynamic_pool: replace task_in_dynamic_pool() with mm_in_dynamic_pool() +- !10579 Fix CVE-2024-41062 +- Bluetooth: Fix usage of __hci_cmd_sync_status +- Bluetooth: L2CAP: Fix deadlock +- bluetooth/l2cap: sync sock recv cb and release +- !10545 bpf: Take return from set_memory_ro() into account with bpf_prog_lock_ro() +- bpf: Take return from set_memory_ro() into account with bpf_prog_lock_ro() +- !10547 powerpc/eeh: avoid possible crash when edev->pdev changes +- powerpc/eeh: avoid possible crash when edev->pdev changes +- !10470 Make cpuset.cpus.exclusive independent of cpuset.cpus +- cgroup/cpuset: Make cpuset.cpus.exclusive independent of cpuset.cpus +- cgroup/cpuset: Delay setting of CS_CPU_EXCLUSIVE until valid partition +- cgroup/cpuset: Documentation update for partition +- !10443 v2 cxl/mem: Fix no cxl_nvd during pmem region auto-assembling +- cxl/mem: Fix no cxl_nvd during pmem region auto-assembling +- !10351 bpf: Fix null-pointer-deref in resolve_prog_type() +- selftests/bpf: Test for null-pointer-deref bugfix in resolve_prog_type() +- bpf: Fix null pointer dereference in resolve_prog_type() for BPF_PROG_TYPE_EXT +- !10401 firmware: cs_dsp: Use strnlen() on name fields in V1 wmfw files +- firmware: cs_dsp: Use strnlen() on name fields in V1 wmfw files +- !10512 powerpc: Avoid nmi_enter/nmi_exit in real mode interrupt. +- powerpc: Avoid nmi_enter/nmi_exit in real mode interrupt. +- !10524 Bluetooth: hci_core: cancel all works upon hci_unregister_dev() +- Bluetooth: hci_core: cancel all works upon hci_unregister_dev() +- !10486 fix CVE-2024-42086 +- iio: chemical: bme680: Fix overflows in compensate() functions +- !10466 null_blk: fix validation of block size +- null_blk: fix validation of block size +- !10480 ALSA: emux: improve patch ioctl data validation +- ALSA: emux: improve patch ioctl data validation +- !10385 firmware: cs_dsp: Fix overflow checking of wmfw header +- firmware: cs_dsp: Fix overflow checking of wmfw header +- !10403 Fix CVE-2024-41069 +- ASoC: topology: Fix route memory corruption +- ASoC: topology: Do not assign fields that are already set +- ASoC: topology: Fix references to freed memory +- !10474 jffs2: Fix potential illegal address access in jffs2_free_inode +- jffs2: Fix potential illegal address access in jffs2_free_inode +- !10463 io_uring: fix possible deadlock in io_register_iowq_max_workers() +- io_uring: fix possible deadlock in io_register_iowq_max_workers() +- !10456 NFSv4: Fix memory leak in nfs4_set_security_label +- NFSv4: Fix memory leak in nfs4_set_security_label +- !10450 fs/ntfs3: Validate ff offset +- fs/ntfs3: Validate ff offset +- !10394 filelock: Fix fcntl/close race recovery compat path +- filelock: Fix fcntl/close race recovery compat path +- !10496 PCI/MSI: Fix UAF in msi_capability_init +- PCI/MSI: Fix UAF in msi_capability_init +- !10380 filelock: fix potential use-after-free in posix_lock_inode +- filelock: fix potential use-after-free in posix_lock_inode +- !10378 fs/ntfs3: Add a check for attr_names and oatbl +- fs/ntfs3: Add a check for attr_names and oatbl +- !10491 Bluetooth: ISO: Check socket flag instead of hcon +- Bluetooth: ISO: Check socket flag instead of hcon +- !10495 drm/amdgpu: Using uninitialized value *size when calling amdgpu_vce_cs_reloc +- drm/amdgpu: Using uninitialized value *size when calling amdgpu_vce_cs_reloc +- !10442 net/sched: Fix UAF when resolving a clash +- net/sched: Fix UAF when resolving a clash +- !10457 udp: Set SOCK_RCU_FREE earlier in udp_lib_get_port(). +- udp: Set SOCK_RCU_FREE earlier in udp_lib_get_port(). +- !10371 iommu/arm-smmu-v3: Reducing the CMD_SYNC times +- iommu/arm-smmu-v3: Reducing the CMD_SYNC times +- !10228 PCI/ROM: Fix PCI ROM header check bug +- PCI/ROM: Fix PCI ROM header check bug +- !10416 [sync] PR-10408: iommu/arm-smmu-v3: Fix the compile warning +- iommu/arm-smmu-v3: Fix the compile warning +- !9824 fix CVE-2024-39486 +- drm/drm_file: Fix pid refcounting race +- !10388 ovl: simplify ovl_parse_param_lowerdir() +- ovl: ovl_parse_param_lowerdir: Add missed ' +- ovl: fix wrong lowerdir number check for parameter Opt_lowerdir +- ovl: pass string to ovl_parse_layer() +- !10507 Backport 6.6.35-40 LTS patches from upstream +- Revert "usb: xhci: prevent potential failure in handle_tx_event() for Transfer events without TRB" +- nilfs2: fix incorrect inode allocation from reserved inodes +- null_blk: Do not allow runt zone with zone capacity smaller then zone size +- drm/amdgpu: silence UBSAN warning +- ALSA: ump: Set default protocol when not given explicitly +- spi: cadence: Ensure data lines set to low during dummy-cycle period +- nfc/nci: Add the inconsistency check between the input data length and count +- kbuild: fix short log for AS in link-vmlinux.sh +- nvmet: fix a possible leak when destroy a ctrl during qp establishment +- platform/x86: touchscreen_dmi: Add info for the EZpad 6s Pro +- platform/x86: touchscreen_dmi: Add info for GlobalSpace SolT IVW 11.6" tablet +- regmap-i2c: Subtract reg size from max_write +- nvme: adjust multiples of NVME_CTRL_PAGE_SIZE in offset +- connector: Fix invalid conversion in cn_proc.h +- dma-mapping: benchmark: avoid needless copy_to_user if benchmark fails +- nvme-multipath: find NUMA path only for online numa-node +- vhost-scsi: Handle vhost_vq_work_queue failures for events +- ALSA: hda/realtek: Enable headset mic of JP-IK LEAP W502 with ALC897 +- fs/ntfs3: Mark volume as dirty if xattr is broken +- i2c: pnx: Fix potential deadlock warning from del_timer_sync() call in isr +- clk: mediatek: mt8183: Only enable runtime PM on mt8183-mfgcfg +- clk: qcom: clk-alpha-pll: set ALPHA_EN bit for Stromer Plus PLLs +- clk: qcom: gcc-sm6350: Fix gpll6* & gpll7 parents +- media: dw2102: fix a potential buffer overflow +- arm64: dts: rockchip: Fix the DCDC_REG2 minimum voltage on Quartz64 Model B +- bnx2x: Fix multiple UBSAN array-index-out-of-bounds +- net: stmmac: dwmac-qcom-ethqos: fix error array size +- mtd: rawnand: rockchip: ensure NVDDR timings are rejected +- mtd: rawnand: Bypass a couple of sanity checks during NAND identification +- mtd: rawnand: Fix the nand_read_data_op() early check +- mtd: rawnand: Ensure ECC configuration is propagated to upper layers +- powerpc/64s: Fix unnecessary copy to 0 when kernel is booted at address 0 +- powerpc/pseries: Fix scv instruction crash with kexec +- clk: sunxi-ng: common: Don't call hw_to_ccu_common on hw without common +- clk: qcom: gcc-ipq9574: Add BRANCH_HALT_VOTED flag +- drm: panel-orientation-quirks: Add quirk for Valve Galileo +- drm/amdgpu/atomfirmware: silence UBSAN warning +- drm/nouveau: fix null pointer dereference in nouveau_connector_get_modes +- Revert "mm/writeback: fix possible divide-by-zero in wb_dirty_limits(), again" +- fsnotify: Do not generate events for O_PATH file descriptors +- can: kvaser_usb: Explicitly initialize family in leafimx driver_info struct +- Bluetooth: qca: Fix BT enable failure again for QCA6390 after warm reboot +- Bluetooth: hci_bcm4377: Fix msgid release +- scsi: mpi3mr: Use proper format specifier in mpi3mr_sas_port_add() +- f2fs: Add inline to f2fs_build_fault_attr() stub +- btrfs: fix adding block group to a reclaim list and the unused list during reclaim +- mm: avoid overflows in dirty throttling logic +- mm: optimize the redundant loop of mm_update_owner_next() +- nilfs2: add missing check for inode numbers on directory entries +- nilfs2: fix inode number range checks +- Revert "igc: fix a log entry using uninitialized netdev" +- platform/x86: toshiba_acpi: Fix quickstart quirk handling +- cpu: Fix broken cmdline "nosmp" and "maxcpus=0" +- gpiolib: of: add polarity quirk for TSC2005 +- mlxsw: core_linecards: Fix double memory deallocation in case of invalid INI file +- inet_diag: Initialize pad field in struct inet_diag_req_v2 +- selftests: make order checking verbose in msg_zerocopy selftest +- selftests: fix OOM in msg_zerocopy selftest +- netfilter: nf_tables: unconditionally flush pending work before notifier +- riscv: kexec: Avoid deadlock in kexec crash path +- wifi: wilc1000: fix ies_len type in connect path +- gpio: mmio: do not calculate bgpio_bits via "ngpios" +- net: ntb_netdev: Move ntb_netdev_rx_handler() to call netif_rx() from __netif_rx() +- net: txgbe: initialize num_q_vectors for MSI/INTx interrupts +- gpiolib: of: fix lookup quirk for MIPS Lantiq +- e1000e: Fix S0ix residency on corporate systems +- KVM: s390: fix LPSWEY handling +- tcp_metrics: validate source addr length +- bluetooth/hci: disallow setting handle bigger than HCI_CONN_HANDLE_MAX +- Bluetooth: ISO: Check socket flag instead of hcon +- Bluetooth: Ignore too large handle values in BIG +- Bluetooth: hci_event: Fix setting of unicast qos interval +- net/mlx5e: Add mqprio_rl cleanup and free in mlx5e_priv_cleanup() +- net/mlx5: E-switch, Create ingress ACL when needed +- UPSTREAM: tcp: fix DSACK undo in fast recovery to call tcp_try_to_open() +- net: phy: phy_device: Fix PHY LED blinking code comment +- mac802154: fix time calculation in ieee802154_configure_durations() +- vhost_task: Handle SIGKILL by flushing work and exiting +- vhost: Release worker mutex during flushes +- vhost: Use virtqueue mutex for swapping worker +- tools/power turbostat: Remember global max_die_id +- cdrom: rearrange last_media_change check to avoid unintentional overflow +- btrfs: scrub: initialize ret in scrub_simple_mirror() to fix compilation warning +- s390/pkey: Wipe sensitive data on failure +- jffs2: Fix potential illegal address access in jffs2_free_inode +- serial: imx: Raise TX trigger level to 8 +- scsi: mpi3mr: Sanitise num_phys +- f2fs: check validation of fault attrs in f2fs_build_fault_attr() +- bpf: Avoid uninitialized value in BPF_CORE_READ_BITFIELD +- igc: fix a log entry using uninitialized netdev +- selftests/net: fix uninitialized variables +- powerpc/xmon: Check cpu id in commands "c#", "dp#" and "dx#" +- kunit: Fix timeout message +- orangefs: fix out-of-bounds fsid access +- powerpc/64: Set _IO_BASE to POISON_POINTER_DELTA not 0 for CONFIG_PCI=n +- i2c: i801: Annotate apanel_addr as __ro_after_init +- media: dvb-frontends: tda10048: Fix integer overflow +- media: s2255: Use refcount_t instead of atomic_t for num_channels +- media: dvb-frontends: tda18271c2dd: Remove casting during div +- net: dsa: mv88e6xxx: Correct check for empty list +- thermal/drivers/mediatek/lvts_thermal: Check NULL ptr on lvts_data +- wifi: mt76: mt7996: add sanity checks for background radar trigger +- wifi: mt76: replace skb_put with skb_put_zero +- usb: xhci: prevent potential failure in handle_tx_event() for Transfer events without TRB +- Input: ff-core - prefer struct_size over open coded arithmetic +- firmware: dmi: Stop decoding on broken entry +- sctp: prefer struct_size over open coded arithmetic +- riscv: Apply SiFive CIP-1200 workaround to single-ASID sfence.vma +- media: dw2102: Don't translate i2c read into write +- drm/amdgpu: fix the warning about the expression (int)size - len +- drm/amdgpu: fix uninitialized scalar variable warning +- drm/amd/display: Fix uninitialized variables in DM +- drm/amd/display: Skip finding free audio for unknown engine_id +- drm/amd/display: Check pipe offset before setting vblank +- drm/amd/display: Check index msg_id before read or write +- drm/amdgpu: Initialize timestamp for some legacy SOCs +- drm/amdgpu: Using uninitialized value *size when calling amdgpu_vce_cs_reloc +- drm/amdgpu: Fix uninitialized variable warnings +- media: mediatek: vcodec: Only free buffer VA that is not NULL +- crypto: aead,cipher - zeroize key buffer after use +- RISC-V: KVM: Fix the initial sample period value +- selftests/bpf: dummy_st_ops should reject 0 for non-nullable params +- selftests/bpf: do not pass NULL for non-nullable params in dummy_st_ops +- selftests/bpf: adjust dummy_st_ops_success to detect additional error +- scsi: qedf: Make qedf_execute_tmf() non-preemptible +- IB/core: Implement a limit on UMAD receive List +- media: dvb-usb: dib0700_devices: Add missing release_firmware() +- media: dvb: as102-fe: Fix as10x_register_addr packing +- powerpc: Avoid nmi_enter/nmi_exit in real mode interrupt. +- drm/lima: fix shared irq handling on driver remove +- leds: an30259a: Use devm_mutex_init() for mutex initialization +- locking/mutex: Introduce devm_mutex_init() +- Revert "powerpc/bpf: rename powerpc64_jit_data to powerpc_jit_data" +- Revert "powerpc/bpf: use bpf_jit_binary_pack_[alloc|finalize|free]" +- tracing/net_sched: NULL pointer dereference in perf_trace_qdisc_reset() +- serial: 8250_omap: Fix Errata i2310 with RX FIFO level check +- serial: imx: only set receiver level if it is zero +- cxl/region: Avoid null pointer dereference in region lookup +- cxl/region: Move cxl_dpa_to_region() work to the region driver +- arm64: dts: rockchip: Add sound-dai-cells for RK3368 +- arm64: dts: rockchip: fix PMIC interrupt pin on ROCK Pi E +- arm64: dts: rockchip: make poweroff(8) work on Radxa ROCK 5A +- ARM: dts: rockchip: rk3066a: add #sound-dai-cells to hdmi node +- arm64: dts: rockchip: Fix the value of `dlg,jack-det-rate` mismatch on rk3399-gru +- arm64: dts: rockchip: Rename LED related pinctrl nodes on rk3308-rock-pi-s +- arm64: dts: rockchip: Fix SD NAND and eMMC init on rk3308-rock-pi-s +- pwm: stm32: Refuse too small period requests +- syscalls: fix sys_fanotify_mark prototype +- syscalls: fix compat_sys_io_pgetevents_time64 usage +- ftruncate: pass a signed offset +- ata: libata-core: Fix double free on error +- ata: ahci: Clean up sysfs file on error +- can: mcp251xfd: fix infinite loop when xmit fails +- batman-adv: Don't accept TT entries for out-of-spec VIDs +- drm/amdgpu/atomfirmware: fix parsing of vram_info +- drm/amd/display: Send DP_TOTAL_LTTPR_CNT during detection if LTTPR is present +- drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_hd_modes +- drm/i915/gt: Fix potential UAF by revoke of fence registers +- drm/amdgpu: avoid using null object of framebuffer +- drm/fbdev-dma: Only set smem_start is enable per module option +- drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_ld_modes +- drm/drm_file: Fix pid refcounting race +- hexagon: fix fadvise64_64 calling conventions +- csky, hexagon: fix broken sys_sync_file_range +- btrfs: zoned: fix initial free space detection +- sh: rework sync_file_range ABI +- kbuild: Install dtb files as 0644 in Makefile.dtbinst +- cpu/hotplug: Fix dynstate assignment in __cpuhp_setup_state_cpuslocked() +- cpufreq: intel_pstate: Use HWP to initialize ITMT if CPPC is missing +- PCI/MSI: Fix UAF in msi_capability_init +- net: can: j1939: enhanced error handling for tightly received RTS messages in xtp_rx_rts_session_new +- net: can: j1939: recover socket queue on CAN bus error during BAM transmission +- net: can: j1939: Initialize unused data in j1939_send_one() +- tty: mcf: MCF54418 has 10 UARTS +- ALSA: hda/realtek: fix mute/micmute LEDs don't work for EliteBook 645/665 G11. +- serial: bcm63xx-uart: fix tx after conversion to uart_port_tx_limited() +- serial: core: introduce uart_port_tx_limited_flags() +- serial: imx: set receiver level before starting uart +- serial: 8250_omap: Implementation of Errata i2310 +- Revert "serial: core: only stop transmit when HW fifo is empty" +- usb: dwc3: core: Workaround for CSR read timeout +- usb: dwc3: core: Add DWC31 version 2.00a controller +- usb: ucsi: stm32: fix command completion handling +- usb: typec: ucsi: glink: fix child node release in probe function +- usb: gadget: aspeed_udc: fix device address configuration +- usb: dwc3: core: remove lock of otg mode during gadget suspend/resume to avoid deadlock +- usb: atm: cxacru: fix endpoint checking in cxacru_bind() +- usb: musb: da8xx: fix a resource leak in probe() +- usb: gadget: printer: fix races against disable +- usb: gadget: printer: SS+ support +- net: usb: ax88179_178a: improve link status logs +- iio: chemical: bme680: Fix sensor data read operation +- iio: chemical: bme680: Fix overflows in compensate() functions +- iio: chemical: bme680: Fix calibration data variable +- iio: chemical: bme680: Fix pressure value output +- iio: accel: fxls8962af: select IIO_BUFFER & IIO_KFIFO_BUF +- iio: adc: ad7266: Fix variable checking bug +- ata,scsi: libata-core: Do not leak memory for ata_port struct members +- ata: libata-core: Fix null pointer dereference on error +- i2c: testunit: discard write requests while old command is running +- i2c: testunit: don't erase registers after STOP +- kbuild: Fix build target deb-pkg: ln: failed to create hard link +- kbuild: doc: Update default INSTALL_MOD_DIR from extra to updates +- counter: ti-eqep: enable clock at probe +- iio: xilinx-ams: Don't include ams_ctrl_channels in scan_mask +- mmc: sdhci: Do not lock spinlock around mmc_gpio_get_ro() +- mmc: sdhci: Do not invert write-protect twice +- mmc: sdhci-pci: Convert PCIBIOS_* return codes to errnos +- mmc: sdhci-brcmstb: check R1_STATUS for erase/trim/discard +- mmc: sdhci-pci-o2micro: Convert PCIBIOS_* return codes to errnos +- mm: fix incorrect vbq reference in purge_fragmented_block +- nfs: drop the incorrect assertion in nfs_swap_rw() +- ocfs2: fix DIO failure due to insufficient transaction credits +- pinctrl: qcom: spmi-gpio: drop broken pm8008 support +- Revert "MIPS: pci: lantiq: restore reset gpio polarity" +- parisc: use generic sys_fanotify_mark implementation +- x86: stop playing stack games in profile_pc() +- randomize_kstack: Remove non-functional per-arch entropy filtering +- gpiolib: cdev: Disallow reconfiguration without direction (uAPI v1) +- riscv: stacktrace: convert arch_stack_walk() to noinstr +- drm/amdgpu: Fix pci state save during mode-1 reset +- RISC-V: fix vector insn load/store width mask +- gpio: davinci: Validate the obtained number of IRQs +- drm/panel: simple: Add missing display timing flags for KOE TX26D202VM0BWA +- nvme: fixup comment for nvme RDMA Provider Type +- drm/radeon/radeon_display: Decrease the size of allocated memory +- gfs2: Fix NULL pointer dereference in gfs2_log_flush +- soc: ti: wkup_m3_ipc: Send NULL dummy message instead of pointer message +- irqchip/loongson: Select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP for IRQ_LOONGARCH_CPU +- media: dvbdev: Initialize sbuf +- ALSA: emux: improve patch ioctl data validation +- crypto: ecdh - explicitly zeroize private_key +- net/dpaa2: Avoid explicit cpumask var allocation on stack +- net/iucv: Avoid explicit cpumask var allocation on stack +- RDMA/restrack: Fix potential invalid address access +- bpf: Mark bpf prog stack with kmsan_unposion_memory in interpreter mode +- wifi: ieee80211: check for NULL in ieee80211_mle_size_ok() +- mtd: partitions: redboot: Added conversion of operands to a larger type +- x86/fpu: Fix AMD X86_BUG_FXSAVE_LEAK fixup +- vduse: Temporarily fail if control queue feature requested +- vduse: validate block features only with block devices +- drm/panel: ilitek-ili9881c: Fix warning with GPIO controllers that sleep +- powerpc/bpf: use bpf_jit_binary_pack_[alloc|finalize|free] +- powerpc/bpf: rename powerpc64_jit_data to powerpc_jit_data +- net: mana: Fix possible double free in error handling path +- netfilter: nf_tables: fully validate NFT_DATA_VALUE on store to data registers +- ALSA: seq: Fix missing MSB in MIDI2 SPP conversion +- tcp: fix tcp_rcv_fastopen_synack() to enter TCP_CA_Loss for failed TFO +- powerpc: restore some missing spu syscalls +- parisc: use correct compat recv/recvfrom syscalls +- sparc: fix compat recv/recvfrom syscalls +- sparc: fix old compat_sys_select() +- net: dsa: microchip: fix wrong register write when masking interrupt +- ALSA: seq: Fix missing channel at encoding RPN/NRPN MIDI2 messages +- Fix race for duplicate reqsk on identical SYN +- btrfs: use NOFS context when getting inodes during logging and log replay +- xdp: Remove WARN() from __xdp_reg_mem_model() +- ice: Rebuild TC queues on VSI queue reconfiguration +- net: dsa: microchip: use collision based back pressure mode +- net: phy: micrel: add Microchip KSZ 9477 to the device table +- ibmvnic: Free any outstanding tx skbs during scrq reset +- mlxsw: spectrum_buffers: Fix memory corruptions on Spectrum-4 systems +- openvswitch: get related ct labels from its master if it is not confirmed +- net: dsa: microchip: fix initial port flush problem +- ASoC: fsl-asoc-card: set priv->pdev before using it +- ASoC: amd: acp: remove i2s configuration check in acp_i2s_probe() +- ASoC: amd: acp: add a null check for chip_pdev structure +- s390/pci: Add missing virt_to_phys() for directed DIBV +- bpf: Add missed var_off setting in coerce_subreg_to_size_sx() +- bpf: Add missed var_off setting in set_sext32_default_val() +- ASoC: q6apm-lpass-dai: close graph on prepare errors +- workqueue: Increase worker desc's length to 32 +- ASoC: atmel: atmel-classd: Re-add dai_link->platform to fix card init +- ASoC: atmel: convert not to use asoc_xxx() +- ASoC: mediatek: mt8183-da7219-max98357: Fix kcontrol name collision +- ASoC: rockchip: i2s-tdm: Fix trcm mode by setting clock on right mclk +- wifi: mac80211: Use flexible array in struct ieee80211_tim_ie +- selftests: mptcp: userspace_pm: fixed subtest names +- selftests: mptcp: print_test out of verify_listener_events +- MIPS: pci: lantiq: restore reset gpio polarity +- pinctrl: rockchip: fix pinmux reset in rockchip_pmx_set +- pinctrl: rockchip: use dedicated pinctrl type for RK3328 +- pinctrl: rockchip: fix pinmux bits for RK3328 GPIO3-B pins +- pinctrl: rockchip: fix pinmux bits for RK3328 GPIO2-B pins +- pinctrl: fix deadlock in create_pinctrl() when handling -EPROBE_DEFER +- Input: ili210x - fix ili251x_read_touch_data() return value +- usb: typec: ucsi: Ack also failed Get Error commands +- usb: typec: ucsi: Never send a lone connector change ack +- iio: pressure: bmp280: Fix BMP580 temperature reading +- iio: pressure: fix some word spelling errors +- Revert "mm: mmap: allow for the maximum number of bits for randomizing mmap_base by default" +- hid: asus: asus_report_fixup: fix potential read out of bounds +- kprobe/ftrace: fix build error due to bad function definition +- ASoC: Intel: sof-sdw: really remove FOUR_SPEAKER quirk +- drm/amd/display: revert Exit idle optimizations before HDCP execution +- LoongArch: Fix entry point in kernel image header +- efi/loongarch: Directly position the loaded image file +- vgacon: rework screen_info #ifdef checks +- riscv: force PAGE_SIZE linear mapping if debug_pagealloc is enabled +- riscv: Don't use PGD entries for the linear mapping +- x86/cpu: Fix x86_match_cpu() to match just X86_VENDOR_INTEL +- x86/cpu/vfm: Add new macros to work with (vendor/family/model) values +- tracing: Add MODULE_DESCRIPTION() to preemptirq_delay_test +- nbd: Fix signal handling +- nbd: Improve the documentation of the locking assumptions +- ocfs2: update inode fsync transaction id in ocfs2_unlink and ocfs2_link +- ocfs2: convert to new timestamp accessors +- wifi: rtl8xxxu: enable MFP support with security flag of RX descriptor +- perf script: Show also errors for --insn-trace option +- perf: script: add raw|disasm arguments to --insn-trace option +- spi: stm32: qspi: Clamp stm32_qspi_get_mode() output to CCR_BUSWIDTH_4 +- arm64: dts: imx8qm-mek: fix gpio number for reg_usdhc2_vmmc +- spi: stm32: qspi: Fix dual flash mode sanity test in stm32_qspi_setup() +- dt-bindings: i2c: google,cros-ec-i2c-tunnel: correct path to i2c-controller schema +- dt-bindings: i2c: atmel,at91sam: correct path to i2c-controller schema +- i2c: ocores: set IACK bit after core is enabled +- mm/page_table_check: fix crash on ZONE_DEVICE +- tcp: clear tp->retrans_stamp in tcp_rcv_fastopen_synack() +- mm: mmap: allow for the maximum number of bits for randomizing mmap_base by default +- efi/x86: Free EFI memory map only when installing a new one. +- kcov: don't lose track of remote references during softirqs +- gcov: add support for GCC 14 +- dt-bindings: dma: fsl-edma: fix dma-channels constraints +- drm/radeon: fix UBSAN warning in kv_dpm.c +- drm/i915/mso: using joiner is not possible with eDP MSO +- ALSA: hda/realtek: Add quirk for Lenovo Yoga Pro 7 14AHP9 +- ALSA: hda/realtek: Limit mic boost on N14AP7 +- ALSA: hda/realtek: fix mute/micmute LEDs don't work for ProBook 445/465 G11. +- ovl: fix encoding fid for lower only root +- RDMA/mlx5: Follow rb_key.ats when creating new mkeys +- RDMA/mlx5: Remove extra unlock on error path +- RDMA/rxe: Fix data copy for IB_SEND_INLINE +- KVM: x86: Always sync PIR to IRR prior to scanning I/O APIC routes +- KVM: arm64: Disassociate vcpus from redistributor region on teardown +- LoongArch: Fix multiple hardware watchpoint issues +- LoongArch: Trigger user-space watchpoints correctly +- LoongArch: Fix watchpoint setting error +- cifs: fix typo in module parameter enable_gcm_256 +- scsi: ufs: core: Free memory allocated for model before reinit +- btrfs: retry block group reclaim without infinite loop +- net: do not leave a dangling sk pointer, when socket creation fails +- net: usb: ax88179_178a: improve reset check +- net: stmmac: Assign configured channel value to EXTTS event +- locking/atomic: scripts: fix ${atomic}_sub_and_test() kerneldoc +- arm64: defconfig: enable the vf610 gpio driver +- ACPI: EC: Evaluate orphan _REG under EC device +- RDMA/mana_ib: Ignore optional access flags for MRs +- RDMA/mlx5: Fix unwind flow as part of mlx5_ib_stage_init_init +- firmware: psci: Fix return value from psci_system_suspend() +- io_uring/rsrc: fix incorrect assignment of iter->nr_segs in io_import_fixed +- spi: spi-imx: imx51: revert burst length calculation back to bits_per_word +- arm64: dts: freescale: imx8mm-verdin: enable hysteresis on slow input pin +- arm64: dts: imx93-11x11-evk: Remove the 'no-sdio' property +- arm64: dts: freescale: imx8mp-venice-gw73xx-2x: fix BT shutdown GPIO +- arm64: dts: imx8mp: Fix TC9595 input clock on DH i.MX8M Plus DHCOM SoM +- arm64: dts: imx8mp: Fix TC9595 reset GPIO on DH i.MX8M Plus DHCOM SoM +- thermal/drivers/mediatek/lvts_thermal: Return error in case of invalid efuse data +- regulator: bd71815: fix ramp values +- dmaengine: ioatdma: Fix missing kmem_cache_destroy() +- dmaengine: fsl-edma: avoid linking both modules +- dmaengine: ioatdma: Fix kmemleak in ioat_pci_probe() +- dmaengine: ioatdma: Fix error path in ioat3_dma_probe() +- dmaengine: ioatdma: Fix leaking on version mismatch +- regulator: core: Fix modpost error "regulator_get_regmap" undefined +- RDMA/rxe: Fix responder length checking for UD request packets +- spi: cs42l43: Correct SPI root clock speed +- RDMA/bnxt_re: Fix the max msix vectors macro +- net: usb: rtl8150 fix unintiatilzed variables in rtl8150_get_link_ksettings +- bnxt_en: Restore PTP tx_avail count in case of skb_pad() error +- ice: Fix VSI list rule with ICE_SW_LKUP_LAST type +- octeontx2-pf: Fix linking objects into multiple modules +- octeontx2-pf: Add error handling to VLAN unoffload handling +- virtio_net: fixing XDP for fully checksummed packets handling +- virtio_net: checksum offloading handling fix +- net: stmmac: No need to calculate speed divider when offload is disabled +- selftests: openvswitch: Use bash as interpreter +- ptp: fix integer overflow in max_vclocks_store +- sched: act_ct: add netns into the key of tcf_ct_flow_table +- net: phy: mxl-gpy: Remove interrupt mask clearing from config_init +- net: lan743x: Support WOL at both the PHY and MAC appropriately +- net: lan743x: disable WOL upon resume to restore full data path operation +- qca_spi: Make interrupt remembering atomic +- netns: Make get_net_ns() handle zero refcount net +- xfrm6: check ip6_dst_idev() return value in xfrm6_get_saddr() +- ipv6: prevent possible NULL deref in fib6_nh_init() +- bpf: Avoid splat in pskb_pull_reason +- ALSA: hda: tas2781: Component should be unbound before deconstruction +- ALSA: hda: cs35l56: Component should be unbound before deconstruction +- cipso: fix total option length computation +- net: mvpp2: use slab_build_skb for oversized frames +- ice: avoid IRQ collision to fix init failure on ACPI S3 resume +- ALSA/hda: intel-dsp-config: Document AVS as dsp_driver option +- ALSA: hda/realtek: Remove Framework Laptop 16 from quirks +- MIPS: Routerboard 532: Fix vendor retry check code +- ALSA: seq: ump: Fix missing System Reset message handling +- PCI: Do not wait for disconnected devices when resuming +- ACPI: EC: Install address space handler at the namespace root +- usb: gadget: function: Remove usage of the deprecated ida_simple_xx() API +- serial: exar: adding missing CTI and Exar PCI ids +- f2fs: don't set RO when shutting down f2fs +- PCI/PM: Avoid D3cold for HP Pavilion 17 PC/1972 PCIe Ports +- udf: udftime: prevent overflow in udf_disk_stamp_to_time() +- usb: typec: ucsi_glink: drop special handling for CCI_BUSY +- usb: dwc3: pci: Don't set "linux,phy_charger_detect" property on Lenovo Yoga Tab2 1380 +- Avoid hw_desc array overrun in dw-axi-dmac +- usb: misc: uss720: check for incompatible versions of the Belkin F5U002 +- usb: gadget: uvc: configfs: ensure guid to be valid before set +- kprobe/ftrace: bail out if ftrace was killed +- power: supply: cros_usbpd: provide ID table for avoiding fallback match +- platform/x86: p2sb: Don't init until unassigned resources have been assigned +- powerpc/io: Avoid clang null pointer arithmetic warnings +- media: mtk-vcodec: potential null pointer deference in SCP +- media: intel/ipu6: Fix build with !ACPI +- ALSA: hda/realtek: Add quirks for Lenovo 13X +- drm/lima: mask irqs in timeout path before hard reset +- drm/lima: add mask irq callback to gp and pp +- ASoC: Intel: sof_sdw: add quirk for Dell SKU 0C0F +- ASoC: Intel: sof_sdw: add JD2 quirk for HP Omen 14 +- platform/x86: toshiba_acpi: Add quirk for buttons on Z830 +- drm/amd/display: Exit idle optimizations before HDCP execution +- Bluetooth: ath3k: Fix multiple issues reported by checkpatch.pl +- ACPI: video: Add backlight=native quirk for Lenovo Slim 7 16ARH7 +- HID: asus: fix more n-key report descriptors if n-key quirked +- HID: Add quirk for Logitech Casa touchpad +- net: dsa: realtek: keep default LED state in rtl8366rb +- kselftest: arm64: Add a null pointer check +- net: sfp: add quirk for ATS SFP-GE-T 1000Base-TX module +- scsi: qedi: Fix crash while reading debugfs attribute +- ACPI: x86: Add PNP_UART1_SKIP quirk for Lenovo Blade2 tablets +- af_packet: avoid a false positive warning in packet_setsockopt() +- wifi: ath9k: work around memset overflow warning +- selftests/bpf: Fix flaky test btf_map_in_map/lookup_update +- selftests/bpf: Prevent client connect before server bind in test_tc_tunnel.sh +- block/ioctl: prefer different overflow check +- rcutorture: Fix invalid context warning when enable srcu barrier testing +- rcutorture: Make stall-tasks directly exit when rcutorture tests end +- rcutorture: Fix rcu_torture_one_read() pipe_count overflow comment +- io_uring/sqpoll: work around a potential audit memory leak +- padata: Disable BH when taking works lock on MT path +- zap_pid_ns_processes: clear TIF_NOTIFY_SIGNAL along with TIF_SIGPENDING +- i2c: designware: Fix the functionality flags of the slave-only interface +- i2c: at91: Fix the functionality flags of the slave-only interface +- misc: microchip: pci1xxxx: Fix a memory leak in the error handling of gp_aux_bus_probe() +- serial: core: Add UPIO_UNKNOWN constant for unknown port type +- device property: Implement device_is_big_endian() +- greybus: Fix use-after-free bug in gb_interface_release due to race condition. +- remoteproc: k3-r5: Jump to error handling labels in start/stop errors +- serial: 8250_pxa: Configure tx_loadsz to match FIFO IRQ level +- mm/huge_memory: don't unpoison huge_zero_folio +- tick/nohz_full: Don't abuse smp_call_function_single() in tick_setup_device() +- nilfs2: fix potential kernel bug due to lack of writeback flag waiting +- xfs: allow cross-linking special files without project quota +- xfs: allow sunit mount option to repair bad primary sb stripe values +- xfs: shrink failure needs to hold AGI buffer +- xfs: fix SEEK_HOLE/DATA for regions with active COW extents +- xfs: fix scrub stats file permissions +- xfs: fix imprecise logic in xchk_btree_check_block_owner +- pmdomain: ti-sci: Fix duplicate PD referrals +- intel_th: pci: Add Lunar Lake support +- intel_th: pci: Add Meteor Lake-S support +- intel_th: pci: Add Sapphire Rapids SOC support +- intel_th: pci: Add Granite Rapids SOC support +- intel_th: pci: Add Granite Rapids support +- drm/i915: Fix audio component initialization +- drm/i915/dpt: Make DPT object unshrinkable +- drm/shmem-helper: Fix BUG_ON() on mmap(PROT_WRITE, MAP_PRIVATE) +- drm/i915/gt: Disarm breadcrumbs if engines are already idle +- rtla/auto-analysis: Replace with spaces +- rtla/timerlat: Simplify "no value" printing on top +- iio: invensense: fix interrupt timestamp alignment +- iio: adc: axi-adc: make sure AXI clock is enabled +- remoteproc: k3-r5: Do not allow core1 to power up before core0 via sysfs +- remoteproc: k3-r5: Wait for core0 power-up before powering up core1 +- dmaengine: axi-dmac: fix possible race in remove() +- PCI: rockchip-ep: Remove wrong mask on subsys_vendor_id +- ocfs2: use coarse time for new created files +- fs/proc: fix softlockup in __read_vmcore +- knfsd: LOOKUP can return an illegal error value +- spmi: hisi-spmi-controller: Do not override device identifier +- dma-buf: handle testing kthreads creation failure +- null_blk: Print correct max open zones limit in null_init_zoned_dev() +- kheaders: explicitly define file modes for archived headers +- tracing/selftests: Fix kprobe event name test for .isra. functions +- riscv: fix overlap of allocated page and PTR_ERR +- perf auxtrace: Fix multiple use of --itrace option +- perf/core: Fix missing wakeup when waiting for context reference +- x86/amd_nb: Check for invalid SMN reads +- x86/kexec: Fix bug with call depth tracking +- irqchip/gic-v3-its: Fix potential race condition in its_vlpi_prop_update() +- mptcp: pm: update add_addr counters after connect +- mptcp: pm: inc RmAddr MIB counter once per RM_ADDR ID +- ACPI: x86: Force StorageD3Enable on more products +- drivers: core: synchronize really_probe() and dev_uevent() +- iio: imu: inv_icm42600: delete unneeded update watermark call +- iio: invensense: fix odr switching to same value +- iio: dac: ad5592r: fix temperature channel scaling value +- iio: adc: ad9467: fix scan type sign +- x86/boot: Don't add the EFI stub to targets, again +- ksmbd: fix missing use of get_write in in smb2_set_ea() +- bnxt_en: Adjust logging of firmware messages in case of released token in __hwrm_send() +- af_unix: Read with MSG_PEEK loops if the first unread byte is OOB +- net/ipv6: Fix the RT cache flush via sysctl using a previous delay +- nvmet-passthru: propagate status from id override functions +- block: fix request.queuelist usage in flush +- block: sed-opal: avoid possible wrong address reference in read_sed_opal_key() +- net: stmmac: replace priv->speed with the portTransmitRate from the tc-cbs parameters +- gve: ignore nonrelevant GSO type bits when processing TSO headers +- net: pse-pd: Use EOPNOTSUPP error code instead of ENOTSUPP +- scsi: ufs: core: Quiesce request queues before checking pending cmds +- x86/uaccess: Fix missed zeroing of ia32 u64 get_user() range checking +- x86/asm: Use %c/%n instead of %P operand modifier in asm templates +- netfilter: nft_inner: validate mandatory meta and payload +- Bluetooth: L2CAP: Fix rejecting L2CAP_CONN_PARAM_UPDATE_REQ +- net/mlx5e: Fix features validation check for tunneled UDP (non-VXLAN) packets +- geneve: Fix incorrect inner network header offset when innerprotoinherit is set +- net dsa: qca8k: fix usages of device_get_named_child_node() +- tcp: fix race in tcp_v6_syn_recv_sock() +- drm/bridge/panel: Fix runtime warning on panel bridge release +- net: stmmac: dwmac-qcom-ethqos: Configure host DMA width +- net: sfp: Always call `sfp_sm_mod_remove()` on remove +- modpost: do not warn about missing MODULE_DESCRIPTION() for vmlinux.o +- af_unix: Annotate data-race of sk->sk_state in unix_accept(). +- drm/vmwgfx: Don't memcmp equivalent pointers +- drm/vmwgfx: Remove STDU logic from generic mode_valid function +- drm/vmwgfx: 3D disabled should not effect STDU memory limits +- drm/vmwgfx: Filter modes which exceed graphics memory +- drm/vmwgfx: Refactor drm connector probing for display modes +- io_uring/io-wq: avoid garbage value of 'match' in io_wq_enqueue() +- iommu: Return right value in iommu_sva_bind_device() +- iommu/amd: Fix sysfs leak in iommu init +- HID: core: remove unnecessary WARN_ON() in implement() +- gpio: tqmx86: fix broken IRQ_TYPE_EDGE_BOTH interrupt type +- gpio: tqmx86: store IRQ trigger type and unmask status separately +- gpio: tqmx86: introduce shadow register for GPIO output value +- gpio: tqmx86: fix typo in Kconfig label +- platform/x86: dell-smbios: Fix wrong token data in sysfs +- drm/panel: sitronix-st7789v: Add check for of_drm_get_panel_orientation +- nvme: fix nvme_pr_* status code parsing +- selftests/tracing: Fix event filter test to retry up to 10 times +- NFS: add barriers when testing for NFS_FSDATA_BLOCKED +- SUNRPC: return proper error from gss_wrap_req_priv +- NFSv4.1 enforce rootpath check in fs_location query +- clk: sifive: Do not register clkdevs for PRCI clocks +- selftests/ftrace: Fix to check required event file +- cxl/test: Add missing vmalloc.h for tools/testing/cxl/test/mem.c +- HID: nvidia-shield: Add missing check for input_ff_create_memless +- powerpc/uaccess: Fix build errors seen with GCC 13/14 +- gve: Clear napi->skb before dev_kfree_skb_any() +- scsi: sd: Use READ(16) when reading block zero on large capacity disks +- scsi: mpt3sas: Avoid test/set_bit() operating in non-allocated memory +- scsi: mpi3mr: Fix ATA NCQ priority support +- scsi: core: Disable CDL by default +- thunderbolt: debugfs: Fix margin debugfs node creation condition +- xhci: Apply broken streams quirk to Etron EJ188 xHCI host +- xhci: Handle TD clearing for multiple streams case +- xhci: Apply reset resume quirk to Etron EJ188 xHCI host +- xhci: Set correct transferred length for cancelled bulk transfers +- jfs: xattr: fix buffer overflow for invalid xattr +- landlock: Fix d_parent walk +- serial: port: Don't block system suspend even if bytes are left to xmit +- tty: n_tty: Fix buffer offsets when lookahead is used +- mei: me: release irq in mei_me_pci_resume error path +- usb: typec: tcpm: Ignore received Hard Reset in TOGGLING state +- usb: typec: tcpm: fix use-after-free case in tcpm_register_source_caps +- USB: xen-hcd: Traverse host/ when CONFIG_USB_XEN_HCD is selected +- USB: class: cdc-wdm: Fix CPU lockup caused by excessive log messages +- bpf: fix multi-uprobe PID filtering logic +- eventfs: Update all the eventfs_inodes from the events descriptor +- irqchip/riscv-intc: Prevent memory leak when riscv_intc_init_common() fails +- irqchip/riscv-intc: Introduce Andes hart-level interrupt controller +- irqchip/riscv-intc: Allow large non-standard interrupt number +- selftests/mm: compaction_test: fix bogus test success on Aarch64 +- selftests/mm: log a consistent test name for check_compaction +- selftests/mm: conform test to TAP format output +- memory-failure: use a folio in me_huge_page() +- firmware: qcom_scm: disable clocks if qcom_scm_bw_enable() fails +- ksmbd: use rwsem instead of rwlock for lease break +- net: ethtool: fix the error condition in ethtool_get_phy_stats_ethtool() +- af_unix: Annotate data-race of sk->sk_shutdown in sk_diag_fill(). +- af_unix: Use skb_queue_len_lockless() in sk_diag_show_rqlen(). +- af_unix: Use skb_queue_empty_lockless() in unix_release_sock(). +- af_unix: Use unix_recvq_full_lockless() in unix_stream_connect(). +- af_unix: Annotate data-race of net->unx.sysctl_max_dgram_qlen. +- af_unix: Annotate data-races around sk->sk_sndbuf. +- af_unix: Annotate data-races around sk->sk_state in UNIX_DIAG. +- af_unix: Annotate data-race of sk->sk_state in unix_stream_read_skb(). +- af_unix: Annotate data-races around sk->sk_state in sendmsg() and recvmsg(). +- af_unix: Annotate data-race of sk->sk_state in unix_stream_connect(). +- af_unix: Annotate data-races around sk->sk_state in unix_write_space() and poll(). +- af_unix: Annotate data-race of sk->sk_state in unix_inq_len(). +- af_unix: Annodate data-races around sk->sk_state for writers. +- af_unix: Set sk->sk_state under unix_state_lock() for truly disconencted peer. +- net: wwan: iosm: Fix tainted pointer delete is case of region creation fail +- ice: add flag to distinguish reset from .ndo_bpf in XDP rings config +- ice: remove af_xdp_zc_qps bitmap +- ice: fix iteration of TLVs in Preserved Fields Area +- ptp: Fix error message on failed pin verification +- net/mlx5: Fix tainted pointer delete is case of flow rules creation fail +- net/mlx5: Stop waiting for PCI if pci channel is offline +- mptcp: count CLOSE-WAIT sockets for MPTCP_MIB_CURRESTAB +- tcp: count CLOSE-WAIT sockets for TCP_MIB_CURRESTAB +- vxlan: Fix regression when dropping packets due to invalid src addresses +- net: phy: Micrel KSZ8061: fix errata solution not taking effect problem +- net/smc: avoid overwriting when adjusting sock bufsizes +- octeontx2-af: Always allocate PF entries from low prioriy zone +- net: tls: fix marking packets as decrypted +- ipv6: sr: block BH in seg6_output_core() and seg6_input_core() +- ipv6: ioam: block BH from ioam6_output() +- bpf: Store ref_ctr_offsets values in bpf_uprobe array +- net: phy: micrel: fix KSZ9477 PHY issues after suspend/resume +- net/ncsi: Fix the multi thread manner of NCSI driver +- net/ncsi: Simplify Kconfig/dts control flow +- ax25: Replace kfree() in ax25_dev_free() with ax25_dev_put() +- ax25: Fix refcount imbalance on inbound connections +- RISC-V: KVM: Fix incorrect reg_subtype labels in kvm_riscv_vcpu_set_reg_isa_ext function +- RISC-V: KVM: No need to use mask when hart-index-bit is 0 +- scsi: ufs: mcq: Fix error output and clean up ufshcd_mcq_abort() +- wifi: mac80211: correctly parse Spatial Reuse Parameter Set element +- wifi: iwlwifi: dbg_ini: move iwl_dbg_tlv_free outside of debugfs ifdef +- wifi: iwlwifi: mvm: set properly mac header +- wifi: iwlwifi: mvm: revert gen2 TX A-MPDU size to 64 +- wifi: iwlwifi: mvm: don't initialize csa_work twice +- wifi: cfg80211: pmsr: use correct nla_get_uX functions +- wifi: cfg80211: Lock wiphy in cfg80211_get_station +- wifi: cfg80211: fully move wiphy work to unbound workqueue +- !10369 Backport 6.6.33-34 LTS patches from upstream +- openeuler_defconfig: add new config +- selftests: net: more strict check in net_helper +- powerpc/bpf: enforce full ordering for ATOMIC operations with BPF_FETCH +- ALSA: seq: Fix incorrect UMP type for system messages +- btrfs: fix leak of qgroup extent records after transaction abort +- tracefs: Clear EVENT_INODE flag in tracefs_drop_inode() +- eventfs: Keep the directories from having the same inode number as files +- NFS: Fix READ_PLUS when server doesn't support OP_READ_PLUS +- nfs: fix undefined behavior in nfs_block_bits() +- EDAC/igen6: Convert PCIBIOS_* return codes to errnos +- ALSA: ump: Don't accept an invalid UMP protocol number +- ALSA: ump: Don't clear bank selection after sending a program change +- i3c: master: svc: fix invalidate IBI type and miss call client IBI handler +- s390/cpacf: Make use of invalid opcode produce a link error +- s390/cpacf: Split and rework cpacf query functions +- parisc: Define sigset_t in parisc uapi header +- parisc: Define HAVE_ARCH_HUGETLB_UNMAPPED_AREA +- ARM: dts: samsung: exynos4412-origen: fix keypad no-autorepeat +- ARM: dts: samsung: smdk4412: fix keypad no-autorepeat +- ARM: dts: samsung: smdkv310: fix keypad no-autorepeat +- riscv: dts: starfive: Remove PMIC interrupt info for Visionfive 2 board +- drm/amdkfd: handle duplicate BOs in reserve_bo_and_cond_vms +- sparc: move struct termio to asm/termios.h +- kdb: Use format-specifiers rather than memset() for padding in kdb_read() +- kdb: Merge identical case statements in kdb_read() +- kdb: Fix console handling when editing and tab-completing commands +- kdb: Use format-strings rather than '0' injection in kdb_read() +- wifi: ath10k: fix QCOM_RPROC_COMMON dependency +- watchdog: rti_wdt: Set min_hw_heartbeat_ms to accommodate a safety margin +- selftests/mm: fix build warnings on ppc64 +- selftests/mm: compaction_test: fix incorrect write of zero to nr_hugepages +- mm/vmalloc: fix vmalloc which may return null if called with __GFP_NOFAIL +- mm: /proc/pid/smaps_rollup: avoid skipping vma after getting mmap_lock again +- mm/hugetlb: pass correct order_per_bit to cma_declare_contiguous_nid +- mm/cma: drop incorrect alignment check in cma_init_reserved_mem +- sparc64: Fix number of online CPUs +- rtla/timerlat: Fix histogram report when a cpu count is 0 +- intel_th: pci: Add Meteor Lake-S CPU support +- tpm_tis: Do *not* flush uninitialized work +- kmsan: do not wipe out origin when doing partial unpoisoning +- mm/ksm: fix ksm_pages_scanned accounting +- net/ipv6: Fix route deleting failure when metric equals 0 +- scsi: core: Handle devices which return an unusually large VPD page count +- HID: i2c-hid: elan: fix reset suspend current leakage +- filemap: add helper mapping_max_folio_size() +- kbuild: Remove support for Clang's ThinLTO caching +- crypto: ecrdsa - Fix module auto-load on add_key +- crypto: ecdsa - Fix module auto-load on add-key +- clk: qcom: clk-alpha-pll: fix rate setting for Stromer PLLs +- LoongArch: Override higher address bits in JUMP_VIRT_ADDR +- LoongArch: Add all CPUs enabled by fdt to NUMA node 0 +- KVM: arm64: AArch32: Fix spurious trapping of conditional instructions +- KVM: arm64: Allow AArch32 PSTATE.M to be restored as System mode +- KVM: arm64: Fix AArch32 register narrowing on userspace write +- Revert "drm/amdkfd: fix gfx_target_version for certain 11.0.3 devices" +- drm/amd: Fix shutdown (again) on some SMU v13.0.4/11 platforms +- drm/amdgpu/atomfirmware: add intergrated info v2.3 table +- drm/fbdev-generic: Do not set physical framebuffer address +- mmc: sdhci-acpi: Add quirk to enable pull-up on the card-detect GPIO on Asus T100TA +- mmc: sdhci-acpi: Disable write protect detection on Toshiba WT10-A +- mmc: sdhci-acpi: Fix Lenovo Yoga Tablet 2 Pro 1380 sdcard slot not working +- mmc: sdhci-acpi: Sort DMI quirks alphabetically +- mmc: sdhci: Add support for "Tuning Error" interrupts +- mmc: core: Add mmc_gpiod_set_cd_config() function +- media: v4l: async: Don't set notifier's V4L2 device if registering fails +- media: v4l2-core: hold videodev_lock until dev reg, finishes +- media: mxl5xx: Move xpt structures off stack +- media: mc: mark the media devnode as registered from the, start +- arm64: dts: ti: verdin-am62: Set memory size to 2gb +- arm64: dts: hi3798cv200: fix the size of GICR +- arm64: dts: qcom: sc8280xp: add missing PCIe minimum OPP +- wifi: rtlwifi: rtl8192de: Fix endianness issue in RX path +- wifi: rtlwifi: rtl8192de: Fix low speed with WPA3-SAE +- wifi: rtlwifi: rtl8192de: Fix 5 GHz TX power +- wifi: rtl8xxxu: Fix the TX power of RTL8192CU, RTL8723AU +- wifi: rtw89: pci: correct TX resource checking for PCI DMA channel of firmware command +- md/raid5: fix deadlock that raid5d() wait for itself to clear MD_SB_CHANGE_PENDING +- arm64: dts: qcom: qcs404: fix bluetooth device address +- arm64: tegra: Correct Tegra132 I2C alias +- ACPI: resource: Do IRQ override on TongFang GXxHRXx and GMxHGxx +- soc: qcom: rpmh-rsc: Enhance check for VRM in-flight request +- proc: Move fdinfo PTRACE_MODE_READ check into the inode .permission operation +- fsverity: use register_sysctl_init() to avoid kmemleak warning +- ata: pata_legacy: make legacy_exit() work again +- wifi: rtw89: correct aSIFSTime for 6GHz band +- bcache: fix variable length array abuse in btree_iter +- f2fs: fix to do sanity check on i_xattr_nid in sanity_check_inode() +- drm/sun4i: hdmi: Move mode_set into enable +- drm/sun4i: hdmi: Convert encoder to atomic +- selftests: net: List helper scripts in TEST_FILES Makefile variable +- selftests: net: included needed helper in the install targets +- selftests/net: synchronize udpgro tests' tx and rx connection +- vxlan: Fix regression when dropping packets due to invalid src addresses +- erofs: avoid allocating DEFLATE streams before mounting +- mptcp: fix full TCP keep-alive support +- mptcp: cleanup SOL_TCP handling +- mptcp: avoid some duplicate code in socket option handling +- net: sfp-bus: fix SFP mode detect from bitrate +- afs: Don't cross .backup mountpoint from backup volume +- mmc: core: Do not force a retune before RPMB switch +- riscv: stacktrace: fixed walk_stackframe() +- riscv: prevent pt_regs corruption for secondary idle threads +- SUNRPC: Fix loop termination condition in gss_free_in_token_pages() +- f2fs: use f2fs_{err,info}_ratelimited() for cleanup +- f2fs: write missing last sum blk of file pinning section +- perf sched timehist: Fix -g/--call-graph option failure +- media: vsp1: Remove unbalanced .s_stream(0) calls +- nouveau: report byte usage in VRAM usage. +- RDMA/bnxt_re: Fix the sparse warnings +- perf evlist: Add perf_evlist__go_system_wide() helper +- platform/x86/intel-uncore-freq: Don't present root domain on error +- platform/x86/intel/tpmi: Handle error from tpmi_process_info() +- KVM: x86: Don't advertise guest.MAXPHYADDR as host.MAXPHYADDR in CPUID +- x86/pci: Skip early E820 check for ECAM region +- x86/efistub: Omit physical KASLR when memory reservations exist +- ALSA: seq: ump: Fix swapped song position pointer data +- hwmon: (shtc1) Fix property misspelling +- hwmon: (intel-m10-bmc-hwmon) Fix multiplier for N6000 board power sensor +- drm/panel: sitronix-st7789v: fix display size for jt240mhqs_hwt_ek_e3 panel +- drm/panel: sitronix-st7789v: tweak timing for jt240mhqs_hwt_ek_e3 panel +- drm/panel: sitronix-st7789v: fix timing for jt240mhqs_hwt_ek_e3 panel +- powerpc/pseries/lparcfg: drop error message from guest name lookup +- ALSA: seq: Fix yet another spot for system message conversion +- ipvlan: Dont Use skb->sk in ipvlan_process_v{4,6}_outbound +- net: ena: Fix redundant device NUMA node override +- net: ena: Reduce lines with longer column width boundary +- net: dsa: microchip: fix RGMII error in KSZ DSA driver +- spi: stm32: Don't warn about spurious interrupts +- kheaders: use `command -v` to test for existence of `cpio` +- drm/i915/gt: Fix CCS id's calculation for CCS mode setting +- drm/i915/guc: avoid FIELD_PREP warning +- kconfig: fix comparison to constant symbols, 'm', 'n' +- net/sched: taprio: extend minimum interval restriction to entire cycle too +- net/sched: taprio: make q->picos_per_byte available to fill_sched_entry() +- netfilter: nft_fib: allow from forward/input without iif selector +- netfilter: tproxy: bail out if IP has been disabled on the device +- netfilter: nft_payload: skbuff vlan metadata mangle support +- net: ti: icssg-prueth: Fix start counter for ft1 filter +- ALSA: seq: Don't clear bank selection at event -> UMP MIDI2 conversion +- ALSA: seq: Fix missing bank setup between MIDI1/MIDI2 UMP conversion +- selftests: mptcp: join: mark 'fail' tests as flaky +- selftests: mptcp: add ms units for tc-netem delay +- selftests: mptcp: simult flows: mark 'unbalanced' tests as flaky +- ice: fix accounting if a VLAN already exists +- net: micrel: Fix lan8841_config_intr after getting out of sleep mode +- net:fec: Add fec_enet_deinit() +- ASoC: cs42l43: Only restrict 44.1kHz for the ASP +- net: usb: smsc95xx: fix changing LED_SEL bit value updated from EEPROM +- Octeontx2-pf: Free send queue buffers incase of leaf to inner +- af_unix: Read sk->sk_hash under bindlock during bind(). +- af_unix: Annotate data-race around unix_sk(sk)->addr. +- enic: Validate length of nl attributes in enic_set_vf_port +- ALSA: hda/realtek: Adjust G814JZR to use SPI init for amp +- ALSA: core: Remove debugfs at disconnection +- ALSA: jack: Use guard() for locking +- bpf: Fix potential integer overflow in resolve_btfids +- net/mlx5e: Fix UDP GSO for encapsulated packets +- net/mlx5e: Use rx_missed_errors instead of rx_dropped for reporting buffer exhaustion +- net/mlx5e: Fix IPsec tunnel mode offload feature check +- net/mlx5: Use mlx5_ipsec_rx_status_destroy to correctly delete status rules +- net/mlx5: Fix MTMP register capability offset in MCAM register +- net/mlx5: Lag, do bond only if slaves agree on roce state +- net: phy: micrel: set soft_reset callback to genphy_soft_reset for KSZ8061 +- drm/amd/display: Enable colorspace property for MST connectors +- nvmet: fix ns enable/disable possible hang +- nvme-multipath: fix io accounting on failover +- nvme-tcp: add definitions for TLS cipher suites +- dma-mapping: benchmark: handle NUMA_NO_NODE correctly +- dma-mapping: benchmark: fix node id validation +- dma-mapping: benchmark: fix up kthread-related error handling +- kthread: add kthread_stop_put +- netfilter: nft_payload: restore vlan q-in-q match support +- netfilter: nfnetlink_queue: acquire rcu_read_lock() in instance_destroy_rcu() +- kasan, fortify: properly rename memintrinsics +- ice: Interpret .set_channels() input differently +- drivers/xen: Improve the late XenStore init protocol +- nfc: nci: Fix handling of zero-length payload packets in nci_rx_work() +- net: relax socket state check at accept time. +- net: fec: avoid lock evasion when reading pps_enable +- Revert "ixgbe: Manual AN-37 for troublesome link partners for X550 SFI" +- i3c: master: svc: change ENXIO to EAGAIN when IBI occurs during start frame +- i3c: master: svc: return actual transfer data len +- i3c: master: svc: rename read_len as actual_len +- i3c: add actual_len in i3c_priv_xfer +- net: lan966x: Remove ptp traps in case the ptp is not enabled. +- rv: Update rv_en(dis)able_monitor doc to match kernel-doc +- openvswitch: Set the skbuff pkt_type for proper pmtud support. +- pNFS/filelayout: fixup pNfs allocation modes +- regulator: tps6594-regulator: Correct multi-phase configuration +- af_unix: Update unix_sk(sk)->oob_skb under sk_receive_queue lock. +- regulator: tps6287x: Force writing VSEL bit +- regulator: pickable ranges: don't always cache vsel +- rpcrdma: fix handling for RDMA_CM_EVENT_DEVICE_REMOVAL +- sunrpc: fix NFSACL RPC retry on soft mount +- nfs: keep server info for remounts +- NFSv4: Fixup smatch warning for ambiguous return +- ASoC: tas2552: Add TX path for capturing AUDIO-OUT data +- nfc: nci: Fix uninit-value in nci_rx_work +- selftests: net: kill smcrouted in the cleanup logic in amt.sh +- ipv6: sr: fix missing sk_buff release in seg6_input_core +- net: Always descend into dsa/ folder with CONFIG_NET_DSA enabled +- x86/kconfig: Select ARCH_WANT_FRAME_POINTERS again when UNWINDER_FRAME_POINTER=y +- perf/arm-dmc620: Fix lockdep assert in ->event_init() +- xen/x86: add extra pages to unpopulated-alloc if available +- regulator: bd71828: Don't overwrite runtime voltages +- blk-cgroup: Properly propagate the iostat update up the hierarchy +- blk-cgroup: fix list corruption from resetting io stat +- drm/nouveau: use tile_mode and pte_kind for VM_BIND bo allocations +- nouveau: add an ioctl to report vram usage +- nouveau: add an ioctl to return vram bar size. +- ASoC: mediatek: mt8192: fix register configuration for tdm +- ALSA: hda: cs35l56: Fix lifetime of cs_dsp instance +- ALSA: hda: cs35l56: Initialize all ASP1 registers +- ASoC: cs35l56: Fix to ensure ASP1 registers match cache +- null_blk: Fix the WARNING: modpost: missing MODULE_DESCRIPTION() +- ASoC: tas2781: Fix a warning reported by robot kernel test +- selftests/powerpc/dexcr: Add -no-pie to hashchk tests +- Revert "drm/bridge: ti-sn65dsi83: Fix enable error path" +- media: cec: core: avoid confusing "transmit timed out" message +- media: cec: core: avoid recursive cec_claim_log_addrs +- media: cec: cec-api: add locking in cec_release() +- media: cec: cec-adap: always cancel work in cec_transmit_msg_fh +- media: sunxi: a83-mips-csi2: also select GENERIC_PHY +- cxl/region: Fix cxlr_pmem leaks +- cxl/trace: Correct DPA field masks for general_media & dram events +- um: Fix the declaration of kasan_map_memory +- um: Fix the -Wmissing-prototypes warning for get_thread_reg +- um: Fix the -Wmissing-prototypes warning for __switch_mm +- powerpc/pseries: Add failure related checks for h_get_mpp and h_get_ppp +- media: flexcop-usb: fix sanity check of bNumEndpoints +- platform/x86: thinkpad_acpi: Take hotkey_mutex during hotkey_exit() +- tools/arch/x86/intel_sdsi: Fix meter_certificate decoding +- tools/arch/x86/intel_sdsi: Fix meter_show display +- tools/arch/x86/intel_sdsi: Fix maximum meter bundle length +- media: mediatek: vcodec: fix possible unbalanced PM counter +- media: mediatek: vcodec: add encoder power management helper functions +- drm/amdgpu: Fix buffer size in gfx_v9_4_3_init_ cp_compute_microcode() and rlc_microcode() +- drm/amdgpu: init microcode chip name from ip versions +- Input: cyapa - add missing input core locking to suspend/resume functions +- drm/bridge: tc358775: fix support for jeida-18 and jeida-24 +- um: vector: fix bpfflash parameter evaluation +- um: Add winch to winch_handlers before registering winch IRQ +- um: Fix return value in ubd_init() +- drm/meson: gate px_clk when setting rate +- drm/mediatek: dp: Fix mtk_dp_aux_transfer return value +- drm/msm/dpu: Always flush the slave INTF on the CTL +- drm/msm/dsi: Print dual-DSI-adjusted pclk instead of original mode pclk +- media: ov2680: Do not fail if data-lanes property is absent +- media: ov2680: Allow probing if link-frequencies is absent +- media: ov2680: Clear the 'ret' variable on success +- media: v4l: Don't turn on privacy LED if streamon fails +- media: v4l2-subdev: Document and enforce .s_stream() requirements +- Input: pm8xxx-vibrator - correct VIB_MAX_LEVELS calculation +- mmc: sdhci_am654: Fix ITAPDLY for HS400 timing +- mmc: sdhci_am654: Add ITAPDLYSEL in sdhci_j721e_4bit_set_clock +- mmc: sdhci_am654: Add OTAP/ITAP delay enable +- mmc: sdhci_am654: Drop lookup for deprecated ti,otap-del-sel +- mmc: sdhci_am654: Write ITAPDLY for DDR52 timing +- mmc: sdhci_am654: Add tuning algorithm for delay chain +- Input: ims-pcu - fix printf string overflow +- dt-bindings: adc: axi-adc: add clocks property +- dt-bindings: adc: axi-adc: update bindings for backend framework +- eventfs: Have "events" directory get permissions from its parent +- eventfs: Free all of the eventfs_inode after RCU +- eventfs/tracing: Add callback for release of an eventfs_inode +- eventfs: Create eventfs_root_inode to store dentry +- serial: sc16is7xx: fix bug in sc16is7xx_set_baud() when using prescaler +- serial: sc16is7xx: replace hardcoded divisor value with BIT() macro +- misc/pvpanic-pci: register attributes via pci_driver +- misc/pvpanic: deduplicate common code +- iio: accel: mxc4005: Reset chip on probe() and resume() +- iio: accel: mxc4005: allow module autoloading via OF compatible +- eventfs: Do not differentiate the toplevel events directory +- drm/amd/display: Revert Remove pixle rate limit for subvp +- drm/amd/display: Remove pixle rate limit for subvp +- dt-bindings: PCI: rockchip,rk3399-pcie: Add missing maxItems to ep-gpios +- s390/boot: Remove alt_stfle_fac_list from decompressor +- s390/ipl: Fix incorrect initialization of nvme dump block +- s390/ipl: Fix incorrect initialization of len fields in nvme reipl block +- s390/vdso: Use standard stack frame layout +- s390/vdso: Generate unwind information for C modules +- s390/vdso64: filter out munaligned-symbols flag for vdso +- LoongArch: Fix callchain parse error with kernel tracepoint events again +- perf tools: Add/use PMU reverse lookup from config to name +- perf tools: Use pmus to describe type from attribute +- perf pmu: "Compat" supports regular expression matching identifiers +- perf pmu: Move pmu__find_core_pmu() to pmus.c +- perf test: Add a test for strcmp_cpuid_str() expression +- perf stat: Don't display metric header for non-leader uncore events +- usb: fotg210: Add missing kernel doc description +- f2fs: fix to add missing iput() in gc_data_segment() +- perf daemon: Fix file leak in daemon_session__control +- libsubcmd: Fix parse-options memory leak +- serial: sh-sci: protect invalidating RXDMA on shutdown +- f2fs: fix to release node block count in error path of f2fs_new_node_page() +- f2fs: compress: fix to cover {reserve,release}_compress_blocks() w/ cp_rwsem lock +- f2fs: compress: fix error path of inc_valid_block_count() +- f2fs: introduce get_available_block_count() for cleanup +- f2fs: deprecate io_bits +- f2fs: compress: fix to update i_compr_blocks correctly +- perf symbols: Fix ownership of string in dso__load_vmlinux() +- perf maps: Move symbol maps functions to maps.c +- perf thread: Fixes to thread__new() related to initializing comm +- perf report: Avoid SEGV in report__setup_sample_type() +- perf ui browser: Avoid SEGV on title +- f2fs: fix block migration when section is not aligned to pow2 +- f2fs: support file pinning for zoned devices +- f2fs: kill heap-based allocation +- f2fs: separate f2fs_gc_range() to use GC for a range +- f2fs: use BLKS_PER_SEG, BLKS_PER_SEC, and SEGS_PER_SEC +- f2fs: support printk_ratelimited() in f2fs_printk() +- f2fs: Clean up errors in segment.h +- PCI/EDR: Align EDR_PORT_LOCATE_DSM with PCI Firmware r3.3 +- PCI/EDR: Align EDR_PORT_DPC_ENABLE_DSM with PCI Firmware r3.3 +- dt-bindings: spmi: hisilicon,hisi-spmi-controller: fix binding references +- extcon: max8997: select IRQ_DOMAIN instead of depending on it +- perf ui browser: Don't save pointer to stack memory +- perf bench internals inject-build-id: Fix trap divide when collecting just one DSO +- i2c: synquacer: Fix an error handling path in synquacer_i2c_probe() +- i2c: cadence: Avoid fifo clear after start +- ppdev: Add an error check in register_device +- ppdev: Remove usage of the deprecated ida_simple_xx() API +- stm class: Fix a double free in stm_register_device() +- usb: gadget: u_audio: Clear uac pointer when freed. +- dt-bindings: phy: qcom,usb-snps-femto-v2: use correct fallback for sc8180x +- dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: fix msm899[68] power-domains +- watchdog: sa1100: Fix PTR_ERR_OR_ZERO() vs NULL check in sa1100dog_probe() +- watchdog: bd9576: Drop "always-running" property +- pinctrl: qcom: pinctrl-sm7150: Fix sdc1 and ufs special pins regs +- dt-bindings: pinctrl: mediatek: mt7622: fix array properties +- VMCI: Fix an error handling path in vmci_guest_probe_device() +- ovl: remove upper umask handling from ovl_create_upper() +- leds: pwm: Disable PWM when going to suspend +- pwm: Rename pwm_apply_state() to pwm_apply_might_sleep() +- perf intel-pt: Fix unassigned instruction op (discovered by MemorySanitizer) +- PCI: Wait for Link Training==0 before starting Link retrain +- microblaze: Remove early printk call from cpuinfo-static.c +- microblaze: Remove gcc flag for non existing early_printk.c file +- udf: Convert udf_expand_file_adinicb() to use a folio +- udf: Remove GFP_NOFS allocation in udf_expand_file_adinicb() +- i915: make inject_virtual_interrupt() void +- coresight: etm4x: Fix access to resource selector registers +- coresight: etm4x: Safe access for TRCQCLTR +- coresight: etm4x: Do not save/restore Data trace control registers +- coresight: etm4x: Do not hardcode IOMEM access for register restore +- iio: adc: adi-axi-adc: only error out in major version mismatch +- iio: adc: adi-axi-adc: move to backend framework +- iio: adc: ad9467: convert to backend framework +- iio: add the IIO backend framework +- iio: buffer-dmaengine: export buffer alloc and free functions +- iio: adc: adi-axi-adc: convert to regmap +- iio: adc: ad9467: use chip_info variables instead of array +- iio: adc: ad9467: use spi_get_device_match_data() +- iio: pressure: dps310: support negative temperature values +- perf test shell arm_coresight: Increase buffer size for Coresight basic tests +- perf docs: Document bpf event modifier +- coresight: etm4x: Fix unbalanced pm_runtime_enable() +- riscv: dts: starfive: visionfive 2: Remove non-existing TDM hardware +- iio: adc: stm32: Fixing err code to not indicate success +- f2fs: fix to check pinfile flag in f2fs_move_file_range() +- f2fs: fix to relocate check condition in f2fs_fallocate() +- f2fs: compress: fix to relocate check condition in f2fs_ioc_{,de}compress_file() +- f2fs: compress: fix to relocate check condition in f2fs_{release,reserve}_compress_blocks() +- perf bench uprobe: Remove lib64 from libc.so.6 binary path +- dt-bindings: PCI: rcar-pci-host: Add missing IOMMU properties +- dt-bindings: PCI: rcar-pci-host: Add optional regulators +- perf record: Fix debug message placement for test consumption +- perf record: Move setting tracking events before record__init_thread_masks() +- perf evlist: Add evlist__findnew_tracking_event() helper +- perf tests: Apply attributes to all events in object code reading test +- perf tests: Make "test data symbol" more robust on Neoverse N1 +- arm64: dts: meson: fix S4 power-controller node +- interconnect: qcom: qcm2290: Fix mas_snoc_bimc QoS port assignment +- module: don't ignore sysfs_create_link() failures +- serial: sc16is7xx: add proper sched.h include for sched_set_fifo() +- PCI: tegra194: Fix probe path for Endpoint mode +- greybus: arche-ctrl: move device table to its right location +- serial: max3100: Fix bitwise types +- serial: max3100: Update uart_driver_registered on driver removal +- perf annotate: Fix annotation_calc_lines() to pass correct address to get_srcline() +- perf annotate: Use global annotation_options +- perf top: Convert to the global annotation_options +- perf report: Convert to the global annotation_options +- perf annotate: Introduce global annotation_options +- perf annotate: Split branch stack cycles information out of 'struct annotation_line' +- perf machine thread: Remove exited threads by default +- perf record: Lazy load kernel symbols +- firmware: dmi-id: add a release callback function +- dmaengine: idma64: Add check for dma_set_max_seg_size +- soundwire: cadence: fix invalid PDI offset +- perf stat: Do not fail on metrics on s390 z/VM systems +- usb: typec: ucsi: simplify partner's PD caps registration +- usb: typec: ucsi: always register a link to USB PD device +- perf annotate: Get rid of duplicate --group option item +- counter: linux/counter.h: fix Excess kernel-doc description warning +- f2fs: fix to wait on page writeback in __clone_blkaddrs() +- phy: qcom: qmp-combo: fix duplicate return in qmp_v4_configure_dp_phy +- iio: core: Leave private pointer NULL when no private data supplied +- perf probe: Add missing libgen.h header needed for using basename() +- perf record: Delete session after stopping sideband thread +- sched/fair: Allow disabling sched_balance_newidle with sched_relax_domain_level +- af_packet: do not call packet_read_pending() from tpacket_destruct_skb() +- net: qrtr: ns: Fix module refcnt +- selftests: net: bridge: increase IGMP/MLD exclude timeout membership interval +- tracing/user_events: Fix non-spaced field matching +- tracing/user_events: Prepare find/delete for same name events +- tracing/user_events: Allow events to persist for perfmon_capable users +- RDMA/cma: Fix kmemleak in rdma_core observed during blktests nvme/rdma use siw +- RDMA/IPoIB: Fix format truncation compilation errors +- selftests/kcmp: remove unused open mode +- SUNRPC: Fix gss_free_in_token_pages() +- bnxt_re: avoid shift undefined behavior in bnxt_qplib_alloc_init_hwq +- RDMA/bnxt_re: Adds MSN table capability for Gen P7 adapters +- RDMA/bnxt_re: Update the HW interface definitions +- RDMA/bnxt_re: Remove roundup_pow_of_two depth for all hardware queue resources +- RDMA/bnxt_re: Refactor the queue index update +- ext4: remove the redundant folio_wait_stable() +- ext4: fix potential unnitialized variable +- sunrpc: removed redundant procp check +- ext4: avoid excessive credit estimate in ext4_tmpfile() +- x86/insn: Add VEX versions of VPDPBUSD, VPDPBUSDS, VPDPWSSD and VPDPWSSDS +- x86/insn: Fix PUSH instruction in x86 instruction decoder opcode map +- clk: qcom: mmcc-msm8998: fix venus clock issue +- clk: qcom: dispcc-sm8550: fix DisplayPort clocks +- clk: qcom: dispcc-sm6350: fix DisplayPort clocks +- clk: qcom: dispcc-sm8450: fix DisplayPort clocks +- lib/test_hmm.c: handle src_pfns and dst_pfns allocation failure +- clk: renesas: r9a07g043: Add clock and reset entry for PLIC +- clk: renesas: r8a779a0: Fix CANFD parent clock +- IB/mlx5: Use __iowrite64_copy() for write combining stores +- RDMA/rxe: Fix incorrect rxe_put in error path +- RDMA/rxe: Allow good work requests to be executed +- clk: qcom: clk-alpha-pll: remove invalid Stromer register offset +- clk: rs9: fix wrong default value for clock amplitude +- clk: mediatek: mt8365-mm: fix DPI0 parent +- clk: mediatek: pllfh: Don't log error for missing fhctl node +- RDMA/mlx5: Adding remote atomic access flag to updatable flags +- RDMA/mlx5: Uncacheable mkey has neither rb_key or cache_ent +- clk: samsung: exynosautov9: fix wrong pll clock id value +- media: cadence: csi2rx: configure DPHY before starting source stream +- drm/edid: Parse topology block for all DispID structure v1.x +- drm/rockchip: vop2: Do not divide height twice for YUV +- media: uvcvideo: Add quirk for Logitech Rally Bar +- drm/mipi-dsi: use correct return type for the DSC functions +- drm/panel: simple: Add missing Innolux G121X1-L03 format, flags, connector +- drm/bridge: anx7625: Update audio status while detecting +- drm/panel: novatek-nt35950: Don't log an error when DSI host can't be found +- drm/bridge: dpc3433: Don't log an error when DSI host can't be found +- drm/bridge: tc358775: Don't log an error when DSI host can't be found +- drm/bridge: lt9611uxc: Don't log an error when DSI host can't be found +- drm/bridge: lt9611: Don't log an error when DSI host can't be found +- drm/bridge: lt8912b: Don't log an error when DSI host can't be found +- drm/bridge: icn6211: Don't log an error when DSI host can't be found +- drm/bridge: anx7625: Don't log an error when DSI host can't be found +- ASoC: tracing: Export SND_SOC_DAPM_DIR_OUT to its value +- drm: vc4: Fix possible null pointer dereference +- media: atomisp: ssh_css: Fix a null-pointer dereference in load_video_binaries +- fbdev: sh7760fb: allow modular build +- media: v4l2-subdev: Fix stream handling for crop API +- media: i2c: et8ek8: Don't strip remove function when driver is builtin +- media: dt-bindings: ovti,ov2680: Fix the power supply names +- media: ipu3-cio2: Request IRQ earlier +- drm/msm/dp: Avoid a long timeout for AUX transfer if nothing connected +- drm/msm/dp: allow voltage swing / pre emphasis of 3 +- media: radio-shark2: Avoid led_names truncations +- media: rcar-vin: work around -Wenum-compare-conditional warning +- media: ngene: Add dvb_ca_en50221_init return value check +- ASoC: Intel: avs: Test result of avs_get_module_entry() +- ASoC: Intel: avs: Fix potential integer overflow +- ASoC: Intel: avs: Fix ASRC module initialization +- selftests: cgroup: skip test_cgcore_lesser_ns_open when cgroup2 mounted without nsdelegate +- fbdev: sisfb: hide unused variables +- ASoC: SOF: Intel: mtl: Implement firmware boot state check +- ASoC: SOF: Intel: mtl: Disable interrupts when firmware boot failed +- ASoC: SOF: Intel: mtl: call dsp dump when boot retry fails +- ASoC: SOF: Intel: lnl: Correct rom_status_reg +- ASoC: SOF: Intel: mtl: Correct rom_status_reg +- ASoC: SOF: Intel: pci-mtl: fix ARL-S definitions +- ASoC: SOF: Intel: pci-mtl: use ARL specific firmware definitions +- ASoC: Intel: common: add ACPI matching tables for Arrow Lake +- powerpc/fsl-soc: hide unused const variable +- drm/meson: vclk: fix calculation of 59.94 fractional rates +- ASoC: kirkwood: Fix potential NULL dereference +- fbdev: shmobile: fix snprintf truncation +- mtd: rawnand: hynix: fixed typo +- mtd: core: Report error if first mtd_otp_size() call fails in mtd_otp_nvmem_add() +- ASoC: Intel: avs: ssm4567: Do not ignore route checks +- ASoC: Intel: Disable route checks for Skylake boards +- drm/amd/display: Fix potential index out of bounds in color transformation function +- drm/panel: atna33xc20: Fix unbalanced regulator in the case HPD doesn't assert +- drm/dp: Don't attempt AUX transfers when eDP panels are not powered +- drm/lcdif: Do not disable clocks on already suspended hardware +- dev_printk: Add and use dev_no_printk() +- printk: Let no_printk() use _printk() +- drm/omapdrm: Fix console with deferred ops +- fbdev: Provide I/O-memory helpers as module +- drm/omapdrm: Fix console by implementing fb_dirty +- drm/ci: update device type for volteer devices +- drm/ci: add subset-1-gfx to LAVA_TAGS and adjust shards +- drm/ci: uprev mesa version: fix container build & crosvm +- drm/bridge: Fix improper bridge init order with pre_enable_prev_first +- Bluetooth: qca: Fix error code in qca_read_fw_build_info() +- Bluetooth: compute LE flow credits based on recvbuf space +- net: micrel: Fix receiving the timestamp in the frame for lan8841 +- mptcp: SO_KEEPALIVE: fix getsockopt support +- riscv, bpf: make some atomic operations fully ordered +- s390/bpf: Emit a barrier for BPF_FETCH instructions +- net/mlx5: Reload only IB representors upon lag disable/enable +- net/mlx5: Enable 4 ports multiport E-switch +- ipv6: sr: fix invalid unregister error path +- ipv6: sr: fix incorrect unregister order +- ipv6: sr: add missing seg6_local_exit +- net: usb: smsc95xx: stop lying about skb->truesize +- net: ethernet: cortina: Locking fixes +- selftests: net: move amt to socat for better compatibility +- selftests: net: add missing config for amt.sh +- selftests: net: add more missing kernel config +- net: ipv6: fix wrong start position when receive hop-by-hop fragment +- m68k: mac: Fix reboot hang on Mac IIci +- m68k: Fix spinlock race in kernel thread creation +- net: usb: sr9700: stop lying about skb->truesize +- usb: aqc111: stop lying about skb->truesize +- HID: amd_sfh: Handle "no sensors" in PM operations +- wifi: mwl8k: initialize cmd->addr[] properly +- scsi: qla2xxx: Fix debugfs output for fw_resource_count +- scsi: bfa: Ensure the copied buf is NUL terminated +- HID: intel-ish-hid: ipc: Add check for pci_alloc_irq_vectors +- selftests/bpf: Fix pointer arithmetic in test_xdp_do_redirect +- kunit: Fix kthread reference +- selftests: default to host arch for LLVM builds +- selftests/resctrl: fix clang build failure: use LOCAL_HDRS +- selftests/binderfs: use the Makefile's rules, not Make's implicit rules +- libbpf: Fix error message in attach_kprobe_multi +- wifi: mt76: mt7603: add wpdma tx eof flag for PSE client reset +- wifi: mt76: mt7603: fix tx queue of loopback packets +- Revert "sh: Handle calling csum_partial with misaligned data" +- sh: kprobes: Merge arch_copy_kprobe() into arch_prepare_kprobe() +- wifi: ar5523: enable proper endpoint verification +- net: give more chances to rcu in netdev_wait_allrefs_any() +- pwm: sti: Simplify probe function using devm functions +- pwm: sti: Prepare removing pwm_chip from driver data +- tcp: avoid premature drops in tcp_add_backlog() +- net: dsa: mv88e6xxx: Avoid EEPROM timeout without EEPROM on 88E6250-family switches +- net: dsa: mv88e6xxx: Add support for model-specific pre- and post-reset handlers +- wifi: ath10k: populate board data for WCN3990 +- cpufreq: brcmstb-avs-cpufreq: ISO C90 forbids mixed declarations +- scsi: ufs: core: mcq: Fix ufshcd_mcq_sqe_search() +- selftests/bpf: Fix a fd leak in error paths in open_netns +- gfs2: do_xmote fixes +- gfs2: finish_xmote cleanup +- gfs2: Rename gfs2_withdrawn to gfs2_withdrawing_or_withdrawn +- gfs2: Mark withdraws as unlikely +- gfs2: Rename gfs2_lookup_{ simple => meta } +- gfs2: Convert gfs2_internal_read to folios +- gfs2: Get rid of gfs2_alloc_blocks generation parameter +- wifi: ath10k: Fix an error code problem in ath10k_dbg_sta_write_peer_debug_trigger() +- dt-bindings: thermal: loongson,ls2k-thermal: Fix incorrect compatible definition +- dt-bindings: thermal: loongson,ls2k-thermal: Add Loongson-2K0500 compatible +- dt-bindings: thermal: loongson,ls2k-thermal: Fix binding check issues +- thermal/drivers/tsens: Fix null pointer dereference +- x86/purgatory: Switch to the position-independent small code model +- scsi: hpsa: Fix allocation size for Scsi_Host private data +- scsi: libsas: Fix the failure of adding phy with zero-address to port +- udp: Avoid call to compute_score on multiple sites +- x86/pat: Fix W^X violation false-positives when running as Xen PV guest +- x86/pat: Restructure _lookup_address_cpa() +- x86/pat: Introduce lookup_address_in_pgd_attr() +- cpufreq: exit() callback is optional +- tcp: increase the default TCP scaling ratio +- selftests/bpf: Fix umount cgroup2 error in test_sockmap +- x86/boot/64: Clear most of CR4 in startup_64(), except PAE, MCE and LA57 +- gfs2: Fix "ignore unlock failures after withdraw" +- gfs2: Don't forget to complete delayed withdraw +- ACPI: disable -Wstringop-truncation +- irqchip/loongson-pch-msi: Fix off-by-one on allocation error path +- irqchip/alpine-msi: Fix off-by-one in allocation error path +- locking/atomic/x86: Correct the definition of __arch_try_cmpxchg128() +- ACPI: LPSS: Advertise number of chip selects via property +- scsi: ufs: core: Perform read back after disabling UIC_COMMAND_COMPL +- scsi: ufs: core: Perform read back after disabling interrupts +- scsi: ufs: core: Perform read back after writing UTP_TASK_REQ_LIST_BASE_H +- scsi: ufs: cdns-pltfrm: Perform read back after writing HCLKDIV +- scsi: ufs: qcom: Perform read back after writing CGC enable +- scsi: ufs: qcom: Perform read back after writing unipro mode +- scsi: ufs: qcom: Perform read back after writing REG_UFS_SYS1CLK_1US +- scsi: ufs: qcom: Perform read back after writing reset bit +- bpf: prevent r10 register from being marked as precise +- bpf: Pack struct bpf_fib_lookup +- bpftool: Mount bpffs on provided dir instead of parent dir +- wifi: carl9170: re-fix fortified-memset warning +- dlm: fix user space lock decision to copy lvb +- bitops: add missing prototype check +- mlx5: stop warning for 64KB pages +- mlx5: avoid truncating error message +- qed: avoid truncating work queue length +- enetc: avoid truncating error message +- ACPI: Fix Generic Initiator Affinity _OSC bit +- sched/fair: Add EAS checks before updating root_domain::overutilized +- wifi: iwlwifi: mvm: fix check in iwl_mvm_sta_fw_id_mask +- wifi: iwlwifi: reconfigure TLC during HW restart +- wifi: iwlwifi: mvm: select STA mask only for active links +- wifi: iwlwifi: mvm: allocate STA links only for active links +- wifi: ieee80211: fix ieee80211_mle_basic_sta_prof_size_ok() +- x86/boot: Ignore relocations in .notes sections in walk_relocs() too +- wifi: mt76: mt7915: workaround too long expansion sparse warnings +- wifi: ath12k: use correct flag field for 320 MHz channels +- bpftool: Fix missing pids during link show +- wifi: ath11k: don't force enable power save on non-running vdevs +- wifi: brcmfmac: pcie: handle randbuf allocation failure +- wifi: ath10k: poll service ready message before failing +- block: fix and simplify blkdevparts= cmdline parsing +- lkdtm: Disable CFI checking for perms functions +- soc: qcom: pmic_glink: Make client-lock non-sleeping +- null_blk: Fix missing mutex_destroy() at module removal +- soc: mediatek: cmdq: Fix typo of CMDQ_JUMP_RELATIVE +- firmware: qcom: scm: Fix __scm and waitq completion variable initialization +- soc: qcom: pmic_glink: notify clients about the current state +- soc: qcom: pmic_glink: don't traverse clients list without a lock +- s390/mm: Re-enable the shared zeropage for !PV and !skeys KVM guests +- mm/userfaultfd: Do not place zeropages when zeropages are disallowed +- io-wq: write next_work before dropping acct_lock +- ARM: configs: sunxi: Enable DRM_DW_HDMI +- io_uring: use the right type for work_llist empty check +- s390/cio: fix tracepoint subchannel type field +- crypto: x86/sha512-avx2 - add missing vzeroupper +- crypto: x86/sha256-avx2 - add missing vzeroupper +- crypto: x86/nh-avx2 - add missing vzeroupper +- crypto: ccp - drop platform ifdef checks +- parisc: add missing export of __cmpxchg_u8() +- nilfs2: fix out-of-range warning +- firmware: raspberrypi: Use correct device for DMA mappings +- mm/slub, kunit: Use inverted data to corrupt kmem cache +- openpromfs: finish conversion to the new mount API +- nvmet: prevent sprintf() overflow in nvmet_subsys_nsid_exists() +- ksmbd: fix uninitialized symbol 'share' in smb2_tree_connect() +- epoll: be better about file lifetimes +- nvmet: fix nvme status code when namespace is disabled +- nvmet-tcp: fix possible memory leak when tearing down a controller +- nvme: cancel pending I/O if nvme controller is in terminal state +- nvmet-auth: replace pr_debug() with pr_err() to report an error. +- nvmet-auth: return the error code to the nvmet_auth_host_hash() callers +- nvme: find numa distance only if controller has valid numa id +- drm/amdkfd: Flush the process wq before creating a kfd_process +- drm/amd/display: Disable seamless boot on 128b/132b encoding +- drm/amd/display: Fix DC mode screen flickering on DCN321 +- drm/amd/display: Add VCO speed parameter for DCN31 FPU +- drm/amd/display: Allocate zero bw after bw alloc enable +- drm/amd/display: Add dtbclk access to dcn315 +- drm/amdgpu: Fix VRAM memory accounting +- ALSA: hda: intel-dsp-config: harden I2C/I2S codec detection +- ASoC: da7219-aad: fix usage of device_get_named_child_node() +- platform/x86: ISST: Add Grand Ridge to HPM CPU list +- softirq: Fix suspicious RCU usage in __do_softirq() +- ALSA: emu10k1: make E-MU FPGA writes potentially more reliable +- bpf, x86: Fix PROBE_MEM runtime load check +- fpga: dfl-pci: add PCI subdevice ID for Intel D5005 card +- Input: xpad - add support for ASUS ROG RAIKIRI +- KVM: selftests: Add test for uaccesses to non-existent vgic-v2 CPUIF +- ASoC: rt715-sdca: volume step modification +- ASoC: rt715: add vendor clear control register +- ASoC: cs35l41: Update DSP1RX5/6 Sources for DSP config +- regulator: vqmmc-ipq4019: fix module autoloading +- regulator: qcom-refgen: fix module autoloading +- ASoC: rt722-sdca: add headset microphone vrefo setting +- ASoC: rt722-sdca: modify channel number to support 4 channels +- ASoC: dt-bindings: rt5645: add cbj sleeve gpio property +- ASoC: rt5645: Fix the electric noise due to the CBJ contacts floating +- ASoC: acp: Support microphone from device Acer 315-24p +- ASoC: SOF: pcm: Restrict DSP D0i3 during S0ix to IPC3 +- ALSA: hda: cs35l56: Exit cache-only after cs35l56_wait_for_firmware_boot() +- regulator: irq_helpers: duplicate IRQ name +- ASoC: Intel: bytcr_rt5640: Apply Asus T100TA quirk to Asus T100TAM too +- sched/isolation: Fix boot crash when maxcpus < first housekeeping CPU +- selftests: sud_test: return correct emulated syscall value on RISC-V +- drm/etnaviv: fix tx clock gating on some GC7000 variants +- LoongArch: Lately init pmu after smp is online +- cpu: Ignore "mitigations" kernel parameter if CPU_MITIGATIONS=n +- drm/amdgpu: Fix the ring buffer size for queue VM flush +- drm/amdkfd: Add VRAM accounting for SVM migration +- drm/amd/pm: Restore config space after reset +- drm/amdgpu: Update BO eviction priorities +- drm/amd/display: Set color_mgmt_changed to true on unsuspend +- net: usb: qmi_wwan: add Telit FN920C04 compositions +- HID: mcp-2221: cancel delayed_work only when CONFIG_IIO is enabled +- dt-bindings: rockchip: grf: Add missing type to 'pcie-phy' node +- wifi: cfg80211: fix the order of arguments for trace events of the tx_rx_evt class +- wifi: mac80211: ensure beacon is non-S1G prior to extracting the beacon timestamp field +- wifi: mac80211: don't use rate mask for scanning +- KEYS: asymmetric: Add missing dependency on CRYPTO_SIG +- ALSA: hda/realtek: fix mute/micmute LEDs don't work for ProBook 440/460 G11. +- ksmbd: ignore trailing slashes in share paths +- ksmbd: avoid to send duplicate oplock break notifications +- fs/ntfs3: Break dir enumeration if directory contents error +- fs/ntfs3: Fix case when index is reused during tree transformation +- fs/ntfs3: Taking DOS names into account during link counting +- fs/ntfs3: Remove max link count info display during driver init +- net: smc91x: Fix m68k kernel compilation for ColdFire CPU +- net: lan966x: remove debugfs directory in probe() error path +- net: ti: icssg_prueth: Fix NULL pointer dereference in prueth_probe() +- tools/nolibc/stdlib: fix memory error in realloc() +- tools/latency-collector: Fix -Wformat-security compile warns +- net: mana: Fix the extra HZ in mana_hwc_send_request +- Revert "r8169: don't try to disable interrupts if NAPI is, scheduled already" +- io_uring: fail NOP if non-zero op flags is passed in +- Input: try trimming too long modalias strings +- serial: 8520_mtk: Set RTS on shutdown for Rx in-band wakeup +- serial: 8250_bcm7271: use default_mux_rate if possible +- tty: n_gsm: fix missing receive state reset after mode switch +- selftests/ftrace: Fix BTFARG testcase to check fprobe is enabled correctly +- x86/tsc: Trust initial offset in architectural TSC-adjust MSRs +- !10398 BMA: Fix DMA reset problem and change the version +- BMA/kbox_drv: Change the version number. +- BMA/veth_drv: Change the version number. +- BMA/cdev_drv: Change the version number. +- BMA/edma_drv: Fix DMA reset problem and change the version number. +- !10358 jbd2: stop waiting for space when jbd2_cleanup_journal_tail() returns error +- jbd2: stop waiting for space when jbd2_cleanup_journal_tail() returns error +- !10344 CVE-2024-39471 +- drm/amdgpu: Fix signedness bug in sdma_v4_0_process_trap_irq() +- drm/amdgpu: add error handle to avoid out-of-bounds +- !9904 ext4: improve buffered write with more than one blocks_per_folio +- ext4: improve sub-polio check in ext4_iomap_write_begin() +- iomap: add iomap_is_fully_dirty() +- iomap: correct the dirty length in page mkwrite +- iomap: advance the ifs allocation if we have more than one blocks per folio +- iomap: support invalidating partial folios +- iomap: correct the range of a partial dirty clear +- !9533 net/mlx5: Add a timeout to acquire the command queue semaphore +- net/mlx5: Add a timeout to acquire the command queue semaphore +- !10317 improve dump_page() robustness +- mm: improve dumping of mapcount and page_type +- mm: add __dump_folio() +- fs: improve dump_mapping() robustness +- !9361 macintosh/via-macii: Fix "BUG: sleeping function called from invalid context" +- macintosh/via-macii: Fix "BUG: sleeping function called from invalid context" +- !9892 support for SMC-D loopback_lo feature +- net/smc: enable the smc-lo on the x86 and arm64 platforms +- net/smc: implement DMB-merged operations of loopback-ism +- net/smc: adapt cursor update when sndbuf and peer DMB are merged +- net/smc: {at|de}tach sndbuf to peer DMB if supported +- net/smc: add operations to merge sndbuf with peer DMB +- net/smc: register loopback-ism into SMC-D device list +- net/smc: ignore loopback-ism when dumping SMC-D devices +- net/smc: mark optional smcd_ops and check for support when called +- net/smc: implement DMB-related operations of loopback-ism +- net/smc: implement ID-related operations of loopback-ism +- net/smc: introduce loopback-ism for SMC intra-OS shortcut +- net/smc: decouple ism_client from SMC-D DMB registration +- net/smc: change the term virtual ISM to Emulated-ISM +- net/smc: fix incorrect SMC-D link group matching logic +- net/smc: manage system EID in SMC stack instead of ISM driver +- net/smc: support extended GID in SMC-D lgr netlink attribute +- net/smc: compatible with 128-bits extended GID of virtual ISM device +- net/smc: define a reserved CHID range for virtual ISM devices +- net/smc: introduce virtual ISM device support feature +- net/smc: support SMCv2.x supplemental features negotiation +- net/smc: unify the structs of accept or confirm message for v1 and v2 +- net/smc: introduce sub-functions for smc_clc_send_confirm_accept() +- net/smc: rename some 'fce' to 'fce_v2x' for clarity +- !10171 netrom: Fix a memory leak in nr_heartbeat_expiry() +- netrom: Fix a memory leak in nr_heartbeat_expiry() +- !10312 bpf: Fix too early release of tcx_entry +- bpf: Fix too early release of tcx_entry +- !10170 x86: resctrl: Fix illegal access by the chips not having RDT +- x86: resctrl: Fix illegal access by the chips not having RDT +- !10311 wifi: mac80211: mesh: Fix leak of mesh_preq_queue objects +- wifi: mac80211: mesh: Fix leak of mesh_preq_queue objects +- !10254 fbdev: savage: Handle err return when savagefb_check_var failed +- fbdev: savage: Handle err return when savagefb_check_var failed +- !10078 bpf: Set run context for rawtp test_run callback +- bpf: Set run context for rawtp test_run callback +- !10261 batman-adv: bypass empty buckets in batadv_purge_orig_ref() +- batman-adv: bypass empty buckets in batadv_purge_orig_ref() +- !10066 serial: imx: Introduce timeout when waiting on transmitter empty +- serial: imx: Introduce timeout when waiting on transmitter empty +- !9971 KVM: Fix a data race on last_boosted_vcpu in kvm_vcpu_on_spin() +- KVM: Fix a data race on last_boosted_vcpu in kvm_vcpu_on_spin() + +' for pr_err +* Wed Jul 24 2024 ZhangPeng - 6.6.0-35.0.0.43 +- !9782 usb-storage: alauda: Check whether the media is initialized +- usb-storage: alauda: Check whether the media is initialized +- !10294 [OLK-6.6] drivers: Fix compile warning "argument used uninitialized" +- drivers: Fix compile warning "argument used uninitialized" +- !10257 media: dvb-usb: Fix unexpected infinite loop in dvb_usb_read_remote_control() +- media: dvb-usb: Fix unexpected infinite loop in dvb_usb_read_remote_control() +- !10287 CVE-2024-36979 +- net: bridge: mst: pass vlan group directly to br_mst_vlan_set_state +- net: bridge: mst: fix suspicious rcu usage in br_mst_set_state +- net: bridge: mst: fix vlan use-after-free +- !10018 ocfs2: fix NULL pointer dereference in ocfs2_journal_dirty() +- ocfs2: fix NULL pointer dereference in ocfs2_journal_dirty() +- !9985 btrfs: zoned: allocate dummy checksums for zoned NODATASUM writes +- btrfs: zoned: allocate dummy checksums for zoned NODATASUM writes +- !10260 [RoCE]从社区回合patch到openEuler(OLK-6.6) +- RDMA/hns: Fix mbx timing out before CMD execution is completed +- RDMA/hns: Fix insufficient extend DB for VFs. +- RDMA/hns: Fix undifined behavior caused by invalid max_sge +- RDMA/hns: Fix shift-out-bounds when max_inline_data is 0 +- RDMA/hns: Fix missing pagesize and alignment check in FRMR +- RDMA/hns: Fix unmatch exception handling when init eq table fails +- RDMA/hns: Check atomic wr length +- !10248 ssb: Fix potential NULL pointer dereference in ssb_device_uevent() +- ssb: Fix potential NULL pointer dereference in ssb_device_uevent() +- !9243 Bluetooth: RFCOMM: Fix not validating setsockopt user input +- Bluetooth: RFCOMM: Fix not validating setsockopt user input +- !10160 fix CVE-2024-40915 +- riscv: rewrite __kernel_map_pages() to fix sleeping in invalid context +- !10264 mm: filemap: optimize semantic when thp_exec_enabled is set to 3 +- mm: filemap: optimize semantic when thp_exec_enabled is set to 3 +- !5264 [OLK-6.6]HYGON: Support CSV Reuse ASID feature on Hygon CPUs +- KVM: SVM: Add support for different CSV guests to reuse the same ASID +- !10231 fix CVE-2024-41007 +- tcp: avoid too many retransmit packets +- tcp: use signed arithmetic in tcp_rtx_probe0_timed_out() +- !10233 fpga: bridge: add owner module and take its refcount +- fpga: bridge: add owner module and take its refcount +- !10237 ocfs2: fix NULL pointer dereference in ocfs2_abort_trigger() +- ocfs2: fix NULL pointer dereference in ocfs2_abort_trigger() +- !9915 powerpc/pseries: Enforce hcall result buffer validity and size +- powerpc/pseries: Enforce hcall result buffer validity and size +- !10148 fs/9p: fix uninitialized values during inode evict +- fs/9p: fix uninitialized values during inode evict +- !10056 io_uring/rsrc: don't lock while !TASK_RUNNING +- io_uring/rsrc: don't lock while !TASK_RUNNING +- !10226 cxl/region: Fix memregion leaks in devm_cxl_add_region() +- cxl/region: Fix memregion leaks in devm_cxl_add_region() +- !10177 ima: Fix use-after-free on a dentry's dname.name +- ima: Fix use-after-free on a dentry's dname.name +- !5262 [OLK-6.6]HYGON: Support Hygon DCU passthrough to VMs +- x86/config: Set CONFIG_HYDCU_FIXUP_HEADER=y by default +- drm/hygon: Add support to passthrough Hygon DCU to virtual machine +- !10220 bpf: Fix overrunning reservations in ringbuf +- bpf: Fix overrunning reservations in ringbuf +- !10219 CVE-2024-35931 +- drm/amdgpu: Skip do PCI error slot reset during RAS recovery +- drm/amdgpu : Add hive ras recovery check +- !10167 CVE-2024-36022 +- drm/amdgpu: Init zone device and drm client after mode-1 reset on reload +- drm/amdgpu: move the drm client creation behind drm device registration +- drm/amdkfd: init drm_client with funcs hook +- drm/amdkfd: Export DMABufs from KFD using GEM handles +- !9598 fpga: manager: add owner module and take its refcount +- fpga: manager: add owner module and take its refcount +- !10139 [sync] PR-10095: CVE-2024-40968 +- MIPS: Octeon: Add PCIe link status check +- !10044 btrfs: fix CVE-2024-39496 +- btrfs: zoned: fix use-after-free due to race with dev replace +- btrfs: zoned: factor out DUP bg handling from btrfs_load_block_group_zone_info +- btrfs: zoned: factor out single bg handling from btrfs_load_block_group_zone_info +- btrfs: zoned: factor out per-zone logic from btrfs_load_block_group_zone_info +- btrfs: zoned: introduce a zone_info struct in btrfs_load_block_group_zone_info +- !10114 v2 ecryptfs: Fix buffer size for tag 66 packet +- ecryptfs: Fix buffer size for tag 66 packet +- !10133 ALSA: timer: Set lower bound of start tick time +- ALSA: timer: Set lower bound of start tick time +- !10115 efi/unaccepted: touch soft lockup during memory accept +- efi/unaccepted: touch soft lockup during memory accept +- !10131 kunit/fortify: Fix mismatched kvalloc()/vfree() usage +- kunit/fortify: Fix mismatched kvalloc()/vfree() usage +- !10132 wifi: ath12k: fix out-of-bound access of qmi_invoke_handler() +- wifi: ath12k: fix out-of-bound access of qmi_invoke_handler() +- !10188 Part of "mm: mapcount for large folios + page_mapcount() cleanups" +- mm/rmap: add fast-path for small folios when adding/removing/duplicating +- mm/rmap: always inline anon/file rmap duplication of a single PTE +- mm: allow for detecting underflows with page_mapcount() again +- !10001 tty: n_gsm: fix possible out-of-bounds in gsm0_receive() +- tty: n_gsm: fix possible out-of-bounds in gsm0_receive() +- !10176 f2fs: compress: don't allow unaligned truncation on released compress inode +- f2fs: compress: don't allow unaligned truncation on released compress inode +- !10106 platform/x86: x86-android-tablets: Unregister devices in reverse order +- platform/x86: x86-android-tablets: Unregister devices in reverse order +- !10109 tracing: Build event generation tests only as modules +- tracing: Build event generation tests only as modules +- !10166 drop_monitor: replace spin_lock by raw_spin_lock +- drop_monitor: replace spin_lock by raw_spin_lock +- !10161 RDMA/mlx5: Add check for srq max_sge attribute +- RDMA/mlx5: Add check for srq max_sge attribute +- !10111 drm/exynos: hdmi: report safe 640x480 mode as a fallback when no EDID found +- drm/exynos: hdmi: report safe 640x480 mode as a fallback when no EDID found +- !10155 wifi: mac80211: Fix deadlock in ieee80211_sta_ps_deliver_wakeup() +- wifi: mac80211: Fix deadlock in ieee80211_sta_ps_deliver_wakeup() +- !10149 mips: bmips: BCM6358: make sure CBR is correctly set +- mips: bmips: BCM6358: make sure CBR is correctly set +- !10103 v2 fpga: region: add owner module and take its refcount +- fpga: region: add owner module and take its refcount +- !10097 [sync] PR-9741: scsi: qedf: Ensure the copied buf is NUL terminated +- scsi: qedf: Ensure the copied buf is NUL terminated +- !10021 drm/exynos/vidi: fix memory leak in .get_modes() +- drm/exynos/vidi: fix memory leak in .get_modes() +- !10127 wifi: iwlwifi: mvm: don't read past the mfuart notifcation +- wifi: iwlwifi: mvm: don't read past the mfuart notifcation +- !10117 wifi: iwlwifi: mvm: check n_ssids before accessing the ssids +- wifi: iwlwifi: mvm: check n_ssids before accessing the ssids +- !10116 wifi: mt76: mt7921s: fix potential hung tasks during chip recovery +- wifi: mt76: mt7921s: fix potential hung tasks during chip recovery +- !10017 liquidio: Adjust a NULL pointer handling path in lio_vf_rep_copy_packet +- liquidio: Adjust a NULL pointer handling path in lio_vf_rep_copy_packet +- !10051 tipc: force a dst refcount before doing decryption +- tipc: force a dst refcount before doing decryption +- !10102 vmxnet3: disable rx data ring on dma allocation failure +- vmxnet3: disable rx data ring on dma allocation failure +- !10093 drm/arm/malidp: fix a possible null pointer dereference +- drm/arm/malidp: fix a possible null pointer dereference +- !9989 io_uring/io-wq: Use set_bit() and test_bit() at worker->flags +- io_uring/io-wq: Use set_bit() and test_bit() at worker->flags +- !10083 CVE-2024-40955 +- ext4: clean up s_mb_rb_lock to fix build warnings with C=1 +- ext4: set the type of max_zeroout to unsigned int to avoid overflow +- ext4: set type of ac_groups_linear_remaining to __u32 to avoid overflow +- ext4: add positive int attr pointer to avoid sysfs variables overflow +- ext4: add new attr pointer attr_mb_order +- ext4: fix slab-out-of-bounds in ext4_mb_find_good_group_avg_frag_lists() +- ext4: refactor out ext4_generic_attr_show() +- ext4: refactor out ext4_generic_attr_store() +- ext4: avoid overflow when setting values via sysfs +- !10069 ALSA: Fix deadlocks with kctl removals at disconnection +- ALSA: Fix deadlocks with kctl removals at disconnection +- !10074 PCI: of_property: Return error for int_map allocation failure +- PCI: of_property: Return error for int_map allocation failure +- !10087 fix CVE-2024-40995 +- net/sched: act_api: fix possible infinite loop in tcf_idr_check_alloc() +- net/sched: act_api: rely on rcu in tcf_idr_check_alloc +- !10064 net/mlx5: Always stop health timer during driver removal +- net/mlx5: Always stop health timer during driver removal +- !9240 v2 cachefiles: introduce failover mechanism +- cachefiles: make on-demand read killable +- cachefiles: flush all requests after setting CACHEFILES_DEAD +- cachefiles: Set object to close if ondemand_id < 0 in copen +- cachefiles: defer exposing anon_fd until after copy_to_user() succeeds +- cachefiles: never get a new anonymous fd if ondemand_id is valid +- cachefiles: add spin_lock for cachefiles_ondemand_info +- cachefiles: add consistency check for copen/cread +- cachefiles: remove err_put_fd label in cachefiles_ondemand_daemon_read() +- cachefiles: fix slab-use-after-free in cachefiles_ondemand_daemon_read() +- cachefiles: fix slab-use-after-free in cachefiles_ondemand_get_fd() +- cachefiles: remove requests from xarray during flushing requests +- cachefiles: add output string to cachefiles_obj_[get|put]_ondemand_fd +- cachefiles, erofs: Fix NULL deref in when cachefiles is not doing ondemand-mode +- cachefiles: add restore command to recover inflight ondemand read requests +- cachefiles: narrow the scope of triggering EPOLLIN events in ondemand mode +- cachefiles: resend an open request if the read request's object is closed +- cachefiles: extract ondemand info field from cachefiles_object +- cachefiles: introduce object ondemand state +- !9933 nvdimm: Backport some bugfixs +- dax: alloc_dax() return ERR_PTR(-EOPNOTSUPP) for CONFIG_DAX=n +- nvdimm/pmem: fix leak on dax_add_host() failure +- !10038 media: v4l: async: Properly re-initialise notifier entry in unregister +- media: v4l: async: Properly re-initialise notifier entry in unregister +- !9970 CVE-2024-39503 +- netfilter: ipset: Fix suspicious rcu_dereference_protected() +- netfilter: ipset: Fix race between namespace cleanup and gc in the list:set type +- netfilter: ipset: Add list flush to cancel_gc +- !10011 xfs: fix mount hung while sb recover fail +- xfs: fix mount hung while sb recover fail +- !10050 vmci: prevent speculation leaks by sanitizing event in event_deliver() +- vmci: prevent speculation leaks by sanitizing event in event_deliver() +- !10006 drm/amdgpu: fix UBSAN warning in kv_dpm.c +- drm/amdgpu: fix UBSAN warning in kv_dpm.c +- !9959 parisc: Try to fix random segmentation faults in package builds +- parisc: Try to fix random segmentation faults in package builds +- !10028 ipv6: prevent possible NULL dereference in rt6_probe() +- ipv6: prevent possible NULL dereference in rt6_probe() +- !10005 seg6: fix parameter passing when calling NF_HOOK() in End.DX4 and End.DX6 behaviors +- seg6: fix parameter passing when calling NF_HOOK() in End.DX4 and End.DX6 behaviors + +* Wed Jul 17 2024 ZhangPeng - 6.6.0-34.0.0.42 +- Remove mlx5 related API from kabi whitelist + +* Wed Jul 17 2024 ZhangPeng - 6.6.0-34.0.0.41 +- !10059 nilfs2: fix use-after-free of timer for log writer thread +- nilfs2: fix use-after-free of timer for log writer thread +- !10025 9p: add missing locking around taking dentry fid list +- 9p: add missing locking around taking dentry fid list +- !9835 fix CVE-2024-39479 +- drm/i915/hwmon: Get rid of devm +- !9998 ALSA: hda/cs_dsp_ctl: Use private_free for control cleanup +- ALSA: hda/cs_dsp_ctl: Use private_free for control cleanup +- !9997 openrisc: traps: Don't send signals to kernel mode threads +- openrisc: traps: Don't send signals to kernel mode threads +- !9956 drm/komeda: check for error-valued pointer +- drm/komeda: check for error-valued pointer +- !9914 arm64: asm-bug: Add .align 2 to the end of __BUG_ENTRY +- arm64: asm-bug: Add .align 2 to the end of __BUG_ENTRY +- !9944 f2fs: remove clear SB_INLINECRYPT flag in default_options +- f2fs: remove clear SB_INLINECRYPT flag in default_options +- !9909 sock_map: avoid race between sock_map_close and sk_psock_put +- sock_map: avoid race between sock_map_close and sk_psock_put +- !10045 misc: microchip: pci1xxxx: fix double free in the error handling of gp_aux_bus_probe() +- misc: microchip: pci1xxxx: fix double free in the error handling of gp_aux_bus_probe() +- !10055 media: v4l: async: Fix notifier list entry init +- media: v4l: async: Fix notifier list entry init +- !9900 ipv6: fix possible race in __fib6_drop_pcpu_from() +- ipv6: fix possible race in __fib6_drop_pcpu_from() +- !9979 CVE-2024-40972 +- ext4: do not create EA inode under buffer lock +- ext4: fold quota accounting into ext4_xattr_inode_lookup_create() +- !9988 netpoll: Fix race condition in netpoll_owner_active +- netpoll: Fix race condition in netpoll_owner_active +- !9945 ACPICA: Revert "ACPICA: avoid Info: mapping multiple BARs. Your kernel is fine." +- ACPICA: Revert "ACPICA: avoid Info: mapping multiple BARs. Your kernel is fine." +- !9935 ALSA: hda: cs35l41: Possible null pointer dereference in cs35l41_hda_unbind() +- ALSA: hda: cs35l41: Possible null pointer dereference in cs35l41_hda_unbind() +- !9962 iommu/arm-smmu-v3: Change the style to identify the the hisi_platform +- iommu/arm-smmu-v3: Change the style to identify the the hisi_platform +- !9896 bonding: Fix out-of-bounds read in bond_option_arp_ip_targets_set() +- bonding: Fix out-of-bounds read in bond_option_arp_ip_targets_set() +- !9928 ocfs2: fix races between hole punching and AIO+DIO +- ocfs2: fix races between hole punching and AIO+DIO +- !9938 fix CVE-2024-40934 +- HID: logitech-dj: Fix memory leak in logi_dj_recv_switch_to_dj_mode() +- !9899 ionic: fix use after netif_napi_del() +- ionic: fix use after netif_napi_del() +- !9898 cpufreq: amd-pstate: fix memory leak on CPU EPP exit +- cpufreq: amd-pstate: fix memory leak on CPU EPP exit +- !9903 mptcp: ensure snd_una is properly initialized on connect +- mptcp: ensure snd_una is properly initialized on connect +- !9878 CVE-2024-39478 +- crypto: starfive - Do not free stack buffer +- !9888 ipv6: sr: fix memleak in seg6_hmac_init_algo +- ipv6: sr: fix memleak in seg6_hmac_init_algo +- !5261 [OLK-6.6]Hygon: Some enhancement and bugfixes for HYGON CSV/CSV2 +- KVM: SVM: Unmap ghcb pages if they're still mapped when destroy guest +- KVM: x86: Fix KVM_GET_MSRS stack info leak +- KVM: SEV: Do not intercept accesses to MSR_IA32_XSS for SEV-ES guests +- x86/head/64: Flush caches for .bss..decrypted section after CR3 switches to early_top_pgt +- KVM: x86: Calls is_64_bit_hypercall() instead of is_64_bit_mode() in complete_hypercall_exit() +- x86/csv2: Keep in atomic context when holding ghcb page if the #VC comes from userspace +- KVM: SVM: Fix the available ASID range for CSV2 guest +- !9861 MPTCP Upstream part 13 +- selftests: mptcp: lib: catch duplicated subtest entries +- selftests: mptcp: explicitly trigger the listener diag code-path +- bpf, btf: Add check_btf_kconfigs helper +- bpf, btf: Fix return value of register_btf_id_dtor_kfuncs +- !9876 v3 Fix xfs file creation issue +- xfs: Avoid races with cnt_btree lastrec updates +- Revert "xfs: Fix file creation failure" +- !9877 gfs2: Fix potential glock use-after-free on unmount +- gfs2: Fix potential glock use-after-free on unmount +- !9862 ipvlan: Modify the value of ipvlan modes +- ipvlan: Modify the value of ipvlan modes +- !5260 [OLK-6.6] Support live migration for CSV/CSV2 guest, and support rebooting CSV/CSV2 guest +- KVM: SVM: Force flush caches before reboot CSV guest +- KVM: SVM: Add support for rebooting CSV2 guest +- KVM: x86: Introduce control_{pre,post}_system_reset ioctl interfaces +- KVM: SVM: Export MSR_AMD64_SEV_ES_GHCB to userspace for CSV2 guest +- KVM: x86: Restore control registers in __set_sregs() to support CSV2 guest live migration +- KVM: SVM: Add KVM_SEV_RECEIVE_UPDATE_VMSA command +- KVM: SVM: Add KVM_SEV_SEND_UPDATE_VMSA command +- crypto: ccp: Fix definition of struct sev_data_send_update_vmsa +- KVM: SVM: Add RECEIVE_UPDATE_DATA command helper to support KVM_CSV_COMMAND_BATCH +- KVM: SVM: Add SEND_UPDATE_DATA command helper to support KVM_CSV_COMMAND_BATCH +- KVM: SVM: Prepare memory pool to allocate buffers for KVM_CSV_COMMAND_BATCH +- KVM: SVM: Add KVM_CSV_COMMAND_BATCH command for applying CSV RING_BUFFER mode +- crypto: ccp: Add support for issue commands in CSV RING_BUFFER mode +- crypto: ccp: Add support to switch to CSV RING_BUFFER mode +- crypto: ccp: Add support for dequeue status in CSV RING_BUFFER mode +- crypto: ccp: Add support for enqueue command pointers in CSV RING_BUFFER mode +- crypto: ccp: Introduce init and free helpers to manage CSV RING_BUFFER queues +- !9294 Compiler: Add clang's PGO support for kernel. +- Compiler: Add clang's PGO support for kernel. +- !9610 rcu: Fix buffer overflow in print_cpu_stall_info() +- rcu: Fix buffer overflow in print_cpu_stall_info() +- !9845 xfs: fix log recovery buffer allocation for the legacy h_size fixup +- xfs: fix log recovery buffer allocation for the legacy h_size fixup +- !9859 block: enable BLK_IO_HUNG_TASK_CHECK by default +- block: enable BLK_IO_HUNG_TASK_CHECK by default +- !9857 drm/amdgpu/mes: fix use-after-free issue +- drm/amdgpu/mes: fix use-after-free issue +- !9829 fix CVE-2024-38620 +- Bluetooth: fix connection setup in l2cap_connect +- Bluetooth: HCI: Remove HCI_AMP support +- Bluetooth: hci_event: Remove code to removed CONFIG_BT_HS +- Bluetooth: Remove usage of the deprecated ida_simple_xx() API +- Bluetooth: ISO: Fix BIS cleanup +- !9838 cgroup: Fix AA deadlock caused by cgroup_bpf_release +- cgroup: Fix AA deadlock caused by cgroup_bpf_release +- !9841 ASoC: SOF: ipc4-topology: Fix input format query of process modules without base extension +- ASoC: SOF: ipc4-topology: Fix input format query of process modules without base extension +- !9834 mmc: davinci: Don't strip remove function when driver is builtin +- mmc: davinci: Don't strip remove function when driver is builtin + +* Wed Jul 10 2024 ZhangPeng - 6.6.0-33.0.0.40 +- !9779 CVE-2024-39461 +- clk: bcm: rpi: Assign ->num before accessing ->hws +- !9801 loongarch平台config配置对kdump的支持 +- loongarch: configs: Configure degbuginfo +- Fix the kdump second kernel boot failure +- loongarch: Cleanup loongson3_defconfig with make savedefconfig +- !9811 fix CVE-2024-39481 +- media: mc: Fix graph walk in media_pipeline_start +- !9810 KVM: SVM: WARN on vNMI + NMI window iff NMIs are outright masked +- KVM: SVM: WARN on vNMI + NMI window iff NMIs are outright masked +- !9821 kdb: Fix buffer overflow during tab-complete +- kdb: Fix buffer overflow during tab-complete +- !9788 net: fix wrong return value in bpf_sock_ops_get_uid_gid +- net: fix wrong return value in bpf_sock_ops_get_uid_gid +- !9816 mm: mem_reliable: Make counting reliable task usage compatible with folio +- mm: mem_reliable: Make counting reliable task usage compatible with folio +- !9807 drm: zynqmp_dpsub: Always register bridge +- drm: zynqmp_dpsub: Always register bridge +- !9804 CVE-2024-36478 +- null_blk: Fix return value of nullb_device_power_store() +- null_blk: fix null-ptr-dereference while configuring 'power' and 'submit_queues' +- !9805 md: fix resync softlockup when bitmap size is less than array size +- md: fix resync softlockup when bitmap size is less than array size +- !9802 ax25: Fix reference count leak issue of net_device +- ax25: Fix reference count leak issue of net_device +- !9770 Add a switch to enable hungtask check for io +- block: disable BLK_IO_HUNG_TASK_CHECK by default +- block: add a switch to enable hungtask check for io +- !9793 drm: bridge: cdns-mhdp8546: Fix possible null pointer dereference +- drm: bridge: cdns-mhdp8546: Fix possible null pointer dereference +- !9649 f2fs: fix to do sanity check on i_xattr_nid in sanity_check_inode() +- f2fs: fix to do sanity check on i_xattr_nid in sanity_check_inode() +- !9732 CVE-2024-39469 +- nilfs2: fix nilfs_empty_dir() misjudgment and long loop on I/O errors +- nilfs2: return the mapped address from nilfs_get_page() +- !9775 mm/slub: Reduce memory consumption in extreme scenarios +- mm/slub: Reduce memory consumption in extreme scenarios +- !9614 v2 wifi: carl9170: add a proper sanity check for endpoints +- wifi: carl9170: add a proper sanity check for endpoints +- !9709 cgroup: fix uaf when proc_cpuset_show +- cgroup: fix uaf when proc_cpuset_show +- !9748 cxl/pci: Skip to handle RAS errors if CXL.mem device is detached +- cxl/pci: Skip to handle RAS errors if CXL.mem device is detached +- !8877 drm/vmwgfx: Fix invalid reads in fence signaled events +- drm/vmwgfx: Fix invalid reads in fence signaled events +- !9730 efi: libstub: only free priv.runtime_map when allocated +- efi: libstub: only free priv.runtime_map when allocated +- !9679 cgroup/cpuset: Make cpuset hotplug processing synchronous +- cgroup/cpuset: Make cpuset hotplug processing synchronous +- !9757 net: openvswitch: fix overwriting ct original tuple for ICMPv6 +- net: openvswitch: fix overwriting ct original tuple for ICMPv6 +- !9665 CVE-2024-38622 +- drm/msm/dpu: make error messages at dpu_core_irq_register_callback() more sensible +- drm/msm/dpu: Add callback function pointer check before its call +- drm/msm/dpu: stop using raw IRQ indices in the kernel output +- drm/msm/dpu: make the irq table size static +- drm/msm/dpu: add helper to get IRQ-related data +- drm/msm/dpu: extract dpu_core_irq_is_valid() helper +- drm/msm/dpu: remove irq_idx argument from IRQ callbacks +- !9668 wifi: nl80211: Avoid address calculations via out of bounds array indexing +- wifi: nl80211: Avoid address calculations via out of bounds array indexing +- !9715 CVE-2024-38602 +- ax25: Fix reference count leak issues of ax25_dev +- ax25: Use kernel universal linked list to implement ax25_dev_list +- !9746 v2 Revert "ACPI: processor: Add support for processors described as container packages" +- Revert "ACPI: processor: Add support for processors described as container packages" +- !9736 net/9p: fix uninit-value in p9_client_rpc() +- net/9p: fix uninit-value in p9_client_rpc() +- !9596 iomap: fix warning in iomap_write_delalloc_release() +- iomap: fix warning in iomap_write_delalloc_release() +- !9703 dma-buf/sw-sync: don't enable IRQ from sync_print_obj() +- dma-buf/sw-sync: don't enable IRQ from sync_print_obj() +- !9642 CVE-2024-38582 +- nilfs2: fix potential hang in nilfs_detach_log_writer() +- nilfs2: fix unexpected freezing of nilfs_segctor_sync() +- !9687 greybus: lights: check return of get_channel_from_mode +- greybus: lights: check return of get_channel_from_mode +- !9678 crypto: bcm - Fix pointer arithmetic +- crypto: bcm - Fix pointer arithmetic +- !7918 [OLK-6.6]drivers: support Yunsilicon's metaScale/metaVisor series NICs +- drivers: support Yunsilicon's MS and MV series NICs +- !9619 r8169: Fix possible ring buffer corruption on fragmented Tx packets. +- r8169: Fix possible ring buffer corruption on fragmented Tx packets. +- !9664 tls: fix missing memory barrier in tls_init +- tls: fix missing memory barrier in tls_init +- !9161 xfs: don't use current->journal_info +- xfs: don't use current->journal_info +- !9624 CVE-2024-38597 +- net: fec: remove .ndo_poll_controller to avoid deadlocks +- eth: sungem: remove .ndo_poll_controller to avoid deadlocks +- !9631 ACPI: APEI: Skip initialization of GHES_ASSIST structures for Machine Check Architecture +- ACPI: APEI: Skip initialization of GHES_ASSIST structures for Machine Check Architecture +- !9632 drm/msm/a6xx: Avoid a nullptr dereference when speedbin setting fails +- drm/msm/a6xx: Avoid a nullptr dereference when speedbin setting fails +- !9399 fix CVE-2024-38544 and CVE-2024-37356 +- tcp: Fix shift-out-of-bounds in dctcp_update_alpha(). +- RDMA/rxe: Fix seg fault in rxe_comp_queue_pkt +- !9341 serial: max3100: Lock port->lock when calling uart_handle_cts_change() +- serial: max3100: Lock port->lock when calling uart_handle_cts_change() +- !9562 CVE-2024-38385 +- genirq/irqdesc: Prevent use-after-free in irq_find_at_or_after() +- !9582 v2 eventfs: Fix a possible null pointer dereference in eventfs_find_events() +- eventfs: Fix a possible null pointer dereference in eventfs_find_events() +- !9588 s390/ap: Fix crash in AP internal function modify_bitmap() +- s390/ap: Fix crash in AP internal function modify_bitmap() +- !9513 RDMA/rxe: Fix seg fault in rxe_comp_queue_pkt +- RDMA/rxe: Fix seg fault in rxe_comp_queue_pkt +- !9561 v2 virtio: delete vq in vp_find_vqs_msix() when request_irq() fails +- virtio: delete vq in vp_find_vqs_msix() when request_irq() fails +- !9578 net/mlx5: Discard command completions in internal error +- net/mlx5: Discard command completions in internal error +- !9549 btrfs: fix crash on racing fsync and size-extending write into prealloc +- btrfs: fix crash on racing fsync and size-extending write into prealloc +- !9479 xfs: fix unlink vs cluster buffer instantiation race +- xfs: fix unlink vs cluster buffer instantiation race +- !9519 MPTCP Upstream part 12 +- mptcp: annotate lockless accesses around read-mostly fields +- mptcp: annotate lockless access for token +- mptcp: annotate lockless access for RX path fields +- mptcp: annotate lockless access for the tx path +- mptcp: annotate access for msk keys +- !9557 i2c: acpi: Unbind mux adapters before delete +- i2c: acpi: Unbind mux adapters before delete +- !9555 smb: client: fix deadlock in smb2_find_smb_tcon() +- smb: client: fix deadlock in smb2_find_smb_tcon() +- !9489 fs/ntfs3: Check 'folio' pointer for NULL +- fs/ntfs3: Check 'folio' pointer for NULL +- !9482 fs/ntfs3: Use 64 bit variable to avoid 32 bit overflow +- fs/ntfs3: Use 64 bit variable to avoid 32 bit overflow +- !9506 usb: gadget: u_audio: Fix race condition use of controls after free during gadget unbind. +- usb: gadget: u_audio: Fix race condition use of controls after free during gadget unbind. +- !9528 media: lgdt3306a: Add a check against null-pointer-def +- media: lgdt3306a: Add a check against null-pointer-def +- !9551 ext4: fix mb_cache_entry's e_refcnt leak in ext4_xattr_block_cache_find() +- ext4: fix mb_cache_entry's e_refcnt leak in ext4_xattr_block_cache_find() +- !9478 watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger +- watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger +- !9536 clk: bcm: dvp: Assign ->num before accessing ->hws +- clk: bcm: dvp: Assign ->num before accessing ->hws +- !9463 fix CVE-2024-38621 +- media: stk1160: fix bounds checking in stk1160_copy_video() +- !9457 bpf: Add BPF_PROG_TYPE_CGROUP_SKB attach type enforcement in BPF_LINK_CREATE +- bpf: Add BPF_PROG_TYPE_CGROUP_SKB attach type enforcement in BPF_LINK_CREATE +- !9459 bpf: Fix verifier assumptions about socket->sk +- bpf: Fix verifier assumptions about socket->sk +- !9522 bonding: fix oops during rmmod +- bonding: fix oops during rmmod +- !9502 netrom: fix possible dead-lock in nr_rt_ioctl() +- netrom: fix possible dead-lock in nr_rt_ioctl() +- !9402 fs/ntfs3: Use variable length array instead of fixed size +- fs/ntfs3: Use variable length array instead of fixed size +- !9320 drm/amd/display: Fix potential index out of bounds in color transformation function +- drm/amd/display: Fix potential index out of bounds in color transformation function +- !9493 thermal/drivers/qcom/lmh: Check for SCM availability at probe +- thermal/drivers/qcom/lmh: Check for SCM availability at probe +- !9398 tracing/probes: fix error check in parse_btf_field() +- tracing/probes: fix error check in parse_btf_field() +- !9510 ftrace: Fix possible use-after-free issue in ftrace_location() +- ftrace: Fix possible use-after-free issue in ftrace_location() +- !9509 cifs: fix pagecache leak when do writepages +- cifs: fix pagecache leak when do writepages +- !9436 v2 ASoC: mediatek: Assign dummy when codec not specified for a DAI link +- ASoC: mediatek: Assign dummy when codec not specified for a DAI link +- !9486 [OLK-6.6] Fix os crash while enable sriov for rnp +- RNPVF: NET: Fix os crash while enable sriov for rnp +- !9371 MPTCP Upstream part 11 +- selftests: net: ip_local_port_range: define IPPROTO_MPTCP +- selftests: mptcp: join: check CURRESTAB counters +- selftests/net: add MPTCP coverage for IP_LOCAL_PORT_RANGE +- mptcp: sockopt: support IP_LOCAL_PORT_RANGE and IP_BIND_ADDRESS_NO_PORT +- mptcp: rename mptcp_setsockopt_sol_ip_set_transparent() +- !5258 [OLK-6.6] Support request attestation report from CSV guest +- driver/virt/coco: Add HYGON CSV Guest dirver. +- KVM: x86: Support VM_ATTESTATION hypercall +- !9485 v2 CVE-2024-38610 +- drivers/virt/acrn: fix PFNMAP PTE checks in acrn_vm_ram_map() +- virt: acrn: stop using follow_pfn +- !9380 psi: using cpuacct_cgrp_id under CONFIG_CGROUP_CPUACCT +- psi: using cpuacct_cgrp_id under CONFIG_CGROUP_CPUACCT +- !8899 block: fix module reference leakage from bdev_open_by_dev error path +- block: fix module reference leakage from bdev_open_by_dev error path +- !9445 blk-cgroup: fix list corruption from reorder of WRITE ->lqueued +- blk-cgroup: fix list corruption from reorder of WRITE ->lqueued +- !9466 io_uring: check for non-NULL file pointer in io_file_can_poll() +- io_uring: check for non-NULL file pointer in io_file_can_poll() +- !9389 block: refine the EOF check in blkdev_iomap_begin +- block: refine the EOF check in blkdev_iomap_begin +- !9414 vfio/pci: fix potential memory leak in vfio_intx_enable() +- vfio/pci: fix potential memory leak in vfio_intx_enable() +- !9455 jffs2: prevent xattr node from overflowing the eraseblock +- jffs2: prevent xattr node from overflowing the eraseblock +- !9465 CVE-2024-38662 +- Revert "bpf, sockmap: Prevent lock inversion deadlock in map delete elem" +- bpf: Allow delete from sockmap/sockhash only if update is allowed +- !9410 Fix CVE-2024-31076 +- genirq/cpuhotplug, x86/vector: Prevent vector leak during CPU offline +- !9449 rcu-tasks: Fix show_rcu_tasks_trace_gp_kthread buffer overflow +- rcu-tasks: Fix show_rcu_tasks_trace_gp_kthread buffer overflow + +* Wed Jun 26 2024 ZhangPeng - 6.6.0-31.0.0.39 +- !9438 【OLK-6.6】RDMA/hns: Fix some mutex UAF +- RDMA/hns: Fix some mutex UAF +- !9394 CVE-2024-38587 +- speakup: Fix sizeof() vs ARRAY_SIZE() bug +- !9405 drm/mediatek: Add 0 size check to mtk_drm_gem_obj +- drm/mediatek: Add 0 size check to mtk_drm_gem_obj +- !9415 mm: drop the 'anon_' prefix for swap-out mTHP counters +- mm: drop the 'anon_' prefix for swap-out mTHP counters +- !9376 ALSA: core: Fix NULL module pointer assignment at card init +- ALSA: core: Fix NULL module pointer assignment at card init +- !9295 Port patches from OLK-5.10 +- livepatch: Enable CONFIG_LIVEPATCH_ISOLATE_KPROBE in openeuler_defconfig +- livepatch: Avoid patching conflicts with kprobes +- !9356 tpm_tis_spi: Account for SPI header when allocating TPM SPI xfer buffer +- tpm_tis_spi: Account for SPI header when allocating TPM SPI xfer buffer +- !9332 net/sched: taprio: always validate TCA_TAPRIO_ATTR_PRIOMAP +- net/sched: taprio: always validate TCA_TAPRIO_ATTR_PRIOMAP +- !9355 f2fs: multidev: fix to recognize valid zero block address +- f2fs: multidev: fix to recognize valid zero block address +- !9329 af_unix: Fix data races in unix_release_sock/unix_stream_sendmsg +- af_unix: Fix data races in unix_release_sock/unix_stream_sendmsg +- !9352 MPTCP Upstream part 10 +- MAINTAINERS: add Geliang as reviewer for MPTCP +- mailmap: add entries for Geliang Tang +- mptcp: fill in missing MODULE_DESCRIPTION() +- netlink: fill in missing MODULE_DESCRIPTION() +- netlink: specs: mptcp: rename the MPTCP path management spec +- !9304 MPTCP Upstream part 9 +- selftests: mptcp: add mptcp_lib_wait_local_port_listen +- selftests: mptcp: add mptcp_lib_check_transfer +- selftests: mptcp: add mptcp_lib_make_file +- selftests: mptcp: add missing oflag=append +- !9307 of: module: add buffer overflow check in of_modalias() +- of: module: add buffer overflow check in of_modalias() +- !9331 Some folio bugfix +- mm/memory: don't require head page for do_set_pmd() +- mm/migrate: fix kernel BUG at mm/compaction.c:2761! +- mm: huge_memory: fix misused mapping_large_folio_support() for anon folios +- mm: shmem: fix getting incorrect lruvec when replacing a shmem folio +- mm: fix possible OOB in numa_rebuild_large_mapping() +- mm: support multi-size THP numa balancing +- mm/rmap: do not add fully unmapped large folio to deferred split list +- !9302 ring-buffer: Fix a race between readers and resize checks +- ring-buffer: Fix a race between readers and resize checks +- !9345 net: sched: sch_multiq: fix possible OOB write in multiq_tune() +- net: sched: sch_multiq: fix possible OOB write in multiq_tune() +- !9346 net: bridge: xmit: make sure we have at least eth header len bytes +- net: bridge: xmit: make sure we have at least eth header len bytes +- !9301 MPTCP Upstream part 8 +- selftests: mptcp: userspace pm send RM_ADDR for ID 0 +- selftests: mptcp: userspace pm remove initial subflow +- mptcp: userspace pm rename remove_err to out +- selftests: mptcp: userspace pm create id 0 subflow +- mptcp: add mptcpi_subflows_total counter +- !9266 MPTCP Upstream part 7 +- net: fill in MODULE_DESCRIPTION()s for SOCK_DIAG modules +- selftests: mptcp: sockopt: drop mptcp_connect var +- mptcp: define more local variables sk +- mptcp: move sk assignment statement ahead +- !9262 MPTCP Upstream part 6 +- mptcp: use mptcp_get_ext helper +- mptcp: use mptcp_check_fallback helper +- mptcp: drop useless ssk in pm_subflow_check_next +- mptcp: ignore notsent_lowat setting at the subflow level +- mptcp: consolidate sockopt synchronization +- !5257 [OLK-6.6] Support DOWNLOAD_FIRMWARE feature for hygon CSV +- crypto: ccp: Implement CSV_DOWNLOAD_FIRMWARE ioctl command +- crypto: ccp: Implement CSV_PLATFORM_SHUTDOWN ioctl command +- crypto: ccp: Implement CSV_PLATFORM_INIT ioctl command +- crypto: ccp: Support DOWNLOAD_FIRMWARE when detect CSV +- !8058 Intel: Backport QuickAssist Technology(QAT) live migration support for in-tree driver +- Enable QAT_VFIO_PCI as kernel module to support Intel QAT live migration +- crypto: qat - Fix ADF_DEV_RESET_SYNC memory leak +- crypto: qat - specify firmware files for 402xx +- crypto: qat - validate slices count returned by FW +- crypto: qat - improve error logging to be consistent across features +- crypto: qat - improve error message in adf_get_arbiter_mapping() +- crypto: qat - implement dh fallback for primes > 4K +- crypto: qat - Fix spelling mistake "Invalide" -> "Invalid" +- crypto: qat - Avoid -Wflex-array-member-not-at-end warnings +- vfio/qat: Add vfio_pci driver for Intel QAT SR-IOV VF devices +- crypto: qat - implement interface for live migration +- crypto: qat - add interface for live migration +- crypto: qat - add bank save and restore flows +- crypto: qat - expand CSR operations for QAT GEN4 devices +- crypto: qat - rename get_sla_arr_of_type() +- crypto: qat - relocate CSR access code +- crypto: qat - move PFVF compat checker to a function +- crypto: qat - relocate and rename 4xxx PF2VM definitions +- crypto: qat - adf_get_etr_base() helper +- !8304 [OLK-6.6] Backport TPMI based RAPL PMU support for next Intel Xeon Granite Rapids (GNR) +- powercap: intel_rapl_tpmi: Enable PMU support +- powercap: intel_rapl: Introduce APIs for PMU support +- powercap: intel_rapl: Sort header files +- !9245 MPTCP Upstream part 5 +- mptcp: prevent BPF accessing lowat from a subflow socket. +- mptcp: use copy_from_iter helpers on transmit +- mptcp: give rcvlowat some love +- tcp: define initial scaling factor value as a macro +- mptcp: use plain bool instead of custom binary enum +- mptcp: add a new sysctl for make after break timeout +- !8422 [OLK-6.6] Intel IAA Compression Accelerator Crypto Driver (iaa_crypto) +- openeuler_defconfig: Add kernel config for Intel IAA crypto driver +- dmaengine: idxd: Avoid unnecessary destruction of file_ida +- dmaengine: idxd: Check for driver name match before sva user feature +- crypto: iaa - Use cpumask_weight() when rebalancing +- crypto: iaa - Fix some errors in IAA documentation +- crypto: iaa - Change iaa statistics to atomic64_t +- crypto: iaa - Add global_stats file and remove individual stat files +- crypto: iaa - Remove comp/decomp delay statistics +- crypto: iaa - fix decomp_bytes_in stats +- crypto: iaa - Fix nr_cpus < nr_iaa case +- crypto: iaa - fix the missing CRYPTO_ALG_ASYNC in cra_flags +- crypto: iaa - Fix comp/decomp delay statistics +- crypto: iaa - Fix async_disable descriptor leak +- crypto: iaa - Remove unnecessary debugfs_create_dir() error check in iaa_crypto_debugfs_init() +- crypto: iaa - Remove header table code +- dmaengine: idxd: constify the struct device_type usage +- dmaengine: idxd: make dsa_bus_type const +- dmaengine: idxd: Remove usage of the deprecated ida_simple_xx() API +- crypto: iaa - Account for cpu-less numa nodes +- crypto: iaa - remove unneeded semicolon +- crypto: iaa - Remove unneeded newline in update_max_adecomp_delay_ns() +- crypto: iaa - Change desc->priv to 0 +- dmaengine: idxd: Add support for device/wq defaults +- crypto: iaa - Add IAA Compression Accelerator stats +- crypto: iaa - Add irq support for the crypto async interface +- crypto: iaa - Add support for deflate-iaa compression algorithm +- crypto: iaa - Add compression mode management along with fixed mode +- crypto: iaa - Add per-cpu workqueue table with rebalancing +- crypto: iaa - Add Intel IAA Compression Accelerator crypto driver core +- crypto: iaa - Add IAA Compression Accelerator Documentation +- dmaengine: idxd: add callback support for iaa crypto +- dmaengine: idxd: Add wq private data accessors +- dmaengine: idxd: Export wq resource management functions +- dmaengine: idxd: Export descriptor management functions +- dmaengine: idxd: Rename drv_enable/disable_wq to idxd_drv_enable/disable_wq, and export +- dmaengine: idxd: add external module driver support for dsa_bus_type +- dmaengine: idxd: Fix incorrect descriptions for GRPCFG register +- dmaengine: idxd: add wq driver name support for accel-config user tool +- dmaengine: idxd: rate limit printk in misc interrupt thread +- !9230 MPTCP Upstream part 4 +- net: mptcp: use policy generated by YAML spec +- net: mptcp: rename netlink handlers to mptcp_pm_nl__{doit,dumpit} +- uapi: mptcp: use header file generated from YAML spec +- Documentation: netlink: add a YAML spec for mptcp +- net: mptcp: convert netlink from small_ops to ops +- !9229 v2 sched: smart_grid: fix potential NULL pointer dereference +- sched: smart_grid: fix potential NULL pointer dereference +- !9226 MPTCP Upstream part 3 +- tools: ynl-gen: add support for exact-len validation +- tools: ynl: add uns-admin-perm to genetlink legacy +- tools: ynl-gen: support limit names +- tools: ynl-gen: support full range of min/max checks for integer values +- tools: ynl-gen: track attribute use +- !9217 memcg: attach memcg async reclaim worker to curcpu +- memcg: attach memcg async reclaim worker to curcpu +- !9173 MPTCP Upstream part 2 +- inet: implement lockless getsockopt(IP_MULTICAST_IF) +- inet: lockless IP_PKTOPTIONS implementation +- inet: implement lockless getsockopt(IP_UNICAST_IF) +- inet: lockless getsockopt(IP_MTU) +- inet: lockless getsockopt(IP_OPTIONS) + +* Wed Jun 19 2024 ZhangPeng - 6.6.0-30.0.0.38 +- !8809 MPTCP Upstream part 1 +- net: bpf: Use sockopt_lock_sock() in ip_sock_set_tos() +- inet: lock the socket in ip_sock_set_tos() +- inet: implement lockless IP_TOS +- inet: implement lockless IP_MTU_DISCOVER +- inet: implement lockless IP_MULTICAST_TTL +- !9141 Fix allmodconfig build frame size error +- net/ethernet/huawei/hiroce3: Fix allmodconfig build frame size error +- !9101 ext4: Skip moving extents if page writeback failed +- ext4: Skip moving extents if page writeback failed +- !9126 arm64: armv8_deprecated: Fix warning in isndep cpuhp starting process +- arm64: armv8_deprecated: Fix warning in isndep cpuhp starting process +- !9010 Backport 6.6.31&6.6.32 LTS patches from upstream +- block: add a partscan sysfs attribute for disks +- block: add a disk_has_partscan helper +- Docs/admin-guide/mm/damon/usage: fix wrong example of DAMOS filter matching sysfs file +- docs: kernel_include.py: Cope with docutils 0.21 +- admin-guide/hw-vuln/core-scheduling: fix return type of PR_SCHED_CORE_GET +- KEYS: trusted: Do not use WARN when encode fails +- remoteproc: mediatek: Make sure IPI buffer fits in L2TCM +- serial: kgdboc: Fix NMI-safety problems from keyboard reset code +- usb: typec: tipd: fix event checking for tps6598x +- usb: typec: ucsi: displayport: Fix potential deadlock +- net: usb: ax88179_178a: fix link status when link is set to down/up +- usb: dwc3: Wait unconditionally after issuing EndXfer command +- binder: fix max_thread type inconsistency +- drm/amdgpu: Fix possible NULL dereference in amdgpu_ras_query_error_status_helper() +- erofs: reliably distinguish block based and fscache mode +- erofs: get rid of erofs_fs_context +- kselftest: Add a ksft_perror() helper +- mmc: core: Add HS400 tuning in HS400es initialization +- KEYS: trusted: Fix memory leak in tpm2_key_encode() +- Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init() +- Bluetooth: L2CAP: Fix slab-use-after-free in l2cap_connect() +- ice: remove unnecessary duplicate checks for VF VSI ID +- ice: pass VSI pointer into ice_vc_isvalid_q_id +- net: ks8851: Fix another TX stall caused by wrong ISR flag handling +- drm/amd/display: Fix division by zero in setup_dsc_config +- smb: smb2pdu.h: Avoid -Wflex-array-member-not-at-end warnings +- ksmbd: add continuous availability share parameter +- cifs: Add tracing for the cifs_tcon struct refcounting +- smb: client: instantiate when creating SFU files +- smb: client: fix NULL ptr deref in cifs_mark_open_handles_for_deleted_file() +- smb3: add trace event for mknod +- smb311: additional compression flag defined in updated protocol spec +- smb311: correct incorrect offset field in compression header +- cifs: Move some extern decls from .c files to .h +- ksmbd: Fix spelling mistake "connction" -> "connection" +- ksmbd: fix possible null-deref in smb_lazy_parent_lease_break_close +- cifs: remove redundant variable assignment +- cifs: fixes for get_inode_info +- cifs: defer close file handles having RH lease +- ksmbd: add support for durable handles v1/v2 +- ksmbd: mark SMB2_SESSION_EXPIRED to session when destroying previous session +- smb: common: simplify compression headers +- smb: common: fix fields sizes in compression_pattern_payload_v1 +- smb: client: negotiate compression algorithms +- smb3: add dynamic trace point for ioctls +- smb: client: return reparse type in /proc/mounts +- smb: client: set correct d_type for reparse DFS/DFSR and mount point +- smb: client: parse uid, gid, mode and dev from WSL reparse points +- smb: client: introduce SMB2_OP_QUERY_WSL_EA +- smb: client: Fix a NULL vs IS_ERR() check in wsl_set_xattrs() +- smb: client: add support for WSL reparse points +- smb: client: reduce number of parameters in smb2_compound_op() +- smb: client: fix potential broken compound request +- smb: client: move most of reparse point handling code to common file +- smb: client: introduce reparse mount option +- smb: client: retry compound request without reusing lease +- smb: client: do not defer close open handles to deleted files +- smb: client: reuse file lease key in compound operations +- smb: client: get rid of smb311_posix_query_path_info() +- smb: client: parse owner/group when creating reparse points +- smb3: update allocation size more accurately on write completion +- smb: client: handle path separator of created SMB symlinks +- cifs: update the same create_guid on replay +- ksmbd: Add kernel-doc for ksmbd_extract_sharename() function +- cifs: set replay flag for retries of write command +- cifs: commands that are retried should have replay flag set +- smb: client: delete "true", "false" defines +- smb: Fix some kernel-doc comments +- cifs: new mount option called retrans +- smb: client: don't clobber ->i_rdev from cached reparse points +- cifs: new nt status codes from MS-SMB2 +- cifs: pick channel for tcon and tdis +- cifs: minor comment cleanup +- cifs: remove redundant variable tcon_exist +- ksmbd: vfs: fix all kernel-doc warnings +- ksmbd: auth: fix most kernel-doc warnings +- cifs: remove unneeded return statement +- cifs: get rid of dup length check in parse_reparse_point() +- cifs: Pass unbyteswapped eof value into SMB2_set_eof() +- smb3: Improve exception handling in allocate_mr_list() +- cifs: fix in logging in cifs_chan_update_iface +- smb: client: handle special files and symlinks in SMB3 POSIX +- smb: client: cleanup smb2_query_reparse_point() +- smb: client: allow creating symlinks via reparse points +- smb: client: optimise reparse point querying +- smb: client: allow creating special files via reparse points +- smb: client: extend smb2_compound_op() to accept more commands +- smb: client: Fix minor whitespace errors and warnings +- smb: client: introduce cifs_sfu_make_node() +- cifs: fix use after free for iface while disabling secondary channels +- Missing field not being returned in ioctl CIFS_IOC_GET_MNT_INFO +- smb3: minor cleanup of session handling code +- smb3: more minor cleanups for session handling routines +- smb3: minor RDMA cleanup +- cifs: print server capabilities in DebugData +- smb: use crypto_shash_digest() in symlink_hash() +- Add definition for new smb3.1.1 command type +- SMB3: clarify some of the unused CreateOption flags +- cifs: Add client version details to NTLM authenticate message +- md: fix kmemleak of rdev->serial +- Revert "selftests/bpf: Add netkit to tc_redirect selftest" +- btrfs: do not wait for short bulk allocation +- keys: Fix overwrite of key expiration on instantiation +- dmaengine: idxd: add a write() method for applications to submit work +- dmaengine: idxd: add a new security check to deal with a hardware erratum +- VFIO: Add the SPR_DSA and SPR_IAX devices to the denylist +- Bluetooth: qca: fix firmware check error path +- Bluetooth: qca: fix info leak when fetching fw build id +- Bluetooth: qca: fix info leak when fetching board id +- Bluetooth: qca: generalise device address check +- Bluetooth: qca: fix NVM configuration parsing +- Bluetooth: qca: add missing firmware sanity checks +- Bluetooth: qca: fix wcn3991 device address check +- Bluetooth: qca: fix invalid device address check +- eventfs: Do not treat events directory different than other directories +- tracefs: Still use mount point as default permissions for instances +- tracefs: Reset permissions on remount if permissions are options +- ksmbd: do not grant v2 lease if parent lease key and epoch are not set +- ksmbd: avoid to send duplicate lease break notifications +- ksmbd: off ipv6only for both ipv4/ipv6 binding +- spi: microchip-core-qspi: fix setting spi bus clock rate +- regulator: core: fix debugfs creation regression +- nvme-pci: Add quirk for broken MSIs +- selftests/mm: fix powerpc ARCH check +- x86/apic: Don't access the APIC when disabling x2APIC +- hwmon: (pmbus/ucd9000) Increase delay from 250 to 500us +- net: fix out-of-bounds access in ops_init +- arm64: dts: qcom: sa8155p-adp: fix SDHC2 CD pin configuration +- drm/amd/display: Fix incorrect DSC instance for MST +- drm/amd/display: Handle Y carry-over in VCP X.Y calculation +- drm/i915/bios: Fix parsing backlight BDB data +- drm/i915/gt: Automate CCS Mode setting during engine resets +- drm/i915/audio: Fix audio time stamp programming for DP +- drm/vmwgfx: Fix invalid reads in fence signaled events +- drm/vmwgfx: Fix Legacy Display Unit +- drm/ttm: Print the memory decryption status just once +- drm/amdkfd: don't allow mapping the MMIO HDP page with large pages +- Revert "drm/nouveau/firmware: Fix SG_DEBUG error with nvkm_firmware_ctor()" +- drm/nouveau/firmware: Fix SG_DEBUG error with nvkm_firmware_ctor() +- mei: me: add lunar lake point M DID +- clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI +- clk: sunxi-ng: common: Support minimum and maximum rate +- slimbus: qcom-ngd-ctrl: Add timeout for wait operation +- dyndbg: fix old BUG_ON in >control parser +- ASoC: ti: davinci-mcasp: Fix race condition during probe +- ASoC: tegra: Fix DSPK 16-bit playback +- net: bcmgenet: synchronize UMAC_CMD access +- net: bcmgenet: synchronize use of bcmgenet_set_rx_mode() +- net: bcmgenet: synchronize EXT_RGMII_OOB_CTRL access +- xtensa: fix MAKE_PC_FROM_RA second argument +- tipc: fix UAF in error path +- e1000e: change usleep_range to udelay in PHY mdic access +- kmsan: compiler_types: declare __no_sanitize_or_inline +- iio: accel: mxc4005: Interrupt handling fixes +- iio: pressure: Fixes BME280 SPI driver data +- iio:imu: adis16475: Fix sync mode setting +- dt-bindings: iio: health: maxim,max30102: fix compatible check +- workqueue: Fix selection of wake_cpu in kick_pool() +- mptcp: only allow set existing scheduler for net.mptcp.scheduler +- mptcp: ensure snd_nxt is properly initialized on connect +- mm/slab: make __free(kfree) accept error pointers +- maple_tree: fix mas_empty_area_rev() null pointer dereference +- btrfs: set correct ram_bytes when splitting ordered extent +- btrfs: add missing mutex_unlock in btrfs_relocate_sys_chunks() +- firewire: ohci: fulfill timestamp for some local asynchronous transaction +- ALSA: hda/realtek: Fix mute led of HP Laptop 15-da3001TU +- usb: typec: tcpm: Check for port partner validity before consuming it +- usb: typec: tcpm: unregister existing source caps before re-registration +- usb: typec: tcpm: clear pd_event queue in PORT_RESET +- usb: dwc3: core: Prevent phy suspend during init +- usb: xhci-plat: Don't include xhci.h +- usb: gadget: f_fs: Fix a race condition when processing setup packets. +- usb: gadget: f_fs: Fix race between aio_cancel() and AIO request complete +- usb: gadget: uvc: use correct buffer size when parsing configfs lists +- usb: gadget: composite: fix OS descriptors w_value logic +- USB: core: Fix access violation during port device removal +- usb: ohci: Prevent missed ohci interrupts +- usb: Fix regression caused by invalid ep0 maxpacket in virtual SuperSpeed device +- usb: typec: ucsi: Fix connector check on init +- usb: typec: ucsi: Check for notifications after init +- Reapply "drm/qxl: simplify qxl_fence_wait" +- firewire: nosy: ensure user_length is taken into account when fetching packet contents +- btrfs: fix kvcalloc() arguments order in btrfs_ioctl_send() +- drm/amdgpu: once more fix the call oder in amdgpu_ttm_move() v2 +- drm/amdgpu: Fix comparison in amdgpu_res_cpu_visible +- drm/amd/display: Atom Integrated System Info v2_2 for DCN35 +- gpiolib: cdev: fix uninitialised kfifo +- gpiolib: cdev: relocate debounce_period_us from struct gpio_desc +- gpiolib: cdev: Fix use after free in lineinfo_changed_notify +- dm/amd/pm: Fix problems with reboot/shutdown for some SMU 13.0.4/13.0.11 users +- drm/connector: Add +- drm/meson: dw-hdmi: add bandgap setting for g12 +- drm/meson: dw-hdmi: power up phy on device init +- net: dsa: mv88e6xxx: add phylink_get_caps for the mv88e6320/21 family +- net/smc: fix neighbour and rtable leak in smc_ib_find_route() +- ipv6: prevent NULL dereference in ip6_output() +- ipv6: annotate data-races around cnf.disable_ipv6 +- hsr: Simplify code for announcing HSR nodes timer setup +- net-sysfs: convert dev->operstate reads to lockless ones +- ipv6: fib6_rules: avoid possible NULL dereference in fib6_rule_action() +- dt-bindings: net: mediatek: remove wrongly added clocks and SerDes +- rxrpc: Only transmit one ACK per jumbo packet received +- rxrpc: Fix congestion control algorithm +- rxrpc: Fix the names of the fields in the ACK trailer struct +- selftests: test_bridge_neigh_suppress.sh: Fix failures due to duplicate MAC +- selftests/net: convert test_bridge_neigh_suppress.sh to run it in unique namespace +- ipv6: Fix potential uninit-value access in __ip6_make_skb() +- net: bridge: fix corrupted ethernet header on multicast-to-unicast +- nfc: nci: Fix kcov check in nci_rx_work() +- phonet: fix rtm_phonet_notify() skb allocation +- hwmon: (corsair-cpro) Protect ccp->wait_input_report with a spinlock +- hwmon: (corsair-cpro) Use complete_all() instead of complete() in ccp_raw_event() +- hwmon: (corsair-cpro) Use a separate buffer for sending commands +- rtnetlink: Correct nested IFLA_VF_VLAN_LIST attribute validation +- net: ks8851: Queue RX packets in IRQ handler instead of disabling BHs +- Bluetooth: l2cap: fix null-ptr-deref in l2cap_chan_timeout +- Bluetooth: HCI: Fix potential null-ptr-deref +- Bluetooth: msft: fix slab-use-after-free in msft_do_close() +- Bluetooth: Fix use-after-free bugs caused by sco_sock_timeout +- tcp: Use refcount_inc_not_zero() in tcp_twsk_unique(). +- tcp: defer shutdown(SEND_SHUTDOWN) for TCP_SYN_RECV sockets +- ARM: 9381/1: kasan: clear stale stack poison +- qibfs: fix dentry leak +- SUNRPC: add a missing rpc_stat for TCP TLS +- blk-iocost: do not WARN if iocg was already offlined +- net:usb:qmi_wwan: support Rolling modules +- drm/radeon: silence UBSAN warning (v3) +- platform/x86: ISST: Add Granite Rapids-D to HPM CPU list +- drm/nouveau/dp: Don't probe eDP ports twice harder +- gpio: lpc32xx: fix module autoloading +- fs/9p: drop inodes immediately on non-.L too +- clk: Don't hold prepare_lock when calling kref_put() +- gpio: crystalcove: Use -ENOTSUPP consistently +- gpio: wcove: Use -ENOTSUPP consistently +- powerpc/crypto/chacha-p10: Fix failure on non Power10 +- 9p: explicitly deny setlease attempts +- fs/9p: fix the cache always being enabled on files with qid flags +- fs/9p: translate O_TRUNC into OTRUNC +- fs/9p: only translate RWX permissions for plain 9P2000 +- iommu: mtk: fix module autoloading +- smb3: fix broken reconnect when password changing on the server by allowing password rotation +- Drivers: hv: vmbus: Don't free ring buffers that couldn't be re-encrypted +- uio_hv_generic: Don't free decrypted memory +- hv_netvsc: Don't free decrypted memory +- Drivers: hv: vmbus: Track decrypted status in vmbus_gpadl +- Drivers: hv: vmbus: Leak pages if set_memory_encrypted() fails +- selftests: timers: Fix valid-adjtimex signed left-shift undefined behavior +- amd/amdkfd: sync all devices to wait all processes being evicted +- drm/amdgpu: Fix VCN allocation in CPX partition +- drm/amd/display: Skip on writeback when it's not applicable +- drm/amdgpu: implement IRQ_STATE_ENABLE for SDMA v4.4.2 +- drm/amdgpu: Refine IB schedule error logging +- tools/power/turbostat: Fix uncore frequency file string +- MIPS: scall: Save thread_info.syscall unconditionally on entry +- gpu: host1x: Do not setup DMA for virtual devices +- blk-iocost: avoid out of bounds shift +- scsi: target: Fix SELinux error when systemd-modules loads the target module +- memblock tests: fix undefined reference to `BIT' +- memblock tests: fix undefined reference to `panic' +- memblock tests: fix undefined reference to `early_pfn_to_nid' +- btrfs: always clear PERTRANS metadata during commit +- btrfs: make btrfs_clear_delalloc_extent() free delalloc reserve +- tools/power turbostat: Fix warning upon failed /dev/cpu_dma_latency read +- tools/power turbostat: Print ucode revision only if valid +- tools/power turbostat: Fix Bzy_MHz documentation typo +- tools/power turbostat: Increase the limit for fd opened +- tools/power turbostat: Fix added raw MSR output +- firewire: ohci: mask bus reset interrupts between ISR and bottom half +- ata: sata_gemini: Check clk_enable() result +- vboxsf: explicitly deny setlease attempts +- net: bcmgenet: Reset RBUF on first open +- ALSA: line6: Zero-initialize message buffers +- scsi: ufs: core: Fix MCQ mode dev command timeout +- scsi: ufs: core: WLUN suspend dev/link state error recovery +- regulator: tps65132: Add of_match table +- ASoC: SOF: Intel: hda-dsp: Skip IMR boot on ACE platforms in case of S3 suspend +- kbuild: Disable KCSAN for autogenerated *.mod.c intermediaries +- selftests/ftrace: Fix event filter target_func selection +- bpf: Check bloom filter map value size +- drm/amdkfd: range check cp bad op exception interrupts +- drm/amdkfd: Check cgroup when returning DMABuf info +- btrfs: return accurate error code on open failure in open_fs_devices() +- scsi: bnx2fc: Remove spin_lock_bh while releasing resources after upload +- scsi: mpi3mr: Avoid memcpy field-spanning write WARNING +- net: mark racy access on sk->sk_rcvbuf +- wifi: iwlwifi: mvm: guard against invalid STA ID on removal +- wifi: iwlwifi: read txq->read_ptr under lock +- wifi: mac80211: fix prep_connection error path +- wifi: cfg80211: fix rdev_dump_mpp() arguments order +- wifi: mac80211: fix ieee80211_bss_*_flags kernel-doc +- gfs2: Fix invalid metadata access in punch_hole +- scsi: lpfc: Use a dedicated lock for ras_fwlog state +- scsi: lpfc: Release hbalock before calling lpfc_worker_wake_up() +- scsi: lpfc: Replace hbalock with ndlp lock in lpfc_nvme_unregister_port() +- scsi: lpfc: Update lpfc_ramp_down_queue_handler() logic +- scsi: lpfc: Remove IRQF_ONESHOT flag from threaded IRQ handling +- scsi: lpfc: Move NPIV's transport unregistration to after resource clean up +- scsi: ufs: core: Fix MCQ MAC configuration +- KVM: arm64: vgic-v2: Check for non-NULL vCPU in vgic_v2_parse_attr() +- KVM: arm64: vgic-v2: Use cpuid from userspace as vcpu_id +- swiotlb: initialise restricted pool list_head when SWIOTLB_DYNAMIC=y +- powerpc/pseries/iommu: LPAR panics during boot up with a frozen PE +- powerpc/pseries: make max polling consistent for longer H_CALLs +- clk: sunxi-ng: h6: Reparent CPUX during PLL CPUX rate change +- clk: qcom: smd-rpm: Restore msm8976 num_clk +- net: gro: add flush check in udp_gro_receive_segment +- net: gro: fix udp bad offset in socket lookup by adding {inner_}network_offset to napi_gro_cb +- net: gro: parse ipv6 ext headers without frag0 invalidation +- ipv4: Fix uninit-value access in __ip_make_skb() +- drm/panel: ili9341: Use predefined error codes +- drm/panel: ili9341: Respect deferred probe +- drm/panel: ili9341: Correct use of device property APIs +- s390/qeth: Fix kernel panic after setting hsuid +- vxlan: Pull inner IP header in vxlan_rcv(). +- tipc: fix a possible memleak in tipc_buf_append +- rxrpc: Clients must accept conn from any address +- net: core: reject skb_copy(_expand) for fraglist GSO skbs +- net: bridge: fix multicast-to-unicast with fraglist GSO +- spi: fix null pointer dereference within spi_sync +- drm/amdgpu: fix doorbell regression +- net: dsa: mv88e6xxx: Fix number of databases for 88E6141 / 88E6341 +- cxgb4: Properly lock TX queue for the selftest. +- s390/cio: Ensure the copied buf is NUL terminated +- ALSA: hda: intel-sdw-acpi: fix usage of device_get_named_child_node() +- ASoC: meson: cards: select SND_DYNAMIC_MINORS +- ASoC: meson: axg-tdm-interface: manage formatters in trigger +- ASoC: meson: axg-card: make links nonatomic +- ASoC: meson: axg-fifo: use threaded irq to check periods +- ASoC: meson: axg-fifo: use FIELD helpers +- vxlan: Add missing VNI filter counter update in arp_reduce(). +- vxlan: Fix racy device stats updates. +- net: qede: use return from qede_parse_actions() +- net: qede: use return from qede_parse_flow_attr() for flow_spec +- net: qede: use return from qede_parse_flow_attr() for flower +- net: qede: sanitize 'rc' in qede_add_tc_flower_fltr() +- ALSA: emu10k1: fix E-MU dock initialization +- ALSA: emu10k1: move the whole GPIO event handling to the workqueue +- ALSA: emu10k1: factor out snd_emu1010_load_dock_firmware() +- ALSA: emu10k1: fix E-MU card dock presence monitoring +- Fix a potential infinite loop in extract_user_to_sg() +- s390/vdso: Add CFI for RA register to asm macro vdso_func +- net l2tp: drop flow hash on forward +- nsh: Restore skb->{protocol,data,mac_header} for outer header in nsh_gso_segment(). +- octeontx2-af: avoid off-by-one read from userspace +- bna: ensure the copied buf is NUL terminated +- xdp: use flags field to disambiguate broadcast redirect +- s390/mm: Fix clearing storage keys for huge pages +- s390/mm: Fix storage key clearing for guest huge pages +- ASoC: codecs: wsa881x: set clk_stop_mode1 flag +- ASoC: Intel: avs: Set name of control as in topology +- riscv, bpf: Fix incorrect runtime stats +- bpf, arm64: Fix incorrect runtime stats +- spi: axi-spi-engine: fix version format string +- spi: axi-spi-engine: use common AXI macros +- spi: axi-spi-engine: move msg state to new struct +- spi: axi-spi-engine: use devm_spi_alloc_host() +- spi: axi-spi-engine: simplify driver data allocation +- spi: spi-axi-spi-engine: Use helper function devm_clk_get_enabled() +- bpf: Fix a verifier verbose message +- nvme: fix warn output about shared namespaces without CONFIG_NVME_MULTIPATH +- ASoC: SOF: Intel: add default firmware library path for LNL +- ASoC: SOF: Introduce generic names for IPC types +- regmap: Add regmap_read_bypassed() +- bpf, skmsg: Fix NULL pointer dereference in sk_psock_skb_ingress_enqueue +- bpf, kconfig: Fix DEBUG_INFO_BTF_MODULES Kconfig definition +- regulator: change devm_regulator_get_enable_optional() stub to return Ok +- regulator: change stubbed devm_regulator_get_enable to return Ok +- regulator: mt6360: De-capitalize devicetree regulator subnodes +- pinctrl: devicetree: fix refcount leak in pinctrl_dt_to_map() +- power: supply: mt6360_charger: Fix of_match for usb-otg-vbus regulator +- power: rt9455: hide unused rt9455_boost_voltage_values +- pinctrl: baytrail: Fix selecting gpio pinctrl state +- nfs: Handle error of rpc_proc_register() in nfs_net_init(). +- nfs: make the rpc_stat per net namespace +- nfs: expose /proc/net/sunrpc/nfs in net namespaces +- sunrpc: add a struct rpc_stats arg to rpc_create_args +- pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE +- pinctrl: mediatek: paris: Fix PIN_CONFIG_INPUT_SCHMITT_ENABLE readback +- pinctrl: core: delete incorrect free in pinctrl_enable() +- pinctrl/meson: fix typo in PDM's pin name +- pinctrl: pinctrl-aspeed-g6: Fix register offset for pinconf of GPIOR-T +- Bluetooth: qca: add support for QCA2066 +- eeprom: at24: fix memory corruption race condition +- eeprom: at24: Probe for DDR3 thermal sensor in the SPD case +- rust: kernel: require `Send` for `Module` implementations +- wifi: nl80211: don't free NULL coalescing rule +- rust: macros: fix soundness issue in `module!` macro +- rust: module: place generated init_module() function in .init.text +- mtd: limit OTP NVMEM cell parse to non-NAND devices +- nvmem: add explicit config option to read old syntax fixed OF cells +- dmaengine: Revert "dmaengine: pl330: issue_pending waits until WFP state" +- dmaengine: pl330: issue_pending waits until WFP state +- !9104 [OLK-6.6] drm/phytium: Fix make allmodconfig build fail +- DRM: Fix Phytium DRM build fail +- !9085 [OLK-6.6] openeuler_defconfig: fix checkdefconfig fail +- openeuler_defconfig: fix checkdefconfig fail +- !8750 ubifs: Check @c->dirty_[n|p +- ubifs: Check @c->dirty_[n|p]n_cnt and @c->nroot state under @c->lp_mutex +- !8703 v2 IMA: Introduce a config to bypass i_version detection for Overlayfs issue +- IMA: Introduce a config to bypass i_version detection for Overlayfs issue +- !8621 LoongArch: fix HT RX INT TRANS register not initialized +- LoongArch: fix HT RX INT TRANS register not initialized +- !8440 arm64: cpufeature: Both the major and the minor version numbers need to be checked +- arm64/mpam: skip mpam initialize under kdump kernel +- arm64: cpufeature: Both the major and the minor version numbers need to be checked +- !8107 [OLK 6.6]net: hns3: fix kernel crash when devlink reload during pf/vf initialization +- {topost} net: hns3: fix kernel crash when devlink reload during vf initialization +- {topost} net: hns3: fix kernel crash when devlink reload during pf initialization +- !8481 Fix vf init and common user permissions issue +- net/ethernet/huawei/hiroce3: Fix vf init and common user permissions issue +- !8576 【OLK-6.6】backport PCC patches to support shared interrupt for multiple subspaces and platform notification handling +- soc: hisilicon: kunpeng_hccs: replace MAILBOX dependency with PCC +- soc: hisilicon: kunpeng_hccs: Add the check for obtaining complete port attribute +- mailbox: pcc: Support shared interrupt for multiple subspaces +- mailbox: pcc: Add support for platform notification handling +- !8471 ext4: Fixes len calculation in mpage_journal_page_buffers +- ext4: Fixes len calculation in mpage_journal_page_buffers +- !8496 mm/mlock: return EINVAL for illegal user memory range in mlock +- mm/mlock: return EINVAL for illegal user memory range in mlock +- !8435 LoongArch: add GMAC&GNET support +- net: stmmac: dwmac-loongson: Add loongson module author +- net: stmmac: dwmac-loongson: Move disable_force flag to _gnet_date +- net: stmmac: dwmac-loongson: Add Loongson GNET support +- net: stmmac: dwmac-loongson: Fixed failure to set network speed to 1000. +- net: stmmac: dwmac-loongson: Add loongson_dwmac_config_legacy +- net: stmmac: dwmac-loongson: Add full PCI support +- net: stmmac: dwmac-loongson: Add phy_interface for Loongson GMAC +- net: stmmac: dwmac-loongson: Add phy mask for Loongson GMAC +- net: stmmac: dwmac-loongson: Add ref and ptp clocks for Loongson +- net: stmmac: dwmac-loongson: Split up the platform data initialization +- net: stmmac: dwmac-loongson: Use PCI_DEVICE_DATA() macro for device identification +- net: stmmac: dwmac-loongson: Drop useless platform data +- net: stmmac: Export dwmac1000_dma_ops +- net: stmmac: Add multi-channel support +- net: stmmac: Move the atds flag to the stmmac_dma_cfg structure +- !7896 backport upstream stmmac related patches. +- net: stmmac: Move MAC caps init to phylink MAC caps getter +- net: stmmac: Rename phylink_get_caps() callback to update_caps() +- net: phylink: provide mac_get_caps() method +- !8450 sched/core: Fix incorrect initialization of the 'burst' parameter in cpu_max_write() +- sched/core: Fix incorrect initialization of the 'burst' parameter in cpu_max_write() +- !7482 v2 perf parse-events: Make legacy events lower priority than sysfs/JSON +- perf x86 test: Update hybrid expectations +- perf parse-events: Make legacy events lower priority than sysfs/JSON +- !8309 xfs: Fix file creation failure +- xfs: Fix file creation failure +- !8183 perf pmu: Count sys and cpuid JSON events separately +- perf pmu: Count sys and cpuid JSON events separately +- !7077 v4 block: dicard bugfix +- block: check io size before submit discard +- block: fix overflow in blk_ioctl_discard() +- !8353 mm/dynamic_pool: clear PG_hugetlb when promote hugepages +- mm/dynamic_pool: clear PG_hugetlb when promote hugepages +- !8151 LoongArch: Fix secondary bridge routing errors +- LoongArch: Fix secondary bridge routing errors +- !7948 【OLK-6.6】Fix BUILD REGRESSION warnings in bzwx N5/N6 series NIC drivers +- drivers: Fix BUILD REGRESSION warnings in bzwx N5/N6 series NIC drivers +- !8228 ubifs: ubifs_link: Fix wrong name len calculating when UBIFS is encrypted +- ubifs: ubifs_link: Fix wrong name len calculating when UBIFS is encrypted +- !6283 fix deadlock in cgroup1_writeback V2 +- cgroup_writeback: fix deadlock in cgroup1_writeback +- cgroup_writeback: Revert "fix deadlock in cgroup1_writeback" +- !8036 fix CVE-2024-27010 +- net/sched: fix kabi change in struct Qdisc +- net/sched: Fix mirred deadlock on device recursion + + to message about demoting connector force-probes +* Thu Jun 13 2024 ZhangPeng - 6.6.0-28.0.0.37 +- Enable kabi check for src and change the check-kabi format to Python3 + +* Thu Jun 6 2024 Mingzheng Xing - 6.6.0-28.0.0.36 +- riscv-kernel patch update to 6.6.0-29.0.0 +- Fix QEMU UEFI boot panic +- Deal with riscv SoC dtb search path + +* Thu Jun 6 2024 ZhangPeng - 6.6.0-28.0.0.35 +- Add kabi_whitelist_aarch64/x86 and update Module.kabi_aarch64/x86 + +* Sun May 26 2024 Mingzheng Xing - 6.6.0-28.0.0.34 +- riscv-kernel patch update to 6.6.0-28.0.0 +- fixed a merge conflict from the commit f1e873348141 + +* Sun May 26 2024 ZhangPeng - 6.6.0-28.0.0.33 +- !8010 mm/mempolicy.c: fix the out-of-bounds access issue in mpol_parse_str +- mm/mempolicy.c: fix the out-of-bounds access issue in mpol_parse_str +- !7997 mm: some misc bugfix +- mm: vmalloc: bail out early in find_vmap_area() if vmap is not init +- Revert "mm: support multi-size THP numa balancing" +- mm: simplify thp_vma_allowable_order +- mm: huge_memory: add the missing folio_test_pmd_mappable() for THP split statistics +- mm/huge_memory: skip invalid debugfs new_order input for folio split +- mm: prohibit the last subpage from reusing the entire large folio +- mm/memory.c: do_numa_page(): remove a redundant page table read +- mm: memory: fix shift-out-of-bounds in fault_around_bytes_set +- !7966 [OLK-6.6] openeuler_defconfig: Modify openeuler-defconfig +- openeuler_defconfig: Modify openeuler-defconfig +- !7909 Scheduler load balance fixes +- config: Disable COBFIG_ARCH_CUSTOM_NUMA_DISTANCE for arm64 +- sched/numa: Fix numa imbalance in load_balance() +- !7917 sched: QOS_SCHED_DYNAMIC_AFFINITY depend on FAIR_GROUP_SCHED +- sched: QOS_SCHED_DYNAMIC_AFFINITY depend on FAIR_GROUP_SCHED +- Revert "sched: QOS_SCHED_DYNAMIC_AFFINITY depend on FAIR_CGROUP_SCHED" +- !7902 v3 Revert "ACPI: Rename ACPI_HOTPLUG_CPU to include 'present'" +- Revert "ACPI: Rename ACPI_HOTPLUG_CPU to include 'present'" +- !7888 v3 mm: add thp anon pmd size mapping align control +- mm: add thp anon pmd size mapping align control +- !7730 v2 sched: QOS_SCHED_DYNAMIC_AFFINITY depend on FAIR_CGROUP_SCHED +- sched: QOS_SCHED_DYNAMIC_AFFINITY depend on FAIR_CGROUP_SCHED +- !7808 Bluetooth: L2CAP: Fix not validating setsockopt user input +- Bluetooth: L2CAP: Fix not validating setsockopt user input +- !7822 LoongArch: limit min pci msi-x/msi vector number when request more than 32 vectors +- LoongArch: limit min pci msi-x/msi vector number when request more than 32 vectors +- !7823 LoongArch: fix kdump not work when legacy mode disabled +- LoongArch: fix efi map page table error +- Revert "LoongArch: kdump: Add memory reservation for old kernel" +- Revert "LoongArch: Fix kdump failure on v40 interface specification" +- Revert "LoongArch: kdump: Add high memory reservation" +- !7764 v2 mm: Some bugfix and optimization +- mm/dynamic_pool: clear PG_hugetlb when demote hugepages +- mm: optimise vmf_anon_prepare() for VMAs without an anon_vma +- mm: delay the check for a NULL anon_vma +- mm: assert the mmap_lock is held in __anon_vma_prepare() +- mm/memory: change vmf_anon_prepare() to be non-static +- mm: always initialise folio->_deferred_list +- mm: page_alloc: control latency caused by zone PCP draining +- mm/hugetlb: fix DEBUG_LOCKS_WARN_ON(1) when dissolve_free_hugetlb_folio() +- hugetlb: check for hugetlb folio before vmemmap_restore +- hugetlb: set hugetlb page flag before optimizing vmemmap +- mm: add alloc_contig_migrate_range allocation statistics +- mm: convert free_zone_device_page to free_zone_device_folio +- mm: combine __folio_put_small, __folio_put_large and __folio_put +- mm: inline destroy_large_folio() into __folio_put_large() +- mm: combine free_the_page() and free_unref_page() +- mm: free non-hugetlb large folios in a batch +- mm: increase folio batch size +- mm: fix list corruption in put_pages_list +- mm: remove folio from deferred split list before uncharging it +- mm: convert free_swap_cache() to take a folio +- mm: use a folio in __collapse_huge_page_copy_succeeded() +- mm: convert free_pages_and_swap_cache() to use folios_put() +- mm: remove lru_to_page() +- mm: remove free_unref_page_list() +- memcg: remove mem_cgroup_uncharge_list() +- mm: free folios directly in move_folios_to_lru() +- mm: free folios in a batch in shrink_folio_list() +- mm: allow non-hugetlb large folios to be batch processed +- mm: handle large folios in free_unref_folios() +- mm: use __page_cache_release() in folios_put() +- mm: use free_unref_folios() in put_pages_list() +- mm: remove use of folio list from folios_put() +- memcg: add mem_cgroup_uncharge_folios() +- mm: use folios_put() in __folio_batch_release() +- mm: add free_unref_folios() +- mm: convert free_unref_page_list() to use folios +- mm: make folios_put() the basis of release_pages() +- !7812 [OLK-6.6] drm/phytium: Replace default efi fb0 with dc fb +- drm/phytium: Replace default efi fb0 with dc fb +- !7767 irqchip/loongson-eiointc: fix gsi register error +- irqchip/loongson-eiointc: fix gsi register error +- !7771 ext4: default enable iomap for buffered IO and large folio +- ext4: default enable iomap for buffered IO and large folio +- !7721 【OLK-6.6】bugfix from upstream v6.9 for AMD EPYC +- x86/CPU/AMD: Add models 0x10-0x1f to the Zen5 range +- x86/CPU/AMD: Do the common init on future Zens too +- !7572 Fix pseudo nmi identifier undeclaration complilation error +- arm64/cpufeature: Fix pseudo nmi identifier undeclaration complilation error +- !7537 [OLK-6.6] irqchip/gic-v3: Fix one race condition due to NMI withdraw +- irqchip/gic-v3: Fix one race condition due to NMI withdraw +- !7164 [sync] PR-7143: media: usbtv: Remove useless locks in usbtv_video_free() +- media: usbtv: Remove useless locks in usbtv_video_free() +- !6386 [OLK-6.6] Fix warnings for RNPVF driver with loongarch-allmodconfig +- RNPVF: NET: Fix "'%d' directive output may be truncated" warnings +- !5243 [OLK-6.6] Support PSP identification for Hygon 4th CPU and print secure features when running on Hygon CPUs +- x86/config: Set CONFIG_HYGON_CSV by default +- x86/cpu/hygon: Clear SME feature flag when not in use +- x86/cpufeatures: Add CSV3 CPU feature +- x86/cpufeatures: Add CPUID_8C86_0000_EDX CPUID leaf +- x86/cpu: Detect memory encryption features on Hygon CPUs +- KVM: SVM: Print Hygon CSV support info if support is detected +- crypto: ccp: Print Hygon CSV API version when CSV support is detected +- x86/mm: Print CSV info into the kernel log +- x86/mm: Provide a Kconfig entry to build the HYGON memory encryption support into the kernel +- Documentation/arch/x86: Add HYGON secure virtualization description +- crypto: ccp: Add support to detect CCP devices on Hygon 4th CPUs +- !7180 【3snic】 use same string “sssnic" for "Kernel driver in use" and "Kernel modules" +- 3snic: use sssnic as kernel driver name +- !7607 Fix allmodconfig build error +- net/ethernet/huawei/hiroce3: Fix allmodconfig build error +- !7583 [OLK-6.6] Fixed display error for ps23xx when using ast and pe2201 bmc card +- drm/ast: Fixed display error for ps23xx when using ast bmc card +- drm/phytium: Bugfix Xorg startup for ps23xx when using pe2201 bmc card +- !7593 memcg_swap_qos: Backport two bugfix +- mm/swapfile: fix infinite loop in get_swap_pages after set memory.swapfile +- memcg: fix incorrect value of sysctl_memcg_swap_qos_stat +- !7595 jbd2: speed up jbd2_transaction_committed() +- jbd2: speed up jbd2_transaction_committed() +- !5480 [OLK-6.6] Fix DMA RW sequence disorder issue +- Add kh40000_iommu_dma_ops for KH-40000 platform +- Add kh40000_direct_dma_ops for KH-40000 platform +- !3133 [OLK-6.6] iommu/vt-d:Add support for detecting ACPI device in RMRR +- iommu/vt-d: Add support for detecting ACPI namespace device in RMRR + +* Fri May 24 2024 Mingzheng Xing - 6.6.0-27.0.0.32 +- Update the riscv-kernel patch for sg2042, rebase 6.6.0-27.0.0 and add features: + - SPI Flash driver + - kexec file raw image + - HIGHMEM +- This patch only applies to the RISC-V architecture, the related commit list: +- +- sg2042: Update sg2042 openeuler_defconfig +- th1520: riscv: config: Enable th1520 support +- riscv: thead: Use the wback_inv instead of wback_only +- riscv: errata: thead: use pa based instructions for CMO +- riscv: errata: thead: use riscv_nonstd_cache_ops for CMO +- Revert "riscv: use VA+PA variant of CMO macros for DMA page preparation" +- Revert "riscv: use VA+PA variant of CMO macros for DMA synchorization" +- Revert "riscv: errata: cmo: add CMO macro variant with both VA and PA" +- Revert "riscv: errata: Replace thead cache clean with flush" +- Revert "riscv: errata: thead: use riscv_nonstd_cache_ops for CMO" +- Revert "riscv: errata: thead: use pa based instructions for CMO" +- riscv: mm: fix NOCACHE_THEAD does not set bit[61] correctly +- riscv: mm: update T-Head memory type definitions +- Revert "sg2042: riscv: changing T-Head PBMT attributes" +- riscv: remove compression for riscv Image +- th1520: cpufreq: correct typo in config name +- th1520: riscv: dts: thead: Add Milk-V Meles board +- th1520: cpufreq: light-mpw-cpufreq: fix -Wunused-variable in panic_cpufreq_notifier_call +- th1520: cpufreq: light-mpw-cpufreq: fix cpu_pll1 already disabled warning +- riscv: Add th1520-lichee-cluster-4a dts support (8G/16G) +- riscv: dts: th1520-beaglev-ahead: add alias for emmc & sd +- riscv: dts: th1520-lichee-pi-4a: add alias for emmc & sd +- riscv: dts: lpi4a 16g support +- th1520: perf vendor events riscv: add T-HEAD C9xx JSON file +- th1520: riscv: dts: thead: Add PMU event node +- riscv: pinctrl: th1520: fix build +- riscv: dts: th1520: lpi4a: add rpmsg node +- riscv: dts: th1520: add mbox client node +- riscv: rpmsg: mailbox-client: sync thead sdk 1.4.2 +- riscv: panic: add thead sdk quirks +- riscv: dts: add watchdog node +- th1520: riscv: dts: Add th1520 reset device tree +- th1520: reset: Add th1520 reset driver support +- th1520: dt-bindings: reset: Document th1520 reset control +- riscv: light_wdt: update sdk 1.4.2 +- th1520_light_event: update sdk 1.4.2 +- th1520_aon: update sdk 1.4.2 +- th1520: fix compile th1520-beaglev-ahead error +- th1520: add TH1520 cpu frequency driver +- th1520: riscv: errata: thead: use pa based instructions for CMO +- th1520: riscv: errata: thead: use riscv_nonstd_cache_ops for CMO +- riscv: dts: thead: Add TH1520 CPU reset node +- th1520: riscv: dts: thead: Enable Lichee Pi 4A USB +- th1520: riscv: dts: thead: Add Lichee Pi 4A IO expansions +- th1520: riscv: dts: thead: Add TH1520 USB nodes +- th1520: riscv: dts: thead: Add TH1520 I2C nodes +- th1520: usb: dwc3: add T-HEAD TH1520 usb driver +- th1520: dt-bindings: usb: Add T-HEAD TH1520 USB controller +- th1520: riscv: dts: thead: Add BeagleV Ahead SDIO0 pins +- th1520: riscv: dts: thead: Add Lichee Pi 4A SDIO0 pins +- th1520: riscv: dts: thead: Add TH1520 ethernet nodes +- th1520: net: stmmac: add glue layer for T-HEAD TH1520 SoC +- th1520: dt-bindings: net: add T-HEAD dwmac support +- th1520: dt-bindings: net: snps,dwmac: allow dwmac-3.70a to set pbl properties +- th1520: riscv: dts: thead: Enable Lichee Pi 4A PWM fan +- th1520: riscv: dts: thead: Add TH1520 PVT node +- th1520: riscv: dts: thead: Add TH1520 PWM node +- th1520: pwm: add T-HEAD PWM driver +- th1520: dt-bindings: pwm: Add T-HEAD PWM controller +- th1520: gpio: dwapb: Use generic request, free and set_config +- riscv: dts: thead: Enable LicheePi 4A eMMC and microSD +- riscv: dts: thead: Enable BeagleV Ahead eMMC and microSD +- riscv: dts: thead: Add TH1520 mmc controllers and sdhci clock +- riscv: defconfig: Enable mmc and dma drivers for T-Head TH1520 +- mmc: sdhci-of-dwcmshc: Add support for T-Head TH1520 +- mmc: sdhci: add __sdhci_execute_tuning() to header +- dt-bindings: mmc: sdhci-of-dwcmhsc: Add T-Head TH1520 support +- th1520: riscv: dtb: thead: Add BeagleV Ahead LEDs +- th1520: riscv: dts: thead: Add TH1520 pinctrl settings for UART0 +- th1520: riscv: dts: thead: Adjust TH1520 GPIO labels +- th1520: riscv: dts: thead: Add TH1520 GPIO ranges +- th1520: riscv: dts: thead: Add TH1520 pin control nodes +- th1520: pinctrl: Add driver for the T-Head TH1520 SoC +- th1520: dt-bindings: pinctrl: Add thead,th1520-pinctrl bindings +- th1520: dt-bindings: gpio: dwapb: allow gpio-ranges +- sg2042: riscv: config: Enable sg2042 support +- sg2042: drivers: rtc: disable BMC RTC device +- sg2042: dts: add i2c-rtc ds1307 device node for single chip +- sg2042: riscv:dts:modify dw gpio clock name +- sg2042: drivers:pci:remove the err log of parsing pci +- sg2042: driver: ipmi: support KVM and IPMI SI for BMC +- sg2042: perf cpumap: Make counter as unsigned ints +- sg2042: driver: radeon: deinit device during kexec +- sg2042: kernel: schedule: Fix set_task_cpu() bug +- sg2042: mm: Modify __find_max_addr for memory hole +- sg2042: riscv: kernel: Optimize apply_relocate_add() +- sg2042: riscv: mm: Clear compilation warning about last_cpupid +- sg2042: kernel: tick: filter unnecessary printing +- sg2042: kernel: Adjust the log level of the tick_switch_to_oneshot function +- sg2042: driver: clk: Modify the timer clock is turned off defaultly +- sg2042: drivers: clock: Add sophgo sg2042 multi-chip clock synchronous support +- Revert "riscv: Fix set_memory_XX() and set_direct_map_XX() by splitting huge linear mappings" +- Revert "riscv: Fix set_direct_map_default_noflush() to reset _PAGE_EXEC" +- Revert "riscv: Fix wrong usage of lm_alias() when splitting a huge linear mapping" +- sg2042: riscv: mm: Add high memory on riscv64 using sv39 +- sg2042: riscv/kexec: handle R_RISCV_ADD16 and R_RISCV_SUB16 relocation types +- sg2042: riscv: kexec: Add image loader for kexec file +- sg2042: drm/amd/display: Support DRM_AMD_DC_FP on RISC-V +- sg2042: riscv: Factor out riscv-march-y to a separate Makefile +- sg2042: riscv: Add support for kernel-mode FPU +- sg2042: mango pci hack:broadcast when no MSI source known +- sg2042: nvidia hda: force msi +- sg2042: radeon hack: force 64-bit msi to fit top intc +- sg2042: amdgpu: disable rebar +- sg2042: ttm: disallow cached mapping +- sg2042: driver: soc: Add sophgo sg2042 soc support +- sg2042: drivers: pcie: Create msi-x whitelist,turn on msi-x for top intr +- sg2042: driver: pcie: Add sophgo sg2042 soc support +- sg2042: driver: net: Add sophgo sg2042 soc support +- sg2042: driver: mtd: Add sophgo sg2042 soc support +- sg2042: driver: mmc: Add sophgo sg2042 soc support +- sg2042: driver: reset: Add sophgo sg2042 soc support +- sg2042: driver: pinctrl: Add sophgo sg2042 soc support +- sg2042: driver: clk: Add sophgo sg2042 soc support +- sg2042: riscv: spinlock: Fix deadlock issue +- sg2042: riscv: add smp_cond_load_acquire() +- sg2042: riscv: add ioremap_wc for gpu +- sg2042: riscv: changing T-Head PBMT attributes +- sg2042: riscv: errata: thead: Make cache clean to flush +- sg2042: riscv: use VA+PA variant of CMO macros for DMA page preparation +- sg2042: riscv: use VA+PA variant of CMO macros for DMA synchorization +- sg2042: riscv: errata: cmo: add CMO macro variant with both VA and PA +- sg2042: riscv: errata: Replace thead cache clean with flush +- sg2042: riscv: Kconfig: Set vector as default no +- sg2042: riscv: Add sophgo sg2042 soc support + * Sat May 18 2024 ZhangPeng - 6.6.0-27.0.0.31 - !7527 ext4 iomap performance optimize - ext4: fallback to generic_perform_write once iov_iter_count <= PAGE_SIZE -- Gitee From 7431e040983472bc6a529a70c13d5d1c80249dab Mon Sep 17 00:00:00 2001 From: ZhangPeng Date: Fri, 8 Nov 2024 12:05:49 +0800 Subject: [PATCH 2/8] release 6.6.0-52.0.0 --- SOURCE | 2 +- kernel.spec | 347 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 346 insertions(+), 3 deletions(-) diff --git a/SOURCE b/SOURCE index 643d873..5b1e203 100644 --- a/SOURCE +++ b/SOURCE @@ -1 +1 @@ -6.6.0-50.0.0 +6.6.0-52.0.0 diff --git a/kernel.spec b/kernel.spec index 8297959..45c1889 100644 --- a/kernel.spec +++ b/kernel.spec @@ -40,9 +40,9 @@ rm -f test_openEuler_sign.ko test_openEuler_sign.ko.sig %global upstream_version 6.6 %global upstream_sublevel 0 -%global devel_release 50 +%global devel_release 52 %global maintenance_release .0.0 -%global pkg_release .55 +%global pkg_release .56 %global openeuler_lts 1 %global openeuler_major 2403 @@ -1085,6 +1085,349 @@ fi %endif %changelog +* Fri Nov 08 2024 ZhangPeng - 6.6.0-52.0.0.56 +- !13117 nebula-matrix: fix ci build err +- Net: nebula_matrix: fix ci build err +- !12280 fix Hygon TKM may execute fail in CSV VM +- drivers/crypto/ccp: fix the increase in page references caused by gfn_to_pfn +- crypto: ccp: fix the sev_do_cmd panic on non-Hygon platforms +- !13108 nfsd: cancel nfsd_shrinker_work using sync mode in nfs4_state_shutdown_net +- nfsd: cancel nfsd_shrinker_work using sync mode in nfs4_state_shutdown_net +- !13109 RDMA/hns: Fix DCA mmap area PUAF +- RDMA/hns: Fix DCA mmap area PUAF +- !12848 Bluetooth: ISO: Fix multiple init when debugfs is disabled +- Bluetooth: ISO: Fix multiple init when debugfs is disabled +- !13112 fix CVE-2024-49926 +- rcu-tasks: Fix access non-existent percpu rtpcp variable in rcu_tasks_need_gpcb() +- rcu-tasks: Initialize data to eliminate RCU-tasks/do_exit() deadlocks +- rcu-tasks: Add data to eliminate RCU-tasks/do_exit() deadlocks +- rcu-tasks: Pull sampling of ->percpu_dequeue_lim out of loop +- !13087 MPTCP Upstream part 18 +- selftests: mptcp: add mptcp_lib_check_output helper +- selftests: mptcp: add token for dump_addr +- selftests: mptcp: add userspace pm subflow flag +- mptcp: check userspace pm flags +- !13086 MPTCP Upstream part 17 +- mptcp: dump addrs in userspace pm list +- mptcp: add token for get-addr in yaml +- mptcp: implement mptcp_userspace_pm_dump_addr +- mptcp: export mptcp_genl_family & mptcp_nl_fill_addr +- mptcp: implement TCP_NOTSENT_LOWAT support +- mptcp: cleanup writer wake-up +- !13084 ksmbd: add refcnt to ksmbd_conn struct +- ksmbd: add refcnt to ksmbd_conn struct +- !12943 bpf: Fix a sdiv overflow issue +- bpf: Fix a sdiv overflow issue +- !13088 drm/amd/display: Fix index out of bounds in degamma hardware format translation +- drm/amd/display: Fix index out of bounds in degamma hardware format translation +- !13081 sched/fair: Take the scheduling domain into account in select_idle_smt() +- sched/fair: Take the scheduling domain into account in select_idle_smt() +- !13066 Fix UAF of rpc_task +- nfs: fix rpc_task use-after-free when open and close different files concurrently +- NFSv4: release seqid when open failed for nfs4.0 +- !13069 NFSD: Mark filecache "down" if init fails +- NFSD: Mark filecache "down" if init fails +- !13077 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.54-6.6.55 LTS Patches +- perf python: Allow checking for the existence of warning options in clang +- Revert "ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path" +- perf report: Fix segfault when 'sym' sort key is not used +- drm/amd/display: Revert Avoid overflow assignment +- crypto: octeontx* - Select CRYPTO_AUTHENC +- vhost/scsi: null-ptr-dereference in vhost_scsi_get_req() +- rxrpc: Fix a race between socket set up and I/O thread creation +- platform/x86: think-lmi: Fix password opcode ordering for workstations +- drm/bridge: adv7511: fix crash on irq during probe +- net: dsa: fix netdev_priv() dereference before check on non-DSA netdevice events +- netfilter: nf_tables: restore set elements when delete set fails +- netfilter: nf_tables: fix memleak in map from abort path +- ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path +- Revert "drm/amd/display: Skip Recompute DSC Params if no Stream on Link" +- drm/rockchip: vop: enable VOP_FEATURE_INTERNAL_RGB on RK3066 +- btrfs: drop the backref cache during relocation if we commit +- btrfs: relocation: constify parameters where possible +- btrfs: relocation: return bool from btrfs_should_ignore_reloc_root +- clk: qcom: gcc-sc8180x: Add GPLL9 support +- iio: pressure: bmp280: Fix waiting time for BMP3xx configuration +- iio: pressure: bmp280: Fix regmap for BMP280 device +- iio: pressure: bmp280: Use BME prefix for BME280 specifics +- iio: pressure: bmp280: Improve indentation and line wrapping +- iio: pressure: bmp280: Allow multiple chips id per family of devices +- dt-bindings: clock: qcom: Add GPLL9 support on gcc-sc8180x +- dt-bindings: clock: qcom: Add missing UFS QREF clocks +- remoteproc: k3-r5: Delay notification of wakeup event +- remoteproc: k3-r5: Acquire mailbox handle during probe routine +- media: imx335: Fix reset-gpio handling +- media: i2c: imx335: Enable regulator supplies +- RDMA/mana_ib: use the correct page table index based on hardware page size +- net: mana: Add support for page sizes other than 4KB on ARM64 +- net: mana: Enable MANA driver on ARM64 with 4K page size +- lib/buildid: harden build ID parsing logic +- build-id: require program headers to be right after ELF header +- drm/amd/display: Allow backlight to go below `AMDGPU_DM_DEFAULT_MIN_BACKLIGHT` +- io_uring/net: harden multishot termination case for recv +- arm64: cputype: Add Neoverse-N3 definitions +- platform/x86: x86-android-tablets: Fix use after free on platform_device_register() errors +- platform/x86: x86-android-tablets: Create a platform_device from module_init() +- kconfig: qconf: fix buffer overflow in debug links +- cpufreq: intel_pstate: Make hwp_notify_lock a raw spinlock +- drm/amd/display: Add HDR workaround for specific eDP +- drm/sched: Add locking to drm_sched_entity_modify_sched +- drm/i915/gem: fix bitwise and logical AND mixup +- close_range(): fix the logics in descriptor table trimming +- rtla: Fix the help text in osnoise and timerlat top tools +- tracing/timerlat: Fix duplicated kthread creation due to CPU online/offline +- tracing/hwlat: Fix a race during cpuhp processing +- ceph: fix cap ref leak via netfs init_request +- mac802154: Fix potential RCU dereference issue in mac802154_scan_worker +- Bluetooth: hci_event: Align BR/EDR JUST_WORKS paring with LE +- net: pcs: xpcs: fix the wrong register that was written back +- gpio: davinci: fix lazy disable +- btrfs: send: fix invalid clone operation for file that got its size decreased +- ACPI: resource: Add Asus ExpertBook B2502CVA to irq1_level_low_skip_override[] +- ACPI: resource: Add Asus Vivobook X1704VAP to irq1_level_low_skip_override[] +- Input: adp5589-keys - fix adp5589_gpio_get_value() +- rtc: at91sam9: fix OF node leak in probe() error path +- net: stmmac: Fix zero-division error when disabling tc cbs +- tomoyo: fallback to realpath if symlink's pathname does not exist +- vrf: revert "vrf: Remove unnecessary RCU-bh critical section" +- iio: magnetometer: ak8975: Fix reading for ak099xx sensors +- smb3: fix incorrect mode displayed for read-only files +- smb: client: use actual path when queryfs +- clk: qcom: clk-alpha-pll: Fix CAL_L_VAL override for LUCID EVO PLL +- clk: qcom: gcc-sc8180x: Fix the sdcc2 and sdcc4 clocks freq table +- media: qcom: camss: Fix ordering of pm_runtime_enable +- media: qcom: camss: Remove use_count guard in stop_streaming +- clk: qcom: gcc-sm8250: Do not turn off PCIe GDSCs during gdsc_disable() +- clk: qcom: gcc-sm8150: De-register gcc_cpuss_ahb_clk_src +- clk: samsung: exynos7885: Update CLKS_NR_FSYS after bindings fix +- clk: qcom: clk-rpmh: Fix overflow in BCM vote +- media: uapi/linux/cec.h: cec_msg_set_reply_to: zero flags +- clk: qcom: gcc-sm8450: Do not turn off PCIe GDSCs during gdsc_disable() +- media: sun4i_csi: Implement link validate for sun4i_csi subdev +- clk: qcom: dispcc-sm8250: use CLK_SET_RATE_PARENT for branch clocks +- remoteproc: k3-r5: Fix error handling when power-up failed +- clk: rockchip: fix error for unknown clocks +- media: ov5675: Fix power on/off delay timings +- aoe: fix the potential use-after-free problem in more places +- riscv: Fix kernel stack size when KASAN is enabled +- RDMA/mana_ib: use the correct page size for mapping user-mode doorbell page +- NFSD: Fix NFSv4's PUTPUBFH operation +- nfsd: fix delegation_blocked() to block correctly for at least 30 seconds +- perf hist: Update hist symbol when updating maps +- perf python: Disable -Wno-cast-function-type-mismatch if present on clang +- riscv: define ILLEGAL_POINTER_VALUE for 64bit +- arm64: fix selection of HAVE_DYNAMIC_FTRACE_WITH_ARGS +- ocfs2: fix null-ptr-deref when journal load failed. +- ocfs2: fix uninit-value in ocfs2_get_block() +- ocfs2: fix the la space leak when unmounting an ocfs2 volume +- mm: krealloc: consider spare memory for __GFP_ZERO +- jbd2: correctly compare tids with tid_geq function in jbd2_fc_begin_commit +- resource: fix region_intersects() vs add_memory_driver_managed() +- of/irq: Support #msi-cells=<0> in of_msi_get_domain +- of: address: Report error on resource bounds overflow +- drm/rockchip: vop: clear DMA stop bit on RK3066 +- parisc: Fix stack start for ADDR_NO_RANDOMIZE personality +- parisc: Allow mmap(MAP_STACK) memory to automatically expand upwards +- parisc: Fix 64-bit userspace syscall path +- ext4: mark fc as ineligible using an handle in ext4_xattr_set() +- ext4: use handle to mark fc as ineligible in __track_dentry_update() +- ext4: fix fast commit inode enqueueing during a full journal commit +- ext4: fix incorrect tid assumption in jbd2_journal_shrink_checkpoint_list() +- ext4: fix incorrect tid assumption in ext4_wait_for_tail_page_commit() +- ext4: fix incorrect tid assumption in __jbd2_log_wait_for_space() +- ext4: fix incorrect tid assumption in ext4_fc_mark_ineligible() +- ext4: propagate errors from ext4_find_extent() in ext4_insert_range() +- ext4: correct encrypted dentry name hash when not casefolded +- ALSA: hda/realtek: Add a quirk for HP Pavilion 15z-ec200 +- ALSA: hda/realtek: Add quirk for Huawei MateBook 13 KLV-WX9 +- ALSA: line6: add hw monitor volume control to POD HD500X +- ALSA: usb-audio: Add native DSD support for Luxman D-08u +- ALSA: usb-audio: Add delay quirk for VIVO USB-C HEADSET +- ALSA: core: add isascii() check to card ID generator +- ALSA: hda/tas2781: Add new quirk for Lenovo Y990 Laptop +- drm: Consistently use struct drm_mode_rect for FB_DAMAGE_CLIPS +- drm/mediatek: ovl_adaptor: Add missing of_node_put() +- parisc: Fix itlb miss handler for 64-bit programs +- perf/core: Fix small negative period being ignored +- power: supply: hwmon: Fix missing temp1_max_alarm attribute +- spi: bcm63xx: Fix missing pm_runtime_disable() +- spi: bcm63xx: Fix module autoloading +- dt-bindings: clock: exynos7885: Fix duplicated binding +- memory: tegra186-emc: drop unused to_tegra186_emc() +- firmware: tegra: bpmp: Drop unused mbox_client_to_bpmp() +- ovl: fail if trusted xattrs are needed but caller lacks permission +- rust: sync: require `T: Sync` for `LockedBy::access` +- i2c: designware: fix controller is holding SCL low while ENABLE bit is disabled +- i2c: xiic: Fix pm_runtime_set_suspended() with runtime pm enabled +- i2c: xiic: Wait for TX empty to avoid missed TX NAKs +- i2c: qcom-geni: Use IRQF_NO_AUTOEN flag in request_irq() +- Revert "ALSA: hda: Conditionally use snooping for AMD HDMI" +- selftests: vDSO: fix vdso_config for s390 +- selftests: vDSO: fix ELF hash table entry size for s390x +- powerpc/vdso: Fix VDSO data access when running in a non-root time namespace +- selftests/mm: fix charge_reserved_hugetlb.sh test +- selftests: vDSO: fix vDSO symbols lookup for powerpc64 +- selftests: vDSO: fix vdso_config for powerpc +- selftests: vDSO: fix vDSO name for powerpc +- perf: Really fix event_function_call() locking +- perf callchain: Fix stitch LBR memory leaks +- spi: rpc-if: Add missing MODULE_DEVICE_TABLE +- accel/ivpu: Add missing MODULE_FIRMWARE metadata +- selftests: breakpoints: use remaining time to check if suspend succeed +- spi: s3c64xx: fix timeout counters in flush_fifo +- selftest: hid: add missing run-hid-tools-tests.sh +- spi: spi-cadence: Fix missing spi_controller_is_target() check +- spi: spi-cadence: Fix pm_runtime_set_suspended() with runtime pm enabled +- spi: spi-cadence: Use helper function devm_clk_get_enabled() +- spi: spi-imx: Fix pm_runtime_set_suspended() with runtime pm enabled +- bpftool: Fix undefined behavior in qsort(NULL, 0, ...) +- bpftool: Fix undefined behavior caused by shifting into the sign bit +- bpf: Make the pointer returned by iter next method valid +- ksmbd: add refcnt to ksmbd_conn struct +- platform/x86: lenovo-ymc: Ignore the 0x0 state +- drm/amdgpu/gfx10: use rlc safe mode for soft recovery +- drm/amdgpu/gfx11: use rlc safe mode for soft recovery +- powerpc/pseries: Use correct data types from pseries_hp_errorlog struct +- of/irq: Refer to actual buffer size in of_irq_parse_one() +- drm/amd/pm: ensure the fw_info is not null before using it +- drm/amdgpu/gfx9: use rlc safe mode for soft recovery +- drm/amdgpu: Block MMR_READ IOCTL in reset +- drm/radeon/r100: Handle unknown family in r100_cp_init_microcode() +- scsi: NCR5380: Initialize buffer for MSG IN and STATUS transfers +- perf: Fix event_function_call() locking +- drm/amdgpu: fix unchecked return value warning for amdgpu_gfx +- scsi: lpfc: Update PRLO handling in direct attached topology +- drm/printer: Allow NULL data in devcoredump printer +- drm/amd/display: Fix index out of bounds in degamma hardware format translation +- drm/stm: ltdc: reset plane transparency after plane disable +- platform/x86: touchscreen_dmi: add nanote-next quirk +- HID: multitouch: Add support for Thinkpad X12 Gen 2 Kbd Portfolio +- drm/amdkfd: Fix resource leak in criu restore queue +- drm/amdgpu: enable gfxoff quirk on HP 705G4 +- drm/amdgpu: add raven1 gfxoff quirk +- scsi: smartpqi: correct stream detection +- jfs: UBSAN: shift-out-of-bounds in dbFindBits +- drm/amd/display: Add null check for 'afb' in amdgpu_dm_plane_handle_cursor_update (v2) +- drm/amd/display: Check null pointers before using dc->clk_mgr +- drm/amdgpu: disallow multiple BO_HANDLES chunks in one submit +- iommu/vt-d: Fix potential lockup if qi_submit_sync called with 0 count +- iommu/vt-d: Always reserve a domain ID for identity setup +- power: reset: brcmstb: Do not go into infinite loop if reset fails +- rcuscale: Provide clear error when async specified without primitives +- fbdev: efifb: Register sysfs groups through driver core +- hwmon: (nct6775) add G15CF to ASUS WMI monitoring list +- x86/syscall: Avoid memcpy() for ia32 syscall_get_arguments() +- selftests/nolibc: avoid passing NULL to printf("%s") +- tools/nolibc: powerpc: limit stack-protector workaround to GCC +- ALSA: hdsp: Break infinite MIDI input flush loop +- x86/kexec: Add EFI config table identity mapping for kexec kernel +- x86/pkeys: Restore altstack access in sigreturn() +- x86/pkeys: Add PKRU as a parameter in signal handling functions +- tools/x86/kcpuid: Protect against faulty "max subleaf" values +- ASoC: codecs: wsa883x: Handle reading version failure +- ALSA: usb-audio: Add logitech Audio profile quirk +- ALSA: usb-audio: Replace complex quirk lines with macros +- ALSA: usb-audio: Define macros for quirk table entries +- ALSA: usb-audio: Add input value sanity checks for standard types +- nfp: Use IRQF_NO_AUTOEN flag in request_irq() +- wifi: mt76: mt7915: hold dev->mt76.mutex while disabling tx worker +- wifi: mt76: mt7915: add dummy HW offload of IEEE 802.11 fragmentation +- can: netlink: avoid call to do_set_data_bittiming callback with stale can_priv::ctrlmode +- drivers/perf: arm_spe: Use perf_allow_kernel() for permissions +- ACPICA: iasl: handle empty connection_node +- wifi: mac80211: fix RCU list iterations +- wifi: iwlwifi: mvm: avoid NULL pointer dereference +- wifi: iwlwifi: mvm: use correct key iteration +- tcp: avoid reusing FIN_WAIT2 when trying to find port in connect() process +- netpoll: Ensure clean state on setup failures +- crypto: simd - Do not call crypto_alloc_tfm during registration +- net: atlantic: Avoid warning about potential string truncation +- ipv4: Mask upper DSCP bits and ECN bits in NETLINK_FIB_LOOKUP family +- wifi: rtw89: correct base HT rate mask for firmware +- ipv4: Check !in_dev earlier for ioctl(SIOCSIFADDR). +- bnxt_en: Extend maximum length of version string by 1 byte +- net: mvpp2: Increase size of queue_name buffer +- ACPICA: check null return of ACPI_ALLOCATE_ZEROED() in acpi_db_convert_to_package() +- ACPI: EC: Do not release locks during operation region accesses +- wifi: rtw88: select WANT_DEV_COREDUMP +- wifi: ath11k: fix array out-of-bound access in SoC stats +- ACPI: CPPC: Add support for setting EPP register in FFH +- ACPI: video: Add force_vendor quirk for Panasonic Toughbook CF-18 +- Bluetooth: btrtl: Set msft ext address filter quirk for RTL8852B +- Bluetooth: btusb: Add Realtek RTL8852C support ID 0x0489:0xe122 +- net: sched: consistently use rcu_replace_pointer() in taprio_change() +- wifi: mt76: mt7915: disable tx worker during tx BA session enable/disable +- e1000e: avoid failing the system during pm_suspend +- ACPICA: Fix memory leak if acpi_ps_get_next_field() fails +- ACPICA: Fix memory leak if acpi_ps_get_next_namepath() fails +- ACPI: PAD: fix crash in exit_round_robin() +- net: hisilicon: hns_mdio: fix OF node leak in probe() +- net: hisilicon: hns_dsaf_mac: fix OF node leak in hns_mac_get_info() +- net: hisilicon: hip04: fix OF node leak in probe() +- wifi: iwlwifi: mvm: drop wrong STA selection in TX +- wifi: iwlwifi: mvm: Fix a race in scan abort flow +- ice: Adjust over allocation of memory in ice_sched_add_root_node() and ice_sched_add_node() +- crypto: octeontx2 - Fix authenc setkey +- crypto: octeontx - Fix authenc setkey +- crypto: x86/sha256 - Add parentheses around macros' single arguments +- wifi: ath9k_htc: Use __skb_set_length() for resetting urb before resubmit +- wifi: rtw89: avoid to add interface to list twice when SER +- wifi: ath9k: fix possible integer overflow in ath9k_get_et_stats() +- ALSA: hda/conexant: Fix conflicting quirk for System76 Pangolin +- ALSA: gus: Fix some error handling paths related to get_bpos() usage +- cifs: Do not convert delimiter when parsing NFS-style symlinks +- ASoC: imx-card: Set card.owner to avoid a warning calltrace if SND=m +- ALSA: hda/generic: Unconditionally prefer preferred_dacs pairs +- cifs: Remove intermediate object of failed create reparse call +- ALSA: hda/realtek: Fix the push button function for the ALC257 +- ALSA: mixer_oss: Remove some incorrect kfree_const() usages +- ASoC: atmel: mchp-pdmc: Skip ALSA restoration if substream runtime is uninitialized +- Bluetooth: hci_sock: Fix not validating setsockopt user input +- loop: don't set QUEUE_FLAG_NOMERGES +- i2c: xiic: Try re-initialization on bus busy timeout +- i2c: xiic: improve error message when transfer fails to start +- sctp: set sk_state back to CLOSED if autobind fails in sctp_listen_start +- dt-bindings: net: xlnx,axi-ethernet: Add missing reg minItems +- iomap: constrain the file range passed to iomap_file_unshare +- ppp: do not assume bh is held in ppp_channel_bridge_input() +- ipv4: ip_gre: Fix drops of small packets in ipgre_xmit +- net: stmmac: dwmac4: extend timeout for VLAN Tag register busy bit check +- net: fec: Reload PTP registers after link-state change +- net: fec: Restart PPS after link state change +- net: ethernet: lantiq_etop: fix memory disclosure +- net: Fix gso_features_check to check for both dev->gso_{ipv4_,}max_size +- net: Add netif_get_gro_max_size helper for GRO +- Bluetooth: btmrvl: Use IRQF_NO_AUTOEN flag in request_irq() +- Bluetooth: L2CAP: Fix uaf in l2cap_connect +- Bluetooth: MGMT: Fix possible crash on mgmt_index_removed +- netfilter: nf_tables: prevent nf_skb_duplicated corruption +- selftests: netfilter: Fix nft_audit.sh for newer nft binaries +- net: wwan: qcom_bam_dmux: Fix missing pm_runtime_disable() +- net: ieee802154: mcr20a: Use IRQF_NO_AUTOEN flag in request_irq() +- netfilter: uapi: NFTA_FLOWTABLE_HOOK is NLA_NESTED +- net/mlx5e: Fix crash caused by calling __xfrm_state_delete() twice +- net/mlx5: Added cond_resched() to crdump collection +- net/mlx5: Fix error path in multi-packet WQE transmit +- net: sparx5: Fix invalid timestamps +- ieee802154: Fix build error +- ceph: remove the incorrect Fw reference check when dirtying pages +- mailbox: bcm2835: Fix timeout during suspend mode +- mailbox: rockchip: fix a typo in module autoloading +- drm/amdgpu: Fix get each xcp macro +- scsi: pm8001: Do not overwrite PCI queue mapping +- scsi: st: Fix input/output error on empty drive reset +- jump_label: Fix static_key_slow_dec() yet again +- jump_label: Simplify and clarify static_key_fast_inc_cpus_locked() +- static_call: Handle module init failure correctly in static_call_del_module() +- !13043 tty: n_gsm: Fix use-after-free in gsm_cleanup_mux +- tty: n_gsm: Fix use-after-free in gsm_cleanup_mux +- !13062 net: test for not too small csum_start in virtio_net_hdr_to_skb() +- net: test for not too small csum_start in virtio_net_hdr_to_skb() +- !13060 net: add more sanity checks to qdisc_pkt_len_init() +- net: add more sanity checks to qdisc_pkt_len_init() +- !13061 net: avoid potential underflow in qdisc_pkt_len_init() with UFO +- net: avoid potential underflow in qdisc_pkt_len_init() with UFO + * Wed Nov 06 2024 ZhangPeng - 6.6.0-50.0.0.55 - !12979 ext4: fix timer use-after-free on failed mount - ext4: fix timer use-after-free on failed mount -- Gitee From 68c0a6db750df5a190dccf0d06cf6be81c547b16 Mon Sep 17 00:00:00 2001 From: ZhangPeng Date: Wed, 13 Nov 2024 11:34:53 +0800 Subject: [PATCH 3/8] release 6.6.0-54.0.0 --- SOURCE | 2 +- kernel.spec | 353 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 352 insertions(+), 3 deletions(-) diff --git a/SOURCE b/SOURCE index 5b1e203..355c86d 100644 --- a/SOURCE +++ b/SOURCE @@ -1 +1 @@ -6.6.0-52.0.0 +6.6.0-54.0.0 diff --git a/kernel.spec b/kernel.spec index 45c1889..86f0c4d 100644 --- a/kernel.spec +++ b/kernel.spec @@ -40,9 +40,9 @@ rm -f test_openEuler_sign.ko test_openEuler_sign.ko.sig %global upstream_version 6.6 %global upstream_sublevel 0 -%global devel_release 52 +%global devel_release 54 %global maintenance_release .0.0 -%global pkg_release .56 +%global pkg_release .57 %global openeuler_lts 1 %global openeuler_major 2403 @@ -1085,6 +1085,355 @@ fi %endif %changelog +* Wed Nov 13 2024 ZhangPeng - 6.6.0-54.0.0.57 +- !12859 intel: backport GNR and SRF intel_idle fix for 6.6 +- intel_idle: fix ACPI _CST matching for newer Xeon platforms +- intel_idle: add Granite Rapids Xeon support +- !13172 sched: smart_grid: Prevent double-free in sched_grid_qos_free +- sched: smart_grid: Prevent double-free in sched_grid_qos_free +- !13181 drm/msm: Avoid NULL dereference in msm_disp_state_print_regs() +- drm/msm: Avoid NULL dereference in msm_disp_state_print_regs() +- !13161 Some patches of RDMA from Linux to olk-6.6 +- RDMA/hns: Fix NULL pointer derefernce in hns_roce_map_mr_sg() +- RDMA/hns: Fix out-of-order issue of requester when setting FENCE +- !13133 CVE-2024-50145 +- octeon_ep: Add SKB allocation failures handling in __octep_oq_process_rx() +- octeon_ep: Implement helper for iterating packets in Rx queue +- !13142 tracing: Consider the NULL character when validating the event length +- tracing: Consider the NULL character when validating the event length +- !13137 drm/amd/display: Check null pointers before multiple uses +- drm/amd/display: Check null pointers before multiple uses +- !13120 smb: client: fix possible double free in smb2_set_ea() +- smb: client: fix possible double free in smb2_set_ea() +- !13096 Update ASPM sysfs on MFD function removal to avoid use-after-free +- PCI/ASPM: Update ASPM sysfs on MFD function removal to avoid use-after-free +- !12877 Revert "LoongArch: Add workaround for 3C6000 about io wr/rd" +- Revert "LoongArch: Add workaround for 3C6000 about io wr/rd" +- !12886 LoongArch: disable cpufreq driver +- LoongArch: disable cpufreq driver +- cpufreq: loongson3-acpi: Initialize scaling_cur_freq correctly +- !12840 drm/loongson: use old version of ast driver for LoongArch platform +- drm/loongson: use old version of ast driver for LoongArch platform +- !12496 LoongArch: add loongson SE support +- LoongArch: add loongson SE SDF support +- dt-bindings: security: add loongson_se +- !12492 LoongArch: Add AVEC irqchip support +- LoongArch: Add AVEC irqchip support +- !13111 MPTCP Upstream part 20 +- mptcp: drop lookup_by_id in lookup_addr +- mptcp: set error messages for set_flags +- mptcp: update set_flags interfaces +- mptcp: drop duplicate header inclusions +- !13110 MPTCP Upstream part 19 +- selftests: mptcp: add token for get_addr +- mptcp: get addr in userspace pm list +- mptcp: implement mptcp_userspace_pm_get_addr +- mptcp: add userspace_pm_lookup_addr_by_id helper +- !13115 smb: client: Handle kstrdup failures for passwords +- smb: client: Handle kstrdup failures for passwords +- !13130 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.57-6.6.58 LTS Patches +- ALSA: hda/conexant - Use cached pin control for Node 0x1d on HP EliteOne 1000 G2 +- nilfs2: propagate directory read errors from nilfs_find_entry() +- serial: qcom-geni: fix receiver enable +- serial: qcom-geni: fix dma rx cancellation +- serial: qcom-geni: revert broken hibernation support +- serial: qcom-geni: fix polled console initialisation +- irqchip/sifive-plic: Unmask interrupt in plic_irq_enable() +- pinctrl: apple: check devm_kasprintf() returned value +- pinctrl: ocelot: fix system hang on level based interrupts +- x86/entry_32: Clear CPU buffers after register restore in NMI return +- x86/entry_32: Do not clobber user EFLAGS.ZF +- x86/CPU/AMD: Only apply Zenbleed fix for Zen2 during late microcode load +- x86/apic: Always explicitly disarm TSC-deadline timer +- x86/resctrl: Annotate get_mem_config() functions as __init +- serial: imx: Update mctrl old_status on RTSD interrupt +- misc: microchip: pci1xxxx: add support for NVMEM_DEVID_AUTO for OTP device +- misc: microchip: pci1xxxx: add support for NVMEM_DEVID_AUTO for EEPROM device +- usb: dwc3: Wait for EndXfer completion before restoring GUSB2PHYCFG +- usb: typec: qcom-pmic-typec: fix sink status being overwritten with RP_DEF +- USB: serial: option: add Telit FN920C04 MBIM compositions +- USB: serial: option: add support for Quectel EG916Q-GL +- xhci: Mitigate failed set dequeue pointer commands +- xhci: Fix incorrect stream context type macro +- xhci: tegra: fix checked USB2 port number +- Bluetooth: btusb: Fix regression with fake CSR controllers 0a12:0001 +- Bluetooth: Remove debugfs directory on module init failure +- Bluetooth: Call iso_exit() on module unload +- iio: accel: kx022a: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig +- iio: adc: ti-ads124s08: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig +- iio: adc: ti-lmp92064: add missing select REGMAP_SPI in Kconfig +- iio: dac: ad3552r: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig +- iio: proximity: mb1232: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig +- iio: dac: ad5766: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig +- iio: light: bu27008: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig +- iio: frequency: adf4377: add missing select REMAP_SPI in Kconfig +- iio: amplifiers: ada4250: add missing select REGMAP_SPI in Kconfig +- iio: light: opt3001: add missing full-scale range value +- iio: light: veml6030: fix IIO device retrieval from embedded device +- iio: light: veml6030: fix ALS sensor resolution +- iio: hid-sensors: Fix an error handling path in _hid_sensor_set_report_latency() +- iio: adc: ti-ads8688: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig +- iio: dac: stm32-dac-core: add missing select REGMAP_MMIO in Kconfig +- iio: dac: ltc1660: add missing select REGMAP_SPI in Kconfig +- iio: dac: ad5770r: add missing select REGMAP_SPI in Kconfig +- drm/amdgpu: prevent BO_HANDLES error from being overwritten +- drm/amdgpu/swsmu: Only force workload setup on init +- drm/vmwgfx: Handle surface check failure correctly +- drm/radeon: Fix encoder->possible_clones +- scsi: ufs: core: Fix the issue of ICU failure +- scsi: ufs: core: Set SDEV_OFFLINE when UFS is shut down +- Input: xpad - add support for MSI Claw A1M +- selftest: hid: add the missing tests directory +- ublk: don't allow user copy for unprivileged device +- io_uring/sqpoll: close race on waiting for sqring entries +- x86/bugs: Do not use UNTRAIN_RET with IBPB on entry +- x86/bugs: Skip RSB fill at VMEXIT +- x86/entry: Have entry_ibpb() invalidate return predictions +- x86/cpufeatures: Add a IBPB_NO_RET BUG flag +- x86/cpufeatures: Define X86_FEATURE_AMD_IBPB_RET +- KVM: s390: Change virtual to physical address access in diag 0x258 handler +- KVM: s390: gaccess: Check if guest address is in memslot +- s390/sclp_vt220: Convert newlines to CRLF instead of LFCR +- s390/sclp: Deactivate sclp after all its users +- iommu/vt-d: Fix incorrect pci_for_each_dma_alias() for non-PCI devices +- mptcp: prevent MPC handshake on port-based signal endpoints +- net: fec: Remove duplicated code +- net: fec: Move `fec_ptp_read()` to the top of the file +- xfs: restrict when we try to align cow fork delalloc to cowextsz hints +- xfs: allow unlinked symlinks and dirs with zero size +- xfs: fix freeing speculative preallocations for preallocated files +- xfs: make sure sb_fdblocks is non-negative +- xfs: allow symlinks with short remote targets +- xfs: use dontcache for grabbing inodes during scrub +- xfs: revert commit 44af6c7e59b12 +- xfs: enforce one namespace per attribute +- xfs: validate recovered name buffers when recovering xattr items +- xfs: check shortform attr entry flags specifically +- xfs: fix missing check for invalid attr flags +- xfs: check opcode and iovec count match in xlog_recover_attri_commit_pass2 +- xfs: require XFS_SB_FEAT_INCOMPAT_LOG_XATTRS for attr log intent item recovery +- xfs: remove a racy if_bytes check in xfs_reflink_end_cow_extent +- xfs: fix xfs_bmap_add_extent_delay_real for partial conversions +- xfs: fix error returns from xfs_bmapi_write +- mm/mglru: only clear kswapd_failures if reclaimable +- selftests/mm: fix deadlock for fork after pthread_create on ARM +- selftests/mm: replace atomic_bool with pthread_barrier_t +- fat: fix uninitialized variable +- net: macb: Avoid 20s boot delay by skipping MDIO bus registration for fixed-link PHY +- arm64: probes: Fix uprobes for big-endian kernels +- arm64: probes: Fix simulate_ldr*_literal() +- arm64: probes: Remove broken LDR (literal) uprobe support +- posix-clock: Fix missing timespec64 check in pc_clock_settime() +- net: enetc: add missing static descriptor and inline keyword +- net: enetc: disable NAPI after all rings are disabled +- net: enetc: disable Tx BD rings after they are empty +- net: enetc: block concurrent XDP transmissions during ring reconfiguration +- net: enetc: remove xdp_drops statistic from enetc_xdp_drop() +- mptcp: pm: fix UaF read in mptcp_pm_nl_rm_addr_or_subflow +- ALSA: hda/conexant - Fix audio routing for HP EliteOne 1000 G2 +- ksmbd: fix user-after-free from session log off +- !13122 fs: 6.6 performance improve patches +- mm/rmap: minimize folio->_nr_pages_mapped updates when batching PTE (un)mapping +- mm: batch unlink_file_vma calls in free_pgd_range +- maple_tree: remove rcu_read_lock() from mt_validate() +- fs: rearrange general fastpath check now that O_CREAT uses it +- fs: remove audit dummy context check +- fs: pull up trailing slashes check for O_CREAT +- fs: move audit parent inode +- fs: try an opportunistic lookup for O_CREAT opens too +- fs/file.c: remove sanity_check and add likely/unlikely in alloc_fd() +- fs/file.c: add fast path in find_next_fd() +- !13092 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.55-6.6.57 LTS Patches +- e1000e: fix force smbus during suspend flow +- net: ethernet: cortina: Restore TSO support +- secretmem: disable memfd_secret() if arch cannot set direct map +- fs/proc/kcore.c: allow translation of physical memory addresses +- btrfs: split remaining space to discard in chunks +- selftests/rseq: Fix mm_cid test failure +- selftests/mm: fix incorrect buffer->mirror size in hmm2 double_map test +- powercap: intel_rapl_tpmi: Fix bogus register reading +- nouveau/dmem: Fix vulnerability in migrate_to_ram upon copy error +- mptcp: pm: do not remove closing subflows +- mptcp: handle consistently DSS corruption +- net: phy: Remove LED entry from LEDs list on unregister +- net: dsa: lan9303: ensure chip reset and wait for READY status +- net: Fix an unsafe loop on the list +- net: explicitly clear the sk pointer, when pf->create fails +- ata: libata: avoid superfluous disk spin down + spin up during hibernation +- mptcp: fallback when MPTCP opts are dropped after 1st data +- scsi: ufs: Use pre-calculated offsets in ufshcd_init_lrb() +- drm/i915/hdcp: fix connector refcounting +- drm/vc4: Stop the active perfmon before being destroyed +- drm/v3d: Stop the active perfmon before being destroyed +- hid: intel-ish-hid: Fix uninitialized variable 'rv' in ish_fw_xfer_direct_dma +- usb: gadget: core: force synchronous registration +- usb: storage: ignore bogus device raised by JieLi BR21 USB sound chip +- usb: xhci: Fix problem with xhci resume from suspend +- usb: dwc3: core: Stop processing of pending events if controller is halted +- Revert "usb: yurex: Replace snprintf() with the safer scnprintf() variant" +- HID: plantronics: Workaround for an unexcepted opposite volume key +- HID: multitouch: Add support for lenovo Y9000P Touchpad +- HID: amd_sfh: Switch to device-managed dmam_alloc_coherent() +- hwmon: (adt7470) Add missing dependency on REGMAP_I2C +- hwmon: (adm9240) Add missing dependency on REGMAP_I2C +- hwmon: (mc34vr500) Add missing dependency on REGMAP_I2C +- hwmon: (tmp513) Add missing dependency on REGMAP_I2C +- hwmon: intel-m10-bmc-hwmon: relabel Columbiaville to CVL Die Temperature +- hid-asus: add ROG Ally X prod ID to quirk list +- HID: asus: add ROG Z13 lightbar +- HID: asus: add ROG Ally N-Key ID and keycodes +- HID: i2c-hid: Skip SET_POWER SLEEP for Cirque touchpad on system suspend +- HID: i2c-hid: Renumber I2C_HID_QUIRK_ defines +- HID: i2c-hid: Remove I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV quirk +- rcu/nocb: Fix rcuog wake-up from offline softirq +- rcu/nocb: Make IRQs disablement symmetric +- ppp: fix ppp_async_encode() illegal access +- mctp: Handle error of rtnl_register_module(). +- bridge: Handle error of rtnl_register_module(). +- vxlan: Handle error of rtnl_register_module(). +- rtnetlink: Add bulk registration helpers for rtnetlink message handlers. +- netfilter: fib: check correct rtable in vrf setups +- netfilter: xtables: avoid NFPROTO_UNSPEC where needed +- sctp: ensure sk_state is set to CLOSED if hashing fails in sctp_listen_start +- btrfs: zoned: fix missing RCU locking in error message when loading zone info +- net: ibm: emac: mal: fix wrong goto +- net/sched: accept TCA_STAB only for root qdisc +- e1000e: change I219 (19) devices to ADP +- ice: Flush FDB entries before reset +- ice: rename switchdev to eswitch +- ice: Fix netif_is_ice() in Safe Mode +- powercap: intel_rapl_tpmi: Ignore minor version change +- platform/x86/intel/tpmi: Add defines to get version information +- gpio: aspeed: Use devm_clk api to manage clock source +- gpio: aspeed: Add the flush write to ensure the write complete. +- nouveau/dmem: Fix privileged error in copy engine channel +- drm/nouveau: pass cli to nouveau_channel_new() instead of drm+device +- net: dsa: b53: fix jumbo frames on 10/100 ports +- net: dsa: b53: allow lower MTUs on BCM5325/5365 +- net: dsa: b53: fix max MTU for BCM5325/BCM5365 +- net: dsa: b53: fix max MTU for 1g switches +- net: dsa: b53: fix jumbo frame mtu check +- net: ethernet: adi: adin1110: Fix some error handling path in adin1110_read_fifo() +- Revert "net: stmmac: set PP_FLAG_DMA_SYNC_DEV only if XDP is enabled" +- thermal: intel: int340x: processor: Fix warning during module unload +- thermal: int340x: processor_thermal: Set feature mask before proc_thermal_add +- net: phy: bcm84881: Fix some error handling paths +- Bluetooth: RFCOMM: FIX possible deadlock in rfcomm_sk_state_change +- selftests: net: no_forwarding: fix VID for $swp2 in one_bridge_two_pvids() test +- netfilter: br_netfilter: fix panic with metadata_dst skb +- rxrpc: Fix uninitialised variable in rxrpc_send_data() +- tcp: fix TFO SYN_RECV to not zero retrans_stamp with retransmits out +- tcp: new TCP_INFO stats for RTO events +- tcp: fix tcp_enter_recovery() to zero retrans_stamp when it's safe +- tcp: fix to allow timestamp undo if no retransmits were sent +- net: phy: dp83869: fix memory corruption when enabling fiber +- SUNRPC: Fix integer overflow in decode_rc_list() +- ice: fix VLAN replay after reset +- ice: set correct dst VSI in only LAN filters +- x86/amd_nb: Add new PCI IDs for AMD family 1Ah model 60h +- x86/amd_nb: Add new PCI IDs for AMD family 0x1a +- fbdev: sisfb: Fix strbuf array overflow +- fbcon: Fix a NULL pointer dereference issue in fbcon_putcs +- scsi: lpfc: Ensure DA_ID handling completion before deleting an NPIV instance +- scsi: lpfc: Add ELS_RSP cmd to the list of WQEs to flush in lpfc_els_flush_cmd() +- driver core: bus: Return -EIO instead of 0 when show/store invalid bus attribute +- staging: vme_user: added bound check to geoid +- tools/iio: Add memory allocation failure check for trigger_name +- virtio_pmem: Check device status before requesting flush +- netfilter: nf_reject: Fix build warning when CONFIG_BRIDGE_NETFILTER=n +- netfilter: nf_nat: don't try nat source port reallocation for reverse dir clash +- LoongArch: Fix memleak in pci_acpi_scan_root() +- comedi: ni_routing: tools: Check when the file could not be opened +- usb: dwc2: Adjust the timing of USB Driver Interrupt Registration in the Crashkernel Scenario +- usb: chipidea: udc: enable suspend interrupt after usb reset +- clk: imx: Remove CLK_SET_PARENT_GATE for DRAM mux for i.MX7D +- remoteproc: imx_rproc: Use imx specific hook for find_loaded_rsc_table +- media: videobuf2-core: clear memory related fields in __vb2_plane_dmabuf_put() +- riscv/kexec_file: Fix relocation type R_RISCV_ADD16 and R_RISCV_SUB16 unknown +- soundwire: cadence: re-check Peripheral status with delayed_work +- RDMA/mlx5: Enforce umem boundaries for explicit ODP page faults +- riscv: avoid Imbalance in RAS +- mfd: intel_soc_pmic_chtwc: Make Lenovo Yoga Tab 3 X90F DMI match less strict +- RISC-V: Don't have MAX_PHYSMEM_BITS exceed phys_addr_t +- i3c: master: cdns: Fix use after free vulnerability in cdns_i3c_master Driver Due to Race Condition +- PCI: Mark Creative Labs EMU20k2 INTx masking as broken +- i2c: i801: Use a different adapter-name for IDF adapters +- PCI: Add ACS quirk for Qualcomm SA8775P +- clk: bcm: bcm53573: fix OF node leak in init +- RDMA/rtrs-srv: Avoid null pointer deref during path establishment +- PCI: Add function 0 DMA alias quirk for Glenfly Arise chip +- soundwire: intel_bus_common: enable interrupts before exiting reset +- RDMA/mad: Improve handling of timed out WRs of mad agent +- ktest.pl: Avoid false positives with grub2 skip regex +- s390/cpum_sf: Remove WARN_ON_ONCE statements +- ext4: nested locking for xattr inode +- bpf, x64: Fix a jit convergence issue +- s390/mm: Add cond_resched() to cmm_alloc/free_pages() +- s390/facility: Disable compile time optimization for decompressor code +- bpf: Check percpu map value size first +- selftests/bpf: Fix ARG_PTR_TO_LONG {half-,}uninitialized test +- Input: synaptics-rmi4 - fix UAF of IRQ domain on driver removal +- virtio_console: fix misc probe bugs +- fs/ntfs3: Refactor enum_rstbl to suppress static checker +- fs/ntfs3: Fix sparse warning in ni_fiemap +- fs/ntfs3: Do not call file_modified if collapse range failed +- drm/amd/display: Revert "Check HDCP returned status" +- drm/amd/display: Remove a redundant check in authenticated_dp +- lib/build_OID_registry: avoid non-destructive substitution for Perl < 5.13.2 compat +- jbd2: fix kernel-doc for j_transaction_overhead_buffers +- selftests: Introduce Makefile variable to list shared bash scripts +- selftests: net: Remove executable bits from library scripts +- libsubcmd: Don't free the usage string +- perf sched: Move curr_pid and cpu_last_switched initialization to perf_sched__{lat|map|replay}() +- perf sched: Move curr_thread initialization to perf_sched__map() +- perf sched: Fix memory leak in perf_sched__map() +- perf sched: Move start_work_mutex and work_done_wait_mutex initialization to perf_sched__replay() +- bootconfig: Fix the kerneldoc of _xbc_exit() +- e1000e: move force SMBUS near the end of enable_ulp function +- i40e: Include types.h to some headers +- i40e: Fix ST code value for Clause 45 +- ASoC: tas2781: mark dvc_tlv with __maybe_unused +- ata: ahci: Add mask_port_map module parameter +- spi: spi-fsl-lpspi: remove redundant spi_controller_put call +- riscv: cpufeature: Fix thead vector hwcap removal +- tracing: Have saved_cmdlines arrays all in one allocation +- libceph: init the cursor when preparing sparse read in msgr2 +- pds_core: no health-thread in VF path +- Revert "powerpc/ps3_defconfig: Disable PPC64_BIG_ENDIAN_ELF_ABI_V2" +- bus: mhi: ep: Do not allocate memory for MHI objects from DMA zone +- bus: mhi: ep: Add support for async DMA read operation +- bus: mhi: ep: Add support for async DMA write operation +- bus: mhi: ep: Introduce async read/write callbacks +- bus: mhi: ep: Rename read_from_host() and write_to_host() APIs +- drm/crtc: fix uninitialized variable use even harder +- ALSA: hda/realtek: cs35l41: Fix device ID / model name +- ALSA: hda/realtek: cs35l41: Fix order and duplicates in quirks table +- tracing: Remove precision vsnprintf() check from print event +- drm/panel: boe-tv101wum-nl6: Fine tune Himax83102-j02 panel HFP and HBP (again) +- net: ethernet: cortina: Drop TSO support +- riscv: Remove SHADOW_OVERFLOW_STACK_SIZE macro +- gfs2: Revert "ignore negated quota changes" +- gfs2: qd_check_sync cleanups +- gfs2: Revert "introduce qd_bh_get_or_undo" +- phy: qualcomm: eusb2-repeater: Rework init to drop redundant zero-out loop +- phy: qualcomm: phy-qcom-eusb2-repeater: Add tuning overrides +- ASoC: cs35l56: Load tunings for the correct speaker models +- Revert "PCI/MSI: Provide stubs for IMS functions" +- net: fec: don't save PTP state if PTP is unsupported +- unicode: Don't special case ignorable code points +- Revert "perf callchain: Fix stitch LBR memory leaks" +- !12160 Add the spidev.ko to OLK-6.6 +- Open the CONFIG for spidev.ko +- !13113 f2fs: fix to wait dio completion +- f2fs: fix to wait dio completion +- !13121 blk-rq-qos: fix crash on rq_qos_wait vs. rq_qos_wake_function race +- blk-rq-qos: fix crash on rq_qos_wait vs. rq_qos_wake_function race +- !13126 Revert "perf callchain: Fix stitch LBR memory leaks" +- Revert "perf callchain: Fix stitch LBR memory leaks" +- !13064 CVE-2024-47702 +- bpf: Fix kabi breakage in struct bpf_insn_access_aux +- bpf: Fail verification for sign-extension of packet data/data_end/data_meta + * Fri Nov 08 2024 ZhangPeng - 6.6.0-52.0.0.56 - !13117 nebula-matrix: fix ci build err - Net: nebula_matrix: fix ci build err -- Gitee From a9441a3ab53eb821ad96ca94d5bef11917000885 Mon Sep 17 00:00:00 2001 From: ZhangPeng Date: Tue, 19 Nov 2024 11:42:51 +0800 Subject: [PATCH 4/8] release 6.6.0-55.0.0 --- SOURCE | 2 +- kernel.spec | 521 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 520 insertions(+), 3 deletions(-) diff --git a/SOURCE b/SOURCE index 355c86d..cd5b239 100644 --- a/SOURCE +++ b/SOURCE @@ -1 +1 @@ -6.6.0-54.0.0 +6.6.0-55.0.0 diff --git a/kernel.spec b/kernel.spec index 86f0c4d..a19e9d2 100644 --- a/kernel.spec +++ b/kernel.spec @@ -40,9 +40,9 @@ rm -f test_openEuler_sign.ko test_openEuler_sign.ko.sig %global upstream_version 6.6 %global upstream_sublevel 0 -%global devel_release 54 +%global devel_release 55 %global maintenance_release .0.0 -%global pkg_release .57 +%global pkg_release .58 %global openeuler_lts 1 %global openeuler_major 2403 @@ -1085,6 +1085,523 @@ fi %endif %changelog +* Tue Nov 19 2024 ZhangPeng - 6.6.0-55.0.0.58 +- !13235 nvmet-auth: assign dh_key to NULL after kfree_sensitive +- nvmet-auth: assign dh_key to NULL after kfree_sensitive +- !9157 [OLK-6.6] cpufreq: ACPI: add ITMT support when CPPC enabled +- Set ASYM_PACKING Flag on Zhaoxin KH-40000 platform +- cpufreq: ACPI: add ITMT support when CPPC enabled +- !13287 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.60-6.6.61 LTS Patches +- vsock/virtio: Initialization of the dangling pointer occurring in vsk->trans +- hv_sock: Initializing vsk->trans to NULL to prevent a dangling pointer +- ASoC: amd: yc: fix internal mic on Xiaomi Book Pro 14 2022 +- ucounts: fix counter leak in inc_rlimit_get_ucounts() +- ocfs2: remove entry once instead of null-ptr-dereference in ocfs2_xa_remove() +- irqchip/gic-v3: Force propagation of the active state with a read-back +- USB: serial: option: add Quectel RG650V +- USB: serial: option: add Fibocom FG132 0x0112 composition +- USB: serial: qcserial: add support for Sierra Wireless EM86xx +- USB: serial: io_edgeport: fix use after free in debug printk +- usb: typec: fix potential out of bounds in ucsi_ccg_update_set_new_cam_cmd() +- usb: typec: qcom-pmic: init value of hdr_len/txbuf_len earlier +- usb: dwc3: fix fault at system suspend if device was already runtime suspended +- usb: musb: sunxi: Fix accessing an released usb phy +- signal: restore the override_rlimit logic +- fs/proc: fix compile warning about variable 'vmcore_mmap_ops' +- i2c: designware: do not hold SCL low when I2C_DYNAMIC_TAR_UPDATE is not set +- filemap: Fix bounds checking in filemap_read() +- media: uvcvideo: Skip parsing frames of type UVC_VS_UNDEFINED in uvc_parse_format +- Revert "selftests/bpf: Implement get_hw_ring_size function to retrieve current and max interface size" +- Revert "wifi: mac80211: fix RCU list iterations" +- btrfs: reinitialize delayed ref list after deleting it from the list +- arm64: smccc: Remove broken support for SMCCCv1.3 SVE discard hint +- arm64: Kconfig: Make SME depend on BROKEN for now +- arm64/sve: Discard stale CPU state when handling SVE traps +- mptcp: use sock_kfree_s instead of kfree +- net: vertexcom: mse102x: Fix possible double free of TX skb +- net: wwan: t7xx: Fix off-by-one error in t7xx_dpmaif_rx_buf_alloc() +- nfs: Fix KMSAN warning in decode_getfattr_attrs() +- ALSA: usb-audio: Add quirk for HP 320 FHD Webcam +- dm-unstriped: cast an operand to sector_t to prevent potential uint32_t overflow +- dm cache: fix potential out-of-bounds access on the first resume +- dm cache: optimize dirty bit checking with find_next_bit when resizing +- dm cache: fix out-of-bounds access to the dirty bitset when resizing +- dm cache: fix flushing uninitialized delayed_work on cache_ctr error +- dm cache: correct the number of origin blocks to match the target length +- thermal/drivers/qcom/lmh: Remove false lockdep backtrace +- drm/amdgpu: prevent NULL pointer dereference if ATIF is not supported +- drm/amdgpu: Fix DPX valid mode check on GC 9.4.3 +- drm/amdgpu: Adjust debugfs register access permissions +- drm/amdgpu: add missing size check in amdgpu_debugfs_gprwave_read() +- drm/amdgpu: Adjust debugfs eviction and IB access permissions +- rpmsg: glink: Handle rejected intent request better +- pwm: imx-tpm: Use correct MODULO value for EPWM mode +- ksmbd: fix slab-use-after-free in smb3_preauth_hash_rsp +- ksmbd: Fix the missing xa_store error check +- ksmbd: check outstanding simultaneous SMB operations +- ksmbd: fix slab-use-after-free in ksmbd_smb2_session_create +- can: mcp251xfd: mcp251xfd_ring_alloc(): fix coalescing configuration when switching CAN modes +- can: mcp251xfd: mcp251xfd_get_tef_len(): fix length calculation +- can: m_can: m_can_close(): don't call free_irq() for IRQ-less devices +- media: v4l2-ctrls-api: fix error handling for v4l2_g_ctrl() +- media: v4l2-tpg: prevent the risk of a division by zero +- media: pulse8-cec: fix data timestamp at pulse8_setup() +- media: cx24116: prevent overflows on SNR calculus +- media: s5p-jpeg: prevent buffer overflows +- media: ar0521: don't overflow when checking PLL values +- ASoC: SOF: sof-client-probes-ipc4: Set param_size extension bits +- ASoC: stm32: spdifrx: fix dma channel release in stm32_spdifrx_remove +- thermal/of: support thermal zones w/o trips subnode +- tools/lib/thermal: Fix sampling handler context ptr +- ALSA: firewire-lib: fix return value on fail in amdtp_tscm_init() +- scsi: sd_zbc: Use kvzalloc() to allocate REPORT ZONES buffer +- media: adv7604: prevent underflow condition when reporting colorspace +- media: dvb_frontend: don't play tricks with underflow values +- media: dvbdev: prevent the risk of out of memory access +- media: stb0899_algo: initialize cfr before using it +- Revert "ALSA: hda/conexant: Mute speakers at suspend / shutdown" +- drivers: net: ionic: add missed debugfs cleanup to ionic_probe() error path +- rxrpc: Fix missing locking causing hanging calls +- net: arc: rockchip: fix emac mdio node support +- net: arc: fix the device for dma_map_single/dma_unmap_single +- virtio_net: Add hash_key_length check +- netfilter: nf_tables: wait for rcu grace period on net_device removal +- netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx +- netfilter: nf_tables: cleanup documentation +- net: stmmac: Fix unbalanced IRQ wake disable warning on single irq case +- net: phy: ti: add PHY_RST_AFTER_CLK_EN flag +- net: hns3: fix kernel crash when uninstalling driver +- e1000e: Remove Meteor Lake SMBUS workarounds +- i40e: fix race condition by adding filter's intermediate sync state +- ice: change q_index variable type to s16 to store -1 value +- can: c_can: fix {rx,tx}_errors statistics +- net: enetc: allocate vf_state during PF probes +- sctp: properly validate chunk size in sctp_sf_ootb() +- dt-bindings: net: xlnx,axi-ethernet: Correct phy-mode property value +- net: enetc: set MAC address to the VF net_device +- regulator: rtq2208: Fix uninitialized use of regulator_config +- nfs: avoid i_lock contention in nfs_clear_invalid_mapping +- NFSv3: only use NFS timeout for MOUNT when protocols are compatible +- sunrpc: handle -ENOTCONN in xs_tcp_setup_socket() +- platform/x86/amd/pmc: Detect when STB is not available +- HID: core: zero-initialize the report buffer +- arm64: dts: rockchip: Correct GPIO polarity on brcm BT nodes +- ARM: dts: rockchip: Fix the realtek audio codec on rk3036-kylin +- ARM: dts: rockchip: Fix the spi controller on rk3036 +- ARM: dts: rockchip: drop grf reference from rk3036 hdmi +- ARM: dts: rockchip: fix rk3036 acodec node +- arm64: dts: rockchip: remove orphaned pinctrl-names from pinephone pro +- firmware: arm_scmi: Fix slab-use-after-free in scmi_bus_notifier() +- arm64: dts: imx8mp: correct sdhc ipg clk +- arm64: dts: imx8-ss-vpu: Fix imx8qm VPU IRQs +- arm64: dts: imx8qxp: Add VPU subsystem file +- arm64: dts: rockchip: remove num-slots property from rk3328-nanopi-r2s-plus +- arm64: dts: rockchip: Fix LED triggers on rk3308-roc-cc +- arm64: dts: rockchip: Remove #cooling-cells from fan on Theobroma lion +- arm64: dts: rockchip: Remove undocumented supports-emmc property +- arm64: dts: rockchip: Add DTS for FriendlyARM NanoPi R2S Plus +- arm64: dts: rockchip: Fix bluetooth properties on Rock960 boards +- arm64: dts: rockchip: Fix bluetooth properties on rk3566 box demo +- arm64: dts: rockchip: fix i2c2 pinctrl-names property on anbernic-rg353p/v +- arm64: dts: rockchip: Fix reset-gpios property on brcm BT nodes +- arm64: dts: rockchip: Fix wakeup prop names on PineNote BT node +- arm64: dts: rockchip: Remove hdmi's 2nd interrupt on rk3328 +- arm64: dts: rockchip: Fix rt5651 compatible value on rk3399-sapphire-excavator +- arm64: dts: rockchip: Fix rt5651 compatible value on rk3399-eaidk-610 +- !13269 Revert "Loongarch: Dynamic enable writecombine" +- Revert "Loongarch: Dynamic enable writecombine" +- !13193 fix CVE-2024-50115 +- KVM: nSVM: Ignore nCR3[4:0] when loading PDPTEs from memory +- !13179 bpf: Use raw_spinlock_t in ringbuf +- bpf: Use raw_spinlock_t in ringbuf +- !13263 bpf: Zero former ARG_PTR_TO_{LONG,INT} args in case of error +- bpf: Zero former ARG_PTR_TO_{LONG,INT} args in case of error +- !12249 Bluetooth: btnxpuart: Fix Null pointer dereference in btnxpuart_flush() +- Bluetooth: btnxpuart: Fix Null pointer dereference in btnxpuart_flush() +- !13259 v2 mm, mmap: limit THP alignment of anonymous mappings to PMD-aligned sizes +- mm: enable PMD anouymous mapping by default +- mm, mmap: limit THP alignment of anonymous mappings to PMD-aligned sizes +- !13215 fork: do not expose incomplete mm on fork +- fork: only invoke khugepaged, ksm hooks if no error +- fork: do not invoke uffd on fork if error occurs +- mm/ksm: remove redundant code in ksm_fork +- !13047 virtcca feature :SM Cryptographic Acceleration +- virtcca feature : SM Cryptographic Aacceleration. +- !13210 Script execution control +- fix kabi breakage due to exec is_check +- IMA support script execution check +- exec: Add a new AT_CHECK flag to execveat(2) +- uselib: remove use of __FMODE_EXEC +- exec: Check __FMODE_EXEC instead of in_execve for LSMs +- execve: open the executable file before doing anything else +- !13257 IMA RoT +- ima: rot: Adapt VirtCCA into Rot +- ima: Rename ima_cvm to ima_virtcca +- ima: rot: Make RoT kick in +- ima: rot: Prepare TPM as an RoT +- ima: rot: Introduce basic framework +- !13240 virtcca feature: support transfer smmu_vmid to tmm +- virtcca feature : transfer smmu_vmid +- !13244 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.59-6.6.60 LTS Patches +- fs/ntfs3: Sequential field availability check in mi_enum_attr() +- ASoC: SOF: ipc4-control: Add support for ALSA enum control +- ASoC: SOF: ipc4-control: Add support for ALSA switch control +- ASoC: SOF: ipc4-topology: Add definition for generic switch/enum control +- SUNRPC: Remove BUG_ON call sites +- mtd: spi-nor: winbond: fix w25q128 regression +- wifi: iwlwifi: mvm: fix 6 GHz scan construction +- nilfs2: fix kernel bug due to missing clearing of checked flag +- wifi: mac80211: fix NULL dereference at band check in starting tx ba session +- arm64: dts: imx8ulp: correct the flexspi compatible string +- vmscan,migrate: fix page count imbalance on node stats when demoting pages +- io_uring/rw: fix missing NOWAIT check for O_DIRECT start write +- kasan: remove vmalloc_percpu test +- nvmet-auth: assign dh_key to NULL after kfree_sensitive +- ALSA: hda/realtek: Fix headset mic on TUXEDO Stellaris 16 Gen6 mb1 +- ALSA: hda/realtek: Fix headset mic on TUXEDO Gemini 17 Gen3 +- xfs: fix finding a last resort AG in xfs_filestream_pick_ag +- mctp i2c: handle NULL header address +- ocfs2: pass u64 to ocfs2_truncate_inline maybe overflow +- x86/traps: move kmsan check after instrumentation_begin +- x86/traps: Enable UBSAN traps on x86 +- mm/page_alloc: let GFP_ATOMIC order-0 allocs access highatomic reserves +- mei: use kvmalloc for read buffer +- mptcp: init: protect sched with rcu_read_lock +- iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP +- cxl/acpi: Ensure ports ready at cxl_acpi_probe() return +- cxl/port: Fix cxl_bus_rescan() vs bus_rescan_devices() +- riscv: Remove duplicated GET_RM +- riscv: Remove unused GENERATING_ASM_OFFSETS +- riscv: Use '%u' to format the output of 'cpu' +- riscv: efi: Set NX compat flag in PE/COFF header +- ALSA: hda/realtek: Limit internal Mic boost on Dell platform +- Input: edt-ft5x06 - fix regmap leak when probe fails +- riscv: vdso: Prevent the compiler from inserting calls to memset() +- spi: spi-fsl-dspi: Fix crash when not using GPIO chip select +- phy: freescale: imx8m-pcie: Do CMN_RST just before PHY PLL lock check +- block: fix sanity checks in blk_rq_map_user_bvec +- mmc: sdhci-pci-gli: GL9767: Fix low power mode in the SD Express process +- mmc: sdhci-pci-gli: GL9767: Fix low power mode on the set clock function +- cxl/port: Fix use-after-free, permit out-of-order decoder shutdown +- thunderbolt: Honor TMU requirements in the domain when setting TMU mode +- tools/mm: -Werror fixes in page-types/slabinfo +- mm: shmem: fix data-race in shmem_getattr() +- RISC-V: ACPI: fix early_ioremap to early_memremap +- nilfs2: fix potential deadlock with newly created symlinks +- iio: light: veml6030: fix microlux value calculation +- iio: gts-helper: Fix memory leaks in iio_gts_build_avail_scale_table() +- iio: gts-helper: Fix memory leaks for the error path of iio_gts_build_avail_scale_table() +- iio: adc: ad7124: fix division by zero in ad7124_set_channel_odr() +- staging: iio: frequency: ad9832: fix division by zero in ad9832_calc_freqreg() +- wifi: iwlegacy: Clear stale interrupts before resuming device +- wifi: cfg80211: clear wdev->cqm_config pointer on free +- wifi: ath10k: Fix memory leak in management tx +- wifi: mac80211: do not pass a stopped vif to the driver in .get_txpower +- Revert "selftests/mm: replace atomic_bool with pthread_barrier_t" +- Revert "selftests/mm: fix deadlock for fork after pthread_create on ARM" +- Revert "driver core: Fix uevent_show() vs driver detach race" +- xhci: Use pm_runtime_get to prevent RPM on unsupported systems +- phy: qcom: qmp-usb-legacy: fix NULL-deref on runtime suspend +- phy: qcom: qmp-usb: fix NULL-deref on runtime suspend +- usb: typec: qcom-pmic-typec: use fwnode_handle_put() to release fwnodes +- usb: typec: fix unreleased fwnode_handle in typec_port_register_altmodes() +- usb: phy: Fix API devm_usb_put_phy() can not release the phy +- usbip: tools: Fix detach_port() invalid port error path +- ALSA: usb-audio: Add quirks for Dell WD19 dock +- USB: gadget: dummy-hcd: Fix "task hung" problem +- usb: gadget: dummy_hcd: execute hrtimer callback in softirq context +- usb: gadget: dummy_hcd: Set transfer interval to 1 microframe +- usb: gadget: dummy_hcd: Switch to hrtimer transfer scheduler +- misc: sgi-gru: Don't disable preemption in GRU driver +- NFS: remove revoked delegation from server's delegation list +- net: amd: mvme147: Fix probe banner message +- thermal: intel: int340x: processor: Add MMIO RAPL PL4 support +- thermal: intel: int340x: processor: Remove MMIO RAPL CPU hotplug support +- cifs: Fix creating native symlinks pointing to current or parent directory +- cifs: Improve creating native symlinks pointing to directory +- scsi: scsi_transport_fc: Allow setting rport state to current state +- fs/ntfs3: Additional check in ntfs_file_release +- fs/ntfs3: Fix general protection fault in run_is_mapped_full +- fs/ntfs3: Additional check in ni_clear() +- fs/ntfs3: Fix possible deadlock in mi_read +- fs/ntfs3: Add rough attr alloc_size check +- fs/ntfs3: Stale inode instead of bad +- fs/ntfs3: Fix warning possible deadlock in ntfs_set_state +- fs/ntfs3: Check if more than chunk-size bytes are written +- ntfs3: Add bounds checking to mi_enum_attr() +- cxl/events: Fix Trace DRAM Event Record +- smb: client: set correct device number on nfs reparse points +- ACPI: CPPC: Make rmw_lock a raw_spin_lock +- afs: Fix missing subdir edit when renamed between parent dirs +- afs: Automatically generate trace tag enums +- kasan: Fix Software Tag-Based KASAN with GCC +- iomap: turn iomap_want_unshare_iter into an inline function +- fsdax: dax_unshare_iter needs to copy entire blocks +- fsdax: remove zeroing code from dax_unshare_iter +- iomap: share iomap_unshare_iter predicate code with fsdax +- iomap: don't bother unsharing delalloc extents +- iomap: improve shared block detection in iomap_unshare_iter +- bpf, test_run: Fix LIVE_FRAME frame update after a page has been recycled +- netfilter: nft_payload: sanitize offset and length before calling skb_checksum() +- mlxsw: spectrum_ipip: Fix memory leak when changing remote IPv6 address +- mlxsw: spectrum_ptp: Add missing verification before pushing Tx header +- net: skip offload for NETIF_F_IPV6_CSUM if ipv6 header contains extension +- Bluetooth: hci: fix null-ptr-deref in hci_read_supported_codecs +- netfilter: nf_reject_ipv6: fix potential crash in nf_send_reset6() +- netfilter: Fix use-after-free in get_info() +- net: fix crash when config small gso_max_size/gso_ipv4_max_size +- bpf: Fix out-of-bounds write in trie_get_next_key() +- netdevsim: Add trailing zero to terminate the string in nsim_nexthop_bucket_activity_write() +- bpf: Force checkpoint when jmp history is too long +- selftests/bpf: Add bpf_percpu_obj_{new,drop}() macro in bpf_experimental.h +- net/sched: stop qdisc_tree_reduce_backlog on TC_H_ROOT +- gtp: allow -1 to be specified as file description from userspace +- ipv4: ip_tunnel: Fix suspicious RCU usage warning in ip_tunnel_init_flow() +- net: stmmac: TSO: Fix unbalanced DMA map/unmap for non-paged SKB data +- net: stmmac: dwmac4: Fix high address display by updating reg_space[] from register values +- macsec: Fix use-after-free while sending the offloading packet +- ASoC: cs42l51: Fix some error handling paths in cs42l51_probe() +- wifi: iwlwifi: mvm: don't add default link in fw restart flow +- wifi: iwlwifi: mvm: Fix response handling in iwl_mvm_send_recovery_cmd() +- wifi: iwlwifi: mvm: disconnect station vifs if recovery failed +- RDMA/bnxt_re: synchronize the qp-handle table array +- RDMA/bnxt_re: Fix the usage of control path spin locks +- RDMA/mlx5: Round max_rd_atomic/max_dest_rd_atomic up instead of down +- RDMA/cxgb4: Dump vendor specific QP details +- wifi: brcm80211: BRCM_TRACING should depend on TRACING +- wifi: ath11k: Fix invalid ring usage in full monitor mode +- wifi: mac80211: skip non-uploaded keys in ieee80211_iter_keys +- mac80211: MAC80211_MESSAGE_TRACING should depend on TRACING +- wifi: iwlegacy: Fix "field-spanning write" warning in il_enqueue_hcmd() +- spi: geni-qcom: Fix boot warning related to pm_runtime and devres +- cgroup: Fix potential overflow issue when checking max_depth +- Input: xpad - add support for 8BitDo Ultimate 2C Wireless Controller +- Input: xpad - sort xpad_device by vendor and product ID +- thermal: core: Free tzp copy along with the thermal zone +- thermal: core: Rework thermal zone availability check +- thermal: core: Make thermal_zone_device_unregister() return after freeing the zone +- !9721 drm: vc4: Fix possible null pointer dereference +- drm: vc4: Fix possible null pointer dereference +- !12376 wifi: mac80211: fix NULL dereference at band check in starting tx ba session +- wifi: mac80211: fix NULL dereference at band check in starting tx ba session +- !13140 CVE-2024-50056 +- usb: gadget: uvc: Fix ERR_PTR dereference in uvc_v4l2.c +- usb: gadget: uvc: fix try format returns on uncompressed formats +- !13180 Add objtool, orc and livepatch support for LoongArch +- LoongArch: Update Loongson-3 default config file +- compiler.h: specify correct attribute for .rodata..c_jump_table +- LoongArch: Set AS_HAS_THIN_ADD_SUB as y if AS_IS_LLVM +- LoongArch: Enable objtool for Clang +- objtool: Handle frame pointer related instructions +- LoongArch: Add ifdefs to fix LSX and LASX related warnings +- LoongArch: Only allow OBJTOOL & ORC unwinder if toolchain supports -mthin-add-sub +- LoongArch: Add kernel livepatching support +- LoongArch: Fix definition of ftrace_regs_set_instruction_pointer() +- LoongArch: Add ORC stack unwinder support +- objtool: Check local label in read_unwind_hints() +- objtool: Check local label in add_dead_ends() +- objtool/LoongArch: Enable orc to be built +- objtool/x86: Separate arch-specific and generic parts +- objtool/LoongArch: Implement instruction decoder +- objtool/LoongArch: Enable objtool to be built +- !13131 [OLK-6.6][Backport] exec: don't WARN for racy path_noexec check +- exec: don't WARN for racy path_noexec check +- Revert "exec: Remove redundant check in do_open_execat/uselib" +- !13192 net/ncsi: Disable the ncsi work before freeing the associated structure +- net/ncsi: Disable the ncsi work before freeing the associated structure +- !13079 serial: core: Fix atomicity violation in uart_tiocmget +- serial: core: Fix atomicity violation in uart_tiocmget +- !13074 selinux: clarify return code in filename_trans_read_helper_compat() +- selinux: clarify return code in filename_trans_read_helper_compat() +- !12431 [olk 6.6] net: hibmcge: add support for hibmcge driver +- net: hibmcge: Add maintainer for hibmcge +- net: hns3/hns: Update the maintainer for the HNS3/HNS ethernet driver +- net: hibmcge: Add a Makefile and update Kconfig for hibmcge +- net: hibmcge: Implement some ethtool_ops functions +- net: hibmcge: Implement rx_poll function to receive packets +- net: hibmcge: Implement .ndo_start_xmit function +- net: hibmcge: Implement some .ndo functions +- net: hibmcge: Add interrupt supported in this module +- net: hibmcge: Add mdio and hardware configuration supported in this module +- net: hibmcge: Add read/write registers supported through the bar space +- net: hibmcge: Add pci table supported in this module +- !13189 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.58-6.6.59 LTS Patches +- xfrm: validate new SA's prefixlen using SA family when sel.family is unset +- RDMA/bnxt_re: Fix unconditional fence for newer adapters +- RDMA/bnxt_re: Avoid creating fence MR for newer adapters +- RDMA/bnxt_re: Fix the offset for GenP7 adapters for user applications +- ACPI: PRM: Clean up guid type in struct prm_handler_info +- platform/x86: dell-wmi: Ignore suspend notifications +- ASoC: qcom: Fix NULL Dereference in asoc_qcom_lpass_cpu_platform_probe() +- ata: libata: Set DID_TIME_OUT for commands that actually timed out +- net: phy: dp83822: Fix reset pin definitions +- selinux: improve error checking in sel_write_load() +- drm/amd/display: Disable PSR-SU on Parade 08-01 TCON too +- hv_netvsc: Fix VF namespace also in synthetic NIC NETDEV_REGISTER event +- xfrm: fix one more kernel-infoleak in algo dumping +- LoongArch: Make KASAN usable for variable cpu_vabits +- LoongArch: Enable IRQ if do_ale() triggered in irq-enabled context +- LoongArch: Get correct cores_per_package for SMT systems +- ALSA: hda/realtek: Add subwoofer quirk for Acer Predator G9-593 +- ALSA: hda/tas2781: select CRC32 instead of CRC32_SARWATE +- x86/lam: Disable ADDRESS_MASKING in most cases +- KVM: arm64: Don't eagerly teardown the vgic on init error +- KVM: arm64: Fix shift-out-of-bounds bug +- KVM: nSVM: Ignore nCR3[4:0] when loading PDPTEs from memory +- openat2: explicitly return -E2BIG for (usize > PAGE_SIZE) +- nilfs2: fix kernel bug due to missing clearing of buffer delay flag +- ACPI: button: Add DMI quirk for Samsung Galaxy Book2 to fix initial lid detection issue +- ACPI: PRM: Find EFI_MEMORY_RUNTIME block for PRM handler and context +- ACPI: resource: Add LG 16T90SP to irq1_level_low_skip_override[] +- drm/amd: Guard against bad data for ATIF ACPI method +- btrfs: zoned: fix zone unusable accounting for freed reserved extent +- btrfs: fix passing 0 to ERR_PTR in btrfs_search_dir_index_item() +- cpufreq: CPPC: fix perf_to_khz/khz_to_perf conversion exception +- cpufreq/cppc: Move and rename cppc_cpufreq_{perf_to_khz|khz_to_perf}() +- ALSA: hda/realtek: Update default depop procedure +- powercap: dtpm_devfreq: Fix error check against dev_pm_qos_add_request() +- ALSA: firewire-lib: Avoid division by zero in apply_constraint_to_size() +- ASoC: fsl_micfil: Add a flag to distinguish with different volume control types +- ASoC: rsnd: Fix probe failure on HiHope boards due to endpoint parsing +- ASoC: max98388: Fix missing increment of variable slot_found +- ASoC: loongson: Fix component check failed on FDT systems +- ASoC: dt-bindings: davinci-mcasp: Fix interrupt properties +- ASoC: dt-bindings: davinci-mcasp: Fix interrupts property +- net: dsa: mv88e6xxx: support 4000ps cycle counter period +- net: dsa: mv88e6xxx: read cycle counter period from hardware +- net: dsa: mv88e6xxx: group cycle counter coefficients +- bpf,perf: Fix perf_event_detach_bpf_prog error handling +- Bluetooth: ISO: Fix UAF on iso_sock_timeout +- Bluetooth: SCO: Fix UAF on sco_sock_timeout +- posix-clock: posix-clock: Fix unbalanced locking in pc_clock_settime() +- r8169: avoid unsolicited interrupts +- net: sched: use RCU read-side critical section in taprio_dump() +- net: sched: fix use-after-free in taprio_change() +- net/sched: act_api: deny mismatched skip_sw/skip_hw flags for actions created by classifiers +- bpf: Simplify checking size of helper accesses +- net: usb: usbnet: fix name regression +- net: fix races in netdev_tx_sent_queue()/dev_watchdog() +- net/sched: adjust device watchdog timer to detect stopped queue at right time +- net: wwan: fix global oob in wwan_rtnl_policy +- netfilter: xtables: fix typo causing some targets not to load on IPv6 +- fsl/fman: Fix refcount handling of fman-related devices +- fsl/fman: Save device references taken in mac_probe() +- net: dsa: mv88e6xxx: Fix error when setting port policy on mv88e6393x +- net: plip: fix break; causing plip to never transmit +- be2net: fix potential memory leak in be_xmit() +- net/sun3_82586: fix potential memory leak in sun3_82586_send_packet() +- netfilter: bpf: must hold reference on net namespace +- xfrm: respect ip protocols rules criteria when performing dst lookups +- xfrm: extract dst lookup parameters into a struct +- tracing/probes: Fix MAX_TRACE_ARGS limit handling +- jfs: Fix sanity check in dbMount +- LoongArch: Don't crash in stack_top() for tasks without vDSO +- platform/x86: dell-sysman: add support for alienware products +- cifs: Validate content of NFS reparse point buffer +- ASoC: qcom: sm8250: add qrb4210-rb2-sndcard compatible string +- udf: fix uninit-value use in udf_get_fileshortad +- udf: refactor inode_bmap() to handle error +- udf: refactor udf_next_aext() to handle error +- udf: refactor udf_current_aext() to handle error +- arm64: Force position-independent veneers +- ASoC: fsl_sai: Enable 'FIFO continue on error' FCONT bit +- ASoC: codecs: lpass-rx-macro: add missing CDC_RX_BCL_VBAT_RF_PROC2 to default regs values +- ASoC: amd: yc: Add quirk for HP Dragonfly pro one +- drm/vboxvideo: Replace fake VLA at end of vbva_mouse_pointer_shape with real VLA +- tracing/probes: cleanup: Set trace_probe::nr_args at trace_probe_init +- tracing/fprobe-event: cleanup: Fix a wrong comment in fprobe event +- usb: dwc3: core: Fix system suspend on TI AM62 platforms +- XHCI: Separate PORT and CAPs macros into dedicated file +- usb: gadget: f_uac2: fix return value for UAC2_ATTRIBUTE_STRING store +- usb: gadget: f_uac2: fix non-newline-terminated function name +- usb: gadget: f_uac2: Replace snprintf() with the safer scnprintf() variant +- xhci: dbc: honor usb transfer size boundaries. +- xhci: dbgtty: use kfifo from tty_port struct +- xhci: dbgtty: remove kfifo_out() wrapper +- iio: adc: ti-lmp92064: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig +- cdrom: Avoid barrier_nospec() in cdrom_ioctl_media_changed() +- bpf: Fix iter/task tid filtering +- nvme-pci: fix race condition between reset and nvme_dev_disable() +- nvme-pci: set doorbell config before unquiescing +- riscv, bpf: Make BPF_CMPXCHG fully ordered +- bpf, vsock: Drop static vsock_bpf_prot initialization +- vsock: Update msg_count on read_skb() +- vsock: Update rx_bytes on read_skb() +- bpf, sockmap: SK_DROP on attempted redirects of unsupported af_vsock +- net/mlx5: Unregister notifier on eswitch init failure +- net/mlx5: Fix command bitmask initialization +- net/mlx5: Check for invalid vector index on EQ creation +- vmxnet3: Fix packet corruption in vmxnet3_xdp_xmit_frame +- Bluetooth: bnep: fix wild-memory-access in proto_unregister +- bpf: Fix link info netfilter flags to populate defrag flag +- s390: Initialize psw mask in perf_arch_fetch_caller_regs() +- usb: typec: altmode should keep reference to parent +- smb: client: fix OOBs when building SMB2_IOCTL request +- scsi: target: core: Fix null-ptr-deref in target_alloc_device() +- net: ravb: Only advertise Rx/Tx timestamps if hardware supports it +- ravb: Remove setting of RX software timestamp +- genetlink: hold RCU in genlmsg_mcast() +- net: dsa: mv88e6xxx: Fix the max_vid definition for the MV88E6361 +- tcp/dccp: Don't use timer_pending() in reqsk_queue_unlink(). +- net: bcmasp: fix potential memory leak in bcmasp_xmit() +- drm/msm/dpu: don't always program merge_3d block +- irqchip/renesas-rzg2l: Fix missing put_device +- irqchip/renesas-rzg2l: Add support for suspend to RAM +- irqchip/renesas-rzg2l: Document structure members +- irqchip/renesas-rzg2l: Align struct member names to tabs +- net: systemport: fix potential memory leak in bcm_sysport_xmit() +- bpf: Fix truncation bug in coerce_reg_to_size_sx() +- net: xilinx: axienet: fix potential memory leak in axienet_start_xmit() +- net/smc: Fix searching in list of known pnetids in smc_pnet_add_pnetid +- net: ethernet: aeroflex: fix potential memory leak in greth_start_xmit_gbit() +- netdevsim: use cond_resched() in nsim_dev_trap_report_work() +- macsec: don't increment counters for an unrelated SA +- drm/amd/amdgpu: Fix double unlock in amdgpu_mes_add_ring +- octeontx2-af: Fix potential integer overflows on integer shifts +- net: stmmac: dwmac-tegra: Fix link bring-up sequence +- net: usb: usbnet: fix race in probe failure +- net/smc: Fix memory leak when using percpu refs +- firmware: arm_scmi: Queue in scmi layer for mailbox implementation +- drm/msm: Allocate memory for disp snapshot with kvzalloc() +- drm/msm/dsi: fix 32-bit signed integer extension in pclk_rate calculation +- drm/msm/dsi: improve/fix dsc pclk calculation +- drm/msm/dpu: check for overflow in _dpu_crtc_setup_lm_bounds() +- drm/msm/dpu: make sure phys resources are properly initialized +- accel/qaic: Fix the for loop used to walk SG table +- RDMA/bnxt_re: Fix the GID table length +- RDMA/bnxt_re: Update the BAR offsets +- RDMA/bnxt_re: Fix a bug while setting up Level-2 PBL pages +- RDMA/bnxt_re: Return more meaningful error +- RDMA/bnxt_re: Fix out of bound check +- RDMA/bnxt_re: Fix the max CQ WQEs for older adapters +- RDMA/bnxt_re: Support new 5760X P7 devices +- ipv4: give an IPv4 dev to blackhole_netdev +- RDMA/srpt: Make slab cache names unique +- RDMA/irdma: Fix misspelling of "accept*" +- RDMA/cxgb4: Fix RDMA_CM_EVENT_UNREACHABLE error for iWARP +- firmware: arm_scmi: Fix the double free in scmi_debugfs_common_setup() +- ALSA: hda/cs8409: Fix possible NULL dereference +- selftests/bpf: Fix cross-compiling urandom_read +- drm/vmwgfx: Handle possible ENOMEM in vmw_stdu_connector_atomic_check +- iio: frequency: admv4420: fix missing select REMAP_SPI in Kconfig +- iio: frequency: {admv4420,adrf6780}: format Kconfig entries +- bpf: fix kfunc btf caching for modules +- s390/pci: Handle PCI error codes other than 0x3a +- selftests/bpf: fix perf_event link info name_len assertion +- selftests/bpf: Add cookies check for perf_event fill_link_info test +- selftests/bpf: Use bpf_link__destroy in fill_link_info tests +- ARM: dts: bcm2837-rpi-cm3-io3: Fix HDMI hpd-gpio pin +- RDMA/core: Fix ENODEV error for iWARP test over vlan +- RDMA/bnxt_re: Add a check for memory allocation +- RDMA/bnxt_re: Fix incorrect AVID type in WQE structure +- RDMA/bnxt_re: Fix a possible memory leak +- bpf: Fix memory leak in bpf_core_apply +- lib/Kconfig.debug: fix grammar in RUST_BUILD_ASSERT_ALLOW +- cpufreq/amd-pstate: Fix amd_pstate mode switch on shared memory systems +- bpf: devmap: provide rxq after redirect +- bpf: Make sure internal and UAPI bpf_redirect flags don't overlap +- iio: accel: bma400: Fix uninitialized variable field_value in tap event handling. + * Wed Nov 13 2024 ZhangPeng - 6.6.0-54.0.0.57 - !12859 intel: backport GNR and SRF intel_idle fix for 6.6 - intel_idle: fix ACPI _CST matching for newer Xeon platforms -- Gitee From b0c782909869c64b39d4d1896c76ea8bd8253f15 Mon Sep 17 00:00:00 2001 From: ZhangPeng Date: Wed, 27 Nov 2024 14:24:26 +0800 Subject: [PATCH 5/8] release 6.6.0-57.0.0 --- SOURCE | 2 +- kernel.spec | 246 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 245 insertions(+), 3 deletions(-) diff --git a/SOURCE b/SOURCE index cd5b239..8186f4a 100644 --- a/SOURCE +++ b/SOURCE @@ -1 +1 @@ -6.6.0-55.0.0 +6.6.0-57.0.0 diff --git a/kernel.spec b/kernel.spec index a19e9d2..4266d16 100644 --- a/kernel.spec +++ b/kernel.spec @@ -40,9 +40,9 @@ rm -f test_openEuler_sign.ko test_openEuler_sign.ko.sig %global upstream_version 6.6 %global upstream_sublevel 0 -%global devel_release 55 +%global devel_release 57 %global maintenance_release .0.0 -%global pkg_release .58 +%global pkg_release .59 %global openeuler_lts 1 %global openeuler_major 2403 @@ -1085,6 +1085,248 @@ fi %endif %changelog +* Wed Nov 27 2024 ZhangPeng - 6.6.0-57.0.0.59 +- !13845 backport some patches from upstream about HCCS low power +- soc: hisilicon: kunpeng_hccs: Support low power feature for the specified HCCS type +- soc: hisilicon: kunpeng_hccs: Add used HCCS types sysfs +- soc: hisilicon: kunpeng_hccs: Fix the 'lane_mode' field name in port info structure to 'max_lane_num' +- soc: hisilicon: kunpeng_hccs: Add the check for base address and size of shared memory +- soc: hisilicon: kunpeng_hccs: Return failure on having not die or port information +- soc: hisilicon: kunpeng_hccs: Fix a PCC typo +- !13842 ima: fix buffer overrun in ima_eventdigest_init_common +- ima: fix buffer overrun in ima_eventdigest_init_common +- !13827 LoongArch: KVM: Mark hrtimer to expire in hard interrupt context +- LoongArch: KVM: Mark hrtimer to expire in hard interrupt context +- !11952 migration: fix reference counting exception issue +- migration: fix reference counting exception issue +- !13816 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.49-6.6.50 LTS Conflicts Patches +- hwmon: (k10temp) Check return value of amd_smn_read() +- mptcp: pr_debug: add missing +- mptcp: avoid duplicated SUB_CLOSED events +- selftests: mptcp: join: check re-re-adding ID 0 signal +- selftests: mptcp: join: validate event numbers +- !11950 arm64/perf: Enable branch stack sampling +- arm64/perf: Enable branch stack sampling +- perf: test: Extend branch stack sampling test for Arm64 BRBE +- perf: test: Remove empty lines from branch filter test output +- perf: test: Speed up running brstack test on an Arm model +- KVM: arm64: nvhe: Disable branch generation in nVHE guests +- drivers: perf: arm_pmuv3: Enable branch stack sampling via FEAT_BRBE +- arm64/boot: Enable EL2 requirements for BRBE +- drivers: perf: arm_pmu: Add infrastructure for branch stack sampling +- KVM: arm64: Explicitly handle BRBE traps as UNDEFINED +- arm64/sysreg: Add BRBE registers and fields +- KVM: arm64: Initialize the kvm host data's fpsimd_state pointer in pKVM +- KVM: arm64: nv: Drop VCPU_HYP_CONTEXT flag +- KVM: arm64: Exclude FP ownership from kvm_vcpu_arch +- KVM: arm64: Exclude host_fpsimd_state pointer from kvm_vcpu_arch +- KVM: arm64: Exclude mdcr_el2_host from kvm_vcpu_arch +- KVM: arm64: Exclude host_debug_data from vcpu_arch +- KVM: arm64: Add accessor for per-CPU state +- KVM: arm64: Fix TRFCR_EL1/PMSCR_EL1 access in hVHE mode +- arm64: Add missing _EL2 encodings +- arm64: Add missing _EL12 encodings +- !13836 virtcca bugfix: correct array copy for hpre_addr +- virtcca bugfix: correct array copy for hpre_addr +- !13416 tpm: Lock TPM chip in tpm_pm_suspend() first +- tpm: Lock TPM chip in tpm_pm_suspend() first +- !13810 【olk 6.6】 net: hns3: add mac tunnel number query +- net: hns3: add mac tunnel number query +- !13831 fix CVE-2024-50192 +- irqchip/gic-v4: Correctly deal with set_affinity on lazily-mapped VPEs +- irqchip/gic-v4: Don't allow a VMOVP on a dying VPE +- !13243 virtcca: fix the double map of cvm secure memory +- virtcca feature : disable swiotlb for passthrough device +- virtcca feature : force vring alloc use dma api +- virtcca feature: enable unmap swiotlb buffer to save iotlb cvm memory +- !12343 net: tcp: add a new congestion control algorithm, CAQM, with endhost-network coordination +- net: tcp: Modify codes for better compatibility of code format +- net: tcp: Add CAQM4TCP in the openeuler 6.6 kernel +- !13818 net/hinic3: Support new NIC feature +- net/hinic3: Support new RX feature +- net/hinic3: Support new TX feature +- !13413 sched/topology: Prevent race condition in sched_domain topology +- sched/topology: Prevent race condition in sched_domain topology +- !13808 perf: Add PMCG platform information for HiSilicon HIP09A +- perf: Add PMCG platform information for HiSilicon HIP09A +- !13794 drm/amd/display: Add NULL check for clk_mgr in dcn32_init_hw +- drm/amd/display: Add NULL check for clk_mgr in dcn32_init_hw +- !13795 drm/amd/display: Initialize denominators' default to 1 +- drm/amd/display: Initialize denominators' default to 1 +- !13408 rseq/mm_cid: change KABI consistency interface +- rseq/mm_cid: change KABI consistency interface +- !13799 media: av7110: fix a spectre vulnerability +- media: av7110: fix a spectre vulnerability +- !13449 RDMA/hns: Fix bonding failure due to wrong reset_state +- RDMA/hns: Fix bonding failure due to wrong reset_state +- !13407 ima: rot: remove misguiding message printing +- ima: rot: remove misguiding message printing +- !13306 btrfs: fix use-after-free of block device file in __btrfs_free_extra_devids() +- btrfs: fix use-after-free of block device file in __btrfs_free_extra_devids() +- !13308 ext4: don't set SB_RDONLY after filesystem errors +- ext4: don't set SB_RDONLY after filesystem errors +- !13355 NFSD: Initialize struct nfsd4_copy earlier +- NFSD: Initialize struct nfsd4_copy earlier +- !13301 RDMA/bnxt_re: Avoid CPU lockups due fifo occupancy check loop +- RDMA/bnxt_re: Avoid CPU lockups due fifo occupancy check loop +- !13391 mm: split critical region in remap_file_pages() and invoke LSMs in between +- mm: split critical region in remap_file_pages() and invoke LSMs in between +- !13394 mm, slub: avoid zeroing kmalloc redzone +- mm, slub: avoid zeroing kmalloc redzone +- !13400 IMA: Fix hungtask issue of digestlist importing +- IMA: Fix hungtask issue of digestlist importing +- !13370 CVE-2024-46713 +- perf: Fix kabi problem by put mutex in front of perf_buffer +- perf/aux: Fix AUX buffer serialization +- !13376 Some patches for RDMA/hns +- RDMA/hns: Fix RoCEE hang when multiple QP banks use EXT_SGE EXT_SGE +- RDMA/hns: Use one CQ bank per context +- RDMA/hns: Fix the modification of max_send_sge +- RDMA/hns: Fix "Should it be static?" warnings +- RDMA/hns: Fix dereference of noderef expression +- RDMA/hns: Fix list_*_careful() not being used in pairs +- RDMA/hns: Fix a meaningless loop in active_dca_pages_proc() +- RDMA/hns: Fix possible RAS when DCA is not attached +- RDMA/hns: Fix integer overflow in calc_loading_percent() +- RDMA/hns: Fix mixed use of u32 and __le32 in sysfs +- RDMA/hns: Fix concurrency between sysfs store and FW configuration of scc params +- RDMA/hns: Fix wrong output of sysfs scc pram when configuration failed +- RDMA/hns: Fix HW UAF when destroy context timeout +- !13350 mm: replace xa_get_order with xas_get_order where appropriate +- mm: replace xa_get_order with xas_get_order where appropriate +- !12240 [OLK-6.6]Update Mont-TSSE driver +- driver: crypto - update support for Mont-TSSE Driver +- !13345 ocfs2: fix unexpected zeroing of virtual disk +- ocfs2: fix unexpected zeroing of virtual disk +- !13377 selftests: udpgro: no need to load xdp for gro +- selftests: udpgro: no need to load xdp for gro +- !13374 netdevsim: fix rtnetlink.sh selftest +- netdevsim: fix rtnetlink.sh selftest +- !13357 x86/selftests: Skip the tests if prerequisites aren't fulfilled +- x86/selftests: Skip the tests if prerequisites aren't fulfilled +- !13248 [OLK-6.6][Backport] selftests/mount_setattr: fix idmap_mount_tree_invalid failed to run +- selftests/mount_setattr: fix idmap_mount_tree_invalid failed to run +- !13389 RDMA/hns: Fix different dgids mapping to the same dip_idx +- RDMA/hns: Fix different dgids mapping to the same dip_idx +- !13362 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.47-6.6.48 LTS Conflicts Patches +- mm/numa: no task_numa_fault() call if PTE is changed +- mm/numa: no task_numa_fault() call if PMD is changed +- mm: fix endless reclaim on machines with unaccepted memory +- !13148 [OLK-6.6] [Backport] mpt3sas_scsih: don't set QUEUE_FLAG_NOMERGES +- mpt3sas_scsih: don't set QUEUE_FLAG_NOMERGES +- !13372 [OLK-6.6] Support Intel Sierra Forest CPU MAXPHYSADDR and fix KVM_STATS_TYPE_MAX +- KVM: selftests: x86: Prioritize getting max_gfn from GuestPhysBits +- KVM: x86: Advertise max mappable GPA in CPUID.0x80000008.GuestPhysBits +- kvm: fix KVM_STATS_TYPE_MAX +- !13331 MPTCP Upstream part 22 +- selftests: mptcp: use KSFT_SKIP/KSFT_PASS/KSFT_FAIL +- selftests: mptcp: add mptcp_lib_verify_listener_events +- selftests: mptcp: extract mptcp_lib_check_expected +- selftests: mptcp: call test_fail without argument +- selftests: mptcp: print test results with colors +- selftests: mptcp: print test results with counters +- selftests: mptcp: add print_title in mptcp_lib +- selftests: mptcp: export TEST_COUNTER variable +- selftests: mptcp: sockopt: print every test result +- selftests: mptcp: connect: fix misaligned output +- selftests: mptcp: connect: add dedicated port counter +- selftests: mptcp: print all error messages to stdout +- mptcp: annotate a data-race around sysctl_tcp_wmem[0] +- tcp: annotate a data-race around sysctl_tcp_wmem[0] +- !13324 v2 CVE-2023-52920 +- bpf: handle fake register spill to stack with BPF_ST_MEM instruction +- selftests/bpf: add stack access precision test +- bpf: Fix kabi breakage in struct bpf_verifier_state and bpf_verifier_env +- bpf: support non-r10 register spill/fill to/from stack in precision tracking +- !13321 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.61-6.6.62 LTS Patches +- 9p: fix slab cache name creation for real +- mm: krealloc: Fix MTE false alarm in __do_krealloc +- bpf: Check validity of link->type in bpf_link_show_fdinfo() +- net: usb: qmi_wwan: add Fibocom FG132 0x0112 composition +- ASoC: fsl_micfil: Add sample rate constraint +- LoongArch: Use "Exception return address" to comment ERA +- ASoC: rt722-sdca: increase clk_stop_timeout to fix clock stop issue +- RISCV: KVM: use raw_spinlock for critical section in imsic +- HID: lenovo: Add support for Thinkpad X1 Tablet Gen 3 keyboard +- HID: multitouch: Add quirk for Logitech Bolt receiver w/ Casa touchpad +- fs: Fix uninitialized value issue in from_kuid and from_kgid +- ASoC: amd: yc: Fix non-functional mic on ASUS E1404FA +- ASoC: amd: yc: Add quirk for ASUS Vivobook S15 M3502RA +- bpf: Fix mismatched RCU unlock flavour in bpf_out_neigh_v6 +- bpf: Add sk_is_inet and IS_ICSK check in tls_sw_has_ctx_tx/rx +- vDPA/ifcvf: Fix pci_read_config_byte() return code handling +- nvme/host: Fix RCU list traversal to use SRCU primitive +- smb: client: Fix use-after-free of network namespace. +- nvme: make keep-alive synchronous operation +- nvme-loop: flush off pending I/O while shutting down loop controller +- net: phy: mdio-bcm-unimac: Add BCM6846 support +- powerpc/powernv: Free name on error in opal_event_init() +- drm/amdkfd: Accounting pdd vram_usage for svm +- nvme-multipath: defer partition scanning +- RDMA/siw: Add sendpage_ok() check to disable MSG_SPLICE_PAGES +- drm/vmwgfx: Limit display layout ioctl array size to VMWGFX_NUM_DISPLAY_UNITS +- sound: Make CONFIG_SND depend on INDIRECT_IOMEM instead of UML +- crypto: marvell/cesa - Disable hash algorithms +- crypto: api - Fix liveliness check in crypto_alg_tested +- bpf: use kvzmalloc to allocate BPF verifier environment +- nvme: disable CC.CRIME (NVME_CC_CRIME) +- iommu/arm-smmu: Clarify MMU-500 CPRE workaround +- HID: multitouch: Add quirk for HONOR MagicBook Art 14 touchpad +- HID: multitouch: Add support for B2402FVA track point +- block: Fix elevator_get_default() checking for NULL q->tag_set +- nvme: tcp: avoid race between queue_lock lock and destroy +- irqchip/ocelot: Fix trigger register address +- selftests/bpf: Verify that sync_linked_regs preserves subreg_def +- 9p: Avoid creating multiple slab caches with the same name +- 9p: v9fs_fid_find: also lookup by inode if not found dentry +- !13335 net/hinic3: Support New SDK and NIC features +- net/hinic3: Support New SDK and NIC features +- !11561 mm: support large folio swap-out and swap-in for shmem +- mm/pageout: Fix kabi broken in writeback_control +- mm:shmem: Support large folio adjust reliable shmem usage count +- mm: shmem: support large folio swap out +- mm: shmem: split large entry if the swapin folio is not large +- mm: shmem: drop folio reference count using 'nr_pages' in shmem_delete_from_page_cache() +- mm: shmem: support large folio allocation for shmem_replace_folio() +- mm: shmem: use swap_free_nr() to free shmem swap entries +- mm: filemap: use xa_get_order() to get the swap entry order +- mm: shmem: return number of pages beeing freed in shmem_free_swap +- mm: shmem: extend shmem_partial_swap_usage() to support large folio swap +- mm: swap: extend swap_shmem_alloc() to support batch SWAP_MAP_SHMEM flag setting +- mm: swap: add nr argument in swapcache_prepare and swapcache_clear to support large folios +- mm/swapfile:__swap_duplicate: drop redundant WRITE_ONCE on swap_map for err cases +- mm: extend 'usage' parameter so that cluster_swap_free_nr() can be reused +- !13251 MPTCP Upstream part 21 +- selftests: userspace pm: avoid relaunching pm events +- selftests: mptcp: simult flows: fix shellcheck warnings +- selftests: mptcp: pm netlink: fix shellcheck warnings +- selftests: mptcp: sockopt: fix shellcheck warnings +- selftests: mptcp: diag: fix shellcheck warnings +- selftests: mptcp: add mptcp_lib_events helper +- selftests: mptcp: more operations in ns_init/exit +- selftests: mptcp: add mptcp_lib_ns_init/exit helpers +- selftests: mptcp: add local variables rndh +- selftests: mptcp: add mptcp_lib_check_tools helper +- selftests: mptcp: stop forcing iptables-legacy +- !13313 fix ci compile nbl_ethtool.c warning +- Net: nebula_matrix: fix ci compile nbl_ethtool.c warning +- !13129 drm/amd/display: Add null check for pipe_ctx->plane_state in dcn20_program_pipe +- drm/amd/display: Add null check for pipe_ctx->plane_state in dcn20_program_pipe +- !13296 sched/numa: Fix the potential null pointer dereference in task_numa_work() +- sched/numa: Fix the potential null pointer dereference in task_numa_work() +- !13300 ima: fix a compilation error with ima_bprm_creds_for_exec() +- ima: fix a compilation error with ima_bprm_creds_for_exec() +- !13298 bpf, arm64: Fix address emission with tag-based KASAN enabled +- bpf, arm64: Fix address emission with tag-based KASAN enabled +- !13275 CVE-2024-46698 +- firmware: sysfb: Fix reference count of sysfb parent device +- firmware/sysfb: fix an error code in sysfb_init() +- video/aperture: optionally match the device in sysfb_disable() +- firmware/sysfb: Create firmware device only for enabled PCI devices +- firmware/sysfb: Set firmware-framebuffer parent device +- of/platform: Disable sysfb if a simple-framebuffer node is found + + at the end * Tue Nov 19 2024 ZhangPeng - 6.6.0-55.0.0.58 - !13235 nvmet-auth: assign dh_key to NULL after kfree_sensitive - nvmet-auth: assign dh_key to NULL after kfree_sensitive -- Gitee From 8f10123d9fb5eacf82d3c92a2c2dfa4dee8cb2ca Mon Sep 17 00:00:00 2001 From: ZhangPeng Date: Wed, 4 Dec 2024 14:56:26 +0800 Subject: [PATCH 6/8] release 6.6.0-61.0.0 --- SOURCE | 2 +- kernel.spec | 437 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 436 insertions(+), 3 deletions(-) diff --git a/SOURCE b/SOURCE index 8186f4a..d6a3511 100644 --- a/SOURCE +++ b/SOURCE @@ -1 +1 @@ -6.6.0-57.0.0 +6.6.0-61.0.0 diff --git a/kernel.spec b/kernel.spec index 4266d16..787aaca 100644 --- a/kernel.spec +++ b/kernel.spec @@ -40,9 +40,9 @@ rm -f test_openEuler_sign.ko test_openEuler_sign.ko.sig %global upstream_version 6.6 %global upstream_sublevel 0 -%global devel_release 57 +%global devel_release 61 %global maintenance_release .0.0 -%global pkg_release .59 +%global pkg_release .60 %global openeuler_lts 1 %global openeuler_major 2403 @@ -1085,6 +1085,439 @@ fi %endif %changelog +* Wed Dec 04 2024 ZhangPeng - 6.6.0-61.0.0.60 +- !13340 cpufreq: Add SEEP governor for hardware-managed P-states +- ACPI: CPPC: fix bug that causes the value written in cpc register to be wrong. +- cpufreq: Add SEEP governor for hardware-managed P-states +- cpufreq: CPPC: Support for auto act window and energy perf in cppc_cpufreq +- ACPI: CPPC: Add New ABIs for reading and writing three new CPPC registers +- !14004 Support haltpoll feature +- arm64: add config for cpuidle-haltpoll +- arm64/delay: remove USECS_TO_CYCLES to avoid conflict +- cpuidle: edit cpuidle-haltpoll driver module parameter +- arm64: support WFET in smp_cond_relaxed_timeout() +- arm64/delay: add some constants to a separate header +- arm64: support cpuidle-haltpoll +- arm64: idle: export arch_cpu_idle +- cpuidle-haltpoll: condition on ARCH_CPUIDLE_HALTPOLL +- governors/haltpoll: drop kvm_para_available() check +- cpuidle-haltpoll: define arch_haltpoll_want() +- ACPI: processor_idle: Support polling state for LPI +- arm64: add support for polling in idle +- arm64: define TIF_POLLING_NRFLAG +- arm64: barrier: add support for smp_cond_relaxed_timeout() +- Kconfig: move ARCH_HAS_OPTIMIZED_POLL to arch/Kconfig +- cpuidle: rename ARCH_HAS_CPU_RELAX to ARCH_HAS_OPTIMIZED_POLL +- cpuidle/poll_state: poll via smp_cond_load_relaxed_timeout() +- asm-generic: add barrier smp_cond_load_relaxed_timeout() +- !13402 【OLK-6.6】Support SMMU vSVA feature +- arm-smmu-v3: remove limitation of S2FWB or CANWBS +- iommufd: enable SVA when IOPF enabled +- iommufd: Extend IOMMU_GET_HW_INFO to report PASID capability +- iommufd: modify iommufd_fault_iopf_enable limitation +- Enable configs for vSVA tests +- iommu/arm-smmu-v3: Implement arm_smmu_get_msi_mapping_domain +- iommu: Fix kabi breakage due to "iommu/dma: Support MSIs through nested domains" +- iommu/dma: Support MSIs through nested domains +- iommu/arm-smmu-v3: Support IOMMU_HWPT_INVALIDATE using a VIOMMU object +- iommu/arm-smmu-v3: Allow ATS for IOMMU_DOMAIN_NESTED +- iommu/arm-smmu-v3: Use S2FWB for NESTED domains +- iommu/arm-smmu-v3: Support IOMMU_DOMAIN_NESTED +- iommu/arm-smmu-v3: Support IOMMU_VIOMMU_ALLOC +- iommu/arm-smmu-v3: Expose the arm_smmu_attach interface +- iommu/arm-smmu-v3: Implement IOMMU_HWPT_ALLOC_NEST_PARENT +- iommu/arm-smmu-v3: Support IOMMU_GET_HW_INFO via struct arm_smmu_hw_info +- iommu/arm-smmu-v3: Report IOMMU_CAP_ENFORCE_CACHE_COHERENCY for CANWBS +- ACPI/IORT: Support CANWBS memory access flag +- ACPICA: IORT: Update for revision E.f +- iommu: Fix kabi breakage due to "vfio: Remove VFIO_TYPE1_NESTING_IOMMU" +- vfio: Remove VFIO_TYPE1_NESTING_IOMMU +- Documentation: userspace-api: iommufd: Update vDEVICE +- iommufd/selftest: Add vIOMMU coverage for IOMMU_HWPT_INVALIDATE ioctl +- iommufd/selftest: Add IOMMU_TEST_OP_DEV_CHECK_CACHE test command +- iommufd/selftest: Add mock_viommu_cache_invalidate +- iommufd/viommu: Add iommufd_viommu_find_dev helper +- iommu: Add iommu_copy_struct_from_full_user_array helper +- iommufd: Allow hwpt_id to carry viommu_id for IOMMU_HWPT_INVALIDATE +- iommu/viommu: Add cache_invalidate to iommufd_viommu_ops +- iommufd/selftest: Add IOMMU_VDEVICE_ALLOC test coverage +- iommufd/viommu: Add IOMMUFD_OBJ_VDEVICE and IOMMU_VDEVICE_ALLOC ioctl +- Documentation: userspace-api: iommufd: Update vIOMMU +- iommufd/selftest: Add IOMMU_VIOMMU_ALLOC test coverage +- iommufd/selftest: Add IOMMU_VIOMMU_TYPE_SELFTEST +- iommufd/selftest: Add refcount to mock_iommu_device +- iommufd/selftest: Prepare for mock_viommu_alloc_domain_nested() +- iommufd/selftest: Add container_of helpers +- iommufd: Allow pt_id to carry viommu_id for IOMMU_HWPT_ALLOC +- iommufd: Add alloc_domain_nested op to iommufd_viommu_ops +- iommufd/viommu: Add IOMMU_VIOMMU_ALLOC ioctl +- iommufd: Verify object in iommufd_object_finalize/abort() +- iommu: Fix kabi breakage due to "iommufd: Introduce IOMMUFD_OBJ_VIOMMU and its related struct" +- iommufd: Introduce IOMMUFD_OBJ_VIOMMU and its related struct +- iommufd: Move _iommufd_object_alloc helper to a sharable file +- iommufd: Move struct iommufd_object to public iommufd header +- Documentation: userspace-api: iommufd: Update HWPT_PAGING and HWPT_NESTED +- iommu/arm-smmu-v3: add missing MODULE_DESCRIPTION() macro +- iommu/arm-smmu-v3: Convert comma to semicolon +- iommu/arm-smmu-v3: Fix last_sid_idx calculation for sid_bits==32 +- iommu: Move IOMMU_DIRTY_NO_CLEAR define +- iommu/arm-smmu-v3: Fix a NULL vs IS_ERR() check +- iommu/arm-smmu-v3: Remove the unused empty definition +- iommu/arm-smmu-v3: Avoid uninitialized asid in case of error +- iommu: Make iommu_sva_domain_alloc() static +- iommu: Handle iommu faults for a bad iopf setup +- iommufd: Put constants for all the uAPI enums +- iommu/arm-smmu-v3: Use *-y instead of *-objs in Makefile +- iommu/arm-smmu-v3: Make the kunit into a module +- iommu/amd: Introduce get_amd_iommu_from_dev() +- iommufd/device: Enforce reserved IOVA also when attached to hwpt_nested +- iommufd/device: Fix hwpt at err_unresv in iommufd_device_do_replace() +- iommufd: Reorder struct forward declarations +- iommufd: Reorder include files +- iommu/arm-smmu-v3: Reorganize struct arm_smmu_ctx_desc_cfg +- iommu/arm-smmu-v3: Add types for each level of the CD table +- iommu/arm-smmu-v3: Shrink the cdtab l1_desc array +- iommu/arm-smmu-v3: Do not use devm for the cd table allocations +- iommu/arm-smmu-v3: Remove strtab_base/cfg +- iommu/arm-smmu-v3: Reorganize struct arm_smmu_strtab_cfg +- iommu/arm-smmu-v3: Add types for each level of the 2 level stream table +- iommu/arm-smmu-v3: Add arm_smmu_strtab_l1/2_idx() +- iommu/arm-smmu-v3: Use the new rb tree helpers +- iommu/arm-smmu-v3: Shrink the strtab l1_desc array +- iommu/arm-smmu-v3: Do not zero the strtab twice +- iommufd: Fix error pointer checking +- iommufd: Add check on user response code +- iommufd: Remove IOMMUFD_PAGE_RESP_FAILURE +- iommufd/selftest: Add coverage for IOPF test +- iommufd/selftest: Add IOPF support for mock device +- iommufd: Associate fault object with iommufd_hw_pgtable +- iommufd: Fault-capable hwpt attach/detach/replace +- iommu: Fix kabi breakage due to "iommufd: Add iommufd fault object" +- iommufd: Add iommufd fault object +- iommufd: Add fault and response message definitions +- iommu: Extend domain attach group with handle support +- iommu: Fix kabi breakage due to "iommu: Add attach handle to struct iopf_group" +- iommu: Add attach handle to struct iopf_group +- iommu: Fix kabi breakage due to "iommu: Remove sva handle list" +- iommu: Remove sva handle list +- iommu: Introduce domain attachment handle +- iommu/arm-smmu-v3: Enable HTTU for stage1 with io-pgtable mapping +- iommu/arm-smmu-v3: Add support for dirty tracking in domain alloc +- iommu/io-pgtable-arm: Add read_and_clear_dirty() support +- iommu/arm-smmu-v3: Add feature detection for HTTU +- iommu/arm-smmu-v3: Add support for domain_alloc_user fn +- iommu/arm-smmu-v3: Allow setting a S1 domain to a PASID +- iommu/arm-smmu-v3: Allow a PASID to be set when RID is IDENTITY/BLOCKED +- iommu/arm-smmu-v3: Test the STE S1DSS functionality +- iommu/arm-smmu-v3: Allow IDENTITY/BLOCKED to be set while PASID is used +- iommu/arm-smmu-v3: Put the SVA mmu notifier in the smmu_domain +- iommu/arm-smmu-v3: Keep track of arm_smmu_master_domain for SVA +- iommu/arm-smmu-v3: Make SVA allocate a normal arm_smmu_domain +- iommu/arm-smmu-v3: Thread SSID through the arm_smmu_attach_*() interface +- iommu/arm-smmu-v3: Do not use master->sva_enable to restrict attaches +- iommu/arm-smmu-v3: Add ssid to struct arm_smmu_master_domain +- iommu/arm-smmu-v3: Make changing domains be hitless for ATS +- iommu/arm-smmu-v3: Make smmu_domain->devices into an allocated list +- iommu/arm-smmu-v3: Start building a generic PASID layer +- iommu/arm-smmu-v3: Convert to domain_alloc_sva() +- iommu/arm-smmu-v3: Add unit tests for arm_smmu_write_entry +- iommu/arm-smmu-v3: Build the whole CD in arm_smmu_make_s1_cd() +- iommu/arm-smmu-v3: Move the CD generation for SVA into a function +- iommu/arm-smmu-v3: Allocate the CD table entry in advance +- iommu/arm-smmu-v3: Make arm_smmu_alloc_cd_ptr() +- iommu/arm-smmu-v3: Consolidate clearing a CD table entry +- iommu/arm-smmu-v3: Move the CD generation for S1 domains into a function +- iommu/arm-smmu-v3: Make CD programming use arm_smmu_write_entry() +- iommu/arm-smmu-v3: Add an ops indirection to the STE code +- iommu: Fix kabi breakage due to "iommu: Add ops->domain_alloc_sva()" +- iommu: Add ops->domain_alloc_sva() +- iommu/arm-smmu-v3: Add a type for the CD entry +- iommu/arm-smmu-v3: Do not ATC invalidate the entire domain +- iommu/arm-smmu-v3: Do not allow a SVA domain to be set on the wrong PASID +- iommu/arm-smmu-v3: Retire disable_bypass parameter +- iommu: Validate the PASID in iommu_attach_device_pasid() +- iommu/arm-smmu-v3: Add cpu_to_le64() around STRTAB_STE_0_V +- iommu: Fix kabi breakage due to "iommu: Pass domain to remove_dev_pasid() op" +- iommu: Pass domain to remove_dev_pasid() op +- iommu: Undo pasid attachment only for the devices that have succeeded +- iommu: Introduce iommu_group_mutex_assert() +- iommu/arm-smmu-v3: Fix access for STE.SHCFG +- iommu/arm-smmu-v3: Convert to domain_alloc_paging() +- iommu/arm-smmu-v3: Pass arm_smmu_domain and arm_smmu_device to finalize +- iommu/arm-smmu-v3: Use the identity/blocked domain during release +- iommu/arm-smmu-v3: Add a global static BLOCKED domain +- iommu/arm-smmu-v3: Add a global static IDENTITY domain +- iommu/arm-smmu-v3: Check that the RID domain is S1 in SVA +- iommu/arm-smmu-v3: Remove arm_smmu_master->domain +- iommu/arm-smmu-v3: Pass smmu_domain to arm_enable/disable_ats() +- iommu/arm-smmu-v3: Put writing the context descriptor in the right order +- iommu/arm-smmu-v3: Do not change the STE twice during arm_smmu_attach_dev() +- iommu/arm-smmu-v3: Compute the STE only once for each master +- iommu/arm-smmu-v3: Hold arm_smmu_asid_lock during all of attach_dev +- iommu/arm-smmu-v3: Build the whole STE in arm_smmu_make_s2_domain_ste() +- iommu/arm-smmu-v3: Move the STE generation for S1 and S2 domains into functions +- iommu/arm-smmu-v3: Consolidate the STE generation for abort/bypass +- iommu/arm-smmu-v3: Make STE programming independent of the callers +- !14019 afs: Fix lock recursion +- afs: Fix lock recursion +- !13230 xfs: Fix fsmap error +- xfs: Fix missing interval for missing_owner in xfs fsmap +- xfs: use XFS_BUF_DADDR_NULL for daddrs in getfsmap code +- !13977 xfs: split xfs_mod_freecounter +- xfs: split xfs_mod_freecounter +- !14005 v2 Optimize functions like get_user and put_user +- openeuler_defconfig: remove GCC_ASM_GOTO_OUTPUT_WORKAROUND for x86 and arm64 +- arm64: uaccess: correct thinko in __get_mem_asm() +- init/Kconfig: remove CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND +- arm64: start using 'asm goto' for put_user() +- arm64: start using 'asm goto' for get_user() when available +- !14031 Various memory tiering fixes +- memory tiering: count PGPROMOTE_SUCCESS when mem tiering is enabled. +- memory tiering: introduce folio_use_access_time() check +- memory tiering: read last_cpupid correctly in do_huge_pmd_numa_page() +- !14025 ext4: show the default enabled prefetch_block_bitmaps option +- ext4: show the default enabled prefetch_block_bitmaps option +- !13906 [openEuler-24.03-LTS][linux-6.6.y sync] Backport 6.6.53-6.6.54 LTS Conflicts Patches +- btrfs: update comment for struct btrfs_inode::lock +- arm64: errata: Enable the AC03_CPU_38 workaround for ampere1a +- xen: allow mapping ACPI data using a different physical address +- sched/fair: Make SCHED_IDLE entity be preempted in strict hierarchy +- !9158 [OLK-6.6] ata: ahci: Add support for AHCI SGPIO Enclosure Management +- config: enable Zhaoxin AHCI SGPIO driver +- ata: ahci: Add support for AHCI SGPIO Enclosure Management +- !9162 [OLK-6.6] efi: cper: Add Zhaoxin/Centaur ZDI/ZPI error decode +- efi: cper: Add Zhaoxin/Centaur ZDI/ZPI error decode +- !14022 [OLK-6.6] perf/x86/zhaoxin/uncore: fix pci_driver conflict issue +- perf/x86/zhaoxin/uncore: fix pci_driver conflict issue +- !13965 arm64: entry: Fix some warnings when enable nohz full CPU +- arm64: entry: Fix some warnings when enable nohz full CPU +- !13926 genirq/proc: Fix warning of no previous prototype for register_irqchip_proc() +- genirq/proc: Fix warning of no previous prototype for register_irqchip_proc() +- !13993 50164 +- bpf: Remove MEM_UNINIT from skb/xdp MTU helpers +- bpf: Fix kabi breakage in enum bpf_type_flag and bpf_arg_type +- bpf: Fix overloading of MEM_UNINIT's meaning +- bpf: Add MEM_WRITE attribute +- !13951 Fix UAF in __update_blocked_fair +- Fix UAF in __update_blocked_fair +- !13950 Fix SCHED_WARN_ON(cfs_rq->throttled_clock) in throttle_cfs_rq +- Fix SCHED_WARN_ON(cfs_rq->throttled_clock) in throttle_cfs_rq +- !13949 sched/fair: Fix qos_timer deadlock when cpuhp offline +- sched/fair: Fix qos_timer deadlock when cpuhp offline +- !13912 media: dvbdev: fix the logic when DVB_DYNAMIC_MINORS is not set +- media: dvbdev: fix the logic when DVB_DYNAMIC_MINORS is not set +- !13961 ext4: avoid remount errors with 'abort' mount option +- ext4: avoid remount errors with 'abort' mount option +- !13974 arm64: optimize tlb flush +- arm64: optimize flush tlb kernel range +- arm64: tlbflush: add __flush_tlb_range_limit_excess() +- arm64: tlb: Allow range operation for MAX_TLBI_RANGE_PAGES +- arm64: tlbflush: Rename MAX_TLBI_OPS +- !13969 libbpf: Fix output .symtab byte-order during linking +- libbpf: Fix output .symtab byte-order during linking +- !13955 drm/amd/display: Add missing NULL pointer check within dpcd_extend_address_range +- drm/amd/display: Add missing NULL pointer check within dpcd_extend_address_range +- !13913 fix CVE-2024-49861 +- bpf: Fix kabi breakage in enum bpf_type_flag and bpf_arg_type +- bpf: Fix helper writes to read-only maps +- !13317 reset: starfive: jh71x0: Fix accessing the empty member on JH7110 SoC +- reset: starfive: jh71x0: Fix accessing the empty member on JH7110 SoC +- !12279 [OLK-6.6]HYGON: CSV3 patch series part 2 (Support launch, run, migrate CSV3 guest) +- x86/mm: Print CSV3 info into kernel log +- x86: Add support for changing the memory attribute for CSV3 guest +- x86: Update memory shared/private attribute in early boot for CSV3 guest +- x86/kernel: Set bss decrypted memory as shared in CSV3 guest +- x86/kernel: Add CSV3 early update(enc/dec)/reset memory helpers +- x86/boot/compressed/64: Add CSV3 update page attr(private/shared) +- x86/boot/compressed/64: Init CSV3 secure call pages +- x86/boot/compressed/64: Add CSV3 guest detection +- KVM: SVM: CSV: Add ioctl API to unpin shared pages of CSV3 guest +- KVM: SVM: CSV: Add KVM_CSV3_RECEIVE_ENCRYPT_CONTEXT command +- KVM: SVM: CSV: Add KVM_CSV3_RECEIVE_ENCRYPT_DATA command +- KVM: SVM: CSV: Add KVM_CSV3_SEND_ENCRYPT_CONTEXT command +- KVM: SVM: CSV: Add KVM_CSV3_SEND_ENCRYPT_DATA command +- crypto: ccp: Define CSV3 migration command id +- KVM: SVM: CSV: Manage CSV3 guest's nested page table +- KVM: SVM: CSV: Add KVM_CSV3_LAUNCH_ENCRYPT_VMCB command +- KVM: SVM: CSV: Add KVM_CSV3_LAUNCH_ENCRYPT_DATA command +- KVM: SVM: CSV: Add KVM_CSV3_INIT command +- KVM: Define CSV3 key management command id +- !13843 Add support for FEAT_HAFT +- openeuler_defconfig: Add configuration to enable FEAT_HAFT +- arm64: pgtable: Warn unexpected pmdp_test_and_clear_young() +- arm64: Enable ARCH_HAS_NONLEAF_PMD_YOUNG +- arm64: Add support for FEAT_HAFT +- arm64: setup: name 'tcr2' register +- arm64/sysreg: Update ID_AA64MMFR1_EL1 register +- !13889 ipmi: Use regspacings passed as a module parameter +- ipmi: Use regspacings passed as a module parameter +- !13454 [OLK-6.6][Backport] tracing/selftests: Update kprobe args char/string to match new functions +- tracing/selftests: Update kprobe args char/string to match new functions +- !13453 [OLK-6.6][Backport] selftest: net: Fix the problem that run veth.sh failed +- selftests: net: veth: test the ability to independently manipulate GRO and XDP +- selftests: net: veth: test syncing GRO and XDP state while device is down +- !13450 [OLK-6.6][Backport] tools/nolibc: add support for constructors and destructors +- tools/nolibc: add support for constructors and destructors +- !13815 [OLK-6.6][Backport] selftests/intel_pstate: fix operand expected error +- selftests/intel_pstate: fix operand expected error +- !13417 [OLK-6.6][Backport] selftest: net/af_unix: Fix the problem that run test_unix_oob failed +- selftest: af_unix: Fix kselftest compilation warnings +- selftest: af_unix: Add msg_oob.c. +- selftest: af_unix: Remove test_unix_oob.c. +- selftest: af_unix: Add Kconfig file. +- !13806 [OLK-6.6][Backport] selftests/watchdog-test: Fix system accidentally reset after watchdog-test +- selftests/watchdog-test: Fix system accidentally reset after watchdog-test +- !13897 drm/amd/display: Check link_index before accessing dc->links[ +- drm/amd/display: Check link_index before accessing dc->links[] +- !13901 RDMA/hns: Fix accessing invalid dip_ctx during destroying QP +- RDMA/hns: Fix accessing invalid dip_ctx during destroying QP +- !13904 NFSD: Never decrement pending_async_copies on error +- NFSD: Never decrement pending_async_copies on error +- !13888 CVE-2024-49891 +- scsi: lpfc: Validate hdwq pointers before dereferencing in reset/errata paths +- !13894 v2 block: support hierarchy stats +- blk-io-hierarchy: support hierarchy stats for bio lifetime +- blk-io-hierarchy: support new rq based stage rq_driver +- blk-io-hierarchy: support new rq based stage requeue +- blk-io-hierarchy: support new rq based stage hctx +- blk-io-hierarchy: support new rq based stage kyber +- blk-io-hierarchy: support new rq based stage bfq +- blk-io-hierarchy: support new rq based stage mq-deadline +- blk-io-hierarchy: support new rq based stage plug +- blk-io-hierarchy: support new bio based stage gettag +- blk-io-hierarchy: support new bio based stage iocost +- blk-io-hierarchy: support new bio based stage wbt +- block-io-hierarchy: core hierarchy stats and iodump implementation +- block: support to record when request is completed +- block: support to recored bio allocation task in request +- block: support to recored bio allocation time in request +- block: support to recored bio allocation task +- block: support to recored bio allocation time +- block: fix kabi broken after caching ns time in blk_plug +- block: fix that blk_time_get_ns() doesn't update time after schedule +- block: limit block time caching to in_task() context +- block: update cached timestamp post schedule/preemption +- block: cache current nsec time in struct blk_plug +- block: add blk_time_get_ns() and blk_time_get() helpers +- block: move cgroup time handling code into blk.h +- block: skip QUEUE_FLAG_STATS and rq-qos for passthrough io +- blk-io-hierarchy: support hierarchy stats for blk-throttle +- !13851 intel: backport intel_pstate driver update from 6.11 +- cpufreq: intel_pstate: Update Balance performance EPP for Emerald Rapids +- cpufreq: intel_pstate: Support highest performance change interrupt +- cpufreq: intel_pstate: Replace boot_cpu_has() +- x86/cpufeatures: Add HWP highest perf change feature flag +- cpufreq: intel_pstate: Check turbo_is_disabled() in store_no_turbo() +- cpufreq: intel_pstate: Fix unchecked HWP MSR access +- cpufreq: intel_pstate: fix struct cpudata::epp_cached kernel-doc +- cpufreq: intel_pstate: hide unused intel_pstate_cpu_oob_ids[] +- cpufreq: intel_pstate: Update the maximum CPU frequency consistently +- cpufreq: intel_pstate: Replace three global.turbo_disabled checks +- cpufreq: intel_pstate: Read global.no_turbo under READ_ONCE() +- cpufreq: intel_pstate: Rearrange show_no_turbo() and store_no_turbo() +- cpufreq: intel_pstate: Do not update global.turbo_disabled after initialization +- cpufreq: intel_pstate: Fold intel_pstate_max_within_limits() into caller +- cpufreq: intel_pstate: Use __ro_after_init for three variables +- cpufreq: intel_pstate: Get rid of unnecessary READ_ONCE() annotations +- cpufreq: intel_pstate: Wait for canceled delayed work to complete +- cpufreq: intel_pstate: Drop redundant locking from intel_pstate_driver_cleanup() +- cpufreq: intel_pstate: Allow model specific EPPs +- cpufreq: intel_pstate: remove cpudata::prev_cummulative_iowait +- cpufreq: intel_pstate: Add Emerald Rapids support in no-HWP mode +- cpufreq: intel_pstate: Prioritize firmware-provided balance performance EPP +- !13850 intel: backport TPMI uncore frequency driver update from 6.10 +- platform/x86/intel-uncore-freq: Use generic helpers for current frequency +- platform/x86/intel-uncore-freq: Rename the sysfs helper macro names +- platform/x86/intel-uncore-freq: Get rid of uncore_read_freq driver API +- platform/x86/intel-uncore-freq: Use uncore_index with read_control_freq +- platform/x86/intel-uncore-freq: Get rid of magic min_max argument +- platform/x86/intel-uncore-freq: Get rid of magic values +- platform/x86/intel-uncore-freq: Re-arrange bit masks +- platform/x86/intel-uncore-freq: Increase minor number support +- platform/x86/intel-uncore-freq: Process read/write blocked feature status +- platform/x86/intel-uncore-freq: Ignore minor version change +- !13849 intel: backport Intel SST TPMI update from 6.10 +- platform/x86: ISST: Simplify isst_misc_reg() and isst_misc_unreg() +- platform/x86: ISST: Fix return value on last invalid resource +- platform/x86: ISST: Use only TPMI interface when present +- platform/x86: ISST: Avoid some SkyLake server models +- platform/x86: ISST: Add model specific loading for common module +- platform/x86: ISST: fix use-after-free in tpmi_sst_dev_remove() +- platform/x86: ISST: Support SST-BF and SST-TF per level +- platform/x86: ISST: Add missing MODULE_DESCRIPTION +- platform/x86: ISST: Add dev_fmt +- platform/x86: ISST: Use in_range() to check package ID validity +- platform/x86: ISST: Support partitioned systems +- platform/x86: ISST: Shorten the assignments for power_domain_info +- platform/x86: ISST: Use local variable for auxdev->dev +- platform/x86: ISST: Allow reading core-power state on HWP disabled systems +- platform/x86: ISST: Process read/write blocked feature status +- platform/x86: ISST: Ignore minor version change +- platform/x86: intel_speed_select_if: Use devm_ioremap_resource +- platform/x86: intel_speed_select_if: Remove hardcoded map size +- platform/x86: ISST: Allow level 0 to be not present +- platform/x86: ISST: Use fuse enabled mask instead of allowed levels +- !13847 intel: backport tpmi base driver and pmt update from 6.10 to 6.6 +- platform/x86/intel/pmt: telemetry: Export API to read telemetry +- platform/x86/intel/pmt: Add header to struct intel_pmt_entry +- platform/x86/intel/tpmi: Add additional TPMI header fields +- platform/x86/intel/tpmi: Align comments in kernel-doc +- platform/x86/intel/tpmi: Check major version change for TPMI Information +- platform/x86/intel/tpmi: Move TPMI ID definition +- platform/x86/intel/tpmi: Modify external interface to get read/write state +- platform/x86/intel/tpmi: Don't create devices for disabled features +- platform/x86/intel/tpmi: Add debugfs support for read/write blocked +- platform/x86/intel/vsec: Remove nuisance message +- platform/x86/intel/vsec: Add base address field +- platform/x86/intel/vsec: Add intel_vsec_register +- platform/x86/intel/vsec: Assign auxdev parent by argument +- platform/x86/intel/vsec: Use cleanup.h +- platform/x86/intel/vsec: remove platform_info from vsec device structure +- platform/x86/intel/vsec: Move structures to header +- platform/x86/intel/vsec: Remove unnecessary return +- !13880 Fix problems of mounting nfs +- nfs: ignore SB_RDONLY when mounting nfs +- nfs: pass flags to second superblock +- !13822 v4 arm64: Add xcall/xint support +- arm64: Add debugfs dir for xint +- arm64: Introduce Xint software solution +- arm64: Faster SVC exception handler with xcall +- arm64: Introduce xcall a faster svc exception handling +- !13828 crypto: pcrypt - Call crypto layer directly when padata_do_parallel() return -EBUSY +- crypto: pcrypt - Call crypto layer directly when padata_do_parallel() return -EBUSY +- !13805 add ebpf sched +- sched/ebpf: Support task selection programmable +- sched: Add kfunc to get cpu statistics +- bpftool: recognize scheduler programs +- libbpf: add support for scheduler bpf programs +- !13373 acc some patch rounds +- crypto: hisilicon/qm - disable same error report before resetting +- crypto: hisilicon - support querying the capability register +- crypto: hisilicon/qm - fix the coding specifications issue +- crypto: hisilicon/hpre - enable all clusters clock gating +- crypto: hisilicon/sec - Remove trailing space after +- crypto: hisilicon/qm - inject error before stopping queue +- crypto: hisilicon/hpre - mask cluster timeout error +- crypto: hisilicon/qm - reset device before enabling it +- crypto: hisilicon/trng - modifying the order of header files +- crypto: hisilicon - add a lock for the qp send operation +- crypto: hisilicon - fix missed error branch +- crypto: hisilicon/zip - Optimize performance by replacing rw_lock with spinlock +- crypto: hisilicon/zip - optimize the address offset of the reg query function +- crypto: hisilicon/qm - adjust the internal processing sequence of the vf enable and disable +- crypto: hisilicon/sec2 - fix for register offset +- crypto: hisilicon/debugfs - mask the unnecessary info from the dump +- Revert "crypto: hisilicon/qm - reset device before enabling it" +- Revert "crypto: hisilicon/qm - inject error before stopping queue" +- Revert "crypto: hisilicon/qm - modify interrupt processing resource application" +- Revert "crypto: hisilicon/qm - mask error bit before flr" +- Revert "crypto: hisilicon/qm - disable same error report before resetting" +- Revert "crypto: hisilicon/hpre - mask cluster timeout error" +- Revert "crypto: hisilicon/zip - optimize the address offset of the reg query function" +- Revert "crypto: hisilicon/qm - adjust the internal processing sequence of the vf enable and disable" +- Revert "crypto: hisilicon/trng - use %u to print u32 variables" + + newline * Wed Nov 27 2024 ZhangPeng - 6.6.0-57.0.0.59 - !13845 backport some patches from upstream about HCCS low power - soc: hisilicon: kunpeng_hccs: Support low power feature for the specified HCCS type -- Gitee From c07b5b77c465b04dd65215a4c3771e9c814fb156 Mon Sep 17 00:00:00 2001 From: ZhangPeng Date: Wed, 11 Dec 2024 10:03:48 +0800 Subject: [PATCH 7/8] release 6.6.0-64.0.0 --- SOURCE | 2 +- kernel.spec | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 205 insertions(+), 3 deletions(-) diff --git a/SOURCE b/SOURCE index d6a3511..2218ca7 100644 --- a/SOURCE +++ b/SOURCE @@ -1 +1 @@ -6.6.0-61.0.0 +6.6.0-64.0.0 diff --git a/kernel.spec b/kernel.spec index 787aaca..083cea6 100644 --- a/kernel.spec +++ b/kernel.spec @@ -40,9 +40,9 @@ rm -f test_openEuler_sign.ko test_openEuler_sign.ko.sig %global upstream_version 6.6 %global upstream_sublevel 0 -%global devel_release 61 +%global devel_release 64 %global maintenance_release .0.0 -%global pkg_release .60 +%global pkg_release .61 %global openeuler_lts 1 %global openeuler_major 2403 @@ -1085,6 +1085,208 @@ fi %endif %changelog +* Wed Dec 11 2024 ZhangPeng - 6.6.0-64.0.0.61 +- !14106 uacce: some bugfix and cleanup +- migration: modify dfx error type without VM driver +- crypto: hisilicon_qm - fix the uacce_alloc return value check +- crypto: hisilicon_zip - correct the wrong word in the printed information +- uacce: add mutex for check qfr +- uacce: add stop_queue to replace put_queue in ioctl +- uacce: check the qfr address before releasing the qfr +- uacce: add error number for the unsupported mremap +- !14117 mm/page_alloc: Separate THP PCP into movable and non-movable categories +- mm: fix kabi breakage due to struct per_cpu_pages +- mm/page_alloc: Separate THP PCP into movable and non-movable categories +- !14120 bpf: sync_linked_regs() must preserve subreg_def +- bpf: sync_linked_regs() must preserve subreg_def +- !14128 sched: Optimize the latency of select_task_rq and pick_next_task. +- sched: Optimize the latency of select_task_rq and pick_next_task. +- !13991 virtio-fs: introduce multi-queue support +- virtio-fs: add multi-queue support +- virtio-fs: limit number of request queues +- virtiofs: include a newline in sysfs tag +- virtiofs: emit uevents on filesystem events +- virtiofs: export filesystem tags through sysfs +- !14126 [OLK-6.6]perf:Add PMCG platform information for HiSilicon HIP09A +- ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A +- Revert "perf: Add PMCG platform information for HiSilicon HIP09A" +- !14103 nilfs2: fix null-ptr-deref in block_dirty_buffer tracepoint +- nilfs2: fix null-ptr-deref in block_dirty_buffer tracepoint +- !13841 Fix livepatch selftest +- selftests/livepatch: fix selftest execution error +- !14069 MPTCP Upstream part 23 +- tcp: socket option to check for MPTCP fallback to TCP +- mptcp: fix typos in comments +- !13970 LoongArch: fix AVEC related issue +- drivers/irqchip: Disable pci_irq_limit when using AVEC interrupt controller +- irqchip/avec: Support AVEC for 3C6000 multi-node machine +- !13981 LoongArch: backport ptw&set_pte patches from upstream +- LoongArch: Set initial pte entry with PAGE_GLOBAL for kernel space +- LoongArch: Improve hardware page table walker +- LoongArch: Use accessors to page table entries instead of direct dereference +- LoongArch: Remove superfluous flush_dcache_page() definition +- !14107 ata: libata-core: Set ATA_QCFLAG_RTF_FILLED in fill_result_tf() +- ata: libata-core: Set ATA_QCFLAG_RTF_FILLED in fill_result_tf() +- !14101 [sync] PR-14087: v2 drivers/perf: hisi: Add support for HiSilicon DDRC v3 PMU driver +- drivers/perf: hisi: Add support for HiSilicon DDRC v3 PMU driver +- !14095 ima: Fix violation digests extending issue in virtcca +- ima: Fix violation digests extending issue in virtcca +- !14079 v3 irqchip: gic: some bugfix of hip10 +- irqchip/gic-v4.1:Check whether indirect table is supported in allocate_vpe_l1_table +- KVM: arm64: vgic-v3: Fix a issue of hip10 erratum 162200806 +- irqchip/gic-v3: Exclude GICv4.1 for hip10 erratum 162200803 +- !14085 ocfs2: uncache inode which has failed entering the group +- ocfs2: uncache inode which has failed entering the group +- !13837 update patches for sw64 architecture +- sw64: wrap frequency workaround into standalone functions +- sw64: remove redudant save_ktp +- sw64: fix compile warning of smp_callin() +- sw64: distribute intx interrupts by hose +- sw64: acpi: remove constraint that cid of boot core must be zero +- sw64: pci: get register base address from firmware +- sw64: fix compile warning of do_entUna() +- sw64: fix save_ktp compatibility for C3 +- sw64: fix PTBR save/restore for hibernation +- sw64: add syscall pfh_ops +- sw64: fix broken rdfpcr() +- sw64: force kernel stack to be 16 bytes aligned +- sw64: match platform device by acpi method +- sw64: spi: update spi controller driver +- sw64: add -fno-sw-unalign-byte to cflags for C4 +- sw64: define cpu_relax() as imb() +- sw64: fix the .endm in hibernate_asm.S +- sw64: fix compile error of efi.systab +- sw64: pci: adjust the maximum number of RC per node +- sw64: get mclk and external clk from firmware +- sw64: fix compile error of MMSIZE +- sw64: acpi: disable ACPI for xuelang +- sw64: ahci: disable parallel bus scan +- sw64: redesign run mode setup method +- sw64: rename static key and related simd libraries +- sw64: fix secondary cpu bring up bug +- sw64: irq: fix compile error when PINTC or LPC-INTC is not set +- sw64: improve the verification logic of DTB +- sw64: apply new boot params from DTB chosen node +- sw64: receive new boot params from firmware +- sw64: setup stackframe at kernel entry point +- sw64: save and restore CSR_WR_FREGS for SIMD libs +- sw64: rename copy and set lib functions +- sw64: rename copy and set lib files +- sw64: choose lib at compile time +- sw64: store topology and numa info by each cpu itself +- sw64: work around suspend for C4 +- sw64: employ trick on regs.pc for specific exception +- sw64: enable CONFIG_FRAME_POINTER by default for junzhang +- sw64: fix syscall_fallback() for vdso gettimeofday +- sw64: dts: add Junzhang +- sw64: lpc: work around hardware flaws +- sw64: improve cpu bring up method +- sw64: introduce new entry framework for C4 +- sw64: irq: update the initial value of nr_irqs +- sw64: dynamically switch between lib implementation +- sw64: msi: remove redundant interrupt enables +- sw64: add unaligned access support for C4 new instructions +- sw64: acpi: fix missed upper bits of rcid for junzhang +- sw64: pci: remove duplicate pcie operations +- sw64: irq: remove unnecessary initialization +- sw64: acpi: enable generic GSI +- sw64: irqchip: support ACPI-based interrupt controller initialization +- sw64: acpi: support MADT entry print for SW PINTC, MSIC and LPC-INTC +- sw64: acpi: add ACPI-style structures for SW PINTC, MSIC and LPC-INTC +- sw64: fix compilation warning +- sw64: fix kconfig selections +- sw64: use a new wrap_asid hmcall when asid wraps +- sw64: rewrite fpcr and swcr conversion +- sw64: enable hardware denorm by default +- sw64: add four-socket system support +- sw64: add a new kernel parameter to override mclk +- sw64: improve sw64_printk() +- sw64: msi: fix bugs in multi-msi interrupts allocation and release +- sw64: pci: change pci transaction ordering rule settings +- sw64: irqchip: fix virtual PINTC not working properly +- sw64: dts: improve properties for PINTC +- sw64: dts: improve properties for LPC-INTC +- sw64: dts: fix interrupt related properties for GPIO +- sw64: dts: add chosen node +- sw64: dts: fix properties for spi controller device node +- sw64: acpi: fix coding style and typos +- sw64: fix rd_f compatibility issue for C4 +- sw64: refactor device interrupt domain +- sw64: fix macro definition compilation error +- USB: xHCI: fix resume issue of some ZHAOXIN hosts +- USB: Fix ehci infinite suspend-resume loop issue in zhaoxin +- sw64: pci: fix compile error when CONFIG_ACPI=n +- sw64: smp: suppress function setup_smp() when ACPI enabled +- sw64: acpi: parse SW CINTC for SMP initialization +- sw64: acpi: support MADT entry print for SW CINTC +- sw64: acpi: add ACPI-style structures for SW CINTC +- sw64: smp: add new structure to record rcid information +- sw64: smp: modify function smp_rcb_init() to receive base address +- sw64: pci: synchronize the OEM table ID of MCFG with BIOS +- sw64: iommu: fix the bug when vfio_iommu unpin pages +- sw64: use rvpcr() to setup run mode +- sw64: kgdb: add single-step debug support +- sw64: fix lockdep error +- sw64: perf: do all event checks in sw64_pmu_event_init() +- sw64: numa: fix compile error when CONFIG_ACPI_NUMA=n +- sw64: pci: export some pci functions +- sw64: uapi: fix a compile error for headers_install +- sw64: perf: hide hardware performance events in guest os +- sw64: fix hugepage support +- sw64: extern vdso_start and vdso_end as char[] +- sw64: remove useless current_policy +- sw64: add arch-specific SYM_END definition +- !13151 [OLK-6.6] arm64: errata: Unify and expand speculative SSBS workaround +- openeuler_defconfig: Enable CONFIG_ARM64_ERRATUM_3194386 by default +- arm64: Subscribe Microsoft Azure Cobalt 100 to erratum 3194386 +- arm64: errata: Expand speculative SSBS workaround once more +- arm64: errata: Expand speculative SSBS workaround (again) +- arm64: errata: Expand speculative SSBS workaround +- arm64: errata: Unify speculative SSBS errata logic +- arm64: errata: Add workaround for Arm errata 3194386 and 3312417 +- !14091 mm, slab: put should_failslab() back behind CONFIG_SHOULD_FAILSLAB +- mm, page_alloc: put should_fail_alloc_page() back behing CONFIG_FAIL_PAGE_ALLOC +- mm, slab: put should_failslab() back behind CONFIG_SHOULD_FAILSLAB +- !14015 【openEuler 24.03 LTS SP1】SCSI: LeapIO RAID: Support leapioraid RAID controllers +- SCSI: LEAPIORAID: Supports LEAPIO RAID controller +- !14072 Revert "Revert "net: libwx: fix alloc msix vectors failed"" +- Revert "Revert "net: libwx: fix alloc msix vectors failed"" +- !14094 block, bfq: fix bfqq uaf in bfq_limit_depth() +- block, bfq: fix bfqq uaf in bfq_limit_depth() +- !14065 vp_vdpa: fix id_table array not null terminated error +- vp_vdpa: fix id_table array not null terminated error +- !13809 scsi: hisi_sas: Some fixes for hisi_sas +- scsi: sd: Retry START STOP UNIT commands +- scsi: core: Allow passthrough to request midlayer retries +- scsi: hisi_sas: Add latest_dump for the debugfs dump +- scsi: hisi_sas: Create all dump files during debugfs initialization +- scsi: hisi_sas: Update v3 hw STP_LINK_TIMER setting +- scsi: hisi_sas: Add time interval between two H2D FIS following soft reset spec +- scsi: hisi_sas: Update disk locked timeout to 7 seconds +- scsi: hisi_sas: Default enable interrupt coalescing +- scsi: hisi_sas: Add cond_resched() for no forced preemption model +- scsi: hisi_sas: Reset PHY again if phyup timeout +- scsi: hisi_sas: Enable all PHYs that are not disabled by user during controller reset +- scsi: hisi_sas: Add firmware information check +- scsi: hisi_sas: Create trigger_dump at the end of the debugfs initialization +- scsi: hisi_sas: Adjust priority of registering and exiting debugfs for security +- scsi: libsas: Set port when ex_phy is added or deleted +- scsi: libsas: Move sas_add_parent_port() to sas_expander.c +- scsi: libsas: Add helper for port add ex_phy +- !14059 cgroup/bpf: use a dedicated workqueue for cgroup bpf destruction +- cgroup/bpf: use a dedicated workqueue for cgroup bpf destruction +- Revert "cgroup: Fix AA deadlock caused by cgroup_bpf_release" +- !14026 drm/amd/display: Pass non-null to dcn20_validate_apply_pipe_split_flags +- drm/amd/display: Pass non-null to dcn20_validate_apply_pipe_split_flags +- !14056 virtcca feature : security rectification +- virtcca feature : security rectification +- !14012 drm/amdkfd: amdkfd_free_gtt_mem clear the correct pointer +- drm/amdkfd: amdkfd_free_gtt_mem clear the correct pointer +- !14011 drm/amd/display: Check phantom_stream before it is used +- drm/amd/display: Check phantom_stream before it is used +- !14013 maple_tree: correct tree corruption on spanning store +- maple_tree: correct tree corruption on spanning store + * Wed Dec 04 2024 ZhangPeng - 6.6.0-61.0.0.60 - !13340 cpufreq: Add SEEP governor for hardware-managed P-states - ACPI: CPPC: fix bug that causes the value written in cpc register to be wrong. -- Gitee From 5502b4f2a525c907c1ae78ed9ce9ae5142ce992f Mon Sep 17 00:00:00 2001 From: liuzh Date: Thu, 12 Dec 2024 02:59:45 +0000 Subject: [PATCH 8/8] update haoc to 6.6.0-64.0.0 --- 0005-haoc-kernel.patch | 19884 ++++++++++++++++++++++++++++++++------- haoc-kernel.spec | 6 +- 2 files changed, 16427 insertions(+), 3463 deletions(-) diff --git a/0005-haoc-kernel.patch b/0005-haoc-kernel.patch index b8fd07e..d8e1000 100644 --- a/0005-haoc-kernel.patch +++ b/0005-haoc-kernel.patch @@ -1,94 +1,620 @@ -From b84a30c244472627ddbf03ce5f3af67bdcc888ad Mon Sep 17 00:00:00 2001 -From: Liu Zhehui -Date: Wed, 6 Nov 2024 15:28:01 +0800 -Subject: [PATCH] Publish k1 code on 6.6.0-50.0.0 +From edbc49b282f231491cfd4f339146f619a279c3b4 Mon Sep 17 00:00:00 2001 +From: liuzh +Date: Thu, 12 Dec 2024 02:23:00 +0000 +Subject: [PATCH] Publish k1 x86 code on 6.6.0-64.0.0 -internal branch: OLK-6.6-tmp -internal commit: 0ba70cc4 + internal branch: ptdesc-test4 + internal commit: a6789a0 + +Squashed commit of the following: + +commit a6789a09e3fa9be286d772dc1e7e8f8cecf8d6b5 +Author: ljl +Date: Thu Dec 12 10:15:41 2024 +0800 + + Fix for LTP. + +commit 1fd4e20987b6c6cbb30cf857ca2e6ce89e738145 +Author: ljl +Date: Wed Dec 11 16:15:55 2024 +0800 + + Fixed several LTP bug. + +commit d26f046e15cc2f6224b339eed6b624b6d8a66b45 +Author: hubing +Date: Wed Dec 11 14:14:05 2024 +0800 + + : remove x86&arm iee operations related to key_payload_jar + +commit 6f0f94b24bcf67c996be9f74442a120e46d11441 +Author: hubing +Date: Wed Dec 11 11:01:04 2024 +0800 + + : remove redundant code + +commit 55d7e14f18d15d6d560e4d107d56c184a1bbfc44 +Author: sh +Date: Tue Dec 10 14:43:21 2024 +0800 + + : fix pgtable error + +commit 45d4908587bb52d26825b4d0e0246832236abcaa +Author: hubing +Date: Tue Dec 10 18:34:04 2024 +0800 + + : fix iee do_split_huge_pmd error + +commit 3055bc26db78bd6f4770a2619c7688b8de4eb2e2 +Author: hubing +Date: Tue Dec 10 16:21:57 2024 +0800 + + : fix error interface + +commit 10aefe28d915beb3f724648f86b9234ddff9d520 +Author: sh +Date: Sun Dec 8 13:19:57 2024 +0800 + + : fix keyp error + +commit e9371ad52dd582cbb91f90b3c9be4f3727be9611 +Author: sh +Date: Sun Dec 8 12:28:08 2024 +0800 + + : fix iee token error + +commit b4b8435ea87cf2baac3288436d5fe463b72425ee +Author: sh +Date: Fri Dec 6 17:03:34 2024 +0800 + + : fix some pgtable_jar bugs + +commit e665ba7fd4a1386fc1317499d07de8d5c2654f15 +Author: sh +Date: Thu Dec 5 16:13:35 2024 +0800 + + : test page ref count + +commit 18a6edbef9133fa6b0ff74ec5e5b8c010f4683c4 +Author: hubing +Date: Thu Dec 5 12:42:10 2024 +0800 + + : fix error + +commit 34d89b660629a7fb26da1dc411bc28c71f4af53a +Author: hubing +Date: Thu Dec 5 12:10:34 2024 +0800 + + : create ptdesc mapping early + +commit 9d1608096525e009cccd61a94b363a0be3397a8f +Author: hubing +Date: Tue Dec 3 11:39:19 2024 +0800 + + : add wrong detect in pgtable_jar alloc + +commit 6fe858ea9e77220131dc170ef060544281ba1c0f +Author: hubing +Date: Mon Dec 2 19:25:47 2024 +0800 + + : use workqueue to free pgtable_slab + +commit 93275ca7ead7f4398c0508d503dc0cdad8ed1d3b +Merge: 2adab75129e2 00b2de65c06d +Author: bing <73176279+mhubing@users.noreply.github.com> +Date: Mon Nov 25 16:47:23 2024 +0800 + + Merge pull request #22 from mhubing/x86-iee + + : fix pgtable jar error + +commit 00b2de65c06d9cb8c54264bed751cbfaf538219d +Author: sh +Date: Wed Nov 13 16:39:40 2024 +0800 + + : fix pgtable jar error + +commit 2adab75129e2cb2c8d534d484c2e17e5313918e3 +Author: hb +Date: Wed Nov 13 12:52:36 2024 +0800 + + : fix compile error on arm64 + +commit fa0c39508f58d7a2c7fefac781ccca19580a5f03 +Author: hb +Date: Wed Nov 13 11:53:51 2024 +0800 + + fix compile error on arm64 + +commit 1c3eb986bab10b4174d38804e15f13df8c2be1d6 +Author: sh +Date: Wed Nov 13 11:05:01 2024 +0800 + + : do not make task struct pmd order without IEE or KOI + +commit 1878703aca53f095e120519fcca73ce6d68beac5 +Author: hubing +Date: Wed Nov 13 10:55:35 2024 +0800 + + fix x86 kabi error + +commit f452a9c43bedc6f84d494abab9a434f605fa1e83 +Author: clingfei <1599101385@qq.com> +Date: Tue Nov 12 17:35:59 2024 +0800 + + fix compile error on arm64 + +commit cefb321645b885838be0f2e1fe585b9ae1cd0e1e +Author: clingfei <1599101385@qq.com> +Date: Mon Nov 11 21:50:23 2024 +0800 + + fix koi bugs + +commit ff1c84c76755806fd568b626fe0caabb9154af92 +Merge: 51226c4c9c8f b73f99cfd540 +Author: clingfei <1599101385@qq.com> +Date: Mon Nov 11 20:56:08 2024 +0800 + + Merge branch 'koi-dev' of gitee.com:amjac/openeuler-kernel into koi-dev + +commit 51226c4c9c8fc7c485fc94167be9f2ad1b9ac9cc +Author: clingfei <1599101385@qq.com> +Date: Mon Nov 11 20:55:52 2024 +0800 + + fix koi bugs, reset dm-zero, upload rtc-test + +commit b73f99cfd5408ae4a7b0c22a06846fbe2e728362 +Author: sh +Date: Mon Nov 11 17:57:36 2024 +0800 + + : fix token pte order set invalid error + +commit 0126b3abb0ac7837737db4e1f55187b131abf6fc +Author: sh +Date: Mon Nov 11 16:58:44 2024 +0800 + + : fix token unset error + +commit 645b49dba484ab405652d6f61ce56f341a0409a8 +Merge: 0323338ccf30 d957a7d02544 +Author: clingfei <1599101385@qq.com> +Date: Mon Nov 11 16:26:11 2024 +0800 + + Merge branch 'koi-dev' of gitee.com:amjac/openeuler-kernel into koi-dev + +commit d957a7d0254435213c0156508215556dbcdb99b6 +Author: sh +Date: Mon Nov 11 16:25:40 2024 +0800 + + : fix token pte order bugs + +commit 0323338ccf306aa56ecdfb2f5ec9b227664b5f76 +Author: clingfei <1599101385@qq.com> +Date: Mon Nov 11 16:24:12 2024 +0800 + + fix koi bugs, upload dm-zero to be test + +commit 8356e255cc806e0793c1af2706e7300f707b648b +Author: sh +Date: Mon Nov 11 15:37:07 2024 +0800 + + : fix koi bugs + +commit 2678c0e51abfba03ef41709b535b32cff92b52a0 +Author: sh +Date: Mon Nov 11 15:12:20 2024 +0800 + + : fix x86 koi task_struct free slab error + +commit 3055f48dcaa3b88a8c7c23fa1a2d7797ea6dd972 +Author: clingfei <1599101385@qq.com> +Date: Mon Nov 11 14:38:57 2024 +0800 + + fix error when koi and iee both enabled + +commit 0f084fceb5ee53db528aa0e5cf0978895e355483 +Author: sh +Date: Mon Nov 11 14:14:05 2024 +0800 + + : fix koi task_struct pmd huge order + +commit 97db04a068206b8459778ea89995162578557977 +Author: clingfei <1599101385@qq.com> +Date: Mon Nov 11 13:38:42 2024 +0800 + + updatre + +commit 5e0c7fd2197529199598e19a63ffb322157a52e6 +Merge: a0a616796b25 b529796aa493 +Author: clingfei <1599101385@qq.com> +Date: Mon Nov 11 13:15:36 2024 +0800 + + Merge branch 'dev-k1' into koi-dev + +commit b529796aa493c0936520bf9b8821996a2f79ac47 +Author: sh +Date: Mon Nov 11 13:13:18 2024 +0800 + + : support IEE_SWITCH_TO_KOI and IEE_SWITCH_TO_KERNEL + +commit a0a616796b25bd62828e3eea7c4ea0ec9ed64766 +Author: clingfei <1599101385@qq.com> +Date: Mon Nov 11 12:55:52 2024 +0800 + + add support for koi on x86_64 + +commit ccbe2ee8cc5e26ea8d036899bf528008d5b56604 +Author: sh +Date: Fri Nov 8 15:33:33 2024 +0800 + + : fix euler base compile error about ptdesc->ptl + +commit 55e5d4a1c582e56d2f824c0d3a878fb03c243efe +Author: sh +Date: Thu Nov 7 14:28:43 2024 +0800 + + : support x86 IEE PTP CREDP SELINUXP KEYP + +commit ced5a9bdac14732a8b013b8bbbb28ea917fa0499 +Author: ljl +Date: Fri Nov 8 01:58:30 2024 +0000 + + Fixed memory leak and make it compatitable with kfence. + +commit 60c0e75fd8197df86a1d08ad777ab59569d80e30 +Author: sh +Date: Wed Nov 6 19:42:45 2024 +0800 + + : fix compile error + +commit 4ccfc605a3fcb9cbe0a92d5e0d112bf97d790716 +Author: Shukai Ni +Date: Wed Nov 6 14:33:28 2024 +0800 + + Disable reg as offset for ARM + + (cherry picked from commit 9da147470dbc027d5fc790bbe525fa0600ab26d7) + Signed-off-by: Liu Zhehui + +commit f4a1dc53648f74a4384351fc952fcd777e053bec +Author: mxy +Date: Mon Oct 14 10:03:24 2024 +0800 + + migrate x86 finished, squashed as a commit + + (cherry picked from commit c76414f15be0568ab24117fd9c40a10c1fe4365a) + Signed-off-by: Liu Zhehui + +commit 793e90e299ac37f6005612f00a6731de496c97f2 +Author: mxy <1356464784@qq.com> +Date: Mon Sep 16 02:14:28 2024 +0000 + + merge debug-skip-instrument + + Squashed commit of the following: + + commit cce53b70fab4597a907e01de1c1bbc068b90eea1 + Author: mxy <1356464784@qq.com> + Date: Mon Sep 16 02:08:11 2024 +0000 + + remove debug output + + commit d9f3416e921d1f4fe2e6b0f9fabc9102d5d31daf + Author: mxy <1356464784@qq.com> + Date: Sun Sep 15 20:00:07 2024 +0800 + + fix percpu alloc failure + + commit 77211a6ba632b4fdacd960b544cc8f93dbe67ca5 + Author: mxy <1356464784@qq.com> + Date: Tue Sep 10 10:50:32 2024 +0000 + + add: if bpf prog has map not supported by HIVE, run without HIVE patched + + commit 252681723a6e40739dada7472082bc04086daa82 + Author: mxy <1356464784@qq.com> + Date: Tue Sep 10 10:43:17 2024 +0000 + + fix: cannot use BPF_ST | BPF_REG + + commit e67c0674738778a6aa3d3ff4f341625fcba916ca + Author: mxy <1356464784@qq.com> + Date: Tue Sep 10 10:38:57 2024 +0000 + + remove: unused debug output + + commit d546b713725692137c1912c8089752e1b4ed3d34 + Author: mxy <1356464784@qq.com> + Date: Tue Sep 10 10:32:02 2024 +0000 + + fix: percpu htab run code to free normal htab + + commit 964d66c9c91c9656cf1f28d6ab17ebd29433ae3d + Author: mxy <1356464784@qq.com> + Date: Tue Sep 10 02:10:34 2024 +0000 + + fix: check list is not empty + + (cherry picked from commit 7ed3883a03f9996951129a98f572570dfa11f21a) + Signed-off-by: Liu Zhehui + +commit fbdcac8fcfabcf4942b0e77f9b1e50dcfa442365 +Author: mxy <1356464784@qq.com> +Date: Mon Sep 9 19:07:38 2024 +0800 + + fix BPF_ST | BPF_REG, and free value when !percpu + + (cherry picked from commit 117e5e3e6a563267ff35145449a70fe15bbd7eb3) + Signed-off-by: Liu Zhehui + +commit 41826d2b3c97fa48b0a4dbe677c7f167f21bc4b3 +Author: mxy <1356464784@qq.com> +Date: Fri Sep 6 18:36:05 2024 +0000 + + modify: if map or mode is not supported (return -ENOTSUPP), just return to normal bpf + + (cherry picked from commit 14df0ccb205549dd57eceb3257d72aecdabfc9ba) + Signed-off-by: Liu Zhehui + +commit 8ade36209feb0bb08d731789225ec7f1d541a782 +Author: mxy <1356464784@qq.com> +Date: Sat Sep 7 01:42:36 2024 +0800 + + migrate bpf 3/3, instrument compartmentalization instructions + + (cherry picked from commit c57c668472a28addf4f84053edde568796a8f178) + Signed-off-by: Liu Zhehui + +commit 990e378c713e95e127d23ddf45cce1e39cd4efa4 +Author: mxy <1356464784@qq.com> +Date: Fri Sep 6 21:52:01 2024 +0800 + + tracex3 exec successfully + + rebase commit log + + (cherry picked from commit 1e986593ba59d4fe0454c00ee6a04f0fa08787e1) + Signed-off-by: Liu Zhehui + +commit c981142f088b70284f0769d66bd7b05e3cca69c4 +Author: mxy +Date: Fri Sep 6 12:38:01 2024 +0000 + + sockex2 exec successfully + + (cherry picked from commit 89eb822666024e701a1d1e3b0d2a22beadaacb54) + Signed-off-by: Liu Zhehui + +commit 63fa9555bf928d5f7b189902e31751414ab9314c +Author: mxy +Date: Fri Sep 6 06:40:43 2024 +0000 + + sockex1 exec successfully + + (cherry picked from commit 67367f40790053ef26314cdb700aa3536d3e72b9) + Signed-off-by: Liu Zhehui + +commit e7f8090caf0379927e839e5b0e3cdf6a10cdd249 +Author: mxy <1356464784@qq.com> +Date: Sun Sep 1 12:09:02 2024 +0800 + + parent 6a788040ad103aac5cf795e1fe6bb39ac046e0e4 + author mxy <1356464784@qq.com> 1725163742 +0800 + committer mxy 1725646109 +0000 + + migrate bpf 2/n, aggregate bpf memory + + add debug output + + fix wrong pgdp + + fix wrong mask + + fix missing of huge page + + remove unsupport compiler feature on aarch64 + + fix wrong pgdp + + fix wrong mask + + fix: use page_address() + + test addr is legal + + need to process huge page + + debugging: use vmalloc to avoid allocate huge page + + fix wrong free and addr mask + + debugging: using __vmalloc to avoid huge page + + debugging: find addr differ between count_all_pages() and map_physic_pages + (cherry picked from commit ba8a7b560d72cfdc304fbf017e0d92eb7e77287e) + Signed-off-by: Liu Zhehui + +commit 341e9150002c212a0d190a56995eb23e48ac1084 +Author: mxy <1356464784@qq.com> +Date: Fri Aug 30 13:02:48 2024 +0800 + + migrate bpf 1/n, arch specific code + + fix missing of huge page + + remove unsupport compiler feature on aarch64 + + (cherry picked from commit 6a788040ad103aac5cf795e1fe6bb39ac046e0e4) + Signed-off-by: Liu Zhehui + +commit 8dd84d3838379079eccbd79720b7ffa1bac53e30 +Author: mxy <1356464784@qq.com> +Date: Fri Aug 30 09:25:20 2024 +0800 + + migrate bpf 0/n, add config HIVE + + (cherry picked from commit d4c5039ec21638bab14801ec65f7e3606e6d36c2) + Signed-off-by: Liu Zhehui + +commit cd9395e25a2a4ac97138eea92b15a9a435d262a1 +Author: Liu Zhehui +Date: Wed Nov 6 15:28:01 2024 +0800 + + Publish k1 code on 6.6.0-48.0.0 + + internal branch: OLK-6.6-tmp + internal commit: 0ba70cc4 --- .gitignore | 4 + - Makefile | 4 +- + Makefile | 7 + arch/arm64/Kconfig | 35 + - arch/arm64/configs/openeuler_defconfig | 8 +- + arch/arm64/configs/openeuler_defconfig | 9 +- arch/arm64/include/asm/assembler.h | 67 + arch/arm64/include/asm/daifflags.h | 16 + arch/arm64/include/asm/efi.h | 4 + arch/arm64/include/asm/fixmap.h | 3 + arch/arm64/include/asm/hw_breakpoint.h | 12 + - arch/arm64/include/asm/iee-access.h | 47 + + arch/arm64/include/asm/iee-access.h | 46 + arch/arm64/include/asm/iee-cred.h | 150 ++ - arch/arm64/include/asm/iee-def.h | 37 + - arch/arm64/include/asm/iee-key.h | 154 ++ + arch/arm64/include/asm/iee-def.h | 130 ++ + arch/arm64/include/asm/iee-key.h | 149 ++ + arch/arm64/include/asm/iee-koi.h | 13 + arch/arm64/include/asm/iee-selinuxp.h | 27 + - arch/arm64/include/asm/iee-si.h | 65 + + arch/arm64/include/asm/iee-si.h | 61 + arch/arm64/include/asm/iee-slab.h | 23 + - arch/arm64/include/asm/iee-token.h | 34 + + arch/arm64/include/asm/iee-token.h | 33 + arch/arm64/include/asm/iee.h | 10 + arch/arm64/include/asm/kernel-pgtable.h | 21 + - arch/arm64/include/asm/koi.h | 531 +++++ + arch/arm64/include/asm/koi.h | 532 +++++ arch/arm64/include/asm/memory.h | 28 + arch/arm64/include/asm/mmu_context.h | 20 + arch/arm64/include/asm/pgalloc.h | 4 + - arch/arm64/include/asm/pgtable-hwdef.h | 11 + + arch/arm64/include/asm/pgtable-hwdef.h | 14 + arch/arm64/include/asm/pgtable.h | 191 +- arch/arm64/include/asm/pgtable_slab.h | 8 + arch/arm64/include/asm/pointer_auth.h | 5 + arch/arm64/include/asm/stack_slab.h | 8 + arch/arm64/include/asm/sysreg.h | 58 + arch/arm64/include/asm/tlb.h | 20 + - arch/arm64/include/asm/tlbflush.h | 58 +- - arch/arm64/kernel/Makefile | 2 + + arch/arm64/include/asm/tlbflush.h | 56 +- + arch/arm64/kernel/Makefile | 3 + arch/arm64/kernel/armv8_deprecated.c | 16 + arch/arm64/kernel/asm-offsets.c | 13 + arch/arm64/kernel/cpu_errata.c | 12 + - arch/arm64/kernel/cpufeature.c | 79 + + arch/arm64/kernel/cpufeature.c | 80 + arch/arm64/kernel/debug-monitors.c | 4 + arch/arm64/kernel/entry-common.c | 4 + - arch/arm64/kernel/entry.S | 625 +++++- + arch/arm64/kernel/entry.S | 623 +++++- arch/arm64/kernel/fpsimd.c | 4 + arch/arm64/kernel/head.S | 5 + arch/arm64/kernel/hibernate.c | 9 + arch/arm64/kernel/hw_breakpoint.c | 99 + arch/arm64/kernel/iee/Makefile | 5 + - arch/arm64/kernel/iee/iee-func.c | 720 +++++++ + arch/arm64/kernel/iee/iee-func.c | 722 +++++++ arch/arm64/kernel/iee/iee-gate.S | 314 +++ - arch/arm64/kernel/iee/iee-key.c | 12 + arch/arm64/kernel/iee/iee-pgtable.c | 402 ++++ arch/arm64/kernel/iee/iee-selinuxp.c | 36 + - arch/arm64/kernel/iee/iee.c | 1734 ++++++++++++++++ - arch/arm64/kernel/iee/pgtable_slab.c | 97 + + arch/arm64/kernel/iee/iee.c | 1720 +++++++++++++++ + arch/arm64/kernel/iee/pgtable_slab.c | 107 + arch/arm64/kernel/iee/stack_slab.c | 19 + arch/arm64/kernel/irq.c | 4 +- arch/arm64/kernel/koi/Makefile | 1 + - arch/arm64/kernel/koi/koi.c | 1688 ++++++++++++++++ + arch/arm64/kernel/koi/koi.c | 1688 +++++++++++++++ arch/arm64/kernel/mte.c | 5 + arch/arm64/kernel/process.c | 13 +- arch/arm64/kernel/proton-pack.c | 8 + arch/arm64/kernel/setup.c | 34 + + arch/arm64/kernel/sfi_bpf_arch.c | 85 + arch/arm64/kernel/traps.c | 26 + - arch/arm64/kernel/vmlinux.lds.S | 60 + + arch/arm64/kernel/vmlinux.lds.S | 55 + arch/arm64/mm/context.c | 125 +- - arch/arm64/mm/fault.c | 13 + - arch/arm64/mm/fixmap.c | 74 +- - arch/arm64/mm/init.c | 36 + - arch/arm64/mm/mmu.c | 1786 +++++++++++++++-- - arch/arm64/mm/pgd.c | 30 + + arch/arm64/mm/fault.c | 28 + + arch/arm64/mm/fixmap.c | 75 +- + arch/arm64/mm/init.c | 40 + + arch/arm64/mm/mmu.c | 1916 +++++++++++++++-- + arch/arm64/mm/pgd.c | 32 + arch/arm64/mm/proc.S | 8 + - arch/arm64/mm/trans_pgd.c | 36 + + arch/arm64/mm/trans_pgd.c | 25 +- + arch/arm64/net/bpf_jit_comp.c | 105 + + arch/x86/Kconfig | 25 + + arch/x86/boot/compressed/ident_map_64.c | 34 + + arch/x86/boot/compressed/pgtable_64.c | 4 + + arch/x86/entry/entry_64.S | 53 + + arch/x86/include/asm/desc.h | 18 + + arch/x86/include/asm/fixmap.h | 5 + + arch/x86/include/asm/iee-access.h | 39 + + arch/x86/include/asm/iee-cred.h | 148 ++ + arch/x86/include/asm/iee-def.h | 124 ++ + arch/x86/include/asm/iee-key.h | 147 ++ + arch/x86/include/asm/iee-koi.h | 5 + + arch/x86/include/asm/iee-selinuxp.h | 26 + + arch/x86/include/asm/iee-si.h | 25 + + arch/x86/include/asm/iee-slab.h | 21 + + arch/x86/include/asm/iee-token.h | 32 + + arch/x86/include/asm/iee.h | 5 + + arch/x86/include/asm/koi.h | 432 ++++ + arch/x86/include/asm/page.h | 20 + + arch/x86/include/asm/page_64.h | 4 + + arch/x86/include/asm/page_types.h | 7 + + arch/x86/include/asm/pgalloc.h | 73 + + arch/x86/include/asm/pgtable.h | 77 +- + arch/x86/include/asm/pgtable_64.h | 119 + + arch/x86/include/asm/pgtable_64_types.h | 5 + + arch/x86/include/asm/pgtable_slab.h | 10 + + arch/x86/include/asm/special_insns.h | 15 + + arch/x86/include/asm/stack_slab.h | 8 + + arch/x86/include/asm/tlb.h | 6 + + arch/x86/kernel/Makefile | 5 + + arch/x86/kernel/asm-offsets.c | 6 + + arch/x86/kernel/cpu/common.c | 20 + + arch/x86/kernel/espfix_64.c | 14 + + arch/x86/kernel/head64.c | 20 + + arch/x86/kernel/idt.c | 11 +- + arch/x86/kernel/iee/Makefile | 5 + + arch/x86/kernel/iee/iee-func.c | 353 +++ + arch/x86/kernel/iee/iee-gate.S | 209 ++ + arch/x86/kernel/iee/iee-selinuxp.c | 36 + + arch/x86/kernel/iee/iee.c | 1080 ++++++++++ + arch/x86/kernel/iee/pgtable-slab.c | 169 ++ + arch/x86/kernel/iee/stack-slab.c | 20 + + arch/x86/kernel/koi/Makefile | 1 + + arch/x86/kernel/koi/koi.c | 1414 ++++++++++++ + arch/x86/kernel/ldt.c | 4 + + arch/x86/kernel/machine_kexec_64.c | 40 +- + arch/x86/kernel/paravirt.c | 4 + + arch/x86/kernel/setup.c | 177 ++ + arch/x86/kernel/sfi_bpf_arch.c | 85 + + arch/x86/kernel/vmlinux.lds.S | 78 + + arch/x86/mm/fault.c | 3 + + arch/x86/mm/ident_map_for_iee.c | 197 ++ + arch/x86/mm/init.c | 659 ++++++ + arch/x86/mm/init_64.c | 341 +++ + arch/x86/mm/ioremap.c | 37 + + arch/x86/mm/kaslr.c | 16 + + arch/x86/mm/mm_internal.h | 9 + + arch/x86/mm/pat/set_memory.c | 72 +- + arch/x86/mm/pgtable.c | 75 + + arch/x86/mm/pti.c | 52 + + arch/x86/net/bpf_jit_comp.c | 62 + + arch/x86/platform/efi/efi_64.c | 25 + + arch/x86/power/hibernate_64.c | 18 + + arch/x86/xen/mmu_pv.c | 6 + block/sed-opal.c | 8 + certs/blacklist.c | 8 + certs/system_keyring.c | 18 + crypto/af_alg.c | 16 + - crypto/asymmetric_keys/asymmetric_type.c | 21 + + crypto/asymmetric_keys/asymmetric_type.c | 20 + crypto/asymmetric_keys/public_key.c | 16 + crypto/asymmetric_keys/signature.c | 10 + drivers/firmware/efi/arm-runtime.c | 4 + drivers/firmware/efi/memmap.c | 20 + + drivers/iommu/amd/io_pgtable.c | 4 + drivers/md/Makefile | 1 + drivers/md/dm-crypt.c | 20 + drivers/md/dm-verity-verify-sig.c | 8 + + drivers/md/dm-zero.c | 2 +- drivers/nvdimm/security.c | 24 + drivers/rtc/rtc-test.c | 2 +- + drivers/rtc/rtc-test_glue.h | 13 + drivers/tty/serial/earlycon.c | 4 + drivers/usb/early/ehci-dbgp.c | 4 + fs/coredump.c | 8 + @@ -107,8 +633,8 @@ internal commit: 0ba70cc4 fs/open.c | 26 + fs/overlayfs/dir.c | 9 + fs/overlayfs/super.c | 12 + - fs/smb/client/cifs_spnego.c | 30 + - fs/smb/client/cifsacl.c | 52 + + fs/smb/client/cifs_spnego.c | 29 + + fs/smb/client/cifsacl.c | 50 + fs/smb/client/connect.c | 8 + fs/smb/client/sess.c | 4 + fs/smb/client/smb2pdu.c | 4 + @@ -116,27 +642,42 @@ internal commit: 0ba70cc4 fs/verity/signature.c | 4 + include/asm-generic/early_ioremap.h | 3 + include/asm-generic/fixmap.h | 18 + + include/asm-generic/memory_model.h | 20 + include/asm-generic/pgalloc.h | 7 + - include/asm-generic/tlb.h | 7 + + include/asm-generic/pgtable-nop4d.h | 5 + + include/asm-generic/tlb.h | 26 +- include/asm-generic/vmlinux.lds.h | 34 +- include/keys/asymmetric-subtype.h | 4 + include/keys/asymmetric-type.h | 8 + include/keys/request_key_auth-type.h | 4 + - include/linux/cred.h | 46 +- + include/linux/bpf.h | 18 + + include/linux/bpf_verifier.h | 19 + + include/linux/cred.h | 45 +- include/linux/efi.h | 9 + - include/linux/iee-flag.h | 116 ++ - include/linux/iee-func.h | 35 + - include/linux/key.h | 83 + - include/linux/mm.h | 103 + + include/linux/filter.h | 3 + + include/linux/iee-func.h | 31 + + include/linux/key.h | 86 + + include/linux/mm.h | 59 + include/linux/mm_types.h | 39 + include/linux/module.h | 1 + + include/linux/pgtable.h | 32 + include/linux/sched.h | 19 + - init/main.c | 31 +- - kernel/cred.c | 186 ++ - kernel/exit.c | 7 + - kernel/fork.c | 286 +-- + include/linux/sfi_bpf.h | 86 + + include/linux/skbuff.h | 3 + + include/uapi/linux/bpf.h | 1 + + include/uapi/linux/bpf_common.h | 1 + + init/main.c | 32 +- + kernel/bpf/Kconfig | 11 + + kernel/bpf/Makefile | 2 + + kernel/bpf/arraymap.c | 194 +- + kernel/bpf/hashtab.c | 323 ++- + kernel/bpf/sfi_bpf.c | 1387 ++++++++++++ + kernel/bpf/verifier.c | 360 +++- + kernel/cred.c | 184 ++ + kernel/exit.c | 8 + + kernel/fork.c | 284 ++- kernel/groups.c | 7 + - kernel/kthread.c | 11 + + kernel/kthread.c | 12 + kernel/module/main.c | 105 +- kernel/sys.c | 107 + kernel/umh.c | 10 + @@ -146,29 +687,31 @@ internal commit: 0ba70cc4 mm/damon/ops-common.c | 1 + mm/debug_vm_pgtable.c | 32 + mm/early_ioremap.c | 57 + - mm/huge_memory.c | 10 +- + mm/huge_memory.c | 26 +- mm/hugetlb_vmemmap.c | 2 +- mm/init-mm.c | 16 + - mm/memory.c | 71 + - mm/mmap.c | 8 + - mm/mmu_gather.c | 117 ++ - mm/pgtable-generic.c | 28 + - mm/slab.h | 27 + - mm/slab_common.c | 35 + - mm/slub.c | 407 +++- + mm/memory.c | 14 + + mm/mmap.c | 14 + + mm/mmu_gather.c | 176 ++ + mm/pgtable-generic.c | 29 + + mm/slab.h | 39 +- + mm/slab_common.c | 39 + + mm/slub.c | 604 +++++- mm/sparse-vmemmap.c | 12 + mm/vmalloc.c | 2 +- net/ceph/ceph_common.c | 4 + net/ceph/crypto.c | 4 + + net/core/filter.c | 18 +- net/dns_resolver/dns_key.c | 24 + net/dns_resolver/dns_query.c | 18 + net/rxrpc/af_rxrpc.c | 4 + net/rxrpc/conn_event.c | 5 + net/rxrpc/key.c | 16 + - net/rxrpc/rxkad.c | 41 + + net/rxrpc/rxkad.c | 40 + net/rxrpc/security.c | 8 + net/rxrpc/sendmsg.c | 4 + net/rxrpc/server_key.c | 8 + + net/sched/cls_bpf.c | 78 + security/commoncap.c | 169 ++ security/integrity/evm/evm_crypto.c | 12 + security/keys/big_key.c | 16 + @@ -177,15 +720,15 @@ internal commit: 0ba70cc4 .../keys/encrypted-keys/masterkey_trusted.c | 5 + security/keys/gc.c | 52 + security/keys/internal.h | 8 + - security/keys/key.c | 233 ++- + security/keys/key.c | 237 +- security/keys/keyctl.c | 91 + - security/keys/keyring.c | 264 +++ + security/keys/keyring.c | 269 +++ security/keys/proc.c | 28 + security/keys/process_keys.c | 88 + security/keys/request_key.c | 16 + security/keys/request_key_auth.c | 20 + security/keys/trusted-keys/trusted_core.c | 8 + - security/keys/user_defined.c | 10 + + security/keys/user_defined.c | 12 + security/security.c | 15 + security/selinux/hooks.c | 60 + security/selinux/ima.c | 20 + @@ -194,11 +737,12 @@ internal commit: 0ba70cc4 security/selinux/ss/services.c | 56 + security/selinux/status.c | 32 + security/smack/smack_lsm.c | 12 + - 188 files changed, 13637 insertions(+), 345 deletions(-) + 273 files changed, 23512 insertions(+), 373 deletions(-) create mode 100644 arch/arm64/include/asm/iee-access.h create mode 100644 arch/arm64/include/asm/iee-cred.h create mode 100644 arch/arm64/include/asm/iee-def.h create mode 100644 arch/arm64/include/asm/iee-key.h + create mode 100644 arch/arm64/include/asm/iee-koi.h create mode 100644 arch/arm64/include/asm/iee-selinuxp.h create mode 100644 arch/arm64/include/asm/iee-si.h create mode 100644 arch/arm64/include/asm/iee-slab.h @@ -210,7 +754,6 @@ internal commit: 0ba70cc4 create mode 100644 arch/arm64/kernel/iee/Makefile create mode 100644 arch/arm64/kernel/iee/iee-func.c create mode 100644 arch/arm64/kernel/iee/iee-gate.S - create mode 100644 arch/arm64/kernel/iee/iee-key.c create mode 100644 arch/arm64/kernel/iee/iee-pgtable.c create mode 100644 arch/arm64/kernel/iee/iee-selinuxp.c create mode 100644 arch/arm64/kernel/iee/iee.c @@ -218,8 +761,35 @@ internal commit: 0ba70cc4 create mode 100644 arch/arm64/kernel/iee/stack_slab.c create mode 100644 arch/arm64/kernel/koi/Makefile create mode 100644 arch/arm64/kernel/koi/koi.c - create mode 100644 include/linux/iee-flag.h + create mode 100644 arch/arm64/kernel/sfi_bpf_arch.c + create mode 100644 arch/x86/include/asm/iee-access.h + create mode 100644 arch/x86/include/asm/iee-cred.h + create mode 100644 arch/x86/include/asm/iee-def.h + create mode 100644 arch/x86/include/asm/iee-key.h + create mode 100644 arch/x86/include/asm/iee-koi.h + create mode 100644 arch/x86/include/asm/iee-selinuxp.h + create mode 100644 arch/x86/include/asm/iee-si.h + create mode 100644 arch/x86/include/asm/iee-slab.h + create mode 100644 arch/x86/include/asm/iee-token.h + create mode 100644 arch/x86/include/asm/iee.h + create mode 100644 arch/x86/include/asm/koi.h + create mode 100644 arch/x86/include/asm/pgtable_slab.h + create mode 100644 arch/x86/include/asm/stack_slab.h + create mode 100644 arch/x86/kernel/iee/Makefile + create mode 100644 arch/x86/kernel/iee/iee-func.c + create mode 100644 arch/x86/kernel/iee/iee-gate.S + create mode 100644 arch/x86/kernel/iee/iee-selinuxp.c + create mode 100644 arch/x86/kernel/iee/iee.c + create mode 100644 arch/x86/kernel/iee/pgtable-slab.c + create mode 100644 arch/x86/kernel/iee/stack-slab.c + create mode 100644 arch/x86/kernel/koi/Makefile + create mode 100644 arch/x86/kernel/koi/koi.c + create mode 100644 arch/x86/kernel/sfi_bpf_arch.c + create mode 100644 arch/x86/mm/ident_map_for_iee.c + create mode 100644 drivers/rtc/rtc-test_glue.h create mode 100644 include/linux/iee-func.h + create mode 100644 include/linux/sfi_bpf.h + create mode 100644 kernel/bpf/sfi_bpf.c diff --git a/.gitignore b/.gitignore index d1a8ab3f98aa..f87d7b8380ab 100644 @@ -241,32 +811,35 @@ index d1a8ab3f98aa..f87d7b8380ab 100644 +#command +command.txt diff --git a/Makefile b/Makefile -index ee377cec01f3..d36eeeb0c9a8 100644 +index ee377cec01f3..7b354f051344 100644 --- a/Makefile +++ b/Makefile -@@ -554,7 +554,7 @@ LINUXINCLUDE := \ - -I$(objtree)/include \ +@@ -555,6 +555,9 @@ LINUXINCLUDE := \ $(USERINCLUDE) --KBUILD_AFLAGS := -D__ASSEMBLY__ -fno-PIE -+KBUILD_AFLAGS := -D__ASSEMBLY__ -fno-PIE -march=armv8.1-a + KBUILD_AFLAGS := -D__ASSEMBLY__ -fno-PIE ++ifeq ($(ARCH), arm64) ++ KBUILD_AFLAGS += -march=armv8.1-a ++endif KBUILD_CFLAGS := KBUILD_CFLAGS += -std=gnu11 -@@ -563,6 +563,8 @@ KBUILD_CFLAGS += -funsigned-char +@@ -563,6 +566,10 @@ KBUILD_CFLAGS += -funsigned-char KBUILD_CFLAGS += -fno-common KBUILD_CFLAGS += -fno-PIE KBUILD_CFLAGS += -fno-strict-aliasing -+KBUILD_CFLAGS += -march=armv8.1-a ++ifeq ($(ARCH), arm64) ++ KBUILD_CFLAGS += -march=armv8.1-a ++endif +#KBUILD_CFLAGS += -fPIC KBUILD_CPPFLAGS := -D__KERNEL__ KBUILD_RUSTFLAGS := $(rust_common_flags) \ diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig -index 501ec560a939..ae30b4c5d549 100644 +index 9da9d58f1c02..cd15ba85864b 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig -@@ -1731,6 +1731,41 @@ config UNMAP_KERNEL_AT_EL0 +@@ -1776,6 +1776,41 @@ config UNMAP_KERNEL_AT_EL0 If unsure, say Y. @@ -298,7 +871,7 @@ index 501ec560a939..ae30b4c5d549 100644 +config IEE_SELINUX_P + depends on IEE + depends on SECURITY_SELINUX -+ def_bool y ++ def_bool n + +# Config for key isolation +config KEYP @@ -309,10 +882,18 @@ index 501ec560a939..ae30b4c5d549 100644 bool "Mitigate Spectre style attacks against branch history" if EXPERT default y diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig -index 61f3e4e34e64..7d3d2fc3d972 100644 +index b152d1ffb547..5e68208c0a72 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig -@@ -1377,7 +1377,7 @@ CONFIG_NETFILTER_NETLINK_ACCT=m +@@ -89,6 +89,7 @@ CONFIG_BPF_JIT_DEFAULT_ON=y + # CONFIG_BPF_PRELOAD is not set + CONFIG_BPF_LSM=y + CONFIG_BPF_SCHED=y ++CONFIG_HIVE=y + # end of BPF subsystem + + CONFIG_PREEMPT_NONE_BUILD=y +@@ -1388,7 +1389,7 @@ CONFIG_NETFILTER_NETLINK_ACCT=m CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NETFILTER_NETLINK_LOG=m CONFIG_NETFILTER_NETLINK_OSF=m @@ -321,7 +902,7 @@ index 61f3e4e34e64..7d3d2fc3d972 100644 CONFIG_NF_LOG_SYSLOG=m CONFIG_NETFILTER_CONNCOUNT=m CONFIG_NF_CONNTRACK_MARK=y -@@ -1408,7 +1408,7 @@ CONFIG_NF_CT_NETLINK=m +@@ -1419,7 +1420,7 @@ CONFIG_NF_CT_NETLINK=m CONFIG_NF_CT_NETLINK_TIMEOUT=m CONFIG_NF_CT_NETLINK_HELPER=m CONFIG_NETFILTER_NETLINK_GLUE_CT=y @@ -330,7 +911,7 @@ index 61f3e4e34e64..7d3d2fc3d972 100644 CONFIG_NF_NAT_AMANDA=m CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m -@@ -1612,7 +1612,7 @@ CONFIG_IP_VS_PE_SIP=m +@@ -1623,7 +1624,7 @@ CONFIG_IP_VS_PE_SIP=m # # IP: Netfilter Configuration # @@ -339,7 +920,7 @@ index 61f3e4e34e64..7d3d2fc3d972 100644 CONFIG_NF_SOCKET_IPV4=m CONFIG_NF_TPROXY_IPV4=m CONFIG_NF_TABLES_IPV4=y -@@ -1684,7 +1684,7 @@ CONFIG_IP6_NF_TARGET_MASQUERADE=m +@@ -1695,7 +1696,7 @@ CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_IP6_NF_TARGET_NPT=m # end of IPv6: Netfilter Configuration @@ -566,51 +1147,50 @@ index 84055329cd8b..f72d89bb9a32 100644 struct perf_event_attr; diff --git a/arch/arm64/include/asm/iee-access.h b/arch/arm64/include/asm/iee-access.h new file mode 100644 -index 000000000000..cfa76c140bee +index 000000000000..9be519b707c5 --- /dev/null +++ b/arch/arm64/include/asm/iee-access.h -@@ -0,0 +1,47 @@ +@@ -0,0 +1,46 @@ +#ifndef _LINUX_IEE_ACCESS_H +#define _LINUX_IEE_ACCESS_H + -+#include +#include +#include + +extern unsigned long long iee_rw_gate(int flag, ...); + +#ifdef CONFIG_IEE -+void iee_write_in_byte(void *ptr, u64 data, int length) ++static inline void iee_write_in_byte(void *ptr, u64 data, int length) +{ + iee_rw_gate(IEE_WRITE_IN_BYTE, ptr, data, length); +} + -+void iee_memset(void *ptr, int data, size_t n) ++static inline void iee_memset(void *ptr, int data, size_t n) +{ + iee_rw_gate(IEE_MEMSET, ptr, data, n); +} + -+void iee_memcpy(void *dst, void *src, size_t n) ++static inline void iee_memcpy(void *dst, const void *src, size_t n) +{ + iee_rw_gate(IEE_MEMCPY, dst, src, n); +} + -+void iee_set_track(struct track *ptr, struct track *data) ++static inline void iee_set_track(struct track *ptr, struct track *data) +{ + iee_rw_gate(IEE_OP_SET_TRACK, ptr, data); +} + -+void iee_set_freeptr(freeptr_t *pptr, freeptr_t ptr) ++static inline void iee_set_freeptr(freeptr_t *pptr, freeptr_t ptr) +{ + iee_rw_gate(IEE_OP_SET_FREEPTR, pptr, ptr); +} + -+void iee_copy_pte_range(pte_t *new_dst, pte_t *old_dst, pte_t *src_pte, struct vm_area_struct *src_vma, unsigned long dst_vm_flags, pte_t *end_pte) ++static inline void iee_copy_pte_range(pte_t *new_dst, pte_t *old_dst, pte_t *src_pte, struct vm_area_struct *src_vma, unsigned long dst_vm_flags, pte_t *end_pte) +{ + iee_rw_gate(IEE_COPY_PTE_RANGE, new_dst, old_dst, src_pte, src_vma, dst_vm_flags, end_pte); +} + -+void iee_split_huge_pmd(pmd_t *pmdp, pte_t *pgtable) ++static inline void iee_split_huge_pmd(pmd_t *pmdp, pte_t *pgtable) +{ + iee_rw_gate(IEE_SPLIT_HUGE_PMD, pmdp, pgtable); +} @@ -777,10 +1357,10 @@ index 000000000000..b8c3bb53f98a \ No newline at end of file diff --git a/arch/arm64/include/asm/iee-def.h b/arch/arm64/include/asm/iee-def.h new file mode 100644 -index 000000000000..2d2b4301ebb3 +index 000000000000..d33d8570a546 --- /dev/null +++ b/arch/arm64/include/asm/iee-def.h -@@ -0,0 +1,37 @@ +@@ -0,0 +1,130 @@ +#ifndef _LINUX_IEE_DEF_H +#define _LINUX_IEE_DEF_H + @@ -800,41 +1380,134 @@ index 000000000000..2d2b4301ebb3 +#define TEST_AND_CLEAR_BIT 2 +#define TEST_AND_SET_BIT 3 + ++// Function Identifiers with Parameters Description ++enum { ++ IEE_WRITE_IN_BYTE=0, // Parameters: void *ptr, __u64 data, int length ++ IEE_OP_SET_PTE, // Parameters: pte_t *ptep, pte_t pte ++ IEE_OP_SET_PMD, // Parameters: pmd_t *pmdp, pmd_t pmd ++ IEE_OP_SET_PUD, // Parameters: pud_t *pudp, pud_t pud ++ IEE_OP_SET_P4D, // Parameters: p4d_t *p4dp, p4d_t p4d ++ IEE_OP_SET_BM_PTE, // Parameters: pte_t *ptep, pte_t pte ++ IEE_OP_SET_SWAPPER_PGD, // Parameters: pgd_t *pgdp, pgd_t pgd ++ IEE_OP_SET_TRAMP_PGD, // Parameters: pgd_t *pgdp, pgd_t pgd ++ IEE_MEMSET, // Parameters: void *ptr, int data, size_t n ++ IEE_OP_SET_TRACK, // Parameters: struct track *ptr, struct track *data ++ IEE_OP_SET_FREEPTR, // Parameters: void **pptr, void *ptr ++ IEE_OP_SET_PTE_U, // Parameters: pte_t *ptep ++ IEE_OP_SET_PTE_P, // Parameters: pte_t *ptep ++ IEE_SET_TOKEN_PGD, // Parameters: struct task_token *token, pgd_t *pgd ++ IEE_INIT_TOKEN, // Parameters: struct task_struct *tsk, void *kernel_stack, void *iee_stack ++ IEE_INVALIDATE_TOKEN, // Parameters: struct task_struct *tsk ++ IEE_SET_SENSITIVE_PTE, // Parameters: pte_t *lm_ptep, pte_t *iee_ptep ++ IEE_UNSET_SENSITIVE_PTE, // Parameters: pte_t *lm_ptep, pte_t *iee_ptep ++ IEE_SET_TOKEN, // Parameters: pte_t *ptep, void *new, unsigned long order ++ IEE_UNSET_TOKEN, // Parameters: pte_t *ptep, void *token_addr, void *token_page, unsigned long order ++ IEE_COPY_PTE_RANGE, // Parameters: pte_t *new_dst, pte_t *old_dst, pte_t *src_pte, struct vm_area_struct *src_vma, ++ // unsigned long dst_vm_flags, pte_t *end_pte ++ IEE_SPLIT_HUGE_PMD, ++ IEE_VALIDATE_TOKEN, ++ IEE_MEMCPY, +#ifdef CONFIG_KOI -+#define IEE_SWITCH_TO_KERNEL 7 -+#define IEE_SWITCH_TO_KOI 8 -+#endif -+ -+#if defined(CONFIG_KOI) && defined(CONFIG_IEE) -+#define IEE_READ_KOI_STACK 24 -+#define IEE_WRITE_KOI_STACK 25 -+#define IEE_READ_TOKEN_TTBR1 26 -+#define IEE_WRITE_TOKEN_TTBR1 27 -+#define IEE_READ_KOI_KERNEL_STACK 28 -+#define IEE_WRITE_KOI_KERNEL_STACK 29 -+#define IEE_READ_KOI_STACK_BASE 30 -+#define IEE_WRITE_KOI_STACK_BASE 31 -+#define IEE_SET_KOI_PGD 32 ++ _IEE_READ_KOI_STACK, // Parameters: struct task_struct *tsk ++ _IEE_WRITE_KOI_STACK, // Parameters: struct task_struct *tsk, unsigned long koi_stack ++ _IEE_READ_TOKEN_TTBR1, // Parameters: struct task_struct *tsk ++ _IEE_WRITE_TOKEN_TTBR1, // Parameters: struct task_struct *tsk, unsigned long current_ttbr1 ++ _IEE_READ_KOI_KERNEL_STACK, // Parameters: struct task_struct *tsk ++ _IEE_WRITE_KOI_KERNEL_STACK, // Parameters: struct task_struct *tsk, unsigned long kernel_stack ++ _IEE_READ_KOI_STACK_BASE, // Parameters: struct task_struct *tsk ++ _IEE_WRITE_KOI_STACK_BASE, // Parameters: struct task_struct *tsk, unsigned long koi_stack_base ++ _IEE_SET_KOI_PGD, // Parameters: unsigned long koi_pgd_addr +#endif -+ ++#ifdef CONFIG_CREDP ++ IEE_OP_COPY_CRED, // Parameters: struct cred *old, struct cred *new ++ IEE_OP_SET_CRED_UID, // Parameters: struct cred *cred, kuid_t uid ++ IEE_OP_SET_CRED_GID, // Parameters: struct cred *cred, kgid_t gid ++ IEE_OP_SET_CRED_SUID, // Parameters: struct cred *cred, kuid_t suid ++ IEE_OP_SET_CRED_SGID, // Parameters: struct cred *cred, kgid_t sgid ++ IEE_OP_SET_CRED_EUID, // Parameters: struct cred *cred, kuid_t euid ++ IEE_OP_SET_CRED_EGID, // Parameters: struct cred *cred, kgid_t egid ++ IEE_OP_SET_CRED_FSUID, // Parameters: struct cred *cred, kuid_t fsuid ++ IEE_OP_SET_CRED_FSGID, // Parameters: struct cred *cred, kgid_t fsgid ++ IEE_OP_SET_CRED_USER, // Parameters: struct cred *cred, struct user_struct *user ++ IEE_OP_SET_CRED_USER_NS, // Parameters: struct cred *cred, struct user_namespace *user_ns ++ IEE_OP_SET_CRED_GROUP_INFO, // Parameters: struct cred *cred, struct group_info *group_info ++ IEE_OP_SET_CRED_SECUREBITS, // Parameters: struct cred *cred, unsigned securebits ++ IEE_OP_SET_CRED_CAP_INHER, // Parameters: struct cred *cred, kernel_cap_t cap_inheritable ++ IEE_OP_SET_CRED_CAP_PERM, // Parameters: struct cred *cred, kernel_cap_t cap_permitted ++ IEE_OP_SET_CRED_CAP_EFFECT, // Parameters: struct cred *cred, kernel_cap_t cap_effective ++ IEE_OP_SET_CRED_CAP_BSET, // Parameters: struct cred *cred, kernel_cap_t cap_bset ++ IEE_OP_SET_CRED_CAP_AMBIENT, // Parameters: struct cred *cred, kernel_cap_t cap_ambient ++ IEE_OP_SET_CRED_JIT_KEYRING, // Parameters: struct cred *cred, unsigned char jit_keyring ++ IEE_OP_SET_CRED_SESS_KEYRING, // Parameters: struct cred *cred, struct key *session_keyring ++ IEE_OP_SET_CRED_PROC_KEYRING, // Parameters: struct cred *cred, struct key *process_keyring ++ IEE_OP_SET_CRED_THREAD_KEYRING, // Parameters: struct cred *cred, struct key *thread_keyring ++ IEE_OP_SET_CRED_REQ_KEYRING, // Parameters: struct cred *cred, struct key *request_key_auth ++ IEE_OP_SET_CRED_NON_RCU, // Parameters: struct cred *cred, int non_rcu ++ IEE_OP_SET_CRED_ATSET_USAGE, // Parameters: struct cred *cred, int i ++ IEE_OP_SET_CRED_ATOP_USAGE, // Parameters: struct cred *cred, int flag ++ IEE_OP_SET_CRED_SECURITY, // Parameters: struct cred *cred, void *security ++ IEE_OP_SET_CRED_RCU, // Parameters: struct cred *cred, struct rcu_head *rcu ++ IEE_OP_SET_CRED_UCOUNTS, // Parameters: struct cred *cred, struct ucounts *ucounts ++// IEE_OP_COMMIT_CRED, // Parameters: struct cred *cred ++// IEE_OP_COPY_CRED_KERNEL, // Parameters: struct cred *old, struct cred *new +#endif -\ No newline at end of file -diff --git a/arch/arm64/include/asm/iee-key.h b/arch/arm64/include/asm/iee-key.h -new file mode 100644 -index 000000000000..eb116bb7604a ---- /dev/null -+++ b/arch/arm64/include/asm/iee-key.h -@@ -0,0 +1,154 @@ -+#ifndef _LINUX_IEE_KEY_H -+#define _LINUX_IEE_KEY_H -+ -+#include -+#include -+ -+extern unsigned long long iee_rw_gate(int flag, ...); -+ +#ifdef CONFIG_KEYP -+static void __maybe_unused iee_set_key_union(struct key *key, struct key_union *key_union) ++ IEE_OP_SET_KEY_UNION, ++ IEE_OP_SET_KEY_STRUCT, ++ IEE_OP_SET_KEY_PAYLOAD, ++ IEE_OP_SET_KEY_USAGE, ++ IEE_OP_SET_KEY_SERIAL, ++ IEE_OP_SET_KEY_WATCHERS, ++ IEE_OP_SET_KEY_USERS, ++ IEE_OP_SET_KEY_SECURITY, ++ IEE_OP_SET_KEY_EXPIRY, ++ IEE_OP_SET_KEY_REVOKED_AT, ++ IEE_OP_SET_KEY_LAST_USED_AT, ++ IEE_OP_SET_KEY_UID, ++ IEE_OP_SET_KEY_GID, ++ IEE_OP_SET_KEY_PERM, ++ IEE_OP_SET_KEY_QUOTALEN, ++ IEE_OP_SET_KEY_DATALEN, ++ IEE_OP_SET_KEY_STATE, ++ IEE_OP_SET_KEY_MAGIC, ++ IEE_OP_SET_KEY_FLAGS, ++ IEE_OP_SET_KEY_INDEX_KEY, ++ IEE_OP_SET_KEY_HASH, ++ IEE_OP_SET_KEY_LEN_DESC, ++ IEE_OP_SET_KEY_TYPE, ++ IEE_OP_SET_KEY_TAG, ++ IEE_OP_SET_KEY_DESCRIPTION, ++ IEE_OP_SET_KEY_RESTRICT_LINK, ++ IEE_OP_SET_KEY_FLAG_BIT, ++#endif ++#ifdef CONFIG_IEE_SELINUX_P ++ IEE_SEL_SET_STATUS_PG, // Parameters: struct page* new_page ++ IEE_SEL_SET_ENFORCING, // Parameters: bool value ++ IEE_SEL_SET_INITIALIZED, ++ IEE_SEL_SET_POLICY_CAP, // Parameters: unsigned int idx, int cap ++ IEE_SEL_RCU_ASSIGN_POLICY, // Parameters: struct selinux_policy* new_policy, struct selinux_policy* iee_new_policy ++#endif ++ IEE_FLAG_END ++}; ++ ++#endif +\ No newline at end of file +diff --git a/arch/arm64/include/asm/iee-key.h b/arch/arm64/include/asm/iee-key.h +new file mode 100644 +index 000000000000..5653720badb6 +--- /dev/null ++++ b/arch/arm64/include/asm/iee-key.h +@@ -0,0 +1,149 @@ ++#ifndef _LINUX_IEE_KEY_H ++#define _LINUX_IEE_KEY_H ++ ++#include ++#include ++ ++extern unsigned long long iee_rw_gate(int flag, ...); ++ ++#ifdef CONFIG_KEYP ++static void __maybe_unused iee_set_key_union(struct key *key, struct key_union *key_union) +{ + iee_rw_gate(IEE_OP_SET_KEY_UNION, key, key_union); +} @@ -849,11 +1522,6 @@ index 000000000000..eb116bb7604a + iee_rw_gate(IEE_OP_SET_KEY_PAYLOAD, key, key_payload); +} + -+static void __maybe_unused iee_write_key_payload(struct key *key, union key_payload payload) -+{ -+ iee_rw_gate(IEE_OP_WRITE_KEY_PAYLOAD, key, payload); -+} -+ +extern bool iee_set_key_usage(struct key *key, int n, int flag); + +static void __maybe_unused iee_set_key_serial(struct key *key, key_serial_t serial) @@ -935,7 +1603,7 @@ index 000000000000..eb116bb7604a + iee_rw_gate(IEE_OP_SET_KEY_FLAGS, key, flags); +} + -+static void __maybe_unused iee_set_key_index_key(struct key *key, struct keyring_index_key index_key) ++static void __maybe_unused iee_set_key_index_key(struct key *key, struct keyring_index_key *index_key) +{ + iee_rw_gate(IEE_OP_SET_KEY_INDEX_KEY, key, index_key); +} @@ -980,9 +1648,29 @@ index 000000000000..eb116bb7604a + +#endif \ No newline at end of file +diff --git a/arch/arm64/include/asm/iee-koi.h b/arch/arm64/include/asm/iee-koi.h +new file mode 100644 +index 000000000000..8f7bfcc7e581 +--- /dev/null ++++ b/arch/arm64/include/asm/iee-koi.h +@@ -0,0 +1,13 @@ ++#if defined(CONFIG_KOI) && defined(CONFIG_IEE) ++#define IEE_SWITCH_TO_KERNEL 7 ++#define IEE_SWITCH_TO_KOI 8 ++#define IEE_READ_KOI_STACK 24 ++#define IEE_WRITE_KOI_STACK 25 ++#define IEE_READ_TOKEN_TTBR1 26 ++#define IEE_WRITE_TOKEN_TTBR1 27 ++#define IEE_READ_KOI_KERNEL_STACK 28 ++#define IEE_WRITE_KOI_KERNEL_STACK 29 ++#define IEE_READ_KOI_STACK_BASE 30 ++#define IEE_WRITE_KOI_STACK_BASE 31 ++#define IEE_SET_KOI_PGD 32 ++#endif +\ No newline at end of file diff --git a/arch/arm64/include/asm/iee-selinuxp.h b/arch/arm64/include/asm/iee-selinuxp.h new file mode 100644 -index 000000000000..4ea3e614c049 +index 000000000000..b1cf52d8c2d8 --- /dev/null +++ b/arch/arm64/include/asm/iee-selinuxp.h @@ -0,0 +1,27 @@ @@ -990,7 +1678,7 @@ index 000000000000..4ea3e614c049 +#define _LINUX_IEE_SELINUX_P_H + +#include -+#include ++#include +#include "security.h" +#include "ss/services.h" + @@ -1016,10 +1704,10 @@ index 000000000000..4ea3e614c049 \ No newline at end of file diff --git a/arch/arm64/include/asm/iee-si.h b/arch/arm64/include/asm/iee-si.h new file mode 100644 -index 000000000000..8d2f7566e272 +index 000000000000..02b77547b29c --- /dev/null +++ b/arch/arm64/include/asm/iee-si.h -@@ -0,0 +1,65 @@ +@@ -0,0 +1,61 @@ +#ifndef _LINUX_IEE_SI_H +#define _LINUX_IEE_SI_H + @@ -1060,10 +1748,6 @@ index 000000000000..8d2f7566e272 +#define IEE_CONTEXT_SWITCH 6 +// #define IEE_WRITE_AFSR0 10 +/* Provide ttbr1 switch gate for KOI */ -+#ifdef CONFIG_KOI -+#define IEE_SWITCH_TO_KERNEL 7 -+#define IEE_SWITCH_TO_KOI 8 -+#endif +/* MASK modify-permitted bits on IEE protected sys registers */ +#define IEE_SCTLR_MASK (SCTLR_EL1_CP15BEN | SCTLR_EL1_SED | SCTLR_EL1_UCT | SCTLR_EL1_UCI |\ + SCTLR_EL1_BT0 | SCTLR_EL1_BT1 | SCTLR_EL1_TCF0_MASK | SCTLR_ELx_DSSBS |\ @@ -1118,15 +1802,14 @@ index 000000000000..4f3c17c7da00 \ No newline at end of file diff --git a/arch/arm64/include/asm/iee-token.h b/arch/arm64/include/asm/iee-token.h new file mode 100644 -index 000000000000..d1b2cdaa0c03 +index 000000000000..25ebf08faf8f --- /dev/null +++ b/arch/arm64/include/asm/iee-token.h -@@ -0,0 +1,34 @@ +@@ -0,0 +1,33 @@ +#ifndef _LINUX_IEE_TOKEN_H +#define _LINUX_IEE_TOKEN_H + +#include -+#include + +extern unsigned long long iee_rw_gate(int flag, ...); +struct task_token; @@ -1134,22 +1817,22 @@ index 000000000000..d1b2cdaa0c03 +struct mm_struct; + +#ifdef CONFIG_IEE -+void iee_set_token_pgd(struct task_struct *tsk, pgd_t *pgd) ++static inline void iee_set_token_pgd(struct task_struct *tsk, pgd_t *pgd) +{ + iee_rw_gate(IEE_SET_TOKEN_PGD, tsk, pgd); +} + -+void iee_init_token(struct task_struct *tsk, void *iee_stack, void *tmp_page) ++static inline void iee_init_token(struct task_struct *tsk, void *iee_stack, void *tmp_page) +{ + iee_rw_gate(IEE_INIT_TOKEN, tsk, iee_stack, tmp_page); +} + -+void iee_invalidate_token(struct task_struct *tsk) ++static inline void iee_invalidate_token(struct task_struct *tsk) +{ + iee_rw_gate(IEE_INVALIDATE_TOKEN, tsk); +} + -+void iee_validate_token(struct task_struct *tsk) ++static inline void iee_validate_token(struct task_struct *tsk) +{ + iee_rw_gate(IEE_VALIDATE_TOKEN, tsk); +} @@ -1205,10 +1888,10 @@ index 85d26143faa5..e7a3081ce285 100644 #endif /* __ASM_KERNEL_PGTABLE_H */ diff --git a/arch/arm64/include/asm/koi.h b/arch/arm64/include/asm/koi.h new file mode 100644 -index 000000000000..a3b0ce0f8019 +index 000000000000..c9afe886bef8 --- /dev/null +++ b/arch/arm64/include/asm/koi.h -@@ -0,0 +1,531 @@ +@@ -0,0 +1,532 @@ +#include "linux/mm.h" +#include "asm/current.h" +#include "asm/pgtable-hwdef.h" @@ -1229,6 +1912,7 @@ index 000000000000..a3b0ce0f8019 +#ifdef CONFIG_IEE +#include "asm/iee-si.h" +#include "asm/iee-def.h" ++#include +#endif + +#ifdef CONFIG_KOI @@ -1850,7 +2534,7 @@ index a6fb325424e7..cca5994dabfb 100644 __cpu_install_idmap(idmap); diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h -index 237224484d0f..4e3304da8421 100644 +index 661964e99b9d..6e40b14db920 100644 --- a/arch/arm64/include/asm/pgalloc.h +++ b/arch/arm64/include/asm/pgalloc.h @@ -63,6 +63,10 @@ static inline void __p4d_populate(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot) @@ -1865,7 +2549,7 @@ index 237224484d0f..4e3304da8421 100644 pmdval_t prot) { diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h -index e4944d517c99..7f60e568c964 100644 +index f736a4222190..babc366acc51 100644 --- a/arch/arm64/include/asm/pgtable-hwdef.h +++ b/arch/arm64/include/asm/pgtable-hwdef.h @@ -84,6 +84,13 @@ @@ -1882,7 +2566,17 @@ index e4944d517c99..7f60e568c964 100644 /* * Hardware page table definitions. * -@@ -285,6 +292,10 @@ +@@ -157,6 +164,9 @@ + #define PTE_CONT (_AT(pteval_t, 1) << 52) /* Contiguous range */ + #define PTE_PXN (_AT(pteval_t, 1) << 53) /* Privileged XN */ + #define PTE_UXN (_AT(pteval_t, 1) << 54) /* User XN */ ++#ifdef CONFIG_HIVE ++#define PTE_BPF_SFI_GP (_AT(pteval_t, 1) << 55) /* BPF_SFI guarded */ ++#endif + + #define PTE_ADDR_LOW (((_AT(pteval_t, 1) << (48 - PAGE_SHIFT)) - 1) << PAGE_SHIFT) + #ifdef CONFIG_ARM64_PA_BITS_52 +@@ -288,6 +298,10 @@ #define TCR_TCMA0 (UL(1) << 57) #define TCR_TCMA1 (UL(1) << 58) @@ -1894,7 +2588,7 @@ index e4944d517c99..7f60e568c964 100644 * TTBR. */ diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h -index e4d6593dfa66..85b4af2c2122 100644 +index d457dd74f534..89206b1a517b 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -34,6 +34,9 @@ @@ -2204,7 +2898,7 @@ index e4d6593dfa66..85b4af2c2122 100644 } while (pte_val(pte) != pte_val(old_pte)); return pte_young(pte); -@@ -952,8 +1089,12 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma, +@@ -954,8 +1091,12 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma, static inline pte_t __ptep_get_and_clear(struct mm_struct *mm, unsigned long address, pte_t *ptep) { @@ -2218,7 +2912,7 @@ index e4d6593dfa66..85b4af2c2122 100644 page_table_check_pte_clear(mm, pte); return pte; -@@ -995,7 +1136,12 @@ static inline pte_t __get_and_clear_full_ptes(struct mm_struct *mm, +@@ -997,7 +1138,12 @@ static inline pte_t __get_and_clear_full_ptes(struct mm_struct *mm, static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm, unsigned long address, pmd_t *pmdp) { @@ -2231,7 +2925,7 @@ index e4d6593dfa66..85b4af2c2122 100644 page_table_check_pmd_clear(mm, pmd); -@@ -1010,10 +1156,19 @@ static inline void ___ptep_set_wrprotect(struct mm_struct *mm, +@@ -1012,10 +1158,19 @@ static inline void ___ptep_set_wrprotect(struct mm_struct *mm, pte_t old_pte; do { @@ -2251,7 +2945,7 @@ index e4d6593dfa66..85b4af2c2122 100644 } while (pte_val(pte) != pte_val(old_pte)); } -@@ -1089,7 +1244,17 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma, +@@ -1091,7 +1246,17 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp, pmd_t pmd) { page_table_check_pmd_set(vma->vm_mm, pmdp, pmd); @@ -2317,10 +3011,10 @@ index 000000000000..0a478828421e + +#endif diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h -index 42358b8d678e..1e2d11e57fe3 100644 +index 435634a703c6..c214643777a6 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h -@@ -1116,6 +1116,64 @@ +@@ -1140,6 +1140,64 @@ write_sysreg_s(__scs_new, sysreg); \ } while (0) @@ -2386,7 +3080,7 @@ index 42358b8d678e..1e2d11e57fe3 100644 u64 par; \ asm(ALTERNATIVE("nop", "dmb sy", ARM64_WORKAROUND_1508412)); \ diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h -index 2c29239d05c3..989c6d23632c 100644 +index 2c29239d05c3..a68ca9e784cf 100644 --- a/arch/arm64/include/asm/tlb.h +++ b/arch/arm64/include/asm/tlb.h @@ -11,11 +11,31 @@ @@ -2408,13 +3102,13 @@ index 2c29239d05c3..989c6d23632c 100644 +{ + struct page *page = (struct page *)_table; + -+ if (!is_huge_zero_page(page)) -+ { -+ if (page_ref_dec_return(page) == 1) -+ { ++ // if (!is_huge_zero_page(page)) ++ // { ++ // if (page_ref_dec_return(page) == 1) ++ // { + free_iee_pgtable_page((void *)page_to_virt(page)); -+ } -+ } ++ // } ++ // } +} +#endif + @@ -2422,7 +3116,7 @@ index 2c29239d05c3..989c6d23632c 100644 static void tlb_flush(struct mmu_gather *tlb); diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h -index 831c314d75ff..d447a0e35a7c 100644 +index 4bbd9ed591f2..ecd8e35ab777 100644 --- a/arch/arm64/include/asm/tlbflush.h +++ b/arch/arm64/include/asm/tlbflush.h @@ -49,6 +49,7 @@ @@ -2524,16 +3218,7 @@ index 831c314d75ff..d447a0e35a7c 100644 #define __flush_s2_tlb_range_op(op, start, pages, stride, tlb_level) \ __flush_tlb_range_op(op, start, pages, stride, 0, tlb_level, false) -@@ -467,7 +517,7 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end - return; - } - -- start = __TLBI_VADDR(start, 0); -+ start = __TLBI_VADDR(start, 0); - end = __TLBI_VADDR(end, 0); - - dsb(ishst); -@@ -483,9 +533,9 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end +@@ -493,9 +543,9 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end */ static inline void __flush_tlb_kernel_pgtable(unsigned long kaddr) { @@ -2547,7 +3232,7 @@ index 831c314d75ff..d447a0e35a7c 100644 dsb(ish); isb(); diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile -index 4ce58887302a..81dd446dc8a3 100644 +index 4ce58887302a..579b1f713849 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -36,6 +36,8 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \ @@ -2559,6 +3244,14 @@ index 4ce58887302a..81dd446dc8a3 100644 obj-$(CONFIG_AARCH32_EL0) += binfmt_elf32.o sys32.o signal32.o \ sys_compat.o obj-$(CONFIG_AARCH32_EL0) += sigreturn32.o +@@ -84,6 +86,7 @@ obj-$(CONFIG_IPI_AS_NMI) += ipi_nmi.o + obj-$(CONFIG_HISI_VIRTCCA_GUEST) += virtcca_cvm_guest.o virtcca_cvm_tsi.o + obj-$(CONFIG_HISI_VIRTCCA_HOST) += virtcca_cvm_host.o + CFLAGS_patch-scs.o += -mbranch-protection=none ++obj-$(CONFIG_HIVE) += sfi_bpf_arch.o + + # Force dependency (vdso*-wrap.S includes vdso.so through incbin) + $(obj)/vdso-wrap.o: $(obj)/vdso/vdso.so diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c index 87ac0b9c0b4f..f135db1d9965 100644 --- a/arch/arm64/kernel/armv8_deprecated.c @@ -2604,10 +3297,10 @@ index 87ac0b9c0b4f..f135db1d9965 100644 static int __a32_setend_handler(struct pt_regs *regs, u32 big_endian) diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c -index e997ad275afb..f584b457a0f4 100644 +index f20918eb36bc..68c08adc86c9 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c -@@ -99,6 +99,19 @@ int main(void) +@@ -102,6 +102,19 @@ int main(void) DEFINE(FREGS_SIZE, sizeof(struct ftrace_regs)); BLANK(); #endif @@ -2628,7 +3321,7 @@ index e997ad275afb..f584b457a0f4 100644 DEFINE(COMPAT_SIGFRAME_REGS_OFFSET, offsetof(struct a32_sigframe, uc.uc_mcontext.arm_r0)); DEFINE(COMPAT_RT_SIGFRAME_REGS_OFFSET, offsetof(struct a32_rt_sigframe, sig.uc.uc_mcontext.arm_r0)); diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c -index 46813132a09f..412006aa323c 100644 +index 2e5e4052a182..d27d11d7b7bb 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -80,7 +80,11 @@ hisilicon_1980005_enable(const struct arm64_cpu_capabilities *__unused) @@ -2668,21 +3361,22 @@ index 46813132a09f..412006aa323c 100644 #ifdef CONFIG_HISILICON_ERRATUM_HIP08_RU_PREFETCH diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c -index a7b4ccd7983e..3c27722b6bfe 100644 +index a1736e9044da..81aaca96478c 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c -@@ -94,6 +94,10 @@ +@@ -94,6 +94,11 @@ #include #include +#ifdef CONFIG_IEE +#include ++#include +#endif + /* Kernel representation of AT_HWCAP and AT_HWCAP2 */ static DECLARE_BITMAP(elf_hwcap, MAX_CPU_FEATURES) __read_mostly; -@@ -1616,7 +1620,11 @@ static void cpu_emulate_effective_ctr(const struct arm64_cpu_capabilities *__unu +@@ -1616,7 +1621,11 @@ static void cpu_emulate_effective_ctr(const struct arm64_cpu_capabilities *__unu * value. */ if (!(read_cpuid_cachetype() & BIT(CTR_EL0_IDC_SHIFT))) @@ -2694,7 +3388,7 @@ index a7b4ccd7983e..3c27722b6bfe 100644 } static bool has_cache_dic(const struct arm64_cpu_capabilities *entry, -@@ -1877,7 +1885,11 @@ static inline void __cpu_enable_hw_dbm(void) +@@ -1877,7 +1886,11 @@ static inline void __cpu_enable_hw_dbm(void) { u64 tcr = read_sysreg(tcr_el1) | TCR_HD; @@ -2706,7 +3400,7 @@ index a7b4ccd7983e..3c27722b6bfe 100644 isb(); local_flush_tlb_all(); } -@@ -2060,7 +2072,9 @@ static void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused) +@@ -2060,7 +2073,9 @@ static void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused) */ WARN_ON_ONCE(in_interrupt()); @@ -2716,7 +3410,7 @@ index a7b4ccd7983e..3c27722b6bfe 100644 set_pstate_pan(1); } #endif /* CONFIG_ARM64_PAN */ -@@ -2125,7 +2139,11 @@ static bool has_generic_auth(const struct arm64_cpu_capabilities *entry, +@@ -2125,7 +2140,11 @@ static bool has_generic_auth(const struct arm64_cpu_capabilities *entry, static void cpu_enable_e0pd(struct arm64_cpu_capabilities const *cap) { if (this_cpu_has_cap(ARM64_HAS_E0PD)) @@ -2728,7 +3422,7 @@ index a7b4ccd7983e..3c27722b6bfe 100644 } #endif /* CONFIG_ARM64_E0PD */ -@@ -2220,7 +2238,11 @@ static void nmi_enable(const struct arm64_cpu_capabilities *__unused) +@@ -2220,7 +2239,11 @@ static void nmi_enable(const struct arm64_cpu_capabilities *__unused) * avoid leaving things masked. */ _allint_clear(); @@ -2740,7 +3434,7 @@ index a7b4ccd7983e..3c27722b6bfe 100644 isb(); } #endif -@@ -2235,7 +2257,11 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused) +@@ -2235,7 +2258,11 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused) * So, be strict and forbid other BRs using other registers to * jump onto a PACIxSP instruction: */ @@ -2752,7 +3446,7 @@ index a7b4ccd7983e..3c27722b6bfe 100644 isb(); } #endif /* CONFIG_ARM64_BTI */ -@@ -2243,7 +2269,11 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused) +@@ -2243,7 +2270,11 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused) #ifdef CONFIG_ARM64_MTE static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) { @@ -2764,7 +3458,7 @@ index a7b4ccd7983e..3c27722b6bfe 100644 mte_cpu_setup(); -@@ -2277,7 +2307,11 @@ static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, in +@@ -2288,7 +2319,11 @@ static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, in static void cpu_trap_el0_impdef(const struct arm64_cpu_capabilities *__unused) { @@ -2776,7 +3470,7 @@ index a7b4ccd7983e..3c27722b6bfe 100644 } static void cpu_enable_dit(const struct arm64_cpu_capabilities *__unused) -@@ -2287,7 +2321,11 @@ static void cpu_enable_dit(const struct arm64_cpu_capabilities *__unused) +@@ -2298,7 +2333,11 @@ static void cpu_enable_dit(const struct arm64_cpu_capabilities *__unused) static void cpu_enable_mops(const struct arm64_cpu_capabilities *__unused) { @@ -2788,7 +3482,7 @@ index a7b4ccd7983e..3c27722b6bfe 100644 } /* Internal helper functions to match cpu capability type */ -@@ -3513,6 +3551,43 @@ static void __init setup_system_capabilities(void) +@@ -3593,6 +3632,43 @@ static void __init setup_system_capabilities(void) enable_cpu_capabilities(SCOPE_ALL & ~SCOPE_BOOT_CPU); } @@ -2832,7 +3526,7 @@ index a7b4ccd7983e..3c27722b6bfe 100644 void __init setup_cpu_features(void) { u32 cwg; -@@ -3540,6 +3615,10 @@ void __init setup_cpu_features(void) +@@ -3621,6 +3697,10 @@ void __init setup_cpu_features(void) if (!cwg) pr_warn("No Cache Writeback Granule information, assuming %d\n", ARCH_DMA_MINALIGN); @@ -2863,10 +3557,10 @@ index 745aefddd9a3..265417e0ad81 100644 NOKPROBE_SYMBOL(mdscr_write); diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c -index 08274e4317b2..0d259e355c90 100644 +index 4602c107c40a..73aa0aad07b1 100644 --- a/arch/arm64/kernel/entry-common.c +++ b/arch/arm64/kernel/entry-common.c -@@ -156,7 +156,11 @@ asmlinkage void noinstr asm_exit_to_user_mode(struct pt_regs *regs) +@@ -212,7 +212,11 @@ static __always_inline void fast_enter_from_user_mode(struct pt_regs *regs) * mode. Before this function is called it is not safe to call regular kernel * code, instrumentable code, or any code which may trigger an exception. */ @@ -2879,16 +3573,15 @@ index 08274e4317b2..0d259e355c90 100644 regs->lockdep_hardirqs = lockdep_hardirqs_enabled(); diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S -index 7fcbee0f6c0e..8ee531918781 100644 +index da3809632f0f..40c279f562f0 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S -@@ -29,12 +29,400 @@ +@@ -29,12 +29,399 @@ #include #include +#ifdef CONFIG_IEE -+#include -+ ++#include +#define BAD_SP_EL0 0 +#define BAD_ELR_EL1 1 +#define BAD_TCR_EL1 2 @@ -3283,7 +3976,7 @@ index 7fcbee0f6c0e..8ee531918781 100644 .macro kernel_ventry, el:req, ht:req, regsize:req, label:req .align 7 .Lventry_start\@: -@@ -53,6 +441,15 @@ +@@ -53,6 +440,15 @@ .Lskip_tramp_vectors_cleanup\@: .endif @@ -3299,7 +3992,7 @@ index 7fcbee0f6c0e..8ee531918781 100644 sub sp, sp, #PT_REGS_SIZE #ifdef CONFIG_VMAP_STACK /* -@@ -320,6 +717,17 @@ alternative_else_nop_endif +@@ -332,6 +728,17 @@ alternative_else_nop_endif msr_s SYS_ICC_PMR_EL1, x20 .Lskip_pmr_save\@: @@ -3317,10 +4010,10 @@ index 7fcbee0f6c0e..8ee531918781 100644 #endif /* -@@ -333,9 +741,11 @@ alternative_else_nop_endif +@@ -345,9 +752,11 @@ alternative_else_nop_endif .endm - .macro kernel_exit, el + .macro kernel_exit, el, fast_mode = std + #ifndef CONFIG_IEE .if \el != 0 disable_daif @@ -3329,7 +4022,7 @@ index 7fcbee0f6c0e..8ee531918781 100644 #ifdef CONFIG_ARM64_PSEUDO_NMI alternative_if_not ARM64_HAS_GIC_PRIO_MASKING -@@ -411,6 +821,41 @@ alternative_else_nop_endif +@@ -435,6 +844,40 @@ alternative_else_nop_endif msr elr_el1, x21 // set up the return data msr spsr_el1, x22 @@ -3338,7 +4031,8 @@ index 7fcbee0f6c0e..8ee531918781 100644 + + .if \el == 0 + -+ #ifndef CONFIG_UNMAP_KERNEL_AT_EL0 ++ /* Skip TCR settings if User\Kernel isolation is already enforced by KPTI.*/ ++ alternative_insn nop, "b 6f", ARM64_UNMAP_KERNEL_AT_EL0 + // SET hpd1 = 0 start + mrs x0, tcr_el1 + and x0, x0, #0xFFFFFBFFFFFFFFFF @@ -3346,14 +4040,12 @@ index 7fcbee0f6c0e..8ee531918781 100644 + msr tcr_el1, x0 + // SET hpd1 = 0 end + -+ disable_daif -+ + // Check ELR_EL1 + mrs x0, elr_el1 + lsr x0, x0, #48 + tst x0, #0xffff + b.ne 5f -+ #endif ++6: + + .endif + @@ -3371,9 +4063,9 @@ index 7fcbee0f6c0e..8ee531918781 100644 ldp x0, x1, [sp, #16 * 0] ldp x2, x3, [sp, #16 * 1] ldp x4, x5, [sp, #16 * 2] -@@ -451,13 +896,30 @@ alternative_if ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD - dsb nsh +@@ -480,6 +923,17 @@ alternative_if ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD alternative_else_nop_endif + .endif eret + +#ifdef CONFIG_IEE @@ -3389,9 +4081,10 @@ index 7fcbee0f6c0e..8ee531918781 100644 .else ldr lr, [sp, #S_LR] add sp, sp, #PT_REGS_SIZE // restore sp - - /* Ensure any device/NC reads complete */ +@@ -488,7 +942,13 @@ alternative_else_nop_endif + .if \fast_mode == std alternative_insn nop, "dmb sy", ARM64_WORKAROUND_1508412 + .endif - +#ifdef CONFIG_KOI + sub sp, sp, #176 @@ -3403,7 +4096,7 @@ index 7fcbee0f6c0e..8ee531918781 100644 eret .endif sb -@@ -569,12 +1031,167 @@ SYM_CODE_START_LOCAL(__bad_stack) +@@ -600,6 +1060,151 @@ SYM_CODE_START_LOCAL(__bad_stack) SYM_CODE_END(__bad_stack) #endif /* CONFIG_VMAP_STACK */ @@ -3430,7 +4123,8 @@ index 7fcbee0f6c0e..8ee531918781 100644 + /* el0 set hpds */ + .if \el == 0 + -+ #ifndef CONFIG_UNMAP_KERNEL_AT_EL0 ++ /* Skip TCR settings if User\Kernel isolation is already enforced by KPTI.*/ ++ alternative_insn nop, "b 6f", ARM64_UNMAP_KERNEL_AT_EL0 + /* SET hpd1 = 1 start */ + mrs x0, tcr_el1 + orr x0, x0, #0x0000040000000000 @@ -3457,7 +4151,6 @@ index 7fcbee0f6c0e..8ee531918781 100644 + +6: + nop -+ #endif + + .else +#ifdef CONFIG_IEE_INTERRUPTABLE @@ -3552,9 +4245,12 @@ index 7fcbee0f6c0e..8ee531918781 100644 +#endif + .endif + .endm - - .macro entry_handler el:req, ht:req, regsize:req, label:req - SYM_CODE_START_LOCAL(el\el\ht\()_\regsize\()_\label) + #ifdef CONFIG_FAST_SYSCALL + .macro check_esr_el1_ec_svc64 + /* Only support SVC64 for now */ +@@ -731,8 +1336,18 @@ SYM_CODE_START_LOCAL(el\el\ht\()_\regsize\()_\label) + .endif + #endif kernel_entry \el, \regsize + + #ifdef CONFIG_IEE @@ -3571,7 +4267,7 @@ index 7fcbee0f6c0e..8ee531918781 100644 .if \el == 0 b ret_to_user .else -@@ -606,9 +1223,15 @@ SYM_CODE_END(el\el\ht\()_\regsize\()_\label) +@@ -764,9 +1379,15 @@ SYM_CODE_END(el\el\ht\()_\regsize\()_\label) entry_handler 0, t, 32, fiq entry_handler 0, t, 32, error @@ -3588,7 +4284,7 @@ index 7fcbee0f6c0e..8ee531918781 100644 SYM_CODE_START_LOCAL(ret_to_user) ldr x19, [tsk, #TSK_TI_FLAGS] // re-check for single-step diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c -index 5cdfcc9e3e54..c0af965bd92e 100644 +index 0137d987631e..fbb543bcdb4a 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -1309,7 +1309,11 @@ void sme_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p) @@ -3802,31 +4498,31 @@ index d39a8787edf2..b5ac4b7670bc 100644 slot = &slots[i]; diff --git a/arch/arm64/kernel/iee/Makefile b/arch/arm64/kernel/iee/Makefile new file mode 100644 -index 000000000000..1d4436f06af4 +index 000000000000..c62a1cc4f03b --- /dev/null +++ b/arch/arm64/kernel/iee/Makefile @@ -0,0 +1,5 @@ +ccflags-$(CONFIG_IEE_SELINUX_P) := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include + -+obj-$(CONFIG_IEE) += iee.o iee-gate.o iee-func.o iee-pgtable.o stack_slab.o pgtable_slab.o iee-key.o ++obj-$(CONFIG_IEE) += iee.o iee-gate.o iee-func.o iee-pgtable.o stack_slab.o pgtable_slab.o + +obj-$(CONFIG_IEE_SELINUX_P) += iee-selinuxp.o \ No newline at end of file diff --git a/arch/arm64/kernel/iee/iee-func.c b/arch/arm64/kernel/iee/iee-func.c new file mode 100644 -index 000000000000..76538e75edd2 +index 000000000000..29035c96a4f2 --- /dev/null +++ b/arch/arm64/kernel/iee/iee-func.c -@@ -0,0 +1,720 @@ +@@ -0,0 +1,722 @@ +#include "asm/pgtable.h" +#include +#include +#include +#include +#include ++#include + +extern s64 iee_offset; -+extern void iee_memset(void *ptr, int data, size_t n); +extern void iee_split_huge_pmd(pmd_t *pmdp, pte_t *pgtable); +#ifdef CONFIG_PTP +extern phys_addr_t __init early_pgtable_alloc(int shift); @@ -4538,10 +5234,12 @@ index 000000000000..76538e75edd2 + flush_tlb_kernel_range(addr, addr+(1 << order)*PAGE_SIZE); + isb(); +} ++ ++void __init iee_rest_init(void) {} \ No newline at end of file diff --git a/arch/arm64/kernel/iee/iee-gate.S b/arch/arm64/kernel/iee/iee-gate.S new file mode 100644 -index 000000000000..24a80378191d +index 000000000000..3b039e1dfbc4 --- /dev/null +++ b/arch/arm64/kernel/iee/iee-gate.S @@ -0,0 +1,314 @@ @@ -4550,7 +5248,7 @@ index 000000000000..24a80378191d +#include +#include +#include -+#include ++#include + +#ifdef CONFIG_IEE + @@ -4859,33 +5557,14 @@ index 000000000000..24a80378191d + .popsection + +#endif -diff --git a/arch/arm64/kernel/iee/iee-key.c b/arch/arm64/kernel/iee/iee-key.c -new file mode 100644 -index 000000000000..a801f9fdebf0 ---- /dev/null -+++ b/arch/arm64/kernel/iee/iee-key.c -@@ -0,0 +1,12 @@ -+#include -+#include -+#include -+ -+extern unsigned long long iee_rw_gate(int flag, ...); -+ -+#ifdef CONFIG_KEYP -+void iee_write_key_payload_rcu_data0(struct key *key, void *rcu_data0) -+{ -+ iee_rw_gate(IEE_OP_WRITE_KEY_PAYLOAD_RCU_DATA0, key, rcu_data0); -+} -+#endif -\ No newline at end of file diff --git a/arch/arm64/kernel/iee/iee-pgtable.c b/arch/arm64/kernel/iee/iee-pgtable.c new file mode 100644 -index 000000000000..bd43af6d4eb3 +index 000000000000..1369f00f410d --- /dev/null +++ b/arch/arm64/kernel/iee/iee-pgtable.c @@ -0,0 +1,402 @@ +#include -+#include ++#include +#include +#include + @@ -5330,10 +6009,10 @@ index 000000000000..394f99f3f574 +#endif diff --git a/arch/arm64/kernel/iee/iee.c b/arch/arm64/kernel/iee/iee.c new file mode 100644 -index 000000000000..2c7882d4f5be +index 000000000000..1464c2e947e7 --- /dev/null +++ b/arch/arm64/kernel/iee/iee.c -@@ -0,0 +1,1734 @@ +@@ -0,0 +1,1720 @@ +#include "linux/sched.h" +#include +#include @@ -5347,7 +6026,7 @@ index 000000000000..2c7882d4f5be +#include +#include +#include -+#include ++#include +#include + +#define is_cow_mapping(flags) (((flags) & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE) @@ -5414,9 +6093,7 @@ index 000000000000..2c7882d4f5be +void __iee_code _iee_set_key_union(unsigned long iee_offset, struct key *key, struct key_union *key_union); +void __iee_code _iee_set_key_struct(unsigned long iee_offset, struct key *key, struct key_struct *key_struct); +void __iee_code _iee_set_key_payload(unsigned long iee_offset, struct key *key, union key_payload *key_payload); -+void __iee_code _iee_write_key_payload(unsigned long iee_offset, struct key *key, union key_payload payload); +void __iee_code _iee_memcpy(unsigned long iee_offset, void *dst, void *src, size_t n); -+void __iee_code _iee_write_key_payload_rcu_data0(unsigned long iee_offset, struct key *key, void *rcu_data0); +bool __iee_code _iee_set_key_usage(unsigned long iee_offset, struct key *key, int n, int flag); +void __iee_code _iee_set_key_serial(unsigned long iee_offset, struct key *key, key_serial_t serial); +void __iee_code _iee_set_key_watchers(unsigned long iee_offset, struct key *key, struct watch_list *watchers); @@ -5433,7 +6110,7 @@ index 000000000000..2c7882d4f5be +void __iee_code _iee_set_key_state(unsigned long iee_offset, struct key *key, short state); +void __iee_code _iee_set_key_magic(unsigned long iee_offset, struct key *key, unsigned magic); +void __iee_code _iee_set_key_flags(unsigned long iee_offset, struct key *key, unsigned long flags); -+void __iee_code _iee_set_key_index_key(unsigned long iee_offset, struct key *key, struct keyring_index_key index_key); ++void __iee_code _iee_set_key_index_key(unsigned long iee_offset, struct key *key, struct keyring_index_key *index_key); +void __iee_code _iee_set_key_hash(unsigned long iee_offset, struct key *key, unsigned long hash); +void __iee_code _iee_set_key_len_desc(unsigned long iee_offset, struct key *key, unsigned long len_desc); +void __iee_code _iee_set_key_type(unsigned long iee_offset, struct key *key, struct key_type *type); @@ -5542,8 +6219,6 @@ index 000000000000..2c7882d4f5be + (iee_func)_iee_set_key_union, + (iee_func)_iee_set_key_struct, + (iee_func)_iee_set_key_payload, -+ (iee_func)_iee_write_key_payload, -+ (iee_func)_iee_write_key_payload_rcu_data0, + (iee_func)_iee_set_key_usage, + (iee_func)_iee_set_key_serial, + (iee_func)_iee_set_key_watchers, @@ -5589,7 +6264,7 @@ index 000000000000..2c7882d4f5be +void __iee_code _iee_write_koi_stack(unsigned long iee_offset, struct task_struct *tsk, unsigned long koi_stack) +{ + struct task_token *token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); -+ token->koi_stack = koi_stack; ++ token->koi_stack = (void *) koi_stack; +} + +unsigned long __iee_code _iee_read_token_ttbr1(unsigned long iee_offset, struct task_struct *tsk) @@ -5607,13 +6282,13 @@ index 000000000000..2c7882d4f5be +unsigned long __iee_code _iee_read_koi_kernel_stack(unsigned long iee_offset, struct task_struct *tsk) +{ + struct task_token *token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); -+ return token->koi_kernel_stack; ++ return (unsigned long) token->koi_kernel_stack; +} + +void __iee_code _iee_write_koi_kernel_stack(unsigned long iee_offset, struct task_struct *tsk, unsigned long kernel_stack) +{ + struct task_token *token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); -+ token->koi_kernel_stack = kernel_stack; ++ token->koi_kernel_stack = (void *) kernel_stack; +} + +unsigned long __iee_code _iee_read_koi_stack_base(unsigned long iee_offset, struct task_struct *tsk) @@ -5625,7 +6300,7 @@ index 000000000000..2c7882d4f5be +void __iee_code _iee_write_koi_stack_base(unsigned long iee_offset, struct task_struct *tsk, unsigned long koi_stack_base) +{ + struct task_token *token = (struct task_token *)((unsigned long)tsk + (unsigned long)iee_offset); -+ token->koi_stack_base = koi_stack_base; ++ token->koi_stack_base = (void *) koi_stack_base; +} + +static inline void iee_set_koi_pgd_writeable(unsigned long koi_pgd_addr, unsigned long iee_si_addr) @@ -5743,10 +6418,10 @@ index 000000000000..2c7882d4f5be + key->flags = flags; +} + -+void __iee_code _iee_set_key_index_key(unsigned long iee_offset, struct key *key, struct keyring_index_key index_key) ++void __iee_code _iee_set_key_index_key(unsigned long iee_offset, struct key *key, struct keyring_index_key *index_key) +{ + key = (struct key *)((unsigned long)key + iee_offset); -+ key->index_key = index_key; ++ key->index_key = *index_key; +} + +void __iee_code _iee_set_key_hash(unsigned long iee_offset, struct key *key, unsigned long hash) @@ -5886,18 +6561,6 @@ index 000000000000..2c7882d4f5be + #endif +} + -+void __iee_code _iee_write_key_payload_rcu_data0(unsigned long iee_offset, struct key *key, void *rcu_data0) -+{ -+ union key_payload *key_payload = (union key_payload *)__phys_to_iee(__pa(key->name_link.next)); -+ WRITE_ONCE(key_payload->rcu_data0, rcu_data0); -+} -+ -+void __iee_code _iee_write_key_payload(unsigned long iee_offset, struct key *key, union key_payload payload) -+{ -+ union key_payload *key_payload = (union key_payload *)__phys_to_iee(__pa(key->name_link.next)); -+ *key_payload = payload; -+} -+ +void __iee_code _iee_set_key_union(unsigned long iee_offset, struct key *key, struct key_union *key_union) +{ + key = (struct key *)((unsigned long)key + iee_offset); @@ -5980,10 +6643,12 @@ index 000000000000..2c7882d4f5be + struct page *page = NULL; + #ifdef CONFIG_ARCH_HAS_PTE_SPECIAL + if (likely(!pte_special(*src_pte))) ++ { + if (unlikely(pte_pfn(*src_pte) > highest_memmap_pfn)) + page = NULL; + else + page = pte_page(*src_pte); ++ } + #else + if((!unlikely(src_vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) || ((src_vma->vm_flags & VM_MIXEDMAP) && pfn_valid(pte_pfn(*src_pte))) || (!(src_vma->vm_flags & VM_MIXEDMAP) && !(pfn == src_vma->vm_pgoff + off) && is_cow_mapping(src_vma->vm_flags))) && !is_zero_pfn(pte_pfn(*src_pte)) && !unlikely(pte_pfn(*src_pte) > highest_memmap_pfn)) + page = pte_page(*src_pte); @@ -7071,24 +7736,43 @@ index 000000000000..2c7882d4f5be \ No newline at end of file diff --git a/arch/arm64/kernel/iee/pgtable_slab.c b/arch/arm64/kernel/iee/pgtable_slab.c new file mode 100644 -index 000000000000..1f98d639a315 +index 000000000000..abd3b3988250 --- /dev/null +++ b/arch/arm64/kernel/iee/pgtable_slab.c -@@ -0,0 +1,97 @@ +@@ -0,0 +1,107 @@ +#include +#include ++#include + +#define PGTABLE_INIT_ORDER 7 +struct kmem_cache *pgtable_jar; +struct kmem_cache *ptdesc_jar; -+extern void iee_set_freeptr(void **pptr, void *ptr); ++struct kmem_cache *pgd_jar; +unsigned long pgtable_jar_offset; ++unsigned long pgd_jar_offset; + +#ifdef CONFIG_PTP ++static inline void iee_ptdesc_init(struct page *page) ++{ ++ /* Alloc struct ptdesc from iee memory pool. */ ++ struct ptdesc *tmp = kmem_cache_alloc(ptdesc_jar, GFP_KERNEL | __GFP_ZERO); ++ spin_lock_init(&tmp->ptl); ++ /* Fill the iee ptdesc pointer array. */ ++ page_to_iee_ptdesc(page) = tmp; ++ /* We need a ptr point back to struct page for list operations. */ ++ ((struct ptdesc_t *)page_to_iee_ptdesc(page))->page = page; ++} ++ ++/* Free ptdesc and clear the iee ptdesc ptr. */ ++static inline void iee_ptdesc_free(struct page *page) ++{ ++ kmem_cache_free(ptdesc_jar, page_to_iee_ptdesc(page)); ++ page_to_iee_ptdesc(page) = NULL; ++} ++ +extern void early_pgtable_jar_alloc(struct kmem_cache *pgtable_jar); +void __init iee_pmd_pgtable_init(pud_t *pud) { + struct page *page; -+ struct ptdesc_t *tmp; + pmd_t *orig_pmd = pud_pgtable(*pud); + pmd_t *pmd; + int i; @@ -7098,16 +7782,12 @@ index 000000000000..1f98d639a315 + if (pmd_none(*pmd) || pmd_bad(*pmd)) + continue; + page = pmd_page(*pmd); -+ tmp = kmem_cache_alloc(ptdesc_jar, GFP_KERNEL | __GFP_ZERO); -+ spin_lock_init(&tmp->ptl); -+ ((struct slab_t *)page)->slab_cache = (struct kmem_cache *)tmp; -+ ((struct ptdesc_t *)(((struct slab_t *)page)->slab_cache))->slab = (struct slab_t *)page; ++ iee_ptdesc_init(page); + } +} + +void __init iee_pud_pgtable_init(p4d_t *p4d) { + struct page *page; -+ struct ptdesc_t *tmp; + pud_t *orig_pud = p4d_pgtable(*p4d); + pud_t *pud; + int i; @@ -7118,10 +7798,7 @@ index 000000000000..1f98d639a315 + continue; + iee_pmd_pgtable_init(pud); + page = pud_page(*pud); -+ tmp = kmem_cache_alloc(ptdesc_jar, GFP_KERNEL | __GFP_ZERO); -+ spin_lock_init(&tmp->ptl); -+ ((struct slab_t *)page)->slab_cache = (struct kmem_cache *)tmp; -+ ((struct ptdesc_t *)(((struct slab_t *)page)->slab_cache))->slab = (struct slab_t *)page; ++ iee_ptdesc_init(page); + } +} + @@ -7130,11 +7807,11 @@ index 000000000000..1f98d639a315 + int i; + pgd_t *pgd; + struct page* page; -+ struct ptdesc_t *tmp; + + ptdesc_jar = kmem_cache_create("ptdesc_jar", sizeof(struct ptdesc_t), 0, SLAB_PANIC|SLAB_RED_ZONE, NULL); + pgtable_jar = kmem_cache_create("pgtable_jar", PAGE_SIZE, PAGE_SIZE, + SLAB_PANIC, NULL); ++ pgd_jar = NULL; + for(i = 0; i < ((1 << (PGTABLE_INIT_ORDER))/nr_cpu_ids); i++) + { + early_pgtable_jar_alloc(pgtable_jar); @@ -7145,31 +7822,29 @@ index 000000000000..1f98d639a315 + continue; + iee_pud_pgtable_init((p4d_t *)pgd); + page = pgd_page(*pgd); -+ tmp = kmem_cache_alloc(ptdesc_jar, GFP_KERNEL | __GFP_ZERO); -+ spin_lock_init(&tmp->ptl); -+ ((struct slab_t *)page)->slab_cache = (struct kmem_cache *)tmp; -+ ((struct ptdesc_t *)(((struct slab_t *)page)->slab_cache))->slab = (struct slab_t *)page; ++ iee_ptdesc_init(page); + } +} -+#else -+void __init iee_pgtable_init(void) -+{ -+ ; -+} +#endif + +void *get_iee_pgtable_page(gfp_t gfpflags) +{ + struct page *page; + void *res = kmem_cache_alloc(pgtable_jar, gfpflags); -+ iee_set_freeptr((void **)((unsigned long)res + pgtable_jar_offset), NULL); ++ if (!res) { ++ panic("IEE PTP: alloc pgtable failed."); ++ return res; ++ } ++ iee_rw_gate(IEE_OP_SET_FREEPTR, (void **)((unsigned long)res + pgtable_jar_offset), NULL); + page = virt_to_page(res); -+ page_ref_inc(page); ++ // page_ref_inc(page); ++ iee_ptdesc_init(page); + return res; +} + +void free_iee_pgtable_page(void *obj) +{ ++ iee_ptdesc_free(virt_to_page(obj)); + kmem_cache_free(pgtable_jar, obj); +} \ No newline at end of file @@ -7223,7 +7898,7 @@ index 000000000000..9be8710b714a \ No newline at end of file diff --git a/arch/arm64/kernel/koi/koi.c b/arch/arm64/kernel/koi/koi.c new file mode 100644 -index 000000000000..aece03f85564 +index 000000000000..20daf4889ca6 --- /dev/null +++ b/arch/arm64/kernel/koi/koi.c @@ -0,0 +1,1688 @@ @@ -7291,7 +7966,7 @@ index 000000000000..aece03f85564 +#include "linux/slab.h" +#include "linux/string.h" +#include "linux/hashtable.h" -+ ++#include +// #define DEBUG + +#ifdef DEBUG @@ -7312,6 +7987,8 @@ index 000000000000..aece03f85564 +#ifdef CONFIG_IEE +extern unsigned long __iee_si_data_start[]; +extern unsigned long __iee_si_text_start[]; ++extern unsigned long _iee_read_token_ttbr1(unsigned long iee_offset, ++ struct task_struct *tsk); +#endif + +__koi_data unsigned long koi_swapper_ttbr1 = 0; @@ -7326,9 +8003,7 @@ index 000000000000..aece03f85564 +extern void koi_switch_to_ko_stack(unsigned long stack_top); +extern void init_ko_mm(struct mm_struct *ko_mm, pgd_t *pgdp); +extern void koi_check_and_switch_context(struct mm_struct *mm); -+extern void koi_add_page_mapping(unsigned long dst, unsigned long src); -+extern unsigned long _iee_read_token_ttbr1(unsigned long iee_offset, -+ struct task_struct *tsk); ++extern void koi_add_page_mapping(void *token, void *new); +/** +*struct koi_mem_list - maintain a linked list of free memory in the kernel +*@addr: stating address of this memory @@ -8917,7 +9592,7 @@ index 000000000000..aece03f85564 +#endif \ No newline at end of file diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c -index cea96ee75d22..cbddc8e464e4 100644 +index c4999d2d7ce8..601b5bc6a2ae 100644 --- a/arch/arm64/kernel/mte.c +++ b/arch/arm64/kernel/mte.c @@ -79,8 +79,13 @@ int memcmp_pages(struct page *page1, struct page *page2) @@ -8971,7 +9646,7 @@ index 068e5bb2661b..e545a2df805f 100644 /* ISB required for the kernel uaccess routines when setting TCF0. */ isb(); diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c -index 58a97861bfc5..c7839247327d 100644 +index 4bca7ad7b5e3..a584557625f7 100644 --- a/arch/arm64/kernel/proton-pack.c +++ b/arch/arm64/kernel/proton-pack.c @@ -551,7 +551,11 @@ static enum mitigation_state spectre_v4_enable_hw_mitigation(void) @@ -8986,7 +9661,7 @@ index 58a97861bfc5..c7839247327d 100644 set_pstate_ssbs(1); return SPECTRE_VULNERABLE; } -@@ -975,7 +979,11 @@ static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot) +@@ -987,7 +991,11 @@ static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot) if (arm64_kernel_unmapped_at_el0()) return; @@ -9061,6 +9736,98 @@ index d82fd6902ea8..84f4fce0b8bc 100644 /* * TTBR0 is only used for the identity mapping at this stage. Make it * point to zero page to avoid speculatively fetching new entries. +diff --git a/arch/arm64/kernel/sfi_bpf_arch.c b/arch/arm64/kernel/sfi_bpf_arch.c +new file mode 100644 +index 000000000000..1201cd11a5de +--- /dev/null ++++ b/arch/arm64/kernel/sfi_bpf_arch.c +@@ -0,0 +1,85 @@ ++#include ++#include ++#include ++ ++pte_t *bpf_sfi_get_ptep(u64 addr) ++{ ++ pgd_t *pgdp; ++ p4d_t *p4dp; ++ pud_t *pudp; ++ pmd_t *pmdp; ++ pte_t *ptep; ++ ++ /* DEBUG check pgd */ ++ // u64 ttbr1_phy, ttbr1_vir; ++ // __asm__ volatile( ++ // "mrs %0, ttbr1_el1\n\t" ++ // : "=r" (ttbr1_phy) ++ // :: ++ // ); ++ // pr_debug("phy = 0x%llx, after mask = 0x%llx\n", ttbr1_phy, (u64)(ttbr1_phy << 16) >> 16); ++ // ttbr1_vir = (u64)__phys_to_kimg((u64)(ttbr1_phy << 16) >> 16); ++ // pr_info("1, ttbr1_vir = 0x%llx, \n", ttbr1_vir); ++ // pr_info("2, init_mm.pgd = 0x%llx\n", (u64)init_mm.pgd); ++ // pr_info("3, swapper_pg_dir = 0x%llx\n", (u64)swapper_pg_dir); ++ ++ pgdp = pgd_offset(&init_mm, addr); ++ if (pgd_none(*pgdp) || pgd_bad(*pgdp)) { ++ pr_err("get pgdp of 0x%llx failed\n", addr); ++ return ERR_PTR(-ENOENT); ++ } ++ ++ p4dp = p4d_offset(pgdp, addr); ++ if (p4d_none(*p4dp) || p4d_bad(*p4dp)) { ++ pr_err("get p4dp of 0x%llx failed\n", addr); ++ return ERR_PTR(-ENOENT); ++ } ++ ++ /* IMPORTANT judge huge page first, then judge table */ ++ pudp = pud_offset(p4dp, addr); ++ if (pud_huge(*pudp)) { ++ // pud is huge page ++ pr_warn("pud of 0x%llx is huge page", addr); ++ // return (pte_t *)pudp; ++ return ERR_PTR(-ENOTSUPP); ++ } ++ if (pud_none(*pudp) || pud_bad(*pudp)) { ++ pr_err("get pudp of 0x%llx failed\n", addr); ++ return ERR_PTR(-ENOENT); ++ } ++ ++ pmdp = pmd_offset(pudp, addr); ++ if (pmd_huge(*pmdp)) { ++ // pmd is huge page ++ pr_warn("pmd of 0x%llx is huge page", addr); ++ // return (pte_t *)pmdp; ++ return ERR_PTR(-ENOTSUPP); ++ } ++ if (pmd_none(*pmdp) || pmd_bad(*pmdp)) { ++ pr_err("get pmdp of 0x%llx failed\n", addr); ++ return ERR_PTR(-ENOENT); ++ } ++ ++ ptep = pte_offset_kernel(pmdp, addr); ++ if (!ptep) { ++ pr_err("get ptep of 0x%llx failed\n", addr); ++ return ERR_PTR(-ENOENT); ++ } ++ ++ return ptep; ++} ++ ++int bpf_sfi_hook_kernel_fault(u64 addr) ++{ ++ pte_t *ptep; ++ ++ ptep = bpf_sfi_get_ptep(addr); ++ if (IS_ERR(ptep)) ++ return PTR_ERR(ptep); ++ ++ if (pte_val(*ptep) & PTE_BPF_SFI_GP) { ++ return true; ++ } ++ else ++ return false; ++} +\ No newline at end of file diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index b7b7afb4a8c7..168a9390d6e9 100644 --- a/arch/arm64/kernel/traps.c @@ -9099,7 +9866,7 @@ index b7b7afb4a8c7..168a9390d6e9 100644 * bad_el0_sync handles unexpected, but potentially recoverable synchronous * exceptions taken from EL0. diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S -index 3cd7e76cc562..8f074828f706 100644 +index 3cd7e76cc562..008b69a83b91 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -134,6 +134,51 @@ jiffies = jiffies_64; @@ -9168,7 +9935,7 @@ index 3cd7e76cc562..8f074828f706 100644 *(.gnu.warning) } -@@ -318,6 +366,18 @@ SECTIONS +@@ -318,6 +366,13 @@ SECTIONS . += INIT_DIR_SIZE; init_pg_end = .; @@ -9177,11 +9944,6 @@ index 3cd7e76cc562..8f074828f706 100644 + init_iee_stack_begin = .; + . += PAGE_SIZE*4; + init_iee_stack_end = .; -+ -+ . = ALIGN(PAGE_SIZE); -+ init_iee_si_stack_begin = .; -+ . += PAGE_SIZE*4; -+ init_iee_si_stack_end = .; + #endif + . = ALIGN(SEGMENT_ALIGN); @@ -9389,10 +10151,31 @@ index 188197590fc9..b6d8a7d0aeca 100644 } early_initcall(asids_init); diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c -index 4ea07caba71c..909c75bf9e41 100644 +index 4ea07caba71c..00f85acfc671 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c -@@ -261,7 +261,15 @@ int __ptep_set_access_flags(struct vm_area_struct *vma, +@@ -26,6 +26,9 @@ + #include + #include + #include ++#ifdef CONFIG_HIVE ++#include ++#endif + + #include + #include +@@ -44,6 +47,10 @@ + #include + #include + ++#ifdef CONFIG_HIVE ++extern int bpf_sfi_hook_kernel_fault(u64 addr); ++#endif ++ + static int sysctl_machine_check_safe = IS_ENABLED(CONFIG_ARCH_HAS_COPY_MC); + + #ifdef CONFIG_ARCH_HAS_COPY_MC +@@ -261,7 +268,15 @@ int __ptep_set_access_flags(struct vm_area_struct *vma, pteval ^= PTE_RDONLY; pteval |= pte_val(entry); pteval ^= PTE_RDONLY; @@ -9408,7 +10191,22 @@ index 4ea07caba71c..909c75bf9e41 100644 } while (pteval != old_pteval); /* Invalidate a stale read-only entry */ -@@ -376,8 +384,13 @@ static void do_tag_recovery(unsigned long addr, unsigned long esr, +@@ -335,6 +350,14 @@ static void die_kernel_fault(const char *msg, unsigned long addr, + { + bust_spinlocks(1); + ++// #ifdef CONFIG_HIVE ++// if (bpf_sfi_hook_kernel_fault(addr)) { ++// pr_err("detected bpf sfi guard page %lx access\n", addr); ++// regs->pc += 4; ++// return; ++// } ++// #endif ++ + pr_alert("Unable to handle kernel %s at virtual address %016lx\n", msg, + addr); + +@@ -376,8 +399,13 @@ static void do_tag_recovery(unsigned long addr, unsigned long esr, * It will be done lazily on the other CPUs when they will hit a * tag fault. */ @@ -9423,7 +10221,7 @@ index 4ea07caba71c..909c75bf9e41 100644 } diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c -index bfc02568805a..580ecb596d2d 100644 +index a55b36d04590..fb80a7251a8e 100644 --- a/arch/arm64/mm/fixmap.c +++ b/arch/arm64/mm/fixmap.c @@ -32,6 +32,22 @@ static pte_t bm_pte[NR_BM_PTE_TABLES][PTRS_PER_PTE] __page_aligned_bss; @@ -9449,49 +10247,53 @@ index bfc02568805a..580ecb596d2d 100644 static inline pte_t *fixmap_pte(unsigned long addr) { return &bm_pte[BM_PTE_TABLE_IDX(addr)][pte_index(addr)]; -@@ -44,7 +60,11 @@ static void __init early_fixmap_init_pte(pmd_t *pmdp, unsigned long addr) +@@ -44,8 +60,12 @@ static void __init early_fixmap_init_pte(pmd_t *pmdp, unsigned long addr) if (pmd_none(pmd)) { ptep = bm_pte[BM_PTE_TABLE_IDX(addr)]; + #ifdef CONFIG_PTP -+ __iee_pmd_populate_pre_init(pmdp, __pa_symbol(ptep), PMD_TYPE_TABLE); ++ __iee_pmd_populate_pre_init(pmdp, __pa_symbol(ptep), PMD_TYPE_TABLE | PMD_TABLE_AF); + #else - __pmd_populate(pmdp, __pa_symbol(ptep), PMD_TYPE_TABLE); + __pmd_populate(pmdp, __pa_symbol(ptep), + PMD_TYPE_TABLE | PMD_TABLE_AF); + #endif } } -@@ -55,8 +75,13 @@ static void __init early_fixmap_init_pmd(pud_t *pudp, unsigned long addr, +@@ -56,10 +76,14 @@ static void __init early_fixmap_init_pmd(pud_t *pudp, unsigned long addr, pud_t pud = READ_ONCE(*pudp); pmd_t *pmdp; - if (pud_none(pud)) + if (pud_none(pud)) { + #ifdef CONFIG_PTP -+ __iee_pud_populate_pre_init(pudp, __pa_symbol(bm_pmd), PUD_TYPE_TABLE); ++ __iee_pud_populate_pre_init(pudp, __pa_symbol(bm_pmd), PUD_TYPE_TABLE | PUD_TABLE_AF); + #else - __pud_populate(pudp, __pa_symbol(bm_pmd), PUD_TYPE_TABLE); + __pud_populate(pudp, __pa_symbol(bm_pmd), + PUD_TYPE_TABLE | PUD_TABLE_AF); +- + #endif + } - pmdp = pmd_offset_kimg(pudp, addr); do { -@@ -82,8 +107,13 @@ static void __init early_fixmap_init_pud(p4d_t *p4dp, unsigned long addr, + next = pmd_addr_end(addr, end); +@@ -84,9 +108,14 @@ static void __init early_fixmap_init_pud(p4d_t *p4dp, unsigned long addr, BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES)); } - if (p4d_none(p4d)) + if (p4d_none(p4d)) { + #ifdef CONFIG_PTP -+ __iee_p4d_populate_pre_init(p4dp, __pa_symbol(bm_pud), P4D_TYPE_TABLE); ++ __iee_p4d_populate_pre_init(p4dp, __pa_symbol(bm_pud), P4D_TYPE_TABLE | P4D_TABLE_AF); + #else - __p4d_populate(p4dp, __pa_symbol(bm_pud), P4D_TYPE_TABLE); + __p4d_populate(p4dp, __pa_symbol(bm_pud), + P4D_TYPE_TABLE | P4D_TABLE_AF); + #endif + } pudp = pud_offset_kimg(p4dp, addr); early_fixmap_init_pmd(pudp, addr, end); -@@ -106,6 +136,27 @@ void __init early_fixmap_init(void) +@@ -109,6 +138,27 @@ void __init early_fixmap_init(void) early_fixmap_init_pud(p4dp, addr, end); } @@ -9519,7 +10321,7 @@ index bfc02568805a..580ecb596d2d 100644 /* * Unusually, this is also called in IRQ context (ghes_iounmap_irq) so if we * ever need to use IPIs for TLB broadcasting, then we're in trouble here. -@@ -121,9 +172,17 @@ void __set_fixmap(enum fixed_addresses idx, +@@ -124,9 +174,17 @@ void __set_fixmap(enum fixed_addresses idx, ptep = fixmap_pte(addr); if (pgprot_val(flags)) { @@ -9537,7 +10339,7 @@ index bfc02568805a..580ecb596d2d 100644 flush_tlb_kernel_range(addr, addr+PAGE_SIZE); } } -@@ -179,8 +238,13 @@ void __init fixmap_copy(pgd_t *pgdir) +@@ -182,8 +240,13 @@ void __init fixmap_copy(pgd_t *pgdir) * live in the carveout for the swapper_pg_dir. We can simply * re-use the existing dir for the fixmap. */ @@ -9551,7 +10353,7 @@ index bfc02568805a..580ecb596d2d 100644 } else if (CONFIG_PGTABLE_LEVELS > 3) { pgd_t *bm_pgdp; p4d_t *bm_p4dp; -@@ -194,9 +258,15 @@ void __init fixmap_copy(pgd_t *pgdir) +@@ -197,9 +260,15 @@ void __init fixmap_copy(pgd_t *pgdir) BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES)); bm_pgdp = pgd_offset_pgd(pgdir, FIXADDR_TOT_START); bm_p4dp = p4d_offset(bm_pgdp, FIXADDR_TOT_START); @@ -9568,7 +10370,7 @@ index bfc02568805a..580ecb596d2d 100644 BUG(); } diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c -index 66a7fff9f373..fa3726fb793d 100644 +index 66a7fff9f373..fdd5ad51307d 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -56,8 +56,20 @@ @@ -9645,8 +10447,19 @@ index 66a7fff9f373..fa3726fb793d 100644 /* * Register the kernel text, kernel data, initrd, and initial +@@ -579,6 +615,10 @@ void __init bootmem_init(void) + * done after the fixed reservations + */ + sparse_init(); ++#ifdef CONFIG_PTP ++ extern void iee_ptdesc_sparse_init(void); ++ iee_ptdesc_sparse_init(); ++#endif + zone_sizes_init(); + + /* diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c -index 31f04f19b635..753fa8d887f3 100644 +index c846cc54e9ce..1148d95e4888 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -6,6 +6,7 @@ @@ -9657,7 +10470,7 @@ index 31f04f19b635..753fa8d887f3 100644 #include #include #include -@@ -41,6 +42,14 @@ +@@ -41,6 +42,15 @@ #include #include #include @@ -9665,6 +10478,7 @@ index 31f04f19b635..753fa8d887f3 100644 +#include +#include +#include ++#include +#endif +#ifdef CONFIG_PTP +#include @@ -9672,7 +10486,7 @@ index 31f04f19b635..753fa8d887f3 100644 #define NO_BLOCK_MAPPINGS BIT(0) #define NO_CONT_MAPPINGS BIT(1) -@@ -77,8 +86,249 @@ EXPORT_SYMBOL(empty_zero_page); +@@ -77,8 +87,236 @@ EXPORT_SYMBOL(empty_zero_page); static DEFINE_SPINLOCK(swapper_pgdir_lock); static DEFINE_MUTEX(fixmap_lock); @@ -9785,19 +10599,6 @@ index 31f04f19b635..753fa8d887f3 100644 + +/* Funcs to set fixmap before iee initialized. */ +bool pgattr_change_is_safe(u64 old, u64 new); -+static int iee_pud_set_huge_fixmap(pud_t *pudp, phys_addr_t phys, pgprot_t prot) -+{ -+ pud_t new_pud = pfn_pud(__phys_to_pfn(phys), mk_pud_sect_prot(prot)); -+ -+ /* Only allow permission changes for now */ -+ if (!pgattr_change_is_safe(READ_ONCE(pud_val(*pudp)), -+ pud_val(new_pud))) -+ return 0; -+ -+ VM_BUG_ON(phys & ~PUD_MASK); -+ iee_set_fixmap_pud_pre_init(pudp, new_pud); -+ return 1; -+} + +static int iee_pmd_set_huge_fixmap(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot) +{ @@ -9893,7 +10694,7 @@ index 31f04f19b635..753fa8d887f3 100644 + isb(); +} + -+void koi_remove_page_mapping(unsigned long token) { ++void koi_remove_page_mapping(unsigned long token, void *__unused, unsigned long order) { + pgd_t *pgdir = swapper_pg_dir; + pgd_t *pgdp = pgd_offset_pgd(pgdir, token); + @@ -9922,7 +10723,7 @@ index 31f04f19b635..753fa8d887f3 100644 pgd_t *fixmap_pgdp; spin_lock(&swapper_pgdir_lock); -@@ -91,6 +341,7 @@ void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd) +@@ -91,6 +329,7 @@ void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd) */ pgd_clear_fixmap(); spin_unlock(&swapper_pgdir_lock); @@ -9930,7 +10731,7 @@ index 31f04f19b635..753fa8d887f3 100644 } pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, -@@ -104,6 +355,34 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, +@@ -104,6 +343,34 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, } EXPORT_SYMBOL(phys_mem_access_prot); @@ -9965,7 +10766,7 @@ index 31f04f19b635..753fa8d887f3 100644 static phys_addr_t __init early_pgtable_alloc(int shift) { phys_addr_t phys; -@@ -119,7 +398,11 @@ static phys_addr_t __init early_pgtable_alloc(int shift) +@@ -119,7 +386,11 @@ static phys_addr_t __init early_pgtable_alloc(int shift) * slot will be free, so we can (ab)use the FIX_PTE slot to initialise * any level of table. */ @@ -9977,7 +10778,7 @@ index 31f04f19b635..753fa8d887f3 100644 memset(ptr, 0, PAGE_SIZE); -@@ -127,10 +410,15 @@ static phys_addr_t __init early_pgtable_alloc(int shift) +@@ -127,10 +398,15 @@ static phys_addr_t __init early_pgtable_alloc(int shift) * Implicit barriers also ensure the zeroed page is visible to the page * table walker */ @@ -9993,7 +10794,7 @@ index 31f04f19b635..753fa8d887f3 100644 bool pgattr_change_is_safe(u64 old, u64 new) { -@@ -179,7 +467,11 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end, +@@ -179,7 +455,11 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end, do { pte_t old_pte = __ptep_get(ptep); @@ -10005,7 +10806,7 @@ index 31f04f19b635..753fa8d887f3 100644 /* * After the PTE entry has been populated once, we -@@ -212,7 +504,11 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr, +@@ -212,7 +492,11 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr, pmdval |= PMD_TABLE_PXN; BUG_ON(!pgtable_alloc); pte_phys = pgtable_alloc(PAGE_SHIFT); @@ -10017,7 +10818,7 @@ index 31f04f19b635..753fa8d887f3 100644 pmd = READ_ONCE(*pmdp); } BUG_ON(pmd_bad(pmd)); -@@ -247,9 +543,17 @@ static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end, +@@ -247,9 +531,17 @@ static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end, next = pmd_addr_end(addr, end); /* try section mapping first */ @@ -10035,7 +10836,7 @@ index 31f04f19b635..753fa8d887f3 100644 /* * After the PMD entry has been populated once, we -@@ -290,7 +594,11 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr, +@@ -290,7 +582,11 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr, pudval |= PUD_TABLE_PXN; BUG_ON(!pgtable_alloc); pmd_phys = pgtable_alloc(PMD_SHIFT); @@ -10048,7 +10849,7 @@ index 31f04f19b635..753fa8d887f3 100644 pud = READ_ONCE(*pudp); } BUG_ON(pud_bad(pud)); -@@ -343,10 +651,21 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end, +@@ -343,6 +639,13 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end, /* * For 4K granule only, attempt to put down a 1GB block */ @@ -10062,15 +10863,7 @@ index 31f04f19b635..753fa8d887f3 100644 if (pud_sect_supported() && ((addr | next | phys) & ~PUD_MASK) == 0 && (flags & NO_BLOCK_MAPPINGS) == 0) { -+ #ifdef CONFIG_PTP -+ iee_pud_set_huge_fixmap(pudp, phys, prot); -+ #else - pud_set_huge(pudp, phys, prot); -+ #endif - - /* - * After the PUD entry has been populated once, we -@@ -361,6 +680,7 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end, +@@ -361,6 +664,7 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end, BUG_ON(pud_val(old_pud) != 0 && pud_val(old_pud) != READ_ONCE(pud_val(*pudp))); } @@ -10078,7 +10871,7 @@ index 31f04f19b635..753fa8d887f3 100644 phys += next - addr; } while (pudp++, addr = next, addr != end); -@@ -375,6 +695,10 @@ static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys, +@@ -375,6 +679,10 @@ static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys, { unsigned long addr, end, next; pgd_t *pgdp = pgd_offset_pgd(pgdir, virt); @@ -10089,7 +10882,7 @@ index 31f04f19b635..753fa8d887f3 100644 /* * If the virtual and physical address don't have the same offset -@@ -391,10 +715,14 @@ static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys, +@@ -391,10 +699,14 @@ static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys, next = pgd_addr_end(addr, end); alloc_init_pud(pgdp, addr, next, phys, prot, pgtable_alloc, flags); @@ -10105,37 +10898,38 @@ index 31f04f19b635..753fa8d887f3 100644 static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys, unsigned long virt, phys_addr_t size, pgprot_t prot, -@@ -414,90 +742,364 @@ void create_kpti_ng_temp_pgd(pgd_t *pgdir, phys_addr_t phys, unsigned long virt, +@@ -414,103 +726,363 @@ void create_kpti_ng_temp_pgd(pgd_t *pgdir, phys_addr_t phys, unsigned long virt, phys_addr_t (*pgtable_alloc)(int), int flags); #endif -static phys_addr_t __pgd_pgtable_alloc(int shift) +#ifdef CONFIG_PTP -+static int __init iee_pud_set_huge_pre_init(pud_t *pudp, phys_addr_t phys, pgprot_t prot) ++static int __init iee_pmd_set_huge_pre_init(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot) { - void *ptr = (void *)__get_free_page(GFP_PGTABLE_KERNEL); - BUG_ON(!ptr); -+ pud_t new_pud = pfn_pud(__phys_to_pfn(phys), mk_pud_sect_prot(prot)); ++ pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), mk_pmd_sect_prot(prot)); - /* Ensure the zeroed page is visible to the page table walker */ - dsb(ishst); - return __pa(ptr); + /* Only allow permission changes for now */ -+ if (!pgattr_change_is_safe(READ_ONCE(pud_val(*pudp)), -+ pud_val(new_pud))) ++ if (!pgattr_change_is_safe(READ_ONCE(pmd_val(*pmdp)), ++ pmd_val(new_pmd))) + return 0; + -+ VM_BUG_ON(phys & ~PUD_MASK); -+ iee_set_pud_pre_init(pudp, new_pud); ++ VM_BUG_ON(phys & ~PMD_MASK); ++ iee_set_pmd_pre_init(pmdp, new_pmd); + return 1; } -static phys_addr_t pgd_pgtable_alloc(int shift) -+static int __init iee_pmd_set_huge_pre_init(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot) ++static __init void iee_init_pte_pre_init(pmd_t *pmdp, unsigned long addr, unsigned long end, ++ phys_addr_t phys, pgprot_t prot) { - phys_addr_t pa = __pgd_pgtable_alloc(shift); - struct ptdesc *ptdesc = page_ptdesc(phys_to_page(pa)); -+ pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), mk_pmd_sect_prot(prot)); ++ pte_t *ptep; - /* - * Call proper page table ctor in case later we need to @@ -10149,16 +10943,13 @@ index 31f04f19b635..753fa8d887f3 100644 - BUG_ON(!pagetable_pte_ctor(ptdesc)); - else if (shift == PMD_SHIFT) - BUG_ON(!pagetable_pmd_ctor(ptdesc)); -+ /* Only allow permission changes for now */ -+ if (!pgattr_change_is_safe(READ_ONCE(pmd_val(*pmdp)), -+ pmd_val(new_pmd))) -+ return 0; ++ ptep = pte_set_fixmap_offset_init(pmdp, addr); ++ do { ++ pte_t old_pte = READ_ONCE(*ptep); - return pa; -+ VM_BUG_ON(phys & ~PMD_MASK); -+ iee_set_pmd_pre_init(pmdp, new_pmd); -+ return 1; - } +-} ++ iee_set_pte_pre_init(ptep, pfn_pte(__phys_to_pfn(phys), prot)); -/* - * This function can only be used to modify existing table entries, @@ -10167,9 +10958,7 @@ index 31f04f19b635..753fa8d887f3 100644 - */ -void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt, - phys_addr_t size, pgprot_t prot) -+static __init void iee_init_pte_pre_init(pmd_t *pmdp, unsigned long addr, unsigned long end, -+ phys_addr_t phys, pgprot_t prot) - { +-{ - if (virt < PAGE_OFFSET) { - pr_warn("BUG: not creating mapping for %pa at 0x%016lx - outside kernel range\n", - &phys, virt); @@ -10177,94 +10966,102 @@ index 31f04f19b635..753fa8d887f3 100644 - } - __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, - NO_CONT_MAPPINGS); --} -+ pte_t *ptep; - --void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, -- unsigned long virt, phys_addr_t size, -- pgprot_t prot, bool page_mappings_only) --{ -- int flags = 0; -+ ptep = pte_set_fixmap_offset_init(pmdp, addr); -+ do { -+ pte_t old_pte = READ_ONCE(*ptep); - -- BUG_ON(mm == &init_mm); -+ iee_set_pte_pre_init(ptep, pfn_pte(__phys_to_pfn(phys), prot)); - -- if (page_mappings_only) -- flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; + /* + * After the PTE entry has been populated once, we + * only allow updates to the permission attributes. + */ + BUG_ON(!pgattr_change_is_safe(pte_val(old_pte), + READ_ONCE(pte_val(*ptep)))); - -- __create_pgd_mapping(mm->pgd, phys, virt, size, prot, -- pgd_pgtable_alloc, flags); ++ + phys += PAGE_SIZE; + } while (ptep++, addr += PAGE_SIZE, addr != end); + + pte_clear_fixmap_init(); } --static void update_mapping_prot(phys_addr_t phys, unsigned long virt, -- phys_addr_t size, pgprot_t prot) +-void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, +- unsigned long virt, phys_addr_t size, +- pgprot_t prot, bool page_mappings_only) +static __init void iee_alloc_init_cont_pte_pre_init(pmd_t *pmdp, unsigned long addr, + unsigned long end, phys_addr_t phys, + pgprot_t prot, + phys_addr_t (*pgtable_alloc)(int), + int flags) { -- if (virt < PAGE_OFFSET) { -- pr_warn("BUG: not updating mapping for %pa at 0x%016lx - outside kernel range\n", -- &phys, virt); -- return; +- int flags = 0; + unsigned long next; + pmd_t pmd = READ_ONCE(*pmdp); -+ + +- BUG_ON(mm == &init_mm); + BUG_ON(pmd_sect(pmd)); + if (pmd_none(pmd)) { + pmdval_t pmdval = PMD_TYPE_TABLE | PMD_TABLE_UXN; + phys_addr_t pte_phys; -+ + +- if (page_mappings_only) +- flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; + if (flags & NO_EXEC_MAPPINGS) + pmdval |= PMD_TABLE_PXN; + BUG_ON(!pgtable_alloc); + pte_phys = pgtable_alloc(PAGE_SHIFT); + __iee_pmd_populate_pre_init(pmdp, pte_phys, pmdval); + pmd = READ_ONCE(*pmdp); - } ++ } + BUG_ON(pmd_bad(pmd)); -- __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, -- NO_CONT_MAPPINGS); +- __create_pgd_mapping(mm->pgd, phys, virt, size, prot, +- pgd_pgtable_alloc, flags); +-} + do { + pgprot_t __prot = prot; -- /* flush the TLBs after updating live kernel mappings */ -- flush_tlb_kernel_range(virt, virt + size); +-static void update_mapping_prot(phys_addr_t phys, unsigned long virt, +- phys_addr_t size, pgprot_t prot) +-{ +- if (virt < PAGE_OFFSET) { +- pr_warn("BUG: not updating mapping for %pa at 0x%016lx - outside kernel range\n", +- &phys, virt); +- return; +- } + next = pte_cont_addr_end(addr, end); -+ + +- __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, +- NO_CONT_MAPPINGS); + /* use a contiguous mapping if the range is suitably aligned */ + if ((((addr | next | phys) & ~CONT_PTE_MASK) == 0) && + (flags & NO_CONT_MAPPINGS) == 0) + __prot = __pgprot(pgprot_val(prot) | PTE_CONT); -+ + +- /* flush the TLBs after updating live kernel mappings */ +- flush_tlb_kernel_range(virt, virt + size); +-} + iee_init_pte_pre_init(pmdp, addr, next, phys, __prot); -+ + +-static void __init __map_memblock(pgd_t *pgdp, phys_addr_t start, +- phys_addr_t end, pgprot_t prot, int flags) +-{ +- __create_pgd_mapping(pgdp, start, __phys_to_virt(start), end - start, +- prot, early_pgtable_alloc, flags); + phys += next - addr; + } while (addr = next, addr != end); -+} -+ + } + +-void __init mark_linear_text_alias_ro(void) +static __init void iee_init_pmd_pre_init(pud_t *pudp, unsigned long addr, unsigned long end, + phys_addr_t phys, pgprot_t prot, + phys_addr_t (*pgtable_alloc)(int), int flags) -+{ + { +- /* +- * Remove the write permissions from the linear alias of .text/.rodata +- */ +- update_mapping_prot(__pa_symbol(_stext), (unsigned long)lm_alias(_stext), +- (unsigned long)__init_begin - (unsigned long)_stext, +- PAGE_KERNEL_RO); +-} + unsigned long next; + pmd_t *pmdp; -+ + +-#ifdef CONFIG_KFENCE + pmdp = pmd_set_fixmap_offset_init(pudp, addr); + do { + pmd_t old_pmd = READ_ONCE(*pmdp); @@ -10512,38 +11309,40 @@ index 31f04f19b635..753fa8d887f3 100644 + + /* flush the TLBs after updating live kernel mappings */ + flush_tlb_kernel_range(virt, virt + size); - } - - static void __init __map_memblock(pgd_t *pgdp, phys_addr_t start, - phys_addr_t end, pgprot_t prot, int flags) - { ++} ++ ++static void __init __map_memblock(pgd_t *pgdp, phys_addr_t start, ++ phys_addr_t end, pgprot_t prot, int flags) ++{ + #ifdef CONFIG_PTP + __iee_create_pgd_mapping_pre_init(pgdp, start, __phys_to_virt(start), end - start, + prot, early_pgtable_alloc, flags); + #else - __create_pgd_mapping(pgdp, start, __phys_to_virt(start), end - start, - prot, early_pgtable_alloc, flags); ++ __create_pgd_mapping(pgdp, start, __phys_to_virt(start), end - start, ++ prot, early_pgtable_alloc, flags); + #endif - } - - void __init mark_linear_text_alias_ro(void) -@@ -645,157 +1247,815 @@ void mark_rodata_ro(void) - debug_checkwx(); - } - --static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end, -- pgprot_t prot, struct vm_struct *vma, -- int flags, unsigned long vm_flags) -+static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end, -+ pgprot_t prot, struct vm_struct *vma, -+ int flags, unsigned long vm_flags) -+{ -+ phys_addr_t pa_start = __pa_symbol(va_start); -+ unsigned long size = va_end - va_start; ++} + -+ BUG_ON(!PAGE_ALIGNED(pa_start)); -+ BUG_ON(!PAGE_ALIGNED(size)); ++void __init mark_linear_text_alias_ro(void) ++{ ++ /* ++ * Remove the write permissions from the linear alias of .text/.rodata ++ */ ++ update_mapping_prot(__pa_symbol(_stext), (unsigned long)lm_alias(_stext), ++ (unsigned long)__init_begin - (unsigned long)_stext, ++ PAGE_KERNEL_RO); ++} + ++#ifdef CONFIG_KFENCE + + bool __ro_after_init kfence_early_init = !!CONFIG_KFENCE_SAMPLE_INTERVAL; + +@@ -655,147 +1227,808 @@ static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end, + BUG_ON(!PAGE_ALIGNED(pa_start)); + BUG_ON(!PAGE_ALIGNED(size)); + +- __create_pgd_mapping(pgdp, pa_start, (unsigned long)va_start, size, prot, +- early_pgtable_alloc, flags); + #ifdef CONFIG_PTP + __iee_create_pgd_mapping_pre_init(pgdp, pa_start, (unsigned long)va_start, size, prot, + early_pgtable_alloc, flags); @@ -10582,9 +11381,9 @@ index 31f04f19b635..753fa8d887f3 100644 + + /* Map only the text into the trampoline page table */ + memset(tramp_pg_dir, 0, PGD_SIZE); -+ #ifdef CONFIG_PTP -+ iee_set_logical_mem_ro((unsigned long)tramp_pg_dir); -+ #endif ++ // #ifdef CONFIG_PTP ++ // iee_set_logical_mem_ro((unsigned long)tramp_pg_dir); ++ // #endif + __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, + entry_tramp_text_size(), prot, + __pgd_pgtable_alloc, NO_BLOCK_MAPPINGS); @@ -10774,6 +11573,7 @@ index 31f04f19b635..753fa8d887f3 100644 +} + +#ifdef CONFIG_IEE ++#ifndef CONFIG_PTP +static void set_init_iee_stack_page(unsigned long addr) +{ + unsigned long iee_addr = __phys_to_iee(__pa_symbol(addr)); @@ -10819,6 +11619,7 @@ index 31f04f19b635..753fa8d887f3 100644 + flush_tlb_kernel_range(addr, addr+4*PAGE_SIZE); + isb(); +} ++#endif + +static void __create_pgd_mapping_for_iee_locked(pgd_t *pgdir, phys_addr_t phys, + unsigned long virt, phys_addr_t size, @@ -10984,7 +11785,7 @@ index 31f04f19b635..753fa8d887f3 100644 +{ + unsigned long va; + // Record current TCR val after system init. -+ iee_si_tcr = read_sysreg(tcr_el1) & ~(SYS_TCR_IEE_SI); ++ // iee_si_tcr = read_sysreg(tcr_el1) & ~(SYS_TCR_IEE_SI); + // CNP maybe enable. + if (system_supports_cnp()) { + iee_base_swapper_pg_dir |= TTBR_CNP_BIT; @@ -11085,40 +11886,21 @@ index 31f04f19b635..753fa8d887f3 100644 +} + +static void __init init_iee_for_one_region(pgd_t *pgdir, unsigned long va_start, unsigned long va_end) - { -- phys_addr_t pa_start = __pa_symbol(va_start); -- unsigned long size = va_end - va_start; -- -- BUG_ON(!PAGE_ALIGNED(pa_start)); -- BUG_ON(!PAGE_ALIGNED(size)); -- -- __create_pgd_mapping(pgdp, pa_start, (unsigned long)va_start, size, prot, -- early_pgtable_alloc, flags); -- -- if (!(vm_flags & VM_NO_GUARD)) -- size += PAGE_SIZE; ++{ + unsigned long addr, end, next; + pgd_t *pgdp = pgd_offset_pgd(pgdir, va_start); - -- vma->addr = va_start; -- vma->phys_addr = pa_start; -- vma->size = size; -- vma->flags = VM_MAP | vm_flags; -- vma->caller = __builtin_return_address(0); ++ + addr = va_start & PAGE_MASK; + end = PAGE_ALIGN(va_end); - -- vm_area_add_early(vma); ++ + do { + next = pgd_addr_end(addr, end); + move_pud_table_into_iee(pgdp, addr, next); + } while (pgdp++, addr = next, addr != end); - } - --static pgprot_t kernel_exec_prot(void) ++} ++ +static void __init init_iee(void) - { -- return rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC; ++{ + unsigned long iee_addr; + phys_addr_t start, end; + u64 i; @@ -11158,110 +11940,124 @@ index 31f04f19b635..753fa8d887f3 100644 + init_iee_for_one_region(pgdp, (unsigned long)__va(start), (unsigned long)__va(end)); + init_iee_for_one_region(pgdp, (unsigned long)__phys_to_iee(start), (unsigned long)__phys_to_iee(end)); + } - } - --#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 --static int __init map_entry_trampoline(void) ++} ++ +static void set_init_iee_stack_page_pre_init(unsigned long addr) - { -- int i; ++{ + unsigned long iee_addr = __phys_to_iee(__pa_symbol(addr)); + pgd_t *pgdir = swapper_pg_dir; + pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); -- pgprot_t prot = kernel_exec_prot(); -- phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start); +- if (!(vm_flags & VM_NO_GUARD)) +- size += PAGE_SIZE; + p4d_t *p4dp = p4d_offset(pgdp, addr); + p4d_t p4d = READ_ONCE(*p4dp); +- vma->addr = va_start; +- vma->phys_addr = pa_start; +- vma->size = size; +- vma->flags = VM_MAP | vm_flags; +- vma->caller = __builtin_return_address(0); ++ pud_t *pudp = pud_offset(p4dp, addr); + +- vm_area_add_early(vma); +-} ++ pmd_t *pmdp = pmd_offset(pudp, addr); + +-static pgprot_t kernel_exec_prot(void) +-{ +- return rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC; +-} ++ pte_t *ptep = pte_offset_kernel(pmdp, addr); + +-#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 +-static int __init map_entry_trampoline(void) +-{ + int i; ++ for(i = 0; i < 4; i++) ++ { ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(pte_val(pte) & ~PTE_VALID); ++ iee_set_pte_pre_init(ptep, pte); ++ ptep++; ++ } + +- pgprot_t prot = kernel_exec_prot(); +- phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start); ++ pgdp = pgd_offset_pgd(pgdir, iee_addr); + - /* The trampoline is always mapped and can therefore be global */ - pgprot_val(prot) &= ~PTE_NG; -+ pud_t *pudp = pud_offset(p4dp, addr); ++ p4dp = p4d_offset(pgdp, iee_addr); ++ p4d = READ_ONCE(*p4dp); - /* Map only the text into the trampoline page table */ - memset(tramp_pg_dir, 0, PGD_SIZE); - __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, - entry_tramp_text_size(), prot, - __pgd_pgtable_alloc, NO_BLOCK_MAPPINGS); -+ pmd_t *pmdp = pmd_offset(pudp, addr); ++ pudp = pud_offset(p4dp, iee_addr); - /* Map both the text and data into the kernel page table */ - for (i = 0; i < DIV_ROUND_UP(entry_tramp_text_size(), PAGE_SIZE); i++) - __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i, - pa_start + i * PAGE_SIZE, prot); -+ pte_t *ptep = pte_offset_kernel(pmdp, addr); ++ pmdp = pmd_offset(pudp, iee_addr); - if (IS_ENABLED(CONFIG_RELOCATABLE)) - __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i, - pa_start + i * PAGE_SIZE, PAGE_KERNEL_RO); -+ int i; ++ ptep = pte_offset_kernel(pmdp, iee_addr); + +- return 0; + for(i = 0; i < 4; i++) + { + pte_t pte = READ_ONCE(*ptep); -+ pte = __pte(pte_val(pte) & ~PTE_VALID); ++ pte = __pte(pte_val(pte) | PTE_VALID); + iee_set_pte_pre_init(ptep, pte); + ptep++; + } - -- return 0; --} ++ flush_tlb_kernel_range(addr, addr+4*PAGE_SIZE); ++ isb(); + } -core_initcall(map_entry_trampoline); -#endif -+ pgdp = pgd_offset_pgd(pgdir, iee_addr); -/* - * Open coded check for BTI, only for use to determine configuration - * for early mappings for before the cpufeature code has run. - */ -static bool arm64_early_this_cpu_has_bti(void) --{ ++static void __init iee_set_pte_table_ro(pmd_t *pmdp, unsigned long addr, unsigned long end) + { - u64 pfr1; -+ p4dp = p4d_offset(pgdp, iee_addr); -+ p4d = READ_ONCE(*p4dp); - +- - if (!IS_ENABLED(CONFIG_ARM64_BTI_KERNEL)) - return false; -+ pudp = pud_offset(p4dp, iee_addr); - +- - pfr1 = __read_sysreg_by_encoding(SYS_ID_AA64PFR1_EL1); - return cpuid_feature_extract_unsigned_field(pfr1, - ID_AA64PFR1_EL1_BT_SHIFT); -+ pmdp = pmd_offset(pudp, iee_addr); -+ -+ ptep = pte_offset_kernel(pmdp, iee_addr); -+ -+ for(i = 0; i < 4; i++) -+ { -+ pte_t pte = READ_ONCE(*ptep); -+ pte = __pte(pte_val(pte) | PTE_VALID); -+ iee_set_pte_pre_init(ptep, pte); -+ ptep++; -+ } -+ flush_tlb_kernel_range(addr, addr+4*PAGE_SIZE); -+ isb(); ++ pmd_t pmd = READ_ONCE(*pmdp); ++ unsigned long logical_addr = (unsigned long)__va(__pmd_to_phys(pmd)); ++ iee_set_logical_mem_ro(logical_addr); } -/* - * Create fine-grained mappings for the kernel. - */ -static void __init map_kernel(pgd_t *pgdp) -+static void __init iee_set_pte_table_ro(pmd_t *pmdp, unsigned long addr, unsigned long end) ++static void __init iee_set_pmd_table_ro(pud_t *pudp, unsigned long addr, unsigned long end) { - static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_inittext, - vmlinux_initdata, vmlinux_data; -+ pmd_t pmd = READ_ONCE(*pmdp); -+ unsigned long logical_addr = (unsigned long)__va(__pmd_to_phys(pmd)); -+ iee_set_logical_mem_ro(logical_addr); -+} - +- - /* - * External debuggers may need to write directly to the text - * mapping to install SW breakpoints. Allow this (only) when - * explicitly requested with rodata=off. - */ - pgprot_t text_prot = kernel_exec_prot(); -+static void __init iee_set_pmd_table_ro(pud_t *pudp, unsigned long addr, unsigned long end) -+{ + unsigned long next; + pud_t pud = READ_ONCE(*pudp); + pmd_t *pmdp; @@ -11365,6 +12161,8 @@ index 31f04f19b635..753fa8d887f3 100644 +// Mark pgtable outside as RO. +void __init iee_mark_all_lm_pgtable_ro(void) +{ ++ extern void *bm_pte_addr; ++ iee_set_logical_mem_ro((unsigned long)bm_pte_addr); + unsigned long logical_addr; + phys_addr_t start, end; + u64 i; @@ -11373,14 +12171,14 @@ index 31f04f19b635..753fa8d887f3 100644 + // handling static allocated page table + #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 + // handling 1-level tramp page table tramp_pg_dir -+ logical_addr = (unsigned long)__va(__pa_symbol(tramp_pg_dir)); -+ iee_set_logical_mem_ro(logical_addr); ++ // logical_addr = (unsigned long)__va(__pa_symbol(tramp_pg_dir)); ++ // iee_set_logical_mem_ro(logical_addr); + #endif + // handling 1-level page table swapper_pg_dir + pgdp = swapper_pg_dir; -+ iee_set_logical_mem_ro((unsigned long)swapper_pg_dir); -+ logical_addr = (unsigned long)__va(__pa_symbol(swapper_pg_dir)); -+ iee_set_logical_mem_ro(logical_addr); ++ // iee_set_logical_mem_ro((unsigned long)swapper_pg_dir); ++ // logical_addr = (unsigned long)__va(__pa_symbol(swapper_pg_dir)); ++ // iee_set_logical_mem_ro(logical_addr); + + // handling 2/3/4-level page table for kernel + iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)_text, (unsigned long)_etext); @@ -11421,7 +12219,6 @@ index 31f04f19b635..753fa8d887f3 100644 +#endif + +#ifdef CONFIG_KOI -+static void map_koi(pgd_t *pgdp); +extern s64 koi_offset; +#endif @@ -11455,7 +12252,7 @@ index 31f04f19b635..753fa8d887f3 100644 extern pgd_t init_idmap_pg_dir[]; idmap_t0sz = 63UL - __fls(__pa_symbol(_end) | GENMASK(VA_BITS_MIN - 1, 0)); -@@ -803,7 +2063,21 @@ void __init paging_init(void) +@@ -803,7 +2036,21 @@ void __init paging_init(void) map_kernel(pgdp); map_mem(pgdp); @@ -11477,7 +12274,7 @@ index 31f04f19b635..753fa8d887f3 100644 cpu_replace_ttbr1(lm_alias(swapper_pg_dir), init_idmap_pg_dir); init_mm.pgd = swapper_pg_dir; -@@ -814,6 +2088,83 @@ void __init paging_init(void) +@@ -814,6 +2061,83 @@ void __init paging_init(void) memblock_allow_resize(); create_idmap(); @@ -11508,7 +12305,7 @@ index 31f04f19b635..753fa8d887f3 100644 + // Use lm to write token before IEE initialized. + token = (struct task_token *)((unsigned long)new + (((unsigned long)&init_task) & ~PAGE_MASK)); + token->pgd = NULL; -+ token->iee_stack = __phys_to_iee(__pa_symbol((void *)init_iee_stack_end)); ++ token->iee_stack = (void *)__phys_to_iee(__pa_symbol((void *)init_iee_stack_end)); + token->valid = true; + iee_set_token_page_valid_pre_init(init_token, new); + #endif @@ -11561,43 +12358,183 @@ index 31f04f19b635..753fa8d887f3 100644 } #ifdef CONFIG_MEMORY_HOTPLUG -@@ -1261,6 +2612,9 @@ int pmd_free_pte_page(pmd_t *pmdp, unsigned long addr) - table = pte_offset_kernel(pmdp, addr); - pmd_clear(pmdp); - __flush_tlb_kernel_pgtable(addr); -+ #ifdef CONFIG_PTP -+ iee_memset(table, 0, PAGE_SIZE); -+ #endif - pte_free_kernel(NULL, table); - return 1; - } -@@ -1521,3 +2875,93 @@ void ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, pte - { - set_pte_at(vma->vm_mm, addr, ptep, pte); +@@ -1202,6 +2526,139 @@ void vmemmap_free(unsigned long start, unsigned long end, } + #endif /* CONFIG_MEMORY_HOTPLUG */ + ++#ifdef CONFIG_PTP + -+#if !defined(CONFIG_IEE) && defined (CONFIG_KOI) -+static void __create_pgd_mapping_for_koi(pgd_t *pgdir, phys_addr_t phys, -+ unsigned long virt, phys_addr_t size, -+ pgprot_t prot, -+ phys_addr_t (*pgtable_alloc)(int), -+ int flags) ++static void * __init iee_ptdesc_alloc_block_zero(unsigned long size, int node, bool pt) +{ -+ unsigned long addr, end, next; -+ pgd_t *pgdp = pgd_offset_pgd(pgdir, virt); ++ void *p = memblock_alloc_try_nid_raw(size, size, __pa(MAX_DMA_ADDRESS), ++ MEMBLOCK_ALLOC_ACCESSIBLE, node); + -+ /* -+ * If the virtual and physical address don't have the same offset -+ * within a page, we cannot map the region as the caller expects. -+ */ -+ if (WARN_ON((phys ^ virt) & ~PAGE_MASK)) -+ return; ++ if (!p) ++ return NULL; ++ memset(p, 0, size); + -+ phys &= PAGE_MASK; -+ addr = virt & PAGE_MASK; -+ end = PAGE_ALIGN(virt + size); ++ /* Vaild iee address to enable page table operations. */ ++ if (pt) ++ set_iee_page_valid((unsigned long)__phys_to_iee(__pa(p))); + -+ do { ++ return p; ++} ++ ++static pte_t * __init iee_ptdesc_pte_populate(pmd_t *pmd, unsigned long addr, int node) ++{ ++ pte_t *pte = pte_offset_kernel(pmd, addr); ++ if (pte_none(ptep_get(pte))) { ++ pte_t entry; ++ void *p = iee_ptdesc_alloc_block_zero(PAGE_SIZE, node, false); ++ if (!p) ++ return NULL; ++ ++ entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL); ++ set_pte_at(&init_mm, addr, pte, entry); ++ } ++ return pte; ++} ++ ++static pmd_t * __init iee_ptdesc_pmd_populate(pud_t *pud, unsigned long addr, int node) ++{ ++ pmd_t *pmd = pmd_offset(pud, addr); ++ if (pmd_none(*pmd)) { ++ void *p = iee_ptdesc_alloc_block_zero(PAGE_SIZE, node, true); ++ if (!p) ++ return NULL; ++ pmd_populate_kernel(&init_mm, pmd, p); ++ } ++ return pmd; ++} ++ ++static pud_t * __init iee_ptdesc_pud_populate(p4d_t *p4d, unsigned long addr, int node) ++{ ++ pud_t *pud = pud_offset(p4d, addr); ++ if (pud_none(*pud)) { ++ void *p = iee_ptdesc_alloc_block_zero(PAGE_SIZE, node, true); ++ if (!p) ++ return NULL; ++ pmd_init(p); ++ pud_populate(&init_mm, pud, p); ++ } ++ return pud; ++} ++ ++static p4d_t * __init iee_ptdesc_p4d_populate(pgd_t *pgd, unsigned long addr, int node) ++{ ++ p4d_t *p4d = p4d_offset(pgd, addr); ++ if (p4d_none(*p4d)) { ++ void *p = iee_ptdesc_alloc_block_zero(PAGE_SIZE, node, true); ++ if (!p) ++ return NULL; ++ pud_init(p); ++ p4d_populate(&init_mm, p4d, p); ++ } ++ return p4d; ++} ++ ++static pgd_t * __init iee_ptdesc_pgd_populate(unsigned long addr, int node) ++{ ++ pgd_t *pgd = pgd_offset_k(addr); ++ if (pgd_none(*pgd)) { ++ void *p = iee_ptdesc_alloc_block_zero(PAGE_SIZE, node, true); ++ if (!p) ++ return NULL; ++ pgd_populate(&init_mm, pgd, p); ++ } ++ return pgd; ++} ++ ++/* Create mappings if that address is not mapped. */ ++static pte_t * __init iee_ptdesc_populate_address(unsigned long addr) ++{ ++ pgd_t *pgd; ++ p4d_t *p4d; ++ pud_t *pud; ++ pmd_t *pmd; ++ pte_t *pte; ++ int node = NUMA_NO_NODE; ++ ++ pgd = iee_ptdesc_pgd_populate(addr, node); ++ if (!pgd) ++ return NULL; ++ p4d = iee_ptdesc_p4d_populate(pgd, addr, node); ++ if (!p4d) ++ return NULL; ++ pud = iee_ptdesc_pud_populate(p4d, addr, node); ++ if (!pud) ++ return NULL; ++ pmd = iee_ptdesc_pmd_populate(pud, addr, node); ++ if (!pmd) ++ return NULL; ++ pte = iee_ptdesc_pte_populate(pmd, addr, node); ++ if (!pte) ++ return NULL; ++ ++ return pte; ++} ++ ++/* Init ptdesc array used by iee. */ ++int __init iee_ptdesc_sparse_init(void) ++{ ++ unsigned long start_pfn, end_pfn; ++ int i, nid; ++ /* */ ++ for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid) { ++ struct ptdesc** ptdesc_start = ALIGN_DOWN((u64)(__pfn_to_ptdesc(start_pfn)), PAGE_SIZE); ++ struct ptdesc** end = ALIGN((u64)(__pfn_to_ptdesc(end_pfn)), PAGE_SIZE); ++ unsigned long addr = ptdesc_start; ++ pte_t *pte; ++ for (; addr < end; addr += PAGE_SIZE) { ++ pte = iee_ptdesc_populate_address(addr); ++ if (!pte) ++ return -ENOMEM; ++ } ++ } ++ return 0; ++} ++#endif /* CONFIG_PTP */ ++ + int pud_set_huge(pud_t *pudp, phys_addr_t phys, pgprot_t prot) + { + pud_t new_pud = pfn_pud(__phys_to_pfn(phys), mk_pud_sect_prot(prot)); +@@ -1261,6 +2718,9 @@ int pmd_free_pte_page(pmd_t *pmdp, unsigned long addr) + table = pte_offset_kernel(pmdp, addr); + pmd_clear(pmdp); + __flush_tlb_kernel_pgtable(addr); ++ #ifdef CONFIG_PTP ++ iee_memset(table, 0, PAGE_SIZE); ++ #endif + pte_free_kernel(NULL, table); + return 1; + } +@@ -1521,3 +2981,93 @@ void ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, pte + { + set_pte_at(vma->vm_mm, addr, ptep, pte); + } ++ ++#if !defined(CONFIG_IEE) && defined (CONFIG_KOI) ++static void __create_pgd_mapping_for_koi(pgd_t *pgdir, phys_addr_t phys, ++ unsigned long virt, phys_addr_t size, ++ pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(int), ++ int flags) ++{ ++ unsigned long addr, end, next; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, virt); ++ ++ /* ++ * If the virtual and physical address don't have the same offset ++ * within a page, we cannot map the region as the caller expects. ++ */ ++ if (WARN_ON((phys ^ virt) & ~PAGE_MASK)) ++ return; ++ ++ phys &= PAGE_MASK; ++ addr = virt & PAGE_MASK; ++ end = PAGE_ALIGN(virt + size); ++ ++ do { + next = pgd_addr_end(addr, end); + alloc_init_pud(pgdp, addr, next, phys, prot, pgtable_alloc, + flags); @@ -11667,7 +12604,7 @@ index 31f04f19b635..753fa8d887f3 100644 +#endif \ No newline at end of file diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c -index 4a64089e5771..b99b35a5190f 100644 +index 4a64089e5771..20008c35d150 100644 --- a/arch/arm64/mm/pgd.c +++ b/arch/arm64/mm/pgd.c @@ -15,14 +15,38 @@ @@ -11709,12 +12646,14 @@ index 4a64089e5771..b99b35a5190f 100644 else return kmem_cache_alloc(pgd_cache, gfp); } -@@ -30,7 +54,13 @@ pgd_t *pgd_alloc(struct mm_struct *mm) +@@ -30,7 +54,15 @@ pgd_t *pgd_alloc(struct mm_struct *mm) void pgd_free(struct mm_struct *mm, pgd_t *pgd) { if (PGD_SIZE == PAGE_SIZE) +#ifdef CONFIG_PTP + { ++ struct page *page = virt_to_page((void *)pgd); ++ set_page_count(page, 1); + free_iee_pgtable_page((void *)pgd); + } +#else @@ -11724,7 +12663,7 @@ index 4a64089e5771..b99b35a5190f 100644 kmem_cache_free(pgd_cache, pgd); } diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S -index 14fdf645edc8..4fad195becff 100644 +index 9ef7b07349d7..b8561144a45a 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -22,6 +22,8 @@ @@ -11744,8 +12683,8 @@ index 14fdf645edc8..4fad195becff 100644 msr ttbr1_el1, x0 isb -@@ -452,6 +455,11 @@ SYM_FUNC_START(__cpu_setup) - orr tcr, tcr, #TCR_HA // hardware Access flag update +@@ -459,6 +462,11 @@ SYM_FUNC_START(__cpu_setup) + #endif /* CONFIG_ARM64_HAFT */ 1: #endif /* CONFIG_ARM64_HW_AFDBM */ + @@ -11757,7 +12696,7 @@ index 14fdf645edc8..4fad195becff 100644 msr tcr_el1, tcr diff --git a/arch/arm64/mm/trans_pgd.c b/arch/arm64/mm/trans_pgd.c -index 5139a28130c0..729b6f5a9314 100644 +index 5139a28130c0..23d8a4b91574 100644 --- a/arch/arm64/mm/trans_pgd.c +++ b/arch/arm64/mm/trans_pgd.c @@ -25,6 +25,9 @@ @@ -11770,14 +12709,11 @@ index 5139a28130c0..729b6f5a9314 100644 static void *trans_alloc(struct trans_pgd_info *info) { -@@ -65,10 +68,16 @@ static int copy_pte(struct trans_pgd_info *info, pmd_t *dst_pmdp, +@@ -65,10 +68,12 @@ static int copy_pte(struct trans_pgd_info *info, pmd_t *dst_pmdp, pte_t *src_ptep; pte_t *dst_ptep; unsigned long addr = start; -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr; -+ #endif - +- dst_ptep = trans_alloc(info); if (!dst_ptep) return -ENOMEM; @@ -11787,15 +12723,7 @@ index 5139a28130c0..729b6f5a9314 100644 pmd_populate_kernel(NULL, dst_pmdp, dst_ptep); dst_ptep = pte_offset_kernel(dst_pmdp, start); -@@ -87,11 +96,17 @@ static int copy_pmd(struct trans_pgd_info *info, pud_t *dst_pudp, - pmd_t *dst_pmdp; - unsigned long next; - unsigned long addr = start; -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr; -+ #endif - - if (pud_none(READ_ONCE(*dst_pudp))) { +@@ -92,6 +97,9 @@ static int copy_pmd(struct trans_pgd_info *info, pud_t *dst_pudp, dst_pmdp = trans_alloc(info); if (!dst_pmdp) return -ENOMEM; @@ -11805,15 +12733,7 @@ index 5139a28130c0..729b6f5a9314 100644 pud_populate(NULL, dst_pudp, dst_pmdp); } dst_pmdp = pmd_offset(dst_pudp, start); -@@ -123,11 +138,17 @@ static int copy_pud(struct trans_pgd_info *info, p4d_t *dst_p4dp, - pud_t *src_pudp; - unsigned long next; - unsigned long addr = start; -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr; -+ #endif - - if (p4d_none(READ_ONCE(*dst_p4dp))) { +@@ -128,6 +136,9 @@ static int copy_pud(struct trans_pgd_info *info, p4d_t *dst_p4dp, dst_pudp = trans_alloc(info); if (!dst_pudp) return -ENOMEM; @@ -11823,7 +12743,7 @@ index 5139a28130c0..729b6f5a9314 100644 p4d_populate(NULL, dst_p4dp, dst_pudp); } dst_pudp = pud_offset(dst_p4dp, start); -@@ -212,6 +233,10 @@ int trans_pgd_create_copy(struct trans_pgd_info *info, pgd_t **dst_pgdp, +@@ -212,6 +223,10 @@ int trans_pgd_create_copy(struct trans_pgd_info *info, pgd_t **dst_pgdp, return -ENOMEM; } @@ -11834,17 +12754,7 @@ index 5139a28130c0..729b6f5a9314 100644 rc = copy_page_tables(info, trans_pgd, start, end); if (!rc) *dst_pgdp = trans_pgd; -@@ -238,6 +263,9 @@ int trans_pgd_idmap_page(struct trans_pgd_info *info, phys_addr_t *trans_ttbr0, - int bits_mapped = PAGE_SHIFT - 4; - unsigned long level_mask, prev_level_entry, *levels[4]; - int this_level, index, level_lsb, level_msb; -+ #ifdef CONFIG_PTP -+ unsigned long iee_addr; -+ #endif - - dst_addr &= PAGE_MASK; - prev_level_entry = pte_val(pfn_pte(pfn, PAGE_KERNEL_ROX)); -@@ -247,12 +275,20 @@ int trans_pgd_idmap_page(struct trans_pgd_info *info, phys_addr_t *trans_ttbr0, +@@ -247,12 +262,20 @@ int trans_pgd_idmap_page(struct trans_pgd_info *info, phys_addr_t *trans_ttbr0, if (!levels[this_level]) return -ENOMEM; @@ -11865,2609 +12775,14236 @@ index 5139a28130c0..729b6f5a9314 100644 pfn = virt_to_pfn(levels[this_level]); prev_level_entry = pte_val(pfn_pte(pfn, -diff --git a/block/sed-opal.c b/block/sed-opal.c -index 1a1cb35bf4b7..7149485a808c 100644 ---- a/block/sed-opal.c -+++ b/block/sed-opal.c -@@ -316,7 +316,11 @@ static int read_sed_opal_key(const char *key_name, u_char *buffer, int buflen) - return PTR_ERR(kref); +diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c +index 76ae4a3131ba..b3b962fcc3f8 100644 +--- a/arch/arm64/net/bpf_jit_comp.c ++++ b/arch/arm64/net/bpf_jit_comp.c +@@ -13,6 +13,9 @@ + #include + #include + #include ++#ifdef CONFIG_HIVE ++#include ++#endif - key = key_ref_to_ptr(kref); -+ #ifdef CONFIG_KEYP -+ down_read(&KEY_SEM(key)); -+ #else - down_read(&key->sem); -+ #endif - ret = key_validate(key); - if (ret == 0) { - if (buflen > key->datalen) -@@ -324,7 +328,11 @@ static int read_sed_opal_key(const char *key_name, u_char *buffer, int buflen) + #include + #include +@@ -67,6 +70,10 @@ static const int bpf2a64[] = { + /* temporary register for blinding constants */ + [BPF_REG_AX] = A64_R(9), + [FP_BOTTOM] = A64_R(27), ++#ifdef CONFIG_HIVE ++ /* fbpf base addr */ ++ [BPF_REG_BASE] = A64_R(28), ++#endif + }; - ret = key->type->read(key, (char *)buffer, buflen); - } -+ #ifdef CONFIG_KEYP -+ up_read(&KEY_SEM(key)); -+ #else - up_read(&key->sem); -+ #endif + struct jit_ctx { +@@ -283,7 +290,11 @@ static bool is_lsi_offset(int offset, int scale) + #define POKE_OFFSET (BTI_INSNS + 1) - key_ref_put(kref); + /* Tail call offset to jump into */ ++#ifdef CONFIG_HIVE ++#define PROLOGUE_OFFSET (BTI_INSNS + 2 + PAC_INSNS + 8 + 6 - 1) ++#else + #define PROLOGUE_OFFSET (BTI_INSNS + 2 + PAC_INSNS + 8) ++#endif -diff --git a/certs/blacklist.c b/certs/blacklist.c -index 675dd7a8f07a..4db9c6cb7732 100644 ---- a/certs/blacklist.c -+++ b/certs/blacklist.c -@@ -19,6 +19,10 @@ - #include - #include "blacklist.h" + static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf) + { +@@ -296,6 +307,9 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf) + const u8 fp = bpf2a64[BPF_REG_FP]; + const u8 tcc = bpf2a64[TCALL_CNT]; + const u8 fpb = bpf2a64[FP_BOTTOM]; ++#ifdef CONFIG_HIVE ++ const u8 base = bpf2a64[BPF_REG_BASE]; ++#endif + const int idx0 = ctx->idx; + int cur_offset; + +@@ -345,10 +359,35 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf) + emit(A64_PUSH(r6, r7, A64_SP), ctx); + emit(A64_PUSH(r8, r9, A64_SP), ctx); + emit(A64_PUSH(fp, tcc, A64_SP), ctx); ++#ifdef CONFIG_HIVE ++ emit(A64_PUSH(fpb, base, A64_SP), ctx); ++#else + emit(A64_PUSH(fpb, A64_R(28), A64_SP), ctx); ++#endif -+#ifdef CONFIG_KEYP -+#include ++#ifdef CONFIG_HIVE ++ /* Set up BPF prog stack base and sfi base register */ ++ u64 sfi_base = (u64)prog->shadow_region_addr; ++ u64 sfi_stack = (u64)(prog->shadow_stack_addr); ++ int idx_before; ++ ++ pr_info("fp=%016llx, base=%016llx\n", sfi_stack, sfi_base); ++ ++ idx_before = ctx->idx; ++ emit_a64_mov_i64(fp, sfi_stack, ctx); // 3 insns ++ while (ctx->idx - idx_before < 3) { ++ emit(A64_NOP, ctx); ++ } ++ idx_before = ctx->idx; ++ emit_a64_mov_i64(base, sfi_base, ctx); // 3 insns ++ while (ctx->idx - idx_before < 3) { ++ emit(A64_NOP, ctx); ++ } ++#else + /* Set up BPF prog stack base register */ + emit(A64_MOV(1, fp, A64_SP), ctx); +#endif + - /* - * According to crypto/asymmetric_keys/x509_cert_parser.c:x509_note_pkey_algo(), - * the size of the currently longest supported hash algorithm is 512 bits, -@@ -91,7 +95,11 @@ static int blacklist_key_instantiate(struct key *key, - #endif - /* Sets safe default permissions for keys loaded by user space. */ -+ #ifdef CONFIG_KEYP -+ iee_set_key_perm(key, BLACKLIST_KEY_PERM); -+ #else - key->perm = BLACKLIST_KEY_PERM; -+ #endif + if (!ebpf_from_cbpf && is_main_prog) { + /* Initialize tail_call_cnt */ +@@ -356,8 +395,13 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf) - /* - * Skips the authentication step for builtin hashes, they are not -diff --git a/certs/system_keyring.c b/certs/system_keyring.c -index a803524044bd..eab10ce55564 100644 ---- a/certs/system_keyring.c -+++ b/certs/system_keyring.c -@@ -96,9 +96,15 @@ int restrict_link_by_builtin_and_secondary_trusted( - /* If we have a secondary trusted keyring, then that contains a link - * through to the builtin keyring and the search will follow that link. - */ -+ #ifdef CONFIG_KEYP -+ if (type == &key_type_keyring && -+ dest_keyring == secondary_trusted_keys && -+ payload == (union key_payload *)(builtin_trusted_keys->name_link.next)) -+ #else - if (type == &key_type_keyring && - dest_keyring == secondary_trusted_keys && - payload == &builtin_trusted_keys->payload) -+ #endif - /* Allow the builtin keyring to be added to the secondary */ - return 0; + cur_offset = ctx->idx - idx0; + if (cur_offset != PROLOGUE_OFFSET) { ++ #ifdef CONFIG_HIVE ++ pr_err("PROLOGUE_OFFSET = %d, expected %d!\n", ++ cur_offset, PROLOGUE_OFFSET); ++ #else + pr_err_once("PROLOGUE_OFFSET = %d, expected %d!\n", + cur_offset, PROLOGUE_OFFSET); ++ #endif + return -1; + } -@@ -125,9 +131,15 @@ int restrict_link_by_digsig_builtin_and_secondary(struct key *dest_keyring, - /* If we have a secondary trusted keyring, then that contains a link - * through to the builtin keyring and the search will follow that link. - */ -+ #ifdef CONFIG_KEYP -+ if (type == &key_type_keyring && -+ dest_keyring == secondary_trusted_keys && -+ payload == (union key_payload *)(builtin_trusted_keys->name_link.next)) -+ #else - if (type == &key_type_keyring && - dest_keyring == secondary_trusted_keys && - payload == &builtin_trusted_keys->payload) -+ #endif - /* Allow the builtin keyring to be added to the secondary */ - return 0; +@@ -662,12 +706,20 @@ static void build_epilogue(struct jit_ctx *ctx) + const u8 r9 = bpf2a64[BPF_REG_9]; + const u8 fp = bpf2a64[BPF_REG_FP]; + const u8 fpb = bpf2a64[FP_BOTTOM]; ++#ifdef CONFIG_HIVE ++ const u8 base = bpf2a64[BPF_REG_BASE]; ++#endif -@@ -212,9 +224,15 @@ int restrict_link_by_builtin_secondary_and_machine( - const union key_payload *payload, - struct key *restrict_key) - { -+ #ifdef CONFIG_KEYP -+ if (machine_trusted_keys && type == &key_type_keyring && -+ dest_keyring == secondary_trusted_keys && -+ payload == (union key_payload *)(machine_trusted_keys->name_link.next)) -+ #else - if (machine_trusted_keys && type == &key_type_keyring && - dest_keyring == secondary_trusted_keys && - payload == &machine_trusted_keys->payload) -+ #endif - /* Allow the machine keyring to be added to the secondary */ - return 0; + /* We're done with BPF stack */ + emit(A64_ADD_I(1, A64_SP, A64_SP, ctx->stack_size), ctx); -diff --git a/crypto/af_alg.c b/crypto/af_alg.c -index 68cc9290cabe..6d4415de9ee4 100644 ---- a/crypto/af_alg.c -+++ b/crypto/af_alg.c -@@ -304,7 +304,11 @@ static int alg_setkey_by_key_serial(struct alg_sock *ask, sockptr_t optval, - if (IS_ERR(key)) - return PTR_ERR(key); ++#ifdef CONFIG_HIVE ++ /* Restore x27 and base (x28) */ ++ emit(A64_POP(fpb, base, A64_SP), ctx); ++#else + /* Restore x27 and x28 */ + emit(A64_POP(fpb, A64_R(28), A64_SP), ctx); ++#endif + /* Restore fs (x25) and x26 */ + emit(A64_POP(fp, A64_R(26), A64_SP), ctx); + +@@ -769,6 +821,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, + const u8 fp = bpf2a64[BPF_REG_FP]; + const u8 fpb = bpf2a64[FP_BOTTOM]; + const s16 off = insn->off; ++#ifdef CONFIG_HIVE ++ u8 off_reg; ++#endif + const s32 imm = insn->imm; + const int i = insn - ctx->prog->insnsi; + const bool is64 = BPF_CLASS(code) == BPF_ALU64 || +@@ -1237,6 +1292,33 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, + return ret; + break; -+ #ifdef CONFIG_KEYP -+ down_read(&KEY_SEM(key)); -+ #else - down_read(&key->sem); ++#ifdef CONFIG_HIVE ++ case BPF_LDX | BPF_REG | BPF_W: ++ case BPF_LDX | BPF_REG | BPF_H: ++ case BPF_LDX | BPF_REG | BPF_B: ++ case BPF_LDX | BPF_REG | BPF_DW: ++ off_reg = bpf2a64[off]; ++ switch (BPF_SIZE(code)) { ++ case BPF_W: ++ emit(A64_LDR32(dst, src, off_reg), ctx); ++ break; ++ case BPF_H: ++ emit(A64_LDRH(dst, src, off_reg), ctx); ++ break; ++ case BPF_B: ++ emit(A64_LDRB(dst, src, off_reg), ctx); ++ break; ++ case BPF_DW: ++ emit(A64_LDR64(dst, src, off_reg), ctx); ++ break; ++ } ++ ++ ret = add_exception_handler(insn, ctx, dst); ++ if (ret) ++ return ret; ++ break; ++#endif ++ + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + /* +@@ -1347,6 +1429,29 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, + break; + } + break; ++ ++ #ifdef CONFIG_HIVE ++ case BPF_STX | BPF_REG | BPF_W: ++ case BPF_STX | BPF_REG | BPF_H: ++ case BPF_STX | BPF_REG | BPF_B: ++ case BPF_STX | BPF_REG | BPF_DW: ++ off_reg = bpf2a64[off]; ++ switch (BPF_SIZE(code)) { ++ case BPF_W: ++ emit(A64_STR32(src, dst, off_reg), ctx); ++ break; ++ case BPF_H: ++ emit(A64_STRH(src, dst, off_reg), ctx); ++ break; ++ case BPF_B: ++ emit(A64_STRB(src, dst, off_reg), ctx); ++ break; ++ case BPF_DW: ++ emit(A64_STR64(src, dst, off_reg), ctx); ++ break; ++ } ++ break; + #endif - ret = ERR_PTR(-ENOPROTOOPT); - if (!strcmp(key->type->name, "user") || -@@ -319,21 +323,33 @@ static int alg_setkey_by_key_serial(struct alg_sock *ask, sockptr_t optval, - } + case BPF_STX | BPF_ATOMIC | BPF_W: + case BPF_STX | BPF_ATOMIC | BPF_DW: +diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig +index df023e1cb5dd..f791ba71b796 100644 +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -1548,6 +1548,25 @@ config AMD_MEM_ENCRYPT + This requires an AMD processor that supports Secure Memory + Encryption (SME). - if (IS_ERR(ret)) { -+ #ifdef CONFIG_KEYP -+ up_read(&KEY_SEM(key)); -+ #else - up_read(&key->sem); -+ #endif - key_put(key); - return PTR_ERR(ret); - } - - key_data = sock_kmalloc(&ask->sk, key_datalen, GFP_KERNEL); - if (!key_data) { -+ #ifdef CONFIG_KEYP -+ up_read(&KEY_SEM(key)); -+ #else - up_read(&key->sem); -+ #endif - key_put(key); - return -ENOMEM; - } - - memcpy(key_data, ret, key_datalen); ++config CREDP ++ bool "Config for credentials isolation" ++ depends on IEE ++ def_bool y ++ ++config IEE ++ bool "Config for Isolated Executed Environment" ++ depends on X86_64 ++ def_bool y ++ ++config KEYP ++ depends on IEE ++ def_bool y ++ ++config IEE_SELINUX_P ++ depends on IEE ++ depends on SECURITY_SELINUX ++ def_bool n ++ + # Common NUMA Features + config NUMA + bool "NUMA Memory Allocation and Scheduler Support" +@@ -2466,6 +2485,12 @@ source "kernel/livepatch/Kconfig" -+ #ifdef CONFIG_KEYP -+ up_read(&KEY_SEM(key)); -+ #else - up_read(&key->sem); -+ #endif - key_put(key); + endmenu - err = type->setkey(ask->private, key_data, key_datalen); -diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c -index 43af5fa510c0..40dd58a69617 100644 ---- a/crypto/asymmetric_keys/asymmetric_type.c -+++ b/crypto/asymmetric_keys/asymmetric_type.c -@@ -16,6 +16,9 @@ - #include - #include - #include "asymmetric_keys.h" -+#ifdef CONFIG_KEYP -+#include ++# Config for kernel module isolation ++config KOI ++ bool "Config for Kernel Module Isolation" ++ depends on X86_64 ++ def_bool y ++ + config CC_HAS_SLS + def_bool $(cc-option,-mharden-sls=all) + +diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c +index a7b4148a943f..23e85a84e45b 100644 +--- a/arch/x86/boot/compressed/ident_map_64.c ++++ b/arch/x86/boot/compressed/ident_map_64.c +@@ -23,7 +23,11 @@ + /* Use the static base for this part of the boot process */ + #undef __PAGE_OFFSET + #define __PAGE_OFFSET __PAGE_OFFSET_BASE ++#ifdef CONFIG_PTP ++#include "../../mm/ident_map_for_iee.c" ++#else + #include "../../mm/ident_map.c" +#endif + #define _SETUP + #include /* For COMMAND_LINE_SIZE */ +@@ -101,9 +105,15 @@ void kernel_add_identity_map(unsigned long start, unsigned long end) + return; - const char *const key_being_used_for[NR__KEY_BEING_USED_FOR] = { -@@ -467,6 +470,18 @@ static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep) - static void asymmetric_key_destroy(struct key *key) - { - struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); -+ #ifdef CONFIG_KEYP -+ struct asymmetric_key_ids *kids = ((union key_payload *)(key->name_link.next))->data[asym_key_ids]; -+ void *data = ((union key_payload *)(key->name_link.next))->data[asym_crypto]; -+ void *auth = ((union key_payload *)(key->name_link.next))->data[asym_auth]; -+ -+ union key_payload key_payload = *((union key_payload *)(key->name_link.next)); -+ key_payload.data[asym_crypto] = NULL; -+ key_payload.data[asym_subtype] = NULL; -+ key_payload.data[asym_key_ids] = NULL; -+ key_payload.data[asym_auth] = NULL; -+ iee_write_key_payload(key, key_payload); + /* Build the mapping. */ ++ #ifdef CONFIG_PTP ++ ret = kernel_ident_mapping_init_for_iee(&mapping_info, (pgd_t *)top_level_pgt, start, end); ++ if (ret) ++ error("Error: kernel_ident_mapping_init_for_iee() failed\n"); + #else - struct asymmetric_key_ids *kids = key->payload.data[asym_key_ids]; - void *data = key->payload.data[asym_crypto]; - void *auth = key->payload.data[asym_auth]; -@@ -475,6 +490,7 @@ static void asymmetric_key_destroy(struct key *key) - key->payload.data[asym_subtype] = NULL; - key->payload.data[asym_key_ids] = NULL; - key->payload.data[asym_auth] = NULL; + ret = kernel_ident_mapping_init(&mapping_info, (pgd_t *)top_level_pgt, start, end); + if (ret) + error("Error: kernel_ident_mapping_init() failed\n"); + #endif + } - if (subtype) { - subtype->destroy(data, auth); -@@ -580,8 +596,13 @@ int asymmetric_key_eds_op(struct kernel_pkey_params *params, - if (key->type != &key_type_asymmetric) - return -EINVAL; - subtype = asymmetric_key_subtype(key); -+ #ifdef CONFIG_KEYP -+ if (!subtype || -+ !((union key_payload *)(key->name_link.next))->data[0]) -+ #else - if (!subtype || - !key->payload.data[0]) -+ #endif - return -EINVAL; - if (!subtype->eds_op) - return -ENOTSUPP; -diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c -index 1dcab27986a6..490ba98995c1 100644 ---- a/crypto/asymmetric_keys/public_key.c -+++ b/crypto/asymmetric_keys/public_key.c -@@ -30,7 +30,11 @@ MODULE_LICENSE("GPL"); - static void public_key_describe(const struct key *asymmetric_key, - struct seq_file *m) - { -+ #ifdef CONFIG_KEYP -+ struct public_key *key = ((union key_payload *)(asymmetric_key->name_link.next))->data[asym_crypto]; -+ #else - struct public_key *key = asymmetric_key->payload.data[asym_crypto]; -+ #endif + /* Locates and clears a region for a new top level page table. */ +@@ -179,7 +189,11 @@ void initialize_identity_maps(void *rmode) + sev_prep_identity_maps(top_level_pgt); - if (key) - seq_printf(m, "%s.%s", key->id_type, key->pkey_algo); -@@ -158,7 +162,11 @@ static int software_key_query(const struct kernel_pkey_params *params, - struct kernel_pkey_query *info) - { - struct crypto_akcipher *tfm; -+ #ifdef CONFIG_KEYP -+ struct public_key *pkey = ((union key_payload *)(params->key->name_link.next))->data[asym_crypto]; + /* Load the new page-table. */ ++ #ifdef CONFIG_IEE ++ native_write_cr3_pre_init(top_level_pgt); + #else - struct public_key *pkey = params->key->payload.data[asym_crypto]; + write_cr3(top_level_pgt); + #endif - char alg_name[CRYPTO_MAX_ALG_NAME]; - struct crypto_sig *sig; - u8 *key, *ptr; -@@ -273,7 +281,11 @@ static int software_key_query(const struct kernel_pkey_params *params, - static int software_key_eds_op(struct kernel_pkey_params *params, - const void *in, void *out) - { -+ #ifdef CONFIG_KEYP -+ const struct public_key *pkey = ((union key_payload *)(params->key->name_link.next))->data[asym_crypto]; + + /* + * Now that the required page table mappings are established and a +@@ -207,7 +221,11 @@ static pte_t *split_large_pmd(struct x86_mapping_info *info, + + /* Populate the PTEs */ + for (i = 0; i < PTRS_PER_PMD; i++) { ++ #ifdef CONFIG_PTP ++ iee_set_pte_pre_init(&pte[i], __pte(address | page_flags)); ++ #else + set_pte(&pte[i], __pte(address | page_flags)); ++ #endif + address += PAGE_SIZE; + } + +@@ -221,9 +239,17 @@ static pte_t *split_large_pmd(struct x86_mapping_info *info, + * of a TLB multihit. + */ + pmd = __pmd((unsigned long)pte | info->kernpg_flag); ++ #ifdef CONFIG_PTP ++ iee_set_pmd_pre_init(pmdp, pmd); + #else - const struct public_key *pkey = params->key->payload.data[asym_crypto]; + set_pmd(pmdp, pmd); + #endif - char alg_name[CRYPTO_MAX_ALG_NAME]; - struct crypto_akcipher *tfm; - struct crypto_sig *sig; -@@ -453,7 +465,11 @@ EXPORT_SYMBOL_GPL(public_key_verify_signature); - static int public_key_verify_signature_2(const struct key *key, - const struct public_key_signature *sig) - { -+ #ifdef CONFIG_KEYP -+ const struct public_key *pk = ((union key_payload *)(key->name_link.next))->data[asym_crypto]; + /* Flush TLB to establish the new PMD */ ++ #ifdef CONFIG_IEE ++ native_write_cr3_pre_init(top_level_pgt); + #else - const struct public_key *pk = key->payload.data[asym_crypto]; + write_cr3(top_level_pgt); + #endif - return public_key_verify_signature(pk, sig); - } -diff --git a/crypto/asymmetric_keys/signature.c b/crypto/asymmetric_keys/signature.c -index 2deff81f8af5..696fa2c4e708 100644 ---- a/crypto/asymmetric_keys/signature.c -+++ b/crypto/asymmetric_keys/signature.c -@@ -51,8 +51,13 @@ int query_asymmetric_key(const struct kernel_pkey_params *params, - if (key->type != &key_type_asymmetric) - return -EINVAL; - subtype = asymmetric_key_subtype(key); -+ #ifdef CONFIG_KEYP -+ if (!subtype || -+ !((union key_payload *)(key->name_link.next))->data[0]) -+ #else - if (!subtype || - !key->payload.data[0]) + return pte + pte_index(__address); + } +@@ -313,7 +339,11 @@ static int set_clr_page_flags(struct x86_mapping_info *info, + pte = *ptep; + pte = pte_set_flags(pte, set); + pte = pte_clear_flags(pte, clr); ++ #ifdef CONFIG_PTP ++ iee_set_pte_pre_init(ptep, pte); ++ #else + set_pte(ptep, pte); + #endif - return -EINVAL; - if (!subtype->query) - return -ENOTSUPP; -@@ -145,8 +150,13 @@ int verify_signature(const struct key *key, - if (key->type != &key_type_asymmetric) - return -EINVAL; - subtype = asymmetric_key_subtype(key); -+ #ifdef CONFIG_KEYP -+ if (!subtype || -+ !((union key_payload *)(key->name_link.next))->data[0]) + + /* + * If the encryption attribute is being set, then change the page state to +@@ -324,7 +354,11 @@ static int set_clr_page_flags(struct x86_mapping_info *info, + snp_set_page_private(__pa(address & PAGE_MASK)); + + /* Flush TLB after changing encryption attribute */ ++ #ifdef CONFIG_IEE ++ native_write_cr3_pre_init(top_level_pgt); + #else - if (!subtype || - !key->payload.data[0]) + write_cr3(top_level_pgt); + #endif - return -EINVAL; - if (!subtype->verify_signature) - return -ENOTSUPP; -diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c -index 83092d93f36a..fb12e7d0660a 100644 ---- a/drivers/firmware/efi/arm-runtime.c -+++ b/drivers/firmware/efi/arm-runtime.c -@@ -94,7 +94,11 @@ static int __init arm_enable_runtime_services(void) - return 0; - } -+ #ifdef CONFIG_PTP -+ efi_memmap_unmap_after_init(); + return 0; + } +diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c +index 7939eb6e6ce9..c922aec0d88a 100644 +--- a/arch/x86/boot/compressed/pgtable_64.c ++++ b/arch/x86/boot/compressed/pgtable_64.c +@@ -196,7 +196,11 @@ asmlinkage void configure_5level_paging(struct boot_params *bp, void *pgtable) + * Move the top level page table out of trampoline memory. + */ + memcpy(pgtable, trampoline_32bit, PAGE_SIZE); ++ #ifdef CONFIG_IEE ++ native_write_cr3_pre_init((unsigned long)pgtable); + #else - efi_memmap_unmap(); + native_write_cr3((unsigned long)pgtable); + #endif - mapsize = efi.memmap.desc_size * efi.memmap.nr_map; + /* Restore trampoline memory */ + memcpy(trampoline_32bit, trampoline_save, TRAMPOLINE_32BIT_SIZE); +diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S +index 2192b6c33ea0..888278c6f2dd 100644 +--- a/arch/x86/entry/entry_64.S ++++ b/arch/x86/entry/entry_64.S +@@ -43,6 +43,12 @@ -diff --git a/drivers/firmware/efi/memmap.c b/drivers/firmware/efi/memmap.c -index 77dd20f9df31..ea8ebecaa153 100644 ---- a/drivers/firmware/efi/memmap.c -+++ b/drivers/firmware/efi/memmap.c -@@ -96,6 +96,26 @@ void __init efi_memmap_unmap(void) - clear_bit(EFI_MEMMAP, &efi.flags); - } + #include "calling.h" -+#ifdef CONFIG_PTP -+void __init efi_memmap_unmap_after_init(void) -+{ -+ if (!efi_enabled(EFI_MEMMAP)) -+ return; -+ -+ if (!(efi.memmap.flags & EFI_MEMMAP_LATE)) { -+ unsigned long size; ++#ifdef CONFIG_IEE ++.section .rodata ++error_idt_addr: ++ .asciz "Incorrectly set smep or smap to 0" ++#endif + -+ size = efi.memmap.desc_size * efi.memmap.nr_map; -+ early_iounmap_after_init((__force void __iomem *)efi.memmap.map, size); -+ } else { -+ memunmap(efi.memmap.map); -+ } + .code64 + .section .entry.text, "ax" + +@@ -663,6 +669,17 @@ SYM_INNER_LABEL(restore_regs_and_return_to_kernel, SYM_L_GLOBAL) + jz 1f + ud2 + 1: ++#endif ++#ifdef CONFIG_KOI ++ movq %cr4, %rcx ++ testq $(1 << 17), %rcx ++ jz 2f ++ # movq koi_kern_cr3(%rip), %rcx ++ # cmpq $0, %rcx ++ # je 2f ++ movq CS-8(%rsp), %rdi ++ call koi_error_return_to_ko ++2: + #endif + POP_REGS + addq $8, %rsp /* skip regs->orig_ax */ +@@ -1072,6 +1089,42 @@ SYM_CODE_START(error_entry) + * for these here too. + */ + .Lerror_kernelspace: ++#ifdef CONFIG_IEE ++ pushq %r12 ++ movq %cr4, %r12 ++ testq $X86_CR4_SMEP, %r12 ++ jz .IEE_ERROR ++ testq $X86_CR4_SMAP, %r12 ++ jz .IEE_ERROR ++ jmp .IEE_CONTINUE ++.IEE_ERROR: ++ /* str: .asciz "Incorrectly set smep or smap to 0" */ ++ mov $error_idt_addr, %rdi ++ call panic ++.IEE_CONTINUE: ++ popq %r12 ++#endif /* CONFIG_IEE */ ++#ifdef CONFIG_KOI ++ movq %cr3, %rcx ++ testq $(1 << 11), %rcx ++ jz 1f ++ pushq %rdx ++ pushq %rsi ++ pushq %rdi ++ pushq %r8 ++ pushq %r9 ++ pushq %r10 ++ pushq %r11 ++ call koi_error_entry_to_kernel ++ popq %r11 ++ popq %r10 ++ popq %r9 ++ popq %r8 ++ popq %rdi ++ popq %rsi ++ popq %rdx ++1: ++#endif + leaq native_irq_return_iret(%rip), %rcx + cmpq %rcx, RIP+8(%rsp) + je .Lerror_bad_iret +diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h +index ab97b22ac04a..cef8de1be0c0 100644 +--- a/arch/x86/include/asm/desc.h ++++ b/arch/x86/include/asm/desc.h +@@ -13,6 +13,10 @@ + #include + #include + ++#ifdef CONFIG_IEE ++#include ++#endif + -+ efi.memmap.map = NULL; -+ clear_bit(EFI_MEMMAP, &efi.flags); + static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *info) + { + desc->limit0 = info->limit & 0x0ffff; +@@ -210,9 +214,23 @@ static inline void native_load_gdt(const struct desc_ptr *dtr) + asm volatile("lgdt %0"::"m" (*dtr)); + } + ++#ifdef CONFIG_IEE ++static __always_inline void iee_load_idt_pre_init(const struct desc_ptr *dtr) ++{ ++ asm volatile("lidt %0"::"m" (*dtr)); +} +#endif + - /** - * efi_memmap_init_late - Map efi.memmap with memremap() - * @phys_addr: Physical address of the new EFI memory map -diff --git a/drivers/md/Makefile b/drivers/md/Makefile -index 84291e38dca8..b3af9d419b6e 100644 ---- a/drivers/md/Makefile -+++ b/drivers/md/Makefile -@@ -71,6 +71,7 @@ obj-$(CONFIG_DM_PERSISTENT_DATA) += persistent-data/ - obj-$(CONFIG_DM_MIRROR) += dm-mirror.o dm-log.o dm-region-hash.o - obj-$(CONFIG_DM_LOG_USERSPACE) += dm-log-userspace.o - obj-$(CONFIG_DM_ZERO) += dm-zero.o -+obj-$(CONFIG_DM_ZERO_KOI) += dm-zero_koi.o - obj-$(CONFIG_DM_RAID) += dm-raid.o - obj-$(CONFIG_DM_THIN_PROVISIONING) += dm-thin-pool.o - obj-$(CONFIG_DM_VERITY) += dm-verity.o -diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c -index aa6bb5b4704b..ecf777e5d176 100644 ---- a/drivers/md/dm-crypt.c -+++ b/drivers/md/dm-crypt.c -@@ -2512,7 +2512,11 @@ static int set_key_encrypted(struct crypt_config *cc, struct key *key) - { - const struct encrypted_key_payload *ekp; - -+ #ifdef CONFIG_KEYP -+ ekp = ((union key_payload *)(key->name_link.next))->data[0]; -+ #else - ekp = key->payload.data[0]; -+ #endif - if (!ekp) - return -EKEYREVOKED; - -@@ -2528,7 +2532,11 @@ static int set_key_trusted(struct crypt_config *cc, struct key *key) - { - const struct trusted_key_payload *tkp; - -+ #ifdef CONFIG_KEYP -+ tkp = ((union key_payload *)(key->name_link.next))->data[0]; -+ #else - tkp = key->payload.data[0]; -+ #endif - if (!tkp) - return -EKEYREVOKED; - -@@ -2590,17 +2598,29 @@ static int crypt_set_keyring_key(struct crypt_config *cc, const char *key_string - return PTR_ERR(key); - } - -+ #ifdef CONFIG_KEYP -+ down_read(&KEY_SEM(key)); -+ #else - down_read(&key->sem); -+ #endif - - ret = set_key(cc, key); - if (ret < 0) { -+ #ifdef CONFIG_KEYP -+ up_read(&KEY_SEM(key)); -+ #else - up_read(&key->sem); -+ #endif - key_put(key); - kfree_sensitive(new_key_string); - return ret; - } - -+ #ifdef CONFIG_KEYP -+ up_read(&KEY_SEM(key)); -+ #else - up_read(&key->sem); -+ #endif - key_put(key); - - /* clear the flag since following operations may invalidate previously valid key */ -diff --git a/drivers/md/dm-verity-verify-sig.c b/drivers/md/dm-verity-verify-sig.c -index 4836508ea50c..d52d5bccc190 100644 ---- a/drivers/md/dm-verity-verify-sig.c -+++ b/drivers/md/dm-verity-verify-sig.c -@@ -40,7 +40,11 @@ static int verity_verify_get_sig_from_key(const char *key_desc, - if (IS_ERR(key)) - return PTR_ERR(key); - -+ #ifdef CONFIG_KEYP -+ down_read(&KEY_SEM(key)); -+ #else - down_read(&key->sem); -+ #endif - - ukp = user_key_payload_locked(key); - if (!ukp) { -@@ -58,7 +62,11 @@ static int verity_verify_get_sig_from_key(const char *key_desc, - memcpy(sig_opts->sig, ukp->data, sig_opts->sig_size); - - end: -+ #ifdef CONFIG_KEYP -+ up_read(&KEY_SEM(key)); -+ #else - up_read(&key->sem); -+ #endif - key_put(key); - - return ret; -diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c -index a03e3c45f297..71bccea085e9 100644 ---- a/drivers/nvdimm/security.c -+++ b/drivers/nvdimm/security.c -@@ -28,7 +28,11 @@ static void *key_data(struct key *key) + static __always_inline void native_load_idt(const struct desc_ptr *dtr) { - struct encrypted_key_payload *epayload = dereference_key_locked(key); - -+ #ifdef CONFIG_KEYP -+ lockdep_assert_held_read(&KEY_SEM(key)); -+ #else - lockdep_assert_held_read(&key->sem); -+ #endif - - return epayload->decrypted_data; - } -@@ -38,7 +42,11 @@ static void nvdimm_put_key(struct key *key) - if (!key) - return; - -+ #ifdef CONFIG_KEYP -+ up_read(&KEY_SEM(key)); ++ /* IEE note: load_idt in __restore_processor_state() is not triggered in qemu, ++ * but still hooked ++ */ ++ #ifdef CONFIG_IEE ++ iee_rwx_gate(IEE_LOAD_IDT, dtr); + #else - up_read(&key->sem); + asm volatile("lidt %0"::"m" (*dtr)); + #endif - key_put(key); } -@@ -65,10 +73,18 @@ static struct key *nvdimm_request_key(struct nvdimm *nvdimm) - } else { - struct encrypted_key_payload *epayload; - -+ #ifdef CONFIG_KEYP -+ down_read(&KEY_SEM(key)); -+ #else - down_read(&key->sem); -+ #endif - epayload = dereference_key_locked(key); - if (epayload->decrypted_datalen != NVDIMM_PASSPHRASE_LEN) { -+ #ifdef CONFIG_KEYP -+ up_read(&KEY_SEM(key)); -+ #else - up_read(&key->sem); -+ #endif - key_put(key); - key = NULL; - } -@@ -107,10 +123,18 @@ static struct key *nvdimm_lookup_user_key(struct nvdimm *nvdimm, - - dev_dbg(dev, "%s: key found: %#x\n", __func__, key_serial(key)); - -+ #ifdef CONFIG_KEYP -+ down_read_nested(&KEY_SEM(key), subclass); -+ #else - down_read_nested(&key->sem, subclass); -+ #endif - epayload = dereference_key_locked(key); - if (epayload->decrypted_datalen != NVDIMM_PASSPHRASE_LEN) { -+ #ifdef CONFIG_KEYP -+ up_read(&KEY_SEM(key)); -+ #else - up_read(&key->sem); -+ #endif - key_put(key); - key = NULL; - } -diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c -index 7e0d8fb26465..950ee6396659 100644 ---- a/drivers/rtc/rtc-test.c -+++ b/drivers/rtc/rtc-test.c -@@ -198,4 +198,4 @@ MODULE_DESCRIPTION("RTC test driver/device"); - MODULE_LICENSE("GPL v2"); - - module_init(test_init); --module_exit(test_exit); -+module_exit(test_exit); -\ No newline at end of file -diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c -index a5fbb6ed38ae..81428783b9da 100644 ---- a/drivers/tty/serial/earlycon.c -+++ b/drivers/tty/serial/earlycon.c -@@ -40,7 +40,11 @@ static void __iomem * __init earlycon_map(resource_size_t paddr, size_t size) - { - void __iomem *base; - #ifdef CONFIG_FIX_EARLYCON_MEM -+ #ifdef CONFIG_PTP -+ __iee_set_fixmap_pre_init(FIX_EARLYCON_MEM_BASE, paddr & PAGE_MASK, FIXMAP_PAGE_IO); -+ #else - set_fixmap_io(FIX_EARLYCON_MEM_BASE, paddr & PAGE_MASK); -+ #endif - base = (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE); - base += paddr & ~PAGE_MASK; - #else -diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c -index 45b42d8f6453..b71072d6957e 100644 ---- a/drivers/usb/early/ehci-dbgp.c -+++ b/drivers/usb/early/ehci-dbgp.c -@@ -879,7 +879,11 @@ int __init early_dbgp_init(char *s) - * FIXME I don't have the bar size so just guess PAGE_SIZE is more - * than enough. 1K is the biggest I have seen. - */ -+ #ifdef CONFIG_PTP -+ __iee_set_fixmap_pre_init(FIX_DBGP_BASE, bar_val & PAGE_MASK, FIXMAP_PAGE_NOCACHE); -+ #else - set_fixmap_nocache(FIX_DBGP_BASE, bar_val & PAGE_MASK); -+ #endif - ehci_bar = (void __iomem *)__fix_to_virt(FIX_DBGP_BASE); - ehci_bar += bar_val & ~PAGE_MASK; - dbgp_printk("ehci_bar: %p\n", ehci_bar); -diff --git a/fs/coredump.c b/fs/coredump.c -index 9d235fa14ab9..72be355903ca 100644 ---- a/fs/coredump.c -+++ b/fs/coredump.c -@@ -53,6 +53,10 @@ - - #include + static inline void native_store_gdt(struct desc_ptr *dtr) +diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h +index d0dcefb5cc59..c6dbea6ab469 100644 +--- a/arch/x86/include/asm/fixmap.h ++++ b/arch/x86/include/asm/fixmap.h +@@ -196,5 +196,10 @@ void __init *early_memremap_decrypted_wp(resource_size_t phys_addr, + void __early_set_fixmap(enum fixed_addresses idx, + phys_addr_t phys, pgprot_t flags); -+#ifdef CONFIG_CREDP -+#include ++#ifdef CONFIG_PTP ++void __iee_set_fixmap_pre_init(enum fixed_addresses idx, ++ phys_addr_t phys, pgprot_t flags); +#endif + - static bool dump_vma_snapshot(struct coredump_params *cprm); - static void free_vma_snapshot(struct coredump_params *cprm); - -@@ -564,7 +568,11 @@ void do_coredump(const kernel_siginfo_t *siginfo) - */ - if (__get_dumpable(cprm.mm_flags) == SUID_DUMP_ROOT) { - /* Setuid core dump mode */ -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(cred,GLOBAL_ROOT_UID); -+ #else - cred->fsuid = GLOBAL_ROOT_UID; /* Dump root private */ -+ #endif - need_suid_safe = true; - } - -diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c -index 7cbb1fd872ac..a8425a83aabf 100644 ---- a/fs/crypto/keyring.c -+++ b/fs/crypto/keyring.c -@@ -590,8 +590,13 @@ static void fscrypt_provisioning_key_describe(const struct key *key, - { - seq_puts(m, key->description); - if (key_is_positive(key)) { -+ #ifdef CONFIG_KEYP -+ const struct fscrypt_provisioning_key_payload *payload = -+ ((union key_payload *)(key->name_link.next))->data[0]; -+ #else - const struct fscrypt_provisioning_key_payload *payload = - key->payload.data[0]; -+ #endif - - seq_printf(m, ": %u [%u]", key->datalen, payload->type); - } -@@ -599,7 +604,11 @@ static void fscrypt_provisioning_key_describe(const struct key *key, - - static void fscrypt_provisioning_key_destroy(struct key *key) - { -+ #ifdef CONFIG_KEYP -+ kfree_sensitive(((union key_payload *)(key->name_link.next))->data[0]); -+ #else - kfree_sensitive(key->payload.data[0]); -+ #endif - } - - static struct key_type key_type_fscrypt_provisioning = { -@@ -641,7 +650,11 @@ static int get_keyring_key(u32 key_id, u32 type, - - if (key->type != &key_type_fscrypt_provisioning) - goto bad_key; -+ #ifdef CONFIG_KEYP + #endif /* !__ASSEMBLY__ */ + #endif /* _ASM_X86_FIXMAP_H */ +diff --git a/arch/x86/include/asm/iee-access.h b/arch/x86/include/asm/iee-access.h +new file mode 100644 +index 000000000000..3eb2346afd6a +--- /dev/null ++++ b/arch/x86/include/asm/iee-access.h +@@ -0,0 +1,39 @@ ++#ifndef _LINUX_IEE_ACCESS_H ++#define _LINUX_IEE_ACCESS_H ++ ++#include ++#include ++ ++extern unsigned long long iee_rw_gate(int flag, ...); ++ ++static inline void iee_memcpy(void *dst, const void *src, size_t n) ++{ ++ iee_rw_gate(IEE_OP_MEMCPY, dst, src, n); ++} ++ ++static inline void iee_memset(void *ptr, int data, size_t n) ++{ ++ iee_rw_gate(IEE_OP_MEMSET, ptr, data, n); ++} ++ ++static inline void iee_set_track(struct track *ptr, struct track *data) ++{ ++ iee_rw_gate(IEE_OP_SET_TRACK, ptr, data); ++} ++ ++static inline void iee_set_freeptr(freeptr_t *pptr, freeptr_t ptr) ++{ ++ iee_rw_gate(IEE_OP_SET_FREEPTR, pptr, ptr); ++} ++ ++static inline void iee_split_huge_pmd(pmd_t *pmdp, pte_t *pgtable) ++{ ++ iee_rw_gate(IEE_OP_SPLIT_HUGE_PMD, pmdp, pgtable); ++} ++ ++static inline unsigned long iee_test_and_clear_bit(long nr, volatile unsigned long *addr) ++{ ++ return iee_rw_gate(IEE_OP_TEST_CLEAR_BIT, nr, addr); ++} ++ ++#endif +\ No newline at end of file +diff --git a/arch/x86/include/asm/iee-cred.h b/arch/x86/include/asm/iee-cred.h +new file mode 100644 +index 000000000000..44ae20ce05ad +--- /dev/null ++++ b/arch/x86/include/asm/iee-cred.h +@@ -0,0 +1,148 @@ ++#ifndef _LINUX_IEE_CRED_H ++#define _LINUX_IEE_CRED_H ++ ++#include ++#include ++ ++extern unsigned long long iee_rw_gate(int flag, ...); ++ ++static void __maybe_unused iee_copy_cred(const struct cred *old, struct cred *new) ++{ ++ iee_rw_gate(IEE_OP_COPY_CRED,old,new); ++} ++ ++static void __maybe_unused iee_set_cred_uid(struct cred *cred, kuid_t uid) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_UID,cred,uid); ++} ++ ++static void __maybe_unused iee_set_cred_gid(struct cred *cred, kgid_t gid) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_GID,cred,gid); ++} ++ ++static void __maybe_unused iee_set_cred_suid(struct cred *cred, kuid_t suid) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_SUID,cred,suid); ++} ++ ++static void __maybe_unused iee_set_cred_sgid(struct cred *cred, kgid_t sgid) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_SGID,cred,sgid); ++} ++ ++static void __maybe_unused iee_set_cred_euid(struct cred *cred, kuid_t euid) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_EUID,cred,euid); ++} ++ ++static void __maybe_unused iee_set_cred_egid(struct cred *cred, kgid_t egid) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_EGID,cred,egid); ++} ++ ++static void __maybe_unused iee_set_cred_fsuid(struct cred *cred, kuid_t fsuid) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_FSUID,cred,fsuid); ++} ++ ++static void __maybe_unused iee_set_cred_fsgid(struct cred *cred, kgid_t fsgid) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_FSGID,cred,fsgid); ++} ++ ++static void __maybe_unused iee_set_cred_user(struct cred *cred, struct user_struct *user) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_USER,cred,user); ++} ++ ++static void __maybe_unused iee_set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_USER_NS,cred,user_ns); ++} ++ ++static void __maybe_unused iee_set_cred_ucounts(struct cred *cred, struct ucounts *ucounts) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_UCOUNTS,cred,ucounts); ++} ++ ++static void __maybe_unused iee_set_cred_group_info(struct cred *cred, struct group_info *group_info) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_GROUP_INFO,cred,group_info); ++} ++ ++static void __maybe_unused iee_set_cred_securebits(struct cred *cred, unsigned securebits) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_SECUREBITS,cred,securebits); ++} ++ ++static void __maybe_unused iee_set_cred_cap_inheritable(struct cred *cred, kernel_cap_t cap_inheritable) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_CAP_INHER,cred,cap_inheritable); ++} ++ ++static void __maybe_unused iee_set_cred_cap_permitted(struct cred *cred, kernel_cap_t cap_permitted) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_CAP_PERM,cred,cap_permitted); ++} ++ ++static void __maybe_unused iee_set_cred_cap_effective(struct cred *cred, kernel_cap_t cap_effective) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_CAP_EFFECT,cred,cap_effective); ++} ++ ++static void __maybe_unused iee_set_cred_cap_bset(struct cred *cred, kernel_cap_t cap_bset) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_CAP_BSET,cred,cap_bset); ++} ++ ++static void __maybe_unused iee_set_cred_cap_ambient(struct cred *cred, kernel_cap_t cap_ambient) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_CAP_AMBIENT,cred,cap_ambient); ++} ++ ++#ifdef CONFIG_KEYS ++static void __maybe_unused iee_set_cred_jit_keyring(struct cred *cred, unsigned char jit_keyring) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_JIT_KEYRING,cred,jit_keyring); ++} ++ ++static void __maybe_unused iee_set_cred_session_keyring(struct cred *cred, struct key *session_keyring) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_SESS_KEYRING,cred,session_keyring); ++} ++ ++static void __maybe_unused iee_set_cred_process_keyring(struct cred *cred, struct key *process_keyring) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_PROC_KEYRING,cred,process_keyring); ++} ++ ++static void __maybe_unused iee_set_cred_thread_keyring(struct cred *cred, struct key *thread_keyring) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_THREAD_KEYRING,cred,thread_keyring); ++} ++ ++static void __maybe_unused iee_set_cred_request_key_auth(struct cred *cred, struct key *request_key_auth) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_REQ_KEYRING,cred,request_key_auth); ++} ++#endif ++ ++static void __maybe_unused iee_set_cred_atomic_set_usage(struct cred *cred, int i) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_ATSET_USAGE,cred,i); ++} ++ ++#ifdef CONFIG_SECURITY ++static void __maybe_unused iee_set_cred_security(struct cred *cred, void *security) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_SECURITY,cred,security); ++} ++#endif ++ ++static void __maybe_unused iee_set_cred_rcu(struct cred *cred, struct rcu_head *rcu) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_RCU,cred,rcu); ++} ++ ++#endif +\ No newline at end of file +diff --git a/arch/x86/include/asm/iee-def.h b/arch/x86/include/asm/iee-def.h +new file mode 100644 +index 000000000000..d9a712c2420e +--- /dev/null ++++ b/arch/x86/include/asm/iee-def.h +@@ -0,0 +1,124 @@ ++#ifndef _LINUX_IEE_DEF_H ++#define _LINUX_IEE_DEF_H ++ ++#ifdef CONFIG_CREDP ++#define AT_ADD 1 ++#define AT_INC_NOT_ZERO 2 ++#define AT_SUB_AND_TEST 3 ++#endif ++ ++#ifdef CONFIG_KEYP ++#define REFCOUNT_INC 1 ++#define REFCOUNT_SET 2 ++#define REFCOUNT_DEC_AND_TEST 3 ++#define REFCOUNT_INC_NOT_ZERO 4 ++ ++#define SET_BIT_OP 1 ++#define TEST_AND_CLEAR_BIT 2 ++#define TEST_AND_SET_BIT 3 ++#endif ++ ++enum { ++ #ifdef CONFIG_PTP ++ IEE_OP_SET_PTE, ++ IEE_OP_SET_PMD, ++ IEE_OP_SET_PUD, ++ IEE_OP_SET_P4D, ++ IEE_OP_SET_PGD, ++ #endif ++ IEE_OP_MEMCPY, ++ IEE_OP_MEMSET, ++ IEE_OP_SET_FREEPTR, ++ IEE_OP_SPLIT_HUGE_PMD, ++ IEE_OP_SET_TOKEN_PGD, ++ IEE_OP_INIT_TOKEN, ++ IEE_OP_INVALIDATE_TOKEN, ++ IEE_OP_VALIDATE_TOKEN, ++ IEE_OP_UNSET_TOKEN, ++ IEE_OP_SET_TOKEN, ++ IEE_OP_SET_TRACK, ++ IEE_OP_TEST_CLEAR_BIT, ++ IEE_SET_SENSITIVE_PTE, ++ IEE_UNSET_SENSITIVE_PTE, ++#ifdef CONFIG_CREDP ++ IEE_OP_COPY_CRED, // Parameters: struct cred *old, struct cred *new ++ IEE_OP_SET_CRED_UID, // Parameters: struct cred *cred, kuid_t uid ++ IEE_OP_SET_CRED_GID, // Parameters: struct cred *cred, kgid_t gid ++ IEE_OP_SET_CRED_SUID, // Parameters: struct cred *cred, kuid_t suid ++ IEE_OP_SET_CRED_SGID, // Parameters: struct cred *cred, kgid_t sgid ++ IEE_OP_SET_CRED_EUID, // Parameters: struct cred *cred, kuid_t euid ++ IEE_OP_SET_CRED_EGID, // Parameters: struct cred *cred, kgid_t egid ++ IEE_OP_SET_CRED_FSUID, // Parameters: struct cred *cred, kuid_t fsuid ++ IEE_OP_SET_CRED_FSGID, // Parameters: struct cred *cred, kgid_t fsgid ++ IEE_OP_SET_CRED_USER, // Parameters: struct cred *cred, struct user_struct *user ++ IEE_OP_SET_CRED_USER_NS, // Parameters: struct cred *cred, struct user_namespace *user_ns ++ IEE_OP_SET_CRED_GROUP_INFO, // Parameters: struct cred *cred, struct group_info *group_info ++ IEE_OP_SET_CRED_SECUREBITS, // Parameters: struct cred *cred, unsigned securebits ++ IEE_OP_SET_CRED_CAP_INHER, // Parameters: struct cred *cred, kernel_cap_t cap_inheritable ++ IEE_OP_SET_CRED_CAP_PERM, // Parameters: struct cred *cred, kernel_cap_t cap_permitted ++ IEE_OP_SET_CRED_CAP_EFFECT, // Parameters: struct cred *cred, kernel_cap_t cap_effective ++ IEE_OP_SET_CRED_CAP_BSET, // Parameters: struct cred *cred, kernel_cap_t cap_bset ++ IEE_OP_SET_CRED_CAP_AMBIENT, // Parameters: struct cred *cred, kernel_cap_t cap_ambient ++ IEE_OP_SET_CRED_JIT_KEYRING, // Parameters: struct cred *cred, unsigned char jit_keyring ++ IEE_OP_SET_CRED_SESS_KEYRING, // Parameters: struct cred *cred, struct key *session_keyring ++ IEE_OP_SET_CRED_PROC_KEYRING, // Parameters: struct cred *cred, struct key *process_keyring ++ IEE_OP_SET_CRED_THREAD_KEYRING, // Parameters: struct cred *cred, struct key *thread_keyring ++ IEE_OP_SET_CRED_REQ_KEYRING, // Parameters: struct cred *cred, struct key *request_key_auth ++ IEE_OP_SET_CRED_NON_RCU, // Parameters: struct cred *cred, int non_rcu ++ IEE_OP_SET_CRED_ATSET_USAGE, // Parameters: struct cred *cred, int i ++ IEE_OP_SET_CRED_ATOP_USAGE, // Parameters: struct cred *cred, int flag ++ IEE_OP_SET_CRED_SECURITY, // Parameters: struct cred *cred, void *security ++ IEE_OP_SET_CRED_RCU, // Parameters: struct cred *cred, struct rcu_head *rcu ++ IEE_OP_SET_CRED_UCOUNTS, // Parameters: struct cred *cred, struct ucounts *ucounts ++#endif ++#ifdef CONFIG_KEYP ++ IEE_OP_SET_KEY_UNION, ++ IEE_OP_SET_KEY_STRUCT, ++ IEE_OP_SET_KEY_PAYLOAD, ++ IEE_OP_SET_KEY_USAGE, ++ IEE_OP_SET_KEY_SERIAL, ++ IEE_OP_SET_KEY_WATCHERS, ++ IEE_OP_SET_KEY_USERS, ++ IEE_OP_SET_KEY_SECURITY, ++ IEE_OP_SET_KEY_EXPIRY, ++ IEE_OP_SET_KEY_REVOKED_AT, ++ IEE_OP_SET_KEY_LAST_USED_AT, ++ IEE_OP_SET_KEY_UID, ++ IEE_OP_SET_KEY_GID, ++ IEE_OP_SET_KEY_PERM, ++ IEE_OP_SET_KEY_QUOTALEN, ++ IEE_OP_SET_KEY_DATALEN, ++ IEE_OP_SET_KEY_STATE, ++ IEE_OP_SET_KEY_MAGIC, ++ IEE_OP_SET_KEY_FLAGS, ++ IEE_OP_SET_KEY_INDEX_KEY, ++ IEE_OP_SET_KEY_HASH, ++ IEE_OP_SET_KEY_LEN_DESC, ++ IEE_OP_SET_KEY_TYPE, ++ IEE_OP_SET_KEY_TAG, ++ IEE_OP_SET_KEY_DESCRIPTION, ++ IEE_OP_SET_KEY_RESTRICT_LINK, ++ IEE_OP_SET_KEY_FLAG_BIT, ++#endif ++#ifdef CONFIG_IEE_SELINUX_P ++ IEE_SEL_SET_STATUS_PG, // Parameters: struct page* new_page ++ IEE_SEL_SET_ENFORCING, // Parameters: bool value ++ IEE_SEL_SET_INITIALIZED, ++ IEE_SEL_SET_POLICY_CAP, // Parameters: unsigned int idx, int cap ++ IEE_SEL_RCU_ASSIGN_POLICY, // Parameters: struct selinux_policy* new_policy, struct selinux_policy* iee_new_policy ++#endif ++#ifdef CONFIG_KOI ++ IEE_READ_KOI_STACK, // Parameters: struct task_struct *tsk ++ IEE_WRITE_KOI_STACK, // Parameters: struct task_struct *tsk, unsigned long koi_stack ++ IEE_READ_TOKEN_TTBR1, // Parameters: struct task_struct *tsk ++ IEE_WRITE_TOKEN_TTBR1, // Parameters: struct task_struct *tsk, unsigned long current_ttbr1 ++ IEE_READ_KOI_KERNEL_STACK, // Parameters: struct task_struct *tsk ++ IEE_WRITE_KOI_KERNEL_STACK, // Parameters: struct task_struct *tsk, unsigned long kernel_stack ++ IEE_READ_KOI_STACK_BASE, // Parameters: struct task_struct *tsk ++ IEE_WRITE_KOI_STACK_BASE, // Parameters: struct task_struct *tsk, unsigned long koi_stack_base ++ IEE_SET_KOI_PGD, // Parameters: unsigned long koi_pgd_addr ++#endif ++ IEE_FLAG_END ++}; ++ ++#endif /* _LINUX_IEE_DEF_H */ +\ No newline at end of file +diff --git a/arch/x86/include/asm/iee-key.h b/arch/x86/include/asm/iee-key.h +new file mode 100644 +index 000000000000..fcac44558cce +--- /dev/null ++++ b/arch/x86/include/asm/iee-key.h +@@ -0,0 +1,147 @@ ++#ifndef _LINUX_IEE_KEY_H ++#define _LINUX_IEE_KEY_H ++ ++#include ++#include ++ ++extern unsigned long long iee_rw_gate(int flag, ...); ++ ++static void __maybe_unused iee_set_key_union(struct key *key, struct key_union *key_union) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_UNION, key, key_union); ++} ++ ++static void __maybe_unused iee_set_key_struct(struct key *key, struct key_struct *key_struct) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_STRUCT, key, key_struct); ++} ++ ++static void __maybe_unused iee_set_key_payload(struct key *key, union key_payload *key_payload) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_PAYLOAD, key, key_payload); ++} ++ ++extern bool iee_set_key_usage(struct key *key, int n, int flag); ++ ++static void __maybe_unused iee_set_key_serial(struct key *key, key_serial_t serial) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_SERIAL, key, serial); ++} ++ ++#ifdef CONFIG_KEY_NOTIFICATIONS ++static void __maybe_unused iee_set_key_watchers(struct key *key, struct watch_list *watchers) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_WATCHERS, key, watchers); ++} ++#endif ++ ++static void __maybe_unused iee_set_key_user(struct key *key, struct key_user *user) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_USERS, key, user); ++} ++ ++static void __maybe_unused iee_set_key_security(struct key *key, void *security) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_SECURITY, key, security); ++} ++ ++static void __maybe_unused iee_set_key_expiry(struct key *key, time64_t expiry) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_EXPIRY, key, expiry); ++} ++ ++static void __maybe_unused iee_set_key_revoked_at(struct key *key, time64_t revoked_at) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_REVOKED_AT, key, revoked_at); ++} ++ ++static void __maybe_unused iee_set_key_last_used_at(struct key *key, time64_t last_used_at) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_LAST_USED_AT, key, last_used_at); ++} ++ ++static void __maybe_unused iee_set_key_uid(struct key *key, kuid_t uid) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_UID, key, uid); ++} ++ ++static void __maybe_unused iee_set_key_gid(struct key *key, kgid_t gid) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_GID, key, gid); ++} ++ ++static void __maybe_unused iee_set_key_perm(struct key *key, key_perm_t perm) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_PERM, key, perm); ++} ++ ++static void __maybe_unused iee_set_key_quotalen(struct key *key, unsigned short quotalen) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_QUOTALEN, key, quotalen); ++} ++ ++static void __maybe_unused iee_set_key_datalen(struct key *key, unsigned short datalen) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_DATALEN, key, datalen); ++} ++ ++static void __maybe_unused iee_set_key_state(struct key *key, short state) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_STATE, key, state); ++} ++ ++#ifdef KEY_DEBUGGING ++static void __maybe_unused iee_set_key_magic(struct key *key, unsigned magic) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_MAGIC, key, magic); ++} ++#endif ++ ++static void __maybe_unused iee_set_key_flags(struct key *key, unsigned long flags) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_FLAGS, key, flags); ++} ++ ++static void __maybe_unused iee_set_key_index_key(struct key *key, struct keyring_index_key* index_key) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_INDEX_KEY, key, index_key); ++} ++ ++static void __maybe_unused iee_set_key_hash(struct key *key, unsigned long hash) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_HASH, key, hash); ++} ++ ++static void __maybe_unused iee_set_key_len_desc(struct key *key, unsigned long len_desc) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_LEN_DESC, key, len_desc); ++} ++ ++static void __maybe_unused iee_set_key_type(struct key *key, struct key_type *type) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_TYPE, key, type); ++} ++ ++static void __maybe_unused iee_set_key_domain_tag(struct key *key, struct key_tag *domain_tag) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_TAG, key, domain_tag); ++} ++ ++static void __maybe_unused iee_set_key_description(struct key *key, char *description) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_DESCRIPTION, key, description); ++} ++ ++static void __maybe_unused iee_set_key_restrict_link(struct key *key, struct key_restriction *restrict_link) ++{ ++ iee_rw_gate(IEE_OP_SET_KEY_RESTRICT_LINK, key, restrict_link); ++} ++ ++static bool __maybe_unused iee_set_key_flag_bit(struct key *key, long nr, int flag) ++{ ++ bool ret; ++ ret = iee_rw_gate(IEE_OP_SET_KEY_FLAG_BIT, key, nr, flag); ++ return ret; ++} ++ ++#endif +\ No newline at end of file +diff --git a/arch/x86/include/asm/iee-koi.h b/arch/x86/include/asm/iee-koi.h +new file mode 100644 +index 000000000000..f55526f8aa60 +--- /dev/null ++++ b/arch/x86/include/asm/iee-koi.h +@@ -0,0 +1,5 @@ ++#if defined(CONFIG_KOI) && defined(CONFIG_IEE) ++#define IEE_SWITCH_TO_KERNEL 5 ++#define IEE_SWITCH_TO_KOI 6 ++ ++#endif +\ No newline at end of file +diff --git a/arch/x86/include/asm/iee-selinuxp.h b/arch/x86/include/asm/iee-selinuxp.h +new file mode 100644 +index 000000000000..29bcadb9979f +--- /dev/null ++++ b/arch/x86/include/asm/iee-selinuxp.h +@@ -0,0 +1,26 @@ ++#ifndef _LINUX_IEE_SELINUX_P_H ++#define _LINUX_IEE_SELINUX_P_H ++ ++#include ++#include "security.h" ++#include "ss/services.h" ++ ++static inline struct mutex* iee_get_selinux_policy_lock(void) ++{ ++ return (struct mutex*)(selinux_state.policy_mutex.owner.counter); ++} ++ ++static inline struct mutex* iee_get_selinux_status_lock(void) ++{ ++ return (struct mutex*)(selinux_state.status_lock.owner.counter); ++} ++ ++/* APIs for modifying selinux_state */ ++extern void iee_set_selinux_status_pg(struct page* new_page); ++extern void iee_set_sel_policy_cap(unsigned int idx, int cap); ++extern void iee_sel_rcu_assign_policy(struct selinux_policy* new_policy, ++ struct selinux_policy* iee_new_policy); ++ ++extern struct kmem_cache *policy_jar; ++ ++#endif +\ No newline at end of file +diff --git a/arch/x86/include/asm/iee-si.h b/arch/x86/include/asm/iee-si.h +new file mode 100644 +index 000000000000..19601dd5a6e4 +--- /dev/null ++++ b/arch/x86/include/asm/iee-si.h +@@ -0,0 +1,25 @@ ++#ifndef _LINUX_IEE_SI_H ++#define _LINUX_IEE_SI_H ++#define __iee_si_code __section(".iee.si_text") ++#define __iee_si_base __section(".iee.si_base") ++#define __iee_si_data __section(".iee.si_data") ++ ++extern bool iee_pgt_jar_init; ++extern bool iee_init_done; ++extern unsigned long iee_base_swapper_pg_dir; ++extern unsigned long __iee_si_text_start[]; ++extern unsigned long __iee_si_text_end[]; ++extern unsigned long __iee_si_data_start[]; ++extern unsigned long __iee_si_data_end[]; ++extern void iee_rwx_gate(int flag, ...); ++// Handler function for sensitive inst ++u64 iee_si_handler(int flag, ...); ++ ++#define IEE_SI_TEST 0 ++#define IEE_WRITE_CR0 1 ++#define IEE_WRITE_CR3 2 ++#define IEE_WRITE_CR4 3 ++#define IEE_LOAD_IDT 4 ++#define IEE_SWITCH_TO_KERNEL 5 ++#define IEE_SWITCH_TO_KOI 6 ++#endif +\ No newline at end of file +diff --git a/arch/x86/include/asm/iee-slab.h b/arch/x86/include/asm/iee-slab.h +new file mode 100644 +index 000000000000..6c79bea4406a +--- /dev/null ++++ b/arch/x86/include/asm/iee-slab.h +@@ -0,0 +1,21 @@ ++#ifndef _LINUX_IEE_SLAB_H ++#define _LINUX_IEE_SLAB_H ++ ++/* ++ * Tracking user of a slab. ++ */ ++#include ++#define TRACK_ADDRS_COUNT 16 ++struct track { ++ unsigned long addr; /* Called from address */ ++#ifdef CONFIG_STACKDEPOT ++ depot_stack_handle_t handle; ++#endif ++ int cpu; /* Was running on cpu */ ++ int pid; /* Pid context */ ++ unsigned long when; /* When did the operation occur */ ++}; ++enum track_item { TRACK_ALLOC, TRACK_FREE }; ++typedef struct { unsigned long v; } freeptr_t; ++ ++#endif +\ No newline at end of file +diff --git a/arch/x86/include/asm/iee-token.h b/arch/x86/include/asm/iee-token.h +new file mode 100644 +index 000000000000..cd38b16beb25 +--- /dev/null ++++ b/arch/x86/include/asm/iee-token.h +@@ -0,0 +1,32 @@ ++#ifndef _LINUX_IEE_TOKEN_H ++#define _LINUX_IEE_TOKEN_H ++ ++#include ++#include ++ ++extern unsigned long long iee_rw_gate(int flag, ...); ++struct task_token; ++struct task_struct; ++struct mm_struct; ++ ++static inline void iee_set_token_pgd(struct task_struct *tsk, pgd_t *pgd) ++{ ++ iee_rw_gate(IEE_OP_SET_TOKEN_PGD, tsk, pgd); ++} ++ ++static inline void iee_init_token(struct task_struct *tsk, void *iee_stack, void *tmp_page) ++{ ++ iee_rw_gate(IEE_OP_INIT_TOKEN, tsk, iee_stack, tmp_page); ++} ++ ++static inline void iee_invalidate_token(struct task_struct *tsk) ++{ ++ iee_rw_gate(IEE_OP_INVALIDATE_TOKEN, tsk); ++} ++ ++static inline void iee_validate_token(struct task_struct *tsk) ++{ ++ iee_rw_gate(IEE_OP_VALIDATE_TOKEN, tsk); ++} ++ ++#endif +\ No newline at end of file +diff --git a/arch/x86/include/asm/iee.h b/arch/x86/include/asm/iee.h +new file mode 100644 +index 000000000000..9b116751df6e +--- /dev/null ++++ b/arch/x86/include/asm/iee.h +@@ -0,0 +1,5 @@ ++#ifndef _LINUX_IEE_H ++#define _LINUX_IEE_H ++#define __iee_code __section(".iee.text") ++#define __iee_header __section(".iee.text.header") ++#endif +\ No newline at end of file +diff --git a/arch/x86/include/asm/koi.h b/arch/x86/include/asm/koi.h +new file mode 100644 +index 000000000000..f0f3ae1623f8 +--- /dev/null ++++ b/arch/x86/include/asm/koi.h +@@ -0,0 +1,432 @@ ++#include "asm/pgtable_types.h" ++#include "linux/percpu-defs.h" ++#include "linux/spinlock_types.h" ++#include "linux/hashtable.h" ++#include "asm/tlbflush.h" ++ ++#define MAX_VAR_NAME 64 ++#define DRIVER_ISOLATION_VAR_ARRAY_SIZE 32 ++#define DRIVER_ISOLATION_MAX_VAL 256 ++ ++#define HASH_TABLE_BIT 10 ++ ++#define PTI_USER_PCID_MASK (1 << X86_CR3_PTI_PCID_USER_BIT) ++ ++DECLARE_PER_CPU_PAGE_ALIGNED(unsigned long, koi_kern_cr3); ++ ++extern struct hlist_head koi_mem_htbl[1024]; ++ ++extern unsigned long koi_offset; ++ ++extern unsigned long koi_cr3_ctor(struct module *mod); ++ ++extern int koi_share_kstack(struct module *mod); ++ ++void koi_map_kostack(struct module *mod); ++ ++#ifdef CONFIG_IEE ++#include "asm/page.h" ++extern unsigned long IEE_OFFSET; ++#endif ++/** ++* struct koi_mem_hash_node - ++*@mod:pointer to driver module ++*@mem_list_head:free memory list head ++*@ko_mm: mm_struct in each driver ++*@pgdp:entry to Page Global Directory :pgd ++*@node:hash linked list node ++*@addr_htbl[1 << (HASH_TABLE_BIT)]: ++*@rcu: ++*/ ++struct koi_mem_hash_node { ++ struct module *mod; ++ struct mm_struct *ko_mm; ++ pgd_t *pgdp; ++ unsigned long ko_cr3; ++ struct hlist_node node; ++ bool is_valid; ++ spinlock_t mod_lock; ++}; ++ ++struct shared_variable_descriptor { ++ unsigned int id; ++ unsigned int type; ++ char name[MAX_VAR_NAME]; ++ unsigned long offset; ++ unsigned int size; ++ unsigned int self_ptr_ids[DRIVER_ISOLATION_VAR_ARRAY_SIZE]; ++}; ++ ++int koi_copy_pagetable(struct mm_struct *ko_mm, pgd_t *koi_pg_dir, ++ unsigned long addr, unsigned long end, pteval_t prot); ++ ++void koi_create_pagetable(struct module *mod); ++void koi_destroy_pagetable(struct module *mod); ++void koi_map_mem(struct module *mod, unsigned long addr, unsigned long size); ++void koi_unmap_mem(struct module *mod, unsigned long addr, unsigned long size); ++ ++#ifndef CONFIG_IEE ++#define __koi_switch_to_ko(mod) \ ++ do { \ ++ unsigned long flags, new_cr3; \ ++ struct task_token *token = (struct task_token *)(__phys_to_koi(__pa(current))); \ ++ asm volatile( \ ++ "pushf\n\t" \ ++ "pop %0\n\t" \ ++ "cli\n\t" \ ++ : "=r"(flags) \ ++ : \ ++ : "memory" \ ++ ); \ ++ new_cr3 = __read_cr3(); \ ++ this_cpu_write(koi_kern_cr3, new_cr3); \ ++ new_cr3 = koi_cr3_ctor(mod); \ ++ token->current_ttbr1 = new_cr3 & (~X86_CR3_PCID_MASK); \ ++ native_write_cr3(new_cr3); \ ++ if (!arch_irqs_disabled_flags(flags)) \ ++ arch_local_irq_enable(); \ ++ } while (0); ++ ++#define koi_switch_to_ko() \ ++ do { \ ++ unsigned long flags, new_cr3; \ ++ struct task_token *token = (struct task_token *)(__phys_to_koi(__pa(current))); \ ++ asm volatile( \ ++ "pushf\n\t" \ ++ "pop %0\n\t" \ ++ "cli\n\t" \ ++ : "=r"(flags) \ ++ : \ ++ : "memory" \ ++ ); \ ++ new_cr3 = __read_cr3(); \ ++ this_cpu_write(koi_kern_cr3, new_cr3); \ ++ new_cr3 = koi_cr3_ctor(THIS_MODULE); \ ++ token->current_ttbr1 = new_cr3 & (~X86_CR3_PCID_MASK); \ ++ native_write_cr3(new_cr3); \ ++ if (!arch_irqs_disabled_flags(flags)) \ ++ arch_local_irq_enable(); \ ++ } while (0); ++ ++#define koi_switch_to_kernel() \ ++ do { \ ++ unsigned long flags, new_cr3; \ ++ asm volatile( \ ++ "pushf\n\t" \ ++ "pop %0\n\t" \ ++ "cli\n\t" \ ++ : "=r"(flags) \ ++ : \ ++ : "memory" \ ++ ); \ ++ new_cr3 = this_cpu_read(koi_kern_cr3); \ ++ /*pcid = __read_cr3(); \ ++ pcid &= X86_CR3_PCID_MASK; \ ++ pcid &= ~PTI_USER_PCID_MASK;*/ \ ++ native_write_cr3(new_cr3); \ ++ struct task_token *token = (struct task_token *)(__phys_to_koi(__pa(current))); \ ++ token->current_ttbr1 = new_cr3; \ ++ if (!arch_irqs_disabled_flags(flags)) \ ++ arch_local_irq_enable(); \ ++ } while (0); ++#else ++#define __koi_switch_to_ko(mod) \ ++ do { \ ++ unsigned long flags, new_cr3; \ ++ asm volatile( \ ++ "pushf\n\t" \ ++ "pop %0\n\t" \ ++ "cli\n\t" \ ++ : "=r"(flags) \ ++ : \ ++ : "memory" \ ++ ); \ ++ new_cr3 = __read_cr3(); \ ++ this_cpu_write(koi_kern_cr3, new_cr3); \ ++ new_cr3 = koi_cr3_ctor(mod); \ ++ iee_rw_gate(IEE_WRITE_TOKEN_TTBR1, current, new_cr3 & (~X86_CR3_PCID_MASK)); \ ++ /* iee_rwx_gate(IEE_SWITCH_TO_KOI, new_cr3); */ \ ++ asm volatile("mov %0,%%cr3": : "r" (new_cr3) : "memory"); \ ++ if (!arch_irqs_disabled_flags(flags)) \ ++ arch_local_irq_enable(); \ ++ } while (0); ++ ++#define koi_switch_to_ko() \ ++ do { \ ++ unsigned long flags, new_cr3; \ ++ asm volatile( \ ++ "pushf\n\t" \ ++ "pop %0\n\t" \ ++ "cli\n\t" \ ++ : "=r"(flags) \ ++ : \ ++ : "memory" \ ++ ); \ ++ new_cr3 = __read_cr3(); \ ++ this_cpu_write(koi_kern_cr3, new_cr3); \ ++ new_cr3 = koi_cr3_ctor(THIS_MODULE); \ ++ iee_rw_gate(IEE_WRITE_TOKEN_TTBR1, current, new_cr3 & (~X86_CR3_PCID_MASK)); \ ++ /* iee_rwx_gate(IEE_SWITCH_TO_KOI, new_cr3); */ \ ++ asm volatile("mov %0,%%cr3": : "r" (new_cr3) : "memory"); \ ++ if (!arch_irqs_disabled_flags(flags)) \ ++ arch_local_irq_enable(); \ ++ } while (0); ++ ++#define koi_switch_to_kernel() \ ++ do { \ ++ unsigned long flags, new_cr3; \ ++ asm volatile( \ ++ "pushf\n\t" \ ++ "pop %0\n\t" \ ++ "cli\n\t" \ ++ : "=r"(flags) \ ++ : \ ++ : "memory" \ ++ ); \ ++ new_cr3 = this_cpu_read(koi_kern_cr3); \ ++ /*pcid = __read_cr3(); \ ++ pcid &= X86_CR3_PCID_MASK; \ ++ pcid &= ~PTI_USER_PCID_MASK;*/ \ ++ asm volatile("mov %0,%%cr3": : "r" (new_cr3) : "memory"); \ ++ /* iee_rwx_gate(IEE_SWITCH_TO_KERNEL, new_cr3);*/ \ ++ iee_rw_gate(IEE_WRITE_TOKEN_TTBR1, current, new_cr3); \ ++ if (!arch_irqs_disabled_flags(flags)) \ ++ arch_local_irq_enable(); \ ++ } while (0); ++#endif ++ ++ ++ ++ ++#ifdef CONFIG_KOI ++ ++extern void *koi_kcalloc_wrapper(struct module *mod, size_t n, size_t size, gfp_t flags); ++extern void *koi_kmalloc_array_wrapper(struct module *mod, size_t n, size_t size, gfp_t flags); ++extern void *koi_vmalloc_wrapper(struct module *mod, unsigned long size); ++extern void *koi_kmalloc_wrapper(struct module *mod, size_t size, gfp_t flags); ++extern void *koi_kzalloc_node_wrapper(struct module *mod, size_t size, gfp_t flags, int node); ++extern void *koi_kzalloc_wrapper(struct module *mod, size_t size, gfp_t flags); ++ ++ ++#define koi_copy_to_user_wrapper(to, from, n) \ ++({ \ ++ koi_switch_to_kernel(); \ ++ long long ret = copy_to_user(to, from, n); \ ++ koi_switch_to_ko(); \ ++ ret; \ ++}) ++ ++#define koi_copy_from_user_wrapper(to, from, n) \ ++({ \ ++ koi_switch_to_kernel(); \ ++ long long ret = copy_from_user(to, from, n); \ ++ koi_switch_to_ko(); \ ++ ret; \ ++}) ++ ++#define koi_kasprintf_wrapper(gfp, fmt, args...)\ ++ ({ \ ++ koi_switch_to_kernel(); \ ++ void *ret = kasprintf(gfp, fmt, ##args); \ ++ koi_map_mem(THIS_MODULE, (unsigned long)ret, sizeof(void *)); \ ++ koi_switch_to_ko(); \ ++ ret;\ ++ }) ++ ++#define koi_sprintf_wrapper(buf, fmt, args...) \ ++({ \ ++ koi_switch_to_kernel(); \ ++ int ret = sprintf(buf, fmt, ##args); \ ++ koi_switch_to_ko(); \ ++ ret; \ ++}) ++ ++#define koi_scnprintf_wrapper(buf, size, fmt, args...) \ ++ ({ \ ++ int ret; \ ++ koi_switch_to_kernel(); \ ++ ret = scnprintf(buf, size, fmt, ##args); \ ++ koi_switch_to_ko(); \ ++ ret; \ ++ }) ++ ++#define koi_sscanf_wrapper(buf, fmt, args...) \ ++ ({ \ ++ int ret; \ ++ koi_switch_to_kernel(); \ ++ ret = sscanf(buf, fmt, ##args); \ ++ koi_switch_to_ko(); \ ++ ret; \ ++ }) ++ ++#define koi_printk_wrapper(arg_0, args...) \ ++ ({ \ ++ int ret; \ ++ koi_switch_to_kernel(); \ ++ ret = printk(arg_0, ##args); \ ++ koi_switch_to_ko(); \ ++ ret; \ ++ }) ++ ++#define PTR_ERR_wrapper(arg) \ ++({ \ ++ long ret; \ ++ koi_switch_to_kernel(); \ ++ ret = PTR_ERR(arg); \ ++ koi_switch_to_ko(); \ ++ ret; \ ++}) ++#define koi_rcu_read_lock_wrapper() \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ rcu_read_lock(); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_rcu_read_unlock_wrapper() \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ rcu_read_unlock(); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_mutex_lock_wrapper(lock) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ mutex_lock(lock); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_mutex_unlock_wrapper(lock) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ mutex_unlock(lock); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_mutex_init_wrapper(lock) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ mutex_init(lock); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_spin_lock_wrapper(lock) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ spin_lock(lock); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_spin_unlock_wrapper(lock) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ spin_unlock(lock); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_spin_lock_irq_wrapper(lock) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ spin_lock_irq(lock); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++ ++#define koi_spin_unlock_irq_wrapper(lock) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ spin_unlock_irq(lock); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_spin_lock_irqsave_wrapper(lock, flags) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ spin_lock_irqsave(lock, flags); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++ ++#define koi_spin_unlock_irqrestore_wrapper(lock, flags) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ spin_unlock_irqrestore(lock, flags); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++ ++#define koi_spin_lock_bh_wrapper(lock) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ spin_lock_bh(lock); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_spin_unlock_bh_wrapper(lock) \ ++ do { \ ++ koi_switch_to_kernel(); \ ++ spin_unlock_bh(lock); \ ++ koi_switch_to_ko(); \ ++ } while(0); ++ ++#define koi_dev_err_wrapper(dev, fmt, args...) \ ++ ({ \ ++ koi_switch_to_kernel(); \ ++ dev_err(dev, fmt, ##args); \ ++ koi_switch_to_ko(); \ ++ }) ++ ++#else ++ ++#define koi_copy_to_user_wrapper copy_to_user ++ ++#define koi_copy_from_user_wrapper copy_from_user ++ ++#define koi_kasprintf_wrapper kasprintf ++ ++#define koi_scnprintf_wrapper scnprintf ++ ++#define koi_sscanf_wrapper sscanf ++ ++#define koi_sprintf_wrapper sprintf ++ ++#define koi_rcu_read_lock_wrapper rcu_read_lock ++ ++#define koi_rcu_read_unlock_wrapper rcu_read_unlock ++ ++#define koi_mutex_lock_wrapper mutex_lock ++ ++#define koi_mutex_unlock_wrapper mutex_unlock ++ ++#define koi_mutex_init_wrapper mutex_init ++ ++#define koi_spin_lock_irq_wrapper spin_lock_irq ++ ++#define koi_spin_unlock_irq_wrapper spin_unlock_irq ++ ++#define koi_spin_lock_wrapper spin_lock ++ ++#define koi_spin_unlock_wrapper spin_unlock ++ ++#define koi_spin_lock_irqsave_wrapper spin_lock_irqsave ++ ++#define koi_spin_unlock_irqrestore_wrapper spin_lock_irqrestore ++ ++#define koi_spin_lock_bh_wrapper spin_lock_bh ++ ++#define koi_spin_unlock_bh_wrapper spin_unlock_bh ++ ++#define koi_kzalloc_wrapper(mod, size, flags) kzalloc(size, flags) ++ ++#define koi_kzalloc_node_wrapper(mod, size, flags, node) kzalloc_node(size, flags, node) ++ ++#define koi_kmalloc_wrapper(mod, size, flags) kmalloc(size, flags) ++ ++#define koi_vmalloc_wrapper(mod, size) vmalloc(size) ++ ++#define koi_kmalloc_array_wrapper(mod, n, size, flags) kmalloc_array(n, size, flags) ++ ++#define koi_kcalloc_wrapper(mod, n, size, flags) kcalloc(n, size, flags) ++ ++#endif +\ No newline at end of file +diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h +index 1b93ff80b43b..4b27230dff49 100644 +--- a/arch/x86/include/asm/page.h ++++ b/arch/x86/include/asm/page.h +@@ -61,6 +61,26 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr, + #define __boot_va(x) __va(x) + #define __boot_pa(x) __pa(x) + ++#ifdef CONFIG_IEE ++extern unsigned long IEE_OFFSET; ++#ifndef __iee_pa ++#define __iee_pa(x) (__pa(x - IEE_OFFSET)) ++#endif ++#ifndef __phys_to_iee ++#define __phys_to_iee(x) ((void *)(__va(x) + IEE_OFFSET)) ++#endif ++#else ++#ifdef CONFIG_KOI ++extern unsigned long KOI_OFFSET; ++#ifndef __koi_pa ++#define __koi_pa(x) (__pa(x - KOI_OFFSET)) ++#endif ++#ifndef __phys_to_koi ++#define __phys_to_koi(x) ((void *)(__va(x) + KOI_OFFSET)) ++#endif ++#endif ++#endif /* CONFIG_IEE*/ ++ + /* + * virt_to_page(kaddr) returns a valid pointer if and only if + * virt_addr_valid(kaddr) returns true. +diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h +index 9dab85aba7af..e14b0b574e0f 100644 +--- a/arch/x86/include/asm/page_64.h ++++ b/arch/x86/include/asm/page_64.h +@@ -19,6 +19,10 @@ extern unsigned long vmalloc_base; + extern unsigned long vmemmap_base; + extern unsigned long physmem_end; + ++#ifdef CONFIG_PTP ++extern unsigned long iee_ptdesc_base; ++#endif ++ + static __always_inline unsigned long __phys_addr_nodebug(unsigned long x) + { + unsigned long y = x - __START_KERNEL_map; +diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h +index 86bd4311daf8..c8656ccb03c1 100644 +--- a/arch/x86/include/asm/page_types.h ++++ b/arch/x86/include/asm/page_types.h +@@ -29,6 +29,13 @@ + + #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) + ++#ifdef CONFIG_IEE ++#define SET_UPAGE(x) __pg(pgprot_val(x) | _PAGE_USER) ++#endif /* CONFIG_IEE*/ ++#if defined (CONFIG_IEE) || defined (CONFIG_KOI) ++#define SET_NG(x) __pg(pgprot_val(x) & (~_PAGE_GLOBAL)) ++#endif ++ + #define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_TSK_EXEC + + #define __PHYSICAL_START ALIGN(CONFIG_PHYSICAL_START, \ +diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h +index c7ec5bb88334..cd9505d0c769 100644 +--- a/arch/x86/include/asm/pgalloc.h ++++ b/arch/x86/include/asm/pgalloc.h +@@ -12,6 +12,10 @@ + + static inline int __paravirt_pgd_alloc(struct mm_struct *mm) { return 0; } + ++#ifdef CONFIG_KOI ++pgd_t *koi_pgd_alloc(void); ++#endif ++ + #ifdef CONFIG_PARAVIRT_XXL + #include + #else +@@ -147,13 +151,78 @@ static inline void pgd_populate_safe(struct mm_struct *mm, pgd_t *pgd, p4d_t *p4 + set_pgd_safe(pgd, __pgd(_PAGE_TABLE | __pa(p4d))); + } + ++#ifdef CONFIG_PTP ++#include ++ ++static inline void iee_pmd_populate_kernel_pre_init(struct mm_struct *mm, ++ pmd_t *pmd, pte_t *pte) ++{ ++ paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT); ++ iee_set_pmd_pre_init(pmd, __pmd(__pa(pte) | _PAGE_TABLE)); ++} ++static inline void iee_pmd_populate_kernel_safe_pre_init(struct mm_struct *mm, ++ pmd_t *pmd, pte_t *pte) ++{ ++ paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT); ++ iee_set_pmd_safe_pre_init(pmd, __pmd(__pa(pte) | _PAGE_TABLE)); ++} ++ ++static inline void iee_pud_populate_pre_init(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) ++{ ++ paravirt_alloc_pmd(mm, __pa(pmd) >> PAGE_SHIFT); ++ iee_set_pud_pre_init(pud, __pud(_PAGE_TABLE | __pa(pmd))); ++} ++ ++static inline void iee_pud_populate_safe_pre_init(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) ++{ ++ paravirt_alloc_pmd(mm, __pa(pmd) >> PAGE_SHIFT); ++ iee_set_pud_safe_pre_init(pud, __pud(_PAGE_TABLE | __pa(pmd))); ++} ++ ++static inline void iee_p4d_populate_pre_init(struct mm_struct *mm, p4d_t *p4d, pud_t *pud) ++{ ++ paravirt_alloc_pud(mm, __pa(pud) >> PAGE_SHIFT); ++ iee_set_p4d_pre_init(p4d, __p4d(_PAGE_TABLE | __pa(pud))); ++} ++ ++static inline void iee_p4d_populate_safe_pre_init(struct mm_struct *mm, p4d_t *p4d, pud_t *pud) ++{ ++ paravirt_alloc_pud(mm, __pa(pud) >> PAGE_SHIFT); ++ iee_set_p4d_safe_pre_init(p4d, __p4d(_PAGE_TABLE | __pa(pud))); ++} ++ ++static inline void iee_pgd_populate_pre_init(struct mm_struct *mm, pgd_t *pgd, p4d_t *p4d) ++{ ++ if (!pgtable_l5_enabled()) ++ return; ++ paravirt_alloc_p4d(mm, __pa(p4d) >> PAGE_SHIFT); ++ iee_set_pgd_pre_init(pgd, __pgd(_PAGE_TABLE | __pa(p4d))); ++} ++ ++static inline void iee_pgd_populate_safe_pre_init(struct mm_struct *mm, pgd_t *pgd, p4d_t *p4d) ++{ ++ if (!pgtable_l5_enabled()) ++ return; ++ paravirt_alloc_p4d(mm, __pa(p4d) >> PAGE_SHIFT); ++ iee_set_pgd_safe_pre_init(pgd, __pgd(_PAGE_TABLE | __pa(p4d))); ++} ++ ++#endif ++ + static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long addr) + { + gfp_t gfp = GFP_KERNEL_ACCOUNT; + + if (mm == &init_mm) + gfp &= ~__GFP_ACCOUNT; ++ #ifdef CONFIG_PTP ++ if (iee_pgt_jar_init) ++ return (p4d_t *)get_iee_pgtable_page(gfp); ++ else ++ return (p4d_t *)get_zeroed_page(gfp); ++ #else + return (p4d_t *)get_zeroed_page(gfp); ++ #endif + } + + static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d) +@@ -162,7 +231,11 @@ static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d) + return; + + BUG_ON((unsigned long)p4d & (PAGE_SIZE-1)); ++ #ifdef CONFIG_PTP ++ free_iee_pgtable_page(p4d); ++ #else + free_page((unsigned long)p4d); ++ #endif + } + + extern void ___p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d); +diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h +index 993d49cd379a..82fac64eccd5 100644 +--- a/arch/x86/include/asm/pgtable.h ++++ b/arch/x86/include/asm/pgtable.h +@@ -94,6 +94,14 @@ extern pmdval_t early_pmd_flags; + #define pud_clear(pud) native_pud_clear(pud) + #endif + ++#ifdef CONFIG_PTP ++#define iee_set_pte_pre_init(ptep, pte) iee_early_set_pte(ptep, pte) ++#define iee_set_pmd_pre_init(pmdp, pmd) iee_early_set_pmd(pmdp, pmd) ++#define iee_set_pgd_pre_init(pgdp, pgd) iee_early_set_pgd(pgdp, pgd) ++#define iee_set_p4d_pre_init(p4dp, p4d) iee_early_set_p4d(p4dp, p4d) ++#define iee_set_pud_pre_init(pudp, pud) iee_early_set_pud(pudp, pud) ++#endif ++ + #define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep) + #define pmd_clear(pmd) native_pmd_clear(pmd) + +@@ -251,6 +259,14 @@ static inline unsigned long pgd_pfn(pgd_t pgd) + return (pgd_val(pgd) & PTE_PFN_MASK) >> PAGE_SHIFT; + } + ++#ifdef CONFIG_IEE ++#define __pte_to_phys(pte) (pte_pfn(pte) << PAGE_SHIFT) ++#define __pmd_to_phys(pmd) (__pte_to_phys(__pte(pmd_val(pmd)))) ++#define __pud_to_phys(pud) (__pte_to_phys(__pte(pud_val(pud)))) ++#define __p4d_to_phys(p4d) (__pte_to_phys(__pte(p4d_val(p4d)))) ++#define __pgd_to_phys(pgd) (__pte_to_phys(__pte(pgd_val(pgd)))) ++#endif ++ + #define p4d_leaf p4d_large + static inline int p4d_large(p4d_t p4d) + { +@@ -928,6 +944,13 @@ static inline pgd_t pti_set_user_pgtbl(pgd_t *pgdp, pgd_t pgd) + #include + #include + ++#ifdef CONFIG_KOI ++static inline int pte_valid(pte_t pte) ++{ ++ return pte.pte & _PAGE_PRESENT; ++} ++#endif ++ + static inline int pte_none(pte_t pte) + { + return !(pte.pte & ~(_PAGE_KNL_ERRATUM_MASK)); +@@ -1189,6 +1212,20 @@ static inline int pgd_none(pgd_t pgd) + + extern int direct_gbpages; + void init_mem_mapping(void); ++#ifdef CONFIG_IEE ++void init_iee_mapping(void); ++unsigned long init_memory_mapping_for_iee(unsigned long start, ++ unsigned long end, pgprot_t prot); ++#else ++#ifdef CONFIG_KOI ++void init_koi_mapping(void); ++unsigned long init_memory_mapping_for_koi(unsigned long start, ++ unsigned long end, pgprot_t prot); ++#endif ++#endif /* CONFIG_IEE*/ ++#ifdef CONFIG_PTP ++void init_iee(void); ++#endif + void early_alloc_pgt_buf(void); + extern void memblock_find_dma_reserve(void); + void __init poking_init(void); +@@ -1289,6 +1326,11 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, + return pte; + } + ++#ifdef CONFIG_PTP ++extern pgprotval_t iee_set_try_cmpxchg(pgprotval_t *pgprotp, pgprotval_t old_pgprotval, pgprotval_t new_pgprotval); ++extern pgprotval_t iee_set_xchg(pgprotval_t *pgprotp, pgprotval_t pgprotval); ++#endif ++ + #define __HAVE_ARCH_PTEP_SET_WRPROTECT + static inline void ptep_set_wrprotect(struct mm_struct *mm, + unsigned long addr, pte_t *ptep) +@@ -1303,7 +1345,12 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, + old_pte = READ_ONCE(*ptep); + do { + new_pte = pte_wrprotect(old_pte); +- } while (!try_cmpxchg((long *)&ptep->pte, (long *)&old_pte, *(long *)&new_pte)); ++ } ++ #ifdef CONFIG_PTP ++ while (!iee_set_try_cmpxchg(__phys_to_iee(__pa(ptep)), pte_val(old_pte), pte_val(new_pte))); ++ #else ++ while (!try_cmpxchg((long *)&ptep->pte, (long *)&old_pte, *(long *)&new_pte)); ++ #endif + } + + #define flush_tlb_fix_spurious_fault(vma, address, ptep) do { } while (0) +@@ -1365,7 +1412,12 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm, + old_pmd = READ_ONCE(*pmdp); + do { + new_pmd = pmd_wrprotect(old_pmd); +- } while (!try_cmpxchg((long *)pmdp, (long *)&old_pmd, *(long *)&new_pmd)); ++ } ++ #ifdef CONFIG_PTP ++ while (!iee_set_try_cmpxchg(__phys_to_iee(__pa(pmdp)), pmd_val(old_pmd), pmd_val(new_pmd))); ++ #else ++ while (!try_cmpxchg((long *)pmdp, (long *)&old_pmd, *(long *)&new_pmd)); ++ #endif + } + + #ifndef pmdp_establish +@@ -1375,10 +1427,19 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma, + { + page_table_check_pmd_set(vma->vm_mm, pmdp, pmd); + if (IS_ENABLED(CONFIG_SMP)) { ++ #ifdef CONFIG_PTP ++ pmdval_t pmdval = iee_set_xchg(__phys_to_iee(__pa(pmdp)), pmd_val(pmd)); ++ return native_make_pmd(pmdval); ++ #else + return xchg(pmdp, pmd); ++ #endif + } else { + pmd_t old = *pmdp; ++ #ifdef CONFIG_PTP ++ set_pmd(pmdp, pmd); ++ #else + WRITE_ONCE(*pmdp, pmd); ++ #endif + return old; + } + } +@@ -1466,6 +1527,17 @@ static inline p4d_t *user_to_kernel_p4dp(p4d_t *p4dp) + */ + static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count) + { ++ #ifdef CONFIG_PTP ++ iee_rw_gate(IEE_OP_MEMCPY, dst, src, count * sizeof(pgd_t)); ++#ifdef CONFIG_PAGE_TABLE_ISOLATION ++ if (!static_cpu_has(X86_FEATURE_PTI)) ++ return; ++ /* Clone the user space pgd as well */ ++ iee_rw_gate(IEE_OP_MEMCPY, kernel_to_user_pgdp(dst), ++ kernel_to_user_pgdp(src), count * sizeof(pgd_t)); ++#endif ++ #else ++ + memcpy(dst, src, count * sizeof(pgd_t)); + #ifdef CONFIG_PAGE_TABLE_ISOLATION + if (!static_cpu_has(X86_FEATURE_PTI)) +@@ -1474,6 +1546,7 @@ static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count) + memcpy(kernel_to_user_pgdp(dst), kernel_to_user_pgdp(src), + count * sizeof(pgd_t)); + #endif ++ #endif + } + + #define PTE_SHIFT ilog2(PTRS_PER_PTE) +diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h +index a629b1b9f65a..10134a82fa2c 100644 +--- a/arch/x86/include/asm/pgtable_64.h ++++ b/arch/x86/include/asm/pgtable_64.h +@@ -16,6 +16,22 @@ + #include + #include + ++#ifdef CONFIG_KOI ++ ++#ifndef __PAGETABLE_PUD_FOLDED ++#define pud_val(x) native_pud_val(x) ++#define __pud(x) native_make_pud(x) ++#endif ++ ++#ifndef __PAGETABLE_PMD_FOLDED ++#define pmd_val(x) native_pmd_val(x) ++#define __pmd(x) native_make_pmd(x) ++#endif ++ ++#define pte_val(x) native_pte_val(x) ++#define __pte(x) native_make_pte(x) ++#endif ++ + extern p4d_t level4_kernel_pgt[512]; + extern p4d_t level4_ident_pgt[512]; + extern pud_t level3_kernel_pgt[512]; +@@ -31,6 +47,12 @@ extern pgd_t init_top_pgt[]; + extern void paging_init(void); + static inline void sync_initial_page_table(void) { } + ++#ifdef CONFIG_PTP ++#include ++extern unsigned long long iee_rw_gate(int flag, ...); ++extern pgprotval_t iee_set_xchg(pgprotval_t *pgprotp, pgprotval_t pgprotval); ++#endif ++ + #define pte_ERROR(e) \ + pr_err("%s:%d: bad pte %p(%016lx)\n", \ + __FILE__, __LINE__, &(e), pte_val(e)) +@@ -62,9 +84,23 @@ static inline bool mm_p4d_folded(struct mm_struct *mm) + void set_pte_vaddr_p4d(p4d_t *p4d_page, unsigned long vaddr, pte_t new_pte); + void set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte); + ++ ++#ifdef CONFIG_KOI ++static int pmd_present(pmd_t pmd); ++static int pud_present(pud_t pud); ++#endif + static inline void native_set_pte(pte_t *ptep, pte_t pte) + { ++#ifdef CONFIG_KOI ++ if (pte_flags(pte) & _PAGE_PRESENT) { ++ pte = __pte(pte_val(pte) & ~_PAGE_GLOBAL); ++ } ++#endif ++ #ifdef CONFIG_PTP ++ iee_rw_gate(IEE_OP_SET_PTE, ptep, pte); ++ #else + WRITE_ONCE(*ptep, pte); ++ #endif + } + + static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr, +@@ -80,7 +116,16 @@ static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) + + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) + { ++#ifdef CONFIG_KOI ++ if (pmd_present(pmd) && pmd_leaf(pmd)) { ++ pmd = __pmd(pmd_val(pmd) & ~_PAGE_GLOBAL); ++ } ++#endif ++ #ifdef CONFIG_PTP ++ iee_rw_gate(IEE_OP_SET_PMD, pmdp, pmd); ++ #else + WRITE_ONCE(*pmdp, pmd); ++ #endif + } + + static inline void native_pmd_clear(pmd_t *pmd) +@@ -91,7 +136,12 @@ static inline void native_pmd_clear(pmd_t *pmd) + static inline pte_t native_ptep_get_and_clear(pte_t *xp) + { + #ifdef CONFIG_SMP ++ #ifdef CONFIG_PTP ++ pteval_t pteval = iee_set_xchg(__phys_to_iee(__pa(xp)), 0); ++ return native_make_pte(pteval); ++ #else + return native_make_pte(xchg(&xp->pte, 0)); ++ #endif + #else + /* native_local_ptep_get_and_clear, + but duplicated because of cyclic dependency */ +@@ -104,7 +154,12 @@ static inline pte_t native_ptep_get_and_clear(pte_t *xp) + static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp) + { + #ifdef CONFIG_SMP ++ #ifdef CONFIG_PTP ++ pmdval_t pmdval = iee_set_xchg(__phys_to_iee(__pa(xp)), 0); ++ return native_make_pmd(pmdval); ++ #else + return native_make_pmd(xchg(&xp->pmd, 0)); ++ #endif + #else + /* native_local_pmdp_get_and_clear, + but duplicated because of cyclic dependency */ +@@ -116,7 +171,17 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp) + + static inline void native_set_pud(pud_t *pudp, pud_t pud) + { ++#ifdef CONFIG_KOI ++ if ((pud_val(pud) & (_PAGE_PSE | _PAGE_PRESENT)) == ++ (_PAGE_PSE | _PAGE_PRESENT)) { ++ pud = __pud(pud_val(pud) & ~_PAGE_GLOBAL); ++ } ++#endif ++ #ifdef CONFIG_PTP ++ iee_rw_gate(IEE_OP_SET_PUD, pudp, pud); ++ #else + WRITE_ONCE(*pudp, pud); ++ #endif + } + + static inline void native_pud_clear(pud_t *pud) +@@ -127,7 +192,12 @@ static inline void native_pud_clear(pud_t *pud) + static inline pud_t native_pudp_get_and_clear(pud_t *xp) + { + #ifdef CONFIG_SMP ++ #ifdef CONFIG_PTP ++ pudval_t pudval = iee_set_xchg(__phys_to_iee(__pa(xp)), 0); ++ return native_make_pud(pudval); ++ #else + return native_make_pud(xchg(&xp->pud, 0)); ++ #endif + #else + /* native_local_pudp_get_and_clear, + * but duplicated because of cyclic dependency +@@ -144,13 +214,21 @@ static inline void native_set_p4d(p4d_t *p4dp, p4d_t p4d) + pgd_t pgd; + + if (pgtable_l5_enabled() || !IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION)) { ++ #ifdef CONFIG_PTP ++ iee_rw_gate(IEE_OP_SET_P4D, p4dp, p4d); ++ #else + WRITE_ONCE(*p4dp, p4d); ++ #endif + return; + } + + pgd = native_make_pgd(native_p4d_val(p4d)); + pgd = pti_set_user_pgtbl((pgd_t *)p4dp, pgd); ++ #ifdef CONFIG_PTP ++ iee_rw_gate(IEE_OP_SET_P4D, p4dp, native_make_p4d(native_pgd_val(pgd))); ++ #else + WRITE_ONCE(*p4dp, native_make_p4d(native_pgd_val(pgd))); ++ #endif + } + + static inline void native_p4d_clear(p4d_t *p4d) +@@ -160,7 +238,12 @@ static inline void native_p4d_clear(p4d_t *p4d) + + static inline void native_set_pgd(pgd_t *pgdp, pgd_t pgd) + { ++ #ifdef CONFIG_PTP ++ iee_rw_gate(IEE_OP_SET_PGD, pgdp, ++ pti_set_user_pgtbl(pgdp, pgd)); ++ #else + WRITE_ONCE(*pgdp, pti_set_user_pgtbl(pgdp, pgd)); ++ #endif + } + + static inline void native_pgd_clear(pgd_t *pgd) +@@ -168,6 +251,42 @@ static inline void native_pgd_clear(pgd_t *pgd) + native_set_pgd(pgd, native_make_pgd(0)); + } + ++#ifdef CONFIG_PTP ++static inline void iee_early_set_pte(pte_t *ptep, pte_t pte) ++{ ++ WRITE_ONCE(*ptep, pte); ++} ++ ++static inline void iee_early_set_pmd(pmd_t *pmdp, pmd_t pmd) ++{ ++ WRITE_ONCE(*pmdp, pmd); ++} ++ ++static inline void iee_early_set_pud(pud_t *pudp, pud_t pud) ++{ ++ WRITE_ONCE(*pudp, pud); ++} ++ ++static inline void iee_early_set_p4d(p4d_t *p4dp, p4d_t p4d) ++{ ++ pgd_t pgd; ++ ++ if (pgtable_l5_enabled() || !IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION)) { ++ WRITE_ONCE(*p4dp, p4d); ++ return; ++ } ++ ++ pgd = native_make_pgd(native_p4d_val(p4d)); ++ pgd = pti_set_user_pgtbl((pgd_t *)p4dp, pgd); ++ WRITE_ONCE(*p4dp, native_make_p4d(native_pgd_val(pgd))); ++} ++ ++static inline void iee_early_set_pgd(pgd_t *pgdp, pgd_t pgd) ++{ ++ WRITE_ONCE(*pgdp, pti_set_user_pgtbl(pgdp, pgd)); ++} ++#endif ++ + /* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. +diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h +index 35c416f06155..bd0d82bb9b18 100644 +--- a/arch/x86/include/asm/pgtable_64_types.h ++++ b/arch/x86/include/asm/pgtable_64_types.h +@@ -140,6 +140,11 @@ extern unsigned int ptrs_per_p4d; + # define VMEMMAP_START __VMEMMAP_BASE_L4 + #endif /* CONFIG_DYNAMIC_MEMORY_LAYOUT */ + ++#ifdef CONFIG_PTP ++#define __VPTDMAP_BASE_L4 0xffffeb0000000000UL ++#define __VPTDMAP_BASE_L5 0xffd6000000000000UL ++#endif ++ + #ifdef CONFIG_RANDOMIZE_MEMORY + # define PHYSMEM_END physmem_end + #endif +diff --git a/arch/x86/include/asm/pgtable_slab.h b/arch/x86/include/asm/pgtable_slab.h +new file mode 100644 +index 000000000000..8b0b4c111a0e +--- /dev/null ++++ b/arch/x86/include/asm/pgtable_slab.h +@@ -0,0 +1,10 @@ ++#ifndef _LINUX_PGTABLE_SLAB_H ++#define _LINUX_PGTABLE_SLAB_H ++ ++extern void __init iee_pgtable_init(void); ++extern void *get_iee_pgtable_page(gfp_t gfpflags); ++extern void free_iee_pgtable_page(void *obj); ++extern void *get_iee_pgd_page(gfp_t gfpflags); ++extern void free_iee_pgd_page(void *obj); ++ ++#endif +\ No newline at end of file +diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h +index 48f8dd47cf68..47f697ce730c 100644 +--- a/arch/x86/include/asm/special_insns.h ++++ b/arch/x86/include/asm/special_insns.h +@@ -10,6 +10,10 @@ + #include + #include + ++#ifdef CONFIG_IEE ++#include ++#endif ++ + /* + * The compiler should not reorder volatile asm statements with respect to each + * other: they should execute in program order. However GCC 4.9.x and 5.x have +@@ -51,9 +55,20 @@ static inline unsigned long __native_read_cr3(void) + + static inline void native_write_cr3(unsigned long val) + { ++ #ifdef CONFIG_IEE ++ iee_rwx_gate(IEE_WRITE_CR3, val); ++ #else + asm volatile("mov %0,%%cr3": : "r" (val) : "memory"); ++ #endif + } + ++#ifdef CONFIG_IEE ++static inline void native_write_cr3_pre_init(unsigned long val) ++{ ++ asm volatile("mov %0,%%cr3": : "r" (val) : "memory"); ++} ++#endif ++ + static inline unsigned long native_read_cr4(void) + { + unsigned long val; +diff --git a/arch/x86/include/asm/stack_slab.h b/arch/x86/include/asm/stack_slab.h +new file mode 100644 +index 000000000000..514c09e1c415 +--- /dev/null ++++ b/arch/x86/include/asm/stack_slab.h +@@ -0,0 +1,8 @@ ++#ifndef _LINUX_STACK_SLAB_H ++#define _LINUX_STACK_SLAB_H ++ ++extern void __init iee_stack_init(void); ++extern void *get_iee_stack(void); ++extern void free_iee_stack(void *obj); ++ ++#endif +\ No newline at end of file +diff --git a/arch/x86/include/asm/tlb.h b/arch/x86/include/asm/tlb.h +index 580636cdc257..f18a855dfa13 100644 +--- a/arch/x86/include/asm/tlb.h ++++ b/arch/x86/include/asm/tlb.h +@@ -34,4 +34,10 @@ static inline void __tlb_remove_table(void *table) + free_page_and_swap_cache(table); + } + ++#ifdef CONFIG_PTP ++static inline void __iee_tlb_remove_table(void *_table) { ++ struct page *page = (struct page *)_table; ++ free_iee_pgtable_page((void *)page_to_virt(page)); ++} ++#endif + #endif /* _ASM_X86_TLB_H */ +diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile +index 2b86fa2d8c64..d8d4e64af538 100644 +--- a/arch/x86/kernel/Makefile ++++ b/arch/x86/kernel/Makefile +@@ -151,6 +151,10 @@ obj-$(CONFIG_X86_CET) += cet.o + + obj-$(CONFIG_X86_USER_SHADOW_STACK) += shstk.o + ++obj-$(CONFIG_IEE) += iee/ ++ ++obj-$(CONFIG_HIVE) += sfi_bpf_arch.o ++ + ### + # 64 bit specific files + ifeq ($(CONFIG_X86_64),y) +@@ -161,6 +165,7 @@ ifeq ($(CONFIG_X86_64),y) + obj-$(CONFIG_MMCONF_FAM10H) += mmconf-fam10h_64.o + obj-y += vsmp_64.o + obj-$(CONFIG_INTEL_IOMMU) += zhaoxin_kh40000.o ++ obj-$(CONFIG_KOI) += koi/ + endif + + obj-$(CONFIG_HYGON_CSV) += csv.o +diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c +index dc3576303f1a..d528f34a0541 100644 +--- a/arch/x86/kernel/asm-offsets.c ++++ b/arch/x86/kernel/asm-offsets.c +@@ -119,6 +119,12 @@ static void __used common(void) + #ifdef CONFIG_CALL_DEPTH_TRACKING + OFFSET(X86_call_depth, pcpu_hot, call_depth); + #endif ++#ifdef CONFIG_IEE ++ DEFINE(iee_from_token_offset, offsetof(struct task_token, iee_stack)); ++ DEFINE(tmp_page_from_token_offset, offsetof(struct task_token, tmp_page)); ++ DEFINE(kernel_from_token_offset,offsetof(struct task_token, kernel_stack)); ++ DEFINE(pgd_from_token_offset, offsetof(struct task_token, pgd)); ++#endif + #if IS_ENABLED(CONFIG_CRYPTO_ARIA_AESNI_AVX_X86_64) + /* Offset for fields in aria_ctx */ + BLANK(); +diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c +index b66364429f98..78df6c5d7e51 100644 +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -68,6 +68,10 @@ + + #include "cpu.h" + ++#ifdef CONFIG_IEE ++#include ++#endif ++ + u32 elf_hwcap2 __read_mostly; + + /* Number of siblings per CPU package */ +@@ -400,14 +404,25 @@ static __always_inline void setup_umip(struct cpuinfo_x86 *c) + } + + /* These bits should not change their value after CPU init is finished. */ ++#ifdef CONFIG_IEE ++const unsigned long cr4_pinned_mask = ++ X86_CR4_UMIP | ++ X86_CR4_FSGSBASE | X86_CR4_CET; ++DEFINE_STATIC_KEY_FALSE_RO(cr_pinning); ++unsigned long cr4_pinned_bits __ro_after_init; ++#else + static const unsigned long cr4_pinned_mask = + X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_UMIP | + X86_CR4_FSGSBASE | X86_CR4_CET; + static DEFINE_STATIC_KEY_FALSE_RO(cr_pinning); + static unsigned long cr4_pinned_bits __ro_after_init; ++#endif + + void native_write_cr0(unsigned long val) + { ++#ifdef CONFIG_IEE ++ iee_rwx_gate(IEE_WRITE_CR0, val); ++#else + unsigned long bits_missing = 0; + + set_register: +@@ -422,11 +437,15 @@ void native_write_cr0(unsigned long val) + /* Warn after we've set the missing bits. */ + WARN_ONCE(bits_missing, "CR0 WP bit went missing!?\n"); + } ++#endif + } + EXPORT_SYMBOL(native_write_cr0); + + void __no_profile native_write_cr4(unsigned long val) + { ++#ifdef CONFIG_IEE ++ iee_rwx_gate(IEE_WRITE_CR4, val); ++#else + unsigned long bits_changed = 0; + + set_register: +@@ -442,6 +461,7 @@ void __no_profile native_write_cr4(unsigned long val) + WARN_ONCE(bits_changed, "pinned CR4 bits changed: 0x%lx!?\n", + bits_changed); + } ++#endif + } + #if IS_MODULE(CONFIG_LKDTM) + EXPORT_SYMBOL_GPL(native_write_cr4); +diff --git a/arch/x86/kernel/espfix_64.c b/arch/x86/kernel/espfix_64.c +index 16f9814c9be0..729b426ab161 100644 +--- a/arch/x86/kernel/espfix_64.c ++++ b/arch/x86/kernel/espfix_64.c +@@ -34,6 +34,9 @@ + #include + #include + ++#ifdef CONFIG_PTP ++#include ++#endif + /* + * Note: we only need 6*8 = 48 bytes for the espfix stack, but round + * it up to a cache line to avoid unnecessary sharing. +@@ -106,6 +109,11 @@ void __init init_espfix_bsp(void) + pgd_t *pgd; + p4d_t *p4d; + ++ #ifdef CONFIG_PTP ++ iee_set_logical_mem_ro((unsigned long)espfix_pud_page); ++ set_iee_page((unsigned long)__va(__pa_symbol(espfix_pud_page)), 0); ++ #endif ++ + /* Install the espfix pud into the kernel page directory */ + pgd = &init_top_pgt[pgd_index(ESPFIX_BASE_ADDR)]; + p4d = p4d_alloc(&init_mm, pgd, ESPFIX_BASE_ADDR); +@@ -158,6 +166,9 @@ void init_espfix_ap(int cpu) + + pmd_p = (pmd_t *)page_address(page); + pud = __pud(__pa(pmd_p) | (PGTABLE_PROT & ptemask)); ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)pmd_p, 0); ++ #endif + paravirt_alloc_pmd(&init_mm, __pa(pmd_p) >> PAGE_SHIFT); + for (n = 0; n < ESPFIX_PUD_CLONES; n++) + set_pud(&pud_p[n], pud); +@@ -170,6 +181,9 @@ void init_espfix_ap(int cpu) + + pte_p = (pte_t *)page_address(page); + pmd = __pmd(__pa(pte_p) | (PGTABLE_PROT & ptemask)); ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)pte_p, 0); ++ #endif + paravirt_alloc_pte(&init_mm, __pa(pte_p) >> PAGE_SHIFT); + for (n = 0; n < ESPFIX_PMD_CLONES; n++) + set_pmd(&pmd_p[n], pmd); +diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c +index 1defe865de67..3a0dfb04da8a 100644 +--- a/arch/x86/kernel/head64.c ++++ b/arch/x86/kernel/head64.c +@@ -44,6 +44,10 @@ + #include + #include + ++#ifdef CONFIG_IEE ++#include ++#endif ++ + /* + * Manage page tables very early on. + */ +@@ -68,6 +72,11 @@ unsigned long vmemmap_base __ro_after_init = __VMEMMAP_BASE_L4; + EXPORT_SYMBOL(vmemmap_base); + #endif + ++#ifdef CONFIG_PTP ++unsigned long iee_ptdesc_base __ro_after_init = __VPTDMAP_BASE_L4; ++EXPORT_SYMBOL(iee_ptdesc_base); ++#endif ++ + /* + * GDT used on the boot CPU before switching to virtual addresses. + */ +@@ -118,6 +127,10 @@ static bool __head check_la57_support(unsigned long physaddr) + *fixup_long(&vmalloc_base, physaddr) = __VMALLOC_BASE_L5; + *fixup_long(&vmemmap_base, physaddr) = __VMEMMAP_BASE_L5; + ++ #ifdef CONFIG_PTP ++ *fixup_long(&iee_ptdesc_base, physaddr) = __VPTDMAP_BASE_L5; ++ #endif ++ + return true; + } + #else +@@ -686,6 +699,9 @@ void __init __noreturn x86_64_start_reservations(char *real_mode_data) + * which also hasn't happened yet in early CPU bringup. + */ + static gate_desc bringup_idt_table[NUM_EXCEPTION_VECTORS] __page_aligned_data; ++#ifdef CONFIG_IEE ++const unsigned long iee_bringup_idt_table_addr = (unsigned long)bringup_idt_table; ++#endif + + static struct desc_ptr bringup_idt_descr = { + .size = (NUM_EXCEPTION_VECTORS * sizeof(gate_desc)) - 1, +@@ -720,7 +736,11 @@ static void startup_64_load_idt(unsigned long physbase) + } + + desc->address = (unsigned long)idt; ++ #ifdef CONFIG_IEE ++ iee_load_idt_pre_init(desc); ++ #else + native_load_idt(desc); ++ #endif + } + + /* This is used when running on kernel addresses */ +diff --git a/arch/x86/kernel/idt.c b/arch/x86/kernel/idt.c +index fc77a96040b7..d15e0d80b38b 100644 +--- a/arch/x86/kernel/idt.c ++++ b/arch/x86/kernel/idt.c +@@ -163,13 +163,20 @@ static const __initconst struct idt_data apic_idts[] = { + }; + + /* Must be page-aligned because the real IDT is used in the cpu entry area */ +-static gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss; ++gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss; ++#ifdef CONFIG_IEE ++const unsigned long iee_idt_table_addr = (unsigned long)idt_table; ++#endif + +-static struct desc_ptr idt_descr __ro_after_init = { ++struct desc_ptr idt_descr __ro_after_init = { + .size = IDT_TABLE_SIZE - 1, + .address = (unsigned long) idt_table, + }; + ++#ifdef CONFIG_KOI ++const unsigned long koi_idt_descr_addr = (unsigned long)&idt_descr; ++#endif ++ + void load_current_idt(void) + { + lockdep_assert_irqs_disabled(); +diff --git a/arch/x86/kernel/iee/Makefile b/arch/x86/kernel/iee/Makefile +new file mode 100644 +index 000000000000..8ca1d39a5d01 +--- /dev/null ++++ b/arch/x86/kernel/iee/Makefile +@@ -0,0 +1,5 @@ ++obj-$(CONFIG_IEE) += iee.o iee-gate.o iee-func.o stack-slab.o ++obj-$(CONFIG_KEYP) += iee-key.o ++ccflags-$(CONFIG_IEE_SELINUX_P) := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include ++obj-$(CONFIG_IEE_SELINUX_P) += iee-selinuxp.o ++obj-$(CONFIG_PTP) += pgtable-slab.o +diff --git a/arch/x86/kernel/iee/iee-func.c b/arch/x86/kernel/iee/iee-func.c +new file mode 100644 +index 000000000000..ae52ae528ba8 +--- /dev/null ++++ b/arch/x86/kernel/iee/iee-func.c +@@ -0,0 +1,353 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static inline void iee_set_sensitive_pte(pte_t *lm_ptep, int order, int use_block_pmd) ++{ ++#ifdef CONFIG_PTP ++ iee_rw_gate(IEE_SET_SENSITIVE_PTE, lm_ptep, order, use_block_pmd); ++#else ++ int i; ++ if (use_block_pmd) { ++ pmd_t pmd = __pmd(pte_val(READ_ONCE(*lm_ptep))); ++ pmd = __pmd((pmd_val(pmd) & (~__RW) & (~___D))); ++ WRITE_ONCE(*lm_ptep, __pte(pmd_val(pmd))); ++ } ++ else ++ { ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*lm_ptep); ++ pte = __pte((pte_val(pte) & (~__RW) & (~___D))); ++ WRITE_ONCE(*lm_ptep, pte); ++ lm_ptep++; ++ } ++ } ++#endif ++} ++ ++static inline void iee_unset_sensitive_pte(pte_t *lm_ptep, int order, int use_block_pmd) ++{ ++#ifdef CONFIG_PTP ++ iee_rw_gate(IEE_UNSET_SENSITIVE_PTE, lm_ptep, order, use_block_pmd); ++#else ++ int i; ++ if (use_block_pmd) ++ { ++ pmd_t pmd = __pmd(pte_val(READ_ONCE(*lm_ptep))); ++ pmd = __pmd((pmd_val(pmd) | __RW | ___D)); ++ WRITE_ONCE(*lm_ptep, __pte(pmd_val(pmd))); ++ } ++ else ++ { ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*lm_ptep); ++ pte = __pte(pte_val(pte) | __RW | ___D); ++ WRITE_ONCE(*lm_ptep, pte); ++ lm_ptep++; ++ } ++ } ++#endif ++} ++ ++static void do_split_huge_pmd(pmd_t* pmdp) ++{ ++ // pte_t *pgtable = pte_alloc_one_kernel(&init_mm); ++ gfp_t gfp = (GFP_PGTABLE_KERNEL & ~__GFP_HIGHMEM) | __GFP_COMP; ++ pte_t *pgtable = (pte_t *)page_to_virt(alloc_pages(gfp, 0)); ++ #ifdef CONFIG_PTP ++ iee_split_huge_pmd(pmdp, pgtable); ++ #else ++ int i; ++ struct page *page = pmd_page(*pmdp); ++ pte_t *ptep = (pte_t *)((unsigned long)pgtable); ++ for (i = 0; i < PMD_SIZE / PAGE_SIZE; i++, ptep++) { ++ pte_t entry; ++ pgprot_t pgprot = pmd_pgprot(*pmdp); ++ entry = mk_pte(page + i, pgprot); ++ WRITE_ONCE(*ptep, entry); ++ } ++ #endif ++ spinlock_t *ptl = pmd_lock(&init_mm, pmdp); ++ if (pmd_leaf(READ_ONCE(*pmdp))) { ++ smp_wmb(); ++ pmd_populate_kernel(&init_mm, pmdp, pgtable); ++ pgtable = NULL; ++ } ++ spin_unlock(ptl); ++ if(pgtable) ++ { ++ #ifdef CONFIG_PTP ++ memset(pgtable, 0, PAGE_SIZE); ++ #endif ++ struct page *page = virt_to_page(pgtable); ++ __free_pages(page, compound_order(page)); ++ // pte_free_kernel(&init_mm, pgtable); ++ } ++} ++ ++// Input is the lm vaddr of sensitive data. ++void set_iee_page(unsigned long addr, int order) ++{ ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ pud_t *pudp = pud_offset(p4dp, addr); ++ pmd_t *pmdp = pmd_offset(pudp, addr); ++ int use_block_pmd = 0; ++ ++ if (pmd_leaf(*pmdp) && order < 9) { ++ do_split_huge_pmd(pmdp); ++ } else if (pmd_leaf(*pmdp)) { ++ use_block_pmd = 1; ++ } ++ pte_t *lm_ptep; ++ if (use_block_pmd) { ++ lm_ptep = (pte_t *)pmdp; ++ } else { ++ lm_ptep = pte_offset_kernel(pmdp, addr); ++ } ++ ++ iee_set_sensitive_pte(lm_ptep, order, use_block_pmd); ++ flush_tlb_kernel_range(addr, addr+PAGE_SIZE*(1 << order)); ++} ++ ++// Input is the lm vaddr of sensitive data. ++void unset_iee_page(unsigned long addr, int order) ++{ ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ pud_t *pudp = pud_offset(p4dp, addr); ++ pmd_t *pmdp = pmd_offset(pudp, addr); ++ pte_t *lm_ptep; ++ int use_block_pmd = 0; ++ // Use Block Descriptor. ++ if(pmd_leaf(*pmdp)) ++ { ++ use_block_pmd = 1; ++ lm_ptep = (pte_t *)pmdp; ++ } ++ else ++ lm_ptep = pte_offset_kernel(pmdp, addr); ++ ++ iee_unset_sensitive_pte(lm_ptep, order, use_block_pmd); ++ flush_tlb_kernel_range(addr, addr+PAGE_SIZE*(1 << order)); ++} ++ ++void iee_set_logical_mem_ro(unsigned long addr) ++{ ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ pud_t *pudp = pud_offset(p4dp, addr); ++ pmd_t *pmdp = pmd_offset(pudp, addr); ++ if (pmd_leaf(*pmdp)) { ++ do_split_huge_pmd(pmdp); ++ } ++ ++ pte_t *ptep = pte_offset_kernel(pmdp, addr); ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte((pte_val(pte) & (~__RW) & (~___D))); ++ set_pte(ptep, pte); ++ flush_tlb_kernel_range(addr, addr+PAGE_SIZE); ++} ++ ++void set_iee_page_valid(unsigned long addr) {} ++ ++void set_iee_page_invalid(unsigned long addr) {} ++ ++void iee_set_token_page_valid(void *token, void *token_page, unsigned int order) ++{ ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, (unsigned long)token); ++ p4d_t *p4dp = p4d_offset(pgdp, (unsigned long)token); ++ pud_t *pudp = pud_offset(p4dp, (unsigned long)token); ++ pmd_t *token_pmdp = pmd_offset(pudp, (unsigned long)token); ++ pte_t *token_ptep = pte_offset_kernel(token_pmdp, (unsigned long)token); ++ ++ pgdp = pgd_offset_pgd(pgdir, (unsigned long)token_page); ++ p4dp = p4d_offset(pgdp, (unsigned long)token_page); ++ pudp = pud_offset(p4dp, (unsigned long)token_page); ++ pmd_t *token_page_pmdp = pmd_offset(pudp, (unsigned long)token_page); ++ pte_t *token_page_ptep; ++ ++ int use_block_pmd = 0; ++ if (pmd_leaf(*token_page_pmdp) && order < 9) { ++ do_split_huge_pmd(token_page_pmdp); ++ } else if (pmd_leaf(*token_page_pmdp)) { ++ use_block_pmd = 1; ++ } ++ ++ if (use_block_pmd) { ++ token_page_ptep = (pte_t *)token_page_pmdp; ++ } else { ++ token_page_ptep = pte_offset_kernel(token_page_pmdp, (unsigned long)token_page); ++ } ++ ++#ifdef CONFIG_PTP ++ iee_rw_gate(IEE_OP_SET_TOKEN, token_ptep, token_page_ptep, token_page, order, use_block_pmd); ++#else ++ if (use_block_pmd) ++ { ++ pmd_t *pmdp = (pmd_t *)token_page_ptep; ++ pmd_t pmd = READ_ONCE(*pmdp); ++ pmd = __pmd((pmd_val(pmd) & ~__RW) & ~___D & ~__PP); ++ WRITE_ONCE(*pmdp, pmd); ++ for(int i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*token_ptep); ++ pte = __pte(((pte_val(pte) & ~PTE_PFN_MASK) | __PP) | (__phys_to_pfn(__pa(token_page) + i * PAGE_SIZE) << PAGE_SHIFT)); ++ WRITE_ONCE(*token_ptep, pte); ++ token_ptep++; ++ } ++ } ++ else { ++ for(int i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*token_ptep); ++ pte = __pte(((pte_val(pte) & ~PTE_PFN_MASK) | __PP) | (__phys_to_pfn(__pa(token_page) + i * PAGE_SIZE) << PAGE_SHIFT)); ++ WRITE_ONCE(*token_ptep, pte); ++ pte = READ_ONCE(*token_page_ptep); ++ pte = __pte((pte_val(pte) & ~__RW) & ~___D & ~__PP); ++ WRITE_ONCE(*token_page_ptep, pte); ++ token_ptep++; ++ token_page_ptep++; ++ } ++ } ++#endif ++ flush_tlb_kernel_range((unsigned long)token, (unsigned long)(token + (PAGE_SIZE * (1 << order)))); ++ flush_tlb_kernel_range((unsigned long)token_page, (unsigned long)(token_page + (PAGE_SIZE * (1 << order)))); ++} ++ ++void iee_set_token_page_invalid(void *token, void *__unused, unsigned long order) ++{ ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, (unsigned long)token); ++ p4d_t *p4dp = p4d_offset(pgdp, (unsigned long)token); ++ pud_t *pudp = pud_offset(p4dp, (unsigned long)token); ++ pmd_t *token_pmdp = pmd_offset(pudp, (unsigned long)token); ++ pte_t *token_ptep = pte_offset_kernel(token_pmdp, (unsigned long)token); ++ void *token_page = page_address(pte_page(*token_ptep)); ++ ++ pgdp = pgd_offset_pgd(pgdir, (unsigned long)token_page); ++ p4dp = p4d_offset(pgdp, (unsigned long)token_page); ++ pudp = pud_offset(p4dp, (unsigned long)token_page); ++ pmd_t *token_page_pmdp = pmd_offset(pudp, (unsigned long)token_page); ++ pte_t *token_page_ptep; ++ int use_block_pmd = 0; ++ if (pmd_leaf(*token_page_pmdp)) { ++ use_block_pmd = 1; ++ token_page_ptep = (pte_t *)token_page_pmdp; ++ } else { ++ token_page_ptep = pte_offset_kernel(token_page_pmdp, (unsigned long)token_page); ++ } ++#ifdef CONFIG_PTP ++ iee_rw_gate(IEE_OP_UNSET_TOKEN, token_ptep, token_page_ptep, token, token_page, order); ++#else ++ if (use_block_pmd) ++ { ++ pmd_t *pmdp = (pmd_t *)token_page_ptep; ++ pmd_t pmd = READ_ONCE(*pmdp); ++ pmd = __pmd(pmd_val(pmd) | ___D | __RW | __PP); ++ WRITE_ONCE(*pmdp, pmd); ++ for(int i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*token_ptep); ++ pte = __pte((pte_val(pte) & ~PTE_PFN_MASK & ~__PP) | (__phys_to_pfn(__iee_pa(token) + i * PAGE_SIZE) << PAGE_SHIFT)); ++ WRITE_ONCE(*token_ptep, pte); ++ token_ptep++; ++ } ++ } ++ else ++ { ++ for(int i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*token_ptep); ++ pte = __pte((pte_val(pte) & ~PTE_PFN_MASK & ~__PP) | (__phys_to_pfn(__iee_pa(token) + i * PAGE_SIZE) << PAGE_SHIFT)); ++ WRITE_ONCE(*token_ptep, pte); ++ pte = READ_ONCE(*token_page_ptep); ++ pte = __pte(pte_val(pte) | ___D | __RW | __PP); ++ WRITE_ONCE(*token_page_ptep, pte); ++ token_ptep++; ++ token_page_ptep++; ++ } ++ } ++#endif ++ free_pages((unsigned long)token_page, order); ++ flush_tlb_kernel_range((unsigned long)token, (unsigned long)(token + (PAGE_SIZE * (1 << order)))); ++ flush_tlb_kernel_range((unsigned long)token_page, (unsigned long)(token_page + (PAGE_SIZE * (1 << order)))); ++} ++ ++void __init iee_set_kernel_upage(unsigned long addr) ++{ ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ pgd_t pgd = READ_ONCE(*pgdp); ++ pgd = __pgd((pgd_val(pgd) | _USR) & ~___G); ++ set_pgd(pgdp, pgd); ++ ++ p4d_t *p4dp = p4d_offset(pgdp, addr); ++ p4d_t p4d = READ_ONCE(*p4dp); ++ p4d = __p4d((p4d_val(p4d) | _USR) & ~___G); ++ set_p4d(p4dp, p4d); ++ ++ pud_t *pudp = pud_offset(p4dp, addr); ++ if (pud_leaf(*pudp)) { ++ panic("Huge pud page set upage!\n"); ++ } ++ pud_t pud = READ_ONCE(*pudp); ++ pud = __pud((pud_val(pud) | _USR) & ~___G); ++ set_pud(pudp, pud); ++ ++ pmd_t *pmdp = pmd_offset(pudp, addr); ++ if (pmd_leaf(*pmdp)) { ++ do_split_huge_pmd(pmdp); ++ } ++ pmd_t pmd = READ_ONCE(*pmdp); ++ pmd = __pmd((pmd_val(pmd) | _USR) & ~___G); ++ set_pmd(pmdp, pmd); ++ ++ pte_t *ptep = pte_offset_kernel(pmdp, addr); ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte((pte_val(pte) | _USR) & ~___G); ++ set_pte(ptep, pte); ++ flush_tlb_kernel_range(addr, addr + PAGE_SIZE); ++} ++ ++void set_iee_stack_page(unsigned long addr, int order) ++{ ++ set_iee_page(addr ,order); ++} ++ ++void unset_iee_stack_page(unsigned long addr, int order) ++{ ++ unset_iee_page(addr, order); ++} ++ ++void __init iee_rest_init(void) ++{ ++ // Prepare data for iee rwx gate ++ unsigned long addr; ++ /* Map .iee.text as U RWX pages */ ++ addr = (unsigned long)__iee_si_text_start; ++ for (; addr < (unsigned long)__iee_si_text_end; addr += PAGE_SIZE){ ++ iee_set_kernel_upage((unsigned long)addr); ++ } ++ iee_init_done = true; ++ iee_base_swapper_pg_dir = __sme_pa(swapper_pg_dir); ++ /* Map .iee.data as RO pages */ ++ set_memory_ro((unsigned long)__iee_si_data_start, ((unsigned long)__iee_si_data_end - (unsigned long)__iee_si_data_start) / PAGE_SIZE); ++ // All initialization is done. Do some simple tests. ++ pr_err("IEE: testing iee_exec_entry si_test..."); ++ iee_rwx_gate(IEE_SI_TEST); ++ pr_err("IEE: testing iee_exec_entry si_test..."); ++} +\ No newline at end of file +diff --git a/arch/x86/kernel/iee/iee-gate.S b/arch/x86/kernel/iee/iee-gate.S +new file mode 100644 +index 000000000000..c80e3f6b45b3 +--- /dev/null ++++ b/arch/x86/kernel/iee/iee-gate.S +@@ -0,0 +1,209 @@ ++#include ++#include ++#include ++#include ++#include ++ ++#define X86_CR4_SMEP_SMAP (X86_CR4_SMEP | X86_CR4_SMAP) ++ ++#ifdef CONFIG_PTP ++SYM_FUNC_START(iee_set_xchg) ++ /* save RFLAGS, close irq */ ++ pushfq ++ cli ++ /* stac, disable SMAP */ ++ stac ++ ++ xchg %rsi, (%rdi) ++ mov %rsi, %rax ++ ++ /* clac, enable SMAP */ ++ clac ++ /* restore RFLAGS*/ ++ popfq ++ jmp __x86_return_thunk /* ret */ ++SYM_FUNC_END(iee_set_xchg) ++ ++SYM_FUNC_START(iee_set_try_cmpxchg) ++ /* save RFLAGS, close irq */ ++ pushfq ++ cli ++ /* stac, disable SMAP */ ++ stac ++ ++ mov %rsi, %rax ++ lock cmpxchgq %rdx, (%rdi) ++ ++ /* clac, enable SMAP */ ++ clac ++ /* restore RFLAGS*/ ++ popfq ++ jmp __x86_return_thunk /* ret */ ++SYM_FUNC_END(iee_set_try_cmpxchg) ++#endif /* CONFIG_PTP */ ++ ++SYM_FUNC_START(iee_rw_gate) ++ /* save Interrupt flag */ ++ pushf ++ /* close irq*/ ++ cli ++ ++ /* stac, disable SMAP */ ++ stac ++ ++ pushq %r12 ++ ++ /* switch to iee stack */ ++ movq PER_CPU_VAR(pcpu_hot) + X86_current_task, %r12 /* r12 -> task_struct */ ++ addq iee_offset(%rip), %r12 ++ movq %rsp, kernel_from_token_offset(%r12) ++ movq iee_from_token_offset(%r12), %rsp ++ ++ /* call iee func */ ++ leaq iee_funcs(%rip), %rax ++ call *(%rax, %rdi, 8) ++ ++ /* switch to kernel stack */ ++ movq kernel_from_token_offset(%r12), %rsp ++ ++ popq %r12 ++ ++ /* clac, enable SMAP */ ++ clac ++ ++ /* restore irq*/ ++ popf ++ ++ lfence /* Serializing instruction before the ret */ ++ jmp __x86_return_thunk /* ret */ ++SYM_FUNC_END(iee_rw_gate) ++#if defined(CONFIG_CREDP) || defined(CONFIG_KEYP) || defined(CONFIG_PTP) || defined(CONFIG_KOI) ++EXPORT_SYMBOL(iee_rw_gate) ++#endif ++ ++SYM_FUNC_START(iee_read_token_stack) ++ /* save Interrupt flag */ ++ pushf ++ /* close irq*/ ++ cli ++ ++ push %r12 ++ ++ /* stac, disable SMAP */ ++ stac ++ ++ addq iee_offset(%rip), %rdi ++ movq iee_from_token_offset(%rdi), %rax ++ ++ /* clac, enable SMAP */ ++ clac ++ ++ pop %r12 ++ ++ /* restore irq*/ ++ popf ++ ++ lfence /* Serializing instruction before the ret */ ++ jmp __x86_return_thunk /* ret */ ++SYM_FUNC_END(iee_read_token_stack) ++ ++SYM_FUNC_START(iee_read_tmp_page) ++ /* save Interrupt flag */ ++ pushf ++ /* close irq*/ ++ cli ++ ++ push %r12 ++ ++ /* stac, disable SMAP */ ++ stac ++ ++ addq iee_offset(%rip), %rdi ++ movq tmp_page_from_token_offset(%rdi), %rax ++ ++ /* clac, enable SMAP */ ++ clac ++ ++ pop %r12 ++ ++ /* restore irq*/ ++ popf ++ lfence /* Serializing instruction before the ret */ ++ jmp __x86_return_thunk /* ret */ ++SYM_FUNC_END(iee_read_tmp_page) ++ ++SYM_FUNC_START(iee_read_freeptr) ++ /* save Interrupt flag */ ++ pushf ++ /* close irq*/ ++ cli ++ ++ push %r12 ++ ++ /* stac, disable SMAP */ ++ stac ++ ++ addq iee_offset(%rip), %rdi ++ movq (%rdi), %rax ++ ++ /* clac, enable SMAP */ ++ clac ++ ++ pop %r12 ++ ++ /* restore irq*/ ++ popf ++ lfence /* Serializing instruction before the ret */ ++ jmp __x86_return_thunk /* ret */ ++SYM_FUNC_END(iee_read_freeptr) ++ ++SYM_FUNC_START(iee_rwx_gate) ++ pushq %r12 ++ ++ /* save Interrupt flag*/ ++ pushfq ++ /* close irq */ ++ cli ++ ++ /* set SMEP=0 to enable supervisor-mode exec user-mode insn */ ++ movq %cr4, %rax /* rax -> cr4 */ ++ andq $(~X86_CR4_SMEP_SMAP), %rax ++ movq %rax, %cr4 ++ ++ movq %rsp, %r12 ++ ++ /* If iee hasn't been initialized, skip stack switch. */ ++ cmpb $0, iee_init_done(%rip) ++ jz 2f ++#ifdef CONFIG_KOI ++ cmpq $IEE_SWITCH_TO_KOI, %rdi ++ jz 2f ++ cmpq $IEE_SWITCH_TO_KERNEL, %rdi ++ jz 2f ++#endif ++ /* switch to iee stack */ ++ movq PER_CPU_VAR(pcpu_hot) + X86_current_task, %rax /* rax -> task_struct */ ++ addq iee_offset(%rip), %rax ++ movq %rsp, kernel_from_token_offset(%rax) ++ movq iee_from_token_offset(%rax), %rsp ++ ++2: call iee_si_handler ++ ++ /* switch to kernel stack. If iee hasn't been initialized, skip switch*/ ++ movq %r12, %rsp ++ ++ /* set SMEP=1 to disable supervisor-mode exec user-mode insn */ ++ movq %cr4, %rax /* rax -> cr4 */ ++1: orq $X86_CR4_SMEP_SMAP, %rax ++ movq %rax, %cr4 ++ andq $(X86_CR4_SMEP_SMAP), %rax ++ cmpq $(X86_CR4_SMEP_SMAP), %rax ++ jnz 1 ++ ++ /* restore irq*/ ++ popfq ++ ++ popq %r12 ++ jmp __x86_return_thunk /* ret */ ++SYM_FUNC_END(iee_rwx_gate) ++EXPORT_SYMBOL(iee_rwx_gate) +\ No newline at end of file +diff --git a/arch/x86/kernel/iee/iee-selinuxp.c b/arch/x86/kernel/iee/iee-selinuxp.c +new file mode 100644 +index 000000000000..47d6eeb7a784 +--- /dev/null ++++ b/arch/x86/kernel/iee/iee-selinuxp.c +@@ -0,0 +1,36 @@ ++#include ++#include ++extern unsigned long long iee_rw_gate(int flag, ...); ++ ++#ifdef CONFIG_IEE_SELINUX_P ++inline void iee_set_selinux_status_pg(struct page *new_page) ++{ ++ iee_rw_gate(IEE_SEL_SET_STATUS_PG, new_page); ++} ++ ++inline void enforcing_set(bool value) ++{ ++ iee_rw_gate(IEE_SEL_SET_ENFORCING, value); ++} ++ ++inline void selinux_mark_initialized(void) ++{ ++ iee_rw_gate(IEE_SEL_SET_INITIALIZED); ++} ++ ++inline void iee_set_sel_policy_cap(unsigned int idx, int cap) ++{ ++ iee_rw_gate(IEE_SEL_SET_POLICY_CAP, idx, cap); ++} ++ ++/* ++ * Please make sure param iee_new_policy is from policy_jar memcache. ++ * Need to free new_policy after calling this func as it's only used to ++ * trans data from kernel. ++ */ ++inline void iee_sel_rcu_assign_policy(struct selinux_policy *new_policy, ++ struct selinux_policy *iee_new_policy) ++{ ++ iee_rw_gate(IEE_SEL_RCU_ASSIGN_POLICY, new_policy, iee_new_policy); ++} ++#endif +diff --git a/arch/x86/kernel/iee/iee.c b/arch/x86/kernel/iee/iee.c +new file mode 100644 +index 000000000000..53d6c1898b0b +--- /dev/null ++++ b/arch/x86/kernel/iee/iee.c +@@ -0,0 +1,1080 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_PTP ++void __iee_code _iee_set_pte(unsigned long __unused, pte_t *ptep, pte_t pte); ++void __iee_code _iee_set_pmd(unsigned long __unused, pmd_t *pmdp, pmd_t pmd); ++void __iee_code _iee_set_pud(unsigned long __unused, pud_t *pudp, pud_t pud); ++void __iee_code _iee_set_p4d(unsigned long __unused, p4d_t *p4dp, p4d_t p4d); ++void __iee_code _iee_set_pgd(unsigned long __unused, pgd_t *pgdp, pgd_t pgd); ++#endif ++void __iee_code _iee_memcpy(unsigned long __unused, void *dst, void *src, size_t n); ++void __iee_code _iee_memset(unsigned long __unused, void *ptr, int data, size_t n); ++void __iee_code _iee_set_freeptr(unsigned long __unused, void **pptr, void *ptr); ++void __iee_code _iee_split_huge_pmd(unsigned long __unused, pmd_t *pmdp, pte_t *pgtable); ++void __iee_code _iee_set_token_pgd(unsigned long __unused, struct task_struct *tsk, pgd_t *pgd); ++void __iee_code _iee_init_token(unsigned long __unused, struct task_struct *tsk, void *iee_stack, void *tmp_page); ++void __iee_code _iee_invalidate_token(unsigned long __unused, struct task_struct *tsk); ++void __iee_code _iee_validate_token(unsigned long __unused, struct task_struct *tsk); ++void __iee_code _iee_unset_token(unsigned long __unused, pte_t *token_ptep, pte_t *token_page_ptep, void *token, void *token_page, unsigned long order, int use_block_pmd); ++void __iee_code _iee_set_token(unsigned long __unused, pte_t *token_ptep, pte_t *new_ptep, void *new, unsigned long order, int use_block_pmd); ++void __iee_code _iee_set_track(unsigned long __unused, struct track *ptr, struct track *data); ++unsigned long __iee_code _iee_test_and_clear_bit(unsigned long __unused, long nr, volatile unsigned long *addr); ++void __iee_code _iee_set_sensitive_pte(unsigned long __unused, pte_t *lm_ptep, int order, int use_block_pmd); ++void __iee_code _iee_unset_sensitive_pte(unsigned long __unused, pte_t *lm_ptep, int order, int use_block_pmd); ++ ++#ifdef CONFIG_CREDP ++extern struct cred init_cred; ++void __iee_code _iee_set_cred_uid(unsigned long __unused, struct cred *cred, kuid_t uid); ++void __iee_code _iee_set_cred_gid(unsigned long __unused, struct cred *cred, kgid_t gid); ++void __iee_code _iee_copy_cred(unsigned long __unused, struct cred *old, struct cred *new); ++void __iee_code _iee_set_cred_suid(unsigned long __unused, struct cred *cred, kuid_t suid); ++void __iee_code _iee_set_cred_sgid(unsigned long __unused, struct cred *cred, kgid_t sgid); ++void __iee_code _iee_set_cred_euid(unsigned long __unused, struct cred *cred, kuid_t euid); ++void __iee_code _iee_set_cred_egid(unsigned long __unused, struct cred *cred, kgid_t egid); ++void __iee_code _iee_set_cred_fsuid(unsigned long __unused, struct cred *cred, kuid_t fsuid); ++void __iee_code _iee_set_cred_fsgid(unsigned long __unused, struct cred *cred, kgid_t fsgid); ++void __iee_code _iee_set_cred_user(unsigned long __unused, struct cred *cred, struct user_struct *user); ++void __iee_code _iee_set_cred_user_ns(unsigned long __unused, struct cred *cred, struct user_namespace *user_ns); ++void __iee_code _iee_set_cred_group_info(unsigned long __unused, struct cred *cred, struct group_info *group_info); ++void __iee_code _iee_set_cred_securebits(unsigned long __unused, struct cred *cred, unsigned securebits); ++void __iee_code _iee_set_cred_cap_inheritable(unsigned long __unused, struct cred *cred, kernel_cap_t cap_inheritable); ++void __iee_code _iee_set_cred_cap_permitted(unsigned long __unused, struct cred *cred, kernel_cap_t cap_permitted); ++void __iee_code _iee_set_cred_cap_effective(unsigned long __unused, struct cred *cred, kernel_cap_t cap_effective); ++void __iee_code _iee_set_cred_cap_bset(unsigned long __unused, struct cred *cred, kernel_cap_t cap_bset); ++void __iee_code _iee_set_cred_cap_ambient(unsigned long __unused, struct cred *cred, kernel_cap_t cap_ambient); ++void __iee_code _iee_set_cred_jit_keyring(unsigned long __unused, struct cred *cred, unsigned char jit_keyring); ++void __iee_code _iee_set_cred_session_keyring(unsigned long __unused, struct cred *cred, struct key *session_keyring); ++void __iee_code _iee_set_cred_process_keyring(unsigned long __unused, struct cred *cred, struct key *process_keyring); ++void __iee_code _iee_set_cred_thread_keyring(unsigned long __unused, struct cred *cred, struct key *thread_keyring); ++void __iee_code _iee_set_cred_request_key_auth(unsigned long __unused, struct cred *cred, struct key *request_key_auth); ++void __iee_code _iee_set_cred_non_rcu(unsigned long __unused, struct cred *cred, int non_rcu); ++void __iee_code _iee_set_cred_atomic_set_usage(unsigned long __unused, struct cred *cred, int i); ++unsigned long __iee_code _iee_set_cred_atomic_op_usage(unsigned long __unused, struct cred *cred, int flag, int nr); ++void __iee_code _iee_set_cred_security(unsigned long __unused, struct cred *cred, void *security); ++void __iee_code _iee_set_cred_rcu(unsigned long __unused, struct cred *cred, struct rcu_head *rcu); ++void __iee_code _iee_set_cred_ucounts(unsigned long __unused, struct cred *cred, struct ucounts *ucounts); ++#endif ++ ++#ifdef CONFIG_KEYP ++struct watch_list; ++void __iee_code _iee_set_key_union(unsigned long __unused, struct key *key, struct key_union *key_union); ++void __iee_code _iee_set_key_struct(unsigned long __unused, struct key *key, struct key_struct *key_struct); ++void __iee_code _iee_set_key_payload(unsigned long __unused, struct key *key, union key_payload *key_payload); ++unsigned long __iee_code _iee_set_key_usage(unsigned long __unused, struct key *key, int n, int flag); ++void __iee_code _iee_set_key_serial(unsigned long __unused, struct key *key, key_serial_t serial); ++void __iee_code _iee_set_key_watchers(unsigned long __unused, struct key *key, struct watch_list *watchers); ++void __iee_code _iee_set_key_user(unsigned long __unused, struct key *key, struct key_user *user); ++void __iee_code _iee_set_key_security(unsigned long __unused, struct key *key, void *security); ++void __iee_code _iee_set_key_expiry(unsigned long __unused, struct key *key, time64_t expiry); ++void __iee_code _iee_set_key_revoked_at(unsigned long __unused, struct key *key, time64_t revoked_at); ++void __iee_code _iee_set_key_last_used_at(unsigned long __unused, struct key *key, time64_t last_used_at); ++void __iee_code _iee_set_key_uid(unsigned long __unused, struct key *key, kuid_t uid); ++void __iee_code _iee_set_key_gid(unsigned long __unused, struct key *key, kgid_t gid); ++void __iee_code _iee_set_key_perm(unsigned long __unused, struct key *key, key_perm_t perm); ++void __iee_code _iee_set_key_quotalen(unsigned long __unused, struct key *key, unsigned short quotalen); ++void __iee_code _iee_set_key_datalen(unsigned long __unused, struct key *key, unsigned short datalen); ++void __iee_code _iee_set_key_state(unsigned long __unused, struct key *key, short state); ++void __iee_code _iee_set_key_magic(unsigned long __unused, struct key *key, unsigned magic); ++void __iee_code _iee_set_key_flags(unsigned long __unused, struct key *key, unsigned long flags); ++void __iee_code _iee_set_key_index_key(unsigned long __unused, struct key *key, struct keyring_index_key* index_key); ++void __iee_code _iee_set_key_hash(unsigned long __unused, struct key *key, unsigned long hash); ++void __iee_code _iee_set_key_len_desc(unsigned long __unused, struct key *key, unsigned long len_desc); ++void __iee_code _iee_set_key_type(unsigned long __unused, struct key *key, struct key_type *type); ++void __iee_code _iee_set_key_domain_tag(unsigned long __unused, struct key *key, struct key_tag *domain_tag); ++void __iee_code _iee_set_key_description(unsigned long __unused, struct key *key, char *description); ++void __iee_code _iee_set_key_restrict_link(unsigned long __unused, struct key *key, struct key_restriction *restrict_link); ++unsigned long __iee_code _iee_set_key_flag_bit(unsigned long __unused, struct key *key, long nr, int flag); ++#endif ++#ifdef CONFIG_KOI ++unsigned long __iee_code _iee_read_koi_stack(unsigned long iee_offset, struct task_struct *tsk); ++void __iee_code _iee_write_koi_stack(unsigned long iee_offset, struct task_struct *tsk, unsigned long koi_stack); ++unsigned long __iee_code _iee_read_token_ttbr1(unsigned long iee_offset, struct task_struct *tsk); ++void __iee_code _iee_write_token_ttbr1(unsigned long iee_offset, struct task_struct *tsk, unsigned long current_ttbr1); ++unsigned long __iee_code _iee_read_koi_kernel_stack(unsigned long iee_offset, struct task_struct *tsk); ++void __iee_code _iee_write_koi_kernel_stack(unsigned long iee_offset, struct task_struct *tsk, unsigned long kernel_stack); ++unsigned long __iee_code _iee_read_koi_stack_base(unsigned long iee_offset, struct task_struct *tsk); ++void __iee_code _iee_write_koi_stack_base(unsigned long iee_offset, struct task_struct *tsk, unsigned long koi_stack_base); ++void __iee_code _iee_set_koi_pgd(unsigned long iee_offset, unsigned long koi_pgd_addr); ++#endif ++ ++#ifdef CONFIG_IEE_SELINUX_P ++#include ++void __iee_code _iee_set_selinux_status_pg(unsigned long __unused, struct page* new_page); ++void __iee_code _iee_set_selinux_enforcing(unsigned long __unused, bool value); ++void __iee_code _iee_mark_selinux_initialized(unsigned long __unused); ++void __iee_code _iee_set_sel_policy_cap(unsigned long __unused, unsigned int idx, int cap); ++void __iee_code _iee_sel_rcu_assign_policy(unsigned long __unused, struct selinux_policy* new_policy, struct selinux_policy* iee_new_policy); ++#endif ++ ++typedef void (*iee_func)(void); ++iee_func iee_funcs[] = { ++ #ifdef CONFIG_PTP ++ (iee_func)_iee_set_pte, ++ (iee_func)_iee_set_pmd, ++ (iee_func)_iee_set_pud, ++ (iee_func)_iee_set_p4d, ++ (iee_func)_iee_set_pgd, ++ #endif ++ (iee_func)_iee_memcpy, ++ (iee_func)_iee_memset, ++ (iee_func)_iee_set_freeptr, ++ (iee_func)_iee_split_huge_pmd, ++ (iee_func)_iee_set_token_pgd, ++ (iee_func)_iee_init_token, ++ (iee_func)_iee_invalidate_token, ++ (iee_func)_iee_validate_token, ++ (iee_func)_iee_unset_token, ++ (iee_func)_iee_set_token, ++ (iee_func)_iee_set_track, ++ (iee_func)_iee_test_and_clear_bit, ++ (iee_func)_iee_set_sensitive_pte, ++ (iee_func)_iee_unset_sensitive_pte, ++#ifdef CONFIG_CREDP ++ (iee_func)_iee_copy_cred, ++ (iee_func)_iee_set_cred_uid, ++ (iee_func)_iee_set_cred_gid, ++ (iee_func)_iee_set_cred_suid, ++ (iee_func)_iee_set_cred_sgid, ++ (iee_func)_iee_set_cred_euid, ++ (iee_func)_iee_set_cred_egid, ++ (iee_func)_iee_set_cred_fsuid, ++ (iee_func)_iee_set_cred_fsgid, ++ (iee_func)_iee_set_cred_user, ++ (iee_func)_iee_set_cred_user_ns, ++ (iee_func)_iee_set_cred_group_info, ++ (iee_func)_iee_set_cred_securebits, ++ (iee_func)_iee_set_cred_cap_inheritable, ++ (iee_func)_iee_set_cred_cap_permitted, ++ (iee_func)_iee_set_cred_cap_effective, ++ (iee_func)_iee_set_cred_cap_bset, ++ (iee_func)_iee_set_cred_cap_ambient, ++ (iee_func)_iee_set_cred_jit_keyring, ++ (iee_func)_iee_set_cred_session_keyring, ++ (iee_func)_iee_set_cred_process_keyring, ++ (iee_func)_iee_set_cred_thread_keyring, ++ (iee_func)_iee_set_cred_request_key_auth, ++ (iee_func)_iee_set_cred_non_rcu, ++ (iee_func)_iee_set_cred_atomic_set_usage, ++ (iee_func)_iee_set_cred_atomic_op_usage, ++ (iee_func)_iee_set_cred_security, ++ (iee_func)_iee_set_cred_rcu, ++ (iee_func)_iee_set_cred_ucounts, ++#endif ++#ifdef CONFIG_KEYP ++ (iee_func)_iee_set_key_union, ++ (iee_func)_iee_set_key_struct, ++ (iee_func)_iee_set_key_payload, ++ (iee_func)_iee_set_key_usage, ++ (iee_func)_iee_set_key_serial, ++ (iee_func)_iee_set_key_watchers, ++ (iee_func)_iee_set_key_user, ++ (iee_func)_iee_set_key_security, ++ (iee_func)_iee_set_key_expiry, ++ (iee_func)_iee_set_key_revoked_at, ++ (iee_func)_iee_set_key_last_used_at, ++ (iee_func)_iee_set_key_uid, ++ (iee_func)_iee_set_key_gid, ++ (iee_func)_iee_set_key_perm, ++ (iee_func)_iee_set_key_quotalen, ++ (iee_func)_iee_set_key_datalen, ++ (iee_func)_iee_set_key_state, ++ (iee_func)_iee_set_key_magic, ++ (iee_func)_iee_set_key_flags, ++ (iee_func)_iee_set_key_index_key, ++ (iee_func)_iee_set_key_hash, ++ (iee_func)_iee_set_key_len_desc, ++ (iee_func)_iee_set_key_type, ++ (iee_func)_iee_set_key_domain_tag, ++ (iee_func)_iee_set_key_description, ++ (iee_func)_iee_set_key_restrict_link, ++ (iee_func)_iee_set_key_flag_bit, ++#endif ++#ifdef CONFIG_IEE_SELINUX_P ++ (iee_func)_iee_set_selinux_status_pg, ++ (iee_func)_iee_set_selinux_enforcing, ++ (iee_func)_iee_mark_selinux_initialized, ++ (iee_func)_iee_set_sel_policy_cap, ++ (iee_func)_iee_sel_rcu_assign_policy, ++#endif ++#ifdef CONFIG_KOI ++ (iee_func)_iee_read_koi_stack, ++ (iee_func)_iee_write_koi_stack, ++ (iee_func)_iee_read_token_ttbr1, ++ (iee_func)_iee_write_token_ttbr1, ++ (iee_func)_iee_read_koi_kernel_stack, ++ (iee_func)_iee_write_koi_kernel_stack, ++ (iee_func)_iee_read_koi_stack_base, ++ (iee_func)_iee_write_koi_stack_base, ++ (iee_func)_iee_set_koi_pgd, ++#endif ++ NULL ++}; ++ ++#ifdef CONFIG_KOI ++unsigned long __iee_code _iee_read_koi_stack(unsigned long __unused, struct task_struct *tsk) ++{ ++ struct task_token *token = (struct task_token *)(__phys_to_iee(__pa(tsk))); ++ return (unsigned long)token->koi_stack; ++} ++ ++void __iee_code _iee_write_koi_stack(unsigned long __unused, struct task_struct *tsk, unsigned long koi_stack) ++{ ++ struct task_token *token = (struct task_token *)(__phys_to_iee(__pa(tsk))); ++ token->koi_stack = (void *) koi_stack; ++} ++ ++unsigned long __iee_code _iee_read_token_ttbr1(unsigned long __unused, struct task_struct *tsk) ++{ ++ struct task_token *token = (struct task_token *)(__phys_to_iee(__pa(tsk))); ++ return token->current_ttbr1; ++} ++ ++void __iee_code _iee_write_token_ttbr1(unsigned long __unused, struct task_struct *tsk, unsigned long current_ttbr1) ++{ ++ struct task_token *token = (struct task_token *)(__phys_to_iee(__pa(tsk))); ++ token->current_ttbr1 = current_ttbr1; ++} ++ ++unsigned long __iee_code _iee_read_koi_kernel_stack(unsigned long __unused, struct task_struct *tsk) ++{ ++ struct task_token *token = (struct task_token *)(__phys_to_iee(__pa(tsk))); ++ return (unsigned long) token->koi_kernel_stack; ++} ++ ++void __iee_code _iee_write_koi_kernel_stack(unsigned long __unused, struct task_struct *tsk, unsigned long kernel_stack) ++{ ++ struct task_token *token = (struct task_token *)(__phys_to_iee(__pa(tsk))); ++ token->koi_kernel_stack = (void *) kernel_stack; ++} ++ ++unsigned long __iee_code _iee_read_koi_stack_base(unsigned long __unused, struct task_struct *tsk) ++{ ++ struct task_token *token = (struct task_token *)(__phys_to_iee(__pa(tsk))); ++ return (unsigned long)token->koi_stack_base; ++} ++ ++void __iee_code _iee_write_koi_stack_base(unsigned long __unused, struct task_struct *tsk, unsigned long koi_stack_base) ++{ ++ struct task_token *token = (struct task_token *)(__phys_to_iee(__pa(tsk))); ++ token->koi_stack_base = (void *) koi_stack_base; ++} ++ ++static inline void iee_set_koi_pgd_writeable(unsigned long koi_pgd_addr, unsigned long iee_si_addr) ++{ ++ return; ++} ++/* ++ * Set IEE SI codes U RWX here to avoid IEE DEP checking fault. ++ * Mark koi pgd in the same time. ++ */ ++void __iee_code _iee_set_koi_pgd(unsigned long iee_offset, unsigned long koi_pgd_addr) ++{ ++ return; ++} ++#endif ++ ++#ifdef CONFIG_PTP ++void __iee_code _iee_set_pte(unsigned long __unused, pte_t *ptep, pte_t pte) ++{ ++ WRITE_ONCE(*(pte_t *)(__phys_to_iee(__pa(ptep))), pte); ++} ++ ++void __iee_code _iee_set_pmd(unsigned long __unused, pmd_t *pmdp, pmd_t pmd) ++{ ++ WRITE_ONCE(*(pmd_t *)(__phys_to_iee(__pa(pmdp))), pmd); ++} ++ ++void __iee_code _iee_set_pud(unsigned long __unused, pud_t *pudp, pud_t pud) ++{ ++ WRITE_ONCE(*(pud_t *)(__phys_to_iee(__pa(pudp))), pud); ++} ++ ++void __iee_code _iee_set_p4d(unsigned long __unused, p4d_t *p4dp, p4d_t p4d) ++{ ++ WRITE_ONCE(*(p4d_t *)(__phys_to_iee(__pa(p4dp))), p4d); ++} ++ ++void __iee_code _iee_set_pgd(unsigned long __unused, pgd_t *pgdp, pgd_t pgd) ++{ ++ WRITE_ONCE(*(pgd_t *)(__phys_to_iee(__pa(pgdp))), pgd); ++} ++#endif ++ ++void __iee_code _iee_memcpy(unsigned long __unused, void *dst, void *src, size_t n) ++{ ++ char *_dst, *_src; ++ ++ _dst = (char *)(__phys_to_iee(__pa(dst))); ++ _src = (char *)src; ++ ++ while (n--) ++ *_dst++ = *_src++; ++} ++ ++void __iee_code _iee_set_track(unsigned long __unused, struct track *ptr, struct track *data) ++{ ++ _iee_memcpy(__unused, ptr, data, sizeof(struct track)); ++} ++ ++void __iee_code _iee_memset(unsigned long __unused, void *ptr, int data, size_t n) ++{ ++ char *_ptr; ++ ++ _ptr = (char *)(__phys_to_iee(__pa(ptr))); ++ ++ while (n--) ++ *_ptr++ = data; ++} ++ ++void __iee_code _iee_set_freeptr(unsigned long __unused, void **pptr, void *ptr) ++{ ++ pptr = (void **)(__phys_to_iee(__pa(pptr))); ++ *pptr = ptr; ++} ++ ++void __iee_code _iee_split_huge_pmd(unsigned long __unused, pmd_t *pmdp, pte_t *pgtable) ++{ ++ int i; ++ struct page *page = pmd_page(*pmdp); ++ pte_t *ptep = (pte_t *)(__phys_to_iee(__pa(pgtable))); ++ for (i = 0; i < PMD_SIZE / PAGE_SIZE; i++, ptep++) { ++ pte_t entry; ++ pgprot_t pgprot = pmd_pgprot(*pmdp); ++ entry = mk_pte(page + i, pgprot); ++ WRITE_ONCE(*ptep, entry); ++ } ++} ++ ++void __iee_code _iee_set_token_pgd(unsigned long __unused, struct task_struct *tsk, pgd_t *pgd) ++{ ++ struct task_token *token; ++ ++ token = (struct task_token *)(__phys_to_iee(__pa(tsk))); ++ token->pgd = pgd; ++} ++ ++void __iee_code _iee_init_token(unsigned long __unused, struct task_struct *tsk, void *iee_stack, void *tmp_page) ++{ ++ struct task_token *token; ++ ++ token = (struct task_token *)(__phys_to_iee(__pa(tsk))); ++ token->iee_stack = iee_stack; ++ token->tmp_page = tmp_page; ++} ++ ++void __iee_code _iee_invalidate_token(unsigned long __unused, struct task_struct *tsk) ++{ ++ struct task_token *token = (struct task_token *)(__phys_to_iee(__pa(tsk))); ++ token->pgd = NULL; ++ token->valid = false; ++ token->kernel_stack = NULL; ++} ++ ++void __iee_code _iee_validate_token(unsigned long __unused, struct task_struct *tsk) ++{ ++ struct task_token *token = (struct task_token *)(__phys_to_iee(__pa(tsk))); ++ token->valid = true; ++} ++ ++void __iee_code _iee_unset_token(unsigned long __unused, pte_t *token_ptep, pte_t *token_page_ptep, void *token, void *token_page, unsigned long order, int use_block_pmd) ++{ ++ token_ptep = (pte_t *)(__phys_to_iee(__pa(token_ptep))); ++ token_page_ptep = (pte_t *)(__phys_to_iee(__pa(token_page_ptep))); ++ if (use_block_pmd) ++ { ++ pmd_t *pmdp = (pmd_t *)token_page_ptep; ++ pmd_t pmd = READ_ONCE(*pmdp); ++ pmd = __pmd(pmd_val(pmd) | ___D | __RW | __PP); ++ WRITE_ONCE(*pmdp, pmd); ++ for(int i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*token_ptep); ++ pte = __pte((pte_val(pte) & ~PTE_PFN_MASK & ~__PP) | (__phys_to_pfn(__iee_pa(token) + i * PAGE_SIZE) << PAGE_SHIFT)); ++ WRITE_ONCE(*token_ptep, pte); ++ token_ptep++; ++ } ++ } ++ else ++ { ++ for(int i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*token_ptep); ++ pte = __pte((pte_val(pte) & ~PTE_PFN_MASK & ~__PP) | (__phys_to_pfn(__iee_pa(token)) << PAGE_SHIFT)); ++ WRITE_ONCE(*token_ptep, pte); ++ pte = READ_ONCE(*token_page_ptep); ++ pte = __pte(pte_val(pte) | ___D | __RW | __PP); ++ WRITE_ONCE(*token_page_ptep, pte); ++ token_ptep++; ++ token_page_ptep++; ++ token += PAGE_SIZE; ++ } ++ } ++} ++ ++void __iee_code _iee_set_token(unsigned long __unused, pte_t *token_ptep, pte_t *token_page_ptep, void *token_page, unsigned long order, int use_block_pmd) ++{ ++ token_ptep = (pte_t *)(__phys_to_iee(__pa(token_ptep))); ++ token_page_ptep = (pte_t *)(__phys_to_iee(__pa(token_page_ptep))); ++ if (use_block_pmd) ++ { ++ pmd_t *pmdp = (pmd_t *)token_page_ptep; ++ pmd_t pmd = READ_ONCE(*pmdp); ++ pmd = __pmd((pmd_val(pmd) & ~__RW) & ~___D & ~__PP); ++ WRITE_ONCE(*pmdp, pmd); ++ for(int i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*token_ptep); ++ pte = __pte(((pte_val(pte) & ~PTE_PFN_MASK) | __PP) | (__phys_to_pfn(__pa(token_page) + i * PAGE_SIZE) << PAGE_SHIFT)); ++ WRITE_ONCE(*token_ptep, pte); ++ token_ptep++; ++ } ++ } ++ else { ++ for(int i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*token_ptep); ++ pte = __pte(((pte_val(pte) & ~PTE_PFN_MASK) | __PP) | (__phys_to_pfn(__pa(token_page)) << PAGE_SHIFT)); ++ WRITE_ONCE(*token_ptep, pte); ++ pte = READ_ONCE(*token_page_ptep); ++ pte = __pte((pte_val(pte) & ~__RW) & ~___D & ~__PP); ++ WRITE_ONCE(*token_page_ptep, pte); ++ token_ptep++; ++ token_page_ptep++; ++ token_page += PAGE_SIZE; ++ } ++ } ++} ++ ++unsigned long __iee_code _iee_test_and_clear_bit(unsigned long __unused, long nr, volatile unsigned long *addr) ++{ ++ unsigned long *iee_addr = (unsigned long*)__phys_to_iee(__pa(addr)); ++ kcsan_mb(); ++ instrument_atomic_read_write(iee_addr + BIT_WORD(nr), sizeof(long)); ++ return arch_test_and_clear_bit(nr, iee_addr); ++} ++ ++void __iee_code _iee_set_sensitive_pte(unsigned long __unused, pte_t *lm_ptep, int order, int use_block_pmd) ++{ ++ int i; ++ lm_ptep = (pte_t *)(__phys_to_iee(__pa(lm_ptep))); ++ if (use_block_pmd) { ++ pmd_t pmd = __pmd(pte_val(READ_ONCE(*lm_ptep))); ++ pmd = __pmd((pmd_val(pmd) & (~__RW) & (~___D))); ++ WRITE_ONCE(*lm_ptep, __pte(pmd_val(pmd))); ++ } ++ else ++ { ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*lm_ptep); ++ pte = __pte((pte_val(pte) & (~__RW) & (~___D))); ++ WRITE_ONCE(*lm_ptep, pte); ++ lm_ptep++; ++ } ++ } ++} ++ ++void __iee_code _iee_unset_sensitive_pte(unsigned long __unused, pte_t *lm_ptep, int order, int use_block_pmd) ++{ ++ int i; ++ lm_ptep = (pte_t *)(__phys_to_iee(__pa(lm_ptep))); ++ if (use_block_pmd) ++ { ++ pmd_t pmd = __pmd(pte_val(READ_ONCE(*lm_ptep))); ++ pmd = __pmd((pmd_val(pmd) | __RW | ___D)); ++ WRITE_ONCE(*lm_ptep, __pte(pmd_val(pmd))); ++ } ++ else ++ { ++ for(i = 0; i < (1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*lm_ptep); ++ pte = __pte(pte_val(pte) | __RW | ___D); ++ WRITE_ONCE(*lm_ptep, pte); ++ lm_ptep++; ++ } ++ } ++} ++ ++#ifdef CONFIG_CREDP ++static struct cred* iee_cred(unsigned long __unused, struct cred *cred) { ++ if(cred == &init_cred) ++ cred = (struct cred *)__phys_to_iee(__pa_symbol(cred)); ++ else ++ cred = (struct cred *)(__phys_to_iee(__pa(cred))); ++ return cred; ++} ++ ++void __iee_code _iee_set_cred_rcu(unsigned long __unused, struct cred *cred, struct rcu_head *rcu) ++{ ++ cred = iee_cred(__unused, cred); ++ *((struct rcu_head **)(&(cred->rcu.func))) = rcu; ++} ++ ++void __iee_code _iee_set_cred_security(unsigned long __unused, struct cred *cred, void *security) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->security = security; ++} ++ ++unsigned long __iee_code _iee_set_cred_atomic_op_usage(unsigned long __unused, struct cred *cred, int flag, int nr) ++{ ++ cred = iee_cred(__unused, cred); ++ switch (flag) ++ { ++ case AT_ADD: { ++ atomic_long_add(nr, &cred->usage); ++ return 0; ++ } ++ case AT_INC_NOT_ZERO: { ++ return atomic_long_inc_not_zero(&cred->usage); ++ } ++ case AT_SUB_AND_TEST: { ++ return atomic_long_sub_and_test(nr, &cred->usage); ++ } ++ } ++ return 0; ++} ++ ++void __iee_code _iee_set_cred_atomic_set_usage(unsigned long __unused, struct cred *cred, int i) ++{ ++ cred = iee_cred(__unused, cred); ++ atomic_long_set(&cred->usage,i); ++} ++ ++void __iee_code _iee_set_cred_non_rcu(unsigned long __unused, struct cred *cred, int non_rcu) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->non_rcu = non_rcu; ++} ++ ++void __iee_code _iee_set_cred_session_keyring(unsigned long __unused, struct cred *cred, struct key *session_keyring) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->session_keyring = session_keyring; ++} ++ ++void __iee_code _iee_set_cred_process_keyring(unsigned long __unused, struct cred *cred, struct key *process_keyring) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->process_keyring = process_keyring; ++} ++ ++void __iee_code _iee_set_cred_thread_keyring(unsigned long __unused, struct cred *cred, struct key *thread_keyring) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->thread_keyring = thread_keyring; ++} ++ ++void __iee_code _iee_set_cred_request_key_auth(unsigned long __unused, struct cred *cred, struct key *request_key_auth) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->request_key_auth = request_key_auth; ++} ++ ++void __iee_code _iee_set_cred_jit_keyring(unsigned long __unused, struct cred *cred, unsigned char jit_keyring) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->jit_keyring = jit_keyring; ++} ++ ++void __iee_code _iee_set_cred_cap_inheritable(unsigned long __unused, struct cred *cred, kernel_cap_t cap_inheritable) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->cap_inheritable = cap_inheritable; ++} ++ ++void __iee_code _iee_set_cred_cap_permitted(unsigned long __unused, struct cred *cred, kernel_cap_t cap_permitted) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->cap_permitted = cap_permitted; ++} ++ ++void __iee_code _iee_set_cred_cap_effective(unsigned long __unused, struct cred *cred, kernel_cap_t cap_effective) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->cap_effective = cap_effective; ++} ++ ++void __iee_code _iee_set_cred_cap_bset(unsigned long __unused, struct cred *cred, kernel_cap_t cap_bset) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->cap_bset = cap_bset; ++} ++ ++void __iee_code _iee_set_cred_cap_ambient(unsigned long __unused, struct cred *cred, kernel_cap_t cap_ambient) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->cap_ambient = cap_ambient; ++} ++ ++void __iee_code _iee_set_cred_securebits(unsigned long __unused, struct cred *cred, unsigned securebits) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->securebits = securebits; ++} ++ ++void __iee_code _iee_set_cred_group_info(unsigned long __unused, struct cred *cred, struct group_info *group_info) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->group_info = group_info; ++} ++ ++void __iee_code _iee_set_cred_ucounts(unsigned long __unused, struct cred *cred, struct ucounts *ucounts) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->ucounts = ucounts; ++} ++ ++void __iee_code _iee_set_cred_user_ns(unsigned long __unused, struct cred *cred, struct user_namespace *user_ns) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->user_ns = user_ns; ++} ++ ++void __iee_code _iee_set_cred_user(unsigned long __unused, struct cred *cred, struct user_struct *user) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->user = user; ++} ++ ++void __iee_code _iee_set_cred_fsgid(unsigned long __unused, struct cred *cred, kgid_t fsgid) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->fsgid = fsgid; ++} ++ ++void __iee_code _iee_set_cred_fsuid(unsigned long __unused, struct cred *cred, kuid_t fsuid) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->fsuid = fsuid; ++} ++ ++void __iee_code _iee_set_cred_egid(unsigned long __unused, struct cred *cred, kgid_t egid) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->egid = egid; ++} ++ ++void __iee_code _iee_set_cred_euid(unsigned long __unused, struct cred *cred, kuid_t euid) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->euid = euid; ++} ++ ++void __iee_code _iee_set_cred_sgid(unsigned long __unused, struct cred *cred, kgid_t sgid) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->sgid = sgid; ++} ++ ++void __iee_code _iee_set_cred_suid(unsigned long __unused, struct cred *cred, kuid_t suid) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->suid = suid; ++} ++ ++void __iee_code _iee_copy_cred(unsigned long __unused, struct cred *old, struct cred *new) ++{ ++ if (new == &init_cred) { ++ panic("copy_cred for init_cred: %lx\n", (unsigned long)new); ++ } ++ struct rcu_head *rcu = (struct rcu_head *)(new->rcu.func); ++ struct cred *_new = (struct cred *)__phys_to_iee(__pa(new)); ++ _iee_memcpy(__unused, new, old, sizeof(struct cred)); ++ *(struct rcu_head **)(&(_new->rcu.func)) = rcu; ++ *(struct rcu_head *)(_new->rcu.func) = *(struct rcu_head *)(old->rcu.func); ++} ++ ++void __iee_code _iee_set_cred_gid(unsigned long __unused, struct cred *cred, kgid_t gid) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->gid = gid; ++} ++ ++void __iee_code _iee_set_cred_uid(unsigned long __unused, struct cred *cred, kuid_t uid) ++{ ++ cred = iee_cred(__unused, cred); ++ cred->uid = uid; ++} ++#endif ++ ++#ifdef CONFIG_KEYP ++unsigned long __iee_code _iee_set_key_flag_bit(unsigned long __unused, struct key *key, ++ long nr, int flag) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ switch (flag) { ++ case SET_BIT_OP: { ++ set_bit(nr, &key->flags); ++ break; ++ } ++ case TEST_AND_CLEAR_BIT: { ++ return test_and_clear_bit(nr, &key->flags); ++ } ++ case TEST_AND_SET_BIT: { ++ return test_and_set_bit(nr, &key->flags); ++ } ++ } ++ return 0; ++} ++ ++void __iee_code _iee_set_key_restrict_link(unsigned long __unused, ++ struct key *key, ++ struct key_restriction *restrict_link) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->restrict_link = restrict_link; ++} ++ ++void __iee_code _iee_set_key_magic(unsigned long __unused, struct key *key, ++ unsigned magic) ++{ ++#ifdef KEY_DEBUGGING ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->magic = magic; ++#endif ++} ++ ++void __iee_code _iee_set_key_flags(unsigned long __unused, struct key *key, ++ unsigned long flags) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->flags = flags; ++} ++ ++void __iee_code _iee_set_key_index_key(unsigned long __unused, ++ struct key *key, ++ struct keyring_index_key* index_key) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->index_key = *index_key; ++} ++ ++void __iee_code _iee_set_key_hash(unsigned long __unused, struct key *key, ++ unsigned long hash) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->hash = hash; ++} ++ ++void __iee_code _iee_set_key_len_desc(unsigned long __unused, struct key *key, ++ unsigned long len_desc) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->len_desc = len_desc; ++} ++ ++void __iee_code _iee_set_key_type(unsigned long __unused, struct key *key, ++ struct key_type *type) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->type = type; ++} ++ ++void __iee_code _iee_set_key_domain_tag(unsigned long __unused, ++ struct key *key, ++ struct key_tag *domain_tag) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->domain_tag = domain_tag; ++} ++ ++void __iee_code _iee_set_key_description(unsigned long __unused, ++ struct key *key, char *description) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->description = description; ++} ++ ++void __iee_code _iee_set_key_uid(unsigned long __unused, struct key *key, ++ kuid_t uid) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->uid = uid; ++} ++ ++void __iee_code _iee_set_key_gid(unsigned long __unused, struct key *key, ++ kgid_t gid) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->gid = gid; ++} ++ ++void __iee_code _iee_set_key_perm(unsigned long __unused, struct key *key, ++ key_perm_t perm) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->perm = perm; ++} ++ ++void __iee_code _iee_set_key_quotalen(unsigned long __unused, struct key *key, ++ unsigned short quotalen) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->quotalen = quotalen; ++} ++ ++void __iee_code _iee_set_key_datalen(unsigned long __unused, struct key *key, ++ unsigned short datalen) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->datalen = datalen; ++} ++ ++void __iee_code _iee_set_key_state(unsigned long __unused, struct key *key, ++ short state) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ WRITE_ONCE(key->state, state); ++} ++ ++void __iee_code _iee_set_key_user(unsigned long __unused, struct key *key, ++ struct key_user *user) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->user = user; ++} ++ ++void __iee_code _iee_set_key_security(unsigned long __unused, struct key *key, ++ void *security) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->security = security; ++} ++ ++void __iee_code _iee_set_key_expiry(unsigned long __unused, struct key *key, ++ time64_t expiry) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->expiry = expiry; ++} ++ ++void __iee_code _iee_set_key_revoked_at(unsigned long __unused, ++ struct key *key, time64_t revoked_at) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->revoked_at = revoked_at; ++} ++ ++void __iee_code _iee_set_key_last_used_at(unsigned long __unused, ++ struct key *key, ++ time64_t last_used_at) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->last_used_at = last_used_at; ++} ++ ++unsigned long __iee_code _iee_set_key_usage(unsigned long __unused, struct key *key, ++ int n, int flag) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ switch (flag) { ++ case REFCOUNT_INC: { ++ refcount_inc(&key->usage); ++ break; ++ } ++ case REFCOUNT_SET: { ++ refcount_set(&key->usage, n); ++ break; ++ } ++ case REFCOUNT_DEC_AND_TEST: { ++ return refcount_dec_and_test(&key->usage); ++ } ++ case REFCOUNT_INC_NOT_ZERO: { ++ return refcount_inc_not_zero(&key->usage); ++ } ++ } ++ return 0; ++} ++ ++void __iee_code _iee_set_key_serial(unsigned long __unused, struct key *key, ++ key_serial_t serial) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->serial = serial; ++} ++ ++void __iee_code _iee_set_key_watchers(unsigned long __unused, struct key *key, struct watch_list *watchers) ++{ ++#ifdef CONFIG_KEY_NOTIFICATIONS ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->watchers = watchers; ++#endif ++} ++ ++void __iee_code _iee_set_key_union(unsigned long __unused, struct key *key, ++ struct key_union *key_union) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->graveyard_link.next = (struct list_head *)key_union; ++} ++ ++void __iee_code _iee_set_key_struct(unsigned long __unused, struct key *key, ++ struct key_struct *key_struct) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->name_link.prev = (struct list_head *)key_struct; ++} ++ ++void __iee_code _iee_set_key_payload(unsigned long __unused, struct key *key, ++ union key_payload *key_payload) ++{ ++ key = (struct key *)(__phys_to_iee(__pa(key))); ++ key->name_link.next = (struct list_head *)key_payload; ++} ++#endif ++ ++#ifdef CONFIG_IEE_SELINUX_P ++void __iee_code _iee_set_selinux_status_pg(unsigned long __unused, struct page* new_page) ++{ ++ struct page** iee_addr = (struct page**)__phys_to_iee(__pa_symbol(&(selinux_state.status_page))); ++ *iee_addr = new_page; ++} ++ ++void __iee_code _iee_set_selinux_enforcing(unsigned long __unused, bool value) ++{ ++ *(bool*)__phys_to_iee(__pa_symbol(&(selinux_state.enforcing))) = value; ++} ++ ++void __iee_code _iee_mark_selinux_initialized(unsigned long __unused) ++{ ++ smp_store_release(((bool*)__phys_to_iee(__pa_symbol(&(selinux_state.initialized)))), true); ++ printk("IEE: Mark selinux initialized."); ++} ++ ++void __iee_code _iee_set_sel_policy_cap(unsigned long __unused, unsigned int idx, int cap) ++{ ++ *(bool*)__phys_to_iee(__pa_symbol(&(selinux_state.policycap[idx]))) = cap; ++} ++ ++/* ++ * Please make sure param iee_new_policy is from policy_jar memcache. ++ * Need to free new_policy after calling this func as it's only used to ++ * trans data from kernel. ++ */ ++void __iee_code _iee_sel_rcu_assign_policy(unsigned long __unused, struct selinux_policy* new_policy, ++ struct selinux_policy* iee_new_policy) ++{ ++ /* TODO: Verify informations from incoming policy. */ ++ // /* Make sure iee_new_policy is from policy_jar memcache. */ ++ // struct slab* policy_pg = (struct slab*)pfn_to_page(__pa(iee_new_policy) >> PAGE_SHIFT); ++ // if (policy_pg->slab_cache != policy_jar) ++ // printk("IEE SELINUXP ERROR: new policy is not from iee memcache."); ++ /* Copy data from kernel to new allocated policy struct inside iee. */ ++ struct selinux_policy* iee_addr = (struct selinux_policy *)(__phys_to_iee(__pa(iee_new_policy))); ++ memcpy(iee_addr, new_policy, sizeof(struct selinux_policy)); ++ ++ rcu_assign_pointer(*((struct selinux_policy**)__phys_to_iee(__pa_symbol(&(selinux_state.policy)))), ++ iee_new_policy); ++ printk("IEE: assigned rcu pointer selinux_state.policy."); ++} ++#endif ++ ++/* iee si */ ++bool iee_pgt_jar_init __iee_si_data; ++bool iee_init_done __iee_si_data; ++unsigned long iee_base_swapper_pg_dir __iee_si_data; ++extern unsigned long iee_idt_table_addr; ++extern unsigned long iee_bringup_idt_table_addr; ++ ++extern const unsigned long cr4_pinned_mask; ++extern struct static_key_false cr_pinning; ++extern unsigned long cr4_pinned_bits; ++ ++u64 __iee_si_code notrace iee_si_handler(int flag, ...) ++{ ++ va_list pArgs; ++ u64 val; ++ ++ va_start(pArgs, flag); ++ switch (flag) { ++ case IEE_SI_TEST: ++ break; ++ case IEE_WRITE_CR0: { ++ val = va_arg(pArgs, u64); ++ unsigned long bits_missing = 0; ++ set_register_cr0: ++ asm volatile("mov %0,%%cr0" : "+r"(val) : : "memory"); ++ if (static_branch_likely(&cr_pinning)) { ++ if (unlikely((val & X86_CR0_WP) != X86_CR0_WP)) { ++ bits_missing = X86_CR0_WP; ++ val |= bits_missing; ++ goto set_register_cr0; ++ } ++ /* Warn after we've set the missing bits. */ ++ WARN_ONCE(bits_missing, "CR0 WP bit went missing!?\n"); ++ } ++ break; ++ } ++ #ifdef CONFIG_KOI ++ case IEE_SWITCH_TO_KOI: ++ #endif ++ case IEE_WRITE_CR3: { ++ val = va_arg(pArgs, u64); ++ asm volatile("mov %0,%%cr3" : : "r"(val) : "memory"); ++ break; ++ } ++ #ifdef CONFIG_KOI ++ case IEE_SWITCH_TO_KERNEL: { ++ val = iee_base_swapper_pg_dir; ++ asm volatile("mov %0,%%cr3" : : "r"(val) : "memory"); ++ break; ++ } ++ #endif ++ case IEE_WRITE_CR4: { ++ val = va_arg(pArgs, u64); ++ val &= ~(X86_CR4_SMEP | X86_CR4_SMAP); ++ unsigned long bits_changed = 0; ++ set_register_cr4: ++ asm volatile("mov %0,%%cr4": "+r" (val) : : "memory"); ++ if (static_branch_likely(&cr_pinning)) { ++ if (unlikely((val & cr4_pinned_mask) != cr4_pinned_bits)) { ++ bits_changed = (val & cr4_pinned_mask) ^ cr4_pinned_bits; ++ val = (val & ~cr4_pinned_mask) | cr4_pinned_bits; ++ goto set_register_cr4; ++ } ++ /* Warn after we've corrected the changed bits. */ ++ WARN_ONCE(bits_changed, "pinned CR4 bits changed: 0x%lx!?\n", ++ bits_changed); ++ } ++ break; ++ } ++ case IEE_LOAD_IDT: { ++ const struct desc_ptr *new_val = va_arg(pArgs, const struct desc_ptr*); ++ unsigned long new_addr = new_val->address; ++ ++ if(new_addr == CPU_ENTRY_AREA_RO_IDT || (new_addr == 0 && new_val->size == 0) ++ || new_addr == iee_idt_table_addr || new_addr == iee_bringup_idt_table_addr) { ++ asm volatile("lidt %0"::"m" (*new_val)); ++ } else { ++ /* IEE note: load_idt in __restore_processor_state() is not triggered in qemu, ++ * but still hooked ++ */ ++ panic("error idt table address: 0x%lx\n", new_addr); ++ } ++ break; ++ } ++ } ++ va_end(pArgs); ++ return 0; ++} +\ No newline at end of file +diff --git a/arch/x86/kernel/iee/pgtable-slab.c b/arch/x86/kernel/iee/pgtable-slab.c +new file mode 100644 +index 000000000000..e64ed15f9598 +--- /dev/null ++++ b/arch/x86/kernel/iee/pgtable-slab.c +@@ -0,0 +1,169 @@ ++#include ++#include ++#include ++#include ++#include ++ ++#define PGTABLE_INIT_ORDER 7 ++struct kmem_cache *pgtable_jar; ++struct kmem_cache *ptdesc_jar; ++struct kmem_cache *pgd_jar; ++unsigned long pgtable_jar_offset; ++unsigned long pgd_jar_offset; ++ ++extern void early_pgtable_jar_alloc(struct kmem_cache *pgtable_jar); ++ ++static inline void iee_ptdesc_init(struct page *page) ++{ ++ struct ptdesc_t *tmp = kmem_cache_alloc(ptdesc_jar, GFP_KERNEL | __GFP_ZERO); ++ if (!tmp) { ++ panic("IEE: failed to alloc ptdesc_jar"); ++ } ++ spin_lock_init(&tmp->ptl); ++ page_to_iee_ptdesc(page) = tmp; ++ ++ page_to_iee_ptdesc(page)->page = page; ++} ++ ++static inline void iee_ptdesc_free(struct page *page) ++{ ++ kmem_cache_free(ptdesc_jar, page_to_iee_ptdesc(page)); ++ page_to_iee_ptdesc(page) = NULL; ++} ++ ++void __init iee_pmd_pgtable_init(pud_t *pud) { ++ struct page *page; ++ pmd_t *orig_pmd = pud_pgtable(*pud); ++ pmd_t *pmd; ++ int i; ++ ++ for (i = 0; i < PTRS_PER_PMD; i++) { ++ pmd = orig_pmd + i; ++ if (pmd_none(*pmd) || pmd_bad(*pmd)) ++ continue; ++ page = pmd_page(*pmd); ++ iee_ptdesc_init(page); ++ } ++} ++ ++void __init iee_pud_pgtable_init(p4d_t *p4d) { ++ struct page *page; ++ pud_t *orig_pud = p4d_pgtable(*p4d); ++ pud_t *pud; ++ int i; ++ ++ for (i = 0; i < PTRS_PER_PUD; i++) { ++ pud = orig_pud + i; ++ if (pud_none(*pud) || pud_bad(*pud)) ++ continue; ++ iee_pmd_pgtable_init(pud); ++ page = pud_page(*pud); ++ iee_ptdesc_init(page); ++ } ++} ++ ++void __init iee_p4d_pgtable_init(pgd_t *pgd) { ++ struct page *page; ++ p4d_t *orig_p4d = (p4d_t *)pgd_page_vaddr(*pgd); ++ p4d_t *p4d; ++ int i; ++ ++ for (i = 0; i < PTRS_PER_P4D; i++) { ++ p4d = orig_p4d + i; ++ if (p4d_none(*p4d) || p4d_bad(*p4d)) ++ continue; ++ iee_pud_pgtable_init(p4d); ++ page = p4d_page(*p4d); ++ iee_ptdesc_init(page); ++ } ++} ++ ++void __init iee_pgtable_init(void) ++{ ++ int i; ++ pgd_t *pgd; ++ struct page* page; ++ ++ pr_err("IEE: iee_ptdesc_base=%lx, vmemmap_base=%lx", iee_ptdesc_base, vmemmap_base); ++ ++ ptdesc_jar = kmem_cache_create("ptdesc_jar", sizeof(struct ptdesc_t), 0, SLAB_PANIC|SLAB_RED_ZONE, NULL); ++ pgtable_jar = kmem_cache_create("pgtable_jar", PAGE_SIZE, PAGE_SIZE, ++ SLAB_PANIC, NULL); ++ pgd_jar = kmem_cache_create("pgd_jar", (PAGE_SIZE << PGD_ALLOCATION_ORDER), ++ (PAGE_SIZE << PGD_ALLOCATION_ORDER), SLAB_PANIC, NULL); ++ ++ for(i = 0; i < ((1 << (PGTABLE_INIT_ORDER))/nr_cpu_ids); i++) { ++ early_pgtable_jar_alloc(pgtable_jar); ++ // early_pgtable_jar_alloc(pgd_jar); ++ } ++ for (i = 0; i < PTRS_PER_PGD; i++) { ++ pgd = swapper_pg_dir + i; ++ if (pgtable_l5_enabled()) { ++ if (pgd_none_or_clear_bad(pgd)) ++ continue; ++ iee_p4d_pgtable_init(pgd); ++ } ++ else { ++ if (p4d_none_or_clear_bad((p4d_t *)pgd)) ++ continue; ++ iee_pud_pgtable_init((p4d_t *)pgd); ++ } ++ page = pgd_page(*pgd); ++ iee_ptdesc_init(page); ++ } ++ iee_pgt_jar_init = true; ++} ++ ++void *get_iee_pgtable_page(gfp_t gfpflags) ++{ ++ struct page *page; ++ void *res = kmem_cache_alloc(pgtable_jar, gfpflags); ++ if(!res) { ++ panic("IEE: failed to alloc pgtable_jar"); ++ } ++ iee_rw_gate(IEE_OP_SET_FREEPTR, (void **)((unsigned long)res + pgtable_jar_offset), NULL); ++ ++ page = virt_to_page(res); ++ iee_ptdesc_init(page); ++ return res; ++} ++ ++void free_iee_pgtable_page(void *obj) ++{ ++ struct page *page = virt_to_page(obj); ++ iee_ptdesc_free(page); ++ ++ kmem_cache_free(pgtable_jar, obj); ++} ++ ++void *get_iee_pgd_page(gfp_t gfpflags) ++{ ++ struct page *page; ++ void *res = kmem_cache_alloc(pgd_jar, gfpflags); ++ if(!res) { ++ panic("IEE: failed to alloc pgd_jar"); ++ } ++ iee_rw_gate(IEE_OP_SET_FREEPTR, (void **)((unsigned long)res + pgd_jar_offset), NULL); ++ ++ page = virt_to_page(res); ++ iee_ptdesc_init(page); ++ ++ #if PGD_ALLOCATION_ORDER == 1 ++ page = virt_to_page((unsigned long)res + PAGE_SIZE); ++ iee_ptdesc_init(page); ++ #endif ++ return res; ++} ++ ++void free_iee_pgd_page(void *obj) ++{ ++ struct page *page = virt_to_page(obj); ++ iee_ptdesc_free(page); ++ ++ #if PGD_ALLOCATION_ORDER == 1 ++ page = virt_to_page((unsigned long)obj + PAGE_SIZE); ++ iee_ptdesc_free(page); ++ #endif ++ ++ kmem_cache_free(pgd_jar, obj); ++} +\ No newline at end of file +diff --git a/arch/x86/kernel/iee/stack-slab.c b/arch/x86/kernel/iee/stack-slab.c +new file mode 100644 +index 000000000000..491f3f1a3be7 +--- /dev/null ++++ b/arch/x86/kernel/iee/stack-slab.c +@@ -0,0 +1,20 @@ ++#include ++#include ++ ++struct kmem_cache *iee_stack_jar; ++ ++void __init iee_stack_init(void) ++{ ++ iee_stack_jar = kmem_cache_create("iee_stack_jar", (PAGE_SIZE << 2), ++ (PAGE_SIZE << 2), SLAB_PANIC, NULL); ++} ++ ++void *get_iee_stack(void) ++{ ++ return __phys_to_iee(__pa(kmem_cache_alloc(iee_stack_jar, GFP_KERNEL))); ++} ++ ++void free_iee_stack(void *obj) ++{ ++ kmem_cache_free(iee_stack_jar, __va(__iee_pa(obj))); ++} +\ No newline at end of file +diff --git a/arch/x86/kernel/koi/Makefile b/arch/x86/kernel/koi/Makefile +new file mode 100644 +index 000000000000..9be8710b714a +--- /dev/null ++++ b/arch/x86/kernel/koi/Makefile +@@ -0,0 +1 @@ ++obj-y += koi.o +\ No newline at end of file +diff --git a/arch/x86/kernel/koi/koi.c b/arch/x86/kernel/koi/koi.c +new file mode 100644 +index 000000000000..77500a7de3ef +--- /dev/null ++++ b/arch/x86/kernel/koi/koi.c +@@ -0,0 +1,1414 @@ ++#include "asm-generic/rwonce.h" ++#include "asm/current.h" ++#include "asm/desc_defs.h" ++#include "asm/page.h" ++#include "asm/page_64_types.h" ++#include "asm/page_types.h" ++#include "asm/percpu.h" ++#include "asm/pgtable.h" ++#include "asm/pgalloc.h" ++#include "asm/pgtable_64.h" ++#include "asm/pgtable_64_types.h" ++#include "asm/pgtable_types.h" ++#include "asm/processor-flags.h" ++#include "asm/special_insns.h" ++#include "linux/cpumask.h" ++#include "linux/export.h" ++#include "linux/mm_types.h" ++#include "linux/percpu-defs.h" ++#include "linux/pgtable.h" ++#include "linux/mm.h" ++#include "asm/pgalloc.h" ++#include "linux/printk.h" ++#include "linux/slab.h" ++#include "asm/koi.h" ++#include "linux/module.h" ++#include "linux/spinlock.h" ++#include "linux/vmalloc.h" ++#include "asm-generic/sections.h" ++#include "asm/desc.h" ++#ifdef CONFIG_IEE ++#include "asm/iee-si.h" ++#endif ++ ++// #define DEBUG ++ ++#ifdef DEBUG ++#define debug_printk(...) printk(KERN_ERR __VA_ARGS__) ++#else ++#define debug_printk(...) ++#endif ++ ++#define __koi_code __section(".koi.text") ++#define __koi_data __section(".data..koi") ++ ++extern unsigned long __koi_code_start[]; ++extern unsigned long __koi_code_end[]; ++extern unsigned long __koi_data_start[]; ++extern unsigned long __koi_data_end[]; ++#ifdef CONFIG_IEE ++extern unsigned long __iee_si_data_start[]; ++extern unsigned long __iee_si_text_start[]; ++extern unsigned long iee_offset; ++#endif ++ ++// extern unsigned long koi_idt_descr_addr; ++extern struct desc_ptr idt_descr; ++extern gate_desc idt_table[IDT_ENTRIES]; ++ ++#define IDT_TABLE_SIZE (IDT_ENTRIES * sizeof(gate_desc)) ++ ++extern void init_ko_mm(struct mm_struct *ko_mm, pgd_t *pgdp); ++ ++extern void error_entry(void); ++ ++extern void error_return(void); ++ ++DEFINE_PER_CPU_PAGE_ALIGNED(unsigned long, koi_kern_cr3); ++EXPORT_SYMBOL(koi_kern_cr3); ++ ++DEFINE_HASHTABLE(koi_mem_htbl, HASH_TABLE_BIT); ++ ++DEFINE_SPINLOCK(koi_mem_htbl_spin_lock); ++EXPORT_SYMBOL(koi_mem_htbl_spin_lock); ++ ++#ifndef CONFIG_IEE ++__koi_code void koi_error_entry_to_kernel(void) { ++ unsigned long cr3 = this_cpu_read(koi_kern_cr3); ++ asm volatile("mov %0,%%cr3": : "r" (cr3) : "memory"); ++} ++ ++__koi_code void koi_error_return_to_ko(unsigned long addr) { ++ struct koi_mem_hash_node *ko; ++ unsigned long cr3; ++ int bkt; ++ unsigned long flags; ++ struct task_token *token_addr = ++ (struct task_token *)((unsigned long)current + (unsigned long)KOI_OFFSET); ++ rcu_read_lock(); ++ hash_for_each_rcu (koi_mem_htbl, bkt, ko, node) { ++ spin_lock_irqsave(&ko->mod_lock, flags); ++ if (!ko->is_valid) { ++ spin_unlock_irqrestore(&ko->mod_lock, flags); ++ goto out; ++ } ++ if (ko->mod != NULL && ko->mod->mem[MOD_INIT_TEXT].base != NULL) { ++ if (addr >= (unsigned long)ko->mod->mem[MOD_INIT_TEXT].base && ++ addr < (unsigned long)ko->mod->mem[MOD_INIT_TEXT].base + ko->mod->mem[MOD_INIT_TEXT].size) { ++ spin_unlock_irqrestore(&ko->mod_lock, flags); ++ if (token_addr->current_ttbr1 == ko->ko_cr3) { ++ cr3 = __read_cr3(); ++ this_cpu_write(koi_kern_cr3, cr3); ++ cr3 = (cr3 & X86_CR3_PCID_MASK) | PTI_USER_PCID_MASK; ++ cr3 |= ko->ko_cr3; ++ rcu_read_unlock(); ++ native_write_cr3(cr3); ++ return; ++ } ++ goto out; ++ } ++ } ++ if (addr >= (unsigned long)ko->mod->mem[MOD_TEXT].base && ++ addr < (unsigned long)ko->mod->mem[MOD_TEXT].base + ko->mod->mem[MOD_TEXT].size) { ++ spin_unlock_irqrestore(&ko->mod_lock, flags); ++ if (token_addr->current_ttbr1 == ko->ko_cr3) { ++ cr3 = __read_cr3(); ++ this_cpu_write(koi_kern_cr3, cr3); ++ cr3 = (cr3 & X86_CR3_PCID_MASK) | PTI_USER_PCID_MASK; ++ cr3 |= ko->ko_cr3; ++ rcu_read_unlock(); ++ native_write_cr3(cr3); ++ return; ++ } ++ goto out; ++ } ++ spin_unlock_irqrestore(&ko->mod_lock, flags); ++ } ++out: ++ rcu_read_unlock(); ++ return; ++} ++#else ++__koi_code void koi_error_entry_to_kernel(void) { ++ unsigned long cr3 = this_cpu_read(koi_kern_cr3); ++ asm volatile("mov %0,%%cr3": : "r" (cr3) : "memory"); ++} ++ ++__koi_code void koi_error_return_to_ko(unsigned long addr) { ++ struct koi_mem_hash_node *ko; ++ unsigned long cr3; ++ int bkt; ++ unsigned long flags; ++ rcu_read_lock(); ++ hash_for_each_rcu (koi_mem_htbl, bkt, ko, node) { ++ spin_lock_irqsave(&ko->mod_lock, flags); ++ if (!ko->is_valid) { ++ spin_unlock_irqrestore(&ko->mod_lock, flags); ++ goto out; ++ } ++ if (ko->mod != NULL && ko->mod->mem[MOD_INIT_TEXT].base != NULL) { ++ if (addr >= (unsigned long)ko->mod->mem[MOD_INIT_TEXT].base && ++ addr < (unsigned long)ko->mod->mem[MOD_INIT_TEXT].base + ko->mod->mem[MOD_INIT_TEXT].size) { ++ spin_unlock_irqrestore(&ko->mod_lock, flags); ++ unsigned long current_ttbr1 = iee_rw_gate(IEE_READ_TOKEN_TTBR1, current); ++ if (current_ttbr1 == ko->ko_cr3) { ++ cr3 = __read_cr3(); ++ this_cpu_write(koi_kern_cr3, cr3); ++ cr3 = (cr3 & X86_CR3_PCID_MASK) | PTI_USER_PCID_MASK; ++ cr3 |= ko->ko_cr3; ++ rcu_read_unlock(); ++ native_write_cr3(cr3); ++ return; ++ } ++ goto out; ++ } ++ } ++ if (addr >= (unsigned long)ko->mod->mem[MOD_TEXT].base && ++ addr < (unsigned long)ko->mod->mem[MOD_TEXT].base + ko->mod->mem[MOD_TEXT].size) { ++ spin_unlock_irqrestore(&ko->mod_lock, flags); ++ unsigned long current_ttbr1 = iee_rw_gate(IEE_READ_TOKEN_TTBR1, current); ++ if (current_ttbr1 == ko->ko_cr3) { ++ cr3 = __read_cr3(); ++ this_cpu_write(koi_kern_cr3, cr3); ++ cr3 = (cr3 & X86_CR3_PCID_MASK) | PTI_USER_PCID_MASK; ++ cr3 |= ko->ko_cr3; ++ rcu_read_unlock(); ++ native_write_cr3(cr3); ++ return; ++ } ++ goto out; ++ } ++ spin_unlock_irqrestore(&ko->mod_lock, flags); ++ } ++out: ++ rcu_read_unlock(); ++ return; ++} ++#endif ++ ++pte_t *find_pte(unsigned long addr, pgd_t *pgdir) ++{ ++ p4d_t *p4dp; ++ pud_t *pudp; ++ pmd_t *pmdp; ++ pte_t *ptep; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, addr); ++ if (pgd_none(*pgdp) || pgd_bad(*pgdp)) { ++ debug_printk("pgdp 0x%lx not available\n", (unsigned long) pgdp); ++ return NULL; ++ } ++ debug_printk( "pgd=0x%lx, pgd_val=0x%lx\n", (unsigned long) pgdp, pgd_val(*pgdp)); ++ ++ p4dp = p4d_offset(pgdp, addr); ++ if (p4d_none(*p4dp) || p4d_bad(*p4dp)) { ++ debug_printk("p4dp 0x%lx not available\n", (unsigned long)p4dp); ++ return NULL; ++ } ++ debug_printk( "p4d=0x%lx, p4d_val=0x%lx\n", (unsigned long) p4dp, p4d_val(*p4dp)); ++ ++ pudp = pud_offset(p4dp, addr); ++ if (pud_none(*pudp) || pud_bad(*pudp)) { ++ debug_printk("pudp 0x%lx not available\n", (unsigned long)pudp); ++ return NULL; ++ } ++ debug_printk( "pud=0x%lx, pud_val=0x%lx\n", (unsigned long)pudp, pud_val(*pudp)); ++ pmdp = pmd_offset(pudp, addr); ++ debug_printk( "pmd=0x%lx, pmd_val=0x%lx\n",(unsigned long) pmdp, pmd_val(*pmdp)); ++ if (is_swap_pmd(*pmdp) || pmd_trans_huge(*pmdp) || ++ (pmd_devmap(*pmdp))) { ++ return (pte_t *)pmdp; ++ } ++ if (pmd_none(*pmdp)) { ++ debug_printk("pmdp 0x%lx not available none\n", (unsigned long)pmdp); ++ return NULL; ++ } ++ if (pmd_bad(*pmdp)) { ++ debug_printk("pmdp 0x%lx bad, pmd_val=0x%16lx\n",(unsigned long) pmdp, pmd_val(*pmdp)); ++ return NULL; ++ } ++ ++ ptep = pte_offset_kernel(pmdp, addr); ++ debug_printk( "pte=0x%lx, pte_val=0x%lx\n", (unsigned long)ptep, pte_val(*ptep)); ++ if (pte_none(*ptep)) { ++ debug_printk("ptep 0x%lx not available\n", (unsigned long)ptep); ++ return NULL; ++ } ++ return ptep; ++} ++ ++struct page *find_page(unsigned long addr, pgd_t *pgdir) ++{ ++ struct page *curr_page; ++ pte_t *ptep; ++ debug_printk("addr=0x%lx\n", addr); ++ // pgd_t *pgdir = swapper_pg_dir; ++ ptep = find_pte(addr, pgdir); ++ if (!ptep) { ++ return NULL; ++ } ++ curr_page = pte_page(*ptep); ++ debug_printk("page=0x%16lx\n", (unsigned long) curr_page); ++ return curr_page; ++} ++ ++__attribute__((unused)) static void check_pgd(pgd_t *new_pgd, pgd_t *old_pgd, ++ unsigned long addr) ++{ ++ pte_t *old_pte = find_pte(addr, old_pgd); ++ pte_t *new_pte = find_pte(addr, new_pgd); ++ if (old_pte == NULL || new_pte == NULL) { ++ debug_printk( "old_pte=0x%16lx, new_pte=0x%16lx\n", (unsigned long)old_pte, (unsigned long)new_pte); ++ return; ++ } ++ unsigned long old_pfn = pte_pfn(*old_pte); ++ unsigned long new_pfn = pte_pfn(*new_pte); ++ struct page *old_page, *new_page; ++ unsigned long *new_address, *old_address; ++ if (old_pfn != new_pfn) { ++ debug_printk( ++ "pfn different! old_pfn=0x%16lx, new_pfn=0x%16lx\n", ++ old_pfn, new_pfn); ++ } ++ old_page = find_page(addr, old_pgd); ++ debug_printk("swapper_pg_dir walk finished\n"); ++ new_page = find_page(addr, new_pgd); ++ debug_printk("new pgd walk finished\n"); ++ ++ if (new_page != old_page) ++ debug_printk("Wrong page walk\n"); ++ if (new_page == NULL) { ++ debug_printk("new page not available\n"); ++ } ++ if (old_page == NULL) { ++ debug_printk("old page not available\n"); ++ } ++ if (old_page == NULL || new_page == NULL) ++ return; ++ new_address = (unsigned long *)page_address(new_page); ++ old_address = (unsigned long *)page_address(old_page); ++ ++ debug_printk("addr=0x%lx, new=0x%lx, old=0x%lx\n", addr, (unsigned long)new_address, ++ (unsigned long)old_address); ++ if (new_address != old_address) { ++ debug_printk("Different page address!\n"); ++ } else { ++ debug_printk("check pgd pass successfully!\n"); ++ } ++} ++ ++// int __koi_pte_alloc(struct mm_struct *mm, pmd_t *pmd) ++// { ++// spinlock_t *ptl; ++// // pgtable_t new = alloc_page(GFP_PGTABLE_KERNEL); ++// pte_t *new = pte_alloc_one_kernel(mm); ++// // debug_printk("alloc new=0x%16lx\n", (unsigned long)new); ++// if (!new) ++// return -ENOMEM; ++ ++// /* ++// * Ensure all pte setup (eg. pte page lock and page clearing) are ++// * visible before the pte is made visible to other CPUs by being ++// * put into page tables. ++// * ++// * The other side of the story is the pointer chasing in the page ++// * table walking code (when walking the page table without locking; ++// * ie. most of the time). Fortunately, these data accesses consist ++// * of a chain of data-dependent loads, meaning most CPUs (alpha ++// * being the notable exception) will already guarantee loads are ++// * seen in-order. See the alpha page table accessors for the ++// * smp_rmb() barriers in page table walking code. ++// */ ++// smp_wmb(); /* Could be smp_wmb__xxx(before|after)_spin_lock */ ++ ++// ptl = pmd_lockptr(mm, pmd); ++// debug_printk("pte_alloc ptl=0x%16lx\n", (unsigned long)ptl); ++// spin_lock(ptl); ++// if (likely(pmd_none(*pmd))) { /* Has another populated it ? */ ++// mm_inc_nr_ptes(mm); ++// pmd_populate_kernel(mm, pmd, new); ++// new = NULL; ++// } ++// spin_unlock(ptl); ++// debug_printk("unlock pte_alloc ptl=0x%16lx\n", (unsigned long)ptl); ++// if (new) { ++// pte_free_kernel(mm, new); ++// } ++// return 0; ++// } ++/* ++#define koi_pte_alloc(mm, pmd) \ ++ (unlikely(pmd_none(*(pmd))) && __koi_pte_alloc(mm, pmd)) ++ ++#define koi_pte_offset_map_lock(mm, pmd, address, ptlp) \ ++ ({ \ ++ spinlock_t *__ptl = pte_lockptr(mm, pmd); \ ++ pte_t *__pte = pte_offset_kernel(pmd, address); \ ++ *(ptlp) = __ptl; \ ++ debug_printk("pre lock ptlp=0x%16lx\n", (unsigned long)__ptl); \ ++ __pte; \ ++ }) ++ ++#define koi_pte_alloc_map_lock(mm, pmd, address, ptlp) \ ++ (koi_pte_alloc(mm, pmd) ? \ ++ NULL : \ ++ koi_pte_offset_map_lock(mm, pmd, address, ptlp)) ++*/ ++// static inline pud_t *koi_pud_alloc(struct mm_struct *mm, p4d_t *p4d, unsigned long address) { ++// return (unlikely(p4d_none(*p4d)) && __koi_pud_alloc(mm, p4d, address)) ? ++// NULL : pud_offset(p4d, address); ++// } ++ ++// static inline pmd_t *koi_pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) ++// { ++// return (unlikely(pud_none(*pud)) && __koi_pmd_alloc(mm, pud, address))? ++// NULL: pmd_offset(pud, address); ++// } ++ ++/** ++ * Copy one pte. Returns 0 if succeeded, or -EAGAIN if one preallocated page ++ * is required to copy this pte. ++*/ ++static inline int koi_copy_present_pte(struct mm_struct *ko_mm, pte_t *dst_pte, ++ pte_t *src_pte, unsigned long addr) ++{ ++ pte_t pte = *src_pte; ++ ++ set_pte(dst_pte, pte); ++ return 0; ++} ++ ++/** ++*koi_copy_pte_range - copy pte from kernel space to driver space ++*/ ++static int koi_copy_pte_range(struct mm_struct *ko_mm, pmd_t *dst_pmd, ++ pmd_t *src_pmd, unsigned long addr, ++ unsigned long end, pteval_t prot) ++{ ++ pte_t *src_pte, *dst_pte; ++ pte_t *orig_src_pte, *orig_dst_pte; ++ spinlock_t *dst_ptl; ++ int ret = 0; ++ ++ dst_pte = pte_alloc_map_lock(ko_mm, dst_pmd, addr, &dst_ptl); ++ if (!dst_pte) { ++ ret = -ENOMEM; ++ goto unlock; ++ } ++ debug_printk("lock dst_ptl=0x%16lx\n", (unsigned long)dst_ptl); ++ src_pte = pte_offset_kernel(src_pmd, addr); ++ if (!src_pte) { ++ pte_unmap_unlock(dst_pte, dst_ptl); ++ debug_printk("unlock dst_ptl=0x%16lx\n", (unsigned long)dst_ptl); ++ goto unlock; ++ } ++ // spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING); ++ orig_src_pte = src_pte; ++ orig_dst_pte = dst_pte; ++ ++ do { ++ if (pte_none(*src_pte)) ++ continue; ++ if (unlikely(!pte_present(*src_pte))) { ++ debug_printk( ++ "not present pte found: addr=0x%16lx, end=0x%16lx, pte_val=0x%16lx\n", ++ addr, end, pte_val(*src_pte)); ++ continue; ++ } ++ if (pte_valid(*dst_pte)) { ++ continue; ++ } ++ /* koi_copy_present_pte() will clear `*prealloc` if consumed */ ++ ret = koi_copy_present_pte(ko_mm, dst_pte, src_pte, addr); ++ debug_printk( ++ "dst_pte=0x%16lx, dst_pte_val=0x%16lx, src_pte=0x%16lx, src_pte_val=0x%16lx, addr=0x%16lx\n", ++ (unsigned long)dst_pte, pte_val(*dst_pte), (unsigned long)src_pte, pte_val(*src_pte), ++ addr); ++ debug_printk( "pte=0x%16lx, pte_val=0x%16lx\n", (unsigned long)dst_pte, (unsigned long)pte_val(*dst_pte)); ++ } while (dst_pte++, src_pte++, addr += PAGE_SIZE, addr != end); ++ pte_unmap_unlock(orig_dst_pte, dst_ptl); ++ debug_printk("unlock dst_ptl=0x%16lx\n", (unsigned long)dst_ptl); ++ ++unlock: ++ // spin_unlock_irq(dst_ptl); ++ debug_printk( "unlock1 dst_ptl=0x%16lx\n", (unsigned long)dst_ptl); ++ return ret; ++} ++ ++/** ++* copy huge pmd from kernel space to driver space. ++*/ ++static int koi_copy_huge_pmd(struct mm_struct *ko_mm, pmd_t *dst_pmd, ++ pmd_t *src_pmd, unsigned long addr, pteval_t prot) ++{ ++ spinlock_t *dst_ptl; ++ int ret = -ENOMEM; ++ debug_printk( ++ "hugepmd: src_pmd=0x%16lx, dst_pmd=0x%16lx, src_pmd_val=0x%16lx, dst_pmd_val=0x%16lx, addr=0x%16lx\n", ++ (unsigned long)src_pmd, (unsigned long)dst_pmd, pmd_val(*src_pmd), pmd_val(*dst_pmd), addr); ++ dst_ptl = pmd_lockptr(ko_mm, dst_pmd); ++ debug_printk("pmd lock dst_ptl=0x%16lx\n", (unsigned long)dst_ptl); ++ spin_lock(dst_ptl); ++ ++ set_pmd(dst_pmd, __pmd(pmd_val(*src_pmd) | prot)); ++ ret = 0; ++ spin_unlock(dst_ptl); ++ debug_printk("pmd unlock dst_ptl=0x%16lx\n", (unsigned long)dst_ptl); ++ debug_printk( ++ "hugepmd: src_pmd=0x%16lx, dst_pmd=0x%16lx, src_pmd_val=0x%16lx, dst_pmd_val=0x%16lx, addr=0x%16lx\n", ++ (unsigned long)src_pmd, (unsigned long)dst_pmd, pmd_val(*src_pmd), pmd_val(*dst_pmd), addr); ++ return ret; ++} ++ ++/** ++*kio_copy_pmd_range - copy pmd from kernel to driver space ++*/ ++static inline int koi_copy_pmd_range(struct mm_struct *ko_mm, pud_t *dst_pud, ++ pud_t *src_pud, unsigned long addr, ++ unsigned long end, pteval_t prot) ++{ ++ pmd_t *src_pmd, *dst_pmd; ++ unsigned long next, flag; ++ int err; ++ debug_printk( ++ "koi_copy_pmd_range src_pud=0x%16lx, dst_pud=0x%16lx, addr=0x%16lx, end=0x%16lx\n", ++ (unsigned long)src_pud, (unsigned long)dst_pud, addr, end); ++ dst_pmd = pmd_alloc(ko_mm, dst_pud, addr); ++ if (!dst_pmd) { ++ return -ENOMEM; ++ } ++ src_pmd = pmd_offset(src_pud, addr); ++ do { ++ next = pmd_addr_end(addr, end); ++ flag = pmd_val(*src_pmd) & PTE_FLAGS_MASK; ++ // debug_printk("src_pmd=0x%16lx, dst_pmd=0x%16lx, addr=0x%16lx\n", src_pmd, dst_pmd, next); ++ // CONFIG_TRANSPARENT_HUGEPAGE is enabled, so we must add copy_huge_pmd ++ if (!pmd_present(*src_pmd)) ++ continue; ++ if (pmd_leaf(*src_pmd)) { ++ // if src_pmd is huge page ++ debug_printk( ++ "koi_copy_pmd_range src_pmd=0x%16lx, dst_pmd=0x%16lx, addr=0x%16lx\n", ++ (unsigned long)src_pmd, (unsigned long)dst_pmd, addr); ++ err = koi_copy_huge_pmd(ko_mm, dst_pmd, src_pmd, addr, prot); ++ if (err == -ENOMEM) ++ return -ENOMEM; ++ continue; ++ } ++ if (koi_copy_pte_range(ko_mm, dst_pmd, src_pmd, addr, next, prot)) ++ return -ENOMEM; ++ set_pmd(dst_pmd, __pmd((pmd_val(*dst_pmd) & (~PTE_FLAGS_MASK)) | flag)); ++ debug_printk( ++ "koi_copy_pmd_range src_pmd_val=0x%16lx, dst_pmd_val=0x%16lx, addr=0x%16lx\n", ++ pmd_val(*src_pmd), pmd_val(*dst_pmd), addr); ++ debug_printk("pmd=0x%16lx, pmd_val=0x%16lx\n", (unsigned long)dst_pmd, (unsigned long)pmd_val(*dst_pmd)); ++ } while (dst_pmd++, src_pmd++, addr = next, addr != end); ++ return 0; ++} ++ ++ ++static int koi_copy_huge_pud(struct mm_struct *ko_mm, pud_t *dst_pud, ++ pud_t *src_pud, unsigned long addr) ++{ ++ spinlock_t *dst_ptl; ++ // pmd_t pmd; ++ int ret = -ENOMEM; ++ debug_printk("huge src_pud=0x%16lx, dst_pud=0x%16lx, addr=0x%16lx\n", ++ (unsigned long)src_pud, (unsigned long)dst_pud, addr); ++ dst_ptl = pud_lockptr(ko_mm, dst_pud); ++ ++ debug_printk("pud lock dst_ptl=0x%16lx\n", (unsigned long)dst_ptl); ++ spin_lock(dst_ptl); ++ set_pte((pte_t *)dst_pud, __pte(pud_val(*src_pud))); ++ spin_unlock(dst_ptl); ++ debug_printk("pud unlock dst_ptl=0x%16lx\n", (unsigned long)dst_ptl); ++ ret = 0; ++ return ret; ++} ++ ++/** ++*koi_copy_pud_range - copy pud from kernel to driver ++*/ ++static inline int koi_copy_pud_range(struct mm_struct *ko_mm, p4d_t *dst_p4d, ++ p4d_t *src_p4d, unsigned long addr, ++ unsigned long end, pteval_t prot) ++{ ++ pud_t *src_pud, *dst_pud; ++ unsigned long next, flag; ++ dst_pud = pud_alloc(ko_mm, dst_p4d, addr); ++ if (!dst_pud) ++ return -ENOMEM; ++ src_pud = pud_offset(src_p4d, addr); ++ do { ++ next = pud_addr_end(addr, end); ++ flag = pud_val(*src_pud) & PTE_FLAGS_MASK; ++ debug_printk( ++ "koi_copy_pud_range src_pud=0x%16lx, dst_pud=0x%16lx, addr=0x%16lx, next=0x%16lx\n", ++ (unsigned long)src_pud, (unsigned long)dst_pud, addr, next); ++ if (!pud_present(*src_pud)) { ++ continue; ++ } ++ if (pud_leaf(*src_pud)) { ++ // indicates that the src_pud maps to a huge page ++ koi_copy_huge_pud(ko_mm, dst_pud, src_pud, addr); ++ continue; ++ } ++ // if (pud_trans_huge(*src_pud) || pud_devmap(*src_pud)) { ++ // debug_printk("pud_trans_huge=%d, pud_devmap=%d, src_pud=0x%16lx\n", pud_trans_huge(*src_pud) , pud_devmap(*src_pud), src_pud); ++ // continue; ++ // /* fall through */ ++ // } ++ if (koi_copy_pmd_range(ko_mm, dst_pud, src_pud, addr, next, prot)) ++ return -ENOMEM; ++ debug_printk("koi_copy_pud_range dst_p4d=0x%16lx, dst_p4d_val=0x%16lx, pud=0x%16lx, pud_val=0x%16lx, addr=0x%16lx, next=0x%16lx\n", (unsigned long)dst_p4d, (unsigned long)p4d_val(*dst_p4d), (unsigned long)dst_pud,(unsigned long) pud_val(*dst_pud), addr, next); ++ set_pud(dst_pud, __pud((pud_val(*dst_pud) & (~PTE_FLAGS_MASK)) | flag)); ++ debug_printk("koi_copy_pud_range pud=0x%16lx, pud_val=0x%16lx\n", (unsigned long)dst_pud,(unsigned long) pud_val(*dst_pud)); ++ } while (dst_pud++, src_pud++, addr = next, addr != end); ++ return 0; ++} ++ ++/** ++* koi_copy_p4d_range - map the kernel pagetable to the driver space level by level ++* @ko_mm: the mm_struct of driver module ++* @dst_pgd: destination pgd ++* @src_pgd: source pgd ++* @addr: the start of address ++* @end: the end of address ++*/ ++static inline int koi_copy_p4d_range(struct mm_struct *ko_mm, pgd_t *dst_pgd, ++ pgd_t *src_pgd, unsigned long addr, ++ unsigned long end, pteval_t prot) ++{ ++ p4d_t *src_p4d, *dst_p4d; ++ unsigned long next; ++ dst_p4d = p4d_alloc(ko_mm, dst_pgd, addr); ++ if (!dst_p4d) ++ return -ENOMEM; ++ src_p4d = p4d_offset(src_pgd, addr); ++ do { ++ next = p4d_addr_end(addr, end); ++ if (p4d_none(*src_p4d) || p4d_bad(*src_p4d)) ++ continue; ++ unsigned long flag = p4d_val(*src_p4d) & PTE_FLAGS_MASK; ++ debug_printk( ++ "koi_copy_p4d_range dst_p4d=0x%16lx, dst_p4d_val=0x%16lx, src_p4d=0x%16lx, src_p4d_val=0x%16lx, addr=0x%16lx\n", ++ (unsigned long)dst_p4d, p4d_val(*dst_p4d), (unsigned long)src_p4d, p4d_val(*src_p4d), addr); ++ if (koi_copy_pud_range(ko_mm, dst_p4d, src_p4d, addr, next, prot)) { ++ return -ENOMEM; ++ } ++ set_p4d(dst_p4d, __p4d((p4d_val(*dst_p4d) & (~PTE_FLAGS_MASK)) | flag)); ++ debug_printk( "p4d=0x%16lx, p4d_val=0x%16lx\n", (unsigned long)dst_p4d, (unsigned long)p4d_val(*dst_p4d)); ++ } while (dst_p4d++, src_p4d++, addr = next, addr != end); ++ return 0; ++} ++ ++/** ++*int koi_copy_pagetable - map the address range from "addr" to "end" to the driver pagetable ++*@ko_mm: the mm_struct of the driver module ++*@koi_pg_dir: koi_pg_dir, related to the driver module, the entry for driver pagetable ++*@addr: the starting address of mapping zone ++*@end: the end address of mapping zone ++*/ ++int koi_copy_pagetable(struct mm_struct *ko_mm, pgd_t *koi_pg_dir, ++ unsigned long addr, unsigned long end, pteval_t prot) ++{ ++ int ret = 0; ++ unsigned long next; ++ ++ pgd_t *src_pgd, *dst_pgd; ++ unsigned long flag; ++ if (addr == 0 || end <= addr || (addr & (PAGE_SIZE - 1)) != 0) { ++ printk(KERN_INFO "Wrong Arguments! addr=0x%16lx, end=0x%16lx, %ld\n", addr, end, addr & (PAGE_SIZE - 1)); ++ return 0; ++ } ++ src_pgd = pgd_offset_pgd(swapper_pg_dir, addr); ++ dst_pgd = pgd_offset_pgd(koi_pg_dir, addr); ++ do { ++ flag = pgd_val(*src_pgd) & PTE_FLAGS_MASK; ++ next = pgd_addr_end(addr, end); ++ if (pgd_none(*src_pgd) || pgd_bad(*src_pgd)) ++ continue; ++ debug_printk("koi_copy_pagetable pgd=0x%16lx, pgd_val=0x%16lx, addr=0x%16lx, next=0x%16lx\n", (unsigned long)dst_pgd, (unsigned long)pgd_val(*dst_pgd), addr, next); ++ if (unlikely(koi_copy_p4d_range(ko_mm, dst_pgd, src_pgd, addr, ++ next, prot))) { ++ ret = -ENOMEM; ++ break; ++ } ++ set_pgd(dst_pgd, __pgd((pgd_val(*dst_pgd) & (~PTE_FLAGS_MASK)) | flag)); ++ debug_printk("koi_copy_pagetable set pgd=0x%16lx, pgd_val=0x%16lx, addr=0x%16lx, next=0x%16lx\n", (unsigned long)dst_pgd, (unsigned long)pgd_val(*dst_pgd), addr, next); ++ } while (dst_pgd++, src_pgd++, addr = next, addr != end); ++ return ret; ++} ++ ++void koi_create_pagetable(struct module *mod) ++{ ++ int ret = 0; ++ int cpu; ++ int i; ++ unsigned long addr; ++ struct desc_ptr desc; ++ struct koi_mem_hash_node *new_node = kzalloc(sizeof(struct koi_mem_hash_node), GFP_KERNEL); ++ if (!new_node) { ++ debug_printk( "[NO MEM] KOI ALLOC new node failed\n"); ++ return; ++ } ++ // if (koi_kern_cr3 == 0) { ++ // // CONFIG_ADDRESS_MASKING is not set in opoeneuler_defconfig, so we don't take lam into consideration. ++ // koi_kern_cr3 = __sme_pa(swapper_pg_dir) | CR3_NOFLUSH; ++ // } ++ new_node->pgdp = koi_pgd_alloc(); ++ new_node->ko_mm = kzalloc(sizeof(struct mm_struct) + sizeof(unsigned long) * BITS_TO_LONGS(NR_CPUS),GFP_KERNEL); ++ new_node->mod = mod; ++ init_ko_mm(new_node->ko_mm, new_node->pgdp); ++ new_node->ko_cr3 = __sme_pa(new_node->pgdp) /*| CR3_NOFLUSH */; ++ printk(KERN_ERR "ko_cr3=0x%16lx, pgdp=0x%16lx\n", new_node->ko_cr3, (unsigned long)new_node->pgdp); ++ // map module layout into module pagetable. ++ for_each_mod_mem_type(type) { ++ printk(KERN_ERR "\033[33mcopying mem range, start=0x%16lx, end=0x%16lx\033[0m\n", ++ (unsigned long)mod->mem[type].base, ++ (unsigned long)mod->mem[type].base + mod->mem[type].size); ++ if (!mod->mem[type].base || !mod->mem[type].size) { ++ continue; ++ } ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, (unsigned long)mod->mem[type].base, (unsigned long)mod->mem[type].base + mod->mem[type].size, 0); ++ if (ret != 0) ++ printk(KERN_ERR ++ "\033[33mError occured when copying range from 0x%lx to 0x%lx, Eno:%d\033[0m\n", ++ (unsigned long)mod->mem[type].base, ++ (unsigned long)mod->mem[type].base + mod->mem[type].size, ++ ret); ++ } ++ ++ for_each_possible_cpu(cpu) { ++ addr = (unsigned long)per_cpu_ptr(&koi_kern_cr3, cpu); ++ ++ debug_printk( "cpu=%d, addr=0x%16lx, this_cpu_off=0x%16lx, this_cpu_off_addr=0x%16lx\n", cpu, addr, this_cpu_read(this_cpu_off), (unsigned long)per_cpu_ptr(&this_cpu_off, cpu)); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, addr, addr + PAGE_SIZE, 0); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, (unsigned long)per_cpu_ptr(&this_cpu_off, cpu) & PAGE_MASK, ((unsigned long)per_cpu_ptr(&this_cpu_off, cpu) & PAGE_MASK) + PAGE_SIZE, 0); ++ } ++ printk(KERN_ERR "mapping koi_data\n"); ++ // map koi_data into module pagetable. ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, ++ (unsigned long)__koi_data_start, ++ (unsigned long)__koi_data_end, 0); ++ printk(KERN_ERR "mapping koi_text\n"); ++ // map koi_text into module pagetable. ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, (unsigned long)__koi_code_start, (unsigned long)__koi_code_end, 0); ++ ++ // map exception entry into module pagetable. ++ printk(KERN_ERR "idt_desct=0x%16lx, size =0x%16lx, end=0x%16lx\n", (unsigned long)&idt_descr & PAGE_MASK, sizeof(idt_descr), ((unsigned long)&idt_descr + sizeof(idt_descr) + PAGE_SIZE) & PAGE_MASK); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, (unsigned long)&idt_descr & PAGE_MASK, ((unsigned long)&idt_descr + sizeof(idt_descr) + PAGE_SIZE) & PAGE_MASK, 0); ++ printk(KERN_ERR "idt_base=0x%16lx, end=0x%16lx, size=0x%16lx\n", idt_descr.address, (unsigned long)idt_descr.address + IDT_TABLE_SIZE, IDT_TABLE_SIZE - 1); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, idt_descr.address, (unsigned long)idt_descr.address + IDT_TABLE_SIZE, 0); ++ printk(KERN_ERR "__entry_text_start=0x%16lx, __entry_text_end=0x%16lx, error_entry=0x%16lx\n", (unsigned long)__entry_text_start & PAGE_MASK, (unsigned long)(__entry_text_end + PAGE_SIZE) & PAGE_MASK, (unsigned long)error_entry); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, (unsigned long)__entry_text_start & PAGE_MASK, (unsigned long)(__entry_text_end + PAGE_SIZE) & PAGE_MASK, 0); ++ // struct desc_ptr dtr; ++ // asm volatile("sidt %0":"=m" (dtr)); ++ // printk(KERN_ERR "dtr.size=%d, address=0x%16lx\n", dtr.size, dtr.address); ++ for (i = 0; i < IDT_ENTRIES; i++) { ++ gate_desc desc = idt_table[i]; ++ addr = desc.offset_low | ((unsigned long)desc.offset_middle << 16) | ((unsigned long)desc.offset_high << 32); ++ printk(KERN_ERR "idt handler addr=0x%16lx, segment=%x, ist=%d, zero=%d, type=%d, dpl=%d, p=%d\n", ++ addr, desc.segment, desc.bits.ist, desc.bits.zero, desc.bits.type, desc.bits.dpl, desc.bits.p); ++ if (addr > (unsigned long)__entry_text_start && addr < (unsigned long)__entry_text_end) ++ continue; ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, addr & PAGE_MASK, (addr + PAGE_SIZE) & PAGE_MASK, 0); ++ } ++ ++ // mapping gdt into module pagetable. ++ for_each_possible_cpu(cpu) { ++ native_store_gdt(&desc); ++ printk(KERN_ERR "address=0x%16lx, size=%d\n", desc.address, desc.size); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, desc.address, desc.address + PAGE_SIZE, 0); ++ ++ addr = (long)get_cpu_gdt_rw(cpu); // this address is logical address. ++ printk(KERN_ERR "gdt rw=0x%16lx, addr=0x%16lx\n", (unsigned long)per_cpu_ptr(gdt_page.gdt, cpu), addr); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, addr, addr + PAGE_SIZE, 0); ++ ++ addr = (long)get_cpu_gdt_ro(cpu); // this address is same to base stored in GDTR. ++ printk(KERN_ERR "gdtp=0x%16lx, addr=0x%16lx\n", (unsigned long)per_cpu_ptr(gdt_page.gdt, cpu), addr); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, addr, addr + PAGE_SIZE, 0); ++ // struct desc_struct desc = per_cpu(gdt_page.gdt[GDT_ENTRY_KERNEL_CS], cpu); ++ // debug_printk("base0=0x%x, base1=0x%x, base2=0x%x, type=0x%x, s=%d, dpl=%d, p=%d, avl=%d, l=%d, d=%d, g=%d\n", ++ // desc.base0, desc.base1, desc.base2, desc.type, desc.s, desc.dpl, desc.p, desc.avl, desc.l, desc.d, desc.g); ++ } ++ ++ // map irq stack into module pagetable. ++ for_each_possible_cpu(cpu) { ++ // unsigned long top_of_stack = per_cpu(pcpu_hot.top_of_stack, cpu); ++ unsigned long hard_irq_stack = (unsigned long)per_cpu(pcpu_hot.hardirq_stack_ptr, cpu) + 8 - IRQ_STACK_SIZE; ++ debug_printk("top_of_stack=0x%16lx, hard_irq_stack=0x%16lx, current_stack=0x%16lx\n", top_of_stack, hard_irq_stack, (unsigned long)current->stack); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, hard_irq_stack, hard_irq_stack + IRQ_STACK_SIZE, 0); ++ } ++ ++ for_each_possible_cpu(cpu) { ++ // map TSS pointed by TSS descriptor in GDT ++ // We can use segment selector in tr to get the descriptor, and the corresponding base address and limit stored in the GDT entry. ++ addr = (unsigned long) &get_cpu_entry_area(cpu)->tss.x86_tss; ++ debug_printk( "addr=0x%16lx\n",(unsigned long) &get_cpu_entry_area(cpu)->tss.x86_tss); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, addr, (addr + sizeof(struct tss_struct) + PAGE_SIZE) & PAGE_MASK, 0); ++ // map ist stack ++ struct tss_struct *tss = (struct tss_struct *)addr; ++ // printk(KERN_ERR "tss=0x%16lx, tss->ist=0x%16lx, DF=0x%16lx, NMI=0x%16lx, DB=0x%16lx, MCE=0x%16lx\n", ++ // (unsigned long)tss, (unsigned long)tss->x86_tss.ist, (unsigned long)tss->x86_tss.ist[IST_INDEX_DF], (unsigned long)tss->x86_tss.ist[IST_INDEX_NMI], (unsigned long)tss->x86_tss.ist[IST_INDEX_DB],(unsigned long) tss->x86_tss.ist[IST_INDEX_MCE] ++ // ); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, (unsigned long)tss->x86_tss.ist[IST_INDEX_DF], (unsigned long)tss->x86_tss.ist[IST_INDEX_DF] + PAGE_SIZE, 0); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, (unsigned long)tss->x86_tss.ist[IST_INDEX_NMI], (unsigned long)tss->x86_tss.ist[IST_INDEX_NMI] + PAGE_SIZE, 0); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, (unsigned long)tss->x86_tss.ist[IST_INDEX_DB], (unsigned long)tss->x86_tss.ist[IST_INDEX_DB] + PAGE_SIZE, 0); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, (unsigned long)tss->x86_tss.ist[IST_INDEX_MCE], (unsigned long)tss->x86_tss.ist[IST_INDEX_MCE] + PAGE_SIZE, 0); ++ koi_copy_pagetable(new_node->ko_mm, new_node->pgdp, (unsigned long)tss->x86_tss.ist[IST_INDEX_VC], (unsigned long)tss->x86_tss.ist[IST_INDEX_VC] + PAGE_SIZE, 0); ++ } ++ spin_lock_init(&new_node->mod_lock); ++ new_node->is_valid = true; ++ ++ spin_lock(&koi_mem_htbl_spin_lock); ++ hash_add_rcu(koi_mem_htbl, &new_node->node, (unsigned long)new_node->mod); ++ spin_unlock(&koi_mem_htbl_spin_lock); ++ printk(KERN_ERR "create pagetable finished\n"); ++ unsigned long gs = 0; ++ asm volatile( ++ "mov %%gs, %0" ++ : "=r"(gs) ++ : ++ ); ++ printk(KERN_ERR "gs=0x%16lx\n", gs); ++} ++ ++void koi_map_mem(struct module *mod, unsigned long addr, unsigned long size) ++{ ++ struct koi_mem_hash_node *target = NULL; ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) ++ break; ++ } ++ rcu_read_unlock(); ++ ++ if (target == NULL) { ++ printk(KERN_ERR "mem node for module: %s not found\n", ++ mod->name); ++ return; ++ } ++ debug_printk("mapping addr=0x%16lx, end=0x%16lx\n", addr & PAGE_MASK, (addr + size + PAGE_SIZE) & PAGE_MASK); ++ koi_copy_pagetable(target->ko_mm, target->pgdp, addr & PAGE_MASK, ++ (addr + size + PAGE_SIZE) & PAGE_MASK, 0); ++ // flush_tlb_one_kernel(addr & PAGE_MASK); ++} ++EXPORT_SYMBOL(koi_map_mem); ++ ++void koi_unmap_pte_table(struct mm_struct *ko_mm, pmd_t *pmd, ++ unsigned long addr, unsigned long end) ++{ ++ pte_t *pte; ++ if (!pmd) ++ return; ++ debug_printk("pmd=0x%16lx, addr=0x%16lx, end=0x%16lx\n", (unsigned long)pmd, addr, end); ++ ++ // struct page *page = pte_page(*pte); ++ // printk(KERN_ERR "pte=0x%16llx, pte_val=0x%16llx\n", pte, pte_val(*pte)); ++ // debug_printk("free pte table 0x%16llx, pmd=0x%16llx, page=0x%16llx, pmd points to page=0x%16llx\n", pte, pmd, page, pte_page(pmd_pte(*pmd))); ++ // printk(KERN_ERR "pmd_pfn=0x%16llx, pte_pfn=0x%16llx\n", pmd_pfn(*pmd), pte_pfn(*pte)); ++ // pte_free(ko_mm, pte_page(pmd_pte(*pmd))); ++ do { ++ pte = pte_offset_kernel(pmd, addr); ++ debug_printk("pte=0x%16lx, pte_val=0x%16lx\n", (unsigned long)pte, pte_val(*pte)); ++ set_pte(pte, __pte(0)); ++ } while (addr += PAGE_SIZE, addr != end); ++} ++ ++void koi_unmap_pmd_range(struct mm_struct *ko_mm, pud_t *pud, ++ unsigned long addr, unsigned long end) ++{ ++ pmd_t *pmd, *orig_pmd; ++ unsigned long next; ++ if (!pud) ++ return; ++ orig_pmd = pmd_offset(pud, addr); ++ pmd = orig_pmd; ++ debug_printk("pud=0x%16lx, addr=0x%16lx, end=0x%16lx\n", (unsigned long) pud, addr, end); ++ // printk(KERN_ERR "pud_pfn=0x%16llx, pmd_pfn=0x%16llx\n", pud_pfn(*pud), pmd_pfn(*pmd)); ++ do { ++ debug_printk( "pmd=0x%16lx, pmd_val=0x%16lx\n", (unsigned long)pmd, pmd_val(*pmd)); ++ next = pmd_addr_end(addr, end); ++ if (pmd_none(*pmd)) ++ continue; ++ if (pmd_bad(*pmd)) { ++ set_pmd(pmd, __pmd(0)); ++ continue; ++ } ++ koi_unmap_pte_table(ko_mm, pmd, addr, next); ++ } while (pmd++, addr = next, addr != end); ++} ++ ++void koi_unmap_pud_range(struct mm_struct *ko_mm, p4d_t *p4d, ++ unsigned long addr, unsigned long end) ++{ ++ pud_t *pud, *orig_pud; ++ unsigned long next; ++ if (!p4d) ++ return; ++ orig_pud = pud_offset(p4d, addr); ++ pud = orig_pud; ++ debug_printk("p4d=0x%16lx, addr=0x%16lx, end=0x%16lx\n", (unsigned long)p4d, addr, end); ++ do { ++ debug_printk( "pud=0x%16llx, pud_val=0x%16llx\n", pud, pud_val(*pud)); ++ next = pud_addr_end(addr, end); ++ if (pud_none(*pud)) ++ continue; ++ if (pud_bad(*pud)) { ++ set_pud(pud, __pud(0)); ++ continue; ++ } ++ koi_unmap_pmd_range(ko_mm, pud, addr, next); ++ } while (pud++, addr = next, addr != end); ++ debug_printk("free pud 0x%16lx, p4d=0x%16lx, orig_pud=0x%16lx\n", (unsigned long) pud, (unsigned long) p4d, (unsigned long) orig_pud); ++} ++ ++void koi_unmap_p4d_range(struct mm_struct *ko_mm, pgd_t *pgd, ++ unsigned long addr, unsigned long end) ++{ ++ p4d_t *p4d, *orig_p4d; ++ unsigned long next; ++ if (!pgd) ++ return; ++ debug_printk("pgd=0x%16lx, addr=0x%16lx, end=0x%16lx\n", (unsigned long)pgd, addr, end); ++ orig_p4d = p4d_offset(pgd, addr); ++ p4d = orig_p4d; ++ do { ++ next = p4d_addr_end(addr, end); ++ debug_printk( "p4d=0x%16lx, p4d_val=0x%16lx, p4d_none=%d\n", (unsigned long)p4d, p4d_val(*p4d), p4d_none(*p4d)); ++ if (p4d_none_or_clear_bad(p4d)) { ++ continue; ++ } ++ koi_unmap_pud_range(ko_mm, p4d, addr, next); ++ } while (p4d++, addr = next, addr != end); ++} ++ ++void koi_unmap_pagetable(struct mm_struct *ko_mm, pgd_t *ko_pg_dir, ++ unsigned long addr, unsigned long end) ++{ ++ unsigned long next; ++ pgd_t *pgd = pgd_offset_pgd(ko_pg_dir, addr); ++ debug_printk("freepagetable addr=0x%16lx, end=0x%16lx\n", addr, end); ++ do { ++ next = pgd_addr_end(addr, end); ++ debug_printk( "pgd=0x%16llx, pgd_val=0x%16llx\n", pgd, pgd_val(*pgd)); ++ if (pgd_none_or_clear_bad(pgd)) { ++ continue; ++ } ++ koi_unmap_p4d_range(ko_mm, pgd, addr, next); ++ } while (pgd++, addr = next, addr != end); ++} ++ ++void koi_unmap_mem(struct module *mod, unsigned long addr, unsigned long size) ++{ ++ debug_printk( "koi_unmap_mem addr=0x%16lx, size=0x%16lx\n", addr, size); ++ struct koi_mem_hash_node *target = NULL; ++ if (!addr || ! size) { ++ return; ++ } ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) ++ break; ++ } ++ rcu_read_unlock(); ++ ++ if (target == NULL) { ++ printk(KERN_ERR "[KOI UNMAP] mem node for module: %s not found\n", ++ mod->name); ++ return; ++ } ++ koi_unmap_pagetable(target->ko_mm, target->pgdp, addr & PAGE_MASK, ++ (addr + size + PAGE_SIZE) & PAGE_MASK); ++ flush_tlb_kernel_range(addr & PAGE_MASK, ++ (addr + size + PAGE_SIZE) & PAGE_MASK); ++} ++EXPORT_SYMBOL(koi_unmap_mem); ++ ++void koi_remove_pte_range(struct mm_struct *ko_mm, pgd_t *ko_pg_dir, pmd_t *pmd) ++{ ++ pte_t *pte = (pte_t *)pmd_page_vaddr(*pmd); ++ debug_printk( ++ "pte=0x%16lx, page=0x%16lx, pmd=0x%16lx, pmd_val=0x%16lx\n", ++ (unsigned long)pte, (unsigned long)pmd_page(*pmd), (unsigned long)pmd, (unsigned long)pmd_val(*pmd)); ++ debug_printk( "free orig_pte=0x%16lx\n", (unsigned long)pte); ++ pte_free_kernel(ko_mm, pte); ++} ++ ++void koi_remove_pmd_range(struct mm_struct *ko_mm, pgd_t *ko_pg_dir, pud_t *pud) ++{ ++ pmd_t *orig_pmd = pud_pgtable(*pud); ++ pmd_t *pmd; ++ int i; ++ for (i = 0; i < PTRS_PER_PMD; i++) { ++ pmd = orig_pmd + i; ++ if (!pmd_present(*pmd) || pmd_bad(*pmd)) ++ continue; ++ debug_printk("pmd=0x%16lx, pmd_val=0x%16lx\n", (unsigned long)pmd, pmd_val(*pmd)); ++ koi_remove_pte_range(ko_mm, ko_pg_dir, pmd); ++ } ++ debug_printk( "free pmd=0x%16lx, page=0x%16lx\n",(unsigned long) orig_pmd, (unsigned long) pud_page(*pud)); ++ ++ pmd_free(ko_mm, orig_pmd); ++} ++ ++void koi_remove_pud_range(struct mm_struct *ko_mm, pgd_t *ko_pg_dir, p4d_t *p4d) ++{ ++ pud_t *orig_pud = p4d_pgtable(*p4d); ++ pud_t *pud; ++ int i; ++ for (i = 0; i < PTRS_PER_PUD; i++) { ++ pud = orig_pud + i; ++ debug_printk( "p4d=0x%16lx, pud=0x%16lx, orig_pud=0x%16lx\n", (unsigned long)p4d, (unsigned long)pud, (unsigned long)orig_pud); ++ if (!pud_present(*pud) || pud_bad(*pud)) ++ continue; ++ debug_printk("pud=0x%16lx, pud_val=0x%16lx\n", (unsigned long)pud, pud_val(*pud)); ++ koi_remove_pmd_range(ko_mm, ko_pg_dir, pud); ++ } ++ debug_printk( "free pud=0x%16lx, page=0x%16lx\n", (unsigned long)orig_pud, (unsigned long) p4d_pgtable(*p4d)); ++ // free pud page dir ++ pud_free(ko_mm, orig_pud); ++} ++ ++void koi_remove_p4d_range(struct mm_struct *ko_mm, pgd_t *ko_pg_dir, pgd_t *pgd) ++{ ++ p4d_t *orig_p4d = __va(pgd_val(*pgd) & PTE_PFN_MASK); ++ p4d_t *p4d; ++ int i; ++ for (i = 0; i < PTRS_PER_PGD; i++) { ++ p4d = orig_p4d + i; ++ if (!p4d_present(*p4d) || p4d_bad(*p4d)) ++ continue; ++ debug_printk( "p4d=0x%16lx, p4d_val=0x%16lx\n", (unsigned long)p4d, (unsigned long)p4d_val(*p4d)); ++ koi_remove_pud_range(ko_mm, ko_pg_dir, p4d); ++ } ++ debug_printk( "free orig_p4d=0x%16lx\n", (unsigned long) orig_p4d); ++ ++ // free p4d page dir. ++ p4d_free(ko_mm, orig_p4d); ++} ++ ++void koi_remove_pagetable(struct mm_struct *ko_mm, pgd_t *ko_pg_dir) ++{ ++ pgd_t *pgd; ++ int i; ++ for (i = 0; i < PTRS_PER_PGD; i++) { ++ pgd = ko_pg_dir + i; ++ if (pgd_none(*pgd) || pgd_bad(*pgd)) ++ continue; ++ debug_printk("pgd=0x%16lx, pgd_val=0x%16lx\n", (unsigned long)pgd, pgd_val(*pgd)); ++ koi_remove_p4d_range(ko_mm, ko_pg_dir, pgd); ++ } ++ debug_printk( "free pgd=0x%16lx\n", (unsigned long) ko_pg_dir); ++ // free pgd page dir ++ free_pages((unsigned long)ko_pg_dir, 0); ++} ++ ++void koi_destroy_pagetable(struct module *mod) ++{ ++ // int cpu; ++ // unsigned long *ptr; ++ struct koi_mem_hash_node *target = NULL; ++ unsigned long flags; ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) { ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ if (target == NULL) { ++ printk(KERN_ERR "mem node for module: %s not found, maybe destroyed before?\n", ++ mod->name); ++ return; ++ } ++ spin_lock_irqsave(&target->mod_lock, flags); ++ target->is_valid = false; ++ spin_unlock_irqrestore(&target->mod_lock, flags);; ++ ++ koi_remove_pagetable(target->ko_mm, target->ko_mm->pgd); ++ kfree(target->ko_mm); ++} ++ ++/** ++* koi_cr3_ctor - return ttbr1 for the given driver module ++*/ ++unsigned long koi_cr3_ctor(struct module *mod) ++{ ++ struct koi_mem_hash_node *ko; ++ struct mm_struct *ko_mm; ++ unsigned long cr3; ++ ++ int bkt; ++ rcu_read_lock(); ++ hash_for_each_rcu (koi_mem_htbl, bkt, ko, node) { ++ if (ko->mod == mod) { ++ ko_mm = ko->ko_mm; ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ if (!ko || !ko_mm) { ++ panic("cannot found module %s in koi_mem_htbl, mod=0x%16lx", ++ mod->name, (unsigned long)mod); ++ return 0; ++ } ++ asm volatile("mov %%cr3,%0\n\t" : "=r" (cr3) : __FORCE_ORDER); ++ this_cpu_write(koi_kern_cr3, cr3); ++ cr3 = (cr3 & X86_CR3_PCID_MASK) | PTI_USER_PCID_MASK | ko->ko_cr3; ++ ++ return cr3; ++} ++EXPORT_SYMBOL(koi_cr3_ctor); ++ ++int koi_share_kstack(struct module *mod) ++{ ++ unsigned long kstack_start, cur_sp; ++ struct koi_mem_hash_node *target = NULL; ++ asm volatile( ++ "mov %%rsp, %0\n" ++ : "=r"(cur_sp) ++ : ++ ); ++ kstack_start = (unsigned long)current->stack; ++ debug_printk("cur_sp=0x%16lx, kstack_start=0x%16lx\n", cur_sp, kstack_start); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) { ++ break; ++ } ++ } ++ ++ return koi_copy_pagetable(target->ko_mm, target->pgdp, kstack_start, ++ kstack_start + THREAD_SIZE, 0); ++} ++EXPORT_SYMBOL(koi_share_kstack); ++ ++// map the driver stack to kernel ++void koi_map_kostack(struct module *mod) ++{ ++} ++EXPORT_SYMBOL(koi_map_kostack); ++ ++__koi_code void koi_set_upage(struct module *mod, unsigned long addr, unsigned long size) { ++ struct koi_mem_hash_node *target = NULL; ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) { ++ break; ++ } ++ } ++ ++ koi_copy_pagetable(target->ko_mm, target->pgdp, addr & PAGE_MASK, ++ (addr + size + PAGE_SIZE) & PAGE_MASK, _PAGE_USER); ++} ++EXPORT_SYMBOL(koi_set_upage); ++ ++//kzalloc function in driver space ++__koi_code void *koi_kzalloc_wrapper(struct module *mod, size_t size, gfp_t flags) ++{ ++ int cnt = (size + PAGE_SIZE - 1) / PAGE_SIZE; ++ void *addr; ++ struct koi_mem_hash_node *target = NULL; ++ koi_switch_to_kernel(); ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) { ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ if (target == NULL) { ++ panic("mem node for module: %s not found\n", mod->name); ++ } ++ printk(KERN_ERR "kzalloc wrapper\n"); ++ addr = kzalloc(cnt * PAGE_SIZE, flags); ++ printk(KERN_ERR "kzalloc mapping addr=0x%16lx, end=0x%16lx\n", (unsigned long)addr, (unsigned long)addr + PAGE_SIZE * cnt); ++ koi_copy_pagetable(target->ko_mm, target->pgdp, (unsigned long)addr, ++ (unsigned long)addr + PAGE_SIZE * cnt, 0); ++ printk(KERN_ERR "kzalloc wrapper return\n"); ++ ++ __koi_switch_to_ko(mod); ++ return addr; ++} ++EXPORT_SYMBOL(koi_kzalloc_wrapper); ++ ++__koi_code void *koi_kzalloc_node_wrapper(struct module *mod, size_t size, gfp_t flags, int node) { ++ int cnt = (size + PAGE_SIZE - 1) / PAGE_SIZE; ++ void *addr = NULL; ++ struct koi_mem_hash_node *target = NULL; ++ koi_switch_to_kernel(); ++ ++ rcu_read_lock(); ++ hash_for_each_possible_rcu(koi_mem_htbl, target, node, (unsigned long)mod) { ++ if (target->mod == mod) ++ break; ++ } ++ rcu_read_unlock(); ++ if (target == NULL) { ++ panic(KERN_ERR "mem node for module: %s not found\n", mod->name); ++ } ++ addr = kzalloc_node(cnt * PAGE_SIZE, flags, node); ++ koi_copy_pagetable(target->ko_mm, target->pgdp, (unsigned long)addr, ++ (unsigned long)addr + PAGE_SIZE * cnt, 0); ++ __koi_switch_to_ko(mod); ++ return (void *)addr; ++} ++EXPORT_SYMBOL(koi_kzalloc_node_wrapper); ++ ++//kmalloc function in driver space ++__koi_code void * ++koi_kmalloc_wrapper(struct module *mod, size_t size, gfp_t flags) ++{ ++ int cnt = (size + PAGE_SIZE - 1) / PAGE_SIZE; ++ void *addr = NULL; ++ struct koi_mem_hash_node *target = NULL; ++ koi_switch_to_kernel(); ++ ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) { ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ if (target == NULL) { ++ panic(KERN_ERR"mem node for module: %s not found\n", mod->name); ++ } ++ ++ addr = kmalloc(cnt * PAGE_SIZE, flags); ++ koi_copy_pagetable(target->ko_mm, target->pgdp, (unsigned long)addr, ++ (unsigned long)addr + PAGE_SIZE * cnt, 0); ++ __koi_switch_to_ko(mod); ++ return (void *)addr; ++} ++EXPORT_SYMBOL(koi_kmalloc_wrapper); ++ ++//vmalloc function in driver space ++__koi_code void *koi_vmalloc_wrapper(struct module *mod, ++ unsigned long size) ++{ ++ int cnt = (size + PAGE_SIZE - 1) / PAGE_SIZE; ++ void *addr; ++ struct koi_mem_hash_node *target = NULL; ++ koi_switch_to_kernel(); ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) { ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ if (target == NULL) { ++ panic("mem node for module: %s not found\n", mod->name); ++ } ++ addr = vmalloc(cnt * PAGE_SIZE); ++ koi_copy_pagetable(target->ko_mm, target->pgdp, (unsigned long)addr, ++ (unsigned long)addr + PAGE_SIZE * cnt, 0); ++ __koi_switch_to_ko(mod); ++ return addr; ++} ++EXPORT_SYMBOL(koi_vmalloc_wrapper); ++ ++//kmalloc_array function in driver space ++__koi_code void *koi_kmalloc_array_wrapper(struct module *mod, ++ size_t n, size_t size, ++ gfp_t flags) ++{ ++ int kpage; ++ void *addr; ++ struct koi_mem_hash_node *target = NULL; ++ koi_switch_to_kernel(); ++ rcu_read_lock(); ++ hash_for_each_possible_rcu (koi_mem_htbl, target, node, ++ (unsigned long)mod) { ++ if (target->mod == mod) { ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ if (target == NULL) { ++ panic("mem node for module: %s not found\n", mod->name); ++ } ++ kpage = (n * size + PAGE_SIZE - 1) / PAGE_SIZE; ++ n = (kpage * PAGE_SIZE) / size; ++ addr = kmalloc_array(n, size, flags); ++ koi_copy_pagetable(target->ko_mm, target->pgdp, (unsigned long)addr, ++ (unsigned long)addr + PAGE_SIZE * kpage, 0); ++ __koi_switch_to_ko(mod); ++ return addr; ++} ++EXPORT_SYMBOL(koi_kmalloc_array_wrapper); ++ ++__koi_code void *koi_kcalloc_wrapper(struct module *mod, size_t n, size_t size, gfp_t flags) { ++ return koi_kmalloc_array_wrapper(mod, n, size, flags | __GFP_ZERO); ++} ++EXPORT_SYMBOL(koi_kcalloc_wrapper); ++ ++#ifndef CONFIG_IEE ++void koi_init_token(struct task_struct *tsk) ++{ ++ struct task_token *token_addr = ++ (struct task_token *)((unsigned long)tsk + KOI_OFFSET); ++ ++ token_addr->koi_kernel_stack = NULL; ++ // token_addr->koi_stack = NULL; ++ // token_addr->koi_stack_base = NULL; ++ token_addr->current_ttbr1 = 0; ++} ++ ++#endif ++ ++ ++#if defined(CONFIG_KOI) && !defined(CONFIG_IEE) ++ ++ ++// mapping the new page to token, whose address is new+KOI_OFFSET. ++ ++static void do_split_huge_pmd(pmd_t* pmdp) ++{ ++ pte_t *pgtable = pte_alloc_one_kernel(&init_mm); ++ int i; ++ struct page *page = pmd_page(*pmdp); ++ pte_t *ptep = (pte_t *)((unsigned long)pgtable); ++ for (i = 0; i < PMD_SIZE / PAGE_SIZE; i++, ptep++) { ++ pte_t entry; ++ pgprot_t pgprot = pmd_pgprot(*pmdp); ++ entry = mk_pte(page + i, pgprot); ++ WRITE_ONCE(*ptep, entry); ++ } ++ spinlock_t *ptl = pmd_lock(&init_mm, pmdp); ++ if (pmd_leaf(READ_ONCE(*pmdp))) { ++ smp_wmb(); ++ pmd_populate_kernel(&init_mm, pmdp, pgtable); ++ pgtable = NULL; ++ } ++ spin_unlock(ptl); ++ if(pgtable) ++ { ++ pte_free_kernel(&init_mm, pgtable); ++ } ++} ++void koi_add_page_mapping(void *token, void *token_page, unsigned int order) ++{ ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, (unsigned long)token); ++ p4d_t *p4dp = p4d_offset(pgdp, (unsigned long)token); ++ pud_t *pudp = pud_offset(p4dp, (unsigned long)token); ++ pmd_t *token_pmdp = pmd_offset(pudp, (unsigned long)token); ++ pte_t *token_ptep; ++ ++ pgdp = pgd_offset_pgd(pgdir, (unsigned long)token_page); ++ p4dp = p4d_offset(pgdp, (unsigned long)token_page); ++ pudp = pud_offset(p4dp, (unsigned long)token_page); ++ pmd_t *token_page_pmdp = pmd_offset(pudp, (unsigned long)token_page); ++ pte_t *token_page_ptep; ++ ++ int use_block_pmd = 0; ++ if (pmd_leaf(*token_pmdp) && order < 9) { ++ do_split_huge_pmd(token_pmdp); ++ do_split_huge_pmd(token_page_pmdp); ++ } else if (pmd_leaf(*token_pmdp)) { ++ use_block_pmd = 1; ++ } ++ ++ if (use_block_pmd) { ++ token_ptep = (pte_t *)token_pmdp; ++ token_page_ptep = (pte_t *)token_page_pmdp; ++ } else { ++ token_ptep = pte_offset_kernel(token_pmdp, (unsigned long)token); ++ token_page_ptep = pte_offset_kernel(token_page_pmdp, (unsigned long)token_page); ++ } ++ ++ if (use_block_pmd) ++ { ++ pmd_t *pmdp = (pmd_t *)token_page_ptep; ++ pmd_t pmd = READ_ONCE(*pmdp); ++ pmd = __pmd((pmd_val(pmd) & ~__RW) & ~___D & ~__PP); ++ WRITE_ONCE(*pmdp, pmd); ++ pmdp = (pmd_t *)token_ptep; ++ pmd = READ_ONCE(*pmdp); ++ pmd = __pmd(((pmd_val(pmd) & ~PTE_PFN_MASK) | __PP) | (__phys_to_pfn(__pa(token_page)) << PAGE_SHIFT)); ++ WRITE_ONCE(*pmdp, pmd); ++ } ++ else { ++ for(int i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*token_ptep); ++ pte = __pte(((pte_val(pte) & ~PTE_PFN_MASK) | __PP) | (__phys_to_pfn(__pa(token_page) + i * PAGE_SIZE) << PAGE_SHIFT)); ++ WRITE_ONCE(*token_ptep, pte); ++ pte = READ_ONCE(*token_page_ptep); ++ pte = __pte((pte_val(pte) & ~__RW) & ~___D & ~__PP); ++ WRITE_ONCE(*token_page_ptep, pte); ++ token_ptep++; ++ token_page_ptep++; ++ } ++ } ++ flush_tlb_kernel_range((unsigned long)token, (unsigned long)(token + (PAGE_SIZE * (1 << order)))); ++ flush_tlb_kernel_range((unsigned long)token_page, (unsigned long)(token_page + (PAGE_SIZE * (1 << order)))); ++} ++ ++void koi_remove_page_mapping(unsigned long token, void *__unused, unsigned long order) { ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, (unsigned long)token); ++ p4d_t *p4dp = p4d_offset(pgdp, (unsigned long)token); ++ pud_t *pudp = pud_offset(p4dp, (unsigned long)token); ++ pmd_t *token_pmdp = pmd_offset(pudp, (unsigned long)token); ++ pte_t *token_ptep; ++ void *token_page; ++ int use_block_pmd = 0; ++ if (pmd_leaf(*token_pmdp)) { ++ use_block_pmd = 1; ++ token_ptep = (pte_t *)token_pmdp; ++ token_page = page_address(pmd_page(*token_pmdp)); ++ } else { ++ token_ptep = pte_offset_kernel(token_pmdp, (unsigned long)token); ++ token_page = page_address(pte_page(*token_ptep)); ++ } ++ pgdp = pgd_offset_pgd(pgdir, (unsigned long)token_page); ++ p4dp = p4d_offset(pgdp, (unsigned long)token_page); ++ pudp = pud_offset(p4dp, (unsigned long)token_page); ++ pmd_t *token_page_pmdp = pmd_offset(pudp, (unsigned long)token_page); ++ pte_t *token_page_ptep; ++ if (use_block_pmd) { ++ token_page_ptep = (pte_t *)token_page_pmdp; ++ } else { ++ token_page_ptep = pte_offset_kernel(token_page_pmdp, (unsigned long)token_page); ++ } ++ if (use_block_pmd) ++ { ++ pmd_t *pmdp = (pmd_t *)token_page_ptep; ++ pmd_t pmd = READ_ONCE(*pmdp); ++ pmd = __pmd(pmd_val(pmd) | ___D | __RW | __PP); ++ WRITE_ONCE(*pmdp, pmd); ++ pmdp = (pmd_t *)token_ptep; ++ pmd = READ_ONCE(*pmdp); ++ pmd = __pmd((pmd_val(pmd) & ~PTE_PFN_MASK & ~__PP) | (__phys_to_pfn(__pa(token - KOI_OFFSET)) << PAGE_SHIFT)); ++ WRITE_ONCE(*pmdp, pmd); ++ } ++ else ++ { ++ for(int i = 0; i < (0x1 << order); i++) ++ { ++ pte_t pte = READ_ONCE(*token_ptep); ++ pte = __pte((pte_val(pte) & ~PTE_PFN_MASK & ~__PP) | (__phys_to_pfn(__pa(token - KOI_OFFSET) + i * PAGE_SIZE) << PAGE_SHIFT)); ++ WRITE_ONCE(*token_ptep, pte); ++ pte = READ_ONCE(*token_page_ptep); ++ pte = __pte(pte_val(pte) | ___D | __RW | __PP); ++ WRITE_ONCE(*token_page_ptep, pte); ++ token_ptep++; ++ token_page_ptep++; ++ } ++ } ++ free_pages((unsigned long)token_page, order); ++ flush_tlb_kernel_range((unsigned long)token, (unsigned long)(token + (PAGE_SIZE * (1 << order)))); ++ flush_tlb_kernel_range((unsigned long)token_page, (unsigned long)(token_page + (PAGE_SIZE * (1 << order)))); ++} ++ ++#endif +\ No newline at end of file +diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c +index adc67f98819a..5eda6c3a5fac 100644 +--- a/arch/x86/kernel/ldt.c ++++ b/arch/x86/kernel/ldt.c +@@ -408,7 +408,11 @@ static void free_ldt_pgtables(struct mm_struct *mm) + */ + tlb_gather_mmu_fullmm(&tlb, mm); + free_pgd_range(&tlb, start, end, start, end); ++ #ifdef CONFIG_PTP ++ iee_tlb_finish_mmu(&tlb); ++ #else + tlb_finish_mmu(&tlb); ++ #endif + #endif + } + +diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c +index bb2af7bcc47d..a5cf20bbbc5f 100644 +--- a/arch/x86/kernel/machine_kexec_64.c ++++ b/arch/x86/kernel/machine_kexec_64.c +@@ -30,6 +30,10 @@ + #include + #include + ++#ifdef CONFIG_PTP ++#include ++#endif ++ + #ifdef CONFIG_ACPI + /* + * Used while adding mapping for ACPI tables. +@@ -139,12 +143,27 @@ map_efi_systab(struct x86_mapping_info *info, pgd_t *level4p) + + static void free_transition_pgtable(struct kimage *image) + { ++ #ifdef CONFIG_PTP ++ unset_iee_page((unsigned long)image->arch.p4d, 0); ++ #endif + free_page((unsigned long)image->arch.p4d); + image->arch.p4d = NULL; ++ ++ #ifdef CONFIG_PTP ++ unset_iee_page((unsigned long)image->arch.pud, 0); ++ #endif + free_page((unsigned long)image->arch.pud); + image->arch.pud = NULL; ++ ++ #ifdef CONFIG_PTP ++ unset_iee_page((unsigned long)image->arch.pmd, 0); ++ #endif + free_page((unsigned long)image->arch.pmd); + image->arch.pmd = NULL; ++ ++ #ifdef CONFIG_PTP ++ unset_iee_page((unsigned long)image->arch.pte, 0); ++ #endif + free_page((unsigned long)image->arch.pte); + image->arch.pte = NULL; + } +@@ -166,6 +185,9 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd) + p4d = (p4d_t *)get_zeroed_page(GFP_KERNEL); + if (!p4d) + goto err; ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)p4d, 0); ++ #endif + image->arch.p4d = p4d; + set_pgd(pgd, __pgd(__pa(p4d) | _KERNPG_TABLE)); + } +@@ -174,6 +196,9 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd) + pud = (pud_t *)get_zeroed_page(GFP_KERNEL); + if (!pud) + goto err; ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)pud, 0); ++ #endif + image->arch.pud = pud; + set_p4d(p4d, __p4d(__pa(pud) | _KERNPG_TABLE)); + } +@@ -182,6 +207,9 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd) + pmd = (pmd_t *)get_zeroed_page(GFP_KERNEL); + if (!pmd) + goto err; ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)pmd, 0); ++ #endif + image->arch.pmd = pmd; + set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE)); + } +@@ -190,6 +218,9 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd) + pte = (pte_t *)get_zeroed_page(GFP_KERNEL); + if (!pte) + goto err; ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)pte, 0); ++ #endif + image->arch.pte = pte; + set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE)); + } +@@ -216,6 +247,10 @@ static void *alloc_pgt_page(void *data) + clear_page(p); + } + ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)page_to_virt(page), 0); ++ #endif ++ + return p; + } + +@@ -234,7 +269,10 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable) + + level4p = (pgd_t *)__va(start_pgtable); + clear_page(level4p); +- ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)level4p, 0); ++ #endif ++ + if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) { + info.page_flag |= _PAGE_ENC; + info.kernpg_flag |= _PAGE_ENC; +diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c +index 8d51c86caa41..c719f4dc4cdc 100644 +--- a/arch/x86/kernel/paravirt.c ++++ b/arch/x86/kernel/paravirt.c +@@ -81,7 +81,11 @@ void __init native_pv_lock_init(void) + + static void native_tlb_remove_table(struct mmu_gather *tlb, void *table) + { ++ #ifdef CONFIG_PTP ++ iee_tlb_remove_page(tlb, table); ++ #else + tlb_remove_page(tlb, table); ++ #endif + } + + unsigned int paravirt_patch(u8 type, void *insn_buff, unsigned long addr, +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index bd33c4f7c125..4ce7c25b5c62 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -57,6 +57,13 @@ + #include + #include + ++#ifdef CONFIG_IEE ++#include ++#endif ++#if defined(CONFIG_IEE) || defined(CONFIG_KOI) ++void *init_token_page_vaddr; ++#endif ++ + /* + * max_low_pfn_mapped: highest directly mapped pfn < 4 GB + * max_pfn_mapped: highest directly mapped pfn > 4 GB +@@ -837,6 +844,105 @@ static void __init x86_report_nx(void) + } + } + ++#ifdef CONFIG_IEE ++#include ++unsigned long IEE_OFFSET = 0x200000000000; // IEE_OFFSET = pgtable_l5_enabled() ? 0x40000000000000 : 0x200000000000; ++unsigned long iee_offset = 0x200000000000; ++int DIRECT_MAP_SHIFT = 47; // __VIRTUAL_MASK_SHIFT (pgtable_l5_enabled() ? 56 : 47) ++EXPORT_SYMBOL(IEE_OFFSET); ++EXPORT_SYMBOL(DIRECT_MAP_SHIFT); ++#ifdef CONFIG_X86_5LEVEL ++void init_iee_offset(void) { ++ if(pgtable_l5_enabled()) { ++ IEE_OFFSET = 0x40000000000000; ++ DIRECT_MAP_SHIFT = 56; ++ iee_offset = IEE_OFFSET; ++ } ++} ++#endif /* CONFIG_X86_5LEVEL */ ++ ++void __init iee_set_token_page_valid_pre_init(void *token, void *token_page) ++{ ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, (unsigned long)token); ++ p4d_t *p4dp = p4d_offset(pgdp, (unsigned long)token); ++ pud_t *pudp = pud_offset(p4dp, (unsigned long)token); ++ pmd_t *pmdp = pmd_offset(pudp, (unsigned long)token); ++ if (pmd_leaf(*pmdp)) { ++ extern void *alloc_low_pages(unsigned int num); ++ pte_t* pgtable = alloc_low_pages(1); ++ struct page *page = pmd_page(*pmdp); ++ pte_t *ptep = (pte_t *)((unsigned long)pgtable); ++ for (int i = 0; i < PMD_SIZE / PAGE_SIZE; i++, ptep++) { ++ pte_t entry; ++ pgprot_t pgprot = pmd_pgprot(*pmdp); ++ entry = mk_pte(page + i, pgprot); ++ WRITE_ONCE(*ptep, entry); ++ } ++ #ifdef CONFIG_PTP ++ iee_pmd_populate_kernel_pre_init(&init_mm, pmdp, pgtable); ++ #else ++ pmd_populate_kernel(&init_mm, pmdp, pgtable); ++ #endif ++ } ++ pte_t *ptep = pte_offset_kernel(pmdp, (unsigned long)token); ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(((pte_val(pte) & ~PTE_PFN_MASK) | __PP) | (__phys_to_pfn(__pa(token_page)) << PAGE_SHIFT)); ++ #ifdef CONFIG_PTP ++ iee_set_pte_pre_init(ptep, pte); ++ #else ++ set_pte(ptep, pte); ++ #endif ++ flush_tlb_kernel_range((unsigned long)token, (unsigned long)(token+PAGE_SIZE)); ++} ++#else ++#ifdef CONFIG_KOI ++#include ++unsigned long KOI_OFFSET = 0x200000000000; // IEE_OFFSET = pgtable_l5_enabled() ? 0x40000000000000 : 0x200000000000; ++unsigned long koi_offset = 0x200000000000; ++int DIRECT_MAP_SHIFT = 47; // __VIRTUAL_MASK_SHIFT (pgtable_l5_enabled() ? 56 : 47) ++EXPORT_SYMBOL(KOI_OFFSET); ++EXPORT_SYMBOL(DIRECT_MAP_SHIFT); ++#ifdef CONFIG_X86_5LEVEL ++void init_koi_offset(void) { ++ if(pgtable_l5_enabled()) { ++ KOI_OFFSET = 0x40000000000000; ++ DIRECT_MAP_SHIFT = 56; ++ koi_offset = KOI_OFFSET; ++ } ++} ++#endif /* CONFIG_X86_5LEVEL */ ++ ++ ++void __init koi_set_token_page_valid_pre_init(void *token, void *token_page) ++{ ++ pgd_t *pgdir = swapper_pg_dir; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, (unsigned long)token); ++ p4d_t *p4dp = p4d_offset(pgdp, (unsigned long)token); ++ pud_t *pudp = pud_offset(p4dp, (unsigned long)token); ++ pmd_t *pmdp = pmd_offset(pudp, (unsigned long)token); ++ if (pmd_leaf(*pmdp)) { ++ extern void *alloc_low_pages(unsigned int num); ++ pte_t* pgtable = alloc_low_pages(1); ++ struct page *page = pmd_page(*pmdp); ++ pte_t *ptep = (pte_t *)((unsigned long)pgtable); ++ for (int i = 0; i < PMD_SIZE / PAGE_SIZE; i++, ptep++) { ++ pte_t entry; ++ pgprot_t pgprot = pmd_pgprot(*pmdp); ++ entry = mk_pte(page + i, pgprot); ++ WRITE_ONCE(*ptep, entry); ++ } ++ pmd_populate_kernel(&init_mm, pmdp, pgtable); ++ } ++ pte_t *ptep = pte_offset_kernel(pmdp, (unsigned long)token); ++ pte_t pte = READ_ONCE(*ptep); ++ pte = __pte(((pte_val(pte) & ~PTE_PFN_MASK) | __PP) | (__phys_to_pfn(__pa(token_page)) << PAGE_SHIFT)); ++ set_pte(ptep, pte); ++ flush_tlb_kernel_range((unsigned long)token, (unsigned long)(token+PAGE_SIZE)); ++} ++#endif /* CONFIG_KOI */ ++#endif /* CONFIG_IEE */ ++ + /* + * Determine if we were loaded by an EFI loader. If so, then we have also been + * passed the efi memmap, systab, etc., so we should use these data structures +@@ -1078,6 +1184,13 @@ void __init setup_arch(char **cmdline_p) + * Define random base addresses for memory sections after max_pfn is + * defined and before each memory section base is used. + */ ++ #if defined(CONFIG_IEE) && defined(CONFIG_X86_5LEVEL) ++ init_iee_offset(); ++ #else ++ #if defined(CONFIG_KOI) && defined(CONFIG_X86_5LEVEL) ++ init_koi_offset(); ++ #endif ++ #endif + kernel_randomize_memory(); + + #ifdef CONFIG_X86_32 +@@ -1163,6 +1276,70 @@ void __init setup_arch(char **cmdline_p) + + init_mem_mapping(); + ++ #ifdef CONFIG_IEE ++ printk(KERN_ERR "init_iee_mapping begin ...\n"); ++ init_iee_mapping(); ++ printk(KERN_ERR "init_iee_mapping done ...\n"); ++ ++ printk(KERN_ERR "init token begin ...\n"); ++ // Change init_task image va to Logival VA ++ unsigned long init_task_la = (unsigned long)__va(__pa_symbol(&init_task)); ++ raw_cpu_write(pcpu_hot.current_task, (struct task_struct *)init_task_la); ++ init_task.cpus_ptr = &(((struct task_struct *)(__va(__pa_symbol(&init_task))))->cpus_mask); ++ init_task.children.prev = (__va(__pa_symbol(init_task.children.prev))); ++ init_task.children.next = (__va(__pa_symbol(init_task.children.next))); ++ ++ void *new; ++ void *init_token; ++ struct task_token *token; ++ ++ // Alloc a page for init_token. ++ extern void *alloc_low_pages(unsigned int num); ++ new = alloc_low_pages(1); ++ init_token_page_vaddr = new; ++ init_token = (void *)__phys_to_iee(__pa_symbol(&init_task)); ++ // Use lm to write token before IEE initialized. ++ token = (struct task_token *)((unsigned long)new + (((unsigned long)&init_task) & ~PAGE_MASK)); ++ token->pgd = NULL; ++ token->iee_stack = (void *)__phys_to_iee(__pa_symbol(init_iee_stack_end)); ++ token->valid = true; ++ iee_set_token_page_valid_pre_init(init_token, new); ++ printk(KERN_ERR "init token end ...\n"); ++ #else ++ #ifdef CONFIG_KOI ++ printk(KERN_ERR "init_iee_mapping begin ...\n"); ++ init_koi_mapping(); ++ printk(KERN_ERR "init_iee_mapping done ...\n"); ++ ++ // Change init_task image va to Logival VA ++ unsigned long init_task_la = (unsigned long)__va(__pa_symbol(&init_task)); ++ raw_cpu_write(pcpu_hot.current_task, (struct task_struct *)init_task_la); ++ init_task.cpus_ptr = &(((struct task_struct *)(__va(__pa_symbol(&init_task))))->cpus_mask); ++ init_task.children.prev = (__va(__pa_symbol(init_task.children.prev))); ++ init_task.children.next = (__va(__pa_symbol(init_task.children.next))); ++ ++ void *new; ++ void *init_token; ++ struct task_token *token; ++ ++ // Alloc a page for init_token. ++ extern void *alloc_low_pages(unsigned int num); ++ new = alloc_low_pages(1); ++ init_token_page_vaddr = new; ++ init_token = (void *)__phys_to_koi(__pa_symbol(&init_task)); ++ // Use lm to write token before IEE initialized. ++ token = (struct task_token *)((unsigned long)new + (((unsigned long)&init_task) & ~PAGE_MASK)); ++ koi_set_token_page_valid_pre_init(init_token, new); ++ printk(KERN_ERR "init token end ...\n"); ++ #endif ++ #endif /* CONFIG_IEE*/ ++ ++ #ifdef CONFIG_PTP ++ printk(KERN_ERR "mapping page table into iee begin ...\n"); ++ init_iee(); ++ printk(KERN_ERR "mapping page table into iee done ...\n"); ++ #endif ++ + idt_setup_early_pf(); + + /* +diff --git a/arch/x86/kernel/sfi_bpf_arch.c b/arch/x86/kernel/sfi_bpf_arch.c +new file mode 100644 +index 000000000000..0021c3ed36f6 +--- /dev/null ++++ b/arch/x86/kernel/sfi_bpf_arch.c +@@ -0,0 +1,85 @@ ++#include ++#include ++#include ++ ++pte_t *bpf_sfi_get_ptep(u64 addr) ++{ ++ pgd_t *pgdp; ++ p4d_t *p4dp; ++ pud_t *pudp; ++ pmd_t *pmdp; ++ pte_t *ptep; ++ ++ /* DEBUG check pgd */ ++ // u64 ttbr1_phy, ttbr1_vir; ++ // __asm__ volatile( ++ // "mrs %0, ttbr1_el1\n\t" ++ // : "=r" (ttbr1_phy) ++ // :: ++ // ); ++ // pr_debug("phy = 0x%llx, after mask = 0x%llx\n", ttbr1_phy, (u64)(ttbr1_phy << 16) >> 16); ++ // ttbr1_vir = (u64)__phys_to_kimg((u64)(ttbr1_phy << 16) >> 16); ++ // pr_info("1, ttbr1_vir = 0x%llx, \n", ttbr1_vir); ++ // pr_info("2, init_mm.pgd = 0x%llx\n", (u64)init_mm.pgd); ++ // pr_info("3, swapper_pg_dir = 0x%llx\n", (u64)swapper_pg_dir); ++ ++ pgdp = pgd_offset(&init_mm, addr); ++ if (pgd_none(*pgdp) || pgd_bad(*pgdp)) { ++ pr_err("get pgdp of 0x%llx failed\n", addr); ++ return ERR_PTR(-ENOENT); ++ } ++ ++ p4dp = p4d_offset(pgdp, addr); ++ if (p4d_none(*p4dp) || p4d_bad(*p4dp)) { ++ pr_err("get p4dp of 0x%llx failed\n", addr); ++ return ERR_PTR(-ENOENT); ++ } ++ ++ /* IMPORTANT judge huge page first, then judge table */ ++ pudp = pud_offset(p4dp, addr); ++ if (pud_huge(*pudp)) { ++ // pud is huge page ++ pr_warn("pud of 0x%llx is huge page", addr); ++ // return (pte_t *)pudp; ++ return ERR_PTR(-ENOTSUPP); ++ } ++ if (pud_none(*pudp) || pud_bad(*pudp)) { ++ pr_err("get pudp of 0x%llx failed\n", addr); ++ return ERR_PTR(-ENOENT); ++ } ++ ++ pmdp = pmd_offset(pudp, addr); ++ if (pmd_huge(*pmdp)) { ++ // pmd is huge page ++ pr_warn("pmd of 0x%llx is huge page", addr); ++ // return (pte_t *)pmdp; ++ return ERR_PTR(-ENOTSUPP); ++ } ++ if (pmd_none(*pmdp) || pmd_bad(*pmdp)) { ++ pr_err("get pmdp of 0x%llx failed\n", addr); ++ return ERR_PTR(-ENOENT); ++ } ++ ++ ptep = pte_offset_kernel(pmdp, addr); ++ if (!ptep) { ++ pr_err("get ptep of 0x%llx failed\n", addr); ++ return ERR_PTR(-ENOENT); ++ } ++ ++ return ptep; ++} ++ ++// int bpf_sfi_hook_kernel_fault(u64 addr) ++// { ++// pte_t *ptep; ++ ++// ptep = bpf_sfi_get_ptep(addr); ++// if (IS_ERR(ptep)) ++// return PTR_ERR(ptep); ++ ++// if (pte_val(*ptep) & PTE_BPF_SFI_GP) { ++// return true; ++// } ++// else ++// return false; ++// } +\ No newline at end of file +diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S +index fbd34ee394a7..3a60fb1bd88a 100644 +--- a/arch/x86/kernel/vmlinux.lds.S ++++ b/arch/x86/kernel/vmlinux.lds.S +@@ -99,6 +99,60 @@ jiffies = jiffies_64; + + #endif + ++#ifdef CONFIG_IEE ++#define IEE_TEXT \ ++ . = ALIGN(PAGE_SIZE); \ ++ __iee_code_start = .; \ ++ *(.iee.text.header) \ ++ *(.iee.text) \ ++ . = ALIGN(PAGE_SIZE); \ ++ __iee_code_end = .; ++#else ++#define IEE_TEXT ++#endif ++#ifdef CONFIG_IEE ++#define IEE_SI_TEXT \ ++ . = ALIGN(PAGE_SIZE); \ ++ __iee_si_text_start = .; \ ++ *(.iee.si_text) \ ++ . = ALIGN(PAGE_SIZE); \ ++ __iee_trampoline_si_text_start = .; \ ++ *(.iee.trampoline.si_text) \ ++ __iee_trampoline_si_text_end = .; \ ++ . = ALIGN(PAGE_SIZE); \ ++ __iee_si_text_end = .; ++#else ++#define IEE_SI_TEXT ++#endif ++#ifdef CONFIG_IEE ++#define IEE_SI_DATA \ ++ . = ALIGN(PAGE_SIZE); \ ++ __iee_si_data_start = .; \ ++ *(.iee.si_data) \ ++ . = ALIGN(PAGE_SIZE); \ ++ __iee_si_data_end = .; ++#else ++#define IEE_SI_DATA ++#endif ++ ++#ifdef CONFIG_CREDP ++ #define CRED_DATA \ ++ . = ALIGN(PAGE_SIZE); \ ++ *(.iee.cred) \ ++ . = ALIGN(PAGE_SIZE); ++#else ++ #define CRED_DATA ++#endif ++ ++#ifdef CONFIG_IEE_SELINUX_P ++ #define IEE_SELINUX_DATA \ ++ . = ALIGN(PAGE_SIZE); \ ++ *(.iee.selinux) \ ++ . = ALIGN(PAGE_SIZE); ++#else ++ #define IEE_SELINUX_DATA ++#endif ++ + PHDRS { + text PT_LOAD FLAGS(5); /* R_E */ + data PT_LOAD FLAGS(6); /* RW_ */ +@@ -111,6 +165,17 @@ PHDRS { + note PT_NOTE FLAGS(0); /* ___ */ + } + ++#ifdef CONFIG_KOI ++#define KOI_TEXT \ ++ . = ALIGN(PAGE_SIZE); \ ++ __koi_code_start = .; \ ++ *(.koi.text) \ ++ . = ALIGN(PAGE_SIZE); \ ++ __koi_code_end = .; ++#else ++#define KOI_TEXT ++#endif ++ + SECTIONS + { + #ifdef CONFIG_X86_32 +@@ -127,10 +192,12 @@ SECTIONS + _stext = .; + /* bootstrapping code */ + HEAD_TEXT ++ IEE_TEXT + TEXT_TEXT + SCHED_TEXT + LOCK_TEXT + KPROBES_TEXT ++ IEE_SI_TEXT + SOFTIRQENTRY_TEXT + #ifdef CONFIG_RETPOLINE + *(.text..__x86.indirect_thunk) +@@ -151,6 +218,7 @@ SECTIONS + *(.text..__x86.rethunk_safe) + #endif + ALIGN_ENTRY_TEXT_END ++ KOI_TEXT + *(.gnu.warning) + + } :text = 0xcccccccc +@@ -181,6 +249,9 @@ SECTIONS + CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) + + DATA_DATA ++ IEE_SI_DATA ++ CRED_DATA ++ IEE_SELINUX_DATA + CONSTRUCTORS + + /* rarely changed data like cpu maps */ +@@ -410,6 +481,13 @@ SECTIONS + __bss_stop = .; + } + ++#ifdef CONFIG_IEE ++ . = ALIGN(PAGE_SIZE*4); ++ init_iee_stack_begin = .; ++ . += PAGE_SIZE*4; ++ init_iee_stack_end = .; ++#endif ++ + /* + * The memory occupied from _text to here, __end_of_kernel_reserve, is + * automatically reserved in setup_arch(). Anything after here must be +diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c +index e568b64a2b6b..3320f4a9fe5b 100644 +--- a/arch/x86/mm/fault.c ++++ b/arch/x86/mm/fault.c +@@ -272,6 +272,9 @@ void arch_sync_kernel_mappings(unsigned long start, unsigned long end) + + spin_lock(&pgd_lock); + list_for_each_entry(page, &pgd_list, lru) { ++ #ifdef CONFIG_PTP ++ page = iee_ptdesc_to_page(page); ++ #endif + spinlock_t *pgt_lock; + + /* the pgt_lock only for Xen */ +diff --git a/arch/x86/mm/ident_map_for_iee.c b/arch/x86/mm/ident_map_for_iee.c +new file mode 100644 +index 000000000000..8b1f1ea52ec4 +--- /dev/null ++++ b/arch/x86/mm/ident_map_for_iee.c +@@ -0,0 +1,197 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Helper routines for building identity mapping page tables. This is ++ * included by both the compressed kernel and the regular kernel. ++ */ ++ ++#ifdef CONFIG_PTP ++static void ident_pmd_init_for_iee(struct x86_mapping_info *info, pmd_t *pmd_page, ++ unsigned long addr, unsigned long end) ++{ ++ addr &= PMD_MASK; ++ for (; addr < end; addr += PMD_SIZE) { ++ pmd_t *pmd = pmd_page + pmd_index(addr); ++ ++ if (pmd_present(*pmd)) ++ continue; ++ ++ #ifdef CONFIG_PTP ++ iee_set_pmd_pre_init(pmd, __pmd((addr - info->offset) | info->page_flag)); ++ #else ++ set_pmd(pmd, __pmd((addr - info->offset) | info->page_flag)); ++ #endif ++ } ++} ++ ++static int ident_pud_init_for_iee(struct x86_mapping_info *info, pud_t *pud_page, ++ unsigned long addr, unsigned long end) ++{ ++ unsigned long next; ++ ++ for (; addr < end; addr = next) { ++ pud_t *pud = pud_page + pud_index(addr); ++ pmd_t *pmd; ++ ++ next = (addr & PUD_MASK) + PUD_SIZE; ++ if (next > end) ++ next = end; ++ ++ if (info->direct_gbpages) { ++ pud_t pudval; ++ ++ if (pud_present(*pud)) ++ continue; ++ ++ addr &= PUD_MASK; ++ pudval = __pud((addr - info->offset) | info->page_flag); ++ #ifdef CONFIG_PTP ++ iee_set_pud_pre_init(pud, pudval); ++ #else ++ set_pud(pud, pudval); ++ #endif ++ continue; ++ } ++ ++ if (pud_present(*pud)) { ++ pmd = pmd_offset(pud, 0); ++ #ifdef CONFIG_PTP ++ ident_pmd_init_for_iee(info, pmd, addr, next); ++ #else ++ ident_pmd_init(info, pmd, addr, next); ++ #endif ++ continue; ++ } ++ pmd = (pmd_t *)info->alloc_pgt_page(info->context); ++ if (!pmd) ++ return -ENOMEM; ++ #ifdef CONFIG_PTP ++ ident_pmd_init_for_iee(info, pmd, addr, next); ++ #else ++ ident_pmd_init(info, pmd, addr, next); ++ #endif ++ #ifdef CONFIG_PTP ++ iee_set_pud_pre_init(pud, __pud(__pa(pmd) | info->kernpg_flag)); ++ #else ++ set_pud(pud, __pud(__pa(pmd) | info->kernpg_flag)); ++ #endif ++ } ++ ++ return 0; ++} ++ ++static int ident_p4d_init_for_iee(struct x86_mapping_info *info, p4d_t *p4d_page, ++ unsigned long addr, unsigned long end) ++{ ++ unsigned long next; ++ int result; ++ ++ for (; addr < end; addr = next) { ++ p4d_t *p4d = p4d_page + p4d_index(addr); ++ pud_t *pud; ++ ++ next = (addr & P4D_MASK) + P4D_SIZE; ++ if (next > end) ++ next = end; ++ ++ if (p4d_present(*p4d)) { ++ pud = pud_offset(p4d, 0); ++ #ifdef CONFIG_PTP ++ result = ident_pud_init_for_iee(info, pud, addr, next); ++ #else ++ result = ident_pud_init(info, pud, addr, next); ++ #endif ++ if (result) ++ return result; ++ ++ continue; ++ } ++ pud = (pud_t *)info->alloc_pgt_page(info->context); ++ if (!pud) ++ return -ENOMEM; ++ ++ #ifdef CONFIG_PTP ++ result = ident_pud_init_for_iee(info, pud, addr, next); ++ #else ++ result = ident_pud_init(info, pud, addr, next); ++ #endif ++ if (result) ++ return result; ++ ++ #ifdef CONFIG_PTP ++ iee_set_p4d_pre_init(p4d, __p4d(__pa(pud) | info->kernpg_flag)); ++ #else ++ set_p4d(p4d, __p4d(__pa(pud) | info->kernpg_flag)); ++ #endif ++ } ++ ++ return 0; ++} ++ ++int kernel_ident_mapping_init_for_iee(struct x86_mapping_info *info, pgd_t *pgd_page, ++ unsigned long pstart, unsigned long pend) ++{ ++ unsigned long addr = pstart + info->offset; ++ unsigned long end = pend + info->offset; ++ unsigned long next; ++ int result; ++ ++ /* Set the default pagetable flags if not supplied */ ++ if (!info->kernpg_flag) ++ info->kernpg_flag = _KERNPG_TABLE; ++ ++ /* Filter out unsupported __PAGE_KERNEL_* bits: */ ++ info->kernpg_flag &= __default_kernel_pte_mask; ++ ++ for (; addr < end; addr = next) { ++ pgd_t *pgd = pgd_page + pgd_index(addr); ++ p4d_t *p4d; ++ ++ next = (addr & PGDIR_MASK) + PGDIR_SIZE; ++ if (next > end) ++ next = end; ++ ++ if (pgd_present(*pgd)) { ++ p4d = p4d_offset(pgd, 0); ++ #ifdef CONFIG_PTP ++ result = ident_p4d_init_for_iee(info, p4d, addr, next); ++ #else ++ result = ident_p4d_init(info, p4d, addr, next); ++ #endif ++ if (result) ++ return result; ++ continue; ++ } ++ ++ p4d = (p4d_t *)info->alloc_pgt_page(info->context); ++ if (!p4d) ++ return -ENOMEM; ++ #ifdef CONFIG_PTP ++ result = ident_p4d_init_for_iee(info, p4d, addr, next); ++ #else ++ result = ident_p4d_init(info, p4d, addr, next); ++ #endif ++ if (result) ++ return result; ++ if (pgtable_l5_enabled()) { ++ #ifdef CONFIG_PTP ++ iee_set_pgd_pre_init(pgd, __pgd(__pa(p4d) | info->kernpg_flag)); ++ #else ++ set_pgd(pgd, __pgd(__pa(p4d) | info->kernpg_flag)); ++ #endif ++ } else { ++ /* ++ * With p4d folded, pgd is equal to p4d. ++ * The pgd entry has to point to the pud page table in this case. ++ */ ++ pud_t *pud = pud_offset(p4d, 0); ++ #ifdef CONFIG_PTP ++ iee_set_pgd_pre_init(pgd, __pgd(__pa(pud) | info->kernpg_flag)); ++ #else ++ set_pgd(pgd, __pgd(__pa(pud) | info->kernpg_flag)); ++ #endif ++ } ++ } ++ ++ return 0; ++} ++#endif +\ No newline at end of file +diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c +index 6215dfa23578..a13a5c41e44c 100644 +--- a/arch/x86/mm/init.c ++++ b/arch/x86/mm/init.c +@@ -28,6 +28,10 @@ + #include + #include + ++#ifdef CONFIG_PTP ++#include ++#endif ++ + /* + * We need to define the tracepoints somewhere, and tlb.c + * is only compiled when SMP=y. +@@ -252,6 +256,8 @@ static void __init probe_page_size_mask(void) + if (cpu_feature_enabled(X86_FEATURE_PTI)) + __default_kernel_pte_mask &= ~_PAGE_GLOBAL; + ++ #ifndef CONFIG_IEE ++ #ifndef CONFIG_KOI + /* Enable 1 GB linear kernel mappings if available: */ + if (direct_gbpages && boot_cpu_has(X86_FEATURE_GBPAGES)) { + printk(KERN_INFO "Using GB pages for direct mapping\n"); +@@ -259,6 +265,8 @@ static void __init probe_page_size_mask(void) + } else { + direct_gbpages = 0; + } ++ #endif ++ #endif + } + + /* +@@ -445,6 +453,8 @@ static int __meminit split_mem_range(struct map_range *mr, int nr_range, + } + + #ifdef CONFIG_X86_64 ++#ifndef CONFIG_IEE ++#ifndef CONFIG_KOI + /* big page (1G) range */ + start_pfn = round_up(pfn, PFN_DOWN(PUD_SIZE)); + end_pfn = round_down(limit_pfn, PFN_DOWN(PUD_SIZE)); +@@ -463,6 +473,8 @@ static int __meminit split_mem_range(struct map_range *mr, int nr_range, + page_size_mask & (1<= end) ++ continue; ++ /* ++ * if it is overlapping with brk pgt, we need to ++ * alloc pgt buf from memblock instead. ++ */ ++ can_use_brk_pgt = max(start, (u64)pgt_buf_end<= ++ min(end, (u64)pgt_buf_top<> PAGE_SHIFT; ++ last_start = real_end; ++ /* ++ * We start from the top (end of memory) and go to the bottom. ++ * The memblock_find_in_range() gets us a block of RAM from the ++ * end of RAM in [min_pfn_mapped, max_pfn_mapped) used as new pages ++ * for page table. ++ */ ++ while (last_start > map_start) { ++ unsigned long start; ++ if (last_start > step_size) { ++ start = round_down(last_start - 1, step_size); ++ if (start < map_start) ++ start = map_start; ++ } else ++ start = map_start; ++ mapped_ram_size += init_range_memory_mapping_for_iee(start, ++ last_start); ++ last_start = start; ++ min_pfn_mapped = last_start >> PAGE_SHIFT; ++ if (mapped_ram_size >= step_size) ++ step_size = get_new_step_size(step_size); ++ } ++ if (real_end < map_end) ++ init_range_memory_mapping_for_iee(real_end, map_end); ++} ++/** ++ * memory_map_bottom_up - Map [map_start, map_end) bottom up ++ * @map_start: start address of the target memory range ++ * @map_end: end address of the target memory range ++ * ++ * This function will setup direct mapping for memory range ++ * [map_start, map_end) in bottom-up. Since we have limited the ++ * bottom-up allocation above the kernel, the page tables will ++ * be allocated just above the kernel and we map the memory ++ * in [map_start, map_end) in bottom-up. ++ */ ++static void __init memory_map_bottom_up_for_iee(unsigned long map_start, ++ unsigned long map_end) ++{ ++ unsigned long next, start; ++ unsigned long mapped_ram_size = 0; ++ /* step_size need to be small so pgt_buf from BRK could cover it */ ++ unsigned long step_size = PMD_SIZE; ++ start = map_start; ++ min_pfn_mapped = start >> PAGE_SHIFT; ++ /* ++ * We start from the bottom (@map_start) and go to the top (@map_end). ++ * The memblock_find_in_range() gets us a block of RAM from the ++ * end of RAM in [min_pfn_mapped, max_pfn_mapped) used as new pages ++ * for page table. ++ */ ++ while (start < map_end) { ++ if (step_size && map_end - start > step_size) { ++ next = round_up(start + 1, step_size); ++ if (next > map_end) ++ next = map_end; ++ } else { ++ next = map_end; ++ } ++ mapped_ram_size += init_range_memory_mapping_for_iee(start, next); ++ start = next; ++ if (mapped_ram_size >= step_size) ++ step_size = get_new_step_size(step_size); ++ } ++} ++unsigned long __ref init_memory_mapping_for_iee(unsigned long start, ++ unsigned long end, pgprot_t prot) ++{ ++ struct map_range mr[NR_RANGE_MR]; ++ unsigned long ret = 0; ++ int nr_range, i; ++ pr_debug("init_memory_mapping_for_iee: [mem %#010lx-%#010lx]\n", ++ start, end - 1); ++ memset(mr, 0, sizeof(mr)); ++ nr_range = split_mem_range(mr, 0, start, end); ++ for (i = 0; i < nr_range; i++) ++ ret = kernel_physical_mapping_init_for_iee(mr[i].start, mr[i].end, ++ 0, ++ prot); ++ ++ add_pfn_range_mapped(start >> PAGE_SHIFT, ret >> PAGE_SHIFT); ++ return ret >> PAGE_SHIFT; ++} ++void __init init_iee_mapping(void) ++{ ++ unsigned long end; ++#ifdef CONFIG_X86_64 ++ end = max_pfn << PAGE_SHIFT; ++#else ++ end = max_low_pfn << PAGE_SHIFT; ++#endif ++ /* the ISA range is always mapped regardless of memory holes */ ++ init_memory_mapping_for_iee(0, ISA_END_ADDRESS, SET_NG(SET_UPAGE(PAGE_KERNEL))); ++ if(__pa_symbol(_end) > IEE_OFFSET) { ++ panic("Image on too high phys mem.\n"); ++ } ++ /* ++ * If the allocation is in bottom-up direction, we setup direct mapping ++ * in bottom-up, otherwise we setup direct mapping in top-down. ++ */ ++ if (memblock_bottom_up()) { ++ unsigned long kernel_end = __pa_symbol(_end); ++ ++ /* ++ * we need two separate calls here. This is because we want to ++ * allocate page tables above the kernel. So we first map ++ * [kernel_end, end) to make memory above the kernel be mapped ++ * as soon as possible. And then use page tables allocated above ++ * the kernel to map [ISA_END_ADDRESS, kernel_end). ++ */ ++ ++ printk("memory_map_bottom_up_for_iee...\n"); ++ memory_map_bottom_up_for_iee(kernel_end, end); ++ memory_map_bottom_up_for_iee(ISA_END_ADDRESS, kernel_end); ++ } else { ++ printk("memory_map_top_down_for_iee...\n"); ++ memory_map_top_down_for_iee(ISA_END_ADDRESS, end); ++ } ++#ifdef CONFIG_X86_64 ++ if (max_pfn > max_low_pfn) { ++ /* can we preserve max_low_pfn ?*/ ++ max_low_pfn = max_pfn; ++ } ++#else ++ early_ioremap_page_table_range_init(); ++#endif ++ early_memtest(0, max_pfn_mapped << PAGE_SHIFT); ++} ++#else ++#ifdef CONFIG_KOI ++static unsigned long __init init_range_memory_mapping_for_koi( ++ unsigned long r_start, ++ unsigned long r_end) ++{ ++ unsigned long start_pfn, end_pfn; ++ unsigned long mapped_ram_size = 0; ++ int i; ++ for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, NULL) { ++ u64 start = clamp_val(PFN_PHYS(start_pfn), r_start, r_end); ++ u64 end = clamp_val(PFN_PHYS(end_pfn), r_start, r_end); ++ if (start >= end) ++ continue; ++ /* ++ * if it is overlapping with brk pgt, we need to ++ * alloc pgt buf from memblock instead. ++ */ ++ can_use_brk_pgt = max(start, (u64)pgt_buf_end<= ++ min(end, (u64)pgt_buf_top<> PAGE_SHIFT; ++ last_start = real_end; ++ /* ++ * We start from the top (end of memory) and go to the bottom. ++ * The memblock_find_in_range() gets us a block of RAM from the ++ * end of RAM in [min_pfn_mapped, max_pfn_mapped) used as new pages ++ * for page table. ++ */ ++ while (last_start > map_start) { ++ unsigned long start; ++ if (last_start > step_size) { ++ start = round_down(last_start - 1, step_size); ++ if (start < map_start) ++ start = map_start; ++ } else ++ start = map_start; ++ mapped_ram_size += init_range_memory_mapping_for_koi(start, ++ last_start); ++ last_start = start; ++ min_pfn_mapped = last_start >> PAGE_SHIFT; ++ if (mapped_ram_size >= step_size) ++ step_size = get_new_step_size(step_size); ++ } ++ if (real_end < map_end) ++ init_range_memory_mapping_for_koi(real_end, map_end); ++} ++/** ++ * memory_map_bottom_up - Map [map_start, map_end) bottom up ++ * @map_start: start address of the target memory range ++ * @map_end: end address of the target memory range ++ * ++ * This function will setup direct mapping for memory range ++ * [map_start, map_end) in bottom-up. Since we have limited the ++ * bottom-up allocation above the kernel, the page tables will ++ * be allocated just above the kernel and we map the memory ++ * in [map_start, map_end) in bottom-up. ++ */ ++static void __init memory_map_bottom_up_for_koi(unsigned long map_start, ++ unsigned long map_end) ++{ ++ unsigned long next, start; ++ unsigned long mapped_ram_size = 0; ++ /* step_size need to be small so pgt_buf from BRK could cover it */ ++ unsigned long step_size = PMD_SIZE; ++ start = map_start; ++ min_pfn_mapped = start >> PAGE_SHIFT; ++ /* ++ * We start from the bottom (@map_start) and go to the top (@map_end). ++ * The memblock_find_in_range() gets us a block of RAM from the ++ * end of RAM in [min_pfn_mapped, max_pfn_mapped) used as new pages ++ * for page table. ++ */ ++ while (start < map_end) { ++ if (step_size && map_end - start > step_size) { ++ next = round_up(start + 1, step_size); ++ if (next > map_end) ++ next = map_end; ++ } else { ++ next = map_end; ++ } ++ mapped_ram_size += init_range_memory_mapping_for_koi(start, next); ++ start = next; ++ if (mapped_ram_size >= step_size) ++ step_size = get_new_step_size(step_size); ++ } ++} ++unsigned long __ref init_memory_mapping_for_koi(unsigned long start, ++ unsigned long end, pgprot_t prot) ++{ ++ struct map_range mr[NR_RANGE_MR]; ++ unsigned long ret = 0; ++ int nr_range, i; ++ pr_debug("init_memory_mapping_for_koi: [mem %#010lx-%#010lx]\n", ++ start, end - 1); ++ memset(mr, 0, sizeof(mr)); ++ nr_range = split_mem_range(mr, 0, start, end); ++ for (i = 0; i < nr_range; i++) ++ ret = kernel_physical_mapping_init_for_koi(mr[i].start, mr[i].end, ++ mr[i].page_size_mask, ++ prot); ++ ++ add_pfn_range_mapped(start >> PAGE_SHIFT, ret >> PAGE_SHIFT); ++ return ret >> PAGE_SHIFT; ++} ++void __init init_koi_mapping(void) ++{ ++ unsigned long end; ++ end = max_pfn << PAGE_SHIFT; ++ /* the ISA range is always mapped regardless of memory holes */ ++ init_memory_mapping_for_koi(0, ISA_END_ADDRESS, SET_NG(PAGE_KERNEL)); ++ if(__pa_symbol(_end) > KOI_OFFSET) { ++ panic("Image on too high phys mem.\n"); ++ } ++ /* ++ * If the allocation is in bottom-up direction, we setup direct mapping ++ * in bottom-up, otherwise we setup direct mapping in top-down. ++ */ ++ if (memblock_bottom_up()) { ++ unsigned long kernel_end = __pa_symbol(_end); ++ ++ /* ++ * we need two separate calls here. This is because we want to ++ * allocate page tables above the kernel. So we first map ++ * [kernel_end, end) to make memory above the kernel be mapped ++ * as soon as possible. And then use page tables allocated above ++ * the kernel to map [ISA_END_ADDRESS, kernel_end). ++ */ ++ ++ printk("memory_map_bottom_up_for_iee...\n"); ++ memory_map_bottom_up_for_koi(kernel_end, end); ++ memory_map_bottom_up_for_koi(ISA_END_ADDRESS, kernel_end); ++ } else { ++ printk("memory_map_top_down_for_iee...\n"); ++ memory_map_top_down_for_koi(ISA_END_ADDRESS, end); ++ } ++ if (max_pfn > max_low_pfn) { ++ /* can we preserve max_low_pfn ?*/ ++ max_low_pfn = max_pfn; ++ } ++ early_memtest(0, max_pfn_mapped << PAGE_SHIFT); ++} ++ ++#endif /* CONFIG_KOI */ ++#endif /* CONFIG_IEE */ ++ ++#ifdef CONFIG_PTP ++extern int DIRECT_MAP_SHIFT; ++void __init set_iee_valid_pre_init(unsigned long addr) {} ++ ++static void __init move_pte_table_into_iee(pmd_t *pmdp, unsigned long addr, unsigned long end) ++{ ++ pmd_t pmd = READ_ONCE(*pmdp); ++ unsigned long iee_addr = (unsigned long)__phys_to_iee(__pmd_to_phys(pmd)); ++ // printk("move_pte_table_into_iee:\n"); ++ set_iee_valid_pre_init(iee_addr); ++} ++ ++static void __init move_pmd_table_into_iee(pud_t *pudp, unsigned long addr, unsigned long end) ++{ ++ unsigned long next; ++ pud_t pud = READ_ONCE(*pudp); ++ pmd_t *pmdp; ++ pmd_t pmd; ++ ++ unsigned long iee_addr = (unsigned long)__phys_to_iee(__pud_to_phys(pud)); ++ // printk("move_pmd_table_into_iee:\n"); ++ set_iee_valid_pre_init(iee_addr); ++ ++ pmdp = pmd_offset(pudp, addr); ++ do { ++ next = pmd_addr_end(addr, end); ++ pmd = READ_ONCE(*pmdp); ++ if(pmd_val(pmd) & _PSE) { ++ continue; ++ } else { ++ move_pte_table_into_iee(pmdp, addr, next); ++ } ++ } while (pmdp++, addr = next, addr != end); ++} ++ ++static void __init move_pud_table_into_iee(p4d_t *p4dp, unsigned long addr, unsigned long end) ++{ ++ unsigned long next; ++ p4d_t p4d = READ_ONCE(*p4dp); ++ pud_t *pudp; ++ pud_t pud; ++ ++ // printk("p4d_phys: 0x%16lx\n", __p4d_to_phys(p4d)); ++ unsigned long iee_addr = (unsigned long)__phys_to_iee(__p4d_to_phys(p4d)); ++ // printk("move_pud_table_into_iee:\n"); ++ set_iee_valid_pre_init(iee_addr); ++ ++ pudp = pud_offset(p4dp, addr); ++ do { ++ next = pud_addr_end(addr, end); ++ pud = READ_ONCE(*pudp); ++ if(pud_val(pud) & _PSE) { ++ // _PSE = 1 means a page, not a table ++ continue; ++ } else { ++ move_pmd_table_into_iee(pudp, addr, next); ++ } ++ } while (pudp++, addr = next, addr != end); ++} ++ ++static void __init move_p4d_table_into_iee(pgd_t *pgdp, unsigned long addr, unsigned long end) ++{ ++ unsigned long next; ++ pgd_t pgd = READ_ONCE(*pgdp); ++ p4d_t *p4dp; ++ p4d_t p4d; ++ ++ // printk("pgdp: 0x%16lx\n", pgd.pgd); ++ unsigned long iee_addr = (unsigned long)__phys_to_iee(__pgd_to_phys(pgd)); ++ // printk("move_p4d_table_into_iee:\n"); ++ set_iee_valid_pre_init(iee_addr); ++ ++ p4dp = p4d_offset(pgdp, addr); ++ do { ++ next = p4d_addr_end(addr, end); ++ p4d = READ_ONCE(*p4dp); ++ /* No 512 GiB huge pages yet */ ++ move_pud_table_into_iee(p4dp, addr, next); ++ } while (p4dp++, addr = next, addr != end); ++} ++ ++static void __init init_iee_for_one_region(pgd_t *pgdir, unsigned long va_start, unsigned long va_end) ++{ ++ unsigned long addr, end, next; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, va_start); ++ ++ addr = va_start & PAGE_MASK; ++ end = PAGE_ALIGN(va_end); ++ ++ do { ++ // printk("region start va: 0x%16lx\n", addr); ++ next = pgd_addr_end(addr, end); ++ move_p4d_table_into_iee(pgdp, addr, next); ++ } while (pgdp++, addr = next, addr != end); ++} ++ ++void __init init_iee(void) ++{ ++ unsigned long iee_addr; ++ pgd_t *pgdp; ++ phys_addr_t start, end; ++ u64 i; ++ ++ // handling 1-level page table swapper_pg_dir ++ pgdp = swapper_pg_dir; ++ iee_addr = (unsigned long)__phys_to_iee(__pa_symbol(swapper_pg_dir)); ++ set_iee_valid_pre_init(iee_addr); ++ #if PGD_ALLOCATION_ORDER == 1 ++ set_iee_valid_pre_init(iee_addr + PAGE_SIZE); ++ #endif ++ ++ #ifdef CONFIG_X86_5LEVEL ++ iee_addr = (unsigned long)__phys_to_iee(__pa_symbol(level4_kernel_pgt)); ++ set_iee_valid_pre_init(iee_addr); ++ #endif ++ ++ iee_addr = (unsigned long)__phys_to_iee(__pa_symbol(level3_kernel_pgt)); ++ set_iee_valid_pre_init(iee_addr); ++ ++ iee_addr = (unsigned long)__phys_to_iee(__pa_symbol(level2_kernel_pgt)); ++ set_iee_valid_pre_init(iee_addr); ++ ++ iee_addr = (unsigned long)__phys_to_iee(__pa_symbol(level2_fixmap_pgt)); ++ set_iee_valid_pre_init(iee_addr); ++ ++ iee_addr = (unsigned long)__phys_to_iee(__pa_symbol(level1_fixmap_pgt)); ++ for (i = 0; i < FIXMAP_PMD_NUM; i++) { ++ set_iee_valid_pre_init(iee_addr + PAGE_SIZE * i); ++ } ++ ++ // handling 2/3/4-level page table for kernel ++ init_iee_for_one_region(pgdp, (unsigned long)_text, (unsigned long)_etext); ++ init_iee_for_one_region(pgdp, (unsigned long)__start_rodata, (unsigned long)__end_rodata); ++ init_iee_for_one_region(pgdp, (unsigned long)_sdata, (unsigned long)_edata); ++ init_iee_for_one_region(pgdp, (unsigned long)__bss_start, (unsigned long)__bss_stop); ++ ++ // handling page table for fixmap i.e. FIXADDR_START ~ FIXADDR_TOP ++ // printk("fixmap into iee:\n"); ++ init_iee_for_one_region(pgdp, FIXADDR_START, FIXADDR_TOP); ++ ++ // handling page table for %esp fixup stacks ++ // espfix_pud_page in espfix_64.c ++ ++ // handling 2/3/4-level page table for logical mem and iee ++ for_each_mem_range(i, &start, &end) { ++ if(start >= end) { ++ break; ++ } ++ init_iee_for_one_region(pgdp, (unsigned long)__va(start), (unsigned long)__va(end)); ++ init_iee_for_one_region(pgdp, (unsigned long)__phys_to_iee(start), (unsigned long)__phys_to_iee(end)); ++ } ++} ++ ++static void __init iee_set_pte_table_ro(pmd_t *pmdp, unsigned long addr, unsigned long end) ++{ ++ pmd_t pmd = READ_ONCE(*pmdp); ++ unsigned long logical_addr = (unsigned long)__va(__pmd_to_phys(pmd)); ++ iee_set_logical_mem_ro(logical_addr); ++} ++ ++static void __init iee_set_pmd_table_ro(pud_t *pudp, unsigned long addr, unsigned long end) ++{ ++ unsigned long next; ++ pud_t pud = READ_ONCE(*pudp); ++ pmd_t *pmdp; ++ pmd_t pmd; ++ unsigned long logical_addr = (unsigned long)__va(__pud_to_phys(pud)); ++ iee_set_logical_mem_ro(logical_addr); ++ ++ pmdp = pmd_offset(pudp, addr); ++ do { ++ next = pmd_addr_end(addr, end); ++ pmd = READ_ONCE(*pmdp); ++ if (pmd_val(pmd) & _PSE) { ++ continue; ++ } else { ++ iee_set_pte_table_ro(pmdp, addr, next); ++ } ++ } while (pmdp++, addr = next, addr != end); ++} ++ ++static void __init iee_set_pud_table_ro(p4d_t *p4dp, unsigned long addr, unsigned long end) ++{ ++ unsigned long next; ++ p4d_t p4d = READ_ONCE(*p4dp); ++ pud_t *pudp; ++ pud_t pud; ++ unsigned long logical_addr = (unsigned long)__va(__p4d_to_phys(p4d)); ++ iee_set_logical_mem_ro(logical_addr); ++ ++ pudp = pud_offset(p4dp, addr); ++ do { ++ next = pud_addr_end(addr, end); ++ pud = READ_ONCE(*pudp); ++ if (pud_val(pud) & _PSE) { ++ // _PSE = 1 means a page, not a table ++ continue; ++ } else { ++ iee_set_pmd_table_ro(pudp, addr, next); ++ } ++ } while (pudp++, addr = next, addr != end); ++} ++ ++static void __init iee_set_p4d_table_ro(pgd_t *pgdp, unsigned long addr, unsigned long end) ++{ ++ unsigned long next; ++ pgd_t pgd = READ_ONCE(*pgdp); ++ p4d_t *p4dp; ++ p4d_t p4d; ++ unsigned long logical_addr = (unsigned long)__va(__pgd_to_phys(pgd)); ++ iee_set_logical_mem_ro(logical_addr); ++ ++ p4dp = p4d_offset(pgdp, addr); ++ do { ++ next = p4d_addr_end(addr, end); ++ p4d = READ_ONCE(*p4dp); ++ /* No 512 GiB huge pages yet */ ++ iee_set_pud_table_ro(p4dp, addr, next); ++ } while (p4dp++, addr = next, addr != end); ++} ++ ++static void __init iee_mark_pgtable_for_one_region_ro(pgd_t *pgdir, unsigned long va_start, unsigned long va_end) ++{ ++ unsigned long addr, end, next; ++ pgd_t *pgdp = pgd_offset_pgd(pgdir, va_start); ++ ++ addr = va_start & PAGE_MASK; ++ end = PAGE_ALIGN(va_end); ++ ++ do { ++ next = pgd_addr_end(addr, end); ++ iee_set_p4d_table_ro(pgdp, addr, next); ++ } while (pgdp++, addr = next, addr != end); ++} ++ ++// Mark pgtable outside as RO. ++void __init iee_mark_all_lm_pgtable_ro(void) ++{ ++ unsigned long logical_addr; ++ phys_addr_t start, end; ++ u64 i; ++ pgd_t *pgdp; ++ ++ // handling 1-level page table swapper_pg_dir ++ pgdp = swapper_pg_dir; ++ iee_set_logical_mem_ro((unsigned long)swapper_pg_dir); ++ logical_addr = (unsigned long)__va(__pa_symbol(swapper_pg_dir)); ++ iee_set_logical_mem_ro(logical_addr); ++ ++ // handling 2/3/4/5-level page table for kernel ++ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)_text, (unsigned long)_etext); ++ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)__start_rodata, (unsigned long)__end_rodata); ++ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)_sdata, (unsigned long)_edata); ++ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)__bss_start, (unsigned long)__bss_stop); ++ ++ // handling 2/3/4/5-level statically allocated page table ++ #ifdef CONFIG_X86_5LEVEL ++ iee_set_logical_mem_ro((unsigned long)level4_kernel_pgt); ++ logical_addr = (unsigned long)__va(__pa_symbol(level4_kernel_pgt)); ++ iee_set_logical_mem_ro(logical_addr); ++ #endif ++ ++ iee_set_logical_mem_ro((unsigned long)level3_kernel_pgt); ++ logical_addr = (unsigned long)__va(__pa_symbol(level3_kernel_pgt)); ++ iee_set_logical_mem_ro(logical_addr); ++ ++ iee_set_logical_mem_ro((unsigned long)level2_kernel_pgt); ++ logical_addr = (unsigned long)__va(__pa_symbol(level2_kernel_pgt)); ++ iee_set_logical_mem_ro(logical_addr); ++ ++ iee_set_logical_mem_ro((unsigned long)level2_fixmap_pgt); ++ logical_addr = (unsigned long)__va(__pa_symbol(level2_fixmap_pgt)); ++ iee_set_logical_mem_ro(logical_addr); ++ ++ iee_set_logical_mem_ro((unsigned long)level1_fixmap_pgt); ++ logical_addr = (unsigned long)__va(__pa_symbol(level1_fixmap_pgt)); ++ for (i = 0; i < FIXMAP_PMD_NUM; i++) { ++ iee_set_logical_mem_ro(logical_addr + PAGE_SIZE * i); ++ } ++ ++ // handling 2/3/4-level page table for logical mem and iee ++ for_each_mem_range(i, &start, &end) { ++ if (start >= end) ++ break; ++ /* ++ * The linear map must allow allocation tags reading/writing ++ * if MTE is present. Otherwise, it has the same attributes as ++ * PAGE_KERNEL. ++ */ ++ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)__va(start), (unsigned long)__va(end)); ++ iee_mark_pgtable_for_one_region_ro(pgdp, (unsigned long)__phys_to_iee(start), (unsigned long)__phys_to_iee(end)); ++ } ++} ++#endif /* CONFIG_PTP */ ++ + /* + * Initialize an mm_struct to be used during poking and a pointer to be used + * during patching. +diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c +index aa69353da49f..2d9b860fd0a4 100644 +--- a/arch/x86/mm/init_64.c ++++ b/arch/x86/mm/init_64.c +@@ -60,6 +60,10 @@ + + #include "ident_map.c" + ++#ifdef CONFIG_PTP ++#include ++#endif ++ + #define DEFINE_POPULATE(fname, type1, type2, init) \ + static inline void fname##_init(struct mm_struct *mm, \ + type1##_t *arg1, type2##_t *arg2, bool init) \ +@@ -90,6 +94,38 @@ DEFINE_ENTRY(pud, pud, init) + DEFINE_ENTRY(pmd, pmd, init) + DEFINE_ENTRY(pte, pte, init) + ++#ifdef CONFIG_PTP ++#define DEFINE_IEE_POPULATE(fname, type1, type2, init) \ ++static inline void iee_##fname##_init(struct mm_struct *mm, \ ++ type1##_t *arg1, type2##_t *arg2, bool init) \ ++{ \ ++ if (init) \ ++ iee_##fname##_safe_pre_init(mm, arg1, arg2); \ ++ else \ ++ iee_##fname##_pre_init(mm, arg1, arg2); \ ++} ++ ++DEFINE_IEE_POPULATE(p4d_populate, p4d, pud, init) ++DEFINE_IEE_POPULATE(pgd_populate, pgd, p4d, init) ++DEFINE_IEE_POPULATE(pud_populate, pud, pmd, init) ++DEFINE_IEE_POPULATE(pmd_populate_kernel, pmd, pte, init) ++ ++#define DEFINE_IEE_ENTRY(type1, type2, init) \ ++static inline void iee_set_##type1##_init(type1##_t *arg1, \ ++ type2##_t arg2, bool init) \ ++{ \ ++ if (init) \ ++ iee_set_##type1##_safe_pre_init(arg1, arg2); \ ++ else \ ++ iee_set_##type1##_pre_init(arg1, arg2); \ ++} ++ ++DEFINE_IEE_ENTRY(p4d, p4d, init) ++DEFINE_IEE_ENTRY(pud, pud, init) ++DEFINE_IEE_ENTRY(pmd, pmd, init) ++DEFINE_IEE_ENTRY(pte, pte, init) ++#endif ++ + static inline pgprot_t prot_sethuge(pgprot_t prot) + { + WARN_ON_ONCE(pgprot_val(prot) & _PAGE_PAT); +@@ -147,6 +183,9 @@ static void sync_global_pgds_l5(unsigned long start, unsigned long end) + + spin_lock(&pgd_lock); + list_for_each_entry(page, &pgd_list, lru) { ++ #ifdef CONFIG_PTP ++ page = iee_ptdesc_to_page(page); ++ #endif + pgd_t *pgd; + spinlock_t *pgt_lock; + +@@ -188,6 +227,9 @@ static void sync_global_pgds_l4(unsigned long start, unsigned long end) + + spin_lock(&pgd_lock); + list_for_each_entry(page, &pgd_list, lru) { ++ #ifdef CONFIG_PTP ++ page = iee_ptdesc_to_page(page); ++ #endif + pgd_t *pgd; + p4d_t *p4d; + spinlock_t *pgt_lock; +@@ -243,6 +285,11 @@ static __ref void *spp_getpage(void) + + pr_debug("spp_getpage %p\n", ptr); + ++ #ifdef CONFIG_PTP ++ unsigned long iee_addr = (unsigned long)__phys_to_iee(__pa(ptr)); ++ set_iee_page_valid(iee_addr); ++ #endif ++ + return ptr; + } + +@@ -442,7 +489,11 @@ void __init cleanup_highmap(void) + if (pmd_none(*pmd)) + continue; + if (vaddr < (unsigned long) _text || vaddr > end) ++ #ifdef CONFIG_PTP ++ iee_set_pmd_pre_init(pmd, __pmd(0)); ++ #else + set_pmd(pmd, __pmd(0)); ++ #endif + } + } + +@@ -470,7 +521,11 @@ phys_pte_init(pte_t *pte_page, unsigned long paddr, unsigned long paddr_end, + E820_TYPE_RAM) && + !e820__mapped_any(paddr & PAGE_MASK, paddr_next, + E820_TYPE_RESERVED_KERN)) ++ #ifdef CONFIG_PTP ++ iee_set_pte_init(pte, __pte(0), init); ++ #else + set_pte_init(pte, __pte(0), init); ++ #endif + continue; + } + +@@ -490,7 +545,11 @@ phys_pte_init(pte_t *pte_page, unsigned long paddr, unsigned long paddr_end, + pr_info(" pte=%p addr=%lx pte=%016lx\n", pte, paddr, + pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL).pte); + pages++; ++ #ifdef CONFIG_PTP ++ iee_set_pte_init(pte, pfn_pte(paddr >> PAGE_SHIFT, prot), init); ++ #else + set_pte_init(pte, pfn_pte(paddr >> PAGE_SHIFT, prot), init); ++ #endif + paddr_last = (paddr & PAGE_MASK) + PAGE_SIZE; + } + +@@ -525,7 +584,11 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long paddr, unsigned long paddr_end, + E820_TYPE_RAM) && + !e820__mapped_any(paddr & PMD_MASK, paddr_next, + E820_TYPE_RESERVED_KERN)) ++ #ifdef CONFIG_PTP ++ iee_set_pmd_init(pmd, __pmd(0), init); ++ #else + set_pmd_init(pmd, __pmd(0), init); ++ #endif + continue; + } + +@@ -563,9 +626,15 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long paddr, unsigned long paddr_end, + if (page_size_mask & (1<> PAGE_SHIFT, prot_sethuge(prot)), ++ init); ++ #else + set_pmd_init(pmd, + pfn_pmd(paddr >> PAGE_SHIFT, prot_sethuge(prot)), + init); ++ #endif + spin_unlock(&init_mm.page_table_lock); + paddr_last = paddr_next; + continue; +@@ -575,7 +644,11 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long paddr, unsigned long paddr_end, + paddr_last = phys_pte_init(pte, paddr, paddr_end, new_prot, init); + + spin_lock(&init_mm.page_table_lock); ++ #ifdef CONFIG_PTP ++ iee_pmd_populate_kernel_init(&init_mm, pmd, pte, init); ++ #else + pmd_populate_kernel_init(&init_mm, pmd, pte, init); ++ #endif + spin_unlock(&init_mm.page_table_lock); + } + update_page_count(PG_LEVEL_2M, pages); +@@ -612,7 +685,11 @@ phys_pud_init(pud_t *pud_page, unsigned long paddr, unsigned long paddr_end, + E820_TYPE_RAM) && + !e820__mapped_any(paddr & PUD_MASK, paddr_next, + E820_TYPE_RESERVED_KERN)) ++ #ifdef CONFIG_PTP ++ iee_set_pud_init(pud, __pud(0), init); ++ #else + set_pud_init(pud, __pud(0), init); ++ #endif + continue; + } + +@@ -649,9 +726,15 @@ phys_pud_init(pud_t *pud_page, unsigned long paddr, unsigned long paddr_end, + if (page_size_mask & (1<> PAGE_SHIFT, prot_sethuge(prot)), ++ init); ++ #else + set_pud_init(pud, + pfn_pud(paddr >> PAGE_SHIFT, prot_sethuge(prot)), + init); ++ #endif + spin_unlock(&init_mm.page_table_lock); + paddr_last = paddr_next; + continue; +@@ -662,7 +745,11 @@ phys_pud_init(pud_t *pud_page, unsigned long paddr, unsigned long paddr_end, + page_size_mask, prot, init); + + spin_lock(&init_mm.page_table_lock); ++ #ifdef CONFIG_PTP ++ iee_pud_populate_init(&init_mm, pud, pmd, init); ++ #else + pud_populate_init(&init_mm, pud, pmd, init); ++ #endif + spin_unlock(&init_mm.page_table_lock); + } + +@@ -715,7 +802,11 @@ phys_p4d_init(p4d_t *p4d_page, unsigned long paddr, unsigned long paddr_end, + page_size_mask, prot, init); + + spin_lock(&init_mm.page_table_lock); ++ #ifdef CONFIG_PTP ++ iee_p4d_populate_init(&init_mm, p4d, pud, init); ++ #else + p4d_populate_init(&init_mm, p4d, pud, init); ++ #endif + spin_unlock(&init_mm.page_table_lock); + } + +@@ -757,10 +848,19 @@ __kernel_physical_mapping_init(unsigned long paddr_start, + + spin_lock(&init_mm.page_table_lock); + if (pgtable_l5_enabled()) ++ #ifdef CONFIG_PTP ++ iee_pgd_populate_init(&init_mm, pgd, p4d, init); ++ #else + pgd_populate_init(&init_mm, pgd, p4d, init); ++ #endif + else ++ #ifdef CONFIG_PTP ++ iee_p4d_populate_init(&init_mm, p4d_offset(pgd, vaddr), ++ (pud_t *) p4d, init); ++ #else + p4d_populate_init(&init_mm, p4d_offset(pgd, vaddr), + (pud_t *) p4d, init); ++ #endif + + spin_unlock(&init_mm.page_table_lock); + pgd_changed = true; +@@ -788,6 +888,118 @@ kernel_physical_mapping_init(unsigned long paddr_start, + page_size_mask, prot, true); + } + ++#ifdef CONFIG_IEE ++static unsigned long __meminit ++__kernel_physical_mapping_init_for_iee(unsigned long paddr_start, ++ unsigned long paddr_end, ++ unsigned long page_size_mask, ++ pgprot_t prot, bool init) ++{ ++ bool pgd_changed = false; ++ unsigned long vaddr, vaddr_start, vaddr_end, vaddr_next, paddr_last; ++ paddr_last = paddr_end; ++ vaddr = (unsigned long)__phys_to_iee(paddr_start); ++ vaddr_end = (unsigned long)__phys_to_iee(paddr_end); ++ vaddr_start = vaddr; ++ for (; vaddr < vaddr_end; vaddr = vaddr_next) { ++ pgd_t *pgd = pgd_offset_k(vaddr); ++ p4d_t *p4d; ++ vaddr_next = (vaddr & PGDIR_MASK) + PGDIR_SIZE; ++ if (pgd_val(*pgd)) { ++ p4d = (p4d_t *)pgd_page_vaddr(*pgd); ++ paddr_last = phys_p4d_init(p4d, __iee_pa(vaddr), ++ __iee_pa(vaddr_end), ++ page_size_mask, prot, init); ++ continue; ++ } ++ p4d = alloc_low_page(); ++ paddr_last = phys_p4d_init(p4d, __iee_pa(vaddr), ++ __iee_pa(vaddr_end), ++ page_size_mask, prot, init); ++ spin_lock(&init_mm.page_table_lock); ++ if (pgtable_l5_enabled()) ++ #ifdef CONFIG_PTP ++ iee_pgd_populate_init(&init_mm, pgd, p4d, init); ++ #else ++ pgd_populate_init(&init_mm, pgd, p4d, init); ++ #endif ++ else ++ #ifdef CONFIG_PTP ++ iee_p4d_populate_init(&init_mm, p4d_offset(pgd, vaddr), ++ (pud_t *) p4d, init); ++ #else ++ p4d_populate_init(&init_mm, p4d_offset(pgd, vaddr), ++ (pud_t *) p4d, init); ++ #endif ++ spin_unlock(&init_mm.page_table_lock); ++ pgd_changed = true; ++ } ++ if (pgd_changed) ++ sync_global_pgds(vaddr_start, vaddr_end - 1); ++ return paddr_last; ++} ++unsigned long __meminit ++kernel_physical_mapping_init_for_iee(unsigned long paddr_start, ++ unsigned long paddr_end, ++ unsigned long page_size_mask, pgprot_t prot) ++{ ++ return __kernel_physical_mapping_init_for_iee(paddr_start, paddr_end, ++ page_size_mask, prot, true); ++} ++#else ++#ifdef CONFIG_KOI ++static unsigned long __meminit ++__kernel_physical_mapping_init_for_koi(unsigned long paddr_start, ++ unsigned long paddr_end, ++ unsigned long page_size_mask, ++ pgprot_t prot, bool init) ++{ ++ bool pgd_changed = false; ++ unsigned long vaddr, vaddr_start, vaddr_end, vaddr_next, paddr_last; ++ paddr_last = paddr_end; ++ vaddr = (unsigned long)__phys_to_koi(paddr_start); ++ vaddr_end = (unsigned long)__phys_to_koi(paddr_end); ++ vaddr_start = vaddr; ++ for (; vaddr < vaddr_end; vaddr = vaddr_next) { ++ pgd_t *pgd = pgd_offset_k(vaddr); ++ p4d_t *p4d; ++ vaddr_next = (vaddr & PGDIR_MASK) + PGDIR_SIZE; ++ if (pgd_val(*pgd)) { ++ p4d = (p4d_t *)pgd_page_vaddr(*pgd); ++ paddr_last = phys_p4d_init(p4d, __koi_pa(vaddr), ++ __koi_pa(vaddr_end), ++ page_size_mask, prot, init); ++ continue; ++ } ++ p4d = alloc_low_page(); ++ paddr_last = phys_p4d_init(p4d, __koi_pa(vaddr), ++ __koi_pa(vaddr_end), ++ page_size_mask, prot, init); ++ spin_lock(&init_mm.page_table_lock); ++ if (pgtable_l5_enabled()) ++ pgd_populate_init(&init_mm, pgd, p4d, init); ++ else ++ p4d_populate_init(&init_mm, p4d_offset(pgd, vaddr), ++ (pud_t *) p4d, init); ++ spin_unlock(&init_mm.page_table_lock); ++ pgd_changed = true; ++ } ++ if (pgd_changed) ++ sync_global_pgds(vaddr_start, vaddr_end - 1); ++ return paddr_last; ++} ++unsigned long __meminit ++kernel_physical_mapping_init_for_koi(unsigned long paddr_start, ++ unsigned long paddr_end, ++ unsigned long page_size_mask, pgprot_t prot) ++{ ++ return __kernel_physical_mapping_init_for_koi(paddr_start, paddr_end, ++ page_size_mask, prot, true); ++} ++ ++#endif ++#endif /* CONFIG_IEE*/ ++ + /* + * This function is similar to kernel_physical_mapping_init() above with the + * exception that it uses set_{pud,pmd}() instead of the set_{pud,pte}_safe() +@@ -811,6 +1023,131 @@ void __init initmem_init(void) + } + #endif + ++#ifdef CONFIG_PTP ++static void * __init iee_ptdesc_alloc_block_zero(unsigned long size, int node, bool is_pgtable) ++{ ++ // void *p = memblock_alloc_try_nid_raw(size, size, __pa(MAX_DMA_ADDRESS), ++ // MEMBLOCK_ALLOC_ACCESSIBLE, node); ++ void *p = alloc_low_page(); ++ ++ if (!p) ++ return NULL; ++ memset(p, 0, size); ++ ++ if (is_pgtable) ++ set_iee_page_valid((unsigned long)__phys_to_iee(__pa(p))); ++ ++ return p; ++} ++ ++static pte_t * __init iee_ptdesc_pte_populate(pmd_t *pmd, unsigned long addr, int node) ++{ ++ pte_t *pte = pte_offset_kernel(pmd, addr); ++ if (pte_none(*pte)) { ++ void *p = iee_ptdesc_alloc_block_zero(PAGE_SIZE, node, false); ++ if (!p) ++ return NULL; ++ ++ pte_t entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL); ++ set_pte_at(&init_mm, addr, pte, entry); ++ } ++ return pte; ++} ++ ++static pmd_t * __init iee_ptdesc_pmd_populate(pud_t *pud, unsigned long addr, int node) ++{ ++ pmd_t *pmd = pmd_offset(pud, addr); ++ if (pmd_none(*pmd)) { ++ void *p = iee_ptdesc_alloc_block_zero(PAGE_SIZE, node, true); ++ if (!p) ++ return NULL; ++ pmd_populate_kernel(&init_mm, pmd, p); ++ } ++ return pmd; ++} ++ ++static pud_t * __init iee_ptdesc_pud_populate(p4d_t *p4d, unsigned long addr, int node) ++{ ++ pud_t *pud = pud_offset(p4d, addr); ++ if (pud_none(*pud)) { ++ void *p = iee_ptdesc_alloc_block_zero(PAGE_SIZE, node, true); ++ if (!p) ++ return NULL; ++ pud_populate(&init_mm, pud, p); ++ } ++ return pud; ++} ++ ++static p4d_t * __init iee_ptdesc_p4d_populate(pgd_t *pgd, unsigned long addr, int node) ++{ ++ p4d_t *p4d = p4d_offset(pgd, addr); ++ if (p4d_none(*p4d)) { ++ void *p = iee_ptdesc_alloc_block_zero(PAGE_SIZE, node, true); ++ if (!p) ++ return NULL; ++ p4d_populate(&init_mm, p4d, p); ++ } ++ return p4d; ++} ++ ++static pgd_t * __init iee_ptdesc_pgd_populate(unsigned long addr, int node) ++{ ++ pgd_t *pgd = pgd_offset_k(addr); ++ if (pgd_none(*pgd)) { ++ void *p = iee_ptdesc_alloc_block_zero(PAGE_SIZE, node, true); ++ if (!p) ++ return NULL; ++ pgd_populate(&init_mm, pgd, p); ++ } ++ return pgd; ++} ++ ++static pte_t * __init iee_ptdesc_populate(unsigned long addr) ++{ ++ pgd_t *pgd; ++ p4d_t *p4d; ++ pud_t *pud; ++ pmd_t *pmd; ++ pte_t *pte; ++ int node = NUMA_NO_NODE; ++ ++ pgd = iee_ptdesc_pgd_populate(addr, node); ++ if (!pgd) ++ return NULL; ++ p4d = iee_ptdesc_p4d_populate(pgd, addr, node); ++ if (!p4d) ++ return NULL; ++ pud = iee_ptdesc_pud_populate(p4d, addr, node); ++ if (!pud) ++ return NULL; ++ pmd = iee_ptdesc_pmd_populate(pud, addr, node); ++ if (!pmd) ++ return NULL; ++ pte = iee_ptdesc_pte_populate(pmd, addr, node); ++ return pte; ++} ++ ++int __init iee_ptdesc_sparse_init(void) ++{ ++ unsigned long start_pfn, end_pfn; ++ int i, nid; ++ for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid) { ++ // pr_err("IEE: start_pfn, end_pfn = %lx, %lx", start_pfn, end_pfn); ++ u64 ptdesc_start = ALIGN_DOWN((u64)(__pfn_to_ptdesc(start_pfn)), PAGE_SIZE); ++ u64 end = ALIGN_DOWN((u64)(__pfn_to_ptdesc(end_pfn)), PAGE_SIZE); ++ unsigned long addr = ptdesc_start; ++ pte_t *pte; ++ for (; addr < end; addr += PAGE_SIZE) { ++ // pr_err("IEE: addr = %lx", addr); ++ pte = iee_ptdesc_populate(addr); ++ if (!pte) ++ return -ENOMEM; ++ } ++ } ++ return 0; ++} ++#endif ++ + void __init paging_init(void) + { + sparse_init(); +@@ -824,6 +1161,10 @@ void __init paging_init(void) + node_clear_state(0, N_MEMORY); + node_clear_state(0, N_NORMAL_MEMORY); + ++ #ifdef CONFIG_PTP ++ iee_ptdesc_sparse_init(); ++ #endif ++ + zone_sizes_init(); + } + +diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c +index aa7d279321ea..dc0f4f13a0c6 100644 +--- a/arch/x86/mm/ioremap.c ++++ b/arch/x86/mm/ioremap.c +@@ -888,7 +888,11 @@ void __init early_ioremap_init(void) + + pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)); + memset(bm_pte, 0, sizeof(bm_pte)); ++ #ifdef CONFIG_PTP ++ iee_pmd_populate_kernel_pre_init(&init_mm, pmd, bm_pte); ++ #else + pmd_populate_kernel(&init_mm, pmd, bm_pte); ++ #endif + + /* + * The boot-ioremap range spans multiple pmds, for which +@@ -929,8 +933,41 @@ void __init __early_set_fixmap(enum fixed_addresses idx, + pgprot_val(flags) &= __supported_pte_mask; + + if (pgprot_val(flags)) ++ #ifdef CONFIG_PTP ++ iee_set_pte_pre_init(pte, pfn_pte(phys >> PAGE_SHIFT, flags)); ++ #else + set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, flags)); ++ #endif + else ++ #ifdef CONFIG_PTP ++ iee_set_pte_pre_init(pte, __pte(0)); ++ #else + pte_clear(&init_mm, addr, pte); ++ #endif + flush_tlb_one_kernel(addr); + } ++ ++#ifdef CONFIG_PTP ++void __init __iee_set_fixmap_pre_init(enum fixed_addresses idx, ++ phys_addr_t phys, pgprot_t flags) ++{ ++ unsigned long addr = __fix_to_virt(idx); ++ pte_t *pte; ++ ++ if (idx >= __end_of_fixed_addresses) { ++ BUG(); ++ return; ++ } ++ pte = early_ioremap_pte(addr); ++ ++ /* Sanitize 'prot' against any unsupported bits: */ ++ pgprot_val(flags) &= __supported_pte_mask; ++ ++ if (pgprot_val(flags)) ++ iee_set_pte_pre_init(pte, pfn_pte(phys >> PAGE_SHIFT, flags)); ++ else ++ iee_set_pte_pre_init(pte, __pte(0)); ++ // pte_clear(&init_mm, addr, pte); ++ flush_tlb_one_kernel(addr); ++} ++#endif +diff --git a/arch/x86/mm/kaslr.c b/arch/x86/mm/kaslr.c +index 230f1dee4f09..02d50f42b88c 100644 +--- a/arch/x86/mm/kaslr.c ++++ b/arch/x86/mm/kaslr.c +@@ -156,6 +156,22 @@ void __init kernel_randomize_memory(void) + vaddr = round_up(vaddr + 1, PUD_SIZE); + remain_entropy -= entropy; + } ++ ++ #ifdef CONFIG_IEE ++ extern unsigned long iee_offset; ++ extern unsigned long IEE_OFFSET; ++ iee_offset = *kaslr_regions[0].base - vaddr_start + IEE_OFFSET; ++ #else ++ extern unsigned long koi_offset; ++ extern unsigned long KOI_OFFSET; ++ koi_offset = *kaslr_regions[0].base - vaddr_start + KOI_OFFSET; ++ #endif /* CONFIG_IEE*/ ++ ++ #ifdef CONFIG_PTP ++ unsigned long *iee_ptdesc_kaslr_base = &iee_ptdesc_base; ++ *iee_ptdesc_kaslr_base = *kaslr_regions[2].base + (kaslr_regions[2].size_tb << TB_SHIFT); ++ pr_err("IEE: ptdesc base with kaslr: %lx\n", iee_ptdesc_base); ++ #endif + } + + void __meminit init_trampoline_kaslr(void) +diff --git a/arch/x86/mm/mm_internal.h b/arch/x86/mm/mm_internal.h +index 3f37b5c80bb3..2dc3f96fbc26 100644 +--- a/arch/x86/mm/mm_internal.h ++++ b/arch/x86/mm/mm_internal.h +@@ -14,6 +14,15 @@ unsigned long kernel_physical_mapping_init(unsigned long start, + unsigned long end, + unsigned long page_size_mask, + pgprot_t prot); ++#ifdef CONFIG_IEE ++unsigned long kernel_physical_mapping_init_for_iee(unsigned long paddr_start, ++ unsigned long paddr_end, ++ unsigned long page_size_mask, pgprot_t prot); ++#else ++unsigned long kernel_physical_mapping_init_for_koi(unsigned long paddr_start, ++ unsigned long paddr_end, ++ unsigned long page_size_mask, pgprot_t prot); ++#endif /* CONFIG_IEE*/ + unsigned long kernel_physical_mapping_change(unsigned long start, + unsigned long end, + unsigned long page_size_mask); +diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c +index 2d850f6bae70..067e3195782d 100644 +--- a/arch/x86/mm/pat/set_memory.c ++++ b/arch/x86/mm/pat/set_memory.c +@@ -37,6 +37,10 @@ + + #include "../mm_internal.h" + ++#ifdef CONFIG_PTP ++#include ++#endif ++ + /* + * The current flushing context - we pass it instead of 5 arguments: + */ +@@ -841,6 +845,9 @@ static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) + struct page *page; + + list_for_each_entry(page, &pgd_list, lru) { ++ #ifdef CONFIG_PTP ++ page = iee_ptdesc_to_page(page); ++ #endif + pgd_t *pgd; + p4d_t *p4d; + pud_t *pud; +@@ -1151,7 +1158,32 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address, + * pagetable protections, the actual ptes set above control the + * primary protection behavior: + */ ++ #ifdef CONFIG_PTP ++ set_pmd((pmd_t *)kpte, __pmd(pte_val(mk_pte(base, __pgprot(_KERNPG_TABLE))))); ++ #ifdef CONFIG_X86_32 ++ if (!SHARED_KERNEL_PMD) { ++ struct page *page; ++ ++ list_for_each_entry(page, &pgd_list, lru) { ++ #ifdef CONFIG_PTP ++ page = iee_ptdesc_to_page(page); ++ #endif ++ pgd_t *pgd; ++ p4d_t *p4d; ++ pud_t *pud; ++ pmd_t *pmd; ++ ++ pgd = (pgd_t *)page_address(page) + pgd_index(address); ++ p4d = p4d_offset(pgd, address); ++ pud = pud_offset(p4d, address); ++ pmd = pmd_offset(pud, address); ++ set_pmd(pmd, mk_pmd(base, __pgprot(_KERNPG_TABLE))); ++ } ++ } ++ #endif ++ #else + __set_pmd_pte(kpte, address, mk_pte(base, __pgprot(_KERNPG_TABLE))); ++ #endif + + /* + * Do a global flush tlb after splitting the large page +@@ -1181,17 +1213,33 @@ static int split_large_page(struct cpa_data *cpa, pte_t *kpte, + unsigned long address) + { + struct page *base; ++ #ifdef CONFIG_PTP ++ pte_t *pbase; ++ #endif + + if (!debug_pagealloc_enabled()) + spin_unlock(&cpa_lock); ++ ++ #ifdef CONFIG_PTP ++ /* without gfp_zero mask, set_pte cannot pass privilege check*/ ++ base = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0); ++ pbase = (pte_t *)page_address(base); ++ set_iee_page((unsigned long)pbase, 0); ++ #else + base = alloc_pages(GFP_KERNEL, 0); ++ #endif ++ + if (!debug_pagealloc_enabled()) + spin_lock(&cpa_lock); + if (!base) + return -ENOMEM; + +- if (__split_large_page(cpa, kpte, address, base)) ++ if (__split_large_page(cpa, kpte, address, base)) { ++ #ifdef CONFIG_PTP ++ unset_iee_page((unsigned long)pbase, 0); ++ #endif + __free_page(base); ++ } + + return 0; + } +@@ -1204,7 +1252,11 @@ static bool try_to_free_pte_page(pte_t *pte) + if (!pte_none(pte[i])) + return false; + ++ #ifdef CONFIG_PTP ++ free_iee_pgtable_page(pte); ++ #else + free_page((unsigned long)pte); ++ #endif + return true; + } + +@@ -1339,6 +1391,10 @@ static int alloc_pte_page(pmd_t *pmd) + if (!pte) + return -1; + ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)pte, 0); ++ #endif ++ + set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE)); + return 0; + } +@@ -1348,6 +1404,10 @@ static int alloc_pmd_page(pud_t *pud) + pmd_t *pmd = (pmd_t *)get_zeroed_page(GFP_KERNEL); + if (!pmd) + return -1; ++ ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)pmd, 0); ++ #endif + + set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE)); + return 0; +@@ -1542,6 +1602,10 @@ static int populate_pgd(struct cpa_data *cpa, unsigned long addr) + p4d = (p4d_t *)get_zeroed_page(GFP_KERNEL); + if (!p4d) + return -1; ++ ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)p4d, 0); ++ #endif + + set_pgd(pgd_entry, __pgd(__pa(p4d) | _KERNPG_TABLE)); + } +@@ -1554,7 +1618,11 @@ static int populate_pgd(struct cpa_data *cpa, unsigned long addr) + pud = (pud_t *)get_zeroed_page(GFP_KERNEL); + if (!pud) + return -1; +- ++ ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)pud, 0); ++ #endif ++ + set_p4d(p4d, __p4d(__pa(pud) | _KERNPG_TABLE)); + } + +diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c +index 8e1ef5345b7a..5ee71c7282ed 100644 +--- a/arch/x86/mm/pgtable.c ++++ b/arch/x86/mm/pgtable.c +@@ -7,6 +7,12 @@ + #include + #include + ++#ifdef CONFIG_PTP ++#include ++#include ++#include ++#endif ++ + #ifdef CONFIG_DYNAMIC_PHYSICAL_MASK + phys_addr_t physical_mask __ro_after_init = (1ULL << __PHYSICAL_MASK_SHIFT) - 1; + EXPORT_SYMBOL(physical_mask); +@@ -94,14 +100,22 @@ static inline void pgd_list_add(pgd_t *pgd) + { + struct ptdesc *ptdesc = virt_to_ptdesc(pgd); + ++ #ifdef CONFIG_PTP ++ list_add(&(iee_ptdesc(ptdesc)->pt_list), &pgd_list); ++ #else + list_add(&ptdesc->pt_list, &pgd_list); ++ #endif + } + + static inline void pgd_list_del(pgd_t *pgd) + { + struct ptdesc *ptdesc = virt_to_ptdesc(pgd); + ++ #ifdef CONFIG_PTP ++ list_del(&(iee_ptdesc(ptdesc)->pt_list)); ++ #else + list_del(&ptdesc->pt_list); ++ #endif + } + + #define UNSHARED_PTRS_PER_PGD \ +@@ -112,12 +126,22 @@ static inline void pgd_list_del(pgd_t *pgd) + + static void pgd_set_mm(pgd_t *pgd, struct mm_struct *mm) + { ++ #ifdef CONFIG_PTP ++ struct ptdesc *ptdesc = virt_to_ptdesc(pgd); ++ (iee_ptdesc(ptdesc))->pt_mm = mm; ++ #else + virt_to_ptdesc(pgd)->pt_mm = mm; ++ #endif + } + + struct mm_struct *pgd_page_get_mm(struct page *page) + { ++ #ifdef CONFIG_PTP ++ struct ptdesc *ptdesc = page_ptdesc(page); ++ return (iee_ptdesc(ptdesc))->pt_mm; ++ #else + return page_ptdesc(page)->pt_mm; ++ #endif + } + + static void pgd_ctor(struct mm_struct *mm, pgd_t *pgd) +@@ -417,16 +441,44 @@ static inline void _pgd_free(pgd_t *pgd) + + static inline pgd_t *_pgd_alloc(void) + { ++ #ifdef CONFIG_PTP ++ return (pgd_t *)get_iee_pgd_page(GFP_PGTABLE_USER); ++ #else + return (pgd_t *)__get_free_pages(GFP_PGTABLE_USER, + PGD_ALLOCATION_ORDER); ++ #endif + } + + static inline void _pgd_free(pgd_t *pgd) + { ++ #ifdef CONFIG_PTP ++ struct page *page = virt_to_page((void *)pgd); ++ #if PGD_ALLOCATION_ORDER == 1 ++ page = virt_to_page((unsigned long)pgd + PAGE_SIZE); ++ #endif ++ free_iee_pgd_page(pgd); ++ #else + free_pages((unsigned long)pgd, PGD_ALLOCATION_ORDER); ++ #endif + } + #endif /* CONFIG_X86_PAE */ + ++#ifdef CONFIG_KOI ++pgd_t *koi_pgd_alloc(void) ++{ ++ pgd_t *pgd; ++#ifdef CONFIG_PTP ++ pgd = (pgd_t *)__get_free_page(GFP_PGTABLE_KERNEL); ++ unsigned long iee_addr = (unsigned long)__phys_to_iee(__pa(pgd)); ++ set_iee_page_valid(iee_addr); ++ iee_set_logical_mem_ro((unsigned long)pgd); ++#else ++ pgd = (pgd_t *)__get_free_page(GFP_PGTABLE_KERNEL); ++#endif ++ return pgd; ++} ++#endif ++ + pgd_t *pgd_alloc(struct mm_struct *mm) + { + pgd_t *pgd; +@@ -557,8 +609,13 @@ int ptep_test_and_clear_young(struct vm_area_struct *vma, + int ret = 0; + + if (pte_young(*ptep)) ++ #ifdef CONFIG_PTP ++ ret = iee_test_and_clear_bit(_PAGE_BIT_ACCESSED, ++ (unsigned long *) &ptep->pte); ++ #else + ret = test_and_clear_bit(_PAGE_BIT_ACCESSED, + (unsigned long *) &ptep->pte); ++ #endif + + return ret; + } +@@ -570,8 +627,13 @@ int pmdp_test_and_clear_young(struct vm_area_struct *vma, + int ret = 0; + + if (pmd_young(*pmdp)) ++ #ifdef CONFIG_PTP ++ ret = iee_test_and_clear_bit(_PAGE_BIT_ACCESSED, ++ (unsigned long *)pmdp); ++ #else + ret = test_and_clear_bit(_PAGE_BIT_ACCESSED, + (unsigned long *)pmdp); ++ #endif + + return ret; + } +@@ -584,8 +646,13 @@ int pudp_test_and_clear_young(struct vm_area_struct *vma, + int ret = 0; + + if (pud_young(*pudp)) ++ #ifdef CONFIG_PTP ++ ret = iee_test_and_clear_bit(_PAGE_BIT_ACCESSED, ++ (unsigned long *)pudp); ++ #else + ret = test_and_clear_bit(_PAGE_BIT_ACCESSED, + (unsigned long *)pudp); ++ #endif + + return ret; + } +@@ -833,7 +900,11 @@ int pud_free_pmd_page(pud_t *pud, unsigned long addr) + for (i = 0; i < PTRS_PER_PMD; i++) { + if (!pmd_none(pmd_sv[i])) { + pte = (pte_t *)pmd_page_vaddr(pmd_sv[i]); ++ #ifdef CONFIG_PTP ++ free_iee_pgtable_page(pte); ++ #else + free_page((unsigned long)pte); ++ #endif + } + } + +@@ -863,7 +934,11 @@ int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) + /* INVLPG to clear all paging-structure caches */ + flush_tlb_kernel_range(addr, addr + PAGE_SIZE-1); + ++ #ifdef CONFIG_PTP ++ free_iee_pgtable_page(pte); ++ #else + free_page((unsigned long)pte); ++ #endif + + return 1; + } +diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c +index 83a6bdf0b498..759da9856751 100644 +--- a/arch/x86/mm/pti.c ++++ b/arch/x86/mm/pti.c +@@ -39,6 +39,10 @@ + #include + #include + ++#ifdef CONFIG_PTP ++#include ++#endif ++ + #undef pr_fmt + #define pr_fmt(fmt) "Kernel/User page tables isolation: " fmt + +@@ -139,7 +143,11 @@ pgd_t __pti_set_user_pgtbl(pgd_t *pgdp, pgd_t pgd) + * The user page tables get the full PGD, accessible from + * userspace: + */ ++ #ifdef CONFIG_PTP ++ iee_rw_gate(IEE_OP_SET_PGD, kernel_to_user_pgdp(pgdp), pgd); ++ #else + kernel_to_user_pgdp(pgdp)->pgd = pgd.pgd; ++ #endif + + /* + * If this is normal user memory, make it NX in the kernel +@@ -182,6 +190,10 @@ static p4d_t *pti_user_pagetable_walk_p4d(unsigned long address) + unsigned long new_p4d_page = __get_free_page(gfp); + if (WARN_ON_ONCE(!new_p4d_page)) + return NULL; ++ ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)new_p4d_page, 0); ++ #endif + + set_pgd(pgd, __pgd(_KERNPG_TABLE | __pa(new_p4d_page))); + } +@@ -211,6 +223,10 @@ static pmd_t *pti_user_pagetable_walk_pmd(unsigned long address) + unsigned long new_pud_page = __get_free_page(gfp); + if (WARN_ON_ONCE(!new_pud_page)) + return NULL; ++ ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)new_pud_page, 0); ++ #endif + + set_p4d(p4d, __p4d(_KERNPG_TABLE | __pa(new_pud_page))); + } +@@ -225,6 +241,10 @@ static pmd_t *pti_user_pagetable_walk_pmd(unsigned long address) + unsigned long new_pmd_page = __get_free_page(gfp); + if (WARN_ON_ONCE(!new_pmd_page)) + return NULL; ++ ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)new_pmd_page, 0); ++ #endif + + set_pud(pud, __pud(_KERNPG_TABLE | __pa(new_pmd_page))); + } +@@ -266,6 +286,10 @@ static pte_t *pti_user_pagetable_walk_pte(unsigned long address, bool late_text) + unsigned long new_pte_page = __get_free_page(gfp); + if (!new_pte_page) + return NULL; ++ ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)new_pte_page, 0); ++ #endif + + set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(new_pte_page))); + } +@@ -292,7 +316,11 @@ static void __init pti_setup_vsyscall(void) + if (WARN_ON(!target_pte)) + return; + ++ #ifdef CONFIG_PTP ++ set_pte(target_pte, *pte); ++ #else + *target_pte = *pte; ++ #endif + set_vsyscall_pgtable_user_bits(kernel_to_user_pgdp(swapper_pg_dir)); + } + #else +@@ -370,14 +398,22 @@ pti_clone_pgtable(unsigned long start, unsigned long end, + * code that only set this bit when supported. + */ + if (boot_cpu_has(X86_FEATURE_PGE)) ++ #ifdef CONFIG_PTP ++ set_pmd(pmd, pmd_set_flags(*pmd, _PAGE_GLOBAL)); ++ #else + *pmd = pmd_set_flags(*pmd, _PAGE_GLOBAL); ++ #endif + + /* + * Copy the PMD. That is, the kernelmode and usermode + * tables will share the last-level page tables of this + * address range + */ ++ #ifdef CONFIG_PTP ++ set_pmd(target_pmd, *pmd); ++ #else + *target_pmd = *pmd; ++ #endif + + addr = round_up(addr + 1, PMD_SIZE); + +@@ -401,10 +437,18 @@ pti_clone_pgtable(unsigned long start, unsigned long end, + + /* Set GLOBAL bit in both PTEs */ + if (boot_cpu_has(X86_FEATURE_PGE)) ++ #ifdef CONFIG_PTP ++ set_pte(pte, pte_set_flags(*pte, _PAGE_GLOBAL)); ++ #else + *pte = pte_set_flags(*pte, _PAGE_GLOBAL); ++ #endif + + /* Clone the PTE */ ++ #ifdef CONFIG_PTP ++ set_pte(target_pte, *pte); ++ #else + *target_pte = *pte; ++ #endif + + addr = round_up(addr + 1, PAGE_SIZE); + +@@ -430,7 +474,11 @@ static void __init pti_clone_p4d(unsigned long addr) + + kernel_pgd = pgd_offset_k(addr); + kernel_p4d = p4d_offset(kernel_pgd, addr); ++ #ifdef CONFIG_PTP ++ set_p4d(user_p4d, *kernel_p4d); ++ #else + *user_p4d = *kernel_p4d; ++ #endif + } + + /* +@@ -461,7 +509,11 @@ static void __init pti_clone_user_shared(void) + if (WARN_ON(!target_pte)) + return; + ++ #ifdef CONFIG_PTP ++ set_pte(target_pte, pfn_pte(pa >> PAGE_SHIFT, PAGE_KERNEL)); ++ #else + *target_pte = pfn_pte(pa >> PAGE_SHIFT, PAGE_KERNEL); ++ #endif + } + } + +diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c +index d61f04743aad..5196ddd91e22 100644 +--- a/arch/x86/net/bpf_jit_comp.c ++++ b/arch/x86/net/bpf_jit_comp.c +@@ -16,6 +16,9 @@ + #include + #include + #include ++#ifdef CONFIG_HIVE ++#include ++#endif + + static u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len) + { +@@ -53,6 +56,11 @@ static u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len) + #define EMIT_ENDBR() + #endif + ++#ifdef CONFIG_HIVE ++static void emit_mov_imm64(u8 **pprog, u32 dst_reg, ++ const u32 imm32_hi, const u32 imm32_lo); ++#endif ++ + static bool is_imm8(int value) + { + return value <= 127 && value >= -128; +@@ -183,6 +191,9 @@ static const int reg2hex[] = { + [BPF_REG_AX] = 2, /* R10 temp register */ + [AUX_REG] = 3, /* R11 temp register */ + [X86_REG_R9] = 1, /* R9 register, 6th function argument */ ++#ifdef CONFIG_HIVE ++ [BPF_REG_BASE] = 4, /* R12 callee saved */ ++#endif + }; + + static const int reg2pt_regs[] = { +@@ -205,6 +216,16 @@ static const int reg2pt_regs[] = { + */ + static bool is_ereg(u32 reg) + { ++#ifdef CONFIG_HIVE ++ return (1 << reg) & (BIT(BPF_REG_5) | ++ BIT(AUX_REG) | ++ BIT(BPF_REG_7) | ++ BIT(BPF_REG_8) | ++ BIT(BPF_REG_9) | ++ BIT(X86_REG_R9) | ++ BIT(BPF_REG_AX) | ++ BIT(BPF_REG_BASE)); ++#else + return (1 << reg) & (BIT(BPF_REG_5) | + BIT(AUX_REG) | + BIT(BPF_REG_7) | +@@ -212,6 +233,7 @@ static bool is_ereg(u32 reg) + BIT(BPF_REG_9) | + BIT(X86_REG_R9) | + BIT(BPF_REG_AX)); ++#endif + } + + /* +@@ -371,6 +393,26 @@ static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf, + *pprog = prog; + } + ++#ifdef CONFIG_HIVE ++static void emit_sfi_prologue(u8 **pprog, struct bpf_prog *bpf_prog) ++{ ++ u8 *prog = *pprog; ++ u64 base_addr, stack_addr; ++ ++ /* assign addr to base and rsp */ ++ EMIT2(0x41, 0x54); /* push %r12 */ ++ EMIT1(0x55); /* push %rbp */ ++ ++ base_addr = (u64)bpf_prog->shadow_region_addr; ++ emit_mov_imm64(&prog, BPF_REG_BASE, (u32)(base_addr >> 32), (u32)base_addr); ++ ++ stack_addr = (u64)bpf_prog->shadow_stack_addr; ++ emit_mov_imm64(&prog, BPF_REG_FP, (u32)(stack_addr >> 32), (u32)stack_addr); ++ ++ *pprog = prog; ++} ++#endif ++ + static int emit_patch(u8 **pprog, void *func, void *ip, u8 opcode) + { + u8 *prog = *pprog; +@@ -503,6 +545,18 @@ static void emit_return(u8 **pprog, u8 *ip) + *pprog = prog; + } + ++#ifdef CONFIG_HIVE ++static void emit_sfi_epilogue(u8 **pprog) ++{ ++ u8 *prog = *pprog; ++ ++ EMIT1(0x5d); /* pop %rbp */ ++ EMIT2(0x41, 0x5c); /* pop %r12 */ ++ ++ *pprog = prog; ++} ++#endif ++ + /* + * Generate the following code: + * +@@ -1097,6 +1151,10 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image + bpf_prog_was_classic(bpf_prog), tail_call_reachable, + bpf_prog->aux->func_idx != 0); + push_callee_regs(&prog, callee_regs_used); ++#ifdef CONFIG_HIVE ++ if (bpf_prog->aux->func_idx == 0) // not subprog ++ emit_sfi_prologue(&prog, bpf_prog); ++#endif + + ilen = prog - temp; + if (rw_image) +@@ -1945,6 +2003,10 @@ st: if (is_imm8(insn->off)) + seen_exit = true; + /* Update cleanup_addr */ + ctx->cleanup_addr = proglen; ++#ifdef CONFIG_HIVE ++ if (bpf_prog->aux->func_idx == 0) // not sub_prog ++ emit_sfi_epilogue(&prog); ++#endif + pop_callee_regs(&prog, callee_regs_used); + EMIT1(0xC9); /* leave */ + emit_return(&prog, image + addrs[i - 1] + (prog - temp)); +diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c +index 91d31ac422d6..e7c782f0cde5 100644 +--- a/arch/x86/platform/efi/efi_64.c ++++ b/arch/x86/platform/efi/efi_64.c +@@ -49,6 +49,10 @@ + #include + #include + ++#ifdef CONFIG_PTP ++#include ++#endif ++ + /* + * We allocate runtime services regions top-down, starting from -4G, i.e. + * 0xffff_ffff_0000_0000 and limit EFI VA mapping space to 64G. +@@ -74,6 +78,11 @@ int __init efi_alloc_page_tables(void) + + gfp_mask = GFP_KERNEL | __GFP_ZERO; + efi_pgd = (pgd_t *)__get_free_pages(gfp_mask, PGD_ALLOCATION_ORDER); ++ ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)efi_pgd, PGD_ALLOCATION_ORDER); ++ #endif ++ + if (!efi_pgd) + goto fail; + +@@ -116,7 +125,11 @@ void efi_sync_low_kernel_mappings(void) + pgd_k = pgd_offset_k(PAGE_OFFSET); + + num_entries = pgd_index(EFI_VA_END) - pgd_index(PAGE_OFFSET); ++ #ifdef CONFIG_PTP ++ iee_memcpy(pgd_efi, pgd_k, sizeof(pgd_t) * num_entries); ++ #else + memcpy(pgd_efi, pgd_k, sizeof(pgd_t) * num_entries); ++ #endif + + pgd_efi = efi_pgd + pgd_index(EFI_VA_END); + pgd_k = pgd_offset_k(EFI_VA_END); +@@ -124,7 +137,11 @@ void efi_sync_low_kernel_mappings(void) + p4d_k = p4d_offset(pgd_k, 0); + + num_entries = p4d_index(EFI_VA_END); ++ #ifdef CONFIG_PTP ++ iee_memcpy(p4d_efi, p4d_k, sizeof(p4d_t) * num_entries); ++ #else + memcpy(p4d_efi, p4d_k, sizeof(p4d_t) * num_entries); ++ #endif + + /* + * We share all the PUD entries apart from those that map the +@@ -139,13 +156,21 @@ void efi_sync_low_kernel_mappings(void) + pud_k = pud_offset(p4d_k, 0); + + num_entries = pud_index(EFI_VA_END); ++ #ifdef CONFIG_PTP ++ iee_memcpy(pud_efi, pud_k, sizeof(pud_t) * num_entries); ++ #else + memcpy(pud_efi, pud_k, sizeof(pud_t) * num_entries); ++ #endif + + pud_efi = pud_offset(p4d_efi, EFI_VA_START); + pud_k = pud_offset(p4d_k, EFI_VA_START); + + num_entries = PTRS_PER_PUD - pud_index(EFI_VA_START); ++ #ifdef CONFIG_PTP ++ iee_memcpy(pud_efi, pud_k, sizeof(pud_t) * num_entries); ++ #else + memcpy(pud_efi, pud_k, sizeof(pud_t) * num_entries); ++ #endif + } + + /* +diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c +index a595953f1d6d..a83a51431b60 100644 +--- a/arch/x86/power/hibernate_64.c ++++ b/arch/x86/power/hibernate_64.c +@@ -55,15 +55,24 @@ static int set_up_temporary_text_mapping(pgd_t *pgd) + p4d = (p4d_t *)get_safe_page(GFP_ATOMIC); + if (!p4d) + return -ENOMEM; ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)p4d, 0); ++ #endif + } + + pud = (pud_t *)get_safe_page(GFP_ATOMIC); + if (!pud) + return -ENOMEM; ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)pud, 0); ++ #endif + + pmd = (pmd_t *)get_safe_page(GFP_ATOMIC); + if (!pmd) + return -ENOMEM; ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)pmd, 0); ++ #endif + + set_pmd(pmd + pmd_index(restore_jump_address), + __pmd((jump_address_phys & PMD_MASK) | pgprot_val(pmd_text_prot))); +@@ -86,7 +95,13 @@ static int set_up_temporary_text_mapping(pgd_t *pgd) + + static void *alloc_pgt_page(void *context) + { ++ #ifdef CONFIG_PTP ++ unsigned long new = get_safe_page(GFP_ATOMIC); ++ set_iee_page((unsigned long)new, 0); ++ return (void *)new; ++ #else + return (void *)get_safe_page(GFP_ATOMIC); ++ #endif + } + + static int set_up_temporary_mappings(void) +@@ -104,6 +119,9 @@ static int set_up_temporary_mappings(void) + pgd = (pgd_t *)get_safe_page(GFP_ATOMIC); + if (!pgd) + return -ENOMEM; ++ #ifdef CONFIG_PTP ++ set_iee_page((unsigned long)pgd, 0); ++ #endif + + /* Prepare a temporary mapping for the kernel text */ + result = set_up_temporary_text_mapping(pgd); +diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c +index 6b201e64d8ab..ee450d16c687 100644 +--- a/arch/x86/xen/mmu_pv.c ++++ b/arch/x86/xen/mmu_pv.c +@@ -785,6 +785,9 @@ void xen_mm_pin_all(void) + spin_lock(&pgd_lock); + + list_for_each_entry(page, &pgd_list, lru) { ++ #ifdef CONFIG_PTP ++ page = iee_ptdesc_to_page(page); ++ #endif + if (!PagePinned(page)) { + __xen_pgd_pin(&init_mm, (pgd_t *)page_address(page)); + SetPageSavePinned(page); +@@ -891,6 +894,9 @@ void xen_mm_unpin_all(void) + spin_lock(&pgd_lock); + + list_for_each_entry(page, &pgd_list, lru) { ++ #ifdef CONFIG_PTP ++ page = iee_ptdesc_to_page(page); ++ #endif + if (PageSavePinned(page)) { + BUG_ON(!PagePinned(page)); + __xen_pgd_unpin(&init_mm, (pgd_t *)page_address(page)); +diff --git a/block/sed-opal.c b/block/sed-opal.c +index 1a1cb35bf4b7..7149485a808c 100644 +--- a/block/sed-opal.c ++++ b/block/sed-opal.c +@@ -316,7 +316,11 @@ static int read_sed_opal_key(const char *key_name, u_char *buffer, int buflen) + return PTR_ERR(kref); + + key = key_ref_to_ptr(kref); ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(key)); ++ #else + down_read(&key->sem); ++ #endif + ret = key_validate(key); + if (ret == 0) { + if (buflen > key->datalen) +@@ -324,7 +328,11 @@ static int read_sed_opal_key(const char *key_name, u_char *buffer, int buflen) + + ret = key->type->read(key, (char *)buffer, buflen); + } ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + + key_ref_put(kref); + +diff --git a/certs/blacklist.c b/certs/blacklist.c +index 675dd7a8f07a..4db9c6cb7732 100644 +--- a/certs/blacklist.c ++++ b/certs/blacklist.c +@@ -19,6 +19,10 @@ + #include + #include "blacklist.h" + ++#ifdef CONFIG_KEYP ++#include ++#endif ++ + /* + * According to crypto/asymmetric_keys/x509_cert_parser.c:x509_note_pkey_algo(), + * the size of the currently longest supported hash algorithm is 512 bits, +@@ -91,7 +95,11 @@ static int blacklist_key_instantiate(struct key *key, + #endif + + /* Sets safe default permissions for keys loaded by user space. */ ++ #ifdef CONFIG_KEYP ++ iee_set_key_perm(key, BLACKLIST_KEY_PERM); ++ #else + key->perm = BLACKLIST_KEY_PERM; ++ #endif + + /* + * Skips the authentication step for builtin hashes, they are not +diff --git a/certs/system_keyring.c b/certs/system_keyring.c +index a803524044bd..eab10ce55564 100644 +--- a/certs/system_keyring.c ++++ b/certs/system_keyring.c +@@ -96,9 +96,15 @@ int restrict_link_by_builtin_and_secondary_trusted( + /* If we have a secondary trusted keyring, then that contains a link + * through to the builtin keyring and the search will follow that link. + */ ++ #ifdef CONFIG_KEYP ++ if (type == &key_type_keyring && ++ dest_keyring == secondary_trusted_keys && ++ payload == (union key_payload *)(builtin_trusted_keys->name_link.next)) ++ #else + if (type == &key_type_keyring && + dest_keyring == secondary_trusted_keys && + payload == &builtin_trusted_keys->payload) ++ #endif + /* Allow the builtin keyring to be added to the secondary */ + return 0; + +@@ -125,9 +131,15 @@ int restrict_link_by_digsig_builtin_and_secondary(struct key *dest_keyring, + /* If we have a secondary trusted keyring, then that contains a link + * through to the builtin keyring and the search will follow that link. + */ ++ #ifdef CONFIG_KEYP ++ if (type == &key_type_keyring && ++ dest_keyring == secondary_trusted_keys && ++ payload == (union key_payload *)(builtin_trusted_keys->name_link.next)) ++ #else + if (type == &key_type_keyring && + dest_keyring == secondary_trusted_keys && + payload == &builtin_trusted_keys->payload) ++ #endif + /* Allow the builtin keyring to be added to the secondary */ + return 0; + +@@ -212,9 +224,15 @@ int restrict_link_by_builtin_secondary_and_machine( + const union key_payload *payload, + struct key *restrict_key) + { ++ #ifdef CONFIG_KEYP ++ if (machine_trusted_keys && type == &key_type_keyring && ++ dest_keyring == secondary_trusted_keys && ++ payload == (union key_payload *)(machine_trusted_keys->name_link.next)) ++ #else + if (machine_trusted_keys && type == &key_type_keyring && + dest_keyring == secondary_trusted_keys && + payload == &machine_trusted_keys->payload) ++ #endif + /* Allow the machine keyring to be added to the secondary */ + return 0; + +diff --git a/crypto/af_alg.c b/crypto/af_alg.c +index 68cc9290cabe..6d4415de9ee4 100644 +--- a/crypto/af_alg.c ++++ b/crypto/af_alg.c +@@ -304,7 +304,11 @@ static int alg_setkey_by_key_serial(struct alg_sock *ask, sockptr_t optval, + if (IS_ERR(key)) + return PTR_ERR(key); + ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(key)); ++ #else + down_read(&key->sem); ++ #endif + + ret = ERR_PTR(-ENOPROTOOPT); + if (!strcmp(key->type->name, "user") || +@@ -319,21 +323,33 @@ static int alg_setkey_by_key_serial(struct alg_sock *ask, sockptr_t optval, + } + + if (IS_ERR(ret)) { ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + return PTR_ERR(ret); + } + + key_data = sock_kmalloc(&ask->sk, key_datalen, GFP_KERNEL); + if (!key_data) { ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + return -ENOMEM; + } + + memcpy(key_data, ret, key_datalen); + ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + + err = type->setkey(ask->private, key_data, key_datalen); +diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c +index 43af5fa510c0..134f38bd1be9 100644 +--- a/crypto/asymmetric_keys/asymmetric_type.c ++++ b/crypto/asymmetric_keys/asymmetric_type.c +@@ -16,6 +16,9 @@ + #include + #include + #include "asymmetric_keys.h" ++#ifdef CONFIG_KEYP ++#include ++#endif + + + const char *const key_being_used_for[NR__KEY_BEING_USED_FOR] = { +@@ -467,6 +470,17 @@ static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep) + static void asymmetric_key_destroy(struct key *key) + { + struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); ++ #ifdef CONFIG_KEYP ++ struct asymmetric_key_ids *kids = ((union key_payload *)(key->name_link.next))->data[asym_key_ids]; ++ void *data = ((union key_payload *)(key->name_link.next))->data[asym_crypto]; ++ void *auth = ((union key_payload *)(key->name_link.next))->data[asym_auth]; ++ ++ union key_payload *key_payload = ((union key_payload *)(key->name_link.next)); ++ key_payload->data[asym_crypto] = NULL; ++ key_payload->data[asym_subtype] = NULL; ++ key_payload->data[asym_key_ids] = NULL; ++ key_payload->data[asym_auth] = NULL; ++ #else + struct asymmetric_key_ids *kids = key->payload.data[asym_key_ids]; + void *data = key->payload.data[asym_crypto]; + void *auth = key->payload.data[asym_auth]; +@@ -475,6 +489,7 @@ static void asymmetric_key_destroy(struct key *key) + key->payload.data[asym_subtype] = NULL; + key->payload.data[asym_key_ids] = NULL; + key->payload.data[asym_auth] = NULL; ++ #endif + + if (subtype) { + subtype->destroy(data, auth); +@@ -580,8 +595,13 @@ int asymmetric_key_eds_op(struct kernel_pkey_params *params, + if (key->type != &key_type_asymmetric) + return -EINVAL; + subtype = asymmetric_key_subtype(key); ++ #ifdef CONFIG_KEYP ++ if (!subtype || ++ !((union key_payload *)(key->name_link.next))->data[0]) ++ #else + if (!subtype || + !key->payload.data[0]) ++ #endif + return -EINVAL; + if (!subtype->eds_op) + return -ENOTSUPP; +diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c +index 1dcab27986a6..490ba98995c1 100644 +--- a/crypto/asymmetric_keys/public_key.c ++++ b/crypto/asymmetric_keys/public_key.c +@@ -30,7 +30,11 @@ MODULE_LICENSE("GPL"); + static void public_key_describe(const struct key *asymmetric_key, + struct seq_file *m) + { ++ #ifdef CONFIG_KEYP ++ struct public_key *key = ((union key_payload *)(asymmetric_key->name_link.next))->data[asym_crypto]; ++ #else + struct public_key *key = asymmetric_key->payload.data[asym_crypto]; ++ #endif + + if (key) + seq_printf(m, "%s.%s", key->id_type, key->pkey_algo); +@@ -158,7 +162,11 @@ static int software_key_query(const struct kernel_pkey_params *params, + struct kernel_pkey_query *info) + { + struct crypto_akcipher *tfm; ++ #ifdef CONFIG_KEYP ++ struct public_key *pkey = ((union key_payload *)(params->key->name_link.next))->data[asym_crypto]; ++ #else + struct public_key *pkey = params->key->payload.data[asym_crypto]; ++ #endif + char alg_name[CRYPTO_MAX_ALG_NAME]; + struct crypto_sig *sig; + u8 *key, *ptr; +@@ -273,7 +281,11 @@ static int software_key_query(const struct kernel_pkey_params *params, + static int software_key_eds_op(struct kernel_pkey_params *params, + const void *in, void *out) + { ++ #ifdef CONFIG_KEYP ++ const struct public_key *pkey = ((union key_payload *)(params->key->name_link.next))->data[asym_crypto]; ++ #else + const struct public_key *pkey = params->key->payload.data[asym_crypto]; ++ #endif + char alg_name[CRYPTO_MAX_ALG_NAME]; + struct crypto_akcipher *tfm; + struct crypto_sig *sig; +@@ -453,7 +465,11 @@ EXPORT_SYMBOL_GPL(public_key_verify_signature); + static int public_key_verify_signature_2(const struct key *key, + const struct public_key_signature *sig) + { ++ #ifdef CONFIG_KEYP ++ const struct public_key *pk = ((union key_payload *)(key->name_link.next))->data[asym_crypto]; ++ #else + const struct public_key *pk = key->payload.data[asym_crypto]; ++ #endif + return public_key_verify_signature(pk, sig); + } + +diff --git a/crypto/asymmetric_keys/signature.c b/crypto/asymmetric_keys/signature.c +index 2deff81f8af5..696fa2c4e708 100644 +--- a/crypto/asymmetric_keys/signature.c ++++ b/crypto/asymmetric_keys/signature.c +@@ -51,8 +51,13 @@ int query_asymmetric_key(const struct kernel_pkey_params *params, + if (key->type != &key_type_asymmetric) + return -EINVAL; + subtype = asymmetric_key_subtype(key); ++ #ifdef CONFIG_KEYP ++ if (!subtype || ++ !((union key_payload *)(key->name_link.next))->data[0]) ++ #else + if (!subtype || + !key->payload.data[0]) ++ #endif + return -EINVAL; + if (!subtype->query) + return -ENOTSUPP; +@@ -145,8 +150,13 @@ int verify_signature(const struct key *key, + if (key->type != &key_type_asymmetric) + return -EINVAL; + subtype = asymmetric_key_subtype(key); ++ #ifdef CONFIG_KEYP ++ if (!subtype || ++ !((union key_payload *)(key->name_link.next))->data[0]) ++ #else + if (!subtype || + !key->payload.data[0]) ++ #endif + return -EINVAL; + if (!subtype->verify_signature) + return -ENOTSUPP; +diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c +index 83092d93f36a..fb12e7d0660a 100644 +--- a/drivers/firmware/efi/arm-runtime.c ++++ b/drivers/firmware/efi/arm-runtime.c +@@ -94,7 +94,11 @@ static int __init arm_enable_runtime_services(void) + return 0; + } + ++ #ifdef CONFIG_PTP ++ efi_memmap_unmap_after_init(); ++ #else + efi_memmap_unmap(); ++ #endif + + mapsize = efi.memmap.desc_size * efi.memmap.nr_map; + +diff --git a/drivers/firmware/efi/memmap.c b/drivers/firmware/efi/memmap.c +index 77dd20f9df31..ea8ebecaa153 100644 +--- a/drivers/firmware/efi/memmap.c ++++ b/drivers/firmware/efi/memmap.c +@@ -96,6 +96,26 @@ void __init efi_memmap_unmap(void) + clear_bit(EFI_MEMMAP, &efi.flags); + } + ++#ifdef CONFIG_PTP ++void __init efi_memmap_unmap_after_init(void) ++{ ++ if (!efi_enabled(EFI_MEMMAP)) ++ return; ++ ++ if (!(efi.memmap.flags & EFI_MEMMAP_LATE)) { ++ unsigned long size; ++ ++ size = efi.memmap.desc_size * efi.memmap.nr_map; ++ early_iounmap_after_init((__force void __iomem *)efi.memmap.map, size); ++ } else { ++ memunmap(efi.memmap.map); ++ } ++ ++ efi.memmap.map = NULL; ++ clear_bit(EFI_MEMMAP, &efi.flags); ++} ++#endif ++ + /** + * efi_memmap_init_late - Map efi.memmap with memremap() + * @phys_addr: Physical address of the new EFI memory map +diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c +index 6c0621f6f572..0ab9f53a7841 100644 +--- a/drivers/iommu/amd/io_pgtable.c ++++ b/drivers/iommu/amd/io_pgtable.c +@@ -187,7 +187,11 @@ static bool increase_address_space(struct protection_domain *domain, + + out: + spin_unlock_irqrestore(&domain->lock, flags); ++ #ifdef CONFIG_PTP ++ free_iee_pgtable_page(pte); ++ #else + free_page((unsigned long)pte); ++ #endif + + return ret; + } +diff --git a/drivers/md/Makefile b/drivers/md/Makefile +index 84291e38dca8..b3af9d419b6e 100644 +--- a/drivers/md/Makefile ++++ b/drivers/md/Makefile +@@ -71,6 +71,7 @@ obj-$(CONFIG_DM_PERSISTENT_DATA) += persistent-data/ + obj-$(CONFIG_DM_MIRROR) += dm-mirror.o dm-log.o dm-region-hash.o + obj-$(CONFIG_DM_LOG_USERSPACE) += dm-log-userspace.o + obj-$(CONFIG_DM_ZERO) += dm-zero.o ++obj-$(CONFIG_DM_ZERO_KOI) += dm-zero_koi.o + obj-$(CONFIG_DM_RAID) += dm-raid.o + obj-$(CONFIG_DM_THIN_PROVISIONING) += dm-thin-pool.o + obj-$(CONFIG_DM_VERITY) += dm-verity.o +diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c +index aa6bb5b4704b..ecf777e5d176 100644 +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -2512,7 +2512,11 @@ static int set_key_encrypted(struct crypt_config *cc, struct key *key) + { + const struct encrypted_key_payload *ekp; + ++ #ifdef CONFIG_KEYP ++ ekp = ((union key_payload *)(key->name_link.next))->data[0]; ++ #else + ekp = key->payload.data[0]; ++ #endif + if (!ekp) + return -EKEYREVOKED; + +@@ -2528,7 +2532,11 @@ static int set_key_trusted(struct crypt_config *cc, struct key *key) + { + const struct trusted_key_payload *tkp; + ++ #ifdef CONFIG_KEYP ++ tkp = ((union key_payload *)(key->name_link.next))->data[0]; ++ #else + tkp = key->payload.data[0]; ++ #endif + if (!tkp) + return -EKEYREVOKED; + +@@ -2590,17 +2598,29 @@ static int crypt_set_keyring_key(struct crypt_config *cc, const char *key_string + return PTR_ERR(key); + } + ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(key)); ++ #else + down_read(&key->sem); ++ #endif + + ret = set_key(cc, key); + if (ret < 0) { ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + kfree_sensitive(new_key_string); + return ret; + } + ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + + /* clear the flag since following operations may invalidate previously valid key */ +diff --git a/drivers/md/dm-verity-verify-sig.c b/drivers/md/dm-verity-verify-sig.c +index 4836508ea50c..d52d5bccc190 100644 +--- a/drivers/md/dm-verity-verify-sig.c ++++ b/drivers/md/dm-verity-verify-sig.c +@@ -40,7 +40,11 @@ static int verity_verify_get_sig_from_key(const char *key_desc, + if (IS_ERR(key)) + return PTR_ERR(key); + ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(key)); ++ #else + down_read(&key->sem); ++ #endif + + ukp = user_key_payload_locked(key); + if (!ukp) { +@@ -58,7 +62,11 @@ static int verity_verify_get_sig_from_key(const char *key_desc, + memcpy(sig_opts->sig, ukp->data, sig_opts->sig_size); + + end: ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + + return ret; +diff --git a/drivers/md/dm-zero.c b/drivers/md/dm-zero.c +index 3b13e6eb1aa4..a93ac50440c6 100644 +--- a/drivers/md/dm-zero.c ++++ b/drivers/md/dm-zero.c +@@ -79,4 +79,4 @@ module_dm(zero); + + MODULE_AUTHOR("Jana Saout "); + MODULE_DESCRIPTION(DM_NAME " dummy target returning zeros"); +-MODULE_LICENSE("GPL"); ++MODULE_LICENSE("GPL"); +\ No newline at end of file +diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c +index a03e3c45f297..71bccea085e9 100644 +--- a/drivers/nvdimm/security.c ++++ b/drivers/nvdimm/security.c +@@ -28,7 +28,11 @@ static void *key_data(struct key *key) + { + struct encrypted_key_payload *epayload = dereference_key_locked(key); + ++ #ifdef CONFIG_KEYP ++ lockdep_assert_held_read(&KEY_SEM(key)); ++ #else + lockdep_assert_held_read(&key->sem); ++ #endif + + return epayload->decrypted_data; + } +@@ -38,7 +42,11 @@ static void nvdimm_put_key(struct key *key) + if (!key) + return; + ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + } + +@@ -65,10 +73,18 @@ static struct key *nvdimm_request_key(struct nvdimm *nvdimm) + } else { + struct encrypted_key_payload *epayload; + ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(key)); ++ #else + down_read(&key->sem); ++ #endif + epayload = dereference_key_locked(key); + if (epayload->decrypted_datalen != NVDIMM_PASSPHRASE_LEN) { ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + key = NULL; + } +@@ -107,10 +123,18 @@ static struct key *nvdimm_lookup_user_key(struct nvdimm *nvdimm, + + dev_dbg(dev, "%s: key found: %#x\n", __func__, key_serial(key)); + ++ #ifdef CONFIG_KEYP ++ down_read_nested(&KEY_SEM(key), subclass); ++ #else + down_read_nested(&key->sem, subclass); ++ #endif + epayload = dereference_key_locked(key); + if (epayload->decrypted_datalen != NVDIMM_PASSPHRASE_LEN) { ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + key = NULL; + } +diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c +index 7e0d8fb26465..950ee6396659 100644 +--- a/drivers/rtc/rtc-test.c ++++ b/drivers/rtc/rtc-test.c +@@ -198,4 +198,4 @@ MODULE_DESCRIPTION("RTC test driver/device"); + MODULE_LICENSE("GPL v2"); + + module_init(test_init); +-module_exit(test_exit); ++module_exit(test_exit); +\ No newline at end of file +diff --git a/drivers/rtc/rtc-test_glue.h b/drivers/rtc/rtc-test_glue.h +new file mode 100644 +index 000000000000..aee28f9680b2 +--- /dev/null ++++ b/drivers/rtc/rtc-test_glue.h +@@ -0,0 +1,13 @@ ++ ++static int test_rtc_read_time_glue(struct device* dev, struct rtc_time* tm); ++static int test_rtc_set_time_glue(struct device* dev, struct rtc_time* tm); ++static int test_rtc_read_alarm_glue(struct device* dev, struct rtc_wkalrm* alrm); ++static int test_rtc_set_alarm_glue(struct device* dev, struct rtc_wkalrm* alrm); ++static int test_rtc_alarm_irq_enable_glue(struct device* dev, unsigned int enable); ++ ++ ++static void add_timer_glue(struct timer_list* tim_0); ++static time64_t rtc_tm_to_time64_glue(struct rtc_time* rtc_0); ++static time64_t ktime_get_real_seconds_glue(void); ++static void rtc_time64_to_tm_glue(time64_t val_0, struct rtc_time* rtc_1); ++static noinline int del_timer_glue(struct timer_list *timer); +\ No newline at end of file +diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c +index a5fbb6ed38ae..81428783b9da 100644 +--- a/drivers/tty/serial/earlycon.c ++++ b/drivers/tty/serial/earlycon.c +@@ -40,7 +40,11 @@ static void __iomem * __init earlycon_map(resource_size_t paddr, size_t size) + { + void __iomem *base; + #ifdef CONFIG_FIX_EARLYCON_MEM ++ #ifdef CONFIG_PTP ++ __iee_set_fixmap_pre_init(FIX_EARLYCON_MEM_BASE, paddr & PAGE_MASK, FIXMAP_PAGE_IO); ++ #else + set_fixmap_io(FIX_EARLYCON_MEM_BASE, paddr & PAGE_MASK); ++ #endif + base = (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE); + base += paddr & ~PAGE_MASK; + #else +diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c +index 45b42d8f6453..b71072d6957e 100644 +--- a/drivers/usb/early/ehci-dbgp.c ++++ b/drivers/usb/early/ehci-dbgp.c +@@ -879,7 +879,11 @@ int __init early_dbgp_init(char *s) + * FIXME I don't have the bar size so just guess PAGE_SIZE is more + * than enough. 1K is the biggest I have seen. + */ ++ #ifdef CONFIG_PTP ++ __iee_set_fixmap_pre_init(FIX_DBGP_BASE, bar_val & PAGE_MASK, FIXMAP_PAGE_NOCACHE); ++ #else + set_fixmap_nocache(FIX_DBGP_BASE, bar_val & PAGE_MASK); ++ #endif + ehci_bar = (void __iomem *)__fix_to_virt(FIX_DBGP_BASE); + ehci_bar += bar_val & ~PAGE_MASK; + dbgp_printk("ehci_bar: %p\n", ehci_bar); +diff --git a/fs/coredump.c b/fs/coredump.c +index 9d235fa14ab9..72be355903ca 100644 +--- a/fs/coredump.c ++++ b/fs/coredump.c +@@ -53,6 +53,10 @@ + + #include + ++#ifdef CONFIG_CREDP ++#include ++#endif ++ + static bool dump_vma_snapshot(struct coredump_params *cprm); + static void free_vma_snapshot(struct coredump_params *cprm); + +@@ -564,7 +568,11 @@ void do_coredump(const kernel_siginfo_t *siginfo) + */ + if (__get_dumpable(cprm.mm_flags) == SUID_DUMP_ROOT) { + /* Setuid core dump mode */ ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(cred,GLOBAL_ROOT_UID); ++ #else + cred->fsuid = GLOBAL_ROOT_UID; /* Dump root private */ ++ #endif + need_suid_safe = true; + } + +diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c +index 7cbb1fd872ac..a8425a83aabf 100644 +--- a/fs/crypto/keyring.c ++++ b/fs/crypto/keyring.c +@@ -590,8 +590,13 @@ static void fscrypt_provisioning_key_describe(const struct key *key, + { + seq_puts(m, key->description); + if (key_is_positive(key)) { ++ #ifdef CONFIG_KEYP ++ const struct fscrypt_provisioning_key_payload *payload = ++ ((union key_payload *)(key->name_link.next))->data[0]; ++ #else + const struct fscrypt_provisioning_key_payload *payload = + key->payload.data[0]; ++ #endif + + seq_printf(m, ": %u [%u]", key->datalen, payload->type); + } +@@ -599,7 +604,11 @@ static void fscrypt_provisioning_key_describe(const struct key *key, + + static void fscrypt_provisioning_key_destroy(struct key *key) + { ++ #ifdef CONFIG_KEYP ++ kfree_sensitive(((union key_payload *)(key->name_link.next))->data[0]); ++ #else + kfree_sensitive(key->payload.data[0]); ++ #endif + } + + static struct key_type key_type_fscrypt_provisioning = { +@@ -641,7 +650,11 @@ static int get_keyring_key(u32 key_id, u32 type, + + if (key->type != &key_type_fscrypt_provisioning) + goto bad_key; ++ #ifdef CONFIG_KEYP ++ payload = ((union key_payload *)(key->name_link.next))->data[0]; ++ #else + payload = key->payload.data[0]; ++ #endif + + /* Don't allow fscrypt v1 keys to be used as v2 keys and vice versa. */ + if (payload->type != type) +diff --git a/fs/crypto/keysetup_v1.c b/fs/crypto/keysetup_v1.c +index 75dabd9b27f9..9d0cc6ef8e48 100644 +--- a/fs/crypto/keysetup_v1.c ++++ b/fs/crypto/keysetup_v1.c +@@ -109,7 +109,11 @@ find_and_lock_process_key(const char *prefix, + if (IS_ERR(key)) + return key; + ++ #ifdef CONFIG_KEYP ++ down_read(&KEY_SEM(key)); ++ #else + down_read(&key->sem); ++ #endif + ukp = user_key_payload_locked(key); + + if (!ukp) /* was the key revoked before we acquired its semaphore? */ +@@ -136,7 +140,11 @@ find_and_lock_process_key(const char *prefix, + return key; + + invalid: ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + return ERR_PTR(-ENOKEY); + } +@@ -315,7 +323,11 @@ int fscrypt_setup_v1_file_key_via_subscribed_keyrings(struct fscrypt_info *ci) + return PTR_ERR(key); + + err = fscrypt_setup_v1_file_key(ci, payload->raw); ++ #ifdef CONFIG_KEYP ++ up_read(&KEY_SEM(key)); ++ #else + up_read(&key->sem); ++ #endif + key_put(key); + return err; + } +diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h +index f2ed0c0266cb..1a24f8dcff5c 100644 +--- a/fs/ecryptfs/ecryptfs_kernel.h ++++ b/fs/ecryptfs/ecryptfs_kernel.h +@@ -82,7 +82,11 @@ ecryptfs_get_encrypted_key_payload_data(struct key *key) + if (key->type != &key_type_encrypted) + return NULL; + ++ #ifdef CONFIG_KEYP + payload = ((union key_payload *)(key->name_link.next))->data[0]; + #else - payload = key->payload.data[0]; + payload = key->payload.data[0]; ++ #endif + if (!payload) + return ERR_PTR(-EKEYREVOKED); + +diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c +index 7f9f68c00ef6..a4859a7d3b5d 100644 +--- a/fs/ecryptfs/keystore.c ++++ b/fs/ecryptfs/keystore.c +@@ -512,7 +512,11 @@ ecryptfs_find_global_auth_tok_for_sig( + goto out_invalid_auth_tok; + } + ++ #ifdef CONFIG_KEYP ++ down_write(&(KEY_SEM(walker->global_auth_tok_key))); ++ #else + down_write(&(walker->global_auth_tok_key->sem)); ++ #endif + rc = ecryptfs_verify_auth_tok_from_key( + walker->global_auth_tok_key, auth_tok); + if (rc) +@@ -525,7 +529,11 @@ ecryptfs_find_global_auth_tok_for_sig( + rc = -ENOENT; + goto out; + out_invalid_auth_tok_unlock: ++ #ifdef CONFIG_KEYP ++ up_write(&(KEY_SEM(walker->global_auth_tok_key))); ++ #else + up_write(&(walker->global_auth_tok_key->sem)); ++ #endif + out_invalid_auth_tok: + printk(KERN_WARNING "Invalidating auth tok with sig = [%s]\n", sig); + walker->flags |= ECRYPTFS_AUTH_TOK_INVALID; +@@ -846,7 +854,11 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, + mutex_unlock(s->tfm_mutex); + out: + if (auth_tok_key) { ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + } + skcipher_request_free(s->skcipher_req); +@@ -1088,7 +1100,11 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, + (*filename) = NULL; + } + if (auth_tok_key) { ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + } + skcipher_request_free(s->skcipher_req); +@@ -1625,10 +1641,18 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, + goto out; + } + } ++ #ifdef CONFIG_KEYP ++ down_write(&KEY_SEM((*auth_tok_key))); ++ #else + down_write(&(*auth_tok_key)->sem); ++ #endif + rc = ecryptfs_verify_auth_tok_from_key(*auth_tok_key, auth_tok); + if (rc) { ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM((*auth_tok_key))); ++ #else + up_write(&(*auth_tok_key)->sem); ++ #endif + key_put(*auth_tok_key); + (*auth_tok_key) = NULL; + goto out; +@@ -1901,7 +1925,11 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, + memcpy(&(candidate_auth_tok->token.private_key), + &(matching_auth_tok->token.private_key), + sizeof(struct ecryptfs_private_key)); ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + rc = decrypt_pki_encrypted_session_key(candidate_auth_tok, + crypt_stat); +@@ -1909,12 +1937,20 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, + memcpy(&(candidate_auth_tok->token.password), + &(matching_auth_tok->token.password), + sizeof(struct ecryptfs_password)); ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + rc = decrypt_passphrase_encrypted_session_key( + candidate_auth_tok, crypt_stat); + } else { ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + rc = -EINVAL; + } +@@ -1976,7 +2012,11 @@ pki_encrypt_session_key(struct key *auth_tok_key, + crypt_stat->cipher, + crypt_stat->key_size), + crypt_stat, &payload, &payload_len); ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + if (rc) { + ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n"); +@@ -2040,7 +2080,11 @@ write_tag_1_packet(char *dest, size_t *remaining_bytes, + memcpy(key_rec->enc_key, + auth_tok->session_key.encrypted_key, + auth_tok->session_key.encrypted_key_size); ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + goto encrypted_session_key_set; + } +@@ -2438,7 +2482,11 @@ ecryptfs_generate_key_packet_set(char *dest_base, + &max, auth_tok, + crypt_stat, key_rec, + &written); ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + if (rc) { + ecryptfs_printk(KERN_WARNING, "Error " +@@ -2467,7 +2515,11 @@ ecryptfs_generate_key_packet_set(char *dest_base, + } + (*len) += written; + } else { ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(auth_tok_key)); ++ #else + up_write(&(auth_tok_key->sem)); ++ #endif + key_put(auth_tok_key); + ecryptfs_printk(KERN_WARNING, "Unsupported " + "authentication token type\n"); +diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c +index 2dc927ba067f..39c6f1d1438c 100644 +--- a/fs/ecryptfs/main.c ++++ b/fs/ecryptfs/main.c +@@ -202,7 +202,11 @@ static int ecryptfs_init_global_auth_toks( + goto out; + } else { + global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID; ++ #ifdef CONFIG_KEYP ++ up_write(&KEY_SEM(global_auth_tok->global_auth_tok_key)); ++ #else + up_write(&(global_auth_tok->global_auth_tok_key)->sem); ++ #endif + } + } + out: +diff --git a/fs/exec.c b/fs/exec.c +index eaec57f79aa1..5688b11ec9d4 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -76,6 +76,14 @@ + + #include + ++#ifdef CONFIG_CREDP ++#include ++#endif ++ ++#ifdef CONFIG_IEE ++#include ++#endif ++ + static int bprm_creds_from_file(struct linux_binprm *bprm); + + int suid_dumpable = 0; +@@ -733,7 +741,11 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) + free_pgd_range(&tlb, old_start, old_end, new_end, + next ? next->vm_start : USER_PGTABLES_CEILING); + } ++ #ifdef CONFIG_PTP ++ iee_tlb_finish_mmu(&tlb); ++ #else + tlb_finish_mmu(&tlb); ++ #endif + + vma_prev(&vmi); + /* Shrink the vma to just the new range */ +@@ -1023,6 +1035,9 @@ static int exec_mmap(struct mm_struct *mm) + if (!IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM)) + local_irq_enable(); + activate_mm(active_mm, mm); ++ #ifdef CONFIG_IEE ++ iee_set_token_pgd(tsk, mm->pgd); ++ #endif + if (IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM)) + local_irq_enable(); + lru_gen_add_mm(mm); +@@ -1678,12 +1693,20 @@ static void bprm_fill_uid(struct linux_binprm *bprm, struct file *file) + + if (mode & S_ISUID) { + bprm->per_clear |= PER_CLEAR_ON_SETID; ++ #ifdef CONFIG_CREDP ++ iee_set_cred_euid(bprm->cred, vfsuid_into_kuid(vfsuid)); ++ #else + bprm->cred->euid = vfsuid_into_kuid(vfsuid); ++ #endif + } + + if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { + bprm->per_clear |= PER_CLEAR_ON_SETID; ++ #ifdef CONFIG_CREDP ++ iee_set_cred_egid(bprm->cred, vfsgid_into_kgid(vfsgid)); ++ #else + bprm->cred->egid = vfsgid_into_kgid(vfsgid); ++ #endif + } + } + +diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c +index 3e724cb7ef01..e32e136e4271 100644 +--- a/fs/nfs/flexfilelayout/flexfilelayout.c ++++ b/fs/nfs/flexfilelayout/flexfilelayout.c +@@ -15,6 +15,10 @@ + + #include + ++#ifdef CONFIG_CREDP ++#include ++#endif ++ + #include "flexfilelayout.h" + #include "../nfs4session.h" + #include "../nfs4idmap.h" +@@ -502,8 +506,13 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh, + rc = -ENOMEM; + if (!kcred) + goto out_err_free; ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(kcred,uid); ++ iee_set_cred_fsgid(kcred,gid); ++ #else + kcred->fsuid = uid; + kcred->fsgid = gid; ++ #endif + cred = RCU_INITIALIZER(kcred); + + if (lgr->range.iomode == IOMODE_READ) +diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c +index 25a7c771cfd8..c11c2e78e782 100644 +--- a/fs/nfs/nfs4idmap.c ++++ b/fs/nfs/nfs4idmap.c +@@ -48,6 +48,13 @@ + #include + #include + ++#ifdef CONFIG_CREDP ++#include ++#endif ++#ifdef CONFIG_KEYP ++#include ++#endif ++ + #include "internal.h" + #include "netns.h" + #include "nfs4idmap.h" +@@ -225,9 +232,18 @@ int nfs_idmap_init(void) + if (ret < 0) + goto failed_reg_legacy; + ++ #ifdef CONFIG_KEYP ++ iee_set_key_flag_bit(keyring, KEY_FLAG_ROOT_CAN_CLEAR, SET_BIT_OP); ++ #else + set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); ++ #endif ++ #ifdef CONFIG_CREDP ++ iee_set_cred_thread_keyring(cred,keyring); ++ iee_set_cred_jit_keyring(cred,KEY_REQKEY_DEFL_THREAD_KEYRING); ++ #else + cred->thread_keyring = keyring; + cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; ++ #endif + id_resolver_cache = cred; + return 0; + +@@ -296,7 +312,11 @@ static struct key *nfs_idmap_request_key(const char *name, size_t namelen, + mutex_unlock(&idmap->idmap_mutex); + } + if (!IS_ERR(rkey)) ++ #ifdef CONFIG_KEYP ++ iee_set_key_flag_bit(rkey, KEY_FLAG_ROOT_CAN_INVAL, SET_BIT_OP); ++ #else + set_bit(KEY_FLAG_ROOT_CAN_INVAL, &rkey->flags); ++ #endif + + kfree(desc); + return rkey; +@@ -321,7 +341,11 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen, + } + + rcu_read_lock(); ++ #ifdef CONFIG_KEYP ++ iee_set_key_perm(rkey, rkey->perm | KEY_USR_VIEW); ++ #else + rkey->perm |= KEY_USR_VIEW; ++ #endif + + ret = key_validate(rkey); + if (ret < 0) +diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c +index e6beaaf4f170..e89385fd81f1 100644 +--- a/fs/nfsd/auth.c ++++ b/fs/nfsd/auth.c +@@ -2,6 +2,9 @@ + /* Copyright (C) 1995, 1996 Olaf Kirch */ + + #include ++#ifdef CONFIG_CREDP ++#include ++#endif + #include "nfsd.h" + #include "auth.h" + +@@ -32,22 +35,40 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) + if (!new) + return -ENOMEM; + ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(new,rqstp->rq_cred.cr_uid); ++ iee_set_cred_fsgid(new,rqstp->rq_cred.cr_gid); ++ #else + new->fsuid = rqstp->rq_cred.cr_uid; + new->fsgid = rqstp->rq_cred.cr_gid; ++ #endif + + rqgi = rqstp->rq_cred.cr_group_info; + + if (flags & NFSEXP_ALLSQUASH) { ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(new,exp->ex_anon_uid); ++ iee_set_cred_fsgid(new,exp->ex_anon_gid); ++ #else + new->fsuid = exp->ex_anon_uid; + new->fsgid = exp->ex_anon_gid; ++ #endif + gi = groups_alloc(0); + if (!gi) + goto oom; + } else if (flags & NFSEXP_ROOTSQUASH) { + if (uid_eq(new->fsuid, GLOBAL_ROOT_UID)) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(new,exp->ex_anon_uid); ++ #else + new->fsuid = exp->ex_anon_uid; ++ #endif + if (gid_eq(new->fsgid, GLOBAL_ROOT_GID)) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsgid(new,exp->ex_anon_gid); ++ #else + new->fsgid = exp->ex_anon_gid; ++ #endif + + gi = groups_alloc(rqgi->ngroups); + if (!gi) +@@ -67,18 +88,35 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) + } + + if (uid_eq(new->fsuid, INVALID_UID)) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(new,exp->ex_anon_uid); ++ #else + new->fsuid = exp->ex_anon_uid; ++ #endif + if (gid_eq(new->fsgid, INVALID_GID)) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsgid(new,exp->ex_anon_gid); ++ #else + new->fsgid = exp->ex_anon_gid; ++ #endif + + set_groups(new, gi); + put_group_info(gi); + + if (!uid_eq(new->fsuid, GLOBAL_ROOT_UID)) ++ #ifdef CONFIG_CREDP ++ iee_set_cred_cap_effective(new,cap_drop_nfsd_set(new->cap_effective)); ++ #else + new->cap_effective = cap_drop_nfsd_set(new->cap_effective); ++ #endif + else ++ #ifdef CONFIG_CREDP ++ iee_set_cred_cap_effective(new,cap_raise_nfsd_set(new->cap_effective, ++ new->cap_permitted)); ++ #else + new->cap_effective = cap_raise_nfsd_set(new->cap_effective, + new->cap_permitted); ++ #endif + put_cred(override_creds(new)); + put_cred(new); + return 0; +diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c +index 49a88dde9631..4fde340b8471 100644 +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -41,6 +41,9 @@ + #include "trace.h" + #include "xdr4cb.h" + #include "xdr4.h" ++#ifdef CONFIG_CREDP ++#include ++#endif + + #define NFSDDBG_FACILITY NFSDDBG_PROC + +@@ -946,8 +949,13 @@ static const struct cred *get_backchannel_cred(struct nfs4_client *clp, struct r + if (!kcred) + return NULL; + +- kcred->fsuid = ses->se_cb_sec.uid; +- kcred->fsgid = ses->se_cb_sec.gid; ++ #ifdef CONFIG_CREDP ++ iee_set_cred_uid(kcred,ses->se_cb_sec.uid); ++ iee_set_cred_gid(kcred,ses->se_cb_sec.gid); ++ #else ++ kcred->uid = ses->se_cb_sec.uid; ++ kcred->gid = ses->se_cb_sec.gid; ++ #endif + return kcred; + } + } +diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c +index 4395577825a7..8c34cfe01075 100644 +--- a/fs/nfsd/nfs4recover.c ++++ b/fs/nfsd/nfs4recover.c +@@ -44,6 +44,10 @@ + #include + #include + ++#ifdef CONFIG_CREDP ++#include ++#endif ++ + #include "nfsd.h" + #include "state.h" + #include "vfs.h" +@@ -78,8 +82,13 @@ nfs4_save_creds(const struct cred **original_creds) + if (!new) + return -ENOMEM; + ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(new,GLOBAL_ROOT_UID); ++ iee_set_cred_fsgid(new,GLOBAL_ROOT_GID); ++ #else + new->fsuid = GLOBAL_ROOT_UID; + new->fsgid = GLOBAL_ROOT_GID; ++ #endif + *original_creds = override_creds(new); + put_cred(new); + return 0; +diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c +index c2495d98c189..779471a0aa66 100644 +--- a/fs/nfsd/nfsfh.c ++++ b/fs/nfsd/nfsfh.c +@@ -16,6 +16,10 @@ + #include "auth.h" + #include "trace.h" + ++#ifdef CONFIG_CREDP ++#include ++#endif ++ + #define NFSDDBG_FACILITY NFSDDBG_FH + + +@@ -223,9 +227,14 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) + error = nfserrno(-ENOMEM); + goto out; + } ++ #ifdef CONFIG_CREDP ++ iee_set_cred_cap_effective(new,cap_raise_nfsd_set(new->cap_effective, ++ new->cap_permitted)); ++ #else + new->cap_effective = + cap_raise_nfsd_set(new->cap_effective, + new->cap_permitted); ++ #endif + put_cred(override_creds(new)); + put_cred(new); + } else { +diff --git a/fs/open.c b/fs/open.c +index f9ac703ec1b2..5561a7ece18d 100644 +--- a/fs/open.c ++++ b/fs/open.c +@@ -35,6 +35,11 @@ + #include + #include + ++#ifdef CONFIG_CREDP ++#include ++#endif ++ ++ + #include "internal.h" + + int do_truncate(struct mnt_idmap *idmap, struct dentry *dentry, +@@ -414,17 +419,34 @@ static const struct cred *access_override_creds(void) + * routine. + */ + ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(override_cred,override_cred->uid); ++ iee_set_cred_fsgid(override_cred,override_cred->gid); ++ #else + override_cred->fsuid = override_cred->uid; + override_cred->fsgid = override_cred->gid; ++ #endif + + if (!issecure(SECURE_NO_SETUID_FIXUP)) { + /* Clear the capabilities if we switch to a non-root user */ + kuid_t root_uid = make_kuid(override_cred->user_ns, 0); + if (!uid_eq(override_cred->uid, root_uid)) ++ #ifdef CONFIG_CREDP ++ do { ++ kernel_cap_t tmp_cap = override_cred->cap_effective; ++ tmp_cap.val = 0; ++ iee_set_cred_cap_effective(override_cred, tmp_cap); ++ } while (0); ++ #else + cap_clear(override_cred->cap_effective); ++ #endif + else ++ #ifdef CONFIG_CREDP ++ iee_set_cred_cap_effective(override_cred,override_cred->cap_permitted); ++ #else + override_cred->cap_effective = + override_cred->cap_permitted; ++ #endif + } + + /* +@@ -444,7 +466,11 @@ static const struct cred *access_override_creds(void) + * expecting RCU freeing. But normal thread-synchronous + * cred accesses will keep things non-RCY. + */ ++ #ifdef CONFIG_CREDP ++ iee_set_cred_non_rcu(override_cred,1); ++ #else + override_cred->non_rcu = 1; ++ #endif + + old_cred = override_creds(override_cred); + +diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c +index 54602f0bed8b..58534612dc64 100644 +--- a/fs/overlayfs/dir.c ++++ b/fs/overlayfs/dir.c +@@ -16,6 +16,10 @@ + #include + #include "overlayfs.h" + ++#ifdef CONFIG_CREDP ++#include ++#endif ++ + static unsigned short ovl_redirect_max = 256; + module_param_named(redirect_max, ovl_redirect_max, ushort, 0644); + MODULE_PARM_DESC(redirect_max, +@@ -590,8 +594,13 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode, + * create a new inode, so just use the ovl mounter's + * fs{u,g}id. + */ ++ #ifdef CONFIG_CREDP ++ iee_set_cred_fsuid(override_cred,inode->i_uid); ++ iee_set_cred_fsgid(override_cred,inode->i_gid); ++ #else + override_cred->fsuid = inode->i_uid; + override_cred->fsgid = inode->i_gid; ++ #endif + err = security_dentry_create_files_as(dentry, + attr->mode, &dentry->d_name, old_cred, + override_cred); +diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c +index 2c056d737c27..9ede99ddb04b 100644 +--- a/fs/overlayfs/super.c ++++ b/fs/overlayfs/super.c +@@ -21,6 +21,10 @@ + #include "overlayfs.h" + #include "params.h" + ++#ifdef CONFIG_CREDP ++#include ++#endif ++ + MODULE_AUTHOR("Miklos Szeredi "); + MODULE_DESCRIPTION("Overlay filesystem"); + MODULE_LICENSE("GPL"); +@@ -1485,7 +1489,15 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc) + sb->s_export_op = &ovl_export_fid_operations; + + /* Never override disk quota limits or use reserved space */ ++ #ifdef CONFIG_CREDP ++ { ++ kernel_cap_t tmp = cred->cap_effective; ++ cap_lower(tmp, CAP_SYS_RESOURCE); ++ iee_set_cred_cap_effective(cred, tmp); ++ } ++ #else + cap_lower(cred->cap_effective, CAP_SYS_RESOURCE); ++ #endif + + sb->s_magic = OVERLAYFS_SUPER_MAGIC; + sb->s_xattr = ofs->config.userxattr ? ovl_user_xattr_handlers : +diff --git a/fs/smb/client/cifs_spnego.c b/fs/smb/client/cifs_spnego.c +index af7849e5974f..880e7386bfff 100644 +--- a/fs/smb/client/cifs_spnego.c ++++ b/fs/smb/client/cifs_spnego.c +@@ -18,6 +18,13 @@ + #include "cifs_spnego.h" + #include "cifs_debug.h" + #include "cifsproto.h" ++#ifdef CONFIG_CREDP ++#include ++#endif ++#ifdef CONFIG_KEYP ++#include ++#endif ++ + static const struct cred *spnego_cred; + + /* create a new cifs key */ +@@ -33,7 +40,12 @@ cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep) + goto error; + + /* attach the data */ ++ #ifdef CONFIG_KEYP ++ union key_payload *key_payload = ((union key_payload *)(key->name_link.next)); ++ key_payload->data[0] = payload; ++ #else + key->payload.data[0] = payload; ++ #endif + ret = 0; + + error: +@@ -43,7 +55,11 @@ cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep) + static void + cifs_spnego_key_destroy(struct key *key) + { ++ #ifdef CONFIG_KEYP ++ kfree(((union key_payload *)(key->name_link.next))->data[0]); ++ #else + kfree(key->payload.data[0]); ++ #endif + } + + +@@ -163,7 +179,11 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo, + + #ifdef CONFIG_CIFS_DEBUG2 + if (cifsFYI && !IS_ERR(spnego_key)) { ++ #ifdef CONFIG_KEYP ++ struct cifs_spnego_msg *msg = ((union key_payload *)(spnego_key->name_link.next))->data[0]; ++ #else + struct cifs_spnego_msg *msg = spnego_key->payload.data[0]; ++ #endif + cifs_dump_mem("SPNEGO reply blob:", msg->data, min(1024U, + msg->secblob_len + msg->sesskey_len)); + } +@@ -211,9 +231,18 @@ init_cifs_spnego(void) + * instruct request_key() to use this special keyring as a cache for + * the results it looks up + */ ++ #ifdef CONFIG_KEYP ++ iee_set_key_flag_bit(keyring, KEY_FLAG_ROOT_CAN_CLEAR, SET_BIT_OP); ++ #else + set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); ++ #endif ++ #ifdef CONFIG_CREDP ++ iee_set_cred_thread_keyring(cred,keyring); ++ iee_set_cred_jit_keyring(cred,KEY_REQKEY_DEFL_THREAD_KEYRING); ++ #else + cred->thread_keyring = keyring; + cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; ++ #endif + spnego_cred = cred; + + cifs_dbg(FYI, "cifs spnego keyring: %d\n", key_serial(keyring)); +diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c +index f5b6df82e857..a51a8b474d4d 100644 +--- a/fs/smb/client/cifsacl.c ++++ b/fs/smb/client/cifsacl.c +@@ -26,6 +26,14 @@ + #include "cifs_fs_sb.h" + #include "cifs_unicode.h" + ++#ifdef CONFIG_CREDP ++#include ++#endif ++#ifdef CONFIG_KEYP ++#include ++#include ++#endif ++ + /* security id for everyone/world system group */ + static const struct cifs_sid sid_everyone = { + 1, 1, {0, 0, 0, 0, 0, 1}, {0} }; +@@ -78,16 +86,31 @@ cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep) + * dereference payload.data! + */ + if (prep->datalen <= sizeof(key->payload)) { ++ #ifdef CONFIG_KEYP ++ union key_payload *key_payload = ((union key_payload *)(key->name_link.next)); ++ key_payload->data[0] = NULL; ++ memcpy(key_payload, prep->data, prep->datalen); ++ #else + key->payload.data[0] = NULL; + memcpy(&key->payload, prep->data, prep->datalen); ++ #endif + } else { + payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL); + if (!payload) + return -ENOMEM; ++ #ifdef CONFIG_KEYP ++ union key_payload *key_payload = ((union key_payload *)(key->name_link.next)); ++ key_payload->data[0] = payload; ++ #else + key->payload.data[0] = payload; ++ #endif + } + ++ #ifdef CONFIG_KEYP ++ iee_set_key_datalen(key, prep->datalen); ++ #else + key->datalen = prep->datalen; ++ #endif + return 0; + } + +@@ -95,7 +118,11 @@ static inline void + cifs_idmap_key_destroy(struct key *key) + { + if (key->datalen > sizeof(key->payload)) ++ #ifdef CONFIG_KEYP ++ kfree(((union key_payload *)(key->name_link.next))->data[0]); ++ #else + kfree(key->payload.data[0]); ++ #endif + } + + static struct key_type cifs_idmap_key_type = { +@@ -311,9 +338,15 @@ id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid) + * there are no subauthorities and the host has 8-byte pointers, then + * it could be. + */ ++ #ifdef CONFIG_KEYP ++ ksid = sidkey->datalen <= sizeof(sidkey->payload) ? ++ (struct cifs_sid *)(sidkey->name_link.next) : ++ (struct cifs_sid *)((union key_payload *)(sidkey->name_link.next))->data[0]; ++ #else + ksid = sidkey->datalen <= sizeof(sidkey->payload) ? + (struct cifs_sid *)&sidkey->payload : + (struct cifs_sid *)sidkey->payload.data[0]; ++ #endif + + ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32)); + if (ksid_size > sidkey->datalen) { +@@ -422,14 +455,22 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, + if (sidtype == SIDOWNER) { + kuid_t uid; + uid_t id; ++ #ifdef CONFIG_KEYP ++ memcpy(&id, &((union key_payload *)(sidkey->name_link.next))->data[0], sizeof(uid_t)); ++ #else + memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t)); ++ #endif + uid = make_kuid(&init_user_ns, id); + if (uid_valid(uid)) + fuid = uid; + } else { + kgid_t gid; + gid_t id; ++ #ifdef CONFIG_KEYP ++ memcpy(&id, &((union key_payload *)(sidkey->name_link.next))->data[0], sizeof(gid_t)); ++ #else + memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t)); ++ #endif + gid = make_kgid(&init_user_ns, id); + if (gid_valid(gid)) + fgid = gid; +@@ -490,9 +531,18 @@ init_cifs_idmap(void) + + /* instruct request_key() to use this special keyring as a cache for + * the results it looks up */ ++ #ifdef CONFIG_KEYP ++ iee_set_key_flag_bit(keyring, KEY_FLAG_ROOT_CAN_CLEAR, SET_BIT_OP); ++ #else + set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); ++ #endif ++ #ifdef CONFIG_CREDP ++ iee_set_cred_thread_keyring(cred,keyring); ++ iee_set_cred_jit_keyring(cred,KEY_REQKEY_DEFL_THREAD_KEYRING); ++ #else + cred->thread_keyring = keyring; + cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; + #endif + root_cred = cred; - /* Don't allow fscrypt v1 keys to be used as v2 keys and vice versa. */ - if (payload->type != type) -diff --git a/fs/crypto/keysetup_v1.c b/fs/crypto/keysetup_v1.c -index 75dabd9b27f9..9d0cc6ef8e48 100644 ---- a/fs/crypto/keysetup_v1.c -+++ b/fs/crypto/keysetup_v1.c -@@ -109,7 +109,11 @@ find_and_lock_process_key(const char *prefix, - if (IS_ERR(key)) - return key; + cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring)); +diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c +index 1df0a6edcc21..c67e1b13ed0c 100644 +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -2149,7 +2149,11 @@ cifs_set_cifscreds(struct smb3_fs_context *ctx, struct cifs_ses *ses) + is_domain = 1; + } + #ifdef CONFIG_KEYP + down_read(&KEY_SEM(key)); + #else down_read(&key->sem); + #endif - ukp = user_key_payload_locked(key); - - if (!ukp) /* was the key revoked before we acquired its semaphore? */ -@@ -136,7 +140,11 @@ find_and_lock_process_key(const char *prefix, - return key; + upayload = user_key_payload_locked(key); + if (IS_ERR_OR_NULL(upayload)) { + rc = upayload ? PTR_ERR(upayload) : -EINVAL; +@@ -2227,7 +2231,11 @@ cifs_set_cifscreds(struct smb3_fs_context *ctx, struct cifs_ses *ses) + strscpy(ctx->workstation_name, ses->workstation_name, sizeof(ctx->workstation_name)); - invalid: + out_key_put: + #ifdef CONFIG_KEYP + up_read(&KEY_SEM(key)); + #else up_read(&key->sem); + #endif key_put(key); - return ERR_PTR(-ENOKEY); - } -@@ -315,7 +323,11 @@ int fscrypt_setup_v1_file_key_via_subscribed_keyrings(struct fscrypt_info *ci) - return PTR_ERR(key); + out_err: + kfree(desc); +diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c +index 3216f786908f..3160e70b820f 100644 +--- a/fs/smb/client/sess.c ++++ b/fs/smb/client/sess.c +@@ -1591,7 +1591,11 @@ sess_auth_kerberos(struct sess_data *sess_data) + goto out; + } - err = fscrypt_setup_v1_file_key(ci, payload->raw); + #ifdef CONFIG_KEYP -+ up_read(&KEY_SEM(key)); ++ msg = ((union key_payload *)(spnego_key->name_link.next))->data[0]; + #else - up_read(&key->sem); + msg = spnego_key->payload.data[0]; + #endif - key_put(key); - return err; - } -diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h -index f2ed0c0266cb..1a24f8dcff5c 100644 ---- a/fs/ecryptfs/ecryptfs_kernel.h -+++ b/fs/ecryptfs/ecryptfs_kernel.h -@@ -82,7 +82,11 @@ ecryptfs_get_encrypted_key_payload_data(struct key *key) - if (key->type != &key_type_encrypted) - return NULL; + /* + * check version field to make sure that cifs.upcall is + * sending us a response in an expected form +diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c +index a86a3fbfb5a4..dbbf0f2e9780 100644 +--- a/fs/smb/client/smb2pdu.c ++++ b/fs/smb/client/smb2pdu.c +@@ -1629,7 +1629,11 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data) + goto out; + } + #ifdef CONFIG_KEYP -+ payload = ((union key_payload *)(key->name_link.next))->data[0]; ++ msg = ((union key_payload *)(spnego_key->name_link.next))->data[0]; + #else - payload = key->payload.data[0]; + msg = spnego_key->payload.data[0]; + #endif - if (!payload) - return ERR_PTR(-EKEYREVOKED); - -diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c -index 7f9f68c00ef6..a4859a7d3b5d 100644 ---- a/fs/ecryptfs/keystore.c -+++ b/fs/ecryptfs/keystore.c -@@ -512,7 +512,11 @@ ecryptfs_find_global_auth_tok_for_sig( - goto out_invalid_auth_tok; - } + /* + * check version field to make sure that cifs.upcall is + * sending us a response in an expected form +diff --git a/fs/ubifs/auth.c b/fs/ubifs/auth.c +index e564d5ff8781..2d3ca5951fa2 100644 +--- a/fs/ubifs/auth.c ++++ b/fs/ubifs/auth.c +@@ -284,7 +284,11 @@ int ubifs_init_authentication(struct ubifs_info *c) + return PTR_ERR(keyring_key); + } -+ #ifdef CONFIG_KEYP -+ down_write(&(KEY_SEM(walker->global_auth_tok_key))); -+ #else - down_write(&(walker->global_auth_tok_key->sem)); -+ #endif - rc = ecryptfs_verify_auth_tok_from_key( - walker->global_auth_tok_key, auth_tok); - if (rc) -@@ -525,7 +529,11 @@ ecryptfs_find_global_auth_tok_for_sig( - rc = -ENOENT; - goto out; - out_invalid_auth_tok_unlock: + #ifdef CONFIG_KEYP -+ up_write(&(KEY_SEM(walker->global_auth_tok_key))); ++ down_read(&KEY_SEM(keyring_key)); + #else - up_write(&(walker->global_auth_tok_key->sem)); + down_read(&keyring_key->sem); + #endif - out_invalid_auth_tok: - printk(KERN_WARNING "Invalidating auth tok with sig = [%s]\n", sig); - walker->flags |= ECRYPTFS_AUTH_TOK_INVALID; -@@ -846,7 +854,11 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, - mutex_unlock(s->tfm_mutex); + + if (keyring_key->type != &key_type_logon) { + ubifs_err(c, "key type must be logon"); +@@ -351,7 +355,11 @@ int ubifs_init_authentication(struct ubifs_info *c) + if (err) + crypto_free_shash(c->hash_tfm); out: - if (auth_tok_key) { -+ #ifdef CONFIG_KEYP -+ up_write(&KEY_SEM(auth_tok_key)); -+ #else - up_write(&(auth_tok_key->sem)); -+ #endif - key_put(auth_tok_key); - } - skcipher_request_free(s->skcipher_req); -@@ -1088,7 +1100,11 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, - (*filename) = NULL; - } - if (auth_tok_key) { -+ #ifdef CONFIG_KEYP -+ up_write(&KEY_SEM(auth_tok_key)); -+ #else - up_write(&(auth_tok_key->sem)); -+ #endif - key_put(auth_tok_key); - } - skcipher_request_free(s->skcipher_req); -@@ -1625,10 +1641,18 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, - goto out; - } - } -+ #ifdef CONFIG_KEYP -+ down_write(&KEY_SEM((*auth_tok_key))); -+ #else - down_write(&(*auth_tok_key)->sem); -+ #endif - rc = ecryptfs_verify_auth_tok_from_key(*auth_tok_key, auth_tok); - if (rc) { -+ #ifdef CONFIG_KEYP -+ up_write(&KEY_SEM((*auth_tok_key))); -+ #else - up_write(&(*auth_tok_key)->sem); -+ #endif - key_put(*auth_tok_key); - (*auth_tok_key) = NULL; - goto out; -@@ -1901,7 +1925,11 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, - memcpy(&(candidate_auth_tok->token.private_key), - &(matching_auth_tok->token.private_key), - sizeof(struct ecryptfs_private_key)); -+ #ifdef CONFIG_KEYP -+ up_write(&KEY_SEM(auth_tok_key)); -+ #else - up_write(&(auth_tok_key->sem)); -+ #endif - key_put(auth_tok_key); - rc = decrypt_pki_encrypted_session_key(candidate_auth_tok, - crypt_stat); -@@ -1909,12 +1937,20 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, - memcpy(&(candidate_auth_tok->token.password), - &(matching_auth_tok->token.password), - sizeof(struct ecryptfs_password)); -+ #ifdef CONFIG_KEYP -+ up_write(&KEY_SEM(auth_tok_key)); -+ #else - up_write(&(auth_tok_key->sem)); -+ #endif - key_put(auth_tok_key); - rc = decrypt_passphrase_encrypted_session_key( - candidate_auth_tok, crypt_stat); - } else { -+ #ifdef CONFIG_KEYP -+ up_write(&KEY_SEM(auth_tok_key)); -+ #else - up_write(&(auth_tok_key->sem)); -+ #endif - key_put(auth_tok_key); - rc = -EINVAL; - } -@@ -1976,7 +2012,11 @@ pki_encrypt_session_key(struct key *auth_tok_key, - crypt_stat->cipher, - crypt_stat->key_size), - crypt_stat, &payload, &payload_len); + #ifdef CONFIG_KEYP -+ up_write(&KEY_SEM(auth_tok_key)); ++ up_read(&KEY_SEM(keyring_key)); + #else - up_write(&(auth_tok_key->sem)); -+ #endif - key_put(auth_tok_key); - if (rc) { - ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n"); -@@ -2040,7 +2080,11 @@ write_tag_1_packet(char *dest, size_t *remaining_bytes, - memcpy(key_rec->enc_key, - auth_tok->session_key.encrypted_key, - auth_tok->session_key.encrypted_key_size); -+ #ifdef CONFIG_KEYP -+ up_write(&KEY_SEM(auth_tok_key)); -+ #else - up_write(&(auth_tok_key->sem)); -+ #endif - key_put(auth_tok_key); - goto encrypted_session_key_set; - } -@@ -2438,7 +2482,11 @@ ecryptfs_generate_key_packet_set(char *dest_base, - &max, auth_tok, - crypt_stat, key_rec, - &written); -+ #ifdef CONFIG_KEYP -+ up_write(&KEY_SEM(auth_tok_key)); -+ #else - up_write(&(auth_tok_key->sem)); -+ #endif - key_put(auth_tok_key); - if (rc) { - ecryptfs_printk(KERN_WARNING, "Error " -@@ -2467,7 +2515,11 @@ ecryptfs_generate_key_packet_set(char *dest_base, - } - (*len) += written; - } else { -+ #ifdef CONFIG_KEYP -+ up_write(&KEY_SEM(auth_tok_key)); -+ #else - up_write(&(auth_tok_key->sem)); -+ #endif - key_put(auth_tok_key); - ecryptfs_printk(KERN_WARNING, "Unsupported " - "authentication token type\n"); -diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c -index 2dc927ba067f..39c6f1d1438c 100644 ---- a/fs/ecryptfs/main.c -+++ b/fs/ecryptfs/main.c -@@ -202,7 +202,11 @@ static int ecryptfs_init_global_auth_toks( - goto out; - } else { - global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID; -+ #ifdef CONFIG_KEYP -+ up_write(&KEY_SEM(global_auth_tok->global_auth_tok_key)); -+ #else - up_write(&(global_auth_tok->global_auth_tok_key)->sem); -+ #endif - } + up_read(&keyring_key->sem); ++ #endif + key_put(keyring_key); + + return err; +diff --git a/fs/verity/signature.c b/fs/verity/signature.c +index 90c07573dd77..e076cb6fbc84 100644 +--- a/fs/verity/signature.c ++++ b/fs/verity/signature.c +@@ -62,7 +62,11 @@ int fsverity_verify_signature(const struct fsverity_info *vi, + return 0; } - out: -diff --git a/fs/exec.c b/fs/exec.c -index a4725461a443..7691f803c9fa 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -76,6 +76,14 @@ - #include ++ #ifdef CONFIG_KEYP ++ if (((struct key_struct *)(fsverity_keyring->name_link.prev))->keys.nr_leaves_on_tree == 0) { ++ #else + if (fsverity_keyring->keys.nr_leaves_on_tree == 0) { ++ #endif + /* + * The ".fs-verity" keyring is empty, due to builtin signatures + * being supported by the kernel but not actually being used. +diff --git a/include/asm-generic/early_ioremap.h b/include/asm-generic/early_ioremap.h +index 9d0479f50f97..f501e0f965f8 100644 +--- a/include/asm-generic/early_ioremap.h ++++ b/include/asm-generic/early_ioremap.h +@@ -17,6 +17,9 @@ extern void *early_memremap_ro(resource_size_t phys_addr, + extern void *early_memremap_prot(resource_size_t phys_addr, + unsigned long size, unsigned long prot_val); + extern void early_iounmap(void __iomem *addr, unsigned long size); ++#ifdef CONFIG_PTP ++extern void early_iounmap_after_init(void __iomem *addr, unsigned long size); ++#endif + extern void early_memunmap(void *addr, unsigned long size); -+#ifdef CONFIG_CREDP -+#include + #if defined(CONFIG_GENERIC_EARLY_IOREMAP) && defined(CONFIG_MMU) +diff --git a/include/asm-generic/fixmap.h b/include/asm-generic/fixmap.h +index 8cc7b09c1bc7..83158589a545 100644 +--- a/include/asm-generic/fixmap.h ++++ b/include/asm-generic/fixmap.h +@@ -70,6 +70,24 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr) + __set_fixmap(idx, 0, FIXMAP_PAGE_CLEAR) + #endif + ++#ifdef CONFIG_PTP ++#ifndef clear_fixmap_init ++#define clear_fixmap_init(idx) \ ++ __iee_set_fixmap_pre_init(idx, 0, FIXMAP_PAGE_CLEAR) +#endif + -+#ifdef CONFIG_IEE -+#include ++#define __iee_set_fixmap_offset_pre_init(idx, phys, flags) \ ++({ \ ++ unsigned long ________addr; \ ++ __iee_set_fixmap_pre_init(idx, phys, flags); \ ++ ________addr = fix_to_virt(idx) + ((phys) & (PAGE_SIZE - 1)); \ ++ ________addr; \ ++}) ++ ++#define iee_set_fixmap_offset_pre_init(idx, phys) \ ++ __iee_set_fixmap_offset_pre_init(idx, phys, FIXMAP_PAGE_NORMAL) +#endif + - static int bprm_creds_from_file(struct linux_binprm *bprm); + /* Return a pointer with offset calculated */ + #define __set_fixmap_offset(idx, phys, flags) \ + ({ \ +diff --git a/include/asm-generic/memory_model.h b/include/asm-generic/memory_model.h +index 6796abe1900e..725cae1dbd02 100644 +--- a/include/asm-generic/memory_model.h ++++ b/include/asm-generic/memory_model.h +@@ -64,6 +64,26 @@ static inline int pfn_valid(unsigned long pfn) + #define page_to_pfn __page_to_pfn + #define pfn_to_page __pfn_to_page - int suid_dumpable = 0; -@@ -725,7 +733,11 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) - free_pgd_range(&tlb, old_start, old_end, new_end, - next ? next->vm_start : USER_PGTABLES_CEILING); - } -+ #ifdef CONFIG_PTP -+ iee_tlb_finish_mmu(&tlb); -+ #else - tlb_finish_mmu(&tlb); -+ #endif ++#ifdef CONFIG_PTP ++#ifdef CONFIG_ARM64 ++#define IEE_PTDESC_MAP_START VMEMMAP_END ++#define iee_ptdesc_base ((struct ptdesc**)IEE_PTDESC_MAP_START - (memstart_addr >> PAGE_SHIFT)) ++ ++#define __pfn_to_ptdesc(pfn) (iee_ptdesc_base + (pfn)) ++#define __ptdesc_to_pfn(ptdesc) (unsigned long)((ptdesc) - iee_ptdesc_base) ++#else ++#define __pfn_to_ptdesc(pfn) (((struct ptdesc_t **)iee_ptdesc_base + (pfn))) ++#define __ptdesc_to_pfn(ptdesc) (unsigned long)((ptdesc) - (struct ptdesc_t **)iee_ptdesc_base) ++#endif ++ ++#define ptdesc_to_pfn __ptdesc_to_pfn ++#define pfn_to_ptdesc __pfn_to_ptdesc ++ ++#define iee_ptdesc(ptdesc) (*(pfn_to_ptdesc(page_to_pfn((struct page*)ptdesc)))) ++#define page_to_iee_ptdesc(page) (*(pfn_to_ptdesc(page_to_pfn(page)))) ++#define iee_ptdesc_to_page(ptdesc) (((struct ptdesc_t *)ptdesc)->page) ++#endif ++ + #endif /* __ASSEMBLY__ */ - vma_prev(&vmi); - /* Shrink the vma to just the new range */ -@@ -1005,6 +1017,9 @@ static int exec_mmap(struct mm_struct *mm) - if (!IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM)) - local_irq_enable(); - activate_mm(active_mm, mm); -+ #ifdef CONFIG_IEE -+ iee_set_token_pgd(tsk, mm->pgd); -+ #endif - if (IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM)) - local_irq_enable(); - lru_gen_add_mm(mm); -@@ -1624,12 +1639,20 @@ static void bprm_fill_uid(struct linux_binprm *bprm, struct file *file) + #endif +diff --git a/include/asm-generic/pgalloc.h b/include/asm-generic/pgalloc.h +index c75d4a753849..1d86942b242c 100644 +--- a/include/asm-generic/pgalloc.h ++++ b/include/asm-generic/pgalloc.h +@@ -7,6 +7,10 @@ + #define GFP_PGTABLE_KERNEL (GFP_KERNEL | __GFP_ZERO) + #define GFP_PGTABLE_USER (GFP_PGTABLE_KERNEL | __GFP_ACCOUNT) - if (mode & S_ISUID) { - bprm->per_clear |= PER_CLEAR_ON_SETID; -+ #ifdef CONFIG_CREDP -+ iee_set_cred_euid(bprm->cred, vfsuid_into_kuid(vfsuid)); -+ #else - bprm->cred->euid = vfsuid_into_kuid(vfsuid); -+ #endif - } ++#ifdef CONFIG_PTP ++#include ++#endif ++ + /** + * __pte_alloc_one_kernel - allocate memory for a PTE-level kernel page table + * @mm: the mm_struct of the current context +@@ -23,6 +27,7 @@ static inline pte_t *__pte_alloc_one_kernel(struct mm_struct *mm) - if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { - bprm->per_clear |= PER_CLEAR_ON_SETID; -+ #ifdef CONFIG_CREDP -+ iee_set_cred_egid(bprm->cred, vfsgid_into_kgid(vfsgid)); -+ #else - bprm->cred->egid = vfsgid_into_kgid(vfsgid); -+ #endif - } + if (!ptdesc) + return NULL; ++ + return ptdesc_address(ptdesc); } -diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c -index 3e724cb7ef01..e32e136e4271 100644 ---- a/fs/nfs/flexfilelayout/flexfilelayout.c -+++ b/fs/nfs/flexfilelayout/flexfilelayout.c -@@ -15,6 +15,10 @@ +@@ -106,6 +111,7 @@ static inline void pte_free(struct mm_struct *mm, struct page *pte_page) + struct ptdesc *ptdesc = page_ptdesc(pte_page); - #include + pagetable_pte_dtor(ptdesc); ++ + pagetable_free(ptdesc); + } -+#ifdef CONFIG_CREDP -+#include +@@ -149,6 +155,7 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) + + BUG_ON((unsigned long)pmd & (PAGE_SIZE-1)); + pagetable_pmd_dtor(ptdesc); ++ + pagetable_free(ptdesc); + } + #endif +diff --git a/include/asm-generic/pgtable-nop4d.h b/include/asm-generic/pgtable-nop4d.h +index 03b7dae47dd4..ef774115704f 100644 +--- a/include/asm-generic/pgtable-nop4d.h ++++ b/include/asm-generic/pgtable-nop4d.h +@@ -26,6 +26,11 @@ static inline void pgd_clear(pgd_t *pgd) { } + + #define pgd_populate(mm, pgd, p4d) do { } while (0) + #define pgd_populate_safe(mm, pgd, p4d) do { } while (0) ++ ++#ifdef CONFIG_PTP ++#define iee_pgd_populate_pre_init(mm, pgd, p4d) do { } while (0) ++#define iee_pgd_populate_safe_pre_init(mm, pgd, p4d) do { } while (0) ++#endif + /* + * (p4ds are folded into pgds so this doesn't get actually called, + * but the define is needed for a generic inline function.) +diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h +index 22384baee10e..fd0a18fe1748 100644 +--- a/include/asm-generic/tlb.h ++++ b/include/asm-generic/tlb.h +@@ -209,6 +209,9 @@ struct mmu_table_batch { + ((PAGE_SIZE - sizeof(struct mmu_table_batch)) / sizeof(void *)) + + extern void tlb_remove_table(struct mmu_gather *tlb, void *table); ++#ifdef CONFIG_PTP ++extern void iee_tlb_remove_table(struct mmu_gather *tlb, void *table); ++#endif + + #else /* !CONFIG_MMU_GATHER_HAVE_TABLE_FREE */ + +@@ -361,7 +364,9 @@ struct mmu_gather { + }; + + void tlb_flush_mmu(struct mmu_gather *tlb); +- ++#ifdef CONFIG_PTP ++void iee_tlb_flush_mmu(struct mmu_gather *tlb); ++#endif + static inline void __tlb_adjust_range(struct mmu_gather *tlb, + unsigned long address, + unsigned int range_size) +@@ -476,6 +481,15 @@ static inline void tlb_remove_page_size(struct mmu_gather *tlb, + tlb_flush_mmu(tlb); + } + ++#ifdef CONFIG_PTP ++static inline void iee_tlb_remove_page_size(struct mmu_gather *tlb, ++ struct page *page, int page_size) ++{ ++ if (__tlb_remove_page_size(tlb, page, false, page_size)) ++ iee_tlb_flush_mmu(tlb); ++} +#endif + - #include "flexfilelayout.h" - #include "../nfs4session.h" - #include "../nfs4idmap.h" -@@ -502,8 +506,13 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh, - rc = -ENOMEM; - if (!kcred) - goto out_err_free; -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(kcred,uid); -+ iee_set_cred_fsgid(kcred,gid); -+ #else - kcred->fsuid = uid; - kcred->fsgid = gid; -+ #endif - cred = RCU_INITIALIZER(kcred); + static __always_inline bool __tlb_remove_page(struct mmu_gather *tlb, + struct page *page, bool delay_rmap) + { +@@ -491,9 +505,19 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) + return tlb_remove_page_size(tlb, page, PAGE_SIZE); + } - if (lgr->range.iomode == IOMODE_READ) -diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c -index 25a7c771cfd8..c11c2e78e782 100644 ---- a/fs/nfs/nfs4idmap.c -+++ b/fs/nfs/nfs4idmap.c -@@ -48,6 +48,13 @@ - #include - #include ++#ifdef CONFIG_PTP ++static inline void iee_tlb_remove_page(struct mmu_gather *tlb, struct page *page) ++{ ++ return iee_tlb_remove_page_size(tlb, page, PAGE_SIZE); ++} ++#endif + static inline void tlb_remove_ptdesc(struct mmu_gather *tlb, void *pt) + { ++ #ifdef CONFIG_PTP ++ iee_tlb_remove_table(tlb, pt); ++ #else + tlb_remove_table(tlb, pt); ++ #endif + } + + /* Like tlb_remove_ptdesc, but for page-like page directories. */ +diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h +index 174d865ce46e..0d945cdd78e0 100644 +--- a/include/asm-generic/vmlinux.lds.h ++++ b/include/asm-generic/vmlinux.lds.h +@@ -379,6 +379,17 @@ + KEEP(*(.dtb.init.rodata)) \ + __dtb_end = .; + ++#ifdef CONFIG_KOI ++#define KOI_DATA() \ ++ . = ALIGN(PAGE_SIZE); \ ++ __koi_data_start = .; \ ++ *(.data..koi) \ ++ . = ALIGN(PAGE_SIZE); \ ++ __koi_data_end = .; ++#else ++#define KOI_DATA() ++#endif ++ + /* + * .data section + */ +@@ -403,8 +414,8 @@ + BRANCH_PROFILE() \ + TRACE_PRINTKS() \ + BPF_RAW_TP() \ +- TRACEPOINT_STR() +- ++ TRACEPOINT_STR() \ ++ KOI_DATA() + /* + * Data section helpers + */ +@@ -1126,6 +1137,23 @@ + * They will fit only a subset of the architectures + */ +#ifdef CONFIG_CREDP -+#include -+#endif -+#ifdef CONFIG_KEYP -+#include ++ #define CRED_DATA \ ++ . = ALIGN(PAGE_SIZE); \ ++ *(.iee.cred) \ ++ . = ALIGN(PAGE_SIZE); ++#else ++ #define CRED_DATA +#endif + - #include "internal.h" - #include "netns.h" - #include "nfs4idmap.h" -@@ -225,9 +232,18 @@ int nfs_idmap_init(void) - if (ret < 0) - goto failed_reg_legacy; ++#ifdef CONFIG_IEE_SELINUX_P ++ #define IEE_SELINUX_DATA \ ++ . = ALIGN(PAGE_SIZE); \ ++ *(.iee.selinux) \ ++ . = ALIGN(PAGE_SIZE); ++#else ++ #define IEE_SELINUX_DATA ++#endif + /* + * Writeable data. +@@ -1143,6 +1171,8 @@ + . = ALIGN(PAGE_SIZE); \ + .data : AT(ADDR(.data) - LOAD_OFFSET) { \ + INIT_TASK_DATA(inittask) \ ++ CRED_DATA \ ++ IEE_SELINUX_DATA \ + NOSAVE_DATA \ + PAGE_ALIGNED_DATA(pagealigned) \ + CACHELINE_ALIGNED_DATA(cacheline) \ +diff --git a/include/keys/asymmetric-subtype.h b/include/keys/asymmetric-subtype.h +index d55171f640a0..1293c5a1c624 100644 +--- a/include/keys/asymmetric-subtype.h ++++ b/include/keys/asymmetric-subtype.h +@@ -54,7 +54,11 @@ struct asymmetric_key_subtype { + static inline + struct asymmetric_key_subtype *asymmetric_key_subtype(const struct key *key) + { + #ifdef CONFIG_KEYP -+ iee_set_key_flag_bit(keyring, KEY_FLAG_ROOT_CAN_CLEAR, SET_BIT_OP); ++ return ((union key_payload *)(key->name_link.next))->data[asym_subtype]; + #else - set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); + return key->payload.data[asym_subtype]; + #endif -+ #ifdef CONFIG_CREDP -+ iee_set_cred_thread_keyring(cred,keyring); -+ iee_set_cred_jit_keyring(cred,KEY_REQKEY_DEFL_THREAD_KEYRING); + } + + #endif /* _KEYS_ASYMMETRIC_SUBTYPE_H */ +diff --git a/include/keys/asymmetric-type.h b/include/keys/asymmetric-type.h +index 69a13e1e5b2e..6cd556bfb216 100644 +--- a/include/keys/asymmetric-type.h ++++ b/include/keys/asymmetric-type.h +@@ -69,13 +69,21 @@ extern struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1, + static inline + const struct asymmetric_key_ids *asymmetric_key_ids(const struct key *key) + { ++ #ifdef CONFIG_KEYP ++ return ((union key_payload *)(key->name_link.next))->data[asym_key_ids]; + #else - cred->thread_keyring = keyring; - cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; + return key->payload.data[asym_key_ids]; + #endif - id_resolver_cache = cred; - return 0; + } -@@ -296,7 +312,11 @@ static struct key *nfs_idmap_request_key(const char *name, size_t namelen, - mutex_unlock(&idmap->idmap_mutex); - } - if (!IS_ERR(rkey)) -+ #ifdef CONFIG_KEYP -+ iee_set_key_flag_bit(rkey, KEY_FLAG_ROOT_CAN_INVAL, SET_BIT_OP); -+ #else - set_bit(KEY_FLAG_ROOT_CAN_INVAL, &rkey->flags); -+ #endif + static inline + const struct public_key *asymmetric_key_public_key(const struct key *key) + { ++ #ifdef CONFIG_KEYP ++ return ((union key_payload *)(key->name_link.next))->data[asym_crypto]; ++ #else + return key->payload.data[asym_crypto]; ++ #endif + } - kfree(desc); - return rkey; -@@ -321,7 +341,11 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen, - } + extern struct key *find_asymmetric_key(struct key *keyring, +diff --git a/include/keys/request_key_auth-type.h b/include/keys/request_key_auth-type.h +index 36b89a933310..63d5d9f66cb4 100644 +--- a/include/keys/request_key_auth-type.h ++++ b/include/keys/request_key_auth-type.h +@@ -26,7 +26,11 @@ struct request_key_auth { - rcu_read_lock(); + static inline struct request_key_auth *get_request_key_auth(const struct key *key) + { + #ifdef CONFIG_KEYP -+ iee_set_key_perm(rkey, rkey->perm | KEY_USR_VIEW); ++ return ((union key_payload *)(key->name_link.next))->data[0]; + #else - rkey->perm |= KEY_USR_VIEW; + return key->payload.data[0]; + #endif + } - ret = key_validate(rkey); - if (ret < 0) -diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c -index e6beaaf4f170..e89385fd81f1 100644 ---- a/fs/nfsd/auth.c -+++ b/fs/nfsd/auth.c -@@ -2,6 +2,9 @@ - /* Copyright (C) 1995, 1996 Olaf Kirch */ - #include +diff --git a/include/linux/bpf.h b/include/linux/bpf.h +index 73ef8dda7ada..29b9ced9443a 100644 +--- a/include/linux/bpf.h ++++ b/include/linux/bpf.h +@@ -304,6 +304,17 @@ struct bpf_map { + bool free_after_mult_rcu_gp; + KABI_FILL_HOLE(bool free_after_rcu_gp) + s64 __percpu *elem_count; ++#ifdef CONFIG_HIVE ++ /* fbpf add for aggregation */ ++ bool is_aggregated; ++ int used_page_cnt; ++ union { ++ struct bpf_used_page *used_pages; ++ void *value; ++ }; ++ void *shadow_data; ++ struct mutex used_page_mutex; ++#endif + + KABI_USE(1, atomic64_t sleepable_refcnt) + KABI_USE(2, const struct btf_type *attach_func_proto) +@@ -1573,6 +1584,13 @@ struct bpf_prog { + const struct bpf_insn *insn); + struct bpf_prog_aux *aux; /* Auxiliary fields */ + struct sock_fprog_kern *orig_prog; /* Original BPF program */ ++#ifdef CONFIG_HIVE ++ void *shadow_stack_addr, *shadow_region_addr, *shadow_top_addr, ++ *shadow_skb_addr, *low_guard_region_addr, *high_guard_region_addr, ++ *map_data_addr; ++ int shadow_stack_page_cnt, total_page_cnt, shadow_skb_page_cnt, ++ guard_region_page_cnt, map_page_cnt; ++#endif + /* Instructions for interpreter */ + union { + DECLARE_FLEX_ARRAY(struct sock_filter, insns); +diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h +index 1447d41474f5..ad3922626b0e 100644 +--- a/include/linux/bpf_verifier.h ++++ b/include/linux/bpf_verifier.h +@@ -10,6 +10,10 @@ + #include + #include + ++#ifdef CONFIG_HIVE ++#include ++#endif ++ + /* Maximum variable offset umax_value permitted when resolving memory accesses. + * In practice this is far bigger than any realistic pointer offset; this limit + * ensures that umax_value + (int)off + (int)size cannot overflow a u64. +@@ -226,6 +230,11 @@ struct bpf_reg_state { + enum bpf_reg_liveness live; + /* if (!precise && SCALAR_VALUE) min/max/tnum don't affect safety */ + bool precise; ++#ifdef CONFIG_HIVE ++ /* used to record whether the reg is checked */ ++ // bool sfi_checked; ++ enum bpf_sfi_check_state sfi_check_state; ++#endif + + KABI_RESERVE(1) + KABI_RESERVE(2) +@@ -565,6 +574,12 @@ struct bpf_insn_aux_data { + bool storage_get_func_atomic; /* bpf_*_storage_get() with atomic memory alloc */ + bool is_iter_next; /* bpf_iter__next() kfunc call */ + u8 alu_state; /* used in combination with alu_limit */ ++#ifdef CONFIG_HIVE ++ /* fbpf record for patch isnns */ ++ enum bpf_reg_type arg_reg_type[5]; ++ u64 extra_map_ptr; ++ // struct bpf_sfi_check_unit *sfi_check_list; ++#endif + + /* below fields are initialized once */ + unsigned int orig_idx; /* original instruction index */ +@@ -693,6 +708,10 @@ struct bpf_verifier_env { + bool bypass_spec_v4; + bool seen_direct_write; + struct bpf_insn_aux_data *insn_aux_data; /* array of per-insn state */ ++#ifdef CONFIG_HIVE ++ struct bpf_sfi_check_unit **insn_check_lists; /* array of per-insn check_list */ ++ struct mutex insn_check_list_mutex; ++#endif + const struct bpf_line_info *prev_linfo; + struct bpf_verifier_log log; + struct bpf_subprog_info subprog_info[BPF_MAX_SUBPROGS + 1]; +diff --git a/include/linux/cred.h b/include/linux/cred.h +index e01c6d094a30..75db7ea97ab6 100644 +--- a/include/linux/cred.h ++++ b/include/linux/cred.h +@@ -18,6 +18,10 @@ + #include + #include + +#ifdef CONFIG_CREDP -+#include ++#include +#endif - #include "nfsd.h" - #include "auth.h" ++ + struct cred; + struct inode; -@@ -32,22 +35,40 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) - if (!new) - return -ENOMEM; +@@ -153,6 +157,22 @@ struct cred { + KABI_RESERVE(4) + } __randomize_layout; ++#ifdef CONFIG_CREDP ++extern unsigned long long iee_rw_gate(int flag, ...); ++static void iee_set_cred_non_rcu(struct cred *cred, int non_rcu) ++{ ++ iee_rw_gate(IEE_OP_SET_CRED_NON_RCU,cred,non_rcu); ++ *(int *)(&(((struct rcu_head *)(cred->rcu.func))->next)) = non_rcu; ++} ++ ++static bool iee_set_cred_atomic_op_usage(struct cred *cred, int flag, int nr) ++{ ++ bool ret; ++ ret = iee_rw_gate(IEE_OP_SET_CRED_ATOP_USAGE,cred,flag,nr); ++ return ret; ++} ++#endif ++ + extern void __put_cred(struct cred *); + extern void exit_creds(struct task_struct *); + extern int copy_creds(struct task_struct *, unsigned long); +@@ -189,7 +209,11 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred) + */ + static inline struct cred *get_new_cred_many(struct cred *cred, int nr) + { + #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(new,rqstp->rq_cred.cr_uid); -+ iee_set_cred_fsgid(new,rqstp->rq_cred.cr_gid); ++ iee_set_cred_atomic_op_usage(cred, AT_ADD, nr); + #else - new->fsuid = rqstp->rq_cred.cr_uid; - new->fsgid = rqstp->rq_cred.cr_gid; + atomic_long_add(nr, &cred->usage); + #endif + return cred; + } - rqgi = rqstp->rq_cred.cr_group_info; - - if (flags & NFSEXP_ALLSQUASH) { -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(new,exp->ex_anon_uid); -+ iee_set_cred_fsgid(new,exp->ex_anon_gid); -+ #else - new->fsuid = exp->ex_anon_uid; - new->fsgid = exp->ex_anon_gid; -+ #endif - gi = groups_alloc(0); - if (!gi) - goto oom; - } else if (flags & NFSEXP_ROOTSQUASH) { - if (uid_eq(new->fsuid, GLOBAL_ROOT_UID)) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(new,exp->ex_anon_uid); -+ #else - new->fsuid = exp->ex_anon_uid; -+ #endif - if (gid_eq(new->fsgid, GLOBAL_ROOT_GID)) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsgid(new,exp->ex_anon_gid); -+ #else - new->fsgid = exp->ex_anon_gid; -+ #endif - - gi = groups_alloc(rqgi->ngroups); - if (!gi) -@@ -67,18 +88,35 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) - } - - if (uid_eq(new->fsuid, INVALID_UID)) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(new,exp->ex_anon_uid); -+ #else - new->fsuid = exp->ex_anon_uid; -+ #endif - if (gid_eq(new->fsgid, INVALID_GID)) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsgid(new,exp->ex_anon_gid); -+ #else - new->fsgid = exp->ex_anon_gid; -+ #endif - - set_groups(new, gi); - put_group_info(gi); +@@ -202,7 +226,7 @@ static inline struct cred *get_new_cred_many(struct cred *cred, int nr) + */ + static inline struct cred *get_new_cred(struct cred *cred) + { +- return get_new_cred_many(cred, 1); ++ return get_new_cred_many(cred, 1); // XXXzgc atomic_inc -> get_new_cred_many + } - if (!uid_eq(new->fsuid, GLOBAL_ROOT_UID)) -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_effective(new,cap_drop_nfsd_set(new->cap_effective)); -+ #else - new->cap_effective = cap_drop_nfsd_set(new->cap_effective); -+ #endif - else -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_effective(new,cap_raise_nfsd_set(new->cap_effective, -+ new->cap_permitted)); -+ #else - new->cap_effective = cap_raise_nfsd_set(new->cap_effective, - new->cap_permitted); -+ #endif - put_cred(override_creds(new)); - put_cred(new); - return 0; -diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c -index 49a88dde9631..4fde340b8471 100644 ---- a/fs/nfsd/nfs4callback.c -+++ b/fs/nfsd/nfs4callback.c -@@ -41,6 +41,9 @@ - #include "trace.h" - #include "xdr4cb.h" - #include "xdr4.h" -+#ifdef CONFIG_CREDP -+#include -+#endif + /** +@@ -224,7 +248,11 @@ static inline const struct cred *get_cred_many(const struct cred *cred, int nr) + struct cred *nonconst_cred = (struct cred *) cred; + if (!cred) + return cred; ++ #ifdef CONFIG_CREDP ++ iee_set_cred_non_rcu(nonconst_cred,0); ++ #else + nonconst_cred->non_rcu = 0; ++ #endif + return get_new_cred_many(nonconst_cred, nr); + } - #define NFSDDBG_FACILITY NFSDDBG_PROC +@@ -247,9 +275,19 @@ static inline const struct cred *get_cred_rcu(const struct cred *cred) + struct cred *nonconst_cred = (struct cred *) cred; + if (!cred) + return NULL; ++ #ifdef CONFIG_CREDP ++ if (!iee_set_cred_atomic_op_usage(nonconst_cred,AT_INC_NOT_ZERO,0)) ++ return NULL; ++ #else + if (!atomic_long_inc_not_zero(&nonconst_cred->usage)) + return NULL; ++ #endif ++ ++ #ifdef CONFIG_CREDP ++ iee_set_cred_non_rcu(nonconst_cred,0); ++ #else + nonconst_cred->non_rcu = 0; ++ #endif + return cred; + } -@@ -946,8 +949,13 @@ static const struct cred *get_backchannel_cred(struct nfs4_client *clp, struct r - if (!kcred) - return NULL; +@@ -270,8 +308,13 @@ static inline void put_cred_many(const struct cred *_cred, int nr) + struct cred *cred = (struct cred *) _cred; -- kcred->fsuid = ses->se_cb_sec.uid; -- kcred->fsgid = ses->se_cb_sec.gid; + if (cred) { + #ifdef CONFIG_CREDP -+ iee_set_cred_uid(kcred,ses->se_cb_sec.uid); -+ iee_set_cred_gid(kcred,ses->se_cb_sec.gid); ++ if (iee_set_cred_atomic_op_usage(cred,AT_SUB_AND_TEST,nr)) ++ __put_cred(cred); + #else -+ kcred->uid = ses->se_cb_sec.uid; -+ kcred->gid = ses->se_cb_sec.gid; + if (atomic_long_sub_and_test(nr, &cred->usage)) + __put_cred(cred); + #endif - return kcred; } } -diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c -index 4395577825a7..8c34cfe01075 100644 ---- a/fs/nfsd/nfs4recover.c -+++ b/fs/nfsd/nfs4recover.c -@@ -44,6 +44,10 @@ - #include - #include -+#ifdef CONFIG_CREDP -+#include +diff --git a/include/linux/efi.h b/include/linux/efi.h +index 9ed79128458c..970cc4f7068b 100644 +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -740,6 +740,15 @@ extern int __init __efi_memmap_init(struct efi_memory_map_data *data); + extern int __init efi_memmap_init_early(struct efi_memory_map_data *data); + extern int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size); + extern void __init efi_memmap_unmap(void); ++#ifdef CONFIG_PTP ++extern void __init efi_memmap_unmap_after_init(void); ++#endif ++extern int __init efi_memmap_install(struct efi_memory_map_data *data); ++extern int __init efi_memmap_split_count(efi_memory_desc_t *md, ++ struct range *range); ++extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap, ++ void *buf, struct efi_mem_range *mem); ++extern void __init efi_print_memmap(void); + + #ifdef CONFIG_EFI_ESRT + extern void __init efi_esrt_init(void); +diff --git a/include/linux/filter.h b/include/linux/filter.h +index c358bad6cf8f..051838ea4c34 100644 +--- a/include/linux/filter.h ++++ b/include/linux/filter.h +@@ -50,6 +50,9 @@ struct ctl_table_header; + #define BPF_REG_ARG5 BPF_REG_5 + #define BPF_REG_CTX BPF_REG_6 + #define BPF_REG_FP BPF_REG_10 ++#ifdef CONFIG_HIVE ++#define BPF_REG_BASE BPF_REG_11 ++#endif + + /* Additional register mappings for converted user programs. */ + #define BPF_REG_A BPF_REG_0 +diff --git a/include/linux/iee-func.h b/include/linux/iee-func.h +new file mode 100644 +index 000000000000..1958c89f5aed +--- /dev/null ++++ b/include/linux/iee-func.h +@@ -0,0 +1,31 @@ ++#ifndef _LINUX_IEE_FUNC_H ++#define _LINUX_IEE_FUNC_H ++#define HUGE_PMD_ORDER 9 ++#define TASK_ORDER 4 ++ ++#ifndef page_to_phys ++#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) +#endif + - #include "nfsd.h" - #include "state.h" - #include "vfs.h" -@@ -78,8 +82,13 @@ nfs4_save_creds(const struct cred **original_creds) - if (!new) - return -ENOMEM; ++extern unsigned long init_iee_stack_begin[]; ++extern unsigned long init_iee_stack_end[]; ++extern void *init_token_page_vaddr; ++ ++extern unsigned long long iee_rw_gate(int flag, ...); ++extern u32 get_cpu_asid_bits(void); ++extern unsigned long arm64_mm_context_get(struct mm_struct *mm); ++extern void set_iee_page(unsigned long addr, int order); ++extern void unset_iee_page(unsigned long addr, int order); ++extern void set_iee_page_valid(unsigned long addr); ++extern void iee_set_logical_mem_ro(unsigned long addr); ++extern void __init iee_mark_all_lm_pgtable_ro(void); ++extern unsigned long iee_read_token_stack(struct task_struct *tsk); ++extern void iee_set_token_page_valid(void *token, void *new, unsigned int order); ++extern void iee_set_token_page_invalid(void *token_addr, void *token_page, unsigned long order); ++extern void unset_iee_stack_page(unsigned long addr, int order); ++extern void set_iee_stack_page(unsigned long addr, int order); ++extern void *iee_read_tmp_page(struct task_struct *tsk); ++extern void *iee_read_freeptr(unsigned long ptr); ++extern void iee_set_stack_freeptr(unsigned long addr, void *free_ptr); ++extern void iee_rest_init(void); ++#endif +diff --git a/include/linux/key.h b/include/linux/key.h +index 938d7ecfb495..057252aacc13 100644 +--- a/include/linux/key.h ++++ b/include/linux/key.h +@@ -280,6 +280,38 @@ struct key { + struct key_restriction *restrict_link; + }; -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(new,GLOBAL_ROOT_UID); -+ iee_set_cred_fsgid(new,GLOBAL_ROOT_GID); ++#ifdef CONFIG_KEYP ++struct key_union { ++ union { ++ struct list_head graveyard_link; ++ struct rb_node serial_node; ++ }; ++ struct rw_semaphore sem; ++ struct key *key; ++}; ++ ++struct key_struct { ++ struct { ++ /* Keyring bits */ ++ struct list_head name_link; ++ struct assoc_array keys; ++ }; ++ struct key *key; ++}; ++#endif ++ ++#ifdef CONFIG_KEYP ++#define KEY_SEM(KEY) (((struct key_union *)(KEY->graveyard_link.next))->sem) ++#include ++extern unsigned long long iee_rw_gate(int flag, ...); ++static bool iee_set_key_usage(struct key *key, int n, int flag) ++{ ++ bool ret; ++ ret = iee_rw_gate(IEE_OP_SET_KEY_USAGE, key, n, flag); ++ return ret; ++} ++#endif ++ + extern struct key *key_alloc(struct key_type *type, + const char *desc, + kuid_t uid, kgid_t gid, +@@ -305,7 +337,11 @@ extern void key_remove_domain(struct key_tag *domain_tag); + + static inline struct key *__key_get(struct key *key) + { ++ #ifdef CONFIG_KEYP ++ iee_set_key_usage(key, 0, REFCOUNT_INC); + #else - new->fsuid = GLOBAL_ROOT_UID; - new->fsgid = GLOBAL_ROOT_GID; + refcount_inc(&key->usage); + #endif - *original_creds = override_creds(new); - put_cred(new); - return 0; -diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c -index c2495d98c189..779471a0aa66 100644 ---- a/fs/nfsd/nfsfh.c -+++ b/fs/nfsd/nfsfh.c -@@ -16,6 +16,10 @@ - #include "auth.h" - #include "trace.h" + return key; + } -+#ifdef CONFIG_CREDP -+#include +@@ -478,17 +514,67 @@ static inline bool key_is_negative(const struct key *key) + return key_read_state(key) < 0; + } + ++#ifdef CONFIG_KEYP ++static inline void iee_write_key_payload_rcu_data0(struct key *key, void *rcu_data0) ++{ ++ union key_payload *key_payload = (union key_payload *)(key->name_link.next); ++ WRITE_ONCE(key_payload->rcu_data0, rcu_data0); ++} ++ ++#define dereference_key_rcu(KEY) \ ++ (rcu_dereference(((union key_payload *)(KEY->name_link.next))->rcu_data0)) ++ ++#ifdef CONFIG_KEYP ++#define dereference_key_locked(KEY) \ ++ (rcu_dereference_protected(((union key_payload *)(KEY->name_link.next))->rcu_data0, \ ++ rwsem_is_locked(&KEY_SEM(((struct key *)(KEY)))))) ++#else ++#define dereference_key_locked(KEY) \ ++ (rcu_dereference_protected(((union key_payload *)(KEY->name_link.next))->rcu_data0, \ ++ rwsem_is_locked(&((struct key *)(KEY))->sem))) +#endif + - #define NFSDDBG_FACILITY NFSDDBG_FH ++#define iee_smp_store_release(p, v, KEY) \ ++do { \ ++ compiletime_assert_atomic_type(*p); \ ++ barrier(); \ ++ iee_write_key_payload_rcu_data0(KEY, v); \ ++} while (0) ++ ++#define iee_rcu_assign_pointer(p, v, KEY) \ ++do { \ ++ uintptr_t _r_a_p__v = (uintptr_t)(v); \ ++ rcu_check_sparse(p, __rcu); \ ++ \ ++ if (__builtin_constant_p(v) && (_r_a_p__v) == (uintptr_t)NULL) \ ++ iee_write_key_payload_rcu_data0(KEY, (typeof(p))(_r_a_p__v)); \ ++ else \ ++ iee_smp_store_release(&p, RCU_INITIALIZER((typeof(p))_r_a_p__v), KEY); \ ++} while (0) ++ ++#define rcu_assign_keypointer(KEY, PAYLOAD) \ ++do { \ ++ iee_rcu_assign_pointer(((union key_payload *)(KEY->name_link.next))->rcu_data0, (PAYLOAD), KEY); \ ++} while (0) ++#else + #define dereference_key_rcu(KEY) \ + (rcu_dereference((KEY)->payload.rcu_data0)) + ++#ifdef CONFIG_KEYP ++#define dereference_key_locked(KEY) \ ++ (rcu_dereference_protected((KEY)->payload.rcu_data0, \ ++ rwsem_is_locked(&KEY_SEM(((struct key *)(KEY)))))) ++#else + #define dereference_key_locked(KEY) \ + (rcu_dereference_protected((KEY)->payload.rcu_data0, \ + rwsem_is_locked(&((struct key *)(KEY))->sem))) ++#endif + #define rcu_assign_keypointer(KEY, PAYLOAD) \ + do { \ + rcu_assign_pointer((KEY)->payload.rcu_data0, (PAYLOAD)); \ + } while (0) ++#endif -@@ -223,9 +227,14 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) - error = nfserrno(-ENOMEM); - goto out; - } -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_effective(new,cap_raise_nfsd_set(new->cap_effective, -+ new->cap_permitted)); -+ #else - new->cap_effective = - cap_raise_nfsd_set(new->cap_effective, - new->cap_permitted); -+ #endif - put_cred(override_creds(new)); - put_cred(new); - } else { -diff --git a/fs/open.c b/fs/open.c -index 59db720693f9..dbbca8701fd1 100644 ---- a/fs/open.c -+++ b/fs/open.c -@@ -35,6 +35,11 @@ - #include - #include + /* + * the userspace interface +diff --git a/include/linux/mm.h b/include/linux/mm.h +index 2e6ef9532fc3..3ecd0d77a1dc 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -32,6 +32,11 @@ + #include + #include -+#ifdef CONFIG_CREDP -+#include ++#ifdef CONFIG_PTP ++#include ++#include +#endif + -+ - #include "internal.h" + struct mempolicy; + struct anon_vma; + struct anon_vma_chain; +@@ -2944,7 +2949,19 @@ static inline bool pagetable_is_reserved(struct ptdesc *pt) + */ + static inline struct ptdesc *pagetable_alloc(gfp_t gfp, unsigned int order) + { ++ #ifdef CONFIG_PTP ++ #ifdef CONFIG_X86_64 ++ struct page *page; ++ if (iee_pgt_jar_init) ++ page = virt_to_page(get_iee_pgtable_page(gfp | __GFP_COMP)); ++ else ++ page = alloc_pages(gfp | __GFP_COMP, order); ++ #else ++ struct page *page = virt_to_page(get_iee_pgtable_page(gfp | __GFP_COMP)); ++ #endif ++ #else + struct page *page = alloc_pages(gfp | __GFP_COMP, order); ++ #endif - int do_truncate(struct mnt_idmap *idmap, struct dentry *dentry, -@@ -414,17 +419,34 @@ static const struct cred *access_override_creds(void) - * routine. - */ + return page_ptdesc(page); + } +@@ -2960,7 +2977,11 @@ static inline void pagetable_free(struct ptdesc *pt) + { + struct page *page = ptdesc_page(pt); -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(override_cred,override_cred->uid); -+ iee_set_cred_fsgid(override_cred,override_cred->gid); ++ #ifdef CONFIG_PTP ++ free_iee_pgtable_page((void *)page_address(page)); + #else - override_cred->fsuid = override_cred->uid; - override_cred->fsgid = override_cred->gid; + __free_pages(page, compound_order(page)); + #endif + } - if (!issecure(SECURE_NO_SETUID_FIXUP)) { - /* Clear the capabilities if we switch to a non-root user */ - kuid_t root_uid = make_kuid(override_cred->user_ns, 0); - if (!uid_eq(override_cred->uid, root_uid)) -+ #ifdef CONFIG_CREDP -+ do { -+ kernel_cap_t tmp_cap = override_cred->cap_effective; -+ tmp_cap.val = 0; -+ iee_set_cred_cap_effective(override_cred, tmp_cap); -+ } while (0); -+ #else - cap_clear(override_cred->cap_effective); -+ #endif - else -+ #ifdef CONFIG_CREDP -+ iee_set_cred_cap_effective(override_cred,override_cred->cap_permitted); -+ #else - override_cred->cap_effective = - override_cred->cap_permitted; -+ #endif - } + #if USE_SPLIT_PTE_PTLOCKS +@@ -2971,7 +2992,18 @@ void ptlock_free(struct ptdesc *ptdesc); - /* -@@ -444,7 +466,11 @@ static const struct cred *access_override_creds(void) - * expecting RCU freeing. But normal thread-synchronous - * cred accesses will keep things non-RCY. + static inline spinlock_t *ptlock_ptr(struct ptdesc *ptdesc) + { ++ #ifdef CONFIG_PTP ++ #ifdef CONFIG_X86_64 ++ if (iee_pgt_jar_init) ++ return (iee_ptdesc(ptdesc))->ptl; ++ else ++ return ptdesc->ptl; ++ #else ++ return (iee_ptdesc(ptdesc))->ptl; ++ #endif ++ #else + return ptdesc->ptl; ++ #endif + } + #else /* ALLOC_SPLIT_PTLOCKS */ + static inline void ptlock_cache_init(void) +@@ -2989,7 +3021,18 @@ static inline void ptlock_free(struct ptdesc *ptdesc) + + static inline spinlock_t *ptlock_ptr(struct ptdesc *ptdesc) + { ++ #ifdef CONFIG_PTP ++ #ifdef CONFIG_X86_64 ++ if (iee_pgt_jar_init) ++ return &(iee_ptdesc(ptdesc))->ptl; ++ else ++ return &ptdesc->ptl; ++ #else ++ return &(iee_ptdesc(ptdesc))->ptl; ++ #endif ++ #else + return &ptdesc->ptl; ++ #endif + } + #endif /* ALLOC_SPLIT_PTLOCKS */ + +@@ -3007,7 +3050,11 @@ static inline bool ptlock_init(struct ptdesc *ptdesc) + * It can happen if arch try to use slab for page table allocation: + * slab code uses page->slab_cache, which share storage with page->ptl. */ -+ #ifdef CONFIG_CREDP -+ iee_set_cred_non_rcu(override_cred,1); ++ #ifdef CONFIG_PTP ++ VM_BUG_ON_PAGE(*(unsigned long *)&(iee_ptdesc(ptdesc)->ptl), ptdesc_page(ptdesc)); + #else - override_cred->non_rcu = 1; + VM_BUG_ON_PAGE(*(unsigned long *)&ptdesc->ptl, ptdesc_page(ptdesc)); ++ #endif + if (!ptlock_alloc(ptdesc)) + return false; + spin_lock_init(ptlock_ptr(ptdesc)); +@@ -3106,7 +3153,11 @@ static inline spinlock_t *pmd_lockptr(struct mm_struct *mm, pmd_t *pmd) + static inline bool pmd_ptlock_init(struct ptdesc *ptdesc) + { + #ifdef CONFIG_TRANSPARENT_HUGEPAGE ++ #ifdef CONFIG_PTP ++ ((iee_ptdesc(ptdesc))->pmd_huge_pte) = NULL; ++ #else + ptdesc->pmd_huge_pte = NULL; ++ #endif + #endif + return ptlock_init(ptdesc); + } +@@ -3114,12 +3165,20 @@ static inline bool pmd_ptlock_init(struct ptdesc *ptdesc) + static inline void pmd_ptlock_free(struct ptdesc *ptdesc) + { + #ifdef CONFIG_TRANSPARENT_HUGEPAGE ++ #ifdef CONFIG_PTP ++ VM_BUG_ON_PAGE(((iee_ptdesc(ptdesc))->pmd_huge_pte), ptdesc_page(ptdesc)); ++ #else + VM_BUG_ON_PAGE(ptdesc->pmd_huge_pte, ptdesc_page(ptdesc)); + #endif + #endif + ptlock_free(ptdesc); + } - old_cred = override_creds(override_cred); ++#ifdef CONFIG_PTP ++#define pmd_huge_pte(mm, pmd) ((iee_ptdesc(pmd_ptdesc(pmd)))->pmd_huge_pte) ++#else + #define pmd_huge_pte(mm, pmd) (pmd_ptdesc(pmd)->pmd_huge_pte) ++#endif -diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c -index 54602f0bed8b..58534612dc64 100644 ---- a/fs/overlayfs/dir.c -+++ b/fs/overlayfs/dir.c -@@ -16,6 +16,10 @@ - #include - #include "overlayfs.h" + #else -+#ifdef CONFIG_CREDP -+#include +diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h +index 4b9a8723d3eb..07da48fd7d88 100644 +--- a/include/linux/mm_types.h ++++ b/include/linux/mm_types.h +@@ -483,6 +483,42 @@ struct ptdesc { + #endif + }; + ++#ifdef CONFIG_PTP ++struct ptdesc_t { ++ unsigned long __page_flags; ++ ++ union { ++ struct rcu_head pt_rcu_head; ++ struct list_head pt_list; ++ struct { ++ unsigned long _pt_pad_1; ++ pgtable_t pmd_huge_pte; ++ }; ++ }; ++ unsigned long __page_mapping; ++ ++ union { ++ struct mm_struct *pt_mm; ++ atomic_t pt_frag_refcount; ++ }; ++ ++ union { ++ unsigned long _pt_pad_2; ++#if ALLOC_SPLIT_PTLOCKS ++ spinlock_t *ptl; ++#else ++ spinlock_t ptl; ++#endif ++ }; ++ unsigned int __page_type; ++ atomic_t _refcount; ++#ifdef CONFIG_MEMCG ++ unsigned long pt_memcg_data; ++#endif ++ struct page *page; ++}; +#endif + - static unsigned short ovl_redirect_max = 256; - module_param_named(redirect_max, ovl_redirect_max, ushort, 0644); - MODULE_PARM_DESC(redirect_max, -@@ -590,8 +594,13 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode, - * create a new inode, so just use the ovl mounter's - * fs{u,g}id. - */ -+ #ifdef CONFIG_CREDP -+ iee_set_cred_fsuid(override_cred,inode->i_uid); -+ iee_set_cred_fsgid(override_cred,inode->i_gid); -+ #else - override_cred->fsuid = inode->i_uid; - override_cred->fsgid = inode->i_gid; -+ #endif - err = security_dentry_create_files_as(dentry, - attr->mode, &dentry->d_name, old_cred, - override_cred); -diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c -index 2c056d737c27..9ede99ddb04b 100644 ---- a/fs/overlayfs/super.c -+++ b/fs/overlayfs/super.c -@@ -21,6 +21,10 @@ - #include "overlayfs.h" - #include "params.h" - -+#ifdef CONFIG_CREDP -+#include + #define TABLE_MATCH(pg, pt) \ + static_assert(offsetof(struct page, pg) == offsetof(struct ptdesc, pt)) + TABLE_MATCH(flags, __page_flags); +@@ -1181,6 +1217,9 @@ struct mmu_gather; + extern void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm); + extern void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm); + extern void tlb_finish_mmu(struct mmu_gather *tlb); ++#ifdef CONFIG_PTP ++extern void iee_tlb_finish_mmu(struct mmu_gather *tlb); +#endif + + struct vm_fault; + +diff --git a/include/linux/module.h b/include/linux/module.h +index 990f9d66d2f1..169021fc8501 100644 +--- a/include/linux/module.h ++++ b/include/linux/module.h +@@ -609,6 +609,7 @@ struct module { + KABI_RESERVE(2) + KABI_RESERVE(3) + KABI_RESERVE(4) + - MODULE_AUTHOR("Miklos Szeredi "); - MODULE_DESCRIPTION("Overlay filesystem"); - MODULE_LICENSE("GPL"); -@@ -1485,7 +1489,15 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc) - sb->s_export_op = &ovl_export_fid_operations; + } ____cacheline_aligned __randomize_layout; + #ifndef MODULE_ARCH_INIT + #define MODULE_ARCH_INIT {} +diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h +index 98db43432ee9..dca565ffb64d 100644 +--- a/include/linux/pgtable.h ++++ b/include/linux/pgtable.h +@@ -1095,6 +1095,38 @@ static inline int pgd_same(pgd_t pgd_a, pgd_t pgd_b) + set_pgd(pgdp, pgd); \ + }) - /* Never override disk quota limits or use reserved space */ -+ #ifdef CONFIG_CREDP -+ { -+ kernel_cap_t tmp = cred->cap_effective; -+ cap_lower(tmp, CAP_SYS_RESOURCE); -+ iee_set_cred_cap_effective(cred, tmp); -+ } -+ #else - cap_lower(cred->cap_effective, CAP_SYS_RESOURCE); -+ #endif ++#ifdef CONFIG_PTP ++#define iee_set_pte_safe_pre_init(ptep, pte) \ ++({ \ ++ WARN_ON_ONCE(pte_present(*ptep) && !pte_same(*ptep, pte)); \ ++ iee_set_pte_pre_init(ptep, pte); \ ++}) ++ ++#define iee_set_pmd_safe_pre_init(pmdp, pmd) \ ++({ \ ++ WARN_ON_ONCE(pmd_present(*pmdp) && !pmd_same(*pmdp, pmd)); \ ++ iee_set_pmd_pre_init(pmdp, pmd); \ ++}) ++ ++#define iee_set_pud_safe_pre_init(pudp, pud) \ ++({ \ ++ WARN_ON_ONCE(pud_present(*pudp) && !pud_same(*pudp, pud)); \ ++ iee_set_pud_pre_init(pudp, pud); \ ++}) ++ ++#define iee_set_p4d_safe_pre_init(p4dp, p4d) \ ++({ \ ++ WARN_ON_ONCE(p4d_present(*p4dp) && !p4d_same(*p4dp, p4d)); \ ++ iee_set_p4d_pre_init(p4dp, p4d); \ ++}) ++ ++#define iee_set_pgd_safe_pre_init(pgdp, pgd) \ ++({ \ ++ WARN_ON_ONCE(pgd_present(*pgdp) && !pgd_same(*pgdp, pgd)); \ ++ iee_set_pgd_pre_init(pgdp, pgd); \ ++}) ++#endif ++ + #ifndef __HAVE_ARCH_DO_SWAP_PAGE + static inline void arch_do_swap_page_nr(struct mm_struct *mm, + struct vm_area_struct *vma, +diff --git a/include/linux/sched.h b/include/linux/sched.h +index a694cc11dea5..5b89c9c5485d 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -773,6 +773,24 @@ struct task_struct_resvd { + struct task_struct *task; + }; - sb->s_magic = OVERLAYFS_SUPER_MAGIC; - sb->s_xattr = ofs->config.userxattr ? ovl_user_xattr_handlers : -diff --git a/fs/smb/client/cifs_spnego.c b/fs/smb/client/cifs_spnego.c -index af7849e5974f..d913a255265f 100644 ---- a/fs/smb/client/cifs_spnego.c -+++ b/fs/smb/client/cifs_spnego.c -@@ -18,6 +18,13 @@ - #include "cifs_spnego.h" - #include "cifs_debug.h" - #include "cifsproto.h" -+#ifdef CONFIG_CREDP -+#include ++#if defined(CONFIG_IEE) || defined(CONFIG_KOI) ++struct task_token { ++#ifdef CONFIG_IEE ++ pgd_t *pgd; /* Logical VA */ ++ void *iee_stack; /* VA */ ++ void *tmp_page; ++ bool valid; ++ void *kernel_stack; /* VA */ +#endif -+#ifdef CONFIG_KEYP -+#include ++#ifdef CONFIG_KOI ++ void *koi_kernel_stack; /* VA */ ++ void *koi_stack; /* VA */ ++ void *koi_stack_base; /* VA */ ++ unsigned long current_ttbr1; ++#endif ++}; +#endif + - static const struct cred *spnego_cred; - - /* create a new cifs key */ -@@ -33,7 +40,13 @@ cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep) - goto error; - - /* attach the data */ -+ #ifdef CONFIG_KEYP -+ union key_payload key_payload = *((union key_payload *)(key->name_link.next)); -+ key_payload.data[0] = payload; -+ iee_write_key_payload(key, key_payload); -+ #else - key->payload.data[0] = payload; -+ #endif - ret = 0; - - error: -@@ -43,7 +56,11 @@ cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep) - static void - cifs_spnego_key_destroy(struct key *key) - { -+ #ifdef CONFIG_KEYP -+ kfree(((union key_payload *)(key->name_link.next))->data[0]); -+ #else - kfree(key->payload.data[0]); -+ #endif - } - - -@@ -163,7 +180,11 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo, + struct task_struct { + #ifdef CONFIG_THREAD_INFO_IN_TASK + /* +@@ -795,6 +813,7 @@ struct task_struct { + randomized_struct_fields_start - #ifdef CONFIG_CIFS_DEBUG2 - if (cifsFYI && !IS_ERR(spnego_key)) { -+ #ifdef CONFIG_KEYP -+ struct cifs_spnego_msg *msg = ((union key_payload *)(spnego_key->name_link.next))->data[0]; -+ #else - struct cifs_spnego_msg *msg = spnego_key->payload.data[0]; -+ #endif - cifs_dump_mem("SPNEGO reply blob:", msg->data, min(1024U, - msg->secblob_len + msg->sesskey_len)); - } -@@ -211,9 +232,18 @@ init_cifs_spnego(void) - * instruct request_key() to use this special keyring as a cache for - * the results it looks up - */ -+ #ifdef CONFIG_KEYP -+ iee_set_key_flag_bit(keyring, KEY_FLAG_ROOT_CAN_CLEAR, SET_BIT_OP); -+ #else - set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); -+ #endif -+ #ifdef CONFIG_CREDP -+ iee_set_cred_thread_keyring(cred,keyring); -+ iee_set_cred_jit_keyring(cred,KEY_REQKEY_DEFL_THREAD_KEYRING); -+ #else - cred->thread_keyring = keyring; - cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; -+ #endif - spnego_cred = cred; + void *stack; ++ + refcount_t usage; + /* Per task flags (PF_*), defined further below: */ + unsigned int flags; +diff --git a/include/linux/sfi_bpf.h b/include/linux/sfi_bpf.h +new file mode 100644 +index 000000000000..23c5d9409c6e +--- /dev/null ++++ b/include/linux/sfi_bpf.h +@@ -0,0 +1,86 @@ ++#ifndef LINUX_SFI_BPF_H ++#define LINUX_SFI_BPF_H ++ ++#include ++#include ++ ++/* fbpf log */ ++#define FBPF_LOG_ENABLE ++#define fbpf_log(fmt, ...) do_fbpf_log(__FUNCTION__, fmt, ##__VA_ARGS__) ++void do_fbpf_log(const char *func_name, const char *fmt, ...); ++ ++/* fbpf used for output */ ++extern const char *bpf_map_type_strings[]; ++ ++/* fbpf map vaddr to struct page* */ ++struct page *kv_virt_to_page(const void *vaddr); ++ ++/* fbpf aggregate */ ++int bpf_sfi_aggregate_memory(struct bpf_verifier_env *env); ++ ++/* fbpf record percpu map used pages */ ++struct bpf_used_page { ++ struct page *physic_page; ++ struct list_head list_head; ++ u64 shadow_page; ++}; ++ ++/* fbpf: relevant api for bpf_used_pages */ ++int bpf_record_used_pages(u64 start_addr, u64 end_addr, ++ struct mutex *write_mutex, struct list_head *head); ++ ++/* fbpf: htab's value addr is built-in element, use api to substitue */ ++void substitute_hash_value_ptr(struct bpf_map *map); ++ ++inline void *alloc_aligned_memory(u64 size); ++ ++inline int map_physic_pages(struct page **pages, void *virt_addr, int page_cnt); ++ ++struct bpf_sfi_check_unit *bpf_sfi_get_check_list( ++ struct bpf_verifier_env *env, struct bpf_insn *insn, ++ struct bpf_reg_state *regs); ++ ++/* fbpf: check type for a reg in insn */ ++enum bpf_sfi_check_type { ++ BPF_SFI_CHECK_LDST_AS_UNSAFE_PTR, ++ BPF_SFI_CHECK_LDST_AS_SAFE_PTR, ++ BPF_SFI_CHECK_LDST_AS_OFFSET, ++ BPF_SFI_CHECK_HELPER_AS_UNSAFE_PTR, ++ BPF_SFI_CHECK_HELPER_AS_SAFE_PTR, ++ BPF_SFI_CHECK_HELPER_AS_OFFSET, ++}; ++ ++/* fbpf: check state for a reg */ ++enum bpf_sfi_check_state { ++ BPF_SFI_UNSAFE_PTR, ++ BPF_SFI_SAFE_PTR, ++ BPF_SFI_OFFSET, ++}; ++ ++// TODO: allocate and free this link list for each insn_aux_data ++/* fbpf: check unit (link list) for a insn */ ++struct bpf_sfi_check_unit { ++ struct list_head list_head; ++ int reg_no; ++ enum bpf_sfi_check_type check_type; ++ bool reg_as_offset; ++ enum bpf_sfi_check_state proposed_state; ++}; ++ ++/* fbpf dump insns of a BPF Program */ ++void dump_insns(struct bpf_prog *prog, int start, int len, const char *prompt); ++ ++int bpf_sfi_tmp_check(struct bpf_verifier_env *env); ++ ++/* fbpf patch to check ld/st insns */ ++int bpf_sfi_check_ldst(struct bpf_verifier_env *env); ++ ++/* fbpf patch to check helper's args */ ++int bpf_sfi_check_helper_args(struct bpf_verifier_env *env); ++ ++struct bpf_prog *_bpf_patch_insn_data(struct bpf_verifier_env *env, u32 off, ++ const struct bpf_insn *patch, u32 len); ++ ++bool bpf_sfi_can_instrument(struct bpf_verifier_env *env); ++ ++#endif +\ No newline at end of file +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index 1597a5f9b5b8..828660c74337 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -1065,6 +1065,9 @@ struct sk_buff { + sk_buff_data_t end; + unsigned char *head, + *data; ++#ifdef CONFIG_HIVE ++ unsigned char *sfi_data, *sfi_data_meta, *sfi_data_end; ++#endif + unsigned int truesize; + refcount_t users; + +diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h +index 482647774bf5..4eb077e21915 100644 +--- a/include/uapi/linux/bpf.h ++++ b/include/uapi/linux/bpf.h +@@ -63,6 +63,7 @@ enum { + BPF_REG_8, + BPF_REG_9, + BPF_REG_10, ++ BPF_REG_11, + __MAX_BPF_REG, + }; - cifs_dbg(FYI, "cifs spnego keyring: %d\n", key_serial(keyring)); -diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c -index f5b6df82e857..7684cf4639e1 100644 ---- a/fs/smb/client/cifsacl.c -+++ b/fs/smb/client/cifsacl.c -@@ -26,6 +26,14 @@ - #include "cifs_fs_sb.h" - #include "cifs_unicode.h" +diff --git a/include/uapi/linux/bpf_common.h b/include/uapi/linux/bpf_common.h +index ee97668bdadb..104caf07a85f 100644 +--- a/include/uapi/linux/bpf_common.h ++++ b/include/uapi/linux/bpf_common.h +@@ -26,6 +26,7 @@ + #define BPF_MEM 0x60 + #define BPF_LEN 0x80 + #define BPF_MSH 0xa0 ++#define BPF_REG 0xe0 + + /* alu/jmp fields */ + #define BPF_OP(code) ((code) & 0xf0) +diff --git a/init/main.c b/init/main.c +index 8fdfa69dba0f..feca51bc2ef9 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -102,6 +102,16 @@ + #include + #include -+#ifdef CONFIG_CREDP -+#include ++#ifdef CONFIG_IEE ++#include ++#include ++#include ++#include +#endif -+#ifdef CONFIG_KEYP -+#include -+#include ++#ifdef CONFIG_PTP ++#include +#endif + - /* security id for everyone/world system group */ - static const struct cifs_sid sid_everyone = { - 1, 1, {0, 0, 0, 0, 0, 1}, {0} }; -@@ -78,16 +86,33 @@ cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep) - * dereference payload.data! - */ - if (prep->datalen <= sizeof(key->payload)) { -+ #ifdef CONFIG_KEYP -+ union key_payload key_payload = *((union key_payload *)(key->name_link.next)); -+ key_payload.data[0] = NULL; -+ iee_write_key_payload(key, key_payload); -+ iee_memcpy(((union key_payload *)(key->name_link.next)), prep->data, prep->datalen); -+ #else - key->payload.data[0] = NULL; - memcpy(&key->payload, prep->data, prep->datalen); -+ #endif - } else { - payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL); - if (!payload) - return -ENOMEM; -+ #ifdef CONFIG_KEYP -+ union key_payload key_payload = *((union key_payload *)(key->name_link.next)); -+ key_payload.data[0] = payload; -+ iee_write_key_payload(key, key_payload); -+ #else - key->payload.data[0] = payload; -+ #endif - } - -+ #ifdef CONFIG_KEYP -+ iee_set_key_datalen(key, prep->datalen); -+ #else - key->datalen = prep->datalen; + #include + #include + #include +@@ -933,6 +943,12 @@ void start_kernel(void) + sort_main_extable(); + trap_init(); + mm_core_init(); ++ #ifdef CONFIG_IEE ++ iee_stack_init(); + #endif - return 0; - } - -@@ -95,7 +120,11 @@ static inline void - cifs_idmap_key_destroy(struct key *key) - { - if (key->datalen > sizeof(key->payload)) -+ #ifdef CONFIG_KEYP -+ kfree(((union key_payload *)(key->name_link.next))->data[0]); -+ #else - kfree(key->payload.data[0]); -+ #endif - } - - static struct key_type cifs_idmap_key_type = { -@@ -311,9 +340,15 @@ id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid) - * there are no subauthorities and the host has 8-byte pointers, then - * it could be. - */ -+ #ifdef CONFIG_KEYP -+ ksid = sidkey->datalen <= sizeof(sidkey->payload) ? -+ (struct cifs_sid *)(sidkey->name_link.next) : -+ (struct cifs_sid *)((union key_payload *)(sidkey->name_link.next))->data[0]; -+ #else - ksid = sidkey->datalen <= sizeof(sidkey->payload) ? - (struct cifs_sid *)&sidkey->payload : - (struct cifs_sid *)sidkey->payload.data[0]; ++ #ifdef CONFIG_PTP ++ iee_pgtable_init(); + #endif + poking_init(); + ftrace_init(); - ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32)); - if (ksid_size > sidkey->datalen) { -@@ -422,14 +457,22 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, - if (sidtype == SIDOWNER) { - kuid_t uid; - uid_t id; -+ #ifdef CONFIG_KEYP -+ memcpy(&id, &((union key_payload *)(sidkey->name_link.next))->data[0], sizeof(uid_t)); -+ #else - memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t)); -+ #endif - uid = make_kuid(&init_user_ns, id); - if (uid_valid(uid)) - fuid = uid; - } else { - kgid_t gid; - gid_t id; -+ #ifdef CONFIG_KEYP -+ memcpy(&id, &((union key_payload *)(sidkey->name_link.next))->data[0], sizeof(gid_t)); -+ #else - memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t)); -+ #endif - gid = make_kgid(&init_user_ns, id); - if (gid_valid(gid)) - fgid = gid; -@@ -490,9 +533,18 @@ init_cifs_idmap(void) +@@ -1073,6 +1089,20 @@ void start_kernel(void) + arch_post_acpi_subsys_init(); + kcsan_init(); - /* instruct request_key() to use this special keyring as a cache for - * the results it looks up */ -+ #ifdef CONFIG_KEYP -+ iee_set_key_flag_bit(keyring, KEY_FLAG_ROOT_CAN_CLEAR, SET_BIT_OP); -+ #else - set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); -+ #endif -+ #ifdef CONFIG_CREDP -+ iee_set_cred_thread_keyring(cred,keyring); -+ iee_set_cred_jit_keyring(cred,KEY_REQKEY_DEFL_THREAD_KEYRING); -+ #else - cred->thread_keyring = keyring; - cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; ++ // Later IEE settings. ++ #ifdef CONFIG_IEE ++ iee_rest_init(); ++ set_iee_stack_page((unsigned long)__va(__pa_symbol(init_iee_stack_begin)), 2); ++ for (int i = 0; i < 4; i++) { ++ iee_set_logical_mem_ro((unsigned long)init_iee_stack_begin + PAGE_SIZE * i); ++ } ++ set_iee_page((unsigned long)init_token_page_vaddr, 0); ++ // Set the logical va of existing pgtable readonly. ++ #ifdef CONFIG_PTP ++ iee_mark_all_lm_pgtable_ro(); + #endif - root_cred = cred; ++ #endif ++ + /* Do the rest non-__init'ed, we're now alive */ + arch_call_rest_init(); - cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring)); -diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c -index e325e06357ff..e43723e8cd0f 100644 ---- a/fs/smb/client/connect.c -+++ b/fs/smb/client/connect.c -@@ -2150,7 +2150,11 @@ cifs_set_cifscreds(struct smb3_fs_context *ctx, struct cifs_ses *ses) - is_domain = 1; +@@ -1460,7 +1490,7 @@ static int __ref kernel_init(void *unused) + * to finalize PTI. + */ + pti_finalize(); +- ++ + system_state = SYSTEM_RUNNING; + numa_default_policy(); + +diff --git a/kernel/bpf/Kconfig b/kernel/bpf/Kconfig +index 19f6ab882ab1..8d0dea7f0f51 100644 +--- a/kernel/bpf/Kconfig ++++ b/kernel/bpf/Kconfig +@@ -113,4 +113,15 @@ config BPF_SCHED + + If you are unsure how to answer this question, answer N. + ++config HIVE ++ bool "Reserved for eBPF security enhancement" ++ default n ++ depends on BPF_SYSCALL ++ depends on DEBUG_INFO_DWARF4 ++ depends on DEBUG_INFO_BTF ++ select NET_ACT_BPF ++ select BPFILTER ++ select NET_CLS_BPF ++ select NET_SCH_INGRESS ++ + endmenu # "BPF subsystem" +diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile +index f526b7573e97..316c693b8d35 100644 +--- a/kernel/bpf/Makefile ++++ b/kernel/bpf/Makefile +@@ -46,3 +46,5 @@ obj-$(CONFIG_BPF_PRELOAD) += preload/ + obj-$(CONFIG_BPF_SYSCALL) += relo_core.o + $(obj)/relo_core.o: $(srctree)/tools/lib/bpf/relo_core.c FORCE + $(call if_changed_rule,cc_o_c) ++ ++obj-$(CONFIG_HIVE) += sfi_bpf.o +diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c +index 1811efcfbd6e..2a59acc27e6e 100644 +--- a/kernel/bpf/arraymap.c ++++ b/kernel/bpf/arraymap.c +@@ -12,6 +12,9 @@ + #include + #include + #include ++#ifdef CONFIG_HIVE ++#include ++#endif + + #include "map_in_map.h" + +@@ -21,12 +24,38 @@ + + static void bpf_array_free_percpu(struct bpf_array *array) + { ++#ifdef CONFIG_HIVE ++ if (unlikely(!array->map.is_aggregated)) { ++ int i; ++ for (i = 0; i < array->map.max_entries; i++) { ++ free_percpu(array->pptrs[i]); ++ cond_resched(); ++ } ++ } else { ++ struct bpf_used_page *used_page_entry, *used_page_next; ++ struct list_head *used_pages_list_head = &array->map.used_pages->list_head; ++ ++ free_percpu(array->pptrs[0]); ++ cond_resched(); ++ ++ if (used_pages_list_head && !list_empty(used_pages_list_head)) { ++ list_for_each_entry_safe(used_page_entry, used_page_next, ++ used_pages_list_head, list_head){ ++ list_del(&used_page_entry->list_head); ++ vfree(used_page_entry); ++ } ++ } ++ ++ vfree(array->map.used_pages); ++ } ++#else + int i; + + for (i = 0; i < array->map.max_entries; i++) { + free_percpu(array->pptrs[i]); + cond_resched(); } ++#endif + } -+ #ifdef CONFIG_KEYP -+ down_read(&KEY_SEM(key)); -+ #else - down_read(&key->sem); -+ #endif - upayload = user_key_payload_locked(key); - if (IS_ERR_OR_NULL(upayload)) { - rc = upayload ? PTR_ERR(upayload) : -EINVAL; -@@ -2228,7 +2232,11 @@ cifs_set_cifscreds(struct smb3_fs_context *ctx, struct cifs_ses *ses) - strscpy(ctx->workstation_name, ses->workstation_name, sizeof(ctx->workstation_name)); + static int bpf_array_alloc_percpu(struct bpf_array *array) +@@ -34,6 +63,55 @@ static int bpf_array_alloc_percpu(struct bpf_array *array) + void __percpu *ptr; + int i; - out_key_put: -+ #ifdef CONFIG_KEYP -+ up_read(&KEY_SEM(key)); -+ #else - up_read(&key->sem); -+ #endif - key_put(key); - out_err: - kfree(desc); -diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c -index 3216f786908f..3160e70b820f 100644 ---- a/fs/smb/client/sess.c -+++ b/fs/smb/client/sess.c -@@ -1591,7 +1591,11 @@ sess_auth_kerberos(struct sess_data *sess_data) - goto out; ++#ifdef CONFIG_HIVE ++ int page_cnt; ++ struct bpf_used_page *used_pages; ++ u64 start_address, end_address; ++ ++ if (unlikely(!array->map.is_aggregated)) { ++ for (i = 0; i < array->map.max_entries; i++) { ++ ptr = bpf_map_alloc_percpu(&array->map, array->elem_size, 8, ++ GFP_USER | __GFP_NOWARN); ++ if (!ptr) { ++ bpf_array_free_percpu(array); ++ return -ENOMEM; ++ } ++ array->pptrs[i] = ptr; ++ cond_resched(); ++ } ++ } else { ++ /* init used_pages of map */ ++ used_pages = vmalloc(sizeof(*used_pages)); ++ if (!used_pages) ++ return -ENOMEM; ++ INIT_LIST_HEAD(&used_pages->list_head); ++ mutex_init(&array->map.used_page_mutex); ++ array->map.used_pages = used_pages; ++ /* WARNING, align to PAGE_SIZE tends to alloc failed */ ++ ptr = __alloc_percpu_gfp(array->elem_size * array->map.max_entries, ++ PAGE_SIZE, GFP_USER | __GFP_NOWARN); ++ if (!ptr) { ++ bpf_array_free_percpu(array); ++ pr_err("alloc percpu failed"); ++ return -ENOMEM; ++ } ++ for (i = 0; i < array->map.max_entries; i++) { ++ array->pptrs[i] = (void *)((u64) ptr + i * array->elem_size); ++ cond_resched(); ++ } ++ ++ /* record physic pages */ ++ start_address = round_down((u64)ptr, PAGE_SIZE); ++ end_address = round_up((u64)ptr + array->map.max_entries * ++ array->elem_size, PAGE_SIZE); ++ page_cnt = bpf_record_used_pages(start_address, end_address, ++ &array->map.used_page_mutex, &array->map.used_pages->list_head); ++ if (page_cnt >= 0) ++ array->map.used_page_cnt = page_cnt; ++ else ++ return page_cnt; ++ } ++#else + for (i = 0; i < array->map.max_entries; i++) { + ptr = bpf_map_alloc_percpu(&array->map, array->elem_size, 8, + GFP_USER | __GFP_NOWARN); +@@ -44,6 +122,7 @@ static int bpf_array_alloc_percpu(struct bpf_array *array) + array->pptrs[i] = ptr; + cond_resched(); } ++#endif -+ #ifdef CONFIG_KEYP -+ msg = ((union key_payload *)(spnego_key->name_link.next))->data[0]; + return 0; + } +@@ -89,6 +168,17 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) + u64 array_size, mask64; + struct bpf_array *array; + ++#ifdef CONFIG_HIVE ++ bool is_aggregated; ++ ++ /* bpf_sfi_on && map_need_aggregate => is_aggregated */ ++ if (attr->map_type == BPF_MAP_TYPE_ARRAY || ++ attr->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) ++ is_aggregated = true; ++ else ++ is_aggregated = false; ++#endif ++ + elem_size = round_up(attr->value_size, 8); + + max_entries = attr->max_entries; +@@ -114,12 +204,21 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) + + array_size = sizeof(*array); + if (percpu) { ++ #ifdef CONFIG_HIVE ++ array_size += PAGE_ALIGN((u64) max_entries * sizeof(void *)); + #else - msg = spnego_key->payload.data[0]; + array_size += (u64) max_entries * sizeof(void *); + #endif - /* - * check version field to make sure that cifs.upcall is - * sending us a response in an expected form -diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c -index 83a03201bb86..4d090ca58257 100644 ---- a/fs/smb/client/smb2pdu.c -+++ b/fs/smb/client/smb2pdu.c -@@ -1629,7 +1629,11 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data) - goto out; - } - -+ #ifdef CONFIG_KEYP -+ msg = ((union key_payload *)(spnego_key->name_link.next))->data[0]; + } else { + /* rely on vmalloc() to return page-aligned memory and + * ensure array->value is exactly page-aligned + */ +- if (attr->map_flags & BPF_F_MMAPABLE) { ++ #ifdef CONFIG_HIVE ++ if ((attr->map_flags & BPF_F_MMAPABLE) || is_aggregated) + #else - msg = spnego_key->payload.data[0]; ++ if (attr->map_flags & BPF_F_MMAPABLE) + #endif - /* - * check version field to make sure that cifs.upcall is - * sending us a response in an expected form -diff --git a/fs/ubifs/auth.c b/fs/ubifs/auth.c -index e564d5ff8781..2d3ca5951fa2 100644 ---- a/fs/ubifs/auth.c -+++ b/fs/ubifs/auth.c -@@ -284,7 +284,11 @@ int ubifs_init_authentication(struct ubifs_info *c) - return PTR_ERR(keyring_key); ++ { + array_size = PAGE_ALIGN(array_size); + array_size += PAGE_ALIGN((u64) max_entries * elem_size); + } else { +@@ -128,7 +227,13 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) } -+ #ifdef CONFIG_KEYP -+ down_read(&KEY_SEM(keyring_key)); -+ #else - down_read(&keyring_key->sem); -+ #endif + /* allocate all map elements and zero-initialize them */ +- if (attr->map_flags & BPF_F_MMAPABLE) { ++#ifdef CONFIG_HIVE ++ if ((attr->map_flags & BPF_F_MMAPABLE) || ++ (is_aggregated && !percpu)) ++#else ++ if (attr->map_flags & BPF_F_MMAPABLE) ++#endif ++ { + void *data; - if (keyring_key->type != &key_type_logon) { - ubifs_err(c, "key type must be logon"); -@@ -351,7 +355,11 @@ int ubifs_init_authentication(struct ubifs_info *c) - if (err) - crypto_free_shash(c->hash_tfm); - out: -+ #ifdef CONFIG_KEYP -+ up_read(&KEY_SEM(keyring_key)); -+ #else - up_read(&keyring_key->sem); -+ #endif - key_put(keyring_key); + /* kmalloc'ed memory can't be mmap'ed, use explicit vmalloc */ +@@ -145,6 +250,16 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) + array->index_mask = index_mask; + array->map.bypass_spec_v1 = bypass_spec_v1; - return err; -diff --git a/fs/verity/signature.c b/fs/verity/signature.c -index 90c07573dd77..e076cb6fbc84 100644 ---- a/fs/verity/signature.c -+++ b/fs/verity/signature.c -@@ -62,7 +62,11 @@ int fsverity_verify_signature(const struct fsverity_info *vi, - return 0; ++#ifdef CONFIG_HIVE ++ array->map.is_aggregated = is_aggregated; ++ array->map.value = array->value; ++ ++ /* record map_page_cnt for aggregation */ ++ if (!percpu && is_aggregated) ++ array->map.used_page_cnt = PAGE_ALIGN((u64) max_entries * elem_size) ++ >> PAGE_SHIFT; ++#endif ++ + /* copy mandatory map attributes */ + bpf_map_init_from_attr(&array->map, attr); + array->elem_size = elem_size; +@@ -171,7 +286,17 @@ static void *array_map_lookup_elem(struct bpf_map *map, void *key) + if (unlikely(index >= array->map.max_entries)) + return NULL; + ++#ifdef CONFIG_HIVE ++ /* here array->shadow_data equals map->shadow_data */ ++ if (map->is_aggregated && map->shadow_data) ++ return map->shadow_data + array->elem_size * ++ (index & array->index_mask); ++ else { ++ return array->value + array->elem_size * (index & array->index_mask); ++ } ++#else + return array->value + (u64)array->elem_size * (index & array->index_mask); ++#endif + } + + static int array_map_direct_value_addr(const struct bpf_map *map, u64 *imm, +@@ -184,7 +309,15 @@ static int array_map_direct_value_addr(const struct bpf_map *map, u64 *imm, + if (off >= map->value_size) + return -EINVAL; + ++ ++#ifdef CONFIG_HIVE ++ if (map->is_aggregated && map->shadow_data) ++ *imm = (unsigned long)map->shadow_data; ++ else ++ *imm = (unsigned long)array->value; ++#else + *imm = (unsigned long)array->value; ++#endif + return 0; + } + +@@ -217,7 +350,21 @@ static int array_map_gen_lookup(struct bpf_map *map, struct bpf_insn *insn_buf) + if (map->map_flags & BPF_F_INNER_MAP) + return -EOPNOTSUPP; + ++#ifdef CONFIG_HIVE ++ fbpf_log("shadow_data = %016llx\n", map->shadow_data); ++ if (map->is_aggregated && map->shadow_data) { ++ /* substitute array->value with map->shadow_data */ ++ /* assume map is the first attribute of struct array, ++ so that array == array->map ++ array=ffff8000844efe80, &array->map=ffff8000844efe80 */ ++ *insn++ = BPF_LDX_MEM(BPF_DW, map_ptr, map_ptr, offsetof(struct bpf_map, shadow_data)); ++ } ++ else ++ *insn++ = BPF_ALU64_IMM(BPF_ADD, map_ptr, ++ offsetof(struct bpf_array, value)); ++#else + *insn++ = BPF_ALU64_IMM(BPF_ADD, map_ptr, offsetof(struct bpf_array, value)); ++#endif + *insn++ = BPF_LDX_MEM(BPF_W, ret, index, 0); + if (!map->bypass_spec_v1) { + *insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 4); +@@ -237,6 +384,35 @@ static int array_map_gen_lookup(struct bpf_map *map, struct bpf_insn *insn_buf) + return insn - insn_buf; + } + ++#ifdef CONFIG_HIVE ++extern pte_t *bpf_sfi_get_ptep(u64 addr); ++ ++static void *__percpu_array_map_lookup_elem(struct bpf_array *array, u64 value_ptr) ++{ ++ // struct page *phy_page; ++ // pteval_t phy_pte, vir_pte; ++ struct list_head *used_pages_head; ++ struct bpf_used_page *entry; ++ struct bpf_used_page *next; ++ u64 in_page_offset; ++ ++ in_page_offset = value_ptr - round_down(value_ptr, PAGE_SIZE); ++ // phy_page = kv_virt_to_page((void *)value_ptr); ++ // phy_pte = pte_val(*bpf_sfi_get_ptep(value_ptr)); ++ ++ used_pages_head = &array->map.used_pages->list_head; ++ list_for_each_entry_safe(entry, next, used_pages_head, list_head) { ++ if ((u64)entry->physic_page == round_down(value_ptr, PAGE_SIZE)) { ++ return (void *)entry->shadow_page + in_page_offset; ++ } ++ } ++ ++ pr_err("fail to find shadow_data of percpu array %016llx\n", ++ (u64)(&array->map)); ++ return NULL; ++} ++#endif ++ + /* Called from eBPF program */ + static void *percpu_array_map_lookup_elem(struct bpf_map *map, void *key) + { +@@ -246,7 +422,17 @@ static void *percpu_array_map_lookup_elem(struct bpf_map *map, void *key) + if (unlikely(index >= array->map.max_entries)) + return NULL; + ++#ifdef CONFIG_HIVE ++ if (!map->is_aggregated) ++ return this_cpu_ptr(array->pptrs[index & array->index_mask]); ++ else { ++ u64 value_ptr = (u64)this_cpu_ptr( ++ array->pptrs[index & array->index_mask]); ++ return __percpu_array_map_lookup_elem(array, value_ptr); ++ } ++#else + return this_cpu_ptr(array->pptrs[index & array->index_mask]); ++#endif + } + + static void *percpu_array_map_lookup_percpu_elem(struct bpf_map *map, void *key, u32 cpu) +@@ -438,7 +624,11 @@ static void array_map_free(struct bpf_map *map) + if (array->map.map_type == BPF_MAP_TYPE_PERCPU_ARRAY) + bpf_array_free_percpu(array); + ++#ifdef CONFIG_HIVE ++ if ((array->map.map_flags & BPF_F_MMAPABLE) || array->map.is_aggregated) ++#else + if (array->map.map_flags & BPF_F_MMAPABLE) ++#endif + bpf_map_area_free(array_map_vmalloc_addr(array)); + else + bpf_map_area_free(array); +diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c +index 7c64ad4f3732..f65f1104557d 100644 +--- a/kernel/bpf/hashtab.c ++++ b/kernel/bpf/hashtab.c +@@ -15,6 +15,9 @@ + #include "bpf_lru_list.h" + #include "map_in_map.h" + #include ++#ifdef CONFIG_HIVE ++#include ++#endif + + #define HTAB_CREATE_FLAG_MASK \ + (BPF_F_NO_PREALLOC | BPF_F_NO_COMMON_LRU | BPF_F_NUMA_NODE | \ +@@ -205,6 +208,19 @@ static inline void __percpu *htab_elem_get_ptr(struct htab_elem *l, u32 key_size + return *(void __percpu **)(l->key + key_size); + } + ++#ifdef CONFIG_HIVE ++static inline void htab_normal_elem_set_ptr(struct htab_elem *l, u32 key_size, ++ void *pptr) ++{ ++ *(void **)(l->key + key_size) = pptr; ++} ++ ++static inline void *htab_normal_elem_get_ptr(struct htab_elem *l, u32 key_size) ++{ ++ return *(void **)(l->key + key_size); ++} ++#endif ++ + static void *fd_htab_map_get_ptr(const struct bpf_map *map, struct htab_elem *l) + { + return *(void **)(l->key + roundup(map->key_size, 8)); +@@ -275,6 +291,35 @@ static void htab_free_elems(struct bpf_htab *htab) + if (!htab_is_percpu(htab)) + goto free_elems; + ++#ifdef CONFIG_HIVE ++ if (unlikely(!htab->map.is_aggregated)) { ++ for (i = 0; i < htab->map.max_entries; i++) { ++ void __percpu *pptr; ++ pptr = htab_elem_get_ptr(get_htab_elem(htab, i), ++ htab->map.key_size); ++ free_percpu(pptr); ++ cond_resched(); ++ } ++ } else { ++ void __percpu *pptr; ++ struct bpf_used_page *used_page_entry, *used_page_next; ++ struct list_head *used_pages_list_head = &htab->map.used_pages->list_head; ++ ++ pptr = htab_elem_get_ptr(get_htab_elem(htab, 0), htab->map.key_size); ++ free_percpu(pptr); ++ cond_resched(); ++ ++ /* free used_pages list */ ++ if (used_pages_list_head && !list_empty(used_pages_list_head)) { ++ list_for_each_entry_safe(used_page_entry, used_page_next, ++ used_pages_list_head, list_head) { ++ list_del(&used_page_entry->list_head); ++ vfree(used_page_entry); ++ } ++ } ++ vfree(htab->map.used_pages); ++ } ++#else + for (i = 0; i < htab->map.max_entries; i++) { + void __percpu *pptr; + +@@ -283,8 +328,13 @@ static void htab_free_elems(struct bpf_htab *htab) + free_percpu(pptr); + cond_resched(); } ++#endif + free_elems: + bpf_map_area_free(htab->elems); ++#ifdef CONFIG_HIVE ++ if (!htab_is_percpu(htab)) ++ vfree(htab->map.value); ++#endif + } -+ #ifdef CONFIG_KEYP -+ if (((struct key_struct *)(fsverity_keyring->name_link.prev))->keys.nr_leaves_on_tree == 0) { -+ #else - if (fsverity_keyring->keys.nr_leaves_on_tree == 0) { -+ #endif - /* - * The ".fs-verity" keyring is empty, due to builtin signatures - * being supported by the kernel but not actually being used. -diff --git a/include/asm-generic/early_ioremap.h b/include/asm-generic/early_ioremap.h -index 9d0479f50f97..f501e0f965f8 100644 ---- a/include/asm-generic/early_ioremap.h -+++ b/include/asm-generic/early_ioremap.h -@@ -17,6 +17,9 @@ extern void *early_memremap_ro(resource_size_t phys_addr, - extern void *early_memremap_prot(resource_size_t phys_addr, - unsigned long size, unsigned long prot_val); - extern void early_iounmap(void __iomem *addr, unsigned long size); -+#ifdef CONFIG_PTP -+extern void early_iounmap_after_init(void __iomem *addr, unsigned long size); + /* The LRU list has a lock (lru_lock). Each htab bucket has a lock +@@ -318,18 +368,82 @@ static int prealloc_init(struct bpf_htab *htab) + { + u32 num_entries = htab->map.max_entries; + int err = -ENOMEM, i; ++#ifdef CONFIG_HIVE ++ void *data; ++ u64 value_size, alloc_size; +#endif - extern void early_memunmap(void *addr, unsigned long size); - #if defined(CONFIG_GENERIC_EARLY_IOREMAP) && defined(CONFIG_MMU) -diff --git a/include/asm-generic/fixmap.h b/include/asm-generic/fixmap.h -index 8cc7b09c1bc7..83158589a545 100644 ---- a/include/asm-generic/fixmap.h -+++ b/include/asm-generic/fixmap.h -@@ -70,6 +70,24 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr) - __set_fixmap(idx, 0, FIXMAP_PAGE_CLEAR) - #endif + if (htab_has_extra_elems(htab)) + num_entries += num_possible_cpus(); -+#ifdef CONFIG_PTP -+#ifndef clear_fixmap_init -+#define clear_fixmap_init(idx) \ -+ __iee_set_fixmap_pre_init(idx, 0, FIXMAP_PAGE_CLEAR) + htab->elems = bpf_map_area_alloc((u64)htab->elem_size * num_entries, + htab->map.numa_node); +- if (!htab->elems) ++ if (!htab->elems) { ++ pr_err("htab->elems = %llx\n", (u64)htab->elems); + return -ENOMEM; ++ } + + if (!htab_is_percpu(htab)) + goto skip_percpu_elems; + ++#ifdef CONFIG_HIVE ++realloc_elems: ++ if (!htab->map.is_aggregated) { ++ for (i = 0; i < num_entries; i++) { ++ u32 size = round_up(htab->map.value_size, 8); ++ void __percpu *pptr; ++ ++ pptr = bpf_map_alloc_percpu(&htab->map, size, 8, ++ GFP_USER | __GFP_NOWARN); ++ if (IS_ERR(pptr)) { ++ err = PTR_ERR(pptr); ++ goto free_elems; ++ } ++ htab_elem_set_ptr(get_htab_elem(htab, i), htab->map.key_size, ++ pptr); ++ cond_resched(); ++ } ++ } else { ++ u32 size = round_up(htab->map.value_size, 8); ++ void __percpu *pptr; ++ struct bpf_used_page *used_pages; ++ u64 start_address, end_address; ++ int page_cnt; ++ pptr = __alloc_percpu_gfp(size * num_entries, PAGE_SIZE, ++ GFP_USER | __GFP_NOWARN); ++ if (!pptr) { ++ pr_err("pptr = %llx\n", (u64)pptr); ++ htab->map.is_aggregated = false; ++ goto realloc_elems; ++ } ++ ++ for (i = 0; i < num_entries; i++) ++ htab_elem_set_ptr(get_htab_elem(htab, i), htab->map.key_size, ++ pptr + size * i); ++ ++ /* fBPF init user_pages */ ++ used_pages = vmalloc(sizeof(*used_pages)); ++ if (IS_ERR(used_pages)) { ++ pr_err("used_pages = %llx\n", (u64)used_pages); ++ goto free_elems; ++ } ++ htab->map.used_pages = used_pages; ++ INIT_LIST_HEAD(&used_pages->list_head); ++ mutex_init(&htab->map.used_page_mutex); ++ ++ /* fBPF record percpu physic pages */ ++ start_address = round_down((u64)pptr, PAGE_SIZE); ++ end_address = round_up((u64)pptr + htab->map.max_entries * size, PAGE_SIZE); ++ page_cnt = bpf_record_used_pages(start_address, end_address, ++ &htab->map.used_page_mutex, &htab->map.used_pages->list_head); ++ if (page_cnt < 0) { ++ err = page_cnt; ++ pr_err("page_cnt = %d\n", page_cnt); ++ goto free_elems; ++ } ++ htab->map.used_page_cnt = page_cnt; ++ } ++#else + for (i = 0; i < num_entries; i++) { + u32 size = round_up(htab->map.value_size, 8); + void __percpu *pptr; +@@ -342,8 +456,30 @@ static int prealloc_init(struct bpf_htab *htab) + pptr); + cond_resched(); + } +#endif + + skip_percpu_elems: ++#ifdef CONFIG_HIVE ++ if (htab_is_percpu(htab) || !htab->map.is_aggregated) ++ goto skip_elems; ++ ++ value_size = round_up(htab->map.value_size, 8); ++ alloc_size = PAGE_ALIGN(value_size * num_entries); ++ // data = bpf_map_area_alloc(alloc_size, htab->map.numa_node); ++ data = vmalloc(alloc_size); ++ if (!data) { ++ pr_err("data = %llx\n", (u64)data); ++ err = -ENOMEM; ++ goto free_elems; ++ } ++ htab->map.value = data; ++ htab->map.used_page_cnt = alloc_size >> PAGE_SHIFT; ++ for (i = 0; i < num_entries; i++) ++ htab_normal_elem_set_ptr(get_htab_elem(htab, i), round_up(htab->map.key_size, 8), ++ data + value_size * i); ++ ++skip_elems: ++#endif + if (htab_is_lru(htab)) + err = bpf_lru_init(&htab->lru, + htab->map.map_flags & BPF_F_NO_COMMON_LRU, +@@ -373,6 +509,29 @@ static int prealloc_init(struct bpf_htab *htab) + return err; + } + ++#ifdef CONFIG_HIVE ++void substitute_hash_value_ptr(struct bpf_map *map) ++{ ++ struct bpf_htab *htab = container_of(map, struct bpf_htab, map); ++ int i; ++ u32 value_size = round_up(map->value_size, 8); ++ int num_entries = map->max_entries; + -+#define __iee_set_fixmap_offset_pre_init(idx, phys, flags) \ -+({ \ -+ unsigned long ________addr; \ -+ __iee_set_fixmap_pre_init(idx, phys, flags); \ -+ ________addr = fix_to_virt(idx) + ((phys) & (PAGE_SIZE - 1)); \ -+ ________addr; \ -+}) ++ if (!htab_is_percpu(htab) && !htab_is_lru(htab)) ++ num_entries += num_possible_cpus(); + -+#define iee_set_fixmap_offset_pre_init(idx, phys) \ -+ __iee_set_fixmap_offset_pre_init(idx, phys, FIXMAP_PAGE_NORMAL) ++ for (i = 0; i < num_entries; i++) { ++ htab_normal_elem_set_ptr(get_htab_elem(htab, i), ++ round_up(htab->map.key_size, 8), ++ map->shadow_data + value_size * i); ++ } ++ ++ pr_info("substitute htab %d data from %016llx to %016llx-%016llx\n", ++ map->id, (u64)htab->map.value, (u64)map->shadow_data, ++ (u64)map->shadow_data + value_size * num_entries); ++} +#endif + - /* Return a pointer with offset calculated */ - #define __set_fixmap_offset(idx, phys, flags) \ - ({ \ -diff --git a/include/asm-generic/pgalloc.h b/include/asm-generic/pgalloc.h -index c75d4a753849..1d86942b242c 100644 ---- a/include/asm-generic/pgalloc.h -+++ b/include/asm-generic/pgalloc.h -@@ -7,6 +7,10 @@ - #define GFP_PGTABLE_KERNEL (GFP_KERNEL | __GFP_ZERO) - #define GFP_PGTABLE_USER (GFP_PGTABLE_KERNEL | __GFP_ACCOUNT) - -+#ifdef CONFIG_PTP -+#include + static void prealloc_destroy(struct bpf_htab *htab) + { + htab_free_elems(htab); +@@ -489,6 +648,19 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) + + bpf_map_init_from_attr(&htab->map, attr); + ++#ifdef CONFIG_HIVE ++ if (htab->map.map_type == BPF_MAP_TYPE_HASH || ++ htab->map.map_type == BPF_MAP_TYPE_PERCPU_HASH || ++ htab->map.map_type == BPF_MAP_TYPE_LRU_HASH || ++ htab->map.map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) { ++ htab->map.is_aggregated = true; ++ htab->map.used_pages = NULL; ++ htab->map.map_flags &= ~BPF_F_NO_PREALLOC; ++ // pr_warn("BPF_F_NO_PREALLOC flag is deprecated\n"); ++ prealloc = true; ++ } +#endif + - /** - * __pte_alloc_one_kernel - allocate memory for a PTE-level kernel page table - * @mm: the mm_struct of the current context -@@ -23,6 +27,7 @@ static inline pte_t *__pte_alloc_one_kernel(struct mm_struct *mm) + if (percpu_lru) { + /* ensure each CPU's lru list has >=1 elements. + * since we are at it, make each lru list has the same +@@ -512,7 +684,12 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) - if (!ptdesc) - return NULL; -+ - return ptdesc_address(ptdesc); - } + htab->elem_size = sizeof(struct htab_elem) + + round_up(htab->map.key_size, 8); ++#ifdef CONFIG_HIVE ++ /* elem size = htab_elem + key + value */ ++ if (percpu || htab->map.is_aggregated) ++#else + if (percpu) ++#endif + htab->elem_size += sizeof(void *); + else + htab->elem_size += round_up(htab->map.value_size, 8); +@@ -699,8 +876,17 @@ static void *htab_map_lookup_elem(struct bpf_map *map, void *key) + { + struct htab_elem *l = __htab_map_lookup_elem(map, key); -@@ -106,6 +111,7 @@ static inline void pte_free(struct mm_struct *mm, struct page *pte_page) - struct ptdesc *ptdesc = page_ptdesc(pte_page); ++#ifdef CONFIG_HIVE ++ if (l) { ++ if (map->is_aggregated) ++ return htab_normal_elem_get_ptr(l, round_up(map->key_size, 8)); ++ else ++ return htab_normal_elem_get_ptr(l, round_up(map->key_size, 8)); ++ } ++#else + if (l) + return l->key + round_up(map->key_size, 8); ++#endif - pagetable_pte_dtor(ptdesc); -+ - pagetable_free(ptdesc); + return NULL; + } +@@ -725,9 +911,21 @@ static int htab_map_gen_lookup(struct bpf_map *map, struct bpf_insn *insn_buf) + (void *(*)(struct bpf_map *map, void *key))NULL)); + *insn++ = BPF_EMIT_CALL(__htab_map_lookup_elem); + *insn++ = BPF_JMP_IMM(BPF_JEQ, ret, 0, 1); ++#ifdef CONFIG_HIVE ++ // if (map->is_aggregated) ++ *insn++ = BPF_LDX_MEM(BPF_DW, ret, ret, ++ offsetof(struct htab_elem, key) + ++ round_up(map->key_size, 8)); ++ // else { ++ // *insn++ = BPF_ALU64_IMM(BPF_ADD, ret, ++ // offsetof(struct htab_elem, key) + ++ // roundup(map->key_size, 8)); ++ // } ++#else + *insn++ = BPF_ALU64_IMM(BPF_ADD, ret, + offsetof(struct htab_elem, key) + + round_up(map->key_size, 8)); ++#endif + return insn - insn_buf; } -@@ -149,6 +155,7 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) +@@ -739,7 +937,14 @@ static __always_inline void *__htab_lru_map_lookup_elem(struct bpf_map *map, + if (l) { + if (mark) + bpf_lru_node_set_ref(&l->lru_node); ++ #ifdef CONFIG_HIVE ++ if (map->is_aggregated) ++ return htab_normal_elem_get_ptr(l, round_up(map->key_size, 8)); ++ else ++ return l->key + round_up(map->key_size, 8); ++ #else + return l->key + round_up(map->key_size, 8); ++ #endif + } - BUG_ON((unsigned long)pmd & (PAGE_SIZE-1)); - pagetable_pmd_dtor(ptdesc); -+ - pagetable_free(ptdesc); + return NULL; +@@ -774,9 +979,20 @@ static int htab_lru_map_gen_lookup(struct bpf_map *map, + offsetof(struct htab_elem, lru_node) + + offsetof(struct bpf_lru_node, ref), + 1); ++#ifdef CONFIG_HIVE ++ if (map->is_aggregated) ++ *insn++ = BPF_LDX_MEM(BPF_DW, ret, ret, ++ offsetof(struct htab_elem, key) + ++ round_up(map->key_size, 8)); ++ else ++ *insn++ = BPF_ALU64_IMM(BPF_ADD, ret, ++ offsetof(struct htab_elem, key) + ++ round_up(map->key_size, 8)); ++#else + *insn++ = BPF_ALU64_IMM(BPF_ADD, ret, + offsetof(struct htab_elem, key) + + round_up(map->key_size, 8)); ++#endif + return insn - insn_buf; } - #endif -diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h -index 22384baee10e..9a6de5467a1c 100644 ---- a/include/asm-generic/tlb.h -+++ b/include/asm-generic/tlb.h -@@ -209,6 +209,9 @@ struct mmu_table_batch { - ((PAGE_SIZE - sizeof(struct mmu_table_batch)) / sizeof(void *)) - extern void tlb_remove_table(struct mmu_gather *tlb, void *table); -+#ifdef CONFIG_PTP -+extern void iee_tlb_remove_table(struct mmu_gather *tlb, void *table); -+#endif +@@ -1002,7 +1218,11 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, + bool percpu, bool onallcpus, + struct htab_elem *old_elem) + { ++#ifdef CONFIG_HIVE ++ u32 size = round_up(htab->map.value_size, 8); ++#else + u32 size = htab->map.value_size; ++#endif + bool prealloc = htab_is_prealloc(htab); + struct htab_elem *l_new, **pl_new; + void __percpu *pptr; +@@ -1064,11 +1284,30 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, + htab_elem_set_ptr(l_new, key_size, pptr); + } else if (fd_htab_map_needs_adjust(htab)) { + size = round_up(size, 8); ++ #ifdef CONFIG_HIVE ++ if (htab->map.is_aggregated) { ++ memcpy(htab_normal_elem_get_ptr(l_new, round_up(key_size, 8)), ++ value, size); ++ } else ++ memcpy(l_new->key + round_up(key_size, 8), value, size); ++ #else + memcpy(l_new->key + round_up(key_size, 8), value, size); ++ #endif + } else { ++ #ifdef CONFIG_HIVE ++ if (htab->map.is_aggregated) ++ copy_map_value(&htab->map, ++ htab_normal_elem_get_ptr(l_new, round_up(key_size, 8)), ++ value); ++ else ++ copy_map_value(&htab->map, ++ l_new->key + round_up(key_size, 8), ++ value); ++ #else + copy_map_value(&htab->map, + l_new->key + round_up(key_size, 8), + value); ++ #endif + } - #else /* !CONFIG_MMU_GATHER_HAVE_TABLE_FREE */ + l_new->hash = hash; +@@ -1129,9 +1368,20 @@ static long htab_map_update_elem(struct bpf_map *map, void *key, void *value, + return ret; + if (l_old) { + /* grab the element lock and update value in place */ ++ #ifdef CONFIG_HIVE ++ if (map->is_aggregated) ++ copy_map_value_locked(map, ++ htab_normal_elem_get_ptr(l_old, round_up(key_size, 8)), ++ value, false); ++ else ++ copy_map_value_locked(map, ++ l_old->key + round_up(key_size, 8), ++ value, false); ++ #else + copy_map_value_locked(map, + l_old->key + round_up(key_size, 8), + value, false); ++ #endif + return 0; + } + /* fall through, grab the bucket lock and lookup again. +@@ -1157,9 +1407,20 @@ static long htab_map_update_elem(struct bpf_map *map, void *key, void *value, + * grab the element lock in addition to the bucket lock + * and update element in place + */ ++ #ifdef CONFIG_HIVE ++ if (map->is_aggregated) ++ copy_map_value_locked(map, ++ htab_normal_elem_get_ptr(l_old, round_up(key_size, 8)), ++ value, false); ++ else ++ copy_map_value_locked(map, ++ l_old->key + round_up(key_size, 8), ++ value, false); ++ #else + copy_map_value_locked(map, + l_old->key + round_up(key_size, 8), + value, false); ++ #endif + ret = 0; + goto err; + } +@@ -1229,8 +1490,17 @@ static long htab_lru_map_update_elem(struct bpf_map *map, void *key, void *value + l_new = prealloc_lru_pop(htab, key, hash); + if (!l_new) + return -ENOMEM; ++#ifdef CONFIG_HIVE ++ if (map->is_aggregated) ++ copy_map_value(&htab->map, ++ htab_normal_elem_get_ptr(l_new, round_up(map->key_size, 8)), value); ++ else ++ copy_map_value(&htab->map, ++ l_new->key + round_up(map->key_size, 8), value); ++#else + copy_map_value(&htab->map, + l_new->key + round_up(map->key_size, 8), value); ++#endif -@@ -493,7 +496,11 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) + ret = htab_lock_bucket(htab, b, hash, &flags); + if (ret) +@@ -2298,13 +2568,52 @@ const struct bpf_map_ops htab_lru_map_ops = { + .iter_seq_info = &iter_seq_info, + }; - static inline void tlb_remove_ptdesc(struct mmu_gather *tlb, void *pt) ++#ifdef CONFIG_HIVE ++static void *percpu_htab_aggregated_addr(struct bpf_htab *htab, const void *value_ptr1) ++{ ++ // struct page *phy_ptr; ++ struct list_head *used_pages_head; ++ struct bpf_used_page *entry; ++ struct bpf_used_page *next; ++ u64 in_page_offset; ++ ++ // phy_ptr = kv_virt_to_page(value_ptr1); ++ used_pages_head = &htab->map.used_pages->list_head; ++ in_page_offset = (u64)value_ptr1 - round_down((u64)value_ptr1, PAGE_SIZE); ++ ++ if (!used_pages_head) { ++ pr_err("used_pages_head is empty = %llx\n", (u64)used_pages_head); ++ return ERR_PTR(-ENOMEM); ++ } ++ ++ list_for_each_entry_safe(entry, next, used_pages_head, list_head) { ++ if ((u64)entry->physic_page == round_down((u64)value_ptr1, PAGE_SIZE)) { ++ return (void *)entry->shadow_page + in_page_offset; ++ } ++ } ++ ++ return 0; ++} ++#endif ++ + /* Called from eBPF program */ + static void *htab_percpu_map_lookup_elem(struct bpf_map *map, void *key) { -+ #ifdef CONFIG_PTP -+ iee_tlb_remove_table(tlb, pt); -+ #else - tlb_remove_table(tlb, pt); -+ #endif + struct htab_elem *l = __htab_map_lookup_elem(map, key); + ++#ifdef CONFIG_HIVE ++ if (l) { ++ if (map->is_aggregated && map->shadow_data) { ++ struct bpf_htab *htab = container_of(map, struct bpf_htab, map); ++ void *value_ptr = this_cpu_ptr(htab_elem_get_ptr(l, map->key_size)); ++ return percpu_htab_aggregated_addr(htab, value_ptr); ++ } else ++ return this_cpu_ptr(htab_elem_get_ptr(l, map->key_size)); ++ } ++#else + if (l) + return this_cpu_ptr(htab_elem_get_ptr(l, map->key_size)); ++#endif + else + return NULL; } +@@ -2317,8 +2626,20 @@ static void *htab_percpu_map_lookup_percpu_elem(struct bpf_map *map, void *key, + return NULL; - /* Like tlb_remove_ptdesc, but for page-like page directories. */ -diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h -index 174d865ce46e..0d945cdd78e0 100644 ---- a/include/asm-generic/vmlinux.lds.h -+++ b/include/asm-generic/vmlinux.lds.h -@@ -379,6 +379,17 @@ - KEEP(*(.dtb.init.rodata)) \ - __dtb_end = .; - -+#ifdef CONFIG_KOI -+#define KOI_DATA() \ -+ . = ALIGN(PAGE_SIZE); \ -+ __koi_data_start = .; \ -+ *(.data..koi) \ -+ . = ALIGN(PAGE_SIZE); \ -+ __koi_data_end = .; + l = __htab_map_lookup_elem(map, key); ++#ifdef CONFIG_HIVE ++ if (l) { ++ if (map->is_aggregated) { ++ struct bpf_htab *htab = container_of(map, struct bpf_htab, map); ++ void *value_ptr = this_cpu_ptr(htab_elem_get_ptr(l, map->key_size)); ++ return percpu_htab_aggregated_addr(htab, value_ptr); ++ } ++ else ++ return per_cpu_ptr(htab_elem_get_ptr(l, map->key_size), cpu); ++ } +#else -+#define KOI_DATA() + if (l) + return per_cpu_ptr(htab_elem_get_ptr(l, map->key_size), cpu); +#endif + else + return NULL; + } +diff --git a/kernel/bpf/sfi_bpf.c b/kernel/bpf/sfi_bpf.c +new file mode 100644 +index 000000000000..93d8c4977820 +--- /dev/null ++++ b/kernel/bpf/sfi_bpf.c +@@ -0,0 +1,1387 @@ ++#include ++#include ++#include "disasm.h" ++#include ++ ++extern pte_t *bpf_sfi_get_ptep(u64 addr); ++ ++const enum bpf_map_type can_lookup_map_types[] = { ++ BPF_MAP_TYPE_ARRAY, ++ BPF_MAP_TYPE_PERCPU_ARRAY, ++ BPF_MAP_TYPE_HASH, ++ BPF_MAP_TYPE_LRU_HASH, ++ BPF_MAP_TYPE_PERCPU_HASH, ++ BPF_MAP_TYPE_LRU_PERCPU_HASH, ++ BPF_MAP_TYPE_CPUMAP, ++ BPF_MAP_TYPE_CGROUP_STORAGE, ++ BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE, ++ BPF_MAP_TYPE_QUEUE, ++ BPF_MAP_TYPE_STACK, ++ BPF_MAP_TYPE_SK_STORAGE, ++ BPF_MAP_TYPE_INODE_STORAGE, ++ BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, ++ BPF_MAP_TYPE_LPM_TRIE, ++ BPF_MAP_TYPE_SOCKMAP, ++ BPF_MAP_TYPE_SOCKHASH, ++}; ++ ++void do_fbpf_log(const char *func_name, const char *fmt, ...) ++{ ++ #ifdef FBPF_LOG_ENABLE ++ va_list args; ++ char buffer[256]; ++ ++ va_start(args, fmt); ++ vsnprintf(buffer, sizeof(buffer), fmt, args); ++ va_end(args); ++ ++ pr_info("%s: %s", func_name, buffer); ++ #endif ++} ++ ++const char *bpf_map_type_strings[] = { ++ "BPF_MAP_TYPE_UNSPEC", ++ "BPF_MAP_TYPE_HASH", ++ "BPF_MAP_TYPE_ARRAY", ++ "BPF_MAP_TYPE_PROG_ARRAY", ++ "BPF_MAP_TYPE_PERF_EVENT_ARRAY", ++ "BPF_MAP_TYPE_PERCPU_HASH", ++ "BPF_MAP_TYPE_PERCPU_ARRAY", ++ "BPF_MAP_TYPE_STACK_TRACE", ++ "BPF_MAP_TYPE_CGROUP_ARRAY", ++ "BPF_MAP_TYPE_LRU_HASH", ++ "BPF_MAP_TYPE_LRU_PERCPU_HASH", ++ "BPF_MAP_TYPE_LPM_TRIE", ++ "BPF_MAP_TYPE_ARRAY_OF_MAPS", ++ "BPF_MAP_TYPE_HASH_OF_MAPS", ++ "BPF_MAP_TYPE_DEVMAP", ++ "BPF_MAP_TYPE_SOCKMAP", ++ "BPF_MAP_TYPE_CPUMAP", ++ "BPF_MAP_TYPE_XSKMAP", ++ "BPF_MAP_TYPE_SOCKHASH", ++ "BPF_MAP_TYPE_CGROUP_STORAGE", ++ "BPF_MAP_TYPE_REUSEPORT_SOCKARRAY", ++ "BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE", ++ "BPF_MAP_TYPE_QUEUE", ++ "BPF_MAP_TYPE_STACK", ++ "BPF_MAP_TYPE_SK_STORAGE", ++ "BPF_MAP_TYPE_DEVMAP_HASH", ++ "BPF_MAP_TYPE_STRUCT_OPS", ++ "BPF_MAP_TYPE_RINGBUF", ++ "BPF_MAP_TYPE_INODE_STORAGE", ++}; ++ ++int bpf_record_used_pages(u64 start_addr, u64 end_addr, ++ struct mutex *write_mutex, struct list_head *head) ++{ ++ int cpu; ++ u64 page_addr = start_addr; ++ int mmapable_page_cnt = 0; ++ ++ while (page_addr < end_addr) { ++ for_each_possible_cpu(cpu) { ++ // struct page *physic_page; ++ void *ptr; ++ struct bpf_used_page* new_page; ++ ++ ptr = per_cpu_ptr((void *)page_addr, cpu); ++ // if (is_vmalloc_addr(ptr)) { ++ // physic_page = vmalloc_to_page(ptr); ++ // } else { ++ // physic_page = virt_to_page(ptr); ++ // } ++ // if (!physic_page) { ++ // pr_err("cannot find physic page for %016llx\n", page_addr); ++ // return -ENOENT; ++ // } ++ new_page = vmalloc(sizeof(*new_page)); ++ new_page->physic_page = ptr; ++ ++ mutex_lock(write_mutex); ++ // printk("virt addr=%016llx\n", (u64)ptr); ++ list_add(&new_page->list_head, head); ++ mmapable_page_cnt++; ++ mutex_unlock(write_mutex); ++ } ++ page_addr += PAGE_SIZE; ++ } ++ ++ return mmapable_page_cnt; ++} ++ ++struct page *kv_virt_to_page(const void *vaddr) ++{ ++ if (is_vmalloc_addr(vaddr)) ++ return vmalloc_to_page(vaddr); ++ else ++ return virt_to_page(vaddr); ++} ++ ++static bool map_can_lookup(struct bpf_map *map) ++{ ++ int i; ++ enum bpf_map_type type = map->map_type; ++ ++ for (i = 0; i < ARRAY_SIZE(can_lookup_map_types); i++) ++ if (type == can_lookup_map_types[i]) ++ return true; ++ ++ return false; ++} ++ ++static int get_env_map_cnt(struct bpf_verifier_env *env) ++{ ++ int i; ++ struct bpf_map *map; ++ int page_cnt = 0; ++ ++ // calculate maps page count ++ for (i = 0; i < env->used_map_cnt; i++) { ++ map = env->used_maps[i]; ++ if (map->is_aggregated && map->used_page_cnt) { ++ page_cnt += map->used_page_cnt; ++ fbpf_log("map %d %s page_cnt = %d\n", map->id, ++ bpf_map_type_strings[map->map_type], map->used_page_cnt); ++ } else if (map_can_lookup(map)) { ++ /* if do not support this map, just return to normal bpf load */ ++ pr_err("unsupport map_type %s\n", bpf_map_type_strings[map->map_type]); ++ return -EPERM; ++ // continue; ++ } ++ } ++ ++ return page_cnt; ++} ++ ++static inline u64 count_page(struct page **pages, u64 start_addr, int *page_index) ++{ ++ pages[*page_index] = (struct page *)start_addr; ++ ++ // pr_info("addr of page %d = %llx\n", *page_index, (u64)start_addr); ++ ++ start_addr += PAGE_SIZE; ++ (*page_index)++; ++ ++ return start_addr; ++} ++ ++static int count_percpu_pages(struct bpf_map *map, struct page **pages, int *page_index) ++{ ++ struct list_head *used_pages_head = NULL; ++ struct bpf_used_page *entry; ++ struct bpf_used_page *next; ++ int i = 0; ++ ++ used_pages_head = &map->used_pages->list_head; ++ ++ /* should not list_del and free here, later other progs may reuse this map */ ++ list_for_each_entry_safe(entry, next, used_pages_head, list_head) { ++ // printk("count page %016llx\n", entry->physic_page); ++ // pages[*page_index] = entry->physic_page; ++ // pages[*page_index] = page_address(entry->physic_page); ++ // entry->shadow_page = *page_index; ++ // if (!pages[*page_index]) { ++ // pr_err("illegal address=%016llx\n", (u64)pages[*page_index]); ++ // return -EFAULT; ++ // } ++ // pr_info("addr of page %d = %llx\n", *page_index, (u64)page_address(entry->physic_page)); ++ // (*page_index)++; ++ count_page(pages, (u64)entry->physic_page, page_index); ++ entry->shadow_page = i; ++ i++; ++ } ++ ++ return 0; ++} ++ ++static int count_all_pages(struct bpf_verifier_env *env, struct page **pages, int *page_index) ++{ ++ struct bpf_map *map; ++ int i, j; ++ u64 start_addr; ++ int err; ++ int page_index_before; ++ ++ /* 1. coutn pages in low guard region */ ++ // start_addr = PAGE_ALIGN((u64)env->prog->low_guard_region_addr); ++ // for (i = 0; i < env->prog->guard_region_page_cnt / 2; i++) { ++ // // pages[*page_index] = kv_virt_to_page((void *)start_addr); ++ // start_addr = count_page(pages, start_addr, page_index); ++ ++ // /* DEBUG check addr */ ++ // // pr_info("check page %d addr 0x%llx\n", i, start_addr); ++ // // *(u64 *)start_addr = 0; ++ // // pr_info("write into 0x%llx page pass\n", start_addr); ++ ++ // /* DEBUG check get_ptep */ ++ // // pte_t *ptep = bpf_sfi_get_ptep(start_addr); ++ // // if (IS_ERR(ptep)) ++ // // pr_err("get ptep of 0x%llx failed\n", start_addr); ++ // // else ++ // // pr_info("get ptep of 0x%llx pass\n", start_addr); ++ // } ++ ++ /* 2. count pages in map's data area */ ++ for (i = 0; i < env->used_map_cnt; i++) { ++ page_index_before = *page_index; ++ map = env->used_maps[i]; ++ ++ if (!map->is_aggregated) ++ continue; ++ ++ if (map->map_type == BPF_MAP_TYPE_ARRAY || ++ map->map_type == BPF_MAP_TYPE_CGROUP_ARRAY) { ++ start_addr = (u64)map->value; ++ } else if (map->map_type == BPF_MAP_TYPE_HASH || ++ map->map_type == BPF_MAP_TYPE_LRU_HASH) { ++ start_addr = (u64)map->value; ++ } else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY || ++ map->map_type == BPF_MAP_TYPE_PERCPU_HASH || ++ map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) { ++ err = count_percpu_pages(map, pages, page_index); ++ if (err) ++ return err; ++ goto hook_end; ++ } else if (map->map_type == BPF_MAP_TYPE_PROG_ARRAY) { ++ pr_err("WARNING: ignore map %s\n", bpf_map_type_strings[map->map_type]); ++ goto hook_end; ++ } else { ++ pr_err("ERROR: miss map %s in count_all_pages()\n", ++ bpf_map_type_strings[map->map_type]); ++ return -ENOENT; ++ } ++ ++ /* assert start_addr is page_aligned */ ++ if (unlikely(!PAGE_ALIGNED(start_addr))) { ++ pr_err("ERROR: fbpf self, map_data should be PAGE_ALIGNED\n"); ++ pr_err("map %s, addr=%016llx", ++ bpf_map_type_strings[map->map_type], (u64)map); ++ return -EFAULT; ++ } ++ ++ /* for normal map with base addr */ ++ for (j = 0; j < map->used_page_cnt; j++) { ++ // pages[*page_index] = kv_virt_to_page((void *)start_addr); ++ start_addr = count_page(pages, start_addr, page_index); ++ } ++ ++hook_end: ++ fbpf_log("hook aggregated area for map %d: %s, %016llx, \ ++page_cnt: %d, should be: %d\n", ++ map->id, bpf_map_type_strings[map->map_type], (u64)map, ++ *page_index - page_index_before, map->used_page_cnt); ++ } ++ ++ /* 3. count pages in skb area */ ++ start_addr = PAGE_ALIGN((u64)env->prog->shadow_skb_addr); ++ for (i = 0; i < env->prog->shadow_skb_page_cnt; i++) { ++ // pages[*page_index] = kv_virt_to_page((void *)start_addr); ++ start_addr = count_page(pages, start_addr, page_index); ++ } ++ ++ /* 4. count pages in stack area */ ++ start_addr = PAGE_ALIGN((u64)env->prog->shadow_stack_addr); ++ for (i = 0; i < env->prog->shadow_stack_page_cnt; i++) { ++ // pages[*page_index] = kv_virt_to_page((void *)start_addr); ++ start_addr = count_page(pages, start_addr, page_index); ++ } ++ ++ /* 5. coutn pages in high guard region */ ++ // start_addr = PAGE_ALIGN((u64)env->prog->high_guard_region_addr); ++ // for (i = 0; i < env->prog->guard_region_page_cnt / 2; i++) { ++ // start_addr = count_page(pages, start_addr, page_index); ++ // } ++ ++ return 0; ++} ++ ++static int record_percpu_map_shadow_page(struct bpf_map *map) ++{ ++ struct list_head *used_pages_head = NULL; ++ struct bpf_used_page *entry; ++ struct bpf_used_page *next; ++ void *shadow_base_addr = map->shadow_data; ++ ++ used_pages_head = &map->used_pages->list_head; ++ ++ /* fbpf should not list_del and free here, ++ later other progs may reuse this map. ++ instead, map_free will do this job */ ++ list_for_each_entry_safe(entry, next, used_pages_head, list_head) { ++ entry->shadow_page = (u64)shadow_base_addr + PAGE_SIZE * ++ entry->shadow_page; /* shadow_page is the index recorded in count_all_pages() */ ++ pteval_t phy_pte, vir_pte; ++ phy_pte = pte_val(*bpf_sfi_get_ptep((u64)entry->physic_page)); ++ vir_pte = pte_val(*bpf_sfi_get_ptep((u64)entry->shadow_page)); ++ if (unlikely(phy_pte != vir_pte)) { ++ pr_err("ERROR: recorded shadow_page unequal actual shadow_page\n"); ++ return -EFAULT; ++ } ++ } ++ ++ return 0; ++} ++ ++// static inline int set_as_guard_page(unsigned long addr) ++// { ++// pte_t pte, *ptep; ++ ++// ptep = bpf_sfi_get_ptep(addr); ++// if (IS_ERR(ptep)) ++// return PTR_ERR(ptep); ++ ++// pte = __pte(pte_val(*ptep) & ~PTE_VALID); ++// set_pte(ptep, __pte((pte_val(pte) | PTE_BPF_SFI_GP))); ++ ++// flush_tlb_kernel_range(addr, addr + PAGE_SIZE); ++// isb(); ++ ++// return 0; ++// } ++ ++inline void *alloc_aligned_memory(u64 size) ++{ ++ // unsigned long order = get_order(size); ++ // void *ptr = (void *)__get_free_pages(GFP_KERNEL, order); ++ int page_cnt = size >> PAGE_SHIFT; ++ void *base = vmalloc((2 * page_cnt - 1) * PAGE_SIZE); ++ if (IS_ERR(base)) { ++ printk(KERN_ERR "Failed to allocate memory\n"); ++ return ERR_PTR(-ENOMEM); ++ } ++ ++ void *ptr = (void *)(((unsigned long)base + page_cnt * PAGE_SIZE) & ~(size - 1)); ++ ++ // check alignment ++ if ((unsigned long)ptr & (size - 1)) { ++ // free_pages((unsigned long)ptr, order); ++ vfree(base); ++ pr_err("Memory not properly aligned\n"); ++ return ERR_PTR(-ENOMEM); ++ } ++ ++ return ptr; ++} ++ ++inline int map_physic_pages(struct page **pages, void *virt_addr, int page_cnt) ++{ ++ int i; ++ ++ for (i = 0; i < page_cnt; i++) { ++ // u64 origin_addr = page_to_pfn(pages[i]) << PAGE_SHIFT; ++ // u64 origin_addr = (u64)page_address(pages[i]); ++ u64 origin_addr = (u64)pages[i]; ++ // pr_info("get origin ptep of page %d, addr = %llx\n", i, origin_addr); ++ pte_t *origin_ptep = bpf_sfi_get_ptep(origin_addr); ++ if (IS_ERR(origin_ptep)) { ++ // pr_err("get origin ptep of 0x%llx failed\n", origin_addr); ++ return PTR_ERR(origin_ptep); ++ } ++ ++ // pr_info("get cur ptep of page %d\n", i); ++ u64 cur_addr = (u64)virt_addr + i * PAGE_SIZE; ++ pte_t *ptep = bpf_sfi_get_ptep(cur_addr); ++ if (IS_ERR(ptep)) { ++ // pr_err("get sfi ptep of 0x%llx failed\n", cur_addr); ++ return PTR_ERR(ptep); ++ } ++ ++ #ifdef CONFIG_PTP ++ set_pte(ptep, *origin_ptep); ++ #else ++ *ptep = *origin_ptep; ++ #endif ++ } ++ ++ return 0; ++} + - /* - * .data section - */ -@@ -403,8 +414,8 @@ - BRANCH_PROFILE() \ - TRACE_PRINTKS() \ - BPF_RAW_TP() \ -- TRACEPOINT_STR() -- -+ TRACEPOINT_STR() \ -+ KOI_DATA() - /* - * Data section helpers - */ -@@ -1126,6 +1137,23 @@ - * They will fit only a subset of the architectures - */ - -+#ifdef CONFIG_CREDP -+ #define CRED_DATA \ -+ . = ALIGN(PAGE_SIZE); \ -+ *(.iee.cred) \ -+ . = ALIGN(PAGE_SIZE); -+#else -+ #define CRED_DATA -+#endif ++/** ++ * sfi_bpf space: ++ * guard page 8 pages ++ * map's data 0xffff80008457f000 - 0xffff80008457f000 ++ * skb 0xffff80008457f000 - 0xffff80008457f000 ++ * stack 0xffff80008457f000 - 0xffff800084580000 ++ * guard page 8 pages ++ */ ++int bpf_sfi_aggregate_memory(struct bpf_verifier_env *env) ++{ ++ struct page **pages = NULL; ++ struct bpf_map *map; ++ u64 start_addr; ++ void *shadow_base_addr = NULL, *shadow_high_addr = NULL; ++ int i, page_index = 0; ++ int total_page_cnt, map_page_cnt, stack_page_cnt, skb_page_cnt/*, guard_page_cnt*/; ++ int err; ++ void *shadow_stack_addr, *shadow_skb_addr; ++ ++ /* calculate page_cnt */ ++ env->prog->map_page_cnt = map_page_cnt = get_env_map_cnt(env); ++ stack_page_cnt = round_up(MAX_BPF_STACK, PAGE_SIZE) >> PAGE_SHIFT; ++ if (env->prog->type == BPF_PROG_TYPE_SCHED_CLS || ++ env->prog->type == BPF_PROG_TYPE_SCHED_ACT || ++ env->prog->type == BPF_PROG_TYPE_XDP || ++ env->prog->type == BPF_PROG_TYPE_LWT_XMIT || ++ env->prog->type == BPF_PROG_TYPE_SK_SKB || ++ env->prog->type == BPF_PROG_TYPE_SK_MSG) ++ skb_page_cnt = 16; ++ else ++ skb_page_cnt = 0; ++ // guard_page_cnt = 16; ++ ++ /* roundup totoal page number to power of two for SFI consideration */ ++ env->prog->shadow_skb_page_cnt = skb_page_cnt; ++ env->prog->total_page_cnt = total_page_cnt = roundup_pow_of_two(stack_page_cnt + map_page_cnt + skb_page_cnt); ++ env->prog->shadow_stack_page_cnt = stack_page_cnt = total_page_cnt - map_page_cnt - skb_page_cnt; ++ pr_info("page_cnt: map=%d, skb=%d, stack=%d\n", ++ map_page_cnt, skb_page_cnt, stack_page_cnt); ++ ++ /* map map's value area to pages */ ++ pages = kzalloc(sizeof(struct page *) * (total_page_cnt), GFP_KERNEL | __GFP_NOWARN); ++ if (IS_ERR(pages)) { ++ pr_err("ERROR: alloc tmp pages array failed\n"); ++ err = PTR_ERR(pages); ++ goto ret; ++ } + -+#ifdef CONFIG_IEE_SELINUX_P -+ #define IEE_SELINUX_DATA \ -+ . = ALIGN(PAGE_SIZE); \ -+ *(.iee.selinux) \ -+ . = ALIGN(PAGE_SIZE); -+#else -+ #define IEE_SELINUX_DATA -+#endif - - /* - * Writeable data. -@@ -1143,6 +1171,8 @@ - . = ALIGN(PAGE_SIZE); \ - .data : AT(ADDR(.data) - LOAD_OFFSET) { \ - INIT_TASK_DATA(inittask) \ -+ CRED_DATA \ -+ IEE_SELINUX_DATA \ - NOSAVE_DATA \ - PAGE_ALIGNED_DATA(pagealigned) \ - CACHELINE_ALIGNED_DATA(cacheline) \ -diff --git a/include/keys/asymmetric-subtype.h b/include/keys/asymmetric-subtype.h -index d55171f640a0..1293c5a1c624 100644 ---- a/include/keys/asymmetric-subtype.h -+++ b/include/keys/asymmetric-subtype.h -@@ -54,7 +54,11 @@ struct asymmetric_key_subtype { - static inline - struct asymmetric_key_subtype *asymmetric_key_subtype(const struct key *key) - { -+ #ifdef CONFIG_KEYP -+ return ((union key_payload *)(key->name_link.next))->data[asym_subtype]; -+ #else - return key->payload.data[asym_subtype]; -+ #endif - } - - #endif /* _KEYS_ASYMMETRIC_SUBTYPE_H */ -diff --git a/include/keys/asymmetric-type.h b/include/keys/asymmetric-type.h -index 69a13e1e5b2e..6cd556bfb216 100644 ---- a/include/keys/asymmetric-type.h -+++ b/include/keys/asymmetric-type.h -@@ -69,13 +69,21 @@ extern struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1, - static inline - const struct asymmetric_key_ids *asymmetric_key_ids(const struct key *key) - { -+ #ifdef CONFIG_KEYP -+ return ((union key_payload *)(key->name_link.next))->data[asym_key_ids]; -+ #else - return key->payload.data[asym_key_ids]; -+ #endif - } - - static inline - const struct public_key *asymmetric_key_public_key(const struct key *key) - { -+ #ifdef CONFIG_KEYP -+ return ((union key_payload *)(key->name_link.next))->data[asym_crypto]; -+ #else - return key->payload.data[asym_crypto]; -+ #endif - } - - extern struct key *find_asymmetric_key(struct key *keyring, -diff --git a/include/keys/request_key_auth-type.h b/include/keys/request_key_auth-type.h -index 36b89a933310..63d5d9f66cb4 100644 ---- a/include/keys/request_key_auth-type.h -+++ b/include/keys/request_key_auth-type.h -@@ -26,7 +26,11 @@ struct request_key_auth { - - static inline struct request_key_auth *get_request_key_auth(const struct key *key) - { -+ #ifdef CONFIG_KEYP -+ return ((union key_payload *)(key->name_link.next))->data[0]; -+ #else - return key->payload.data[0]; -+ #endif - } - - -diff --git a/include/linux/cred.h b/include/linux/cred.h -index e01c6d094a30..c7b3fe009f66 100644 ---- a/include/linux/cred.h -+++ b/include/linux/cred.h -@@ -18,6 +18,11 @@ - #include - #include - -+#ifdef CONFIG_CREDP -+#include -+#include -+#endif ++ /* alloc tmp skb page to fill in pages */ ++ if (skb_page_cnt) { ++ shadow_skb_addr = vmalloc(skb_page_cnt * PAGE_SIZE); ++ if (IS_ERR(shadow_skb_addr)) { ++ pr_err("alloc skb area failed\n"); ++ err = PTR_ERR(shadow_skb_addr); ++ goto ret; ++ } ++ env->prog->shadow_skb_addr = shadow_skb_addr; ++ } + - struct cred; - struct inode; - -@@ -153,6 +158,22 @@ struct cred { - KABI_RESERVE(4) - } __randomize_layout; - -+#ifdef CONFIG_CREDP -+extern unsigned long long iee_rw_gate(int flag, ...); -+static void iee_set_cred_non_rcu(struct cred *cred, int non_rcu) ++ /* alloc shadow stack value area */ ++ if (stack_page_cnt) { ++ shadow_stack_addr = vmalloc(stack_page_cnt * PAGE_SIZE); ++ if (IS_ERR(shadow_stack_addr)) { ++ pr_err("alloc stack area failed\n"); ++ err = PTR_ERR(shadow_stack_addr); ++ goto ret; ++ } ++ env->prog->shadow_stack_addr = shadow_stack_addr; ++ } else { ++ pr_err("no bpf stack is alloced!\n"); ++ err = -ENOMEM; ++ goto ret; ++ } ++ ++ /* alloc guard region */ ++ // if (guard_page_cnt) { ++ // void *guard_region_addr = vmalloc(guard_page_cnt * PAGE_SIZE); ++ // if (IS_ERR(guard_region_addr)) { ++ // pr_err("alloc guard region failed\n"); ++ // err = PTR_ERR(guard_region_addr); ++ // goto ret; ++ // } ++ // env->prog->low_guard_region_addr = guard_region_addr; ++ // env->prog->high_guard_region_addr = guard_region_addr + guard_page_cnt / 2 * PAGE_SIZE; ++ // } ++ ++ /* fill the array pages */ ++ err = count_all_pages(env, pages, &page_index); ++ if (err) ++ goto ret; ++ ++ /* check every page is counted */ ++ fbpf_log("page index=%d, page cnt=%d (should equal)\n", page_index, total_page_cnt); ++ if(unlikely(page_index != total_page_cnt)) { ++ pr_err("ERROR: page_index != page_cnt\n"); ++ err = -EFAULT; ++ goto ret; ++ } ++ ++ /* remap memory area to virtually contiguous space */ ++ // shadow_base_addr = vmap(pages, total_page_cnt, VM_MAP, PAGE_KERNEL); ++ shadow_base_addr = alloc_aligned_memory(total_page_cnt * PAGE_SIZE); ++ if (IS_ERR(shadow_base_addr)) { ++ pr_err("unable to vmap map's value area and stack area\n"); ++ err = PTR_ERR(shadow_base_addr); ++ goto ret; ++ } ++ shadow_high_addr = shadow_base_addr + total_page_cnt * PAGE_SIZE; ++ env->prog->shadow_region_addr = shadow_base_addr; ++ env->prog->shadow_top_addr = shadow_high_addr; ++ ++ fbpf_log("shadow_base = 0x%llx, shadow_stack = 0x%llx\n", shadow_base_addr, shadow_high_addr); ++ ++ err = map_physic_pages(pages, shadow_base_addr, total_page_cnt); ++ if (err < 0) { ++ pr_err("remap failed, %d\n", err); ++ goto ret; ++ } ++ ++ /* substitute with SFI address space addrs */ ++ start_addr = (u64)shadow_base_addr; ++ ++ /* low guard region */ ++ // env->prog->low_guard_region_addr = (void *)start_addr; ++ // start_addr += guard_page_cnt / 2 * PAGE_SIZE; ++ ++ /* IMPORTANT: update shadow addr for maps */ ++ env->prog->map_data_addr = (void *)start_addr; ++ for (i = 0; i < env->used_map_cnt; i++) { ++ map = env->used_maps[i]; ++ ++ if (!map->is_aggregated) ++ continue; ++ ++ /* record addr mapping info */ ++ map->shadow_data = (void *)start_addr; ++ ++ if (map->map_type == BPF_MAP_TYPE_HASH || ++ map->map_type == BPF_MAP_TYPE_LRU_HASH) { ++ substitute_hash_value_ptr(map); ++ } else if (map->map_type == BPF_MAP_TYPE_ARRAY || ++ map->map_type == BPF_MAP_TYPE_CGROUP_ARRAY) { ++ ; // only need to record map->shadow_data ++ } else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY || ++ map->map_type == BPF_MAP_TYPE_PERCPU_HASH || ++ map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) { ++ err = record_percpu_map_shadow_page(map); ++ if (err) ++ goto ret; ++ } else { ++ ; // no need to record or substitute ++ } ++ ++ start_addr += map->used_page_cnt * PAGE_SIZE; ++ } ++ ++ /* the space between map's data and stack is for skb_buff */ ++ env->prog->shadow_skb_addr = (void *)start_addr; ++ start_addr += skb_page_cnt * PAGE_SIZE; ++ ++ /* stack */ ++ /* NOTICE: stack's addr is high addr (sp), rather than low addr (fp) */ ++ start_addr += stack_page_cnt * PAGE_SIZE; ++ env->prog->shadow_stack_addr = (void *)start_addr; ++ ++ /* high guard region */ ++ // env->prog->high_guard_region_addr = (void *)start_addr; ++ // start_addr += guard_page_cnt / 2 * PAGE_SIZE; ++ ++ BUG_ON(unlikely(start_addr != (u64)(env->prog->shadow_top_addr))); ++ ++ // set guard region and skb region as guard page ++ // start_addr = (u64)env->prog->low_guard_region_addr; ++ // for (int i = 0; i < guard_page_cnt / 2; i++) { ++ // err = set_as_guard_page(start_addr); ++ // if (err < 0) { ++ // pr_err("set as guard page failed, %d\n", err); ++ // goto ret; ++ // } ++ // start_addr += PAGE_SIZE; ++ // } ++ // start_addr = (u64)env->prog->high_guard_region_addr; ++ // for (int i = 0; i < guard_page_cnt / 2; i++) { ++ // err = set_as_guard_page(start_addr); ++ // if (err < 0) { ++ // pr_err("set as guard page failed, %d\n", err); ++ // goto ret; ++ // } ++ // start_addr += PAGE_SIZE; ++ // } ++ // start_addr = (u64)env->prog->shadow_skb_addr; ++ // for (int i = 0; i < skb_page_cnt; i++) { ++ // err = set_as_guard_page(start_addr); ++ // if (err < 0) { ++ // pr_err("set as guard page failed, %d\n", err); ++ // goto ret; ++ // } ++ // start_addr += PAGE_SIZE; ++ // } ++ ++ // manually trigger page fault now ++ // pr_err("start probe now\n"); ++ // *(u64 *)(env->prog->low_guard_region_addr + 16) = 1; ++ // pr_err("oops, back from page fault!\n"); ++ ++ fbpf_log("sfi_bpf space:\n"); ++ // fbpf_log("low guard region\t0x%016llx - 0x%016llx\n", ++ // env->prog->low_guard_region_addr, env->prog->low_guard_region_addr + guard_page_cnt / 2 * PAGE_SIZE); ++ fbpf_log("map's data\t\t0x%016llx - 0x%016llx\n", ++ env->prog->map_data_addr, env->prog->map_data_addr + map_page_cnt * PAGE_SIZE); ++ fbpf_log("skb\t\t\t0x%016llx - 0x%016llx\n", ++ env->prog->shadow_skb_addr, env->prog->shadow_skb_addr + skb_page_cnt * PAGE_SIZE); ++ fbpf_log("stack\t\t\t0x%016llx - 0x%016llx\n", ++ env->prog->shadow_stack_addr - stack_page_cnt * PAGE_SIZE, env->prog->shadow_stack_addr); ++ // fbpf_log("high guard region\t0x%016llx - 0x%016llx\n", ++ // env->prog->high_guard_region_addr, env->prog->high_guard_region_addr + guard_page_cnt / 2 * PAGE_SIZE); ++ ++ fbpf_log("prog [%s] func_id = %d: 0x%016llx - 0x%016llx, size = 0x%llx\n", ++ env->prog->aux->name, env->prog->aux->func_idx, ++ (u64)env->prog->shadow_region_addr, ++ (u64)env->prog->shadow_stack_addr, ++ (u64)(total_page_cnt * PAGE_SIZE)); ++ ++ret: ++ if (pages) ++ kfree(pages); ++ return err; ++} ++ ++static inline bool is_LDST_insn(struct bpf_insn *insn) +{ -+ iee_rw_gate(IEE_OP_SET_CRED_NON_RCU,cred,non_rcu); -+ *(int *)(&(((struct rcu_head *)(cred->rcu.func))->next)) = non_rcu; ++ u8 class = BPF_CLASS(insn->code); ++ ++ if (class == BPF_LD || class == BPF_LDX || class == BPF_ST || class == BPF_STX) ++ return true; ++ else ++ return false; +} + -+static bool iee_set_cred_atomic_op_usage(struct cred *cred, int flag, int nr) ++static inline bool is_HELPER_insn(struct bpf_insn *insn) +{ -+ bool ret; -+ ret = iee_rw_gate(IEE_OP_SET_CRED_ATOP_USAGE,cred,flag,nr); -+ return ret; ++ u8 class = BPF_CLASS(insn->code); ++ u8 op = BPF_OP(insn->code); ++ ++ if ((class == BPF_JMP || class == BPF_JMP32) && ++ op == BPF_CALL && ++ insn->src_reg != BPF_PSEUDO_CALL) ++ return true; ++ else ++ return false; +} -+#endif + - extern void __put_cred(struct cred *); - extern void exit_creds(struct task_struct *); - extern int copy_creds(struct task_struct *, unsigned long); -@@ -189,7 +210,11 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred) - */ - static inline struct cred *get_new_cred_many(struct cred *cred, int nr) - { -+ #ifdef CONFIG_CREDP -+ iee_set_cred_atomic_op_usage(cred, AT_ADD, nr); -+ #else - atomic_long_add(nr, &cred->usage); -+ #endif - return cred; - } - -@@ -202,7 +227,7 @@ static inline struct cred *get_new_cred_many(struct cred *cred, int nr) - */ - static inline struct cred *get_new_cred(struct cred *cred) - { -- return get_new_cred_many(cred, 1); -+ return get_new_cred_many(cred, 1); // XXXzgc atomic_inc -> get_new_cred_many - } - - /** -@@ -224,7 +249,11 @@ static inline const struct cred *get_cred_many(const struct cred *cred, int nr) - struct cred *nonconst_cred = (struct cred *) cred; - if (!cred) - return cred; -+ #ifdef CONFIG_CREDP -+ iee_set_cred_non_rcu(nonconst_cred,0); -+ #else - nonconst_cred->non_rcu = 0; -+ #endif - return get_new_cred_many(nonconst_cred, nr); - } - -@@ -247,9 +276,19 @@ static inline const struct cred *get_cred_rcu(const struct cred *cred) - struct cred *nonconst_cred = (struct cred *) cred; - if (!cred) - return NULL; -+ #ifdef CONFIG_CREDP -+ if (!iee_set_cred_atomic_op_usage(nonconst_cred,AT_INC_NOT_ZERO,0)) -+ return NULL; -+ #else - if (!atomic_long_inc_not_zero(&nonconst_cred->usage)) - return NULL; -+ #endif ++__attribute__((unused)) static char *bpf_sfi_check_type_strs[] = { ++ [BPF_SFI_CHECK_HELPER_AS_UNSAFE_PTR] = "BPF_SFI_CHECK_HELPER_AS_UNSAFE_PTR", ++ [BPF_SFI_CHECK_HELPER_AS_SAFE_PTR] = "BPF_SFI_CHECK_HELPER_AS_SAFE_PTR", ++ [BPF_SFI_CHECK_HELPER_AS_OFFSET] = "BPF_SFI_CHECK_HELPER_AS_OFFSET", ++ [BPF_SFI_CHECK_LDST_AS_UNSAFE_PTR] = "BPF_SFI_CHECK_LDST_AS_UNSAFE_PTR", ++ [BPF_SFI_CHECK_LDST_AS_SAFE_PTR] = "BPF_SFI_CHECK_LDST_AS_SAFE_PTR", ++ [BPF_SFI_CHECK_LDST_AS_OFFSET] = "BPF_SFI_CHECK_LDST_AS_OFFSET", ++}; ++ ++/** ++ * return a link list, each element mark a check of a reg need to be done. ++ * Ex: ++ * - { reg_0, CHECK_LDST } -> NULL ++ * - { reg_3, CHEKC_HELPER } -> { reg_2, CHECK_MODIFIED } -> { reg_1, CHECK_NONE } ++ * ++ */ ++struct bpf_sfi_check_unit *bpf_sfi_get_check_list(struct bpf_verifier_env *env, struct bpf_insn *insn, struct bpf_reg_state *regs) ++{ ++ if (is_LDST_insn(insn)) { ++ enum bpf_reg_type ptr_type; ++ int reg_no; ++ struct bpf_sfi_check_unit *check_list, *new_unit; ++ bool reg_as_offset; ++ u8 mode; ++ ++ if (BPF_CLASS(insn->code) == BPF_LD || ++ BPF_CLASS(insn->code) == BPF_LDX) ++ reg_no = insn->src_reg; ++ else ++ reg_no = insn->dst_reg; ++ ++ if (reg_no == BPF_REG_FP) ++ return NULL; ++ ++ ptr_type = base_type(regs[reg_no].type); ++ if (ptr_type != PTR_TO_STACK && ++ ptr_type != PTR_TO_MAP_VALUE && ++ ptr_type != PTR_TO_PACKET) { ++ // fbpf_log("%d: ignore ptr=%d, r%d", i, ptr_type, reg); ++ return NULL; ++ } ++ ++ mode = BPF_MODE(insn->code); ++ switch (mode) { ++ case BPF_MEM: ++ reg_as_offset = true; ++ break; ++ case BPF_ATOMIC: ++ case BPF_IMM: ++ reg_as_offset = false; ++ break; ++ default: ++ pr_err("unprocessed mode %d\n", mode); ++ return ERR_PTR(ENOTSUPP); ++ } ++ ++ reg_as_offset = false; ++ ++ check_list = (struct bpf_sfi_check_unit *)kzalloc(sizeof(struct bpf_sfi_check_unit), GFP_KERNEL); ++ INIT_LIST_HEAD(&check_list->list_head); ++ ++ new_unit = (struct bpf_sfi_check_unit *)kzalloc(sizeof(struct bpf_sfi_check_unit), GFP_KERNEL); ++ INIT_LIST_HEAD(&new_unit->list_head); ++ new_unit->reg_no = reg_no; ++ new_unit->reg_as_offset = reg_as_offset; ++ ++ if (regs[reg_no].sfi_check_state == BPF_SFI_UNSAFE_PTR) { ++ new_unit->check_type = BPF_SFI_CHECK_LDST_AS_UNSAFE_PTR; ++ } ++ else if (regs[reg_no].sfi_check_state == BPF_SFI_SAFE_PTR) { ++ new_unit->check_type = BPF_SFI_CHECK_LDST_AS_SAFE_PTR; ++ } ++ else { ++ new_unit->check_type = BPF_SFI_CHECK_LDST_AS_OFFSET; ++ } ++ ++ if (insn->off == 0) { ++ if (new_unit->check_type == BPF_SFI_CHECK_LDST_AS_UNSAFE_PTR || ++ new_unit->check_type == BPF_SFI_CHECK_LDST_AS_OFFSET) { ++ if (reg_as_offset) ++ new_unit->proposed_state = BPF_SFI_OFFSET; ++ else ++ new_unit->proposed_state = BPF_SFI_SAFE_PTR; ++ } ++ else ++ new_unit->proposed_state = BPF_SFI_SAFE_PTR; ++ } else { ++ new_unit->proposed_state = BPF_SFI_SAFE_PTR; ++ } ++ ++ list_add(&new_unit->list_head, &check_list->list_head); ++ // fbpf_log("%d: add %s check point\n", insn - env->prog->insnsi, ++ // bpf_sfi_check_type_strs[new_unit->check_type]); ++ ++ return check_list; ++ } ++ else if (is_HELPER_insn(insn)) { ++ const struct bpf_func_proto *fn; ++ int arg, reg_no; ++ enum bpf_reg_type arg_reg_type; ++ struct bpf_sfi_check_unit *bpf_sfi_check_list; ++ ++ if (unlikely(!env->ops->get_func_proto)) { ++ pr_err("ERROR: unsupport helper\n"); ++ return ERR_PTR(ENOENT); ++ } ++ fn = env->ops->get_func_proto(insn->imm, env->prog); ++ if (!fn) { ++ pr_err("ERROR: unknown helper type\n"); ++ return ERR_PTR(ENOENT); ++ } ++ ++ bpf_sfi_check_list = (struct bpf_sfi_check_unit *)kzalloc(sizeof(struct bpf_sfi_check_unit), GFP_KERNEL); ++ INIT_LIST_HEAD(&bpf_sfi_check_list->list_head); ++ ++ for (arg = 0; arg < 5; arg++) { ++ reg_no = arg + 1; ++ /* here use mapped actual reg type, not formal arg type */ ++ arg_reg_type = base_type(regs[reg_no].type); ++ ++ // fbpf_log("%d: arg%d_type = %d\n", insn - env->prog->insnsi, reg_no, arg_reg_type); ++ ++ if (arg_reg_type == PTR_TO_STACK || ++ arg_reg_type == PTR_TO_MAP_VALUE || ++ arg_reg_type == PTR_TO_PACKET) { ++ struct bpf_sfi_check_unit *check_unit = (struct bpf_sfi_check_unit *)kzalloc(sizeof(struct bpf_sfi_check_unit), GFP_KERNEL); ++ INIT_LIST_HEAD(&check_unit->list_head); ++ check_unit->reg_no = reg_no; ++ ++ if (regs[reg_no].sfi_check_state == BPF_SFI_UNSAFE_PTR) { ++ check_unit->check_type = BPF_SFI_CHECK_HELPER_AS_UNSAFE_PTR; ++ } ++ else if (regs[reg_no].sfi_check_state == BPF_SFI_SAFE_PTR) { ++ check_unit->check_type = BPF_SFI_CHECK_HELPER_AS_SAFE_PTR; ++ } ++ else { ++ check_unit->check_type = BPF_SFI_CHECK_HELPER_AS_OFFSET; ++ } ++ ++ check_unit->proposed_state = BPF_SFI_SAFE_PTR; ++ ++ list_add(&check_unit->list_head, &bpf_sfi_check_list->list_head); ++ // fbpf_log("%d: add %s check point\n", insn - env->prog->insnsi, ++ // bpf_sfi_check_type_strs[check_unit->check_type]); ++ } ++ } ++ ++ return bpf_sfi_check_list; ++ } ++ else { ++ return NULL; ++ } ++} + -+ #ifdef CONFIG_CREDP -+ iee_set_cred_non_rcu(nonconst_cred,0); -+ #else - nonconst_cred->non_rcu = 0; ++__printf(2, 3) static void fake_verbose(void *private_data, const char *fmt, ...) ++{ ++ va_list args; ++ ++ va_start(args, fmt); ++ vprintk(fmt, args); ++ va_end(args); ++} ++ ++void dump_insns(struct bpf_prog *prog, int start, int len, const char *prompt) ++{ ++ #ifdef FBPF_LOG_ENABLE ++ int insn_cnt; ++ struct bpf_insn *insn; ++ int i; ++ struct bpf_insn_cbs cbs = { ++ .cb_print = fake_verbose, ++ .private_data = NULL, ++ }; ++ ++ if (unlikely(!prog)) { ++ fbpf_log("ERROR: prog is NULL\n"); ++ return; ++ } ++ ++ if (start + len > prog->len) { ++ fbpf_log("ERROR: print insn from %d to %d is out of bound\n", start, start + len - 1); ++ return; ++ } ++ insn_cnt = len; ++ insn = prog->insnsi + start; ++ ++ if (prompt) ++ printk("[dump insns] --- %s\n", prompt); ++ for (i = 0; i < insn_cnt; i++) { ++ print_bpf_insn(&cbs, insn, false); ++ insn++; ++ } + #endif - return cred; - } - -@@ -270,8 +309,13 @@ static inline void put_cred_many(const struct cred *_cred, int nr) - struct cred *cred = (struct cred *) _cred; - - if (cred) { -+ #ifdef CONFIG_CREDP -+ if (iee_set_cred_atomic_op_usage(cred,AT_SUB_AND_TEST,nr)) -+ __put_cred(cred); -+ #else - if (atomic_long_sub_and_test(nr, &cred->usage)) - __put_cred(cred); -+ #endif - } - } - -diff --git a/include/linux/efi.h b/include/linux/efi.h -index 9ed79128458c..970cc4f7068b 100644 ---- a/include/linux/efi.h -+++ b/include/linux/efi.h -@@ -740,6 +740,15 @@ extern int __init __efi_memmap_init(struct efi_memory_map_data *data); - extern int __init efi_memmap_init_early(struct efi_memory_map_data *data); - extern int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size); - extern void __init efi_memmap_unmap(void); -+#ifdef CONFIG_PTP -+extern void __init efi_memmap_unmap_after_init(void); -+#endif -+extern int __init efi_memmap_install(struct efi_memory_map_data *data); -+extern int __init efi_memmap_split_count(efi_memory_desc_t *md, -+ struct range *range); -+extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap, -+ void *buf, struct efi_mem_range *mem); -+extern void __init efi_print_memmap(void); - - #ifdef CONFIG_EFI_ESRT - extern void __init efi_esrt_init(void); -diff --git a/include/linux/iee-flag.h b/include/linux/iee-flag.h -new file mode 100644 -index 000000000000..a6d70ef1d446 ---- /dev/null -+++ b/include/linux/iee-flag.h -@@ -0,0 +1,116 @@ -+#ifndef _LINUX_IEE_FLAG_H -+#define _LINUX_IEE_FLAG_H ++} + -+// Function Identifiers with Parameters Description -+enum { -+ IEE_WRITE_IN_BYTE=0, // Parameters: void *ptr, __u64 data, int length -+ IEE_OP_SET_PTE, // Parameters: pte_t *ptep, pte_t pte -+ IEE_OP_SET_PMD, // Parameters: pmd_t *pmdp, pmd_t pmd -+ IEE_OP_SET_PUD, // Parameters: pud_t *pudp, pud_t pud -+ IEE_OP_SET_P4D, // Parameters: p4d_t *p4dp, p4d_t p4d -+ IEE_OP_SET_BM_PTE, // Parameters: pte_t *ptep, pte_t pte -+ IEE_OP_SET_SWAPPER_PGD, // Parameters: pgd_t *pgdp, pgd_t pgd -+ IEE_OP_SET_TRAMP_PGD, // Parameters: pgd_t *pgdp, pgd_t pgd -+ IEE_MEMSET, // Parameters: void *ptr, int data, size_t n -+ IEE_OP_SET_TRACK, // Parameters: struct track *ptr, struct track *data -+ IEE_OP_SET_FREEPTR, // Parameters: void **pptr, void *ptr -+ IEE_OP_SET_PTE_U, // Parameters: pte_t *ptep -+ IEE_OP_SET_PTE_P, // Parameters: pte_t *ptep -+ IEE_SET_TOKEN_PGD, // Parameters: struct task_token *token, pgd_t *pgd -+ IEE_INIT_TOKEN, // Parameters: struct task_struct *tsk, void *kernel_stack, void *iee_stack -+ IEE_INVALIDATE_TOKEN, // Parameters: struct task_struct *tsk -+ IEE_SET_SENSITIVE_PTE, // Parameters: pte_t *lm_ptep, pte_t *iee_ptep -+ IEE_UNSET_SENSITIVE_PTE, // Parameters: pte_t *lm_ptep, pte_t *iee_ptep -+ IEE_SET_TOKEN, // Parameters: pte_t *ptep, void *new, unsigned long order -+ IEE_UNSET_TOKEN, // Parameters: pte_t *ptep, void *token_addr, void *token_page, unsigned long order -+ IEE_COPY_PTE_RANGE, // Parameters: pte_t *new_dst, pte_t *old_dst, pte_t *src_pte, struct vm_area_struct *src_vma, -+ // unsigned long dst_vm_flags, pte_t *end_pte -+ IEE_SPLIT_HUGE_PMD, -+ IEE_VALIDATE_TOKEN, -+ IEE_MEMCPY, -+#ifdef CONFIG_KOI -+ _IEE_READ_KOI_STACK, // Parameters: struct task_struct *tsk -+ _IEE_WRITE_KOI_STACK, // Parameters: struct task_struct *tsk, unsigned long koi_stack -+ _IEE_READ_TOKEN_TTBR1, // Parameters: struct task_struct *tsk -+ _IEE_WRITE_TOKEN_TTBR1, // Parameters: struct task_struct *tsk, unsigned long current_ttbr1 -+ _IEE_READ_KOI_KERNEL_STACK, // Parameters: struct task_struct *tsk -+ _IEE_WRITE_KOI_KERNEL_STACK, // Parameters: struct task_struct *tsk, unsigned long kernel_stack -+ _IEE_READ_KOI_STACK_BASE, // Parameters: struct task_struct *tsk -+ _IEE_WRITE_KOI_STACK_BASE, // Parameters: struct task_struct *tsk, unsigned long koi_stack_base -+ _IEE_SET_KOI_PGD, // Parameters: unsigned long koi_pgd_addr -+#endif -+#ifdef CONFIG_CREDP -+ IEE_OP_COPY_CRED, // Parameters: struct cred *old, struct cred *new -+ IEE_OP_SET_CRED_UID, // Parameters: struct cred *cred, kuid_t uid -+ IEE_OP_SET_CRED_GID, // Parameters: struct cred *cred, kgid_t gid -+ IEE_OP_SET_CRED_SUID, // Parameters: struct cred *cred, kuid_t suid -+ IEE_OP_SET_CRED_SGID, // Parameters: struct cred *cred, kgid_t sgid -+ IEE_OP_SET_CRED_EUID, // Parameters: struct cred *cred, kuid_t euid -+ IEE_OP_SET_CRED_EGID, // Parameters: struct cred *cred, kgid_t egid -+ IEE_OP_SET_CRED_FSUID, // Parameters: struct cred *cred, kuid_t fsuid -+ IEE_OP_SET_CRED_FSGID, // Parameters: struct cred *cred, kgid_t fsgid -+ IEE_OP_SET_CRED_USER, // Parameters: struct cred *cred, struct user_struct *user -+ IEE_OP_SET_CRED_USER_NS, // Parameters: struct cred *cred, struct user_namespace *user_ns -+ IEE_OP_SET_CRED_GROUP_INFO, // Parameters: struct cred *cred, struct group_info *group_info -+ IEE_OP_SET_CRED_SECUREBITS, // Parameters: struct cred *cred, unsigned securebits -+ IEE_OP_SET_CRED_CAP_INHER, // Parameters: struct cred *cred, kernel_cap_t cap_inheritable -+ IEE_OP_SET_CRED_CAP_PERM, // Parameters: struct cred *cred, kernel_cap_t cap_permitted -+ IEE_OP_SET_CRED_CAP_EFFECT, // Parameters: struct cred *cred, kernel_cap_t cap_effective -+ IEE_OP_SET_CRED_CAP_BSET, // Parameters: struct cred *cred, kernel_cap_t cap_bset -+ IEE_OP_SET_CRED_CAP_AMBIENT, // Parameters: struct cred *cred, kernel_cap_t cap_ambient -+ IEE_OP_SET_CRED_JIT_KEYRING, // Parameters: struct cred *cred, unsigned char jit_keyring -+ IEE_OP_SET_CRED_SESS_KEYRING, // Parameters: struct cred *cred, struct key *session_keyring -+ IEE_OP_SET_CRED_PROC_KEYRING, // Parameters: struct cred *cred, struct key *process_keyring -+ IEE_OP_SET_CRED_THREAD_KEYRING, // Parameters: struct cred *cred, struct key *thread_keyring -+ IEE_OP_SET_CRED_REQ_KEYRING, // Parameters: struct cred *cred, struct key *request_key_auth -+ IEE_OP_SET_CRED_NON_RCU, // Parameters: struct cred *cred, int non_rcu -+ IEE_OP_SET_CRED_ATSET_USAGE, // Parameters: struct cred *cred, int i -+ IEE_OP_SET_CRED_ATOP_USAGE, // Parameters: struct cred *cred, int flag -+ IEE_OP_SET_CRED_SECURITY, // Parameters: struct cred *cred, void *security -+ IEE_OP_SET_CRED_RCU, // Parameters: struct cred *cred, struct rcu_head *rcu -+ IEE_OP_SET_CRED_UCOUNTS, // Parameters: struct cred *cred, struct ucounts *ucounts -+// IEE_OP_COMMIT_CRED, // Parameters: struct cred *cred -+// IEE_OP_COPY_CRED_KERNEL, // Parameters: struct cred *old, struct cred *new -+#endif -+#ifdef CONFIG_KEYP -+ IEE_OP_SET_KEY_UNION, -+ IEE_OP_SET_KEY_STRUCT, -+ IEE_OP_SET_KEY_PAYLOAD, -+ IEE_OP_WRITE_KEY_PAYLOAD, -+ IEE_OP_WRITE_KEY_PAYLOAD_RCU_DATA0, -+ IEE_OP_SET_KEY_USAGE, -+ IEE_OP_SET_KEY_SERIAL, -+ IEE_OP_SET_KEY_WATCHERS, -+ IEE_OP_SET_KEY_USERS, -+ IEE_OP_SET_KEY_SECURITY, -+ IEE_OP_SET_KEY_EXPIRY, -+ IEE_OP_SET_KEY_REVOKED_AT, -+ IEE_OP_SET_KEY_LAST_USED_AT, -+ IEE_OP_SET_KEY_UID, -+ IEE_OP_SET_KEY_GID, -+ IEE_OP_SET_KEY_PERM, -+ IEE_OP_SET_KEY_QUOTALEN, -+ IEE_OP_SET_KEY_DATALEN, -+ IEE_OP_SET_KEY_STATE, -+ IEE_OP_SET_KEY_MAGIC, -+ IEE_OP_SET_KEY_FLAGS, -+ IEE_OP_SET_KEY_INDEX_KEY, -+ IEE_OP_SET_KEY_HASH, -+ IEE_OP_SET_KEY_LEN_DESC, -+ IEE_OP_SET_KEY_TYPE, -+ IEE_OP_SET_KEY_TAG, -+ IEE_OP_SET_KEY_DESCRIPTION, -+ IEE_OP_SET_KEY_RESTRICT_LINK, -+ IEE_OP_SET_KEY_FLAG_BIT, -+#endif -+#ifdef CONFIG_IEE_SELINUX_P -+ IEE_SEL_SET_STATUS_PG, // Parameters: struct page* new_page -+ IEE_SEL_SET_ENFORCING, // Parameters: bool value -+ IEE_SEL_SET_INITIALIZED, -+ IEE_SEL_SET_POLICY_CAP, // Parameters: unsigned int idx, int cap -+ IEE_SEL_RCU_ASSIGN_POLICY, // Parameters: struct selinux_policy* new_policy, struct selinux_policy* iee_new_policy -+#endif -+ IEE_FLAG_END -+}; ++int bpf_sfi_tmp_check(struct bpf_verifier_env *env) ++{ ++ struct bpf_prog *prog; ++ struct bpf_insn *insn; ++ int insn_cnt; ++ struct bpf_insn_aux_data *aux; ++ int i; ++ struct bpf_sfi_check_unit *check_list; + -+#endif -\ No newline at end of file -diff --git a/include/linux/iee-func.h b/include/linux/iee-func.h -new file mode 100644 -index 000000000000..a3e4909a650f ---- /dev/null -+++ b/include/linux/iee-func.h -@@ -0,0 +1,35 @@ -+#ifndef _LINUX_IEE_FUNC_H -+#define _LINUX_IEE_FUNC_H ++ if (!env) { ++ fbpf_log("env is NULL\n"); ++ return -EFAULT; ++ } ++ prog = env->prog; ++ aux = env->insn_aux_data; + -+#ifdef CONFIG_IEE -+#define HUGE_PMD_ORDER 9 -+#define TASK_ORDER 4 -+extern unsigned long init_iee_stack_begin[]; -+extern unsigned long init_iee_stack_end[]; -+extern void *init_token_page_vaddr; ++ if (!prog) { ++ fbpf_log("prog is NULL\n"); ++ return -EFAULT; ++ } ++ insn_cnt = prog->len; + -+extern unsigned long long iee_rw_gate(int flag, ...); -+extern u32 get_cpu_asid_bits(void); -+extern unsigned long arm64_mm_context_get(struct mm_struct *mm); -+extern void set_iee_page(unsigned long addr, int order); -+extern void unset_iee_page(unsigned long addr, int order); -+extern void set_iee_page_valid(unsigned long addr); -+extern void iee_set_logical_mem_ro(unsigned long addr); -+extern void __init iee_mark_all_lm_pgtable_ro(void); -+extern void iee_set_token_pgd(struct task_struct *tsk, pgd_t *pgd); -+extern void iee_init_token(struct task_struct *tsk, void *iee_stack, void *tmp_page); -+extern void iee_invalidate_token(struct task_struct *tsk); -+extern void iee_validate_token(struct task_struct *tsk); -+extern unsigned long iee_read_token_stack(struct task_struct *tsk); -+extern void iee_set_token_page_valid(void *token, void *new, unsigned int order); -+extern void iee_set_token_page_invalid(void *token_addr, void *token_page, unsigned long order); -+extern void unset_iee_stack_page(unsigned long addr, int order); -+extern void set_iee_stack_page(unsigned long addr, int order); -+extern void iee_write_in_byte(void *ptr, u64 data, int length); -+extern void *iee_read_tmp_page(struct task_struct *tsk); -+extern void *iee_read_freeptr(void *ptr); -+extern void iee_set_stack_freeptr(unsigned long addr, void *free_ptr); -+extern void iee_memset(void *ptr, int data, size_t n); -+#endif ++ insn = prog->insnsi; ++ if (!insn) ++ return 0; ++ ++ for (i = 0; i < insn_cnt; i++) { ++ insn = &prog->insnsi[i]; ++ aux = &env->insn_aux_data[i]; ++ check_list = env->insn_check_lists[i]; ++ ++ if (!aux) { ++ dump_insns(prog, i, 1, "empty aux"); ++ fbpf_log("aux is empty for insn %d", i); ++ return -EFAULT; ++ } ++ ++ /* check optimization */ ++ if (check_list) { ++ struct bpf_sfi_check_unit *p; ++ char check_type[128]; ++ ++ mutex_lock(&env->insn_check_list_mutex); ++ list_for_each_entry(p, &check_list->list_head, list_head) { ++ switch (p->check_type) { ++ case BPF_SFI_CHECK_LDST_AS_UNSAFE_PTR: ++ if (insn->off == 0) ++ strcpy(check_type, "BPF_SFI_CHECK_LDST_AS_UNSAFE_PTR"); ++ else ++ strcpy(check_type, "BPF_SFI_CHECK_LDST_OFFSET_AS_UNSAFE_PTR");; ++ break; ++ case BPF_SFI_CHECK_LDST_AS_SAFE_PTR: ++ if (insn->off == 0) ++ strcpy(check_type, "BPF_SFI_CHECK_LDST_AS_SAFE_PTR"); ++ else ++ strcpy(check_type, "BPF_SFI_CHECK_LDST_OFFSET_AS_SAFE_PTR");; ++ break; ++ case BPF_SFI_CHECK_LDST_AS_OFFSET: ++ if (insn->off == 0) ++ strcpy(check_type, "BPF_SFI_CHECK_LDST_AS_OFFSET"); ++ else ++ strcpy(check_type, "BPF_SFI_CHECK_LDST_OFFSET_AS_OFFSET");; ++ break; ++ case BPF_SFI_CHECK_HELPER_AS_UNSAFE_PTR: ++ strcpy(check_type, "BPF_SFI_CHECK_HELPER_AS_UNSAFE_PTR"); ++ break; ++ case BPF_SFI_CHECK_HELPER_AS_SAFE_PTR: ++ strcpy(check_type, "BPF_SFI_CHECK_HELPER_AS_SAFE_PTR"); ++ break; ++ case BPF_SFI_CHECK_HELPER_AS_OFFSET: ++ strcpy(check_type, "BPF_SFI_CHECK_HELPER_AS_OFFSET"); ++ break; ++ } ++ fbpf_log("%d: reg %d, check type %s\n", i, p->reg_no, check_type); ++ } ++ mutex_unlock(&env->insn_check_list_mutex); ++ } ++ } ++ ++ return 0; ++} ++ ++/** ++ * return: ++ * > 0: patch cnt ++ * = 0: no need to patch ++ * < 0: errno ++ */ ++static inline int form_check_ldst_as_unsafe_ptr(struct bpf_insn *origin_insn, struct bpf_insn *patch, bool reg_as_offset, ++ u64 sfi_region_size, int reg, int *origin_insn_no) ++{ ++ int patch_len; ++ struct bpf_insn modified_origin_insn = *origin_insn; ++ u8 size = BPF_SIZE(origin_insn->code); ++ u8 class = BPF_CLASS(origin_insn->code); ++ ++ pr_info("reg_as_offset %d\n", reg_as_offset); ++ ++ /* lock *(u64 *)(r0 + 0) += 1 */ ++ /* lock *(u64 *)(r0 + 8) += 1 */ ++ if (!reg_as_offset) { ++ patch[0] = BPF_ALU64_IMM(BPF_AND, reg, sfi_region_size - 1); ++ patch[1] = BPF_ALU64_REG(BPF_OR, reg, BPF_REG_BASE); ++ patch[2] = *origin_insn; ++ ++ *origin_insn_no = 2; ++ patch_len = 3; ++ } else { ++ /* *(u64 *)(r0 + 0) = 0 */ ++ if (origin_insn->off == 0) { ++ patch[0] = BPF_ALU64_IMM(BPF_AND, reg, sfi_region_size - 1); ++ modified_origin_insn.code = class | BPF_REG | size; ++ if (class == BPF_LD || class == BPF_LDX) ++ modified_origin_insn.src_reg = BPF_REG_BASE; ++ if (class == BPF_ST || class == BPF_STX) ++ modified_origin_insn.dst_reg = BPF_REG_BASE; ++ modified_origin_insn.off = reg; ++ patch[1] = modified_origin_insn; ++ ++ *origin_insn_no = 1; ++ patch_len = 2; ++ } ++ /* *(u64 *)(r0 + 8) = 0 */ ++ else { ++ patch[0] = BPF_ALU64_IMM(BPF_AND, reg, sfi_region_size - 1); ++ patch[1] = BPF_ALU64_REG(BPF_OR, reg, BPF_REG_BASE); ++ patch[2] = *origin_insn; ++ ++ *origin_insn_no = 2; ++ patch_len = 3; ++ } ++ } ++ ++ return patch_len; ++} ++ ++/** ++ * return: ++ * > 0: patch cnt ++ * = 0: no need to patch ++ * < 0: errno ++ */ ++static inline int form_check_ldst_as_offset(struct bpf_insn *origin_insn, struct bpf_insn *patch, bool reg_as_offset, ++ u64 sfi_region_size, int reg, int *origin_insn_no) ++{ ++ int patch_len; ++ struct bpf_insn modified_origin_insn = *origin_insn; ++ u8 size = BPF_SIZE(origin_insn->code); ++ u8 class = BPF_CLASS(origin_insn->code); ++ ++ if (!reg_as_offset) { ++ /* lock *(u64 *)(r0 + 0) += 1 */ ++ /* lock *(u64 *)(r0 + 8) += 1 */ ++ patch[0] = BPF_ALU64_REG(BPF_OR, reg, BPF_REG_BASE); ++ patch[1] = *origin_insn; ++ ++ *origin_insn_no = 1; ++ patch_len = 2; ++ ++ } else { ++ /* *(u64 *)(r0 + 0) = 0 */ ++ if (origin_insn->off == 0) { ++ modified_origin_insn.code = class | BPF_REG | size; ++ if (class == BPF_LD || class == BPF_LDX) ++ modified_origin_insn.src_reg = BPF_REG_BASE; ++ if (class == BPF_ST || class == BPF_STX) ++ modified_origin_insn.dst_reg = BPF_REG_BASE; ++ modified_origin_insn.off = reg; ++ patch[0] = modified_origin_insn; ++ ++ *origin_insn_no = 0; ++ patch_len = 1; ++ } ++ /* *(u64 *)(r0 + 8) = 0 */ ++ else { ++ patch[0] = BPF_ALU64_REG(BPF_OR, reg, BPF_REG_BASE); ++ patch[1] = *origin_insn; ++ ++ *origin_insn_no = 1; ++ patch_len = 2; ++ } ++ } ++ ++ return patch_len; ++} ++ ++/** ++ * form a patch according to the insn ++ * v3 means this is optimized twice ++ * @origin_insn: where the instrument point locates at ++ * @check_unit: the sfi check unit ++ * @patch_array: patch will be stored in this array if return code is 0 ++ * @origin_insn_no: the index of origin insn ++ * @sfi_region_size: the size of sfi region ++ * return: ++ * < 0: errno ++ * >= 0: patch_cnt ++ */ ++int form_sfi_check_patch_v3(struct bpf_insn *origin_insn, struct bpf_sfi_check_unit *check_unit, ++ struct bpf_insn *patch_array, int* origin_insn_no, u64 sfi_region_size) ++{ ++ struct bpf_insn patch[16]; ++ int patch_len = 0; ++ enum bpf_sfi_check_type type = check_unit->check_type; ++ int reg = check_unit->reg_no; ++ ++ /** normal case, ++ * 1. and with SFI_REGION_SIZE ++ * 2. if not reg_as_offset ++ * 2.1 or with SFI_REGION_BASE ++ * 2.2 if has off, add off ++ * 2.3 origin insn ++ * 2.4 if has off, sub off ++ * 3. if reg_as_offset ++ * 3.1 if has off, add off ++ * 3.2 replace BPF_LD/BPF_ST to BPF_LDR/BPF_STR ++ * 3.3 if has off, sub off ++ */ ++ if (type == BPF_SFI_CHECK_LDST_AS_UNSAFE_PTR) { ++ bool reg_as_offset = check_unit->reg_as_offset; ++ patch_len = form_check_ldst_as_unsafe_ptr(origin_insn, patch, ++ reg_as_offset, sfi_region_size, reg, origin_insn_no); ++ } ++ /** second case ++ * 1. no need to and again ++ * 2. but need to process off ++ * 3. and replace insn to BPF_LDR/BPF_STR ++ */ ++ else if (type == BPF_SFI_CHECK_LDST_AS_OFFSET) { ++ bool reg_as_offset = check_unit->reg_as_offset; ++ patch_len = form_check_ldst_as_offset(origin_insn, patch, ++ reg_as_offset, sfi_region_size, reg, origin_insn_no); ++ } ++ /** after check helper, ptr is still ptr, but safe ++ * 1. and with SFI_REGION_SIZE ++ * 2. or with SFI_REGION_BASE ++ */ ++ else if (type == BPF_SFI_CHECK_HELPER_AS_UNSAFE_PTR) { ++ patch[0] = BPF_ALU64_IMM(BPF_AND, reg, sfi_region_size - 1); ++ patch[1] = BPF_ALU64_REG(BPF_OR, reg, BPF_REG_BASE); ++ patch[2] = *origin_insn; ++ ++ *origin_insn_no = 2; ++ patch_len = 3; ++ } ++ /** second case ++ * 1. no need to and ++ * 2. just or ++ */ ++ else if (type == BPF_SFI_CHECK_HELPER_AS_OFFSET) { ++ patch[0] = BPF_ALU64_REG(BPF_OR, reg, BPF_REG_BASE); ++ patch[1] = *origin_insn; ++ ++ *origin_insn_no = 1; ++ patch_len = 2; ++ } ++ /* no need to check again */ ++ else if (type == BPF_SFI_CHECK_HELPER_AS_SAFE_PTR || ++ type == BPF_SFI_CHECK_LDST_AS_SAFE_PTR) { ++ *origin_insn_no = 0; ++ patch_len = 0; ++ } ++ else { ++ pr_err("unresolved case\n"); ++ BUG_ON(1); ++ } + -+#endif -\ No newline at end of file -diff --git a/include/linux/key.h b/include/linux/key.h -index 938d7ecfb495..7cde506953cd 100644 ---- a/include/linux/key.h -+++ b/include/linux/key.h -@@ -280,6 +280,39 @@ struct key { - struct key_restriction *restrict_link; - }; - -+#ifdef CONFIG_IEE -+struct key_union { -+ union { -+ struct list_head graveyard_link; -+ struct rb_node serial_node; -+ }; -+ struct rw_semaphore sem; -+ struct key *key; -+}; ++ if (patch_len > sizeof(patch_array)) ++ return -ENOMEM; + -+struct key_struct { -+ struct { -+ /* Keyring bits */ -+ struct list_head name_link; -+ struct assoc_array keys; -+ }; -+ struct key *key; -+}; -+#endif ++ for (int i = 0; i < patch_len; i++) ++ patch_array[i] = patch[i]; ++ ++ return patch_len; ++} + -+#ifdef CONFIG_KEYP -+#define KEY_SEM(KEY) (((struct key_union *)(KEY->graveyard_link.next))->sem) -+#include -+#include -+extern unsigned long long iee_rw_gate(int flag, ...); -+static bool iee_set_key_usage(struct key *key, int n, int flag) ++int bpf_sfi_check_ldst(struct bpf_verifier_env *env) +{ -+ bool ret; -+ ret = iee_rw_gate(IEE_OP_SET_KEY_USAGE, key, n, flag); -+ return ret; -+} -+#endif ++ struct bpf_prog *prog; ++ struct bpf_insn *insn; ++ int insn_cnt; ++ struct bpf_insn_aux_data *aux; ++ struct bpf_prog *new_prog; ++ int i, cnt, delta = 0; ++ u8 reg; ++ int origin_insn_no; ++ enum bpf_reg_type ptr_type; ++ struct bpf_sfi_check_unit *check_list, *origin_check_list; + - extern struct key *key_alloc(struct key_type *type, - const char *desc, - kuid_t uid, kgid_t gid, -@@ -305,7 +338,11 @@ extern void key_remove_domain(struct key_tag *domain_tag); - - static inline struct key *__key_get(struct key *key) - { -+ #ifdef CONFIG_KEYP -+ iee_set_key_usage(key, 0, REFCOUNT_INC); -+ #else - refcount_inc(&key->usage); -+ #endif - return key; - } - -@@ -478,17 +515,63 @@ static inline bool key_is_negative(const struct key *key) - return key_read_state(key) < 0; - } - -+#ifdef CONFIG_KEYP -+extern void iee_write_key_payload_rcu_data0(struct key *key, void *rcu_data0); ++ if (!env) { ++ fbpf_log("env is NULL\n"); ++ return -EFAULT; ++ } ++ prog = env->prog; ++ aux = env->insn_aux_data; + -+#define dereference_key_rcu(KEY) \ -+ (rcu_dereference(((union key_payload *)(KEY->name_link.next))->rcu_data0)) ++ if (!prog) { ++ fbpf_log("prog is NULL\n"); ++ return -EFAULT; ++ } ++ insn_cnt = prog->len; + -+#ifdef CONFIG_KEYP -+#define dereference_key_locked(KEY) \ -+ (rcu_dereference_protected(((union key_payload *)(KEY->name_link.next))->rcu_data0, \ -+ rwsem_is_locked(&KEY_SEM(((struct key *)(KEY)))))) -+#else -+#define dereference_key_locked(KEY) \ -+ (rcu_dereference_protected(((union key_payload *)(KEY->name_link.next))->rcu_data0, \ -+ rwsem_is_locked(&((struct key *)(KEY))->sem))) -+#endif ++ insn = prog->insnsi; ++ if (!insn) ++ return 0; + -+#define iee_smp_store_release(p, v, KEY) \ -+do { \ -+ compiletime_assert_atomic_type(*p); \ -+ barrier(); \ -+ iee_write_key_payload_rcu_data0(KEY, v); \ -+} while (0) ++ /* use i + delta to traverse: insn, aux. */ ++ for (i = 0; i < insn_cnt; i++) { ++ struct bpf_insn_aux_data origin_insn_aux; + -+#define iee_rcu_assign_pointer(p, v, KEY) \ -+do { \ -+ uintptr_t _r_a_p__v = (uintptr_t)(v); \ -+ rcu_check_sparse(p, __rcu); \ -+ \ -+ if (__builtin_constant_p(v) && (_r_a_p__v) == (uintptr_t)NULL) \ -+ iee_write_key_payload_rcu_data0(KEY, (typeof(p))(_r_a_p__v)); \ -+ else \ -+ iee_smp_store_release(&p, RCU_INITIALIZER((typeof(p))_r_a_p__v), KEY); \ -+} while (0) ++ insn = &prog->insnsi[i + delta]; ++ aux = &env->insn_aux_data[i + delta]; ++ check_list = env->insn_check_lists[i + delta]; + -+#define rcu_assign_keypointer(KEY, PAYLOAD) \ -+do { \ -+ iee_rcu_assign_pointer(((union key_payload *)(KEY->name_link.next))->rcu_data0, (PAYLOAD), KEY); \ -+} while (0) -+#else - #define dereference_key_rcu(KEY) \ - (rcu_dereference((KEY)->payload.rcu_data0)) - -+#ifdef CONFIG_KEYP -+#define dereference_key_locked(KEY) \ -+ (rcu_dereference_protected((KEY)->payload.rcu_data0, \ -+ rwsem_is_locked(&KEY_SEM(((struct key *)(KEY)))))) -+#else - #define dereference_key_locked(KEY) \ - (rcu_dereference_protected((KEY)->payload.rcu_data0, \ - rwsem_is_locked(&((struct key *)(KEY))->sem))) -+#endif - - #define rcu_assign_keypointer(KEY, PAYLOAD) \ - do { \ - rcu_assign_pointer((KEY)->payload.rcu_data0, (PAYLOAD)); \ - } while (0) -+#endif - - /* - * the userspace interface -diff --git a/include/linux/mm.h b/include/linux/mm.h -index ffdd46c1108a..e938f50f2d7f 100644 ---- a/include/linux/mm.h -+++ b/include/linux/mm.h -@@ -32,6 +32,77 @@ - #include - #include - -+#ifdef CONFIG_PTP -+#include -+struct slab_t { -+ unsigned long __page_flags; ++ if (!aux) { ++ dump_insns(prog, i, 1, "empty aux"); ++ fbpf_log("aux is empty for insn %d", i); ++ return -EFAULT; ++ } ++ origin_insn_aux = *aux; ++ origin_check_list = env->insn_check_lists[i + delta]; ++ ++ /* check optimization */ ++ if (check_list) { ++ struct bpf_sfi_check_unit *p; ++ // u64 offset_bound_mask = (roundup_pow_of_two( ++ // env->prog->total_page_cnt) << PAGE_SHIFT) - 1; ++ u64 sfi_region_size = env->prog->total_page_cnt << PAGE_SHIFT; ++ ++ list_for_each_entry(p, &check_list->list_head, list_head) { ++ if (p->check_type != BPF_SFI_CHECK_LDST_AS_UNSAFE_PTR && ++ p->check_type != BPF_SFI_CHECK_LDST_AS_SAFE_PTR && ++ p->check_type != BPF_SFI_CHECK_LDST_AS_OFFSET) ++ continue; ++ ++ reg = p->reg_no; ++ ptr_type = base_type(aux->ptr_type); ++ ++ fbpf_log("%d: check ptr=%d, r%d", i, ptr_type, reg); ++ dump_insns(prog, i + delta, 1, "Ld/st insn to rewrite"); ++ ++ struct bpf_insn patch[16]; ++ cnt = form_sfi_check_patch_v3(insn, p, patch, &origin_insn_no, ++ sfi_region_size); ++ ++ /* NOTICE: use cnt to decide whether to patch */ ++ if (cnt == 0) ++ continue; ++ ++ new_prog = _bpf_patch_insn_data(env, i + delta, patch, cnt); ++ if (!new_prog) { ++ fbpf_log("patch failed\n"); ++ return -ENOMEM; ++ } + -+#if defined(CONFIG_SLAB) ++ dump_insns(new_prog, i + delta, cnt, "restore ldst"); + -+ void *slab_cache; -+ union { -+ struct { -+ struct list_head slab_list; -+ void *freelist; /* array of free object indexes */ -+ void *s_mem; /* first object */ -+ }; -+ struct rcu_head rcu_head; -+ }; -+ unsigned int active; ++ env->insn_aux_data[i + delta + origin_insn_no] = origin_insn_aux; ++ env->insn_check_lists[i + delta + origin_insn_no] = origin_check_list; ++ env->prog = prog = new_prog; ++ delta += cnt - 1; ++ } + -+#elif defined(CONFIG_SLUB) ++ // if (!old_off) { ++ // struct bpf_insn zero_off_patch[] = { ++ // BPF_ALU64_IMM(BPF_AND, reg, offset_bound_mask), ++ // BPF_ALU64_REG(BPF_OR, reg, BPF_REG_BASE), ++ // *insn, ++ // }; ++ ++ // cnt = ARRAY_SIZE(zero_off_patch); ++ // origin_insn_no = find_origin_insn(zero_off_patch, cnt, insn); ++ ++ // new_prog = bpf_patch_insn_data(env, i + delta, zero_off_patch, cnt); ++ // if (!new_prog) { ++ // fbpf_log("patch failed\n"); ++ // return -ENOMEM; ++ // } ++ ++ // // dump_insns(new_prog, i + delta, cnt, "restore ldst"); ++ ++ // env->insn_aux_data[i + delta + origin_insn_no] = ++ // origin_insn_aux; ++ // env->prog = prog = new_prog; ++ // delta += cnt - 1; ++ // continue; ++ // } else { ++ // struct bpf_insn non_zero_off_patch[] = { ++ // BPF_ALU64_IMM(BPF_ADD, reg, old_off), ++ // BPF_ALU64_IMM(BPF_AND, reg, offset_bound_mask), ++ // BPF_ALU64_REG(BPF_OR, reg, BPF_REG_BASE), ++ // *insn, ++ // BPF_ALU64_IMM(BPF_SUB, reg, old_off), ++ // }; ++ ++ // cnt = ARRAY_SIZE(non_zero_off_patch); ++ // origin_insn_no = find_origin_insn(non_zero_off_patch, cnt, insn); ++ ++ // new_prog = bpf_patch_insn_data(env, i + delta, non_zero_off_patch, cnt); ++ // if (!new_prog) { ++ // fbpf_log("patch failed\n"); ++ // return -ENOMEM; ++ // } ++ ++ // // dump_insns(new_prog, i + delta, cnt, "restore ldst"); ++ ++ // env->insn_aux_data[i + delta + origin_insn_no] = ++ // origin_insn_aux; ++ // env->prog = prog = new_prog; ++ // delta += cnt - 1; ++ // continue; ++ // } ++ } ++ } + -+ void *slab_cache; -+ union { -+ struct { -+ union { -+ struct list_head slab_list; -+#ifdef CONFIG_SLUB_CPU_PARTIAL -+ struct { -+ struct slab_t *next; -+ int slabs; /* Nr of slabs left */ -+ }; -+#endif -+ }; -+ /* Double-word boundary */ -+ union { -+ struct { -+ void *freelist; /* first free object */ -+ union { -+ unsigned long counters; -+ struct { -+ unsigned inuse:16; -+ unsigned objects:15; -+ unsigned frozen:1; -+ }; -+ }; -+ }; -+#ifdef system_has_freelist_aba -+ union { -+ struct { -+ void *freelist; -+ unsigned long counter; -+ }; -+ u64 full; -+ }; -+#endif -+ }; -+ }; -+ struct rcu_head rcu_head; -+ }; -+ unsigned int __unused; ++ // dump_insns(env->prog, 0, env->prog->len, "all after restore ldst"); + -+#else -+#error "Unexpected slab allocator configured" -+#endif ++ return 0; ++} + -+ atomic_t __page_refcount; -+#ifdef CONFIG_MEMCG -+ unsigned long memcg_data; -+#endif -+}; -+#endif ++int bpf_sfi_check_helper_args(struct bpf_verifier_env *env) ++{ ++ struct bpf_prog *prog; ++ int insn_cnt; ++ struct bpf_prog *new_prog; ++ int i, cnt, delta = 0; ++ struct bpf_sfi_check_unit *check_list, *origin_check_list; + - struct mempolicy; - struct anon_vma; - struct anon_vma_chain; -@@ -2938,7 +3009,11 @@ static inline bool pagetable_is_reserved(struct ptdesc *pt) - */ - static inline struct ptdesc *pagetable_alloc(gfp_t gfp, unsigned int order) - { -+ #ifdef CONFIG_PTP -+ struct page *page = virt_to_page(get_iee_pgtable_page(gfp | __GFP_COMP)); -+ #else - struct page *page = alloc_pages(gfp | __GFP_COMP, order); -+ #endif - - return page_ptdesc(page); - } -@@ -2954,7 +3029,11 @@ static inline void pagetable_free(struct ptdesc *pt) - { - struct page *page = ptdesc_page(pt); - -+ #ifdef CONFIG_PTP -+ free_iee_pgtable_page((void *)page_address(page)); -+ #else - __free_pages(page, compound_order(page)); -+ #endif - } - - #if USE_SPLIT_PTE_PTLOCKS -@@ -2965,7 +3044,11 @@ void ptlock_free(struct ptdesc *ptdesc); - - static inline spinlock_t *ptlock_ptr(struct ptdesc *ptdesc) - { -+ #ifdef CONFIG_PTP -+ return ((struct ptdesc_t *)(((struct slab_t *)ptdesc)->slab_cache))->ptl; -+ #else - return ptdesc->ptl; -+ #endif - } - #else /* ALLOC_SPLIT_PTLOCKS */ - static inline void ptlock_cache_init(void) -@@ -2983,7 +3066,11 @@ static inline void ptlock_free(struct ptdesc *ptdesc) - - static inline spinlock_t *ptlock_ptr(struct ptdesc *ptdesc) - { -+ #ifdef CONFIG_PTP -+ return &(((struct ptdesc_t *)(((struct slab_t *)ptdesc)->slab_cache))->ptl); -+ #else - return &ptdesc->ptl; -+ #endif - } - #endif /* ALLOC_SPLIT_PTLOCKS */ - -@@ -3001,7 +3088,11 @@ static inline bool ptlock_init(struct ptdesc *ptdesc) - * It can happen if arch try to use slab for page table allocation: - * slab code uses page->slab_cache, which share storage with page->ptl. - */ -+ #ifdef CONFIG_PTP -+ VM_BUG_ON_PAGE(*(unsigned long *)&(((struct ptdesc_t *)(((struct slab_t *)ptdesc)->slab_cache))->ptl), ptdesc_page(ptdesc)); -+ #else - VM_BUG_ON_PAGE(*(unsigned long *)&ptdesc->ptl, ptdesc_page(ptdesc)); -+ #endif - if (!ptlock_alloc(ptdesc)) - return false; - spin_lock_init(ptlock_ptr(ptdesc)); -@@ -3100,7 +3191,11 @@ static inline spinlock_t *pmd_lockptr(struct mm_struct *mm, pmd_t *pmd) - static inline bool pmd_ptlock_init(struct ptdesc *ptdesc) - { - #ifdef CONFIG_TRANSPARENT_HUGEPAGE -+ #ifdef CONFIG_PTP -+ (((struct ptdesc_t *)(((struct slab_t *)ptdesc)->slab_cache))->pmd_huge_pte) = NULL; -+ #else - ptdesc->pmd_huge_pte = NULL; -+ #endif - #endif - return ptlock_init(ptdesc); - } -@@ -3108,12 +3203,20 @@ static inline bool pmd_ptlock_init(struct ptdesc *ptdesc) - static inline void pmd_ptlock_free(struct ptdesc *ptdesc) - { - #ifdef CONFIG_TRANSPARENT_HUGEPAGE -+ #ifdef CONFIG_PTP -+ VM_BUG_ON_PAGE((((struct ptdesc_t *)(((struct slab_t *)ptdesc)->slab_cache))->pmd_huge_pte), ptdesc_page(ptdesc)); -+ #else - VM_BUG_ON_PAGE(ptdesc->pmd_huge_pte, ptdesc_page(ptdesc)); -+ #endif - #endif - ptlock_free(ptdesc); - } - -+#ifdef CONFIG_PTP -+#define pmd_huge_pte(mm, pmd) (((struct ptdesc_t *)(((struct slab_t *)pmd_ptdesc(pmd))->slab_cache))->pmd_huge_pte) -+#else - #define pmd_huge_pte(mm, pmd) (pmd_ptdesc(pmd)->pmd_huge_pte) -+#endif - - #else - -diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h -index fdc047bdbc49..df8d03ea6955 100644 ---- a/include/linux/mm_types.h -+++ b/include/linux/mm_types.h -@@ -483,6 +483,42 @@ struct ptdesc { - #endif - }; - -+#ifdef CONFIG_IEE -+struct ptdesc_t { -+ unsigned long __page_flags; ++ if (!env) { ++ fbpf_log("ERROR: env is NULL\n"); ++ return -EFAULT; ++ } ++ prog = env->prog; + -+ union { -+ struct rcu_head pt_rcu_head; -+ struct list_head pt_list; -+ struct { -+ unsigned long _pt_pad_1; -+ pgtable_t pmd_huge_pte; -+ }; -+ }; -+ unsigned long __page_mapping; ++ if (!prog) { ++ fbpf_log("ERROR: prog is NULL\n"); ++ return -EFAULT; ++ } ++ insn_cnt = prog->len; ++ ++ // dump_insns(prog, 0, prog->len, "before restore_helper_args"); ++ ++ /** ++ * use i + delta to traverse: insn, aux. ++ * in inner loop, do not update the insn and aux. ++ */ ++ for (i = 0; i < insn_cnt; i++) { ++ struct bpf_insn_aux_data origin_insn_aux; ++ int sub_delta = 0; ++ int alpha = 0; ++ struct bpf_insn_aux_data *aux; ++ struct bpf_insn *insn; ++ ++ insn = &prog->insnsi[i + delta + alpha]; ++ aux = &env->insn_aux_data[i + delta + alpha]; ++ check_list = env->insn_check_lists[i + delta + alpha]; ++ if (!aux) { ++ dump_insns(prog, i, 1, "empty aux"); ++ fbpf_log("ERROR: aux is empty for insn %d\n", i); ++ return -EFAULT; ++ } ++ origin_insn_aux = *aux; ++ origin_check_list = env->insn_check_lists[i + delta + alpha]; ++ ++ /* check optimization */ ++ if (check_list) { ++ int func_id = insn->imm; ++ struct bpf_sfi_check_unit *p; ++ // u64 offset_bound_mask = (roundup_pow_of_two( ++ // env->prog->total_page_cnt) << PAGE_SHIFT) - 1; ++ u64 sfi_region_size = env->prog->total_page_cnt << PAGE_SHIFT; ++ ++ list_for_each_entry(p, &check_list->list_head, list_head) { ++ int origin_insn_no; ++ int reg_no = p->reg_no; ++ enum bpf_reg_type arg_type = aux->arg_reg_type[reg_no - 1]; ++ insn = &prog->insnsi[i + delta + alpha]; ++ aux = &env->insn_aux_data[i + delta + alpha]; ++ struct bpf_insn patch[16]; ++ ++ // struct bpf_insn patch[] = { ++ // BPF_ALU64_IMM(BPF_AND, reg_no, offset_bound_mask), ++ // BPF_ALU64_REG(BPF_OR, reg_no, BPF_REG_BASE), ++ // *insn, ++ // }; ++ ++ if (p->check_type != BPF_SFI_CHECK_HELPER_AS_UNSAFE_PTR && ++ p->check_type != BPF_SFI_CHECK_HELPER_AS_SAFE_PTR && ++ p->check_type != BPF_SFI_CHECK_HELPER_AS_OFFSET) ++ break; ++ ++ cnt = form_sfi_check_patch_v3(insn, p, patch, &origin_insn_no, ++ sfi_region_size); ++ ++ /* NOTICE: use cnt to decide whether to patch */ ++ if (cnt == 0) ++ continue; ++ ++ // cnt = ARRAY_SIZE(patch); ++ // origin_insn_no = find_origin_insn(patch, cnt, insn); ++ ++ fbpf_log("patch %d(%d): helper func=%d, \ ++restore arg r%d, type=%d, cnt=%d, alpha=%d\n", ++ i + delta + alpha, i, func_id, reg_no, ++ arg_type, cnt, alpha); ++ ++ new_prog = _bpf_patch_insn_data(env, i + delta + alpha, ++ patch, cnt); ++ if (!new_prog) { ++ fbpf_log("ERROR: patch failed\n"); ++ return -ENOMEM; ++ } ++ ++ dump_insns(new_prog, i + delta + alpha, ++ cnt, "restore stack ptr arg"); ++ ++ env->insn_aux_data[i + delta + alpha + origin_insn_no] = origin_insn_aux; ++ env->insn_check_lists[i + delta + alpha + origin_insn_no] = origin_check_list; ++ env->prog = prog = new_prog; ++ ++ sub_delta += cnt - 1; ++ alpha += origin_insn_no; ++ } ++ ++ delta += sub_delta; ++ } ++ } + -+ union { -+ struct mm_struct *pt_mm; -+ atomic_t pt_frag_refcount; -+ }; ++ return 0; ++} + -+ union { -+ unsigned long _pt_pad_2; -+#if ALLOC_SPLIT_PTLOCKS -+ spinlock_t *ptl; -+#else -+ spinlock_t ptl; -+#endif -+ }; -+ unsigned int __page_type; -+ atomic_t _refcount; -+#ifdef CONFIG_MEMCG -+ unsigned long pt_memcg_data; -+#endif -+ struct slab_t *slab; -+}; ++bool bpf_sfi_can_instrument(struct bpf_verifier_env *env) ++{ ++ for (int i = 0; i < env->used_map_cnt; i++) { ++ struct bpf_map *map = env->used_maps[i]; ++ if (map_can_lookup(map) && !map->is_aggregated) { ++ return false; ++ } ++ } ++ ++ return true; ++} +\ No newline at end of file +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 8fa7b37152c0..f305e2fdce82 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -32,6 +32,10 @@ + #include + #endif + ++#ifdef CONFIG_HIVE ++#include +#endif + - #define TABLE_MATCH(pg, pt) \ - static_assert(offsetof(struct page, pg) == offsetof(struct ptdesc, pt)) - TABLE_MATCH(flags, __page_flags); -@@ -1182,6 +1218,9 @@ struct mmu_gather; - extern void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm); - extern void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm); - extern void tlb_finish_mmu(struct mmu_gather *tlb); -+#ifdef CONFIG_PTP -+extern void iee_tlb_finish_mmu(struct mmu_gather *tlb); + #include "disasm.h" + + static const struct bpf_verifier_ops * const bpf_verifier_ops[] = { +@@ -10032,6 +10036,9 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn + int insn_idx = *insn_idx_p; + bool changes_data; + int i, err, func_id; ++#ifdef CONFIG_HIVE ++ struct bpf_insn_aux_data *aux = &env->insn_aux_data[insn_idx]; +#endif - struct vm_fault; + /* find function prototype */ + func_id = insn->imm; +@@ -10122,6 +10129,13 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn -diff --git a/include/linux/module.h b/include/linux/module.h -index 990f9d66d2f1..169021fc8501 100644 ---- a/include/linux/module.h -+++ b/include/linux/module.h -@@ -609,6 +609,7 @@ struct module { - KABI_RESERVE(2) - KABI_RESERVE(3) - KABI_RESERVE(4) -+ - } ____cacheline_aligned __randomize_layout; - #ifndef MODULE_ARCH_INIT - #define MODULE_ARCH_INIT {} -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 7b1c53f71ee4..3b42a96a4ae0 100644 ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -773,6 +773,24 @@ struct task_struct_resvd { - struct task_struct *task; - }; + regs = cur_regs(env); -+#if defined(CONFIG_IEE) || defined(CONFIG_KOI) -+struct task_token { -+#ifdef CONFIG_IEE -+ pgd_t *pgd; /* Logical VA */ -+ void *iee_stack; /* VA */ -+ void *tmp_page; -+ bool valid; -+ void *kernel_stack; /* VA */ ++#ifdef CONFIG_HIVE ++ /* fbpf record real arg type of helper call */ ++ for (i = 0; i < 5; i++) { ++ aux->arg_reg_type[i] = regs[i + 1].type; ++ } +#endif -+#ifdef CONFIG_KOI -+ void *koi_kernel_stack; /* VA */ -+ void *koi_stack; /* VA */ -+ void *koi_stack_base; /* VA */ -+ unsigned long current_ttbr1; ++ + if (meta.release_regno) { + err = -EINVAL; + /* This can only be set for PTR_TO_STACK, as CONST_PTR_TO_DYNPTR cannot +@@ -16468,7 +16482,7 @@ static int propagate_liveness(struct bpf_verifier_env *env, + return -EFAULT; + } + /* Propagate read liveness of registers... */ +- BUILD_BUG_ON(BPF_REG_FP + 1 != MAX_BPF_REG); ++ BUILD_BUG_ON(BPF_REG_FP + 2 != MAX_BPF_REG); + for (frame = 0; frame <= vstate->curframe; frame++) { + parent = vparent->frame[frame]; + state = vstate->frame[frame]; +@@ -17076,15 +17090,30 @@ static int do_check(struct bpf_verifier_env *env) + bool pop_log = !(env->log.level & BPF_LOG_LEVEL2); + struct bpf_verifier_state *state = env->cur_state; + struct bpf_insn *insns = env->prog->insnsi; ++#ifdef CONFIG_HIVE ++ struct bpf_reg_state *regs = NULL, *regs_before = NULL; ++ struct bpf_sfi_check_unit *check_list; ++ int i; ++#else + struct bpf_reg_state *regs; +#endif -+}; + int insn_cnt = env->prog->len; + bool do_print_state = false; + int prev_insn_idx = -1; + ++#ifdef CONFIG_HIVE ++ regs_before = vmalloc(sizeof(struct bpf_reg_state) * MAX_BPF_REG); ++ if (IS_ERR(regs_before)) ++ return PTR_ERR(regs_before); +#endif + - struct task_struct { - #ifdef CONFIG_THREAD_INFO_IN_TASK - /* -@@ -795,6 +813,7 @@ struct task_struct { - randomized_struct_fields_start + for (;;) { + struct bpf_insn *insn; + u8 class; + int err; ++ #ifdef CONFIG_HIVE ++ bool updated[MAX_BPF_REG] = {false}; ++ #endif + + /* reset current history entry on each new instruction */ + env->cur_hist_ent = NULL; +@@ -17177,6 +17206,16 @@ static int do_check(struct bpf_verifier_env *env) + sanitize_mark_insn_seen(env); + prev_insn_idx = env->insn_idx; + ++ #ifdef CONFIG_HIVE ++ /* fbpf: compare regs_before and regs to get which regs are changed */ ++ memcpy(regs_before, regs, sizeof(struct bpf_reg_state) * MAX_BPF_REG); ++ ++ /* fbpf: used to form check list of vulnerable insns */ ++ check_list = bpf_sfi_get_check_list(env, insn, regs); ++ if (IS_ERR(check_list)) ++ return PTR_ERR(check_list); ++ #endif ++ + if (class == BPF_ALU || class == BPF_ALU64) { + err = check_alu_op(env, insn); + if (err) +@@ -17218,8 +17257,17 @@ static int do_check(struct bpf_verifier_env *env) + err = check_atomic(env, env->insn_idx, insn); + if (err) + return err; ++ #ifdef CONFIG_HIVE ++ err = save_aux_ptr_type(env, regs[insn->dst_reg].type, true); ++ if (err) ++ return err; ++ #endif + env->insn_idx++; ++ #ifdef CONFIG_HIVE ++ goto next_insn; ++ #else + continue; ++ #endif + } - void *stack; + if (BPF_MODE(insn->code) != BPF_MEM || insn->imm != 0) { +@@ -17323,7 +17371,12 @@ static int do_check(struct bpf_verifier_env *env) + env->insn_idx += insn->off + 1; + else + env->insn_idx += insn->imm + 1; ++ ++ #ifdef CONFIG_HIVE ++ goto next_insn; ++ #else + continue; ++ #endif + + } else if (opcode == BPF_EXIT) { + if (BPF_SRC(insn->code) != BPF_K || +@@ -17363,7 +17416,11 @@ static int do_check(struct bpf_verifier_env *env) + if (err) + return err; + do_print_state = true; ++ #ifdef CONFIG_HIVE ++ goto next_insn; ++ #else + continue; ++ #endif + } + + err = check_return_code(env); +@@ -17380,7 +17437,11 @@ static int do_check(struct bpf_verifier_env *env) + break; + } else { + do_print_state = true; ++ #ifdef CONFIG_HIVE ++ goto next_insn; ++ #else + continue; ++ #endif + } + } else { + err = check_cond_jmp_op(env, insn, &env->insn_idx); +@@ -17406,12 +17467,52 @@ static int do_check(struct bpf_verifier_env *env) + verbose(env, "invalid BPF_LD mode\n"); + return -EINVAL; + } ++ #ifdef CONFIG_HIVE ++ err = save_aux_ptr_type(env, regs[insn->src_reg].type, true); ++ if (err) ++ return err; ++ #endif + } else { + verbose(env, "unknown insn class %d\n", class); + return -EINVAL; + } + + env->insn_idx++; + - refcount_t usage; - /* Per task flags (PF_*), defined further below: */ - unsigned int flags; -diff --git a/init/main.c b/init/main.c -index 8fdfa69dba0f..9c6aeae0ea66 100644 ---- a/init/main.c -+++ b/init/main.c -@@ -102,6 +102,14 @@ - #include - #include ++#ifdef CONFIG_HIVE ++next_insn: ++ if (check_list) { ++ struct bpf_sfi_check_unit *p; ++ list_for_each_entry(p, &check_list->list_head, list_head) { ++ int reg_no = p->reg_no; ++ regs[reg_no].sfi_check_state = p->proposed_state; ++ updated[reg_no] = true; ++ } ++ ++ if (!env->insn_check_lists[prev_insn_idx]) { ++ // fbpf_log("update into %d\n", prev_insn_idx); ++ env->insn_check_lists[prev_insn_idx] = check_list; ++ } ++ } ++ ++ for (i = 0; i < MAX_BPF_REG; i++) { ++ // if (base_type(regs_before[i].type) == PTR_TO_STACK) ++ // continue; ++ /* reg move from src to dst, use src_reg's check_state */ ++ if (insn->code == (BPF_ALU64 | BPF_MOV | BPF_X)) ++ continue; ++ /* use check_list proposed state if have */ ++ if (updated[i]) ++ continue; ++ /* if reg changed, reset sfi_check state */ ++ if (memcmp(regs_before + i, regs + i, sizeof(struct bpf_reg_state))) { ++ regs[i].sfi_check_state = BPF_SFI_UNSAFE_PTR; ++ } ++ } ++ ++ // fbpf_log("debugging insn %d", prev_insn_idx); ++ // bpf_sfi_tmp_check(env); ++#endif + } -+#ifdef CONFIG_IEE -+#include -+#include -+#include -+#include -+#include + return 0; +@@ -17866,6 +17967,168 @@ static int resolve_pseudo_ldimm64(struct bpf_verifier_env *env) + return 0; + } + ++ ++ ++#ifdef CONFIG_HIVE ++static int resolve_pseudo_ldimm64_again(struct bpf_verifier_env *env) ++{ ++ struct bpf_insn *insn = env->prog->insnsi; ++ int insn_cnt = env->prog->len; ++ int i, j, err; ++ ++ err = bpf_prog_calc_tag(env->prog); ++ if (err) ++ return err; ++ ++ for (i = 0; i < insn_cnt; i++, insn++) { ++ if (insn[0].code == (BPF_LD | BPF_IMM | BPF_DW)) { ++ struct bpf_insn_aux_data *aux; ++ struct bpf_map *map; ++ struct fd f; ++ u64 addr; ++ u32 fd; ++ ++ if (insn[0].src_reg == 0) ++ /* valid generic load 64-bit imm */ ++ goto next_insn; ++ ++ if (insn[0].src_reg == BPF_PSEUDO_BTF_ID) { ++ aux = &env->insn_aux_data[i]; ++ err = check_pseudo_btf_id(env, insn, aux); ++ if (err) ++ return err; ++ goto next_insn; ++ } ++ ++ if (insn[0].src_reg == BPF_PSEUDO_FUNC) { ++ aux = &env->insn_aux_data[i]; ++ aux->ptr_type = PTR_TO_FUNC; ++ goto next_insn; ++ } ++ ++ /* In final convert_pseudo_ld_imm64() step, this is ++ * converted into regular 64-bit imm load insn. ++ */ ++ switch (insn[0].src_reg) { ++ case BPF_PSEUDO_MAP_VALUE: ++ break; ++ default: ++ goto next_insn; ++ } ++ ++ fd = insn[0].imm; ++ ++ f = fdget(fd); ++ map = __bpf_map_get(f); ++ if (IS_ERR(map)) { ++ verbose(env, "fd %d is not pointing to valid bpf_map\n", ++ insn[0].imm); ++ return PTR_ERR(map); ++ } ++ ++ err = check_map_prog_compatibility(env, map, env->prog); ++ if (err) { ++ fdput(f); ++ return err; ++ } ++ ++ aux = &env->insn_aux_data[i]; ++ if (insn[0].src_reg == BPF_PSEUDO_MAP_FD || ++ insn[0].src_reg == BPF_PSEUDO_MAP_IDX) { ++ addr = (unsigned long)map; ++ goto next_insn; ++ } else { ++ u32 off = insn[1].imm; ++ ++ /* do this after aggregation */ ++ if (!env->prog->shadow_region_addr) { ++ pr_err("bpf sfi aggregate memory failed\n"); ++ return -EINVAL; ++ } ++ ++ if (off >= BPF_MAX_VAR_OFF) { ++ verbose(env, "direct value offset of %u is not allowed\n", off); ++ fdput(f); ++ return -EINVAL; ++ } ++ ++ if (!map->ops->map_direct_value_addr) { ++ verbose(env, "no direct value access support for this map type\n"); ++ fdput(f); ++ return -EINVAL; ++ } ++ ++ err = map->ops->map_direct_value_addr(map, &addr, off); ++ if (err) { ++ verbose(env, "invalid access to map value pointer, value_size=%u off=%u\n", ++ map->value_size, off); ++ fdput(f); ++ return err; ++ } ++ ++ aux->map_off = off; ++ addr += off; ++ aux->extra_map_ptr = (u64)map; ++ } ++ ++ insn[0].imm = (u32)addr; ++ insn[1].imm = addr >> 32; ++ ++ /* check whether we recorded this map already */ ++ for (j = 0; j < env->used_map_cnt; j++) { ++ if (env->used_maps[j] == map) { ++ aux->map_index = j; ++ fdput(f); ++ goto next_insn; ++ } ++ } ++ ++ if (env->used_map_cnt >= MAX_USED_MAPS) { ++ fdput(f); ++ return -E2BIG; ++ } ++ ++ if (env->prog->aux->sleepable) ++ atomic64_inc(&map->sleepable_refcnt); ++ /* hold the map. If the program is rejected by verifier, ++ * the map will be released by release_maps() or it ++ * will be used by the valid program until it's unloaded ++ * and all maps are released in bpf_free_used_maps() ++ */ ++ bpf_map_inc(map); ++ ++ aux->map_index = env->used_map_cnt; ++ env->used_maps[env->used_map_cnt++] = map; ++ ++ if (bpf_map_is_cgroup_storage(map) && ++ bpf_cgroup_storage_assign(env->prog->aux, map)) { ++ verbose(env, "only one cgroup storage of each type is allowed\n"); ++ fdput(f); ++ return -EBUSY; ++ } ++ ++ fdput(f); ++next_insn: ++ insn++; ++ i++; ++ continue; ++ } ++ ++ /* Basic sanity check before we invest more work here. */ ++ if (!bpf_opcode_in_insntable(insn->code)) { ++ verbose(env, "unknown opcode %02x\n", insn->code); ++ return -EINVAL; ++ } ++ } ++ ++ /* now all pseudo BPF_LD_IMM64 instructions load valid ++ * 'struct bpf_map *' into a register instead of user map_fd. ++ * These pointers will be used later by verifier to validate map access. ++ */ ++ return 0; ++} +#endif + - #include - #include - #include -@@ -112,6 +120,10 @@ - - #include + /* drop refcnt of maps used by the rejected program */ + static void release_maps(struct bpf_verifier_env *env) + { +@@ -17932,6 +18195,26 @@ static void adjust_insn_aux_data(struct bpf_verifier_env *env, + vfree(old_data); + } -+#ifdef CONFIG_PTP -+extern void *bm_pte_addr; ++#ifdef CONFIG_HIVE ++static void adjust_insn_check_lists(struct bpf_verifier_env *env, ++ struct bpf_sfi_check_unit **new_check_lists, ++ struct bpf_prog *new_prog, u32 off, u32 cnt) ++{ ++ struct bpf_sfi_check_unit **old_check_lists = env->insn_check_lists; ++ u32 prog_len; ++ ++ if (cnt == 1) ++ return; ++ prog_len = new_prog->len; ++ ++ memcpy(new_check_lists, old_check_lists, sizeof(struct bpf_insn_check_unit *) * off); ++ memcpy(new_check_lists + off + cnt - 1, old_check_lists + off, ++ sizeof(struct bpf_insn_check_unit *) * (prog_len - off - cnt + 1)); ++ env->insn_check_lists = new_check_lists; ++ vfree(old_check_lists); ++} +#endif + - static int kernel_init(void *); + static void adjust_subprog_starts(struct bpf_verifier_env *env, u32 off, u32 len) + { + int i; +@@ -17965,12 +18248,21 @@ static struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 of + { + struct bpf_prog *new_prog; + struct bpf_insn_aux_data *new_data = NULL; ++#ifdef CONFIG_HIVE ++ struct bpf_sfi_check_unit **new_check_lists = NULL; ++#endif - /* -@@ -933,6 +945,10 @@ void start_kernel(void) - sort_main_extable(); - trap_init(); - mm_core_init(); -+ #ifdef CONFIG_IEE -+ iee_stack_init(); -+ iee_pgtable_init(); + if (len > 1) { + new_data = vzalloc(array_size(env->prog->len + len - 1, + sizeof(struct bpf_insn_aux_data))); + if (!new_data) + return NULL; ++ #ifdef CONFIG_HIVE ++ new_check_lists = vzalloc(array_size(env->prog->len + len - 1, ++ sizeof(struct bpf_sfi_check_unit *))); ++ if (!new_check_lists) ++ return NULL; + #endif - poking_init(); - ftrace_init(); + } -@@ -1073,6 +1089,16 @@ void start_kernel(void) - arch_post_acpi_subsys_init(); - kcsan_init(); + new_prog = bpf_patch_insn_single(env->prog, off, patch, len); +@@ -17983,11 +18275,22 @@ static struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 of + return NULL; + } + adjust_insn_aux_data(env, new_data, new_prog, off, len); ++#ifdef CONFIG_HIVE ++ adjust_insn_check_lists(env, new_check_lists, new_prog, off, len); ++#endif + adjust_subprog_starts(env, off, len); + adjust_poke_descs(new_prog, off, len); + return new_prog; + } -+ // Later IEE settings. -+ #ifdef CONFIG_IEE -+ set_iee_stack_page((unsigned long)__va(__pa_symbol(init_iee_stack_begin)), 2); -+ set_iee_page((unsigned long)init_token_page_vaddr, 0); -+ // Set the logical va of existing pgtable readonly. -+ #ifdef CONFIG_PTP -+ iee_mark_all_lm_pgtable_ro(); -+ #endif -+ #endif ++#ifdef CONFIG_HIVE ++struct bpf_prog *_bpf_patch_insn_data(struct bpf_verifier_env *env, u32 off, ++ const struct bpf_insn *patch, u32 len) ++{ ++ return bpf_patch_insn_data(env, off, patch, len); ++} ++#endif + - /* Do the rest non-__init'ed, we're now alive */ - arch_call_rest_init(); - -@@ -1444,6 +1470,9 @@ static int __ref kernel_init(void *unused) - wait_for_completion(&kthreadd_done); - - kernel_init_freeable(); -+ #ifdef CONFIG_PTP -+ iee_set_logical_mem_ro((unsigned long)bm_pte_addr); -+ #endif - /* need to finish all async __init code before freeing the memory */ - async_synchronize_full(); - -@@ -1460,7 +1489,7 @@ static int __ref kernel_init(void *unused) - * to finalize PTI. - */ - pti_finalize(); -- -+ - system_state = SYSTEM_RUNNING; - numa_default_policy(); + static int adjust_subprog_starts_after_remove(struct bpf_verifier_env *env, + u32 off, u32 cnt) + { +@@ -18643,6 +18946,10 @@ static int jit_subprogs(struct bpf_verifier_env *env) + func[i]->aux->name[0] = 'F'; + func[i]->aux->stack_depth = env->subprog_info[i].stack_depth; + func[i]->jit_requested = 1; ++ #ifdef CONFIG_HIVE ++ func[i]->shadow_stack_addr = env->prog->shadow_stack_addr; ++ func[i]->shadow_region_addr = env->prog->shadow_region_addr; ++ #endif + func[i]->blinding_requested = prog->blinding_requested; + func[i]->aux->kfunc_tab = prog->aux->kfunc_tab; + func[i]->aux->kfunc_btf_tab = prog->aux->kfunc_btf_tab; +@@ -20473,6 +20780,12 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3 + len = (*prog)->len; + env->insn_aux_data = + vzalloc(array_size(sizeof(struct bpf_insn_aux_data), len)); ++#ifdef CONFIG_HIVE ++ env->insn_check_lists = vzalloc(array_size(sizeof(struct bpf_sfi_check_unit *), len)); ++ for (i = 0; i < len; i++) ++ env->insn_check_lists[i] = NULL; ++ mutex_init(&env->insn_check_list_mutex); ++#endif + ret = -ENOMEM; + if (!env->insn_aux_data) + goto err_free_env; +@@ -20564,6 +20877,48 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3 + + if (ret == 0 && bpf_prog_is_offloaded(env->prog->aux)) + ret = bpf_prog_offload_finalize(env); ++ ++#ifdef CONFIG_HIVE ++ /* bpf_sfi aggregate and check is after bpf_check, if skip full_check, ++ bpf_sfi checks are skipped either */ ++ fbpf_log("bpf_check finished\n"); ++ // dump_insns(env->prog, 0, env->prog->len, "after do_check"); ++ ++ // if (ret == 0) ++ // ret = bpf_sfi_tmp_check(env); ++ ++ /* if not support map or mode, just return to normal bpf */ ++ if (!bpf_sfi_can_instrument(env)) { ++ struct bpf_map *map; ++ for (i = 0; i < env->used_map_cnt; i++) { ++ map = env->used_maps[i]; ++ map->is_aggregated = false; ++ } ++ fbpf_log("skip sfi instrument\n"); ++ goto skip_sfi_instrument; ++ } ++ ++ // TODO unmap shadow data ++ /* fbpf aggregate values and caculate shadow stack addr */ ++ if (ret == 0) ++ ret = bpf_sfi_aggregate_memory(env); ++ ++ if (ret == 0) ++ ret = resolve_pseudo_ldimm64_again(env); ++ ++ if (ret == 0) ++ ret = bpf_sfi_check_ldst(env); ++ ++ if (ret == 0) ++ ret = bpf_sfi_check_helper_args(env); ++ ++skip_sfi_instrument: ++ // dump_insns(env->prog, 0, env->prog->len, "after bpf_sfi_checks"); ++ ++ fbpf_log("bpf_sfi_check finished\n"); ++ ++ pr_info("[%s] bpf insn len = %d\n", env->prog->aux->name, env->prog->len); ++#endif + skip_full_check: + kvfree(env->explored_states); +@@ -20685,5 +21040,8 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3 + vfree(env->insn_aux_data); + err_free_env: + kvfree(env); ++#ifdef CONFIG_HIVE ++ pr_info("prog [%s] bpf_check's ret = %d\n", env->prog->aux->name, ret); ++#endif + return ret; + } diff --git a/kernel/cred.c b/kernel/cred.c -index c033a201c808..ba57e19a26b8 100644 +index c033a201c808..813db29f35df 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -20,6 +20,11 @@ @@ -14482,22 +27019,20 @@ index c033a201c808..ba57e19a26b8 100644 #if 0 #define kdebug(FMT, ...) \ printk("[%-5.5s%5u] " FMT "\n", \ -@@ -33,7 +38,14 @@ do { \ +@@ -33,7 +38,12 @@ do { \ } while (0) #endif -+#ifdef CONFIG_IEE -+struct kmem_cache *cred_jar; +#ifdef CONFIG_CREDP ++struct kmem_cache *cred_jar; +static struct kmem_cache *rcu_jar; -+#endif +#else static struct kmem_cache *cred_jar; +#endif /* init to 2 - one for init_task, one to ensure it is never freed */ static struct group_info init_groups = { .usage = REFCOUNT_INIT(2) }; -@@ -41,6 +53,32 @@ static struct group_info init_groups = { .usage = REFCOUNT_INIT(2) }; +@@ -41,6 +51,32 @@ static struct group_info init_groups = { .usage = REFCOUNT_INIT(2) }; /* * The initial credentials for the initial task */ @@ -14530,7 +27065,7 @@ index c033a201c808..ba57e19a26b8 100644 struct cred init_cred = { .usage = ATOMIC_INIT(4), .uid = GLOBAL_ROOT_UID, -@@ -61,13 +99,43 @@ struct cred init_cred = { +@@ -61,13 +97,43 @@ struct cred init_cred = { .group_info = &init_groups, .ucounts = &init_ucounts, }; @@ -14574,7 +27109,7 @@ index c033a201c808..ba57e19a26b8 100644 kdebug("put_cred_rcu(%p)", cred); -@@ -86,6 +154,9 @@ static void put_cred_rcu(struct rcu_head *rcu) +@@ -86,6 +152,9 @@ static void put_cred_rcu(struct rcu_head *rcu) if (cred->ucounts) put_ucounts(cred->ucounts); put_user_ns(cred->user_ns); @@ -14584,7 +27119,7 @@ index c033a201c808..ba57e19a26b8 100644 kmem_cache_free(cred_jar, cred); } -@@ -104,10 +175,22 @@ void __put_cred(struct cred *cred) +@@ -104,10 +173,22 @@ void __put_cred(struct cred *cred) BUG_ON(cred == current->cred); BUG_ON(cred == current->real_cred); @@ -14607,7 +27142,7 @@ index c033a201c808..ba57e19a26b8 100644 } EXPORT_SYMBOL(__put_cred); -@@ -178,7 +261,18 @@ struct cred *cred_alloc_blank(void) +@@ -178,7 +259,18 @@ struct cred *cred_alloc_blank(void) if (!new) return NULL; @@ -14626,7 +27161,7 @@ index c033a201c808..ba57e19a26b8 100644 if (security_cred_alloc_blank(new, GFP_KERNEL_ACCOUNT) < 0) goto error; -@@ -213,13 +307,25 @@ struct cred *prepare_creds(void) +@@ -213,13 +305,25 @@ struct cred *prepare_creds(void) if (!new) return NULL; @@ -14652,7 +27187,7 @@ index c033a201c808..ba57e19a26b8 100644 get_group_info(new->group_info); get_uid(new->user); get_user_ns(new->user_ns); -@@ -232,10 +338,18 @@ struct cred *prepare_creds(void) +@@ -232,10 +336,18 @@ struct cred *prepare_creds(void) #endif #ifdef CONFIG_SECURITY @@ -14671,7 +27206,7 @@ index c033a201c808..ba57e19a26b8 100644 if (!new->ucounts) goto error; -@@ -265,15 +379,30 @@ struct cred *prepare_exec_creds(void) +@@ -265,15 +377,30 @@ struct cred *prepare_exec_creds(void) #ifdef CONFIG_KEYS /* newly exec'd tasks don't get a thread keyring */ key_put(new->thread_keyring); @@ -14702,7 +27237,7 @@ index c033a201c808..ba57e19a26b8 100644 return new; } -@@ -327,7 +456,11 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) +@@ -327,7 +454,11 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) * had one */ if (new->thread_keyring) { key_put(new->thread_keyring); @@ -14714,7 +27249,7 @@ index c033a201c808..ba57e19a26b8 100644 if (clone_flags & CLONE_THREAD) install_thread_keyring_to_cred(new); } -@@ -337,7 +470,11 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) +@@ -337,7 +468,11 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) */ if (!(clone_flags & CLONE_THREAD)) { key_put(new->process_keyring); @@ -14726,7 +27261,7 @@ index c033a201c808..ba57e19a26b8 100644 } #endif -@@ -594,7 +731,11 @@ int set_cred_ucounts(struct cred *new) +@@ -594,7 +729,11 @@ int set_cred_ucounts(struct cred *new) if (!(new_ucounts = alloc_ucounts(new->user_ns, new->uid))) return -EAGAIN; @@ -14738,7 +27273,7 @@ index c033a201c808..ba57e19a26b8 100644 put_ucounts(old_ucounts); return 0; -@@ -606,8 +747,21 @@ int set_cred_ucounts(struct cred *new) +@@ -606,8 +745,21 @@ int set_cred_ucounts(struct cred *new) void __init cred_init(void) { /* allocate a slab in which we can store credentials */ @@ -14750,7 +27285,7 @@ index c033a201c808..ba57e19a26b8 100644 + // Map init_cred + *((struct rcu_head **)(&(init_cred.rcu.func))) = (struct rcu_head *)kmem_cache_zalloc(rcu_jar, GFP_KERNEL); + *(struct cred **)(((struct rcu_head *)(init_cred.rcu.func)) + 1) = &init_cred; -+ set_iee_page_valid(__phys_to_iee(__pa_symbol(&init_cred))); ++ set_iee_page_valid((unsigned long)__phys_to_iee(__pa_symbol(&init_cred))); + iee_set_logical_mem_ro((unsigned long)&init_cred); + iee_set_logical_mem_ro((unsigned long)__va(__pa_symbol(&init_cred))); + #else @@ -14760,7 +27295,7 @@ index c033a201c808..ba57e19a26b8 100644 } /** -@@ -638,29 +792,56 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) +@@ -638,29 +790,56 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) if (!new) return NULL; @@ -14817,7 +27352,7 @@ index c033a201c808..ba57e19a26b8 100644 if (!new->ucounts) goto error; -@@ -727,8 +908,13 @@ int set_create_files_as(struct cred *new, struct inode *inode) +@@ -727,8 +906,13 @@ int set_create_files_as(struct cred *new, struct inode *inode) { if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid)) return -EINVAL; @@ -14832,21 +27367,22 @@ index c033a201c808..ba57e19a26b8 100644 } EXPORT_SYMBOL(set_create_files_as); diff --git a/kernel/exit.c b/kernel/exit.c -index 3540b2c9b1b6..e71d3d9290e9 100644 +index 3540b2c9b1b6..3bb305d7edf2 100644 --- a/kernel/exit.c +++ b/kernel/exit.c -@@ -74,6 +74,10 @@ +@@ -74,6 +74,11 @@ #include #include +#ifdef CONFIG_IEE ++#include +#include +#endif + /* * The default value should be high enough to not crash a system that randomly * crashes its kernel from time to time, but low enough to at least not permit -@@ -560,6 +564,9 @@ static void exit_mm(void) +@@ -560,6 +565,9 @@ static void exit_mm(void) smp_mb__after_spinlock(); local_irq_disable(); current->mm = NULL; @@ -14857,22 +27393,24 @@ index 3540b2c9b1b6..e71d3d9290e9 100644 enter_lazy_tlb(mm, current); local_irq_enable(); diff --git a/kernel/fork.c b/kernel/fork.c -index 27d605c64b45..9e01499a25a1 100644 +index f30b24c68442..617cb03938ff 100644 --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -115,6 +115,11 @@ +@@ -115,6 +115,13 @@ #define CREATE_TRACE_POINTS #include +#ifdef CONFIG_IEE +#include +#include ++#include ++#include +#endif + /* * Minimum number of threads to boot the kernel */ -@@ -128,14 +133,14 @@ +@@ -128,14 +135,14 @@ /* * Protected counters by write_lock_irq(&tasklist_lock) */ @@ -14892,7 +27430,7 @@ index 27d605c64b45..9e01499a25a1 100644 NAMED_ARRAY_INDEX(MM_FILEPAGES), NAMED_ARRAY_INDEX(MM_ANONPAGES), NAMED_ARRAY_INDEX(MM_SWAPENTS), -@@ -144,7 +149,7 @@ static const char * const resident_page_types[] = { +@@ -144,7 +151,7 @@ static const char * const resident_page_types[] = { DEFINE_PER_CPU(unsigned long, process_counts) = 0; @@ -14901,7 +27439,7 @@ index 27d605c64b45..9e01499a25a1 100644 #ifdef CONFIG_PROVE_RCU int lockdep_tasklist_lock_is_held(void) -@@ -159,7 +164,7 @@ int nr_processes(void) +@@ -159,7 +166,7 @@ int nr_processes(void) int cpu; int total = 0; @@ -14910,7 +27448,7 @@ index 27d605c64b45..9e01499a25a1 100644 total += per_cpu(process_counts, cpu); return total; -@@ -170,7 +175,11 @@ void __weak arch_release_task_struct(struct task_struct *tsk) +@@ -170,7 +177,11 @@ void __weak arch_release_task_struct(struct task_struct *tsk) } #ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR @@ -14922,7 +27460,7 @@ index 27d605c64b45..9e01499a25a1 100644 static inline struct task_struct *alloc_task_struct_node(int node) { -@@ -190,7 +199,7 @@ static inline void free_task_struct(struct task_struct *tsk) +@@ -190,7 +201,7 @@ static inline void free_task_struct(struct task_struct *tsk) * Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a * kmemcache based allocator. */ @@ -14931,7 +27469,7 @@ index 27d605c64b45..9e01499a25a1 100644 # ifdef CONFIG_VMAP_STACK /* -@@ -311,8 +320,8 @@ static int alloc_thread_stack_node(struct task_struct *tsk, int node) +@@ -311,8 +322,8 @@ static int alloc_thread_stack_node(struct task_struct *tsk, int node) * so memcg accounting is performed manually on assigning/releasing * stacks to tasks. Drop __GFP_ACCOUNT. */ @@ -14942,7 +27480,7 @@ index 27d605c64b45..9e01499a25a1 100644 THREADINFO_GFP & ~__GFP_ACCOUNT, PAGE_KERNEL, 0, node, __builtin_return_address(0)); -@@ -410,9 +419,10 @@ static void free_thread_stack(struct task_struct *tsk) +@@ -410,9 +421,10 @@ static void free_thread_stack(struct task_struct *tsk) void thread_stack_cache_init(void) { @@ -14956,7 +27494,7 @@ index 27d605c64b45..9e01499a25a1 100644 BUG_ON(thread_stack_cache == NULL); } -@@ -502,7 +512,8 @@ struct vm_area_struct *vm_area_alloc(struct mm_struct *mm) +@@ -502,7 +514,8 @@ struct vm_area_struct *vm_area_alloc(struct mm_struct *mm) struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig) { @@ -14966,7 +27504,7 @@ index 27d605c64b45..9e01499a25a1 100644 if (!new) return NULL; -@@ -602,6 +613,10 @@ void put_task_stack(struct task_struct *tsk) +@@ -602,6 +615,10 @@ void put_task_stack(struct task_struct *tsk) } #endif @@ -14977,7 +27515,7 @@ index 27d605c64b45..9e01499a25a1 100644 void free_task(struct task_struct *tsk) { #ifdef CONFIG_SECCOMP -@@ -633,6 +648,21 @@ void free_task(struct task_struct *tsk) +@@ -633,6 +650,21 @@ void free_task(struct task_struct *tsk) if (dynamic_affinity_enabled()) sched_prefer_cpus_free(tsk); #endif @@ -14991,7 +27529,7 @@ index 27d605c64b45..9e01499a25a1 100644 +#endif +#else +#ifdef CONFIG_KOI -+ struct task_token *token = (struct task_token *)((unsigned long)tsk + koi_offset); ++ struct task_token *token = (struct task_token *)((unsigned long)tsk + KOI_OFFSET); + memset(token, 0, sizeof(struct task_token)); +#endif +#endif @@ -14999,7 +27537,7 @@ index 27d605c64b45..9e01499a25a1 100644 #ifdef CONFIG_QOS_SCHED_SMART_GRID if (smart_grid_enabled()) sched_grid_qos_free(tsk); -@@ -657,7 +687,7 @@ static void dup_mm_exe_file(struct mm_struct *mm, struct mm_struct *oldmm) +@@ -661,7 +693,7 @@ static void dup_mm_exe_file(struct mm_struct *mm, struct mm_struct *oldmm) #ifdef CONFIG_MMU static __latent_entropy int dup_mmap(struct mm_struct *mm, @@ -15008,7 +27546,7 @@ index 27d605c64b45..9e01499a25a1 100644 { struct vm_area_struct *mpnt, *tmp; int retval; -@@ -773,7 +803,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, +@@ -772,7 +804,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, flush_dcache_mmap_lock(mapping); /* insert tmp into the share list, just after mpnt */ vma_interval_tree_insert_after(tmp, mpnt, @@ -15017,7 +27555,7 @@ index 27d605c64b45..9e01499a25a1 100644 flush_dcache_mmap_unlock(mapping); i_mmap_unlock_write(mapping); } -@@ -842,7 +872,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) +@@ -846,7 +878,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) mmap_write_unlock(oldmm); return 0; } @@ -15026,7 +27564,7 @@ index 27d605c64b45..9e01499a25a1 100644 #define mm_free_pgd(mm) #endif /* CONFIG_MMU */ -@@ -850,20 +880,22 @@ static void check_mm(struct mm_struct *mm) +@@ -854,20 +886,22 @@ static void check_mm(struct mm_struct *mm) { int i; @@ -15054,7 +27592,7 @@ index 27d605c64b45..9e01499a25a1 100644 #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS VM_BUG_ON_MM(mm->pmd_huge_pte, mm); -@@ -1014,14 +1046,6 @@ void __put_task_struct(struct task_struct *tsk) +@@ -1018,14 +1052,6 @@ void __put_task_struct(struct task_struct *tsk) } EXPORT_SYMBOL_GPL(__put_task_struct); @@ -15069,7 +27607,7 @@ index 27d605c64b45..9e01499a25a1 100644 void __init __weak arch_task_cache_init(void) { } /* -@@ -1039,8 +1063,8 @@ static void set_max_threads(unsigned int max_threads_suggested) +@@ -1043,8 +1069,8 @@ static void set_max_threads(unsigned int max_threads_suggested) if (fls64(nr_pages) + fls64(PAGE_SIZE) > 64) threads = MAX_THREADS; else @@ -15080,7 +27618,7 @@ index 27d605c64b45..9e01499a25a1 100644 if (threads > max_threads_suggested) threads = max_threads_suggested; -@@ -1075,17 +1099,24 @@ void __init fork_init(void) +@@ -1079,17 +1105,24 @@ void __init fork_init(void) int i; #ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR #ifndef ARCH_MIN_TASKALIGN @@ -15107,7 +27645,7 @@ index 27d605c64b45..9e01499a25a1 100644 #endif /* do the arch specific task caches init */ -@@ -1093,8 +1124,8 @@ void __init fork_init(void) +@@ -1097,8 +1130,8 @@ void __init fork_init(void) set_max_threads(MAX_THREADS); @@ -15118,7 +27656,7 @@ index 27d605c64b45..9e01499a25a1 100644 init_task.signal->rlim[RLIMIT_SIGPENDING] = init_task.signal->rlim[RLIMIT_NPROC]; -@@ -1107,8 +1138,8 @@ void __init fork_init(void) +@@ -1111,8 +1144,8 @@ void __init fork_init(void) set_userns_rlimit_max(&init_user_ns, UCOUNT_RLIMIT_MEMLOCK, RLIM_INFINITY); #ifdef CONFIG_VMAP_STACK @@ -15129,7 +27667,7 @@ index 27d605c64b45..9e01499a25a1 100644 #endif scs_init(); -@@ -1118,7 +1149,7 @@ void __init fork_init(void) +@@ -1122,7 +1155,7 @@ void __init fork_init(void) } int __weak arch_dup_task_struct(struct task_struct *dst, @@ -15138,7 +27676,7 @@ index 27d605c64b45..9e01499a25a1 100644 { *dst = *src; return 0; -@@ -1129,14 +1160,14 @@ void set_task_stack_end_magic(struct task_struct *tsk) +@@ -1133,14 +1166,14 @@ void set_task_stack_end_magic(struct task_struct *tsk) unsigned long *stackend; stackend = end_of_stack(tsk); @@ -15156,7 +27694,7 @@ index 27d605c64b45..9e01499a25a1 100644 if (!dst->_resvd) return false; -@@ -1309,7 +1340,7 @@ static void mm_init_uprobes_state(struct mm_struct *mm) +@@ -1321,7 +1354,7 @@ static void mm_init_uprobes_state(struct mm_struct *mm) } static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p, @@ -15165,7 +27703,7 @@ index 27d605c64b45..9e01499a25a1 100644 { mt_init_flags(&mm->mm_mt, MM_MT_FLAGS); mt_set_external_lock(&mm->mm_mt, &mm->mmap_lock); -@@ -1426,8 +1457,8 @@ EXPORT_SYMBOL_GPL(mmput); +@@ -1438,8 +1471,8 @@ EXPORT_SYMBOL_GPL(mmput); #ifdef CONFIG_MMU static void mmput_async_fn(struct work_struct *work) { @@ -15176,7 +27714,7 @@ index 27d605c64b45..9e01499a25a1 100644 __mmput(mm); } -@@ -1603,13 +1634,12 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) +@@ -1615,13 +1648,12 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) struct mm_struct *mm; int err; @@ -15192,7 +27730,7 @@ index 27d605c64b45..9e01499a25a1 100644 mmput(mm); mm = ERR_PTR(-EACCES); } -@@ -1632,7 +1662,7 @@ static void complete_vfork_done(struct task_struct *tsk) +@@ -1644,7 +1676,7 @@ static void complete_vfork_done(struct task_struct *tsk) } static int wait_for_vfork_done(struct task_struct *child, @@ -15201,7 +27739,7 @@ index 27d605c64b45..9e01499a25a1 100644 { unsigned int state = TASK_UNINTERRUPTIBLE|TASK_KILLABLE|TASK_FREEZABLE; int killed; -@@ -1683,8 +1713,8 @@ static void mm_release(struct task_struct *tsk, struct mm_struct *mm) +@@ -1695,8 +1727,8 @@ static void mm_release(struct task_struct *tsk, struct mm_struct *mm) * not set up a proper pointer then tough luck. */ put_user(0, tsk->clear_child_tid); @@ -15212,7 +27750,7 @@ index 27d605c64b45..9e01499a25a1 100644 } tsk->clear_child_tid = NULL; } -@@ -1768,6 +1798,9 @@ static int copy_mm(unsigned long clone_flags, struct task_struct *tsk) +@@ -1780,6 +1812,9 @@ static int copy_mm(unsigned long clone_flags, struct task_struct *tsk) #endif tsk->mm = NULL; @@ -15222,7 +27760,7 @@ index 27d605c64b45..9e01499a25a1 100644 tsk->active_mm = NULL; /* -@@ -1799,6 +1832,9 @@ static int copy_mm(unsigned long clone_flags, struct task_struct *tsk) +@@ -1811,6 +1846,9 @@ static int copy_mm(unsigned long clone_flags, struct task_struct *tsk) } tsk->mm = mm; @@ -15232,7 +27770,7 @@ index 27d605c64b45..9e01499a25a1 100644 tsk->active_mm = mm; sched_mm_cid_fork(tsk); return 0; -@@ -2016,8 +2052,8 @@ static inline void init_task_pid_links(struct task_struct *task) +@@ -2025,8 +2063,8 @@ static inline void init_task_pid_links(struct task_struct *task) INIT_HLIST_NODE(&task->pid_links[type]); } @@ -15243,20 +27781,19 @@ index 27d605c64b45..9e01499a25a1 100644 { if (type == PIDTYPE_PID) task->thread_pid = pid; -@@ -2278,6 +2314,12 @@ static void copy_oom_score_adj(u64 clone_flags, struct task_struct *tsk) +@@ -2288,6 +2326,11 @@ static void copy_oom_score_adj(u64 clone_flags, struct task_struct *tsk) mutex_unlock(&oom_adj_mutex); } +#if defined(CONFIG_KOI) && !defined(CONFIG_IEE) +extern s64 koi_offset; -+extern void koi_init_token(struct task_struct *tsk); +#endif + + #ifdef CONFIG_RV static void rv_task_fork(struct task_struct *p) { -@@ -2315,10 +2357,12 @@ __latent_entropy struct task_struct *copy_process( +@@ -2325,10 +2368,12 @@ __latent_entropy struct task_struct *copy_process( * Don't allow sharing the root directory with processes in a different * namespace */ @@ -15271,7 +27808,7 @@ index 27d605c64b45..9e01499a25a1 100644 return ERR_PTR(-EINVAL); /* -@@ -2343,7 +2387,7 @@ __latent_entropy struct task_struct *copy_process( +@@ -2353,7 +2398,7 @@ __latent_entropy struct task_struct *copy_process( * from creating siblings. */ if ((clone_flags & CLONE_PARENT) && @@ -15280,21 +27817,18 @@ index 27d605c64b45..9e01499a25a1 100644 return ERR_PTR(-EINVAL); /* -@@ -2388,6 +2432,13 @@ __latent_entropy struct task_struct *copy_process( +@@ -2398,6 +2443,10 @@ __latent_entropy struct task_struct *copy_process( p = dup_task_struct(current, node); if (!p) goto fork_out; +#ifdef CONFIG_IEE + iee_validate_token(p); +#else -+#ifdef CONFIG_KOI -+ koi_init_token(p); -+#endif +#endif p->flags &= ~PF_KTHREAD; if (args->kthread) p->flags |= PF_KTHREAD; -@@ -2409,7 +2460,8 @@ __latent_entropy struct task_struct *copy_process( +@@ -2419,7 +2468,8 @@ __latent_entropy struct task_struct *copy_process( /* * Clear TID on mm_release()? */ @@ -15304,7 +27838,7 @@ index 27d605c64b45..9e01499a25a1 100644 ftrace_graph_init_task(p); -@@ -2520,10 +2572,10 @@ __latent_entropy struct task_struct *copy_process( +@@ -2539,10 +2589,10 @@ __latent_entropy struct task_struct *copy_process( #endif #ifdef CONFIG_TRACE_IRQFLAGS memset(&p->irqtrace, 0, sizeof(p->irqtrace)); @@ -15319,7 +27853,7 @@ index 27d605c64b45..9e01499a25a1 100644 #endif p->pagefault_disabled = 0; -@@ -2536,8 +2588,8 @@ __latent_entropy struct task_struct *copy_process( +@@ -2555,8 +2605,8 @@ __latent_entropy struct task_struct *copy_process( p->blocked_on = NULL; /* not blocked yet */ #endif #ifdef CONFIG_BCACHE @@ -15330,7 +27864,7 @@ index 27d605c64b45..9e01499a25a1 100644 #endif #ifdef CONFIG_BPF_SYSCALL RCU_INIT_POINTER(p->bpf_storage, NULL); -@@ -2624,7 +2676,7 @@ __latent_entropy struct task_struct *copy_process( +@@ -2643,7 +2693,7 @@ __latent_entropy struct task_struct *copy_process( /* * sigaltstack should be cleared when sharing the same VM */ @@ -15339,7 +27873,7 @@ index 27d605c64b45..9e01499a25a1 100644 sas_ss_reset(p); /* -@@ -2703,7 +2755,7 @@ __latent_entropy struct task_struct *copy_process( +@@ -2722,7 +2772,7 @@ __latent_entropy struct task_struct *copy_process( write_lock_irq(&tasklist_lock); /* CLONE_PARENT re-uses the old parent */ @@ -15348,7 +27882,7 @@ index 27d605c64b45..9e01499a25a1 100644 p->real_parent = current->real_parent; p->parent_exec_id = current->parent_exec_id; if (clone_flags & CLONE_THREAD) -@@ -2767,8 +2819,9 @@ __latent_entropy struct task_struct *copy_process( +@@ -2786,8 +2836,9 @@ __latent_entropy struct task_struct *copy_process( * tasklist_lock with adding child to the process tree * for propagate_has_child_subreaper optimization. */ @@ -15360,7 +27894,7 @@ index 27d605c64b45..9e01499a25a1 100644 list_add_tail(&p->sibling, &p->real_parent->children); list_add_tail_rcu(&p->tasks, &init_task.tasks); attach_pid(p, PIDTYPE_TGID); -@@ -2919,8 +2972,8 @@ struct task_struct * __init fork_idle(int cpu) +@@ -2938,8 +2989,8 @@ struct task_struct * __init fork_idle(int cpu) */ struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node) { @@ -15371,7 +27905,7 @@ index 27d605c64b45..9e01499a25a1 100644 struct kernel_clone_args args = { .flags = ((lower_32_bits(flags) | CLONE_VM | CLONE_UNTRACED) & ~CSIGNAL), -@@ -3084,8 +3137,8 @@ SYSCALL_DEFINE0(fork) +@@ -3103,8 +3154,8 @@ SYSCALL_DEFINE0(fork) SYSCALL_DEFINE0(vfork) { struct kernel_clone_args args = { @@ -15382,7 +27916,7 @@ index 27d605c64b45..9e01499a25a1 100644 }; return kernel_clone(&args); -@@ -3095,35 +3148,30 @@ SYSCALL_DEFINE0(vfork) +@@ -3114,35 +3165,30 @@ SYSCALL_DEFINE0(vfork) #ifdef __ARCH_WANT_SYS_CLONE #ifdef CONFIG_CLONE_BACKWARDS SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, @@ -15434,7 +27968,7 @@ index 27d605c64b45..9e01499a25a1 100644 }; return kernel_clone(&args); -@@ -3179,21 +3227,21 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs, +@@ -3198,21 +3244,21 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs, return -EINVAL; *kargs = (struct kernel_clone_args){ @@ -15468,7 +28002,7 @@ index 27d605c64b45..9e01499a25a1 100644 return -EFAULT; kargs->set_tid = kset_tid; -@@ -3288,7 +3336,8 @@ SYSCALL_DEFINE2(clone3, struct clone_args __user *, uargs, size_t, size) +@@ -3307,7 +3353,8 @@ SYSCALL_DEFINE2(clone3, struct clone_args __user *, uargs, size_t, size) } #endif @@ -15478,7 +28012,7 @@ index 27d605c64b45..9e01499a25a1 100644 { struct task_struct *leader, *parent, *child; int res; -@@ -3296,8 +3345,8 @@ void walk_process_tree(struct task_struct *top, proc_visitor visitor, void *data +@@ -3315,8 +3362,8 @@ void walk_process_tree(struct task_struct *top, proc_visitor visitor, void *data read_lock(&tasklist_lock); leader = top = top->group_leader; down: @@ -15489,7 +28023,7 @@ index 27d605c64b45..9e01499a25a1 100644 res = visitor(child, data); if (res) { if (res < 0) -@@ -3305,8 +3354,7 @@ void walk_process_tree(struct task_struct *top, proc_visitor visitor, void *data +@@ -3324,8 +3371,7 @@ void walk_process_tree(struct task_struct *top, proc_visitor visitor, void *data leader = child; goto down; } @@ -15499,7 +28033,7 @@ index 27d605c64b45..9e01499a25a1 100644 } } -@@ -3383,11 +3431,11 @@ void __init proc_caches_init(void) +@@ -3402,11 +3448,11 @@ void __init proc_caches_init(void) */ static int check_unshare_flags(unsigned long unshare_flags) { @@ -15516,7 +28050,7 @@ index 27d605c64b45..9e01499a25a1 100644 return -EINVAL; /* * Not implemented, but pretend it works if there is nothing -@@ -3498,7 +3546,7 @@ int ksys_unshare(unsigned long unshare_flags) +@@ -3516,7 +3562,7 @@ int ksys_unshare(unsigned long unshare_flags) * to a new ipc namespace, the semaphore arrays from the old * namespace are unreachable. */ @@ -15525,7 +28059,7 @@ index 27d605c64b45..9e01499a25a1 100644 do_sysvsem = 1; err = unshare_fs(unshare_flags, &new_fs); if (err) -@@ -3509,8 +3557,8 @@ int ksys_unshare(unsigned long unshare_flags) +@@ -3527,8 +3573,8 @@ int ksys_unshare(unsigned long unshare_flags) err = unshare_userns(unshare_flags, &new_cred); if (err) goto bad_unshare_cleanup_fd; @@ -15536,7 +28070,7 @@ index 27d605c64b45..9e01499a25a1 100644 if (err) goto bad_unshare_cleanup_cred; -@@ -3607,8 +3655,8 @@ int unshare_files(void) +@@ -3625,8 +3671,8 @@ int unshare_files(void) return 0; } @@ -15574,21 +28108,22 @@ index 9b43da22647d..8045812e8a3c 100644 EXPORT_SYMBOL(set_groups); diff --git a/kernel/kthread.c b/kernel/kthread.c -index 980e6b325b7d..4208d4740ceb 100644 +index 980e6b325b7d..d83342b67608 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c -@@ -30,6 +30,10 @@ +@@ -30,6 +30,11 @@ #include #include +#ifdef CONFIG_IEE ++#include +#include +#endif + static DEFINE_SPINLOCK(kthread_create_lock); static LIST_HEAD(kthread_create_list); -@@ -1457,6 +1461,9 @@ void kthread_use_mm(struct mm_struct *mm) +@@ -1457,6 +1462,9 @@ void kthread_use_mm(struct mm_struct *mm) tsk->active_mm = mm; tsk->mm = mm; membarrier_update_current_mm(mm); @@ -15598,7 +28133,7 @@ index 980e6b325b7d..4208d4740ceb 100644 switch_mm_irqs_off(active_mm, mm, tsk); local_irq_enable(); task_unlock(tsk); -@@ -1501,7 +1508,11 @@ void kthread_unuse_mm(struct mm_struct *mm) +@@ -1501,7 +1509,11 @@ void kthread_unuse_mm(struct mm_struct *mm) local_irq_disable(); tsk->mm = NULL; membarrier_update_current_mm(NULL); @@ -16312,7 +28847,7 @@ index ce06b2884789..a039c7a50ec5 100644 void __init __iomem * early_ioremap(resource_size_t phys_addr, unsigned long size) diff --git a/mm/huge_memory.c b/mm/huge_memory.c -index eafe846739f4..406ee5134569 100644 +index 16bc36ab903b..2524277912f5 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -40,6 +40,10 @@ @@ -16326,26 +28861,44 @@ index eafe846739f4..406ee5134569 100644 #include #include #include "internal.h" -@@ -2551,7 +2555,8 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma, +@@ -2548,8 +2552,17 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma, old_pmd = pmdp_huge_clear_flush(vma, haddr, pmd); pgtable = pgtable_trans_huge_withdraw(mm, pmd); -- pmd_populate(mm, &_pmd, pgtable); -+ //pmd_populate(mm, &_pmd, pgtable); ++ #ifdef CONFIG_PTP ++ #ifdef CONFIG_X86_64 ++ unsigned long pfn = page_to_pfn(pgtable); ++ paravirt_alloc_pte(mm, pfn); ++ _pmd = __pmd(((pteval_t)pfn << PAGE_SHIFT) | _PAGE_TABLE); ++ #else + _pmd = __pmd(__phys_to_pmd_val(page_to_phys(pgtable)) | PMD_TYPE_TABLE); - ++ #endif ++ #else + pmd_populate(mm, &_pmd, pgtable); +- ++ #endif pte = pte_offset_map(&_pmd, haddr); VM_BUG_ON(!pte); -@@ -2721,7 +2726,8 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, + for (i = 0, addr = haddr; i < HPAGE_PMD_NR; i++, addr += PAGE_SIZE) { +@@ -2718,8 +2731,17 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, * This's critical for some architectures (Power). */ pgtable = pgtable_trans_huge_withdraw(mm, pmd); -- pmd_populate(mm, &_pmd, pgtable); -+ //pmd_populate(mm, &_pmd, pgtable); ++ #ifdef CONFIG_PTP ++ #ifdef CONFIG_X86_64 ++ unsigned long pfn = page_to_pfn(pgtable); ++ paravirt_alloc_pte(mm, pfn); ++ _pmd = __pmd(((pteval_t)pfn << PAGE_SHIFT) | _PAGE_TABLE); ++ #else + _pmd = __pmd(__phys_to_pmd_val(page_to_phys(pgtable)) | PMD_TYPE_TABLE); - ++ #endif ++ #else + pmd_populate(mm, &_pmd, pgtable); +- ++ #endif pte = pte_offset_map(&_pmd, haddr); VM_BUG_ON(!pte); + diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c index 149ab629855c..93b6a7ebde82 100644 --- a/mm/hugetlb_vmemmap.c @@ -16384,7 +28937,7 @@ index 24c809379274..4539eb8e7cce 100644 +} +#endif diff --git a/mm/memory.c b/mm/memory.c -index e248b8338417..e291818c8ed0 100644 +index 23bdb2975087..297a8fde5a69 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -80,6 +80,11 @@ @@ -16393,151 +28946,26 @@ index e248b8338417..e291818c8ed0 100644 +#ifdef CONFIG_PTP +#include -+extern void iee_copy_pte_range(pte_t *new_dst, pte_t *old_dst, pte_t *src_pte, struct vm_area_struct *src_vma, unsigned long dst_vm_flags, pte_t *end_pte); ++#include +#endif + #include #include -@@ -809,7 +814,11 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, - /* Mark the swap entry as shared. */ - if (pte_swp_exclusive(orig_pte)) { - pte = pte_swp_clear_exclusive(orig_pte); -+ #ifdef CONFIG_PTP -+ iee_set_pte_at_delayed(src_mm, addr, src_pte, pte); -+ #else - set_pte_at(src_mm, addr, src_pte, pte); -+ #endif - } - rss[MM_SWAPENTS]++; - } else if (is_migration_entry(entry)) { -@@ -831,7 +840,11 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, - pte = pte_swp_mksoft_dirty(pte); - if (pte_swp_uffd_wp(orig_pte)) - pte = pte_swp_mkuffd_wp(pte); -+ #ifdef CONFIG_PTP -+ iee_set_pte_at_delayed(src_mm, addr, src_pte, pte); -+ #else - set_pte_at(src_mm, addr, src_pte, pte); -+ #endif - } - } else if (is_device_private_entry(entry)) { - page = pfn_swap_entry_to_page(entry); -@@ -865,7 +878,11 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, - pte = swp_entry_to_pte(entry); - if (pte_swp_uffd_wp(orig_pte)) - pte = pte_swp_mkuffd_wp(pte); -+ #ifdef CONFIG_PTP -+ iee_set_pte_at_delayed(src_mm, addr, src_pte, pte); -+ #else - set_pte_at(src_mm, addr, src_pte, pte); -+ #endif - } - } else if (is_device_exclusive_entry(entry)) { - /* -@@ -882,13 +899,22 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, - pte_marker marker = copy_pte_marker(entry, dst_vma); - - if (marker) -+ #ifdef CONFIG_PTP -+ iee_set_pte_at(dst_mm, addr, dst_pte, -+ make_pte_marker(marker)); -+ #else - set_pte_at(dst_mm, addr, dst_pte, - make_pte_marker(marker)); -+ #endif - return 0; - } - if (!userfaultfd_wp(dst_vma)) - pte = pte_swp_clear_uffd_wp(pte); -+ #ifdef CONFIG_PTP -+ iee_set_pte_at(dst_mm, addr, dst_pte, pte); -+ #else - set_pte_at(dst_mm, addr, dst_pte, pte); -+ #endif - return 0; - } - -@@ -936,7 +962,11 @@ copy_present_page(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma - if (userfaultfd_pte_wp(dst_vma, ptep_get(src_pte))) - /* Uffd-wp needs to be delivered to dest pte as well */ - pte = pte_mkuffd_wp(pte); -+ #ifdef CONFIG_PTP -+ iee_set_pte_at(dst_vma->vm_mm, addr, dst_pte, pte); -+ #else - set_pte_at(dst_vma->vm_mm, addr, dst_pte, pte); -+ #endif - return 0; - } - -@@ -960,7 +990,21 @@ static __always_inline void __copy_present_ptes(struct vm_area_struct *dst_vma, - if (!userfaultfd_wp(dst_vma)) - pte = pte_clear_uffd_wp(pte); - -+ #ifdef CONFIG_PTP -+ page_table_check_ptes_set(dst_vma->vm_mm, dst_pte, pte, nr); -+ __sync_cache_and_tags(pte, nr); -+ -+ for (;;) { -+ __check_safe_pte_update(dst_vma->vm_mm, dst_pte, pte); -+ iee_set_pte_at(dst_vma->vm_mm, addr, dst_pte, pte); -+ if (--nr == 0) -+ break; -+ dst_pte++; -+ pte = pte_advance_pfn(pte, 1); -+ } -+ #else - set_ptes(dst_vma->vm_mm, addr, dst_pte, pte, nr); -+ #endif - } - - /* -@@ -1087,6 +1131,12 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma, - swp_entry_t entry = (swp_entry_t){0}; - struct folio *prealloc = NULL; - int nr; -+ #ifdef CONFIG_PTP -+ unsigned long orig_addr; -+ pmd_t pmd; -+ pte_t *old_dst; -+ void *new; -+ #endif - - again: - progress = 0; -@@ -1105,6 +1155,13 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma, +@@ -1111,6 +1116,7 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma, ret = -ENOMEM; goto out; } -+#ifdef CONFIG_PTP -+ orig_addr = addr; -+ new = (void *)iee_read_tmp_page(get_current()); -+ pmd = READ_ONCE(*dst_pmd); -+ dst_pte = (pte_t *)new + pte_index(addr); -+ old_dst = pte_offset_map(&pmd, addr); -+#endif ++ src_pte = pte_offset_map_nolock(src_mm, src_pmd, addr, &src_ptl); if (!src_pte) { pte_unmap_unlock(dst_pte, dst_ptl); -@@ -1183,6 +1240,12 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma, - } while (dst_pte += nr, src_pte += nr, addr += PAGE_SIZE * nr, - addr != end); - -+ #ifdef CONFIG_PTP -+ iee_copy_pte_range(orig_dst_pte, old_dst, orig_src_pte, src_vma, dst_vma->vm_flags, src_pte); -+ orig_dst_pte = pte_offset_map(&pmd, orig_addr); -+ dst_pte = pte_offset_map(&pmd, addr); -+ #endif -+ - arch_leave_lazy_mmu_mode(); - pte_unmap_unlock(orig_src_pte, src_ptl); - add_mm_rss_vec(dst_mm, rss); -@@ -6624,12 +6687,20 @@ bool ptlock_alloc(struct ptdesc *ptdesc) +@@ -6628,12 +6634,20 @@ bool ptlock_alloc(struct ptdesc *ptdesc) ptl = kmem_cache_alloc(page_ptl_cachep, GFP_KERNEL); if (!ptl) return false; + #ifdef CONFIG_PTP -+ ((struct ptdesc_t *)(((struct slab *)ptdesc)->slab_cache)->ptl) = ptl; ++ (iee_ptdesc(ptdesc))->ptl = ptl; + #else ptdesc->ptl = ptl; + #endif @@ -16547,17 +28975,23 @@ index e248b8338417..e291818c8ed0 100644 void ptlock_free(struct ptdesc *ptdesc) { + #ifdef CONFIG_PTP -+ kmem_cache_free(page_ptl_cachep, ((struct ptdesc_t *)(((struct slab *)ptdesc)->slab_cache)->ptl)); ++ kmem_cache_free(page_ptl_cachep, (iee_ptdesc(ptdesc))->ptl); + #else kmem_cache_free(page_ptl_cachep, ptdesc->ptl); + #endif } #endif diff --git a/mm/mmap.c b/mm/mmap.c -index 07ffb6c37b96..02d1f6f54e36 100644 +index dfa3d2bfe289..9139c6838279 100644 --- a/mm/mmap.c +++ b/mm/mmap.c -@@ -2375,7 +2375,11 @@ static void unmap_region(struct mm_struct *mm, struct ma_state *mas, +@@ -2413,10 +2413,17 @@ static void unmap_region(struct mm_struct *mm, struct ma_state *mas, + update_hiwater_rss(mm); + unmap_vmas(&tlb, mas, vma, start, end, tree_end, mm_wr_locked); + mas_set(mas, mt_start); ++ #ifdef CONFIG_PTP ++ tlb_flush_mmu(&tlb); ++ #endif free_pgtables(&tlb, mas, vma, prev ? prev->vm_end : FIRST_USER_ADDRESS, next ? next->vm_start : USER_PGTABLES_CEILING, mm_wr_locked); @@ -16569,8 +29003,13 @@ index 07ffb6c37b96..02d1f6f54e36 100644 } /* -@@ -3286,7 +3290,11 @@ void exit_mmap(struct mm_struct *mm) +@@ -3360,9 +3367,16 @@ void exit_mmap(struct mm_struct *mm) + mmap_write_lock(mm); + mt_clear_in_rcu(&mm->mm_mt); mas_set(&mas, vma->vm_end); ++ #ifdef CONFIG_PTP ++ tlb_flush_mmu(&tlb); ++ #endif free_pgtables(&tlb, &mas, vma, FIRST_USER_ADDRESS, USER_PGTABLES_CEILING, true); + #ifdef CONFIG_PTP @@ -16582,10 +29021,83 @@ index 07ffb6c37b96..02d1f6f54e36 100644 /* * Walk the list again, actually closing and freeing it, with preemption diff --git a/mm/mmu_gather.c b/mm/mmu_gather.c -index 99b3e9408aa0..16c79de60435 100644 +index 99b3e9408aa0..ff58ad5365ce 100644 --- a/mm/mmu_gather.c +++ b/mm/mmu_gather.c -@@ -347,6 +347,71 @@ void tlb_remove_table(struct mmu_gather *tlb, void *table) +@@ -141,6 +141,54 @@ static void __tlb_batch_free_encoded_pages(struct mmu_gather_batch *batch) + } + } + ++#ifdef CONFIG_PTP ++static void __iee_tlb_batch_free_encoded_pages(struct mmu_gather_batch *batch) ++{ ++ struct encoded_page **pages = batch->encoded_pages; ++ unsigned int nr, nr_pages; ++ ++ while (batch->nr) { ++ if (!page_poisoning_enabled_static() && !want_init_on_free()) { ++ nr = min(MAX_NR_FOLIOS_PER_FREE, batch->nr); ++ ++ /* ++ * Make sure we cover page + nr_pages, and don't leave ++ * nr_pages behind when capping the number of entries. ++ */ ++ if (unlikely(encoded_page_flags(pages[nr - 1]) & ++ ENCODED_PAGE_BIT_NR_PAGES_NEXT)) ++ nr++; ++ } else { ++ /* ++ * With page poisoning and init_on_free, the time it ++ * takes to free memory grows proportionally with the ++ * actual memory size. Therefore, limit based on the ++ * actual memory size and not the number of involved ++ * folios. ++ */ ++ for (nr = 0, nr_pages = 0; ++ nr < batch->nr && nr_pages < MAX_NR_FOLIOS_PER_FREE; ++ nr++) { ++ if (unlikely(encoded_page_flags(pages[nr]) & ++ ENCODED_PAGE_BIT_NR_PAGES_NEXT)) ++ nr_pages += encoded_nr_pages(pages[++nr]); ++ else ++ nr_pages++; ++ } ++ } ++ ++ for (int i = 0; i < nr; i++) { ++ struct page *page = encoded_page_ptr(pages[i]); ++ __iee_tlb_remove_table((void *)page); ++ } ++ pages += nr; ++ batch->nr -= nr; ++ ++ cond_resched(); ++ } ++} ++#endif ++ + static void tlb_batch_pages_flush(struct mmu_gather *tlb) + { + struct mmu_gather_batch *batch; +@@ -150,6 +198,17 @@ static void tlb_batch_pages_flush(struct mmu_gather *tlb) + tlb->active = &tlb->local; + } + ++#ifdef CONFIG_PTP ++static void iee_tlb_batch_pages_flush(struct mmu_gather *tlb) ++{ ++ struct mmu_gather_batch *batch; ++ ++ for (batch = &tlb->local; batch && batch->nr; batch = batch->next) ++ __iee_tlb_batch_free_encoded_pages(batch); ++ tlb->active = &tlb->local; ++} ++#endif ++ + static void tlb_batch_list_free(struct mmu_gather *tlb) + { + struct mmu_gather_batch *batch, *next; +@@ -347,6 +406,71 @@ void tlb_remove_table(struct mmu_gather *tlb, void *table) tlb_table_flush(tlb); } @@ -16657,7 +29169,7 @@ index 99b3e9408aa0..16c79de60435 100644 static inline void tlb_table_init(struct mmu_gather *tlb) { tlb->batch = NULL; -@@ -469,3 +534,55 @@ void tlb_finish_mmu(struct mmu_gather *tlb) +@@ -469,3 +593,55 @@ void tlb_finish_mmu(struct mmu_gather *tlb) #endif dec_tlb_flush_pending(tlb->mm); } @@ -16667,7 +29179,7 @@ index 99b3e9408aa0..16c79de60435 100644 +{ + iee_tlb_table_flush(tlb); +#ifndef CONFIG_MMU_GATHER_NO_GATHER -+ tlb_batch_pages_flush(tlb); ++ iee_tlb_batch_pages_flush(tlb); +#endif +} + @@ -16715,7 +29227,7 @@ index 99b3e9408aa0..16c79de60435 100644 +#endif \ No newline at end of file diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c -index 4fcd959dcc4d..bedc3522ddc3 100644 +index 4fcd959dcc4d..17f2d8b81285 100644 --- a/mm/pgtable-generic.c +++ b/mm/pgtable-generic.c @@ -169,9 +169,17 @@ void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, @@ -16723,27 +29235,28 @@ index 4fcd959dcc4d..bedc3522ddc3 100644 /* FIFO */ if (!pmd_huge_pte(mm, pmdp)) + #ifdef CONFIG_PTP -+ INIT_LIST_HEAD(&(((struct ptdesc_t *)(((struct slab_t *)pgtable)->slab_cache))->pt_list)); ++ INIT_LIST_HEAD(&((page_to_iee_ptdesc(pgtable))->pt_list)); + #else INIT_LIST_HEAD(&pgtable->lru); + #endif else + #ifdef CONFIG_PTP -+ list_add(&(((struct ptdesc_t *)(((struct slab_t *)pgtable)->slab_cache))->pt_list), &(((struct ptdesc_t *)(((struct slab_t *)(pmd_huge_pte(mm, pmdp)))->slab_cache))->pt_list)); ++ list_add(&((page_to_iee_ptdesc(pgtable))->pt_list), &((page_to_iee_ptdesc(pmd_huge_pte(mm, pmdp)))->pt_list)); + #else list_add(&pgtable->lru, &pmd_huge_pte(mm, pmdp)->lru); + #endif pmd_huge_pte(mm, pmdp) = pgtable; } #endif -@@ -186,10 +194,22 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp) +@@ -186,10 +194,23 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp) /* FIFO */ pgtable = pmd_huge_pte(mm, pmdp); + #ifdef CONFIG_PTP -+ struct ptdesc_t *ptdesc = list_first_entry_or_null(&(((struct ptdesc_t *)(((struct slab_t *)pgtable)->slab_cache))->pt_list), struct ptdesc_t, pt_list); ++ struct ptdesc_t *ptdesc = list_first_entry_or_null(&((page_to_iee_ptdesc(pgtable))->pt_list), ++ struct ptdesc_t, pt_list); + if(ptdesc) -+ pmd_huge_pte(mm, pmdp) = (struct page *)ptdesc->slab; ++ pmd_huge_pte(mm, pmdp) = ptdesc->page; + else + pmd_huge_pte(mm, pmdp) = NULL; + #else @@ -16752,31 +29265,31 @@ index 4fcd959dcc4d..bedc3522ddc3 100644 + #endif if (pmd_huge_pte(mm, pmdp)) + #ifdef CONFIG_PTP -+ list_del(&(((struct ptdesc_t *)(((struct slab_t *)pgtable)->slab_cache))->pt_list)); ++ list_del(&((iee_ptdesc(pgtable))->pt_list)); + #else list_del(&pgtable->lru); + #endif return pgtable; } #endif -@@ -238,7 +258,11 @@ static void pte_free_now(struct rcu_head *head) +@@ -238,7 +259,11 @@ static void pte_free_now(struct rcu_head *head) { struct page *page; + #ifdef CONFIG_PTP -+ page = (struct page *)((container_of(head, struct ptdesc_t, pt_rcu_head))->slab); ++ page = container_of(head, struct ptdesc_t, pt_rcu_head)->page; + #else page = container_of(head, struct page, rcu_head); + #endif pte_free(NULL /* mm not passed and not used */, (pgtable_t)page); } -@@ -247,7 +271,11 @@ void pte_free_defer(struct mm_struct *mm, pgtable_t pgtable) +@@ -247,7 +272,11 @@ void pte_free_defer(struct mm_struct *mm, pgtable_t pgtable) struct page *page; page = pgtable; + #ifdef CONFIG_PTP -+ call_rcu(&(((struct ptdesc_t *)(((struct slab_t *)page)->slab_cache))->pt_rcu_head), pte_free_now); ++ call_rcu(&((page_to_iee_ptdesc(page))->pt_rcu_head), pte_free_now); + #else call_rcu(&page->rcu_head, pte_free_now); + #endif @@ -16784,35 +29297,54 @@ index 4fcd959dcc4d..bedc3522ddc3 100644 #endif /* pte_free_defer */ #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ diff --git a/mm/slab.h b/mm/slab.h -index 3d07fb428393..69e3f4787ee1 100644 +index 3d07fb428393..67ff0beb4ec3 100644 --- a/mm/slab.h +++ b/mm/slab.h -@@ -26,6 +26,24 @@ typedef u64 freelist_full_t; +@@ -26,6 +26,35 @@ typedef u64 freelist_full_t; #undef system_has_freelist_aba #endif +#ifdef CONFIG_IEE +extern struct kmem_cache *iee_stack_jar; -+extern struct kmem_cache *cred_jar; -+extern struct kmem_cache *key_jar; ++#endif ++ ++#ifdef CONFIG_PTP +extern struct kmem_cache *pgtable_jar; +extern struct kmem_cache *ptdesc_jar; ++extern struct kmem_cache *pgd_jar; ++#endif ++ ++#ifdef CONFIG_CREDP ++extern struct kmem_cache *cred_jar; ++#endif ++ ++#ifdef CONFIG_KEYP ++extern struct kmem_cache *key_jar; +extern struct kmem_cache *key_union_jar; +extern struct kmem_cache *key_struct_jar; +extern struct kmem_cache *key_payload_jar; -+extern void iee_memset(void *ptr, int data, size_t n); -+#endif -+#if defined(CONFIG_KOI) || defined(CONFIG_IEE) -+extern struct kmem_cache *task_struct_cachep; +#endif ++ +#ifdef CONFIG_IEE_SELINUX_P +extern struct kmem_cache *policy_jar; +#endif ++ ++#if defined(CONFIG_KOI) || defined(CONFIG_IEE) ++extern struct kmem_cache *task_struct_cachep; ++#endif + /* * Freelist pointer and counter to cmpxchg together, avoids the typical ABA * problems with cmpxchg of just a pointer. -@@ -843,6 +861,15 @@ static inline void cache_random_seq_destroy(struct kmem_cache *cachep) { } +@@ -767,7 +796,6 @@ static inline void slab_post_alloc_hook(struct kmem_cache *s, + s->flags, flags); + kmsan_slab_alloc(s, p[i], flags); + } +- + memcg_slab_post_alloc_hook(s, objcg, flags, size, p); + } + +@@ -843,6 +871,15 @@ static inline void cache_random_seq_destroy(struct kmem_cache *cachep) { } static inline bool slab_want_init_on_alloc(gfp_t flags, struct kmem_cache *c) { @@ -16821,7 +29353,7 @@ index 3d07fb428393..69e3f4787ee1 100644 + return false; + #endif + #ifdef CONFIG_PTP -+ if(c == pgtable_jar) ++ if(c == pgtable_jar || c == pgd_jar) + return false; + #endif + @@ -16829,10 +29361,10 @@ index 3d07fb428393..69e3f4787ee1 100644 &init_on_alloc)) { if (c->ctor) diff --git a/mm/slab_common.c b/mm/slab_common.c -index 8d431193c273..c755e7320111 100644 +index 735f59618556..a6252bc223be 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c -@@ -145,6 +145,24 @@ int slab_unmergeable(struct kmem_cache *s) +@@ -145,6 +145,26 @@ int slab_unmergeable(struct kmem_cache *s) if (s->ctor) return 1; @@ -16843,9 +29375,11 @@ index 8d431193c273..c755e7320111 100644 + #ifdef CONFIG_PTP + if(strcmp(s->name, "pgtable_jar") == 0) + return 1; ++ if(strcmp(s->name, "pgd_jar") == 0) ++ return 1; + #endif + #ifdef CONFIG_KEYP -+ if((strcmp(s->name, "key_jar") == 0) || (strcmp(s->name, "key_payload_jar") == 0)) ++ if(strcmp(s->name, "key_jar") == 0) + return 1; + #endif + #ifdef CONFIG_IEE_SELINUX_P @@ -16857,7 +29391,7 @@ index 8d431193c273..c755e7320111 100644 #ifdef CONFIG_HARDENED_USERCOPY if (s->usersize) return 1; -@@ -170,6 +188,23 @@ struct kmem_cache *find_mergeable(unsigned int size, unsigned int align, +@@ -170,6 +190,25 @@ struct kmem_cache *find_mergeable(unsigned int size, unsigned int align, if (ctor) return NULL; @@ -16868,12 +29402,14 @@ index 8d431193c273..c755e7320111 100644 + #ifdef CONFIG_PTP + if(strcmp(name, "pgtable_jar") == 0) + return NULL; ++ if(strcmp(name, "pgd_jar") == 0) ++ return NULL; + #endif + #ifdef CONFIG_KEYP -+ if((strcmp(name, "key_jar") == 0) || (strcmp(name, "key_payload_jar") == 0)) ++ if(strcmp(name, "key_jar") == 0) + return NULL; + #endif -+ #ifdef CONFIG_PTP ++ #ifdef CONFIG_IEE_SELINUX_P + if(strcmp(name, "policy_jar") == 0) + return NULL; + #endif @@ -16882,10 +29418,10 @@ index 8d431193c273..c755e7320111 100644 align = calculate_alignment(flags, align, size); size = ALIGN(size, align); diff --git a/mm/slub.c b/mm/slub.c -index bcbfd720b574..3f05ad78eaf1 100644 +index a5ff41567a8f..d426c6fe2251 100644 --- a/mm/slub.c +++ b/mm/slub.c -@@ -42,11 +42,27 @@ +@@ -42,11 +42,30 @@ #include #include @@ -16893,10 +29429,18 @@ index bcbfd720b574..3f05ad78eaf1 100644 +#include +#include +#include ++#include ++#else ++#ifdef CONFIG_KOI ++#include ++extern void koi_add_page_mapping(void *token, void *token_page, unsigned int order); ++extern void koi_init_token(struct task_struct *tsk); ++#endif +#endif +#ifdef CONFIG_PTP +#include +extern unsigned long pgtable_jar_offset; ++extern unsigned long pgd_jar_offset; +#endif + #include @@ -16904,16 +29448,11 @@ index bcbfd720b574..3f05ad78eaf1 100644 #include "internal.h" -+#ifdef CONFIG_KOI -+extern void koi_add_page_mapping(unsigned long dst, unsigned long src); -+extern void koi_remove_page_mapping(unsigned long addr); -+#endif -+ + /* * Lock order: * 1. slab_mutex (Global Mutex) -@@ -317,6 +333,7 @@ static inline bool kmem_cache_has_cpu_partial(struct kmem_cache *s) +@@ -317,6 +336,7 @@ static inline bool kmem_cache_has_cpu_partial(struct kmem_cache *s) /* * Tracking user of a slab. */ @@ -16921,7 +29460,7 @@ index bcbfd720b574..3f05ad78eaf1 100644 #define TRACK_ADDRS_COUNT 16 struct track { unsigned long addr; /* Called from address */ -@@ -329,6 +346,7 @@ struct track { +@@ -329,6 +349,7 @@ struct track { }; enum track_item { TRACK_ALLOC, TRACK_FREE }; @@ -16929,7 +29468,7 @@ index bcbfd720b574..3f05ad78eaf1 100644 #ifdef SLAB_SUPPORTS_SYSFS static int sysfs_slab_add(struct kmem_cache *); -@@ -379,7 +397,9 @@ static struct workqueue_struct *flushwq; +@@ -379,7 +400,9 @@ static struct workqueue_struct *flushwq; * freeptr_t represents a SLUB freelist pointer, which might be encoded * and not dereferenceable if CONFIG_SLAB_FREELIST_HARDENED is enabled. */ @@ -16939,7 +29478,7 @@ index bcbfd720b574..3f05ad78eaf1 100644 /* * Returns freelist pointer (ptr). With hardening, this is obfuscated -@@ -419,7 +439,14 @@ static inline void *get_freepointer(struct kmem_cache *s, void *object) +@@ -419,7 +442,14 @@ static inline void *get_freepointer(struct kmem_cache *s, void *object) object = kasan_reset_tag(object); ptr_addr = (unsigned long)object + s->offset; @@ -16954,36 +29493,51 @@ index bcbfd720b574..3f05ad78eaf1 100644 return freelist_ptr_decode(s, p, ptr_addr); } -@@ -464,7 +491,19 @@ static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp) +@@ -464,6 +494,36 @@ static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp) #endif freeptr_addr = (unsigned long)kasan_reset_tag((void *)freeptr_addr); + #ifdef CONFIG_IEE -+ if((s == iee_stack_jar) || (IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) || (IS_ENABLED(CONFIG_PTP) && (s == pgtable_jar)) || -+ (IS_ENABLED(CONFIG_KEYP) && (s == key_payload_jar)) || (IS_ENABLED(CONFIG_KEYP) && (s == key_jar))) ++ if (s == iee_stack_jar) { + iee_set_freeptr((freeptr_t *)freeptr_addr, freelist_ptr_encode(s, fp, freeptr_addr)); -+#ifdef CONFIG_IEE_SELINUX_P -+ else if (s == policy_jar) ++ return; ++ } ++ #endif ++ #ifdef CONFIG_PTP ++ if (s == pgtable_jar || s == pgd_jar) { + iee_set_freeptr((freeptr_t *)freeptr_addr, freelist_ptr_encode(s, fp, freeptr_addr)); -+#endif -+ else -+ *(freeptr_t *)freeptr_addr = freelist_ptr_encode(s, fp, freeptr_addr); -+ #else - *(freeptr_t *)freeptr_addr = freelist_ptr_encode(s, fp, freeptr_addr); ++ return; ++ } ++ #endif ++ #ifdef CONFIG_CREDP ++ if (s == cred_jar) { ++ iee_set_freeptr((freeptr_t *)freeptr_addr, freelist_ptr_encode(s, fp, freeptr_addr)); ++ return; ++ } ++ #endif ++ #ifdef CONFIG_KEYP ++ if(s == key_jar) { ++ iee_set_freeptr((freeptr_t *)freeptr_addr, freelist_ptr_encode(s, fp, freeptr_addr)); ++ return; ++ } ++ #endif ++ #ifdef CONFIG_IEE_SELINUX_P ++ if (s == policy_jar) { ++ iee_set_freeptr((freeptr_t *)freeptr_addr, freelist_ptr_encode(s, fp, freeptr_addr)); ++ return; ++ } + #endif + *(freeptr_t *)freeptr_addr = freelist_ptr_encode(s, fp, freeptr_addr); } - /* Loop over all objects in a slab */ -@@ -809,7 +848,34 @@ static void set_track_update(struct kmem_cache *s, void *object, +@@ -853,7 +913,31 @@ static void set_track_update(struct kmem_cache *s, void *object, depot_stack_handle_t handle) { struct track *p = get_track(s, object, alloc); -+#ifdef CONFIG_IEE +- ++#ifdef CONFIG_CREDP + struct track tmp; -+#endif - -+#ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) ++ if(s == cred_jar) + { + tmp = *p; + #ifdef CONFIG_STACKDEPOT @@ -17009,7 +29563,7 @@ index bcbfd720b574..3f05ad78eaf1 100644 #ifdef CONFIG_STACKDEPOT p->handle = handle; #endif -@@ -817,6 +883,7 @@ static void set_track_update(struct kmem_cache *s, void *object, +@@ -861,6 +945,7 @@ static void set_track_update(struct kmem_cache *s, void *object, p->cpu = smp_processor_id(); p->pid = current->pid; p->when = jiffies; @@ -17017,12 +29571,12 @@ index bcbfd720b574..3f05ad78eaf1 100644 } static __always_inline void set_track(struct kmem_cache *s, void *object, -@@ -835,7 +902,14 @@ static void init_tracking(struct kmem_cache *s, void *object) +@@ -879,7 +964,14 @@ static void init_tracking(struct kmem_cache *s, void *object) return; p = get_track(s, object, TRACK_ALLOC); -+ #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) ++ #ifdef CONFIG_CREDP ++ if(s == cred_jar) + iee_memset(p, 0, 2*sizeof(struct track)); + else + memset(p, 0, 2*sizeof(struct track)); @@ -17032,12 +29586,12 @@ index bcbfd720b574..3f05ad78eaf1 100644 } static void print_track(const char *s, struct track *t, unsigned long pr_time) -@@ -1045,7 +1119,14 @@ static void init_object(struct kmem_cache *s, void *object, u8 val) +@@ -1045,7 +1137,14 @@ static void init_object(struct kmem_cache *s, void *object, u8 val) unsigned int poison_size = s->object_size; if (s->flags & SLAB_RED_ZONE) { -+ #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) ++ #ifdef CONFIG_CREDP ++ if(s == cred_jar) + iee_memset(p - s->red_left_pad, val, s->red_left_pad); + else + memset(p - s->red_left_pad, val, s->red_left_pad); @@ -17047,12 +29601,12 @@ index bcbfd720b574..3f05ad78eaf1 100644 if (slub_debug_orig_size(s) && val == SLUB_RED_ACTIVE) { /* -@@ -1058,12 +1139,34 @@ static void init_object(struct kmem_cache *s, void *object, u8 val) +@@ -1058,12 +1157,33 @@ static void init_object(struct kmem_cache *s, void *object, u8 val) } if (s->flags & __OBJECT_POISON) { -+ #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) ++ #ifdef CONFIG_CREDP ++ if(s == cred_jar) + { + iee_memset(p, POISON_FREE, poison_size - 1); + iee_memset(&p[poison_size - 1], POISON_END, 1); @@ -17070,25 +29624,24 @@ index bcbfd720b574..3f05ad78eaf1 100644 - if (s->flags & SLAB_RED_ZONE) + if (s->flags & SLAB_RED_ZONE) { -+ #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) ++ #ifdef CONFIG_CREDP ++ if(s == cred_jar) + iee_memset(p + poison_size, val, s->inuse - poison_size); + else + memset(p + poison_size, val, s->inuse - poison_size); + #else memset(p + poison_size, val, s->inuse - poison_size); + #endif -+ + } } static void restore_bytes(struct kmem_cache *s, char *message, u8 data, -@@ -1433,7 +1536,14 @@ void setup_slab_debug(struct kmem_cache *s, struct slab *slab, void *addr) +@@ -1433,7 +1553,14 @@ void setup_slab_debug(struct kmem_cache *s, struct slab *slab, void *addr) return; metadata_access_enable(); -+ #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) ++ #ifdef CONFIG_CREDP ++ if(s == cred_jar) + iee_memset(kasan_reset_tag(addr), POISON_INUSE, slab_size(slab)); + else + memset(kasan_reset_tag(addr), POISON_INUSE, slab_size(slab)); @@ -17098,7 +29651,7 @@ index bcbfd720b574..3f05ad78eaf1 100644 metadata_access_disable(); } -@@ -1984,6 +2094,21 @@ static bool shuffle_freelist(struct kmem_cache *s, struct slab *slab) +@@ -1990,6 +2117,32 @@ static bool shuffle_freelist(struct kmem_cache *s, struct slab *slab) cur = setup_object(s, cur); slab->freelist = cur; @@ -17116,11 +29669,22 @@ index bcbfd720b574..3f05ad78eaf1 100644 + } + } + #endif -+ ++ #if defined(CONFIG_KOI) && !defined(CONFIG_IEE) ++ if(s == task_struct_cachep) ++ { ++ int i; ++ void *obj; ++ for(i = 0; i < freelist_count; i++) ++ { ++ obj = start + s->random_seq[i]; ++ koi_init_token((struct task_struct *)obj); ++ } ++ } ++ #endif for (idx = 1; idx < slab->objects; idx++) { next = next_freelist_entry(s, &pos, start, page_limit, freelist_count); -@@ -2015,6 +2140,9 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) +@@ -2021,6 +2174,9 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) void *start, *p, *next; int idx; bool shuffle; @@ -17130,21 +29694,22 @@ index bcbfd720b574..3f05ad78eaf1 100644 flags &= gfp_allowed_mask; -@@ -2028,15 +2156,45 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) +@@ -2034,15 +2190,46 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) if ((alloc_gfp & __GFP_DIRECT_RECLAIM) && oo_order(oo) > oo_order(s->min)) alloc_gfp = (alloc_gfp | __GFP_NOMEMALLOC) & ~__GFP_RECLAIM; -+ #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_PTP) && (s == pgtable_jar)) -+ alloc_gfp |= __GFP_ZERO; -+ #ifdef CONFIG_IEE_SELINUX_P -+ if(s == policy_jar) ++ #ifdef CONFIG_PTP ++ if(s == pgtable_jar || s == pgd_jar) + alloc_gfp |= __GFP_ZERO; + #endif -+ #endif + #ifdef CONFIG_KEYP + if(s == key_jar) + alloc_gfp |= __GFP_ZERO; ++ #endif ++ ++ #ifdef CONFIG_IEE_SELINUX_P ++ if(s == policy_jar) ++ alloc_gfp |= __GFP_ZERO; + #endif slab = alloc_slab_page(alloc_gfp, node, oo); + #if defined(CONFIG_IEE) || defined(CONFIG_KOI) @@ -17153,17 +29718,17 @@ index bcbfd720b574..3f05ad78eaf1 100644 if (unlikely(!slab)) { oo = s->min; alloc_gfp = flags; -+ #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_PTP) && (s == pgtable_jar)) -+ alloc_gfp |= __GFP_ZERO; -+ #ifdef CONFIG_IEE_SELINUX_P -+ if(s == policy_jar) ++ #ifdef CONFIG_PTP ++ if(s == pgtable_jar || s == pgd_jar) + alloc_gfp |= __GFP_ZERO; + #endif -+ #endif + #ifdef CONFIG_KEYP + if(s == key_jar) + alloc_gfp |= __GFP_ZERO; ++ #endif ++ #ifdef CONFIG_IEE_SELINUX_P ++ if(s == policy_jar) ++ alloc_gfp |= __GFP_ZERO; + #endif /* * Allocation may have failed due to fragmentation. @@ -17176,34 +29741,41 @@ index bcbfd720b574..3f05ad78eaf1 100644 if (unlikely(!slab)) return NULL; stat(s, ORDER_FALLBACK); -@@ -2046,9 +2204,71 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) +@@ -2052,6 +2239,63 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) slab->inuse = 0; slab->frozen = 0; + #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_PTP) && (s == pgtable_jar)) ++ if (s == task_struct_cachep) + { -+ int i; -+ struct page *page = folio_page(slab_folio(slab), 0); -+ for(i = 0; i < (0x1 << order); i++) -+ { -+ set_page_refcounted(page + i); -+ (slab+i)->slab_cache = kmem_cache_alloc(ptdesc_jar, GFP_KERNEL); -+ ((struct ptdesc_t *)((slab+i)->slab_cache))->slab = (struct slab_t *)(slab+i); -+ __folio_set_slab((struct folio *)(slab+i)); -+ } -+ set_iee_page((unsigned long)page_address(page), order); ++ void *token_addr = (void *)__phys_to_iee(page_to_phys(folio_page(slab_folio(slab), 0))); ++ void *alloc_token = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order); ++ iee_set_token_page_valid(token_addr, alloc_token, order); + } ++ if (s == iee_stack_jar) { ++ set_iee_stack_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order); ++ } ++ ++ #ifdef CONFIG_PTP ++ if (s == pgtable_jar || s == pgd_jar) ++ { ++ set_iee_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order); ++ } ++ #endif + -+ if(IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) ++ #ifdef CONFIG_CREDP ++ if (s == cred_jar) + { + set_iee_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order); + } ++ #endif + -+ if(IS_ENABLED(CONFIG_KEYP) && ((s == key_jar) || (s == key_payload_jar))) ++ #ifdef CONFIG_KEYP ++ if(s == key_jar) + { + set_iee_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order); + } ++ #endif + + #ifdef CONFIG_IEE_SELINUX_P + if(s == policy_jar) @@ -17211,84 +29783,156 @@ index bcbfd720b574..3f05ad78eaf1 100644 + set_iee_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order); + } + #endif -+ -+ if(s == iee_stack_jar) -+ { -+ set_iee_stack_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order); -+ } -+ -+ // If the page belongs to a task_struct, alloc token for it and set iee&lm va. -+ if(s == task_struct_cachep) -+ { -+ void *token_addr = (void *)__phys_to_iee(page_to_phys(folio_page(slab_folio(slab), 0))); -+ void *alloc_token = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order); -+ iee_set_token_page_valid(token_addr, alloc_token, order); -+ } + #else + #ifdef CONFIG_KOI + if (s == task_struct_cachep) { ++#ifdef CONFIG_X86_64 ++ void *token_addr = (void *)__phys_to_koi(page_to_phys(folio_page(slab_folio(slab), 0))); ++ void *alloc_token = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order); ++ koi_add_page_mapping(token_addr, alloc_token, order); ++#else + int i; + for (i = 0; i < (0x1 << order); i++) { + unsigned long token_addr = __phys_to_virt(page_to_phys(folio_page(slab_folio(slab), i))) + (unsigned long)KOI_OFFSET; + unsigned long alloc_token = __get_free_page(GFP_KERNEL | __GFP_ZERO); + koi_add_page_mapping(token_addr, alloc_token); + } ++#endif + } + #endif + #endif + account_slab(slab, oo_order(oo), s, flags); -+ #ifdef CONFIG_PTP -+ if(!(s == pgtable_jar)) -+ slab->slab_cache = s; -+ #else slab->slab_cache = s; -+ #endif - - kasan_poison_slab(slab); +@@ -2091,6 +2335,114 @@ static struct slab *new_slab(struct kmem_cache *s, gfp_t flags, int node) + flags & (GFP_RECLAIM_MASK | GFP_CONSTRAINT_MASK), node); + } -@@ -2098,6 +2318,98 @@ static void __free_slab(struct kmem_cache *s, struct slab *slab) - __folio_clear_slab(folio); - mm_account_reclaimed_pages(pages); - unaccount_slab(slab, order, s); -+ -+ #ifdef CONFIG_IEE -+ if(IS_ENABLED(CONFIG_PTP) && (s == pgtable_jar)) ++#if defined(CONFIG_X86_64) && defined (CONFIG_IEE) ++struct iee_free_slab_work { ++ struct work_struct work; ++ struct kmem_cache *s; ++ struct slab *slab; ++}; ++static void iee_free_task_struct_slab(struct work_struct *work) ++{ ++ struct iee_free_slab_work *iee_free_slab_work = container_of(work, struct iee_free_slab_work, work); ++ struct kmem_cache *s = iee_free_slab_work->s; ++ struct slab *slab = iee_free_slab_work->slab; ++ struct folio *folio = slab_folio(slab); ++ int order = folio_order(folio); ++ // Free stack and tmp page. ++ int i; ++ void *start = fixup_red_left(s, page_address(folio_page(folio, 0))); ++ void *obj; ++ void *iee_stack; ++ void *tmp_page; ++ void *token; ++ for(i = 0; i < oo_objects(s->oo); i++) + { -+ int i; -+ unset_iee_page((unsigned long)page_address(folio_page(folio, 0)), order); -+ for(i = 0; i < (0x1 << order); i++) -+ { -+ set_page_count(folio_page(folio, i), 0); ++ obj = start + s->random_seq[i]; ++ iee_stack = (void *)iee_read_token_stack((struct task_struct *)obj); ++ if (iee_stack) { ++ free_iee_stack((void *)(iee_stack - PAGE_SIZE * 4 - IEE_OFFSET)); + } ++ tmp_page = iee_read_tmp_page((struct task_struct *)obj); ++ free_pages((unsigned long)tmp_page, 0); + } ++ // Free token. ++ token = (void *)__phys_to_iee(page_to_phys(folio_page(folio, 0))); ++ iee_set_token_page_invalid(token, NULL, order); ++ __free_pages(&folio->page, order); ++ kfree(iee_free_slab_work); ++} ++#ifdef CONFIG_PTP ++static void iee_free_pgtable_slab(struct work_struct *work) ++{ ++ struct iee_free_slab_work *iee_free_slab_work = container_of(work, struct iee_free_slab_work, work); ++ struct slab *slab = iee_free_slab_work->slab; ++ struct folio *folio = slab_folio(slab); ++ int order = folio_order(folio); ++ unset_iee_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order); ++ __free_pages(&folio->page, order); ++ kfree(iee_free_slab_work); ++} ++#endif + -+ if(IS_ENABLED(CONFIG_CREDP) && (s == cred_jar)) -+ { -+ unset_iee_page((unsigned long)page_address(folio_page(folio, 0)), order); -+ } -+ -+ if(IS_ENABLED(CONFIG_KEYP) && ((s == key_jar) || (s == key_payload_jar))) -+ { -+ unset_iee_page((unsigned long)page_address(folio_page(folio, 0)), order); -+ } ++#ifdef CONFIG_CREDP ++static void iee_free_cred_slab(struct work_struct *work) ++{ ++ struct iee_free_slab_work *iee_free_slab_work = container_of(work, struct iee_free_slab_work, work); ++ struct slab *slab = iee_free_slab_work->slab; ++ struct folio *folio = slab_folio(slab); ++ int order = folio_order(folio); ++ unset_iee_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order); ++ __free_pages(&folio->page, order); ++ kfree(iee_free_slab_work); ++} ++#endif ++static void iee_free_slab(struct kmem_cache *s, struct slab *slab, void (*do_free_slab)(struct work_struct *work)) ++{ ++ struct iee_free_slab_work *iee_free_slab_work = kmalloc(sizeof(struct iee_free_slab_work), GFP_ATOMIC); ++ if (!iee_free_slab_work) ++ panic("No mem for struct iee_free_slab_work"); ++ iee_free_slab_work->s = s; ++ iee_free_slab_work->slab = slab; ++ INIT_WORK(&iee_free_slab_work->work, do_free_slab); ++ schedule_work(&iee_free_slab_work->work); ++} ++#else ++#ifdef CONFIG_KOI ++extern void koi_remove_page_mapping(unsigned long token, void *__unused, unsigned long order); ++#ifdef CONFIG_X86_64 ++struct koi_free_slab_work { ++ struct work_struct work; ++ struct kmem_cache *s; ++ struct slab *slab; ++}; ++static void koi_free_task_struct_slab(struct work_struct *work) ++{ ++ struct koi_free_slab_work *koi_free_slab_work = container_of(work, struct koi_free_slab_work, work); ++ struct slab *slab = koi_free_slab_work->slab; ++ struct folio *folio = slab_folio(slab); ++ int order = folio_order(folio); ++ void *token; ++ // Free token. ++ token = (void *)__phys_to_koi(page_to_phys(folio_page(folio, 0))); ++ koi_remove_page_mapping((unsigned long)token, NULL, order); ++ __free_pages(&folio->page, order); ++ kfree(koi_free_slab_work); ++} + -+ #ifdef CONFIG_IEE_SELINUX_P -+ if(s == policy_jar) -+ { -+ unset_iee_page((unsigned long)page_address(folio_page(folio, 0)), order); -+ } -+ #endif ++static void koi_free_slab(struct kmem_cache *s, struct slab *slab, void (*do_free_slab)(struct work_struct *work)) ++{ ++ struct koi_free_slab_work *koi_free_slab_work = kmalloc(sizeof(struct koi_free_slab_work), GFP_ATOMIC); ++ if (!koi_free_slab_work) ++ panic("No mem for struct koi_free_slab_work"); ++ koi_free_slab_work->s = s; ++ koi_free_slab_work->slab = slab; ++ INIT_WORK(&koi_free_slab_work->work, do_free_slab); ++ schedule_work(&koi_free_slab_work->work); ++} ++#endif /* CONFIG_X86_64 */ ++#endif /* CONFIG_KOI */ ++#endif + -+ if(s == iee_stack_jar) -+ { -+ unset_iee_stack_page((unsigned long)page_address(folio_page(folio, 0)), order); -+ } + static void __free_slab(struct kmem_cache *s, struct slab *slab) + { + struct folio *folio = slab_folio(slab); +@@ -2104,6 +2456,118 @@ static void __free_slab(struct kmem_cache *s, struct slab *slab) + __folio_clear_slab(folio); + mm_account_reclaimed_pages(pages); + unaccount_slab(slab, order, s); + ++ #ifdef CONFIG_IEE + // If the page containing this token is empty, free it and restore iee&lm va. + if(s == task_struct_cachep) + { ++ #ifdef CONFIG_X86_64 ++ iee_free_slab(s, slab, iee_free_task_struct_slab); ++ return; ++ #else + // Free stack. + int i; + void *start = fixup_red_left(s, page_address(folio_page(folio, 0))); @@ -17319,27 +29963,75 @@ index bcbfd720b574..3f05ad78eaf1 100644 + iee_set_token_page_invalid(token_addr, token_page, order); + free_pages((unsigned long)token_page, order); + } ++ #endif ++ } ++ if (s == iee_stack_jar) ++ { ++ unset_iee_stack_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order); ++ } ++ ++ #ifdef CONFIG_PTP ++ if(s == pgtable_jar || s == pgd_jar) ++ { ++ #ifdef CONFIG_X86_64 ++ iee_free_slab(s, slab, iee_free_pgtable_slab); ++ return; ++ #else ++ unset_iee_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order); ++ #endif ++ } ++ #endif ++ ++ #ifdef CONFIG_CREDP ++ if (s == cred_jar) ++ { ++ #ifdef CONFIG_X86_64 ++ iee_free_slab(s, slab, iee_free_cred_slab); ++ return; ++ #else ++ unset_iee_page((unsigned long)page_address(folio_page(folio, 0)), order); ++ #endif ++ } ++ #endif ++ ++ #ifdef CONFIG_KEYP ++ if(s == key_jar) ++ { ++ unset_iee_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order); ++ } ++ #endif ++ ++ #ifdef CONFIG_IEE_SELINUX_P ++ if(s == policy_jar) ++ { ++ unset_iee_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order); + } ++ #endif ++ + #else + #ifdef CONFIG_KOI + if(s == task_struct_cachep) + { -+ int i; ++ #ifdef CONFIG_X86_64 ++ koi_free_slab(s, slab, koi_free_task_struct_slab); ++ return; ++ #else ++ int i; + for(i = 0; i < (0x1 << order); i++) -+ { -+ unsigned long token_addr = __phys_to_virt(page_to_phys(folio_page(folio, i))) + (unsigned long)KOI_OFFSET; -+ unsigned long flags; -+ local_irq_save(flags); -+ asm volatile("at s1e1r, %0"::"r"(token_addr)); -+ isb(); -+ unsigned long res = read_sysreg(par_el1); -+ local_irq_restore(flags); -+ if(!(res & 0x1)) -+ { -+ koi_remove_page_mapping(token_addr); -+ free_page((unsigned long)__va(res & PTE_ADDR_MASK)); -+ } -+ } ++ { ++ unsigned long token_addr = __phys_to_virt(page_to_phys(folio_page(folio, i))) + (unsigned long)KOI_OFFSET; ++ unsigned long flags; ++ local_irq_save(flags); ++ asm volatile("at s1e1r, %0"::"r"(token_addr)); ++ isb(); ++ unsigned long res = read_sysreg(par_el1); ++ local_irq_restore(flags); ++ if(!(res & 0x1)) { ++ koi_remove_page_mapping(token_addr, NULL, 0); ++ free_page((unsigned long)__va(res & PTE_ADDR_MASK)); ++ } ++ } ++ #endif + } + #endif + #endif @@ -17347,31 +30039,110 @@ index bcbfd720b574..3f05ad78eaf1 100644 __free_pages(&folio->page, order); } -@@ -2118,6 +2430,23 @@ static void free_slab(struct kmem_cache *s, struct slab *slab) - check_object(s, slab, p, SLUB_RED_INACTIVE); - } +@@ -3447,6 +3911,38 @@ static __always_inline void maybe_wipe_obj_freeptr(struct kmem_cache *s, + 0, sizeof(void *)); + } -+ #ifdef CONFIG_PTP -+ struct page *page = folio_page(slab_folio(slab), 0); -+ int order = compound_order(page); -+ if(s == pgtable_jar) -+ { -+ int i; -+ kmem_cache_free(ptdesc_jar, slab->slab_cache); -+ slab->slab_cache = s; -+ for(i = 1; i < (0x1 << order); i++) -+ { -+ kmem_cache_free(ptdesc_jar, (slab+i)->slab_cache); -+ set_compound_head(page+i,page); -+ __folio_clear_slab((struct folio *)(slab+i)); -+ } -+ } -+ #endif ++#ifdef CONFIG_IEE ++#ifdef CONFIG_KFENCE ++static bool is_iee_kmem_cache(struct kmem_cache *s) ++{ ++ if (s == iee_stack_jar) ++ return true; ++#ifdef CONFIG_PTP ++ else if (s == pgtable_jar || s == pgd_jar) ++ return true; ++#endif ++#ifdef CONFIG_CREDP ++ else if (s == cred_jar) ++ return true; ++#endif ++#ifdef CONFIG_KEYP ++ else if (s == key_jar) ++ return true; ++#endif ++#ifdef CONFIG_IEE_SELINUX_P ++ else if (s == policy_jar) ++ return true; ++#endif ++ return false; ++} ++#else ++static bool is_iee_kmem_cache(struct kmem_cache *s) ++{ ++ return false; ++} ++#endif // CONFIG_KFENCE ++#endif // CONFIG_IEE + - if (unlikely(s->flags & SLAB_TYPESAFE_BY_RCU)) - call_rcu(&slab->rcu_head, rcu_free_slab); - else -@@ -4285,6 +4614,35 @@ static void early_kmem_cache_node_alloc(int node) + /* + * Inlined fastpath so that allocation functions (kmalloc, kmem_cache_alloc) + * have the fastpath folded into their functions. So no function call +@@ -3468,10 +3964,18 @@ static __fastpath_inline void *slab_alloc_node(struct kmem_cache *s, struct list + if (!s) + return NULL; + ++#ifdef CONFIG_IEE ++ /* Skip kfence_alloc for iee kmem caches. */ ++ if(is_iee_kmem_cache(s)) ++ goto slab_alloc; ++#endif + object = kfence_alloc(s, orig_size, gfpflags); + if (unlikely(object)) + goto out; + ++#ifdef CONFIG_IEE ++slab_alloc: ++#endif + object = __slab_alloc_node(s, gfpflags, node, addr, orig_size); + + maybe_wipe_obj_freeptr(s, object); +@@ -3493,6 +3997,8 @@ static __fastpath_inline void *slab_alloc(struct kmem_cache *s, struct list_lru + return slab_alloc_node(s, lru, gfpflags, NUMA_NO_NODE, addr, orig_size); + } + ++// u64 pgtable_alloc_count = 0; ++ + static __fastpath_inline + void *__kmem_cache_alloc_lru(struct kmem_cache *s, struct list_lru *lru, + gfp_t gfpflags) +@@ -3501,6 +4007,13 @@ void *__kmem_cache_alloc_lru(struct kmem_cache *s, struct list_lru *lru, + + trace_kmem_cache_alloc(_RET_IP_, ret, s, gfpflags, NUMA_NO_NODE); + ++ // if (s == pgtable_jar && (pgtable_alloc_count % 100 == 0)) { ++ // printk("IEE TEST: object 0x%llx slab 0x%llx obj_to_page 0x%llx", ++ // (u64)ret, page_address((struct page*)virt_to_slab(ret)), ++ // page_address(virt_to_page(ret))); ++ // pgtable_alloc_count++; ++ // } ++ + return ret; + } + +@@ -3951,6 +4464,11 @@ static inline int __kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, + local_lock_irqsave(&s->cpu_slab->lock, irqflags); + + for (i = 0; i < size; i++) { ++ #ifdef CONFIG_IEE ++ /* Skip kfence_alloc for iee kmem caches. */ ++ if(is_iee_kmem_cache(s)) ++ goto slab_alloc; ++ #endif + void *object = kfence_alloc(s, s->object_size, flags); + + if (unlikely(object)) { +@@ -3958,6 +4476,9 @@ static inline int __kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, + continue; + } + ++ #ifdef CONFIG_IEE ++ slab_alloc: ++ #endif + object = c->freelist; + if (unlikely(!object)) { + /* +@@ -4291,6 +4812,36 @@ static void early_kmem_cache_node_alloc(int node) __add_partial(n, slab, DEACTIVATE_TO_HEAD); } @@ -17394,6 +30165,7 @@ index bcbfd720b574..3f05ad78eaf1 100644 + } + + slab->inuse = 0; ++ inc_slabs_node(pgtable_jar, node, slab->objects); + + /* + * No locks need to be taken here as it has just been @@ -17407,11 +30179,12 @@ index bcbfd720b574..3f05ad78eaf1 100644 static void free_kmem_cache_nodes(struct kmem_cache *s) { int node; -@@ -4479,6 +4837,31 @@ static int calculate_sizes(struct kmem_cache *s) +@@ -4484,6 +5035,31 @@ static int calculate_sizes(struct kmem_cache *s) + s->size = size; s->reciprocal_size = reciprocal_value(size); order = calculate_order(size); - -+ #ifdef CONFIG_IEE ++ ++ #if defined(CONFIG_IEE) || defined(CONFIG_KOI) + if(strcmp(s->name, "task_struct") == 0) + order = HUGE_PMD_ORDER; + if(strcmp(s->name, "iee_stack_jar") == 0) @@ -17420,6 +30193,8 @@ index bcbfd720b574..3f05ad78eaf1 100644 + #ifdef CONFIG_PTP + if(strcmp(s->name, "pgtable_jar") == 0) + order = HUGE_PMD_ORDER; ++ if(strcmp(s->name, "pgd_jar") == 0) ++ order = HUGE_PMD_ORDER; + #endif + #ifdef CONFIG_CREDP + if(strcmp(s->name, "cred_jar") == 0) @@ -17428,18 +30203,15 @@ index bcbfd720b574..3f05ad78eaf1 100644 + #ifdef CONFIG_KEYP + if(strcmp(s->name, "key_jar") == 0) + order = HUGE_PMD_ORDER; -+ if(strcmp(s->name, "key_payload_jar") == 0) -+ order = HUGE_PMD_ORDER; + #endif + #ifdef CONFIG_IEE_SELINUX_P + if(strcmp(s->name, "policy_jar") == 0) + order = HUGE_PMD_ORDER; + #endif -+ + if ((int)order < 0) return 0; - -@@ -4540,6 +4923,23 @@ static int kmem_cache_open(struct kmem_cache *s, slab_flags_t flags) +@@ -4546,6 +5122,23 @@ static int kmem_cache_open(struct kmem_cache *s, slab_flags_t flags) s->min_partial = min_t(unsigned long, MAX_PARTIAL, ilog2(s->size) / 2); s->min_partial = max_t(unsigned long, MIN_PARTIAL, s->min_partial); @@ -17452,31 +30224,33 @@ index bcbfd720b574..3f05ad78eaf1 100644 + #ifdef CONFIG_PTP + if(strcmp(s->name, "pgtable_jar") == 0) + s->min_partial = (1 << HUGE_PMD_ORDER); ++ if(strcmp(s->name, "pgd_jar") == 0) ++ s->min_partial = (1 << HUGE_PMD_ORDER); + #endif + #ifdef CONFIG_KEYP + if(strcmp(s->name, "key_jar") == 0) + s->min_partial = (1 << TASK_ORDER); -+ if(strcmp(s->name, "key_payload_jar") == 0) -+ s->min_partial = (1 << TASK_ORDER); + #endif + set_cpu_partial(s); #ifdef CONFIG_NUMA -@@ -5113,6 +5513,11 @@ int __kmem_cache_create(struct kmem_cache *s, slab_flags_t flags) +@@ -5119,6 +5712,13 @@ int __kmem_cache_create(struct kmem_cache *s, slab_flags_t flags) if (err) return err; + #ifdef CONFIG_PTP + if(strcmp(s->name, "pgtable_jar") == 0) + pgtable_jar_offset = s->offset; ++ if (strcmp(s->name, "pgd_jar") == 0) ++ pgd_jar_offset = s->offset; + #endif + /* Mutex is not taken during early boot */ if (slab_state <= UP) return 0; diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c -index a2cbe44c48e1..6b118447f197 100644 +index 2628fc02be08..8601b88ab96f 100644 --- a/mm/sparse-vmemmap.c +++ b/mm/sparse-vmemmap.c @@ -28,6 +28,10 @@ @@ -17502,9 +30276,9 @@ index a2cbe44c48e1..6b118447f197 100644 get_page(reuse); p = page_to_virt(reuse); } -+#ifdef CONFIG_PTP -+ set_iee_page((unsigned long)p,0); -+#endif ++ #ifdef CONFIG_PTP ++ set_iee_page_valid((unsigned long)__phys_to_iee(__pa(p))); ++ #endif entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL); set_pte_at(&init_mm, addr, pte, entry); } @@ -17513,7 +30287,7 @@ index a2cbe44c48e1..6b118447f197 100644 memset(p, 0, size); + #ifdef CONFIG_PTP -+ set_iee_page_valid(__phys_to_iee(__pa(p))); ++ set_iee_page_valid((unsigned long)__phys_to_iee(__pa(p))); + #endif + return p; @@ -17564,6 +30338,61 @@ index 051d22c0e4ad..cd5839ea3000 100644 ceph_crypto_key_destroy(ckey); kfree(ckey); +diff --git a/net/core/filter.c b/net/core/filter.c +index 48dd2896ee1d..4ef815d885d4 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -569,7 +569,7 @@ static int bpf_convert_filter(struct sock_filter *prog, int len, + u8 bpf_src; + + BUILD_BUG_ON(BPF_MEMWORDS * sizeof(u32) > MAX_BPF_STACK); +- BUILD_BUG_ON(BPF_REG_FP + 1 != MAX_BPF_REG); ++ BUILD_BUG_ON(BPF_REG_FP + 2 != MAX_BPF_REG); + + if (len <= 0 || len > BPF_MAXINSNS) + return -EINVAL; +@@ -9699,25 +9699,41 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type, + break; + + case offsetof(struct __sk_buff, data): ++ #ifdef CONFIG_HIVE ++ *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, sfi_data), ++ si->dst_reg, si->src_reg, ++ offsetof(struct sk_buff, sfi_data)); ++ #else + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, data), + si->dst_reg, si->src_reg, + offsetof(struct sk_buff, data)); ++ #endif + break; + + case offsetof(struct __sk_buff, data_meta): + off = si->off; + off -= offsetof(struct __sk_buff, data_meta); ++ #ifdef CONFIG_HIVE ++ off += offsetof(struct sk_buff, sfi_data_meta); ++ *insn++ = BPF_LDX_MEM(BPF_SIZEOF(void *), si->dst_reg, ++ si->src_reg, off); ++ #else + off += offsetof(struct sk_buff, cb); + off += offsetof(struct bpf_skb_data_end, data_meta); + *insn++ = BPF_LDX_MEM(BPF_SIZEOF(void *), si->dst_reg, + si->src_reg, off); ++ #endif + break; + + case offsetof(struct __sk_buff, data_end): + off = si->off; + off -= offsetof(struct __sk_buff, data_end); ++ #ifdef CONFIG_HIVE ++ off += offsetof(struct sk_buff, sfi_data_end); ++ #else + off += offsetof(struct sk_buff, cb); + off += offsetof(struct bpf_skb_data_end, data_end); ++ #endif + *insn++ = BPF_LDX_MEM(BPF_SIZEOF(void *), si->dst_reg, + si->src_reg, off); + break; diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c index c42ddd85ff1f..8450eb924b62 100644 --- a/net/dns_resolver/dns_key.c @@ -17766,7 +30595,7 @@ index 33e8302a79e3..c4b755733ed2 100644 ENCODE(toksize); oldxdr = xdr; diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c -index ad6c57a9f27c..b70b43f7c893 100644 +index ad6c57a9f27c..3161cbf4a958 100644 --- a/net/rxrpc/rxkad.c +++ b/net/rxrpc/rxkad.c @@ -21,6 +21,10 @@ @@ -17780,16 +30609,15 @@ index ad6c57a9f27c..b70b43f7c893 100644 #define RXKAD_VERSION 2 #define MAXKRB5TICKETLEN 1024 #define RXKAD_TKT_TYPE_KERBEROS_V5 256 -@@ -88,10 +92,19 @@ static void rxkad_free_preparse_server_key(struct key_preparsed_payload *prep) +@@ -88,10 +92,18 @@ static void rxkad_free_preparse_server_key(struct key_preparsed_payload *prep) static void rxkad_destroy_server_key(struct key *key) { + #ifdef CONFIG_KEYP + if (((union key_payload *)(key->name_link.next))->data[0]) { + crypto_free_skcipher(((union key_payload *)(key->name_link.next))->data[0]); -+ union key_payload key_payload = *((union key_payload *)(key->name_link.next)); -+ key_payload.data[0] = NULL; -+ iee_write_key_payload(key, key_payload); ++ union key_payload *key_payload = ((union key_payload *)(key->name_link.next)); ++ key_payload->data[0] = NULL; + } + #else if (key->payload.data[0]) { @@ -17800,7 +30628,7 @@ index ad6c57a9f27c..b70b43f7c893 100644 } /* -@@ -205,7 +218,11 @@ static int rxkad_prime_packet_security(struct rxrpc_connection *conn, +@@ -205,7 +217,11 @@ static int rxkad_prime_packet_security(struct rxrpc_connection *conn, return -ENOMEM; } @@ -17812,7 +30640,7 @@ index ad6c57a9f27c..b70b43f7c893 100644 memcpy(&iv, token->kad->session_key, sizeof(iv)); tmpbuf[0] = htonl(conn->proto.epoch); -@@ -317,7 +334,11 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call, +@@ -317,7 +333,11 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call, } /* encrypt from the session key */ @@ -17824,7 +30652,7 @@ index ad6c57a9f27c..b70b43f7c893 100644 memcpy(&iv, token->kad->session_key, sizeof(iv)); sg_init_one(&sg, txb->data, txb->len); -@@ -507,7 +528,11 @@ static int rxkad_verify_packet_2(struct rxrpc_call *call, struct sk_buff *skb, +@@ -507,7 +527,11 @@ static int rxkad_verify_packet_2(struct rxrpc_call *call, struct sk_buff *skb, } /* decrypt from the session key */ @@ -17836,7 +30664,7 @@ index ad6c57a9f27c..b70b43f7c893 100644 memcpy(&iv, token->kad->session_key, sizeof(iv)); skcipher_request_set_sync_tfm(req, call->conn->rxkad.cipher); -@@ -824,7 +849,11 @@ static int rxkad_respond_to_challenge(struct rxrpc_connection *conn, +@@ -824,7 +848,11 @@ static int rxkad_respond_to_challenge(struct rxrpc_connection *conn, return rxrpc_abort_conn(conn, skb, RXKADLEVELFAIL, -EACCES, rxkad_abort_chall_level); @@ -17848,7 +30676,7 @@ index ad6c57a9f27c..b70b43f7c893 100644 /* build the response packet */ resp = kzalloc(sizeof(struct rxkad_response), GFP_NOFS); -@@ -876,12 +905,24 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn, +@@ -876,12 +904,24 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn, *_expiry = 0; @@ -17902,7 +30730,7 @@ index cb8dd1d3b1d4..6bffe9965040 100644 goto found; } diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c -index 8e0b94714e84..5cdd058d729c 100644 +index 24f765d243db..4369ed7bf34b 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c @@ -585,7 +585,11 @@ rxrpc_new_client_call_for_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, @@ -17945,6 +30773,120 @@ index e51940589ee5..1ea7e51b71f0 100644 seq_puts(m, key->description); if (sec && sec->describe_server_key) +diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c +index 382c7a71f81f..9416a3c0ac66 100644 +--- a/net/sched/cls_bpf.c ++++ b/net/sched/cls_bpf.c +@@ -16,6 +16,10 @@ + #include + #include + ++#ifdef CONFIG_HIVE ++#include ++#endif ++ + #include + #include + #include +@@ -29,6 +33,10 @@ MODULE_DESCRIPTION("TC BPF based classifier"); + #define CLS_BPF_SUPPORTED_GEN_FLAGS \ + (TCA_CLS_FLAGS_SKIP_HW | TCA_CLS_FLAGS_SKIP_SW) + ++#ifdef CONFIG_HIVE ++extern pte_t *bpf_sfi_get_ptep(u64 addr); ++#endif ++ + struct cls_bpf_head { + struct list_head plist; + struct idr handle_idr; +@@ -78,6 +86,70 @@ static int cls_bpf_exec_opcode(int code) + } + } + ++#ifdef CONFIG_HIVE ++static inline void bpf_sfi_map_skb(struct bpf_prog *prog, struct sk_buff *skb) ++{ ++ u32 skb_data_offset, skb_meta_offset, skb_end_offset, reserved_skb_data_size; ++ u64 addr_to_map, map_length, map_page_cnt; ++ u64 start_time, end_time; ++ pte_t pte; ++ struct bpf_skb_data_end *cb; ++ ++ // skb_data_size = (u64)((struct bpf_skb_data_end *)skb->cb)->data_end - (u64)skb->head; ++ // skb_page_cnt = PAGE_ALIGN(skb_data_size) >> PAGE_SHIFT; ++ // pr_err("skb page cnt = %d\n", skb_page_cnt); ++ ++#ifdef CONFIG_ARM64 ++ isb(); ++#elif CONFIG_X86_64 ++ asm volatile("mfence":::"memory"); ++#endif ++ start_time = sched_clock(); ++ ++ // 1. get skb data size ++ cb = (struct bpf_skb_data_end *)skb->cb; ++ skb_data_offset = (u64)skb->data & ~PAGE_MASK; ++ skb_meta_offset = cb->data_meta - (void *)skb->data; ++ skb_end_offset = cb->data_end - (void *)skb->sfi_data_end; ++ map_length = skb->len; ++ // 2. ensure bpf_sfi reserved size is enough ++ reserved_skb_data_size = prog->shadow_skb_page_cnt * PAGE_SIZE; ++ BUG_ON(unlikely(reserved_skb_data_size < map_length)); ++ // 3. double map ++ map_page_cnt = PAGE_ALIGN(map_length) >> PAGE_SHIFT; ++ addr_to_map = (u64)prog->shadow_skb_addr; ++ // printk("skb %llx, %d page, map to %llx\n", (u64)skb->data, skb_page_cnt, addr_to_map); ++ for (int i = 0; i < map_page_cnt; i++) { ++ pte_t *origin_ptep = bpf_sfi_get_ptep((u64)skb->data + i * PAGE_SIZE); ++ if (unlikely(IS_ERR(origin_ptep))) { ++ pr_err("map pkt %llx failed\n", (u64)skb->data + i * PAGE_SIZE); ++ return; ++ } ++ pte_t *sfi_ptep = bpf_sfi_get_ptep(addr_to_map + i * PAGE_SIZE); ++ if (unlikely(IS_ERR(sfi_ptep))) { ++ pr_err("map pkt %llx failed\n", addr_to_map + i * PAGE_SIZE); ++ return; ++ } ++ pte = __pte(pte_val(*origin_ptep)); ++ set_pte(sfi_ptep, pte); ++ } ++ flush_tlb_kernel_range(addr_to_map, addr_to_map + map_page_cnt * PAGE_SIZE); ++ // skb->sfi_bpf_mapped = true; ++ skb->sfi_data = (void *)addr_to_map + skb_data_offset; ++ skb->sfi_data_meta = skb->sfi_data + skb_meta_offset; ++ skb->sfi_data_end = skb->sfi_data + skb_end_offset; ++ ++#ifdef CONFIG_ARM64 ++ isb(); ++#elif CONFIG_X86_64 ++ asm volatile("mfence":::"memory"); ++#endif ++ end_time = sched_clock(); ++ // pr_err("shadow packet region: %llx, %llx", addr_to_map, addr_to_map + map_page_cnt * PAGE_SIZE); ++ pr_err("shadow packet time = %lldns", end_time - start_time); ++} ++#endif ++ + TC_INDIRECT_SCOPE int cls_bpf_classify(struct sk_buff *skb, + const struct tcf_proto *tp, + struct tcf_result *res) +@@ -98,10 +170,16 @@ TC_INDIRECT_SCOPE int cls_bpf_classify(struct sk_buff *skb, + /* It is safe to push/pull even if skb_shared() */ + __skb_push(skb, skb->mac_len); + bpf_compute_data_pointers(skb); ++ #ifdef CONFIG_HIVE ++ bpf_sfi_map_skb(prog->filter, skb); ++ #endif + filter_res = bpf_prog_run(prog->filter, skb); + __skb_pull(skb, skb->mac_len); + } else { + bpf_compute_data_pointers(skb); ++ #ifdef CONFIG_HIVE ++ bpf_sfi_map_skb(prog->filter, skb); ++ #endif + filter_res = bpf_prog_run(prog->filter, skb); + } + if (unlikely(!skb->tstamp && skb->mono_delivery_time)) diff --git a/security/commoncap.c b/security/commoncap.c index bc0521104197..d7d3b7cc13e8 100644 --- a/security/commoncap.c @@ -18511,7 +31453,7 @@ index e6d22ce77e98..13803e0f1a8f 100644 *master_keylen = tpayload->key_len; error: diff --git a/security/keys/gc.c b/security/keys/gc.c -index eaddaceda14e..d1a8e1e6bf22 100644 +index eaddaceda14e..4038e7b95395 100644 --- a/security/keys/gc.c +++ b/security/keys/gc.c @@ -10,6 +10,11 @@ @@ -18519,8 +31461,8 @@ index eaddaceda14e..d1a8e1e6bf22 100644 #include "internal.h" +#ifdef CONFIG_KEYP ++#include +#include -+extern void iee_memset(void *ptr, int data, size_t n); +#endif + /* @@ -18666,7 +31608,7 @@ index ec2ec335b613..00d76f89179c 100644 extern void key_type_put(struct key_type *ktype); diff --git a/security/keys/key.c b/security/keys/key.c -index 35db23d05302..831c21329488 100644 +index 35db23d05302..92b8840bed69 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -17,7 +17,18 @@ @@ -18674,9 +31616,9 @@ index 35db23d05302..831c21329488 100644 #include "internal.h" +#ifdef CONFIG_KEYP ++#include +#include +#include -+extern void iee_memset(void *ptr, int data, size_t n); +#endif + struct kmem_cache *key_jar; @@ -18731,9 +31673,16 @@ index 35db23d05302..831c21329488 100644 spin_unlock(&key_serial_lock); return; -@@ -175,7 +202,11 @@ static inline void key_alloc_serial(struct key *key) +@@ -173,9 +200,18 @@ static inline void key_alloc_serial(struct key *key) + * that point looking for the next unused serial number */ + serial_exists: for (;;) { ++ #ifdef CONFIG_KEYP ++ key_serial_t tmp = key->serial + 1; ++ iee_set_key_serial(key, tmp); ++ #else key->serial++; ++ #endif if (key->serial < 3) { + #ifdef CONFIG_KEYP + iee_set_key_serial(key, 3); @@ -18743,7 +31692,7 @@ index 35db23d05302..831c21329488 100644 goto attempt_insertion; } -@@ -183,7 +214,11 @@ static inline void key_alloc_serial(struct key *key) +@@ -183,7 +219,11 @@ static inline void key_alloc_serial(struct key *key) if (!parent) goto attempt_insertion; @@ -18755,7 +31704,7 @@ index 35db23d05302..831c21329488 100644 if (key->serial < xkey->serial) goto attempt_insertion; } -@@ -231,6 +266,9 @@ struct key *key_alloc(struct key_type *type, const char *desc, +@@ -231,6 +271,9 @@ struct key *key_alloc(struct key_type *type, const char *desc, struct key *key; size_t desclen, quotalen; int ret; @@ -18765,7 +31714,7 @@ index 35db23d05302..831c21329488 100644 key = ERR_PTR(-EINVAL); if (!desc || !*desc) -@@ -274,17 +312,72 @@ struct key *key_alloc(struct key_type *type, const char *desc, +@@ -274,17 +317,72 @@ struct key *key_alloc(struct key_type *type, const char *desc, } /* allocate and initialise the key and its description */ @@ -18791,7 +31740,7 @@ index 35db23d05302..831c21329488 100644 + struct keyring_index_key tmp = key->index_key; + tmp.desc_len = desclen; + tmp.description = kmemdup(desc, desclen + 1, GFP_KERNEL); -+ iee_set_key_index_key(key, tmp); ++ iee_set_key_index_key(key, &tmp); + #else key->index_key.desc_len = desclen; key->index_key.description = kmemdup(desc, desclen + 1, GFP_KERNEL); @@ -18801,7 +31750,7 @@ index 35db23d05302..831c21329488 100644 + #ifdef CONFIG_KEYP + tmp = key->index_key; + tmp.type = type; -+ iee_set_key_index_key(key, tmp); ++ iee_set_key_index_key(key, &tmp); + iee_key_set_index_key(&key->index_key); + #else key->index_key.type = type; @@ -18839,7 +31788,7 @@ index 35db23d05302..831c21329488 100644 refcount_set(&key->usage, 1); init_rwsem(&key->sem); lockdep_set_class(&key->sem, &type->lock_class); -@@ -310,6 +403,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, +@@ -310,6 +408,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, #ifdef KEY_DEBUGGING key->magic = KEY_DEBUG_MAGIC; #endif @@ -18847,7 +31796,7 @@ index 35db23d05302..831c21329488 100644 /* let the security module know about the key */ ret = security_key_alloc(key, cred, flags); -@@ -326,6 +420,12 @@ struct key *key_alloc(struct key_type *type, const char *desc, +@@ -326,6 +425,12 @@ struct key *key_alloc(struct key_type *type, const char *desc, security_error: kfree(key->description); @@ -18860,7 +31809,7 @@ index 35db23d05302..831c21329488 100644 kmem_cache_free(key_jar, key); if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) { spin_lock(&user->lock); -@@ -338,6 +438,12 @@ struct key *key_alloc(struct key_type *type, const char *desc, +@@ -338,6 +443,12 @@ struct key *key_alloc(struct key_type *type, const char *desc, goto error; no_memory_3: @@ -18873,7 +31822,7 @@ index 35db23d05302..831c21329488 100644 kmem_cache_free(key_jar, key); no_memory_2: if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) { -@@ -391,14 +497,22 @@ int key_payload_reserve(struct key *key, size_t datalen) +@@ -391,14 +502,22 @@ int key_payload_reserve(struct key *key, size_t datalen) } else { key->user->qnbytes += delta; @@ -18896,7 +31845,7 @@ index 35db23d05302..831c21329488 100644 return ret; } -@@ -412,8 +526,14 @@ static void mark_key_instantiated(struct key *key, int reject_error) +@@ -412,8 +531,14 @@ static void mark_key_instantiated(struct key *key, int reject_error) /* Commit the payload before setting the state; barrier versus * key_read_state(). */ @@ -18911,7 +31860,7 @@ index 35db23d05302..831c21329488 100644 } /* -@@ -449,13 +569,22 @@ static int __key_instantiate_and_link(struct key *key, +@@ -449,13 +574,22 @@ static int __key_instantiate_and_link(struct key *key, mark_key_instantiated(key, 0); notify_key(key, NOTIFY_KEY_INSTANTIATED, 0); @@ -18934,7 +31883,7 @@ index 35db23d05302..831c21329488 100644 __key_link(keyring, key, _edit); } -@@ -464,8 +593,14 @@ static int __key_instantiate_and_link(struct key *key, +@@ -464,8 +598,14 @@ static int __key_instantiate_and_link(struct key *key, if (authkey) key_invalidate(authkey); @@ -18950,7 +31899,7 @@ index 35db23d05302..831c21329488 100644 } } -@@ -605,10 +740,20 @@ int key_reject_and_link(struct key *key, +@@ -605,10 +745,20 @@ int key_reject_and_link(struct key *key, atomic_inc(&key->user->nikeys); mark_key_instantiated(key, -error); notify_key(key, NOTIFY_KEY_INSTANTIATED, -error); @@ -18971,7 +31920,7 @@ index 35db23d05302..831c21329488 100644 ret = 0; -@@ -647,8 +792,13 @@ void key_put(struct key *key) +@@ -647,8 +797,13 @@ void key_put(struct key *key) if (key) { key_check(key); @@ -18985,7 +31934,7 @@ index 35db23d05302..831c21329488 100644 } } EXPORT_SYMBOL(key_put); -@@ -666,7 +816,11 @@ struct key *key_lookup(key_serial_t id) +@@ -666,7 +821,11 @@ struct key *key_lookup(key_serial_t id) /* search the tree for the specified key */ n = key_serial_tree.rb_node; while (n) { @@ -18997,7 +31946,7 @@ index 35db23d05302..831c21329488 100644 if (id < key->serial) n = n->rb_left; -@@ -684,8 +838,13 @@ struct key *key_lookup(key_serial_t id) +@@ -684,8 +843,13 @@ struct key *key_lookup(key_serial_t id) /* A key is allowed to be looked up only if someone still owns a * reference to it - otherwise it's awaiting the gc. */ @@ -19011,7 +31960,7 @@ index 35db23d05302..831c21329488 100644 error: spin_unlock(&key_serial_lock); -@@ -723,13 +882,27 @@ void key_set_timeout(struct key *key, unsigned timeout) +@@ -723,13 +887,27 @@ void key_set_timeout(struct key *key, unsigned timeout) time64_t expiry = TIME64_MAX; /* make the changes with the locks held to prevent races */ @@ -19039,7 +31988,7 @@ index 35db23d05302..831c21329488 100644 } EXPORT_SYMBOL_GPL(key_set_timeout); -@@ -762,7 +935,11 @@ static inline key_ref_t __key_update(key_ref_t key_ref, +@@ -762,7 +940,11 @@ static inline key_ref_t __key_update(key_ref_t key_ref, if (!key->type->update) goto error; @@ -19051,7 +32000,7 @@ index 35db23d05302..831c21329488 100644 ret = key->type->update(key, prep); if (ret == 0) { -@@ -771,7 +948,11 @@ static inline key_ref_t __key_update(key_ref_t key_ref, +@@ -771,7 +953,11 @@ static inline key_ref_t __key_update(key_ref_t key_ref, notify_key(key, NOTIFY_KEY_UPDATED, 0); } @@ -19063,7 +32012,7 @@ index 35db23d05302..831c21329488 100644 if (ret < 0) goto error; -@@ -1087,7 +1268,11 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) +@@ -1087,7 +1273,11 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) goto error; } @@ -19075,7 +32024,7 @@ index 35db23d05302..831c21329488 100644 ret = key->type->update(key, &prep); if (ret == 0) { -@@ -1096,7 +1281,11 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) +@@ -1096,7 +1286,11 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) notify_key(key, NOTIFY_KEY_UPDATED, 0); } @@ -19087,7 +32036,7 @@ index 35db23d05302..831c21329488 100644 error: if (key->type->preparse) -@@ -1125,6 +1314,23 @@ void key_revoke(struct key *key) +@@ -1125,6 +1319,23 @@ void key_revoke(struct key *key) * authorisation key whilst holding the sem on a key we've just * instantiated */ @@ -19111,7 +32060,7 @@ index 35db23d05302..831c21329488 100644 down_write_nested(&key->sem, 1); if (!test_and_set_bit(KEY_FLAG_REVOKED, &key->flags)) { notify_key(key, NOTIFY_KEY_REVOKED, 0); -@@ -1140,6 +1346,7 @@ void key_revoke(struct key *key) +@@ -1140,6 +1351,7 @@ void key_revoke(struct key *key) } up_write(&key->sem); @@ -19119,7 +32068,7 @@ index 35db23d05302..831c21329488 100644 } EXPORT_SYMBOL(key_revoke); -@@ -1157,12 +1364,21 @@ void key_invalidate(struct key *key) +@@ -1157,12 +1369,21 @@ void key_invalidate(struct key *key) key_check(key); if (!test_bit(KEY_FLAG_INVALIDATED, &key->flags)) { @@ -19141,16 +32090,15 @@ index 35db23d05302..831c21329488 100644 } } EXPORT_SYMBOL(key_invalidate); -@@ -1186,9 +1402,17 @@ int generic_key_instantiate(struct key *key, struct key_preparsed_payload *prep) +@@ -1186,9 +1407,16 @@ int generic_key_instantiate(struct key *key, struct key_preparsed_payload *prep) ret = key_payload_reserve(key, prep->quotalen); if (ret == 0) { rcu_assign_keypointer(key, prep->payload.data[0]); + #ifdef CONFIG_KEYP -+ union key_payload key_payload = *((union key_payload *)(key->name_link.next)); -+ key_payload.data[1] = prep->payload.data[1]; -+ key_payload.data[2] = prep->payload.data[2]; -+ key_payload.data[3] = prep->payload.data[3]; -+ iee_write_key_payload(key, key_payload); ++ union key_payload *key_payload = ((union key_payload *)(key->name_link.next)); ++ key_payload->data[1] = prep->payload.data[1]; ++ key_payload->data[2] = prep->payload.data[2]; ++ key_payload->data[3] = prep->payload.data[3]; + #else key->payload.data[1] = prep->payload.data[1]; key->payload.data[2] = prep->payload.data[2]; @@ -19159,7 +32107,7 @@ index 35db23d05302..831c21329488 100644 prep->payload.data[0] = NULL; prep->payload.data[1] = NULL; prep->payload.data[2] = NULL; -@@ -1262,6 +1486,11 @@ void __init key_init(void) +@@ -1262,6 +1490,11 @@ void __init key_init(void) /* allocate a slab in which we can store keys */ key_jar = kmem_cache_create("key_jar", sizeof(struct key), 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); @@ -19407,7 +32355,7 @@ index aa1dc43b16dd..e92df31642d5 100644 } diff --git a/security/keys/keyring.c b/security/keys/keyring.c -index f331725d5a37..1da67fd7e4f1 100644 +index f331725d5a37..b8bb07a55130 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -21,6 +21,11 @@ @@ -19416,7 +32364,7 @@ index f331725d5a37..1da67fd7e4f1 100644 +#ifdef CONFIG_KEYP +#include -+extern void iee_memcpy(void *dst, void *src, size_t n); ++#include +#endif + /* @@ -19446,7 +32394,7 @@ index f331725d5a37..1da67fd7e4f1 100644 /* make the keyring available by name if it has one */ keyring_publish_name(keyring); return 0; -@@ -207,6 +220,57 @@ static void hash_key_type_and_desc(struct keyring_index_key *index_key) +@@ -207,13 +220,70 @@ static void hash_key_type_and_desc(struct keyring_index_key *index_key) index_key->hash = hash; } @@ -19497,21 +32445,33 @@ index f331725d5a37..1da67fd7e4f1 100644 + hash = (hash + (hash << level_shift)) & ~fan_mask; + struct keyring_index_key tmp = *index_key; + tmp.hash = hash; -+ iee_set_key_index_key(container_of(index_key, struct key, index_key), tmp); ++ iee_set_key_index_key(container_of(index_key, struct key, index_key), &tmp); +} +#endif ++ ++#ifdef CONFIG_KEYP ++static struct key_tag default_domain_tag = { .usage = REFCOUNT_INIT(1), }; ++#endif + /* * Finalise an index key to include a part of the description actually in the * index key, to set the domain tag and to calculate the hash. -@@ -228,6 +292,34 @@ void key_set_index_key(struct keyring_index_key *index_key) + */ + void key_set_index_key(struct keyring_index_key *index_key) + { ++ #ifndef CONFIG_KEYP + static struct key_tag default_domain_tag = { .usage = REFCOUNT_INIT(1), }; ++ #endif + size_t n = min_t(size_t, index_key->desc_len, sizeof(index_key->desc)); + + memcpy(index_key->desc, index_key->description, n); +@@ -228,6 +298,33 @@ void key_set_index_key(struct keyring_index_key *index_key) hash_key_type_and_desc(index_key); } +#ifdef CONFIG_KEYP +void iee_key_set_index_key(struct keyring_index_key *index_key) +{ -+ static struct key_tag default_domain_tag = { .usage = REFCOUNT_INIT(1), }; + size_t n = min_t(size_t, index_key->desc_len, sizeof(index_key->desc)); + struct keyring_index_key tmp; + @@ -19522,13 +32482,13 @@ index f331725d5a37..1da67fd7e4f1 100644 + { + tmp = *index_key; + tmp.domain_tag = current->nsproxy->net_ns->key_domain; -+ iee_set_key_index_key(container_of(index_key, struct key, index_key), tmp); ++ iee_set_key_index_key(container_of(index_key, struct key, index_key), &tmp); + } + else + { + tmp = *index_key; + tmp.domain_tag = &default_domain_tag; -+ iee_set_key_index_key(container_of(index_key, struct key, index_key), tmp); ++ iee_set_key_index_key(container_of(index_key, struct key, index_key), &tmp); + } + } + @@ -19539,7 +32499,7 @@ index f331725d5a37..1da67fd7e4f1 100644 /** * key_put_tag - Release a ref on a tag. * @tag: The tag to release. -@@ -414,9 +506,15 @@ static void keyring_destroy(struct key *keyring) +@@ -414,9 +511,15 @@ static void keyring_destroy(struct key *keyring) if (keyring->description) { write_lock(&keyring_name_lock); @@ -19555,7 +32515,7 @@ index f331725d5a37..1da67fd7e4f1 100644 write_unlock(&keyring_name_lock); } -@@ -428,7 +526,11 @@ static void keyring_destroy(struct key *keyring) +@@ -428,7 +531,11 @@ static void keyring_destroy(struct key *keyring) kfree(keyres); } @@ -19567,7 +32527,7 @@ index f331725d5a37..1da67fd7e4f1 100644 } /* -@@ -442,8 +544,13 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m) +@@ -442,8 +549,13 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m) seq_puts(m, "[anon]"); if (key_is_positive(keyring)) { @@ -19581,7 +32541,7 @@ index f331725d5a37..1da67fd7e4f1 100644 else seq_puts(m, ": empty"); } -@@ -494,8 +601,13 @@ static long keyring_read(const struct key *keyring, +@@ -494,8 +606,13 @@ static long keyring_read(const struct key *keyring, ctx.buffer = (key_serial_t *)buffer; ctx.buflen = buflen; ctx.count = 0; @@ -19595,7 +32555,7 @@ index f331725d5a37..1da67fd7e4f1 100644 if (ret < 0) { kleave(" = %ld [iterate]", ret); return ret; -@@ -503,7 +615,11 @@ static long keyring_read(const struct key *keyring, +@@ -503,7 +620,11 @@ static long keyring_read(const struct key *keyring, } /* Return the size of the buffer needed */ @@ -19607,7 +32567,7 @@ index f331725d5a37..1da67fd7e4f1 100644 if (ret <= buflen) kleave("= %ld [ok]", ret); else -@@ -648,12 +764,22 @@ static int search_keyring(struct key *keyring, struct keyring_search_context *ct +@@ -648,12 +769,22 @@ static int search_keyring(struct key *keyring, struct keyring_search_context *ct if (ctx->match_data.lookup_type == KEYRING_SEARCH_LOOKUP_DIRECT) { const void *object; @@ -19630,7 +32590,7 @@ index f331725d5a37..1da67fd7e4f1 100644 } /* -@@ -729,7 +855,11 @@ static bool search_nested_keyrings(struct key *keyring, +@@ -729,7 +860,11 @@ static bool search_nested_keyrings(struct key *keyring, if (!(ctx->flags & KEYRING_SEARCH_RECURSE)) goto not_this_keyring; @@ -19642,7 +32602,7 @@ index f331725d5a37..1da67fd7e4f1 100644 if (!ptr) goto not_this_keyring; -@@ -856,10 +986,17 @@ static bool search_nested_keyrings(struct key *keyring, +@@ -856,10 +991,17 @@ static bool search_nested_keyrings(struct key *keyring, key = key_ref_to_ptr(ctx->result); key_check(key); if (!(ctx->flags & KEYRING_SEARCH_NO_UPDATE_TIME)) { @@ -19660,7 +32620,7 @@ index f331725d5a37..1da67fd7e4f1 100644 } kleave(" = true"); return true; -@@ -1056,7 +1193,11 @@ int keyring_restrict(key_ref_t keyring_ref, const char *type, +@@ -1056,7 +1198,11 @@ int keyring_restrict(key_ref_t keyring_ref, const char *type, goto error; } @@ -19672,7 +32632,7 @@ index f331725d5a37..1da67fd7e4f1 100644 down_write(&keyring_serialise_restrict_sem); if (keyring->restrict_link) { -@@ -1064,12 +1205,20 @@ int keyring_restrict(key_ref_t keyring_ref, const char *type, +@@ -1064,12 +1210,20 @@ int keyring_restrict(key_ref_t keyring_ref, const char *type, } else if (keyring_detect_restriction_cycle(keyring, restrict_link)) { ret = -EDEADLK; } else { @@ -19693,7 +32653,7 @@ index f331725d5a37..1da67fd7e4f1 100644 if (ret < 0) { key_put(restrict_link->key); -@@ -1109,8 +1258,13 @@ key_ref_t find_key_to_update(key_ref_t keyring_ref, +@@ -1109,8 +1263,13 @@ key_ref_t find_key_to_update(key_ref_t keyring_ref, kenter("{%d},{%s,%s}", keyring->serial, index_key->type->name, index_key->description); @@ -19707,7 +32667,7 @@ index f331725d5a37..1da67fd7e4f1 100644 if (object) goto found; -@@ -1154,7 +1308,13 @@ struct key *find_keyring_by_name(const char *name, bool uid_keyring) +@@ -1154,7 +1313,13 @@ struct key *find_keyring_by_name(const char *name, bool uid_keyring) /* Search this hash bucket for a keyring with a matching name that * grants Search permission and that hasn't been revoked */ @@ -19721,7 +32681,7 @@ index f331725d5a37..1da67fd7e4f1 100644 if (!kuid_has_mapping(ns, keyring->user->uid)) continue; -@@ -1177,9 +1337,15 @@ struct key *find_keyring_by_name(const char *name, bool uid_keyring) +@@ -1177,9 +1342,15 @@ struct key *find_keyring_by_name(const char *name, bool uid_keyring) /* we've got a match but we might end up racing with * key_cleanup() if the keyring is currently 'dead' * (ie. it has a zero usage count) */ @@ -19737,7 +32697,7 @@ index f331725d5a37..1da67fd7e4f1 100644 goto out; } -@@ -1238,13 +1404,21 @@ static int keyring_detect_cycle(struct key *A, struct key *B) +@@ -1238,13 +1409,21 @@ static int keyring_detect_cycle(struct key *A, struct key *B) */ int __key_link_lock(struct key *keyring, const struct keyring_index_key *index_key) @@ -19759,7 +32719,7 @@ index f331725d5a37..1da67fd7e4f1 100644 /* Serialise link/link calls to prevent parallel calls causing a cycle * when linking two keyring in opposite orders. -@@ -1260,8 +1434,13 @@ int __key_link_lock(struct key *keyring, +@@ -1260,8 +1439,13 @@ int __key_link_lock(struct key *keyring, */ int __key_move_lock(struct key *l_keyring, struct key *u_keyring, const struct keyring_index_key *index_key) @@ -19773,7 +32733,7 @@ index f331725d5a37..1da67fd7e4f1 100644 __acquires(&keyring_serialise_link_lock) { if (l_keyring->type != &key_type_keyring || -@@ -1273,11 +1452,21 @@ int __key_move_lock(struct key *l_keyring, struct key *u_keyring, +@@ -1273,11 +1457,21 @@ int __key_move_lock(struct key *l_keyring, struct key *u_keyring, * move operation. */ if (l_keyring < u_keyring) { @@ -19795,7 +32755,7 @@ index f331725d5a37..1da67fd7e4f1 100644 } /* Serialise link/link calls to prevent parallel calls causing a cycle -@@ -1314,10 +1503,17 @@ int __key_link_begin(struct key *keyring, +@@ -1314,10 +1508,17 @@ int __key_link_begin(struct key *keyring, /* Create an edit script that will insert/replace the key in the * keyring tree. */ @@ -19813,7 +32773,7 @@ index f331725d5a37..1da67fd7e4f1 100644 if (IS_ERR(edit)) { ret = PTR_ERR(edit); goto error; -@@ -1385,7 +1581,11 @@ void __key_link(struct key *keyring, struct key *key, +@@ -1385,7 +1586,11 @@ void __key_link(struct key *keyring, struct key *key, void __key_link_end(struct key *keyring, const struct keyring_index_key *index_key, struct assoc_array_edit *edit) @@ -19825,7 +32785,7 @@ index f331725d5a37..1da67fd7e4f1 100644 __releases(&keyring_serialise_link_lock) { BUG_ON(index_key->type == NULL); -@@ -1398,7 +1598,11 @@ void __key_link_end(struct key *keyring, +@@ -1398,7 +1603,11 @@ void __key_link_end(struct key *keyring, } assoc_array_cancel_edit(edit); } @@ -19837,7 +32797,7 @@ index f331725d5a37..1da67fd7e4f1 100644 if (index_key->type == &key_type_keyring) mutex_unlock(&keyring_serialise_link_lock); -@@ -1411,8 +1615,13 @@ static int __key_link_check_restriction(struct key *keyring, struct key *key) +@@ -1411,8 +1620,13 @@ static int __key_link_check_restriction(struct key *keyring, struct key *key) { if (!keyring->restrict_link || !keyring->restrict_link->check) return 0; @@ -19851,7 +32811,7 @@ index f331725d5a37..1da67fd7e4f1 100644 } /** -@@ -1472,12 +1681,20 @@ EXPORT_SYMBOL(key_link); +@@ -1472,12 +1686,20 @@ EXPORT_SYMBOL(key_link); * Lock a keyring for unlink. */ static int __key_unlink_lock(struct key *keyring) @@ -19872,7 +32832,7 @@ index f331725d5a37..1da67fd7e4f1 100644 return 0; } -@@ -1491,8 +1708,13 @@ static int __key_unlink_begin(struct key *keyring, struct key *key, +@@ -1491,8 +1713,13 @@ static int __key_unlink_begin(struct key *keyring, struct key *key, BUG_ON(*_edit != NULL); @@ -19886,7 +32846,7 @@ index f331725d5a37..1da67fd7e4f1 100644 if (IS_ERR(edit)) return PTR_ERR(edit); -@@ -1521,11 +1743,19 @@ static void __key_unlink(struct key *keyring, struct key *key, +@@ -1521,11 +1748,19 @@ static void __key_unlink(struct key *keyring, struct key *key, static void __key_unlink_end(struct key *keyring, struct key *key, struct assoc_array_edit *edit) @@ -19906,7 +32866,7 @@ index f331725d5a37..1da67fd7e4f1 100644 } /** -@@ -1655,9 +1885,15 @@ int keyring_clear(struct key *keyring) +@@ -1655,9 +1890,15 @@ int keyring_clear(struct key *keyring) if (keyring->type != &key_type_keyring) return -ENOTDIR; @@ -19922,7 +32882,7 @@ index f331725d5a37..1da67fd7e4f1 100644 if (IS_ERR(edit)) { ret = PTR_ERR(edit); } else { -@@ -1668,7 +1904,11 @@ int keyring_clear(struct key *keyring) +@@ -1668,7 +1909,11 @@ int keyring_clear(struct key *keyring) ret = 0; } @@ -19934,7 +32894,7 @@ index f331725d5a37..1da67fd7e4f1 100644 return ret; } EXPORT_SYMBOL(keyring_clear); -@@ -1682,7 +1922,11 @@ static void keyring_revoke(struct key *keyring) +@@ -1682,7 +1927,11 @@ static void keyring_revoke(struct key *keyring) { struct assoc_array_edit *edit; @@ -19946,7 +32906,7 @@ index f331725d5a37..1da67fd7e4f1 100644 if (!IS_ERR(edit)) { if (edit) assoc_array_apply_edit(edit); -@@ -1728,8 +1972,13 @@ void keyring_gc(struct key *keyring, time64_t limit) +@@ -1728,8 +1977,13 @@ void keyring_gc(struct key *keyring, time64_t limit) /* scan the keyring looking for dead keys */ rcu_read_lock(); @@ -19960,7 +32920,7 @@ index f331725d5a37..1da67fd7e4f1 100644 rcu_read_unlock(); if (result == true) goto do_gc; -@@ -1739,10 +1988,17 @@ void keyring_gc(struct key *keyring, time64_t limit) +@@ -1739,10 +1993,17 @@ void keyring_gc(struct key *keyring, time64_t limit) return; do_gc: @@ -19978,7 +32938,7 @@ index f331725d5a37..1da67fd7e4f1 100644 kleave(" [gc]"); } -@@ -1781,7 +2037,11 @@ void keyring_restriction_gc(struct key *keyring, struct key_type *dead_type) +@@ -1781,7 +2042,11 @@ void keyring_restriction_gc(struct key *keyring, struct key_type *dead_type) } /* Lock the keyring to ensure that a link is not in progress */ @@ -19990,7 +32950,7 @@ index f331725d5a37..1da67fd7e4f1 100644 keyres = keyring->restrict_link; -@@ -1791,7 +2051,11 @@ void keyring_restriction_gc(struct key *keyring, struct key_type *dead_type) +@@ -1791,7 +2056,11 @@ void keyring_restriction_gc(struct key *keyring, struct key_type *dead_type) keyres->key = NULL; keyres->keytype = NULL; @@ -20414,19 +33374,21 @@ index fee1ab2c734d..5ef67deb1df0 100644 struct key_type key_type_trusted = { diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c -index 749e2a4dcb13..a0a5e9ca620f 100644 +index 749e2a4dcb13..1985cea69256 100644 --- a/security/keys/user_defined.c +++ b/security/keys/user_defined.c -@@ -14,6 +14,8 @@ +@@ -14,6 +14,10 @@ #include #include "internal.h" ++#ifdef CONFIG_KEYP +#include ++#endif + static int logon_vet_description(const char *desc); /* -@@ -109,7 +111,11 @@ int user_update(struct key *key, struct key_preparsed_payload *prep) +@@ -109,7 +113,11 @@ int user_update(struct key *key, struct key_preparsed_payload *prep) return ret; /* attach the new data, displacing the old */ @@ -20438,7 +33400,7 @@ index 749e2a4dcb13..a0a5e9ca620f 100644 if (key_is_positive(key)) zap = dereference_key_locked(key); rcu_assign_keypointer(key, prep->payload.data[0]); -@@ -145,7 +151,11 @@ EXPORT_SYMBOL(user_revoke); +@@ -145,7 +153,11 @@ EXPORT_SYMBOL(user_revoke); */ void user_destroy(struct key *key) { @@ -20451,7 +33413,7 @@ index 749e2a4dcb13..a0a5e9ca620f 100644 kfree_sensitive(upayload); } diff --git a/security/security.c b/security/security.c -index b6144833c7a8..ca5d99847f77 100644 +index 839e12addac7..12320f9d4989 100644 --- a/security/security.c +++ b/security/security.c @@ -30,6 +30,9 @@ @@ -20484,7 +33446,7 @@ index b6144833c7a8..ca5d99847f77 100644 if (cred->security == NULL) return -ENOMEM; return 0; -@@ -2950,7 +2961,11 @@ void security_cred_free(struct cred *cred) +@@ -2965,7 +2976,11 @@ void security_cred_free(struct cred *cred) call_void_hook(cred_free, cred); kfree(cred->security); @@ -20497,7 +33459,7 @@ index b6144833c7a8..ca5d99847f77 100644 /** diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c -index d4a99d98ec77..70e5ca8c80df 100644 +index d4a99d98ec77..a08b94e13fd8 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -104,9 +104,22 @@ @@ -20590,7 +33552,7 @@ index d4a99d98ec77..70e5ca8c80df 100644 + selinux_state.policy_mutex.owner.counter = (s64)policy_mutex; + + /* Setting lm addr to be RO, IEE addr valid. */ -+ set_iee_page_valid(__phys_to_iee(__pa_symbol(&selinux_state))); ++ set_iee_page_valid((unsigned long)__phys_to_iee(__pa_symbol(&selinux_state))); + iee_set_logical_mem_ro((unsigned long)&selinux_state); + iee_set_logical_mem_ro((unsigned long)__va(__pa_symbol(&selinux_state))); + printk("IEE SELINUXP: Succeeded on preparing selinux_state."); @@ -20687,7 +33649,7 @@ index a9de89af8fdc..2eee89071a56 100644 static inline bool enforcing_enabled(void) { diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c -index 2c23a5a28608..f89b4fef4919 100644 +index 54bc18e8164b..137cdc6ea27c 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -43,6 +43,10 @@ @@ -20733,9 +33695,9 @@ index 2c23a5a28608..f89b4fef4919 100644 if (plm) vfree(plm->data); -@@ -587,7 +603,11 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, - ssize_t length; - void *data = NULL; +@@ -594,7 +610,11 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, + if (!count) + return -EINVAL; +#ifdef CONFIG_IEE_SELINUX_P + mutex_lock(iee_get_selinux_policy_lock()); @@ -20745,9 +33707,9 @@ index 2c23a5a28608..f89b4fef4919 100644 length = avc_has_perm(current_sid(), SECINITSID_SECURITY, SECCLASS_SECURITY, SECURITY__LOAD_POLICY, NULL); -@@ -630,13 +650,31 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, - from_kuid(&init_user_ns, audit_get_loginuid(current)), +@@ -632,13 +652,31 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, audit_get_sessionid(current)); + out: +#ifdef CONFIG_IEE_SELINUX_P + mutex_unlock(iee_get_selinux_policy_lock()); @@ -20777,7 +33739,7 @@ index 2c23a5a28608..f89b4fef4919 100644 .llseek = generic_file_llseek, }; -@@ -1214,7 +1252,11 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf, +@@ -1216,7 +1254,11 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf, unsigned index = file_inode(filep)->i_ino & SEL_INO_MASK; const char *name = filep->f_path.dentry->d_name.name; @@ -20789,7 +33751,7 @@ index 2c23a5a28608..f89b4fef4919 100644 ret = -EINVAL; if (index >= fsi->bool_num || strcmp(name, -@@ -1233,14 +1275,22 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf, +@@ -1235,14 +1277,22 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf, } length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing, fsi->bool_pending_values[index]); @@ -20812,7 +33774,7 @@ index 2c23a5a28608..f89b4fef4919 100644 goto out_free; } -@@ -1265,7 +1315,11 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf, +@@ -1267,7 +1317,11 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf, if (IS_ERR(page)) return PTR_ERR(page); @@ -20824,7 +33786,7 @@ index 2c23a5a28608..f89b4fef4919 100644 length = avc_has_perm(current_sid(), SECINITSID_SECURITY, SECCLASS_SECURITY, SECURITY__SETBOOL, -@@ -1289,7 +1343,11 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf, +@@ -1291,7 +1345,11 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf, length = count; out: @@ -20836,7 +33798,7 @@ index 2c23a5a28608..f89b4fef4919 100644 kfree(page); return length; } -@@ -1320,7 +1378,11 @@ static ssize_t sel_commit_bools_write(struct file *filep, +@@ -1322,7 +1380,11 @@ static ssize_t sel_commit_bools_write(struct file *filep, if (IS_ERR(page)) return PTR_ERR(page); @@ -20848,7 +33810,7 @@ index 2c23a5a28608..f89b4fef4919 100644 length = avc_has_perm(current_sid(), SECINITSID_SECURITY, SECCLASS_SECURITY, SECURITY__SETBOOL, -@@ -1341,7 +1403,11 @@ static ssize_t sel_commit_bools_write(struct file *filep, +@@ -1343,7 +1405,11 @@ static ssize_t sel_commit_bools_write(struct file *filep, length = count; out: @@ -21118,5 +34080,5 @@ index 4625674f0e95..cbd843db9d41 100644 /** -- -2.43.0 +2.34.1 diff --git a/haoc-kernel.spec b/haoc-kernel.spec index 48c9a65..d9c93aa 100644 --- a/haoc-kernel.spec +++ b/haoc-kernel.spec @@ -40,9 +40,9 @@ rm -f test_openEuler_sign.ko test_openEuler_sign.ko.sig %global upstream_version 6.6 %global upstream_sublevel 0 -%global devel_release 50 +%global devel_release 64 %global maintenance_release .0.0 -%global pkg_release .56 +%global pkg_release .57 %global openeuler_lts 1 %global openeuler_major 2403 @@ -1092,6 +1092,8 @@ fi %endif %changelog +* Thu Dec 12 2024 Liu Zhehui - 6.6.0-64.0.0.57 +- update haoc to 6.6.0-64.0.0 * Thu Nov 7 2024 Liu Zhehui - 6.6.0-50.0.0.56 - add some optimization, update haoc to 6.6.0-50.0.0 * Wed Nov 06 2024 ZhangPeng - 6.6.0-50.0.0.55 -- Gitee