arm64 fixes for 6.13-rc2:

- MTE/hugetlbfs:
 
   - Set VM_MTE_ALLOWED in the arch code and remove it from the core code
     for hugetlbfs mappings
 
   - Fix copy_highpage() warning when the source is a huge page but not
     MTE tagged, taking the wrong small page path
 
 - drivers/virt/coco:
 
   - Add the pKVM and Arm CCA drivers under the arm64 maintainership
 
   - Fix the pkvm driver to fall back to ioremap() (and warn) if the
     MMIO_GUARD hypercall fails
 
   - Keep the Arm CCA driver default 'n' rather than 'm'
 
 - A series of fixes for the arm64 ptrace() implementation, potentially
   leading to the kernel consuming uninitialised stack variables when
   PTRACE_SETREGSET is invoked with a length of 0
 
 - Fix zone_dma_limit calculation when RAM starts below 4GB and ZONE_DMA
   is capped to this limit
 
 - Fix early boot warning with CONFIG_DEBUG_VIRTUAL=y triggered by a call
   to page_to_phys() (from patch_map()) which checks pfn_valid() before
   vmemmap has been set up
 
 - Do not clobber bits 15:8 of the ASID used for TTBR1_EL1 and TLBI ops
   when the kernel assumes 8-bit ASIDs but running under a hypervisor on
   a system that implements 16-bit ASIDs (found running Linux under
   Parallels on Apple M4)
 
 - ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A as it is
   using the same SMMU PMCG as HIP09 and suffers from the same errata
 
 - Add GCS to cpucap_is_possible(), missed in the recent merge
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEE5RElWfyWxS+3PLO2a9axLQDIXvEFAmdTQW4ACgkQa9axLQDI
 XvGLUQ/+MEiCFytDsSIQsGMaCpRCcrNX3dzhgekjTSiS+iPRTGjhHPMxAgnKgtim
 U6MIdxItS5bvFKWQC/VmA3V+EtMy+9uwfQOy7MbG+wIzwlg48Pn2MjgmheSxhftO
 0x+lUB+5ELU9KxL0KV+WNCE5l/iBpzcSG+Uj3iqc5rPuYHxa8npekd/KVba42zGY
 QqZ75yCW5EQwyuSZve8SSMqyHNgZHNgwzhs0aRr3ZwccqE9eMKpcEv5wxbl6raGB
 Qr4HG+c3w4rQFBsj+9Zs/f5G45uZ+pM55aAVLSihhCdq51/oXXPajOWMP3tV6ke+
 hHXm4buxgIR2CWeCXp8n/H7S3OQIj4uFqmaFIGxv0+0OTemUBIEg8kAtqVcnxSXY
 hk00J5yMurDik1hhud21ZHaJaELwWAwpisVCjYBblUGOoH9uH062gb02CGWv3lSe
 hrzYohhi7IAPzDzK339Q3HVr5PZOGagoBS2B1ptX2f6rrPITIuB2rW+lzNDuuBSX
 twHcdZzmSgl2zmFu4D3ql5Oa2ewLMiOn0Z96Esz5y9f74jbLh9ynU7QyRZM0MioS
 V6te7HanJ17zMK6S2thj7qsewqV6N4lcWd7M5ZclK29F8qcW5OWuKn5njFQT7K4s
 QDI0+1uYaSMcWoDAXNVXZf3oKMJDy1LeG+UXGyP5b0AQJrqYrWQ=
 =zZ4I
 -----END PGP SIGNATURE-----

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Catalin Marinas:
 "Nothing major, some left-overs from the recent merging window (MTE,
  coco) and some newly found issues like the ptrace() ones.

   - MTE/hugetlbfs:

      - Set VM_MTE_ALLOWED in the arch code and remove it from the core
        code for hugetlbfs mappings

      - Fix copy_highpage() warning when the source is a huge page but
        not MTE tagged, taking the wrong small page path

   - drivers/virt/coco:

      - Add the pKVM and Arm CCA drivers under the arm64 maintainership

      - Fix the pkvm driver to fall back to ioremap() (and warn) if the
        MMIO_GUARD hypercall fails

      - Keep the Arm CCA driver default 'n' rather than 'm'

   - A series of fixes for the arm64 ptrace() implementation,
     potentially leading to the kernel consuming uninitialised stack
     variables when PTRACE_SETREGSET is invoked with a length of 0

   - Fix zone_dma_limit calculation when RAM starts below 4GB and
     ZONE_DMA is capped to this limit

   - Fix early boot warning with CONFIG_DEBUG_VIRTUAL=y triggered by a
     call to page_to_phys() (from patch_map()) which checks pfn_valid()
     before vmemmap has been set up

   - Do not clobber bits 15:8 of the ASID used for TTBR1_EL1 and TLBI
     ops when the kernel assumes 8-bit ASIDs but running under a
     hypervisor on a system that implements 16-bit ASIDs (found running
     Linux under Parallels on Apple M4)

   - ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A as it
     is using the same SMMU PMCG as HIP09 and suffers from the same
     errata

   - Add GCS to cpucap_is_possible(), missed in the recent merge"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  arm64: ptrace: fix partial SETREGSET for NT_ARM_GCS
  arm64: ptrace: fix partial SETREGSET for NT_ARM_POE
  arm64: ptrace: fix partial SETREGSET for NT_ARM_FPMR
  arm64: ptrace: fix partial SETREGSET for NT_ARM_TAGGED_ADDR_CTRL
  arm64: cpufeature: Add GCS to cpucap_is_possible()
  coco: virt: arm64: Do not enable cca guest driver by default
  arm64: mte: Fix copy_highpage() warning on hugetlb folios
  arm64: Ensure bits ASID[15:8] are masked out when the kernel uses 8-bit ASIDs
  ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A
  MAINTAINERS: Add CCA and pKVM CoCO guest support to the ARM64 entry
  drivers/virt: pkvm: Don't fail ioremap() call if MMIO_GUARD fails
  arm64: patching: avoid early page_to_phys()
  arm64: mm: Fix zone_dma_limit calculation
  arm64: mte: set VM_MTE_ALLOWED for hugetlbfs at correct place
This commit is contained in:
Linus Torvalds 2024-12-06 13:47:55 -08:00
commit f3ddc438a2
14 changed files with 67 additions and 45 deletions

View File

@ -255,8 +255,9 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| Hisilicon | Hip08 SMMU PMCG | #162001800 | N/A | | Hisilicon | Hip08 SMMU PMCG | #162001800 | N/A |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| Hisilicon | Hip{08,09,10,10C| #162001900 | N/A | | Hisilicon | Hip{08,09,09A,10| #162001900 | N/A |
| | ,11} SMMU PMCG | | | | | ,10C,11} | | |
| | SMMU PMCG | | |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| Hisilicon | Hip09 | #162100801 | HISILICON_ERRATUM_162100801 | | Hisilicon | Hip09 | #162100801 | HISILICON_ERRATUM_162100801 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+

View File

@ -3376,6 +3376,8 @@ S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
F: Documentation/arch/arm64/ F: Documentation/arch/arm64/
F: arch/arm64/ F: arch/arm64/
F: drivers/virt/coco/arm-cca-guest/
F: drivers/virt/coco/pkvm-guest/
F: tools/testing/selftests/arm64/ F: tools/testing/selftests/arm64/
X: arch/arm64/boot/dts/ X: arch/arm64/boot/dts/

View File

@ -44,6 +44,8 @@ cpucap_is_possible(const unsigned int cap)
return IS_ENABLED(CONFIG_ARM64_TLB_RANGE); return IS_ENABLED(CONFIG_ARM64_TLB_RANGE);
case ARM64_HAS_S1POE: case ARM64_HAS_S1POE:
return IS_ENABLED(CONFIG_ARM64_POE); return IS_ENABLED(CONFIG_ARM64_POE);
case ARM64_HAS_GCS:
return IS_ENABLED(CONFIG_ARM64_GCS);
case ARM64_UNMAP_KERNEL_AT_EL0: case ARM64_UNMAP_KERNEL_AT_EL0:
return IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0); return IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0);
case ARM64_WORKAROUND_843419: case ARM64_WORKAROUND_843419:

View File

@ -847,8 +847,7 @@ static inline bool system_supports_poe(void)
static inline bool system_supports_gcs(void) static inline bool system_supports_gcs(void)
{ {
return IS_ENABLED(CONFIG_ARM64_GCS) && return alternative_has_cap_unlikely(ARM64_HAS_GCS);
alternative_has_cap_unlikely(ARM64_HAS_GCS);
} }
static inline bool system_supports_haft(void) static inline bool system_supports_haft(void)

View File

@ -7,6 +7,7 @@
#ifndef BUILD_VDSO #ifndef BUILD_VDSO
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/hugetlb.h>
#include <linux/shmem_fs.h> #include <linux/shmem_fs.h>
#include <linux/types.h> #include <linux/types.h>
@ -44,7 +45,7 @@ static inline unsigned long arch_calc_vm_flag_bits(struct file *file,
if (system_supports_mte()) { if (system_supports_mte()) {
if (flags & (MAP_ANONYMOUS | MAP_HUGETLB)) if (flags & (MAP_ANONYMOUS | MAP_HUGETLB))
return VM_MTE_ALLOWED; return VM_MTE_ALLOWED;
if (shmem_file(file)) if (shmem_file(file) || is_file_hugepages(file))
return VM_MTE_ALLOWED; return VM_MTE_ALLOWED;
} }

View File

@ -30,20 +30,17 @@ static bool is_image_text(unsigned long addr)
static void __kprobes *patch_map(void *addr, int fixmap) static void __kprobes *patch_map(void *addr, int fixmap)
{ {
unsigned long uintaddr = (uintptr_t) addr; phys_addr_t phys;
bool image = is_image_text(uintaddr);
struct page *page;
if (image)
page = phys_to_page(__pa_symbol(addr));
else if (IS_ENABLED(CONFIG_EXECMEM))
page = vmalloc_to_page(addr);
else
return addr;
if (is_image_text((unsigned long)addr)) {
phys = __pa_symbol(addr);
} else {
struct page *page = vmalloc_to_page(addr);
BUG_ON(!page); BUG_ON(!page);
return (void *)set_fixmap_offset(fixmap, page_to_phys(page) + phys = page_to_phys(page) + offset_in_page(addr);
(uintaddr & ~PAGE_MASK)); }
return (void *)set_fixmap_offset(fixmap, phys);
} }
static void __kprobes patch_unmap(int fixmap) static void __kprobes patch_unmap(int fixmap)

View File

@ -720,6 +720,8 @@ static int fpmr_set(struct task_struct *target, const struct user_regset *regset
if (!system_supports_fpmr()) if (!system_supports_fpmr())
return -EINVAL; return -EINVAL;
fpmr = target->thread.uw.fpmr;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fpmr, 0, count); ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fpmr, 0, count);
if (ret) if (ret)
return ret; return ret;
@ -1427,7 +1429,7 @@ static int tagged_addr_ctrl_get(struct task_struct *target,
{ {
long ctrl = get_tagged_addr_ctrl(target); long ctrl = get_tagged_addr_ctrl(target);
if (IS_ERR_VALUE(ctrl)) if (WARN_ON_ONCE(IS_ERR_VALUE(ctrl)))
return ctrl; return ctrl;
return membuf_write(&to, &ctrl, sizeof(ctrl)); return membuf_write(&to, &ctrl, sizeof(ctrl));
@ -1441,6 +1443,10 @@ static int tagged_addr_ctrl_set(struct task_struct *target, const struct
int ret; int ret;
long ctrl; long ctrl;
ctrl = get_tagged_addr_ctrl(target);
if (WARN_ON_ONCE(IS_ERR_VALUE(ctrl)))
return ctrl;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl, 0, -1); ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl, 0, -1);
if (ret) if (ret)
return ret; return ret;
@ -1472,6 +1478,8 @@ static int poe_set(struct task_struct *target, const struct
if (!system_supports_poe()) if (!system_supports_poe())
return -EINVAL; return -EINVAL;
ctrl = target->thread.por_el0;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl, 0, -1); ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl, 0, -1);
if (ret) if (ret)
return ret; return ret;
@ -1483,6 +1491,22 @@ static int poe_set(struct task_struct *target, const struct
#endif #endif
#ifdef CONFIG_ARM64_GCS #ifdef CONFIG_ARM64_GCS
static void task_gcs_to_user(struct user_gcs *user_gcs,
const struct task_struct *target)
{
user_gcs->features_enabled = target->thread.gcs_el0_mode;
user_gcs->features_locked = target->thread.gcs_el0_locked;
user_gcs->gcspr_el0 = target->thread.gcspr_el0;
}
static void task_gcs_from_user(struct task_struct *target,
const struct user_gcs *user_gcs)
{
target->thread.gcs_el0_mode = user_gcs->features_enabled;
target->thread.gcs_el0_locked = user_gcs->features_locked;
target->thread.gcspr_el0 = user_gcs->gcspr_el0;
}
static int gcs_get(struct task_struct *target, static int gcs_get(struct task_struct *target,
const struct user_regset *regset, const struct user_regset *regset,
struct membuf to) struct membuf to)
@ -1495,9 +1519,7 @@ static int gcs_get(struct task_struct *target,
if (target == current) if (target == current)
gcs_preserve_current_state(); gcs_preserve_current_state();
user_gcs.features_enabled = target->thread.gcs_el0_mode; task_gcs_to_user(&user_gcs, target);
user_gcs.features_locked = target->thread.gcs_el0_locked;
user_gcs.gcspr_el0 = target->thread.gcspr_el0;
return membuf_write(&to, &user_gcs, sizeof(user_gcs)); return membuf_write(&to, &user_gcs, sizeof(user_gcs));
} }
@ -1513,6 +1535,8 @@ static int gcs_set(struct task_struct *target, const struct
if (!system_supports_gcs()) if (!system_supports_gcs())
return -EINVAL; return -EINVAL;
task_gcs_to_user(&user_gcs, target);
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &user_gcs, 0, -1); ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &user_gcs, 0, -1);
if (ret) if (ret)
return ret; return ret;
@ -1520,9 +1544,7 @@ static int gcs_set(struct task_struct *target, const struct
if (user_gcs.features_enabled & ~PR_SHADOW_STACK_SUPPORTED_STATUS_MASK) if (user_gcs.features_enabled & ~PR_SHADOW_STACK_SUPPORTED_STATUS_MASK)
return -EINVAL; return -EINVAL;
target->thread.gcs_el0_mode = user_gcs.features_enabled; task_gcs_from_user(target, &user_gcs);
target->thread.gcs_el0_locked = user_gcs.features_locked;
target->thread.gcspr_el0 = user_gcs.gcspr_el0;
return 0; return 0;
} }

View File

@ -32,9 +32,9 @@ static unsigned long nr_pinned_asids;
static unsigned long *pinned_asid_map; static unsigned long *pinned_asid_map;
#define ASID_MASK (~GENMASK(asid_bits - 1, 0)) #define ASID_MASK (~GENMASK(asid_bits - 1, 0))
#define ASID_FIRST_VERSION (1UL << asid_bits) #define ASID_FIRST_VERSION (1UL << 16)
#define NUM_USER_ASIDS ASID_FIRST_VERSION #define NUM_USER_ASIDS (1UL << asid_bits)
#define ctxid2asid(asid) ((asid) & ~ASID_MASK) #define ctxid2asid(asid) ((asid) & ~ASID_MASK)
#define asid2ctxid(asid, genid) ((asid) | (genid)) #define asid2ctxid(asid, genid) ((asid) | (genid))

View File

@ -30,11 +30,13 @@ void copy_highpage(struct page *to, struct page *from)
if (!system_supports_mte()) if (!system_supports_mte())
return; return;
if (folio_test_hugetlb(src) && if (folio_test_hugetlb(src)) {
folio_test_hugetlb_mte_tagged(src)) { if (!folio_test_hugetlb_mte_tagged(src) ||
if (!folio_try_hugetlb_mte_tagging(dst)) from != folio_page(src, 0))
return; return;
WARN_ON_ONCE(!folio_try_hugetlb_mte_tagging(dst));
/* /*
* Populate tags for all subpages. * Populate tags for all subpages.
* *

View File

@ -117,15 +117,6 @@ static void __init arch_reserve_crashkernel(void)
static phys_addr_t __init max_zone_phys(phys_addr_t zone_limit) static phys_addr_t __init max_zone_phys(phys_addr_t zone_limit)
{ {
/**
* Information we get from firmware (e.g. DT dma-ranges) describe DMA
* bus constraints. Devices using DMA might have their own limitations.
* Some of them rely on DMA zone in low 32-bit memory. Keep low RAM
* DMA zone on platforms that have RAM there.
*/
if (memblock_start_of_DRAM() < U32_MAX)
zone_limit = min(zone_limit, U32_MAX);
return min(zone_limit, memblock_end_of_DRAM() - 1) + 1; return min(zone_limit, memblock_end_of_DRAM() - 1) + 1;
} }
@ -141,6 +132,14 @@ static void __init zone_sizes_init(void)
acpi_zone_dma_limit = acpi_iort_dma_get_max_cpu_address(); acpi_zone_dma_limit = acpi_iort_dma_get_max_cpu_address();
dt_zone_dma_limit = of_dma_get_max_cpu_address(NULL); dt_zone_dma_limit = of_dma_get_max_cpu_address(NULL);
zone_dma_limit = min(dt_zone_dma_limit, acpi_zone_dma_limit); zone_dma_limit = min(dt_zone_dma_limit, acpi_zone_dma_limit);
/*
* Information we get from firmware (e.g. DT dma-ranges) describe DMA
* bus constraints. Devices using DMA might have their own limitations.
* Some of them rely on DMA zone in low 32-bit memory. Keep low RAM
* DMA zone on platforms that have RAM there.
*/
if (memblock_start_of_DRAM() < U32_MAX)
zone_dma_limit = min(zone_dma_limit, U32_MAX);
arm64_dma_phys_limit = max_zone_phys(zone_dma_limit); arm64_dma_phys_limit = max_zone_phys(zone_dma_limit);
max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit); max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit);
#endif #endif

View File

@ -1716,6 +1716,8 @@ static struct acpi_platform_list pmcg_plat_info[] __initdata = {
/* HiSilicon Hip09 Platform */ /* HiSilicon Hip09 Platform */
{"HISI ", "HIP09 ", 0, ACPI_SIG_IORT, greater_than_or_equal, {"HISI ", "HIP09 ", 0, ACPI_SIG_IORT, greater_than_or_equal,
"Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
{"HISI ", "HIP09A ", 0, ACPI_SIG_IORT, greater_than_or_equal,
"Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
/* HiSilicon Hip10/11 Platform uses the same SMMU IP with Hip09 */ /* HiSilicon Hip10/11 Platform uses the same SMMU IP with Hip09 */
{"HISI ", "HIP10 ", 0, ACPI_SIG_IORT, greater_than_or_equal, {"HISI ", "HIP10 ", 0, ACPI_SIG_IORT, greater_than_or_equal,
"Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},

View File

@ -1,7 +1,6 @@
config ARM_CCA_GUEST config ARM_CCA_GUEST
tristate "Arm CCA Guest driver" tristate "Arm CCA Guest driver"
depends on ARM64 depends on ARM64
default m
select TSM_REPORTS select TSM_REPORTS
help help
The driver provides userspace interface to request and The driver provides userspace interface to request and

View File

@ -87,12 +87,8 @@ static int mmio_guard_ioremap_hook(phys_addr_t phys, size_t size,
while (phys < end) { while (phys < end) {
const int func_id = ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID; const int func_id = ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID;
int err;
err = arm_smccc_do_one_page(func_id, phys);
if (err)
return err;
WARN_ON_ONCE(arm_smccc_do_one_page(func_id, phys));
phys += PAGE_SIZE; phys += PAGE_SIZE;
} }

View File

@ -113,7 +113,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
* way when do_mmap unwinds (may be important on powerpc * way when do_mmap unwinds (may be important on powerpc
* and ia64). * and ia64).
*/ */
vm_flags_set(vma, VM_HUGETLB | VM_DONTEXPAND | VM_MTE_ALLOWED); vm_flags_set(vma, VM_HUGETLB | VM_DONTEXPAND);
vma->vm_ops = &hugetlb_vm_ops; vma->vm_ops = &hugetlb_vm_ops;
ret = seal_check_write(info->seals, vma); ret = seal_check_write(info->seals, vma);