kern: update for new exception flag semantics

This commit is contained in:
Michael Scire 2022-10-12 00:50:03 -07:00 committed by SciresM
parent 13238fc4fd
commit bf4fdf6188
4 changed files with 27 additions and 12 deletions

View File

@ -38,6 +38,25 @@ namespace ams::kern::arch::arm64::cpu {
ALWAYS_INLINE ~KScopedCoreMigrationDisable() { GetCurrentThread().EnableCoreMigration(); } ALWAYS_INLINE ~KScopedCoreMigrationDisable() { GetCurrentThread().EnableCoreMigration(); }
}; };
class KScopedCacheMaintenance {
private:
bool m_active;
public:
ALWAYS_INLINE KScopedCacheMaintenance() {
__asm__ __volatile__("" ::: "memory");
if (m_active = !GetCurrentThread().IsInCacheMaintenanceOperation(); m_active) {
GetCurrentThread().SetInCacheMaintenanceOperation();
}
}
ALWAYS_INLINE ~KScopedCacheMaintenance() {
if (m_active) {
GetCurrentThread().ClearInCacheMaintenanceOperation();
}
__asm__ __volatile__("" ::: "memory");
}
};
/* Nintendo registers a handler for a SGI on thread termination, but does not handle anything. */ /* Nintendo registers a handler for a SGI on thread termination, but does not handle anything. */
/* This is sufficient, because post-interrupt scheduling is all they really intend to occur. */ /* This is sufficient, because post-interrupt scheduling is all they really intend to occur. */
class KThreadTerminationInterruptHandler : public KInterruptHandler { class KThreadTerminationInterruptHandler : public KInterruptHandler {
@ -432,9 +451,7 @@ namespace ams::kern::arch::arm64::cpu {
Result InvalidateDataCache(void *addr, size_t size) { Result InvalidateDataCache(void *addr, size_t size) {
/* Mark ourselves as in a cache maintenance operation, and prevent re-ordering. */ /* Mark ourselves as in a cache maintenance operation, and prevent re-ordering. */
__asm__ __volatile__("" ::: "memory"); KScopedCacheMaintenance cm;
GetCurrentThread().SetInCacheMaintenanceOperation();
ON_SCOPE_EXIT { GetCurrentThread().ClearInCacheMaintenanceOperation(); __asm__ __volatile__("" ::: "memory"); };
const uintptr_t start = reinterpret_cast<uintptr_t>(addr); const uintptr_t start = reinterpret_cast<uintptr_t>(addr);
const uintptr_t end = start + size; const uintptr_t end = start + size;
@ -460,9 +477,7 @@ namespace ams::kern::arch::arm64::cpu {
Result StoreDataCache(const void *addr, size_t size) { Result StoreDataCache(const void *addr, size_t size) {
/* Mark ourselves as in a cache maintenance operation, and prevent re-ordering. */ /* Mark ourselves as in a cache maintenance operation, and prevent re-ordering. */
__asm__ __volatile__("" ::: "memory"); KScopedCacheMaintenance cm;
GetCurrentThread().SetInCacheMaintenanceOperation();
ON_SCOPE_EXIT { GetCurrentThread().ClearInCacheMaintenanceOperation(); __asm__ __volatile__("" ::: "memory"); };
const uintptr_t start = util::AlignDown(reinterpret_cast<uintptr_t>(addr), DataCacheLineSize); const uintptr_t start = util::AlignDown(reinterpret_cast<uintptr_t>(addr), DataCacheLineSize);
const uintptr_t end = util::AlignUp( reinterpret_cast<uintptr_t>(addr) + size, DataCacheLineSize); const uintptr_t end = util::AlignUp( reinterpret_cast<uintptr_t>(addr) + size, DataCacheLineSize);
@ -472,9 +487,7 @@ namespace ams::kern::arch::arm64::cpu {
Result FlushDataCache(const void *addr, size_t size) { Result FlushDataCache(const void *addr, size_t size) {
/* Mark ourselves as in a cache maintenance operation, and prevent re-ordering. */ /* Mark ourselves as in a cache maintenance operation, and prevent re-ordering. */
__asm__ __volatile__("" ::: "memory"); KScopedCacheMaintenance cm;
GetCurrentThread().SetInCacheMaintenanceOperation();
ON_SCOPE_EXIT { GetCurrentThread().ClearInCacheMaintenanceOperation(); __asm__ __volatile__("" ::: "memory"); };
const uintptr_t start = util::AlignDown(reinterpret_cast<uintptr_t>(addr), DataCacheLineSize); const uintptr_t start = util::AlignDown(reinterpret_cast<uintptr_t>(addr), DataCacheLineSize);
const uintptr_t end = util::AlignUp( reinterpret_cast<uintptr_t>(addr) + size, DataCacheLineSize); const uintptr_t end = util::AlignUp( reinterpret_cast<uintptr_t>(addr) + size, DataCacheLineSize);

View File

@ -86,9 +86,10 @@ _ZN3ams4kern3svc14RestoreContextEm:
/* Get our exception flags. */ /* Get our exception flags. */
ldrb w9, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_EXCEPTION_FLAGS)] ldrb w9, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_EXCEPTION_FLAGS)]
/* Clear in-svc and needs-fpu-restore flags. */ /* Clear in-svc, in-user-exception, and needs-fpu-restore flags. */
and w10, w9, #(~(THREAD_EXCEPTION_FLAG_IS_FPU_CONTEXT_RESTORE_NEEDED)) and w10, w9, #(~(THREAD_EXCEPTION_FLAG_IS_FPU_CONTEXT_RESTORE_NEEDED))
and w10, w10, #(~(THREAD_EXCEPTION_FLAG_IS_CALLING_SVC)) and w10, w10, #(~(THREAD_EXCEPTION_FLAG_IS_CALLING_SVC))
and w10, w10, #(~(THREAD_EXCEPTION_FLAG_IS_IN_USERMODE_EXCEPTION_HANDLER))
strb w10, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_EXCEPTION_FLAGS)] strb w10, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_EXCEPTION_FLAGS)]
/* If we don't need to restore the fpu, skip restoring it. */ /* If we don't need to restore the fpu, skip restoring it. */

View File

@ -509,7 +509,8 @@ namespace ams::kern {
void KThread::OnLeaveUsermodeException() { void KThread::OnLeaveUsermodeException() {
this->ClearUsermodeExceptionSvcPermissions(); this->ClearUsermodeExceptionSvcPermissions();
this->ClearInUsermodeExceptionHandler();
/* NOTE: InUsermodeExceptionHandler will be cleared by RestoreContext. */
} }
void KThread::Pin() { void KThread::Pin() {

View File

@ -57,7 +57,7 @@ namespace ams::svc {
/* This is the highest SVC version supported by Atmosphere, to be updated on new kernel releases. */ /* This is the highest SVC version supported by Atmosphere, to be updated on new kernel releases. */
/* NOTE: Official kernel versions have SVC major = SDK major + 4, SVC minor = SDK minor. */ /* NOTE: Official kernel versions have SVC major = SDK major + 4, SVC minor = SDK minor. */
constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(14); constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(15);
constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion( 3); constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion( 3);
constexpr inline u32 SupportedKernelVersion = EncodeKernelVersion(SupportedKernelMajorVersion, SupportedKernelMinorVersion); constexpr inline u32 SupportedKernelVersion = EncodeKernelVersion(SupportedKernelMajorVersion, SupportedKernelMinorVersion);