summary refs log tree commit diff stats
path: root/target/arm/helper.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
...
* target/arm: Split "get pending exception info" from "acknowledge it"Peter Maydell2018-02-091-4/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently armv7m_nvic_acknowledge_irq() does three things: * make the current highest priority pending interrupt active * return a bool indicating whether that interrupt is targeting Secure or NonSecure state * implicitly tell the caller which is the highest priority pending interrupt by setting env->v7m.exception We need to split these jobs, because v7m_exception_taken() needs to know whether the pending interrupt targets Secure so it can choose to stack callee-saves registers or not, but it must not make the interrupt active until after it has done that stacking, in case the stacking causes a derived exception. Similarly, it needs to know the number of the pending interrupt so it can read the correct vector table entry before the interrupt is made active, because vector table reads might also cause a derived exception. Create a new armv7m_nvic_get_pending_irq_info() function which simply returns information about the highest priority pending interrupt, and use it to rearrange the v7m_exception_taken() code so we don't acknowledge the exception until we've done all the things which could possibly cause a derived exception. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 1517324542-6607-3-git-send-email-peter.maydell@linaro.org
* target/arm: Simplify fp_exception_el for user-onlyRichard Henderson2018-01-251-1/+2
| | | | | | | | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20180119045438.28582-16-richard.henderson@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
* target/arm: Hoist store to flags output in cpu_get_tb_cpu_stateRichard Henderson2018-01-251-16/+19
| | | | | | | | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20180119045438.28582-15-richard.henderson@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
* target/arm: Move cpu_get_tb_cpu_state out of lineRichard Henderson2018-01-251-0/+126
| | | | | | | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20180119045438.28582-14-richard.henderson@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
* target/arm: Add aa{32, 64}_vfp_{dreg, qreg} helpersRichard Henderson2018-01-251-12/+20
| | | | | | | | | | Helpers that return a pointer into env->vfp.regs so that we isolate the logic of how to index the regs array for different cpu modes. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20180119045438.28582-7-richard.henderson@linaro.org Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
* target/arm: Change the type of vfp.regsRichard Henderson2018-01-251-10/+10
| | | | | | | | | | All direct users of this field want an integral value. Drop all of the extra casting between uint64_t and float64. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20180119045438.28582-6-richard.henderson@linaro.org Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
* target/arm: Fix 32-bit address truncationArd Biesheuvel2018-01-251-1/+1
| | | | | | | | | | | | | | | | Commit ("3b39d734141a target/arm: Handle page table walk load failures correctly") modified both versions of the page table walking code (i.e., arm_ldl_ptw and arm_ldq_ptw) to record the result of the translation in a temporary 'data' variable so that it can be inspected before being returned. However, arm_ldq_ptw() returns an uint64_t, and using a temporary uint32_t variable truncates the upper bits, corrupting the result. This causes problems when using more than 4 GB of memory in a TCG guest. So use a uint64_t instead. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Message-id: 20180119194648.25501-1-ard.biesheuvel@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
* target/arm: Handle page table walk load failures correctlyPeter Maydell2018-01-161-5/+34
| | | | | | | | | | | | | | Instead of ignoring the response from address_space_ld*() (indicating an attempt to read a page table descriptor from an invalid physical address), use it to report the failure correctly. Since this is another couple of locations where we need to decide the value of the ARMMMUFaultInfo ea bit based on a MemTxResult, we factor out that operation into a helper function. Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
* get_phys_addr_pmsav7: Support AP=0b111 for v7MPeter Maydell2018-01-161-0/+14
| | | | | | | | | | | | | | For PMSAv7, the v7A/R Arm ARM defines that setting AP to 0b111 is an UNPREDICTABLE reserved combination. However, for v7M this value is documented as having the same behaviour as 0b110: read-only for both privileged and unprivileged. Accept this value on an M profile core rather than treating it as a guest error and a no-access page. Reported-by: Andy Gross <andy.gross@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 1512742402-31669-1-git-send-email-peter.maydell@linaro.org
* target/arm: Extend PAR format determinationEdgar E. Iglesias2017-12-131-4/+29
| | | | | | | | | | | | | | | | | | | Now that do_ats_write() is entirely in control of whether to generate a 32-bit PAR or a 64-bit PAR, we can make it use the correct (complicated) condition for doing so. Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Tested-by: Stefano Stabellini <sstabellini@kernel.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 1512503192-2239-13-git-send-email-peter.maydell@linaro.org [PMM: Rebased Edgar's patch on top of get_phys_addr() refactoring; use arm_s1_regime_using_lpae_format() rather than regime_using_lpae_format() because the latter will assert if passed ARMMMUIdx_S12NSE0 or ARMMMUIdx_S12NSE1; updated commit message appropriately] Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
* target/arm: Remove fsr argument from get_phys_addr() and arm_tlb_fill()Peter Maydell2017-12-131-31/+14
| | | | | | | | | | | | All of the callers of get_phys_addr() and arm_tlb_fill() now ignore the FSR values they return, so we can just remove the argument entirely. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Tested-by: Stefano Stabellini <sstabellini@kernel.org> Message-id: 1512503192-2239-12-git-send-email-peter.maydell@linaro.org
* target/arm: Ignore fsr from get_phys_addr() in do_ats_write()Peter Maydell2017-12-131-6/+10
| | | | | | | | | | | | | | | | | In do_ats_write(), rather than using the FSR value from get_phys_addr(), construct the PAR values using the information in the ARMMMUFaultInfo struct. This allows us to create a PAR of the correct format regardless of what the translation table format is. For the moment we leave the condition for "when should this be a 64 bit PAR" as it was previously; this will need to be fixed to properly support AArch32 Hyp mode. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Tested-by: Stefano Stabellini <sstabellini@kernel.org> Message-id: 1512503192-2239-11-git-send-email-peter.maydell@linaro.org
* target/arm: Convert get_phys_addr_pmsav8() to not return FSC valuesPeter Maydell2017-12-131-11/+18
| | | | | | | | | | | Make get_phys_addr_pmsav8() return a fault type in the ARMMMUFaultInfo structure, which we convert to the FSC at the callsite. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Tested-by: Stefano Stabellini <sstabellini@kernel.org> Message-id: 1512503192-2239-9-git-send-email-peter.maydell@linaro.org
* target/arm: Convert get_phys_addr_pmsav7() to not return FSC valuesPeter Maydell2017-12-131-4/+7
| | | | | | | | | | | Make get_phys_addr_pmsav7() return a fault type in the ARMMMUFaultInfo structure, which we convert to the FSC at the callsite. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Tested-by: Stefano Stabellini <sstabellini@kernel.org> Message-id: 1512503192-2239-8-git-send-email-peter.maydell@linaro.org
* target/arm: Convert get_phys_addr_pmsav5() to not return FSC valuesPeter Maydell2017-12-131-7/+13
| | | | | | | | | | | | | | | | | Make get_phys_addr_pmsav5() return a fault type in the ARMMMUFaultInfo structure, which we convert to the FSC at the callsite. Note that PMSAv5 does not define any guest-visible fault status register, so the different "fsr" values we were previously returning are entirely arbitrary. So we can just switch to using the most appropriae fi->type values without worrying that we need to special-case FaultInfo->FSC conversion for PMSAv5. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Tested-by: Stefano Stabellini <sstabellini@kernel.org> Message-id: 1512503192-2239-7-git-send-email-peter.maydell@linaro.org
* target/arm: Convert get_phys_addr_lpae() to not return FSC valuesPeter Maydell2017-12-131-23/+18
| | | | | | | | | | | Make get_phys_addr_v6() return a fault type in the ARMMMUFaultInfo structure, which we convert to the FSC at the callsite. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Tested-by: Stefano Stabellini <sstabellini@kernel.org> Message-id: 1512503192-2239-6-git-send-email-peter.maydell@linaro.org
* target/arm: Convert get_phys_addr_v6() to not return FSC valuesPeter Maydell2017-12-131-18/+22
| | | | | | | | | | | Make get_phys_addr_v6() return a fault type in the ARMMMUFaultInfo structure, which we convert to the FSC at the callsite. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Tested-by: Stefano Stabellini <sstabellini@kernel.org> Message-id: 1512503192-2239-5-git-send-email-peter.maydell@linaro.org
* target/arm: Convert get_phys_addr_v5() to not return FSC valuesPeter Maydell2017-12-131-15/+18
| | | | | | | | | | | Make get_phys_addr_v5() return a fault type in the ARMMMUFaultInfo structure, which we convert to the FSC at the callsite. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Tested-by: Stefano Stabellini <sstabellini@kernel.org> Message-id: 1512503192-2239-4-git-send-email-peter.maydell@linaro.org
* target/arm: Remove fsr argument from arm_ld*_ptw()Peter Maydell2017-12-131-13/+11
| | | | | | | | | | | | | | | | All the callers of arm_ldq_ptw() and arm_ldl_ptw() ignore the value that those functions store in the fsr argument on failure: if they return failure to their callers they will always overwrite the fsr value with something else. Remove the argument from these functions and S1_ptw_translate(). This will simplify removing fsr from the calling functions. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Tested-by: Stefano Stabellini <sstabellini@kernel.org> Message-id: 1512503192-2239-3-git-send-email-peter.maydell@linaro.org
* target/arm: Implement TT instructionPeter Maydell2017-12-131-0/+108
| | | | | | | | | Implement the TT instruction which queries the security state and access permissions of a memory location. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1512153879-5291-8-git-send-email-peter.maydell@linaro.org
* target/arm: Factor MPU lookup code out of get_phys_addr_pmsav8()Peter Maydell2017-12-131-51/+79
| | | | | | | | | | | | | | | | | | For the TT instruction we're going to need to do an MPU lookup that also tells us which MPU region the access hit. This requires us to do the MPU lookup without first doing the SAU security access check, so pull the MPU lookup parts of get_phys_addr_pmsav8() out into their own function. The TT instruction also needs to know the MPU region number which the lookup hit, so provide this information to the caller of the MPU lookup code, even though get_phys_addr_pmsav8() doesn't need to know it. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1512153879-5291-7-git-send-email-peter.maydell@linaro.org Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
* target/arm: Split M profile MNegPri mmu index into user and privPeter Maydell2017-12-131-4/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | For M profile, we currently have an mmu index MNegPri for "requested execution priority negative". This fails to distinguish "requested execution priority negative, privileged" from "requested execution priority negative, usermode", but the two can return different results for MPU lookups. Fix this by splitting MNegPri into MNegPriPriv and MNegPriUser, and similarly for the Secure equivalent MSNegPri. This takes us from 6 M profile MMU modes to 8, which means we need to bump NB_MMU_MODES; this is OK since the point where we are forced to reduce TLB sizes is 9 MMU modes. (It would in theory be possible to stick with 6 MMU indexes: {mpu-disabled,user,privileged} x {secure,nonsecure} since in the MPU-disabled case the result of an MPU lookup is always the same for both user and privileged code. However we would then need to rework the TB flags handling to put user/priv into the TB flags separately from the mmuidx. Adding an extra couple of mmu indexes is simpler.) Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1512153879-5291-5-git-send-email-peter.maydell@linaro.org
* target/arm: Add missing M profile case to regime_is_user()Peter Maydell2017-12-131-0/+1
| | | | | | | | | | | | When we added the ARMMMUIdx_MSUser MMU index we forgot to add it to the case statement in regime_is_user(), so we weren't treating it as unprivileged when doing MPU lookups. Correct the omission. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1512153879-5291-4-git-send-email-peter.maydell@linaro.org Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
* target/arm: Allow explicit writes to CONTROL.SPSEL in Handler modePeter Maydell2017-12-131-1/+4
| | | | | | | | | | | | | | | | In ARMv7M the CPU ignores explicit writes to CONTROL.SPSEL in Handler mode. In v8M the behaviour is slightly different: writes to the bit are permitted but will have no effect. We've already done the hard work to handle the value in CONTROL.SPSEL being out of sync with what stack pointer is actually in use, so all we need to do to fix this last loose end is to update the condition we use to guard whether we call write_v7m_control_spsel() on the register write. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1512153879-5291-3-git-send-email-peter.maydell@linaro.org
* target/arm: Handle SPSEL and current stack being out of sync in MSP/PSP readsPeter Maydell2017-12-131-6/+4
| | | | | | | | | | | | | For v8M it is possible for the CONTROL.SPSEL bit value and the current stack to be out of sync. This means we need to update the checks used in reads and writes of the PSP and MSP special registers to use v7m_using_psp() rather than directly checking the SPSEL bit in the control register. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1512153879-5291-2-git-send-email-peter.maydell@linaro.org Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
* arm: check regime, not current state, for ATS write PAR formatPeter Maydell2017-11-201-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | In do_ats_write(), rather than using extended_addresses_enabled() to decide whether the value we get back from get_phys_addr() is a 64-bit format PAR or a 32-bit one, use arm_s1_regime_using_lpae_format(). This is not really the correct answer, because the PAR format depends on the AT instruction being used, not just on the translation regime. However getting this correct requires a significant refactoring, so that get_phys_addr() returns raw information about the fault which the caller can then assemble into a suitable FSR/PAR/syndrome for its purposes, rather than get_phys_addr() returning a pre-formatted FSR. However this change at least improves the situation by making the PAR work correctly for address translation operations done at AArch64 EL2 on the EL2 translation regime. In particular, this is necessary for Xen to be able to run in our emulation, so this seems like a safer interim fix given that we are in freeze. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Tested-by: Stefano Stabellini <sstabellini@kernel.org> Message-id: 1509719814-6191-1-git-send-email-peter.maydell@linaro.org
* target/arm: Report GICv3 sysregs present in ID registers if neededPeter Maydell2017-11-201-4/+40
| | | | | | | | | | | | | | | | | | | | | | The CPU ID registers ID_AA64PFR0_EL1, ID_PFR1_EL1 and ID_PFR1 have a field for reporting presence of GICv3 system registers. We need to report this field correctly in order for Xen to work as a guest inside QEMU emulation. We mustn't incorrectly claim the sysregs exist when they don't, though, or Linux will crash. Unfortunately the way we've designed the GICv3 emulation in QEMU puts the system registers as part of the GICv3 device, which may be created after the CPU proper has been realized. This means that we don't know at the point when we define the ID registers what the correct value is. Handle this by switching them to calling a function at runtime to read the value, where we can fill in the GIC field appropriately. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Tested-by: Stefano Stabellini <sstabellini@kernel.org> Message-id: 1510066898-3725-1-git-send-email-peter.maydell@linaro.org
* arm: implement cache/shareability attribute bits for PAR registersAndrew Baumann2017-11-071-14/+164
| | | | | | | | | | | | | | | | | | On a successful address translation instruction, PAR is supposed to contain cacheability and shareability attributes determined by the translation. We previously returned 0 for these bits (in line with the general strategy of ignoring caches and memory attributes), but some guest OSes may depend on them. This patch collects the attribute bits in the page-table walk, and updates PAR with the correct attributes for all LPAE translations. Short descriptor formats still return 0 for these bits, as in the prior implementation. Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com> Message-id: 20171031223830.4608-1-Andrew.Baumann@microsoft.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
* target/arm: Implement secure function returnPeter Maydell2017-10-121-8/+107
| | | | | | | | | | | | | | | | | Secure function return happens when a non-secure function has been called using BLXNS and so has a particular magic LR value (either 0xfefffffe or 0xfeffffff). The function return via BX behaves specially when the new PC value is this magic value, in the same way that exception returns are handled. Adjust our BX excret guards so that they recognize the function return magic number as well, and perform the function-return unstacking in do_v7m_exception_exit(). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Acked-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1507556919-24992-5-git-send-email-peter.maydell@linaro.org
* target/arm: Implement BLXNSPeter Maydell2017-10-121-0/+59
| | | | | | | | | Implement the BLXNS instruction, which allows secure code to call non-secure code. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1507556919-24992-4-git-send-email-peter.maydell@linaro.org
* target/arm: Implement SG instructionPeter Maydell2017-10-121-5/+127
| | | | | | | | | Implement the SG instruction, which we emulate 'by hand' in the exception handling code path. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1507556919-24992-3-git-send-email-peter.maydell@linaro.org
* target/arm: Implement security attribute lookups for memory accessesPeter Maydell2017-10-061-2/+180
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Implement the security attribute lookups for memory accesses in the get_phys_addr() functions, causing these to generate various kinds of SecureFault for bad accesses. The major subtlety in this code relates to handling of the case when the security attributes the SAU assigns to the address don't match the current security state of the CPU. In the ARM ARM pseudocode for validating instruction accesses, the security attributes of the address determine whether the Secure or NonSecure MPU state is used. At face value, handling this would require us to encode the relevant bits of state into mmu_idx for both S and NS at once, which would result in our needing 16 mmu indexes. Fortunately we don't actually need to do this because a mismatch between address attributes and CPU state means either: * some kind of fault (usually a SecureFault, but in theory perhaps a UserFault for unaligned access to Device memory) * execution of the SG instruction in NS state from a Secure & NonSecure code region The purpose of SG is simply to flip the CPU into Secure state, so we can handle it by emulating execution of that instruction directly in arm_v7m_cpu_do_interrupt(), which means we can treat all the mismatch cases as "throw an exception" and we don't need to encode the state of the other MPU bank into our mmu_idx values. This commit doesn't include the actual emulation of SG; it also doesn't include implementation of the IDAU, which is a per-board way to specify hard-coded memory attributes for addresses, which override the CPU-internal SAU if they specify a more secure setting than the SAU is programmed to. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1506092407-26985-15-git-send-email-peter.maydell@linaro.org
* target/arm: Add v8M support to exception entry codePeter Maydell2017-10-061-20/+145
| | | | | | | | | | | | | | | Add support for v8M and in particular the security extension to the exception entry code. This requires changes to: * calculation of the exception-return magic LR value * push the callee-saves registers in certain cases * clear registers when taking non-secure exceptions to avoid leaking information from the interrupted secure code * switch to the correct security state on entry * use the vector table for the security state we're targeting Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1506092407-26985-13-git-send-email-peter.maydell@linaro.org
* target/arm: Add support for restoring v8M additional state contextPeter Maydell2017-10-061-0/+30
| | | | | | | | | | | For v8M, exceptions from Secure to Non-Secure state will save callee-saved registers to the exception frame as well as the caller-saved registers. Add support for unstacking these registers in exception exit when necessary. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1506092407-26985-12-git-send-email-peter.maydell@linaro.org
* target/arm: Update excret sanity checks for v8MPeter Maydell2017-10-061-15/+58
| | | | | | | | | | In v8M, more bits are defined in the exception-return magic values; update the code that checks these so we accept the v8M values when the CPU permits them. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1506092407-26985-11-git-send-email-peter.maydell@linaro.org
* target/arm: Don't warn about exception return with PC low bit set for v8MPeter Maydell2017-10-061-7/+15
| | | | | | | | | | | In the v8M architecture, return from an exception to a PC which has bit 0 set is not UNPREDICTABLE; it is defined that bit 0 is discarded [R_HRJH]. Restrict our complaint about this to v7M. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1506092407-26985-9-git-send-email-peter.maydell@linaro.org
* target/arm: Warn about restoring to unaligned stackPeter Maydell2017-10-061-0/+7
| | | | | | | | | | | | | Attempting to do an exception return with an exception frame that is not 8-aligned is UNPREDICTABLE in v8M; warn about this. (It is not UNPREDICTABLE in v7M, and our implementation can handle the merely-4-aligned case fine, so we don't need to do anything except warn.) Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1506092407-26985-8-git-send-email-peter.maydell@linaro.org
* target/arm: Check for xPSR mismatch usage faults earlier for v8MPeter Maydell2017-10-061-3/+27
| | | | | | | | | | | | | | | | | | | ARM v8M specifies that the INVPC usage fault for mismatched xPSR exception field and handler mode bit should be checked before updating the PSR and SP, so that the fault is taken with the existing stack frame rather than by pushing a new one. Perform this check in the right place for v8M. Since v7M specifies in its pseudocode that this usage fault check should happen later, we have to retain the original code for that check rather than being able to merge the two. (The distinction is architecturally visible but only in very obscure corner cases like attempting an invalid exception return with an exception frame in read only memory.) Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1506092407-26985-7-git-send-email-peter.maydell@linaro.org
* target/arm: Restore SPSEL to correct CONTROL register on exception returnPeter Maydell2017-10-061-13/+27
| | | | | | | | | | | | | | | On exception return for v8M, the SPSEL bit in the EXC_RETURN magic value should be restored to the SPSEL bit in the CONTROL register banked specified by the EXC_RETURN.ES bit. Add write_v7m_control_spsel_for_secstate() which behaves like write_v7m_control_spsel() but allows the caller to specify which CONTROL bank to use, reimplement write_v7m_control_spsel() in terms of it, and use it in exception return. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1506092407-26985-6-git-send-email-peter.maydell@linaro.org
* target/arm: Restore security state on exception returnPeter Maydell2017-10-061-0/+2
| | | | | | | | | | | | | Now that we can handle the CONTROL.SPSEL bit not necessarily being in sync with the current stack pointer, we can restore the correct security state on exception return. This happens before we start to read registers off the stack frame, but after we have taken possible usage faults for bad exception return magic values and updated CONTROL.SPSEL. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1506092407-26985-5-git-send-email-peter.maydell@linaro.org
* target/arm: Prepare for CONTROL.SPSEL being nonzero in Handler modePeter Maydell2017-10-061-22/+43
| | | | | | | | | | | | | | | | | | | | | | | | In the v7M architecture, there is an invariant that if the CPU is in Handler mode then the CONTROL.SPSEL bit cannot be nonzero. This in turn means that the current stack pointer is always indicated by CONTROL.SPSEL, even though Handler mode always uses the Main stack pointer. In v8M, this invariant is removed, and CONTROL.SPSEL may now be nonzero in Handler mode (though Handler mode still always uses the Main stack pointer). In preparation for this change, change how we handle this bit: rename switch_v7m_sp() to the now more accurate write_v7m_control_spsel(), and make it check both the handler mode state and the SPSEL bit. Note that this implicitly changes the point at which we switch active SP on exception exit from before we pop the exception frame to after it. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1506092407-26985-4-git-send-email-peter.maydell@linaro.org
* target/arm: Don't switch to target stack early in v7M exception returnPeter Maydell2017-10-061-32/+98
| | | | | | | | | | | | | | | | | | | | | | | Currently our M profile exception return code switches to the target stack pointer relatively early in the process, before it tries to pop the exception frame off the stack. This is awkward for v8M for two reasons: * in v8M the process vs main stack pointer is not selected purely by the value of CONTROL.SPSEL, so updating SPSEL and relying on that to switch to the right stack pointer won't work * the stack we should be reading the stack frame from and the stack we will eventually switch to might not be the same if the guest is doing strange things Change our exception return code to use a 'frame pointer' to read the exception frame rather than assuming that we can switch the live stack pointer this early. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1506092407-26985-3-git-send-email-peter.maydell@linaro.org
* arm: Fix SMC reporting to EL2 when QEMU provides PSCIJan Kiszka2017-10-061-1/+8
| | | | | | | | | | | | | This properly forwards SMC events to EL2 when PSCI is provided by QEMU itself and, thus, ARM_FEATURE_EL3 is off. Found and tested with the Jailhouse hypervisor. Solution based on suggestions by Peter Maydell. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Message-id: 4f243068-aaea-776f-d18f-f9e05e7be9cd@siemens.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
* nvic: Support banked exceptions in acknowledge and completePeter Maydell2017-09-211-3/+5
| | | | | | | | | | | | | | | Update armv7m_nvic_acknowledge_irq() and armv7m_nvic_complete_irq() to handle banked exceptions: * acknowledge needs to use the correct vector, which may be in sec_vectors[] * acknowledge needs to return to its caller whether the exception should be taken to secure or non-secure state * complete needs its caller to tell it whether the exception being completed is a secure one or not Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1505240046-11454-20-git-send-email-peter.maydell@linaro.org
* nvic: Make set_pending and clear_pending take a secure parameterPeter Maydell2017-09-211-10/+14
| | | | | | | | | | | | | | | Make the armv7m_nvic_set_pending() and armv7m_nvic_clear_pending() functions take a bool indicating whether to pend the secure or non-secure version of a banked interrupt, and update the callsites accordingly. In most callsites we can simply pass the correct security state in; in a couple of cases we use TODO comments to indicate that we will return the code in a subsequent commit. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1505240046-11454-10-git-send-email-peter.maydell@linaro.org
* target/arm: Implement MSR/MRS access to NS banked registersPeter Maydell2017-09-211-0/+110
| | | | | | | | | | | | | In v8M the MSR and MRS instructions have extra register value encodings to allow secure code to access the non-secure banked version of various special registers. (We don't implement the MSPLIM_NS or PSPLIM_NS aliases, because we don't currently implement the stack limit registers at all.) Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1505240046-11454-2-git-send-email-peter.maydell@linaro.org
* target/arm: Rename 'type' to 'excret' in do_v7m_exception_exit()Peter Maydell2017-09-141-11/+12
| | | | | | | | | | | | | | In the v7M and v8M ARM ARM, the magic exception return values are referred to as EXC_RETURN values, and in QEMU we use V7M_EXCRET_* constants to define bits within them. Rename the 'type' variable which holds the exception return value in do_v7m_exception_exit() to excret, making it clearer that it does hold an EXC_RETURN value. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Alistair Francis <alistair.francis@xilinx.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1505137930-13255-8-git-send-email-peter.maydell@linaro.org
* target/arm: Add and use defines for EXCRET constantsPeter Maydell2017-09-141-5/+9
| | | | | | | | | | | | | | The exception-return magic values get some new bits in v8M, which makes some bit definitions for them worthwhile. We don't use the bit definitions for the switch on the low bits which checks the return type for v7M, because this is defined in the v7M ARM ARM as a set of valid values rather than via per-bit checks. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alistair Francis <alistair.francis@xilinx.com> Message-id: 1505137930-13255-7-git-send-email-peter.maydell@linaro.org
* target/arm: Remove unnecessary '| 0xf0000000' from do_v7m_exception_exit()Peter Maydell2017-09-141-2/+2
| | | | | | | | | | | | | In do_v7m_exception_exit(), there's no need to force the high 4 bits of 'type' to 1 when calling v7m_exception_taken(), because we know that they're always 1 or we could not have got to this "handle return to magic exception return address" code. Remove the unnecessary ORs. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Acked-by: Alistair Francis <alistair.francis@xilinx.com> Message-id: 1505137930-13255-6-git-send-email-peter.maydell@linaro.org
* target/arm: Get PRECISERR and IBUSERR the right way roundPeter Maydell2017-09-141-4/+4
| | | | | | | | | | | For a bus fault, the M profile BFSR bit PRECISERR means a bus fault on a data access, and IBUSERR means a bus fault on an instruction access. We had these the wrong way around; fix this. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alistair Francis <alistair.francis@xilinx.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1505137930-13255-4-git-send-email-peter.maydell@linaro.org