exo2: implement SmcSetKernelCarveoutRegion

This commit is contained in:
Michael Scire 2020-05-15 12:05:17 -07:00 committed by SciresM
parent bf546d5fb3
commit b6b114ec40
5 changed files with 31 additions and 4 deletions

View file

@ -1194,4 +1194,13 @@ namespace ams::secmon {
hw::InstructionSynchronizationBarrier(); hw::InstructionSynchronizationBarrier();
} }
void SetKernelCarveoutRegion(int index, uintptr_t address, size_t size) {
/* Configure the carveout. */
auto &carveout = g_kernel_carveouts[index];
carveout.address = address;
carveout.size = size;
SetupKernelCarveouts();
}
} }

View file

@ -23,6 +23,8 @@ namespace ams::secmon {
constexpr inline int KernelCarveoutCount = 2; constexpr inline int KernelCarveoutCount = 2;
constexpr size_t CarveoutSizeMax = 512_MB - 128_KB;
void SetupCpuMemoryControllersEnableMmu(); void SetupCpuMemoryControllersEnableMmu();
void SetupCpuCoreContext(); void SetupCpuCoreContext();
void SetupCpuSErrorDebug(); void SetupCpuSErrorDebug();
@ -37,4 +39,6 @@ namespace ams::secmon {
void SaveSecurityEngineAesKeySlotTestVector(); void SaveSecurityEngineAesKeySlotTestVector();
void SetKernelCarveoutRegion(int index, uintptr_t address, size_t size);
} }

View file

@ -111,7 +111,7 @@ namespace ams::secmon::smc {
u8 kek_source[AesKeySize]; u8 kek_source[AesKeySize];
std::memcpy(kek_source, std::addressof(args.r[1]), AesKeySize); std::memcpy(kek_source, std::addressof(args.r[1]), AesKeySize);
const int generation = std::min<int>(args.r[3] - 1, pkg1::KeyGeneration_1_0_0); const int generation = std::max<int>(static_cast<int>(args.r[3]) - 1, pkg1::KeyGeneration_1_0_0);
const util::BitPack32 option = { static_cast<u32>(args.r[4]) }; const util::BitPack32 option = { static_cast<u32>(args.r[4]) };
const bool is_device_unique = option.Get<GenerateAesKekOption::IsDeviceUnique>(); const bool is_device_unique = option.Get<GenerateAesKekOption::IsDeviceUnique>();

View file

@ -15,13 +15,27 @@
*/ */
#include <exosphere.hpp> #include <exosphere.hpp>
#include "../secmon_error.hpp" #include "../secmon_error.hpp"
#include "../secmon_setup.hpp"
#include "secmon_smc_carveout.hpp" #include "secmon_smc_carveout.hpp"
namespace ams::secmon::smc { namespace ams::secmon::smc {
SmcResult SmcSetKernelCarveoutRegion(SmcArguments &args) { SmcResult SmcSetKernelCarveoutRegion(SmcArguments &args) {
/* TODO */ /* Decode arguments. */
return SmcResult::NotImplemented; const int index = args.r[1];
const uintptr_t address = args.r[2];
const size_t size = args.r[3];
/* Validate arguments. */
SMC_R_UNLESS(0 <= index && index < KernelCarveoutCount, InvalidArgument);
SMC_R_UNLESS(util::IsAligned(address, 128_KB), InvalidArgument);
SMC_R_UNLESS(util::IsAligned(size, 128_KB), InvalidArgument);
SMC_R_UNLESS(size <= CarveoutSizeMax, InvalidArgument);
/* Set the carveout. */
SetKernelCarveoutRegion(index, address, size);
return SmcResult::Success;
} }
} }

View file

@ -242,7 +242,7 @@ namespace ams::secmon::smc {
util::WaitMicroSeconds(1000); util::WaitMicroSeconds(1000);
} }
if (args.r[0] != static_cast<u64>(SmcResult::Success)) { if (args.r[0] != static_cast<u64>(SmcResult::Success) && info.function_id != 0xC3000007 /* generate aes key fails during SetupKekAccessKeys */) {
*(volatile u32 *)(MemoryRegionVirtualDebug.GetAddress()) = 0xCCCCCCCC; *(volatile u32 *)(MemoryRegionVirtualDebug.GetAddress()) = 0xCCCCCCCC;
*(volatile u32 *)(MemoryRegionVirtualDebug.GetAddress() + 0x10) = static_cast<u32>(info.function_id); *(volatile u32 *)(MemoryRegionVirtualDebug.GetAddress() + 0x10) = static_cast<u32>(info.function_id);
for (size_t i = 0; i < sizeof(args) / sizeof(u32); ++i) { for (size_t i = 0; i < sizeof(args) / sizeof(u32); ++i) {