Pull RISC-V updates from Palmer Dabbelt: - Support for the T-Head PMU via the perf subsystem - ftrace support for rv32 - Support for non-volatile memory devices - Various fixes and cleanups * tag 'riscv-for-linus-6.2-mw1' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: (52 commits) Documentation: RISC-V: patch-acceptance: s/implementor/implementer Documentation: RISC-V: Mention the UEFI Standards Documentation: RISC-V: Allow patches for non-standard behavior Documentation: RISC-V: Fix a typo in patch-acceptance riscv: Fixup compile error with !MMU riscv: Fix P4D_SHIFT definition for 3-level page table mode riscv: Apply a static assert to riscv_isa_ext_id RISC-V: Add some comments about the shadow and overflow stacks RISC-V: Align the shadow stack RISC-V: Ensure Zicbom has a valid block size RISC-V: Introduce riscv_isa_extension_check RISC-V: Improve use of isa2hwcap[] riscv: Don't duplicate _ALTERNATIVE_CFG* macros riscv: alternatives: Drop the underscores from the assembly macro names riscv: alternatives: Don't name unused macro parameters riscv: Don't duplicate __ALTERNATIVE_CFG in __ALTERNATIVE_CFG_2 riscv: mm: call best_map_size many times during linear-mapping riscv: Move cast inside kernel_mapping_[pv]a_to_[vp]a riscv: Fix crash during early errata patching riscv: boot: add zstd support ...
Unified · Split
| @@ -595,3 +595,32 @@ X2TLB · 594 unmodified lines | |||
| 595 | ----- | 595 | ----- |
| 596 | 596 | ||
| 597 | Indicates whether the crashed kernel enabled SH extended mode. | 597 | Indicates whether the crashed kernel enabled SH extended mode. |
| 598 | |||
| 599 | RISCV64 | ||
| 600 | ======= | ||
| 601 | |||
| 602 | VA_BITS | ||
| 603 | ------- | ||
| 604 | |||
| 605 | The maximum number of bits for virtual addresses. Used to compute the | ||
| 606 | virtual memory ranges. | ||
| 607 | |||
| 608 | PAGE_OFFSET | ||
| 609 | ----------- | ||
| 610 | |||
| 611 | Indicates the virtual kernel start address of the direct-mapped RAM region. | ||
| 612 | |||
| 613 | phys_ram_base | ||
| 614 | ------------- | ||
| 615 | |||
| 616 | Indicates the start physical RAM address. | ||
| 617 | |||
| 618 | MODULES_VADDR|MODULES_END|VMALLOC_START|VMALLOC_END|VMEMMAP_START|VMEMMAP_END|KERNEL_LINK_ADDR | ||
| 619 | ---------------------------------------------------------------------------------------------- | ||
| 620 | |||
| 621 | Used to get the correct ranges: | ||
| 622 | |||
| 623 | * MODULES_VADDR ~ MODULES_END : Kernel module space. | ||
| 624 | * VMALLOC_START ~ VMALLOC_END : vmalloc() / ioremap() space. | ||
| 625 | * VMEMMAP_START ~ VMEMMAP_END : vmemmap space, used for struct page array. | ||
| 626 | * KERNEL_LINK_ADDR : start address of Kernel link and BPF | ||
| @@ -21,7 +21,7 @@ · 20 unmodified lines | |||
| 21 | | openrisc: | TODO | | 21 | | openrisc: | TODO | |
| 22 | | parisc: | TODO | | 22 | | parisc: | TODO | |
| 23 | | powerpc: | ok | | 23 | | powerpc: | ok | |
| 24 | | riscv: | TODO | | 24 | | riscv: | ok | |
| 25 | | s390: | TODO | | 25 | | s390: | TODO | |
| 26 | | sh: | TODO | | 26 | | sh: | TODO | |
| 27 | | sparc: | TODO | | 27 | | sparc: | TODO | |
| @@ -20,16 +20,22 @@ Submit Checklist Addendum · 19 unmodified lines | |||
| 20 | ------------------------- | 20 | ------------------------- |
| 21 | We'll only accept patches for new modules or extensions if the | 21 | We'll only accept patches for new modules or extensions if the |
| 22 | specifications for those modules or extensions are listed as being | 22 | specifications for those modules or extensions are listed as being |
| 23 | "Frozen" or "Ratified" by the RISC-V Foundation. (Developers may, of | 23 | unlikely to be incompatibly changed in the future. For |
| 24 | course, maintain their own Linux kernel trees that contain code for | 24 | specifications from the RISC-V foundation this means "Frozen" or |
| 25 | any draft extensions that they wish.) | 25 | "Ratified", for the UEFI forum specifications this means a published |
| 26 | ECR. (Developers may, of course, maintain their own Linux kernel trees | ||
| 27 | that contain code for any draft extensions that they wish.) | ||
| 26 | 28 | ||
| 27 | Additionally, the RISC-V specification allows implementors to create | 29 | Additionally, the RISC-V specification allows implementers to create |
| 28 | their own custom extensions. These custom extensions aren't required | 30 | their own custom extensions. These custom extensions aren't required |
| 29 | to go through any review or ratification process by the RISC-V | 31 | to go through any review or ratification process by the RISC-V |
| 30 | Foundation. To avoid the maintenance complexity and potential | 32 | Foundation. To avoid the maintenance complexity and potential |
| 31 | performance impact of adding kernel code for implementor-specific | 33 | performance impact of adding kernel code for implementor-specific |
| 32 | RISC-V extensions, we'll only to accept patches for extensions that | 34 | RISC-V extensions, we'll only consider patches for extensions that either: |
| 33 | have been officially frozen or ratified by the RISC-V Foundation. | 35 | |
| 34 | (Implementors, may, of course, maintain their own Linux kernel trees | 36 | - Have been officially frozen or ratified by the RISC-V Foundation, or |
| 35 | containing code for any custom extensions that they wish.) | 37 | - Have been implemented in hardware that is widely available, per standard |
| 38 | Linux practice. | ||
| 39 | |||
| 40 | (Implementers, may, of course, maintain their own Linux kernel trees containing | ||
| 41 | code for any custom extensions that they wish.) | ||
| @@ -25,6 +25,7 @@ config RISCV · 24 unmodified lines | |||
| 25 | select ARCH_HAS_GIGANTIC_PAGE | 25 | select ARCH_HAS_GIGANTIC_PAGE |
| 26 | select ARCH_HAS_KCOV | 26 | select ARCH_HAS_KCOV |
| 27 | select ARCH_HAS_MMIOWB | 27 | select ARCH_HAS_MMIOWB |
| 28 | select ARCH_HAS_PMEM_API | ||
| 28 | select ARCH_HAS_PTE_SPECIAL | 29 | select ARCH_HAS_PTE_SPECIAL |
| 29 | select ARCH_HAS_SET_DIRECT_MAP if MMU | 30 | select ARCH_HAS_SET_DIRECT_MAP if MMU |
| 30 | select ARCH_HAS_SET_MEMORY if MMU | 31 | select ARCH_HAS_SET_MEMORY if MMU |
| @@ -72,6 +73,8 @@ config RISCV · 41 unmodified lines | |||
| 72 | select GENERIC_VDSO_TIME_NS if HAVE_GENERIC_VDSO | 73 | select GENERIC_VDSO_TIME_NS if HAVE_GENERIC_VDSO |
| 73 | select HARDIRQS_SW_RESEND | 74 | select HARDIRQS_SW_RESEND |
| 74 | select HAVE_ARCH_AUDITSYSCALL | 75 | select HAVE_ARCH_AUDITSYSCALL |
| 76 | select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP | ||
| 77 | select HAVE_ARCH_HUGE_VMAP if MMU && 64BIT && !XIP_KERNEL | ||
| 75 | select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL | 78 | select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL |
| 76 | select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL | 79 | select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL |
| 77 | select HAVE_ARCH_KASAN if MMU && 64BIT | 80 | select HAVE_ARCH_KASAN if MMU && 64BIT |
| @@ -99,6 +102,7 @@ config RISCV · 21 unmodified lines | |||
| 99 | select HAVE_KPROBES if !XIP_KERNEL | 102 | select HAVE_KPROBES if !XIP_KERNEL |
| 100 | select HAVE_KPROBES_ON_FTRACE if !XIP_KERNEL | 103 | select HAVE_KPROBES_ON_FTRACE if !XIP_KERNEL |
| 101 | select HAVE_KRETPROBES if !XIP_KERNEL | 104 | select HAVE_KRETPROBES if !XIP_KERNEL |
| 105 | select HAVE_RETHOOK if !XIP_KERNEL | ||
| 102 | select HAVE_MOVE_PMD | 106 | select HAVE_MOVE_PMD |
| 103 | select HAVE_MOVE_PUD | 107 | select HAVE_MOVE_PUD |
| 104 | select HAVE_PCI | 108 | select HAVE_PCI |
| @@ -123,12 +127,18 @@ config RISCV · 18 unmodified lines | |||
| 123 | select PCI_MSI if PCI | 127 | select PCI_MSI if PCI |
| 124 | select RISCV_INTC | 128 | select RISCV_INTC |
| 125 | select RISCV_TIMER if RISCV_SBI | 129 | select RISCV_TIMER if RISCV_SBI |
| 130 | select SIFIVE_PLIC | ||
| 126 | select SPARSE_IRQ | 131 | select SPARSE_IRQ |
| 127 | select SYSCTL_EXCEPTION_TRACE | 132 | select SYSCTL_EXCEPTION_TRACE |
| 128 | select THREAD_INFO_IN_TASK | 133 | select THREAD_INFO_IN_TASK |
| 129 | select TRACE_IRQFLAGS_SUPPORT | 134 | select TRACE_IRQFLAGS_SUPPORT |
| 130 | select UACCESS_MEMCPY if !MMU | 135 | select UACCESS_MEMCPY if !MMU |
| 131 | select ZONE_DMA32 if 64BIT | 136 | select ZONE_DMA32 if 64BIT |
| 137 | select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && MMU && $(cc-option,-fpatchable-function-entry=8) | ||
| 138 | select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE | ||
| 139 | select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL | ||
| 140 | select HAVE_FUNCTION_GRAPH_TRACER | ||
| 141 | select HAVE_FUNCTION_TRACER if !XIP_KERNEL | ||
| 132 | 142 | ||
| 133 | config ARCH_MMAP_RND_BITS_MIN | 143 | config ARCH_MMAP_RND_BITS_MIN |
| 134 | default 18 if 64BIT | 144 | default 18 if 64BIT |
| @@ -274,11 +284,6 @@ config ARCH_RV64I · 139 unmodified lines | |||
| 274 | bool "RV64I" | 284 | bool "RV64I" |
| 275 | select 64BIT | 285 | select 64BIT |
| 276 | select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 | 286 | select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 |
| 277 | select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && MMU && $(cc-option,-fpatchable-function-entry=8) | ||
| 278 | select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE | ||
| 279 | select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL | ||
| 280 | select HAVE_FUNCTION_GRAPH_TRACER | ||
| 281 | select HAVE_FUNCTION_TRACER if !XIP_KERNEL | ||
| 282 | select SWIOTLB if MMU | 287 | select SWIOTLB if MMU |
| 283 | 288 | ||
| 284 | endchoice | 289 | endchoice |
| @@ -502,7 +507,7 @@ config KEXEC_FILE · 217 unmodified lines | |||
| 502 | select KEXEC_CORE | 507 | select KEXEC_CORE |
| 503 | select KEXEC_ELF | 508 | select KEXEC_ELF |
| 504 | select HAVE_IMA_KEXEC if IMA | 509 | select HAVE_IMA_KEXEC if IMA |
| 505 | depends on 64BIT | 510 | depends on 64BIT && MMU |
| 506 | help | 511 | help |
| 507 | This is new version of kexec system call. This system call is | 512 | This is new version of kexec system call. This system call is |
| 508 | file based and takes file descriptors as system call argument | 513 | file based and takes file descriptors as system call argument |
| @@ -691,6 +696,8 @@ menu "CPU Power Management" · 182 unmodified lines | |||
| 691 | 696 | ||
| 692 | source "drivers/cpuidle/Kconfig" | 697 | source "drivers/cpuidle/Kconfig" |
| 693 | 698 | ||
| 699 | source "drivers/cpufreq/Kconfig" | ||
| 700 | |||
| 694 | endmenu # "CPU Power Management" | 701 | endmenu # "CPU Power Management" |
| 695 | 702 | ||
| 696 | source "arch/riscv/kvm/Kconfig" | 703 | source "arch/riscv/kvm/Kconfig" |
| @@ -66,4 +66,17 @@ config ERRATA_THEAD_CMO · 65 unmodified lines | |||
| 66 | 66 | ||
| 67 | If you don't know what to do here, say "Y". | 67 | If you don't know what to do here, say "Y". |
| 68 | 68 | ||
| 69 | config ERRATA_THEAD_PMU | ||
| 70 | bool "Apply T-Head PMU errata" | ||
| 71 | depends on ERRATA_THEAD && RISCV_PMU_SBI | ||
| 72 | default y | ||
| 73 | help | ||
| 74 | The T-Head C9xx cores implement a PMU overflow extension very | ||
| 75 | similar to the core SSCOFPMF extension. | ||
| 76 | |||
| 77 | This will apply the overflow errata to handle the non-standard | ||
| 78 | behaviour via the regular SBI PMU driver and interface. | ||
| 79 | |||
| 80 | If you don't know what to do here, say "Y". | ||
| 81 | |||
| 69 | endmenu # "CPU errata selection" | 82 | endmenu # "CPU errata selection" |
| @@ -3,7 +3,6 @@ menu "SoC selection" · 2 unmodified lines | |||
| 3 | config SOC_MICROCHIP_POLARFIRE | 3 | config SOC_MICROCHIP_POLARFIRE |
| 4 | bool "Microchip PolarFire SoCs" | 4 | bool "Microchip PolarFire SoCs" |
| 5 | select MCHP_CLK_MPFS | 5 | select MCHP_CLK_MPFS |
| 6 | select SIFIVE_PLIC | ||
| 7 | help | 6 | help |
| 8 | This enables support for Microchip PolarFire SoC platforms. | 7 | This enables support for Microchip PolarFire SoC platforms. |
| 9 | 8 | ||
| @@ -18,7 +17,6 @@ config SOC_SIFIVE · 8 unmodified lines | |||
| 18 | select SERIAL_SIFIVE_CONSOLE if TTY | 17 | select SERIAL_SIFIVE_CONSOLE if TTY |
| 19 | select CLK_SIFIVE | 18 | select CLK_SIFIVE |
| 20 | select CLK_SIFIVE_PRCI | 19 | select CLK_SIFIVE_PRCI |
| 21 | select SIFIVE_PLIC | ||
| 22 | select ERRATA_SIFIVE if !XIP_KERNEL | 20 | select ERRATA_SIFIVE if !XIP_KERNEL |
| 23 | help | 21 | help |
| 24 | This enables support for SiFive SoC platform hardware. | 22 | This enables support for SiFive SoC platform hardware. |
| @@ -27,7 +25,6 @@ config SOC_STARFIVE · 2 unmodified lines | |||
| 27 | bool "StarFive SoCs" | 25 | bool "StarFive SoCs" |
| 28 | select PINCTRL | 26 | select PINCTRL |
| 29 | select RESET_CONTROLLER | 27 | select RESET_CONTROLLER |
| 30 | select SIFIVE_PLIC | ||
| 31 | help | 28 | help |
| 32 | This enables support for StarFive SoC platform hardware. | 29 | This enables support for StarFive SoC platform hardware. |
| 33 | 30 | ||
| @@ -39,7 +36,6 @@ config SOC_VIRT · 5 unmodified lines | |||
| 39 | select POWER_RESET_SYSCON_POWEROFF | 36 | select POWER_RESET_SYSCON_POWEROFF |
| 40 | select GOLDFISH | 37 | select GOLDFISH |
| 41 | select RTC_DRV_GOLDFISH if RTC_CLASS | 38 | select RTC_DRV_GOLDFISH if RTC_CLASS |
| 42 | select SIFIVE_PLIC | ||
| 43 | select PM_GENERIC_DOMAINS if PM | 39 | select PM_GENERIC_DOMAINS if PM |
| 44 | select PM_GENERIC_DOMAINS_OF if PM && OF | 40 | select PM_GENERIC_DOMAINS_OF if PM && OF |
| 45 | select RISCV_SBI_CPUIDLE if CPU_IDLE && RISCV_SBI | 41 | select RISCV_SBI_CPUIDLE if CPU_IDLE && RISCV_SBI |
| @@ -52,7 +48,6 @@ config SOC_CANAAN · 6 unmodified lines | |||
| 52 | select CLINT_TIMER if RISCV_M_MODE | 48 | select CLINT_TIMER if RISCV_M_MODE |
| 53 | select SERIAL_SIFIVE if TTY | 49 | select SERIAL_SIFIVE if TTY |
| 54 | select SERIAL_SIFIVE_CONSOLE if TTY | 50 | select SERIAL_SIFIVE_CONSOLE if TTY |
| 55 | select SIFIVE_PLIC | ||
| 56 | select ARCH_HAS_RESET_CONTROLLER | 51 | select ARCH_HAS_RESET_CONTROLLER |
| 57 | select PINCTRL | 52 | select PINCTRL |
| 58 | select COMMON_CLK | 53 | select COMMON_CLK |
| @@ -56,6 +56,9 @@ $(obj)/Image.lzma: $(obj)/Image FORCE · 55 unmodified lines | |||
| 56 | $(obj)/Image.lzo: $(obj)/Image FORCE | 56 | $(obj)/Image.lzo: $(obj)/Image FORCE |
| 57 | $(call if_changed,lzo) | 57 | $(call if_changed,lzo) |
| 58 | 58 | ||
| 59 | $(obj)/Image.zst: $(obj)/Image FORCE | ||
| 60 | $(call if_changed,zstd) | ||
| 61 | |||
| 59 | $(obj)/loader.bin: $(obj)/loader FORCE | 62 | $(obj)/loader.bin: $(obj)/loader FORCE |
| 60 | $(call if_changed,objcopy) | 63 | $(call if_changed,objcopy) |
| 61 | 64 | ||
| @@ -39,6 +39,7 @@ CONFIG_KVM=m · 38 unmodified lines | |||
| 39 | CONFIG_JUMP_LABEL=y | 39 | CONFIG_JUMP_LABEL=y |
| 40 | CONFIG_MODULES=y | 40 | CONFIG_MODULES=y |
| 41 | CONFIG_MODULE_UNLOAD=y | 41 | CONFIG_MODULE_UNLOAD=y |
| 42 | CONFIG_SPARSEMEM_MANUAL=y | ||
| 42 | CONFIG_BLK_DEV_THROTTLING=y | 43 | CONFIG_BLK_DEV_THROTTLING=y |
| 43 | CONFIG_NET=y | 44 | CONFIG_NET=y |
| 44 | CONFIG_PACKET=y | 45 | CONFIG_PACKET=y |
| @@ -123,6 +124,7 @@ CONFIG_MICROSEMI_PHY=y · 78 unmodified lines | |||
| 123 | CONFIG_INPUT_MOUSEDEV=y | 124 | CONFIG_INPUT_MOUSEDEV=y |
| 124 | CONFIG_SERIAL_8250=y | 125 | CONFIG_SERIAL_8250=y |
| 125 | CONFIG_SERIAL_8250_CONSOLE=y | 126 | CONFIG_SERIAL_8250_CONSOLE=y |
| 127 | CONFIG_SERIAL_8250_DW=y | ||
| 126 | CONFIG_SERIAL_OF_PLATFORM=y | 128 | CONFIG_SERIAL_OF_PLATFORM=y |
| 127 | CONFIG_SERIAL_SH_SCI=y | 129 | CONFIG_SERIAL_SH_SCI=y |
| 128 | CONFIG_VIRTIO_CONSOLE=y | 130 | CONFIG_VIRTIO_CONSOLE=y |
| @@ -162,6 +164,7 @@ CONFIG_RPMSG_CHAR=y · 33 unmodified lines | |||
| 162 | CONFIG_RPMSG_CTRL=y | 164 | CONFIG_RPMSG_CTRL=y |
| 163 | CONFIG_RPMSG_VIRTIO=y | 165 | CONFIG_RPMSG_VIRTIO=y |
| 164 | CONFIG_ARCH_R9A07G043=y | 166 | CONFIG_ARCH_R9A07G043=y |
| 167 | CONFIG_LIBNVDIMM=y | ||
| 165 | CONFIG_EXT4_FS=y | 168 | CONFIG_EXT4_FS=y |
| 166 | CONFIG_EXT4_FS_POSIX_ACL=y | 169 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 167 | CONFIG_EXT4_FS_SECURITY=y | 170 | CONFIG_EXT4_FS_SECURITY=y |
| @@ -47,6 +47,22 @@ static bool errata_probe_cmo(unsigned int stage, · 46 unmodified lines | |||
| 47 | return true; | 47 | return true; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | static bool errata_probe_pmu(unsigned int stage, | ||
| 51 | unsigned long arch_id, unsigned long impid) | ||
| 52 | { | ||
| 53 | if (!IS_ENABLED(CONFIG_ERRATA_THEAD_PMU)) | ||
| 54 | return false; | ||
| 55 | |||
| 56 | /* target-c9xx cores report arch_id and impid as 0 */ | ||
| 57 | if (arch_id != 0 || impid != 0) | ||
| 58 | return false; | ||
| 59 | |||
| 60 | if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) | ||
| 61 | return false; | ||
| 62 | |||
| 63 | return true; | ||
| 64 | } | ||
| 65 | |||
| 50 | static u32 thead_errata_probe(unsigned int stage, | 66 | static u32 thead_errata_probe(unsigned int stage, |
| 51 | unsigned long archid, unsigned long impid) | 67 | unsigned long archid, unsigned long impid) |
| 52 | { | 68 | { |
| @@ -58,6 +74,9 @@ static u32 thead_errata_probe(unsigned int stage, · 5 unmodified lines | |||
| 58 | if (errata_probe_cmo(stage, archid, impid)) | 74 | if (errata_probe_cmo(stage, archid, impid)) |
| 59 | cpu_req_errata |= BIT(ERRATA_THEAD_CMO); | 75 | cpu_req_errata |= BIT(ERRATA_THEAD_CMO); |
| 60 | 76 | ||
| 77 | if (errata_probe_pmu(stage, archid, impid)) | ||
| 78 | cpu_req_errata |= BIT(ERRATA_THEAD_PMU); | ||
| 79 | |||
| 61 | return cpu_req_errata; | 80 | return cpu_req_errata; |
| 62 | } | 81 | } |
| 63 | 82 | ||
| @@ -33,7 +33,7 @@ · 32 unmodified lines | |||
| 33 | .endif | 33 | .endif |
| 34 | .endm | 34 | .endm |
| 35 | 35 | ||
| 36 | .macro __ALTERNATIVE_CFG old_c, new_c, vendor_id, errata_id, enable | 36 | .macro ALTERNATIVE_CFG old_c, new_c, vendor_id, errata_id, enable |
| 37 | 886 : | 37 | 886 : |
| 38 | .option push | 38 | .option push |
| 39 | .option norvc | 39 | .option norvc |
| @@ -44,30 +44,14 @@ · 4 unmodified lines | |||
| 44 | ALT_NEW_CONTENT \vendor_id, \errata_id, \enable, \new_c | 44 | ALT_NEW_CONTENT \vendor_id, \errata_id, \enable, \new_c |
| 45 | .endm | 45 | .endm |
| 46 | 46 | ||
| 47 | #define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k) \ | 47 | .macro ALTERNATIVE_CFG_2 old_c, new_c_1, vendor_id_1, errata_id_1, enable_1, \ |
| 48 | __ALTERNATIVE_CFG old_c, new_c, vendor_id, errata_id, IS_ENABLED(CONFIG_k) | 48 | new_c_2, vendor_id_2, errata_id_2, enable_2 |
| 49 | 49 | ALTERNATIVE_CFG \old_c, \new_c_1, \vendor_id_1, \errata_id_1, \enable_1 | |
| 50 | .macro __ALTERNATIVE_CFG_2 old_c, new_c_1, vendor_id_1, errata_id_1, enable_1, \ | ||
| 51 | new_c_2, vendor_id_2, errata_id_2, enable_2 | ||
| 52 | 886 : | ||
| 53 | .option push | ||
| 54 | .option norvc | ||
| 55 | .option norelax | ||
| 56 | \old_c | ||
| 57 | .option pop | ||
| 58 | 887 : | ||
| 59 | ALT_NEW_CONTENT \vendor_id_1, \errata_id_1, \enable_1, \new_c_1 | ||
| 60 | ALT_NEW_CONTENT \vendor_id_2, \errata_id_2, \enable_2, \new_c_2 | 50 | ALT_NEW_CONTENT \vendor_id_2, \errata_id_2, \enable_2, \new_c_2 |
| 61 | .endm | 51 | .endm |
| 62 | 52 | ||
| 63 | #define _ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, \ | 53 | #define __ALTERNATIVE_CFG(...) ALTERNATIVE_CFG __VA_ARGS__ |
| 64 | CONFIG_k_1, \ | 54 | #define __ALTERNATIVE_CFG_2(...) ALTERNATIVE_CFG_2 __VA_ARGS__ |
| 65 | new_c_2, vendor_id_2, errata_id_2, \ | ||
| 66 | CONFIG_k_2) \ | ||
| 67 | __ALTERNATIVE_CFG_2 old_c, new_c_1, vendor_id_1, errata_id_1, \ | ||
| 68 | IS_ENABLED(CONFIG_k_1), \ | ||
| 69 | new_c_2, vendor_id_2, errata_id_2, \ | ||
| 70 | IS_ENABLED(CONFIG_k_2) | ||
| 71 | 55 | ||
| 72 | #else /* !__ASSEMBLY__ */ | 56 | #else /* !__ASSEMBLY__ */ |
| 73 | 57 | ||
| @@ -109,63 +93,44 @@ · 35 unmodified lines | |||
| 109 | "887 :\n" \ | 93 | "887 :\n" \ |
| 110 | ALT_NEW_CONTENT(vendor_id, errata_id, enable, new_c) | 94 | ALT_NEW_CONTENT(vendor_id, errata_id, enable, new_c) |
| 111 | 95 | ||
| 112 | #define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k) \ | 96 | #define __ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, enable_1, \ |
| 113 | __ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, IS_ENABLED(CONFIG_k)) | 97 | new_c_2, vendor_id_2, errata_id_2, enable_2) \ |
| 114 | 98 | __ALTERNATIVE_CFG(old_c, new_c_1, vendor_id_1, errata_id_1, enable_1) \ | |
| 115 | #define __ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, \ | ||
| 116 | enable_1, \ | ||
| 117 | new_c_2, vendor_id_2, errata_id_2, \ | ||
| 118 | enable_2) \ | ||
| 119 | "886 :\n" \ | ||
| 120 | ".option push\n" \ | ||
| 121 | ".option norvc\n" \ | ||
| 122 | ".option norelax\n" \ | ||
| 123 | old_c "\n" \ | ||
| 124 | ".option pop\n" \ | ||
| 125 | "887 :\n" \ | ||
| 126 | ALT_NEW_CONTENT(vendor_id_1, errata_id_1, enable_1, new_c_1) \ | ||
| 127 | ALT_NEW_CONTENT(vendor_id_2, errata_id_2, enable_2, new_c_2) | 99 | ALT_NEW_CONTENT(vendor_id_2, errata_id_2, enable_2, new_c_2) |
| 128 | 100 | ||
| 129 | #define _ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, \ | ||
| 130 | CONFIG_k_1, \ | ||
| 131 | new_c_2, vendor_id_2, errata_id_2, \ | ||
| 132 | CONFIG_k_2) \ | ||
| 133 | __ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, \ | ||
| 134 | IS_ENABLED(CONFIG_k_1), \ | ||
| 135 | new_c_2, vendor_id_2, errata_id_2, \ | ||
| 136 | IS_ENABLED(CONFIG_k_2)) | ||
| 137 | |||
| 138 | #endif /* __ASSEMBLY__ */ | 101 | #endif /* __ASSEMBLY__ */ |
| 139 | 102 | ||
| 103 | #define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k) \ | ||
| 104 | __ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, IS_ENABLED(CONFIG_k)) | ||
| 105 | |||
| 106 | #define _ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, CONFIG_k_1, \ | ||
| 107 | new_c_2, vendor_id_2, errata_id_2, CONFIG_k_2) \ | ||
| 108 | __ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, IS_ENABLED(CONFIG_k_1), \ | ||
| 109 | new_c_2, vendor_id_2, errata_id_2, IS_ENABLED(CONFIG_k_2)) | ||
| 110 | |||
| 140 | #else /* CONFIG_RISCV_ALTERNATIVE */ | 111 | #else /* CONFIG_RISCV_ALTERNATIVE */ |
| 141 | #ifdef __ASSEMBLY__ | 112 | #ifdef __ASSEMBLY__ |
| 142 | 113 | ||
| 143 | .macro __ALTERNATIVE_CFG old_c | 114 | .macro ALTERNATIVE_CFG old_c |
| 144 | \old_c | 115 | \old_c |
| 145 | .endm | 116 | .endm |
| 146 | 117 | ||
| 147 | #define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k) \ | 118 | #define _ALTERNATIVE_CFG(old_c, ...) \ |
| 148 | __ALTERNATIVE_CFG old_c | 119 | ALTERNATIVE_CFG old_c |
| 149 | 120 | ||
| 150 | #define _ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, \ | 121 | #define _ALTERNATIVE_CFG_2(old_c, ...) \ |
| 151 | CONFIG_k_1, \ | 122 | ALTERNATIVE_CFG old_c |
| 152 | new_c_2, vendor_id_2, errata_id_2, \ | ||
| 153 | CONFIG_k_2) \ | ||
| 154 | __ALTERNATIVE_CFG old_c | ||
| 155 | 123 | ||
| 156 | #else /* !__ASSEMBLY__ */ | 124 | #else /* !__ASSEMBLY__ */ |
| 157 | 125 | ||
| 158 | #define __ALTERNATIVE_CFG(old_c) \ | 126 | #define __ALTERNATIVE_CFG(old_c) \ |
| 159 | old_c "\n" | 127 | old_c "\n" |
| 160 | 128 | ||
| 161 | #define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k) \ | 129 | #define _ALTERNATIVE_CFG(old_c, ...) \ |
| 162 | __ALTERNATIVE_CFG(old_c) | 130 | __ALTERNATIVE_CFG(old_c) |
| 163 | 131 | ||
| 164 | #define _ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, \ | 132 | #define _ALTERNATIVE_CFG_2(old_c, ...) \ |
| 165 | CONFIG_k_1, \ | 133 | __ALTERNATIVE_CFG(old_c) |
| 166 | new_c_2, vendor_id_2, errata_id_2, \ | ||
| 167 | CONFIG_k_2) \ | ||
| 168 | __ALTERNATIVE_CFG(old_c) | ||
| 169 | 134 | ||
| 170 | #endif /* __ASSEMBLY__ */ | 135 | #endif /* __ASSEMBLY__ */ |
| 171 | #endif /* CONFIG_RISCV_ALTERNATIVE */ | 136 | #endif /* CONFIG_RISCV_ALTERNATIVE */ |
| @@ -193,13 +158,9 @@ · 21 unmodified lines | |||
| 193 | * on the following sample code and then replace ALTERNATIVE() with | 158 | * on the following sample code and then replace ALTERNATIVE() with |
| 194 | * ALTERNATIVE_2() to append its customized content. | 159 | * ALTERNATIVE_2() to append its customized content. |
| 195 | */ | 160 | */ |
| 196 | #define ALTERNATIVE_2(old_content, new_content_1, vendor_id_1, \ | 161 | #define ALTERNATIVE_2(old_content, new_content_1, vendor_id_1, errata_id_1, CONFIG_k_1, \ |
| 197 | errata_id_1, CONFIG_k_1, \ | 162 | new_content_2, vendor_id_2, errata_id_2, CONFIG_k_2) \ |
| 198 | new_content_2, vendor_id_2, \ | 163 | _ALTERNATIVE_CFG_2(old_content, new_content_1, vendor_id_1, errata_id_1, CONFIG_k_1, \ |
| 199 | errata_id_2, CONFIG_k_2) \ | 164 | new_content_2, vendor_id_2, errata_id_2, CONFIG_k_2) |
| 200 | _ALTERNATIVE_CFG_2(old_content, new_content_1, vendor_id_1, \ | ||
| 201 | errata_id_1, CONFIG_k_1, \ | ||
| 202 | new_content_2, vendor_id_2, \ | ||
| 203 | errata_id_2, CONFIG_k_2) | ||
| 204 | 165 | ||
| 205 | #endif | 166 | #endif |
| @@ -17,6 +17,13 @@ static inline void local_flush_icache_all(void) · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | static inline void flush_dcache_page(struct page *page) | 18 | static inline void flush_dcache_page(struct page *page) |
| 19 | { | 19 | { |
| 20 | /* | ||
| 21 | * HugeTLB pages are always fully mapped and only head page will be | ||
| 22 | * set PG_dcache_clean (see comments in flush_icache_pte()). | ||
| 23 | */ | ||
| 24 | if (PageHuge(page)) | ||
| 25 | page = compound_head(page); | ||
| 26 | |||
| 20 | if (test_bit(PG_dcache_clean, &page->flags)) | 27 | if (test_bit(PG_dcache_clean, &page->flags)) |
| 21 | clear_bit(PG_dcache_clean, &page->flags); | 28 | clear_bit(PG_dcache_clean, &page->flags); |
| 22 | } | 29 | } |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | #define ASM_ERRATA_LIST_H | 6 | #define ASM_ERRATA_LIST_H |
| 7 | 7 | ||
| 8 | #include <asm/alternative.h> | 8 | #include <asm/alternative.h> |
| 9 | #include <asm/csr.h> | ||
| 9 | #include <asm/vendorid_list.h> | 10 | #include <asm/vendorid_list.h> |
| 10 | 11 | ||
| 11 | #ifdef CONFIG_ERRATA_SIFIVE | 12 | #ifdef CONFIG_ERRATA_SIFIVE |
| @@ -17,7 +18,8 @@ · 5 unmodified lines | |||
| 17 | #ifdef CONFIG_ERRATA_THEAD | 18 | #ifdef CONFIG_ERRATA_THEAD |
| 18 | #define ERRATA_THEAD_PBMT 0 | 19 | #define ERRATA_THEAD_PBMT 0 |
| 19 | #define ERRATA_THEAD_CMO 1 | 20 | #define ERRATA_THEAD_CMO 1 |
| 20 | #define ERRATA_THEAD_NUMBER 2 | 21 | #define ERRATA_THEAD_PMU 2 |
| 22 | #define ERRATA_THEAD_NUMBER 3 | ||
| 21 | #endif | 23 | #endif |
| 22 | 24 | ||
| 23 | #define CPUFEATURE_SVPBMT 0 | 25 | #define CPUFEATURE_SVPBMT 0 |
| @@ -142,6 +144,18 @@ asm volatile(ALTERNATIVE_2( \ · 118 unmodified lines | |||
| 142 | "r"((unsigned long)(_start) + (_size)) \ | 144 | "r"((unsigned long)(_start) + (_size)) \ |
| 143 | : "a0") | 145 | : "a0") |
| 144 | 146 | ||
| 147 | #define THEAD_C9XX_RV_IRQ_PMU 17 | ||
| 148 | #define THEAD_C9XX_CSR_SCOUNTEROF 0x5c5 | ||
| 149 | |||
| 150 | #define ALT_SBI_PMU_OVERFLOW(__ovl) \ | ||
| 151 | asm volatile(ALTERNATIVE( \ | ||
| 152 | "csrr %0, " __stringify(CSR_SSCOUNTOVF), \ | ||
| 153 | "csrr %0, " __stringify(THEAD_C9XX_CSR_SCOUNTEROF), \ | ||
| 154 | THEAD_VENDOR_ID, ERRATA_THEAD_PMU, \ | ||
| 155 | CONFIG_ERRATA_THEAD_PMU) \ | ||
| 156 | : "=r" (__ovl) : \ | ||
| 157 | : "memory") | ||
| 158 | |||
| 145 | #endif /* __ASSEMBLY__ */ | 159 | #endif /* __ASSEMBLY__ */ |
| 146 | 160 | ||
| 147 | #endif | 161 | #endif |
| @@ -5,4 +5,10 @@ · 4 unmodified lines | |||
| 5 | #include <asm-generic/hugetlb.h> | 5 | #include <asm-generic/hugetlb.h> |
| 6 | #include <asm/page.h> | 6 | #include <asm/page.h> |
| 7 | 7 | ||
| 8 | static inline void arch_clear_hugepage_flags(struct page *page) | ||
| 9 | { | ||
| 10 | clear_bit(PG_dcache_clean, &page->flags); | ||
| 11 | } | ||
| 12 | #define arch_clear_hugepage_flags arch_clear_hugepage_flags | ||
| 13 | |||
| 8 | #endif /* _ASM_RISCV_HUGETLB_H */ | 14 | #endif /* _ASM_RISCV_HUGETLB_H */ |
| @@ -59,8 +59,9 @@ enum riscv_isa_ext_id { · 58 unmodified lines | |||
| 59 | RISCV_ISA_EXT_ZIHINTPAUSE, | 59 | RISCV_ISA_EXT_ZIHINTPAUSE, |
| 60 | RISCV_ISA_EXT_SSTC, | 60 | RISCV_ISA_EXT_SSTC, |
| 61 | RISCV_ISA_EXT_SVINVAL, | 61 | RISCV_ISA_EXT_SVINVAL, |
| 62 | RISCV_ISA_EXT_ID_MAX = RISCV_ISA_EXT_MAX, | 62 | RISCV_ISA_EXT_ID_MAX |
| 63 | }; | 63 | }; |
| 64 | static_assert(RISCV_ISA_EXT_ID_MAX <= RISCV_ISA_EXT_MAX); | ||
| 64 | 65 | ||
| 65 | /* | 66 | /* |
| 66 | * This enum represents the logical ID for each RISC-V ISA extension static | 67 | * This enum represents the logical ID for each RISC-V ISA extension static |
| @@ -135,4 +135,9 @@ __io_writes_outs(outs, u64, q, __io_pbr(), __io_paw()) · 134 unmodified lines | |||
| 135 | 135 | ||
| 136 | #include <asm-generic/io.h> | 136 | #include <asm-generic/io.h> |
| 137 | 137 | ||
| 138 | #ifdef CONFIG_MMU | ||
| 139 | #define arch_memremap_wb(addr, size) \ | ||
| 140 | ((__force void *)ioremap_prot((addr), (size), _PAGE_KERNEL)) | ||
| 141 | #endif | ||
| 142 | |||
| 138 | #endif /* _ASM_RISCV_IO_H */ | 143 | #endif /* _ASM_RISCV_IO_H */ |
| @@ -39,6 +39,7 @@ crash_setup_regs(struct pt_regs *newregs, · 38 unmodified lines | |||
| 39 | #define ARCH_HAS_KIMAGE_ARCH | 39 | #define ARCH_HAS_KIMAGE_ARCH |
| 40 | 40 | ||
| 41 | struct kimage_arch { | 41 | struct kimage_arch { |
| 42 | void *fdt; /* For CONFIG_KEXEC_FILE */ | ||
| 42 | unsigned long fdt_addr; | 43 | unsigned long fdt_addr; |
| 43 | }; | 44 | }; |
| 44 | 45 | ||
| @@ -62,6 +63,10 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi, · 17 unmodified lines | |||
| 62 | const Elf_Shdr *relsec, | 63 | const Elf_Shdr *relsec, |
| 63 | const Elf_Shdr *symtab); | 64 | const Elf_Shdr *symtab); |
| 64 | #define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add | 65 | #define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add |
| 66 | |||
| 67 | struct kimage; | ||
| 68 | int arch_kimage_file_post_load_cleanup(struct kimage *image); | ||
| 69 | #define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup | ||
| 65 | #endif | 70 | #endif |
| 66 | 71 | ||
| 67 | #endif | 72 | #endif |
| @@ -40,8 +40,6 @@ void arch_remove_kprobe(struct kprobe *p); · 39 unmodified lines | |||
| 40 | int kprobe_fault_handler(struct pt_regs *regs, unsigned int trapnr); | 40 | int kprobe_fault_handler(struct pt_regs *regs, unsigned int trapnr); |
| 41 | bool kprobe_breakpoint_handler(struct pt_regs *regs); | 41 | bool kprobe_breakpoint_handler(struct pt_regs *regs); |
| 42 | bool kprobe_single_step_handler(struct pt_regs *regs); | 42 | bool kprobe_single_step_handler(struct pt_regs *regs); |
| 43 | void __kretprobe_trampoline(void); | ||
| 44 | void __kprobes *trampoline_probe_handler(struct pt_regs *regs); | ||
| 45 | 43 | ||
| 46 | #endif /* CONFIG_KPROBES */ | 44 | #endif /* CONFIG_KPROBES */ |
| 47 | #endif /* _ASM_RISCV_KPROBES_H */ | 45 | #endif /* _ASM_RISCV_KPROBES_H */ |
| @@ -19,6 +19,8 @@ typedef struct { · 18 unmodified lines | |||
| 19 | #ifdef CONFIG_SMP | 19 | #ifdef CONFIG_SMP |
| 20 | /* A local icache flush is needed before user execution can resume. */ | 20 | /* A local icache flush is needed before user execution can resume. */ |
| 21 | cpumask_t icache_stale_mask; | 21 | cpumask_t icache_stale_mask; |
| 22 | /* A local tlb flush is needed before user execution can resume. */ | ||
| 23 | cpumask_t tlb_stale_mask; | ||
| 22 | #endif | 24 | #endif |
| 23 | } mm_context_t; | 25 | } mm_context_t; |
| 24 | 26 | ||
| @@ -123,20 +123,20 @@ extern phys_addr_t phys_ram_base; · 122 unmodified lines | |||
| 123 | ((x) >= PAGE_OFFSET && (!IS_ENABLED(CONFIG_64BIT) || (x) < PAGE_OFFSET + KERN_VIRT_SIZE)) | 123 | ((x) >= PAGE_OFFSET && (!IS_ENABLED(CONFIG_64BIT) || (x) < PAGE_OFFSET + KERN_VIRT_SIZE)) |
| 124 | 124 | ||
| 125 | #define linear_mapping_pa_to_va(x) ((void *)((unsigned long)(x) + kernel_map.va_pa_offset)) | 125 | #define linear_mapping_pa_to_va(x) ((void *)((unsigned long)(x) + kernel_map.va_pa_offset)) |
| 126 | #define kernel_mapping_pa_to_va(y) ({ \ | 126 | #define kernel_mapping_pa_to_va(y) ({ \ |
| 127 | unsigned long _y = y; \ | 127 | unsigned long _y = (unsigned long)(y); \ |
| 128 | (IS_ENABLED(CONFIG_XIP_KERNEL) && _y < phys_ram_base) ? \ | 128 | (IS_ENABLED(CONFIG_XIP_KERNEL) && _y < phys_ram_base) ? \ |
| 129 | (void *)((unsigned long)(_y) + kernel_map.va_kernel_xip_pa_offset) : \ | 129 | (void *)(_y + kernel_map.va_kernel_xip_pa_offset) : \ |
| 130 | (void *)((unsigned long)(_y) + kernel_map.va_kernel_pa_offset + XIP_OFFSET); \ | 130 | (void *)(_y + kernel_map.va_kernel_pa_offset + XIP_OFFSET); \ |
| 131 | }) | 131 | }) |
| 132 | #define __pa_to_va_nodebug(x) linear_mapping_pa_to_va(x) | 132 | #define __pa_to_va_nodebug(x) linear_mapping_pa_to_va(x) |
| 133 | 133 | ||
| 134 | #define linear_mapping_va_to_pa(x) ((unsigned long)(x) - kernel_map.va_pa_offset) | 134 | #define linear_mapping_va_to_pa(x) ((unsigned long)(x) - kernel_map.va_pa_offset) |
| 135 | #define kernel_mapping_va_to_pa(y) ({ \ | 135 | #define kernel_mapping_va_to_pa(y) ({ \ |
| 136 | unsigned long _y = y; \ | 136 | unsigned long _y = (unsigned long)(y); \ |
| 137 | (IS_ENABLED(CONFIG_XIP_KERNEL) && _y < kernel_map.virt_addr + XIP_OFFSET) ? \ | 137 | (IS_ENABLED(CONFIG_XIP_KERNEL) && _y < kernel_map.virt_addr + XIP_OFFSET) ? \ |
| 138 | ((unsigned long)(_y) - kernel_map.va_kernel_xip_pa_offset) : \ | 138 | (_y - kernel_map.va_kernel_xip_pa_offset) : \ |
| 139 | ((unsigned long)(_y) - kernel_map.va_kernel_pa_offset - XIP_OFFSET); \ | 139 | (_y - kernel_map.va_kernel_pa_offset - XIP_OFFSET); \ |
| 140 | }) | 140 | }) |
| 141 | 141 | ||
| 142 | #define __va_to_pa_nodebug(x) ({ \ | 142 | #define __va_to_pa_nodebug(x) ({ \ |
| @@ -25,7 +25,11 @@ extern bool pgtable_l5_enabled; · 24 unmodified lines | |||
| 25 | #define PGDIR_MASK (~(PGDIR_SIZE - 1)) | 25 | #define PGDIR_MASK (~(PGDIR_SIZE - 1)) |
| 26 | 26 | ||
| 27 | /* p4d is folded into pgd in case of 4-level page table */ | 27 | /* p4d is folded into pgd in case of 4-level page table */ |
| 28 | #define P4D_SHIFT 39 | 28 | #define P4D_SHIFT_L3 30 |
| 29 | #define P4D_SHIFT_L4 39 | ||
| 30 | #define P4D_SHIFT_L5 39 | ||
| 31 | #define P4D_SHIFT (pgtable_l5_enabled ? P4D_SHIFT_L5 : \ | ||
| 32 | (pgtable_l4_enabled ? P4D_SHIFT_L4 : P4D_SHIFT_L3)) | ||
| 29 | #define P4D_SIZE (_AC(1, UL) << P4D_SHIFT) | 33 | #define P4D_SIZE (_AC(1, UL) << P4D_SHIFT) |
| 30 | #define P4D_MASK (~(P4D_SIZE - 1)) | 34 | #define P4D_MASK (~(P4D_SIZE - 1)) |
| 31 | 35 | ||
| @@ -415,9 +415,12 @@ static inline void update_mmu_cache(struct vm_area_struct *vma, · 414 unmodified lines | |||
| 415 | * Relying on flush_tlb_fix_spurious_fault would suffice, but | 415 | * Relying on flush_tlb_fix_spurious_fault would suffice, but |
| 416 | * the extra traps reduce performance. So, eagerly SFENCE.VMA. | 416 | * the extra traps reduce performance. So, eagerly SFENCE.VMA. |
| 417 | */ | 417 | */ |
| 418 | local_flush_tlb_page(address); | 418 | flush_tlb_page(vma, address); |
| 419 | } | 419 | } |
| 420 | 420 | ||
| 421 | #define __HAVE_ARCH_UPDATE_MMU_TLB | ||
| 422 | #define update_mmu_tlb update_mmu_cache | ||
| 423 | |||
| 421 | static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, | 424 | static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, |
| 422 | unsigned long address, pmd_t *pmdp) | 425 | unsigned long address, pmd_t *pmdp) |
| 423 | { | 426 | { |
| @@ -327,4 +327,9 @@ int sbi_err_map_linux_errno(int err); · 326 unmodified lines | |||
| 327 | static inline int sbi_remote_fence_i(const struct cpumask *cpu_mask) { return -1; } | 327 | static inline int sbi_remote_fence_i(const struct cpumask *cpu_mask) { return -1; } |
| 328 | static inline void sbi_init(void) {} | 328 | static inline void sbi_init(void) {} |
| 329 | #endif /* CONFIG_RISCV_SBI */ | 329 | #endif /* CONFIG_RISCV_SBI */ |
| 330 | |||
| 331 | unsigned long riscv_cached_mvendorid(unsigned int cpu_id); | ||
| 332 | unsigned long riscv_cached_marchid(unsigned int cpu_id); | ||
| 333 | unsigned long riscv_cached_mimpid(unsigned int cpu_id); | ||
| 334 | |||
| 330 | #endif /* _ASM_RISCV_SBI_H */ | 335 | #endif /* _ASM_RISCV_SBI_H */ |
| @@ -22,6 +22,24 @@ static inline void local_flush_tlb_page(unsigned long addr) · 21 unmodified lines | |||
| 22 | { | 22 | { |
| 23 | ALT_FLUSH_TLB_PAGE(__asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory")); | 23 | ALT_FLUSH_TLB_PAGE(__asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory")); |
| 24 | } | 24 | } |
| 25 | |||
| 26 | static inline void local_flush_tlb_all_asid(unsigned long asid) | ||
| 27 | { | ||
| 28 | __asm__ __volatile__ ("sfence.vma x0, %0" | ||
| 29 | : | ||
| 30 | : "r" (asid) | ||
| 31 | : "memory"); | ||
| 32 | } | ||
| 33 | |||
| 34 | static inline void local_flush_tlb_page_asid(unsigned long addr, | ||
| 35 | unsigned long asid) | ||
| 36 | { | ||
| 37 | __asm__ __volatile__ ("sfence.vma %0, %1" | ||
| 38 | : | ||
| 39 | : "r" (addr), "r" (asid) | ||
| 40 | : "memory"); | ||
| 41 | } | ||
| 42 | |||
| 25 | #else /* CONFIG_MMU */ | 43 | #else /* CONFIG_MMU */ |
| 26 | #define local_flush_tlb_all() do { } while (0) | 44 | #define local_flush_tlb_all() do { } while (0) |
| 27 | #define local_flush_tlb_page(addr) do { } while (0) | 45 | #define local_flush_tlb_page(addr) do { } while (0) |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | |||
| 10 | 10 | ||
| 11 | /* | 11 | /* |
| 12 | * All systems with an MMU have a VDSO, but systems without an MMU don't | 12 | * All systems with an MMU have a VDSO, but systems without an MMU don't |
| 13 | * support shared libraries and therefor don't have one. | 13 | * support shared libraries and therefore don't have one. |
| 14 | */ | 14 | */ |
| 15 | #ifdef CONFIG_MMU | 15 | #ifdef CONFIG_MMU |
| 16 | 16 | ||
| @@ -1,4 +1,22 @@ | |||
| 1 | #ifndef _ASM_RISCV_VMALLOC_H | 1 | #ifndef _ASM_RISCV_VMALLOC_H |
| 2 | #define _ASM_RISCV_VMALLOC_H | 2 | #define _ASM_RISCV_VMALLOC_H |
| 3 | 3 | ||
| 4 | #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP | ||
| 5 | |||
| 6 | #define IOREMAP_MAX_ORDER (PUD_SHIFT) | ||
| 7 | |||
| 8 | #define arch_vmap_pud_supported arch_vmap_pud_supported | ||
| 9 | static inline bool arch_vmap_pud_supported(pgprot_t prot) | ||
| 10 | { | ||
| 11 | return true; | ||
| 12 | } | ||
| 13 | |||
| 14 | #define arch_vmap_pmd_supported arch_vmap_pmd_supported | ||
| 15 | static inline bool arch_vmap_pmd_supported(pgprot_t prot) | ||
| 16 | { | ||
| 17 | return true; | ||
| 18 | } | ||
| 19 | |||
| 20 | #endif | ||
| 21 | |||
| 4 | #endif /* _ASM_RISCV_VMALLOC_H */ | 22 | #endif /* _ASM_RISCV_VMALLOC_H */ |
| @@ -15,19 +15,23 @@ struct ucontext { · 14 unmodified lines | |||
| 15 | struct ucontext *uc_link; | 15 | struct ucontext *uc_link; |
| 16 | stack_t uc_stack; | 16 | stack_t uc_stack; |
| 17 | sigset_t uc_sigmask; | 17 | sigset_t uc_sigmask; |
| 18 | /* There's some padding here to allow sigset_t to be expanded in the | 18 | /* |
| 19 | * There's some padding here to allow sigset_t to be expanded in the | ||
| 19 | * future. Though this is unlikely, other architectures put uc_sigmask | 20 | * future. Though this is unlikely, other architectures put uc_sigmask |
| 20 | * at the end of this structure and explicitly state it can be | 21 | * at the end of this structure and explicitly state it can be |
| 21 | * expanded, so we didn't want to box ourselves in here. */ | 22 | * expanded, so we didn't want to box ourselves in here. |
| 23 | */ | ||
| 22 | __u8 __unused[1024 / 8 - sizeof(sigset_t)]; | 24 | __u8 __unused[1024 / 8 - sizeof(sigset_t)]; |
| 23 | /* We can't put uc_sigmask at the end of this structure because we need | 25 | /* |
| 26 | * We can't put uc_sigmask at the end of this structure because we need | ||
| 24 | * to be able to expand sigcontext in the future. For example, the | 27 | * to be able to expand sigcontext in the future. For example, the |
| 25 | * vector ISA extension will almost certainly add ISA state. We want | 28 | * vector ISA extension will almost certainly add ISA state. We want |
| 26 | * to ensure all user-visible ISA state can be saved and restored via a | 29 | * to ensure all user-visible ISA state can be saved and restored via a |
| 27 | * ucontext, so we're putting this at the end in order to allow for | 30 | * ucontext, so we're putting this at the end in order to allow for |
| 28 | * infinite extensibility. Since we know this will be extended and we | 31 | * infinite extensibility. Since we know this will be extended and we |
| 29 | * assume sigset_t won't be extended an extreme amount, we're | 32 | * assume sigset_t won't be extended an extreme amount, we're |
| 30 | * prioritizing this. */ | 33 | * prioritizing this. |
| 34 | */ | ||
| 31 | struct sigcontext uc_mcontext; | 35 | struct sigcontext uc_mcontext; |
| 32 | }; | 36 | }; |
| 33 | 37 | ||
| @@ -81,6 +81,7 @@ obj-$(CONFIG_KGDB) += kgdb.o · 80 unmodified lines | |||
| 81 | obj-$(CONFIG_KEXEC_CORE) += kexec_relocate.o crash_save_regs.o machine_kexec.o | 81 | obj-$(CONFIG_KEXEC_CORE) += kexec_relocate.o crash_save_regs.o machine_kexec.o |
| 82 | obj-$(CONFIG_KEXEC_FILE) += elf_kexec.o machine_kexec_file.o | 82 | obj-$(CONFIG_KEXEC_FILE) += elf_kexec.o machine_kexec_file.o |
| 83 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o | 83 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o |
| 84 | obj-$(CONFIG_CRASH_CORE) += crash_core.o | ||
| 84 | 85 | ||
| 85 | obj-$(CONFIG_JUMP_LABEL) += jump_label.o | 86 | obj-$(CONFIG_JUMP_LABEL) += jump_label.o |
| 86 | 87 | ||
| @@ -70,8 +70,6 @@ int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid) · 69 unmodified lines | |||
| 70 | return -1; | 70 | return -1; |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | #ifdef CONFIG_PROC_FS | ||
| 74 | |||
| 75 | struct riscv_cpuinfo { | 73 | struct riscv_cpuinfo { |
| 76 | unsigned long mvendorid; | 74 | unsigned long mvendorid; |
| 77 | unsigned long marchid; | 75 | unsigned long marchid; |
| @@ -79,6 +77,30 @@ struct riscv_cpuinfo { · 1 unmodified line | |||
| 79 | }; | 77 | }; |
| 80 | static DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo); | 78 | static DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo); |
| 81 | 79 | ||
| 80 | unsigned long riscv_cached_mvendorid(unsigned int cpu_id) | ||
| 81 | { | ||
| 82 | struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id); | ||
| 83 | |||
| 84 | return ci->mvendorid; | ||
| 85 | } | ||
| 86 | EXPORT_SYMBOL(riscv_cached_mvendorid); | ||
| 87 | |||
| 88 | unsigned long riscv_cached_marchid(unsigned int cpu_id) | ||
| 89 | { | ||
| 90 | struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id); | ||
| 91 | |||
| 92 | return ci->marchid; | ||
| 93 | } | ||
| 94 | EXPORT_SYMBOL(riscv_cached_marchid); | ||
| 95 | |||
| 96 | unsigned long riscv_cached_mimpid(unsigned int cpu_id) | ||
| 97 | { | ||
| 98 | struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id); | ||
| 99 | |||
| 100 | return ci->mimpid; | ||
| 101 | } | ||
| 102 | EXPORT_SYMBOL(riscv_cached_mimpid); | ||
| 103 | |||
| 82 | static int riscv_cpuinfo_starting(unsigned int cpu) | 104 | static int riscv_cpuinfo_starting(unsigned int cpu) |
| 83 | { | 105 | { |
| 84 | struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo); | 106 | struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo); |
| @@ -113,7 +135,9 @@ static int __init riscv_cpuinfo_init(void) · 28 unmodified lines | |||
| 113 | 135 | ||
| 114 | return 0; | 136 | return 0; |
| 115 | } | 137 | } |
| 116 | device_initcall(riscv_cpuinfo_init); | 138 | arch_initcall(riscv_cpuinfo_init); |
| 139 | |||
| 140 | #ifdef CONFIG_PROC_FS | ||
| 117 | 141 | ||
| 118 | #define __RISCV_ISA_EXT_DATA(UPROP, EXTID) \ | 142 | #define __RISCV_ISA_EXT_DATA(UPROP, EXTID) \ |
| 119 | { \ | 143 | { \ |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | #include <linux/bitmap.h> | 9 | #include <linux/bitmap.h> |
| 10 | #include <linux/ctype.h> | 10 | #include <linux/ctype.h> |
| 11 | #include <linux/libfdt.h> | 11 | #include <linux/libfdt.h> |
| 12 | #include <linux/log2.h> | ||
| 12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 13 | #include <linux/of.h> | 14 | #include <linux/of.h> |
| 14 | #include <asm/alternative.h> | 15 | #include <asm/alternative.h> |
| @@ -68,21 +69,38 @@ bool __riscv_isa_extension_available(const unsigned long *isa_bitmap, int bit) · 53 unmodified lines | |||
| 68 | } | 69 | } |
| 69 | EXPORT_SYMBOL_GPL(__riscv_isa_extension_available); | 70 | EXPORT_SYMBOL_GPL(__riscv_isa_extension_available); |
| 70 | 71 | ||
| 72 | static bool riscv_isa_extension_check(int id) | ||
| 73 | { | ||
| 74 | switch (id) { | ||
| 75 | case RISCV_ISA_EXT_ZICBOM: | ||
| 76 | if (!riscv_cbom_block_size) { | ||
| 77 | pr_err("Zicbom detected in ISA string, but no cbom-block-size found\n"); | ||
| 78 | return false; | ||
| 79 | } else if (!is_power_of_2(riscv_cbom_block_size)) { | ||
| 80 | pr_err("cbom-block-size present, but is not a power-of-2\n"); | ||
| 81 | return false; | ||
| 82 | } | ||
| 83 | return true; | ||
| 84 | } | ||
| 85 | |||
| 86 | return true; | ||
| 87 | } | ||
| 88 | |||
| 71 | void __init riscv_fill_hwcap(void) | 89 | void __init riscv_fill_hwcap(void) |
| 72 | { | 90 | { |
| 73 | struct device_node *node; | 91 | struct device_node *node; |
| 74 | const char *isa; | 92 | const char *isa; |
| 75 | char print_str[NUM_ALPHA_EXTS + 1]; | 93 | char print_str[NUM_ALPHA_EXTS + 1]; |
| 76 | int i, j, rc; | 94 | int i, j, rc; |
| 77 | static unsigned long isa2hwcap[256] = {0}; | 95 | unsigned long isa2hwcap[26] = {0}; |
| 78 | unsigned long hartid; | 96 | unsigned long hartid; |
| 79 | 97 | ||
| 80 | isa2hwcap['i'] = isa2hwcap['I'] = COMPAT_HWCAP_ISA_I; | 98 | isa2hwcap['i' - 'a'] = COMPAT_HWCAP_ISA_I; |
| 81 | isa2hwcap['m'] = isa2hwcap['M'] = COMPAT_HWCAP_ISA_M; | 99 | isa2hwcap['m' - 'a'] = COMPAT_HWCAP_ISA_M; |
| 82 | isa2hwcap['a'] = isa2hwcap['A'] = COMPAT_HWCAP_ISA_A; | 100 | isa2hwcap['a' - 'a'] = COMPAT_HWCAP_ISA_A; |
| 83 | isa2hwcap['f'] = isa2hwcap['F'] = COMPAT_HWCAP_ISA_F; | 101 | isa2hwcap['f' - 'a'] = COMPAT_HWCAP_ISA_F; |
| 84 | isa2hwcap['d'] = isa2hwcap['D'] = COMPAT_HWCAP_ISA_D; | 102 | isa2hwcap['d' - 'a'] = COMPAT_HWCAP_ISA_D; |
| 85 | isa2hwcap['c'] = isa2hwcap['C'] = COMPAT_HWCAP_ISA_C; | 103 | isa2hwcap['c' - 'a'] = COMPAT_HWCAP_ISA_C; |
| 86 | 104 | ||
| 87 | elf_hwcap = 0; | 105 | elf_hwcap = 0; |
| 88 | 106 | ||
| @@ -189,15 +207,20 @@ void __init riscv_fill_hwcap(void) · 100 unmodified lines | |||
| 189 | #define SET_ISA_EXT_MAP(name, bit) \ | 207 | #define SET_ISA_EXT_MAP(name, bit) \ |
| 190 | do { \ | 208 | do { \ |
| 191 | if ((ext_end - ext == sizeof(name) - 1) && \ | 209 | if ((ext_end - ext == sizeof(name) - 1) && \ |
| 192 | !memcmp(ext, name, sizeof(name) - 1)) \ | 210 | !memcmp(ext, name, sizeof(name) - 1) && \ |
| 211 | riscv_isa_extension_check(bit)) \ | ||
| 193 | set_bit(bit, this_isa); \ | 212 | set_bit(bit, this_isa); \ |
| 194 | } while (false) \ | 213 | } while (false) \ |
| 195 | 214 | ||
| 196 | if (unlikely(ext_err)) | 215 | if (unlikely(ext_err)) |
| 197 | continue; | 216 | continue; |
| 198 | if (!ext_long) { | 217 | if (!ext_long) { |
| 199 | this_hwcap |= isa2hwcap[(unsigned char)(*ext)]; | 218 | int nr = *ext - 'a'; |
| 200 | set_bit(*ext - 'a', this_isa); | 219 | |
| 220 | if (riscv_isa_extension_check(nr)) { | ||
| 221 | this_hwcap |= isa2hwcap[nr]; | ||
| 222 | set_bit(nr, this_isa); | ||
| 223 | } | ||
| 201 | } else { | 224 | } else { |
| 202 | SET_ISA_EXT_MAP("sscofpmf", RISCV_ISA_EXT_SSCOFPMF); | 225 | SET_ISA_EXT_MAP("sscofpmf", RISCV_ISA_EXT_SSCOFPMF); |
| 203 | SET_ISA_EXT_MAP("svpbmt", RISCV_ISA_EXT_SVPBMT); | 226 | SET_ISA_EXT_MAP("svpbmt", RISCV_ISA_EXT_SVPBMT); |
| @@ -0,0 +1,21 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | |||
| 3 | #include <linux/crash_core.h> | ||
| 4 | #include <linux/pagemap.h> | ||
| 5 | |||
| 6 | void arch_crash_save_vmcoreinfo(void) | ||
| 7 | { | ||
| 8 | VMCOREINFO_NUMBER(VA_BITS); | ||
| 9 | VMCOREINFO_NUMBER(phys_ram_base); | ||
| 10 | |||
| 11 | vmcoreinfo_append_str("NUMBER(PAGE_OFFSET)=0x%lx\n", PAGE_OFFSET); | ||
| 12 | vmcoreinfo_append_str("NUMBER(VMALLOC_START)=0x%lx\n", VMALLOC_START); | ||
| 13 | vmcoreinfo_append_str("NUMBER(VMALLOC_END)=0x%lx\n", VMALLOC_END); | ||
| 14 | vmcoreinfo_append_str("NUMBER(VMEMMAP_START)=0x%lx\n", VMEMMAP_START); | ||
| 15 | vmcoreinfo_append_str("NUMBER(VMEMMAP_END)=0x%lx\n", VMEMMAP_END); | ||
| 16 | #ifdef CONFIG_64BIT | ||
| 17 | vmcoreinfo_append_str("NUMBER(MODULES_VADDR)=0x%lx\n", MODULES_VADDR); | ||
| 18 | vmcoreinfo_append_str("NUMBER(MODULES_END)=0x%lx\n", MODULES_END); | ||
| 19 | #endif | ||
| 20 | vmcoreinfo_append_str("NUMBER(KERNEL_LINK_ADDR)=0x%lx\n", KERNEL_LINK_ADDR); | ||
| 21 | } | ||
| @@ -21,6 +21,18 @@ · 20 unmodified lines | |||
| 21 | #include <linux/memblock.h> | 21 | #include <linux/memblock.h> |
| 22 | #include <asm/setup.h> | 22 | #include <asm/setup.h> |
| 23 | 23 | ||
| 24 | int arch_kimage_file_post_load_cleanup(struct kimage *image) | ||
| 25 | { | ||
| 26 | kvfree(image->arch.fdt); | ||
| 27 | image->arch.fdt = NULL; | ||
| 28 | |||
| 29 | vfree(image->elf_headers); | ||
| 30 | image->elf_headers = NULL; | ||
| 31 | image->elf_headers_sz = 0; | ||
| 32 | |||
| 33 | return kexec_image_post_load_cleanup_default(image); | ||
| 34 | } | ||
| 35 | |||
| 24 | static int riscv_kexec_elf_load(struct kimage *image, struct elfhdr *ehdr, | 36 | static int riscv_kexec_elf_load(struct kimage *image, struct elfhdr *ehdr, |
| 25 | struct kexec_elf_info *elf_info, unsigned long old_pbase, | 37 | struct kexec_elf_info *elf_info, unsigned long old_pbase, |
| 26 | unsigned long new_pbase) | 38 | unsigned long new_pbase) |
| @@ -298,6 +310,8 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf, · 271 unmodified lines | |||
| 298 | pr_err("Error add DTB kbuf ret=%d\n", ret); | 310 | pr_err("Error add DTB kbuf ret=%d\n", ret); |
| 299 | goto out_free_fdt; | 311 | goto out_free_fdt; |
| 300 | } | 312 | } |
| 313 | /* Cache the fdt buffer address for memory cleanup */ | ||
| 314 | image->arch.fdt = fdt; | ||
| 301 | pr_notice("Loaded device tree at 0x%lx\n", kbuf.mem); | 315 | pr_notice("Loaded device tree at 0x%lx\n", kbuf.mem); |
| 302 | goto out; | 316 | goto out; |
| 303 | 317 | ||
| @@ -248,7 +248,7 @@ ret_from_syscall_rejected: · 247 unmodified lines | |||
| 248 | andi t0, t0, _TIF_SYSCALL_WORK | 248 | andi t0, t0, _TIF_SYSCALL_WORK |
| 249 | bnez t0, handle_syscall_trace_exit | 249 | bnez t0, handle_syscall_trace_exit |
| 250 | 250 | ||
| 251 | ret_from_exception: | 251 | SYM_CODE_START_NOALIGN(ret_from_exception) |
| 252 | REG_L s0, PT_STATUS(sp) | 252 | REG_L s0, PT_STATUS(sp) |
| 253 | csrc CSR_STATUS, SR_IE | 253 | csrc CSR_STATUS, SR_IE |
| 254 | #ifdef CONFIG_TRACE_IRQFLAGS | 254 | #ifdef CONFIG_TRACE_IRQFLAGS |
| @@ -262,13 +262,13 @@ ret_from_exception: · 7 unmodified lines | |||
| 262 | andi s0, s0, SR_SPP | 262 | andi s0, s0, SR_SPP |
| 263 | #endif | 263 | #endif |
| 264 | bnez s0, resume_kernel | 264 | bnez s0, resume_kernel |
| 265 | SYM_CODE_END(ret_from_exception) | ||
| 265 | 266 | ||
| 266 | resume_userspace: | ||
| 267 | /* Interrupts must be disabled here so flags are checked atomically */ | 267 | /* Interrupts must be disabled here so flags are checked atomically */ |
| 268 | REG_L s0, TASK_TI_FLAGS(tp) /* current_thread_info->flags */ | 268 | REG_L s0, TASK_TI_FLAGS(tp) /* current_thread_info->flags */ |
| 269 | andi s1, s0, _TIF_WORK_MASK | 269 | andi s1, s0, _TIF_WORK_MASK |
| 270 | bnez s1, work_pending | 270 | bnez s1, resume_userspace_slow |
| 271 | 271 | resume_userspace: | |
| 272 | #ifdef CONFIG_CONTEXT_TRACKING_USER | 272 | #ifdef CONFIG_CONTEXT_TRACKING_USER |
| 273 | call user_enter_callable | 273 | call user_enter_callable |
| 274 | #endif | 274 | #endif |
| @@ -368,19 +368,12 @@ resume_kernel: · 93 unmodified lines | |||
| 368 | j restore_all | 368 | j restore_all |
| 369 | #endif | 369 | #endif |
| 370 | 370 | ||
| 371 | work_pending: | 371 | resume_userspace_slow: |
| 372 | /* Enter slow path for supplementary processing */ | 372 | /* Enter slow path for supplementary processing */ |
| 373 | la ra, ret_from_exception | ||
| 374 | andi s1, s0, _TIF_NEED_RESCHED | ||
| 375 | bnez s1, work_resched | ||
| 376 | work_notifysig: | ||
| 377 | /* Handle pending signals and notify-resume requests */ | ||
| 378 | csrs CSR_STATUS, SR_IE /* Enable interrupts for do_notify_resume() */ | ||
| 379 | move a0, sp /* pt_regs */ | 373 | move a0, sp /* pt_regs */ |
| 380 | move a1, s0 /* current_thread_info->flags */ | 374 | move a1, s0 /* current_thread_info->flags */ |
| 381 | tail do_notify_resume | 375 | call do_work_pending |
| 382 | work_resched: | 376 | j resume_userspace |
| 383 | tail schedule | ||
| 384 | 377 | ||
| 385 | /* Slow paths for ptrace. */ | 378 | /* Slow paths for ptrace. */ |
| 386 | handle_syscall_trace_enter: | 379 | handle_syscall_trace_enter: |
| @@ -15,8 +15,8 @@ · 14 unmodified lines | |||
| 15 | 15 | ||
| 16 | .macro SAVE_ABI_STATE | 16 | .macro SAVE_ABI_STATE |
| 17 | addi sp, sp, -16 | 17 | addi sp, sp, -16 |
| 18 | sd s0, 0(sp) | 18 | REG_S s0, 0*SZREG(sp) |
| 19 | sd ra, 8(sp) | 19 | REG_S ra, 1*SZREG(sp) |
| 20 | addi s0, sp, 16 | 20 | addi s0, sp, 16 |
| 21 | .endm | 21 | .endm |
| 22 | 22 | ||
| @@ -25,24 +25,26 @@ · 2 unmodified lines | |||
| 25 | * register if a0 was not saved. | 25 | * register if a0 was not saved. |
| 26 | */ | 26 | */ |
| 27 | .macro SAVE_RET_ABI_STATE | 27 | .macro SAVE_RET_ABI_STATE |
| 28 | addi sp, sp, -32 | 28 | addi sp, sp, -4*SZREG |
| 29 | sd s0, 16(sp) | 29 | REG_S s0, 2*SZREG(sp) |
| 30 | sd ra, 24(sp) | 30 | REG_S ra, 3*SZREG(sp) |
| 31 | sd a0, 8(sp) | 31 | REG_S a0, 1*SZREG(sp) |
| 32 | addi s0, sp, 32 | 32 | REG_S a1, 0*SZREG(sp) |
| 33 | addi s0, sp, 4*SZREG | ||
| 33 | .endm | 34 | .endm |
| 34 | 35 | ||
| 35 | .macro RESTORE_ABI_STATE | 36 | .macro RESTORE_ABI_STATE |
| 36 | ld ra, 8(sp) | 37 | REG_L ra, 1*SZREG(sp) |
| 37 | ld s0, 0(sp) | 38 | REG_L s0, 0*SZREG(sp) |
| 38 | addi sp, sp, 16 | 39 | addi sp, sp, 16 |
| 39 | .endm | 40 | .endm |
| 40 | 41 | ||
| 41 | .macro RESTORE_RET_ABI_STATE | 42 | .macro RESTORE_RET_ABI_STATE |
| 42 | ld ra, 24(sp) | 43 | REG_L ra, 3*SZREG(sp) |
| 43 | ld s0, 16(sp) | 44 | REG_L s0, 2*SZREG(sp) |
| 44 | ld a0, 8(sp) | 45 | REG_L a0, 1*SZREG(sp) |
| 45 | addi sp, sp, 32 | 46 | REG_L a1, 0*SZREG(sp) |
| 47 | addi sp, sp, 4*SZREG | ||
| 46 | .endm | 48 | .endm |
| 47 | 49 | ||
| 48 | ENTRY(ftrace_stub) | 50 | ENTRY(ftrace_stub) |
| @@ -71,9 +73,9 @@ ENTRY(return_to_handler) · 22 unmodified lines | |||
| 71 | mv a0, t6 | 73 | mv a0, t6 |
| 72 | #endif | 74 | #endif |
| 73 | call ftrace_return_to_handler | 75 | call ftrace_return_to_handler |
| 74 | mv a1, a0 | 76 | mv a2, a0 |
| 75 | RESTORE_RET_ABI_STATE | 77 | RESTORE_RET_ABI_STATE |
| 76 | jalr a1 | 78 | jalr a2 |
| 77 | ENDPROC(return_to_handler) | 79 | ENDPROC(return_to_handler) |
| 78 | #endif | 80 | #endif |
| 79 | 81 | ||
| @@ -82,16 +84,16 @@ ENTRY(MCOUNT_NAME) · 2 unmodified lines | |||
| 82 | la t4, ftrace_stub | 84 | la t4, ftrace_stub |
| 83 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 85 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 84 | la t0, ftrace_graph_return | 86 | la t0, ftrace_graph_return |
| 85 | ld t1, 0(t0) | 87 | REG_L t1, 0(t0) |
| 86 | bne t1, t4, do_ftrace_graph_caller | 88 | bne t1, t4, do_ftrace_graph_caller |
| 87 | 89 | ||
| 88 | la t3, ftrace_graph_entry | 90 | la t3, ftrace_graph_entry |
| 89 | ld t2, 0(t3) | 91 | REG_L t2, 0(t3) |
| 90 | la t6, ftrace_graph_entry_stub | 92 | la t6, ftrace_graph_entry_stub |
| 91 | bne t2, t6, do_ftrace_graph_caller | 93 | bne t2, t6, do_ftrace_graph_caller |
| 92 | #endif | 94 | #endif |
| 93 | la t3, ftrace_trace_function | 95 | la t3, ftrace_trace_function |
| 94 | ld t5, 0(t3) | 96 | REG_L t5, 0(t3) |
| 95 | bne t5, t4, do_trace | 97 | bne t5, t4, do_trace |
| 96 | ret | 98 | ret |
| 97 | 99 | ||
| @@ -101,10 +103,10 @@ ENTRY(MCOUNT_NAME) · 3 unmodified lines | |||
| 101 | * prepare_to_return(&ra_to_caller_of_caller, ra_to_caller) | 103 | * prepare_to_return(&ra_to_caller_of_caller, ra_to_caller) |
| 102 | */ | 104 | */ |
| 103 | do_ftrace_graph_caller: | 105 | do_ftrace_graph_caller: |
| 104 | addi a0, s0, -8 | 106 | addi a0, s0, -SZREG |
| 105 | mv a1, ra | 107 | mv a1, ra |
| 106 | #ifdef HAVE_FUNCTION_GRAPH_FP_TEST | 108 | #ifdef HAVE_FUNCTION_GRAPH_FP_TEST |
| 107 | ld a2, -16(s0) | 109 | REG_L a2, -2*SZREG(s0) |
| 108 | #endif | 110 | #endif |
| 109 | SAVE_ABI_STATE | 111 | SAVE_ABI_STATE |
| 110 | call prepare_ftrace_return | 112 | call prepare_ftrace_return |
| @@ -117,7 +119,7 @@ do_ftrace_graph_caller: · 6 unmodified lines | |||
| 117 | * (*ftrace_trace_function)(ra_to_caller, ra_to_caller_of_caller) | 119 | * (*ftrace_trace_function)(ra_to_caller, ra_to_caller_of_caller) |
| 118 | */ | 120 | */ |
| 119 | do_trace: | 121 | do_trace: |
| 120 | ld a1, -8(s0) | 122 | REG_L a1, -SZREG(s0) |
| 121 | mv a0, ra | 123 | mv a0, ra |
| 122 | 124 | ||
| 123 | SAVE_ABI_STATE | 125 | SAVE_ABI_STATE |
| @@ -1,6 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | obj-$(CONFIG_KPROBES) += kprobes.o decode-insn.o simulate-insn.o | 2 | obj-$(CONFIG_KPROBES) += kprobes.o decode-insn.o simulate-insn.o |
| 3 | obj-$(CONFIG_KPROBES) += kprobes_trampoline.o | 3 | obj-$(CONFIG_RETHOOK) += rethook.o rethook_trampoline.o |
| 4 | obj-$(CONFIG_KPROBES_ON_FTRACE) += ftrace.o | 4 | obj-$(CONFIG_KPROBES_ON_FTRACE) += ftrace.o |
| 5 | obj-$(CONFIG_UPROBES) += uprobes.o decode-insn.o simulate-insn.o | 5 | obj-$(CONFIG_UPROBES) += uprobes.o decode-insn.o simulate-insn.o |
| 6 | CFLAGS_REMOVE_simulate-insn.o = $(CC_FLAGS_FTRACE) | 6 | CFLAGS_REMOVE_simulate-insn.o = $(CC_FLAGS_FTRACE) |
| @@ -345,19 +345,6 @@ int __init arch_populate_kprobe_blacklist(void) · 344 unmodified lines | |||
| 345 | return ret; | 345 | return ret; |
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs) | ||
| 349 | { | ||
| 350 | return (void *)kretprobe_trampoline_handler(regs, NULL); | ||
| 351 | } | ||
| 352 | |||
| 353 | void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, | ||
| 354 | struct pt_regs *regs) | ||
| 355 | { | ||
| 356 | ri->ret_addr = (kprobe_opcode_t *)regs->ra; | ||
| 357 | ri->fp = NULL; | ||
| 358 | regs->ra = (unsigned long) &__kretprobe_trampoline; | ||
| 359 | } | ||
| 360 | |||
| 361 | int __kprobes arch_trampoline_kprobe(struct kprobe *p) | 348 | int __kprobes arch_trampoline_kprobe(struct kprobe *p) |
| 362 | { | 349 | { |
| 363 | return 0; | 350 | return 0; |
| @@ -0,0 +1,27 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Generic return hook for riscv. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <linux/kprobes.h> | ||
| 7 | #include <linux/rethook.h> | ||
| 8 | #include "rethook.h" | ||
| 9 | |||
| 10 | /* This is called from arch_rethook_trampoline() */ | ||
| 11 | unsigned long __used arch_rethook_trampoline_callback(struct pt_regs *regs) | ||
| 12 | { | ||
| 13 | return rethook_trampoline_handler(regs, regs->s0); | ||
| 14 | } | ||
| 15 | |||
| 16 | NOKPROBE_SYMBOL(arch_rethook_trampoline_callback); | ||
| 17 | |||
| 18 | void arch_rethook_prepare(struct rethook_node *rhn, struct pt_regs *regs, bool mcount) | ||
| 19 | { | ||
| 20 | rhn->ret_addr = regs->ra; | ||
| 21 | rhn->frame = regs->s0; | ||
| 22 | |||
| 23 | /* replace return addr with trampoline */ | ||
| 24 | regs->ra = (unsigned long)arch_rethook_trampoline; | ||
| 25 | } | ||
| 26 | |||
| 27 | NOKPROBE_SYMBOL(arch_rethook_prepare); | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| 2 | #ifndef __RISCV_RETHOOK_H | ||
| 3 | #define __RISCV_RETHOOK_H | ||
| 4 | |||
| 5 | unsigned long arch_rethook_trampoline_callback(struct pt_regs *regs); | ||
| 6 | void arch_rethook_prepare(struct rethook_node *rhn, struct pt_regs *regs, bool mcount); | ||
| 7 | |||
| 8 | #endif | ||
| @@ -75,13 +75,13 @@ · 74 unmodified lines | |||
| 75 | REG_L x31, PT_T6(sp) | 75 | REG_L x31, PT_T6(sp) |
| 76 | .endm | 76 | .endm |
| 77 | 77 | ||
| 78 | ENTRY(__kretprobe_trampoline) | 78 | ENTRY(arch_rethook_trampoline) |
| 79 | addi sp, sp, -(PT_SIZE_ON_STACK) | 79 | addi sp, sp, -(PT_SIZE_ON_STACK) |
| 80 | save_all_base_regs | 80 | save_all_base_regs |
| 81 | 81 | ||
| 82 | move a0, sp /* pt_regs */ | 82 | move a0, sp /* pt_regs */ |
| 83 | 83 | ||
| 84 | call trampoline_probe_handler | 84 | call arch_rethook_trampoline_callback |
| 85 | 85 | ||
| 86 | /* use the result as the return-address */ | 86 | /* use the result as the return-address */ |
| 87 | move ra, a0 | 87 | move ra, a0 |
| @@ -90,4 +90,4 @@ ENTRY(__kretprobe_trampoline) · 2 unmodified lines | |||
| 90 | addi sp, sp, PT_SIZE_ON_STACK | 90 | addi sp, sp, PT_SIZE_ON_STACK |
| 91 | 91 | ||
| 92 | ret | 92 | ret |
| 93 | ENDPROC(__kretprobe_trampoline) | 93 | ENDPROC(arch_rethook_trampoline) |
| @@ -313,19 +313,27 @@ static void do_signal(struct pt_regs *regs) · 312 unmodified lines | |||
| 313 | } | 313 | } |
| 314 | 314 | ||
| 315 | /* | 315 | /* |
| 316 | * notification of userspace execution resumption | 316 | * Handle any pending work on the resume-to-userspace path, as indicated by |
| 317 | * - triggered by the _TIF_WORK_MASK flags | 317 | * _TIF_WORK_MASK. Entered from assembly with IRQs off. |
| 318 | */ | 318 | */ |
| 319 | asmlinkage __visible void do_notify_resume(struct pt_regs *regs, | 319 | asmlinkage __visible void do_work_pending(struct pt_regs *regs, |
| 320 | unsigned long thread_info_flags) | 320 | unsigned long thread_info_flags) |
| 321 | { | 321 | { |
| 322 | if (thread_info_flags & _TIF_UPROBE) | 322 | do { |
| 323 | uprobe_notify_resume(regs); | 323 | if (thread_info_flags & _TIF_NEED_RESCHED) { |
| 324 | 324 | schedule(); | |
| 325 | /* Handle pending signal delivery */ | 325 | } else { |
| 326 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) | 326 | local_irq_enable(); |
| 327 | do_signal(regs); | 327 | if (thread_info_flags & _TIF_UPROBE) |
| 328 | 328 | uprobe_notify_resume(regs); | |
| 329 | if (thread_info_flags & _TIF_NOTIFY_RESUME) | 329 | /* Handle pending signal delivery */ |
| 330 | resume_user_mode_work(regs); | 330 | if (thread_info_flags & (_TIF_SIGPENDING | |
| 331 | _TIF_NOTIFY_SIGNAL)) | ||
| 332 | do_signal(regs); | ||
| 333 | if (thread_info_flags & _TIF_NOTIFY_RESUME) | ||
| 334 | resume_user_mode_work(regs); | ||
| 335 | } | ||
| 336 | local_irq_disable(); | ||
| 337 | thread_info_flags = read_thread_flags(); | ||
| 338 | } while (thread_info_flags & _TIF_WORK_MASK); | ||
| 331 | } | 339 | } |
| @@ -16,6 +16,8 @@ · 15 unmodified lines | |||
| 16 | 16 | ||
| 17 | #ifdef CONFIG_FRAME_POINTER | 17 | #ifdef CONFIG_FRAME_POINTER |
| 18 | 18 | ||
| 19 | extern asmlinkage void ret_from_exception(void); | ||
| 20 | |||
| 19 | void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, | 21 | void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, |
| 20 | bool (*fn)(void *, unsigned long), void *arg) | 22 | bool (*fn)(void *, unsigned long), void *arg) |
| 21 | { | 23 | { |
| @@ -58,7 +60,14 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, · 36 unmodified lines | |||
| 58 | } else { | 60 | } else { |
| 59 | fp = frame->fp; | 61 | fp = frame->fp; |
| 60 | pc = ftrace_graph_ret_addr(current, NULL, frame->ra, | 62 | pc = ftrace_graph_ret_addr(current, NULL, frame->ra, |
| 61 | (unsigned long *)(fp - 8)); | 63 | &frame->ra); |
| 64 | if (pc == (unsigned long)ret_from_exception) { | ||
| 65 | if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc))) | ||
| 66 | break; | ||
| 67 | |||
| 68 | pc = ((struct pt_regs *)sp)->epc; | ||
| 69 | fp = ((struct pt_regs *)sp)->s0; | ||
| 70 | } | ||
| 62 | } | 71 | } |
| 63 | 72 | ||
| 64 | } | 73 | } |
| @@ -208,18 +208,18 @@ int is_valid_bugaddr(unsigned long pc) · 207 unmodified lines | |||
| 208 | #endif /* CONFIG_GENERIC_BUG */ | 208 | #endif /* CONFIG_GENERIC_BUG */ |
| 209 | 209 | ||
| 210 | #ifdef CONFIG_VMAP_STACK | 210 | #ifdef CONFIG_VMAP_STACK |
| 211 | /* | ||
| 212 | * Extra stack space that allows us to provide panic messages when the kernel | ||
| 213 | * has overflowed its stack. | ||
| 214 | */ | ||
| 211 | static DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], | 215 | static DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], |
| 212 | overflow_stack)__aligned(16); | 216 | overflow_stack)__aligned(16); |
| 213 | /* | 217 | /* |
| 214 | * shadow stack, handled_ kernel_ stack_ overflow(in kernel/entry.S) is used | 218 | * A temporary stack for use by handle_kernel_stack_overflow. This is used so |
| 215 | * to get per-cpu overflow stack(get_overflow_stack). | 219 | * we can call into C code to get the per-hart overflow stack. Usage of this |
| 220 | * stack must be protected by spin_shadow_stack. | ||
| 216 | */ | 221 | */ |
| 217 | long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE/sizeof(long)]; | 222 | long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE/sizeof(long)] __aligned(16); |
| 218 | asmlinkage unsigned long get_overflow_stack(void) | ||
| 219 | { | ||
| 220 | return (unsigned long)this_cpu_ptr(overflow_stack) + | ||
| 221 | OVERFLOW_STACK_SIZE; | ||
| 222 | } | ||
| 223 | 223 | ||
| 224 | /* | 224 | /* |
| 225 | * A pseudo spinlock to protect the shadow stack from being used by multiple | 225 | * A pseudo spinlock to protect the shadow stack from being used by multiple |
| @@ -230,6 +230,12 @@ asmlinkage unsigned long get_overflow_stack(void) · 4 unmodified lines | |||
| 230 | */ | 230 | */ |
| 231 | unsigned long spin_shadow_stack; | 231 | unsigned long spin_shadow_stack; |
| 232 | 232 | ||
| 233 | asmlinkage unsigned long get_overflow_stack(void) | ||
| 234 | { | ||
| 235 | return (unsigned long)this_cpu_ptr(overflow_stack) + | ||
| 236 | OVERFLOW_STACK_SIZE; | ||
| 237 | } | ||
| 238 | |||
| 233 | asmlinkage void handle_bad_stack(struct pt_regs *regs) | 239 | asmlinkage void handle_bad_stack(struct pt_regs *regs) |
| 234 | { | 240 | { |
| 235 | unsigned long tsk_stk = (unsigned long)current->stack; | 241 | unsigned long tsk_stk = (unsigned long)current->stack; |
| @@ -13,6 +13,8 @@ obj-y += extable.o · 12 unmodified lines | |||
| 13 | obj-$(CONFIG_MMU) += fault.o pageattr.o | 13 | obj-$(CONFIG_MMU) += fault.o pageattr.o |
| 14 | obj-y += cacheflush.o | 14 | obj-y += cacheflush.o |
| 15 | obj-y += context.o | 15 | obj-y += context.o |
| 16 | obj-y += pgtable.o | ||
| 17 | obj-y += pmem.o | ||
| 16 | 18 | ||
| 17 | ifeq ($(CONFIG_MMU),y) | 19 | ifeq ($(CONFIG_MMU),y) |
| 18 | obj-$(CONFIG_SMP) += tlbflush.o | 20 | obj-$(CONFIG_SMP) += tlbflush.o |
| @@ -83,6 +83,13 @@ void flush_icache_pte(pte_t pte) · 82 unmodified lines | |||
| 83 | { | 83 | { |
| 84 | struct page *page = pte_page(pte); | 84 | struct page *page = pte_page(pte); |
| 85 | 85 | ||
| 86 | /* | ||
| 87 | * HugeTLB pages are always fully mapped, so only setting head page's | ||
| 88 | * PG_dcache_clean flag is enough. | ||
| 89 | */ | ||
| 90 | if (PageHuge(page)) | ||
| 91 | page = compound_head(page); | ||
| 92 | |||
| 86 | if (!test_and_set_bit(PG_dcache_clean, &page->flags)) | 93 | if (!test_and_set_bit(PG_dcache_clean, &page->flags)) |
| 87 | flush_icache_all(); | 94 | flush_icache_all(); |
| 88 | } | 95 | } |
| @@ -196,6 +196,16 @@ switch_mm_fast: · 195 unmodified lines | |||
| 196 | 196 | ||
| 197 | if (need_flush_tlb) | 197 | if (need_flush_tlb) |
| 198 | local_flush_tlb_all(); | 198 | local_flush_tlb_all(); |
| 199 | #ifdef CONFIG_SMP | ||
| 200 | else { | ||
| 201 | cpumask_t *mask = &mm->context.tlb_stale_mask; | ||
| 202 | |||
| 203 | if (cpumask_test_cpu(cpu, mask)) { | ||
| 204 | cpumask_clear_cpu(cpu, mask); | ||
| 205 | local_flush_tlb_all_asid(cntx & asid_mask); | ||
| 206 | } | ||
| 207 | } | ||
| 208 | #endif | ||
| 199 | } | 209 | } |
| 200 | 210 | ||
| 201 | static void set_mm_noasid(struct mm_struct *mm) | 211 | static void set_mm_noasid(struct mm_struct *mm) |
| @@ -672,10 +672,11 @@ void __init create_pgd_mapping(pgd_t *pgdp, · 671 unmodified lines | |||
| 672 | static uintptr_t __init best_map_size(phys_addr_t base, phys_addr_t size) | 672 | static uintptr_t __init best_map_size(phys_addr_t base, phys_addr_t size) |
| 673 | { | 673 | { |
| 674 | /* Upgrade to PMD_SIZE mappings whenever possible */ | 674 | /* Upgrade to PMD_SIZE mappings whenever possible */ |
| 675 | if ((base & (PMD_SIZE - 1)) || (size & (PMD_SIZE - 1))) | 675 | base &= PMD_SIZE - 1; |
| 676 | return PAGE_SIZE; | 676 | if (!base && size >= PMD_SIZE) |
| 677 | return PMD_SIZE; | ||
| 677 | 678 | ||
| 678 | return PMD_SIZE; | 679 | return PAGE_SIZE; |
| 679 | } | 680 | } |
| 680 | 681 | ||
| 681 | #ifdef CONFIG_XIP_KERNEL | 682 | #ifdef CONFIG_XIP_KERNEL |
| @@ -926,15 +927,15 @@ static void __init pt_ops_set_early(void) · 244 unmodified lines | |||
| 926 | */ | 927 | */ |
| 927 | static void __init pt_ops_set_fixmap(void) | 928 | static void __init pt_ops_set_fixmap(void) |
| 928 | { | 929 | { |
| 929 | pt_ops.alloc_pte = kernel_mapping_pa_to_va((uintptr_t)alloc_pte_fixmap); | 930 | pt_ops.alloc_pte = kernel_mapping_pa_to_va(alloc_pte_fixmap); |
| 930 | pt_ops.get_pte_virt = kernel_mapping_pa_to_va((uintptr_t)get_pte_virt_fixmap); | 931 | pt_ops.get_pte_virt = kernel_mapping_pa_to_va(get_pte_virt_fixmap); |
| 931 | #ifndef __PAGETABLE_PMD_FOLDED | 932 | #ifndef __PAGETABLE_PMD_FOLDED |
| 932 | pt_ops.alloc_pmd = kernel_mapping_pa_to_va((uintptr_t)alloc_pmd_fixmap); | 933 | pt_ops.alloc_pmd = kernel_mapping_pa_to_va(alloc_pmd_fixmap); |
| 933 | pt_ops.get_pmd_virt = kernel_mapping_pa_to_va((uintptr_t)get_pmd_virt_fixmap); | 934 | pt_ops.get_pmd_virt = kernel_mapping_pa_to_va(get_pmd_virt_fixmap); |
| 934 | pt_ops.alloc_pud = kernel_mapping_pa_to_va((uintptr_t)alloc_pud_fixmap); | 935 | pt_ops.alloc_pud = kernel_mapping_pa_to_va(alloc_pud_fixmap); |
| 935 | pt_ops.get_pud_virt = kernel_mapping_pa_to_va((uintptr_t)get_pud_virt_fixmap); | 936 | pt_ops.get_pud_virt = kernel_mapping_pa_to_va(get_pud_virt_fixmap); |
| 936 | pt_ops.alloc_p4d = kernel_mapping_pa_to_va((uintptr_t)alloc_p4d_fixmap); | 937 | pt_ops.alloc_p4d = kernel_mapping_pa_to_va(alloc_p4d_fixmap); |
| 937 | pt_ops.get_p4d_virt = kernel_mapping_pa_to_va((uintptr_t)get_p4d_virt_fixmap); | 938 | pt_ops.get_p4d_virt = kernel_mapping_pa_to_va(get_p4d_virt_fixmap); |
| 938 | #endif | 939 | #endif |
| 939 | } | 940 | } |
| 940 | 941 | ||
| @@ -1110,9 +1111,9 @@ static void __init setup_vm_final(void) · 169 unmodified lines | |||
| 1110 | if (end >= __pa(PAGE_OFFSET) + memory_limit) | 1111 | if (end >= __pa(PAGE_OFFSET) + memory_limit) |
| 1111 | end = __pa(PAGE_OFFSET) + memory_limit; | 1112 | end = __pa(PAGE_OFFSET) + memory_limit; |
| 1112 | 1113 | ||
| 1113 | map_size = best_map_size(start, end - start); | ||
| 1114 | for (pa = start; pa < end; pa += map_size) { | 1114 | for (pa = start; pa < end; pa += map_size) { |
| 1115 | va = (uintptr_t)__va(pa); | 1115 | va = (uintptr_t)__va(pa); |
| 1116 | map_size = best_map_size(pa, end - pa); | ||
| 1116 | 1117 | ||
| 1117 | create_pgd_mapping(swapper_pg_dir, va, pa, map_size, | 1118 | create_pgd_mapping(swapper_pg_dir, va, pa, map_size, |
| 1118 | pgprot_from_va(va)); | 1119 | pgprot_from_va(va)); |
| @@ -0,0 +1,83 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | |||
| 3 | #include <asm/pgalloc.h> | ||
| 4 | #include <linux/gfp.h> | ||
| 5 | #include <linux/kernel.h> | ||
| 6 | #include <linux/pgtable.h> | ||
| 7 | |||
| 8 | #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP | ||
| 9 | int p4d_set_huge(p4d_t *p4d, phys_addr_t addr, pgprot_t prot) | ||
| 10 | { | ||
| 11 | return 0; | ||
| 12 | } | ||
| 13 | |||
| 14 | void p4d_clear_huge(p4d_t *p4d) | ||
| 15 | { | ||
| 16 | } | ||
| 17 | |||
| 18 | int pud_set_huge(pud_t *pud, phys_addr_t phys, pgprot_t prot) | ||
| 19 | { | ||
| 20 | pud_t new_pud = pfn_pud(__phys_to_pfn(phys), prot); | ||
| 21 | |||
| 22 | set_pud(pud, new_pud); | ||
| 23 | return 1; | ||
| 24 | } | ||
| 25 | |||
| 26 | int pud_clear_huge(pud_t *pud) | ||
| 27 | { | ||
| 28 | if (!pud_leaf(READ_ONCE(*pud))) | ||
| 29 | return 0; | ||
| 30 | pud_clear(pud); | ||
| 31 | return 1; | ||
| 32 | } | ||
| 33 | |||
| 34 | int pud_free_pmd_page(pud_t *pud, unsigned long addr) | ||
| 35 | { | ||
| 36 | pmd_t *pmd = pud_pgtable(*pud); | ||
| 37 | int i; | ||
| 38 | |||
| 39 | pud_clear(pud); | ||
| 40 | |||
| 41 | flush_tlb_kernel_range(addr, addr + PUD_SIZE); | ||
| 42 | |||
| 43 | for (i = 0; i < PTRS_PER_PMD; i++) { | ||
| 44 | if (!pmd_none(pmd[i])) { | ||
| 45 | pte_t *pte = (pte_t *)pmd_page_vaddr(pmd[i]); | ||
| 46 | |||
| 47 | pte_free_kernel(NULL, pte); | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | pmd_free(NULL, pmd); | ||
| 52 | |||
| 53 | return 1; | ||
| 54 | } | ||
| 55 | |||
| 56 | int pmd_set_huge(pmd_t *pmd, phys_addr_t phys, pgprot_t prot) | ||
| 57 | { | ||
| 58 | pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), prot); | ||
| 59 | |||
| 60 | set_pmd(pmd, new_pmd); | ||
| 61 | return 1; | ||
| 62 | } | ||
| 63 | |||
| 64 | int pmd_clear_huge(pmd_t *pmd) | ||
| 65 | { | ||
| 66 | if (!pmd_leaf(READ_ONCE(*pmd))) | ||
| 67 | return 0; | ||
| 68 | pmd_clear(pmd); | ||
| 69 | return 1; | ||
| 70 | } | ||
| 71 | |||
| 72 | int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) | ||
| 73 | { | ||
| 74 | pte_t *pte = (pte_t *)pmd_page_vaddr(*pmd); | ||
| 75 | |||
| 76 | pmd_clear(pmd); | ||
| 77 | |||
| 78 | flush_tlb_kernel_range(addr, addr + PMD_SIZE); | ||
| 79 | pte_free_kernel(NULL, pte); | ||
| 80 | return 1; | ||
| 81 | } | ||
| 82 | |||
| 83 | #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */ | ||
| @@ -22,7 +22,7 @@ EXPORT_SYMBOL(__virt_to_phys); · 21 unmodified lines | |||
| 22 | phys_addr_t __phys_addr_symbol(unsigned long x) | 22 | phys_addr_t __phys_addr_symbol(unsigned long x) |
| 23 | { | 23 | { |
| 24 | unsigned long kernel_start = kernel_map.virt_addr; | 24 | unsigned long kernel_start = kernel_map.virt_addr; |
| 25 | unsigned long kernel_end = (unsigned long)_end; | 25 | unsigned long kernel_end = kernel_start + kernel_map.size; |
| 26 | 26 | ||
| 27 | /* | 27 | /* |
| 28 | * Boundary checking aginst the kernel image mapping. | 28 | * Boundary checking aginst the kernel image mapping. |
| @@ -0,0 +1,21 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2022 Ventana Micro Systems Inc. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <linux/export.h> | ||
| 7 | #include <linux/libnvdimm.h> | ||
| 8 | |||
| 9 | #include <asm/cacheflush.h> | ||
| 10 | |||
| 11 | void arch_wb_cache_pmem(void *addr, size_t size) | ||
| 12 | { | ||
| 13 | ALT_CMO_OP(clean, addr, size, riscv_cbom_block_size); | ||
| 14 | } | ||
| 15 | EXPORT_SYMBOL_GPL(arch_wb_cache_pmem); | ||
| 16 | |||
| 17 | void arch_invalidate_pmem(void *addr, size_t size) | ||
| 18 | { | ||
| 19 | ALT_CMO_OP(inval, addr, size, riscv_cbom_block_size); | ||
| 20 | } | ||
| 21 | EXPORT_SYMBOL_GPL(arch_invalidate_pmem); | ||
| @@ -5,23 +5,7 @@ · 4 unmodified lines | |||
| 5 | #include <linux/sched.h> | 5 | #include <linux/sched.h> |
| 6 | #include <asm/sbi.h> | 6 | #include <asm/sbi.h> |
| 7 | #include <asm/mmu_context.h> | 7 | #include <asm/mmu_context.h> |
| 8 | 8 | #include <asm/tlbflush.h> | |
| 9 | static inline void local_flush_tlb_all_asid(unsigned long asid) | ||
| 10 | { | ||
| 11 | __asm__ __volatile__ ("sfence.vma x0, %0" | ||
| 12 | : | ||
| 13 | : "r" (asid) | ||
| 14 | : "memory"); | ||
| 15 | } | ||
| 16 | |||
| 17 | static inline void local_flush_tlb_page_asid(unsigned long addr, | ||
| 18 | unsigned long asid) | ||
| 19 | { | ||
| 20 | __asm__ __volatile__ ("sfence.vma %0, %1" | ||
| 21 | : | ||
| 22 | : "r" (addr), "r" (asid) | ||
| 23 | : "memory"); | ||
| 24 | } | ||
| 25 | 9 | ||
| 26 | void flush_tlb_all(void) | 10 | void flush_tlb_all(void) |
| 27 | { | 11 | { |
| @@ -31,6 +15,7 @@ void flush_tlb_all(void) · 3 unmodified lines | |||
| 31 | static void __sbi_tlb_flush_range(struct mm_struct *mm, unsigned long start, | 15 | static void __sbi_tlb_flush_range(struct mm_struct *mm, unsigned long start, |
| 32 | unsigned long size, unsigned long stride) | 16 | unsigned long size, unsigned long stride) |
| 33 | { | 17 | { |
| 18 | struct cpumask *pmask = &mm->context.tlb_stale_mask; | ||
| 34 | struct cpumask *cmask = mm_cpumask(mm); | 19 | struct cpumask *cmask = mm_cpumask(mm); |
| 35 | unsigned int cpuid; | 20 | unsigned int cpuid; |
| 36 | bool broadcast; | 21 | bool broadcast; |
| @@ -44,6 +29,15 @@ static void __sbi_tlb_flush_range(struct mm_struct *mm, unsigned long start, · 7 unmodified lines | |||
| 44 | if (static_branch_unlikely(&use_asid_allocator)) { | 29 | if (static_branch_unlikely(&use_asid_allocator)) { |
| 45 | unsigned long asid = atomic_long_read(&mm->context.id); | 30 | unsigned long asid = atomic_long_read(&mm->context.id); |
| 46 | 31 | ||
| 32 | /* | ||
| 33 | * TLB will be immediately flushed on harts concurrently | ||
| 34 | * executing this MM context. TLB flush on other harts | ||
| 35 | * is deferred until this MM context migrates there. | ||
| 36 | */ | ||
| 37 | cpumask_setall(pmask); | ||
| 38 | cpumask_clear_cpu(cpuid, pmask); | ||
| 39 | cpumask_andnot(pmask, pmask, cmask); | ||
| 40 | |||
| 47 | if (broadcast) { | 41 | if (broadcast) { |
| 48 | sbi_remote_sfence_vma_asid(cmask, start, size, asid); | 42 | sbi_remote_sfence_vma_asid(cmask, start, size, asid); |
| 49 | } else if (size <= stride) { | 43 | } else if (size <= stride) { |
| @@ -538,31 +538,14 @@ config TI_PRUSS_INTC · 537 unmodified lines | |||
| 538 | different processors within the SoC. | 538 | different processors within the SoC. |
| 539 | 539 | ||
| 540 | config RISCV_INTC | 540 | config RISCV_INTC |
| 541 | bool "RISC-V Local Interrupt Controller" | 541 | bool |
| 542 | depends on RISCV | 542 | depends on RISCV |
| 543 | default y | ||
| 544 | help | ||
| 545 | This enables support for the per-HART local interrupt controller | ||
| 546 | found in standard RISC-V systems. The per-HART local interrupt | ||
| 547 | controller handles timer interrupts, software interrupts, and | ||
| 548 | hardware interrupts. Without a per-HART local interrupt controller, | ||
| 549 | a RISC-V system will be unable to handle any interrupts. | ||
| 550 | |||
| 551 | If you don't know what to do here, say Y. | ||
| 552 | 543 | ||
| 553 | config SIFIVE_PLIC | 544 | config SIFIVE_PLIC |
| 554 | bool "SiFive Platform-Level Interrupt Controller" | 545 | bool |
| 555 | depends on RISCV | 546 | depends on RISCV |
| 556 | select IRQ_DOMAIN_HIERARCHY | 547 | select IRQ_DOMAIN_HIERARCHY |
| 557 | select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP | 548 | select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP |
| 558 | help | ||
| 559 | This enables support for the PLIC chip found in SiFive (and | ||
| 560 | potentially other) RISC-V systems. The PLIC controls devices | ||
| 561 | interrupts and connects them to each core's local interrupt | ||
| 562 | controller. Aside from timer and software interrupts, all other | ||
| 563 | interrupt sources are subordinate to the PLIC. | ||
| 564 | |||
| 565 | If you don't know what to do here, say Y. | ||
| 566 | 549 | ||
| 567 | config EXYNOS_IRQ_COMBINER | 550 | config EXYNOS_IRQ_COMBINER |
| 568 | bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST | 551 | bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | |||
| 20 | #include <linux/cpu_pm.h> | 20 | #include <linux/cpu_pm.h> |
| 21 | #include <linux/sched/clock.h> | 21 | #include <linux/sched/clock.h> |
| 22 | 22 | ||
| 23 | #include <asm/errata_list.h> | ||
| 23 | #include <asm/sbi.h> | 24 | #include <asm/sbi.h> |
| 24 | #include <asm/hwcap.h> | 25 | #include <asm/hwcap.h> |
| 25 | 26 | ||
| @@ -47,6 +48,8 @@ static const struct attribute_group *riscv_pmu_attr_groups[] = { · 21 unmodified lines | |||
| 47 | * per_cpu in case of harts with different pmu counters | 48 | * per_cpu in case of harts with different pmu counters |
| 48 | */ | 49 | */ |
| 49 | static union sbi_pmu_ctr_info *pmu_ctr_list; | 50 | static union sbi_pmu_ctr_info *pmu_ctr_list; |
| 51 | static bool riscv_pmu_use_irq; | ||
| 52 | static unsigned int riscv_pmu_irq_num; | ||
| 50 | static unsigned int riscv_pmu_irq; | 53 | static unsigned int riscv_pmu_irq; |
| 51 | 54 | ||
| 52 | struct sbi_pmu_event_data { | 55 | struct sbi_pmu_event_data { |
| @@ -580,7 +583,7 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev) · 527 unmodified lines | |||
| 580 | fidx = find_first_bit(cpu_hw_evt->used_hw_ctrs, RISCV_MAX_COUNTERS); | 583 | fidx = find_first_bit(cpu_hw_evt->used_hw_ctrs, RISCV_MAX_COUNTERS); |
| 581 | event = cpu_hw_evt->events[fidx]; | 584 | event = cpu_hw_evt->events[fidx]; |
| 582 | if (!event) { | 585 | if (!event) { |
| 583 | csr_clear(CSR_SIP, SIP_LCOFIP); | 586 | csr_clear(CSR_SIP, BIT(riscv_pmu_irq_num)); |
| 584 | return IRQ_NONE; | 587 | return IRQ_NONE; |
| 585 | } | 588 | } |
| 586 | 589 | ||
| @@ -588,13 +591,13 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev) · 1 unmodified line | |||
| 588 | pmu_sbi_stop_hw_ctrs(pmu); | 591 | pmu_sbi_stop_hw_ctrs(pmu); |
| 589 | 592 | ||
| 590 | /* Overflow status register should only be read after counter are stopped */ | 593 | /* Overflow status register should only be read after counter are stopped */ |
| 591 | overflow = csr_read(CSR_SSCOUNTOVF); | 594 | ALT_SBI_PMU_OVERFLOW(overflow); |
| 592 | 595 | ||
| 593 | /* | 596 | /* |
| 594 | * Overflow interrupt pending bit should only be cleared after stopping | 597 | * Overflow interrupt pending bit should only be cleared after stopping |
| 595 | * all the counters to avoid any race condition. | 598 | * all the counters to avoid any race condition. |
| 596 | */ | 599 | */ |
| 597 | csr_clear(CSR_SIP, SIP_LCOFIP); | 600 | csr_clear(CSR_SIP, BIT(riscv_pmu_irq_num)); |
| 598 | 601 | ||
| 599 | /* No overflow bit is set */ | 602 | /* No overflow bit is set */ |
| 600 | if (!overflow) | 603 | if (!overflow) |
| @@ -661,10 +664,10 @@ static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node) · 60 unmodified lines | |||
| 661 | /* Stop all the counters so that they can be enabled from perf */ | 664 | /* Stop all the counters so that they can be enabled from perf */ |
| 662 | pmu_sbi_stop_all(pmu); | 665 | pmu_sbi_stop_all(pmu); |
| 663 | 666 | ||
| 664 | if (riscv_isa_extension_available(NULL, SSCOFPMF)) { | 667 | if (riscv_pmu_use_irq) { |
| 665 | cpu_hw_evt->irq = riscv_pmu_irq; | 668 | cpu_hw_evt->irq = riscv_pmu_irq; |
| 666 | csr_clear(CSR_IP, BIT(RV_IRQ_PMU)); | 669 | csr_clear(CSR_IP, BIT(riscv_pmu_irq_num)); |
| 667 | csr_set(CSR_IE, BIT(RV_IRQ_PMU)); | 670 | csr_set(CSR_IE, BIT(riscv_pmu_irq_num)); |
| 668 | enable_percpu_irq(riscv_pmu_irq, IRQ_TYPE_NONE); | 671 | enable_percpu_irq(riscv_pmu_irq, IRQ_TYPE_NONE); |
| 669 | } | 672 | } |
| 670 | 673 | ||
| @@ -673,9 +676,9 @@ static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node) · 2 unmodified lines | |||
| 673 | 676 | ||
| 674 | static int pmu_sbi_dying_cpu(unsigned int cpu, struct hlist_node *node) | 677 | static int pmu_sbi_dying_cpu(unsigned int cpu, struct hlist_node *node) |
| 675 | { | 678 | { |
| 676 | if (riscv_isa_extension_available(NULL, SSCOFPMF)) { | 679 | if (riscv_pmu_use_irq) { |
| 677 | disable_percpu_irq(riscv_pmu_irq); | 680 | disable_percpu_irq(riscv_pmu_irq); |
| 678 | csr_clear(CSR_IE, BIT(RV_IRQ_PMU)); | 681 | csr_clear(CSR_IE, BIT(riscv_pmu_irq_num)); |
| 679 | } | 682 | } |
| 680 | 683 | ||
| 681 | /* Disable all counters access for user mode now */ | 684 | /* Disable all counters access for user mode now */ |
| @@ -691,7 +694,18 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pde · 9 unmodified lines | |||
| 691 | struct device_node *cpu, *child; | 694 | struct device_node *cpu, *child; |
| 692 | struct irq_domain *domain = NULL; | 695 | struct irq_domain *domain = NULL; |
| 693 | 696 | ||
| 694 | if (!riscv_isa_extension_available(NULL, SSCOFPMF)) | 697 | if (riscv_isa_extension_available(NULL, SSCOFPMF)) { |
| 698 | riscv_pmu_irq_num = RV_IRQ_PMU; | ||
| 699 | riscv_pmu_use_irq = true; | ||
| 700 | } else if (IS_ENABLED(CONFIG_ERRATA_THEAD_PMU) && | ||
| 701 | riscv_cached_mvendorid(0) == THEAD_VENDOR_ID && | ||
| 702 | riscv_cached_marchid(0) == 0 && | ||
| 703 | riscv_cached_mimpid(0) == 0) { | ||
| 704 | riscv_pmu_irq_num = THEAD_C9XX_RV_IRQ_PMU; | ||
| 705 | riscv_pmu_use_irq = true; | ||
| 706 | } | ||
| 707 | |||
| 708 | if (!riscv_pmu_use_irq) | ||
| 695 | return -EOPNOTSUPP; | 709 | return -EOPNOTSUPP; |
| 696 | 710 | ||
| 697 | for_each_of_cpu_node(cpu) { | 711 | for_each_of_cpu_node(cpu) { |
| @@ -713,7 +727,7 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pde · 15 unmodified lines | |||
| 713 | return -ENODEV; | 727 | return -ENODEV; |
| 714 | } | 728 | } |
| 715 | 729 | ||
| 716 | riscv_pmu_irq = irq_create_mapping(domain, RV_IRQ_PMU); | 730 | riscv_pmu_irq = irq_create_mapping(domain, riscv_pmu_irq_num); |
| 717 | if (!riscv_pmu_irq) { | 731 | if (!riscv_pmu_irq) { |
| 718 | pr_err("Failed to map PMU interrupt for node\n"); | 732 | pr_err("Failed to map PMU interrupt for node\n"); |
| 719 | return -ENODEV; | 733 | return -ENODEV; |
| @@ -38,7 +38,6 @@ arch/powerpc/kernel/entry_64.o · 37 unmodified lines | |||
| 38 | arch/powerpc/kernel/fpu.o | 38 | arch/powerpc/kernel/fpu.o |
| 39 | arch/powerpc/kernel/vector.o | 39 | arch/powerpc/kernel/vector.o |
| 40 | arch/powerpc/kernel/prom_init.o | 40 | arch/powerpc/kernel/prom_init.o |
| 41 | arch/riscv/kernel/head.o | ||
| 42 | arch/s390/kernel/head64.o | 41 | arch/s390/kernel/head64.o |
| 43 | arch/sh/kernel/head_32.o | 42 | arch/sh/kernel/head_32.o |
| 44 | arch/sparc/kernel/head_32.o | 43 | arch/sparc/kernel/head_32.o |