Commit a8a1b163 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20181113' into staging



target/arm queue:
 * Remove no-longer-needed workaround for small SAU regions for v8M
 * Remove antique TODO comment
 * MAINTAINERS: Add an entry for the 'collie' machine
 * hw/arm/sysbus-fdt: Only call match_fn callback if the type matches
 * Fix infinite recursion in tlbi_aa64_vmalle1_write()
 * ARM KVM: fix various bugs in handling of guest debugging
 * Correctly implement handling of HCR_EL2.{VI, VF}
 * Hyp mode R14 is shared with User and System
 * Give Cortex-A15 and -A7 the EL2 feature

# gpg: Signature made Tue 13 Nov 2018 10:51:53 GMT
# gpg:                using RSA key 3C2525ED14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>"
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>"
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20181113:
  target/arm/cpu: Give Cortex-A15 and -A7 the EL2 feature
  target/arm: Hyp mode R14 is shared with User and System
  target/arm: Correctly implement handling of HCR_EL2.{VI, VF}
  target/arm: Track the state of our irq lines from the GIC explicitly
  Revert "target/arm: Implement HCR.VI and VF"
  arm: fix aa64_generate_debug_exceptions to work with EL2
  arm: use symbolic MDCR_TDE in arm_debug_target_el
  tests/guest-debug: fix scoping of failcount
  target/arm64: kvm debug set target_el when passing exception to guest
  target/arm64: hold BQL when calling do_interrupt()
  target/arm64: properly handle DBGVR RESS bits
  target/arm: Fix typo in tlbi_aa64_vmalle1_write
  hw/arm/sysbus-fdt: Only call match_fn callback if the type matches
  MAINTAINERS: Add an entry for the 'collie' machine
  target/arm: Remove antique TODO comment
  target/arm: Remove workaround for small SAU regions

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 6db87aae 436c0cbb
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -591,6 +591,13 @@ F: hw/*/pxa2xx*
F: hw/misc/mst_fpga.c
F: include/hw/arm/pxa.h

Sharp SL-5500 (Collie) PDA
M: Peter Maydell <peter.maydell@linaro.org>
L: qemu-arm@nongnu.org
S: Odd Fixes
F: hw/arm/collie.c
F: hw/arm/strongarm*

Stellaris
M: Peter Maydell <peter.maydell@linaro.org>
L: qemu-arm@nongnu.org
+7 −5
Original line number Diff line number Diff line
@@ -449,7 +449,7 @@ static bool type_match(SysBusDevice *sbdev, const BindingEntry *entry)
    return !strcmp(object_get_typename(OBJECT(sbdev)), entry->typename);
}

#define TYPE_BINDING(type, add_fn) {(type), NULL, (add_fn), type_match}
#define TYPE_BINDING(type, add_fn) {(type), NULL, (add_fn), NULL}

/* list of supported dynamic sysbus bindings */
static const BindingEntry bindings[] = {
@@ -481,12 +481,14 @@ static void add_fdt_node(SysBusDevice *sbdev, void *opaque)
    for (i = 0; i < ARRAY_SIZE(bindings); i++) {
        const BindingEntry *iter = &bindings[i];

        if (iter->match_fn(sbdev, iter)) {
        if (type_match(sbdev, iter)) {
            if (!iter->match_fn || iter->match_fn(sbdev, iter)) {
                ret = iter->add_fn(sbdev, opaque);
                assert(!ret);
                return;
            }
        }
    }
    error_report("Device %s can not be dynamically instantiated",
                     qdev_fw_name(DEVICE(sbdev)));
    exit(1);
+66 −1
Original line number Diff line number Diff line
@@ -436,6 +436,48 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
}
#endif

void arm_cpu_update_virq(ARMCPU *cpu)
{
    /*
     * Update the interrupt level for VIRQ, which is the logical OR of
     * the HCR_EL2.VI bit and the input line level from the GIC.
     */
    CPUARMState *env = &cpu->env;
    CPUState *cs = CPU(cpu);

    bool new_state = (env->cp15.hcr_el2 & HCR_VI) ||
        (env->irq_line_state & CPU_INTERRUPT_VIRQ);

    if (new_state != ((cs->interrupt_request & CPU_INTERRUPT_VIRQ) != 0)) {
        if (new_state) {
            cpu_interrupt(cs, CPU_INTERRUPT_VIRQ);
        } else {
            cpu_reset_interrupt(cs, CPU_INTERRUPT_VIRQ);
        }
    }
}

void arm_cpu_update_vfiq(ARMCPU *cpu)
{
    /*
     * Update the interrupt level for VFIQ, which is the logical OR of
     * the HCR_EL2.VF bit and the input line level from the GIC.
     */
    CPUARMState *env = &cpu->env;
    CPUState *cs = CPU(cpu);

    bool new_state = (env->cp15.hcr_el2 & HCR_VF) ||
        (env->irq_line_state & CPU_INTERRUPT_VFIQ);

    if (new_state != ((cs->interrupt_request & CPU_INTERRUPT_VFIQ) != 0)) {
        if (new_state) {
            cpu_interrupt(cs, CPU_INTERRUPT_VFIQ);
        } else {
            cpu_reset_interrupt(cs, CPU_INTERRUPT_VFIQ);
        }
    }
}

#ifndef CONFIG_USER_ONLY
static void arm_cpu_set_irq(void *opaque, int irq, int level)
{
@@ -449,11 +491,21 @@ static void arm_cpu_set_irq(void *opaque, int irq, int level)
        [ARM_CPU_VFIQ] = CPU_INTERRUPT_VFIQ
    };

    if (level) {
        env->irq_line_state |= mask[irq];
    } else {
        env->irq_line_state &= ~mask[irq];
    }

    switch (irq) {
    case ARM_CPU_VIRQ:
        assert(arm_feature(env, ARM_FEATURE_EL2));
        arm_cpu_update_virq(cpu);
        break;
    case ARM_CPU_VFIQ:
        assert(arm_feature(env, ARM_FEATURE_EL2));
        /* fall through */
        arm_cpu_update_vfiq(cpu);
        break;
    case ARM_CPU_IRQ:
    case ARM_CPU_FIQ:
        if (level) {
@@ -471,19 +523,30 @@ static void arm_cpu_kvm_set_irq(void *opaque, int irq, int level)
{
#ifdef CONFIG_KVM
    ARMCPU *cpu = opaque;
    CPUARMState *env = &cpu->env;
    CPUState *cs = CPU(cpu);
    int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT;
    uint32_t linestate_bit;

    switch (irq) {
    case ARM_CPU_IRQ:
        kvm_irq |= KVM_ARM_IRQ_CPU_IRQ;
        linestate_bit = CPU_INTERRUPT_HARD;
        break;
    case ARM_CPU_FIQ:
        kvm_irq |= KVM_ARM_IRQ_CPU_FIQ;
        linestate_bit = CPU_INTERRUPT_FIQ;
        break;
    default:
        g_assert_not_reached();
    }

    if (level) {
        env->irq_line_state |= linestate_bit;
    } else {
        env->irq_line_state &= ~linestate_bit;
    }

    kvm_irq |= cs->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT;
    kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0);
#endif
@@ -1587,6 +1650,7 @@ static void cortex_a7_initfn(Object *obj)
    set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
    set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
    set_feature(&cpu->env, ARM_FEATURE_EL2);
    set_feature(&cpu->env, ARM_FEATURE_EL3);
    cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7;
    cpu->midr = 0x410fc075;
@@ -1633,6 +1697,7 @@ static void cortex_a15_initfn(Object *obj)
    set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
    set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
    set_feature(&cpu->env, ARM_FEATURE_EL2);
    set_feature(&cpu->env, ARM_FEATURE_EL3);
    cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
    cpu->midr = 0x412fc0f1;
+28 −16
Original line number Diff line number Diff line
@@ -538,6 +538,9 @@ typedef struct CPUARMState {
        uint64_t esr;
    } serror;

    /* State of our input IRQ/FIQ/VIRQ/VFIQ lines */
    uint32_t irq_line_state;

    /* Thumb-2 EE state.  */
    uint32_t teecr;
    uint32_t teehbr;
@@ -2743,7 +2746,7 @@ static inline int arm_debug_target_el(CPUARMState *env)

    if (arm_feature(env, ARM_FEATURE_EL2) && !secure) {
        route_to_el2 = env->cp15.hcr_el2 & HCR_TGE ||
                       env->cp15.mdcr_el2 & (1 << 8);
                       env->cp15.mdcr_el2 & MDCR_TDE;
    }

    if (route_to_el2) {
@@ -2764,23 +2767,35 @@ static inline bool arm_v7m_csselr_razwi(ARMCPU *cpu)
    return (cpu->clidr & R_V7M_CLIDR_CTYPE_ALL_MASK) != 0;
}

/* See AArch64.GenerateDebugExceptionsFrom() in ARM ARM pseudocode */
static inline bool aa64_generate_debug_exceptions(CPUARMState *env)
{
    if (arm_is_secure(env)) {
        /* MDCR_EL3.SDD disables debug events from Secure state */
        if (extract32(env->cp15.mdcr_el3, 16, 1) != 0
            || arm_current_el(env) == 3) {
    int cur_el = arm_current_el(env);
    int debug_el;

    if (cur_el == 3) {
        return false;
    }
    }

    if (arm_current_el(env) == arm_debug_target_el(env)) {
        if ((extract32(env->cp15.mdscr_el1, 13, 1) == 0)
            || (env->daif & PSTATE_D)) {
    /* MDCR_EL3.SDD disables debug events from Secure state */
    if (arm_is_secure_below_el3(env)
        && extract32(env->cp15.mdcr_el3, 16, 1)) {
        return false;
    }

    /*
     * Same EL to same EL debug exceptions need MDSCR_KDE enabled
     * while not masking the (D)ebug bit in DAIF.
     */
    debug_el = arm_debug_target_el(env);

    if (cur_el == debug_el) {
        return extract32(env->cp15.mdscr_el1, 13, 1)
            && !(env->daif & PSTATE_D);
    }
    return true;

    /* Otherwise the debug target needs to be a higher EL */
    return debug_el > cur_el;
}

static inline bool aa32_generate_debug_exceptions(CPUARMState *env)
@@ -2833,9 +2848,6 @@ static inline bool aa32_generate_debug_exceptions(CPUARMState *env)
 * since the pseudocode has it at all callsites except for the one in
 * CheckSoftwareStep(), where it is elided because both branches would
 * always return the same value.
 *
 * Parts of the pseudocode relating to EL2 and EL3 are omitted because we
 * don't yet implement those exception levels or their associated trap bits.
 */
static inline bool arm_generate_debug_exceptions(CPUARMState *env)
{
+33 −68
Original line number Diff line number Diff line
@@ -3155,7 +3155,7 @@ static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
    CPUState *cs = ENV_GET_CPU(env);

    if (tlb_force_broadcast(env)) {
        tlbi_aa64_vmalle1_write(env, NULL, value);
        tlbi_aa64_vmalle1is_write(env, NULL, value);
        return;
    }

@@ -3931,7 +3931,6 @@ static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
{
    ARMCPU *cpu = arm_env_get_cpu(env);
    CPUState *cs = ENV_GET_CPU(env);
    uint64_t valid_mask = HCR_MASK;

    if (arm_feature(env, ARM_FEATURE_EL3)) {
@@ -3950,28 +3949,6 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
    /* Clear RES0 bits.  */
    value &= valid_mask;

    /*
     * VI and VF are kept in cs->interrupt_request. Modifying that
     * requires that we have the iothread lock, which is done by
     * marking the reginfo structs as ARM_CP_IO.
     * Note that if a write to HCR pends a VIRQ or VFIQ it is never
     * possible for it to be taken immediately, because VIRQ and
     * VFIQ are masked unless running at EL0 or EL1, and HCR
     * can only be written at EL2.
     */
    g_assert(qemu_mutex_iothread_locked());
    if (value & HCR_VI) {
        cs->interrupt_request |= CPU_INTERRUPT_VIRQ;
    } else {
        cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
    }
    if (value & HCR_VF) {
        cs->interrupt_request |= CPU_INTERRUPT_VFIQ;
    } else {
        cs->interrupt_request &= ~CPU_INTERRUPT_VFIQ;
    }
    value &= ~(HCR_VI | HCR_VF);

    /* These bits change the MMU setup:
     * HCR_VM enables stage 2 translation
     * HCR_PTW forbids certain page-table setups
@@ -3981,6 +3958,21 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
        tlb_flush(CPU(cpu));
    }
    env->cp15.hcr_el2 = value;

    /*
     * Updates to VI and VF require us to update the status of
     * virtual interrupts, which are the logical OR of these bits
     * and the state of the input lines from the GIC. (This requires
     * that we have the iothread lock, which is done by marking the
     * reginfo structs as ARM_CP_IO.)
     * Note that if a write to HCR pends a VIRQ or VFIQ it is never
     * possible for it to be taken immediately, because VIRQ and
     * VFIQ are masked unless running at EL0 or EL1, and HCR
     * can only be written at EL2.
     */
    g_assert(qemu_mutex_iothread_locked());
    arm_cpu_update_virq(cpu);
    arm_cpu_update_vfiq(cpu);
}

static void hcr_writehigh(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -3999,32 +3991,17 @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
    hcr_write(env, NULL, value);
}

static uint64_t hcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    /* The VI and VF bits live in cs->interrupt_request */
    uint64_t ret = env->cp15.hcr_el2 & ~(HCR_VI | HCR_VF);
    CPUState *cs = ENV_GET_CPU(env);

    if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
        ret |= HCR_VI;
    }
    if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
        ret |= HCR_VF;
    }
    return ret;
}

static const ARMCPRegInfo el2_cp_reginfo[] = {
    { .name = "HCR_EL2", .state = ARM_CP_STATE_AA64,
      .type = ARM_CP_IO,
      .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
      .writefn = hcr_write, .readfn = hcr_read },
      .writefn = hcr_write },
    { .name = "HCR", .state = ARM_CP_STATE_AA32,
      .type = ARM_CP_ALIAS | ARM_CP_IO,
      .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
      .writefn = hcr_writelow, .readfn = hcr_read },
      .writefn = hcr_writelow },
    { .name = "ELR_EL2", .state = ARM_CP_STATE_AA64,
      .type = ARM_CP_ALIAS,
      .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
@@ -6455,13 +6432,14 @@ static void switch_mode(CPUARMState *env, int mode)

    i = bank_number(old_mode);
    env->banked_r13[i] = env->regs[13];
    env->banked_r14[i] = env->regs[14];
    env->banked_spsr[i] = env->spsr;

    i = bank_number(mode);
    env->regs[13] = env->banked_r13[i];
    env->regs[14] = env->banked_r14[i];
    env->spsr = env->banked_spsr[i];

    env->banked_r14[r14_bank_number(old_mode)] = env->regs[14];
    env->regs[14] = env->banked_r14[r14_bank_number(mode)];
}

/* Physical Interrupt Target EL Lookup Table
@@ -8040,7 +8018,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
        if (mode == ARM_CPU_MODE_HYP) {
            env->xregs[14] = env->regs[14];
        } else {
            env->xregs[14] = env->banked_r14[bank_number(ARM_CPU_MODE_USR)];
            env->xregs[14] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_USR)];
        }
    }

@@ -8054,7 +8032,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
        env->xregs[16] = env->regs[14];
        env->xregs[17] = env->regs[13];
    } else {
        env->xregs[16] = env->banked_r14[bank_number(ARM_CPU_MODE_IRQ)];
        env->xregs[16] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_IRQ)];
        env->xregs[17] = env->banked_r13[bank_number(ARM_CPU_MODE_IRQ)];
    }

@@ -8062,7 +8040,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
        env->xregs[18] = env->regs[14];
        env->xregs[19] = env->regs[13];
    } else {
        env->xregs[18] = env->banked_r14[bank_number(ARM_CPU_MODE_SVC)];
        env->xregs[18] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_SVC)];
        env->xregs[19] = env->banked_r13[bank_number(ARM_CPU_MODE_SVC)];
    }

@@ -8070,7 +8048,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
        env->xregs[20] = env->regs[14];
        env->xregs[21] = env->regs[13];
    } else {
        env->xregs[20] = env->banked_r14[bank_number(ARM_CPU_MODE_ABT)];
        env->xregs[20] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_ABT)];
        env->xregs[21] = env->banked_r13[bank_number(ARM_CPU_MODE_ABT)];
    }

@@ -8078,7 +8056,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
        env->xregs[22] = env->regs[14];
        env->xregs[23] = env->regs[13];
    } else {
        env->xregs[22] = env->banked_r14[bank_number(ARM_CPU_MODE_UND)];
        env->xregs[22] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_UND)];
        env->xregs[23] = env->banked_r13[bank_number(ARM_CPU_MODE_UND)];
    }

@@ -8095,7 +8073,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
            env->xregs[i] = env->fiq_regs[i - 24];
        }
        env->xregs[29] = env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)];
        env->xregs[30] = env->banked_r14[bank_number(ARM_CPU_MODE_FIQ)];
        env->xregs[30] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_FIQ)];
    }

    env->pc = env->regs[15];
@@ -8145,7 +8123,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
        if (mode == ARM_CPU_MODE_HYP) {
            env->regs[14] = env->xregs[14];
        } else {
            env->banked_r14[bank_number(ARM_CPU_MODE_USR)] = env->xregs[14];
            env->banked_r14[r14_bank_number(ARM_CPU_MODE_USR)] = env->xregs[14];
        }
    }

@@ -8159,7 +8137,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
        env->regs[14] = env->xregs[16];
        env->regs[13] = env->xregs[17];
    } else {
        env->banked_r14[bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[16];
        env->banked_r14[r14_bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[16];
        env->banked_r13[bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[17];
    }

@@ -8167,7 +8145,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
        env->regs[14] = env->xregs[18];
        env->regs[13] = env->xregs[19];
    } else {
        env->banked_r14[bank_number(ARM_CPU_MODE_SVC)] = env->xregs[18];
        env->banked_r14[r14_bank_number(ARM_CPU_MODE_SVC)] = env->xregs[18];
        env->banked_r13[bank_number(ARM_CPU_MODE_SVC)] = env->xregs[19];
    }

@@ -8175,7 +8153,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
        env->regs[14] = env->xregs[20];
        env->regs[13] = env->xregs[21];
    } else {
        env->banked_r14[bank_number(ARM_CPU_MODE_ABT)] = env->xregs[20];
        env->banked_r14[r14_bank_number(ARM_CPU_MODE_ABT)] = env->xregs[20];
        env->banked_r13[bank_number(ARM_CPU_MODE_ABT)] = env->xregs[21];
    }

@@ -8183,7 +8161,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
        env->regs[14] = env->xregs[22];
        env->regs[13] = env->xregs[23];
    } else {
        env->banked_r14[bank_number(ARM_CPU_MODE_UND)] = env->xregs[22];
        env->banked_r14[r14_bank_number(ARM_CPU_MODE_UND)] = env->xregs[22];
        env->banked_r13[bank_number(ARM_CPU_MODE_UND)] = env->xregs[23];
    }

@@ -8200,7 +8178,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
            env->fiq_regs[i - 24] = env->xregs[i];
        }
        env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[29];
        env->banked_r14[bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[30];
        env->banked_r14[r14_bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[30];
    }

    env->regs[15] = env->pc;
@@ -8378,7 +8356,6 @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
        return;
    }

    /* TODO: Vectored interrupt controller.  */
    switch (cs->exception_index) {
    case EXCP_UDEF:
        new_mode = ARM_CPU_MODE_UND;
@@ -10560,18 +10537,6 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,

    ret = pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr,
                            txattrs, prot, &mpu_is_subpage, fi, NULL);
    /*
     * TODO: this is a temporary hack to ignore the fact that the SAU region
     * is smaller than a page if this is an executable region. We never
     * supported small MPU regions, but we did (accidentally) allow small
     * SAU regions, and if we now made small SAU regions not be executable
     * then this would break previously working guest code. We can't
     * remove this until/unless we implement support for execution from
     * small regions.
     */
    if (*prot & PAGE_EXEC) {
        sattrs.subpage = false;
    }
    *page_size = sattrs.subpage || mpu_is_subpage ? 1 : TARGET_PAGE_SIZE;
    return ret;
}
Loading