mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
arm/mpu: Move the functions to arm64 specific files
prepare_selector(), read_protection_region() and write_protection_region()
differ significantly between arm32 and arm64. Thus, move these functions
to their sub-arch specific folder.
Also the macro GENERATE_{WRITE/READ}_PR_REG_CASE are moved, in order to
keep them in the same file of their usage and improve readability.
Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
Reviewed-by: Luca Fancellu <luca.fancellu@arm.com>
Acked-by: Michal Orzel <michal.orzel@amd.com>
This commit is contained in:
1 parent
3c36a5a0df
commit
78afa06cf8
4 files changed
+132
-117
No files matched your search
@@ -1,3 +1,4 @@
|
||||
obj-$(CONFIG_ARM_64) += arm64/
|
||||
obj-$(CONFIG_ARM_32) += domain-page.o
|
||||
obj-y += mm.o
|
||||
obj-y += p2m.o
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
obj-y += mm.o
|
||||
@@ -0,0 +1,130 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <xen/bug.h>
|
||||
#include <xen/types.h>
|
||||
#include <asm/mpu.h>
|
||||
#include <asm/sysregs.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
/*
|
||||
* The following are needed for the cases: GENERATE_WRITE_PR_REG_CASE
|
||||
* and GENERATE_READ_PR_REG_CASE with num==0
|
||||
*/
|
||||
#define PRBAR0_EL2 PRBAR_EL2
|
||||
#define PRLAR0_EL2 PRLAR_EL2
|
||||
|
||||
#define PRBAR_EL2_(n) PRBAR##n##_EL2
|
||||
#define PRLAR_EL2_(n) PRLAR##n##_EL2
|
||||
|
||||
#define GENERATE_WRITE_PR_REG_CASE(num, pr) \
|
||||
case num: \
|
||||
{ \
|
||||
WRITE_SYSREG(pr->prbar.bits & ~MPU_REGION_RES0, PRBAR_EL2_(num)); \
|
||||
WRITE_SYSREG(pr->prlar.bits & ~MPU_REGION_RES0, PRLAR_EL2_(num)); \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define GENERATE_READ_PR_REG_CASE(num, pr) \
|
||||
case num: \
|
||||
{ \
|
||||
pr->prbar.bits = READ_SYSREG(PRBAR_EL2_(num)); \
|
||||
pr->prlar.bits = READ_SYSREG(PRLAR_EL2_(num)); \
|
||||
break; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Armv8-R supports direct access and indirect access to the MPU regions through
|
||||
* registers:
|
||||
* - indirect access involves changing the MPU region selector, issuing an isb
|
||||
* barrier and accessing the selected region through specific registers
|
||||
* - direct access involves accessing specific registers that point to
|
||||
* specific MPU regions, without changing the selector, avoiding the use of
|
||||
* a barrier.
|
||||
* For Arm64 the PR{B,L}AR_ELx (for n=0) and PR{B,L}AR<n>_ELx (for n=1..15) are
|
||||
* used for the direct access to the regions selected by
|
||||
* PRSELR_EL2.REGION<7:4>:n, so 16 regions can be directly accessed when the
|
||||
* selector is a multiple of 16, giving access to all the supported memory
|
||||
* regions.
|
||||
*/
|
||||
static void prepare_selector(uint8_t *sel)
|
||||
{
|
||||
uint8_t cur_sel = *sel;
|
||||
|
||||
/*
|
||||
* {read,write}_protection_region works using the direct access to the 0..15
|
||||
* regions, so in order to save the isb() overhead, change the PRSELR_EL2
|
||||
* only when needed, so when the upper 4 bits of the selector will change.
|
||||
*/
|
||||
cur_sel &= 0xF0U;
|
||||
if ( READ_SYSREG(PRSELR_EL2) != cur_sel )
|
||||
{
|
||||
WRITE_SYSREG(cur_sel, PRSELR_EL2);
|
||||
isb();
|
||||
}
|
||||
*sel &= 0xFU;
|
||||
}
|
||||
|
||||
void read_protection_region(pr_t *pr_read, uint8_t sel)
|
||||
{
|
||||
prepare_selector(&sel);
|
||||
|
||||
switch ( sel )
|
||||
{
|
||||
GENERATE_READ_PR_REG_CASE(0, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(1, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(2, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(3, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(4, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(5, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(6, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(7, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(8, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(9, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(10, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(11, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(12, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(13, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(14, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(15, pr_read);
|
||||
default:
|
||||
BUG(); /* Can't happen */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void write_protection_region(const pr_t *pr_write, uint8_t sel)
|
||||
{
|
||||
prepare_selector(&sel);
|
||||
|
||||
switch ( sel )
|
||||
{
|
||||
GENERATE_WRITE_PR_REG_CASE(0, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(1, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(2, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(3, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(4, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(5, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(6, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(7, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(8, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(9, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(10, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(11, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(12, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(13, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(14, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(15, pr_write);
|
||||
default:
|
||||
BUG(); /* Can't happen */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-file-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -29,35 +29,6 @@ DECLARE_BITMAP(xen_mpumap_mask, MAX_MPU_REGION_NR) \
|
||||
/* EL2 Xen MPU memory region mapping table. */
|
||||
pr_t __cacheline_aligned __section(".data") xen_mpumap[MAX_MPU_REGION_NR];
|
||||
|
||||
#ifdef CONFIG_ARM_64
|
||||
/*
|
||||
* The following are needed for the cases: GENERATE_WRITE_PR_REG_CASE
|
||||
* and GENERATE_READ_PR_REG_CASE with num==0
|
||||
*/
|
||||
#define PRBAR0_EL2 PRBAR_EL2
|
||||
#define PRLAR0_EL2 PRLAR_EL2
|
||||
|
||||
#define PRBAR_EL2_(n) PRBAR##n##_EL2
|
||||
#define PRLAR_EL2_(n) PRLAR##n##_EL2
|
||||
|
||||
#endif /* CONFIG_ARM_64 */
|
||||
|
||||
#define GENERATE_WRITE_PR_REG_CASE(num, pr) \
|
||||
case num: \
|
||||
{ \
|
||||
WRITE_SYSREG(pr->prbar.bits & ~MPU_REGION_RES0, PRBAR_EL2_(num)); \
|
||||
WRITE_SYSREG(pr->prlar.bits & ~MPU_REGION_RES0, PRLAR_EL2_(num)); \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define GENERATE_READ_PR_REG_CASE(num, pr) \
|
||||
case num: \
|
||||
{ \
|
||||
pr->prbar.bits = READ_SYSREG(PRBAR_EL2_(num)); \
|
||||
pr->prlar.bits = READ_SYSREG(PRLAR_EL2_(num)); \
|
||||
break; \
|
||||
}
|
||||
|
||||
static void __init __maybe_unused build_assertions(void)
|
||||
{
|
||||
/*
|
||||
@@ -69,94 +40,6 @@ static void __init __maybe_unused build_assertions(void)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM_64
|
||||
/*
|
||||
* Armv8-R supports direct access and indirect access to the MPU regions through
|
||||
* registers:
|
||||
* - indirect access involves changing the MPU region selector, issuing an isb
|
||||
* barrier and accessing the selected region through specific registers
|
||||
* - direct access involves accessing specific registers that point to
|
||||
* specific MPU regions, without changing the selector, avoiding the use of
|
||||
* a barrier.
|
||||
* For Arm64 the PR{B,L}AR_ELx (for n=0) and PR{B,L}AR<n>_ELx (for n=1..15) are
|
||||
* used for the direct access to the regions selected by
|
||||
* PRSELR_EL2.REGION<7:4>:n, so 16 regions can be directly accessed when the
|
||||
* selector is a multiple of 16, giving access to all the supported memory
|
||||
* regions.
|
||||
*/
|
||||
static void prepare_selector(uint8_t *sel)
|
||||
{
|
||||
uint8_t cur_sel = *sel;
|
||||
|
||||
/*
|
||||
* {read,write}_protection_region works using the direct access to the 0..15
|
||||
* regions, so in order to save the isb() overhead, change the PRSELR_EL2
|
||||
* only when needed, so when the upper 4 bits of the selector will change.
|
||||
*/
|
||||
cur_sel &= 0xF0U;
|
||||
if ( READ_SYSREG(PRSELR_EL2) != cur_sel )
|
||||
{
|
||||
WRITE_SYSREG(cur_sel, PRSELR_EL2);
|
||||
isb();
|
||||
}
|
||||
*sel &= 0xFU;
|
||||
}
|
||||
|
||||
void read_protection_region(pr_t *pr_read, uint8_t sel)
|
||||
{
|
||||
prepare_selector(&sel);
|
||||
|
||||
switch ( sel )
|
||||
{
|
||||
GENERATE_READ_PR_REG_CASE(0, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(1, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(2, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(3, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(4, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(5, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(6, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(7, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(8, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(9, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(10, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(11, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(12, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(13, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(14, pr_read);
|
||||
GENERATE_READ_PR_REG_CASE(15, pr_read);
|
||||
default:
|
||||
BUG(); /* Can't happen */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void write_protection_region(const pr_t *pr_write, uint8_t sel)
|
||||
{
|
||||
prepare_selector(&sel);
|
||||
|
||||
switch ( sel )
|
||||
{
|
||||
GENERATE_WRITE_PR_REG_CASE(0, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(1, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(2, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(3, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(4, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(5, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(6, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(7, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(8, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(9, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(10, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(11, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(12, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(13, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(14, pr_write);
|
||||
GENERATE_WRITE_PR_REG_CASE(15, pr_write);
|
||||
default:
|
||||
BUG(); /* Can't happen */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pr_t pr_of_addr(paddr_t base, paddr_t limit, unsigned int flags)
|
||||
{
|
||||
unsigned int attr_idx = PAGE_AI_MASK(flags);
|
||||
|
||||