Commit graph

234 commits

Author SHA1 Message Date
Peter Maydell 2c4578f46e
target/arm: Implement SG instruction
Implement the SG instruction, which we emulate 'by hand' in the
exception handling code path.

Backports commit 333e10c51ef5876ced26f77b61b69ce0f83161a9 from qemu
2018-03-05 03:28:28 -05:00
Peter Maydell 19ecd4f732
target/arm: Add M profile secure MMU index values to get_a32_user_mem_index()
Add the M profile secure MMU index values to the switch in
get_a32_user_mem_index() so that LDRT/STRT work correctly
rather than asserting at translate time.

Backports commit b9f587d62cebed427206539750ebf59bde4df422 from qemu
2018-03-05 03:25:54 -05:00
Emilio G. Cota 5fae6dd433
tcg: remove addr argument from lookup_tb_ptr
It is unlikely that we will ever want to call this helper passing
an argument other than the current PC. So just remove the argument,
and use the pc we already get from cpu_get_tb_cpu_state.

This change paves the way to having a common "tb_lookup" function.

Backports commit 7f11636dbee89b0e4d03e9e2b96e14649a7db778 from qemu
2018-03-05 02:16:34 -05:00
Peter Maydell 059f238f11
target/arm: Factor out "get mmuidx for specified security state"
For the SG instruction and secure function return we are going
to want to do memory accesses using the MMU index of the CPU
in secure state, even though the CPU is currently in non-secure
state. Write arm_v7m_mmu_idx_for_secstate() to do this job,
and use it in cpu_mmu_index().

Backports commit b81ac0eb6315e602b18439961e0538538e4aed4f from qemu
2018-03-05 02:00:23 -05:00
Peter Maydell 6958a4763d
target/arm: Fix calculation of secure mm_idx values
In cpu_mmu_index() we try to do this:
if (env->v7m.secure) {
mmu_idx += ARMMMUIdx_MSUser;
}
but it will give the wrong answer, because ARMMMUIdx_MSUser
includes the 0x40 ARM_MMU_IDX_M field, and so does the
mmu_idx we're adding to, and we'll end up with 0x8n rather
than 0x4n. This error is then nullified by the call to
arm_to_core_mmu_idx() which masks out the high part, but
we're about to factor out the code that calculates the
ARMMMUIdx values so it can be used without passing it through
arm_to_core_mmu_idx(), so fix this bug first.

Backports commit fe768788d29597ee56fc11ba2279d502c2617457 from qemu
2018-03-05 01:58:42 -05:00
Peter Maydell 7988aec017
target/arm: Implement security attribute lookups for memory accesses
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.

Backports commit 35337cc391245f251bfb9134f181c33e6375d6c1 from qemu
2018-03-05 01:57:07 -05:00
Peter Maydell f9b4381ce0
nvic: Implement Security Attribution Unit registers
Implement the register interface for the SAU: SAU_CTRL,
SAU_TYPE, SAU_RNR, SAU_RBAR and SAU_RLAR. None of the
actual behaviour is implemented here; registers just
read back as written.

When the CPU definition for Cortex-M33 is eventually
added, its initfn will set cpu->sau_sregion, in the same
way that we currently set cpu->pmsav7_dregion for the
M3 and M4.

Number of SAU regions is typically a configurable
CPU parameter, but this patch doesn't provide a
QEMU CPU property for it. We can easily add one when
we have a board that requires it.

Backports commit 9901c576f6c02d43206e5faaf6e362ab7ea83246 from qemu
2018-03-05 01:55:11 -05:00
Peter Maydell 3da3a3fb41
target/arm: Add v8M support to exception entry code
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

Backports commit d3392718e1fcf0859fb7c0774a8e946bacb8419c from qemu
2018-03-05 01:51:22 -05:00
Peter Maydell 39466771d6
target/arm: Add support for restoring v8M additional state context
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.

Backports commit 907bedb3f3ce134c149599bd9cb61856d811b8ca from qemu
2018-03-05 01:47:25 -05:00
Peter Maydell 2feecbac0d
target/arm: Update excret sanity checks for v8M
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.

Backports commit bfb2eb52788b9605ef2fc9bc72683d4299117fde from qemu
2018-03-05 01:44:33 -05:00
Peter Maydell 33d2358c91
target/arm: Add new-in-v8M SFSR and SFAR
Add the new M profile Secure Fault Status Register
and Secure Fault Address Register.

Backports commit bed079da04dd9e0e249b9bc22bca8dce58b67f40 from qemu
2018-03-05 01:42:52 -05:00
Peter Maydell 7af730ed3e
target/arm: Don't warn about exception return with PC low bit set for v8M
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.

Backports commit 4e4259d3c574a8e89c3af27bcb84bc19a442efb1 from qemu
2018-03-05 01:41:51 -05:00
Peter Maydell 2aea283c4f
target/arm: Warn about restoring to unaligned stack
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.)

Backports commit cb484f9a6e790205e69d9a444c3e353a3a1cfd84 from qemu
2018-03-05 01:40:40 -05:00
Peter Maydell 5063ca11ab
target/arm: Check for xPSR mismatch usage faults earlier for v8M
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.)

Backports commit 224e0c300a0098fb577a03bd29d774d0769f632a from qemu
2018-03-05 01:39:39 -05:00
Peter Maydell 6f08acdcfe
target/arm: Restore SPSEL to correct CONTROL register on exception return
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.

Backports commit 3f0cddeee1f266d43c956581f3050058360a810d from qemu
2018-03-05 01:35:17 -05:00
Peter Maydell 0bb50b9a7e
target/arm: Restore security state on exception return
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.

Backports commit 3919e60b6efd9a86a0e6ba637aa584222855ac3a from qemu
2018-03-05 01:31:58 -05:00
Peter Maydell c7b5fccfb8
target/arm: Prepare for CONTROL.SPSEL being nonzero in Handler mode
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.

Backports commit de2db7ec894f11931932ca78cd14a8d2b1389d5b from qemu
2018-03-05 01:29:54 -05:00
Peter Maydell 8036c5b3de
target/arm: Don't switch to target stack early in v7M exception return
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.

Backports commit 5b5223997c04b769bb362767cecb5f7ec382c5f0 from qemu
2018-03-05 01:26:05 -05:00
Jan Kiszka ae16a26c20
arm: Fix SMC reporting to EL2 when QEMU provides PSCI
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.

Backports commit 77077a83006c3c9bdca496727f1735a3c5c5355d from qemu
2018-03-05 01:19:22 -05:00
Peter Maydell f0569ba11a
target/arm: Remove out of date ARM ARM section references in A64 decoder
In the A64 decoder, we have a lot of references to section numbers
from version A.a of the v8A ARM ARM (DDI0487). This version of the
document is now long obsolete (we are currently on revision B.a),
and various intervening versions renumbered all the sections.

The most recent B.a version of the document doesn't assign
section numbers at all to the individual instruction classes
in the way that the various A.x versions did. The simplest thing
to do is just to delete all the out of date C.x.x references.

Backports commit 4ce31af4aeb8471f6a913de7c59d3bde1fc4f03d from qemu
2018-03-05 01:05:53 -05:00
Peter Maydell 72dadc6518
target/arm: Handle banking in negative-execution-priority check in cpu_mmu_index()
Now that we have a banked FAULTMASK register and banked exceptions,
we can implement the correct check in cpu_mmu_index() for whether
the MPU_CTRL.HFNMIENA bit's effect should apply. This bit causes
handlers which have requested a negative execution priority to run
with the MPU disabled. In v8M the test has to check this for the
current security state and so takes account of banking.

Backports relevant part of commit 5d4791991d4de12e83d44738417c9e964167b6e8 from qemu
2018-03-05 00:54:28 -05:00
Peter Maydell 4b8bdda695
target/arm: Implement MSR/MRS access to NS banked registers
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.)

Backports commit 50f11062d4c896408731d6a286bcd116d1e08465 from qemu
2018-03-05 00:53:13 -05:00
Igor Mammedov 607bc396c3
arm: drop intermediate cpu_model -> cpu type parsing and use cpu type directly
Backports defines from commit ba1ba5cca3962a9cc400c713c736b4fb8db1f38e from qemu
2018-03-05 00:10:21 -05:00
Richard Henderson c5e952978c
target/arm: Avoid an extra temporary for store_exclusive
Instead of copying addr to a local temp, reuse the value (which we
have just compared as equal) already saved in cpu_exclusive_addr.

Backports commit 37e29a64254bf82a1901784fcca17c25f8164c2f from qemu
2018-03-04 23:17:50 -05:00
Jaroslaw Pelczar 7fded6c15c
AArch64: Fix single stepping of ERET instruction
Previously when single stepping through ERET instruction via GDB
would result in debugger entering the "next" PC after ERET instruction.
When debugging in kernel mode, this will also cause unintended behavior,
because debugger will try to access memory from EL0 point of view.

Backports commit dddbba9943ef6a81c8702e4a50cb0a8b1a4201fe from qemu
2018-03-04 23:15:30 -05:00
Peter Maydell 6a951f17ed
target/arm: Rename 'type' to 'excret' in do_v7m_exception_exit()
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.

Backports commit 351e527a613147aa2a2e6910f92923deef27ee48 from qemu
2018-03-04 23:14:22 -05:00
Peter Maydell 1301cb1771
target/arm: Add and use defines for EXCRET constants
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.

Backports commit 4d1e7a4745c050f7ccac49a1c01437526b5130b5 from qemu
2018-03-04 23:12:37 -05:00
Peter Maydell aa71933721
target/arm: Remove unnecessary '| 0xf0000000' from do_v7m_exception_exit()
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.

Backports commit 7115cdf5782922611bcc44c89eec5990db7f6466 from qemu
2018-03-04 23:11:13 -05:00
Peter Maydell 2718aa8233
target/arm: Get PRECISERR and IBUSERR the right way round
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.

Backports commit c6158878650c01b2c753b2ea7d0967c8fe5ca59e from qemu
2018-03-04 23:10:33 -05:00
Peter Maydell ceccd92940
target/arm: Clear exclusive monitor on v7M reset, exception entry/exit
For M profile we must clear the exclusive monitor on reset, exception
entry and exception exit. We weren't doing any of these things; fix
this bug.

Backports commit dc3c4c14f0f12854dbd967be3486f4db4e66d25b from qemu
2018-03-04 23:09:41 -05:00
Peter Maydell 2a9b62c12b
target/arm: Clear exclusive monitor on v7M reset, exception entry/exit
For M profile we must clear the exclusive monitor on reset, exception
entry and exception exit. We weren't doing any of these things; fix
this bug.

Backports commit dc3c4c14f0f12854dbd967be3486f4db4e66d25b from qemu
2018-03-04 23:08:31 -05:00
Peter Maydell 09ca9356a3
target/arm: Use M_REG_NUM_BANKS rather than hardcoding 2
Use a symbolic constant M_REG_NUM_BANKS for the array size for
registers which are banked by M profile security state, rather
than hardcoding lots of 2s.

Backports commit 4a16724f06ead684a5962477a557c26c677c2729 from qemu
2018-03-04 23:07:30 -05:00
Peter Maydell 8d02ee3b51
target/arm: Implement new do_transaction_failed hook
Implement the new do_transaction_failed hook for ARM, which should
cause the CPU to take a prefetch abort or data abort.

Backports commit c79c0a314c43b78f6326d5f137bdbafdbf8e9766 from qemu
2018-03-04 21:29:05 -05:00
Peter Maydell 2070ef1c37
boards.h: Define new flag ignore_memory_transaction_failures
Define a new MachineClass field ignore_memory_transaction_failures.
If this is flag is true then the CPU will ignore memory transaction
failures which should cause the CPU to take an exception due to an
access to an unassigned physical address; the transaction will
instead return zero (for a read) or be ignored (for a write). This
should be set only by legacy board models which rely on the old
RAZ/WI behaviour for handling devices that QEMU does not yet model.
New board models should instead use "unimplemented-device" for all
memory ranges where the guest will attempt to probe for a device that
QEMU doesn't implement and a stub device is required.

We need this for ARM boards, where we're about to implement support for
generating external aborts on memory transaction failures. Too many
of our legacy board models rely on the RAZ/WI behaviour and we
would break currently working guests when their "probe for device"
code provoked an external abort rather than a RAZ.

Backports commit ed860129acd3fcd0b1e47884e810212aaca4d21b from qemu
2018-03-04 21:27:15 -05:00
Peter Maydell 4b816fe0aa
target/arm: Implement BXNS, and banked stack pointers
Implement the BXNS v8M instruction, which is like BX but will do a
jump-and-switch-to-NonSecure if the branch target address has bit 0
clear.

This is the first piece of code which implements "switch to the
other security state", so the commit also includes the code to
switch the stack pointers around, which is the only complicated
part of switching security state.

BLXNS is more complicated than just "BXNS but set the link register",
so we leave it for a separate commit.

Backports commit fb602cb726b3ebdd01ef3b1732d74baf9fee7ec9 from qemu
2018-03-04 21:21:23 -05:00
Peter Maydell 221232fb35
target/arm: Move regime_is_secure() to target/arm/internals.h
Move the regime_is_secure() utility function to internals.h;
we are going to want to call it from translate.c.

Backports commit 61fcd69b0db268e7612b07fadc436b93def91768 from qemu
2018-03-04 21:14:05 -05:00
Peter Maydell 07b9144ef2
target/arm: Make CFSR register banked for v8M
Make the CFSR register banked if v8M security extensions are enabled.

Not all the bits in this register are banked: the BFSR
bits [15:8] are shared between S and NS, and we store them
in the NS copy of the register.

Backports commit 334e8dad7a109d15cb20b090131374ae98682a50 from qemu
2018-03-04 21:12:55 -05:00
Peter Maydell 74c66cc2a9
target/arm: Make MMFAR banked for v8M
Make the MMFAR register banked if v8M security extensions are
enabled.

Backports commit c51a5cfc9fae82099028eb12cb1d064ee07f348e from qemu
2018-03-04 21:10:47 -05:00
Peter Maydell 4b24f6d87b
target/arm: Make CCR register banked for v8M
Make the CCR register banked if v8M security extensions are enabled.

This is slightly more complicated than the other "add banking"
patches because there is one bit in the register which is not
banked. We keep the live data in the NS copy of the register,
and adjust it on register reads and writes. (Since we don't
currently implement the behaviour that the bit controls, there
is nowhere else that needs to care.)

This patch includes the enforcement of the bits which are newly
RES1 in ARMv8M.

Backports commit 9d40cd8a68cfc7606f4548cc9e812bab15c6dc28 from qemu
2018-03-04 21:09:34 -05:00
Peter Maydell f88f4b5e31
target/arm: Make MPU_CTRL register banked for v8M
Make the MPU_CTRL register banked if v8M security extensions are
enabled.

Backports commit ecf5e8eae8b0b5fa41f00b53d67747b42fd1b8b9 from qemu
2018-03-04 21:08:16 -05:00
Peter Maydell 683830d5ac
target/arm: Make MPU_RNR register banked for v8M
Make the MPU_RNR register banked if v8M security extensions are
enabled.

Backports commit 1bc04a8880374407c4b12d82ceb8752e12ff5336 from qemu
2018-03-04 21:06:01 -05:00
Peter Maydell 5e14b33c65
target/arm: Make MPU_RBAR, MPU_RLAR banked for v8M
Make the MPU registers MPU_MAIR0 and MPU_MAIR1 banked if v8M security
extensions are enabled.

We can freely add more items to vmstate_m_security without
breaking migration compatibility, because no CPU currently
has the ARM_FEATURE_M_SECURITY bit enabled and so this
subsection is not yet used by anything.

Backports commit 62c58ee0b24eafb44c06402fe059fbd7972eb409 from qemu
2018-03-04 21:04:41 -05:00
Peter Maydell 5b6e1e2150
target/arm: Make MPU_MAIR0, MPU_MAIR1 registers banked for v8M
Make the MPU registers MPU_MAIR0 and MPU_MAIR1 banked if v8M security
extensions are enabled.

Backports commit 4125e6feb71c810ca38f0d8e66e748b472a9cc54 from qemu
2018-03-04 21:02:51 -05:00
Peter Maydell 3e35eee327
target/arm: Make VTOR register banked for v8M
Make the VTOR register banked if v8M security extensions are enabled.

Backports commit 45db7ba681ede57113a67499840e69ee586bcdf2 from qemu
2018-03-04 21:01:51 -05:00
Peter Maydell 59c6845ada
target/arm: Make CONTROL register banked for v8M
Make the CONTROL register banked if v8M security extensions are enabled.

Backports commit 8bfc26ea302ec03585d7258a7cf8938f76512730 from qemu
2018-03-04 21:00:58 -05:00
Peter Maydell 14cb6925f3
target/arm: Make FAULTMASK register banked for v8M
Make the FAULTMASK register banked if v8M security extensions are enabled.

Note that we do not yet implement the functionality of the new
AIRCR.PRIS bit (which allows the effect of the NS copy of FAULTMASK to
be restricted).

This patch includes the code to determine for v8M which copy
of FAULTMASK should be updated on exception exit; further
changes will be required to the exception exit code in general
to support v8M, so this is just a small piece of that.

The v8M ARM ARM introduces a notation where individual paragraphs
are labelled with R (for rule) or I (for information) followed
by a random group of subscript letters. In comments where we want
to refer to a particular part of the manual we use this convention,
which should be more stable across document revisions than using
section or page numbers.

Backports commit 42a6686b2f6199d086a58edd7731faeb2dbe7c14 from qemu
2018-03-04 20:58:38 -05:00
Peter Maydell ff3f7811ce
target/arm: Make PRIMASK register banked for v8M
Make the PRIMASK register banked if v8M security extensions are enabled.

Note that we do not yet implement the functionality of the new
AIRCR.PRIS bit (which allows the effect of the NS copy of PRIMASK to
be restricted).

Backports commit 6d8048341995b31a77dc2e0dcaaf4e3df0e3121a from qemu
2018-03-04 20:55:49 -05:00
Peter Maydell c9a7aad4dc
target/arm: Make BASEPRI register banked for v8M
Make the BASEPRI register banked if v8M security extensions are enabled.

Note that we do not yet implement the functionality of the new
AIRCR.PRIS bit (which allows the effect of the NS copy of BASEPRI to
be restricted).

Backports commit acf949411ffb675edbfb707e235800b02e6a36f8 from qemu
2018-03-04 20:54:44 -05:00
Peter Maydell f4d155ad3a
target/arm: Add MMU indexes for secure v8M
Now that MPU lookups can return different results for v8M
when the CPU is in secure vs non-secure state, we need to
have separate MMU indexes; add the secure counterparts
to the existing three M profile MMU indexes.

Backports commit 66787c7868d05d29974e09201611b718c976f955 from qemu
2018-03-04 20:53:04 -05:00
Peter Maydell 13bad2c234
target/arm: Register second AddressSpace for secure v8M CPUs
If a v8M CPU supports the security extension then we need to
give it two AddressSpaces, the same way we do already for
an A profile core with EL3.

Backports commit 1d2091bc75ab7f9e2c43082f361a528a63c79527 from qemu
2018-03-04 20:51:00 -05:00
Peter Maydell 8ce42ad30c
target/arm: Add state field, feature bit and migration for v8M secure state
As the first step in implementing ARM v8M's security extension:
* add a new feature bit ARM_FEATURE_M_SECURITY
* add the CPU state field that indicates whether the CPU is
currently in the secure state
* add a migration subsection for this new state
(we will add the Secure copies of banked register state
to this subsection in later patches)
* add a #define for the one new-in-v8M exception type
* make the CPU debug log print S/NS status

Backports commit 1e577cc7cffd3de14dbd321de5c3ef191c6ab07f from qemu
2018-03-04 20:50:04 -05:00
Peter Maydell 829a34ec55
target/arm: Implement new PMSAv8 behaviour
Implement the behavioural side of the new PMSAv8 specification.

Backports commit 504e3cc36b68b34c176f3f4116b1d5677471ec20 from qemu
2018-03-04 20:47:54 -05:00
Peter Maydell 1acd9efdc2
target/arm: Implement ARMv8M's PMSAv8 registers
As part of ARMv8M, we need to add support for the PMSAv8 MPU
architecture.

PMSAv8 differs from PMSAv7 both in register/data layout (for instance
using base and limit registers rather than base and size) and also in
behaviour (for example it does not have subregions); rather than
trying to wedge it into the existing PMSAv7 code and data structures,
we define separate ones.

This commit adds the data structures which hold the state for a
PMSAv8 MPU and the register interface to it. The implementation of
the MPU behaviour will be added in a subsequent commit.

Backports commit 0e1a46bbd2d6c39614b87f4e88ea305acce8a35f from qemu
2018-03-04 20:45:49 -05:00
Richard Henderson 6d2bcf6ed8
target/arm: Perform per-insn cross-page check only for Thumb
ARM is a fixed-length ISA and we can compute the page crossing
condition exactly once during init_disas_context.

Backports commit d0264d86b026e9d948de577b05ff86d708658576 from qemu
2018-03-04 20:42:22 -05:00
Richard Henderson ab21785d3f
target/arm: Split out thumb_tr_translate_insn
We need not check for ARM vs Thumb state in order to dispatch
disassembly of every instruction.

Backports commit 722ef0a562a8cd810297b00516e36380e2f33353 from qemu
2018-03-04 20:41:07 -05:00
Richard Henderson 23d769c856
target/arm: Move ss check to init_disas_context
We can check for single-step just once.

Backports commit f7708456aac23a8bb8864b12bcf1f20c6e4b7045 from qemu
2018-03-04 20:34:33 -05:00
Richard Henderson dd36ec2bbf
target/arm: [a64] Move page and ss checks to init_disas_context
Since AArch64 uses a fixed-width ISA, we can pre-compute the number of
insns remaining on the page. Also, we can check for single-step once.

Backports commit dcc3a21209a8eeae0fe43966012f8e08d3566f98 from qemu
2018-03-04 20:32:45 -05:00
Lluís Vilanova 74d437827b
target/arm: [tcg] Port to generic translation framework
Backports commit 2316922420da6fd0d1ffb5557d0cdcc5958bcf44 from qemu
2018-03-04 20:28:06 -05:00
Lluís Vilanova cc00feb2df
target/arm: [tcg,a64] Port to disas_log
Incrementally paves the way towards using the generic instruction translation
loop.

Backports commit 58350fa4b2852fede96cfebad0b26bf79bca419c from qemu
2018-03-04 20:09:39 -05:00
Lluís Vilanova 5d3ff533a1
target/arm: [tcg] Port to disas_log
Incrementally paves the way towards using the generic instruction translation
loop.

Backports commit 4013f7fc811e90b89da3a516dc71b01ca0e7e54e from qemu
2018-03-04 20:05:16 -05:00
Lluís Vilanova 7a02cb360c
target/arm: [tcg,a64] Port to tb_stop
Incrementally paves the way towards using the generic instruction translation
loop.

Backports commit be4079641f1bc755fc5d3ff194cf505c506227d8 from qemu
2018-03-04 20:02:45 -05:00
Lluís Vilanova d8def0cdb5
target/arm: [tcg] Port to tb_stop
Incrementally paves the way towards using the generic instruction translation
loop.

Backports commit 70d3c035ae36a2c5c0f991ba958526127c92bb67 from qemu
2018-03-04 20:02:32 -05:00
Lluís Vilanova 665192d96f
target/arm: [tcg,a64] Port to translate_insn
Incrementally paves the way towards using the generic instruction translation
loop.

Backports commit 24299c892cbfe29120f051b6b7d0bcf3e0cc8e85 from qemu
2018-03-04 19:47:54 -05:00
Lluís Vilanova 0c4909738d
target/arm: [tcg] Port to translate_insn
Incrementally paves the way towards using the generic instruction translation
loop.

Backports commit 13189a9080b35b13af23f2be4806fa0cdbb31af3 from qemu
2018-03-04 19:44:01 -05:00
Lluís Vilanova 7b89c4c813
target/arm: [tcg,a64] Port to breakpoint_check
Incrementally paves the way towards using the generic instruction translation
loop.

Backports commit 0cb56b373da70047979b61b042f59aaff4012e1b from qemu
2018-03-04 19:34:06 -05:00
Lluís Vilanova 67e0d99080
target/arm: [tcg,a64] Port to insn_start
Incrementally paves the way towards using the generic instruction translation
loop.

Backports commit a68956ad7f8510bdc0b54793c65c62c6a94570a4 from qemu
2018-03-04 19:31:22 -05:00
Lluís Vilanova b9df4e0ca0
target/arm: [tcg] Port to insn_start
Incrementally paves the way towards using the generic instruction translation
loop.

Backports commit f62bd897e64c6fb1f93e8795e835980516fe53b5 from qemu
2018-03-04 19:25:29 -05:00
Lluís Vilanova b3878f117e
target/arm: [tcg] Port to tb_start
Incrementally paves the way towards using the generic instruction translation
loop.

Backports commit b14768544fd715a3f1742c10fc36ae81c703cbc1 from qemu
2018-03-04 19:22:20 -05:00
Lluís Vilanova 529c6c17f1
target/arm: [tcg,a64] Port to init_disas_context
Incrementally paves the way towards using the generic instruction translation
loop.

Backports commit 5c03990665aa9095e4d2734c8ca0f936a8e8f000 from qemu
2018-03-04 19:17:09 -05:00
Lluís Vilanova 5e5c722359
target/arm: [tcg] Port to init_disas_context
Incrementally paves the way towards using the generic instruction translation
loop.

Backports commit 1d8a5535238fc5976e0542a413f4ad88f5d4b233 from qemu
2018-03-04 19:10:55 -05:00
Lluís Vilanova 8581e6f6fe
target/arm: [tcg] Port to DisasContextBase
Incrementally paves the way towards using the generic
instruction translation loop.

Backports commit dcba3a8d443842f7a30a2c52d50a6b50b6982b35 from qemu
2018-03-04 19:00:06 -05:00
Paolo Bonzini 6997a5a090
gen-icount: check cflags instead of use_icount global
Backports commit cd42d5b23691ad73edfd6dbcfc935a960a9c5a65 from qemu
2018-03-04 14:26:26 -05:00
Richard Henderson cbb20881a2
target/arm: Delay check for magic kernel page
There's nothing magic about the exception that we generate in order
to execute the magic kernel page. We can and should allow gdb to
set a breakpoint at this location.

Backports commit 3805c2eba8999049bbbea29fdcdea4d47d943c88 from qemu
2018-03-04 14:09:09 -05:00
Lluís Vilanova 3a196c62ae
target: [tcg] Use a generic enum for DISAS_ values
Used later. An enum makes expected values explicit and
bounds the value space of switches.

Backports commit 77fc6f5e28667634916f114ae04c6029cd7b9c45 from qemu
2018-03-04 14:08:43 -05:00
Richard Henderson 4a5b1aec34
target/arm: Use DISAS_NORETURN
Fold DISAS_EXC and DISAS_TB_JUMP into DISAS_NORETURN.

In both cases all following code is dead. In the first
case because we have exited the TB via exception; in the
second case because we have exited the TB via goto_tb
and its associated machinery.

Backports commit a0c231e651b249960906f250b8e5eef5ed9888c4 from qemu
2018-03-04 13:57:18 -05:00
Peter Maydell b9f06be41d
target/arm: Allow deliver_fault() caller to specify EA bit
For external aborts, we will want to be able to specify the EA
(external abort type) bit in the syndrome field. Allow callers of
deliver_fault() to do that by adding a field to ARMMMUFaultInfo which
we use when constructing the syndrome values.

Backports commit c528af7aa64f159eb30b46e567b650c5440fc117 from qemu
2018-03-04 13:20:23 -05:00
Peter Maydell 320655293a
target/arm: Factor out fault delivery code
We currently have some similar code in tlb_fill() and in
arm_cpu_do_unaligned_access() for delivering a data abort or prefetch
abort. We're also going to want to do the same thing to handle
external aborts. Factor out the common code into a new function
deliver_fault().

Backports commit aac43da1d772a50778ab1252c13c08c2eb31fb39 from qemu
2018-03-04 13:18:31 -05:00
Peter Maydell 06619904c6
target/arm: Create and use new function arm_v7m_is_handler_mode()
Add a utility function for testing whether the CPU is in Handler
mode; this is just a check whether v7m.exception is non-zero, but
we do it in several places and it makes the code a bit easier
to read to not have to mentally figure out what the test is testing.

Backports commit 15b3f556bab4f961bf92141eb8521c8da3df5eb2 from qemu
2018-03-04 13:06:45 -05:00
Peter Maydell a897ee919b
target-arm: v7M: ignore writes to CONTROL.SPSEL from Thread mode
For v7M, writes to the CONTROL register are only permitted for
privileged code. However even if the code is privileged, the
write must not affect the SPSEL bit in the CONTROL register
if the CPU is in Thread mode (as documented in the pseudocode
for the MSR instruction). Implement this, instead of permitting
SPSEL to be written in all cases.

This was causing mbed applications not to run, because the
RTX RTOS they use relies on this behaviour.

Backports commit 792dac309c8660306557ba058b8b5a6a75ab3c1f from qemu
2018-03-04 13:04:20 -05:00
Peter Maydell 4ae080e27f
target/arm: Don't calculate lr in arm_v7m_cpu_do_interrupt() until needed
Move the code in arm_v7m_cpu_do_interrupt() that calculates the
magic LR value down to when we're actually going to use it.
Having the calculation and use so far apart makes the code
a little harder to understand than it needs to be.

Backports commit bd70b29ba92e4446f9e4eb8b9acc19ef6ff4a4d5 from qemu
2018-03-04 12:59:38 -05:00
Peter Maydell 75f8224d13
target/arm: Make arm_cpu_dump_state() handle the M-profile XPSR
Make the arm_cpu_dump_state() debug logging handle the M-profile XPSR
rather than assuming it's an A-profile CPSR. On M profile the PSR
line of a register dump will now look like this:

XPSR=41000000 -Z-- T priv-thread

Backports commit 5b906f3589443a3c69d8feeaac37263843ecfb8d from qemu
2018-03-04 12:58:56 -05:00
Peter Maydell 9056a93c9a
target/arm: Don't store M profile PRIMASK and FAULTMASK in daif
We currently store the M profile CPU register state PRIMASK and
FAULTMASK in the daif field of the CPU state in its I and F
bits. This is a legacy from the original implementation, which
tried to share the cpu_exec_interrupt code between A profile
and M profile. We've since separated out the two cases because
they are significantly different, so now there is no common
code between M and A profile which looks at env->daif: all the
uses are either in A-only or M-only code paths. Sharing the state
fields now is just confusing, and will make things awkward
when we implement v8M, where the PRIMASK and FAULTMASK
registers are banked between security states.

Switch M profile over to using v7m.faultmask and v7m.primask
fields for these registers.

Backports commit e6ae5981ea4b0f6feb223009a5108582e7644f8f from qemu
2018-03-04 12:56:29 -05:00
Peter Maydell 5d6b031550
target/arm: Define and use XPSR bit masks
The M profile XPSR is almost the same format as the A profile CPSR,
but not quite. Define some XPSR_* macros and use them where we
definitely dealing with an XPSR rather than reusing the CPSR ones.

Backports commit 987ab45e108953c1c98126c338c2119c243c372b from qemu
2018-03-04 12:54:41 -05:00
Peter Maydell 64c6727e4a
target/arm: Fix outdated comment about exception exit
When we switched our handling of exception exit to detect
the magic addresses at translate time rather than via
a do_unassigned_access hook, we forgot to update a
comment; correct the omission.

Backports commit 9d17da4b68a05fc78daa47f0f3d914eea5d802ea from qemu
2018-03-04 12:52:34 -05:00
Peter Maydell 219b3e8a08
target/arm: Remove incorrect comment about MPU_CTRL
Remove the comment that claims that some MPU_CTRL bits are stored
in sctlr_el[1]. This has never been true since MPU_CTRL was added
in commit 29c483a50607 -- the comment is a leftover from
Michael Davidsaver's original implementation, which I modified
not to use sctlr_el[1]; I forgot to delete the comment then.

Backports commit 59e4972c3fc63d981e8b613ebb3bb01a05848075 from qemu
2018-03-04 12:52:02 -05:00
Peter Maydell 108cff5e61
target/arm: Tighten up Thumb decode where new v8M insns will be
Tighten up the T32 decoder in the places where new v8M instructions
will be:
* TT/TTT/TTA/TTAT are in what was nominally LDREX/STREX r15, ...
which is UNPREDICTABLE:
make the UNPREDICTABLE behaviour be to UNDEF
* BXNS/BLXNS are distinguished from BX/BLX via the low 3 bits,
which in previous architectural versions are SBZ:
enforce the SBZ via UNDEF rather than ignoring it, and move
the "ARCH(5)" UNDEF case up so we don't leak a TCG temporary
* SG is in the encoding which would be LDRD/STRD with rn = r15;
this is UNPREDICTABLE and we currently UNDEF:
move this check further up the code so that we don't leak
TCG temporaries in the UNDEF case and have a better place
to put the SG decode.

This means that if a v8M binary is accidentally run on v7M
or if a test case hits something that we haven't implemented
yet the behaviour will be obvious (UNDEF) rather than obscure
(plough on treating it as a different instruction).

In the process, add some comments about the instruction patterns
at these points in the decode. Our Thumb and ARM decoders are
very difficult to understand currently, but gradually adding
comments like this should help to clarify what exactly has
been decoded when.

Backports commit ebfe27c593e5b222aa2a1fc545b447be3d995faa from qemu
2018-03-04 12:51:08 -05:00
Peter Maydell 6f4afe1a13
target/arm: Consolidate PMSA handling in get_phys_addr()
Currently get_phys_addr() has PMSAv7 handling before the
"is translation disabled?" check, and then PMSAv5 after it.
Tidy this up by making the PMSAv5 code handle the "MPU disabled"
case itself, so that we have all the PMSA code in one place.
This will make adding the PMSAv8 code slightly cleaner, and
also means that pre-v7 PMSA cores benefit from the MPU lookup
logging that the PMSAv7 codepath had.

Backports commit 3279adb95e34dd3d67c66d729458f7784747cf8d from qemu
2018-03-04 12:48:22 -05:00
Peter Maydell f85f301316
target/arm: Don't trap WFI/WFE for M profile
M profile cores can never trap on WFI or WFE instructions. Check for
M profile in check_wfx_trap() to ensure this.

The existing code will do the right thing for v7M cores because
the hcr_el2 and scr_el3 registers will be all-zeroes and so we
won't attempt to trap, but when we start setting ARM_FEATURE_V8
for v8M cores the v8A handling of SCTLR.nTWE and .nTWI will not
give the right results.

Backports commit 0e2845689ebdb4ea7174f96f6797e2d8942bd114 from qemu
2018-03-04 12:46:37 -05:00
Peter Maydell 2c9a196efe
target/arm: Use MMUAccessType enum rather than int
In the ARM get_phys_addr() code, switch to using the MMUAccessType
enum and its MMU_* values rather than int and literal 0/1/2.

Backports commit 03ae85f858fc46495258a5dd4551fff2c34bd495 from qemu
2018-03-04 12:45:56 -05:00
Alistair Francis 5d742aad0b
target/arm: Require alignment for load exclusive
According to the ARM ARM exclusive loads require the same alignment as
exclusive stores. Let's update the memops used for the load to match
that of the store. This adds the alignment requirement to the memops.

Backports commit 4a2fdb78e794c1ad93aa9e160235d6a61a2125de from qemu
2018-03-04 01:53:04 -05:00
Richard Henderson 4a8f556c29
target/arm: Correct load exclusive pair atomicity
We are not providing the required single-copy atomic semantics for
the 64-bit operation that is the 32-bit paired load.

At the same time, leave the entire 64-bit value in cpu_exclusive_val
and stop writing to cpu_exclusive_high. This means that we do not
have to re-assemble the 64-bit quantity when it comes time to store.

At the same time, drop a redundant temporary and perform all loads
directly into the cpu_exclusive_* globals.

Backports commit 19514cde3b92938df750acaecf2caaa85e1d36a6 from qemu
2018-03-04 01:49:35 -05:00
Alistair Francis 009a52dd13
target/arm: Correct exclusive store cmpxchg memop mask
When we perform the atomic_cmpxchg operation we want to perform the
operation on a pair of 32-bit registers. Previously we were just passing
the register size in which was set to MO_32. This would result in the
high register to be ignored. To fix this issue we hardcode the size to
be 64-bits long when operating on 32-bit pairs.

Backports commit 955fd0ad5d610f62ba2f4ce46a872bf50434dcf8 from qemu
2018-03-04 01:43:55 -05:00
Peter Maydell d72175d671
target/arm: Move PMSAv7 reset into arm_cpu_reset() so M profile MPUs get reset
When the PMSAv7 implementation was originally added it was for R profile
CPUs only, and reset was handled using the cpreg .resetfn hooks.
Unfortunately for M profile cores this doesn't work, because they do
not register any cpregs. Move the reset handling into arm_cpu_reset(),
where it will work for both R profile and M profile cores.

Backports commit 69ceea64bf565559a2b865ffb2a097d2caab805b from qemu
2018-03-04 01:20:57 -05:00
Peter Maydell 6add2f0f65
target/arm: Rename cp15.c6_rgnr to pmsav7.rnr
Almost all of the PMSAv7 state is in the pmsav7 substruct of
the ARM CPU state structure. The exception is the region
number register, which is in cp15.c6_rgnr. This exception
is a bit odd for M profile, which otherwise generally does
not store state in the cp15 substruct.

Rename cp15.c6_rgnr to pmsav7.rnr accordingly.

Backports commit 8531eb4f614a60e6582d4832b15eee09f7d27874 from qemu
2018-03-04 01:18:53 -05:00
Peter Maydell 266885f50f
target/arm: Don't allow guest to make System space executable for M profile
For an M profile v7PMSA, the system space (0xe0000000 - 0xffffffff) can
never be executable, even if the guest tries to set the MPU registers
up that way. Enforce this restriction.

Backports commit bf446a11dfb17ae7d8ed2b61a2444804eb458075 from qemu
2018-03-04 01:17:01 -05:00
Peter Maydell 34b9740081
target/arm: Don't do MPU lookups for addresses in M profile PPB region
The M profile PMSAv7 specification says that if the address being looked
up is in the PPB region (0xe0000000 - 0xe00fffff) then we do not use
the MPU regions but always use the default memory map. Implement this
(we were previously behaving like an R profile PMSAv7, which does not
special case this).

Backports commit 38aaa60ca464b48e6feef346709e97335d01b289 from qemu
2018-03-04 01:14:22 -05:00
Peter Maydell 4dc69f4b26
target/arm: Correct MPU trace handling of write vs execute
Correct off-by-one bug in the PSMAv7 MPU tracing where it would print
a write access as "reading", an insn fetch as "writing", and a read
access as "execute".

Since we have an MMUAccessType enum now, we can make the code clearer
in the process by using that rather than the raw 0/1/2 values.

Backports commit 709e4407add7acacc593cb6cdac026558c9a8fb6 from qemu
2018-03-04 01:13:19 -05:00
Lluís Vilanova 32b3c3815d
tcg: Pass generic CPUState to gen_intermediate_code()
Needed to implement a target-agnostic gen_intermediate_code()
in the future.

Backports commit 9c489ea6bed134fecfd556b439c68bba48fbe102 from qemu
2018-03-03 23:34:18 -05:00
Alex Bennée 0bd8dc4e0a
target/arm: use DISAS_EXIT for eret handling
Previously DISAS_JUMP did ensure this but with the optimisation of
8a6b28c7 (optimize indirect branches) we might not leave the loop.
This means if any pending interrupts are cleared by changing IRQ flags
we might never get around to servicing them. You usually notice this
by seeing the lookup_tb_ptr() helper gainfully chaining TBs together
while cpu->interrupt_request remains high and the exit_request has not
been set.

This breaks amongst other things the OPTEE test suite which executes
an eret from the secure world after a non-secure world IRQ has gone
pending which then never gets serviced.

Instead of using the previously implied semantics of DISAS_JUMP we use
DISAS_EXIT which will always exit the run-loop.

Backports commit b29fd33db578decacd14f34933b29aece3e7c25e from qemu
2018-03-03 22:43:16 -05:00
Alex Bennée 65356210a8
target/arm: use gen_goto_tb for ISB handling
While an ISB will ensure any raised IRQs happen on the next
instruction it doesn't cause any to get raised by itself. We can
therefore use a simple tb exit for ISB instructions and rely on the
exit_request check at the top of each TB to deal with exiting if
needed.

Backports commit 0b609cc128ba5ef16cc841bcade898d1898f1dc3 from qemu
2018-03-03 22:42:33 -05:00