Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions linux-user/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,11 @@ static void handle_arg_latx_monitor_shared_mem(const char *arg)
option_monitor_shared_mem = strtol(arg, NULL, 0);
}

static void handle_arg_latx_private_mmap_shadow(const char *arg)
{
option_private_mmap_shadow = strtol(arg, NULL, 0);
}

static void handle_arg_smc_reload(const char *arg)
{
long value = 0;
Expand Down Expand Up @@ -899,6 +904,9 @@ static const struct qemu_argument arg_table[] = {
"", "enable get real self maps"},
{"latx-monitor-shared-mem", "LATX_MONITOR_SHARED_MEM", true, handle_arg_latx_monitor_shared_mem,
"", "monitor shared memory, retranslate self modifying page"},
{"latx-private-mmap-shadow", "LATX_PRIVATE_MMAP_SHADOW", true,
handle_arg_latx_private_mmap_shadow, "",
"shadow writable private SQLite file mapping fragments"},
{"smc_reload", "LATX_SMC_RELOAD", true, handle_arg_smc_reload,
"", "reload SMC TB"},
{"latx-wine-pe-fixed-base", "LATX_WINE_PE_FIXED_BASE", true,
Expand Down
42 changes: 41 additions & 1 deletion linux-user/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,35 @@ int target_mprotect(abi_ulong start, abi_ulong len, int target_prot)
return ret;
}

static bool fd_is_writable_sqlite_file(int fd)
{
static const char sqlite_header[] = "SQLite format 3";
char header[sizeof(sqlite_header)];
int fd_flags, saved_errno;
ssize_t bytes_read;
bool result = false;

saved_errno = errno;
if (fd < 0) {
goto out;
}

fd_flags = fcntl(fd, F_GETFL);
if (fd_flags < 0 || (fd_flags & O_ACCMODE) == O_RDONLY) {
goto out;
}

do {
bytes_read = pread(fd, header, sizeof(header), 0);
} while (bytes_read < 0 && errno == EINTR);

result = bytes_read == sizeof(header) &&
memcmp(header, sqlite_header, sizeof(header)) == 0;
out:
errno = saved_errno;
return result;
}

/* map an incomplete host page */
static int mmap_frag(abi_ulong real_start,
abi_ulong start, abi_ulong end,
Expand All @@ -290,6 +319,7 @@ static int mmap_frag(abi_ulong real_start,
abi_ulong real_end, addr;
void *host_start;
int prot1, prot2, prot_new;
bool writable_sqlite_mapping;

real_end = real_start + qemu_host_page_size;
host_start = g2h_untagged(real_start);
Expand Down Expand Up @@ -324,6 +354,12 @@ static int mmap_frag(abi_ulong real_start,
}
prot1 &= PAGE_BITS;

/* A pread-backed SQLite fragment cannot observe later writes via fd. */
writable_sqlite_mapping = option_private_mmap_shadow &&
!(flags & MAP_ANONYMOUS) &&
(flags & MAP_TYPE) == MAP_PRIVATE &&
fd_is_writable_sqlite_file(fd);

int shadow_mask = hostpage_exist_shadow_page(start);
int page_mask = 0;
for (addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
Expand All @@ -343,8 +379,12 @@ static int mmap_frag(abi_ulong real_start,

prot_new = prot | prot1;
if (!(flags & MAP_ANONYMOUS)) {
if ((flags & MAP_TYPE) == MAP_SHARED) {
if (writable_sqlite_mapping) {
create_shadow_page_chunk(start, end, prot, flags, fd, offset);
return 1;
} else if ((flags & MAP_TYPE) == MAP_SHARED) {
struct stat stat_info;

fstat(fd, &stat_info);
if (!stat_info.st_nlink ||
(prot & PROT_WRITE)) {
Expand Down
2 changes: 2 additions & 0 deletions target/i386/latx/include/latx-options.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ extern uint64_t imm_skip_pc;
extern int option_mem_test;
extern int option_real_maps;
extern int option_monitor_shared_mem;
extern int option_private_mmap_shadow;
extern int option_shadow_file;
extern int option_smc_opt;
#define FORK_UNLINK_MAGIC 0x88888889
Expand Down Expand Up @@ -129,6 +130,7 @@ extern unsigned long long counter_mips_tr;
ENVFUN(LATX_MT, handle_arg_latx_mem_test) \
ENVFUN(LATX_REAL_MAPS, handle_arg_latx_real_maps) \
ENVFUN(LATX_MONITOR_SHARED_MEM, handle_arg_latx_monitor_shared_mem) \
ENVFUN(LATX_PRIVATE_MMAP_SHADOW, handle_arg_latx_private_mmap_shadow) \
ENVFUN(LATX_FORK_UNLINK, handle_arg_latx_fork_unlink) \
ENVFUN(LATX_ANONYM, handle_arg_latx_anonym) \
ENVFUN(LATX_MMAP_START, handle_arg_mmap_start) \
Expand Down
2 changes: 2 additions & 0 deletions target/i386/latx/latx-options.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ int option_anonym;
int option_mem_test;
int option_real_maps;
int option_monitor_shared_mem;
int option_private_mmap_shadow;
int option_shadow_file;
int option_smc_opt;
/* Disabled by default; LATX_FORK_UNLINK enables the internal signal. */
Expand Down Expand Up @@ -254,6 +255,7 @@ void options_init(void)
option_mem_test = 0;
option_real_maps = 0;
option_monitor_shared_mem = 0;
option_private_mmap_shadow = 0;
#ifdef LOW_MEM_MODE_0
option_shadow_file = 1;
#endif
Expand Down