Paste number 160204: Test case for possible TLB bug

Paste number 160204: Test case for possible TLB bug
Pasted by: nyef
When:9 years, 3 months ago
Share:Tweet this! | http://paste.lisp.org/+3FM4
Channel:None
Paste contents:
Raw Source | XML | Display As
#include <stdio.h>
#include <sys/mman.h>
#include <signal.h>
#include <stdlib.h>

#define BINDSTACK_SIZE 0x1000000
#define BINDSTACK_PAGE_SIZE 0x1000
#define BINDSTACK_LOW_GUARD_PAGE 0x0ffe000
#define BINDSTACK_HIGH_GUARD_PAGE 0xfff000

void *bindstack;

struct symdata {
    unsigned int pad0;
    unsigned int value;
    unsigned int pad2;
    unsigned int pad3;
    unsigned int pad4;
    unsigned int pad5;
};

#define SYMDATA_SIZE 0x6000 /* 1024 entries, 6 words/entry, 4 bytes/word */

struct symdata *symdata;

int trap_1_hit;

void protect_low(int protect)
{
    mprotect(bindstack + BINDSTACK_LOW_GUARD_PAGE,
	     BINDSTACK_PAGE_SIZE,
	     protect? 0: PROT_READ | PROT_WRITE | PROT_EXEC);
}

void protect_high(int protect)
{
    mprotect(bindstack + BINDSTACK_HIGH_GUARD_PAGE,
	     BINDSTACK_PAGE_SIZE,
	     protect? 0: PROT_READ | PROT_WRITE | PROT_EXEC);
}

void sigsegv_handler(int signal, siginfo_t *info, void *context)
{
    void *addr = info->si_addr;

    if (addr == (bindstack + BINDSTACK_HIGH_GUARD_PAGE)) {
	printf("trap 1\n");
	protect_high(0);
	protect_low(1);
	trap_1_hit = 1;
    } else if ((addr > (bindstack + BINDSTACK_LOW_GUARD_PAGE)) &&
	       (addr < (bindstack + BINDSTACK_HIGH_GUARD_PAGE))) {
	printf("trap 2\n");
	protect_high(1);
	protect_low(0);
    } else {
	printf("unknown trap address %p\n", addr);
	abort();
    }
}

void run_bind_test(void)
{
    unsigned int *p = bindstack;
    unsigned int i = 0;

    while (!trap_1_hit) {
	p[0] = (unsigned int)&symdata[i];
	p[1] = symdata[i].value;
	symdata[i].value = 0xf001f001;
	p += 2;
	i = (i + 1) & 1023;
    }

    while (p != bindstack) {
	p -= 2;
	((struct symdata *)p[0])->value = p[1];
	p[0] = 0;
	p[1] = 0;
    }
}

int main(void)
{
    struct sigaction sa;

    if (sigprocmask(SIG_BLOCK, NULL, &sa.sa_mask)) {
	perror("sigprocmask");
	return 0;
    }

    sa.sa_sigaction = sigsegv_handler;
    sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_RESTART;
    if (sigaction(SIGSEGV, &sa, NULL)) {
	perror("sigaction");
	return 0;
    }

    bindstack = mmap(NULL,
		     BINDSTACK_SIZE,
		     PROT_READ | PROT_WRITE | PROT_EXEC,
		     MAP_PRIVATE | MAP_ANONYMOUS,
		     -1,
		     0);
    if (bindstack == MAP_FAILED) {
	perror("mmap bindstack");
	return 0;
    }

    symdata = mmap(NULL,
		   SYMDATA_SIZE,
		   PROT_READ | PROT_WRITE | PROT_EXEC,
		   MAP_PRIVATE | MAP_ANONYMOUS,
		   -1,
		   0);
    if (symdata == MAP_FAILED) {
	perror("mmap symdata");
	return 0;
    }

    protect_high(1);

    trap_1_hit = 0;

    printf("bindstack: %p, symdata: %p\n", bindstack, symdata);

    run_bind_test();

    printf("done\n");

    return 0;
}

This paste has no annotations.

Colorize as:
Show Line Numbers

Lisppaste pastes can be made by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively.