[akaros] [PATCH 2/2] reorder the top level Makefile so that full builds work again

2016-10-31 Thread Ronald G. Minnich
Otherwise, they fail, as gelf.h is not installed when
make tests runs.

Change-Id: If19d8515706a7a43ccd37bf2e60fbf88ce4cd581
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 12fe6c3..e7fe80a 100644
--- a/Makefile
+++ b/Makefile
@@ -735,9 +735,9 @@ xcc-upgrade: xcc
@$(MAKE) userclean
@$(MAKE) install-libs
@$(MAKE) testclean utestclean
-   @$(MAKE) tests utest
@$(call make_as_parent, apps-clean)
@$(call make_as_parent, apps-install)
+   @$(MAKE) tests utest
@$(MAKE) fill-kfs
@$(MAKE) akaros-kernel
 
-- 
2.8.0.rc3.226.g39d4020

-- 
You received this message because you are subscribed to the Google Groups 
"Akaros" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akaros+unsubscr...@googlegroups.com.
To post to this group, send email to akaros@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[akaros] [PATCH 1/2] vmrunkernel: read the elf, not a binary

2016-10-31 Thread Ronald G. Minnich
This has been used to boot a full Linux kernel environment
to multiuser.

Change-Id: I12c399aafd30cdf05208831ca30129753f027f2a
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 tests/vmm/Makefrag  |   2 +-
 tests/vmm/vmrunkernel.c | 192 +++-
 2 files changed, 142 insertions(+), 52 deletions(-)

diff --git a/tests/vmm/Makefrag b/tests/vmm/Makefrag
index 4208f63..49eb20f 100644
--- a/tests/vmm/Makefrag
+++ b/tests/vmm/Makefrag
@@ -4,7 +4,7 @@ VMM_TESTS_CFLAGS += $(CFLAGS_TESTS)
 
 ALL_VMM_TEST_FILES := $(wildcard $(VMM_TESTS_DIR)/*.c)
 
-VMM_TESTS_LDLIBS := $(TESTS_LDLIBS)
+VMM_TESTS_LDLIBS := $(TESTS_LDLIBS) -lelf
 
 VMM_TESTS_SRCS := $(ALL_VMM_TEST_FILES)
 
diff --git a/tests/vmm/vmrunkernel.c b/tests/vmm/vmrunkernel.c
index ea2ac5a..5f2787f 100644
--- a/tests/vmm/vmrunkernel.c
+++ b/tests/vmm/vmrunkernel.c
@@ -6,7 +6,9 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -36,6 +38,9 @@
 #include 
 #include 
 
+#define DBG(format, ...) if (debug)\
+   fprintf(stderr, format, __VA_ARGS__)
+
 struct virtual_machine local_vm, *vm = _vm;
 
 struct vmm_gpcore_init gpci;
@@ -292,13 +297,13 @@ static uint8_t acpi_tb_checksum(uint8_t *buffer, uint32_t 
length)
 {
uint8_t sum = 0;
uint8_t *end = buffer + length;
-   fprintf(stderr, "tbchecksum %p for %d", buffer, length);
+   DBG("tbchecksum %p for %d", buffer, length);
while (buffer < end) {
-   if (end - buffer < 2)
+   if (0 && end - buffer < 2)
fprintf(stderr, "%02x\n", sum);
sum = (uint8_t)(sum + *(buffer++));
}
-   fprintf(stderr, " is %02x\n", sum);
+   DBG(" is %02x\n", sum);
return (sum);
 }
 
@@ -307,11 +312,11 @@ static void gencsum(uint8_t *target, void *data, int len)
uint8_t csum;
// blast target to zero so it does not get counted
// (it might be in the struct we checksum) And, yes, it is, goodness.
-   fprintf(stderr, "gencsum %p target %p source %d bytes\n", target, data, 
len);
+   DBG("gencsum %p target %p source %d bytes\n", target, data, len);
*target = 0;
csum  = acpi_tb_checksum((uint8_t *)data, len);
*target = ~csum + 1;
-   fprintf(stderr, "Cmoputed is %02x\n", *target);
+   DBG("ACPI: genchecksum: Computed is %02x\n", *target);
 }
 
 static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
@@ -324,15 +329,108 @@ static inline int test_and_set_bit(int nr, volatile 
unsigned long *addr)
return oldbit;
 }
 
-static void pir_dump()
+/* load_kernel loads an ELF file as a kernel. */
+uintptr_t
+load_kernel(char *filename, uintptr_t *kernstart, uintptr_t *kernend)
 {
-   unsigned long *pir_ptr = gpci.posted_irq_desc;
-   int i;
-   fprintf(stderr, "---Begin PIR dump---\n");
-   for (i = 0; i < 8; i++){
-   fprintf(stderr, "Byte %d: 0x%016x\n", i, pir_ptr[i]);
+   Elf64_Ehdr *ehdr;
+   Elf *elf;
+   size_t phnum = 0;
+   Elf64_Phdr *hdrs;
+   int fd;
+
+   elf_version(EV_CURRENT);
+   fd = open(filename, O_RDONLY);
+   if (fd < 0) {
+   fprintf(stderr, "Can't open %s: %r\n", filename);
+   return 0;
+   }
+
+   elf = elf_begin(fd, ELF_C_READ, NULL);
+   if (elf == NULL) {
+   fprintf(stderr, "%s: cannot read %s ELF file.\n", __func__, 
filename);
+   close(fd);
+   return 0;
+   }
+
+   ehdr = elf64_getehdr(elf);
+   if (ehdr == NULL) {
+   fprintf(stderr, "%s: cannot get exec header of %s.\n",
+   __func__, filename);
+   goto fail;
+   }
+   fprintf(stderr, "%s ELF entry point is %p\n", filename, ehdr->e_entry);
+
+   if (elf_getphdrnum(elf, ) < 0) {
+   fprintf(stderr, "%s: cannot get program header num of %s.\n",
+   __func__, filename);
+   goto fail;
}
-   fprintf(stderr, "---End PIR dump---\n");
+   fprintf(stderr, "%s has %d program headers\n", filename, phnum);
+
+   hdrs = elf64_getphdr(elf);
+   if (hdrs == NULL) {
+   fprintf(stderr, "%s: cannot get program headers of %s.\n",
+   __func__, filename);
+   goto fail;
+   }
+
+   for (int i = 0; i < phnum; i++) {
+   size_t tot;
+   Elf64_Phdr *h = [i];
+   uintptr_t pa;
+
+   fprintf(stderr,
+   "%d: type 0x%lx flags 0x%lx  offset 0x%lx vaddr 0x%lx 
paddr 0x%lx size 0x%lx  memsz 0x%lx align 0x%lx\n&q

[akaros] [PATCH] vmrunkernel: move to using mmap or backing the kernel image. Fail miserably.

2016-10-31 Thread Ronald G. Minnich
I've gotten rid of the uint8_t kernel[] and am using mmap to back the image.

The image starts and runs UNTIL it tries to load its own cr3 and run from
that. Then it dies:

Map 0x100 for 20426752 bytes
p512 0x10049000 p512[0] is 0x1004a003 p1 0x1004a000 p1[0] is 0x4b003
Don't know how to handle exit 2
RIP 0x81000147, shutdown 0x2
vmm: handle_vmexit returned false
Note: this may be a kernel module, not the kernel
RIP was 0x81000147:
01000147: b8 01 00 00 80 0f a2 89 d7 b9 80 00 00 c0 0f 32  ...2
02008000: 63 90 00 02 00 00 00 00 63 90 00 02 00 00 00 00  c...c...
02008010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
...
02008ff0: 00 00 00 00 00 00 00 00 67 e0 e0 01 00 00 00 00  g...
01e0e000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
...
Shutdown: core 0, exit due to TRIPLE_FAULT(0x2); ret code 0x2
  gva 0x81000147 gpa (nil) cr3 0x2008000
  rax  0x81000147
  rbx  0x0200a000
  rcx  0x00a0
  rdx  0x0200a063
  rbp  0x
  rsi  0x000e4000
  rdi  0x01e1
  r8   0x01e1
  r9   0x
  r10  0x
  r11  0x
  r12  0x
  r13  0x
  r14  0x
  r15  0x

So, note the cr3 is 2008000, and the last 64-bit word in that page
(ff8) points to 01e0e000. This all makes sense, save that page table is
all zeros. Damn.

I think I had this problem earlier and it's why I went to the pre-allocated
part-of-.date kernel[] array, but it's time we fixed this.

Change-Id: I90a90cf7ffe6abcb5666e1648ecf1d41ceb17fc9
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 tests/vmm/vmrunkernel.c | 76 +
 user/vmm/sched.c|  2 ++
 2 files changed, 41 insertions(+), 37 deletions(-)

diff --git a/tests/vmm/vmrunkernel.c b/tests/vmm/vmrunkernel.c
index 5f2787f..04082c6 100644
--- a/tests/vmm/vmrunkernel.c
+++ b/tests/vmm/vmrunkernel.c
@@ -14,7 +14,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -38,8 +37,8 @@
 #include 
 #include 
 
-#define DBG(format, ...) if (debug)\
-   fprintf(stderr, format, __VA_ARGS__)
+#define DBG(args...) if (debug) \
+   fprintf(stderr, args)
 
 struct virtual_machine local_vm, *vm = _vm;
 
@@ -136,9 +135,6 @@ unsigned int maxresume = (unsigned int) -1;
 
 #define MiB 0x10ull
 #define GiB (1ull << 30)
-#define GKERNBASE (16*MiB)
-#define KERNSIZE (1024 * MiB + GKERNBASE)
-uint8_t _kernel[KERNSIZE];
 
 unsigned long long *p512, *p1, *p2m;
 
@@ -176,7 +172,7 @@ void timer_thread(void *arg)
vmm_interrupt_guest(vm, 0, vector);
uthread_usleep(10);
}
-   fprintf(stderr, "SENDING TIMER\n");
+   DBG("SENDING TIMER\n");
 }
 
 
@@ -300,7 +296,7 @@ static uint8_t acpi_tb_checksum(uint8_t *buffer, uint32_t 
length)
DBG("tbchecksum %p for %d", buffer, length);
while (buffer < end) {
if (0 && end - buffer < 2)
-   fprintf(stderr, "%02x\n", sum);
+   DBG( "%02x\n", sum);
sum = (uint8_t)(sum + *(buffer++));
}
DBG(" is %02x\n", sum);
@@ -338,6 +334,7 @@ load_kernel(char *filename, uintptr_t *kernstart, uintptr_t 
*kernend)
size_t phnum = 0;
Elf64_Phdr *hdrs;
int fd;
+   uint64_t align, start, end, size;
 
elf_version(EV_CURRENT);
fd = open(filename, O_RDONLY);
@@ -359,14 +356,14 @@ load_kernel(char *filename, uintptr_t *kernstart, 
uintptr_t *kernend)
__func__, filename);
goto fail;
}
-   fprintf(stderr, "%s ELF entry point is %p\n", filename, ehdr->e_entry);
+   DBG( "%s ELF entry point is %p\n", filename, ehdr->e_entry);
 
if (elf_getphdrnum(elf, ) < 0) {
fprintf(stderr, "%s: cannot get program header num of %s.\n",
__func__, filename);
goto fail;
}
-   fprintf(stderr, "%s has %d program headers\n", filename, phnum);
+   DBG( "%s has %d program headers\n", filename, phnum);
 
hdrs = elf64_getphdr(elf);
if (hdrs == NULL) {
@@ -380,7 +377,7 @@ load_kernel(char *filename, uintptr_t *kernstart, uintptr_t 
*kernend)
Elf64_Phdr *h = [i];
uintptr_t pa;
 
-   fprintf(stderr,
+   DBG(
"%d: type 0x%lx flags 0x%lx  offset 0x%lx vaddr 0x%lx 
paddr 0x%lx size 0x%lx  memsz 0x%lx align 0x%lx\n",
i,
h->p_type,  /* Segment type */
@@ -396,16 +393,37 @@ loa

[akaros] [PATCH] vmrunkernel: read the elf, not a binary

2016-10-31 Thread Ronald G. Minnich
This has been used to boot a full Linux kernel environment
to multiuser.

Change-Id: I12c399aafd30cdf05208831ca30129753f027f2a
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 tests/vmm/Makefrag  |   2 +-
 tests/vmm/vmrunkernel.c | 192 +++-
 2 files changed, 142 insertions(+), 52 deletions(-)

diff --git a/tests/vmm/Makefrag b/tests/vmm/Makefrag
index 4208f63..49eb20f 100644
--- a/tests/vmm/Makefrag
+++ b/tests/vmm/Makefrag
@@ -4,7 +4,7 @@ VMM_TESTS_CFLAGS += $(CFLAGS_TESTS)
 
 ALL_VMM_TEST_FILES := $(wildcard $(VMM_TESTS_DIR)/*.c)
 
-VMM_TESTS_LDLIBS := $(TESTS_LDLIBS)
+VMM_TESTS_LDLIBS := $(TESTS_LDLIBS) -lelf
 
 VMM_TESTS_SRCS := $(ALL_VMM_TEST_FILES)
 
diff --git a/tests/vmm/vmrunkernel.c b/tests/vmm/vmrunkernel.c
index ea2ac5a..5f2787f 100644
--- a/tests/vmm/vmrunkernel.c
+++ b/tests/vmm/vmrunkernel.c
@@ -6,7 +6,9 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -36,6 +38,9 @@
 #include 
 #include 
 
+#define DBG(format, ...) if (debug)\
+   fprintf(stderr, format, __VA_ARGS__)
+
 struct virtual_machine local_vm, *vm = _vm;
 
 struct vmm_gpcore_init gpci;
@@ -292,13 +297,13 @@ static uint8_t acpi_tb_checksum(uint8_t *buffer, uint32_t 
length)
 {
uint8_t sum = 0;
uint8_t *end = buffer + length;
-   fprintf(stderr, "tbchecksum %p for %d", buffer, length);
+   DBG("tbchecksum %p for %d", buffer, length);
while (buffer < end) {
-   if (end - buffer < 2)
+   if (0 && end - buffer < 2)
fprintf(stderr, "%02x\n", sum);
sum = (uint8_t)(sum + *(buffer++));
}
-   fprintf(stderr, " is %02x\n", sum);
+   DBG(" is %02x\n", sum);
return (sum);
 }
 
@@ -307,11 +312,11 @@ static void gencsum(uint8_t *target, void *data, int len)
uint8_t csum;
// blast target to zero so it does not get counted
// (it might be in the struct we checksum) And, yes, it is, goodness.
-   fprintf(stderr, "gencsum %p target %p source %d bytes\n", target, data, 
len);
+   DBG("gencsum %p target %p source %d bytes\n", target, data, len);
*target = 0;
csum  = acpi_tb_checksum((uint8_t *)data, len);
*target = ~csum + 1;
-   fprintf(stderr, "Cmoputed is %02x\n", *target);
+   DBG("ACPI: genchecksum: Computed is %02x\n", *target);
 }
 
 static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
@@ -324,15 +329,108 @@ static inline int test_and_set_bit(int nr, volatile 
unsigned long *addr)
return oldbit;
 }
 
-static void pir_dump()
+/* load_kernel loads an ELF file as a kernel. */
+uintptr_t
+load_kernel(char *filename, uintptr_t *kernstart, uintptr_t *kernend)
 {
-   unsigned long *pir_ptr = gpci.posted_irq_desc;
-   int i;
-   fprintf(stderr, "---Begin PIR dump---\n");
-   for (i = 0; i < 8; i++){
-   fprintf(stderr, "Byte %d: 0x%016x\n", i, pir_ptr[i]);
+   Elf64_Ehdr *ehdr;
+   Elf *elf;
+   size_t phnum = 0;
+   Elf64_Phdr *hdrs;
+   int fd;
+
+   elf_version(EV_CURRENT);
+   fd = open(filename, O_RDONLY);
+   if (fd < 0) {
+   fprintf(stderr, "Can't open %s: %r\n", filename);
+   return 0;
+   }
+
+   elf = elf_begin(fd, ELF_C_READ, NULL);
+   if (elf == NULL) {
+   fprintf(stderr, "%s: cannot read %s ELF file.\n", __func__, 
filename);
+   close(fd);
+   return 0;
+   }
+
+   ehdr = elf64_getehdr(elf);
+   if (ehdr == NULL) {
+   fprintf(stderr, "%s: cannot get exec header of %s.\n",
+   __func__, filename);
+   goto fail;
+   }
+   fprintf(stderr, "%s ELF entry point is %p\n", filename, ehdr->e_entry);
+
+   if (elf_getphdrnum(elf, ) < 0) {
+   fprintf(stderr, "%s: cannot get program header num of %s.\n",
+   __func__, filename);
+   goto fail;
}
-   fprintf(stderr, "---End PIR dump---\n");
+   fprintf(stderr, "%s has %d program headers\n", filename, phnum);
+
+   hdrs = elf64_getphdr(elf);
+   if (hdrs == NULL) {
+   fprintf(stderr, "%s: cannot get program headers of %s.\n",
+   __func__, filename);
+   goto fail;
+   }
+
+   for (int i = 0; i < phnum; i++) {
+   size_t tot;
+   Elf64_Phdr *h = [i];
+   uintptr_t pa;
+
+   fprintf(stderr,
+   "%d: type 0x%lx flags 0x%lx  offset 0x%lx vaddr 0x%lx 
paddr 0x%lx size 0x%lx  memsz 0x%lx align 0x%lx\n&q

[akaros] [PATCH] AHCI: Skip device permission check

2016-10-17 Thread Ronald G. Minnich
From: Fergus Simpson 

Permissions are not currently implemented in Akaros. This change simply
makes it so that devpermcheck(...) always returns before throwing an
error that would result in permission being denied. This allows the
device to actually be used while even though permissions have not been
implemented.

Change-Id: Ic2f19071803bba497d916031a22bcbc0b70e8ffd
Signed-off-by: Fergus Simpson 
---
 kern/src/ns/dev.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/kern/src/ns/dev.c b/kern/src/ns/dev.c
index 496cf94..abf683a 100644
--- a/kern/src/ns/dev.c
+++ b/kern/src/ns/dev.c
@@ -388,6 +388,10 @@ devdirread(struct chan *c, char *d, long n,
 void devpermcheck(char *fileuid, uint32_t perm, int omode)
 {
int rwx;
+
+   /* TODO: Implement permission checking, for now permission is always
+* granted. */
+   return;
/* select user, group, or other from the traditional rwxrwxrwx, shifting
 * into the upper-most position */
if (strcmp(current->user, fileuid) == 0)
-- 
2.8.0.rc3.226.g39d4020

-- 
You received this message because you are subscribed to the Google Groups 
"Akaros" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akaros+unsubscr...@googlegroups.com.
To post to this group, send email to akaros@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[akaros] [PATCH] AHCI: Fix hardware address gets in driver

2016-10-17 Thread Ronald G. Minnich
From: Fergus Simpson 

The AHCI driver was using PCIWADDR(ptr) to get the physical address of
memory mapped structs, but only assinging it to the lower 32 bits of
any address field and setting the upper 32-bits to 0. AHCI's memory
mapped structs use 32-bit regsters so both halves are stored in
sequential registers.

This fix uses paddr_low32(ptr) and paddr_hgih32(ptr) to get both halves
of the address.

This should fix issues that occur when a memory mapped struct is outside
of the 32-bit address space.

Change-Id: I8e5ef62c580cc002510ccabadef9c2fcf0153bc8
Signed-off-by: Fergus Simpson 
---
 kern/drivers/dev/sdiahci.c | 32 
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/kern/drivers/dev/sdiahci.c b/kern/drivers/dev/sdiahci.c
index af40b3d..9be3a0c 100644
--- a/kern/drivers/dev/sdiahci.c
+++ b/kern/drivers/dev/sdiahci.c
@@ -336,8 +336,8 @@ static void listsetup(struct aportc *pc, int flags)
list = pc->pm->list;
list->flags = flags | 5;
list->len = 0;
-   list->ctab = PCIWADDR(pc->pm->ctab);
-   list->ctabhi = 0;
+   list->ctab = paddr_low32(pc->pm->ctab);
+   list->ctabhi = paddr_high32(pc->pm->ctab);
 }
 
 static int nop(struct aportc *pc)
@@ -504,8 +504,8 @@ static int ahciidentify0(struct aportc *pc, void *id, int 
atapi)
 
memset(id, 0, 0x100); /* magic */
p = >pm->ctab->prdt;
-   p->dba = PCIWADDR(id);
-   p->dbahi = 0;
+   p->dba = paddr_low32(id);
+   p->dbahi = paddr_high32(id);
p->count = 1 << 31 | (0x200 - 2) | 1;
return ahciwait(pc, 3 * 1000);
 }
@@ -744,10 +744,10 @@ static int ahciconfigdrive(struct drive *d)
 
p->serror = SerrAll;
 
-   p->list = PCIWADDR(pm->list);
-   p->listhi = 0;
-   p->fis = PCIWADDR(pm->fis.base);
-   p->fishi = 0;
+   p->list = paddr_low32(pm->list);
+   p->listhi = paddr_high32(pm->list);
+   p->fis = paddr_low32(pm->fis.base);
+   p->fishi = paddr_high32(pm->fis.base);
p->cmd |= Afre | Ast;
 
/* drive coming up in slumbering? */
@@ -1542,12 +1542,12 @@ static struct alist *ahcibuild(struct drive *d, 
unsigned char *cmd, void *data,
if (dir == Write)
l->flags |= Lwrite;
l->len = 0;
-   l->ctab = PCIWADDR(t);
-   l->ctabhi = 0;
+   l->ctab = paddr_low32(t);
+   l->ctabhi = paddr_high32(t);
 
p = >prdt;
-   p->dba = PCIWADDR(data);
-   p->dbahi = 0;
+   p->dba = paddr_low32(data);
+   p->dbahi = paddr_high32(data);
if (d->unit == NULL)
panic("ahcibuild: NULL d->unit");
p->count = 1 << 31 | (d->unit->secsize * n - 2) | 1;
@@ -1596,15 +1596,15 @@ static struct alist *ahcibuildpkt(struct aportm *pm, 
struct sdreq *r,
if (r->write != 0 && data)
l->flags |= Lwrite;
l->len = 0;
-   l->ctab = PCIWADDR(t);
-   l->ctabhi = 0;
+   l->ctab = paddr_low32(t);
+   l->ctabhi = paddr_high32(t);
 
if (data == 0)
return l;
 
p = >prdt;
-   p->dba = PCIWADDR(data);
-   p->dbahi = 0;
+   p->dba = paddr_low32(data);
+   p->dbahi = paddr_high32(data);
p->count = 1 << 31 | (n - 2) | 1;
 
return l;
-- 
2.8.0.rc3.226.g39d4020

-- 
You received this message because you are subscribed to the Google Groups 
"Akaros" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akaros+unsubscr...@googlegroups.com.
To post to this group, send email to akaros@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[akaros] [PATCH] AHCI: Remove struct typedefs from driver

2016-10-17 Thread Ronald G. Minnich
From: Fergus Simpson 

This makes the driver more consistent with the rest of Akaros's code.

Change-Id: I427e439ee1b34a2bcf5ec86c94e4f590c0681ee5
Signed-off-by: Fergus Simpson 
---
 kern/drivers/dev/sdiahci.c | 22 +++---
 kern/include/ahci.h| 44 ++--
 2 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/kern/drivers/dev/sdiahci.c b/kern/drivers/dev/sdiahci.c
index accb4ca..af40b3d 100644
--- a/kern/drivers/dev/sdiahci.c
+++ b/kern/drivers/dev/sdiahci.c
@@ -175,7 +175,7 @@ struct ctlr {
 
/* virtual register addresses */
uintptr_t mmio;
-   Ahba *hba;
+   struct ahba *hba;
 
/* phyical register address */
uintptr_t physio;
@@ -556,7 +556,7 @@ static int64_t ahciidentify(struct aportc *pc, uint16_t *id)
 
 #if 0
 static int
-ahciquiet(Aport *a)
+ahciquiet(struct aport *a)
 {
uint32_t *p, i;
 
@@ -593,7 +593,7 @@ stop1:
 
 #if 0
 static int
-ahcicomreset(Aportc *pc)
+ahcicomreset(struct aportc *pc)
 {
unsigned char *c;
 
@@ -717,7 +717,7 @@ static void ahciwakeup(struct aport *p)
 static int ahciconfigdrive(struct drive *d)
 {
char *name;
-   Ahba *h;
+   struct ahba *h;
struct aport *p;
struct aportm *pm;
 
@@ -765,12 +765,12 @@ static int ahciconfigdrive(struct drive *d)
return 0;
 }
 
-static void ahcienable(Ahba *h)
+static void ahcienable(struct ahba *h)
 {
h->ghc |= Hie;
 }
 
-static void ahcidisable(Ahba *h)
+static void ahcidisable(struct ahba *h)
 {
h->ghc &= ~Hie;
 }
@@ -788,10 +788,10 @@ static int countbits(uint32_t u)
 
 static int ahciconf(struct ctlr *ctlr)
 {
-   Ahba *h;
+   struct ahba *h;
uint32_t u;
 
-   h = ctlr->hba = (Ahba *)ctlr->mmio;
+   h = ctlr->hba = (struct ahba *)ctlr->mmio;
u = h->cap;
 
if ((u & Hsam) == 0)
@@ -807,7 +807,7 @@ static int ahciconf(struct ctlr *ctlr)
 
 #if 0
 static int
-ahcihbareset(Ahba *h)
+ahcihbareset(struct ahba *h)
 {
int wait;
 
@@ -2070,7 +2070,7 @@ static struct sdev *iapnp(void)
if (Intel(c) && p->dev_id != 0x2681)
iasetupahci(c);
nunit = ahciconf(c);
-   //  ahcihbareset((Ahba*)c->mmio);
+   //  ahcihbareset((struct ahba*)c->mmio);
if (Intel(c) && iaahcimode(p) == -1)
break;
if (nunit < 1) {
@@ -2309,7 +2309,7 @@ static char *iartopctl(struct sdev *sdev, char *p, char 
*e)
 {
uint32_t cap;
char pr[25];
-   Ahba *hba;
+   struct ahba *hba;
struct ctlr *ctlr;
 
 #define has(x, str)
\
diff --git a/kern/include/ahci.h b/kern/include/ahci.h
index 1931fd2..452d934 100644
--- a/kern/include/ahci.h
+++ b/kern/include/ahci.h
@@ -86,7 +86,7 @@ enum {
Hhr = 1 << 0,  /* hba reset */
 };
 
-typedef struct abha {
+struct ahba {
uint32_t cap;
uint32_t ghc;
uint32_t isr;
@@ -96,7 +96,7 @@ typedef struct abha {
uint32_t cccports;
uint32_t emloc;
uint32_t emctl;
-} Ahba;
+};
 
 enum {
Acpds = 1 << 31, /* cold port detect status */
@@ -187,7 +187,7 @@ enum {
 #define serror scr1
 #define sactive scr3
 
-typedef struct aport {
+struct aport {
uint32_t list; /* PxCLB must be 1kb aligned. */
uint32_t listhi;
uint32_t fis; /* 256-byte aligned */
@@ -206,7 +206,7 @@ typedef struct aport {
uint32_t ntf;
unsigned char res2[8];
uint32_t vendor;
-} Aport;
+};
 
 enum {
/*
@@ -227,14 +227,14 @@ enum {
 };
 
 /* in host's memory; not memory mapped */
-typedef struct afis {
+struct afis {
unsigned char *base;
unsigned char *d;
unsigned char *p;
unsigned char *r;
unsigned char *u;
uint32_t *devicebits;
-} Afis;
+};
 
 enum {
Lprdtl = 1 << 16, /* physical region descriptor table len */
@@ -249,27 +249,27 @@ enum {
 };
 
 /* in hosts memory; memory mapped */
-typedef struct alist {
+struct alist {
uint32_t flags;
uint32_t len;
uint32_t ctab;
uint32_t ctabhi;
unsigned char reserved[16];
-} Alist;
+};
 
-typedef struct aprdt {
+struct aprdt {
uint32_t dba;
uint32_t dbahi;
uint32_t pad;
uint32_t count;
-} Aprdt;
+};
 
-typedef struct actab {
+struct actab {
unsigned char cfis[0x40];
unsigned char atapi[0x10];
unsigned char pad[0x30];
-   Aprdt prdt;
-} Actab;
+   struct aprdt prdt;
+};
 
 enum {
Ferror = 1,
@@ -285,18 +285,18 @@ enum {
Datapi16 = 1 << 5,
 };
 
-typedef struct aportm {
+struct aportm {
qlock_t ql;
struct rendez Rendez;
unsigned char flag;
unsigned char feat;
unsigned char smart;
-   Afis fis;
-   Alist *list;
-

[akaros] [PATCH] Convert the capability device to use SHA1

2016-10-14 Thread Ronald G. Minnich
This involves a minor code change but I take the opportunity
to clean things up, getting rid of files we don't need,
and fixing includes.

Change-Id: Ie9ead4b6a2473d2f25b7b0a777343aef598f8dd9
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 kern/drivers/dev/capability.c   |  15 +-
 kern/include/crypto/2api.h  |   5 +-
 kern/include/crypto/2hmac.h |   1 -
 kern/lib/crypto/2api.c  | 208 
 kern/lib/crypto/2common.c   |   8 +-
 kern/lib/crypto/2crc8.c |   4 +-
 kern/lib/crypto/2hmac.c |   6 +-
 kern/lib/crypto/2misc.c | 408 
 kern/lib/crypto/2nvstorage.c| 370 
 kern/lib/crypto/2rsa.c  |   8 +-
 kern/lib/crypto/2secdata.c  |  10 +-
 kern/lib/crypto/2secdatak.c |  10 +-
 kern/lib/crypto/2sha1.c |   6 +-
 kern/lib/crypto/2sha512.c   |   6 +-
 kern/lib/crypto/2sha_utility.c  |   6 +-
 kern/lib/crypto/2stub.c |  59 --
 kern/lib/crypto/2tpm_bootmode.c |  54 --
 kern/lib/crypto/Kbuild  |  18 +-
 18 files changed, 54 insertions(+), 1148 deletions(-)
 delete mode 100644 kern/lib/crypto/2api.c
 delete mode 100644 kern/lib/crypto/2misc.c
 delete mode 100644 kern/lib/crypto/2nvstorage.c
 delete mode 100644 kern/lib/crypto/2stub.c
 delete mode 100644 kern/lib/crypto/2tpm_bootmode.c

diff --git a/kern/drivers/dev/capability.c b/kern/drivers/dev/capability.c
index ab0cd95..f974fff 100644
--- a/kern/drivers/dev/capability.c
+++ b/kern/drivers/dev/capability.c
@@ -21,8 +21,13 @@
 #include 
 #include 
 
+#include 
+#include 
+#include 
+#include 
+
 enum {
-   Hashlen = 20, // SHA1dlen,
+   Hashlen = VB2_SHA256_BLOCK_SIZE,
Maxhash = 256,
 };
 
@@ -197,6 +202,7 @@ static long capwrite(struct chan *c, void *va, long n, 
int64_t m)
uint8_t hash[Hashlen];
char *key, *from, *to;
char err[256];
+   int ret;
ERRSTACK(1);
 
switch ((uint32_t)c->qid.path) {
@@ -226,9 +232,10 @@ static long capwrite(struct chan *c, void *va, long n, 
int64_t m)
error(EIO, "short read: Quse");
*key++ = 0;
 
-   panic("No way to hash");
-   //hmac_sha1((uint8_t *)from, strlen(from), (uint8_t *)key, 
strlen(key),
-   //hash, NULL);
+   ret = hmac(VB2_ALG_RSA1024_SHA256, key, strlen(key),
+  from, strlen(from), hash, sizeof(hash));
+   if (ret)
+   error(EINVAL,"HMAC failed");
 
p = remcap(hash);
if (p == NULL) {
diff --git a/kern/include/crypto/2api.h b/kern/include/crypto/2api.h
index e4c6ad0..23d413d 100644
--- a/kern/include/crypto/2api.h
+++ b/kern/include/crypto/2api.h
@@ -17,8 +17,8 @@
  *  must be done elsewhere, and VB2_NV_DEBUG_RESET_MODE is ignored.
  */
 
-#ifndef VBOOT_2_API_H_
-#define VBOOT_2_API_H_
+#pragma once
+
 #include 
 
 #include "2common.h"
@@ -658,4 +658,3 @@ int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, 
uint32_t size);
  */
 int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size);
 
-#endif  /* VBOOT_2_API_H_ */
diff --git a/kern/include/crypto/2hmac.h b/kern/include/crypto/2hmac.h
index 7209a38..ad7dfea 100644
--- a/kern/include/crypto/2hmac.h
+++ b/kern/include/crypto/2hmac.h
@@ -25,4 +25,3 @@ int hmac(enum vb2_hash_algorithm alg,
 const void *msg, uint32_t msg_size,
 uint8_t *mac, uint32_t mac_size);
 
-#endif
diff --git a/kern/lib/crypto/2api.c b/kern/lib/crypto/2api.c
deleted file mode 100644
index c12a805..000
--- a/kern/lib/crypto/2api.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Externally-callable APIs
- * (Firmware portion)
- */
-
-#include "2sysincludes.h"
-#include "2api.h"
-#include "2common.h"
-#include "2misc.h"
-#include "2nvstorage.h"
-#include "2secdata.h"
-#include "2sha.h"
-#include "2rsa.h"
-#include "2tpm_bootmode.h"
-
-int vb2api_secdata_check(const struct vb2_context *ctx)
-{
-   return vb2_secdata_check_crc(ctx);
-}
-
-int vb2api_secdata_create(struct vb2_context *ctx)
-{
-   return vb2_secdata_create(ctx);
-}
-
-void vb2api_fail(struct vb2_context *ctx, uint8_t reason, uint8_t subcode)
-{
-   /* Initialize the vboot context if it hasn't been yet */
-   vb2_init_context(ctx);
-
-   vb2_fail(ctx, reason, subcode);
-}
-
-int vb2api_fw_phase1(struct vb2_context *ctx)
-{
-   int rv;
-
-   /* Initialize the vboot context if it hasn't been yet */
-   vb2_init_context(ctx);
-
-   /* Initialize NV context */
-   vb2_nv_init(ctx);
-
-   /*
-* Handle caller-requested reboot due

[akaros] [PATCH 1/4] add the capability device from Harvey (from Plan 9)

2016-10-14 Thread Ronald G. Minnich
Change-Id: If159e72517809eedd0d1e98271e3dde57e035090
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 kern/drivers/dev/capability.c | 295 ++
 1 file changed, 295 insertions(+)
 create mode 100644 kern/drivers/dev/capability.c

diff --git a/kern/drivers/dev/capability.c b/kern/drivers/dev/capability.c
new file mode 100644
index 000..53a59af
--- /dev/null
+++ b/kern/drivers/dev/capability.c
@@ -0,0 +1,295 @@
+/*
+ * This file is part of the UCB release of Plan 9. It is subject to the license
+ * terms in the LICENSE file found in the top-level directory of this
+ * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
+ * part of the UCB release of Plan 9, including this file, may be copied,
+ * modified, propagated, or distributed except according to the terms contained
+ * in the LICENSE file.
+ */
+
+#include   "u.h"
+#include   "../port/lib.h"
+#include   "mem.h"
+#include   "dat.h"
+#include   "fns.h"
+#include   "../port/error.h"
+
+#include   
+
+enum
+{
+   Hashlen=SHA1dlen,
+   Maxhash=256,
+};
+
+/*
+ *  if a process knows cap->cap, it can change user
+ *  to capabilty->user.
+ */
+typedef struct Caphash Caphash;
+struct Caphash
+{
+   Caphash *next;
+   charhash[Hashlen];
+};
+
+struct
+{
+   QLock QLock;
+   Caphash *first;
+   int nhash;
+} capalloc;
+
+enum
+{
+   Qdir,
+   Qhash,
+   Quse,
+};
+
+/* caphash must be last */
+Dirtab capdir[] =
+{
+   ".",{Qdir,0,QTDIR}, 0,  DMDIR|0500,
+   "capuse",   {Quse}, 0,  0222,
+   "caphash",  {Qhash},0,  0200,
+};
+int ncapdir = nelem(capdir);
+
+static Chan*
+capattach(char *spec)
+{
+   return devattach(L'¤', spec);
+}
+
+static Walkqid*
+capwalk(Chan *c, Chan *nc, char **name, int nname)
+{
+   return devwalk(c, nc, name, nname, capdir, ncapdir, devgen);
+}
+
+static void
+capremove(Chan *c)
+{
+   if(iseve() && c->qid.path == Qhash)
+   ncapdir = nelem(capdir)-1;
+   else
+   error(Eperm);
+}
+
+
+static int32_t
+capstat(Chan *c, uint8_t *db, int32_t n)
+{
+   return devstat(c, db, n, capdir, ncapdir, devgen);
+}
+
+/*
+ *  if the stream doesn't exist, create it
+ */
+static Chan*
+capopen(Chan *c, int omode)
+{
+   if(c->qid.type & QTDIR){
+   if(omode != OREAD)
+   error(Ebadarg);
+   c->mode = omode;
+   c->flag |= COPEN;
+   c->offset = 0;
+   return c;
+   }
+
+   switch((uint32_t)c->qid.path){
+   case Qhash:
+   if(!iseve())
+   error(Eperm);
+   break;
+   }
+
+   c->mode = openmode(omode);
+   c->flag |= COPEN;
+   c->offset = 0;
+   return c;
+}
+
+/*
+static char*
+hashstr(uchar *hash)
+{
+   static char buf[2*Hashlen+1];
+   int i;
+
+   for(i = 0; i < Hashlen; i++)
+   sprint(buf+2*i, "%2.2x", hash[i]);
+   buf[2*Hashlen] = 0;
+   return buf;
+}
+ */
+
+static Caphash*
+remcap(uint8_t *hash)
+{
+   Caphash *t, **l;
+
+   qlock();
+
+   /* find the matching capability */
+   for(l =  *l != nil;){
+   t = *l;
+   if(memcmp(hash, t->hash, Hashlen) == 0)
+   break;
+   l = >next;
+   }
+   t = *l;
+   if(t != nil){
+   capalloc.nhash--;
+   *l = t->next;
+   }
+   qunlock();
+
+   return t;
+}
+
+/* add a capability, throwing out any old ones */
+static void
+addcap(uint8_t *hash)
+{
+   Caphash *p, *t, **l;
+
+   p = smalloc(sizeof *p);
+   memmove(p->hash, hash, Hashlen);
+   p->next = nil;
+
+   qlock();
+
+   /* trim extras */
+   while(capalloc.nhash >= Maxhash){
+   t = capalloc.first;
+   if(t == nil)
+   panic("addcap");
+   capalloc.first = t->next;
+   free(t);
+   capalloc.nhash--;
+   }
+
+   /* add new one */
+   for(l =  *l != nil; l = &(*l)->next)
+   ;
+   *l = p;
+   capalloc.nhash++;
+
+   qunlock();
+}
+
+static void
+capclose(Chan* c)
+{
+}
+
+static int32_t
+capread(Chan *c, void *va, int32_t n, int64_t m)
+{
+   switch((uint32_t)c->qid.path){
+   case Qdir:
+   return devdirread(c, va, n, capdir, ncapdir, devgen);
+
+   default:
+   error(Eperm);
+   break;
+   }
+   return n;
+}
+
+static int32_t
+capwrite(Chan *c, void *va, int32_t n, int64_t m)
+{
+   Caphash *p;
+   char *cp;
+   uint8_t hash[Hashlen];
+   c

[akaros] [PATCH 3/4] capability: run scripts/PLAN9 on capability device

2016-10-14 Thread Ronald G. Minnich
Change-Id: I55dbed3e636730c4768c61168f22c61c9e2c82fb
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 kern/drivers/dev/capability.c | 108 +-
 1 file changed, 64 insertions(+), 44 deletions(-)

diff --git a/kern/drivers/dev/capability.c b/kern/drivers/dev/capability.c
index a3bafd7..9bd487c 100644
--- a/kern/drivers/dev/capability.c
+++ b/kern/drivers/dev/capability.c
@@ -7,14 +7,33 @@
  * in the LICENSE file.
  */
 
-#include "../port/error.h"
-#include "../port/lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "mem.h"
-#include "u.h"
-
-#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 enum {
Hashlen = SHA1dlen,
@@ -32,7 +51,7 @@ struct Caphash {
 };
 
 struct {
-   QLock QLock;
+   qlock_t qlock_t qlock;
Caphash *first;
int nhash;
 } capalloc;
@@ -44,31 +63,32 @@ enum {
 };
 
 /* caphash must be last */
-Dirtab capdir[] = {
+struct dirtab capdir[] = {
 ".",   {Qdir, 0, QTDIR}, 0, DMDIR | 0500, "capuse", {Quse}, 0, 0222,
 "caphash", {Qhash},  0, 0200,
 };
-int ncapdir = nelem(capdir);
+int ncapdir = ARRAY_SIZE(capdir);
 
-static Chan *capattach(char *spec)
+static struct chan *capattach(char *spec)
 {
return devattach(L'¤', spec);
 }
 
-static Walkqid *capwalk(Chan *c, Chan *nc, char **name, int nname)
+static struct walkqid *capwalk(struct chan *c, struct chan *nc, char **name,
+   int nname)
 {
return devwalk(c, nc, name, nname, capdir, ncapdir, devgen);
 }
 
-static void capremove(Chan *c)
+static void capremove(struct chan *c)
 {
if (iseve() && c->qid.path == Qhash)
-   ncapdir = nelem(capdir) - 1;
+   ncapdir = ARRAY_SIZE(capdir) - 1;
else
error(Eperm);
 }
 
-static int32_t capstat(Chan *c, uint8_t *db, int32_t n)
+static int32_t capstat(struct chan *c, uint8_t *db, int32_t n)
 {
return devstat(c, db, n, capdir, ncapdir, devgen);
 }
@@ -76,7 +96,7 @@ static int32_t capstat(Chan *c, uint8_t *db, int32_t n)
 /*
  *  if the stream doesn't exist, create it
  */
-static Chan *capopen(Chan *c, int omode)
+static struct chan *capopen(struct chan *c, int omode)
 {
if (c->qid.type & QTDIR) {
if (omode != OREAD)
@@ -102,7 +122,7 @@ static Chan *capopen(Chan *c, int omode)
 
 /*
 static char*
-hashstr(uchar *hash)
+hashstr(uint8_t *hash)
 {
 static char buf[2*Hashlen+1];
 int i;
@@ -118,21 +138,21 @@ static Caphash *remcap(uint8_t *hash)
 {
Caphash *t, **l;
 
-   qlock();
+   qlock(&()->qlock);
 
/* find the matching capability */
-   for (l =  *l != nil;) {
+   for (l =  *l != NULL;) {
t = *l;
if (memcmp(hash, t->hash, Hashlen) == 0)
break;
l = >next;
}
t = *l;
-   if (t != nil) {
+   if (t != NULL) {
capalloc.nhash--;
*l = t->next;
}
-   qunlock();
+   qunlock(&()->qlock);
 
return t;
 }
@@ -142,36 +162,36 @@ static void addcap(uint8_t *hash)
 {
Caphash *p, *t, **l;
 
-   p = smalloc(sizeof *p);
+   p = kzmalloc(sizeof *p, 0);
memmove(p->hash, hash, Hashlen);
-   p->next = nil;
+   p->next = NULL;
 
-   qlock();
+   qlock(&()->qlock);
 
/* trim extras */
while (capalloc.nhash >= Maxhash) {
t = capalloc.first;
-   if (t == nil)
+   if (t == NULL)
panic("addcap");
capalloc.first = t->next;
-   free(t);
+   kfree(t);
capalloc.nhash--;
}
 
/* add new one */
-   for (l =  *l != nil; l = &(*l)->next)
+   for (l =  *l != NULL; l = &(*l)->next)
;
*l = p;
capalloc.nhash++;
 
-   qunlock();
+   qunlock(&()->qlock);
 }
 
-static void capclose(Chan *c)
+static void capclose(struct chan *c)
 {
 }
 
-static int32_t capread(Chan *c, void *va, int32_t n, int64_t m)
+static int32_t capread(struct chan *c, void *va, int32_t n, int64_t m)
 {
switch ((uint32_t)c->qid.path) {
case Qdir:
@@ -184,14 +204,14 @@ static int32_t capread(Chan *c, void *va, int32_t n, 
int64_t m)
return n;
 }
 
-static int32_t capwrite(Chan *c, void *va, int32_t n, int64_t m)
+static int32_t capwrite(struct chan *c, void *va, int32_t n, int64_t m)
 {
Caphash *p;
char *cp;
uint8_t hash[Hashlen];
char *key, *f

[akaros] [PATCH 2/4] capability: clang-format the capability device

2016-10-14 Thread Ronald G. Minnich
Change-Id: I3e99b8317fc57fbfb775fd4242e5fb2f36411a46
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 kern/drivers/dev/capability.c | 181 +++---
 1 file changed, 81 insertions(+), 100 deletions(-)

diff --git a/kern/drivers/dev/capability.c b/kern/drivers/dev/capability.c
index 53a59af..a3bafd7 100644
--- a/kern/drivers/dev/capability.c
+++ b/kern/drivers/dev/capability.c
@@ -7,79 +7,68 @@
  * in the LICENSE file.
  */
 
-#include   "u.h"
-#include   "../port/lib.h"
-#include   "mem.h"
-#include   "dat.h"
-#include   "fns.h"
-#include   "../port/error.h"
-
-#include   
-
-enum
-{
-   Hashlen=SHA1dlen,
-   Maxhash=256,
+#include "../port/error.h"
+#include "../port/lib.h"
+#include "dat.h"
+#include "fns.h"
+#include "mem.h"
+#include "u.h"
+
+#include 
+
+enum {
+   Hashlen = SHA1dlen,
+   Maxhash = 256,
 };
 
 /*
  *  if a process knows cap->cap, it can change user
  *  to capabilty->user.
  */
-typedef struct Caphash Caphash;
-struct Caphash
-{
-   Caphash *next;
-   charhash[Hashlen];
+typedef struct Caphash Caphash;
+struct Caphash {
+   Caphash *next;
+   char hash[Hashlen];
 };
 
-struct
-{
+struct {
QLock QLock;
-   Caphash *first;
-   int nhash;
+   Caphash *first;
+   int nhash;
 } capalloc;
 
-enum
-{
+enum {
Qdir,
Qhash,
Quse,
 };
 
 /* caphash must be last */
-Dirtab capdir[] =
-{
-   ".",{Qdir,0,QTDIR}, 0,  DMDIR|0500,
-   "capuse",   {Quse}, 0,  0222,
-   "caphash",  {Qhash},0,  0200,
+Dirtab capdir[] = {
+".",   {Qdir, 0, QTDIR}, 0, DMDIR | 0500, "capuse", {Quse}, 0, 0222,
+"caphash", {Qhash},  0, 0200,
 };
 int ncapdir = nelem(capdir);
 
-static Chan*
-capattach(char *spec)
+static Chan *capattach(char *spec)
 {
return devattach(L'¤', spec);
 }
 
-static Walkqid*
-capwalk(Chan *c, Chan *nc, char **name, int nname)
+static Walkqid *capwalk(Chan *c, Chan *nc, char **name, int nname)
 {
return devwalk(c, nc, name, nname, capdir, ncapdir, devgen);
 }
 
-static void
-capremove(Chan *c)
+static void capremove(Chan *c)
 {
-   if(iseve() && c->qid.path == Qhash)
-   ncapdir = nelem(capdir)-1;
+   if (iseve() && c->qid.path == Qhash)
+   ncapdir = nelem(capdir) - 1;
else
error(Eperm);
 }
 
-
-static int32_t
-capstat(Chan *c, uint8_t *db, int32_t n)
+static int32_t capstat(Chan *c, uint8_t *db, int32_t n)
 {
return devstat(c, db, n, capdir, ncapdir, devgen);
 }
@@ -87,11 +76,10 @@ capstat(Chan *c, uint8_t *db, int32_t n)
 /*
  *  if the stream doesn't exist, create it
  */
-static Chan*
-capopen(Chan *c, int omode)
+static Chan *capopen(Chan *c, int omode)
 {
-   if(c->qid.type & QTDIR){
-   if(omode != OREAD)
+   if (c->qid.type & QTDIR) {
+   if (omode != OREAD)
error(Ebadarg);
c->mode = omode;
c->flag |= COPEN;
@@ -99,9 +87,9 @@ capopen(Chan *c, int omode)
return c;
}
 
-   switch((uint32_t)c->qid.path){
+   switch ((uint32_t)c->qid.path) {
case Qhash:
-   if(!iseve())
+   if (!iseve())
error(Eperm);
break;
}
@@ -116,32 +104,31 @@ capopen(Chan *c, int omode)
 static char*
 hashstr(uchar *hash)
 {
-   static char buf[2*Hashlen+1];
-   int i;
+static char buf[2*Hashlen+1];
+int i;
 
-   for(i = 0; i < Hashlen; i++)
-   sprint(buf+2*i, "%2.2x", hash[i]);
-   buf[2*Hashlen] = 0;
-   return buf;
+for(i = 0; i < Hashlen; i++)
+sprint(buf+2*i, "%2.2x", hash[i]);
+buf[2*Hashlen] = 0;
+return buf;
 }
  */
 
-static Caphash*
-remcap(uint8_t *hash)
+static Caphash *remcap(uint8_t *hash)
 {
Caphash *t, **l;
 
qlock();
 
/* find the matching capability */
-   for(l =  *l != nil;){
+   for (l =  *l != nil;) {
t = *l;
-   if(memcmp(hash, t->hash, Hashlen) == 0)
+   if (memcmp(hash, t->hash, Hashlen) == 0)
break;
l = >next;
}
t = *l;
-   if(t != nil){
+   if (t != nil) {
capalloc.nhash--;
*l = t->next;
}
@@ -151,8 +138,7 @@ remcap(uint8_t *hash)
 }
 
 /* add a capability, throwing out any old ones */
-static void
-addcap(uint8_t *hash)
+static void addcap(uint8_t *hash)
 {
Caphash *p, *t, **l;
 
@@ -163,9 +149,9 @@ addcap(

[akaros] [PATCH 3/3] crypto: get sha256 support to build.

2016-10-13 Thread Ronald G. Minnich
For now we'll just go with the sh256.c. That said,
we'll keep the other bits in here. Sooner or later we may
need the other crypto functions. Note these are not compiled
in conditionally.

We should consider removing the conditional compiling
of the unrolled code; we don't have space constraints of firmware.

Change-Id: Ic792cf2b89fa4f01a94c420eb3c620b62c7bf2a9
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 kern/include/crypto/2common.h   |  4 +---
 kern/include/crypto/2crc8.h |  4 +---
 kern/include/crypto/2crypto.h   |  4 +---
 kern/include/crypto/2fw_hash_tags.h |  4 +---
 kern/include/crypto/2hmac.h |  3 +--
 kern/include/crypto/2id.h   |  4 +---
 kern/include/crypto/2misc.h |  4 +---
 kern/include/crypto/2nvstorage.h|  4 +---
 kern/include/crypto/2nvstorage_fields.h |  4 +---
 kern/include/crypto/2recovery_reasons.h |  4 +---
 kern/include/crypto/2rsa.h  |  4 +---
 kern/include/crypto/2secdata.h  |  4 +---
 kern/include/crypto/2sha.h  |  4 +---
 kern/include/crypto/2struct.h   |  4 +---
 kern/include/crypto/2sysincludes.h  | 35 -
 kern/include/crypto/2tpm_bootmode.h |  4 +---
 kern/lib/Kbuild |  1 +
 kern/lib/crypto/2sha256.c   |  6 +++---
 18 files changed, 40 insertions(+), 61 deletions(-)

diff --git a/kern/include/crypto/2common.h b/kern/include/crypto/2common.h
index 4622ab1..46c9a36 100644
--- a/kern/include/crypto/2common.h
+++ b/kern/include/crypto/2common.h
@@ -5,8 +5,7 @@
  * Common functions between firmware and kernel verified boot.
  */
 
-#ifndef VBOOT_REFERENCE_VBOOT_2COMMON_H_
-#define VBOOT_REFERENCE_VBOOT_2COMMON_H_
+#pragma once
 
 #include "2api.h"
 #include "2return_codes.h"
@@ -194,4 +193,3 @@ const struct vb2_id *vb2_hash_id(enum vb2_hash_algorithm 
hash_alg);
 /* Size of work buffer sufficient for vb2_verify_fw_preamble() worst case. */
 #define VB2_VERIFY_FIRMWARE_PREAMBLE_WORKBUF_BYTES 
VB2_VERIFY_DATA_WORKBUF_BYTES
 
-#endif  /* VBOOT_REFERENCE_VBOOT_2COMMON_H_ */
diff --git a/kern/include/crypto/2crc8.h b/kern/include/crypto/2crc8.h
index f01eabd..a846e5a 100644
--- a/kern/include/crypto/2crc8.h
+++ b/kern/include/crypto/2crc8.h
@@ -5,8 +5,7 @@
  * Very simple 8-bit CRC function.
  */
 
-#ifndef VBOOT_REFERENCE_2_CRC8_H_
-#define VBOOT_REFERENCE_2_CRC8_H_
+#pragma once
 
 /**
  * Calculate CRC-8 of the data, using x^8 + x^2 + x + 1 polynomial.
@@ -17,4 +16,3 @@
  */
 uint8_t vb2_crc8(const void *data, uint32_t size);
 
-#endif /* VBOOT_REFERENCE_2_CRC8_H_ */
diff --git a/kern/include/crypto/2crypto.h b/kern/include/crypto/2crypto.h
index c1f225d..461c459 100644
--- a/kern/include/crypto/2crypto.h
+++ b/kern/include/crypto/2crypto.h
@@ -5,8 +5,7 @@
  * Crypto constants for verified boot
  */
 
-#ifndef VBOOT_REFERENCE_VBOOT_2CRYPTO_H_
-#define VBOOT_REFERENCE_VBOOT_2CRYPTO_H_
+#pragma once
 #include 
 
 /* Verified boot crypto algorithms */
@@ -62,4 +61,3 @@ enum vb2_hash_algorithm {
VB2_HASH_ALG_COUNT,
 };
 
-#endif /* VBOOT_REFERENCE_VBOOT_2CRYPTO_H_ */
diff --git a/kern/include/crypto/2fw_hash_tags.h 
b/kern/include/crypto/2fw_hash_tags.h
index 0c061f5..d6e366a 100644
--- a/kern/include/crypto/2fw_hash_tags.h
+++ b/kern/include/crypto/2fw_hash_tags.h
@@ -5,8 +5,7 @@
  * Firmware hash tags for verified boot
  */
 
-#ifndef VBOOT_REFERENCE_VBOOT_2FW_HASH_TAGS_H_
-#define VBOOT_REFERENCE_VBOOT_2FW_HASH_TAGS_H_
+#pragma once
 #include 
 
 /*
@@ -37,4 +36,3 @@ enum vb2_hash_tag {
VB2_HASH_TAG_CALLER_BASE = 0x4000
 };
 
-#endif /* VBOOT_REFERENCE_VBOOT_2FW_HASH_TAGS_H_ */
diff --git a/kern/include/crypto/2hmac.h b/kern/include/crypto/2hmac.h
index 1df1939..7209a38 100644
--- a/kern/include/crypto/2hmac.h
+++ b/kern/include/crypto/2hmac.h
@@ -3,8 +3,7 @@
  * found in the LICENSE file.
  */
 
-#ifndef VBOOT_REFERENCE_VBOOT_2HMAC_H_
-#define VBOOT_REFERENCE_VBOOT_2HMAC_H_
+#pragma once
 
 #include 
 #include "2crypto.h"
diff --git a/kern/include/crypto/2id.h b/kern/include/crypto/2id.h
index 03f6d96..12f5059 100644
--- a/kern/include/crypto/2id.h
+++ b/kern/include/crypto/2id.h
@@ -8,8 +8,7 @@
  * resistant to collisions and easy to compare.
  */
 
-#ifndef VBOOT_REFERENCE_VBOOT_2ID_H_
-#define VBOOT_REFERENCE_VBOOT_2ID_H_
+#pragma once
 #include 
 
 #define VB2_ID_NUM_BYTES 20
@@ -25,4 +24,3 @@ struct vb2_id {
 #define VB2_ID_NONE_SHA256 {{0x02, 0x56,}}
 #define VB2_ID_NONE_SHA512 {{0x05, 0x12,}}
 
-#endif  /* VBOOT_REFERENCE_VBOOT_2ID_H_ */
diff --git a/kern/include/crypto/2misc.h b/kern/include/crypto/2misc.h
index f562fad..fdc252d 100644
--- a/kern/include/crypto/2misc.h
+++ b/kern/include/crypto/2misc.h
@@ -5,8 +5,7 @@
  * Misc functions which need access to vb2_context but are not public APIs
  */
 
-#ifndef VBOOT_REFERENCE_VBOOT_2MISC_H_
-#define VBOOT_REFERENCE_VBOOT_2MISC_H_
+#pragma once
 
 #includ

[akaros] [PATCH 2/4] capability: clang-format the capability device

2016-10-13 Thread Ronald G. Minnich
Change-Id: I3e99b8317fc57fbfb775fd4242e5fb2f36411a46
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 kern/drivers/dev/capability.c | 181 +++---
 1 file changed, 81 insertions(+), 100 deletions(-)

diff --git a/kern/drivers/dev/capability.c b/kern/drivers/dev/capability.c
index 53a59af..a3bafd7 100644
--- a/kern/drivers/dev/capability.c
+++ b/kern/drivers/dev/capability.c
@@ -7,79 +7,68 @@
  * in the LICENSE file.
  */
 
-#include   "u.h"
-#include   "../port/lib.h"
-#include   "mem.h"
-#include   "dat.h"
-#include   "fns.h"
-#include   "../port/error.h"
-
-#include   
-
-enum
-{
-   Hashlen=SHA1dlen,
-   Maxhash=256,
+#include "../port/error.h"
+#include "../port/lib.h"
+#include "dat.h"
+#include "fns.h"
+#include "mem.h"
+#include "u.h"
+
+#include 
+
+enum {
+   Hashlen = SHA1dlen,
+   Maxhash = 256,
 };
 
 /*
  *  if a process knows cap->cap, it can change user
  *  to capabilty->user.
  */
-typedef struct Caphash Caphash;
-struct Caphash
-{
-   Caphash *next;
-   charhash[Hashlen];
+typedef struct Caphash Caphash;
+struct Caphash {
+   Caphash *next;
+   char hash[Hashlen];
 };
 
-struct
-{
+struct {
QLock QLock;
-   Caphash *first;
-   int nhash;
+   Caphash *first;
+   int nhash;
 } capalloc;
 
-enum
-{
+enum {
Qdir,
Qhash,
Quse,
 };
 
 /* caphash must be last */
-Dirtab capdir[] =
-{
-   ".",{Qdir,0,QTDIR}, 0,  DMDIR|0500,
-   "capuse",   {Quse}, 0,  0222,
-   "caphash",  {Qhash},0,  0200,
+Dirtab capdir[] = {
+".",   {Qdir, 0, QTDIR}, 0, DMDIR | 0500, "capuse", {Quse}, 0, 0222,
+"caphash", {Qhash},  0, 0200,
 };
 int ncapdir = nelem(capdir);
 
-static Chan*
-capattach(char *spec)
+static Chan *capattach(char *spec)
 {
return devattach(L'¤', spec);
 }
 
-static Walkqid*
-capwalk(Chan *c, Chan *nc, char **name, int nname)
+static Walkqid *capwalk(Chan *c, Chan *nc, char **name, int nname)
 {
return devwalk(c, nc, name, nname, capdir, ncapdir, devgen);
 }
 
-static void
-capremove(Chan *c)
+static void capremove(Chan *c)
 {
-   if(iseve() && c->qid.path == Qhash)
-   ncapdir = nelem(capdir)-1;
+   if (iseve() && c->qid.path == Qhash)
+   ncapdir = nelem(capdir) - 1;
else
error(Eperm);
 }
 
-
-static int32_t
-capstat(Chan *c, uint8_t *db, int32_t n)
+static int32_t capstat(Chan *c, uint8_t *db, int32_t n)
 {
return devstat(c, db, n, capdir, ncapdir, devgen);
 }
@@ -87,11 +76,10 @@ capstat(Chan *c, uint8_t *db, int32_t n)
 /*
  *  if the stream doesn't exist, create it
  */
-static Chan*
-capopen(Chan *c, int omode)
+static Chan *capopen(Chan *c, int omode)
 {
-   if(c->qid.type & QTDIR){
-   if(omode != OREAD)
+   if (c->qid.type & QTDIR) {
+   if (omode != OREAD)
error(Ebadarg);
c->mode = omode;
c->flag |= COPEN;
@@ -99,9 +87,9 @@ capopen(Chan *c, int omode)
return c;
}
 
-   switch((uint32_t)c->qid.path){
+   switch ((uint32_t)c->qid.path) {
case Qhash:
-   if(!iseve())
+   if (!iseve())
error(Eperm);
break;
}
@@ -116,32 +104,31 @@ capopen(Chan *c, int omode)
 static char*
 hashstr(uchar *hash)
 {
-   static char buf[2*Hashlen+1];
-   int i;
+static char buf[2*Hashlen+1];
+int i;
 
-   for(i = 0; i < Hashlen; i++)
-   sprint(buf+2*i, "%2.2x", hash[i]);
-   buf[2*Hashlen] = 0;
-   return buf;
+for(i = 0; i < Hashlen; i++)
+sprint(buf+2*i, "%2.2x", hash[i]);
+buf[2*Hashlen] = 0;
+return buf;
 }
  */
 
-static Caphash*
-remcap(uint8_t *hash)
+static Caphash *remcap(uint8_t *hash)
 {
Caphash *t, **l;
 
qlock();
 
/* find the matching capability */
-   for(l =  *l != nil;){
+   for (l =  *l != nil;) {
t = *l;
-   if(memcmp(hash, t->hash, Hashlen) == 0)
+   if (memcmp(hash, t->hash, Hashlen) == 0)
break;
l = >next;
}
t = *l;
-   if(t != nil){
+   if (t != nil) {
capalloc.nhash--;
*l = t->next;
}
@@ -151,8 +138,7 @@ remcap(uint8_t *hash)
 }
 
 /* add a capability, throwing out any old ones */
-static void
-addcap(uint8_t *hash)
+static void addcap(uint8_t *hash)
 {
Caphash *p, *t, **l;
 
@@ -163,9 +149,9 @@ addcap(

[akaros] [PATCH 4/4] capability device: get it to compile

2016-10-13 Thread Ronald G. Minnich
We need to do something about the use of sha1.

Change-Id: I80795609ccea1ac629cb7b9d4a95040cc040d76a
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 kern/drivers/dev/Kbuild   |   1 +
 kern/drivers/dev/capability.c | 155 --
 kern/include/env.h|   2 +-
 kern/include/ns.h |   2 +-
 4 files changed, 77 insertions(+), 83 deletions(-)

diff --git a/kern/drivers/dev/Kbuild b/kern/drivers/dev/Kbuild
index 183bddd..9ea2b05 100644
--- a/kern/drivers/dev/Kbuild
+++ b/kern/drivers/dev/Kbuild
@@ -1,5 +1,6 @@
 obj-y  += acpi.o
 obj-y  += alarm.o
+obj-y  += capability.o
 obj-y  += coreboot.o
 obj-y  += cons.o
 obj-y  += ether.o
diff --git a/kern/drivers/dev/capability.c b/kern/drivers/dev/capability.c
index 9bd487c..bb4fcdf 100644
--- a/kern/drivers/dev/capability.c
+++ b/kern/drivers/dev/capability.c
@@ -21,22 +21,8 @@
 #include 
 #include 
 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
 enum {
-   Hashlen = SHA1dlen,
+   Hashlen = 20, // SHA1dlen,
Maxhash = 256,
 };
 
@@ -44,15 +30,14 @@ enum {
  *  if a process knows cap->cap, it can change user
  *  to capabilty->user.
  */
-typedef struct Caphash Caphash;
 struct Caphash {
-   Caphash *next;
+   struct Caphash *next;
char hash[Hashlen];
 };
 
 struct {
-   qlock_t qlock_t qlock;
-   Caphash *first;
+   qlock_t qlock;
+   struct Caphash *first;
int nhash;
 } capalloc;
 
@@ -64,18 +49,19 @@ enum {
 
 /* caphash must be last */
 struct dirtab capdir[] = {
-".",   {Qdir, 0, QTDIR}, 0, DMDIR | 0500, "capuse", {Quse}, 0, 0222,
-"caphash", {Qhash},  0, 0200,
+   {".",   {Qdir, 0, QTDIR}, 0, DMDIR | 0500},
+   {"capuse",  {Quse}, 0, 0222,},
+   {"caphash", {Qhash},  0, 0200,},
 };
 int ncapdir = ARRAY_SIZE(capdir);
 
 static struct chan *capattach(char *spec)
 {
-   return devattach(L'¤', spec);
+   return devattach("capability", spec);
 }
 
 static struct walkqid *capwalk(struct chan *c, struct chan *nc, char **name,
-   int nname)
+   int nname)
 {
return devwalk(c, nc, name, nname, capdir, ncapdir, devgen);
 }
@@ -85,7 +71,7 @@ static void capremove(struct chan *c)
if (iseve() && c->qid.path == Qhash)
ncapdir = ARRAY_SIZE(capdir) - 1;
else
-   error(Eperm);
+   error(EPERM, "Permission denied");
 }
 
 static int32_t capstat(struct chan *c, uint8_t *db, int32_t n)
@@ -99,8 +85,8 @@ static int32_t capstat(struct chan *c, uint8_t *db, int32_t n)
 static struct chan *capopen(struct chan *c, int omode)
 {
if (c->qid.type & QTDIR) {
-   if (omode != OREAD)
-   error(Ebadarg);
+   if (omode != O_RDONLY)
+   error(EISDIR, "Is a directory");
c->mode = omode;
c->flag |= COPEN;
c->offset = 0;
@@ -110,7 +96,7 @@ static struct chan *capopen(struct chan *c, int omode)
switch ((uint32_t)c->qid.path) {
case Qhash:
if (!iseve())
-   error(Eperm);
+   error(EPERM, "Permission denied: only eve() can open 
Qhash");
break;
}
 
@@ -121,24 +107,24 @@ static struct chan *capopen(struct chan *c, int omode)
 }
 
 /*
-static char*
-hashstr(uint8_t *hash)
+  static char*
+  hashstr(uint8_t *hash)
+  {
+  static char buf[2*Hashlen+1];
+  int i;
+
+  for(i = 0; i < Hashlen; i++)
+  sprint(buf+2*i, "%2.2x", hash[i]);
+  buf[2*Hashlen] = 0;
+  return buf;
+  }
+*/
+
+static struct Caphash *remcap(uint8_t *hash)
 {
-static char buf[2*Hashlen+1];
-int i;
+   struct Caphash *t, **l;
 
-for(i = 0; i < Hashlen; i++)
-sprint(buf+2*i, "%2.2x", hash[i]);
-buf[2*Hashlen] = 0;
-return buf;
-}
- */
-
-static Caphash *remcap(uint8_t *hash)
-{
-   Caphash *t, **l;
-
-   qlock(&()->qlock);
+   qlock();
 
/* find the matching capability */
for (l =  *l != NULL;) {
@@ -152,21 +138,21 @@ static Caphash *remcap(uint8_t *hash)
capalloc.nhash--;
*l = t->next;
}
-   qunlock(&()->qlock);
-
+   qunlock();
+   
return t;
 }
 
 /* add a capability, throwing out any old ones */
 static void addcap(uint8_t *hash)
 {
-   Caphash *p, *t, **l;
+   struct Caphash *p, *t, **l;
 
   

[akaros] [PATCH 3/4] capability: run scripts/PLAN9 on capability device

2016-10-13 Thread Ronald G. Minnich
Change-Id: I55dbed3e636730c4768c61168f22c61c9e2c82fb
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 kern/drivers/dev/capability.c | 108 +-
 1 file changed, 64 insertions(+), 44 deletions(-)

diff --git a/kern/drivers/dev/capability.c b/kern/drivers/dev/capability.c
index a3bafd7..9bd487c 100644
--- a/kern/drivers/dev/capability.c
+++ b/kern/drivers/dev/capability.c
@@ -7,14 +7,33 @@
  * in the LICENSE file.
  */
 
-#include "../port/error.h"
-#include "../port/lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "mem.h"
-#include "u.h"
-
-#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 enum {
Hashlen = SHA1dlen,
@@ -32,7 +51,7 @@ struct Caphash {
 };
 
 struct {
-   QLock QLock;
+   qlock_t qlock_t qlock;
Caphash *first;
int nhash;
 } capalloc;
@@ -44,31 +63,32 @@ enum {
 };
 
 /* caphash must be last */
-Dirtab capdir[] = {
+struct dirtab capdir[] = {
 ".",   {Qdir, 0, QTDIR}, 0, DMDIR | 0500, "capuse", {Quse}, 0, 0222,
 "caphash", {Qhash},  0, 0200,
 };
-int ncapdir = nelem(capdir);
+int ncapdir = ARRAY_SIZE(capdir);
 
-static Chan *capattach(char *spec)
+static struct chan *capattach(char *spec)
 {
return devattach(L'¤', spec);
 }
 
-static Walkqid *capwalk(Chan *c, Chan *nc, char **name, int nname)
+static struct walkqid *capwalk(struct chan *c, struct chan *nc, char **name,
+   int nname)
 {
return devwalk(c, nc, name, nname, capdir, ncapdir, devgen);
 }
 
-static void capremove(Chan *c)
+static void capremove(struct chan *c)
 {
if (iseve() && c->qid.path == Qhash)
-   ncapdir = nelem(capdir) - 1;
+   ncapdir = ARRAY_SIZE(capdir) - 1;
else
error(Eperm);
 }
 
-static int32_t capstat(Chan *c, uint8_t *db, int32_t n)
+static int32_t capstat(struct chan *c, uint8_t *db, int32_t n)
 {
return devstat(c, db, n, capdir, ncapdir, devgen);
 }
@@ -76,7 +96,7 @@ static int32_t capstat(Chan *c, uint8_t *db, int32_t n)
 /*
  *  if the stream doesn't exist, create it
  */
-static Chan *capopen(Chan *c, int omode)
+static struct chan *capopen(struct chan *c, int omode)
 {
if (c->qid.type & QTDIR) {
if (omode != OREAD)
@@ -102,7 +122,7 @@ static Chan *capopen(Chan *c, int omode)
 
 /*
 static char*
-hashstr(uchar *hash)
+hashstr(uint8_t *hash)
 {
 static char buf[2*Hashlen+1];
 int i;
@@ -118,21 +138,21 @@ static Caphash *remcap(uint8_t *hash)
 {
Caphash *t, **l;
 
-   qlock();
+   qlock(&()->qlock);
 
/* find the matching capability */
-   for (l =  *l != nil;) {
+   for (l =  *l != NULL;) {
t = *l;
if (memcmp(hash, t->hash, Hashlen) == 0)
break;
l = >next;
}
t = *l;
-   if (t != nil) {
+   if (t != NULL) {
capalloc.nhash--;
*l = t->next;
}
-   qunlock();
+   qunlock(&()->qlock);
 
return t;
 }
@@ -142,36 +162,36 @@ static void addcap(uint8_t *hash)
 {
Caphash *p, *t, **l;
 
-   p = smalloc(sizeof *p);
+   p = kzmalloc(sizeof *p, 0);
memmove(p->hash, hash, Hashlen);
-   p->next = nil;
+   p->next = NULL;
 
-   qlock();
+   qlock(&()->qlock);
 
/* trim extras */
while (capalloc.nhash >= Maxhash) {
t = capalloc.first;
-   if (t == nil)
+   if (t == NULL)
panic("addcap");
capalloc.first = t->next;
-   free(t);
+   kfree(t);
capalloc.nhash--;
}
 
/* add new one */
-   for (l =  *l != nil; l = &(*l)->next)
+   for (l =  *l != NULL; l = &(*l)->next)
;
*l = p;
capalloc.nhash++;
 
-   qunlock();
+   qunlock(&()->qlock);
 }
 
-static void capclose(Chan *c)
+static void capclose(struct chan *c)
 {
 }
 
-static int32_t capread(Chan *c, void *va, int32_t n, int64_t m)
+static int32_t capread(struct chan *c, void *va, int32_t n, int64_t m)
 {
switch ((uint32_t)c->qid.path) {
case Qdir:
@@ -184,14 +204,14 @@ static int32_t capread(Chan *c, void *va, int32_t n, 
int64_t m)
return n;
 }
 
-static int32_t capwrite(Chan *c, void *va, int32_t n, int64_t m)
+static int32_t capwrite(struct chan *c, void *va, int32_t n, int64_t m)
 {
Caphash *p;
char *cp;
uint8_t hash[Hashlen];
char *key, *f

[akaros] [PATCH 1/4] add the capability device from Harvey (from Plan 9)

2016-10-13 Thread Ronald G. Minnich
Change-Id: If159e72517809eedd0d1e98271e3dde57e035090
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 kern/drivers/dev/capability.c | 295 ++
 1 file changed, 295 insertions(+)
 create mode 100644 kern/drivers/dev/capability.c

diff --git a/kern/drivers/dev/capability.c b/kern/drivers/dev/capability.c
new file mode 100644
index 000..53a59af
--- /dev/null
+++ b/kern/drivers/dev/capability.c
@@ -0,0 +1,295 @@
+/*
+ * This file is part of the UCB release of Plan 9. It is subject to the license
+ * terms in the LICENSE file found in the top-level directory of this
+ * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
+ * part of the UCB release of Plan 9, including this file, may be copied,
+ * modified, propagated, or distributed except according to the terms contained
+ * in the LICENSE file.
+ */
+
+#include   "u.h"
+#include   "../port/lib.h"
+#include   "mem.h"
+#include   "dat.h"
+#include   "fns.h"
+#include   "../port/error.h"
+
+#include   
+
+enum
+{
+   Hashlen=SHA1dlen,
+   Maxhash=256,
+};
+
+/*
+ *  if a process knows cap->cap, it can change user
+ *  to capabilty->user.
+ */
+typedef struct Caphash Caphash;
+struct Caphash
+{
+   Caphash *next;
+   charhash[Hashlen];
+};
+
+struct
+{
+   QLock QLock;
+   Caphash *first;
+   int nhash;
+} capalloc;
+
+enum
+{
+   Qdir,
+   Qhash,
+   Quse,
+};
+
+/* caphash must be last */
+Dirtab capdir[] =
+{
+   ".",{Qdir,0,QTDIR}, 0,  DMDIR|0500,
+   "capuse",   {Quse}, 0,  0222,
+   "caphash",  {Qhash},0,  0200,
+};
+int ncapdir = nelem(capdir);
+
+static Chan*
+capattach(char *spec)
+{
+   return devattach(L'¤', spec);
+}
+
+static Walkqid*
+capwalk(Chan *c, Chan *nc, char **name, int nname)
+{
+   return devwalk(c, nc, name, nname, capdir, ncapdir, devgen);
+}
+
+static void
+capremove(Chan *c)
+{
+   if(iseve() && c->qid.path == Qhash)
+   ncapdir = nelem(capdir)-1;
+   else
+   error(Eperm);
+}
+
+
+static int32_t
+capstat(Chan *c, uint8_t *db, int32_t n)
+{
+   return devstat(c, db, n, capdir, ncapdir, devgen);
+}
+
+/*
+ *  if the stream doesn't exist, create it
+ */
+static Chan*
+capopen(Chan *c, int omode)
+{
+   if(c->qid.type & QTDIR){
+   if(omode != OREAD)
+   error(Ebadarg);
+   c->mode = omode;
+   c->flag |= COPEN;
+   c->offset = 0;
+   return c;
+   }
+
+   switch((uint32_t)c->qid.path){
+   case Qhash:
+   if(!iseve())
+   error(Eperm);
+   break;
+   }
+
+   c->mode = openmode(omode);
+   c->flag |= COPEN;
+   c->offset = 0;
+   return c;
+}
+
+/*
+static char*
+hashstr(uchar *hash)
+{
+   static char buf[2*Hashlen+1];
+   int i;
+
+   for(i = 0; i < Hashlen; i++)
+   sprint(buf+2*i, "%2.2x", hash[i]);
+   buf[2*Hashlen] = 0;
+   return buf;
+}
+ */
+
+static Caphash*
+remcap(uint8_t *hash)
+{
+   Caphash *t, **l;
+
+   qlock();
+
+   /* find the matching capability */
+   for(l =  *l != nil;){
+   t = *l;
+   if(memcmp(hash, t->hash, Hashlen) == 0)
+   break;
+   l = >next;
+   }
+   t = *l;
+   if(t != nil){
+   capalloc.nhash--;
+   *l = t->next;
+   }
+   qunlock();
+
+   return t;
+}
+
+/* add a capability, throwing out any old ones */
+static void
+addcap(uint8_t *hash)
+{
+   Caphash *p, *t, **l;
+
+   p = smalloc(sizeof *p);
+   memmove(p->hash, hash, Hashlen);
+   p->next = nil;
+
+   qlock();
+
+   /* trim extras */
+   while(capalloc.nhash >= Maxhash){
+   t = capalloc.first;
+   if(t == nil)
+   panic("addcap");
+   capalloc.first = t->next;
+   free(t);
+   capalloc.nhash--;
+   }
+
+   /* add new one */
+   for(l =  *l != nil; l = &(*l)->next)
+   ;
+   *l = p;
+   capalloc.nhash++;
+
+   qunlock();
+}
+
+static void
+capclose(Chan* c)
+{
+}
+
+static int32_t
+capread(Chan *c, void *va, int32_t n, int64_t m)
+{
+   switch((uint32_t)c->qid.path){
+   case Qdir:
+   return devdirread(c, va, n, capdir, ncapdir, devgen);
+
+   default:
+   error(Eperm);
+   break;
+   }
+   return n;
+}
+
+static int32_t
+capwrite(Chan *c, void *va, int32_t n, int64_t m)
+{
+   Caphash *p;
+   char *cp;
+   uint8_t hash[Hashlen];
+   c

[akaros] [PATCH] VMM: add two vthread functions.

2016-09-07 Thread Ronald G. Minnich
The intent of these functions it to give users a familiar
API (pthreads).  I just had the experience of running the
naming by a non-Akaros person and the reaction was really
positive to the pthreads similarity.

Here's a usage example:

struct virtual_machine vm[1];

static volatile int count;

static void vmcall(void *a)
{
while (count < 100) {
__asm__ __volatile__("vmcall\n\t");
count++;
}
count++;
while (1);
}

int main(int argc, char **argv)
{

vthread_attr_init(vm, 0);
vthread_create(vm, 0, (uint64_t) vmcall, NULL);

while(count < 2) {
}

return 0;
}

Change-Id: I3e72d8a0efd89482d2f9856daccb7945f7ae1c92
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 user/vmm/include/vmm/sched.h |   4 +
 user/vmm/include/vmm/vmm.h   |   7 ++
 user/vmm/vthread.c   | 176 +++
 3 files changed, 187 insertions(+)
 create mode 100644 user/vmm/vthread.c

diff --git a/user/vmm/include/vmm/sched.h b/user/vmm/include/vmm/sched.h
index c9a7136..403ca3f 100644
--- a/user/vmm/include/vmm/sched.h
+++ b/user/vmm/include/vmm/sched.h
@@ -80,4 +80,8 @@ void start_guest_thread(struct guest_thread *gth);
 struct task_thread *vmm_run_task(struct virtual_machine *vm,
  void (*func)(void *), void *arg);
 
+int vthread_attr_init(struct virtual_machine *vm, int vmmflags);
+int vthread_attr_kernel_init(struct virtual_machine *vm, int vmmflags);
+int vthread_create(struct virtual_machine *vm, int guest, void *rip, void 
*arg);
+
 __END_DECLS
diff --git a/user/vmm/include/vmm/vmm.h b/user/vmm/include/vmm/vmm.h
index 5139b2a..6577651 100644
--- a/user/vmm/include/vmm/vmm.h
+++ b/user/vmm/include/vmm/vmm.h
@@ -27,12 +27,19 @@ struct virtual_machine {
struct guest_thread **gths;
unsigned intnr_gpcs;
struct vmm_gpcore_init  *gpcis;
+   bool vminit;
 
/* TODO: put these in appropriate structures.  e.g., virtio things in
 * something related to virtio.  low4k in something related to the 
guest's
 * memory. */
uint8_t *low4k;
struct virtio_mmio_dev  
*virtio_mmio_devices[VIRTIO_MMIO_MAX_NUM_DEV];
+
+   /* Default root pointer to use if one is not set in a
+* guest thread. We expect this to be the common case,
+* where all guests share a page table. It's not required
+* however. */
+   void *root;
 };
 
 char *regname(uint8_t reg);
diff --git a/user/vmm/vthread.c b/user/vmm/vthread.c
new file mode 100644
index 000..8754c30
--- /dev/null
+++ b/user/vmm/vthread.c
@@ -0,0 +1,176 @@
+/* Copyright (c) 2016 Google Inc.
+ *
+ * See LICENSE for details.
+ *
+ * Helper functions for virtual machines */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+
+static void *page(void *addr, int count)
+{
+   void *v;
+   unsigned long flags = MAP_POPULATE | MAP_ANONYMOUS;
+
+   if (addr)
+   flags |= MAP_FIXED;
+   return mmap(addr, count * 4096, PROT_READ | PROT_WRITE, flags, -1, 0);
+}
+
+/* vmsetup is a basic helper function used by vthread_attr_init
+ * and vthread_attr_kernel_init. */
+static int vmsetup(struct virtual_machine *vm, int flags)
+{
+   unsigned long long *p512, *p1;
+   struct vm_trapframe *vm_tf;
+   int i, ret;
+   uint8_t *p;
+
+   if (vm->vminit)
+   return -EBUSY;
+
+   if (vm->nr_gpcs == 0)
+   vm->nr_gpcs = 1;
+
+   vm->gpcis = calloc(vm->nr_gpcs, sizeof(*vm->gpcis));
+
+   /* Set up default page mappings. The common case,
+* for user VM threads and kernel VM threads, is that
+* they need some kind of initial page tables. The kernels
+* will almost always throw them away; the user VM threads
+* will almost always continue to use them. Using two
+* pages and setting up an initial page table is
+* cheap and makes users lives easier. This initial
+* page table can grow to 512 GiB, which should be enough
+* for now.
+*
+* At the same time, we allow users to select other
+* arrangements if they wish.  Here's a simple example: is it
+* possible someone will want a different guest page table for
+* every guest? Yes.
+*
+* We lock the page table to 0x100 for now. We can't just
+* let it pick anything as it may pick something the guest
+* can't address (i.e. outside EPT range). */
+
+   /* Allocate 2 pages for page table pages: a page of
+* 512 GiB PTEs with only one entry filled to point to
+* a page of 1 GiB PTEs; a page of 1 GiB PTEs with
+* only one entry filled. */
+
+   p512 = page((void *)0x100, 2);
+   if (!p51

[akaros] [PATCH] VMM: add two vthread functions.

2016-09-06 Thread Ronald G. Minnich
The intent of these functions it to give users a familiar
API (pthreads).  I just had the experience of running the
naming by a non-Akaros person and the reaction was really
positive to the pthreads similarity.

Here's a usage example:

struct virtual_machine vm[1];

static volatile int count;

static void vmcall(void *a)
{
while (count < 100) {
__asm__ __volatile__("vmcall\n\t");
count++;
}
count++;
while (1);
}

unsigned long long s[512];
int main(int argc, char **argv)
{

vthread_attr_init(vm, 0);
vthread_create(vm, 0, (uint64_t) vmcall, NULL, [511]);

while(count < 2) {
}

return 0;
}

Change-Id: I3e72d8a0efd89482d2f9856daccb7945f7ae1c92
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 user/vmm/include/vmm/sched.h |   4 ++
 user/vmm/include/vmm/vmm.h   |   7 +++
 user/vmm/vthread.c   | 144 +++
 3 files changed, 155 insertions(+)
 create mode 100644 user/vmm/vthread.c

diff --git a/user/vmm/include/vmm/sched.h b/user/vmm/include/vmm/sched.h
index c9a7136..7fc8fad 100644
--- a/user/vmm/include/vmm/sched.h
+++ b/user/vmm/include/vmm/sched.h
@@ -80,4 +80,8 @@ void start_guest_thread(struct guest_thread *gth);
 struct task_thread *vmm_run_task(struct virtual_machine *vm,
  void (*func)(void *), void *arg);
 
+int vthread_attr_init(struct virtual_machine *vm, int vmmflags);
+int vthread_attr_kernel_init(struct virtual_machine *vm, int vmmflags);
+int vthread_create(struct virtual_machine *vm, int guest, void *rip, void 
*arg, void *stack);
+
 __END_DECLS
diff --git a/user/vmm/include/vmm/vmm.h b/user/vmm/include/vmm/vmm.h
index 5139b2a..483ec0b 100644
--- a/user/vmm/include/vmm/vmm.h
+++ b/user/vmm/include/vmm/vmm.h
@@ -27,12 +27,19 @@ struct virtual_machine {
struct guest_thread **gths;
unsigned intnr_gpcs;
struct vmm_gpcore_init  *gpcis;
+   bool vminit;
 
/* TODO: put these in appropriate structures.  e.g., virtio things in
 * something related to virtio.  low4k in something related to the 
guest's
 * memory. */
uint8_t *low4k;
struct virtio_mmio_dev  
*virtio_mmio_devices[VIRTIO_MMIO_MAX_NUM_DEV];
+
+   /* Default root pointer to use if one is not set in a
+* guest thread. We expect this to be the common case,
+* where all guests share a page table. It's not required
+* however. */
+   uintptr_t root;
 };
 
 char *regname(uint8_t reg);
diff --git a/user/vmm/vthread.c b/user/vmm/vthread.c
new file mode 100644
index 000..ef7c5b5
--- /dev/null
+++ b/user/vmm/vthread.c
@@ -0,0 +1,144 @@
+/* Copyright (c) 2016 Google Inc.
+ *
+ * See LICENSE for details.
+ *
+ * Helper functions for virtual machines */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static void *page(void *addr)
+{
+   void *v;
+   unsigned long flags = MAP_POPULATE | MAP_ANONYMOUS;
+
+   if (addr)
+   flags |= MAP_FIXED;
+   return mmap(addr, 4096, PROT_READ | PROT_WRITE, flags, -1, 0);
+}
+
+/* vmsetup is a basic helper function used by vthread_attr_init
+ * and vthread_attr_kernel_init. */
+static int vmsetup(struct virtual_machine *vm, int flags)
+{
+   unsigned long long *p512, *p1;
+   struct vm_trapframe *vm_tf;
+   int i, ret;
+
+   if (vm->vminit)
+   return -EBUSY;
+
+   if (vm->nr_gpcs == 0)
+   vm->nr_gpcs = 1;
+
+   vm->gpcis = calloc(vm->nr_gpcs, sizeof(*vm->gpcis));
+
+   /* Set up default page mappings. The common case,
+* for user VM threads and kernel VM threads, is that
+* they need some kind of initial page tables. The kernels
+* will almost always throw them away; the user VM threads
+* will almost always continue to use them. Using two
+* pages and setting up an initial page table is
+* cheap and makes users lives easier. This initial
+* page table can grow to 512 GiB, which should be enough
+* for now.
+*
+* At the same time, we allow users to select other
+* arrangements if they wish.  Here's a simple example: is it
+* possible someone will want a different guest page table for
+* every guest? Yes.
+* 
+* We lock the page table to 0x100 for now. We can't just
+* let it pick anything as it may pick something the guest
+* can't address (i.e. outside EPT range). */
+
+   /* Allocate 2 pages for page table pages: a page of
+* 512 GiB PTEs with only one entry filled to point to
+* a page of 1 GiB PTEs; a page of 1 GiB PTEs with
+* only one entry filled. */
+   
+   p512 = page((void *)0x100);
+   p1 = p

[akaros] [PATCH] VMM: add two vthread functions.

2016-09-06 Thread Ronald G. Minnich
The intent of these functions it to give users a familiar
API (pthreads).  I just had the experience of running the
naming by a non-Akaros person and the reaction was really
positive to the pthreads similarity.

Here's a usage example:

struct virtual_machine vm[1];

static volatile int count;

static void vmcall(void *a)
{
while (count < 100) {
__asm__ __volatile__("vmcall\n\t");
count++;
}
count++;
while (1);
}

unsigned long long s[512];
int main(int argc, char **argv)
{

vthread_attr_init(vm, 0);
vthread_create(vm, 0, (uint64_t) vmcall, NULL, [511]);

while(count < 2) {
}

return 0;
}

Change-Id: I3e72d8a0efd89482d2f9856daccb7945f7ae1c92
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 user/vmm/include/vmm/sched.h |   4 ++
 user/vmm/vthread.c   | 129 +++
 2 files changed, 133 insertions(+)
 create mode 100644 user/vmm/vthread.c

diff --git a/user/vmm/include/vmm/sched.h b/user/vmm/include/vmm/sched.h
index c9a7136..7fc8fad 100644
--- a/user/vmm/include/vmm/sched.h
+++ b/user/vmm/include/vmm/sched.h
@@ -80,4 +80,8 @@ void start_guest_thread(struct guest_thread *gth);
 struct task_thread *vmm_run_task(struct virtual_machine *vm,
  void (*func)(void *), void *arg);
 
+int vthread_attr_init(struct virtual_machine *vm, int vmmflags);
+int vthread_attr_kernel_init(struct virtual_machine *vm, int vmmflags);
+int vthread_create(struct virtual_machine *vm, int guest, void *rip, void 
*arg, void *stack);
+
 __END_DECLS
diff --git a/user/vmm/vthread.c b/user/vmm/vthread.c
new file mode 100644
index 000..ee9b55a
--- /dev/null
+++ b/user/vmm/vthread.c
@@ -0,0 +1,129 @@
+/* Copyright (c) 2016 Google Inc.
+ *
+ * See LICENSE for details.
+ *
+ * Helper functions for virtual machines */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static void *page(void *addr)
+{
+   void *v;
+   unsigned long flags = MAP_POPULATE | MAP_ANONYMOUS;
+
+   if (addr)
+   flags |= MAP_FIXED;
+   return mmap(addr, 4096, PROT_READ | PROT_WRITE, flags, -1, 0);
+}
+
+/* vthread_addr sets up a virtual_machine struct such that functions
+ * can start up VM guests.  It is like pthread_attr in that it sets up
+ * default attributes and can be used in vthread_create calls. If
+ * vm->nrgpcs is not set then the vm will be set up for 1 guest. */
+int vthread_attr_init(struct virtual_machine *vm, int vmmflags)
+{
+   uint32_t *apic;
+   unsigned long long *p512, *p1, *p2m;
+   struct vm_trapframe *vm_tf;
+   int i;
+
+   if (vm->vminit)
+   return EINUSE;
+
+   vm->flags = vmmflags;
+
+   if (vm->nr_gpcs == 0)
+   vm->nr_gpcs = 1;
+
+   vm->gpcis = calloc(vm->nr_gpcs, sizeof(*vm->gpcis));
+
+   /* For now, only set up page mappings if they did not
+* ask for anything.  Anything else we can think of
+* here will get too constraining.  Here's a simple
+* example: is it possible someone will want a
+* different guest page table for every guest? Yes. So
+* we don't want to rule that out. We lock the page
+* table to 0x100 for now. We can't just let it
+* pick anything as it may pick something the guest
+* can't address (i.e. outside EPT range). */
+
+   /* Allocate 3 pages for page table pages: a page of
+* 512 GiB PTEs with only one entry filled to point to
+* a page of 1 GiB PTEs; a page of 1 GiB PTEs with
+* only one entry filled to point to a page of 2 MiB
+* PTEs; and a page of 2 MiB PTEs, only a subset of
+* which will be filled. */
+   
+   p512 = page((void *)0x100);
+   p1 = page(p512 + 512);
+   p2m = page(p1 + 512);
+   
+   /* Set up a 1:1 ("identity") page mapping from host
+* virtual to guest physical for 1 GiB.  This mapping
+* is used unless the guest (e.g. Linux) sets up its
+* own page tables. Be aware that the values stored in
+* the table are physical addresses.  This is subtle
+* and mistakes are easily disguised due to the
+* identity mapping, so take care when manipulating
+* these mappings. Note: we don't yet have symbols for
+* "start of virtual address common to host and guest"
+* so we just use 4M to 16M for now.*/
+   p512[PML4(0x40)] = (uint64_t)p1 | PTE_KERN_RW;
+   p1[PML3(0x40)] = PTE_PS | PTE_KERN_RW;
+
+   for (i = 0; i < vm->nr_gpcs; i++){
+   vm_tf = gth_to_vmtf(vm->gths[i]);
+   vm_tf->tf_cr3 = (uint64_t)p512;
+   }
+
+   return 0;
+}
+
+/* vthread_attr_kernel_init sets up minimum basic attributes for
+ * running a kernel, as opposed to just user mode.  This set

[akaros] [PATCH] VMM: add two vthread functions.

2016-08-31 Thread Ronald G. Minnich
The intent of these functions it to give users a familiar
API (pthreads).  I just had the experience of running the
naming by a non-Akaros person and the reaction was really
positive to the pthreads similarity.

Here's a usage example:

struct virtual_machine vm[1];

static volatile int count;

static void vmcall(void *a)
{
while (count < 100) {
__asm__ __volatile__("vmcall\n\t");
count++;
}
count++;
while (1);
}

unsigned long long s[512];
int main(int argc, char **argv)
{

vthread_attr_init(vm, 0);
vthread_create(vm->gths[0], (uint64_t) vmcall, NULL, [511]);

while(count < 2) {
}

return 0;
}

Change-Id: I3e72d8a0efd89482d2f9856daccb7945f7ae1c92
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 user/vmm/include/vmm/sched.h |  3 ++
 user/vmm/vthread.c   | 98 
 2 files changed, 101 insertions(+)
 create mode 100644 user/vmm/vthread.c

diff --git a/user/vmm/include/vmm/sched.h b/user/vmm/include/vmm/sched.h
index c9a7136..b3866e6 100644
--- a/user/vmm/include/vmm/sched.h
+++ b/user/vmm/include/vmm/sched.h
@@ -80,4 +80,7 @@ void start_guest_thread(struct guest_thread *gth);
 struct task_thread *vmm_run_task(struct virtual_machine *vm,
  void (*func)(void *), void *arg);
 
+int vthread_attr_init(struct virtual_machine *vm, int vmmflags);
+int vthread_create(struct guest_thread *g, void *rip, void *arg, void *stack);
+
 __END_DECLS
diff --git a/user/vmm/vthread.c b/user/vmm/vthread.c
new file mode 100644
index 000..f470785
--- /dev/null
+++ b/user/vmm/vthread.c
@@ -0,0 +1,98 @@
+/* Copyright (c) 2016 Google Inc.
+ *
+ * See LICENSE for details.
+ *
+ * Helper functions for virtual machines */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static void *page(void *addr)
+{
+   void *v;
+   unsigned long flags = MAP_POPULATE | MAP_ANONYMOUS;
+
+   if (addr)
+   flags |= MAP_FIXED;
+   return mmap(addr, 4096, PROT_READ | PROT_WRITE, flags, -1, 0);
+}
+
+/* vthread_addr sets up a virtual_machine struct such that functions
+ * can start up VM guests.  It is like pthread_attr in that it sets up
+ * default attributes and can be used in vthread_create calls. If
+ * vm->nrgpcs is not set then the vm will be set up for 1 guest. */
+int vthread_attr_init(struct virtual_machine *vm, int vmmflags)
+{
+   uint32_t *apic;
+   unsigned long long *p512, *p1, *p2m;
+   struct vm_trapframe *vm_tf;
+
+   if (vm->nr_gpcs == 0) {
+   /* TODO: should we set up for the max cores available? */
+   vm->nr_gpcs = 1;
+   vm->gpcis = calloc(vm->nr_gpcs, sizeof(*vm->gpcis));
+   vm->gpcis->posted_irq_desc = page(NULL);
+   vm->gpcis->vapic_addr = page(NULL);
+   apic = vm->gpcis->apic_addr = page((void *)0xfee0);
+   memset(apic, 0, 4096);
+   apic[0x30 / 4] = 0x01060015;
+
+   /* For now, only set up page mappings if they did not
+* ask for anything.  Anything else we can think of
+* here will get too constraining.  Here's a simple
+* example: is it possible someone will want a
+* different guest page table for every guest? Yes. So
+* we don't want to rule that out. We lock the page
+* table to 0x100 for now. We can't just let it
+* pick anything as it will pick something the guest
+* can't address (i.e. outside EPT range). */
+   p512 = page((void *)0x100);
+   p1 = page(p512 + 512);
+   p2m = page(p1 + 512);
+
+   /* Allocate 3 pages for page table pages: a page of
+* 512 GiB PTEs with only one entry filled to point to
+* a page of 1 GiB PTEs; a page of 1 GiB PTEs with
+* only one entry filled to point to a page of 2 MiB
+* PTEs; and a page of 2 MiB PTEs, only a subset of
+* which will be filled. */
+
+   /* Set up a 1:1 ("identity") page mapping from host
+* virtual to guest physical for 1 GiB.  This mapping
+* is used unless the guest (e.g. Linux) sets up its
+* own page tables. Be aware that the values stored in
+* the table are physical addresses.  This is subtle
+* and mistakes are easily disguised due to the
+* identity mapping, so take care when manipulating
+* these mappings. Note: we don't yet have symbols for
+* "start of virtual address common to host and guest"
+* so we just use 4M to 16M for now.*/
+   p512[PML4(0x40)] = (uin

[akaros] [PATCH 1/2] AHCI initial commit.

2016-08-09 Thread Ronald G. Minnich
>From github.com:harvey-os/harvey 5be5d9cc0a1da28339c61e974c31b1915d2a1b03

Change-Id: I5cd052ce7bde5f6eb6de9557dfe6151174d1ef5f
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 kern/drivers/dev/sd.c  | 1683 ++
 kern/drivers/dev/sdiahci.c | 2461 
 kern/drivers/dev/sdscsi.c  |  436 
 kern/include/ahci.h|  302 ++
 kern/include/sd.h  |  203 
 5 files changed, 5085 insertions(+)
 create mode 100644 kern/drivers/dev/sd.c
 create mode 100644 kern/drivers/dev/sdiahci.c
 create mode 100644 kern/drivers/dev/sdscsi.c
 create mode 100644 kern/include/ahci.h
 create mode 100644 kern/include/sd.h

diff --git a/kern/drivers/dev/sd.c b/kern/drivers/dev/sd.c
new file mode 100644
index 000..5ca4f5c
--- /dev/null
+++ b/kern/drivers/dev/sd.c
@@ -0,0 +1,1683 @@
+/*
+ * This file is part of the UCB release of Plan 9. It is subject to the license
+ * terms in the LICENSE file found in the top-level directory of this
+ * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
+ * part of the UCB release of Plan 9, including this file, may be copied,
+ * modified, propagated, or distributed except according to the terms contained
+ * in the LICENSE file.
+ */
+
+/*
+ * Storage Device.
+ */
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "ureg.h"
+#include "../port/error.h"
+
+#include "../port/sd.h"
+
+extern Dev sddevtab;
+extern SDifc* sdifc[];
+
+static char Echange[] = "media or partition has changed";
+
+static char devletters[] = "0123456789"
+   "abcdefghijklmnopqrstuvwxyz"
+   "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+static SDev *devs[sizeof devletters-1];
+static QLock devslock;
+
+enum {
+   Rawcmd,
+   Rawdata,
+   Rawstatus,
+};
+
+enum {
+   Qtopdir = 1,/* top level directory */
+   Qtopbase,
+   Qtopctl  = Qtopbase,
+
+   Qunitdir,   /* directory per unit */
+   Qunitbase,
+   Qctl= Qunitbase,
+   Qraw,
+   Qpart,
+
+   TypeLOG = 4,
+   NType   = (1<<TypeLOG),
+   TypeMASK= (NType-1),
+   TypeSHIFT   = 0,
+
+   PartLOG = 8,
+   NPart   = (1<<PartLOG),
+   PartMASK= (NPart-1),
+   PartSHIFT   = TypeLOG,
+
+   UnitLOG = 8,
+   NUnit   = (1<<UnitLOG),
+   UnitMASK= (NUnit-1),
+   UnitSHIFT   = (PartLOG+TypeLOG),
+
+   DevLOG  = 8,
+   NDev= (1 << DevLOG),
+   DevMASK = (NDev-1),
+   DevSHIFT = (UnitLOG+PartLOG+TypeLOG),
+
+   Ncmd = 20,
+};
+
+#define TYPE(q)uint32_t)(q).path)>>TypeSHIFT) & TypeMASK)
+#define PART(q)uint32_t)(q).path)>>PartSHIFT) & PartMASK)
+#define UNIT(q)uint32_t)(q).path)>>UnitSHIFT) & UnitMASK)
+#define DEV(q) uint32_t)(q).path)>>DevSHIFT) & DevMASK)
+#define QID(d,u, p, t) (((d)<<DevSHIFT)|((u)<<UnitSHIFT)|\
+((p)<<PartSHIFT)|((t)<<TypeSHIFT))
+
+
+void
+sdaddpart(SDunit* unit, char* name, uint64_t start, uint64_t end)
+{
+   SDpart *pp;
+   int i, partno;
+
+   /*
+* Check name not already used
+* and look for a free slot.
+*/
+   if(unit->part != nil){
+   partno = -1;
+   for(i = 0; i < unit->npart; i++){
+   pp = >part[i];
+   if(!pp->valid){
+   if(partno == -1)
+   partno = i;
+   break;
+   }
+   if(strcmp(name, pp->SDperm.name) == 0){
+   if(pp->start == start && pp->end == end)
+   return;
+   error(Ebadctl);
+   }
+   }
+   }
+   else{
+   if((unit->part = malloc(sizeof(SDpart)*SDnpart)) == nil)
+   error(Enomem);
+   unit->npart = SDnpart;
+   partno = 0;
+   }
+
+   /*
+* If no free slot found then increase the
+* array size (can't get here with unit->part == nil).
+*/
+   if(partno == -1){
+   if(unit->npart >= NPart)
+   error(Enomem);
+   if((pp = malloc(sizeof(SDpart)*(unit->npart+SDnpart))) == nil)
+   error(Enomem);
+   memmove(pp, unit->part, sizeof(SDpart)*uni

[akaros] [PATCH] VMM: move to waserror/error style.

2016-08-01 Thread Ronald G. Minnich
This simplifies the code and improves error diagnostics.

I've tested some of the error handling paths by trying to
set up a VM with bad parameters and also inserting some
calls to error() in a few places.

Change-Id: I5437f559f618c132be751897785aee6da3b771be
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 kern/arch/x86/vmm/intel/vmx.c | 76 ---
 kern/arch/x86/vmm/vmm.c   | 46 --
 2 files changed, 56 insertions(+), 66 deletions(-)

diff --git a/kern/arch/x86/vmm/intel/vmx.c b/kern/arch/x86/vmm/intel/vmx.c
index 1ea4666..27a3329 100644
--- a/kern/arch/x86/vmm/intel/vmx.c
+++ b/kern/arch/x86/vmm/intel/vmx.c
@@ -687,16 +687,16 @@ setup_vmcs_config(void *p)
*ret = 0;
 }
 
-static struct vmcs *
-__vmx_alloc_vmcs(int node)
+static struct vmcs *__vmx_alloc_vmcs(int node)
 {
struct vmcs *vmcs;
 
vmcs = get_cont_pages_node(node, vmcs_config.order, MEM_WAIT);
if (!vmcs)
-   return 0;
+   error(ENOMEM, "__vmx_alloc_vmcs: Could not get %d contig pages",
+ vmcs_config.order);
memset(vmcs, 0, vmcs_config.size);
-   vmcs->revision_id = vmcs_config.revision_id;/* vmcs revision id */
+   vmcs->revision_id = vmcs_config.revision_id; /* vmcs revision id */
printd("%d: set rev id %d\n", core_id(), vmcs->revision_id);
return vmcs;
 }
@@ -729,8 +729,7 @@ vmx_free_vmcs(struct vmcs *vmcs)
  * Note that host-state that does change is set elsewhere. E.g., host-state
  * that is set differently for each CPU is set in __vmx_setup_pcpu(), not here.
  */
-static void
-vmx_setup_constant_host_state(void)
+static void vmx_setup_constant_host_state(void)
 {
uint32_t low32, high32;
unsigned long tmpl;
@@ -804,42 +803,42 @@ construct_eptp(physaddr_t root_hpa)
 /* Helper: some fields of the VMCS need a physical page address, e.g. the VAPIC
  * page.  We have the user address.  This converts the user to phys addr and
  * sets that up in the VMCS.  Returns 0 on success, -1 o/w. */
-static int vmcs_set_pgaddr(struct proc *p, void *u_addr, unsigned long field)
+static void vmcs_set_pgaddr(struct proc *p, void *u_addr,
+unsigned long field, char *what)
 {
uintptr_t kva;
physaddr_t paddr;
 
/* Enforce page alignment */
kva = uva2kva(p, ROUNDDOWN(u_addr, PGSIZE), PGSIZE, PROT_WRITE);
-   if (!kva) {
-   set_error(EINVAL, "Unmapped pgaddr %p for VMCS", u_addr);
-   return -1;
-   }
+   if (!kva)
+   error(EINVAL, "Unmapped pgaddr %p for VMCS page %s", u_addr, 
what);
+
paddr = PADDR(kva);
-   /* TODO: need to pin the page.  A munmap would actually be okay (though
-* probably we should kill the process), but we need to keep the page 
from
-* being reused.  A refcnt would do the trick, which we decref when we
-* destroy the guest core/vcpu. */
+   /* TODO: need to pin the page.  A munmap would actually be okay
+* (though probably we should kill the process), but we need to
+* keep the page from being reused.  A refcnt would do the trick,
+* which we decref when we destroy the guest core/vcpu. Note that
+* this is an assert, not an error, because it represents an error
+* in the kernel itself. */
assert(!PGOFF(paddr));
vmcs_writel(field, paddr);
/* Pages are inserted twice.  Once, with the full paddr.  The next 
field is
 * the upper 32 bits of the paddr. */
vmcs_writel(field + 1, paddr >> 32);
-   return 0;
 }
 
 /**
  * vmx_setup_initial_guest_state - configures the initial state of guest
  * registers and the VMCS.  Returns 0 on success, -1 o/w.
  */
-static int vmx_setup_initial_guest_state(struct proc *p,
- struct vmm_gpcore_init *gpci)
+static void vmx_setup_initial_guest_state(struct proc *p,
+  struct vmm_gpcore_init *gpci)
 {
unsigned long tmpl;
unsigned long cr4 = X86_CR4_PAE | X86_CR4_VMXE | X86_CR4_OSXMMEXCPT |
X86_CR4_PGE | X86_CR4_OSFXSR;
uint32_t protected_mode = X86_CR0_PG | X86_CR0_PE;
-   int ret = 0;
 
 #if 0
do
@@ -948,11 +947,11 @@ static int vmx_setup_initial_guest_state(struct proc *p,
 
/* Initialize parts based on the users info.  If one of them fails, 
we'll do
 * the others but then error out. */
-   ret |= vmcs_set_pgaddr(p, gpci->posted_irq_desc, POSTED_INTR_DESC_ADDR);
-   ret |= vmcs_set_pgaddr(p, gpci->vapic_addr, VIRTUAL_APIC_PAGE_ADDR);
-   ret |= vmcs_set_pgaddr(p, gpci->apic_addr, APIC_ACCESS_ADDR);
-
-   return ret;
+   vmcs_set_pgaddr(p, gpci->posted_irq_desc, POSTED_INTR_DESC_ADDR,
+   "posted_i

[akaros] [PATCH 1/2] vmm_init: support use of waserror()/error() style.

2016-07-20 Thread Ronald G. Minnich
The vm startup is complicated and has lots of room for error.
In practice using the 'test return value' model has been
hard to use because the call order and functions are changing
-in the most recent case we're getting back
ENOMEM when the error is not ENOMEM at all.

Set up the sys_vmm_setup so that it can call functions
which use error(). I've talked to Barret and we're
good with this change.

Change-Id: I5260814cda2207eb8c698d5b8e9a27c5fb38fbf5
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 kern/src/syscall.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/kern/src/syscall.c b/kern/src/syscall.c
index 43ce692..2708745 100644
--- a/kern/src/syscall.c
+++ b/kern/src/syscall.c
@@ -1469,7 +1469,15 @@ static int sys_pop_ctx(struct proc *p, struct 
user_context *ctx)
 static int sys_vmm_setup(struct proc *p, unsigned int nr_guest_pcores,
  struct vmm_gpcore_init *gpcis, int flags)
 {
-   return vmm_struct_init(p, nr_guest_pcores, gpcis, flags);
+   int ret;
+   ERRSTACK(1);
+   if (waserror()) {
+   poperror();
+   return -1;
+   }
+   ret = vmm_struct_init(p, nr_guest_pcores, gpcis, flags);
+   poperror();
+   return ret;
 }
 
 static int sys_vmm_poke_guest(struct proc *p, int guest_pcoreid)
-- 
2.8.0.rc3.226.g39d4020

-- 
You received this message because you are subscribed to the Google Groups 
"Akaros" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akaros+unsubscr...@googlegroups.com.
To post to this group, send email to akaros@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[akaros] [PATCH 2/2] VMM: move to waserror/error style.

2016-07-20 Thread Ronald G. Minnich
This simplifies the code and improves error diagnostics.

I've tested some of the error handling paths by trying to
set up a VM with bad parameters and also inserting some
calls to error() in a few places.

Change-Id: I5437f559f618c132be751897785aee6da3b771be
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 kern/arch/x86/vmm/intel/vmx.c | 76 ---
 kern/arch/x86/vmm/vmm.c   | 44 +++--
 2 files changed, 55 insertions(+), 65 deletions(-)

diff --git a/kern/arch/x86/vmm/intel/vmx.c b/kern/arch/x86/vmm/intel/vmx.c
index 1ea4666..27a3329 100644
--- a/kern/arch/x86/vmm/intel/vmx.c
+++ b/kern/arch/x86/vmm/intel/vmx.c
@@ -687,16 +687,16 @@ setup_vmcs_config(void *p)
*ret = 0;
 }
 
-static struct vmcs *
-__vmx_alloc_vmcs(int node)
+static struct vmcs *__vmx_alloc_vmcs(int node)
 {
struct vmcs *vmcs;
 
vmcs = get_cont_pages_node(node, vmcs_config.order, MEM_WAIT);
if (!vmcs)
-   return 0;
+   error(ENOMEM, "__vmx_alloc_vmcs: Could not get %d contig pages",
+ vmcs_config.order);
memset(vmcs, 0, vmcs_config.size);
-   vmcs->revision_id = vmcs_config.revision_id;/* vmcs revision id */
+   vmcs->revision_id = vmcs_config.revision_id; /* vmcs revision id */
printd("%d: set rev id %d\n", core_id(), vmcs->revision_id);
return vmcs;
 }
@@ -729,8 +729,7 @@ vmx_free_vmcs(struct vmcs *vmcs)
  * Note that host-state that does change is set elsewhere. E.g., host-state
  * that is set differently for each CPU is set in __vmx_setup_pcpu(), not here.
  */
-static void
-vmx_setup_constant_host_state(void)
+static void vmx_setup_constant_host_state(void)
 {
uint32_t low32, high32;
unsigned long tmpl;
@@ -804,42 +803,42 @@ construct_eptp(physaddr_t root_hpa)
 /* Helper: some fields of the VMCS need a physical page address, e.g. the VAPIC
  * page.  We have the user address.  This converts the user to phys addr and
  * sets that up in the VMCS.  Returns 0 on success, -1 o/w. */
-static int vmcs_set_pgaddr(struct proc *p, void *u_addr, unsigned long field)
+static void vmcs_set_pgaddr(struct proc *p, void *u_addr,
+unsigned long field, char *what)
 {
uintptr_t kva;
physaddr_t paddr;
 
/* Enforce page alignment */
kva = uva2kva(p, ROUNDDOWN(u_addr, PGSIZE), PGSIZE, PROT_WRITE);
-   if (!kva) {
-   set_error(EINVAL, "Unmapped pgaddr %p for VMCS", u_addr);
-   return -1;
-   }
+   if (!kva)
+   error(EINVAL, "Unmapped pgaddr %p for VMCS page %s", u_addr, 
what);
+
paddr = PADDR(kva);
-   /* TODO: need to pin the page.  A munmap would actually be okay (though
-* probably we should kill the process), but we need to keep the page 
from
-* being reused.  A refcnt would do the trick, which we decref when we
-* destroy the guest core/vcpu. */
+   /* TODO: need to pin the page.  A munmap would actually be okay
+* (though probably we should kill the process), but we need to
+* keep the page from being reused.  A refcnt would do the trick,
+* which we decref when we destroy the guest core/vcpu. Note that
+* this is an assert, not an error, because it represents an error
+* in the kernel itself. */
assert(!PGOFF(paddr));
vmcs_writel(field, paddr);
/* Pages are inserted twice.  Once, with the full paddr.  The next 
field is
 * the upper 32 bits of the paddr. */
vmcs_writel(field + 1, paddr >> 32);
-   return 0;
 }
 
 /**
  * vmx_setup_initial_guest_state - configures the initial state of guest
  * registers and the VMCS.  Returns 0 on success, -1 o/w.
  */
-static int vmx_setup_initial_guest_state(struct proc *p,
- struct vmm_gpcore_init *gpci)
+static void vmx_setup_initial_guest_state(struct proc *p,
+  struct vmm_gpcore_init *gpci)
 {
unsigned long tmpl;
unsigned long cr4 = X86_CR4_PAE | X86_CR4_VMXE | X86_CR4_OSXMMEXCPT |
X86_CR4_PGE | X86_CR4_OSFXSR;
uint32_t protected_mode = X86_CR0_PG | X86_CR0_PE;
-   int ret = 0;
 
 #if 0
do
@@ -948,11 +947,11 @@ static int vmx_setup_initial_guest_state(struct proc *p,
 
/* Initialize parts based on the users info.  If one of them fails, 
we'll do
 * the others but then error out. */
-   ret |= vmcs_set_pgaddr(p, gpci->posted_irq_desc, POSTED_INTR_DESC_ADDR);
-   ret |= vmcs_set_pgaddr(p, gpci->vapic_addr, VIRTUAL_APIC_PAGE_ADDR);
-   ret |= vmcs_set_pgaddr(p, gpci->apic_addr, APIC_ACCESS_ADDR);
-
-   return ret;
+   vmcs_set_pgaddr(p, gpci->posted_irq_desc, POSTED_INTR_DESC_ADDR,
+   "posted_i

[akaros] [PATCH] parlib/x86/atomic.h: (void) __sync_fetch_and_* calls

2016-07-18 Thread Ronald G. Minnich
In several cases the return from __sync_fetch_and_* is ignored
and external builds were throwing errors when -Werror was used.

Indicate via the standard (void) cast that the
return from the call can be ignored.

Change-Id: I944cbaf25f5e7ecadf01d206fcc0c74935183780
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 user/parlib/include/parlib/x86/atomic.h | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/user/parlib/include/parlib/x86/atomic.h 
b/user/parlib/include/parlib/x86/atomic.h
index da31c58..1ecd3e2 100644
--- a/user/parlib/include/parlib/x86/atomic.h
+++ b/user/parlib/include/parlib/x86/atomic.h
@@ -41,12 +41,12 @@ static inline void atomic_set(atomic_t *number, long val)
 
 static inline void atomic_inc(atomic_t *number)
 {
-   __sync_fetch_and_add(number, 1);
+   (void)__sync_fetch_and_add(number, 1);
 }
 
 static inline void atomic_dec(atomic_t *number)
 {
-   __sync_fetch_and_sub(number, 1);
+   (void)__sync_fetch_and_sub(number, 1);
 }
 
 static inline long atomic_fetch_and_add(atomic_t *number, long val)
@@ -88,12 +88,12 @@ static inline bool atomic_cas_u32(uint32_t *addr, uint32_t 
exp_val,
 
 static inline void atomic_andb(volatile uint8_t *number, uint8_t mask)
 {
-   __sync_fetch_and_and(number, mask);
+   (void)__sync_fetch_and_and(number, mask);
 }
 
 static inline void atomic_orb(volatile uint8_t *number, uint8_t mask)
 {
-   __sync_fetch_and_or(number, mask);
+   (void)__sync_fetch_and_or(number, mask);
 }
 
 __END_DECLS
-- 
2.8.0.rc3.226.g39d4020

-- 
You received this message because you are subscribed to the Google Groups 
"Akaros" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akaros+unsubscr...@googlegroups.com.
To post to this group, send email to akaros@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[akaros] [PATCH 2/3] vmm/vmrunkernel: make 60K of low 1M available in e820map.

2016-06-08 Thread Ronald G. Minnich
Linux needs to be able to allocate several pages in low memory.
We had hoped to get around this limit, but it's not possible.

The range 0 to 16M was formerly marked as E820_RESERVED.
Set up 60K of memory (4K->64K) as E820_RAM for guest use.
Continue to leave the 0-4k region as E820_RESERVED, as well
as 64K to 16M.

Change-Id: Icd48bb8b7d6501269d3edb6a8e5b1d7899826a50
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 tests/vmm/vmrunkernel.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/tests/vmm/vmrunkernel.c b/tests/vmm/vmrunkernel.c
index 6dd66a4..116baed 100644
--- a/tests/vmm/vmrunkernel.c
+++ b/tests/vmm/vmrunkernel.c
@@ -556,11 +556,20 @@ int main(int argc, char **argv)
memset(bp, 0, 4096);
 
/* Put the e820 memory region information in the boot_params */
-   bp->e820_entries = 3;
+   bp->e820_entries = 5;
int e820i = 0;
 
+   /* Give it just a tiny bit of memory -- 60k -- at low memory. */
bp->e820_map[e820i].addr = 0;
-   bp->e820_map[e820i].size = 16 * 1048576;
+   bp->e820_map[e820i].size = 4 * 1024;
+   bp->e820_map[e820i++].type = E820_RESERVED;
+
+   bp->e820_map[e820i].addr = 4 * 1024;
+   bp->e820_map[e820i].size = 64 * 1024 - 4 * 1024;
+   bp->e820_map[e820i++].type = E820_RAM;
+
+   bp->e820_map[e820i].addr = 64 * 1024;
+   bp->e820_map[e820i].size = 16 * 1048576 - 64 * 1024;
bp->e820_map[e820i++].type = E820_RESERVED;
 
bp->e820_map[e820i].addr = 16 * 1048576;
-- 
2.8.0.rc3.226.g39d4020

-- 
You received this message because you are subscribed to the Google Groups 
"Akaros" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akaros+unsubscr...@googlegroups.com.
To post to this group, send email to akaros@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[akaros] [PATCH] vmm: properly set CR4 SHADOW and GUEST_HOST_MASK registers.

2016-06-06 Thread Ronald G. Minnich
Set the SHADOW register to 0, and set the GUEST_HOST_MASK
to CR4_VMXE. This ensures that the guest can set the
CR4_VMXE in its CR4 copy to 0, which Linux wants to do.
This eliminates the patch we used to need in Linux
in the early startup assembly code (head_64.S).

Change-Id: I8ee64a5485abef1b5c1d8b07a705f0642335a038
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 kern/arch/x86/vmm/intel/vmx.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/kern/arch/x86/vmm/intel/vmx.c b/kern/arch/x86/vmm/intel/vmx.c
index 5a93c5a..14e0588 100644
--- a/kern/arch/x86/vmm/intel/vmx.c
+++ b/kern/arch/x86/vmm/intel/vmx.c
@@ -860,7 +860,11 @@ static int vmx_setup_initial_guest_state(struct proc *p,
X86_CR0_MP | X86_CR0_ET | X86_CR0_NE);
vmcs_writel(GUEST_CR3, rcr3());
vmcs_writel(GUEST_CR4, cr4);
-   vmcs_writel(CR4_READ_SHADOW, cr4);
+   /* The only bits that matter in this shadow are those that are
+* set in CR4_GUEST_HOST_MASK.  TODO: do we need to separate
+* the setting of this value from that of
+* CR4_GUEST_HOST_MASK? */
+   vmcs_writel(CR4_READ_SHADOW, 0);
vmcs_writel(GUEST_IA32_EFER, EFER_LME | EFER_LMA |
EFER_SCE /*| EFER_FFXSR */ );
vmcs_writel(GUEST_GDTR_BASE, 0);
@@ -1096,7 +1100,17 @@ static void vmx_setup_vmcs(struct guest_pcore *gpc)
vmcs_write32(VM_ENTRY_CONTROLS, vmcs_config.vmentry_ctrl);
 
vmcs_writel(CR0_GUEST_HOST_MASK, 0);// ~0ul);
-   vmcs_writel(CR4_GUEST_HOST_MASK, 0);// ~0ul);
+
+   /* Mask some bits in CR4 as host-owned by setting them in this
+* VMCS entry.  For example, for now, we mark the CR4_VMXE bit
+* as host owned.  Right now, when Linux boots, it wants to
+* set CR4_VMXE to 0 at first, which is fine -- we do not want
+* to think about nested virtualization yet. But if we don't
+* mark this bit as host owned we get a VMEXIT. Marking
+* CR4_VMXE as host owned means that the reads and writes go
+* to the CR4_READ_SHADOW, and we've set the bit to 0
+* there. */
+   vmcs_writel(CR4_GUEST_HOST_MASK, CR4_VMXE);
 
//kvm_write_tsc(>gpc, 0);
vmcs_writel(TSC_OFFSET, 0);
-- 
2.8.0.rc3.226.g39d4020

-- 
You received this message because you are subscribed to the Google Groups 
"Akaros" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akaros+unsubscr...@googlegroups.com.
To post to this group, send email to akaros@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[akaros] [PATCH 1/3] VMM: clean up IO emulation.

2016-06-06 Thread Ronald G. Minnich
The io emulation code was written early in the game and was not correct
in several ways.

The big change is that we DO note that an IO address is not supported
but DO NOT consider it an error. The hardware does not, and we should
not. We do log a message to stderr that there was IO to an unsupported
address, but people commonly do such IO operations to implement, e.g.,
timing loops. It's perfectly legal to do IO to nonexistant config space
registers, as well, so it makes no sense to check those either. We can't
assume that an IO to a bogus address or config space register is not
intended or mistaken.

There is only one error return from the io() function: IO instructions
we did not handle because we could not interpret them. In that case, the
function really has no option but to return false. In all other cases,
it should return true.

As a result, all the configread/write functions become void, io() itself
now returns a bool, and handle_io returns what io returns.

We should consider changing regp() so that writes "to air" go to a
different place than reads "from air", as one might argue that reads
"from air" should return all 1s. In real hardware, not even this
reasonable rule always applies, so it's hard to make a strong argument
either way.

Change-Id: Ifec56655528f748183a35663c8ef20b8bc486b35
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 user/vmm/include/vmm/vmm.h |  2 +-
 user/vmm/io.c  | 75 ++
 user/vmm/vmexit.c  |  3 +-
 3 files changed, 51 insertions(+), 29 deletions(-)

diff --git a/user/vmm/include/vmm/vmm.h b/user/vmm/include/vmm/vmm.h
index 971f2d0..8dedb28 100644
--- a/user/vmm/include/vmm/vmm.h
+++ b/user/vmm/include/vmm/vmm.h
@@ -34,7 +34,7 @@ struct virtual_machine {
 char *regname(uint8_t reg);
 int decode(struct guest_thread *vm_thread, uint64_t *gpa, uint8_t *destreg,
uint64_t **regp, int *store, int *size, int *advance);
-int io(struct guest_thread *vm_thread);
+bool io(struct guest_thread *vm_thread);
 void showstatus(FILE *f, struct guest_thread *vm_thread);
 int msrio(struct guest_thread *vm_thread, struct vmm_gpcore_init *gpci,
   uint32_t opcode);
diff --git a/user/vmm/io.c b/user/vmm/io.c
index 9e83057..f602c98 100644
--- a/user/vmm/io.c
+++ b/user/vmm/io.c
@@ -53,23 +53,21 @@ void regp(uint32_t **reg)
//printf("-->regp *reg 0x%lx\n", **reg);
 }
 
-static uint32_t configaddr(uint32_t val)
+static void configaddr(uint32_t val)
 {
printf("%s 0x%lx\n", __func__, val);
cf8 = val;
-   return 0;
 }
 
-static uint32_t configread32(uint32_t edx, uint64_t *reg)
+static void configread32(uint32_t edx, uint64_t *reg)
 {
uint32_t *r = 
regp();
*reg = *r;
printf("%s: 0x%lx 0x%lx, 0x%lx 0x%lx\n", __func__, cf8, edx, r, *reg);
-   return 0;
 }
 
-static uint32_t configread16(uint32_t edx, uint64_t *reg)
+static void configread16(uint32_t edx, uint64_t *reg)
 {
uint64_t val;
int which = ((edx&2)>>1) * 16;
@@ -77,10 +75,9 @@ static uint32_t configread16(uint32_t edx, uint64_t *reg)
val >>= which;
*reg = val;
printf("%s: 0x%lx, 0x%lx 0x%lx\n", __func__, edx, val, *reg);
-   return 0;
 }
 
-static uint32_t configread8(uint32_t edx, uint64_t *reg)
+static void configread8(uint32_t edx, uint64_t *reg)
 {
uint64_t val;
int which = (edx&3) * 8;
@@ -88,28 +85,24 @@ static uint32_t configread8(uint32_t edx, uint64_t *reg)
val >>= which;
*reg = val;
printf("%s: 0x%lx, 0x%lx 0x%lx\n", __func__, edx, val, *reg);
-   return 0;
 }
 
-static int configwrite32(uint32_t addr, uint32_t val)
+static void configwrite32(uint32_t addr, uint32_t val)
 {
uint32_t *r = 
regp();
*r = val;
printf("%s 0x%lx 0x%lx\n", __func__, addr, val);
-   return 0;
 }
 
-static int configwrite16(uint32_t addr, uint16_t val)
+static void configwrite16(uint32_t addr, uint16_t val)
 {
printf("%s 0x%lx 0x%lx\n", __func__, addr, val);
-   return 0;
 }
 
-static int configwrite8(uint32_t addr, uint8_t val)
+static void configwrite8(uint32_t addr, uint8_t val)
 {
printf("%s 0x%lx 0x%lx\n", __func__, addr, val);
-   return 0;
 }
 
 /* this is very minimal. It needs to move to vmm/io.c but we don't
@@ -119,7 +112,7 @@ static int configwrite8(uint32_t addr, uint8_t val)
  * It would have been nice had intel encoded the IO exit info as nicely as they
  * encoded, some of the other exits.
  */
-int io(struct guest_thread *vm_thread)
+bool io(struct guest_thread *vm_thread)
 {
 
/* Get a pointer to the memory at %rip. This is quite messy and part of 
the
@@ -147,14 +140,31 @@ int io(struct guest_thread *vm_thread)
/* out at %edx */
if (edx == 0xcf8) {
   

[akaros] [PATCH 2/3] user/vmm: print RIP and hexdump of RIP[0:16] on failed vmexit handling.

2016-06-06 Thread Ronald G. Minnich
Sometimes the current status dump is not quite enough for debugging.
One example is when the RIP somehow ends up with a weird value,
e.g. the middle of allocated memory, and that code is hence
not visible in the disassembled kernel.

The exit now prints a bit more information, and a hex dump of
the 16 bytes starting at RIP. This little extra bit of information
allowed me to figure out a strange problem I was having.

Change-Id: Ic37396d48bfe8934d7943e9ac6729540468badfa
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 user/vmm/sched.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/user/vmm/sched.c b/user/vmm/sched.c
index a489f6d..2edc42e 100644
--- a/user/vmm/sched.c
+++ b/user/vmm/sched.c
@@ -322,6 +322,17 @@ static void __ctlr_entry(void)
struct virtual_machine *vm = gth_to_vm(cth->buddy);
 
if (!handle_vmexit(cth->buddy)) {
+   struct vm_trapframe *vm_tf = gth_to_vmtf(cth->buddy);
+
+   fprintf(stderr, "vmm: handle_vmexit returned false\n");
+   fprintf(stderr,
+"Note: this may be a kernel module, not the kernel\n");
+   fprintf(stderr, "RIP was %p:\n", (void *)vm_tf->tf_rip);
+   /* TODO: properly walk the kernel page tables to map the tf_rip
+* to a physical address. For now, however, this hack is good
+* enough.
+*/
+   hexdump(stderr, (void *)(vm_tf->tf_rip & 0x3fff), 16);
showstatus(stderr, cth->buddy);
exit(0);
}
-- 
2.8.0.rc3.226.g39d4020

-- 
You received this message because you are subscribed to the Google Groups 
"Akaros" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akaros+unsubscr...@googlegroups.com.
To post to this group, send email to akaros@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[akaros] [PATCH 2/2] user/vmm: print RIP and hexdump of RIP[0:16] on failed vmexit handling.

2016-06-03 Thread Ronald G. Minnich
Sometimes the current status dump is not quite enough for debugging.
One example is when the RIP somehow ends up with a weird value,
e.g. the middle of allocated memory, and that code is hence
not visible in the disassembled kernel.

The exit now prints a bit more information, and a hex dump of
the 16 bytes starting at RIP. This little extra bit of information
allowed me to figure out a strange problem I was having.

Change-Id: Ic37396d48bfe8934d7943e9ac6729540468badfa
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 user/vmm/sched.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/user/vmm/sched.c b/user/vmm/sched.c
index a489f6d..2edc42e 100644
--- a/user/vmm/sched.c
+++ b/user/vmm/sched.c
@@ -322,6 +322,17 @@ static void __ctlr_entry(void)
struct virtual_machine *vm = gth_to_vm(cth->buddy);
 
if (!handle_vmexit(cth->buddy)) {
+   struct vm_trapframe *vm_tf = gth_to_vmtf(cth->buddy);
+
+   fprintf(stderr, "vmm: handle_vmexit returned false\n");
+   fprintf(stderr,
+"Note: this may be a kernel module, not the kernel\n");
+   fprintf(stderr, "RIP was %p:\n", (void *)vm_tf->tf_rip);
+   /* TODO: properly walk the kernel page tables to map the tf_rip
+* to a physical address. For now, however, this hack is good
+* enough.
+*/
+   hexdump(stderr, (void *)(vm_tf->tf_rip & 0x3fff), 16);
showstatus(stderr, cth->buddy);
exit(0);
}
-- 
2.8.0.rc3.226.g39d4020

-- 
You received this message because you are subscribed to the Google Groups 
"Akaros" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akaros+unsubscr...@googlegroups.com.
To post to this group, send email to akaros@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[akaros] [PATCH 1/2] VMM: clean up IO emulation.

2016-06-03 Thread Ronald G. Minnich
The io emulation code was written early in the game and was not correct
in several ways.

The big change is that we DO note that an IO address is not supported
but DO NOT consider it an error. The hardware does not, and we should
not. We do log a message to stderr that there was IO to an unsupported
address, but people commonly do such IO operations to implement, e.g.,
timing loops. It's perfectly legal to do IO to nonexistant config space
registers, as well, so it makes no sense to check those either. We can't
assume that an IO to a bogus address or config space register is not
intended or mistaken.

There is only one error return from the io() function: IO instructions
we did not handle because we could not interpret them. In that case, the
function really has no option but to return false. In all other cases,
it should return true.

As a result, all the configread/write functions become void, io() itself
now returns a bool, and handle_io returns what io returns.

We should consider changing regp() so that writes "to air" go to a
different place than reads "from air", as one might argue that reads
"from air" should return all 1s. In real hardware, not even this
reasonable rule always applies, so it's hard to make a strong argument
either way.

Change-Id: Ifec56655528f748183a35663c8ef20b8bc486b35
Signed-off-by: Ronald G. Minnich <rminn...@gmail.com>
---
 user/vmm/include/vmm/vmm.h |  2 +-
 user/vmm/io.c  | 75 ++
 user/vmm/vmexit.c  |  3 +-
 3 files changed, 51 insertions(+), 29 deletions(-)

diff --git a/user/vmm/include/vmm/vmm.h b/user/vmm/include/vmm/vmm.h
index 971f2d0..8dedb28 100644
--- a/user/vmm/include/vmm/vmm.h
+++ b/user/vmm/include/vmm/vmm.h
@@ -34,7 +34,7 @@ struct virtual_machine {
 char *regname(uint8_t reg);
 int decode(struct guest_thread *vm_thread, uint64_t *gpa, uint8_t *destreg,
uint64_t **regp, int *store, int *size, int *advance);
-int io(struct guest_thread *vm_thread);
+bool io(struct guest_thread *vm_thread);
 void showstatus(FILE *f, struct guest_thread *vm_thread);
 int msrio(struct guest_thread *vm_thread, struct vmm_gpcore_init *gpci,
   uint32_t opcode);
diff --git a/user/vmm/io.c b/user/vmm/io.c
index 9e83057..f602c98 100644
--- a/user/vmm/io.c
+++ b/user/vmm/io.c
@@ -53,23 +53,21 @@ void regp(uint32_t **reg)
//printf("-->regp *reg 0x%lx\n", **reg);
 }
 
-static uint32_t configaddr(uint32_t val)
+static void configaddr(uint32_t val)
 {
printf("%s 0x%lx\n", __func__, val);
cf8 = val;
-   return 0;
 }
 
-static uint32_t configread32(uint32_t edx, uint64_t *reg)
+static void configread32(uint32_t edx, uint64_t *reg)
 {
uint32_t *r = 
regp();
*reg = *r;
printf("%s: 0x%lx 0x%lx, 0x%lx 0x%lx\n", __func__, cf8, edx, r, *reg);
-   return 0;
 }
 
-static uint32_t configread16(uint32_t edx, uint64_t *reg)
+static void configread16(uint32_t edx, uint64_t *reg)
 {
uint64_t val;
int which = ((edx&2)>>1) * 16;
@@ -77,10 +75,9 @@ static uint32_t configread16(uint32_t edx, uint64_t *reg)
val >>= which;
*reg = val;
printf("%s: 0x%lx, 0x%lx 0x%lx\n", __func__, edx, val, *reg);
-   return 0;
 }
 
-static uint32_t configread8(uint32_t edx, uint64_t *reg)
+static void configread8(uint32_t edx, uint64_t *reg)
 {
uint64_t val;
int which = (edx&3) * 8;
@@ -88,28 +85,24 @@ static uint32_t configread8(uint32_t edx, uint64_t *reg)
val >>= which;
*reg = val;
printf("%s: 0x%lx, 0x%lx 0x%lx\n", __func__, edx, val, *reg);
-   return 0;
 }
 
-static int configwrite32(uint32_t addr, uint32_t val)
+static void configwrite32(uint32_t addr, uint32_t val)
 {
uint32_t *r = 
regp();
*r = val;
printf("%s 0x%lx 0x%lx\n", __func__, addr, val);
-   return 0;
 }
 
-static int configwrite16(uint32_t addr, uint16_t val)
+static void configwrite16(uint32_t addr, uint16_t val)
 {
printf("%s 0x%lx 0x%lx\n", __func__, addr, val);
-   return 0;
 }
 
-static int configwrite8(uint32_t addr, uint8_t val)
+static void configwrite8(uint32_t addr, uint8_t val)
 {
printf("%s 0x%lx 0x%lx\n", __func__, addr, val);
-   return 0;
 }
 
 /* this is very minimal. It needs to move to vmm/io.c but we don't
@@ -119,7 +112,7 @@ static int configwrite8(uint32_t addr, uint8_t val)
  * It would have been nice had intel encoded the IO exit info as nicely as they
  * encoded, some of the other exits.
  */
-int io(struct guest_thread *vm_thread)
+bool io(struct guest_thread *vm_thread)
 {
 
/* Get a pointer to the memory at %rip. This is quite messy and part of 
the
@@ -147,14 +140,31 @@ int io(struct guest_thread *vm_thread)
/* out at %edx */
if (edx == 0xcf8) {