From 490c80ae8b638d5edabd017144aaa0c7b105b6d6 Mon Sep 17 00:00:00 2001 From: Jia He Date: Thu, 14 Nov 2024 05:34:28 +0000 Subject: [PATCH 01/13] anolis: Revert "anolis: configs: refresh kconfigs" ANBZ: #11595 This reverts commit 1b7e94c4231c44f82686f9381b81c58d36bc597f. This conflicts the reorganization of arm64 LIVEPATCH support, hence revert it firstly and refresh kconfigs after reorganization. Signed-off-by: Jia He --- .../configs/L0-MANDATORY/{default => arm64}/CONFIG_PCI_PF_STUB | 0 anolis/configs/L0-MANDATORY/default/CONFIG_CPU_MITIGATIONS | 1 - anolis/configs/L0-MANDATORY/{default => x86}/CONFIG_LIVEPATCH | 0 anolis/configs/L0-MANDATORY/x86/CONFIG_PCI_PF_STUB | 1 + anolis/configs/L0-MANDATORY/x86/CONFIG_SPECULATION_MITIGATIONS | 1 + anolis/configs/L0-MANDATORY/{default => x86}/CONFIG_UNWINDER_ORC | 0 anolis/configs/L1-RECOMMEND/arm64/CONFIG_ARM64_CONTPTE | 1 - anolis/configs/L1-RECOMMEND/arm64/CONFIG_ARM64_ERRATUM_3194386 | 1 - .../configs/L1-RECOMMEND/{default => arm64}/CONFIG_GENERIC_PHY | 0 .../L1-RECOMMEND/arm64/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET | 1 + .../L1-RECOMMEND/{default => arm64}/CONFIG_HAVE_LIVEPATCH | 0 .../{default => arm64}/CONFIG_HAVE_RELIABLE_STACKTRACE | 0 .../L1-RECOMMEND/{default => arm64}/CONFIG_HAVE_STACK_VALIDATION | 0 anolis/configs/L1-RECOMMEND/arm64/CONFIG_LIVEPATCH | 1 + anolis/configs/L1-RECOMMEND/{default => arm64}/CONFIG_OBJTOOL | 0 anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET | 1 + .../{x86 => arm64}/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT | 0 .../arm64/CONFIG_UNWINDER_FRAME_POINTER | 0 anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_ORC | 1 + anolis/configs/L1-RECOMMEND/default/CONFIG_AHCI_ZHAOXIN_SGPIO | 1 - anolis/configs/L1-RECOMMEND/default/CONFIG_PCP_BATCH_SCALE_MAX | 1 - .../L1-RECOMMEND/{x86 => default}/CONFIG_RANDOMIZE_KSTACK_OFFSET | 0 .../L1-RECOMMEND/default/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT | 1 + anolis/configs/L1-RECOMMEND/x86/CONFIG_GENERIC_PHY | 1 + anolis/configs/L1-RECOMMEND/x86/CONFIG_MITIGATION_SPECTRE_BHI | 1 - .../configs/L1-RECOMMEND/{default => x86}/CONFIG_TEST_LIVEPATCH | 0 .../{default => arm64}/CONFIG_DRM_PANEL_ILITEK_ILI9341 | 0 anolis/configs/L2-OPTIONAL/arm64/CONFIG_TEST_LIVEPATCH | 1 + .../configs/L2-OPTIONAL/default/CONFIG_BCACHE_ASYNC_REGISTRATION | 1 - anolis/configs/L2-OPTIONAL/default/CONFIG_BCACHE_CLOSURES_DEBUG | 1 - anolis/configs/L2-OPTIONAL/default/CONFIG_BCACHE_DEBUG | 1 - anolis/configs/L2-OPTIONAL/default/CONFIG_CRYPTO_SIG | 1 - anolis/configs/L2-OPTIONAL/default/CONFIG_FB_IOMEM_FOPS | 1 - .../default}/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET | 0 anolis/configs/L2-OPTIONAL/default/CONFIG_PATA_HPT3X3_DMA | 1 - anolis/configs/L2-OPTIONAL/default/CONFIG_SCREEN_INFO | 1 - anolis/configs/L2-OPTIONAL/default/CONFIG_SCSI_MVSAS_DEBUG | 1 - anolis/configs/L2-OPTIONAL/default/CONFIG_SCSI_MVSAS_TASKLET | 1 - anolis/configs/L2-OPTIONAL/x86/CONFIG_AD9467 | 1 - anolis/configs/L2-OPTIONAL/x86/CONFIG_ADI_AXI_ADC | 1 - .../L2-OPTIONAL/x86/CONFIG_ARCH_CONFIGURES_CPU_MITIGATIONS | 1 - anolis/configs/L2-OPTIONAL/x86/CONFIG_HAVE_LIVEPATCH | 1 + anolis/configs/L2-OPTIONAL/x86/CONFIG_HAVE_RELIABLE_STACKTRACE | 1 + anolis/configs/L2-OPTIONAL/x86/CONFIG_HAVE_STACK_VALIDATION | 1 + anolis/configs/L2-OPTIONAL/x86/CONFIG_OBJTOOL | 1 + 45 files changed, 13 insertions(+), 18 deletions(-) rename anolis/configs/L0-MANDATORY/{default => arm64}/CONFIG_PCI_PF_STUB (100%) delete mode 100644 anolis/configs/L0-MANDATORY/default/CONFIG_CPU_MITIGATIONS rename anolis/configs/L0-MANDATORY/{default => x86}/CONFIG_LIVEPATCH (100%) create mode 100644 anolis/configs/L0-MANDATORY/x86/CONFIG_PCI_PF_STUB create mode 100644 anolis/configs/L0-MANDATORY/x86/CONFIG_SPECULATION_MITIGATIONS rename anolis/configs/L0-MANDATORY/{default => x86}/CONFIG_UNWINDER_ORC (100%) delete mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_ARM64_CONTPTE delete mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_ARM64_ERRATUM_3194386 rename anolis/configs/L1-RECOMMEND/{default => arm64}/CONFIG_GENERIC_PHY (100%) create mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET rename anolis/configs/L1-RECOMMEND/{default => arm64}/CONFIG_HAVE_LIVEPATCH (100%) rename anolis/configs/L1-RECOMMEND/{default => arm64}/CONFIG_HAVE_RELIABLE_STACKTRACE (100%) rename anolis/configs/L1-RECOMMEND/{default => arm64}/CONFIG_HAVE_STACK_VALIDATION (100%) create mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_LIVEPATCH rename anolis/configs/L1-RECOMMEND/{default => arm64}/CONFIG_OBJTOOL (100%) create mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET rename anolis/configs/L1-RECOMMEND/{x86 => arm64}/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT (100%) rename anolis/configs/{L0-MANDATORY => L1-RECOMMEND}/arm64/CONFIG_UNWINDER_FRAME_POINTER (100%) create mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_ORC delete mode 100644 anolis/configs/L1-RECOMMEND/default/CONFIG_AHCI_ZHAOXIN_SGPIO delete mode 100644 anolis/configs/L1-RECOMMEND/default/CONFIG_PCP_BATCH_SCALE_MAX rename anolis/configs/L1-RECOMMEND/{x86 => default}/CONFIG_RANDOMIZE_KSTACK_OFFSET (100%) create mode 100644 anolis/configs/L1-RECOMMEND/default/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT create mode 100644 anolis/configs/L1-RECOMMEND/x86/CONFIG_GENERIC_PHY delete mode 100644 anolis/configs/L1-RECOMMEND/x86/CONFIG_MITIGATION_SPECTRE_BHI rename anolis/configs/L1-RECOMMEND/{default => x86}/CONFIG_TEST_LIVEPATCH (100%) rename anolis/configs/L2-OPTIONAL/{default => arm64}/CONFIG_DRM_PANEL_ILITEK_ILI9341 (100%) create mode 100644 anolis/configs/L2-OPTIONAL/arm64/CONFIG_TEST_LIVEPATCH delete mode 100644 anolis/configs/L2-OPTIONAL/default/CONFIG_BCACHE_ASYNC_REGISTRATION delete mode 100644 anolis/configs/L2-OPTIONAL/default/CONFIG_BCACHE_CLOSURES_DEBUG delete mode 100644 anolis/configs/L2-OPTIONAL/default/CONFIG_BCACHE_DEBUG delete mode 100644 anolis/configs/L2-OPTIONAL/default/CONFIG_CRYPTO_SIG delete mode 100644 anolis/configs/L2-OPTIONAL/default/CONFIG_FB_IOMEM_FOPS rename anolis/configs/{L1-RECOMMEND/x86 => L2-OPTIONAL/default}/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET (100%) delete mode 100644 anolis/configs/L2-OPTIONAL/default/CONFIG_PATA_HPT3X3_DMA delete mode 100644 anolis/configs/L2-OPTIONAL/default/CONFIG_SCREEN_INFO delete mode 100644 anolis/configs/L2-OPTIONAL/default/CONFIG_SCSI_MVSAS_DEBUG delete mode 100644 anolis/configs/L2-OPTIONAL/default/CONFIG_SCSI_MVSAS_TASKLET delete mode 100644 anolis/configs/L2-OPTIONAL/x86/CONFIG_AD9467 delete mode 100644 anolis/configs/L2-OPTIONAL/x86/CONFIG_ADI_AXI_ADC delete mode 100644 anolis/configs/L2-OPTIONAL/x86/CONFIG_ARCH_CONFIGURES_CPU_MITIGATIONS create mode 100644 anolis/configs/L2-OPTIONAL/x86/CONFIG_HAVE_LIVEPATCH create mode 100644 anolis/configs/L2-OPTIONAL/x86/CONFIG_HAVE_RELIABLE_STACKTRACE create mode 100644 anolis/configs/L2-OPTIONAL/x86/CONFIG_HAVE_STACK_VALIDATION create mode 100644 anolis/configs/L2-OPTIONAL/x86/CONFIG_OBJTOOL diff --git a/anolis/configs/L0-MANDATORY/default/CONFIG_PCI_PF_STUB b/anolis/configs/L0-MANDATORY/arm64/CONFIG_PCI_PF_STUB similarity index 100% rename from anolis/configs/L0-MANDATORY/default/CONFIG_PCI_PF_STUB rename to anolis/configs/L0-MANDATORY/arm64/CONFIG_PCI_PF_STUB diff --git a/anolis/configs/L0-MANDATORY/default/CONFIG_CPU_MITIGATIONS b/anolis/configs/L0-MANDATORY/default/CONFIG_CPU_MITIGATIONS deleted file mode 100644 index 3d6f96778a81..000000000000 --- a/anolis/configs/L0-MANDATORY/default/CONFIG_CPU_MITIGATIONS +++ /dev/null @@ -1 +0,0 @@ -CONFIG_CPU_MITIGATIONS=y diff --git a/anolis/configs/L0-MANDATORY/default/CONFIG_LIVEPATCH b/anolis/configs/L0-MANDATORY/x86/CONFIG_LIVEPATCH similarity index 100% rename from anolis/configs/L0-MANDATORY/default/CONFIG_LIVEPATCH rename to anolis/configs/L0-MANDATORY/x86/CONFIG_LIVEPATCH diff --git a/anolis/configs/L0-MANDATORY/x86/CONFIG_PCI_PF_STUB b/anolis/configs/L0-MANDATORY/x86/CONFIG_PCI_PF_STUB new file mode 100644 index 000000000000..46eee76194b0 --- /dev/null +++ b/anolis/configs/L0-MANDATORY/x86/CONFIG_PCI_PF_STUB @@ -0,0 +1 @@ +CONFIG_PCI_PF_STUB=y diff --git a/anolis/configs/L0-MANDATORY/x86/CONFIG_SPECULATION_MITIGATIONS b/anolis/configs/L0-MANDATORY/x86/CONFIG_SPECULATION_MITIGATIONS new file mode 100644 index 000000000000..37f78a6f2368 --- /dev/null +++ b/anolis/configs/L0-MANDATORY/x86/CONFIG_SPECULATION_MITIGATIONS @@ -0,0 +1 @@ +CONFIG_SPECULATION_MITIGATIONS=y diff --git a/anolis/configs/L0-MANDATORY/default/CONFIG_UNWINDER_ORC b/anolis/configs/L0-MANDATORY/x86/CONFIG_UNWINDER_ORC similarity index 100% rename from anolis/configs/L0-MANDATORY/default/CONFIG_UNWINDER_ORC rename to anolis/configs/L0-MANDATORY/x86/CONFIG_UNWINDER_ORC diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_ARM64_CONTPTE b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_ARM64_CONTPTE deleted file mode 100644 index 23a09e20f027..000000000000 --- a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_ARM64_CONTPTE +++ /dev/null @@ -1 +0,0 @@ -CONFIG_ARM64_CONTPTE=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_ARM64_ERRATUM_3194386 b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_ARM64_ERRATUM_3194386 deleted file mode 100644 index f6f6f286638d..000000000000 --- a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_ARM64_ERRATUM_3194386 +++ /dev/null @@ -1 +0,0 @@ -CONFIG_ARM64_ERRATUM_3194386=y diff --git a/anolis/configs/L1-RECOMMEND/default/CONFIG_GENERIC_PHY b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_GENERIC_PHY similarity index 100% rename from anolis/configs/L1-RECOMMEND/default/CONFIG_GENERIC_PHY rename to anolis/configs/L1-RECOMMEND/arm64/CONFIG_GENERIC_PHY diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET new file mode 100644 index 000000000000..c7daa4f60d5d --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET @@ -0,0 +1 @@ +# CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET is not set diff --git a/anolis/configs/L1-RECOMMEND/default/CONFIG_HAVE_LIVEPATCH b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_LIVEPATCH similarity index 100% rename from anolis/configs/L1-RECOMMEND/default/CONFIG_HAVE_LIVEPATCH rename to anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_LIVEPATCH diff --git a/anolis/configs/L1-RECOMMEND/default/CONFIG_HAVE_RELIABLE_STACKTRACE b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_RELIABLE_STACKTRACE similarity index 100% rename from anolis/configs/L1-RECOMMEND/default/CONFIG_HAVE_RELIABLE_STACKTRACE rename to anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_RELIABLE_STACKTRACE diff --git a/anolis/configs/L1-RECOMMEND/default/CONFIG_HAVE_STACK_VALIDATION b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_STACK_VALIDATION similarity index 100% rename from anolis/configs/L1-RECOMMEND/default/CONFIG_HAVE_STACK_VALIDATION rename to anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_STACK_VALIDATION diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_LIVEPATCH b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_LIVEPATCH new file mode 100644 index 000000000000..1b05d0d1a109 --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_LIVEPATCH @@ -0,0 +1 @@ +CONFIG_LIVEPATCH=y diff --git a/anolis/configs/L1-RECOMMEND/default/CONFIG_OBJTOOL b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_OBJTOOL similarity index 100% rename from anolis/configs/L1-RECOMMEND/default/CONFIG_OBJTOOL rename to anolis/configs/L1-RECOMMEND/arm64/CONFIG_OBJTOOL diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET new file mode 100644 index 000000000000..759cb13e424c --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET @@ -0,0 +1 @@ +# CONFIG_RANDOMIZE_KSTACK_OFFSET is not set diff --git a/anolis/configs/L1-RECOMMEND/x86/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT similarity index 100% rename from anolis/configs/L1-RECOMMEND/x86/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT rename to anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT diff --git a/anolis/configs/L0-MANDATORY/arm64/CONFIG_UNWINDER_FRAME_POINTER b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_FRAME_POINTER similarity index 100% rename from anolis/configs/L0-MANDATORY/arm64/CONFIG_UNWINDER_FRAME_POINTER rename to anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_FRAME_POINTER diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_ORC b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_ORC new file mode 100644 index 000000000000..6b6908419acb --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_ORC @@ -0,0 +1 @@ +CONFIG_UNWINDER_ORC=y diff --git a/anolis/configs/L1-RECOMMEND/default/CONFIG_AHCI_ZHAOXIN_SGPIO b/anolis/configs/L1-RECOMMEND/default/CONFIG_AHCI_ZHAOXIN_SGPIO deleted file mode 100644 index 6a7ffe559b94..000000000000 --- a/anolis/configs/L1-RECOMMEND/default/CONFIG_AHCI_ZHAOXIN_SGPIO +++ /dev/null @@ -1 +0,0 @@ -CONFIG_AHCI_ZHAOXIN_SGPIO=m diff --git a/anolis/configs/L1-RECOMMEND/default/CONFIG_PCP_BATCH_SCALE_MAX b/anolis/configs/L1-RECOMMEND/default/CONFIG_PCP_BATCH_SCALE_MAX deleted file mode 100644 index 8c42e3567daa..000000000000 --- a/anolis/configs/L1-RECOMMEND/default/CONFIG_PCP_BATCH_SCALE_MAX +++ /dev/null @@ -1 +0,0 @@ -CONFIG_PCP_BATCH_SCALE_MAX=5 diff --git a/anolis/configs/L1-RECOMMEND/x86/CONFIG_RANDOMIZE_KSTACK_OFFSET b/anolis/configs/L1-RECOMMEND/default/CONFIG_RANDOMIZE_KSTACK_OFFSET similarity index 100% rename from anolis/configs/L1-RECOMMEND/x86/CONFIG_RANDOMIZE_KSTACK_OFFSET rename to anolis/configs/L1-RECOMMEND/default/CONFIG_RANDOMIZE_KSTACK_OFFSET diff --git a/anolis/configs/L1-RECOMMEND/default/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT b/anolis/configs/L1-RECOMMEND/default/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT new file mode 100644 index 000000000000..d680659c1703 --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/default/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT @@ -0,0 +1 @@ +# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set diff --git a/anolis/configs/L1-RECOMMEND/x86/CONFIG_GENERIC_PHY b/anolis/configs/L1-RECOMMEND/x86/CONFIG_GENERIC_PHY new file mode 100644 index 000000000000..582e87c3b9f5 --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/x86/CONFIG_GENERIC_PHY @@ -0,0 +1 @@ +# CONFIG_GENERIC_PHY is not set diff --git a/anolis/configs/L1-RECOMMEND/x86/CONFIG_MITIGATION_SPECTRE_BHI b/anolis/configs/L1-RECOMMEND/x86/CONFIG_MITIGATION_SPECTRE_BHI deleted file mode 100644 index 71b428227384..000000000000 --- a/anolis/configs/L1-RECOMMEND/x86/CONFIG_MITIGATION_SPECTRE_BHI +++ /dev/null @@ -1 +0,0 @@ -CONFIG_MITIGATION_SPECTRE_BHI=y diff --git a/anolis/configs/L1-RECOMMEND/default/CONFIG_TEST_LIVEPATCH b/anolis/configs/L1-RECOMMEND/x86/CONFIG_TEST_LIVEPATCH similarity index 100% rename from anolis/configs/L1-RECOMMEND/default/CONFIG_TEST_LIVEPATCH rename to anolis/configs/L1-RECOMMEND/x86/CONFIG_TEST_LIVEPATCH diff --git a/anolis/configs/L2-OPTIONAL/default/CONFIG_DRM_PANEL_ILITEK_ILI9341 b/anolis/configs/L2-OPTIONAL/arm64/CONFIG_DRM_PANEL_ILITEK_ILI9341 similarity index 100% rename from anolis/configs/L2-OPTIONAL/default/CONFIG_DRM_PANEL_ILITEK_ILI9341 rename to anolis/configs/L2-OPTIONAL/arm64/CONFIG_DRM_PANEL_ILITEK_ILI9341 diff --git a/anolis/configs/L2-OPTIONAL/arm64/CONFIG_TEST_LIVEPATCH b/anolis/configs/L2-OPTIONAL/arm64/CONFIG_TEST_LIVEPATCH new file mode 100644 index 000000000000..0dd7700464a8 --- /dev/null +++ b/anolis/configs/L2-OPTIONAL/arm64/CONFIG_TEST_LIVEPATCH @@ -0,0 +1 @@ +CONFIG_TEST_LIVEPATCH=m diff --git a/anolis/configs/L2-OPTIONAL/default/CONFIG_BCACHE_ASYNC_REGISTRATION b/anolis/configs/L2-OPTIONAL/default/CONFIG_BCACHE_ASYNC_REGISTRATION deleted file mode 100644 index d966c9744d3d..000000000000 --- a/anolis/configs/L2-OPTIONAL/default/CONFIG_BCACHE_ASYNC_REGISTRATION +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_BCACHE_ASYNC_REGISTRATION is not set diff --git a/anolis/configs/L2-OPTIONAL/default/CONFIG_BCACHE_CLOSURES_DEBUG b/anolis/configs/L2-OPTIONAL/default/CONFIG_BCACHE_CLOSURES_DEBUG deleted file mode 100644 index eb3f1af90e6c..000000000000 --- a/anolis/configs/L2-OPTIONAL/default/CONFIG_BCACHE_CLOSURES_DEBUG +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_BCACHE_CLOSURES_DEBUG is not set diff --git a/anolis/configs/L2-OPTIONAL/default/CONFIG_BCACHE_DEBUG b/anolis/configs/L2-OPTIONAL/default/CONFIG_BCACHE_DEBUG deleted file mode 100644 index 36426027b2d1..000000000000 --- a/anolis/configs/L2-OPTIONAL/default/CONFIG_BCACHE_DEBUG +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_BCACHE_DEBUG is not set diff --git a/anolis/configs/L2-OPTIONAL/default/CONFIG_CRYPTO_SIG b/anolis/configs/L2-OPTIONAL/default/CONFIG_CRYPTO_SIG deleted file mode 100644 index 01ee2034fbdc..000000000000 --- a/anolis/configs/L2-OPTIONAL/default/CONFIG_CRYPTO_SIG +++ /dev/null @@ -1 +0,0 @@ -CONFIG_CRYPTO_SIG=y diff --git a/anolis/configs/L2-OPTIONAL/default/CONFIG_FB_IOMEM_FOPS b/anolis/configs/L2-OPTIONAL/default/CONFIG_FB_IOMEM_FOPS deleted file mode 100644 index 485cf9b71de5..000000000000 --- a/anolis/configs/L2-OPTIONAL/default/CONFIG_FB_IOMEM_FOPS +++ /dev/null @@ -1 +0,0 @@ -CONFIG_FB_IOMEM_FOPS=y diff --git a/anolis/configs/L1-RECOMMEND/x86/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET b/anolis/configs/L2-OPTIONAL/default/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET similarity index 100% rename from anolis/configs/L1-RECOMMEND/x86/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET rename to anolis/configs/L2-OPTIONAL/default/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET diff --git a/anolis/configs/L2-OPTIONAL/default/CONFIG_PATA_HPT3X3_DMA b/anolis/configs/L2-OPTIONAL/default/CONFIG_PATA_HPT3X3_DMA deleted file mode 100644 index 723cb8bb73ac..000000000000 --- a/anolis/configs/L2-OPTIONAL/default/CONFIG_PATA_HPT3X3_DMA +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_PATA_HPT3X3_DMA is not set diff --git a/anolis/configs/L2-OPTIONAL/default/CONFIG_SCREEN_INFO b/anolis/configs/L2-OPTIONAL/default/CONFIG_SCREEN_INFO deleted file mode 100644 index e5a12d9c60db..000000000000 --- a/anolis/configs/L2-OPTIONAL/default/CONFIG_SCREEN_INFO +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SCREEN_INFO=y diff --git a/anolis/configs/L2-OPTIONAL/default/CONFIG_SCSI_MVSAS_DEBUG b/anolis/configs/L2-OPTIONAL/default/CONFIG_SCSI_MVSAS_DEBUG deleted file mode 100644 index aa295ebbb545..000000000000 --- a/anolis/configs/L2-OPTIONAL/default/CONFIG_SCSI_MVSAS_DEBUG +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SCSI_MVSAS_DEBUG=y diff --git a/anolis/configs/L2-OPTIONAL/default/CONFIG_SCSI_MVSAS_TASKLET b/anolis/configs/L2-OPTIONAL/default/CONFIG_SCSI_MVSAS_TASKLET deleted file mode 100644 index 028f7d8e3d25..000000000000 --- a/anolis/configs/L2-OPTIONAL/default/CONFIG_SCSI_MVSAS_TASKLET +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_SCSI_MVSAS_TASKLET is not set diff --git a/anolis/configs/L2-OPTIONAL/x86/CONFIG_AD9467 b/anolis/configs/L2-OPTIONAL/x86/CONFIG_AD9467 deleted file mode 100644 index 421ac1f25eec..000000000000 --- a/anolis/configs/L2-OPTIONAL/x86/CONFIG_AD9467 +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_AD9467 is not set diff --git a/anolis/configs/L2-OPTIONAL/x86/CONFIG_ADI_AXI_ADC b/anolis/configs/L2-OPTIONAL/x86/CONFIG_ADI_AXI_ADC deleted file mode 100644 index e98b407ac85f..000000000000 --- a/anolis/configs/L2-OPTIONAL/x86/CONFIG_ADI_AXI_ADC +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_ADI_AXI_ADC is not set diff --git a/anolis/configs/L2-OPTIONAL/x86/CONFIG_ARCH_CONFIGURES_CPU_MITIGATIONS b/anolis/configs/L2-OPTIONAL/x86/CONFIG_ARCH_CONFIGURES_CPU_MITIGATIONS deleted file mode 100644 index a7a95432397c..000000000000 --- a/anolis/configs/L2-OPTIONAL/x86/CONFIG_ARCH_CONFIGURES_CPU_MITIGATIONS +++ /dev/null @@ -1 +0,0 @@ -CONFIG_ARCH_CONFIGURES_CPU_MITIGATIONS=y diff --git a/anolis/configs/L2-OPTIONAL/x86/CONFIG_HAVE_LIVEPATCH b/anolis/configs/L2-OPTIONAL/x86/CONFIG_HAVE_LIVEPATCH new file mode 100644 index 000000000000..7ebdb924703e --- /dev/null +++ b/anolis/configs/L2-OPTIONAL/x86/CONFIG_HAVE_LIVEPATCH @@ -0,0 +1 @@ +CONFIG_HAVE_LIVEPATCH=y diff --git a/anolis/configs/L2-OPTIONAL/x86/CONFIG_HAVE_RELIABLE_STACKTRACE b/anolis/configs/L2-OPTIONAL/x86/CONFIG_HAVE_RELIABLE_STACKTRACE new file mode 100644 index 000000000000..2ce8faabc4cf --- /dev/null +++ b/anolis/configs/L2-OPTIONAL/x86/CONFIG_HAVE_RELIABLE_STACKTRACE @@ -0,0 +1 @@ +CONFIG_HAVE_RELIABLE_STACKTRACE=y diff --git a/anolis/configs/L2-OPTIONAL/x86/CONFIG_HAVE_STACK_VALIDATION b/anolis/configs/L2-OPTIONAL/x86/CONFIG_HAVE_STACK_VALIDATION new file mode 100644 index 000000000000..6f36a32d84ae --- /dev/null +++ b/anolis/configs/L2-OPTIONAL/x86/CONFIG_HAVE_STACK_VALIDATION @@ -0,0 +1 @@ +CONFIG_HAVE_STACK_VALIDATION=y diff --git a/anolis/configs/L2-OPTIONAL/x86/CONFIG_OBJTOOL b/anolis/configs/L2-OPTIONAL/x86/CONFIG_OBJTOOL new file mode 100644 index 000000000000..cf3a9f20f93d --- /dev/null +++ b/anolis/configs/L2-OPTIONAL/x86/CONFIG_OBJTOOL @@ -0,0 +1 @@ +CONFIG_OBJTOOL=y -- Gitee From 11e0098a0eb0618da5e45cf17c274e584966f617 Mon Sep 17 00:00:00 2001 From: Jia He Date: Mon, 4 Nov 2024 06:00:56 +0000 Subject: [PATCH 02/13] Revert "anolis: configs: Enable CONFIG_LIVEPATCH for arm64" ANBZ: #11595 cherry-picked from https://lore.kernel.org/lkml/20230202074036.507249-1-madvenka@linux.microsoft.com/ This reverts commit ce8c54e48ecebb6979504596749f410fefcc2a3b. To support livepatch features on other architectures, it's preferable to keep the Anolis livepatch code layout closely aligned with the upstream kernel. Therefore, we should revert the commits that reorganized the code specifically for arm64 livepatch support. Hence temporarily disable the livepatch support on arm64 when reverting some reorganization commits to avoid conflicts or compilation errors. Signed-off-by: Jia He --- .../configs/L1-RECOMMEND/arm64/CONFIG_FRAME_POINTER_VALIDATION | 1 - .../L1-RECOMMEND/arm64/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET | 1 - anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_LIVEPATCH | 1 - .../configs/L1-RECOMMEND/arm64/CONFIG_HAVE_RELIABLE_STACKTRACE | 1 - anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_STACK_VALIDATION | 1 - anolis/configs/L1-RECOMMEND/arm64/CONFIG_LIVEPATCH | 1 - anolis/configs/L1-RECOMMEND/arm64/CONFIG_OBJTOOL | 1 - anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET | 1 - .../L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT | 1 - anolis/configs/L1-RECOMMEND/arm64/CONFIG_STACK_VALIDATION | 1 - anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_FRAME_POINTER | 1 - anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_ORC | 1 - anolis/configs/L2-OPTIONAL/arm64/CONFIG_TEST_LIVEPATCH | 1 - 13 files changed, 13 deletions(-) delete mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_FRAME_POINTER_VALIDATION delete mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET delete mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_LIVEPATCH delete mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_RELIABLE_STACKTRACE delete mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_STACK_VALIDATION delete mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_LIVEPATCH delete mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_OBJTOOL delete mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET delete mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT delete mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_STACK_VALIDATION delete mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_FRAME_POINTER delete mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_ORC delete mode 100644 anolis/configs/L2-OPTIONAL/arm64/CONFIG_TEST_LIVEPATCH diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_FRAME_POINTER_VALIDATION b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_FRAME_POINTER_VALIDATION deleted file mode 100644 index cc041e559182..000000000000 --- a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_FRAME_POINTER_VALIDATION +++ /dev/null @@ -1 +0,0 @@ -CONFIG_FRAME_POINTER_VALIDATION=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET deleted file mode 100644 index c7daa4f60d5d..000000000000 --- a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET is not set diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_LIVEPATCH b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_LIVEPATCH deleted file mode 100644 index 7ebdb924703e..000000000000 --- a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_LIVEPATCH +++ /dev/null @@ -1 +0,0 @@ -CONFIG_HAVE_LIVEPATCH=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_RELIABLE_STACKTRACE b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_RELIABLE_STACKTRACE deleted file mode 100644 index 2ce8faabc4cf..000000000000 --- a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_RELIABLE_STACKTRACE +++ /dev/null @@ -1 +0,0 @@ -CONFIG_HAVE_RELIABLE_STACKTRACE=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_STACK_VALIDATION b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_STACK_VALIDATION deleted file mode 100644 index 6f36a32d84ae..000000000000 --- a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_STACK_VALIDATION +++ /dev/null @@ -1 +0,0 @@ -CONFIG_HAVE_STACK_VALIDATION=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_LIVEPATCH b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_LIVEPATCH deleted file mode 100644 index 1b05d0d1a109..000000000000 --- a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_LIVEPATCH +++ /dev/null @@ -1 +0,0 @@ -CONFIG_LIVEPATCH=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_OBJTOOL b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_OBJTOOL deleted file mode 100644 index cf3a9f20f93d..000000000000 --- a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_OBJTOOL +++ /dev/null @@ -1 +0,0 @@ -CONFIG_OBJTOOL=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET deleted file mode 100644 index 759cb13e424c..000000000000 --- a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_RANDOMIZE_KSTACK_OFFSET is not set diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT deleted file mode 100644 index d680659c1703..000000000000 --- a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_STACK_VALIDATION b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_STACK_VALIDATION deleted file mode 100644 index e335fefdd9be..000000000000 --- a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_STACK_VALIDATION +++ /dev/null @@ -1 +0,0 @@ -CONFIG_STACK_VALIDATION=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_FRAME_POINTER b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_FRAME_POINTER deleted file mode 100644 index 0938fde11ffe..000000000000 --- a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_FRAME_POINTER +++ /dev/null @@ -1 +0,0 @@ -CONFIG_UNWINDER_FRAME_POINTER=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_ORC b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_ORC deleted file mode 100644 index 6b6908419acb..000000000000 --- a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_ORC +++ /dev/null @@ -1 +0,0 @@ -CONFIG_UNWINDER_ORC=y diff --git a/anolis/configs/L2-OPTIONAL/arm64/CONFIG_TEST_LIVEPATCH b/anolis/configs/L2-OPTIONAL/arm64/CONFIG_TEST_LIVEPATCH deleted file mode 100644 index 0dd7700464a8..000000000000 --- a/anolis/configs/L2-OPTIONAL/arm64/CONFIG_TEST_LIVEPATCH +++ /dev/null @@ -1 +0,0 @@ -CONFIG_TEST_LIVEPATCH=m -- Gitee From 8524a4578cbefa14b7cb7bad44c5738b51ac6ae7 Mon Sep 17 00:00:00 2001 From: Jia He Date: Mon, 4 Nov 2024 06:01:09 +0000 Subject: [PATCH 03/13] Revert "arm64: Enable livepatch for ARM64" ANBZ: #11595 cherry-picked from https://lore.kernel.org/lkml/20230202074036.507249-1-madvenka@linux.microsoft.com/ This reverts commit 01cc06c19187d6d4df515842add3156e68013cc0. To support livepatch features on other architectures, it's preferable to keep the Anolis livepatch code layout closely aligned with the upstream kernel. Therefore, we should revert the commits that reorganized the code specifically for arm64 livepatch support. Hence temporarily disable the livepatch support on arm64 when reverting some reorganization commits to avoid conflicts or compilation errors. Signed-off-by: Jia He --- arch/arm64/Kconfig | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index e553aa8058db..630f0f498cb1 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -174,7 +174,7 @@ config ARM64 select HAVE_ARCH_MMAP_RND_BITS select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT select HAVE_ARCH_PREL32_RELOCATIONS - select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET if !HAVE_LIVEPATCH + select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_STACKLEAK select HAVE_ARCH_THREAD_STRUCT_WHITELIST @@ -258,8 +258,6 @@ config ARM64 select HAVE_SOFTIRQ_ON_OWN_STACK select HAVE_STACK_VALIDATION if FRAME_POINTER_VALIDATION select STACK_VALIDATION if HAVE_STACK_VALIDATION - select HAVE_RELIABLE_STACKTRACE if STACK_VALIDATION - select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_ARGS && HAVE_RELIABLE_STACKTRACE help ARM 64-bit (AArch64) Linux support. @@ -2406,4 +2404,3 @@ source "drivers/acpi/Kconfig" source "arch/arm64/kvm/Kconfig" -source "kernel/livepatch/Kconfig" -- Gitee From e289cb7fbd40dcdaeaf2028f33b889fffe653a4a Mon Sep 17 00:00:00 2001 From: Jia He Date: Tue, 29 Oct 2024 11:03:00 +0000 Subject: [PATCH 04/13] Revert "objtool: Reorganize ORC kernel code" ANBZ: #11595 cherry-picked from https://lore.kernel.org/lkml/20230202074036.507249-1-madvenka@linux.microsoft.com/ This reverts commit e46e240a9dafb543e4ff824cfd86632af6f9f799. To support livepatch features on other architectures, it's preferable to keep the Anolis livepatch code layout closely aligned with the upstream kernel. Therefore, we should revert the commits that reorganized the code specifically for arm64 livepatch support. Signed-off-by: Jia He --- .../arm64/include/asm}/orc_lookup.h | 0 arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/module.c | 2 +- {kernel => arch/arm64/kernel}/orc_lookup.c | 2 +- arch/arm64/kernel/setup.c | 2 +- arch/arm64/kernel/stacktrace.c | 2 +- arch/arm64/kernel/vmlinux.lds.S | 2 +- arch/x86/include/asm/orc_lookup.h | 34 +++ arch/x86/include/asm/unwind.h | 5 + arch/x86/kernel/module.c | 7 +- arch/x86/kernel/unwind_orc.c | 257 +++++++++++++++++- arch/x86/kernel/vmlinux.lds.S | 2 +- kernel/Makefile | 2 - tools/objtool/arch/x86/orc.c | 1 - 14 files changed, 299 insertions(+), 20 deletions(-) rename {include/asm-generic => arch/arm64/include/asm}/orc_lookup.h (100%) rename {kernel => arch/arm64/kernel}/orc_lookup.c (99%) create mode 100644 arch/x86/include/asm/orc_lookup.h diff --git a/include/asm-generic/orc_lookup.h b/arch/arm64/include/asm/orc_lookup.h similarity index 100% rename from include/asm-generic/orc_lookup.h rename to arch/arm64/include/asm/orc_lookup.h diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 7c67e2f29206..f9439f96f0ec 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -76,6 +76,7 @@ obj-$(CONFIG_ARM64_MTE) += mte.o obj-y += vdso-wrap.o obj-$(CONFIG_COMPAT_VDSO) += vdso32-wrap.o obj-$(CONFIG_UNWIND_PATCH_PAC_INTO_SCS) += patch-scs.o +obj-$(CONFIG_UNWINDER_ORC) += orc_lookup.o CFLAGS_patch-scs.o += -mbranch-protection=none # Force dependency (vdso*-wrap.S includes vdso.so through incbin) diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c index 09251ad0ff4e..8f19c7a7d65d 100644 --- a/arch/arm64/kernel/module.c +++ b/arch/arm64/kernel/module.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include static u64 module_direct_base __ro_after_init = 0; static u64 module_plt_base __ro_after_init = 0; diff --git a/kernel/orc_lookup.c b/arch/arm64/kernel/orc_lookup.c similarity index 99% rename from kernel/orc_lookup.c rename to arch/arm64/kernel/orc_lookup.c index ad845da546b4..9c062c054dcb 100644 --- a/kernel/orc_lookup.c +++ b/arch/arm64/kernel/orc_lookup.c @@ -3,7 +3,7 @@ #include #include #include -#include +#include bool orc_init __ro_after_init; static unsigned int lookup_num_blocks __ro_after_init; diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index e7d0cb515d9c..80960d97d55f 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -53,7 +53,7 @@ #include #include #include -#include +#include static int num_standard_resources; static struct resource *standard_resources; diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 71157c0eb77b..ab9605aa721d 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -6,7 +6,7 @@ */ #include #include -#include +#include #include #include #include diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 7cf905d551af..031a5272b91b 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -61,7 +61,7 @@ #define RUNTIME_DISCARD_EXIT #include -#include +#include #include #include #include diff --git a/arch/x86/include/asm/orc_lookup.h b/arch/x86/include/asm/orc_lookup.h new file mode 100644 index 000000000000..241631282e43 --- /dev/null +++ b/arch/x86/include/asm/orc_lookup.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2017 Josh Poimboeuf + */ +#ifndef _ORC_LOOKUP_H +#define _ORC_LOOKUP_H + +/* + * This is a lookup table for speeding up access to the .orc_unwind table. + * Given an input address offset, the corresponding lookup table entry + * specifies a subset of the .orc_unwind table to search. + * + * Each block represents the end of the previous range and the start of the + * next range. An extra block is added to give the last range an end. + * + * The block size should be a power of 2 to avoid a costly 'div' instruction. + * + * A block size of 256 was chosen because it roughly doubles unwinder + * performance while only adding ~5% to the ORC data footprint. + */ +#define LOOKUP_BLOCK_ORDER 8 +#define LOOKUP_BLOCK_SIZE (1 << LOOKUP_BLOCK_ORDER) + +#ifndef LINKER_SCRIPT + +extern unsigned int orc_lookup[]; +extern unsigned int orc_lookup_end[]; + +#define LOOKUP_START_IP (unsigned long)_stext +#define LOOKUP_STOP_IP (unsigned long)_etext + +#endif /* LINKER_SCRIPT */ + +#endif /* _ORC_LOOKUP_H */ diff --git a/arch/x86/include/asm/unwind.h b/arch/x86/include/asm/unwind.h index 71af8246c69e..7cede4dc21f0 100644 --- a/arch/x86/include/asm/unwind.h +++ b/arch/x86/include/asm/unwind.h @@ -94,8 +94,13 @@ static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state, #ifdef CONFIG_UNWINDER_ORC void unwind_init(void); +void unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size, + void *orc, size_t orc_size); #else static inline void unwind_init(void) {} +static inline +void unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size, + void *orc, size_t orc_size) {} #endif static inline diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index 2fc4411a22d9..5f71a0cf4399 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #if 0 #define DEBUGP(fmt, ...) \ @@ -370,9 +370,8 @@ int module_finalize(const Elf_Ehdr *hdr, } if (orc && orc_ip) - orc_lookup_module_init(me, - (void *)orc_ip->sh_addr, orc_ip->sh_size, - (void *)orc->sh_addr, orc->sh_size); + unwind_module_init(me, (void *)orc_ip->sh_addr, orc_ip->sh_size, + (void *)orc->sh_addr, orc->sh_size); return 0; } diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c index b5d27bd3d515..c79360196365 100644 --- a/arch/x86/kernel/unwind_orc.c +++ b/arch/x86/kernel/unwind_orc.c @@ -7,12 +7,34 @@ #include #include #include +#include #include -#include ORC_HEADER; +#define orc_warn(fmt, ...) \ + printk_deferred_once(KERN_WARNING "WARNING: " fmt, ##__VA_ARGS__) + +#define orc_warn_current(args...) \ +({ \ + static bool dumped_before; \ + if (state->task == current && !state->error) { \ + orc_warn(args); \ + if (unwind_debug && !dumped_before) { \ + dumped_before = true; \ + unwind_dump(state); \ + } \ + } \ +}) + +extern int __start_orc_unwind_ip[]; +extern int __stop_orc_unwind_ip[]; +extern struct orc_entry __start_orc_unwind[]; +extern struct orc_entry __stop_orc_unwind[]; + +static bool orc_init __ro_after_init; static bool unwind_debug __ro_after_init; +static unsigned int lookup_num_blocks __ro_after_init; static int __init unwind_debug_cmdline(char *str) { @@ -54,9 +76,60 @@ static void unwind_dump(struct unwind_state *state) } } -#include +static inline unsigned long orc_ip(const int *ip) +{ + return (unsigned long)ip + *ip; +} + +static struct orc_entry *__orc_find(int *ip_table, struct orc_entry *u_table, + unsigned int num_entries, unsigned long ip) +{ + int *first = ip_table; + int *last = ip_table + num_entries - 1; + int *mid = first, *found = first; + + if (!num_entries) + return NULL; + + /* + * Do a binary range search to find the rightmost duplicate of a given + * starting address. Some entries are section terminators which are + * "weak" entries for ensuring there are no gaps. They should be + * ignored when they conflict with a real entry. + */ + while (first <= last) { + mid = first + ((last - first) / 2); + + if (orc_ip(mid) <= ip) { + found = mid; + first = mid + 1; + } else + last = mid - 1; + } + + return u_table + (found - ip_table); +} + +#ifdef CONFIG_MODULES +static struct orc_entry *orc_module_find(unsigned long ip) +{ + struct module *mod; + + mod = __module_address(ip); + if (!mod || !mod->arch.orc_unwind || !mod->arch.orc_unwind_ip) + return NULL; + return __orc_find(mod->arch.orc_unwind_ip, mod->arch.orc_unwind, + mod->arch.num_orcs, ip); +} +#else +static struct orc_entry *orc_module_find(unsigned long ip) +{ + return NULL; +} +#endif #ifdef CONFIG_DYNAMIC_FTRACE +static struct orc_entry *orc_find(unsigned long ip); /* * Ftrace dynamic trampolines do not have orc entries of their own. @@ -100,10 +173,19 @@ static struct orc_entry *orc_ftrace_find(unsigned long ip) } #endif -struct orc_entry *arch_orc_find(unsigned long ip) -{ - return orc_ftrace_find(ip); -} +/* + * If we crash with IP==0, the last successfully executed instruction + * was probably an indirect function call with a NULL function pointer, + * and we don't have unwind information for NULL. + * This hardcoded ORC entry for IP==0 allows us to unwind from a NULL function + * pointer into its parent and then continue normally from there. + */ +static struct orc_entry null_orc_entry = { + .sp_offset = sizeof(long), + .sp_reg = ORC_REG_SP, + .bp_reg = ORC_REG_UNDEFINED, + .type = ORC_TYPE_CALL +}; /* Fake frame pointer entry -- used as a fallback for generated code */ static struct orc_entry orc_fp_entry = { @@ -114,9 +196,170 @@ static struct orc_entry orc_fp_entry = { .bp_offset = -16, }; +static struct orc_entry *orc_find(unsigned long ip) +{ + static struct orc_entry *orc; + + if (ip == 0) + return &null_orc_entry; + + /* For non-init vmlinux addresses, use the fast lookup table: */ + if (ip >= LOOKUP_START_IP && ip < LOOKUP_STOP_IP) { + unsigned int idx, start, stop; + + idx = (ip - LOOKUP_START_IP) / LOOKUP_BLOCK_SIZE; + + if (unlikely((idx >= lookup_num_blocks-1))) { + orc_warn("WARNING: bad lookup idx: idx=%u num=%u ip=%pB\n", + idx, lookup_num_blocks, (void *)ip); + return NULL; + } + + start = orc_lookup[idx]; + stop = orc_lookup[idx + 1] + 1; + + if (unlikely((__start_orc_unwind + start >= __stop_orc_unwind) || + (__start_orc_unwind + stop > __stop_orc_unwind))) { + orc_warn("WARNING: bad lookup value: idx=%u num=%u start=%u stop=%u ip=%pB\n", + idx, lookup_num_blocks, start, stop, (void *)ip); + return NULL; + } + + return __orc_find(__start_orc_unwind_ip + start, + __start_orc_unwind + start, stop - start, ip); + } + + /* vmlinux .init slow lookup: */ + if (is_kernel_inittext(ip)) + return __orc_find(__start_orc_unwind_ip, __start_orc_unwind, + __stop_orc_unwind_ip - __start_orc_unwind_ip, ip); + + /* Module lookup: */ + orc = orc_module_find(ip); + if (orc) + return orc; + + return orc_ftrace_find(ip); +} + +#ifdef CONFIG_MODULES + +static DEFINE_MUTEX(sort_mutex); +static int *cur_orc_ip_table = __start_orc_unwind_ip; +static struct orc_entry *cur_orc_table = __start_orc_unwind; + +static void orc_sort_swap(void *_a, void *_b, int size) +{ + struct orc_entry *orc_a, *orc_b; + int *a = _a, *b = _b, tmp; + int delta = _b - _a; + + /* Swap the .orc_unwind_ip entries: */ + tmp = *a; + *a = *b + delta; + *b = tmp - delta; + + /* Swap the corresponding .orc_unwind entries: */ + orc_a = cur_orc_table + (a - cur_orc_ip_table); + orc_b = cur_orc_table + (b - cur_orc_ip_table); + swap(*orc_a, *orc_b); +} + +static int orc_sort_cmp(const void *_a, const void *_b) +{ + struct orc_entry *orc_a; + const int *a = _a, *b = _b; + unsigned long a_val = orc_ip(a); + unsigned long b_val = orc_ip(b); + + if (a_val > b_val) + return 1; + if (a_val < b_val) + return -1; + + /* + * The "weak" section terminator entries need to always be first + * to ensure the lookup code skips them in favor of real entries. + * These terminator entries exist to handle any gaps created by + * whitelisted .o files which didn't get objtool generation. + */ + orc_a = cur_orc_table + (a - cur_orc_ip_table); + return orc_a->type == ORC_TYPE_UNDEFINED ? -1 : 1; +} + +void unwind_module_init(struct module *mod, void *_orc_ip, size_t orc_ip_size, + void *_orc, size_t orc_size) +{ + int *orc_ip = _orc_ip; + struct orc_entry *orc = _orc; + unsigned int num_entries = orc_ip_size / sizeof(int); + + WARN_ON_ONCE(orc_ip_size % sizeof(int) != 0 || + orc_size % sizeof(*orc) != 0 || + num_entries != orc_size / sizeof(*orc)); + + /* + * The 'cur_orc_*' globals allow the orc_sort_swap() callback to + * associate an .orc_unwind_ip table entry with its corresponding + * .orc_unwind entry so they can both be swapped. + */ + mutex_lock(&sort_mutex); + cur_orc_ip_table = orc_ip; + cur_orc_table = orc; + sort(orc_ip, num_entries, sizeof(int), orc_sort_cmp, orc_sort_swap); + mutex_unlock(&sort_mutex); + + mod->arch.orc_unwind_ip = orc_ip; + mod->arch.orc_unwind = orc; + mod->arch.num_orcs = num_entries; +} +#endif + void __init unwind_init(void) { - orc_lookup_init(); + size_t orc_ip_size = (void *)__stop_orc_unwind_ip - (void *)__start_orc_unwind_ip; + size_t orc_size = (void *)__stop_orc_unwind - (void *)__start_orc_unwind; + size_t num_entries = orc_ip_size / sizeof(int); + struct orc_entry *orc; + int i; + + if (!num_entries || orc_ip_size % sizeof(int) != 0 || + orc_size % sizeof(struct orc_entry) != 0 || + num_entries != orc_size / sizeof(struct orc_entry)) { + orc_warn("WARNING: Bad or missing .orc_unwind table. Disabling unwinder.\n"); + return; + } + + /* + * Note, the orc_unwind and orc_unwind_ip tables were already + * sorted at build time via the 'sorttable' tool. + * It's ready for binary search straight away, no need to sort it. + */ + + /* Initialize the fast lookup table: */ + lookup_num_blocks = orc_lookup_end - orc_lookup; + for (i = 0; i < lookup_num_blocks-1; i++) { + orc = __orc_find(__start_orc_unwind_ip, __start_orc_unwind, + num_entries, + LOOKUP_START_IP + (LOOKUP_BLOCK_SIZE * i)); + if (!orc) { + orc_warn("WARNING: Corrupt .orc_unwind table. Disabling unwinder.\n"); + return; + } + + orc_lookup[i] = orc - __start_orc_unwind; + } + + /* Initialize the ending block: */ + orc = __orc_find(__start_orc_unwind_ip, __start_orc_unwind, num_entries, + LOOKUP_STOP_IP); + if (!orc) { + orc_warn("WARNING: Corrupt .orc_unwind table. Disabling unwinder.\n"); + return; + } + orc_lookup[lookup_num_blocks-1] = orc - __start_orc_unwind; + + orc_init = true; } unsigned long unwind_get_return_address(struct unwind_state *state) diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 7e7b7846c632..54a5596adaa6 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/kernel/Makefile b/kernel/Makefile index 680be35dffc6..ce105a5558fc 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -132,8 +132,6 @@ obj-$(CONFIG_WATCH_QUEUE) += watch_queue.o obj-$(CONFIG_RESOURCE_KUNIT_TEST) += resource_kunit.o obj-$(CONFIG_SYSCTL_KUNIT_TEST) += sysctl-test.o -obj-$(CONFIG_UNWINDER_ORC) += orc_lookup.o - CFLAGS_stackleak.o += $(DISABLE_STACKLEAK_PLUGIN) obj-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak.o KASAN_SANITIZE_stackleak.o := n diff --git a/tools/objtool/arch/x86/orc.c b/tools/objtool/arch/x86/orc.c index 3526dfd9749d..891b85ae314e 100644 --- a/tools/objtool/arch/x86/orc.c +++ b/tools/objtool/arch/x86/orc.c @@ -9,7 +9,6 @@ #include #include -#include #include #include #include -- Gitee From f23bf747b8cd0eaab91dc2b15b45196e4aa83b5c Mon Sep 17 00:00:00 2001 From: Jia He Date: Tue, 29 Oct 2024 11:24:31 +0000 Subject: [PATCH 05/13] =?UTF-8?q?Revert=20=E2=80=9Cobjtool:=20Reorganize?= =?UTF-8?q?=20ORC=20code=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #11595 cherry-picked from https://lore.kernel.org/lkml/20230202074036.507249-1-madvenka@linux.microsoft.com/ This reverts commit eb97f05779918730493086e79b2a3faeb3112691. To support livepatch features on other architectures, it's preferable to keep the Anolis livepatch code layout closely aligned with the upstream kernel. Therefore, we should revert the commits that reorganized the code specifically for arm64 livepatch support. Signed-off-by: Jia He --- tools/objtool/arch/x86/Build | 1 - tools/objtool/arch/x86/include/arch/elf.h | 1 - tools/objtool/arch/x86/orc.c | 161 ---------------------- tools/objtool/include/objtool/orc.h | 18 --- tools/objtool/orc_dump.c | 65 ++++++++- tools/objtool/orc_gen.c | 94 ++++++++++++- 6 files changed, 152 insertions(+), 188 deletions(-) delete mode 100644 tools/objtool/arch/x86/orc.c delete mode 100644 tools/objtool/include/objtool/orc.h diff --git a/tools/objtool/arch/x86/Build b/tools/objtool/arch/x86/Build index 77b9a66cd6da..9f7869b5c5e0 100644 --- a/tools/objtool/arch/x86/Build +++ b/tools/objtool/arch/x86/Build @@ -1,6 +1,5 @@ objtool-y += special.o objtool-y += decode.o -objtool-$(BUILD_ORC) += orc.o inat_tables_script = ../arch/x86/tools/gen-insn-attr-x86.awk inat_tables_maps = ../arch/x86/lib/x86-opcode-map.txt diff --git a/tools/objtool/arch/x86/include/arch/elf.h b/tools/objtool/arch/x86/include/arch/elf.h index 39f23cb55352..7131f7f51a4e 100644 --- a/tools/objtool/arch/x86/include/arch/elf.h +++ b/tools/objtool/arch/x86/include/arch/elf.h @@ -9,6 +9,5 @@ #define R_DATA64 R_X86_64_PC32 #define R_TEXT32 R_X86_64_PC32 #define R_TEXT64 R_X86_64_PC32 -#define R_PCREL R_X86_64_PC32 #endif /* _OBJTOOL_ARCH_ELF */ diff --git a/tools/objtool/arch/x86/orc.c b/tools/objtool/arch/x86/orc.c deleted file mode 100644 index 891b85ae314e..000000000000 --- a/tools/objtool/arch/x86/orc.c +++ /dev/null @@ -1,161 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2017 Josh Poimboeuf - */ - -#include -#include - -#include - -#include -#include -#include -#include - -int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, - struct instruction *insn) -{ - struct cfi_reg *bp = &cfi->regs[CFI_BP]; - - memset(orc, 0, sizeof(*orc)); - - if (!cfi) { - /* - * This is usually either unreachable nops/traps (which don't - * trigger unreachable instruction warnings), or - * STACK_FRAME_NON_STANDARD functions. - */ - orc->type = ORC_TYPE_UNDEFINED; - return 0; - } - - switch (cfi->type) { - case UNWIND_HINT_TYPE_UNDEFINED: - orc->type = ORC_TYPE_UNDEFINED; - return 0; - case UNWIND_HINT_TYPE_END_OF_STACK: - orc->type = ORC_TYPE_END_OF_STACK; - return 0; - case UNWIND_HINT_TYPE_CALL: - orc->type = ORC_TYPE_CALL; - break; - case UNWIND_HINT_TYPE_REGS: - orc->type = ORC_TYPE_REGS; - break; - case UNWIND_HINT_TYPE_REGS_PARTIAL: - orc->type = ORC_TYPE_REGS_PARTIAL; - break; - default: - WARN_INSN(insn, "unknown unwind hint type %d", cfi->type); - return -1; - } - - orc->signal = cfi->signal; - - switch (cfi->cfa.base) { - case CFI_SP: - orc->sp_reg = ORC_REG_SP; - break; - case CFI_SP_INDIRECT: - orc->sp_reg = ORC_REG_SP_INDIRECT; - break; - case CFI_BP: - orc->sp_reg = ORC_REG_BP; - break; - case CFI_BP_INDIRECT: - orc->sp_reg = ORC_REG_BP_INDIRECT; - break; - case CFI_R10: - orc->sp_reg = ORC_REG_R10; - break; - case CFI_R13: - orc->sp_reg = ORC_REG_R13; - break; - case CFI_DI: - orc->sp_reg = ORC_REG_DI; - break; - case CFI_DX: - orc->sp_reg = ORC_REG_DX; - break; - default: - WARN_INSN(insn, "unknown CFA base reg %d", cfi->cfa.base); - return -1; - } - - switch (bp->base) { - case CFI_UNDEFINED: - orc->bp_reg = ORC_REG_UNDEFINED; - break; - case CFI_CFA: - orc->bp_reg = ORC_REG_PREV_SP; - break; - case CFI_BP: - orc->bp_reg = ORC_REG_BP; - break; - default: - WARN_INSN(insn, "unknown BP base reg %d", bp->base); - return -1; - } - - orc->sp_offset = cfi->cfa.offset; - orc->bp_offset = bp->offset; - - return 0; -} - -static const char *reg_name(unsigned int reg) -{ - switch (reg) { - case ORC_REG_PREV_SP: - return "prevsp"; - case ORC_REG_DX: - return "dx"; - case ORC_REG_DI: - return "di"; - case ORC_REG_BP: - return "bp"; - case ORC_REG_SP: - return "sp"; - case ORC_REG_R10: - return "r10"; - case ORC_REG_R13: - return "r13"; - case ORC_REG_BP_INDIRECT: - return "bp(ind)"; - case ORC_REG_SP_INDIRECT: - return "sp(ind)"; - default: - return "?"; - } -} - -const char *orc_type_name(unsigned int type) -{ - switch (type) { - case ORC_TYPE_UNDEFINED: - return "(und)"; - case ORC_TYPE_END_OF_STACK: - return "end"; - case ORC_TYPE_CALL: - return "call"; - case ORC_TYPE_REGS: - return "regs"; - case ORC_TYPE_REGS_PARTIAL: - return "regs (partial)"; - default: - return "?"; - } -} - -void orc_print_reg(unsigned int reg, int offset) -{ - if (reg == ORC_REG_BP_INDIRECT) - printf("(bp%+d)", offset); - else if (reg == ORC_REG_SP_INDIRECT) - printf("(sp)%+d", offset); - else if (reg == ORC_REG_UNDEFINED) - printf("(und)"); - else - printf("%s%+d", reg_name(reg), offset); -} diff --git a/tools/objtool/include/objtool/orc.h b/tools/objtool/include/objtool/orc.h deleted file mode 100644 index 11e746786fb4..000000000000 --- a/tools/objtool/include/objtool/orc.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2015-2017 Josh Poimboeuf - */ - -#ifndef _OBJTOOL_ORC_H -#define _OBJTOOL_ORC_H - -#include - -int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, - struct instruction *insn); -const char *orc_type_name(unsigned int type); -void orc_print_reg(unsigned int reg, int offset); -void orc_print_sp(void); -void orc_print_fp(void); - -#endif /* _OBJTOOL_ORC_H */ diff --git a/tools/objtool/orc_dump.c b/tools/objtool/orc_dump.c index 84545d5e694e..0e183bb1c720 100644 --- a/tools/objtool/orc_dump.c +++ b/tools/objtool/orc_dump.c @@ -4,12 +4,67 @@ */ #include +#include #include -#include -#include #include #include +static const char *reg_name(unsigned int reg) +{ + switch (reg) { + case ORC_REG_PREV_SP: + return "prevsp"; + case ORC_REG_DX: + return "dx"; + case ORC_REG_DI: + return "di"; + case ORC_REG_BP: + return "bp"; + case ORC_REG_SP: + return "sp"; + case ORC_REG_R10: + return "r10"; + case ORC_REG_R13: + return "r13"; + case ORC_REG_BP_INDIRECT: + return "bp(ind)"; + case ORC_REG_SP_INDIRECT: + return "sp(ind)"; + default: + return "?"; + } +} + +static const char *orc_type_name(unsigned int type) +{ + switch (type) { + case ORC_TYPE_UNDEFINED: + return "(und)"; + case ORC_TYPE_END_OF_STACK: + return "end"; + case ORC_TYPE_CALL: + return "call"; + case ORC_TYPE_REGS: + return "regs"; + case ORC_TYPE_REGS_PARTIAL: + return "regs (partial)"; + default: + return "?"; + } +} + +static void print_reg(unsigned int reg, int offset) +{ + if (reg == ORC_REG_BP_INDIRECT) + printf("(bp%+d)", offset); + else if (reg == ORC_REG_SP_INDIRECT) + printf("(sp)%+d", offset); + else if (reg == ORC_REG_UNDEFINED) + printf("(und)"); + else + printf("%s%+d", reg_name(reg), offset); +} + int orc_dump(const char *_objname) { int fd, nr_entries, i, *orc_ip = NULL, orc_size = 0; @@ -154,11 +209,11 @@ int orc_dump(const char *_objname) printf(" sp:"); - orc_print_reg(orc[i].sp_reg, bswap_if_needed(&dummy_elf, orc[i].sp_offset)); + print_reg(orc[i].sp_reg, bswap_if_needed(&dummy_elf, orc[i].sp_offset)); - printf(" fp:"); + printf(" bp:"); - orc_print_reg(orc[i].fp_reg, bswap_if_needed(&dummy_elf, orc[i].fp_offset)); + print_reg(orc[i].bp_reg, bswap_if_needed(&dummy_elf, orc[i].bp_offset)); printf(" signal:%d\n", orc[i].signal); } diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c index a146666ea9d1..cfa01f43edd6 100644 --- a/tools/objtool/orc_gen.c +++ b/tools/objtool/orc_gen.c @@ -7,10 +7,9 @@ #include #include -#include +#include #include -#include #include #include @@ -19,6 +18,97 @@ bool __weak orc_ignore_section(struct section *sec) return false; } +static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, + struct instruction *insn) +{ + struct cfi_reg *bp = &cfi->regs[CFI_BP]; + + memset(orc, 0, sizeof(*orc)); + + if (!cfi) { + /* + * This is usually either unreachable nops/traps (which don't + * trigger unreachable instruction warnings), or + * STACK_FRAME_NON_STANDARD functions. + */ + orc->type = ORC_TYPE_UNDEFINED; + return 0; + } + + switch (cfi->type) { + case UNWIND_HINT_TYPE_UNDEFINED: + orc->type = ORC_TYPE_UNDEFINED; + return 0; + case UNWIND_HINT_TYPE_END_OF_STACK: + orc->type = ORC_TYPE_END_OF_STACK; + return 0; + case UNWIND_HINT_TYPE_CALL: + orc->type = ORC_TYPE_CALL; + break; + case UNWIND_HINT_TYPE_REGS: + orc->type = ORC_TYPE_REGS; + break; + case UNWIND_HINT_TYPE_REGS_PARTIAL: + orc->type = ORC_TYPE_REGS_PARTIAL; + break; + default: + WARN_INSN(insn, "unknown unwind hint type %d", cfi->type); + return -1; + } + + orc->signal = cfi->signal; + + switch (cfi->cfa.base) { + case CFI_SP: + orc->sp_reg = ORC_REG_SP; + break; + case CFI_SP_INDIRECT: + orc->sp_reg = ORC_REG_SP_INDIRECT; + break; + case CFI_BP: + orc->sp_reg = ORC_REG_BP; + break; + case CFI_BP_INDIRECT: + orc->sp_reg = ORC_REG_BP_INDIRECT; + break; + case CFI_R10: + orc->sp_reg = ORC_REG_R10; + break; + case CFI_R13: + orc->sp_reg = ORC_REG_R13; + break; + case CFI_DI: + orc->sp_reg = ORC_REG_DI; + break; + case CFI_DX: + orc->sp_reg = ORC_REG_DX; + break; + default: + WARN_INSN(insn, "unknown CFA base reg %d", cfi->cfa.base); + return -1; + } + + switch (bp->base) { + case CFI_UNDEFINED: + orc->bp_reg = ORC_REG_UNDEFINED; + break; + case CFI_CFA: + orc->bp_reg = ORC_REG_PREV_SP; + break; + case CFI_BP: + orc->bp_reg = ORC_REG_BP; + break; + default: + WARN_INSN(insn, "unknown BP base reg %d", bp->base); + return -1; + } + + orc->sp_offset = cfi->cfa.offset; + orc->bp_offset = bp->offset; + + return 0; +} + static int write_orc_entry(struct elf *elf, struct section *orc_sec, struct section *ip_sec, unsigned int idx, struct section *insn_sec, unsigned long insn_off, -- Gitee From dd055738b89dd23f4c65de089d0016317b89e8d9 Mon Sep 17 00:00:00 2001 From: Jia He Date: Wed, 30 Oct 2024 00:24:06 +0000 Subject: [PATCH 06/13] objtool: Seperate arch-specific and generic parts ANBZ: #11595 commit b8e85e6f3a09fc56b0ff574887798962ef8a8f80 upstream. This reverts commit 9ec25e3e74653d228e00dfb7d816919ec5003d27. In addition, it cherry-pick commit b8e85e6f3a09 ("objtool/x86: Separate arch-specific and generic parts") And it also implements the arm64 specific orc.c Co-developed-by: Jinyang He Signed-off-by: Jinyang He Co-developed-by: Youling Tang Signed-off-by: Youling Tang Signed-off-by: Tiezhu Yang Signed-off-by: Huacai Chen Signed-off-by: Jia He --- tools/objtool/arch/arm64/include/arch/orc.h | 23 +++ tools/objtool/arch/arm64/orc.c | 39 +++- tools/objtool/arch/x86/Build | 1 + tools/objtool/arch/x86/orc.c | 188 ++++++++++++++++++++ tools/objtool/include/objtool/orc.h | 20 +++ tools/objtool/orc_dump.c | 69 +------ tools/objtool/orc_gen.c | 113 +----------- 7 files changed, 273 insertions(+), 180 deletions(-) create mode 100644 tools/objtool/arch/arm64/include/arch/orc.h create mode 100644 tools/objtool/arch/x86/orc.c create mode 100644 tools/objtool/include/objtool/orc.h diff --git a/tools/objtool/arch/arm64/include/arch/orc.h b/tools/objtool/arch/arm64/include/arch/orc.h new file mode 100644 index 000000000000..24fc9cf4de97 --- /dev/null +++ b/tools/objtool/arch/arm64/include/arch/orc.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2015-2017 Josh Poimboeuf + */ + +#ifndef _OBJTOOL_ORC_H +#define _OBJTOOL_ORC_H + +#include + +int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, + struct instruction *insn); +void orc_print_dump(struct elf *dummy_elf, struct orc_entry *orc, int i); +int write_orc_entry(struct elf *elf, struct section *orc_sec, + struct section *ip_sec, unsigned int idx, + struct section *insn_sec, unsigned long insn_off, + struct orc_entry *o); +const char *orc_type_name(unsigned int type); +void orc_print_reg(unsigned int reg, int offset); +void orc_print_sp(void); +void orc_print_fp(void); + +#endif /* _OBJTOOL_ORC_H */ diff --git a/tools/objtool/arch/arm64/orc.c b/tools/objtool/arch/arm64/orc.c index 98e930991ef1..25fba97534a1 100644 --- a/tools/objtool/arch/arm64/orc.c +++ b/tools/objtool/arch/arm64/orc.c @@ -9,7 +9,8 @@ #include #include -#include +#include +#include int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, struct instruction *insn) @@ -39,6 +40,27 @@ int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, return 0; } +int write_orc_entry(struct elf *elf, struct section *orc_sec, + struct section *ip_sec, unsigned int idx, + struct section *insn_sec, unsigned long insn_off, + struct orc_entry *o) +{ + struct orc_entry *orc; + + /* populate ORC data */ + orc = (struct orc_entry *)orc_sec->data->d_buf + idx; + memcpy(orc, o, sizeof(*orc)); + orc->sp_offset = bswap_if_needed(elf, orc->sp_offset); + orc->fp_offset = bswap_if_needed(elf, orc->fp_offset); + + /* populate reloc for ip */ + if (!elf_init_reloc_text_sym(elf, ip_sec, idx * sizeof(int), idx, + insn_sec, insn_off)) + return -1; + + return 0; +} + static const char *reg_name(unsigned int reg) { switch (reg) { @@ -67,6 +89,21 @@ const char *orc_type_name(unsigned int type) } } +void orc_print_dump(struct elf *dummy_elf, struct orc_entry *orc, int i) +{ + printf("type:%s", orc_type_name(orc[i].type)); + + printf(" sp:"); + + orc_print_reg(orc[i].sp_reg, bswap_if_needed(dummy_elf, orc[i].sp_offset)); + + printf(" fp:"); + + orc_print_reg(orc[i].fp_reg, bswap_if_needed(dummy_elf, orc[i].fp_offset)); + + printf(" signal:%d\n", orc[i].signal); +} + void orc_print_reg(unsigned int reg, int offset) { if (reg == ORC_REG_UNDEFINED) diff --git a/tools/objtool/arch/x86/Build b/tools/objtool/arch/x86/Build index 9f7869b5c5e0..3dedb2fd8f3a 100644 --- a/tools/objtool/arch/x86/Build +++ b/tools/objtool/arch/x86/Build @@ -1,5 +1,6 @@ objtool-y += special.o objtool-y += decode.o +objtool-y += orc.o inat_tables_script = ../arch/x86/tools/gen-insn-attr-x86.awk inat_tables_maps = ../arch/x86/lib/x86-opcode-map.txt diff --git a/tools/objtool/arch/x86/orc.c b/tools/objtool/arch/x86/orc.c new file mode 100644 index 000000000000..b6cd943e87f9 --- /dev/null +++ b/tools/objtool/arch/x86/orc.c @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include +#include + +#include +#include +#include +#include + +int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, struct instruction *insn) +{ + struct cfi_reg *bp = &cfi->regs[CFI_BP]; + + memset(orc, 0, sizeof(*orc)); + + if (!cfi) { + /* + * This is usually either unreachable nops/traps (which don't + * trigger unreachable instruction warnings), or + * STACK_FRAME_NON_STANDARD functions. + */ + orc->type = ORC_TYPE_UNDEFINED; + return 0; + } + + switch (cfi->type) { + case UNWIND_HINT_TYPE_UNDEFINED: + orc->type = ORC_TYPE_UNDEFINED; + return 0; + case UNWIND_HINT_TYPE_END_OF_STACK: + orc->type = ORC_TYPE_END_OF_STACK; + return 0; + case UNWIND_HINT_TYPE_CALL: + orc->type = ORC_TYPE_CALL; + break; + case UNWIND_HINT_TYPE_REGS: + orc->type = ORC_TYPE_REGS; + break; + case UNWIND_HINT_TYPE_REGS_PARTIAL: + orc->type = ORC_TYPE_REGS_PARTIAL; + break; + default: + WARN_INSN(insn, "unknown unwind hint type %d", cfi->type); + return -1; + } + + orc->signal = cfi->signal; + + switch (cfi->cfa.base) { + case CFI_SP: + orc->sp_reg = ORC_REG_SP; + break; + case CFI_SP_INDIRECT: + orc->sp_reg = ORC_REG_SP_INDIRECT; + break; + case CFI_BP: + orc->sp_reg = ORC_REG_BP; + break; + case CFI_BP_INDIRECT: + orc->sp_reg = ORC_REG_BP_INDIRECT; + break; + case CFI_R10: + orc->sp_reg = ORC_REG_R10; + break; + case CFI_R13: + orc->sp_reg = ORC_REG_R13; + break; + case CFI_DI: + orc->sp_reg = ORC_REG_DI; + break; + case CFI_DX: + orc->sp_reg = ORC_REG_DX; + break; + default: + WARN_INSN(insn, "unknown CFA base reg %d", cfi->cfa.base); + return -1; + } + + switch (bp->base) { + case CFI_UNDEFINED: + orc->bp_reg = ORC_REG_UNDEFINED; + break; + case CFI_CFA: + orc->bp_reg = ORC_REG_PREV_SP; + break; + case CFI_BP: + orc->bp_reg = ORC_REG_BP; + break; + default: + WARN_INSN(insn, "unknown BP base reg %d", bp->base); + return -1; + } + + orc->sp_offset = cfi->cfa.offset; + orc->bp_offset = bp->offset; + + return 0; +} + +int write_orc_entry(struct elf *elf, struct section *orc_sec, + struct section *ip_sec, unsigned int idx, + struct section *insn_sec, unsigned long insn_off, + struct orc_entry *o) +{ + struct orc_entry *orc; + + /* populate ORC data */ + orc = (struct orc_entry *)orc_sec->data->d_buf + idx; + memcpy(orc, o, sizeof(*orc)); + orc->sp_offset = bswap_if_needed(elf, orc->sp_offset); + orc->bp_offset = bswap_if_needed(elf, orc->bp_offset); + + /* populate reloc for ip */ + if (!elf_init_reloc_text_sym(elf, ip_sec, idx * sizeof(int), idx, + insn_sec, insn_off)) + return -1; + + return 0; +} + +static const char *reg_name(unsigned int reg) +{ + switch (reg) { + case ORC_REG_PREV_SP: + return "prevsp"; + case ORC_REG_DX: + return "dx"; + case ORC_REG_DI: + return "di"; + case ORC_REG_BP: + return "bp"; + case ORC_REG_SP: + return "sp"; + case ORC_REG_R10: + return "r10"; + case ORC_REG_R13: + return "r13"; + case ORC_REG_BP_INDIRECT: + return "bp(ind)"; + case ORC_REG_SP_INDIRECT: + return "sp(ind)"; + default: + return "?"; + } +} + +static const char *orc_type_name(unsigned int type) +{ + switch (type) { + case ORC_TYPE_UNDEFINED: + return "(und)"; + case ORC_TYPE_END_OF_STACK: + return "end"; + case ORC_TYPE_CALL: + return "call"; + case ORC_TYPE_REGS: + return "regs"; + case ORC_TYPE_REGS_PARTIAL: + return "regs (partial)"; + default: + return "?"; + } +} + +static void print_reg(unsigned int reg, int offset) +{ + if (reg == ORC_REG_BP_INDIRECT) + printf("(bp%+d)", offset); + else if (reg == ORC_REG_SP_INDIRECT) + printf("(sp)%+d", offset); + else if (reg == ORC_REG_UNDEFINED) + printf("(und)"); + else + printf("%s%+d", reg_name(reg), offset); +} + +void orc_print_dump(struct elf *dummy_elf, struct orc_entry *orc, int i) +{ + printf("type:%s", orc_type_name(orc[i].type)); + + printf(" sp:"); + print_reg(orc[i].sp_reg, bswap_if_needed(dummy_elf, orc[i].sp_offset)); + + printf(" bp:"); + print_reg(orc[i].bp_reg, bswap_if_needed(dummy_elf, orc[i].bp_offset)); + + printf(" signal:%d\n", orc[i].signal); +} diff --git a/tools/objtool/include/objtool/orc.h b/tools/objtool/include/objtool/orc.h new file mode 100644 index 000000000000..88dc98a2b8a4 --- /dev/null +++ b/tools/objtool/include/objtool/orc.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2015-2017 Josh Poimboeuf + */ + +#ifndef _OBJTOOL_ORC_H +#define _OBJTOOL_ORC_H + +#include +#include + +int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, + struct instruction *insn); +void orc_print_dump(struct elf *dummy_elf, struct orc_entry *orc, int i); +int write_orc_entry(struct elf *elf, struct section *orc_sec, + struct section *ip_sec, unsigned int idx, + struct section *insn_sec, unsigned long insn_off, + struct orc_entry *o); + +#endif /* _OBJTOOL_ORC_H */ diff --git a/tools/objtool/orc_dump.c b/tools/objtool/orc_dump.c index 0e183bb1c720..a62247efb64f 100644 --- a/tools/objtool/orc_dump.c +++ b/tools/objtool/orc_dump.c @@ -6,65 +6,10 @@ #include #include #include +#include #include #include -static const char *reg_name(unsigned int reg) -{ - switch (reg) { - case ORC_REG_PREV_SP: - return "prevsp"; - case ORC_REG_DX: - return "dx"; - case ORC_REG_DI: - return "di"; - case ORC_REG_BP: - return "bp"; - case ORC_REG_SP: - return "sp"; - case ORC_REG_R10: - return "r10"; - case ORC_REG_R13: - return "r13"; - case ORC_REG_BP_INDIRECT: - return "bp(ind)"; - case ORC_REG_SP_INDIRECT: - return "sp(ind)"; - default: - return "?"; - } -} - -static const char *orc_type_name(unsigned int type) -{ - switch (type) { - case ORC_TYPE_UNDEFINED: - return "(und)"; - case ORC_TYPE_END_OF_STACK: - return "end"; - case ORC_TYPE_CALL: - return "call"; - case ORC_TYPE_REGS: - return "regs"; - case ORC_TYPE_REGS_PARTIAL: - return "regs (partial)"; - default: - return "?"; - } -} - -static void print_reg(unsigned int reg, int offset) -{ - if (reg == ORC_REG_BP_INDIRECT) - printf("(bp%+d)", offset); - else if (reg == ORC_REG_SP_INDIRECT) - printf("(sp)%+d", offset); - else if (reg == ORC_REG_UNDEFINED) - printf("(und)"); - else - printf("%s%+d", reg_name(reg), offset); -} - int orc_dump(const char *_objname) { int fd, nr_entries, i, *orc_ip = NULL, orc_size = 0; @@ -205,17 +150,7 @@ int orc_dump(const char *_objname) printf("%llx:", (unsigned long long)(orc_ip_addr + (i * sizeof(int)) + orc_ip[i])); } - printf("type:%s", orc_type_name(orc[i].type)); - - printf(" sp:"); - - print_reg(orc[i].sp_reg, bswap_if_needed(&dummy_elf, orc[i].sp_offset)); - - printf(" bp:"); - - print_reg(orc[i].bp_reg, bswap_if_needed(&dummy_elf, orc[i].bp_offset)); - - printf(" signal:%d\n", orc[i].signal); + orc_print_dump(&dummy_elf, orc, i); } elf_end(elf); diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c index cfa01f43edd6..71cdbb5fe138 100644 --- a/tools/objtool/orc_gen.c +++ b/tools/objtool/orc_gen.c @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -18,118 +19,6 @@ bool __weak orc_ignore_section(struct section *sec) return false; } -static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, - struct instruction *insn) -{ - struct cfi_reg *bp = &cfi->regs[CFI_BP]; - - memset(orc, 0, sizeof(*orc)); - - if (!cfi) { - /* - * This is usually either unreachable nops/traps (which don't - * trigger unreachable instruction warnings), or - * STACK_FRAME_NON_STANDARD functions. - */ - orc->type = ORC_TYPE_UNDEFINED; - return 0; - } - - switch (cfi->type) { - case UNWIND_HINT_TYPE_UNDEFINED: - orc->type = ORC_TYPE_UNDEFINED; - return 0; - case UNWIND_HINT_TYPE_END_OF_STACK: - orc->type = ORC_TYPE_END_OF_STACK; - return 0; - case UNWIND_HINT_TYPE_CALL: - orc->type = ORC_TYPE_CALL; - break; - case UNWIND_HINT_TYPE_REGS: - orc->type = ORC_TYPE_REGS; - break; - case UNWIND_HINT_TYPE_REGS_PARTIAL: - orc->type = ORC_TYPE_REGS_PARTIAL; - break; - default: - WARN_INSN(insn, "unknown unwind hint type %d", cfi->type); - return -1; - } - - orc->signal = cfi->signal; - - switch (cfi->cfa.base) { - case CFI_SP: - orc->sp_reg = ORC_REG_SP; - break; - case CFI_SP_INDIRECT: - orc->sp_reg = ORC_REG_SP_INDIRECT; - break; - case CFI_BP: - orc->sp_reg = ORC_REG_BP; - break; - case CFI_BP_INDIRECT: - orc->sp_reg = ORC_REG_BP_INDIRECT; - break; - case CFI_R10: - orc->sp_reg = ORC_REG_R10; - break; - case CFI_R13: - orc->sp_reg = ORC_REG_R13; - break; - case CFI_DI: - orc->sp_reg = ORC_REG_DI; - break; - case CFI_DX: - orc->sp_reg = ORC_REG_DX; - break; - default: - WARN_INSN(insn, "unknown CFA base reg %d", cfi->cfa.base); - return -1; - } - - switch (bp->base) { - case CFI_UNDEFINED: - orc->bp_reg = ORC_REG_UNDEFINED; - break; - case CFI_CFA: - orc->bp_reg = ORC_REG_PREV_SP; - break; - case CFI_BP: - orc->bp_reg = ORC_REG_BP; - break; - default: - WARN_INSN(insn, "unknown BP base reg %d", bp->base); - return -1; - } - - orc->sp_offset = cfi->cfa.offset; - orc->bp_offset = bp->offset; - - return 0; -} - -static int write_orc_entry(struct elf *elf, struct section *orc_sec, - struct section *ip_sec, unsigned int idx, - struct section *insn_sec, unsigned long insn_off, - struct orc_entry *o) -{ - struct orc_entry *orc; - - /* populate ORC data */ - orc = (struct orc_entry *)orc_sec->data->d_buf + idx; - memcpy(orc, o, sizeof(*orc)); - orc->sp_offset = bswap_if_needed(elf, orc->sp_offset); - orc->fp_offset = bswap_if_needed(elf, orc->fp_offset); - - /* populate reloc for ip */ - if (!elf_init_reloc_text_sym(elf, ip_sec, idx * sizeof(int), idx, - insn_sec, insn_off)) - return -1; - - return 0; -} - struct orc_list_entry { struct list_head list; struct orc_entry orc; -- Gitee From c5a254d52bb7ba01b6d3074303c1122aff6ed67c Mon Sep 17 00:00:00 2001 From: Jia He Date: Wed, 30 Oct 2024 01:21:08 +0000 Subject: [PATCH 07/13] Revert "objtool: Reorganize ORC types" ANBZ: #11595 cherry-picked from https://lore.kernel.org/lkml/20230202074036.507249-1-madvenka@linux.microsoft.com/ This reverts commit 4c76014d8319006bf2c1a27896f4aa262cc19f25. To support livepatch features on other architectures, it's preferable to keep the Anolis livepatch code layout closely aligned with the upstream kernel. Therefore, we should revert the commits that reorganized the code specifically for arm64 livepatch support. Signed-off-by: Jia He --- arch/x86/include/asm/orc_types.h | 37 +++++++++++++++++++++----- tools/arch/x86/include/asm/orc_types.h | 37 +++++++++++++++++++++----- tools/objtool/orc_gen.c | 6 ++++- tools/objtool/sync-check.sh | 1 - 4 files changed, 65 insertions(+), 16 deletions(-) diff --git a/arch/x86/include/asm/orc_types.h b/arch/x86/include/asm/orc_types.h index 45f21662ac21..46d7e06763c9 100644 --- a/arch/x86/include/asm/orc_types.h +++ b/arch/x86/include/asm/orc_types.h @@ -8,13 +8,6 @@ #include #include -#include - -/* - * For x86, use the appripriate name for the frame pointer in orc_entry. - */ -#define bp_offset fp_offset -#define bp_reg fp_reg /* * The ORC_REG_* registers are base registers which are used to find other @@ -52,4 +45,34 @@ #define ORC_TYPE_REGS 3 #define ORC_TYPE_REGS_PARTIAL 4 +#ifndef __ASSEMBLY__ +#include + +/* + * This struct is more or less a vastly simplified version of the DWARF Call + * Frame Information standard. It contains only the necessary parts of DWARF + * CFI, simplified for ease of access by the in-kernel unwinder. It tells the + * unwinder how to find the previous SP and BP (and sometimes entry regs) on + * the stack for a given code address. Each instance of the struct corresponds + * to one or more code locations. + */ +struct orc_entry { + s16 sp_offset; + s16 bp_offset; +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned sp_reg:4; + unsigned bp_reg:4; + unsigned type:3; + unsigned signal:1; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned bp_reg:4; + unsigned sp_reg:4; + unsigned unused:4; + unsigned signal:1; + unsigned type:3; +#endif +} __packed; + +#endif /* __ASSEMBLY__ */ + #endif /* _ORC_TYPES_H */ diff --git a/tools/arch/x86/include/asm/orc_types.h b/tools/arch/x86/include/asm/orc_types.h index 45f21662ac21..46d7e06763c9 100644 --- a/tools/arch/x86/include/asm/orc_types.h +++ b/tools/arch/x86/include/asm/orc_types.h @@ -8,13 +8,6 @@ #include #include -#include - -/* - * For x86, use the appripriate name for the frame pointer in orc_entry. - */ -#define bp_offset fp_offset -#define bp_reg fp_reg /* * The ORC_REG_* registers are base registers which are used to find other @@ -52,4 +45,34 @@ #define ORC_TYPE_REGS 3 #define ORC_TYPE_REGS_PARTIAL 4 +#ifndef __ASSEMBLY__ +#include + +/* + * This struct is more or less a vastly simplified version of the DWARF Call + * Frame Information standard. It contains only the necessary parts of DWARF + * CFI, simplified for ease of access by the in-kernel unwinder. It tells the + * unwinder how to find the previous SP and BP (and sometimes entry regs) on + * the stack for a given code address. Each instance of the struct corresponds + * to one or more code locations. + */ +struct orc_entry { + s16 sp_offset; + s16 bp_offset; +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned sp_reg:4; + unsigned bp_reg:4; + unsigned type:3; + unsigned signal:1; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned bp_reg:4; + unsigned sp_reg:4; + unsigned unused:4; + unsigned signal:1; + unsigned type:3; +#endif +} __packed; + +#endif /* __ASSEMBLY__ */ + #endif /* _ORC_TYPES_H */ diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c index 71cdbb5fe138..217a4e7d5617 100644 --- a/tools/objtool/orc_gen.c +++ b/tools/objtool/orc_gen.c @@ -14,6 +14,10 @@ #include #include +#ifdef __aarch64__ +#define bp_reg fp_reg +#endif + bool __weak orc_ignore_section(struct section *sec) { return false; @@ -59,7 +63,7 @@ int orc_create(struct objtool_file *file) struct list_head orc_list; struct orc_entry null = { - .fp_reg = ORC_REG_UNDEFINED, + .bp_reg = ORC_REG_UNDEFINED, .type = UNWIND_HINT_TYPE_CALL, }; diff --git a/tools/objtool/sync-check.sh b/tools/objtool/sync-check.sh index 9bacf219bfe0..d75b494e010d 100755 --- a/tools/objtool/sync-check.sh +++ b/tools/objtool/sync-check.sh @@ -18,7 +18,6 @@ arch/x86/include/asm/unwind_hints.h arch/x86/lib/x86-opcode-map.txt arch/x86/tools/gen-insn-attr-x86.awk include/linux/static_call_types.h -include/linux/orc_entry.h " SYNC_CHECK_FILES=' -- Gitee From cba34249de6e6e93d70c931c008f85748a3db92d Mon Sep 17 00:00:00 2001 From: Jia He Date: Wed, 30 Oct 2024 10:30:18 +0000 Subject: [PATCH 08/13] Revert "objtool: Reorganize Unwind hint code" ANBZ: #11595 cherry-picked from https://lore.kernel.org/lkml/20230202074036.507249-1-madvenka@linux.microsoft.com/ This reverts commit b3416886ab7d17d03b7e6501cb816daa760b0b89. To support livepatch features on other architectures, it's preferable to keep the Anolis livepatch code layout closely aligned with the upstream kernel. Therefore, we should revert the commits that reorganized the code specifically for arm64 livepatch support. Signed-off-by: Jia He --- arch/x86/entry/entry.S | 1 - arch/x86/include/asm/unwind_hints.h | 67 +------- arch/x86/kernel/unwind_orc.c | 3 +- include/linux/objtool.h | 49 ++++++ tools/arch/x86/include/asm/unwind_hints.h | 158 ------------------ tools/objtool/Build | 1 - tools/objtool/arch/arm64/Build | 1 + tools/objtool/{ => arch/arm64}/unwind_hints.c | 0 tools/objtool/check.c | 91 ++++++++++ tools/objtool/include/objtool/insn.h | 3 + tools/objtool/sync-check.sh | 1 - 11 files changed, 146 insertions(+), 229 deletions(-) delete mode 100644 tools/arch/x86/include/asm/unwind_hints.h rename tools/objtool/{ => arch/arm64}/unwind_hints.c (100%) diff --git a/arch/x86/entry/entry.S b/arch/x86/entry/entry.S index f6f6af24e569..718c00367f9a 100644 --- a/arch/x86/entry/entry.S +++ b/arch/x86/entry/entry.S @@ -4,7 +4,6 @@ */ #include -#include #include #include #include diff --git a/arch/x86/include/asm/unwind_hints.h b/arch/x86/include/asm/unwind_hints.h index 196b82f806e4..85cc57cb6539 100644 --- a/arch/x86/include/asm/unwind_hints.h +++ b/arch/x86/include/asm/unwind_hints.h @@ -1,75 +1,10 @@ #ifndef _ASM_X86_UNWIND_HINTS_H #define _ASM_X86_UNWIND_HINTS_H -#include +#include #include "orc_types.h" -#ifdef CONFIG_OBJTOOL - -#ifndef __ASSEMBLY__ - -#define UNWIND_HINT(type, sp_reg, sp_offset, signal) \ - "987: \n\t" \ - ".pushsection .discard.unwind_hints\n\t" \ - /* struct unwind_hint */ \ - ".long 987b - .\n\t" \ - ".short " __stringify(sp_offset) "\n\t" \ - ".byte " __stringify(sp_reg) "\n\t" \ - ".byte " __stringify(type) "\n\t" \ - ".byte " __stringify(signal) "\n\t" \ - ".balign 4 \n\t" \ - ".popsection\n\t" - -#else /* __ASSEMBLY__ */ - -/* - * In asm, there are two kinds of code: normal C-type callable functions and - * the rest. The normal callable functions can be called by other code, and - * don't do anything unusual with the stack. Such normal callable functions - * are annotated with the ENTRY/ENDPROC macros. Most asm code falls in this - * category. In this case, no special debugging annotations are needed because - * objtool can automatically generate the ORC data for the ORC unwinder to read - * at runtime. - * - * Anything which doesn't fall into the above category, such as syscall and - * interrupt handlers, tends to not be called directly by other functions, and - * often does unusual non-C-function-type things with the stack pointer. Such - * code needs to be annotated such that objtool can understand it. The - * following CFI hint macros are for this type of code. - * - * These macros provide hints to objtool about the state of the stack at each - * instruction. Objtool starts from the hints and follows the code flow, - * making automatic CFI adjustments when it sees pushes and pops, filling out - * the debuginfo as necessary. It will also warn if it sees any - * inconsistencies. - */ -.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 -.Lhere_\@: - .pushsection .discard.unwind_hints - /* struct unwind_hint */ - .long .Lhere_\@ - . - .short \sp_offset - .byte \sp_reg - .byte \type - .byte \signal - .balign 4 - .popsection -.endm - -#endif /* __ASSEMBLY__ */ - -#else /* !CONFIG_OBJTOOL */ - -#ifndef __ASSEMBLY__ -#define UNWIND_HINT(type, sp_reg, sp_offset, signal) "\n\t" -#else -.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 -.endm -#endif - -#endif /* CONFIG_OBJTOOL */ - #ifdef __ASSEMBLY__ .macro UNWIND_HINT_END_OF_STACK diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c index c79360196365..7e574cf3bf8a 100644 --- a/arch/x86/kernel/unwind_orc.c +++ b/arch/x86/kernel/unwind_orc.c @@ -1,11 +1,10 @@ // SPDX-License-Identifier: GPL-2.0-only -#include #include +#include #include #include #include #include -#include #include #include #include diff --git a/include/linux/objtool.h b/include/linux/objtool.h index 865caa2d1232..ac959bbbffd5 100644 --- a/include/linux/objtool.h +++ b/include/linux/objtool.h @@ -12,6 +12,18 @@ #ifndef __ASSEMBLY__ +#define UNWIND_HINT(type, sp_reg, sp_offset, signal) \ + "987: \n\t" \ + ".pushsection .discard.unwind_hints\n\t" \ + /* struct unwind_hint */ \ + ".long 987b - .\n\t" \ + ".short " __stringify(sp_offset) "\n\t" \ + ".byte " __stringify(sp_reg) "\n\t" \ + ".byte " __stringify(type) "\n\t" \ + ".byte " __stringify(signal) "\n\t" \ + ".balign 4 \n\t" \ + ".popsection\n\t" + /* * This macro marks the given function's stack frame as "non-standard", which * tells objtool to ignore the function when doing stack metadata validation. @@ -59,6 +71,40 @@ .long 999b; \ .popsection; +/* + * In asm, there are two kinds of code: normal C-type callable functions and + * the rest. The normal callable functions can be called by other code, and + * don't do anything unusual with the stack. Such normal callable functions + * are annotated with the ENTRY/ENDPROC macros. Most asm code falls in this + * category. In this case, no special debugging annotations are needed because + * objtool can automatically generate the ORC data for the ORC unwinder to read + * at runtime. + * + * Anything which doesn't fall into the above category, such as syscall and + * interrupt handlers, tends to not be called directly by other functions, and + * often does unusual non-C-function-type things with the stack pointer. Such + * code needs to be annotated such that objtool can understand it. The + * following CFI hint macros are for this type of code. + * + * These macros provide hints to objtool about the state of the stack at each + * instruction. Objtool starts from the hints and follows the code flow, + * making automatic CFI adjustments when it sees pushes and pops, filling out + * the debuginfo as necessary. It will also warn if it sees any + * inconsistencies. + */ +.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 +.Lhere_\@: + .pushsection .discard.unwind_hints + /* struct unwind_hint */ + .long .Lhere_\@ - . + .short \sp_offset + .byte \sp_reg + .byte \type + .byte \signal + .balign 4 + .popsection +.endm + .macro STACK_FRAME_NON_STANDARD func:req .pushsection .discard.func_stack_frame_non_standard, "aw" .long \func - . @@ -108,12 +154,15 @@ #ifndef __ASSEMBLY__ +#define UNWIND_HINT(type, sp_reg, sp_offset, signal) "\n\t" #define STACK_FRAME_NON_STANDARD(func) #define STACK_FRAME_NON_STANDARD_FP(func) #define ANNOTATE_NOENDBR #define ASM_REACHABLE #else #define ANNOTATE_INTRA_FUNCTION_CALL +.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 +.endm .macro STACK_FRAME_NON_STANDARD func:req .endm .macro ANNOTATE_NOENDBR diff --git a/tools/arch/x86/include/asm/unwind_hints.h b/tools/arch/x86/include/asm/unwind_hints.h deleted file mode 100644 index 196b82f806e4..000000000000 --- a/tools/arch/x86/include/asm/unwind_hints.h +++ /dev/null @@ -1,158 +0,0 @@ -#ifndef _ASM_X86_UNWIND_HINTS_H -#define _ASM_X86_UNWIND_HINTS_H - -#include - -#include "orc_types.h" - -#ifdef CONFIG_OBJTOOL - -#ifndef __ASSEMBLY__ - -#define UNWIND_HINT(type, sp_reg, sp_offset, signal) \ - "987: \n\t" \ - ".pushsection .discard.unwind_hints\n\t" \ - /* struct unwind_hint */ \ - ".long 987b - .\n\t" \ - ".short " __stringify(sp_offset) "\n\t" \ - ".byte " __stringify(sp_reg) "\n\t" \ - ".byte " __stringify(type) "\n\t" \ - ".byte " __stringify(signal) "\n\t" \ - ".balign 4 \n\t" \ - ".popsection\n\t" - -#else /* __ASSEMBLY__ */ - -/* - * In asm, there are two kinds of code: normal C-type callable functions and - * the rest. The normal callable functions can be called by other code, and - * don't do anything unusual with the stack. Such normal callable functions - * are annotated with the ENTRY/ENDPROC macros. Most asm code falls in this - * category. In this case, no special debugging annotations are needed because - * objtool can automatically generate the ORC data for the ORC unwinder to read - * at runtime. - * - * Anything which doesn't fall into the above category, such as syscall and - * interrupt handlers, tends to not be called directly by other functions, and - * often does unusual non-C-function-type things with the stack pointer. Such - * code needs to be annotated such that objtool can understand it. The - * following CFI hint macros are for this type of code. - * - * These macros provide hints to objtool about the state of the stack at each - * instruction. Objtool starts from the hints and follows the code flow, - * making automatic CFI adjustments when it sees pushes and pops, filling out - * the debuginfo as necessary. It will also warn if it sees any - * inconsistencies. - */ -.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 -.Lhere_\@: - .pushsection .discard.unwind_hints - /* struct unwind_hint */ - .long .Lhere_\@ - . - .short \sp_offset - .byte \sp_reg - .byte \type - .byte \signal - .balign 4 - .popsection -.endm - -#endif /* __ASSEMBLY__ */ - -#else /* !CONFIG_OBJTOOL */ - -#ifndef __ASSEMBLY__ -#define UNWIND_HINT(type, sp_reg, sp_offset, signal) "\n\t" -#else -.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 -.endm -#endif - -#endif /* CONFIG_OBJTOOL */ - -#ifdef __ASSEMBLY__ - -.macro UNWIND_HINT_END_OF_STACK - UNWIND_HINT type=UNWIND_HINT_TYPE_END_OF_STACK -.endm - -.macro UNWIND_HINT_UNDEFINED - UNWIND_HINT type=UNWIND_HINT_TYPE_UNDEFINED -.endm - -.macro UNWIND_HINT_ENTRY - VALIDATE_UNRET_BEGIN - UNWIND_HINT_END_OF_STACK -.endm - -.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0 signal=1 - .if \base == %rsp - .if \indirect - .set sp_reg, ORC_REG_SP_INDIRECT - .else - .set sp_reg, ORC_REG_SP - .endif - .elseif \base == %rbp - .set sp_reg, ORC_REG_BP - .elseif \base == %rdi - .set sp_reg, ORC_REG_DI - .elseif \base == %rdx - .set sp_reg, ORC_REG_DX - .elseif \base == %r10 - .set sp_reg, ORC_REG_R10 - .else - .error "UNWIND_HINT_REGS: bad base register" - .endif - - .set sp_offset, \offset - - .if \partial - .set type, UNWIND_HINT_TYPE_REGS_PARTIAL - .elseif \extra == 0 - .set type, UNWIND_HINT_TYPE_REGS_PARTIAL - .set sp_offset, \offset + (16*8) - .else - .set type, UNWIND_HINT_TYPE_REGS - .endif - - UNWIND_HINT sp_reg=sp_reg sp_offset=sp_offset type=type signal=\signal -.endm - -.macro UNWIND_HINT_IRET_REGS base=%rsp offset=0 signal=1 - UNWIND_HINT_REGS base=\base offset=\offset partial=1 signal=\signal -.endm - -.macro UNWIND_HINT_IRET_ENTRY base=%rsp offset=0 signal=1 - VALIDATE_UNRET_BEGIN - UNWIND_HINT_IRET_REGS base=\base offset=\offset signal=\signal -.endm - -.macro UNWIND_HINT_FUNC - UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=8 type=UNWIND_HINT_TYPE_FUNC -.endm - -.macro UNWIND_HINT_SAVE - UNWIND_HINT type=UNWIND_HINT_TYPE_SAVE -.endm - -.macro UNWIND_HINT_RESTORE - UNWIND_HINT type=UNWIND_HINT_TYPE_RESTORE -.endm - -#else - -#define UNWIND_HINT_UNDEFINED \ - UNWIND_HINT(UNWIND_HINT_TYPE_UNDEFINED, 0, 0, 0) - -#define UNWIND_HINT_FUNC \ - UNWIND_HINT(UNWIND_HINT_TYPE_FUNC, ORC_REG_SP, 8, 0) - -#define UNWIND_HINT_SAVE \ - UNWIND_HINT(UNWIND_HINT_TYPE_SAVE, 0, 0, 0) - -#define UNWIND_HINT_RESTORE \ - UNWIND_HINT(UNWIND_HINT_TYPE_RESTORE, 0, 0, 0) - -#endif /* __ASSEMBLY__ */ - -#endif /* _ASM_X86_UNWIND_HINTS_H */ diff --git a/tools/objtool/Build b/tools/objtool/Build index 9da7ebdae86c..e0a4685ac7a3 100644 --- a/tools/objtool/Build +++ b/tools/objtool/Build @@ -9,7 +9,6 @@ objtool-y += builtin-check.o objtool-y += cfi.o objtool-y += insn.o objtool-y += decode.o -objtool-y += unwind_hints.o objtool-y += elf.o objtool-y += objtool.o diff --git a/tools/objtool/arch/arm64/Build b/tools/objtool/arch/arm64/Build index 8615abfb12cf..77619e7ef476 100644 --- a/tools/objtool/arch/arm64/Build +++ b/tools/objtool/arch/arm64/Build @@ -1,2 +1,3 @@ objtool-y += decode.o objtool-y += orc.o +objtool-y += unwind_hints.o diff --git a/tools/objtool/unwind_hints.c b/tools/objtool/arch/arm64/unwind_hints.c similarity index 100% rename from tools/objtool/unwind_hints.c rename to tools/objtool/arch/arm64/unwind_hints.c diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 68bc4d8b3ca5..09384fafe862 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1814,6 +1814,97 @@ static int add_jump_table_alts(struct objtool_file *file) return 0; } +static int read_unwind_hints(struct objtool_file *file) +{ + struct cfi_state cfi = init_cfi; + struct section *sec; + struct unwind_hint *hint; + struct instruction *insn; + struct reloc *reloc; + int i; + + sec = find_section_by_name(file->elf, ".discard.unwind_hints"); + if (!sec) + return 0; + + if (!sec->rsec) { + WARN("missing .rela.discard.unwind_hints section"); + return -1; + } + + if (sec->sh.sh_size % sizeof(struct unwind_hint)) { + WARN("struct unwind_hint size mismatch"); + return -1; + } + + file->hints = true; + + for (i = 0; i < sec->sh.sh_size / sizeof(struct unwind_hint); i++) { + hint = (struct unwind_hint *)sec->data->d_buf + i; + + reloc = find_reloc_by_dest(file->elf, sec, i * sizeof(*hint)); + if (!reloc) { + WARN("can't find reloc for unwind_hints[%d]", i); + return -1; + } + + insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc)); + if (!insn) { + WARN("can't find insn for unwind_hints[%d]", i); + return -1; + } + + insn->hint = true; + + if (hint->type == UNWIND_HINT_TYPE_UNDEFINED) { + insn->cfi = &force_undefined_cfi; + continue; + } + + if (hint->type == UNWIND_HINT_TYPE_SAVE) { + insn->hint = false; + insn->save = true; + continue; + } + + if (hint->type == UNWIND_HINT_TYPE_RESTORE) { + insn->restore = true; + continue; + } + + if (hint->type == UNWIND_HINT_TYPE_REGS_PARTIAL) { + struct symbol *sym = find_symbol_by_offset(insn->sec, insn->offset); + + if (sym && sym->bind == STB_GLOBAL) { + if (opts.ibt && insn->type != INSN_ENDBR && !insn->noendbr) { + WARN_INSN(insn, "UNWIND_HINT_IRET_REGS without ENDBR"); + } + } + } + + if (hint->type == UNWIND_HINT_TYPE_FUNC) { + insn->cfi = &func_cfi; + continue; + } + + if (insn->cfi) + cfi = *(insn->cfi); + + if (arch_decode_hint_reg(hint->sp_reg, &cfi.cfa.base)) { + WARN_INSN(insn, "unsupported unwind_hint sp base reg %d", hint->sp_reg); + return -1; + } + + cfi.cfa.offset = bswap_if_needed(file->elf, hint->sp_offset); + cfi.type = hint->type; + cfi.signal = hint->signal; + + insn->cfi = cfi_hash_find_or_add(&cfi); + } + + return 0; +} + static int read_noendbr_hints(struct objtool_file *file) { struct instruction *insn; diff --git a/tools/objtool/include/objtool/insn.h b/tools/objtool/include/objtool/insn.h index d19cd2c12f06..d1e877095541 100644 --- a/tools/objtool/include/objtool/insn.h +++ b/tools/objtool/include/objtool/insn.h @@ -111,7 +111,10 @@ bool is_first_func_insn(struct objtool_file *file, struct instruction *insn, struct symbol *sym); int decode_instructions(struct objtool_file *file); +/* temporily add for revert */ +#ifdef __aarch64__ int read_unwind_hints(struct objtool_file *file); +#endif #define sec_for_each_insn(file, _sec, insn) \ for (insn = find_insn(file, _sec, 0); \ diff --git a/tools/objtool/sync-check.sh b/tools/objtool/sync-check.sh index d75b494e010d..b06b5b881121 100755 --- a/tools/objtool/sync-check.sh +++ b/tools/objtool/sync-check.sh @@ -14,7 +14,6 @@ arch/x86/include/asm/nops.h arch/x86/include/asm/inat_types.h arch/x86/include/asm/orc_types.h arch/x86/include/asm/emulate_prefix.h -arch/x86/include/asm/unwind_hints.h arch/x86/lib/x86-opcode-map.txt arch/x86/tools/gen-insn-attr-x86.awk include/linux/static_call_types.h -- Gitee From a6e7fe6d3997eb86bcc22aa75c659569d2b50bc9 Mon Sep 17 00:00:00 2001 From: Jia He Date: Wed, 30 Oct 2024 10:55:15 +0000 Subject: [PATCH 09/13] Revert "objtool: Move decode_instructions() to a separate file" ANBZ: #11595 cherry-picked from https://lore.kernel.org/lkml/20230202074036.507249-1-madvenka@linux.microsoft.com/ This reverts commit 9ec25e3e74653d228e00dfb7d816919ec5003d27. To support livepatch features on other architectures, it's preferable to keep the Anolis livepatch code layout closely aligned with the upstream kernel. Therefore, we should revert the commits that reorganized the code specifically for arm64 livepatch support. Signed-off-by: Jia He --- arch/x86/coco/tdx/tdcall.S | 1 - tools/objtool/Build | 1 - tools/objtool/arch/arm64/decode.c | 129 +++++++++++++++++++++++++ tools/objtool/check.c | 126 +++++++++++++++++++++++++ tools/objtool/decode.c | 136 --------------------------- tools/objtool/include/objtool/insn.h | 3 +- 6 files changed, 256 insertions(+), 140 deletions(-) delete mode 100644 tools/objtool/decode.c diff --git a/arch/x86/coco/tdx/tdcall.S b/arch/x86/coco/tdx/tdcall.S index b021281958fe..2eca5f43734f 100644 --- a/arch/x86/coco/tdx/tdcall.S +++ b/arch/x86/coco/tdx/tdcall.S @@ -7,7 +7,6 @@ #include #include #include -#include #include "../../virt/vmx/tdx/tdxcall.S" diff --git a/tools/objtool/Build b/tools/objtool/Build index e0a4685ac7a3..9d934bf1ceee 100644 --- a/tools/objtool/Build +++ b/tools/objtool/Build @@ -8,7 +8,6 @@ objtool-$(DYNAMIC_CHECK) += dcheck.o objtool-y += builtin-check.o objtool-y += cfi.o objtool-y += insn.o -objtool-y += decode.o objtool-y += elf.o objtool-y += objtool.o diff --git a/tools/objtool/arch/arm64/decode.c b/tools/objtool/arch/arm64/decode.c index 19ef9b22a734..28a972eb9976 100644 --- a/tools/objtool/arch/arm64/decode.c +++ b/tools/objtool/arch/arm64/decode.c @@ -13,12 +13,16 @@ #include #include +#include #include #include +#include #include #include +unsigned long nr_insns; + /* ARM64 instructions are all 4 bytes wide. */ #define INSN_SIZE 4 @@ -579,3 +583,128 @@ int arch_decode_instruction(struct objtool_file *file, insn->type = var.type; return 0; } + +/* + * Call the arch-specific instruction decoder for all the instructions and add + * them to the global instruction list. + */ +int decode_instructions(struct objtool_file *file) +{ + struct section *sec; + struct symbol *func; + unsigned long offset; + struct instruction *insn; + int ret; + + for_each_sec(file, sec) { + struct instruction *insns = NULL; + u8 prev_len = 0; + u8 idx = 0; + + if (!(sec->sh.sh_flags & SHF_EXECINSTR)) + continue; + + if (strcmp(sec->name, ".altinstr_replacement") && + strcmp(sec->name, ".altinstr_aux") && + strncmp(sec->name, ".discard.", 9)) + sec->text = true; + + if (!strcmp(sec->name, ".noinstr.text") || + !strcmp(sec->name, ".entry.text") || + !strcmp(sec->name, ".cpuidle.text") || + !strncmp(sec->name, ".text..__x86.", 13)) + sec->noinstr = true; + + /* + * .init.text code is ran before userspace and thus doesn't + * strictly need retpolines, except for modules which are + * loaded late, they very much do need retpoline in their + * .init.text + */ + if (!strcmp(sec->name, ".init.text") && !opts.module) + sec->init = true; + + for (offset = 0; offset < sec->sh.sh_size; offset += insn->len) { + if (!insns || idx == INSN_CHUNK_MAX) { + insns = calloc(sizeof(*insn), INSN_CHUNK_SIZE); + if (!insns) { + WARN("malloc failed"); + return -1; + } + idx = 0; + } else { + idx++; + } + insn = &insns[idx]; + insn->idx = idx; + + INIT_LIST_HEAD(&insn->call_node); + insn->sec = sec; + insn->offset = offset; + insn->prev_len = prev_len; + + ret = arch_decode_instruction(file, sec, offset, + sec->sh.sh_size - offset, + insn); + if (ret) + return ret; + + prev_len = insn->len; + + /* + * By default, "ud2" is a dead end unless otherwise + * annotated, because GCC 7 inserts it for certain + * divide-by-zero cases. + */ + if (insn->type == INSN_BUG) + insn->dead_end = true; + + hash_add(file->insn_hash, &insn->hash, sec_offset_hash(sec, insn->offset)); + nr_insns++; + } + +// printf("%s: last chunk used: %d\n", sec->name, (int)idx); + + sec_for_each_sym(sec, func) { + if (func->type != STT_NOTYPE && func->type != STT_FUNC) + continue; + + if (func->offset == sec->sh.sh_size) { + /* Heuristic: likely an "end" symbol */ + if (func->type == STT_NOTYPE) + continue; + WARN("%s(): STT_FUNC at end of section", + func->name); + return -1; + } + + if (func->embedded_insn || func->alias != func) + continue; + + if (!find_insn(file, sec, func->offset)) { + WARN("%s(): can't find starting instruction", + func->name); + return -1; + } + + sym_for_each_insn(file, func, insn) { + insn->sym = func; + if (func->type == STT_FUNC && + insn->type == INSN_ENDBR && + list_empty(&insn->call_node)) { + if (insn->offset == func->offset) { + list_add_tail(&insn->call_node, &file->endbr_list); + file->nr_endbr++; + } else { + file->nr_endbr_int++; + } + } + } + } + } + + if (opts.stats) + printf("nr_insns: %lu\n", nr_insns); + + return 0; +} diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 09384fafe862..f9791097cf18 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -157,8 +157,134 @@ static bool dead_end_function(struct objtool_file *file, struct symbol *func) return __dead_end_function(file, func, 0); } +static unsigned long nr_insns; static unsigned long nr_insns_visited; +/* + * Call the arch-specific instruction decoder for all the instructions and add + * them to the global instruction list. + */ +static int decode_instructions(struct objtool_file *file) +{ + struct section *sec; + struct symbol *func; + unsigned long offset; + struct instruction *insn; + int ret; + + for_each_sec(file, sec) { + struct instruction *insns = NULL; + u8 prev_len = 0; + u8 idx = 0; + + if (!(sec->sh.sh_flags & SHF_EXECINSTR)) + continue; + + if (strcmp(sec->name, ".altinstr_replacement") && + strcmp(sec->name, ".altinstr_aux") && + strncmp(sec->name, ".discard.", 9)) + sec->text = true; + + if (!strcmp(sec->name, ".noinstr.text") || + !strcmp(sec->name, ".entry.text") || + !strcmp(sec->name, ".cpuidle.text") || + !strncmp(sec->name, ".text..__x86.", 13)) + sec->noinstr = true; + + /* + * .init.text code is ran before userspace and thus doesn't + * strictly need retpolines, except for modules which are + * loaded late, they very much do need retpoline in their + * .init.text + */ + if (!strcmp(sec->name, ".init.text") && !opts.module) + sec->init = true; + + for (offset = 0; offset < sec->sh.sh_size; offset += insn->len) { + if (!insns || idx == INSN_CHUNK_MAX) { + insns = calloc(sizeof(*insn), INSN_CHUNK_SIZE); + if (!insns) { + WARN("malloc failed"); + return -1; + } + idx = 0; + } else { + idx++; + } + insn = &insns[idx]; + insn->idx = idx; + + INIT_LIST_HEAD(&insn->call_node); + insn->sec = sec; + insn->offset = offset; + insn->prev_len = prev_len; + + ret = arch_decode_instruction(file, sec, offset, + sec->sh.sh_size - offset, + insn); + if (ret) + return ret; + + prev_len = insn->len; + + /* + * By default, "ud2" is a dead end unless otherwise + * annotated, because GCC 7 inserts it for certain + * divide-by-zero cases. + */ + if (insn->type == INSN_BUG) + insn->dead_end = true; + + hash_add(file->insn_hash, &insn->hash, sec_offset_hash(sec, insn->offset)); + nr_insns++; + } + +// printf("%s: last chunk used: %d\n", sec->name, (int)idx); + + sec_for_each_sym(sec, func) { + if (func->type != STT_NOTYPE && func->type != STT_FUNC) + continue; + + if (func->offset == sec->sh.sh_size) { + /* Heuristic: likely an "end" symbol */ + if (func->type == STT_NOTYPE) + continue; + WARN("%s(): STT_FUNC at end of section", + func->name); + return -1; + } + + if (func->embedded_insn || func->alias != func) + continue; + + if (!find_insn(file, sec, func->offset)) { + WARN("%s(): can't find starting instruction", + func->name); + return -1; + } + + sym_for_each_insn(file, func, insn) { + insn->sym = func; + if (func->type == STT_FUNC && + insn->type == INSN_ENDBR && + list_empty(&insn->call_node)) { + if (insn->offset == func->offset) { + list_add_tail(&insn->call_node, &file->endbr_list); + file->nr_endbr++; + } else { + file->nr_endbr_int++; + } + } + } + } + } + + if (opts.stats) + printf("nr_insns: %lu\n", nr_insns); + + return 0; +} + /* * Read the pv_ops[] .data table to find the static initialized values. */ diff --git a/tools/objtool/decode.c b/tools/objtool/decode.c deleted file mode 100644 index 59fea7e1d35b..000000000000 --- a/tools/objtool/decode.c +++ /dev/null @@ -1,136 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2015-2017 Josh Poimboeuf - */ -#include - -#include -#include -#include - -unsigned long nr_insns; - -/* - * Call the arch-specific instruction decoder for all the instructions and add - * them to the global instruction list. - */ -int decode_instructions(struct objtool_file *file) -{ - struct section *sec; - struct symbol *func; - unsigned long offset; - struct instruction *insn; - int ret; - - for_each_sec(file, sec) { - struct instruction *insns = NULL; - u8 prev_len = 0; - u8 idx = 0; - - if (!(sec->sh.sh_flags & SHF_EXECINSTR)) - continue; - - if (strcmp(sec->name, ".altinstr_replacement") && - strcmp(sec->name, ".altinstr_aux") && - strncmp(sec->name, ".discard.", 9)) - sec->text = true; - - if (!strcmp(sec->name, ".noinstr.text") || - !strcmp(sec->name, ".entry.text") || - !strcmp(sec->name, ".cpuidle.text") || - !strncmp(sec->name, ".text..__x86.", 13)) - sec->noinstr = true; - - /* - * .init.text code is ran before userspace and thus doesn't - * strictly need retpolines, except for modules which are - * loaded late, they very much do need retpoline in their - * .init.text - */ - if (!strcmp(sec->name, ".init.text") && !opts.module) - sec->init = true; - - for (offset = 0; offset < sec->sh.sh_size; offset += insn->len) { - if (!insns || idx == INSN_CHUNK_MAX) { - insns = calloc(sizeof(*insn), INSN_CHUNK_SIZE); - if (!insns) { - WARN("malloc failed"); - return -1; - } - idx = 0; - } else { - idx++; - } - insn = &insns[idx]; - insn->idx = idx; - - INIT_LIST_HEAD(&insn->call_node); - insn->sec = sec; - insn->offset = offset; - insn->prev_len = prev_len; - - ret = arch_decode_instruction(file, sec, offset, - sec->sh.sh_size - offset, - insn); - if (ret) - return ret; - - prev_len = insn->len; - - /* - * By default, "ud2" is a dead end unless otherwise - * annotated, because GCC 7 inserts it for certain - * divide-by-zero cases. - */ - if (insn->type == INSN_BUG) - insn->dead_end = true; - - hash_add(file->insn_hash, &insn->hash, sec_offset_hash(sec, insn->offset)); - nr_insns++; - } - -// printf("%s: last chunk used: %d\n", sec->name, (int)idx); - - sec_for_each_sym(sec, func) { - if (func->type != STT_NOTYPE && func->type != STT_FUNC) - continue; - - if (func->offset == sec->sh.sh_size) { - /* Heuristic: likely an "end" symbol */ - if (func->type == STT_NOTYPE) - continue; - WARN("%s(): STT_FUNC at end of section", - func->name); - return -1; - } - - if (func->embedded_insn || func->alias != func) - continue; - - if (!find_insn(file, sec, func->offset)) { - WARN("%s(): can't find starting instruction", - func->name); - return -1; - } - - sym_for_each_insn(file, func, insn) { - insn->sym = func; - if (func->type == STT_FUNC && - insn->type == INSN_ENDBR && - list_empty(&insn->call_node)) { - if (insn->offset == func->offset) { - list_add_tail(&insn->call_node, &file->endbr_list); - file->nr_endbr++; - } else { - file->nr_endbr_int++; - } - } - } - } - } - - if (opts.stats) - printf("nr_insns: %lu\n", nr_insns); - - return 0; -} diff --git a/tools/objtool/include/objtool/insn.h b/tools/objtool/include/objtool/insn.h index d1e877095541..9bfb1fa93e3e 100644 --- a/tools/objtool/include/objtool/insn.h +++ b/tools/objtool/include/objtool/insn.h @@ -110,10 +110,10 @@ bool insn_cfi_match(struct instruction *insn, struct cfi_state *cfi2, bool is_first_func_insn(struct objtool_file *file, struct instruction *insn, struct symbol *sym); -int decode_instructions(struct objtool_file *file); /* temporily add for revert */ #ifdef __aarch64__ int read_unwind_hints(struct objtool_file *file); +int decode_instructions(struct objtool_file *file); #endif #define sec_for_each_insn(file, _sec, insn) \ @@ -149,5 +149,4 @@ int read_unwind_hints(struct objtool_file *file); for (insn = next_insn_same_sec(file, insn); insn; \ insn = next_insn_same_sec(file, insn)) -extern unsigned long nr_insns; #endif /* _INSN_H */ -- Gitee From 6b10c164f57fcfdcbc23cd14a28f36e5aefacba3 Mon Sep 17 00:00:00 2001 From: Jia He Date: Wed, 30 Oct 2024 11:14:50 +0000 Subject: [PATCH 10/13] Revert "objtool: Reorganize instruction-related code" ANBZ: #11595 cherry-picked from https://lore.kernel.org/lkml/20230202074036.507249-1-madvenka@linux.microsoft.com/ This reverts commit 9eacf42afe83bca4cba24403d0481dd957c8f2ed. To support livepatch features on other architectures, it's preferable to keep the Anolis livepatch code layout closely aligned with the upstream kernel. Therefore, we should revert the commits that reorganized the code specifically for arm64 livepatch support. Signed-off-by: Jia He --- tools/objtool/Build | 1 - tools/objtool/arch/arm64/Build | 1 + tools/objtool/arch/arm64/decode.c | 1 - tools/objtool/{ => arch/arm64}/insn.c | 0 tools/objtool/check.c | 212 +++++++++++++++++++++++++- tools/objtool/include/objtool/check.h | 101 +++++++++++- tools/objtool/include/objtool/insn.h | 21 +++ 7 files changed, 333 insertions(+), 4 deletions(-) rename tools/objtool/{ => arch/arm64}/insn.c (100%) diff --git a/tools/objtool/Build b/tools/objtool/Build index 9d934bf1ceee..1b2cdac753ef 100644 --- a/tools/objtool/Build +++ b/tools/objtool/Build @@ -7,7 +7,6 @@ objtool-$(STATIC_CHECK) += special.o objtool-$(DYNAMIC_CHECK) += dcheck.o objtool-y += builtin-check.o objtool-y += cfi.o -objtool-y += insn.o objtool-y += elf.o objtool-y += objtool.o diff --git a/tools/objtool/arch/arm64/Build b/tools/objtool/arch/arm64/Build index 77619e7ef476..00e9a5566b71 100644 --- a/tools/objtool/arch/arm64/Build +++ b/tools/objtool/arch/arm64/Build @@ -1,3 +1,4 @@ objtool-y += decode.o objtool-y += orc.o objtool-y += unwind_hints.o +objtool-y += insn.o diff --git a/tools/objtool/arch/arm64/decode.c b/tools/objtool/arch/arm64/decode.c index 28a972eb9976..49d46feb6a8a 100644 --- a/tools/objtool/arch/arm64/decode.c +++ b/tools/objtool/arch/arm64/decode.c @@ -14,7 +14,6 @@ #include #include -#include #include #include #include diff --git a/tools/objtool/insn.c b/tools/objtool/arch/arm64/insn.c similarity index 100% rename from tools/objtool/insn.c rename to tools/objtool/arch/arm64/insn.c diff --git a/tools/objtool/check.c b/tools/objtool/check.c index f9791097cf18..231f803d2ebd 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -27,6 +27,103 @@ struct alternative { bool skip_orig; }; +struct instruction *find_insn(struct objtool_file *file, + struct section *sec, unsigned long offset) +{ + struct instruction *insn; + + hash_for_each_possible(file->insn_hash, insn, hash, sec_offset_hash(sec, offset)) { + if (insn->sec == sec && insn->offset == offset) + return insn; + } + + return NULL; +} + +struct instruction *next_insn_same_sec(struct objtool_file *file, + struct instruction *insn) +{ + if (insn->idx == INSN_CHUNK_MAX) + return find_insn(file, insn->sec, insn->offset + insn->len); + + insn++; + if (!insn->len) + return NULL; + + return insn; +} + +static struct instruction *next_insn_same_func(struct objtool_file *file, + struct instruction *insn) +{ + struct instruction *next = next_insn_same_sec(file, insn); + struct symbol *func = insn_func(insn); + + if (!func) + return NULL; + + if (next && insn_func(next) == func) + return next; + + /* Check if we're already in the subfunction: */ + if (func == func->cfunc) + return NULL; + + /* Move to the subfunction: */ + return find_insn(file, func->cfunc->sec, func->cfunc->offset); +} + +static struct instruction *prev_insn_same_sec(struct objtool_file *file, + struct instruction *insn) +{ + if (insn->idx == 0) { + if (insn->prev_len) + return find_insn(file, insn->sec, insn->offset - insn->prev_len); + return NULL; + } + + return insn - 1; +} + +static struct instruction *prev_insn_same_sym(struct objtool_file *file, + struct instruction *insn) +{ + struct instruction *prev = prev_insn_same_sec(file, insn); + + if (prev && insn_func(prev) == insn_func(insn)) + return prev; + + return NULL; +} + +#define for_each_insn(file, insn) \ + for (struct section *__sec, *__fake = (struct section *)1; \ + __fake; __fake = NULL) \ + for_each_sec(file, __sec) \ + sec_for_each_insn(file, __sec, insn) + +#define func_for_each_insn(file, func, insn) \ + for (insn = find_insn(file, func->sec, func->offset); \ + insn; \ + insn = next_insn_same_func(file, insn)) + +#define sym_for_each_insn(file, sym, insn) \ + for (insn = find_insn(file, sym->sec, sym->offset); \ + insn && insn->offset < sym->offset + sym->len; \ + insn = next_insn_same_sec(file, insn)) + +#define sym_for_each_insn_continue_reverse(file, sym, insn) \ + for (insn = prev_insn_same_sec(file, insn); \ + insn && insn->offset >= sym->offset; \ + insn = prev_insn_same_sec(file, insn)) + +#define sec_for_each_insn_from(file, insn) \ + for (; insn; insn = next_insn_same_sec(file, insn)) + +#define sec_for_each_insn_continue(file, insn) \ + for (insn = next_insn_same_sec(file, insn); insn; \ + insn = next_insn_same_sec(file, insn)) + static inline struct symbol *insn_call_dest(struct instruction *insn) { if (insn->type == INSN_JUMP_DYNAMIC || @@ -157,6 +254,21 @@ static bool dead_end_function(struct objtool_file *file, struct symbol *func) return __dead_end_function(file, func, 0); } +static void init_insn_state(struct objtool_file *file, struct insn_state *state, + struct section *sec) +{ + memset(state, 0, sizeof(*state)); + init_cfi_state(&state->cfi); + + /* + * We need the full vmlinux for noinstr validation, otherwise we can + * not correctly determine insn_call_dest(insn)->sec (external symbols + * do not have a section). + */ + if (opts.link && opts.noinstr && sec) + state->noinstr = sec->noinstr; +} + static unsigned long nr_insns; static unsigned long nr_insns_visited; @@ -362,6 +474,19 @@ static int init_pv_ops(struct objtool_file *file) return 0; } +static struct instruction *find_last_insn(struct objtool_file *file, + struct section *sec) +{ + struct instruction *insn = NULL; + unsigned int offset; + unsigned int end = (sec->sh.sh_size > 10) ? sec->sh.sh_size - 10 : 0; + + for (offset = sec->sh.sh_size - 1; offset >= end && !insn; offset--) + insn = find_insn(file, sec, offset); + + return insn; +} + /* * Mark "ud2" instructions and manually annotated dead ends. */ @@ -1101,6 +1226,26 @@ __weak bool arch_is_embedded_insn(struct symbol *sym) return false; } +static struct reloc *insn_reloc(struct objtool_file *file, struct instruction *insn) +{ + struct reloc *reloc; + + if (insn->no_reloc) + return NULL; + + if (!file) + return NULL; + + reloc = find_reloc_by_dest_range(file->elf, insn->sec, + insn->offset, insn->len); + if (!reloc) { + insn->no_reloc = 1; + return NULL; + } + + return reloc; +} + static void remove_insn_ops(struct instruction *insn) { struct stack_op *op, *next; @@ -1260,6 +1405,24 @@ static void add_return_call(struct objtool_file *file, struct instruction *insn, list_add_tail(&insn->call_node, &file->return_thunk_list); } +static bool is_first_func_insn(struct objtool_file *file, + struct instruction *insn, struct symbol *sym) +{ + if (insn->offset == sym->offset) + return true; + + /* Allow direct CALL/JMP past ENDBR */ + if (opts.ibt) { + struct instruction *prev = prev_insn_same_sym(file, insn); + + if (prev && prev->type == INSN_ENDBR && + insn->offset == sym->offset + prev->len) + return true; + } + + return false; +} + /* * A sibling call is a tail-call to another symbol -- to differentiate from a * recursive tail-call which is to the same symbol. @@ -3031,6 +3194,53 @@ static int handle_insn_ops(struct instruction *insn, return 0; } +static bool insn_cfi_match(struct instruction *insn, struct cfi_state *cfi2) +{ + struct cfi_state *cfi1 = insn->cfi; + int i; + + if (!cfi1) { + WARN("CFI missing"); + return false; + } + + if (memcmp(&cfi1->cfa, &cfi2->cfa, sizeof(cfi1->cfa))) { + + WARN_INSN(insn, "stack state mismatch: cfa1=%d%+d cfa2=%d%+d", + cfi1->cfa.base, cfi1->cfa.offset, + cfi2->cfa.base, cfi2->cfa.offset); + + } else if (memcmp(&cfi1->regs, &cfi2->regs, sizeof(cfi1->regs))) { + for (i = 0; i < CFI_NUM_REGS; i++) { + if (!memcmp(&cfi1->regs[i], &cfi2->regs[i], + sizeof(struct cfi_reg))) + continue; + + WARN_INSN(insn, "stack state mismatch: reg1[%d]=%d%+d reg2[%d]=%d%+d", + i, cfi1->regs[i].base, cfi1->regs[i].offset, + i, cfi2->regs[i].base, cfi2->regs[i].offset); + break; + } + + } else if (cfi1->type != cfi2->type) { + + WARN_INSN(insn, "stack state mismatch: type1=%d type2=%d", + cfi1->type, cfi2->type); + + } else if (cfi1->drap != cfi2->drap || + (cfi1->drap && cfi1->drap_reg != cfi2->drap_reg) || + (cfi1->drap && cfi1->drap_offset != cfi2->drap_offset)) { + + WARN_INSN(insn, "stack state mismatch: drap1=%d(%d,%d) drap2=%d(%d,%d)", + cfi1->drap, cfi1->drap_reg, cfi1->drap_offset, + cfi2->drap, cfi2->drap_reg, cfi2->drap_offset); + + } else + return true; + + return false; +} + static inline bool func_uaccess_safe(struct symbol *func) { if (func) @@ -3264,7 +3474,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, visited = VISITED_BRANCH << state.uaccess; if (insn->visited & VISITED_BRANCH_MASK) { - if (!insn->hint && !insn_cfi_match(insn, &state.cfi, true)) + if (!insn->hint && !insn_cfi_match(insn, &state.cfi)) return 1; if (insn->visited & visited) diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/objtool/check.h index 1f63eca11ddd..f389816e3fa2 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -6,8 +6,21 @@ #ifndef _CHECK_H #define _CHECK_H -#include +#ifdef __aarch64__ #include +#else +#include +#include +#include + +struct insn_state { + struct cfi_state cfi; + unsigned int uaccess_stack; + bool uaccess; + bool df; + bool noinstr; + s8 instr; +}; struct alt_group { /* @@ -26,9 +39,95 @@ struct alt_group { struct cfi_state **cfi; }; +#define INSN_CHUNK_BITS 8 +#define INSN_CHUNK_SIZE (1 << INSN_CHUNK_BITS) +#define INSN_CHUNK_MAX (INSN_CHUNK_SIZE - 1) + +struct instruction { + struct hlist_node hash; + struct list_head call_node; + struct section *sec; + unsigned long offset; + unsigned long immediate; + + u8 len; + u8 prev_len; + u8 type; + s8 instr; + + u32 idx : INSN_CHUNK_BITS, + dead_end : 1, + ignore : 1, + ignore_alts : 1, + hint : 1, + save : 1, + restore : 1, + retpoline_safe : 1, + noendbr : 1, + unret : 1, + visited : 4, + no_reloc : 1; + /* 10 bit hole */ + + struct alt_group *alt_group; + struct instruction *jump_dest; + struct instruction *first_jump_src; + union { + struct symbol *_call_dest; + struct reloc *_jump_table; + }; + struct alternative *alts; + struct symbol *sym; + struct stack_op *stack_ops; + struct cfi_state *cfi; +}; + +static inline struct symbol *insn_func(struct instruction *insn) +{ + struct symbol *sym = insn->sym; + + if (sym && sym->type != STT_FUNC) + sym = NULL; + + return sym; +} + #define VISITED_BRANCH 0x01 #define VISITED_BRANCH_UACCESS 0x02 #define VISITED_BRANCH_MASK 0x03 #define VISITED_UNRET 0x04 +static inline bool is_static_jump(struct instruction *insn) +{ + return insn->type == INSN_JUMP_CONDITIONAL || + insn->type == INSN_JUMP_UNCONDITIONAL; +} + +static inline bool is_dynamic_jump(struct instruction *insn) +{ + return insn->type == INSN_JUMP_DYNAMIC || + insn->type == INSN_JUMP_DYNAMIC_CONDITIONAL; +} + +static inline bool is_jump(struct instruction *insn) +{ + return is_static_jump(insn) || is_dynamic_jump(insn); +} + +struct instruction *find_insn(struct objtool_file *file, + struct section *sec, unsigned long offset); + +struct instruction *next_insn_same_sec(struct objtool_file *file, struct instruction *insn); + +#define sec_for_each_insn(file, _sec, insn) \ + for (insn = find_insn(file, _sec, 0); \ + insn && insn->sec == _sec; \ + insn = next_insn_same_sec(file, insn)) + +static inline bool insn_can_reloc(struct instruction *insn) +{ + return true; +} + +#endif /* endof !__aarch64__ */ #endif /* _CHECK_H */ diff --git a/tools/objtool/include/objtool/insn.h b/tools/objtool/include/objtool/insn.h index 9bfb1fa93e3e..b650cffaf7b1 100644 --- a/tools/objtool/include/objtool/insn.h +++ b/tools/objtool/include/objtool/insn.h @@ -6,6 +6,8 @@ #ifndef _INSN_H #define _INSN_H +/* This is an arm64 specific version for check.h */ +#ifdef __aarch64__ #include #include @@ -61,6 +63,23 @@ struct instruction { struct cfi_state *cfi; }; +struct alt_group { + /* + * Pointer from a replacement group to the original group. NULL if it + * *is* the original group. + */ + struct alt_group *orig_group; + + /* First and last instructions in the group */ + struct instruction *first_insn, *last_insn, *nop; + + /* + * Byte-offset-addressed len-sized array of pointers to CFI structs. + * This is shared with the other alt_groups in the same alternative. + */ + struct cfi_state **cfi; +}; + static inline struct symbol *insn_func(struct instruction *insn) { struct symbol *sym = insn->sym; @@ -149,4 +168,6 @@ int decode_instructions(struct objtool_file *file); for (insn = next_insn_same_sec(file, insn); insn; \ insn = next_insn_same_sec(file, insn)) +extern unsigned long nr_insns; +#endif /* __aarch64__ */ #endif /* _INSN_H */ -- Gitee From 2675796446a8369e808f0615ad6e046104c36849 Mon Sep 17 00:00:00 2001 From: Jia He Date: Thu, 31 Oct 2024 04:10:10 +0000 Subject: [PATCH 11/13] Revert "objtool: Reorganize CFI code" ANBZ: #11595 cherry-picked from https://lore.kernel.org/lkml/20230202074036.507249-1-madvenka@linux.microsoft.com/ This reverts commit 15dd22635b4a253a60cfa3f219293175740516aa. To support livepatch features on other architectures, it's preferable to keep the Anolis livepatch code layout closely aligned with the upstream kernel. Therefore, we should revert the commits that reorganized the code specifically for arm64 livepatch support. Signed-off-by: Jia He --- tools/objtool/Build | 1 - tools/objtool/arch/arm64/Build | 1 + tools/objtool/{ => arch/arm64}/cfi.c | 1 + tools/objtool/arch/arm64/include/arch/cfi.h | 26 ++++++ tools/objtool/arch/arm64/insn.c | 1 + tools/objtool/arch/arm64/unwind_hints.c | 1 + tools/objtool/check.c | 98 +++++++++++++++++++++ tools/objtool/dcheck.c | 1 + tools/objtool/include/objtool/cfi.h | 13 --- tools/objtool/include/objtool/insn.h | 3 - 10 files changed, 129 insertions(+), 17 deletions(-) rename tools/objtool/{ => arch/arm64}/cfi.c (99%) create mode 100644 tools/objtool/arch/arm64/include/arch/cfi.h diff --git a/tools/objtool/Build b/tools/objtool/Build index 1b2cdac753ef..b71547b660ce 100644 --- a/tools/objtool/Build +++ b/tools/objtool/Build @@ -6,7 +6,6 @@ objtool-$(STATIC_CHECK) += check.o objtool-$(STATIC_CHECK) += special.o objtool-$(DYNAMIC_CHECK) += dcheck.o objtool-y += builtin-check.o -objtool-y += cfi.o objtool-y += elf.o objtool-y += objtool.o diff --git a/tools/objtool/arch/arm64/Build b/tools/objtool/arch/arm64/Build index 00e9a5566b71..8d2f99a5b1ab 100644 --- a/tools/objtool/arch/arm64/Build +++ b/tools/objtool/arch/arm64/Build @@ -2,3 +2,4 @@ objtool-y += decode.o objtool-y += orc.o objtool-y += unwind_hints.o objtool-y += insn.o +objtool-y += cfi.o diff --git a/tools/objtool/cfi.c b/tools/objtool/arch/arm64/cfi.c similarity index 99% rename from tools/objtool/cfi.c rename to tools/objtool/arch/arm64/cfi.c index bc3e216f1a94..753aa82d20c8 100644 --- a/tools/objtool/cfi.c +++ b/tools/objtool/arch/arm64/cfi.c @@ -8,6 +8,7 @@ #include #include +#include #include #include diff --git a/tools/objtool/arch/arm64/include/arch/cfi.h b/tools/objtool/arch/arm64/include/arch/cfi.h new file mode 100644 index 000000000000..55f7a988d824 --- /dev/null +++ b/tools/objtool/arch/arm64/include/arch/cfi.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2015-2017 Josh Poimboeuf + */ + +#ifndef _OBJTOOL_ARCH_CFI_H +#define _OBJTOOL_ARCH_CFI_H + +#include + +#include + +void init_cfi_state(struct cfi_state *cfi); +bool cficmp(struct cfi_state *cfi1, struct cfi_state *cfi2); +struct cfi_state *cfi_hash_find_or_add(struct cfi_state *cfi); +void cfi_hash_add(struct cfi_state *cfi); +void *cfi_hash_alloc(unsigned long size); +void set_func_state(struct cfi_state *state); + +extern unsigned long nr_cfi, nr_cfi_reused, nr_cfi_cache; +extern struct cfi_init_state initial_func_cfi; +extern struct cfi_state init_cfi; +extern struct cfi_state func_cfi; +extern struct cfi_state force_undefined_cfi; + +#endif /* _OBJTOOL_ARCH_CFI_H */ diff --git a/tools/objtool/arch/arm64/insn.c b/tools/objtool/arch/arm64/insn.c index b63ec049696a..b205868690c2 100644 --- a/tools/objtool/arch/arm64/insn.c +++ b/tools/objtool/arch/arm64/insn.c @@ -8,6 +8,7 @@ #include #include #include +#include struct instruction *find_insn(struct objtool_file *file, struct section *sec, unsigned long offset) diff --git a/tools/objtool/arch/arm64/unwind_hints.c b/tools/objtool/arch/arm64/unwind_hints.c index c59d259d0392..3e5364623def 100644 --- a/tools/objtool/arch/arm64/unwind_hints.c +++ b/tools/objtool/arch/arm64/unwind_hints.c @@ -8,6 +8,7 @@ #include #include #include +#include int read_unwind_hints(struct objtool_file *file) { diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 231f803d2ebd..e3fc263b1b20 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -27,6 +27,13 @@ struct alternative { bool skip_orig; }; +static unsigned long nr_cfi, nr_cfi_reused, nr_cfi_cache; + +static struct cfi_init_state initial_func_cfi; +static struct cfi_state init_cfi; +static struct cfi_state func_cfi; +static struct cfi_state force_undefined_cfi; + struct instruction *find_insn(struct objtool_file *file, struct section *sec, unsigned long offset) { @@ -254,6 +261,19 @@ static bool dead_end_function(struct objtool_file *file, struct symbol *func) return __dead_end_function(file, func, 0); } +static void init_cfi_state(struct cfi_state *cfi) +{ + int i; + + for (i = 0; i < CFI_NUM_REGS; i++) { + cfi->regs[i].base = CFI_UNDEFINED; + cfi->vals[i].base = CFI_UNDEFINED; + } + cfi->cfa.base = CFI_UNDEFINED; + cfi->drap_reg = CFI_UNDEFINED; + cfi->drap_offset = -1; +} + static void init_insn_state(struct objtool_file *file, struct insn_state *state, struct section *sec) { @@ -269,6 +289,75 @@ static void init_insn_state(struct objtool_file *file, struct insn_state *state, state->noinstr = sec->noinstr; } +static struct cfi_state *cfi_alloc(void) +{ + struct cfi_state *cfi = calloc(sizeof(struct cfi_state), 1); + if (!cfi) { + WARN("calloc failed"); + exit(1); + } + nr_cfi++; + return cfi; +} + +static int cfi_bits; +static struct hlist_head *cfi_hash; + +static inline bool cficmp(struct cfi_state *cfi1, struct cfi_state *cfi2) +{ + return memcmp((void *)cfi1 + sizeof(cfi1->hash), + (void *)cfi2 + sizeof(cfi2->hash), + sizeof(struct cfi_state) - sizeof(struct hlist_node)); +} + +static inline u32 cfi_key(struct cfi_state *cfi) +{ + return jhash((void *)cfi + sizeof(cfi->hash), + sizeof(*cfi) - sizeof(cfi->hash), 0); +} + +static struct cfi_state *cfi_hash_find_or_add(struct cfi_state *cfi) +{ + struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)]; + struct cfi_state *obj; + + hlist_for_each_entry(obj, head, hash) { + if (!cficmp(cfi, obj)) { + nr_cfi_cache++; + return obj; + } + } + + obj = cfi_alloc(); + *obj = *cfi; + hlist_add_head(&obj->hash, head); + + return obj; +} + +static void cfi_hash_add(struct cfi_state *cfi) +{ + struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)]; + + hlist_add_head(&cfi->hash, head); +} + +static void *cfi_hash_alloc(unsigned long size) +{ + cfi_bits = max(10, ilog2(size)); + cfi_hash = mmap(NULL, sizeof(struct hlist_head) << cfi_bits, + PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANON, -1, 0); + if (cfi_hash == (void *)-1L) { + WARN("mmap fail cfi_hash"); + cfi_hash = NULL; + } else if (opts.stats) { + printf("cfi_bits: %d\n", cfi_bits); + } + + return cfi_hash; +} + static unsigned long nr_insns; static unsigned long nr_insns_visited; @@ -2103,6 +2192,15 @@ static int add_jump_table_alts(struct objtool_file *file) return 0; } +static void set_func_state(struct cfi_state *state) +{ + state->cfa = initial_func_cfi.cfa; + memcpy(&state->regs, &initial_func_cfi.regs, + CFI_NUM_REGS * sizeof(struct cfi_reg)); + state->stack_size = initial_func_cfi.cfa.offset; + state->type = UNWIND_HINT_TYPE_CALL; +} + static int read_unwind_hints(struct objtool_file *file) { struct cfi_state cfi = init_cfi; diff --git a/tools/objtool/dcheck.c b/tools/objtool/dcheck.c index 39dcd0a30f46..a4c342bf697d 100644 --- a/tools/objtool/dcheck.c +++ b/tools/objtool/dcheck.c @@ -11,6 +11,7 @@ #include #include #include +#include /* * Find the destination instructions for all jumps. diff --git a/tools/objtool/include/objtool/cfi.h b/tools/objtool/include/objtool/cfi.h index 557366799315..c8a6bec4f6b9 100644 --- a/tools/objtool/include/objtool/cfi.h +++ b/tools/objtool/include/objtool/cfi.h @@ -39,17 +39,4 @@ struct cfi_state { bool force_undefined; }; -void init_cfi_state(struct cfi_state *cfi); -bool cficmp(struct cfi_state *cfi1, struct cfi_state *cfi2); -struct cfi_state *cfi_hash_find_or_add(struct cfi_state *cfi); -void cfi_hash_add(struct cfi_state *cfi); -void *cfi_hash_alloc(unsigned long size); -void set_func_state(struct cfi_state *state); - -extern unsigned long nr_cfi, nr_cfi_reused, nr_cfi_cache; -extern struct cfi_init_state initial_func_cfi; -extern struct cfi_state init_cfi; -extern struct cfi_state func_cfi; -extern struct cfi_state force_undefined_cfi; - #endif /* _OBJTOOL_CFI_H */ diff --git a/tools/objtool/include/objtool/insn.h b/tools/objtool/include/objtool/insn.h index b650cffaf7b1..36922da5ccc7 100644 --- a/tools/objtool/include/objtool/insn.h +++ b/tools/objtool/include/objtool/insn.h @@ -129,11 +129,8 @@ bool insn_cfi_match(struct instruction *insn, struct cfi_state *cfi2, bool is_first_func_insn(struct objtool_file *file, struct instruction *insn, struct symbol *sym); -/* temporily add for revert */ -#ifdef __aarch64__ int read_unwind_hints(struct objtool_file *file); int decode_instructions(struct objtool_file *file); -#endif #define sec_for_each_insn(file, _sec, insn) \ for (insn = find_insn(file, _sec, 0); \ -- Gitee From 1168e686298d6452632baff8461ddb826e164bac Mon Sep 17 00:00:00 2001 From: "Madhavan T. Venkataraman" Date: Sun, 29 Jan 2023 15:42:10 -0600 Subject: [PATCH 12/13] arm64: Enable livepatch for ARM64 ANBZ: #11595 cherry-picked from https://lore.kernel.org/lkml/20230202074036.507249-1-madvenka@linux.microsoft.com/ Enable livepatch again in arch/arm64/Kconfig since the code reorganization has been completed. Signed-off-by: Jia He --- arch/arm64/Kconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 630f0f498cb1..e553aa8058db 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -174,7 +174,7 @@ config ARM64 select HAVE_ARCH_MMAP_RND_BITS select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT select HAVE_ARCH_PREL32_RELOCATIONS - select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET + select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET if !HAVE_LIVEPATCH select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_STACKLEAK select HAVE_ARCH_THREAD_STRUCT_WHITELIST @@ -258,6 +258,8 @@ config ARM64 select HAVE_SOFTIRQ_ON_OWN_STACK select HAVE_STACK_VALIDATION if FRAME_POINTER_VALIDATION select STACK_VALIDATION if HAVE_STACK_VALIDATION + select HAVE_RELIABLE_STACKTRACE if STACK_VALIDATION + select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_ARGS && HAVE_RELIABLE_STACKTRACE help ARM 64-bit (AArch64) Linux support. @@ -2404,3 +2406,4 @@ source "drivers/acpi/Kconfig" source "arch/arm64/kvm/Kconfig" +source "kernel/livepatch/Kconfig" -- Gitee From 0dfbca19c60cdb813db265b84e3897dcc2469fda Mon Sep 17 00:00:00 2001 From: Jia He Date: Fri, 13 Sep 2024 11:50:30 +0000 Subject: [PATCH 13/13] anolis: configs: Enable CONFIG_LIVEPATCH for arm64 ANBZ: #11595 cherry-picked from https://lore.kernel.org/lkml/20230202074036.507249-1-madvenka@linux.microsoft.com/ Enable CONFIG_LIVEPATCH and its dependency configs again for anolis_defconfig and anolis-debug_defconfig on arm64 since the code reorganization has been completed. Signed-off-by: Jia He --- .../configs/L1-RECOMMEND/arm64/CONFIG_FRAME_POINTER_VALIDATION | 1 + .../L1-RECOMMEND/arm64/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET | 1 + anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_LIVEPATCH | 1 + .../configs/L1-RECOMMEND/arm64/CONFIG_HAVE_RELIABLE_STACKTRACE | 1 + anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_STACK_VALIDATION | 1 + anolis/configs/L1-RECOMMEND/arm64/CONFIG_LIVEPATCH | 1 + anolis/configs/L1-RECOMMEND/arm64/CONFIG_OBJTOOL | 1 + anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET | 1 + .../L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT | 1 + anolis/configs/L1-RECOMMEND/arm64/CONFIG_STACK_VALIDATION | 1 + anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_FRAME_POINTER | 1 + anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_ORC | 1 + anolis/configs/L2-OPTIONAL/arm64/CONFIG_TEST_LIVEPATCH | 1 + 13 files changed, 13 insertions(+) create mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_FRAME_POINTER_VALIDATION create mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET create mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_LIVEPATCH create mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_RELIABLE_STACKTRACE create mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_STACK_VALIDATION create mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_LIVEPATCH create mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_OBJTOOL create mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET create mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT create mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_STACK_VALIDATION create mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_FRAME_POINTER create mode 100644 anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_ORC create mode 100644 anolis/configs/L2-OPTIONAL/arm64/CONFIG_TEST_LIVEPATCH diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_FRAME_POINTER_VALIDATION b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_FRAME_POINTER_VALIDATION new file mode 100644 index 000000000000..cc041e559182 --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_FRAME_POINTER_VALIDATION @@ -0,0 +1 @@ +CONFIG_FRAME_POINTER_VALIDATION=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET new file mode 100644 index 000000000000..c7daa4f60d5d --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET @@ -0,0 +1 @@ +# CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET is not set diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_LIVEPATCH b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_LIVEPATCH new file mode 100644 index 000000000000..7ebdb924703e --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_LIVEPATCH @@ -0,0 +1 @@ +CONFIG_HAVE_LIVEPATCH=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_RELIABLE_STACKTRACE b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_RELIABLE_STACKTRACE new file mode 100644 index 000000000000..2ce8faabc4cf --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_RELIABLE_STACKTRACE @@ -0,0 +1 @@ +CONFIG_HAVE_RELIABLE_STACKTRACE=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_STACK_VALIDATION b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_STACK_VALIDATION new file mode 100644 index 000000000000..6f36a32d84ae --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_HAVE_STACK_VALIDATION @@ -0,0 +1 @@ +CONFIG_HAVE_STACK_VALIDATION=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_LIVEPATCH b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_LIVEPATCH new file mode 100644 index 000000000000..1b05d0d1a109 --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_LIVEPATCH @@ -0,0 +1 @@ +CONFIG_LIVEPATCH=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_OBJTOOL b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_OBJTOOL new file mode 100644 index 000000000000..cf3a9f20f93d --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_OBJTOOL @@ -0,0 +1 @@ +CONFIG_OBJTOOL=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET new file mode 100644 index 000000000000..759cb13e424c --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET @@ -0,0 +1 @@ +# CONFIG_RANDOMIZE_KSTACK_OFFSET is not set diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT new file mode 100644 index 000000000000..d680659c1703 --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT @@ -0,0 +1 @@ +# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_STACK_VALIDATION b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_STACK_VALIDATION new file mode 100644 index 000000000000..e335fefdd9be --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_STACK_VALIDATION @@ -0,0 +1 @@ +CONFIG_STACK_VALIDATION=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_FRAME_POINTER b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_FRAME_POINTER new file mode 100644 index 000000000000..0938fde11ffe --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_FRAME_POINTER @@ -0,0 +1 @@ +CONFIG_UNWINDER_FRAME_POINTER=y diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_ORC b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_ORC new file mode 100644 index 000000000000..6b6908419acb --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_UNWINDER_ORC @@ -0,0 +1 @@ +CONFIG_UNWINDER_ORC=y diff --git a/anolis/configs/L2-OPTIONAL/arm64/CONFIG_TEST_LIVEPATCH b/anolis/configs/L2-OPTIONAL/arm64/CONFIG_TEST_LIVEPATCH new file mode 100644 index 000000000000..0dd7700464a8 --- /dev/null +++ b/anolis/configs/L2-OPTIONAL/arm64/CONFIG_TEST_LIVEPATCH @@ -0,0 +1 @@ +CONFIG_TEST_LIVEPATCH=m -- Gitee