mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 01:32:21 +02:00
arm64 fixes for -rc5
- Fix early_ioremap() of unaligned ACPI tables - Remove bogus information from data abort diagnostics - Fix kprobes recursion during single-step - Fix incorrect constant in ESR address size fault macro - Fix OOB page-table walk in memory hot-unplug notifier - Fix OOB access to the linear map when retrieving an unaligned huge pte - Fix MPAM register reset values - Fix MPAM NULL dereference on teardown -----BEGIN PGP SIGNATURE----- iQFEBAABCgAuFiEEPxTL6PPUbjXGY88ct6xw3ITBYzQFAmpjYKMQHHdpbGxAa2Vy bmVsLm9yZwAKCRC3rHDchMFjNDMIB/9MTWfjEY3QYefcaP3yIRqN4IVY1CORewCi yGE/BKq4WH86mCKp7k+OojyXYV5WP7YZOVZcEYIuSCyJ5KrRmbJ6ezFgQaDP+C4y 18ZSMSks9LKVkV0gZNiAkdr2NtKPX4uI/iqFskKWUIRoRBHXjijc5J6R71BPiQYV r3Uwtw4TQPd8YV/L5j71OyK/PhgSQyfdXClo0iW3b4WK0xoZJUcrIQIVEZduKL6J IPlzarT46sZKvyb8MZkOWiURVRE8JWMDn1LY9QP02OMyJeWyO9q3TlQ4dC/FNpb9 tUMfomyteXr7TIxU3ueTRs+wng7zQJtWpiFtpwFlzFaZcXVrH0xU =M9Lk -----END PGP SIGNATURE----- Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux Pull arm64 fixes from Will Deacon: "It's a bit all over the place, as I was hoping to fix a decade-old bug in our seccomp handling on syscall entry and ended up collecting other fixes in the meantime. You'll see the failed attempt (+revert) here but I didn't want to hold off on the others any longer. Hopefully we'll get that one squashed next week... - Fix early_ioremap() of unaligned ACPI tables - Remove bogus information from data abort diagnostics - Fix kprobes recursion during single-step - Fix incorrect constant in ESR address size fault macro - Fix OOB page-table walk in memory hot-unplug notifier - Fix OOB access to the linear map when retrieving an unaligned huge pte - Fix MPAM register reset values - Fix MPAM NULL dereference on teardown" * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: make huge_ptep_get handled unaligned addresses arm64/mm: Check the requested PFN range during memory removal arm64: Correct value returned by ESR_ELx_FSC_ADDRSZ_nL() arm64: kprobes: Allow reentering kprobes while single-stepping arm64: kprobes: Only handle faults originating from XOL slot drivers/virt: pkvm: Fix end calculation in mmio_guard_ioremap_hook() Revert "arm64: syscall: Ensure saved x0 is kept in-sync with tracer updates" arm64: mm: When logging data aborts only decode Xs when ISV=1 arm64: fixmap: Allow 256K early_ioremap() at any offset arm_mpam: guard MBWU state before adding it to garbage arm_mpam: Fix MPAMCFG_MBW_PBM register setting arm_mpam: Fix software reset values of MPAMCFG_PRI arm64: syscall: Ensure saved x0 is kept in-sync with tracer updates
This commit is contained in:
commit
0c452fbdf4
|
|
@ -131,7 +131,7 @@
|
|||
* Annoyingly, the negative levels for Address size faults aren't laid out
|
||||
* contiguously (or in the desired order)
|
||||
*/
|
||||
#define ESR_ELx_FSC_ADDRSZ_nL(n) ((n) == -1 ? 0x25 : 0x2C)
|
||||
#define ESR_ELx_FSC_ADDRSZ_nL(n) ((n) == -1 ? 0x29 : 0x2C)
|
||||
#define ESR_ELx_FSC_ADDRSZ_L(n) ((n) < 0 ? ESR_ELx_FSC_ADDRSZ_nL(n) : \
|
||||
(ESR_ELx_FSC_ADDRSZ + (n)))
|
||||
|
||||
|
|
|
|||
|
|
@ -78,8 +78,12 @@ enum fixed_addresses {
|
|||
/*
|
||||
* Temporary boot-time mappings, used by early_ioremap(),
|
||||
* before ioremap() is functional.
|
||||
*
|
||||
* Reserve one extra page so a 256K mapping may start at any
|
||||
* offset within a page. early_ioremap() maps the page-aligned
|
||||
* physical range, so the initial offset can consume an extra page.
|
||||
*/
|
||||
#define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)
|
||||
#define NR_FIX_BTMAPS ((SZ_256K / PAGE_SIZE) + 1)
|
||||
#define FIX_BTMAPS_SLOTS 7
|
||||
#define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,12 @@
|
|||
struct prev_kprobe {
|
||||
struct kprobe *kp;
|
||||
unsigned int status;
|
||||
|
||||
/*
|
||||
* The original DAIF state of the outer kprobe, saved here before
|
||||
* a nested kprobe overwrites kcb->saved_irqflag during reentry.
|
||||
*/
|
||||
unsigned long saved_irqflag;
|
||||
};
|
||||
|
||||
/* per-cpu kprobe control block */
|
||||
|
|
|
|||
|
|
@ -174,12 +174,27 @@ static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
|
|||
{
|
||||
kcb->prev_kprobe.kp = kprobe_running();
|
||||
kcb->prev_kprobe.status = kcb->kprobe_status;
|
||||
|
||||
/*
|
||||
* Save the outer kprobe's original DAIF flags before the nested
|
||||
* kprobe calls kprobes_save_local_irqflag() and overwrites
|
||||
* kcb->saved_irqflag. Without this, the outer kprobe will restore
|
||||
* the wrong DAIF state and leave interrupts permanently masked.
|
||||
*/
|
||||
kcb->prev_kprobe.saved_irqflag = kcb->saved_irqflag;
|
||||
}
|
||||
|
||||
static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
|
||||
{
|
||||
__this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
|
||||
kcb->kprobe_status = kcb->prev_kprobe.status;
|
||||
|
||||
/*
|
||||
* Restore the outer kprobe's saved_irqflag so that when its
|
||||
* single-step completes, kprobes_restore_local_irqflag() uses
|
||||
* the correct original DAIF value.
|
||||
*/
|
||||
kcb->saved_irqflag = kcb->prev_kprobe.saved_irqflag;
|
||||
}
|
||||
|
||||
static void __kprobes set_current_kprobe(struct kprobe *p)
|
||||
|
|
@ -240,10 +255,16 @@ static int __kprobes reenter_kprobe(struct kprobe *p,
|
|||
switch (kcb->kprobe_status) {
|
||||
case KPROBE_HIT_SSDONE:
|
||||
case KPROBE_HIT_ACTIVE:
|
||||
case KPROBE_HIT_SS:
|
||||
/*
|
||||
* A probe can be hit while another kprobe is preparing or
|
||||
* executing its XOL single-step instruction. This is still a
|
||||
* recoverable one-level reentry, so handle it in the same way as
|
||||
* reentry from KPROBE_HIT_ACTIVE or KPROBE_HIT_SSDONE.
|
||||
*/
|
||||
kprobes_inc_nmissed_count(p);
|
||||
setup_singlestep(p, regs, kcb, 1);
|
||||
break;
|
||||
case KPROBE_HIT_SS:
|
||||
case KPROBE_REENTER:
|
||||
pr_warn("Failed to recover from reentered kprobes.\n");
|
||||
dump_kprobe(p);
|
||||
|
|
@ -282,9 +303,31 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
|
|||
struct kprobe *cur = kprobe_running();
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
/*
|
||||
* Simulated kprobes execute in the debug trap context and have no
|
||||
* XOL slot. Any page fault taken while a simulated kprobe is in
|
||||
* progress cannot have been caused by kprobe single-stepping and
|
||||
* must be left alone for the normal page fault handler, including
|
||||
* fixup_exception.
|
||||
*/
|
||||
if (cur && !cur->ainsn.xol_insn)
|
||||
return 0;
|
||||
|
||||
switch (kcb->kprobe_status) {
|
||||
case KPROBE_HIT_SS:
|
||||
case KPROBE_REENTER:
|
||||
/*
|
||||
* A page fault taken while in KPROBE_HIT_SS or
|
||||
* KPROBE_REENTER state is only attributable to kprobe
|
||||
* single-stepping if the faulting PC points to the
|
||||
* current kprobe's XOL instruction. If the fault occurred
|
||||
* elsewhere (e.g. in perf or tracing code invoked from the
|
||||
* debug exception path), leave it for the normal page fault
|
||||
* handler to process.
|
||||
*/
|
||||
if (instruction_pointer(regs) != (unsigned long)cur->ainsn.xol_insn)
|
||||
break;
|
||||
|
||||
/*
|
||||
* We are here because the instruction being single
|
||||
* stepped caused a page fault. We reset the current
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ static void data_abort_decode(unsigned long esr)
|
|||
pr_alert(" SF = %lu, AR = %lu\n",
|
||||
(esr & ESR_ELx_SF) >> ESR_ELx_SF_SHIFT,
|
||||
(esr & ESR_ELx_AR) >> ESR_ELx_AR_SHIFT);
|
||||
pr_alert(" Xs = %llu\n",
|
||||
(iss2 & ESR_ELx_Xs_MASK) >> ESR_ELx_Xs_SHIFT);
|
||||
} else {
|
||||
pr_alert(" ISV = 0, ISS = 0x%08lx, ISS2 = 0x%08lx\n",
|
||||
esr & ESR_ELx_ISS_MASK, iss2);
|
||||
|
|
@ -87,11 +89,10 @@ static void data_abort_decode(unsigned long esr)
|
|||
(iss2 & ESR_ELx_TnD) >> ESR_ELx_TnD_SHIFT,
|
||||
(iss2 & ESR_ELx_TagAccess) >> ESR_ELx_TagAccess_SHIFT);
|
||||
|
||||
pr_alert(" GCS = %ld, Overlay = %lu, DirtyBit = %lu, Xs = %llu\n",
|
||||
pr_alert(" GCS = %ld, Overlay = %lu, DirtyBit = %lu\n",
|
||||
(iss2 & ESR_ELx_GCS) >> ESR_ELx_GCS_SHIFT,
|
||||
(iss2 & ESR_ELx_Overlay) >> ESR_ELx_Overlay_SHIFT,
|
||||
(iss2 & ESR_ELx_DirtyBit) >> ESR_ELx_DirtyBit_SHIFT,
|
||||
(iss2 & ESR_ELx_Xs_MASK) >> ESR_ELx_Xs_SHIFT);
|
||||
(iss2 & ESR_ELx_DirtyBit) >> ESR_ELx_DirtyBit_SHIFT);
|
||||
}
|
||||
|
||||
static void mem_abort_decode(unsigned long esr)
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ static int find_num_contig(struct mm_struct *mm, unsigned long addr,
|
|||
p4dp = p4d_offset(pgdp, addr);
|
||||
pudp = pud_offset(p4dp, addr);
|
||||
pmdp = pmd_offset(pudp, addr);
|
||||
if ((pte_t *)pmdp == ptep) {
|
||||
if ((pte_t *)PTR_ALIGN_DOWN(pmdp, sizeof(*pmdp) * CONT_PMDS) == ptep) {
|
||||
*pgsize = PMD_SIZE;
|
||||
return CONT_PMDS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2194,7 +2194,7 @@ static int prevent_memory_remove_notifier(struct notifier_block *nb,
|
|||
}
|
||||
}
|
||||
|
||||
if (!can_unmap_without_split(pfn, arg->nr_pages))
|
||||
if (!can_unmap_without_split(arg->start_pfn, arg->nr_pages))
|
||||
return NOTIFY_BAD;
|
||||
|
||||
return NOTIFY_OK;
|
||||
|
|
|
|||
|
|
@ -1552,12 +1552,9 @@ static u16 mpam_wa_t241_calc_min_from_max(struct mpam_props *props,
|
|||
static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid,
|
||||
struct mpam_config *cfg)
|
||||
{
|
||||
u32 pri_val = 0;
|
||||
u16 cmax = MPAMCFG_CMAX_CMAX;
|
||||
struct mpam_msc *msc = ris->vmsc->msc;
|
||||
struct mpam_props *rprops = &ris->props;
|
||||
u16 dspri = GENMASK(rprops->dspri_wd, 0);
|
||||
u16 intpri = GENMASK(rprops->intpri_wd, 0);
|
||||
|
||||
mutex_lock(&msc->part_sel_lock);
|
||||
__mpam_part_sel(ris->ris_idx, partid, msc);
|
||||
|
|
@ -1583,9 +1580,9 @@ static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid,
|
|||
|
||||
if (mpam_has_feature(mpam_feat_mbw_part, rprops)) {
|
||||
if (mpam_has_feature(mpam_feat_mbw_part, cfg))
|
||||
mpam_reset_msc_bitmap(msc, MPAMCFG_MBW_PBM, rprops->mbw_pbm_bits);
|
||||
else
|
||||
mpam_write_partsel_reg(msc, MBW_PBM, cfg->mbw_pbm);
|
||||
else
|
||||
mpam_reset_msc_bitmap(msc, MPAMCFG_MBW_PBM, rprops->mbw_pbm_bits);
|
||||
}
|
||||
|
||||
if (mpam_has_feature(mpam_feat_mbw_min, rprops)) {
|
||||
|
|
@ -1622,16 +1619,25 @@ static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid,
|
|||
|
||||
if (mpam_has_feature(mpam_feat_intpri_part, rprops) ||
|
||||
mpam_has_feature(mpam_feat_dspri_part, rprops)) {
|
||||
/* aces high? */
|
||||
if (!mpam_has_feature(mpam_feat_intpri_part_0_low, rprops))
|
||||
intpri = 0;
|
||||
if (!mpam_has_feature(mpam_feat_dspri_part_0_low, rprops))
|
||||
dspri = 0;
|
||||
u32 pri_val = 0;
|
||||
|
||||
if (mpam_has_feature(mpam_feat_intpri_part, rprops)) {
|
||||
u16 intpri = GENMASK(rprops->intpri_wd - 1, 0);
|
||||
|
||||
/* aces high? */
|
||||
if (!mpam_has_feature(mpam_feat_intpri_part_0_low, rprops))
|
||||
intpri = 0;
|
||||
|
||||
if (mpam_has_feature(mpam_feat_intpri_part, rprops))
|
||||
pri_val |= FIELD_PREP(MPAMCFG_PRI_INTPRI, intpri);
|
||||
if (mpam_has_feature(mpam_feat_dspri_part, rprops))
|
||||
}
|
||||
if (mpam_has_feature(mpam_feat_dspri_part, rprops)) {
|
||||
u16 dspri = GENMASK(rprops->dspri_wd - 1, 0);
|
||||
|
||||
if (!mpam_has_feature(mpam_feat_dspri_part_0_low, rprops))
|
||||
dspri = 0;
|
||||
|
||||
pri_val |= FIELD_PREP(MPAMCFG_PRI_DSPRI, dspri);
|
||||
}
|
||||
|
||||
mpam_write_partsel_reg(msc, PRI, pri_val);
|
||||
}
|
||||
|
|
@ -2606,8 +2612,10 @@ static void __destroy_component_cfg(struct mpam_component *comp)
|
|||
msc = vmsc->msc;
|
||||
|
||||
if (mpam_mon_sel_lock(msc)) {
|
||||
list_for_each_entry(ris, &vmsc->ris, vmsc_list)
|
||||
add_to_garbage(ris->mbwu_state);
|
||||
list_for_each_entry(ris, &vmsc->ris, vmsc_list) {
|
||||
if (ris->mbwu_state)
|
||||
add_to_garbage(ris->mbwu_state);
|
||||
}
|
||||
mpam_mon_sel_unlock(msc);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,8 +82,8 @@ static int mmio_guard_ioremap_hook(phys_addr_t phys, size_t size,
|
|||
if (protval != PROT_DEVICE_nGnRE && protval != PROT_DEVICE_nGnRnE)
|
||||
return 0;
|
||||
|
||||
end = PAGE_ALIGN(phys + size);
|
||||
phys = PAGE_ALIGN_DOWN(phys);
|
||||
end = phys + PAGE_ALIGN(size);
|
||||
|
||||
while (phys < end) {
|
||||
const int func_id = ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user