summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimon Kruiper <timonkruiper@gmail.com>2023-01-30 16:06:24 +0100
committerJelle Raaijmakers <jelle@gmta.nl>2023-02-15 22:53:19 +0100
commite57d35ff537c892ff5987a3d4f371eafb05a6761 (patch)
tree0e7c77a733c5913af0d9cec1a391cbf0ece4d400
parentdfc6555fecddf409741b3f211b231ee923803029 (diff)
downloadserenity-e57d35ff537c892ff5987a3d4f371eafb05a6761.zip
Kernel/aarch64: Do not trap floating-point instructions
This requires setting the FPEN field of the Architectural Feature Access Control Register (CPACR_EL1) to 0b11.
-rw-r--r--Kernel/Arch/aarch64/Exceptions.cpp7
-rw-r--r--Kernel/Arch/aarch64/Registers.h20
2 files changed, 27 insertions, 0 deletions
diff --git a/Kernel/Arch/aarch64/Exceptions.cpp b/Kernel/Arch/aarch64/Exceptions.cpp
index cc03e3ff9c..af95df6d85 100644
--- a/Kernel/Arch/aarch64/Exceptions.cpp
+++ b/Kernel/Arch/aarch64/Exceptions.cpp
@@ -78,6 +78,13 @@ static void setup_el1()
Aarch64::SCTLR_EL1::write(system_control_register_el1);
+ Aarch64::CPACR_EL1 cpacr_el1 = {};
+ cpacr_el1.ZEN = 0; // Trap SVE instructions at EL1 and EL0
+ cpacr_el1.FPEN = 0b11; // Don't trap Advanced SIMD and floating-point instructions
+ cpacr_el1.SMEN = 0; // Trap SME instructions at EL1 and EL0
+ cpacr_el1.TTA = 0; // Don't trap access to trace registers
+ Aarch64::CPACR_EL1::write(cpacr_el1);
+
Aarch64::Asm::load_el1_vector_table(&vector_table_el1);
}
diff --git a/Kernel/Arch/aarch64/Registers.h b/Kernel/Arch/aarch64/Registers.h
index 096b4672f3..6c68d28924 100644
--- a/Kernel/Arch/aarch64/Registers.h
+++ b/Kernel/Arch/aarch64/Registers.h
@@ -1344,4 +1344,24 @@ struct alignas(u64) PMCCNTR_EL0 {
};
static_assert(sizeof(PMCCNTR_EL0) == 8);
+// D17.2.30 CPACR_EL1, Architectural Feature Access Control Register
+struct alignas(u64) CPACR_EL1 {
+ int _reserved0 : 16 = 0;
+ int ZEN : 2;
+ int _reserved18 : 2 = 0;
+ int FPEN : 2;
+ int _reserved22 : 2 = 0;
+ int SMEN : 2;
+ int _reserved26 : 2 = 0;
+ int TTA : 1;
+ int _reserved29 : 3 = 0;
+ int _reserved32 : 32 = 0;
+
+ static inline void write(CPACR_EL1 cpacr_el1)
+ {
+ asm("msr cpacr_el1, %[value]" ::[value] "r"(cpacr_el1));
+ }
+};
+static_assert(sizeof(CPACR_EL1) == 8);
+
}