Pull cache flush out of Haystack am: 84d7185e5f am: 6304a242ae

am: 4354c9182a

Change-Id: I826e93e08dc046b52aea97a3619e73dae98fb2db
This commit is contained in:
Fred Gylys-Colwell
2016-09-12 17:30:52 +00:00
committed by android-build-merger
5 changed files with 64 additions and 4 deletions

View File

@@ -13,6 +13,13 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#if __mips__
#include <sys/syscall.h>
#include <asm/cachectl.h>
#endif
#include <iostream> #include <iostream>
#include <map> #include <map>
@@ -235,6 +242,61 @@ struct FunctionPointers {
L1_LoadKeys_V9_or_V10_t LoadKeys_V9_or_V10; L1_LoadKeys_V9_or_V10_t LoadKeys_V9_or_V10;
}; };
// The Cache Flush function is very processor dependent, but is needed by the
// haystack code. The haystack code is delivered as a static prebuilt library.
// For that reason, we pass a function pointer for cache_flush into the
// haystack. The function is combiled outside of the haystack and may use
// target (processor) specific compiler flags.
void clear_cache_function(void *page, size_t len) {
// Note on cross platform support. If __has_builtin is not defined as a
// preprocessor function, we cannot use
// "#if defined(__has_builtin) && __has_builtin(..)".
// So, instead, we will define USED_BUILTIN_CLEAR_CACHE if both conditions
// are true, and use "#ifndef USED_BUILTIN_CLEAR_CACHE" instead of #else.
#ifdef __has_builtin
#if __has_builtin(__builtin___clear_cache)
#pragma message "clear_cache_function is using __builtin___clear_cache."
#define USED_BUILTIN_CLEAR_CACHE
char *begin = static_cast<char *>(page);
char *end = begin + len;
__builtin___clear_cache(begin, end);
#endif
#endif
#ifndef USED_BUILTIN_CLEAR_CACHE
#if __arm__
#pragma message "clear_cache_function is using arm asm."
// ARM Cache Flush System Call:
char *begin = static_cast<char *>(page);
char *end = begin + len;
const int syscall = 0xf0002;
__asm __volatile (
"push {r0, r1, r2, r7}\n"
"mov r0, %0\n"
"mov r1, %1\n"
"mov r7, %2\n"
"mov r2, #0x0\n"
"svc 0x00000000\n"
"pop {r0, r1, r2, r7}\n"
:
: "r" (begin), "r" (end), "r" (syscall)
: "r0", "r1", "r7"
);
#elif __mips__
#pragma message "clear_cache_function is using mips asm."
int result = syscall(__NR_cacheflush, page, len, ICACHE);
if (result) {
fprintf(stderr, "cacheflush failed!: errno=%d %s\n", errno,
strerror(errno));
exit(-1); // TODO(fredgc): figure out more graceful error handling.
}
#else
#pragma message "clear_cache_function is not doing anything."
// TODO(fredgc): silence warning about unused variables.
#endif
#endif
}
struct LevelSession { struct LevelSession {
FunctionPointers* fcn; FunctionPointers* fcn;
OEMCrypto_SESSION session; OEMCrypto_SESSION session;
@@ -269,7 +331,7 @@ class Adapter {
OEMCryptoResult Initialize() { OEMCryptoResult Initialize() {
LoadLevel3(); LoadLevel3();
OEMCryptoResult result = Level3_Initialize(); OEMCryptoResult result = Level3_Initialize(clear_cache_function);
if (force_level3()) { if (force_level3()) {
LOGW("Test code. User requested falling back to L3"); LOGW("Test code. User requested falling back to L3");
return result; return result;
@@ -416,7 +478,6 @@ class Adapter {
} }
void LoadLevel3() { void LoadLevel3() {
level3_.Initialize = Level3_Initialize;
level3_.Terminate = Level3_Terminate; level3_.Terminate = Level3_Terminate;
level3_.OpenSession = Level3_OpenSession; level3_.OpenSession = Level3_OpenSession;
level3_.CloseSession = Level3_CloseSession; level3_.CloseSession = Level3_CloseSession;

View File

@@ -64,7 +64,7 @@ namespace wvoec3 {
extern "C" { extern "C" {
bool Level3_PreInitialize(const char* path); bool Level3_PreInitialize(const char* path);
OEMCryptoResult Level3_Initialize(void); OEMCryptoResult Level3_Initialize(void (*ClearCache)(void *, size_t));
OEMCryptoResult Level3_Terminate(void); OEMCryptoResult Level3_Terminate(void);
OEMCryptoResult Level3_OpenSession(OEMCrypto_SESSION *session); OEMCryptoResult Level3_OpenSession(OEMCrypto_SESSION *session);
OEMCryptoResult Level3_CloseSession(OEMCrypto_SESSION session); OEMCryptoResult Level3_CloseSession(OEMCrypto_SESSION session);
@@ -80,7 +80,6 @@ OEMCryptoResult Level3_GenerateSignature(OEMCrypto_SESSION session,
size_t message_length, size_t message_length,
uint8_t* signature, uint8_t* signature,
size_t* signature_length); size_t* signature_length);
OEMCryptoResult Level3_LoadKeys(OEMCrypto_SESSION session, OEMCryptoResult Level3_LoadKeys(OEMCrypto_SESSION session,
const uint8_t* message, const uint8_t* message,
size_t message_length, size_t message_length,