Treat tabs as having eight spaces instead of four
For whatever bad reason, we chose to treat tabs as four spaces instead
of eight. e.g. in vim, tabstop=4.
That's a huge pain - both when dealing with other tools and when
switching between projects. I don't particularly like having
per-project vim settings and whatnot. Plus, that's a bit harder for
other people who look at our code and have their vim/emacs set to 8
space tabs.
I had regretted that for a long time, but I didn't want to make the
change for two reasons:
1) With other people working on the project, changes of this sort can
lead to merge conflicts. Since I'm the only one working on it, for the
most part, this isn't a concern.
2) The bigger reason is that major reformatting changes break git blame.
However, there are tools that can ignore commits when running git blame.
Chromium has git hyper-blame. I thought that feature ought to be baked
into git, so I have a patchset out for git to do so. Either way, I'll
either have my own patched git or the feature will get merged. In a
future commit, I'll have instructions for how to use that feature.
A lot of our files didn't need too much attention, due to our old
"spaces for formatting" policy. I didn't change those to use tabs
instead of spaces for the formatting either. I expect newer code will
just do whatever people's editors do. I didn't want to change more
lines than were needed, and the code looks the same either way.
The biggest offenders were indented comments. Structs with
column-aligned members needed some work too. I did most of that stuff
manually, since the tools do a mediocre job.
Since I was making changes, I also fixed up the switch-case indenting:
don't do an extra level of indentation for the case keywords. Doing
this now actually helped with the 8-space tab change, since switch
statements got a few spaces to work with.
A few of the kernel's C files were so badly messed up that I just used
clang-format on them. Same for Plan 9 files that had been
clang-formatted before and hadn't been heavily modified by us.
Clang-format caused a few problems with its "alphabetized headers"
policy. That was fun.
Higher-quality (subjectively) code didn't need as much work as older,
poorer code. Specifically, code with way too many levels of indentation
looks even worse than before - that's actually a benefit of 8-space
tabs: it tells you when your code is bad. A lot of that older code
needs a more serious refactoring, which this commit does not do.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
diff --git a/.clang-format b/.clang-format
index 65fc911..7080dce 100644
--- a/.clang-format
+++ b/.clang-format
@@ -1,6 +1,6 @@
BasedOnStyle: LLVM
-IndentWidth: 4
-TabWidth: 4
+IndentWidth: 8
+TabWidth: 8
UseTab: ForIndentation
BreakBeforeBraces: Linux
AllowShortIfStatementsOnASingleLine: false
diff --git a/Documentation/Contributing.md b/Documentation/Contributing.md
index d7d672a..991c73c 100644
--- a/Documentation/Contributing.md
+++ b/Documentation/Contributing.md
@@ -1,6 +1,6 @@
Akaros Contribution Policies
===========================
-**2016-03-14** Barret Rhoden (`brho`)
+**2019-03-14** Barret Rhoden (`brho`)
Interested in contributing to Akaros? This document covers coding standards,
version control usage, and other contribution policies.
@@ -148,20 +148,25 @@
Coding Standard
---------------------------
-Our coding standard is similar to the Linux kernel style (but with a tabstop of
-4), so when in doubt, do what they do.
+We use the Linux kernel coding style. When in doubt, do what they do.
+ If you are bringing in code from another project other than Linux, such as
-Plan 9, run clang-format on it. We have a format file in the root of the Akaros
-repo. clang-format isn't perfect, but it's close enough. Linux code is usually
-fine (even with 8 space tabs), and formatters sometimes do more harm than good
-on that code. You can try clang-format for Linux code and see how it works.
+ Plan 9, consider running clang-format on it. We have a format file in the
+ root of the Akaros repo. clang-format isn't perfect, but it's close enough.
+ We do this for Plan 9 code, which we heavily internalize, but if the code is
+ a library (random, crypto, zlib) that we won't touch, then just leave it as
+ is. That makes it easier to update the library.
+ You'll note that old code may lack the correct style, especially due to the
large bodies of code from other systems involved. Typically, we fix it when
fixing the code for other reasons, so that git blame points at the most
recent relevant change.
++ We can do major reformatting commits and have git blame ignore them. Talk
+ with brho before doing major reformatting.
+
++ Indentation is done with tabs, 8-spaces wide.
+
+ No spaces after the name of a function in a call. For example,
`printk("hello")` not `printk ("hello")`.
@@ -181,8 +186,11 @@
and one of them has braces, put braces on both. An `else` line should start
with a brace.
-+ Beginning-of-line indentation via tabs, not spaces. Use spaces for
- additional formatting (such as lining up text when word wrapping).
++ You can use tabs or spaces for indentation, so long as the spaces follow the
+ tabs and they are not intermixed. Older code used tabs for indentation, and
+ spaces for formatting/aligning. Using spaces for alignment was easier when
+ we changed from four-space tabs to eight-space tabs. That style is also
+ eaiser for some scenarios and editors. Don't worry too much about it.
+ Preprocessor macros are usually upper-case. Try to avoid using macros
unless necessary (I prefer static inlines).
@@ -213,6 +221,8 @@
hierarchies. Keep in mind that people will need to work with and find these
files (even via tab completion, it can be a pain).
++ Consider aligning the members of structs with multiple values. I often align
+ the members (not the types) at 40 chars. This is a stylistic choice.
Git Workflow
------------------------------------
diff --git a/kern/arch/riscv/arch.h b/kern/arch/riscv/arch.h
index 76e8c9a..53b09ca 100644
--- a/kern/arch/riscv/arch.h
+++ b/kern/arch/riscv/arch.h
@@ -86,9 +86,10 @@
// < 0 means more disabled calls have been made
// Mostly doing this so we can call disable_irqsave first if we want
- // one side or another "gets a point" if interrupts were already the
- // way it wanted to go. o/w, state stays at 0. if the state was not 0
- // then, enabling/disabling isn't even an option. just increment/decrement
+ // one side or another "gets a point" if interrupts were already the way
+ // it wanted to go. o/w, state stays at 0. if the state was not 0
+ // then, enabling/disabling isn't even an option. just
+ // increment/decrement
// if enabling is winning or tied, make sure it's enabled
if ((*state == 0) && !irq_is_enabled())
diff --git a/kern/arch/riscv/cboot.c b/kern/arch/riscv/cboot.c
index cd6717b..3b031a3 100644
--- a/kern/arch/riscv/cboot.c
+++ b/kern/arch/riscv/cboot.c
@@ -1,37 +1,37 @@
-#include <multiboot.h>
-#include <ros/memlayout.h>
#include <arch/arch.h>
#include <arch/mmu.h>
-#include <string.h>
#include <assert.h>
-#include <stdio.h>
+#include <multiboot.h>
#include <pmap.h>
+#include <ros/memlayout.h>
+#include <stdio.h>
+#include <string.h>
#define MAX_KERNBASE_SIZE (KERN_VMAP_TOP - KERNBASE)
-uint32_t num_cores = 1; // this must not be in BSS
+uint32_t num_cores = 1; // this must not be in BSS
-static uint64_t
-mem_size(uint64_t sz_mb)
+static uint64_t mem_size(uint64_t sz_mb)
{
uint64_t sz = (uint64_t)sz_mb * 1024 * 1024;
- return MIN(sz, MIN(MAX_KERNBASE_SIZE, (uint64_t)L1PGSIZE * NPTENTRIES));
+
+ return MIN(sz, MIN(MAX_KERNBASE_SIZE, (uint64_t)L1PGSIZE * NPTENTRIES));
}
-void pagetable_init(uint32_t memsize_mb, pte_t* l1pt, pte_t* l1pt_boot,
- pte_t* l2pt)
+void pagetable_init(uint32_t memsize_mb, pte_t *l1pt, pte_t *l1pt_boot,
+ pte_t *l2pt)
{
static_assert(KERNBASE % L1PGSIZE == 0);
// The boot L1 PT retains the identity mapping [0,memsize-1],
// whereas the post-boot L1 PT does not.
uint64_t memsize = mem_size(memsize_mb);
- for(uint64_t pa = 0; pa < memsize+L1PGSIZE-1; pa += L1PGSIZE)
- {
+
+ for (uint64_t pa = 0; pa < memsize + L1PGSIZE - 1; pa += L1PGSIZE) {
pte_t pte = build_pte(pa, PTE_KERN_RW | PTE_E);
- l1pt_boot[L1X(pa)] = pte; // identity mapping
- l1pt_boot[L1X(KERNBASE+pa)] = pte; // KERNBASE mapping
- l1pt[L1X(KERNBASE+pa)] = pte; // KERNBASE mapping
+ l1pt_boot[L1X(pa)] = pte; // identity mapping
+ l1pt_boot[L1X(KERNBASE + pa)] = pte; // KERNBASE mapping
+ l1pt[L1X(KERNBASE + pa)] = pte; // KERNBASE mapping
}
#ifdef __riscv64
@@ -47,15 +47,16 @@
l1pt[L1X(KERN_LOAD_ADDR)] = PTD(l2pt);
l1pt_boot[L1X(KERN_LOAD_ADDR)] = PTD(l2pt);
- for (uintptr_t pa = 0; pa < (uintptr_t)(-KERN_LOAD_ADDR); pa += L2PGSIZE)
- l2pt[L2X(KERN_LOAD_ADDR+pa)] = build_pte(pa, PTE_KERN_RW | PTE_E);
+ for (uintptr_t pa = 0; pa < (uintptr_t)(-KERN_LOAD_ADDR);
+ pa += L2PGSIZE)
+ l2pt[L2X(KERN_LOAD_ADDR + pa)] =
+ build_pte(pa, PTE_KERN_RW | PTE_E);
#else
- (void) l2pt; // don't need this for rv32
+ (void)l2pt; // don't need this for rv32
#endif
}
-void
-cmain(uint32_t memsize_mb, uint32_t nc)
+void cmain(uint32_t memsize_mb, uint32_t nc)
{
multiboot_info_t mbi;
memset(&mbi, 0, sizeof(mbi));
@@ -64,7 +65,8 @@
num_cores = nc;
- extern void kernel_init(multiboot_info_t *mboot_info);
+ extern void kernel_init(multiboot_info_t * mboot_info);
+
// kernel_init expects a pre-relocation mbi address
- kernel_init((multiboot_info_t*)PADDR(&mbi));
+ kernel_init((multiboot_info_t *)PADDR(&mbi));
}
diff --git a/kern/arch/riscv/console.c b/kern/arch/riscv/console.c
index 1f92e1a..34881d4 100644
--- a/kern/arch/riscv/console.c
+++ b/kern/arch/riscv/console.c
@@ -1,10 +1,10 @@
#include <arch/console.h>
-#include <pmap.h>
#include <atomic.h>
-#include <smp.h>
#include <kmalloc.h>
#include <monitor.h>
+#include <pmap.h>
#include <process.h>
+#include <smp.h>
int cons_get_any_char(void)
{
@@ -13,14 +13,14 @@
void cons_init()
{
- mtpcr(PCR_SR, mfpcr(PCR_SR) | (1 << (IRQ_HOST+SR_IM_SHIFT)));
- while (mtpcr(PCR_TOHOST, 0x01L << 56));
+ mtpcr(PCR_SR, mfpcr(PCR_SR) | (1 << (IRQ_HOST + SR_IM_SHIFT)));
+ while (mtpcr(PCR_TOHOST, 0x01L << 56))
+ ;
}
// `High'-level console I/O. Used by readline and cprintf.
-void
-cputbuf(const char* str, int len)
+void cputbuf(const char *str, int len)
{
for (int i = 0; i < len; i++)
cputchar(str[i]);
@@ -32,25 +32,23 @@
// Low-level console I/O
-void
-cputchar(int c)
+void cputchar(int c)
{
- while (mtpcr(PCR_TOHOST, 0x0101000000000000 | (unsigned char)c));
+ while (mtpcr(PCR_TOHOST, 0x0101000000000000 | (unsigned char)c))
+ ;
}
-int
-getchar(void)
+int getchar(void)
{
char c = 'x';
- #warning "implement me"
+#warning "implement me"
/* maybe do a qio read */
return c;
}
-int
-iscons(int fdnum)
+int iscons(int fdnum)
{
// used by readline
return 1;
diff --git a/kern/arch/riscv/cpuinfo.c b/kern/arch/riscv/cpuinfo.c
index ba71bc1..ecf086b 100644
--- a/kern/arch/riscv/cpuinfo.c
+++ b/kern/arch/riscv/cpuinfo.c
@@ -1,51 +1,49 @@
#include <arch/arch.h>
#include <arch/mmu.h>
-#include <stdio.h>
#include <assert.h>
-#include <smp.h>
-#include <umem.h>
#include <pmap.h>
+#include <smp.h>
+#include <stdio.h>
+#include <umem.h>
-static void
-static_asserts_can_go_here()
+static void static_asserts_can_go_here(void)
{
static_assert(SIZEOF_HW_TRAPFRAME == sizeof(struct hw_trapframe));
}
-void
-print_cpuinfo(void)
+void print_cpuinfo(void)
{
int id = mfpcr(PCR_IMPL);
- const char* name = "(unknown implementation)";
+ const char *name = "(unknown implementation)";
if (id == 1)
- name = "ISA Simulator";
+ name = "ISA Simulator";
else if (id == 2)
- name = "Rocket64";
+ name = "Rocket64";
cprintf("CPU Info: RISC-V %s\n", name);
}
#warning "convert pgdir* to pgdir_t"
void show_mapping(pgdir_t *pt, uintptr_t start, size_t size)
{
- pte_t* pte;
+ pte_t *pte;
uintptr_t i;
- page_t* page;
+ page_t *page;
- cprintf(" Virtual Physical SR SW SX UR UW UX D R\n");
- cprintf("------------------------------------------------------------\n");
- for(i = 0; i < size; i += PGSIZE, start += PGSIZE)
- {
- page = page_lookup(pt, (void*)start, &pte);
- cprintf("%016p ",start);
- if(page)
- {
+ cprintf(
+ " Virtual Physical SR SW SX UR UW UX D R\n");
+ cprintf(
+ "------------------------------------------------------------\n");
+ for (i = 0; i < size; i += PGSIZE, start += PGSIZE) {
+ page = page_lookup(pt, (void *)start, &pte);
+ cprintf("%016p ", start);
+ if (page) {
cprintf("%016p %1d %1d %1d %1d %1d %1d %1d %1d\n",
- page2pa(page),
- !!(*pte & PTE_SR), !!(*pte & PTE_SW), !!(*pte & PTE_SX),
- !!(*pte & PTE_UR), !!(*pte & PTE_UW), !!(*pte & PTE_UX),
- !!(*pte & PTE_D), !!(*pte & PTE_R));
- }
- else
- cprintf("%016p\n",0);
+ page2pa(page), !!(*pte & PTE_SR),
+ !!(*pte & PTE_SW), !!(*pte & PTE_SX),
+ !!(*pte & PTE_UR), !!(*pte & PTE_UW),
+ !!(*pte & PTE_UX), !!(*pte & PTE_D),
+ !!(*pte & PTE_R));
+ } else
+ cprintf("%016p\n", 0);
}
}
diff --git a/kern/arch/riscv/env.c b/kern/arch/riscv/env.c
index 2b7d32d..0adcdd0 100644
--- a/kern/arch/riscv/env.c
+++ b/kern/arch/riscv/env.c
@@ -1,10 +1,10 @@
-#include <trap.h>
-#include <env.h>
-#include <assert.h>
#include <arch/arch.h>
+#include <assert.h>
+#include <env.h>
#include <pmap.h>
+#include <trap.h>
-void save_fp_state(ancillary_state_t* silly)
+void save_fp_state(ancillary_state_t *silly)
{
uintptr_t sr = enable_fp();
uint32_t fsr = read_fsr();
@@ -46,7 +46,7 @@
mtpcr(PCR_SR, sr);
}
-void restore_fp_state(ancillary_state_t* silly)
+void restore_fp_state(ancillary_state_t *silly)
{
uintptr_t sr = enable_fp();
uint32_t fsr = silly->fsr;
@@ -92,70 +92,74 @@
{
uintptr_t sr = enable_fp();
- asm("fcvt.d.w f0, x0; fcvt.d.w f1 ,x0; fcvt.d.w f2, x0; fcvt.d.w f3, x0;");
- asm("fcvt.d.w f4, x0; fcvt.d.w f5, x0; fcvt.d.w f6, x0; fcvt.d.w f7, x0;");
- asm("fcvt.d.w f8, x0; fcvt.d.w f9, x0; fcvt.d.w f10,x0; fcvt.d.w f11,x0;");
- asm("fcvt.d.w f12,x0; fcvt.d.w f13,x0; fcvt.d.w f14,x0; fcvt.d.w f15,x0;");
- asm("fcvt.d.w f16,x0; fcvt.d.w f17,x0; fcvt.d.w f18,x0; fcvt.d.w f19,x0;");
- asm("fcvt.d.w f20,x0; fcvt.d.w f21,x0; fcvt.d.w f22,x0; fcvt.d.w f23,x0;");
- asm("fcvt.d.w f24,x0; fcvt.d.w f25,x0; fcvt.d.w f26,x0; fcvt.d.w f27,x0;");
- asm("fcvt.d.w f28,x0; fcvt.d.w f29,x0; fcvt.d.w f30,x0; fcvt.d.w f31,x0;");
+ asm("fcvt.d.w f0, x0; fcvt.d.w f1 ,x0; fcvt.d.w f2, x0; fcvt.d.w f3, "
+ "x0;");
+ asm("fcvt.d.w f4, x0; fcvt.d.w f5, x0; fcvt.d.w f6, x0; fcvt.d.w f7, "
+ "x0;");
+ asm("fcvt.d.w f8, x0; fcvt.d.w f9, x0; fcvt.d.w f10,x0; fcvt.d.w "
+ "f11,x0;");
+ asm("fcvt.d.w f12,x0; fcvt.d.w f13,x0; fcvt.d.w f14,x0; fcvt.d.w "
+ "f15,x0;");
+ asm("fcvt.d.w f16,x0; fcvt.d.w f17,x0; fcvt.d.w f18,x0; fcvt.d.w "
+ "f19,x0;");
+ asm("fcvt.d.w f20,x0; fcvt.d.w f21,x0; fcvt.d.w f22,x0; fcvt.d.w "
+ "f23,x0;");
+ asm("fcvt.d.w f24,x0; fcvt.d.w f25,x0; fcvt.d.w f26,x0; fcvt.d.w "
+ "f27,x0;");
+ asm("fcvt.d.w f28,x0; fcvt.d.w f29,x0; fcvt.d.w f30,x0; fcvt.d.w "
+ "f31,x0;");
asm("mtfsr x0");
mtpcr(PCR_SR, sr);
}
-static int
-user_mem_walk_recursive(env_t* e, uintptr_t start, size_t len,
- mem_walk_callback_t callback, void* arg,
- mem_walk_callback_t pt_callback, void* pt_arg,
- pte_t* pt, int level)
+static int user_mem_walk_recursive(env_t *e, uintptr_t start, size_t len,
+ mem_walk_callback_t callback, void *arg,
+ mem_walk_callback_t pt_callback,
+ void *pt_arg, pte_t *pt, int level)
{
int ret = 0;
- int pgshift = L1PGSHIFT - level*(L1PGSHIFT-L2PGSHIFT);
+ int pgshift = L1PGSHIFT - level * (L1PGSHIFT - L2PGSHIFT);
uintptr_t pgsize = 1UL << pgshift;
- uintptr_t start_idx = (start >> pgshift) & (NPTENTRIES-1);
- uintptr_t end_idx = ((start+len-1) >> pgshift) & (NPTENTRIES-1);
+ uintptr_t start_idx = (start >> pgshift) & (NPTENTRIES - 1);
+ uintptr_t end_idx = ((start + len - 1) >> pgshift) & (NPTENTRIES - 1);
- for(uintptr_t idx = start_idx; idx <= end_idx; idx++)
- {
- uintptr_t pgaddr = ROUNDDOWN(start, pgsize) + (idx-start_idx)*pgsize;
- pte_t* pte = &pt[idx];
+ for (uintptr_t idx = start_idx; idx <= end_idx; idx++) {
+ uintptr_t pgaddr =
+ ROUNDDOWN(start, pgsize) + (idx - start_idx) * pgsize;
+ pte_t *pte = &pt[idx];
- if(*pte & PTE_T)
- {
- assert(level < NPTLEVELS-1);
+ if (*pte & PTE_T) {
+ assert(level < NPTLEVELS - 1);
uintptr_t st = MAX(pgaddr, start);
size_t ln = MIN(start + len, pgaddr + pgsize) - st;
- if((ret = user_mem_walk_recursive(e, st, ln, callback, arg,
- pt_callback, pt_arg,
- KADDR(PTD_ADDR(*pte)), level+1)))
+ if ((ret = user_mem_walk_recursive(
+ e, st, ln, callback, arg, pt_callback, pt_arg,
+ KADDR(PTD_ADDR(*pte)), level + 1)))
goto out;
- if(pt_callback != NULL && (ret = pt_callback(e, pte, (void*)pgaddr, arg)))
+ if (pt_callback != NULL &&
+ (ret = pt_callback(e, pte, (void *)pgaddr, arg)))
goto out;
- }
- else if(callback != NULL)
- if((ret = callback(e, pte, (void*)pgaddr, arg)))
+ } else if (callback != NULL)
+ if ((ret = callback(e, pte, (void *)pgaddr, arg)))
goto out;
}
out:
return ret;
}
-int
-env_user_mem_walk(env_t* e, void* start, size_t len,
- mem_walk_callback_t callback, void* arg)
+int env_user_mem_walk(env_t *e, void *start, size_t len,
+ mem_walk_callback_t callback, void *arg)
{
assert(PGOFF(start) == 0 && PGOFF(len) == 0);
return user_mem_walk_recursive(e, (uintptr_t)start, len, callback, arg,
NULL, NULL, e->env_pgdir, 0);
}
-void
-env_pagetable_free(env_t* e)
+void env_pagetable_free(env_t *e)
{
- int pt_free(env_t* e, pte_t* pte, void* va, void* arg)
+ int pt_free(env_t * e, pte_t * pte, void *va, void *arg)
{
if (!PAGE_PRESENT(pte))
return 0;
@@ -163,6 +167,6 @@
return 0;
}
- assert(user_mem_walk_recursive(e, 0, KERNBASE, NULL, NULL,
- pt_free, NULL, e->env_pgdir, 0) == 0);
+ assert(user_mem_walk_recursive(e, 0, KERNBASE, NULL, NULL, pt_free,
+ NULL, e->env_pgdir, 0) == 0);
}
diff --git a/kern/arch/riscv/fpu.c b/kern/arch/riscv/fpu.c
index e2b0c2e..6c89015 100644
--- a/kern/arch/riscv/fpu.c
+++ b/kern/arch/riscv/fpu.c
@@ -1,35 +1,34 @@
-#include <trap.h>
-#include <smp.h>
-#include <umem.h>
#include <arch/softfloat.h>
+#include <smp.h>
+#include <trap.h>
+#include <umem.h>
-static uint32_t ls(uint64_t* addr)
+static uint32_t ls(uint64_t *addr)
{
uint32_t r;
- asm ("fld f0, %1; mftx.s %0, f0" : "=r"(r) : "m"(*addr));
+ asm("fld f0, %1; mftx.s %0, f0" : "=r"(r) : "m"(*addr));
return r;
}
-static void ss(uint64_t* addr, uint32_t val)
+static void ss(uint64_t *addr, uint32_t val)
{
- asm ("mxtf.s f0, %0; fsd f0, %1" : : "r"(val), "m"(*addr));
+ asm("mxtf.s f0, %0; fsd f0, %1" : : "r"(val), "m"(*addr));
}
static int emulate_fpu_silly(struct hw_trapframe *state,
ancillary_state_t *silly)
{
int insn;
- if (memcpy_from_user(current, &insn, (void*)state->epc, 4))
- {
+ if (memcpy_from_user(current, &insn, (void *)state->epc, 4)) {
state->cause = CAUSE_FAULT_FETCH;
handle_trap(state);
}
- #define DECLARE_INSN(name, match, mask) bool is_##name = (insn & mask) == match;
- #include <arch/opcodes.h>
- #undef DECLARE_INSN
+#define DECLARE_INSN(name, match, mask) bool is_##name = (insn & mask) == match;
+#include <arch/opcodes.h>
+#undef DECLARE_INSN
- int rd = (insn >> 27) & 0x1f;
+ int rd = (insn >> 27) & 0x1f;
int rs1 = (insn >> 22) & 0x1f;
int rs2 = (insn >> 17) & 0x1f;
int rs3 = (insn >> 12) & 0x1f;
@@ -37,8 +36,8 @@
int imm = (insn << 10) >> 20;
int bimm = ((insn >> 10) & 0x7f) | ((insn & 0xf8000000) >> 20);
- void* load_address = (void*)(state->gpr[rs1] + imm);
- void* store_address = (void*)(state->gpr[rs1] + bimm);
+ void *load_address = (void *)(state->gpr[rs1] + imm);
+ void *store_address = (void *)(state->gpr[rs1] + bimm);
softfloat_t sf;
sf.float_rounding_mode = silly->fsr >> 5;
@@ -49,65 +48,71 @@
else if (is_fsqrt_d)
silly->fpr[rd] = float64_sqrt(&sf, silly->fpr[rs1]);
else if (is_fdiv_s)
- ss(&silly->fpr[rd], float32_div(&sf, ls(&silly->fpr[rs1]), ls(&silly->fpr[rs2])));
+ ss(&silly->fpr[rd], float32_div(&sf, ls(&silly->fpr[rs1]),
+ ls(&silly->fpr[rs2])));
else if (is_fdiv_d)
- silly->fpr[rd] = float64_div(&sf, silly->fpr[rs1], silly->fpr[rs2]);
+ silly->fpr[rd] =
+ float64_div(&sf, silly->fpr[rs1], silly->fpr[rs2]);
/* Eventually, we will emulate the full FPU, including the below insns
else if (is_mffsr)
{
- // use sf instead of silly->fsr
- state->gpr[rd] = silly->fsr;
+ // use sf instead of silly->fsr
+ state->gpr[rd] = silly->fsr;
}
else if (is_mtfsr)
{
- // use sf instead of silly->fsr
- int temp = silly->fsr;
- silly->fsr = state->gpr[rs1] & 0xFF;
- state->gpr[rd] = silly->fsr;
+ // use sf instead of silly->fsr
+ int temp = silly->fsr;
+ silly->fsr = state->gpr[rs1] & 0xFF;
+ state->gpr[rd] = silly->fsr;
}
else if (is_fld)
{
- uint64_t dest;
- if (!memcpy_from_user(current, &dest, load_address, sizeof(dest)))
- {
- state->cause = CAUSE_FAULT_LOAD;
- state->badvaddr = (long)load_address;
- handle_trap(state);
- }
- silly->fpr[rd] = dest;
+ uint64_t dest;
+ if (!memcpy_from_user(current, &dest, load_address,
+ sizeof(dest)))
+ {
+ state->cause = CAUSE_FAULT_LOAD;
+ state->badvaddr = (long)load_address;
+ handle_trap(state);
+ }
+ silly->fpr[rd] = dest;
}
else if (is_flw)
{
- uint32_t dest;
- if (!memcpy_from_user(current, &dest, load_address, sizeof(dest)))
- {
- state->cause = CAUSE_FAULT_LOAD;
- state->badvaddr = (long)load_address;
- handle_trap(state);
- }
- silly->fpr[rd] = dest;
+ uint32_t dest;
+ if (!memcpy_from_user(current, &dest, load_address,
+ sizeof(dest)))
+ {
+ state->cause = CAUSE_FAULT_LOAD;
+ state->badvaddr = (long)load_address;
+ handle_trap(state);
+ }
+ silly->fpr[rd] = dest;
}
else if (is_fsd)
{
- if (!memcpy_to_user(current, store_address, &silly->fpr[rs2], sizeof(uint64_t)))
- {
- state->cause = CAUSE_FAULT_STORE;
- state->badvaddr = (long)store_address;
- handle_trap(state);
- }
+ if (!memcpy_to_user(current, store_address, &silly->fpr[rs2],
+ sizeof(uint64_t)))
+ {
+ state->cause = CAUSE_FAULT_STORE;
+ state->badvaddr = (long)store_address;
+ handle_trap(state);
+ }
}
else if (is_flw)
{
- if (!memcpy_to_user(current, store_address, &silly->fpr[rs2], sizeof(uint32_t)))
- {
- state->cause = CAUSE_FAULT_STORE;
- state->badvaddr = (long)store_address;
- handle_trap(state);
- }
+ if (!memcpy_to_user(current, store_address, &silly->fpr[rs2],
+ sizeof(uint32_t)))
+ {
+ state->cause = CAUSE_FAULT_STORE;
+ state->badvaddr = (long)store_address;
+ handle_trap(state);
+ }
}
*/
else
- return 1;
+ return 1;
silly->fsr = sf.float_rounding_mode << 5 | sf.float_exception_flags;
return 0;
@@ -116,8 +121,7 @@
/* For now we can only emulate missing compute insns, not the whole FPU */
int emulate_fpu(struct hw_trapframe *state)
{
- if (!(state->sr & SR_EF))
- {
+ if (!(state->sr & SR_EF)) {
state->cause = CAUSE_FP_DISABLED;
handle_trap(state);
}
@@ -125,6 +129,7 @@
ancillary_state_t fp_state;
save_fp_state(&fp_state);
int code = emulate_fpu_silly(state, &fp_state);
+
restore_fp_state(&fp_state);
return code;
}
diff --git a/kern/arch/riscv/init.c b/kern/arch/riscv/init.c
index 1c53b15..6aab49b 100644
--- a/kern/arch/riscv/init.c
+++ b/kern/arch/riscv/init.c
@@ -1,10 +1,10 @@
/* See COPYRIGHT for copyright information. */
-#include <smp.h>
-#include <arch/init.h>
#include <arch/console.h>
+#include <arch/init.h>
+#include <smp.h>
-void arch_init()
+void arch_init(void)
{
smp_boot();
proc_init();
diff --git a/kern/arch/riscv/kdebug.c b/kern/arch/riscv/kdebug.c
index fb196cb..2b30155 100644
--- a/kern/arch/riscv/kdebug.c
+++ b/kern/arch/riscv/kdebug.c
@@ -1,8 +1,8 @@
-#include <string.h>
#include <assert.h>
#include <kdebug.h>
#include <pmap.h>
#include <process.h>
+#include <string.h>
/* Here's the old backtrace, remove it once gen_backtrace is done: */
#if 0
@@ -36,7 +36,7 @@
}
size_t backtrace_user_list(uintptr_t pc, uintptr_t fp, uintptr_t *pcs,
- size_t nr_slots)
+ size_t nr_slots)
{
printk("\n\tTODO: %s on riscv\n\n", __func__);
return 0;
diff --git a/kern/arch/riscv/page_alloc.c b/kern/arch/riscv/page_alloc.c
index dac28d2..97a0cc2 100644
--- a/kern/arch/riscv/page_alloc.c
+++ b/kern/arch/riscv/page_alloc.c
@@ -7,11 +7,11 @@
* Kevin Klues <klueska@cs.berkeley.edu>
*/
-#include <sys/queue.h>
-#include <page_alloc.h>
-#include <pmap.h>
#include <kmalloc.h>
#include <multiboot.h>
+#include <page_alloc.h>
+#include <pmap.h>
+#include <sys/queue.h>
void base_arena_init(struct multiboot_info *mbi)
{
@@ -26,8 +26,8 @@
first_invalid_page = ROUNDUP(boot_freelimit, PGSIZE);
assert(first_invalid_page == max_nr_pages * PGSIZE);
- base_arena = arena_builder(base_pg, "base", PGSIZE, NULL, NULL, NULL,
- 0);
+ base_arena =
+ arena_builder(base_pg, "base", PGSIZE, NULL, NULL, NULL, 0);
arena_add(base_arena, KADDR(first_free_page),
first_invalid_page - first_free_page, MEM_WAIT);
}
diff --git a/kern/arch/riscv/pmap.c b/kern/arch/riscv/pmap.c
index 031d12e..5709109 100644
--- a/kern/arch/riscv/pmap.c
+++ b/kern/arch/riscv/pmap.c
@@ -5,25 +5,24 @@
#include <error.h>
#include <sys/queue.h>
-#include <atomic.h>
-#include <string.h>
#include <assert.h>
-#include <pmap.h>
+#include <atomic.h>
#include <env.h>
-#include <stdio.h>
#include <kmalloc.h>
#include <page_alloc.h>
+#include <pmap.h>
+#include <stdio.h>
+#include <string.h>
#warning "convert pgdir* to pgdir_t"
-pgdir_t* boot_pgdir; // Virtual address of boot time page directory
-physaddr_t boot_cr3; // Physical address of boot time page directory
+pgdir_t *boot_pgdir; // Virtual address of boot time page directory
+physaddr_t boot_cr3; // Physical address of boot time page directory
// --------------------------------------------------------------
// Set up initial memory mappings and turn on MMU.
// --------------------------------------------------------------
-void
-vm_init(void)
+void vm_init(void)
{
// we already set up our page tables before jumping
// into the kernel, so there's not much going on here
@@ -45,55 +44,54 @@
//
// This is boot_pgdir_walk, but using page_alloc() instead of boot_alloc().
// Unlike boot_pgdir_walk, pgdir_walk can fail.
-pte_t*
-pgdir_walk(pgdir_t *pgdir, const void *va, int create)
+pte_t *pgdir_walk(pgdir_t *pgdir, const void *va, int create)
{
- pte_t* ppte;
- pte_t* pt;
+ pte_t *ppte;
+ pte_t *pt;
pt = pgdir;
- for(int i = 0; i < NPTLEVELS-1; i++)
- {
- // this code relies upon the fact that all page tables are the same size
- uintptr_t idx = (uintptr_t)va >> (L1PGSHIFT - i*(L1PGSHIFT-L2PGSHIFT));
- idx = idx & (NPTENTRIES-1);
+ for (int i = 0; i < NPTLEVELS - 1; i++) {
+ // this code relies upon the fact that all page tables are the
+ // same size
+ uintptr_t idx = (uintptr_t)va >>
+ (L1PGSHIFT - i * (L1PGSHIFT - L2PGSHIFT));
+ idx = idx & (NPTENTRIES - 1);
ppte = &pt[idx];
- if(*ppte & PTE_E)
+ if (*ppte & PTE_E)
return ppte;
- if(!(*ppte & PTE_T))
- {
- if(!create)
+ if (!(*ppte & PTE_T)) {
+ if (!create)
return NULL;
page_t *new_table;
- if(kpage_alloc(&new_table))
+ if (kpage_alloc(&new_table))
return NULL;
memset(page2kva(new_table), 0, PGSIZE);
*ppte = PTD(page2pa(new_table));
}
- pt = (pte_t*)KADDR(PTD_ADDR(*ppte));
+ pt = (pte_t *)KADDR(PTD_ADDR(*ppte));
}
- uintptr_t idx = (uintptr_t)va >> (L1PGSHIFT - (NPTLEVELS-1)*(L1PGSHIFT-L2PGSHIFT));
- idx = idx & (NPTENTRIES-1);
- return &pt[idx];
+ uintptr_t idx = (uintptr_t)va >>
+ (L1PGSHIFT - (NPTLEVELS - 1) * (L1PGSHIFT - L2PGSHIFT));
+ idx = idx & (NPTENTRIES - 1);
+ return &pt[idx];
}
/* Returns the effective permissions for PTE_U, PTE_W, and PTE_P on a given
* virtual address. */
int get_va_perms(pgdir_t *pgdir, const void *va)
{
- pte_t* pte = pgdir_walk(pgdir, va, 0);
+ pte_t *pte = pgdir_walk(pgdir, va, 0);
return pte == NULL ? 0 : (*pte & (PTE_PERM | PTE_E));
}
-void
-page_check(void)
+void page_check(void)
{
}
@@ -108,7 +106,7 @@
pte_t *kpt = kpage_alloc_addr();
if (!kpt)
return -ENOMEM;
- memcpy(kpt, (pte_t*)boot_copy, PGSIZE);
+ memcpy(kpt, (pte_t *)boot_copy, PGSIZE);
/* TODO: VPT/UVPT mappings */
@@ -118,7 +116,7 @@
physaddr_t arch_pgdir_get_cr3(pgdir_t pd)
{
- return PADDR((pte_t*)pd);
+ return PADDR((pte_t *)pd);
}
void arch_pgdir_clear(pgdir_t *pd)
@@ -129,24 +127,25 @@
/* Returns the page shift of the largest jumbo supported */
int arch_max_jumbo_page_shift(void)
{
- #warning "What jumbo page sizes does RISC support?"
+#warning "What jumbo page sizes does RISC support?"
return PGSHIFT;
}
-#warning "Not sure where you do your PT destruction. Be sure to not unmap any intermediate page tables for kernel mappings. At least not the PML(n-1) maps"
+#warning \
+ "Not sure where you do your PT destruction. Be sure to not unmap any intermediate page tables for kernel mappings. At least not the PML(n-1) maps"
void arch_add_intermediate_pts(pgdir_t pgdir, uintptr_t va, size_t len)
{
- #error "Implement me"
+#error "Implement me"
}
void map_segment(pgdir_t pgdir, uintptr_t va, size_t size, physaddr_t pa,
int perm, int pml_shift)
{
- #error "Implement me"
+#error "Implement me"
}
int unmap_segment(pgdir_t pgdir, uintptr_t va, size_t size)
{
- #error "Implement me"
+#error "Implement me"
}
diff --git a/kern/arch/riscv/pmap_ops.h b/kern/arch/riscv/pmap_ops.h
index 0cc2963..4761ce9 100644
--- a/kern/arch/riscv/pmap_ops.h
+++ b/kern/arch/riscv/pmap_ops.h
@@ -14,15 +14,15 @@
}
/* PTE states:
- * - present: the PTE is involved in a valid page table walk, with the physaddr
- * part pointing to a physical page.
+ * - present: the PTE is involved in a valid page table walk, with the physaddr
+ * part pointing to a physical page.
*
- * - mapped: the PTE is involved in some sort of mapping, e.g. a VMR. We're
- * storing something in the PTE, but it is isn't necessarily present and
- * pointing to an actual physical page. All present are mapped, but not vice
- * versa. Mapped could also include paged-out, if we support that later.
+ * - mapped: the PTE is involved in some sort of mapping, e.g. a VMR. We're
+ * storing something in the PTE, but it is isn't necessarily present and
+ * pointing to an actual physical page. All present are mapped, but not vice
+ * versa. Mapped could also include paged-out, if we support that later.
*
- * - unmapped: completely unused. (0 value) */
+ * - unmapped: completely unused. (0 value) */
static inline bool pte_is_present(pte_t pte)
{
return *(kpte_t*)pte & PTE_P ? TRUE : FALSE;
diff --git a/kern/arch/riscv/process.c b/kern/arch/riscv/process.c
index 70d14ad..2d62920 100644
--- a/kern/arch/riscv/process.c
+++ b/kern/arch/riscv/process.c
@@ -1,19 +1,19 @@
#include <arch/arch.h>
-#include <trap.h>
-#include <process.h>
#include <pmap.h>
+#include <process.h>
#include <smp.h>
+#include <trap.h>
-#include <string.h>
#include <assert.h>
#include <stdio.h>
+#include <string.h>
void proc_pop_ctx(struct user_context *ctx)
{
struct hw_trapframe *tf = &ctx->tf.hw_tf;
assert(ctx->type == ROS_HW_CTX);
- extern void pop_hw_tf(struct hw_trapframe *tf)
- __attribute__((noreturn)); /* in asm */
+ extern void pop_hw_tf(struct hw_trapframe * tf)
+ __attribute__((noreturn)); /* in asm */
pop_hw_tf(tf);
}
@@ -25,23 +25,25 @@
ctx->type = ROS_HW_CTX;
/* TODO: If you'd like, take tls_desc and save it in the ctx somehow, so
- * that proc_pop_ctx will set up that TLS before launching. If you do this,
- * you can change _start.c to not reset the TLS in userspace.
+ * that proc_pop_ctx will set up that TLS before launching. If you do
+ * this, you can change _start.c to not reset the TLS in userspace.
*
- * This is a bigger deal on amd64, where we take a (fast) syscall to change
- * the TLS desc, right after the kernel just 0'd out the TLS desc. If you
- * can change your HW TLS desc with negligible overhead, then feel free to
- * do whatever. Long term, it might be better to do whatever amd64 does. */
+ * This is a bigger deal on amd64, where we take a (fast) syscall to
+ * change the TLS desc, right after the kernel just 0'd out the TLS
+ * desc. If you can change your HW TLS desc with negligible overhead,
+ * then feel free to do whatever. Long term, it might be better to do
+ * whatever amd64 does. */
memset(tf, 0, sizeof(*tf));
- tf->gpr[GPR_SP] = stack_top-64;
+ tf->gpr[GPR_SP] = stack_top - 64;
tf->sr = SR_U64 | SR_EF;
tf->epc = entryp;
- /* Coupled closely with user's entry.S. id is the vcoreid, which entry.S
- * uses to determine what to do. vcoreid == 0 is the main core/context. */
+ /* Coupled closely with user's entry.S. id is the vcoreid, which
+ * entry.S uses to determine what to do. vcoreid == 0 is the main
+ * core/context. */
tf->gpr[GPR_A0] = vcoreid;
}
diff --git a/kern/arch/riscv/riscv.h b/kern/arch/riscv/riscv.h
index c1819c9..262de7f 100644
--- a/kern/arch/riscv/riscv.h
+++ b/kern/arch/riscv/riscv.h
@@ -25,8 +25,8 @@
static inline uintptr_t
read_bp(void)
{
- /* frame pointer. yes, read_bp is a shitty name. i'll change all of them
- * to read_fp when you read this and implement the function. =) */
+ /* frame pointer. yes, read_bp is a shitty name. i'll change all of
+ * them to read_fp when you read this and implement the function. =) */
return 0;
}
diff --git a/kern/arch/riscv/ros/arch.h b/kern/arch/riscv/ros/arch.h
index 5fa6717..3fa3f48 100644
--- a/kern/arch/riscv/ros/arch.h
+++ b/kern/arch/riscv/ros/arch.h
@@ -1,6 +1,6 @@
#pragma once
-#define MAX_NUM_CORES 16 // it's safe to change this as needed
+#define MAX_NUM_CORES 16 // it's safe to change this as needed
#ifndef __ASSEMBLER__
diff --git a/kern/arch/riscv/ros/cpu_feat.h b/kern/arch/riscv/ros/cpu_feat.h
index dcfdc6c..8accdc7 100644
--- a/kern/arch/riscv/ros/cpu_feat.h
+++ b/kern/arch/riscv/ros/cpu_feat.h
@@ -10,5 +10,5 @@
#pragma once
-#define CPU_FEAT_RISCV_FOO (__CPU_FEAT_ARCH_START + 0)
-#define __NR_CPU_FEAT (__CPU_FEAT_ARCH_START + 64)
+#define CPU_FEAT_RISCV_FOO (__CPU_FEAT_ARCH_START + 0)
+#define __NR_CPU_FEAT (__CPU_FEAT_ARCH_START + 64)
diff --git a/kern/arch/riscv/ros/mmu.h b/kern/arch/riscv/ros/mmu.h
index d8bf3bb..c9bf1fa 100644
--- a/kern/arch/riscv/ros/mmu.h
+++ b/kern/arch/riscv/ros/mmu.h
@@ -11,7 +11,7 @@
# define KERNBASE 0xFFFFFC0000000000
# define ULIM 0x0000040000000000
# define KERN_LOAD_ADDR 0xFFFFFFFF80000000
-# define KERN_VMAP_TOP KERN_LOAD_ADDR // upper 2GB reserved (see mmu_init)
+# define KERN_VMAP_TOP KERN_LOAD_ADDR // upper 2GB reserved (see mmu_init)
# define NPTLEVELS 3
# define L1PGSHIFT (13+10+10)
# define L1PGSIZE (1L << L1PGSHIFT)
@@ -25,7 +25,7 @@
# define KERNBASE 0x80000000
# define ULIM 0x7F000000
# define KERN_LOAD_ADDR KERNBASE
-# define KERN_VMAP_TOP 0xfec00000
+# define KERN_VMAP_TOP 0xfec00000
# define NPTLEVELS 2
# define L1PGSHIFT (13+11)
# define L1PGSIZE (1 << L1PGSHIFT)
diff --git a/kern/arch/riscv/ros/trapframe.h b/kern/arch/riscv/ros/trapframe.h
index b5025a6..5901e10 100644
--- a/kern/arch/riscv/ros/trapframe.h
+++ b/kern/arch/riscv/ros/trapframe.h
@@ -49,8 +49,9 @@
static inline uintptr_t get_hwtf_fp(struct hw_trapframe *hw_tf)
{
- /* do you even have frame pointers? this is used for backtrace, but if you
- * don't use FPs, we'll need to change up our parameters or something. */
+ /* do you even have frame pointers? this is used for backtrace, but if
+ * you don't use FPs, we'll need to change up our parameters or
+ * something. */
#warning "fix me"
return 0;
//return hw_tf->tf_rbp;
@@ -58,8 +59,9 @@
static inline uintptr_t get_hwtf_sp(struct hw_trapframe *hw_tf)
{
- /* do you even have frame pointers? this is used for backtrace, but if you
- * don't use FPs, we'll need to change up our parameters or something. */
+ /* do you even have frame pointers? this is used for backtrace, but if
+ * you don't use FPs, we'll need to change up our parameters or
+ * something. */
#warning "fix me"
return 0;
//return hw_tf->tf_rsp;
diff --git a/kern/arch/riscv/smp.c b/kern/arch/riscv/smp.c
index d064c64..2126bbf 100644
--- a/kern/arch/riscv/smp.c
+++ b/kern/arch/riscv/smp.c
@@ -1,44 +1,42 @@
-#include <smp.h>
#include <arch/arch.h>
#include <arch/smp.h>
-#include <stdio.h>
-#include <string.h>
-#include <error.h>
#include <assert.h>
#include <atomic.h>
+#include <error.h>
#include <pmap.h>
+#include <smp.h>
+#include <stdio.h>
+#include <string.h>
volatile uint32_t num_cores_booted = 0;
-void
-smp_boot(void)
+void smp_boot(void)
{
smp_percpu_init();
num_cores_booted = 1;
- while(num_cores_booted < num_cores);
+ while (num_cores_booted < num_cores)
+ ;
printd("%d cores reporting!\n", num_cores);
}
-void
-smp_init(void)
+void smp_init(void)
{
smp_percpu_init();
__sync_fetch_and_add(&num_cores_booted, 1);
- printd("Good morning, Vietnam! (core id = %d)\n",core_id());
+ printd("Good morning, Vietnam! (core id = %d)\n", core_id());
smp_idle();
}
-handler_wrapper_t*
-smp_make_wrapper()
+handler_wrapper_t *smp_make_wrapper(void)
{
- static handler_wrapper_t
- wrapper_pool[MAX_NUM_CORES*8] = {{{0},SPINLOCK_INITIALIZER}};
+ static handler_wrapper_t wrapper_pool[MAX_NUM_CORES * 8] = {
+ {{0}, SPINLOCK_INITIALIZER}};
size_t i;
- for(i = 0; i < sizeof(wrapper_pool)/sizeof(wrapper_pool[0]); i++)
- if(spin_trylock(&wrapper_pool[i].lock) == 0)
+ for (i = 0; i < sizeof(wrapper_pool) / sizeof(wrapper_pool[0]); i++)
+ if (spin_trylock(&wrapper_pool[i].lock) == 0)
return &wrapper_pool[i];
return NULL;
}
@@ -46,39 +44,38 @@
void smp_call_wrapper(uint32_t src, isr_t handler, handler_wrapper_t *wrapper,
void *data)
{
- if(wrapper)
+ if (wrapper)
wrapper->wait_list[core_id()] = 0;
handler(0, data);
}
-int smp_call_function_self(isr_t handler, void* data,
- handler_wrapper_t** wait_wrapper)
+int smp_call_function_self(isr_t handler, void *data,
+ handler_wrapper_t **wait_wrapper)
{
return smp_call_function_single(core_id(), handler, data, wait_wrapper);
}
-int smp_call_function_all(isr_t handler, void* data,
- handler_wrapper_t** wait_wrapper)
+int smp_call_function_all(isr_t handler, void *data,
+ handler_wrapper_t **wait_wrapper)
{
int8_t state = 0;
int i, me;
- handler_wrapper_t* wrapper = 0;
- if(wait_wrapper)
- {
+ handler_wrapper_t *wrapper = 0;
+
+ if (wait_wrapper) {
wrapper = *wait_wrapper = smp_make_wrapper();
- if(!wrapper)
+ if (!wrapper)
return -ENOMEM;
- for(i = 0; i < num_cores; i++)
+ for (i = 0; i < num_cores; i++)
wrapper->wait_list[i] = 1;
}
enable_irqsave(&state);
// send to others
- for(i = 0, me = core_id(); i < num_cores; i++)
- {
- if(i == me)
+ for (i = 0, me = core_id(); i < num_cores; i++) {
+ if (i == me)
continue;
send_kernel_message(i, (amr_t)smp_call_wrapper, (long)handler,
@@ -96,15 +93,15 @@
return 0;
}
-int smp_call_function_single(uint32_t dest, isr_t handler, void* data,
- handler_wrapper_t** wait_wrapper)
+int smp_call_function_single(uint32_t dest, isr_t handler, void *data,
+ handler_wrapper_t **wait_wrapper)
{
int8_t state = 0;
- handler_wrapper_t* wrapper = 0;
- if(wait_wrapper)
- {
+ handler_wrapper_t *wrapper = 0;
+
+ if (wait_wrapper) {
wrapper = *wait_wrapper = smp_make_wrapper();
- if(!wrapper)
+ if (!wrapper)
return -ENOMEM;
wrapper->wait_list[dest] = 1;
}
@@ -121,11 +118,13 @@
return 0;
}
-int smp_call_wait(handler_wrapper_t* wrapper)
+int smp_call_wait(handler_wrapper_t *wrapper)
{
int i;
- for(i = 0; i < num_cores; i++)
- while(wrapper->wait_list[i]);
+
+ for (i = 0; i < num_cores; i++)
+ while (wrapper->wait_list[i])
+ ;
spin_unlock(&wrapper->lock);
return 0;
@@ -136,11 +135,11 @@
* smp_boot process. */
void __arch_pcpu_init(uint32_t coreid)
{
- // Switch to the real L1 page table, rather than the boot page table which
- // has the [0,KERNSIZE-1] identity mapping.
+ // Switch to the real L1 page table, rather than the boot page table
+ // which has the [0,KERNSIZE-1] identity mapping.
extern pte_t l1pt[NPTENTRIES];
lcr3(PADDR(l1pt));
- register uintptr_t sp asm ("sp");
+ register uintptr_t sp asm("sp");
set_stack_top(ROUNDUP(sp, PGSIZE));
}
diff --git a/kern/arch/riscv/time.c b/kern/arch/riscv/time.c
index c03b80e..7de6071 100644
--- a/kern/arch/riscv/time.c
+++ b/kern/arch/riscv/time.c
@@ -1,61 +1,54 @@
-#include <arch/time.h>
-#include <ros/common.h>
-#include <trap.h>
#include <arch/arch.h>
-#include <stdio.h>
+#include <arch/time.h>
#include <assert.h>
+#include <ros/common.h>
#include <ros/procinfo.h>
+#include <stdio.h>
+#include <trap.h>
-void
-timer_init(void)
+void timer_init(void)
{
__proc_global_info.tsc_freq = TSC_HZ;
cprintf("TSC Frequency: %llu\n", __proc_global_info.tsc_freq);
}
-void
-set_core_timer(uint32_t usec, bool periodic)
+void set_core_timer(uint32_t usec, bool periodic)
{
// we could implement periodic timers using one-shot timers,
// but for now we only support one-shot
assert(!periodic);
- if (usec)
- {
- uint32_t clocks = (uint64_t)usec*TSC_HZ/1000000;
+ if (usec) {
+ uint32_t clocks = (uint64_t)usec * TSC_HZ / 1000000;
int8_t irq_state = 0;
disable_irqsave(&irq_state);
mtpcr(PCR_COUNT, 0);
mtpcr(PCR_COMPARE, clocks);
- mtpcr(PCR_SR, mfpcr(PCR_SR) | (1 << (IRQ_TIMER+SR_IM_SHIFT)));
+ mtpcr(PCR_SR, mfpcr(PCR_SR) | (1 << (IRQ_TIMER + SR_IM_SHIFT)));
enable_irqsave(&irq_state);
- }
- else
- {
- mtpcr(PCR_SR, mfpcr(PCR_SR) & ~(1 << (IRQ_TIMER+SR_IM_SHIFT)));
+ } else {
+ mtpcr(PCR_SR,
+ mfpcr(PCR_SR) & ~(1 << (IRQ_TIMER + SR_IM_SHIFT)));
}
}
-void
-udelay(uint64_t usec)
+void udelay(uint64_t usec)
{
- if (__proc_global_info.tsc_freq != 0)
- {
+ if (__proc_global_info.tsc_freq != 0) {
uint64_t start, end, now;
start = read_tsc();
end = start + (__proc_global_info.tsc_freq * usec) / 1000000;
- do
- {
+ do {
cpu_relax();
now = read_tsc();
} while (now < end || (now > start && end < start));
- }
- else panic("udelay() was called before timer_init(), moron!");
+ } else
+ panic("udelay() was called before timer_init(), moron!");
}
uint64_t read_persistent_clock(void)
diff --git a/kern/arch/riscv/trap.c b/kern/arch/riscv/trap.c
index 125a2ca..0e8a980 100644
--- a/kern/arch/riscv/trap.c
+++ b/kern/arch/riscv/trap.c
@@ -1,18 +1,18 @@
#include <arch/arch.h>
-#include <assert.h>
-#include <trap.h>
#include <arch/console.h>
-#include <string.h>
-#include <process.h>
-#include <syscall.h>
-#include <monitor.h>
+#include <assert.h>
#include <manager.h>
-#include <stdio.h>
-#include <smp.h>
-#include <slab.h>
#include <mm.h>
-#include <umem.h>
+#include <monitor.h>
#include <pmap.h>
+#include <process.h>
+#include <slab.h>
+#include <smp.h>
+#include <stdio.h>
+#include <string.h>
+#include <syscall.h>
+#include <trap.h>
+#include <umem.h>
/* These are the stacks the kernel will load when it receives a trap from user
* space. The deal is that they get set right away in entry.S, and can always
@@ -25,8 +25,7 @@
* per_cpu_info. */
uintptr_t core_stacktops[MAX_NUM_CORES] = {0xcafebabe, 0};
-void
-advance_pc(struct hw_trapframe *state)
+void advance_pc(struct hw_trapframe *state)
{
state->epc += 4;
}
@@ -41,14 +40,13 @@
/* Note the assertion assumes we are in the top page of the stack. */
uintptr_t get_stack_top(void)
{
- register uintptr_t sp asm ("sp");
+ register uintptr_t sp asm("sp");
uintptr_t stacktop = core_stacktops[core_id()];
assert(ROUNDUP(sp, PGSIZE) == stacktop);
return stacktop;
}
-void
-idt_init(void)
+void idt_init(void)
{
}
@@ -76,38 +74,35 @@
pcpui->cur_ctx = &pcpui->actual_ctx;
}
-static int
-format_trapframe(struct hw_trapframe *hw_tf, char* buf, int bufsz)
+static int format_trapframe(struct hw_trapframe *hw_tf, char *buf, int bufsz)
{
// slightly hackish way to read out the instruction that faulted.
// not guaranteed to be right 100% of the time
uint32_t insn;
- if(!(current && !memcpy_from_user(current,&insn,(void*)hw_tf->epc,4)))
+ if (!(current &&
+ !memcpy_from_user(current, &insn, (void *)hw_tf->epc, 4)))
insn = -1;
- int len = snprintf(buf,bufsz,"TRAP frame at %p on core %d\n",
- hw_tf, core_id());
- static const char* regnames[] = {
- "z ", "ra", "s0", "s1", "s2", "s3", "s4", "s5",
- "s6", "s7", "s8", "s9", "sA", "sB", "sp", "tp",
- "v0", "v1", "a0", "a1", "a2", "a3", "a4", "a5",
- "a6", "a7", "a8", "a9", "aA", "aB", "aC", "aD"
- };
+ int len = snprintf(buf, bufsz, "TRAP frame at %p on core %d\n", hw_tf,
+ core_id());
+ static const char *regnames[] = {
+ "z ", "ra", "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8",
+ "s9", "sA", "sB", "sp", "tp", "v0", "v1", "a0", "a1", "a2", "a3",
+ "a4", "a5", "a6", "a7", "a8", "a9", "aA", "aB", "aC", "aD"};
hw_tf->gpr[0] = 0;
- for(int i = 0; i < 32; i+=4)
- {
- for(int j = 0; j < 4; j++)
- len += snprintf(buf+len, bufsz-len,
- "%s %016lx%c", regnames[i+j], hw_tf->gpr[i+j],
+ for (int i = 0; i < 32; i += 4) {
+ for (int j = 0; j < 4; j++)
+ len += snprintf(buf + len, bufsz - len, "%s %016lx%c",
+ regnames[i + j], hw_tf->gpr[i + j],
j < 3 ? ' ' : '\n');
}
- len += snprintf(buf+len, bufsz-len,
+ len += snprintf(buf + len, bufsz - len,
"sr %016lx pc %016lx va %016lx insn %08x\n",
- hw_tf->sr, hw_tf->epc, hw_tf->badvaddr, insn);
+ hw_tf->sr, hw_tf->epc, hw_tf->badvaddr, insn);
- buf[bufsz-1] = 0;
+ buf[bufsz - 1] = 0;
return len;
}
@@ -115,32 +110,32 @@
{
char buf[1024];
int len = format_trapframe(hw_tf, buf, sizeof(buf));
- cputbuf(buf,len);
+ cputbuf(buf, len);
}
void print_swtrapframe(struct sw_trapframe *sw_tf)
{
- #warning "fix me"
+#warning "fix me"
}
void print_vmtrapframe(struct vm_trapframe *vm_tf)
{
- #warning "fix me"
+#warning "fix me"
}
static void exit_halt_loop(struct hw_trapframe *hw_tf)
{
extern char after_cpu_halt;
- if ((char*)hw_tf->epc >= (char*)&cpu_halt &&
- (char*)hw_tf->epc < &after_cpu_halt)
+ if ((char *)hw_tf->epc >= (char *)&cpu_halt &&
+ (char *)hw_tf->epc < &after_cpu_halt)
hw_tf->epc = hw_tf->gpr[GPR_RA];
}
static void handle_keypress(char c)
{
- #warning "fix me"
- /* TODO: does cons_init need to be before cons_add_char? Also, do something
- * with CTRL-G, Q, and B. */
+#warning "fix me"
+ /* TODO: does cons_init need to be before cons_add_char? Also, do
+ * something with CTRL-G, Q, and B. */
cons_add_char(c);
cons_init();
@@ -149,11 +144,14 @@
static void handle_host_interrupt(struct hw_trapframe *hw_tf)
{
uintptr_t fh = mtpcr(PCR_FROMHOST, 0);
- switch (fh >> 56)
- {
- case 0x00: return;
- case 0x01: handle_keypress(fh); return;
- default: assert(0);
+ switch (fh >> 56) {
+ case 0x00:
+ return;
+ case 0x01:
+ handle_keypress(fh);
+ return;
+ default:
+ assert(0);
}
}
@@ -169,23 +167,20 @@
handle_kmsg_ipi(hw_tf, 0);
}
-static void
-unhandled_trap(struct hw_trapframe *state, const char* name)
+static void unhandled_trap(struct hw_trapframe *state, const char *name)
{
static spinlock_t screwup_lock = SPINLOCK_INITIALIZER;
spin_lock(&screwup_lock);
- if(in_kernel(state))
- {
+ if (in_kernel(state)) {
print_trapframe(state);
panic("Unhandled trap in kernel!\nTrap type: %s", name);
- }
- else
- {
+ } else {
char tf_buf[1024];
format_trapframe(state, tf_buf, sizeof(tf_buf));
- warn("Unhandled trap in user!\nTrap type: %s\n%s", name, tf_buf);
+ warn("Unhandled trap in user!\nTrap type: %s\n%s", name,
+ tf_buf);
backtrace();
spin_unlock(&screwup_lock);
@@ -194,45 +189,39 @@
}
}
-static void
-handle_misaligned_fetch(struct hw_trapframe *state)
+static void handle_misaligned_fetch(struct hw_trapframe *state)
{
unhandled_trap(state, "Misaligned Fetch");
}
-static void
-handle_misaligned_load(struct hw_trapframe *state)
+static void handle_misaligned_load(struct hw_trapframe *state)
{
unhandled_trap(state, "Misaligned Load");
}
-static void
-handle_misaligned_store(struct hw_trapframe *state)
+static void handle_misaligned_store(struct hw_trapframe *state)
{
unhandled_trap(state, "Misaligned Store");
}
-static void
-handle_fault_fetch(struct hw_trapframe *state)
+static void handle_fault_fetch(struct hw_trapframe *state)
{
- if(in_kernel(state))
- {
+ if (in_kernel(state)) {
print_trapframe(state);
- panic("Instruction Page Fault in the Kernel at %p!", state->epc);
+ panic("Instruction Page Fault in the Kernel at %p!",
+ state->epc);
}
set_current_ctx_hw(&per_cpu_info[core_id()], state);
#warning "returns EAGAIN if you should reflect the fault"
- if(handle_page_fault(current, state->epc, PROT_EXEC))
+ if (handle_page_fault(current, state->epc, PROT_EXEC))
unhandled_trap(state, "Instruction Page Fault");
}
-static void
-handle_fault_load(struct hw_trapframe *state)
+static void handle_fault_load(struct hw_trapframe *state)
{
- if(in_kernel(state))
- {
+ if (in_kernel(state)) {
print_trapframe(state);
panic("Load Page Fault in the Kernel at %p!", state->badvaddr);
}
@@ -240,34 +229,30 @@
set_current_ctx_hw(&per_cpu_info[core_id()], state);
#warning "returns EAGAIN if you should reflect the fault"
- if(handle_page_fault(current, state->badvaddr, PROT_READ))
+ if (handle_page_fault(current, state->badvaddr, PROT_READ))
unhandled_trap(state, "Load Page Fault");
}
-static void
-handle_fault_store(struct hw_trapframe *state)
+static void handle_fault_store(struct hw_trapframe *state)
{
- if(in_kernel(state))
- {
+ if (in_kernel(state)) {
print_trapframe(state);
panic("Store Page Fault in the Kernel at %p!", state->badvaddr);
}
set_current_ctx_hw(&per_cpu_info[core_id()], state);
- if(handle_page_fault(current, state->badvaddr, PROT_WRITE))
+ if (handle_page_fault(current, state->badvaddr, PROT_WRITE))
unhandled_trap(state, "Store Page Fault");
}
-static void
-handle_illegal_instruction(struct hw_trapframe *state)
+static void handle_illegal_instruction(struct hw_trapframe *state)
{
assert(!in_kernel(state));
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
set_current_ctx_hw(pcpui, state);
- if (emulate_fpu(state) == 0)
- {
+ if (emulate_fpu(state) == 0) {
advance_pc(&pcpui->cur_ctx->tf.hw_tf);
return;
}
@@ -275,8 +260,7 @@
unhandled_trap(state, "Illegal Instruction");
}
-static void
-handle_syscall(struct hw_trapframe *state)
+static void handle_syscall(struct hw_trapframe *state)
{
uintptr_t a0 = state->gpr[GPR_A0];
uintptr_t a1 = state->gpr[GPR_A1];
@@ -284,43 +268,40 @@
advance_pc(state);
set_current_ctx_hw(&per_cpu_info[core_id()], state);
enable_irq();
- prep_syscalls(current, (struct syscall*)a0, a1);
+ prep_syscalls(current, (struct syscall *)a0, a1);
}
-static void
-handle_breakpoint(struct hw_trapframe *state)
+static void handle_breakpoint(struct hw_trapframe *state)
{
advance_pc(state);
monitor(state);
}
-void
-handle_trap(struct hw_trapframe *hw_tf)
+void handle_trap(struct hw_trapframe *hw_tf)
{
static void (*const trap_handlers[])(struct hw_trapframe *) = {
- [CAUSE_MISALIGNED_FETCH] = handle_misaligned_fetch,
- [CAUSE_FAULT_FETCH] = handle_fault_fetch,
- [CAUSE_ILLEGAL_INSTRUCTION] = handle_illegal_instruction,
- [CAUSE_PRIVILEGED_INSTRUCTION] = handle_illegal_instruction,
- [CAUSE_SYSCALL] = handle_syscall,
- [CAUSE_BREAKPOINT] = handle_breakpoint,
- [CAUSE_MISALIGNED_LOAD] = handle_misaligned_load,
- [CAUSE_MISALIGNED_STORE] = handle_misaligned_store,
- [CAUSE_FAULT_LOAD] = handle_fault_load,
- [CAUSE_FAULT_STORE] = handle_fault_store,
+ [CAUSE_MISALIGNED_FETCH] = handle_misaligned_fetch,
+ [CAUSE_FAULT_FETCH] = handle_fault_fetch,
+ [CAUSE_ILLEGAL_INSTRUCTION] = handle_illegal_instruction,
+ [CAUSE_PRIVILEGED_INSTRUCTION] = handle_illegal_instruction,
+ [CAUSE_SYSCALL] = handle_syscall,
+ [CAUSE_BREAKPOINT] = handle_breakpoint,
+ [CAUSE_MISALIGNED_LOAD] = handle_misaligned_load,
+ [CAUSE_MISALIGNED_STORE] = handle_misaligned_store,
+ [CAUSE_FAULT_LOAD] = handle_fault_load,
+ [CAUSE_FAULT_STORE] = handle_fault_store,
};
static void (*const irq_handlers[])(struct hw_trapframe *) = {
- [IRQ_TIMER] = handle_timer_interrupt,
- [IRQ_HOST] = handle_host_interrupt,
- [IRQ_IPI] = handle_interprocessor_interrupt,
+ [IRQ_TIMER] = handle_timer_interrupt,
+ [IRQ_HOST] = handle_host_interrupt,
+ [IRQ_IPI] = handle_interprocessor_interrupt,
};
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
- if (hw_tf->cause < 0)
- {
+ if (hw_tf->cause < 0) {
uint8_t irq = hw_tf->cause;
- assert(irq < sizeof(irq_handlers)/sizeof(irq_handlers[0]) &&
+ assert(irq < sizeof(irq_handlers) / sizeof(irq_handlers[0]) &&
irq_handlers[irq]);
if (in_kernel(hw_tf))
@@ -331,10 +312,9 @@
inc_irq_depth(pcpui);
irq_handlers[irq](hw_tf);
dec_irq_depth(pcpui);
- }
- else
- {
- assert(hw_tf->cause < sizeof(trap_handlers)/sizeof(trap_handlers[0]) &&
+ } else {
+ assert(hw_tf->cause <
+ sizeof(trap_handlers) / sizeof(trap_handlers[0]) &&
trap_handlers[hw_tf->cause]);
if (in_kernel(hw_tf)) {
inc_ktrap_depth(pcpui);
@@ -343,14 +323,14 @@
} else {
trap_handlers[hw_tf->cause](hw_tf);
}
- #warning "if a trap wasn't handled fully, like an MCP pf, reflect it
+#warning "if a trap wasn't handled fully, like an MCP pf, reflect it
reflect_unhandled_trap(hw_tf->tf_trapno, hw_tf->tf_err, aux);
}
- extern void pop_hw_tf(struct hw_trapframe *tf); /* in asm */
- /* Return to the current process, which should be runnable. If we're the
- * kernel, we should just return naturally. Note that current and tf need
- * to still be okay (might not be after blocking) */
+ extern void pop_hw_tf(struct hw_trapframe * tf); /* in asm */
+ /* Return to the current process, which should be runnable. If we're
+ * the kernel, we should just return naturally. Note that current and
+ * tf need to still be okay (might not be after blocking) */
if (in_kernel(hw_tf))
pop_hw_tf(hw_tf);
else
diff --git a/kern/arch/riscv/uaccess.h b/kern/arch/riscv/uaccess.h
index 8b91715..16194f5 100644
--- a/kern/arch/riscv/uaccess.h
+++ b/kern/arch/riscv/uaccess.h
@@ -26,11 +26,11 @@
uint64_t fixup;
};
-#define _ASM_EXTABLE(from, to) \
- " .pushsection \"__ex_table\",\"a\"\n" \
- " .balign 16\n" \
- " .quad (" #from ") - .\n" \
- " .quad (" #to ") - .\n" \
+#define _ASM_EXTABLE(from, to) \
+ " .pushsection \"__ex_table\",\"a\"\n" \
+ " .balign 16\n" \
+ " .quad (" #from ") - .\n" \
+ " .quad (" #to ") - .\n" \
" .popsection\n"
static inline int __put_user(void *dst, const void *src, unsigned int count)
diff --git a/kern/arch/x86/apic.c b/kern/arch/x86/apic.c
index e030647..9eadd5b 100644
--- a/kern/arch/x86/apic.c
+++ b/kern/arch/x86/apic.c
@@ -18,14 +18,15 @@
bool lapic_check_spurious(int trap_nr)
{
- /* FYI: lapic_spurious is 255 on qemu and 15 on the nehalem.. We actually
- * can set bits 4-7, and P6s have 0-3 hardwired to 0. YMMV. NxM seems to
- * say the lower 3 bits are usually 1. We'll see if the assert trips.
+ /* FYI: lapic_spurious is 255 on qemu and 15 on the nehalem.. We
+ * actually can set bits 4-7, and P6s have 0-3 hardwired to 0. YMMV.
+ * NxM seems to say the lower 3 bits are usually 1. We'll see if the
+ * assert trips.
*
- * The SDM recommends not using the spurious vector for any other IRQs (LVT
- * or IOAPIC RTE), since the handlers don't send an EOI. However, our check
- * here allows us to use the vector since we can tell the diff btw a
- * spurious and a real IRQ. */
+ * The SDM recommends not using the spurious vector for any other IRQs
+ * (LVT or IOAPIC RTE), since the handlers don't send an EOI. However,
+ * our check here allows us to use the vector since we can tell the diff
+ * btw a spurious and a real IRQ. */
assert(IdtLAPIC_SPURIOUS == (apicrget(MSR_LAPIC_SPURIOUS) & 0xff));
/* Note the lapic's vectors are not shifted by an offset. */
if ((trap_nr == IdtLAPIC_SPURIOUS) &&
@@ -77,6 +78,7 @@
void lapic_mask_irq(struct irq_handler *unused, int apic_vector)
{
uintptr_t mm_reg;
+
if (apic_vector < IdtLAPIC || IdtLAPIC + 4 < apic_vector) {
warn("Bad apic vector %d\n", apic_vector);
return;
@@ -88,6 +90,7 @@
void lapic_unmask_irq(struct irq_handler *unused, int apic_vector)
{
uintptr_t mm_reg;
+
if (apic_vector < IdtLAPIC || IdtLAPIC + 4 < apic_vector) {
warn("Bad apic vector %d\n", apic_vector);
return;
@@ -116,8 +119,9 @@
void __lapic_set_timer(uint32_t ticks, uint8_t vec, bool periodic, uint8_t div)
{
#ifdef CONFIG_LOUSY_LAPIC_TIMER
- /* qemu without kvm seems to delay timer IRQs on occasion, and needs extra
- * IRQs from any source to get them delivered. periodic does the trick. */
+ /* qemu without kvm seems to delay timer IRQs on occasion, and needs
+ * extra IRQs from any source to get them delivered. periodic does the
+ * trick. */
periodic = TRUE;
#endif
// clears bottom bit and then set divider
@@ -126,23 +130,20 @@
// set LVT with interrupt handling information. also unmasks.
apicrput(MSR_LAPIC_LVT_TIMER, vec | (periodic << 17));
apicrput(MSR_LAPIC_INITIAL_COUNT, ticks);
- // For debugging when we expand this
- //cprintf("LAPIC LVT Timer: 0x%08x\n", apicrget(MSR_LAPIC_LVT_TIMER));
- //cprintf("LAPIC Init Count: 0x%08x\n", apicrget(MSR_LAPIC_INITIAL_COUNT));
- //cprintf("LAPIC Current Count: 0x%08x\n",
- // apicrget(MSR_LAPIC_CURRENT_COUNT));
}
void lapic_set_timer(uint32_t usec, bool periodic)
{
- /* If we overflowed a uint32, send in the max timer possible. The lapic can
- * only handle a 32 bit. We could muck with changing the divisor, but even
- * then, we might not be able to match 4000 sec (based on the bus speed).
- * The kernel alarm code can handle spurious timer interrupts, so we just
- * set the timer for as close as we can get to the desired time. */
+ /* If we overflowed a uint32, send in the max timer possible. The lapic
+ * can only handle a 32 bit. We could muck with changing the divisor,
+ * but even then, we might not be able to match 4000 sec (based on the
+ * bus speed). The kernel alarm code can handle spurious timer
+ * interrupts, so we just set the timer for as close as we can get to
+ * the desired time. */
uint64_t ticks64 = (usec * __proc_global_info.bus_freq)
/ LAPIC_TIMER_DIVISOR_VAL / 1000000;
uint32_t ticks32 = ((ticks64 >> 32) ? 0xffffffff : ticks64);
+
assert(ticks32 > 0);
__lapic_set_timer(ticks32, IdtLAPIC_TIMER, periodic,
LAPIC_TIMER_DIVISOR_BITS);
@@ -151,6 +152,7 @@
uint32_t lapic_get_default_id(void)
{
uint32_t ebx;
+
cpuid(0x1, 0x0, 0, &ebx, 0, 0);
// p6 family only uses 4 bits here, and 0xf is reserved for the IOAPIC
return (ebx & 0xFF000000) >> 24;
diff --git a/kern/arch/x86/apic.h b/kern/arch/x86/apic.h
index fc0fd97..5752b89 100644
--- a/kern/arch/x86/apic.h
+++ b/kern/arch/x86/apic.h
@@ -23,8 +23,8 @@
* spaces. We just happen to have a slight 'hole' in addressable physical
* memory. We can move the PBASE, but we're limited to 32 bit (physical)
* addresses. */
-#define LAPIC_PBASE 0xfee00000 /* default *physical* address */
-#define LAPIC_LVT_MASK 0x00010000
+#define LAPIC_PBASE 0xfee00000 /* default *physical* address */
+#define LAPIC_LVT_MASK 0x00010000
/* Quick note on the divisor. The LAPIC timer ticks once per divisor-bus ticks
* (system bus or APIC bus, depending on the model). Ex: A divisor of 128 means
@@ -39,15 +39,15 @@
#define LAPIC_TIMER_DIVISOR_BITS 0x8 /* Div = 32 */
// IPI Interrupt Command Register
-#define LAPIC_IPI_ICR_LOWER 0x30
-#define LAPIC_IPI_ICR_UPPER 0x31
+#define LAPIC_IPI_ICR_LOWER 0x30
+#define LAPIC_IPI_ICR_UPPER 0x31
/* Interrupts being serviced (in-service) and pending (interrupt request reg).
* Note these registers are not normal bitmaps, but instead are 8 separate
* 32-bit registers, spaced/aligned on 16 byte boundaries in the LAPIC address
* space. */
-#define LAPIC_ISR 0x10
-#define LAPIC_IRR 0x20
-#define LAPIC_DFR 0x0e
+#define LAPIC_ISR 0x10
+#define LAPIC_IRR 0x20
+#define LAPIC_DFR 0x0e
struct irq_handler; /* include loops */
@@ -129,7 +129,6 @@
static inline void lapic_disable(void)
{
apicrput(MSR_LAPIC_SPURIOUS, apicrget(MSR_LAPIC_SPURIOUS) & 0xffffefff);
- //write_msr(IA32_APIC_BASE, read_msr(IA32_APIC_BASE) & ~MSR_APIC_ENABLE);
}
static inline void lapic_enable(void)
@@ -203,15 +202,15 @@
*/
struct ioapic {
- spinlock_t lock; /* IOAPIC: register access */
- uintptr_t addr; /* IOAPIC: register base */
- uintptr_t paddr; /* register base */
- int nrdt; /* IOAPIC: size of RDT */
- int ibase; /* global interrupt base */
+ spinlock_t lock; /* IOAPIC: register access */
+ uintptr_t addr; /* IOAPIC: register base */
+ uintptr_t paddr; /* register base */
+ int nrdt; /* IOAPIC: size of RDT */
+ int ibase; /* global interrupt base */
};
struct lapic {
- int machno; /* similar to os_coreid, unused */
+ int machno; /* similar to os_coreid, unused */
uint32_t lvt[8];
int nlvt;
@@ -244,7 +243,7 @@
* [16] Interrupt Mask
*/
enum {
- MTf = 0x00000000, /* Fixed */
+ MTf = 0x00000000, /* Fixed */
MTlp = 0x00000100, /* Lowest Priority */
MTsmi = 0x00000200, /* SMI */
MTrr = 0x00000300, /* Remote Read */
diff --git a/kern/arch/x86/apic9.c b/kern/arch/x86/apic9.c
index 569ba71..e5eb11e 100644
--- a/kern/arch/x86/apic9.c
+++ b/kern/arch/x86/apic9.c
@@ -38,13 +38,13 @@
[MSR_LAPIC_LVT_THERMAL] "Thermal Sensor",
};
-enum { /* Siv */
- Swen = 0x00000100, /* Software Enable */
+enum { /* Siv */
+ Swen = 0x00000100, /* Software Enable */
Fdis = 0x00000200, /* Focus Disable */
};
-enum { /* Iclo */
- Lassert = 0x00004000, /* Assert level */
+enum { /* Iclo */
+ Lassert = 0x00004000, /* Assert level */
DSnone = 0x00000000, /* Use Destination Field */
DSself = 0x00040000, /* Self is only destination */
@@ -52,12 +52,12 @@
DSallexc = 0x000c0000, /* All Excluding self */
};
-enum { /* Tlvt */
- Periodic = 0x00020000, /* Periodic Timer Mode */
+enum { /* Tlvt */
+ Periodic = 0x00020000, /* Periodic Timer Mode */
};
-enum { /* Tdc */
- DivX2 = 0x00000000, /* Divide by 2 */
+enum { /* Tdc */
+ DivX2 = 0x00000000, /* Divide by 2 */
DivX4 = 0x00000001, /* Divide by 4 */
DivX8 = 0x00000002, /* Divide by 8 */
DivX16 = 0x00000003, /* Divide by 16 */
@@ -87,16 +87,18 @@
for (i = 7; i >= 0; i--) {
val = apicrget(r+i);
if (val) {
- printk("Register at range (%d,%d]: 0x%08x\n", ((i+1)*32),
- i*32, val);
+ printk("Register at range (%d,%d]: 0x%08x\n",
+ ((i + 1) * 32), i * 32, val);
}
}
}
+
void apic_isr_dump(void)
{
printk("ISR DUMP\n");
__apic_ir_dump(MSR_LAPIC_ISR_START);
}
+
void apic_irr_dump(void)
{
printk("IRR DUMP\n");
@@ -152,6 +154,7 @@
{
struct apic *apic;
uint64_t msr_val;
+
/*
* Mark the APIC useable if it has a good ID
* and the registers can be mapped.
@@ -209,8 +212,8 @@
if (!2)
return start;
- start =
- seprintf(start, end, "apicbase %#p apmachno %d\n", apicbase, apmachno);
+ start = seprintf(start, end, "apicbase %#p apmachno %d\n", apicbase,
+ apmachno);
for (i = 0; i < Napic; i++)
start = apicdump0(start, end, xlapic + i, i);
for (i = 0; i < Napic; i++)
@@ -221,6 +224,7 @@
void handle_lapic_error(struct hw_trapframe *hw_tf, void *data)
{
uint32_t err;
+
apicrput(MSR_LAPIC_ESR, 0);
err = apicrget(MSR_LAPIC_ESR);
/* i get a shitload of these on my nehalem, many with err == 0 */
@@ -247,7 +251,8 @@
apic = &xlapic[apicno];
/* The addr check tells us if it is an IOAPIC or not... */
if (!apic->useable || apic->addr) {
- printk("Unsuitable apicno %d on HW core %d!!\n", apicno, hw_core_id());
+ printk("Unsuitable apicno %d on HW core %d!!\n", apicno,
+ hw_core_id());
return 0;
}
/* Things that can only be done when on the processor owning the APIC,
@@ -262,8 +267,8 @@
apic->nlvt = nlvt;
apic->ver = ver & 0xff;
- /* These don't really matter in Physical mode; set the defaults anyway. If
- * we have problems with logical IPIs on AMD, check this out: */
+ /* These don't really matter in Physical mode; set the defaults anyway.
+ * If we have problems with logical IPIs on AMD, check this out: */
//if (memcmp(m->cpuinfo, "AuthenticAMD", 12) == 0)
// dfr = 0xf0000000;
//else
@@ -271,32 +276,32 @@
//apicrput(Df, dfr);
//apicrput(MSR_LAPIC_LDR, 0x00000000);
- /* Disable interrupts until ready by setting the Task Priority register to
- * 0xff. */
+ /* Disable interrupts until ready by setting the Task Priority register
+ * to 0xff. */
apicrput(MSR_LAPIC_TPR, 0xff);
- /* Software-enable the APIC in the Spurious Interrupt Vector register and
- * set the vector number. The vector number must have bits 3-0 0x0f unless
- * the Extended Spurious Vector Enable bit is set in the HyperTransport
- * Transaction Control register. */
+ /* Software-enable the APIC in the Spurious Interrupt Vector register
+ * and set the vector number. The vector number must have bits 3-0 0x0f
+ * unless the Extended Spurious Vector Enable bit is set in the
+ * HyperTransport Transaction Control register. */
apicrput(MSR_LAPIC_SPURIOUS, Swen | IdtLAPIC_SPURIOUS);
/* Acknowledge any outstanding interrupts. */
apicrput(MSR_LAPIC_EOI, 0);
/* Mask interrupts on Performance Counter overflow and Thermal Sensor if
- * implemented, and on Lintr0 (Legacy INTR), Lintr1 (Legacy NMI), and the
- * Timer. Clear any Error Status (write followed by read) and enable the
- * Error interrupt. */
+ * implemented, and on Lintr0 (Legacy INTR), Lintr1 (Legacy NMI), and
+ * the Timer. Clear any Error Status (write followed by read) and
+ * enable the Error interrupt. */
switch (apic->nlvt) {
- case 6:
- apicrput(MSR_LAPIC_LVT_THERMAL, Im);
- /* fall-through */
- case 5:
- apicrput(MSR_LAPIC_LVT_PERFMON, Im);
- /* fall-through */
- default:
- break;
+ case 6:
+ apicrput(MSR_LAPIC_LVT_THERMAL, Im);
+ /* fall-through */
+ case 5:
+ apicrput(MSR_LAPIC_LVT_PERFMON, Im);
+ /* fall-through */
+ default:
+ break;
}
/* lvt[0] and [1] were set to 0 in the BSS */
apicrput(MSR_LAPIC_LVT_LINT1, apic->lvt[1] | Im | IdtLAPIC_LINT1);
diff --git a/kern/arch/x86/arch.h b/kern/arch/x86/arch.h
index 0d3e935..b4c06fb 100644
--- a/kern/arch/x86/arch.h
+++ b/kern/arch/x86/arch.h
@@ -76,12 +76,14 @@
asm volatile("xorq %%rcx, %%rcx;"
"xorq %%rdx, %%rdx;"
"monitor;"
- /* this is racy, generically. we never check if the write to
- * the monitored address happened already. */
+ /* this is racy, generically. we never check
+ * if the write to the monitored address
+ * happened already. */
"movq $0, %%rax;" /* c-state hint. this is C1 */
"mwait;"
: : "a"(eax));
}
+
/* Check out k/a/x86/rdtsc_test.c for more info */
static inline uint64_t read_tsc_serialized(void)
{
@@ -107,9 +109,10 @@
// < 0 means more disabled calls have been made
// Mostly doing this so we can call disable_irqsave first if we want
- // one side or another "gets a point" if interrupts were already the
- // way it wanted to go. o/w, state stays at 0. if the state was not 0
- // then, enabling/disabling isn't even an option. just increment/decrement
+ // one side or another "gets a point" if interrupts were already the way
+ // it wanted to go. o/w, state stays at 0. if the state was not 0
+ // then, enabling/disabling isn't even an option. just
+ // increment/decrement
// if enabling is winning or tied, make sure it's enabled
if ((*state == 0) && !irq_is_enabled())
@@ -149,6 +152,7 @@
static inline void reboot(void)
{
uint8_t cf9 = inb(0xcf9) & ~6;
+
outb(0x92, 0x3);
outb(0xcf9, cf9 | 2);
outb(0xcf9, cf9 | 6);
@@ -192,11 +196,11 @@
static inline void __attribute__((noreturn))
__reset_stack_pointer(void *arg, uintptr_t sp, void (*f)(void *))
{
- /* FP must be zeroed before SP. Ideally, we'd do both atomically. If we
- * take an IRQ/NMI in between and set SP first, then a backtrace would be
- * confused since FP points *below* the SP that the *IRQ handler* is now
- * using. By zeroing FP first, at least we won't BT at all (though FP is
- * still out of sync with SP). */
+ /* FP must be zeroed before SP. Ideally, we'd do both atomically. If
+ * we take an IRQ/NMI in between and set SP first, then a backtrace
+ * would be confused since FP points *below* the SP that the *IRQ
+ * handler* is now using. By zeroing FP first, at least we won't BT at
+ * all (though FP is still out of sync with SP). */
asm volatile ("mov $0x0, %%rbp;"
"mov %0, %%rsp;"
"jmp *%%rdx;"
diff --git a/kern/arch/x86/atomic.h b/kern/arch/x86/atomic.h
index a7766d8..54dca37 100644
--- a/kern/arch/x86/atomic.h
+++ b/kern/arch/x86/atomic.h
@@ -132,18 +132,17 @@
static inline void __spin_lock_raw(volatile uint32_t *rlock)
{
uint8_t dicks = 0;
- asm volatile(
- "1: "
- " cmpb $0, %0; "
- " je 2f; "
- " pause; "
- " jmp 1b; "
- "2: "
- " movb $1, %1; "
- " xchgb %1, %0; "
- " cmpb $0, %1; "
- " jne 1b; "
- : : "m"(*rlock), "r"(dicks) : "cc");
+ asm volatile("1: "
+ " cmpb $0, %0; "
+ " je 2f; "
+ " pause; "
+ " jmp 1b; "
+ "2: "
+ " movb $1, %1; "
+ " xchgb %1, %0; "
+ " cmpb $0, %1; "
+ " jne 1b; "
+ : : "m"(*rlock), "r"(dicks) : "cc");
cmb(); /* need cmb(), the CPU mb() was handled by the xchg */
}
@@ -154,8 +153,8 @@
static inline bool __spin_trylock(spinlock_t *lock)
{
- /* since this is an or, we're not going to clobber the top bytes (if that
- * matters) */
+ /* since this is an or, we're not going to clobber the top bytes (if
+ * that matters) */
return !__sync_fetch_and_or(&lock->rlock, 1);
}
diff --git a/kern/arch/x86/boot/main.c b/kern/arch/x86/boot/main.c
index a42d289..5b68e3f 100644
--- a/kern/arch/x86/boot/main.c
+++ b/kern/arch/x86/boot/main.c
@@ -36,8 +36,7 @@
void readsect(void*, uint32_t);
void readseg(uint32_t, uint32_t, uint32_t);
-void
-cmain(void)
+void cmain(void)
{
proghdr_t *ph, *eph;
@@ -67,8 +66,7 @@
// Read 'count' bytes at 'offset' from kernel into virtual address 'va'.
// Might copy more than asked
-void
-readseg(uint32_t va, uint32_t count, uint32_t offset)
+void readseg(uint32_t va, uint32_t count, uint32_t offset)
{
uint32_t end_va;
@@ -91,16 +89,14 @@
}
}
-void
-waitdisk(void)
+void waitdisk(void)
{
// wait for disk ready
while ((inb(0x1F7) & 0xC0) != 0x40)
/* do nothing */;
}
-void
-readsect(void *dst, uint32_t offset)
+void readsect(void *dst, uint32_t offset)
{
// wait for disk to be ready
waitdisk();
@@ -112,14 +108,14 @@
Offset is 28 bytes long
*/
- outb(0x1F2, 1); // number of sectors to read
- outb(0x1F3, offset); // bits 0-7 (low bits) of 28-bit offset
- outb(0x1F4, offset >> 8); // bits 8-15 of 28-bit offset
- outb(0x1F5, offset >> 16); // bits 16-23 of 28-bit offset
- outb(0x1F6, (offset >> 24) | 0xE0); // bits 24-27 of 28-bit offset
- // bit 28 (= 0) means Disk 0
- // other bits (29-31) must be set to one
- outb(0x1F7, 0x20); // cmd 0x20 - read sectors
+ outb(0x1F2, 1); // number of sectors to read
+ outb(0x1F3, offset); // bits 0-7 (low bits) of 28-bit offset
+ outb(0x1F4, offset >> 8); // bits 8-15 of 28-bit offset
+ outb(0x1F5, offset >> 16); // bits 16-23 of 28-bit offset
+ outb(0x1F6, (offset >> 24) | 0xE0); // bits 24-27 of 28-bit offset
+ // bit 28 (= 0) means Disk 0
+ // other bits (29-31) must be set to one
+ outb(0x1F7, 0x20); // cmd 0x20 - read sectors
// wait for disk to be ready
waitdisk();
diff --git a/kern/arch/x86/console.c b/kern/arch/x86/console.c
index 43118de..9c4bd5c 100644
--- a/kern/arch/x86/console.c
+++ b/kern/arch/x86/console.c
@@ -15,30 +15,30 @@
/***** Serial I/O code *****/
-#define COM1 0x3F8 /* irq 4 */
-#define COM2 0x2F8 /* irq 3 */
-#define COM3 0x3E8 /* irq 4 */
-#define COM4 0x2E8 /* irq 3 */
+#define COM1 0x3F8 /* irq 4 */
+#define COM2 0x2F8 /* irq 3 */
+#define COM3 0x3E8 /* irq 4 */
+#define COM4 0x2E8 /* irq 3 */
-#define COM_RX 0 // In: Receive buffer (DLAB=0)
-#define COM_DLL 0 // Out: Divisor Latch Low (DLAB=1)
-#define COM_DLM 1 // Out: Divisor Latch High (DLAB=1)
-#define COM_IER 1 // Out: Interrupt Enable Register
-#define COM_IER_RDI 0x01 // Enable receiver data interrupt
-#define COM_IIR 2 // In: Interrupt ID Register
-#define COM_FCR 2 // Out: FIFO Control Register
-#define COM_LCR 3 // Out: Line Control Register
+#define COM_RX 0 // In: Receive buffer (DLAB=0)
+#define COM_DLL 0 // Out: Divisor Latch Low (DLAB=1)
+#define COM_DLM 1 // Out: Divisor Latch High (DLAB=1)
+#define COM_IER 1 // Out: Interrupt Enable Register
+#define COM_IER_RDI 0x01 // Enable receiver data interrupt
+#define COM_IIR 2 // In: Interrupt ID Register
+#define COM_FCR 2 // Out: FIFO Control Register
+#define COM_LCR 3 // Out: Line Control Register
#define COM_LCR_DLAB 0x80 // Divisor latch access bit
#define COM_LCR_WLEN8 0x03 // Wordlength: 8 bits
-#define COM_MCR 4 // Out: Modem Control Register
-#define COM_MCR_RTS 0x02 // RTS complement
-#define COM_MCR_DTR 0x01 // DTR complement
+#define COM_MCR 4 // Out: Modem Control Register
+#define COM_MCR_RTS 0x02 // RTS complement
+#define COM_MCR_DTR 0x01 // DTR complement
#define COM_MCR_OUT2 0x08 // Out2 complement
#define COM_MCR_GLB_IRQ 0x08 /* global irq controlled via MCR */
-#define COM_LSR 5 // In: Line Status Register
+#define COM_LSR 5 // In: Line Status Register
#define COM_LSR_DATA 0x01 // Data available
#define COM_LSR_READY 0x20 // Ready to send
-#define COM_SCRATCH 7 /* Scratch register */
+#define COM_SCRATCH 7 /* Scratch register */
/* List of all initialized console devices */
struct cons_dev_slist cdev_list = SLIST_HEAD_INITIALIZER(cdev_list);
@@ -50,9 +50,10 @@
if (!(inb(com + COM_LSR) & COM_LSR_DATA))
return -1;
*data = inb(com + COM_RX);
- /* serial input sends \r a lot, but we interpret them as \n later on. this
- * will help userspace too, which isn't expecting the \rs. the right answer
- * might involve telling userspace what sort of console this is. */
+ /* serial input sends \r a lot, but we interpret them as \n later on.
+ * this will help userspace too, which isn't expecting the \rs. the
+ * right answer might involve telling userspace what sort of console
+ * this is. */
if (*data == '\r')
*data = '\n';
return 0;
@@ -74,30 +75,30 @@
static void serial_put_char(struct cons_dev *cdev, uint8_t c)
{
assert(cdev->type == CONS_SER_DEV);
- /* We do some funky editing of a few chars, to suit what minicom seems to
- * expect (at least for brho). */
+ /* We do some funky editing of a few chars, to suit what minicom seems
+ * to expect (at least for brho). */
switch (c & 0xff) {
- case '\b':
- case 0x7f:
- #ifdef CONFIG_PRINTK_NO_BACKSPACE
- __serial_put_char(cdev->val, (uint8_t)('^'));
- __serial_put_char(cdev->val, (uint8_t)('H'));
- #else
- __serial_put_char(cdev->val, '\b');
- __serial_put_char(cdev->val, (uint8_t)(' '));
- __serial_put_char(cdev->val, '\b');
- #endif /* CONFIG_PRINTK_NO_BACKSPACE */
- break;
- case '\n':
- __serial_put_char(cdev->val, (uint8_t)('\n'));
- __serial_put_char(cdev->val, (uint8_t)('\r'));
- break;
- case '\r':
- __serial_put_char(cdev->val, (uint8_t)('\r'));
- break;
- default:
- __serial_put_char(cdev->val, (uint8_t)(c & 0xff));
- break;
+ case '\b':
+ case 0x7f:
+ #ifdef CONFIG_PRINTK_NO_BACKSPACE
+ __serial_put_char(cdev->val, (uint8_t)('^'));
+ __serial_put_char(cdev->val, (uint8_t)('H'));
+ #else
+ __serial_put_char(cdev->val, '\b');
+ __serial_put_char(cdev->val, (uint8_t)(' '));
+ __serial_put_char(cdev->val, '\b');
+ #endif /* CONFIG_PRINTK_NO_BACKSPACE */
+ break;
+ case '\n':
+ __serial_put_char(cdev->val, (uint8_t)('\n'));
+ __serial_put_char(cdev->val, (uint8_t)('\r'));
+ break;
+ case '\r':
+ __serial_put_char(cdev->val, (uint8_t)('\r'));
+ break;
+ default:
+ __serial_put_char(cdev->val, (uint8_t)(c & 0xff));
+ break;
}
}
@@ -105,6 +106,7 @@
static void serial_spam_char(int c)
{
struct cons_dev *i;
+
SLIST_FOREACH(i, &cdev_list, next) {
if (i->type == CONS_SER_DEV)
serial_put_char(i, c);
@@ -119,6 +121,7 @@
{
uint8_t val;
char *model = 0;
+
/* First, check that the port actually exists. I haven't seen any
* documentation of the LSR 0xff check, but it seems to work on qemu and
* hardware (brho's nehalem). Perhaps 0xff is the default state for
@@ -126,8 +129,8 @@
/* Serial port doesn't exist if COM_LSR returns 0xff */
if (inb(com + COM_LSR) == 0xff)
return model;
- /* Try to set FIFO, then based on the bits enabled, we can tell what model
- * it is */
+ /* Try to set FIFO, then based on the bits enabled, we can tell what
+ * model it is */
outb(com + COM_FCR, 0xe7);
val = inb(com + COM_IIR);
if (val & (1 << 6)) {
@@ -163,17 +166,17 @@
cdev->type = CONS_SER_DEV;
cdev->val = com;
switch (com) {
- case (COM1):
- case (COM3):
- cdev->irq = 4;
- break;
- case (COM2):
- case (COM4):
- cdev->irq = 3;
- break;
- default:
- /* not that printing is the safest thing right now... */
- panic("Unknown COM %d", com);
+ case COM1:
+ case COM3:
+ cdev->irq = 4;
+ break;
+ case COM2:
+ case COM4:
+ cdev->irq = 3;
+ break;
+ default:
+ /* not that printing is the safest thing right now... */
+ panic("Unknown COM %d", com);
}
cdev->getc = serial_get_char;
/* Turn off the FIFO (not sure this is needed) */
@@ -185,11 +188,12 @@
outb(com + COM_DLM, 0);
/* 8 data bits, 1 stop bit, parity off; turn off DLAB latch */
outb(com + COM_LCR, COM_LCR_WLEN8 & ~COM_LCR_DLAB);
- /* This should turn on hardware flow control and make sure the global irq
- * bit is on. This bit is definitely used some hardware's 16550As, though
- * not for qemu. Also, on both qemu and hardware, this whole line is a
- * noop, since the COM_MCR is already 0x0b, so we're just making sure the
- * three bits are still turned on (and leaving other bits unchanged) */
+ /* This should turn on hardware flow control and make sure the global
+ * irq bit is on. This bit is definitely used some hardware's 16550As,
+ * though not for qemu. Also, on both qemu and hardware, this whole
+ * line is a noop, since the COM_MCR is already 0x0b, so we're just
+ * making sure the three bits are still turned on (and leaving other
+ * bits unchanged) */
outb(com + COM_MCR, inb(com + COM_MCR) | COM_MCR_RTS | COM_MCR_DTR |
COM_MCR_GLB_IRQ);
/* Enable rx interrupts */
@@ -215,8 +219,7 @@
// page.
// Stupid I/O delay routine necessitated by historical PC design flaws
-static void
-delay(void)
+static void delay(void)
{
inb(0x84);
inb(0x84);
@@ -224,8 +227,7 @@
inb(0x84);
}
-static void
-lpt_putc(int c)
+static void lpt_putc(int c)
{
int i;
@@ -259,8 +261,7 @@
static uint16_t scrolling_crt_pos;
static uint8_t current_crt_buf;
-void
-cga_init(void)
+void cga_init(void)
{
volatile uint16_t *cp;
uint16_t was;
@@ -298,7 +299,8 @@
int offset = scrolling_crt_pos + leftovers - (screen_num + 1)*CRT_SIZE;
offset = (offset > 0) ? offset : 0;
- memcpy(crt_buf, scrolling_crt_buf + offset, CRT_SIZE * sizeof(uint16_t));
+ memcpy(crt_buf, scrolling_crt_buf + offset,
+ CRT_SIZE * sizeof(uint16_t));
}
static void scroll_screen_up(void)
@@ -321,8 +323,7 @@
set_screen(current_crt_buf);
}
-void
-cga_putc(int c)
+void cga_putc(int c)
{
// if no attribute given, then use black on white
if (!(c & ~0xFF))
@@ -364,13 +365,14 @@
break;
}
- // The purpose of this is to allow the screen to appear as if it is scrolling as
- // more lines are added beyond the size of the monitor. The top line is dropped
- // and everything is shifted up by one.
+ // The purpose of this is to allow the screen to appear as if it is
+ // scrolling as more lines are added beyond the size of the monitor.
+ // The top line is dropped and everything is shifted up by one.
if (crt_pos >= CRT_SIZE) {
int i;
- memcpy(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) * sizeof(uint16_t));
+ memcpy(crt_buf, crt_buf + CRT_COLS,
+ (CRT_SIZE - CRT_COLS) * sizeof(uint16_t));
for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i++)
crt_buf[i] = 0x0700 | ' ';
crt_pos -= CRT_COLS;
@@ -381,7 +383,8 @@
memcpy(scrolling_crt_buf, scrolling_crt_buf + CRT_COLS,
(SCROLLING_CRT_SIZE - CRT_COLS) * sizeof(uint16_t));
- for (i = SCROLLING_CRT_SIZE - CRT_COLS; i < SCROLLING_CRT_SIZE; i++)
+ for (i = SCROLLING_CRT_SIZE - CRT_COLS; i < SCROLLING_CRT_SIZE;
+ i++)
scrolling_crt_buf[i] = 0x0700 | ' ';
scrolling_crt_pos -= CRT_COLS;
}
@@ -399,7 +402,7 @@
#define NO 0
-#define SHIFT (1<<0)
+#define SHIFT (1<<0)
#define CTL (1<<1)
#define ALT (1<<2)
@@ -502,8 +505,7 @@
static bool crt_scrolled = FALSE;
/* TODO: i'm concerned about the (lack of) locking when scrolling the screen. */
-static int
-kbd_proc_data(void)
+static int kbd_proc_data(void)
{
#ifdef CONFIG_X86_DISABLE_KEYBOARD
/* on some machines with usb keyboards, any keyboard input triggers SMM
@@ -667,22 +669,19 @@
// `High'-level console I/O. Used by readline and cprintf.
-void
-cputchar(int c)
+void cputchar(int c)
{
cons_putc(c);
}
-void
-cputbuf(const char*buf, int len)
+void cputbuf(const char*buf, int len)
{
int i;
for(i = 0; i < len; i++)
cons_putc(buf[i]);
}
-int
-getchar(void)
+int getchar(void)
{
int c;
@@ -691,8 +690,7 @@
return c;
}
-int
-iscons(int fdnum)
+int iscons(int fdnum)
{
// used by readline
return 1;
diff --git a/kern/arch/x86/console.h b/kern/arch/x86/console.h
index 54d7615..e2660f8 100644
--- a/kern/arch/x86/console.h
+++ b/kern/arch/x86/console.h
@@ -11,16 +11,16 @@
/* Types of console devices */
#define CONS_KB_DEV 1
-#define CONS_SER_DEV 2
+#define CONS_SER_DEV 2
struct cons_dev;
/* Interrupt-driven console input devices */
struct cons_dev {
SLIST_ENTRY(cons_dev) next;
- int type; /* e.g., CONS_KB_DEV */
- int val; /* e.g., COM1 */
- int irq; /* desired irq */
- char *model; /* descriptive string */
+ int type; /* e.g., CONS_KB_DEV */
+ int val; /* e.g., COM1 */
+ int irq; /* desired irq */
+ char *model; /* descriptive string */
int (*getc)(struct cons_dev *, uint8_t *);
};
SLIST_HEAD(cons_dev_slist, cons_dev);
diff --git a/kern/arch/x86/cpuinfo.c b/kern/arch/x86/cpuinfo.c
index 0e16f75..1594252 100644
--- a/kern/arch/x86/cpuinfo.c
+++ b/kern/arch/x86/cpuinfo.c
@@ -50,8 +50,8 @@
cpu_set_feat(CPU_FEAT_X86_VENDOR_AMD);
- /* intel supports a way to hide the upper leaves of cpuid, beyond 3. the
- * bios might have done this, so we'll make sure it is off. */
+ /* intel supports a way to hide the upper leaves of cpuid, beyond 3.
+ * the bios might have done this, so we'll make sure it is off. */
if (cpu_has_feat(CPU_FEAT_X86_VENDOR_INTEL)) {
msr_val = read_msr(IA32_MISC_ENABLE);
if (msr_val & (1 << 22))
@@ -218,19 +218,21 @@
printk(" %sVirtual %sPhysical Ps Dr Ac G CD WT U W P EPTE\n",
BIT_SPACING, BIT_SPACING);
- printk("-------------------------------------------------%s\n", BIT_DASHES);
+ printk("-------------------------------------------------%s\n",
+ BIT_DASHES);
for(i = 0; i < size; i += PGSIZE, start += PGSIZE) {
pte = pgdir_walk(pgdir, (void*)start, 0);
printk("%p ", start);
if (pte_walk_okay(pte)) {
- /* A note on PTE perms. If you look at just the PTE, you don't get
- * the full picture for W and U. Those are the intersection of all
- * bits. In Akaros, we do U or not at the earliest point (PML4
- * entries). All other PTEs have U set. For W, it's the opposite.
- * The PTE for the actual page has W or not, and all others has W
- * set. W needs to be more fine-grained, but U doesn't. Plus the
- * UVPT mapping requires the U to see interior pages (but have W
- * off). */
+ /* A note on PTE perms. If you look at just the PTE,
+ * you don't get the full picture for W and U. Those
+ * are the intersection of all bits. In Akaros, we do U
+ * or not at the earliest point (PML4 entries). All
+ * other PTEs have U set. For W, it's the opposite.
+ * The PTE for the actual page has W or not, and all
+ * others has W set. W needs to be more fine-grained,
+ * but U doesn't. Plus the UVPT mapping requires the U
+ * to see interior pages (but have W off). */
perm = get_va_perms(pgdir, (void*)start);
printk("%p %1d %1d %1d %1d %1d %1d %1d %1d %1d 0x%llx\n",
pte_get_paddr(pte),
diff --git a/kern/arch/x86/devarch.c b/kern/arch/x86/devarch.c
index a70c96f..a40c622 100644
--- a/kern/arch/x86/devarch.c
+++ b/kern/arch/x86/devarch.c
@@ -51,8 +51,8 @@
spinlock_t lock;
struct io_map *map;
struct io_map *free;
- struct io_map maps[32]; // some initial free maps
- qlock_t ql; // lock for reading map
+ struct io_map maps[32]; // some initial free maps
+ qlock_t ql; // lock for reading map
} iomap;
enum {
@@ -99,13 +99,14 @@
};
static struct address_range msr_wr_wlist[] = {
ADDRESS_RANGE(MSR_IA32_PERFCTR0,
- MSR_IA32_PERFCTR0 + MSR_MAX_VAR_COUNTERS - 1),
+ MSR_IA32_PERFCTR0 + MSR_MAX_VAR_COUNTERS - 1),
ADDRESS_RANGE(MSR_ARCH_PERFMON_EVENTSEL0,
- MSR_ARCH_PERFMON_EVENTSEL0 + MSR_MAX_VAR_COUNTERS - 1),
+ MSR_ARCH_PERFMON_EVENTSEL0 + MSR_MAX_VAR_COUNTERS - 1),
ADDRESS_RANGE(MSR_IA32_PERF_CTL, MSR_IA32_PERF_CTL),
ADDRESS_RANGE(MSR_CORE_PERF_FIXED_CTR0,
- MSR_CORE_PERF_FIXED_CTR0 + MSR_MAX_FIX_COUNTERS - 1),
- ADDRESS_RANGE(MSR_CORE_PERF_FIXED_CTR_CTRL, MSR_CORE_PERF_GLOBAL_OVF_CTRL),
+ MSR_CORE_PERF_FIXED_CTR0 + MSR_MAX_FIX_COUNTERS - 1),
+ ADDRESS_RANGE(MSR_CORE_PERF_FIXED_CTR_CTRL,
+ MSR_CORE_PERF_GLOBAL_OVF_CTRL),
ADDRESS_RANGE(MSR_IA32_MPERF, MSR_IA32_APERF),
};
int gdbactive = 0;
@@ -150,7 +151,8 @@
map = *l;
if (map->end <= port)
continue;
- if (map->reserved && map->start == port && map->end == port + size) {
+ if (map->reserved && map->start == port &&
+ map->end == port + size) {
map->reserved = 0;
spin_unlock(&(&iomap)->lock);
return map->start;
@@ -393,73 +395,73 @@
ktop = kptr + usize;
error_assert(EBADMSG, (kptr + 1) <= ktop);
switch (*kptr++) {
- case PERFMON_CMD_COUNTER_OPEN: {
- int ped;
- struct perfmon_event pev;
- struct core_set cset;
+ case PERFMON_CMD_COUNTER_OPEN: {
+ int ped;
+ struct perfmon_event pev;
+ struct core_set cset;
- error_assert(EBADMSG, (kptr + 3 * sizeof(uint64_t)) <= ktop);
- perfmon_init_event(&pev);
- kptr = get_le_u64(kptr, &pev.event);
- kptr = get_le_u64(kptr, &pev.flags);
- kptr = get_le_u64(kptr, &pev.trigger_count);
- kptr = get_le_u64(kptr, &pev.user_data);
- kptr = arch_read_core_set(&cset, kptr, ktop);
+ error_assert(EBADMSG, (kptr + 3 * sizeof(uint64_t)) <= ktop);
+ perfmon_init_event(&pev);
+ kptr = get_le_u64(kptr, &pev.event);
+ kptr = get_le_u64(kptr, &pev.flags);
+ kptr = get_le_u64(kptr, &pev.trigger_count);
+ kptr = get_le_u64(kptr, &pev.user_data);
+ kptr = arch_read_core_set(&cset, kptr, ktop);
- ped = perfmon_open_event(&cset, pc->ps, &pev);
+ ped = perfmon_open_event(&cset, pc->ps, &pev);
- pc->resp_size = sizeof(uint32_t);
- pc->resp = kmalloc(pc->resp_size, MEM_WAIT);
- put_le_u32(pc->resp, (uint32_t) ped);
- break;
- }
- case PERFMON_CMD_COUNTER_STATUS: {
- uint32_t ped;
- uint8_t *rptr;
- struct perfmon_status *pef;
+ pc->resp_size = sizeof(uint32_t);
+ pc->resp = kmalloc(pc->resp_size, MEM_WAIT);
+ put_le_u32(pc->resp, (uint32_t) ped);
+ break;
+ }
+ case PERFMON_CMD_COUNTER_STATUS: {
+ uint32_t ped;
+ uint8_t *rptr;
+ struct perfmon_status *pef;
- error_assert(EBADMSG, (kptr + sizeof(uint32_t)) <= ktop);
- kptr = get_le_u32(kptr, &ped);
+ error_assert(EBADMSG, (kptr + sizeof(uint32_t)) <= ktop);
+ kptr = get_le_u32(kptr, &ped);
- pef = perfmon_get_event_status(pc->ps, (int) ped);
+ pef = perfmon_get_event_status(pc->ps, (int) ped);
- pc->resp_size = sizeof(uint32_t) + num_cores * sizeof(uint64_t);
- pc->resp = kmalloc(pc->resp_size, MEM_WAIT);
- rptr = put_le_u32(pc->resp, num_cores);
- for (int i = 0; i < num_cores; i++)
- rptr = put_le_u64(rptr, pef->cores_values[i]);
+ pc->resp_size = sizeof(uint32_t) + num_cores * sizeof(uint64_t);
+ pc->resp = kmalloc(pc->resp_size, MEM_WAIT);
+ rptr = put_le_u32(pc->resp, num_cores);
+ for (int i = 0; i < num_cores; i++)
+ rptr = put_le_u64(rptr, pef->cores_values[i]);
- perfmon_free_event_status(pef);
- break;
- }
- case PERFMON_CMD_COUNTER_CLOSE: {
- uint32_t ped;
+ perfmon_free_event_status(pef);
+ break;
+ }
+ case PERFMON_CMD_COUNTER_CLOSE: {
+ uint32_t ped;
- error_assert(EBADMSG, (kptr + sizeof(uint32_t)) <= ktop);
- kptr = get_le_u32(kptr, &ped);
+ error_assert(EBADMSG, (kptr + sizeof(uint32_t)) <= ktop);
+ kptr = get_le_u32(kptr, &ped);
- perfmon_close_event(pc->ps, (int) ped);
- break;
- }
- case PERFMON_CMD_CPU_CAPS: {
- uint8_t *rptr;
- struct perfmon_cpu_caps pcc;
+ perfmon_close_event(pc->ps, (int) ped);
+ break;
+ }
+ case PERFMON_CMD_CPU_CAPS: {
+ uint8_t *rptr;
+ struct perfmon_cpu_caps pcc;
- perfmon_get_cpu_caps(&pcc);
+ perfmon_get_cpu_caps(&pcc);
- pc->resp_size = 6 * sizeof(uint32_t);
- pc->resp = kmalloc(pc->resp_size, MEM_WAIT);
+ pc->resp_size = 6 * sizeof(uint32_t);
+ pc->resp = kmalloc(pc->resp_size, MEM_WAIT);
- rptr = put_le_u32(pc->resp, pcc.perfmon_version);
- rptr = put_le_u32(rptr, pcc.proc_arch_events);
- rptr = put_le_u32(rptr, pcc.bits_x_counter);
- rptr = put_le_u32(rptr, pcc.counters_x_proc);
- rptr = put_le_u32(rptr, pcc.bits_x_fix_counter);
- rptr = put_le_u32(rptr, pcc.fix_counters_x_proc);
- break;
- }
- default:
- error(EINVAL, "Invalid perfmon command: 0x%x", kptr[-1]);
+ rptr = put_le_u32(pc->resp, pcc.perfmon_version);
+ rptr = put_le_u32(rptr, pcc.proc_arch_events);
+ rptr = put_le_u32(rptr, pcc.bits_x_counter);
+ rptr = put_le_u32(rptr, pcc.counters_x_proc);
+ rptr = put_le_u32(rptr, pcc.bits_x_fix_counter);
+ rptr = put_le_u32(rptr, pcc.fix_counters_x_proc);
+ break;
+ }
+ default:
+ error(EINVAL, "Invalid perfmon command: 0x%x", kptr[-1]);
}
poperror();
qunlock(&pc->resp_lock);
@@ -472,12 +474,12 @@
{
c = devopen(c, omode, archdir, Qmax, devgen);
switch ((uint32_t) c->qid.path) {
- case Qperf:
- if (!perfmon_supported())
- error(ENODEV, "perf is not supported");
- assert(!c->aux);
- c->aux = arch_create_perf_context();
- break;
+ case Qperf:
+ if (!perfmon_supported())
+ error(ENODEV, "perf is not supported");
+ assert(!c->aux);
+ c->aux = arch_create_perf_context();
+ break;
}
return c;
@@ -486,12 +488,12 @@
static void archclose(struct chan *c)
{
switch ((uint32_t) c->qid.path) {
- case Qperf:
- if (c->aux) {
- arch_free_perf_context((struct perf_context *) c->aux);
- c->aux = NULL;
- }
- break;
+ case Qperf:
+ if (c->aux) {
+ arch_free_perf_context((struct perf_context *) c->aux);
+ c->aux = NULL;
+ }
+ break;
}
}
@@ -508,96 +510,99 @@
struct msr_value msrv;
switch ((uint32_t) c->qid.path) {
- case Qdir:
- return devdirread(c, a, n, archdir, Qmax, devgen);
- case Qgdb:
- p = gdbactive ? "1" : "0";
- return readstr(offset, a, n, p);
- case Qiob:
- port = offset;
- checkport(offset, offset + n);
- for (p = a; port < offset + n; port++)
- *p++ = inb(port);
- return n;
- case Qiow:
- if (n & 1)
- error(EINVAL, ERROR_FIXME);
- checkport(offset, offset + n);
- sp = a;
- for (port = offset; port < offset + n; port += 2)
- *sp++ = inw(port);
- return n;
- case Qiol:
- if (n & 3)
- error(EINVAL, ERROR_FIXME);
- checkport(offset, offset + n);
- lp = a;
- for (port = offset; port < offset + n; port += 4)
- *lp++ = inl(port);
- return n;
- case Qioalloc:
- break;
- case Qrealmem:
- return readmem(offset, a, n, KADDR(0), REAL_MEM_SIZE);
- case Qmsr:
- if (!address_range_find(msr_rd_wlist, ARRAY_SIZE(msr_rd_wlist),
- (uintptr_t) offset))
- error(EPERM, "MSR 0x%x not in read whitelist", offset);
- core_set_init(&cset);
- core_set_fill_available(&cset);
- msr_set_address(&msra, (uint32_t) offset);
- values = kzmalloc(num_cores * sizeof(uint64_t),
- MEM_WAIT);
- if (!values)
- error(ENOMEM, ERROR_FIXME);
- msr_set_values(&msrv, values, num_cores);
+ case Qdir:
+ return devdirread(c, a, n, archdir, Qmax, devgen);
+ case Qgdb:
+ p = gdbactive ? "1" : "0";
+ return readstr(offset, a, n, p);
+ case Qiob:
+ port = offset;
+ checkport(offset, offset + n);
+ for (p = a; port < offset + n; port++)
+ *p++ = inb(port);
+ return n;
+ case Qiow:
+ if (n & 1)
+ error(EINVAL, ERROR_FIXME);
+ checkport(offset, offset + n);
+ sp = a;
+ for (port = offset; port < offset + n; port += 2)
+ *sp++ = inw(port);
+ return n;
+ case Qiol:
+ if (n & 3)
+ error(EINVAL, ERROR_FIXME);
+ checkport(offset, offset + n);
+ lp = a;
+ for (port = offset; port < offset + n; port += 4)
+ *lp++ = inl(port);
+ return n;
+ case Qioalloc:
+ break;
+ case Qrealmem:
+ return readmem(offset, a, n, KADDR(0), REAL_MEM_SIZE);
+ case Qmsr:
+ if (!address_range_find(msr_rd_wlist, ARRAY_SIZE(msr_rd_wlist),
+ (uintptr_t) offset))
+ error(EPERM, "MSR 0x%x not in read whitelist", offset);
+ core_set_init(&cset);
+ core_set_fill_available(&cset);
+ msr_set_address(&msra, (uint32_t) offset);
+ values = kzmalloc(num_cores * sizeof(uint64_t),
+ MEM_WAIT);
+ if (!values)
+ error(ENOMEM, ERROR_FIXME);
+ msr_set_values(&msrv, values, num_cores);
- err = msr_cores_read(&cset, &msra, &msrv);
+ err = msr_cores_read(&cset, &msra, &msrv);
- if (likely(!err)) {
- if (n >= num_cores * sizeof(uint64_t)) {
- if (!memcpy_to_user_errno(current, a, values,
- num_cores * sizeof(uint64_t)))
- n = num_cores * sizeof(uint64_t);
- else
- n = -1;
- } else {
- kfree(values);
- error(ERANGE, "Not enough space for MSR read");
- }
- } else {
- switch (-err) {
- case (EFAULT):
- error(-err, "read_msr() faulted on MSR 0x%x", offset);
- case (ERANGE):
- error(-err, "Not enough space for MSR read");
- };
- error(-err, "MSR read failed");
- }
- kfree(values);
- return n;
- case Qperf: {
- struct perf_context *pc = (struct perf_context *) c->aux;
-
- assert(pc);
- qlock(&pc->resp_lock);
- if (pc->resp && ((size_t) offset < pc->resp_size)) {
- n = MIN(n, (long) pc->resp_size - (long) offset);
- if (memcpy_to_user_errno(current, a, pc->resp + offset, n))
+ if (likely(!err)) {
+ if (n >= num_cores * sizeof(uint64_t)) {
+ if (!memcpy_to_user_errno(current, a, values,
+ num_cores *
+ sizeof(uint64_t)))
+ n = num_cores * sizeof(uint64_t);
+ else
n = -1;
} else {
- n = 0;
+ kfree(values);
+ error(ERANGE, "Not enough space for MSR read");
}
- qunlock(&pc->resp_lock);
-
- return n;
- case Qcstate:
- return readnum_hex(offset, a, n, get_cstate(), NUMSIZE32);
- case Qpstate:
- return readnum_hex(offset, a, n, get_pstate(), NUMSIZE32);
+ } else {
+ switch (-err) {
+ case (EFAULT):
+ error(-err, "read_msr() faulted on MSR 0x%x",
+ offset);
+ case (ERANGE):
+ error(-err, "Not enough space for MSR read");
+ };
+ error(-err, "MSR read failed");
}
- default:
- error(EINVAL, ERROR_FIXME);
+ kfree(values);
+ return n;
+ case Qperf: {
+ struct perf_context *pc = (struct perf_context *) c->aux;
+
+ assert(pc);
+ qlock(&pc->resp_lock);
+ if (pc->resp && ((size_t) offset < pc->resp_size)) {
+ n = MIN(n, (long) pc->resp_size - (long) offset);
+ if (memcpy_to_user_errno(current, a, pc->resp + offset,
+ n))
+ n = -1;
+ } else {
+ n = 0;
+ }
+ qunlock(&pc->resp_lock);
+
+ return n;
+ case Qcstate:
+ return readnum_hex(offset, a, n, get_cstate(), NUMSIZE32);
+ case Qpstate:
+ return readnum_hex(offset, a, n, get_pstate(), NUMSIZE32);
+ }
+ default:
+ error(EINVAL, ERROR_FIXME);
}
if ((buf = kzmalloc(n, 0)) == NULL)
@@ -607,18 +612,19 @@
offset = offset / Linelen;
switch ((uint32_t) c->qid.path) {
- case Qioalloc:
- spin_lock(&(&iomap)->lock);
- for (map = iomap.map; n > 0 && map != NULL; map = map->next) {
- if (offset-- > 0)
- continue;
- snprintf(p, n * Linelen, "%#8p %#8p %-12.12s\n", map->start,
- map->end - 1, map->tag);
- p += Linelen;
- n--;
- }
- spin_unlock(&(&iomap)->lock);
- break;
+ case Qioalloc:
+ spin_lock(&(&iomap)->lock);
+ for (map = iomap.map; n > 0 && map != NULL; map = map->next) {
+ if (offset-- > 0)
+ continue;
+ snprintf(p, n * Linelen, "%#8p %#8p %-12.12s\n",
+ map->start,
+ map->end - 1, map->tag);
+ p += Linelen;
+ n--;
+ }
+ spin_unlock(&(&iomap)->lock);
+ break;
}
n = p - buf;
@@ -666,77 +672,78 @@
struct msr_value msrv;
switch ((uint32_t) c->qid.path) {
- case Qgdb:
- p = a;
- if (n != 1)
- error(EINVAL, "Gdb: Write one byte, '1' or '0'");
- if (*p == '1')
- gdbactive = 1;
- else if (*p == '0')
- gdbactive = 0;
- else
- error(EINVAL, "Gdb: must be 1 or 0");
- return 1;
- case Qiob:
- p = a;
- checkport(offset, offset + n);
- for (port = offset; port < offset + n; port++)
- outb(port, *p++);
- return n;
- case Qiow:
- if (n & 1)
- error(EINVAL, ERROR_FIXME);
- checkport(offset, offset + n);
- sp = a;
- for (port = offset; port < offset + n; port += 2)
- outw(port, *sp++);
- return n;
- case Qiol:
- if (n & 3)
- error(EINVAL, ERROR_FIXME);
- checkport(offset, offset + n);
- lp = a;
- for (port = offset; port < offset + n; port += 4)
- outl(port, *lp++);
- return n;
- case Qmsr:
- if (!address_range_find(msr_wr_wlist, ARRAY_SIZE(msr_wr_wlist),
- (uintptr_t) offset))
- error(EPERM, "MSR 0x%x not in write whitelist", offset);
- if (n != sizeof(uint64_t))
- error(EINVAL, "Tried to write more than a u64 (%p)", n);
- if (memcpy_from_user_errno(current, &value, a, sizeof(value)))
- return -1;
-
- core_set_init(&cset);
- core_set_fill_available(&cset);
- msr_set_address(&msra, (uint32_t) offset);
- msr_set_value(&msrv, value);
-
- err = msr_cores_write(&cset, &msra, &msrv);
- if (unlikely(err)) {
- switch (-err) {
- case (EFAULT):
- error(-err, "write_msr() faulted on MSR 0x%x", offset);
- case (ERANGE):
- error(-err, "Not enough space for MSR write");
- };
- error(-err, "MSR write failed");
- }
- return sizeof(uint64_t);
- case Qperf: {
- struct perf_context *pc = (struct perf_context *) c->aux;
-
- assert(pc);
-
- return arch_perf_write(pc, a, n);
- }
- case Qcstate:
- return cstate_write(a, n, 0);
- case Qpstate:
- return pstate_write(a, n, 0);
- default:
+ case Qgdb:
+ p = a;
+ if (n != 1)
+ error(EINVAL, "Gdb: Write one byte, '1' or '0'");
+ if (*p == '1')
+ gdbactive = 1;
+ else if (*p == '0')
+ gdbactive = 0;
+ else
+ error(EINVAL, "Gdb: must be 1 or 0");
+ return 1;
+ case Qiob:
+ p = a;
+ checkport(offset, offset + n);
+ for (port = offset; port < offset + n; port++)
+ outb(port, *p++);
+ return n;
+ case Qiow:
+ if (n & 1)
error(EINVAL, ERROR_FIXME);
+ checkport(offset, offset + n);
+ sp = a;
+ for (port = offset; port < offset + n; port += 2)
+ outw(port, *sp++);
+ return n;
+ case Qiol:
+ if (n & 3)
+ error(EINVAL, ERROR_FIXME);
+ checkport(offset, offset + n);
+ lp = a;
+ for (port = offset; port < offset + n; port += 4)
+ outl(port, *lp++);
+ return n;
+ case Qmsr:
+ if (!address_range_find(msr_wr_wlist, ARRAY_SIZE(msr_wr_wlist),
+ (uintptr_t) offset))
+ error(EPERM, "MSR 0x%x not in write whitelist", offset);
+ if (n != sizeof(uint64_t))
+ error(EINVAL, "Tried to write more than a u64 (%p)", n);
+ if (memcpy_from_user_errno(current, &value, a, sizeof(value)))
+ return -1;
+
+ core_set_init(&cset);
+ core_set_fill_available(&cset);
+ msr_set_address(&msra, (uint32_t) offset);
+ msr_set_value(&msrv, value);
+
+ err = msr_cores_write(&cset, &msra, &msrv);
+ if (unlikely(err)) {
+ switch (-err) {
+ case (EFAULT):
+ error(-err, "write_msr() faulted on MSR 0x%x",
+ offset);
+ case (ERANGE):
+ error(-err, "Not enough space for MSR write");
+ };
+ error(-err, "MSR write failed");
+ }
+ return sizeof(uint64_t);
+ case Qperf: {
+ struct perf_context *pc = (struct perf_context *) c->aux;
+
+ assert(pc);
+
+ return arch_perf_write(pc, a, n);
+ }
+ case Qcstate:
+ return cstate_write(a, n, 0);
+ case Qpstate:
+ return pstate_write(a, n, 0);
+ default:
+ error(EINVAL, ERROR_FIXME);
}
return 0;
}
diff --git a/kern/arch/x86/idle.c b/kern/arch/x86/idle.c
index 202016d..101de50 100644
--- a/kern/arch/x86/idle.c
+++ b/kern/arch/x86/idle.c
@@ -12,10 +12,12 @@
void cpu_halt(void)
{
if (cpu_has_feat(CPU_FEAT_X86_MWAIT)) {
- /* TODO: since we're monitoring anyway, x86 could use monitor/mwait for
- * KMSGs, instead of relying on IPIs. (Maybe only for ROUTINE). */
+ /* TODO: since we're monitoring anyway, x86 could use
+ * monitor/mwait for KMSGs, instead of relying on IPIs. (Maybe
+ * only for ROUTINE). */
asm volatile("monitor" : : "a"(KERNBASE), "c"(0), "d"(0));
- asm volatile("sti; mwait" : : "c"(0x0), "a"(x86_cstate) : "memory");
+ asm volatile("sti; mwait" : : "c"(0x0), "a"(x86_cstate)
+ : "memory");
} else {
asm volatile("sti; hlt" : : : "memory");
}
@@ -28,13 +30,15 @@
void cpu_halt_notif_pending(struct preempt_data *vcpd)
{
if (cpu_has_feat(CPU_FEAT_X86_MWAIT))
- asm volatile("monitor" : : "a"(&vcpd->notif_pending), "c"(0), "d"(0));
+ asm volatile("monitor" :
+ : "a"(&vcpd->notif_pending), "c"(0), "d"(0));
if (vcpd->notif_pending)
return;
- /* Note we don't use the ecx=1 setting - we actually want to sti so that we
- * handle the IRQ and not just wake from it. */
+ /* Note we don't use the ecx=1 setting - we actually want to sti so that
+ * we handle the IRQ and not just wake from it. */
if (cpu_has_feat(CPU_FEAT_X86_MWAIT))
- asm volatile("sti; mwait" : : "c"(0x0), "a"(x86_cstate) : "memory");
+ asm volatile("sti; mwait" :
+ : "c"(0x0), "a"(x86_cstate) : "memory");
else
asm volatile("sti; hlt" : : : "memory");
disable_irq();
@@ -44,9 +48,9 @@
{
uint64_t perf_ctl;
- /* This MSR was introduced in 0f_03 (family/model), so checking cpuid should
- * suffice. Though my Qemu says it is a later generation and still fails to
- * support it (patches pending, I hear). */
+ /* This MSR was introduced in 0f_03 (family/model), so checking cpuid
+ * should suffice. Though my Qemu says it is a later generation and
+ * still fails to support it (patches pending, I hear). */
if (read_msr_safe(MSR_IA32_PERF_CTL, &perf_ctl))
return;
/* The p-state ratio is actually at 15:8, AFAIK, for both PERF_CTL and
@@ -65,7 +69,8 @@
* lieu of a full per-model driver, we can just take a peak. */
if (read_msr_safe(MSR_TURBO_RATIO_LIMIT, &turbo_ratio_limit))
return;
- /* The lowest byte is the max turbo ratio achievable by one active core. */
+ /* The lowest byte is the max turbo ratio achievable by one active core.
+ */
set_pstate(turbo_ratio_limit & 0xff);
}
@@ -91,8 +96,8 @@
void set_cstate(unsigned int cstate)
{
- /* No real need to lock for an assignment. Any core can set this, and other
- * cores will notice the next time they halt. */
+ /* No real need to lock for an assignment. Any core can set this, and
+ * other cores will notice the next time they halt. */
x86_cstate = cstate;
}
diff --git a/kern/arch/x86/init.c b/kern/arch/x86/init.c
index 5cf6076..965b15f 100644
--- a/kern/arch/x86/init.c
+++ b/kern/arch/x86/init.c
@@ -29,25 +29,28 @@
return;
/* Control code intercepts */
switch (c) {
- case capchar2ctl('G'):
- /* traditional 'ctrl-g', will put you in the monitor gracefully */
- send_kernel_message(core_id(), __run_mon, 0, 0, 0, KMSG_ROUTINE);
+ case capchar2ctl('G'):
+ /* traditional 'ctrl-g', will put you in the monitor gracefully
+ */
+ send_kernel_message(core_id(), __run_mon, 0, 0, 0,
+ KMSG_ROUTINE);
+ return;
+ case capchar2ctl('Q'):
+ /* force you into the monitor. you might deadlock. */
+ printk("\nForcing entry to the monitor\n");
+ monitor(hw_tf);
+ return;
+ case capchar2ctl('B'):
+ /* backtrace / debugging for the core receiving the irq */
+ printk("\nForced trapframe and backtrace for core %d\n",
+ core_id());
+ if (!hw_tf) {
+ printk("(no hw_tf, we probably polled the console)\n");
return;
- case capchar2ctl('Q'):
- /* force you into the monitor. you might deadlock. */
- printk("\nForcing entry to the monitor\n");
- monitor(hw_tf);
- return;
- case capchar2ctl('B'):
- /* backtrace / debugging for the core receiving the irq */
- printk("\nForced trapframe and backtrace for core %d\n", core_id());
- if (!hw_tf) {
- printk("(no hw_tf, we probably polled the console)\n");
- return;
- }
- print_trapframe(hw_tf);
- backtrace_hwtf(hw_tf);
- return;
+ }
+ print_trapframe(hw_tf);
+ backtrace_hwtf(hw_tf);
+ return;
}
cons_add_char(c);
}
@@ -74,7 +77,8 @@
void ancillary_state_init(void)
{
uint32_t eax, ebx, ecx, edx;
- uint64_t proc_supported_features; /* proc supported user state components */
+ /* proc supported user state components */
+ uint64_t proc_supported_features;
// If you don't at least have FXSAVE and FXRSTOR
// (includes OSFXSR), you don't boot.
@@ -83,7 +87,8 @@
if (cpu_has_feat(CPU_FEAT_X86_XSAVE)) {
// Next determine the user state components supported
- // by the processor and set x86_default_xcr0 in proc_global_info.
+ // by the processor and set x86_default_xcr0 in
+ // proc_global_info.
cpuid(0x0d, 0x00, &eax, 0, 0, &edx);
proc_supported_features = ((uint64_t)edx << 32) | eax;
@@ -93,25 +98,27 @@
proc_supported_features;
/*
- * Make sure CR4.OSXSAVE is set and set the local xcr0 to the default.
- * We will do both of these things again during per-cpu init,
- * but we are about to use XSAVE to build our default extended state
- * record, so we need them enabled.
- * You must set CR4_OSXSAVE before setting xcr0, or a #UD fault occurs.
+ * Make sure CR4.OSXSAVE is set and set the local xcr0 to the
+ * default. We will do both of these things again during
+ * per-cpu init, but we are about to use XSAVE to build our
+ * default extended state record, so we need them enabled. You
+ * must set CR4_OSXSAVE before setting xcr0, or a #UD fault
+ * occurs.
*/
lcr4(rcr4() | CR4_OSXSAVE);
lxcr0(__proc_global_info.x86_default_xcr0);
- /* Build a default set of extended state values that we can later use
- * to initialize extended state on other cores, or restore on this
- * core. FNINIT won't actually do it - if you xsave after fninit, x87
- * will show up as active in xstate_bv[0]. Instead, we just need
- * the xstate_bv bits zeroed (and memset the rest for sanity's sake).
+ /* Build a default set of extended state values that we can
+ * later use to initialize extended state on other cores, or
+ * restore on this core. FNINIT won't actually do it - if you
+ * xsave after fninit, x87 will show up as active in
+ * xstate_bv[0]. Instead, we just need the xstate_bv bits
+ * zeroed (and memset the rest for sanity's sake).
*/
memset(&x86_default_fpu, 0x00, sizeof(struct ancillary_state));
- /* We must set the MXCSR field in the default state struct to its
- * power-on value of 0x1f80. This masks all SIMD floating
+ /* We must set the MXCSR field in the default state struct to
+ * its power-on value of 0x1f80. This masks all SIMD floating
* point exceptions and clears all SIMD floating-point exception
* flags, sets rounding control to round-nearest, disables
* flush-to-zero mode, and disables denormals-are-zero mode.
@@ -132,13 +139,14 @@
__proc_global_info.x86_default_xcr0 = 0x0;
/*
- * Build a default set of extended state values that we can later use to
- * initialize extended state on other cores, or restore on this core.
- * We need to use FNINIT to reset the FPU before saving, in case boot
- * agents used the FPU or it is dirty for some reason. An old comment
- * that used to be here said "had this happen on c89, which had a full
- * FP stack after booting." Note that FNINIT does not clear the data
- * registers, but it tags them all as empty (0b11).
+ * Build a default set of extended state values that we can
+ * later use to initialize extended state on other cores, or
+ * restore on this core. We need to use FNINIT to reset the FPU
+ * before saving, in case boot agents used the FPU or it is
+ * dirty for some reason. An old comment that used to be here
+ * said "had this happen on c89, which had a full FP stack after
+ * booting." Note that FNINIT does not clear the data registers,
+ * but it tags them all as empty (0b11).
*/
// Zero the default extended state memory region before saving.
@@ -146,12 +154,14 @@
memset(&x86_default_fpu, 0x00, sizeof(struct ancillary_state));
/*
- * FNINIT clears FIP and FDP and, even though it is technically a
- * control instruction, it clears FOP while initializing the FPU.
+ * FNINIT clears FIP and FDP and, even though it is technically
+ * a control instruction, it clears FOP while initializing the
+ * FPU.
*
- * This marks the STX/MMX registers as empty in the FPU tag word,
- * but does not actually clear the values in the registers,
- * so we manually clear them in the xsave area after saving.
+ * This marks the STX/MMX registers as empty in the FPU tag
+ * word, but does not actually clear the values in the
+ * registers, so we manually clear them in the xsave area after
+ * saving.
*/
asm volatile ("fninit");
@@ -159,7 +169,8 @@
asm volatile("fxsave64 %0" : : "m"(x86_default_fpu));
/*
- * Clear junk that might have been saved from the STX/MMX registers.
+ * Clear junk that might have been saved from the STX/MMX
+ * registers.
*
* FXSAVE may have also saved junk from the XMM registers,
* depending on how the hardware was implemented and the setting
diff --git a/kern/arch/x86/intel.c b/kern/arch/x86/intel.c
index da6d120..6960e6a 100644
--- a/kern/arch/x86/intel.c
+++ b/kern/arch/x86/intel.c
@@ -30,7 +30,8 @@
pmbase &= ~1; /* clear bit 0 */
uint32_t smi_ctl = inl(pmbase + 0x30);
#if 0
- /* halt the tco timer: this busts things, and won't work with the lock on */
+ /* halt the tco timer: this busts things, and won't work with the lock
+ * on */
uint16_t tco1 = inw(pmbase + 0x60 + 0x08);
if (tco1 & (1 << 12)) {
printk("\t\tTCO_LOCK is on!\n");
@@ -44,9 +45,10 @@
smi_ctl = inl(pmbase + 0x30);
}
-void intel_lpc_init()
+void intel_lpc_init(void)
{
struct pci_device *i;
+
STAILQ_FOREACH(i, &pci_devices, all_dev) {
if ((i->dev == 0x1f) && (i->func == 0x00))
lpc_init_pci(i);
diff --git a/kern/arch/x86/io.h b/kern/arch/x86/io.h
index b077731..43a1591 100644
--- a/kern/arch/x86/io.h
+++ b/kern/arch/x86/io.h
@@ -53,8 +53,8 @@
/*
* PCI support code.
*/
-enum { /* type 0 and type 1 pre-defined header */
- PciVID = 0x00, /* vendor ID */
+enum { /* type 0 and type 1 pre-defined header */
+ PciVID = 0x00, /* vendor ID */
PciDID = 0x02, /* device ID */
PciPCR = 0x04, /* command */
PciPSR = 0x06, /* status */
@@ -78,16 +78,16 @@
/* ccrb (base class code) values; controller types */
enum {
- Pcibcpci1 = 0, /* pci 1.0; no class codes defined */
- Pcibcstore = 1, /* mass storage */
- Pcibcnet = 2, /* network */
- Pcibcdisp = 3, /* display */
+ Pcibcpci1 = 0, /* pci 1.0; no class codes defined */
+ Pcibcstore = 1, /* mass storage */
+ Pcibcnet = 2, /* network */
+ Pcibcdisp = 3, /* display */
Pcibcmmedia = 4, /* multimedia */
- Pcibcmem = 5, /* memory */
+ Pcibcmem = 5, /* memory */
Pcibcbridge = 6, /* bridge */
- Pcibccomm = 7, /* simple comms (e.g., serial) */
+ Pcibccomm = 7, /* simple comms (e.g., serial) */
Pcibcbasesys = 8, /* base system */
- Pcibcinput = 9, /* input */
+ Pcibcinput = 9, /* input */
Pcibcdock = 0xa, /* docking stations */
Pcibcproc = 0xb, /* processors */
Pcibcserial = 0xc, /* serial bus (e.g., USB) */
@@ -101,17 +101,17 @@
/* ccru (sub-class code) values; common cases only */
enum {
/* mass storage */
- Pciscscsi = 0, /* SCSI */
- Pciscide = 1, /* IDE (ATA) */
- Pciscsata = 6, /* SATA */
+ Pciscscsi = 0, /* SCSI */
+ Pciscide = 1, /* IDE (ATA) */
+ Pciscsata = 6, /* SATA */
/* network */
- Pciscether = 0, /* Ethernet */
+ Pciscether = 0, /* Ethernet */
/* display */
- Pciscvga = 0, /* VGA */
- Pciscxga = 1, /* XGA */
- Pcisc3d = 2, /* 3D */
+ Pciscvga = 0, /* VGA */
+ Pciscxga = 1, /* XGA */
+ Pcisc3d = 2, /* 3D */
/* bridges */
Pcischostpci = 0, /* host/pci */
@@ -125,17 +125,17 @@
Pciscusb = 3, /* USB */
};
-enum { /* type 0 pre-defined header */
- PciCIS = 0x28, /* cardbus CIS pointer */
+enum { /* type 0 pre-defined header */
+ PciCIS = 0x28, /* cardbus CIS pointer */
PciSVID = 0x2C, /* subsystem vendor ID */
PciSID = 0x2E, /* cardbus CIS pointer */
- PciEBAR0 = 0x30, /* expansion ROM base address */
+ PciEBAR0 = 0x30,/* expansion ROM base address */
PciMGNT = 0x3E, /* burst period length */
PciMLT = 0x3F, /* maximum latency between bursts */
};
-enum { /* type 1 pre-defined header */
- PciPBN = 0x18, /* primary bus number */
+enum { /* type 1 pre-defined header */
+ PciPBN = 0x18, /* primary bus number */
PciSBN = 0x19, /* secondary bus number */
PciUBN = 0x1A, /* subordinate bus number */
PciSLTR = 0x1B, /* secondary latency timer */
@@ -150,11 +150,11 @@
PciPULR = 0x2C, /* prefetchable limit upper 32 bits */
PciIUBR = 0x30, /* I/O base upper 16 bits */
PciIULR = 0x32, /* I/O limit upper 16 bits */
- PciEBAR1 = 0x28, /* expansion ROM base address */
+ PciEBAR1 = 0x28,/* expansion ROM base address */
PciBCR = 0x3E, /* bridge control register */
};
-enum { /* type 2 pre-defined header */
+enum { /* type 2 pre-defined header */
PciCBExCA = 0x10,
PciCBSPSR = 0x16,
PciCBPBN = 0x18, /* primary bus number */
@@ -176,7 +176,7 @@
/* capabilities */
enum {
- PciCapPMG = 0x01, /* power management */
+ PciCapPMG = 0x01, /* power management */
PciCapAGP = 0x02,
PciCapVPD = 0x03, /* vital product data */
PciCapSID = 0x04, /* slot id */
diff --git a/kern/arch/x86/ioapic.c b/kern/arch/x86/ioapic.c
index c4d760c..68f83e8 100644
--- a/kern/arch/x86/ioapic.c
+++ b/kern/arch/x86/ioapic.c
@@ -33,23 +33,23 @@
struct Rdt {
struct apic *apic;
int intin;
- uint32_t lo; /* matches the lo in the intin, incl Im */
- uint32_t hi; /* matches the hi in the intin, incl routing */
+ uint32_t lo; /* matches the lo in the intin, incl Im */
+ uint32_t hi; /* matches the hi in the intin, incl routing */
- int ref; /* could map to multiple busses */
- int enabled; /* times enabled */
+ int ref; /* could map to multiple busses */
+ int enabled; /* times enabled */
};
-enum { /* IOAPIC registers */
- Ioregsel = 0x00, /* indirect register address */
- Iowin = 0x10, /* indirect register data */
- Ioipa = 0x08, /* IRQ Pin Assertion */
- Ioeoi = 0x10, /* EOI */
+enum { /* IOAPIC registers */
+ Ioregsel = 0x00, /* indirect register address */
+ Iowin = 0x10, /* indirect register data */
+ Ioipa = 0x08, /* IRQ Pin Assertion */
+ Ioeoi = 0x10, /* EOI */
Ioapicid = 0x00, /* Identification */
Ioapicver = 0x01, /* Version */
Ioapicarb = 0x02, /* Arbitration */
- Ioabcfg = 0x03, /* Boot Coniguration */
+ Ioabcfg = 0x03, /* Boot Coniguration */
Ioredtbl = 0x10, /* Redirection Table */
};
@@ -109,6 +109,7 @@
struct Rdt *rbus_get_rdt(int busno, int devno)
{
struct Rbus *rbus;
+
for (rbus = rdtbus[busno]; rbus != NULL; rbus = rbus->next) {
if (rbus->devno == devno)
return rbus->rdt;
@@ -150,10 +151,11 @@
rdt->lo = lo;
rdt->hi = 0;
} else {
- /* Polarity/trigger check. Stored lo also has the vector in 0xff */
+ /* Polarity/trigger check. Stored lo also has the vector in
+ * 0xff */
if (lo != (rdt->lo & ~0xff)) {
- printk("multiple irq botch bus %d %d/%d/%d lo %d vs %d\n",
- busno, ioapicno, intin, devno, lo, rdt->lo);
+ printk("multi-irq botch bus %d %d/%d/%d lo %d vs %d\n",
+ busno, ioapicno, intin, devno, lo, rdt->lo);
return;
}
}
@@ -180,11 +182,13 @@
struct apic *ioapic;
/* with acpi, the ioapics map a global interrupt space. each covers a
* window of the space from [ibase, ibase + nrdt). */
- for (ioapic = xioapic; ioapic < &xioapic[Napic]; ioapic++, ioapic_idx++) {
+ for (ioapic = xioapic; ioapic < &xioapic[Napic]; ioapic++, ioapic_idx++)
+ {
/* addr check is just for sanity */
if (!ioapic->useable || !ioapic->addr)
continue;
- if ((ioapic->ibase <= irq) && (irq < ioapic->ibase + ioapic->nrdt))
+ if ((ioapic->ibase <= irq) &&
+ (irq < ioapic->ibase + ioapic->nrdt))
return ioapic_idx;
}
return -1;
@@ -198,20 +202,20 @@
*
* From Brendan http://f.osdev.org/viewtopic.php?f=1&t=25951:
*
- * Before parsing the MADT you should begin by assuming that redirection
- * entries 0 to 15 are used for ISA IRQs 0 to 15. The MADT's "Interrupt
- * Source Override Structures" will tell you when this initial/default
- * assumption is wrong. For example, the MADT might tell you that ISA IRQ 9
- * is connected to IO APIC 44 and is level triggered; and (in this case)
- * it'd be silly to assume that ISA IRQ 9 is also connected to IO APIC
- * input 9 just because IO APIC input 9 is not listed.
+ * Before parsing the MADT you should begin by assuming that redirection
+ * entries 0 to 15 are used for ISA IRQs 0 to 15. The MADT's "Interrupt
+ * Source Override Structures" will tell you when this initial/default
+ * assumption is wrong. For example, the MADT might tell you that ISA IRQ 9
+ * is connected to IO APIC 44 and is level triggered; and (in this case)
+ * it'd be silly to assume that ISA IRQ 9 is also connected to IO APIC
+ * input 9 just because IO APIC input 9 is not listed.
*
- * For PCI IRQs, the MADT tells you nothing and you can't assume anything
- * at all. Sadly, you have to interpret the ACPI AML to determine how PCI
- * IRQs are connected to IO APIC inputs (or find some other work-around;
- * like implementing a motherboard driver for each different motherboard,
- * or some complex auto-detection scheme, or just configure PCI devices to
- * use MSI instead). */
+ * For PCI IRQs, the MADT tells you nothing and you can't assume anything
+ * at all. Sadly, you have to interpret the ACPI AML to determine how PCI
+ * IRQs are connected to IO APIC inputs (or find some other work-around;
+ * like implementing a motherboard driver for each different motherboard,
+ * or some complex auto-detection scheme, or just configure PCI devices to
+ * use MSI instead). */
static int acpi_make_rdt(int tbdf, int irq, int busno, int devno)
{
struct Atable *at;
@@ -249,13 +253,15 @@
gsi_irq = irq;
} else {
/* Need to query ACPI at some point to handle this */
- printk("Non-ISA IRQ %d not found in MADT, aborting\n", irq);
+ printk("Non-ISA IRQ %d not found in MADT, aborting\n",
+ irq);
return -1;
}
}
ioapic_nr = acpi_irq2ioapic(gsi_irq);
if (ioapic_nr < 0) {
- printk("Could not find an IOAPIC for global irq %d!\n", gsi_irq);
+ printk("Could not find an IOAPIC for global irq %d!\n",
+ gsi_irq);
return -1;
}
ioapicintrinit(busno, ioapic_nr, gsi_irq - xioapic[ioapic_nr].ibase,
@@ -268,7 +274,8 @@
struct apic *apic;
static int base;
- assert((IOAPIC_PBASE <= pa) && (pa + PGSIZE <= IOAPIC_PBASE + APIC_SIZE));
+ assert((IOAPIC_PBASE <= pa) &&
+ (pa + PGSIZE <= IOAPIC_PBASE + APIC_SIZE));
/*
* Mark the IOAPIC useable if it has a good ID
* and the registers can be mapped.
@@ -291,8 +298,8 @@
spin_lock(&apic->lock);
write_mmreg32(apic->addr + Ioregsel, Ioapicver);
apic->nrdt = ((read_mmreg32(apic->addr + Iowin) >> 16) & 0xff) + 1;
- /* the ibase is the global system interrupt base, told to us by ACPI. if
- * it's -1, we're called from mpparse, and just guess/make up our own
+ /* the ibase is the global system interrupt base, told to us by ACPI.
+ * if it's -1, we're called from mpparse, and just guess/make up our own
* assignments. */
if (ibase != -1)
apic->ibase = ibase;
@@ -320,13 +327,15 @@
apic = &xioapic[i];
if (!apic->useable || apic->addr == 0)
continue;
- start = seprintf(start, end, "ioapic %d addr %p nrdt %d ibase %d\n",
- i, apic->addr, apic->nrdt, apic->ibase);
+ start = seprintf(start, end,
+ "ioapic %d addr %p nrdt %d ibase %d\n",
+ i, apic->addr, apic->nrdt, apic->ibase);
for (n = 0; n < apic->nrdt; n++) {
spin_lock(&apic->lock);
rtblget(apic, n, &hi, &lo);
spin_unlock(&apic->lock);
- start = seprintf(start, end, " rdt %2.2d %p %p\n", n, hi, lo);
+ start = seprintf(start, end, " rdt %2.2d %p %p\n",
+ n, hi, lo);
}
}
for (i = 0; i < Nbus; i++) {
@@ -336,9 +345,10 @@
for (; rbus != NULL; rbus = rbus->next) {
rdt = rbus->rdt;
start = seprintf(start, end,
- " apic %ld devno %p(%d %d) intin %d hi %p lo %p\n",
- rdt->apic - xioapic, rbus->devno, rbus->devno >> 2,
- rbus->devno & 0x03, rdt->intin, rdt->hi, rdt->lo);
+ " apic %ld devno %p(%d %d) intin %d hi %p lo %p\n",
+ rdt->apic - xioapic, rbus->devno,
+ rbus->devno >> 2, rbus->devno & 0x03,
+ rdt->intin, rdt->hi, rdt->lo);
}
}
return start;
@@ -449,12 +459,14 @@
static struct Rdt *ioapic_vector2rdt(int apic_vector)
{
struct Rdt *rdt;
+
if (apic_vector < IdtIOAPIC || apic_vector > MaxIdtIOAPIC) {
warn("ioapic vector %d out of range", apic_vector);
return 0;
}
- /* Fortunately rdtvecno[vecno] is static once assigned. o/w, we'll need some
- * global sync for the callers, both for lookup and keeping rdt valid. */
+ /* Fortunately rdtvecno[vecno] is static once assigned. o/w, we'll need
+ * some global sync for the callers, both for lookup and keeping rdt
+ * valid. */
rdt = rdtvecno[apic_vector];
if (!rdt) {
warn("vector %d has no RDT! (did you enable it?)", apic_vector);
@@ -470,6 +482,7 @@
int hw_coreid)
{
struct Rdt *rdt = ioapic_vector2rdt(apic_vector);
+
if (!rdt) {
printk("Missing IOAPIC route for vector!\n", apic_vector);
return;
@@ -491,6 +504,7 @@
{
/* could store the rdt in the irq_h */
struct Rdt *rdt = ioapic_vector2rdt(apic_vector);
+
if (!rdt)
return;
spin_lock(&rdt->apic->lock);
@@ -555,72 +569,74 @@
}
}
switch (BUSTYPE(irq_h->tbdf)) {
- case BusLAPIC:
- /* nxm used to set the initial 'isr' method (i think equiv to our
- * check_spurious) to apiceoi for non-spurious lapic vectors. in
- * effect, i think they were sending the EOI early, and their eoi
- * method was 0. we're not doing that (unless we have to). */
- irq_h->check_spurious = lapic_check_spurious;
- irq_h->eoi = lapic_send_eoi;
- irq_h->mask = lapic_mask_irq;
- irq_h->unmask = lapic_unmask_irq;
- irq_h->route_irq = 0;
- irq_h->type = "lapic";
- /* For the LAPIC, irq == vector */
- return irq_h->dev_irq;
- case BusIPI:
- /* similar to LAPIC, but we don't actually have LVT entries */
- irq_h->check_spurious = lapic_check_spurious;
- irq_h->eoi = lapic_send_eoi;
- irq_h->mask = 0;
- irq_h->unmask = 0;
- irq_h->route_irq = 0;
- irq_h->type = "IPI";
- return irq_h->dev_irq;
- case BusISA:
- if (mpisabusno == -1)
- panic("No ISA bus allocated");
- busno = mpisabusno;
- /* need to track the irq in devno in PCI interrupt assignment entry
- * format (see mp.c or MP spec D.3). */
- devno = irq_h->dev_irq << 2;
- break;
- case BusPCI:
- pcidev = pci_match_tbdf(irq_h->tbdf);
- if (!pcidev) {
- warn("No PCI dev for tbdf %p!", irq_h->tbdf);
- return -1;
- }
- if ((vecno = msi_irq_enable(irq_h, pcidev)) != -1)
- return vecno;
- busno = BUSBNO(irq_h->tbdf);
- assert(busno == pcidev->bus);
- devno = pcidev_read8(pcidev, PciINTP);
+ case BusLAPIC:
+ /* nxm used to set the initial 'isr' method (i think equiv to
+ * our check_spurious) to apiceoi for non-spurious lapic
+ * vectors. in effect, i think they were sending the EOI early,
+ * and their eoi method was 0. we're not doing that (unless we
+ * have to). */
+ irq_h->check_spurious = lapic_check_spurious;
+ irq_h->eoi = lapic_send_eoi;
+ irq_h->mask = lapic_mask_irq;
+ irq_h->unmask = lapic_unmask_irq;
+ irq_h->route_irq = 0;
+ irq_h->type = "lapic";
+ /* For the LAPIC, irq == vector */
+ return irq_h->dev_irq;
+ case BusIPI:
+ /* similar to LAPIC, but we don't actually have LVT entries */
+ irq_h->check_spurious = lapic_check_spurious;
+ irq_h->eoi = lapic_send_eoi;
+ irq_h->mask = 0;
+ irq_h->unmask = 0;
+ irq_h->route_irq = 0;
+ irq_h->type = "IPI";
+ return irq_h->dev_irq;
+ case BusISA:
+ if (mpisabusno == -1)
+ panic("No ISA bus allocated");
+ busno = mpisabusno;
+ /* need to track the irq in devno in PCI interrupt assignment
+ * entry format (see mp.c or MP spec D.3). */
+ devno = irq_h->dev_irq << 2;
+ break;
+ case BusPCI:
+ pcidev = pci_match_tbdf(irq_h->tbdf);
+ if (!pcidev) {
+ warn("No PCI dev for tbdf %p!", irq_h->tbdf);
+ return -1;
+ }
+ if ((vecno = msi_irq_enable(irq_h, pcidev)) != -1)
+ return vecno;
+ busno = BUSBNO(irq_h->tbdf);
+ assert(busno == pcidev->bus);
+ devno = pcidev_read8(pcidev, PciINTP);
- /* this might not be a big deal - some PCI devices have no INTP. if
- * so, change our devno - 1 below. */
- if (devno == 0)
- panic("no INTP for tbdf %p", irq_h->tbdf);
- /* remember, devno is the device shifted with irq pin in bits 0-1.
- * we subtract 1, since the PCI intp maps 1 -> INTA, 2 -> INTB, etc,
- * and the MP spec uses 0 -> INTA, 1 -> INTB, etc. */
- devno = BUSDNO(irq_h->tbdf) << 2 | (devno - 1);
- break;
- default:
- panic("Unknown bus type, TBDF %p", irq_h->tbdf);
+ /* this might not be a big deal - some PCI devices have no INTP.
+ * if so, change our devno - 1 below. */
+ if (devno == 0)
+ panic("no INTP for tbdf %p", irq_h->tbdf);
+ /* remember, devno is the device shifted with irq pin in bits
+ * 0-1. we subtract 1, since the PCI intp maps 1 -> INTA, 2 ->
+ * INTB, etc, and the MP spec uses 0 -> INTA, 1 -> INTB, etc. */
+ devno = BUSDNO(irq_h->tbdf) << 2 | (devno - 1);
+ break;
+ default:
+ panic("Unknown bus type, TBDF %p", irq_h->tbdf);
}
- /* busno and devno are set, regardless of the bustype, enough to find rdt.
- * these may differ from the values in tbdf. */
+ /* busno and devno are set, regardless of the bustype, enough to find
+ * rdt. these may differ from the values in tbdf. */
rdt = rbus_get_rdt(busno, devno);
if (!rdt) {
- /* second chance. if we didn't find the item the first time, then (if
- * it exists at all), it wasn't in the MP tables (or we had no tables).
- * So maybe we can figure it out via ACPI. */
+ /* second chance. if we didn't find the item the first time,
+ * then (if it exists at all), it wasn't in the MP tables (or we
+ * had no tables). So maybe we can figure it out via ACPI. */
acpi_make_rdt(irq_h->tbdf, irq_h->dev_irq, busno, devno);
rdt = rbus_get_rdt(busno, devno);
}
if (!rdt) {
- printk("Unable to build IOAPIC route for irq %d\n", irq_h->dev_irq);
+ printk("Unable to build IOAPIC route for irq %d\n",
+ irq_h->dev_irq);
return -1;
}
/*
@@ -636,15 +652,16 @@
* rather than putting a Lock in each entry.
*/
spin_lock(&rdt->apic->lock);
- /* if a destination has already been picked, we store it in the lo. this
- * stays around regardless of enabled/disabled, since we don't reap vectors
- * yet. nor do we really mess with enabled... */
+ /* if a destination has already been picked, we store it in the lo.
+ * this stays around regardless of enabled/disabled, since we don't reap
+ * vectors yet. nor do we really mess with enabled... */
if ((rdt->lo & 0xff) == 0) {
vecno = nextvec();
rdt->lo |= vecno;
rdtvecno[vecno] = rdt;
} else {
- printd("%p: mutiple irq bus %d dev %d\n", irq_h->tbdf, busno, devno);
+ printd("%p: mutiple irq bus %d dev %d\n", irq_h->tbdf, busno,
+ devno);
}
rdt->enabled++;
rdt->hi = 0; /* route to 0 by default */
diff --git a/kern/arch/x86/ioapic.h b/kern/arch/x86/ioapic.h
index a04ed91..ab439ed 100644
--- a/kern/arch/x86/ioapic.h
+++ b/kern/arch/x86/ioapic.h
@@ -44,13 +44,13 @@
ApicLOGICAL = 0x00000800,
ApicDELIVS = 0x00001000, /* [12] Delivery Status (RO) */
- ApicHIGH = 0x00000000, /* [13] Interrupt Input Pin Polarity (RW) */
+ ApicHIGH = 0x00000000, /* [13] IRQ Input Pin Polarity (RW) */
ApicLOW = 0x00002000,
ApicRemoteIRR = 0x00004000, /* [14] Remote IRR (RO) */
ApicEDGE = 0x00000000, /* [15] Trigger Mode (RW) */
ApicLEVEL = 0x00008000,
ApicIMASK = 0x00010000, /* [16] Interrupt Mask */
- IOAPIC_PBASE = 0xfec00000, /* default *physical* address */
+ IOAPIC_PBASE = 0xfec00000, /* default *physical* address */
};
extern int mpisabusno;
diff --git a/kern/arch/x86/kclock.c b/kern/arch/x86/kclock.c
index d31becb..7f5d1ad 100644
--- a/kern/arch/x86/kclock.c
+++ b/kern/arch/x86/kclock.c
@@ -6,23 +6,23 @@
#include <arch/x86.h>
#include <atomic.h>
-#define CMOS_RTC_SELECT 0x70
-#define CMOS_RTC_DATA 0x71
+#define CMOS_RTC_SELECT 0x70
+#define CMOS_RTC_DATA 0x71
#define RTC_A_UPDATE_IN_PROGRESS (1 << 7)
-#define RTC_B_24HOUR_MODE (1 << 1)
-#define RTC_B_BINARY_MODE (1 << 2)
-#define RTC_12_HOUR_PM (1 << 7)
-#define CMOS_RTC_SECOND 0x00
-#define CMOS_RTC_MINUTE 0x02
-#define CMOS_RTC_HOUR 0x04
-#define CMOS_RTC_WEEKDAY 0x06
-#define CMOS_RTC_DAY 0x07
-#define CMOS_RTC_MONTH 0x08
-#define CMOS_RTC_YEAR 0x09
-#define CMOS_RTC_CENTURY 0x32
-#define CMOS_RTC_STATUS_A 0x0A
-#define CMOS_RTC_STATUS_B 0x0B
+#define RTC_B_24HOUR_MODE (1 << 1)
+#define RTC_B_BINARY_MODE (1 << 2)
+#define RTC_12_HOUR_PM (1 << 7)
+#define CMOS_RTC_SECOND 0x00
+#define CMOS_RTC_MINUTE 0x02
+#define CMOS_RTC_HOUR 0x04
+#define CMOS_RTC_WEEKDAY 0x06
+#define CMOS_RTC_DAY 0x07
+#define CMOS_RTC_MONTH 0x08
+#define CMOS_RTC_YEAR 0x09
+#define CMOS_RTC_CENTURY 0x32
+#define CMOS_RTC_STATUS_A 0x0A
+#define CMOS_RTC_STATUS_B 0x0B
/* If we ever disable NMIs, we'll need to make sure we don't reenable them here.
* (Top bit of the CMOS_RTC_SELECT selector). */
diff --git a/kern/arch/x86/kdebug.c b/kern/arch/x86/kdebug.c
index 64187e6..2484e3a 100644
--- a/kern/arch/x86/kdebug.c
+++ b/kern/arch/x86/kdebug.c
@@ -51,15 +51,16 @@
if (!fp)
break;
assert(KERNBASE <= fp);
- /* We need to check the next FP before reading PC from beyond it. FP
- * could be 0 and be at the top of the stack, and reading PC in that
- * case will be a wild read. */
+ /* We need to check the next FP before reading PC from beyond
+ * it. FP could be 0 and be at the top of the stack, and
+ * reading PC in that case will be a wild read. */
if (!*(uintptr_t*)fp)
break;
- /* We used to set PC = retaddr - 1, where the -1 would put our PC back
- * inside the function that called us. This was for obscure cases where
- * a no-return function calls another function and has no other code
- * after the function call. Or something. */
+ /* We used to set PC = retaddr - 1, where the -1 would put our
+ * PC back inside the function that called us. This was for
+ * obscure cases where a no-return function calls another
+ * function and has no other code after the function call. Or
+ * something. */
pc = *(uintptr_t*)(fp + sizeof(uintptr_t));
fp = *(uintptr_t*)fp;
}
@@ -77,7 +78,8 @@
pcs[nr_pcs++] = pc;
if (!fp)
break;
- error = copy_from_user(frame, (const void *) fp, 2 * sizeof(uintptr_t));
+ error = copy_from_user(frame, (const void *) fp, 2 *
+ sizeof(uintptr_t));
if (unlikely(error))
break;
pc = frame[1];
diff --git a/kern/arch/x86/kdebug.h b/kern/arch/x86/kdebug.h
index 370fefb..608e8c3 100644
--- a/kern/arch/x86/kdebug.h
+++ b/kern/arch/x86/kdebug.h
@@ -14,11 +14,12 @@
static inline uintptr_t get_caller_pc(void)
{
unsigned long *ebp = (unsigned long*)read_bp();
+
if (!ebp)
return 0;
/* this is part of the way back into the call() instruction's bytes
- * eagle-eyed readers should be able to explain why this is good enough, and
- * retaddr (just *(ebp + 1) is not) */
+ * eagle-eyed readers should be able to explain why this is good enough,
+ * and retaddr (just *(ebp + 1) is not) */
return *(ebp + 1) - 1;
}
diff --git a/kern/arch/x86/kpt.h b/kern/arch/x86/kpt.h
index 7821496..ecc0f43 100644
--- a/kern/arch/x86/kpt.h
+++ b/kern/arch/x86/kpt.h
@@ -57,7 +57,8 @@
static inline void kpte_write(kpte_t *kpte, physaddr_t pa, int settings)
{
assert(!PGOFF(pa));
- /* The arch-bits like PTE_D, PTE_PS, etc are all in the native KPT format */
+ /* The arch-bits like PTE_D, PTE_PS, etc are all in the native KPT
+ * format */
*kpte = build_kpte(pa, settings);
}
diff --git a/kern/arch/x86/mp.c b/kern/arch/x86/mp.c
index 8de0d50..2bb8b49 100644
--- a/kern/arch/x86/mp.c
+++ b/kern/arch/x86/mp.c
@@ -23,7 +23,7 @@
* MultiProcessor Specification Version 1.[14].
*/
typedef struct { /* MP Floating Pointer */
- uint8_t signature[4]; /* "_MP_" */
+ uint8_t signature[4]; /* "_MP_" */
uint8_t addr[4]; /* PCMP */
uint8_t length; /* 1 */
uint8_t revision; /* [14] */
@@ -32,7 +32,7 @@
} _MP_;
typedef struct { /* MP Configuration Table */
- uint8_t signature[4]; /* "PCMP" */
+ uint8_t signature[4]; /* "PCMP" */
uint8_t length[2];
uint8_t revision; /* [14] */
uint8_t checksum;
@@ -108,35 +108,36 @@
return 0;
}
switch (p[0]) {
- default:
- mpintrprint("INTIN botch", p);
+ default:
+ mpintrprint("INTIN botch", p);
+ return 0;
+ case 3: /* IOINTR */
+ apic = &xioapic[p[6]];
+ if (!apic->useable) {
+ mpintrprint("unuseable ioapic", p);
return 0;
- case 3: /* IOINTR */
- apic = &xioapic[p[6]];
- if (!apic->useable) {
- mpintrprint("unuseable ioapic", p);
- return 0;
- }
- if (p[7] >= apic->nrdt) {
- mpintrprint("IO INTIN out of range", p);
- return 0;
- }
- break;
- case 4: /* LINTR */
- apic = &xlapic[p[6]];
- if (!apic->useable) {
- mpintrprint("unuseable lapic", p);
- return 0;
- }
- if (p[7] >= ARRAY_SIZE(apic->lvt)) {
- mpintrprint("LOCAL INTIN out of range", p);
- return 0;
- }
- break;
+ }
+ if (p[7] >= apic->nrdt) {
+ mpintrprint("IO INTIN out of range", p);
+ return 0;
+ }
+ break;
+ case 4: /* LINTR */
+ apic = &xlapic[p[6]];
+ if (!apic->useable) {
+ mpintrprint("unuseable lapic", p);
+ return 0;
+ }
+ if (p[7] >= ARRAY_SIZE(apic->lvt)) {
+ mpintrprint("LOCAL INTIN out of range", p);
+ return 0;
+ }
+ break;
}
}
n = l16get(p + 2);
- if ((polarity = (n & 0x03)) == 2 || (trigger = ((n >> 2) & 0x03)) == 2) {
+ if ((polarity = (n & 0x03)) == 2 || (trigger = ((n >> 2) & 0x03)) == 2)
+ {
mpintrprint("invalid polarity/trigger", p);
return 0;
}
@@ -151,42 +152,42 @@
*/
v = Im;
switch (p[1]) {
- default:
- mpintrprint("invalid type", p);
- return 0;
- case 0: /* INT */
- switch (polarity) {
- case 0:
- v |= mpbus[p[4]]->polarity;
- break;
- case 1:
- v |= IPhigh;
- break;
- case 3:
- v |= IPlow;
- break;
- }
- switch (trigger) {
- case 0:
- v |= mpbus[p[4]]->trigger;
- break;
- case 1:
- v |= TMedge;
- break;
- case 3:
- v |= TMlevel;
- break;
- }
+ default:
+ mpintrprint("invalid type", p);
+ return 0;
+ case 0: /* INT */
+ switch (polarity) {
+ case 0:
+ v |= mpbus[p[4]]->polarity;
break;
- case 1: /* NMI */
- v |= TMedge | IPhigh | MTnmi;
+ case 1:
+ v |= IPhigh;
break;
- case 2: /* SMI */
- v |= TMedge | IPhigh | MTsmi;
+ case 3:
+ v |= IPlow;
break;
- case 3: /* ExtINT */
- v |= TMedge | IPhigh | MTei;
+ }
+ switch (trigger) {
+ case 0:
+ v |= mpbus[p[4]]->trigger;
break;
+ case 1:
+ v |= TMedge;
+ break;
+ case 3:
+ v |= TMlevel;
+ break;
+ }
+ break;
+ case 1: /* NMI */
+ v |= TMedge | IPhigh | MTnmi;
+ break;
+ case 2: /* SMI */
+ v |= TMedge | IPhigh | MTsmi;
+ break;
+ case 3: /* ExtINT */
+ v |= TMedge | IPhigh | MTei;
+ break;
}
return v;
@@ -202,138 +203,145 @@
e = ((uint8_t *) pcmp) + l16get(pcmp->length);
while (p < e)
switch (*p) {
- default:
- printd("mpparse: unknown PCMP type %d (e-p %#ld)\n", *p, e - p);
- for (i = 0; p < e; i++) {
- if (i && ((i & 0x0f) == 0))
- printd("\n");
- printd(" 0x%#2.2x", *p);
- p++;
- }
- printd("\n");
+ default:
+ printd("mpparse: unknown PCMP type %d (e-p %#ld)\n", *p,
+ e - p);
+ for (i = 0; p < e; i++) {
+ if (i && ((i & 0x0f) == 0))
+ printd("\n");
+ printd(" 0x%#2.2x", *p);
+ p++;
+ }
+ printd("\n");
+ break;
+ case 0: /* processor */
+ /*
+ * Initialise the APIC if it is enabled (p[3] & 0x01).
+ * p[1] is the APIC ID, the memory mapped address comes
+ * from the PCMP structure as the addess is local to the
+ * CPU and identical for all. Indicate whether this is
+ * the bootstrap processor (p[3] & 0x02).
+ */
+ printd("mpparse: cpu %d pa %p bp %d\n",
+ p[1], l32get(pcmp->apicpa), p[3] & 0x02);
+ if ((p[3] & 0x01) != 0 && maxcores > 0) {
+ maxcores--;
+ apicinit(p[1], l32get(pcmp->apicpa), p[3] &
+ 0x02);
+ }
+ p += 20;
+ break;
+ case 1: /* bus */
+ printd("mpparse: bus: %d type %6.6s\n", p[1], (char *)p
+ + 2);
+ if (p[1] >= Nbus) {
+ printk("mpparse: bus %d out of range\n", p[1]);
+ p += 8;
break;
- case 0: /* processor */
- /*
- * Initialise the APIC if it is enabled (p[3] & 0x01).
- * p[1] is the APIC ID, the memory mapped address comes
- * from the PCMP structure as the addess is local to the
- * CPU and identical for all. Indicate whether this is
- * the bootstrap processor (p[3] & 0x02).
- */
- printd("mpparse: cpu %d pa %p bp %d\n",
- p[1], l32get(pcmp->apicpa), p[3] & 0x02);
- if ((p[3] & 0x01) != 0 && maxcores > 0) {
- maxcores--;
- apicinit(p[1], l32get(pcmp->apicpa), p[3] & 0x02);
- }
- p += 20;
+ }
+ if (mpbus[p[1]] != NULL) {
+ printk("mpparse: bus %d already allocated\n",
+ p[1]);
+ p += 8;
break;
- case 1: /* bus */
- printd("mpparse: bus: %d type %6.6s\n", p[1], (char *)p + 2);
- if (p[1] >= Nbus) {
- printk("mpparse: bus %d out of range\n", p[1]);
- p += 8;
- break;
- }
- if (mpbus[p[1]] != NULL) {
- printk("mpparse: bus %d already allocated\n", p[1]);
- p += 8;
- break;
- }
- for (i = 0; i < ARRAY_SIZE(mpbusdef); i++) {
- if (memcmp(p + 2, mpbusdef[i].type, 6) != 0)
+ }
+ for (i = 0; i < ARRAY_SIZE(mpbusdef); i++) {
+ if (memcmp(p + 2, mpbusdef[i].type, 6) != 0)
+ continue;
+ if (memcmp(p + 2, "ISA ", 6) == 0) {
+ if (mpisabusno != -1) {
+ printk("mpparse: bus %d already have ISA bus %d\n",
+ p[1], mpisabusno);
continue;
- if (memcmp(p + 2, "ISA ", 6) == 0) {
- if (mpisabusno != -1) {
- printk("mpparse: bus %d already have ISA bus %d\n",
- p[1], mpisabusno);
- continue;
- }
- mpisabusno = p[1];
}
- mpbus[p[1]] = &mpbusdef[i];
- break;
+ mpisabusno = p[1];
}
- if (mpbus[p[1]] == NULL)
- printk("mpparse: bus %d type %6.6s unknown\n",
- p[1], (char *)p + 2);
+ mpbus[p[1]] = &mpbusdef[i];
+ break;
+ }
+ if (mpbus[p[1]] == NULL)
+ printk("mpparse: bus %d type %6.6s unknown\n",
+ p[1], (char *)p + 2);
+ p += 8;
+ break;
+ case 2: /* IOAPIC */
+ /*
+ * Initialise the IOAPIC if it is enabled (p[3] & 0x01).
+ * p[1] is the APIC ID, p[4-7] is the memory mapped
+ * address.
+ */
+ if (p[3] & 0x01)
+ ioapicinit(p[1], -1, l32get(p + 4));
+
+ p += 8;
+ break;
+ case 3: /* IOINTR */
+ /*
+ * p[1] is the interrupt type;
+ * p[2-3] contains the polarity and trigger mode;
+ * p[4] is the source bus;
+ * p[5] is the IRQ on the source bus;
+ * p[6] is the destination IOAPIC;
+ * p[7] is the INITIN pin on the destination IOAPIC.
+ */
+ if (p[6] == 0xff) {
+ mpintrprint("routed to all IOAPICs", p);
p += 8;
break;
- case 2: /* IOAPIC */
- /*
- * Initialise the IOAPIC if it is enabled (p[3] & 0x01).
- * p[1] is the APIC ID, p[4-7] is the memory mapped address.
- */
- if (p[3] & 0x01)
- ioapicinit(p[1], -1, l32get(p + 4));
-
- p += 8;
- break;
- case 3: /* IOINTR */
- /*
- * p[1] is the interrupt type;
- * p[2-3] contains the polarity and trigger mode;
- * p[4] is the source bus;
- * p[5] is the IRQ on the source bus;
- * p[6] is the destination IOAPIC;
- * p[7] is the INITIN pin on the destination IOAPIC.
- */
- if (p[6] == 0xff) {
- mpintrprint("routed to all IOAPICs", p);
- p += 8;
- break;
- }
- if ((lo = mpmkintr(p)) == 0) {
- if (MP_VERBOSE_DEBUG)
- mpintrprint("iointr skipped", p);
- p += 8;
- break;
- }
+ }
+ if ((lo = mpmkintr(p)) == 0) {
if (MP_VERBOSE_DEBUG)
- mpintrprint("iointr", p);
-
- /*
- * Always present the device number in the style
- * of a PCI Interrupt Assignment Entry. For the ISA
- * bus the IRQ is the device number but unencoded.
- * May need to handle other buses here in the future
- * (but unlikely).
- *
- * For PCI devices, this field's lowest two bits are INT#A == 0,
- * INT#B == 1, etc. Bits 2-6 are the PCI device number.
- */
- devno = p[5];
- if (memcmp(mpbus[p[4]]->type, "PCI ", 6) != 0)
- devno <<= 2;
- ioapicintrinit(p[4], p[6], p[7], devno, lo);
-
+ mpintrprint("iointr skipped", p);
p += 8;
break;
- case 4: /* LINTR */
- /*
- * Format is the same as IOINTR above.
- */
- if ((lo = mpmkintr(p)) == 0) {
- p += 8;
- break;
+ }
+ if (MP_VERBOSE_DEBUG)
+ mpintrprint("iointr", p);
+
+ /*
+ * Always present the device number in the style
+ * of a PCI Interrupt Assignment Entry. For the ISA
+ * bus the IRQ is the device number but unencoded.
+ * May need to handle other buses here in the future
+ * (but unlikely).
+ *
+ * For PCI devices, this field's lowest two bits are
+ * INT#A == 0, INT#B == 1, etc. Bits 2-6 are the PCI
+ * device number.
+ */
+ devno = p[5];
+ if (memcmp(mpbus[p[4]]->type, "PCI ", 6) != 0)
+ devno <<= 2;
+ ioapicintrinit(p[4], p[6], p[7], devno, lo);
+
+ p += 8;
+ break;
+ case 4: /* LINTR */
+ /*
+ * Format is the same as IOINTR above.
+ */
+ if ((lo = mpmkintr(p)) == 0) {
+ p += 8;
+ break;
+ }
+ if (MP_VERBOSE_DEBUG)
+ mpintrprint("LINTR", p);
+
+ /*
+ * Everything was checked in mpmkintr above.
+ */
+ if (p[6] == 0xff) {
+ for (i = 0; i < Napic; i++) {
+ if (!xlapic[i].useable ||
+ xlapic[i].addr)
+ continue;
+ xlapic[i].lvt[p[7]] = lo;
}
- if (MP_VERBOSE_DEBUG)
- mpintrprint("LINTR", p);
-
- /*
- * Everything was checked in mpmkintr above.
- */
- if (p[6] == 0xff) {
- for (i = 0; i < Napic; i++) {
- if (!xlapic[i].useable || xlapic[i].addr)
- continue;
- xlapic[i].lvt[p[7]] = lo;
- }
- } else
- xlapic[p[6]].lvt[p[7]] = lo;
- p += 8;
- break;
+ } else
+ xlapic[p[6]].lvt[p[7]] = lo;
+ p += 8;
+ break;
}
/*
@@ -344,34 +352,36 @@
e = p + l16get(pcmp->xlength);
while (p < e)
switch (*p) {
- default:
- n = p[1];
- printd("mpparse: unknown extended entry %d length %d\n", *p, n);
- for (i = 0; i < n; i++) {
- if (i && ((i & 0x0f) == 0))
- printd("\n");
- printd(" %#2.2ux", *p);
- p++;
- }
- printd("\n");
- break;
- case 128:
- printd("address space mapping\n");
- printd(" bus %d type %d base %#llux length %#llux\n",
- p[2], p[3], l64get(p + 4), l64get(p + 12));
- p += p[1];
- break;
- case 129:
- printd("bus hierarchy descriptor\n");
- printd(" bus %d sd %d parent bus %d\n", p[2], p[3], p[4]);
- p += p[1];
- break;
- case 130:
- printd("compatibility bus address space modifier\n");
- printd(" bus %d pr %d range list %d\n",
- p[2], p[3], l32get(p + 4));
- p += p[1];
- break;
+ default:
+ n = p[1];
+ printd("mpparse: unknown extended entry %d length %d\n",
+ *p, n);
+ for (i = 0; i < n; i++) {
+ if (i && ((i & 0x0f) == 0))
+ printd("\n");
+ printd(" %#2.2ux", *p);
+ p++;
+ }
+ printd("\n");
+ break;
+ case 128:
+ printd("address space mapping\n");
+ printd(" bus %d type %d base %#llux length %#llux\n",
+ p[2], p[3], l64get(p + 4), l64get(p + 12));
+ p += p[1];
+ break;
+ case 129:
+ printd("bus hierarchy descriptor\n");
+ printd(" bus %d sd %d parent bus %d\n", p[2], p[3],
+ p[4]);
+ p += p[1];
+ break;
+ case 130:
+ printd("compatibility bus address space modifier\n");
+ printd(" bus %d pr %d range list %d\n",
+ p[2], p[3], l32get(p + 4));
+ p += p[1];
+ break;
}
return maxcores;
}
@@ -421,8 +431,8 @@
printk("No mp tables found, might have issues!\n");
return maxcores;
}
- /* TODO: if an IMCR exists, we should set it to 1, though i've heard that
- * ACPI-capable HW doesn't have the IMCR anymore. */
+ /* TODO: if an IMCR exists, we should set it to 1, though i've heard
+ * that ACPI-capable HW doesn't have the IMCR anymore. */
if (MP_VERBOSE_DEBUG) {
printk("_MP_ @ %#p, addr %p length %ud rev %d",
diff --git a/kern/arch/x86/mpacpi.c b/kern/arch/x86/mpacpi.c
index 95ccf62..a5407a0 100644
--- a/kern/arch/x86/mpacpi.c
+++ b/kern/arch/x86/mpacpi.c
@@ -28,11 +28,11 @@
struct Apicst *st;
struct Madt *mt;
- /* If we don't have an mpisabusno yet, it's because the MP tables failed to
- * parse. So we'll just take the last one available. I think we're
- * supposed to parse the ACPI shit with the AML to figure out the buses and
- * find a clear one, but fuck that. Note this busno is just for our own
- * RDT/Rbus bookkeeping. */
+ /* If we don't have an mpisabusno yet, it's because the MP tables failed
+ * to parse. So we'll just take the last one available. I think we're
+ * supposed to parse the ACPI shit with the AML to figure out the buses
+ * and find a clear one, but fuck that. Note this busno is just for our
+ * own RDT/Rbus bookkeeping. */
if (mpisabusno == -1)
mpisabusno = Nbus - 1;
@@ -50,40 +50,42 @@
st = apics->children[i]->tbl;
already = "";
switch (st->type) {
- case ASlapic:
- printd("ASlapic %d\n", st->lapic.id);
- /* this table is supposed to have all of them if it exists */
- if (st->lapic.id > MaxAPICNO)
- break;
- apic = xlapic + st->lapic.id;
- bp = (np++ == 0);
- if (apic->useable) {
- already = "(mp)";
- } else if (ncleft != 0) {
- ncleft--;
- apicinit(st->lapic.id, mt->lapicpa, bp);
- } else
- already = "(off)";
+ case ASlapic:
+ printd("ASlapic %d\n", st->lapic.id);
+ /* this table is supposed to have all of them if it
+ * exists */
+ if (st->lapic.id > MaxAPICNO)
+ break;
+ apic = xlapic + st->lapic.id;
+ bp = (np++ == 0);
+ if (apic->useable) {
+ already = "(mp)";
+ } else if (ncleft != 0) {
+ ncleft--;
+ apicinit(st->lapic.id, mt->lapicpa, bp);
+ } else
+ already = "(off)";
- printd("apic proc %d/%d apicid %d %s\n", np - 1, apic->machno,
- st->lapic.id, already);
+ printd("apic proc %d/%d apicid %d %s\n", np - 1,
+ apic->machno, st->lapic.id, already);
+ break;
+ case ASioapic:
+ printd("ASioapic %d\n", st->ioapic.id);
+ if (st->ioapic.id > Napic)
break;
- case ASioapic:
- printd("ASioapic %d\n", st->ioapic.id);
- if (st->ioapic.id > Napic)
- break;
- apic = xioapic + st->ioapic.id;
- if (apic->useable) {
- apic->ibase = st->ioapic.ibase; /* gnarly */
- already = "(mp)";
- goto pr1;
- }
- ioapicinit(st->ioapic.id, st->ioapic.ibase, st->ioapic.addr);
+ apic = xioapic + st->ioapic.id;
+ if (apic->useable) {
+ apic->ibase = st->ioapic.ibase; /* gnarly */
+ already = "(mp)";
+ goto pr1;
+ }
+ ioapicinit(st->ioapic.id, st->ioapic.ibase,
+ st->ioapic.addr);
pr1:
- printd("ioapic %d ", st->ioapic.id);
- printd("addr %p base %d %s\n", apic->paddr, apic->ibase,
- already);
- break;
+ printd("ioapic %d ", st->ioapic.id);
+ printd("addr %p base %d %s\n", apic->paddr, apic->ibase,
+ already);
+ break;
}
}
return ncleft;
diff --git a/kern/arch/x86/msi.c b/kern/arch/x86/msi.c
index 9686cc7..06e8319 100644
--- a/kern/arch/x86/msi.c
+++ b/kern/arch/x86/msi.c
@@ -27,35 +27,35 @@
};
enum {
- /* MSI address format
- *
- * +31----------------------20+19----------12+11--------4+--3--+--2--+1---0+
- * | 0xfee | Dest APIC ID | Reserved | RH | DM | XX |
- * +--------------------------+--------------+-----------+-----+-----+-----+
- *
- * RH: Redirection Hint
- * DM: Destinatio Mode
- * XX: Probably reserved, set to 0
- */
- Msiabase = 0xfee00000u,
- Msiadest = 1<<12, /* same as 63:56 of apic vector */
+/* MSI address format
+ *
+ * +31----------------------20+19----------12+11--------4+--3--+--2--+1---0+
+ * | 0xfee | Dest APIC ID | Reserved | RH | DM | XX |
+ * +--------------------------+--------------+-----------+-----+-----+-----+
+ *
+ * RH: Redirection Hint
+ * DM: Destinatio Mode
+ * XX: Probably reserved, set to 0
+ */
+ Msiabase = 0xfee00000u,
+ Msiadest = 1<<12, /* same as 63:56 of apic vector */
Msiaedest = 1<<4, /* same as 55:48 of apic vector */
Msialowpri = 1<<3, /* redirection hint */
Msialogical = 1<<2,
- /* MSI data format
- * +63-------------------------------------------------------------------32+
- * | Reserved |
- * +-------------------------------+-15-+-14-+--------+10----8+7----------0+
- * | Reserved | TM | Lv | Reserv | Dmode | Vector |
- * +-------------------------------+----+----+--------+-------+------------+
- *
- * Dmode: delivery mode (like APIC/LVT messages). Usually 000 (Fixed).
- * TM: Trigger mode (0 Edge, 1 Level)
- * Lv: Level assert (0 Deassert, 1 Assert)
- *
- *
- * for more info, check intel's SDMv3 (grep message signal) */
+/* MSI data format
+ * +63-------------------------------------------------------------------32+
+ * | Reserved |
+ * +-------------------------------+-15-+-14-+--------+10----8+7----------0+
+ * | Reserved | TM | Lv | Reserv | Dmode | Vector |
+ * +-------------------------------+----+----+--------+-------+------------+
+ *
+ * Dmode: delivery mode (like APIC/LVT messages). Usually 000 (Fixed).
+ * TM: Trigger mode (0 Edge, 1 Level)
+ * Lv: Level assert (0 Deassert, 1 Assert)
+ *
+ *
+ * for more info, check intel's SDMv3 (grep message signal) */
Msidlevel = 1<<15,
Msidassert = 1<<14,
Msidmode = 1<<8, /* 3 bits; delivery mode */
@@ -66,7 +66,7 @@
/* msi capabilities */
Vmask = 1<<8, /* Vectors can be masked. Optional. */
Cap64 = 1<<7, /* 64-bit addresses. Optional. */
- Mmesgmsk = 7<<4, /* Mask for # of messages allowed. See 6.8.1.3 */
+ Mmesgmsk = 7<<4, /* Mask for # of messages allowed. See 6.8.1.3*/
Mmcap = 7<<1, /* # of messages the function can support. */
Msienable = 1<<0, /* Enable. */
/* msix capabilities */
@@ -103,8 +103,8 @@
static int msix_blacklist(struct pci_device *p)
{
switch (p->ven_id << 16 | p->dev_id) {
-// case 0x11ab << 16 | 0x6485: /* placeholder */
- return -1;
+// case 0x11ab << 16 | 0x6485: /* placeholder */
+ return -1;
}
return 0;
}
@@ -112,14 +112,15 @@
static uint32_t msi_make_addr_lo(uint64_t vec)
{
unsigned int dest, lopri, logical;
+
/* The destination is the traditional 8-bit APIC id is in 63:56 of the
* vector. Later we may need to deal with extra destination bits
* (Msiaedest, in this code). I haven't seen anything in the Intel SDM
* about using Msiaedest (the bits are reserved) */
dest = vec >> 56;
- /* lopri is rarely set, and intel doesn't recommend using it. with msi, the
- * lopri field is actually a redirection hint, and also must be set when
- * sending logical messages. */
+ /* lopri is rarely set, and intel doesn't recommend using it. with msi,
+ * the lopri field is actually a redirection hint, and also must be set
+ * when sending logical messages. */
lopri = (vec & 0x700) == MTlp;
logical = (vec & Lm) != 0;
if (logical)
@@ -131,10 +132,11 @@
static uint32_t msi_make_data(uint64_t vec)
{
unsigned int deliv_mode;
+
deliv_mode = (vec >> 8) & 7;
- /* We can only specify the lower 16 bits of the MSI message, the rest gets
- * forced to 0 by the device. MSI-X can use the full 32 bits. We're
- * assuming edge triggered here. */
+ /* We can only specify the lower 16 bits of the MSI message, the rest
+ * gets forced to 0 by the device. MSI-X can use the full 32 bits.
+ * We're assuming edge triggered here. */
return Msidmode * deliv_mode | ((unsigned int)vec & 0xff);
}
@@ -155,15 +157,16 @@
return -1;
}
if (p->msi_ready) {
- /* only allowing one enable of MSI per device (not supporting multiple
- * vectors) */
+ /* only allowing one enable of MSI per device (not supporting
+ * multiple vectors) */
printk("MSI: MSI is already enabled, aborting\n");
spin_unlock_irqsave(&p->lock);
return -1;
}
p->msi_ready = TRUE;
- /* Get the offset of the MSI capability in the function's config space. */
+ /* Get the offset of the MSI capability in the function's config space.
+ */
c = msicap(p);
if (!c) {
spin_unlock_irqsave(&p->lock);
@@ -207,11 +210,11 @@
if(f & Vmask)
pcidev_write32(p, c + datao + 4, 0);
- /* Now write the control bits back, with the Mmesg mask (which is a power of
- * 2) set to 0 (meaning one vector only). Note we still haven't enabled
- * MSI. Will do that when we unmask. According to the spec, we're not
- * supposed to use the Msienable bit to mask the IRQ, though I don't see how
- * we can mask on non-Vmask-supported HW. */
+ /* Now write the control bits back, with the Mmesg mask (which is a
+ * power of 2) set to 0 (meaning one vector only). Note we still
+ * haven't enabled MSI. Will do that when we unmask. According to the
+ * spec, we're not supposed to use the Msienable bit to mask the IRQ,
+ * though I don't see how we can mask on non-Vmask-supported HW. */
printd("write @ %d %04lx\n",c + 2, f);
pcidev_write16(p, c + 2, f);
spin_unlock_irqsave(&p->lock);
@@ -268,7 +271,6 @@
}
if (msix_blacklist(p) != 0)
return -1;
- /* Get the offset of the MSI capability in the function's config space. */
c = msixcap(p);
if (c == 0)
return -1;
@@ -287,7 +289,8 @@
return -1;
}
p->msix_nr_vec = (f & Msixtblsize) + 1;
- p->msix_tbl_vaddr = vmap_pmem_nocache(p->msix_tbl_paddr, p->msix_nr_vec *
+ p->msix_tbl_vaddr = vmap_pmem_nocache(p->msix_tbl_paddr,
+ p->msix_nr_vec *
sizeof(struct msix_entry));
if (!p->msix_tbl_vaddr) {
pcidev_write16(p, c + 2, f & ~Msixenable);
@@ -300,12 +303,12 @@
pcidev_write16(p, c + 2, f & ~Msixenable);
printk("MSI-X: unable to vmap the PBA!\n");
vunmap_vmem(p->msix_tbl_paddr,
- p->msix_nr_vec * sizeof(struct msix_entry));
+ p->msix_nr_vec * sizeof(struct msix_entry));
return -1;
}
- /* they should all be masked already, but remasking just in case. likewise,
- * we need to 0 out the data, since we'll use the lower byte later when
- * determining if an msix vector is free or not. */
+ /* they should all be masked already, but remasking just in case.
+ * likewise, we need to 0 out the data, since we'll use the lower byte
+ * later when determining if an msix vector is free or not. */
entry = (struct msix_entry*)p->msix_tbl_vaddr;
for (int i = 0; i < p->msix_nr_vec; i++, entry++) {
__msix_mask_entry(entry);
@@ -349,8 +352,8 @@
spin_unlock_irqsave(&p->lock);
return 0;
}
- /* find an unused slot (no apic_vector assigned). later, we might want to
- * point back to the irq_hs for each entry. not a big deal now. */
+ /* find an unused slot (no apic_vector assigned). later, we might want
+ * to point back to the irq_hs for each entry. not a big deal now. */
entry = (struct msix_entry*)p->msix_tbl_vaddr;
for (i = 0; i < p->msix_nr_vec; i++, entry++)
if (!(read_mmreg32((uintptr_t)&entry->data) & 0xff))
@@ -388,6 +391,7 @@
void pci_msi_mask(struct pci_device *p)
{
unsigned int c, f;
+
c = msicap(p);
assert(c);
@@ -400,6 +404,7 @@
void pci_msi_unmask(struct pci_device *p)
{
unsigned int c, f;
+
c = msicap(p);
assert(c);
@@ -412,6 +417,7 @@
void pci_msi_route(struct pci_device *p, int dest)
{
unsigned int c, f;
+
c = msicap(p);
assert(c);
diff --git a/kern/arch/x86/msr.h b/kern/arch/x86/msr.h
index 42f9af6..6367745 100644
--- a/kern/arch/x86/msr.h
+++ b/kern/arch/x86/msr.h
@@ -29,10 +29,10 @@
};
int msr_cores_read(const struct core_set *cset, const struct msr_address *msra,
- struct msr_value *msrv);
+ struct msr_value *msrv);
int msr_core_read(unsigned int core, uint32_t addr, uint64_t *value);
int msr_cores_write(const struct core_set *cset, const struct msr_address *msra,
- const struct msr_value *msrv);
+ const struct msr_value *msrv);
int msr_core_write(unsigned int core, uint32_t addr, uint64_t value);
static inline void msr_set_address(struct msr_address *msra, uint32_t addr)
@@ -42,8 +42,8 @@
}
static inline void msr_set_addresses(struct msr_address *msra,
- const uint32_t *addresses,
- size_t num_addresses)
+ const uint32_t *addresses,
+ size_t num_addresses)
{
ZERO_DATA(*msra);
msra->addresses = addresses;
@@ -51,8 +51,8 @@
}
static inline int msr_get_core_address(unsigned int coreno,
- const struct msr_address *msra,
- uint32_t *paddr)
+ const struct msr_address *msra,
+ uint32_t *paddr)
{
if (msra->addresses != NULL) {
if (coreno >= (unsigned int) msra->num_addresses)
@@ -73,7 +73,7 @@
}
static inline void msr_set_values(struct msr_value *msrv,
- const uint64_t *values, size_t num_values)
+ const uint64_t *values, size_t num_values)
{
ZERO_DATA(*msrv);
@@ -85,7 +85,7 @@
}
static inline int msr_set_core_value(unsigned int coreno, uint64_t value,
- struct msr_value *msrv)
+ struct msr_value *msrv)
{
if (msrv->values != NULL) {
if (coreno >= (unsigned int) msrv->num_values)
@@ -100,8 +100,8 @@
}
static inline int msr_get_core_value(unsigned int coreno,
- const struct msr_value *msrv,
- uint64_t *pvalue)
+ const struct msr_value *msrv,
+ uint64_t *pvalue)
{
if (msrv->values != NULL) {
if (coreno >= (unsigned int) msrv->num_values)
diff --git a/kern/arch/x86/page_alloc.c b/kern/arch/x86/page_alloc.c
index e0161cb..cd1a481 100644
--- a/kern/arch/x86/page_alloc.c
+++ b/kern/arch/x86/page_alloc.c
@@ -25,8 +25,8 @@
return;
if (start + len > max_paddr)
len = max_paddr - start;
- /* For paranoia, skip anything below EXTPHYSMEM. If we ever change this,
- * we'll need to deal with smp_boot's trampoline page. */
+ /* For paranoia, skip anything below EXTPHYSMEM. If we ever change
+ * this, we'll need to deal with smp_boot's trampoline page. */
if ((start < EXTPHYSMEM) && (start + len < EXTPHYSMEM))
return;
if ((start < EXTPHYSMEM) && (EXTPHYSMEM <= start + len)) {
@@ -35,13 +35,15 @@
}
/* Skip over any pages already allocated in boot_alloc().
* (boot_freemem_paddr is the next free addr.) */
- if ((start < boot_freemem_paddr) && (boot_freemem_paddr <= start + len)) {
+ if ((start < boot_freemem_paddr)
+ && (boot_freemem_paddr <= start + len)) {
len = start + len - boot_freemem_paddr;
start = boot_freemem_paddr;
}
- /* Skip any part that intersects with the kernel, which is linked and loaded
- * from EXTPHYSMEM to end in kernel64.ld */
- if (regions_collide_unsafe(EXTPHYSMEM, PADDR(end), start, start + len)) {
+ /* Skip any part that intersects with the kernel, which is linked and
+ * loaded from EXTPHYSMEM to end in kernel64.ld */
+ if (regions_collide_unsafe(EXTPHYSMEM, PADDR(end), start, start + len))
+ {
len = start + len - PADDR(end);
start = PADDR(end);
}
@@ -72,11 +74,11 @@
*
* So we'll go with two free memory regions:
*
- * [ 0, ROUNDUP(boot_freemem_paddr, PGSIZE) ) = busy
- * [ ROUNDUP(boot_freemem_paddr, PGSIZE), TOP_OF_1 ) = free
- * [ MAGIC_HOLE, 0x0000000100000000 ) = busy
- * (and maybe this:)
- * [ 0x0000000100000000, max_paddr ) = free
+ * [ 0, ROUNDUP(boot_freemem_paddr, PGSIZE) ) = busy
+ * [ ROUNDUP(boot_freemem_paddr, PGSIZE), TOP_OF_1 ) = free
+ * [ MAGIC_HOLE, 0x0000000100000000 ) = busy
+ * (and maybe this:)
+ * [ 0x0000000100000000, max_paddr ) = free
*
* where TOP_OF_1 is the min of IOAPIC_PBASE and max_paddr.
*
@@ -89,19 +91,19 @@
physaddr_t top_of_free_1 = MIN(0xc0000000, max_paddr);
physaddr_t start_of_free_2;
- printk("Warning: poor memory detection (qemu?). May lose 1GB of RAM\n");
+ printk("Warning: poor memory detection (qemu?). May lose 1GB of RAM\n");
arena_add(base_arena, KADDR(top_of_busy), top_of_free_1 - top_of_busy,
MEM_WAIT);
/* If max_paddr is less than the start of our potential second free mem
- * region, we can just leave. We also don't want to poke around the pages
- * array either (and accidentally run off the end of the array).
+ * region, we can just leave. We also don't want to poke around the
+ * pages array either (and accidentally run off the end of the array).
*
* Additionally, 32 bit doesn't acknowledge pmem above the 4GB mark. */
start_of_free_2 = 0x0000000100000000;
if (max_paddr < start_of_free_2)
return;
- arena_add(base_arena, KADDR(start_of_free_2), max_paddr - start_of_free_2,
- MEM_WAIT);
+ arena_add(base_arena, KADDR(start_of_free_2), max_paddr -
+ start_of_free_2, MEM_WAIT);
}
/* Initialize base arena based on available free memory. After this, do not use
@@ -110,11 +112,12 @@
{
/* First, all memory is busy / not free by default.
*
- * To avoid a variety of headaches, any memory below 1MB is considered busy.
- * Likewise, everything in the kernel, up to _end is also busy. And
- * everything we've already boot_alloc'd is busy. These chunks of memory
- * are reported as 'free' by multiboot. All of this memory is below
- * boot_freemem_paddr. We don't treat anything below that as free.
+ * To avoid a variety of headaches, any memory below 1MB is considered
+ * busy. Likewise, everything in the kernel, up to _end is also busy.
+ * And everything we've already boot_alloc'd is busy. These chunks of
+ * memory are reported as 'free' by multiboot. All of this memory is
+ * below boot_freemem_paddr. We don't treat anything below that as
+ * free.
*
* We'll also abort the mapping for any addresses over max_paddr, since
* we'll never use them. 'pages' does not track them either.
@@ -131,9 +134,11 @@
0);
boot_freemem_paddr = PADDR(ROUNDUP(boot_freemem, PGSIZE));
if (mboot_has_mmaps(mbi)) {
- mboot_foreach_mmap(mbi, parse_mboot_region, (void*)boot_freemem_paddr);
+ mboot_foreach_mmap(mbi, parse_mboot_region,
+ (void*)boot_freemem_paddr);
} else {
- /* No multiboot mmap regions (probably run from qemu with -kernel) */
+ /* No multiboot mmap regions (probably run from qemu with
+ * -kernel) */
account_for_pages(boot_freemem_paddr);
}
}
diff --git a/kern/arch/x86/pci.c b/kern/arch/x86/pci.c
index 771b9ba..3da1b86 100644
--- a/kern/arch/x86/pci.c
+++ b/kern/arch/x86/pci.c
@@ -29,6 +29,7 @@
static uint32_t pci_getbar(struct pci_device *pcidev, unsigned int bar)
{
uint8_t type;
+
if (bar >= MAX_PCI_BAR)
panic("Nonexistant bar requested!");
type = pcidev_read8(pcidev, PCI_HEADER_REG);
@@ -66,6 +67,7 @@
static uint32_t pci_getmembar32(uint32_t bar)
{
uint8_t type = bar & PCI_MEMBAR_TYPE;
+
if (type != PCI_MEMBAR_32BIT) {
warn("Unhandled PCI membar type: %02p\n", type >> 1);
return 0;
@@ -91,6 +93,7 @@
uint32_t bar_off = PCI_BAR0_STD + bar * PCI_BAR_OFF;
uint32_t old_val = pcidev_read32(pcidev, bar_off);
uint32_t retval;
+
pcidev_write32(pcidev, bar_off, 0xffffffff);
/* Don't forget to mask the lower 3 bits! */
retval = pcidev_read32(pcidev, bar_off) & PCI_BAR_MEM_MASK;
@@ -107,13 +110,15 @@
{
uint32_t bar_val;
int max_bars;
+
if (pcidev->header_type == STD_PCI_DEV)
max_bars = MAX_PCI_BAR;
else if (pcidev->header_type == PCI2PCI)
max_bars = 2;
else
max_bars = 0;
- /* TODO: consider aborting for classes 00, 05 (memory ctlr), 06 (bridge) */
+ /* TODO: consider aborting for classes 00, 05 (memory ctlr), 06 (bridge)
+ */
for (int i = 0; i < max_bars; i++) {
bar_val = pci_getbar(pcidev, i);
pcidev->bar[i].raw_bar = bar_val;
@@ -123,23 +128,31 @@
pcidev->bar[i].pio_base = pci_getiobar32(bar_val);
} else {
if (pci_is_membar32(bar_val)) {
- pcidev->bar[i].mmio_base32 = bar_val & PCI_BAR_MEM_MASK;
- pcidev->bar[i].mmio_sz = __pci_membar_get_sz(pcidev, i);
+ pcidev->bar[i].mmio_base32 =
+ bar_val & PCI_BAR_MEM_MASK;
+ pcidev->bar[i].mmio_sz =
+ __pci_membar_get_sz(pcidev, i);
} else if (pci_is_membar64(bar_val)) {
- /* 64 bit, the lower 32 are in this bar, the upper
- * are in the next bar */
- pcidev->bar[i].mmio_base64 = bar_val & PCI_BAR_MEM_MASK;
+ /* 64 bit, the lower 32 are in this bar, the
+ * upper are in the next bar */
+ pcidev->bar[i].mmio_base64 =
+ bar_val & PCI_BAR_MEM_MASK;
assert(i < max_bars - 1);
- bar_val = pci_getbar(pcidev, i + 1); /* read next bar */
- /* note we don't check for IO or memsize. the entire next bar
- * is supposed to be for the upper 32 bits. */
- pcidev->bar[i].mmio_base64 |= (uint64_t)bar_val << 32;
- pcidev->bar[i].mmio_sz = __pci_membar_get_sz(pcidev, i);
+ /* read next bar */
+ bar_val = pci_getbar(pcidev, i + 1);
+ /* note we don't check for IO or memsize. the
+ * entire next bar is supposed to be for the
+ * upper 32 bits. */
+ pcidev->bar[i].mmio_base64 |=
+ (uint64_t)bar_val << 32;
+ pcidev->bar[i].mmio_sz =
+ __pci_membar_get_sz(pcidev, i);
i++;
}
}
- /* this will track the maximum bar we've had. it'll include the 64 bit
- * uppers, as well as devices that have only higher numbered bars. */
+ /* this will track the maximum bar we've had. it'll include the
+ * 64 bit uppers, as well as devices that have only higher
+ * numbered bars. */
pcidev->nr_bars = i + 1;
}
}
@@ -148,18 +161,19 @@
{
uint32_t cap_off; /* not sure if this can be extended from u8 */
uint8_t cap_id;
+
if (!(pcidev_read16(pcidev, PCI_STATUS_REG) & (1 << 4)))
return;
switch (pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7f) {
- case 0: /* etc */
- case 1: /* pci to pci bridge */
- cap_off = 0x34;
- break;
- case 2: /* cardbus bridge */
- cap_off = 0x14;
- break;
- default:
- return;
+ case 0: /* etc */
+ case 1: /* pci to pci bridge */
+ cap_off = 0x34;
+ break;
+ case 2: /* cardbus bridge */
+ cap_off = 0x14;
+ break;
+ default:
+ return;
}
/* initial offset points to the addr of the first cap */
cap_off = pcidev_read8(pcidev, cap_off);
@@ -167,16 +181,16 @@
while (cap_off) {
cap_id = pcidev_read8(pcidev, cap_off);
if (cap_id > PCI_CAP_ID_MAX) {
- printk("PCI %x:%x:%x had bad cap 0x%x\n", pcidev->bus, pcidev->dev,
- pcidev->func, cap_id);
+ printk("PCI %x:%x:%x had bad cap 0x%x\n", pcidev->bus,
+ pcidev->dev, pcidev->func, cap_id);
return;
}
pcidev->caps[cap_id] = cap_off;
cap_off = pcidev_read8(pcidev, cap_off + 1);
/* not sure if subsequent caps must be aligned or not */
if (cap_off & 0x3)
- printk("PCI %x:%x:%x had unaligned cap offset 0x%x\n", pcidev->bus,
- pcidev->dev, pcidev->func, cap_off);
+ printk("PCI %x:%x:%x had unaligned cap offset 0x%x\n",
+ pcidev->bus, pcidev->dev, pcidev->func, cap_off);
}
}
@@ -188,9 +202,9 @@
uint16_t dev_id, ven_id;
struct pci_device *pcidev;
int max_nr_func;
- /* In earlier days bus address 0xff caused problems so we only iterated to
- * PCI_MAX_BUS - 1, but this should no longer be an issue.
- * Old comment: phantoms at 0xff */
+ /* In earlier days bus address 0xff caused problems so we only iterated
+ * to PCI_MAX_BUS - 1, but this should no longer be an issue. Old
+ * comment: phantoms at 0xff */
for (int i = 0; i < PCI_MAX_BUS; i++) {
for (int j = 0; j < PCI_MAX_DEV; j++) {
max_nr_func = 1;
@@ -199,16 +213,18 @@
dev_id = result >> 16;
ven_id = result & 0xffff;
/* Skip invalid IDs (not a device)
- * If the first function doesn't exist then no device is
- * connected, but there can be gaps in the other function
- * numbers. Eg. 0,2,3 is ok. */
+ * If the first function doesn't exist then no
+ * device is connected, but there can be gaps in
+ * the other function numbers. Eg. 0,2,3 is ok.
+ * */
if (ven_id == INVALID_VENDOR_ID) {
if (k == 0)
break;
continue;
}
pcidev = kzmalloc(sizeof(struct pci_device), 0);
- /* we don't need to lock it til we post the pcidev to the list*/
+ /* we don't need to lock it til we post the
+ * pcidev to the list*/
spinlock_init_irqsave(&pcidev->lock);
pcidev->bus = i;
pcidev->dev = j;
@@ -219,43 +235,58 @@
pcidev->dev_id = dev_id;
pcidev->ven_id = ven_id;
/* Get the Class/subclass */
- pcidev->class = pcidev_read8(pcidev, PCI_CLASS_REG);
- pcidev->subclass = pcidev_read8(pcidev, PCI_SUBCLASS_REG);
- pcidev->progif = pcidev_read8(pcidev, PCI_PROGIF_REG);
- /* All device types (0, 1, 2) have the IRQ in the same place */
+ pcidev->class =
+ pcidev_read8(pcidev, PCI_CLASS_REG);
+ pcidev->subclass =
+ pcidev_read8(pcidev, PCI_SUBCLASS_REG);
+ pcidev->progif =
+ pcidev_read8(pcidev, PCI_PROGIF_REG);
+ /* All device types (0, 1, 2) have the IRQ in
+ * the same place */
/* This is the PIC IRQ the device is wired to */
- pcidev->irqline = pcidev_read8(pcidev, PCI_IRQLINE_STD);
- /* This is the interrupt pin the device uses (INTA# - INTD#) */
- pcidev->irqpin = pcidev_read8(pcidev, PCI_IRQPIN_STD);
+ pcidev->irqline =
+ pcidev_read8(pcidev, PCI_IRQLINE_STD);
+ /* This is the interrupt pin the device uses
+ * (INTA# - INTD#) */
+ pcidev->irqpin =
+ pcidev_read8(pcidev, PCI_IRQPIN_STD);
/* bottom 7 bits are header type */
- switch (pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7c) {
- case 0x00:
- pcidev->header_type = STD_PCI_DEV;
- break;
- case 0x01:
- pcidev->header_type = PCI2PCI;
- break;
- case 0x02:
- pcidev->header_type = PCI2CARDBUS;
- break;
- default:
- pcidev->header_type = "Unknown Header Type";
+ switch (pcidev_read8(pcidev, PCI_HEADER_REG)
+ & 0x7c) {
+ case 0x00:
+ pcidev->header_type = STD_PCI_DEV;
+ break;
+ case 0x01:
+ pcidev->header_type = PCI2PCI;
+ break;
+ case 0x02:
+ pcidev->header_type = PCI2CARDBUS;
+ break;
+ default:
+ pcidev->header_type =
+ "Unknown Header Type";
}
+
__pci_handle_bars(pcidev);
__pci_parse_caps(pcidev);
- /* we're the only writer at this point in the boot process */
- STAILQ_INSERT_TAIL(&pci_devices, pcidev, all_dev);
+ /* we're the only writer at this point in the
+ * boot process */
+ STAILQ_INSERT_TAIL(&pci_devices, pcidev,
+ all_dev);
#ifdef CONFIG_PCI_VERBOSE
pcidev_print_info(pcidev, 4);
#else
pcidev_print_info(pcidev, 0);
#endif /* CONFIG_PCI_VERBOSE */
- /* Top bit determines if we have multiple functions on this
- * device. We can't just check for more functions, since
- * non-multifunction devices exist that respond to different
- * functions with the same underlying device (same bars etc).
- * Note that this style allows for devices that only report
- * multifunction in the first function's header. */
+ /* Top bit determines if we have multiple
+ * functions on this device. We can't just
+ * check for more functions, since
+ * non-multifunction devices exist that respond
+ * to different functions with the same
+ * underlying device (same bars etc). Note that
+ * this style allows for devices that only
+ * report multifunction in the first function's
+ * header. */
if (pcidev_read8(pcidev, PCI_HEADER_REG) & 0x80)
max_nr_func = PCI_MAX_FUNC;
}
@@ -269,8 +300,8 @@
((uint32_t)dev << 11) |
((uint32_t)func << 8) |
(reg & 0xfc) |
- ((reg & 0xf00) << 16) | /* extended PCI CFG space... */
- 0x80000000);
+ ((reg & 0xf00) << 16) |/* extended PCI CFG space... */
+ 0x80000000);
}
/* Helper to read 32 bits from the config space of B:D:F. 'Offset' is how far
@@ -278,6 +309,7 @@
uint32_t pci_read32(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset)
{
uint32_t ret;
+
spin_lock_irqsave(&pci_lock);
outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
ret = inl(PCI_CONFIG_DATA);
@@ -299,6 +331,7 @@
uint16_t pci_read16(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset)
{
uint16_t ret;
+
spin_lock_irqsave(&pci_lock);
outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
ret = inw(PCI_CONFIG_DATA + (offset & 2));
@@ -318,6 +351,7 @@
uint8_t pci_read8(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset)
{
uint8_t ret;
+
spin_lock_irqsave(&pci_lock);
outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
ret = inb(PCI_CONFIG_DATA + (offset & 3));
@@ -369,7 +403,7 @@
static void pcidev_get_cldesc(struct pci_device *pcidev, char **class,
char **subclass, char **progif)
{
- int i ;
+ int i;
*class = *subclass = *progif = "";
for (i = 0; i < PCI_CLASSCODETABLE_LEN; i++) {
@@ -378,8 +412,10 @@
*class = PciClassCodeTable[i].BaseDesc;
if (PciClassCodeTable[i].SubClass == pcidev->subclass) {
if (!(**subclass))
- *subclass = PciClassCodeTable[i].SubDesc;
- if (PciClassCodeTable[i].ProgIf == pcidev->progif) {
+ *subclass =
+ PciClassCodeTable[i].SubDesc;
+ if (PciClassCodeTable[i].ProgIf ==
+ pcidev->progif) {
*progif = PciClassCodeTable[i].ProgDesc;
break ;
}
@@ -392,7 +428,7 @@
static void pcidev_get_devdesc(struct pci_device *pcidev, char **vend_short,
char **vend_full, char **chip, char **chip_desc)
{
- int i ;
+ int i;
*vend_short = *vend_full = *chip = *chip_desc = "";
for (i = 0; i < PCI_VENTABLE_LEN; i++) {
@@ -416,6 +452,7 @@
void pcidev_print_info(struct pci_device *pcidev, int verbosity)
{
char *ven_sht, *ven_fl, *chip, *chip_txt, *class, *subcl, *progif;
+
pcidev_get_cldesc(pcidev, &class, &subcl, &progif);
pcidev_get_devdesc(pcidev, &ven_sht, &ven_fl, &chip, &chip_txt);
@@ -448,7 +485,8 @@
assert(pcidev->bar[i].pio_base);
printk("IO port 0x%04x\n", pcidev->bar[i].pio_base);
} else {
- bool bar_is_64 = pci_is_membar64(pcidev->bar[i].raw_bar);
+ bool bar_is_64 =
+ pci_is_membar64(pcidev->bar[i].raw_bar);
printk("MMIO Base%s %p, MMIO Size %p\n",
bar_is_64 ? "64" : "32",
bar_is_64 ? pcidev->bar[i].mmio_base64 :
@@ -456,7 +494,7 @@
pcidev->bar[i].mmio_sz);
/* Takes up two bars */
if (bar_is_64) {
- assert(!pcidev->bar[i].mmio_base32); /* double-check */
+ assert(!pcidev->bar[i].mmio_base32);
i++;
}
}
@@ -480,6 +518,7 @@
void pci_clr_bus_master(struct pci_device *pcidev)
{
uint16_t reg;
+
spin_lock_irqsave(&pcidev->lock);
reg = pcidev_read16(pcidev, PCI_CMD_REG);
reg &= ~PCI_CMD_BUS_MAS;
@@ -491,6 +530,7 @@
{
struct pci_device *search;
int bus, dev, func;
+
bus = BUSBNO(tbdf);
dev = BUSDNO(tbdf);
func = BUSFNO(tbdf);
@@ -513,8 +553,8 @@
assert(pci_is_membar64(pcidev->bar[bir].raw_bar));
return pcidev->bar[bir].mmio_base64;
}
- /* we can just return mmio_base32, even if it's 0. but i'd like to do the
- * assert too. */
+ /* we can just return mmio_base32, even if it's 0. but i'd like to do
+ * the assert too. */
if (pcidev->bar[bir].mmio_base32) {
assert(pci_is_membar32(pcidev->bar[bir].raw_bar));
return pcidev->bar[bir].mmio_base32;
@@ -555,15 +595,16 @@
uint16_t pci_get_subvendor(struct pci_device *pcidev)
{
uint8_t header_type = pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7c;
+
switch (header_type) {
- case 0x00: /* STD_PCI_DEV */
- return pcidev_read16(pcidev, PCI_SUBSYSVEN_STD);
- case 0x01: /* PCI2PCI */
- return -1;
- case 0x02: /* PCI2CARDBUS */
- return pcidev_read16(pcidev, PCI_SUBVENID_CB);
- default:
- warn("Unknown Header Type, %d", header_type);
+ case 0x00: /* STD_PCI_DEV */
+ return pcidev_read16(pcidev, PCI_SUBSYSVEN_STD);
+ case 0x01: /* PCI2PCI */
+ return -1;
+ case 0x02: /* PCI2CARDBUS */
+ return pcidev_read16(pcidev, PCI_SUBVENID_CB);
+ default:
+ warn("Unknown Header Type, %d", header_type);
}
return -1;
}
@@ -571,15 +612,16 @@
uint16_t pci_get_subdevice(struct pci_device *pcidev)
{
uint8_t header_type = pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7c;
+
switch (header_type) {
- case 0x00: /* STD_PCI_DEV */
- return pcidev_read16(pcidev, PCI_SUBSYSID_STD);
- case 0x01: /* PCI2PCI */
- return -1;
- case 0x02: /* PCI2CARDBUS */
- return pcidev_read16(pcidev, PCI_SUBDEVID_CB);
- default:
- warn("Unknown Header Type, %d", header_type);
+ case 0x00: /* STD_PCI_DEV */
+ return pcidev_read16(pcidev, PCI_SUBSYSID_STD);
+ case 0x01: /* PCI2PCI */
+ return -1;
+ case 0x02: /* PCI2CARDBUS */
+ return pcidev_read16(pcidev, PCI_SUBDEVID_CB);
+ default:
+ warn("Unknown Header Type, %d", header_type);
}
return -1;
}
@@ -600,8 +642,9 @@
return -EINVAL;
if (!pcidev->caps[cap_id])
return -ENOENT;
- /* The actual value at caps[id] is the offset in the PCI config space where
- * that ID was stored. That's needed for accessing the capability. */
+ /* The actual value at caps[id] is the offset in the PCI config space
+ * where that ID was stored. That's needed for accessing the
+ * capability. */
if (cap_reg)
*cap_reg = pcidev->caps[cap_id];
return 0;
@@ -616,6 +659,7 @@
{
uintptr_t paddr = pci_get_membar(dev, bir);
size_t sz = pci_get_membar_sz(dev, bir);
+
if (!paddr || !sz)
return 0;
return vmap_pmem_nocache(paddr, sz);
diff --git a/kern/arch/x86/pci.h b/kern/arch/x86/pci.h
index 374ef44..ba0ad9f 100644
--- a/kern/arch/x86/pci.h
+++ b/kern/arch/x86/pci.h
@@ -30,7 +30,7 @@
#define PCI_DEV_VEND_REG 0x00 /* for the 32 bit read of dev/vend */
#define PCI_VENDID_REG 0x00
#define PCI_DEVID_REG 0x02
-#define PCI_CMD_REG 0x04
+#define PCI_CMD_REG 0x04
#define PCI_STATUS_REG 0x06
#define PCI_REVID_REG 0x08
#define PCI_PROGIF_REG 0x09
@@ -47,7 +47,7 @@
#define PCI_BAR3_STD 0x1c
#define PCI_BAR4_STD 0x20
#define PCI_BAR5_STD 0x24
-#define PCI_BAR_OFF 0x04
+#define PCI_BAR_OFF 0x04
#define PCI_CARDBUS_STD 0x28
#define PCI_SUBSYSVEN_STD 0x2c
#define PCI_SUBSYSID_STD 0x2e
@@ -60,10 +60,10 @@
/* Config space for header type 0x01 (PCI-PCI bridge) */
/* None of these have been used, so if you use them, check them against
* http://wiki.osdev.org/PCI#PCI_Device_Structure */
-#define PCI_BAR0_BR 0x10
-#define PCI_BAR1_BR 0x14
-#define PCI_BUS1_BR 0x18
-#define PCI_BUS2_BR 0x19
+#define PCI_BAR0_BR 0x10
+#define PCI_BAR1_BR 0x14
+#define PCI_BUS1_BR 0x18
+#define PCI_BUS2_BR 0x19
#define PCI_SUBBUS_BR 0x1a
#define PCI_LATTIM2_BR 0x1b
#define PCI_IOBASE_BR 0x1c
@@ -113,7 +113,7 @@
#define PCI_CMD_BUS_MAS (1 << 2)
#define PCI_CMD_SPC_CYC (1 << 3)
#define PCI_CMD_WR_EN (1 << 4)
-#define PCI_CMD_VGA (1 << 5)
+#define PCI_CMD_VGA (1 << 5)
#define PCI_CMD_PAR_ERR (1 << 6)
/* #define PCI_CMD_XXX (1 << 7) Reserved */
#define PCI_CMD_SERR (1 << 8)
@@ -136,68 +136,68 @@
#define PCI_ST_PAR_ERR (1 << 15)
/* BARS: Base Address Registers */
-#define PCI_BAR_IO 0x1 /* 1 == IO, 0 == Mem */
+#define PCI_BAR_IO 0x1 /* 1 == IO, 0 == Mem */
#define PCI_BAR_IO_MASK 0xfffffffc
#define PCI_BAR_MEM_MASK 0xfffffff0
#define PCI_MEMBAR_TYPE (3 << 1)
#define PCI_MEMBAR_32BIT 0x0
-#define PCI_MEMBAR_RESV 0x2 /* type 0x1 shifted to MEMBAR_TYPE */
-#define PCI_MEMBAR_64BIT 0x4 /* type 0x2 shifted to MEMBAR_TYPE */
+#define PCI_MEMBAR_RESV 0x2 /* type 0x1 shifted to MEMBAR_TYPE */
+#define PCI_MEMBAR_64BIT 0x4 /* type 0x2 shifted to MEMBAR_TYPE */
-#define PCI_MAX_BUS 256
-#define PCI_MAX_DEV 32
+#define PCI_MAX_BUS 256
+#define PCI_MAX_DEV 32
#define PCI_MAX_FUNC 8
// Run the PCI Code to loop over the PCI BARs. For now we don't use the BARs,
// dont check em.
-#define CHECK_BARS 0
+#define CHECK_BARS 0
-#define MAX_PCI_BAR 6
+#define MAX_PCI_BAR 6
/* Nothing yet, but this helps with Linux drivers. */
struct device {
};
struct pci_bar {
- uint32_t raw_bar;
- uint32_t pio_base;
- uint32_t mmio_base32;
- uint64_t mmio_base64;
- uint32_t mmio_sz;
+ uint32_t raw_bar;
+ uint32_t pio_base;
+ uint32_t mmio_base32;
+ uint64_t mmio_base64;
+ uint32_t mmio_sz;
};
struct pci_device {
- STAILQ_ENTRY(pci_device) all_dev; /* list of all devices */
- SLIST_ENTRY(pci_device) irq_dev; /* list of all devs off an irq */
- char name[9];
- spinlock_t lock;
- void *dev_data; /* device private pointer */
- struct device device;
- bool in_use; /* prevent double discovery */
- uint8_t bus;
- uint8_t dev;
- uint8_t func;
- uint16_t dev_id;
- uint16_t ven_id;
- uint8_t irqline;
- uint8_t irqpin;
- char *header_type;
- uint8_t class;
- uint8_t subclass;
- uint8_t progif;
- bool msi_ready;
- uint32_t msi_msg_addr_hi;
- uint32_t msi_msg_addr_lo;
- uint32_t msi_msg_data;
- uint8_t nr_bars;
- struct pci_bar bar[MAX_PCI_BAR];
- uint32_t caps[PCI_CAP_ID_MAX + 1];
- uintptr_t msix_tbl_paddr;
- uintptr_t msix_tbl_vaddr;
- uintptr_t msix_pba_paddr;
- uintptr_t msix_pba_vaddr;
- unsigned int msix_nr_vec;
- bool msix_ready;
+ STAILQ_ENTRY(pci_device) all_dev; /* list of all devices */
+ SLIST_ENTRY(pci_device) irq_dev; /* list of all devs on irq */
+ char name[9];
+ spinlock_t lock;
+ void *dev_data; /* device private pointer */
+ struct device device;
+ bool in_use; /* prevent double discovery */
+ uint8_t bus;
+ uint8_t dev;
+ uint8_t func;
+ uint16_t dev_id;
+ uint16_t ven_id;
+ uint8_t irqline;
+ uint8_t irqpin;
+ char *header_type;
+ uint8_t class;
+ uint8_t subclass;
+ uint8_t progif;
+ bool msi_ready;
+ uint32_t msi_msg_addr_hi;
+ uint32_t msi_msg_addr_lo;
+ uint32_t msi_msg_data;
+ uint8_t nr_bars;
+ struct pci_bar bar[MAX_PCI_BAR];
+ uint32_t caps[PCI_CAP_ID_MAX + 1];
+ uintptr_t msix_tbl_paddr;
+ uintptr_t msix_tbl_vaddr;
+ uintptr_t msix_pba_paddr;
+ uintptr_t msix_pba_vaddr;
+ unsigned int msix_nr_vec;
+ bool msix_ready;
};
struct msix_entry {
@@ -205,11 +205,11 @@
};
struct msix_irq_vector {
- struct pci_device *pcidev;
- struct msix_entry *entry;
- uint32_t addr_lo;
- uint32_t addr_hi;
- uint32_t data;
+ struct pci_device *pcidev;
+ struct msix_entry *entry;
+ uint32_t addr_lo;
+ uint32_t addr_hi;
+ uint32_t data;
};
/* List of all discovered devices */
diff --git a/kern/arch/x86/perfmon.c b/kern/arch/x86/perfmon.c
index 0e7de49..65ca629 100644
--- a/kern/arch/x86/perfmon.c
+++ b/kern/arch/x86/perfmon.c
@@ -69,16 +69,17 @@
#define PROFILER_BT_DEPTH 16
struct sample_snapshot {
- struct user_context ctx;
- uintptr_t pc_list[PROFILER_BT_DEPTH];
- size_t nr_pcs;
+ struct user_context ctx;
+ uintptr_t pc_list[PROFILER_BT_DEPTH];
+ size_t nr_pcs;
};
static DEFINE_PERCPU(struct sample_snapshot, sample_snapshots);
static void perfmon_counters_env_init(void)
{
for (int i = 0; i < num_cores; i++) {
- struct perfmon_cpu_context *cctx = _PERCPU_VARPTR(counters_env, i);
+ struct perfmon_cpu_context *cctx =
+ _PERCPU_VARPTR(counters_env, i);
spinlock_init_irqsave(&cctx->lock);
}
@@ -113,8 +114,8 @@
uint64_t gctrl;
/* Events can be disabled in either location. We could just clear the
- * global ctrl, but we use the contents of EVENTSEL to say if the counter is
- * available or not. */
+ * global ctrl, but we use the contents of EVENTSEL to say if the
+ * counter is available or not. */
write_msr(MSR_ARCH_PERFMON_EVENTSEL0 + idx, 0);
gctrl = read_msr(MSR_CORE_PERF_GLOBAL_CTRL);
write_msr(MSR_CORE_PERF_GLOBAL_CTRL, gctrl & ~(1 << idx));
@@ -162,7 +163,8 @@
fx = perfmon_apply_fixevent_mask(event, idx, fxctrl_value);
write_msr(MSR_CORE_PERF_FIXED_CTR_CTRL, fx);
gctrl = read_msr(MSR_CORE_PERF_GLOBAL_CTRL);
- write_msr(MSR_CORE_PERF_GLOBAL_CTRL, gctrl | ((uint64_t) 1 << (32 + idx)));
+ write_msr(MSR_CORE_PERF_GLOBAL_CTRL,
+ gctrl | ((uint64_t) 1 << (32 + idx)));
}
static void perfmon_disable_fix_event(int idx, uint64_t fxctrl_value)
@@ -175,7 +177,8 @@
write_msr(MSR_CORE_PERF_FIXED_CTR_CTRL,
fxctrl_value & ~(FIXCNTR_MASK << (idx * FIXCNTR_NBITS)));
gctrl = read_msr(MSR_CORE_PERF_GLOBAL_CTRL);
- write_msr(MSR_CORE_PERF_GLOBAL_CTRL, gctrl & ~((uint64_t) 1 << (32 + idx)));
+ write_msr(MSR_CORE_PERF_GLOBAL_CTRL,
+ gctrl & ~((uint64_t) 1 << (32 + idx)));
}
static bool perfmon_fix_event_available(uint32_t idx, uint64_t fxctrl_value)
@@ -213,7 +216,8 @@
{
switch (err_code) {
case EBUSY:
- set_error(err_code, "Fixed perf counter is busy on core %d", core_id);
+ set_error(err_code, "Fixed perf counter is busy on core %d",
+ core_id);
break;
case ENOSPC:
set_error(err_code, "Perf counter idx out of range on core %d",
@@ -223,7 +227,8 @@
set_error(err_code, "Perf counter not set on core %d", core_id);
break;
default:
- set_error(err_code, "Unknown perf counter error on core %d", core_id);
+ set_error(err_code, "Unknown perf counter error on core %d",
+ core_id);
break;
};
}
@@ -245,20 +250,24 @@
} else if (!perfmon_fix_event_available(i, fxctrl_value)) {
i = -EBUSY;
} else {
- /* Keep a copy of pa->ev for later. pa is read-only and shared. */
+ /* Keep a copy of pa->ev for later. pa is read-only and
+ * shared. */
cctx->fixed_counters[i] = pa->ev;
pev = &cctx->fixed_counters[i];
if (PMEV_GET_INTEN(pev->event))
- perfmon_set_fixed_trigger(i, pev->trigger_count);
+ perfmon_set_fixed_trigger(i,
+ pev->trigger_count);
else
write_msr(MSR_CORE_PERF_FIXED_CTR0 + i, 0);
- write_msr(MSR_CORE_PERF_GLOBAL_OVF_CTRL, 1ULL << (32 + i));
+ write_msr(MSR_CORE_PERF_GLOBAL_OVF_CTRL,
+ 1ULL << (32 + i));
perfmon_enable_fix_event(i, pev->event, fxctrl_value);
}
} else {
for (i = 0; i < (int) cpu_caps.counters_x_proc; i++) {
if (cctx->counters[i].event == 0) {
- /* kernel bug if the MSRs don't agree with our bookkeeping */
+ /* kernel bug if the MSRs don't agree with our
+ * bookkeeping */
assert(perfmon_event_available(i));
break;
}
@@ -267,7 +276,8 @@
cctx->counters[i] = pa->ev;
pev = &cctx->counters[i];
if (PMEV_GET_INTEN(pev->event))
- perfmon_set_unfixed_trigger(i, pev->trigger_count);
+ perfmon_set_unfixed_trigger(i,
+ pev->trigger_count);
else
write_msr(MSR_IA32_PERFCTR0 + i, 0);
write_msr(MSR_CORE_PERF_GLOBAL_OVF_CTRL, 1ULL << i);
@@ -347,9 +357,11 @@
spin_lock_irqsave(&cctx->lock);
if (perfmon_is_fixed_event(&env->pa->ev))
- env->pef->cores_values[coreno] = perfmon_read_fixed_counter(ccno);
+ env->pef->cores_values[coreno] =
+ perfmon_read_fixed_counter(ccno);
else
- env->pef->cores_values[coreno] = perfmon_read_unfixed_counter(ccno);
+ env->pef->cores_values[coreno] =
+ perfmon_read_unfixed_counter(ccno);
spin_unlock_irqsave(&cctx->lock);
}
@@ -388,7 +400,7 @@
{
int i;
struct perfmon_alloc *pa = kzmalloc(sizeof(struct perfmon_alloc) +
- num_cores * sizeof(counter_t),
+ num_cores * sizeof(counter_t),
MEM_WAIT);
pa->ev = *pev;
@@ -401,7 +413,7 @@
static struct perfmon_status *perfmon_status_alloc(void)
{
struct perfmon_status *pef = kzmalloc(sizeof(struct perfmon_status) +
- num_cores * sizeof(uint64_t),
+ num_cores * sizeof(uint64_t),
MEM_WAIT);
return pef;
@@ -487,25 +499,28 @@
{
struct sample_snapshot *sample = PERCPU_VARPTR(sample_snapshots);
- /* We shouldn't need to worry about another NMI that concurrently mucks with
- * the sample. The PMU won't rearm the interrupt until we're done here. In
- * the event that we do get another NMI from another source, we may get a
- * weird backtrace in the perf output. */
+ /* We shouldn't need to worry about another NMI that concurrently mucks
+ * with the sample. The PMU won't rearm the interrupt until we're done
+ * here. In the event that we do get another NMI from another source,
+ * we may get a weird backtrace in the perf output. */
switch (sample->ctx.type) {
case ROS_HW_CTX:
if (in_kernel(&sample->ctx.tf.hw_tf)) {
- profiler_push_kernel_backtrace(sample->pc_list, sample->nr_pcs,
- info);
+ profiler_push_kernel_backtrace(sample->pc_list,
+ sample->nr_pcs, info);
} else {
- profiler_push_user_backtrace(sample->pc_list, sample->nr_pcs, info);
+ profiler_push_user_backtrace(sample->pc_list,
+ sample->nr_pcs, info);
}
break;
case ROS_VM_CTX:
- /* TODO: add VM support to perf. For now, just treat it like a user
- * addr. Note that the address is a guest-virtual address, not
- * guest-physical (which would be host virtual), and our VM_CTXs don't
- * make a distinction between user and kernel TFs (yet). */
- profiler_push_user_backtrace(sample->pc_list, sample->nr_pcs, info);
+ /* TODO: add VM support to perf. For now, just treat it like a
+ * user addr. Note that the address is a guest-virtual address,
+ * not guest-physical (which would be host virtual), and our
+ * VM_CTXs don't make a distinction between user and kernel TFs
+ * (yet). */
+ profiler_push_user_backtrace(sample->pc_list, sample->nr_pcs,
+ info);
break;
default:
warn("Bad perf sample type %d!", sample->ctx.type);
@@ -530,8 +545,10 @@
if (status & ((uint64_t) 1 << i)) {
if (cctx->counters[i].event) {
profiler_add_sample(
- perfmon_make_sample_event(cctx->counters + i));
- perfmon_set_unfixed_trigger(i, cctx->counters[i].trigger_count);
+ perfmon_make_sample_event(
+ cctx->counters + i));
+ perfmon_set_unfixed_trigger(i,
+ cctx->counters[i].trigger_count);
}
}
}
@@ -539,7 +556,8 @@
if (status & ((uint64_t) 1 << (32 + i))) {
if (cctx->fixed_counters[i].event) {
profiler_add_sample(
- perfmon_make_sample_event(cctx->fixed_counters + i));
+ perfmon_make_sample_event(
+ cctx->fixed_counters + i));
perfmon_set_fixed_trigger(i,
cctx->fixed_counters[i].trigger_count);
}
@@ -551,8 +569,8 @@
/* We need to re-arm the IRQ as the PFM IRQ gets masked on trigger.
* Note that KVM and real HW seems to be doing two different things WRT
- * re-arming the IRQ. KVM re-arms does not mask the IRQ, while real HW does.
- */
+ * re-arming the IRQ. KVM re-arms does not mask the IRQ, while real HW
+ * does. */
perfmon_arm_irq();
}
@@ -592,9 +610,9 @@
pa->ev.event &= 0xffffffff;
if (cpu_caps.perfmon_version < 3)
PMEV_SET_ANYTH(pa->ev.event, 0);
- /* Ensure we're turning on the event. The user could have forgotten to set
- * it. Our tracking of whether or not a counter is in use depends on it
- * being enabled, or at least that some bit is set. */
+ /* Ensure we're turning on the event. The user could have forgotten to
+ * set it. Our tracking of whether or not a counter is in use depends
+ * on it being enabled, or at least that some bit is set. */
PMEV_SET_EN(pa->ev.event, 1);
smp_do_in_cores(cset, perfmon_do_cores_alloc, pa);
@@ -613,8 +631,8 @@
* until the perfmon_install_session_alloc() completes, and at that
* time the smp_do_in_cores(perfmon_do_cores_alloc) will have run on
* all cores.
- * The perfmon_alloc data structure will never be changed once published.
- */
+ * The perfmon_alloc data structure will never be changed once
+ * published. */
i = perfmon_install_session_alloc(ps, pa);
poperror();
diff --git a/kern/arch/x86/perfmon.h b/kern/arch/x86/perfmon.h
index 060eecc..6433a2b 100644
--- a/kern/arch/x86/perfmon.h
+++ b/kern/arch/x86/perfmon.h
@@ -55,10 +55,10 @@
void perfmon_interrupt(struct hw_trapframe *hw_tf, void *data);
void perfmon_get_cpu_caps(struct perfmon_cpu_caps *pcc);
int perfmon_open_event(const struct core_set *cset, struct perfmon_session *ps,
- const struct perfmon_event *pev);
+ const struct perfmon_event *pev);
void perfmon_close_event(struct perfmon_session *ps, int ped);
struct perfmon_status *perfmon_get_event_status(struct perfmon_session *ps,
- int ped);
+ int ped);
void perfmon_free_event_status(struct perfmon_status *pef);
struct perfmon_session *perfmon_create_session(void);
void perfmon_close_session(struct perfmon_session *ps);
diff --git a/kern/arch/x86/pic.c b/kern/arch/x86/pic.c
index b52e3e7..5814694 100644
--- a/kern/arch/x86/pic.c
+++ b/kern/arch/x86/pic.c
@@ -12,7 +12,7 @@
spinlock_t piclock = SPINLOCK_INITIALIZER_IRQSAVE;
-/* * Remaps the Programmable Interrupt Controller to use IRQs 32-47
+/* Remaps the Programmable Interrupt Controller to use IRQs 32-47
* http://wiki.osdev.org/PIC
* Check osdev for a more thorough explanation/implementation.
* http://bochs.sourceforge.net/techspec/PORTS.LST */
@@ -41,6 +41,7 @@
void pic_mask_irq(struct irq_handler *unused, int trap_nr)
{
int irq = trap_nr - PIC1_OFFSET;
+
spin_lock_irqsave(&piclock);
if (irq > 7)
outb(PIC2_DATA, inb(PIC2_DATA) | (1 << (irq - 8)));
@@ -56,7 +57,8 @@
spin_lock_irqsave(&piclock);
if (irq > 7) {
outb(PIC2_DATA, inb(PIC2_DATA) & ~(1 << (irq - 8)));
- outb(PIC1_DATA, inb(PIC1_DATA) & 0xfb); // make sure irq2 is unmasked
+ // make sure irq2 is unmasked
+ outb(PIC1_DATA, inb(PIC1_DATA) & 0xfb);
} else
outb(PIC1_DATA, inb(PIC1_DATA) & ~(1 << irq));
spin_unlock_irqsave(&piclock);
@@ -72,6 +74,7 @@
uint16_t pic_get_mask(void)
{
uint16_t ret;
+
spin_lock_irqsave(&piclock);
ret = (inb(PIC2_DATA) << 8) | inb(PIC1_DATA);
spin_unlock_irqsave(&piclock);
@@ -81,6 +84,7 @@
static uint16_t __pic_get_irq_reg(int ocw3)
{
uint16_t ret;
+
spin_lock_irqsave(&piclock);
/* OCW3 to PIC CMD to get the register values. PIC2 is chained, and
* represents IRQs 8-15. PIC1 is IRQs 0-7, with 2 being the chain */
@@ -106,17 +110,19 @@
/* Takes a raw vector/trap number (32-47), not a device IRQ (0-15) */
bool pic_check_spurious(int trap_nr)
{
- /* the PIC may send spurious irqs via one of the chips irq 7. if the isr
- * doesn't show that irq, then it was spurious, and we don't send an eoi.
- * Check out http://wiki.osdev.org/8259_PIC#Spurious_IRQs */
+ /* the PIC may send spurious irqs via one of the chips irq 7. if the
+ * isr doesn't show that irq, then it was spurious, and we don't send an
+ * eoi. Check out http://wiki.osdev.org/8259_PIC#Spurious_IRQs */
if ((trap_nr == PIC1_SPURIOUS) && !(pic_get_isr() & (1 << 7))) {
- printd("Spurious PIC1 irq!\n"); /* want to know if this happens */
+ /* want to know if this happens */
+ printd("Spurious PIC1 irq!\n");
return TRUE;
}
if ((trap_nr == PIC2_SPURIOUS) && !(pic_get_isr() & (1 << 15))) {
- printd("Spurious PIC2 irq!\n"); /* want to know if this happens */
- /* for the cascaded PIC, we *do* need to send an EOI to the master's
- * cascade irq (2). */
+ /* want to know if this happens */
+ printd("Spurious PIC2 irq!\n");
+ /* for the cascaded PIC, we *do* need to send an EOI to the
+ * master's cascade irq (2). */
pic_send_eoi(2 + PIC1_OFFSET);
return TRUE;
}
@@ -126,6 +132,7 @@
void pic_send_eoi(int trap_nr)
{
int irq = trap_nr - PIC1_OFFSET;
+
spin_lock_irqsave(&piclock);
// all irqs beyond the first seven need to be chained to the slave
if (irq > 7)
diff --git a/kern/arch/x86/pic.h b/kern/arch/x86/pic.h
index fbaec1a..8df1725 100644
--- a/kern/arch/x86/pic.h
+++ b/kern/arch/x86/pic.h
@@ -13,21 +13,21 @@
* means that blindly writing to PIC1_DATA is an OCW1 (interrupt masks). When
* writing to CMD (A0), the chip can determine betweeb OCW2 and OCW3 by the
* setting of a few specific bits (OCW2 has bit 3 unset, OCW3 has it set). */
-#define PIC1_CMD 0x20
-#define PIC1_DATA 0x21
-#define PIC2_CMD 0xA0
-#define PIC2_DATA 0xA1
+#define PIC1_CMD 0x20
+#define PIC1_DATA 0x21
+#define PIC2_CMD 0xA0
+#define PIC2_DATA 0xA1
// These are also hardcoded into the IRQ_HANDLERs of kern/trapentry.S
-#define PIC1_OFFSET 0x20
-#define PIC2_OFFSET 0x28
-#define PIC1_SPURIOUS (7 + PIC1_OFFSET)
-#define PIC2_SPURIOUS (7 + PIC2_OFFSET)
-#define PIC_EOI 0x20 /* OCW2 EOI */
+#define PIC1_OFFSET 0x20
+#define PIC2_OFFSET 0x28
+#define PIC1_SPURIOUS (7 + PIC1_OFFSET)
+#define PIC2_SPURIOUS (7 + PIC2_OFFSET)
+#define PIC_EOI 0x20 /* OCW2 EOI */
/* These set the next CMD read to return specific values. Note that the chip
* remembers what setting we had before (IRR or ISR), if you do other reads of
* CMD. (not tested, written in the spec sheet) */
-#define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */
-#define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */
+#define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */
+#define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */
struct irq_handler; /* include loops */
diff --git a/kern/arch/x86/pmap.c b/kern/arch/x86/pmap.c
index 5cc1efe..c64a419 100644
--- a/kern/arch/x86/pmap.c
+++ b/kern/arch/x86/pmap.c
@@ -24,6 +24,7 @@
bool enable_pse(void)
{
uint32_t edx, cr4;
+
cpuid(0x1, 0x0, 0, 0, 0, &edx);
if (edx & CPUID_PSE_SUPPORT) {
cr4 = rcr4();
@@ -34,12 +35,12 @@
return 0;
}
-#define PAT_UC 0x00
-#define PAT_WC 0x01
-#define PAT_WT 0x04
-#define PAT_WP 0x05
-#define PAT_WB 0x06
-#define PAT_UCm 0x07
+#define PAT_UC 0x00
+#define PAT_WC 0x01
+#define PAT_WT 0x04
+#define PAT_WP 0x05
+#define PAT_WB 0x06
+#define PAT_UCm 0x07
static inline uint64_t mk_pat(int pat_idx, int type)
{
@@ -53,17 +54,17 @@
/* Default PAT at boot:
* 0: WB, 1: WT, 2: UC-, 3: UC, 4: WB, 5: WT, 6: UC-, 7: UC
*
- * We won't use PATs 4-7, but we'll at least enforce that they are set up
- * the way we think they are. I'd like to avoid using the PAT flag, since
- * that is also the PTE_PS (jumbo) flag. That means we can't use __PTE_PAT
- * on jumbo pages, and we'd need to be careful whenever using any unorthodox
- * types. We're better off just not using it.
+ * We won't use PATs 4-7, but we'll at least enforce that they are set
+ * up the way we think they are. I'd like to avoid using the PAT flag,
+ * since that is also the PTE_PS (jumbo) flag. That means we can't use
+ * __PTE_PAT on jumbo pages, and we'd need to be careful whenever using
+ * any unorthodox types. We're better off just not using it.
*
- * We want WB, WT, WC, and either UC or UC- for our memory types. (WT is
- * actually optional at this point). We'll use UC- instead of UC, since
- * Linux uses that for their pgprot_noncached. The UC- type is UC with the
- * ability to override to WC via MTRR. We don't use the MTRRs much yet, and
- * hopefully won't. The UC- will only matter if we do.
+ * We want WB, WT, WC, and either UC or UC- for our memory types. (WT
+ * is actually optional at this point). We'll use UC- instead of UC,
+ * since Linux uses that for their pgprot_noncached. The UC- type is UC
+ * with the ability to override to WC via MTRR. We don't use the MTRRs
+ * much yet, and hopefully won't. The UC- will only matter if we do.
*
* No one should be using the __PTE_{PAT,PCD,PWT} bits directly, and
* everyone should use things like PTE_NOCACHE. */
@@ -122,7 +123,8 @@
write_msr(IA32_MTRR_PHYSMASK6, 0);
write_msr(IA32_MTRR_PHYSMASK7, 0);
- // keeps default type to WB (06), turns MTRRs on, and turns off fixed ranges
+ // keeps default type to WB (06), turns MTRRs on, and turns off fixed
+ // ranges
write_msr(IA32_MTRR_DEF_TYPE, 0x00000806);
#endif
pat_init();
diff --git a/kern/arch/x86/pmap64.c b/kern/arch/x86/pmap64.c
index ea1924a..01d1768 100644
--- a/kern/arch/x86/pmap64.c
+++ b/kern/arch/x86/pmap64.c
@@ -37,7 +37,7 @@
segdesc_t *gdt;
pseudodesc_t gdt_pd;
-#define PG_WALK_SHIFT_MASK 0x00ff /* first byte = target shift */
+#define PG_WALK_SHIFT_MASK 0x00ff /* first byte = target shift */
#define PG_WALK_CREATE 0x0100
kpte_t *pml_walk(kpte_t *pml, uintptr_t va, int flags);
@@ -99,25 +99,31 @@
return NULL;
new_pml_kva = kpages_alloc(2 * PGSIZE, MEM_WAIT);
memset(new_pml_kva, 0, PGSIZE * 2);
- /* Might want better error handling (we're probably out of memory) */
+ /* Might want better error handling (we're probably out of
+ * memory) */
if (!new_pml_kva)
return NULL;
- /* We insert the new PT into the PML with U and W perms. Permissions on
- * page table walks are anded together (if any of them are !User, the
- * translation is !User). We put the perms on the last entry, not the
- * intermediates. */
+ /* We insert the new PT into the PML with U and W perms.
+ * Permissions on page table walks are anded together (if any of
+ * them are !User, the translation is !User). We put the perms
+ * on the last entry, not the intermediates. */
*kpte = PADDR(new_pml_kva) | PTE_P | PTE_U | PTE_W;
- /* For a dose of paranoia, we'll avoid mapping intermediate eptes when
- * we know we're using an address that should never be ept-accesible. */
+ /* For a dose of paranoia, we'll avoid mapping intermediate
+ * eptes when we know we're using an address that should never
+ * be ept-accesible. */
if (va < ULIM) {
- /* The physaddr of the new_pml is one page higher than the KPT page.
+ /* The physaddr of the new_pml is one page higher than
+ * the KPT page.
* A few other things:
* - for the same reason that we have U and X set on all
- * intermediate PTEs, we now set R, X, and W for the EPTE.
+ * intermediate PTEs, we now set R, X, and W for the
+ * EPTE.
* - All EPTEs have U perms
- * - We can't use epte_write since we're workin on intermediate
- * PTEs, and they don't have the memory type set. */
- *epte = (PADDR(new_pml_kva) + PGSIZE) | EPTE_R | EPTE_X | EPTE_W;
+ * - We can't use epte_write since we're workin on
+ * intermediate PTEs, and they don't have the memory
+ * type set. */
+ *epte = (PADDR(new_pml_kva) + PGSIZE) | EPTE_R | EPTE_X
+ | EPTE_W;
}
}
return __pml_walk(kpte2pml(*kpte), va, flags, pml_shift - BITS_PER_PML);
@@ -144,9 +150,9 @@
* pml_shift. */
static uintptr_t amt_til_aligned(uintptr_t va, int pml_shift)
{
- /* find the lower bits of va, subtract them from the shift to see what we
- * would need to add to get to the shift. va might be aligned already, and
- * we subtracted 0, so we mask off the top part again. */
+ /* find the lower bits of va, subtract them from the shift to see what
+ * we would need to add to get to the shift. va might be aligned
+ * already, and we subtracted 0, so we mask off the top part again. */
return ((1UL << pml_shift) - (va & ((1UL << pml_shift) - 1))) &
((1UL << pml_shift) - 1);
}
@@ -162,10 +168,11 @@
static kpte_t *get_next_pte(kpte_t *old_pte, kpte_t *pgdir, uintptr_t va,
int flags)
{
- /* PTEs (undereferenced) are addresses within page tables. so long as we
- * stay inside the PML, we can just advance via pointer arithmetic. if we
- * advance old_pte and it points to the beginning of a page (offset == 0),
- * we've looped outside of our original PML, and need to get a new one. */
+ /* PTEs (undereferenced) are addresses within page tables. so long as
+ * we stay inside the PML, we can just advance via pointer arithmetic.
+ * if we advance old_pte and it points to the beginning of a page
+ * (offset == 0), we've looped outside of our original PML, and need to
+ * get a new one. */
old_pte++;
if (!PGOFF(old_pte))
return pml_walk(pgdir, va, flags);
@@ -182,9 +189,11 @@
for (size_t i = 0; i < size; i += pgsize, va += pgsize,
pa += pgsize) {
- kpte = get_next_pte(kpte, pgdir, va, PG_WALK_CREATE | pml_shift);
+ kpte = get_next_pte(kpte, pgdir, va,
+ PG_WALK_CREATE | pml_shift);
assert(kpte);
- pte_write(kpte, pa, perm | (pml_shift != PML1_SHIFT ? PTE_PS : 0));
+ pte_write(kpte, pa, perm | (pml_shift != PML1_SHIFT ? PTE_PS
+ : 0));
printd("Wrote *kpte %p, for va %p to pa %p tried to cover %p\n",
*kpte, va, pa, amt_mapped);
}
@@ -264,10 +273,10 @@
{
int max_shift_possible;
if (PGOFF(va) || PGOFF(pa) || PGOFF(size))
- panic("Asked to map with bad alignment. va %p, pa %p, size %p\n", va,
- pa, size);
- /* Given the max_page_size, try and use larger pages. We'll figure out the
- * largest possible jumbo page, up to whatever we were asked for. */
+ panic("Asked to map with bad alignment. va %p, pa %p, size %p\n",
+ va, pa, size);
+ /* Given the max_page_size, try and use larger pages. We'll figure out
+ * the largest possible jumbo page, up to whatever we were asked for. */
if (pml_shift != PGSHIFT) {
max_shift_possible = max_possible_shift(va, pa);
max_shift_possible = MIN(max_shift_possible,
@@ -303,14 +312,14 @@
if (!len)
return 0;
kpte_s = &pml[PMLx(start, pml_shift)];
- /* Later, we'll loop up to and including kpte_e. Since start + len might
- * not be page aligned, we'll need to include the final kpte. If it is
- * aligned, we don't want to visit, so we subtract one so that the aligned
- * case maps to the index below its normal kpte. */
+ /* Later, we'll loop up to and including kpte_e. Since start + len
+ * might not be page aligned, we'll need to include the final kpte. If
+ * it is aligned, we don't want to visit, so we subtract one so that the
+ * aligned case maps to the index below its normal kpte. */
kpte_e = &pml[PMLx(start + len - 1, pml_shift)];
/* tracks the virt addr kpte_i works on, rounded for this PML */
kva = ROUNDDOWN(start, pgsize);
- printd("PFE, start %p PMLx(S) %d, end-inc %p PMLx(E) %d shift %d, kva %p\n",
+ printd("start %p PMLx(S) %d, end-inc %p PMLx(E) %d shift %d, kva %p\n",
start, PMLx(start, pml_shift), start + len - 1,
PMLx(start + len - 1, pml_shift), pml_shift, kva);
for (kpte_i = kpte_s; kpte_i <= kpte_e; kpte_i++, kva += pgsize) {
@@ -318,24 +327,27 @@
/* Complete only on the last level (PML1_SHIFT) or on a jumbo */
if (kpte_is_present(kpte_i) &&
(!walk_is_complete(kpte_i, pml_shift, PML1_SHIFT))) {
- /* only pass truncated end points (e.g. start may not be page
- * aligned) when we're on the first (or last) item. For the middle
- * entries, we want the subpmls to process the full range they are
- * responsible for: [kva, kva + pgsize). */
+ /* only pass truncated end points (e.g. start may not be
+ * page aligned) when we're on the first (or last) item.
+ * For the middle entries, we want the subpmls to
+ * process the full range they are responsible for:
+ * [kva, kva + pgsize). */
uintptr_t sub_start = MAX(kva, start);
size_t sub_len = MIN(start + len - sub_start,
kva + pgsize - sub_start);
- ret = __pml_for_each(kpte2pml(*kpte_i), sub_start, sub_len,
- callback, arg, pml_shift - BITS_PER_PML);
+ ret = __pml_for_each(kpte2pml(*kpte_i), sub_start,
+ sub_len, callback, arg,
+ pml_shift - BITS_PER_PML);
if (ret)
return ret;
- /* based on sub_{start,end}, we can tell if our sub visited all of
- * its PTES. */
+ /* based on sub_{start,end}, we can tell if our sub
+ * visited all of its PTES. */
if ((sub_start == kva) && (sub_len == pgsize))
visited_all_subs = TRUE;
}
- if ((ret = callback(kpte_i, kva, pml_shift, visited_all_subs, arg)))
+ if ((ret = callback(kpte_i, kva, pml_shift, visited_all_subs,
+ arg)))
return ret;
}
return 0;
@@ -352,8 +364,8 @@
* page tables, nor does it flush the TLB. */
int unmap_segment(pgdir_t pgdir, uintptr_t va, size_t size)
{
- int pt_free_cb(kpte_t *kpte, uintptr_t kva, int shift, bool visited_subs,
- void *data)
+ int pt_free_cb(kpte_t *kpte, uintptr_t kva, int shift,
+ bool visited_subs, void *data)
{
if (!kpte_is_present(kpte))
return 0;
@@ -361,15 +373,16 @@
pte_clear(kpte);
return 0;
}
- /* Never remove intermediate pages for any kernel mappings. This is
- * also important for x86 so that we don't accidentally free any of the
- * boot PMLs, which aren't two-page alloc'd from kpages_arena. */
+ /* Never remove intermediate pages for any kernel mappings.
+ * This is also important for x86 so that we don't accidentally
+ * free any of the boot PMLs, which aren't two-page alloc'd from
+ * kpages_arena. */
if (kva >= ULIM)
return 0;
- /* If we haven't visited all of our subs, we might still have some
- * mappings hanging off this page table. */
+ /* If we haven't visited all of our subs, we might still have
+ * some mappings hanging off this page table. */
if (!visited_subs) {
- kpte_t *kpte_i = kpte2pml(*kpte); /* first kpte == pml */
+ kpte_t *kpte_i = kpte2pml(*kpte);/* first kpte == pml */
/* make sure we have no PTEs in use */
for (int i = 0; i < NPTENTRIES; i++, kpte_i++) {
if (*kpte_i)
@@ -422,8 +435,8 @@
#define check_sym_va(sym, addr) \
({ \
- if ((sym) != (addr)) \
- panic("Error: " #sym " is %p, should be " #addr, sym); \
+ if ((sym) != (addr)) \
+ panic("Error: " #sym " is %p, should be " #addr, sym); \
})
static void check_syms_va(void)
@@ -459,11 +472,13 @@
boot_pgdir.eptp = 0;
gdt = KADDR(get_gdt64());
- /* We need to limit our mappings on machines that don't support 1GB pages */
+ /* We need to limit our mappings on machines that don't support 1GB
+ * pages */
max_jumbo_shift = arch_max_jumbo_page_shift();
check_syms_va();
- /* KERNBASE mapping: we already have 512 GB complete (one full PML3_REACH).
- * It's okay if we have extra, just need to make sure we reach max_paddr. */
+ /* KERNBASE mapping: we already have 512 GB complete (one full
+ * PML3_REACH). It's okay if we have extra, just need to make sure we
+ * reach max_paddr. */
if (KERNBASE + PML3_REACH < (uintptr_t)KADDR(max_paddr)) {
map_segment(boot_pgdir, KERNBASE + PML3_REACH,
max_paddr - PML3_REACH, 0x0 + PML3_REACH,
@@ -479,9 +494,9 @@
boot_kpt[PML4(UVPT)] = PADDR(boot_kpt) | PTE_USER_RO;
/* set up core0s now (mostly for debugging) */
setup_default_mtrrs(0);
- /* Our current gdt_pd (gdt64desc) is pointing to a physical address for the
- * GDT. We need to switch over to pointing to one with a virtual address,
- * so we can later unmap the low memory */
+ /* Our current gdt_pd (gdt64desc) is pointing to a physical address for
+ * the GDT. We need to switch over to pointing to one with a virtual
+ * address, so we can later unmap the low memory */
gdt_pd = (pseudodesc_t) {sizeof(segdesc_t) * SEG_COUNT - 1,
(uintptr_t)gdt};
asm volatile("lgdt %0" : : "m"(gdt_pd));
@@ -489,9 +504,10 @@
void x86_cleanup_bootmem(void)
{
- /* the boot page tables weren't alloc'd the same as other pages, so we'll
- * need to do some hackery to 'free' them. This doesn't actually free
- * anything - it just unmaps but leave 2 KPTs (4 pages) sitting around. */
+ /* the boot page tables weren't alloc'd the same as other pages, so
+ * we'll need to do some hackery to 'free' them. This doesn't actually
+ * free anything - it just unmaps but leave 2 KPTs (4 pages) sitting
+ * around. */
//unmap_segment(boot_pgdir, 0, PML3_PTE_REACH); // want to do this
boot_pgdir.kpte[0] = 0;
tlb_flush_global();
@@ -511,12 +527,13 @@
mem_walk_callback_t cb;
void *cb_arg;
};
- int trampoline_cb(kpte_t *kpte, uintptr_t kva, int shift, bool visited_subs,
- void *data)
+ int trampoline_cb(kpte_t *kpte, uintptr_t kva, int shift,
+ bool visited_subs, void *data)
{
struct tramp_package *tp = (struct tramp_package*)data;
assert(tp->cb);
- /* memwalk CBs don't know how to handle intermediates or jumbos */
+ /* memwalk CBs don't know how to handle intermediates or jumbos
+ */
if (shift != PML1_SHIFT)
return 0;
return tp->cb(tp->p, kpte, (void*)kva, tp->cb_arg);
@@ -561,7 +578,8 @@
if (memcpy_from_user(p, &pte, &u_pml[PMLx(gva, pml_shift)],
sizeof(kpte_t))) {
- warn("Buggy pml %p, tried %p\n", u_pml, &u_pml[PMLx(gva, pml_shift)]);
+ warn("Buggy pml %p, tried %p\n", u_pml,
+ &u_pml[PMLx(gva, pml_shift)]);
return 0;
}
if (walk_is_complete(&pte, pml_shift, flags))
@@ -580,8 +598,9 @@
pte = __guest_pml_walk(p, (kpte_t*)cr3, gva, shift, PML4_SHIFT);
if (!pte)
return 0;
- /* TODO: Jumbos mess with us. We need to know the shift the walk did. This
- * is a little nasty, but will work til we make Akaros more jumbo-aware. */
+ /* TODO: Jumbos mess with us. We need to know the shift the walk did.
+ * This is a little nasty, but will work til we make Akaros more
+ * jumbo-aware. */
while (pte & PTE_PS) {
shift += BITS_PER_PML;
pte = __guest_pml_walk(p, (kpte_t*)cr3, gva, shift, PML4_SHIFT);
@@ -634,21 +653,22 @@
ept = kpte_to_epte(kpt);
memset(ept, 0, PGSIZE);
- /* This bit of paranoia slows process creation a little, but makes sure that
- * there is nothing below ULIM in boot_pgdir. Any PML4 entries copied from
- * boot_pgdir (e.g. the kernel's memory) will be *shared* among all
- * processes, including *everything* under the PML4 entries reach (e.g.
- * PML4_PTE_REACH = 512 GB) and any activity would need to be synchronized.
+ /* This bit of paranoia slows process creation a little, but makes sure
+ * that there is nothing below ULIM in boot_pgdir. Any PML4 entries
+ * copied from boot_pgdir (e.g. the kernel's memory) will be *shared*
+ * among all processes, including *everything* under the PML4 entries
+ * reach (e.g. PML4_PTE_REACH = 512 GB) and any activity would need to
+ * be synchronized.
*
- * We could do this once at boot time, but that would miss out on potential
- * changes to the boot_pgdir at runtime.
+ * We could do this once at boot time, but that would miss out on
+ * potential changes to the boot_pgdir at runtime.
*
* We could also just memset that region to 0. For now, I want to catch
* whatever mappings exist, since they are probably bugs. */
for (int i = 0; i < PML4(ULIM - 1); i++)
assert(kpt[i] == 0);
- /* VPT and UVPT map the proc's page table, with different permissions. */
+ /* VPT and UVPT map the proc's page table, with different permissions.*/
kpt[PML4(VPT)] = build_kpte(PADDR(kpt), PTE_KERN_RW);
kpt[PML4(UVPT)] = build_kpte(PADDR(kpt), PTE_USER_RO);
@@ -711,7 +731,8 @@
/* We insert the same as for __pml_walk. */
*kpte = PADDR(new_pml_kva) | PTE_P | PTE_U | PTE_W;
if (va < ULIM)
- *epte = (PADDR(new_pml_kva) + PGSIZE) | EPTE_R | EPTE_X | EPTE_W;
+ *epte = (PADDR(new_pml_kva) + PGSIZE) | EPTE_R | EPTE_X
+ | EPTE_W;
}
}
diff --git a/kern/arch/x86/pmap_ops.h b/kern/arch/x86/pmap_ops.h
index 1e16a3f..3ad586d 100644
--- a/kern/arch/x86/pmap_ops.h
+++ b/kern/arch/x86/pmap_ops.h
@@ -23,23 +23,23 @@
}
/* PTE states:
- * - present: the PTE is involved in a valid page table walk, can be used
- * for some form of hardware access (read, write, user, etc), and with the
- * physaddr part pointing to a physical page.
+ * - present: the PTE is involved in a valid page table walk, can be used for
+ * some form of hardware access (read, write, user, etc), and with the
+ * physaddr part pointing to a physical page.
*
- * - mapped: the PTE is involved in some sort of mapping, e.g. a VMR. We're
- * storing something in the PTE, but it is isn't necessarily present.
- * Currently, all mapped pages should point to an actual physical page.
- * All present are mapped, but not vice versa. Mapped pages can point to a
- * real page, but with no access permissions, which is the main distinction
- * between present and mapped.
+ * - mapped: the PTE is involved in some sort of mapping, e.g. a VMR. We're
+ * storing something in the PTE, but it is isn't necessarily present.
+ * Currently, all mapped pages should point to an actual physical page. All
+ * present are mapped, but not vice versa. Mapped pages can point to a real
+ * page, but with no access permissions, which is the main distinction between
+ * present and mapped.
*
- * - paged_out: we don't actually use this yet. Since mapped vs present is
- * based on the PTE present bits, we'd need to use reserved bits in the PTE to
- * differentiate between other states. Right now, paged_out == mapped, as far
- * as the code is concerned.
+ * - paged_out: we don't actually use this yet. Since mapped vs present is
+ * based on the PTE present bits, we'd need to use reserved bits in the PTE to
+ * differentiate between other states. Right now, paged_out == mapped, as far
+ * as the code is concerned.
*
- * - unmapped: completely unused. (0 value) */
+ * - unmapped: completely unused. (0 value) */
static inline bool pte_is_present(pte_t pte)
{
return kpte_is_present(pte);
diff --git a/kern/arch/x86/process64.c b/kern/arch/x86/process64.c
index 1b7c3fc..3a227c7 100644
--- a/kern/arch/x86/process64.c
+++ b/kern/arch/x86/process64.c
@@ -11,8 +11,8 @@
static void __attribute__((noreturn)) proc_pop_hwtf(struct hw_trapframe *tf)
{
- /* for both HW and SW, note we pass an offset into the TF, beyond the fs and
- * gs bases */
+ /* for both HW and SW, note we pass an offset into the TF, beyond the fs
+ * and gs bases */
if (x86_hwtf_is_partial(tf)) {
swap_gs();
} else {
@@ -53,9 +53,9 @@
write_gsbase(tf->tf_gsbase);
write_fsbase(tf->tf_fsbase);
}
- /* We need to 0 out any registers that aren't part of the sw_tf and that we
- * won't use/clobber on the out-path. While these aren't part of the sw_tf,
- * we also don't want to leak any kernel register content. */
+ /* We need to 0 out any registers that aren't part of the sw_tf and that
+ * we won't use/clobber on the out-path. While these aren't part of the
+ * sw_tf, we also don't want to leak any kernel register content. */
asm volatile (".globl __asm_pop_swtf_start;"
"__asm_pop_swtf_start: "
"movq %0, %%rsp; "
@@ -126,18 +126,21 @@
* context, but be on a new stack. set_stack_top() doesn't really know
* about the VMCS. */
vmcs_write(HOST_RSP, pcpui->stacktop);
- /* cr2 is not part of the VMCS state; we need to save/restore it manually */
+ /* cr2 is not part of the VMCS state; we need to save/restore it
+ * manually */
lcr2(tf->tf_cr2);
vmcs_write(VM_ENTRY_INTR_INFO_FIELD, tf->tf_trap_inject);
- /* Someone may have tried poking the guest and posting an IRQ, but the IPI
- * missed (concurrent vmexit). In these cases, the 'outstanding
- * notification' bit should still be set, and we can resend the IPI. This
- * will arrive after we vmenter, since IRQs are currently disabled. */
+ /* Someone may have tried poking the guest and posting an IRQ, but the
+ * IPI missed (concurrent vmexit). In these cases, the 'outstanding
+ * notification' bit should still be set, and we can resend the IPI.
+ * This will arrive after we vmenter, since IRQs are currently disabled.
+ * */
if (test_bit(VMX_POSTED_OUTSTANDING_NOTIF, gpc->posted_irq_desc))
send_self_ipi(I_POKE_GUEST);
- /* The first time a VMCS is started after being loaded, it must be launched.
- * Subsequent starts must be resumes. Once the VMCS is cleared, we start
- * with a launch again. Note this is the VMCS, not the GPC unload. */
+ /* The first time a VMCS is started after being loaded, it must be
+ * launched. Subsequent starts must be resumes. Once the VMCS is
+ * cleared, we start with a launch again. Note this is the VMCS, not
+ * the GPC unload. */
if (gpc->should_vmresume) {
tf->tf_flags |= VMCTX_FL_VMRESUME;
} else {
@@ -145,14 +148,14 @@
gpc->should_vmresume = TRUE;
}
/* vmlaunch/resume can fail, so we need to be able to return from this.
- * Thus we can't clobber rsp via the popq style of setting the registers.
- * Likewise, we don't want to lose rbp via the clobber list.
+ * Thus we can't clobber rsp via the popq style of setting the
+ * registers. Likewise, we don't want to lose rbp via the clobber list.
*
* Partial contexts have already been launched, so we resume them. */
asm volatile (".globl __asm_pop_vmtf_start;"
"__asm_pop_vmtf_start: "
"testl $"STRINGIFY(VMCTX_FL_VMRESUME)", %c[flags](%0);"
- "pushq %%rbp; " /* save in case we fail */
+ "pushq %%rbp; " /* save in case we fail */
"movq %c[rbx](%0), %%rbx; "
"movq %c[rcx](%0), %%rcx; "
"movq %c[rdx](%0), %%rdx; "
@@ -167,12 +170,12 @@
"movq %c[r13](%0), %%r13; "
"movq %c[r14](%0), %%r14; "
"movq %c[r15](%0), %%r15; "
- "movq %c[rax](%0), %%rax; " /* clobber our *tf last */
- "jnz 1f; " /* jump if resume */
- ASM_VMX_VMLAUNCH"; " /* non-resume gets launched */
+ "movq %c[rax](%0), %%rax; " /* clobber our *tf last */
+ "jnz 1f; " /* jump if resume */
+ ASM_VMX_VMLAUNCH"; " /* non-resume gets launched*/
"jmp 2f; "
"1: "ASM_VMX_VMRESUME"; "
- "2: popq %%rbp; " /* vmlaunch failed */
+ "2: popq %%rbp; " /* vmlaunch failed */
".globl __asm_pop_vmtf_end;"
"__asm_pop_vmtf_end: "
:
@@ -195,20 +198,20 @@
[flags]"i"(offsetof(struct vm_trapframe, tf_flags))
: "cc", "memory", "rbx", "rcx", "rdx", "rsi", "rdi",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
- /* vmlaunch/resume failed. It could be for a few reasons, including things
- * like launching instead of resuming, not having a VMCS loaded, failing a
- * host-state area check, etc. Those are kernel problems.
+ /* vmlaunch/resume failed. It could be for a few reasons, including
+ * things like launching instead of resuming, not having a VMCS loaded,
+ * failing a host-state area check, etc. Those are kernel problems.
*
- * The user should not be able to trigger these problems. The user could
- * trigger a problem loading the guest-state area, such as a non-canonical
- * address for RIP. Those sorts of errors should appear to be a normal
- * vmexit with some flags set.
+ * The user should not be able to trigger these problems. The user
+ * could trigger a problem loading the guest-state area, such as a
+ * non-canonical address for RIP. Those sorts of errors should appear
+ * to be a normal vmexit with some flags set.
*
* Any failed vmlaunch/resume is likely a kernel bug, but we'll still
* reflect it to the user for debugability.
*
- * Also we should always have a non-shadow VMCS, so ZF should be 1 and we
- * can read the error register. */
+ * Also we should always have a non-shadow VMCS, so ZF should be 1 and
+ * we can read the error register. */
assert(read_flags() & FL_ZF);
tf->tf_exit_reason = EXIT_REASON_VMENTER_FAILED;
tf->tf_exit_qual = vmcs_read(VM_INSTRUCTION_ERROR);
@@ -240,32 +243,36 @@
uintptr_t stack_top, uintptr_t tls_desc)
{
struct sw_trapframe *sw_tf = &ctx->tf.sw_tf;
- /* zero the entire structure for any type, prevent potential disclosure */
+
+ /* zero the entire structure for any type, prevent potential disclosure
+ */
memset(ctx, 0, sizeof(struct user_context));
ctx->type = ROS_SW_CTX;
/* Stack pointers in x86 C functions need to be such that adding or
- * subtracting 8 will result in 16 byte alignment (AMD64 ABI), which we call
- * an odd-8-byte alignment. The reason is so that input arguments (on the
- * stack) are 16 byte aligned. The extra 8 bytes is the retaddr, pushed on
- * the stack. Compilers know they can subtract 8 to get 16 byte alignment
- * for instructions like movaps.
+ * subtracting 8 will result in 16 byte alignment (AMD64 ABI), which we
+ * call an odd-8-byte alignment. The reason is so that input arguments
+ * (on the stack) are 16 byte aligned. The extra 8 bytes is the
+ * retaddr, pushed on the stack. Compilers know they can subtract 8 to
+ * get 16 byte alignment for instructions like movaps.
*
- * However, the kernel will start contexts at 16 byte aligned stacks. This
- * is because glibc's _start (in ASM) expects this. Parlib x86's vcore
- * entry does the same.
+ * However, the kernel will start contexts at 16 byte aligned stacks.
+ * This is because glibc's _start (in ASM) expects this. Parlib x86's
+ * vcore entry does the same.
*
- * We init contexts for both an elf startup as well as vcore entry. It is
- * up to the caller (including the user) to make sure the stack is aligned
- * properly. elf.c doesn't know about these concerns, so if it messes up,
- * there's nothing we can really do, since the args are just wrong. ld will
- * fail immediately though, so we'll find out quickly. */
+ * We init contexts for both an elf startup as well as vcore entry. It
+ * is up to the caller (including the user) to make sure the stack is
+ * aligned properly. elf.c doesn't know about these concerns, so if it
+ * messes up, there's nothing we can really do, since the args are just
+ * wrong. ld will fail immediately though, so we'll find out quickly.
+ * */
sw_tf->tf_rsp = stack_top;
sw_tf->tf_rip = entryp;
sw_tf->tf_rbp = 0; /* for potential backtraces */
sw_tf->tf_mxcsr = 0x00001f80; /* x86 default mxcsr */
sw_tf->tf_fpucw = 0x037f; /* x86 default FP CW */
- /* Coupled closely with user's entry.S. id is the vcoreid, which entry.S
- * uses to determine what to do. vcoreid == 0 is the main core/context. */
+ /* Coupled closely with user's entry.S. id is the vcoreid, which
+ * entry.S uses to determine what to do. vcoreid == 0 is the main
+ * core/context. */
sw_tf->tf_rbx = vcoreid;
sw_tf->tf_fsbase = tls_desc;
proc_secure_ctx(ctx);
@@ -286,8 +293,8 @@
/* Always 1: interrupts */
tf->tf_rflags |= FL_IF;
/* Always 0: IOPL must be set to 0. VM (virtual 8086) probably doesn't
- * matter - SDM says it can't get modified via iret anyways. VIF and VIP
- * are also virtual-8086 mode stuff. Supposedly NT is settable by
+ * matter - SDM says it can't get modified via iret anyways. VIF and
+ * VIP are also virtual-8086 mode stuff. Supposedly NT is settable by
* userspace, but there's no good reason for it. Rather be paranoid. */
tf->tf_rflags &= ~(FL_IOPL_MASK | FL_VM | FL_NT | FL_VIF | FL_VIP);
tf->tf_rflags |= FL_RSVD_1;
@@ -301,26 +308,26 @@
enforce_user_canon(&tf->tf_fsbase);
enforce_user_canon(&tf->tf_rip);
enforce_user_canon(&tf->tf_rsp);
- /* The kernel doesn't actually load the mxcsr or the fpucw, but we can still
- * sanitize it in case we ever do load it. */
+ /* The kernel doesn't actually load the mxcsr or the fpucw, but we can
+ * still sanitize it in case we ever do load it. */
tf->tf_mxcsr &= MXCSR_RSVD_0;
x86_swtf_clear_partial(tf);
}
static void proc_secure_vmtf(struct vm_trapframe *tf)
{
- /* The user can say whatever it wants for the bulk of the TF. If they mess
- * up something in the guest-area, it'll be treated like a vmexit. There
- * are a few things in the TF that we use on the kernel side.
+ /* The user can say whatever it wants for the bulk of the TF. If they
+ * mess up something in the guest-area, it'll be treated like a vmexit.
+ * There are a few things in the TF that we use on the kernel side.
*
- * If guest_pcoreid is bad (not a guest_pcore), we'll fail to load the GPC
- * and reflect the fault to userspace.
+ * If guest_pcoreid is bad (not a guest_pcore), we'll fail to load the
+ * GPC and reflect the fault to userspace.
*
- * Regarding tf_flags, some are informational for the user, some are used
- * for our own use in the kernel.
+ * Regarding tf_flags, some are informational for the user, some are
+ * used for our own use in the kernel.
* - VMCTX_FL_PARTIAL: We clear this below
- * - VMCTX_FL_VMRESUME: Used to temporarily carry a bool in pop_vmtf, but we
- * never trust the value in the VM TF.
+ * - VMCTX_FL_VMRESUME: Used to temporarily carry a bool in pop_vmtf,
+ * but we never trust the value in the VM TF.
* These are write-only from the kernel and passed to the user:
* - VMCTX_FL_HAS_FAULT
* - VMCTX_FL_EPT_VMR_BACKED */
@@ -340,8 +347,9 @@
proc_secure_vmtf(&ctx->tf.vm_tf);
break;
default:
- /* If we aren't another ctx type, we're assuming (and forcing) a HW ctx.
- * If this is somehow fucked up, userspace should die rather quickly. */
+ /* If we aren't another ctx type, we're assuming (and forcing) a
+ * HW ctx. If this is somehow fucked up, userspace should die
+ * rather quickly. */
ctx->type = ROS_HW_CTX;
proc_secure_hwtf(&ctx->tf.hw_tf);
}
diff --git a/kern/arch/x86/rdtsc_test.c b/kern/arch/x86/rdtsc_test.c
index 7774f8d..076c7b5 100644
--- a/kern/arch/x86/rdtsc_test.c
+++ b/kern/arch/x86/rdtsc_test.c
@@ -6,8 +6,8 @@
*
* The idea behind this was that the traditional style of using rdtsc was to
* call:
- * cpuid;
- * rdtsc;
+ * cpuid;
+ * rdtsc;
* since rdtsc does no serialization (meaning later instructions can get
* executed before it, or vice versa). While this first cpuid isn't a big deal,
* doing this in pairs means reading the end time also measures cpuid. This is
@@ -16,11 +16,11 @@
* If we use rdtscp for the end call, we can put the cpuid after rdtscp, thereby
* not including cpuid's overhead (and variability) in our measurement. That's
* where the intel doc ends. For more info, check out:
- * http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/ia-32-ia-64-benchmark-code-execution-paper.pdf
+ * http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/ia-32-ia-64-benchmark-code-execution-paper.pdf
*
* Note that the Intel SDM says you can serialize rdtsc with lfence, such as:
- * lfence;
- * rdtsc;
+ * lfence;
+ * rdtsc;
* Linux uses this (mfence on amd64, lfence on intel). For more info:
* https://lkml.org/lkml/2008/1/2/353
* Note this use of lfence before rdtsc is supposedly serializing any
@@ -28,17 +28,17 @@
* while lfence only serializes memory (and not arbitrary instructions), in
* actual hardware there is no point to reorder non-memory instructions around
* rdtsc:
- * http://stackoverflow.com/questions/12631856/difference-between-rdtscp-rdtsc-memory-and-cpuid-rdtsc
- * (look for janneb's response to questions about his comment)
+ * http://stackoverflow.com/questions/12631856/difference-between-rdtscp-rdtsc-memory-and-cpuid-rdtsc
+ * (look for janneb's response to questions about his comment)
*
* Its not clear from what anyone writes as to whether or not you need to
* serialize below rdtsc. Supposedly, you'd need cpuid/lfence on both sides of
* rdtsc to prevent reordering in both directions. Andi Kleen does this in a
* few places
- * https://lkml.org/lkml/2008/1/7/276
+ * https://lkml.org/lkml/2008/1/7/276
* though other places in the kernel suggest it is unnecessary (at least for
* loads:
- * http://lxr.linux.no/#linux+v3.8.2/arch/x86/kvm/x86.c#L1258
+ * http://lxr.linux.no/#linux+v3.8.2/arch/x86/kvm/x86.c#L1258
* The intel docs don't mention it (otherwise we would be told to use
* lfence;rdtsc;lfence). The howto this file is based off of didn't mention it
* either, other than to say rdtscp needs to serialize from below. AFAIK,
@@ -56,12 +56,12 @@
*
* CASE START ASM END ASM
* ---------------------------------------------------
- * case 0: cpuid;rdtsc; cpuid;rdtscp;
- * case 1: cpuid;rdtsc; rdtscp;cpuid; (or rdtscp;lfence)
- * case 2: lfence;rdtsc; rdtscp;cpuid; (or rdtscp;lfence)
- * case 3: rdtscp; rdtscp;cpuid; (or rdtscp;lfence)
- * case 4: rdtscp; rdtscp;
- * case 5: lfence;rdtsc; lfence;rdtsc;
+ * case 0: cpuid;rdtsc; cpuid;rdtscp;
+ * case 1: cpuid;rdtsc; rdtscp;cpuid; (or rdtscp;lfence)
+ * case 2: lfence;rdtsc; rdtscp;cpuid; (or rdtscp;lfence)
+ * case 3: rdtscp; rdtscp;cpuid; (or rdtscp;lfence)
+ * case 4: rdtscp; rdtscp;
+ * case 5: lfence;rdtsc; lfence;rdtsc;
* case 6: lfence;rdtsc;lfence; lfence;rdtsc;lfence;
*
* Note I only ran these a couple times, with 1000x10000, and I did notice some
@@ -81,8 +81,8 @@
* case 5: most lines 3 var, 4 max dev, 28 min, 2 var 4 max dev overall
* case 6: most lines 3 var, 4 max dev, 44 min, 2 var 4 max dev overall
*
- * case 1-3: cpuid vs lfence: both seem to work the same and have no effect
- * (since they are outside the loop)
+ * case 1-3: cpuid vs lfence: both seem to work the same and have no effect
+ * (since they are outside the loop)
*
* So running with rdtscp for both start and stop (case 3 and 4) had the least
* amount of variance (both per line and total). When these cases have had any
@@ -139,7 +139,7 @@
* potentially underestimating by a few cycles/ticks. One thing we can do is
* try to see what the resolution is of the different methods.
*
- * case 1: cpuid;rdtsc; rdtscp;cpuid; (or rdtscp;lfence)
+ * case 1: cpuid;rdtsc; rdtscp;cpuid; (or rdtscp;lfence)
* -------------------
* loop_size:0 >>>> variance(cycles): 3; max_deviation: 8; min time: 44
* loop_size:1 >>>> variance(cycles): 6; max_deviation: 28; min time: 44
@@ -154,7 +154,7 @@
* loop_size:10 >>>> variance(cycles): 9; max_deviation: 36; min time: 52
* loop_size:11 >>>> variance(cycles): 16; max_deviation: 64; min time: 56
*
- * case 4: rdtscp; rdtscp;
+ * case 4: rdtscp; rdtscp;
* -------------------
* loop_size:0 >>>> variance(cycles): 1; max_deviation: 20; min time: 32
* loop_size:1 >>>> variance(cycles): 12; max_deviation: 36; min time: 36
@@ -166,7 +166,7 @@
* loop_size:7 >>>> variance(cycles): 8; max_deviation: 32; min time: 44
* loop_size:8 >>>> variance(cycles): 10; max_deviation: 48; min time: 48
*
- * case 5: lfence;rdtsc; lfence;rdtsc;
+ * case 5: lfence;rdtsc; lfence;rdtsc;
* -------------------
* loop_size:0 >>>> variance(cycles): 3; max_deviation: 12; min time: 28
* loop_size:1 >>>> variance(cycles): 8; max_deviation: 28; min time: 32
@@ -190,12 +190,12 @@
* some extra tsc-related code above the measurement (an accidental asm
* insertion of lfence;rdtsc above reading the start time) and with no work in
* between:
- * case 1: no effect
- * case 2: no effect
+ * case 1: no effect
+ * case 2: no effect
* These both had some form of serialization (cpuid or lfence) above the rdtsc
* command. But when we try using just rdtscp (with no extra serialization:)
- * case 3, normal: lines 0 var, 0 max dev, 32 min, 0 var 0 max dev
- * case 3, extras: lines 2-3 var, 4 max dev, 28 min, 2 var 4 max dev
+ * case 3, normal: lines 0 var, 0 max dev, 32 min, 0 var 0 max dev
+ * case 3, extras: lines 2-3 var, 4 max dev, 28 min, 2 var 4 max dev
* Similar deal with case 4. Lots of 28s and deviation. It looks like some
* times the rdtsc diff is only 28, and others 32 (hence the deviation of 4).
* Note this means the measurement interval is *lower*, which means the code was
@@ -204,33 +204,33 @@
* code *slower*)? Or is it because the previous command was rdtsc, which might
* 'speed up' subsequent rdtscs. I tried it again, with a little work between
* the unused TSC read and the start tsc read:
- * case 3, more crap : lines 2-3 var, 4 max dev, 28 min, 2 var 4 max dev
+ * case 3, more crap : lines 2-3 var, 4 max dev, 28 min, 2 var 4 max dev
* So no real change from adding minor code in between. What about adding an
* lfence above the rdtscp (so it is almost exactly like case 2)?
* Our assembly code now looks like:
- * lfence;
- * rdtsc;
- * mov %edx, (memory); // these get overwritten
- * mov %eax, (memory); // these get overwritten
+ * lfence;
+ * rdtsc;
+ * mov %edx, (memory); // these get overwritten
+ * mov %eax, (memory); // these get overwritten
*
- * mov (memory), %eax; // misc work (variable = i + j)
- * add %esi, %eax; // misc work (variable = i + j)
- * mov %eax, (memory); // misc work (variable = i + j)
+ * mov (memory), %eax; // misc work (variable = i + j)
+ * add %esi, %eax; // misc work (variable = i + j)
+ * mov %eax, (memory); // misc work (variable = i + j)
*
- * lfence;
- * rdtscp; // this is the real start measurement
- * mov %edx, (memory);
- * mov %eax, (memory);
+ * lfence;
+ * rdtscp; // this is the real start measurement
+ * mov %edx, (memory);
+ * mov %eax, (memory);
*
* // no extra work here
*
- * rdtscp; // this is the real end measurement
- * mov %edx, (memory);
- * mov %eax, (memory);
- * cpuid; // this is case 3, with sync after
+ * rdtscp; // this is the real end measurement
+ * mov %edx, (memory);
+ * mov %eax, (memory);
+ * cpuid; // this is case 3, with sync after
*
* Even with this extra lfence, case 3-style still shows numbers like:
- * case 3, added crap: lines 2-3 var, 4 max dev, 28 min, 2 var 4 max dev
+ * case 3, added crap: lines 2-3 var, 4 max dev, 28 min, 2 var 4 max dev
* So either rdtscp is somehow faster due to internal-processor-caching (a
* previous rdtsc makes the next rdtscp somewhat faster sometimes, including
* after some instructions and an lfence), or the baseline case of no variation
@@ -277,7 +277,7 @@
* support in the BIOS. Specifically, faking USB keyboards and mice (making
* them look like PS/2) and USB mass storage (making them look like a HDD) all
* lead to an increase in SMIs. For more info, check out:
- * https://rt.wiki.kernel.org/index.php/HOWTO:_Build_an_RT-application
+ * https://rt.wiki.kernel.org/index.php/HOWTO:_Build_an_RT-application
* It is not sufficient to merely not use things like the USB mass storage. It
* needs to be disabled in the BIOS. At least, this is true on my nehalem. A
* while back, we had an issue with microbenchmarks taking 10% longer if you
@@ -330,69 +330,71 @@
for (j = 0; j < loop_bound; j++) {
for (i = 0; i < stat_size; i++) {
variable = 0;
- /* starting side, i want to make sure we always copy out to memory
- * (stack), instead of sometimes using registers (and other times
- * not). if you use =a, for instance, with no work, the compiler
- * will use esi and edi to store start_high and _low.
+ /* starting side, i want to make sure we always copy out
+ * to memory (stack), instead of sometimes using
+ * registers (and other times not). if you use =a, for
+ * instance, with no work, the compiler will use esi and
+ * edi to store start_high and _low.
*
- * The same concern is probably unnecessary at the end, but it might
- * keep the compiler from reserving the use of those registers.*/
+ * The same concern is probably unnecessary at the end,
+ * but it might keep the compiler from reserving the use
+ * of those registers.*/
#if 0 /* extra crap before the measurement code */
asm volatile (
- "lfence;"
- "rdtsc;"
- "mov %%edx, %0;"
- "mov %%eax, %1;"
- : "=m" (dummy_high), "=m" (dummy_low)
- :
- : "%eax", "%edx");
+ "lfence;"
+ "rdtsc;"
+ "mov %%edx, %0;"
+ "mov %%eax, %1;"
+ : "=m" (dummy_high), "=m" (dummy_low)
+ :
+ : "%eax", "%edx");
variable = i + j;
#endif
asm volatile (
- "lfence;"
- "rdtsc;"
- "mov %%edx, %0;"
- "mov %%eax, %1;"
- : "=m" (start_high), "=m" (start_low)
- :
- : "%eax", "%edx");
+ "lfence;"
+ "rdtsc;"
+ "mov %%edx, %0;"
+ "mov %%eax, %1;"
+ : "=m" (start_high), "=m" (start_low)
+ :
+ : "%eax", "%edx");
#if 0 /* types of start time measurements */
asm volatile (
"cpuid;"
"rdtsc;"
- "mov %%edx, %0;"
- "mov %%eax, %1;"
- : "=m" (start_high), "=m" (start_low)
- :
- : "%eax", "%ebx", "%ecx", "%edx");
+ "mov %%edx, %0;"
+ "mov %%eax, %1;"
+ : "=m" (start_high), "=m" (start_low)
+ :
+ : "%eax", "%ebx", "%ecx", "%edx");
asm volatile (
- "lfence;"
+ "lfence;"
"rdtsc;"
- "mov %%edx, %0;"
- "mov %%eax, %1;"
- : "=m" (start_high), "=m" (start_low)
- :
- : "%eax", "%edx");
+ "mov %%edx, %0;"
+ "mov %%eax, %1;"
+ : "=m" (start_high), "=m" (start_low)
+ :
+ : "%eax", "%edx");
asm volatile (
- "lfence;"
+ "lfence;"
"rdtsc;"
- "lfence;"
- "mov %%edx, %0;"
- "mov %%eax, %1;"
- : "=m" (start_high), "=m" (start_low)
- :
- : "%eax", "%edx");
+ "lfence;"
+ "mov %%edx, %0;"
+ "mov %%eax, %1;"
+ : "=m" (start_high), "=m" (start_low)
+ :
+ : "%eax", "%edx");
asm volatile(
"rdtscp;"
- "mov %%edx, %0;"
- "mov %%eax, %1;"
- : "=m" (start_high), "=m" (start_low)
- :
- : "%eax", "%ecx", "%edx");
+ "mov %%edx, %0;"
+ "mov %%eax, %1;"
+ : "=m" (start_high), "=m" (start_low)
+ :
+ : "%eax", "%ecx", "%edx");
#endif
/* call the function to measure here */
@@ -410,65 +412,66 @@
"rdtsc;"
"mov %%edx, %0;"
"mov %%eax, %1;"
- : "=m" (end_high), "=m" (end_low)
- :
- : "%eax", "%edx");
+ : "=m" (end_high), "=m" (end_low)
+ :
+ : "%eax", "%edx");
#if 0 /* types of end time measurements */
asm volatile("cpuid;"
"rdtsc;"
"mov %%edx, %0;"
"mov %%eax, %1;"
- : "=m" (end_high), "=m" (end_low)
- :
- : "%eax", "%ebx", "%ecx", "%edx");
+ : "=m" (end_high), "=m" (end_low)
+ :
+ : "%eax", "%ebx", "%ecx", "%edx");
asm volatile("lfence;"
"rdtsc;"
"mov %%edx, %0;"
"mov %%eax, %1;"
- : "=m" (end_high), "=m" (end_low)
- :
- : "%eax", "%edx");
+ : "=m" (end_high), "=m" (end_low)
+ :
+ : "%eax", "%edx");
asm volatile("lfence;"
"rdtsc;"
"lfence;"
"mov %%edx, %0;"
"mov %%eax, %1;"
- : "=m" (end_high), "=m" (end_low)
- :
- : "%eax", "%edx");
+ : "=m" (end_high), "=m" (end_low)
+ :
+ : "%eax", "%edx");
asm volatile(
"rdtscp;"
"mov %%edx, %0;"
"mov %%eax, %1;"
- : "=m" (end_high), "=m" (end_low)
- :
- : "%eax", "%ecx", "%edx");
+ : "=m" (end_high), "=m" (end_low)
+ :
+ : "%eax", "%ecx", "%edx");
asm volatile(
"rdtscp;"
"lfence;"
"mov %%edx, %0;"
"mov %%eax, %1;"
- : "=m" (end_high), "=m" (end_low)
- :
- : "%eax", "%ecx", "%edx");
+ : "=m" (end_high), "=m" (end_low)
+ :
+ : "%eax", "%ecx", "%edx");
asm volatile(
"rdtscp;"
"mov %%edx, %0;"
"mov %%eax, %1;"
"cpuid;"
- : "=m" (end_high), "=m" (end_low)
- :
- : "%eax", "%ebx", "%ecx", "%edx");
+ : "=m" (end_high), "=m" (end_low)
+ :
+ : "%eax", "%ebx", "%ecx", "%edx");
#endif
start = ( ((uint64_t)start_high << 32) | start_low );
end = ( ((uint64_t)end_high << 32) | end_low );
if ( (int64_t)(end - start) < 0) {
- printk("CRITICAL ERROR IN TAKING THE TIME!!!!!!\n"
- "loop(%d) stat(%d) start = %llu, end = %llu, "
- "variable = %u\n", j, i, start, end, variable);
+ printk("CRITICAL ERROR IN TAKING THE TIME!!!!\n"
+ "loop(%d) stat(%d) start = %llu, "
+ "end = %llu, variable = %u\n", j, i,
+ start, end, variable);
times[j][i] = 0;
} else {
times[j][i] = end - start;
@@ -483,6 +486,7 @@
{
int i;
uint64_t acc = 0, previous = 0, temp_var = 0;
+
for (i = 0; i < size; i++) {
if (acc < previous)
goto overflow;
@@ -519,6 +523,7 @@
uint64_t *min_values;
uint64_t max_dev = 0, min_time = 0, max_time = 0, prev_min = 0;
uint64_t tot_var = 0, max_dev_all = 0, var_of_vars = 0, var_of_mins = 0;
+
loop_bound = loop_bound ?: LOOP_BOUND_DEF;
stat_size = stat_size ?: STAT_SIZE_DEF;
@@ -581,8 +586,8 @@
tot_var += variances[j];
printk("loop_size:%d >>>> variance(cycles): %llu; "
- "max_deviation: %llu; min time: %llu\n", j, variances[j],
- max_dev, min_time);
+ "max_deviation: %llu; min time: %llu\n", j, variances[j],
+ max_dev, min_time);
prev_min = min_time;
}
@@ -655,110 +660,111 @@
start = read_tsc_serialized();
for (int i = 0; i < 1000; i++) {
asm volatile ("addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- "addl $1, %%eax;"
- : : : "eax", "cc");
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ "addl $1, %%eax;"
+ : : : "eax", "cc");
}
end = read_tsc_serialized();
end = end - start - __proc_global_info.tsc_overhead;
- printk("%llu (100,000) ticks passed, run twice to load the icache\n", end);
+ printk("%llu (100,000) ticks passed, run twice to load the icache\n",
+ end);
enable_irqsave(&irq_state);
}
@@ -809,7 +815,7 @@
size_t total = 0;
size_t max = 0;
- deadline += pmc_cycles();
+ deadline += pmc_cycles();
enable_irq();
do {
total++;
diff --git a/kern/arch/x86/ros/cpu_feat.h b/kern/arch/x86/ros/cpu_feat.h
index 2ecf9b1..1572085 100644
--- a/kern/arch/x86/ros/cpu_feat.h
+++ b/kern/arch/x86/ros/cpu_feat.h
@@ -10,11 +10,11 @@
#pragma once
-#define CPU_FEAT_X86_VENDOR_INTEL (__CPU_FEAT_ARCH_START + 0)
-#define CPU_FEAT_X86_VENDOR_AMD (__CPU_FEAT_ARCH_START + 1)
-#define CPU_FEAT_X86_FXSR (__CPU_FEAT_ARCH_START + 2)
-#define CPU_FEAT_X86_XSAVE (__CPU_FEAT_ARCH_START + 3)
-#define CPU_FEAT_X86_XSAVEOPT (__CPU_FEAT_ARCH_START + 4)
-#define CPU_FEAT_X86_FSGSBASE (__CPU_FEAT_ARCH_START + 5)
-#define CPU_FEAT_X86_MWAIT (__CPU_FEAT_ARCH_START + 6)
-#define __NR_CPU_FEAT (__CPU_FEAT_ARCH_START + 64)
+#define CPU_FEAT_X86_VENDOR_INTEL (__CPU_FEAT_ARCH_START + 0)
+#define CPU_FEAT_X86_VENDOR_AMD (__CPU_FEAT_ARCH_START + 1)
+#define CPU_FEAT_X86_FXSR (__CPU_FEAT_ARCH_START + 2)
+#define CPU_FEAT_X86_XSAVE (__CPU_FEAT_ARCH_START + 3)
+#define CPU_FEAT_X86_XSAVEOPT (__CPU_FEAT_ARCH_START + 4)
+#define CPU_FEAT_X86_FSGSBASE (__CPU_FEAT_ARCH_START + 5)
+#define CPU_FEAT_X86_MWAIT (__CPU_FEAT_ARCH_START + 6)
+#define __NR_CPU_FEAT (__CPU_FEAT_ARCH_START + 64)
diff --git a/kern/arch/x86/ros/mmu64.h b/kern/arch/x86/ros/mmu64.h
index d8970fc..c896b1b 100644
--- a/kern/arch/x86/ros/mmu64.h
+++ b/kern/arch/x86/ros/mmu64.h
@@ -160,13 +160,13 @@
/* The kernel needs to be loaded in the top 2 GB of memory, since we compile it
* with -mcmodel=kernel (helps with relocations). We're actually loading it in
* the top 1 GB. */
-#define KERN_LOAD_ADDR 0xffffffffc0000000
+#define KERN_LOAD_ADDR 0xffffffffc0000000
/* Static kernel mappings */
#define APIC_SIZE 0x100000
#define IOAPIC_BASE (KERN_LOAD_ADDR - APIC_SIZE)
/* This is the range of the dynamic virtual mappings. */
-#define KERN_DYN_TOP 0xffffffff80000000
-#define KERN_DYN_BOT 0xfffffff000000000
+#define KERN_DYN_TOP 0xffffffff80000000
+#define KERN_DYN_BOT 0xfffffff000000000
/* Virtual page table. Every PML4 has a PTE at the slot (PML4(VPT))
* corresponding to VPT that points to that PML4's base. In essence, the 512
@@ -183,7 +183,7 @@
* PML4 (using PML3(va)), say 9 bits = "9X". The VA 9v9v9v9X000 will map to
* that PML3. */
#define VPT_TOP 0xffffff0000000000
-#define VPT (VPT_TOP - PML4_PTE_REACH)
+#define VPT (VPT_TOP - PML4_PTE_REACH)
/* Helper to return the current outer pgdir via the VPT mapping. */
#define PML4_VIA_VPT (VPT + ((VPT & 0x0000ffffffffffff) >> 9) + \
((VPT & 0x0000ffffffffffff) >> 18) + \
@@ -192,11 +192,11 @@
/* Top of the kernel virtual mapping area (KERNBASE) */
#define KERN_VMAP_TOP (VPT)
/* Base of the physical memory map. This maps from 0 physical to max_paddr */
-#define KERNBASE 0xffff800000000000
+#define KERNBASE 0xffff800000000000
/* Highest user address: 0x00007fffffffffff: 1 zero, 47 ones, sign extended.
* From here down to UWLIM is User Read-only */
-#define ULIM 0x0000800000000000
+#define ULIM 0x0000800000000000
/* Same as VPT but read-only for users */
#define UVPT (ULIM - PML4_PTE_REACH)
/* Arbitrary boundary between the break and the start of
@@ -231,7 +231,7 @@
#define PML3_SHIFT 30
#define PML2_SHIFT 21
#define PML1_SHIFT 12
-#define BITS_PER_PML 9
+#define BITS_PER_PML 9
/* PTE reach is the amount of VM an entry can map, either as a jumbo or as
* further page tables. I'd like to write these as shifts, but I can't please
@@ -260,7 +260,7 @@
#define PGSHIFT PML1_SHIFT
#define PGSIZE PML1_PTE_REACH
#define LA2PPN(la) ((uintptr_t)(la) >> PGSHIFT)
-#define PTE2PPN(pte) LA2PPN(pte)
+#define PTE2PPN(pte) LA2PPN(pte)
#define PGOFF(la) ((uintptr_t)(la) & (PGSIZE - 1))
#define NPTENTRIES 512
@@ -287,7 +287,7 @@
#define __PTE_JPAT (1 << 12) /* Jumbo PAT */
#define PTE_XD (1 << 63) /* Execute disabled */
#define PTE_NOCACHE (__PTE_PWT | __PTE_PCD)
-#define PTE_WRITECOMB (__PTE_PCD)
+#define PTE_WRITECOMB (__PTE_PCD)
/* Permissions fields and common access modes. These should be read as 'just
* kernel or user too' and 'RO or RW'. USER_RO means read-only for everyone. */
@@ -339,39 +339,39 @@
/* 64 bit code segment. This is for long mode, no compatibility. If we want
* to support 32 bit apps later, we'll want to adjust this. */
#define SEG_CODE_64(dpl) \
- .word 0, 0; \
- .byte 0; \
- .byte (((1/*p*/) << 7) | ((dpl) << 5) | 0x18 | ((0/*c*/) << 2)); \
- .byte (((0/*d*/) << 6) | ((1/*l*/) << 5)); \
+ .word 0, 0; \
+ .byte 0; \
+ .byte (((1/*p*/) << 7) | ((dpl) << 5) | 0x18 | ((0/*c*/) << 2)); \
+ .byte (((0/*d*/) << 6) | ((1/*l*/) << 5)); \
.byte 0;
/* 64 bit data segment. These are pretty much completely ignored (except if we
* use them for fs/gs, or compatibility mode */
#define SEG_DATA_64(dpl) \
- .word 0xffff, 0; \
- .byte 0; \
- .byte (0x92 | ((dpl) << 5)); \
- .byte 0x8f; \
+ .word 0xffff, 0; \
+ .byte 0; \
+ .byte (0x92 | ((dpl) << 5)); \
+ .byte 0x8f; \
.byte 0;
/* System segments (TSS/LDT) are twice as long as usual (16 bytes). */
#define SEG_SYS_64(type, base, lim, dpl) \
- .word ((lim) & 0xffff); \
- .word ((base) & 0xffff); \
- .byte (((base) >> 16) & 0xff); \
- .byte ((1 << 7) | ((dpl) << 5) | (type)); \
- .byte (((1/*g*/) << 7) | (((lim) >> 16) & 0xf)); \
- .byte (((base) >> 24) & 0xff); \
- .quad ((base) >> 32); \
+ .word ((lim) & 0xffff); \
+ .word ((base) & 0xffff); \
+ .byte (((base) >> 16) & 0xff); \
+ .byte ((1 << 7) | ((dpl) << 5) | (type)); \
+ .byte (((1/*g*/) << 7) | (((lim) >> 16) & 0xf)); \
+ .byte (((base) >> 24) & 0xff); \
+ .quad ((base) >> 32); \
.quad 0;
/* Default segment (32 bit style). Would work for fs/gs, if needed */
#define SEG(type, base, lim) \
- .word (((lim) >> 12) & 0xffff); \
- .word ((base) & 0xffff); \
- .byte (((base) >> 16) & 0xff); \
- .byte (0x90 | (type)); \
- .byte (0xC0 | (((lim) >> 28) & 0xf)); \
+ .word (((lim) >> 12) & 0xffff); \
+ .word ((base) & 0xffff); \
+ .byte (((base) >> 16) & 0xff); \
+ .byte (0x90 | (type)); \
+ .byte (0xC0 | (((lim) >> 28) & 0xf)); \
.byte (((base) >> 24) & 0xff)
#else // not __ASSEMBLER__
@@ -399,16 +399,16 @@
unsigned sd_base_15_0 : 16; /* Low bits of segment base address */
unsigned sd_base_23_16 : 8; /* Middle bits of segment base address */
unsigned sd_type : 4; /* Segment type (see STS_ constants) */
- unsigned sd_s : 1; /* 0 = system, 1 = application */
+ unsigned sd_s : 1; /* 0 = system, 1 = application */
unsigned sd_dpl : 2; /* Descriptor Privilege Level */
- unsigned sd_p : 1; /* Present */
+ unsigned sd_p : 1; /* Present */
unsigned sd_lim_19_16 : 4; /* High bits of segment limit */
- unsigned sd_avl : 1; /* Unused (available for software use) */
+ unsigned sd_avl : 1; /* Unused (available for software ) */
unsigned sd_rsv2 : 2; /* Reserved */
- unsigned sd_g : 1; /* Granularity: limit scaled by 4K when set */
+ unsigned sd_g : 1; /* Granularity: limit scaled by 4K when set */
unsigned sd_base_31_24 : 8; /* 24-31 bits of segment base address */
unsigned sd_base_63_32; /* top 32 bits of the base */
- unsigned sd_reserved; /* some parts must be zero, just zero it all */
+ unsigned sd_reserved; /* some parts must be zero, just zero it all */
};
typedef struct x86_sysseg64 syssegdesc_t;
@@ -432,36 +432,36 @@
/* 64 bit task state segment (AMD 2:12.2.5) */
typedef struct taskstate {
- uint32_t ts_rsv1; /* reserved / ignored */
- uint64_t ts_rsp0; /* stack ptr in ring 0 */
- uint64_t ts_rsp1; /* stack ptr in ring 1 */
- uint64_t ts_rsp2; /* stack ptr in ring 2 */
- uint64_t ts_rsv2; /* reserved / ignored */
- uint64_t ts_ist1; /* IST stacks: unconditional rsp */
- uint64_t ts_ist2; /* check AMD 2:8.9.4 for info */
- uint64_t ts_ist3;
- uint64_t ts_ist4;
- uint64_t ts_ist5;
- uint64_t ts_ist6;
- uint64_t ts_ist7;
- uint64_t ts_rsv3; /* reserved / ignored */
- uint16_t ts_rsv4; /* reserved / ignored */
- uint16_t ts_iobm; /* IO base map (offset) */
+ uint32_t ts_rsv1; /* reserved / ignored */
+ uint64_t ts_rsp0; /* stack ptr in ring 0 */
+ uint64_t ts_rsp1; /* stack ptr in ring 1 */
+ uint64_t ts_rsp2; /* stack ptr in ring 2 */
+ uint64_t ts_rsv2; /* reserved / ignored */
+ uint64_t ts_ist1; /* IST: unconditional rsp */
+ uint64_t ts_ist2; /* check AMD 2:8.9.4 for info */
+ uint64_t ts_ist3;
+ uint64_t ts_ist4;
+ uint64_t ts_ist5;
+ uint64_t ts_ist6;
+ uint64_t ts_ist7;
+ uint64_t ts_rsv3; /* reserved / ignored */
+ uint16_t ts_rsv4; /* reserved / ignored */
+ uint16_t ts_iobm; /* IO base map (offset) */
} __attribute__((packed)) taskstate_t;
/* 64 bit gate descriptors for interrupts and traps */
typedef struct Gatedesc {
unsigned gd_off_15_0 : 16; /* low 16 bits of offset in segment */
unsigned gd_ss : 16; /* segment selector */
- unsigned gd_ist : 3; /* interrupt stack table selector (0 = none) */
+ unsigned gd_ist : 3; /* interrupt stack table selector (0 = none) */
unsigned gd_rsv1 : 5; /* ignored */
unsigned gd_type : 4; /* type(STS_{TG,IG32,TG32}) */
- unsigned gd_s : 1; /* must be 0 (system) */
- unsigned gd_dpl : 2; /* DPL - highest ring allowed to use this */
- unsigned gd_p : 1; /* Present */
+ unsigned gd_s : 1; /* must be 0 (system) */
+ unsigned gd_dpl : 2; /* DPL - highest ring allowed to use this */
+ unsigned gd_p : 1; /* Present */
unsigned gd_off_31_16 : 16; /* 16-31 bits of offset in segment */
unsigned gd_off_63_32; /* top 32 bits of offset */
- unsigned gd_rsv2; /* reserved / unsused */
+ unsigned gd_rsv2; /* reserved / unsused */
} gatedesc_t;
/* Set up an IST-capable 64 bit interrupt/trap gate descriptor. IST selects a
@@ -469,17 +469,17 @@
* unconditionally when we hit this gate - regardless of privelege change. */
#define SETGATE64(gate, istrap, sel, off, dpl, ist) \
{ \
- (gate).gd_off_15_0 = (uintptr_t) (off) & 0xffff; \
- (gate).gd_ss = (sel); \
- (gate).gd_ist = (ist); \
- (gate).gd_rsv1 = 0; \
- (gate).gd_type = (istrap) ? STS_TG32 : STS_IG32; \
- (gate).gd_s = 0; \
- (gate).gd_dpl = (dpl); \
- (gate).gd_p = 1; \
- (gate).gd_off_31_16 = (uintptr_t) (off) >> 16; \
- (gate).gd_off_63_32 = (uintptr_t) (off) >> 32; \
- (gate).gd_rsv2 = 0; \
+ (gate).gd_off_15_0 = (uintptr_t) (off) & 0xffff; \
+ (gate).gd_ss = (sel); \
+ (gate).gd_ist = (ist); \
+ (gate).gd_rsv1 = 0; \
+ (gate).gd_type = (istrap) ? STS_TG32 : STS_IG32; \
+ (gate).gd_s = 0; \
+ (gate).gd_dpl = (dpl); \
+ (gate).gd_p = 1; \
+ (gate).gd_off_31_16 = (uintptr_t) (off) >> 16; \
+ (gate).gd_off_63_32 = (uintptr_t) (off) >> 32; \
+ (gate).gd_rsv2 = 0; \
}
/* Set up a normal, 64 bit interrupt/trap gate descriptor.
diff --git a/kern/arch/x86/ros/msr-index.h b/kern/arch/x86/ros/msr-index.h
index deaad47..0843304 100644
--- a/kern/arch/x86/ros/msr-index.h
+++ b/kern/arch/x86/ros/msr-index.h
@@ -33,20 +33,20 @@
/* Intel MSRs. Some also available on other CPUs */
#define MSR_IA32_PERFCTR0 0x000000c1
#define MSR_IA32_PERFCTR1 0x000000c2
-#define MSR_ARCH_PERFMON_EVENTSEL0 0x186
-#define MSR_ARCH_PERFMON_EVENTSEL1 0x187
+#define MSR_ARCH_PERFMON_EVENTSEL0 0x186
+#define MSR_ARCH_PERFMON_EVENTSEL1 0x187
-#define ARCH_PERFMON_EVENTSEL_EVENT 0x000000FFULL
-#define ARCH_PERFMON_EVENTSEL_UMASK 0x0000FF00ULL
-#define ARCH_PERFMON_EVENTSEL_USR (1ULL << 16)
-#define ARCH_PERFMON_EVENTSEL_OS (1ULL << 17)
-#define ARCH_PERFMON_EVENTSEL_EDGE (1ULL << 18)
-#define ARCH_PERFMON_EVENTSEL_PIN_CONTROL (1ULL << 19)
-#define ARCH_PERFMON_EVENTSEL_INT (1ULL << 20)
-#define ARCH_PERFMON_EVENTSEL_ANY (1ULL << 21)
-#define ARCH_PERFMON_EVENTSEL_ENABLE (1ULL << 22)
-#define ARCH_PERFMON_EVENTSEL_INV (1ULL << 23)
-#define ARCH_PERFMON_EVENTSEL_CMASK 0xFF000000ULL
+#define ARCH_PERFMON_EVENTSEL_EVENT 0x000000FFULL
+#define ARCH_PERFMON_EVENTSEL_UMASK 0x0000FF00ULL
+#define ARCH_PERFMON_EVENTSEL_USR (1ULL << 16)
+#define ARCH_PERFMON_EVENTSEL_OS (1ULL << 17)
+#define ARCH_PERFMON_EVENTSEL_EDGE (1ULL << 18)
+#define ARCH_PERFMON_EVENTSEL_PIN_CONTROL (1ULL << 19)
+#define ARCH_PERFMON_EVENTSEL_INT (1ULL << 20)
+#define ARCH_PERFMON_EVENTSEL_ANY (1ULL << 21)
+#define ARCH_PERFMON_EVENTSEL_ENABLE (1ULL << 22)
+#define ARCH_PERFMON_EVENTSEL_INV (1ULL << 23)
+#define ARCH_PERFMON_EVENTSEL_CMASK 0xFF000000ULL
#define MSR_FSB_FREQ 0x000000cd
#define MSR_PLATFORM_INFO 0x000000ce
@@ -73,7 +73,7 @@
#define MSR_OFFCORE_RSP_0 0x000001a6
#define MSR_OFFCORE_RSP_1 0x000001a7
#define MSR_NHM_TURBO_RATIO_LIMIT 0x000001ad
-#define MSR_TURBO_RATIO_LIMIT 0x000001ad
+#define MSR_TURBO_RATIO_LIMIT 0x000001ad
#define MSR_IVT_TURBO_RATIO_LIMIT 0x000001ae
#define MSR_LBR_SELECT 0x000001c8
@@ -111,69 +111,69 @@
#define MSR_IA32_LASTINTTOIP 0x000001de
/* X86 X2APIC registers */
-#define MSR_LAPIC_ID 0x00000802
-#define MSR_LAPIC_VERSION 0x00000803
-#define MSR_LAPIC_TPR 0x00000808
-#define MSR_LAPIC_PPR 0x0000080a
-#define MSR_LAPIC_EOI 0x0000080b
-#define MSR_LAPIC_LDR 0x0000080d
-#define MSR_LAPIC_SPURIOUS 0x0000080f
+#define MSR_LAPIC_ID 0x00000802
+#define MSR_LAPIC_VERSION 0x00000803
+#define MSR_LAPIC_TPR 0x00000808
+#define MSR_LAPIC_PPR 0x0000080a
+#define MSR_LAPIC_EOI 0x0000080b
+#define MSR_LAPIC_LDR 0x0000080d
+#define MSR_LAPIC_SPURIOUS 0x0000080f
-#define MSR_LAPIC_ISR_31_0 0x00000810
-#define MSR_LAPIC_ISR_63_32 0x00000811
-#define MSR_LAPIC_ISR_95_64 0x00000812
-#define MSR_LAPIC_ISR_127_96 0x00000813
-#define MSR_LAPIC_ISR_159_128 0x00000814
-#define MSR_LAPIC_ISR_191_160 0x00000815
-#define MSR_LAPIC_ISR_223_192 0x00000816
-#define MSR_LAPIC_ISR_255_224 0x00000817
+#define MSR_LAPIC_ISR_31_0 0x00000810
+#define MSR_LAPIC_ISR_63_32 0x00000811
+#define MSR_LAPIC_ISR_95_64 0x00000812
+#define MSR_LAPIC_ISR_127_96 0x00000813
+#define MSR_LAPIC_ISR_159_128 0x00000814
+#define MSR_LAPIC_ISR_191_160 0x00000815
+#define MSR_LAPIC_ISR_223_192 0x00000816
+#define MSR_LAPIC_ISR_255_224 0x00000817
// For easier looping
-#define MSR_LAPIC_ISR_START MSR_LAPIC_ISR_31_0
-#define MSR_LAPIC_ISR_END (MSR_LAPIC_ISR_255_224 + 1)
+#define MSR_LAPIC_ISR_START MSR_LAPIC_ISR_31_0
+#define MSR_LAPIC_ISR_END (MSR_LAPIC_ISR_255_224 + 1)
-#define MSR_LAPIC_TMR_31_0 0x00000818
-#define MSR_LAPIC_TMR_63_32 0x00000819
-#define MSR_LAPIC_TMR_95_64 0x0000081a
-#define MSR_LAPIC_TMR_127_96 0x0000081b
-#define MSR_LAPIC_TMR_159_128 0x0000081c
-#define MSR_LAPIC_TMR_191_160 0x0000081d
-#define MSR_LAPIC_TMR_223_192 0x0000081e
-#define MSR_LAPIC_TMR_255_224 0x0000081f
+#define MSR_LAPIC_TMR_31_0 0x00000818
+#define MSR_LAPIC_TMR_63_32 0x00000819
+#define MSR_LAPIC_TMR_95_64 0x0000081a
+#define MSR_LAPIC_TMR_127_96 0x0000081b
+#define MSR_LAPIC_TMR_159_128 0x0000081c
+#define MSR_LAPIC_TMR_191_160 0x0000081d
+#define MSR_LAPIC_TMR_223_192 0x0000081e
+#define MSR_LAPIC_TMR_255_224 0x0000081f
// For easier looping
-#define MSR_LAPIC_TMR_START MSR_LAPIC_TMR_31_0
-#define MSR_LAPIC_TMR_END (MSR_LAPIC_TMR_255_224 + 1)
+#define MSR_LAPIC_TMR_START MSR_LAPIC_TMR_31_0
+#define MSR_LAPIC_TMR_END (MSR_LAPIC_TMR_255_224 + 1)
-#define MSR_LAPIC_IRR_31_0 0x00000820
-#define MSR_LAPIC_IRR_63_32 0x00000821
-#define MSR_LAPIC_IRR_95_64 0x00000822
-#define MSR_LAPIC_IRR_127_96 0x00000823
-#define MSR_LAPIC_IRR_159_128 0x00000824
-#define MSR_LAPIC_IRR_191_160 0x00000825
-#define MSR_LAPIC_IRR_223_192 0x00000826
-#define MSR_LAPIC_IRR_255_224 0x00000827
+#define MSR_LAPIC_IRR_31_0 0x00000820
+#define MSR_LAPIC_IRR_63_32 0x00000821
+#define MSR_LAPIC_IRR_95_64 0x00000822
+#define MSR_LAPIC_IRR_127_96 0x00000823
+#define MSR_LAPIC_IRR_159_128 0x00000824
+#define MSR_LAPIC_IRR_191_160 0x00000825
+#define MSR_LAPIC_IRR_223_192 0x00000826
+#define MSR_LAPIC_IRR_255_224 0x00000827
// For easier looping
-#define MSR_LAPIC_IRR_START MSR_LAPIC_IRR_31_0
-#define MSR_LAPIC_IRR_END (MSR_LAPIC_IRR_255_224 + 1)
+#define MSR_LAPIC_IRR_START MSR_LAPIC_IRR_31_0
+#define MSR_LAPIC_IRR_END (MSR_LAPIC_IRR_255_224 + 1)
-#define MSR_LAPIC_ESR 0x00000828
-#define MSR_LAPIC_LVT_CMCI 0x0000082f
-#define MSR_LAPIC_ICR 0x00000830
-#define MSR_LAPIC_LVT_TIMER 0x00000832
-#define MSR_LAPIC_LVT_THERMAL 0x00000833
-#define MSR_LAPIC_LVT_PERFMON 0x00000834
-#define MSR_LAPIC_LVT_LINT0 0x00000835
-#define MSR_LAPIC_LVT_LINT1 0x00000836
-#define MSR_LAPIC_LVT_ERROR_REG 0x00000837
-#define MSR_LAPIC_INITIAL_COUNT 0x00000838
-#define MSR_LAPIC_CURRENT_COUNT 0x00000839
-#define MSR_LAPIC_DIVIDE_CONFIG_REG 0x0000083e
-#define MSR_LAPIC_SELF_IPI 0x0000083f
+#define MSR_LAPIC_ESR 0x00000828
+#define MSR_LAPIC_LVT_CMCI 0x0000082f
+#define MSR_LAPIC_ICR 0x00000830
+#define MSR_LAPIC_LVT_TIMER 0x00000832
+#define MSR_LAPIC_LVT_THERMAL 0x00000833
+#define MSR_LAPIC_LVT_PERFMON 0x00000834
+#define MSR_LAPIC_LVT_LINT0 0x00000835
+#define MSR_LAPIC_LVT_LINT1 0x00000836
+#define MSR_LAPIC_LVT_ERROR_REG 0x00000837
+#define MSR_LAPIC_INITIAL_COUNT 0x00000838
+#define MSR_LAPIC_CURRENT_COUNT 0x00000839
+#define MSR_LAPIC_DIVIDE_CONFIG_REG 0x0000083e
+#define MSR_LAPIC_SELF_IPI 0x0000083f
-#define MSR_LAPIC_END (MSR_LAPIC_SELF_IPI + 1)
+#define MSR_LAPIC_END (MSR_LAPIC_SELF_IPI + 1)
/* DEBUGCTLMSR bits (others vary by model): */
-#define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */
-#define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */
+#define DEBUGCTLMSR_LBR (1UL << 0)/* last branch recording */
+#define DEBUGCTLMSR_BTF (1UL << 1)/* single-step on branches */
#define DEBUGCTLMSR_TR (1UL << 6)
#define DEBUGCTLMSR_BTS (1UL << 7)
#define DEBUGCTLMSR_BTINT (1UL << 8)
@@ -590,13 +590,13 @@
#define MSR_IA32_VMX_TRUE_ENTRY_CTLS 0x00000490
/* VMX_BASIC bits and bitmasks */
-#define VMX_BASIC_VMCS_SIZE_SHIFT 32
-#define VMX_BASIC_64 (1ULL << 48)
-#define VMX_BASIC_MEM_TYPE_SHIFT 50
-#define VMX_BASIC_MEM_TYPE_MASK (0xfULL << VMX_BASIC_MEM_TYPE_SHIFT)
-#define VMX_BASIC_MEM_TYPE_WB 6LLU
-#define VMX_BASIC_INOUT (1ULL << 54)
-#define VMX_BASIC_TRUE_CTLS (1ULL << 55)
+#define VMX_BASIC_VMCS_SIZE_SHIFT 32
+#define VMX_BASIC_64 (1ULL << 48)
+#define VMX_BASIC_MEM_TYPE_SHIFT 50
+#define VMX_BASIC_MEM_TYPE_MASK (0xfULL << VMX_BASIC_MEM_TYPE_SHIFT)
+#define VMX_BASIC_MEM_TYPE_WB 6LLU
+#define VMX_BASIC_INOUT (1ULL << 54)
+#define VMX_BASIC_TRUE_CTLS (1ULL << 55)
/* AMD-V MSRs */
diff --git a/kern/arch/x86/ros/syscall64.h b/kern/arch/x86/ros/syscall64.h
index 7b63ca7..f5bed72 100644
--- a/kern/arch/x86/ros/syscall64.h
+++ b/kern/arch/x86/ros/syscall64.h
@@ -15,18 +15,19 @@
static inline intreg_t __syscall_sysenter(uintreg_t a0, uintreg_t a1)
{
intreg_t ret = 0;
- long dummy;
- /* we're calling using the amd function call abi. this asm and the kernel
- * will save the callee-saved state. We'll use the clobber list to force
- * the compiler to save caller-saved state. As with uthread code, you need
- * to make sure you have one ABI-compliant, non-inlined function call
- * between any floating point ops and this.
+ long dummy; /* force D, S clobber */
+
+ /* we're calling using the amd function call abi. this asm and the
+ * kernel will save the callee-saved state. We'll use the clobber list
+ * to force the compiler to save caller-saved state. As with uthread
+ * code, you need to make sure you have one ABI-compliant, non-inlined
+ * function call between any floating point ops and this.
*
- * Note that syscall doesn't save the stack pointer - using rdx for that.
- * The kernel will restore it for us. */
+ * Note that syscall doesn't save the stack pointer - using rdx for
+ * that. The kernel will restore it for us. */
asm volatile ("movq %%rsp, %%rdx; "
"syscall; "
- : "=a"(ret), "=D"(dummy), "=S"(dummy) /* force D, S clobber */
+ : "=a"(ret), "=D"(dummy), "=S"(dummy)
: "D"(a0), "S"(a1)
: "cc", "memory", "rcx", "rdx", "r8", "r9", "r10", "r11");
return ret;
@@ -35,6 +36,7 @@
static inline intreg_t __syscall_trap(uintreg_t a0, uintreg_t a1)
{
intreg_t ret;
+
/* If you change this, change pop_user_ctx() */
asm volatile("int %1"
: "=a" (ret)
@@ -50,8 +52,9 @@
* non-canonical address, which should never be a legitamate syscall. */
static inline void __fastcall_setfsbase(uintptr_t fsbase)
{
- long dummy;
- asm volatile ("syscall" : "=D"(dummy), "=S"(dummy) /* force D, S clobber */
+ long dummy; /* force D, S clobber */
+
+ asm volatile ("syscall" : "=D"(dummy), "=S"(dummy)
: "D"(FASTCALL_SETFSBASE), "S"(fsbase)
: "rax", "r11", "rcx", "rdx", "memory");
}
diff --git a/kern/arch/x86/ros/trapframe.h b/kern/arch/x86/ros/trapframe.h
index 68d3983..5e46ea0 100644
--- a/kern/arch/x86/ros/trapframe.h
+++ b/kern/arch/x86/ros/trapframe.h
@@ -69,49 +69,49 @@
* See SDM 2a 3-451. */
/* Header for the non-64-bit mode FXSAVE map */
struct fp_header_non_64bit {
- uint16_t fcw;
- uint16_t fsw;
- uint8_t ftw;
- uint8_t padding0;
- uint16_t fop;
- uint32_t fpu_ip;
- uint16_t cs;
- uint16_t padding1;
- uint32_t fpu_dp;
- uint16_t ds;
- uint16_t padding2;
- uint32_t mxcsr;
- uint32_t mxcsr_mask;
+ uint16_t fcw;
+ uint16_t fsw;
+ uint8_t ftw;
+ uint8_t padding0;
+ uint16_t fop;
+ uint32_t fpu_ip;
+ uint16_t cs;
+ uint16_t padding1;
+ uint32_t fpu_dp;
+ uint16_t ds;
+ uint16_t padding2;
+ uint32_t mxcsr;
+ uint32_t mxcsr_mask;
};
/* Header for the 64-bit mode FXSAVE map with promoted operand size */
struct fp_header_64bit_promoted {
- uint16_t fcw;
- uint16_t fsw;
- uint8_t ftw;
- uint8_t padding0;
- uint16_t fop;
- uint64_t fpu_ip;
- uint64_t fpu_dp;
- uint32_t mxcsr;
- uint32_t mxcsr_mask;
+ uint16_t fcw;
+ uint16_t fsw;
+ uint8_t ftw;
+ uint8_t padding0;
+ uint16_t fop;
+ uint64_t fpu_ip;
+ uint64_t fpu_dp;
+ uint32_t mxcsr;
+ uint32_t mxcsr_mask;
};
/* Header for the 64-bit mode FXSAVE map with default operand size */
struct fp_header_64bit_default {
- uint16_t fcw;
- uint16_t fsw;
- uint8_t ftw;
- uint8_t padding0;
- uint16_t fop;
- uint32_t fpu_ip;
- uint16_t cs;
- uint16_t padding1;
- uint32_t fpu_dp;
- uint16_t ds;
- uint16_t padding2;
- uint32_t mxcsr;
- uint32_t mxcsr_mask;
+ uint16_t fcw;
+ uint16_t fsw;
+ uint8_t ftw;
+ uint8_t padding0;
+ uint16_t fop;
+ uint32_t fpu_ip;
+ uint16_t cs;
+ uint16_t padding1;
+ uint32_t fpu_dp;
+ uint16_t ds;
+ uint16_t padding2;
+ uint32_t mxcsr;
+ uint32_t mxcsr_mask;
};
/* Just for storage space, not for real use */
@@ -137,44 +137,45 @@
typedef struct ancillary_state {
/* Legacy region of the XSAVE area */
union { /* whichever header used depends on the mode */
- struct fp_header_non_64bit fp_head_n64;
+ struct fp_header_non_64bit fp_head_n64;
struct fp_header_64bit_promoted fp_head_64p;
struct fp_header_64bit_default fp_head_64d;
};
/* offset 32 bytes */
- __128bits st0_mm0; /* 128 bits: 80 for the st0, 48 reserved */
- __128bits st1_mm1;
- __128bits st2_mm2;
- __128bits st3_mm3;
- __128bits st4_mm4;
- __128bits st5_mm5;
- __128bits st6_mm6;
- __128bits st7_mm7;
+ /* 128 bits: 80 for the st0, 48 reserved */
+ __128bits st0_mm0;
+ __128bits st1_mm1;
+ __128bits st2_mm2;
+ __128bits st3_mm3;
+ __128bits st4_mm4;
+ __128bits st5_mm5;
+ __128bits st6_mm6;
+ __128bits st7_mm7;
/* offset 160 bytes */
- __128bits xmm0;
- __128bits xmm1;
- __128bits xmm2;
- __128bits xmm3;
- __128bits xmm4;
- __128bits xmm5;
- __128bits xmm6;
- __128bits xmm7;
+ __128bits xmm0;
+ __128bits xmm1;
+ __128bits xmm2;
+ __128bits xmm3;
+ __128bits xmm4;
+ __128bits xmm5;
+ __128bits xmm6;
+ __128bits xmm7;
/* xmm8-xmm15 are only available in 64-bit-mode */
- __128bits xmm8;
- __128bits xmm9;
- __128bits xmm10;
- __128bits xmm11;
- __128bits xmm12;
- __128bits xmm13;
- __128bits xmm14;
- __128bits xmm15;
+ __128bits xmm8;
+ __128bits xmm9;
+ __128bits xmm10;
+ __128bits xmm11;
+ __128bits xmm12;
+ __128bits xmm13;
+ __128bits xmm14;
+ __128bits xmm15;
/* offset 416 bytes */
- __128bits reserv0;
- __128bits reserv1;
- __128bits reserv2;
- __128bits reserv3;
- __128bits reserv4;
- __128bits reserv5;
+ __128bits reserv0;
+ __128bits reserv1;
+ __128bits reserv2;
+ __128bits reserv3;
+ __128bits reserv4;
+ __128bits reserv5;
/* offset 512 bytes */
/*
@@ -183,26 +184,27 @@
*/
// xstate_bv identifies the state components in the XSAVE area
- uint64_t xstate_bv;
+ uint64_t xstate_bv;
/*
* xcomp_bv[bit 63] is 1 if the compacted format is used, else 0.
- * All bits in xcomp_bv should be 0 if the processor does not support the
- * compaction extensions to the XSAVE feature set.
- */
- uint64_t xcomp_bv;
- __128bits reserv6;
+ * All bits in xcomp_bv should be 0 if the processor does not
+ * support the compaction extensions to the XSAVE feature set.
+ */
+ uint64_t xcomp_bv;
+ __128bits reserv6;
/* offset 576 bytes */
/*
* Extended region of the XSAVE area
* We currently support an extended region of up to 2112 bytes,
* for a total ancillary_state size of 2688 bytes.
- * This supports x86 state components up through the zmm31 register.
- * If you need more, please ask!
- * See the Intel Architecture Instruction Set Extensions Programming
- * Reference page 3-3 for detailed offsets in this region.
- */
- uint8_t extended_region[2120];
+ * This supports x86 state components up through the zmm31
+ * register. If you need more, please ask!
+ * See the Intel Architecture Instruction Set Extensions
+ * Programming Reference page 3-3 for detailed offsets in this
+ * region.
+ */
+ uint8_t extended_region[2120];
/* ancillary state */
} __attribute__((aligned(64))) ancillary_state_t;
diff --git a/kern/arch/x86/ros/trapframe64.h b/kern/arch/x86/ros/trapframe64.h
index b16c6d1..64380e2 100644
--- a/kern/arch/x86/ros/trapframe64.h
+++ b/kern/arch/x86/ros/trapframe64.h
@@ -32,7 +32,8 @@
uint16_t tf_padding3; /* used in trap reflection */
uint32_t tf_padding2;
uint64_t tf_rflags;
- /* unlike 32 bit, SS:RSP is always pushed, even when not changing rings */
+ /* unlike 32 bit, SS:RSP is always pushed, even when not changing rings
+ */
uint64_t tf_rsp;
uint16_t tf_ss;
uint16_t tf_padding1;
diff --git a/kern/arch/x86/ros/vmm.h b/kern/arch/x86/ros/vmm.h
index 60e5c67..6d5d2f9 100644
--- a/kern/arch/x86/ros/vmm.h
+++ b/kern/arch/x86/ros/vmm.h
@@ -11,11 +11,11 @@
/* Initialization data provided by the userspace part of the VMM when setting
* up a guest physical core (vmx vcpu). */
struct vmm_gpcore_init {
- void *posted_irq_desc;
- void *vapic_addr;
- void *apic_addr;
- uintptr_t fsbase;
- uintptr_t gsbase;
+ void *posted_irq_desc;
+ void *vapic_addr;
+ void *apic_addr;
+ uintptr_t fsbase;
+ uintptr_t gsbase;
};
/* Intel VM Trap Injection Fields */
diff --git a/kern/arch/x86/smp.c b/kern/arch/x86/smp.c
index 1020112..8287bf3 100644
--- a/kern/arch/x86/smp.c
+++ b/kern/arch/x86/smp.c
@@ -31,9 +31,9 @@
handler_wrapper_t* wrapper;
extern atomic_t outstanding_calls;
- // prevents us from ever having more than NUM_HANDLER_WRAPPERS callers in
- // the process of competing for vectors. not decremented until both after
- // the while(1) loop and after it's been waited on.
+ // prevents us from ever having more than NUM_HANDLER_WRAPPERS callers
+ // in the process of competing for vectors. not decremented until both
+ // after the while(1) loop and after it's been waited on.
atomic_inc(&outstanding_calls);
if (atomic_read(&outstanding_calls) > NUM_HANDLER_WRAPPERS) {
atomic_dec(&outstanding_calls);
@@ -46,41 +46,43 @@
// build the mask based on the type and destination
INIT_CHECKLIST_MASK(cpu_mask, MAX_NUM_CORES);
- // set checklist mask's size dynamically to the num cpus actually present
+ // set checklist mask's size dynamically to the num cpus actually
+ // present
cpu_mask.size = num_cores;
switch (type) {
- case 1: // self
- SET_BITMASK_BIT(cpu_mask.bits, core_id());
- break;
- case 2: // all
- FILL_BITMASK(cpu_mask.bits, num_cores);
- break;
- case 3: // all but self
- FILL_BITMASK(cpu_mask.bits, num_cores);
- CLR_BITMASK_BIT(cpu_mask.bits, core_id());
- break;
- case 4: // physical mode
- // note this only supports sending to one specific physical id
- // (only sets one bit, so if multiple cores have the same phys id
- // the first one through will set this).
- SET_BITMASK_BIT(cpu_mask.bits, dest);
- break;
- case 5: // logical mode
- // TODO
- warn("Logical mode bitmask handler protection not implemented!");
- break;
- default:
- panic("Invalid type for cross-core function call!");
+ case 1: // self
+ SET_BITMASK_BIT(cpu_mask.bits, core_id());
+ break;
+ case 2: // all
+ FILL_BITMASK(cpu_mask.bits, num_cores);
+ break;
+ case 3: // all but self
+ FILL_BITMASK(cpu_mask.bits, num_cores);
+ CLR_BITMASK_BIT(cpu_mask.bits, core_id());
+ break;
+ case 4: // physical mode
+ // note this only supports sending to one specific physical id
+ // (only sets one bit, so if multiple cores have the same phys
+ // id the first one through will set this).
+ SET_BITMASK_BIT(cpu_mask.bits, dest);
+ break;
+ case 5: // logical mode
+ // TODO
+ warn("Logical mode bitmask handler protection unimplemented!");
+ break;
+ default:
+ panic("Invalid type for cross-core function call!");
}
- // Find an available vector/wrapper. Starts with this core's id (mod the
- // number of wrappers). Walk through on conflict.
+ // Find an available vector/wrapper. Starts with this core's id (mod
+ // the number of wrappers). Walk through on conflict.
// Commit returns an error if it wanted to give up for some reason,
// like taking too long to acquire the lock or clear the mask, at which
// point, we try the next one.
// When we are done, wrapper points to the one we finally got.
- // this wrapper_num trick doesn't work as well if you send a bunch in a row
- // and wait, since you always check your main one (which is currently busy).
+ // this wrapper_num trick doesn't work as well if you send a bunch in a
+ // row and wait, since you always check your main one (which is
+ // currently busy).
wrapper_num = core_id() % NUM_HANDLER_WRAPPERS;
while(1) {
wrapper = &handler_wrappers[wrapper_num];
@@ -89,17 +91,19 @@
wrapper_num = (wrapper_num + 1) % NUM_HANDLER_WRAPPERS;
/*
uint32_t count = 0;
- // instead of deadlock, smp_call can fail with this. makes it harder
- // to use (have to check your return value). consider putting a delay
- // here too (like if wrapper_num == initial_wrapper_num)
- if (count++ > NUM_HANDLER_WRAPPERS * 1000) // note 1000 isn't enough...
+ // instead of deadlock, smp_call can fail with this. makes it
+ // harder to use (have to check your return value). consider
+ // putting a delay here too (like if wrapper_num ==
+ // initial_wrapper_num)
+ // note 1000 isn't enough...
+ if (count++ > NUM_HANDLER_WRAPPERS * 1000)
return -EBUSY;
*/
}
// Wanting to wait is expressed by having a non-NULL handler_wrapper_t**
- // passed in. Pass out our reference to wrapper, to wait later.
- // If we don't want to wait, release the checklist (though it is still not
+ // passed in. Pass out our reference to wrapper, to wait later. If we
+ // don't want to wait, release the checklist (though it is still not
// clear, so it can't be used til everyone checks in).
if (wait_wrapper)
*wait_wrapper = wrapper;
@@ -108,15 +112,18 @@
atomic_dec(&outstanding_calls);
}
- /* TODO: once we can unregister, we can reregister. This here assumes that
- * there is only one IRQ registered, and its the one for SMP call function.
- * We're waiting on RCU to do a nice unregister. */
+ /* TODO: once we can unregister, we can reregister. This here assumes
+ * that there is only one IRQ registered, and its the one for SMP call
+ * function. We're waiting on RCU to do a nice unregister. */
extern struct irq_handler *irq_handlers[];
+
if (!irq_handlers[wrapper->vector]) {
- register_irq(wrapper->vector, handler, data, MKBUS(BusIPI, 0, 0, 0));
+ register_irq(wrapper->vector, handler, data, MKBUS(BusIPI, 0, 0,
+ 0));
} else {
- /* we're replacing the old one. hope it was ours, and the IRQ is firing
- * concurrently (if it is, there's an smp_call bug)! */
+ /* we're replacing the old one. hope it was ours, and the IRQ
+ * is firing concurrently (if it is, there's an smp_call bug)!
+ * */
irq_handlers[wrapper->vector]->isr = handler;
irq_handlers[wrapper->vector]->data = data;
}
@@ -125,23 +132,23 @@
enable_irqsave(&state);
// Send the proper type of IPI. I made up these numbers.
switch (type) {
- case 1:
- send_self_ipi(wrapper->vector);
- break;
- case 2:
- send_broadcast_ipi(wrapper->vector);
- break;
- case 3:
- send_all_others_ipi(wrapper->vector);
- break;
- case 4: // physical mode
- send_ipi(dest, wrapper->vector);
- break;
- case 5: // logical mode
- send_group_ipi(dest, wrapper->vector);
- break;
- default:
- panic("Invalid type for cross-core function call!");
+ case 1:
+ send_self_ipi(wrapper->vector);
+ break;
+ case 2:
+ send_broadcast_ipi(wrapper->vector);
+ break;
+ case 3:
+ send_all_others_ipi(wrapper->vector);
+ break;
+ case 4: // physical mode
+ send_ipi(dest, wrapper->vector);
+ break;
+ case 5: // logical mode
+ send_group_ipi(dest, wrapper->vector);
+ break;
+ default:
+ panic("Invalid type for cross-core function call!");
}
// wait long enough to receive our own broadcast (PROBABLY WORKS) TODO
disable_irqsave(&state);
diff --git a/kern/arch/x86/smp_boot.c b/kern/arch/x86/smp_boot.c
index 133b9d6..0f1bb4b 100644
--- a/kern/arch/x86/smp_boot.c
+++ b/kern/arch/x86/smp_boot.c
@@ -38,9 +38,9 @@
#define INIT_HANDLER_WRAPPER(v) \
{ \
- handler_wrappers[(v)].vector = 0xe##v; \
- handler_wrappers[(v)].cpu_list = &f##v##_cpu_list; \
- handler_wrappers[(v)].cpu_list->mask.size = num_cores; \
+ handler_wrappers[(v)].vector = 0xe##v; \
+ handler_wrappers[(v)].cpu_list = &f##v##_cpu_list; \
+ handler_wrappers[(v)].cpu_list->mask.size = num_cores; \
}
DECLARE_HANDLER_CHECKLISTS(0);
@@ -66,6 +66,7 @@
{
uint32_t edx;
int rdtscp_ecx;
+
/* TODO: have some sort of 'cpu info structure' with flags */
cpuid(0x80000001, 0x0, 0, 0, 0, &edx);
if (edx & (1 << 27)) {
@@ -84,12 +85,13 @@
int coreid = get_os_coreid(hw_core_id());
struct per_cpu_info *pcpui = &per_cpu_info[coreid];
pcpui->coreid = coreid;
- write_msr(MSR_GS_BASE, (uintptr_t)pcpui); /* our cr4 isn't set yet */
+ write_msr(MSR_GS_BASE, (uintptr_t)pcpui); /* our cr4 isn't set yet */
write_msr(MSR_KERN_GS_BASE, (uint64_t)pcpui);
- /* don't need this for the kernel anymore, but userspace can still use it */
+ /* don't need this for the kernel anymore, but userspace can still use
+ * it */
setup_rdtscp(coreid);
- /* After this point, all cores have set up their segmentation and whatnot to
- * be able to do a proper core_id(). */
+ /* After this point, all cores have set up their segmentation and
+ * whatnot to be able to do a proper core_id(). */
waiton_barrier(&generic_barrier);
if (coreid == 0)
core_id_ready = TRUE;
@@ -114,10 +116,12 @@
static void __spin_bootlock_raw(void)
{
- uint16_t *bootlock = (uint16_t*)(smp_boot_lock - smp_entry + trampoline_pg);
+ uint16_t *bootlock = (uint16_t*)(smp_boot_lock - smp_entry +
+ trampoline_pg);
+
/* Same lock code as in smp_entry */
asm volatile ("movw $1, %%ax; "
- "1: "
+ "1: "
"xchgw %%ax, %0; "
"test %%ax, %%ax; "
"jne 1b;" : : "m"(*bootlock) : "eax", "cc", "memory");
@@ -134,21 +138,23 @@
memcpy(KADDR(trampoline_pg), (void *)smp_entry,
smp_entry_end - smp_entry);
- /* Make sure the trampoline page is mapped. 64 bit already has the tramp pg
- * mapped (1 GB of lowmem), so this is a nop. */
+ /* Make sure the trampoline page is mapped. 64 bit already has the
+ * tramp pg mapped (1 GB of lowmem), so this is a nop. */
// Allocate a stack for the cores starting up. One for all, must share
if (kpage_alloc(&smp_stack))
panic("No memory for SMP boot stack!");
smp_stack_top = (uintptr_t)(page2kva(smp_stack) + PGSIZE);
- /* During SMP boot, core_id_early() returns 0, so all of the cores, which
- * grab locks concurrently, share the same pcpui and thus the same
- * lock_depth. We need to disable checking until core_id works properly. */
+ /* During SMP boot, core_id_early() returns 0, so all of the cores,
+ * which grab locks concurrently, share the same pcpui and thus the same
+ * lock_depth. We need to disable checking until core_id works
+ * properly. */
pcpui0->__lock_checking_enabled = 0;
// Start the IPI process (INIT, wait, SIPI, wait, SIPI, wait)
send_init_ipi();
- // SDM 3A is a little wonky wrt the proper delays. These are my best guess.
+ // SDM 3A is a little wonky wrt the proper delays. These are my best
+ // guess.
udelay(10000);
// first SIPI
send_startup_ipi(0x01);
@@ -159,22 +165,24 @@
*/
udelay(500000);
- // Each core will also increment smp_semaphore, and decrement when it is done,
- // all in smp_entry. It's purpose is to keep Core0 from competing for the
- // smp_boot_lock. So long as one AP increments the sem before the final
- // LAPIC timer goes off, all available cores will be initialized.
+ // Each core will also increment smp_semaphore, and decrement when it is
+ // done, all in smp_entry. It's purpose is to keep Core0 from competing
+ // for the smp_boot_lock. So long as one AP increments the sem before
+ // the final LAPIC timer goes off, all available cores will be
+ // initialized.
while (*get_smp_semaphore())
cpu_relax();
- // From here on, no other cores are coming up. Grab the lock to ensure it.
- // Another core could be in it's prelock phase and be trying to grab the lock
- // forever....
+ // From here on, no other cores are coming up. Grab the lock to ensure
+ // it. Another core could be in it's prelock phase and be trying to
+ // grab the lock forever....
// The lock exists on the trampoline, so it can be grabbed right away in
- // real mode. If core0 wins the race and blocks other CPUs from coming up
- // it can crash the machine if the other cores are allowed to proceed with
- // booting. Specifically, it's when they turn on paging and have that temp
- // mapping pulled out from under them. Now, if a core loses, it will spin
- // on the trampoline (which we must be careful to not deallocate)
+ // real mode. If core0 wins the race and blocks other CPUs from coming
+ // up it can crash the machine if the other cores are allowed to proceed
+ // with booting. Specifically, it's when they turn on paging and have
+ // that temp mapping pulled out from under them. Now, if a core loses,
+ // it will spin on the trampoline (which we must be careful to not
+ // deallocate)
__spin_bootlock_raw();
printk("Number of Cores Detected: %d\n", x86_num_cores_booted);
#ifdef CONFIG_DISABLE_SMT
@@ -184,12 +192,12 @@
/* cleans up the trampoline page, and any other low boot mem mappings */
x86_cleanup_bootmem();
- /* trampoline_pg had a refcount of 2 earlier, so we need to dec once more to
- * free it but only if all cores are in (or we reset / reinit those that
- * failed) */
+ /* trampoline_pg had a refcount of 2 earlier, so we need to dec once
+ * more to free it but only if all cores are in (or we reset / reinit
+ * those that failed) */
if (x86_num_cores_booted == num_cores) {
- /* TODO: if we ever alloc the trampoline_pg or something, we can free it
- * here. */
+ /* TODO: if we ever alloc the trampoline_pg or something, we can
+ * free it here. */
} else {
warn("ACPI/MP found %d cores, smp_boot initialized %d, using %d\n",
num_cores, x86_num_cores_booted, x86_num_cores_booted);
@@ -217,21 +225,9 @@
*/
uintptr_t smp_main(void)
{
- /*
- // Print some diagnostics. Uncomment if there're issues.
- cprintf("Good morning Vietnam!\n");
- cprintf("This core's Default APIC ID: 0x%08x\n", lapic_get_default_id());
- cprintf("This core's Current APIC ID: 0x%08x\n", lapic_get_id());
- if (read_msr(IA32_APIC_BASE) & 0x00000100)
- cprintf("I am the Boot Strap Processor\n");
- else
- cprintf("I am an Application Processor\n");
- cprintf("Num_Cores: %d\n\n", num_cores);
- */
-
- /* We need to fake being core 0 for our memory allocations to work nicely.
- * This is safe since the entire machine is single threaded while we are in
- * this function. */
+ /* We need to fake being core 0 for our memory allocations to work
+ * nicely. This is safe since the entire machine is single threaded
+ * while we are in this function. */
write_msr(MSR_GS_BASE, (uintptr_t)&per_cpu_info[0]);
// Get a per-core kernel stack
@@ -241,14 +237,15 @@
unsigned int blob_size = sizeof(segdesc_t) * SEG_COUNT +
sizeof(pseudodesc_t) + sizeof(taskstate_t);
/* TODO: don't use kmalloc - might have issues in the future */
- void *gdt_etc = kmalloc(blob_size, 0); /* we'll never free this btw */
+ void *gdt_etc = kmalloc(blob_size, 0); /* we'll never free this btw */
taskstate_t *my_ts = gdt_etc;
pseudodesc_t *my_gdt_pd = (void*)my_ts + sizeof(taskstate_t);
segdesc_t *my_gdt = (void*)my_gdt_pd + sizeof(pseudodesc_t);
- /* This is a bit ghetto: we need to communicate our GDT and TSS's location
- * to smp_percpu_init(), but we can't trust our coreid (since they haven't
- * been remapped yet (so we can't write it directly to per_cpu_info)). So
- * we use the bottom of the stack page... */
+
+ /* This is a bit ghetto: we need to communicate our GDT and TSS's
+ * location to smp_percpu_init(), but we can't trust our coreid (since
+ * they haven't been remapped yet (so we can't write it directly to
+ * per_cpu_info)). So we use the bottom of the stack page... */
*kstack_bottom_addr(my_stack_top) = (uintptr_t)gdt_etc;
// Build and load the gdt / gdt_pd
@@ -271,8 +268,8 @@
apiconline();
- /* Stop pretending to be core 0. We'll get our own coreid shortly and set
- * gs properly (smp_final_core_init()) */
+ /* Stop pretending to be core 0. We'll get our own coreid shortly and
+ * set gs properly (smp_final_core_init()) */
write_msr(MSR_GS_BASE, 0);
return my_stack_top; // will be loaded in smp_entry.S
@@ -282,10 +279,10 @@
{
uintptr_t nmi_entry_stacktop = get_kstack();
- /* NMI handlers can't use swapgs for kernel TFs, so we need to bootstrap a
- * bit. We'll use a little bit of space above the actual NMI stacktop for
- * storage for the pcpui pointer. But we need to be careful: the HW will
- * align RSP to 16 bytes on entry. */
+ /* NMI handlers can't use swapgs for kernel TFs, so we need to bootstrap
+ * a bit. We'll use a little bit of space above the actual NMI stacktop
+ * for storage for the pcpui pointer. But we need to be careful: the HW
+ * will align RSP to 16 bytes on entry. */
nmi_entry_stacktop -= 16;
*(uintptr_t*)nmi_entry_stacktop = (uintptr_t)pcpui;
pcpui->tss->ts_ist1 = nmi_entry_stacktop;
@@ -311,8 +308,8 @@
struct per_cpu_info *pcpui = &per_cpu_info[coreid];
uint32_t eax, edx;
- /* Flushes any potentially old mappings from smp_boot() (note the page table
- * removal) */
+ /* Flushes any potentially old mappings from smp_boot() (note the page
+ * table removal) */
tlbflush();
if (cpu_has_feat(CPU_FEAT_X86_FSGSBASE))
@@ -320,7 +317,8 @@
/*
* Enable SSE instructions.
- * CR4.OSFXSR enables SSE and ensures that MXCSR/XMM gets saved with FXSAVE
+ * CR4.OSFXSR enables SSE and ensures that MXCSR/XMM gets saved with
+ * FXSAVE
* CR4.OSXSAVE enables XSAVE instructions. Only set if XSAVE supported.
* CR4.OSXMME indicates OS support for software exception handlers for
* SIMD floating-point exceptions (turn it on to get #XM exceptions
@@ -335,15 +333,18 @@
lxcr0(__proc_global_info.x86_default_xcr0);
}
- // Initialize fpu and extended state by restoring our default XSAVE area.
+ // Initialize fpu and extended state by restoring our default XSAVE
+ // area.
init_fp_state();
/* core 0 set up earlier in idt_init() */
if (coreid) {
- my_stack_bot = kstack_bottom_addr(ROUNDUP(read_sp() - 1, PGSIZE));
+ my_stack_bot = kstack_bottom_addr(ROUNDUP(read_sp() - 1,
+ PGSIZE));
pcpui->tss = (taskstate_t*)(*my_stack_bot);
pcpui->gdt = (segdesc_t*)(*my_stack_bot +
- sizeof(taskstate_t) + sizeof(pseudodesc_t));
+ sizeof(taskstate_t) +
+ sizeof(pseudodesc_t));
}
assert(read_gsbase() == (uintptr_t)pcpui);
assert(read_msr(MSR_KERN_GS_BASE) == (uint64_t)pcpui);
@@ -357,11 +358,12 @@
vmm_pcpu_init();
lcr4(rcr4() & ~CR4_TSD);
- /* This should allow turbo mode. I haven't found a doc that says how deep
- * we need to sleep. At a minimum on some machines, it's C2. Given that
- * "C2 or deeper" pops up in a few other areas as a deeper sleep (e.g.
- * mwaits on memory accesses from outside the processor won't wake >= C2),
- * this might be deep enough for turbo mode to kick in. */
+ /* This should allow turbo mode. I haven't found a doc that says how
+ * deep we need to sleep. At a minimum on some machines, it's C2.
+ * Given that "C2 or deeper" pops up in a few other areas as a deeper
+ * sleep (e.g. mwaits on memory accesses from outside the processor
+ * won't wake >= C2), this might be deep enough for turbo mode to kick
+ * in. */
set_fastest_pstate();
set_cstate(X86_MWAIT_C2);
}
diff --git a/kern/arch/x86/time.c b/kern/arch/x86/time.c
index c4c807e..228354e 100644
--- a/kern/arch/x86/time.c
+++ b/kern/arch/x86/time.c
@@ -37,14 +37,16 @@
bool computed = FALSE;
if (!read_msr_safe(MSR_PLATFORM_INFO, &msr_val))
- tsc_freq = __proc_global_info.bus_freq * ((msr_val >> 8) & 0xff);
+ tsc_freq = __proc_global_info.bus_freq
+ * ((msr_val >> 8) & 0xff);
/* Even if we have the MSR, it might have given us 0. (QEMU). */
if (!tsc_freq) {
tsc_freq = compute_tsc_freq();
computed = TRUE;
}
__proc_global_info.tsc_freq = tsc_freq;
- printk("TSC Frequency: %llu%s\n", tsc_freq, computed ? " (computed)" : "");
+ printk("TSC Frequency: %llu%s\n", tsc_freq,
+ computed ? " (computed)" : "");
}
static uint64_t compute_bus_freq(void)
@@ -58,22 +60,23 @@
timercount[0] = apicrget(MSR_LAPIC_CURRENT_COUNT);
udelay_pit(1000000);
timercount[1] = apicrget(MSR_LAPIC_CURRENT_COUNT);
- /* The time base for the timer is derived from the processor's bus clock,
- * divided by the value specified in the divide configuration register.
- * Note we mult and div by the divisor, saving the actual freq (even though
- * we don't use it yet). */
+ /* The time base for the timer is derived from the processor's bus
+ * clock, divided by the value specified in the divide configuration
+ * register. Note we mult and div by the divisor, saving the actual
+ * freq (even though we don't use it yet). */
return (timercount[0] - timercount[1]) * LAPIC_TIMER_DIVISOR_VAL;
}
static uint64_t lookup_bus_freq(void)
{
- /* Got these from the good book for any model supporting MSR_PLATFORM_INFO.
- * If they don't support that MSR, we're going to compute the TSC anyways.
+ /* Got these from the good book for any model supporting
+ * MSR_PLATFORM_INFO. If they don't support that MSR, we're going to
+ * compute the TSC anyways.
*
* A couple models weren't in the book, but were reported at:
* http://a4lg.com/tech/x86/database/x86-families-and-models.en.html.
- * Feel free to add more. If we fail here, we'll compute it manually and be
- * off slightly. */
+ * Feel free to add more. If we fail here, we'll compute it manually
+ * and be off slightly. */
switch ((x86_family << 16) | x86_model) {
case 0x6001a:
case 0x6001e:
@@ -126,7 +129,8 @@
computed = TRUE;
}
__proc_global_info.bus_freq = bus_freq;
- printk("Bus Frequency: %llu%s\n", bus_freq, computed ? " (computed)" : "");
+ printk("Bus Frequency: %llu%s\n", bus_freq,
+ computed ? " (computed)" : "");
}
void timer_init(void)
@@ -149,18 +153,18 @@
// cprintf("timer mode set to %d, divisor %d\n",mode, divisor);
}
-static int getpit()
+static int getpit(void)
{
- int high, low;
+ int high, low;
// TODO: need a lock to protect access to PIT
-
- /* Select counter 0 and latch counter value. */
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
-
- low = inb(TIMER_CNTR0);
- high = inb(TIMER_CNTR0);
-
- return ((high << 8) | low);
+
+ /* Select counter 0 and latch counter value. */
+ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
+
+ low = inb(TIMER_CNTR0);
+ high = inb(TIMER_CNTR0);
+
+ return ((high << 8) | low);
}
// forces cpu to relax for usec miliseconds. declared in kern/include/time.h
diff --git a/kern/arch/x86/topology.c b/kern/arch/x86/topology.c
index d0a27e0..ea2a8c0 100644
--- a/kern/arch/x86/topology.c
+++ b/kern/arch/x86/topology.c
@@ -33,6 +33,7 @@
static void adjust_ids(int id_offset)
{
int new_id = 0, old_id = -1;
+
for (int i = 0; i < num_cores; i++) {
for (int j = 0; j < num_cores; j++) {
int *id_field = ((void*)&core_list[j] + id_offset);
@@ -54,15 +55,18 @@
static void set_socket_ids(void)
{
int socket_id, raw_socket_id;
+
for (int numa_id = 0; numa_id < num_numa; numa_id++) {
socket_id = 0;
for (int i = 0; i < num_cores; i++) {
if (core_list[i].numa_id == numa_id) {
if (core_list[i].socket_id == -1) {
core_list[i].socket_id = socket_id;
- raw_socket_id = core_list[i].raw_socket_id;
+ raw_socket_id =
+ core_list[i].raw_socket_id;
for (int j = i; j < num_cores; j++) {
- if (core_list[j].numa_id == numa_id) {
+ if (core_list[j].numa_id ==
+ numa_id) {
if (core_list[j].raw_socket_id == raw_socket_id) {
core_list[j].socket_id = socket_id;
}
@@ -149,7 +153,8 @@
struct Srat *temp = srat->children[i]->tbl;
if (temp != NULL && temp->type == SRlapic)
- if (is_unique_numa(temp, srat->children, i + 1, srat->nchildren))
+ if (is_unique_numa(temp, srat->children, i + 1,
+ srat->nchildren))
numa++;
}
@@ -179,17 +184,18 @@
static void init_os_coreid_lookup(void)
{
/* Allocate (max_apic_id+1) entries in our os_coreid_lookup table.
- * There may be holes in this table because of the way apic_ids work, but
- * a little wasted space is OK for a constant time lookup of apic_id ->
- * logical core id (from the OS's perspective). Memset the array to -1 to
- * to represent invalid entries (which it's very possible we might have if
- * the apic_id space has holes in it). */
+ * There may be holes in this table because of the way apic_ids work,
+ * but a little wasted space is OK for a constant time lookup of apic_id
+ * -> logical core id (from the OS's perspective). Memset the array to
+ * -1 to to represent invalid entries (which it's very possible we
+ * might have if the apic_id space has holes in it). */
os_coreid_lookup = kmalloc((max_apic_id + 1) * sizeof(int), 0);
memset(os_coreid_lookup, -1, (max_apic_id + 1) * sizeof(int));
- /* Loop through and set all valid entries to 0 to start with (making them
- * temporarily valid, but not yet set to the correct value). This step is
- * necessary because there is no ordering to the linked list we are
+ /* Loop through and set all valid entries to 0 to start with (making
+ * them temporarily valid, but not yet set to the correct value). This
+ * step is necessary because there is no ordering to the linked list we
+ * are
* pulling these ids from. After this, loop back through and set the
* mapping appropriately. */
for (int i = 0; i < apics->nchildren; i++) {
@@ -199,6 +205,7 @@
os_coreid_lookup[temp->lapic.id] = 0;
}
int os_coreid = 0;
+
for (int i = 0; i <= max_apic_id; i++)
if (os_coreid_lookup[i] == 0)
os_coreid_lookup[i] = os_coreid++;
@@ -211,22 +218,24 @@
* with. */
core_list = kzmalloc(num_cores * sizeof(struct core_info), 0);
- /* Loop through all possible apic_ids and fill in the core_list array with
- * *relative* topology info. We will change this relative info to absolute
- * info in a future step. As part of this step, we update our
+ /* Loop through all possible apic_ids and fill in the core_list array
+ * with *relative* topology info. We will change this relative info to
+ * absolute info in a future step. As part of this step, we update our
* os_coreid_lookup array to contain the proper value. */
int os_coreid = 0;
int max_cpus = (1 << cpu_bits);
int max_cores_per_cpu = (1 << core_bits);
int max_logical_cores = (1 << (core_bits + cpu_bits));
int raw_socket_id = 0, cpu_id = 0, core_id = 0;
+
for (int apic_id = 0; apic_id <= max_apic_id; apic_id++) {
if (os_coreid_lookup[apic_id] != -1) {
raw_socket_id = apic_id & ~(max_logical_cores - 1);
cpu_id = (apic_id >> core_bits) & (max_cpus - 1);
core_id = apic_id & (max_cores_per_cpu - 1);
- core_list[os_coreid].numa_id = find_numa_domain(apic_id);
+ core_list[os_coreid].numa_id =
+ find_numa_domain(apic_id);
core_list[os_coreid].raw_socket_id = raw_socket_id;
core_list[os_coreid].socket_id = -1;
core_list[os_coreid].cpu_id = cpu_id;
@@ -236,25 +245,25 @@
}
}
- /* In general, the various id's set in the previous step are all unique in
- * terms of representing the topology (i.e. all cores under the same socket
- * have the same socket_id set), but these id's are not necessarily
- * contiguous, and are only relative to the level of the hierarchy they
- * exist at (e.g. cpu_id 4 may exist under *both* socket_id 0 and
- * socket_id 1). In this step, we squash these id's down so they are
- * contiguous. In a following step, we will make them all absolute instead
- * of relative. */
+ /* In general, the various id's set in the previous step are all unique
+ * in terms of representing the topology (i.e. all cores under the same
+ * socket have the same socket_id set), but these id's are not
+ * necessarily contiguous, and are only relative to the level of the
+ * hierarchy they exist at (e.g. cpu_id 4 may exist under *both*
+ * socket_id 0 and socket_id 1). In this step, we squash these id's down
+ * so they are contiguous. In a following step, we will make them all
+ * absolute instead of relative. */
adjust_ids(offsetof(struct core_info, numa_id));
adjust_ids(offsetof(struct core_info, raw_socket_id));
adjust_ids(offsetof(struct core_info, cpu_id));
adjust_ids(offsetof(struct core_info, core_id));
/* We haven't yet set the socket id of each core yet. So far, all we've
- * extracted is a "raw" socket id from the top bits in our apic id, but we
- * need to condense these down into something workable for a socket id, per
- * numa domain. OSDev has an algorithm for doing so
- * (http://wiki.osdev.org/Detecting_CPU_Topology_%2880x86%29). We adapt it
- * for our setup. */
+ * extracted is a "raw" socket id from the top bits in our apic id, but
+ * we need to condense these down into something workable for a socket
+ * id, per numa domain. OSDev has an algorithm for doing so
+ * (http://wiki.osdev.org/Detecting_CPU_Topology_%2880x86%29).
+ * We adapt it for our setup. */
set_socket_ids();
}
@@ -265,9 +274,10 @@
* with. */
core_list = kzmalloc(num_cores * sizeof(struct core_info), 0);
- /* Loop through all possible apic_ids and fill in the core_list array with
- * flat topology info. */
+ /* Loop through all possible apic_ids and fill in the core_list array
+ * with flat topology info. */
int os_coreid = 0;
+
for (int apic_id = 0; apic_id <= max_apic_id; apic_id++) {
if (os_coreid_lookup[apic_id] != -1) {
core_list[os_coreid].numa_id = 0;
@@ -283,9 +293,9 @@
static void set_remaining_topology_info(void)
{
- /* Assuming we have our core_list set up with relative topology info, loop
- * through our core_list and calculate the other statistics that we hold
- * in our cpu_topology_info struct. */
+ /* Assuming we have our core_list set up with relative topology info,
+ * loop through our core_list and calculate the other statistics that we
+ * hold in our cpu_topology_info struct. */
int last_numa = -1, last_socket = -1, last_cpu = -1, last_core = -1;
for (int i = 0; i < num_cores; i++) {
if (core_list[i].socket_id > last_socket) {
@@ -370,7 +380,7 @@
build_flat_topology();
}
-void print_cpu_topology()
+void print_cpu_topology(void)
{
printk("num_numa: %d, num_sockets: %d, num_cpus: %d, num_cores: %d\n",
num_numa, num_sockets, num_cpus, num_cores);
diff --git a/kern/arch/x86/topology.h b/kern/arch/x86/topology.h
index 6652770..98b3046 100644
--- a/kern/arch/x86/topology.h
+++ b/kern/arch/x86/topology.h
@@ -57,15 +57,16 @@
static inline int numa_id(void)
{
int os_coreid = os_coreid_lookup[lapic_get_id()];
+
return cpu_topology_info.core_list[os_coreid].numa_id;
}
static inline int core_id(void)
{
int coreid;
- /* assuming we're right after stacktop. gs base is the pcpui struct, but we
- * don't have access to the pcpui struct or to the extern per_cpu_info here,
- * due to include loops. */
+ /* assuming we're right after stacktop. gs base is the pcpui struct,
+ * but we don't have access to the pcpui struct or to the extern
+ * per_cpu_info here, due to include loops. */
asm volatile ("movl %%gs:8, %0" : "=r"(coreid));
return coreid;
}
@@ -74,6 +75,7 @@
static inline int core_id_early(void)
{
extern bool core_id_ready;
+
if (!core_id_ready)
return 0;
return core_id();
diff --git a/kern/arch/x86/trap.c b/kern/arch/x86/trap.c
index 01b0dd5..20f53fd 100644
--- a/kern/arch/x86/trap.c
+++ b/kern/arch/x86/trap.c
@@ -89,6 +89,7 @@
void set_stack_top(uintptr_t stacktop)
{
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+
/* No need to reload the task register, this takes effect immediately */
x86_set_stacktop_tss(pcpui->tss, stacktop);
/* Also need to make sure sysenters come in correctly */
@@ -113,6 +114,7 @@
{
/* NMI / IPI for x86 are limited to 8 bits */
uint8_t hw_core = (uint8_t)get_hw_coreid(os_coreid);
+
__send_nmi(hw_core);
}
@@ -138,7 +140,8 @@
* handler with a fake interrupt number (500) that is out of bounds of
* the idt[] */
for (i = 0; i < trap_tbl_size - 1; i++)
- SETGATE(idt[trap_tbl[i].trapnumber], 0, GD_KT, trap_tbl[i].trapaddr, 0);
+ SETGATE(idt[trap_tbl[i].trapnumber], 0, GD_KT,
+ trap_tbl[i].trapaddr, 0);
/* Sanity check */
assert((uintptr_t)ISR_syscall ==
((uintptr_t)idt[T_SYSCALL].gd_off_63_32 << 32 |
@@ -163,8 +166,8 @@
/* We will set this properly once we have a kstack from the slab. */
set_stack_top(0xdeadbeef);
- /* Initialize the TSS field of the gdt. The size of the TSS desc differs
- * between 64 and 32 bit, hence the pointer acrobatics */
+ /* Initialize the TSS field of the gdt. The size of the TSS desc
+ * differs between 64 and 32 bit, hence the pointer acrobatics */
syssegdesc_t *ts_slot = (syssegdesc_t*)&gdt[GD_TSS >> 3];
*ts_slot = (syssegdesc_t)SEG_SYS_SMALL(STS_T32A, (uintptr_t)&ts,
sizeof(taskstate_t), 0);
@@ -189,8 +192,8 @@
num_cores_mpacpi = MAX_NUM_CORES - ncleft;
printk("MP and ACPI found %d cores\n", num_cores_mpacpi);
if (num_cores != num_cores_mpacpi)
- warn("Topology (%d) and MP/ACPI (%d) differ on num_cores!", num_cores,
- num_cores_mpacpi);
+ warn("Topology (%d) and MP/ACPI (%d) differ on num_cores!",
+ num_cores, num_cores_mpacpi);
apiconline();
ioapiconline();
@@ -202,7 +205,8 @@
MKBUS(BusLAPIC, 0, 0, 0));
register_irq(IdtLAPIC_PCINT, perfmon_interrupt, NULL,
MKBUS(BusLAPIC, 0, 0, 0));
- register_irq(I_KERNEL_MSG, handle_kmsg_ipi, NULL, MKBUS(BusIPI, 0, 0, 0));
+ register_irq(I_KERNEL_MSG, handle_kmsg_ipi, NULL,
+ MKBUS(BusIPI, 0, 0, 0));
}
static void print_fperr(struct hw_trapframe *hw_tf)
@@ -215,8 +219,8 @@
asm volatile ("stmxcsr %0" : "=m"(mxcsr));
print_lock();
print_trapframe(hw_tf);
- printk("Core %d: FP ERR, CW: 0x%04x, SW: 0x%04x, MXCSR 0x%08x\n", core_id(),
- fpcw, fpsw, mxcsr);
+ printk("Core %d: FP ERR, CW: 0x%04x, SW: 0x%04x, MXCSR 0x%08x\n",
+ core_id(), fpcw, fpsw, mxcsr);
printk("Core %d: The following faults are unmasked:\n", core_id());
if (fpsw & ~fpcw & FP_EXCP_IE) {
printk("\tInvalid Operation: ");
@@ -273,30 +277,31 @@
}
/* In general, if there's no cur_proc, a KPF is a bug. */
if (!pcpui->cur_proc) {
- /* This only runs from test_uaccess(), where it is expected to fail. */
+ /* This only runs from test_uaccess(), where it is expected to
+ * fail. */
if (try_handle_exception_fixup(hw_tf))
return TRUE;
panic_hwtf(hw_tf, "Proc-less Page Fault in the Kernel at %p!",
fault_va);
}
- /* TODO - handle kernel page faults. This is dangerous, since we might be
- * holding locks in the kernel and could deadlock when we HPF. For now, I'm
- * just disabling the lock checker, since it'll flip out when it sees there
- * is a kernel trap. Will need to think about this a bit, esp when we
- * properly handle bad addrs and whatnot. */
+ /* TODO - handle kernel page faults. This is dangerous, since we might
+ * be holding locks in the kernel and could deadlock when we HPF. For
+ * now, I'm just disabling the lock checker, since it'll flip out when
+ * it sees there is a kernel trap. Will need to think about this a bit,
+ * esp when we properly handle bad addrs and whatnot. */
pcpui->__lock_checking_enabled--;
- /* It is a bug for the kernel to access user memory while holding locks that
- * are used by handle_page_fault. At a minimum, this includes p->vmr_lock
- * and memory allocation locks.
+ /* It is a bug for the kernel to access user memory while holding locks
+ * that are used by handle_page_fault. At a minimum, this includes
+ * p->vmr_lock and memory allocation locks.
*
- * In an effort to reduce the number of locks (both now and in the future),
- * the kernel will not attempt to handle faults on file-back VMRs. We
- * probably can turn that on in the future, but I'd rather keep things safe
- * for now. (We'll probably need to change this when we stop
- * MAP_POPULATE | MAP_LOCKED entire binaries).
+ * In an effort to reduce the number of locks (both now and in the
+ * future), the kernel will not attempt to handle faults on file-back
+ * VMRs. We probably can turn that on in the future, but I'd rather
+ * keep things safe for now. (We'll probably need to change this when
+ * we stop MAP_POPULATE | MAP_LOCKED entire binaries).
*
- * Note that we do not enable IRQs here, unlike in the user case. Again,
- * this is to limit the locks we could be grabbing. */
+ * Note that we do not enable IRQs here, unlike in the user case.
+ * Again, this is to limit the locks we could be grabbing. */
err = handle_page_fault_nofile(pcpui->cur_proc, fault_va, prot);
pcpui->__lock_checking_enabled++;
if (err) {
@@ -309,11 +314,12 @@
*(uintptr_t*)(hw_tf->tf_rsp + 8),
*(uintptr_t*)(hw_tf->tf_rsp + 16),
*(uintptr_t*)(hw_tf->tf_rsp + 24));
- panic_hwtf(hw_tf, "Proc-ful Page Fault in the Kernel at %p!", fault_va);
- /* if we want to do something like kill a process or other code, be
- * aware we are in a sort of irq-like context, meaning the main
- * kernel code we 'interrupted' could be holding locks - even
- * irqsave locks. */
+ panic_hwtf(hw_tf, "Proc-ful Page Fault in the Kernel at %p!",
+ fault_va);
+ /* if we want to do something like kill a process or other code,
+ * be aware we are in a sort of irq-like context, meaning the
+ * main kernel code we 'interrupted' could be holding locks -
+ * even irqsave locks. */
}
return TRUE;
}
@@ -334,15 +340,16 @@
static void do_nmi_work(struct hw_trapframe *hw_tf)
{
assert(!irq_is_enabled());
- /* It's mostly harmless to snapshot the TF, and we can send a spurious PCINT
- * interrupt. perfmon.c just uses the interrupt to tell it to check its
- * counters for overflow. Note that the PCINT interrupt is just a regular
- * IRQ. The backtrace was recorded during the NMI and emitted during IRQ.
+ /* It's mostly harmless to snapshot the TF, and we can send a spurious
+ * PCINT interrupt. perfmon.c just uses the interrupt to tell it to
+ * check its counters for overflow. Note that the PCINT interrupt is
+ * just a regular IRQ. The backtrace was recorded during the NMI and
+ * emitted during IRQ.
*
* That being said, it's OK if the monitor triggers debugging NMIs while
* perf is running. If perf triggers an NMI when the monitor wants to
- * print, the monitor will debug *that* NMI, and not the one that gets sent
- * moments later. That's fine. */
+ * print, the monitor will debug *that* NMI, and not the one that gets
+ * sent moments later. That's fine. */
emit_monitor_backtrace(ROS_HW_CTX, hw_tf);
perfmon_snapshot_hwtf(hw_tf);
send_self_ipi(IdtLAPIC_PCINT);
@@ -397,35 +404,40 @@
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
while (1) {
- /* Signal that we're doing work. A concurrent NMI will set this to
- * NMI_HANDLE_ANOTHER if we should continue, which we'll catch later. */
+ /* Signal that we're doing work. A concurrent NMI will set this
+ * to NMI_HANDLE_ANOTHER if we should continue, which we'll
+ * catch later. */
pcpui->nmi_status = NMI_IN_PROGRESS;
do_nmi_work(hw_tf);
- /* We need to check nmi_status to see if it is NMI_HANDLE_ANOTHER (if
- * so, run again), write NMI_NORMAL_OPN, leave this stack, and return to
- * the original context. We need to do that in such a manner that an
- * NMI can come in at any time. There are two concerns.
+ /* We need to check nmi_status to see if it is
+ * NMI_HANDLE_ANOTHER (if so, run again), write NMI_NORMAL_OPN,
+ * leave this stack, and return to the original context. We
+ * need to do that in such a manner that an NMI can come in at
+ * any time. There are two concerns.
*
- * First, we need to not "miss the signal" telling us to re-run the NMI
- * handler. To do that, we'll do the actual checking in asm. Being in
- * the asm code block is a signal to the real NMI handler that we need
- * to abort and do_nmi_work() again.
+ * First, we need to not "miss the signal" telling us to re-run
+ * the NMI handler. To do that, we'll do the actual checking in
+ * asm. Being in the asm code block is a signal to the real NMI
+ * handler that we need to abort and do_nmi_work() again.
*
- * Second, we need to atomically leave the stack and return. By being
- * in asm, the NMI handler knows to just hack our PC to make us return,
- * instead of starting up a fresh __nmi_bottom_half().
+ * Second, we need to atomically leave the stack and return. By
+ * being in asm, the NMI handler knows to just hack our PC to
+ * make us return, instead of starting up a fresh
+ * __nmi_bottom_half().
*
- * The NMI handler works together with the following function such that
- * if that race occurs while we're in the function, it'll fail and
- * return. Then we'll just do_nmi_work() and try again. */
+ * The NMI handler works together with the following function
+ * such that if that race occurs while we're in the function,
+ * it'll fail and return. Then we'll just do_nmi_work() and try
+ * again. */
extern void nmi_try_to_pop(struct hw_trapframe *tf, int *status,
int old_val, int new_val);
nmi_try_to_pop(hw_tf, &pcpui->nmi_status, NMI_IN_PROGRESS,
NMI_NORMAL_OPN);
- /* Either we returned on our own, since we lost a race with nmi_status
- * and didn't write (status = ANOTHER), or we won the race, but an NMI
- * handler set the status to ANOTHER and restarted us. */
+ /* Either we returned on our own, since we lost a race with
+ * nmi_status and didn't write (status = ANOTHER), or we won the
+ * race, but an NMI handler set the status to ANOTHER and
+ * restarted us. */
assert(pcpui->nmi_status != NMI_NORMAL_OPN);
}
}
@@ -469,65 +481,67 @@
uintptr_t worker_stacktop;
/* At this point, we're an NMI and other NMIs are blocked. Only once we
- * hop to the bottom half could that be no longer true. NMI with NMIs fully
- * blocked will run without interruption. For that reason, we don't have to
- * be careful about any memory accesses or compiler tricks. */
+ * hop to the bottom half could that be no longer true. NMI with NMIs
+ * fully blocked will run without interruption. For that reason, we
+ * don't have to be careful about any memory accesses or compiler
+ * tricks. */
if (pcpui->nmi_status == NMI_HANDLE_ANOTHER)
return;
if (pcpui->nmi_status == NMI_IN_PROGRESS) {
/* Force the handler to run again. We don't need to worry about
- * concurrent access here. We're running, they are not. We cannot
- * 'PAUSE' since NMIs are fully blocked.
+ * concurrent access here. We're running, they are not. We
+ * cannot 'PAUSE' since NMIs are fully blocked.
*
- * The asm routine, for its part, does a compare-and-swap, so if we
- * happened to interrupt it before it wrote NMI_NORMAL_OPN, it'll
- * notice, abort, and not write the status. */
+ * The asm routine, for its part, does a compare-and-swap, so if
+ * we happened to interrupt it before it wrote NMI_NORMAL_OPN,
+ * it'll notice, abort, and not write the status. */
pcpui->nmi_status = NMI_HANDLE_ANOTHER;
return;
}
assert(pcpui->nmi_status == NMI_NORMAL_OPN);
pcpui->nmi_status = NMI_HANDLE_ANOTHER;
- /* We could be interrupting an NMI that is trying to pop back to a normal
- * context. We can tell by looking at its PC. If it is within the popping
- * routine, then we interrupted it at this bad time. We'll hack the TF such
- * that it will return instead of succeeding. */
+ /* We could be interrupting an NMI that is trying to pop back to a
+ * normal context. We can tell by looking at its PC. If it is within
+ * the popping routine, then we interrupted it at this bad time. We'll
+ * hack the TF such that it will return instead of succeeding. */
if (nmi_check_and_hack_tf(hw_tf))
return;
- /* OK, so we didn't interrupt an NMI that was trying to return. So we need
- * to run the bottom half. We're going to jump stacks, but we also need to
- * copy the hw_tf. The existing one will be clobbered by any interrupting
- * NMIs.
+ /* OK, so we didn't interrupt an NMI that was trying to return. So we
+ * need to run the bottom half. We're going to jump stacks, but we also
+ * need to copy the hw_tf. The existing one will be clobbered by any
+ * interrupting NMIs.
*
- * We also need to save some space on the top of that stack for a pointer to
- * pcpui and a scratch register, which nmi_try_to_pop() will use. The
- * target stack will look like this:
+ * We also need to save some space on the top of that stack for a
+ * pointer to pcpui and a scratch register, which nmi_try_to_pop() will
+ * use. The target stack will look like this:
*
- * +--------------------------+ Page boundary (e.g. 0x6000)
- * | scratch space (rsp) |
- * | pcpui pointer |
- * | tf_ss + padding | HW_TF end
- * | tf_rsp |
- * | . |
- * | . |
- * RSP -> | tf_gsbase | HW_TF start, hw_tf_copy
- * +--------------------------+
- * | . |
- * | . |
- * | . |
- * +--------------------------+ Page boundary (e.g. 0x5000)
+ * +--------------------------+ Page boundary (e.g. 0x6000)
+ * | scratch space (rsp) |
+ * | pcpui pointer |
+ * | tf_ss + padding | HW_TF end
+ * | tf_rsp |
+ * | . |
+ * | . |
+ * RSP -> | tf_gsbase | HW_TF start, hw_tf_copy
+ * +--------------------------+
+ * | . |
+ * | . |
+ * | . |
+ * +--------------------------+ Page boundary (e.g. 0x5000)
*
- * __nmi_bottom_half() just picks up using the stack below tf_gsbase. It'll
- * push as needed, growing down. Basically we're just using the space
- * 'above' the stack as storage. */
+ * __nmi_bottom_half() just picks up using the stack below tf_gsbase.
+ * It'll push as needed, growing down. Basically we're just using the
+ * space 'above' the stack as storage. */
worker_stacktop = pcpui->nmi_worker_stacktop - 2 * sizeof(uintptr_t);
*(uintptr_t*)worker_stacktop = (uintptr_t)pcpui;
worker_stacktop = worker_stacktop - sizeof(struct hw_trapframe);
hw_tf_copy = (struct hw_trapframe*)worker_stacktop;
*hw_tf_copy = *hw_tf;
- /* Once we head to the bottom half, consider ourselves interruptible (though
- * it's not until the first time we do_nmi_work()). We'll never come back
- * to this stack. Doing this in asm so we can easily pass an argument. We
- * don't need to call (vs jmp), but it helps keep the stack aligned. */
+ /* Once we head to the bottom half, consider ourselves interruptible
+ * (though it's not until the first time we do_nmi_work()). We'll never
+ * come back to this stack. Doing this in asm so we can easily pass an
+ * argument. We don't need to call (vs jmp), but it helps keep the
+ * stack aligned. */
asm volatile("mov $0x0, %%rbp;"
"mov %0, %%rsp;"
"call __nmi_bottom_half;"
@@ -551,63 +565,67 @@
// Handle processor exceptions.
switch(hw_tf->tf_trapno) {
- case T_BRKPT:
- if (!in_kernel(hw_tf))
- backtrace_user_ctx(current, current_ctx);
- else
- monitor(hw_tf);
+ case T_BRKPT:
+ if (!in_kernel(hw_tf))
+ backtrace_user_ctx(current, current_ctx);
+ else
+ monitor(hw_tf);
+ handled = TRUE;
+ break;
+ case T_ILLOP:
+ {
+ /* TODO: this can PF if there is a concurrent unmap/PM removal.
+ * */
+ uintptr_t ip = get_hwtf_pc(hw_tf);
+
+ pcpui = &per_cpu_info[core_id()];
+ pcpui->__lock_checking_enabled--; /* for print debugging */
+ /* We will muck with the actual TF. If we're dealing with
+ * userspace, we need to make sure we edit the actual TF that
+ * will get restarted (pcpui), and not the TF on the kstack
+ * (which aren't the same). See set_current_ctx() for more
+ * info. */
+ if (!in_kernel(hw_tf))
+ hw_tf = &pcpui->cur_ctx->tf.hw_tf;
+ printd("bad opcode, eip: %p, next 3 bytes: %x %x %x\n", ip,
+ *(uint8_t*)(ip + 0),
+ *(uint8_t*)(ip + 1),
+ *(uint8_t*)(ip + 2));
+ /* rdtscp: 0f 01 f9 */
+ if (*(uint8_t*)(ip + 0) == 0x0f,
+ *(uint8_t*)(ip + 1) == 0x01,
+ *(uint8_t*)(ip + 2) == 0xf9) {
+ x86_fake_rdtscp(hw_tf);
handled = TRUE;
- break;
- case T_ILLOP:
- {
- /* TODO: this can PF if there is a concurrent unmap/PM removal. */
- uintptr_t ip = get_hwtf_pc(hw_tf);
- pcpui = &per_cpu_info[core_id()];
- pcpui->__lock_checking_enabled--; /* for print debugging */
- /* We will muck with the actual TF. If we're dealing with
- * userspace, we need to make sure we edit the actual TF that will
- * get restarted (pcpui), and not the TF on the kstack (which aren't
- * the same). See set_current_ctx() for more info. */
- if (!in_kernel(hw_tf))
- hw_tf = &pcpui->cur_ctx->tf.hw_tf;
- printd("bad opcode, eip: %p, next 3 bytes: %x %x %x\n", ip,
- *(uint8_t*)(ip + 0),
- *(uint8_t*)(ip + 1),
- *(uint8_t*)(ip + 2));
- /* rdtscp: 0f 01 f9 */
- if (*(uint8_t*)(ip + 0) == 0x0f,
- *(uint8_t*)(ip + 1) == 0x01,
- *(uint8_t*)(ip + 2) == 0xf9) {
- x86_fake_rdtscp(hw_tf);
- handled = TRUE;
- }
- pcpui->__lock_checking_enabled++; /* for print debugging */
- break;
}
- case T_PGFLT:
- handled = __handle_page_fault(hw_tf, &aux);
- break;
- case T_GPFLT:
- case T_FPERR:
- handled = try_handle_exception_fixup(hw_tf);
- break;
- case T_SYSCALL:
- enable_irq();
- // check for userspace, for now
- assert(hw_tf->tf_cs != GD_KT);
- /* Set up and run the async calls */
- /* TODO: this is using the wrong reg1 for traps for 32 bit */
- prep_syscalls(current,
- (struct syscall*)x86_get_systrap_arg0(hw_tf),
- (unsigned int)x86_get_systrap_arg1(hw_tf));
- disable_irq();
- handled = TRUE;
- break;
+ pcpui->__lock_checking_enabled++; /* for print debugging */
+ break;
+ }
+ case T_PGFLT:
+ handled = __handle_page_fault(hw_tf, &aux);
+ break;
+ case T_GPFLT:
+ case T_FPERR:
+ handled = try_handle_exception_fixup(hw_tf);
+ break;
+ case T_SYSCALL:
+ enable_irq();
+ // check for userspace, for now
+ assert(hw_tf->tf_cs != GD_KT);
+ /* Set up and run the async calls */
+ /* TODO: this is using the wrong reg1 for traps for 32 bit */
+ prep_syscalls(current,
+ (struct syscall*)x86_get_systrap_arg0(hw_tf),
+ (unsigned int)x86_get_systrap_arg1(hw_tf));
+ disable_irq();
+ handled = TRUE;
+ break;
}
if (!handled) {
if (in_kernel(hw_tf))
- panic_hwtf(hw_tf, "Damn Damn! Unhandled trap in the kernel!");
+ panic_hwtf(hw_tf,
+ "Damn Damn! Unhandled trap in the kernel!");
reflect_unhandled_trap(hw_tf->tf_trapno, hw_tf->tf_err, aux);
}
}
@@ -654,6 +672,7 @@
void trap(struct hw_trapframe *hw_tf)
{
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+
/* Copy out the TF for now */
if (!in_kernel(hw_tf)) {
set_current_ctx_hw(pcpui, hw_tf);
@@ -667,9 +686,9 @@
if ((hw_tf->tf_cs & ~3) != GD_UT && (hw_tf->tf_cs & ~3) != GD_KT)
panic_hwtf(hw_tf, "Trapframe with invalid CS!");
trap_dispatch(hw_tf);
- /* Return to the current process, which should be runnable. If we're the
- * kernel, we should just return naturally. Note that current and tf need
- * to still be okay (might not be after blocking) */
+ /* Return to the current process, which should be runnable. If we're
+ * the kernel, we should just return naturally. Note that current and
+ * tf need to still be okay (might not be after blocking) */
if (in_kernel(hw_tf)) {
dec_ktrap_depth(pcpui);
return;
@@ -703,8 +722,8 @@
if (!irq_h) {
warn_once("Received IRQ %d, had no handler registered!",
hw_tf->tf_trapno);
- /* If we don't have an IRQ handler, we don't know how to EOI. Odds are,
- * it's a LAPIC IRQ, such as I_TESTING */
+ /* If we don't have an IRQ handler, we don't know how to EOI.
+ * Odds are, it's a LAPIC IRQ, such as I_TESTING */
if (!lapic_check_spurious(hw_tf->tf_trapno))
lapic_send_eoi(hw_tf->tf_trapno);
goto out_no_eoi;
@@ -722,7 +741,8 @@
extern handler_wrapper_t handler_wrappers[NUM_HANDLER_WRAPPERS];
if ((I_SMP_CALL0 <= hw_tf->tf_trapno) &&
(hw_tf->tf_trapno <= I_SMP_CALL_LAST))
- down_checklist(handler_wrappers[hw_tf->tf_trapno & 0x0f].cpu_list);
+ down_checklist(handler_wrappers[hw_tf->tf_trapno & 0x0f]
+ .cpu_list);
disable_irq();
/* Keep in sync with ipi_is_pending */
irq_handlers[hw_tf->tf_trapno]->eoi(hw_tf->tf_trapno);
@@ -750,9 +770,9 @@
if (!in_kernel(hw_tf))
set_current_ctx_hw(pcpui, hw_tf);
irq_dispatch(hw_tf);
- /* Return to the current process, which should be runnable. If we're the
- * kernel, we should just return naturally. Note that current and tf need
- * to still be okay (might not be after blocking) */
+ /* Return to the current process, which should be runnable. If we're
+ * the kernel, we should just return naturally. Note that current and
+ * tf need to still be okay (might not be after blocking) */
if (in_kernel(hw_tf))
return;
proc_restartcore();
@@ -764,6 +784,7 @@
{
struct irq_handler *irq_h;
int vector;
+
irq_h = kzmalloc(sizeof(struct irq_handler), 0);
assert(irq_h);
irq_h->dev_irq = irq;
@@ -810,7 +831,8 @@
}
hw_coreid = get_hw_coreid(os_coreid);
if (hw_coreid == -1) {
- printk("[kernel] os_coreid %d not a valid hw core!\n", os_coreid);
+ printk("[kernel] os_coreid %d not a valid hw core!\n",
+ os_coreid);
return -1;
}
irq_h->route_irq(irq_h, irq_h->apic_vector, hw_coreid);
@@ -824,6 +846,7 @@
{
struct irq_handler *irq_h;
int ret = -1;
+
if (!vector_is_irq(apic_vec)) {
printk("[kernel] vector %d is not an IRQ vector!\n", apic_vec);
return -1;
@@ -845,12 +868,12 @@
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
set_current_ctx_sw(pcpui, sw_tf);
__set_cpu_state(pcpui, CPU_STATE_KERNEL);
- /* Once we've set_current_ctx, we can enable interrupts. This used to be
- * mandatory (we had immediate KMSGs that would muck with cur_ctx). Now it
- * should only help for sanity/debugging. */
+ /* Once we've set_current_ctx, we can enable interrupts. This used to
+ * be mandatory (we had immediate KMSGs that would muck with cur_ctx).
+ * Now it should only help for sanity/debugging. */
enable_irq();
- /* Set up and run the async calls. This may block, and we could migrate to
- * another core. If you use pcpui again, you need to reread it. */
+ /* Set up and run the async calls. This may block, and we could migrate
+ * to another core. If you use pcpui again, you need to reread it. */
prep_syscalls(current, sysc, count);
disable_irq();
proc_restartcore();
@@ -860,6 +883,7 @@
void send_ipi(uint32_t os_coreid, uint8_t vector)
{
int hw_coreid = get_hw_coreid(os_coreid);
+
if (hw_coreid == -1) {
panic("Unmapped OS coreid (OS %d)!\n", os_coreid);
return;
@@ -882,62 +906,63 @@
cpuid(tf->tf_rax, tf->tf_rcx, &eax, &ebx, &ecx, &edx);
switch (tf->tf_rax) {
- /* TODO: If we can move this to userspace, vmrunkernel can make GPCS on
- * the fly. */
- case 0x01:
- /* Set the hypervisor bit to let the guest know it is virtualized */
- ecx |= 1 << 31;
- /* Unset the monitor capability bit so that the guest does not try
- * to use monitor/mwait. */
- ecx &= ~(1 << 3);
- /* Unset the vmx capability bit so that the guest does not try
- * to turn it on. */
- ecx &= ~(1 << 5);
- /* Unset the perf capability bit so that the guest does not try
- * to turn it on. */
- ecx &= ~(1 << 15);
+ /* TODO: If we can move this to userspace, vmrunkernel can make GPCS on
+ * the fly. */
+ case 0x01:
+ /* Set the hypervisor bit to let the guest know it is
+ * virtualized */
+ ecx |= 1 << 31;
+ /* Unset the monitor capability bit so that the guest does not
+ * try to use monitor/mwait. */
+ ecx &= ~(1 << 3);
+ /* Unset the vmx capability bit so that the guest does not try
+ * to turn it on. */
+ ecx &= ~(1 << 5);
+ /* Unset the perf capability bit so that the guest does not try
+ * to turn it on. */
+ ecx &= ~(1 << 15);
- /* Set the guest pcore id into the apic ID field in CPUID. */
- ebx &= 0x0000ffff;
- ebx |= (current->vmm.nr_guest_pcores & 0xff) << 16;
- ebx |= (tf->tf_guest_pcoreid & 0xff) << 24;
- break;
- case 0x0A:
- eax = 0;
- ebx = 0;
- ecx = 0;
- edx = 0;
- break;
- /* Signal the use of KVM. */
- case 0x40000000:
- sigptr = (const uint32_t *)kvm_sig;
- eax = 0;
- ebx = sigptr[0];
- ecx = sigptr[1];
- edx = sigptr[2];
- break;
- /* Hypervisor Features. */
- case 0x40000003:
- /* Unset the monitor capability bit so that the guest does not try
- * to use monitor/mwait. */
- edx &= ~(1 << 0);
- break;
- /* Signal the use of AKAROS. */
- case 0x40000100:
- sigptr = (const uint32_t *)akaros_sig;
- eax = 0;
- ebx = sigptr[0];
- ecx = sigptr[1];
- edx = sigptr[2];
- break;
- /* Hypervisor Features. */
- case 0x40000103:
- /* Unset the monitor capability bit so that the guest does not try
- * to use monitor/mwait. */
- edx &= ~(1 << 0);
- break;
- default:
- break;
+ /* Set the guest pcore id into the apic ID field in CPUID. */
+ ebx &= 0x0000ffff;
+ ebx |= (current->vmm.nr_guest_pcores & 0xff) << 16;
+ ebx |= (tf->tf_guest_pcoreid & 0xff) << 24;
+ break;
+ case 0x0A:
+ eax = 0;
+ ebx = 0;
+ ecx = 0;
+ edx = 0;
+ break;
+ /* Signal the use of KVM. */
+ case 0x40000000:
+ sigptr = (const uint32_t *)kvm_sig;
+ eax = 0;
+ ebx = sigptr[0];
+ ecx = sigptr[1];
+ edx = sigptr[2];
+ break;
+ /* Hypervisor Features. */
+ case 0x40000003:
+ /* Unset the monitor capability bit so that the guest does not
+ * try to use monitor/mwait. */
+ edx &= ~(1 << 0);
+ break;
+ /* Signal the use of AKAROS. */
+ case 0x40000100:
+ sigptr = (const uint32_t *)akaros_sig;
+ eax = 0;
+ ebx = sigptr[0];
+ ecx = sigptr[1];
+ edx = sigptr[2];
+ break;
+ /* Hypervisor Features. */
+ case 0x40000103:
+ /* Unset the monitor capability bit so that the guest does not
+ * try to use monitor/mwait. */
+ edx &= ~(1 << 0);
+ break;
+ default:
+ break;
}
tf->tf_rax = eax;
tf->tf_rbx = ebx;
@@ -967,15 +992,17 @@
}
/* Regarding NMI blocking,
- * "An NMI causes subsequent NMIs to be blocked, but only after the VM exit
- * completes." (SDM)
+ * "An NMI causes subsequent NMIs to be blocked, but only after the VM exit
+ * completes." (SDM)
*
* Like handle_nmi(), this function and anything it calls directly cannot fault,
* or else we lose our NMI protections. */
static bool handle_vmexit_nmi(struct vm_trapframe *tf)
{
- /* Sanity checks, make sure we really got an NMI. Feel free to remove. */
- assert((tf->tf_intrinfo2 & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR);
+ /* Sanity checks, make sure we really got an NMI. Feel free to remove.
+ */
+ assert((tf->tf_intrinfo2 & INTR_INFO_INTR_TYPE_MASK)
+ == INTR_TYPE_NMI_INTR);
assert((tf->tf_intrinfo2 & INTR_INFO_VECTOR_MASK) == T_NMI);
assert(!irq_is_enabled());
@@ -989,9 +1016,8 @@
{
bool ret;
- ret = vmm_emulate_msr(tf,
- (tf->tf_exit_reason == EXIT_REASON_MSR_READ
- ? VMM_MSR_EMU_READ : VMM_MSR_EMU_WRITE));
+ ret = vmm_emulate_msr(tf, (tf->tf_exit_reason == EXIT_REASON_MSR_READ
+ ? VMM_MSR_EMU_READ : VMM_MSR_EMU_WRITE));
if (ret)
tf->tf_rip += 2;
return ret;
@@ -1002,9 +1028,10 @@
struct hw_trapframe hw_tf;
uint32_t trap_nr;
- /* For now, we just handle external IRQs. I think guest traps should go to
- * the guest, based on our vmctls */
- assert((tf->tf_intrinfo2 & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_EXT_INTR);
+ /* For now, we just handle external IRQs. I think guest traps should go
+ * to the guest, based on our vmctls */
+ assert((tf->tf_intrinfo2 & INTR_INFO_INTR_TYPE_MASK)
+ == INTR_TYPE_EXT_INTR);
/* The POKE_HANDLER doesn't run for an ExtINT that triggers a vmexit */
trap_nr = tf->tf_intrinfo2 & INTR_INFO_VECTOR_MASK;
if (trap_nr == I_POKE_CORE) {
@@ -1012,8 +1039,8 @@
return TRUE;
}
/* TODO: Our IRQ handlers all expect TFs. Let's fake one. A bunch of
- * handlers (e.g. backtrace/perf) will probably be unhappy about a user TF
- * that is really a VM, so this all needs work. */
+ * handlers (e.g. backtrace/perf) will probably be unhappy about a user
+ * TF that is really a VM, so this all needs work. */
hw_tf.tf_gsbase = 0;
hw_tf.tf_fsbase = 0;
hw_tf.tf_rax = tf->tf_rax;
@@ -1052,8 +1079,8 @@
// If the VM tries to set xcr0 to a superset
// of Akaros's default value, kill the VM.
- // Bit in vm_rfbm and x86_default_xcr0: Ok. Requested and allowed.
- // Bit in vm_rfbm but not x86_default_xcr0: Bad! Requested, not allowed.
+ // Bit in vm_rfbm and x86_default_xcr0: Ok. Requested and allowed.
+ // Bit in vm_rfbm but not x86_default_xcr0: Bad! Requested, not allowed.
// Bit not in vm_rfbm but in x86_default_xcr0: Ok. Not requested.
// vm_rfbm & (~x86_default_xcr0) is nonzero if any bits
@@ -1081,13 +1108,14 @@
/* Do not block in any of these functions.
*
- * If we block, we'll probably need to finalize the context. If we do, then
- * there's a chance the guest pcore can start somewhere else, and then we
- * can't get the GPC loaded again. Plus, they could be running a GPC with
- * an unresolved vmexit. It's just mess.
+ * If we block, we'll probably need to finalize the context. If we do,
+ * then there's a chance the guest pcore can start somewhere else, and
+ * then we can't get the GPC loaded again. Plus, they could be running
+ * a GPC with an unresolved vmexit. It's just mess.
*
- * If we want to enable IRQs, we can do so on a case-by-case basis. Don't
- * do it for external IRQs - the irq_dispatch code will handle it. */
+ * If we want to enable IRQs, we can do so on a case-by-case basis.
+ * Don't do it for external IRQs - the irq_dispatch code will handle it.
+ * */
switch (tf->tf_exit_reason) {
case EXIT_REASON_VMCALL:
if (current->vmm.flags & VMM_CTL_FL_KERN_PRINTC &&
@@ -1117,14 +1145,15 @@
handled = handle_vmexit_xsetbv(tf);
break;
default:
- printd("Unhandled vmexit: reason 0x%x, exit qualification 0x%x\n",
+ printd("Unhandled vmexit: reason 0x%x, exit qual 0x%x\n",
tf->tf_exit_reason, tf->tf_exit_qual);
}
if (!handled) {
tf->tf_flags |= VMCTX_FL_HAS_FAULT;
if (reflect_current_context()) {
- /* VM contexts shouldn't be in vcore context, so this should be
- * pretty rare (unlike SCPs or VC ctx page faults). */
+ /* VM contexts shouldn't be in vcore context, so this
+ * should be pretty rare (unlike SCPs or VC ctx page
+ * faults). */
printk("[kernel] Unable to reflect VM Exit\n");
print_vmtrapframe(tf);
proc_destroy(current);
@@ -1155,9 +1184,9 @@
__set_cpu_state(pcpui, CPU_STATE_KERNEL);
tf = &pcpui->cur_ctx->tf.vm_tf;
vmexit_dispatch(tf);
- /* We're either restarting a partial VM ctx (vmcs was launched, loaded on
- * the core, etc) or a SW vc ctx for the reflected trap. Or the proc is
- * dying and we'll handle a __death KMSG shortly. */
+ /* We're either restarting a partial VM ctx (vmcs was launched, loaded
+ * on the core, etc) or a SW vc ctx for the reflected trap. Or the proc
+ * is dying and we'll handle a __death KMSG shortly. */
proc_restartcore();
}
diff --git a/kern/arch/x86/trap.h b/kern/arch/x86/trap.h
index 0f9a7a8..051b9c6 100644
--- a/kern/arch/x86/trap.h
+++ b/kern/arch/x86/trap.h
@@ -31,84 +31,84 @@
#define T_SIMDERR 19 // SIMD floating point error
/* 32-47 are PIC/8259 IRQ vectors */
-#define IdtPIC 32
-#define IrqCLOCK 0
-#define IrqKBD 1
-#define IrqUART1 3
-#define IrqUART0 4
-#define IrqPCMCIA 5
-#define IrqFLOPPY 6
-#define IrqLPT 7
-#define IrqAUX 12 /* PS/2 port */
-#define IrqIRQ13 13 /* coprocessor on 386 */
-#define IrqATA0 14
-#define IrqATA1 15
-#define MaxIrqPIC 15
-#define MaxIdtPIC (IdtPIC + MaxIrqPIC)
+#define IdtPIC 32
+#define IrqCLOCK 0
+#define IrqKBD 1
+#define IrqUART1 3
+#define IrqUART0 4
+#define IrqPCMCIA 5
+#define IrqFLOPPY 6
+#define IrqLPT 7
+#define IrqAUX 12 /* PS/2 port */
+#define IrqIRQ13 13 /* coprocessor on 386 */
+#define IrqATA0 14
+#define IrqATA1 15
+#define MaxIrqPIC 15
+#define MaxIdtPIC (IdtPIC + MaxIrqPIC)
/* T_SYSCALL is defined by the following include (48) */
#include <ros/arch/syscall.h>
/* 49-223 are IOAPIC routing vectors (from IOAPIC to LAPIC) */
-#define IdtIOAPIC (T_SYSCALL + 1)
-#define MaxIdtIOAPIC 223
+#define IdtIOAPIC (T_SYSCALL + 1)
+#define MaxIdtIOAPIC 223
/* 224-239 are OS IPI vectors (0xe0-0xef) */
/* smp_call_function IPIs, keep in sync with NUM_HANDLER_WRAPPERS.
* SMP_CALL0 needs to be 16-aligned (we mask in x86/trap.c). If you move these,
* also change INIT_HANDLER_WRAPPER */
-#define I_SMP_CALL0 224
-#define I_SMP_CALL1 (I_SMP_CALL0 + 1)
-#define I_SMP_CALL2 (I_SMP_CALL0 + 2)
-#define I_SMP_CALL3 (I_SMP_CALL0 + 3)
-#define I_SMP_CALL4 (I_SMP_CALL0 + 4)
-#define I_SMP_CALL_LAST I_SMP_CALL4
-#define I_TESTING 236 /* Testing IPI (used in testing.c) */
-#define I_POKE_GUEST 237
-#define I_POKE_CORE 238
-#define I_KERNEL_MSG 239
+#define I_SMP_CALL0 224
+#define I_SMP_CALL1 (I_SMP_CALL0 + 1)
+#define I_SMP_CALL2 (I_SMP_CALL0 + 2)
+#define I_SMP_CALL3 (I_SMP_CALL0 + 3)
+#define I_SMP_CALL4 (I_SMP_CALL0 + 4)
+#define I_SMP_CALL_LAST I_SMP_CALL4
+#define I_TESTING 236 /* Testing IPI (used in testing.c) */
+#define I_POKE_GUEST 237
+#define I_POKE_CORE 238
+#define I_KERNEL_MSG 239
/* 240-255 are LAPIC vectors (0xf0-0xff), hightest priority class */
-#define IdtLAPIC 240
-#define IdtLAPIC_TIMER (IdtLAPIC + 0)
-#define IdtLAPIC_THERMAL (IdtLAPIC + 1)
-#define IdtLAPIC_PCINT (IdtLAPIC + 2)
-#define IdtLAPIC_LINT0 (IdtLAPIC + 3)
-#define IdtLAPIC_LINT1 (IdtLAPIC + 4)
-#define IdtLAPIC_ERROR (IdtLAPIC + 5)
+#define IdtLAPIC 240
+#define IdtLAPIC_TIMER (IdtLAPIC + 0)
+#define IdtLAPIC_THERMAL (IdtLAPIC + 1)
+#define IdtLAPIC_PCINT (IdtLAPIC + 2)
+#define IdtLAPIC_LINT0 (IdtLAPIC + 3)
+#define IdtLAPIC_LINT1 (IdtLAPIC + 4)
+#define IdtLAPIC_ERROR (IdtLAPIC + 5)
/* Plan 9 apic note: the spurious vector number must have bits 3-0 0x0f
* unless the Extended Spurious Vector Enable bit is set in the
* HyperTransport Transaction Control register. On some intel machines, those
* bits are hardwired to 1s (SDM 3-10.9). */
-#define IdtLAPIC_SPURIOUS (IdtLAPIC + 0xf) /* Aka 255, 0xff */
-#define MaxIdtLAPIC (IdtLAPIC + 0xf)
+#define IdtLAPIC_SPURIOUS (IdtLAPIC + 0xf) /* Aka 255, 0xff */
+#define MaxIdtLAPIC (IdtLAPIC + 0xf)
-#define IdtMAX 255
+#define IdtMAX 255
-#define T_DEFAULT 0x0000beef // catchall
+#define T_DEFAULT 0x0000beef // catchall
/* Floating point constants */
-#define FP_EXCP_IE (1 << 0) /* invalid op */
-#define FP_EXCP_DE (1 << 1) /* denormalized op */
-#define FP_EXCP_ZE (1 << 2) /* div by zero */
-#define FP_EXCP_OE (1 << 3) /* numeric overflow */
-#define FP_EXCP_UE (1 << 4) /* numeric underflow */
-#define FP_EXCP_PE (1 << 5) /* precision */
+#define FP_EXCP_IE (1 << 0) /* invalid op */
+#define FP_EXCP_DE (1 << 1) /* denormalized op */
+#define FP_EXCP_ZE (1 << 2) /* div by zero */
+#define FP_EXCP_OE (1 << 3) /* numeric overflow */
+#define FP_EXCP_UE (1 << 4) /* numeric underflow */
+#define FP_EXCP_PE (1 << 5) /* precision */
-#define FP_SW_SF (1 << 6) /* stack fault */
-#define FP_SW_ES (1 << 7) /* error summary status */
-#define FP_SW_C0 (1 << 8) /* condition codes */
-#define FP_SW_C1 (1 << 9)
-#define FP_SW_C2 (1 << 10)
-#define FP_SW_C3 (1 << 14)
-#define FP_CW_TOP_SHIFT (11)
-#define FP_CW_TOP_MASK (7 << FP_CW_TOP_SHIFT)
+#define FP_SW_SF (1 << 6) /* stack fault */
+#define FP_SW_ES (1 << 7) /* error summary status */
+#define FP_SW_C0 (1 << 8) /* condition codes */
+#define FP_SW_C1 (1 << 9)
+#define FP_SW_C2 (1 << 10)
+#define FP_SW_C3 (1 << 14)
+#define FP_CW_TOP_SHIFT (11)
+#define FP_CW_TOP_MASK (7 << FP_CW_TOP_SHIFT)
-#define FP_CW_PC_SHIFT (8)
-#define FP_CW_PC_MASK (3 << FP_CW_PC_SHIFT)
-#define FP_CW_RC_SHIFT (10)
-#define FP_CW_RC_MASK (3 << FP_CW_RC_SHIFT)
-#define FP_CW_IC (1 << 12)
+#define FP_CW_PC_SHIFT (8)
+#define FP_CW_PC_MASK (3 << FP_CW_PC_SHIFT)
+#define FP_CW_RC_SHIFT (10)
+#define FP_CW_RC_MASK (3 << FP_CW_RC_SHIFT)
+#define FP_CW_IC (1 << 12)
#ifndef __ASSEMBLER__
@@ -132,9 +132,9 @@
void *data;
int apic_vector;
- /* all handlers in the chain need to have the same func pointers. we only
- * really use the first one, and the latter are to catch bugs. also, we
- * won't be doing a lot of IRQ line sharing */
+ /* all handlers in the chain need to have the same func pointers. we
+ * only really use the first one, and the latter are to catch bugs.
+ * also, we won't be doing a lot of IRQ line sharing */
bool (*check_spurious)(int);
void (*eoi)(int);
void (*mask)(struct irq_handler *irq_h, int vec);
@@ -168,38 +168,42 @@
/* PLEASE NOTE:
* AMD CPUs ignore the FOP/FIP/FDP fields when there is
- * no pending exception. When you are on AMD, we zero these fields in the
- * ancillary_state argument before saving. This way, if you are on AMD and
- * re-using an ancillary_state memory region, an old save's information
- * won't leak into your new data. The side-effect of this is that you can't
- * trust these fields to report accurate information on AMD unless an
- * exception was pending. Granted, AMD says that only exception handlers
- * should care about FOP/FIP/FDP, so that's probably okay.
+ * no pending exception. When you are on AMD, we zero these fields in
+ * the ancillary_state argument before saving. This way, if you are on
+ * AMD and re-using an ancillary_state memory region, an old save's
+ * information won't leak into your new data. The side-effect of this is
+ * that you can't trust these fields to report accurate information on
+ * AMD unless an exception was pending. Granted, AMD says that only
+ * exception handlers should care about FOP/FIP/FDP, so that's probably
+ * okay.
*
- * You should also note that on newer Intel 64 processors, while the value
- * of the FOP is always saved and restored, it contains the opcode of the
- * most recent x87 FPU instruction that triggered an unmasked exception,
- * rather than simply the most recent opcode. Some older Xeons and P4s had
- * the fopcode compatibility mode feature, which you could use to make the
- * FOP update on every x87 non-control instruction, but that has been
- * eliminated in newer hardware.
+ * You should also note that on newer Intel 64 processors, while the
+ * value of the FOP is always saved and restored, it contains the opcode
+ * of the most recent x87 FPU instruction that triggered an unmasked
+ * exception, rather than simply the most recent opcode. Some older
+ * Xeons and P4s had the fopcode compatibility mode feature, which you
+ * could use to make the FOP update on every x87 non-control
+ * instruction, but that has been eliminated in newer hardware.
*
*/
if (cpu_has_feat(CPU_FEAT_X86_VENDOR_AMD)) {
silly->fp_head_64d.fop = 0x0;
silly->fp_head_64d.fpu_ip = 0x0;
silly->fp_head_64d.cs = 0x0;
- silly->fp_head_64d.padding1 = 0x0; // padding1 is FIP or rsvd, proc dep.
+ // padding1 is FIP or rsvd, proc dep.
+ silly->fp_head_64d.padding1 = 0x0;
silly->fp_head_64d.fpu_dp = 0x0;
silly->fp_head_64d.ds = 0x0;
- silly->fp_head_64d.padding2 = 0x0; // padding2 is FDP or rsvd, proc dep.
+ // padding2 is FDP or rsvd, proc dep.
+ silly->fp_head_64d.padding2 = 0x0;
}
if (cpu_has_feat(CPU_FEAT_X86_XSAVEOPT)) {
edx = x86_default_xcr0 >> 32;
eax = x86_default_xcr0;
- asm volatile("xsaveopt64 %0" : : "m"(*silly), "a"(eax), "d"(edx));
+ asm volatile("xsaveopt64 %0" : : "m"(*silly), "a"(eax),
+ "d"(edx));
} else if (cpu_has_feat(CPU_FEAT_X86_XSAVE)) {
edx = x86_default_xcr0 >> 32;
eax = x86_default_xcr0;
@@ -230,14 +234,15 @@
* We check for a pending exception by checking FSW.ES (bit 7)
*
* FNINIT clears FIP and FDP and, even though it is technically a
- * control instruction, it clears FOP because it is initializing the FPU.
+ * control instruction, it clears FOP because it is initializing the
+ * FPU.
*
* NOTE: This might not be the most efficient way to do things, and
* could be an optimization target for context switch performance
* on AMD processors in the future.
*/
if (!(silly->fp_head_64d.fsw & 0x80)
- && cpu_has_feat(CPU_FEAT_X86_VENDOR_AMD))
+ && cpu_has_feat(CPU_FEAT_X86_VENDOR_AMD))
asm volatile ("fninit;");
if (cpu_has_feat(CPU_FEAT_X86_XSAVE)) {
@@ -293,14 +298,16 @@
static inline void __attribute__((always_inline))
set_stack_pointer(uintptr_t sp)
{
- asm volatile("mov %0,%%"X86_REG_SP"" : : "r"(sp) : "memory", X86_REG_SP);
+ asm volatile("mov %0,%%"X86_REG_SP"" : : "r"(sp)
+ : "memory", X86_REG_SP);
}
static inline void __attribute__((always_inline))
set_frame_pointer(uintptr_t fp)
{
- /* note we can't list BP as a clobber - the compiler will flip out. makes
- * me wonder if clobbering SP above makes a difference (probably not) */
+ /* note we can't list BP as a clobber - the compiler will flip out.
+ * makes me wonder if clobbering SP above makes a difference (probably
+ * not) */
asm volatile("mov %0,%%"X86_REG_BP"" : : "r"(fp) : "memory");
}
diff --git a/kern/arch/x86/trap64.c b/kern/arch/x86/trap64.c
index 5370788..f1a2efb 100644
--- a/kern/arch/x86/trap64.c
+++ b/kern/arch/x86/trap64.c
@@ -28,9 +28,10 @@
void print_trapframe(struct hw_trapframe *hw_tf)
{
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
- /* This is only called in debug scenarios, and often when the kernel trapped
- * and needs to tell us about it. Disable the lock checker so it doesn't go
- * nuts when we print/panic */
+
+ /* This is only called in debug scenarios, and often when the kernel
+ * trapped and needs to tell us about it. Disable the lock checker so
+ * it doesn't go nuts when we print/panic */
pcpui->__lock_checking_enabled--;
spin_lock_irqsave(&ptf_lock);
printk("HW TRAP frame %sat %p on core %d\n",
diff --git a/kern/arch/x86/trap64.h b/kern/arch/x86/trap64.h
index 8e86c41..4055af7 100644
--- a/kern/arch/x86/trap64.h
+++ b/kern/arch/x86/trap64.h
@@ -43,15 +43,15 @@
}
#define AKAROS_MSR_STAR (((((uint64_t)GD_UD - 8) | 0x3) << 48) | \
- ((uint64_t)GD_KT << 32))
+ ((uint64_t)GD_KT << 32))
#define AKAROS_MSR_LSTAR ((uintptr_t)&sysenter_handler)
/* Masking all flags. when we syscall, we'll get rflags = 0 */
#define AKAROS_MSR_SFMASK (FL_AC | FL_NT | FL_IOPL_MASK | FL_DF | FL_IF | FL_TF)
static inline void x86_sysenter_init(void)
{
- /* check amd 2:6.1.1 for details. they have some expectations about the GDT
- * layout. */
+ /* check amd 2:6.1.1 for details. they have some expectations about the
+ * GDT layout. */
write_msr(MSR_STAR, AKAROS_MSR_STAR);
write_msr(MSR_LSTAR, AKAROS_MSR_LSTAR);
write_msr(MSR_SFMASK, AKAROS_MSR_SFMASK);
diff --git a/kern/arch/x86/uaccess.h b/kern/arch/x86/uaccess.h
index b3d6f27..4a1927d 100644
--- a/kern/arch/x86/uaccess.h
+++ b/kern/arch/x86/uaccess.h
@@ -25,71 +25,71 @@
uint64_t fixup;
};
-#define __read_msr_asm(eax, edx, addr, err, errret) \
- asm volatile(ASM_STAC "\n" \
- "1: rdmsr\n" \
- " mfence\n" \
- "2: " ASM_CLAC "\n" \
- ".section .fixup,\"ax\"\n" \
- "3: mov %4,%0\n" \
- " jmp 2b\n" \
- ".previous\n" \
- _ASM_EXTABLE(1b, 3b) \
- : "=r" (err), "=d" (edx), "=a" (eax) \
+#define __read_msr_asm(eax, edx, addr, err, errret) \
+ asm volatile(ASM_STAC "\n" \
+ "1:rdmsr\n" \
+ " mfence\n" \
+ "2: " ASM_CLAC "\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3:mov %4,%0\n" \
+ " jmp 2b\n" \
+ ".previous\n" \
+ _ASM_EXTABLE(1b, 3b) \
+ : "=r" (err), "=d" (edx), "=a" (eax) \
: "c" (addr), "i" (errret), "0" (err))
-#define __write_msr_asm(val, addr, err, errret) \
- asm volatile(ASM_STAC "\n" \
- "1: wrmsr\n" \
- "2: " ASM_CLAC "\n" \
- ".section .fixup,\"ax\"\n" \
- "3: mov %4,%0\n" \
- " jmp 2b\n" \
- ".previous\n" \
- _ASM_EXTABLE(1b, 3b) \
- : "=r" (err) \
- : "d" ((uint32_t) (val >> 32)), \
- "a" ((uint32_t) (val & 0xffffffff)), "c" (addr), \
- "i" (errret), "0" (err))
+#define __write_msr_asm(val, addr, err, errret) \
+ asm volatile(ASM_STAC "\n" \
+ "1:wrmsr\n" \
+ "2: " ASM_CLAC "\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3:mov %4,%0\n" \
+ " jmp 2b\n" \
+ ".previous\n" \
+ _ASM_EXTABLE(1b, 3b) \
+ : "=r" (err) \
+ : "d" ((uint32_t) (val >> 32)), \
+ "a" ((uint32_t) (val & 0xffffffff)), "c" (addr), \
+ "i" (errret), "0" (err))
-#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
- asm volatile(ASM_STAC "\n" \
- "1: mov"itype" %"rtype"1,%2\n" \
- "2: " ASM_CLAC "\n" \
- ".section .fixup,\"ax\"\n" \
- "3: mov %3,%0\n" \
- " jmp 2b\n" \
- ".previous\n" \
- _ASM_EXTABLE(1b, 3b) \
- : "=r"(err) \
- : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
+#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
+ asm volatile(ASM_STAC "\n" \
+ "1:mov"itype" %"rtype"1,%2\n" \
+ "2: " ASM_CLAC "\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3:mov %3,%0\n" \
+ " jmp 2b\n" \
+ ".previous\n" \
+ _ASM_EXTABLE(1b, 3b) \
+ : "=r"(err) \
+ : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
- asm volatile(ASM_STAC "\n" \
- "1: mov"itype" %2,%"rtype"1\n" \
- "2: " ASM_CLAC "\n" \
- ".section .fixup,\"ax\"\n" \
- "3: mov %3,%0\n" \
- " xor"itype" %"rtype"1,%"rtype"1\n" \
- " jmp 2b\n" \
- ".previous\n" \
- _ASM_EXTABLE(1b, 3b) \
- : "=r" (err), ltype(x) \
- : "m" (__m(addr)), "i" (errret), "0" (err))
+ asm volatile(ASM_STAC "\n" \
+ "1:mov"itype" %2,%"rtype"1\n" \
+ "2: " ASM_CLAC "\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3:mov %3,%0\n" \
+ " xor"itype" %"rtype"1,%"rtype"1\n" \
+ " jmp 2b\n" \
+ ".previous\n" \
+ _ASM_EXTABLE(1b, 3b) \
+ : "=r" (err), ltype(x) \
+ : "m" (__m(addr)), "i" (errret), "0" (err))
-#define __user_memcpy(dst, src, count, err, errret) \
- asm volatile(ASM_STAC "\n" \
- " cld\n" \
- "1: rep movsb\n" \
- "2: " ASM_CLAC "\n" \
- ".section .fixup,\"ax\"\n" \
- "3: mov %4,%0\n" \
- " jmp 2b\n" \
- ".previous\n" \
- _ASM_EXTABLE(1b, 3b) \
- : "=r"(err), "+D" (dst), "+S" (src), "+c" (count) \
- : "i" (errret), "0" (err) \
- : "memory")
+#define __user_memcpy(dst, src, count, err, errret) \
+ asm volatile(ASM_STAC "\n" \
+ " cld\n" \
+ "1:rep movsb\n" \
+ "2: " ASM_CLAC "\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3:mov %4,%0\n" \
+ " jmp 2b\n" \
+ ".previous\n" \
+ _ASM_EXTABLE(1b, 3b) \
+ : "=r"(err), "+D" (dst), "+S" (src), "+c" (count) \
+ : "i" (errret), "0" (err) \
+ : "memory")
static inline int __put_user(void *dst, const void *src, unsigned int count)
{
@@ -97,20 +97,20 @@
switch (count) {
case 1:
- __put_user_asm(*(const uint8_t *) src, (uint8_t *) dst, err, "b",
- "b", "iq", -EFAULT);
+ __put_user_asm(*(const uint8_t *) src, (uint8_t *) dst, err,
+ "b", "b", "iq", -EFAULT);
break;
case 2:
- __put_user_asm(*(const uint16_t *) src, (uint16_t *) dst, err, "w",
- "w", "ir", -EFAULT);
+ __put_user_asm(*(const uint16_t *) src, (uint16_t *) dst, err,
+ "w", "w", "ir", -EFAULT);
break;
case 4:
- __put_user_asm(*(const uint32_t *) src, (uint32_t *) dst, err, "l",
- "k", "ir", -EFAULT);
+ __put_user_asm(*(const uint32_t *) src, (uint32_t *) dst, err,
+ "l", "k", "ir", -EFAULT);
break;
case 8:
- __put_user_asm(*(const uint64_t *) src, (uint64_t *) dst, err, "q",
- "", "er", -EFAULT);
+ __put_user_asm(*(const uint64_t *) src, (uint64_t *) dst, err,
+ "q", "", "er", -EFAULT);
break;
default:
__user_memcpy(dst, src, count, err, -EFAULT);
@@ -140,20 +140,20 @@
switch (count) {
case 1:
- __get_user_asm(*(uint8_t *) dst, (const uint8_t *) src, err, "b",
- "b", "=q", -EFAULT);
+ __get_user_asm(*(uint8_t *) dst, (const uint8_t *) src, err,
+ "b", "b", "=q", -EFAULT);
break;
case 2:
- __get_user_asm(*(uint16_t *) dst, (const uint16_t *) src, err, "w",
- "w", "=r", -EFAULT);
+ __get_user_asm(*(uint16_t *) dst, (const uint16_t *) src, err,
+ "w", "w", "=r", -EFAULT);
break;
case 4:
- __get_user_asm(*(uint32_t *) dst, (const uint32_t *) src, err, "l",
- "k", "=r", -EFAULT);
+ __get_user_asm(*(uint32_t *) dst, (const uint32_t *) src, err,
+ "l", "k", "=r", -EFAULT);
break;
case 8:
- __get_user_asm(*(uint64_t *) dst, (const uint64_t *) src, err, "q",
- "", "=r", -EFAULT);
+ __get_user_asm(*(uint64_t *) dst, (const uint64_t *) src, err,
+ "q", "", "=r", -EFAULT);
break;
default:
__user_memcpy(dst, src, count, err, -EFAULT);
diff --git a/kern/arch/x86/usb.c b/kern/arch/x86/usb.c
index 1541a5e..7f8e7f0 100644
--- a/kern/arch/x86/usb.c
+++ b/kern/arch/x86/usb.c
@@ -31,11 +31,13 @@
//ptr = (ctlr->capio->capparms >> Ceecpshift) & Ceecpmask;
uintptr_t bar0 = pci_get_membar(pcidev, 0);
assert(bar0);
- uintptr_t ehci_hcc_regs = vmap_pmem_nocache(bar0, pcidev->bar[0].mmio_sz);
+ uintptr_t ehci_hcc_regs = vmap_pmem_nocache(bar0,
+ pcidev->bar[0].mmio_sz);
uint32_t hccparams = read_mmreg32(ehci_hcc_regs + 0x08);
+
ptr = (hccparams >> 8) & ((1 << 8) - 1);
- for(; ptr != 0; ptr = pcidev_read8(pcidev, ptr + 1)) {
+ for (; ptr != 0; ptr = pcidev_read8(pcidev, ptr + 1)) {
if (ptr < 0x40 || (ptr & ~0xFC))
break;
cap = pcidev_read8(pcidev, ptr);
@@ -79,8 +81,8 @@
hccparams = read_mmreg32(xhci_hcc_regs + 0x10);
xecp = (hccparams >> 16) & 0xffff;
- /* xecp is the rel offset, in 32 bit words, from the base to the extended
- * capabilities pointer. */
+ /* xecp is the rel offset, in 32 bit words, from the base to the
+ * extended capabilities pointer. */
for (/* xecp set */; xecp; xecp = (read_mmreg32(xecp) >> 8) & 0xff) {
xecp = xhci_hcc_regs + (xecp << 2);
val = read_mmreg32(xecp);
@@ -90,10 +92,11 @@
/* bios already does not own it */
if (!(val & (1 << 16)))
return;
- /* take ownership. Note we're allowed to do byte-width writes here. */
+ /* take ownership. Note we're allowed to do byte-width writes
+ * here. */
write_mmreg8(xecp + 3, 1);
- /* book says to wait up to a second, though i regularly see it time out
- * on my machines. */
+ /* book says to wait up to a second, though i regularly see it
+ * time out on my machines. */
for (i = 0; i < 100000; i++) {
if (!(read_mmreg32(xecp) & (1 << 16)))
break;
@@ -105,8 +108,8 @@
/* Force the bios's byte clear */
write_mmreg8(xecp + 2, 0);
}
- /* Turn off settings in USBLEGCTLSTS. Not sure if any of this is
- * necessary. */
+ /* Turn off settings in USBLEGCTLSTS. Not sure if any of this
+ * is necessary. */
val = read_mmreg32(xecp + 4);
val &= ~((1 << 0) | (1 << 4) | (0x7 << 13));
/* These are write-to-clear. */
@@ -127,26 +130,26 @@
pcidev->bus, pcidev->dev, pcidev->func);
}
-void usb_disable_legacy()
+void usb_disable_legacy(void)
{
struct pci_device *i;
STAILQ_FOREACH(i, &pci_devices, all_dev) {
if ((i->class == 0x0c) && (i->subclass == 0x03)) {
switch (i->progif) {
- case 0x00:
- uhci_disable_leg(i);
- break;
- case 0x20:
- ehci_disable_leg(i);
- break;
- case 0x30:
- xhci_disable_leg(i);
- break;
- default:
- /* TODO: ohci */
- printk("PCI USB %x:%x:%x, unknown progif 0x%x\n",
- i->bus, i->dev, i->func, i->progif);
+ case 0x00:
+ uhci_disable_leg(i);
+ break;
+ case 0x20:
+ ehci_disable_leg(i);
+ break;
+ case 0x30:
+ xhci_disable_leg(i);
+ break;
+ default:
+ /* TODO: ohci */
+ printk("PCI USB %x:%x:%x unknown progif 0x%x\n",
+ i->bus, i->dev, i->func, i->progif);
}
}
}
diff --git a/kern/arch/x86/vmm/ept.h b/kern/arch/x86/vmm/ept.h
index 9bc5706..5d03de3 100644
--- a/kern/arch/x86/vmm/ept.h
+++ b/kern/arch/x86/vmm/ept.h
@@ -10,23 +10,23 @@
#include <smp.h> /* for current */
/* Some EPTE PTE flags are only valid for the last PTEs in a walk */
-#define EPTE_R (1ULL << 0) /* Readable */
-#define EPTE_W (1ULL << 1) /* Writeable */
-#define EPTE_X (1ULL << 2) /* Executable */
-#define EPTE_MEM_BITS (7ULL << 3) /* Memory type specifier */
-#define EPTE_IGN_PAT (1ULL << 6) /* Ignore PAT */
-#define EPTE_PS (1ULL << 7) /* Jumbo Page Size */
-#define EPTE_A (1ULL << 8) /* Accessed */
-#define EPTE_D (1ULL << 9) /* Dirty */
-#define EPTE_SUP_VE (1ULL << 63) /* Suppress virt exceptions */
+#define EPTE_R (1ULL << 0) /* Readable */
+#define EPTE_W (1ULL << 1) /* Writeable */
+#define EPTE_X (1ULL << 2) /* Executable */
+#define EPTE_MEM_BITS (7ULL << 3) /* Memory type specifier */
+#define EPTE_IGN_PAT (1ULL << 6) /* Ignore PAT */
+#define EPTE_PS (1ULL << 7) /* Jumbo Page Size */
+#define EPTE_A (1ULL << 8) /* Accessed */
+#define EPTE_D (1ULL << 9) /* Dirty */
+#define EPTE_SUP_VE (1ULL << 63) /* Suppress virt exceptions */
#define EPTE_P (EPTE_R | EPTE_W | EPTE_X)
/* Types available for the EPTE_MEM_TYPE */
-#define EPT_MEM_TYPE_UC 0
-#define EPT_MEM_TYPE_WC 1
-#define EPT_MEM_TYPE_WT 4
-#define EPT_MEM_TYPE_WP 5
-#define EPT_MEM_TYPE_WB 6
+#define EPT_MEM_TYPE_UC 0
+#define EPT_MEM_TYPE_WC 1
+#define EPT_MEM_TYPE_WT 4
+#define EPT_MEM_TYPE_WP 5
+#define EPT_MEM_TYPE_WB 6
/* Helper to align the type to its location in the PTE */
#define EPT_MEM_TYPE(type) ((type) << 3)
@@ -40,7 +40,8 @@
static inline bool epte_is_present(epte_t *epte)
{
- /* Actually, certain combos, like W but not R could be misconfigurations */
+ /* Actually, certain combos, like W but not R could be
+ * misconfigurations. */
return *epte & EPTE_P ? TRUE : FALSE;
}
@@ -78,26 +79,26 @@
static inline physaddr_t epte_get_paddr(epte_t *epte)
{
- /* 63:52 are ignored/flags. 51:12 are the addr. Technically 51:N must be
- * 0, where N is the physical addr width */
+ /* 63:52 are ignored/flags. 51:12 are the addr. Technically 51:N must
+ * be 0, where N is the physical addr width */
return *epte & 0x000ffffffffff000;
}
static inline int __pte_to_epte_perm(int perm)
{
switch (perm) {
- /* Since we keep the EPT in lockstep with the KPT, we might get some
- * mapping requests for the kernel (e.g. vmap_pmem). */
- case PTE_KERN_RW:
- case PTE_KERN_RO:
- case PTE_NONE:
- return 0;
- case PTE_USER_RW:
- return EPTE_W | EPTE_R | EPTE_X;
- case PTE_USER_RO:
- return EPTE_R | EPTE_X;
- default:
- panic("Bad PTE type 0x%x\n", perm);
+ /* Since we keep the EPT in lockstep with the KPT, we might get
+ * some mapping requests for the kernel (e.g. vmap_pmem). */
+ case PTE_KERN_RW:
+ case PTE_KERN_RO:
+ case PTE_NONE:
+ return 0;
+ case PTE_USER_RW:
+ return EPTE_W | EPTE_R | EPTE_X;
+ case PTE_USER_RO:
+ return EPTE_R | EPTE_X;
+ default:
+ panic("Bad PTE type 0x%x\n", perm);
}
}
@@ -107,8 +108,8 @@
epte_t temp = pa;
temp |= __pte_to_epte_perm(settings & PTE_PERM);
temp |= settings & PTE_PS ? EPTE_PS : 0;
- /* All memory is WB by default, but the guest can override that with their
- * PAT on the first page walk (guest KPT/cr3) */
+ /* All memory is WB by default, but the guest can override that with
+ * their PAT on the first page walk (guest KPT/cr3) */
temp |= EPT_MEM_TYPE(EPT_MEM_TYPE_WB);
*epte = temp;
}
@@ -142,8 +143,8 @@
{
int settings = 0;
if (*epte & EPTE_P) {
- /* We want to know User and Writable, in the 'PTE' sense. All present
- * epte entries are User PTEs. */
+ /* We want to know User and Writable, in the 'PTE' sense. All
+ * present epte entries are User PTEs. */
settings |= PTE_P | PTE_U;
settings |= *epte & EPTE_W ? PTE_W : 0;
}
diff --git a/kern/arch/x86/vmm/intel/vmx.c b/kern/arch/x86/vmm/intel/vmx.c
index abe3b2f..28a827c 100644
--- a/kern/arch/x86/vmm/intel/vmx.c
+++ b/kern/arch/x86/vmm/intel/vmx.c
@@ -43,7 +43,8 @@
* Yep, it's confusing. This is in part because the vmcs is used twice, for two different things.
* You're left with the feeling that they got part way through and realized they had to have one for
*
- * 1) your CPU is going to be capable of running VMs, and you need state for that.
+ * 1) your CPU is going to be capable of running VMs, and you need state for
+ * that.
*
* 2) you're about to start a guest, and you need state for that.
*
@@ -67,9 +68,12 @@
* anyway.
*
* Next, call setup_vmcs_config to configure the GLOBAL vmcs_config struct,
- * which contains all the naughty bits settings for all the cpus that can run a VM.
- * Realistically, all VMX-capable cpus in a system will have identical configurations.
- * So: 0 or more cpus can run VMX; all cpus which can run VMX will have the same configuration.
+ * which contains all the naughty bits settings for all the cpus that can run a
+ * VM.
+ * Realistically, all VMX-capable cpus in a system will have identical
+ * configurations.
+ * So: 0 or more cpus can run VMX; all cpus which can run VMX will have the same
+ * configuration.
*
* configure the msr_bitmap. This is the bitmap of MSRs which the
* guest can manipulate. Currently, we only allow GS and FS base.
@@ -110,13 +114,14 @@
* }
*
* get a vcpu
- * See if the current cpu has a vcpu. If so, and is the same as the vcpu we want,
- * vmcs_load(vcpu->vmcs) -- i.e. issue a VMPTRLD.
+ * See if the current cpu has a vcpu. If so, and is the same as the vcpu we
+ * want, vmcs_load(vcpu->vmcs) -- i.e. issue a VMPTRLD.
*
- * If it's not the same, see if the vcpu thinks it is on the core. If it is not, call
- * __vmx_get_cpu_helper on the other cpu, to free it up. Else vmcs_clear the one
- * attached to this cpu. Then vmcs_load the vmcs for vcpu on this this cpu,
- * call __vmx_setup_cpu, mark this vcpu as being attached to this cpu, done.
+ * If it's not the same, see if the vcpu thinks it is on the core. If it is not,
+ * call __vmx_get_cpu_helper on the other cpu, to free it up. Else vmcs_clear
+ * the one attached to this cpu. Then vmcs_load the vmcs for vcpu on this this
+ * cpu, call __vmx_setup_cpu, mark this vcpu as being attached to this cpu,
+ * done.
*
* vmx_run_vcpu this one gets messy, mainly because it's a giant wad
* of inline assembly with embedded CPP crap. I suspect we'll want to
@@ -204,10 +209,10 @@
-1, -1, -1, -1, -1, -1, -1
};
-__always_inline unsigned long vmcs_readl(unsigned long field);
+static __always_inline unsigned long vmcs_readl(unsigned long field);
+
/* See section 24-3 of The Good Book */
-void
-show_cr_access(uint64_t val)
+void show_cr_access(uint64_t val)
{
int crnr = val & 0xf;
int type = (val >> 4) & 3;
@@ -225,101 +230,92 @@
print_unlock();
}
-void
-ept_flush(uint64_t eptp)
+void ept_flush(uint64_t eptp)
{
ept_sync_context(eptp);
}
-static void
-vmcs_clear(struct vmcs *vmcs)
+static void vmcs_clear(struct vmcs *vmcs)
{
uint64_t phys_addr = PADDR(vmcs);
uint8_t error;
- asm volatile (ASM_VMX_VMCLEAR_RAX "; setna %0":"=qm"(error):"a"(&phys_addr),
- "m"(phys_addr)
- :"cc", "memory");
+ asm volatile (ASM_VMX_VMCLEAR_RAX "; setna %0"
+ : "=qm"(error)
+ : "a"(&phys_addr), "m"(phys_addr)
+ :"cc", "memory");
if (error)
printk("vmclear fail: %p/%llx\n", vmcs, phys_addr);
}
-static void
-vmcs_load(struct vmcs *vmcs)
+static void vmcs_load(struct vmcs *vmcs)
{
uint64_t phys_addr = PADDR(vmcs);
uint8_t error;
- asm volatile (ASM_VMX_VMPTRLD_RAX "; setna %0":"=qm"(error):"a"(&phys_addr),
- "m"(phys_addr)
- :"cc", "memory");
+ asm volatile (ASM_VMX_VMPTRLD_RAX "; setna %0"
+ : "=qm"(error)
+ : "a"(&phys_addr), "m"(phys_addr)
+ : "cc", "memory");
if (error)
printk("vmptrld %p/%llx failed\n", vmcs, phys_addr);
}
/* Returns the paddr pointer of the current CPU's VMCS region, or -1 if none. */
-static physaddr_t
-vmcs_get_current(void)
+static physaddr_t vmcs_get_current(void)
{
physaddr_t vmcs_paddr;
+
/* RAX contains the addr of the location to store the VMCS pointer. The
- * compiler doesn't know the ASM will deref that pointer, hence the =m */
+ * compiler doesn't know the ASM will deref that pointer, hence the =m
+ */
asm volatile (ASM_VMX_VMPTRST_RAX:"=m"(vmcs_paddr):"a"(&vmcs_paddr));
return vmcs_paddr;
}
-__always_inline unsigned long
-vmcs_readl(unsigned long field)
+static __always_inline unsigned long vmcs_readl(unsigned long field)
{
return vmcs_read(field);
}
-__always_inline uint16_t
-vmcs_read16(unsigned long field)
+static __always_inline uint16_t vmcs_read16(unsigned long field)
{
return vmcs_readl(field);
}
-static __always_inline uint32_t
-vmcs_read32(unsigned long field)
+static __always_inline uint32_t vmcs_read32(unsigned long field)
{
return vmcs_readl(field);
}
-static __always_inline uint64_t
-vmcs_read64(unsigned long field)
+static __always_inline uint64_t vmcs_read64(unsigned long field)
{
return vmcs_readl(field);
}
-void
-vmwrite_error(unsigned long field, unsigned long value)
+void vmwrite_error(unsigned long field, unsigned long value)
{
printk("vmwrite error: reg %lx value %lx (err %d)\n",
- field, value, vmcs_read32(VM_INSTRUCTION_ERROR));
+ field, value, vmcs_read32(VM_INSTRUCTION_ERROR));
}
-void
-vmcs_writel(unsigned long field, unsigned long value)
+void vmcs_writel(unsigned long field, unsigned long value)
{
if (!vmcs_write(field, value))
vmwrite_error(field, value);
}
-static void
-vmcs_write16(unsigned long field, uint16_t value)
+static void vmcs_write16(unsigned long field, uint16_t value)
{
vmcs_writel(field, value);
}
-static void
-vmcs_write32(unsigned long field, uint32_t value)
+static void vmcs_write32(unsigned long field, uint32_t value)
{
vmcs_writel(field, value);
}
-static void
-vmcs_write64(unsigned long field, uint64_t value)
+static void vmcs_write64(unsigned long field, uint64_t value)
{
vmcs_writel(field, value);
}
@@ -424,7 +420,7 @@
if (vmx_msr_low & ~vmx_msr_high)
warn("JACKPOT: Conflicting VMX ec ctls for %s, high 0x%08x low 0x%08x",
- v->name, vmx_msr_high, vmx_msr_low);
+ v->name, vmx_msr_high, vmx_msr_low);
reserved_0 = (~vmx_msr_low) & (~vmx_msr_high);
reserved_1 = vmx_msr_low & vmx_msr_high;
@@ -443,35 +439,42 @@
(v->must_be_0 & (v->try_set_1 | v->try_set_0)) ||
(v->try_set_1 & v->try_set_0)) {
printk("%s: must 0 (0x%x) and must be 1 (0x%x) and try_set_0 (0x%x) and try_set_1 (0x%x) overlap\n",
- v->name, v->must_be_0, v->must_be_1, v->try_set_0, v->try_set_1);
+ v->name, v->must_be_0, v->must_be_1, v->try_set_0,
+ v->try_set_1);
err = true;
}
/* coverage */
- if (((v->must_be_0 | v->must_be_1 | v->try_set_0 | v->try_set_1) & changeable_bits) != changeable_bits) {
+ if (((v->must_be_0 | v->must_be_1 | v->try_set_0 | v->try_set_1)
+ & changeable_bits) != changeable_bits) {
printk("%s: Need to cover 0x%x and have 0x%x,0x%x\n",
- v->name, changeable_bits, v->must_be_0, v->must_be_1, v->try_set_0, v->try_set_1);
+ v->name, changeable_bits, v->must_be_0, v->must_be_1,
+ v->try_set_0, v->try_set_1);
err = true;
}
- if ((v->must_be_0 | v->must_be_1 | v->try_set_0 | v->try_set_1 | reserved_0 | reserved_1) != 0xffffffff) {
+ if ((v->must_be_0 | v->must_be_1 | v->try_set_0 | v->try_set_1
+ | reserved_0 | reserved_1) != 0xffffffff) {
printk("%s: incomplete coverage: have 0x%x, want 0x%x\n",
- v->name, v->must_be_0 | v->must_be_1 | v->try_set_0 | v->try_set_1 |
- reserved_0 | reserved_1, 0xffffffff);
+ v->name, v->must_be_0 | v->must_be_1 | v->try_set_0 |
+ v->try_set_1 | reserved_0 | reserved_1, 0xffffffff);
err = true;
}
/* Don't try to change bits that can't be changed. */
if ((v->must_be_0 & (reserved_0 | changeable_bits)) != v->must_be_0) {
- printk("%s: set to 0 (0x%x) can't be done\n", v->name, v->must_be_0);
+ printk("%s: set to 0 (0x%x) can't be done\n", v->name,
+ v->must_be_0);
err = true;
}
if ((v->must_be_1 & (reserved_1 | changeable_bits)) != v->must_be_1) {
- printk("%s: set to 1 (0x%x) can't be done\n", v->name, v->must_be_1);
+ printk("%s: set to 1 (0x%x) can't be done\n", v->name,
+ v->must_be_1);
err = true;
}
- // Note we don't REQUIRE that try_set_0 or try_set_0 be possible. We just want to try it.
+ // Note we don't REQUIRE that try_set_0 or try_set_0 be possible. We
+ // just want to try it.
// Clear bits in try_set that can't be set.
try1 = v->try_set_1 & (reserved_1 | changeable_bits);
@@ -506,9 +509,9 @@
.truemsr = MSR_IA32_VMX_TRUE_PINBASED_CTLS,
.must_be_1 = (PIN_BASED_EXT_INTR_MASK |
- PIN_BASED_NMI_EXITING |
- PIN_BASED_VIRTUAL_NMIS |
- PIN_BASED_POSTED_INTR),
+ PIN_BASED_NMI_EXITING |
+ PIN_BASED_VIRTUAL_NMIS |
+ PIN_BASED_POSTED_INTR),
.must_be_0 = (PIN_BASED_VMX_PREEMPTION_TIMER),
};
@@ -519,35 +522,35 @@
.truemsr = MSR_IA32_VMX_TRUE_PROCBASED_CTLS,
.must_be_1 = (
- CPU_BASED_MWAIT_EXITING |
- CPU_BASED_HLT_EXITING |
- CPU_BASED_TPR_SHADOW |
- CPU_BASED_RDPMC_EXITING |
- CPU_BASED_CR8_LOAD_EXITING |
- CPU_BASED_CR8_STORE_EXITING |
- CPU_BASED_USE_MSR_BITMAPS |
- CPU_BASED_USE_IO_BITMAPS |
- CPU_BASED_ACTIVATE_SECONDARY_CONTROLS),
+ CPU_BASED_MWAIT_EXITING |
+ CPU_BASED_HLT_EXITING |
+ CPU_BASED_TPR_SHADOW |
+ CPU_BASED_RDPMC_EXITING |
+ CPU_BASED_CR8_LOAD_EXITING |
+ CPU_BASED_CR8_STORE_EXITING |
+ CPU_BASED_USE_MSR_BITMAPS |
+ CPU_BASED_USE_IO_BITMAPS |
+ CPU_BASED_ACTIVATE_SECONDARY_CONTROLS),
.must_be_0 = (
- CPU_BASED_VIRTUAL_INTR_PENDING |
- CPU_BASED_INVLPG_EXITING |
- CPU_BASED_USE_TSC_OFFSETING |
- CPU_BASED_RDTSC_EXITING |
- CPU_BASED_CR3_LOAD_EXITING |
- CPU_BASED_CR3_STORE_EXITING |
- CPU_BASED_MOV_DR_EXITING |
- CPU_BASED_VIRTUAL_NMI_PENDING |
- CPU_BASED_MONITOR_TRAP |
- CPU_BASED_PAUSE_EXITING |
- CPU_BASED_UNCOND_IO_EXITING),
+ CPU_BASED_VIRTUAL_INTR_PENDING |
+ CPU_BASED_INVLPG_EXITING |
+ CPU_BASED_USE_TSC_OFFSETING |
+ CPU_BASED_RDTSC_EXITING |
+ CPU_BASED_CR3_LOAD_EXITING |
+ CPU_BASED_CR3_STORE_EXITING |
+ CPU_BASED_MOV_DR_EXITING |
+ CPU_BASED_VIRTUAL_NMI_PENDING |
+ CPU_BASED_MONITOR_TRAP |
+ CPU_BASED_PAUSE_EXITING |
+ CPU_BASED_UNCOND_IO_EXITING),
.try_set_0 = (CPU_BASED_MONITOR_EXITING),
.policy_changeable = (
- CPU_BASED_HLT_EXITING |
- CPU_BASED_PAUSE_EXITING |
- CPU_BASED_MWAIT_EXITING |
- 0),
+ CPU_BASED_HLT_EXITING |
+ CPU_BASED_PAUSE_EXITING |
+ CPU_BASED_MWAIT_EXITING |
+ 0),
};
static struct vmxec cb2ec = {
@@ -556,24 +559,24 @@
.truemsr = MSR_IA32_VMX_PROCBASED_CTLS2,
.must_be_1 = (SECONDARY_EXEC_ENABLE_EPT |
- SECONDARY_EXEC_APIC_REGISTER_VIRT |
- SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
- SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
- SECONDARY_EXEC_ENABLE_INVPCID |
- SECONDARY_EXEC_WBINVD_EXITING),
+ SECONDARY_EXEC_APIC_REGISTER_VIRT |
+ SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
+ SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
+ SECONDARY_EXEC_ENABLE_INVPCID |
+ SECONDARY_EXEC_WBINVD_EXITING),
.must_be_0 = (
- SECONDARY_EXEC_DESCRIPTOR_EXITING |
- SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
- SECONDARY_EXEC_ENABLE_VPID |
- SECONDARY_EXEC_UNRESTRICTED_GUEST |
- SECONDARY_EXEC_PAUSE_LOOP_EXITING |
- SECONDARY_EXEC_RDRAND_EXITING |
- SECONDARY_EXEC_ENABLE_VMFUNC |
- SECONDARY_EXEC_SHADOW_VMCS |
- SECONDARY_EXEC_RDSEED_EXITING |
- SECONDARY_EPT_VE |
- SECONDARY_ENABLE_XSAV_RESTORE),
+ SECONDARY_EXEC_DESCRIPTOR_EXITING |
+ SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
+ SECONDARY_EXEC_ENABLE_VPID |
+ SECONDARY_EXEC_UNRESTRICTED_GUEST |
+ SECONDARY_EXEC_PAUSE_LOOP_EXITING |
+ SECONDARY_EXEC_RDRAND_EXITING |
+ SECONDARY_EXEC_ENABLE_VMFUNC |
+ SECONDARY_EXEC_SHADOW_VMCS |
+ SECONDARY_EXEC_RDSEED_EXITING |
+ SECONDARY_EPT_VE |
+ SECONDARY_ENABLE_XSAV_RESTORE),
.try_set_1 = SECONDARY_EXEC_RDTSCP,
@@ -588,13 +591,13 @@
/* exact order from vmx.h; only the first two are enabled. */
.must_be_1 = (VM_ENTRY_LOAD_DEBUG_CONTROLS | /* can't set to 0 */
- VM_ENTRY_LOAD_IA32_EFER |
- VM_ENTRY_IA32E_MODE),
+ VM_ENTRY_LOAD_IA32_EFER |
+ VM_ENTRY_IA32E_MODE),
.must_be_0 = (VM_ENTRY_SMM |
- VM_ENTRY_DEACT_DUAL_MONITOR |
- VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL |
- VM_ENTRY_LOAD_IA32_PAT),
+ VM_ENTRY_DEACT_DUAL_MONITOR |
+ VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL |
+ VM_ENTRY_LOAD_IA32_PAT),
};
static struct vmxec vmexit = {
@@ -603,19 +606,18 @@
.truemsr = MSR_IA32_VMX_TRUE_EXIT_CTLS,
.must_be_1 = (VM_EXIT_SAVE_DEBUG_CONTROLS | /* can't set to 0 */
- VM_EXIT_ACK_INTR_ON_EXIT |
- VM_EXIT_SAVE_IA32_EFER |
- VM_EXIT_LOAD_IA32_EFER |
- VM_EXIT_HOST_ADDR_SPACE_SIZE), /* 64 bit */
+ VM_EXIT_ACK_INTR_ON_EXIT |
+ VM_EXIT_SAVE_IA32_EFER |
+ VM_EXIT_LOAD_IA32_EFER |
+ VM_EXIT_HOST_ADDR_SPACE_SIZE), /* 64 bit */
.must_be_0 = (VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
- VM_EXIT_SAVE_IA32_PAT |
- VM_EXIT_LOAD_IA32_PAT |
- VM_EXIT_SAVE_VMX_PREEMPTION_TIMER),
+ VM_EXIT_SAVE_IA32_PAT |
+ VM_EXIT_LOAD_IA32_PAT |
+ VM_EXIT_SAVE_VMX_PREEMPTION_TIMER),
};
-static void
-setup_vmcs_config(void *p)
+static void setup_vmcs_config(void *p)
{
int *ret = p;
struct vmcs_config *vmcs_conf = &vmcs_config;
@@ -644,8 +646,8 @@
* Don't worry that one or more of these might fail and leave
* the VMCS in some kind of incomplete state. If one of these
* fails, the caller is going to discard the VMCS.
- * It is written this way to ensure we get results of all tests and avoid
- * BMAFR behavior.
+ * It is written this way to ensure we get results of all tests and
+ * avoid BMAFR behavior.
*/
ok = check_vmxec_controls(&pbec, have_true_msrs,
&vmcs_conf->pin_based_exec_ctrl);
@@ -658,7 +660,7 @@
&vmcs_conf->vmentry_ctrl) && ok;
ok = check_vmxec_controls(&vmexit, have_true_msrs,
&vmcs_conf->vmexit_ctrl) && ok;
- if (! ok) {
+ if (!ok) {
printk("vmxexec controls is no good.\n");
return;
}
@@ -716,8 +718,7 @@
*
* Returns a valid VMCS region.
*/
-static struct vmcs *
-vmx_alloc_vmcs(void)
+static struct vmcs *vmx_alloc_vmcs(void)
{
return __vmx_alloc_vmcs(numa_id());
}
@@ -725,8 +726,7 @@
/**
* vmx_free_vmcs - frees a VMCS region
*/
-static void
-vmx_free_vmcs(struct vmcs *vmcs)
+static void vmx_free_vmcs(struct vmcs *vmcs)
{
kpages_free(vmcs, vmcs_config.size);
}
@@ -783,19 +783,20 @@
/* TODO: we might need to also set HOST_IA32_PERF_GLOBAL_CTRL. Need to
* think about how perf will work with VMs */
/* Userspace can request changes to the ctls. They take effect when we
- * reload the GPC, which occurs after a transition from userspace to VM. */
+ * reload the GPC, which occurs after a transition from userspace to VM.
+ */
vmcs_write(PIN_BASED_VM_EXEC_CONTROL, vmx->pin_exec_ctls);
vmcs_write(CPU_BASED_VM_EXEC_CONTROL, vmx->cpu_exec_ctls);
vmcs_write(SECONDARY_VM_EXEC_CONTROL, vmx->cpu2_exec_ctls);
}
-uint64_t
-construct_eptp(physaddr_t root_hpa)
+uint64_t construct_eptp(physaddr_t root_hpa)
{
uint64_t eptp;
/* set WB memory and 4 levels of walk. we checked these in ept_init */
- eptp = VMX_EPT_MEM_TYPE_WB | (VMX_EPT_GAW_4_LVL << VMX_EPT_GAW_EPTP_SHIFT);
+ eptp = VMX_EPT_MEM_TYPE_WB | (VMX_EPT_GAW_4_LVL <<
+ VMX_EPT_GAW_EPTP_SHIFT);
if (cpu_has_vmx_ept_ad_bits())
eptp |= VMX_EPT_AD_ENABLE_BIT;
eptp |= (root_hpa & PAGE_MASK);
@@ -815,7 +816,8 @@
/* Enforce page alignment */
kva = uva2kva(p, ROUNDDOWN(u_addr, PGSIZE), PGSIZE, PROT_WRITE);
if (!kva)
- error(EINVAL, "Unmapped pgaddr %p for VMCS page %s", u_addr, what);
+ 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
@@ -826,8 +828,8 @@
* 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. */
+ /* 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);
}
@@ -953,8 +955,10 @@
}
static void __vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,
- uint32_t msr) {
+ uint32_t msr)
+{
int f = sizeof(unsigned long);
+
/*
* See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). Early manuals
* have the write-low and read-high bitmap offsets the wrong way round.
@@ -972,11 +976,13 @@
/* note the io_bitmap is big enough for the 64K port space. */
static void __vmx_disable_intercept_for_io(unsigned long *io_bitmap,
- uint16_t port) {
+ uint16_t port)
+{
__clear_bit(port, io_bitmap);
}
-static void dumpmsrs(void) {
+static void dumpmsrs(void)
+{
int i;
int set[] = {
MSR_LSTAR,
@@ -986,6 +992,7 @@
MSR_SFMASK,
MSR_IA32_PEBS_ENABLE
};
+
for (i = 0; i < ARRAY_SIZE(set); i++) {
printk("%p: %p\n", set[i], read_msr(set[i]));
}
@@ -1005,8 +1012,8 @@
* only work on certain architectures. */
static void setup_msr(struct guest_pcore *gpc)
{
- /* Since PADDR(msr_bitmap) is non-zero, and the bitmap is all 0xff, we now
- * intercept all MSRs */
+ /* Since PADDR(msr_bitmap) is non-zero, and the bitmap is all 0xff, we
+ * now intercept all MSRs */
vmcs_write64(MSR_BITMAP, PADDR(msr_bitmap));
vmcs_write64(IO_BITMAP_A, PADDR(io_bitmap));
@@ -1124,7 +1131,8 @@
kfree(gpc);
}
-static void vmx_step_instruction(void) {
+static void vmx_step_instruction(void)
+{
vmcs_writel(GUEST_RIP, vmcs_readl(GUEST_RIP) +
vmcs_read32(VM_EXIT_INSTRUCTION_LEN));
}
@@ -1133,7 +1141,8 @@
* __vmx_enable - low-level enable of VMX mode on the current CPU
* @vmxon_buf: an opaque buffer for use as the VMXON region
*/
-static int __vmx_enable(struct vmcs *vmxon_buf) {
+static int __vmx_enable(struct vmcs *vmxon_buf)
+{
uint64_t phys_addr = PADDR(vmxon_buf);
uint64_t old, test_bits;
@@ -1174,7 +1183,8 @@
/**
* vmx_disable - disables VMX mode on the current CPU
*/
-static void vmx_disable(void *unused) {
+static void vmx_disable(void *unused)
+{
if (currentcpu->vmx_enabled) {
__vmxoff();
lcr4(rcr4() & ~X86_CR4_VMXE);
@@ -1185,7 +1195,8 @@
/* Probe the cpus to see which ones can do vmx.
* Return -errno if it fails, and 1 if it succeeds.
*/
-static bool probe_cpu_vmx(void) {
+static bool probe_cpu_vmx(void)
+{
/* The best way to test this code is:
* wrmsr -p <cpu> 0x3a 1
* This will lock vmx off; then modprobe dune.
@@ -1204,7 +1215,8 @@
}
}
-static int ept_init(void) {
+static int ept_init(void)
+{
if (!cpu_has_vmx_ept()) {
printk("VMX doesn't support EPT!\n");
return -1;
@@ -1248,12 +1260,13 @@
}
/**
- * vmx_init sets up physical core data areas that are required to run a vm at all.
- * These data areas are not connected to a specific user process in any way. Instead,
- * they are in some sense externalizing what would other wise be a very large ball of
- * state that would be inside the CPU.
+ * vmx_init sets up physical core data areas that are required to run a vm at
+ * all. These data areas are not connected to a specific user process in any
+ * way. Instead, they are in some sense externalizing what would other wise be a
+ * very large ball of state that would be inside the CPU.
*/
-int intel_vmm_init(void) {
+int intel_vmm_init(void)
+{
int r, cpu, ret;
if (!probe_cpu_vmx()) {
@@ -1293,8 +1306,8 @@
memset(io_bitmap, 0xff, VMX_IO_BITMAP_SZ);
/* These are the only MSRs that are not intercepted. The hardware takes
- * care of FS_BASE, GS_BASE, and EFER. We do the rest manually when loading
- * and unloading guest pcores. */
+ * care of FS_BASE, GS_BASE, and EFER. We do the rest manually when
+ * loading and unloading guest pcores. */
__vmx_disable_intercept_for_msr(msr_bitmap, MSR_FS_BASE);
__vmx_disable_intercept_for_msr(msr_bitmap, MSR_GS_BASE);
__vmx_disable_intercept_for_msr(msr_bitmap, MSR_EFER);
@@ -1303,8 +1316,8 @@
__vmx_disable_intercept_for_msr(msr_bitmap, MSR_STAR);
__vmx_disable_intercept_for_msr(msr_bitmap, MSR_SFMASK);
- /* TODO: this might be dangerous, since they can do more than just read the
- * CMOS */
+ /* TODO: this might be dangerous, since they can do more than just read
+ * the CMOS */
__vmx_disable_intercept_for_io(io_bitmap, CMOS_RAM_IDX);
__vmx_disable_intercept_for_io(io_bitmap, CMOS_RAM_DATA);
@@ -1313,8 +1326,8 @@
return ret;
}
printk("VMX setup succeeded\n");
- /* If this isn't true (we have VMX but not mwait), then we'll have to look
- * closely at CPU_BASED_MWAIT_EXITING. */
+ /* If this isn't true (we have VMX but not mwait), then we'll have to
+ * look closely at CPU_BASED_MWAIT_EXITING. */
assert(cpu_has_feat(CPU_FEAT_X86_MWAIT));
return 0;
}
@@ -1400,22 +1413,24 @@
PERCPU_VAR(gpc_to_clear_to) = NULL;
return;
}
- /* Clear ours *before* waiting on someone else; avoids deadlock (circular
- * wait). */
+ /* Clear ours *before* waiting on someone else; avoids deadlock
+ * (circular wait). */
__clear_vmcs(0, 0, 0, 0);
remote_core = ACCESS_ONCE(gpc->vmcs_core_id);
if (remote_core != -1) {
/* This is a bit nasty. It requires the remote core to receive
- * interrupts, which means we're now waiting indefinitely for them to
- * enable IRQs. They can wait on another core, and so on. We cleared
- * our vmcs first, so that we won't deadlock on *this*.
+ * interrupts, which means we're now waiting indefinitely for
+ * them to enable IRQs. They can wait on another core, and so
+ * on. We cleared our vmcs first, so that we won't deadlock on
+ * *this*.
*
- * However, this means we can't wait on another core with IRQs disabled
- * for any *other* reason. For instance, if some other subsystem
- * decides to have one core wait with IRQs disabled on another, the core
- * that has our VMCS could be waiting on us to do something that we'll
- * never do. */
- send_kernel_message(remote_core, __clear_vmcs, 0, 0, 0, KMSG_IMMEDIATE);
+ * However, this means we can't wait on another core with IRQs
+ * disabled for any *other* reason. For instance, if some other
+ * subsystem decides to have one core wait with IRQs disabled on
+ * another, the core that has our VMCS could be waiting on us to
+ * do something that we'll never do. */
+ send_kernel_message(remote_core, __clear_vmcs, 0, 0, 0,
+ KMSG_IMMEDIATE);
while (gpc->vmcs_core_id != -1)
cpu_relax();
}
@@ -1427,8 +1442,9 @@
void vmx_unload_guest_pcore(struct guest_pcore *gpc)
{
/* We don't have to worry about races yet. No one will try to load gpc
- * until we've returned and unlocked, and no one will clear an old VMCS to
- * this GPC, since it was cleared before we finished loading (above). */
+ * until we've returned and unlocked, and no one will clear an old VMCS
+ * to this GPC, since it was cleared before we finished loading (above).
+ */
assert(!irq_is_enabled());
gpc->vmcs_core_id = core_id();
PERCPU_VAR(gpc_to_clear_to) = gpc;
diff --git a/kern/arch/x86/vmm/intel/vmx.h b/kern/arch/x86/vmm/intel/vmx.h
index b851933..4df4f65 100644
--- a/kern/arch/x86/vmm/intel/vmx.h
+++ b/kern/arch/x86/vmm/intel/vmx.h
@@ -153,10 +153,11 @@
static inline unsigned long get_desc_base(const struct desc_struct *desc)
{
- return (unsigned)(desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24));
+ return (unsigned)(desc->base0 | ((desc->base1) << 16) |
+ ((desc->base2) << 24));
}
-#define store_gdt(dtr) native_store_gdt(dtr)
+#define store_gdt(dtr) native_store_gdt(dtr)
static inline void native_store_gdt(pseudodesc_t *dtr)
{
asm volatile("sgdt %0":"=m" (*dtr));
@@ -391,9 +392,9 @@
/* Per-VM VMX info */
struct vmx_vmm {
- uint32_t pin_exec_ctls;
- uint32_t cpu_exec_ctls;
- uint32_t cpu2_exec_ctls;
+ uint32_t pin_exec_ctls;
+ uint32_t cpu_exec_ctls;
+ uint32_t cpu2_exec_ctls;
};
int intel_vmm_init(void);
diff --git a/kern/arch/x86/vmm/vmm.c b/kern/arch/x86/vmm/vmm.c
index 1665f15..c42fe1d 100644
--- a/kern/arch/x86/vmm/vmm.c
+++ b/kern/arch/x86/vmm/vmm.c
@@ -39,6 +39,7 @@
/* Check first for intel capabilities. This is hence two back-to-back
* implementationd-dependent checks. That's ok, it's all msr dependent.
*/
+
ret = intel_vmm_init();
if (! ret) {
x86_supports_vmx = TRUE;
@@ -96,7 +97,8 @@
if (new_nr_gpcs <= vmm->gpc_array_elem)
return;
- /* TODO: (RCU) we could defer the free, maybe with an RCU-safe krealloc. */
+ /* TODO: (RCU) we could defer the free, maybe with an RCU-safe krealloc.
+ */
old_array = vmm->guest_pcores;
new_nr_elem = MAX(vmm->gpc_array_elem * 2, new_nr_gpcs);
new_array = kzmalloc(new_nr_elem * sizeof(void*), MEM_WAIT);
@@ -123,10 +125,13 @@
error(EINVAL, "Can't add %u new gpcs", new_nr_gpcs);
__vmm_grow_gpc_array(vmm, new_nr_gpcs);
for (int i = 0; i < nr_more_gpcs; i++) {
- if (copy_from_user(&gpci, &u_gpcis[i], sizeof(struct vmm_gpcore_init)))
+ if (copy_from_user(&gpci, &u_gpcis[i],
+ sizeof(struct vmm_gpcore_init)))
error(EINVAL, "Bad pointer %p for gps", u_gpcis);
- vmm->guest_pcores[vmm->nr_guest_pcores] = create_guest_pcore(p, &gpci);
- wmb(); /* concurrent readers will check nr_guest_pcores first */
+ vmm->guest_pcores[vmm->nr_guest_pcores] =
+ create_guest_pcore(p, &gpci);
+ /* concurrent readers will check nr_guest_pcores first */
+ wmb();
vmm->nr_guest_pcores++;
}
}
@@ -137,6 +142,7 @@
void __vmm_struct_cleanup(struct proc *p)
{
struct vmm *vmm = &p->vmm;
+
if (!vmm->vmmcp)
return;
for (int i = 0; i < vmm->nr_guest_pcores; i++) {
@@ -162,11 +168,11 @@
* best effort service. */
pcoreid = ACCESS_ONCE(gpc->cpu);
if (pcoreid == -1) {
- /* So we know that we'll miss the poke for the posted IRQ. We could
- * return an error. However, error handling for this case isn't
- * particularly helpful (yet). The absence of the error does not mean
- * the IRQ was posted. We'll still return 0, meaning "the user didn't
- * mess up; we tried." */
+ /* So we know that we'll miss the poke for the posted IRQ. We
+ * could return an error. However, error handling for this case
+ * isn't particularly helpful (yet). The absence of the error
+ * does not mean the IRQ was posted. We'll still return 0,
+ * meaning "the user didn't mess up; we tried." */
return 0;
}
send_ipi(pcoreid, I_POKE_GUEST);
@@ -208,7 +214,8 @@
}
gpc->cpu = core_id();
spin_unlock(&p->vmm.lock);
- /* We've got dibs on the gpc; we don't need to hold the lock any longer. */
+ /* We've got dibs on the gpc; we don't need to hold the lock any longer.
+ */
pcpui->guest_pcoreid = guest_pcoreid;
vmx_load_guest_pcore(gpc);
/* Load guest's xcr0 */
@@ -391,8 +398,8 @@
target_coreid = ACCESS_ONCE(gpc->cpu);
if (target_coreid == -1)
return false;
- /* If it's us, we'll send_ipi when we restart the VMTF. Note this is rare:
- * the guest will usually use the self_ipi virtualization. */
+ /* If it's us, we'll send_ipi when we restart the VMTF. Note this is
+ * rare: the guest will usually use the self_ipi virtualization. */
if (target_coreid != core_id())
send_ipi(target_coreid, I_POKE_GUEST);
/* No MBs needed here: only that it happens after setting notif */
@@ -524,8 +531,9 @@
uint32_t eax, edx;
if (!msr->written) {
- /* TODO: tightly coupled to the addr in vmrunkernel. We want this func
- * to return the val that vmrunkernel put into the VMCS. */
+ /* TODO: tightly coupled to the addr in vmrunkernel. We want
+ * this func to return the val that vmrunkernel put into the
+ * VMCS. */
eax = 0xfee00d00;
if (vm_tf->tf_guest_pcoreid != 0) {
// Remove BSP bit if not core 0
diff --git a/kern/arch/x86/vmm/vmm.h b/kern/arch/x86/vmm/vmm.h
index 38c4940..ca72e3a 100644
--- a/kern/arch/x86/vmm/vmm.h
+++ b/kern/arch/x86/vmm/vmm.h
@@ -6,6 +6,7 @@
static inline int cpu_has_vmx(void)
{
unsigned long ecx = cpuid_ecx(1);
+
return ecx & (1<<5); /* CPUID.1:ECX.VMX[bit 5] -> VT */
}
diff --git a/kern/arch/x86/x86.h b/kern/arch/x86/x86.h
index 96cdeb7..1a7040a 100644
--- a/kern/arch/x86/x86.h
+++ b/kern/arch/x86/x86.h
@@ -8,62 +8,62 @@
/* Model Specific Registers */
// TODO: figure out which are intel specific, and name them accordingly
-#define IA32_APIC_BASE 0x1b
+#define IA32_APIC_BASE 0x1b
/* These two are intel-only */
-#define IA32_FEATURE_CONTROL 0x3a
-#define IA32_MISC_ENABLE 0x1a0
+#define IA32_FEATURE_CONTROL 0x3a
+#define IA32_MISC_ENABLE 0x1a0
-#define IA32_MTRR_DEF_TYPE 0x2ff
-#define IA32_MTRR_PHYSBASE0 0x200
-#define IA32_MTRR_PHYSMASK0 0x201
-#define IA32_MTRR_PHYSBASE1 0x202
-#define IA32_MTRR_PHYSMASK1 0x203
-#define IA32_MTRR_PHYSBASE2 0x204
-#define IA32_MTRR_PHYSMASK2 0x205
-#define IA32_MTRR_PHYSBASE3 0x206
-#define IA32_MTRR_PHYSMASK3 0x207
-#define IA32_MTRR_PHYSBASE4 0x208
-#define IA32_MTRR_PHYSMASK4 0x209
-#define IA32_MTRR_PHYSBASE5 0x20a
-#define IA32_MTRR_PHYSMASK5 0x20b
-#define IA32_MTRR_PHYSBASE6 0x20c
-#define IA32_MTRR_PHYSMASK6 0x20d
-#define IA32_MTRR_PHYSBASE7 0x20e
-#define IA32_MTRR_PHYSMASK7 0x20f
+#define IA32_MTRR_DEF_TYPE 0x2ff
+#define IA32_MTRR_PHYSBASE0 0x200
+#define IA32_MTRR_PHYSMASK0 0x201
+#define IA32_MTRR_PHYSBASE1 0x202
+#define IA32_MTRR_PHYSMASK1 0x203
+#define IA32_MTRR_PHYSBASE2 0x204
+#define IA32_MTRR_PHYSMASK2 0x205
+#define IA32_MTRR_PHYSBASE3 0x206
+#define IA32_MTRR_PHYSMASK3 0x207
+#define IA32_MTRR_PHYSBASE4 0x208
+#define IA32_MTRR_PHYSMASK4 0x209
+#define IA32_MTRR_PHYSBASE5 0x20a
+#define IA32_MTRR_PHYSMASK5 0x20b
+#define IA32_MTRR_PHYSBASE6 0x20c
+#define IA32_MTRR_PHYSMASK6 0x20d
+#define IA32_MTRR_PHYSBASE7 0x20e
+#define IA32_MTRR_PHYSMASK7 0x20f
-#define MSR_APIC_ENABLE 0x00000800
-#define MSR_APIC_BASE_ADDRESS 0x0000000FFFFFF000
+#define MSR_APIC_ENABLE 0x00000800
+#define MSR_APIC_BASE_ADDRESS 0x0000000FFFFFF000
-#define IA32_EFER_MSR 0xc0000080
-# define IA32_EFER_SYSCALL (1 << 0)
-# define IA32_EFER_IA32E_EN (1 << 8)
-# define IA32_EFER_IA32E_ACT (1 << 10)
-# define IA32_EFER_EXE_DIS_BIT (1 << 11)
+#define IA32_EFER_MSR 0xc0000080
+# define IA32_EFER_SYSCALL (1 << 0)
+# define IA32_EFER_IA32E_EN (1 << 8)
+# define IA32_EFER_IA32E_ACT (1 << 10)
+# define IA32_EFER_EXE_DIS_BIT (1 << 11)
-#define MSR_TSC_AUX 0xc0000103
+#define MSR_TSC_AUX 0xc0000103
-#define MSR_FS_BASE 0xc0000100
-#define MSR_GS_BASE 0xc0000101
-#define MSR_KERN_GS_BASE 0xc0000102
+#define MSR_FS_BASE 0xc0000100
+#define MSR_GS_BASE 0xc0000101
+#define MSR_KERN_GS_BASE 0xc0000102
-#define MSR_STAR 0xc0000081
-#define MSR_LSTAR 0xc0000082
-#define MSR_CSTAR 0xc0000083
-#define MSR_SFMASK 0xc0000084
+#define MSR_STAR 0xc0000081
+#define MSR_LSTAR 0xc0000082
+#define MSR_CSTAR 0xc0000083
+#define MSR_SFMASK 0xc0000084
/* CPUID */
-#define CPUID_PSE_SUPPORT 0x00000008
+#define CPUID_PSE_SUPPORT 0x00000008
/* Arch Constants */
-#define MAX_NUM_CORES 255
+#define MAX_NUM_CORES 255
-#define X86_REG_BP "rbp"
-#define X86_REG_SP "rsp"
-#define X86_REG_IP "rip"
-#define X86_REG_AX "rax"
-#define X86_REG_BX "rbx"
-#define X86_REG_CX "rcx"
-#define X86_REG_DX "rdx"
+#define X86_REG_BP "rbp"
+#define X86_REG_SP "rsp"
+#define X86_REG_IP "rip"
+#define X86_REG_AX "rax"
+#define X86_REG_BX "rbx"
+#define X86_REG_CX "rcx"
+#define X86_REG_DX "rdx"
/* Various flags defined: can be included from assembler. */
@@ -136,12 +136,12 @@
/* MWAIT C-state hints. The names might not be right for different processors.
* For instance, the Linux idle driver for a Haswell calls the mwait for 0x10
* "C3-HSW". */
-#define X86_MWAIT_C1 0x00
-#define X86_MWAIT_C2 0x10
-#define X86_MWAIT_C3 0x20
-#define X86_MWAIT_C4 0x30
-#define X86_MWAIT_C5 0x40
-#define X86_MWAIT_C6 0x50
+#define X86_MWAIT_C1 0x00
+#define X86_MWAIT_C2 0x10
+#define X86_MWAIT_C3 0x20
+#define X86_MWAIT_C4 0x30
+#define X86_MWAIT_C5 0x40
+#define X86_MWAIT_C6 0x50
/*
* x86-64 Task Priority Register, CR8
@@ -185,22 +185,21 @@
static inline unsigned long read_flags(void) __attribute__((always_inline));
static inline void write_eflags(unsigned long eflags)
- __attribute__((always_inline));
+ __attribute__((always_inline));
static inline unsigned long read_bp(void) __attribute__((always_inline));
static inline unsigned long read_pc(void) __attribute__((always_inline));
static inline unsigned long read_sp(void) __attribute__((always_inline));
static inline void cpuid(uint32_t info1, uint32_t info2, uint32_t *eaxp,
uint32_t *ebxp, uint32_t *ecxp, uint32_t *edxp)
- __attribute__((always_inline));
+ __attribute__((always_inline));
static inline uint32_t cpuid_ecx(uint32_t op) __attribute__((always_inline));
static inline uint64_t read_msr(uint32_t reg) __attribute__((always_inline));
static inline void write_msr(uint32_t reg, uint64_t val)
- __attribute__((always_inline));
+ __attribute__((always_inline));
/* if we have mm64s, change the hpet helpers */
static inline void write_mmreg8(uintptr_t reg, uint8_t val)
- __attribute__((always_inline));
-static inline uint8_t read_mmreg8(uintptr_t reg)
- __attribute__((always_inline));
+ __attribute__((always_inline));
+static inline uint8_t read_mmreg8(uintptr_t reg) __attribute__((always_inline));
static inline void write_mmreg32(uintptr_t reg, uint32_t val)
__attribute__((always_inline));
static inline uint32_t read_mmreg32(uintptr_t reg)
@@ -217,6 +216,7 @@
static inline uint8_t inb(int port)
{
uint8_t data;
+
asm volatile("inb %w1,%0" : "=a" (data) : "d" (port));
return data;
}
@@ -231,6 +231,7 @@
static inline uint16_t inw(int port)
{
+
uint16_t data;
asm volatile("inw %w1,%0" : "=a" (data) : "d" (port));
return data;
@@ -246,6 +247,7 @@
static inline uint32_t inl(int port)
{
+
uint32_t data;
asm volatile("inl %w1,%0" : "=a" (data) : "d" (port));
return data;
@@ -380,7 +382,7 @@
edx = xcr0 >> 32;
eax = xcr0;
asm volatile(ASM_STAC ";"
- "1: xsetbv ;"
+ "1: xsetbv ;"
"2: " ASM_CLAC " ;"
".section .fixup, \"ax\";"
"3: mov %4, %0 ;"
@@ -407,6 +409,7 @@
static inline unsigned long read_flags(void)
{
unsigned long eflags;
+
asm volatile("pushf; pop %0" : "=r" (eflags));
return eflags;
}
@@ -419,6 +422,7 @@
static inline unsigned long read_bp(void)
{
unsigned long bp;
+
asm volatile("mov %%"X86_REG_BP",%0" : "=r" (bp));
return bp;
}
@@ -426,6 +430,7 @@
static inline unsigned long read_pc(void)
{
unsigned long ip;
+
asm volatile("call 1f; 1: pop %0" : "=r"(ip));
return ip;
}
@@ -433,6 +438,7 @@
static inline unsigned long read_sp(void)
{
unsigned long sp;
+
asm volatile("mov %%"X86_REG_SP",%0" : "=r" (sp));
return sp;
}
@@ -441,6 +447,7 @@
uint32_t *ebxp, uint32_t *ecxp, uint32_t *edxp)
{
uint32_t eax, ebx, ecx, edx;
+
/* Can select with both eax (info1) and ecx (info2) */
asm volatile("cpuid"
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
@@ -458,6 +465,7 @@
static inline uint32_t cpuid_ecx(uint32_t op)
{
uint32_t ecx;
+
cpuid(op, 0, NULL, NULL, &ecx, NULL);
return ecx;
}
@@ -466,6 +474,7 @@
static inline uint64_t read_msr(uint32_t reg)
{
uint32_t edx, eax;
+
asm volatile("rdmsr; mfence" : "=d"(edx), "=a"(eax) : "c"(reg));
return (uint64_t)edx << 32 | eax;
}
@@ -504,8 +513,8 @@
* with arch/arch.h and arch/apic.h */
static inline void __cpu_relax(void)
{
- // in case the compiler doesn't serialize for pause, the "m" will make sure
- // no memory is reordered around this instruction.
+ // in case the compiler doesn't serialize for pause, the "m" will make
+ // sure no memory is reordered around this instruction.
asm volatile("pause" : : : "memory");
}
diff --git a/kern/drivers/dev/acpi.c b/kern/drivers/dev/acpi.c
index d3bfb34..cc999cc 100644
--- a/kern/drivers/dev/acpi.c
+++ b/kern/drivers/dev/acpi.c
@@ -7,20 +7,20 @@
* in the LICENSE file.
*/
-#include <slab.h>
+#include <acpi.h>
+#include <assert.h>
+#include <cpio.h>
+#include <error.h>
#include <kmalloc.h>
#include <kref.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <error.h>
-#include <cpio.h>
-#include <pmap.h>
-#include <smp.h>
#include <net/ip.h>
#include <ns.h>
-#include <acpi.h>
+#include <pmap.h>
+#include <slab.h>
#include <slice.h>
+#include <smp.h>
+#include <stdio.h>
+#include <string.h>
#include "../timers/hpet.h"
@@ -43,21 +43,20 @@
* Qpretty, at any level, will print the pretty form for that level and all
* descendants.
*/
-enum {
- Qroot = 0,
+enum { Qroot = 0,
- // The type is the qid.path mod NQtypes.
- Qdir = 0,
- Qpretty,
- Qraw,
- Qtbl,
- NQtypes,
+ // The type is the qid.path mod NQtypes.
+ Qdir = 0,
+ Qpretty,
+ Qraw,
+ Qtbl,
+ NQtypes,
- QIndexShift = 8,
- QIndexMask = (1 << QIndexShift) - 1,
+ QIndexShift = 8,
+ QIndexMask = (1 << QIndexShift) - 1,
};
-#define ATABLEBUFSZ ROUNDUP(sizeof(struct Atable), KMALLOC_ALIGNMENT)
+#define ATABLEBUFSZ ROUNDUP(sizeof(struct Atable), KMALLOC_ALIGNMENT)
static uint64_t lastpath;
static struct slice emptyslice;
@@ -78,28 +77,27 @@
* interpreter.
*/
static struct cmdtab ctls[] = {
- {CMregion, "region", 6},
- {CMgpe, "gpe", 3},
+ {CMregion, "region", 6},
+ {CMgpe, "gpe", 3},
};
-static struct Facs *facs; /* Firmware ACPI control structure */
-static struct Fadt *fadt; /* Fixed ACPI description to reach ACPI regs */
+static struct Facs *facs; /* Firmware ACPI control structure */
+static struct Fadt *fadt; /* Fixed ACPI description to reach ACPI regs */
static struct Atable *root;
-static struct Xsdt *xsdt; /* XSDT table */
-static struct Atable *tfirst; /* loaded DSDT/SSDT/... tables */
-static struct Atable *tlast; /* pointer to last table */
-struct Atable *apics; /* APIC info */
-struct Atable *srat; /* System resource affinity used by physalloc */
+static struct Xsdt *xsdt; /* XSDT table */
+static struct Atable *tfirst; /* loaded DSDT/SSDT/... tables */
+static struct Atable *tlast; /* pointer to last table */
+struct Atable *apics; /* APIC info */
+struct Atable *srat; /* System resource affinity used by physalloc */
struct Atable *dmar;
-static struct Slit *slit; /* Sys locality info table used by scheduler */
-static struct Atable *mscttbl; /* Maximum system characteristics table */
-static struct Reg *reg; /* region used for I/O */
-static struct Gpe *gpes; /* General purpose events */
+static struct Slit *slit; /* Sys locality info table used by scheduler */
+static struct Atable *mscttbl; /* Maximum system characteristics table */
+static struct Reg *reg; /* region used for I/O */
+static struct Gpe *gpes; /* General purpose events */
static int ngpes;
static char *regnames[] = {
- "mem", "io", "pcicfg", "embed",
- "smb", "cmos", "pcibar", "ipmi",
+ "mem", "io", "pcicfg", "embed", "smb", "cmos", "pcibar", "ipmi",
};
/*
@@ -121,9 +119,8 @@
* isomorphic to directories in the file system namespace; this code
* ensures that invariant.
*/
-struct Atable *mkatable(struct Atable *parent,
- int type, char *name, uint8_t *raw,
- size_t rawsize, size_t addsize)
+struct Atable *mkatable(struct Atable *parent, int type, char *name,
+ uint8_t *raw, size_t rawsize, size_t addsize)
{
void *m;
struct Atable *t;
@@ -139,7 +136,7 @@
t->rawsize = rawsize;
t->raw = raw;
strlcpy(t->name, name, sizeof(t->name));
- mkqid(&t->qid, (lastpath << QIndexShift) + Qdir, 0, QTDIR);
+ mkqid(&t->qid, (lastpath << QIndexShift) + Qdir, 0, QTDIR);
mkqid(&t->rqid, (lastpath << QIndexShift) + Qraw, 0, 0);
mkqid(&t->pqid, (lastpath << QIndexShift) + Qpretty, 0, 0);
mkqid(&t->tqid, (lastpath << QIndexShift) + Qtbl, 0, 0);
@@ -157,13 +154,13 @@
n = slice_len(slice);
t->nchildren = n;
t->children = (struct Atable **)slice_finalize(slice);
- dirs = kreallocarray(NULL, n + NQtypes, sizeof(struct dirtab),
- MEM_WAIT);
+ dirs =
+ kreallocarray(NULL, n + NQtypes, sizeof(struct dirtab), MEM_WAIT);
assert(dirs != NULL);
- dirs[0] = (struct dirtab){ ".", t->qid, 0, 0555 };
- dirs[1] = (struct dirtab){ "pretty", t->pqid, 0, 0444 };
- dirs[2] = (struct dirtab){ "raw", t->rqid, 0, 0444 };
- dirs[3] = (struct dirtab){ "table", t->tqid, 0, 0444 };
+ dirs[0] = (struct dirtab){".", t->qid, 0, 0555};
+ dirs[1] = (struct dirtab){"pretty", t->pqid, 0, 0444};
+ dirs[2] = (struct dirtab){"raw", t->rqid, 0, 0444};
+ dirs[3] = (struct dirtab){"table", t->tqid, 0, 0444};
for (size_t i = 0; i < n; i++) {
strlcpy(dirs[i + NQtypes].name, t->children[i]->name, KNAMELEN);
dirs[i + NQtypes].qid = t->children[i]->qid;
@@ -190,7 +187,7 @@
static char *acpiregstr(int id)
{
- static char buf[20]; /* BUG */
+ static char buf[20]; /* BUG */
if (id >= 0 && id < ARRAY_SIZE(regnames))
return regnames[id];
@@ -212,49 +209,49 @@
*/
static uint8_t mget8(uintptr_t p, void *unused)
{
- uint8_t *cp = (uint8_t *) p;
+ uint8_t *cp = (uint8_t *)p;
return *cp;
}
static void mset8(uintptr_t p, uint8_t v, void *unused)
{
- uint8_t *cp = (uint8_t *) p;
+ uint8_t *cp = (uint8_t *)p;
*cp = v;
}
static uint16_t mget16(uintptr_t p, void *unused)
{
- uint16_t *cp = (uint16_t *) p;
+ uint16_t *cp = (uint16_t *)p;
return *cp;
}
static void mset16(uintptr_t p, uint16_t v, void *unused)
{
- uint16_t *cp = (uint16_t *) p;
+ uint16_t *cp = (uint16_t *)p;
*cp = v;
}
static uint32_t mget32(uintptr_t p, void *unused)
{
- uint32_t *cp = (uint32_t *) p;
+ uint32_t *cp = (uint32_t *)p;
return *cp;
}
static void mset32(uintptr_t p, uint32_t v, void *unused)
{
- uint32_t *cp = (uint32_t *) p;
+ uint32_t *cp = (uint32_t *)p;
*cp = v;
}
static uint64_t mget64(uintptr_t p, void *unused)
{
- uint64_t *cp = (uint64_t *) p;
+ uint64_t *cp = (uint64_t *)p;
return *cp;
}
static void mset64(uintptr_t p, uint64_t v, void *unused)
{
- uint64_t *cp = (uint64_t *) p;
+ uint64_t *cp = (uint64_t *)p;
*cp = v;
}
@@ -346,30 +343,20 @@
pcidev_write32(&pcidev, p, v);
}
-static struct Regio memio = {
- NULL,
- mget8, mset8, mget16, mset16,
- mget32, mset32, mget64, mset64
-};
+static struct Regio memio = {NULL, mget8, mset8, mget16, mset16,
+ mget32, mset32, mget64, mset64};
-static struct Regio ioio = {
- NULL,
- ioget8, ioset8, ioget16, ioset16,
- ioget32, ioset32, NULL, NULL
-};
+static struct Regio ioio = {NULL, ioget8, ioset8, ioget16, ioset16,
+ ioget32, ioset32, NULL, NULL};
-static struct Regio cfgio = {
- NULL,
- cfgget8, cfgset8, cfgget16, cfgset16,
- cfgget32, cfgset32, NULL, NULL
-};
+static struct Regio cfgio = {NULL, cfgget8, cfgset8, cfgget16, cfgset16,
+ cfgget32, cfgset32, NULL, NULL};
/*
* Copy memory, 1/2/4/8-bytes at a time, to/from a region.
*/
-static long
-regcpy(struct Regio *dio, uintptr_t da, struct Regio *sio,
- uintptr_t sa, long len, int align)
+static long regcpy(struct Regio *dio, uintptr_t da, struct Regio *sio,
+ uintptr_t sa, long len, int align)
{
int n, i;
@@ -379,25 +366,25 @@
n = len / align;
for (i = 0; i < n; i++) {
switch (align) {
- case 1:
- printd("cpy8 %#p %#p\n", da, sa);
- dio->set8(da, sio->get8(sa, sio->arg), dio->arg);
- break;
- case 2:
- printd("cpy16 %#p %#p\n", da, sa);
- dio->set16(da, sio->get16(sa, sio->arg), dio->arg);
- break;
- case 4:
- printd("cpy32 %#p %#p\n", da, sa);
- dio->set32(da, sio->get32(sa, sio->arg), dio->arg);
- break;
- case 8:
- printd("cpy64 %#p %#p\n", da, sa);
- warn("Not doing set64 for some reason, fix me!");
- // dio->set64(da, sio->get64(sa, sio->arg), dio->arg);
- break;
- default:
- panic("regcpy: align bug");
+ case 1:
+ printd("cpy8 %#p %#p\n", da, sa);
+ dio->set8(da, sio->get8(sa, sio->arg), dio->arg);
+ break;
+ case 2:
+ printd("cpy16 %#p %#p\n", da, sa);
+ dio->set16(da, sio->get16(sa, sio->arg), dio->arg);
+ break;
+ case 4:
+ printd("cpy32 %#p %#p\n", da, sa);
+ dio->set32(da, sio->get32(sa, sio->arg), dio->arg);
+ break;
+ case 8:
+ printd("cpy64 %#p %#p\n", da, sa);
+ warn("Not doing set64 for some reason, fix me!");
+ // dio->set64(da, sio->get64(sa, sio->arg), dio->arg);
+ break;
+ default:
+ panic("regcpy: align bug");
}
da += align;
sa += align;
@@ -414,8 +401,8 @@
struct Regio rio;
uintptr_t rp;
- printd("reg%s %s %#p %#p %#lx sz=%d\n",
- iswr ? "out" : "in", r->name, p, off, len, r->accsz);
+ printd("reg%s %s %#p %#p %#lx sz=%d\n", iswr ? "out" : "in", r->name, p,
+ off, len, r->accsz);
rp = 0;
if (off + len > r->len) {
printd("regio: access outside limits");
@@ -426,36 +413,36 @@
return 0;
}
switch (r->spc) {
- case Rsysmem:
- if (r->p == NULL)
- r->p = KADDR_NOCHECK(r->base);
- if (r->p == NULL)
- error(EFAIL, "regio: vmap/KADDR failed");
- rp = (uintptr_t) r->p + off;
- rio = memio;
- break;
- case Rsysio:
- rp = r->base + off;
- rio = ioio;
- break;
- case Rpcicfg:
- rp = r->base + off;
- rio = cfgio;
- rio.arg = r;
- break;
- case Rpcibar:
- case Rembed:
- case Rsmbus:
- case Rcmos:
- case Ripmi:
- case Rfixedhw:
- printd("regio: reg %s not supported\n", acpiregstr(r->spc));
- error(EFAIL, "region not supported");
+ case Rsysmem:
+ if (r->p == NULL)
+ r->p = KADDR_NOCHECK(r->base);
+ if (r->p == NULL)
+ error(EFAIL, "regio: vmap/KADDR failed");
+ rp = (uintptr_t)r->p + off;
+ rio = memio;
+ break;
+ case Rsysio:
+ rp = r->base + off;
+ rio = ioio;
+ break;
+ case Rpcicfg:
+ rp = r->base + off;
+ rio = cfgio;
+ rio.arg = r;
+ break;
+ case Rpcibar:
+ case Rembed:
+ case Rsmbus:
+ case Rcmos:
+ case Ripmi:
+ case Rfixedhw:
+ printd("regio: reg %s not supported\n", acpiregstr(r->spc));
+ error(EFAIL, "region not supported");
}
if (iswr)
- regcpy(&rio, rp, &memio, (uintptr_t) p, len, r->accsz);
+ regcpy(&rio, rp, &memio, (uintptr_t)p, len, r->accsz);
else
- regcpy(&memio, (uintptr_t) p, &rio, rp, len, r->accsz);
+ regcpy(&memio, (uintptr_t)p, &rio, rp, len, r->accsz);
return len;
}
@@ -489,7 +476,8 @@
}
*n = l32get(sdt->length);
if (!*n) {
- printk("sdt has zero length: pa = %p, sig = %.4s\n", pa, sdt->sig);
+ printk("sdt has zero length: pa = %p, sig = %.4s\n", pa,
+ sdt->sig);
return NULL;
}
if (cksum != 0 && sdtchecksum(sdt, *n) != 0) {
@@ -560,59 +548,75 @@
start = seprintf(start, end, "acpi: FADT@%p\n", fp);
start = seprintf(start, end, "acpi: fadt: facs: $%p\n", fp->facs);
start = seprintf(start, end, "acpi: fadt: dsdt: $%p\n", fp->dsdt);
- start = seprintf(start, end, "acpi: fadt: pmprofile: $%p\n", fp->pmprofile);
+ start =
+ seprintf(start, end, "acpi: fadt: pmprofile: $%p\n", fp->pmprofile);
start = seprintf(start, end, "acpi: fadt: sciint: $%p\n", fp->sciint);
start = seprintf(start, end, "acpi: fadt: smicmd: $%p\n", fp->smicmd);
+ start = seprintf(start, end, "acpi: fadt: acpienable: $%p\n",
+ fp->acpienable);
+ start = seprintf(start, end, "acpi: fadt: acpidisable: $%p\n",
+ fp->acpidisable);
start =
- seprintf(start, end, "acpi: fadt: acpienable: $%p\n", fp->acpienable);
+ seprintf(start, end, "acpi: fadt: s4biosreq: $%p\n", fp->s4biosreq);
start =
- seprintf(start, end, "acpi: fadt: acpidisable: $%p\n", fp->acpidisable);
- start = seprintf(start, end, "acpi: fadt: s4biosreq: $%p\n", fp->s4biosreq);
- start = seprintf(start, end, "acpi: fadt: pstatecnt: $%p\n", fp->pstatecnt);
+ seprintf(start, end, "acpi: fadt: pstatecnt: $%p\n", fp->pstatecnt);
+ start = seprintf(start, end, "acpi: fadt: pm1aevtblk: $%p\n",
+ fp->pm1aevtblk);
+ start = seprintf(start, end, "acpi: fadt: pm1bevtblk: $%p\n",
+ fp->pm1bevtblk);
+ start = seprintf(start, end, "acpi: fadt: pm1acntblk: $%p\n",
+ fp->pm1acntblk);
+ start = seprintf(start, end, "acpi: fadt: pm1bcntblk: $%p\n",
+ fp->pm1bcntblk);
start =
- seprintf(start, end, "acpi: fadt: pm1aevtblk: $%p\n", fp->pm1aevtblk);
+ seprintf(start, end, "acpi: fadt: pm2cntblk: $%p\n", fp->pm2cntblk);
start =
- seprintf(start, end, "acpi: fadt: pm1bevtblk: $%p\n", fp->pm1bevtblk);
- start =
- seprintf(start, end, "acpi: fadt: pm1acntblk: $%p\n", fp->pm1acntblk);
- start =
- seprintf(start, end, "acpi: fadt: pm1bcntblk: $%p\n", fp->pm1bcntblk);
- start = seprintf(start, end, "acpi: fadt: pm2cntblk: $%p\n", fp->pm2cntblk);
- start = seprintf(start, end, "acpi: fadt: pmtmrblk: $%p\n", fp->pmtmrblk);
+ seprintf(start, end, "acpi: fadt: pmtmrblk: $%p\n", fp->pmtmrblk);
start = seprintf(start, end, "acpi: fadt: gpe0blk: $%p\n", fp->gpe0blk);
start = seprintf(start, end, "acpi: fadt: gpe1blk: $%p\n", fp->gpe1blk);
- start = seprintf(start, end, "acpi: fadt: pm1evtlen: $%p\n", fp->pm1evtlen);
- start = seprintf(start, end, "acpi: fadt: pm1cntlen: $%p\n", fp->pm1cntlen);
- start = seprintf(start, end, "acpi: fadt: pm2cntlen: $%p\n", fp->pm2cntlen);
- start = seprintf(start, end, "acpi: fadt: pmtmrlen: $%p\n", fp->pmtmrlen);
start =
- seprintf(start, end, "acpi: fadt: gpe0blklen: $%p\n", fp->gpe0blklen);
+ seprintf(start, end, "acpi: fadt: pm1evtlen: $%p\n", fp->pm1evtlen);
start =
- seprintf(start, end, "acpi: fadt: gpe1blklen: $%p\n", fp->gpe1blklen);
+ seprintf(start, end, "acpi: fadt: pm1cntlen: $%p\n", fp->pm1cntlen);
+ start =
+ seprintf(start, end, "acpi: fadt: pm2cntlen: $%p\n", fp->pm2cntlen);
+ start =
+ seprintf(start, end, "acpi: fadt: pmtmrlen: $%p\n", fp->pmtmrlen);
+ start = seprintf(start, end, "acpi: fadt: gpe0blklen: $%p\n",
+ fp->gpe0blklen);
+ start = seprintf(start, end, "acpi: fadt: gpe1blklen: $%p\n",
+ fp->gpe1blklen);
start = seprintf(start, end, "acpi: fadt: gp1base: $%p\n", fp->gp1base);
start = seprintf(start, end, "acpi: fadt: cstcnt: $%p\n", fp->cstcnt);
- start = seprintf(start, end, "acpi: fadt: plvl2lat: $%p\n", fp->plvl2lat);
- start = seprintf(start, end, "acpi: fadt: plvl3lat: $%p\n", fp->plvl3lat);
- start = seprintf(start, end, "acpi: fadt: flushsz: $%p\n", fp->flushsz);
start =
- seprintf(start, end, "acpi: fadt: flushstride: $%p\n", fp->flushstride);
+ seprintf(start, end, "acpi: fadt: plvl2lat: $%p\n", fp->plvl2lat);
+ start =
+ seprintf(start, end, "acpi: fadt: plvl3lat: $%p\n", fp->plvl3lat);
+ start = seprintf(start, end, "acpi: fadt: flushsz: $%p\n", fp->flushsz);
+ start = seprintf(start, end, "acpi: fadt: flushstride: $%p\n",
+ fp->flushstride);
start = seprintf(start, end, "acpi: fadt: dutyoff: $%p\n", fp->dutyoff);
- start = seprintf(start, end, "acpi: fadt: dutywidth: $%p\n", fp->dutywidth);
+ start =
+ seprintf(start, end, "acpi: fadt: dutywidth: $%p\n", fp->dutywidth);
start = seprintf(start, end, "acpi: fadt: dayalrm: $%p\n", fp->dayalrm);
start = seprintf(start, end, "acpi: fadt: monalrm: $%p\n", fp->monalrm);
start = seprintf(start, end, "acpi: fadt: century: $%p\n", fp->century);
- start =
- seprintf(start, end, "acpi: fadt: iapcbootarch: $%p\n",
- fp->iapcbootarch);
+ start = seprintf(start, end, "acpi: fadt: iapcbootarch: $%p\n",
+ fp->iapcbootarch);
start = seprintf(start, end, "acpi: fadt: flags: $%p\n", fp->flags);
start = dumpGas(start, end, "acpi: fadt: resetreg: ", &fp->resetreg);
- start = seprintf(start, end, "acpi: fadt: resetval: $%p\n", fp->resetval);
+ start =
+ seprintf(start, end, "acpi: fadt: resetval: $%p\n", fp->resetval);
start = seprintf(start, end, "acpi: fadt: xfacs: %p\n", fp->xfacs);
start = seprintf(start, end, "acpi: fadt: xdsdt: %p\n", fp->xdsdt);
- start = dumpGas(start, end, "acpi: fadt: xpm1aevtblk:", &fp->xpm1aevtblk);
- start = dumpGas(start, end, "acpi: fadt: xpm1bevtblk:", &fp->xpm1bevtblk);
- start = dumpGas(start, end, "acpi: fadt: xpm1acntblk:", &fp->xpm1acntblk);
- start = dumpGas(start, end, "acpi: fadt: xpm1bcntblk:", &fp->xpm1bcntblk);
+ start =
+ dumpGas(start, end, "acpi: fadt: xpm1aevtblk:", &fp->xpm1aevtblk);
+ start =
+ dumpGas(start, end, "acpi: fadt: xpm1bevtblk:", &fp->xpm1bevtblk);
+ start =
+ dumpGas(start, end, "acpi: fadt: xpm1acntblk:", &fp->xpm1acntblk);
+ start =
+ dumpGas(start, end, "acpi: fadt: xpm1bcntblk:", &fp->xpm1bcntblk);
start = dumpGas(start, end, "acpi: fadt: xpm2cntblk:", &fp->xpm2cntblk);
start = dumpGas(start, end, "acpi: fadt: xpmtmrblk:", &fp->xpmtmrblk);
start = dumpGas(start, end, "acpi: fadt: xgpe0blk:", &fp->xgpe0blk);
@@ -620,8 +624,8 @@
return start;
}
-static struct Atable *parsefadt(struct Atable *parent,
- char *name, uint8_t *p, size_t rawsize)
+static struct Atable *parsefadt(struct Atable *parent, char *name, uint8_t *p,
+ size_t rawsize)
{
struct Atable *t;
struct Fadt *fp;
@@ -697,7 +701,7 @@
else
loadfacs(fp->facs);
- if (fp->xdsdt == (uint64_t)fp->dsdt) /* acpica */
+ if (fp->xdsdt == (uint64_t)fp->dsdt) /* acpica */
loaddsdt(fp->xdsdt);
else
loaddsdt(fp->dsdt);
@@ -716,14 +720,16 @@
if (!msct)
return start;
- start = seprintf(start, end, "acpi: msct: %d doms %d clkdoms %#p maxpa\n",
- msct->ndoms, msct->nclkdoms, msct->maxpa);
+ start =
+ seprintf(start, end, "acpi: msct: %d doms %d clkdoms %#p maxpa\n",
+ msct->ndoms, msct->nclkdoms, msct->maxpa);
for (int i = 0; i < table->nchildren; i++) {
struct Atable *domtbl = table->children[i]->tbl;
struct Mdom *st = domtbl->tbl;
- start = seprintf(start, end, "\t[%d:%d] %d maxproc %#p maxmmem\n",
- st->start, st->end, st->maxproc, st->maxmem);
+ start =
+ seprintf(start, end, "\t[%d:%d] %d maxproc %#p maxmmem\n",
+ st->start, st->end, st->maxproc, st->maxmem);
}
start = seprintf(start, end, "\n");
@@ -734,8 +740,8 @@
* XXX: should perhaps update our idea of available memory.
* Else we should remove this code.
*/
-static struct Atable *parsemsct(struct Atable *parent,
- char *name, uint8_t *raw, size_t rawsize)
+static struct Atable *parsemsct(struct Atable *parent, char *name, uint8_t *raw,
+ size_t rawsize)
{
struct Atable *t;
uint8_t *r, *re;
@@ -806,35 +812,37 @@
if (st == NULL)
continue;
switch (st->type) {
- case SRlapic:
- start =
- seprintf(start, end,
- "\tlapic: dom %d apic %d sapic %d clk %d\n",
- st->lapic.dom, st->lapic.apic, st->lapic.sapic,
- st->lapic.clkdom);
- break;
- case SRmem:
- start = seprintf(start, end, "\tmem: dom %d %#p %#p %c%c\n",
- st->mem.dom, st->mem.addr, st->mem.len,
- st->mem.hplug ? 'h' : '-',
- st->mem.nvram ? 'n' : '-');
- break;
- case SRlx2apic:
- start =
- seprintf(start, end, "\tlx2apic: dom %d apic %d clk %d\n",
- st->lx2apic.dom, st->lx2apic.apic,
- st->lx2apic.clkdom);
- break;
- default:
- start = seprintf(start, end, "\t<unknown srat entry>\n");
+ case SRlapic:
+ start = seprintf(
+ start, end,
+ "\tlapic: dom %d apic %d sapic %d clk %d\n",
+ st->lapic.dom, st->lapic.apic, st->lapic.sapic,
+ st->lapic.clkdom);
+ break;
+ case SRmem:
+ start =
+ seprintf(start, end, "\tmem: dom %d %#p %#p %c%c\n",
+ st->mem.dom, st->mem.addr, st->mem.len,
+ st->mem.hplug ? 'h' : '-',
+ st->mem.nvram ? 'n' : '-');
+ break;
+ case SRlx2apic:
+ start = seprintf(start, end,
+ "\tlx2apic: dom %d apic %d clk %d\n",
+ st->lx2apic.dom, st->lx2apic.apic,
+ st->lx2apic.clkdom);
+ break;
+ default:
+ start =
+ seprintf(start, end, "\t<unknown srat entry>\n");
}
}
start = seprintf(start, end, "\n");
return start;
}
-static struct Atable *parsesrat(struct Atable *parent,
- char *name, uint8_t *p, size_t rawsize)
+static struct Atable *parsesrat(struct Atable *parent, char *name, uint8_t *p,
+ size_t rawsize)
{
struct Atable *t, *tt, *tail;
@@ -861,43 +869,44 @@
st = tt->tbl;
st->type = p[0];
switch (st->type) {
- case SRlapic:
- st->lapic.dom = p[2] | p[9] << 24 | p[10] << 16 | p[11] << 8;
- st->lapic.apic = p[3];
- st->lapic.sapic = p[8];
- st->lapic.clkdom = l32get(p + 12);
- if (l32get(p + 4) == 0) {
- kfree(tt);
- tt = NULL;
- }
- break;
- case SRmem:
- st->mem.dom = l32get(p + 2);
- st->mem.addr = l64get(p + 8);
- st->mem.len = l64get(p + 16);
- flags = l32get(p + 28);
- if ((flags & 1) == 0) { /* not enabled */
- kfree(tt);
- tt = NULL;
- } else {
- st->mem.hplug = flags & 2;
- st->mem.nvram = flags & 4;
- }
- break;
- case SRlx2apic:
- st->lx2apic.dom = l32get(p + 4);
- st->lx2apic.apic = l32get(p + 8);
- st->lx2apic.clkdom = l32get(p + 16);
- if (l32get(p + 12) == 0) {
- kfree(tt);
- tt = NULL;
- }
- break;
- default:
- printd("unknown SRAT structure\n");
+ case SRlapic:
+ st->lapic.dom =
+ p[2] | p[9] << 24 | p[10] << 16 | p[11] << 8;
+ st->lapic.apic = p[3];
+ st->lapic.sapic = p[8];
+ st->lapic.clkdom = l32get(p + 12);
+ if (l32get(p + 4) == 0) {
kfree(tt);
tt = NULL;
- break;
+ }
+ break;
+ case SRmem:
+ st->mem.dom = l32get(p + 2);
+ st->mem.addr = l64get(p + 8);
+ st->mem.len = l64get(p + 16);
+ flags = l32get(p + 28);
+ if ((flags & 1) == 0) { /* not enabled */
+ kfree(tt);
+ tt = NULL;
+ } else {
+ st->mem.hplug = flags & 2;
+ st->mem.nvram = flags & 4;
+ }
+ break;
+ case SRlx2apic:
+ st->lx2apic.dom = l32get(p + 4);
+ st->lx2apic.apic = l32get(p + 8);
+ st->lx2apic.clkdom = l32get(p + 16);
+ if (l32get(p + 12) == 0) {
+ kfree(tt);
+ tt = NULL;
+ }
+ break;
+ default:
+ printd("unknown SRAT structure\n");
+ kfree(tt);
+ tt = NULL;
+ break;
}
if (tt != NULL) {
finatable_nochildren(tt);
@@ -917,9 +926,8 @@
return start;
start = seprintf(start, end, "acpi slit:\n");
for (i = 0; i < sl->rowlen * sl->rowlen; i++) {
- start = seprintf(start, end,
- "slit: %ux\n",
- sl->e[i / sl->rowlen][i % sl->rowlen].dist);
+ start = seprintf(start, end, "slit: %ux\n",
+ sl->e[i / sl->rowlen][i % sl->rowlen].dist);
}
start = seprintf(start, end, "\n");
return start;
@@ -934,8 +942,8 @@
return se1->dist - se2->dist;
}
-static struct Atable *parseslit(struct Atable *parent,
- char *name, uint8_t *raw, size_t rawsize)
+static struct Atable *parseslit(struct Atable *parent, char *name, uint8_t *raw,
+ size_t rawsize)
{
struct Atable *t;
uint8_t *r, *re;
@@ -989,25 +997,16 @@
return color * ncorepercol + index % ncorepercol;
}
-static char *polarity[4] = {
- "polarity/trigger like in ISA",
- "active high",
- "BOGUS POLARITY",
- "active low"
-};
+static char *polarity[4] = {"polarity/trigger like in ISA", "active high",
+ "BOGUS POLARITY", "active low"};
-static char *trigger[] = {
- "BOGUS TRIGGER",
- "edge",
- "BOGUS TRIGGER",
- "level"
-};
+static char *trigger[] = {"BOGUS TRIGGER", "edge", "BOGUS TRIGGER", "level"};
static char *printiflags(char *start, char *end, int flags)
{
- return seprintf(start, end, "[%s,%s]",
- polarity[flags & AFpmask], trigger[(flags & AFtmask) >> 2]);
+ return seprintf(start, end, "[%s,%s]", polarity[flags & AFpmask],
+ trigger[(flags & AFtmask) >> 2]);
}
static char *dumpmadt(char *start, char *end, struct Atable *apics)
@@ -1027,72 +1026,71 @@
struct Apicst *st = apic->tbl;
switch (st->type) {
- case ASlapic:
- start =
- seprintf(start, end, "\tlapic pid %d id %d\n",
- st->lapic.pid, st->lapic.id);
- break;
- case ASioapic:
- case ASiosapic:
- start =
- seprintf(start, end,
- "\tioapic id %d addr %p ibase %d\n",
- st->ioapic.id, st->ioapic.addr, st->ioapic.ibase);
- break;
- case ASintovr:
- start =
- seprintf(start, end, "\tintovr irq %d intr %d flags $%p",
- st->intovr.irq, st->intovr.intr, st->intovr.flags);
- start = printiflags(start, end, st->intovr.flags);
- start = seprintf(start, end, "\n");
- break;
- case ASnmi:
- start = seprintf(start, end, "\tnmi intr %d flags $%p\n",
- st->nmi.intr, st->nmi.flags);
- break;
- case ASlnmi:
- start =
- seprintf(start, end, "\tlnmi pid %d lint %d flags $%p\n",
- st->lnmi.pid, st->lnmi.lint, st->lnmi.flags);
- break;
- case ASlsapic:
- start =
- seprintf(start, end,
- "\tlsapic pid %d id %d eid %d puid %d puids %s\n",
- st->lsapic.pid, st->lsapic.id, st->lsapic.eid,
- st->lsapic.puid, st->lsapic.puids);
- break;
- case ASintsrc:
- start =
- seprintf(start, end,
- "\tintr type %d pid %d peid %d iosv %d intr %d %#x\n",
- st->type, st->intsrc.pid, st->intsrc.peid,
- st->intsrc.iosv, st->intsrc.intr,
- st->intsrc.flags);
- start = printiflags(start, end, st->intsrc.flags);
- start = seprintf(start, end, "\n");
- break;
- case ASlx2apic:
- start =
- seprintf(start, end, "\tlx2apic puid %d id %d\n",
- st->lx2apic.puid, st->lx2apic.id);
- break;
- case ASlx2nmi:
- start =
- seprintf(start, end, "\tlx2nmi puid %d intr %d flags $%p\n",
- st->lx2nmi.puid, st->lx2nmi.intr,
- st->lx2nmi.flags);
- break;
- default:
- start = seprintf(start, end, "\t<unknown madt entry>\n");
+ case ASlapic:
+ start = seprintf(start, end, "\tlapic pid %d id %d\n",
+ st->lapic.pid, st->lapic.id);
+ break;
+ case ASioapic:
+ case ASiosapic:
+ start = seprintf(
+ start, end, "\tioapic id %d addr %p ibase %d\n",
+ st->ioapic.id, st->ioapic.addr, st->ioapic.ibase);
+ break;
+ case ASintovr:
+ start = seprintf(
+ start, end, "\tintovr irq %d intr %d flags $%p",
+ st->intovr.irq, st->intovr.intr, st->intovr.flags);
+ start = printiflags(start, end, st->intovr.flags);
+ start = seprintf(start, end, "\n");
+ break;
+ case ASnmi:
+ start =
+ seprintf(start, end, "\tnmi intr %d flags $%p\n",
+ st->nmi.intr, st->nmi.flags);
+ break;
+ case ASlnmi:
+ start = seprintf(
+ start, end, "\tlnmi pid %d lint %d flags $%p\n",
+ st->lnmi.pid, st->lnmi.lint, st->lnmi.flags);
+ break;
+ case ASlsapic:
+ start = seprintf(
+ start, end,
+ "\tlsapic pid %d id %d eid %d puid %d puids %s\n",
+ st->lsapic.pid, st->lsapic.id, st->lsapic.eid,
+ st->lsapic.puid, st->lsapic.puids);
+ break;
+ case ASintsrc:
+ start = seprintf(start, end,
+ "\tintr type %d pid %d peid %d iosv "
+ "%d intr %d %#x\n",
+ st->type, st->intsrc.pid,
+ st->intsrc.peid, st->intsrc.iosv,
+ st->intsrc.intr, st->intsrc.flags);
+ start = printiflags(start, end, st->intsrc.flags);
+ start = seprintf(start, end, "\n");
+ break;
+ case ASlx2apic:
+ start =
+ seprintf(start, end, "\tlx2apic puid %d id %d\n",
+ st->lx2apic.puid, st->lx2apic.id);
+ break;
+ case ASlx2nmi:
+ start = seprintf(
+ start, end, "\tlx2nmi puid %d intr %d flags $%p\n",
+ st->lx2nmi.puid, st->lx2nmi.intr, st->lx2nmi.flags);
+ break;
+ default:
+ start =
+ seprintf(start, end, "\t<unknown madt entry>\n");
}
}
start = seprintf(start, end, "\n");
return start;
}
-static struct Atable *parsemadt(struct Atable *parent,
- char *name, uint8_t *p, size_t size)
+static struct Atable *parsemadt(struct Atable *parent, char *name, uint8_t *p,
+ size_t size)
{
struct Atable *t, *tt, *tail;
uint8_t *pe;
@@ -1117,100 +1115,104 @@
st = tt->tbl;
st->type = p[0];
switch (st->type) {
- case ASlapic:
- st->lapic.pid = p[2];
- st->lapic.id = p[3];
- if (l32get(p + 4) == 0) {
- kfree(tt);
- tt = NULL;
- }
- break;
- case ASioapic:
- st->ioapic.id = id = p[2];
- st->ioapic.addr = l32get(p + 4);
- st->ioapic.ibase = l32get(p + 8);
- /* ioapic overrides any ioapic entry for the same id */
- for (int i = 0; i < slice_len(&slice); i++) {
- l = ((struct Atable *)slice_get(&slice, i))->tbl;
- if (l->type == ASiosapic && l->iosapic.id == id) {
- st->ioapic = l->iosapic;
- /* we leave it linked; could be removed */
- break;
- }
- }
- break;
- case ASintovr:
- st->intovr.irq = p[3];
- st->intovr.intr = l32get(p + 4);
- st->intovr.flags = l16get(p + 8);
- break;
- case ASnmi:
- st->nmi.flags = l16get(p + 2);
- st->nmi.intr = l32get(p + 4);
- break;
- case ASlnmi:
- st->lnmi.pid = p[2];
- st->lnmi.flags = l16get(p + 3);
- st->lnmi.lint = p[5];
- break;
- case ASladdr:
- /* This is for 64 bits, perhaps we should not
- * honor it on 32 bits.
- */
- mt->lapicpa = l64get(p + 8);
- break;
- case ASiosapic:
- id = st->iosapic.id = p[2];
- st->iosapic.ibase = l32get(p + 4);
- st->iosapic.addr = l64get(p + 8);
- /* iosapic overrides any ioapic entry for the same id */
- for (int i = 0; i < slice_len(&slice); i++) {
- l = ((struct Atable*)slice_get(&slice, i))->tbl;
- if (l->type == ASioapic && l->ioapic.id == id) {
- l->ioapic = st->iosapic;
- kfree(tt);
- tt = NULL;
- break;
- }
- }
- break;
- case ASlsapic:
- st->lsapic.pid = p[2];
- st->lsapic.id = p[3];
- st->lsapic.eid = p[4];
- st->lsapic.puid = l32get(p + 12);
- if (l32get(p + 8) == 0) {
- kfree(tt);
- tt = NULL;
- } else
- kstrdup(&st->lsapic.puids, (char *)p + 16);
- break;
- case ASintsrc:
- st->intsrc.flags = l16get(p + 2);
- st->type = p[4];
- st->intsrc.pid = p[5];
- st->intsrc.peid = p[6];
- st->intsrc.iosv = p[7];
- st->intsrc.intr = l32get(p + 8);
- st->intsrc.any = l32get(p + 12);
- break;
- case ASlx2apic:
- st->lx2apic.id = l32get(p + 4);
- st->lx2apic.puid = l32get(p + 12);
- if (l32get(p + 8) == 0) {
- kfree(tt);
- tt = NULL;
- }
- break;
- case ASlx2nmi:
- st->lx2nmi.flags = l16get(p + 2);
- st->lx2nmi.puid = l32get(p + 4);
- st->lx2nmi.intr = p[8];
- break;
- default:
- printd("unknown APIC structure\n");
+ case ASlapic:
+ st->lapic.pid = p[2];
+ st->lapic.id = p[3];
+ if (l32get(p + 4) == 0) {
kfree(tt);
tt = NULL;
+ }
+ break;
+ case ASioapic:
+ st->ioapic.id = id = p[2];
+ st->ioapic.addr = l32get(p + 4);
+ st->ioapic.ibase = l32get(p + 8);
+ /* ioapic overrides any ioapic entry for the same id */
+ for (int i = 0; i < slice_len(&slice); i++) {
+ l = ((struct Atable *)slice_get(&slice, i))
+ ->tbl;
+ if (l->type == ASiosapic &&
+ l->iosapic.id == id) {
+ st->ioapic = l->iosapic;
+ /* we leave it linked; could be removed
+ */
+ break;
+ }
+ }
+ break;
+ case ASintovr:
+ st->intovr.irq = p[3];
+ st->intovr.intr = l32get(p + 4);
+ st->intovr.flags = l16get(p + 8);
+ break;
+ case ASnmi:
+ st->nmi.flags = l16get(p + 2);
+ st->nmi.intr = l32get(p + 4);
+ break;
+ case ASlnmi:
+ st->lnmi.pid = p[2];
+ st->lnmi.flags = l16get(p + 3);
+ st->lnmi.lint = p[5];
+ break;
+ case ASladdr:
+ /* This is for 64 bits, perhaps we should not
+ * honor it on 32 bits.
+ */
+ mt->lapicpa = l64get(p + 8);
+ break;
+ case ASiosapic:
+ id = st->iosapic.id = p[2];
+ st->iosapic.ibase = l32get(p + 4);
+ st->iosapic.addr = l64get(p + 8);
+ /* iosapic overrides any ioapic entry for the same id */
+ for (int i = 0; i < slice_len(&slice); i++) {
+ l = ((struct Atable *)slice_get(&slice, i))
+ ->tbl;
+ if (l->type == ASioapic && l->ioapic.id == id) {
+ l->ioapic = st->iosapic;
+ kfree(tt);
+ tt = NULL;
+ break;
+ }
+ }
+ break;
+ case ASlsapic:
+ st->lsapic.pid = p[2];
+ st->lsapic.id = p[3];
+ st->lsapic.eid = p[4];
+ st->lsapic.puid = l32get(p + 12);
+ if (l32get(p + 8) == 0) {
+ kfree(tt);
+ tt = NULL;
+ } else
+ kstrdup(&st->lsapic.puids, (char *)p + 16);
+ break;
+ case ASintsrc:
+ st->intsrc.flags = l16get(p + 2);
+ st->type = p[4];
+ st->intsrc.pid = p[5];
+ st->intsrc.peid = p[6];
+ st->intsrc.iosv = p[7];
+ st->intsrc.intr = l32get(p + 8);
+ st->intsrc.any = l32get(p + 12);
+ break;
+ case ASlx2apic:
+ st->lx2apic.id = l32get(p + 4);
+ st->lx2apic.puid = l32get(p + 12);
+ if (l32get(p + 8) == 0) {
+ kfree(tt);
+ tt = NULL;
+ }
+ break;
+ case ASlx2nmi:
+ st->lx2nmi.flags = l16get(p + 2);
+ st->lx2nmi.puid = l32get(p + 4);
+ st->lx2nmi.intr = p[8];
+ break;
+ default:
+ printd("unknown APIC structure\n");
+ kfree(tt);
+ tt = NULL;
}
if (tt != NULL) {
finatable_nochildren(tt);
@@ -1222,8 +1224,8 @@
return apics;
}
-static struct Atable *parsedmar(struct Atable *parent,
- char *name, uint8_t *raw, size_t rawsize)
+static struct Atable *parsedmar(struct Atable *parent, char *name, uint8_t *raw,
+ size_t rawsize)
{
struct Atable *t, *tt;
int i;
@@ -1238,8 +1240,8 @@
/* count the entries */
for (nentry = 0, off = 48; off < rawsize; nentry++) {
dslen = l16get(raw + off + 2);
- printk("acpi DMAR: entry %d is addr %p (0x%x/0x%x)\n",
- nentry, raw + off, l16get(raw + off), dslen);
+ printk("acpi DMAR: entry %d is addr %p (0x%x/0x%x)\n", nentry,
+ raw + off, l16get(raw + off), dslen);
off = off + dslen;
}
printk("DMAR: %d entries\n", nentry);
@@ -1267,12 +1269,12 @@
nscope = 0;
for (int o = off + 16; o < (off + dslen); o += dhlen) {
nscope++;
- dhlen = *(raw + o + 1); // Single byte length.
+ dhlen = *(raw + o + 1); // Single byte length.
npath += ((dhlen - 6) / 2);
}
tt = mkatable(t, DRHD, buf, raw + off, dslen,
sizeof(struct Drhd) + 2 * npath +
- nscope * sizeof(struct DevScope));
+ nscope * sizeof(struct DevScope));
flags = *(raw + off + 4);
drhd = tt->tbl;
drhd->all = flags & 1;
@@ -1280,8 +1282,8 @@
drhd->rba = l64get(raw + off + 8);
drhd->nscope = nscope;
drhd->scopes = (void *)drhd + sizeof(struct Drhd);
- pathp = (void *)drhd +
- sizeof(struct Drhd) + nscope * sizeof(struct DevScope);
+ pathp = (void *)drhd + sizeof(struct Drhd) +
+ nscope * sizeof(struct DevScope);
for (int i = 0, o = off + 16; i < nscope; i++) {
struct DevScope *ds = &drhd->scopes[i];
@@ -1291,8 +1293,8 @@
ds->npath = (dhlen - 6) / 2;
ds->paths = pathp;
for (int j = 0; j < ds->npath; j++)
- ds->paths[j] = l16get(raw + o + 6 + 2*j);
- pathp += 2*ds->npath;
+ ds->paths[j] = l16get(raw + o + 6 + 2 * j);
+ pathp += 2 * ds->npath;
o += dhlen;
}
/*
@@ -1312,8 +1314,8 @@
/*
* Map the table and keep it there.
*/
-static struct Atable *parsessdt(struct Atable *parent,
- char *name, uint8_t *raw, size_t size)
+static struct Atable *parsessdt(struct Atable *parent, char *name, uint8_t *raw,
+ size_t size)
{
struct Atable *t;
struct Sdthdr *h;
@@ -1360,7 +1362,7 @@
uint8_t *p;
int i, n;
- p = (uint8_t *)t->tbl; /* include header */
+ p = (uint8_t *)t->tbl; /* include header */
n = t->rawsize;
s = seprintf(s, e, "%s @ %#p\n", t->name, p);
for (i = 0; i < n; i++) {
@@ -1406,20 +1408,14 @@
*/
struct Parser {
char *sig;
- struct Atable *(*parse)(struct Atable *parent,
- char *name, uint8_t *raw, size_t rawsize);
+ struct Atable *(*parse)(struct Atable *parent, char *name, uint8_t *raw,
+ size_t rawsize);
};
-
static struct Parser ptable[] = {
- {"FACP", parsefadt},
- {"APIC", parsemadt},
- {"DMAR", parsedmar},
- {"SRAT", parsesrat},
- {"SLIT", parseslit},
- {"MSCT", parsemsct},
- {"SSDT", parsessdt},
- {"HPET", parsehpet},
+ {"FACP", parsefadt}, {"APIC", parsemadt}, {"DMAR", parsedmar},
+ {"SRAT", parsesrat}, {"SLIT", parseslit}, {"MSCT", parsemsct},
+ {"SSDT", parsessdt}, {"HPET", parsehpet},
};
/*
@@ -1452,8 +1448,10 @@
continue;
printd("acpi: %s addr %#p\n", tsig, sdt);
for (int j = 0; j < ARRAY_SIZE(ptable); j++) {
- if (memcmp(sdt->sig, ptable[j].sig, sizeof(sdt->sig)) == 0) {
- table = ptable[j].parse(root, ptable[j].sig, (void *)sdt, l);
+ if (memcmp(sdt->sig, ptable[j].sig, sizeof(sdt->sig)) ==
+ 0) {
+ table = ptable[j].parse(root, ptable[j].sig,
+ (void *)sdt, l);
if (table != NULL)
slice_append(&slice, table);
break;
@@ -1497,19 +1495,22 @@
root = mkatable(NULL, XSDT, devname(), NULL, 0, sizeof(struct Xsdt));
root->parent = root;
- printd("/* RSDP */ struct Rsdp = {%08c, %x, %06c, %x, %p, %d, %p, %x}\n",
- rsd->signature, rsd->rchecksum, rsd->oemid, rsd->revision,
- *(uint32_t *)rsd->raddr, *(uint32_t *)rsd->length,
- *(uint32_t *)rsd->xaddr, rsd->xchecksum);
+ printd(
+ "/* RSDP */ struct Rsdp = {%08c, %x, %06c, %x, %p, %d, %p, %x}\n",
+ rsd->signature, rsd->rchecksum, rsd->oemid, rsd->revision,
+ *(uint32_t *)rsd->raddr, *(uint32_t *)rsd->length,
+ *(uint32_t *)rsd->xaddr, rsd->xchecksum);
printd("acpi: RSD PTR@ %#p, physaddr $%p length %ud %#llux rev %d\n",
- rsd, l32get(rsd->raddr), l32get(rsd->length),
- l64get(rsd->xaddr), rsd->revision);
+ rsd, l32get(rsd->raddr), l32get(rsd->length), l64get(rsd->xaddr),
+ rsd->revision);
if (rsd->revision >= 2) {
cksum = sdtchecksum(rsd, 36);
if (cksum != 0) {
- printk("acpi: bad RSD checksum %d, 64 bit parser aborted\n", cksum);
+ printk("acpi: bad RSD checksum %d, 64 bit parser "
+ "aborted\n",
+ cksum);
return;
}
sdtpa = l64get(rsd->xaddr);
@@ -1517,7 +1518,9 @@
} else {
cksum = sdtchecksum(rsd, 20);
if (cksum != 0) {
- printk("acpi: bad RSD checksum %d, 32 bit parser aborted\n", cksum);
+ printk("acpi: bad RSD checksum %d, 32 bit parser "
+ "aborted\n",
+ cksum);
return;
}
sdtpa = l32get(rsd->raddr);
@@ -1533,18 +1536,18 @@
printk("acpi: sdtmap failed\n");
return;
}
- if ((xsdt->p[0] != 'R' && xsdt->p[0] != 'X')
- || memcmp(xsdt->p + 1, "SDT", 3) != 0) {
- printd("acpi: xsdt sig: %c%c%c%c\n",
- xsdt->p[0], xsdt->p[1], xsdt->p[2], xsdt->p[3]);
+ if ((xsdt->p[0] != 'R' && xsdt->p[0] != 'X') ||
+ memcmp(xsdt->p + 1, "SDT", 3) != 0) {
+ printd("acpi: xsdt sig: %c%c%c%c\n", xsdt->p[0], xsdt->p[1],
+ xsdt->p[2], xsdt->p[3]);
xsdt = NULL;
return;
}
xsdt->asize = asize;
printd("acpi: XSDT %#p\n", xsdt);
parsexsdt(root);
- atableindex = kreallocarray(NULL, lastpath, sizeof(struct Atable *),
- MEM_WAIT);
+ atableindex =
+ kreallocarray(NULL, lastpath, sizeof(struct Atable *), MEM_WAIT);
assert(atableindex != NULL);
makeindex(root);
}
@@ -1558,10 +1561,11 @@
physaddr_t sdt_pa;
struct Sdthdr *sdt;
- ptr_tbl = (uint8_t*)xsdt + sizeof(struct Sdthdr);
+ ptr_tbl = (uint8_t *)xsdt + sizeof(struct Sdthdr);
ptr_tbl_len = l32get(xsdt->length) - sizeof(struct Sdthdr);
for (int i = 0; i < ptr_tbl_len; i += addr_size) {
- sdt_pa = (addr_size == 8) ? l64get(ptr_tbl + i) : l32get(ptr_tbl + i);
+ sdt_pa = (addr_size == 8) ? l64get(ptr_tbl + i)
+ : l32get(ptr_tbl + i);
sdt = KADDR_NOCHECK(sdt_pa);
if (memcmp(sdt->sig, sig, sizeof(sdt->sig)) == 0)
return sdt;
@@ -1576,7 +1580,7 @@
size_t entry_len;
int nr_cores = 0;
- p = (uint8_t*)madt;
+ p = (uint8_t *)madt;
madt_end = p + l32get(madt->length);
for (p += 44; p < madt_end; p += entry_len) {
entry_len = p[1];
@@ -1611,11 +1615,11 @@
}
xsdt = KADDR_NOCHECK(sdtpa);
- xsdt_buf = (uint8_t*)xsdt;
- if ((xsdt_buf[0] != 'R' && xsdt_buf[0] != 'X')
- || memcmp(xsdt_buf + 1, "SDT", 3) != 0) {
- panic("acpi: xsdt sig: %c%c%c%c\n",
- xsdt_buf[0], xsdt_buf[1], xsdt_buf[2], xsdt_buf[3]);
+ xsdt_buf = (uint8_t *)xsdt;
+ if ((xsdt_buf[0] != 'R' && xsdt_buf[0] != 'X') ||
+ memcmp(xsdt_buf + 1, "SDT", 3) != 0) {
+ panic("acpi: xsdt sig: %c%c%c%c\n", xsdt_buf[0], xsdt_buf[1],
+ xsdt_buf[2], xsdt_buf[3]);
}
madt = xsdt_find_tbl(xsdt, "APIC", asize);
assert(madt);
@@ -1646,14 +1650,14 @@
}
static int acpigen(struct chan *c, char *name, struct dirtab *tab, int ntab,
- int i, struct dir *dp)
+ int i, struct dir *dp)
{
struct Atable *a = genatable(c);
if (i == DEVDOTDOT) {
assert((c->qid.path & QIndexMask) == Qdir);
- devdir(c, a->parent->qid, a->parent->name, 0, eve.name, DMDIR | 0555,
- dp);
+ devdir(c, a->parent->qid, a->parent->name, 0, eve.name,
+ DMDIR | 0555, dp);
return 1;
}
return devgen(c, name, a->cdirs, a->nchildren + NQtypes, i, dp);
@@ -1664,8 +1668,8 @@
*/
static void dumpxsdt(void)
{
- printk("xsdt: len = %lu, asize = %lu, p = %p\n",
- xsdt->len, xsdt->asize, xsdt->p);
+ printk("xsdt: len = %lu, asize = %lu, p = %p\n", xsdt->len, xsdt->asize,
+ xsdt->p);
}
static char *dumpGas(char *start, char *end, char *prefix, struct Gas *g)
@@ -1673,34 +1677,32 @@
start = seprintf(start, end, "%s", prefix);
switch (g->spc) {
- case Rsysmem:
- case Rsysio:
- case Rembed:
- case Rsmbus:
- case Rcmos:
- case Rpcibar:
- case Ripmi:
- start = seprintf(start, end, "[%s ", regnames[g->spc]);
- break;
- case Rpcicfg:
- start = seprintf(start, end, "[pci ");
- start =
- seprintf(start, end, "dev %#p ",
- (uint32_t)(g->addr >> 32) & 0xFFFF);
- start =
- seprintf(start, end, "fn %#p ",
- (uint32_t)(g->addr & 0xFFFF0000) >> 16);
- start =
- seprintf(start, end, "adr %#p ", (uint32_t)(g->addr & 0xFFFF));
- break;
- case Rfixedhw:
- start = seprintf(start, end, "[hw ");
- break;
- default:
- start = seprintf(start, end, "[spc=%#p ", g->spc);
+ case Rsysmem:
+ case Rsysio:
+ case Rembed:
+ case Rsmbus:
+ case Rcmos:
+ case Rpcibar:
+ case Ripmi:
+ start = seprintf(start, end, "[%s ", regnames[g->spc]);
+ break;
+ case Rpcicfg:
+ start = seprintf(start, end, "[pci ");
+ start = seprintf(start, end, "dev %#p ",
+ (uint32_t)(g->addr >> 32) & 0xFFFF);
+ start = seprintf(start, end, "fn %#p ",
+ (uint32_t)(g->addr & 0xFFFF0000) >> 16);
+ start = seprintf(start, end, "adr %#p ",
+ (uint32_t)(g->addr & 0xFFFF));
+ break;
+ case Rfixedhw:
+ start = seprintf(start, end, "[hw ");
+ break;
+ default:
+ start = seprintf(start, end, "[spc=%#p ", g->spc);
}
- start = seprintf(start, end, "off %d len %d addr %#p sz%d]",
- g->off, g->len, g->addr, g->accsz);
+ start = seprintf(start, end, "off %d len %d addr %#p sz%d]", g->off,
+ g->len, g->addr, g->accsz);
start = seprintf(start, end, "\n");
return start;
}
@@ -1711,26 +1713,26 @@
r = 0;
switch (sz) {
- case 1:
- if (ra != 0)
- r |= inb(ra);
- if (rb != 0)
- r |= inb(rb);
- break;
- case 2:
- if (ra != 0)
- r |= inw(ra);
- if (rb != 0)
- r |= inw(rb);
- break;
- case 4:
- if (ra != 0)
- r |= inl(ra);
- if (rb != 0)
- r |= inl(rb);
- break;
- default:
- printd("getbanked: wrong size\n");
+ case 1:
+ if (ra != 0)
+ r |= inb(ra);
+ if (rb != 0)
+ r |= inb(rb);
+ break;
+ case 2:
+ if (ra != 0)
+ r |= inw(ra);
+ if (rb != 0)
+ r |= inw(rb);
+ break;
+ case 4:
+ if (ra != 0)
+ r |= inl(ra);
+ if (rb != 0)
+ r |= inl(rb);
+ break;
+ default:
+ printd("getbanked: wrong size\n");
}
return r;
}
@@ -1741,26 +1743,26 @@
r = -1;
switch (sz) {
- case 1:
- if (ra != 0)
- outb(ra, v);
- if (rb != 0)
- outb(rb, v);
- break;
- case 2:
- if (ra != 0)
- outw(ra, v);
- if (rb != 0)
- outw(rb, v);
- break;
- case 4:
- if (ra != 0)
- outl(ra, v);
- if (rb != 0)
- outl(rb, v);
- break;
- default:
- printd("setbanked: wrong size\n");
+ case 1:
+ if (ra != 0)
+ outb(ra, v);
+ if (rb != 0)
+ outb(rb, v);
+ break;
+ case 2:
+ if (ra != 0)
+ outw(ra, v);
+ if (rb != 0)
+ outw(rb, v);
+ break;
+ case 4:
+ if (ra != 0)
+ outl(ra, v);
+ if (rb != 0)
+ outl(rb, v);
+ break;
+ default:
+ printd("setbanked: wrong size\n");
}
return r;
}
@@ -1780,7 +1782,8 @@
static unsigned int getpm1sts(void)
{
assert(fadt != NULL);
- return getbanked(fadt->pm1aevtblk, fadt->pm1bevtblk, fadt->pm1evtlen / 2);
+ return getbanked(fadt->pm1aevtblk, fadt->pm1bevtblk,
+ fadt->pm1evtlen / 2);
}
static unsigned int getpm1en(void)
@@ -1947,7 +1950,7 @@
}
static struct walkqid *acpiwalk(struct chan *c, struct chan *nc, char **name,
- unsigned int nname)
+ unsigned int nname)
{
/*
* Note that devwalk hard-codes a test against the location of 'devgen',
@@ -2118,8 +2121,7 @@
struct {
char *(*pretty)(struct Atable *atbl, char *start, char *end, void *arg);
-} acpisw[NACPITBLS] = {
-};
+} acpisw[NACPITBLS] = {};
static char *pretty(struct Atable *atbl, char *start, char *end, void *arg)
{
@@ -2143,21 +2145,21 @@
}
struct dev acpidevtab __devtab = {
- .name = "acpi",
+ .name = "acpi",
- .reset = devreset,
- .init = devinit,
- .shutdown = devshutdown,
- .attach = acpiattach,
- .walk = acpiwalk,
- .stat = acpistat,
- .open = acpiopen,
- .create = devcreate,
- .close = acpiclose,
- .read = acpiread,
- .bread = devbread,
- .write = acpiwrite,
- .bwrite = devbwrite,
- .remove = devremove,
- .wstat = devwstat,
+ .reset = devreset,
+ .init = devinit,
+ .shutdown = devshutdown,
+ .attach = acpiattach,
+ .walk = acpiwalk,
+ .stat = acpistat,
+ .open = acpiopen,
+ .create = devcreate,
+ .close = acpiclose,
+ .read = acpiread,
+ .bread = devbread,
+ .write = acpiwrite,
+ .bwrite = devbwrite,
+ .remove = devremove,
+ .wstat = devwstat,
};
diff --git a/kern/drivers/dev/alarm.c b/kern/drivers/dev/alarm.c
index ccde970..2186af2 100644
--- a/kern/drivers/dev/alarm.c
+++ b/kern/drivers/dev/alarm.c
@@ -37,22 +37,22 @@
*
* Notes on refcnting (the trickier parts here):
* - the proc_alarms have counted references to their proc
- * proc won't free til all alarms are closed, which is fine. we close
- * all files in destroy. if a proc drops a chan in srv, the proc will stay
- * alive because the alarm is alive - til that chan is closed (srvremove)
+ * proc won't free til all alarms are closed, which is fine. we close
+ * all files in destroy. if a proc drops a chan in srv, the proc will stay
+ * alive because the alarm is alive - til that chan is closed (srvremove)
*
- * other shady ways to keep a chan alive: cd to it! if it is ., we'd
- * keep a ref around. however, only alarmdir *file* grab refs, not
- * directories.
+ * other shady ways to keep a chan alive: cd to it! if it is ., we'd
+ * keep a ref around. however, only alarmdir *file* grab refs, not
+ * directories.
*
* - proc_alarms are kref'd, since there can be multiple chans per alarm
- * the only thing that keeps an alarm alive is a chan on a CTL or TIMER (or
- * other file). when you cloned, you got back an open CTL, which keeps the
- * alarm (and the dir) alive.
+ * the only thing that keeps an alarm alive is a chan on a CTL or TIMER (or
+ * other file). when you cloned, you got back an open CTL, which keeps the
+ * alarm (and the dir) alive.
*
- * we need to be careful generating krefs, in case alarms are concurrently
- * released and removed from the lists. just like with procs and pid2proc,
- * we need to sync with the source of the kref. */
+ * we need to be careful generating krefs, in case alarms are concurrently
+ * released and removed from the lists. just like with procs and pid2proc,
+ * we need to sync with the source of the kref. */
#include <kmalloc.h>
#include <string.h>
@@ -76,13 +76,13 @@
}
/* qid path types */
-#define Qtopdir 1
-#define Qclone 2
-#define Qalarmdir 3
-#define Qctl 4
-#define Qtimer 5 /* Qctl + 1 */
-#define Qperiod 6
-#define Qcount 7
+#define Qtopdir 1
+#define Qclone 2
+#define Qalarmdir 3
+#define Qctl 4
+#define Qtimer 5 /* Qctl + 1 */
+#define Qperiod 6
+#define Qcount 7
/* This paddr/kaddr is a bit dangerous. it'll work so long as we don't need all
* 64 bits for a physical address (48 is the current norm on x86_64). */
@@ -96,6 +96,7 @@
{
struct proc_alarm *a = container_of(kref, struct proc_alarm, kref);
struct proc *p = a->proc;
+
assert(p);
spin_lock(&p->alarmset.lock);
TAILQ_REMOVE(&p->alarmset.list, a, link);
@@ -116,7 +117,8 @@
static void proc_alarm_handler(struct alarm_waiter *a_waiter)
{
- struct proc_alarm *a = container_of(a_waiter, struct proc_alarm, a_waiter);
+ struct proc_alarm *a = container_of(a_waiter, struct proc_alarm,
+ a_waiter);
cv_lock(&a->cv);
a->count++;
@@ -142,116 +144,120 @@
p->alarmset.id_counter = 0;
}
-static int alarmgen(struct chan *c, char *entry_name,
- struct dirtab *unused, int unused_nr_dirtab,
- int s, struct dir *dp)
+static int alarmgen(struct chan *c, char *entry_name, struct dirtab *unused,
+ int unused_nr_dirtab, int s, struct dir *dp)
{
struct qid q;
struct proc_alarm *a_i;
struct proc *p = current;
- /* Whether we're in one dir or at the top, .. still takes us to the top. */
+
+ /* Whether we're in one dir or at the top, .. still takes us to the top.
+ */
if (s == DEVDOTDOT) {
mkqid(&q, Qtopdir, 0, QTDIR);
devdir(c, q, devname(), 0, eve.name, 0555, dp);
return 1;
}
switch (TYPE(c->qid)) {
- case Qtopdir:
- /* Generate elements for the top level dir. We support a clone and
- * alarm dirs at the top level */
- if (s == 0) {
- mkqid(&q, Qclone, 0, QTFILE);
- devdir(c, q, "clone", 0, eve.name, 0666, dp);
- return 1;
- }
- s--; /* 1 -> 0th element, 2 -> 1st element, etc */
- /* Gets the s-th element (0 index)
- *
- * I would like to take advantage of the state machine and our
- * previous answer to get the sth element of the list. We can get
- * at our previous run of gen from dp (struct dir), and use that to
- * get the next item. I'd like to do something like:
- *
- * if (dp->qid.path >> ADDR_SHIFT)
- * a_i = TAILQ_NEXT(QID2A(dp->qid), link);
- *
- * Dev would give us a 0'd dp path on the first run, so if we have a
- * path, we know we're on an iterative run. However, the problem is
- * that we could have lost the element dp refers to (QID2A(dp->qid))
- * since our previous run, so we can't even access that memory to
- * check for refcnts or anything. We need a new model for how gen
- * works (probably a gen_start and gen_stop devop, passed as
- * parameters to devwalk), so that we can have some invariants
- * between gen runs.
- *
- * Til then, we're stuck with arrays like in #ip (though we can use
- * Linux style fdsets) or lousy O(n^2) linked lists (like #srv).
- *
- * Note that we won't always start a gen loop with s == 0
- * (devdirread, for instance) */
- spin_lock(&p->alarmset.lock);
- TAILQ_FOREACH(a_i, &p->alarmset.list, link) {
- if (s-- == 0)
- break;
- }
- /* As soon as we unlock, someone could free a_i */
- if (!a_i) {
- spin_unlock(&p->alarmset.lock);
- return -1;
- }
- snprintf(get_cur_genbuf(), GENBUF_SZ, "a%d", a_i->id);
- mkqid(&q, QID(a_i, Qalarmdir), 0, QTDIR);
- devdir(c, q, get_cur_genbuf(), 0, eve.name, 0555, dp);
+ case Qtopdir:
+ /* Generate elements for the top level dir. We support a clone
+ * and alarm dirs at the top level */
+ if (s == 0) {
+ mkqid(&q, Qclone, 0, QTFILE);
+ devdir(c, q, "clone", 0, eve.name, 0666, dp);
+ return 1;
+ }
+ s--; /* 1 -> 0th element, 2 -> 1st element, etc */
+ /* Gets the s-th element (0 index)
+ *
+ * I would like to take advantage of the state machine and our
+ * previous answer to get the sth element of the list. We can
+ * get at our previous run of gen from dp (struct dir), and use
+ * that to get the next item. I'd like to do something like:
+ *
+ * if (dp->qid.path >> ADDR_SHIFT)
+ * a_i = TAILQ_NEXT(QID2A(dp->qid), link);
+ *
+ * Dev would give us a 0'd dp path on the first run, so if we
+ * have a path, we know we're on an iterative run. However, the
+ * problem is that we could have lost the element dp refers to
+ * (QID2A(dp->qid)) since our previous run, so we can't even
+ * access that memory to check for refcnts or anything. We need
+ * a new model for how gen works (probably a gen_start and
+ * gen_stop devop, passed as parameters to devwalk), so that we
+ * can have some invariants between gen runs.
+ *
+ * Til then, we're stuck with arrays like in #ip (though we can
+ * use Linux style fdsets) or lousy O(n^2) linked lists (like
+ * #srv).
+ *
+ * Note that we won't always start a gen loop with s == 0
+ * (devdirread, for instance) */
+ spin_lock(&p->alarmset.lock);
+ TAILQ_FOREACH(a_i, &p->alarmset.list, link) {
+ if (s-- == 0)
+ break;
+ }
+ /* As soon as we unlock, someone could free a_i */
+ if (!a_i) {
spin_unlock(&p->alarmset.lock);
- return 1;
- case Qalarmdir:
- /* Gen the contents of the alarm dirs */
- s += Qctl; /* first time through, start on Qctl */
- switch (s) {
- case Qctl:
- mkqid(&q, QID(QID2A(c->qid), Qctl), 0, QTFILE);
- devdir(c, q, "ctl", 0, eve.name, 0666, dp);
- return 1;
- case Qtimer:
- mkqid(&q, QID(QID2A(c->qid), Qtimer), 0, QTFILE);
- devdir(c, q, "timer", 0, eve.name, 0666, dp);
- return 1;
- case Qperiod:
- mkqid(&q, QID(QID2A(c->qid), Qperiod), 0, QTFILE);
- devdir(c, q, "period", 0, eve.name, 0666, dp);
- return 1;
- case Qcount:
- mkqid(&q, QID(QID2A(c->qid), Qcount), 0, QTFILE);
- devdir(c, q, "count", 0, eve.name, 0666, dp);
- return 1;
- }
return -1;
- /* Need to also provide a direct hit for Qclone and all other files
- * (at all levels of the hierarchy). Every file is both generated
- * (via the s increments in their respective directories) and
- * directly gen-able. devstat() will call gen with a specific path
- * in the qid. In these cases, we make a dir for whatever they are
- * asking for. Note the qid stays the same. I think this is what
- * the old plan9 comments above devgen were talking about for (ii).
- *
- * We don't need to do this for the directories - devstat will look
- * for the a directory by path and fail. Then it will manually
- * build the stat output (check the -1 case in devstat). */
- case Qclone:
- devdir(c, c->qid, "clone", 0, eve.name, 0666, dp);
- return 1;
+ }
+ snprintf(get_cur_genbuf(), GENBUF_SZ, "a%d", a_i->id);
+ mkqid(&q, QID(a_i, Qalarmdir), 0, QTDIR);
+ devdir(c, q, get_cur_genbuf(), 0, eve.name, 0555, dp);
+ spin_unlock(&p->alarmset.lock);
+ return 1;
+ case Qalarmdir:
+ /* Gen the contents of the alarm dirs */
+ s += Qctl; /* first time through, start on Qctl */
+ switch (s) {
case Qctl:
- devdir(c, c->qid, "ctl", 0, eve.name, 0666, dp);
+ mkqid(&q, QID(QID2A(c->qid), Qctl), 0, QTFILE);
+ devdir(c, q, "ctl", 0, eve.name, 0666, dp);
return 1;
case Qtimer:
- devdir(c, c->qid, "timer", 0, eve.name, 0666, dp);
+ mkqid(&q, QID(QID2A(c->qid), Qtimer), 0, QTFILE);
+ devdir(c, q, "timer", 0, eve.name, 0666, dp);
return 1;
case Qperiod:
- devdir(c, c->qid, "period", 0, eve.name, 0666, dp);
+ mkqid(&q, QID(QID2A(c->qid), Qperiod), 0, QTFILE);
+ devdir(c, q, "period", 0, eve.name, 0666, dp);
return 1;
case Qcount:
- devdir(c, c->qid, "count", 0, eve.name, 0666, dp);
+ mkqid(&q, QID(QID2A(c->qid), Qcount), 0, QTFILE);
+ devdir(c, q, "count", 0, eve.name, 0666, dp);
return 1;
+ }
+ return -1;
+ /* Need to also provide a direct hit for Qclone and all other
+ * files (at all levels of the hierarchy). Every file is both
+ * generated (via the s increments in their respective
+ * directories) and directly gen-able. devstat() will call gen
+ * with a specific path in the qid. In these cases, we make a
+ * dir for whatever they are asking for. Note the qid stays the
+ * same. I think this is what the old plan9 comments above
+ * devgen were talking about for (ii).
+ *
+ * We don't need to do this for the directories - devstat will
+ * look for the a directory by path and fail. Then it will
+ * manually build the stat output (check the -1 case in
+ * devstat). */
+ case Qclone:
+ devdir(c, c->qid, "clone", 0, eve.name, 0666, dp);
+ return 1;
+ case Qctl:
+ devdir(c, c->qid, "ctl", 0, eve.name, 0666, dp);
+ return 1;
+ case Qtimer:
+ devdir(c, c->qid, "timer", 0, eve.name, 0666, dp);
+ return 1;
+ case Qperiod:
+ devdir(c, c->qid, "period", 0, eve.name, 0666, dp);
+ return 1;
+ case Qcount:
+ devdir(c, c->qid, "count", 0, eve.name, 0666, dp);
+ return 1;
}
return -1;
}
@@ -263,12 +269,13 @@
static struct chan *alarmattach(char *spec)
{
struct chan *c = devattach(devname(), spec);
+
mkqid(&c->qid, Qtopdir, 0, QTDIR);
return c;
}
static struct walkqid *alarmwalk(struct chan *c, struct chan *nc, char **name,
- unsigned int nname)
+ unsigned int nname)
{
return devwalk(c, nc, name, nname, 0, 0, alarmgen);
}
@@ -285,57 +292,60 @@
struct proc *p = current;
struct proc_alarm *a, *a_i;
switch (TYPE(c->qid)) {
- case Qtopdir:
- case Qalarmdir:
- if (omode & O_REMCLO)
- error(EPERM, ERROR_FIXME);
- if (omode & O_WRITE)
- error(EISDIR, ERROR_FIXME);
- break;
- case Qclone:
- a = kzmalloc(sizeof(struct proc_alarm), MEM_WAIT);
- kref_init(&a->kref, alarm_release, 1);
- SLIST_INIT(&a->fd_taps);
- cv_init(&a->cv);
- qlock_init(&a->qlock);
- init_awaiter(&a->a_waiter, proc_alarm_handler);
- spin_lock(&p->alarmset.lock);
- a->id = p->alarmset.id_counter++;
- proc_incref(p, 1);
- a->proc = p;
- TAILQ_INSERT_TAIL(&p->alarmset.list, a, link);
- spin_unlock(&p->alarmset.lock);
- mkqid(&c->qid, QID(a, Qctl), 0, QTFILE);
- break;
- case Qctl:
- case Qtimer:
- case Qperiod:
- case Qcount:
- /* the purpose of opening is to hold a kref on the proc_alarm */
- a = QID2A(c->qid);
- assert(a);
- /* this isn't a valid pointer yet, since our chan doesn't have a
- * ref. since the time that walk gave our chan the qid, the chan
- * could have been closed, and the alarm decref'd and freed. the
- * qid is essentially an uncounted reference, and we need to go to
- * the source to attempt to get a real ref. Unfortunately, this is
- * another scan of the list, same as devsrv. */
- spin_lock(&p->alarmset.lock);
- TAILQ_FOREACH(a_i, &p->alarmset.list, link) {
- if (a_i == a) {
- assert(a->proc == current);
- /* it's still possible we're not getting the ref, racing
- * with the release method */
- if (!kref_get_not_zero(&a->kref, 1)) {
- a_i = 0; /* lost the race, will error out later */
- }
- break;
+ case Qtopdir:
+ case Qalarmdir:
+ if (omode & O_REMCLO)
+ error(EPERM, ERROR_FIXME);
+ if (omode & O_WRITE)
+ error(EISDIR, ERROR_FIXME);
+ break;
+ case Qclone:
+ a = kzmalloc(sizeof(struct proc_alarm), MEM_WAIT);
+ kref_init(&a->kref, alarm_release, 1);
+ SLIST_INIT(&a->fd_taps);
+ cv_init(&a->cv);
+ qlock_init(&a->qlock);
+ init_awaiter(&a->a_waiter, proc_alarm_handler);
+ spin_lock(&p->alarmset.lock);
+ a->id = p->alarmset.id_counter++;
+ proc_incref(p, 1);
+ a->proc = p;
+ TAILQ_INSERT_TAIL(&p->alarmset.list, a, link);
+ spin_unlock(&p->alarmset.lock);
+ mkqid(&c->qid, QID(a, Qctl), 0, QTFILE);
+ break;
+ case Qctl:
+ case Qtimer:
+ case Qperiod:
+ case Qcount:
+ /* the purpose of opening is to hold a kref on the proc_alarm */
+ a = QID2A(c->qid);
+ assert(a);
+ /* this isn't a valid pointer yet, since our chan doesn't have a
+ * ref. since the time that walk gave our chan the qid, the
+ * chan could have been closed, and the alarm decref'd and
+ * freed. the qid is essentially an uncounted reference, and we
+ * need to go to the source to attempt to get a real ref.
+ * Unfortunately, this is another scan of the list, same as
+ * devsrv. */
+ spin_lock(&p->alarmset.lock);
+ TAILQ_FOREACH(a_i, &p->alarmset.list, link) {
+ if (a_i == a) {
+ assert(a->proc == current);
+ /* it's still possible we're not getting the
+ * ref, racing with the release method */
+ if (!kref_get_not_zero(&a->kref, 1)) {
+ /* lost the race; error out later */
+ a_i = 0;
}
+ break;
}
- spin_unlock(&p->alarmset.lock);
- if (!a_i)
- error(EFAIL, "Unable to open alarm, concurrent closing");
- break;
+ }
+ spin_unlock(&p->alarmset.lock);
+ if (!a_i)
+ error(EFAIL,
+ "Unable to open alarm, concurrent closing");
+ break;
}
c->mode = openmode(omode);
/* Assumes c is unique (can't be closed concurrently */
@@ -346,18 +356,18 @@
static void alarmclose(struct chan *c)
{
- /* There are more closes than opens. For instance, sysstat doesn't open,
- * but it will close the chan it got from namec. We only want to clean
- * up/decref chans that were actually open. */
+ /* There are more closes than opens. For instance, sysstat doesn't
+ * open, but it will close the chan it got from namec. We only want to
+ * clean up/decref chans that were actually open. */
if (!(c->flag & COPEN))
return;
switch (TYPE(c->qid)) {
- case Qctl:
- case Qtimer:
- case Qperiod:
- case Qcount:
- kref_put(&QID2A(c->qid)->kref);
- break;
+ case Qctl:
+ case Qtimer:
+ case Qperiod:
+ case Qcount:
+ kref_put(&QID2A(c->qid)->kref);
+ break;
}
}
@@ -401,24 +411,24 @@
struct proc_alarm *p_alarm;
switch (TYPE(c->qid)) {
- case Qtopdir:
- case Qalarmdir:
- return devdirread(c, ubuf, n, 0, 0, alarmgen);
- case Qctl:
- p_alarm = QID2A(c->qid);
- /* simple reads from p_alarm shouldn't need a lock */
- return readnum(offset, ubuf, n, p_alarm->id, NUMSIZE32);
- case Qtimer:
- p_alarm = QID2A(c->qid);
- return readnum(offset, ubuf, n, p_alarm->a_waiter.wake_up_time,
- NUMSIZE64);
- case Qperiod:
- p_alarm = QID2A(c->qid);
- return readnum(offset, ubuf, n, p_alarm->period, NUMSIZE64);
- case Qcount:
- return read_qcount(c, ubuf, n); /* ignore offset */
- default:
- panic("Bad QID %p in devalarm", c->qid.path);
+ case Qtopdir:
+ case Qalarmdir:
+ return devdirread(c, ubuf, n, 0, 0, alarmgen);
+ case Qctl:
+ p_alarm = QID2A(c->qid);
+ /* simple reads from p_alarm shouldn't need a lock */
+ return readnum(offset, ubuf, n, p_alarm->id, NUMSIZE32);
+ case Qtimer:
+ p_alarm = QID2A(c->qid);
+ return readnum(offset, ubuf, n, p_alarm->a_waiter.wake_up_time,
+ NUMSIZE64);
+ case Qperiod:
+ p_alarm = QID2A(c->qid);
+ return readnum(offset, ubuf, n, p_alarm->period, NUMSIZE64);
+ case Qcount:
+ return read_qcount(c, ubuf, n); /* ignore offset */
+ default:
+ panic("Bad QID %p in devalarm", c->qid.path);
}
return 0;
}
@@ -426,18 +436,19 @@
/* Helper, sets the procalarm to hexval (abs TSC ticks). 0 disarms. */
static void set_proc_alarm(struct proc_alarm *a, uint64_t hexval)
{
- /* Due to how we have to maintain 'count', we need to strictly account for
- * the firings of the alarm. Easiest thing is to disarm it, reset
- * everything, then rearm it. Note that if someone is blocked on count = 0,
- * they may still be blocked until the next time the alarm fires.
+ /* Due to how we have to maintain 'count', we need to strictly account
+ * for the firings of the alarm. Easiest thing is to disarm it, reset
+ * everything, then rearm it. Note that if someone is blocked on count
+ * = 0, they may still be blocked until the next time the alarm fires.
*
- * unset waits on the handler, which grabs the cv lock, so we don't grab the
- * cv lock. However, we still need to protect ourselves from multiple
- * setters trying to run this at once. Unset actually can handle being
- * called concurrently, but alarm setters can't, nor can it handle the
- * unsets and sets getting out of sync. For instance, two unsets followed
- * by two sets would be a bug. Likewise, setting the awaiter value while it
- * is on a tchain is a bug. The qlock prevents that. */
+ * unset waits on the handler, which grabs the cv lock, so we don't grab
+ * the cv lock. However, we still need to protect ourselves from
+ * multiple setters trying to run this at once. Unset actually can
+ * handle being called concurrently, but alarm setters can't, nor can it
+ * handle the unsets and sets getting out of sync. For instance, two
+ * unsets followed by two sets would be a bug. Likewise, setting the
+ * awaiter value while it is on a tchain is a bug. The qlock prevents
+ * that. */
qlock(&a->qlock);
unset_alarm(a->proc->alarmset.tchain, &a->a_waiter);
cv_lock(&a->cv);
@@ -459,23 +470,23 @@
struct proc_alarm *p_alarm;
switch (TYPE(c->qid)) {
- case Qtopdir:
- case Qalarmdir:
- case Qctl:
- case Qcount:
- error(EPERM, ERROR_FIXME);
- case Qtimer:
- set_proc_alarm(QID2A(c->qid), strtoul_from_ubuf(ubuf, n, 16));
- break;
- case Qperiod:
- p_alarm = QID2A(c->qid);
- /* racing with the handler which checks the val repeatedly */
- cv_lock(&p_alarm->cv);
- p_alarm->period = strtoul_from_ubuf(ubuf, n, 16);
- cv_unlock(&p_alarm->cv);
- break;
- default:
- panic("Bad QID %p in devalarm", c->qid.path);
+ case Qtopdir:
+ case Qalarmdir:
+ case Qctl:
+ case Qcount:
+ error(EPERM, ERROR_FIXME);
+ case Qtimer:
+ set_proc_alarm(QID2A(c->qid), strtoul_from_ubuf(ubuf, n, 16));
+ break;
+ case Qperiod:
+ p_alarm = QID2A(c->qid);
+ /* racing with the handler which checks the val repeatedly */
+ cv_lock(&p_alarm->cv);
+ p_alarm->period = strtoul_from_ubuf(ubuf, n, 16);
+ cv_unlock(&p_alarm->cv);
+ break;
+ default:
+ panic("Bad QID %p in devalarm", c->qid.path);
}
return n;
}
diff --git a/kern/drivers/dev/capability.c b/kern/drivers/dev/capability.c
index e360180..6625086 100644
--- a/kern/drivers/dev/capability.c
+++ b/kern/drivers/dev/capability.c
@@ -106,7 +106,8 @@
switch ((uint32_t)c->qid.path) {
case Qhash:
if (!iseve())
- error(EPERM, "Permission denied: only eve can open Qhash");
+ error(EPERM,
+ "Permission denied: only eve can open Qhash");
break;
}
@@ -250,7 +251,8 @@
p = remcap((uint8_t *)hashstr);
if (p == NULL) {
- snprintf(err, sizeof(err), "invalid capability %s@%s", from, key);
+ snprintf(err, sizeof(err), "invalid capability %s@%s",
+ from, key);
error(EINVAL, err);
}
diff --git a/kern/drivers/dev/cons.c b/kern/drivers/dev/cons.c
index ffa0df2..4fdb4ea 100644
--- a/kern/drivers/dev/cons.c
+++ b/kern/drivers/dev/cons.c
@@ -8,35 +8,35 @@
*/
#include <arch/arch.h>
-#include <ros/fs.h>
-#include <ns.h>
-#include <kmalloc.h>
-#include <string.h>
-#include <stdio.h>
-#include <time.h>
#include <atomic.h>
-#include <smp.h>
-#include <error.h>
-#include <sys/queue.h>
-#include <event.h>
#include <env.h>
+#include <error.h>
+#include <event.h>
+#include <kmalloc.h>
+#include <ns.h>
+#include <ros/fs.h>
#include <ros/procinfo.h>
+#include <smp.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/queue.h>
+#include <time.h>
#if 0
void (*consdebug) (void) = NULL;
#endif
-void (*screenputs) (const char *, int) = cputbuf;
+void (*screenputs)(const char *, int) = cputbuf;
-struct queue *kbdq; /* unprocessed console input */
-struct queue *lineq; /* processed console input */
-struct queue *serialoq; /* serial console output */
-struct queue *kprintoq; /* console output, for /dev/kprint */
-atomic_t kprintinuse = 0; /* test and set whether /dev/kprint is open */
+struct queue *kbdq; /* unprocessed console input */
+struct queue *lineq; /* processed console input */
+struct queue *serialoq; /* serial console output */
+struct queue *kprintoq; /* console output, for /dev/kprint */
+atomic_t kprintinuse = 0; /* test and set whether /dev/kprint is open */
int iprintscreenputs = 1;
int keepbroken = 1;
static bool cons_has_init = FALSE;
-struct queue *cons_q; /* Akaros cons input: keyboard, serial, etc */
+struct queue *cons_q; /* Akaros cons input: keyboard, serial, etc */
spinlock_t cons_q_lock = SPINLOCK_INITIALIZER;
struct fdtap_slist cons_q_fd_taps = SLIST_HEAD_INITIALIZER(cons_q_fd_taps);
@@ -70,22 +70,26 @@
static struct {
qlock_t qlock;
- int raw; /* true if we shouldn't process input */
- struct kref ctl; /* number of opens to the control file */
- int x; /* index into line */
- char line[1024]; /* current input line */
+ int raw; /* true if we shouldn't process input */
+ struct kref ctl; /* number of opens to the control file */
+ int x; /* index into line */
+ char line[1024]; /* current input line */
int count;
int ctlpoff;
- /* a place to save up characters at interrupt time before dumping them in the queue */
+ /* a place to save up characters at interrupt time before dumping them
+ * in the queue */
spinlock_t lockputc;
char istage[1024];
char *iw;
char *ir;
char *ie;
} kbd = {
-.iw = kbd.istage,.ir = kbd.istage,.ie = kbd.istage + sizeof(kbd.istage),};
+ .iw = kbd.istage,
+ .ir = kbd.istage,
+ .ie = kbd.istage + sizeof(kbd.istage),
+};
char *sysname;
int64_t fasthz;
@@ -97,23 +101,18 @@
static int hostownerwrite(char *, size_t);
static void killkid(void);
-enum {
- CMbroken,
- CMconsole,
- CMhalt,
- CMnobroken,
- CMpanic,
- CMreboot,
+enum { CMbroken,
+ CMconsole,
+ CMhalt,
+ CMnobroken,
+ CMpanic,
+ CMreboot,
};
-
struct cmdtab rebootmsg[] = {
- {CMbroken, "broken", 0},
- {CMconsole, "console", 1},
- {CMhalt, "halt", 1},
- {CMnobroken, "nobroken", 0},
- {CMpanic, "panic", 0},
- {CMreboot, "reboot", 0},
+ {CMbroken, "broken", 0}, {CMconsole, "console", 1},
+ {CMhalt, "halt", 1}, {CMnobroken, "nobroken", 0},
+ {CMpanic, "panic", 0}, {CMreboot, "reboot", 0},
};
void printinit(void)
@@ -277,7 +276,7 @@
* Make a good faith effort.
*/
static spinlock_t iprintlock;
-static int iprintcanlock(spinlock_t * l)
+static int iprintcanlock(spinlock_t *l)
{
int i;
@@ -427,18 +426,18 @@
for (p = buf; p < e; p++) {
switch (*p) {
#if 0
- case 0x10: /* ^P */
- if (cpuserver && !kbd.ctlpoff) {
- active.exiting = 1;
- return;
- }
- break;
+ case 0x10: /* ^P */
+ if (cpuserver && !kbd.ctlpoff) {
+ active.exiting = 1;
+ return;
+ }
+ break;
#endif
- case 0x14: /* ^T */
- ctrlt++;
- if (ctrlt > 2)
- ctrlt = 2;
- continue;
+ case 0x14: /* ^T */
+ ctrlt++;
+ if (ctrlt > 2)
+ ctrlt = 2;
+ continue;
}
if (ctrlt != 2)
@@ -448,57 +447,57 @@
ctrlt = 0;
switch (*p) {
#if 0
- case 'S':{
- int8_t x = 0;
- disable_irqsave(&x);
- dumpstack();
- procdump();
- enable_irqsave(&x);
- return;
- }
-#endif
- case 's':
+ case 'S':{
+ int8_t x = 0;
+ disable_irqsave(&x);
dumpstack();
- return;
-#if 0
- case 'x':
- xsummary();
- ixsummary();
- mallocsummary();
- memorysummary();
- pagersummary();
- return;
- case 'd':
- if (consdebug == NULL)
- consdebug = rdb;
- else
- consdebug = NULL;
- printd("consdebug now %#p\n", consdebug);
- return;
- case 'D':
- if (consdebug == NULL)
- consdebug = rdb;
- consdebug();
- return;
- case 'p':
- x = spllo();
procdump();
- splx(x);
+ enable_irqsave(&x);
return;
- case 'q':
- scheddump();
- return;
- case 'k':
- killbig("^t ^t k");
- return;
+ }
#endif
- case 'r':
- exit(0);
- return;
+ case 's':
+ dumpstack();
+ return;
+#if 0
+ case 'x':
+ xsummary();
+ ixsummary();
+ mallocsummary();
+ memorysummary();
+ pagersummary();
+ return;
+ case 'd':
+ if (consdebug == NULL)
+ consdebug = rdb;
+ else
+ consdebug = NULL;
+ printd("consdebug now %#p\n", consdebug);
+ return;
+ case 'D':
+ if (consdebug == NULL)
+ consdebug = rdb;
+ consdebug();
+ return;
+ case 'p':
+ x = spllo();
+ procdump();
+ splx(x);
+ return;
+ case 'q':
+ scheddump();
+ return;
+ case 'k':
+ killbig("^t ^t k");
+ return;
+#endif
+ case 'r':
+ exit(0);
+ return;
}
}
- qwrite(kbdq, buf, n); /* was once qproduce, YMMV */
+ qwrite(kbdq, buf, n); /* was once qproduce, YMMV */
if (kbd.raw)
return;
kmesgputs(buf, n);
@@ -517,7 +516,7 @@
{
char *next;
- spin_lock_irqsave(&kbd.lockputc); /* just a mutex */
+ spin_lock_irqsave(&kbd.lockputc); /* just a mutex */
if (ch == '\r' && !kbd.raw)
ch = '\n';
next = kbd.iw + 1;
@@ -540,16 +539,16 @@
int i, n;
char buf[3];
// Akaros does not use Rune et al.
- //Rune r;
+ // Rune r;
int r;
char *next;
if (kbd.ir == NULL)
- return 0; /* in case we're not inited yet */
+ return 0; /* in case we're not inited yet */
- spin_lock_irqsave(&kbd.lockputc); /* just a mutex */
+ spin_lock_irqsave(&kbd.lockputc); /* just a mutex */
r = ch;
- //n = runetochar(buf, &r);
+ // n = runetochar(buf, &r);
// Fake Rune support.
n = 1;
buf[0] = r;
@@ -588,74 +587,72 @@
}
}
-enum {
- Qdir,
- Qbintime,
- Qconfig,
- Qcons,
- Qconsctl,
- Qcputime,
- Qdrivers,
- Qhostdomain,
- Qhostowner,
- Qklog,
- Qkmesg,
- Qkprint,
- Qnull,
- Qosversion,
- Qpgrpid,
- Qpid,
- Qppid,
- Qreboot,
- Qstdin,
- Qstdout,
- Qstderr,
- Qswap,
- Qsysctl,
- Qsysname,
- Qsysstat,
- Qtime,
- Quser,
- Qzero,
- Qkillkid,
+enum { Qdir,
+ Qbintime,
+ Qconfig,
+ Qcons,
+ Qconsctl,
+ Qcputime,
+ Qdrivers,
+ Qhostdomain,
+ Qhostowner,
+ Qklog,
+ Qkmesg,
+ Qkprint,
+ Qnull,
+ Qosversion,
+ Qpgrpid,
+ Qpid,
+ Qppid,
+ Qreboot,
+ Qstdin,
+ Qstdout,
+ Qstderr,
+ Qswap,
+ Qsysctl,
+ Qsysname,
+ Qsysstat,
+ Qtime,
+ Quser,
+ Qzero,
+ Qkillkid,
};
-enum {
- VLNUMSIZE = 22,
- DOMLEN = 256,
+enum { VLNUMSIZE = 22,
+ DOMLEN = 256,
};
static struct dirtab consdir[] = {
- {".", {Qdir, 0, QTDIR}, 0, DMDIR | 0555},
- {"bintime", {Qbintime}, 24, 0664},
- {"config", {Qconfig}, 0, 0444},
- {"cons", {Qcons}, 0, 0660},
- {"consctl", {Qconsctl}, 0, 0220},
- // FIXME -- we don't have real permissions yet so we set it to 222, not 220
- {"killkid", {Qkillkid}, 0, 0220 | /* BOGUS */ 2},
- {"cputime", {Qcputime}, 6 * NUMSIZE, 0444},
- {"drivers", {Qdrivers}, 0, 0444},
- {"hostdomain", {Qhostdomain}, DOMLEN, 0664},
- {"hostowner", {Qhostowner}, 0, 0664},
- {"klog", {Qklog}, 0, 0440},
- {"kmesg", {Qkmesg}, 0, 0440},
- {"kprint", {Qkprint, 0, QTEXCL}, 0, DMEXCL | 0440},
- {"null", {Qnull}, 0, 0666},
- {"osversion", {Qosversion}, 0, 0444},
- {"pgrpid", {Qpgrpid}, NUMSIZE, 0444},
- {"pid", {Qpid}, NUMSIZE, 0444},
- {"ppid", {Qppid}, NUMSIZE, 0444},
- {"reboot", {Qreboot}, 0, 0660},
- {"stdin", {Qstdin}, 0, 0666},
- {"stdout", {Qstdout}, 0, 0666},
- {"stderr", {Qstderr}, 0, 0666},
- {"swap", {Qswap}, 0, 0664},
- {"sysctl", {Qsysctl}, 0, 0666},
- {"sysname", {Qsysname}, 0, 0664},
- {"sysstat", {Qsysstat}, 0, 0666},
- {"time", {Qtime}, NUMSIZE + 3 * VLNUMSIZE, 0664},
- {"user", {Quser}, 0, 0666},
- {"zero", {Qzero}, 0, 0444},
+ {".", {Qdir, 0, QTDIR}, 0, DMDIR | 0555},
+ {"bintime", {Qbintime}, 24, 0664},
+ {"config", {Qconfig}, 0, 0444},
+ {"cons", {Qcons}, 0, 0660},
+ {"consctl", {Qconsctl}, 0, 0220},
+ // FIXME -- we don't have real permissions yet so we set it to 222, not 220
+ {"killkid", {Qkillkid}, 0, 0220 | /* BOGUS */ 2},
+ {"cputime", {Qcputime}, 6 * NUMSIZE, 0444},
+ {"drivers", {Qdrivers}, 0, 0444},
+ {"hostdomain", {Qhostdomain}, DOMLEN, 0664},
+ {"hostowner", {Qhostowner}, 0, 0664},
+ {"klog", {Qklog}, 0, 0440},
+ {"kmesg", {Qkmesg}, 0, 0440},
+ {"kprint", {Qkprint, 0, QTEXCL}, 0, DMEXCL | 0440},
+ {"null", {Qnull}, 0, 0666},
+ {"osversion", {Qosversion}, 0, 0444},
+ {"pgrpid", {Qpgrpid}, NUMSIZE, 0444},
+ {"pid", {Qpid}, NUMSIZE, 0444},
+ {"ppid", {Qppid}, NUMSIZE, 0444},
+ {"reboot", {Qreboot}, 0, 0660},
+ {"stdin", {Qstdin}, 0, 0666},
+ {"stdout", {Qstdout}, 0, 0666},
+ {"stderr", {Qstderr}, 0, 0666},
+ {"swap", {Qswap}, 0, 0664},
+ {"sysctl", {Qsysctl}, 0, 0666},
+ {"sysname", {Qsysname}, 0, 0664},
+ {"sysstat", {Qsysstat}, 0, 0666},
+ {"time", {Qtime}, NUMSIZE + 3 * VLNUMSIZE, 0664},
+ {"user", {Quser}, 0, 0666},
+ {"zero", {Qzero}, 0, 0444},
};
int consreadnum(uint32_t off, char *buf, uint32_t n, uint32_t val, int size)
@@ -699,7 +696,7 @@
#if 0
addclock0link(kbdputcclock, 22);
#endif
- cmb(); /* single-core, just need previous instructions to be issued. */
+ cmb(); /* single-core, just need previous instructions to be issued. */
cons_has_init = TRUE;
}
@@ -711,9 +708,10 @@
}
static struct walkqid *conswalk(struct chan *c, struct chan *nc, char **name,
- unsigned int nname)
+ unsigned int nname)
{
- return devwalk(c, nc, name, nname, consdir, ARRAY_SIZE(consdir), devgen);
+ return devwalk(c, nc, name, nname, consdir, ARRAY_SIZE(consdir),
+ devgen);
}
static size_t consstat(struct chan *c, uint8_t *dp, size_t n)
@@ -727,7 +725,8 @@
tab = &consdir[Qstdin];
perm = tab->perm;
perm |= qreadable(cons_q) ? DMREADABLE : 0;
- devdir(c, tab->qid, tab->name, qlen(cons_q), eve.name, perm, &dir);
+ devdir(c, tab->qid, tab->name, qlen(cons_q), eve.name, perm,
+ &dir);
return dev_make_stat(c, &dir, dp, n);
case Qnull:
tab = &consdir[Qnull];
@@ -743,49 +742,49 @@
{
c->aux = NULL;
c = devopen(c, omode, consdir, ARRAY_SIZE(consdir), devgen);
- switch ((uint32_t) c->qid.path) {
- case Qconsctl:
- kref_get(&kbd.ctl, 1);
- break;
+ switch ((uint32_t)c->qid.path) {
+ case Qconsctl:
+ kref_get(&kbd.ctl, 1);
+ break;
- case Qkprint:
- if (atomic_swap(&kprintinuse, 1) != 0) {
- c->flag &= ~COPEN;
- error(EADDRINUSE, "kprintinuse lock failed");
- }
+ case Qkprint:
+ if (atomic_swap(&kprintinuse, 1) != 0) {
+ c->flag &= ~COPEN;
+ error(EADDRINUSE, "kprintinuse lock failed");
+ }
+ if (kprintoq == NULL) {
+ kprintoq = qopen(8 * 1024, Qcoalesce, 0, 0);
if (kprintoq == NULL) {
- kprintoq = qopen(8 * 1024, Qcoalesce, 0, 0);
- if (kprintoq == NULL) {
- c->flag &= ~COPEN;
- error(ENOMEM, "Can't allocate kprintoq");
- }
- qdropoverflow(kprintoq, 1);
- } else
- qreopen(kprintoq);
- c->iounit = qiomaxatomic;
- break;
+ c->flag &= ~COPEN;
+ error(ENOMEM, "Can't allocate kprintoq");
+ }
+ qdropoverflow(kprintoq, 1);
+ } else
+ qreopen(kprintoq);
+ c->iounit = qiomaxatomic;
+ break;
}
return c;
}
static void consclose(struct chan *c)
{
- switch ((uint32_t) c->qid.path) {
- /* last close of control file turns off raw */
- case Qconsctl:
- if (c->flag & COPEN) {
- if (kref_put(&kbd.ctl) == 0)
- kbd.raw = 0;
- }
- break;
+ switch ((uint32_t)c->qid.path) {
+ /* last close of control file turns off raw */
+ case Qconsctl:
+ if (c->flag & COPEN) {
+ if (kref_put(&kbd.ctl) == 0)
+ kbd.raw = 0;
+ }
+ break;
- /* close of kprint allows other opens */
- case Qkprint:
- if (c->flag & COPEN) {
- kprintinuse = 0;
- qhangup(kprintoq, NULL);
- }
- break;
+ /* close of kprint allows other opens */
+ case Qkprint:
+ if (c->flag & COPEN) {
+ kprintinuse = 0;
+ qhangup(kprintoq, NULL);
+ }
+ break;
}
}
@@ -797,7 +796,7 @@
Mach *mp;
#endif
char *b, *bp, ch;
- char tmp[256]; /* must be >= 18*NUMSIZE (Qswap) */
+ char tmp[256]; /* must be >= 18*NUMSIZE (Qswap) */
int i, k, id, send;
int64_t offset = off;
#if 0
@@ -807,247 +806,257 @@
if (n <= 0)
return n;
- switch ((uint32_t) c->qid.path) {
- case Qdir:
- return devdirread(c, buf, n, consdir, ARRAY_SIZE(consdir), devgen);
+ switch ((uint32_t)c->qid.path) {
+ case Qdir:
+ return devdirread(c, buf, n, consdir, ARRAY_SIZE(consdir),
+ devgen);
- case Qcons:
- qlock(&(&kbd)->qlock);
- if (waserror()) {
- qunlock(&(&kbd)->qlock);
- nexterror();
- }
- while (!qcanread(lineq)) {
- if (qread(kbdq, &ch, 1) == 0)
- continue;
- send = 0;
- if (ch == 0) {
- /* flush output on rawoff -> rawon */
- if (kbd.x > 0)
- send = !qcanread(kbdq);
- } else if (kbd.raw) {
- kbd.line[kbd.x++] = ch;
- send = !qcanread(kbdq);
- } else {
- switch (ch) {
- case '\b':
- if (kbd.x > 0)
- kbd.x--;
- break;
- case 0x15: /* ^U */
- kbd.x = 0;
- break;
- case '\n':
- case 0x04: /* ^D */
- send = 1;
- default:
- if (ch != 0x04)
- kbd.line[kbd.x++] = ch;
- break;
- }
- }
- if (send || kbd.x == sizeof kbd.line) {
- qwrite(lineq, kbd.line, kbd.x);
- kbd.x = 0;
- }
- }
- n = qread(lineq, buf, n);
+ case Qcons:
+ qlock(&(&kbd)->qlock);
+ if (waserror()) {
qunlock(&(&kbd)->qlock);
- poperror();
- return n;
-
-#if 0
- case Qcputime:
- k = offset;
- if (k >= 6 * NUMSIZE)
- return 0;
- if (k + n > 6 * NUMSIZE)
- n = 6 * NUMSIZE - k;
- /* easiest to format in a separate buffer and copy out */
- for (i = 0; i < 6 && NUMSIZE * i < k + n; i++) {
- l = current->time[i];
- if (i == TReal)
- l = MACHP(0)->ticks - l;
- l = TK2MS(l);
- consreadnum(0, tmp + NUMSIZE * i, NUMSIZE, l, NUMSIZE);
- }
- memmove(buf, tmp + k, n);
- return n;
-#endif
-
- case Qkmesg:
- /*
- * This is unlocked to avoid tying up a process
- * that's writing to the buffer. kmesg.n never
- * gets smaller, so worst case the reader will
- * see a slurred buffer.
- */
- if (off >= kmesg.n)
- n = 0;
- else {
- if (off + n > kmesg.n)
- n = kmesg.n - off;
- memmove(buf, kmesg.buf + off, n);
- }
- return n;
-
- case Qkprint:
- return qread(kprintoq, buf, n);
-
- case Qpgrpid:
- return consreadnum((uint32_t) offset, buf, n, current->pgrp->pgrpid,
- NUMSIZE);
-
- case Qpid:
- return consreadnum((uint32_t) offset, buf, n, current->pid,
- NUMSIZE);
-
- case Qppid:
- return consreadnum((uint32_t) offset, buf, n, current->ppid,
- NUMSIZE);
-
- case Qtime:
- return readtime((uint32_t) offset, buf, n);
-
- case Qbintime:
- return readbintime(buf, n);
-
- case Qhostowner:
- return consreadstr((uint32_t) offset, buf, n, eve.name);
-
- case Qhostdomain:
- return consreadstr((uint32_t) offset, buf, n, hostdomain);
-
- case Quser:
- return consreadstr((uint32_t) offset, buf, n, current->user.name);
-
- case Qnull:
- return 0;
-
-#if 0
- case Qconfig:
- return consreadstr((uint32_t) offset, buf, n, configfile);
-
- case Qsysstat:
- b = kzmalloc(conf.nmach * (NUMSIZE * 11 + 1) + 1, 0); /* +1 for NUL */
- bp = b;
- for (id = 0; id < 32; id++) {
- if (active.machs & (1 << id)) {
- mp = MACHP(id);
- consreadnum(0, bp, NUMSIZE, id, NUMSIZE);
- bp += NUMSIZE;
- consreadnum(0, bp, NUMSIZE, mp->cs, NUMSIZE);
- bp += NUMSIZE;
- consreadnum(0, bp, NUMSIZE, mp->intr, NUMSIZE);
- bp += NUMSIZE;
- consreadnum(0, bp, NUMSIZE, mp->syscall, NUMSIZE);
- bp += NUMSIZE;
- consreadnum(0, bp, NUMSIZE, mp->pfault, NUMSIZE);
- bp += NUMSIZE;
- consreadnum(0, bp, NUMSIZE, mp->tlbfault, NUMSIZE);
- bp += NUMSIZE;
- consreadnum(0, bp, NUMSIZE, mp->tlbpurge, NUMSIZE);
- bp += NUMSIZE;
- consreadnum(0, bp, NUMSIZE, mp->load, NUMSIZE);
- bp += NUMSIZE;
- consreadnum(0, bp, NUMSIZE,
- (mp->perf.avg_inidle * 100) / mp->perf.period,
- NUMSIZE);
- bp += NUMSIZE;
- consreadnum(0, bp, NUMSIZE,
- (mp->perf.avg_inintr * 100) / mp->perf.period,
- NUMSIZE);
- bp += NUMSIZE;
- *bp++ = '\n';
+ nexterror();
+ }
+ while (!qcanread(lineq)) {
+ if (qread(kbdq, &ch, 1) == 0)
+ continue;
+ send = 0;
+ if (ch == 0) {
+ /* flush output on rawoff -> rawon */
+ if (kbd.x > 0)
+ send = !qcanread(kbdq);
+ } else if (kbd.raw) {
+ kbd.line[kbd.x++] = ch;
+ send = !qcanread(kbdq);
+ } else {
+ switch (ch) {
+ case '\b':
+ if (kbd.x > 0)
+ kbd.x--;
+ break;
+ case 0x15: /* ^U */
+ kbd.x = 0;
+ break;
+ case '\n':
+ case 0x04: /* ^D */
+ send = 1;
+ default:
+ if (ch != 0x04)
+ kbd.line[kbd.x++] = ch;
+ break;
}
}
- if (waserror()) {
- kfree(b);
- nexterror();
+ if (send || kbd.x == sizeof kbd.line) {
+ qwrite(lineq, kbd.line, kbd.x);
+ kbd.x = 0;
}
- n = consreadstr((uint32_t) offset, buf, n, b);
- kfree(b);
- poperror();
- return n;
+ }
+ n = qread(lineq, buf, n);
+ qunlock(&(&kbd)->qlock);
+ poperror();
+ return n;
- case Qswap:
- snprintf(tmp, sizeof tmp,
- "%lud memory\n"
- "%d pagesize\n"
- "%lud kernel\n"
- "%lud/%lud user\n"
- "%lud/%lud swap\n"
- "%lud/%lud kernel malloc\n"
- "%lud/%lud kernel draw\n",
- conf.npage * BY2PG,
- BY2PG,
- conf.npage - conf.upages,
- palloc.user - palloc.freecount, palloc.user,
- conf.nswap - swapalloc.free, conf.nswap,
- mainmem->cursize, mainmem->maxsize,
- imagmem->cursize, imagmem->maxsize);
-
- return consreadstr((uint32_t) offset, buf, n, tmp);
+#if 0
+ case Qcputime:
+ k = offset;
+ if (k >= 6 * NUMSIZE)
+ return 0;
+ if (k + n > 6 * NUMSIZE)
+ n = 6 * NUMSIZE - k;
+ /* easiest to format in a separate buffer and copy out */
+ for (i = 0; i < 6 && NUMSIZE * i < k + n; i++) {
+ l = current->time[i];
+ if (i == TReal)
+ l = MACHP(0)->ticks - l;
+ l = TK2MS(l);
+ consreadnum(0, tmp + NUMSIZE * i, NUMSIZE, l, NUMSIZE);
+ }
+ memmove(buf, tmp + k, n);
+ return n;
#endif
- case Qstdin:
- if (c->flag & O_NONBLOCK)
- return qread_nonblock(cons_q, buf, n);
- else
- return qread(cons_q, buf, n);
- case Qsysname:
- /* TODO: this is racy */
- if (sysname == NULL)
- return 0;
- return consreadstr((uint32_t) offset, buf, n, sysname);
+ case Qkmesg:
+ /*
+ * This is unlocked to avoid tying up a process
+ * that's writing to the buffer. kmesg.n never
+ * gets smaller, so worst case the reader will
+ * see a slurred buffer.
+ */
+ if (off >= kmesg.n)
+ n = 0;
+ else {
+ if (off + n > kmesg.n)
+ n = kmesg.n - off;
+ memmove(buf, kmesg.buf + off, n);
+ }
+ return n;
- case Qdrivers:
- b = kzmalloc(READSTR, 0);
- if (b == NULL)
- error(ENOMEM, "allocation for /dev/drivers read failed");
- k = 0;
- for (int i = 0; &devtab[i] < __devtabend; i++)
- k += snprintf(b + k, READSTR - k, "#%s\n", devtab[i].name);
- if (waserror()) {
- kfree(b);
- nexterror();
+ case Qkprint:
+ return qread(kprintoq, buf, n);
+
+ case Qpgrpid:
+ return consreadnum((uint32_t)offset, buf, n,
+ current->pgrp->pgrpid, NUMSIZE);
+
+ case Qpid:
+ return consreadnum((uint32_t)offset, buf, n, current->pid,
+ NUMSIZE);
+
+ case Qppid:
+ return consreadnum((uint32_t)offset, buf, n, current->ppid,
+ NUMSIZE);
+
+ case Qtime:
+ return readtime((uint32_t)offset, buf, n);
+
+ case Qbintime:
+ return readbintime(buf, n);
+
+ case Qhostowner:
+ return consreadstr((uint32_t)offset, buf, n, eve.name);
+
+ case Qhostdomain:
+ return consreadstr((uint32_t)offset, buf, n, hostdomain);
+
+ case Quser:
+ return consreadstr((uint32_t)offset, buf, n,
+ current->user.name);
+
+ case Qnull:
+ return 0;
+
+#if 0
+ case Qconfig:
+ return consreadstr((uint32_t) offset, buf, n, configfile);
+
+ case Qsysstat:
+ /* +1 for NUL */
+ b = kzmalloc(conf.nmach * (NUMSIZE * 11 + 1) + 1, 0);
+ bp = b;
+ for (id = 0; id < 32; id++) {
+ if (active.machs & (1 << id)) {
+ mp = MACHP(id);
+ consreadnum(0, bp, NUMSIZE, id, NUMSIZE);
+ bp += NUMSIZE;
+ consreadnum(0, bp, NUMSIZE, mp->cs, NUMSIZE);
+ bp += NUMSIZE;
+ consreadnum(0, bp, NUMSIZE, mp->intr, NUMSIZE);
+ bp += NUMSIZE;
+ consreadnum(0, bp, NUMSIZE, mp->syscall,
+ NUMSIZE);
+ bp += NUMSIZE;
+ consreadnum(0, bp, NUMSIZE, mp->pfault,
+ NUMSIZE);
+ bp += NUMSIZE;
+ consreadnum(0, bp, NUMSIZE, mp->tlbfault,
+ NUMSIZE);
+ bp += NUMSIZE;
+ consreadnum(0, bp, NUMSIZE, mp->tlbpurge,
+ NUMSIZE);
+ bp += NUMSIZE;
+ consreadnum(0, bp, NUMSIZE, mp->load, NUMSIZE);
+ bp += NUMSIZE;
+ consreadnum(0, bp, NUMSIZE,
+ (mp->perf.avg_inidle * 100) /
+ mp->perf.period, NUMSIZE);
+ bp += NUMSIZE;
+ consreadnum(0, bp, NUMSIZE,
+ (mp->perf.avg_inintr * 100) /
+ mp->perf.period, NUMSIZE);
+ bp += NUMSIZE;
+ *bp++ = '\n';
}
- n = consreadstr((uint32_t) offset, buf, n, b);
+ }
+ if (waserror()) {
kfree(b);
- poperror();
- return n;
+ nexterror();
+ }
+ n = consreadstr((uint32_t) offset, buf, n, b);
+ kfree(b);
+ poperror();
+ return n;
- case Qklog:
- //return qread(klogq, buf, n);
- /* the queue gives us some elasticity for log reading. */
- if (!logqueue)
- logqueue = qopen(1 << 20, 0, 0, 0);
- if (logqueue) {
- int ret;
- /* atomic sets/gets are not that important in this case. */
- reading_kmesg = 1;
- qwrite(logqueue, logbuffer, index);
- index = 0;
- ret = qread(logqueue, buf, n);
- reading_kmesg = 0;
- return ret;
- }
- break;
+ case Qswap:
+ snprintf(tmp, sizeof tmp,
+ "%lud memory\n"
+ "%d pagesize\n"
+ "%lud kernel\n"
+ "%lud/%lud user\n"
+ "%lud/%lud swap\n"
+ "%lud/%lud kernel malloc\n"
+ "%lud/%lud kernel draw\n",
+ conf.npage * BY2PG,
+ BY2PG,
+ conf.npage - conf.upages,
+ palloc.user - palloc.freecount, palloc.user,
+ conf.nswap - swapalloc.free, conf.nswap,
+ mainmem->cursize, mainmem->maxsize,
+ imagmem->cursize, imagmem->maxsize);
- case Qzero:
- memset(buf, 0, n);
- return n;
+ return consreadstr((uint32_t) offset, buf, n, tmp);
+#endif
- case Qosversion:
- snprintf(tmp, sizeof tmp, "2000");
- n = consreadstr((uint32_t) offset, buf, n, tmp);
- return n;
+ case Qstdin:
+ if (c->flag & O_NONBLOCK)
+ return qread_nonblock(cons_q, buf, n);
+ else
+ return qread(cons_q, buf, n);
+ case Qsysname:
+ /* TODO: this is racy */
+ if (sysname == NULL)
+ return 0;
+ return consreadstr((uint32_t)offset, buf, n, sysname);
- default:
- printd("consread %#llux\n", c->qid.path);
- error(EINVAL, "bad QID in consread");
+ case Qdrivers:
+ b = kzmalloc(READSTR, 0);
+ if (b == NULL)
+ error(ENOMEM,
+ "allocation for /dev/drivers read failed");
+ k = 0;
+ for (int i = 0; &devtab[i] < __devtabend; i++)
+ k += snprintf(b + k, READSTR - k, "#%s\n",
+ devtab[i].name);
+ if (waserror()) {
+ kfree(b);
+ nexterror();
+ }
+ n = consreadstr((uint32_t)offset, buf, n, b);
+ kfree(b);
+ poperror();
+ return n;
+
+ case Qklog:
+ // return qread(klogq, buf, n);
+ /* the queue gives us some elasticity for log reading. */
+ if (!logqueue)
+ logqueue = qopen(1 << 20, 0, 0, 0);
+ if (logqueue) {
+ int ret;
+ /* atomic sets/gets are not that important in this case.
+ */
+ reading_kmesg = 1;
+ qwrite(logqueue, logbuffer, index);
+ index = 0;
+ ret = qread(logqueue, buf, n);
+ reading_kmesg = 0;
+ return ret;
+ }
+ break;
+
+ case Qzero:
+ memset(buf, 0, n);
+ return n;
+
+ case Qosversion:
+ snprintf(tmp, sizeof tmp, "2000");
+ n = consreadstr((uint32_t)offset, buf, n, tmp);
+ return n;
+
+ default:
+ printd("consread %#llux\n", c->qid.path);
+ error(EINVAL, "bad QID in consread");
}
- return -1; /* never reached */
+ return -1; /* never reached */
}
static size_t conswrite(struct chan *c, void *va, size_t n, off64_t off)
@@ -1056,7 +1065,7 @@
char buf[256], ch;
long l, bp;
char *a;
- //Mach *mp;
+ // Mach *mp;
int id, fd;
struct chan *swc;
uint32_t offset;
@@ -1069,186 +1078,187 @@
a = va;
offset = off;
- switch ((uint32_t) c->qid.path) {
- case Qcons:
- /*
- * Can't page fault in putstrn, so copy the data locally.
- */
- l = n;
- while (l > 0) {
- bp = l;
- if (bp > sizeof buf)
- bp = sizeof buf;
- memmove(buf, a, bp);
- putstrn0(buf, bp, 1);
- a += bp;
- l -= bp;
+ switch ((uint32_t)c->qid.path) {
+ case Qcons:
+ /*
+ * Can't page fault in putstrn, so copy the data locally.
+ */
+ l = n;
+ while (l > 0) {
+ bp = l;
+ if (bp > sizeof buf)
+ bp = sizeof buf;
+ memmove(buf, a, bp);
+ putstrn0(buf, bp, 1);
+ a += bp;
+ l -= bp;
+ }
+ break;
+
+ /* TODO: have it take a command about just *how* to kill the kid? */
+ case Qkillkid:
+ killkid();
+ break;
+
+ case Qconsctl:
+ if (n >= sizeof(buf))
+ n = sizeof(buf) - 1;
+ strncpy(buf, a, n);
+ buf[n] = 0;
+ for (a = buf; a;) {
+ if (strncmp(a, "rawon", 5) == 0) {
+ kbd.raw = 1;
+ /* clumsy hack - wake up reader */
+ ch = 0;
+ qwrite(kbdq, &ch, 1);
+ } else if (strncmp(a, "rawoff", 6) == 0) {
+ kbd.raw = 0;
+ } else if (strncmp(a, "ctlpon", 6) == 0) {
+ kbd.ctlpoff = 0;
+ } else if (strncmp(a, "ctlpoff", 7) == 0) {
+ kbd.ctlpoff = 1;
}
- break;
+ if ((a = strchr(a, ' ')) != NULL)
+ a++;
+ }
+ break;
- /* TODO: have it take a command about just *how* to kill the kid? */
- case Qkillkid:
- killkid();
- break;
+ case Qtime:
+ if (!iseve())
+ error(EPERM, "Hodie Natus Est Radici Frater");
+ return writetime(a, n);
- case Qconsctl:
- if (n >= sizeof(buf))
- n = sizeof(buf) - 1;
- strncpy(buf, a, n);
- buf[n] = 0;
- for (a = buf; a;) {
- if (strncmp(a, "rawon", 5) == 0) {
- kbd.raw = 1;
- /* clumsy hack - wake up reader */
- ch = 0;
- qwrite(kbdq, &ch, 1);
- } else if (strncmp(a, "rawoff", 6) == 0) {
- kbd.raw = 0;
- } else if (strncmp(a, "ctlpon", 6) == 0) {
- kbd.ctlpoff = 0;
- } else if (strncmp(a, "ctlpoff", 7) == 0) {
- kbd.ctlpoff = 1;
- }
- if ((a = strchr(a, ' ')) != NULL)
- a++;
- }
- break;
+ case Qbintime:
+ if (!iseve())
+ error(EPERM, ERROR_FIXME);
+ return writebintime(a, n);
- case Qtime:
- if (!iseve())
- error(EPERM, "Hodie Natus Est Radici Frater");
- return writetime(a, n);
-
- case Qbintime:
- if (!iseve())
- error(EPERM, ERROR_FIXME);
- return writebintime(a, n);
-
- case Qhostowner:
- return hostownerwrite(a, n);
+ case Qhostowner:
+ return hostownerwrite(a, n);
#if 0
- case Qhostdomain:
- return hostdomainwrite(a, n);
+ case Qhostdomain:
+ return hostdomainwrite(a, n);
- case Quser:
- return userwrite(a, n);
+ case Quser:
+ return userwrite(a, n);
#endif
- case Qnull:
- break;
+ case Qnull:
+ break;
- case Qconfig:
- error(EPERM, "Cannot write to config QID");
- break;
+ case Qconfig:
+ error(EPERM, "Cannot write to config QID");
+ break;
- case Qsysctl:
- //if (!iseve()) error(EPERM, ERROR_FIXME);
- cb = parsecmd(a, n);
- if (cb->nf > 1)
+ case Qsysctl:
+ // if (!iseve()) error(EPERM, ERROR_FIXME);
+ cb = parsecmd(a, n);
+ if (cb->nf > 1)
printd("cons sysctl cmd %s\n", cb->f[0]);
- case Qreboot:
- if (!iseve())
- error(EPERM, ERROR_FIXME);
- cb = parsecmd(a, n);
+ case Qreboot:
+ if (!iseve())
+ error(EPERM, ERROR_FIXME);
+ cb = parsecmd(a, n);
- if (waserror()) {
- kfree(cb);
- nexterror();
- }
- ct = lookupcmd(cb, rebootmsg, ARRAY_SIZE(rebootmsg));
- switch (ct->index) {
- case CMhalt:
- cpu_halt();
- break;
- case CMbroken:
- keepbroken = 1;
- break;
- case CMnobroken:
- keepbroken = 0;
- break;
- case CMreboot:
- reboot();
- break;
- case CMpanic:
- *(uint32_t *) 0 = 0;
- panic("/dev/reboot");
- break;
- }
- poperror();
+ if (waserror()) {
kfree(cb);
+ nexterror();
+ }
+ ct = lookupcmd(cb, rebootmsg, ARRAY_SIZE(rebootmsg));
+ switch (ct->index) {
+ case CMhalt:
+ cpu_halt();
break;
+ case CMbroken:
+ keepbroken = 1;
+ break;
+ case CMnobroken:
+ keepbroken = 0;
+ break;
+ case CMreboot:
+ reboot();
+ break;
+ case CMpanic:
+ *(uint32_t *)0 = 0;
+ panic("/dev/reboot");
+ break;
+ }
+ poperror();
+ kfree(cb);
+ break;
#if 0
- case Qsysstat:
- for (id = 0; id < 32; id++) {
- if (active.machs & (1 << id)) {
- mp = MACHP(id);
- mp->cs = 0;
- mp->intr = 0;
- mp->syscall = 0;
- mp->pfault = 0;
- mp->tlbfault = 0;
- mp->tlbpurge = 0;
- }
+ case Qsysstat:
+ for (id = 0; id < 32; id++) {
+ if (active.machs & (1 << id)) {
+ mp = MACHP(id);
+ mp->cs = 0;
+ mp->intr = 0;
+ mp->syscall = 0;
+ mp->pfault = 0;
+ mp->tlbfault = 0;
+ mp->tlbpurge = 0;
}
- break;
+ }
+ break;
- case Qswap:
- if (n >= sizeof buf)
- error(EINVAL, "n is bigger than sizeof buf for Qswap");
- memmove(buf, va, n); /* so we can NUL-terminate */
- buf[n] = 0;
- /* start a pager if not already started */
- if (strncmp(buf, "start", 5) == 0) {
- kickpager();
- break;
- }
- if (!iseve())
- error(EPERM, ERROR_FIXME);
- if (buf[0] < '0' || '9' < buf[0])
- error(EINVAL, ERROR_FIXME);
- fd = strtoul(buf, 0, 0);
- swc = fdtochan(fd, -1, 1, 1);
- setswapchan(swc);
+ case Qswap:
+ if (n >= sizeof buf)
+ error(EINVAL, "n is bigger than sizeof buf for Qswap");
+ memmove(buf, va, n); /* so we can NUL-terminate */
+ buf[n] = 0;
+ /* start a pager if not already started */
+ if (strncmp(buf, "start", 5) == 0) {
+ kickpager();
break;
+ }
+ if (!iseve())
+ error(EPERM, ERROR_FIXME);
+ if (buf[0] < '0' || '9' < buf[0])
+ error(EINVAL, ERROR_FIXME);
+ fd = strtoul(buf, 0, 0);
+ swc = fdtochan(fd, -1, 1, 1);
+ setswapchan(swc);
+ break;
#endif
- case Qstdout:
- case Qstderr:
- print_lock();
- if (waserror()) {
- print_unlock();
- nexterror();
- }
- /* TODO: tty hack. they are sending us an escape sequence, and the
- * keyboard would try to print it (which it can't do yet). The hack
- * is even dirtier in that we only detect it if it is the first
- * char, and we ignore everything else. \033 is 0x1b. */
- if (((char*)va)[0] != '\033') {
- n = MIN(n, 80);
- cputbuf(va, n);
- }
- poperror();
+ case Qstdout:
+ case Qstderr:
+ print_lock();
+ if (waserror()) {
print_unlock();
- return n;
- case Qsysname:
- /* TODO: this is racy */
- if (offset != 0)
- error(EINVAL, ERROR_FIXME);
- if (n <= 0 || n >= sizeof buf)
- error(EINVAL, ERROR_FIXME);
- strncpy(buf, a, n);
- buf[n] = 0;
- if (buf[n - 1] == '\n')
- buf[n - 1] = 0;
- kstrdup(&sysname, buf);
- break;
+ nexterror();
+ }
+ /* TODO: tty hack. they are sending us an escape sequence, and
+ * the keyboard would try to print it (which it can't do yet).
+ * The hack is even dirtier in that we only detect it if it is
+ * the first
+ * char, and we ignore everything else. \033 is 0x1b. */
+ if (((char *)va)[0] != '\033') {
+ n = MIN(n, 80);
+ cputbuf(va, n);
+ }
+ poperror();
+ print_unlock();
+ return n;
+ case Qsysname:
+ /* TODO: this is racy */
+ if (offset != 0)
+ error(EINVAL, ERROR_FIXME);
+ if (n <= 0 || n >= sizeof buf)
+ error(EINVAL, ERROR_FIXME);
+ strncpy(buf, a, n);
+ buf[n] = 0;
+ if (buf[n - 1] == '\n')
+ buf[n - 1] = 0;
+ kstrdup(&sysname, buf);
+ break;
- default:
- printd("conswrite: %#llux\n", c->qid.path);
- error(EINVAL, "bad QID in conswrite");
+ default:
+ printd("conswrite: %#llux\n", c->qid.path);
+ error(EINVAL, "bad QID in conswrite");
}
return n;
}
@@ -1271,26 +1281,25 @@
int filter = a0;
spin_lock(&cons_q_lock);
- SLIST_FOREACH(tap_i, &cons_q_fd_taps, link)
+ SLIST_FOREACH (tap_i, &cons_q_fd_taps, link)
fire_tap(tap_i, filter);
spin_unlock(&cons_q_lock);
-
}
static void cons_q_wake_cb(struct queue *q, void *data, int filter)
{
- /* TODO: taps can't fire from IRQ context, but the qiwrites for stdin come
- * from IRQ context. So we need an RKM here. */
- send_kernel_message(core_id(), __consq_fire_taps, filter,
- 0, 0, KMSG_ROUTINE);
+ /* TODO: taps can't fire from IRQ context, but the qiwrites for stdin
+ * come from IRQ context. So we need an RKM here. */
+ send_kernel_message(core_id(), __consq_fire_taps, filter, 0, 0,
+ KMSG_ROUTINE);
}
static int tap_stdin(struct chan *c, struct fd_tap *tap, int cmd)
{
int ret;
- /* We don't actually support HANGUP, but epoll implies it. */
- #define CONS_STDIN_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_HANGUP)
+/* We don't actually support HANGUP, but epoll implies it. */
+#define CONS_STDIN_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_HANGUP)
if (tap->filter & ~CONS_STDIN_TAPS) {
set_error(ENOSYS, "Unsupported #%s tap, must be %p", devname(),
@@ -1312,7 +1321,8 @@
ret = 0;
break;
default:
- set_error(ENOSYS, "Unsupported #%s tap command %p", devname(), cmd);
+ set_error(ENOSYS, "Unsupported #%s tap command %p", devname(),
+ cmd);
ret = -1;
}
spin_unlock(&cons_q_lock);
@@ -1328,8 +1338,8 @@
* writable, so epoll will appear to have an event. */
static int tap_null(struct chan *c, struct fd_tap *tap, int cmd)
{
- /* We don't actually support HANGUP, but epoll implies it. */
- #define CONS_NULL_TAPS (FDTAP_FILT_WRITABLE | FDTAP_FILT_HANGUP)
+/* We don't actually support HANGUP, but epoll implies it. */
+#define CONS_NULL_TAPS (FDTAP_FILT_WRITABLE | FDTAP_FILT_HANGUP)
if (tap->filter & ~CONS_NULL_TAPS) {
set_error(ENOSYS, "Unsupported #%s tap, must be %p", devname(),
@@ -1354,26 +1364,26 @@
}
struct dev consdevtab __devtab = {
- .name = "cons",
+ .name = "cons",
- .reset = devreset,
- .init = consinit,
- .shutdown = devshutdown,
- .attach = consattach,
- .walk = conswalk,
- .stat = consstat,
- .open = consopen,
- .create = devcreate,
- .close = consclose,
- .read = consread,
- .bread = devbread,
- .write = conswrite,
- .bwrite = devbwrite,
- .remove = devremove,
- .wstat = devwstat,
- .power = devpower,
- .chaninfo = cons_chaninfo,
- .tapfd = cons_tapfd,
+ .reset = devreset,
+ .init = consinit,
+ .shutdown = devshutdown,
+ .attach = consattach,
+ .walk = conswalk,
+ .stat = consstat,
+ .open = consopen,
+ .create = devcreate,
+ .close = consclose,
+ .read = consread,
+ .bread = devbread,
+ .write = conswrite,
+ .bwrite = devbwrite,
+ .remove = devremove,
+ .wstat = devwstat,
+ .power = devpower,
+ .chaninfo = cons_chaninfo,
+ .tapfd = cons_tapfd,
};
static char *devname(void)
@@ -1383,25 +1393,25 @@
static uint64_t uvorder = 0x0001020304050607ULL;
-static uint8_t *le2int64_t(int64_t * to, uint8_t * f)
+static uint8_t *le2int64_t(int64_t *to, uint8_t *f)
{
uint8_t *t, *o;
int i;
- t = (uint8_t *) to;
- o = (uint8_t *) & uvorder;
+ t = (uint8_t *)to;
+ o = (uint8_t *)&uvorder;
for (i = 0; i < sizeof(int64_t); i++)
t[o[i]] = f[i];
return f + sizeof(int64_t);
}
-static uint8_t *int64_t2le(uint8_t * t, int64_t from)
+static uint8_t *int64_t2le(uint8_t *t, int64_t from)
{
uint8_t *f, *o;
int i;
- f = (uint8_t *) & from;
- o = (uint8_t *) & uvorder;
+ f = (uint8_t *)&from;
+ o = (uint8_t *)&uvorder;
for (i = 0; i < sizeof(int64_t); i++)
t[i] = f[o[i]];
return t + sizeof(int64_t);
@@ -1409,25 +1419,25 @@
static long order = 0x00010203;
-static uint8_t *le2long(long *to, uint8_t * f)
+static uint8_t *le2long(long *to, uint8_t *f)
{
uint8_t *t, *o;
int i;
- t = (uint8_t *) & to;
- o = (uint8_t *) & order;
+ t = (uint8_t *)&to;
+ o = (uint8_t *)ℴ
for (i = 0; i < sizeof(long); i++)
t[o[i]] = f[i];
return f + sizeof(long);
}
-static uint8_t *long2le(uint8_t * t, long from)
+static uint8_t *long2le(uint8_t *t, long from)
{
uint8_t *f, *o;
int i;
- f = (uint8_t *) & from;
- o = (uint8_t *) & order;
+ f = (uint8_t *)&from;
+ o = (uint8_t *)ℴ
for (i = 0; i < sizeof(long); i++)
t[i] = f[o[i]];
return t + sizeof(long);
@@ -1455,9 +1465,9 @@
ticks = read_tsc();
nsec = tsc2nsec(ticks);
sec = nsec / 1000000000ULL;
- snprintf(str, sizeof(str), "%*lud %*llud %*llud %*llud ",
- NUMSIZE - 1, sec,
- VLNUMSIZE - 1, nsec, VLNUMSIZE - 1, ticks, VLNUMSIZE - 1, fasthz);
+ snprintf(str, sizeof(str), "%*lud %*llud %*llud %*llud ", NUMSIZE - 1,
+ sec, VLNUMSIZE - 1, nsec, VLNUMSIZE - 1, ticks, VLNUMSIZE - 1,
+ fasthz);
return consreadstr(off, buf, n, str);
}
@@ -1492,7 +1502,7 @@
{
int i;
int64_t nsec, ticks;
- uint8_t *b = (uint8_t *) buf;
+ uint8_t *b = (uint8_t *)buf;
i = 0;
if (fasthz == 0LL)
@@ -1531,35 +1541,35 @@
long period = 0;
n--;
- p = (uint8_t *) buf + 1;
+ p = (uint8_t *)buf + 1;
switch (*buf) {
- case 'n':
- if (n < sizeof(int64_t))
- error(EINVAL, ERROR_FIXME);
- le2int64_t(&delta, p);
+ case 'n':
+ if (n < sizeof(int64_t))
+ error(EINVAL, ERROR_FIXME);
+ le2int64_t(&delta, p);
#if 0
todset(delta, 0, 0);
#endif
- break;
- case 'd':
- if (n < sizeof(int64_t) + sizeof(long))
- error(EINVAL, ERROR_FIXME);
- p = le2int64_t(&delta, p);
- le2long(&period, p);
+ break;
+ case 'd':
+ if (n < sizeof(int64_t) + sizeof(long))
+ error(EINVAL, ERROR_FIXME);
+ p = le2int64_t(&delta, p);
+ le2long(&period, p);
#if 0
todset(-1, delta, period);
#endif
- break;
- case 'f':
- if (n < sizeof(uint64_t))
- error(EINVAL, ERROR_FIXME);
- le2int64_t(&fasthz, p);
- if (fasthz <= 0)
- error(EINVAL, ERROR_FIXME);
+ break;
+ case 'f':
+ if (n < sizeof(uint64_t))
+ error(EINVAL, ERROR_FIXME);
+ le2int64_t(&fasthz, p);
+ if (fasthz <= 0)
+ error(EINVAL, ERROR_FIXME);
#if 0
todsetfreq(fasthz);
#endif
- break;
+ break;
}
return n;
}
@@ -1609,9 +1619,10 @@
for (size_t i = 0; i < pset.num_processes; i++) {
// Won't update current again
- // Note: if a name is being written to the user field as it is read
- // here, it will appear as ""; but no other writes should occur
- // as early as this should be run
+ // Note: if a name is being written to the user field as it is
+ // read
+ // here, it will appear as ""; but no other writes should
+ // occur as early as this should be run
if (strcmp(pset.procs[i]->user.name, "") == 0)
proc_set_username(pset.procs[i], buf);
}
@@ -1652,8 +1663,8 @@
* terminology was Ken's idea; go yell at him. If you want, we can
* rename this to DrownCuteKittens.
*
- * This was hard to get right so it's way more verbose than you might think we need.
- * Sorry.
+ * This was hard to get right so it's way more verbose than you might think we
+ * need. Sorry.
*/
void killkid(void)
{
diff --git a/kern/drivers/dev/ether.c b/kern/drivers/dev/ether.c
index d4f732d..e1bcb18 100644
--- a/kern/drivers/dev/ether.c
+++ b/kern/drivers/dev/ether.c
@@ -46,7 +46,7 @@
}
enum {
- Type8021Q = 0x8100, /* value of type field for 802.1[pQ] tags */
+ Type8021Q = 0x8100, /* value of type field for 802.1[pQ] tags */
};
static struct ether *etherxx[MaxEther]; /* real controllers */
@@ -117,7 +117,7 @@
}
static struct walkqid *etherwalk(struct chan *chan, struct chan *nchan,
- char **name, unsigned int nname)
+ char **name, unsigned int nname)
{
ERRSTACK(1);
struct walkqid *wq;
@@ -312,8 +312,8 @@
ether->inpackets++;
pkt = (struct etherpkt *)bp->rp;
- /* TODO: we might need to assert more for higher layers, or otherwise deal
- * with extra data. */
+ /* TODO: we might need to assert more for higher layers, or otherwise
+ * deal with extra data. */
assert(BHLEN(bp) >= offsetof(struct etherpkt, data));
type = (pkt->type[0] << 8) | pkt->type[1];
if (type == Type8021Q && ether->nvlan) {
@@ -322,9 +322,11 @@
for (i = 0; i < ARRAY_SIZE(ether->vlans); i++) {
vlan = ether->vlans[i];
if (vlan != NULL && vlan->vlanid == vlanid) {
- /* might have a problem with extra data here */
+ /* might have a problem with extra data
+ * here */
assert(BHLEN(bp) >= 4 + 2 * Eaddrlen);
- memmove(bp->rp + 4, bp->rp, 2 * Eaddrlen);
+ memmove(bp->rp + 4, bp->rp,
+ 2 * Eaddrlen);
bp->rp += 4;
return etheriq(vlan, bp, fromwire);
}
@@ -434,7 +436,8 @@
bp = padblock(bp, 2 + 2);
memmove(bp->rp, bp->rp + 4, 2 * Eaddrlen);
hnputs(bp->rp + 2 * Eaddrlen, Type8021Q);
- hnputs(bp->rp + 2 * Eaddrlen + 2, ether->vlanid & 0xFFF); /* prio:3 0:1 vid:12 */
+ /* prio:3 0:1 vid:12 */
+ hnputs(bp->rp + 2 * Eaddrlen + 2, ether->vlanid & 0xFFF);
ether = ether->ctlr;
}
@@ -554,8 +557,8 @@
int i;
cb = parsecmd(buf, n);
- if (cb->nf >= 2
- && strcmp(cb->f[0], "ea") == 0 && parseether(ea, cb->f[1]) == 0) {
+ if (cb->nf >= 2 && strcmp(cb->f[0], "ea") == 0 &&
+ parseether(ea, cb->f[1]) == 0) {
kfree(cb);
memmove(ether->ea, ea, Eaddrlen);
memmove(ether->addr, ether->ea, Eaddrlen);
@@ -613,7 +616,8 @@
rwinit(&vlan->rwlock);
qlock_init(&vlan->vlq);
netifinit(vlan, name, Ntypes, ether->limit);
- ether->vlans[fid] = vlan; /* id is still zero, can't be matched */
+ /* id is still zero, can't be matched */
+ ether->vlans[fid] = vlan;
ether->nvlan++;
} else
memmove(vlan->name, name, KNAMELEN - 1);
@@ -702,10 +706,11 @@
/* looked like irq type, we don't have these yet */
//ether->netif.itype = -1;
- /* TODO: looks like they expected some init to be done here. at the
- * very least, ether->type is 0 right now, and needs to be set. looking
- * around online, it seems to find out ether config settings, so that we
- * can set some flags in the opt parseing below. */
+ /* TODO: looks like they expected some init to be done here. at
+ * the very least, ether->type is 0 right now, and needs to be
+ * set. looking around online, it seems to find out ether
+ * config settings, so that we can set some flags in the opt
+ * parseing below. */
//if(archether(ctlrno, ether) <= 0)
// continue;
@@ -715,45 +720,46 @@
continue;
for (i = 0; i < ether->nopt; i++) {
if (cistrncmp(ether->opt[i], "ea=", 3) == 0) {
- if (parseether(ether->ea, ðer->opt[i][3]) == -1)
+ if (parseether(ether->ea,
+ ðer->opt[i][3]) == -1)
memset(ether->ea, 0, Eaddrlen);
- } else if (cistrcmp(ether->opt[i], "fullduplex") == 0 ||
- cistrcmp(ether->opt[i], "10BASE-TFD") == 0)
+ } else if (cistrcmp(ether->opt[i], "fullduplex")
+ == 0 || cistrcmp(ether->opt[i],
+ "10BASE-TFD") == 0)
ether->fullduplex = 1;
- else if (cistrcmp(ether->opt[i], "100BASE-TXFD") == 0)
+ else if (cistrcmp(ether->opt[i], "100BASE-TXFD")
+ == 0)
ether->mbps = 100;
}
#endif
if (cards[n].reset(ether))
continue;
- /* might be fucked a bit - reset() doesn't know the type. might not
- * even matter, except for debugging. */
+ /* might be fucked a bit - reset() doesn't know the
+ * type. might not even matter, except for debugging */
ether->type = cards[n].type;
snprintf(name, sizeof(name), "ether%d", ctlrno);
i = snprintf(buf, sizeof(buf),
- "#l%d: %s: %dMbps port 0x%x irq %u", ctlrno,
- ether->type, ether->mbps,
- ether->port,
- ether->irq);
+ "#l%d: %s: %dMbps port 0x%x irq %u",
+ ctlrno, ether->type, ether->mbps,
+ ether->port, ether->irq);
/* Looks like this is for printing MMIO addrs */
#if 0
if (ether->mem)
- i += snprintf(buf + i, sizeof(buf) - i, " addr 0x%lx",
- PADDR(ether->mem));
+ i += snprintf(buf + i, sizeof(buf) - i,
+ " addr 0x%lx", PADDR(ether->mem));
if (ether->size)
- i += snprintf(buf + i, sizeof(buf) - i, " size 0x%lx",
- ether->size);
+ i += snprintf(buf + i, sizeof(buf) - i,
+ " size 0x%lx", ether->size);
#endif
i += snprintf(buf + i, sizeof(buf) - i,
- ": %02.2x:%02.2x:%02.2x:%02.2x:%02.2x:%02.2x",
- ether->ea[0], ether->ea[1], ether->ea[2],
- ether->ea[3], ether->ea[4], ether->ea[5]);
+ ": %02.2x:%02.2x:%02.2x:%02.2x:%02.2x:%02.2x",
+ ether->ea[0], ether->ea[1], ether->ea[2],
+ ether->ea[3], ether->ea[4], ether->ea[5]);
snprintf(buf + i, sizeof(buf) - i, "\n");
printk(buf);
switch (ether->mbps) {
-
case 1 ... 99:
qsize = 64 * 1024;
break;
@@ -790,18 +796,21 @@
struct ether *ether;
/* TODO: fix etherpower. locking and ether->readers are broken. */
- warn("%s needs attention. had a rough porting from inferno", __FUNCTION__);
+ warn("%s needs attention. had a rough porting from inferno",
+ __FUNCTION__);
for (i = 0; i < MaxEther; i++) {
if ((ether = etherxx[i]) == NULL || ether->power == NULL)
continue;
if (on) {
- /* brho: not sure what they are doing. there seem to be certain
- * assumptions about calling etherpower. i think they are using
- * canrlock to see if the lock is currently writelocked. and if it
- * was not lockable, they would assume they had the write lock and
- * could unlock. this is super fucked up. */
+ /* brho: not sure what they are doing. there seem to be
+ * certain assumptions about calling etherpower. i
+ * think they are using canrlock to see if the lock is
+ * currently writelocked. and if it was not lockable,
+ * they would assume they had the write lock and could
+ * unlock. this is super fucked up. */
if (canrlock(ðer->rwlock)) {
- runlock(ðer->rwlock); // brho added this
+ // brho added this
+ runlock(ðer->rwlock);
continue;
}
if (ether->power != NULL)
diff --git a/kern/drivers/dev/eventfd.c b/kern/drivers/dev/eventfd.c
index a46e6c9..479666c 100644
--- a/kern/drivers/dev/eventfd.c
+++ b/kern/drivers/dev/eventfd.c
@@ -40,26 +40,27 @@
};
enum {
- EFD_SEMAPHORE = 1 << 0,
- EFD_MAX_VAL = (unsigned long)(-2), // i.e. 0xfffffffffffffffe
+ EFD_SEMAPHORE = 1 << 0,
+ EFD_MAX_VAL = (unsigned long)(-2), // i.e. 0xfffffffffffffffe
};
struct eventfd {
- int flags;
- atomic_t counter;
- struct fdtap_slist fd_taps;
- spinlock_t tap_lock;
- struct rendez rv_readers;
- struct rendez rv_writers;
- struct kref refcnt;
+ int flags;
+ atomic_t counter;
+ struct fdtap_slist fd_taps;
+ spinlock_t tap_lock;
+ struct rendez rv_readers;
+ struct rendez rv_writers;
+ struct kref refcnt;
};
static void efd_release(struct kref *kref)
{
struct eventfd *efd = container_of(kref, struct eventfd, refcnt);
- /* All FDs with taps should be closed before we decreffed all the chans */
+
+ /* All FDs with taps must be closed before we decreffed all the chans */
assert(SLIST_EMPTY(&efd->fd_taps));
kfree(efd);
}
@@ -75,42 +76,43 @@
spinlock_init(&efd->tap_lock);
rendez_init(&efd->rv_readers);
rendez_init(&efd->rv_writers);
- /* Attach and walk are the two sources of chans. Each returns a refcnt'd
- * object, for the most part. */
+ /* Attach and walk are the two sources of chans. Each returns a
+ * refcnt'd object, for the most part. */
kref_init(&efd->refcnt, efd_release, 1);
/* nothing special in the qid to ID this eventfd. the main thing is the
* aux. we could put a debugging ID in the path like pipe. */
mkqid(&c->qid, Qdir, 0, QTDIR);
c->aux = efd;
- /* just to be fancy and remove a syscall, if they pass spec == "sem", then
- * we'll treat them as being in semaphore mode. */
+ /* just to be fancy and remove a syscall, if they pass spec == "sem",
+ * then we'll treat them as being in semaphore mode. */
if (!strcmp(spec, "sem"))
efd->flags |= EFD_SEMAPHORE;
return c;
}
static struct walkqid *efd_walk(struct chan *c, struct chan *nc, char **name,
- unsigned int nname)
+ unsigned int nname)
{
struct walkqid *wq;
struct eventfd *efd = c->aux;
wq = devwalk(c, nc, name, nname, efd_dir, ARRAY_SIZE(efd_dir), devgen);
- /* Walk is a source of a distinct chan from this device. The other source
- * is attach. Once created, these chans will eventually be closed, and when
- * they close, they will decref their aux, efd. All chans within this
- * *instance* of eventfd share the same efd. Each one will have one refcnt.
- * Each chan may also have several copies of its pointer out there (e.g. FD
- * dup), all of which have their own *chan* refcnt.
+ /* Walk is a source of a distinct chan from this device. The other
+ * source is attach. Once created, these chans will eventually be
+ * closed, and when they close, they will decref their aux, efd. All
+ * chans within this *instance* of eventfd share the same efd. Each one
+ * will have one refcnt. Each chan may also have several copies of its
+ * pointer out there (e.g. FD dup), all of which have their own *chan*
+ * refcnt.
*
- * All of the above applies on successful walks that found all nname parts
- * of the path. A mid-success is wq: we got something. wq->clone means we
- * got to the end and the "big walk" considers this a success.
+ * All of the above applies on successful walks that found all nname
+ * parts of the path. A mid-success is wq: we got something. wq->clone
+ * means we got to the end and the "big walk" considers this a success.
*
- * There is a slight chance the new chan is the same as our original chan
- * (if nc == c when we're called). In which case, there's only one chan.
- * The number of refs on efd == the number of distinct chans within this
- * instance of #eventfd. */
+ * There is a slight chance the new chan is the same as our original
+ * chan (if nc == c when we're called). In which case, there's only one
+ * chan. The number of refs on efd == the number of distinct chans
+ * within this instance of #eventfd. */
if (wq != NULL && wq->clone != NULL && wq->clone != c)
kref_get(&efd->refcnt, 1);
return wq;
@@ -130,6 +132,7 @@
static void efd_close(struct chan *c)
{
struct eventfd *efd = c->aux;
+
/* Here's where we put the ref from attach and successful walks */
kref_put(&efd->refcnt);
}
@@ -137,6 +140,7 @@
static void efd_fire_taps(struct eventfd *efd, int filter)
{
struct fd_tap *tap_i;
+
if (SLIST_EMPTY(&efd->fd_taps))
return;
/* We're not expecting many FD taps, so it's not worth splitting readers
@@ -151,6 +155,7 @@
static int has_counts(void *arg)
{
struct eventfd *efd = arg;
+
return atomic_read(&efd->counter) != 0;
}
@@ -158,11 +163,13 @@
static unsigned long efd_read_efd(struct eventfd *efd, struct chan *c)
{
unsigned long old_count, new_count, ret;
+
while (1) {
old_count = atomic_read(&efd->counter);
if (!old_count) {
if (c->flag & O_NONBLOCK)
- error(EAGAIN, "Would block on #%s read", devname());
+ error(EAGAIN, "Would block on #%s read",
+ devname());
rendez_sleep(&efd->rv_readers, has_counts, efd);
} else {
if (efd->flags & EFD_SEMAPHORE) {
@@ -187,17 +194,16 @@
struct eventfd *efd = c->aux;
switch (c->qid.path) {
- case Qdir:
- return devdirread(c, ubuf, n, efd_dir, ARRAY_SIZE(efd_dir),
- devgen);
- case Qctl:
- return readnum(offset, ubuf, n, efd->flags, NUMSIZE32);
- case Qefd:
- /* ignoring the chan offset for Qefd */
- return readnum(0, ubuf, n, efd_read_efd(efd, c),
- NUMSIZE64);
- default:
- panic("Bad Qid %p!", c->qid.path);
+ case Qdir:
+ return devdirread(c, ubuf, n, efd_dir, ARRAY_SIZE(efd_dir),
+ devgen);
+ case Qctl:
+ return readnum(offset, ubuf, n, efd->flags, NUMSIZE32);
+ case Qefd:
+ /* ignoring the chan offset for Qefd */
+ return readnum(0, ubuf, n, efd_read_efd(efd, c), NUMSIZE64);
+ default:
+ panic("Bad Qid %p!", c->qid.path);
}
return -1;
}
@@ -213,12 +219,14 @@
struct chan *c)
{
unsigned long old_count, new_count;
+
while (1) {
old_count = atomic_read(&efd->counter);
new_count = old_count + add_to;
if (new_count > EFD_MAX_VAL) {
if (c->flag & O_NONBLOCK)
- error(EAGAIN, "Would block on #%s write", devname());
+ error(EAGAIN, "Would block on #%s write",
+ devname());
rendez_sleep(&efd->rv_writers, has_room, efd);
} else {
if (atomic_cas(&efd->counter, old_count, new_count))
@@ -237,26 +245,26 @@
char num64[NUMSIZE64];
switch (c->qid.path) {
- case Qctl:
- /* If we want to allow runtime changing of settings, we can do it
- * here. */
- error(EFAIL, "No #%s ctl commands supported", devname());
- break;
- case Qefd:
- /* We want to give strtoul a null-terminated buf (can't handle
- * arbitrary user strings). Ignoring the chan offset too. */
- if (n > sizeof(num64))
- error(EAGAIN, "attempted to write %d chars, max %d", n,
- sizeof(num64));
- memcpy(num64, ubuf, n);
- num64[n] = 0; /* enforce trailing 0 */
- write_val = strtoul(num64, 0, 0);
- if (write_val == (unsigned long)(-1))
- error(EFAIL, "Eventfd write must not be -1");
- efd_write_efd(efd, write_val, c);
- break;
- default:
- panic("Bad Qid %p!", c->qid.path);
+ case Qctl:
+ /* If we want to allow runtime changing of settings, we can do
+ * it here. */
+ error(EFAIL, "No #%s ctl commands supported", devname());
+ break;
+ case Qefd:
+ /* We want to give strtoul a null-terminated buf (can't handle
+ * arbitrary user strings). Ignoring the chan offset too. */
+ if (n > sizeof(num64))
+ error(EAGAIN, "attempted to write %d chars, max %d", n,
+ sizeof(num64));
+ memcpy(num64, ubuf, n);
+ num64[n] = 0; /* enforce trailing 0 */
+ write_val = strtoul(num64, 0, 0);
+ if (write_val == (unsigned long)(-1))
+ error(EFAIL, "Eventfd write must not be -1");
+ efd_write_efd(efd, write_val, c);
+ break;
+ default:
+ panic("Bad Qid %p!", c->qid.path);
}
return n;
}
@@ -266,7 +274,8 @@
struct eventfd *efd = c->aux;
snprintf(ret, ret_l, "QID type %s, flags %p, counter %p",
- efd_dir[c->qid.path].name, efd->flags, atomic_read(&efd->counter));
+ efd_dir[c->qid.path].name, efd->flags,
+ atomic_read(&efd->counter));
return ret;
}
@@ -275,42 +284,42 @@
struct eventfd *efd = c->aux;
int ret;
- /* HANGUP, ERROR, and PRIORITY will never fire, but people can ask for them.
- * We don't actually support HANGUP, but epoll implies it. Linux's eventfd
- * cand have ERROR, so apps can ask for it. Likewise, priority is
- * meaningless for us, but sometimes people ask for it. */
- #define EFD_LEGAL_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_WRITABLE | \
- FDTAP_FILT_HANGUP | FDTAP_FILT_PRIORITY | \
- FDTAP_FILT_ERROR)
+ /* HANGUP, ERROR, and PRIORITY will never fire, but people can ask for
+ * them. We don't actually support HANGUP, but epoll implies it.
+ * Linux's eventfd cand have ERROR, so apps can ask for it. Likewise,
+ * priority is meaningless for us, but sometimes people ask for it. */
+#define EFD_LEGAL_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_WRITABLE | \
+ FDTAP_FILT_HANGUP | FDTAP_FILT_PRIORITY | \
+ FDTAP_FILT_ERROR)
switch (c->qid.path) {
- case Qefd:
- if (tap->filter & ~EFD_LEGAL_TAPS) {
- set_error(ENOSYS, "Unsupported #%s tap, must be %p", devname(),
- EFD_LEGAL_TAPS);
- return -1;
- }
- spin_lock(&efd->tap_lock);
- switch (cmd) {
- case (FDTAP_CMD_ADD):
- SLIST_INSERT_HEAD(&efd->fd_taps, tap, link);
- ret = 0;
- break;
- case (FDTAP_CMD_REM):
- SLIST_REMOVE(&efd->fd_taps, tap, fd_tap, link);
- ret = 0;
- break;
- default:
- set_error(ENOSYS, "Unsupported #%s tap command %p",
- devname(), cmd);
- ret = -1;
- }
- spin_unlock(&efd->tap_lock);
- return ret;
- default:
- set_error(ENOSYS, "Can't tap #%s file type %d", devname(),
- c->qid.path);
+ case Qefd:
+ if (tap->filter & ~EFD_LEGAL_TAPS) {
+ set_error(ENOSYS, "Unsupported #%s tap, must be %p",
+ devname(), EFD_LEGAL_TAPS);
return -1;
+ }
+ spin_lock(&efd->tap_lock);
+ switch (cmd) {
+ case (FDTAP_CMD_ADD):
+ SLIST_INSERT_HEAD(&efd->fd_taps, tap, link);
+ ret = 0;
+ break;
+ case (FDTAP_CMD_REM):
+ SLIST_REMOVE(&efd->fd_taps, tap, fd_tap, link);
+ ret = 0;
+ break;
+ default:
+ set_error(ENOSYS, "Unsupported #%s tap command %p",
+ devname(), cmd);
+ ret = -1;
+ }
+ spin_unlock(&efd->tap_lock);
+ return ret;
+ default:
+ set_error(ENOSYS, "Can't tap #%s file type %d", devname(),
+ c->qid.path);
+ return -1;
}
}
diff --git a/kern/drivers/dev/gtfs.c b/kern/drivers/dev/gtfs.c
index 9f82c77..96ac2e4 100644
--- a/kern/drivers/dev/gtfs.c
+++ b/kern/drivers/dev/gtfs.c
@@ -25,7 +25,7 @@
struct gtfs {
struct tree_filesystem tfs;
- struct kref users;
+ struct kref users;
};
/* Blob hanging off the fs_file->priv. The backend chans are only accessed,
@@ -51,13 +51,13 @@
* Also note that you can't trust be_length for directories. You'll often get
* 4096 or 0, depending on the 9p server you're talking to. */
struct gtfs_priv {
- struct chan *be_walk; /* never opened */
- struct chan *be_read;
- struct chan *be_write;
- uint64_t be_length;
- uint32_t be_mode;
- struct timespec be_mtime;
- bool was_removed;
+ struct chan *be_walk; /* never opened */
+ struct chan *be_read;
+ struct chan *be_write;
+ uint64_t be_length;
+ uint32_t be_mode;
+ struct timespec be_mtime;
+ bool was_removed;
};
static inline struct gtfs_priv *fsf_to_gtfs_priv(struct fs_file *f)
@@ -146,10 +146,10 @@
nexterror();
}
wstat_dir(f, &dir);
- /* We set these after the wstat succeeds. If we set them earlier, we'd have
- * to roll back. Remember the invariant: the be_values match the backend's
- * file's values. We should be able to stat be_walk and check these (though
- * the 9p server might muck with atime/mtime). */
+ /* We set these after the wstat succeeds. If we set them earlier, we'd
+ * have to roll back. Remember the invariant: the be_values match the
+ * backend's file's values. We should be able to stat be_walk and check
+ * these (though the 9p server might muck with atime/mtime). */
if (f->dir.length != gp->be_length)
gp->be_length = f->dir.length;
if (f->dir.mode != gp->be_mode)
@@ -164,18 +164,19 @@
static void writeback_file(struct fs_file *f)
{
sync_metadata(f);
- /* This is a lockless peak. Once a file is dirtied, we never undirty it.
- * To do so, we need the file qlock (not a big deal, though that may replace
- * the PM qlock), and we still need to handle/scan mmaps. Specifically, we
- * only dirty when an mmap attaches (PROT_WRITE and MAP_SHARED), but we
- * don't know if an existing mapping has caused more dirtying (an mmap can
- * re-dirty then detach before our next writeback). That usually requires a
- * scan. This is all an optimization to avoid scanning the entire PM's
- * pages for whether or not they are dirty.
+ /* This is a lockless peak. Once a file is dirtied, we never undirty
+ * it. To do so, we need the file qlock (not a big deal, though that
+ * may replace the PM qlock), and we still need to handle/scan mmaps.
+ * Specifically, we only dirty when an mmap attaches (PROT_WRITE and
+ * MAP_SHARED), but we don't know if an existing mapping has caused more
+ * dirtying (an mmap can re-dirty then detach before our next
+ * writeback). That usually requires a scan. This is all an
+ * optimization to avoid scanning the entire PM's pages for whether or
+ * not they are dirty.
*
- * Also, our writeback pm op grabs the file's qlock. So be careful; though
- * we could use another qlock, since we're mostly protecting backend state.
- */
+ * Also, our writeback pm op grabs the file's qlock. So be careful;
+ * though we could use another qlock, since we're mostly protecting
+ * backend state. */
if (qid_is_file(f->dir.qid) && (f->flags & FSF_DIRTY))
pm_writeback_pages(f->pm);
}
@@ -245,9 +246,9 @@
qunlock(&f->qlock);
nexterror();
}
- /* Readers and writers both need be_read. With fs files you can't have a
- * writable-only file, since we need to load the page into the page cache,
- * which is a readpage. */
+ /* Readers and writers both need be_read. With fs files you can't have
+ * a writable-only file, since we need to load the page into the page
+ * cache, which is a readpage. */
if (!gp->be_read)
gp->be_read = cclone_and_open(gp->be_walk, O_READ);
if (!gp->be_write && (omode & O_WRITE))
@@ -258,8 +259,8 @@
static struct chan *gtfs_open(struct chan *c, int omode)
{
- /* truncate can happen before we setup the be_chans. if we need those, we
- * can swap the order */
+ /* truncate can happen before we setup the be_chans. if we need those,
+ * we can swap the order */
c = tree_chan_open(c, omode);
setup_be_chans(c, omode);
return c;
@@ -270,8 +271,8 @@
char *ext)
{
tree_chan_create(c, name, omode, perm, ext);
- /* We have to setup *after* create, since it moves the chan from the parent
- * to the new file. */
+ /* We have to setup *after* create, since it moves the chan from the
+ * parent to the new file. */
setup_be_chans(c, omode);
}
@@ -301,9 +302,9 @@
size_t ret;
ret = tree_chan_wstat(c, m_buf, m_buf_sz);
- /* Tell the backend so that any metadata changes take effect immediately.
- * Consider chmod +w. We need to tell the 9p server so that it will allow
- * future accesses. */
+ /* Tell the backend so that any metadata changes take effect
+ * immediately. Consider chmod +w. We need to tell the 9p server so
+ * that it will allow future accesses. */
sync_metadata(&chan_to_tree_file(c)->file);
return ret;
}
@@ -424,25 +425,27 @@
struct gtfs_priv *gp = tf_to_gtfs_priv(child);
struct chan *be_walk = gp->be_walk;
- /* Remove clunks the be_walk chan/fid. if it succeeded (and I think even if
- * it didn't), we shouldn't close that fid again, which is what will happen
- * soon after this function. The TF code calls unlink, then when the last
- * ref closes the TF, it'll get freed and we'll call back to gtfs_tf_free().
+ /* Remove clunks the be_walk chan/fid. if it succeeded (and I think
+ * even if it didn't), we shouldn't close that fid again, which is what
+ * will happen soon after this function. The TF code calls unlink, then
+ * when the last ref closes the TF, it'll get freed and we'll call back
+ * to gtfs_tf_free().
*
* This is the same issue we run into with all of the device remove ops
- * where we want to refcnt something hanging off e.g. c->aux. In 9p, you're
- * not supposed to close a chan/fid that was already removed.
+ * where we want to refcnt something hanging off e.g. c->aux. In 9p,
+ * you're not supposed to close a chan/fid that was already removed.
*
- * Now here's the weird thing. We can close the be_walk chan after remove,
- * but it's possible that someone has walked and perhaps opened a frontend
- * chan + TF, but hasn't done a read yet. So someone might want to set up
- * be_read, but they can't due to be_walk being closed. We could give them
- * a 'phase error' (one of 9p's errors for I/O on a removed file).
+ * Now here's the weird thing. We can close the be_walk chan after
+ * remove, but it's possible that someone has walked and perhaps opened
+ * a frontend chan + TF, but hasn't done a read yet. So someone might
+ * want to set up be_read, but they can't due to be_walk being closed.
+ * We could give them a 'phase error' (one of 9p's errors for I/O on a
+ * removed file).
*
- * Alternatively, we can mark the gtfs_priv so that when we do free it, we
- * skip the dev.remove, similar to what sysremove() does. That's probably
- * easier. This is technically racy, but we know that the release/free
- * method won't be called until we return. */
+ * Alternatively, we can mark the gtfs_priv so that when we do free it,
+ * we skip the dev.remove, similar to what sysremove() does. That's
+ * probably easier. This is technically racy, but we know that the
+ * release/free method won't be called until we return. */
gp->was_removed = true;
devtab[be_walk->type].remove(be_walk);
}
@@ -457,15 +460,17 @@
struct chan *be_walk = tf_to_gtfs_priv(parent)->be_walk;
struct chan *child_be_walk;
- wq = devtab[be_walk->type].walk(be_walk, NULL, &child->file.dir.name, 1);
+ wq = devtab[be_walk->type].walk(be_walk, NULL, &child->file.dir.name,
+ 1);
if (!wq || !wq->clone) {
kfree(wq);
- /* This isn't racy, since the child isn't linked to the tree yet */
+ /* This isn't racy, since the child isn't linked to the tree
+ * yet. */
child->flags |= TF_F_NEGATIVE | TF_F_HAS_BEEN_USED;
return;
}
- /* walk shouldn't give us the same chan struct since we gave it a name and a
- * NULL nc. */
+ /* walk shouldn't give us the same chan struct since we gave it a name
+ * and a NULL nc. */
assert(wq->clone != be_walk);
/* only gave it one name, and it didn't fail. */
assert(wq->nqid == 1);
@@ -489,10 +494,10 @@
devtab[c->type].create(c, tree_file_to_name(child), 0, perm,
child->file.dir.ext);
/* The chan c is opened, which we don't want. We can't cclone it either
- * (since it is opened). All we can do is have the parent walk again so we
- * can get the child's unopened be_walk chan. Conveniently, that's
- * basically a lookup, so create is really two things: make it, then look it
- * up from the backend. */
+ * (since it is opened). All we can do is have the parent walk again so
+ * we can get the child's unopened be_walk chan. Conveniently, that's
+ * basically a lookup, so create is really two things: make it, then
+ * look it up from the backend. */
cclose(c);
poperror();
if (waserror()) {
@@ -521,8 +526,8 @@
struct chan *np_c = tf_to_gtfs_priv(new_parent)->be_walk;
if (!devtab[tf_c->type].rename) {
- /* 9p can handle intra-directory renames, though some Akaros #devices
- * might throw. */
+ /* 9p can handle intra-directory renames, though some Akaros
+ * #devices might throw. */
if (old_parent == new_parent) {
gtfs_wstat_rename(&tf->file, name);
return;
@@ -541,8 +546,9 @@
/* Any read should work, but there might be issues asking for something
* smaller than a dir.
*
- * Note we use the unlocked read here. The fs_file's qlock is held by our
- * caller, and we reuse that qlock for the sync for reading/writing. */
+ * Note we use the unlocked read here. The fs_file's qlock is held by
+ * our caller, and we reuse that qlock for the sync for reading/writing.
+ */
return __gtfs_fsf_read(&parent->file, dir, sizeof(struct dir), 0) > 0;
}
@@ -570,10 +576,10 @@
poperror();
return -get_errno();
}
- /* If offset is beyond the length of the file, the 9p device/server should
- * return 0. We'll just init an empty page. The length on the frontend (in
- * the fsf->dir.length) will be adjusted. The backend will hear about it on
- * the next sync. */
+ /* If offset is beyond the length of the file, the 9p device/server
+ * should return 0. We'll just init an empty page. The length on the
+ * frontend (in the fsf->dir.length) will be adjusted. The backend will
+ * hear about it on the next sync. */
ret = gtfs_fsf_read(pm->pm_file, kva, PGSIZE, offset);
poperror();
if (ret < PGSIZE)
@@ -630,7 +636,8 @@
void *zeros;
if (PGOFF(begin) || PGOFF(end))
- error(EINVAL, "zero_fill had unaligned begin (%p) or end (%p)\n",
+ error(EINVAL,
+ "zero_fill had unaligned begin (%p) or end (%p)\n",
begin, end);
zeros = kpages_zalloc(PGSIZE, MEM_WAIT);
if (waserror()) {
@@ -734,8 +741,8 @@
frontend = devattach(devname(), 0);
if (waserror()) {
- /* same as #mnt - don't cclose, since we don't want to devtab close, and
- * we know the ref == 1 here. */
+ /* same as #mnt - don't cclose, since we don't want to devtab
+ * close, and we know the ref == 1 here. */
chanfree(frontend);
nexterror();
}
@@ -744,11 +751,12 @@
* These come from attaches and successful, 'moving' walks. */
kref_init(>fs->users, gtfs_release, 1);
tfs = (struct tree_filesystem*)gtfs;
- /* This gives us one ref on root, released during gtfs_release(). name is
- * set to ".", though that gets overwritten during coupling. */
+ /* This gives us one ref on root, released during gtfs_release(). name
+ * is set to ".", though that gets overwritten during coupling. */
tfs_init(tfs);
if (waserror()) {
- /* don't consume the backend ref on error, caller expects to have it */
+ /* don't consume the backend ref on error, caller expects to
+ * have it */
tf_to_gtfs_priv(tfs->root)->be_walk = NULL;
/* ref from tfs_init. this should free the TF. */
tf_kref_put(tfs->root);
@@ -793,13 +801,13 @@
/* Under memory pressure, there are a bunch of things we can do. */
static void gtfs_free_memory(struct gtfs *gtfs)
{
- /* This attempts to remove every file from the LRU. It'll write back dirty
- * files, then if they haven't been used since we started, it'll delete the
- * frontend TF, which will delete the entire page cache entry. The heavy
- * lifting is done by TF code. */
+ /* This attempts to remove every file from the LRU. It'll write back
+ * dirty files, then if they haven't been used since we started, it'll
+ * delete the frontend TF, which will delete the entire page cache
+ * entry. The heavy lifting is done by TF code. */
tfs_lru_for_each(>fs->tfs, lru_prune_cb, -1);
- /* This drops the negative TFs. It's not a huge deal, since they are small,
- * but perhaps it'll help. */
+ /* This drops the negative TFs. It's not a huge deal, since they are
+ * small, but perhaps it'll help. */
tfs_lru_prune_neg(>fs->tfs);
/* This will attempt to free memory from all files in the frontend,
* regardless of whether or not they are in use. This might help if you
diff --git a/kern/drivers/dev/kfs.c b/kern/drivers/dev/kfs.c
index aedf7a9..b8cc09d 100644
--- a/kern/drivers/dev/kfs.c
+++ b/kern/drivers/dev/kfs.c
@@ -19,7 +19,7 @@
struct kfs {
struct tree_filesystem tfs;
- atomic_t qid;
+ atomic_t qid;
} kfs;
static uint64_t kfs_get_qid_path(void)
@@ -51,9 +51,10 @@
fs_file_init_dir(&tf->file, dir_type, dir_dev, user, perm);
dir->qid.path = kfs_get_qid_path();
dir->qid.vers = 0;
- /* This is the "+1 for existing" ref. There is no backing store for the FS,
- * such as a disk or 9p, so we can't get rid of a file until it is unlinked
- * and decreffed. Note that KFS doesn't use pruners or anything else. */
+ /* This is the "+1 for existing" ref. There is no backing store for the
+ * FS, such as a disk or 9p, so we can't get rid of a file until it is
+ * unlinked and decreffed. Note that KFS doesn't use pruners or
+ * anything else. */
__kref_get(&tf->kref, 1);
}
@@ -69,14 +70,14 @@
struct tree_file *new_parent, const char *name,
int flags)
{
- /* We don't have a backend, so we don't need to do anything additional for
- * rename. */
+ /* We don't have a backend, so we don't need to do anything additional
+ * for rename. */
}
static bool kfs_tf_has_children(struct tree_file *parent)
{
- /* The tree_file parent list is complete and not merely a cache for a real
- * backend. */
+ /* The tree_file parent list is complete and not merely a cache for a
+ * real backend. */
return !list_empty(&parent->children);
}
@@ -97,10 +98,10 @@
{
memset(page2kva(pg), 0, PGSIZE);
atomic_or(&pg->pg_flags, PG_UPTODATE);
- /* Pretend that we blocked while filing this page. This catches a lot of
- * bugs. It does slightly slow down the kernel, but it's only when filling
- * the page cache, and considering we are using a RAMFS, you shouldn't
- * measure things that actually rely on KFS's performance. */
+ /* Pretend that we blocked while filing this page. This catches a lot
+ * of bugs. It does slightly slow down the kernel, but it's only when
+ * filling the page cache, and considering we are using a RAMFS, you
+ * shouldn't measure things that actually rely on KFS's performance. */
kthread_usleep(1);
return 0;
}
@@ -142,7 +143,8 @@
poperror();
return NULL;
}
- c = namec_from(root, path, Acreate, O_EXCL, DMDIR | c_bhdr->c_mode, NULL);
+ c = namec_from(root, path, Acreate, O_EXCL, DMDIR | c_bhdr->c_mode,
+ NULL);
poperror();
return c;
}
@@ -183,7 +185,8 @@
poperror();
return NULL;
}
- c = namec_from(root, path, Acreate, O_EXCL | O_RDWR, c_bhdr->c_mode, NULL);
+ c = namec_from(root, path, Acreate, O_EXCL | O_RDWR, c_bhdr->c_mode,
+ NULL);
poperror();
if (waserror()) {
warn("failed to modify %s", path);
@@ -234,8 +237,8 @@
ts.tv_sec = c_bhdr->c_mtime;
ts.tv_nsec = 0;
/* Lockless */
- __set_acmtime_to(&tf->file, FSF_ATIME | FSF_BTIME | FSF_CTIME | FSF_MTIME,
- &ts);
+ __set_acmtime_to(&tf->file, FSF_ATIME | FSF_BTIME | FSF_CTIME |
+ FSF_MTIME, &ts);
/* TODO: consider UID/GID. Right now, everything is owned by eve. */
cclose(c);
return 0;
@@ -286,8 +289,8 @@
tfs->fs_ops = kfs_fs_ops;
/* Note this gives us the "+1 for existing" ref on tfs->root. */
__kfs_tf_init(tfs->root, &kfs_devtab - devtab, 0, &eve, DMDIR | 0777);
- /* Other devices might want to create things like kthreads that run the LRU
- * pruner or PM sweeper. */
+ /* Other devices might want to create things like kthreads that run the
+ * LRU pruner or PM sweeper. */
kfs_get_cpio_info(ci);
kfs_extract_cpio(ci);
kfs_free_cpio(ci);
diff --git a/kern/drivers/dev/kprof.c b/kern/drivers/dev/kprof.c
index 8bdf01a..9a6bd66 100644
--- a/kern/drivers/dev/kprof.c
+++ b/kern/drivers/dev/kprof.c
@@ -56,13 +56,13 @@
struct dev kprofdevtab;
struct dirtab kproftab[] = {
- {".", {Kprofdirqid, 0, QTDIR}, 0, DMDIR|0550},
- {"kpdata", {Kprofdataqid}, 0, 0600},
- {"kpctl", {Kprofctlqid}, 0, 0600},
+ {".", {Kprofdirqid, 0, QTDIR},0, DMDIR|0550},
+ {"kpdata", {Kprofdataqid}, 0, 0600},
+ {"kpctl", {Kprofctlqid}, 0, 0600},
{"kptrace_ctl", {Kptracectlqid}, 0, 0660},
- {"kptrace", {Kptraceqid}, 0, 0600},
- {"kprintx", {Kprintxqid}, 0, 0600},
- {"mpstat", {Kmpstatqid}, 0, 0600},
+ {"kptrace", {Kptraceqid}, 0, 0600},
+ {"kprintx", {Kprintxqid}, 0, 0600},
+ {"mpstat", {Kmpstatqid}, 0, 0600},
{"mpstat-raw", {Kmpstatrawqid}, 0, 0600},
};
@@ -186,7 +186,8 @@
static struct walkqid *kprof_walk(struct chan *c, struct chan *nc, char **name,
unsigned int nname)
{
- return devwalk(c, nc, name, nname, kproftab, ARRAY_SIZE(kproftab), devgen);
+ return devwalk(c, nc, name, nname, kproftab, ARRAY_SIZE(kproftab),
+ devgen);
}
static size_t kprof_profdata_size(void)
@@ -215,16 +216,17 @@
}
switch ((int) c->qid.path) {
case Kprofctlqid:
- /* We have one global profiler. Only one FD may be opened at a time for
- * it. If we ever have separate profilers, we can create the profiler
- * here, and every open would get a separate instance. */
+ /* We have one global profiler. Only one FD may be opened at a
+ * time for it. If we ever have separate profilers, we can
+ * create the profiler here, and every open would get a separate
+ * instance. */
qlock(&kprof.lock);
if (kprof.opened) {
qunlock(&kprof.lock);
error(EBUSY, "Global profiler is already open");
}
kprof.opened = TRUE;
- /* TODO: have a real creation function for a non-global profiler */
+ /* TODO: have a creation function for a non-global profiler */
profiler_setup();
qunlock(&kprof.lock);
break;
@@ -265,8 +267,9 @@
len += snprintf(buf + len, bufsz - len, " CPU: ");
for (int j = 0; j < NR_CPU_STATES; j++)
- len += snprintf(buf + len, bufsz - len, "%23s%s", cpu_state_names[j],
- j != NR_CPU_STATES - 1 ? " " : " \n");
+ len += snprintf(buf + len, bufsz - len, "%23s%s",
+ cpu_state_names[j],
+ j != NR_CPU_STATES - 1 ? " " : " \n");
for (int i = 0; i < num_cores; i++) {
pcpui = &per_cpu_info[i];
@@ -277,9 +280,11 @@
cpu_total = MAX(cpu_total, 1); /* for the divide later */
for (int j = 0; j < NR_CPU_STATES; j++) {
ts = tsc2timespec(pcpui->state_ticks[j]);
- len += snprintf(buf + len, bufsz - len, "%10d.%06d (%3d%%)%s",
+ len += snprintf(buf + len, bufsz - len,
+ "%10d.%06d (%3d%%)%s",
ts.tv_sec, ts.tv_nsec / 1000,
- MIN((pcpui->state_ticks[j] * 100) / cpu_total, 100),
+ MIN((pcpui->state_ticks[j] * 100) /
+ cpu_total, 100),
j != NR_CPU_STATES - 1 ? ", " : " \n");
}
}
@@ -295,14 +300,16 @@
int len = 0;
struct per_cpu_info *pcpui;
- /* could spit it all out in binary, though then it'd be harder to process
- * the data across a mnt (if we export #K). probably not a big deal. */
+ /* could spit it all out in binary, though then it'd be harder to
+ * process the data across a mnt (if we export #K). probably not a big
+ * deal. */
/* header line: version, num_cores, tsc freq, state names */
- len += snprintf(buf + len, bufsz - len, "v%03d %5d %16llu", 1, num_cores,
- __proc_global_info.tsc_freq);
+ len += snprintf(buf + len, bufsz - len, "v%03d %5d %16llu", 1,
+ num_cores, __proc_global_info.tsc_freq);
for (int j = 0; j < NR_CPU_STATES; j++)
- len += snprintf(buf + len, bufsz - len, " %6s", cpu_state_names[j]);
+ len += snprintf(buf + len, bufsz - len, " %6s",
+ cpu_state_names[j]);
len += snprintf(buf + len, bufsz - len, "\n");
for (int i = 0; i < num_cores; i++) {
@@ -328,7 +335,8 @@
switch ((int) c->qid.path) {
case Kprofdirqid:
- return devdirread(c, va, n, kproftab, ARRAY_SIZE(kproftab), devgen);
+ return devdirread(c, va, n, kproftab, ARRAY_SIZE(kproftab),
+ devgen);
case Kprofdataqid:
n = kprof_profdata_read(va, n, off);
break;
@@ -488,16 +496,16 @@
if (unlikely(booting))
return &boot_tpb;
if (unlikely(!cpu_tpbs)) {
- /* Poor man per-CPU data structure. I really do no like littering global
- * data structures with module specific data.
- * We cannot take the ktrace_lock to protect the kzmalloc() call, as
- * that might trigger printk()s, and we would reenter here.
- * Let only one core into the kzmalloc() path, and let the others get
- * the boot_tpb until finished.
- */
+ /* Poor man per-CPU data structure. I really do no like
+ * littering global data structures with module specific data.
+ * We cannot take the ktrace_lock to protect the kzmalloc()
+ * call, as that might trigger printk()s, and we would reenter
+ * here. Let only one core into the kzmalloc() path, and let
+ * the others get the boot_tpb until finished. */
if (!atomic_cas(&alloc_done, 0, 1))
return &boot_tpb;
- cpu_tpbs = kzmalloc(num_cores * sizeof(struct trace_printk_buffer), 0);
+ cpu_tpbs = kzmalloc(num_cores *
+ sizeof(struct trace_printk_buffer), 0);
}
return cpu_tpbs + core_id_early();
@@ -510,7 +518,8 @@
char *top;
};
- void emit_print_buf_str(struct print_buf *pb, const char *str, ssize_t size)
+ void emit_print_buf_str(struct print_buf *pb, const char *str,
+ ssize_t size)
{
if (size < 0) {
for (; *str && (pb->ptr < pb->top); str++)
@@ -543,8 +552,8 @@
if (pb.ptr[-1] != '\n')
emit_print_buf_str(&pb, "\n", 1);
- /* snprintf null terminates the buffer, and does not count that as part of
- * the len. If we maxed out the buffer, let's make sure it has a \n.
+ /* snprintf null terminates the buffer, and does not count that as part
+ * of the len. If we maxed out the buffer, let's make sure it has a \n.
*/
if (pb.ptr == pb.top)
pb.ptr[-1] = '\n';
diff --git a/kern/drivers/dev/mem.c b/kern/drivers/dev/mem.c
index b80e31f..8ea2189 100644
--- a/kern/drivers/dev/mem.c
+++ b/kern/drivers/dev/mem.c
@@ -48,9 +48,10 @@
}
static struct walkqid *mem_walk(struct chan *c, struct chan *nc, char **name,
- unsigned int nname)
+ unsigned int nname)
{
- return devwalk(c, nc, name, nname, mem_dir, ARRAY_SIZE(mem_dir), devgen);
+ return devwalk(c, nc, name, nname, mem_dir, ARRAY_SIZE(mem_dir),
+ devgen);
}
static size_t mem_stat(struct chan *c, uint8_t *db, size_t n)
@@ -182,7 +183,8 @@
j++;
longest_hash_chain = MAX(longest_hash_chain, j);
}
- sza_printf(sza, "Nr hash %d, empty hash: %d, longest hash %d, loadlim %d\n",
+ sza_printf(sza,
+ "Nr hash %d, empty hash: %d, longest hash %d, loadlim %d\n",
kc->hh.nr_hash_lists, empty_hash_chain,
longest_hash_chain, kc->hh.load_limit);
spin_unlock_irqsave(&kc->cache_lock);
diff --git a/kern/drivers/dev/mnt.c b/kern/drivers/dev/mnt.c
index ff4c99a..2083dc8 100644
--- a/kern/drivers/dev/mnt.c
+++ b/kern/drivers/dev/mnt.c
@@ -72,20 +72,20 @@
}
struct mntrpc {
- struct chan *c; /* Channel for whom we are working */
- struct mntrpc *list; /* Free/pending list */
- struct fcall request; /* Outgoing file system protocol message */
- struct fcall reply; /* Incoming reply */
- struct mnt *m; /* Mount device during rpc */
- struct rendez r; /* Place to hang out */
- uint8_t *rpc; /* I/O Data buffer */
- unsigned int rpclen; /* len of buffer */
- struct block *b; /* reply blocks */
- char done; /* Rpc completed */
- uint64_t stime; /* start time for mnt statistics */
- uint32_t reqlen; /* request length for mnt statistics */
- uint32_t replen; /* reply length for mnt statistics */
- struct mntrpc *flushed; /* message this one flushes */
+ struct chan *c; /* Channel for whom we are working */
+ struct mntrpc *list; /* Free/pending list */
+ struct fcall request; /* Outgoing file system protocol message */
+ struct fcall reply; /* Incoming reply */
+ struct mnt *m; /* Mount device during rpc */
+ struct rendez r; /* Place to hang out */
+ uint8_t *rpc; /* I/O Data buffer */
+ unsigned int rpclen; /* len of buffer */
+ struct block *b; /* reply blocks */
+ char done; /* Rpc completed */
+ uint64_t stime; /* start time for mnt statistics */
+ uint32_t reqlen; /* request length for mnt statistics */
+ uint32_t replen; /* reply length for mnt statistics */
+ struct mntrpc *flushed; /* message this one flushes */
};
/* Our TRUNC and remove on close differ from 9ps, so we'll need to translate.
@@ -95,7 +95,7 @@
struct Mntalloc {
spinlock_t l;
- struct mnt *list; /* Mount devices in use */
+ struct mnt *list; /* Mount devices in use */
struct mnt *mntfree; /* Free list */
struct mntrpc *rpcfree;
int nrpcfree;
@@ -148,7 +148,8 @@
uint64_t oo;
char buf[128];
- qlock(&c->umqlock); /* make sure no one else does this until we've established ourselves */
+ /* make sure no one else does this until we've established ourselves */
+ qlock(&c->umqlock);
if (waserror()) {
qunlock(&c->umqlock);
nexterror();
@@ -178,8 +179,9 @@
strlcpy(buf, m->version, sizeof(buf));
k = strlen(buf);
if (strncmp(buf, v, k) != 0) {
- snprintf(buf, sizeof buf, "incompatible 9P versions %s %s",
- m->version, v);
+ snprintf(buf, sizeof buf,
+ "incompatible 9P versions %s %s", m->version,
+ v);
error(EFAIL, buf);
}
if (returnlen > 0) {
@@ -321,7 +323,8 @@
r->request.type = Tauth;
r->request.afid = c->fid;
- /* This assumes we're called from a syscall, which should always be true. */
+ /* This assumes we're called from a syscall, which should always be
+ * true. */
if (!current_kthread->sysc)
warn("Kthread %s didn't have a syscall, current is %s",
current_kthread->name, current ? current->progname : NULL);
@@ -385,7 +388,8 @@
r->request.afid = NOFID;
else
r->request.afid = params->authchan->fid;
- /* This assumes we're called from a syscall, which should always be true. */
+ /* This assumes we're called from a syscall, which should always be
+ * true. */
if (!current_kthread->sysc)
warn("Kthread %s didn't have a syscall, current is %s",
current_kthread->name, current ? current->progname : NULL);
@@ -450,8 +454,9 @@
if (nc == NULL) {
nc = devclone(c);
/* Until the other side accepts this fid, we can't mntclose it.
- * Therefore set type to -1 for now. inferno was setting this to 0,
- * assuming it was devroot. lining up with chanrelease and newchan */
+ * Therefore set type to -1 for now. inferno was setting this
+ * to 0, assuming it was devroot. lining up with chanrelease
+ * and newchan */
nc->type = -1;
alloc = 1;
}
@@ -537,7 +542,7 @@
}
static struct chan *mntopencreate(int type, struct chan *c, char *name,
- int omode, uint32_t perm)
+ int omode, uint32_t perm)
{
ERRSTACK(1);
struct mnt *m;
@@ -724,7 +729,7 @@
{
ERRSTACK(1);
struct mnt *m;
- struct mntrpc *r; /* TO DO: volatile struct { Mntrpc *r; } r; */
+ struct mntrpc *r; /* TO DO: volatile struct { Mntrpc *r; } r; */
char *uba;
uint32_t cnt, nr, nreq;
@@ -779,37 +784,37 @@
t = r->reply.type;
switch (t) {
- case Rerror:
- /* in Akaros mode, first four characters
- * are errno.
- */
- e = r->reply.ename;
- /* If it is in the format "XXXX <at least one char>" */
- if ((strlen(e) > 5) && isxdigit(e[0]) &&
- isxdigit(e[1]) &&
- isxdigit(e[2]) &&
- isxdigit(e[3])) {
+ case Rerror:
+ /* in Akaros mode, first four characters
+ * are errno.
+ */
+ e = r->reply.ename;
+ /* If it is in the format "XXXX <at least one char>" */
+ if ((strlen(e) > 5) && isxdigit(e[0]) &&
+ isxdigit(e[1]) &&
+ isxdigit(e[2]) &&
+ isxdigit(e[3])) {
- int errno = strtoul(e, NULL, 16);
+ int errno = strtoul(e, NULL, 16);
- error(errno, &r->reply.ename[5]);
- } else
- error(EFAIL, r->reply.ename);
- case Rflush:
- error(EINTR, ERROR_FIXME);
- default:
- if (t == r->request.type + 1)
- break;
- sn = "?";
- if (m->c->name != NULL)
- sn = m->c->name->s;
- cn = "?";
- if (r->c != NULL && r->c->name != NULL)
- cn = r->c->name->s;
- warn("mnt: mismatch from %s %s rep %p tag %d fid %d T%d R%d rp %d\n",
- sn, cn, r, r->request.tag,
- r->request.fid, r->request.type, r->reply.type, r->reply.tag);
- error(EPROTO, ERROR_FIXME);
+ error(errno, &r->reply.ename[5]);
+ } else
+ error(EFAIL, r->reply.ename);
+ case Rflush:
+ error(EINTR, ERROR_FIXME);
+ default:
+ if (t == r->request.type + 1)
+ break;
+ sn = "?";
+ if (m->c->name != NULL)
+ sn = m->c->name->s;
+ cn = "?";
+ if (r->c != NULL && r->c->name != NULL)
+ cn = r->c->name->s;
+ warn("mnt: mismatch from %s %s rep %p tag %d fid %d T%d R%d rp %d\n",
+ sn, cn, r, r->request.tag, r->request.fid, r->request.type,
+ r->reply.type, r->reply.tag);
+ error(EPROTO, ERROR_FIXME);
}
}
@@ -826,24 +831,28 @@
while (waserror()) {
if (m->rip == current_kthread)
mntgate(m);
- /* Syscall aborts are like Plan 9 Eintr. For those, we need to change
- * the old request to a flush (mntflushalloc) and try again. We'll
- * always try to flush, and you can't get out until the flush either
- * succeeds or errors out with a non-abort/Eintr error.
+ /* Syscall aborts are like Plan 9 Eintr. For those, we need to
+ * change the old request to a flush (mntflushalloc) and try
+ * again. We'll always try to flush, and you can't get out
+ * until the flush either succeeds or errors out with a
+ * non-abort/Eintr error.
*
- * This all means that regular aborts cannot break us out of here! We
- * can consider that policy in the future, if we need to. Regardless,
- * if the process is dying, we really do need to abort. We might not
- * always have a process (RKM chan_release), but in that case we're fine
+ * This all means that regular aborts cannot break us out of
+ * here! We can consider that policy in the future, if we need
+ * to. Regardless, if the process is dying, we really do need
+ * to abort. We might not always have a process (RKM
+ * chan_release), but in that case we're fine
* - we're not preventing a process from dying. */
- if ((get_errno() != EINTR) || kth_proc_is_dying(current_kthread)) {
+ if ((get_errno() != EINTR) ||
+ kth_proc_is_dying(current_kthread)) {
/* all other errors or dying, bail out! */
mntflushfree(m, r);
nexterror();
}
- /* try again. this is where you can get the "rpc tags" errstr. */
+ /* try again. this is where you can get the "rpc tags" errstr.
+ */
r = mntflushalloc(r, m->msize);
- /* need one for every waserror call (so this plus one outside) */
+ /* need one for every waserror call; so this plus one outside */
poperror();
}
@@ -919,7 +928,8 @@
return -1;
nb = pullupqueue(m->q, BIT32SZ + BIT8SZ + BIT16SZ);
- /* read in the rest of the message, avoid ridiculous (for now) message sizes */
+ /* read in the rest of the message, avoid ridiculous (for now) message
+ * sizes */
len = GBIT32(nb->rp);
if (len > m->msize) {
qdiscard(m->q, qlen(m->q));
@@ -947,15 +957,16 @@
return -1;
}
- /* TODO: this should use a qio helper directly. qputback should have the
- * qlocked, but I guess we assume we're the only one using it. */
+ /* TODO: this should use a qio helper directly. qputback should have
+ * the qlocked, but I guess we assume we're the only one using it. */
/* hang the data off of the fcall struct */
l = &r->b;
*l = NULL;
do {
b = qget(m->q);
- /* TODO: have better block helpers for this and the memmove below */
+ /* TODO: have better block helpers for this and the memmove
+ * below */
b = linearizeblock(b);
if (hlen > 0) {
b->rp += hlen;
@@ -1018,8 +1029,8 @@
q->done = 1;
spin_unlock(&m->lock);
if (mntstats != NULL)
- (*mntstats) (q->request.type,
- m->c, q->stime, q->reqlen + r->replen);
+ (*mntstats) (q->request.type, m->c, q->stime,
+ q->reqlen + r->replen);
if (q != r)
rendez_wakeup(&q->r);
return;
@@ -1028,11 +1039,11 @@
}
spin_unlock(&m->lock);
if (r->reply.type == Rerror) {
- printd("unexpected reply tag %u; type %d (error %q)\n", r->reply.tag,
- r->reply.type, r->reply.ename);
+ printd("unexpected reply tag %u; type %d (error %q)\n",
+ r->reply.tag, r->reply.type, r->reply.ename);
} else {
printd("unexpected reply tag %u; type %d\n", r->reply.tag,
- r->reply.type);
+ r->reply.type);
}
}
@@ -1183,10 +1194,11 @@
{
struct mnt *m;
- /* This routine is mostly vestiges of prior lives; now it's just sanity checking */
+ /* This routine is mostly vestiges of prior lives; now it's just sanity
+ * checking */
if (c->mchan == NULL)
- panic("mntchk 1: NULL mchan c %s\n", /*c2name(c) */ "channame?");
+ panic("mntchk 1: NULL mchan c %s\n", /*c2name(c)*/ "channame?");
m = c->mchan->mux;
@@ -1210,11 +1222,11 @@
*/
void mntdirfix(uint8_t * dirbuf, struct chan *c)
{
- /* TODO: We used to use the device's char (dc), instead of the type. not
- * sure about the effects one way or the other. This might be the type[2]
- * and dev[4] in a D (struct dir, see 9p's stat
- * (http://man.cat-v.org/plan_9/5/stat). In which case, those should be for
- * the kernel's use. Hopefully our kernel. */
+ /* TODO: We used to use the device's char (dc), instead of the type.
+ * not sure about the effects one way or the other. This might be the
+ * type[2] and dev[4] in a D (struct dir, see 9p's stat
+ * (http://man.cat-v.org/plan_9/5/stat). In which case, those should be
+ * for the kernel's use. Hopefully our kernel. */
dirbuf += BIT16SZ; /* skip count */
PBIT16(dirbuf, c->type);
dirbuf += BIT16SZ;
diff --git a/kern/drivers/dev/pci.c b/kern/drivers/dev/pci.c
index b1251d4..73fe9d9 100644
--- a/kern/drivers/dev/pci.c
+++ b/kern/drivers/dev/pci.c
@@ -77,9 +77,9 @@
switch (TYPE(c->qid)) {
case Qtopdir:
if (s == DEVDOTDOT) {
- q = (struct qid) {
- QID(0, Qtopdir), 0, QTDIR};
- snprintf(get_cur_genbuf(), GENBUF_SZ, "#%s", pcidevtab.name);
+ q = (struct qid) { QID(0, Qtopdir), 0, QTDIR };
+ snprintf(get_cur_genbuf(), GENBUF_SZ, "#%s",
+ pcidevtab.name);
devdir(c, q, get_cur_genbuf(), 0, eve.name, 0555, dp);
return 1;
}
@@ -88,7 +88,8 @@
if (s == DEVDOTDOT) {
q = (struct qid) {
QID(0, Qtopdir), 0, QTDIR};
- snprintf(get_cur_genbuf(), GENBUF_SZ, "#%s", pcidevtab.name);
+ snprintf(get_cur_genbuf(), GENBUF_SZ, "#%s",
+ pcidevtab.name);
devdir(c, q, get_cur_genbuf(), 0, eve.name, 0555, dp);
return 1;
}
@@ -162,13 +163,13 @@
error(EINVAL, ERROR_FIXME);
ebuf = buf + sizeof(buf) - 1; /* -1 for newline */
w = seprintf(buf, ebuf, "%.2x.%.2x.%.2x %.4x/%.4x %3d",
- p->class, p->subclass, p->progif, p->ven_id, p->dev_id,
- p->irqline);
+ p->class, p->subclass, p->progif, p->ven_id,
+ p->dev_id, p->irqline);
for (i = 0; i < COUNT_OF(p->bar); i++) {
if (p->bar[i].mmio_sz == 0)
continue;
- w = seprintf(w, ebuf, " %d:%.8lux %d", i, p->bar[i].pio_base,
- p->bar[i].mmio_sz);
+ w = seprintf(w, ebuf, " %d:%.8lux %d", i,
+ p->bar[i].pio_base, p->bar[i].mmio_sz);
}
*w++ = '\n';
*w = '\0';
diff --git a/kern/drivers/dev/pipe.c b/kern/drivers/dev/pipe.c
index b857a65..d97acd5 100644
--- a/kern/drivers/dev/pipe.c
+++ b/kern/drivers/dev/pipe.c
@@ -188,13 +188,14 @@
}
static struct walkqid *pipewalk(struct chan *c, struct chan *nc, char **name,
- unsigned int nname)
+ unsigned int nname)
{
struct walkqid *wq;
Pipe *p;
p = c->aux;
- wq = devwalk(c, nc, name, nname, p->pipedir, ARRAY_SIZE(pipedir), pipegen);
+ wq = devwalk(c, nc, name, nname, p->pipedir, ARRAY_SIZE(pipedir),
+ pipegen);
if (wq != NULL && wq->clone != NULL && wq->clone != c) {
qlock(&p->qlock);
kref_get(&p->ref, 1);
@@ -225,25 +226,27 @@
tab = p->pipedir;
switch (type) {
- case Qdir:
- case Qctl:
- devdir(c, c->qid, tab[type].name, tab[type].length, eve.name,
- tab[type].perm, &dir);
- break;
- case Qdata0:
- perm = tab[1].perm;
- perm |= qreadable(p->q[0]) ? DMREADABLE : 0;
- perm |= qwritable(p->q[1]) ? DMWRITABLE : 0;
- devdir(c, c->qid, tab[1].name, qlen(p->q[0]), eve.name, perm, &dir);
- break;
- case Qdata1:
- perm = tab[2].perm;
- perm |= qreadable(p->q[1]) ? DMREADABLE : 0;
- perm |= qwritable(p->q[0]) ? DMWRITABLE : 0;
- devdir(c, c->qid, tab[2].name, qlen(p->q[1]), eve.name, perm, &dir);
- break;
- default:
- panic("pipestat");
+ case Qdir:
+ case Qctl:
+ devdir(c, c->qid, tab[type].name, tab[type].length, eve.name,
+ tab[type].perm, &dir);
+ break;
+ case Qdata0:
+ perm = tab[1].perm;
+ perm |= qreadable(p->q[0]) ? DMREADABLE : 0;
+ perm |= qwritable(p->q[1]) ? DMWRITABLE : 0;
+ devdir(c, c->qid, tab[1].name, qlen(p->q[0]), eve.name, perm,
+ &dir);
+ break;
+ case Qdata1:
+ perm = tab[2].perm;
+ perm |= qreadable(p->q[1]) ? DMREADABLE : 0;
+ perm |= qwritable(p->q[0]) ? DMWRITABLE : 0;
+ devdir(c, c->qid, tab[2].name, qlen(p->q[1]), eve.name, perm,
+ &dir);
+ break;
+ default:
+ panic("pipestat");
}
n = convD2M(&dir, db, n);
if (n < BIT16SZ)
@@ -261,8 +264,9 @@
if (c->qid.type & QTDIR) {
if (omode & O_WRITE)
- error(EINVAL, "Can only open directories O_READ, mode is %o oct",
- omode);
+ error(EINVAL,
+ "Can only open directories O_READ, mode is %o oct",
+ omode);
c->mode = openmode(omode);
c->flag |= COPEN;
c->offset = 0;
@@ -278,14 +282,14 @@
nexterror();
}
switch (NETTYPE(c->qid.path)) {
- case Qdata0:
- devpermcheck(p->user, p->pipedir[1].perm, omode);
- p->qref[0]++;
- break;
- case Qdata1:
- devpermcheck(p->user, p->pipedir[2].perm, omode);
- p->qref[1]++;
- break;
+ case Qdata0:
+ devpermcheck(p->user, p->pipedir[1].perm, omode);
+ p->qref[0]++;
+ break;
+ case Qdata1:
+ devpermcheck(p->user, p->pipedir[2].perm, omode);
+ p->qref[1]++;
+ break;
}
poperror();
qunlock(&p->qlock);
@@ -309,20 +313,20 @@
* closing either side hangs up the stream
*/
switch (NETTYPE(c->qid.path)) {
- case Qdata0:
- p->qref[0]--;
- if (p->qref[0] == 0) {
- qhangup(p->q[1], 0);
- qclose(p->q[0]);
- }
- break;
- case Qdata1:
- p->qref[1]--;
- if (p->qref[1] == 0) {
- qhangup(p->q[0], 0);
- qclose(p->q[1]);
- }
- break;
+ case Qdata0:
+ p->qref[0]--;
+ if (p->qref[0] == 0) {
+ qhangup(p->q[1], 0);
+ qclose(p->q[0]);
+ }
+ break;
+ case Qdata1:
+ p->qref[1]--;
+ if (p->qref[1] == 0) {
+ qhangup(p->q[0], 0);
+ qclose(p->q[1]);
+ }
+ break;
}
}
@@ -348,23 +352,23 @@
p = c->aux;
switch (NETTYPE(c->qid.path)) {
- case Qdir:
- return devdirread(c, va, n, p->pipedir, ARRAY_SIZE(pipedir),
- pipegen);
- case Qctl:
- return readnum(offset, va, n, p->path, NUMSIZE32);
- case Qdata0:
- if (c->flag & O_NONBLOCK)
- return qread_nonblock(p->q[0], va, n);
- else
- return qread(p->q[0], va, n);
- case Qdata1:
- if (c->flag & O_NONBLOCK)
- return qread_nonblock(p->q[1], va, n);
- else
- return qread(p->q[1], va, n);
- default:
- panic("piperead");
+ case Qdir:
+ return devdirread(c, va, n, p->pipedir, ARRAY_SIZE(pipedir),
+ pipegen);
+ case Qctl:
+ return readnum(offset, va, n, p->path, NUMSIZE32);
+ case Qdata0:
+ if (c->flag & O_NONBLOCK)
+ return qread_nonblock(p->q[0], va, n);
+ else
+ return qread(p->q[0], va, n);
+ case Qdata1:
+ if (c->flag & O_NONBLOCK)
+ return qread_nonblock(p->q[1], va, n);
+ else
+ return qread(p->q[1], va, n);
+ default:
+ panic("piperead");
}
return -1; /* not reached */
}
@@ -376,16 +380,16 @@
p = c->aux;
switch (NETTYPE(c->qid.path)) {
- case Qdata0:
- if (c->flag & O_NONBLOCK)
- return qbread_nonblock(p->q[0], n);
- else
- return qbread(p->q[0], n);
- case Qdata1:
- if (c->flag & O_NONBLOCK)
- return qbread_nonblock(p->q[1], n);
- else
- return qbread(p->q[1], n);
+ case Qdata0:
+ if (c->flag & O_NONBLOCK)
+ return qbread_nonblock(p->q[0], n);
+ else
+ return qbread(p->q[0], n);
+ case Qdata1:
+ if (c->flag & O_NONBLOCK)
+ return qbread_nonblock(p->q[1], n);
+ else
+ return qbread(p->q[1], n);
}
return devbread(c, n, offset);
@@ -403,42 +407,42 @@
p = c->aux;
switch (NETTYPE(c->qid.path)) {
- case Qctl:
- cb = parsecmd(va, n);
- if (waserror()) {
- kfree(cb);
- nexterror();
- }
- if (cb->nf < 1)
- error(EFAIL, "short control request");
- if (strcmp(cb->f[0], "oneblock") == 0) {
- q_toggle_qmsg(p->q[0], TRUE);
- q_toggle_qcoalesce(p->q[0], TRUE);
- q_toggle_qmsg(p->q[1], TRUE);
- q_toggle_qcoalesce(p->q[1], TRUE);
- } else {
- error(EFAIL, "unknown control request");
- }
+ case Qctl:
+ cb = parsecmd(va, n);
+ if (waserror()) {
kfree(cb);
- poperror();
- break;
+ nexterror();
+ }
+ if (cb->nf < 1)
+ error(EFAIL, "short control request");
+ if (strcmp(cb->f[0], "oneblock") == 0) {
+ q_toggle_qmsg(p->q[0], TRUE);
+ q_toggle_qcoalesce(p->q[0], TRUE);
+ q_toggle_qmsg(p->q[1], TRUE);
+ q_toggle_qcoalesce(p->q[1], TRUE);
+ } else {
+ error(EFAIL, "unknown control request");
+ }
+ kfree(cb);
+ poperror();
+ break;
- case Qdata0:
- if (c->flag & O_NONBLOCK)
- n = qwrite_nonblock(p->q[1], va, n);
- else
- n = qwrite(p->q[1], va, n);
- break;
+ case Qdata0:
+ if (c->flag & O_NONBLOCK)
+ n = qwrite_nonblock(p->q[1], va, n);
+ else
+ n = qwrite(p->q[1], va, n);
+ break;
- case Qdata1:
- if (c->flag & O_NONBLOCK)
- n = qwrite_nonblock(p->q[0], va, n);
- else
- n = qwrite(p->q[0], va, n);
- break;
+ case Qdata1:
+ if (c->flag & O_NONBLOCK)
+ n = qwrite_nonblock(p->q[0], va, n);
+ else
+ n = qwrite(p->q[0], va, n);
+ break;
- default:
- panic("pipewrite");
+ default:
+ panic("pipewrite");
}
return n;
@@ -452,25 +456,25 @@
p = c->aux;
switch (NETTYPE(c->qid.path)) {
- case Qctl:
- return devbwrite(c, bp, offset);
- case Qdata0:
- if (c->flag & O_NONBLOCK)
- n = qbwrite_nonblock(p->q[1], bp);
- else
- n = qbwrite(p->q[1], bp);
- break;
+ case Qctl:
+ return devbwrite(c, bp, offset);
+ case Qdata0:
+ if (c->flag & O_NONBLOCK)
+ n = qbwrite_nonblock(p->q[1], bp);
+ else
+ n = qbwrite(p->q[1], bp);
+ break;
- case Qdata1:
- if (c->flag & O_NONBLOCK)
- n = qbwrite_nonblock(p->q[0], bp);
- else
- n = qbwrite(p->q[0], bp);
- break;
+ case Qdata1:
+ if (c->flag & O_NONBLOCK)
+ n = qbwrite_nonblock(p->q[0], bp);
+ else
+ n = qbwrite(p->q[0], bp);
+ break;
- default:
- n = 0;
- panic("pipebwrite");
+ default:
+ n = 0;
+ panic("pipebwrite");
}
return n;
@@ -561,18 +565,19 @@
spin_lock(&p->tap_lock);
SLIST_FOREACH(tap_i, &p->data_taps, link) {
chan = tap_i->chan;
- /* Depending which chan did the tapping, we'll care about different
- * filters on different qs. For instance, if we tapped Qdata0, then we
- * only care about readables on q[0], writables on q[1], and hangups on
- * either. More precisely, we don't care about writables on q[0] or
- * readables on q[1].
+ /* Depending which chan did the tapping, we'll care about
+ * different filters on different qs. For instance, if we
+ * tapped Qdata0, then we only care about readables on q[0],
+ * writables on q[1], and hangups on either. More precisely, we
+ * don't care about writables on q[0] or readables on q[1].
*
- * Note the *tap's* filter might differ from the CB's filter. The CB
- * could be for read|write|hangup on q[1], with a Qdata0 tap for just
- * read. We don't want to just pass the CB filt directly to fire_tap,
- * since that would pass the CB's read on q[1] to the tap and fire. The
- * user would think q[0] was readable. This is why I mask out the CB
- * filter events that we know they don't want. */
+ * Note the *tap's* filter might differ from the CB's filter.
+ * The CB could be for read|write|hangup on q[1], with a Qdata0
+ * tap for just read. We don't want to just pass the CB filt
+ * directly to fire_tap, since that would pass the CB's read on
+ * q[1] to the tap and fire. The user would think q[0] was
+ * readable. This is why I mask out the CB filter events that
+ * we know they don't want. */
switch (NETTYPE(chan->qid.path)) {
case Qdata0:
if (q == p->q[0])
@@ -587,7 +592,8 @@
filter &= ~FDTAP_FILT_READABLE;
break;
default:
- panic("Shouldn't be able to tap pipe qid %p", chan->qid.path);
+ panic("Shouldn't be able to tap pipe qid %p",
+ chan->qid.path);
}
fire_tap(tap_i, filter);
}
@@ -608,8 +614,9 @@
case Qdata1:
if (tap->filter & ~DEVPIPE_LEGAL_DATA_TAPS) {
set_errno(ENOSYS);
- set_errstr("Unsupported #%s data tap %p, must be %p", devname(),
- tap->filter, DEVPIPE_LEGAL_DATA_TAPS);
+ set_errstr("Unsupported #%s data tap %p, must be %p",
+ devname(), tap->filter,
+ DEVPIPE_LEGAL_DATA_TAPS);
return -1;
}
spin_lock(&p->tap_lock);
@@ -632,7 +639,8 @@
break;
default:
set_errno(ENOSYS);
- set_errstr("Unsupported #%s data tap command %p", devname(), cmd);
+ set_errstr("Unsupported #%s data tap command %p",
+ devname(), cmd);
ret = -1;
}
spin_unlock(&p->tap_lock);
diff --git a/kern/drivers/dev/proc.c b/kern/drivers/dev/proc.c
index c8051d0..c12ace7 100644
--- a/kern/drivers/dev/proc.c
+++ b/kern/drivers/dev/proc.c
@@ -17,19 +17,20 @@
* rather than excise code that won't work, I'm bracketing it with
* #if 0 until we know we don't want it
*/
-#include <slab.h>
+#include <assert.h>
+#include <cpio.h>
+#include <error.h>
#include <kmalloc.h>
#include <kref.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <error.h>
-#include <cpio.h>
#include <pmap.h>
-#include <smp.h>
-#include <umem.h>
-#include <arch/vmm/vmm.h>
#include <ros/vmm.h>
+#include <slab.h>
+#include <smp.h>
+#include <stdio.h>
+#include <string.h>
+#include <umem.h>
+
+#include <arch/vmm/vmm.h>
struct dev procdevtab;
@@ -38,93 +39,86 @@
return procdevtab.name;
}
-enum {
- Qdir,
- Qtrace,
- Qtracepids,
- Qself,
- Qns,
- Qargs,
- Qctl,
- Qfd,
- Qfpregs,
- Qkregs,
- Qmaps,
- Qmem,
- Qnote,
- Qnoteid,
- Qnotepg,
- Qproc,
- Qregs,
- Quser,
- Qsegment,
- Qstatus,
- Qstrace,
- Qstrace_traceset,
- Qvmstatus,
- Qtext,
- Qwait,
- Qprofile,
- Qsyscall,
- Qcore,
+enum { Qdir,
+ Qtrace,
+ Qtracepids,
+ Qself,
+ Qns,
+ Qargs,
+ Qctl,
+ Qfd,
+ Qfpregs,
+ Qkregs,
+ Qmaps,
+ Qmem,
+ Qnote,
+ Qnoteid,
+ Qnotepg,
+ Qproc,
+ Qregs,
+ Quser,
+ Qsegment,
+ Qstatus,
+ Qstrace,
+ Qstrace_traceset,
+ Qvmstatus,
+ Qtext,
+ Qwait,
+ Qprofile,
+ Qsyscall,
+ Qcore,
};
-enum {
- CMclose,
- CMclosefiles,
- CMhang,
- CMstraceme,
- CMstraceall,
- CMstrace_drop,
+enum { CMclose,
+ CMclosefiles,
+ CMhang,
+ CMstraceme,
+ CMstraceall,
+ CMstrace_drop,
};
-enum {
- Nevents = 0x4000,
- Emask = Nevents - 1,
- Ntracedpids = 1024,
- STATSIZE = 8 + 1 + 10 + 1 + 6 + 2,
+enum { Nevents = 0x4000,
+ Emask = Nevents - 1,
+ Ntracedpids = 1024,
+ STATSIZE = 8 + 1 + 10 + 1 + 6 + 2,
};
/*
- * Status, fd, and ns are left fully readable (0444) because of their use in debugging,
- * particularly on shared servers.
- * Arguably, ns and fd shouldn't be readable; if you'd prefer, change them to 0000
+ * Status, fd, and ns are left fully readable (0444) because of their use in
+ * debugging, particularly on shared servers. Arguably, ns and fd shouldn't be
+ * readable; if you'd prefer, change them to 0000
*/
struct dirtab procdir[] = {
- {"args", {Qargs}, 0, 0660},
- {"ctl", {Qctl}, 0, 0660},
- {"fd", {Qfd}, 0, 0444},
- {"fpregs", {Qfpregs}, 0, 0000},
- // {"kregs", {Qkregs}, sizeof(Ureg), 0600},
- {"maps", {Qmaps}, 0, 0000},
- {"mem", {Qmem}, 0, 0000},
- {"note", {Qnote}, 0, 0000},
- {"noteid", {Qnoteid}, 0, 0664},
- {"notepg", {Qnotepg}, 0, 0000},
- {"ns", {Qns}, 0, 0444},
- {"proc", {Qproc}, 0, 0400},
- // {"regs", {Qregs}, sizeof(Ureg), 0000},
- {"user", {Quser}, 0, 0444},
- {"segment", {Qsegment}, 0, 0444},
- {"status", {Qstatus}, STATSIZE, 0444},
- {"strace", {Qstrace}, 0, 0444},
- {"strace_traceset", {Qstrace_traceset}, 0, 0666},
- {"vmstatus", {Qvmstatus}, 0, 0444},
- {"text", {Qtext}, 0, 0000},
- {"wait", {Qwait}, 0, 0400},
- {"profile", {Qprofile}, 0, 0400},
- {"syscall", {Qsyscall}, 0, 0400},
- {"core", {Qcore}, 0, 0444},
+ {"args", {Qargs}, 0, 0660},
+ {"ctl", {Qctl}, 0, 0660},
+ {"fd", {Qfd}, 0, 0444},
+ {"fpregs", {Qfpregs}, 0, 0000},
+ // {"kregs", {Qkregs}, sizeof(Ureg), 0600},
+ {"maps", {Qmaps}, 0, 0000},
+ {"mem", {Qmem}, 0, 0000},
+ {"note", {Qnote}, 0, 0000},
+ {"noteid", {Qnoteid}, 0, 0664},
+ {"notepg", {Qnotepg}, 0, 0000},
+ {"ns", {Qns}, 0, 0444},
+ {"proc", {Qproc}, 0, 0400},
+ // {"regs", {Qregs}, sizeof(Ureg), 0000},
+ {"user", {Quser}, 0, 0444},
+ {"segment", {Qsegment}, 0, 0444},
+ {"status", {Qstatus}, STATSIZE, 0444},
+ {"strace", {Qstrace}, 0, 0444},
+ {"strace_traceset", {Qstrace_traceset}, 0, 0666},
+ {"vmstatus", {Qvmstatus}, 0, 0444},
+ {"text", {Qtext}, 0, 0000},
+ {"wait", {Qwait}, 0, 0400},
+ {"profile", {Qprofile}, 0, 0400},
+ {"syscall", {Qsyscall}, 0, 0400},
+ {"core", {Qcore}, 0, 0444},
};
-static
-struct cmdtab proccmd[] = {
- {CMclose, "close", 2},
- {CMclosefiles, "closefiles", 0},
- {CMhang, "hang", 0},
- {CMstraceme, "straceme", 0},
- {CMstraceall, "straceall", 0},
- {CMstrace_drop, "strace_drop", 2},
+static struct cmdtab proccmd[] = {
+ {CMclose, "close", 2}, {CMclosefiles, "closefiles", 0},
+ {CMhang, "hang", 0}, {CMstraceme, "straceme", 0},
+ {CMstraceall, "straceall", 0}, {CMstrace_drop, "strace_drop", 2},
};
/*
@@ -135,31 +129,31 @@
* 32 bits of pid, for consistency checking
* If notepg, c->pgrpid.path is pgrp slot, .vers is noteid.
*/
-#define QSHIFT 5 /* location in qid of proc slot # */
-#define SLOTBITS 23 /* number of bits in the slot */
-#define QIDMASK ((1<<QSHIFT)-1)
-#define SLOTMASK (((1<<SLOTBITS)-1) << QSHIFT)
+#define QSHIFT 5 /* location in qid of proc slot # */
+#define SLOTBITS 23 /* number of bits in the slot */
+#define QIDMASK ((1 << QSHIFT) - 1)
+#define SLOTMASK (((1 << SLOTBITS) - 1) << QSHIFT)
-#define QID(q) ((((uint32_t)(q).path)&QIDMASK)>>0)
-#define SLOT(q) (((((uint32_t)(q).path)&SLOTMASK)>>QSHIFT)-1)
-#define PID(q) ((q).vers)
-#define NOTEID(q) ((q).vers)
+#define QID(q) ((((uint32_t)(q).path) & QIDMASK) >> 0)
+#define SLOT(q) (((((uint32_t)(q).path) & SLOTMASK) >> QSHIFT) - 1)
+#define PID(q) ((q).vers)
+#define NOTEID(q) ((q).vers)
static void procctlreq(struct proc *, char *, int);
static int procctlmemio(struct proc *, uintptr_t, int, void *, int);
-//static struct chan* proctext(struct chan*, struct proc*);
-//static Segment* txt2data(struct proc*, Segment*);
-//static int procstopped(void*);
+// static struct chan* proctext(struct chan*, struct proc*);
+// static Segment* txt2data(struct proc*, Segment*);
+// static int procstopped(void*);
static void mntscan(struct mntwalk *, struct proc *);
-//static Traceevent *tevents;
+// static Traceevent *tevents;
static char *tpids, *tpidsc, *tpidse;
static spinlock_t tlock;
static int topens;
static int tproduced, tconsumed;
-//static void notrace(struct proc*, int, int64_t);
+// static void notrace(struct proc*, int, int64_t);
-//void (*proctrace)(struct proc*, int, int64_t) = notrace;
+// void (*proctrace)(struct proc*, int, int64_t) = notrace;
#if 0
static void profclock(Ureg * ur, Timer *)
@@ -177,9 +171,8 @@
}
}
#endif
-static int
-procgen(struct chan *c, char *name, struct dirtab *tab, int unused, int s,
- struct dir *dp)
+static int procgen(struct chan *c, char *name, struct dirtab *tab, int unused,
+ int s, struct dir *dp)
{
struct qid qid;
struct proc *p;
@@ -210,7 +203,8 @@
p = current;
strlcpy(get_cur_genbuf(), "self", GENBUF_SZ);
mkqid(&qid, (p->pid + 1) << QSHIFT, p->pid, QTDIR);
- devdir(c, qid, get_cur_genbuf(), 0, p->user.name, DMDIR | 0555, dp);
+ devdir(c, qid, get_cur_genbuf(), 0, p->user.name,
+ DMDIR | 0555, dp);
return 1;
}
s -= 3;
@@ -222,12 +216,14 @@
p = pid2proc(pid);
if (!p)
return -1;
- /* Need to update s, so that it's the correct 'index' for our proc
- * (aka, the pid). We use s later when making the qid. */
+ /* Need to update s, so that it's the correct 'index'
+ * for our proc (aka, the pid). We use s later when
+ * making the qid. */
s = pid;
} else {
- /* This is a shitty iterator, and the list isn't guaranteed to give
- * you the same ordering twice in a row. (procs come and go). */
+ /* This is a shitty iterator, and the list isn't
+ * guaranteed to give you the same ordering twice in a
+ * row. (procs come and go). */
p = pid_nth(s);
if (!p)
return -1;
@@ -240,12 +236,14 @@
* name must match its formatted pid.
*/
if (name != NULL && strcmp(name, get_cur_genbuf()) != 0) {
- printk("pid-name mismatch, name: %s, pid %d\n", name, pid);
+ printk("pid-name mismatch, name: %s, pid %d\n", name,
+ pid);
proc_decref(p);
return -1;
}
mkqid(&qid, (s + 1) << QSHIFT, pid, QTDIR);
- devdir(c, qid, get_cur_genbuf(), 0, p->user.name, DMDIR | 0555, dp);
+ devdir(c, qid, get_cur_genbuf(), 0, p->user.name, DMDIR | 0555,
+ dp);
proc_decref(p);
return 1;
}
@@ -267,9 +265,11 @@
panic("procgen");
tab = &procdir[s];
- /* path is everything other than the QID part. Not sure from the orig code
- * if they wanted just the pid part (SLOTMASK) or everything above QID */
- path = c->qid.path & ~QIDMASK; /* slot component */
+ /* path is everything other than the QID part. Not sure from the orig
+ * code
+ * if they wanted just the pid part (SLOTMASK) or everything above QID
+ */
+ path = c->qid.path & ~QIDMASK; /* slot component */
if ((p = pid2proc(SLOT(c->qid))) == NULL)
return -1;
perm = 0444 | tab->perm;
@@ -358,7 +358,7 @@
}
static struct walkqid *procwalk(struct chan *c, struct chan *nc, char **name,
- unsigned int nname)
+ unsigned int nname)
{
return devwalk(c, nc, name, nname, 0, 0, procgen);
}
@@ -389,13 +389,13 @@
}
struct bm_helper {
- struct sized_alloc *sza;
- size_t buflen;
+ struct sized_alloc *sza;
+ size_t buflen;
};
static void get_needed_sz_cb(struct vm_region *vmr, void *arg)
{
- struct bm_helper *bmh = (struct bm_helper*)arg;
+ struct bm_helper *bmh = (struct bm_helper *)arg;
/* ballpark estimate of a line */
bmh->buflen += 150;
@@ -403,7 +403,7 @@
static void build_maps_cb(struct vm_region *vmr, void *arg)
{
- struct bm_helper *bmh = (struct bm_helper*)arg;
+ struct bm_helper *bmh = (struct bm_helper *)arg;
struct sized_alloc *sza = bmh->sza;
size_t old_sofar;
char path_buf[MAX_FILENAME_SZ];
@@ -420,16 +420,14 @@
}
old_sofar = sza->sofar;
- sza_printf(sza, "%08lx-%08lx %c%c%c%c %08x %02d:%02d %d ",
- vmr->vm_base, vmr->vm_end,
- vmr->vm_prot & PROT_READ ? 'r' : '-',
- vmr->vm_prot & PROT_WRITE ? 'w' : '-',
- vmr->vm_prot & PROT_EXEC ? 'x' : '-',
- vmr->vm_flags & MAP_PRIVATE ? 'p' : 's',
- vmr_has_file(vmr) ? vmr->vm_foff : 0,
- vmr_has_file(vmr) ? 1 : 0, /* VFS == 1 for major */
- 0,
- inode_nr);
+ sza_printf(sza, "%08lx-%08lx %c%c%c%c %08x %02d:%02d %d ", vmr->vm_base,
+ vmr->vm_end, vmr->vm_prot & PROT_READ ? 'r' : '-',
+ vmr->vm_prot & PROT_WRITE ? 'w' : '-',
+ vmr->vm_prot & PROT_EXEC ? 'x' : '-',
+ vmr->vm_flags & MAP_PRIVATE ? 'p' : 's',
+ vmr_has_file(vmr) ? vmr->vm_foff : 0,
+ vmr_has_file(vmr) ? 1 : 0, /* VFS == 1 for major */
+ 0, inode_nr);
/* Align the filename to the 74th char, like Linux (73 chars so far) */
sza_printf(sza, "%*s", 73 - (sza->sofar - old_sofar), "");
sza_printf(sza, "%s\n", path);
@@ -439,8 +437,8 @@
{
struct bm_helper bmh[1];
- /* Try to figure out the size needed: start with extra space, then add a bit
- * for each VMR */
+ /* Try to figure out the size needed: start with extra space, then add a
+ * bit for each VMR */
bmh->buflen = 150;
enumerate_vmrs(p, get_needed_sz_cb, bmh);
bmh->sza = sized_kzmalloc(bmh->buflen, MEM_WAIT);
@@ -511,9 +509,9 @@
}
if ((p = pid2proc(SLOT(c->qid))) == NULL)
error(ESRCH, ERROR_FIXME);
- //qlock(&p->debug);
+ // qlock(&p->debug);
if (waserror()) {
- //qunlock(&p->debug);
+ // qunlock(&p->debug);
proc_decref(p);
nexterror();
}
@@ -524,91 +522,91 @@
omode = openmode(omode);
switch (QID(c->qid)) {
- case Qtext:
- error(ENOSYS, ERROR_FIXME);
-/*
- if (omode != OREAD)
- error(EPERM, ERROR_FIXME);
- tc = proctext(c, p);
- tc->offset = 0;
- poperror();
- qunlock(&p->debug);
- proc_decref(p);
- cclose(c);
- return tc;
-*/
- case Qproc:
- case Qsegment:
- case Qprofile:
- case Qfd:
- if (omode != O_READ)
- error(EPERM, ERROR_FIXME);
- break;
-
- case Qnote:
-// if (p->privatemem)
+ case Qtext:
+ error(ENOSYS, ERROR_FIXME);
+ /*
+ if (omode != OREAD)
+ error(EPERM, ERROR_FIXME);
+ tc = proctext(c, p);
+ tc->offset = 0;
+ poperror();
+ qunlock(&p->debug);
+ proc_decref(p);
+ cclose(c);
+ return tc;
+ */
+ case Qproc:
+ case Qsegment:
+ case Qprofile:
+ case Qfd:
+ if (omode != O_READ)
error(EPERM, ERROR_FIXME);
- break;
+ break;
- case Qmem:
-// if (p->privatemem)
+ case Qnote:
+ // if (p->privatemem)
+ error(EPERM, ERROR_FIXME);
+ break;
+
+ case Qmem:
+ // if (p->privatemem)
+ error(EPERM, ERROR_FIXME);
+ // nonone(p);
+ break;
+
+ case Qargs:
+ case Qnoteid:
+ case Qwait:
+ case Qregs:
+ case Qfpregs:
+ case Qkregs:
+ case Qsyscall:
+ case Qcore:
+ nonone(p);
+ break;
+
+ case Qns:
+ if (omode != O_READ)
error(EPERM, ERROR_FIXME);
- //nonone(p);
- break;
+ c->aux = kzmalloc(sizeof(struct mntwalk), MEM_WAIT);
+ break;
+ case Quser:
+ case Qstatus:
+ case Qvmstatus:
+ case Qctl:
+ break;
- case Qargs:
- case Qnoteid:
- case Qwait:
- case Qregs:
- case Qfpregs:
- case Qkregs:
- case Qsyscall:
- case Qcore:
- nonone(p);
- break;
-
- case Qns:
- if (omode != O_READ)
- error(EPERM, ERROR_FIXME);
- c->aux = kzmalloc(sizeof(struct mntwalk), MEM_WAIT);
- break;
- case Quser:
- case Qstatus:
- case Qvmstatus:
- case Qctl:
- break;
-
- case Qstrace:
- if (!p->strace)
- error(ENOENT, "Process does not have tracing enabled");
- spin_lock(&p->strace->lock);
- if (p->strace->tracing) {
- spin_unlock(&p->strace->lock);
- error(EBUSY, "Process is already being traced");
- }
- /* It's not critical that we reopen before setting tracing, but it's
- * a little cleaner (concurrent syscalls could be trying to use the
- * queue before it was reopened, and they'd throw). */
- qreopen(p->strace->q);
- p->strace->tracing = TRUE;
+ case Qstrace:
+ if (!p->strace)
+ error(ENOENT, "Process does not have tracing enabled");
+ spin_lock(&p->strace->lock);
+ if (p->strace->tracing) {
spin_unlock(&p->strace->lock);
- /* the ref we are upping is the one we put in __proc_free, which is
- * the one we got from CMstrace{on,me}. We have a ref on p, so we
- * know we won't free until we decref the proc. */
- kref_get(&p->strace->users, 1);
- c->aux = p->strace;
- break;
- case Qstrace_traceset:
- if (!p->strace)
- error(ENOENT, "Process does not have tracing enabled");
- kref_get(&p->strace->users, 1);
- c->aux = p->strace;
- break;
- case Qmaps:
- c->aux = build_maps(p);
- break;
- case Qnotepg:
- error(ENOSYS, ERROR_FIXME);
+ error(EBUSY, "Process is already being traced");
+ }
+ /* It's not critical that we reopen before setting tracing, but
+ * it's a little cleaner (concurrent syscalls could be trying to
+ * use the queue before it was reopened, and they'd throw). */
+ qreopen(p->strace->q);
+ p->strace->tracing = TRUE;
+ spin_unlock(&p->strace->lock);
+ /* the ref we are upping is the one we put in __proc_free, which
+ * is the one we got from CMstrace{on,me}. We have a ref on p,
+ * so we know we won't free until we decref the proc. */
+ kref_get(&p->strace->users, 1);
+ c->aux = p->strace;
+ break;
+ case Qstrace_traceset:
+ if (!p->strace)
+ error(ENOENT, "Process does not have tracing enabled");
+ kref_get(&p->strace->users, 1);
+ c->aux = p->strace;
+ break;
+ case Qmaps:
+ c->aux = build_maps(p);
+ break;
+ case Qnotepg:
+ error(ENOSYS, ERROR_FIXME);
#if 0
nonone(p);
pg = p->pgrp;
@@ -619,26 +617,27 @@
c->pgrpid.path = pg->pgrpid + 1;
c->pgrpid.vers = p->noteid;
#endif
- break;
+ break;
- default:
- printk("procopen %#llux\n", c->qid.path);
- error(EINVAL, ERROR_FIXME);
+ default:
+ printk("procopen %#llux\n", c->qid.path);
+ error(EINVAL, ERROR_FIXME);
}
/* Affix pid to qid */
-// if (p->state != Dead)
+ // if (p->state != Dead)
c->qid.vers = p->pid;
- /* make sure the process slot didn't get reallocated while we were playing */
- //coherence();
- /* TODO: think about what we really want here. In akaros, we wouldn't have
- * our pid changed like that. */
+ /* make sure the process slot didn't get reallocated while we were
+ * playing */
+ // coherence();
+ /* TODO: think about what we really want here. In akaros, we wouldn't
+ * have our pid changed like that. */
if (p->pid != pid)
error(ESRCH, ERROR_FIXME);
tc = devopen(c, omode, 0, 0, procgen);
poperror();
- //qunlock(&p->debug);
+ // qunlock(&p->debug);
proc_decref(p);
return tc;
}
@@ -813,7 +812,7 @@
if (QID(c->qid) == Qstrace && c->aux != 0) {
struct strace *s = c->aux;
- assert(c->flag & COPEN); /* only way aux should have been set */
+ assert(c->flag & COPEN); /* only way aux should have been set */
s->tracing = FALSE;
qhangup(s->q, NULL);
kref_put(&s->users);
@@ -940,106 +939,107 @@
p->pid, PID(c->qid));
}
switch (QID(c->qid)) {
- default:
+ default:
+ proc_decref(p);
+ break;
+ case Quser: {
+ int i;
+
+ i = readstr(off, va, n, p->user.name);
+ proc_decref(p);
+ return i;
+ }
+ case Qstatus: {
+ /* the old code grew the stack and was hideous.
+ * status is not a high frequency operation; just malloc. */
+ char *buf = kmalloc(4096, MEM_WAIT);
+ char *s = buf, *e = buf + 4096;
+ int i;
+
+ s = seprintf(s, e, "%8d %-*s %-10s %6d", p->pid,
+ PROC_PROGNAME_SZ, p->progname,
+ procstate2str(p->state), p->ppid);
+ if (p->strace)
+ s = seprintf(s, e, " %d trace users %d traced procs",
+ kref_refcnt(&p->strace->users),
+ kref_refcnt(&p->strace->procs));
+ proc_decref(p);
+ i = readstr(off, va, n, buf);
+ kfree(buf);
+ return i;
+ }
+
+ case Qvmstatus: {
+ size_t buflen = 50 * 65 + 2;
+ char *buf = kmalloc(buflen, MEM_WAIT);
+ int i, offset;
+ offset = 0;
+ offset += snprintf(buf + offset, buflen - offset, "{\n");
+ for (i = 0; i < 65; i++) {
+ if (p->vmm.vmexits[i] != 0) {
+ offset +=
+ snprintf(buf + offset, buflen - offset,
+ "\"%s\":\"%lld\",\n",
+ VMX_EXIT_REASON_NAMES[i],
+ p->vmm.vmexits[i]);
+ }
+ }
+ offset += snprintf(buf + offset, buflen - offset, "}\n");
+ proc_decref(p);
+ n = readstr(off, va, n, buf);
+ kfree(buf);
+ return n;
+ }
+ case Qns:
+ // qlock(&p->debug);
+ if (waserror()) {
+ // qunlock(&p->debug);
proc_decref(p);
- break;
- case Quser: {
- int i;
-
- i = readstr(off, va, n, p->user.name);
- proc_decref(p);
- return i;
- }
- case Qstatus:{
- /* the old code grew the stack and was hideous.
- * status is not a high frequency operation; just malloc. */
- char *buf = kmalloc(4096, MEM_WAIT);
- char *s = buf, *e = buf + 4096;
- int i;
-
- s = seprintf(s, e,
- "%8d %-*s %-10s %6d", p->pid, PROC_PROGNAME_SZ,
- p->progname, procstate2str(p->state),
- p->ppid);
- if (p->strace)
- s = seprintf(s, e, " %d trace users %d traced procs",
- kref_refcnt(&p->strace->users),
- kref_refcnt(&p->strace->procs));
- proc_decref(p);
- i = readstr(off, va, n, buf);
- kfree(buf);
- return i;
- }
-
- case Qvmstatus:
- {
- size_t buflen = 50 * 65 + 2;
- char *buf = kmalloc(buflen, MEM_WAIT);
- int i, offset;
- offset = 0;
- offset += snprintf(buf + offset, buflen - offset, "{\n");
- for (i = 0; i < 65; i++) {
- if (p->vmm.vmexits[i] != 0) {
- offset += snprintf(buf + offset, buflen - offset,
- "\"%s\":\"%lld\",\n",
- VMX_EXIT_REASON_NAMES[i],
- p->vmm.vmexits[i]);
- }
- }
- offset += snprintf(buf + offset, buflen - offset, "}\n");
- proc_decref(p);
- n = readstr(off, va, n, buf);
- kfree(buf);
- return n;
- }
- case Qns:
- //qlock(&p->debug);
- if (waserror()) {
- //qunlock(&p->debug);
- proc_decref(p);
- nexterror();
- }
- if (p->pgrp == NULL || p->pid != PID(c->qid))
- error(ESRCH, ERROR_FIXME);
- mw = c->aux;
- if (mw->cddone) {
- poperror();
- //qunlock(&p->debug);
- proc_decref(p);
- return 0;
- }
- mntscan(mw, p);
- if (mw->mh == 0) {
- mw->cddone = 1;
- i = snprintf(va, n, "cd %s\n", p->dot->name->s);
- poperror();
- //qunlock(&p->debug);
- proc_decref(p);
- return i;
- }
- int2flag(mw->cm->mflag, flag);
- if (strcmp(mw->cm->to->name->s, "#mnt") == 0) {
- srv = srvname(mw->cm->to->mchan);
- i = snprintf(va, n, "mount %s %s %s %s\n", flag,
- srv == NULL ? mw->cm->to->mchan->name->s : srv,
- mw->mh->from->name->s,
- mw->cm->spec ? mw->cm->spec : "");
- kfree(srv);
- } else
- i = snprintf(va, n, "bind %s %s %s\n", flag,
- mw->cm->to->name->s, mw->mh->from->name->s);
+ nexterror();
+ }
+ if (p->pgrp == NULL || p->pid != PID(c->qid))
+ error(ESRCH, ERROR_FIXME);
+ mw = c->aux;
+ if (mw->cddone) {
poperror();
- //qunlock(&p->debug);
+ // qunlock(&p->debug);
+ proc_decref(p);
+ return 0;
+ }
+ mntscan(mw, p);
+ if (mw->mh == 0) {
+ mw->cddone = 1;
+ i = snprintf(va, n, "cd %s\n", p->dot->name->s);
+ poperror();
+ // qunlock(&p->debug);
proc_decref(p);
return i;
- case Qmaps:
- sza = c->aux;
- i = readstr(off, va, n, sza->buf);
- proc_decref(p);
- return i;
+ }
+ int2flag(mw->cm->mflag, flag);
+ if (strcmp(mw->cm->to->name->s, "#mnt") == 0) {
+ srv = srvname(mw->cm->to->mchan);
+ i = snprintf(va, n, "mount %s %s %s %s\n", flag,
+ srv == NULL ? mw->cm->to->mchan->name->s
+ : srv,
+ mw->mh->from->name->s,
+ mw->cm->spec ? mw->cm->spec : "");
+ kfree(srv);
+ } else
+ i = snprintf(va, n, "bind %s %s %s\n", flag,
+ mw->cm->to->name->s,
+ mw->mh->from->name->s);
+ poperror();
+ // qunlock(&p->debug);
+ proc_decref(p);
+ return i;
+ case Qmaps:
+ sza = c->aux;
+ i = readstr(off, va, n, sza->buf);
+ proc_decref(p);
+ return i;
}
error(EINVAL, "QID %d did not match any QIDs for #proc", QID(c->qid));
- return 0; /* not reached */
+ return 0; /* not reached */
}
static void mntscan(struct mntwalk *mw, struct proc *p)
@@ -1053,7 +1053,7 @@
rlock(&pg->ns);
nxt = 0;
- best = (int)(~0U >> 1); /* largest 2's complement int */
+ best = (int)(~0U >> 1); /* largest 2's complement int */
last = 0;
if (mw->mh)
@@ -1062,7 +1062,8 @@
for (i = 0; i < MNTHASH; i++) {
for (f = pg->mnthash[i]; f; f = f->hash) {
for (t = f->mount; t; t = t->next) {
- if (mw->mh == 0 || (t->mountid > last && t->mountid < best)) {
+ if (mw->mh == 0 ||
+ (t->mountid > last && t->mountid < best)) {
mw->cm = t;
mw->mh = f;
best = mw->cm->mountid;
@@ -1142,19 +1143,22 @@
n = fpudevprocio(p, va, n, offset, 1);
break;
#endif
- case Qctl:
- procctlreq(p, va, n);
- break;
- case Qstrace_traceset:
- s = c->aux;
- if (n + offset > bitmap_size(MAX_SYSCALL_NR))
- error(EINVAL, "strace_traceset: Short write (%llu at off %llu)",
- n, offset);
- if (memcpy_from_user(current, (void*)s->trace_set + offset, va, n))
- error(EFAULT, "strace_traceset: Bad addr (%p + %llu)", va, n);
- break;
- default:
- error(EFAIL, "unknown qid %#llux in procwrite\n", c->qid.path);
+ case Qctl:
+ procctlreq(p, va, n);
+ break;
+ case Qstrace_traceset:
+ s = c->aux;
+ if (n + offset > bitmap_size(MAX_SYSCALL_NR))
+ error(EINVAL,
+ "strace_traceset: Short write (%llu at off %llu)",
+ n, offset);
+ if (memcpy_from_user(current, (void *)s->trace_set + offset, va,
+ n))
+ error(EFAULT, "strace_traceset: Bad addr (%p + %llu)",
+ va, n);
+ break;
+ default:
+ error(EFAIL, "unknown qid %#llux in procwrite\n", c->qid.path);
}
poperror();
proc_decref(p);
@@ -1162,25 +1166,25 @@
}
struct dev procdevtab __devtab = {
- .name = "proc",
+ .name = "proc",
- .reset = devreset,
- .init = procinit,
- .shutdown = devshutdown,
- .attach = procattach,
- .walk = procwalk,
- .stat = procstat,
- .open = procopen,
- .create = devcreate,
- .close = procclose,
- .read = procread,
- .bread = devbread,
- .write = procwrite,
- .bwrite = devbwrite,
- .remove = devremove,
- .wstat = procwstat,
- .power = devpower,
- .chaninfo = devchaninfo,
+ .reset = devreset,
+ .init = procinit,
+ .shutdown = devshutdown,
+ .attach = procattach,
+ .walk = procwalk,
+ .stat = procstat,
+ .open = procopen,
+ .create = devcreate,
+ .close = procclose,
+ .read = procread,
+ .bread = devbread,
+ .write = procwrite,
+ .bwrite = devbwrite,
+ .remove = devremove,
+ .wstat = procwstat,
+ .power = devpower,
+ .chaninfo = devchaninfo,
};
#if 0
@@ -1267,7 +1271,7 @@
#endif
static void procctlcloseone(struct proc *p, int fd)
{
-// TODO: resolve this and sys_close
+ // TODO: resolve this and sys_close
sysclose(fd);
return;
}
@@ -1328,31 +1332,36 @@
case CMstraceall:
case CMstraceme:
case CMstrace_drop:
- /* common allocation. if we inherited, we might have one already */
+ /* common allocation. if we inherited, we might have one
+ * already */
if (!p->strace) {
strace = kzmalloc(sizeof(*p->strace), MEM_WAIT);
spinlock_init(&strace->lock);
bitmap_set(strace->trace_set, 0, MAX_SYSCALL_NR);
strace->q = qopen(65536, Qmsg, NULL, NULL);
- /* The queue is reopened and hungup whenever we open the Qstrace
- * file. This hangup might not be necessary, but is safer. */
+ /* The queue is reopened and hungup whenever we open the
+ * Qstrace file. This hangup might not be necessary,
+ * but is safer. */
qhangup(strace->q, NULL);
- /* both of these refs are put when the proc is freed. procs is for
- * every process that has this p->strace. users is procs + every
- * user (e.g. from open()).
+ /* both of these refs are put when the proc is freed.
+ * procs is for every process that has this p->strace.
+ * users is procs + every user (e.g. from open()).
*
- * it is possible to kref_put the procs kref in proc_destroy, which
- * would make strace's job easier (no need to do an async wait on
- * the child), and we wouldn't need to decref p in
- * procread(Qstrace). But the downside is that proc_destroy races
+ * it is possible to kref_put the procs kref in
+ * proc_destroy, which would make strace's job easier
+ * (no need to do an async wait on the child), and we
+ * wouldn't need to decref p in procread(Qstrace). But
+ * the downside is that proc_destroy races
* with us here with the kref initialization. */
kref_init(&strace->procs, strace_shutdown, 1);
kref_init(&strace->users, strace_release, 1);
- if (!atomic_cas_ptr((void**)&p->strace, 0, strace)) {
- /* someone else won the race and installed strace. */
+ if (!atomic_cas_ptr((void **)&p->strace, 0, strace)) {
+ /* someone else won the race and installed
+ * strace. */
qfree(strace->q);
kfree(strace);
- error(EAGAIN, "Concurrent strace init, try again");
+ error(EAGAIN,
+ "Concurrent strace init, try again");
}
}
break;
diff --git a/kern/drivers/dev/random.c b/kern/drivers/dev/random.c
index c915525..75e4acb 100644
--- a/kern/drivers/dev/random.c
+++ b/kern/drivers/dev/random.c
@@ -105,8 +105,7 @@
Qurandom
};
-static
-struct dirtab randomdir[] = {
+static struct dirtab randomdir[] = {
{".", {Qdir, 0, QTDIR}, 0, DMDIR | 0500},
{"random", {Qrandom}, 0, 0444},
{"urandom", {Qurandom}, 0, 0444},
@@ -150,7 +149,8 @@
devdir(c, tab->qid, tab->name, 0, eve.name, perm, &dir);
return dev_make_stat(c, &dir, dp, n);
default:
- return devstat(c, dp, n, randomdir, ARRAY_SIZE(randomdir), devgen);
+ return devstat(c, dp, n, randomdir, ARRAY_SIZE(randomdir),
+ devgen);
}
}
@@ -169,15 +169,15 @@
static size_t randomread(struct chan *c, void *va, size_t n, off64_t ignored)
{
switch (c->qid.path) {
- case Qdir:
- return devdirread(c, va, n, randomdir,
- ARRAY_SIZE(randomdir), devgen);
- case Qrandom:
- return random_read(va, n);
- case Qurandom:
- return urandom_read(va, n);
- default:
- panic("randomread: qid %d is impossible", c->qid.path);
+ case Qdir:
+ return devdirread(c, va, n, randomdir,
+ ARRAY_SIZE(randomdir), devgen);
+ case Qrandom:
+ return random_read(va, n);
+ case Qurandom:
+ return urandom_read(va, n);
+ default:
+ panic("randomread: qid %d is impossible", c->qid.path);
}
return -1; /* not reached */
}
diff --git a/kern/drivers/dev/regress.c b/kern/drivers/dev/regress.c
index 6030db7..fe09574 100644
--- a/kern/drivers/dev/regress.c
+++ b/kern/drivers/dev/regress.c
@@ -47,15 +47,14 @@
};
struct dirtab regresstab[]={
- {".", {Monitordirqid, 0, QTDIR},0, DMDIR|0550},
+ {".", {Monitordirqid, 0, QTDIR}, 0, DMDIR|0550},
{"mondata", {Monitordataqid}, 0, 0600},
{"monctl", {Monitorctlqid}, 0, 0600},
};
static char *ctlcommands = "ktest";
-static struct chan*
-regressattach(char *spec)
+static struct chan *regressattach(char *spec)
{
uint32_t n;
@@ -66,8 +65,7 @@
return devattach(devname(), spec);
}
-static void
-regressinit(void)
+static void regressinit(void)
{
}
@@ -88,11 +86,10 @@
return devstat(c, db, n, regresstab, ARRAY_SIZE(regresstab), devgen);
}
-static struct chan*
-regressopen(struct chan *c, int omode)
+static struct chan *regressopen(struct chan *c, int omode)
{
- if(c->qid.type & QTDIR){
- if(openmode(omode) != O_READ)
+ if (c->qid.type & QTDIR) {
+ if (openmode(omode) != O_READ)
error(EPERM, ERROR_FIXME);
}
c->mode = openmode(omode);
@@ -101,8 +98,7 @@
return c;
}
-static void
-regressclose(struct chan*unused)
+static void regressclose(struct chan *unused)
{
}
@@ -116,7 +112,8 @@
switch((int)c->qid.path){
case Monitordirqid:
- n = devdirread(c, va, n, regresstab, ARRAY_SIZE(regresstab), devgen);
+ n = devdirread(c, va, n, regresstab, ARRAY_SIZE(regresstab),
+ devgen);
break;
case Monitorctlqid:
@@ -125,7 +122,8 @@
case Monitordataqid:
if (regress.monitor) {
- printd("monitordataqid: regress.monitor %p len %p\n", regress.monitor, qlen(kprof.monitor));
+ printd("monitordataqid: regress.monitor %p len %p\n",
+ regress.monitor, qlen(kprof.monitor));
if (qlen(regress.monitor) > 0)
n = qread(regress.monitor, va, n);
else
@@ -157,7 +155,8 @@
if(strncmp(a, "ktest", 5) == 0){
run_registered_ktest_suites();
} else {
- error(EFAIL, "regresswrite: only commands are %s", ctlcommands);
+ error(EFAIL, "regresswrite: only commands are %s",
+ ctlcommands);
}
break;
diff --git a/kern/drivers/dev/sd.c b/kern/drivers/dev/sd.c
index da0a41a..b0c894b 100644
--- a/kern/drivers/dev/sd.c
+++ b/kern/drivers/dev/sd.c
@@ -11,13 +11,12 @@
* Storage Device.
*/
-
#include <assert.h>
#include <cpio.h>
#include <error.h>
-#include <net/ip.h>
#include <kmalloc.h>
#include <kref.h>
+#include <net/ip.h>
#include <pmap.h>
#include <slab.h>
#include <smp.h>
@@ -33,7 +32,8 @@
* necessary;
* we can use linker sets at some point, as we do elsewhere in Akaros. */
struct sdifc *sdifc[] = {
- &sdiahciifc, NULL,
+ &sdiahciifc,
+ NULL,
};
static const char Echange[] = "media or partition has changed";
@@ -45,44 +45,42 @@
static qlock_t devslock = QLOCK_INITIALIZER(devslock);
-enum {
- Rawcmd,
- Rawdata,
- Rawstatus,
+enum { Rawcmd,
+ Rawdata,
+ Rawstatus,
};
-enum {
- Qtopdir = 1, /* top level directory */
- Qtopbase,
- Qtopctl = Qtopbase,
+enum { Qtopdir = 1, /* top level directory */
+ Qtopbase,
+ Qtopctl = Qtopbase,
- Qunitdir, /* directory per unit */
- Qunitbase,
- Qctl = Qunitbase,
- Qraw,
- Qpart,
+ Qunitdir, /* directory per unit */
+ Qunitbase,
+ Qctl = Qunitbase,
+ Qraw,
+ Qpart,
- TypeLOG = 4,
- NType = (1 << TypeLOG),
- TypeMASK = (NType - 1),
- TypeSHIFT = 0,
+ TypeLOG = 4,
+ NType = (1 << TypeLOG),
+ TypeMASK = (NType - 1),
+ TypeSHIFT = 0,
- PartLOG = 8,
- NPart = (1 << PartLOG),
- PartMASK = (NPart - 1),
- PartSHIFT = TypeLOG,
+ PartLOG = 8,
+ NPart = (1 << PartLOG),
+ PartMASK = (NPart - 1),
+ PartSHIFT = TypeLOG,
- UnitLOG = 8,
- NUnit = (1 << UnitLOG),
- UnitMASK = (NUnit - 1),
- UnitSHIFT = (PartLOG + TypeLOG),
+ UnitLOG = 8,
+ NUnit = (1 << UnitLOG),
+ UnitMASK = (NUnit - 1),
+ UnitSHIFT = (PartLOG + TypeLOG),
- DevLOG = 8,
- NDev = (1 << DevLOG),
- DevMASK = (NDev - 1),
- DevSHIFT = (UnitLOG + PartLOG + TypeLOG),
+ DevLOG = 8,
+ NDev = (1 << DevLOG),
+ DevMASK = (NDev - 1),
+ DevSHIFT = (UnitLOG + PartLOG + TypeLOG),
- Ncmd = 20,
+ Ncmd = 20,
};
#define TYPE(q) ((((uint32_t)(q).path) >> TypeSHIFT) & TypeMASK)
@@ -90,7 +88,7 @@
#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) | \
+ (((d) << DevSHIFT) | ((u) << UnitSHIFT) | ((p) << PartSHIFT) | \
((t) << TypeSHIFT))
void sdaddpart(struct sdunit *unit, char *name, uint64_t start, uint64_t end)
@@ -114,7 +112,8 @@
if (strcmp(name, pp->sdperm.name) == 0) {
if (pp->start == start && pp->end == end)
return;
- error(EINVAL, "%s: '%s' is not valid", __func__, name);
+ error(EINVAL, "%s: '%s' is not valid", __func__,
+ name);
}
}
} else {
@@ -133,9 +132,11 @@
if (partno == -1) {
if (unit->npart >= NPart)
error(ENOMEM, "%s: no memory", __func__);
- pp = kzmalloc(sizeof(struct sdpart) * (unit->npart + SDnpart), 0);
+ pp = kzmalloc(sizeof(struct sdpart) * (unit->npart + SDnpart),
+ 0);
if (pp == NULL)
- error(ENOMEM, "%s: Can't allocate space for %d partitions",
+ error(ENOMEM,
+ "%s: Can't allocate space for %d partitions",
unit->npart + SDnpart);
memmove(pp, unit->part, sizeof(struct sdpart) * unit->npart);
kfree(unit->part);
@@ -150,8 +151,8 @@
if (start > end)
error(EINVAL, "%s: start %d > end %d", __func__, start, end);
if (end > unit->sectors)
- error(EINVAL, "%s: end %d > number of sectors %d", __func__, end,
- unit->sectors);
+ error(EINVAL, "%s: end %d > number of sectors %d", __func__,
+ end, unit->sectors);
pp = &unit->part[partno];
pp->start = start;
pp->end = end;
@@ -178,9 +179,10 @@
if (i >= unit->npart)
error(EINVAL, "%s: %d > npart %d", __func__, i, unit->npart);
- /* TODO: Implement permission checking and raise errors as appropriate. */
+ /* TODO: Implement permission checking and raise errors as appropriate.
+ */
// if (strcmp(current->user.name, pp->SDperm.user) && !iseve())
- // error(Eperm);
+ // error(Eperm);
pp->valid = 0;
pp->vers++;
@@ -401,7 +403,8 @@
if (devs[j] == NULL) {
sdev->idno = devletters[j];
devs[j] = sdev;
- snprintf(sdev->name, sizeof(sdev->name), "sd%c", devletters[j]);
+ snprintf(sdev->name, sizeof(sdev->name), "sd%c",
+ devletters[j]);
break;
}
}
@@ -471,7 +474,8 @@
unit->vers + pp->vers, QTFILE);
if (emptystr(pp->sdperm.user))
kstrdup(&pp->sdperm.user, eve.name);
- devdir(c, q, pp->sdperm.name, l, pp->sdperm.user, pp->sdperm.perm, dp);
+ devdir(c, q, pp->sdperm.name, l, pp->sdperm.user,
+ pp->sdperm.perm, dp);
rv = 1;
break;
}
@@ -507,7 +511,8 @@
case Qtopdir:
if (s == DEVDOTDOT) {
mkqid(&q, QID(0, 0, 0, Qtopdir), 0, QTDIR);
- snprintf(get_cur_genbuf(), GENBUF_SZ, "#%s", sddevtab.name);
+ snprintf(get_cur_genbuf(), GENBUF_SZ, "#%s",
+ sddevtab.name);
devdir(c, q, get_cur_genbuf(), 0, eve.name, 0555, dp);
return 1;
}
@@ -551,15 +556,16 @@
mkqid(&q, QID(sdev->idno, s, 0, Qunitdir), 0, QTDIR);
if (emptystr(unit->sdperm.user))
kstrdup(&unit->sdperm.user, eve.name);
- devdir(c, q, unit->sdperm.name, 0, unit->sdperm.user, unit->sdperm.perm,
- dp);
+ devdir(c, q, unit->sdperm.name, 0, unit->sdperm.user,
+ unit->sdperm.perm, dp);
kref_put(&sdev->r);
return 1;
case Qunitdir:
if (s == DEVDOTDOT) {
mkqid(&q, QID(0, 0, 0, Qtopdir), 0, QTDIR);
- snprintf(get_cur_genbuf(), GENBUF_SZ, "#%s", sddevtab.name);
+ snprintf(get_cur_genbuf(), GENBUF_SZ, "#%s",
+ sddevtab.name);
devdir(c, q, get_cur_genbuf(), 0, eve.name, 0555, dp);
return 1;
}
@@ -580,8 +586,8 @@
* will return > 1.
* Online is a bit of a large hammer but does the job.
*/
- if (unit->sectors == 0 ||
- (unit->dev->ifc->online && unit->dev->ifc->online(unit) > 1))
+ if (unit->sectors == 0 || (unit->dev->ifc->online &&
+ unit->dev->ifc->online(unit) > 1))
sdinitpart(unit);
i = s + Qunitbase;
@@ -608,7 +614,8 @@
unit->vers + pp->vers, QTFILE);
if (emptystr(pp->sdperm.user))
kstrdup(&pp->sdperm.user, eve.name);
- devdir(c, q, pp->sdperm.name, l, pp->sdperm.user, pp->sdperm.perm, dp);
+ devdir(c, q, pp->sdperm.name, l, pp->sdperm.user,
+ pp->sdperm.perm, dp);
qunlock(&unit->ctl);
kref_put(&sdev->r);
return 1;
@@ -649,7 +656,8 @@
}
if (spec[0] != 's' || spec[1] != 'd')
- error(EINVAL, "First two characters of spec must be 'sd', not %c%c",
+ error(EINVAL,
+ "First two characters of spec must be 'sd', not %c%c",
spec[0], spec[1]);
idno = spec[2];
subno = strtol(&spec[3], &p, 0);
@@ -756,8 +764,7 @@
}
}
-static size_t sdbio(struct chan *c, int write, char *a, size_t len,
- off64_t off)
+static size_t sdbio(struct chan *c, int write, char *a, size_t len, off64_t off)
{
ERRSTACK(2);
int nchange;
@@ -788,7 +795,8 @@
* machine use an sdi{ata,ahci} on another machine, and it all
* works. Nobody is going to do that, now, so get_errno() it is.
* if (strcmp(up->errstr, Eio) == 0 ... */
- if ((get_errno() == EIO) && (unit->sectors == 0) && (nchange++ == 0)) {
+ if ((get_errno() == EIO) && (unit->sectors == 0) &&
+ (nchange++ == 0)) {
sdinitpart(unit);
poperror();
continue;
@@ -815,7 +823,8 @@
* been brought online.
*/
bno = (off / unit->secsize) + pp->start;
- nb = ((off + len + unit->secsize - 1) / unit->secsize) + pp->start - bno;
+ nb =
+ ((off + len + unit->secsize - 1) / unit->secsize) + pp->start - bno;
max = SDmaxio / unit->secsize;
if (nb > max)
nb = max;
@@ -823,8 +832,8 @@
nb = pp->end - bno;
if (bno >= pp->end || nb == 0) {
if (write)
- error(EIO, "bno(%d) >= pp->end(%d) or nb(%d) == 0", bno, pp->end,
- nb);
+ error(EIO, "bno(%d) >= pp->end(%d) or nb(%d) == 0", bno,
+ pp->end, nb);
qunlock(&unit->ctl);
kref_put(&sdev->r);
poperror();
@@ -837,7 +846,8 @@
b = kzmalloc(nb * unit->secsize, MEM_WAIT);
if (b == NULL)
- error(ENOMEM, "%s: could not allocate %d bytes", nb * unit->secsize);
+ error(ENOMEM, "%s: could not allocate %d bytes",
+ nb * unit->secsize);
if (waserror()) {
kfree(b);
if (!(unit->inquiry[1] & SDinq1removable))
@@ -1161,7 +1171,8 @@
p = kzmalloc(mm, 0);
if (p == NULL)
error(ENOMEM, "Alloc of %d bytes failed", mm);
- l = snprintf(p, mm, "inquiry %.48s\n", (char *)unit->inquiry + 8);
+ l = snprintf(p, mm, "inquiry %.48s\n",
+ (char *)unit->inquiry + 8);
qlock(&unit->ctl);
/*
* If there's a device specific routine it must
@@ -1174,13 +1185,16 @@
sdinitpart(unit);
if (unit->sectors) {
if (unit->dev->ifc->rctl == NULL)
- l += snprintf(p + l, mm - l, "geometry %llu %lu\n",
+ l += snprintf(p + l, mm - l,
+ "geometry %llu %lu\n",
unit->sectors, unit->secsize);
pp = unit->part;
for (i = 0; i < unit->npart; i++) {
if (pp->valid)
- l += snprintf(p + l, mm - l, "part %s %llu %llu\n",
- pp->sdperm.name, pp->start, pp->end);
+ l += snprintf(p + l, mm - l,
+ "part %s %llu %llu\n",
+ pp->sdperm.name,
+ pp->start, pp->end);
pp++;
}
}
@@ -1320,10 +1334,13 @@
error(EIO, "Unit changed");
if (cb->nf < 1)
- error(EINVAL, "%s requires at least one argument", cb->f[0]);
+ error(EINVAL, "%s requires at least one argument",
+ cb->f[0]);
if (strcmp(cb->f[0], "part") == 0) {
if (cb->nf != 4)
- error(EINVAL, "Part got %d arguments, requires 4", cb->nf);
+ error(EINVAL,
+ "Part got %d arguments, requires 4",
+ cb->nf);
if (unit->sectors == 0)
error(EINVAL, "unit->sectors was 0");
if (!sdinitpart(unit))
@@ -1333,7 +1350,8 @@
sdaddpart(unit, cb->f[1], start, end);
} else if (strcmp(cb->f[0], "delpart") == 0) {
if (cb->nf != 2)
- error(EINVAL, "delpart got %d args, 2 required");
+ error(EINVAL,
+ "delpart got %d args, 2 required");
if (unit->part == NULL)
error(EIO, "partition was NULL");
sddelpart(unit, cb->f[1]);
@@ -1361,7 +1379,8 @@
switch (unit->state) {
case Rawcmd:
if (n < 6 || n > sizeof(req->cmd))
- error(EINVAL, "%d is < 6 or > %d", n, sizeof(req->cmd));
+ error(EINVAL, "%d is < 6 or > %d", n,
+ sizeof(req->cmd));
req = kzmalloc(sizeof(struct sdreq), 0);
if (req == NULL)
error(ENOMEM, "Can't allocate an sdreq");
@@ -1439,9 +1458,10 @@
break;
}
- /* TODO: Implement permissions checking and raise errors as appropriate. */
+ /* TODO: Implement permissions checking and raise errors as appropriate.
+ * */
// if (strcmp(current->user.name, perm->user) && !iseve())
- // error(Eperm);
+ // error(Eperm);
d = kzmalloc(sizeof(struct dir) + n, 0);
n = convM2D(dp, n, &d[0], (char *)&d[1]);
@@ -1589,11 +1609,11 @@
{
struct devport *p;
- p = (struct devport *)kzmalloc((dc->nports + 1) * sizeof(struct devport),
- 0);
+ p = (struct devport *)kzmalloc(
+ (dc->nports + 1) * sizeof(struct devport), 0);
if (p == NULL)
- error(ENOMEM, "Can't allocate %d bytes for %d ports", dc->nports,
- (dc->nports + 1) * sizeof(struct devport));
+ error(ENOMEM, "Can't allocate %d bytes for %d ports",
+ dc->nports, (dc->nports + 1) * sizeof(struct devport));
if (dc->nports > 0) {
memmove(p, dc->ports, dc->nports * sizeof(struct devport));
kfree(dc->ports);
@@ -1652,12 +1672,8 @@
char *name;
void (*parse)(struct confdata *, char *unused_char_p_t);
} options[] = {
- {"switch", parseswitch},
- {"spec", parsespec},
- {"port", parseport},
- {"size", parsesize},
- {"irq", parseirq},
- {"type", parsetype},
+ {"switch", parseswitch}, {"spec", parsespec}, {"port", parseport},
+ {"size", parsesize}, {"irq", parseirq}, {"type", parsetype},
};
static void legacytopctl(struct cmdbuf *cb)
diff --git a/kern/drivers/dev/sdiahci.c b/kern/drivers/dev/sdiahci.c
index f92adf2..4213c4a 100644
--- a/kern/drivers/dev/sdiahci.c
+++ b/kern/drivers/dev/sdiahci.c
@@ -12,13 +12,12 @@
* copyright © 2007-8 coraid, inc.
*/
-
#include <assert.h>
#include <cpio.h>
#include <error.h>
-#include <net/ip.h>
#include <kmalloc.h>
#include <kref.h>
+#include <net/ip.h>
#include <pmap.h>
#include <sd.h>
#include <slab.h>
@@ -28,95 +27,98 @@
#include <ahci.h>
-enum {
- Vatiamd = 0x1002,
- Vintel = 0x8086,
- Vmarvell = 0x1b4b,
+enum { Vatiamd = 0x1002,
+ Vintel = 0x8086,
+ Vmarvell = 0x1b4b,
};
#define iprintd(...) \
- do { \
- if (prid) \
- printd(__VA_ARGS__); \
+ do { \
+ if (prid) \
+ printd(__VA_ARGS__); \
} while (0)
#define aprintd(...) \
- do { \
- if (datapi) \
- printd(__VA_ARGS__); \
+ do { \
+ if (datapi) \
+ printd(__VA_ARGS__); \
} while (0)
#define Tname(c) tname[(c)->type]
#define Intel(x) ((x)->pci->ven_id == Vintel)
-enum {
- NCtlr = 16,
- NCtlrdrv = 32,
- NDrive = NCtlr * NCtlrdrv,
+enum { NCtlr = 16,
+ NCtlrdrv = 32,
+ NDrive = NCtlr * NCtlrdrv,
- Read = 0,
- Write,
+ Read = 0,
+ Write,
- Nms = 256, /* ms. between drive checks */
- Mphywait = 2 * 1024 / Nms - 1,
- Midwait = 16 * 1024 / Nms - 1,
- Mcomrwait = 64 * 1024 / Nms - 1,
+ Nms = 256, /* ms. between drive checks */
+ Mphywait = 2 * 1024 / Nms - 1,
+ Midwait = 16 * 1024 / Nms - 1,
+ Mcomrwait = 64 * 1024 / Nms - 1,
- Obs = 0xa0, /* obsolete device bits */
+ Obs = 0xa0, /* obsolete device bits */
- /*
- * if we get more than this many interrupts per tick for a drive,
- * either the hardware is broken or we've got a bug in this driver.
- */
- Maxintrspertick = 2000, /* was 1000 */
+ /*
+ * if we get more than this many interrupts per tick for a drive,
+ * either the hardware is broken or we've got a bug in this driver.
+ */
+ Maxintrspertick = 2000, /* was 1000 */
};
/* pci space configuration */
-enum {
- Pmap = 0x90,
- Ppcs = 0x91,
- Prev = 0xa8,
+enum { Pmap = 0x90,
+ Ppcs = 0x91,
+ Prev = 0xa8,
};
-enum {
- Tesb,
- Tich,
- Tsb600,
- Tunk,
+enum { Tesb,
+ Tich,
+ Tsb600,
+ Tunk,
};
static char *tname[] = {
- "63xxesb", "ich", "sb600", "unknown",
+ "63xxesb",
+ "ich",
+ "sb600",
+ "unknown",
};
-enum {
- Dnull,
- Dmissing,
- Dnew,
- Dready,
- Derror,
- Dreset,
- Doffline,
- Dportreset,
- Dlast,
+enum { Dnull,
+ Dmissing,
+ Dnew,
+ Dready,
+ Derror,
+ Dreset,
+ Doffline,
+ Dportreset,
+ Dlast,
};
static char *diskstates[Dlast] = {
"null", "missing", "new", "ready", "error", "reset", "offline", "portreset",
};
-enum {
- DMautoneg,
- DMsatai,
- DMsataii,
- DMsata3,
+enum { DMautoneg,
+ DMsatai,
+ DMsataii,
+ DMsata3,
};
static char *modename[] = {
/* used in control messages */
- "auto", "satai", "sataii", "sata3",
+ "auto",
+ "satai",
+ "sataii",
+ "sata3",
};
static char *descmode[] = {
/* only printed */
- "auto", "sata 1", "sata 2", "sata 3",
+ "auto",
+ "sata 1",
+ "sata 2",
+ "sata 3",
};
static char *flagname[] = {
@@ -206,11 +208,9 @@
static int datapi;
// TODO: does this get initialized correctly?
-static char stab[] = {
- [0] = 'i', 'm',
- [8] = 't', 'c', 'p', 'e',
- [16] = 'N', 'I', 'W', 'B', 'D', 'C', 'H', 'S', 'T', 'F', 'X'
-};
+static char stab[] = {[0] = 'i', 'm', [8] = 't', 'c', 'p', 'e',
+ [16] = 'N', 'I', 'W', 'B', 'D', 'C',
+ 'H', 'S', 'T', 'F', 'X'};
// AHCI register access helper functions
// TODO(afergs): Figure out what the datatype for reg/offset should really be!
@@ -423,7 +423,8 @@
cfis = pc->pm->ctab; // cfis is the first thing in ctab, same location
memset((void *)cfis, 0, 0x20);
ahci_cfis_write8(cfis, 0, 0x27); // H2D
- ahci_cfis_write8(cfis, 1, 0x80); // Transfer due to update to CMD register
+ ahci_cfis_write8(cfis, 1,
+ 0x80); // Transfer due to update to CMD register
ahci_cfis_write8(cfis, 7, Obs);
return cfis;
}
@@ -524,7 +525,8 @@
// TODO(afergs): Replace 1|32 with constants
if (ahciwait(pc, 1000) == -1 ||
ahci_port_read32(pc->p, PORT_TFD) & (1 | 32)) {
- printd("ahci: smart fail %#lx\n", ahci_port_read32(pc->p, PORT_TFD));
+ printd("ahci: smart fail %#lx\n",
+ ahci_port_read32(pc->p, PORT_TFD));
return -1;
}
if (n)
@@ -608,7 +610,8 @@
{
void *cfis, *prdt;
static unsigned char tab[] = {
- 0xec, 0xa1,
+ 0xec,
+ 0xa1,
};
cfis = cfissetup(pc);
@@ -898,7 +901,8 @@
/* drive coming up in slumbering? */
sstatus = ahci_port_read32(port, PORT_SSTS);
if ((sstatus & Devdet) == Devpresent &&
- ((sstatus & Intpm) == Intslumber || (sstatus & Intpm) == Intpartpwr))
+ ((sstatus & Intpm) == Intslumber ||
+ (sstatus & Intpm) == Intpartpwr))
ahciwakeup(port);
/* "disable power management" sequence from book. */
@@ -945,8 +949,8 @@
printd("#S/sd%c: type %s port %#p: sss %ld ncs %ld coal %ld "
"%ld ports, led %ld clo %ld ems %ld\n",
ctlr->sdev->idno, tname[ctlr->type], hba, (cap >> 27) & 1,
- (cap >> 8) & 0x1f, (cap >> 7) & 1, (cap & 0x1f) + 1, (cap >> 25) & 1,
- (cap >> 24) & 1, (cap >> 6) & 1);
+ (cap >> 8) & 0x1f, (cap >> 7) & 1, (cap & 0x1f) + 1,
+ (cap >> 25) & 1, (cap >> 24) & 1, (cap >> 6) & 1);
return countbits(ahci_hba_read32(hba, HBA_PI));
}
@@ -1076,8 +1080,9 @@
task = ahci_port_read32(port, PORT_TFD);
if (cause & Adhrs) {
if (task & (1 << 5 | 1)) {
- printd("ahci: %s: Adhrs cause %#lx serr %#lx task %#lx\n", name,
- cause, serr, task);
+ printd(
+ "ahci: %s: Adhrs cause %#lx serr %#lx task %#lx\n",
+ name, cause, serr, task);
d->portm.flag |= Ferror;
ewake = 1;
}
@@ -1085,8 +1090,8 @@
}
sstatus = ahci_port_read32(port, PORT_SSTS);
if (task & 1 && last != cause)
- printd("%s: err ca %#lx serr %#lx task %#lx sstat %#lx\n", name, cause,
- serr, task, sstatus);
+ printd("%s: err ca %#lx serr %#lx task %#lx sstat %#lx\n", name,
+ cause, serr, task, sstatus);
if (pr)
printd("%s: upd %#lx ta %#lx\n", name, cause, task);
@@ -1105,7 +1110,8 @@
break;
case Devpresent | Devphycomm:
/* power mgnt crap for surprise removal */
- set_bit32(port, PORT_IE, Aprcs | Apcs); /* is this required? */
+ set_bit32(port, PORT_IE,
+ Aprcs | Apcs); /* is this required? */
d->state = Dreset;
break;
case Devphyoffline:
@@ -1249,8 +1255,8 @@
qunlock(&pc->pm->ql);
iprintd("%s: %sLBA %llu sectors: %s %s %s %s\n", d->unit->sdperm.name,
- (pm->feat & Dllba ? "L" : ""), d->sectors, d->model, d->firmware,
- d->serial, d->mediachange ? "[mediachange]" : "");
+ (pm->feat & Dllba ? "L" : ""), d->sectors, d->model,
+ d->firmware, d->serial, d->mediachange ? "[mediachange]" : "");
return 0;
lose:
@@ -1284,9 +1290,7 @@
i = -1;
qlock(&d->portm.ql);
if (ahciportreset(&d->portc) == -1)
- printd("ahci: doportreset: fails\n")
- else
- i = 0;
+ printd("ahci: doportreset: fails\n") else i = 0;
qunlock(&d->portm.ql);
printd("ahci: doportreset: portreset → %s [task %#lx]\n",
diskstates[d->state], ahci_port_read32(d->port, PORT_TFD));
@@ -1365,7 +1369,8 @@
d->state = Dportreset;
goto portreset;
}
- printd("%s: reset; new mode %s\n", name, modename[d->mode]);
+ printd("%s: reset; new mode %s\n", name,
+ modename[d->mode]);
spin_unlock_irqsave(&d->Lock);
resetdisk(d);
spin_lock_irqsave(&d->Lock);
@@ -1373,13 +1378,14 @@
case Intactive | Devphycomm | Devpresent:
task = ahci_port_read32(d->port, PORT_TFD);
if ((++d->wait & Midwait) == 0) {
- printd("%s: slow reset %06#x task=%#lx; %d\n", name, s, task,
- d->wait);
+ printd("%s: slow reset %06#x task=%#lx; %d\n",
+ name, s, task, d->wait);
goto reset;
}
s = (unsigned char)task;
if (s == 0x7f ||
- ((ahci_port_read32(d->port, PORT_SIG) >> 16) != 0xeb14 &&
+ ((ahci_port_read32(d->port, PORT_SIG) >> 16) !=
+ 0xeb14 &&
(s & ~0x17) != (1 << 6)))
break;
spin_unlock_irqsave(&d->Lock);
@@ -1597,10 +1603,11 @@
panic("iaenable: zero s->ctlr->ndrive");
pci_set_bus_master(c->pci);
snprintf(name, sizeof(name), "%s (%s)", s->name, s->ifc->name);
- /*c->vector = intrenable(c->pci->intl, iainterrupt, c, c->pci->tbdf,
- *name);*/
+ /*c->vector = intrenable(c->pci->intl, iainterrupt, c,
+ *c->pci->tbdf, name);*/
/* what do we do about the arg? */
- register_irq(c->pci->irqline, iainterrupt, c, pci_to_tbdf(c->pci));
+ register_irq(c->pci->irqline, iainterrupt, c,
+ pci_to_tbdf(c->pci));
/* supposed to squelch leftover interrupts here. */
ahcienable(c->hba);
c->enabled = 1;
@@ -1664,7 +1671,8 @@
struct aportm *pm;
uint32_t flags;
static unsigned char tab[2][2] = {
- {0xc8, 0x25}, {0xca, 0x35},
+ {0xc8, 0x25},
+ {0xca, 0x35},
};
pm = &d->portm;
@@ -1681,7 +1689,8 @@
ahci_cfis_write8(cfis, 2, acmd);
ahci_cfis_write8(cfis, 3, 0);
- ahci_cfis_write8(cfis, 4, lba); /* sector lba low 7:0 */
+ ahci_cfis_write8(cfis, 4, lba); /* sector lba low
+ 7:0 */
ahci_cfis_write8(cfis, 5, lba >> 8); /* cylinder low lba mid 15:8 */
ahci_cfis_write8(cfis, 6, lba >> 16); /* cylinder hi lba hi 23:16 */
c7 = Obs | 0x40; /* 0x40 == lba */
@@ -1689,10 +1698,14 @@
c7 |= (lba >> 24) & 7;
ahci_cfis_write8(cfis, 7, c7);
- ahci_cfis_write8(cfis, 8, lba >> 24); /* sector (exp) lba 31:24 */
- ahci_cfis_write8(cfis, 9, lba >> 32); /* cylinder low (exp) lba 39:32 */
- ahci_cfis_write8(cfis, 10, lba >> 48); /* cylinder hi (exp) lba 48:40 */
- ahci_cfis_write8(cfis, 11, 0); /* features (exp); */
+ ahci_cfis_write8(
+ cfis, 8,
+ lba >> 24); /* sector (exp) lba 31:24 */
+ ahci_cfis_write8(cfis, 9,
+ lba >> 32); /* cylinder low (exp) lba 39:32 */
+ ahci_cfis_write8(
+ cfis, 10, lba >> 48); /* cylinder hi (exp) lba 48:40 */
+ ahci_cfis_write8(cfis, 11, 0); /* features (exp); */
ahci_cfis_write8(cfis, 12, n); /* sector count */
ahci_cfis_write8(cfis, 13, n >> 8); /* sector count (exp) */
@@ -1748,9 +1761,10 @@
else
ahci_cfis_write8(cfis, 3, 0); /* features (exp); */
- ahci_cfis_write8(cfis, 4, 0); /* sector lba low 7:0 */
- ahci_cfis_write8(cfis, 5, n); /* cylinder low lba mid 15:8 */
- ahci_cfis_write8(cfis, 6, n >> 8); /* cylinder hi lba hi 23:16 */
+ ahci_cfis_write8(cfis, 4, 0); /* sector lba low 7:0 */
+ ahci_cfis_write8(cfis, 5, n); /* cylinder low lba mid 15:8 */
+ ahci_cfis_write8(cfis, 6,
+ n >> 8); /* cylinder hi lba hi 23:16 */
ahci_cfis_write8(cfis, 7, Obs);
for (i = 0; i < 12; i++)
@@ -1763,8 +1777,8 @@
ahci_list_write32(list, ALIST_LEN, 0);
ahci_list_write32(list, ALIST_CTAB, paddr_low32(ctab));
ahci_list_write32(list, ALIST_CTABHI, paddr_high32(ctab));
- printd("ahci: %s: LIST->CTAB physical address=0x%08x:0x%08x\n", __func__,
- paddr_high32(ctab), paddr_low32(ctab));
+ printd("ahci: %s: LIST->CTAB physical address=0x%08x:0x%08x\n",
+ __func__, paddr_high32(ctab), paddr_low32(ctab));
if (data == 0)
return list;
@@ -1773,8 +1787,8 @@
ahci_prdt_write32(prdt, APRDT_DBA, paddr_low32(data));
ahci_prdt_write32(prdt, APRDT_DBAHI, paddr_high32(data));
ahci_prdt_write32(prdt, APRDT_COUNT, 1 << 31 | (n - 2) | 1);
- printd("ahci: %s: PRDT->DBA physical address=0x%08x:0x%08x\n", __func__,
- paddr_high32(data), paddr_low32(data));
+ printd("ahci: %s: PRDT->DBA physical address=0x%08x:0x%08x\n",
+ __func__, paddr_high32(data), paddr_low32(data));
return list;
}
@@ -1784,7 +1798,8 @@
uint32_t s, i, delta;
for (i = 0; i < 15000; i += 250) {
- if (d->state == Dreset || d->state == Dportreset || d->state == Dnew)
+ if (d->state == Dreset || d->state == Dportreset ||
+ d->state == Dnew)
return 1;
delta = ms() - d->lastseen;
if (d->state == Dnull || delta > 10 * 1000)
@@ -1794,7 +1809,8 @@
spin_unlock_irqsave(&d->Lock);
if ((s & Intpm) == 0 && delta > 1500)
return -1; /* no detect */
- if (d->state == Dready && (s & Devdet) == (Devphycomm | Devpresent))
+ if (d->state == Dready &&
+ (s & Devdet) == (Devphycomm | Devpresent))
return 0; /* ready, present & phy. comm. */
esleep(250);
}
@@ -1830,7 +1846,8 @@
static int iariopkt(struct sdreq *r, struct drive *d)
{
ERRSTACK(2);
- int n, count, try, max, flag, task, wormwrite;
+ int n, count, try
+ , max, flag, task, wormwrite;
char *name;
unsigned char *cmd, *data;
void *port;
@@ -1841,14 +1858,15 @@
port = d->port;
aprintd("ahci: iariopkt: %04#x %04#x %c %d %p\n", cmd[0], cmd[2],
- "rw"[r->write], r->dlen, r->data);
+ "rw"[r->write], r -> dlen, r -> data);
if (cmd[0] == 0x5a && (cmd[2] & 0x3f) == 0x3f)
return sdmodesense(r, cmd, d->info, d->infosz);
r->rlen = 0;
count = r->dlen;
max = 65536;
- try = 0;
+ try
+ = 0;
retry:
data = r->data;
n = count;
@@ -1879,7 +1897,8 @@
while (waserror())
poperror();
/* don't sleep here forever */
- rendez_sleep_timeout(&d->portm.Rendez, ahciclear, &as, (3 * 1000) * 1000);
+ rendez_sleep_timeout(&d->portm.Rendez, ahciclear, &as,
+ (3 * 1000) * 1000);
poperror();
if (!ahciclear(&as)) {
qunlock(&d->portm.ql);
@@ -1948,7 +1967,8 @@
static int iario(struct sdreq *r)
{
ERRSTACK(1);
- int i, n, count, try, max, flag, task;
+ int i, n, count, try
+ , max, flag, task;
uint64_t lba;
char *name;
unsigned char *cmd, *data;
@@ -1994,7 +2014,8 @@
count = r->dlen / unit->secsize;
max = 128;
- try = 0;
+ try
+ = 0;
retry:
data = r->data;
while (count > 0) {
@@ -2030,7 +2051,8 @@
poperror();
if (!ahciclear(&as)) {
qunlock(&d->portm.ql);
- printd("%s: ahciclear not true after 3 seconds\n", name);
+ printd("%s: ahciclear not true after 3 seconds\n",
+ name);
r->status = SDcheck;
return SDcheck;
}
@@ -2058,7 +2080,8 @@
goto retry;
}
if (flag & Ferror) {
- printk("%s: i/o error task=%#x @%lld\n", name, task, lba);
+ printk("%s: i/o error task=%#x @%lld\n", name, task,
+ lba);
r->status = SDeio;
return SDeio;
}
@@ -2091,7 +2114,8 @@
pcidev_write16(c->pci, 0x40, pcidev_read16(c->pci, 0x40) & ~(1 << 15));
pcidev_write16(c->pci, 0x42, pcidev_read16(c->pci, 0x42) & ~(1 << 15));
- ahci_hba_write32(p, HBA_GHC, 1 << 31); /* enable ahci mode (ghc register) */
+ ahci_hba_write32(p, HBA_GHC,
+ 1 << 31); /* enable ahci mode (ghc register) */
ahci_hba_write32(p, HBA_PI,
(1 << 6) - 1); /* 5 ports. (supposedly ro pi reg.) */
@@ -2122,18 +2146,23 @@
return Tich;
break;
case Vatiamd:
- if (p->dev_id == 0x4380 || p->dev_id == 0x4390 || p->dev_id == 0x4391) {
- printd("detected sb600 vid %#x did %#x\n", p->ven_id, p->dev_id);
+ if (p->dev_id == 0x4380 || p->dev_id == 0x4390 ||
+ p->dev_id == 0x4391) {
+ printd("detected sb600 vid %#x did %#x\n", p->ven_id,
+ p->dev_id);
return Tsb600;
}
break;
case Vmarvell:
if (p->dev_id == 0x9123)
- printk("ahci: marvell sata 3 controller has delusions of something on unit 7\n");
+ printk("ahci: marvell sata 3 controller has delusions "
+ "of something on unit 7\n");
break;
}
- if (p->class == Pcibcstore && p->subclass == Pciscsata && p->progif == 1) {
- printd("ahci: Tunk: vid %#4.4x did %#4.4x\n", p->ven_id, p->dev_id);
+ if (p->class == Pcibcstore && p->subclass == Pciscsata &&
+ p->progif == 1) {
+ printd("ahci: Tunk: vid %#4.4x did %#4.4x\n", p->ven_id,
+ p->dev_id);
return Tunk;
}
return -1;
@@ -2151,8 +2180,9 @@
ctlr->mport = h_cap & ((1 << 5) - 1);
i = (h_cap >> 20) & ((1 << 4) - 1); /* iss */
- printk("#S/sd%c: %s: %#p %s, %d ports, irq %d\n", sdev->idno, Tname(ctlr),
- ctlr->physio, descmode[i], nunit, ctlr->pci->irqline);
+ printk("#S/sd%c: %s: %#p %s, %d ports, irq %d\n", sdev->idno,
+ Tname(ctlr), ctlr->physio, descmode[i], nunit,
+ ctlr->pci->irqline);
/* map the drives -- they don't all need to be enabled. */
n = 0;
ctlr->rawdrive = kzmalloc(NCtlrdrv * sizeof(struct drive), 0);
@@ -2182,7 +2212,8 @@
}
for (i = 0; i < n; i++)
if (ahciidle(ctlr->drive[i]->port) == -1) {
- printd("ahci: %s: port %d wedged; abort\n", Tname(ctlr), i);
+ printd("ahci: %s: port %d wedged; abort\n", Tname(ctlr),
+ i);
return -1;
}
for (i = 0; i < n; i++) {
@@ -2209,7 +2240,7 @@
memset(olds, 0xff, sizeof olds);
p = NULL;
head = tail = NULL;
- STAILQ_FOREACH(p, &pci_devices, all_dev) {
+ STAILQ_FOREACH (p, &pci_devices, all_dev) {
type = didtype(p);
if (type == -1)
continue;
@@ -2218,7 +2249,8 @@
if (p->bar[Abar].mmio_base32 == 0)
continue;
if (niactlr == NCtlr) {
- printk("ahci: iapnp: %s: too many controllers\n", tname[type]);
+ printk("ahci: iapnp: %s: too many controllers\n",
+ tname[type]);
break;
}
c = iactlr + niactlr;
@@ -2229,15 +2261,16 @@
qlock_init(&s->ql);
qlock_init(&s->unitlock);
c->physio = p->bar[Abar].mmio_base32 & ~0xf;
- c->mmio = (void *)vmap_pmem_nocache(c->physio, p->bar[Abar].mmio_sz);
+ c->mmio =
+ (void *)vmap_pmem_nocache(c->physio, p->bar[Abar].mmio_sz);
spinlock_init_irqsave(&c->Lock);
if (c->mmio == 0) {
- printk("ahci: %s: address %#lX in use did=%#x\n", Tname(c),
- c->physio, p->dev_id);
+ printk("ahci: %s: address %#lX in use did=%#x\n",
+ Tname(c), c->physio, p->dev_id);
continue;
}
- printk("sdiahci %s: Mapped %p/%d to %p\n", tname[type], c->physio,
- p->bar[Abar].mmio_sz, c->mmio);
+ printk("sdiahci %s: Mapped %p/%d to %p\n", tname[type],
+ c->physio, p->bar[Abar].mmio_sz, c->mmio);
c->pci = p;
c->type = type;
@@ -2310,11 +2343,13 @@
else if (d->smartrs == 0)
p = seprintf(p, e, "smart\tdisabled\n");
else
- p = seprintf(p, e, "smart\t%s\n", smarttab[d->portm.smart]);
+ p = seprintf(p, e, "smart\t%s\n",
+ smarttab[d->portm.smart]);
p = seprintf(p, e, "flag\t");
p = pflag(p, e, d->portm.feat);
} else
- p = seprintf(p, e, "no disk present [%s]\n", diskstates[d->state]);
+ p = seprintf(p, e, "no disk present [%s]\n",
+ diskstates[d->state]);
serror = ahci_port_read32(port, PORT_SERR);
task = ahci_port_read32(port, PORT_TFD);
cmd = ahci_port_read32(port, PORT_CMD);
@@ -2324,7 +2359,8 @@
sstatus = ahci_port_read32(port, PORT_SSTS);
serrstr(serror, buf, buf + sizeof(buf) - 1);
p = seprintf(p, e,
- "reg\ttask %#lx cmd %#lx serr %#lx %s ci %#lx is %#lx; sig %#lx sstatus %06#lx\n",
+ "reg\ttask %#lx cmd %#lx serr %#lx %s ci %#lx is %#lx; "
+ "sig %#lx sstatus %06#lx\n",
task, cmd, serror, buf, ci, is, sig, sstatus);
if (d->unit == NULL)
panic("iarctl: nil d->unit");
@@ -2500,9 +2536,9 @@
struct ctlr *ctlr;
#define has(x, str) \
- do { \
- if (cap & (x)) \
- p = seprintf(p, e, "%s ", (str)); \
+ do { \
+ if (cap & (x)) \
+ p = seprintf(p, e, "%s ", (str)); \
} while (0)
ctlr = sdev->ctlr;
@@ -2531,9 +2567,10 @@
isr = ahci_hba_read32(hba, HBA_ISR);
ver = ahci_hba_read32(hba, HBA_VS);
return seprintf(
- p, e, "iss %ld ncs %ld np %ld; ghc %#lx isr %#lx pi %#lx %s ver %#lx\n",
- (cap >> 20) & 0xf, (cap >> 8) & 0x1f, 1 + (cap & 0x1f), ghc, isr, pi,
- ver);
+ p, e,
+ "iss %ld ncs %ld np %ld; ghc %#lx isr %#lx pi %#lx %s ver %#lx\n",
+ (cap >> 20) & 0xf, (cap >> 8) & 0x1f, 1 + (cap & 0x1f), ghc, isr,
+ pi, ver);
#undef has
}
@@ -2558,7 +2595,8 @@
switch (cmd->nf) {
default:
- sdierror(cmd, "%s: %d args, only 1 or 2 allowed", __func__, cmd->nf);
+ sdierror(cmd, "%s: %d args, only 1 or 2 allowed", __func__,
+ cmd->nf);
case 1:
*v ^= 1;
break;
@@ -2575,20 +2613,12 @@
struct sdifc sdiahciifc = {
"iahci",
- iapnp,
- NULL, /* legacy */
- iaenable,
- iadisable,
+ iapnp, NULL, /* legacy */
+ iaenable, iadisable,
- iaverify,
- iaonline,
- iario,
- iarctl,
- iawctl,
+ iaverify, iaonline, iario, iarctl, iawctl,
- scsibio,
- NULL, /* probe */
- NULL, /* clear */
- iartopctl,
- iawtopctl,
+ scsibio, NULL, /* probe */
+ NULL, /* clear */
+ iartopctl, iawtopctl,
};
diff --git a/kern/drivers/dev/sdscsi.c b/kern/drivers/dev/sdscsi.c
index 1a63300..f99a517 100644
--- a/kern/drivers/dev/sdscsi.c
+++ b/kern/drivers/dev/sdscsi.c
@@ -7,13 +7,12 @@
* in the LICENSE file.
*/
-
#include <assert.h>
#include <cpio.h>
#include <error.h>
-#include <net/ip.h>
#include <kmalloc.h>
#include <kref.h>
+#include <net/ip.h>
#include <pmap.h>
#include <sd.h>
#include <slab.h>
@@ -164,7 +163,8 @@
/*
* If no medium present, bail out.
* If unit is becoming ready, rather than not
- * not ready, wait a little then poke it again. */
+ * not ready, wait a little then poke it again.
+ */
if (r->sense[12] == 0x3A)
break;
if (r->sense[12] != 0x04 || r->sense[13] != 0x01)
@@ -226,8 +226,10 @@
default:
break;
case 0:
- unit->sectors = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
- unit->secsize = (p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7];
+ unit->sectors =
+ (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+ unit->secsize =
+ (p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7];
/*
* Some ATAPI CD readers lie about the block size.
@@ -405,8 +407,8 @@
default:
break;
case 0x01: /* recovered error */
- printd("%s: recovered error at sector %llu\n", unit->SDperm.name,
- bno);
+ printd("%s: recovered error at sector %llu\n",
+ unit->SDperm.name, bno);
rlen = r->rlen;
break;
case 0x06: /* check condition */
diff --git a/kern/drivers/dev/srv.c b/kern/drivers/dev/srv.c
index 6eb7509..04d5e1f 100644
--- a/kern/drivers/dev/srv.c
+++ b/kern/drivers/dev/srv.c
@@ -48,10 +48,10 @@
TAILQ_ENTRY(srvfile) link;
char *name;
struct chan *chan;
- struct kref ref; /* +1 for existing on create, -1 on remove */
+ struct kref ref; /* +1 for existing on create, -1 on remove */
char *user;
uint32_t perm;
- atomic_t opens; /* used for exclusive open checks */
+ atomic_t opens; /* used for exclusive open checks */
};
struct srvfile *top_dir;
@@ -60,13 +60,14 @@
* without the lock. (if you're on the list, we can grab a ref). */
spinlock_t srvlock = SPINLOCK_INITIALIZER;
-atomic_t nr_srvs = 0; /* debugging - concerned about leaking mem */
+atomic_t nr_srvs = 0; /* debugging - concerned about leaking mem */
/* Given a pointer (internal ref), we attempt to get a kref */
static bool grab_ref(struct srvfile *srv)
{
bool ret = FALSE;
struct srvfile *srv_i;
+
spin_lock(&srvlock);
TAILQ_FOREACH(srv_i, &srvfiles, link) {
if (srv_i == srv) {
@@ -81,6 +82,7 @@
static void srv_release(struct kref *kref)
{
struct srvfile *srv = container_of(kref, struct srvfile, ref);
+
kfree(srv->user);
kfree(srv->name);
if (srv->chan)
@@ -111,13 +113,15 @@
spin_unlock(&srvlock);
return -1;
}
- /* update c to point to our new srvfile. this keeps the chan and its srv in
- * sync with what we're genning. */
+ /* update c to point to our new srvfile. this keeps the chan and its
+ * srv in sync with what we're genning. */
c->aux = next; /* uncounted ref */
mkqid(&q, Qsrvfile, 0, QTFILE);
- /* once we release the lock, next could disappear, including next->name */
+ /* once we release the lock, next could disappear, including next->name
+ */
strlcpy(get_cur_genbuf(), next->name, GENBUF_SZ);
- devdir(c, q, get_cur_genbuf(), 1 /* length */ , next->user, next->perm, dp);
+ devdir(c, q, get_cur_genbuf(), 1 /* length */ , next->user, next->perm,
+ dp);
spin_unlock(&srvlock);
return 1;
}
@@ -144,6 +148,7 @@
/* the inferno attach was pretty complicated, but
* we're not sure that complexity is needed. */
struct chan *c = devattach(devname(), spec);
+
mkqid(&c->qid, Qtopdir, 0, QTDIR);
/* c->aux is an uncounted ref */
c->aux = top_dir;
@@ -161,8 +166,7 @@
return devstat(c, db, n, 0, 0, srvgen);
}
-char*
-srvname(struct chan *c)
+char *srvname(struct chan *c)
{
struct srvfile *srv_i;
char *s;
@@ -185,7 +189,9 @@
{
ERRSTACK(1);
struct srvfile *srv;
- openmode(omode); /* used as an error checker in plan9, does little now */
+
+ /* used as an error checker in plan9, does little now */
+ openmode(omode);
if (c->qid.type & QTDIR) {
if (omode & O_WRITE)
error(EISDIR, ERROR_FIXME);
@@ -207,8 +213,8 @@
/* srv->chan is write-once, so we don't need to sync. */
if (!srv->chan)
error(EFAIL, "srv file has no chan yet");
- /* this is more than just the ref - 1, since there will be refs in flight
- * as gens work their way through the list */
+ /* this is more than just the ref - 1, since there will be refs in
+ * flight as gens work their way through the list */
atomic_inc(&srv->opens);
/* the magic of srv: open c, get c->srv->chan back */
cclose(c);
@@ -304,8 +310,9 @@
kbuf = kmalloc(count + 1, MEM_WAIT);
strlcpy(kbuf, va, count + 1);
fd = strtoul(kbuf, 0, 10);
- /* the magic of srv: srv stores the chan corresponding to the fd. -1 for
- * mode, so we just get the chan with no checks (RDWR would work too). */
+ /* the magic of srv: srv stores the chan corresponding to the fd. -1
+ * for mode, so we just get the chan with no checks (RDWR would work
+ * too). */
new_chan = fdtochan(¤t->open_files, fd, -1, FALSE, TRUE);
/* fdtochan already increffed for us */
if (!__sync_bool_compare_and_swap(&srv->chan, 0, new_chan)) {
diff --git a/kern/drivers/dev/tmpfs.c b/kern/drivers/dev/tmpfs.c
index 2ddb280..f8f2eeb 100644
--- a/kern/drivers/dev/tmpfs.c
+++ b/kern/drivers/dev/tmpfs.c
@@ -32,8 +32,8 @@
struct tmpfs {
struct tree_filesystem tfs;
- atomic_t qid;
- struct kref users;
+ atomic_t qid;
+ struct kref users;
};
static uint64_t tmpfs_get_qid_path(struct tmpfs *tmpfs)
@@ -65,9 +65,10 @@
fs_file_init_dir(&tf->file, dir_type, dir_dev, user, perm);
dir->qid.path = tmpfs_get_qid_path((struct tmpfs*)tf->tfs);
dir->qid.vers = 0;
- /* This is the "+1 for existing" ref. There is no backing store for the FS,
- * such as a disk or 9p, so we can't get rid of a file until it is unlinked
- * and decreffed. Note that KFS doesn't use pruners or anything else. */
+ /* This is the "+1 for existing" ref. There is no backing store for the
+ * FS, such as a disk or 9p, so we can't get rid of a file until it is
+ * unlinked and decreffed. Note that KFS doesn't use pruners or
+ * anything else. */
__kref_get(&tf->kref, 1);
}
@@ -75,22 +76,22 @@
static void tmpfs_tf_create(struct tree_file *parent, struct tree_file *child,
int perm)
{
- __tmpfs_tf_init(child, parent->file.dir.type, parent->file.dir.dev, &eve,
- perm);
+ __tmpfs_tf_init(child, parent->file.dir.type, parent->file.dir.dev,
+ &eve, perm);
}
static void tmpfs_tf_rename(struct tree_file *tf, struct tree_file *old_parent,
struct tree_file *new_parent, const char *name,
int flags)
{
- /* We don't have a backend, so we don't need to do anything additional for
- * rename. */
+ /* We don't have a backend, so we don't need to do anything additional
+ * for rename. */
}
static bool tmpfs_tf_has_children(struct tree_file *parent)
{
- /* The tree_file parent list is complete and not merely a cache for a real
- * backend. */
+ /* The tree_file parent list is complete and not merely a cache for a
+ * real backend. */
return !list_empty(&parent->children);
}
@@ -111,10 +112,10 @@
{
memset(page2kva(pg), 0, PGSIZE);
atomic_or(&pg->pg_flags, PG_UPTODATE);
- /* Pretend that we blocked while filing this page. This catches a lot of
- * bugs. It does slightly slow down the kernel, but it's only when filling
- * the page cache, and considering we are using a RAMFS, you shouldn't
- * measure things that actually rely on KFS's performance. */
+ /* Pretend that we blocked while filing this page. This catches a lot
+ * of bugs. It does slightly slow down the kernel, but it's only when
+ * filling the page cache, and considering we are using a RAMFS, you
+ * shouldn't measure things that actually rely on KFS's performance. */
kthread_usleep(1);
return 0;
}
@@ -185,8 +186,8 @@
struct tree_filesystem *tfs = kzmalloc(sizeof(struct tmpfs), MEM_WAIT);
struct tmpfs *tmpfs = (struct tmpfs*)tfs;
- /* All distinct chans get a ref on the filesystem, so that we can destroy it
- * when the last user disconnects/closes. */
+ /* All distinct chans get a ref on the filesystem, so that we can
+ * destroy it when the last user disconnects/closes. */
kref_init(&tmpfs->users, tmpfs_release, 1);
/* This gives us one ref on root, dropped during tmpfs_release(). */
@@ -194,10 +195,11 @@
tfs->tf_ops = tmpfs_tf_ops;
tfs->fs_ops = tmpfs_fs_ops;
- /* This gives us an extra refcnt on tfs->root. This is "+1 for existing."
- * It is decreffed during the purge CB. */
- __tmpfs_tf_init(tfs->root, &tmpfs_devtab - devtab, 0, &eve, DMDIR | 0777);
- /* This also increfs, copying tfs->root's ref for the chan it returns. */
+ /* This gives us an extra refcnt on tfs->root. This is "+1 for
+ * existing." It is decreffed during the purge CB. */
+ __tmpfs_tf_init(tfs->root, &tmpfs_devtab - devtab, 0, &eve, DMDIR |
+ 0777);
+ /* This also increfs, copying tfs->root's ref for the chan it returns.*/
return tree_file_alloc_chan(tfs->root, &tmpfs_devtab, "#tmpfs");
}
diff --git a/kern/drivers/dev/vars.c b/kern/drivers/dev/vars.c
index 1e4a375..69ff731 100644
--- a/kern/drivers/dev/vars.c
+++ b/kern/drivers/dev/vars.c
@@ -14,8 +14,8 @@
* d (decimal)
* u (unsigned)
* o (octal)
- * c (char) does not need a size
- * s (string) does not need a size
+ * c (char) does not need a size
+ * s (string) does not need a size
* size is:
* b (8 bits)
* h (16 bits)
@@ -105,7 +105,7 @@
}
static struct walkqid *vars_walk(struct chan *c, struct chan *nc, char **name,
- unsigned int nname)
+ unsigned int nname)
{
ERRSTACK(1);
struct walkqid *ret;
@@ -227,10 +227,11 @@
qlock(&vars_lock);
new_slot = find_free_var();
if (!new_slot) {
- vars_dir = kreallocarray(vars_dir, nr_vars * 2, sizeof(struct dirtab),
- MEM_WAIT);
+ vars_dir = kreallocarray(vars_dir, nr_vars * 2,
+ sizeof(struct dirtab), MEM_WAIT);
if (!vars_dir)
- error(ENOMEM, "krealloc_array failed, nr_vars was %p", nr_vars);
+ error(ENOMEM, "krealloc_array failed, nr_vars was %p",
+ nr_vars);
memset(vars_dir + nr_vars, 0, nr_vars * sizeof(struct dirtab));
for (size_t i = nr_vars; i < nr_vars * 2; i++)
vars_dir[i].qid.vers = -1;
@@ -318,7 +319,8 @@
* double-check for the user-provided vars. */
fmt = strchr(c->name->s, '!');
if (!fmt)
- error(EINVAL, "var %s has no ! in its format string", c->name->s);
+ error(EINVAL, "var %s has no ! in its format string",
+ c->name->s);
fmt++;
data_fmt = *fmt;
if (!data_fmt)
@@ -348,34 +350,43 @@
switch (data_size) {
case 'b':
if (is_signed)
- size = snprintf(tmp, size, fmt_int, *(int8_t*)c->qid.path);
+ size = snprintf(tmp, size, fmt_int,
+ *(int8_t*)c->qid.path);
else
- size = snprintf(tmp, size, fmt_int, *(uint8_t*)c->qid.path);
+ size = snprintf(tmp, size, fmt_int,
+ *(uint8_t*)c->qid.path);
break;
case 'h':
if (is_signed)
- size = snprintf(tmp, size, fmt_int, *(int16_t*)c->qid.path);
+ size = snprintf(tmp, size, fmt_int,
+ *(int16_t*)c->qid.path);
else
- size = snprintf(tmp, size, fmt_int, *(uint16_t*)c->qid.path);
+ size = snprintf(tmp, size, fmt_int,
+ *(uint16_t*)c->qid.path);
break;
case 'w':
if (is_signed)
- size = snprintf(tmp, size, fmt_int, *(int32_t*)c->qid.path);
+ size = snprintf(tmp, size, fmt_int,
+ *(int32_t*)c->qid.path);
else
- size = snprintf(tmp, size, fmt_int, *(uint32_t*)c->qid.path);
+ size = snprintf(tmp, size, fmt_int,
+ *(uint32_t*)c->qid.path);
break;
case 'g':
if (is_signed)
- size = snprintf(tmp, size, fmt_int, *(int64_t*)c->qid.path);
+ size = snprintf(tmp, size, fmt_int,
+ *(int64_t*)c->qid.path);
else
- size = snprintf(tmp, size, fmt_int, *(uint64_t*)c->qid.path);
+ size = snprintf(tmp, size, fmt_int,
+ *(uint64_t*)c->qid.path);
break;
default:
error(EINVAL, "Bad #%s size %c", devname(), data_size);
}
break;
default:
- error(EINVAL, "Unknown #%s data_format %c", devname(), data_fmt);
+ error(EINVAL, "Unknown #%s data_format %c", devname(),
+ data_fmt);
}
fmt++;
if (*fmt)
@@ -403,7 +414,7 @@
struct dirtab *dir;
char *dir_name;
- /* chan's name may have multiple elements in the path; get the last one. */
+ /* chan may have multiple elements in the path; get the last one. */
dir_name = strrchr(c->name->s, '/');
dir_name = dir_name ? dir_name + 1 : c->name->s;
diff --git a/kern/drivers/dev/version.c b/kern/drivers/dev/version.c
index f475a91..d083eb4 100644
--- a/kern/drivers/dev/version.c
+++ b/kern/drivers/dev/version.c
@@ -28,13 +28,13 @@
struct dev verdevtab;
static struct dirtab vertab[] = {
- {".", {Kverdirqid, 0, QTDIR}, 0, DMDIR|0550},
- {"build_id", {Kverbuildid}, 0, 0444},
- {"date", {Kverdate}, 0, 0444},
- {"commitid", {Kvercommitid}, 0, 0444},
- {"version", {Kverversion}, 0, 0444},
- {"version_name", {Kverversionname}, 0, 0444},
- {"kconfig", {Kverkconfig}, 0, 0444},
+ {".", {Kverdirqid, 0, QTDIR}, 0, DMDIR|0550},
+ {"build_id", {Kverbuildid}, 0, 0444},
+ {"date", {Kverdate}, 0, 0444},
+ {"commitid", {Kvercommitid}, 0, 0444},
+ {"version", {Kverversion}, 0, 0444},
+ {"version_name",{Kverversionname}, 0, 0444},
+ {"kconfig", {Kverkconfig}, 0, 0444},
};
extern char __note_build_id_start[];
@@ -84,7 +84,8 @@
vertab[Kverdate].length = ver_get_file_size(build_info_date);
vertab[Kvercommitid].length = ver_get_file_size(build_info_commitid);
vertab[Kverversion].length = ver_get_file_size(build_info_version);
- vertab[Kverversionname].length = ver_get_file_size(build_info_version_name);
+ vertab[Kverversionname].length =
+ ver_get_file_size(build_info_version_name);
vertab[Kverkconfig].length = strlen(__kconfig_str) + 1;
}
@@ -94,7 +95,7 @@
}
static struct walkqid *ver_walk(struct chan *c, struct chan *nc, char **name,
- unsigned int nname)
+ unsigned int nname)
{
return devwalk(c, nc, name, nname, vertab, ARRAY_SIZE(vertab), devgen);
}
@@ -152,19 +153,23 @@
return read_buildid(va, n, off);
case Kverdate:
if (build_info_date)
- return ver_emit_nlstr(va, build_info_date, n, (long) off);
+ return ver_emit_nlstr(va, build_info_date, n,
+ (long) off);
break;
case Kvercommitid:
if (build_info_commitid)
- return ver_emit_nlstr(va, build_info_commitid, n, (long) off);
+ return ver_emit_nlstr(va, build_info_commitid, n,
+ (long) off);
break;
case Kverversion:
if (build_info_version)
- return ver_emit_nlstr(va, build_info_version, n, (long) off);
+ return ver_emit_nlstr(va, build_info_version, n,
+ (long) off);
break;
case Kverversionname:
if (build_info_version_name)
- return ver_emit_nlstr(va, build_info_version_name, n, (long) off);
+ return ver_emit_nlstr(va, build_info_version_name, n,
+ (long) off);
break;
case Kverkconfig:
return readstr(off, va, n, __kconfig_str);
diff --git a/kern/drivers/net/bnx2x/bnx2x_cmn.c b/kern/drivers/net/bnx2x/bnx2x_cmn.c
index 9ee6d74..835bd61 100644
--- a/kern/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/kern/drivers/net/bnx2x/bnx2x_cmn.c
@@ -1020,7 +1020,8 @@
if (likely(bnx2x_alloc_rx_data(bp, fp, bd_prod,
0) == 0)) {
dma_unmap_single(&bp->pdev->dev,
- dma_unmap_addr(rx_buf, mapping),
+ dma_unmap_addr(rx_buf,
+ mapping),
fp->rx_buf_size,
DMA_FROM_DEVICE);
/* TODO: block extra data here */
@@ -1135,7 +1136,8 @@
prefetch(&fp->sb_running_index[SM_RX_ID]);
// AKAROS_PORT
- send_kernel_message(core_id(), bnx2x_poll, (long)fp, 0, 0, KMSG_ROUTINE);
+ send_kernel_message(core_id(), bnx2x_poll, (long)fp, 0, 0,
+ KMSG_ROUTINE);
napi_schedule_irqoff(&bnx2x_fp(bp, fp->index, napi));
return;
@@ -1761,7 +1763,8 @@
if (CNIC_SUPPORT(bp)) {
offset++;
// AKAROS_PORT
- rc = register_irq(0, bullshit_handler, 0, pci_to_tbdf(bp->pdev));
+ rc = register_irq(0, bullshit_handler, 0,
+ pci_to_tbdf(bp->pdev));
if (rc) {
BNX2X_ERR("Fucked up getting a CNIC MSIX vector!");
return -EBUSY;
@@ -2142,7 +2145,8 @@
#if 0 // AKAROS_PORT
netdev_rss_key_fill(params.rss_key, T_ETH_RSS_KEY * 4);
#else
- /* linux picks a random, once, then uses it here. it could be 5a! */
+ /* linux picks a random, once, then uses it here. it could be
+ * 5a! */
memset(params.rss_key, 0x5a, T_ETH_RSS_KEY * 4);
#endif
__set_bit(BNX2X_RSS_SET_SRCH, ¶ms.rss_flags);
@@ -3950,7 +3954,8 @@
/* when transmitting in a vf, start bd must hold the ethertype
* for fw to enforce it
*/
- uint16_t type_le16 = (eth->type[0] << 8) | eth->type[1];// AKAROS_PORT
+ // AKAROS_PORT
+ uint16_t type_le16 = (eth->type[0] << 8) | eth->type[1];
#ifndef BNX2X_STOP_ON_ERROR
if (IS_VF(bp))
#endif
diff --git a/kern/drivers/net/bnx2x/bnx2x_dev.c b/kern/drivers/net/bnx2x/bnx2x_dev.c
index 7b7b16a..b31691f 100644
--- a/kern/drivers/net/bnx2x/bnx2x_dev.c
+++ b/kern/drivers/net/bnx2x/bnx2x_dev.c
@@ -69,13 +69,13 @@
continue;
/* based on the stat, spit out a string */
switch (i) {
- default:
- ctlr->statistics[i] += r;
- if (ctlr->statistics[i] == 0)
- continue;
- l += snprintf(p + l, READSTR - l, "%s: %ud %ud\n",
- s, ctlr->statistics[i], r);
- break;
+ default:
+ ctlr->statistics[i] += r;
+ if (ctlr->statistics[i] == 0)
+ continue;
+ l += snprintf(p + l, READSTR - l, "%s: %ud %ud\n", s,
+ ctlr->statistics[i], r);
+ break;
}
}
@@ -130,23 +130,23 @@
* again). Consider this:
*
* this func:
- * calls start_xmit, fails with BUSY. wants to set ABORT flag
+ * calls start_xmit, fails with BUSY. wants to set ABORT flag
*
* PAUSE - meanwhile:
*
* tx_int clears the ABORT flag, then pokes:
- * drain so there is room;
- * clear flag (combo of these is "post work");
- * poke;. guaranteed that poke will happen after we cleared flag.
- * but it is concurrent with this function
+ * drain so there is room;
+ * clear flag (combo of these is "post work");
+ * poke;. guaranteed that poke will happen after we cleared flag.
+ * but it is concurrent with this function
*
- * RESUME this func:
+ * RESUME this func:
*
- * sets ABORT flag
- * returns.
- * tx_int's poke ensures we run again
- * we run again and see ABORT, then return
- * never try again til the next tx_int, if ever
+ * sets ABORT flag
+ * returns.
+ * tx_int's poke ensures we run again
+ * we run again and see ABORT, then return
+ * never try again til the next tx_int, if ever
*
* Instead, in this func, we must set ABORT flag, then check tx_avail. Or
* have two flags, one set by us, another set by tx_int, where this func only
@@ -167,18 +167,20 @@
while ((block = qget(oq))) {
if ((bnx2x_start_xmit(block, txdata) != NETDEV_TX_OK)) {
- /* all queue readers are sync'd by the poke, so we can putback
- * without fear of going out of order. */
+ /* all queue readers are sync'd by the poke, so we can
+ * putback without fear of going out of order. */
- /* TODO: q code has methods that should be called with the spinlock
- * held, but no methods to do the locking... */
+ /* TODO: q code has methods that should be called with
+ * the spinlock held, but no methods to do the
+ * locking... */
//spin_unlock_irqsave(&oq->lock);
qputback(oq, block);
//spin_lock_irqsave(&oq->lock);
- /* device can't handle any more, we're done for now. tx_int will
- * poke when space frees up. it may be poking concurrently, and in
- * which case, we'll run again immediately. */
+ /* device can't handle any more, we're done for now.
+ * tx_int will poke when space frees up. it may be
+ * poking concurrently, and in which case, we'll run
+ * again immediately. */
break;
}
}
@@ -208,7 +210,8 @@
// TODO: use your block size, e.g. Rbsz
bp = block_alloc(64, MEM_ATOMIC);
if (bp == NULL) {
- /* needs to be a safe print for interrupt level */
+ /* needs to be a safe print for interrupt level
+ * */
printk("#l%d bnx2x_replenish: no available buffers\n",
ctlr->edev->ctlrno);
break;
@@ -254,7 +257,8 @@
rendez_sleep(&ctlr->rrendez, bnx2x_rim, ctlr);
for (;;) {
- /* if we can get a block, here's how to ram it up the stack */
+ /* if we can get a block, here's how to ram it up the
+ * stack */
if (1) {
bp = (void*)0xdeadbeef;
@@ -262,10 +266,10 @@
//bp->wp += rd->length;
//bp->next = NULL;
/* conditionally, set block flags */
- //bp->flag |= Bipck; /* IP checksum done in HW */
- //bp->flag |= Btcpck | Budpck;
- //bp->checksum = rd->checksum;
- //bp->flag |= Bpktck; /* Packet checksum? */
+ //bp->flag |= Bipck; /* IP checksum done in HW*/
+ //bp->flag |= Btcpck | Budpck;
+ //bp->checksum = rd->checksum;
+ //bp->flag |= Bpktck; /* Packet checksum? */
etheriq(edev, bp, 1);
} else {
//freeb(ctlr->rb[rdh]);
@@ -324,8 +328,8 @@
/* At some point, wake up the rproc */
rendez_wakeup(&ctlr->rrendez);
- /* optionally, might need to transmit (not sure if this is a good idea in
- * hard irq or not) */
+ /* optionally, might need to transmit (not sure if this is a good idea
+ * in hard irq or not) */
bnx2x_transmit(edev);
}
@@ -358,7 +362,6 @@
const struct pci_device_id *pci_id;
STAILQ_FOREACH(pcidev, &pci_devices, all_dev) {
- /* This checks that pcidev is a Network Controller for Ethernet */
if (pcidev->class != 0x02 || pcidev->subclass != 0x00)
continue;
id = pcidev->dev_id << 16 | pcidev->ven_id;
@@ -403,8 +406,8 @@
{
struct bnx2x *ctlr;
- /* Allocs ctlrs for all PCI devices matching our IDs, does various PCI and
- * MMIO/port setup */
+ /* Allocs ctlrs for all PCI devices matching our IDs, does various PCI
+ * and MMIO/port setup */
run_once(bnx2x_pci());
spin_lock(&bnx2x_tq_lock);
@@ -423,7 +426,7 @@
ctlr->edev = edev;
strlcpy(edev->drv_name, "bnx2x", KNAMELEN);
- //edev->port = ctlr->port; /* might just remove this from devether */
+ //edev->port = ctlr->port; /* might remove this from devether */
edev->irq = ctlr->pcidev->irqline;
edev->tbdf = MKBUS(BusPCI, ctlr->pcidev->bus, ctlr->pcidev->dev,
ctlr->pcidev->func);
diff --git a/kern/drivers/net/ether8139.c b/kern/drivers/net/ether8139.c
index 8fab64e..f5761df 100644
--- a/kern/drivers/net/ether8139.c
+++ b/kern/drivers/net/ether8139.c
@@ -44,88 +44,88 @@
#include <net/ip.h>
#include <arch/io.h>
-enum { /* registers */
- Idr0 = 0x0000, /* MAC address */
- Mar0 = 0x0008, /* Multicast address */
- Tsd0 = 0x0010, /* Transmit Status Descriptor0 */
- Tsad0 = 0x0020, /* Transmit Start Address Descriptor0 */
+enum { /* registers */
+ Idr0 = 0x0000, /* MAC address */
+ Mar0 = 0x0008, /* Multicast address */
+ Tsd0 = 0x0010, /* Transmit Status Descriptor0 */
+ Tsad0 = 0x0020, /* Transmit Start Address Descriptor0 */
Rbstart = 0x0030, /* Receive Buffer Start Address */
- Erbcr = 0x0034, /* Early Receive Byte Count */
- Ersr = 0x0036, /* Early Receive Status */
- Cr = 0x0037, /* Command Register */
- Capr = 0x0038, /* Current Address of Packet Read */
- Cbr = 0x003A, /* Current Buffer Address */
- Imr = 0x003C, /* Interrupt Mask */
- Isr = 0x003E, /* Interrupt Status */
- Tcr = 0x0040, /* Transmit Configuration */
- Rcr = 0x0044, /* Receive Configuration */
- Tctr = 0x0048, /* Timer Count */
- Mpc = 0x004C, /* Missed Packet Counter */
+ Erbcr = 0x0034, /* Early Receive Byte Count */
+ Ersr = 0x0036, /* Early Receive Status */
+ Cr = 0x0037, /* Command Register */
+ Capr = 0x0038, /* Current Address of Packet Read */
+ Cbr = 0x003A, /* Current Buffer Address */
+ Imr = 0x003C, /* Interrupt Mask */
+ Isr = 0x003E, /* Interrupt Status */
+ Tcr = 0x0040, /* Transmit Configuration */
+ Rcr = 0x0044, /* Receive Configuration */
+ Tctr = 0x0048, /* Timer Count */
+ Mpc = 0x004C, /* Missed Packet Counter */
Cr9346 = 0x0050, /* 9346 Command Register */
Config0 = 0x0051, /* Configuration Register 0 */
Config1 = 0x0052, /* Configuration Register 1 */
TimerInt = 0x0054, /* Timer Interrupt */
- Msr = 0x0058, /* Media Status */
+ Msr = 0x0058, /* Media Status */
Config3 = 0x0059, /* Configuration Register 3 */
Config4 = 0x005A, /* Configuration Register 4 */
Mulint = 0x005C, /* Multiple Interrupt Select */
- RerID = 0x005E, /* PCI Revision ID */
- Tsad = 0x0060, /* Transmit Status of all Descriptors */
+ RerID = 0x005E, /* PCI Revision ID */
+ Tsad = 0x0060, /* Transmit Status of all Descriptors */
- Bmcr = 0x0062, /* Basic Mode Control */
- Bmsr = 0x0064, /* Basic Mode Status */
- Anar = 0x0066, /* Auto-Negotiation Advertisment */
+ Bmcr = 0x0062, /* Basic Mode Control */
+ Bmsr = 0x0064, /* Basic Mode Status */
+ Anar = 0x0066, /* Auto-Negotiation Advertisment */
Anlpar = 0x0068, /* Auto-Negotiation Link Partner */
- Aner = 0x006A, /* Auto-Negotiation Expansion */
- Dis = 0x006C, /* Disconnect Counter */
- Fcsc = 0x006E, /* False Carrier Sense Counter */
+ Aner = 0x006A, /* Auto-Negotiation Expansion */
+ Dis = 0x006C, /* Disconnect Counter */
+ Fcsc = 0x006E, /* False Carrier Sense Counter */
Nwaytr = 0x0070, /* N-way Test */
- Rec = 0x0072, /* RX_ER Counter */
- Cscr = 0x0074, /* CS Configuration */
+ Rec = 0x0072, /* RX_ER Counter */
+ Cscr = 0x0074, /* CS Configuration */
Phy1parm = 0x0078, /* PHY Parameter 1 */
Twparm = 0x007C, /* Twister Parameter */
Phy2parm = 0x0080, /* PHY Parameter 2 */
};
-enum { /* Cr */
- Bufe = 0x01, /* Rx Buffer Empty */
- Te = 0x04, /* Transmitter Enable */
- Re = 0x08, /* Receiver Enable */
- Rst = 0x10, /* Software Reset */
+enum { /* Cr */
+ Bufe = 0x01, /* Rx Buffer Empty */
+ Te = 0x04, /* Transmitter Enable */
+ Re = 0x08, /* Receiver Enable */
+ Rst = 0x10, /* Software Reset */
};
-enum { /* Imr/Isr */
- Rok = 0x0001, /* Receive OK */
- Rer = 0x0002, /* Receive Error */
- Tok = 0x0004, /* Transmit OK */
- Ter = 0x0008, /* Transmit Error */
- Rxovw = 0x0010, /* Receive Buffer Overflow */
- PunLc = 0x0020, /* Packet Underrun or Link Change */
- Fovw = 0x0040, /* Receive FIFO Overflow */
- Clc = 0x2000, /* Cable Length Change */
+enum { /* Imr/Isr */
+ Rok = 0x0001, /* Receive OK */
+ Rer = 0x0002, /* Receive Error */
+ Tok = 0x0004, /* Transmit OK */
+ Ter = 0x0008, /* Transmit Error */
+ Rxovw = 0x0010, /* Receive Buffer Overflow */
+ PunLc = 0x0020, /* Packet Underrun or Link Change */
+ Fovw = 0x0040, /* Receive FIFO Overflow */
+ Clc = 0x2000, /* Cable Length Change */
Timerbit = 0x4000, /* Timer */
- Serr = 0x8000, /* System Error */
+ Serr = 0x8000, /* System Error */
};
-enum { /* Tcr */
- Clrabt = 0x00000001, /* Clear Abort */
- TxrrSHIFT = 4, /* Transmit Retry Count */
+enum { /* Tcr */
+ Clrabt = 0x00000001, /* Clear Abort */
+ TxrrSHIFT = 4, /* Transmit Retry Count */
TxrrMASK = 0x000000F0,
MtxdmaSHIFT = 8, /* Max. DMA Burst Size */
MtxdmaMASK = 0x00000700,
Mtxdma2048 = 0x00000700,
Acrc = 0x00010000, /* Append CRC (not) */
- LbkSHIFT = 17, /* Loopback Test */
+ LbkSHIFT = 17, /* Loopback Test */
LbkMASK = 0x00060000,
Rtl8139ArevG = 0x00800000, /* RTL8139A Rev. G ID */
- IfgSHIFT = 24, /* Interframe Gap */
+ IfgSHIFT = 24, /* Interframe Gap */
IfgMASK = 0x03000000,
HwveridSHIFT = 26, /* Hardware Version ID */
HwveridMASK = 0x7C000000,
};
-enum { /* Rcr */
- Aap = 0x00000001, /* Accept All Packets */
+enum { /* Rcr */
+ Aap = 0x00000001, /* Accept All Packets */
Apm = 0x00000002, /* Accept Physical Match */
Am = 0x00000004, /* Accept Multicast */
Ab = 0x00000008, /* Accept Broadcast */
@@ -153,45 +153,45 @@
Erxthnone = 0x00000000,
};
-enum { /* Received Packet Status */
- Rcok = 0x0001, /* Receive Completed OK */
- Fae = 0x0002, /* Frame Alignment Error */
- Crc = 0x0004, /* CRC Error */
- Long = 0x0008, /* Long Packet */
- Runt = 0x0010, /* Runt Packet Received */
- Ise = 0x0020, /* Invalid Symbol Error */
- Bar = 0x2000, /* Broadcast Address Received */
- Pam = 0x4000, /* Physical Address Matched */
- Mar = 0x8000, /* Multicast Address Received */
+enum { /* Received Packet Status */
+ Rcok = 0x0001, /* Receive Completed OK */
+ Fae = 0x0002, /* Frame Alignment Error */
+ Crc = 0x0004, /* CRC Error */
+ Long = 0x0008, /* Long Packet */
+ Runt = 0x0010, /* Runt Packet Received */
+ Ise = 0x0020, /* Invalid Symbol Error */
+ Bar = 0x2000, /* Broadcast Address Received */
+ Pam = 0x4000, /* Physical Address Matched */
+ Mar = 0x8000, /* Multicast Address Received */
};
-enum { /* Media Status Register */
- Rxpf = 0x01, /* Pause Flag */
- Txpf = 0x02, /* Pause Flag */
- Linkb = 0x04, /* Inverse of Link Status */
- Speed10 = 0x08, /* 10Mbps */
+enum { /* Media Status Register */
+ Rxpf = 0x01, /* Pause Flag */
+ Txpf = 0x02, /* Pause Flag */
+ Linkb = 0x04, /* Inverse of Link Status */
+ Speed10 = 0x08, /* 10Mbps */
Auxstatus = 0x10, /* Aux. Power Present Status */
- Rxfce = 0x40, /* Receive Flow Control Enable */
- Txfce = 0x80, /* Transmit Flow Control Enable */
+ Rxfce = 0x40, /* Receive Flow Control Enable */
+ Txfce = 0x80, /* Transmit Flow Control Enable */
};
typedef struct Td Td;
-struct Td { /* Soft Transmit Descriptor */
+struct Td { /* Soft Transmit Descriptor */
int tsd;
int tsad;
uint8_t *data;
struct block *bp;
};
-enum { /* Tsd0 */
- SizeSHIFT = 0, /* Descriptor Size */
+enum { /* Tsd0 */
+ SizeSHIFT = 0, /* Descriptor Size */
SizeMASK = 0x00001FFF,
Own = 0x00002000,
Tun = 0x00004000, /* Transmit FIFO Underrun */
Tcok = 0x00008000, /* Transmit COmpleted OK */
EtxthSHIFT = 16, /* Early Tx Threshold */
EtxthMASK = 0x001F0000,
- NccSHIFT = 24, /* Number of Collisions Count */
+ NccSHIFT = 24, /* Number of Collisions Count */
NccMASK = 0x0F000000,
Cdh = 0x10000000, /* CD Heartbeat */
Owc = 0x20000000, /* Out of Window Collision */
@@ -200,8 +200,8 @@
};
enum {
- Rblen = Rblen64K, /* Receive Buffer Length */
- Ntd = 4, /* Number of Transmit Descriptors */
+ Rblen = Rblen64K, /* Receive Buffer Length */
+ Ntd = 4, /* Number of Transmit Descriptors */
};
#define Tdbsz ROUNDUP(sizeof(struct etherpkt), 4)
@@ -212,27 +212,27 @@
int active;
int id;
- qlock_t alock; /* attach */
- spinlock_t ilock; /* init */
- void *alloc; /* base of per-ctlr allocated data */
+ qlock_t alock; /* attach */
+ spinlock_t ilock; /* init */
+ void *alloc; /* base of per-ctlr allocated data */
- int rcr; /* receive configuration register */
- uint8_t *rbstart; /* receive buffer */
- int rblen; /* receive buffer length */
- int ierrs; /* receive errors */
+ int rcr; /* receive configuration register */
+ uint8_t *rbstart; /* receive buffer */
+ int rblen; /* receive buffer length */
+ int ierrs; /* receive errors */
- spinlock_t tlock; /* transmit */
+ spinlock_t tlock; /* transmit */
Td td[Ntd];
- int ntd; /* descriptors active */
- int tdh; /* host index into td */
- int tdi; /* interface index into td */
- int etxth; /* early transmit threshold */
- int taligned; /* packet required no alignment */
- int tunaligned; /* packet required alignment */
+ int ntd; /* descriptors active */
+ int tdh; /* host index into td */
+ int tdi; /* interface index into td */
+ int etxth; /* early transmit threshold */
+ int taligned; /* packet required no alignment */
+ int tunaligned; /* packet required alignment */
- int dis; /* disconnect counter */
- int fcsc; /* false carrier sense counter */
- int rec; /* RX_ER counter */
+ int dis; /* disconnect counter */
+ int fcsc; /* false carrier sense counter */
+ int rec; /* RX_ER counter */
} ctlr;
static struct ctlr *ctlrhead;
@@ -306,9 +306,11 @@
l += snprintf(p + l, READSTR - l, "Bmcr 0x%4.4x\n", csr16r(ctlr, Bmcr));
l += snprintf(p + l, READSTR - l, "Bmsr 0x%4.4x\n", csr16r(ctlr, Bmsr));
l += snprintf(p + l, READSTR - l, "Anar 0x%4.4x\n", csr16r(ctlr, Anar));
- l += snprintf(p + l, READSTR - l, "Anlpar 0x%4.4x\n", csr16r(ctlr, Anlpar));
+ l += snprintf(p + l, READSTR - l, "Anlpar 0x%4.4x\n",
+ csr16r(ctlr, Anlpar));
l += snprintf(p + l, READSTR - l, "Aner 0x%4.4x\n", csr16r(ctlr, Aner));
- l += snprintf(p + l, READSTR - l, "Nwaytr 0x%4.4x\n", csr16r(ctlr, Nwaytr));
+ l += snprintf(p + l, READSTR - l, "Nwaytr 0x%4.4x\n",
+ csr16r(ctlr, Nwaytr));
snprintf(p + l, READSTR - l, "Cscr 0x%4.4x\n", csr16r(ctlr, Cscr));
n = readstr(offset, a, n, p);
kfree(p);
@@ -364,8 +366,8 @@
/*
* MAC Address.
*/
- r = (edev->ea[3] << 24) | (edev->ea[2] << 16) | (edev->ea[1] << 8) | edev->
- ea[0];
+ r = (edev->ea[3] << 24) | (edev->ea[2] << 16) | (edev->ea[1] << 8)
+ | edev-> ea[0];
csr32w(ctlr, Idr0, r);
r = (edev->ea[5] << 8) | edev->ea[4];
csr32w(ctlr, Idr0 + 4, r);
@@ -400,7 +402,7 @@
*/
csr32w(ctlr, TimerInt, 0);
csr16w(ctlr, Imr,
- Serr | Timerbit | Fovw | PunLc | Rxovw | Ter | Tok | Rer | Rok);
+ Serr | Timerbit | Fovw | PunLc | Rxovw | Ter | Tok | Rer | Rok);
csr32w(ctlr, Mpc, 0);
/*
@@ -423,8 +425,8 @@
qlock(&ctlr->alock);
if (ctlr->alloc == NULL) {
ctlr->rblen = 1 << ((Rblen >> RblenSHIFT) + 13);
- ctlr->alloc = kzmalloc(ctlr->rblen + 16 + Ntd * Tdbsz + ARCH_CL_SIZE,
- MEM_WAIT);
+ ctlr->alloc = kzmalloc(ctlr->rblen + 16 + Ntd * Tdbsz
+ + ARCH_CL_SIZE, MEM_WAIT);
rtl8139init(edev);
}
qunlock(&ctlr->alock);
@@ -588,7 +590,9 @@
if (!(tsd & Tcok)) {
if (tsd & Tun) {
- if (ctlr->etxth < (ETHERMAXTU + ETHERHDRSIZE) / 32)
+ if (ctlr->etxth < (ETHERMAXTU +
+ ETHERHDRSIZE)
+ / 32)
ctlr->etxth++;
}
edev->oerrs++;
@@ -616,7 +620,8 @@
if (!(msr & Speed10) && edev->mbps != 100) {
edev->mbps = 100;
qsetlimit(edev->oq, 256 * 1024);
- } else if ((msr & Speed10) && edev->mbps != 10) {
+ } else if ((msr & Speed10) && edev->mbps != 10)
+ {
edev->mbps = 10;
qsetlimit(edev->oq, 65 * 1024);
}
@@ -663,8 +668,8 @@
continue;
#if 0
- /* trying to alloc PIO ports (.size of them?). for now, we just assume
- * they are free */
+ /* trying to alloc PIO ports (.size of them?). for now, we just
+ * assume they are free */
if (ioalloc(port, pcidev->mem[0].size, 0, "rtl8139") < 0) {
printd("rtl8139: port 0x%x in use\n", port);
continue;
@@ -693,7 +698,7 @@
{
"dfe-538tx", (0x1300 << 16) | 0x1186,}, /* D-Link DFE-538TX */
{
- "dfe-560txd", (0x1340 << 16) | 0x1186,}, /* D-Link DFE-560TXD */
+ "dfe-560txd", (0x1340 << 16) | 0x1186,},/* D-Link DFE-560TXD */
{
NULL},};
@@ -749,7 +754,8 @@
ctlr = rtl8139match(edev, id);
else
for (i = 0; rtl8139pci[i].name; i++) {
- if ((ctlr = rtl8139match(edev, rtl8139pci[i].id)) != NULL)
+ if ((ctlr = rtl8139match(edev, rtl8139pci[i].id)) !=
+ NULL)
break;
}
if (ctlr == NULL)
diff --git a/kern/drivers/net/ether82563.c b/kern/drivers/net/ether82563.c
index 708f1b6..09665e8 100644
--- a/kern/drivers/net/ether82563.c
+++ b/kern/drivers/net/ether82563.c
@@ -34,17 +34,17 @@
* on the assumption that allowing jumbo packets makes the controller
* much slower (as is true of the 82579), never allow jumbos.
*/
-#include <slab.h>
+#include <assert.h>
+#include <cpio.h>
+#include <error.h>
#include <kmalloc.h>
#include <kref.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <error.h>
-#include <cpio.h>
-#include <pmap.h>
-#include <smp.h>
#include <net/ip.h>
+#include <pmap.h>
+#include <slab.h>
+#include <smp.h>
+#include <stdio.h>
+#include <string.h>
#define now() TK2MS(MACHP(0)->ticks)
@@ -55,332 +55,333 @@
enum {
/* General */
- Ctrl = 0x0000, /* Device Control */
- Status = 0x0008, /* Device Status */
- Eec = 0x0010, /* EEPROM/Flash Control/Data */
- Fextnvm6 = 0x0010, /* Future Extended NVM 6 */
- Eerd = 0x0014, /* EEPROM Read */
- Ctrlext = 0x0018, /* Extended Device Control */
- Fla = 0x001c, /* Flash Access */
- Mdic = 0x0020, /* MDI Control */
- Seresctl = 0x0024, /* Serdes ana */
- Fcal = 0x0028, /* Flow Control Address Low */
- Fcah = 0x002C, /* Flow Control Address High */
- Fct = 0x0030, /* Flow Control Type */
- Kumctrlsta = 0x0034, /* MAC-PHY Interface */
- Vet = 0x0038, /* VLAN EtherType */
- Fcttv = 0x0170, /* Flow Control Transmit Timer Value */
- Txcw = 0x0178, /* Transmit Configuration Word */
- Rxcw = 0x0180, /* Receive Configuration Word */
- Ledctl = 0x0E00, /* LED control */
- Pba = 0x1000, /* Packet Buffer Allocation */
- Pbs = 0x1008, /* Packet Buffer Size */
+ Ctrl = 0x0000, /* Device Control */
+ Status = 0x0008, /* Device Status */
+ Eec = 0x0010, /* EEPROM/Flash Control/Data */
+ Fextnvm6 = 0x0010, /* Future Extended NVM 6 */
+ Eerd = 0x0014, /* EEPROM Read */
+ Ctrlext = 0x0018, /* Extended Device Control */
+ Fla = 0x001c, /* Flash Access */
+ Mdic = 0x0020, /* MDI Control */
+ Seresctl = 0x0024, /* Serdes ana */
+ Fcal = 0x0028, /* Flow Control Address Low */
+ Fcah = 0x002C, /* Flow Control Address High */
+ Fct = 0x0030, /* Flow Control Type */
+ Kumctrlsta = 0x0034, /* MAC-PHY Interface */
+ Vet = 0x0038, /* VLAN EtherType */
+ Fcttv = 0x0170, /* Flow Control Transmit Timer Value */
+ Txcw = 0x0178, /* Transmit Configuration Word */
+ Rxcw = 0x0180, /* Receive Configuration Word */
+ Ledctl = 0x0E00, /* LED control */
+ Pba = 0x1000, /* Packet Buffer Allocation */
+ Pbs = 0x1008, /* Packet Buffer Size */
/* Interrupt */
- Icr = 0x00C0, /* Interrupt Cause Read */
- Itr = 0x00c4, /* Interrupt Throttling Rate */
- Ics = 0x00C8, /* Interrupt Cause Set */
- Ims = 0x00D0, /* Interrupt Mask Set/Read */
- Imc = 0x00D8, /* Interrupt mask Clear */
- Iam = 0x00E0, /* Interrupt acknowledge Auto Mask */
+ Icr = 0x00C0, /* Interrupt Cause Read */
+ Itr = 0x00c4, /* Interrupt Throttling Rate */
+ Ics = 0x00C8, /* Interrupt Cause Set */
+ Ims = 0x00D0, /* Interrupt Mask Set/Read */
+ Imc = 0x00D8, /* Interrupt mask Clear */
+ Iam = 0x00E0, /* Interrupt acknowledge Auto Mask */
/* Receive */
- Rctl = 0x0100, /* Control */
- Ert = 0x2008, /* Early Receive Threshold (573[EVL], 579 only) */
- Fcrtl = 0x2160, /* Flow Control RX Threshold Low */
- Fcrth = 0x2168, /* Flow Control Rx Threshold High */
- Psrctl = 0x2170, /* Packet Split Receive Control */
- Rdbal = 0x2800, /* Rdesc Base Address Low Queue 0 */
- Rdbah = 0x2804, /* Rdesc Base Address High Queue 0 */
- Rdlen = 0x2808, /* Descriptor Length Queue 0 */
- Srrctl = 0x280c, /* split and replication rx control (82575) */
- Rdh = 0x2810, /* Descriptor Head Queue 0 */
- Rdt = 0x2818, /* Descriptor Tail Queue 0 */
- Rdtr = 0x2820, /* Descriptor Timer Ring */
- Rxdctl = 0x2828, /* Descriptor Control */
- Radv = 0x282C, /* Interrupt Absolute Delay Timer */
- Rdbal1 = 0x2900, /* Rdesc Base Address Low Queue 1 */
- Rdbah1 = 0x2804, /* Rdesc Base Address High Queue 1 */
- Rdlen1 = 0x2908, /* Descriptor Length Queue 1 */
- Rdh1 = 0x2910, /* Descriptor Head Queue 1 */
- Rdt1 = 0x2918, /* Descriptor Tail Queue 1 */
- Rxdctl1 = 0x2928, /* Descriptor Control Queue 1 */
- Rsrpd = 0x2c00, /* Small Packet Detect */
- Raid = 0x2c08, /* ACK interrupt delay */
- Cpuvec = 0x2c10, /* CPU Vector */
- Rxcsum = 0x5000, /* Checksum Control */
- Rmpl = 0x5004, /* rx maximum packet length (82575) */
- Rfctl = 0x5008, /* Filter Control */
- Mta = 0x5200, /* Multicast Table Array */
- Ral = 0x5400, /* Receive Address Low */
- Rah = 0x5404, /* Receive Address High */
- Vfta = 0x5600, /* VLAN Filter Table Array */
- Mrqc = 0x5818, /* Multiple Receive Queues Command */
- Rssim = 0x5864, /* RSS Interrupt Mask */
- Rssir = 0x5868, /* RSS Interrupt Request */
- Reta = 0x5c00, /* Redirection Table */
- Rssrk = 0x5c80, /* RSS Random Key */
+ Rctl = 0x0100, /* Control */
+ Ert = 0x2008, /* Early Receive Threshold (573[EVL], 579 only) */
+ Fcrtl = 0x2160, /* Flow Control RX Threshold Low */
+ Fcrth = 0x2168, /* Flow Control Rx Threshold High */
+ Psrctl = 0x2170, /* Packet Split Receive Control */
+ Rdbal = 0x2800, /* Rdesc Base Address Low Queue 0 */
+ Rdbah = 0x2804, /* Rdesc Base Address High Queue 0 */
+ Rdlen = 0x2808, /* Descriptor Length Queue 0 */
+ Srrctl = 0x280c, /* split and replication rx control (82575) */
+ Rdh = 0x2810, /* Descriptor Head Queue 0 */
+ Rdt = 0x2818, /* Descriptor Tail Queue 0 */
+ Rdtr = 0x2820, /* Descriptor Timer Ring */
+ Rxdctl = 0x2828, /* Descriptor Control */
+ Radv = 0x282C, /* Interrupt Absolute Delay Timer */
+ Rdbal1 = 0x2900, /* Rdesc Base Address Low Queue 1 */
+ Rdbah1 = 0x2804, /* Rdesc Base Address High Queue 1 */
+ Rdlen1 = 0x2908, /* Descriptor Length Queue 1 */
+ Rdh1 = 0x2910, /* Descriptor Head Queue 1 */
+ Rdt1 = 0x2918, /* Descriptor Tail Queue 1 */
+ Rxdctl1 = 0x2928, /* Descriptor Control Queue 1 */
+ Rsrpd = 0x2c00, /* Small Packet Detect */
+ Raid = 0x2c08, /* ACK interrupt delay */
+ Cpuvec = 0x2c10, /* CPU Vector */
+ Rxcsum = 0x5000, /* Checksum Control */
+ Rmpl = 0x5004, /* rx maximum packet length (82575) */
+ Rfctl = 0x5008, /* Filter Control */
+ Mta = 0x5200, /* Multicast Table Array */
+ Ral = 0x5400, /* Receive Address Low */
+ Rah = 0x5404, /* Receive Address High */
+ Vfta = 0x5600, /* VLAN Filter Table Array */
+ Mrqc = 0x5818, /* Multiple Receive Queues Command */
+ Rssim = 0x5864, /* RSS Interrupt Mask */
+ Rssir = 0x5868, /* RSS Interrupt Request */
+ Reta = 0x5c00, /* Redirection Table */
+ Rssrk = 0x5c80, /* RSS Random Key */
/* Transmit */
- Tctl = 0x0400, /* Transmit Control */
- Tipg = 0x0410, /* Transmit IPG */
- Tkabgtxd = 0x3004, /* glci afe band gap transmit ref data, or something */
- Tdbal = 0x3800, /* Tdesc Base Address Low */
- Tdbah = 0x3804, /* Tdesc Base Address High */
- Tdlen = 0x3808, /* Descriptor Length */
- Tdh = 0x3810, /* Descriptor Head */
- Tdt = 0x3818, /* Descriptor Tail */
- Tidv = 0x3820, /* Interrupt Delay Value */
- Txdctl = 0x3828, /* Descriptor Control */
- Tadv = 0x382C, /* Interrupt Absolute Delay Timer */
- Tarc0 = 0x3840, /* Arbitration Counter Queue 0 */
- Tdbal1 = 0x3900, /* Descriptor Base Low Queue 1 */
- Tdbah1 = 0x3904, /* Descriptor Base High Queue 1 */
- Tdlen1 = 0x3908, /* Descriptor Length Queue 1 */
- Tdh1 = 0x3910, /* Descriptor Head Queue 1 */
- Tdt1 = 0x3918, /* Descriptor Tail Queue 1 */
- Txdctl1 = 0x3928, /* Descriptor Control 1 */
- Tarc1 = 0x3940, /* Arbitration Counter Queue 1 */
+ Tctl = 0x0400, /* Transmit Control */
+ Tipg = 0x0410, /* Transmit IPG */
+ Tkabgtxd =
+ 0x3004, /* glci afe band gap transmit ref data, or something */
+ Tdbal = 0x3800, /* Tdesc Base Address Low */
+ Tdbah = 0x3804, /* Tdesc Base Address High */
+ Tdlen = 0x3808, /* Descriptor Length */
+ Tdh = 0x3810, /* Descriptor Head */
+ Tdt = 0x3818, /* Descriptor Tail */
+ Tidv = 0x3820, /* Interrupt Delay Value */
+ Txdctl = 0x3828, /* Descriptor Control */
+ Tadv = 0x382C, /* Interrupt Absolute Delay Timer */
+ Tarc0 = 0x3840, /* Arbitration Counter Queue 0 */
+ Tdbal1 = 0x3900, /* Descriptor Base Low Queue 1 */
+ Tdbah1 = 0x3904, /* Descriptor Base High Queue 1 */
+ Tdlen1 = 0x3908, /* Descriptor Length Queue 1 */
+ Tdh1 = 0x3910, /* Descriptor Head Queue 1 */
+ Tdt1 = 0x3918, /* Descriptor Tail Queue 1 */
+ Txdctl1 = 0x3928, /* Descriptor Control 1 */
+ Tarc1 = 0x3940, /* Arbitration Counter Queue 1 */
/* Statistics */
- Statistics = 0x4000, /* Start of Statistics Area */
- Gorcl = 0x88 / 4, /* Good Octets Received Count */
- Gotcl = 0x90 / 4, /* Good Octets Transmitted Count */
- Torl = 0xC0 / 4, /* Total Octets Received */
- Totl = 0xC8 / 4, /* Total Octets Transmitted */
+ Statistics = 0x4000, /* Start of Statistics Area */
+ Gorcl = 0x88 / 4, /* Good Octets Received Count */
+ Gotcl = 0x90 / 4, /* Good Octets Transmitted Count */
+ Torl = 0xC0 / 4, /* Total Octets Received */
+ Totl = 0xC8 / 4, /* Total Octets Transmitted */
Nstatistics = 0x124 / 4,
};
-enum { /* Ctrl */
- GIOmd = 1 << 2, /* BIO master disable */
- Lrst = 1 << 3, /* link reset */
- Slu = 1 << 6, /* Set Link Up */
- SspeedMASK = 3 << 8, /* Speed Selection */
- SspeedSHIFT = 8,
- Sspeed10 = 0x00000000, /* 10Mb/s */
- Sspeed100 = 0x00000100, /* 100Mb/s */
- Sspeed1000 = 0x00000200, /* 1000Mb/s */
- Frcspd = 1 << 11, /* Force Speed */
- Frcdplx = 1 << 12, /* Force Duplex */
- SwdpinsloMASK = 0x003C0000, /* Software Defined Pins - lo nibble */
- SwdpinsloSHIFT = 18,
- SwdpioloMASK = 0x03C00000, /* Software Defined Pins - I or O */
- SwdpioloSHIFT = 22,
- Devrst = 1 << 26, /* Device Reset */
- Rfce = 1 << 27, /* Receive Flow Control Enable */
- Tfce = 1 << 28, /* Transmit Flow Control Enable */
- Vme = 1 << 30, /* VLAN Mode Enable */
- Phyrst = 1 << 31, /* Phy Reset */
+enum { /* Ctrl */
+ GIOmd = 1 << 2, /* BIO master disable */
+ Lrst = 1 << 3, /* link reset */
+ Slu = 1 << 6, /* Set Link Up */
+ SspeedMASK = 3 << 8, /* Speed Selection */
+ SspeedSHIFT = 8,
+ Sspeed10 = 0x00000000, /* 10Mb/s */
+ Sspeed100 = 0x00000100, /* 100Mb/s */
+ Sspeed1000 = 0x00000200, /* 1000Mb/s */
+ Frcspd = 1 << 11, /* Force Speed */
+ Frcdplx = 1 << 12, /* Force Duplex */
+ SwdpinsloMASK = 0x003C0000, /* Software Defined Pins - lo nibble */
+ SwdpinsloSHIFT = 18,
+ SwdpioloMASK = 0x03C00000, /* Software Defined Pins - I or O */
+ SwdpioloSHIFT = 22,
+ Devrst = 1 << 26, /* Device Reset */
+ Rfce = 1 << 27, /* Receive Flow Control Enable */
+ Tfce = 1 << 28, /* Transmit Flow Control Enable */
+ Vme = 1 << 30, /* VLAN Mode Enable */
+ Phyrst = 1 << 31, /* Phy Reset */
};
-enum { /* Status */
- Lu = 1 << 1, /* Link Up */
- Lanid = 3 << 2, /* mask for Lan ID. */
- Txoff = 1 << 4, /* Transmission Paused */
- Tbimode = 1 << 5, /* TBI Mode Indication */
- Phyra = 1 << 10, /* PHY Reset Asserted */
- GIOme = 1 << 19, /* GIO Master Enable Status */
+enum { /* Status */
+ Lu = 1 << 1, /* Link Up */
+ Lanid = 3 << 2, /* mask for Lan ID. */
+ Txoff = 1 << 4, /* Transmission Paused */
+ Tbimode = 1 << 5, /* TBI Mode Indication */
+ Phyra = 1 << 10, /* PHY Reset Asserted */
+ GIOme = 1 << 19, /* GIO Master Enable Status */
};
enum {
/* Eec */
- Nvpres = 1 << 8, /* nvram present */
- Autord = 1 << 9, /* autoread complete */
- Sec1val = 1 << 22, /* sector 1 valid (!sec0) */
+ Nvpres = 1 << 8, /* nvram present */
+ Autord = 1 << 9, /* autoread complete */
+ Sec1val = 1 << 22, /* sector 1 valid (!sec0) */
};
-enum { /* Eerd */
- EEstart = 1 << 0, /* Start Read */
- EEdone = 1 << 1, /* Read done */
+enum { /* Eerd */
+ EEstart = 1 << 0, /* Start Read */
+ EEdone = 1 << 1, /* Read done */
};
-enum { /* Ctrlext */
- Asdchk = 1 << 12, /* ASD Check */
- Eerst = 1 << 13, /* EEPROM Reset */
- Spdbyps = 1 << 15, /* Speed Select Bypass */
+enum { /* Ctrlext */
+ Asdchk = 1 << 12, /* ASD Check */
+ Eerst = 1 << 13, /* EEPROM Reset */
+ Spdbyps = 1 << 15, /* Speed Select Bypass */
};
/*
* TODO(dcross): 'Ea' is 0 elsewhere. Investigate and possibly correct.
*/
-enum { /* EEPROM content offsets */
- OldEa = 0x00, /* Old Ethernet address */
- Ea = 0x01, /* Ethernet Address */
- Cf = 0x03, /* Compatibility Field */
- Icw1 = 0x0A, /* Initialization Control Word 1 */
- Sid = 0x0B, /* Subsystem ID */
- Svid = 0x0C, /* Subsystem Vendor ID */
- Did = 0x0D, /* Device ID */
- Vid = 0x0E, /* Vendor ID */
- Icw2 = 0x0F, /* Initialization Control Word 2 */
+enum { /* EEPROM content offsets */
+ OldEa = 0x00, /* Old Ethernet address */
+ Ea = 0x01, /* Ethernet Address */
+ Cf = 0x03, /* Compatibility Field */
+ Icw1 = 0x0A, /* Initialization Control Word 1 */
+ Sid = 0x0B, /* Subsystem ID */
+ Svid = 0x0C, /* Subsystem Vendor ID */
+ Did = 0x0D, /* Device ID */
+ Vid = 0x0E, /* Vendor ID */
+ Icw2 = 0x0F, /* Initialization Control Word 2 */
};
-enum { /* Mdic */
- MDIdMASK = 0x0000FFFF, /* Data */
- MDIdSHIFT = 0,
- MDIrMASK = 0x001F0000, /* PHY Register Address */
- MDIrSHIFT = 16,
- MDIpMASK = 0x03E00000, /* PHY Address */
- MDIpSHIFT = 21,
- MDIwop = 0x04000000, /* Write Operation */
- MDIrop = 0x08000000, /* Read Operation */
- MDIready = 0x10000000, /* End of Transaction */
- MDIie = 0x20000000, /* Interrupt Enable */
- MDIe = 0x40000000, /* Error */
+enum { /* Mdic */
+ MDIdMASK = 0x0000FFFF, /* Data */
+ MDIdSHIFT = 0,
+ MDIrMASK = 0x001F0000, /* PHY Register Address */
+ MDIrSHIFT = 16,
+ MDIpMASK = 0x03E00000, /* PHY Address */
+ MDIpSHIFT = 21,
+ MDIwop = 0x04000000, /* Write Operation */
+ MDIrop = 0x08000000, /* Read Operation */
+ MDIready = 0x10000000, /* End of Transaction */
+ MDIie = 0x20000000, /* Interrupt Enable */
+ MDIe = 0x40000000, /* Error */
};
-enum { /* phy interface registers */
- Phyctl = 0, /* phy ctl */
- Physsr = 17, /* phy secondary status */
- Phyier = 18, /* 82573 phy interrupt enable */
- Phyisr = 19, /* 82563 phy interrupt status */
- Phylhr = 19, /* 8257[12] link health */
- Phyier218 = 24, /* 218 (phy79?) phy interrupt enable */
- Phyisr218 = 25, /* 218 (phy79?) phy interrupt status */
- Phystat = 26, /* 82580 (phy79?) phy status */
- Phypage = 31, /* page number */
+enum { /* phy interface registers */
+ Phyctl = 0, /* phy ctl */
+ Physsr = 17, /* phy secondary status */
+ Phyier = 18, /* 82573 phy interrupt enable */
+ Phyisr = 19, /* 82563 phy interrupt status */
+ Phylhr = 19, /* 8257[12] link health */
+ Phyier218 = 24, /* 218 (phy79?) phy interrupt enable */
+ Phyisr218 = 25, /* 218 (phy79?) phy interrupt status */
+ Phystat = 26, /* 82580 (phy79?) phy status */
+ Phypage = 31, /* page number */
- Rtlink = 1 << 10, /* realtime link status */
- Phyan = 1 << 11, /* phy has auto-negotiated */
+ Rtlink = 1 << 10, /* realtime link status */
+ Phyan = 1 << 11, /* phy has auto-negotiated */
- /* Phyctl bits */
- Ran = 1 << 9, /* restart auto-negotiation */
- Ean = 1 << 12, /* enable auto-negotiation */
+ /* Phyctl bits */
+ Ran = 1 << 9, /* restart auto-negotiation */
+ Ean = 1 << 12, /* enable auto-negotiation */
- /* 82573 Phyier interrupt enable bits */
- Lscie = 1 << 10, /* link status changed */
- Ancie = 1 << 11, /* auto-negotiation complete */
- Spdie = 1 << 14, /* speed changed */
- Panie = 1 << 15, /* phy auto-negotiation error */
+ /* 82573 Phyier interrupt enable bits */
+ Lscie = 1 << 10, /* link status changed */
+ Ancie = 1 << 11, /* auto-negotiation complete */
+ Spdie = 1 << 14, /* speed changed */
+ Panie = 1 << 15, /* phy auto-negotiation error */
- /* Phylhr/Phyisr bits */
- Anf = 1 << 6, /* lhr: auto-negotiation fault */
- Ane = 1 << 15, /* isr: auto-negotiation error */
+ /* Phylhr/Phyisr bits */
+ Anf = 1 << 6, /* lhr: auto-negotiation fault */
+ Ane = 1 << 15, /* isr: auto-negotiation error */
- /* 82580 Phystat bits */
- Ans = 3 << 14, /* 82580 autoneg. status */
- Link = 1 << 6, /* 82580 link */
+ /* 82580 Phystat bits */
+ Ans = 3 << 14, /* 82580 autoneg. status */
+ Link = 1 << 6, /* 82580 link */
- /* 218 Phystat bits */
- Anfs = 3 << 13, /* fault status */
- Ans218 = 1 << 12, /* autoneg complete */
+ /* 218 Phystat bits */
+ Anfs = 3 << 13, /* fault status */
+ Ans218 = 1 << 12, /* autoneg complete */
- /* 218 Phyier218 interrupt enable bits */
- Spdie218 = 1 << 1, /* speed changed */
- Lscie218 = 1 << 2, /* link status changed */
- Ancie218 = 1 << 8, /* auto-negotiation changed */
+ /* 218 Phyier218 interrupt enable bits */
+ Spdie218 = 1 << 1, /* speed changed */
+ Lscie218 = 1 << 2, /* link status changed */
+ Ancie218 = 1 << 8, /* auto-negotiation changed */
};
-enum { /* Icr, Ics, Ims, Imc */
- Txdw = 0x00000001, /* Transmit Descriptor Written Back */
- Txqe = 0x00000002, /* Transmit Queue Empty */
- Lsc = 0x00000004, /* Link Status Change */
- Rxseq = 0x00000008, /* Receive Sequence Error */
- Rxdmt0 = 0x00000010, /* Rdesc Minimum Threshold Reached */
- Rxo = 0x00000040, /* Receiver Overrun */
- Rxt0 = 0x00000080, /* Receiver Timer Interrupt */
- Mdac = 0x00000200, /* MDIO Access Completed */
- Rxcfg = 0x00000400, /* Receiving /C/ ordered sets */
- Gpi0 = 0x00000800, /* General Purpose Interrupts */
- Gpi1 = 0x00001000,
- Gpi2 = 0x00002000,
- Gpi3 = 0x00004000,
- Ack = 0x00020000, /* Receive ACK frame */
+enum { /* Icr, Ics, Ims, Imc */
+ Txdw = 0x00000001, /* Transmit Descriptor Written Back */
+ Txqe = 0x00000002, /* Transmit Queue Empty */
+ Lsc = 0x00000004, /* Link Status Change */
+ Rxseq = 0x00000008, /* Receive Sequence Error */
+ Rxdmt0 = 0x00000010, /* Rdesc Minimum Threshold Reached */
+ Rxo = 0x00000040, /* Receiver Overrun */
+ Rxt0 = 0x00000080, /* Receiver Timer Interrupt */
+ Mdac = 0x00000200, /* MDIO Access Completed */
+ Rxcfg = 0x00000400, /* Receiving /C/ ordered sets */
+ Gpi0 = 0x00000800, /* General Purpose Interrupts */
+ Gpi1 = 0x00001000,
+ Gpi2 = 0x00002000,
+ Gpi3 = 0x00004000,
+ Ack = 0x00020000, /* Receive ACK frame */
};
-enum { /* Txcw */
- TxcwFd = 0x00000020, /* Full Duplex */
- TxcwHd = 0x00000040, /* Half Duplex */
- TxcwPauseMASK = 0x00000180, /* Pause */
- TxcwPauseSHIFT = 7,
- TxcwPs = 1 << TxcwPauseSHIFT, /* Pause Supported */
- TxcwAs = 2 << TxcwPauseSHIFT, /* Asymmetric FC desired */
- TxcwRfiMASK = 0x00003000, /* Remote Fault Indication */
- TxcwRfiSHIFT = 12,
- TxcwNpr = 0x00008000, /* Next Page Request */
- TxcwConfig = 0x40000000, /* Transmit Config Control */
- TxcwAne = 0x80000000, /* Auto-Negotiation Enable */
+enum { /* Txcw */
+ TxcwFd = 0x00000020, /* Full Duplex */
+ TxcwHd = 0x00000040, /* Half Duplex */
+ TxcwPauseMASK = 0x00000180, /* Pause */
+ TxcwPauseSHIFT = 7,
+ TxcwPs = 1 << TxcwPauseSHIFT, /* Pause Supported */
+ TxcwAs = 2 << TxcwPauseSHIFT, /* Asymmetric FC desired */
+ TxcwRfiMASK = 0x00003000, /* Remote Fault Indication */
+ TxcwRfiSHIFT = 12,
+ TxcwNpr = 0x00008000, /* Next Page Request */
+ TxcwConfig = 0x40000000, /* Transmit Config Control */
+ TxcwAne = 0x80000000, /* Auto-Negotiation Enable */
};
-enum { /* Rctl */
- Rrst = 0x00000001, /* Receiver Software Reset */
- Ren = 0x00000002, /* Receiver Enable */
- Sbp = 0x00000004, /* Store Bad Packets */
- Upe = 0x00000008, /* Unicast Promiscuous Enable */
- Mpe = 0x00000010, /* Multicast Promiscuous Enable */
- Lpe = 0x00000020, /* Long Packet Reception Enable */
- LbmMASK = 0x000000C0, /* Loopback Mode */
- LbmOFF = 0x00000000, /* No Loopback */
- LbmTBI = 0x00000040, /* TBI Loopback */
- LbmMII = 0x00000080, /* GMII/MII Loopback */
- LbmXCVR = 0x000000C0, /* Transceiver Loopback */
- RdtmsMASK = 0x00000300, /* Rdesc Minimum Threshold Size */
- RdtmsHALF = 0x00000000, /* Threshold is 1/2 Rdlen */
- RdtmsQUARTER = 0x00000100, /* Threshold is 1/4 Rdlen */
- RdtmsEIGHTH = 0x00000200, /* Threshold is 1/8 Rdlen */
- MoMASK = 0x00003000, /* Multicast Offset */
- Bam = 0x00008000, /* Broadcast Accept Mode */
- BsizeMASK = 0x00030000, /* Receive Buffer Size */
- Bsize16384 = 0x00010000, /* Bsex = 1 */
- Bsize8192 = 0x00020000, /* Bsex = 1 */
- Bsize2048 = 0x00000000,
- Bsize1024 = 0x00010000,
- Bsize512 = 0x00020000,
- Bsize256 = 0x00030000,
- BsizeFlex = 0x08000000, /* Flexible Bsize in 1KB increments */
- Vfe = 0x00040000, /* VLAN Filter Enable */
- Cfien = 0x00080000, /* Canonical Form Indicator Enable */
- Cfi = 0x00100000, /* Canonical Form Indicator value */
- Dpf = 0x00400000, /* Discard Pause Frames */
- Pmcf = 0x00800000, /* Pass MAC Control Frames */
- Bsex = 0x02000000, /* Buffer Size Extension */
- Secrc = 0x04000000, /* Strip CRC from incoming packet */
+enum { /* Rctl */
+ Rrst = 0x00000001, /* Receiver Software Reset */
+ Ren = 0x00000002, /* Receiver Enable */
+ Sbp = 0x00000004, /* Store Bad Packets */
+ Upe = 0x00000008, /* Unicast Promiscuous Enable */
+ Mpe = 0x00000010, /* Multicast Promiscuous Enable */
+ Lpe = 0x00000020, /* Long Packet Reception Enable */
+ LbmMASK = 0x000000C0, /* Loopback Mode */
+ LbmOFF = 0x00000000, /* No Loopback */
+ LbmTBI = 0x00000040, /* TBI Loopback */
+ LbmMII = 0x00000080, /* GMII/MII Loopback */
+ LbmXCVR = 0x000000C0, /* Transceiver Loopback */
+ RdtmsMASK = 0x00000300, /* Rdesc Minimum Threshold Size */
+ RdtmsHALF = 0x00000000, /* Threshold is 1/2 Rdlen */
+ RdtmsQUARTER = 0x00000100, /* Threshold is 1/4 Rdlen */
+ RdtmsEIGHTH = 0x00000200, /* Threshold is 1/8 Rdlen */
+ MoMASK = 0x00003000, /* Multicast Offset */
+ Bam = 0x00008000, /* Broadcast Accept Mode */
+ BsizeMASK = 0x00030000, /* Receive Buffer Size */
+ Bsize16384 = 0x00010000, /* Bsex = 1 */
+ Bsize8192 = 0x00020000, /* Bsex = 1 */
+ Bsize2048 = 0x00000000,
+ Bsize1024 = 0x00010000,
+ Bsize512 = 0x00020000,
+ Bsize256 = 0x00030000,
+ BsizeFlex = 0x08000000, /* Flexible Bsize in 1KB increments */
+ Vfe = 0x00040000, /* VLAN Filter Enable */
+ Cfien = 0x00080000, /* Canonical Form Indicator Enable */
+ Cfi = 0x00100000, /* Canonical Form Indicator value */
+ Dpf = 0x00400000, /* Discard Pause Frames */
+ Pmcf = 0x00800000, /* Pass MAC Control Frames */
+ Bsex = 0x02000000, /* Buffer Size Extension */
+ Secrc = 0x04000000, /* Strip CRC from incoming packet */
};
-enum { /* Srrctl */
- Dropen = 1 << 31,
+enum { /* Srrctl */
+ Dropen = 1 << 31,
};
-enum { /* Tctl */
- Trst = 0x00000001, /* Transmitter Software Reset */
- Ten = 0x00000002, /* Transmit Enable */
- Psp = 0x00000008, /* Pad Short Packets */
- Mulr = 0x10000000, /* Allow multiple concurrent requests */
- Ctmask = 0x00000FF0, /* Collision Threshold */
- Ctshift = 4,
- ColdMASK = 0x003FF000, /* Collision Distance */
- ColdSHIFT = 12,
- Swxoff = 0x00400000, /* Sofware XOFF Transmission */
- Pbe = 0x00800000, /* Packet Burst Enable */
- Rtlc = 0x01000000, /* Re-transmit on Late Collision */
- Nrtu = 0x02000000, /* No Re-transmit on Underrrun */
+enum { /* Tctl */
+ Trst = 0x00000001, /* Transmitter Software Reset */
+ Ten = 0x00000002, /* Transmit Enable */
+ Psp = 0x00000008, /* Pad Short Packets */
+ Mulr = 0x10000000, /* Allow multiple concurrent requests */
+ Ctmask = 0x00000FF0, /* Collision Threshold */
+ Ctshift = 4,
+ ColdMASK = 0x003FF000, /* Collision Distance */
+ ColdSHIFT = 12,
+ Swxoff = 0x00400000, /* Sofware XOFF Transmission */
+ Pbe = 0x00800000, /* Packet Burst Enable */
+ Rtlc = 0x01000000, /* Re-transmit on Late Collision */
+ Nrtu = 0x02000000, /* No Re-transmit on Underrrun */
};
-enum { /* [RT]xdctl */
- PthreshMASK = 0x0000003F, /* Prefetch Threshold */
- PthreshSHIFT = 0,
- HthreshMASK = 0x00003F00, /* Host Threshold */
- HthreshSHIFT = 8,
- WthreshMASK = 0x003F0000, /* Writeback Threshold */
- WthreshSHIFT = 16,
- Gran = 0x01000000, /* Granularity (descriptors, not cls) */
- Qenable = 0x02000000, /* Queue Enable (82575) */
+enum { /* [RT]xdctl */
+ PthreshMASK = 0x0000003F, /* Prefetch Threshold */
+ PthreshSHIFT = 0,
+ HthreshMASK = 0x00003F00, /* Host Threshold */
+ HthreshSHIFT = 8,
+ WthreshMASK = 0x003F0000, /* Writeback Threshold */
+ WthreshSHIFT = 16,
+ Gran = 0x01000000, /* Granularity (descriptors, not cls) */
+ Qenable = 0x02000000, /* Queue Enable (82575) */
};
-enum { /* Rxcsum */
- PcssMASK = 0x00FF, /* Packet Checksum Start */
- PcssSHIFT = 0,
- Ipofl = 0x0100, /* IP Checksum Off-load Enable */
- Tuofl = 0x0200, /* TCP/UDP Checksum Off-load Enable */
+enum { /* Rxcsum */
+ PcssMASK = 0x00FF, /* Packet Checksum Start */
+ PcssSHIFT = 0,
+ Ipofl = 0x0100, /* IP Checksum Off-load Enable */
+ Tuofl = 0x0200, /* TCP/UDP Checksum Off-load Enable */
};
-enum { /* Receive Delay Timer Ring */
- DelayMASK = 0xFFFF, /* delay timer in 1.024nS increments */
- DelaySHIFT = 0,
- Fpd = 0x80000000, /* Flush partial Descriptor Block */
+enum { /* Receive Delay Timer Ring */
+ DelayMASK = 0xFFFF, /* delay timer in 1.024nS increments */
+ DelaySHIFT = 0,
+ Fpd = 0x80000000, /* Flush partial Descriptor Block */
};
-struct rd { /* Receive Descriptor */
+struct rd { /* Receive Descriptor */
uint32_t addr[2];
uint16_t length;
uint16_t checksum;
@@ -389,56 +390,56 @@
uint16_t special;
};
-enum { /* Rd status */
- Rdd = 0x01, /* Descriptor Done */
- Reop = 0x02, /* End of Packet */
- Ixsm = 0x04, /* Ignore Checksum Indication */
- Vp = 0x08, /* Packet is 802.1Q (matched VET) */
- Tcpcs = 0x20, /* TCP Checksum Calculated on Packet */
- Ipcs = 0x40, /* IP Checksum Calculated on Packet */
- Pif = 0x80, /* Passed in-exact filter */
+enum { /* Rd status */
+ Rdd = 0x01, /* Descriptor Done */
+ Reop = 0x02, /* End of Packet */
+ Ixsm = 0x04, /* Ignore Checksum Indication */
+ Vp = 0x08, /* Packet is 802.1Q (matched VET) */
+ Tcpcs = 0x20, /* TCP Checksum Calculated on Packet */
+ Ipcs = 0x40, /* IP Checksum Calculated on Packet */
+ Pif = 0x80, /* Passed in-exact filter */
};
-enum { /* Rd errors */
- Ce = 0x01, /* CRC Error or Alignment Error */
- Se = 0x02, /* Symbol Error */
- Seq = 0x04, /* Sequence Error */
- Cxe = 0x10, /* Carrier Extension Error */
- Tcpe = 0x20, /* TCP/UDP Checksum Error */
- Ipe = 0x40, /* IP Checksum Error */
- Rxe = 0x80, /* RX Data Error */
+enum { /* Rd errors */
+ Ce = 0x01, /* CRC Error or Alignment Error */
+ Se = 0x02, /* Symbol Error */
+ Seq = 0x04, /* Sequence Error */
+ Cxe = 0x10, /* Carrier Extension Error */
+ Tcpe = 0x20, /* TCP/UDP Checksum Error */
+ Ipe = 0x40, /* IP Checksum Error */
+ Rxe = 0x80, /* RX Data Error */
};
-struct td { /* Transmit Descriptor */
- uint32_t addr[2]; /* Data */
+struct td { /* Transmit Descriptor */
+ uint32_t addr[2]; /* Data */
uint32_t control;
uint32_t status;
};
-enum { /* Tdesc control */
- LenMASK = 0x000FFFFF, /* Data/Packet Length Field */
- LenSHIFT = 0,
- DtypeCD = 0x00000000, /* Data Type 'Context Descriptor' */
- DtypeDD = 0x00100000, /* Data Type 'Data Descriptor' */
- PtypeTCP = 0x01000000, /* TCP/UDP Packet Type (CD) */
- Teop = 0x01000000, /* End of Packet (DD) */
- PtypeIP = 0x02000000, /* IP Packet Type (CD) */
- Ifcs = 0x02000000, /* Insert FCS (DD) */
- Tse = 0x04000000, /* TCP Segmentation Enable */
- Rs = 0x08000000, /* Report Status */
- Rps = 0x10000000, /* Report Status Sent */
- Dext = 0x20000000, /* Descriptor Extension */
- Vle = 0x40000000, /* VLAN Packet Enable */
- Ide = 0x80000000, /* Interrupt Delay Enable */
+enum { /* Tdesc control */
+ LenMASK = 0x000FFFFF, /* Data/Packet Length Field */
+ LenSHIFT = 0,
+ DtypeCD = 0x00000000, /* Data Type 'Context Descriptor' */
+ DtypeDD = 0x00100000, /* Data Type 'Data Descriptor' */
+ PtypeTCP = 0x01000000, /* TCP/UDP Packet Type (CD) */
+ Teop = 0x01000000, /* End of Packet (DD) */
+ PtypeIP = 0x02000000, /* IP Packet Type (CD) */
+ Ifcs = 0x02000000, /* Insert FCS (DD) */
+ Tse = 0x04000000, /* TCP Segmentation Enable */
+ Rs = 0x08000000, /* Report Status */
+ Rps = 0x10000000, /* Report Status Sent */
+ Dext = 0x20000000, /* Descriptor Extension */
+ Vle = 0x40000000, /* VLAN Packet Enable */
+ Ide = 0x80000000, /* Interrupt Delay Enable */
};
-enum { /* Tdesc status */
- Tdd = 0x0001, /* Descriptor Done */
- Ec = 0x0002, /* Excess Collisions */
- Lc = 0x0004, /* Late Collision */
- Tu = 0x0008, /* Transmit Underrun */
- CssMASK = 0xFF00, /* Checksum Start Field */
- CssSHIFT = 8,
+enum { /* Tdesc status */
+ Tdd = 0x0001, /* Descriptor Done */
+ Ec = 0x0002, /* Excess Collisions */
+ Lc = 0x0004, /* Late Collision */
+ Tu = 0x0008, /* Transmit Underrun */
+ CssMASK = 0xFF00, /* Checksum Start Field */
+ CssSHIFT = 8,
};
struct flash {
@@ -450,23 +451,23 @@
enum {
/* 16 and 32-bit flash registers for ich flash parts */
- Bfpr = 0x00 / 4, /* flash base 0:12; lim 16:28 */
- Fsts = 0x04 / 2, /* flash status; Hsfsts */
- Fctl = 0x06 / 2, /* flash control; Hsfctl */
- Faddr = 0x08 / 4, /* flash address to r/w */
- Fdata = 0x10 / 4, /* data @ address */
+ Bfpr = 0x00 / 4, /* flash base 0:12; lim 16:28 */
+ Fsts = 0x04 / 2, /* flash status; Hsfsts */
+ Fctl = 0x06 / 2, /* flash control; Hsfctl */
+ Faddr = 0x08 / 4, /* flash address to r/w */
+ Fdata = 0x10 / 4, /* data @ address */
/* status register */
- Fdone = 1 << 0, /* flash cycle done */
- Fcerr = 1 << 1, /* cycle error; write 1 to clear */
- Ael = 1 << 2, /* direct access error log; 1 to clear */
- Scip = 1 << 5, /* spi cycle in progress */
- Fvalid = 1 << 14, /* flash descriptor valid */
+ Fdone = 1 << 0, /* flash cycle done */
+ Fcerr = 1 << 1, /* cycle error; write 1 to clear */
+ Ael = 1 << 2, /* direct access error log; 1 to clear */
+ Scip = 1 << 5, /* spi cycle in progress */
+ Fvalid = 1 << 14, /* flash descriptor valid */
/* control register */
- Fgo = 1 << 0, /* start cycle */
- Flcycle = 1 << 1, /* two bits: r=0; w=2 */
- Fdbc = 1 << 8, /* bytes to read; 5 bits */
+ Fgo = 1 << 0, /* start cycle */
+ Flcycle = 1 << 1, /* two bits: r=0; w=2 */
+ Fdbc = 1 << 8, /* bytes to read; 5 bits */
};
/*
@@ -474,23 +475,22 @@
* intel's esb2 ich8 (io controller hub), it carries mii bits. can be used
* to reset the phy. intel proprietary, see "kumeran specification".
*/
-enum {
- I217inbandctlpage = 770, /* phy page */
- I217inbandctlreg = 18, /* phy register */
- I217inbandctllnkststxtmoutmask = 0x3F00,
- I217inbandctllnkststxtmoutshift = 8,
+enum { I217inbandctlpage = 770, /* phy page */
+ I217inbandctlreg = 18, /* phy register */
+ I217inbandctllnkststxtmoutmask = 0x3F00,
+ I217inbandctllnkststxtmoutshift = 8,
- Fextnvm6reqpllclk = 0x100,
- Fextnvm6enak1entrycond = 0x200, /* extend K1 entry latency */
+ Fextnvm6reqpllclk = 0x100,
+ Fextnvm6enak1entrycond = 0x200, /* extend K1 entry latency */
- Nvmk1cfg = 0x1B, /* NVM K1 Config Word */
- Nvmk1enable = 0x1, /* NVM Enable K1 bit */
+ Nvmk1cfg = 0x1B, /* NVM K1 Config Word */
+ Nvmk1enable = 0x1, /* NVM Enable K1 bit */
- Kumctrlstaoff = 0x1F0000,
- Kumctrlstaoffshift = 16,
- Kumctrlstaren = 0x200000,
- Kumctrlstak1cfg = 0x7,
- Kumctrlstak1enable = 0x2,
+ Kumctrlstaoff = 0x1F0000,
+ Kumctrlstaoffshift = 16,
+ Kumctrlstaren = 0x200000,
+ Kumctrlstak1cfg = 0x7,
+ Kumctrlstak1enable = 0x2,
};
enum {
@@ -502,46 +502,44 @@
* Tdlen and Rdlen have to be multiples of 128. Rd and Td are both
* 16 bytes long, so Nrd and Ntd must be multiples of 8.
*/
- Ntd = 32, /* power of two >= 8 */
- Nrd = 128, /* power of two >= 8 */
+ Ntd = 32, /* power of two >= 8 */
+ Nrd = 128, /* power of two >= 8 */
Rbalign = 16,
- Slop = 32, /* for vlan headers, crcs, etc. */
+ Slop = 32, /* for vlan headers, crcs, etc. */
};
-enum {
- Iany = -1,
- i82563,
- i82566,
- i82567,
- i82567m,
- i82571,
- i82572,
- i82573,
- i82574,
- i82575,
- i82576,
- i82577,
- i82577m,
- i82578,
- i82578m,
- i82579,
- i82580,
- i82583,
- i210,
- i217,
- i218,
- i350,
- Nctlrtype,
+enum { Iany = -1,
+ i82563,
+ i82566,
+ i82567,
+ i82567m,
+ i82571,
+ i82572,
+ i82573,
+ i82574,
+ i82575,
+ i82576,
+ i82577,
+ i82577m,
+ i82578,
+ i82578m,
+ i82579,
+ i82580,
+ i82583,
+ i210,
+ i217,
+ i218,
+ i350,
+ Nctlrtype,
};
-enum {
- Fload = 1 << 0,
- Fert = 1 << 1,
- F75 = 1 << 2,
- Fpba = 1 << 3,
- Fflashea = 1 << 4,
- F79phy = 1 << 5,
- Fnofct = 1 << 6,
+enum { Fload = 1 << 0,
+ Fert = 1 << 1,
+ F75 = 1 << 2,
+ Fpba = 1 << 3,
+ Fflashea = 1 << 4,
+ F79phy = 1 << 5,
+ Fnofct = 1 << 6,
};
struct ctlrtype {
@@ -553,26 +551,26 @@
};
static struct ctlrtype ctlrtab[Nctlrtype] = {
- {i82563, 9014, 1, "i82563", Fpba},
- {i82566, 1514, 1, "i82566", Fload},
- {i82567, 9234, 1, "i82567", Fload},
- {i82567m, 1514, 1, "i82567m", 0},
- {i82571, 9234, 1, "i82571", Fpba},
- {i82572, 9234, 1, "i82572", Fpba},
- {i82573, 8192, 1, "i82573", Fert}, /* terrible perf above 8k */
- {i82574, 9018, 1, "i82574", 0},
- {i82575, 9728, 1, "i82575", F75 | Fflashea},
- {i82576, 9728, 1, "i82576", F75},
- {i82577, 4096, 2, "i82577", Fload | Fert},
- {i82577m, 1514, 2, "i82577", Fload | Fert},
- {i82578, 4096, 2, "i82578", Fload | Fert},
- {i82578m, 1514, 2, "i82578", Fload | Fert},
- {i82579, 9018, 2, "i82579", Fload | Fert | F79phy | Fnofct},
- {i82580, 9728, 1, "i82580", F75 | F79phy},
- {i82583, 1514, 1, "i82583", 0},
- {i210, 9728, 1, "i210", F75 | Fnofct | Fert},
- {i217, 9728, 1, "i217", F79phy | Fnofct | Fload | Fert},
- {i350, 9728, 1, "i350", F75 | F79phy | Fnofct},
+ {i82563, 9014, 1, "i82563", Fpba},
+ {i82566, 1514, 1, "i82566", Fload},
+ {i82567, 9234, 1, "i82567", Fload},
+ {i82567m, 1514, 1, "i82567m", 0},
+ {i82571, 9234, 1, "i82571", Fpba},
+ {i82572, 9234, 1, "i82572", Fpba},
+ {i82573, 8192, 1, "i82573", Fert}, /* terrible perf above 8k */
+ {i82574, 9018, 1, "i82574", 0},
+ {i82575, 9728, 1, "i82575", F75 | Fflashea},
+ {i82576, 9728, 1, "i82576", F75},
+ {i82577, 4096, 2, "i82577", Fload | Fert},
+ {i82577m, 1514, 2, "i82577", Fload | Fert},
+ {i82578, 4096, 2, "i82578", Fload | Fert},
+ {i82578m, 1514, 2, "i82578", Fload | Fert},
+ {i82579, 9018, 2, "i82579", Fload | Fert | F79phy | Fnofct},
+ {i82580, 9728, 1, "i82580", F75 | F79phy},
+ {i82583, 1514, 1, "i82583", 0},
+ {i210, 9728, 1, "i210", F75 | Fnofct | Fert},
+ {i217, 9728, 1, "i217", F79phy | Fnofct | Fload | Fert},
+ {i350, 9728, 1, "i350", F75 | F79phy | Fnofct},
};
struct ctlr {
@@ -584,14 +582,14 @@
int type;
uint16_t eeprom[0x40];
- qlock_t alock; /* attach */
+ qlock_t alock; /* attach */
void *alloc;
unsigned int rbsz;
int attached;
int *nic;
spinlock_t imlock;
- int im; /* interrupt mask */
+ int im; /* interrupt mask */
struct rendez lrendez;
int lim;
@@ -611,31 +609,31 @@
unsigned int tcpcs;
unsigned int speeds[4];
- uint8_t ra[Eaddrlen]; /* receive address */
- uint32_t mta[128]; /* multicast table array */
+ uint8_t ra[Eaddrlen]; /* receive address */
+ uint32_t mta[128]; /* multicast table array */
struct rendez rrendez;
int rim;
- int rdfree; /* rx descriptors awaiting packets */
- struct rd *rdba; /* receive descriptor base address */
- struct block **rb; /* receive buffers */
- unsigned int rdh; /* receive descriptor head */
- unsigned int rdt; /* receive descriptor tail */
- int rdtr; /* receive delay timer ring value */
- int radv; /* receive interrupt absolute delay timer */
+ int rdfree; /* rx descriptors awaiting packets */
+ struct rd *rdba; /* receive descriptor base address */
+ struct block **rb; /* receive buffers */
+ unsigned int rdh; /* receive descriptor head */
+ unsigned int rdt; /* receive descriptor tail */
+ int rdtr; /* receive delay timer ring value */
+ int radv; /* receive interrupt absolute delay timer */
struct rendez trendez;
qlock_t tlock;
- struct td *tdba; /* transmit descriptor base address */
- struct block **tb; /* transmit buffers */
- int tdh; /* transmit descriptor head */
- int tdt; /* transmit descriptor tail */
+ struct td *tdba; /* transmit descriptor base address */
+ struct block **tb; /* transmit buffers */
+ int tdh; /* transmit descriptor head */
+ int tdt; /* transmit descriptor tail */
int fcrtl;
int fcrth;
- unsigned int pbs; /* packet buffer size */
- unsigned int pba; /* packet buffer allocation */
+ unsigned int pbs; /* packet buffer size */
+ unsigned int pba; /* packet buffer allocation */
};
static inline uint32_t csr32r(struct ctlr *c, uintptr_t reg)
@@ -651,84 +649,82 @@
static struct ctlr *i82563ctlrhead;
static struct ctlr *i82563ctlrtail;
-static int speedtab[] = {
- 10, 100, 1000, 0
-};
+static int speedtab[] = {10, 100, 1000, 0};
static char *statistics[] = {
- "CRC Error",
- "Alignment Error",
- "Symbol Error",
- "RX Error",
- "Missed Packets",
- "Single Collision",
- "Excessive Collisions",
- "Multiple Collision",
- "Late Collisions",
- NULL,
- "Collision",
- "Transmit Underrun",
- "Defer",
- "Transmit - No CRS",
- "Sequence Error",
- "Carrier Extension Error",
- "Receive Error Length",
- NULL,
- "XON Received",
- "XON Transmitted",
- "XOFF Received",
- "XOFF Transmitted",
- "FC Received Unsupported",
- "Packets Received (64 Bytes)",
- "Packets Received (65-127 Bytes)",
- "Packets Received (128-255 Bytes)",
- "Packets Received (256-511 Bytes)",
- "Packets Received (512-1023 Bytes)",
- "Packets Received (1024-mtu Bytes)",
- "Good Packets Received",
- "Broadcast Packets Received",
- "Multicast Packets Received",
- "Good Packets Transmitted",
- NULL,
- "Good Octets Received",
- NULL,
- "Good Octets Transmitted",
- NULL,
- NULL,
- NULL,
- "Receive No Buffers",
- "Receive Undersize",
- "Receive Fragment",
- "Receive Oversize",
- "Receive Jabber",
- "Management Packets Rx",
- "Management Packets Drop",
- "Management Packets Tx",
- "Total Octets Received",
- NULL,
- "Total Octets Transmitted",
- NULL,
- "Total Packets Received",
- "Total Packets Transmitted",
- "Packets Transmitted (64 Bytes)",
- "Packets Transmitted (65-127 Bytes)",
- "Packets Transmitted (128-255 Bytes)",
- "Packets Transmitted (256-511 Bytes)",
- "Packets Transmitted (512-1023 Bytes)",
- "Packets Transmitted (1024-mtu Bytes)",
- "Multicast Packets Transmitted",
- "Broadcast Packets Transmitted",
- "TCP Segmentation Context Transmitted",
- "TCP Segmentation Context Fail",
- "Interrupt Assertion",
- "Interrupt Rx Pkt Timer",
- "Interrupt Rx Abs Timer",
- "Interrupt Tx Pkt Timer",
- "Interrupt Tx Abs Timer",
- "Interrupt Tx Queue Empty",
- "Interrupt Tx Desc Low",
- "Interrupt Rx Min",
- "Interrupt Rx Overrun",
+ "CRC Error",
+ "Alignment Error",
+ "Symbol Error",
+ "RX Error",
+ "Missed Packets",
+ "Single Collision",
+ "Excessive Collisions",
+ "Multiple Collision",
+ "Late Collisions",
+ NULL,
+ "Collision",
+ "Transmit Underrun",
+ "Defer",
+ "Transmit - No CRS",
+ "Sequence Error",
+ "Carrier Extension Error",
+ "Receive Error Length",
+ NULL,
+ "XON Received",
+ "XON Transmitted",
+ "XOFF Received",
+ "XOFF Transmitted",
+ "FC Received Unsupported",
+ "Packets Received (64 Bytes)",
+ "Packets Received (65-127 Bytes)",
+ "Packets Received (128-255 Bytes)",
+ "Packets Received (256-511 Bytes)",
+ "Packets Received (512-1023 Bytes)",
+ "Packets Received (1024-mtu Bytes)",
+ "Good Packets Received",
+ "Broadcast Packets Received",
+ "Multicast Packets Received",
+ "Good Packets Transmitted",
+ NULL,
+ "Good Octets Received",
+ NULL,
+ "Good Octets Transmitted",
+ NULL,
+ NULL,
+ NULL,
+ "Receive No Buffers",
+ "Receive Undersize",
+ "Receive Fragment",
+ "Receive Oversize",
+ "Receive Jabber",
+ "Management Packets Rx",
+ "Management Packets Drop",
+ "Management Packets Tx",
+ "Total Octets Received",
+ NULL,
+ "Total Octets Transmitted",
+ NULL,
+ "Total Packets Received",
+ "Total Packets Transmitted",
+ "Packets Transmitted (64 Bytes)",
+ "Packets Transmitted (65-127 Bytes)",
+ "Packets Transmitted (128-255 Bytes)",
+ "Packets Transmitted (256-511 Bytes)",
+ "Packets Transmitted (512-1023 Bytes)",
+ "Packets Transmitted (1024-mtu Bytes)",
+ "Multicast Packets Transmitted",
+ "Broadcast Packets Transmitted",
+ "TCP Segmentation Context Transmitted",
+ "TCP Segmentation Context Fail",
+ "Interrupt Assertion",
+ "Interrupt Rx Pkt Timer",
+ "Interrupt Rx Abs Timer",
+ "Interrupt Tx Pkt Timer",
+ "Interrupt Tx Abs Timer",
+ "Interrupt Tx Queue Empty",
+ "Interrupt Tx Desc Low",
+ "Interrupt Rx Min",
+ "Interrupt Rx Overrun",
};
static char *cname(struct ctlr *c)
@@ -760,30 +756,32 @@
if (stat == NULL)
continue;
switch (i) {
- case Gorcl:
- case Gotcl:
- case Torl:
- case Totl:
- ruvl = r;
- ruvl += (uint64_t) csr32r(ctlr, Statistics + (i + 1) * 4) << 32;
- tuvl = ruvl;
- tuvl += ctlr->statistics[i];
- tuvl += (uint64_t) ctlr->statistics[i + 1] << 32;
- if (tuvl == 0)
- continue;
- ctlr->statistics[i] = tuvl;
- ctlr->statistics[i + 1] = tuvl >> 32;
- p = seprintf(p, e, "%s: %llud %llud\n", stat, tuvl, ruvl);
- i++;
- break;
+ case Gorcl:
+ case Gotcl:
+ case Torl:
+ case Totl:
+ ruvl = r;
+ ruvl += (uint64_t)csr32r(ctlr, Statistics + (i + 1) * 4)
+ << 32;
+ tuvl = ruvl;
+ tuvl += ctlr->statistics[i];
+ tuvl += (uint64_t)ctlr->statistics[i + 1] << 32;
+ if (tuvl == 0)
+ continue;
+ ctlr->statistics[i] = tuvl;
+ ctlr->statistics[i + 1] = tuvl >> 32;
+ p = seprintf(p, e, "%s: %llud %llud\n", stat, tuvl,
+ ruvl);
+ i++;
+ break;
- default:
- ctlr->statistics[i] += r;
- if (ctlr->statistics[i] == 0)
- continue;
- p = seprintf(p, e, "%s: %ud %ud\n", stat,
- ctlr->statistics[i], r);
- break;
+ default:
+ ctlr->statistics[i] += r;
+ if (ctlr->statistics[i] == 0)
+ continue;
+ p = seprintf(p, e, "%s: %ud %ud\n", stat,
+ ctlr->statistics[i], r);
+ break;
}
}
@@ -791,7 +789,7 @@
p = seprintf(p, e, "rintr: %ud %ud\n", ctlr->rintr, ctlr->rsleep);
p = seprintf(p, e, "tintr: %ud %ud\n", ctlr->tintr, ctlr->txdw);
p = seprintf(p, e, "ixcs: %ud %ud %ud\n", ctlr->ixsm, ctlr->ipcs,
- ctlr->tcpcs);
+ ctlr->tcpcs);
p = seprintf(p, e, "ctrl: %.8ux\n", csr32r(ctlr, Ctrl));
p = seprintf(p, e, "ctrlext: %.8ux\n", csr32r(ctlr, Ctrlext));
p = seprintf(p, e, "status: %.8ux\n", csr32r(ctlr, Status));
@@ -801,17 +799,17 @@
p = seprintf(p, e, "pba: %#.8ux\n", ctlr->pba);
p = seprintf(p, e, "speeds: 10:%ud 100:%ud 1000:%ud ?:%ud\n",
- ctlr->speeds[0], ctlr->speeds[1], ctlr->speeds[2],
- ctlr->speeds[3]);
+ ctlr->speeds[0], ctlr->speeds[1], ctlr->speeds[2],
+ ctlr->speeds[3]);
p = seprintf(p, e, "type: %s\n", cname(ctlr));
-// p = seprintf(p, e, "eeprom:");
-// for(i = 0; i < 0x40; i++){
-// if(i && ((i & 7) == 0))
-// p = seprintf(p, e, "\n ");
-// p = seprintf(p, e, " %4.4ux", ctlr->eeprom[i]);
-// }
-// p = seprintf(p, e, "\n");
+ // p = seprintf(p, e, "eeprom:");
+ // for(i = 0; i < 0x40; i++){
+ // if(i && ((i & 7) == 0))
+ // p = seprintf(p, e, "\n ");
+ // p = seprintf(p, e, " %4.4ux", ctlr->eeprom[i]);
+ // }
+ // p = seprintf(p, e, "\n");
n = readstr(offset, a, n, s);
kfree(s);
@@ -820,18 +818,17 @@
return n;
}
-enum {
- CMrdtr,
- CMradv,
- CMpause,
- CMan,
+enum { CMrdtr,
+ CMradv,
+ CMpause,
+ CMan,
};
static struct cmdtab i82563ctlmsg[] = {
- {CMrdtr, "rdtr", 2},
- {CMradv, "radv", 2},
- {CMpause, "pause", 1},
- {CMan, "an", 1},
+ {CMrdtr, "rdtr", 2},
+ {CMradv, "radv", 2},
+ {CMpause, "pause", 1},
+ {CMan, "an", 1},
};
static long i82563ctl(struct ether *edev, void *buf, long n)
@@ -855,26 +852,26 @@
ct = lookupcmd(cb, i82563ctlmsg, ARRAY_SIZE(i82563ctlmsg));
switch (ct->index) {
- case CMrdtr:
- v = strtoul(cb->f[1], &p, 0);
- if (*p || v > 0xffff)
- error(EINVAL, ERROR_FIXME);
- ctlr->rdtr = v;
- csr32w(ctlr, Rdtr, v);
- break;
- case CMradv:
- v = strtoul(cb->f[1], &p, 0);
- if (*p || v > 0xffff)
- error(EINVAL, ERROR_FIXME);
- ctlr->radv = v;
- csr32w(ctlr, Radv, v);
- break;
- case CMpause:
- csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) ^ (Rfce | Tfce));
- break;
- case CMan:
- csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) | Lrst | Phyrst);
- break;
+ case CMrdtr:
+ v = strtoul(cb->f[1], &p, 0);
+ if (*p || v > 0xffff)
+ error(EINVAL, ERROR_FIXME);
+ ctlr->rdtr = v;
+ csr32w(ctlr, Rdtr, v);
+ break;
+ case CMradv:
+ v = strtoul(cb->f[1], &p, 0);
+ if (*p || v > 0xffff)
+ error(EINVAL, ERROR_FIXME);
+ ctlr->radv = v;
+ csr32w(ctlr, Radv, v);
+ break;
+ case CMpause:
+ csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) ^ (Rfce | Tfce));
+ break;
+ case CMan:
+ csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) | Lrst | Phyrst);
+ break;
}
kfree(cb);
poperror();
@@ -912,38 +909,39 @@
static int mcastbits(struct ctlr *ctlr)
{
switch (ctlr->type) {
- /*
- * openbsd says all `ich8' versions (ich8, ich9, ich10, pch,
- * pch2 and pch_lpt) have 32 longs (use 10 bits of mac address
- * for hash).
- */
- case i82566:
- case i82567:
- // case i82578:
- case i82579:
- case i217:
- case i218:
- // case i219:
- return 10; /* 32 longs */
- case i82563:
- case i82571:
- case i82572:
- case i82573:
- case i82574:
- // case i82575:
- // case i82583:
- case i210: /* includes i211 */
- return 12; /* 128 longs */
- default:
- printk("82563: unsure of multicast bits in mac addresses; enabling promiscuous multicast reception\n");
- csr32w(ctlr, Rctl, csr32r(ctlr, Rctl) | Mpe);
- return 10; /* be conservative (for mta size) */
- }
+ /*
+ * openbsd says all `ich8' versions (ich8, ich9, ich10, pch,
+ * pch2 and pch_lpt) have 32 longs (use 10 bits of mac address
+ * for hash).
+ */
+ case i82566:
+ case i82567:
+ // case i82578:
+ case i82579:
+ case i217:
+ case i218:
+ // case i219:
+ return 10; /* 32 longs */
+ case i82563:
+ case i82571:
+ case i82572:
+ case i82573:
+ case i82574:
+ // case i82575:
+ // case i82583:
+ case i210: /* includes i211 */
+ return 12; /* 128 longs */
+ default:
+ printk("82563: unsure of multicast bits in mac addresses; "
+ "enabling promiscuous multicast reception\n");
+ csr32w(ctlr, Rctl, csr32r(ctlr, Rctl) | Mpe);
+ return 10; /* be conservative (for mta size) */
+ }
}
static int mcbitstolongs(int nmcbits)
{
- return 1 << (nmcbits - 5); /* 2^5 = 32 */
+ return 1 << (nmcbits - 5); /* 2^5 = 32 */
}
static void i82563multicast(void *arg, uint8_t *addr, int on)
@@ -958,9 +956,9 @@
nbits = mcastbits(ctlr);
tblsz = mcbitstolongs(nbits);
/* assume multicast offset in Rctl is 0 (we clear it above) */
- hash = addr[5] << 4 | addr[4] >> 4; /* bits 47:36 of mac */
+ hash = addr[5] << 4 | addr[4] >> 4; /* bits 47:36 of mac */
if (nbits == 10)
- hash >>= 2; /* discard 37:36 of mac */
+ hash >>= 2; /* discard 37:36 of mac */
word = (hash / 32) & (tblsz - 1);
bit = 1UL << (hash % 32);
/*
@@ -972,9 +970,9 @@
*/
if (on)
ctlr->mta[word] |= bit;
-// else
-// ctlr->mta[word] &= ~bit;
- csr32w(ctlr, Mta+word*4, ctlr->mta[word]);
+ // else
+ // ctlr->mta[word] &= ~bit;
+ csr32w(ctlr, Mta + word * 4, ctlr->mta[word]);
}
static void i82563im(struct ctlr *ctlr, int im)
@@ -1000,18 +998,18 @@
tctl |= (66 << ColdSHIFT | Mulr);
}
switch (ctlr->type) {
- case i210:
- break;
- default:
- tctl |= Mulr;
- /* fall through */
- case i217:
- case i218:
- tctl |= 66 << ColdSHIFT;
- break;
+ case i210:
+ break;
+ default:
+ tctl |= Mulr;
+ /* fall through */
+ case i217:
+ case i218:
+ tctl |= 66 << ColdSHIFT;
+ break;
}
csr32w(ctlr, Tctl, tctl);
- csr32w(ctlr, Tipg, 6 << 20 | 8 << 10 | 8); /* yb sez: 0x702008 */
+ csr32w(ctlr, Tipg, 6 << 20 | 8 << 10 | 8); /* yb sez: 0x702008 */
for (i = 0; i < Ntd; i++) {
bp = ctlr->tb[i];
if (bp != NULL) {
@@ -1027,7 +1025,7 @@
csr32w(ctlr, Tdh, 0);
ctlr->tdt = 0;
csr32w(ctlr, Tdt, 0);
- csr32w(ctlr, Tidv, 0); /* don't coalesce interrupts */
+ csr32w(ctlr, Tidv, 0); /* don't coalesce interrupts */
csr32w(ctlr, Tadv, 0);
r = csr32r(ctlr, Txdctl) & ~(WthreshMASK | PthreshMASK);
r |= 4 << WthreshSHIFT | 4 << PthreshSHIFT;
@@ -1082,7 +1080,7 @@
*/
tdt = ctlr->tdt;
for (;;) {
- if (NEXT_RING(tdt, Ntd) == tdh) { /* ring full? */
+ if (NEXT_RING(tdt, Ntd) == tdh) { /* ring full? */
ctlr->txdw++;
i82563im(ctlr, Txdw);
break;
@@ -1152,15 +1150,17 @@
if (ctlr->rbsz % 1024)
i++;
if (ctlrtab[ctlr->type].flag & F75) {
- csr32w(ctlr, Rctl, Lpe | Dpf | Bsize2048 | Bam | RdtmsHALF | Secrc);
+ csr32w(ctlr, Rctl,
+ Lpe | Dpf | Bsize2048 | Bam | RdtmsHALF | Secrc);
if (ctlr->type != i82575)
- i |= (Nrd / 2 >> 4) << 20; /* RdmsHalf */
+ i |= (Nrd / 2 >> 4) << 20; /* RdmsHalf */
csr32w(ctlr, Srrctl, i | Dropen);
csr32w(ctlr, Rmpl, ctlr->rbsz);
// csr32w(ctlr, Drxmxod, 0x7ff);
} else
csr32w(ctlr, Rctl,
- Lpe | Dpf | BsizeFlex * i | Bam | RdtmsHALF | Secrc);
+ Lpe | Dpf | BsizeFlex * i | Bam | RdtmsHALF |
+ Secrc);
}
/*
@@ -1180,7 +1180,7 @@
}
if (ctlrtab[ctlr->type].flag & Fert)
- csr32w(ctlr, Ert, 1024 / 8); /* early rx threshold */
+ csr32w(ctlr, Ert, 1024 / 8); /* early rx threshold */
csr32w(ctlr, Rdbal, paddr_low32(ctlr->rdba));
csr32w(ctlr, Rdbah, paddr_high32(ctlr->rdba));
@@ -1246,7 +1246,8 @@
}
if (rd->status & Tcpcs) {
/*
- * TCP/UDP checksum calculated (and valid as errors == 0).
+ * TCP/UDP checksum calculated (and valid as errors ==
+ * 0).
*/
ctlr->tcpcs++;
bp->flag |= Btcpck | Budpck;
@@ -1295,15 +1296,15 @@
bp = ctlr->rb[rdh];
if ((rd->status & Reop) && rd->errors == 0) {
bp->wp += rd->length;
- bp->lim = bp->wp; /* lie like a dog. */
+ bp->lim = bp->wp; /* lie like a dog. */
if (0)
ckcksums(ctlr, rd, bp);
- etheriq(edev, bp, 1); /* pass pkt upstream */
+ etheriq(edev, bp, 1); /* pass pkt upstream */
passed++;
} else {
if (rd->status & Reop && rd->errors)
printd("%s: input packet error %#ux\n",
- tname[ctlr->type], rd->errors);
+ tname[ctlr->type], rd->errors);
freeb(bp);
}
ctlr->rb[rdh] = NULL;
@@ -1331,16 +1332,17 @@
{
if (ctlr->phynum < 0)
switch (ctlr->type) {
- case i82577:
-// case i82578: /* not yet implemented */
- case i82579:
- case i217:
- case i218:
- ctlr->phynum = 2; /* pcie phy */
- break;
- default:
- ctlr->phynum = 1; /* gbe phy */
- break;
+ case i82577:
+ // case i82578: /* not yet implemented
+ // */
+ case i82579:
+ case i217:
+ case i218:
+ ctlr->phynum = 2; /* pcie phy */
+ break;
+ default:
+ ctlr->phynum = 1; /* gbe phy */
+ break;
}
return ctlr->phynum;
}
@@ -1351,7 +1353,8 @@
if (reg >= 32)
iprint("phyread: reg %d >= 32\n", reg);
- csr32w(ctlr, Mdic, MDIrop | phynum(ctlr) << MDIpSHIFT | reg << MDIrSHIFT);
+ csr32w(ctlr, Mdic,
+ MDIrop | phynum(ctlr) << MDIpSHIFT | reg << MDIrSHIFT);
phy = 0;
for (i = 0; i < 64; i++) {
phy = csr32r(ctlr, Mdic);
@@ -1370,8 +1373,8 @@
if (reg >= 32)
iprint("phyread: reg %d >= 32\n", reg);
- csr32w(ctlr, Mdic, MDIwop | phynum(ctlr) << MDIpSHIFT | reg << MDIrSHIFT |
- val);
+ csr32w(ctlr, Mdic,
+ MDIwop | phynum(ctlr) << MDIpSHIFT | reg << MDIrSHIFT | val);
phy = 0;
for (i = 0; i < 64; i++) {
phy = csr32r(ctlr, Mdic);
@@ -1388,7 +1391,8 @@
{
/* write register address */
csr32w(ctlr, Kumctrlsta,
- ((reg_addr << Kumctrlstaoffshift) & Kumctrlstaoff) | Kumctrlstaren);
+ ((reg_addr << Kumctrlstaoffshift) & Kumctrlstaoff) |
+ Kumctrlstaren);
udelay(2);
/* read data */
return csr32r(ctlr, Kumctrlsta);
@@ -1396,8 +1400,8 @@
static void kmrnwrite(struct ctlr *ctlr, uint32_t reg_addr, uint16_t data)
{
- csr32w(ctlr, Kumctrlsta, ((reg_addr << Kumctrlstaoffshift) &
- Kumctrlstaoff) | data);
+ csr32w(ctlr, Kumctrlsta,
+ ((reg_addr << Kumctrlstaoffshift) & Kumctrlstaoff) | data);
udelay(2);
}
@@ -1426,7 +1430,7 @@
*/
static void k1fix(struct ctlr *ctlr)
{
- int txtmout; /* units of 10µs */
+ int txtmout; /* units of 10µs */
uint32_t fextnvm6, status;
uint16_t reg;
struct ether *edev;
@@ -1451,8 +1455,8 @@
* 217 manual claims not to have Frcdplx bit in status;
* 218 manual just omits the non-phy registers.
*/
- if (!edev->link ||
- (status & (Sspeed100 >> 2 | Frcdplx)) == (Sspeed100 >> 2 | Frcdplx)) {
+ if (!edev->link || (status & (Sspeed100 >> 2 | Frcdplx)) ==
+ (Sspeed100 >> 2 | Frcdplx)) {
csr32w(ctlr, Fextnvm6, fextnvm6);
ctlr->didk1fix = 1;
return;
@@ -1461,17 +1465,17 @@
/* access other page via phy addr 1 reg 31, then access reg 16-30 */
phywrite(ctlr, Phypage, I217inbandctlpage << 5);
reg = phyread(ctlr, I217inbandctlreg) & ~I217inbandctllnkststxtmoutmask;
- if (status & (Sspeed100 >> 2)) { /* 100Mb/s half-duplex? */
+ if (status & (Sspeed100 >> 2)) { /* 100Mb/s half-duplex? */
txtmout = 5;
fextnvm6 &= ~Fextnvm6enak1entrycond;
- } else { /* 10Mb/s */
+ } else { /* 10Mb/s */
txtmout = 50;
fextnvm6 |= Fextnvm6enak1entrycond;
}
- phywrite(ctlr, I217inbandctlreg, reg |
- txtmout << I217inbandctllnkststxtmoutshift);
+ phywrite(ctlr, I217inbandctlreg,
+ reg | txtmout << I217inbandctllnkststxtmoutshift);
csr32w(ctlr, Fextnvm6, fextnvm6);
- phywrite(ctlr, Phypage, 0 << 5); /* reset page to usual 0 */
+ phywrite(ctlr, Phypage, 0 << 5); /* reset page to usual 0 */
ctlr->didk1fix = 1;
}
@@ -1488,13 +1492,13 @@
ctlr = edev->ctlr;
phy79 = 0;
switch (ctlr->type) {
- case i82579:
- case i82580:
- case i217:
- case i218:
- case i350:
- phy79 = 1;
- break;
+ case i82579:
+ case i82580:
+ case i217:
+ case i218:
+ case i350:
+ phy79 = 1;
+ break;
}
/*
* TODO(dcross): Extract PHY number from ctlrtab.
@@ -1519,33 +1523,35 @@
} else {
sp = (phy >> 14) & 3;
switch (ctlr->type) {
- case i82563:
- case i210:
- a = phyread(ctlr, Phyisr) & Ane; /* a-n error */
- break;
- case i82571:
- case i82572:
- case i82575:
- case i82576:
- a = phyread(ctlr, Phylhr) & Anf; /* a-n fault */
- sp = (sp - 1) & 3;
- break;
+ case i82563:
+ case i210:
+ a = phyread(ctlr, Phyisr) & Ane; /* a-n error */
+ break;
+ case i82571:
+ case i82572:
+ case i82575:
+ case i82576:
+ a = phyread(ctlr, Phylhr) & Anf; /* a-n fault */
+ sp = (sp - 1) & 3;
+ break;
}
}
- if (a) /* enable & restart autoneg */ /* enable & restart autoneg */
- phywrite(ctlr, Phyctl, phyread(ctlr, Phyctl) | Ran | Ean);
+ if (a) /* enable & restart autoneg */ /* enable & restart
+ autoneg */
+ phywrite(ctlr, Phyctl,
+ phyread(ctlr, Phyctl) | Ran | Ean);
edev->link = (phy & (phy79 ? Link : Rtlink)) != 0;
if (edev->link) {
ctlr->speeds[sp]++;
if (speedtab[sp])
edev->mbps = speedtab[sp];
if (prevlink == 0 && ctlr->type == i218)
- k1fix(ctlr); /* link newly up: kludge away */
+ k1fix(ctlr); /* link newly up: kludge away */
netif_carrier_on(edev);
} else
- ctlr->didk1fix = 0; /* force fix at next link up */
+ ctlr->didk1fix = 0; /* force fix at next link up */
prevlink = edev->link;
-next:
+ next:
ctlr->lim = 0;
i82563im(ctlr, Lsc);
ctlr->lsleep++;
@@ -1627,9 +1633,8 @@
nexterror();
}
- ctlr->alloc = kzmalloc(Nrd * sizeof(struct rd) +
- Ntd * sizeof(struct td) + 255,
- MEM_WAIT);
+ ctlr->alloc = kzmalloc(
+ Nrd * sizeof(struct rd) + Ntd * sizeof(struct td) + 255, MEM_WAIT);
if (ctlr->alloc == NULL) {
qunlock(&ctlr->alock);
error(ENOMEM, "i82563attach: error allocating rx/tx rings");
@@ -1643,7 +1648,7 @@
error(ENOMEM, "i82563attach: error allocating rx/tx buffers");
}
- ctlr->edev = edev; /* point back to Ether* */
+ ctlr->edev = edev; /* point back to Ether* */
ctlr->attached = 1;
lname = kzmalloc(KNAMELEN, MEM_WAIT);
@@ -1676,9 +1681,9 @@
csr32w(ctlr, Imc, ~0);
im = ctlr->im;
loops = 0;
- i = Nrd; /* don't livelock */
+ i = Nrd; /* don't livelock */
for (icr = csr32r(ctlr, Icr); icr & ctlr->im && i-- > 0;
- icr = csr32r(ctlr, Icr)) {
+ icr = csr32r(ctlr, Icr)) {
loops++;
if (icr & Lsc) {
im &= ~Lsc;
@@ -1710,7 +1715,7 @@
struct ctlr *ctlr;
for (ctlr = i82563ctlrhead; ctlr != NULL && ctlr->edev != NULL;
- ctlr = ctlr->next)
+ ctlr = ctlr->next)
i82563interrupt(NULL, ctlr->edev);
}
@@ -1751,21 +1756,22 @@
/* set packet buffer size if present. no effect until soft reset. */
switch (ctlr->type) {
- case i82566:
- case i82567:
- case i217:
- ctlr->pbs = 16; /* in KB */
- csr32w(ctlr, Pbs, ctlr->pbs);
- break;
- case i218:
- // after pxe or 9fat boot, pba is always 0xe0012 on i218 => 32K
- ctlr->pbs = (ctlr->pba >> 16) + (uint16_t) ctlr->pba;
- csr32w(ctlr, Pbs, ctlr->pbs);
- break;
+ case i82566:
+ case i82567:
+ case i217:
+ ctlr->pbs = 16; /* in KB */
+ csr32w(ctlr, Pbs, ctlr->pbs);
+ break;
+ case i218:
+ // after pxe or 9fat boot, pba is always 0xe0012 on i218 => 32K
+ ctlr->pbs = (ctlr->pba >> 16) + (uint16_t)ctlr->pba;
+ csr32w(ctlr, Pbs, ctlr->pbs);
+ break;
}
r = csr32r(ctlr, Ctrl);
- if (ctlr->type == i82566 || ctlr->type == i82567 || ctlr->type == i82579)
+ if (ctlr->type == i82566 || ctlr->type == i82567 ||
+ ctlr->type == i82579)
r |= Phyrst;
csr32w(ctlr, Ctrl, Devrst | r);
udelay(1000);
@@ -1855,7 +1861,7 @@
return -1;
f->reg[Fsts] |= Fcerr | Ael;
for (i = 0; i < 10; i++) {
- if ((s & Scip) == 0) /* spi cycle done? */
+ if ((s & Scip) == 0) /* spi cycle done? */
return 0;
udelay(1000);
s = f->reg[Fsts];
@@ -1876,8 +1882,8 @@
/* setup flash control register */
s = f->reg[Fctl] & ~(0x1f << 8);
- s |= (2 - 1) << 8; /* 2 bytes */
- s &= ~(2 * Flcycle); /* read */
+ s |= (2 - 1) << 8; /* 2 bytes */
+ s &= ~(2 * Flcycle); /* read */
f->reg[Fctl] = s | Fgo;
n = 1000000;
@@ -1899,8 +1905,8 @@
struct pci_device *pcidev = ctlr->pcidev;
struct flash f;
- mmio_paddr = pcidev->bar[1].mmio_base32 ? pcidev->bar[1].mmio_base32 :
- pcidev->bar[1].mmio_base64;
+ mmio_paddr = pcidev->bar[1].mmio_base32 ? pcidev->bar[1].mmio_base32
+ : pcidev->bar[1].mmio_base64;
f.reg = (void *)vmap_pmem(mmio_paddr, pcidev->bar[1].mmio_sz);
if (f.reg == NULL)
return -1;
@@ -1938,22 +1944,22 @@
if (ctlr->ra[Eaddrlen - 1] != 0)
goto macset;
switch (type) {
- case i82566:
- case i82567:
- case i82577:
- // case i82578: /* not yet implemented */
- case i82579:
- case i217:
- case i218:
- r = fload(ctlr);
- break;
- default:
- r = eeload(ctlr);
- break;
+ case i82566:
+ case i82567:
+ case i82577:
+ // case i82578: /* not yet implemented */
+ case i82579:
+ case i217:
+ case i218:
+ r = fload(ctlr);
+ break;
+ default:
+ r = eeload(ctlr);
+ break;
}
if (r != 0 && r != 0xBABA) {
printd("%s: bad EEPROM checksum - %#.4ux\n", tname[type], r);
- //return -1;
+ // return -1;
}
/* set mac addr */
@@ -1968,7 +1974,7 @@
* AV bits should be zeroed by master reset & there may only be 11
* other registers on e.g., the i217.
*/
- for (i = 1; i < 12; i++) { /* `12' used to be `16' here */
+ for (i = 1; i < 12; i++) { /* `12' used to be `16' here */
csr32w(ctlr, Ral + i * 8, 0);
csr32w(ctlr, Rah + i * 8, 0);
}
@@ -1976,8 +1982,8 @@
macset:
/* low mac addr */
csr32w(ctlr, Ral,
- ctlr->ra[3] << 24 | ctlr->ra[2] << 16 |
- ctlr->ra[1] << 8 | ctlr->ra[0]);
+ ctlr->ra[3] << 24 | ctlr->ra[2] << 16 | ctlr->ra[1] << 8 |
+ ctlr->ra[0]);
/* address valid | high mac addr */
csr32w(ctlr, Rah, 0x80000000 | ctlr->ra[5] << 8 | ctlr->ra[4]);
@@ -1996,7 +2002,7 @@
if (type != i82579 && type != i210 && type != i217 && type != i218)
/* flow control type, dictated by Intel */
csr32w(ctlr, Fct, 0x8808);
- csr32w(ctlr, Fcttv, 0x0100); /* for XOFF frame */
+ csr32w(ctlr, Fcttv, 0x0100); /* for XOFF frame */
// ctlr->fcrtl = 0x00002000; /* rcv low water mark: 8KB */
/* rcv high water mark: 16KB, < rcv buffer in PBA & RXA */
// ctlr->fcrth = 0x00004000;
@@ -2015,127 +2021,127 @@
struct ctlr *ctlr;
p = NULL;
- STAILQ_FOREACH(p, &pci_devices, all_dev) {
+ STAILQ_FOREACH (p, &pci_devices, all_dev) {
if (p->ven_id != 0x8086)
continue;
switch (p->dev_id) {
- default:
- continue;
- case 0x1096:
- case 0x10ba:
- case 0x1098: /* serdes; not seen */
- case 0x10bb: /* serdes */
- type = i82563;
- break;
- case 0x1049: /* mm */
- case 0x104a: /* dm */
- case 0x104b: /* dc */
- case 0x104d: /* mc */
- case 0x10bd: /* dm */
- case 0x294c: /* dc-2 */
- type = i82566;
- break;
- case 0x10de: /* lm-3 */
- case 0x10df: /* lf ich10 */
- case 0x10e5: /* lm ich9 */
- case 0x10f5: /* lm-2 */
- type = i82567;
- break;
- case 0x10bf: /* lf ich9m */
- case 0x10cb: /* v ich9m */
- case 0x10cd: /* lf ich10 */
- case 0x10ce: /* v ich10 */
- case 0x10cc: /* lm ich10 */
- type = i82567m;
- break;
- case 0x105e: /* eb */
- case 0x105f: /* eb */
- case 0x1060: /* eb */
- case 0x10a4: /* eb */
- case 0x10a5: /* eb fiber */
- case 0x10bc: /* eb */
- case 0x10d9: /* eb serdes */
- case 0x10da: /* eb serdes “ophir” */
- type = i82571;
- break;
- case 0x107d: /* eb copper */
- case 0x107e: /* ei fiber */
- case 0x107f: /* ei */
- case 0x10b9: /* sic, 82572gi */
- type = i82572;
- break;
- case 0x108b: /* v */
- case 0x108c: /* e (iamt) */
- case 0x109a: /* l */
- type = i82573;
- break;
- case 0x10d3: /* l */
- type = i82574;
- break;
- case 0x10a7: /* 82575eb: one of a pair of controllers */
- case 0x10a9: /* fiber/serdes */
- type = i82575;
- break;
- case 0x10c9: /* 82576 copper */
- case 0x10e6: /* 82576 fiber */
- case 0x10e7: /* 82576 serdes */
- case 0x150d: /* backplane */
- type = i82576;
- break;
- case 0x10ea: /* 82577lm */
- type = i82577;
- break;
- case 0x10eb: /* lm “calpella” */
- type = i82577m;
- break;
- case 0x1502: /* 82579lm */
- case 0x1503: /* 82579v */
- type = i82579;
- break;
- case 0x10f0: /* dm “king's creek” */
- type = i82578m;
- break;
- case 0x150e: /* “barton hills” */
- case 0x150f: /* fiber */
- case 0x1510: /* backplane */
- case 0x1511: /* sfp */
- case 0x1516:
- type = i82580;
- break;
- case 0x1506: /* v */
- type = i82583;
- break;
- case 0x1533: /* i210-t1 */
- case 0x1534: /* i210 */
- case 0x1536: /* i210-fiber */
- case 0x1537: /* i210-backplane */
- case 0x1538:
- case 0x1539: /* i211 */
- case 0x157b: /* i210 */
- case 0x157c: /* i210 */
- type = i210;
- break;
- case 0x153a: /* i217-lm */
- case 0x153b: /* i217-v */
- type = i217;
- break;
- case 0x15a0: /* i218-lm */
- case 0x15a1: /* i218-v */
- case 0x15a2: /* i218-lm */
- case 0x15a3: /* i218-v */
- type = i218;
- break;
- case 0x151f: /* “powerville” eeprom-less */
- case 0x1521: /* copper */
- case 0x1522: /* fiber */
- case 0x1523: /* serdes */
- case 0x1524: /* sgmii */
- type = i350;
- break;
+ default:
+ continue;
+ case 0x1096:
+ case 0x10ba:
+ case 0x1098: /* serdes; not seen */
+ case 0x10bb: /* serdes */
+ type = i82563;
+ break;
+ case 0x1049: /* mm */
+ case 0x104a: /* dm */
+ case 0x104b: /* dc */
+ case 0x104d: /* mc */
+ case 0x10bd: /* dm */
+ case 0x294c: /* dc-2 */
+ type = i82566;
+ break;
+ case 0x10de: /* lm-3 */
+ case 0x10df: /* lf ich10 */
+ case 0x10e5: /* lm ich9 */
+ case 0x10f5: /* lm-2 */
+ type = i82567;
+ break;
+ case 0x10bf: /* lf ich9m */
+ case 0x10cb: /* v ich9m */
+ case 0x10cd: /* lf ich10 */
+ case 0x10ce: /* v ich10 */
+ case 0x10cc: /* lm ich10 */
+ type = i82567m;
+ break;
+ case 0x105e: /* eb */
+ case 0x105f: /* eb */
+ case 0x1060: /* eb */
+ case 0x10a4: /* eb */
+ case 0x10a5: /* eb fiber */
+ case 0x10bc: /* eb */
+ case 0x10d9: /* eb serdes */
+ case 0x10da: /* eb serdes “ophir” */
+ type = i82571;
+ break;
+ case 0x107d: /* eb copper */
+ case 0x107e: /* ei fiber */
+ case 0x107f: /* ei */
+ case 0x10b9: /* sic, 82572gi */
+ type = i82572;
+ break;
+ case 0x108b: /* v */
+ case 0x108c: /* e (iamt) */
+ case 0x109a: /* l */
+ type = i82573;
+ break;
+ case 0x10d3: /* l */
+ type = i82574;
+ break;
+ case 0x10a7: /* 82575eb: one of a pair of controllers */
+ case 0x10a9: /* fiber/serdes */
+ type = i82575;
+ break;
+ case 0x10c9: /* 82576 copper */
+ case 0x10e6: /* 82576 fiber */
+ case 0x10e7: /* 82576 serdes */
+ case 0x150d: /* backplane */
+ type = i82576;
+ break;
+ case 0x10ea: /* 82577lm */
+ type = i82577;
+ break;
+ case 0x10eb: /* lm “calpella” */
+ type = i82577m;
+ break;
+ case 0x1502: /* 82579lm */
+ case 0x1503: /* 82579v */
+ type = i82579;
+ break;
+ case 0x10f0: /* dm “king's creek” */
+ type = i82578m;
+ break;
+ case 0x150e: /* “barton hills” */
+ case 0x150f: /* fiber */
+ case 0x1510: /* backplane */
+ case 0x1511: /* sfp */
+ case 0x1516:
+ type = i82580;
+ break;
+ case 0x1506: /* v */
+ type = i82583;
+ break;
+ case 0x1533: /* i210-t1 */
+ case 0x1534: /* i210 */
+ case 0x1536: /* i210-fiber */
+ case 0x1537: /* i210-backplane */
+ case 0x1538:
+ case 0x1539: /* i211 */
+ case 0x157b: /* i210 */
+ case 0x157c: /* i210 */
+ type = i210;
+ break;
+ case 0x153a: /* i217-lm */
+ case 0x153b: /* i217-v */
+ type = i217;
+ break;
+ case 0x15a0: /* i218-lm */
+ case 0x15a1: /* i218-v */
+ case 0x15a2: /* i218-lm */
+ case 0x15a3: /* i218-v */
+ type = i218;
+ break;
+ case 0x151f: /* “powerville” eeprom-less */
+ case 0x1521: /* copper */
+ case 0x1522: /* fiber */
+ case 0x1523: /* serdes */
+ case 0x1524: /* sgmii */
+ type = i350;
+ break;
}
- io = p->bar[0].mmio_base32 ? p->bar[0].mmio_base32 :
- p->bar[0].mmio_base64;
+ io = p->bar[0].mmio_base32 ? p->bar[0].mmio_base32
+ : p->bar[0].mmio_base64;
mem = (void *)vmap_pmem(io, p->bar[0].mmio_sz);
if (mem == NULL) {
printd("%s: can't map %.8lux\n", tname[type], io);
@@ -2151,7 +2157,7 @@
ctlr->pcidev = p;
ctlr->type = type;
ctlr->nic = mem;
- ctlr->phynum = -1; /* not yet known */
+ ctlr->phynum = -1; /* not yet known */
qlock_init(&ctlr->alock);
spinlock_init_irqsave(&ctlr->imlock);
@@ -2205,7 +2211,7 @@
edev->ctlr = ctlr;
strlcpy(edev->drv_name, "i82563", KNAMELEN);
- ctlr->edev = edev; /* point back to Ether* */
+ ctlr->edev = edev; /* point back to Ether* */
edev->port = ctlr->mmio_paddr;
edev->irq = ctlr->pcidev->irqline;
edev->tbdf = pci_to_tbdf(ctlr->pcidev);
@@ -2213,8 +2219,8 @@
edev->max_mtu = ctlr->rbsz - ETHERHDRSIZE;
edev->mtu = edev->mtu;
memmove(edev->ea, ctlr->ra, Eaddrlen);
- /* Jim or whoever have this turned on already. We might be capable of other
- * features. */
+ /* Jim or whoever have this turned on already. We might be capable of
+ * other features. */
edev->feat = NETF_RXCSUM;
/*
diff --git a/kern/drivers/net/etherigbe.c b/kern/drivers/net/etherigbe.c
index fae902f..7da2d76 100644
--- a/kern/drivers/net/etherigbe.c
+++ b/kern/drivers/net/etherigbe.c
@@ -29,237 +29,236 @@
* fixed CLS bug (continue -> break)
* made sure igbepci only runs once, even if it fails */
-#include <slab.h>
+#include <arch/pci.h>
+#include <assert.h>
+#include <cpio.h>
+#include <error.h>
#include <kmalloc.h>
#include <kref.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <error.h>
-#include <cpio.h>
-#include <pmap.h>
-#include <smp.h>
-#include <arch/pci.h>
#include <net/ip.h>
#include <ns.h>
+#include <pmap.h>
+#include <slab.h>
+#include <smp.h>
+#include <stdio.h>
+#include <string.h>
+
#include "ethermii.h"
#define ilock(x) spin_lock_irqsave(x)
#define iunlock(x) spin_unlock_irqsave(x)
-enum {
- i82542 = (0x1000<<16)|0x8086,
- i82543gc = (0x1004<<16)|0x8086,
- i82544ei = (0x1008<<16)|0x8086,
- i82544eif = (0x1009<<16)|0x8086,
- i82544gc = (0x100d<<16)|0x8086,
- i82540em = (0x100E<<16)|0x8086,
- i82540eplp = (0x101E<<16)|0x8086,
- i82545em = (0x100F<<16)|0x8086,
- i82545gmc = (0x1026<<16)|0x8086,
- i82547ei = (0x1019<<16)|0x8086,
- i82547gi = (0x1075<<16)|0x8086,
- i82541ei = (0x1013<<16)|0x8086,
- i82541gi = (0x1076<<16)|0x8086,
- i82541gi2 = (0x1077<<16)|0x8086,
- i82541pi = (0x107c<<16)|0x8086,
- i82546gb = (0x1079<<16)|0x8086,
- i82546eb = (0x1010<<16)|0x8086,
+enum { i82542 = (0x1000 << 16) | 0x8086,
+ i82543gc = (0x1004 << 16) | 0x8086,
+ i82544ei = (0x1008 << 16) | 0x8086,
+ i82544eif = (0x1009 << 16) | 0x8086,
+ i82544gc = (0x100d << 16) | 0x8086,
+ i82540em = (0x100E << 16) | 0x8086,
+ i82540eplp = (0x101E << 16) | 0x8086,
+ i82545em = (0x100F << 16) | 0x8086,
+ i82545gmc = (0x1026 << 16) | 0x8086,
+ i82547ei = (0x1019 << 16) | 0x8086,
+ i82547gi = (0x1075 << 16) | 0x8086,
+ i82541ei = (0x1013 << 16) | 0x8086,
+ i82541gi = (0x1076 << 16) | 0x8086,
+ i82541gi2 = (0x1077 << 16) | 0x8086,
+ i82541pi = (0x107c << 16) | 0x8086,
+ i82546gb = (0x1079 << 16) | 0x8086,
+ i82546eb = (0x1010 << 16) | 0x8086,
};
-enum {
- Ctrl = 0x00000000, /* Device Control */
- Ctrldup = 0x00000004, /* Device Control Duplicate */
- Status = 0x00000008, /* Device Status */
- Eecd = 0x00000010, /* EEPROM/Flash Control/Data */
- Ctrlext = 0x00000018, /* Extended Device Control */
- Mdic = 0x00000020, /* MDI Control */
- Fcal = 0x00000028, /* Flow Control Address Low */
- Fcah = 0x0000002C, /* Flow Control Address High */
- Fct = 0x00000030, /* Flow Control Type */
- Icr = 0x000000C0, /* Interrupt Cause Read */
- Ics = 0x000000C8, /* Interrupt Cause Set */
- Ims = 0x000000D0, /* Interrupt Mask Set/Read */
- Imc = 0x000000D8, /* Interrupt mask Clear */
- Rctl = 0x00000100, /* Receive Control */
- Fcttv = 0x00000170, /* Flow Control Transmit Timer Value */
- Txcw = 0x00000178, /* Transmit Configuration Word */
- Rxcw = 0x00000180, /* Receive Configuration Word */
- /* on the oldest cards (8254[23]), the Mta register is at 0x200 */
- Tctl = 0x00000400, /* Transmit Control */
- Tipg = 0x00000410, /* Transmit IPG */
- Tbt = 0x00000448, /* Transmit Burst Timer */
- Ait = 0x00000458, /* Adaptive IFS Throttle */
- Fcrtl = 0x00002160, /* Flow Control RX Threshold Low */
- Fcrth = 0x00002168, /* Flow Control Rx Threshold High */
- Rdfh = 0x00002410, /* Receive data fifo head */
- Rdft = 0x00002418, /* Receive data fifo tail */
- Rdfhs = 0x00002420, /* Receive data fifo head saved */
- Rdfts = 0x00002428, /* Receive data fifo tail saved */
- Rdfpc = 0x00002430, /* Receive data fifo packet count */
- Rdbal = 0x00002800, /* Rd Base Address Low */
- Rdbah = 0x00002804, /* Rd Base Address High */
- Rdlen = 0x00002808, /* Receive Descriptor Length */
- Rdh = 0x00002810, /* Receive Descriptor Head */
- Rdt = 0x00002818, /* Receive Descriptor Tail */
- Rdtr = 0x00002820, /* Receive Descriptor Timer Ring */
- Rxdctl = 0x00002828, /* Receive Descriptor Control */
- Radv = 0x0000282C, /* Receive Interrupt Absolute Delay Timer */
- Txdmac = 0x00003000, /* Transfer DMA Control */
- Ett = 0x00003008, /* Early Transmit Control */
- Tdfh = 0x00003410, /* Transmit data fifo head */
- Tdft = 0x00003418, /* Transmit data fifo tail */
- Tdfhs = 0x00003420, /* Transmit data Fifo Head saved */
- Tdfts = 0x00003428, /* Transmit data fifo tail saved */
- Tdfpc = 0x00003430, /* Trasnmit data Fifo packet count */
- Tdbal = 0x00003800, /* Td Base Address Low */
- Tdbah = 0x00003804, /* Td Base Address High */
- Tdlen = 0x00003808, /* Transmit Descriptor Length */
- Tdh = 0x00003810, /* Transmit Descriptor Head */
- Tdt = 0x00003818, /* Transmit Descriptor Tail */
- Tidv = 0x00003820, /* Transmit Interrupt Delay Value */
- Txdctl = 0x00003828, /* Transmit Descriptor Control */
- Tadv = 0x0000382C, /* Transmit Interrupt Absolute Delay Timer */
+enum { Ctrl = 0x00000000, /* Device Control */
+ Ctrldup = 0x00000004, /* Device Control Duplicate */
+ Status = 0x00000008, /* Device Status */
+ Eecd = 0x00000010, /* EEPROM/Flash Control/Data */
+ Ctrlext = 0x00000018, /* Extended Device Control */
+ Mdic = 0x00000020, /* MDI Control */
+ Fcal = 0x00000028, /* Flow Control Address Low */
+ Fcah = 0x0000002C, /* Flow Control Address High */
+ Fct = 0x00000030, /* Flow Control Type */
+ Icr = 0x000000C0, /* Interrupt Cause Read */
+ Ics = 0x000000C8, /* Interrupt Cause Set */
+ Ims = 0x000000D0, /* Interrupt Mask Set/Read */
+ Imc = 0x000000D8, /* Interrupt mask Clear */
+ Rctl = 0x00000100, /* Receive Control */
+ Fcttv = 0x00000170, /* Flow Control Transmit Timer Value */
+ Txcw = 0x00000178, /* Transmit Configuration Word */
+ Rxcw = 0x00000180, /* Receive Configuration Word */
+ /* on the oldest cards (8254[23]), the Mta register is at 0x200 */
+ Tctl = 0x00000400, /* Transmit Control */
+ Tipg = 0x00000410, /* Transmit IPG */
+ Tbt = 0x00000448, /* Transmit Burst Timer */
+ Ait = 0x00000458, /* Adaptive IFS Throttle */
+ Fcrtl = 0x00002160, /* Flow Control RX Threshold Low */
+ Fcrth = 0x00002168, /* Flow Control Rx Threshold High */
+ Rdfh = 0x00002410, /* Receive data fifo head */
+ Rdft = 0x00002418, /* Receive data fifo tail */
+ Rdfhs = 0x00002420, /* Receive data fifo head saved */
+ Rdfts = 0x00002428, /* Receive data fifo tail saved */
+ Rdfpc = 0x00002430, /* Receive data fifo packet count */
+ Rdbal = 0x00002800, /* Rd Base Address Low */
+ Rdbah = 0x00002804, /* Rd Base Address High */
+ Rdlen = 0x00002808, /* Receive Descriptor Length */
+ Rdh = 0x00002810, /* Receive Descriptor Head */
+ Rdt = 0x00002818, /* Receive Descriptor Tail */
+ Rdtr = 0x00002820, /* Receive Descriptor Timer Ring */
+ Rxdctl = 0x00002828, /* Receive Descriptor Control */
+ Radv = 0x0000282C, /* Receive Interrupt Absolute Delay Timer */
+ Txdmac = 0x00003000, /* Transfer DMA Control */
+ Ett = 0x00003008, /* Early Transmit Control */
+ Tdfh = 0x00003410, /* Transmit data fifo head */
+ Tdft = 0x00003418, /* Transmit data fifo tail */
+ Tdfhs = 0x00003420, /* Transmit data Fifo Head saved */
+ Tdfts = 0x00003428, /* Transmit data fifo tail saved */
+ Tdfpc = 0x00003430, /* Trasnmit data Fifo packet count */
+ Tdbal = 0x00003800, /* Td Base Address Low */
+ Tdbah = 0x00003804, /* Td Base Address High */
+ Tdlen = 0x00003808, /* Transmit Descriptor Length */
+ Tdh = 0x00003810, /* Transmit Descriptor Head */
+ Tdt = 0x00003818, /* Transmit Descriptor Tail */
+ Tidv = 0x00003820, /* Transmit Interrupt Delay Value */
+ Txdctl = 0x00003828, /* Transmit Descriptor Control */
+ Tadv = 0x0000382C, /* Transmit Interrupt Absolute Delay Timer */
- Statistics = 0x00004000, /* Start of Statistics Area */
- Gorcl = 0x88/4, /* Good Octets Received Count */
- Gotcl = 0x90/4, /* Good Octets Transmitted Count */
- Torl = 0xC0/4, /* Total Octets Received */
- Totl = 0xC8/4, /* Total Octets Transmitted */
- Nstatistics = 64,
+ Statistics = 0x00004000, /* Start of Statistics Area */
+ Gorcl = 0x88 / 4, /* Good Octets Received Count */
+ Gotcl = 0x90 / 4, /* Good Octets Transmitted Count */
+ Torl = 0xC0 / 4, /* Total Octets Received */
+ Totl = 0xC8 / 4, /* Total Octets Transmitted */
+ Nstatistics = 64,
- Rxcsum = 0x00005000, /* Receive Checksum Control */
- Mta = 0x00005200, /* Multicast Table Array */
- Ral = 0x00005400, /* Receive Address Low */
- Rah = 0x00005404, /* Receive Address High */
- Manc = 0x00005820, /* Management Control */
+ Rxcsum = 0x00005000, /* Receive Checksum Control */
+ Mta = 0x00005200, /* Multicast Table Array */
+ Ral = 0x00005400, /* Receive Address Low */
+ Rah = 0x00005404, /* Receive Address High */
+ Manc = 0x00005820, /* Management Control */
};
-enum { /* Ctrl */
- Bem = 0x00000002, /* Big Endian Mode */
- Prior = 0x00000004, /* Priority on the PCI bus */
- Lrst = 0x00000008, /* Link Reset */
- Asde = 0x00000020, /* Auto-Speed Detection Enable */
- Slu = 0x00000040, /* Set Link Up */
- Ilos = 0x00000080, /* Invert Loss of Signal (LOS) */
- SspeedMASK = 0x00000300, /* Speed Selection */
- SspeedSHIFT = 8,
- Sspeed10 = 0x00000000, /* 10Mb/s */
- Sspeed100 = 0x00000100, /* 100Mb/s */
- Sspeed1000 = 0x00000200, /* 1000Mb/s */
- Frcspd = 0x00000800, /* Force Speed */
- Frcdplx = 0x00001000, /* Force Duplex */
- SwdpinsloMASK = 0x003C0000, /* Software Defined Pins - lo nibble */
- SwdpinsloSHIFT = 18,
- SwdpioloMASK = 0x03C00000, /* Software Defined Pins - I or O */
- SwdpioloSHIFT = 22,
- Devrst = 0x04000000, /* Device Reset */
- Rfce = 0x08000000, /* Receive Flow Control Enable */
- Tfce = 0x10000000, /* Transmit Flow Control Enable */
- Vme = 0x40000000, /* VLAN Mode Enable */
+enum { /* Ctrl */
+ Bem = 0x00000002, /* Big Endian Mode */
+ Prior = 0x00000004, /* Priority on the PCI bus */
+ Lrst = 0x00000008, /* Link Reset */
+ Asde = 0x00000020, /* Auto-Speed Detection Enable */
+ Slu = 0x00000040, /* Set Link Up */
+ Ilos = 0x00000080, /* Invert Loss of Signal (LOS) */
+ SspeedMASK = 0x00000300, /* Speed Selection */
+ SspeedSHIFT = 8,
+ Sspeed10 = 0x00000000, /* 10Mb/s */
+ Sspeed100 = 0x00000100, /* 100Mb/s */
+ Sspeed1000 = 0x00000200, /* 1000Mb/s */
+ Frcspd = 0x00000800, /* Force Speed */
+ Frcdplx = 0x00001000, /* Force Duplex */
+ SwdpinsloMASK = 0x003C0000, /* Software Defined Pins - lo nibble */
+ SwdpinsloSHIFT = 18,
+ SwdpioloMASK = 0x03C00000, /* Software Defined Pins - I or O */
+ SwdpioloSHIFT = 22,
+ Devrst = 0x04000000, /* Device Reset */
+ Rfce = 0x08000000, /* Receive Flow Control Enable */
+ Tfce = 0x10000000, /* Transmit Flow Control Enable */
+ Vme = 0x40000000, /* VLAN Mode Enable */
};
/*
* can't find Tckok nor Rbcok in any Intel docs,
* but even 82543gc docs define Lanid.
*/
-enum { /* Status */
- Lu = 0x00000002, /* Link Up */
- Lanid = 0x0000000C, /* mask for Lan ID. (function id) */
-// Tckok = 0x00000004, /* Transmit clock is running */
-// Rbcok = 0x00000008, /* Receive clock is running */
- Txoff = 0x00000010, /* Transmission Paused */
- Tbimode = 0x00000020, /* TBI Mode Indication */
- LspeedMASK = 0x000000C0, /* Link Speed Setting */
- LspeedSHIFT = 6,
- Lspeed10 = 0x00000000, /* 10Mb/s */
- Lspeed100 = 0x00000040, /* 100Mb/s */
- Lspeed1000 = 0x00000080, /* 1000Mb/s */
- Mtxckok = 0x00000400, /* MTX clock is running */
- Pci66 = 0x00000800, /* PCI Bus speed indication */
- Bus64 = 0x00001000, /* PCI Bus width indication */
- Pcixmode = 0x00002000, /* PCI-X mode */
- PcixspeedMASK = 0x0000C000, /* PCI-X bus speed */
- PcixspeedSHIFT = 14,
- Pcix66 = 0x00000000, /* 50-66MHz */
- Pcix100 = 0x00004000, /* 66-100MHz */
- Pcix133 = 0x00008000, /* 100-133MHz */
+enum { /* Status */
+ Lu = 0x00000002, /* Link Up */
+ Lanid = 0x0000000C, /* mask for Lan ID. (function id) */
+ // Tckok = 0x00000004, /* Transmit clock is running */
+ // Rbcok = 0x00000008, /* Receive clock is running */
+ Txoff = 0x00000010, /* Transmission Paused */
+ Tbimode = 0x00000020, /* TBI Mode Indication */
+ LspeedMASK = 0x000000C0, /* Link Speed Setting */
+ LspeedSHIFT = 6,
+ Lspeed10 = 0x00000000, /* 10Mb/s */
+ Lspeed100 = 0x00000040, /* 100Mb/s */
+ Lspeed1000 = 0x00000080, /* 1000Mb/s */
+ Mtxckok = 0x00000400, /* MTX clock is running */
+ Pci66 = 0x00000800, /* PCI Bus speed indication */
+ Bus64 = 0x00001000, /* PCI Bus width indication */
+ Pcixmode = 0x00002000, /* PCI-X mode */
+ PcixspeedMASK = 0x0000C000, /* PCI-X bus speed */
+ PcixspeedSHIFT = 14,
+ Pcix66 = 0x00000000, /* 50-66MHz */
+ Pcix100 = 0x00004000, /* 66-100MHz */
+ Pcix133 = 0x00008000, /* 100-133MHz */
};
-enum { /* Ctrl and Status */
- Fd = 0x00000001, /* Full-Duplex */
- AsdvMASK = 0x00000300,
- AsdvSHIFT = 8,
- Asdv10 = 0x00000000, /* 10Mb/s */
- Asdv100 = 0x00000100, /* 100Mb/s */
- Asdv1000 = 0x00000200, /* 1000Mb/s */
+enum { /* Ctrl and Status */
+ Fd = 0x00000001, /* Full-Duplex */
+ AsdvMASK = 0x00000300,
+ AsdvSHIFT = 8,
+ Asdv10 = 0x00000000, /* 10Mb/s */
+ Asdv100 = 0x00000100, /* 100Mb/s */
+ Asdv1000 = 0x00000200, /* 1000Mb/s */
};
-enum { /* Eecd */
- Sk = 0x00000001, /* Clock input to the EEPROM */
- Cs = 0x00000002, /* Chip Select */
- Di = 0x00000004, /* Data Input to the EEPROM */
- Do = 0x00000008, /* Data Output from the EEPROM */
- Areq = 0x00000040, /* EEPROM Access Request */
- Agnt = 0x00000080, /* EEPROM Access Grant */
- Eepresent = 0x00000100, /* EEPROM Present */
- Eesz256 = 0x00000200, /* EEPROM is 256 words not 64 */
- Eeszaddr = 0x00000400, /* EEPROM size for 8254[17] */
- Spi = 0x00002000, /* EEPROM is SPI not Microwire */
+enum { /* Eecd */
+ Sk = 0x00000001, /* Clock input to the EEPROM */
+ Cs = 0x00000002, /* Chip Select */
+ Di = 0x00000004, /* Data Input to the EEPROM */
+ Do = 0x00000008, /* Data Output from the EEPROM */
+ Areq = 0x00000040, /* EEPROM Access Request */
+ Agnt = 0x00000080, /* EEPROM Access Grant */
+ Eepresent = 0x00000100, /* EEPROM Present */
+ Eesz256 = 0x00000200, /* EEPROM is 256 words not 64 */
+ Eeszaddr = 0x00000400, /* EEPROM size for 8254[17] */
+ Spi = 0x00002000, /* EEPROM is SPI not Microwire */
};
-enum { /* Ctrlext */
- Gpien = 0x0000000F, /* General Purpose Interrupt Enables */
- SwdpinshiMASK = 0x000000F0, /* Software Defined Pins - hi nibble */
- SwdpinshiSHIFT = 4,
- SwdpiohiMASK = 0x00000F00, /* Software Defined Pins - I or O */
- SwdpiohiSHIFT = 8,
- Asdchk = 0x00001000, /* ASD Check */
- Eerst = 0x00002000, /* EEPROM Reset */
- Ips = 0x00004000, /* Invert Power State */
- Spdbyps = 0x00008000, /* Speed Select Bypass */
+enum { /* Ctrlext */
+ Gpien = 0x0000000F, /* General Purpose Interrupt Enables */
+ SwdpinshiMASK = 0x000000F0, /* Software Defined Pins - hi nibble */
+ SwdpinshiSHIFT = 4,
+ SwdpiohiMASK = 0x00000F00, /* Software Defined Pins - I or O */
+ SwdpiohiSHIFT = 8,
+ Asdchk = 0x00001000, /* ASD Check */
+ Eerst = 0x00002000, /* EEPROM Reset */
+ Ips = 0x00004000, /* Invert Power State */
+ Spdbyps = 0x00008000, /* Speed Select Bypass */
};
-enum { /* EEPROM content offsets */
- Ea = 0x00, /* Ethernet Address */
- Cf = 0x03, /* Compatibility Field */
- Pba = 0x08, /* Printed Board Assembly number */
- Icw1 = 0x0A, /* Initialization Control Word 1 */
- Sid = 0x0B, /* Subsystem ID */
- Svid = 0x0C, /* Subsystem Vendor ID */
- Did = 0x0D, /* Device ID */
- Vid = 0x0E, /* Vendor ID */
- Icw2 = 0x0F, /* Initialization Control Word 2 */
+enum { /* EEPROM content offsets */
+ Ea = 0x00, /* Ethernet Address */
+ Cf = 0x03, /* Compatibility Field */
+ Pba = 0x08, /* Printed Board Assembly number */
+ Icw1 = 0x0A, /* Initialization Control Word 1 */
+ Sid = 0x0B, /* Subsystem ID */
+ Svid = 0x0C, /* Subsystem Vendor ID */
+ Did = 0x0D, /* Device ID */
+ Vid = 0x0E, /* Vendor ID */
+ Icw2 = 0x0F, /* Initialization Control Word 2 */
};
-enum { /* Mdic */
- MDIdMASK = 0x0000FFFF, /* Data */
- MDIdSHIFT = 0,
- MDIrMASK = 0x001F0000, /* PHY Register Address */
- MDIrSHIFT = 16,
- MDIpMASK = 0x03E00000, /* PHY Address */
- MDIpSHIFT = 21,
- MDIwop = 0x04000000, /* Write Operation */
- MDIrop = 0x08000000, /* Read Operation */
- MDIready = 0x10000000, /* End of Transaction */
- MDIie = 0x20000000, /* Interrupt Enable */
- MDIe = 0x40000000, /* Error */
+enum { /* Mdic */
+ MDIdMASK = 0x0000FFFF, /* Data */
+ MDIdSHIFT = 0,
+ MDIrMASK = 0x001F0000, /* PHY Register Address */
+ MDIrSHIFT = 16,
+ MDIpMASK = 0x03E00000, /* PHY Address */
+ MDIpSHIFT = 21,
+ MDIwop = 0x04000000, /* Write Operation */
+ MDIrop = 0x08000000, /* Read Operation */
+ MDIready = 0x10000000, /* End of Transaction */
+ MDIie = 0x20000000, /* Interrupt Enable */
+ MDIe = 0x40000000, /* Error */
};
-enum { /* Icr, Ics, Ims, Imc */
- Txdw = 0x00000001, /* Transmit Descriptor Written Back */
- Txqe = 0x00000002, /* Transmit Queue Empty */
- Lsc = 0x00000004, /* Link Status Change */
- Rxseq = 0x00000008, /* Receive Sequence Error */
- Rxdmt0 = 0x00000010, /* Rd Minimum Threshold Reached */
- Rxo = 0x00000040, /* Receiver Overrun */
- Rxt0 = 0x00000080, /* Receiver Timer Interrupt */
- Mdac = 0x00000200, /* MDIO Access Completed */
- Rxcfg = 0x00000400, /* Receiving /C/ ordered sets */
- Gpi0 = 0x00000800, /* General Purpose Interrupts */
- Gpi1 = 0x00001000,
- Gpi2 = 0x00002000,
- Gpi3 = 0x00004000,
+enum { /* Icr, Ics, Ims, Imc */
+ Txdw = 0x00000001, /* Transmit Descriptor Written Back */
+ Txqe = 0x00000002, /* Transmit Queue Empty */
+ Lsc = 0x00000004, /* Link Status Change */
+ Rxseq = 0x00000008, /* Receive Sequence Error */
+ Rxdmt0 = 0x00000010, /* Rd Minimum Threshold Reached */
+ Rxo = 0x00000040, /* Receiver Overrun */
+ Rxt0 = 0x00000080, /* Receiver Timer Interrupt */
+ Mdac = 0x00000200, /* MDIO Access Completed */
+ Rxcfg = 0x00000400, /* Receiving /C/ ordered sets */
+ Gpi0 = 0x00000800, /* General Purpose Interrupts */
+ Gpi1 = 0x00001000,
+ Gpi2 = 0x00002000,
+ Gpi3 = 0x00004000,
};
/*
@@ -268,267 +267,265 @@
* These definitions work for the Intel PRO/1000 T Server Adapter.
* The direction pin bits are read from the EEPROM.
*/
-enum {
- Mdd = ((1<<2)<<SwdpinsloSHIFT), /* data */
- Mddo = ((1<<2)<<SwdpioloSHIFT), /* pin direction */
- Mdc = ((1<<3)<<SwdpinsloSHIFT), /* clock */
- Mdco = ((1<<3)<<SwdpioloSHIFT), /* pin direction */
- Mdr = ((1<<0)<<SwdpinshiSHIFT), /* reset */
- Mdro = ((1<<0)<<SwdpiohiSHIFT), /* pin direction */
+enum { Mdd = ((1 << 2) << SwdpinsloSHIFT), /* data */
+ Mddo = ((1 << 2) << SwdpioloSHIFT), /* pin direction */
+ Mdc = ((1 << 3) << SwdpinsloSHIFT), /* clock */
+ Mdco = ((1 << 3) << SwdpioloSHIFT), /* pin direction */
+ Mdr = ((1 << 0) << SwdpinshiSHIFT), /* reset */
+ Mdro = ((1 << 0) << SwdpiohiSHIFT), /* pin direction */
};
-enum { /* Txcw */
- TxcwFd = 0x00000020, /* Full Duplex */
- TxcwHd = 0x00000040, /* Half Duplex */
- TxcwPauseMASK = 0x00000180, /* Pause */
- TxcwPauseSHIFT = 7,
- TxcwPs = (1<<TxcwPauseSHIFT), /* Pause Supported */
- TxcwAs = (2<<TxcwPauseSHIFT), /* Asymmetric FC desired */
- TxcwRfiMASK = 0x00003000, /* Remote Fault Indication */
- TxcwRfiSHIFT = 12,
- TxcwNpr = 0x00008000, /* Next Page Request */
- TxcwConfig = 0x40000000, /* Transmit COnfig Control */
- TxcwAne = 0x80000000, /* Auto-Negotiation Enable */
+enum { /* Txcw */
+ TxcwFd = 0x00000020, /* Full Duplex */
+ TxcwHd = 0x00000040, /* Half Duplex */
+ TxcwPauseMASK = 0x00000180, /* Pause */
+ TxcwPauseSHIFT = 7,
+ TxcwPs = (1 << TxcwPauseSHIFT), /* Pause Supported */
+ TxcwAs = (2 << TxcwPauseSHIFT), /* Asymmetric FC desired */
+ TxcwRfiMASK = 0x00003000, /* Remote Fault Indication */
+ TxcwRfiSHIFT = 12,
+ TxcwNpr = 0x00008000, /* Next Page Request */
+ TxcwConfig = 0x40000000, /* Transmit COnfig Control */
+ TxcwAne = 0x80000000, /* Auto-Negotiation Enable */
};
-enum { /* Rxcw */
- Rxword = 0x0000FFFF, /* Data from auto-negotiation process */
- Rxnocarrier = 0x04000000, /* Carrier Sense indication */
- Rxinvalid = 0x08000000, /* Invalid Symbol during configuration */
- Rxchange = 0x10000000, /* Change to the Rxword indication */
- Rxconfig = 0x20000000, /* /C/ order set reception indication */
- Rxsync = 0x40000000, /* Lost bit synchronization indication */
- Anc = 0x80000000, /* Auto Negotiation Complete */
+enum { /* Rxcw */
+ Rxword = 0x0000FFFF, /* Data from auto-negotiation process */
+ Rxnocarrier = 0x04000000, /* Carrier Sense indication */
+ Rxinvalid = 0x08000000, /* Invalid Symbol during configuration */
+ Rxchange = 0x10000000, /* Change to the Rxword indication */
+ Rxconfig = 0x20000000, /* /C/ order set reception indication */
+ Rxsync = 0x40000000, /* Lost bit synchronization indication */
+ Anc = 0x80000000, /* Auto Negotiation Complete */
};
-enum { /* Rctl */
- Rrst = 0x00000001, /* Receiver Software Reset */
- Ren = 0x00000002, /* Receiver Enable */
- Sbp = 0x00000004, /* Store Bad Packets */
- Upe = 0x00000008, /* Unicast Promiscuous Enable */
- Mpe = 0x00000010, /* Multicast Promiscuous Enable */
- Lpe = 0x00000020, /* Long Packet Reception Enable */
- LbmMASK = 0x000000C0, /* Loopback Mode */
- LbmOFF = 0x00000000, /* No Loopback */
- LbmTBI = 0x00000040, /* TBI Loopback */
- LbmMII = 0x00000080, /* GMII/MII Loopback */
- LbmXCVR = 0x000000C0, /* Transceiver Loopback */
- RdtmsMASK = 0x00000300, /* Rd Minimum Threshold Size */
- RdtmsHALF = 0x00000000, /* Threshold is 1/2 Rdlen */
- RdtmsQUARTER = 0x00000100, /* Threshold is 1/4 Rdlen */
- RdtmsEIGHTH = 0x00000200, /* Threshold is 1/8 Rdlen */
- MoMASK = 0x00003000, /* Multicast Offset */
- Mo47b36 = 0x00000000, /* bits [47:36] of received address */
- Mo46b35 = 0x00001000, /* bits [46:35] of received address */
- Mo45b34 = 0x00002000, /* bits [45:34] of received address */
- Mo43b32 = 0x00003000, /* bits [43:32] of received address */
- Bam = 0x00008000, /* Broadcast Accept Mode */
- BsizeMASK = 0x00030000, /* Receive Buffer Size */
- Bsize2048 = 0x00000000, /* Bsex = 0 */
- Bsize1024 = 0x00010000, /* Bsex = 0 */
- Bsize512 = 0x00020000, /* Bsex = 0 */
- Bsize256 = 0x00030000, /* Bsex = 0 */
- Bsize16384 = 0x00010000, /* Bsex = 1 */
- Vfe = 0x00040000, /* VLAN Filter Enable */
- Cfien = 0x00080000, /* Canonical Form Indicator Enable */
- Cfi = 0x00100000, /* Canonical Form Indicator value */
- Dpf = 0x00400000, /* Discard Pause Frames */
- Pmcf = 0x00800000, /* Pass MAC Control Frames */
- Bsex = 0x02000000, /* Buffer Size Extension */
- Secrc = 0x04000000, /* Strip CRC from incoming packet */
+enum { /* Rctl */
+ Rrst = 0x00000001, /* Receiver Software Reset */
+ Ren = 0x00000002, /* Receiver Enable */
+ Sbp = 0x00000004, /* Store Bad Packets */
+ Upe = 0x00000008, /* Unicast Promiscuous Enable */
+ Mpe = 0x00000010, /* Multicast Promiscuous Enable */
+ Lpe = 0x00000020, /* Long Packet Reception Enable */
+ LbmMASK = 0x000000C0, /* Loopback Mode */
+ LbmOFF = 0x00000000, /* No Loopback */
+ LbmTBI = 0x00000040, /* TBI Loopback */
+ LbmMII = 0x00000080, /* GMII/MII Loopback */
+ LbmXCVR = 0x000000C0, /* Transceiver Loopback */
+ RdtmsMASK = 0x00000300, /* Rd Minimum Threshold Size */
+ RdtmsHALF = 0x00000000, /* Threshold is 1/2 Rdlen */
+ RdtmsQUARTER = 0x00000100, /* Threshold is 1/4 Rdlen */
+ RdtmsEIGHTH = 0x00000200, /* Threshold is 1/8 Rdlen */
+ MoMASK = 0x00003000, /* Multicast Offset */
+ Mo47b36 = 0x00000000, /* bits [47:36] of received address */
+ Mo46b35 = 0x00001000, /* bits [46:35] of received address */
+ Mo45b34 = 0x00002000, /* bits [45:34] of received address */
+ Mo43b32 = 0x00003000, /* bits [43:32] of received address */
+ Bam = 0x00008000, /* Broadcast Accept Mode */
+ BsizeMASK = 0x00030000, /* Receive Buffer Size */
+ Bsize2048 = 0x00000000, /* Bsex = 0 */
+ Bsize1024 = 0x00010000, /* Bsex = 0 */
+ Bsize512 = 0x00020000, /* Bsex = 0 */
+ Bsize256 = 0x00030000, /* Bsex = 0 */
+ Bsize16384 = 0x00010000, /* Bsex = 1 */
+ Vfe = 0x00040000, /* VLAN Filter Enable */
+ Cfien = 0x00080000, /* Canonical Form Indicator Enable */
+ Cfi = 0x00100000, /* Canonical Form Indicator value */
+ Dpf = 0x00400000, /* Discard Pause Frames */
+ Pmcf = 0x00800000, /* Pass MAC Control Frames */
+ Bsex = 0x02000000, /* Buffer Size Extension */
+ Secrc = 0x04000000, /* Strip CRC from incoming packet */
};
-enum { /* Tctl */
- Trst = 0x00000001, /* Transmitter Software Reset */
- Ten = 0x00000002, /* Transmit Enable */
- Psp = 0x00000008, /* Pad Short Packets */
- CtMASK = 0x00000FF0, /* Collision Threshold */
- CtSHIFT = 4,
- ColdMASK = 0x003FF000, /* Collision Distance */
- ColdSHIFT = 12,
- Swxoff = 0x00400000, /* Sofware XOFF Transmission */
- Pbe = 0x00800000, /* Packet Burst Enable */
- Rtlc = 0x01000000, /* Re-transmit on Late Collision */
- Nrtu = 0x02000000, /* No Re-transmit on Underrrun */
+enum { /* Tctl */
+ Trst = 0x00000001, /* Transmitter Software Reset */
+ Ten = 0x00000002, /* Transmit Enable */
+ Psp = 0x00000008, /* Pad Short Packets */
+ CtMASK = 0x00000FF0, /* Collision Threshold */
+ CtSHIFT = 4,
+ ColdMASK = 0x003FF000, /* Collision Distance */
+ ColdSHIFT = 12,
+ Swxoff = 0x00400000, /* Sofware XOFF Transmission */
+ Pbe = 0x00800000, /* Packet Burst Enable */
+ Rtlc = 0x01000000, /* Re-transmit on Late Collision */
+ Nrtu = 0x02000000, /* No Re-transmit on Underrrun */
};
-enum { /* [RT]xdctl */
- PthreshMASK = 0x0000003F, /* Prefetch Threshold */
- PthreshSHIFT = 0,
- HthreshMASK = 0x00003F00, /* Host Threshold */
- HthreshSHIFT = 8,
- WthreshMASK = 0x003F0000, /* Writeback Threshold */
- WthreshSHIFT = 16,
- Gran = 0x01000000, /* Granularity */
- LthreshMASK = 0xFE000000, /* Low Threshold */
- LthreshSHIFT = 25,
+enum { /* [RT]xdctl */
+ PthreshMASK = 0x0000003F, /* Prefetch Threshold */
+ PthreshSHIFT = 0,
+ HthreshMASK = 0x00003F00, /* Host Threshold */
+ HthreshSHIFT = 8,
+ WthreshMASK = 0x003F0000, /* Writeback Threshold */
+ WthreshSHIFT = 16,
+ Gran = 0x01000000, /* Granularity */
+ LthreshMASK = 0xFE000000, /* Low Threshold */
+ LthreshSHIFT = 25,
};
-enum { /* Rxcsum */
- PcssMASK = 0x000000FF, /* Packet Checksum Start */
- PcssSHIFT = 0,
- Ipofl = 0x00000100, /* IP Checksum Off-load Enable */
- Tuofl = 0x00000200, /* TCP/UDP Checksum Off-load Enable */
+enum { /* Rxcsum */
+ PcssMASK = 0x000000FF, /* Packet Checksum Start */
+ PcssSHIFT = 0,
+ Ipofl = 0x00000100, /* IP Checksum Off-load Enable */
+ Tuofl = 0x00000200, /* TCP/UDP Checksum Off-load Enable */
};
-enum { /* Manc */
- Arpen = 0x00002000, /* Enable ARP Request Filtering */
+enum { /* Manc */
+ Arpen = 0x00002000, /* Enable ARP Request Filtering */
};
-enum { /* Receive Delay Timer Ring */
- DelayMASK = 0x0000FFFF, /* delay timer in 1.024nS increments */
- DelaySHIFT = 0,
- Fpd = 0x80000000, /* Flush partial Descriptor Block */
+enum { /* Receive Delay Timer Ring */
+ DelayMASK = 0x0000FFFF, /* delay timer in 1.024nS increments */
+ DelaySHIFT = 0,
+ Fpd = 0x80000000, /* Flush partial Descriptor Block */
};
-typedef struct Rd { /* Receive Descriptor */
- unsigned int addr[2];
- uint16_t length;
- uint16_t checksum;
- uint8_t status;
- uint8_t errors;
- uint16_t special;
+typedef struct Rd { /* Receive Descriptor */
+ unsigned int addr[2];
+ uint16_t length;
+ uint16_t checksum;
+ uint8_t status;
+ uint8_t errors;
+ uint16_t special;
} Rd;
-enum { /* Rd status */
- Rdd = 0x01, /* Descriptor Done */
- Reop = 0x02, /* End of Packet */
- Ixsm = 0x04, /* Ignore Checksum Indication */
- Vp = 0x08, /* Packet is 802.1Q (matched VET) */
- Tcpcs = 0x20, /* TCP Checksum Calculated on Packet */
- Ipcs = 0x40, /* IP Checksum Calculated on Packet */
- Pif = 0x80, /* Passed in-exact filter */
+enum { /* Rd status */
+ Rdd = 0x01, /* Descriptor Done */
+ Reop = 0x02, /* End of Packet */
+ Ixsm = 0x04, /* Ignore Checksum Indication */
+ Vp = 0x08, /* Packet is 802.1Q (matched VET) */
+ Tcpcs = 0x20, /* TCP Checksum Calculated on Packet */
+ Ipcs = 0x40, /* IP Checksum Calculated on Packet */
+ Pif = 0x80, /* Passed in-exact filter */
};
-enum { /* Rd errors */
- Ce = 0x01, /* CRC Error or Alignment Error */
- Se = 0x02, /* Symbol Error */
- Seq = 0x04, /* Sequence Error */
- Cxe = 0x10, /* Carrier Extension Error */
- Tcpe = 0x20, /* TCP/UDP Checksum Error */
- Ipe = 0x40, /* IP Checksum Error */
- Rxe = 0x80, /* RX Data Error */
+enum { /* Rd errors */
+ Ce = 0x01, /* CRC Error or Alignment Error */
+ Se = 0x02, /* Symbol Error */
+ Seq = 0x04, /* Sequence Error */
+ Cxe = 0x10, /* Carrier Extension Error */
+ Tcpe = 0x20, /* TCP/UDP Checksum Error */
+ Ipe = 0x40, /* IP Checksum Error */
+ Rxe = 0x80, /* RX Data Error */
};
typedef struct Td Td;
-struct Td { /* Transmit Descriptor */
+struct Td { /* Transmit Descriptor */
union {
- unsigned int addr[2]; /* Data */
- struct { /* Context */
- uint8_t ipcss;
- uint8_t ipcso;
- uint16_t ipcse;
- uint8_t tucss;
- uint8_t tucso;
- uint16_t tucse;
+ unsigned int addr[2]; /* Data */
+ struct { /* Context */
+ uint8_t ipcss;
+ uint8_t ipcso;
+ uint16_t ipcse;
+ uint8_t tucss;
+ uint8_t tucso;
+ uint16_t tucse;
};
};
- unsigned int control;
- unsigned int status;
+ unsigned int control;
+ unsigned int status;
};
-enum { /* Td control */
- LenMASK = 0x000FFFFF, /* Data/Packet Length Field */
- LenSHIFT = 0,
- DtypeCD = 0x00000000, /* Data Type 'Context Descriptor' */
- DtypeDD = 0x00100000, /* Data Type 'Data Descriptor' */
- PtypeTCP = 0x01000000, /* TCP/UDP Packet Type (CD) */
- Teop = 0x01000000, /* End of Packet (DD) */
- PtypeIP = 0x02000000, /* IP Packet Type (CD) */
- Ifcs = 0x02000000, /* Insert FCS (DD) */
- Tse = 0x04000000, /* TCP Segmentation Enable */
- Rs = 0x08000000, /* Report Status */
- Rps = 0x10000000, /* Report Status Sent */
- Dext = 0x20000000, /* Descriptor Extension */
- Vle = 0x40000000, /* VLAN Packet Enable */
- Ide = 0x80000000, /* Interrupt Delay Enable */
+enum { /* Td control */
+ LenMASK = 0x000FFFFF, /* Data/Packet Length Field */
+ LenSHIFT = 0,
+ DtypeCD = 0x00000000, /* Data Type 'Context Descriptor' */
+ DtypeDD = 0x00100000, /* Data Type 'Data Descriptor' */
+ PtypeTCP = 0x01000000, /* TCP/UDP Packet Type (CD) */
+ Teop = 0x01000000, /* End of Packet (DD) */
+ PtypeIP = 0x02000000, /* IP Packet Type (CD) */
+ Ifcs = 0x02000000, /* Insert FCS (DD) */
+ Tse = 0x04000000, /* TCP Segmentation Enable */
+ Rs = 0x08000000, /* Report Status */
+ Rps = 0x10000000, /* Report Status Sent */
+ Dext = 0x20000000, /* Descriptor Extension */
+ Vle = 0x40000000, /* VLAN Packet Enable */
+ Ide = 0x80000000, /* Interrupt Delay Enable */
};
-enum { /* Td status */
- Tdd = 0x00000001, /* Descriptor Done */
- Ec = 0x00000002, /* Excess Collisions */
- Lc = 0x00000004, /* Late Collision */
- Tu = 0x00000008, /* Transmit Underrun */
- Iixsm = 0x00000100, /* Insert IP Checksum */
- Itxsm = 0x00000200, /* Insert TCP/UDP Checksum */
- HdrlenMASK = 0x0000FF00, /* Header Length (Tse) */
- HdrlenSHIFT = 8,
- VlanMASK = 0x0FFF0000, /* VLAN Identifier */
- VlanSHIFT = 16,
- Tcfi = 0x10000000, /* Canonical Form Indicator */
- PriMASK = 0xE0000000, /* User Priority */
- PriSHIFT = 29,
- MssMASK = 0xFFFF0000, /* Maximum Segment Size (Tse) */
- MssSHIFT = 16,
+enum { /* Td status */
+ Tdd = 0x00000001, /* Descriptor Done */
+ Ec = 0x00000002, /* Excess Collisions */
+ Lc = 0x00000004, /* Late Collision */
+ Tu = 0x00000008, /* Transmit Underrun */
+ Iixsm = 0x00000100, /* Insert IP Checksum */
+ Itxsm = 0x00000200, /* Insert TCP/UDP Checksum */
+ HdrlenMASK = 0x0000FF00, /* Header Length (Tse) */
+ HdrlenSHIFT = 8,
+ VlanMASK = 0x0FFF0000, /* VLAN Identifier */
+ VlanSHIFT = 16,
+ Tcfi = 0x10000000, /* Canonical Form Indicator */
+ PriMASK = 0xE0000000, /* User Priority */
+ PriSHIFT = 29,
+ MssMASK = 0xFFFF0000, /* Maximum Segment Size (Tse) */
+ MssSHIFT = 16,
};
-enum {
- Nrd = 256, /* multiple of 8 */
- Ntd = 64, /* multiple of 8 */
- Rbsz = 2048,
+enum { Nrd = 256, /* multiple of 8 */
+ Ntd = 64, /* multiple of 8 */
+ Rbsz = 2048,
};
struct ctlr {
- int port;
+ int port;
struct pci_device *pci;
- struct ctlr* next;
- struct ether* edev;
- int active;
- int started;
- int id;
- int cls;
- uint16_t eeprom[0x40];
+ struct ctlr *next;
+ struct ether *edev;
+ int active;
+ int started;
+ int id;
+ int cls;
+ uint16_t eeprom[0x40];
- qlock_t alock; /* attach */
- void* alloc; /* receive/transmit descriptors */
- int nrd;
- int ntd;
+ qlock_t alock; /* attach */
+ void *alloc; /* receive/transmit descriptors */
+ int nrd;
+ int ntd;
- int* nic;
- spinlock_t imlock;
- int im; /* interrupt mask */
+ int *nic;
+ spinlock_t imlock;
+ int im; /* interrupt mask */
- struct mii* mii;
- struct rendez lrendez;
- int lim;
+ struct mii *mii;
+ struct rendez lrendez;
+ int lim;
- int link;
+ int link;
- qlock_t slock;
- unsigned int statistics[Nstatistics];
- unsigned int lsleep;
- unsigned int lintr;
- unsigned int rsleep;
- unsigned int rintr;
- unsigned int txdw;
- unsigned int tintr;
- unsigned int ixsm;
- unsigned int ipcs;
- unsigned int tcpcs;
+ qlock_t slock;
+ unsigned int statistics[Nstatistics];
+ unsigned int lsleep;
+ unsigned int lintr;
+ unsigned int rsleep;
+ unsigned int rintr;
+ unsigned int txdw;
+ unsigned int tintr;
+ unsigned int ixsm;
+ unsigned int ipcs;
+ unsigned int tcpcs;
- uint8_t ra[Eaddrlen]; /* receive address */
- uint32_t mta[128]; /* multicast table array */
+ uint8_t ra[Eaddrlen]; /* receive address */
+ uint32_t mta[128]; /* multicast table array */
- struct rendez rrendez;
- int rim;
- int rdfree;
- Rd* rdba; /* receive descriptor base address */
- struct block** rb; /* receive buffers */
- int rdh; /* receive descriptor head */
- int rdt; /* receive descriptor tail */
- int rdtr; /* receive delay timer ring value */
+ struct rendez rrendez;
+ int rim;
+ int rdfree;
+ Rd *rdba; /* receive descriptor base address */
+ struct block **rb; /* receive buffers */
+ int rdh; /* receive descriptor head */
+ int rdt; /* receive descriptor tail */
+ int rdtr; /* receive delay timer ring value */
- spinlock_t tlock;
- int tbusy;
- int tdfree;
- Td* tdba; /* transmit descriptor base address */
- struct block** tb; /* transmit buffers */
- int tdh; /* transmit descriptor head */
- int tdt; /* transmit descriptor tail */
+ spinlock_t tlock;
+ int tbusy;
+ int tdfree;
+ Td *tdba; /* transmit descriptor base address */
+ struct block **tb; /* transmit buffers */
+ int tdh; /* transmit descriptor head */
+ int tdt; /* transmit descriptor tail */
- int txcw;
- int fcrtl;
- int fcrth;
+ int txcw;
+ int fcrtl;
+ int fcrth;
};
static inline uint32_t csr32r(struct ctlr *c, uintptr_t reg)
@@ -541,91 +538,85 @@
write_mmreg32((uintptr_t)(c->nic + (reg / 4)), val);
}
-static struct ctlr* igbectlrhead;
-static struct ctlr* igbectlrtail;
+static struct ctlr *igbectlrhead;
+static struct ctlr *igbectlrtail;
-static char* statistics[Nstatistics] = {
- "CRC Error",
- "Alignment Error",
- "Symbol Error",
- "RX Error",
- "Missed Packets",
- "Single Collision",
- "Excessive Collisions",
- "Multiple Collision",
- "Late Collisions",
- NULL,
- "Collision",
- "Transmit Underrun",
- "Defer",
- "Transmit - No CRS",
- "Sequence Error",
- "Carrier Extension Error",
- "Receive Error Length",
- NULL,
- "XON Received",
- "XON Transmitted",
- "XOFF Received",
- "XOFF Transmitted",
- "FC Received Unsupported",
- "Packets Received (64 Bytes)",
- "Packets Received (65-127 Bytes)",
- "Packets Received (128-255 Bytes)",
- "Packets Received (256-511 Bytes)",
- "Packets Received (512-1023 Bytes)",
- "Packets Received (1024-1522 Bytes)",
- "Good Packets Received",
- "Broadcast Packets Received",
- "Multicast Packets Received",
- "Good Packets Transmitted",
- NULL,
- "Good Octets Received",
- NULL,
- "Good Octets Transmitted",
- NULL,
- NULL,
- NULL,
- "Receive No Buffers",
- "Receive Undersize",
- "Receive Fragment",
- "Receive Oversize",
- "Receive Jabber",
- NULL,
- NULL,
- NULL,
- "Total Octets Received",
- NULL,
- "Total Octets Transmitted",
- NULL,
- "Total Packets Received",
- "Total Packets Transmitted",
- "Packets Transmitted (64 Bytes)",
- "Packets Transmitted (65-127 Bytes)",
- "Packets Transmitted (128-255 Bytes)",
- "Packets Transmitted (256-511 Bytes)",
- "Packets Transmitted (512-1023 Bytes)",
- "Packets Transmitted (1024-1522 Bytes)",
- "Multicast Packets Transmitted",
- "Broadcast Packets Transmitted",
- "TCP Segmentation Context Transmitted",
- "TCP Segmentation Context Fail",
+static char *statistics[Nstatistics] = {
+ "CRC Error",
+ "Alignment Error",
+ "Symbol Error",
+ "RX Error",
+ "Missed Packets",
+ "Single Collision",
+ "Excessive Collisions",
+ "Multiple Collision",
+ "Late Collisions",
+ NULL,
+ "Collision",
+ "Transmit Underrun",
+ "Defer",
+ "Transmit - No CRS",
+ "Sequence Error",
+ "Carrier Extension Error",
+ "Receive Error Length",
+ NULL,
+ "XON Received",
+ "XON Transmitted",
+ "XOFF Received",
+ "XOFF Transmitted",
+ "FC Received Unsupported",
+ "Packets Received (64 Bytes)",
+ "Packets Received (65-127 Bytes)",
+ "Packets Received (128-255 Bytes)",
+ "Packets Received (256-511 Bytes)",
+ "Packets Received (512-1023 Bytes)",
+ "Packets Received (1024-1522 Bytes)",
+ "Good Packets Received",
+ "Broadcast Packets Received",
+ "Multicast Packets Received",
+ "Good Packets Transmitted",
+ NULL,
+ "Good Octets Received",
+ NULL,
+ "Good Octets Transmitted",
+ NULL,
+ NULL,
+ NULL,
+ "Receive No Buffers",
+ "Receive Undersize",
+ "Receive Fragment",
+ "Receive Oversize",
+ "Receive Jabber",
+ NULL,
+ NULL,
+ NULL,
+ "Total Octets Received",
+ NULL,
+ "Total Octets Transmitted",
+ NULL,
+ "Total Packets Received",
+ "Total Packets Transmitted",
+ "Packets Transmitted (64 Bytes)",
+ "Packets Transmitted (65-127 Bytes)",
+ "Packets Transmitted (128-255 Bytes)",
+ "Packets Transmitted (256-511 Bytes)",
+ "Packets Transmitted (512-1023 Bytes)",
+ "Packets Transmitted (1024-1522 Bytes)",
+ "Multicast Packets Transmitted",
+ "Broadcast Packets Transmitted",
+ "TCP Segmentation Context Transmitted",
+ "TCP Segmentation Context Fail",
};
static void igbe_print_rd(struct Rd *rd)
{
printk("Rd %p: stat 0x%02x, err 0x%02x, len 0x%04x, check 0x%04x, "
- "spec 0x%04x, addr[1] 0x%08x, addr[0] 0x%08x\n", rd,
- rd->status,
- rd->errors,
- rd->length,
- rd->checksum,
- rd->special,
- rd->addr[1],
- rd->addr[0]);
+ "spec 0x%04x, addr[1] 0x%08x, addr[0] 0x%08x\n",
+ rd, rd->status, rd->errors, rd->length, rd->checksum,
+ rd->special, rd->addr[1], rd->addr[0]);
}
-static long
-igbeifstat(struct ether* edev, void* a, long n, uint32_t offset)
+static long igbeifstat(struct ether *edev, void *a, long n, uint32_t offset)
{
struct ctlr *ctlr;
char *p, *s;
@@ -635,72 +626,75 @@
ctlr = edev->ctlr;
qlock(&ctlr->slock);
p = kzmalloc(READSTR, 0);
- if(p == NULL) {
+ if (p == NULL) {
qunlock(&ctlr->slock);
error(ENOMEM, ERROR_FIXME);
}
l = 0;
- for(i = 0; i < Nstatistics; i++){
- r = csr32r(ctlr, Statistics+i*4);
- if((s = statistics[i]) == NULL)
+ for (i = 0; i < Nstatistics; i++) {
+ r = csr32r(ctlr, Statistics + i * 4);
+ if ((s = statistics[i]) == NULL)
continue;
- switch(i){
+ switch (i) {
case Gorcl:
case Gotcl:
case Torl:
case Totl:
ruvl = r;
- ruvl += ((uint64_t)csr32r(ctlr, Statistics+(i+1)*4))<<32;
+ ruvl +=
+ ((uint64_t)csr32r(ctlr, Statistics + (i + 1) * 4))
+ << 32;
tuvl = ruvl;
tuvl += ctlr->statistics[i];
- tuvl += ((uint64_t)ctlr->statistics[i+1])<<32;
- if(tuvl == 0)
+ tuvl += ((uint64_t)ctlr->statistics[i + 1]) << 32;
+ if (tuvl == 0)
continue;
ctlr->statistics[i] = tuvl;
- ctlr->statistics[i+1] = tuvl>>32;
- l += snprintf(p+l, READSTR-l, "%s: %llud %llud\n",
- s, tuvl, ruvl);
+ ctlr->statistics[i + 1] = tuvl >> 32;
+ l += snprintf(p + l, READSTR - l, "%s: %llud %llud\n",
+ s, tuvl, ruvl);
i++;
break;
default:
ctlr->statistics[i] += r;
- if(ctlr->statistics[i] == 0)
+ if (ctlr->statistics[i] == 0)
continue;
- l += snprintf(p+l, READSTR-l, "%s: %ud %ud\n",
- s, ctlr->statistics[i], r);
+ l += snprintf(p + l, READSTR - l, "%s: %ud %ud\n", s,
+ ctlr->statistics[i], r);
break;
}
}
- l += snprintf(p+l, READSTR-l, "lintr: %ud %ud\n",
- ctlr->lintr, ctlr->lsleep);
- l += snprintf(p+l, READSTR-l, "rintr: %ud %ud\n",
- ctlr->rintr, ctlr->rsleep);
- l += snprintf(p+l, READSTR-l, "tintr: %ud %ud\n",
- ctlr->tintr, ctlr->txdw);
- l += snprintf(p+l, READSTR-l, "ixcs: %ud %ud %ud\n",
- ctlr->ixsm, ctlr->ipcs, ctlr->tcpcs);
- l += snprintf(p+l, READSTR-l, "rdtr: %ud\n", ctlr->rdtr);
- l += snprintf(p+l, READSTR-l, "Ctrlext: %08x\n", csr32r(ctlr, Ctrlext));
+ l += snprintf(p + l, READSTR - l, "lintr: %ud %ud\n", ctlr->lintr,
+ ctlr->lsleep);
+ l += snprintf(p + l, READSTR - l, "rintr: %ud %ud\n", ctlr->rintr,
+ ctlr->rsleep);
+ l += snprintf(p + l, READSTR - l, "tintr: %ud %ud\n", ctlr->tintr,
+ ctlr->txdw);
+ l += snprintf(p + l, READSTR - l, "ixcs: %ud %ud %ud\n", ctlr->ixsm,
+ ctlr->ipcs, ctlr->tcpcs);
+ l += snprintf(p + l, READSTR - l, "rdtr: %ud\n", ctlr->rdtr);
+ l += snprintf(p + l, READSTR - l, "Ctrlext: %08x\n",
+ csr32r(ctlr, Ctrlext));
- l += snprintf(p+l, READSTR-l, "eeprom:");
- for(i = 0; i < 0x40; i++){
- if(i && ((i & 0x07) == 0))
- l += snprintf(p+l, READSTR-l, "\n ");
- l += snprintf(p+l, READSTR-l, " %4.4uX", ctlr->eeprom[i]);
+ l += snprintf(p + l, READSTR - l, "eeprom:");
+ for (i = 0; i < 0x40; i++) {
+ if (i && ((i & 0x07) == 0))
+ l += snprintf(p + l, READSTR - l, "\n ");
+ l += snprintf(p + l, READSTR - l, " %4.4uX", ctlr->eeprom[i]);
}
- l += snprintf(p+l, READSTR-l, "\n");
+ l += snprintf(p + l, READSTR - l, "\n");
- if(ctlr->mii != NULL && ctlr->mii->curphy != NULL){
- l += snprintf(p+l, READSTR-l, "phy: ");
- for(i = 0; i < NMiiPhyr; i++){
- if(i && ((i & 0x07) == 0))
- l += snprintf(p+l, READSTR-l, "\n ");
+ if (ctlr->mii != NULL && ctlr->mii->curphy != NULL) {
+ l += snprintf(p + l, READSTR - l, "phy: ");
+ for (i = 0; i < NMiiPhyr; i++) {
+ if (i && ((i & 0x07) == 0))
+ l += snprintf(p + l, READSTR - l, "\n ");
r = miimir(ctlr->mii, i);
- l += snprintf(p+l, READSTR-l, " %4.4uX", r);
+ l += snprintf(p + l, READSTR - l, " %4.4uX", r);
}
- snprintf(p+l, READSTR-l, "\n");
+ snprintf(p + l, READSTR - l, "\n");
}
n = readstr(offset, a, n, p);
kfree(p);
@@ -709,16 +703,14 @@
return n;
}
-enum {
- CMrdtr,
+enum { CMrdtr,
};
static struct cmdtab igbectlmsg[] = {
- {CMrdtr, "rdtr", 2},
+ {CMrdtr, "rdtr", 2},
};
-static long
-igbectl(struct ether* edev, void* buf, long n)
+static long igbectl(struct ether *edev, void *buf, long n)
{
ERRSTACK(2);
int v;
@@ -727,23 +719,23 @@
struct cmdbuf *cb;
struct cmdtab *ct;
- if((ctlr = edev->ctlr) == NULL)
+ if ((ctlr = edev->ctlr) == NULL)
error(ENODEV, ERROR_FIXME);
cb = parsecmd(buf, n);
- if(waserror()){
+ if (waserror()) {
kfree(cb);
nexterror();
}
ct = lookupcmd(cb, igbectlmsg, ARRAY_SIZE(igbectlmsg));
- switch(ct->index){
+ switch (ct->index) {
case CMrdtr:
v = strtol(cb->f[1], &p, 0);
- if(v < 0 || p == cb->f[1] || v > 0xFFFF)
+ if (v < 0 || p == cb->f[1] || v > 0xFFFF)
error(EINVAL, ERROR_FIXME);
ctlr->rdtr = v;
- csr32w(ctlr, Rdtr, Fpd|v);
+ csr32w(ctlr, Rdtr, Fpd | v);
break;
}
kfree(cb);
@@ -752,8 +744,7 @@
return n;
}
-static void
-igbepromiscuous(void* arg, int on)
+static void igbepromiscuous(void *arg, int on)
{
int rctl;
struct ctlr *ctlr;
@@ -765,15 +756,14 @@
rctl = csr32r(ctlr, Rctl);
rctl &= ~MoMASK;
rctl |= Mo47b36;
- if(on)
- rctl |= Upe|Mpe;
+ if (on)
+ rctl |= Upe | Mpe;
else
- rctl &= ~(Upe|Mpe);
- csr32w(ctlr, Rctl, rctl|Mpe); /* temporarily keep Mpe on */
+ rctl &= ~(Upe | Mpe);
+ csr32w(ctlr, Rctl, rctl | Mpe); /* temporarily keep Mpe on */
}
-static void
-igbemulticast(void* arg, uint8_t* addr, int add)
+static void igbemulticast(void *arg, uint8_t *addr, int add)
{
int bit, x;
struct ctlr *ctlr;
@@ -782,8 +772,8 @@
edev = arg;
ctlr = edev->ctlr;
- x = addr[5]>>1;
- bit = ((addr[5] & 1)<<4)|(addr[4]>>4);
+ x = addr[5] >> 1;
+ bit = ((addr[5] & 1) << 4) | (addr[4] >> 4);
/*
* multiple ether addresses can hash to the same filter bit,
* so it's never safe to clear a filter bit.
@@ -791,16 +781,15 @@
* all the multicast addresses in use, clear all the filter bits,
* then set the ones corresponding to in-use addresses.
*/
- if(add)
- ctlr->mta[x] |= 1<<bit;
-// else
-// ctlr->mta[x] &= ~(1<<bit);
+ if (add)
+ ctlr->mta[x] |= 1 << bit;
+ // else
+ // ctlr->mta[x] &= ~(1<<bit);
- csr32w(ctlr, Mta+x*4, ctlr->mta[x]);
+ csr32w(ctlr, Mta + x * 4, ctlr->mta[x]);
}
-static void
-igbeim(struct ctlr* ctlr, int im)
+static void igbeim(struct ctlr *ctlr, int im)
{
ilock(&ctlr->imlock);
ctlr->im |= im;
@@ -808,14 +797,12 @@
iunlock(&ctlr->imlock);
}
-static int
-igbelim(void* ctlr)
+static int igbelim(void *ctlr)
{
- return ((struct ctlr*)ctlr)->lim != 0;
+ return ((struct ctlr *)ctlr)->lim != 0;
}
-static void
-igbelproc(void* arg)
+static void igbelproc(void *arg)
{
struct ctlr *ctlr;
struct ether *edev;
@@ -824,13 +811,15 @@
edev = arg;
ctlr = edev->ctlr;
- for(;;){
- /* plan9 originally had a busy loop here (just called continue). though
- * either you have the mii or you don't. i don't think it'll magically
- * show up later (it should have been initialized during pnp/pci, which
+ for (;;) {
+ /* plan9 originally had a busy loop here (just called continue).
+ * though either you have the mii or you don't. i don't think
+ * it'll magically show up later (it should have been
+ * initialized during pnp/pci, which
* is before attach, which is before lproc). -brho */
if (ctlr->mii == NULL || ctlr->mii->curphy == NULL) {
- printk("[kernel] igbelproc can't find a mii/curphy, aborting!\n");
+ printk("[kernel] igbelproc can't find a mii/curphy, "
+ "aborting!\n");
/* name alloc'd in attach */
kfree(per_cpu_info[core_id()].cur_kthread->name);
return;
@@ -843,26 +832,27 @@
*
* MiiPhy.speed, etc. should be in Mii.
*/
- if(miistatus(ctlr->mii) < 0)
- //continue; /* this comment out was plan9, not brho */
+ if (miistatus(ctlr->mii) < 0)
+ // continue; /* this comment out was plan9, not brho
+ // */
goto enable;
phy = ctlr->mii->curphy;
ctrl = csr32r(ctlr, Ctrl);
- switch(ctlr->id){
+ switch (ctlr->id) {
case i82543gc:
case i82544ei:
case i82544eif:
default:
- if(!(ctrl & Asde)){
- ctrl &= ~(SspeedMASK|Ilos|Fd);
- ctrl |= Frcdplx|Frcspd;
- if(phy->speed == 1000)
+ if (!(ctrl & Asde)) {
+ ctrl &= ~(SspeedMASK | Ilos | Fd);
+ ctrl |= Frcdplx | Frcspd;
+ if (phy->speed == 1000)
ctrl |= Sspeed1000;
- else if(phy->speed == 100)
+ else if (phy->speed == 100)
ctrl |= Sspeed100;
- if(phy->fd)
+ if (phy->fd)
ctrl |= Fd;
}
break;
@@ -881,22 +871,22 @@
*/
r = csr32r(ctlr, Tctl);
r &= ~ColdMASK;
- if(phy->fd)
- r |= 64<<ColdSHIFT;
+ if (phy->fd)
+ r |= 64 << ColdSHIFT;
else
- r |= 512<<ColdSHIFT;
+ r |= 512 << ColdSHIFT;
csr32w(ctlr, Tctl, r);
/*
* Flow control.
*/
- if(phy->rfc)
+ if (phy->rfc)
ctrl |= Rfce;
- if(phy->tfc)
+ if (phy->tfc)
ctrl |= Tfce;
csr32w(ctlr, Ctrl, ctrl);
-enable:
+ enable:
netif_carrier_on(edev);
ctlr->lim = 0;
igbeim(ctlr, Lsc);
@@ -906,14 +896,13 @@
}
}
-static void
-igbetxinit(struct ctlr* ctlr)
+static void igbetxinit(struct ctlr *ctlr)
{
int i, r;
struct block *bp;
- csr32w(ctlr, Tctl, (0x0F<<CtSHIFT)|Psp|(66<<ColdSHIFT));
- switch(ctlr->id){
+ csr32w(ctlr, Tctl, (0x0F << CtSHIFT) | Psp | (66 << ColdSHIFT));
+ switch (ctlr->id) {
default:
r = 6;
break;
@@ -936,19 +925,19 @@
r = 8;
break;
}
- csr32w(ctlr, Tipg, (6<<20)|(8<<10)|r);
+ csr32w(ctlr, Tipg, (6 << 20) | (8 << 10) | r);
csr32w(ctlr, Ait, 0);
csr32w(ctlr, Txdmac, 0);
csr32w(ctlr, Tdbal, paddr_low32(ctlr->tdba));
csr32w(ctlr, Tdbah, paddr_high32(ctlr->tdba));
- csr32w(ctlr, Tdlen, ctlr->ntd*sizeof(Td));
+ csr32w(ctlr, Tdlen, ctlr->ntd * sizeof(Td));
ctlr->tdh = PREV_RING(0, ctlr->ntd);
csr32w(ctlr, Tdh, 0);
ctlr->tdt = 0;
csr32w(ctlr, Tdt, 0);
- for(i = 0; i < ctlr->ntd; i++){
- if((bp = ctlr->tb[i]) != NULL){
+ for (i = 0; i < ctlr->ntd; i++) {
+ if ((bp = ctlr->tb[i]) != NULL) {
ctlr->tb[i] = NULL;
freeb(bp);
}
@@ -957,9 +946,9 @@
ctlr->tdfree = ctlr->ntd;
csr32w(ctlr, Tidv, 128);
- r = (4<<WthreshSHIFT)|(4<<HthreshSHIFT)|(8<<PthreshSHIFT);
+ r = (4 << WthreshSHIFT) | (4 << HthreshSHIFT) | (8 << PthreshSHIFT);
- switch(ctlr->id){
+ switch (ctlr->id) {
default:
break;
case i82540em:
@@ -974,7 +963,7 @@
case i82541pi:
r = csr32r(ctlr, Txdctl);
r &= ~WthreshMASK;
- r |= Gran|(4<<WthreshSHIFT);
+ r |= Gran | (4 << WthreshSHIFT);
csr32w(ctlr, Tadv, 64);
break;
@@ -987,8 +976,7 @@
csr32w(ctlr, Tctl, r);
}
-static void
-igbetransmit(struct ether* edev)
+static void igbetransmit(struct ether *edev)
{
Td *td;
struct block *bp;
@@ -1003,8 +991,8 @@
* Free any completed packets
*/
tdh = ctlr->tdh;
- while(NEXT_RING(tdh, ctlr->ntd) != csr32r(ctlr, Tdh)){
- if((bp = ctlr->tb[tdh]) != NULL){
+ while (NEXT_RING(tdh, ctlr->ntd) != csr32r(ctlr, Tdh)) {
+ if ((bp = ctlr->tb[tdh]) != NULL) {
ctlr->tb[tdh] = NULL;
freeb(bp);
}
@@ -1017,17 +1005,17 @@
* Try to fill the ring back up.
*/
tdt = ctlr->tdt;
- while(NEXT_RING(tdt, ctlr->ntd) != tdh){
- if((bp = qget(edev->oq)) == NULL)
+ while (NEXT_RING(tdt, ctlr->ntd) != tdh) {
+ if ((bp = qget(edev->oq)) == NULL)
break;
td = &ctlr->tdba[tdt];
td->addr[0] = paddr_low32(bp->rp);
td->addr[1] = paddr_high32(bp->rp);
- td->control = ((BLEN(bp) & LenMASK)<<LenSHIFT);
- td->control |= Dext|Ifcs|Teop|DtypeDD;
+ td->control = ((BLEN(bp) & LenMASK) << LenSHIFT);
+ td->control |= Dext | Ifcs | Teop | DtypeDD;
ctlr->tb[tdt] = bp;
tdt = NEXT_RING(tdt, ctlr->ntd);
- if(NEXT_RING(tdt, ctlr->ntd) == tdh){
+ if (NEXT_RING(tdt, ctlr->ntd) == tdh) {
td->control |= Rs;
ctlr->txdw++;
ctlr->tdt = tdt;
@@ -1042,29 +1030,30 @@
iunlock(&ctlr->tlock);
}
-static void
-igbereplenish(struct ctlr* ctlr)
+static void igbereplenish(struct ctlr *ctlr)
{
Rd *rd;
int rdt;
struct block *bp;
rdt = ctlr->rdt;
- while(NEXT_RING(rdt, ctlr->nrd) != ctlr->rdh){
+ while (NEXT_RING(rdt, ctlr->nrd) != ctlr->rdh) {
rd = &ctlr->rdba[rdt];
- if(ctlr->rb[rdt] == NULL){
+ if (ctlr->rb[rdt] == NULL) {
bp = block_alloc(Rbsz, MEM_ATOMIC);
- if(bp == NULL){
- /* needs to be a safe print for interrupt level */
- printk("#l%d: igbereplenish: no available buffers\n",
- ctlr->edev->ctlrno);
+ if (bp == NULL) {
+ /* needs to be a safe print for interrupt level
+ */
+ printk("#l%d: igbereplenish: no available "
+ "buffers\n",
+ ctlr->edev->ctlrno);
break;
}
ctlr->rb[rdt] = bp;
rd->addr[0] = paddr_low32(bp->rp);
rd->addr[1] = paddr_high32(bp->rp);
}
- wmb(); /* ensure prev rd writes come before status = 0. */
+ wmb(); /* ensure prev rd writes come before status = 0. */
rd->status = 0;
rdt = NEXT_RING(rdt, ctlr->nrd);
ctlr->rdfree++;
@@ -1073,33 +1062,32 @@
csr32w(ctlr, Rdt, rdt);
}
-static void
-igberxinit(struct ctlr* ctlr)
+static void igberxinit(struct ctlr *ctlr)
{
int i;
struct block *bp;
/* temporarily keep Mpe on */
- csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF|Mpe);
+ csr32w(ctlr, Rctl, Dpf | Bsize2048 | Bam | RdtmsHALF | Mpe);
csr32w(ctlr, Rdbal, paddr_low32(ctlr->rdba));
csr32w(ctlr, Rdbah, paddr_high32(ctlr->rdba));
- csr32w(ctlr, Rdlen, ctlr->nrd*sizeof(Rd));
+ csr32w(ctlr, Rdlen, ctlr->nrd * sizeof(Rd));
ctlr->rdh = 0;
csr32w(ctlr, Rdh, 0);
ctlr->rdt = 0;
csr32w(ctlr, Rdt, 0);
ctlr->rdtr = 0;
- csr32w(ctlr, Rdtr, Fpd|0);
+ csr32w(ctlr, Rdtr, Fpd | 0);
- for(i = 0; i < ctlr->nrd; i++){
- if((bp = ctlr->rb[i]) != NULL){
+ for (i = 0; i < ctlr->nrd; i++) {
+ if ((bp = ctlr->rb[i]) != NULL) {
ctlr->rb[i] = NULL;
freeb(bp);
}
}
igbereplenish(ctlr);
- switch(ctlr->id){
+ switch (ctlr->id) {
case i82540em:
case i82540eplp:
case i82541gi:
@@ -1113,22 +1101,20 @@
csr32w(ctlr, Radv, 64);
break;
}
- csr32w(ctlr, Rxdctl, (8<<WthreshSHIFT)|(8<<HthreshSHIFT)|4);
+ csr32w(ctlr, Rxdctl, (8 << WthreshSHIFT) | (8 << HthreshSHIFT) | 4);
/*
* Enable checksum offload.
*/
- csr32w(ctlr, Rxcsum, Tuofl|Ipofl|(ETHERHDRSIZE<<PcssSHIFT));
+ csr32w(ctlr, Rxcsum, Tuofl | Ipofl | (ETHERHDRSIZE << PcssSHIFT));
}
-static int
-igberim(void* ctlr)
+static int igberim(void *ctlr)
{
- return ((struct ctlr*)ctlr)->rim != 0;
+ return ((struct ctlr *)ctlr)->rim != 0;
}
-static void
-igberproc(void* arg)
+static void igberproc(void *arg)
{
Rd *rd;
struct block *bp;
@@ -1144,17 +1130,17 @@
r |= Ren;
csr32w(ctlr, Rctl, r);
- for(;;){
+ for (;;) {
ctlr->rim = 0;
- igbeim(ctlr, Rxt0|Rxo|Rxdmt0|Rxseq);
+ igbeim(ctlr, Rxt0 | Rxo | Rxdmt0 | Rxseq);
ctlr->rsleep++;
rendez_sleep(&ctlr->rrendez, igberim, ctlr);
rdh = ctlr->rdh;
- for(;;){
+ for (;;) {
rd = &ctlr->rdba[rdh];
- if(!(rd->status & Rdd))
+ if (!(rd->status & Rdd))
break;
/*
@@ -1164,14 +1150,14 @@
* an indication of whether the checksums were
* calculated and valid.
*/
- if((rd->status & Reop) && rd->errors == 0){
+ if ((rd->status & Reop) && rd->errors == 0) {
bp = ctlr->rb[rdh];
ctlr->rb[rdh] = NULL;
bp->wp += rd->length;
bp->next = NULL;
- if(!(rd->status & Ixsm)){
+ if (!(rd->status & Ixsm)) {
ctlr->ixsm++;
- if(rd->status & Ipcs){
+ if (rd->status & Ipcs) {
/*
* IP checksum calculated
* (and valid as errors == 0).
@@ -1179,37 +1165,37 @@
ctlr->ipcs++;
bp->flag |= Bipck;
}
- if(rd->status & Tcpcs){
+ if (rd->status & Tcpcs) {
/*
* TCP/UDP checksum calculated
* (and valid as errors == 0).
*/
ctlr->tcpcs++;
- bp->flag |= Btcpck|Budpck;
+ bp->flag |= Btcpck | Budpck;
}
bp->flag |= Bpktck;
}
etheriq(edev, bp, 1);
- }
- else if(ctlr->rb[rdh] != NULL){
+ } else if (ctlr->rb[rdh] != NULL) {
freeb(ctlr->rb[rdh]);
ctlr->rb[rdh] = NULL;
}
memset(rd, 0, sizeof(Rd));
- wmb(); /* make sure the zeroing happens before free (i think) */
+ /* make sure the zeroing happens before free (i think)
+ */
+ wmb();
ctlr->rdfree--;
rdh = NEXT_RING(rdh, ctlr->nrd);
}
ctlr->rdh = rdh;
- if(ctlr->rdfree < ctlr->nrd/2 || (ctlr->rim & Rxdmt0))
+ if (ctlr->rdfree < ctlr->nrd / 2 || (ctlr->rim & Rxdmt0))
igbereplenish(ctlr);
}
}
-static void
-igbeattach(struct ether* edev)
+static void igbeattach(struct ether *edev)
{
ERRSTACK(1);
struct block *bp;
@@ -1217,9 +1203,9 @@
char *name;
ctlr = edev->ctlr;
- ctlr->edev = edev; /* point back to Ether* */
+ ctlr->edev = edev; /* point back to Ether* */
qlock(&ctlr->alock);
- if(ctlr->alloc != NULL){ /* already allocated? */
+ if (ctlr->alloc != NULL) { /* already allocated? */
qunlock(&ctlr->alock);
return;
}
@@ -1227,7 +1213,7 @@
ctlr->tb = NULL;
ctlr->rb = NULL;
ctlr->alloc = NULL;
- if(waserror()){
+ if (waserror()) {
kfree(ctlr->tb);
ctlr->tb = NULL;
kfree(ctlr->rb);
@@ -1240,13 +1226,14 @@
ctlr->nrd = Nrd;
ctlr->ntd = Ntd;
- ctlr->alloc = kzmalloc(ctlr->nrd * sizeof(Rd) + ctlr->ntd * sizeof(Td) + 127, 0);
- if(ctlr->alloc == NULL) {
+ ctlr->alloc =
+ kzmalloc(ctlr->nrd * sizeof(Rd) + ctlr->ntd * sizeof(Td) + 127, 0);
+ if (ctlr->alloc == NULL) {
printd("igbe: can't allocate ctlr->alloc\n");
error(ENOMEM, ERROR_FIXME);
}
- ctlr->rdba = (Rd*)ROUNDUP((uintptr_t)ctlr->alloc, 128);
- ctlr->tdba = (Td*)(ctlr->rdba+ctlr->nrd);
+ ctlr->rdba = (Rd *)ROUNDUP((uintptr_t)ctlr->alloc, 128);
+ ctlr->tdba = (Td *)(ctlr->rdba + ctlr->nrd);
ctlr->rb = kzmalloc(ctlr->nrd * sizeof(struct block *), 0);
ctlr->tb = kzmalloc(ctlr->ntd * sizeof(struct block *), 0);
@@ -1284,20 +1271,20 @@
im = ctlr->im;
txdw = 0;
- while((icr = csr32r(ctlr, Icr) & ctlr->im) != 0){
- if(icr & Lsc){
+ while ((icr = csr32r(ctlr, Icr) & ctlr->im) != 0) {
+ if (icr & Lsc) {
im &= ~Lsc;
ctlr->lim = icr & Lsc;
rendez_wakeup(&ctlr->lrendez);
ctlr->lintr++;
}
- if(icr & (Rxt0|Rxo|Rxdmt0|Rxseq)){
- im &= ~(Rxt0|Rxo|Rxdmt0|Rxseq);
- ctlr->rim = icr & (Rxt0|Rxo|Rxdmt0|Rxseq);
+ if (icr & (Rxt0 | Rxo | Rxdmt0 | Rxseq)) {
+ im &= ~(Rxt0 | Rxo | Rxdmt0 | Rxseq);
+ ctlr->rim = icr & (Rxt0 | Rxo | Rxdmt0 | Rxseq);
rendez_wakeup(&ctlr->rrendez);
ctlr->rintr++;
}
- if(icr & Txdw){
+ if (icr & Txdw) {
im &= ~Txdw;
txdw++;
ctlr->tintr++;
@@ -1308,12 +1295,11 @@
csr32w(ctlr, Ims, im);
iunlock(&ctlr->imlock);
- if(txdw)
+ if (txdw)
igbetransmit(edev);
}
-static int
-i82543mdior(struct ctlr* ctlr, int n)
+static int i82543mdior(struct ctlr *ctlr, int n)
{
int ctrl, data, i, r;
@@ -1321,12 +1307,12 @@
* Read n bits from the Management Data I/O Interface.
*/
ctrl = csr32r(ctlr, Ctrl);
- r = (ctrl & ~Mddo)|Mdco;
+ r = (ctrl & ~Mddo) | Mdco;
data = 0;
- for(i = n-1; i >= 0; i--){
- if(csr32r(ctlr, Ctrl) & Mdd)
- data |= (1<<i);
- csr32w(ctlr, Ctrl, Mdc|r);
+ for (i = n - 1; i >= 0; i--) {
+ if (csr32r(ctlr, Ctrl) & Mdd)
+ data |= (1 << i);
+ csr32w(ctlr, Ctrl, Mdc | r);
csr32w(ctlr, Ctrl, r);
}
csr32w(ctlr, Ctrl, ctrl);
@@ -1334,8 +1320,7 @@
return data;
}
-static int
-i82543mdiow(struct ctlr* ctlr, int bits, int n)
+static int i82543mdiow(struct ctlr *ctlr, int bits, int n)
{
int ctrl, i, r;
@@ -1343,13 +1328,13 @@
* Write n bits to the Management Data I/O Interface.
*/
ctrl = csr32r(ctlr, Ctrl);
- r = Mdco|Mddo|ctrl;
- for(i = n-1; i >= 0; i--){
- if(bits & (1<<i))
+ r = Mdco | Mddo | ctrl;
+ for (i = n - 1; i >= 0; i--) {
+ if (bits & (1 << i))
r |= Mdd;
else
r &= ~Mdd;
- csr32w(ctlr, Ctrl, Mdc|r);
+ csr32w(ctlr, Ctrl, Mdc | r);
csr32w(ctlr, Ctrl, r);
}
csr32w(ctlr, Ctrl, ctrl);
@@ -1357,8 +1342,7 @@
return 0;
}
-static int
-i82543miimir(struct mii* mii, int pa, int ra)
+static int i82543miimir(struct mii *mii, int pa, int ra)
{
int data;
struct ctlr *ctlr;
@@ -1373,17 +1357,16 @@
* TA + 16 data bits.
*/
i82543mdiow(ctlr, 0xFFFFFFFF, 32);
- i82543mdiow(ctlr, 0x1800|(pa<<5)|ra, 14);
+ i82543mdiow(ctlr, 0x1800 | (pa << 5) | ra, 14);
data = i82543mdior(ctlr, 18);
- if(data & 0x10000)
+ if (data & 0x10000)
return -1;
return data & 0xFFFF;
}
-static int
-i82543miimiw(struct mii* mii, int pa, int ra, int data)
+static int i82543miimiw(struct mii *mii, int pa, int ra, int data)
{
struct ctlr *ctlr;
@@ -1398,36 +1381,35 @@
*/
i82543mdiow(ctlr, 0xFFFFFFFF, 32);
data &= 0xFFFF;
- data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16);
+ data |= (0x05 << (5 + 5 + 2 + 16)) | (pa << (5 + 2 + 16)) |
+ (ra << (2 + 16)) | (0x02 << 16);
i82543mdiow(ctlr, data, 32);
return 0;
}
-static int
-igbemiimir(struct mii* mii, int pa, int ra)
+static int igbemiimir(struct mii *mii, int pa, int ra)
{
struct ctlr *ctlr;
int mdic, timo;
ctlr = mii->ctlr;
- csr32w(ctlr, Mdic, MDIrop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT));
+ csr32w(ctlr, Mdic, MDIrop | (pa << MDIpSHIFT) | (ra << MDIrSHIFT));
mdic = 0;
- for(timo = 64; timo; timo--){
+ for (timo = 64; timo; timo--) {
mdic = csr32r(ctlr, Mdic);
- if(mdic & (MDIe|MDIready))
+ if (mdic & (MDIe | MDIready))
break;
udelay(1);
}
- if((mdic & (MDIe|MDIready)) == MDIready)
+ if ((mdic & (MDIe | MDIready)) == MDIready)
return mdic & 0xFFFF;
return -1;
}
-static int
-igbemiimiw(struct mii* mii, int pa, int ra, int data)
+static int igbemiimiw(struct mii *mii, int pa, int ra, int data)
{
struct ctlr *ctlr;
int mdic, timo;
@@ -1435,53 +1417,51 @@
ctlr = mii->ctlr;
data &= MDIdMASK;
- csr32w(ctlr, Mdic, MDIwop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT)|data);
+ csr32w(ctlr, Mdic,
+ MDIwop | (pa << MDIpSHIFT) | (ra << MDIrSHIFT) | data);
mdic = 0;
- for(timo = 64; timo; timo--){
+ for (timo = 64; timo; timo--) {
mdic = csr32r(ctlr, Mdic);
- if(mdic & (MDIe|MDIready))
+ if (mdic & (MDIe | MDIready))
break;
udelay(1);
}
- if((mdic & (MDIe|MDIready)) == MDIready)
+ if ((mdic & (MDIe | MDIready)) == MDIready)
return 0;
return -1;
}
-static int
-i82543miirw(struct mii* mii, int write, int pa, int ra, int data)
+static int i82543miirw(struct mii *mii, int write, int pa, int ra, int data)
{
- if(write)
+ if (write)
return i82543miimiw(mii, pa, ra, data);
return i82543miimir(mii, pa, ra);
}
-static int
-igbemiirw(struct mii* mii, int write, int pa, int ra, int data)
+static int igbemiirw(struct mii *mii, int write, int pa, int ra, int data)
{
- if(write)
+ if (write)
return igbemiimiw(mii, pa, ra, data);
return igbemiimir(mii, pa, ra);
}
-static int
-igbemii(struct ctlr* ctlr)
+static int igbemii(struct ctlr *ctlr)
{
int ctrl, p, r;
- int (*rw)(struct mii*, int unused_int, int, int, int);
+ int (*rw)(struct mii *, int unused_int, int, int, int);
r = csr32r(ctlr, Status);
- if(r & Tbimode)
+ if (r & Tbimode)
return -1;
ctrl = csr32r(ctlr, Ctrl);
ctrl |= Slu;
- switch(ctlr->id){
+ switch (ctlr->id) {
case i82543gc:
- ctrl |= Frcdplx|Frcspd;
+ ctrl |= Frcdplx | Frcspd;
csr32w(ctlr, Ctrl, ctrl);
/*
@@ -1491,18 +1471,18 @@
* so bail.
*/
r = csr32r(ctlr, Ctrlext);
- if(!(r & Mdro))
+ if (!(r & Mdro))
return -1;
csr32w(ctlr, Ctrlext, r);
- udelay(20*1000);
+ udelay(20 * 1000);
r = csr32r(ctlr, Ctrlext);
r &= ~Mdr;
csr32w(ctlr, Ctrlext, r);
- udelay(20*1000);
+ udelay(20 * 1000);
r = csr32r(ctlr, Ctrlext);
r |= Mdr;
csr32w(ctlr, Ctrlext, r);
- udelay(20*1000);
+ udelay(20 * 1000);
rw = i82543miirw;
break;
@@ -1521,7 +1501,7 @@
case i82545gmc:
case i82546gb:
case i82546eb:
- ctrl &= ~(Frcdplx|Frcspd);
+ ctrl &= ~(Frcdplx | Frcspd);
csr32w(ctlr, Ctrl, ctrl);
rw = igbemiirw;
break;
@@ -1540,7 +1520,7 @@
* Set appropriate values then reset the PHY to have
* changes noted.
*/
- switch(ctlr->id){
+ switch (ctlr->id) {
case i82547gi:
case i82541gi:
case i82541gi2:
@@ -1552,22 +1532,22 @@
break;
default:
r = miimir(ctlr->mii, 16);
- r |= 0x0800; /* assert CRS on Tx */
- r |= 0x0060; /* auto-crossover all speeds */
- r |= 0x0002; /* polarity reversal enabled */
+ r |= 0x0800; /* assert CRS on Tx */
+ r |= 0x0060; /* auto-crossover all speeds */
+ r |= 0x0002; /* polarity reversal enabled */
miimiw(ctlr->mii, 16, r);
r = miimir(ctlr->mii, 20);
- r |= 0x0070; /* +25MHz clock */
+ r |= 0x0070; /* +25MHz clock */
r &= ~0x0F00;
- r |= 0x0100; /* 1x downshift */
+ r |= 0x0100; /* 1x downshift */
miimiw(ctlr->mii, 20, r);
miireset(ctlr->mii);
p = 0;
- if(ctlr->txcw & TxcwPs)
+ if (ctlr->txcw & TxcwPs)
p |= AnaP;
- if(ctlr->txcw & TxcwAs)
+ if (ctlr->txcw & TxcwAs)
p |= AnaAP;
miiane(ctlr->mii, ~0, p, ~0);
break;
@@ -1575,8 +1555,7 @@
return 0;
}
-static int
-at93c46io(struct ctlr* ctlr, char* op, int data)
+static int at93c46io(struct ctlr *ctlr, char *op, int data)
{
char *lp, *p;
int i, loop, eecd, r;
@@ -1586,90 +1565,89 @@
r = 0;
loop = -1;
lp = NULL;
- for(p = op; *p != '\0'; p++){
- switch(*p){
+ for (p = op; *p != '\0'; p++) {
+ switch (*p) {
default:
return -1;
case ' ':
continue;
- case ':': /* start of loop */
- loop = strtol(p+1, &lp, 0)-1;
+ case ':': /* start of loop */
+ loop = strtol(p + 1, &lp, 0) - 1;
lp--;
- if(p == lp)
+ if (p == lp)
loop = 7;
p = lp;
continue;
- case ';': /* end of loop */
- if(lp == NULL)
+ case ';': /* end of loop */
+ if (lp == NULL)
return -1;
loop--;
- if(loop >= 0)
+ if (loop >= 0)
p = lp;
else
lp = NULL;
continue;
- case 'C': /* assert clock */
+ case 'C': /* assert clock */
eecd |= Sk;
break;
- case 'c': /* deassert clock */
+ case 'c': /* deassert clock */
eecd &= ~Sk;
break;
- case 'D': /* next bit in 'data' byte */
- if(loop < 0)
+ case 'D': /* next bit in 'data' byte */
+ if (loop < 0)
return -1;
- if(data & (1<<loop))
+ if (data & (1 << loop))
eecd |= Di;
else
eecd &= ~Di;
break;
- case 'O': /* collect data output */
+ case 'O': /* collect data output */
i = (csr32r(ctlr, Eecd) & Do) != 0;
- if(loop >= 0)
- r |= (i<<loop);
+ if (loop >= 0)
+ r |= (i << loop);
else
r = i;
continue;
- case 'I': /* assert data input */
+ case 'I': /* assert data input */
eecd |= Di;
break;
- case 'i': /* deassert data input */
+ case 'i': /* deassert data input */
eecd &= ~Di;
break;
- case 'S': /* enable chip select */
+ case 'S': /* enable chip select */
eecd |= Cs;
break;
- case 's': /* disable chip select */
+ case 's': /* disable chip select */
eecd &= ~Cs;
break;
}
csr32w(ctlr, Eecd, eecd);
udelay(50);
}
- if(loop >= 0)
+ if (loop >= 0)
return -1;
return r;
}
-static int
-at93c46r(struct ctlr* ctlr)
+static int at93c46r(struct ctlr *ctlr)
{
uint16_t sum;
char rop[20];
int addr, areq, bits, data, eecd, i;
eecd = csr32r(ctlr, Eecd);
- if(eecd & Spi){
+ if (eecd & Spi) {
printd("igbe: SPI EEPROM access not implemented\n");
return 0;
}
- if(eecd & (Eeszaddr|Eesz256))
+ if (eecd & (Eeszaddr | Eesz256))
bits = 8;
else
bits = 6;
sum = 0;
- switch(ctlr->id){
+ switch (ctlr->id) {
default:
areq = 0;
break;
@@ -1686,29 +1664,30 @@
case i82547ei:
case i82547gi:
areq = 1;
- csr32w(ctlr, Eecd, eecd|Areq);
- for(i = 0; i < 1000; i++){
- if((eecd = csr32r(ctlr, Eecd)) & Agnt)
+ csr32w(ctlr, Eecd, eecd | Areq);
+ for (i = 0; i < 1000; i++) {
+ if ((eecd = csr32r(ctlr, Eecd)) & Agnt)
break;
udelay(5);
}
- if(!(eecd & Agnt)){
+ if (!(eecd & Agnt)) {
printd("igbe: not granted EEPROM access\n");
goto release;
}
break;
}
- snprintf(rop, sizeof(rop), "S :%dDCc;", bits+3);
+ snprintf(rop, sizeof(rop), "S :%dDCc;", bits + 3);
- for(addr = 0; addr < 0x40; addr++){
+ for (addr = 0; addr < 0x40; addr++) {
/*
* Read a word at address 'addr' from the Atmel AT93C46
* 3-Wire Serial EEPROM or compatible. The EEPROM access is
* controlled by 4 bits in Eecd. See the AT93C46 datasheet
* for protocol details.
*/
- if(at93c46io(ctlr, rop, (0x06<<bits)|addr) != 0){
- printd("igbe: can't set EEPROM address 0x%2.2X\n", addr);
+ if (at93c46io(ctlr, rop, (0x06 << bits) | addr) != 0) {
+ printd("igbe: can't set EEPROM address 0x%2.2X\n",
+ addr);
goto release;
}
data = at93c46io(ctlr, ":16COc;", 0);
@@ -1718,13 +1697,12 @@
}
release:
- if(areq)
+ if (areq)
csr32w(ctlr, Eecd, eecd & ~Areq);
return sum;
}
-static int
-igbedetach(struct ctlr* ctlr)
+static int igbedetach(struct ctlr *ctlr)
{
int r, timeo;
@@ -1737,30 +1715,30 @@
csr32w(ctlr, Rctl, 0);
csr32w(ctlr, Tctl, 0);
- udelay(10*1000);
+ udelay(10 * 1000);
csr32w(ctlr, Ctrl, Devrst);
- udelay(1*1000);
- for(timeo = 0; timeo < 1000; timeo++){
- if(!(csr32r(ctlr, Ctrl) & Devrst))
+ udelay(1 * 1000);
+ for (timeo = 0; timeo < 1000; timeo++) {
+ if (!(csr32r(ctlr, Ctrl) & Devrst))
break;
- udelay(1*1000);
+ udelay(1 * 1000);
}
- if(csr32r(ctlr, Ctrl) & Devrst)
+ if (csr32r(ctlr, Ctrl) & Devrst)
return -1;
r = csr32r(ctlr, Ctrlext);
- csr32w(ctlr, Ctrlext, r|Eerst);
- udelay(1*1000);
+ csr32w(ctlr, Ctrlext, r | Eerst);
+ udelay(1 * 1000);
- for(timeo = 0; timeo < 1000; timeo++){
- if(!(csr32r(ctlr, Ctrlext) & Eerst))
+ for (timeo = 0; timeo < 1000; timeo++) {
+ if (!(csr32r(ctlr, Ctrlext) & Eerst))
break;
- udelay(1*1000);
+ udelay(1 * 1000);
}
- if(csr32r(ctlr, Ctrlext) & Eerst)
+ if (csr32r(ctlr, Ctrlext) & Eerst)
return -1;
- switch(ctlr->id){
+ switch (ctlr->id) {
default:
break;
case i82540em:
@@ -1780,37 +1758,35 @@
}
csr32w(ctlr, Imc, ~0);
- udelay(1*1000);
- for(timeo = 0; timeo < 1000; timeo++){
- if(!csr32r(ctlr, Icr))
+ udelay(1 * 1000);
+ for (timeo = 0; timeo < 1000; timeo++) {
+ if (!csr32r(ctlr, Icr))
break;
- udelay(1*1000);
+ udelay(1 * 1000);
}
- if(csr32r(ctlr, Icr))
+ if (csr32r(ctlr, Icr))
return -1;
return 0;
}
-static void
-igbeshutdown(struct ether* ether)
+static void igbeshutdown(struct ether *ether)
{
igbedetach(ether->ctlr);
}
-static int
-igbereset(struct ctlr* ctlr)
+static int igbereset(struct ctlr *ctlr)
{
int ctrl, i, pause, r, swdpio, txcw;
- if(igbedetach(ctlr))
+ if (igbedetach(ctlr))
return -1;
/*
* Read the EEPROM, validate the checksum
* then get the device back to a power-on state.
*/
- if((r = at93c46r(ctlr)) != 0xBABA){
+ if ((r = at93c46r(ctlr)) != 0xBABA) {
printd("igbe: bad EEPROM checksum - 0x%4.4uX\n", r);
return -1;
}
@@ -1822,27 +1798,28 @@
*/
if ((ctlr->id == i82546gb || ctlr->id == i82546eb) &&
(pci_config_addr(ctlr->pci->bus, ctlr->pci->dev, 0, 0) ==
- pci_config_addr(0, 1, 0, 0)))
- ctlr->eeprom[Ea+2] += 0x100; /* second interface */
- if(ctlr->id == i82541gi && ctlr->eeprom[Ea] == 0xFFFF)
+ pci_config_addr(0, 1, 0, 0)))
+ ctlr->eeprom[Ea + 2] += 0x100; /* second interface */
+ if (ctlr->id == i82541gi && ctlr->eeprom[Ea] == 0xFFFF)
ctlr->eeprom[Ea] = 0xD000;
- for(i = Ea; i < Eaddrlen/2; i++){
- ctlr->ra[2*i] = ctlr->eeprom[i];
- ctlr->ra[2*i+1] = ctlr->eeprom[i]>>8;
+ for (i = Ea; i < Eaddrlen / 2; i++) {
+ ctlr->ra[2 * i] = ctlr->eeprom[i];
+ ctlr->ra[2 * i + 1] = ctlr->eeprom[i] >> 8;
}
/* lan id seems to vary on 82543gc; don't use it */
if (ctlr->id != i82543gc) {
r = (csr32r(ctlr, Status) & Lanid) >> 2;
- ctlr->ra[5] += r; /* ea ctlr[1] = ea ctlr[0]+1 */
+ ctlr->ra[5] += r; /* ea ctlr[1] = ea ctlr[0]+1 */
}
- r = (ctlr->ra[3]<<24)|(ctlr->ra[2]<<16)|(ctlr->ra[1]<<8)|ctlr->ra[0];
+ r = (ctlr->ra[3] << 24) | (ctlr->ra[2] << 16) | (ctlr->ra[1] << 8) |
+ ctlr->ra[0];
csr32w(ctlr, Ral, r);
- r = 0x80000000|(ctlr->ra[5]<<8)|ctlr->ra[4];
+ r = 0x80000000 | (ctlr->ra[5] << 8) | ctlr->ra[4];
csr32w(ctlr, Rah, r);
- for(i = 1; i < 16; i++){
- csr32w(ctlr, Ral+i*8, 0);
- csr32w(ctlr, Rah+i*8, 0);
+ for (i = 1; i < 16; i++) {
+ csr32w(ctlr, Ral + i * 8, 0);
+ csr32w(ctlr, Rah + i * 8, 0);
}
/*
@@ -1850,8 +1827,8 @@
* It's a 4096 bit vector accessed as 128 32-bit registers.
*/
memset(ctlr->mta, 0, sizeof(ctlr->mta));
- for(i = 0; i < 128; i++)
- csr32w(ctlr, Mta+i*4, 0);
+ for (i = 0; i < 128; i++)
+ csr32w(ctlr, Mta + i * 4, 0);
/*
* Just in case the Eerst didn't load the defaults
@@ -1859,41 +1836,41 @@
*/
if (ctlr->id == i82543gc) {
txcw = csr32r(ctlr, Txcw);
- txcw &= ~(TxcwAne|TxcwPauseMASK|TxcwFd);
+ txcw &= ~(TxcwAne | TxcwPauseMASK | TxcwFd);
ctrl = csr32r(ctlr, Ctrl);
- ctrl &= ~(SwdpioloMASK|Frcspd|Ilos|Lrst|Fd);
+ ctrl &= ~(SwdpioloMASK | Frcspd | Ilos | Lrst | Fd);
- if(ctlr->eeprom[Icw1] & 0x0400){
+ if (ctlr->eeprom[Icw1] & 0x0400) {
ctrl |= Fd;
txcw |= TxcwFd;
}
- if(ctlr->eeprom[Icw1] & 0x0200)
+ if (ctlr->eeprom[Icw1] & 0x0200)
ctrl |= Lrst;
- if(ctlr->eeprom[Icw1] & 0x0010)
+ if (ctlr->eeprom[Icw1] & 0x0010)
ctrl |= Ilos;
- if(ctlr->eeprom[Icw1] & 0x0800)
+ if (ctlr->eeprom[Icw1] & 0x0800)
ctrl |= Frcspd;
- swdpio = (ctlr->eeprom[Icw1] & 0x01E0)>>5;
- ctrl |= swdpio<<SwdpioloSHIFT;
+ swdpio = (ctlr->eeprom[Icw1] & 0x01E0) >> 5;
+ ctrl |= swdpio << SwdpioloSHIFT;
csr32w(ctlr, Ctrl, ctrl);
ctrl = csr32r(ctlr, Ctrlext);
- ctrl &= ~(Ips|SwdpiohiMASK);
- swdpio = (ctlr->eeprom[Icw2] & 0x00F0)>>4;
- if(ctlr->eeprom[Icw1] & 0x1000)
+ ctrl &= ~(Ips | SwdpiohiMASK);
+ swdpio = (ctlr->eeprom[Icw2] & 0x00F0) >> 4;
+ if (ctlr->eeprom[Icw1] & 0x1000)
ctrl |= Ips;
- ctrl |= swdpio<<SwdpiohiSHIFT;
+ ctrl |= swdpio << SwdpiohiSHIFT;
csr32w(ctlr, Ctrlext, ctrl);
- if(ctlr->eeprom[Icw2] & 0x0800)
+ if (ctlr->eeprom[Icw2] & 0x0800)
txcw |= TxcwAne;
- pause = (ctlr->eeprom[Icw2] & 0x3000)>>12;
- txcw |= pause<<TxcwPauseSHIFT;
- switch(pause){
+ pause = (ctlr->eeprom[Icw2] & 0x3000) >> 12;
+ txcw |= pause << TxcwPauseSHIFT;
+ switch (pause) {
default:
ctlr->fcrtl = 0x00002000;
ctlr->fcrth = 0x00004000;
- txcw |= TxcwAs|TxcwPs;
+ txcw |= TxcwAs | TxcwPs;
break;
case 0:
ctlr->fcrtl = 0x00002000;
@@ -1909,7 +1886,6 @@
csr32w(ctlr, Txcw, txcw);
}
-
/*
* Flow control - values from the datasheet.
*/
@@ -1922,7 +1898,7 @@
csr32w(ctlr, Fcrth, ctlr->fcrth);
/* FYI, igbemii checks status right away too. */
- if(!(csr32r(ctlr, Status) & Tbimode) && igbemii(ctlr) < 0) {
+ if (!(csr32r(ctlr, Status) & Tbimode) && igbemii(ctlr) < 0) {
printk("igbemii failed! igbe failing to reset!\n");
return -1;
}
@@ -1930,8 +1906,7 @@
return 0;
}
-static void
-igbepci(void)
+static void igbepci(void)
{
int id;
struct pci_device *pcidev;
@@ -1939,8 +1914,9 @@
void *mem;
uintptr_t mmio_paddr;
- STAILQ_FOREACH(pcidev, &pci_devices, all_dev) {
- /* This checks that pcidev is a Network Controller for Ethernet */
+ STAILQ_FOREACH (pcidev, &pci_devices, all_dev) {
+ /* This checks that pcidev is a Network Controller for Ethernet
+ */
if (pcidev->class != 0x02 || pcidev->subclass != 0x00)
continue;
id = pcidev->dev_id << 16 | pcidev->ven_id;
@@ -1966,19 +1942,22 @@
break;
}
printk("igbe/e1000 driver found 0x%04x:%04x at %02x:%02x.%x\n",
- pcidev->ven_id, pcidev->dev_id,
- pcidev->bus, pcidev->dev, pcidev->func);
+ pcidev->ven_id, pcidev->dev_id, pcidev->bus, pcidev->dev,
+ pcidev->func);
- mmio_paddr = pcidev->bar[0].mmio_base32 ? pcidev->bar[0].mmio_base32 :
- pcidev->bar[0].mmio_base64;
- mem = (void*)vmap_pmem_nocache(mmio_paddr, pcidev->bar[0].mmio_sz);
- if(mem == NULL){
- printd("igbe: can't map %p\n", pcidev->bar[0].mmio_base32);
+ mmio_paddr = pcidev->bar[0].mmio_base32
+ ? pcidev->bar[0].mmio_base32
+ : pcidev->bar[0].mmio_base64;
+ mem = (void *)vmap_pmem_nocache(mmio_paddr,
+ pcidev->bar[0].mmio_sz);
+ if (mem == NULL) {
+ printd("igbe: can't map %p\n",
+ pcidev->bar[0].mmio_base32);
continue;
}
pci_set_cacheline_size(pcidev);
ctlr = kzmalloc(sizeof(struct ctlr), 0);
- if(ctlr == NULL) {
+ if (ctlr == NULL) {
vunmap_vmem((uintptr_t)mem, pcidev->bar[0].mmio_sz);
error(ENOMEM, ERROR_FIXME);
}
@@ -1988,22 +1967,23 @@
qlock_init(&ctlr->slock);
rendez_init(&ctlr->lrendez);
rendez_init(&ctlr->rrendez);
- /* port seems to be unused, and only used for some comparison with edev.
- * plan9 just used the top of the raw bar, regardless of the type. */
+ /* port seems to be unused, and only used for some comparison
+ * with edev. plan9 just used the top of the raw bar,
+ * regardless of the type. */
ctlr->port = pcidev->bar[0].raw_bar & ~0x0f;
ctlr->pci = pcidev;
ctlr->id = id;
ctlr->cls = pcidev_read8(pcidev, PCI_CLSZ_REG);
ctlr->nic = mem;
- if(igbereset(ctlr)){
+ if (igbereset(ctlr)) {
kfree(ctlr);
vunmap_vmem((uintptr_t)mem, pcidev->bar[0].mmio_sz);
continue;
}
pci_set_bus_master(pcidev);
- if(igbectlrhead != NULL)
+ if (igbectlrhead != NULL)
igbectlrtail->next = ctlr;
else
igbectlrhead = ctlr;
@@ -2011,8 +1991,7 @@
}
}
-static int
-igbepnp(struct ether* edev)
+static int igbepnp(struct ether *edev)
{
struct ctlr *ctlr;
@@ -2022,15 +2001,15 @@
* Any adapter matches if no edev->port is supplied,
* otherwise the ports must match.
*/
- for(ctlr = igbectlrhead; ctlr != NULL; ctlr = ctlr->next){
- if(ctlr->active)
+ for (ctlr = igbectlrhead; ctlr != NULL; ctlr = ctlr->next) {
+ if (ctlr->active)
continue;
- if(edev->port == 0 || edev->port == ctlr->port){
+ if (edev->port == 0 || edev->port == ctlr->port) {
ctlr->active = 1;
break;
}
}
- if(ctlr == NULL)
+ if (ctlr == NULL)
return -1;
edev->ctlr = ctlr;
@@ -2040,8 +2019,8 @@
edev->tbdf = pci_to_tbdf(ctlr->pci);
edev->mbps = 1000;
memmove(edev->ea, ctlr->ra, Eaddrlen);
- /* Jim or whoever have this turned on already. We might be capable of other
- * features. */
+ /* Jim or whoever have this turned on already. We might be capable of
+ * other features. */
edev->feat = NETF_RXCSUM;
/*
diff --git a/kern/drivers/net/ethermii.c b/kern/drivers/net/ethermii.c
index 9ed7667..6aa46ce 100644
--- a/kern/drivers/net/ethermii.c
+++ b/kern/drivers/net/ethermii.c
@@ -5,20 +5,20 @@
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file. */
-#include <slab.h>
+#include <assert.h>
+#include <cpio.h>
+#include <error.h>
#include <kmalloc.h>
#include <kref.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <error.h>
-#include <cpio.h>
#include <pmap.h>
+#include <slab.h>
#include <smp.h>
+#include <stdio.h>
+#include <string.h>
+
#include "ethermii.h"
-static int
-miiprobe(struct mii* mii, int mask)
+static int miiprobe(struct mii *mii, int mask)
{
struct miiphy *miiphy;
int bit, oui, phyno, r, rmask;
@@ -30,23 +30,23 @@
* the Mii information.
*/
rmask = 0;
- for(phyno = 0; phyno < NMiiPhy; phyno++){
- bit = 1<<phyno;
- if(!(mask & bit))
+ for (phyno = 0; phyno < NMiiPhy; phyno++) {
+ bit = 1 << phyno;
+ if (!(mask & bit))
continue;
- if(mii->mask & bit){
+ if (mii->mask & bit) {
rmask |= bit;
continue;
}
- if(mii->rw(mii, 0, phyno, Bmsr, 0) == -1)
+ if (mii->rw(mii, 0, phyno, Bmsr, 0) == -1)
continue;
- r = mii->rw(mii, 0, phyno, Phyidr1, 0)<<16;
+ r = mii->rw(mii, 0, phyno, Phyidr1, 0) << 16;
r |= mii->rw(mii, 0, phyno, Phyidr2, 0);
- oui = (r>>10) & 0xffff;
- if(oui == 0xffff || oui == 0)
+ oui = (r >> 10) & 0xffff;
+ if (oui == 0xffff || oui == 0)
continue;
- if((miiphy = kzmalloc(sizeof(struct miiphy), 0)) == NULL)
+ if ((miiphy = kzmalloc(sizeof(struct miiphy), 0)) == NULL)
continue;
miiphy->mii = mii;
@@ -59,7 +59,7 @@
miiphy->mscr = ~0;
mii->phy[phyno] = miiphy;
- if(mii->curphy == NULL)
+ if (mii->curphy == NULL)
mii->curphy = miiphy;
mii->mask |= bit;
mii->nphy++;
@@ -69,119 +69,114 @@
return rmask;
}
-int
-miimir(struct mii* mii, int r)
+int miimir(struct mii *mii, int r)
{
- if(mii == NULL || mii->ctlr == NULL || mii->curphy == NULL)
+ if (mii == NULL || mii->ctlr == NULL || mii->curphy == NULL)
return -1;
return mii->rw(mii, 0, mii->curphy->phyno, r, 0);
}
-int
-miimiw(struct mii* mii, int r, int data)
+int miimiw(struct mii *mii, int r, int data)
{
- if(mii == NULL || mii->ctlr == NULL || mii->curphy == NULL)
+ if (mii == NULL || mii->ctlr == NULL || mii->curphy == NULL)
return -1;
return mii->rw(mii, 1, mii->curphy->phyno, r, data);
}
-int
-miireset(struct mii* mii)
+int miireset(struct mii *mii)
{
int bmcr, timeo;
- if(mii == NULL || mii->ctlr == NULL || mii->curphy == NULL)
+ if (mii == NULL || mii->ctlr == NULL || mii->curphy == NULL)
return -1;
bmcr = mii->rw(mii, 0, mii->curphy->phyno, Bmcr, 0);
- mii->rw(mii, 1, mii->curphy->phyno, Bmcr, BmcrR|bmcr);
- for(timeo = 0; timeo < 1000; timeo++){
+ mii->rw(mii, 1, mii->curphy->phyno, Bmcr, BmcrR | bmcr);
+ for (timeo = 0; timeo < 1000; timeo++) {
bmcr = mii->rw(mii, 0, mii->curphy->phyno, Bmcr, 0);
- if(!(bmcr & BmcrR))
+ if (!(bmcr & BmcrR))
break;
udelay(1);
}
- if(bmcr & BmcrR)
+ if (bmcr & BmcrR)
return -1;
- if(bmcr & BmcrI)
+ if (bmcr & BmcrI)
mii->rw(mii, 1, mii->curphy->phyno, Bmcr, bmcr & ~BmcrI);
return 0;
}
-int
-miiane(struct mii* mii, int a, int p, int e)
+int miiane(struct mii *mii, int a, int p, int e)
{
int anar, bmsr, mscr, r, phyno;
- if(mii == NULL || mii->ctlr == NULL || mii->curphy == NULL)
+ if (mii == NULL || mii->ctlr == NULL || mii->curphy == NULL)
return -1;
phyno = mii->curphy->phyno;
mii->rw(mii, 1, phyno, Bmsr, 0);
bmsr = mii->rw(mii, 0, phyno, Bmsr, 0);
- if(!(bmsr & BmsrAna))
+ if (!(bmsr & BmsrAna))
return -1;
- if(a != ~0)
- anar = (AnaTXFD|AnaTXHD|Ana10FD|Ana10HD) & a;
- else if(mii->curphy->anar != ~0)
+ if (a != ~0)
+ anar = (AnaTXFD | AnaTXHD | Ana10FD | Ana10HD) & a;
+ else if (mii->curphy->anar != ~0)
anar = mii->curphy->anar;
- else{
+ else {
anar = mii->rw(mii, 0, phyno, Anar, 0);
- anar &= ~(AnaAP|AnaP|AnaT4|AnaTXFD|AnaTXHD|Ana10FD|Ana10HD);
- if(bmsr & Bmsr10THD)
+ anar &= ~(AnaAP | AnaP | AnaT4 | AnaTXFD | AnaTXHD | Ana10FD |
+ Ana10HD);
+ if (bmsr & Bmsr10THD)
anar |= Ana10HD;
- if(bmsr & Bmsr10TFD)
+ if (bmsr & Bmsr10TFD)
anar |= Ana10FD;
- if(bmsr & Bmsr100TXHD)
+ if (bmsr & Bmsr100TXHD)
anar |= AnaTXHD;
- if(bmsr & Bmsr100TXFD)
+ if (bmsr & Bmsr100TXFD)
anar |= AnaTXFD;
}
mii->curphy->anar = anar;
- if(p != ~0)
- anar |= (AnaAP|AnaP) & p;
- else if(mii->curphy->fc != ~0)
+ if (p != ~0)
+ anar |= (AnaAP | AnaP) & p;
+ else if (mii->curphy->fc != ~0)
anar |= mii->curphy->fc;
- mii->curphy->fc = (AnaAP|AnaP) & anar;
+ mii->curphy->fc = (AnaAP | AnaP) & anar;
- if(bmsr & BmsrEs){
+ if (bmsr & BmsrEs) {
mscr = mii->rw(mii, 0, phyno, Mscr, 0);
- mscr &= ~(Mscr1000TFD|Mscr1000THD);
- if(e != ~0)
- mscr |= (Mscr1000TFD|Mscr1000THD) & e;
- else if(mii->curphy->mscr != ~0)
+ mscr &= ~(Mscr1000TFD | Mscr1000THD);
+ if (e != ~0)
+ mscr |= (Mscr1000TFD | Mscr1000THD) & e;
+ else if (mii->curphy->mscr != ~0)
mscr = mii->curphy->mscr;
- else{
+ else {
r = mii->rw(mii, 0, phyno, Esr, 0);
- if(r & Esr1000THD)
+ if (r & Esr1000THD)
mscr |= Mscr1000THD;
- if(r & Esr1000TFD)
+ if (r & Esr1000TFD)
mscr |= Mscr1000TFD;
}
mii->curphy->mscr = mscr;
mii->rw(mii, 1, phyno, Mscr, mscr);
- }
- else
+ } else
mii->curphy->mscr = 0;
mii->rw(mii, 1, phyno, Anar, anar);
r = mii->rw(mii, 0, phyno, Bmcr, 0);
- if(!(r & BmcrR)){
- r |= BmcrAne|BmcrRan;
+ if (!(r & BmcrR)) {
+ r |= BmcrAne | BmcrRan;
mii->rw(mii, 1, phyno, Bmcr, r);
}
return 0;
}
-int
-miistatus(struct mii* mii)
+int miistatus(struct mii *mii)
{
struct miiphy *phy;
int anlpar, bmsr, p, r, phyno;
- if(mii == NULL || mii->ctlr == NULL || mii->curphy == NULL)
+ if (mii == NULL || mii->ctlr == NULL || mii->curphy == NULL)
return -1;
phy = mii->curphy;
phyno = phy->phyno;
@@ -191,53 +186,50 @@
* (Read status twice as the Ls bit is sticky).
*/
bmsr = mii->rw(mii, 0, phyno, Bmsr, 0);
- if(!(bmsr & (BmsrAnc|BmsrAna)))
+ if (!(bmsr & (BmsrAnc | BmsrAna)))
return -1;
bmsr = mii->rw(mii, 0, phyno, Bmsr, 0);
- if(!(bmsr & BmsrLs)){
+ if (!(bmsr & BmsrLs)) {
phy->link = 0;
return -1;
}
phy->speed = phy->fd = phy->rfc = phy->tfc = 0;
- if(phy->mscr){
+ if (phy->mscr) {
r = mii->rw(mii, 0, phyno, Mssr, 0);
- if((phy->mscr & Mscr1000TFD) && (r & Mssr1000TFD)){
+ if ((phy->mscr & Mscr1000TFD) && (r & Mssr1000TFD)) {
phy->speed = 1000;
phy->fd = 1;
- }
- else if((phy->mscr & Mscr1000THD) && (r & Mssr1000THD))
+ } else if ((phy->mscr & Mscr1000THD) && (r & Mssr1000THD))
phy->speed = 1000;
}
anlpar = mii->rw(mii, 0, phyno, Anlpar, 0);
- if(phy->speed == 0){
+ if (phy->speed == 0) {
r = phy->anar & anlpar;
- if(r & AnaTXFD){
+ if (r & AnaTXFD) {
phy->speed = 100;
phy->fd = 1;
- }
- else if(r & AnaTXHD)
+ } else if (r & AnaTXHD)
phy->speed = 100;
- else if(r & Ana10FD){
+ else if (r & Ana10FD) {
phy->speed = 10;
phy->fd = 1;
- }
- else if(r & Ana10HD)
+ } else if (r & Ana10HD)
phy->speed = 10;
}
- if(phy->speed == 0)
+ if (phy->speed == 0)
return -1;
- if(phy->fd){
+ if (phy->fd) {
p = phy->fc;
- r = anlpar & (AnaAP|AnaP);
- if(p == AnaAP && r == (AnaAP|AnaP))
+ r = anlpar & (AnaAP | AnaP);
+ if (p == AnaAP && r == (AnaAP | AnaP))
phy->tfc = 1;
- else if(p == (AnaAP|AnaP) && r == AnaAP)
+ else if (p == (AnaAP | AnaP) && r == AnaAP)
phy->rfc = 1;
- else if((p & AnaP) && (r & AnaP))
+ else if ((p & AnaP) && (r & AnaP))
phy->rfc = phy->tfc = 1;
}
@@ -246,17 +238,16 @@
return 0;
}
-char*
-miidumpphy(struct mii* mii, char* p, char* e)
+char *miidumpphy(struct mii *mii, char *p, char *e)
{
int i, r;
- if(mii == NULL || mii->curphy == NULL)
+ if (mii == NULL || mii->curphy == NULL)
return p;
p = seprintf(p, e, "phy: ");
- for(i = 0; i < NMiiPhyr; i++){
- if(i && ((i & 0x07) == 0))
+ for (i = 0; i < NMiiPhyr; i++) {
+ if (i && ((i & 0x07) == 0))
p = seprintf(p, e, "\n ");
r = mii->rw(mii, 0, mii->curphy->phyno, i, 0);
p = seprintf(p, e, " %4.4ux", r);
@@ -266,13 +257,12 @@
return p;
}
-void
-miidetach(struct mii* mii)
+void miidetach(struct mii *mii)
{
int i;
- for(i = 0; i < NMiiPhy; i++){
- if(mii->phy[i] == NULL)
+ for (i = 0; i < NMiiPhy; i++) {
+ if (mii->phy[i] == NULL)
continue;
kfree(mii);
mii->phy[i] = NULL;
@@ -280,17 +270,17 @@
kfree(mii);
}
-struct mii*
-miiattach(void* ctlr, int mask, int (*rw)(struct mii*, int unused_int, int, int, int))
+struct mii *miiattach(void *ctlr, int mask,
+ int (*rw)(struct mii *, int unused_int, int, int, int))
{
- struct mii* mii;
+ struct mii *mii;
- if((mii = kzmalloc(sizeof(struct mii), 0)) == NULL)
+ if ((mii = kzmalloc(sizeof(struct mii), 0)) == NULL)
return NULL;
mii->ctlr = ctlr;
mii->rw = rw;
- if(miiprobe(mii, mask) == 0){
+ if (miiprobe(mii, mask) == 0) {
kfree(mii);
mii = NULL;
}
diff --git a/kern/drivers/net/ethermii.h b/kern/drivers/net/ethermii.h
index f6f69f5..d88c953 100644
--- a/kern/drivers/net/ethermii.h
+++ b/kern/drivers/net/ethermii.h
@@ -121,4 +121,7 @@
int miistatus(struct mii *mii);
char *miidumpphy(struct mii *mii, char *p, char *e);
void miidetach(struct mii *mii);
-struct mii *miiattach(void *ctlr, int mask, int (*rw)(struct mii *, int unused_int, int unused2, int unused3, int unused4));
+struct mii *miiattach(void *ctlr, int mask, int (*rw)(struct mii *,
+ int unused_int,
+ int unused2, int unused3,
+ int unused4));
diff --git a/kern/drivers/net/mlx4/en_netdev.c b/kern/drivers/net/mlx4/en_netdev.c
index 0a9ac75..c4e3e36 100644
--- a/kern/drivers/net/mlx4/en_netdev.c
+++ b/kern/drivers/net/mlx4/en_netdev.c
@@ -105,10 +105,10 @@
int rxq_index;
struct mlx4_en_priv *priv;
- uint32_t flow_id; /* RFS infrastructure id */
+ uint32_t flow_id; /* RFS infrastructure id */
int id; /* mlx4_en driver id */
- uint64_t reg_id; /* Flow steering API id */
- uint8_t activated; /* Used to prevent expiry before filter
+ uint64_t reg_id; /* Flow steering API id */
+ uint8_t activated; /* Used to prevent expiry before filter
* is attached
*/
struct hlist_node filter_chain;
diff --git a/kern/drivers/net/mlx4/en_rx.c b/kern/drivers/net/mlx4/en_rx.c
index bd3b015..2ee592a 100644
--- a/kern/drivers/net/mlx4/en_rx.c
+++ b/kern/drivers/net/mlx4/en_rx.c
@@ -369,7 +369,8 @@
ring->log_stride = ffs(ring->stride) - 1;
ring->buf_size = ring->size * ring->stride + TXBB_SIZE;
- tmp = size * ROUNDUPPWR2(MLX4_EN_MAX_RX_FRAGS * sizeof(struct mlx4_en_rx_alloc));
+ tmp = size * ROUNDUPPWR2(MLX4_EN_MAX_RX_FRAGS *
+ sizeof(struct mlx4_en_rx_alloc));
ring->rx_info = vmalloc_node(tmp, node);
if (!ring->rx_info) {
ring->rx_info = vmalloc(tmp);
@@ -423,7 +424,8 @@
int i;
int ring_ind;
int err;
- int stride = ROUNDUPPWR2(sizeof(struct mlx4_en_rx_desc) + DS_SIZE * priv->num_frags);
+ int stride = ROUNDUPPWR2(sizeof(struct mlx4_en_rx_desc) +
+ DS_SIZE * priv->num_frags);
for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) {
ring = priv->rx_ring[ring_ind];
@@ -907,7 +909,8 @@
if (likely(dev->feat & NETIF_F_RXCSUM)) {
if (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_TCP |
MLX4_CQE_STATUS_UDP)) {
- if ((cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPOK)) &&
+ if ((cqe->status &
+ cpu_to_be16(MLX4_CQE_STATUS_IPOK)) &&
cqe->checksum == cpu_to_be16(0xffff)) {
ip_summed = CHECKSUM_UNNECESSARY;
ring->csum_ok++;
@@ -916,9 +919,11 @@
ring->csum_none++;
}
} else {
- if (priv->flags & MLX4_EN_FLAG_RX_CSUM_NON_TCP_UDP &&
- (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPV4 |
- MLX4_CQE_STATUS_IPV6))) {
+ if (priv->flags &
+ MLX4_EN_FLAG_RX_CSUM_NON_TCP_UDP &&
+ (cqe->status &
+ cpu_to_be16(MLX4_CQE_STATUS_IPV4 |
+ MLX4_CQE_STATUS_IPV6))) {
ip_summed = CHECKSUM_COMPLETE;
ring->csum_complete++;
} else {
diff --git a/kern/drivers/net/mlx4/en_tx.c b/kern/drivers/net/mlx4/en_tx.c
index 36db4ab..148fb6d 100644
--- a/kern/drivers/net/mlx4/en_tx.c
+++ b/kern/drivers/net/mlx4/en_tx.c
@@ -432,7 +432,8 @@
if (unlikely((cqe->owner_sr_opcode & MLX4_CQE_OPCODE_MASK) ==
MLX4_CQE_OPCODE_ERROR)) {
- struct mlx4_err_cqe *cqe_err = (struct mlx4_err_cqe *)cqe;
+ struct mlx4_err_cqe *cqe_err =
+ (struct mlx4_err_cqe *)cqe;
en_err(priv, "CQE error - vendor syndrome: 0x%x syndrome: 0x%x\n",
cqe_err->vendor_err_syndrome,
@@ -775,10 +776,11 @@
if (ebd->base && ebd->len > 0)
nr_frags++;
}
- /* Transport stack should always put the packet headers in the main body. */
+ /* Transport stack should always put the packet headers in the main
+ * body. */
assert(!(lso_header_size > BHLEN(block)));
- /* == means there is nothing in the block main body other than the headers.
- * in which case, we won't need an extra data_seg. */
+ /* == means there is nothing in the block main body other than the
+ * headers. in which case, we won't need an extra data_seg. */
is_linear = lso_header_size < BHLEN(block);
real_size = CTRL_SIZE + nr_frags * DS_SIZE;
@@ -873,8 +875,9 @@
/* Prepare ctrl segement apart opcode+ownership */
tx_desc->ctrl.srcrb_flags = priv->ctrl_flags;
if (likely(block->flag & BLOCK_TRANS_TX_CSUM)) {
- tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
- MLX4_WQE_CTRL_TCP_UDP_CSUM);
+ tx_desc->ctrl.srcrb_flags |=
+ cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
+ MLX4_WQE_CTRL_TCP_UDP_CSUM);
ring->tx_csum++;
}
@@ -885,7 +888,8 @@
* so that VFs and PF can communicate with each other
*/
ethh = (struct ethhdr *)block->rp;
- tx_desc->ctrl.srcrb_flags16[0] = get_unaligned((__be16 *)ethh->h_dest);
+ tx_desc->ctrl.srcrb_flags16[0] =
+ get_unaligned((__be16 *)ethh->h_dest);
tx_desc->ctrl.imm = get_unaligned((__be32 *)(ethh->h_dest + 2));
}
@@ -904,7 +908,8 @@
/* Copy headers;
* note that we already verified that it is linear.
- * brho - meaning that the lso_header_size is within block->rp. */
+ * brho - meaning that the lso_header_size is within block->rp.
+ */
memcpy(tx_desc->lso.header, block->rp, lso_header_size);
ring->tso_packets++;
diff --git a/kern/drivers/net/mlx4/main.c b/kern/drivers/net/mlx4/main.c
index 39287a3..75c49b3 100644
--- a/kern/drivers/net/mlx4/main.c
+++ b/kern/drivers/net/mlx4/main.c
@@ -3910,7 +3910,8 @@
probed = true;
STAILQ_FOREACH(pdev, &pci_devices, all_dev) {
- /* This checks that pcidev is a Network Controller for Ethernet */
+ /* This checks that pcidev is a Network Controller for Ethernet
+ */
if (pdev->class != 0x02 || pdev->subclass != 0x00)
continue;
diff --git a/kern/drivers/net/mlx4/mlx4_en.h b/kern/drivers/net/mlx4/mlx4_en.h
index 37fd9b0..2d279b1 100644
--- a/kern/drivers/net/mlx4/mlx4_en.h
+++ b/kern/drivers/net/mlx4/mlx4_en.h
@@ -284,8 +284,8 @@
} ____cacheline_aligned_in_smp;
struct mlx4_poke_args {
- struct ether *edev;
- struct mlx4_en_priv *priv;
+ struct ether *edev;
+ struct mlx4_en_priv *priv;
struct mlx4_en_tx_ring *ring;
};
diff --git a/kern/drivers/net/mlx4u/main.c b/kern/drivers/net/mlx4u/main.c
index d7ba859..124a86b 100644
--- a/kern/drivers/net/mlx4u/main.c
+++ b/kern/drivers/net/mlx4u/main.c
@@ -77,13 +77,13 @@
void mlx4_ib_mcg_destroy() { }
int mlx4_ib_mcg_init(void) { return 0; }
void mlx4_ib_invalidate_all_guid_record(struct mlx4_ib_dev *dev, int port) {}
-void mlx4_ib_slave_alias_guid_event(struct mlx4_ib_dev *dev, int slave,
- int port, int slave_init) {}
+void mlx4_ib_slave_alias_guid_event(struct mlx4_ib_dev *dev, int slave, int
+ port, int slave_init) {}
void handle_port_mgmt_change_event(struct work_struct *work){}
void mlx4_ib_tunnels_update_work(struct work_struct *work) {}
-int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int mad_ifc_flags, int port,
- struct ib_wc *in_wc, struct ib_grh *in_grh, void *in_mad,
- void *response_mad) { return 0; }
+int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int mad_ifc_flags, int port, struct
+ ib_wc *in_wc, struct ib_grh *in_grh, void *in_mad, void
+ *response_mad) { return 0; }
/* STUB END */
#endif /* AKAROS */
diff --git a/kern/drivers/net/r8169.c b/kern/drivers/net/r8169.c
index 93f0113..038a01a 100644
--- a/kern/drivers/net/r8169.c
+++ b/kern/drivers/net/r8169.c
@@ -752,14 +752,14 @@
struct rtl8169_private {
/* 9ns compat */
- struct pci_device *pcidev;
- struct ether *edev;
+ struct pci_device *pcidev;
+ struct ether *edev;
TAILQ_ENTRY(rtl8169_private) link9ns;
- const struct pci_device_id *pci_id; /* for navigating pci/pnp */
- struct rendez irq_task; /* bottom half IRQ */
- struct poke_tracker poker; /* tx concurrency */
- bool active;
- bool attached;
+ const struct pci_device_id *pci_id; /* for navigating pci/pnp */
+ struct rendez irq_task; /* bottom half IRQ */
+ struct poke_tracker poker; /* tx concurrency */
+ bool active;
+ bool attached;
void __iomem *mmio_addr; /* memory map physical address */
struct pci_device *pci_dev;
@@ -6998,9 +6998,10 @@
txd->addr = cpu_to_le64(mapping);
tp->tx_skb[entry].len = len;
- /* Tracking how many frags we're sending. The expectation from the
- * Linux code is that cur_frag is 0-indexed during the loop, and
- * incremented at the end. This only seems to matter for err_out. */
+ /* Tracking how many frags we're sending. The expectation from
+ * the Linux code is that cur_frag is 0-indexed during the loop,
+ * and incremented at the end. This only seems to matter for
+ * err_out. */
cur_frag++;
}
@@ -7031,8 +7032,8 @@
struct block *bp)
{
if (bp->mss) {
- /* Need to break the large packet up into smaller segments. Would need
- * support from higher in the stack. */
+ /* Need to break the large packet up into smaller segments.
+ * Would need support from higher in the stack. */
panic("Not implemented");
#if 0 // AKAROS_PORT
netdev_features_t features = tp->dev->feat;
@@ -7053,8 +7054,8 @@
dev_consume_skb_any(skb);
#endif
} else if (bp->flag & BLOCK_TRANS_TX_CSUM) {
- /* Yes, finalize checks the bp->flag too, but we wanted to know if we
- * should even try, and o/w drop. */
+ /* Yes, finalize checks the bp->flag too, but we wanted to know
+ * if we should even try, and o/w drop. */
ptclcsum_finalize(bp, 0);
rtl8169_start_xmit(bp, tp->dev);
} else {
@@ -7163,11 +7164,11 @@
} else if (bp->flag & BLOCK_TRANS_TX_CSUM) {
uint8_t ip_protocol;
- /* Linux would conditionally pad it the packet if the hardware can't do
- * it (which is my interpretation of seeing eth_skb_pad / ETH_ZLEN
- * padding/checks. On Akaros, we'll tell the ethernet layer to do it
- * for the bad models (grep NETF_PADMIN), and leave the checks in here
- * for sanity. */
+ /* Linux would conditionally pad it the packet if the hardware
+ * can't do it (which is my interpretation of seeing eth_skb_pad
+ * / ETH_ZLEN padding/checks. On Akaros, we'll tell the
+ * ethernet layer to do it for the bad models (grep
+ * NETF_PADMIN), and leave the checks in here for sanity. */
assert(!rtl_test_hw_pad_bug(tp, bp));
if (transport_offset > TCPHO_MAX) {
@@ -7193,7 +7194,8 @@
break;
}
- /* Note Akaros could check the specific BLOCK_TRANS_TX_CSUM flag */
+ /* Note Akaros could check the specific BLOCK_TRANS_TX_CSUM flag
+ */
if (ip_protocol == IPPROTO_TCP)
opts[1] |= TD1_TCP_CS;
else if (ip_protocol == IPPROTO_UDP)
@@ -7221,10 +7223,11 @@
uint32_t opts[2];
int frags;
- /* TODO: This isn't quite nr_frags, since there could be holes. Should fix
- * the block extra data to track valid segments. */
+ /* TODO: This isn't quite nr_frags, since there could be holes. Should
+ * fix the block extra data to track valid segments. */
if (unlikely(!TX_FRAGS_READY_FOR(tp, bp->nr_extra_bufs))) {
- netif_err(tp, drv, dev, "BUG! Tx Ring full when queue awake!\n");
+ netif_err(tp, drv, dev,
+ "BUG! Tx Ring full when queue awake!\n");
goto err_stop_0;
}
@@ -7240,8 +7243,8 @@
}
len = BHLEN(bp);
- /* I think we always have some sort of header in BHLEN. If not, change the
- * rest of this to handle it. */
+ /* I think we always have some sort of header in BHLEN. If not, change
+ * the rest of this to handle it. */
assert(len);
mapping = dma_map_single(d, bp->rp, len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(d, mapping))) {
@@ -7283,7 +7286,8 @@
bus_wmb();
- /* Linux calls netif_stop_queue if (!TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS))
+ /* Linux calls netif_stop_queue if (!TX_FRAGS_READY_FOR(tp,
+ * MAX_SKB_FRAGS))
*
* We do our backpressure in __rtl_xmit_poke. */
@@ -7406,10 +7410,10 @@
RTL_W8(TxPoll, NPQ);
}
- /* I'm not sure if this needs to happen after the TxPoll hack. The
- * netif is woken first on linux, but there might be a napi ordering,
- * where the expectation is that the TxPoll hack happens before the
- * netif stop (and potentially start) */
+ /* I'm not sure if this needs to happen after the TxPoll hack.
+ * The netif is woken first on linux, but there might be a napi
+ * ordering, where the expectation is that the TxPoll hack
+ * happens before the netif stop (and potentially start) */
struct rtl_poke_args args[1];
args->edev = dev;
@@ -7427,8 +7431,8 @@
{
uint32_t status = opts1 & RxProtoMask;
- /* Linux marked CHECKSUM_UNNECESSARY here. We might need to do something
- * with Bipck still. */
+ /* Linux marked CHECKSUM_UNNECESSARY here. We might need to do
+ * something with Bipck still. */
if (((status == RxProtoTCP) && !(opts1 & TCPFail)) ||
((status == RxProtoUDP) && !(opts1 & UDPFail)))
bp->flag |= Btcpck | Budpck;
@@ -7571,8 +7575,8 @@
if (status) {
handled = 1;
rtl_irq_disable(tp);
- /* It's not clear if there's only one IRQ at a time (SMP) or not.
- * Safest way is to use a ktask. */
+ /* It's not clear if there's only one IRQ at a time
+ * (SMP) or not. Safest way is to use a ktask. */
rendez_wakeup(&tp->irq_task);
}
}
@@ -7593,7 +7597,8 @@
switch (tp->mac_version) {
/* Work around for rx fifo overflow */
case RTL_GIGA_MAC_VER_11:
- /* This might not work, given how our workqueue shims go */
+ /* This might not work, given how our workqueue shims go
+ */
panic("Not implemented");
netif_stop_queue(dev);
/* XXX - Hack alert. See rtl_task(). */
@@ -7673,8 +7678,10 @@
status = rtl_get_events(tp);
rtl_ack_events(tp, status & ~tp->event_slow);
- if (status & RTL_EVENT_NAPI_RX)
- rtl_rx(dev, tp, UINT32_MAX); /* careful of budget's type */
+ if (status & RTL_EVENT_NAPI_RX) {
+ /* careful of budget's type */
+ rtl_rx(dev, tp, UINT32_MAX);
+ }
if (status & RTL_EVENT_NAPI_TX)
rtl_tx(dev, tp);
@@ -7784,13 +7791,15 @@
* Rx and Tx descriptors needs 256 bytes alignment.
* dma_alloc_coherent provides more.
*/
- tp->TxDescArray = dma_zalloc_coherent(&pdev->device, R8169_TX_RING_BYTES,
- &tp->TxPhyAddr, MEM_WAIT);
+ tp->TxDescArray = dma_zalloc_coherent(&pdev->device,
+ R8169_TX_RING_BYTES,
+ &tp->TxPhyAddr, MEM_WAIT);
if (!tp->TxDescArray)
goto err_pm_runtime_put;
- tp->RxDescArray = dma_zalloc_coherent(&pdev->device, R8169_RX_RING_BYTES,
- &tp->RxPhyAddr, MEM_WAIT);
+ tp->RxDescArray = dma_zalloc_coherent(&pdev->device,
+ R8169_RX_RING_BYTES,
+ &tp->RxPhyAddr, MEM_WAIT);
if (!tp->RxDescArray)
goto err_free_tx_0;
@@ -8519,9 +8528,9 @@
* properly for all devices */
dev->feat |= NETIF_F_RXCSUM |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
- /* AKAROS: We don't have a way (currently) to turn on certain features at
- * runtime. Linux's NIC didn't want SG, CSUM, and TSO by default, but we'll
- * turn it on until we find a NIC with a problem. */
+ /* AKAROS: We don't have a way (currently) to turn on certain features
+ * at runtime. Linux's NIC didn't want SG, CSUM, and TSO by default,
+ * but we'll turn it on until we find a NIC with a problem. */
dev->feat |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
/* AKAROS: Some versions don't pad to the mintu. */
@@ -8683,13 +8692,13 @@
bp = qget(edev->oq);
if (!bp)
break;
- /* TODO: If this is a problem, we can peak at the first block and wait
- * til we have enough room. Though we are still capped by the max TX
- * possible, and it might not be worth doing (leaving the NIC idle and
- * blasting packets.
+ /* TODO: If this is a problem, we can peak at the first block
+ * and wait til we have enough room. Though we are still capped
+ * by the max TX possible, and it might not be worth doing
+ * (leaving the NIC idle and blasting packets.
*
- * We probably need qclone to respect MAX_SKB_FRAGS or some other
- * system-wide constant. */
+ * We probably need qclone to respect MAX_SKB_FRAGS or some
+ * other system-wide constant. */
if (bp->nr_extra_bufs > MAX_SKB_FRAGS)
bp = linearizeblock(bp);
rtl8169_start_xmit(bp, edev);
@@ -8744,9 +8753,10 @@
{
struct rtl8169_private *tp = netdev_priv(ether);
- /* 9ns doesn't even call into devether shutdown - not sure what the hell is
- * going on there. Completely untested, and I don't know if the order of
- * shutdown / remove_one is right, or if other things need to be done. */
+ /* 9ns doesn't even call into devether shutdown - not sure what the hell
+ * is going on there. Completely untested, and I don't know if the
+ * order of shutdown / remove_one is right, or if other things need to
+ * be done. */
warn("Untested NIC shutdown!");
rtl_shutdown(tp->pcidev);
rtl_remove_one(tp->pcidev);
@@ -8772,13 +8782,15 @@
struct rtl8169_private *ctlr;
STAILQ_FOREACH(pcidev, &pci_devices, all_dev) {
- /* This checks that pcidev is a Network Controller for Ethernet */
+ /* This checks that pcidev is a Network Controller for Ethernet
+ */
if (pcidev->class != 0x02 || pcidev->subclass != 0x00)
continue;
pci_id = srch_linux_pci_tbl(rtl8169_pci_tbl, pcidev);
if (!pci_id)
continue;
- /* If we have a module init method, call it here via run_once() */
+ /* If we have a module init method, call it here via run_once()
+ */
printk("rtl8169 driver found 0x%04x:%04x at %02x:%02x.%x\n",
pcidev->ven_id, pcidev->dev_id,
pcidev->bus, pcidev->dev, pcidev->func);
@@ -8826,14 +8838,15 @@
pcidev = ctlr->pcidev;
strlcpy(edev->drv_name, "r8169", KNAMELEN);
- /* Unlike bnx2x, we need to do the device init early so we can extract info
- * like the MAC addr. */
+ /* Unlike bnx2x, we need to do the device init early so we can extract
+ * info like the MAC addr. */
rc = rtl_init_one(edev, pcidev, ctlr->pci_id);
if (rc) {
printk("Failed to init r8169 0x%04x:%04x at %02x:%02x.%x\n",
pcidev->ven_id, pcidev->dev_id,
pcidev->bus, pcidev->dev, pcidev->func);
- /* We could clear 'active', but if it failed once, it'll fail again. */
+ /* We could clear 'active', but if it failed once, it'll fail
+ * again. */
return -1;
}
diff --git a/kern/drivers/net/udrvr/compat.c b/kern/drivers/net/udrvr/compat.c
index 4647558..e17b0f5 100644
--- a/kern/drivers/net/udrvr/compat.c
+++ b/kern/drivers/net/udrvr/compat.c
@@ -41,7 +41,8 @@
* vmap_pmem_nocache(). This routine is expected to be invoked as part of mmap()
* handler.
*/
-int map_upage_at_addr(struct proc *p, physaddr_t paddr, uintptr_t addr, int pteprot, int dolock)
+int map_upage_at_addr(struct proc *p, physaddr_t paddr, uintptr_t addr,
+ int pteprot, int dolock)
{
pte_t pte;
int rv = -1;
@@ -89,7 +90,7 @@
}
int get_user_page(struct proc *p, unsigned long uvastart, int write, int force,
- struct page **plist)
+ struct page **plist)
{
pte_t pte;
int ret = -1;
@@ -133,8 +134,9 @@
goto err1;
}
- /* TODO (GUP): change the interface such that devices provide the memory and
- * the user mmaps it, instead of trying to pin arbitrary user memory. */
+ /* TODO (GUP): change the interface such that devices provide the memory
+ * and the user mmaps it, instead of trying to pin arbitrary user
+ * memory. */
warn_once("Extremely unsafe, unpinned memory mapped! If your process dies, you might scribble on RAM!");
plist[0] = pp;
@@ -197,7 +199,7 @@
/* Callers must pass in null terminated strings */
static ssize_t sysfs_read(char __user *buf, size_t ucount, loff_t *pos,
- char *src)
+ char *src)
{
int slen = strlen(src) + 1; /* + 1 for terminating null */
unsigned long off = *pos, nb = slen - off;
@@ -213,7 +215,7 @@
}
static ssize_t ib_api_ver_read(struct file *filp, char __user *buf,
- size_t count, loff_t *pos)
+ size_t count, loff_t *pos)
{
char src[4] = { 0, 0, 0, 0};
@@ -230,8 +232,8 @@
};
#endif
-static ssize_t mlx4_mgm_read(struct file *filp, char __user *buf,
- size_t count, loff_t *pos)
+static ssize_t mlx4_mgm_read(struct file *filp, char __user *buf, size_t count,
+ loff_t *pos)
{
#if CONFIG_MLX4_DEFAULT_MGM_LOG_ENTRY_SIZE == -1
char src[4] = { '-', '1', 0, 0 };
@@ -271,8 +273,8 @@
}
}
-static ssize_t cpu_read(struct file *filp, char __user *buf,
- size_t count, loff_t *pos)
+static ssize_t cpu_read(struct file *filp, char __user *buf, size_t count,
+ loff_t *pos)
{
char cpu_info_str[128];
long freq = __proc_global_info.tsc_freq, idx;
@@ -333,8 +335,8 @@
#endif
}
-static ssize_t dver_read(struct file *filp, char __user *buf,
- size_t count, loff_t *pos)
+static ssize_t dver_read(struct file *filp, char __user *buf, size_t count,
+ loff_t *pos)
{
struct ib_uverbs_device *uvp;
char src[4] = { 0, 0, 0, 0};
@@ -345,8 +347,8 @@
return sysfs_read(buf, count, pos, src);
}
-static ssize_t dname_read(struct file *filp, char __user *buf,
- size_t count, loff_t *pos)
+static ssize_t dname_read(struct file *filp, char __user *buf, size_t count,
+ loff_t *pos)
{
struct ib_uverbs_device *uvp;
@@ -354,32 +356,32 @@
return sysfs_read(buf, count, pos, uvp->ib_dev->name);
}
-static ssize_t ntype_read(struct file *filp, char __user *buf,
- size_t count, loff_t *pos)
+static ssize_t ntype_read(struct file *filp, char __user *buf, size_t count,
+ loff_t *pos)
{
char src[] = "1";
return sysfs_read(buf, count, pos, src);
}
-static ssize_t ddev_read(struct file *filp, char __user *buf,
- size_t count, loff_t *pos)
+static ssize_t ddev_read(struct file *filp, char __user *buf, size_t count,
+ loff_t *pos)
{
char src[] = "0x1003";
return sysfs_read(buf, count, pos, src);
}
-static ssize_t dven_read(struct file *filp, char __user *buf,
- size_t count, loff_t *pos)
+static ssize_t dven_read(struct file *filp, char __user *buf, size_t count,
+ loff_t *pos)
{
char src[] = "0x15b3";
return sysfs_read(buf, count, pos, src);
}
-static ssize_t vsd_read(struct file *filp, char __user *buf,
- size_t count, loff_t *pos)
+static ssize_t vsd_read(struct file *filp, char __user *buf, size_t count,
+ loff_t *pos)
{
char *src = "puma20_A1-10.2.3.0";
@@ -425,7 +427,7 @@
#endif
void sysfs_create(int devnum, const struct file_operations *verb_fops,
- void *ptr)
+ void *ptr)
{
#if 1 // AKAROS_PORT
warn("mlx4: udrvr stuff requires various files, implement for 9ns!");
@@ -520,7 +522,7 @@
};
static ssize_t compat_ex(struct ib_uverbs_file *file, size_t count,
- const char __user *buf)
+ const char __user *buf)
{
struct ib_uverbs_cmd_hdr hdr;
struct ib_uverbs_ex_cmd_hdr_compat ex_hdr;
@@ -610,7 +612,7 @@
}
static ssize_t compat(struct ib_uverbs_file *file, size_t count,
- const char __user *buf)
+ const char __user *buf)
{
unsigned long tmpbuf[17];
struct ib_uverbs_cmd_hdr *p = (struct ib_uverbs_cmd_hdr *)tmpbuf;
@@ -654,7 +656,7 @@
* 8B hca_core_clock
*/
static ssize_t compat_query(struct ib_uverbs_file *file, size_t count,
- const char __user *buf)
+ const char __user *buf)
{
unsigned long tmpbuf[17], tval = 0;
struct ib_uverbs_cmd_hdr *p = (struct ib_uverbs_cmd_hdr *)tmpbuf;
diff --git a/kern/drivers/net/udrvr/umem.c b/kern/drivers/net/udrvr/umem.c
index 9a723da..9118174 100644
--- a/kern/drivers/net/udrvr/umem.c
+++ b/kern/drivers/net/udrvr/umem.c
@@ -55,7 +55,8 @@
#define ib_umem_odp_get(c, u) ({ BUG(); -1; })
#endif /* AKAROS */
-static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int dirty)
+static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem,
+ int dirty)
{
struct scatterlist *sg;
struct page *page;
diff --git a/kern/drivers/net/udrvr/uverbs.h b/kern/drivers/net/udrvr/uverbs.h
index 34069a5..2c0c78c 100644
--- a/kern/drivers/net/udrvr/uverbs.h
+++ b/kern/drivers/net/udrvr/uverbs.h
@@ -61,12 +61,12 @@
(udata)->outlen = (olen); \
} while (0)
-#define INIT_UDATA_BUF_OR_NULL(udata, ibuf, obuf, ilen, olen) \
- do { \
- (udata)->inbuf = (ilen) ? (const void __user *) (ibuf) : NULL; \
- (udata)->outbuf = (olen) ? (void __user *) (obuf) : NULL; \
- (udata)->inlen = (ilen); \
- (udata)->outlen = (olen); \
+#define INIT_UDATA_BUF_OR_NULL(udata, ibuf, obuf, ilen, olen) \
+ do { \
+ (udata)->inbuf = (ilen) ? (const void __user *) (ibuf) : NULL;\
+ (udata)->outbuf = (olen) ? (void __user *) (obuf) : NULL;\
+ (udata)->inlen = (ilen); \
+ (udata)->outlen = (olen); \
} while (0)
/*
diff --git a/kern/drivers/timers/hpet.c b/kern/drivers/timers/hpet.c
index 7ccfd8e..0dd88e2 100644
--- a/kern/drivers/timers/hpet.c
+++ b/kern/drivers/timers/hpet.c
@@ -23,10 +23,11 @@
struct Atable *parsehpet(struct Atable *parent,
char *name, uint8_t *raw, size_t rawsize)
{
- /* Do we want to keep this table around? if so, we can use newtable, which
- * allocs an Atable and puts it on a global stailq. then we return that
- * pointer, not as an addr, but as a signal to parse code about whether or
- * not it is safe to unmap (which we don't do anymore). */
+ /* Do we want to keep this table around? if so, we can use newtable,
+ * which allocs an Atable and puts it on a global stailq. then we
+ * return that pointer, not as an addr, but as a signal to parse code
+ * about whether or not it is safe to unmap (which we don't do anymore).
+ */
struct Atable *hpet = mkatable(parent, HPET, "HPET", raw, rawsize, 0);
unsigned long hp_addr;
uint32_t evt_blk_id;
@@ -49,8 +50,8 @@
printd("Timer %d, config reg %p\n", i,
hpet_r64(hp_addr + 0x100 + 0x20 * i));
/* 0x10, general config register. bottom two bits are legacy mode and
- * global enable. turning them both off. need to do read-modify-writes to
- * HPET registers with reserved fields.*/
+ * global enable. turning them both off. need to do read-modify-writes
+ * to HPET registers with reserved fields.*/
hpet_w64(hp_addr + 0x10, hpet_r64(hp_addr + 0x10) & ~0x3);
printk("Disabled the HPET timer\n");
@@ -62,9 +63,9 @@
uint8_t cmos_b;
/* this stuff tries to turn off various cmos / RTC timer bits. keeping
- * around if we need to disable the RTC alarm. note that the HPET replaces
- * the RTC periodic function (where available), and in those cases the RTC
- * alarm function is implemented with SMM. */
+ * around if we need to disable the RTC alarm. note that the HPET
+ * replaces the RTC periodic function (where available), and in those
+ * cases the RTC alarm function is implemented with SMM. */
outb(0x70, 0xb);
cmos_b = inb(0x71);
printk("cmos b 0x%02x\n", cmos_b);
diff --git a/kern/include/acpi.h b/kern/include/acpi.h
index 02b4df2..b02c026 100644
--- a/kern/include/acpi.h
+++ b/kern/include/acpi.h
@@ -57,7 +57,7 @@
enum {
- Sdthdrsz = 36, /* size of SDT header */
+ Sdthdrsz = 36, /* size of SDT header */
/* ACPI regions. Gas ids */
Rsysmem = 0,
@@ -71,7 +71,7 @@
Rfixedhw = 0x7f,
/* ACPI PM1 control */
- Pm1SciEn = 0x1, /* Generate SCI and not SMI */
+ Pm1SciEn = 0x1, /* Generate SCI and not SMI */
/* ACPI tbdf as encoded in acpi region base addresses */
Rpciregshift = 0,
@@ -85,21 +85,21 @@
/* Apic structure types */
ASlapic = 0, /* processor local apic */
- ASioapic, /* I/O apic */
- ASintovr, /* Interrupt source override */
- ASnmi, /* NMI source */
- ASlnmi, /* local apic nmi */
- ASladdr, /* local apic address override */
- ASiosapic, /* I/O sapic */
- ASlsapic, /* local sapic */
- ASintsrc, /* platform interrupt sources */
- ASlx2apic, /* local x2 apic */
- ASlx2nmi, /* local x2 apic NMI */
+ ASioapic, /* I/O apic */
+ ASintovr, /* Interrupt source override */
+ ASnmi, /* NMI source */
+ ASlnmi, /* local apic nmi */
+ ASladdr, /* local apic address override */
+ ASiosapic, /* I/O sapic */
+ ASlsapic, /* local sapic */
+ ASintsrc, /* platform interrupt sources */
+ ASlx2apic, /* local x2 apic */
+ ASlx2nmi, /* local x2 apic NMI */
/* Apic flags */
- AFbus = 0, /* polarity/trigger like in ISA */
- AFhigh = 1, /* active high */
- AFlow = 3, /* active low */
+ AFbus = 0, /* polarity/trigger like in ISA */
+ AFhigh = 1, /* active high */
+ AFlow = 3, /* active low */
AFpmask = 3, /* polarity bits */
AFedge = 1 << 2, /* edge triggered */
AFlevel = 3 << 2, /* level triggered */
@@ -136,12 +136,12 @@
ATSR,
RHSA,
ANDD,
- NACPITBLS, /* Number of ACPI tables */
+ NACPITBLS, /* Number of ACPI tables */
/* SRAT types */
SRlapic = 0, /* Local apic/sapic affinity */
- SRmem, /* Memory affinity */
- SRlx2apic, /* x2 apic affinity */
+ SRmem, /* Memory affinity */
+ SRlx2apic, /* x2 apic affinity */
/* Atable constants */
SIGSZ = 4+1, /* Size of the signature (including NUL) */
@@ -149,12 +149,12 @@
OEMTBLIDSZ = 8+1, /* Size of the OEM Table ID (including NUL) */
/* Arg for _PIC */
- Ppic = 0, /* PIC interrupt model */
- Papic, /* APIC interrupt model */
- Psapic, /* SAPIC interrupt model */
+ Ppic = 0, /* PIC interrupt model */
+ Papic, /* APIC interrupt model */
+ Psapic, /* SAPIC interrupt model */
CMregion = 0, /* regio name spc base len accsz */
- CMgpe, /* gpe name id */
+ CMgpe, /* gpe name id */
};
/*
@@ -172,32 +172,32 @@
* same array.
*/
struct Atable {
- struct qid qid; /* QID corresponding to this table. */
- struct qid rqid; /* This table's 'raw' QID. */
- struct qid pqid; /* This table's 'pretty' QID. */
- struct qid tqid; /* This table's 'table' QID. */
- int type; /* This table's type */
- void *tbl; /* pointer to the converted table, e.g. madt. */
- char name[16]; /* name of this table */
+ struct qid qid; /* QID corresponding to this table. */
+ struct qid rqid; /* This table's 'raw' QID. */
+ struct qid pqid; /* This table's 'pretty' QID. */
+ struct qid tqid; /* This table's 'table' QID. */
+ int type; /* This table's type */
+ void *tbl; /* pointer to the converted table, e.g. madt. */
+ char name[16]; /* name of this table */
- struct Atable *parent; /* Parent pointer */
- struct Atable **children; /* children of this node (an array). */
- struct dirtab *cdirs; /* child directory entries of this node. */
- size_t nchildren; /* count of this node's children */
- struct Atable *next; /* Pointer to the next sibling. */
+ struct Atable *parent; /* Parent pointer */
+ struct Atable **children; /* children of this node (an array). */
+ struct dirtab *cdirs; /* child directory entries of this node. */
+ size_t nchildren; /* count of this node's children */
+ struct Atable *next; /* Pointer to the next sibling. */
- size_t rawsize; /* Total size of raw table */
- uint8_t *raw; /* Raw data. */
+ size_t rawsize; /* Total size of raw table */
+ uint8_t *raw; /* Raw data. */
};
struct Gpe {
- uintptr_t stsio; /* port used for status */
- int stsbit; /* bit number */
- uintptr_t enio; /* port used for enable */
- int enbit; /* bit number */
- int nb; /* event number */
- char *obj; /* handler object */
- int id; /* id as supplied by user */
+ uintptr_t stsio; /* port used for status */
+ int stsbit; /* bit number */
+ uintptr_t enio; /* port used for enable */
+ int enbit; /* bit number */
+ int nb; /* event number */
+ char *obj; /* handler object */
+ int id; /* id as supplied by user */
};
struct Regio {
@@ -214,22 +214,22 @@
struct Reg {
char *name;
- int spc; /* io space */
- uint64_t base; /* address, physical */
- uint8_t *p; /* address, kmapped */
+ int spc; /* io space */
+ uint64_t base; /* address, physical */
+ uint8_t *p; /* address, kmapped */
uint64_t len;
int tbdf;
- int accsz; /* access size */
+ int accsz; /* access size */
};
/* Generic address structure.
*/
struct Gas {
- uint8_t spc; /* address space id */
- uint8_t len; /* register size in bits */
- uint8_t off; /* bit offset */
- uint8_t accsz; /* 1: byte; 2: word; 3: dword; 4: qword */
- uint64_t addr; /* address (or acpi encoded tbdf + reg) */
+ uint8_t spc; /* address space id */
+ uint8_t len; /* register size in bits */
+ uint8_t off; /* bit offset */
+ uint8_t accsz; /* 1: byte; 2: word; 3: dword; 4: qword */
+ uint64_t addr; /* address (or acpi encoded tbdf + reg) */
};
/* Root system description table pointer.
@@ -242,21 +242,21 @@
* - pointers to other tables for apics, etc.
*/
struct Rsdp {
- uint8_t signature[8]; /* "RSD PTR " */
+ uint8_t signature[8]; /* "RSD PTR " */
uint8_t rchecksum;
uint8_t oemid[6];
uint8_t revision;
- uint8_t raddr[4]; /* RSDT */
+ uint8_t raddr[4]; /* RSDT */
uint8_t length[4];
- uint8_t xaddr[8]; /* XSDT */
- uint8_t xchecksum; /* XSDT */
- uint8_t _reserved[3]; /* reserved */
+ uint8_t xaddr[8]; /* XSDT */
+ uint8_t xchecksum; /* XSDT */
+ uint8_t _reserved[3]; /* reserved */
};
/* Header for ACPI description tables
*/
struct Sdthdr {
- uint8_t sig[4]; /* "FACP" or whatever */
+ uint8_t sig[4]; /* "FACP" or whatever */
uint8_t length[4];
uint8_t rev;
uint8_t csum;
@@ -284,18 +284,18 @@
/* Maximum System Characteristics table
*/
struct Msct {
- int ndoms; /* number of domains */
- int nclkdoms; /* number of clock domains */
- uint64_t maxpa; /* max physical address */
- size_t nmdom; /* number of discovered domains */
- struct Mdom *dom; /* array of domains */
+ int ndoms; /* number of domains */
+ int nclkdoms; /* number of clock domains */
+ uint64_t maxpa; /* max physical address */
+ size_t nmdom; /* number of discovered domains */
+ struct Mdom *dom; /* array of domains */
};
struct Mdom {
- int start; /* start dom id */
- int end; /* end dom id */
- int maxproc; /* max processor capacity */
- uint64_t maxmem; /* max memory capacity */
+ int start; /* start dom id */
+ int end; /* end dom id */
+ int maxproc; /* max processor capacity */
+ uint64_t maxmem; /* max memory capacity */
};
/* Multiple APIC description table
@@ -305,55 +305,55 @@
* Only enabled devices are linked, others are filtered out.
*/
struct Madt {
- uint64_t lapicpa; /* local APIC addr */
- int pcat; /* the machine has PC/AT 8259s */
+ uint64_t lapicpa; /* local APIC addr */
+ int pcat; /* the machine has PC/AT 8259s */
};
struct Apicst {
int type;
union {
struct {
- int pid; /* processor id */
- int id; /* apic no */
+ int pid; /* processor id */
+ int id; /* apic no */
} lapic;
struct {
- int id; /* io apic id */
+ int id; /* io apic id */
uint32_t ibase; /* interrupt base addr. */
uint64_t addr; /* base address */
} ioapic, iosapic;
struct {
- int irq; /* bus intr. source (ISA only) */
- int intr; /* system interrupt */
- int flags; /* apic flags */
+ int irq; /* bus intr. source (ISA only) */
+ int intr; /* system interrupt */
+ int flags; /* apic flags */
} intovr;
struct {
- int intr; /* system interrupt */
- int flags; /* apic flags */
+ int intr; /* system interrupt */
+ int flags; /* apic flags */
} nmi;
struct {
- int pid; /* processor id */
- int flags; /* lapic flags */
- int lint; /* lapic LINTn for nmi */
+ int pid; /* processor id */
+ int flags; /* lapic flags */
+ int lint; /* lapic LINTn for nmi */
} lnmi;
struct {
- int pid; /* processor id */
- int id; /* apic id */
- int eid; /* apic eid */
- int puid; /* processor uid */
+ int pid; /* processor id */
+ int id; /* apic id */
+ int eid; /* apic eid */
+ int puid; /* processor uid */
char *puids; /* same thing */
} lsapic;
struct {
- int pid; /* processor id */
- int peid; /* processor eid */
- int iosv; /* io sapic vector */
- int intr; /* global sys intr. */
- int type; /* intr type */
- int flags; /* apic flags */
- int any; /* err sts at any proc */
+ int pid; /* processor id */
+ int peid; /* processor eid */
+ int iosv; /* io sapic vector */
+ int intr; /* global sys intr. */
+ int type; /* intr type */
+ int flags; /* apic flags */
+ int any; /* err sts at any proc */
} intsrc;
struct {
- int id; /* x2 apic id */
- int puid; /* processor uid */
+ int id; /* x2 apic id */
+ int puid; /* processor uid */
} lx2apic;
struct {
int puid;
@@ -369,22 +369,22 @@
int type;
union {
struct {
- int dom; /* proximity domain */
- int apic; /* apic id */
- int sapic; /* sapic id */
- int clkdom; /* clock domain */
+ int dom; /* proximity domain */
+ int apic; /* apic id */
+ int sapic; /* sapic id */
+ int clkdom; /* clock domain */
} lapic;
struct {
- int dom; /* proximity domain */
+ int dom; /* proximity domain */
uint64_t addr; /* base address */
uint64_t len;
- int hplug; /* hot pluggable */
- int nvram; /* non volatile */
+ int hplug; /* hot pluggable */
+ int nvram; /* non volatile */
} mem;
struct {
- int dom; /* proximity domain */
- int apic; /* x2 apic id */
- int clkdom; /* clock domain */
+ int dom; /* proximity domain */
+ int apic; /* x2 apic id */
+ int clkdom; /* clock domain */
} lx2apic;
};
};
@@ -397,8 +397,8 @@
};
struct SlEntry {
- int dom; /* proximity domain */
- unsigned int dist; /* distance to proximity domain */
+ int dom; /* proximity domain */
+ unsigned int dist; /* distance to proximity domain */
};
/* Fixed ACPI description table.
diff --git a/kern/include/address_range.h b/kern/include/address_range.h
index c1ef3e4..1d7a06e 100644
--- a/kern/include/address_range.h
+++ b/kern/include/address_range.h
@@ -18,4 +18,4 @@
int address_range_validate(const struct address_range *ars, size_t count);
int address_range_init(struct address_range *ars, size_t count);
const struct address_range *address_range_find(const struct address_range *ars,
- size_t count, uintptr_t addr);
+ size_t count, uintptr_t addr);
diff --git a/kern/include/alarm.h b/kern/include/alarm.h
index d0514a2..7510d1c 100644
--- a/kern/include/alarm.h
+++ b/kern/include/alarm.h
@@ -36,15 +36,12 @@
* Note that RKM unset_alarm() has a waits-on dependency with the actual alarm
* handler, so be careful of deadlock.
*
- * To use an IRQ alarm, init the waiter with init_awaiter_irq().
- *
* Quick howto, using the pcpu tchains:
* struct timer_chain *tchain = &per_cpu_info[core_id()].tchain;
* To block your kthread on an alarm:
* struct alarm_waiter *waiter = kmalloc(sizeof(struct alarm_waiter), 0);
- * struct alarm_waiter a_waiter; // or use the stack
*
- * init_awaiter(waiter, HANDLER); // or init_awaiter_irq() for IRQ ctx alarms
+ * init_awaiter(waiter, HANDLER);
* set_awaiter_rel(waiter, USEC);
* set_alarm(tchain, waiter);
*
@@ -68,11 +65,11 @@
/* These structures allow code to defer work for a certain amount of time.
* Timer chains (like off a per-core timer) are made of lists/trees of these. */
struct alarm_waiter {
- uint64_t wake_up_time; /* ugh, this is a TSC for now */
+ uint64_t wake_up_time;
void (*func) (struct alarm_waiter *waiter);
- void *data;
+ void *data;
TAILQ_ENTRY(alarm_waiter) next;
- bool on_tchain;
+ bool on_tchain;
};
TAILQ_HEAD(awaiters_tailq, alarm_waiter); /* ideally not a LL */
@@ -82,12 +79,12 @@
* with a lock, even if its rarely needed (like the pcpu tchains).
* set_interrupt() is a method for setting the interrupt source. */
struct timer_chain {
- spinlock_t lock;
+ spinlock_t lock;
struct awaiters_tailq waiters;
- struct alarm_waiter *running;
- uint64_t earliest_time;
- uint64_t latest_time;
- struct cond_var cv;
+ struct alarm_waiter *running;
+ uint64_t earliest_time;
+ uint64_t latest_time;
+ struct cond_var cv;
void (*set_interrupt)(struct timer_chain *);
};
@@ -125,6 +122,6 @@
}
/* Debugging */
-#define ALARM_POISON_TIME 12345 /* could use some work */
+#define ALARM_POISON_TIME 12345 /* could use some work */
void print_chain(struct timer_chain *tchain);
void print_pcpu_chains(void);
diff --git a/kern/include/apipe.h b/kern/include/apipe.h
index 3c62f37..9bc796e 100644
--- a/kern/include/apipe.h
+++ b/kern/include/apipe.h
@@ -55,18 +55,18 @@
#include <kthread.h>
struct atomic_pipe {
- char *ap_buf;
- size_t ap_ring_sz;
- size_t ap_elem_sz;
- size_t ap_rd_off;
- size_t ap_wr_off;
- unsigned int ap_nr_readers;
- unsigned int ap_nr_writers;
- spinlock_t ap_lock;
- struct cond_var ap_priority_reader;
- struct cond_var ap_general_readers;
- struct cond_var ap_writers;
- bool ap_has_priority_reader;
+ char *ap_buf;
+ size_t ap_ring_sz;
+ size_t ap_elem_sz;
+ size_t ap_rd_off;
+ size_t ap_wr_off;
+ unsigned int ap_nr_readers;
+ unsigned int ap_nr_writers;
+ spinlock_t ap_lock;
+ struct cond_var ap_priority_reader;
+ struct cond_var ap_general_readers;
+ struct cond_var ap_writers;
+ bool ap_has_priority_reader;
};
void apipe_init(struct atomic_pipe *ap, void *buf, size_t buf_sz,
diff --git a/kern/include/arena.h b/kern/include/arena.h
index f23ed8e..049674c 100644
--- a/kern/include/arena.h
+++ b/kern/include/arena.h
@@ -31,17 +31,17 @@
} btag_status_t;
struct btag {
- struct rb_node all_link; /* connects all non-free BTs */
- BSD_LIST_ENTRY(btag) misc_link; /* freelist, unused, or hash */
- uintptr_t start;
- size_t size;
- btag_status_t status;
+ struct rb_node all_link; /* all non-free BTs */
+ BSD_LIST_ENTRY(btag) misc_link; /* freelist unused or hash */
+ uintptr_t start;
+ size_t size;
+ btag_status_t status;
};
BSD_LIST_HEAD(btag_list, btag);
/* 64 is the most powers of two we can express with 64 bits. */
-#define ARENA_NR_FREE_LISTS 64
-#define ARENA_NAME_SZ 32
+#define ARENA_NR_FREE_LISTS 64
+#define ARENA_NAME_SZ 32
/* Forward declarations of import lists */
struct arena;
@@ -53,41 +53,41 @@
* All free segments are on one of the free_segs[] lists. There is one list for
* each power-of-two we can allocate. */
struct arena {
- spinlock_t lock;
- uint8_t import_scale;
- bool is_base;
- size_t quantum;
- size_t qcache_max;
- struct kmem_cache *qcaches;
- struct rb_root all_segs; /* BTs, using all_link */
- struct btag_list unused_btags; /* BTs, using misc_link */
- struct btag_list *alloc_hash; /* BTs, using misc_link */
- struct hash_helper hh;
+ spinlock_t lock;
+ uint8_t import_scale;
+ bool is_base;
+ size_t quantum;
+ size_t qcache_max;
+ struct kmem_cache *qcaches;
+ struct rb_root all_segs; /* BTs, using all_link */
+ struct btag_list unused_btags;/* BTs, using misc_link */
+ struct btag_list *alloc_hash; /* BTs, using misc_link */
+ struct hash_helper hh;
void *(*afunc)(struct arena *, size_t, int);
void (*ffunc)(struct arena *, void *, size_t);
- struct arena *source;
- size_t amt_total_segs; /* Does not include qcache */
- size_t amt_alloc_segs;
- size_t nr_allocs_ever;
- uintptr_t last_nextfit_alloc;
- struct btag_list free_segs[ARENA_NR_FREE_LISTS];
- struct btag_list static_hash[HASH_INIT_SZ];
+ struct arena *source;
+ size_t amt_total_segs; /* not include qcache */
+ size_t amt_alloc_segs;
+ size_t nr_allocs_ever;
+ uintptr_t last_nextfit_alloc;
+ struct btag_list free_segs[ARENA_NR_FREE_LISTS];
+ struct btag_list static_hash[HASH_INIT_SZ];
/* Accounting */
- char name[ARENA_NAME_SZ];
- TAILQ_ENTRY(arena) next;
+ char name[ARENA_NAME_SZ];
+ TAILQ_ENTRY(arena) next;
/* These lists are protected by the global arena_and_slab qlock */
- TAILQ_ENTRY(arena) import_link;
- struct arena_tailq __importing_arenas;
+ TAILQ_ENTRY(arena) import_link;
+ struct arena_tailq __importing_arenas;
struct kmem_cache_tailq __importing_slabs;
};
extern struct arena_tailq all_arenas;
/* Arena allocation styles, or'd with MEM_FLAGS */
-#define ARENA_BESTFIT 0x100
-#define ARENA_INSTANTFIT 0x200
-#define ARENA_NEXTFIT 0x400
+#define ARENA_BESTFIT 0x100
+#define ARENA_INSTANTFIT 0x200
+#define ARENA_NEXTFIT 0x400
#define ARENA_ALLOC_STYLES (ARENA_BESTFIT | ARENA_INSTANTFIT | ARENA_NEXTFIT)
/* Creates an area, with initial segment [@base, @base + @size). Allocs are in
diff --git a/kern/include/atomic.h b/kern/include/atomic.h
index d7682c7..a6c261a 100644
--- a/kern/include/atomic.h
+++ b/kern/include/atomic.h
@@ -110,13 +110,13 @@
* bigger one. In the future, they might be growable, etc, which init code may
* care about. */
struct hashlock {
- unsigned int nr_entries;
- struct spinlock locks[];
+ unsigned int nr_entries;
+ struct spinlock locks[];
};
#define HASHLOCK_DEFAULT_SZ 53 /* nice prime, might be a bit large */
struct small_hashlock {
- unsigned int nr_entries;
- struct spinlock locks[HASHLOCK_DEFAULT_SZ];
+ unsigned int nr_entries;
+ struct spinlock locks[HASHLOCK_DEFAULT_SZ];
};
void hashlock_init(struct hashlock *hl, unsigned int nr_entries);
@@ -173,12 +173,12 @@
/* Will spin for a little while, but not deadlock if it never happens */
#define spin_on(x) \
- for (int i = 0; (x); i++) { \
- cpu_relax(); \
- if (i == MAX_SPINS) { \
- printk("Probably timed out/failed.\n"); \
- break; \
- } \
+ for (int i = 0; (x); i++) { \
+ cpu_relax(); \
+ if (i == MAX_SPINS) { \
+ printk("Probably timed out/failed.\n"); \
+ break; \
+ } \
}
/*********************** Checklist stuff **********************/
@@ -192,7 +192,8 @@
struct checklist {
spinlock_t lock;
checklist_mask_t mask;
- // eagle-eyed readers may know why this might have been needed. 2009-09-04
+ // eagle-eyed readers may know why this might have been needed.
+ // 2009-09-04
//volatile uint8_t (COUNT(BYTES_FOR_BITMASK(size)) bits)[];
};
typedef struct checklist checklist_t;
diff --git a/kern/include/bitmask.h b/kern/include/bitmask.h
index 8b8d079..e718979 100644
--- a/kern/include/bitmask.h
+++ b/kern/include/bitmask.h
@@ -2,34 +2,34 @@
#include <arch/bitmask.h>
-static inline bool BITMASK_IS_SET_IN_RANGE(uint8_t* m, size_t beg, size_t end)
+static inline bool BITMASK_IS_SET_IN_RANGE(uint8_t *m, size_t beg, size_t end)
{
- for(size_t i=beg; i<end; i++) {
- if(!GET_BITMASK_BIT(m, i))
+ for (size_t i = beg; i <end; i++) {
+ if (!GET_BITMASK_BIT(m, i))
return FALSE;
}
return TRUE;
}
-static inline bool BITMASK_IS_CLR_IN_RANGE(uint8_t* m, size_t beg, size_t end)
+static inline bool BITMASK_IS_CLR_IN_RANGE(uint8_t *m, size_t beg, size_t end)
{
- for(size_t i=beg; i<end; i++) {
- if(GET_BITMASK_BIT(m, i))
+ for (size_t i = beg; i < end; i++) {
+ if (GET_BITMASK_BIT(m, i))
return FALSE;
}
return TRUE;
}
-static inline void SET_BITMASK_RANGE(uint8_t* m, size_t beg, size_t end)
+static inline void SET_BITMASK_RANGE(uint8_t *m, size_t beg, size_t end)
{
- for(size_t i=beg; i<end; i++) {
+ for (size_t i = beg; i < end; i++) {
SET_BITMASK_BIT(m, i);
}
}
-static inline void CLR_BITMASK_RANGE(uint8_t* m, size_t beg, size_t end)
+static inline void CLR_BITMASK_RANGE(uint8_t *m, size_t beg, size_t end)
{
- for(size_t i=beg; i<end; i++) {
+ for (size_t i = beg; i < end; i++) {
CLR_BITMASK_BIT(m, i);
}
}
@@ -44,11 +44,11 @@
* overheads. */
#define BITMASK_FOREACH_SET(name, size, work_fn, clear) \
{ \
- for (int i = 0; i < (size); i++) { \
- bool present = GET_BITMASK_BIT((name), i); \
- if (present && (clear)) \
- CLR_BITMASK_BIT_ATOMIC((name), i); \
- if (present) \
- (work_fn)(i); \
- } \
+ for (int i = 0; i < (size); i++) { \
+ bool present = GET_BITMASK_BIT((name), i); \
+ if (present && (clear)) \
+ CLR_BITMASK_BIT_ATOMIC((name), i); \
+ if (present) \
+ (work_fn)(i); \
+ } \
}
diff --git a/kern/include/bitops.h b/kern/include/bitops.h
index e60e198..8b82fe0 100644
--- a/kern/include/bitops.h
+++ b/kern/include/bitops.h
@@ -120,12 +120,12 @@
* overheads. */
#define BITMASK_FOREACH_SET(name, size, work_fn, clear) \
{ \
- for (int i = 0; i < (size); i++) { \
- bool present = GET_BITMASK_BIT((name), i); \
- if (present && (clear)) \
- CLR_BITMASK_BIT_ATOMIC((name), i); \
- if (present) \
- (work_fn)(i); \
- } \
+ for (int i = 0; i < (size); i++) { \
+ bool present = GET_BITMASK_BIT((name), i); \
+ if (present && (clear)) \
+ CLR_BITMASK_BIT_ATOMIC((name), i); \
+ if (present) \
+ (work_fn)(i); \
+ } \
}
#endif
diff --git a/kern/include/circular_buffer.h b/kern/include/circular_buffer.h
index 9b3e59c..cc090c6 100644
--- a/kern/include/circular_buffer.h
+++ b/kern/include/circular_buffer.h
@@ -40,9 +40,9 @@
void circular_buffer_destroy(struct circular_buffer *cb);
void circular_buffer_clear(struct circular_buffer *cb);
size_t circular_buffer_write(struct circular_buffer *cb, const char *data,
- size_t size);
+ size_t size);
size_t circular_buffer_read(struct circular_buffer *cb, char *data, size_t size,
- size_t off);
+ size_t off);
static inline size_t circular_buffer_size(const struct circular_buffer *cb)
{
diff --git a/kern/include/common.h b/kern/include/common.h
index 178cfef..344da5c 100644
--- a/kern/include/common.h
+++ b/kern/include/common.h
@@ -44,31 +44,32 @@
* other callers spin til the func is complete. */
#define run_once(func) \
do { \
- static bool ran_once = FALSE; \
- static bool is_running = FALSE; \
- if (!ran_once) { \
- /* fetch and set TRUE, without a header or test_and_set weirdness */ \
- if (!__sync_fetch_and_or(&is_running, TRUE)) { \
- /* we won the race and get to run the func */ \
- func; \
- wmb(); /* don't let the ran_once write pass previous writes */ \
- ran_once = TRUE; \
- } else { \
- /* someone else won, wait til they are done to break out */ \
- while (!ran_once) \
- cpu_relax(); \
- } \
- } \
+ static bool ran_once = FALSE; \
+ static bool is_running = FALSE; \
+ if (!ran_once) { \
+ /* fetch and set TRUE, w/o a header or test_and_set weirdness*/\
+ if (!__sync_fetch_and_or(&is_running, TRUE)) { \
+ /* we won the race and get to run the func */ \
+ func; \
+ /* don't let the ran_once write pass previous writes */\
+ wmb(); \
+ ran_once = TRUE; \
+ } else { \
+ /* someone else won */ \
+ while (!ran_once) \
+ cpu_relax(); \
+ } \
+ } \
} while (0)
/* Unprotected, single-threaded version, makes sure func is run exactly once */
#define run_once_racy(func) \
do { \
- static bool ran_once = FALSE; \
- if (!ran_once) { \
- func; \
- ran_once = TRUE; \
- } \
+ static bool ran_once = FALSE; \
+ if (!ran_once) { \
+ func; \
+ ran_once = TRUE; \
+ } \
} while (0)
#ifndef __ASSEMBLER__
diff --git a/kern/include/compat_todo.h b/kern/include/compat_todo.h
index 83c317a..c673f8e 100644
--- a/kern/include/compat_todo.h
+++ b/kern/include/compat_todo.h
@@ -23,7 +23,7 @@
-struct mdio_if_info { // need to interface with mii stuff?
+struct mdio_if_info { // need to interface with mii stuff?
};
struct sk_buff { // block
};
diff --git a/kern/include/core_set.h b/kern/include/core_set.h
index 19b7b51..c93aa9f 100644
--- a/kern/include/core_set.h
+++ b/kern/include/core_set.h
@@ -32,7 +32,7 @@
}
static inline bool core_set_getcpu(const struct core_set *cset,
- unsigned int cpuno)
+ unsigned int cpuno)
{
return test_bit(cpuno, cset->cpus);
}
diff --git a/kern/include/corealloc_fcfs.h b/kern/include/corealloc_fcfs.h
index 3d82a26..3e47d7b 100644
--- a/kern/include/corealloc_fcfs.h
+++ b/kern/include/corealloc_fcfs.h
@@ -12,16 +12,16 @@
* references, and should only be used as a ref source while the ksched has a
* valid kref. */
struct sched_pcore {
- TAILQ_ENTRY(sched_pcore) prov_next; /* on a proc's prov list */
- TAILQ_ENTRY(sched_pcore) alloc_next; /* on an alloc list (idle)*/
- struct proc *prov_proc; /* who this is prov to */
- struct proc *alloc_proc; /* who this is alloc to */
+ TAILQ_ENTRY(sched_pcore) prov_next; /* on a proc's prov list */
+ TAILQ_ENTRY(sched_pcore) alloc_next; /* on an alloc list (idle)*/
+ struct proc *prov_proc;
+ struct proc *alloc_proc;
};
TAILQ_HEAD(sched_pcore_tailq, sched_pcore);
struct core_request_data {
- struct sched_pcore_tailq prov_alloc_me; /* prov cores alloced us */
- struct sched_pcore_tailq prov_not_alloc_me; /* maybe alloc to others */
+ struct sched_pcore_tailq prov_alloc_me;
+ struct sched_pcore_tailq prov_not_alloc_me;
};
static inline uint32_t spc2pcoreid(struct sched_pcore *spc)
diff --git a/kern/include/corealloc_packed.h b/kern/include/corealloc_packed.h
index fea3f79..62bc856 100644
--- a/kern/include/corealloc_packed.h
+++ b/kern/include/corealloc_packed.h
@@ -18,19 +18,19 @@
* references, and should only be used as a ref source while the ksched has a
* valid kref. */
struct sched_pcore {
- TAILQ_ENTRY(sched_pcore) prov_next; /* on a proc's prov list */
- TAILQ_ENTRY(sched_pcore) alloc_next; /* on an alloc list (idle)*/
- struct proc *prov_proc; /* who this is prov to */
- struct proc *alloc_proc; /* who this is alloc to */
- struct core_info *core_info;
- struct sched_pnode *sched_pnode;
+ TAILQ_ENTRY(sched_pcore) prov_next; /* on a proc's prov list */
+ TAILQ_ENTRY(sched_pcore) alloc_next; /* on an alloc list (idle)*/
+ struct proc *prov_proc;
+ struct proc *alloc_proc;
+ struct core_info *core_info;
+ struct sched_pnode *sched_pnode;
};
TAILQ_HEAD(sched_pcore_tailq, sched_pcore);
struct core_request_data {
- struct sched_pcore_tailq alloc_me; /* cores alloced to us */
- struct sched_pcore_tailq prov_alloc_me; /* prov cores alloced us */
- struct sched_pcore_tailq prov_not_alloc_me; /* maybe alloc to others */
+ struct sched_pcore_tailq alloc_me;
+ struct sched_pcore_tailq prov_alloc_me;
+ struct sched_pcore_tailq prov_not_alloc_me;
};
static inline uint32_t spc2pcoreid(struct sched_pcore *spc)
diff --git a/kern/include/cpio.h b/kern/include/cpio.h
index d110b25..9998fa1 100644
--- a/kern/include/cpio.h
+++ b/kern/include/cpio.h
@@ -4,16 +4,16 @@
#define CPIO_CRC_ASCII 070702
/* Mode bits */
#define CPIO_FILE_MASK 0170000
-#define CPIO_SOCKET 0120000
+#define CPIO_SOCKET 0120000
#define CPIO_SYMLINK 0120000
#define CPIO_REG_FILE 0100000
#define CPIO_BLK_SPEC 0060000
#define CPIO_DIRECTORY 0040000
#define CPIO_CHAR_SPEC 0020000
#define CPIO_FIFO_PIPE 0010000
-#define CPIO_SUID 0004000
-#define CPIO_SGID 0002000
-#define CPIO_STICKY 0001000
+#define CPIO_SUID 0004000
+#define CPIO_SGID 0002000
+#define CPIO_STICKY 0001000
#define CPIO_PERM_MASK 0000777
struct cpio_newc_header
@@ -31,23 +31,25 @@
char c_rdev_maj[8]; /* only valid for chr and blk special files */
char c_rdev_min[8]; /* only valid for chr and blk special files */
char c_namesize[8]; /* count includes terminating NUL in pathname */
- char c_chksum[8]; /* for CRC format the sum of all the bytes in the file*/
+ /* for CRC format, chksum is the sum of all the bytes in the file */
+ char c_chksum[8];
};
/* Header passed around when initing a FS based on a CPIO archive */
struct cpio_bin_hdr
{
- unsigned long c_ino; /* FYI: we ignore this */
- int c_mode;
+ unsigned long c_ino; /* FYI: we ignore this */
+ int c_mode;
uid_t c_uid;
gid_t c_gid;
- unsigned int c_nlink; /* not sure how this makes CPIO-sense, ignoring */
- unsigned long c_mtime;
+ /* not sure how this makes CPIO-sense, ignoring */
+ unsigned int c_nlink;
+ unsigned long c_mtime;
size_t c_filesize;
- unsigned long c_dev_maj;
- unsigned long c_dev_min;
- unsigned long c_rdev_maj;
- unsigned long c_rdev_min;
+ unsigned long c_dev_maj;
+ unsigned long c_dev_min;
+ unsigned long c_rdev_maj;
+ unsigned long c_rdev_min;
char *c_filename;
void *c_filestart;
};
diff --git a/kern/include/debug.h b/kern/include/debug.h
index 4c3fb7b..d10c39d 100644
--- a/kern/include/debug.h
+++ b/kern/include/debug.h
@@ -2,8 +2,8 @@
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
@@ -15,14 +15,14 @@
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
diff --git a/kern/include/devalarm.h b/kern/include/devalarm.h
index 1b99215..e947b8a 100644
--- a/kern/include/devalarm.h
+++ b/kern/include/devalarm.h
@@ -15,23 +15,23 @@
struct proc_alarm {
TAILQ_ENTRY(proc_alarm) link;
- int id;
- struct kref kref;
- struct alarm_waiter a_waiter;
- struct cond_var cv;
- qlock_t qlock;
- struct proc *proc;
- struct fdtap_slist fd_taps;
- unsigned long period;
- unsigned long count;
+ int id;
+ struct kref kref;
+ struct alarm_waiter a_waiter;
+ struct cond_var cv;
+ qlock_t qlock;
+ struct proc *proc;
+ struct fdtap_slist fd_taps;
+ unsigned long period;
+ unsigned long count;
};
TAILQ_HEAD(proc_alarm_list, proc_alarm);
struct proc_alarm_set {
struct proc_alarm_list list;
- spinlock_t lock;
- struct timer_chain *tchain;
- int id_counter;
+ spinlock_t lock;
+ struct timer_chain *tchain;
+ int id_counter;
};
void devalarm_init(struct proc *p);
diff --git a/kern/include/elf.h b/kern/include/elf.h
index 01b8aa1..4d0cb09 100644
--- a/kern/include/elf.h
+++ b/kern/include/elf.h
@@ -151,5 +151,4 @@
int load_elf(struct proc *p, struct file_or_chan *f,
int argc, char *argv[], int envc, char *envp[]);
ssize_t get_startup_argc(struct proc *p);
-char *get_startup_argv(struct proc *p, size_t idx, char *argp,
- size_t max_size);
+char *get_startup_argv(struct proc *p, size_t idx, char *argp, size_t max_size);
diff --git a/kern/include/env.h b/kern/include/env.h
index 30a5ac0..88418da 100644
--- a/kern/include/env.h
+++ b/kern/include/env.h
@@ -38,7 +38,7 @@
TAILQ_ENTRY(proc) proc_arsc_link;
TAILQ_ENTRY(proc) sibling_link;
spinlock_t proc_lock;
- struct user_context scp_ctx; /* context for an SCP. TODO: move to vc0 */
+ struct user_context scp_ctx; /* context for an SCP. TODO: move to vc0 */
struct username user;
/* This is effectively a (potentially short) version of argv[0].
@@ -51,17 +51,17 @@
char *binary_path;
pid_t pid;
- /* Tempting to add a struct proc *parent, but we'd need to protect the use
- * of that reference from concurrent parent-death (letting init inherit
- * children, etc), which is basically what we do when we do pid2proc. If we
- * do add *parent, it'll be a weak ref, and you'll need to lock the child to
- * kref_get or to remove the pointer. */
- pid_t ppid; /* parent's pid, not a reference */
- struct proc_list children; /* protected by the proc lock for now */
- int exitcode; /* exit() param or main() return value */
- struct cond_var child_wait; /* signal for dying or o/w waitable child */
+ /* Tempting to add a struct proc *parent, but we'd need to protect the
+ * use of that reference from concurrent parent-death (letting init
+ * inherit children, etc), which is basically what we do when we do
+ * pid2proc. If we do add *parent, it'll be a weak ref, and you'll need
+ * to lock the child to kref_get or to remove the pointer. */
+ pid_t ppid; /* parent's pid, not a reference */
+ struct proc_list children; /* protected by the proc lock for now */
+ int exitcode; /* exit() param or main() return value */
+ struct cond_var child_wait; /* signal for dying or o/w waitable child */
uint32_t state; // Status of the process
- struct kref p_kref; /* Refcnt */
+ struct kref p_kref; /* Refcnt */
uint32_t env_flags;
/* Lists of vcores */
struct vcore_tailq online_vcs;
@@ -77,8 +77,8 @@
void *args_base;
// Address space
- pgdir_t env_pgdir; // Kernel virtual address of page dir
- physaddr_t env_cr3; // Physical address of page dir
+ pgdir_t env_pgdir; // Kernel virtual address of page dir
+ physaddr_t env_cr3; // Physical address of page dir
spinlock_t vmr_lock; /* Protects VMR tree (mem mgmt) */
spinlock_t pte_lock; /* Protects page tables (mem mgmt) */
struct vmr_tailq vm_regions;
@@ -88,34 +88,36 @@
procinfo_t *procinfo; // KVA of per-process shared info table (RO)
procdata_t *procdata; // KVA of per-process shared data table (RW)
- // The backring pointers for processing asynchronous system calls from the user
- // Note this is the actual backring, not a pointer to it somewhere else
+ // The backring pointers for processing asynchronous system calls from
+ // the user Note this is the actual backring, not a pointer to it
+ // somewhere else
syscall_back_ring_t syscallbackring;
- // The front ring pointers for pushing asynchronous system events out to the user
- // Note this is the actual frontring, not a pointer to it somewhere else
+ // The front ring pointers for pushing asynchronous system events out to
+ // the user Note this is the actual frontring, not a pointer to it
+ // somewhere else
sysevent_front_ring_t syseventfrontring;
/* Filesystem info */
- int umask;
- struct fd_table open_files;
- struct pgrp *pgrp;
- struct chan *slash;
- struct chan *dot;
+ int umask;
+ struct fd_table open_files;
+ struct pgrp *pgrp;
+ struct chan *slash;
+ struct chan *dot;
/* UCQ hashlocks */
- struct hashlock *ucq_hashlock;
- struct small_hashlock ucq_hl_noref; /* don't reference directly */
+ struct hashlock *ucq_hashlock;
+ struct small_hashlock ucq_hl_noref; /* don't reference directly */
/* For devalarm */
- struct proc_alarm_set alarmset;
- struct cv_lookup_tailq abortable_sleepers;
- spinlock_t abort_list_lock;
+ struct proc_alarm_set alarmset;
+ struct cv_lookup_tailq abortable_sleepers;
+ spinlock_t abort_list_lock;
/* VMMCP */
struct vmm vmm;
- struct strace *strace;
+ struct strace *strace;
};
/* Til we remove all Env references */
@@ -124,16 +126,17 @@
/* Process Flags */
#define PROC_TRANSITION_TO_M (1 << 0)
-#define PROC_TRACED (1 << 1)
+#define PROC_TRACED (1 << 1)
-extern atomic_t num_envs; // Number of envs
+extern atomic_t num_envs; // Number of envs
-int env_setup_vm(env_t *e);
-void env_user_mem_free(env_t* e, void* start, size_t len);
-void env_pagetable_free(env_t* e);
+int env_setup_vm(env_t *e);
+void env_user_mem_free(env_t* e, void* start, size_t len);
+void env_pagetable_free(env_t* e);
typedef int (*mem_walk_callback_t)(env_t* e, pte_t pte, void* va, void* arg);
-int env_user_mem_walk(env_t* e, void* start, size_t len, mem_walk_callback_t callback, void* arg);
+int env_user_mem_walk(env_t* e, void* start, size_t len,
+ mem_walk_callback_t callback, void* arg);
static inline void set_traced_proc(struct proc *p, bool traced)
{
diff --git a/kern/include/err.h b/kern/include/err.h
index c712360..317d186 100644
--- a/kern/include/err.h
+++ b/kern/include/err.h
@@ -17,19 +17,19 @@
#define error_jmp() longjmp(&get_cur_errbuf()->jmpbuf, 1)
-#define error(e, x, ...) \
- do { \
- set_error(e, x, ##__VA_ARGS__); \
- error_jmp(); \
+#define error(e, x, ...) \
+ do { \
+ set_error(e, x, ##__VA_ARGS__); \
+ error_jmp(); \
} while(0)
-#define nexterror() longjmp(&(errpop(errstack, ARRAY_SIZE(errstack), &curindex, \
- prev_errbuf)->jmpbuf), 1)
+#define nexterror() longjmp(&(errpop(errstack, ARRAY_SIZE(errstack), &curindex,\
+ prev_errbuf)->jmpbuf), 1)
#define poperror() errpop(errstack, ARRAY_SIZE(errstack), &curindex, \
- prev_errbuf)
+ prev_errbuf)
/* Give Akaros people a hint that we need a real error message. */
#define ERROR_FIXME "This space in %s@%d needs filling in.", __FILE__, __LINE__
struct errbuf *errpush(struct errbuf *errstack, int stacksize, int *curindex,
- struct errbuf **prev_errbuf);
+ struct errbuf **prev_errbuf);
struct errbuf *errpop(struct errbuf *errstack, int stacksize, int *curindex,
- struct errbuf *prev_errbuf);
+ struct errbuf *prev_errbuf);
diff --git a/kern/include/fdtap.h b/kern/include/fdtap.h
index 2eed853..d63d885 100644
--- a/kern/include/fdtap.h
+++ b/kern/include/fdtap.h
@@ -19,15 +19,15 @@
SLIST_HEAD(fdtap_slist, fd_tap);
struct fd_tap {
- SLIST_ENTRY(fd_tap) link; /* for device use */
- struct kref kref;
- struct chan *chan;
- int fd;
- int filter;
- struct proc *proc;
- struct event_queue *ev_q;
- int ev_id;
- void *data;
+ SLIST_ENTRY(fd_tap) link; /* for device use */
+ struct kref kref;
+ struct chan *chan;
+ int fd;
+ int filter;
+ struct proc *proc;
+ struct event_queue *ev_q;
+ int ev_id;
+ void *data;
};
int add_fd_tap(struct proc *p, struct fd_tap_req *tap_req);
diff --git a/kern/include/fs_file.h b/kern/include/fs_file.h
index 9b4f06a..f8a7bf9 100644
--- a/kern/include/fs_file.h
+++ b/kern/include/fs_file.h
@@ -76,19 +76,19 @@
bool (*can_grow_to)(struct fs_file *f, size_t len);
};
-#define FSF_DIRTY (1 << 1)
+#define FSF_DIRTY (1 << 1)
struct fs_file {
- struct dir dir;
- int flags;
- qlock_t qlock;
- struct fs_file_ops *ops;
- struct page_map *pm;
- void *priv;
+ struct dir dir;
+ int flags;
+ qlock_t qlock;
+ struct fs_file_ops *ops;
+ struct page_map *pm;
+ void *priv;
/* optional inline storage */
- char static_name[KNAMELEN]; /* for dir->name */
- struct page_map static_pm; /* for pm */
+ char static_name[KNAMELEN]; /* dir->name */
+ struct page_map static_pm; /* for pm */
/* we need to be aligned to 64 bytes for the linker tables. */
} __attribute__ ((aligned(64)));
@@ -115,10 +115,10 @@
void fs_file_copy_from_dir(struct fs_file *f, struct dir *dir);
void cleanup_fs_file(struct fs_file *f);
-#define FSF_ATIME (1 << 0)
-#define FSF_BTIME (1 << 1)
-#define FSF_CTIME (1 << 2)
-#define FSF_MTIME (1 << 3)
+#define FSF_ATIME (1 << 0)
+#define FSF_BTIME (1 << 1)
+#define FSF_CTIME (1 << 2)
+#define FSF_MTIME (1 << 3)
void __set_acmtime_to(struct fs_file *f, int which, struct timespec *t);
void __set_acmtime(struct fs_file *f, int which);
diff --git a/kern/include/hash_helper.h b/kern/include/hash_helper.h
index c31c9a7..f3478d8 100644
--- a/kern/include/hash_helper.h
+++ b/kern/include/hash_helper.h
@@ -7,10 +7,10 @@
#pragma once
struct hash_helper {
- unsigned int nr_hash_lists;
- unsigned int nr_hash_bits;
- size_t nr_items;
- size_t load_limit;
+ unsigned int nr_hash_lists;
+ unsigned int nr_hash_bits;
+ size_t nr_items;
+ size_t load_limit;
};
#define HASH_MAX_LOAD_FACTOR(size) ((size * 13) / 20)
diff --git a/kern/include/hashtable.h b/kern/include/hashtable.h
index 3e94257..f989463 100644
--- a/kern/include/hashtable.h
+++ b/kern/include/hashtable.h
@@ -39,7 +39,7 @@
/*****************************************************************************/
/* Example of use:
- * hashtable_init(); // Do this once during kernel initialization
+ * hashtable_init(); // Do this once during kernel initialization
*
* struct hashtable *h;
* struct some_key *k;
diff --git a/kern/include/kdebug.h b/kern/include/kdebug.h
index 083a5da..9251089 100644
--- a/kern/include/kdebug.h
+++ b/kern/include/kdebug.h
@@ -42,12 +42,12 @@
size_t nr_slots);
/* Backtraces a user PC/FP, stores results in *pcs */
size_t backtrace_user_list(uintptr_t pc, uintptr_t fp, uintptr_t *pcs,
- size_t nr_slots);
+ size_t nr_slots);
/* Prints out a backtrace list, using pfunc(opaque, "line") for the printk.
* This does a symbol lookup on the kernel binary, so it is less useful for a
* user backtrace. */
void print_backtrace_list(uintptr_t *pcs, size_t nr_pcs,
- void (*pfunc)(void *, const char *), void *opaque);
+ void (*pfunc)(void *, const char *), void *opaque);
void sza_print_backtrace_list(struct sized_alloc *sza, uintptr_t *pcs,
size_t nr_pcs);
/* Backtraces the calling kernel context, using pfunc for printing */
@@ -75,13 +75,13 @@
extern bool printx_on;
void set_printx(int mode);
#define printx(args...) \
- do { \
- if (printx_on) \
- printk(args); \
+ do { \
+ if (printx_on) \
+ printk(args); \
} while (0)
#define trace_printx(args...) \
- do { \
- if (printx_on) \
+ do { \
+ if (printx_on) \
trace_printk(args); \
} while (0)
diff --git a/kern/include/kmalloc.h b/kern/include/kmalloc.h
index 97d2d1a..5fcdaa8 100644
--- a/kern/include/kmalloc.h
+++ b/kern/include/kmalloc.h
@@ -29,9 +29,9 @@
void kmalloc_canary_check(char *str);
void *debug_canary;
-#define MEM_ATOMIC (1 << 1)
-#define MEM_WAIT (1 << 2)
-#define MEM_ERROR (1 << 3)
+#define MEM_ATOMIC (1 << 1)
+#define MEM_WAIT (1 << 2)
+#define MEM_ERROR (1 << 3)
#define MEM_FLAGS (MEM_ATOMIC | MEM_WAIT | MEM_ERROR)
/* Kmalloc tag flags looks like this:
@@ -40,11 +40,11 @@
* | Flag specific data | Flags |
* +-------------------------------+------------+
*/
-#define KMALLOC_TAG_CACHE 1 /* memory came from slabs */
-#define KMALLOC_TAG_PAGES 2 /* memory came from page allocator */
-#define KMALLOC_TAG_UNALIGN 3 /* not a real tag, jump back by offset */
-#define KMALLOC_ALIGN_SHIFT 4 /* max flag is 16 */
-#define KMALLOC_FLAG_MASK ((1 << KMALLOC_ALIGN_SHIFT) - 1)
+#define KMALLOC_TAG_CACHE 1 /* memory came from slabs */
+#define KMALLOC_TAG_PAGES 2 /* memory came from page allocator */
+#define KMALLOC_TAG_UNALIGN 3 /* not a real tag, jump back by offset */
+#define KMALLOC_ALIGN_SHIFT 4 /* max flag is 16 */
+#define KMALLOC_FLAG_MASK ((1 << KMALLOC_ALIGN_SHIFT) - 1)
#define KMALLOC_CANARY 0xdeadbabe
@@ -63,9 +63,9 @@
/* This is aligned so that the buf is aligned to the usual kmalloc alignment. */
struct sized_alloc {
- void *buf;
- size_t size;
- size_t sofar;
+ void *buf;
+ size_t size;
+ size_t sofar;
} __attribute__((aligned(KMALLOC_ALIGNMENT)));
/* Allocate a sized_alloc, big enough to hold size bytes. Free with kfree. */
diff --git a/kern/include/kstack.h b/kern/include/kstack.h
index 1a089fc..5f92b9f 100644
--- a/kern/include/kstack.h
+++ b/kern/include/kstack.h
@@ -1,5 +1,5 @@
#pragma once
-#define KSTKSHIFT (PGSHIFT + 1) /* KSTKSIZE == 2 * PGSIZE */
+#define KSTKSHIFT (PGSHIFT + 1) /* KSTKSIZE == 2 * PGSIZE */
-#define KSTKSIZE (1 << KSTKSHIFT) /* size of a static kernel stack */
+#define KSTKSIZE (1 << KSTKSHIFT) /* size of a static kernel stack */
diff --git a/kern/include/ktest.h b/kern/include/ktest.h
index a06e17d..e86434a 100644
--- a/kern/include/ktest.h
+++ b/kern/include/ktest.h
@@ -16,22 +16,22 @@
/* Macros for assertions.
*/
-#define KT_ASSERT(test) \
+#define KT_ASSERT(test) \
KT_ASSERT_M("", test)
-#define KT_ASSERT_M(message, test) \
- do { \
- if (!(test)) { \
- char fmt[] = "Assertion failure in %s() at %s:%d: %s"; \
- snprintf(ktest_msg, sizeof(ktest_msg), fmt, __FUNCTION__, \
- __FILE__, __LINE__, message); \
- return false; \
- } \
- } while (0)
+#define KT_ASSERT_M(message, test) \
+do { \
+ if (!(test)) { \
+ char fmt[] = "Assertion failure in %s() at %s:%d: %s"; \
+ snprintf(ktest_msg, sizeof(ktest_msg), fmt, __FUNCTION__, \
+ __FILE__, __LINE__, message); \
+ return false; \
+ } \
+} while (0)
struct ktest {
char name[256]; // Name of the test function.
- bool (*func)(void); // Name of the test function, should be equal to 'name'.
+ bool (*func)(void); // Name of the test function, should be = to 'name'.
bool enabled; // Whether to run or not the test.
};
@@ -48,12 +48,12 @@
#define KTEST_REG(name, config) \
{"test_" #name, test_##name, is_defined(config)}
-#define REGISTER_KTESTS(ktests, num_ktests) \
- do { \
- ktest_suite.ktests = ktests; \
- ktest_suite.num_ktests = num_ktests; \
- register_ktest_suite(&ktest_suite); \
- } while (0)
+#define REGISTER_KTESTS(ktests, num_ktests) \
+do { \
+ ktest_suite.ktests = ktests; \
+ ktest_suite.num_ktests = num_ktests; \
+ register_ktest_suite(&ktest_suite); \
+} while (0)
/* Global string used to report info about the last completed test */
extern char ktest_msg[1024];
diff --git a/kern/include/kthread.h b/kern/include/kthread.h
index c33e385..85c2f19 100644
--- a/kern/include/kthread.h
+++ b/kern/include/kthread.h
@@ -41,18 +41,18 @@
* a kthread is running, we make sure its stacktop is the default kernel stack,
* meaning it will receive the interrupts from userspace. */
struct kthread {
- struct jmpbuf context;
- uintptr_t stacktop;
- struct proc *proc;
- struct syscall *sysc;
- struct errbuf *errbuf;
+ struct jmpbuf context;
+ uintptr_t stacktop;
+ struct proc *proc;
+ struct syscall *sysc;
+ struct errbuf *errbuf;
TAILQ_ENTRY(kthread) link;
/* ID, other shit, etc */
- int flags;
- char *name;
- char generic_buf[GENBUF_SZ];
- int errno;
- char errstr[MAX_ERRSTR_LEN];
+ int flags;
+ char *name;
+ char generic_buf[GENBUF_SZ];
+ int errno;
+ char errstr[MAX_ERRSTR_LEN];
struct systrace_record *strace;
};
@@ -63,8 +63,8 @@
struct kth_db_info {
TAILQ_ENTRY(kth_db_info) link;
- unsigned int type;
- bool on_list;
+ unsigned int type;
+ bool on_list;
};
#define KTH_DB_INIT .db = { .type = KTH_DB_SEM },
@@ -81,44 +81,44 @@
/* Semaphore for kthreads to sleep on. 0 or less means you need to sleep */
struct semaphore {
- struct kth_db_info db;
+ struct kth_db_info db;
struct kthread_tailq waiters;
- int nr_signals;
- spinlock_t lock;
+ int nr_signals;
+ spinlock_t lock;
};
#define SEMAPHORE_INITIALIZER(name, n) \
{ \
.waiters = TAILQ_HEAD_INITIALIZER((name).waiters), \
- .nr_signals = (n), \
+ .nr_signals = (n), \
.lock = SPINLOCK_INITIALIZER, \
- KTH_DB_INIT \
+ KTH_DB_INIT \
}
#define SEMAPHORE_INITIALIZER_IRQSAVE(name, n) \
{ \
.waiters = TAILQ_HEAD_INITIALIZER((name).waiters), \
- .nr_signals = (n), \
+ .nr_signals = (n), \
.lock = SPINLOCK_INITIALIZER_IRQSAVE, \
- KTH_DB_INIT \
+ KTH_DB_INIT \
}
struct cond_var {
- struct kth_db_info db;
+ struct kth_db_info db;
struct kthread_tailq waiters;
- spinlock_t *lock; /* usually points to internal_ */
- spinlock_t internal_lock;
- unsigned long nr_waiters;
+ spinlock_t *lock; /* usually points to internal */
+ spinlock_t internal_lock;
+ unsigned long nr_waiters;
};
struct cv_lookup_elm {
TAILQ_ENTRY(cv_lookup_elm) link;
- TAILQ_ENTRY(cv_lookup_elm) abortall_link; /* only used in abort_all */
- struct cond_var *cv;
- struct kthread *kthread;
- struct syscall *sysc;
- struct proc *proc;
- atomic_t abort_in_progress; /* 0 = no */
+ TAILQ_ENTRY(cv_lookup_elm) abortall_link;
+ struct cond_var *cv;
+ struct kthread *kthread;
+ struct syscall *sysc;
+ struct proc *proc;
+ atomic_t abort_in_progress; /* 0 = no */
};
TAILQ_HEAD(cv_lookup_tailq, cv_lookup_elm);
diff --git a/kern/include/linker_func.h b/kern/include/linker_func.h
index 638763e..72e3e68 100644
--- a/kern/include/linker_func.h
+++ b/kern/include/linker_func.h
@@ -37,23 +37,23 @@
typedef void (*linker_func_t)(void);
#define linker_func_1(x) \
- void (x)(void); \
- linker_func_t __linkerfunc1 __##x = (x); \
+ void (x)(void); \
+ linker_func_t __linkerfunc1 __##x = (x); \
void (x)(void)
#define linker_func_2(x) \
- void (x)(void); \
- linker_func_t __linkerfunc2 __##x = (x); \
+ void (x)(void); \
+ linker_func_t __linkerfunc2 __##x = (x); \
void (x)(void)
#define linker_func_3(x) \
- void (x)(void); \
- linker_func_t __linkerfunc3 __##x = (x); \
+ void (x)(void); \
+ linker_func_t __linkerfunc3 __##x = (x); \
void (x)(void)
#define linker_func_4(x) \
- void (x)(void); \
- linker_func_t __linkerfunc4 __##x = (x); \
+ void (x)(void); \
+ linker_func_t __linkerfunc4 __##x = (x); \
void (x)(void)
extern linker_func_t __linkerfunc1start[];
diff --git a/kern/include/linux_compat.h b/kern/include/linux_compat.h
index d4ca975..0d9232c 100644
--- a/kern/include/linux_compat.h
+++ b/kern/include/linux_compat.h
@@ -44,12 +44,12 @@
#define atomic_cmpxchg(_addr, _old, _new) \
({ \
- typeof(_old) _ret; \
- if (atomic_cas((_addr), (_old), (_new))) \
- _ret = _old; \
- else \
- _ret = atomic_read(_addr); \
- _ret; \
+ typeof(_old) _ret; \
+ if (atomic_cas((_addr), (_old), (_new))) \
+ _ret = _old; \
+ else \
+ _ret = atomic_read(_addr); \
+ _ret; \
})
#define UINT_MAX UINT64_MAX
@@ -100,6 +100,7 @@
gfp_t flags)
{
void *vaddr = __dma_alloc_coherent(size, dma_handle, flags);
+
if (vaddr)
memset(vaddr, 0, size);
return vaddr;
@@ -162,6 +163,7 @@
static void *vmalloc(size_t size)
{
void *vaddr = get_cont_pages(LOG2_UP(nr_pages(size)), MEM_WAIT);
+
/* zalloc, to be safe */
if (vaddr)
memset(vaddr, 0, size);
@@ -466,31 +468,31 @@
/* Sockaddr structs */
struct sockaddr {
- uint16_t sa_family;
- char sa_data[14];
+ uint16_t sa_family;
+ char sa_data[14];
};
struct in_addr {
uint32_t s_addr;
};
struct sockaddr_in {
- uint16_t sin_family;
- uint16_t sin_port;
- struct in_addr sin_addr;
- uint8_t sin_zero[8]; /* padding */
+ uint16_t sin_family;
+ uint16_t sin_port;
+ struct in_addr sin_addr;
+ uint8_t sin_zero[8]; /* padding */
};
struct in6_addr {
/* this is actually a weird union in glibc */
- uint8_t s6_addr[16];
+ uint8_t s6_addr[16];
};
struct sockaddr_in6 {
- uint16_t sin6_family;
- uint16_t sin6_port;
- uint32_t sin6_flowinfo;
- struct in6_addr sin6_addr;
- uint32_t sin6_scope_id;
+ uint16_t sin6_family;
+ uint16_t sin6_port;
+ uint32_t sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ uint32_t sin6_scope_id;
};
/* Common way to go from netdev (ether / netif) to driver-private ctlr */
@@ -522,23 +524,23 @@
* checksum was already done. There is no flag for saying the device can do
* it. For transmits, the stack needs to know in advance if the device can
* handle the checksum or not. */
-#define NETIF_F_RXHASH 0
-#define NETIF_F_RXCSUM NETF_RXCSUM
-#define NETIF_F_LRO NETF_LRO
-#define NETIF_F_GRO 0
-#define NETIF_F_LOOPBACK 0
-#define NETIF_F_TSO NETF_TSO
-#define NETIF_F_SG NETF_SG
-#define NETIF_F_IP_CSUM (NETF_IPCK | NETF_UDPCK | NETF_TCPCK)
-#define NETIF_F_IPV6_CSUM (NETF_IPCK | NETF_UDPCK | NETF_TCPCK)
-#define NETIF_F_GSO_GRE 0
+#define NETIF_F_RXHASH 0
+#define NETIF_F_RXCSUM NETF_RXCSUM
+#define NETIF_F_LRO NETF_LRO
+#define NETIF_F_GRO 0
+#define NETIF_F_LOOPBACK 0
+#define NETIF_F_TSO NETF_TSO
+#define NETIF_F_SG NETF_SG
+#define NETIF_F_IP_CSUM (NETF_IPCK | NETF_UDPCK | NETF_TCPCK)
+#define NETIF_F_IPV6_CSUM (NETF_IPCK | NETF_UDPCK | NETF_TCPCK)
+#define NETIF_F_GSO_GRE 0
#define NETIF_F_GSO_UDP_TUNNEL 0
-#define NETIF_F_GSO_IPIP 0
-#define NETIF_F_GSO_SIT 0
-#define NETIF_F_TSO_ECN 0
-#define NETIF_F_TSO6 0
+#define NETIF_F_GSO_IPIP 0
+#define NETIF_F_GSO_SIT 0
+#define NETIF_F_TSO_ECN 0
+#define NETIF_F_TSO6 0
#define NETIF_F_HW_VLAN_CTAG_TX 0
-#define NETIF_F_HIGHDMA 0
+#define NETIF_F_HIGHDMA 0
#define NETIF_F_HW_VLAN_CTAG_RX 0
#define NETIF_F_TSO_MANGLEID 0
#define NETIF_F_ALL_TSO (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN | NETIF_F_TSO_MANGLEID)
@@ -551,11 +553,11 @@
#define netif_msg_ifup(p) ((p)->msg_enable & NETIF_MSG_IFUP)
#define netif_msg_rx_err(p) ((p)->msg_enable & NETIF_MSG_RX_ERR)
#define netif_msg_tx_err(p) ((p)->msg_enable & NETIF_MSG_TX_ERR)
-#define netif_msg_tx_queued(p) ((p)->msg_enable & NETIF_MSG_TX_QUEUED)
+#define netif_msg_tx_queued(p) ((p)->msg_enable & NETIF_MSG_TX_QUEUED)
#define netif_msg_intr(p) ((p)->msg_enable & NETIF_MSG_INTR)
-#define netif_msg_tx_done(p) ((p)->msg_enable & NETIF_MSG_TX_DONE)
-#define netif_msg_rx_status(p) ((p)->msg_enable & NETIF_MSG_RX_STATUS)
-#define netif_msg_pktdata(p) ((p)->msg_enable & NETIF_MSG_PKTDATA)
+#define netif_msg_tx_done(p) ((p)->msg_enable & NETIF_MSG_TX_DONE)
+#define netif_msg_rx_status(p) ((p)->msg_enable & NETIF_MSG_RX_STATUS)
+#define netif_msg_pktdata(p) ((p)->msg_enable & NETIF_MSG_PKTDATA)
#define netif_msg_hw(p) ((p)->msg_enable & NETIF_MSG_HW)
#define netif_msg_wol(p) ((p)->msg_enable & NETIF_MSG_WOL)
@@ -581,9 +583,9 @@
enum netdev_tx {
__NETDEV_TX_MIN = INT32_MIN, /* make sure enum is signed */
- NETDEV_TX_OK = 0x00, /* driver took care of packet */
- NETDEV_TX_BUSY = 0x10, /* driver tx path was busy*/
- NETDEV_TX_LOCKED = 0x20, /* driver tx lock was already taken */
+ NETDEV_TX_OK = 0x00, /* driver took care of packet */
+ NETDEV_TX_BUSY = 0x10, /* driver tx path was busy*/
+ NETDEV_TX_LOCKED = 0x20, /* driver tx lock was already taken */
};
typedef enum netdev_tx netdev_tx_t;
@@ -600,10 +602,10 @@
* devices, and this table is handled by higher level systems. We don't have
* those systems, but we probably want the table still for our own parsing. */
struct pci_device_id {
- uint32_t vendor, device; /* Vendor and device ID or PCI_ANY_ID*/
+ uint32_t vendor, device; /* Vendor and device ID or PCI_ANY_ID*/
uint32_t subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
- uint32_t class, class_mask; /* (class,subclass,prog-if) triplet */
- unsigned long driver_data; /* Data private to the driver */
+ uint32_t class, class_mask; /* (class,subclass,prog-if) triplet */
+ unsigned long driver_data; /* Data private to the driver */
};
static const struct pci_device_id *
@@ -612,7 +614,8 @@
const struct pci_device_id *i;
for (i = tbl; i->vendor; i++) {
- if ((needle->ven_id == i->vendor) && (needle->dev_id == i->device))
+ if ((needle->ven_id == i->vendor) && (needle->dev_id ==
+ i->device))
break;
}
if (i->vendor)
@@ -710,8 +713,8 @@
}
#define IORESOURCE_TYPE_BITS 0x00001f00 /* Resource type */
-#define IORESOURCE_IO 0x00000100 /* PCI/ISA I/O ports */
-#define IORESOURCE_MEM 0x00000200
+#define IORESOURCE_IO 0x00000100 /* PCI/ISA I/O ports */
+#define IORESOURCE_MEM 0x00000200
static inline int pci_resource_flags(struct pci_device *pdev, int bir)
{
@@ -859,7 +862,7 @@
static inline int request_firmware(const struct firmware **fwp,
const char *file_name,
- struct device *ignored)
+ struct device *ignored)
{
struct firmware *ret_fw;
struct file_or_chan *fw_file;
diff --git a/kern/include/mm.h b/kern/include/mm.h
index 88c7dec..9569aa1 100644
--- a/kern/include/mm.h
+++ b/kern/include/mm.h
@@ -17,7 +17,7 @@
struct chan;
struct fd_table;
-struct proc; /* preprocessor games */
+struct proc; /* preprocessor games */
#define F_OR_C_CHAN 2
@@ -47,17 +47,17 @@
struct vm_region {
TAILQ_ENTRY(vm_region) vm_link;
TAILQ_ENTRY(vm_region) vm_pm_link;
- struct proc *vm_proc; /* owning process, for now */
- uintptr_t vm_base;
- uintptr_t vm_end;
- int vm_prot;
- int vm_flags;
- struct file_or_chan *__vm_foc;
- size_t vm_foff;
- bool vm_ready; /* racy, for the PM checks */
- bool vm_shootdown_needed;
+ struct proc *vm_proc;
+ uintptr_t vm_base;
+ uintptr_t vm_end;
+ int vm_prot;
+ int vm_flags;
+ struct file_or_chan *__vm_foc;
+ size_t vm_foff;
+ bool vm_ready; /* racy, for the PM checks */
+ bool vm_shootdown_needed;
};
-TAILQ_HEAD(vmr_tailq, vm_region); /* Declares 'struct vmr_tailq' */
+TAILQ_HEAD(vmr_tailq, vm_region); /* Declares 'struct vmr_tailq' */
static inline bool vmr_has_file(struct vm_region *vmr)
{
@@ -74,9 +74,8 @@
void unmap_and_destroy_vmrs(struct proc *p);
int duplicate_vmrs(struct proc *p, struct proc *new_p);
void print_vmrs(struct proc *p);
-void enumerate_vmrs(struct proc *p,
- void (*func)(struct vm_region *vmr, void *opaque),
- void *opaque);
+void enumerate_vmrs(struct proc *p, void (*func)(struct vm_region *vmr, void
+ *opaque), void *opaque);
/* mmap() related functions. These manipulate VMRs and change the hardware page
* tables. Any requests below the LOWEST_VA will silently be upped. This may
diff --git a/kern/include/net/ip.h b/kern/include/net/ip.h
index c650ed1..c89208f 100644
--- a/kern/include/net/ip.h
+++ b/kern/include/net/ip.h
@@ -80,40 +80,40 @@
struct conv {
qlock_t qlock;
- int x; /* conversation index */
+ int x; /* conversation index */
struct Proto *p;
- int restricted; /* remote port is restricted */
- uint32_t ttl; /* max time to live */
- uint32_t tos; /* type of service */
- int ignoreadvice; /* don't terminate connection on icmp errors */
+ int restricted; /* remote port is restricted */
+ uint32_t ttl; /* max time to live */
+ uint32_t tos; /* type of service */
+ int ignoreadvice; /* don't terminate connection on icmp errors */
uint8_t ipversion;
- uint8_t laddr[IPaddrlen]; /* local IP address */
- uint8_t raddr[IPaddrlen]; /* remote IP address */
- uint16_t lport; /* local port number */
- uint16_t rport; /* remote port number */
+ uint8_t laddr[IPaddrlen];/* local IP address */
+ uint8_t raddr[IPaddrlen];/* remote IP address */
+ uint16_t lport; /* local port number */
+ uint16_t rport; /* remote port number */
- char *owner; /* protections */
+ char *owner; /* protections */
int perm;
- int inuse; /* opens of listen/data/ctl */
+ int inuse; /* opens of listen/data/ctl */
int length;
int state;
- struct queue *rq_save; /* rq created by proto, saved during bypass */
- struct queue *wq_save; /* wq created by proto, saved during bypass */
+ struct queue *rq_save; /* rq created by proto, saved during bypass */
+ struct queue *wq_save; /* wq created by proto, saved during bypass */
/* udp specific */
- int headers; /* data src/dst headers in udp */
- int reliable; /* true if reliable udp */
+ int headers; /* data src/dst headers in udp */
+ int reliable; /* true if reliable udp */
- struct conv *incall; /* calls waiting to be listened for */
+ struct conv *incall; /* calls waiting to be listened for */
struct conv *next;
- struct queue *rq; /* queued data waiting to be read */
- struct queue *wq; /* queued data waiting to be written */
- struct queue *eq; /* returned error packets */
- struct queue *sq; /* snooping queue */
- atomic_t snoopers; /* number of processes with snoop open */
+ struct queue *rq; /* queued data waiting to be read */
+ struct queue *wq; /* queued data waiting to be written */
+ struct queue *eq; /* returned error packets */
+ struct queue *sq; /* snooping queue */
+ atomic_t snoopers; /* number of processes with snoop open */
struct fdtap_slist data_taps;
struct fdtap_slist listen_taps;
@@ -125,12 +125,12 @@
qlock_t listenq;
struct rendez listenr;
- struct Ipmulti *multi; /* multicast bindings for this interface */
+ struct Ipmulti *multi; /* multicast bindings for this interface */
- void *ptcl; /* Protocol specific stuff */
+ void *ptcl; /* Protocol specific stuff */
- struct route *r; /* last route used */
- uint32_t rgen; /* routetable generation for *r */
+ struct route *r; /* last route used */
+ uint32_t rgen; /* routetable generation for *r */
};
struct Ipifc;
@@ -138,15 +138,15 @@
struct medium {
char *name;
- int hsize; /* medium header size */
- int mintu; /* default min mtu */
- int maxtu; /* default max mtu */
- int maclen; /* mac address length */
+ int hsize; /* medium header size */
+ int mintu; /* default min mtu */
+ int maxtu; /* default max mtu */
+ int maclen; /* mac address length */
void (*bind) (struct Ipifc * unused_Ipifc, int unused_int,
- char **unused_char_pp_t);
+ char **unused_char_pp_t);
void (*unbind) (struct Ipifc * unused_Ipifc);
- void (*bwrite) (struct Ipifc * ifc,
- struct block * b, int version, uint8_t * ip);
+ void (*bwrite) (struct Ipifc * ifc, struct block * b, int version,
+ uint8_t * ip);
/* for arming interfaces to receive multicast */
void (*addmulti) (struct Ipifc * ifc, uint8_t * a, uint8_t * ia);
@@ -157,9 +157,9 @@
/* routes for router boards */
void (*addroute) (struct Ipifc * ifc, int unused_int, uint8_t * u8p,
- uint8_t *, uint8_t * u8p2, int);
+ uint8_t *, uint8_t * u8p2, int);
void (*remroute) (struct Ipifc * ifc, int i, uint8_t * u8p,
- uint8_t * uu8p2);
+ uint8_t * uu8p2);
void (*flushroutes) (struct Ipifc * ifc);
/* for routing multicast groups */
@@ -167,13 +167,15 @@
void (*leavemulti) (struct Ipifc * ifc, uint8_t * a, uint8_t * ia);
/* address resolution */
- void (*ares) (struct Fs *, int unused_int, uint8_t * unused_uint8_p_t, uint8_t *, int, int); /* resolve */
- void (*areg) (struct Ipifc * unused_Ipifc, uint8_t * unused_uint8_p_t); /* register */
+ void (*ares) (struct Fs *, int unused_int, uint8_t * unused_uint8_p_t,
+ uint8_t *, int, int); /* resolve */
+ void (*areg) (struct Ipifc * unused_Ipifc,
+ uint8_t * unused_uint8_p_t); /* register */
/* v6 address generation */
void (*pref2addr) (uint8_t * pref, uint8_t * ea);
- int unbindonclose; /* if non-zero, unbind on last close */
+ int unbindonclose; /* if non-zero, unbind on last close */
};
/* logical interface associated with a physical one */
@@ -182,12 +184,12 @@
uint8_t mask[IPaddrlen];
uint8_t remote[IPaddrlen];
uint8_t net[IPaddrlen];
- uint8_t tentative; /* =1 => v6 dup disc on, =0 => confirmed unique */
- uint8_t onlink; /* =1 => onlink, =0 offlink. */
- uint8_t autoflag; /* v6 autonomous flag */
- uint64_t validlt; /* v6 valid lifetime */
- uint64_t preflt; /* v6 preferred lifetime */
- uint64_t origint; /* time when addr was added */
+ uint8_t tentative; /* =1 => v6 dup disc on, =0 => confirmed unique */
+ uint8_t onlink; /* =1 => onlink, =0 offlink. */
+ uint8_t autoflag; /* v6 autonomous flag */
+ uint64_t validlt; /* v6 valid lifetime */
+ uint64_t preflt; /* v6 preferred lifetime */
+ uint64_t origint; /* time when addr was added */
struct Iplink *link; /* addresses linked to this lifc */
struct Iplifc *next;
};
@@ -221,34 +223,34 @@
struct Ipifc {
rwlock_t rwlock;
- struct conv *conv; /* link to its conversation structure */
- char dev[64]; /* device we're attached to */
- struct medium *m; /* Media pointer */
- int maxtu; /* Maximum transfer unit */
- int mintu; /* Minumum tranfer unit */
- unsigned int feat; /* Offload features */
- void *arg; /* medium specific */
- int reassemble; /* reassemble IP packets before forwarding */
+ struct conv *conv; /* link to its conversation structure */
+ char dev[64]; /* device we're attached to */
+ struct medium *m; /* Media pointer */
+ int maxtu; /* Maximum transfer unit */
+ int mintu; /* Minumum tranfer unit */
+ unsigned int feat; /* Offload features */
+ void *arg; /* medium specific */
+ int reassemble; /* reassemble IP packets before forwarding */
/* these are used so that we can unbind on the fly */
spinlock_t idlock;
- uint8_t ifcid; /* incremented each 'bind/unbind/add/remove' */
- int ref; /* number of proc's using this Ipifc */
- struct rendez wait; /* where unbinder waits for ref == 0 */
+ uint8_t ifcid; /* incremented each 'bind/unbind/add/remove' */
+ int ref; /* number of proc's using this Ipifc */
+ struct rendez wait; /* where unbinder waits for ref == 0 */
int unbinding;
- uint8_t mac[MAClen]; /* MAC address */
+ uint8_t mac[MAClen]; /* MAC address */
- struct Iplifc *lifc; /* logical interfaces on this physical one */
+ struct Iplifc *lifc; /* logical interfaces on this physical one */
- uint32_t in, out; /* message statistics */
- uint32_t inerr, outerr; /* ... */
+ uint32_t in, out; /* message statistics */
+ uint32_t inerr, outerr; /* ... */
uint32_t tracedrop;
- uint8_t sendra6; /* == 1 => send router advs on this ifc */
- uint8_t recvra6; /* == 1 => recv router advs on this ifc */
- struct routerparams rp; /* router parameters as in RFC 2461, pp.40--43.
- used only if node is router */
+ uint8_t sendra6; /* == 1 => send router advs on this ifc */
+ uint8_t recvra6; /* == 1 => recv router advs on this ifc */
+ struct routerparams rp; /* router parameters as in RFC 2461, pp.40--43.
+ used only if node is router */
};
/*
@@ -264,7 +266,7 @@
* hash table for 2 ip addresses + 2 ports
*/
enum {
- Nipht = 521, /* convenient prime */
+ Nipht = 521, /* convenient prime */
IPmatchexact = 0, /* match on 4 tuple */
IPmatchany, /* *!* */
@@ -286,7 +288,7 @@
void iphtadd(struct Ipht *, struct conv *);
void iphtrem(struct Ipht *, struct conv *);
struct conv *iphtlook(struct Ipht *ht, uint8_t * sa, uint16_t sp, uint8_t * da,
- uint16_t dp);
+ uint16_t dp);
void dump_ipht(struct Ipht *ht);
/*
@@ -294,9 +296,9 @@
*/
struct Proto {
qlock_t qlock;
- char *name; /* protocol name */
- int x; /* protocol index */
- int ipproto; /* ip protocol type */
+ char *name; /* protocol name */
+ int x; /* protocol index */
+ int ipproto; /* ip protocol type */
void (*connect)(struct conv *, char **, int);
void (*announce)(struct conv *, char **, int);
@@ -313,14 +315,15 @@
int (*local) (struct conv *, char *unused_char_p_t, int);
int (*remote) (struct conv *, char *unused_char_p_t, int);
int (*inuse) (struct conv *);
- int (*gc) (struct Proto *); /* returns true if any conversations are freed */
+ /* returns true if any conversations are freed */
+ int (*gc) (struct Proto *);
- struct Fs *f; /* file system this proto is part of */
- struct conv **conv; /* array of conversations */
- int ptclsize; /* size of per protocol ctl block */
- int nc; /* number of conversations */
+ struct Fs *f; /* file system this proto is part of */
+ struct conv **conv; /* array of conversations */
+ int ptclsize; /* size of per protocol ctl block */
+ int nc; /* number of conversations */
int ac;
- struct qid qid; /* qid for protocol directory */
+ struct qid qid; /* qid for protocol directory */
uint16_t nextport;
uint16_t nextrport;
@@ -346,8 +349,8 @@
int np;
struct Proto *p[Maxproto + 1]; /* list of supported protocols */
struct Proto *t2p[256]; /* vector of all protocols */
- struct Proto *ipifc; /* kludge for ipifcremroute & ipifcaddroute */
- struct Proto *ipmux; /* kludge for finding an ip multiplexor */
+ struct Proto *ipifc; /* kludge for ipifcremroute & ipifcaddroute */
+ struct Proto *ipmux; /* kludge for finding an ip multiplexor */
struct IP *ip;
struct Ipselftab *self;
@@ -357,12 +360,12 @@
struct route *v4root[1 << Lroot]; /* v4 routing forest */
struct route *v6root[1 << Lroot]; /* v6 routing forest */
- struct route *queue; /* used as temp when reinjecting routes */
+ struct route *queue; /* used as temp when reinjecting routes */
struct Netlog *alog;
struct Ifclog *ilog;
- char ndb[1024]; /* an ndb entry for this interface */
+ char ndb[1024]; /* an ndb entry for this interface */
int ndbvers;
long ndbmtime;
};
@@ -385,13 +388,13 @@
struct routerparams rp; /* v6 params, one copy per node now */
struct hostparams hp;
struct V6router v6rlist[3]; /* max 3 default routers, currently */
- int cdrouter; /* uses only v6rlist[cdrouter] if */
+ int cdrouter; /* uses only v6rlist[cdrouter] if */
/* cdrouter >= 0. */
};
int Fsconnected(struct conv *, char *unused_char_p_t);
struct conv *Fsnewcall(struct conv *, uint8_t * unused_uint8_p_t, uint16_t,
- uint8_t *, uint16_t, uint8_t unused_uint8_t);
+ uint8_t *, uint16_t, uint8_t unused_uint8_t);
int Fspcolstats(char *unused_char_p_t, int);
int Fsproto(struct Fs *, struct Proto *);
int Fsbuiltinproto(struct Fs *, uint8_t unused_uint8_t);
@@ -449,8 +452,8 @@
enum {
/* type bits */
- Rv4 = (1 << 0), /* this is a version 4 route */
- Rifc = (1 << 1), /* this route is a directly connected interface */
+ Rv4 = (1 << 0), /* this is a version 4 route */
+ Rifc = (1 << 1), /* route is a directly connected interface */
Rptpt = (1 << 2), /* this route is a pt to pt interface */
Runi = (1 << 3), /* a unicast self address */
Rbcast = (1 << 4), /* a broadcast self address */
@@ -473,7 +476,7 @@
struct route *mid;
uint8_t depth;
uint8_t type;
- uint8_t ifcid; /* must match ifc->id */
+ uint8_t ifcid; /* must match ifc->id */
struct Ipifc *ifc;
char tag[4];
struct kref kref;
@@ -500,9 +503,9 @@
};
};
extern void v4addroute(struct Fs *f, char *tag, uint8_t * a, uint8_t * mask,
- uint8_t * gate, int type);
+ uint8_t * gate, int type);
extern void v6addroute(struct Fs *f, char *tag, uint8_t * a, uint8_t * mask,
- uint8_t * gate, int type);
+ uint8_t * gate, int type);
extern void v4delroute(struct Fs *f, uint8_t * a, uint8_t * mask, int dolock);
extern void v6delroute(struct Fs *f, uint8_t * a, uint8_t * mask, int dolock);
extern struct route *v4lookup(struct Fs *f, uint8_t * a, struct conv *c);
@@ -512,7 +515,7 @@
extern void routetype(int unused_int, char *unused_char_p_t);
extern void ipwalkroutes(struct Fs *, struct routewalk *);
extern void convroute(struct route *r, uint8_t * u8pt, uint8_t * u8pt1,
- uint8_t * u8pt2, char *unused_char_p_t, int *intp);
+ uint8_t * u8pt2, char *unused_char_p_t, int *intp);
/*
* devip.c
@@ -523,7 +526,7 @@
* It maintains the state used by devip and iproute.
*/
struct IPaux {
- char *owner; /* the user that did the attach */
+ char *owner; /* the user that did the attach */
char tag[4];
};
@@ -535,30 +538,30 @@
struct arpent {
uint8_t ip[IPaddrlen];
uint8_t mac[MAClen];
- struct medium *type; /* media type */
+ struct medium *type; /* media type */
struct arpent *hash;
struct block *hold;
struct block *last;
- uint64_t ctime; /* time entry was created or refreshed */
- uint64_t utime; /* time entry was last used */
+ uint64_t ctime; /* time entry was created or refreshed */
+ uint64_t utime; /* time entry was last used */
uint8_t state;
- struct arpent *nextrxt; /* re-transmit chain */
- uint64_t rtime; /* time for next retransmission */
+ struct arpent *nextrxt; /* re-transmit chain */
+ uint64_t rtime; /* time for next retransmission */
uint8_t rxtsrem;
struct Ipifc *ifc;
- uint8_t ifcid; /* must match ifc->id */
+ uint8_t ifcid; /* must match ifc->id */
};
extern void arpinit(struct Fs *);
extern int arpread(struct arp *, char *unused_char_p_t, uint32_t, int);
extern int arpwrite(struct Fs *, char *unused_char_p_t, long);
extern struct arpent *arpget(struct arp *, struct block *bp, int version,
- struct Ipifc *ifc, uint8_t * ip, uint8_t * h);
+ struct Ipifc *ifc, uint8_t * ip, uint8_t * h);
extern void arprelease(struct arp *, struct arpent *a);
extern struct block *arpresolve(struct arp *, struct arpent *a,
- struct medium *type, uint8_t * mac);
-extern void arpenter(struct Fs *, int version, uint8_t * ip,
- uint8_t * mac, int len, int norefresh);
+ struct medium *type, uint8_t * mac);
+extern void arpenter(struct Fs *, int version, uint8_t * ip, uint8_t * mac,
+ int len, int norefresh);
/*
* ipaux.c
@@ -595,6 +598,7 @@
{
uint32_t *a = (uint32_t *)x;
uint32_t *b = (uint32_t *)y;
+
return (a[0] ^ b[0]) | (a[1] ^ b[1]) |
(a[2] ^ b[2]) | (a[3] ^ b[3]);
}
@@ -641,10 +645,10 @@
extern void ipifccheckout(struct Ipifc *ifc);
extern int ipifcgrab(struct Ipifc *ifc);
extern void ipifcaddroute(struct Fs *, int unused_int,
- uint8_t * unused_uint8_p_t, uint8_t *, uint8_t *,
+ uint8_t * unused_uint8_p_t, uint8_t *, uint8_t *,
int);
extern void ipifcremroute(struct Fs *, int unused_int, uint8_t * u8pt,
- uint8_t * u8pt2);
+ uint8_t * u8pt2);
extern void ipifcremmulti(struct conv *c, uint8_t * ma, uint8_t * ia);
extern void ipifcaddmulti(struct conv *c, uint8_t * ma, uint8_t * ia);
extern void ipifc_trace_block(struct Ipifc *ifc, struct block *bp);
@@ -658,16 +662,16 @@
extern void icmpnoconv(struct Fs *, struct block *);
extern void icmpcantfrag(struct Fs *, struct block *, int);
extern void icmpttlexceeded(struct Fs *, uint8_t * unused_uint8_p_t,
- struct block *);
+ struct block *);
uint16_t ipchecksum(uint8_t *addr, int len);
extern uint16_t ipcsum(uint8_t * unused_uint8_p_t);
extern void ipiput4(struct Fs *, struct Ipifc *unused_ipifc, struct block *);
extern void ipiput6(struct Fs *, struct Ipifc *unused_ipifc, struct block *);
-extern int ipoput4(struct Fs *,
- struct block *, int unused_int, int, int, struct conv *);
-extern int ipoput6(struct Fs *,
- struct block *, int unused_int, int, int, struct conv *);
+extern int ipoput4(struct Fs *, struct block *, int unused_int, int, int,
+ struct conv *);
+extern int ipoput6(struct Fs *, struct block *, int unused_int, int, int,
+ struct conv *);
extern int ipstats(struct Fs *, char *unused_char_p_t, int);
extern uint16_t ptclbsum(uint8_t * unused_uint8_p_t, int);
extern uint16_t ptclcsum(struct block *, int unused_int, int);
@@ -690,9 +694,10 @@
if (flag && (flag & feat) != flag) {
csum_store = bp->rp + bp->transport_offset + bp->tx_csum_offset;
- /* NOTE pseudo-header partial checksum (if any) is already placed at
- * csum_store (e.g. tcpcksum), and the ptclcsum() below will include
- * that partial checksum as part of the calculation.
+ /* NOTE pseudo-header partial checksum (if any) is already
+ * placed at csum_store (e.g. tcpcksum), and the ptclcsum()
+ * below will include that partial checksum as part of the
+ * calculation.
*/
hnputs((uint16_t *)csum_store,
ptclcsum(bp, bp->transport_offset,
@@ -725,7 +730,7 @@
* global to all of the stack
*/
extern void (*igmpreportfn) (struct Ipifc * unused_ipifc,
- uint8_t * unused_uint8_p_t);
+ uint8_t * unused_uint8_p_t);
/* IPV6 */
/* rfc 3513 defines the address prefices */
@@ -746,23 +751,23 @@
typedef struct Fraghdr6 Fraghdr6;
struct Ip4hdr {
- uint8_t vihl; /* Version and header length */
- uint8_t tos; /* Type of service */
- uint8_t length[2]; /* packet length */
- uint8_t id[2]; /* ip->identification */
- uint8_t frag[2]; /* Fragment information */
- uint8_t ttl; /* Time to live */
- uint8_t proto; /* Protocol */
- uint8_t cksum[2]; /* Header checksum */
- uint8_t src[4]; /* IP source */
- uint8_t dst[4]; /* IP destination */
+ uint8_t vihl; /* Version and header length */
+ uint8_t tos; /* Type of service */
+ uint8_t length[2]; /* packet length */
+ uint8_t id[2]; /* ip->identification */
+ uint8_t frag[2]; /* Fragment information */
+ uint8_t ttl; /* Time to live */
+ uint8_t proto; /* Protocol */
+ uint8_t cksum[2]; /* Header checksum */
+ uint8_t src[4]; /* IP source */
+ uint8_t dst[4]; /* IP destination */
};
struct ip6hdr {
- uint8_t vcf[4]; // version:4, traffic class:8, flow label:20
- uint8_t ploadlen[2]; // payload length: packet length - 40
- uint8_t proto; // next header type
- uint8_t ttl; // hop limit
+ uint8_t vcf[4]; // version:4, traffic class:8, flow label:20
+ uint8_t ploadlen[2]; // payload length: packet length - 40
+ uint8_t proto; // next header type
+ uint8_t ttl; // hop limit
uint8_t src[IPaddrlen];
uint8_t dst[IPaddrlen];
};
@@ -786,8 +791,8 @@
uint8_t id[4];
};
-enum { /* Header Types */
- HBH = 0, //?
+enum { /* Header Types */
+ HBH = 0,
ICMP = 1,
IGMP = 2,
GGP = 3,
@@ -906,14 +911,13 @@
extern void ipv62smcast(uint8_t *, uint8_t *);
extern void icmpns(struct Fs *f, uint8_t * src, int suni, uint8_t * targ,
- int tuni, uint8_t * mac);
+ int tuni, uint8_t * mac);
extern void icmpna(struct Fs *f, uint8_t * src, uint8_t * dst, uint8_t * targ,
- uint8_t * mac, uint8_t flags);
+ uint8_t * mac, uint8_t flags);
extern void icmpttlexceeded6(struct Fs *f, struct Ipifc *ifc, struct block *bp);
extern void icmppkttoobig6(struct Fs *f, struct Ipifc *ifc, struct block *bp);
-extern void icmphostunr(struct Fs *f,
- struct Ipifc *ifc,
- struct block *bp, int code, int free);
+extern void icmphostunr(struct Fs *f, struct Ipifc *ifc, struct block *bp,
+ int code, int free);
extern uint8_t v6allnodesN[IPaddrlen];
extern uint8_t v6allnodesL[IPaddrlen];
@@ -983,25 +987,25 @@
uint32_t mode;
char owner[KNAMELEN];
- int type; /* multiplexor type */
- int prom; /* promiscuous mode */
- int scan; /* base station scanning interval */
- int bridge; /* bridge mode */
- int headersonly; /* headers only - no data */
- uint8_t maddr[8]; /* bitmask of multicast addresses requested */
- int nmaddr; /* number of multicast addresses */
+ int type; /* multiplexor type */
+ int prom; /* promiscuous mode */
+ int scan; /* base station scanning interval */
+ int bridge; /* bridge mode */
+ int headersonly; /* headers only - no data */
+ uint8_t maddr[8]; /* bitmask of multicast addresses requested */
+ int nmaddr; /* number of multicast addresses */
- struct queue *in; /* input buffer */
+ struct queue *in; /* input buffer */
};
/*
* a network address
*/
struct netaddr {
- struct netaddr *next; /* allocation chain */
+ struct netaddr *next; /* allocation chain */
struct netaddr *hnext;
uint8_t addr[Nmaxaddr];
- int ref; /* leaving this as an int, not a kref. no reaping, yet. */
+ int ref; /* leaving this as an int, not a kref. no reaping, yet. */
};
/*
@@ -1018,7 +1022,7 @@
NETF_UDPCK = (1 << NS_UDPCK_SHIFT), /* xmit udp checksum */
NETF_TCPCK = (1 << NS_TCPCK_SHIFT), /* xmit tcp checksum */
NETF_PADMIN = (1 << NETF_PADMIN_SHIFT), /* device pads to mintu */
- NETF_SG = (1 << NETF_SG_SHIFT), /* device can do scatter/gather */
+ NETF_SG = (1 << NETF_SG_SHIFT), /* can do scatter/gather */
NETF_TSO = (1 << NS_TSO_SHIFT), /* device can do TSO */
NETF_LRO = (1 << NETF_LRO_SHIFT), /* device can do LRO */
NETF_RXCSUM = (1 << NETF_RXCSUM_SHIFT), /* device can do rx checksums */
@@ -1026,36 +1030,36 @@
/* Linux's rtnl_link_stats64 */
struct netif_stats {
- uint64_t rx_packets; /* total packets received */
- uint64_t tx_packets; /* total packets transmitted */
- uint64_t rx_bytes; /* total bytes received */
- uint64_t tx_bytes; /* total bytes transmitted */
- uint64_t rx_errors; /* bad packets received */
- uint64_t tx_errors; /* packet transmit problems */
- uint64_t rx_dropped; /* no space in linux buffers */
- uint64_t tx_dropped; /* no space available in linux */
- uint64_t multicast; /* multicast packets received */
- uint64_t collisions;
+ uint64_t rx_packets; /* total packets received */
+ uint64_t tx_packets; /* total packets transmitted */
+ uint64_t rx_bytes; /* total bytes received */
+ uint64_t tx_bytes; /* total bytes transmitted */
+ uint64_t rx_errors; /* bad packets received */
+ uint64_t tx_errors; /* packet transmit problems */
+ uint64_t rx_dropped; /* no space in linux buffers */
+ uint64_t tx_dropped; /* no space available in linux*/
+ uint64_t multicast; /* multicast packets received */
+ uint64_t collisions;
/* detailed rx_errors: */
- uint64_t rx_length_errors;
- uint64_t rx_over_errors; /* receiver ring buff overflow */
- uint64_t rx_crc_errors; /* recved pkt with crc error */
- uint64_t rx_frame_errors;/* recv'd frame alignment error */
- uint64_t rx_fifo_errors; /* recv'r fifo overrun */
- uint64_t rx_missed_errors; /* receiver missed packet */
+ uint64_t rx_length_errors;
+ uint64_t rx_over_errors; /* recv'r ring buff overflow */
+ uint64_t rx_crc_errors; /* recv'd pkt with crc error */
+ uint64_t rx_frame_errors;/* recv'd frame alignment err */
+ uint64_t rx_fifo_errors; /* recv'r fifo overrun */
+ uint64_t rx_missed_errors; /* receiver missed packet */
/* detailed tx_errors */
- uint64_t tx_aborted_errors;
- uint64_t tx_carrier_errors;
- uint64_t tx_fifo_errors;
- uint64_t tx_heartbeat_errors;
- uint64_t tx_window_errors;
+ uint64_t tx_aborted_errors;
+ uint64_t tx_carrier_errors;
+ uint64_t tx_fifo_errors;
+ uint64_t tx_heartbeat_errors;
+ uint64_t tx_window_errors;
/* for cslip etc */
- uint64_t rx_compressed;
- uint64_t tx_compressed;
- uint64_t rx_nohandler; /* dropped, no handler found */
+ uint64_t rx_compressed;
+ uint64_t tx_compressed;
+ uint64_t rx_nohandler; /* dropped, no handler found */
};
/*
@@ -1066,42 +1070,42 @@
qlock_t qlock;
/* multiplexing */
- char name[KNAMELEN]; /* for top level directory */
- char drv_name[KNAMELEN]; /* device driver name */
- int nfile; /* max number of Netfiles */
+ char name[KNAMELEN]; /* for top level directory */
+ char drv_name[KNAMELEN];/* device driver name */
+ int nfile; /* max number of Netfiles */
struct netfile **f;
/* about net */
- int limit; /* flow control */
- int alen; /* address length */
- int mbps; /* megabits per sec */
- int link; /* link status (seems to be driver specific) */
+ int limit; /* flow control */
+ int alen; /* address length */
+ int mbps; /* megabits per sec */
+ int link; /* link status (seems to be driver specific) */
struct rendez link_rz;
bool link_is_up;
- unsigned int feat; /* dev features turned on */
+ unsigned int feat; /* dev features turned on */
unsigned int hw_features; /* dev features available */
uint8_t addr[Nmaxaddr];
uint8_t bcast[Nmaxaddr];
- struct netaddr *maddr; /* known multicast addresses */
- int nmaddr; /* number of known multicast addresses */
+ struct netaddr *maddr; /* known multicast addresses */
+ int nmaddr; /* number of known multicast addresses */
struct netaddr *mhash[Nmhash]; /* hash table of multicast addresses */
- int prom; /* number of promiscuous opens */
- int scan; /* number of base station scanners */
- int all; /* number of -1 multiplexors */
- /* Analogous to linux's IFF_PROMISC flags, currently used by linux drivers,
- * pending a rewrite of ow promiscuous works */
+ int prom; /* number of promiscuous opens */
+ int scan; /* number of base station scanners */
+ int all; /* number of -1 multiplexors */
+ /* Analogous to linux's IFF_PROMISC flags, currently used by linux
+ * drivers, pending a rewrite of ow promiscuous works */
int rx_mode;
/* 9ns statistics */
int misses;
int inpackets;
int outpackets;
- int crcs; /* input crc errors */
- int oerrs; /* output errors */
- int frames; /* framing errors */
- int overflows; /* packet overflows */
- int buffs; /* buffering errors */
- int soverflows; /* software overflow */
+ int crcs; /* input crc errors */
+ int oerrs; /* output errors */
+ int frames; /* framing errors */
+ int overflows; /* packet overflows */
+ int buffs; /* buffering errors */
+ int soverflows; /* software overflow */
/* Linux-style statistics */
struct netif_stats stats;
@@ -1113,9 +1117,8 @@
};
void netifinit(struct ether *, char *, int, uint32_t);
-struct walkqid *netifwalk(struct ether *, struct chan *, struct chan *,
- char **,
- int);
+struct walkqid *netifwalk(struct ether *, struct chan *, struct chan *, char **,
+ int);
struct chan *netifopen(struct ether *, struct chan *, int);
void netifclose(struct ether *, struct chan *);
long netifread(struct ether *, struct chan *, void *, long, uint32_t);
@@ -1167,13 +1170,13 @@
void (*detach) (struct ether *);
void (*transmit) (struct ether *);
long (*ifstat) (struct ether *, void *, long, uint32_t);
- long (*ctl) (struct ether *, void *, long); /* custom ctl messages */
+ long (*ctl) (struct ether *, void *, long); /* custom ctl messages */
void (*power) (struct ether *, int); /* power on/off */
- void (*shutdown) (struct ether *); /* shutdown hardware before reboot */
+ void (*shutdown) (struct ether *); /* shutdown hardware before reboot */
void *ctlr;
int pcmslot; /* PCMCIA */
int fullduplex; /* non-zero if full duplex */
- int vlanid; /* non-zero if vlan */
+ int vlanid; /* non-zero if vlan */
struct queue *oq;
diff --git a/kern/include/net/tcp.h b/kern/include/net/tcp.h
index f88d7f3..4154718 100644
--- a/kern/include/net/tcp.h
+++ b/kern/include/net/tcp.h
@@ -51,7 +51,7 @@
TcptimerDONE = 2,
MAX_TIME = (1 << 20), /* Forever */
TCP_ACK = 50, /* Timed ack sequence in ms */
- MAXBACKMS = 9 * 60 * 1000, /* longest backoff time (ms) before hangup */
+ MAXBACKMS = 9 * 60 * 1000, /* longest backoff time (ms) before hangup */
URG = 0x20, /* Data marked urgent */
ACK = 0x10, /* Acknowledge is valid */
@@ -66,10 +66,10 @@
MSS_LENGTH = 4, /* max segment size header option length */
WSOPT = 3,
WS_LENGTH = 3, /* WS header option length */
- MAX_WS_VALUE = 14, /* RFC specified. Limits available window to 2^30 */
+ MAX_WS_VALUE = 14, /* RFC specified. Limits available window to 2^30 */
TS_OPT = 8,
TS_LENGTH = 10,
- TS_SEND_PREPAD = 2, /* For non-SYNs, pre-pad 2 nops for 32 byte alignment */
+ TS_SEND_PREPAD = 2, /* For non-SYNs, pre-pad 2 nops for 32 byte align */
SACK_OK_OPT = 4,
SACK_OK_LENGTH = 2,
SACK_OPT = 5,
@@ -113,7 +113,7 @@
Last_ack,
Time_wait,
- Maxlimbo = 1000, /* maximum procs waiting for response to SYN ACK */
+ Maxlimbo = 1000,/* maximum procs waiting for response to SYN ACK */
NLHT = 256, /* hash table size, must be a power of 2 */
LHTMASK = NLHT - 1,
@@ -154,11 +154,11 @@
*/
typedef struct tcp4hdr Tcp4hdr;
struct tcp4hdr {
- uint8_t vihl; /* Version and header length */
- uint8_t tos; /* Type of service */
- uint8_t length[2]; /* packet length */
- uint8_t id[2]; /* Identification */
- uint8_t frag[2]; /* Fragment information */
+ uint8_t vihl; /* Version and header length */
+ uint8_t tos; /* Type of service */
+ uint8_t length[2]; /* packet length */
+ uint8_t id[2]; /* Identification */
+ uint8_t frag[2]; /* Fragment information */
uint8_t Unused;
uint8_t proto;
uint8_t tcplen[2];
@@ -196,14 +196,14 @@
uint32_t seq;
uint32_t ack;
uint8_t flags;
- uint16_t ws; /* window scale option (if not zero) */
+ uint16_t ws; /* window scale option (if not zero) */
uint32_t wnd;
uint16_t urg;
- uint16_t mss; /* max segment size option (if not zero) */
- uint16_t len; /* size of data */
- uint32_t ts_val; /* timestamp val from sender */
- uint32_t ts_ecr; /* timestamp echo response from sender */
- bool sack_ok; /* header had/should have SACK_PERMITTED */
+ uint16_t mss; /* max segment size option (if not zero) */
+ uint16_t len; /* size of data */
+ uint32_t ts_val; /* timestamp val from sender */
+ uint32_t ts_ecr; /* timestamp echo response from sender */
+ bool sack_ok; /* header had/should have SACK_PERMITTED */
uint8_t nr_sacks;
struct sack_block sacks[MAX_NR_SACKS_PER_PACKET];
};
@@ -225,71 +225,71 @@
*/
typedef struct tcpctl Tcpctl;
struct tcpctl {
- uint8_t state; /* Connection state */
- uint8_t type; /* Listening or active connection */
- uint8_t code; /* Icmp code */
+ uint8_t state; /* Connection state */
+ uint8_t type; /* Listening or active connection */
+ uint8_t code; /* Icmp code */
struct {
- uint32_t una; /* Left edge of unacked data region */
- uint32_t nxt; /* Next seq to send, right edge of unacked */
- uint32_t rtx; /* Next to send for retrans */
- uint32_t wnd; /* Tcp send window */
- uint32_t urg; /* Urgent data pointer */
+ uint32_t una; /* Left edge of unacked data region */
+ uint32_t nxt; /* Next seq to send, right edge of unacked */
+ uint32_t rtx; /* Next to send for retrans */
+ uint32_t wnd; /* Tcp send window */
+ uint32_t urg; /* Urgent data pointer */
uint32_t wl2;
- int scale; /* how much to right shift window for xmit */
- uint32_t in_flight; /* estimate of how much is in flight */
- uint8_t loss_hint; /* number of loss hints rcvd */
+ int scale; /* how much to right shift window for xmit */
+ uint32_t in_flight; /* estimate of how much is in flight */
+ uint8_t loss_hint; /* number of loss hints rcvd */
uint8_t sack_loss_hint; /* For detecting sack rxmit losses */
- bool flush_sacks; /* Two timeouts in a row == dump sacks */
- uint8_t recovery; /* loss recovery flag */
+ bool flush_sacks; /* Two timeouts in a row == dump sacks */
+ uint8_t recovery; /* loss recovery flag */
uint32_t recovery_pt; /* right window for recovery point */
uint8_t nr_sacks;
struct sack_block sacks[MAX_NR_SND_SACKS];
} snd;
struct {
- uint32_t nxt; /* Receive pointer to next uint8_t slot */
- uint32_t wnd; /* Receive window incoming */
- uint32_t urg; /* Urgent pointer */
+ uint32_t nxt; /* Receive pointer to next uint8_t slot */
+ uint32_t wnd; /* Receive window incoming */
+ uint32_t urg; /* Urgent pointer */
int blocked;
- int una; /* unacked data segs */
- int scale; /* how much to left shift window for rx */
+ int una; /* unacked data segs */
+ int scale; /* how much to left shift window for rx */
uint8_t nr_sacks;
struct sack_block sacks[MAX_NR_RCV_SACKS];
} rcv;
- uint32_t iss; /* Initial sequence number */
- int sawwsopt; /* true if we saw a wsopt on the incoming SYN */
- uint32_t cwind; /* Congestion window */
- int scale; /* desired snd.scale */
- uint32_t ssthresh; /* Slow start threshold */
- int irs; /* Initial received squence */
- uint16_t mss; /* Max segment size */
- uint16_t typical_mss; /* MSS for most packets (< MSS for some opts) */
- int rerecv; /* Overlap of data rerecevived */
- uint32_t window; /* Recevive window */
- uint8_t backoff; /* Exponential backoff counter */
- int backedoff; /* ms we've backed off for rexmits */
- uint8_t flags; /* State flags */
- Reseq *reseq; /* Resequencing queue */
- Tcptimer timer; /* Activity timer */
- Tcptimer acktimer; /* Acknowledge timer */
- Tcptimer rtt_timer; /* Round trip timer */
- Tcptimer katimer; /* keep alive timer */
- uint32_t rttseq; /* Round trip sequence */
- int srtt; /* Shortened round trip */
- int mdev; /* Mean deviation of round trip */
- int kacounter; /* count down for keep alive */
- uint64_t sndsyntime; /* time syn sent */
- uint64_t time; /* time Finwait2 was sent */
- int nochecksum; /* non-zero means don't send checksums */
- int flgcnt; /* number of flags in the sequence (FIN,SYN) */
- uint32_t ts_recent; /* timestamp received around last_ack_sent */
- uint32_t last_ack_sent; /* to determine when to update timestamp */
- bool sack_ok; /* Can use SACK for this connection */
- struct Ipifc *ifc; /* Uncounted ref */
+ uint32_t iss; /* Initial sequence number */
+ int sawwsopt; /* true if we saw a wsopt on the incoming SYN */
+ uint32_t cwind; /* Congestion window */
+ int scale; /* desired snd.scale */
+ uint32_t ssthresh; /* Slow start threshold */
+ int irs; /* Initial received squence */
+ uint16_t mss; /* Max segment size */
+ uint16_t typical_mss; /* MSS for most packets (< MSS for some opts) */
+ int rerecv; /* Overlap of data rerecevived */
+ uint32_t window; /* Recevive window */
+ uint8_t backoff; /* Exponential backoff counter */
+ int backedoff; /* ms we've backed off for rexmits */
+ uint8_t flags; /* State flags */
+ Reseq *reseq; /* Resequencing queue */
+ Tcptimer timer; /* Activity timer */
+ Tcptimer acktimer; /* Acknowledge timer */
+ Tcptimer rtt_timer; /* Round trip timer */
+ Tcptimer katimer; /* keep alive timer */
+ uint32_t rttseq; /* Round trip sequence */
+ int srtt; /* Shortened round trip */
+ int mdev; /* Mean deviation of round trip */
+ int kacounter; /* count down for keep alive */
+ uint64_t sndsyntime; /* time syn sent */
+ uint64_t time; /* time Finwait2 was sent */
+ int nochecksum; /* non-zero means don't send checksums */
+ int flgcnt; /* number of flags in the sequence (FIN,SYN) */
+ uint32_t ts_recent; /* timestamp received around last_ack_sent */
+ uint32_t last_ack_sent; /* to determine when to update timestamp */
+ bool sack_ok; /* Can use SACK for this connection */
+ struct Ipifc *ifc; /* Uncounted ref */
union {
Tcp4hdr tcp4hdr;
Tcp6hdr tcp6hdr;
- } protohdr; /* prototype header */
+ } protohdr; /* prototype header */
};
/* New calls are put in limbo rather than having a conversation structure
@@ -312,17 +312,17 @@
uint8_t raddr[IPaddrlen];
uint16_t lport;
uint16_t rport;
- uint32_t irs; /* initial received sequence */
- uint32_t iss; /* initial sent sequence */
- uint16_t mss; /* mss from the other end */
- uint16_t rcvscale; /* how much to scale rcvd windows */
- uint16_t sndscale; /* how much to scale sent windows */
- uint64_t lastsend; /* last time we sent a synack */
- uint8_t version; /* v4 or v6 */
- uint8_t rexmits; /* number of retransmissions */
- bool sack_ok; /* other side said SACK_OK */
- uint32_t ts_val; /* timestamp val from sender */
- struct Ipifc *ifc; /* Uncounted ref */
+ uint32_t irs; /* initial received sequence */
+ uint32_t iss; /* initial sent sequence */
+ uint16_t mss; /* mss from the other end */
+ uint16_t rcvscale; /* how much to scale rcvd windows */
+ uint16_t sndscale; /* how much to scale sent windows */
+ uint64_t lastsend; /* last time we sent a synack */
+ uint8_t version; /* v4 or v6 */
+ uint8_t rexmits; /* number of retransmissions */
+ bool sack_ok; /* other side said SACK_OK */
+ uint32_t ts_val; /* timestamp val from sender */
+ struct Ipifc *ifc; /* Uncounted ref */
};
enum {
diff --git a/kern/include/ns.h b/kern/include/ns.h
index 6570985..5615df0 100644
--- a/kern/include/ns.h
+++ b/kern/include/ns.h
@@ -44,14 +44,14 @@
* functions (possibly) linked in, complete, from libc.
*/
enum {
- UTFmax = 4, /* maximum bytes per rune */
- Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */
+ UTFmax = 4, /* maximum bytes per rune */
+ Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */
Runeself = 0x80, /* rune and UTF sequences are the same (<) */
Runeerror = 0xFFFD, /* decoding error in UTF */
Runemax = 0x10FFFF, /* 21-bit rune */
Runemask = 0x1FFFFF, /* bits used by runes (see grep) */
- NUMSIZE32 = 10, /* max size of formatted 32 bit number (hex or decimal) */
- NUMSIZE64 = 20, /* max size of formatted 64 bit number (hex or decimal) */
+ NUMSIZE32 = 10, /* max size of formatted 32 bit number (hex or deci) */
+ NUMSIZE64 = 20, /* max size of formatted 64 bit number (hex or deci) */
};
/*
@@ -67,7 +67,6 @@
* one-of-a-kind
*/
extern char *cleanname(char *unused_char_p_t);
-//extern uint32_t getcallerpc(void*);
static inline uint32_t getcallerpc(void *v)
{
return 0;
@@ -106,8 +105,8 @@
#define NRSTR 3 /* restore saved state */
#define STATMAX 65535U /* max length of machine-independent stat structure */
-#define ERRMAX 128 /* max length of error string */
-#define KNAMELEN 28 /* max length of name held in kernel */
+#define ERRMAX 128 /* max length of error string */
+#define KNAMELEN 28 /* max length of name held in kernel */
/* bits in Qid.type */
#define QTDIR 0x80 /* type bit for directories */
@@ -143,32 +142,32 @@
struct dir {
/* system-modified data */
- uint16_t type; /* server type */
- uint32_t dev; /* server subtype */
+ uint16_t type; /* server type */
+ uint32_t dev; /* server subtype */
/* file data */
- struct qid qid; /* unique id from server */
- uint32_t mode; /* permissions */
+ struct qid qid; /* unique id from server */
+ uint32_t mode; /* permissions */
/* 9p stat has u32 atime (seconds) here */
/* 9p stat has u32 mtime (seconds) here */
- uint64_t length; /* file length: see <u.h> */
- char *name; /* last element of path */
- char *uid; /* owner name */
- char *gid; /* group name */
- char *muid; /* last modifier name */
- char *ext; /* extensions for special files (symlinks) */
- uint32_t n_uid; /* numeric owner uid */
- uint32_t n_gid; /* numeric group id */
- uint32_t n_muid; /* numeric last modifier id */
- struct timespec atime; /* last access time */
- struct timespec btime; /* file creation time */
- struct timespec ctime; /* last attribute change time */
- struct timespec mtime; /* last data modification time */
+ uint64_t length; /* file length: see <u.h> */
+ char *name; /* last element of path */
+ char *uid; /* owner name */
+ char *gid; /* group name */
+ char *muid; /* last modifier name */
+ char *ext; /* extensions for special files (symlinks) */
+ uint32_t n_uid; /* numeric owner uid */
+ uint32_t n_gid; /* numeric group id */
+ uint32_t n_muid; /* numeric last modifier id */
+ struct timespec atime; /* last access time */
+ struct timespec btime; /* file creation time */
+ struct timespec ctime; /* last attribute change time */
+ struct timespec mtime; /* last data modification time */
};
struct waitmsg {
- int pid; /* of loved one */
- uint32_t time[3]; /* of loved one and descendants */
- char msg[ERRMAX]; /* actually variable-size in user mode */
+ int pid; /* of loved one */
+ uint32_t time[3]; /* of loved one and descendants */
+ char msg[ERRMAX]; /* actually variable-size in user mode */
};
#define VERSION9P "9P2000"
@@ -182,69 +181,69 @@
uint16_t tag;
/* union { */
/* struct { */
- uint32_t msize; /* Tversion, Rversion */
- char *version; /* Tversion, Rversion */
+ uint32_t msize; /* Tversion, Rversion */
+ char *version; /* Tversion, Rversion */
/* }; */
/* struct { */
- uint16_t oldtag; /* Tflush */
+ uint16_t oldtag; /* Tflush */
/* }; */
/* struct { */
- char *ename; /* Rerror */
+ char *ename; /* Rerror */
/* }; */
/* struct { */
- struct qid qid; /* Rattach, Ropen, Rcreate */
- uint32_t iounit; /* Ropen, Rcreate */
+ struct qid qid; /* Rattach, Ropen, Rcreate */
+ uint32_t iounit; /* Ropen, Rcreate */
/* }; */
/* struct { */
- struct qid aqid; /* Rauth */
+ struct qid aqid; /* Rauth */
/* }; */
/* struct { */
- uint32_t afid; /* Tauth, Tattach */
- char *uname; /* Tauth, Tattach */
- char *aname; /* Tauth, Tattach */
+ uint32_t afid; /* Tauth, Tattach */
+ char *uname; /* Tauth, Tattach */
+ char *aname; /* Tauth, Tattach */
/* }; */
/* struct { */
- uint32_t perm; /* Tcreate */
- char *name; /* Tcreate */
- uint8_t mode; /* Tcreate, Topen */
+ uint32_t perm; /* Tcreate */
+ char *name; /* Tcreate */
+ uint8_t mode; /* Tcreate, Topen */
/* }; */
/* struct { */
- uint32_t newfid; /* Twalk */
- uint16_t nwname; /* Twalk */
+ uint32_t newfid; /* Twalk */
+ uint16_t nwname; /* Twalk */
char *wname[MAXWELEM]; /* Twalk */
/* }; */
/* struct { */
- uint16_t nwqid; /* Rwalk */
+ uint16_t nwqid; /* Rwalk */
struct qid wqid[MAXWELEM]; /* Rwalk */
/* }; */
/* struct { */
- int64_t offset; /* Tread, Twrite */
- uint32_t count; /* Tread, Twrite, Rread */
- char *data; /* Twrite, Rread */
+ int64_t offset; /* Tread, Twrite */
+ uint32_t count; /* Tread, Twrite, Rread */
+ char *data; /* Twrite, Rread */
/* }; */
/* struct { */
- uint16_t nstat; /* Twstat, Rstat */
- uint8_t *stat; /* Twstat, Rstat */
+ uint16_t nstat; /* Twstat, Rstat */
+ uint8_t *stat; /* Twstat, Rstat */
/* }; */
/* }; */
} fcall;
-#define GBIT8(p) ((p)[0])
-#define GBIT16(p) ((p)[0]|((p)[1]<<8))
-#define GBIT32(p) ((uint32_t)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)))
-#define GBIT64(p) ((uint32_t)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)) |\
- ((int64_t)((p)[4]|((p)[5]<<8)|((p)[6]<<16)|((p)[7]<<24)) << 32))
+#define GBIT8(p) ((p)[0])
+#define GBIT16(p) ((p)[0]|((p)[1]<<8))
+#define GBIT32(p) ((uint32_t)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)))
+#define GBIT64(p) ((uint32_t)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)) |\
+ ((int64_t)((p)[4]|((p)[5]<<8)|((p)[6]<<16)|((p)[7]<<24)) << 32))
-#define PBIT8(p,v) (p)[0]=(v)
-#define PBIT16(p,v) (p)[0]=(v);(p)[1]=(v)>>8
-#define PBIT32(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24
-#define PBIT64(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24;\
- (p)[4]=(v)>>32;(p)[5]=(v)>>40;(p)[6]=(v)>>48;(p)[7]=(v)>>56
+#define PBIT8(p,v) (p)[0]=(v)
+#define PBIT16(p,v) (p)[0]=(v);(p)[1]=(v)>>8
+#define PBIT32(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24
+#define PBIT64(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24;\
+ (p)[4]=(v)>>32;(p)[5]=(v)>>40;(p)[6]=(v)>>48;(p)[7]=(v)>>56
-#define BIT8SZ 1
-#define BIT16SZ 2
-#define BIT32SZ 4
-#define BIT64SZ 8
+#define BIT8SZ 1
+#define BIT16SZ 2
+#define BIT32SZ 4
+#define BIT64SZ 8
#define QIDSZ (BIT8SZ+BIT32SZ+BIT64SZ)
/* The 9p STATFIXLENs include the leading 16-bit count. The count, however,
@@ -293,7 +292,7 @@
#define NOTAG (uint16_t)~0U /* Dummy tag */
#define NOFID (uint32_t)~0U /* Dummy fid */
-#define IOHDRSZ 24 /* ample room for Twrite/Rread header (iounit) */
+#define IOHDRSZ 24 /* ample room for Twrite/Rread header (iounit) */
enum {
Tversion = 100,
@@ -329,17 +328,17 @@
void init_empty_dir(struct dir *d);
unsigned int convM2S(uint8_t * unused_uint8_p_t, unsigned int unused_int,
- struct fcall *);
+ struct fcall *);
unsigned int convS2M(struct fcall *, uint8_t * unused_uint8_p_t, unsigned int);
unsigned int sizeS2M(struct fcall *);
unsigned int convM2kdirent(uint8_t * buf, unsigned int nbuf, struct kdirent *kd,
- char *strs);
+ char *strs);
unsigned int convM2kstat(uint8_t * buf, unsigned int nbuf, struct kstat *ks);
void statcheck(uint8_t *buf, size_t nbuf);
unsigned int convM2D(uint8_t * unused_uint8_p_t, unsigned int unused_int,
- struct dir *, char *unused_char_p_t);
+ struct dir *, char *unused_char_p_t);
unsigned int convD2M(struct dir *, uint8_t * unused_uint8_p_t, unsigned int);
unsigned int sizeD2M(struct dir *);
@@ -378,14 +377,14 @@
* Access types in namec & channel flags
*/
enum {
- Aaccess, /* as in stat, wstat */
- Abind, /* for left-hand-side of bind */
- Atodir, /* as in chdir */
- Aopen, /* for i/o */
- Amount, /* to be mounted or mounted upon */
- Acreate, /* is to be created */
- Aremove, /* will be removed by caller */
- Arename, /* new_path of a rename */
+ Aaccess, /* as in stat, wstat */
+ Abind, /* for left-hand-side of bind */
+ Atodir, /* as in chdir */
+ Aopen, /* for i/o */
+ Amount, /* to be mounted or mounted upon */
+ Acreate, /* is to be created */
+ Aremove, /* will be removed by caller */
+ Arename, /* new_path of a rename */
/* internal chan flags, used by the kernel only */
COPEN = 0x0001, /* for i/o */
@@ -418,7 +417,7 @@
Budpck = (1 << NS_UDPCK_SHIFT), /* udp checksum (rx), needed (tx) */
Btcpck = (1 << NS_TCPCK_SHIFT), /* tcp checksum (rx), needed (tx) */
Bpktck = (1 << NS_PKTCK_SHIFT), /* packet checksum (rx, maybe) */
- Btso = (1 << NS_TSO_SHIFT), /* TSO desired (tx) */
+ Btso = (1 << NS_TSO_SHIFT), /* TSO desired (tx) */
};
#define BLOCK_META_FLAGS (Bipck | Budpck | Btcpck | Bpktck | Btso)
#define BLOCK_TRANS_TX_CSUM (Budpck | Btcpck)
@@ -434,13 +433,13 @@
struct block {
struct block *next;
struct block *list;
- uint8_t *rp; /* first unconsumed byte */
- uint8_t *wp; /* first empty byte */
- uint8_t *lim; /* 1 past the end of the buffer */
- uint8_t *base; /* start of the buffer */
+ uint8_t *rp; /* first unconsumed byte */
+ uint8_t *wp; /* first empty byte */
+ uint8_t *lim; /* 1 past the end of the buffer */
+ uint8_t *base; /* start of the buffer */
void (*free) (struct block *);
uint16_t flag;
- uint16_t mss; /* TCP MSS for TSO */
+ uint16_t mss; /* TCP MSS for TSO */
uint16_t network_offset; /* offset from start */
uint16_t transport_offset; /* offset from start */
uint16_t tx_csum_offset; /* offset from tx_offset to store csum */
@@ -456,42 +455,42 @@
struct chan {
spinlock_t lock;
struct kref ref;
- struct chan *next; /* allocation */
+ struct chan *next; /* allocation */
struct chan *link;
- int64_t offset; /* in file */
- int type; /* ID for device type, e.g. #mnt, #kfs, #ip */
- uint32_t dev; /* device specific; can be an instance ID */
- uint16_t mode; /* read/write */
+ int64_t offset; /* in file */
+ int type; /* ID for device type, e.g. #mnt, #kfs, #ip */
+ uint32_t dev; /* device specific; can be an instance ID */
+ uint16_t mode; /* read/write */
int flag;
struct qid qid;
- int fid; /* for devmnt */
- uint32_t iounit; /* chunk size for i/o; 0==default */
- struct mhead *umh; /* mount point that derived Chan; used in unionread */
- struct chan *umc; /* channel in union; held for union read */
- qlock_t umqlock; /* serialize unionreads */
- int uri; /* union read index */
- int dri; /* devdirread index */
+ int fid; /* for devmnt */
+ uint32_t iounit; /* chunk size for i/o; 0==default */
+ struct mhead *umh; /* mount point that derived Chan */
+ struct chan *umc; /* channel in union; for union read */
+ qlock_t umqlock; /* serialize unionreads */
+ int uri; /* union read index */
+ int dri; /* devdirread index */
uint32_t mountid;
- struct mntcache *mcp; /* Mount cache pointer */
- struct mnt *mux; /* Mnt for clients using me for messages */
+ struct mntcache *mcp; /* Mount cache pointer */
+ struct mnt *mux; /* Mnt for clients using me for messages */
union {
void *aux;
- char tag[4]; /* for iproute */
+ char tag[4]; /* for iproute */
};
/* mountpoint, as discovered during walk.
* Used for rename at present.
*/
struct chan *mountpoint;
- struct chan *mchan; /* channel to mounted server */
- struct qid mqid; /* qid of root of mount point */
+ struct chan *mchan; /* channel to mounted server */
+ struct qid mqid; /* qid of root of mount point */
struct cname *name;
/* hack for dir reads to try to get them right. */
int ateof;
void *buf;
int bufused;
- /* A lot of synthetic files need something generated at open time, which the
- * user can read from (including offsets) while the underlying file changes.
- * Hang that buffer here. */
+ /* A lot of synthetic files need something generated at open time, which
+ * the user can read from (including offsets) while the underlying file
+ * changes. Hang that buffer here. */
void *synth_buf;
};
@@ -499,8 +498,8 @@
struct cname {
struct kref ref;
- int alen; /* allocated length */
- int len; /* strlen(s) */
+ int alen; /* allocated length */
+ int len; /* strlen(s) */
char *s;
};
@@ -526,7 +525,7 @@
void (*remove)(struct chan *);
void (*rename)(struct chan *, struct chan *, const char *, int);
size_t (*wstat)(struct chan *, uint8_t *, size_t);
- void (*power)(int); /* power mgt: power(1) → on, power (0) → off */
+ void (*power)(int); /* power mgt: power(1) → on, power (0) → off */
// int (*config)( int unused_int, char *unused_char_p_t, DevConf*);
char *(*chaninfo)(struct chan *, char *, size_t);
int (*tapfd)(struct chan *, struct fd_tap *, int);
@@ -557,7 +556,7 @@
NSCACHE = (1 << NSLOG),
};
-struct mntwalk { /* state for /proc/#/ns */
+struct mntwalk { /* state for /proc/#/ns */
int cddone;
uint32_t id;
struct mhead *mh;
@@ -570,7 +569,7 @@
struct mhead *head;
struct mount *copy;
struct mount *order;
- struct chan *to; /* channel replacing channel */
+ struct chan *to; /* channel replacing channel */
int mflag;
char *spec;
};
@@ -578,23 +577,24 @@
struct mhead {
struct kref ref;
struct rwlock lock;
- struct chan *from; /* channel mounted upon */
+ struct chan *from; /* channel mounted upon */
struct mount *mount; /* what's mounted upon it */
- struct mhead *hash; /* Hash chain */
+ struct mhead *hash; /* Hash chain */
};
struct mnt {
spinlock_t lock;
- /* references are counted using c->ref; channels on this mount point incref(c->mchan) == Mnt.c */
- struct chan *c; /* Channel to file service */
+ /* references are counted using c->ref; channels on this mount point
+ * incref(c->mchan) == Mnt.c */
+ struct chan *c; /* Channel to file service */
struct kthread *rip; /* Reader in progress */
- struct mntrpc *queue; /* Queue of pending requests on this channel */
- uint32_t id; /* Multiplexer id for channel check */
- struct mnt *list; /* Free list */
- int flags; /* cache */
- int msize; /* data + IOHDRSZ */
- char *version; /* 9P version */
- struct queue *q; /* input queue */
+ struct mntrpc *queue; /* Queue of pending requests on chan */
+ uint32_t id; /* Multiplexer id for channel check */
+ struct mnt *list; /* Free list */
+ int flags; /* cache */
+ int msize; /* data + IOHDRSZ */
+ char *version; /* 9P version */
+ struct queue *q; /* input queue */
};
enum {
@@ -615,10 +615,10 @@
};
struct pgrp {
- struct kref ref; /* also used as a lock when mounting */
+ struct kref ref; /* also used as a lock when mounting */
uint32_t pgrpid;
- qlock_t debug; /* single access via devproc.c */
- struct rwlock ns; /* Namespace n read/one write lock */
+ qlock_t debug; /* single access via devproc.c */
+ struct rwlock ns; /* Namespace n read/one write lock */
qlock_t nsh;
struct mhead *mnthash[MNTHASH];
int progmode;
@@ -638,8 +638,8 @@
struct kref ref;
qlock_t qlock;
struct evalue *entries;
- uint32_t path; /* qid.path of next Evalue to be allocated */
- uint32_t vers; /* of Egrp */
+ uint32_t path; /* qid.path of next Evalue to be allocated */
+ uint32_t vers; /* of Egrp */
};
struct signerkey {
@@ -666,9 +666,9 @@
*/
enum {
/* Mode */
- Trelative, /* timer programmed in ns from now */
- Tabsolute, /* timer programmed in ns since epoch */
- Tperiodic, /* periodic timer, period in ns */
+ Trelative, /* timer programmed in ns from now */
+ Tabsolute, /* timer programmed in ns since epoch */
+ Tperiodic, /* periodic timer, period in ns */
};
enum {
@@ -688,18 +688,18 @@
};
struct cmdtab {
- int index; /* used by client to switch on result */
- char *cmd; /* command name */
- int narg; /* expected #args; 0 ==> variadic */
+ int index; /* used by client to switch on result */
+ char *cmd; /* command name */
+ int narg; /* expected #args; 0 ==> variadic */
};
/* queue state bits, all can be set in qopen (Qstarve is always set) */
enum {
- Qmsg = (1 << 1), /* message stream */
- Qclosed = (1 << 2), /* queue has been closed/hungup */
- Qcoalesce = (1 << 3), /* coalesce empty packets on read */
- Qkick = (1 << 4), /* always call the kick routine after qwrite */
- Qdropoverflow = (1 << 5), /* writes that would block will be dropped */
+ Qmsg = (1 << 1), /* message stream */
+ Qclosed = (1 << 2), /* queue has been closed/hungup */
+ Qcoalesce = (1 << 3), /* coalesce empty packets on read */
+ Qkick = (1 << 4), /* always call kick() after qwrite */
+ Qdropoverflow = (1 << 5), /* drop writes that would block */
};
/* Per-process structs */
@@ -729,22 +729,22 @@
/* Describes an open file. We need this, since the FD flags are supposed to be
* per file descriptor, not per file (like the file status flags). */
struct file_desc {
- struct chan *fd_chan;
- unsigned int fd_flags;
- struct fd_tap *fd_tap;
+ struct chan *fd_chan;
+ unsigned int fd_flags;
+ struct fd_tap *fd_tap;
};
/* All open files for a process */
struct fd_table {
- spinlock_t lock;
- bool closed;
- int max_files; /* max files ptd to by fd */
- int max_fdset; /* max of the current fd_set */
- int hint_min_fd; /* <= min available fd */
- struct file_desc *fd; /* initially pts to fd_array */
- struct fd_set *open_fds; /* init, pts to open_fds_init */
- struct small_fd_set open_fds_init;
- struct file_desc fd_array[NR_OPEN_FILES_DEFAULT];
+ spinlock_t lock;
+ bool closed;
+ int max_files; /* max files ptd to by fd */
+ int max_fdset; /* max of the current fd_set */
+ int hint_min_fd; /* <= min available fd */
+ struct file_desc *fd; /* initially pts to fd_array */
+ struct fd_set *open_fds; /* init, pts to open_fds_init */
+ struct small_fd_set open_fds_init;
+ struct file_desc fd_array[NR_OPEN_FILES_DEFAULT];
};
ssize_t kread_file(struct file_or_chan *file, void *buf, size_t sz);
@@ -761,7 +761,7 @@
#define DEVDOTDOT -1
typedef int Devgen(struct chan *, char *unused_char_p_t, struct dirtab *,
- int unused_int, int, struct dir *);
+ int unused_int, int, struct dir *);
/* inferno portfns.h. Not all these are needed. */
#define FPinit() fpinit() /* remove this if math lib is linked */
@@ -820,15 +820,15 @@
struct chan *devclone(struct chan *);
void devcreate(struct chan *, char *name, int mode, uint32_t perm, char *ext);
void devdir(struct chan *, struct qid, char *, int64_t, char *, long,
- struct dir *);
+ struct dir *);
long devdirread(struct chan *, char *, long, struct dirtab *, int, Devgen *);
Devgen devgen;
void devinit(void);
int devno(const char *name, int user);
void devpower(int);
struct dev *devbyname(char *unused_char_p_t);
-struct chan *devopen(struct chan *, int unused_int,
- struct dirtab *, int unused_int2, Devgen *);
+struct chan *devopen(struct chan *, int unused_int, struct dirtab *,
+ int unused_int2, Devgen *);
void devpermcheck(char *unused_char_p_t, uint32_t, int);
void devremove(struct chan *);
void devreset(void);
@@ -836,9 +836,9 @@
size_t dev_make_stat(struct chan *c, struct dir *dir, uint8_t *dp, size_t n);
size_t devstat(struct chan *, uint8_t *db, size_t n, struct dirtab *,
int ntab, Devgen *);
-struct walkqid *devwalk(struct chan *,
- struct chan *, char **unused_char_pp_t, int unused_int,
- struct dirtab *, int unused_intw, Devgen *);
+struct walkqid *devwalk(struct chan *, struct chan *, char **unused_char_pp_t,
+ int unused_int, struct dirtab *, int unused_intw,
+ Devgen *);
size_t devwstat(struct chan *, uint8_t *, size_t);
char *devchaninfo(struct chan *chan, char *ret, size_t ret_l);
void disinit(void *);
@@ -905,7 +905,7 @@
struct chan *newchan(void);
struct egrp *newegrp(void);
struct mount *newmount(struct mhead *, struct chan *, int unused_int,
- char *unused_char_p_t);
+ char *unused_char_p_t);
struct pgrp *newpgrp(void);
struct proc *newproc(void);
char *nextelem(char *unused_char_p_t, char *);
@@ -925,7 +925,7 @@
void pgrpcpy(struct pgrp *, struct pgrp *);
int progfdprint(struct chan *, int unused_int, int, char *unused_char_p_t,
- int i);
+ int i);
int pullblock(struct block **, int);
struct block *pullupblock(struct block *, int);
struct block *pullupqueue(struct queue *, int);
@@ -976,10 +976,10 @@
bool qwritable(struct queue *q);
void *realloc(void *, uint32_t);
-int readmem(unsigned long offset, char *buf, unsigned long n,
- const void *mem, size_t mem_len);
+int readmem(unsigned long offset, char *buf, unsigned long n, const void *mem,
+ size_t mem_len);
int readnum(unsigned long off, char *buf, unsigned long n, unsigned long val,
- size_t size);
+ size_t size);
int readnum_hex(unsigned long off, char *buf, unsigned long n,
unsigned long val, size_t size);
int readstr(unsigned long offset, char *buf, unsigned long n, const char *str);
diff --git a/kern/include/page_alloc.h b/kern/include/page_alloc.h
index 9e776da..2397b45 100644
--- a/kern/include/page_alloc.h
+++ b/kern/include/page_alloc.h
@@ -39,16 +39,16 @@
* an issue, we can dynamically allocate some of these things when we're a
* buffer page (in a page mapping) */
struct page {
- BSD_LIST_ENTRY(page) pg_link; /* membership in various lists */
- atomic_t pg_flags;
- struct page_map *pg_mapping; /* for debugging... */
- unsigned long pg_index;
- void **pg_tree_slot;
- void *pg_private; /* type depends on page usage */
- struct semaphore pg_sem; /* for blocking on IO */
- uint64_t gpa; /* physical address in guest */
+ BSD_LIST_ENTRY(page) pg_link;
+ atomic_t pg_flags;
+ struct page_map *pg_mapping; /* for debugging... */
+ unsigned long pg_index;
+ void **pg_tree_slot;
+ void *pg_private;
+ struct semaphore pg_sem;
+ uint64_t gpa; /* physical address in guest */
- bool pg_is_free; /* TODO: will remove */
+ bool pg_is_free; /* TODO: will remove */
};
/******** Externally visible global variables ************/
diff --git a/kern/include/pagemap.h b/kern/include/pagemap.h
index f2ad2f0..ca4d958 100644
--- a/kern/include/pagemap.h
+++ b/kern/include/pagemap.h
@@ -22,13 +22,13 @@
* currently in memory. It is a map, per object, from index to physical page
* frame. */
struct page_map {
- qlock_t pm_qlock; /* for the radix tree nr_pgs */
- struct fs_file *pm_file;
- struct radix_tree pm_tree; /* tracks present pages */
- unsigned long pm_num_pages; /* how many pages are present */
+ qlock_t pm_qlock;/* for the radix tree nr_pgs */
+ struct fs_file *pm_file;
+ struct radix_tree pm_tree; /* tracks present pgs */
+ unsigned long pm_num_pages; /* num present */
struct page_map_operations *pm_op;
- spinlock_t pm_lock; /* for the VMR list */
- struct vmr_tailq pm_vmrs;
+ spinlock_t pm_lock; /* for the VMR list */
+ struct vmr_tailq pm_vmrs;
};
/* Operations performed on a page_map. These are usually FS specific, which
diff --git a/kern/include/percpu.h b/kern/include/percpu.h
index 32d4785..893b48a 100644
--- a/kern/include/percpu.h
+++ b/kern/include/percpu.h
@@ -47,8 +47,8 @@
*
* // One core can print them all out
* for_each_core(i)
- * printk("Addr %p, value %lu\n", _PERCPU_VARPTR(*foos, i),
- * _PERCPU_VAR(*foos, i));
+ * printk("Addr %p, value %lu\n", _PERCPU_VARPTR(*foos, i),
+ * _PERCPU_VAR(*foos, i));
*
* // Free, but don't deref here. 'foos' is your handle.
* percpu_free(foos);
@@ -71,16 +71,16 @@
#define PERCPU_SIZE (PERCPU_STATIC_SIZE + PERCPU_DYN_SIZE)
#define PERCPU_OFFSET(var) ((char *) &(var) - PERCPU_START_VAR)
-#define __PERCPU_VARPTR(var, cpu) \
- ({ \
- typeof(var) *__cv; \
- if (likely(percpu_base)) \
- __cv = (typeof(var) *) (percpu_base + cpu * PERCPU_SIZE + \
- PERCPU_OFFSET(var)); \
- else \
- __cv = &var; \
- __cv; \
- })
+#define __PERCPU_VARPTR(var, cpu) \
+({ \
+ typeof(var) *__cv; \
+ if (likely(percpu_base)) \
+ __cv = (typeof(var) *) (percpu_base + cpu * PERCPU_SIZE + \
+ PERCPU_OFFSET(var)); \
+ else \
+ __cv = &var; \
+ __cv; \
+})
#define _PERCPU_VARPTR(var, cpu) __PERCPU_VARPTR(var, cpu)
#define PERCPU_VARPTR(var) __PERCPU_VARPTR(var, core_id())
@@ -89,8 +89,8 @@
#define DEFINE_PERCPU(type, var) \
__typeof__(type) var __attribute__ ((section (PERCPU_SECTION_STR)))
-#define DECLARE_PERCPU(type, var) \
- extern __typeof__(type) var \
+#define DECLARE_PERCPU(type, var) \
+ extern __typeof__(type) var \
__attribute__ ((section (PERCPU_SECTION_STR)))
#define PERCPU_INIT_SECTION __percpu_init
@@ -100,9 +100,9 @@
#define PERCPU_INIT_STOP_VAR PASTE(__stop_, PERCPU_INIT_SECTION)
#define PERCPU_INIT_NAME(func) PASTE(__percpu_, func)
-#define DEFINE_PERCPU_INIT(func) \
- static void func(void); \
- void (* const PERCPU_INIT_NAME(func))(void) \
+#define DEFINE_PERCPU_INIT(func) \
+ static void func(void); \
+ void (* const PERCPU_INIT_NAME(func))(void) \
__attribute__ ((section (PERCPU_INIT_SECTION_STR))) = (func)
extern char __attribute__((weak)) PERCPU_START_VAR[];
diff --git a/kern/include/pmap.h b/kern/include/pmap.h
index b93158f..b42b475 100644
--- a/kern/include/pmap.h
+++ b/kern/include/pmap.h
@@ -29,14 +29,14 @@
*/
#define PADDR(kva) \
({ \
- physaddr_t __m_pa, __m_kva = (physaddr_t) (kva); \
+ physaddr_t __m_pa, __m_kva = (physaddr_t) (kva); \
if (__m_kva < KERNBASE) \
panic("PADDR called with invalid kva %p", __m_kva);\
- if(__m_kva >= KERN_LOAD_ADDR) \
- __m_pa = __m_kva - KERN_LOAD_ADDR; \
- else \
- __m_pa = __m_kva - KERNBASE; \
- __m_pa; \
+ if(__m_kva >= KERN_LOAD_ADDR) \
+ __m_pa = __m_kva - KERN_LOAD_ADDR; \
+ else \
+ __m_pa = __m_kva - KERNBASE; \
+ __m_pa; \
})
#define paddr_low32(p) ((uint32_t)(uintptr_t)PADDR(p))
@@ -48,7 +48,7 @@
({ \
physaddr_t __m_pa = (pa); \
size_t __m_ppn = LA2PPN(__m_pa); \
- if (__m_ppn > max_nr_pages) \
+ if (__m_ppn > max_nr_pages) \
warn("KADDR called with invalid pa %p", __m_pa);\
(void*) (__m_pa + KERNBASE); \
})
@@ -56,8 +56,8 @@
#define KADDR_NOCHECK(pa) ((void*)(pa + KERNBASE))
#define KBASEADDR(kla) KADDR(PADDR(kla))
-extern physaddr_t max_pmem; /* Total amount of physical memory */
-extern size_t max_nr_pages; /* Total number of physical memory pages */
+extern physaddr_t max_pmem; /* Total amount of physical memory */
+extern size_t max_nr_pages; /* Total number of physical memory pages */
extern physaddr_t max_paddr; /* Maximum addressable physical address */
extern size_t nr_free_pages;
extern struct multiboot_info *multiboot_kaddr;
@@ -108,7 +108,8 @@
static inline page_t *ppn2page(size_t ppn)
{
if (ppn >= max_nr_pages)
- warn("ppn2page called with ppn (%08lu) larger than max_nr_pages", ppn);
+ warn("%s called with ppn (%p) larger than max_nr_pages (%p)",
+ __func__, ppn, max_nr_pages);
return &(pages[ppn]);
}
@@ -125,7 +126,8 @@
static inline page_t *pa2page(physaddr_t pa)
{
if (LA2PPN(pa) >= max_nr_pages)
- warn("pa2page called with pa (%p) larger than max_nr_pages", pa);
+ warn("%s called with pa (%p) larger than max_nr_pages (%p)",
+ __func__, pa, max_nr_pages);
return &pages[LA2PPN(pa)];
}
diff --git a/kern/include/pool.h b/kern/include/pool.h
index 69c8217..b38d486 100644
--- a/kern/include/pool.h
+++ b/kern/include/pool.h
@@ -5,67 +5,68 @@
#include <string.h>
-#define POOL_TYPE_DEFINE(_type, p, sz) \
-typedef struct struct_##p { \
+#define POOL_TYPE_DEFINE(_type, p, sz) \
+typedef struct struct_##p { \
uint32_t size; \
uint32_t free; \
uint32_t index; \
- _type* queue[(sz)]; \
- _type pool[(sz)]; \
+ _type* queue[(sz)]; \
+ _type pool[(sz)]; \
} p##_t;
#define POOL_INIT(p, sz) \
({ \
- (p)->size = (sz); \
- (p)->free = (sz); \
- (p)->index = 0; \
- memset((p)->pool, 0, (sz) * sizeof((p)->pool[0])); \
- for(int i=0; i<(p)->size; i++) { \
- (p)->queue[i] = &((p)->pool[i]); \
- } \
+ (p)->size = (sz); \
+ (p)->free = (sz); \
+ (p)->index = 0; \
+ memset((p)->pool, 0, (sz) * sizeof((p)->pool[0])); \
+ for(int i=0; i<(p)->size; i++) { \
+ (p)->queue[i] = &((p)->pool[i]); \
+ } \
})
-#define POOL_GET(p) \
-({ \
- void* rval = NULL; \
- if((p)->free) { \
- rval = (p)->queue[(p)->index]; \
- (p)->queue[(p)->index] = NULL; \
- (p)->free--; \
- (p)->index++; \
- if((p)->index == (p)->size) { \
- (p)->index = 0; \
- } \
- } \
- rval; \
+#define POOL_GET(p) \
+({ \
+ void* rval = NULL; \
+ if((p)->free) { \
+ rval = (p)->queue[(p)->index]; \
+ (p)->queue[(p)->index] = NULL; \
+ (p)->free--; \
+ (p)->index++; \
+ if((p)->index == (p)->size) { \
+ (p)->index = 0; \
+ } \
+ } \
+ rval; \
})
-// emptyIndex is also the first element that has been allocated, iterate thru to index-1
+// emptyIndex is also the first element that has been allocated, iterate thru to
+// index-1
-#define POOL_FOR_EACH(p, func) \
-({ \
- int emptyIndex = ((p)->index + (p)->free); \
- if (emptyIndex >= (p)->size) { \
- emptyIndex -= (p)->size; \
- } \
- for(int _i = emptyIndex; _i < (p)->index; _i++){ \
- func((p)->queue[_i]); \
- } \
-}) \
+#define POOL_FOR_EACH(p, func) \
+({ \
+ int emptyIndex = ((p)->index + (p)->free); \
+ if (emptyIndex >= (p)->size) { \
+ emptyIndex -= (p)->size; \
+ } \
+ for(int _i = emptyIndex; _i < (p)->index; _i++){ \
+ func((p)->queue[_i]); \
+ } \
+})
#define POOL_PUT(p, val) \
({ \
- int rval = -1; \
- if((p)->free < (p)->size) { \
+ int rval = -1; \
+ if((p)->free < (p)->size) { \
int emptyIndex = ((p)->index + (p)->free); \
if (emptyIndex >= (p)->size) { \
emptyIndex -= (p)->size; \
} \
(p)->queue[emptyIndex] = val; \
(p)->free++; \
- rval = 1; \
+ rval = 1; \
} \
- rval; \
+ rval; \
})
#define POOL_EMPTY(p) ((p)->free == 0)
diff --git a/kern/include/process.h b/kern/include/process.h
index ec98687..69ece85 100644
--- a/kern/include/process.h
+++ b/kern/include/process.h
@@ -43,7 +43,7 @@
#define PROC_RUNNABLE_S 0x02
#define PROC_RUNNING_S 0x04
#define PROC_WAITING 0x08 // can split out to INT and UINT
-#define PROC_DYING 0x10
+#define PROC_DYING 0x10
#define PROC_DYING_ABORT 0x20
#define PROC_RUNNABLE_M 0x40
#define PROC_RUNNING_M 0x80
diff --git a/kern/include/profiler.h b/kern/include/profiler.h
index 012214e..41dc839 100644
--- a/kern/include/profiler.h
+++ b/kern/include/profiler.h
@@ -28,5 +28,5 @@
int profiler_size(void);
int profiler_read(void *va, int n);
void profiler_notify_mmap(struct proc *p, uintptr_t addr, size_t size, int prot,
- int flags, struct file_or_chan *foc, size_t offset);
+ int flags, struct file_or_chan *foc, size_t offset);
void profiler_notify_new_process(struct proc *p);
diff --git a/kern/include/radix.h b/kern/include/radix.h
index af521a7..c30f462 100644
--- a/kern/include/radix.h
+++ b/kern/include/radix.h
@@ -27,12 +27,12 @@
#include <rcu.h>
struct radix_node {
- struct rcu_head rcu;
- void *items[NR_RNODE_SLOTS];
- unsigned int num_items;
- bool leaf;
- struct radix_node *parent;
- struct radix_node **my_slot;
+ struct rcu_head rcu;
+ void *items[NR_RNODE_SLOTS];
+ unsigned int num_items;
+ bool leaf;
+ struct radix_node *parent;
+ struct radix_node **my_slot;
};
/* writers (insert, delete, and callbacks) must synchronize externally, e.g. a
@@ -58,10 +58,10 @@
* the slot pointer and what it points to are protected by RCU.
*/
struct radix_tree {
- seq_ctr_t seq;
- struct radix_node *root;
- unsigned int depth;
- unsigned long upper_bound;
+ seq_ctr_t seq;
+ struct radix_node *root;
+ unsigned int depth;
+ unsigned long upper_bound;
};
void radix_init(void); /* initializes the whole radix system */
diff --git a/kern/include/rcu.h b/kern/include/rcu.h
index 578a303..e67553d 100644
--- a/kern/include/rcu.h
+++ b/kern/include/rcu.h
@@ -17,9 +17,9 @@
typedef void (*call_rcu_func_t)(struct rcu_head *head, rcu_callback_t func);
struct rcu_head {
- struct list_head link;
- rcu_callback_t func;
- unsigned long gpnum;
+ struct list_head link;
+ rcu_callback_t func;
+ unsigned long gpnum;
};
#include <rcupdate.h>
@@ -33,46 +33,46 @@
#include <rendez.h>
struct rcu_node {
- struct rcu_node *parent;
- unsigned long qsmask; /* cores that need to check in */
- unsigned long qsmaskinit;
- unsigned int level;
- unsigned int grplo; /* lowest nr CPU here */
- unsigned int grphi; /* highest nr CPU here */
- unsigned int grpnum; /* our number in our parent */
- unsigned long grpmask;/* our bit in our parent */
+ struct rcu_node *parent;
+ unsigned long qsmask; /* cores that need to check in*/
+ unsigned long qsmaskinit;
+ unsigned int level;
+ unsigned int grplo; /* lowest nr CPU here */
+ unsigned int grphi; /* highest nr CPU here */
+ unsigned int grpnum; /* our number in our parent */
+ unsigned long grpmask;/* our bit in our parent */
};
struct rcu_state {
- struct rcu_node node[NUM_RCU_NODES];
- struct rcu_node *level[RCU_NUM_LVLS];
+ struct rcu_node node[NUM_RCU_NODES];
+ struct rcu_node *level[RCU_NUM_LVLS];
/* These are read by everyone but only written by the GP kthread */
- unsigned long gpnum;
- unsigned long completed;
+ unsigned long gpnum;
+ unsigned long completed;
- /* These are written by anyone trying to wake the gp kthread, which can be
- * any core whose CB list is long or does an rcu_barrier() */
+ /* These are written by anyone trying to wake the gp kthread, which can
+ * be any core whose CB list is long or does an rcu_barrier() */
/* TODO: make a ktask struct and use a read-only pointer. */
- struct rendez gp_ktask_rv;
- int gp_ktask_ctl;
+ struct rendez gp_ktask_rv;
+ int gp_ktask_ctl;
};
struct rcu_pcpui {
- struct rcu_state *rsp;
- struct rcu_node *my_node;
- int coreid;
- unsigned int grpnum;
- unsigned long grpmask;
- bool booted;
+ struct rcu_state *rsp;
+ struct rcu_node *my_node;
+ int coreid;
+ unsigned int grpnum;
+ unsigned long grpmask;
+ bool booted;
- spinlock_t lock;
- struct list_head cbs;
- unsigned int nr_cbs;
- unsigned long gp_acked;
+ spinlock_t lock;
+ struct list_head cbs;
+ unsigned int nr_cbs;
+ unsigned long gp_acked;
- struct rendez mgmt_ktask_rv;
- int mgmt_ktask_ctl;
+ struct rendez mgmt_ktask_rv;
+ int mgmt_ktask_ctl;
};
DECLARE_PERCPU(struct rcu_pcpui, rcu_pcpui);
diff --git a/kern/include/refd_pages.h b/kern/include/refd_pages.h
index b61f1a5..20e6008 100644
--- a/kern/include/refd_pages.h
+++ b/kern/include/refd_pages.h
@@ -19,9 +19,9 @@
#include <assert.h>
struct refd_pages {
- void *rp_kva;
- size_t rp_order;
- struct kref rp_kref;
+ void *rp_kva;
+ size_t rp_order;
+ struct kref rp_kref;
};
static struct page *rp2page(struct refd_pages *rp)
diff --git a/kern/include/rendez.h b/kern/include/rendez.h
index 06f257a..e1d5720 100644
--- a/kern/include/rendez.h
+++ b/kern/include/rendez.h
@@ -7,16 +7,16 @@
* We implement it with CVs, and it can handle multiple sleepers/wakers.
*
* Init:
- * rendez_init(&rv);
+ * rendez_init(&rv);
*
* Sleeper usage:
- * rendez_sleep(&rv, some_func_taking_void*, void *arg);
+ * rendez_sleep(&rv, some_func_taking_void*, void *arg);
* or
- * rendez_sleep_timeout(&rv, some_func_taking_void*, void *arg, usec);
+ * rendez_sleep_timeout(&rv, some_func_taking_void*, void *arg, usec);
*
* Waker usage: (can be used from IRQ context)
- * // set the condition to TRUE, then:
- * rendez_wakeup(&rv);
+ * // set the condition to TRUE, then:
+ * rendez_wakeup(&rv);
*
* Some notes:
* - Some_func checks some condition and returns TRUE when we want to wake up.
@@ -42,7 +42,7 @@
#include <alarm.h>
struct rendez {
- struct cond_var cv;
+ struct cond_var cv;
};
typedef int (*rendez_cond_t)(void *arg);
diff --git a/kern/include/ros/atomic.h b/kern/include/ros/atomic.h
index b37a50f..58f8fed 100644
--- a/kern/include/ros/atomic.h
+++ b/kern/include/ros/atomic.h
@@ -25,8 +25,8 @@
/* Basic helpers for readers. Ex:
* do {
- * seq_ctr_t seq = kernel_maintained_seq_ctr
- * read_data_whatever();
+ * seq_ctr_t seq = kernel_maintained_seq_ctr
+ * read_data_whatever();
* } while (seqctr_retry(seq, kernel_maintained_seq_ctr);
*/
static inline bool seq_is_locked(seq_ctr_t seq_ctr)
@@ -39,8 +39,8 @@
seq_ctr_t old_val;
rmb(); /* don't allow protected reads to reorder after the check */
- /* Even though old_ctr is passed in, we might be inlined and can't guarantee
- * old_ctr was in a register or otherwise won't be re-read. */
+ /* Even though old_ctr is passed in, we might be inlined and can't
+ * guarantee old_ctr was in a register or otherwise won't be re-read. */
old_val = READ_ONCE(old_ctr);
return (seq_is_locked(old_val)) || (old_val != new_ctr);
}
diff --git a/kern/include/ros/bcq.h b/kern/include/ros/bcq.h
index 4bf7222..5ec00f3 100644
--- a/kern/include/ros/bcq.h
+++ b/kern/include/ros/bcq.h
@@ -111,8 +111,8 @@
/* Functions */
#define bcq_init(_bcq, _ele_type, _num_elems) \
({ \
- memset((_bcq), 0, sizeof(*(_bcq))); \
- assert((_num_elems) == ROUNDUPPWR2(_num_elems)); \
+ memset((_bcq), 0, sizeof(*(_bcq))); \
+ assert((_num_elems) == ROUNDUPPWR2(_num_elems)); \
})
/* Num empty buffer slots in the BCQ */
@@ -132,61 +132,61 @@
* macro got a bit ugly, esp with the __retval hackery. */
#define bcq_enqueue(_bcq, _elem, _num_elems, _num_fail) \
({ \
- uint32_t __prod, __new_prod, __cons_pub, __failctr = 0; \
- int __retval = 0; \
- do { \
- cmb(); \
- if (((_num_fail)) && (__failctr++ >= (_num_fail))) { \
- __retval = -EFAIL; \
- break; \
- } \
- __prod = (_bcq)->hdr.prod_idx; \
- __cons_pub = (_bcq)->hdr.cons_pub_idx; \
- if (BCQ_FULL(__prod, __cons_pub, (_num_elems))) { \
- __retval = -EBUSY; \
- break; \
- } \
- __new_prod = __prod + 1; \
- } while (!atomic_cas_u32(&(_bcq)->hdr.prod_idx, __prod, __new_prod)); \
- if (!__retval) { \
- /* from here out, __prod is the local __prod that we won */ \
- (_bcq)->wraps[__prod & ((_num_elems)-1)].elem = *(_elem); \
- wmb(); \
- (_bcq)->wraps[__prod & ((_num_elems)-1)].rdy_for_cons = TRUE; \
- } \
- __retval; \
+ uint32_t __prod, __new_prod, __cons_pub, __failctr = 0; \
+ int __retval = 0; \
+ do { \
+ cmb(); \
+ if (((_num_fail)) && (__failctr++ >= (_num_fail))) { \
+ __retval = -EFAIL; \
+ break; \
+ } \
+ __prod = (_bcq)->hdr.prod_idx; \
+ __cons_pub = (_bcq)->hdr.cons_pub_idx; \
+ if (BCQ_FULL(__prod, __cons_pub, (_num_elems))) { \
+ __retval = -EBUSY; \
+ break; \
+ } \
+ __new_prod = __prod + 1; \
+ } while (!atomic_cas_u32(&(_bcq)->hdr.prod_idx, __prod, __new_prod)); \
+ if (!__retval) { \
+ /* from here out, __prod is the local __prod that we won */ \
+ (_bcq)->wraps[__prod & ((_num_elems)-1)].elem = *(_elem); \
+ wmb(); \
+ (_bcq)->wraps[__prod & ((_num_elems)-1)].rdy_for_cons = TRUE; \
+ } \
+ __retval; \
})
/* Similar to enqueue, spin afterwards til cons_pub is our element, then
* advance it. */
#define bcq_dequeue(_bcq, _elem, _num_elems) \
({ \
- uint32_t __prod, __cons_pvt, __new_cons_pvt, __cons_pub; \
- int __retval = 0; \
- do { \
- cmb(); \
- __prod = (_bcq)->hdr.prod_idx; \
- __cons_pvt = (_bcq)->hdr.cons_pvt_idx; \
- if (BCQ_NO_WORK(__prod, __cons_pvt)) { \
- __retval = -EBUSY; \
- break; \
- } \
- __new_cons_pvt = (__cons_pvt + 1); \
- } while (!atomic_cas_u32(&(_bcq)->hdr.cons_pvt_idx, __cons_pvt, \
- __new_cons_pvt)); \
- if (!__retval) { \
- /* from here out, __cons_pvt is the local __cons_pvt that we won */ \
- /* wait for the producer to finish copying it in */ \
- while (!(_bcq)->wraps[__cons_pvt & ((_num_elems)-1)].rdy_for_cons) \
- cpu_relax(); \
- *(_elem) = (_bcq)->wraps[__cons_pvt & ((_num_elems)-1)].elem; \
- (_bcq)->wraps[__cons_pvt & ((_num_elems)-1)].rdy_for_cons = FALSE; \
- /* wait til we're the cons_pub, then advance it by one */ \
- while ((_bcq)->hdr.cons_pub_idx != __cons_pvt) \
- cpu_relax_vc(vcore_id()); \
- (_bcq)->hdr.cons_pub_idx = __cons_pvt + 1; \
- } \
- __retval; \
+ uint32_t __prod, __cons_pvt, __new_cons_pvt, __cons_pub; \
+ int __retval = 0; \
+ do { \
+ cmb(); \
+ __prod = (_bcq)->hdr.prod_idx; \
+ __cons_pvt = (_bcq)->hdr.cons_pvt_idx; \
+ if (BCQ_NO_WORK(__prod, __cons_pvt)) { \
+ __retval = -EBUSY; \
+ break; \
+ } \
+ __new_cons_pvt = (__cons_pvt + 1); \
+ } while (!atomic_cas_u32(&(_bcq)->hdr.cons_pvt_idx, __cons_pvt, \
+ __new_cons_pvt)); \
+ if (!__retval) { \
+ /* from here out, __cons_pvt is the local __cons_pvt that we */\
+ /* won. wait for the producer to finish copying it in */ \
+ while (!(_bcq)->wraps[__cons_pvt & ((_num_elems)-1)].rdy_for_cons) \
+ cpu_relax(); \
+ *(_elem) = (_bcq)->wraps[__cons_pvt & ((_num_elems)-1)].elem; \
+ (_bcq)->wraps[__cons_pvt & ((_num_elems)-1)].rdy_for_cons = FALSE; \
+ /* wait til we're the cons_pub, then advance it by one */ \
+ while ((_bcq)->hdr.cons_pub_idx != __cons_pvt) \
+ cpu_relax_vc(vcore_id()); \
+ (_bcq)->hdr.cons_pub_idx = __cons_pvt + 1; \
+ } \
+ __retval; \
})
/* Checks of a bcq is empty (meaning no work), instead of trying to dequeue */
diff --git a/kern/include/ros/bcq_struct.h b/kern/include/ros/bcq_struct.h
index 13420b7..2a96303 100644
--- a/kern/include/ros/bcq_struct.h
+++ b/kern/include/ros/bcq_struct.h
@@ -10,7 +10,7 @@
#include <ros/common.h>
struct bcq_header {
- uint32_t prod_idx; /* next to be produced in */
+ uint32_t prod_idx; /* next to be produced in */
uint32_t cons_pub_idx; /* last completely consumed */
uint32_t cons_pvt_idx; /* last a consumer has dibs on */
};
@@ -19,12 +19,12 @@
\
/* Wrapper, per element, with the consumption bool */ \
struct __name##_bcq_wrap { \
- __elem_t elem; \
- bool rdy_for_cons; /* elem is ready for consumption */ \
+ __elem_t elem; \
+ bool rdy_for_cons; /* elem is ready for consumption */ \
}; \
\
/* The actual BC queue */ \
struct __name##_bcq { \
- struct bcq_header hdr; \
- struct __name##_bcq_wrap wraps[__num_elems]; \
+ struct bcq_header hdr; \
+ struct __name##_bcq_wrap wraps[__num_elems]; \
};
diff --git a/kern/include/ros/bitfield.h b/kern/include/ros/bitfield.h
index a99b2ee..a2fc678 100644
--- a/kern/include/ros/bitfield.h
+++ b/kern/include/ros/bitfield.h
@@ -28,7 +28,7 @@
uint8_t nbits;
};
-#define MKBITFIELD(s, n) \
+#define MKBITFIELD(s, n) \
((struct bitfield_conf) { .shift = (s), .nbits = (n) })
#define BF_MKMASK(type, bfc) ((((type) 1 << bfc.nbits) - 1) << bfc.shift)
@@ -36,7 +36,7 @@
#define BF_GETFIELD(val, bfc) \
({ ((val) >> bfc.shift) & (((typeof(val)) 1 << bfc.nbits) - 1); })
-#define BF_SETFIELD(val, x, bfc) \
- ({ typeof(val) m = BF_MKMASK(typeof(val), bfc); \
- (val) = ((val) & ~m) | \
+#define BF_SETFIELD(val, x, bfc) \
+ ({ typeof(val) m = BF_MKMASK(typeof(val), bfc); \
+ (val) = ((val) & ~m) | \
(((typeof(val)) (x) << bfc.shift) & m); })
diff --git a/kern/include/ros/bits/event.h b/kern/include/ros/bits/event.h
index 5a67cee..f1beb49 100644
--- a/kern/include/ros/bits/event.h
+++ b/kern/include/ros/bits/event.h
@@ -9,45 +9,45 @@
#include <ros/common.h>
/* Event Delivery Flags from the process to the kernel */
-#define EVENT_IPI 0x00001 /* IPI the vcore (usually with INDIR) */
-#define EVENT_SPAM_PUBLIC 0x00002 /* spam the msg to public vcpd mboxes */
-#define EVENT_INDIR 0x00004 /* send an indirection event to vcore */
-#define EVENT_VCORE_PRIVATE 0x00008 /* Will go to the private VCPD mbox */
-#define EVENT_SPAM_INDIR 0x00010 /* spam INDIRs if the vcore's offline */
+#define EVENT_IPI 0x00001 /* IPI the vcore (usually with INDIR) */
+#define EVENT_SPAM_PUBLIC 0x00002 /* spam the msg to public vcpd mboxes */
+#define EVENT_INDIR 0x00004 /* send an indirection event to vcore */
+#define EVENT_VCORE_PRIVATE 0x00008 /* Will go to the private VCPD mbox */
+#define EVENT_SPAM_INDIR 0x00010 /* spam INDIRs if the vcore's offline */
#define EVENT_VCORE_MUST_RUN 0x00020 /* spams go to a vcore that will run */
-#define EVENT_NOTHROTTLE 0x00040 /* send all INDIRs (no throttling) */
-#define EVENT_ROUNDROBIN 0x00080 /* pick a vcore, RR style */
-#define EVENT_VCORE_APPRO 0x00100 /* send to where the kernel wants */
-#define EVENT_WAKEUP 0x00200 /* wake up the process after sending */
+#define EVENT_NOTHROTTLE 0x00040 /* send all INDIRs (no throttling) */
+#define EVENT_ROUNDROBIN 0x00080 /* pick a vcore, RR style */
+#define EVENT_VCORE_APPRO 0x00100 /* send to where the kernel wants */
+#define EVENT_WAKEUP 0x00200 /* wake up the process after sending */
/* Event Message Types */
-#define EV_NONE 0
-#define EV_PREEMPT_PENDING 1
+#define EV_NONE 0
+#define EV_PREEMPT_PENDING 1
#define EV_GANG_PREMPT_PENDING 2
-#define EV_VCORE_PREEMPT 3
-#define EV_GANG_RETURN 4
-#define EV_USER_IPI 5
-#define EV_PAGE_FAULT 6
-#define EV_ALARM 7
-#define EV_EVENT 8
-#define EV_FREE_APPLE_PIE 9
-#define EV_SYSCALL 10
-#define EV_CHECK_MSGS 11
-#define EV_POSIX_SIGNAL 12
-#define NR_EVENT_TYPES 25 /* keep me last (and 1 > the last one) */
+#define EV_VCORE_PREEMPT 3
+#define EV_GANG_RETURN 4
+#define EV_USER_IPI 5
+#define EV_PAGE_FAULT 6
+#define EV_ALARM 7
+#define EV_EVENT 8
+#define EV_FREE_APPLE_PIE 9
+#define EV_SYSCALL 10
+#define EV_CHECK_MSGS 11
+#define EV_POSIX_SIGNAL 12
+#define NR_EVENT_TYPES 25 /* keep me last (and 1 > the last one) */
/* Will probably have dynamic notifications later */
-#define MAX_NR_DYN_EVENT 25
-#define MAX_NR_EVENT (NR_EVENT_TYPES + MAX_NR_DYN_EVENT)
+#define MAX_NR_DYN_EVENT 25
+#define MAX_NR_EVENT (NR_EVENT_TYPES + MAX_NR_DYN_EVENT)
/* Want to keep this small and generic, but add items as you need them. One
* item some will need is an expiration time, which ought to be put in the 64
* bit arg. Will need tweaking / thought as we come up with events. These are
* what get put on the per-core queue in procdata. */
struct event_msg {
- uint16_t ev_type;
- uint16_t ev_arg1;
- uint32_t ev_arg2;
- void *ev_arg3;
- uint64_t ev_arg4;
+ uint16_t ev_type;
+ uint16_t ev_arg1;
+ uint32_t ev_arg2;
+ void *ev_arg3;
+ uint64_t ev_arg4;
};
diff --git a/kern/include/ros/bits/syscall.h b/kern/include/ros/bits/syscall.h
index 00f3182..cfcd587 100644
--- a/kern/include/ros/bits/syscall.h
+++ b/kern/include/ros/bits/syscall.h
@@ -3,102 +3,102 @@
/* system call numbers. need to #def them for use in assembly. Removing
* useless ones is okay, but if we change a number, we'll need to rebuild
* userspace (which is why we have holes). */
-#define SYS_null 1
-#define SYS_block 2
-#define SYS_cache_invalidate 3
-#define SYS_reboot 4
-/* was SYS_cputs 5 */
-/* was SYS_cgetc 6 */
-#define SYS_getpcoreid 7
-#define SYS_getvcoreid 8
-/* was #define SYS_getpid 9 */
-#define SYS_proc_create 10
-#define SYS_proc_run 11
-#define SYS_proc_destroy 12
-#define SYS_proc_yield 13
-#define SYS_change_vcore 14
-#define SYS_fork 15
-#define SYS_exec 16
-#define SYS_waitpid 17
-#define SYS_mmap 18
-#define SYS_munmap 19
-#define SYS_mprotect 20
-/* was SYS_brk 21 */
-#define SYS_shared_page_alloc 22
-#define SYS_shared_page_free 23
-#define SYS_provision 24
-#define SYS_notify 25
-#define SYS_self_notify 26
-#define SYS_halt_core 27
-#define SYS_init_arsc 28
-#define SYS_change_to_m 29
-#define SYS_poke_ksched 30
-#define SYS_abort_sysc 31
-#define SYS_populate_va 32
-#define SYS_abort_sysc_fd 33
-#define SYS_vmm_add_gpcs 34
-#define SYS_vc_entry 35
-#define SYS_nanosleep 36
-#define SYS_pop_ctx 37
-#define SYS_vmm_poke_guest 38
-#define SYS_send_event 39
-#define SYS_vmm_ctl 40
+#define SYS_null 1
+#define SYS_block 2
+#define SYS_cache_invalidate 3
+#define SYS_reboot 4
+/* was SYS_cputs 5 */
+/* was SYS_cgetc 6 */
+#define SYS_getpcoreid 7
+#define SYS_getvcoreid 8
+/* was #define SYS_getpid 9 */
+#define SYS_proc_create 10
+#define SYS_proc_run 11
+#define SYS_proc_destroy 12
+#define SYS_proc_yield 13
+#define SYS_change_vcore 14
+#define SYS_fork 15
+#define SYS_exec 16
+#define SYS_waitpid 17
+#define SYS_mmap 18
+#define SYS_munmap 19
+#define SYS_mprotect 20
+/* was SYS_brk 21 */
+#define SYS_shared_page_alloc 22
+#define SYS_shared_page_free 23
+#define SYS_provision 24
+#define SYS_notify 25
+#define SYS_self_notify 26
+#define SYS_halt_core 27
+#define SYS_init_arsc 28
+#define SYS_change_to_m 29
+#define SYS_poke_ksched 30
+#define SYS_abort_sysc 31
+#define SYS_populate_va 32
+#define SYS_abort_sysc_fd 33
+#define SYS_vmm_add_gpcs 34
+#define SYS_vc_entry 35
+#define SYS_nanosleep 36
+#define SYS_pop_ctx 37
+#define SYS_vmm_poke_guest 38
+#define SYS_send_event 39
+#define SYS_vmm_ctl 40
/* FS Syscalls */
-#define SYS_read 100
-#define SYS_write 101
-#define SYS_openat 102
-#define SYS_close 103
-#define SYS_fstat 104
-#define SYS_stat 105
-#define SYS_lstat 106
-#define SYS_fcntl 107
-#define SYS_access 108
-#define SYS_umask 109
-/* was SYS_chmod 110 */
-#define SYS_llseek 111
-#define SYS_link 112
-#define SYS_unlink 113
-#define SYS_symlink 114
-#define SYS_readlink 115
-#define SYS_chdir 116
-#define SYS_getcwd 117
-#define SYS_mkdir 118
-#define SYS_rmdir 119
-/* was SYS_pipe 120 */
+#define SYS_read 100
+#define SYS_write 101
+#define SYS_openat 102
+#define SYS_close 103
+#define SYS_fstat 104
+#define SYS_stat 105
+#define SYS_lstat 106
+#define SYS_fcntl 107
+#define SYS_access 108
+#define SYS_umask 109
+/* was SYS_chmod 110 */
+#define SYS_llseek 111
+#define SYS_link 112
+#define SYS_unlink 113
+#define SYS_symlink 114
+#define SYS_readlink 115
+#define SYS_chdir 116
+#define SYS_getcwd 117
+#define SYS_mkdir 118
+#define SYS_rmdir 119
+/* was SYS_pipe 120 */
-#define SYS_wstat 121
-#define SYS_fwstat 122
-#define SYS_rename 123
-#define SYS_fchdir 124
-#define SYS_dup_fds_to 125
-#define SYS_tap_fds 126
+#define SYS_wstat 121
+#define SYS_fwstat 122
+#define SYS_rename 123
+#define SYS_fchdir 124
+#define SYS_dup_fds_to 125
+#define SYS_tap_fds 126
/* Misc syscalls */
/* was #define SYS_gettimeofday 140 */
-#define SYS_tcgetattr 141
-#define SYS_tcsetattr 142
-#define SYS_setuid 143
-#define SYS_setgid 144
+#define SYS_tcgetattr 141
+#define SYS_tcsetattr 142
+#define SYS_setuid 143
+#define SYS_setgid 144
/* hotness! */
-#define SYS_nbind 145
-#define SYS_nmount 146
-#define SYS_nunmount 147
-/* was SYS_something 148 */
-#define SYS_fd2path 149
+#define SYS_nbind 145
+#define SYS_nmount 146
+#define SYS_nunmount 147
+/* was SYS_something 148 */
+#define SYS_fd2path 149
-#define MAX_SYSCALL_NR 200
+#define MAX_SYSCALL_NR 200
// for system calls that pass filenames
#define MAX_PATH_LEN 256
/* wstat flags, so the kernel knows what M fields to look at */
-#define WSTAT_MODE 0x001
-#define WSTAT_ATIME 0x002
-#define WSTAT_MTIME 0x004
-#define WSTAT_LENGTH 0x008
-#define WSTAT_NAME 0x010
-#define WSTAT_UID 0x020
-#define WSTAT_GID 0x040
-#define WSTAT_MUID 0x080
+#define WSTAT_MODE 0x001
+#define WSTAT_ATIME 0x002
+#define WSTAT_MTIME 0x004
+#define WSTAT_LENGTH 0x008
+#define WSTAT_NAME 0x010
+#define WSTAT_UID 0x020
+#define WSTAT_GID 0x040
+#define WSTAT_MUID 0x080
diff --git a/kern/include/ros/ceq.h b/kern/include/ros/ceq.h
index 4dce3de..bf40b48 100644
--- a/kern/include/ros/ceq.h
+++ b/kern/include/ros/ceq.h
@@ -38,14 +38,14 @@
#include <ros/atomic.h>
#include <ros/ring_buffer.h>
-#define CEQ_OR 1
-#define CEQ_ADD 2
+#define CEQ_OR 1
+#define CEQ_ADD 2
struct ceq_event {
- atomic_t coalesce; /* ev_arg2 */
- uint64_t blob_data; /* ev_arg3 */
- bool idx_posted; /* for syncing with consumer */
- uint64_t user_data; /* for apps, ignored by CEQ */
+ atomic_t coalesce; /* ev_arg2 */
+ uint64_t blob_data; /* ev_arg3 */
+ bool idx_posted; /* syncing with cons */
+ uint64_t user_data;
};
/* The events array and the ring buffer are provided by the consumer.
@@ -66,17 +66,17 @@
* (nr_empty) is the size - (prod - pub). */
struct ceq {
- struct ceq_event *events; /* consumer pointer */
- unsigned int nr_events;
- unsigned int last_recovered;
- atomic_t max_event_ever;
- int32_t *ring; /* consumer pointer */
- uint32_t ring_sz; /* size (power of 2) */
- uint8_t operation; /* e.g. CEQ_OR */
- bool ring_overflowed;
- bool overflow_recovery;
- atomic_t prod_idx; /* next prod slot to fill */
- atomic_t cons_pub_idx; /* how far has been consumed */
- atomic_t cons_pvt_idx; /* next cons slot to get */
- uint32_t u_lock[2]; /* user space lock */
+ struct ceq_event *events; /* consumer pointer */
+ unsigned int nr_events;
+ unsigned int last_recovered;
+ atomic_t max_event_ever;
+ int32_t *ring; /* consumer pointer */
+ uint32_t ring_sz; /* size (power of 2) */
+ uint8_t operation; /* e.g. CEQ_OR */
+ bool ring_overflowed;
+ bool overflow_recovery;
+ atomic_t prod_idx; /* next slot to fill */
+ atomic_t cons_pub_idx; /* consumed so far */
+ atomic_t cons_pvt_idx; /* next slot to get */
+ uint32_t u_lock[2]; /* user space lock */
};
diff --git a/kern/include/ros/common.h b/kern/include/ros/common.h
index 7bf4958..50cbac5 100644
--- a/kern/include/ros/common.h
+++ b/kern/include/ros/common.h
@@ -48,29 +48,29 @@
* that we can round down uint64_t, without chopping off the top 32 bits. */
#define ROUNDDOWN(a, n) \
({ \
- typeof(a) __b; \
- if (sizeof(a) == 8) { \
- uint64_t __a = (uint64_t) (a); \
- __b = (typeof(a)) (__a - __a % (n)); \
- } else { \
- uintptr_t __a = (uintptr_t) (a); \
- __b = (typeof(a)) (__a - __a % (n)); \
- } \
- __b; \
+ typeof(a) __b; \
+ if (sizeof(a) == 8) { \
+ uint64_t __a = (uint64_t) (a); \
+ __b = (typeof(a)) (__a - __a % (n)); \
+ } else { \
+ uintptr_t __a = (uintptr_t) (a); \
+ __b = (typeof(a)) (__a - __a % (n)); \
+ } \
+ __b; \
})
/* Round up to the nearest multiple of n */
#define ROUNDUP(a, n) \
({ \
- typeof(a) __b; \
- if (sizeof(a) == 8) { \
- uint64_t __n = (uint64_t) (n); \
- __b = (typeof(a)) (ROUNDDOWN((uint64_t) (a) + __n - 1, __n)); \
- } else { \
- uintptr_t __n = (uintptr_t) (n); \
- __b = (typeof(a)) (ROUNDDOWN((uintptr_t) (a) + __n - 1, __n)); \
- } \
- __b; \
+ typeof(a) __b; \
+ if (sizeof(a) == 8) { \
+ uint64_t __n = (uint64_t) (n); \
+ __b = (typeof(a)) (ROUNDDOWN((uint64_t) (a) + __n - 1, __n)); \
+ } else { \
+ uintptr_t __n = (uintptr_t) (n); \
+ __b = (typeof(a)) (ROUNDDOWN((uintptr_t) (a) + __n - 1, __n)); \
+ } \
+ __b; \
})
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
@@ -88,7 +88,9 @@
static inline uintptr_t LOG2_UP(uintptr_t value)
{
uintptr_t ret = LOG2_DOWN(value);
- ret += 0 != (value ^ ((uintptr_t) 1 << ret)); // Add 1 if a lower bit set
+
+ // Add 1 if a lower bit set
+ ret += 0 != (value ^ ((uintptr_t) 1 << ret));
return ret;
}
@@ -117,38 +119,39 @@
/* Return the container/struct holding the object 'ptr' points to */
#define container_of(ptr, type, member) ({ \
- (type*)((char*)ptr - offsetof(type, member)); \
+ (type*)((char*)ptr - offsetof(type, member)); \
})
/* Makes sure func is run exactly once. Can handle concurrent callers, and
* other callers spin til the func is complete. */
#define run_once(func) \
do { \
- static bool ran_once = FALSE; \
- static bool is_running = FALSE; \
- if (!ran_once) { \
- /* fetch and set TRUE, without a header or test_and_set weirdness */ \
- if (!__sync_fetch_and_or(&is_running, TRUE)) { \
- /* we won the race and get to run the func */ \
- func; \
- wmb(); /* don't let the ran_once write pass previous writes */ \
- ran_once = TRUE; \
- } else { \
- /* someone else won, wait til they are done to break out */ \
- while (!ran_once) \
- cpu_relax(); \
- } \
- } \
+ static bool ran_once = FALSE; \
+ static bool is_running = FALSE; \
+ if (!ran_once) { \
+ /* fetch and set TRUE, w/o a header or test_and_set weirdness*/\
+ if (!__sync_fetch_and_or(&is_running, TRUE)) { \
+ /* we won the race and get to run the func */ \
+ func; \
+ /* don't let the ran_once write pass previous writes */\
+ wmb(); \
+ ran_once = TRUE; \
+ } else { \
+ /* someone else woni */ \
+ while (!ran_once) \
+ cpu_relax(); \
+ } \
+ } \
} while (0)
/* Unprotected, single-threaded version, makes sure func is run exactly once */
#define run_once_racy(func) \
do { \
- static bool ran_once = FALSE; \
- if (!ran_once) { \
- func; \
- ran_once = TRUE; \
- } \
+ static bool ran_once = FALSE; \
+ if (!ran_once) { \
+ func; \
+ ran_once = TRUE; \
+ } \
} while (0)
#ifdef ROS_KERNEL
diff --git a/kern/include/ros/cpu_feat.h b/kern/include/ros/cpu_feat.h
index 1834699..cf2729c 100644
--- a/kern/include/ros/cpu_feat.h
+++ b/kern/include/ros/cpu_feat.h
@@ -12,8 +12,8 @@
#include <ros/common.h>
-#define CPU_FEAT_VMM 1
-#define __CPU_FEAT_ARCH_START 64
+#define CPU_FEAT_VMM 1
+#define __CPU_FEAT_ARCH_START 64
#include <ros/arch/cpu_feat.h>
diff --git a/kern/include/ros/evbitmap.h b/kern/include/ros/evbitmap.h
index 9ea7990..a434cea 100644
--- a/kern/include/ros/evbitmap.h
+++ b/kern/include/ros/evbitmap.h
@@ -10,6 +10,6 @@
#include <ros/bits/event.h>
struct evbitmap {
- bool check_bits;
- uint8_t bitmap[(MAX_NR_EVENT - 1) / 8 + 1];
+ bool check_bits;
+ uint8_t bitmap[(MAX_NR_EVENT - 1) / 8 + 1];
};
diff --git a/kern/include/ros/event.h b/kern/include/ros/event.h
index 4bf0234..d214e71 100644
--- a/kern/include/ros/event.h
+++ b/kern/include/ros/event.h
@@ -14,67 +14,67 @@
#include <ros/evbitmap.h>
#include <ros/ceq.h>
-#define EV_MBOX_UCQ 1
-#define EV_MBOX_BITMAP 2
-#define EV_MBOX_CEQ 3
+#define EV_MBOX_UCQ 1
+#define EV_MBOX_BITMAP 2
+#define EV_MBOX_CEQ 3
/* Structure for storing / receiving event messages. An overflow causes the
* bit of the event to get set in the bitmap. You can also have just the bit
* sent (and no message). */
struct event_mbox {
- int type;
+ int type;
union {
- struct ucq ucq;
- struct evbitmap evbm;
- struct ceq ceq;
+ struct ucq ucq;
+ struct evbitmap evbm;
+ struct ceq ceq;
};
};
/* The kernel sends messages to this structure, which describes how and where
* to receive messages, including optional IPIs. */
struct event_queue {
- struct event_mbox *ev_mbox;
- int ev_flags;
- bool ev_alert_pending;
- uint32_t ev_vcore;
- void (*ev_handler)(struct event_queue *);
- void *ev_udata;
+ struct event_mbox *ev_mbox;
+ int ev_flags;
+ bool ev_alert_pending;
+ uint32_t ev_vcore;
+ void (*ev_handler)(struct event_queue *);
+ void *ev_udata;
};
/* Big version, contains storage space for the ev_mbox. Never access the
* internal mbox directly. */
struct event_queue_big {
- struct event_mbox *ev_mbox;
- int ev_flags;
- bool ev_alert_pending;
- uint32_t ev_vcore;
- void (*ev_handler)(struct event_queue *);
- void *ev_udata;
- struct event_mbox ev_imbox;
+ struct event_mbox *ev_mbox;
+ int ev_flags;
+ bool ev_alert_pending;
+ uint32_t ev_vcore;
+ void (*ev_handler)(struct event_queue *);
+ void *ev_udata;
+ struct event_mbox ev_imbox;
};
/* Vcore state flags. K_LOCK means the kernel is writing */
-#define VC_K_LOCK 0x001 /* CASing with the kernel */
-#define VC_PREEMPTED 0x002 /* VC is preempted */
-#define VC_CAN_RCV_MSG 0x004 /* someone will get msg */
-#define VC_UTHREAD_STEALING 0x008 /* Uthread being stolen */
-#define VC_SCP_NOVCCTX 0x010 /* can't go into vc ctx */
+#define VC_K_LOCK 0x001 /* CASing with the kernel */
+#define VC_PREEMPTED 0x002 /* VC is preempted */
+#define VC_CAN_RCV_MSG 0x004 /* someone will get msg */
+#define VC_UTHREAD_STEALING 0x008 /* Uthread being stolen */
+#define VC_SCP_NOVCCTX 0x010 /* can't go into vc ctx */
/* Racy flags, where we don't need the atomics */
-#define VC_FPU_SAVED 0x1000 /* valid FPU state in anc */
+#define VC_FPU_SAVED 0x1000 /* valid FPU state in anc */
/* Per-core data about preemptions and notifications */
struct preempt_data {
- struct user_context vcore_ctx; /* for preemptions */
+ struct user_context vcore_ctx;
struct ancillary_state preempt_anc;
- struct user_context uthread_ctx; /* for preempts or notifs */
- uintptr_t vcore_entry; /* advertised by the user */
- uintptr_t vcore_stack; /* advertised by the user */
- uintptr_t vcore_tls_desc; /* advertised by the user */
- atomic_t flags;
- int rflags; /* racy flags */
- bool notif_disabled; /* vcore unwilling to recv*/
- bool notif_pending; /* notif k_msg on the way */
- struct event_mbox ev_mbox_public; /* can be read remotely */
- struct event_mbox ev_mbox_private; /* for this vcore only */
+ struct user_context uthread_ctx;
+ uintptr_t vcore_entry;
+ uintptr_t vcore_stack;
+ uintptr_t vcore_tls_desc;
+ atomic_t flags;
+ int rflags; /* racy flags */
+ bool notif_disabled;
+ bool notif_pending;
+ struct event_mbox ev_mbox_public;
+ struct event_mbox ev_mbox_private;
};
diff --git a/kern/include/ros/fdtap.h b/kern/include/ros/fdtap.h
index 64929a8..3f11456 100644
--- a/kern/include/ros/fdtap.h
+++ b/kern/include/ros/fdtap.h
@@ -8,9 +8,9 @@
/* FD Tap commands. The commands get passed to the device, but intermediate
* code will process them to some extent. */
-#define FDTAP_CMD_ADD 1
-#define FDTAP_CMD_REM 2
-#define FDTAP_CMD_MOD 3
+#define FDTAP_CMD_ADD 1
+#define FDTAP_CMD_REM 2
+#define FDTAP_CMD_MOD 3
/* FD Tap Event/Filter types. These are somewhat a mix of kqueue and epoll
* filters and are in flux. For instance, we don't support things like
@@ -18,27 +18,27 @@
*
* When using these, you're communicating directly with the device, so really
* anything goes, but we'll try to standardize on a few flags. */
-#define FDTAP_FILT_READABLE 0x00000001
-#define FDTAP_FILT_WRITABLE 0x00000002
-#define FDTAP_FILT_WRITTEN 0x00000004
-#define FDTAP_FILT_DELETED 0x00000008
-#define FDTAP_FILT_ERROR 0x00000010 /* may overwrite *data */
-#define FDTAP_FILT_RENAME 0x00000020
-#define FDTAP_FILT_TRUNCATE 0x00000040
-#define FDTAP_FILT_ATTRIB 0x00000080
-#define FDTAP_FILT_PRIORITY 0x00000100
-#define FDTAP_FILT_HANGUP 0x00000200
-#define FDTAP_FILT_RDHUP 0x00000400
+#define FDTAP_FILT_READABLE 0x00000001
+#define FDTAP_FILT_WRITABLE 0x00000002
+#define FDTAP_FILT_WRITTEN 0x00000004
+#define FDTAP_FILT_DELETED 0x00000008
+#define FDTAP_FILT_ERROR 0x00000010 /* may overwrite *data */
+#define FDTAP_FILT_RENAME 0x00000020
+#define FDTAP_FILT_TRUNCATE 0x00000040
+#define FDTAP_FILT_ATTRIB 0x00000080
+#define FDTAP_FILT_PRIORITY 0x00000100
+#define FDTAP_FILT_HANGUP 0x00000200
+#define FDTAP_FILT_RDHUP 0x00000400
/* When an event on FD matches filter, that event will be sent to ev_q with
* ev_id, with an optional data blob passed back. The specifics will depend on
* the type of ev_q used. For a CEQ, the event will coalesce, and the data will
* be a 'last write wins'. */
struct fd_tap_req {
- int fd;
- int cmd;
- int filter;
- int ev_id;
- struct event_queue *ev_q;
- void *data;
+ int fd;
+ int cmd;
+ int filter;
+ int ev_id;
+ struct event_queue *ev_q;
+ void *data;
};
diff --git a/kern/include/ros/fs.h b/kern/include/ros/fs.h
index 453d6bf..fe3bcad 100644
--- a/kern/include/ros/fs.h
+++ b/kern/include/ros/fs.h
@@ -8,11 +8,11 @@
* send the strlen along with the d_name. The sizes need rechecked too, since
* they are probably wrong. */
struct kdirent {
- __ino64_t d_ino; /* inode number */
- __off64_t d_off; /* offset to the next dirent */
- unsigned short d_reclen; /* length of this record */
- unsigned char d_type;
- char d_name[MAX_FILENAME_SZ + 1]; /* filename */
+ __ino64_t d_ino; /* inode number */
+ __off64_t d_off; /* offset to the next dirent */
+ unsigned short d_reclen; /* length of this record */
+ unsigned char d_type;
+ char d_name[MAX_FILENAME_SZ + 1]; /* filename */
} __attribute__((aligned(8)));
/* These stat sizes should match the types in stat.h and types.h and the sizes
@@ -20,19 +20,19 @@
* stat, we have this here so that the kernel is exporting the interface it
* expects. We #def stat for our own internal use at the end. */
struct kstat {
- __dev_t st_dev; /* Device. */
- __ino64_t st_ino; /* File serial number. */
- __mode_t st_mode; /* File mode. */
- __nlink_t st_nlink; /* Link count. */
- __uid_t st_uid; /* User ID of the file's owner. */
- __gid_t st_gid; /* Group ID of the file's group.*/
- __dev_t st_rdev; /* Device number, if device. */
- __off64_t st_size; /* Size of file, in bytes. */
- __blksize_t st_blksize; /* Optimal block size for I/O. */
- __blkcnt64_t st_blocks; /* Number 512-byte blocks allocd. */
- struct timespec st_atim; /* Time of last access. */
- struct timespec st_mtim; /* Time of last modification. */
- struct timespec st_ctim; /* Time of last status change. */
+ __dev_t st_dev; /* Device. */
+ __ino64_t st_ino; /* File serial number. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file owner */
+ __gid_t st_gid; /* Group ID of the file group */
+ __dev_t st_rdev; /* Device number, if device. */
+ __off64_t st_size; /* Size of file, in bytes. */
+ __blksize_t st_blksize; /* Optimal block size for I/O */
+ __blkcnt64_t st_blocks; /* Nr 512-byte blocks allocd. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification */
+ struct timespec st_ctim; /* Time of last status change */
};
/* File access modes for open and fcntl. */
@@ -41,12 +41,12 @@
#define O_EXEC 0x04 /* Open for exec */
#define O_RDONLY O_READ /* Open read-only */
#define O_WRONLY O_WRITE /* Open write-only */
-#define O_RDWR (O_READ | O_WRITE) /* Open read/write */
+#define O_RDWR (O_READ | O_WRITE) /* Open read/write */
#define O_ACCMODE 0x07
/* Bits OR'd into the second argument to open */
#define O_CREAT 00000100 /* not fcntl */
-#define O_CREATE O_CREAT /* fucking saving space with the 'E'? */
+#define O_CREATE O_CREAT
#define O_EXCL 00000200 /* not fcntl */
#define O_NOCTTY 00000400 /* not fcntl */
#define O_TRUNC 00001000 /* not fcntl */
@@ -61,38 +61,38 @@
#define O_NOFOLLOW 00400000 /* Do not follow links. */
#define O_NOATIME 01000000 /* Do not set atime. */
#define O_CLOEXEC 02000000 /* Set close_on_exec. */
-#define O_REMCLO 04000000 /* Remove on close (unsupported). */
+#define O_REMCLO 04000000 /* Remove on close. */
/* Keep this value in sync with glibc (io/fcntl.h) */
-#define AT_FDCWD -100
+#define AT_FDCWD -100
-#define F_DUPFD 0 /* Duplicate file descriptor */
-#define F_GETFD 1 /* Get file descriptor flags */
-#define F_SETFD 2 /* Set file descriptor flags */
-#define F_GETFL 3 /* Get file status flags */
-#define F_SETFL 4 /* Set file status flags */
-#define F_SYNC 101 /* fsync() */
-#define F_ADVISE 102 /* posix_fadvise{,64}() */
-#define F_CHANCTL_BASE 1000
+#define F_DUPFD 0 /* Duplicate file descriptor */
+#define F_GETFD 1 /* Get file descriptor flags */
+#define F_SETFD 2 /* Set file descriptor flags */
+#define F_GETFL 3 /* Get file status flags */
+#define F_SETFL 4 /* Set file status flags */
+#define F_SYNC 101 /* fsync() */
+#define F_ADVISE 102 /* posix_fadvise{,64}() */
+#define F_CHANCTL_BASE 1000
/* We don't need a GET_FL. The caller has the chan / FID. If you have the
* chan, you already have the flags. It's not like when you have an FD and
* don't (yet) have the Unix struct file. */
-#define CCTL_SET_FL (F_CHANCTL_BASE + 0)
-#define CCTL_SYNC (F_CHANCTL_BASE + 1)
-#define CCTL_DEBUG (F_CHANCTL_BASE + 2)
+#define CCTL_SET_FL (F_CHANCTL_BASE + 0)
+#define CCTL_SYNC (F_CHANCTL_BASE + 1)
+#define CCTL_DEBUG (F_CHANCTL_BASE + 2)
/* For F_[GET|SET]FD */
-#define FD_CLOEXEC 1
+#define FD_CLOEXEC 1
#define FD_VALID_FLAGS (FD_CLOEXEC)
/* Advise to `posix_fadvise'. */
-#define POSIX_FADV_NORMAL 0 /* No further special treatment */
-#define POSIX_FADV_RANDOM 1 /* Expect random page references */
+#define POSIX_FADV_NORMAL 0 /* No further special treatment */
+#define POSIX_FADV_RANDOM 1 /* Expect random page references */
#define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references */
-#define POSIX_FADV_WILLNEED 3 /* Will need these pages */
-#define POSIX_FADV_DONTNEED 4 /* Don't need these pages */
-#define POSIX_FADV_NOREUSE 5 /* Data will be accessed once */
+#define POSIX_FADV_WILLNEED 3 /* Will need these pages */
+#define POSIX_FADV_DONTNEED 4 /* Don't need these pages */
+#define POSIX_FADV_NOREUSE 5 /* Data will be accessed once */
/* TODO: have userpsace use our stuff from bits/stats.h */
#ifdef ROS_KERNEL
@@ -149,8 +149,8 @@
/* Non-standard bits */
#define __S_NONSTD 077000000 /* Magic Akaros bits */
-#define __S_READABLE 001000000 /* File is readable */
-#define __S_WRITABLE 002000000 /* File is writable */
+#define __S_READABLE 001000000 /* File is readable */
+#define __S_WRITABLE 002000000 /* File is writable */
/* Test macros for non-standard bits */
#define S_READABLE(mode) (((mode) & __S_READABLE) != 0)
diff --git a/kern/include/ros/mman.h b/kern/include/ros/mman.h
index 1086af0..576f234 100644
--- a/kern/include/ros/mman.h
+++ b/kern/include/ros/mman.h
@@ -15,8 +15,8 @@
#define PROT_WRITE 0x2
#define PROT_EXEC 0x4
#define PROT_NONE 0x0
-#define PROT_GROWSDOWN 0x01000000
-#define PROT_GROWSUP 0x02000000
+#define PROT_GROWSDOWN 0x01000000
+#define PROT_GROWSUP 0x02000000
// TODO NOT A REAL STATE
#define PROT_UNMAP 0x100
@@ -24,16 +24,16 @@
#define MAP_SHARED 0x01
#define MAP_PRIVATE 0x02
#define MAP_FIXED 0x10
-#define MAP_ANONYMOUS 0x20
+#define MAP_ANONYMOUS 0x20
#define MAP_ANON MAP_ANONYMOUS
-#define MAP_GROWSDOWN 0x00100
-#define MAP_DENYWRITE 0x00800
-#define MAP_EXECUTABLE 0x01000
+#define MAP_GROWSDOWN 0x00100
+#define MAP_DENYWRITE 0x00800
+#define MAP_EXECUTABLE 0x01000
#define MAP_LOCKED 0x02000
-#define MAP_NORESERVE 0x04000
-#define MAP_POPULATE 0x08000
-#define MAP_NONBLOCK 0x10000
+#define MAP_NORESERVE 0x04000
+#define MAP_POPULATE 0x08000
+#define MAP_NONBLOCK 0x10000
#define MAP_STACK 0x20000
#define MAP_FAILED ((void*)-1)
diff --git a/kern/include/ros/procdata.h b/kern/include/ros/procdata.h
index 1480e7c..f05304c 100644
--- a/kern/include/ros/procdata.h
+++ b/kern/include/ros/procdata.h
@@ -14,19 +14,21 @@
typedef struct procdata {
/*
syscall_sring_t syscallring;
- char pad1[SYSCALLRINGSIZE - sizeof(syscall_sring_t)];
+ char pad1[SYSCALLRINGSIZE -
+ sizeof(syscall_sring_t)];
*/
syscall_sring_t *syscallring;
sysevent_sring_t syseventring;
- char pad2[SYSEVENTRINGSIZE - sizeof(sysevent_sring_t)];
- bool printx_on;
- uint8_t pad8;
- uint16_t pad16;
- uint32_t pad32;
+ char pad2[SYSEVENTRINGSIZE
+ - sizeof(sysevent_sring_t)];
+ bool printx_on;
+ uint8_t pad8;
+ uint16_t pad16;
+ uint32_t pad32;
struct resource_req res_req[MAX_NUM_RESOURCES];
struct event_queue *kernel_evts[MAX_NR_EVENT];
- /* Long range, would like these to be mapped in lazily, as the vcores are
- * requested. Sharing MAX_NUM_CORES is a bit weird too. */
+ /* Long range, would like these to be mapped in lazily, as the vcores
+ * are requested. Sharing MAX_NUM_CORES is a bit weird too. */
struct preempt_data vcore_preempt_data[MAX_NUM_CORES];
} procdata_t;
diff --git a/kern/include/ros/procinfo.h b/kern/include/ros/procinfo.h
index 56bf7d9..332ee61 100644
--- a/kern/include/ros/procinfo.h
+++ b/kern/include/ros/procinfo.h
@@ -25,20 +25,23 @@
struct vcore;
struct vcore {
#ifdef ROS_KERNEL
- TAILQ_ENTRY(vcore) list;
+ TAILQ_ENTRY(vcore) list;
#else /* userspace */
void *dummy_ptr1;
void *dummy_ptr2;
#endif /* ROS_KERNEL */
uint32_t pcoreid;
bool valid;
- uint32_t nr_preempts_sent; /* these two differ when a preempt*/
- uint32_t nr_preempts_done; /* is in flight. */
+ /* these two differ when a preempt is in flight. */
+ uint32_t nr_preempts_sent;
+ uint32_t nr_preempts_done;
uint64_t preempt_pending;
- /* A process can see cumulative runtime as of the last resume, and can also
- * calculate runtime in this interval, by adding (ns - resume) + total. */
- uint64_t resume_ticks; /* TSC at resume time */
- uint64_t total_ticks; /* ticks up to last offlining */
+ /* A process can see cumulative runtime as of the last resume, and can
+ * also calculate runtime in this interval, by adding (ns - resume) +
+ * total. */
+ uint64_t resume_ticks; /* TSC at resume time */
+ /* ticks up to last offlining */
+ uint64_t total_ticks;
};
struct pcore {
@@ -53,13 +56,13 @@
uint64_t tsc_freq;
uint64_t timing_overhead;
uintptr_t program_end;
- /* glibc relies on stuff above this point. if you change it, you need to
- * rebuild glibc. */
+ /* glibc relies on stuff above this point. if you change it, you need
+ * to rebuild glibc. */
bool is_mcp; /* is in multi mode */
- unsigned long res_grant[MAX_NUM_RESOURCES];
- struct vcore vcoremap[MAX_NUM_CORES];
+ unsigned long res_grant[MAX_NUM_RESOURCES];
+ struct vcore vcoremap[MAX_NUM_CORES];
uint32_t num_vcores;
- struct pcore pcoremap[MAX_NUM_CORES];
+ struct pcore pcoremap[MAX_NUM_CORES];
seq_ctr_t coremap_seqctr;
} procinfo_t;
#define PROCINFO_NUM_PAGES ((sizeof(procinfo_t)-1)/PGSIZE + 1)
@@ -95,18 +98,20 @@
static inline uint32_t __get_vcoreid_from_procinfo(void)
{
/* The assumption is that any IPIs/KMSGs would knock userspace into the
- * kernel before it could read the closing of the seqctr. Put another way,
- * there is a 'memory barrier' between the IPI write and the seqctr write.
- * I think this is true. */
+ * kernel before it could read the closing of the seqctr. Put another
+ * way, there is a 'memory barrier' between the IPI write and the seqctr
+ * write. I think this is true. */
uint32_t kpcoreid, kvcoreid;
extern long __ros_syscall_noerrno(unsigned int _num, long _a0, long _a1,
- long _a2, long _a3, long _a4, long _a5);
+ long _a2, long _a3, long _a4,
+ long _a5);
seq_ctr_t old_seq;
do {
cmb();
old_seq = __procinfo.coremap_seqctr;
- kpcoreid = __ros_syscall_noerrno(SYS_getpcoreid, 0, 0, 0, 0, 0, 0);
+ kpcoreid = __ros_syscall_noerrno(SYS_getpcoreid, 0, 0, 0, 0, 0,
+ 0);
if (!__procinfo.pcoremap[kpcoreid].valid)
continue;
kvcoreid = __procinfo.pcoremap[kpcoreid].vcoreid;
diff --git a/kern/include/ros/profiler_records.h b/kern/include/ros/profiler_records.h
index fb6b785..4989a7b 100644
--- a/kern/include/ros/profiler_records.h
+++ b/kern/include/ros/profiler_records.h
@@ -29,7 +29,7 @@
uint64_t trace[0];
} __attribute__((packed));
-#define PROFTYPE_PID_MMAP64 3
+#define PROFTYPE_PID_MMAP64 3
struct proftype_pid_mmap64 {
uint64_t tstamp;
diff --git a/kern/include/ros/resource.h b/kern/include/ros/resource.h
index 3bf6206..58e3110 100644
--- a/kern/include/ros/resource.h
+++ b/kern/include/ros/resource.h
@@ -11,17 +11,17 @@
#include <ros/common.h>
/* Types of resource requests */
-#define RES_CORES 0
-#define RES_MEMORY 1
-#define RES_APPLE_PIES 2
-#define MAX_NUM_RESOURCES 3
+#define RES_CORES 0
+#define RES_MEMORY 1
+#define RES_APPLE_PIES 2
+#define MAX_NUM_RESOURCES 3
/* Flags */
-#define REQ_ASYNC 0x01 // Sync by default (?)
-#define REQ_SOFT 0x02 // just making something up
+#define REQ_ASYNC 0x01 // Sync by default (?)
+#define REQ_SOFT 0x02 // just making something up
struct resource_req {
- unsigned long amt_wanted;
- unsigned long amt_wanted_min;
- int flags;
+ unsigned long amt_wanted;
+ unsigned long amt_wanted_min;
+ int flags;
};
diff --git a/kern/include/ros/ring_syscall.h b/kern/include/ros/ring_syscall.h
index 522a4c6..6bee652 100644
--- a/kern/include/ros/ring_syscall.h
+++ b/kern/include/ros/ring_syscall.h
@@ -8,13 +8,17 @@
* syscalls themselves */
struct syscall;
typedef enum {
- RES_free, // The response has been digested by the user space, can be reallocated
- REQ_alloc, // Space fo request is allocated
- REQ_ready, // The request is populated by the caller
- REQ_processing, // The request is being processed,
- // or a kernel thread is going to pick up the stack to process this later.
-
- RES_ready // The response is ready to be picked up
+ // The response has been digested by the user space, can be reallocated
+ RES_free,
+ // Space fo request is allocated
+ REQ_alloc,
+ // The request is populated by the caller
+ REQ_ready,
+ // The request is being processed, or a kernel thread is going to pick
+ // up the stack to process this later.
+ REQ_processing,
+ // The response is ready to be picked up
+ RES_ready
} syscall_status_t;
typedef struct syscall_req {
diff --git a/kern/include/ros/syscall.h b/kern/include/ros/syscall.h
index 556299e..cd7c023 100644
--- a/kern/include/ros/syscall.h
+++ b/kern/include/ros/syscall.h
@@ -6,29 +6,29 @@
#include <ros/atomic.h>
/* Flags for an individual syscall. */
-#define SC_DONE 0x0001 /* SC is done */
-#define SC_PROGRESS 0x0002 /* SC made progress */
-#define SC_UEVENT 0x0004 /* user has an ev_q */
-#define SC_K_LOCK 0x0008 /* kernel locked sysc */
-#define SC_ABORT 0x0010 /* syscall abort attempted */
+#define SC_DONE 0x0001 /* SC is done */
+#define SC_PROGRESS 0x0002 /* SC made progress */
+#define SC_UEVENT 0x0004 /* user has an ev_q */
+#define SC_K_LOCK 0x0008 /* kernel locked sysc */
+#define SC_ABORT 0x0010 /* syscall abort attempted */
-#define MAX_ERRSTR_LEN 128
-#define SYSTR_BUF_SZ PGSIZE
+#define MAX_ERRSTR_LEN 128
+#define SYSTR_BUF_SZ PGSIZE
struct syscall {
- unsigned int num;
- int err; /* errno */
- long retval;
- atomic_t flags;
- struct event_queue *ev_q;
- void *u_data;
- long arg0;
- long arg1;
- long arg2;
- long arg3;
- long arg4;
- long arg5;
- char errstr[MAX_ERRSTR_LEN];
+ unsigned int num;
+ int err; /* errno */
+ long retval;
+ atomic_t flags;
+ struct event_queue *ev_q;
+ void *u_data;
+ long arg0;
+ long arg1;
+ long arg2;
+ long arg3;
+ long arg4;
+ long arg5;
+ char errstr[MAX_ERRSTR_LEN];
};
static inline bool syscall_retval_is_error(unsigned int sysc_nr, long retval)
@@ -115,9 +115,9 @@
}
struct childfdmap {
- unsigned int parentfd;
- unsigned int childfd;
- int ok;
+ unsigned int parentfd;
+ unsigned int childfd;
+ int ok;
};
struct argenv {
diff --git a/kern/include/ros/trapframe.h b/kern/include/ros/trapframe.h
index 28251a1..00540e0 100644
--- a/kern/include/ros/trapframe.h
+++ b/kern/include/ros/trapframe.h
@@ -4,18 +4,18 @@
#include <ros/arch/trapframe.h>
-#define ROS_HW_CTX 1
-#define ROS_SW_CTX 2
-#define ROS_VM_CTX 3
+#define ROS_HW_CTX 1
+#define ROS_SW_CTX 2
+#define ROS_VM_CTX 3
/* User-space context, either from a hardware event (IRQ, trap, etc), from a
* syscall, or virtual machine. Each arch defines its types. */
struct user_context {
- int type;
+ int type;
union {
- struct hw_trapframe hw_tf;
- struct sw_trapframe sw_tf;
- struct vm_trapframe vm_tf;
+ struct hw_trapframe hw_tf;
+ struct sw_trapframe sw_tf;
+ struct vm_trapframe vm_tf;
} tf;
};
diff --git a/kern/include/ros/ucq.h b/kern/include/ros/ucq.h
index 2f8dce2..21e4101 100644
--- a/kern/include/ros/ucq.h
+++ b/kern/include/ros/ucq.h
@@ -32,26 +32,26 @@
/* The main UCQ structure, contains indexes and start points (for the indexes),
* etc. */
struct ucq {
- atomic_t prod_idx; /* both pg and slot nr */
- atomic_t spare_pg; /* mmaped, unused page */
- atomic_t nr_extra_pgs; /* nr pages mmaped */
- atomic_t cons_idx; /* cons pg and slot nr */
- bool prod_overflow; /* flag to prevent wraparound */
- bool ucq_ready; /* ucq is ready to be used */
+ atomic_t prod_idx; /* both pg and slot nr */
+ atomic_t spare_pg; /* mmaped, unused page */
+ atomic_t nr_extra_pgs; /* nr pages mmaped */
+ atomic_t cons_idx; /* cons pg and slot nr */
+ bool prod_overflow;/* prevent wraparound */
+ bool ucq_ready;
/* Userspace lock for modifying the UCQ */
- uint32_t u_lock[2];
+ uint32_t u_lock[2];
};
/* Struct at the beginning of every page/buffer, tracking consumers and
* pointing to the next one, so that the consumer can follow. */
struct ucq_page_header {
- uintptr_t cons_next_pg; /* next page to consume */
- atomic_t nr_cons; /* like an inverted refcnt */
+ uintptr_t cons_next_pg; /* next page to consume */
+ atomic_t nr_cons; /* like an inverted refcnt */
};
struct msg_container {
- struct event_msg ev_msg;
- bool ready; /* kernel has written */
+ struct event_msg ev_msg;
+ bool ready;
};
struct ucq_page {
@@ -59,7 +59,7 @@
struct msg_container msgs[];
};
-#define UCQ_WARN_THRESH 1000 /* nr pages befor warning */
+#define UCQ_WARN_THRESH 1000 /* nr pages befor warning */
#define NR_MSG_PER_PAGE ((PGSIZE - ROUNDUP(sizeof(struct ucq_page_header), \
__alignof__(struct msg_container))) \
@@ -70,6 +70,7 @@
{
uintptr_t counter = PGOFF(slot);
uintptr_t pg_addr = PTE_ADDR(slot);
+
return ((counter < NR_MSG_PER_PAGE) && pg_addr) ? TRUE : FALSE;
}
diff --git a/kern/include/ros/vmm.h b/kern/include/ros/vmm.h
index 7e03fdb..fc0ac44 100644
--- a/kern/include/ros/vmm.h
+++ b/kern/include/ros/vmm.h
@@ -25,4 +25,4 @@
#define VMM_CTL_ALL_EXITS ((1 << 3) - 1)
#define VMM_CTL_FL_KERN_PRINTC (1 << 0)
-#define VMM_CTL_ALL_FLAGS (VMM_CTL_FL_KERN_PRINTC)
+#define VMM_CTL_ALL_FLAGS (VMM_CTL_FL_KERN_PRINTC)
diff --git a/kern/include/rwlock.h b/kern/include/rwlock.h
index e33273b..bbd3b2e 100644
--- a/kern/include/rwlock.h
+++ b/kern/include/rwlock.h
@@ -17,11 +17,11 @@
#include <atomic.h>
struct rwlock {
- spinlock_t lock;
- atomic_t nr_readers;
- bool writing;
- struct cond_var readers;
- struct cond_var writers;
+ spinlock_t lock;
+ atomic_t nr_readers;
+ bool writing;
+ struct cond_var readers;
+ struct cond_var writers;
};
typedef struct rwlock rwlock_t;
diff --git a/kern/include/schedule.h b/kern/include/schedule.h
index eddcf8b..9d0c460 100644
--- a/kern/include/schedule.h
+++ b/kern/include/schedule.h
@@ -17,9 +17,9 @@
/* One of these embedded in every struct proc */
struct sched_proc_data {
- TAILQ_ENTRY(proc) proc_link; /* tailq linkage */
- struct proc_list *cur_list; /* which tailq we're on */
- struct core_request_data crd; /* prov/alloc cores */
+ TAILQ_ENTRY(proc) proc_link;
+ struct proc_list *cur_list; /* which tailq we're on */
+ struct core_request_data crd; /* prov/alloc cores */
/* count of lists? */
/* other accounting info */
};
diff --git a/kern/include/slab.h b/kern/include/slab.h
index 64a8cd0..812985c 100644
--- a/kern/include/slab.h
+++ b/kern/include/slab.h
@@ -38,42 +38,42 @@
#define NUM_BUF_PER_SLAB 8
#define SLAB_LARGE_CUTOFF (PGSIZE / NUM_BUF_PER_SLAB)
-#define KMC_NAME_SZ 32
-#define KMC_MAG_MIN_SZ 8
-#define KMC_MAG_MAX_SZ 62 /* chosen for mag size and caching */
+#define KMC_NAME_SZ 32
+#define KMC_MAG_MIN_SZ 8
+#define KMC_MAG_MAX_SZ 62 /* chosen for mag size and caching */
/* Cache creation flags: */
-#define KMC_NOTOUCH 0x0001 /* Can't use source/object's memory */
-#define KMC_QCACHE 0x0002 /* Cache is an arena's qcache */
-#define KMC_NOTRACE 0x0004 /* Do not trace allocations */
-#define __KMC_USE_BUFCTL 0x1000 /* Internal use */
-#define __KMC_TRACED 0x2000 /* Internal use */
-#define __KMC_EVER_TRACED 0x3000 /* Internal use */
+#define KMC_NOTOUCH 0x0001 /* Can't use source/object's memory */
+#define KMC_QCACHE 0x0002 /* Cache is an arena's qcache */
+#define KMC_NOTRACE 0x0004 /* Do not trace allocations */
+#define __KMC_USE_BUFCTL 0x1000 /* Internal use */
+#define __KMC_TRACED 0x2000 /* Internal use */
+#define __KMC_EVER_TRACED 0x3000 /* Internal use */
struct kmem_magazine {
SLIST_ENTRY(kmem_magazine) link;
- unsigned int nr_rounds;
- void *rounds[KMC_MAG_MAX_SZ];
+ unsigned int nr_rounds;
+ void *rounds[KMC_MAG_MAX_SZ];
} __attribute__((aligned(ARCH_CL_SIZE)));
SLIST_HEAD(kmem_mag_slist, kmem_magazine);
struct kmem_pcpu_cache {
- int8_t irq_state;
- unsigned int magsize;
+ int8_t irq_state;
+ unsigned int magsize;
struct kmem_magazine *loaded;
struct kmem_magazine *prev;
- size_t nr_allocs_ever;
+ size_t nr_allocs_ever;
} __attribute__((aligned(ARCH_CL_SIZE)));
struct kmem_depot {
- spinlock_t lock;
+ spinlock_t lock;
struct kmem_mag_slist not_empty;
struct kmem_mag_slist empty;
- unsigned int magsize;
- unsigned int nr_empty;
- unsigned int nr_not_empty;
- unsigned int busy_count;
- uint64_t busy_start;
+ unsigned int magsize;
+ unsigned int nr_empty;
+ unsigned int nr_not_empty;
+ unsigned int busy_count;
+ uint64_t busy_start;
};
struct kmem_slab;
@@ -102,18 +102,18 @@
TAILQ_HEAD(kmem_slab_list, kmem_slab);
struct kmem_trace {
- void *obj;
- struct hlist_node hash;
- size_t nr_pcs;
- uintptr_t pcs[MAX_BT_DEPTH];
- char str[60];
+ void *obj;
+ struct hlist_node hash;
+ size_t nr_pcs;
+ uintptr_t pcs[MAX_BT_DEPTH];
+ char str[60];
};
struct kmem_trace_ht {
- spinlock_t lock;
- struct hash_helper hh;
- struct hlist_head *ht;
- struct hlist_head static_ht[HASH_INIT_SZ];
+ spinlock_t lock;
+ struct hash_helper hh;
+ struct hlist_head *ht;
+ struct hlist_head static_ht[HASH_INIT_SZ];
};
/* Actual cache */
diff --git a/kern/include/smp.h b/kern/include/smp.h
index 5a04a9a..4f4e5cf 100644
--- a/kern/include/smp.h
+++ b/kern/include/smp.h
@@ -35,8 +35,8 @@
struct per_cpu_info {
#ifdef CONFIG_X86
- uintptr_t stacktop; /* must be first */
- int coreid; /* must be second */
+ uintptr_t stacktop; /* must be first */
+ int coreid; /* must be second */
int nmi_status;
uintptr_t nmi_worker_stacktop;
int vmx_enabled;
@@ -47,10 +47,10 @@
// cur_proc should be valid on all cores that are not management cores.
struct proc *cur_proc; /* which process context is loaded */
struct proc *owning_proc; /* proc owning the core / cur_ctx */
- uint32_t owning_vcoreid; /* vcoreid of owning proc (if applicable */
+ uint32_t owning_vcoreid; /* of owning proc, if applicable */
struct user_context *cur_ctx; /* user ctx we came in on (can be 0) */
struct user_context actual_ctx; /* storage for cur_ctx */
- uint32_t __ctx_depth; /* don't access directly. see trap.h. */
+ uint32_t __ctx_depth; /* don't access directly. see trap.h.*/
int __lock_checking_enabled;/* == 1, enables spinlock depth checking */
struct kthread *cur_kthread;/* tracks the running kernel context */
struct kthread *spare; /* useful when restarting */
@@ -115,9 +115,9 @@
/* PCPUI Trace Rings: */
struct pcpu_trace_event {
- int type;
- int arg0;
- uint64_t arg1;
+ int type;
+ int arg0;
+ uint64_t arg1;
};
/* If you want to add a type, use the next available number, increment NR_TYPES,
@@ -132,11 +132,11 @@
# define pcpui_trace_kmsg(pcpui, pc) \
{ \
- struct pcpu_trace_event *e = get_trace_slot_racy(&pcpui->traces); \
- if (e) { \
- e->type = PCPUI_TR_TYPE_KMSG; \
- e->arg1 = pc; \
- } \
+ struct pcpu_trace_event *e = get_trace_slot_racy(&pcpui->traces); \
+ if (e) { \
+ e->type = PCPUI_TR_TYPE_KMSG; \
+ e->arg1 = pc; \
+ } \
}
#else
@@ -150,12 +150,12 @@
# define pcpui_trace_locks(pcpui, lock) \
{ \
- struct pcpu_trace_event *e = get_trace_slot_overwrite(&pcpui->traces); \
- if (e) { \
- e->type = PCPUI_TR_TYPE_LOCKS; \
- e->arg0 = (int)tsc2usec(read_tsc()); \
- e->arg1 = (uintptr_t)lock; \
- } \
+ struct pcpu_trace_event *e = get_trace_slot_overwrite(&pcpui->traces); \
+ if (e) { \
+ e->type = PCPUI_TR_TYPE_LOCKS; \
+ e->arg0 = (int)tsc2usec(read_tsc()); \
+ e->arg1 = (uintptr_t)lock; \
+ } \
}
#else
@@ -165,7 +165,7 @@
#endif /* CONFIG_TRACE_LOCKS */
void smp_do_in_cores(const struct core_set *cset, void (*func)(void *),
- void *opaque);
+ void *opaque);
/* Run the handlers for all events in a pcpui ring. Can run on all cores, or
* just one core. 'type' selects which event type is handled (0 for all). */
diff --git a/kern/include/syscall.h b/kern/include/syscall.h
index 304b4e8..9d0ede0 100644
--- a/kern/include/syscall.h
+++ b/kern/include/syscall.h
@@ -10,19 +10,18 @@
#include <ns.h>
#include <bitmap.h>
-#define SYSTRACE_ON 0x01
-#define SYSTRACE_LOUD 0x02
-#define SYSTRACE_ALLPROC 0x04
+#define SYSTRACE_ON 0x01
+#define SYSTRACE_LOUD 0x02
+#define SYSTRACE_ALLPROC 0x04
-#define MAX_SYSTRACES 1024
+#define MAX_SYSTRACES 1024
-#define SYSCALL_STRLEN 128
+#define SYSCALL_STRLEN 128
-#define MAX_ASRC_BATCH 10
+#define MAX_ASRC_BATCH 10
-#define SYSTR_RECORD_SZ 256
-#define SYSTR_PRETTY_BUF_SZ (SYSTR_BUF_SZ - \
- sizeof(struct systrace_record))
+#define SYSTR_RECORD_SZ 256
+#define SYSTR_PRETTY_BUF_SZ (SYSTR_BUF_SZ - sizeof(struct systrace_record))
struct systrace_record {
struct systrace_record_anon {
uint64_t start_timestamp, end_timestamp;
@@ -34,14 +33,14 @@
uintreg_t arg4;
uintreg_t arg5;
uintreg_t retval;
- int pid;
+ int pid;
uint32_t coreid;
uint32_t vcoreid;
char *pretty_buf;
uint8_t datalen;
- int errno;
+ int errno;
};
- uint8_t data[SYSTR_RECORD_SZ - sizeof(struct systrace_record_anon)];
+ uint8_t data[SYSTR_RECORD_SZ - sizeof(struct systrace_record_anon)];
};
struct strace {
@@ -51,7 +50,7 @@
atomic_t nr_drops;
unsigned long appx_nr_sysc;
struct kref procs; /* when procs goes to zero, q is hung up. */
- struct kref users; /* when users goes to zero, q and struct are freed. */
+ struct kref users; /* when users goes to zero, q and struct are freed.*/
struct queue *q;
spinlock_t lock;
DECLARE_BITMAP(trace_set, MAX_SYSCALL_NR);
diff --git a/kern/include/taskqueue.h b/kern/include/taskqueue.h
index acbb413..375b37c 100644
--- a/kern/include/taskqueue.h
+++ b/kern/include/taskqueue.h
@@ -22,8 +22,8 @@
typedef void (*task_fn_t)(void *context, int pending);
struct taskqueue {};
struct task {
- task_fn_t ta_func; /* task handler */
- void *ta_context; /* argument for handler */
+ task_fn_t ta_func; /* task handler */
+ void *ta_context; /* arg for handler */
};
#define taskqueue_drain(x, y)
@@ -36,7 +36,7 @@
/* We're already fast, no need for another function! */
#define taskqueue_enqueue_fast taskqueue_enqueue
#define TASK_INIT(str, dummy, func, arg) \
- (str)->ta_func = func; \
+ (str)->ta_func = func; \
(str)->ta_context = (void*)arg;
struct workqueue_struct {
@@ -51,7 +51,7 @@
/* Delayed work is embedded in other structs. Handlers will expect to get a
* work_struct pointer. */
struct delayed_work {
- struct work_struct work;
+ struct work_struct work;
/* TODO: support for the actual alarm / timer */
};
diff --git a/kern/include/termios.h b/kern/include/termios.h
index 6a22c64..addc81d 100644
--- a/kern/include/termios.h
+++ b/kern/include/termios.h
@@ -26,8 +26,8 @@
tcflag_t c_lflag; /* local mode flags */
cc_t c_line; /* line discipline */
cc_t c_cc[NCCS]; /* control characters */
- /* these last two might not be supported by all glibc builds. search for
- * _HAVE_STRUCT_TERMIOS_C_ISPEED and friends. */
+ /* these last two might not be supported by all glibc builds. search
+ * for _HAVE_STRUCT_TERMIOS_C_ISPEED and friends. */
speed_t c_ispeed; /* input speed */
speed_t c_ospeed; /* output speed */
};
diff --git a/kern/include/test_infrastructure.h b/kern/include/test_infrastructure.h
index b84d74f..59c8b21 100644
--- a/kern/include/test_infrastructure.h
+++ b/kern/include/test_infrastructure.h
@@ -12,31 +12,31 @@
/* Macros for assertions.
* They depend on <stdbool.h> and printk() to be included in the source file.
*/
-#define KT_ASSERT_M(message, test) \
- do { \
- if (!(test)) { \
- extern char *kern_test_msg; \
- char prefix[] = "Assertion failed: "; \
- int msg_size = sizeof(prefix) + sizeof(message) - 1; \
- kern_test_msg = (char*) kmalloc(msg_size, 0); \
- snprintf(kern_test_msg, msg_size, "%s%s", prefix, message); \
- return false; \
- } \
- } while (0)
+#define KT_ASSERT_M(message, test) \
+do { \
+ if (!(test)) { \
+ extern char *kern_test_msg; \
+ char prefix[] = "Assertion failed: "; \
+ int msg_size = sizeof(prefix) + sizeof(message) - 1; \
+ kern_test_msg = (char*) kmalloc(msg_size, 0); \
+ snprintf(kern_test_msg, msg_size, "%s%s", prefix, message); \
+ return false; \
+ } \
+} while (0)
-#define KT_ASSERT(test) \
- do { \
- if (!(test)) { \
- return false; \
- } \
- } while (0)
+#define KT_ASSERT(test) \
+do { \
+ if (!(test)) { \
+ return false; \
+ } \
+} while (0)
/* Postboot kernel tests: tests ran after boot in kernel mode. */
struct pb_kernel_test {
char name[256]; // Name of the test function.
- bool (*func)(void); // Name of the test function, should be equal to 'name'.
+ bool (*func)(void); // Name of the test function, should be = to 'name'.
bool enabled; // Whether to run or not the test.
};
diff --git a/kern/include/time.h b/kern/include/time.h
index ee88e30..32d42f5 100644
--- a/kern/include/time.h
+++ b/kern/include/time.h
@@ -16,28 +16,34 @@
uint64_t read_persistent_clock(void); /* arch-specific */
uint64_t tsc2nsec(uint64_t tsc_time);
+
static inline uint64_t tsc2usec(uint64_t tsc_time)
{
return tsc2nsec(tsc_time) / NSEC_PER_USEC;
}
+
static inline uint64_t tsc2msec(uint64_t tsc_time)
{
return tsc2nsec(tsc_time) / NSEC_PER_MSEC;
}
+
static inline uint64_t tsc2sec(uint64_t tsc_time)
{
return tsc2nsec(tsc_time) / NSEC_PER_SEC;
}
uint64_t nsec2tsc(uint64_t nsec);
+
static inline uint64_t usec2tsc(uint64_t usec)
{
return nsec2tsc(usec * NSEC_PER_USEC);
}
+
static inline uint64_t msec2tsc(uint64_t msec)
{
return nsec2tsc(msec * NSEC_PER_MSEC);
}
+
static inline uint64_t sec2tsc(uint64_t sec)
{
return nsec2tsc(sec * NSEC_PER_SEC);
@@ -125,8 +131,8 @@
_timer_##tag->curr_run = start_timing();
#define TAGGED_TIMING_END(tag) \
({ \
- _timer_##tag->curr_run = stop_timing(_timer_##tag->curr_run); \
- _timer_##tag->aggr_run += _timer_##tag->curr_run; \
+ _timer_##tag->curr_run = stop_timing(_timer_##tag->curr_run); \
+ _timer_##tag->aggr_run += _timer_##tag->curr_run; \
})
#endif
diff --git a/kern/include/trace.h b/kern/include/trace.h
index 9716c5f..1431da7 100644
--- a/kern/include/trace.h
+++ b/kern/include/trace.h
@@ -10,23 +10,23 @@
* Users need to provide a contiguous memory buffer and the size of an event
* struct to init. For example:
*
- * trace_ring_init(my_trace_ring_ptr, my_buf, buf_sz, event_sz);
+ * trace_ring_init(my_trace_ring_ptr, my_buf, buf_sz, event_sz);
*
* And then to store a trace, first get a slot, then fill it in:
*
- * struct my_trace_event *my_trace = get_trace_slot(my_trace_ring_ptr);
- * if (my_trace) // only need to check if we aren't overwriting
- * my_trace = whatever;
+ * struct my_trace_event *my_trace = get_trace_slot(my_trace_ring_ptr);
+ * if (my_trace) // only need to check if we aren't overwriting
+ * my_trace = whatever;
*
* Later, to process the traces, provide a function pointer to
* trace_ring_foreach(). This performs the func on all traces in the ring,
* including the unused:
*
- * void trace_handler(void *trace_event, void *data)
- * {
- * whatever();
- * }
- * trace_ring_foreach(my_trace_ring_ptr, trace_handler, optional_blob);
+ * void trace_handler(void *trace_event, void *data)
+ * {
+ * whatever();
+ * }
+ * trace_ring_foreach(my_trace_ring_ptr, trace_handler, optional_blob);
*
* Rings can be racy or not, and can overwrite entries or not. If you are not
* overwriting, the ring will stop giving you slots. You need to reset the ring
@@ -43,11 +43,11 @@
#include <assert.h>
struct trace_ring {
- unsigned char *tr_buf;
- size_t tr_buf_sz;
- unsigned int tr_event_sz_shift;
- unsigned int tr_max;
- unsigned long tr_next;
+ unsigned char *tr_buf;
+ size_t tr_buf_sz;
+ unsigned int tr_event_sz_shift;
+ unsigned int tr_max;
+ unsigned long tr_next;
};
typedef void (*trace_handler_t)(void *event, void *blob);
@@ -86,11 +86,13 @@
static inline void *get_trace_slot(struct trace_ring *tr)
{
- /* Using syncs, instead of atomics, since we access tr_next as both atomic
- * and 'normal'. */
+ /* Using syncs, instead of atomics, since we access tr_next as both
+ * atomic and 'normal'. */
unsigned long my_slot = __sync_fetch_and_add(&tr->tr_next, 1);
- /* We can briefly go over, so long as we subtract back down to where we were
- * before. This will work so long as we don't have ~2^64 threads... */
+
+ /* We can briefly go over, so long as we subtract back down to where we
+ * were before. This will work so long as we don't have ~2^64
+ * threads... */
if (my_slot >= tr->tr_max) {
__sync_fetch_and_add(&tr->tr_next, -1);
return 0;
@@ -106,6 +108,7 @@
static inline void *get_trace_slot_racy(struct trace_ring *tr)
{
unsigned long my_slot = tr->tr_next;
+
if (my_slot >= tr->tr_max)
return 0;
tr->tr_next++;
diff --git a/kern/include/trap.h b/kern/include/trap.h
index 294ff4a..d8c2683 100644
--- a/kern/include/trap.h
+++ b/kern/include/trap.h
@@ -123,8 +123,8 @@
* messages can have three arguments, but the deferred function pointer counts
* as one. Note the arguments to the function will be treated as longs. */
#define run_as_rkm(f, ...) do { \
- static_assert(MACRO_NR_ARGS(__VA_ARGS__) <= 2); \
- PASTE(__run_as_rkm_, MACRO_NR_ARGS(__VA_ARGS__))(f, ##__VA_ARGS__); \
+ static_assert(MACRO_NR_ARGS(__VA_ARGS__) <= 2); \
+ PASTE(__run_as_rkm_, MACRO_NR_ARGS(__VA_ARGS__))(f, ##__VA_ARGS__); \
} while (0)
#define __run_as_rkm_0(f) \
@@ -143,8 +143,8 @@
* user-space traps) we have.
*
* Some examples:
- * (original context in parens, +(x, y) is the change to IRQ and ktrap
- * depth):
+ * (original context in parens, +(x, y) is the change to IRQ and ktrap
+ * depth):
* - syscall (user): +(0, 0)
* - trap (user): +(0, 0)
* - irq (user): +(1, 0)
@@ -173,13 +173,13 @@
* +-------------+-------------+-------------+-------------+
*
*/
-#define __CTX_IRQ_D_SHIFT 0
-#define __CTX_KTRAP_D_SHIFT 8
-#define __CTX_FLAG_SHIFT 24
-#define __CTX_IRQ_D_MASK ((1 << 8) - 1)
-#define __CTX_KTRAP_D_MASK ((1 << 8) - 1)
+#define __CTX_IRQ_D_SHIFT 0
+#define __CTX_KTRAP_D_SHIFT 8
+#define __CTX_FLAG_SHIFT 24
+#define __CTX_IRQ_D_MASK ((1 << 8) - 1)
+#define __CTX_KTRAP_D_MASK ((1 << 8) - 1)
#define __CTX_NESTED_CTX_MASK ((1 << 16) - 1)
-#define __CTX_CANNOT_BLOCK (1 << (__CTX_FLAG_SHIFT + 0))
+#define __CTX_CANNOT_BLOCK (1 << (__CTX_FLAG_SHIFT + 0))
/* Basic functions to get or change depths */
diff --git a/kern/include/tree_file.h b/kern/include/tree_file.h
index 61c6c16..dab14e5 100644
--- a/kern/include/tree_file.h
+++ b/kern/include/tree_file.h
@@ -30,12 +30,12 @@
* the tree. They are never increffed, only rcu-read.
*/
struct walk_cache {
- spinlock_t lru_lock;
- struct list_head lru;
- spinlock_t ht_lock;
- struct hash_helper hh; /* parts are rcu-read */
- struct hlist_head *ht;
- struct hlist_head static_ht[HASH_INIT_SZ];
+ spinlock_t lru_lock;
+ struct list_head lru;
+ spinlock_t ht_lock;
+ struct hash_helper hh; /* parts are rcu-read */
+ struct hlist_head *ht;
+ struct hlist_head static_ht[HASH_INIT_SZ];
};
/* All ops that operate on a parent have the parent qlocked.
@@ -69,19 +69,21 @@
void (*free)(struct tree_file *tf);
void (*unlink)(struct tree_file *parent, struct tree_file *child);
void (*lookup)(struct tree_file *parent, struct tree_file *child);
- void (*create)(struct tree_file *parent, struct tree_file *child, int perm);
+ void (*create)(struct tree_file *parent, struct tree_file *child,
+ int perm);
void (*rename)(struct tree_file *tf, struct tree_file *old_parent,
- struct tree_file *new_parent, const char *name, int flags);
+ struct tree_file *new_parent, const char *name,
+ int flags);
bool (*has_children)(struct tree_file *parent);
};
struct tree_filesystem {
- struct walk_cache wc;
+ struct walk_cache wc;
struct tree_file_ops tf_ops;
- struct fs_file_ops fs_ops;
- qlock_t rename_mtx;
- struct tree_file *root;
- void *priv;
+ struct fs_file_ops fs_ops;
+ qlock_t rename_mtx;
+ struct tree_file *root;
+ void *priv;
};
/* The tree_file is an fs_file (i.e. the first struct field) that exists in a
@@ -157,25 +159,25 @@
* - Qlocking multiple files that aren't parent->child requires the rename_mtx
*/
struct tree_file {
- struct fs_file file;
- spinlock_t lifetime;
- int flags;
- struct kref kref;
- struct rcu_head rcu;
- struct tree_file *parent; /* rcu protected */
- struct hlist_node hash; /* rcu protected */
- struct list_head siblings;
- struct list_head children;
- struct list_head lru;
- bool can_have_children;
+ struct fs_file file;
+ spinlock_t lifetime;
+ int flags;
+ struct kref kref;
+ struct rcu_head rcu;
+ struct tree_file *parent; /* rcu protected */
+ struct hlist_node hash; /* rcu protected */
+ struct list_head siblings;
+ struct list_head children;
+ struct list_head lru;
+ bool can_have_children;
struct tree_filesystem *tfs;
};
-#define TF_F_DISCONNECTED (1 << 0)
-#define TF_F_NEGATIVE (1 << 1)
-#define TF_F_ON_LRU (1 << 2)
-#define TF_F_IS_ROOT (1 << 3)
-#define TF_F_HAS_BEEN_USED (1 << 4)
+#define TF_F_DISCONNECTED (1 << 0)
+#define TF_F_NEGATIVE (1 << 1)
+#define TF_F_ON_LRU (1 << 2)
+#define TF_F_IS_ROOT (1 << 3)
+#define TF_F_HAS_BEEN_USED (1 << 4)
/* Devices can put their tree_files / fs_files whereever they want. For now,
* all of them will use aux. We can make ops for this if we need it. */
diff --git a/kern/lib/address_range.c b/kern/lib/address_range.c
index 6e63589..dfb766d 100644
--- a/kern/lib/address_range.c
+++ b/kern/lib/address_range.c
@@ -35,7 +35,7 @@
}
const struct address_range *address_range_find(const struct address_range *ars,
- size_t count, uintptr_t addr)
+ size_t count, uintptr_t addr)
{
ssize_t l = 0, r = count - 1;
diff --git a/kern/lib/circular_buffer.c b/kern/lib/circular_buffer.c
index b720d0a..4ef522b 100644
--- a/kern/lib/circular_buffer.c
+++ b/kern/lib/circular_buffer.c
@@ -85,8 +85,8 @@
if (unlikely(esize > cb->allocated))
return 0;
- /* If at the end of the buffer, the next block to be written does not fit,
- * we move the pointer to the beginning of the circular buffer.
+ /* If at the end of the buffer, the next block to be written does not
+ * fit, we move the pointer to the beginning of the circular buffer.
*/
if (unlikely(esize > wspace)) {
circular_buffer_write_skip(cb, wrptr, wspace);
@@ -123,7 +123,8 @@
} else {
size_t csize = MIN(esize - off, size);
- memcpy(data, rdptr + sizeof(cbuf_size_t) + off, csize);
+ memcpy(data, rdptr + sizeof(cbuf_size_t) + off,
+ csize);
data += csize;
size -= csize;
rsize += csize;
diff --git a/kern/lib/cpio.c b/kern/lib/cpio.c
index eafdafa..7cec9a3 100644
--- a/kern/lib/cpio.c
+++ b/kern/lib/cpio.c
@@ -17,8 +17,8 @@
c_hdr = (struct cpio_newc_header*)(cpio_b + offset);
offset += sizeof(*c_hdr);
if (offset > cpio_sz) {
- printk("CPIO offset %d beyond size %d, aborting.\n", offset,
- cpio_sz);
+ printk("CPIO offset %d beyond size %d, aborting.\n",
+ offset, cpio_sz);
return;
}
if (strncmp(c_hdr->c_magic, "070701", 6)) {
@@ -34,14 +34,16 @@
c_bhdr->c_mode = (int)cpio_strntol(buf, c_hdr->c_mode, 8);
c_bhdr->c_uid = cpio_strntol(buf, c_hdr->c_uid, 8);
c_bhdr->c_gid = cpio_strntol(buf, c_hdr->c_gid, 8);
- c_bhdr->c_nlink = (unsigned int)cpio_strntol(buf, c_hdr->c_nlink, 8);
+ c_bhdr->c_nlink = (unsigned int)cpio_strntol(buf,
+ c_hdr->c_nlink, 8);
c_bhdr->c_mtime = cpio_strntol(buf, c_hdr->c_mtime, 8);
c_bhdr->c_filesize = cpio_strntol(buf, c_hdr->c_filesize, 8);
c_bhdr->c_dev_maj = cpio_strntol(buf, c_hdr->c_dev_maj, 8);
c_bhdr->c_dev_min = cpio_strntol(buf, c_hdr->c_dev_min, 8);
c_bhdr->c_rdev_maj = cpio_strntol(buf, c_hdr->c_rdev_maj, 8);
c_bhdr->c_rdev_min = cpio_strntol(buf, c_hdr->c_rdev_min, 8);
- printd("File: %s: %d Bytes\n", c_bhdr->c_filename, c_bhdr->c_filesize);
+ printd("File: %s: %d Bytes\n", c_bhdr->c_filename,
+ c_bhdr->c_filesize);
offset += namesize;
/* header + name will be padded out to 4-byte alignment */
offset = ROUNDUP(offset, 4);
@@ -49,8 +51,8 @@
offset += c_bhdr->c_filesize;
offset = ROUNDUP(offset, 4);
if (offset > cpio_sz) {
- printk("CPIO offset %d beyond size %d, aborting.\n", offset,
- cpio_sz);
+ printk("CPIO offset %d beyond size %d, aborting.\n",
+ offset, cpio_sz);
return;
}
if (cb(c_bhdr, cb_arg)) {
diff --git a/kern/lib/random/fortuna.c b/kern/lib/random/fortuna.c
index 90c86cf..0a645e5 100644
--- a/kern/lib/random/fortuna.c
+++ b/kern/lib/random/fortuna.c
@@ -36,7 +36,6 @@
#include <random/rijndael.h>
#include <random/sha2.h>
-
/*
* Why Fortuna-like: There does not seem to be any definitive reference
* on Fortuna in the net. Instead this implementation is based on
@@ -83,31 +82,29 @@
* In our case the minimal cycle time would be bit longer
* than the system-randomness feeding frequency.
*/
-enum {
- numPools = 23,
+enum { numPools = 23,
- /* in microseconds */
- reseedInterval = 100000, /* 0.1 sec */
+ /* in microseconds */
+ reseedInterval = 100000, /* 0.1 sec */
- /* for one big request, reseed after this many bytes */
- reseedBytes = (1024 * 1024),
+ /* for one big request, reseed after this many bytes */
+ reseedBytes = (1024 * 1024),
- /*
+ /*
* Skip reseed if pool 0 has less than this many
* bytes added since last reseed.
*/
- pool0Fill = (256 / 8),
+ pool0Fill = (256 / 8),
- /*
+ /*
* Algorithm constants
*/
- /* Both cipher key size and hash result size */
- block = 32,
+ /* Both cipher key size and hash result size */
+ block = 32,
- /* cipher block size */
- ciphBlock = 16
-};
+ /* cipher block size */
+ ciphBlock = 16 };
/* for internal wrappers */
typedef SHA256Ctx mdCtx;
@@ -145,7 +142,10 @@
rijndael_encrypt(ctx, (const uint32_t *)in, (uint32_t *)out);
}
-static void md_init(mdCtx *ctx) { SHA256_Init(ctx); }
+static void md_init(mdCtx *ctx)
+{
+ SHA256_Init(ctx);
+}
static void md_update(mdCtx *ctx, const uint8_t *data, int len)
{
diff --git a/kern/lib/random/rijndael.c b/kern/lib/random/rijndael.c
index 144ec61..94da1b2 100644
--- a/kern/lib/random/rijndael.c
+++ b/kern/lib/random/rijndael.c
@@ -4,17 +4,21 @@
/* This is an independent implementation of the encryption algorithm: */
/* */
-/* RIJNDAEL by Joan Daemen and Vincent Rijmen */
+/* RIJNDAEL by Joan Daemen and Vincent Rijmen
+ */
/* */
/* which is a candidate algorithm in the Advanced Encryption Standard */
/* programme of the US National Institute of Standards and Technology. */
/* */
-/* Copyright in this implementation is held by Dr B R Gladman but I */
+/* Copyright in this implementation is held by Dr B R Gladman but I
+ */
/* hereby give permission for its free direct or derivative use subject */
/* to acknowledgment of its origin and compliance with any conditions */
-/* that the originators of the algorithm place on its exploitation. */
+/* that the originators of the algorithm place on its exploitation.
+ */
/* */
-/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */
+/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999
+ */
/* Timing data for Rijndael (rijndael.c)
@@ -44,14 +48,16 @@
#include "rijndael.tbl"
-/* 3. Basic macros for speeding up generic operations */
+/* 3. Basic macros for speeding up generic operations */
-/* Circular rotate of 32 bit values */
+/* Circular rotate of 32 bit values
+ */
#define rotr(x, n) (((x) >> ((int)(n))) | ((x) << (32 - (int)(n))))
#define rotl(x, n) (((x) << ((int)(n))) | ((x) >> (32 - (int)(n))))
-/* Invert byte order in a 32 bit variable */
+/* Invert byte order in a 32 bit variable
+ */
#define bswap(x) ((rotl((x), 8) & 0x00ff00ff) | (rotr((x), 8) & 0xff00ff00))
@@ -65,100 +71,100 @@
((a) && (b) ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0)
#define f_rn(bo, bi, n, k) \
- (bo)[n] = ft_tab[0][byte((bi)[n], 0)] ^ \
- ft_tab[1][byte((bi)[((n) + 1) & 3], 1)] ^ \
- ft_tab[2][byte((bi)[((n) + 2) & 3], 2)] ^ \
- ft_tab[3][byte((bi)[((n) + 3) & 3], 3)] ^ *((k) + (n))
+ (bo)[n] = ft_tab[0][byte((bi)[n], 0)] ^ \
+ ft_tab[1][byte((bi)[((n) + 1) & 3], 1)] ^ \
+ ft_tab[2][byte((bi)[((n) + 2) & 3], 2)] ^ \
+ ft_tab[3][byte((bi)[((n) + 3) & 3], 3)] ^ *((k) + (n))
#define i_rn(bo, bi, n, k) \
- (bo)[n] = it_tab[0][byte((bi)[n], 0)] ^ \
- it_tab[1][byte((bi)[((n) + 3) & 3], 1)] ^ \
- it_tab[2][byte((bi)[((n) + 2) & 3], 2)] ^ \
- it_tab[3][byte((bi)[((n) + 1) & 3], 3)] ^ *((k) + (n))
+ (bo)[n] = it_tab[0][byte((bi)[n], 0)] ^ \
+ it_tab[1][byte((bi)[((n) + 3) & 3], 1)] ^ \
+ it_tab[2][byte((bi)[((n) + 2) & 3], 2)] ^ \
+ it_tab[3][byte((bi)[((n) + 1) & 3], 3)] ^ *((k) + (n))
#define ls_box(x) \
- (fl_tab[0][byte(x, 0)] ^ fl_tab[1][byte(x, 1)] ^ fl_tab[2][byte(x, 2)] ^ \
- fl_tab[3][byte(x, 3)])
+ (fl_tab[0][byte(x, 0)] ^ fl_tab[1][byte(x, 1)] ^ \
+ fl_tab[2][byte(x, 2)] ^ fl_tab[3][byte(x, 3)])
#define f_rl(bo, bi, n, k) \
- (bo)[n] = fl_tab[0][byte((bi)[n], 0)] ^ \
- fl_tab[1][byte((bi)[((n) + 1) & 3], 1)] ^ \
- fl_tab[2][byte((bi)[((n) + 2) & 3], 2)] ^ \
- fl_tab[3][byte((bi)[((n) + 3) & 3], 3)] ^ *((k) + (n))
+ (bo)[n] = fl_tab[0][byte((bi)[n], 0)] ^ \
+ fl_tab[1][byte((bi)[((n) + 1) & 3], 1)] ^ \
+ fl_tab[2][byte((bi)[((n) + 2) & 3], 2)] ^ \
+ fl_tab[3][byte((bi)[((n) + 3) & 3], 3)] ^ *((k) + (n))
#define i_rl(bo, bi, n, k) \
- (bo)[n] = il_tab[0][byte((bi)[n], 0)] ^ \
- il_tab[1][byte((bi)[((n) + 3) & 3], 1)] ^ \
- il_tab[2][byte((bi)[((n) + 2) & 3], 2)] ^ \
- il_tab[3][byte((bi)[((n) + 1) & 3], 3)] ^ *((k) + (n))
+ (bo)[n] = il_tab[0][byte((bi)[n], 0)] ^ \
+ il_tab[1][byte((bi)[((n) + 3) & 3], 1)] ^ \
+ il_tab[2][byte((bi)[((n) + 2) & 3], 2)] ^ \
+ il_tab[3][byte((bi)[((n) + 1) & 3], 3)] ^ *((k) + (n))
#define star_x(x) (((x)&0x7f7f7f7f) << 1) ^ ((((x)&0x80808080) >> 7) * 0x1b)
#define imix_col(y, x) \
- do { \
- u = star_x(x); \
- v = star_x(u); \
- w = star_x(v); \
- t = w ^ (x); \
- (y) = u ^ v ^ w; \
- (y) ^= rotr(u ^ t, 8) ^ rotr(v ^ t, 16) ^ rotr(t, 24); \
+ do { \
+ u = star_x(x); \
+ v = star_x(u); \
+ w = star_x(v); \
+ t = w ^ (x); \
+ (y) = u ^ v ^ w; \
+ (y) ^= rotr(u ^ t, 8) ^ rotr(v ^ t, 16) ^ rotr(t, 24); \
} while (0)
/* initialise the key schedule from the user supplied key */
#define loop4(i) \
- do { \
- t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \
- t ^= e_key[4 * i]; \
- e_key[4 * i + 4] = t; \
- t ^= e_key[4 * i + 1]; \
- e_key[4 * i + 5] = t; \
- t ^= e_key[4 * i + 2]; \
- e_key[4 * i + 6] = t; \
- t ^= e_key[4 * i + 3]; \
- e_key[4 * i + 7] = t; \
+ do { \
+ t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \
+ t ^= e_key[4 * i]; \
+ e_key[4 * i + 4] = t; \
+ t ^= e_key[4 * i + 1]; \
+ e_key[4 * i + 5] = t; \
+ t ^= e_key[4 * i + 2]; \
+ e_key[4 * i + 6] = t; \
+ t ^= e_key[4 * i + 3]; \
+ e_key[4 * i + 7] = t; \
} while (0)
#define loop6(i) \
- do { \
- t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \
- t ^= e_key[6 * (i)]; \
- e_key[6 * (i) + 6] = t; \
- t ^= e_key[6 * (i) + 1]; \
- e_key[6 * (i) + 7] = t; \
- t ^= e_key[6 * (i) + 2]; \
- e_key[6 * (i) + 8] = t; \
- t ^= e_key[6 * (i) + 3]; \
- e_key[6 * (i) + 9] = t; \
- t ^= e_key[6 * (i) + 4]; \
- e_key[6 * (i) + 10] = t; \
- t ^= e_key[6 * (i) + 5]; \
- e_key[6 * (i) + 11] = t; \
+ do { \
+ t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \
+ t ^= e_key[6 * (i)]; \
+ e_key[6 * (i) + 6] = t; \
+ t ^= e_key[6 * (i) + 1]; \
+ e_key[6 * (i) + 7] = t; \
+ t ^= e_key[6 * (i) + 2]; \
+ e_key[6 * (i) + 8] = t; \
+ t ^= e_key[6 * (i) + 3]; \
+ e_key[6 * (i) + 9] = t; \
+ t ^= e_key[6 * (i) + 4]; \
+ e_key[6 * (i) + 10] = t; \
+ t ^= e_key[6 * (i) + 5]; \
+ e_key[6 * (i) + 11] = t; \
} while (0)
#define loop8(i) \
- do { \
- t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \
- t ^= e_key[8 * (i)]; \
- e_key[8 * (i) + 8] = t; \
- t ^= e_key[8 * (i) + 1]; \
- e_key[8 * (i) + 9] = t; \
- t ^= e_key[8 * (i) + 2]; \
- e_key[8 * (i) + 10] = t; \
- t ^= e_key[8 * (i) + 3]; \
- e_key[8 * (i) + 11] = t; \
- t = e_key[8 * (i) + 4] ^ ls_box(t); \
- e_key[8 * (i) + 12] = t; \
- t ^= e_key[8 * (i) + 5]; \
- e_key[8 * (i) + 13] = t; \
- t ^= e_key[8 * (i) + 6]; \
- e_key[8 * (i) + 14] = t; \
- t ^= e_key[8 * (i) + 7]; \
- e_key[8 * (i) + 15] = t; \
+ do { \
+ t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \
+ t ^= e_key[8 * (i)]; \
+ e_key[8 * (i) + 8] = t; \
+ t ^= e_key[8 * (i) + 1]; \
+ e_key[8 * (i) + 9] = t; \
+ t ^= e_key[8 * (i) + 2]; \
+ e_key[8 * (i) + 10] = t; \
+ t ^= e_key[8 * (i) + 3]; \
+ e_key[8 * (i) + 11] = t; \
+ t = e_key[8 * (i) + 4] ^ ls_box(t); \
+ e_key[8 * (i) + 12] = t; \
+ t ^= e_key[8 * (i) + 5]; \
+ e_key[8 * (i) + 13] = t; \
+ t ^= e_key[8 * (i) + 6]; \
+ e_key[8 * (i) + 14] = t; \
+ t ^= e_key[8 * (i) + 7]; \
+ e_key[8 * (i) + 15] = t; \
} while (0)
rijndaelCtx *rijndael_set_key(rijndaelCtx *ctx, const uint32_t *in_key,
- const uint32_t key_len, int encrypt)
+ const uint32_t key_len, int encrypt)
{
uint32_t i, t, u, v, w;
uint32_t *e_key = ctx->e_key;
@@ -213,24 +219,24 @@
/* encrypt a block of text */
#define f_nround(bo, bi, k) \
- do { \
- f_rn(bo, bi, 0, k); \
- f_rn(bo, bi, 1, k); \
- f_rn(bo, bi, 2, k); \
- f_rn(bo, bi, 3, k); \
- k += 4; \
+ do { \
+ f_rn(bo, bi, 0, k); \
+ f_rn(bo, bi, 1, k); \
+ f_rn(bo, bi, 2, k); \
+ f_rn(bo, bi, 3, k); \
+ k += 4; \
} while (0)
#define f_lround(bo, bi, k) \
- do { \
- f_rl(bo, bi, 0, k); \
- f_rl(bo, bi, 1, k); \
- f_rl(bo, bi, 2, k); \
- f_rl(bo, bi, 3, k); \
+ do { \
+ f_rl(bo, bi, 0, k); \
+ f_rl(bo, bi, 1, k); \
+ f_rl(bo, bi, 2, k); \
+ f_rl(bo, bi, 3, k); \
} while (0)
void rijndael_encrypt(rijndaelCtx *ctx, const uint32_t *in_blk,
- uint32_t *out_blk)
+ uint32_t *out_blk)
{
uint32_t k_len = ctx->k_len;
uint32_t *e_key = ctx->e_key;
@@ -273,24 +279,24 @@
/* decrypt a block of text */
#define i_nround(bo, bi, k) \
- do { \
- i_rn(bo, bi, 0, k); \
- i_rn(bo, bi, 1, k); \
- i_rn(bo, bi, 2, k); \
- i_rn(bo, bi, 3, k); \
- k -= 4; \
+ do { \
+ i_rn(bo, bi, 0, k); \
+ i_rn(bo, bi, 1, k); \
+ i_rn(bo, bi, 2, k); \
+ i_rn(bo, bi, 3, k); \
+ k -= 4; \
} while (0)
#define i_lround(bo, bi, k) \
- do { \
- i_rl(bo, bi, 0, k); \
- i_rl(bo, bi, 1, k); \
- i_rl(bo, bi, 2, k); \
- i_rl(bo, bi, 3, k); \
+ do { \
+ i_rl(bo, bi, 0, k); \
+ i_rl(bo, bi, 1, k); \
+ i_rl(bo, bi, 2, k); \
+ i_rl(bo, bi, 3, k); \
} while (0)
void rijndael_decrypt(rijndaelCtx *ctx, const uint32_t *in_blk,
- uint32_t *out_blk)
+ uint32_t *out_blk)
{
uint32_t b0[4], b1[4], *kp;
uint32_t k_len = ctx->k_len;
@@ -339,7 +345,7 @@
*/
void aes_set_key(rijndaelCtx *ctx, const uint8_t *key, unsigned keybits,
- int enc)
+ int enc)
{
uint32_t *k;
@@ -376,7 +382,7 @@
}
void aes_cbc_encrypt(rijndaelCtx *ctx, uint8_t *iva, uint8_t *data,
- unsigned len)
+ unsigned len)
{
uint32_t *iv = (uint32_t *)iva;
uint32_t *d = (uint32_t *)data;
@@ -397,7 +403,7 @@
}
void aes_cbc_decrypt(rijndaelCtx *ctx, uint8_t *iva, uint8_t *data,
- unsigned len)
+ unsigned len)
{
uint32_t *d = (uint32_t *)data;
unsigned bs = 16;
diff --git a/kern/lib/random/sha2.c b/kern/lib/random/sha2.c
index ebd1556..e6eb0f3 100644
--- a/kern/lib/random/sha2.c
+++ b/kern/lib/random/sha2.c
@@ -39,10 +39,8 @@
#include <random/sha2.h>
/*** SHA-256/512 Various Length Definitions ***********************/
-enum {
- SHA256ShortBlockLength = (SHA256BlockLength - 8),
- SHA512ShortBlockLength = (SHA512_block_length - 16)
-};
+enum { SHA256ShortBlockLength = (SHA256BlockLength - 8),
+ SHA512ShortBlockLength = (SHA512_block_length - 16) };
/*
* Macro for incrementally adding the unsigned 64-bit integer n to the
@@ -50,11 +48,11 @@
* 64-bit words):
*/
#define ADDINC128(w, n) \
- { \
- (w)[0] += (uint64_t)(n); \
- if ((w)[0] < (n)) { \
- (w)[1]++; \
- } \
+ { \
+ (w)[0] += (uint64_t)(n); \
+ if ((w)[0] < (n)) { \
+ (w)[1]++; \
+ } \
}
/*** THE SIX LOGICAL FUNCTIONS ****************************************/
@@ -101,71 +99,71 @@
/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
/* Hash constant words K for SHA-256: */
const uint32_t K256[64] = {
- 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
- 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
- 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
- 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
- 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
- 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
- 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
- 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
- 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
- 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
- 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
- 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
- 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL};
+ 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
+ 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
+ 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
+ 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+ 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
+ 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
+ 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
+ 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+ 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
+ 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
+ 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
+ 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+ 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL};
/* Initial hash value H for SHA-224: */
const uint32_t sha224_initial_hash_value[8] = {
- 0xc1059ed8UL, 0x367cd507UL, 0x3070dd17UL, 0xf70e5939UL,
- 0xffc00b31UL, 0x68581511UL, 0x64f98fa7UL, 0xbefa4fa4UL};
+ 0xc1059ed8UL, 0x367cd507UL, 0x3070dd17UL, 0xf70e5939UL,
+ 0xffc00b31UL, 0x68581511UL, 0x64f98fa7UL, 0xbefa4fa4UL};
/* Initial hash value H for SHA-256: */
static const uint32_t sha256_initial_hash_value[8] = {
- 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL,
- 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL};
+ 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL,
+ 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL};
/* Hash constant words K for SHA-384 and SHA-512: */
static const uint64_t K512[80] = {
- 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
- 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
- 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
- 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
- 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
- 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
- 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
- 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
- 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
- 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
- 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
- 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
- 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
- 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
- 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
- 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
- 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
- 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
- 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
- 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
- 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
- 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
- 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
- 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
- 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
- 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
- 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
+ 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+ 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
+ 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+ 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
+ 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+ 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
+ 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+ 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
+ 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+ 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
+ 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+ 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
+ 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+ 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
+ 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+ 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
+ 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+ 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
+ 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
+ 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+ 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
+ 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+ 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
+ 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};
/* Initial hash value H for SHA-384 */
static const uint64_t sha384_initial_hash_value[8] = {
- 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL,
- 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
- 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL};
+ 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL,
+ 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
+ 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL};
/* Initial hash value H for SHA-512 */
static const uint64_t sha512_initial_hash_value[8] = {
- 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
- 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
- 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};
+ 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
+ 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};
/*** SHA-256: *********************************************************/
void SHA256_Init(SHA256Ctx *context)
@@ -197,7 +195,7 @@
j = 0;
do {
W256[j] = (uint32_t)data[3] | ((uint32_t)data[2] << 8) |
- ((uint32_t)data[1] << 16) | ((uint32_t)data[0] << 24);
+ ((uint32_t)data[1] << 16) | ((uint32_t)data[0] << 24);
data += 4;
/* Apply the SHA-256 compression function to update a..h */
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
@@ -223,7 +221,7 @@
/* Apply the SHA-256 compression function to update a..h */
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
- (W256[j & 0x0f] += s1 + W256[(j + 9) & 0x0f] + s0);
+ (W256[j & 0x0f] += s1 + W256[(j + 9) & 0x0f] + s0);
T2 = Sigma0_256(a) + Maj(a, b, c);
h = g;
g = f;
@@ -309,11 +307,11 @@
if (usedspace <= SHA256ShortBlockLength) {
/* Set-up for the last transform: */
memset(&context->buffer[usedspace], 0,
- SHA256ShortBlockLength - usedspace);
+ SHA256ShortBlockLength - usedspace);
} else {
if (usedspace < SHA256BlockLength) {
memset(&context->buffer[usedspace], 0,
- SHA256BlockLength - usedspace);
+ SHA256BlockLength - usedspace);
}
/* Do second-to-last transform: */
SHA256_Transform(context, (uint32_t *)context->buffer);
@@ -329,7 +327,8 @@
*context->buffer = 0x80;
}
/* Set the bit count: */
- *(uint64_t *)&context->buffer[SHA256ShortBlockLength] = context->bitcount;
+ *(uint64_t *)&context->buffer[SHA256ShortBlockLength] =
+ context->bitcount;
/* Final transform: */
SHA256_Transform(context, (uint32_t *)context->buffer);
@@ -376,10 +375,11 @@
j = 0;
do {
- W512[j] = (uint64_t)data[7] | ((uint64_t)data[6] << 8) |
- ((uint64_t)data[5] << 16) | ((uint64_t)data[4] << 24) |
- ((uint64_t)data[3] << 32) | ((uint64_t)data[2] << 40) |
- ((uint64_t)data[1] << 48) | ((uint64_t)data[0] << 56);
+ W512[j] =
+ (uint64_t)data[7] | ((uint64_t)data[6] << 8) |
+ ((uint64_t)data[5] << 16) | ((uint64_t)data[4] << 24) |
+ ((uint64_t)data[3] << 32) | ((uint64_t)data[2] << 40) |
+ ((uint64_t)data[1] << 48) | ((uint64_t)data[0] << 56);
data += 8;
/* Apply the SHA-512 compression function to update a..h */
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
@@ -405,7 +405,7 @@
/* Apply the SHA-512 compression function to update a..h */
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
- (W512[j & 0x0f] += s1 + W512[(j + 9) & 0x0f] + s0);
+ (W512[j & 0x0f] += s1 + W512[(j + 9) & 0x0f] + s0);
T2 = Sigma0_512(a) + Maj(a, b, c);
h = g;
g = f;
@@ -491,11 +491,11 @@
if (usedspace <= SHA512ShortBlockLength) {
/* Set-up for the last transform: */
memset(&context->buffer[usedspace], 0,
- SHA512ShortBlockLength - usedspace);
+ SHA512ShortBlockLength - usedspace);
} else {
if (usedspace < SHA512_block_length) {
memset(&context->buffer[usedspace], 0,
- SHA512_block_length - usedspace);
+ SHA512_block_length - usedspace);
}
/* Do second-to-last transform: */
SHA512_Transform(context, (uint64_t *)context->buffer);
@@ -512,9 +512,9 @@
}
/* Store the length of input data (in bits): */
*(uint64_t *)&context->buffer[SHA512ShortBlockLength] =
- context->bitcount[1];
+ context->bitcount[1];
*(uint64_t *)&context->buffer[SHA512ShortBlockLength + 8] =
- context->bitcount[0];
+ context->bitcount[0];
/* Final transform: */
SHA512_Transform(context, (uint64_t *)context->buffer);
diff --git a/kern/lib/slice.c b/kern/lib/slice.c
index fef606a..8535a59 100644
--- a/kern/lib/slice.c
+++ b/kern/lib/slice.c
@@ -56,7 +56,7 @@
s->capacity *= 2;
ps = kreallocarray(s->ptrs, s->capacity, sizeof(void *),
MEM_WAIT);
- assert(ps != NULL); /* XXX: if size*sizeof(void*) overflows. */
+ assert(ps != NULL); /* XXX: if size*sizeof(void*) overflows. */
s->ptrs = ps;
}
s->ptrs[s->len] = p;
diff --git a/kern/src/alarm.c b/kern/src/alarm.c
index 79aec94..6ee32e8 100644
--- a/kern/src/alarm.c
+++ b/kern/src/alarm.c
@@ -8,10 +8,10 @@
* after the time you specify. (for now, this might change).
*
* TODO:
- * - have a kernel sense of time, instead of just the TSC or whatever timer the
- * chain uses...
- * - coalesce or otherwise deal with alarms that are close to cut down on
- * interrupt overhead. */
+ * - have a kernel sense of time, instead of just the TSC or whatever timer the
+ * chain uses...
+ * - coalesce or otherwise deal with alarms that are close to cut down on
+ * interrupt overhead. */
#include <ros/common.h>
#include <sys/queue.h>
@@ -30,9 +30,10 @@
tchain->earliest_time = ALARM_POISON_TIME;
tchain->latest_time = ALARM_POISON_TIME;
} else {
- tchain->earliest_time = TAILQ_FIRST(&tchain->waiters)->wake_up_time;
+ tchain->earliest_time =
+ TAILQ_FIRST(&tchain->waiters)->wake_up_time;
tchain->latest_time =
- TAILQ_LAST(&tchain->waiters, awaiters_tailq)->wake_up_time;
+ TAILQ_LAST(&tchain->waiters, awaiters_tailq)->wake_up_time;
}
}
@@ -68,10 +69,11 @@
void set_awaiter_rel(struct alarm_waiter *waiter, uint64_t usleep)
{
uint64_t now, then;
+
now = read_tsc();
then = now + usec2tsc(usleep);
- /* This will go off if we wrap-around the TSC. It'll never happen for legit
- * values, but this might catch some bugs with large usleeps. */
+ /* This will go off if we wrap-around the TSC. It'll never happen for
+ * legit values, but this might catch some bugs with large usleeps. */
assert(now <= then);
set_awaiter_abs(waiter, then);
}
@@ -174,25 +176,26 @@
/* Need to turn on the timer interrupt later */
return TRUE;
}
- /* If not, either we're first, last, or in the middle. Reset the interrupt
- * and adjust the tchain's times accordingly. */
+ /* If not, either we're first, last, or in the middle. Reset the
+ * interrupt and adjust the tchain's times accordingly. */
if (waiter->wake_up_time < tchain->earliest_time) {
tchain->earliest_time = waiter->wake_up_time;
TAILQ_INSERT_HEAD(&tchain->waiters, waiter, next);
- /* Changed the first entry; we'll need to reset the interrupt later */
+ /* Changed the first entry; we'll need to reset the interrupt
+ * later */
return TRUE;
}
- /* If there is a tie for last, the newer one will really go last. We need
- * to handle equality here since the loop later won't catch it. */
+ /* If there is a tie for last, the newer one will really go last. We
+ * need to handle equality here since the loop later won't catch it. */
if (waiter->wake_up_time >= tchain->latest_time) {
tchain->latest_time = waiter->wake_up_time;
/* Proactively put it at the end if we know we're last */
TAILQ_INSERT_TAIL(&tchain->waiters, waiter, next);
return FALSE;
}
- /* Insert before the first one you are earlier than. This won't scale well
- * (TODO) if we have a lot of inserts. The proactive insert_tail up above
- * will help a bit. */
+ /* Insert before the first one you are earlier than. This won't scale
+ * well (TODO) if we have a lot of inserts. The proactive insert_tail
+ * up above will help a bit. */
TAILQ_FOREACH_SAFE(i, &tchain->waiters, next, temp) {
if (waiter->wake_up_time < i->wake_up_time) {
TAILQ_INSERT_BEFORE(i, waiter, next);
@@ -222,18 +225,20 @@
struct alarm_waiter *waiter)
{
struct alarm_waiter *temp;
- bool reset_int = FALSE; /* whether or not to reset the interrupt */
+ bool reset_int = FALSE; /* whether or not to reset the interrupt */
- /* Need to make sure earliest and latest are set, in case we're mucking with
- * the first and/or last element of the chain. */
+ /* Need to make sure earliest and latest are set, in case we're mucking
+ * with the first and/or last element of the chain. */
if (TAILQ_FIRST(&tchain->waiters) == waiter) {
temp = TAILQ_NEXT(waiter, next);
- tchain->earliest_time = (temp) ? temp->wake_up_time : ALARM_POISON_TIME;
- reset_int = TRUE; /* we'll need to reset the timer later */
+ tchain->earliest_time = (temp) ? temp->wake_up_time
+ : ALARM_POISON_TIME;
+ reset_int = TRUE; /* we'll need to reset the timer later */
}
if (TAILQ_LAST(&tchain->waiters, awaiters_tailq) == waiter) {
temp = TAILQ_PREV(waiter, awaiters_tailq, next);
- tchain->latest_time = (temp) ? temp->wake_up_time : ALARM_POISON_TIME;
+ tchain->latest_time = (temp) ? temp->wake_up_time
+ : ALARM_POISON_TIME;
}
TAILQ_REMOVE(&tchain->waiters, waiter, next);
waiter->on_tchain = FALSE;
@@ -321,21 +326,21 @@
struct timer_chain *pcpui_tchain = &pcpui->tchain;
if (pcpui_tchain != tchain) {
- /* cross-core call. we can simply send an alarm IRQ. the alarm handler
- * will reset its pcpu timer, based on its current lists. they take an
- * extra IRQ, but it gets the job done. */
+ /* cross-core call. we can simply send an alarm IRQ. the alarm
+ * handler will reset its pcpu timer, based on its current
+ * lists. they take an extra IRQ, but it gets the job done. */
rem_pcpui = (struct per_cpu_info*)((uintptr_t)tchain -
offsetof(struct per_cpu_info, tchain));
- /* TODO: using the LAPIC vector is a bit ghetto, since that's x86. But
- * RISCV ignores the vector field, and we don't have a global IRQ vector
- * namespace or anything. */
+ /* TODO: using the LAPIC vector is a bit ghetto, since that's
+ * x86. But RISCV ignores the vector field, and we don't have a
+ * global IRQ vector namespace or anything. */
send_ipi(rem_pcpui - &per_cpu_info[0], IdtLAPIC_TIMER);
return;
}
time = TAILQ_EMPTY(&tchain->waiters) ? 0 : tchain->earliest_time;
if (time) {
- /* Arm the alarm. For times in the past, we just need to make sure it
- * goes off. */
+ /* Arm the alarm. For times in the past, we just need to make
+ * sure it goes off. */
now = read_tsc();
if (time <= now)
rel_usec = 1;
diff --git a/kern/src/apipe.c b/kern/src/apipe.c
index c97333d..87106a5 100644
--- a/kern/src/apipe.c
+++ b/kern/src/apipe.c
@@ -87,13 +87,15 @@
int nr_copied = 0;
for (int i = 0; i < nr_elem; i++) {
- /* readers that call read_locked directly might have failed to check for
- * emptiness, so we'll double check early. */
+ /* readers that call read_locked directly might have failed to
+ * check for emptiness, so we'll double check early. */
if (__ring_empty(ap->ap_wr_off, ap->ap_rd_off))
break;
- /* power of 2 elements in the ring buffer, index is the lower n bits */
+ /* power of 2 elements in the ring buffer, index is the lower n
+ * bits */
rd_idx = ap->ap_rd_off & (ap->ap_ring_sz - 1);
- memcpy(buf, ap->ap_buf + rd_idx * ap->ap_elem_sz, ap->ap_elem_sz);
+ memcpy(buf, ap->ap_buf + rd_idx * ap->ap_elem_sz,
+ ap->ap_elem_sz);
ap->ap_rd_off++;
buf += ap->ap_elem_sz;
nr_copied++;
@@ -112,12 +114,12 @@
int nr_copied = 0;
spin_lock(&ap->ap_lock);
- /* Need to wait til the priority reader is gone, and the ring isn't empty.
- * If we do this as two steps, (either of priority check or empty check
- * first), there's a chance the second one will fail, and when we sleep and
- * wake up, the first condition could have changed. (An alternative would
- * be to block priority readers too, by promoting ourselves to a priority
- * reader). */
+ /* Need to wait til the priority reader is gone, and the ring isn't
+ * empty. If we do this as two steps, (either of priority check or
+ * empty check first), there's a chance the second one will fail, and
+ * when we sleep and wake up, the first condition could have changed.
+ * (An alternative would be to block priority readers too, by promoting
+ * ourselves to a priority reader). */
while (ap->ap_has_priority_reader ||
__ring_empty(ap->ap_wr_off, ap->ap_rd_off)) {
if (!ap->ap_nr_writers) {
@@ -129,9 +131,9 @@
}
/* This read call wakes up writers */
nr_copied = apipe_read_locked(ap, buf, nr_elem);
- /* If the writer didn't broadcast, we'd need to wake other readers (imagine
- * a long queue of blocked readers, and a queue filled by one massive
- * write). (same with the error case). */
+ /* If the writer didn't broadcast, we'd need to wake other readers
+ * (imagine a long queue of blocked readers, and a queue filled by one
+ * massive write). (same with the error case). */
spin_unlock(&ap->ap_lock);
return nr_copied;
}
@@ -152,9 +154,11 @@
cpu_relax();
}
for (int i = 0; i < nr_elem; i++) {
- /* power of 2 elements in the ring buffer, index is the lower n bits */
+ /* power of 2 elements in the ring buffer, index is the lower n
+ * bits */
wr_idx = ap->ap_wr_off & (ap->ap_ring_sz - 1);
- memcpy(ap->ap_buf + wr_idx * ap->ap_elem_sz, buf, ap->ap_elem_sz);
+ memcpy(ap->ap_buf + wr_idx * ap->ap_elem_sz, buf,
+ ap->ap_elem_sz);
ap->ap_wr_off++;
buf += ap->ap_elem_sz;
nr_copied++;
@@ -162,8 +166,8 @@
break;
}
/* We only need to wake readers, since the reader that woke us used a
- * broadcast. o/w, we'd need to wake the next writer. (same goes for the
- * error case). */
+ * broadcast. o/w, we'd need to wake the next writer. (same goes for
+ * the error case). */
__apipe_wake_readers(ap);
spin_unlock(&ap->ap_lock);
return nr_copied;
@@ -173,7 +177,8 @@
{
if (__ring_empty(ap->ap_wr_off, ap->ap_rd_off))
return 0;
- return ap->ap_buf + (ap->ap_rd_off & (ap->ap_ring_sz - 1)) * ap->ap_elem_sz;
+ return ap->ap_buf +
+ (ap->ap_rd_off & (ap->ap_ring_sz - 1)) * ap->ap_elem_sz;
}
/*
@@ -210,10 +215,11 @@
ret = f(ap, arg);
if (ret)
break;
- /* if nr_writers goes to zero, that's bad. return -1 because they're
- * going to have to clean up. We should have been able to call f once
- * though, to pull out any remaining elements. The main concern here is
- * sleeping on the cv when no one (no writers) will wake us. */
+ /* if nr_writers goes to zero, that's bad. return -1 because
+ * they're going to have to clean up. We should have been able
+ * to call f once though, to pull out any remaining elements.
+ * The main concern here is sleeping on the cv when no one (no
+ * writers) will wake us. */
if (!ap->ap_nr_writers) {
ret = -1;
goto out;
@@ -222,13 +228,13 @@
cpu_relax();
}
out:
- /* All out paths need to wake other readers. When we were woken up, there
- * was no broadcast sent to the other readers. Plus, there may be other
- * potential priority readers. */
+ /* All out paths need to wake other readers. When we were woken up,
+ * there was no broadcast sent to the other readers. Plus, there may be
+ * other potential priority readers. */
ap->ap_has_priority_reader = FALSE;
__apipe_wake_readers(ap);
- /* FYI, writers were woken up after an actual read. If we had an error (ret
- * == -1), there should be no writers. */
+ /* FYI, writers were woken up after an actual read. If we had an error
+ * (ret == -1), there should be no writers. */
spin_unlock(&ap->ap_lock);
return ret;
}
diff --git a/kern/src/arena.c b/kern/src/arena.c
index 26a5991..859cd40 100644
--- a/kern/src/arena.c
+++ b/kern/src/arena.c
@@ -101,9 +101,10 @@
* arena. */
static struct arena *find_my_base(struct arena *arena)
{
- /* TODO: could walk down sources until is_base is set. But barring that,
- * we'd still need a way to find a base arena for some other allocator that
- * just wants a page. arena may be NULL, so handle that. */
+ /* TODO: could walk down sources until is_base is set. But barring
+ * that, we'd still need a way to find a base arena for some other
+ * allocator that just wants a page. arena may be NULL, so handle that.
+ * */
return base_arena;
}
@@ -117,15 +118,18 @@
if (!nr_qcaches)
return;
- /* TODO: same as with hash tables, here and in slab.c, we ideally want the
- * nearest kpages arena, but bootstrappers need to use base_alloc. */
- arena->qcaches = base_alloc(arena, nr_qcaches * sizeof(struct kmem_cache),
- MEM_WAIT);
+ /* TODO: same as with hash tables, here and in slab.c, we ideally want
+ * the nearest kpages arena, but bootstrappers need to use base_alloc.
+ * */
+ arena->qcaches = base_alloc(arena,
+ nr_qcaches * sizeof(struct kmem_cache),
+ MEM_WAIT);
for (int i = 0; i < nr_qcaches; i++) {
qc_size = (i + 1) * quantum;
snprintf(kc_name, KMC_NAME_SZ, "%s_%d", arena->name, qc_size);
- __kmem_cache_create(&arena->qcaches[i], kc_name, qc_size, quantum,
- KMC_NOTOUCH | KMC_QCACHE, arena, NULL, NULL, NULL);
+ __kmem_cache_create(&arena->qcaches[i], kc_name, qc_size,
+ quantum, KMC_NOTOUCH | KMC_QCACHE, arena,
+ NULL, NULL, NULL);
}
}
@@ -193,7 +197,8 @@
arena_init(arena, name, quantum, afunc, ffunc, source, qcache_max);
if (base) {
if (!arena_add(arena, base, size, flags)) {
- warn("Failed to add base to arena %s, aborting!", arena->name);
+ warn("Failed to add base to arena %s, aborting!",
+ arena->name);
arena_destroy(arena);
return 0;
}
@@ -215,20 +220,22 @@
assert(BSD_LIST_EMPTY(&arena->alloc_hash[i]));
if (arena->alloc_hash != arena->static_hash)
kfree(arena->alloc_hash);
- /* We shouldn't have any spans left. We can tell we messed up if we had a
- * source and still have some free segments. Otherwise, just collect the
- * free tags on the unused btag list. */
+ /* We shouldn't have any spans left. We can tell we messed up if we had
+ * a source and still have some free segments. Otherwise, just collect
+ * the free tags on the unused btag list. */
for (int i = 0; i < ARENA_NR_FREE_LISTS; i++) {
if (arena->source)
assert(BSD_LIST_EMPTY(&arena->free_segs[i]));
- BSD_LIST_FOREACH_SAFE(bt_i, &arena->free_segs[i], misc_link, temp) {
+ BSD_LIST_FOREACH_SAFE(bt_i, &arena->free_segs[i], misc_link,
+ temp) {
BSD_LIST_REMOVE(bt_i, misc_link);
- BSD_LIST_INSERT_HEAD(&arena->unused_btags, bt_i, misc_link);
+ BSD_LIST_INSERT_HEAD(&arena->unused_btags, bt_i,
+ misc_link);
}
}
- /* To free our BTs, we need to give the page back to the base arena. The
- * BTs that are page aligned are the ones we want. We can just ignore the
- * others (unlink from the list). */
+ /* To free our BTs, we need to give the page back to the base arena.
+ * The BTs that are page aligned are the ones we want. We can just
+ * ignore the others (unlink from the list). */
BSD_LIST_FOREACH_SAFE(bt_i, &arena->unused_btags, misc_link, temp) {
if (PGOFF(bt_i->start))
BSD_LIST_REMOVE(bt_i, misc_link);
@@ -247,8 +254,9 @@
while (*new) {
node = container_of(*new, struct btag, all_link);
parent = *new;
- /* Span (BTAG_SPAN) nodes are ahead (less than) of regular segment nodes
- * (BTAG_FREE or BTAG_ALLOC) that have the same start. */
+ /* Span (BTAG_SPAN) nodes are ahead (less than) of regular
+ * segment nodes (BTAG_FREE or BTAG_ALLOC) that have the same
+ * start. */
if (bt->start < node->start)
new = &parent->rb_left;
else if (bt->start > node->start)
@@ -315,12 +323,13 @@
return;
new_tbl_nr_lists = hash_next_nr_lists(&arena->hh);
/* We want future checkers to not think we need an increase, to avoid
- * excessive hash resizers as well as base arena deadlocks (base_alloc must
- * not call into base_alloc infinitely) */
+ * excessive hash resizers as well as base arena deadlocks (base_alloc
+ * must not call into base_alloc infinitely) */
hash_set_load_limit(&arena->hh, SIZE_MAX);
spin_unlock_irqsave(&arena->lock);
new_tbl_sz = new_tbl_nr_lists * sizeof(struct btag_list);
- /* Regardless of the caller's style, we'll try and be quick with INSTANT. */
+ /* Regardless of the caller's style, we'll try and be quick with
+ * INSTANT. */
flags &= ~ARENA_ALLOC_STYLES;
flags |= ARENA_INSTANTFIT;
new_tbl = base_zalloc(arena, new_tbl_sz, flags);
@@ -347,8 +356,10 @@
for (int i = 0; i < old_tbl_nr_lists; i++) {
while ((bt_i = BSD_LIST_FIRST(&old_tbl[i]))) {
BSD_LIST_REMOVE(bt_i, misc_link);
- hash_idx = hash_long(bt_i->start, arena->hh.nr_hash_bits);
- BSD_LIST_INSERT_HEAD(&arena->alloc_hash[hash_idx], bt_i, misc_link);
+ hash_idx = hash_long(bt_i->start,
+ arena->hh.nr_hash_bits);
+ BSD_LIST_INSERT_HEAD(&arena->alloc_hash[hash_idx], bt_i,
+ misc_link);
}
}
hash_reset_load_limit(&arena->hh);
@@ -392,19 +403,20 @@
if (arena->is_base) {
bt = __get_from_freelists(arena, LOG2_UP(PGSIZE));
if (!bt) {
- /* TODO: block / reclaim if not MEM_ATOMIC. Remember, we hold the
- * lock! We might need to rework this or get a reserved page. */
+ /* TODO: block / reclaim if not MEM_ATOMIC. Remember,
+ * we hold the lock! We might need to rework this or
+ * get a reserved page. */
if (!(mem_flags & MEM_ATOMIC))
- panic("Base failed to alloc its own btag, OOM!");
+ panic("Base failed to alloc its own btag, OOM");
return 0;
}
- /* __account_alloc() will often need a new BT; specifically when we
- * only need part of the segment tracked by the BT. Since we don't have
- * any extra BTs, we'll use the first one on the page we just allocated.
- */
+ /* __account_alloc() will often need a new BT; specifically when
+ * we only need part of the segment tracked by the BT. Since we
+ * don't have any extra BTs, we'll use the first one on the page
+ * we just allocated. */
tags = (struct btag*)bt->start;
if (__account_alloc(arena, bt, PGSIZE, &tags[0])) {
- /* We used the tag[0]; we'll have to skip over it now. */
+ /* We used the tag[0]; we'll have to skip over it now.*/
tags++;
nr_bts--;
}
@@ -442,9 +454,9 @@
assert(mem_flags & MEM_ATOMIC);
return FALSE;
}
- /* Since the lock was held in __add_more_btags, no one should have been able
- * to drain them. If someone asked for more than a page worth of BTs,
- * there's a problem somewhere else. */
+ /* Since the lock was held in __add_more_btags, no one should have been
+ * able to drain them. If someone asked for more than a page worth of
+ * BTs, there's a problem somewhere else. */
assert(__has_enough_btags(arena, nr_needed));
return TRUE;
}
@@ -457,8 +469,8 @@
struct btag *ret;
ret = BSD_LIST_FIRST(&arena->unused_btags);
- /* All code paths should have made sure that there were enough BTs before
- * diving in. */
+ /* All code paths should have made sure that there were enough BTs
+ * before diving in. */
assert(ret);
BSD_LIST_REMOVE(ret, misc_link);
return ret;
@@ -593,7 +605,8 @@
ret = __alloc_nextfit(arena, size);
else
ret = __alloc_instantfit(arena, size);
- /* Careful, this will unlock and relock. It's OK right before an unlock. */
+ /* Careful, this will unlock and relock. It's OK right before an
+ * unlock. */
__try_hash_resize(arena, flags, &to_free_addr, &to_free_sz);
spin_unlock_irqsave(&arena->lock);
if (to_free_addr)
@@ -607,12 +620,12 @@
size_t size)
{
if (!ALIGNED(base, arena->quantum))
- panic("Unaligned base %p for arena %s, quantum %p, source %s", base,
- arena->name, arena->quantum,
+ panic("Unaligned base %p for arena %s, quantum %p, source %s",
+ base, arena->name, arena->quantum,
arena->source ? arena->source->name : "none");
if (!ALIGNED(size, arena->quantum))
- panic("Unaligned size %p for arena %s, quantum %p, source %s", size,
- arena->name, arena->quantum,
+ panic("Unaligned size %p for arena %s, quantum %p, source %s",
+ size, arena->name, arena->quantum,
arena->source ? arena->source->name : "none");
}
@@ -639,7 +652,8 @@
span_bt->start = (uintptr_t)base;
span_bt->size = size;
span_bt->status = BTAG_SPAN;
- /* Note the btag span is not on any list, but it is in all_segs */
+ /* Note the btag span is not on any list, but it is in all_segs
+ */
__insert_btag(&arena->all_segs, span_bt);
}
bt->start = (uintptr_t)base;
@@ -654,8 +668,9 @@
/* Adds segment [@base, @base + @size) to @arena. */
void *arena_add(struct arena *arena, void *base, size_t size, int flags)
{
- /* This wasn't clear from the paper, but mixing source spans and manually
- * added spans seems like a pain when coalescing BTs and freeing. */
+ /* This wasn't clear from the paper, but mixing source spans and
+ * manually added spans seems like a pain when coalescing BTs and
+ * freeing. */
if (arena->source)
panic("Arenas with sources must not manually add resources.");
return __arena_add(arena, base, size, flags);
@@ -675,7 +690,8 @@
if (!span)
return FALSE;
if (!__arena_add(arena, span, import_size, flags)) {
- /* We could fail if MEM_ATOMIC and we couldn't get a BT */
+ /* We could fail if MEM_ATOMIC and we couldn't get a BT
+ */
warn("Excessively rare failure, tell brho");
arena->ffunc(arena->source, span, import_size);
return FALSE;
@@ -692,9 +708,9 @@
/* Helper. For a given size, return the applicable qcache. */
static struct kmem_cache *size_to_qcache(struct arena *arena, size_t size)
{
- /* If we ever get grumpy about the costs of dividing (both here and in the
- * ROUND ops, we could either insist that quantum is a power of two, or
- * track whether or not it is and use other shifting ops. */
+ /* If we ever get grumpy about the costs of dividing (both here and in
+ * the ROUND ops, we could either insist that quantum is a power of two,
+ * or track whether or not it is and use other shifting ops. */
return &arena->qcaches[(size / arena->quantum) - 1];
}
@@ -706,10 +722,11 @@
if (!size)
panic("Arena %s, request for zero", arena->name);
if (size <= arena->qcache_max) {
- /* NEXTFIT is an error, since free won't know to skip the qcache and
- * then we'd be handing an item to the qcache that it didn't alloc. */
+ /* NEXTFIT is an error, since free won't know to skip the qcache
+ * and then we'd be handing an item to the qcache that it didn't
+ * alloc. */
if (flags & ARENA_NEXTFIT)
- panic("Arena %s, NEXTFIT, but has qcaches. Use xalloc.",
+ panic("Arena %s, NEXTFIT, but has qcaches. Use xalloc.",
arena->name);
return kmem_cache_alloc(size_to_qcache(arena, size), flags);
}
@@ -717,20 +734,22 @@
ret = alloc_from_arena(arena, size, flags);
if (ret)
return ret;
- /* This is a little nasty. We asked our source for enough, but it may
- * be a bestfit sized chunk, not an instant fit. Since we already
- * failed once, we can just downgrade to BESTFIT, which will likely find
- * our recently-allocated span. Even worse, the source might only give
- * us segments that are BESTFIT, and if we only look at the INSTANTFIT,
- * we'll keep looping. The invariant here is that if we
- * get_more_resources, then our allocation can succeed if no one else
- * grabs that memory first.
+ /* This is a little nasty. We asked our source for enough, but
+ * it may be a bestfit sized chunk, not an instant fit. Since
+ * we already failed once, we can just downgrade to BESTFIT,
+ * which will likely find our recently-allocated span. Even
+ * worse, the source might only give us segments that are
+ * BESTFIT, and if we only look at the INSTANTFIT, we'll keep
+ * looping. The invariant here is that if we
+ * get_more_resources, then our allocation can succeed if no one
+ * else grabs that memory first.
*
- * We actually have two options here. Either we downgrade to BESTFIT or
- * we round up our request to our source to the nearest power of two.
- * Doing so brings some of the fragmentation into our arena, but an
- * instant fit is likely to succeed. Considering how the first item on
- * the BESTFIT list is likely ours, downgrading makes sense. */
+ * We actually have two options here. Either we downgrade to
+ * BESTFIT or we round up our request to our source to the
+ * nearest power of two. Doing so brings some of the
+ * fragmentation into our arena, but an instant fit is likely to
+ * succeed. Considering how the first item on the BESTFIT list
+ * is likely ours, downgrading makes sense. */
flags &= ~ARENA_ALLOC_STYLES;
flags |= ARENA_BESTFIT;
if (!get_more_resources(arena, size, flags))
@@ -765,13 +784,13 @@
return 0;
if (nocross == 0)
return try;
- /* Got to deal with nocross boundaries. If we round up from our potential
- * start and that is beyond our potential finish, we're OK. */
+ /* Got to deal with nocross boundaries. If we round up from our
+ * potential start and that is beyond our potential finish, we're OK. */
if (ROUNDUP(try, nocross) >= try + size)
return try;
- /* The segment still might have a chance. Perhaps we started right before a
- * nocross. Let's try again, being careful of overflow. The ROUNDUP
- * shouldn't trigger a wraparound. */
+ /* The segment still might have a chance. Perhaps we started right
+ * before a nocross. Let's try again, being careful of overflow. The
+ * ROUNDUP shouldn't trigger a wraparound. */
try = ROUNDUP(bt_start, nocross);
try_size = bt_size - (try - bt_start);
/* Underflow of bt_size - large_number. */
@@ -791,10 +810,11 @@
struct btag *front = __get_btag(arena);
/* We're changing bt's start, which is its key for its position in the
- * all_segs tree. However, we don't need to remove and reinsert it, since
- * although we increased its start, we know that no BT should be between its
- * old start and its new start. That's actually where the front BT will get
- * inserted (so long as we insert after changing bt's start). */
+ * all_segs tree. However, we don't need to remove and reinsert it,
+ * since although we increased its start, we know that no BT should be
+ * between its old start and its new start. That's actually where the
+ * front BT will get inserted (so long as we insert after changing bt's
+ * start). */
front->status = BTAG_FREE;
front->start = bt->start;
front->size = at - bt->start;
@@ -802,9 +822,9 @@
bt->size -= front->size;
__track_free_seg(arena, front);
__insert_btag(&arena->all_segs, front);
- /* At this point, bt's old space in all_segs is broken into:
- * front: [old_start, try), bt: [try, old_end). front is on the free list.
- * bt is not. */
+ /* At this point, bt's old space in all_segs is broken into: front:
+ * [old_start, try), bt: [try, old_end). front is on the free list. bt
+ * is not. */
}
/* Helper. We want the first bt >= mindaddr, with prev < minaddr. */
@@ -841,8 +861,8 @@
else
node = node->rb_right;
}
- /* Now we're probably at the first start point (or there's no node). Just
- * scan from here. */
+ /* Now we're probably at the first start point (or there's no node).
+ * Just scan from here. */
for (/* node set */; node; node = rb_next(node)) {
bt = container_of(node, struct btag, all_link);
try = __find_sufficient(bt->start, bt->size, size, align, phase,
@@ -876,8 +896,8 @@
list_idx += try_instant_fit ? 1 : 0;
for (int i = list_idx; i < ARENA_NR_FREE_LISTS; i++) {
BSD_LIST_FOREACH(bt_i, &arena->free_segs[i], misc_link) {
- try = __find_sufficient(bt_i->start, bt_i->size, size, align,
- phase, nocross);
+ try = __find_sufficient(bt_i->start, bt_i->size, size,
+ align, phase, nocross);
if (try) {
BSD_LIST_REMOVE(bt_i, misc_link);
break;
@@ -900,8 +920,9 @@
void *ret;
/* NEXTFIT is a lot like a minaddr. We can start from the old addr + 1,
- * since the implementation of that helper starts a search from minaddr. If
- * it fails, we can try again from 1 (quantum, really), skipping 0. */
+ * since the implementation of that helper starts a search from minaddr.
+ * If it fails, we can try again from 1 (quantum, really), skipping 0.
+ * */
ret = __xalloc_min_max(arena, size, align, phase, nocross,
arena->last_nextfit_alloc + arena->quantum, 0);
if (!ret) {
@@ -933,16 +954,18 @@
(uintptr_t)minaddr, (uintptr_t)maxaddr);
} else {
if (flags & ARENA_BESTFIT) {
- ret = __xalloc_from_freelists(arena, size, align, phase, nocross,
- FALSE);
+ ret = __xalloc_from_freelists(arena, size, align, phase,
+ nocross, FALSE);
} else if (flags & ARENA_NEXTFIT) {
- ret = __xalloc_nextfit(arena, size, align, phase, nocross);
+ ret = __xalloc_nextfit(arena, size, align, phase,
+ nocross);
} else {
- ret = __xalloc_from_freelists(arena, size, align, phase, nocross,
- TRUE);
+ ret = __xalloc_from_freelists(arena, size, align, phase,
+ nocross, TRUE);
}
}
- /* Careful, this will unlock and relock. It's OK right before an unlock. */
+ /* Careful, this will unlock and relock. It's OK right before an
+ * unlock. */
__try_hash_resize(arena, flags, &to_free_addr, &to_free_sz);
spin_unlock_irqsave(&arena->lock);
if (to_free_addr)
@@ -960,9 +983,11 @@
if (!size)
panic("Arena %s, request for zero", arena->name);
if (!IS_PWR2(align))
- panic("Arena %s, non-power of two align %p", arena->name, align);
+ panic("Arena %s, non-power of two align %p", arena->name,
+ align);
if (nocross && !IS_PWR2(nocross))
- panic("Arena %s, non-power of nocross %p", arena->name, nocross);
+ panic("Arena %s, non-power of nocross %p", arena->name,
+ nocross);
if (!ALIGNED(align, arena->quantum))
panic("Arena %s, non-aligned align %p", arena->name, align);
if (!ALIGNED(nocross, arena->quantum))
@@ -970,61 +995,62 @@
if (!ALIGNED(phase, arena->quantum))
panic("Arena %s, non-aligned phase %p", arena->name, phase);
if (size + align < size)
- panic("Arena %s, size %p + align %p overflow%p", arena->name, size,
- align);
+ panic("Arena %s, size %p + align %p overflow%p", arena->name,
+ size, align);
if (size + phase < size)
- panic("Arena %s, size %p + phase %p overflow%p", arena->name, size,
- phase);
+ panic("Arena %s, size %p + phase %p overflow%p", arena->name,
+ size, phase);
if (align + phase < align)
- panic("Arena %s, align %p + phase %p overflow%p", arena->name, align,
- phase);
- /* Ok, it's a pain to import resources from a source such that we'll be able
- * to guarantee we make progress without stranding resources if we have
- * nocross or min/maxaddr. For min/maxaddr, when we ask the source, we
- * aren't easily able to xalloc from their (it may depend on the afunc).
- * For nocross, we can't easily ask the source for the right span that
- * satisfies the request (again, no real xalloc). Some constraints might
- * not even be possible.
+ panic("Arena %s, align %p + phase %p overflow%p", arena->name,
+ align, phase);
+ /* Ok, it's a pain to import resources from a source such that we'll be
+ * able to guarantee we make progress without stranding resources if we
+ * have nocross or min/maxaddr. For min/maxaddr, when we ask the
+ * source, we aren't easily able to xalloc from their (it may depend on
+ * the afunc). For nocross, we can't easily ask the source for the
+ * right span that satisfies the request (again, no real xalloc). Some
+ * constraints might not even be possible.
*
- * If we get a span from the source and never use it, then we run a risk of
- * fragmenting and stranding a bunch of spans in our current arena. Imagine
- * the loop where we keep asking for spans (e.g. 8 pgs) and getting
- * something that doesn't work. Those 8 pgs are fragmented, and we won't
- * give them back to the source until we allocate and then free them
- * (barring some sort of reclaim callback).
+ * If we get a span from the source and never use it, then we run a risk
+ * of fragmenting and stranding a bunch of spans in our current arena.
+ * Imagine the loop where we keep asking for spans (e.g. 8 pgs) and
+ * getting something that doesn't work. Those 8 pgs are fragmented, and
+ * we won't give them back to the source until we allocate and then free
+ * them (barring some sort of reclaim callback).
*
* Besides, I don't know if we even need/want nocross/min/maxaddr. */
if (arena->source && (nocross || minaddr || maxaddr))
panic("Arena %s, has source, can't xalloc with nocross %p, minaddr %p, or maxaddr %p",
arena->name, nocross, minaddr, maxaddr);
while (1) {
- ret = xalloc_from_arena(arena, size, align, phase, nocross, minaddr,
- maxaddr, flags);
+ ret = xalloc_from_arena(arena, size, align, phase, nocross,
+ minaddr, maxaddr, flags);
if (ret)
return ret;
- /* We checked earlier than no two of these overflow, so I think we don't
- * need to worry about multiple overflows. */
+ /* We checked earlier than no two of these overflow, so I think
+ * we don't need to worry about multiple overflows. */
req_size = size + align + phase;
- /* Note that this check isn't the same as the one we make when finding a
- * sufficient segment. Here we check overflow on the requested size.
- * Later, we check aligned bt_start + phase. The concern is that this
- * check succeeds, but the other fails. (Say size = PGSIZE, phase =
+ /* Note that this check isn't the same as the one we make when
+ * finding a sufficient segment. Here we check overflow on the
+ * requested size. Later, we check aligned bt_start + phase.
+ * The concern is that this check succeeds, but the other fails.
+ * (Say size = PGSIZE, phase =
* -PGSIZE -1. req_size is very large.
*
- * In this case, we're still fine - if our source is able to satisfy the
- * request, our bt_start and bt_size will be able to express that size
- * without wrapping. */
+ * In this case, we're still fine - if our source is able to
+ * satisfy the request, our bt_start and bt_size will be able to
+ * express that size without wrapping. */
if (req_size < size)
- panic("Arena %s, size %p + align %p + phase %p overflow",
+ panic("Arena %s, size %p + align %p + phase %p overflw",
arena->name, size, align, phase);
if (!get_more_resources(arena, req_size, flags))
return NULL;
- /* Our source may have given us a segment that is on the BESTFIT list,
- * same as with arena_alloc. */
+ /* Our source may have given us a segment that is on the BESTFIT
+ * list, same as with arena_alloc. */
flags &= ~ARENA_ALLOC_STYLES;
flags |= ARENA_BESTFIT;
- /* TODO: could put a check in here to make sure we don't loop forever,
- * in case we trip some other bug. */
+ /* TODO: could put a check in here to make sure we don't loop
+ * forever, in case we trip some other bug. */
}
}
@@ -1033,7 +1059,7 @@
static bool __merge_right_to_left(struct arena *arena, struct btag *left,
struct btag *right)
{
- /* These checks will also make sure we never merge SPAN boundary tags. */
+ /* These checks will also make sure we never merge SPAN boundary tags.*/
if (left->status != BTAG_FREE)
return FALSE;
if (right->status != BTAG_FREE)
@@ -1100,10 +1126,11 @@
spin_lock_irqsave(&arena->lock);
bt = __untrack_alloc_seg(arena, (uintptr_t)addr);
if (!bt)
- panic("Free of unallocated addr %p from arena %s", addr, arena->name);
+ panic("Free of unallocated addr %p from arena %s", addr,
+ arena->name);
if (bt->size != size)
- panic("Free of %p with wrong size %p (%p) from arena %s", addr, size,
- bt->size, arena->name);
+ panic("Free of %p with wrong size %p (%p) from arena %s", addr,
+ size, bt->size, arena->name);
arena->amt_alloc_segs -= size;
__track_free_seg(arena, bt);
__coalesce_free_seg(arena, bt, &to_free_addr, &to_free_sz);
diff --git a/kern/src/arsc.c b/kern/src/arsc.c
index c25db79..9124460 100644
--- a/kern/src/arsc.c
+++ b/kern/src/arsc.c
@@ -30,9 +30,10 @@
syscall_sring_t* sys_init_arsc(struct proc *p)
{
- kref_get(&p->p_kref, 1); /* we're storing an external ref here */
+ kref_get(&p->p_kref, 1); /* we're storing an external ref here */
syscall_sring_t* sring;
void * va;
+
// TODO: need to pin this page in the future when swapping happens
va = do_mmap(p,MMAP_LOWEST_VA, SYSCALLRINGSIZE, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_POPULATE | MAP_PRIVATE, NULL, 0);
@@ -58,20 +59,23 @@
void arsc_server(uint32_t srcid, long a0, long a1, long a2)
{
struct proc *p = NULL;
+
TAILQ_INIT(&arsc_proc_list);
while (1) {
while (TAILQ_EMPTY(&arsc_proc_list))
cpu_relax();
TAILQ_FOREACH(p, &arsc_proc_list, proc_arsc_link) {
- /* Probably want to try to process a dying process's syscalls. If
- * not, just move it to an else case */
+ /* Probably want to try to process a dying process's
+ * syscalls. If not, just move it to an else case */
process_generic_syscalls (p, MAX_ASRC_BATCH);
if (proc_is_dying(p)) {
- TAILQ_REMOVE(&arsc_proc_list, p, proc_arsc_link);
+ TAILQ_REMOVE(&arsc_proc_list, p,
+ proc_arsc_link);
proc_decref(p);
- /* Need to break out, so the TAILQ_FOREACH doesn't flip out.
- * It's not fair, but we're not dealing with that yet anyway */
+ /* Need to break out, so the TAILQ_FOREACH
+ * doesn't flip out. It's not fair, but we're
+ * not dealing with that yet anyway */
break;
}
}
@@ -84,6 +88,7 @@
syscall_back_ring_t* sysbr = &p->syscallbackring;
struct per_cpu_info* pcpui = &per_cpu_info[core_id()];
uintptr_t old_proc;
+
// looking at a process not initialized to perform arsc.
if (sysbr == NULL)
return count;
@@ -95,10 +100,10 @@
old_proc = switch_to(p);
// max is the most we'll process. max = 0 means do as many as possible
// TODO: check for initialization of the ring.
- while (RING_HAS_UNCONSUMED_REQUESTS(sysbr) && ((!max)||(count < max)) ) {
+ while (RING_HAS_UNCONSUMED_REQUESTS(sysbr) && ((!max)||(count < max))) {
// ASSUME: one queue per process
count++;
- //printk("DEBUG PRE: sring->req_prod: %d, sring->rsp_prod: %d\n",
+ //printk("DEBUG PRE sring->req_prod: %d, sring->rsp_prod: %d\n",
// sysbr->sring->req_prod, sysbr->sring->rsp_prod);
// might want to think about 0-ing this out, if we aren't
// going to explicitly fill in all fields
@@ -107,14 +112,15 @@
syscall_req_t* req = RING_GET_REQUEST(sysbr, ++sysbr->req_cons);
pcpui->cur_kthread->sysc = req->sc;
- run_local_syscall(req->sc); // TODO: blocking call will block arcs as well.
+ // TODO: blocking call will block arcs as well.
+ run_local_syscall(req->sc);
// need to keep the slot in the ring buffer if it is blocked
(sysbr->rsp_prod_pvt)++;
req->status = RES_ready;
RING_PUSH_RESPONSES(sysbr);
- //printk("DEBUG POST: sring->req_prod: %d, sring->rsp_prod: %d\n",
+ //printk("DEBUG PST sring->req_prod: %d, sring->rsp_prod: %d\n",
// sysbr->sring->req_prod, sysbr->sring->rsp_prod);
}
/* switch back to whatever context we were in before */
diff --git a/kern/src/atomic.c b/kern/src/atomic.c
index 70d2805..194d2ef 100644
--- a/kern/src/atomic.c
+++ b/kern/src/atomic.c
@@ -54,9 +54,10 @@
{
uint32_t coreid = core_id_early();
struct per_cpu_info *pcpui = &per_cpu_info[coreid];
- /* Short circuit our lock checking, so we can print or do other things to
- * announce the failure that require locks. Also avoids anything else
- * requiring pcpui initialization. */
+
+ /* Short circuit our lock checking, so we can print or do other things
+ * to announce the failure that require locks. Also avoids anything
+ * else requiring pcpui initialization. */
if (pcpui->__lock_checking_enabled != 1)
goto lock;
if (lock->irq_okay) {
@@ -70,7 +71,8 @@
if (!can_spinwait_noirq(pcpui)) {
pcpui->__lock_checking_enabled--;
print_kctx_depths("NOIRQ");
- panic("Lock %p tried to spin when it shouldn't\n", lock);
+ panic("Lock %p tried to spin when it shouldn't\n",
+ lock);
pcpui->__lock_checking_enabled++;
}
}
@@ -177,51 +179,57 @@
atomic_set(&tracker->need_to_run, TRUE);
/* will need to repeatedly do it if someone keeps posting work */
do {
- /* want an wrmb() btw posting work/need_to_run and in_progress. the
- * swap provides the HW mb. just need a cmb, which we do in the loop to
- * cover the iterations (even though i can't imagine the compiler
- * reordering the check it needed to do for the branch).. */
+ /* want an wrmb() btw posting work/need_to_run and in_progress.
+ * the swap provides the HW mb. just need a cmb, which we do in
+ * the loop to cover the iterations (even though i can't imagine
+ * the compiler reordering the check it needed to do for the
+ * branch).. */
cmb();
- /* poke / make sure someone does it. if we get a TRUE (1) back, someone
- * is already running and will deal with the posted work. (probably on
- * their next loop). if we got a 0 back, we won the race and have the
- * 'lock'. */
+ /* poke / make sure someone does it. if we get a TRUE (1) back,
+ * someone is already running and will deal with the posted
+ * work. (probably on their next loop). if we got a 0 back, we
+ * won the race and have the 'lock'. */
if (atomic_swap(&tracker->run_in_progress, TRUE))
return;
- /* if we're here, then we're the one who needs to run the func. */
- /* clear the 'need to run', since we're running it now. new users will
- * set it again. this write needs to be wmb()'d after in_progress. the
- * swap provided the HW mb(). */
+ /* if we're here, then we're the one who needs to run the func.
+ * */
+ /* clear the 'need to run', since we're running it now. new
+ * users will set it again. this write needs to be wmb()'d
+ * after in_progress. the swap provided the HW mb(). */
cmb();
- atomic_set(&tracker->need_to_run, FALSE); /* no internal HW mb */
- /* run the actual function. the poke sync makes sure only one caller is
- * in that func at a time. */
+ /* no internal HW mb */
+ atomic_set(&tracker->need_to_run, FALSE);
+ /* run the actual function. the poke sync makes sure only one
+ * caller is in that func at a time. */
assert(tracker->func);
tracker->func(arg);
- wmb(); /* ensure the in_prog write comes after the run_again. */
- atomic_set(&tracker->run_in_progress, FALSE); /* no internal HW mb */
+ /* ensure the in_prog write comes after the run_again. */
+ wmb();
+ /* no internal HW mb */
+ atomic_set(&tracker->run_in_progress, FALSE);
/* in_prog write must come before run_again read */
wrmb();
- } while (atomic_read(&tracker->need_to_run)); /* while there's more work*/
+ } while (atomic_read(&tracker->need_to_run));
}
// Must be called in a pair with waiton_checklist
int commit_checklist_wait(checklist_t* list, checklist_mask_t* mask)
{
assert(list->mask.size == mask->size);
- // abort if the list is locked. this will protect us from trying to commit
- // and thus spin on a checklist that we are already waiting on. it is
- // still possible to not get the lock, but the holder is on another core.
- // Or, bail out if we can see the list is already in use. This check is
- // just an optimization before we try to use the list for real.
+ // abort if the list is locked. this will protect us from trying to
+ // commit and thus spin on a checklist that we are already waiting on.
+ // it is still possible to not get the lock, but the holder is on
+ // another core. Or, bail out if we can see the list is already in use.
+ // This check is just an optimization before we try to use the list for
+ // real.
if ((checklist_is_locked(list)) || !checklist_is_clear(list))
return -EBUSY;
// possession of this lock means you can wait on it and set it
spin_lock_irqsave(&list->lock);
// wait til the list is available. could have some adaptive thing here
- // where it fails after X tries (like 500), gives up the lock, and returns
- // an error code
+ // where it fails after X tries (like 500), gives up the lock, and
+ // returns an error code
while (!checklist_is_clear(list))
cpu_relax();
@@ -240,7 +248,8 @@
return e;
}
// The deal with the lock:
-// what if two different actors are waiting on the list, but for different reasons?
+// what if two different actors are waiting on the list, but for different
+// reasons?
// part of the problem is we are doing both set and check via the same path
//
// aside: we made this a lot more difficult than the usual barriers or even
@@ -250,16 +259,16 @@
// how about this: if we want to wait on this later, we just don't release the
// lock. if we release it, then we don't care who comes in and grabs and starts
// checking the list.
-// - regardless, there are going to be issues with people looking for a free
-// item. even if they grab the lock, they may end up waiting a while and
-// wantint to bail (like test for a while, give up, move on, etc).
-// - still limited in that only the setter can check, and only one person
-// can spinwait / check for completion. if someone else tries to wait (wanting
-// completion), they may miss it if someone else comes in and grabs the lock
-// to use it for a new checklist
-// - if we had the ability to sleep and get woken up, we could have a
-// queue. actually, we could do a queue anyway, but they all spin
-// and it's the bosses responsibility to *wake* them
+// - regardless, there are going to be issues with people looking for a free
+// item. even if they grab the lock, they may end up waiting a while and
+// wantint to bail (like test for a while, give up, move on, etc).
+// - still limited in that only the setter can check, and only one person
+// can spinwait / check for completion. if someone else tries to wait (wanting
+// completion), they may miss it if someone else comes in and grabs the lock
+// to use it for a new checklist
+// - if we had the ability to sleep and get woken up, we could have a
+// queue. actually, we could do a queue anyway, but they all spin
+// and it's the bosses responsibility to *wake* them
// Must be called after commit_checklist
// Assumed we held the lock if we ever call this
diff --git a/kern/src/ceq.c b/kern/src/ceq.c
index bc511bf..c8e3422 100644
--- a/kern/src/ceq.c
+++ b/kern/src/ceq.c
@@ -47,8 +47,8 @@
return;
}
ceq_update_max_event(ceq, msg->ev_type);
- /* ACCESS_ONCE, prevent the compiler from rereading ceq->events later, and
- * possibly getting a new, illegal version after our check */
+ /* ACCESS_ONCE, prevent the compiler from rereading ceq->events later,
+ * and possibly getting a new, illegal version after our check */
ceq_ev = &(ACCESS_ONCE(ceq->events))[msg->ev_type];
if (!is_user_rwaddr(ceq_ev, sizeof(struct ceq_event))) {
error_addr(ceq, p, ceq);
@@ -56,53 +56,54 @@
}
/* ideally, we'd like the blob to be posted after the coal, so that the
* 'reason' for the blob is present when the blob is. but we can't
- * guarantee that. after we write the coal, the cons could consume that.
- * then the next time it looks at us, it could just see the blob - so
- * there's no good way to keep them together. the user will just have to
- * deal with it. in that case, we might as well do it first, to utilize the
- * atomic ops's memory barrier. */
+ * guarantee that. after we write the coal, the cons could consume
+ * that. then the next time it looks at us, it could just see the blob
+ * - so there's no good way to keep them together. the user will just
+ * have to deal with it. in that case, we might as well do it first,
+ * to utilize the atomic ops's memory barrier. */
ceq_ev->blob_data = (uint64_t)msg->ev_arg3;
switch (ceq->operation) {
- case (CEQ_OR):
- atomic_or(&ceq_ev->coalesce, msg->ev_arg2);
- break;
- case (CEQ_ADD):
- atomic_add(&ceq_ev->coalesce, msg->ev_arg2);
- break;
- default:
- printk("[kernel] CEQ %p invalid op %d\n", ceq, ceq->operation);
- return;
+ case (CEQ_OR):
+ atomic_or(&ceq_ev->coalesce, msg->ev_arg2);
+ break;
+ case (CEQ_ADD):
+ atomic_add(&ceq_ev->coalesce, msg->ev_arg2);
+ break;
+ default:
+ printk("[kernel] CEQ %p invalid op %d\n", ceq, ceq->operation);
+ return;
}
/* write before checking if we need to post (covered by the atomic) */
if (ceq_ev->idx_posted) {
- /* our entry was updated and posted was still set: we know the consumer
- * will still check it, so we can safely leave. If we ever have exit
- * codes or something from send_*_msg, then we can tell the kernel to
- * not bother with INDIRS/IPIs/etc. This is unnecessary now since
- * INDIRs are throttled */
+ /* our entry was updated and posted was still set: we know the
+ * consumer will still check it, so we can safely leave. If we
+ * ever have exit codes or something from send_*_msg, then we
+ * can tell the kernel to not bother with INDIRS/IPIs/etc. This
+ * is unnecessary now since INDIRs are throttled */
return;
}
- /* at this point, we need to make sure the cons looks at our entry. it may
- * have already done so while we were mucking around, but 'poking' them to
- * look again can't hurt */
+ /* at this point, we need to make sure the cons looks at our entry. it
+ * may have already done so while we were mucking around, but 'poking'
+ * them to look again can't hurt */
ceq_ev->idx_posted = TRUE;
/* idx_posted write happens before the writes posting it. the following
* atomic provides the cpu mb() */
cmb();
- /* I considered checking the buffer for full-ness or the ceq overflow here.
- * Those would be reads, which would require a wrmb() right above for every
- * ring post, all for something we check for later anyways and for something
- * that should be rare. In return, when we are overflowed, which should be
- * rare if the user sizes their ring buffer appropriately, we go through a
- * little more hassle below. */
- /* I tried doing this with fetch_and_add to avoid the while loop and picking
- * a number of times to try. The trick is that you need to back out, and
- * could have multiple producers working on the same slot. Although the
- * overflow makes it okay for the producers idxes to be clobbered, it's not
- * okay to have two producers on the same slot, since there'd only be one
- * consumer. Theoretically, you could have a producer delayed a long time
- * that just clobbers an index at some point in the future, or leaves an
- * index in the non-init state (-1). It's a mess. */
+ /* I considered checking the buffer for full-ness or the ceq overflow
+ * here. Those would be reads, which would require a wrmb() right above
+ * for every ring post, all for something we check for later anyways and
+ * for something that should be rare. In return, when we are
+ * overflowed, which should be rare if the user sizes their ring buffer
+ * appropriately, we go through a little more hassle below. */
+ /* I tried doing this with fetch_and_add to avoid the while loop and
+ * picking a number of times to try. The trick is that you need to back
+ * out, and could have multiple producers working on the same slot.
+ * Although the overflow makes it okay for the producers idxes to be
+ * clobbered, it's not okay to have two producers on the same slot,
+ * since there'd only be one consumer. Theoretically, you could have a
+ * producer delayed a long time that just clobbers an index at some
+ * point in the future, or leaves an index in the non-init state (-1).
+ * It's a mess. */
do {
cmb(); /* reread the indices */
my_slot = atomic_read(&ceq->prod_idx);
@@ -119,9 +120,9 @@
/* ring_slot is a user pointer, calculated by ring, my_slot, and sz */
ring_slot = &(ACCESS_ONCE(ceq->ring))[my_slot & (ceq->ring_sz - 1)];
if (!is_user_rwaddr(ring_slot, sizeof(int32_t))) {
- /* This is a serious user error. We're just bailing out, and any
- * consumers might be spinning waiting on us to produce. Probably not
- * though, since the ring slot is bad memory. */
+ /* This is a serious user error. We're just bailing out, and
+ * any consumers might be spinning waiting on us to produce.
+ * Probably not though, since the ring slot is bad memory. */
error_addr(ceq, p, ring_slot);
return;
}
@@ -174,8 +175,8 @@
atomic_read(&ceq->cons_pub_idx),
atomic_read(&ceq->cons_pvt_idx));
for (int i = 0; i < atomic_read(&ceq->max_event_ever) + 1; i++)
- printk("\tEvent %3d, coal %p, blob %p, idx_posted %d, user %p\n", i,
- atomic_read(&ceq->events[i].coalesce),
+ printk("\tEvent%3d, coal %p, blob %p, idx_posted %d, user %p\n",
+ i, atomic_read(&ceq->events[i].coalesce),
ceq->events[i].blob_data,
ceq->events[i].idx_posted,
ceq->events[i].user_data);
diff --git a/kern/src/corealloc_fcfs.c b/kern/src/corealloc_fcfs.c
index d250af9..cb346e9 100644
--- a/kern/src/corealloc_fcfs.c
+++ b/kern/src/corealloc_fcfs.c
@@ -22,9 +22,9 @@
{
/* Allocate all of our pcores. */
all_pcores = kzmalloc(sizeof(struct sched_pcore) * num_cores, 0);
- /* init the idlecore list. if they turned off hyperthreading, give them the
- * odds from 1..max-1. otherwise, give them everything by 0 (default mgmt
- * core). TODO: (CG/LL) better LL/CG mgmt */
+ /* init the idlecore list. if they turned off hyperthreading, give them
+ * the odds from 1..max-1. otherwise, give them everything by 0
+ * (default mgmt core). TODO: (CG/LL) better LL/CG mgmt */
for (int i = 0; i < num_cores; i++) {
if (is_ll_core(i))
continue;
@@ -71,8 +71,10 @@
spc->alloc_proc = p;
/* if the pcore is prov to them and now allocated, move lists */
if (spc->prov_proc == p) {
- TAILQ_REMOVE(&p->ksched_data.crd.prov_not_alloc_me, spc, prov_next);
- TAILQ_INSERT_TAIL(&p->ksched_data.crd.prov_alloc_me, spc, prov_next);
+ TAILQ_REMOVE(&p->ksched_data.crd.prov_not_alloc_me, spc,
+ prov_next);
+ TAILQ_INSERT_TAIL(&p->ksched_data.crd.prov_alloc_me, spc,
+ prov_next);
}
/* Actually allocate the core, removing it from the idle core list. */
TAILQ_REMOVE(&idlecores, spc, alloc_next);
@@ -91,10 +93,10 @@
/* if the pcore is prov to them and now deallocated, move lists */
if (spc->prov_proc == p) {
TAILQ_REMOVE(&p->ksched_data.crd.prov_alloc_me, spc, prov_next);
- /* this is the victim list, which can be sorted so that we pick the
- * right victim (sort by alloc_proc reverse priority, etc). In this
- * case, the core isn't alloc'd by anyone, so it should be the first
- * victim. */
+ /* this is the victim list, which can be sorted so that we pick
+ * the right victim (sort by alloc_proc reverse priority, etc).
+ * In this case, the core isn't alloc'd by anyone, so it should
+ * be the first victim. */
TAILQ_INSERT_HEAD(&p->ksched_data.crd.prov_not_alloc_me, spc,
prov_next);
}
@@ -128,7 +130,8 @@
if (match) {
TAILQ_REMOVE(&idlecores, spc_i, alloc_next);
TAILQ_INSERT_HEAD(&idlecores, spc_i, alloc_next);
- printk("Pcore %d will be given out next (from the idles)\n", pcoreid);
+ printk("Pcore %d will be given out next (from the idles)\n",
+ pcoreid);
}
}
@@ -145,7 +148,8 @@
TAILQ_FOREACH_SAFE(spc_i, &sorter, alloc_next, temp) {
TAILQ_REMOVE(&sorter, spc_i, alloc_next);
added = FALSE;
- /* don't need foreach_safe since we break after we muck with the list */
+ /* don't need foreach_safe since we break after we muck with the
+ * list */
TAILQ_FOREACH(spc_j, &idlecores, alloc_next) {
if (spc_i < spc_j) {
TAILQ_INSERT_BEFORE(spc_j, spc_i, alloc_next);
@@ -167,5 +171,6 @@
printk("Idle cores (unlocked!):\n");
TAILQ_FOREACH(spc_i, &idlecores, alloc_next)
printk("Core %d, prov to %d (%p)\n", spc2pcoreid(spc_i),
- spc_i->prov_proc ? spc_i->prov_proc->pid : 0, spc_i->prov_proc);
+ spc_i->prov_proc ? spc_i->prov_proc->pid : 0,
+ spc_i->prov_proc);
}
diff --git a/kern/src/corealloc_packed.c b/kern/src/corealloc_packed.c
index 64b8000..6ce3e382 100644
--- a/kern/src/corealloc_packed.c
+++ b/kern/src/corealloc_packed.c
@@ -27,8 +27,8 @@
enum pnode_type type;
struct sched_pnode *parent;
- /* Refcount is used to track how many cores have been allocated beneath the
- * current node in the hierarchy. */
+ /* Refcount is used to track how many cores have been allocated beneath
+ * the current node in the hierarchy. */
int refcount;
/* All nodes except cores have children. Cores have a sched_pcore. */
@@ -119,16 +119,18 @@
if (n->type == CORE) {
n->sched_pcore = &all_pcores[n->id];
n->sched_pcore->sched_pnode = n;
- n->sched_pcore->core_info = &cpu_topology_info.core_list[n->id];
+ n->sched_pcore->core_info =
+ &cpu_topology_info.core_list[n->id];
n->sched_pcore->alloc_proc = NULL;
n->sched_pcore->prov_proc = NULL;
}
- /* Otherwise initialize the children field, updating the parent of all
- * children to the current node. This assumes the children have already
- * been initialized (i.e. init_nodes() must be called iteratively from
- * the bottom-up). */
+ /* Otherwise initialize the children field, updating the parent
+ * of all children to the current node. This assumes the
+ * children have already been initialized (i.e. init_nodes()
+ * must be called iteratively from the bottom-up). */
if (n->type != CORE) {
- n->children = &node_lookup[child_node_type(type)][i * nchildren];
+ n->children =
+ &node_lookup[child_node_type(type)][i * nchildren];
for (int j = 0; j < nchildren; j++)
n->children[j].parent = n;
}
@@ -235,7 +237,8 @@
struct sched_pcore *temp = NULL;
TAILQ_FOREACH(temp, &cl, alloc_next) {
- d += core_distance[c->core_info->core_id][temp->core_info->core_id];
+ d += core_distance[c->core_info->core_id]
+ [temp->core_info->core_id];
}
return d;
}
@@ -267,8 +270,9 @@
int best_refcount;
/* Find the best, first provisioned core if there are any. Even if the
- * whole machine is allocated, we still give out provisioned cores, because
- * they will be revoked from their current owner if necessary. */
+ * whole machine is allocated, we still give out provisioned cores,
+ * because they will be revoked from their current owner if necessary.
+ */
c = find_first_provisioned_core(p);
if (c != NULL)
return c;
@@ -279,9 +283,9 @@
if (bestn->refcount == num_descendants[MACHINE][CORE])
return NULL;
- /* Otherwise, we know at least one core is still available, so let's find
- * the best one to allocate first. We start at NUMA, and loop through the
- * topology to find it. */
+ /* Otherwise, we know at least one core is still available, so let's
+ * find the best one to allocate first. We start at NUMA, and loop
+ * through the topology to find it. */
for (int i = NUMA; i >= CORE; i--) {
nodes = bestn->children;
best_refcount = total_nodes;
@@ -306,7 +310,8 @@
* already own. If no cores are available we return NULL.*/
static struct sched_pcore *find_closest_provisioned_core(struct proc *p)
{
- struct sched_pcore_tailq provisioned = p->ksched_data.crd.prov_not_alloc_me;
+ struct sched_pcore_tailq provisioned =
+ p->ksched_data.crd.prov_not_alloc_me;
struct sched_pcore_tailq allocated = p->ksched_data.crd.alloc_me;
struct sched_pcore *bestc = NULL;
struct sched_pcore *c = NULL;
@@ -392,8 +397,10 @@
spc->alloc_proc = p;
/* if the pcore is prov to them and now allocated, move lists */
if (spc->prov_proc == p) {
- TAILQ_REMOVE(&p->ksched_data.crd.prov_not_alloc_me, spc, prov_next);
- TAILQ_INSERT_TAIL(&p->ksched_data.crd.prov_alloc_me, spc, prov_next);
+ TAILQ_REMOVE(&p->ksched_data.crd.prov_not_alloc_me, spc,
+ prov_next);
+ TAILQ_INSERT_TAIL(&p->ksched_data.crd.prov_alloc_me, spc,
+ prov_next);
}
/* Actually allocate the core, removing it from the idle core list. */
TAILQ_REMOVE(&idlecores, spc, alloc_next);
@@ -414,10 +421,10 @@
/* if the pcore is prov to them and now deallocated, move lists */
if (spc->prov_proc == p) {
TAILQ_REMOVE(&p->ksched_data.crd.prov_alloc_me, spc, prov_next);
- /* this is the victim list, which can be sorted so that we pick the
- * right victim (sort by alloc_proc reverse priority, etc). In this
- * case, the core isn't alloc'd by anyone, so it should be the first
- * victim. */
+ /* this is the victim list, which can be sorted so that we pick
+ * the right victim (sort by alloc_proc reverse priority, etc).
+ * In this case, the core isn't alloc'd by anyone, so it should
+ * be the first victim. */
TAILQ_INSERT_HEAD(&p->ksched_data.crd.prov_not_alloc_me, spc,
prov_next);
}
@@ -441,7 +448,8 @@
* duration of the call. */
void __next_core_to_alloc(uint32_t pcoreid)
{
- printk("This function is not supported by this core allocation policy!\n");
+ printk("%s is not supported by this core allocation policy!\n",
+ __func__);
}
/* One off function to sort the idle core list for debugging in the kernel
@@ -449,7 +457,8 @@
* for the duration of the call. */
void __sort_idle_cores(void)
{
- printk("This function is not supported by this core allocation policy!\n");
+ printk("%s is not supported by this core allocation policy!\n",
+ __func__);
}
/* Print the map of idle cores that are still allocatable through our core
@@ -461,8 +470,9 @@
struct sched_pcore *spc_i = &all_pcores[i];
if (spc_i->alloc_proc == NULL)
- printk("Core %d, prov to %d (%p)\n", spc_i->core_info->core_id,
- spc_i->prov_proc ? spc_i->prov_proc->pid :
- 0, spc_i->prov_proc);
+ printk("Core %d, prov to %d (%p)\n",
+ spc_i->core_info->core_id,
+ spc_i->prov_proc ? spc_i->prov_proc->pid : 0,
+ spc_i->prov_proc);
}
}
diff --git a/kern/src/coreprov.c b/kern/src/coreprov.c
index b432dfe..229280c 100644
--- a/kern/src/coreprov.c
+++ b/kern/src/coreprov.c
@@ -15,27 +15,29 @@
struct sched_pcore *spc = pcoreid2spc(pcoreid);
struct sched_pcore_tailq *prov_list;
- /* If the core is already prov to someone else, take it away. (last write
- * wins, some other layer or new func can handle permissions). */
+ /* If the core is already prov to someone else, take it away. (last
+ * write wins, some other layer or new func can handle permissions). */
if (spc->prov_proc) {
- /* the list the spc is on depends on whether it is alloced to the
- * prov_proc or not */
- prov_list = (spc->alloc_proc == spc->prov_proc ?
- &spc->prov_proc->ksched_data.crd.prov_alloc_me :
- &spc->prov_proc->ksched_data.crd.prov_not_alloc_me);
+ /* the list the spc is on depends on whether it is alloced to
+ * the prov_proc or not */
+ prov_list = spc->alloc_proc == spc->prov_proc ?
+ &spc->prov_proc->ksched_data.crd.prov_alloc_me :
+ &spc->prov_proc->ksched_data.crd.prov_not_alloc_me;
TAILQ_REMOVE(prov_list, spc, prov_next);
}
- /* Now prov it to p. Again, the list it goes on depends on whether it is
- * alloced to p or not. Callers can also send in 0 to de-provision. */
+ /* Now prov it to p. Again, the list it goes on depends on whether it
+ * is alloced to p or not. Callers can also send in 0 to de-provision.
+ * */
if (p) {
if (spc->alloc_proc == p) {
TAILQ_INSERT_TAIL(&p->ksched_data.crd.prov_alloc_me, spc,
prov_next);
} else {
- /* this is be the victim list, which can be sorted so that we pick
- * the right victim (sort by alloc_proc reverse priority, etc). */
- TAILQ_INSERT_TAIL(&p->ksched_data.crd.prov_not_alloc_me, spc,
- prov_next);
+ /* this is be the victim list, which can be sorted so
+ * that we pick the right victim (sort by alloc_proc
+ * reverse priority, etc). */
+ TAILQ_INSERT_TAIL(&p->ksched_data.crd.prov_not_alloc_me,
+ spc, prov_next);
}
}
spc->prov_proc = p;
@@ -45,11 +47,12 @@
static void __unprov_pcore_list(struct sched_pcore_tailq *list_head)
{
struct sched_pcore *spc_i;
- /* We can leave them connected within the tailq, since the scps don't have a
- * default list (if they aren't on a proc's list, then we don't care about
- * them), and since the INSERTs don't care what list you were on before
- * (chummy with the implementation). Pretty sure this is right. If there's
- * suspected list corruption, be safer here. */
+
+ /* We can leave them connected within the tailq, since the scps don't
+ * have a default list (if they aren't on a proc's list, then we don't
+ * care about them), and since the INSERTs don't care what list you were
+ * on before (chummy with the implementation). Pretty sure this is
+ * right. If there's suspected list corruption, be safer here. */
TAILQ_FOREACH(spc_i, list_head, prov_next)
spc_i->prov_proc = 0;
TAILQ_INIT(list_head);
@@ -74,7 +77,8 @@
printk("Prov cores alloced to proc %d (%p)\n----------\n", p->pid, p);
TAILQ_FOREACH(spc_i, &p->ksched_data.crd.prov_alloc_me, prov_next)
printk("Pcore %d\n", spc2pcoreid(spc_i));
- printk("Prov cores not alloced to proc %d (%p)\n----------\n", p->pid, p);
+ printk("Prov cores not alloced to proc %d (%p)\n----------\n", p->pid,
+ p);
TAILQ_FOREACH(spc_i, &p->ksched_data.crd.prov_not_alloc_me, prov_next)
printk("Pcore %d (alloced to %d (%p))\n", spc2pcoreid(spc_i),
spc_i->alloc_proc ? spc_i->alloc_proc->pid : 0,
@@ -90,11 +94,12 @@
/* Doing this without a scheduler lock, which is dangerous, but won't
* deadlock */
print_lock();
- printk("Which cores are provisioned to which procs:\n------------------\n");
+ printk("Which cores are provisioned to which procs:\n--------------\n");
for (int i = 0; i < num_cores; i++) {
spc_i = pcoreid2spc(i);
printk("Core %02d, prov: %d(%p) alloc: %d(%p)\n", i,
- spc_i->prov_proc ? spc_i->prov_proc->pid : 0, spc_i->prov_proc,
+ spc_i->prov_proc ? spc_i->prov_proc->pid : 0,
+ spc_i->prov_proc,
spc_i->alloc_proc ? spc_i->alloc_proc->pid : 0,
spc_i->alloc_proc);
}
diff --git a/kern/src/elf.c b/kern/src/elf.c
index 7a91373..af7cc63 100644
--- a/kern/src/elf.c
+++ b/kern/src/elf.c
@@ -45,7 +45,8 @@
flags, NULL, 0) == MAP_FAILED)
return 0;
- /* Function to get the lengths of the argument and environment strings. */
+ /* Function to get the lengths of the argument and environment strings.
+ */
int get_lens(int argc, char *argv[], int arg_lens[])
{
int total = 0;
@@ -64,7 +65,8 @@
int offset = 0;
char *temp_argv[argc + 1];
for(int i = 0; i < argc; i++) {
- if (memcpy_to_user(p, new_argbuf + offset, argv[i], arg_lens[i]))
+ if (memcpy_to_user(p, new_argbuf + offset, argv[i],
+ arg_lens[i]))
return -1;
temp_argv[i] = new_argbuf + offset;
offset += arg_lens[i];
@@ -75,9 +77,9 @@
return offset;
}
- /* Start tracking the size of the buffer necessary to hold all of our data
- * on the stack. Preallocate space for argc, argv, envp, and auxv in this
- * buffer. */
+ /* Start tracking the size of the buffer necessary to hold all of our
+ * data on the stack. Preallocate space for argc, argv, envp, and auxv
+ * in this buffer. */
int bufsize = 0;
bufsize += 1 * sizeof(size_t);
bufsize += (auxc + 1) * sizeof(elf_aux_t);
@@ -90,7 +92,8 @@
bufsize += get_lens(argc, argv, arg_lens);
bufsize += get_lens(envc, envp, env_lens);
- /* Adjust bufsize so that our buffer will ultimately be 16 byte aligned. */
+ /* Adjust bufsize so that our buffer will ultimately be 16 byte aligned.
+ */
bufsize = ROUNDUP(bufsize, 16);
/* Set up pointers to all of the appropriate data regions we map to. */
@@ -153,7 +156,8 @@
elf64_t* elfhdr64 = &elfhdr_storage;
if (foc_read(foc, (char*)elfhdr64, sizeof(elf64_t), f_off)
!= sizeof(elf64_t)) {
- /* if you ever debug this, be sure to 0 out elfhrd_storage in advance */
+ /* if you ever debug this, be sure to 0 out elfhrd_storage in
+ * advance */
printk("[kernel] load_one_elf: failed to read file\n");
goto fail;
}
@@ -195,7 +199,7 @@
f_off = e_phoff;
if (!phdrs || foc_read(foc, phdrs, e_phnum * phsz, f_off) !=
e_phnum * phsz) {
- printk("[kernel] load_one_elf: could not get program headers\n");
+ printk("[kernel] load_one_elf: couldn't get program headers\n");
goto fail;
}
for (int i = 0; i < e_phnum; i++) {
@@ -211,19 +215,21 @@
/* Here's the ld hack, mentioned above */
p_flags |= (writable ? ELF_PROT_WRITE : 0);
- /* All mmaps need to be fixed to their VAs. If the program wants it to
- * be a writable region, we also need the region to be private. */
- mm_flags = MAP_FIXED |
- (p_flags & ELF_PROT_WRITE ? MAP_PRIVATE : MAP_SHARED);
+ /* All mmaps need to be fixed to their VAs. If the program
+ * wants it to be a writable region, we also need the region to
+ * be private. */
+ mm_flags = MAP_FIXED | (p_flags & ELF_PROT_WRITE ? MAP_PRIVATE :
+ MAP_SHARED);
if (p_type == ELF_PROG_PHDR)
ei->phdr = p_va;
else if (p_type == ELF_PROG_INTERP) {
f_off = p_offset;
ssize_t maxlen = sizeof(ei->interp);
- ssize_t bytes = foc_read(foc, ei->interp, maxlen, f_off);
- /* trying to catch errors. don't know how big it could be, but it
- * should be at least 0. */
+ ssize_t bytes = foc_read(foc, ei->interp, maxlen,
+ f_off);
+ /* trying to catch errors. don't know how big it could
+ * be, but it should be at least 0. */
if (bytes <= 0) {
printk("[kernel] load_one_elf: could not read ei->interp\n");
goto fail;
@@ -251,7 +257,8 @@
uintptr_t filesz = p_offset + p_filesz - filestart;
uintptr_t memstart = ROUNDDOWN(p_va, PGSIZE);
- uintptr_t memsz = ROUNDUP(p_va + p_memsz, PGSIZE) - memstart;
+ uintptr_t memsz = ROUNDUP(p_va + p_memsz, PGSIZE) -
+ memstart;
memstart += pg_num * PGSIZE;
if (memstart + memsz > ei->highest_addr)
@@ -263,63 +270,77 @@
mm_perms |= (p_flags & ELF_PROT_EXEC ? PROT_EXEC : 0);
if (filesz) {
- /* Due to elf-ghetto-ness, we need to zero the first part of
- * the BSS from the last page of the data segment. If we end
- * on a partial page, we map it in separately with
- * MAP_POPULATE so that we can zero the rest of it now. We
- * translate to the KVA so we don't need to worry about using
- * the proc's mapping */
+ /* Due to elf-ghetto-ness, we need to zero the
+ * first part of the BSS from the last page of
+ * the data segment. If we end on a partial
+ * page, we map it in separately with
+ * MAP_POPULATE so that we can zero the rest of
+ * it now. We translate to the KVA so we don't
+ * need to worry about using the proc's mapping
+ * */
uintptr_t partial = PGOFF(filesz);
if (filesz - partial) {
/* Map the complete pages. */
- if (do_mmap(p, memstart, filesz - partial, mm_perms,
- mm_flags, foc, filestart) == MAP_FAILED) {
+ if (do_mmap(p, memstart, filesz -
+ partial, mm_perms, mm_flags,
+ foc, filestart) ==
+ MAP_FAILED) {
printk("[kernel] load_one_elf: complete mmap failed\n");
goto fail;
}
}
- /* Note that we (probably) only need to do this zeroing the end
- * of a partial file page when we are dealing with
- * ELF_PROT_WRITE-able PHs, and not for all cases. */
+ /* Note that we (probably) only need to do this
+ * zeroing the end of a partial file page when
+ * we are dealing with ELF_PROT_WRITE-able PHs,
+ * and not for all cases. */
if (partial) {
- /* Need our own populated, private copy of the page so that
- * we can zero the remainder - and not zero chunks of the
- * real file in the page cache. */
+ /* Need our own populated, private copy
+ * of the page so that we can zero the
+ * remainder - and not zero chunks of
+ * the real file in the page cache. */
mm_flags &= ~MAP_SHARED;
mm_flags |= MAP_PRIVATE | MAP_POPULATE;
/* Map the final partial page. */
- uintptr_t last_page = memstart + filesz - partial;
- if (do_mmap(p, last_page, PGSIZE, mm_perms, mm_flags,
- foc, filestart + filesz - partial)
- == MAP_FAILED) {
+ uintptr_t last_page = memstart + filesz
+ - partial;
+ if (do_mmap(p, last_page, PGSIZE,
+ mm_perms, mm_flags, foc,
+ filestart + filesz -
+ partial) == MAP_FAILED) {
printk("[kernel] load_one_elf: partial mmap failed\n");
goto fail;
}
- /* Zero the end of it. This is a huge pain in the ass. The
- * filesystems should zero out the last bits of a page if
- * the file doesn't fill the last page. But we're dealing
- * with windows into otherwise complete files. */
- pte_t pte = pgdir_walk(p->env_pgdir, (void*)last_page, 0);
- /* if we were able to get a PTE, then there is a real page
- * backing the VMR, and we need to zero the excess. if
- * there isn't, then the page fault code should handle it.
- * since we set populate above, we should have a PTE, except
- * in cases where the offset + len window exceeded the file
- * size. in this case, we let them mmap it, but didn't
- * populate it. there will be a PF right away if someone
- * tries to use this. check out do_mmap for more info. */
+ pte_t pte = pgdir_walk(p->env_pgdir,
+ (void*)last_page,
+ 0);
+ /* if we were able to get a PTE, then
+ * there is a real page backing the VMR,
+ * and we need to zero the excess. if
+ * there isn't, then the page fault code
+ * should handle it. since we set
+ * populate above, we should have a PTE,
+ * except in cases where the offset +
+ * len window exceeded the file size.
+ * in this case, we let them mmap it,
+ * but didn't populate it. there will
+ * be a PF right away if someone tries
+ * to use this. check out do_mmap for
+ * more info. */
if (pte_walk_okay(pte)) {
- void* last_page_kva = KADDR(pte_get_paddr(pte));
- memset(last_page_kva + partial, 0, PGSIZE - partial);
+ void *last_page_kva =
+ KADDR(pte_get_paddr(pte));
+ memset(last_page_kva + partial,
+ 0, PGSIZE - partial);
}
filesz = ROUNDUP(filesz, PGSIZE);
}
}
- /* Any extra pages are mapped anonymously... (a bit weird) */
+ /* Any extra pages are mapped anonymously... (a bit
+ * weird) */
if (filesz < memsz)
if (do_mmap(p, memstart + filesz, memsz-filesz,
PROT_READ | PROT_WRITE, MAP_PRIVATE,
@@ -362,16 +383,17 @@
return -1;
if (ei.dynamic) {
- struct file_or_chan *interp = foc_open(ei.interp, O_EXEC | O_READ, 0);
+ struct file_or_chan *interp = foc_open(ei.interp, O_EXEC |
+ O_READ, 0);
if (!interp)
return -1;
/* Load dynamic linker at 1M. Obvious MIB joke avoided.
- * It used to be loaded at page 1, but the existence of valid addresses
- * that low masked bad derefs through NULL pointer structs. This in turn
- * helped us waste a full day debugging a bug in the Go runtime. True!
- * Note that MMAP_LOWEST_VA also has this value but we want to make this
- * explicit. */
+ * It used to be loaded at page 1, but the existence of valid
+ * addresses that low masked bad derefs through NULL pointer
+ * structs. This in turn helped us waste a full day debugging a
+ * bug in the Go runtime. True! Note that MMAP_LOWEST_VA also
+ * has this value but we want to make this explicit. */
int error = load_one_elf(p, interp, MMAP_LD_FIXED_VA >> PGSHIFT,
&interp_ei, TRUE);
foc_decref(interp);
@@ -387,7 +409,8 @@
int auxc = sizeof(auxv)/sizeof(auxv[0]);
/* Populate the stack with the required info. */
- uintptr_t stack_top = populate_stack(p, argc, argv, envc, envp, auxc, auxv);
+ uintptr_t stack_top = populate_stack(p, argc, argv, envc, envp, auxc,
+ auxv);
if (!stack_top)
return -1;
@@ -417,7 +440,8 @@
char *get_startup_argv(struct proc *p, size_t idx, char *argp,
size_t max_size)
{
- size_t stack_space = (const char *) USTACKTOP - (const char *) p->args_base;
+ size_t stack_space = (const char *) USTACKTOP - (const char *)
+ p->args_base;
const char *sptr = (const char *) p->args_base + sizeof(size_t) +
idx * sizeof(char *);
const char *argv = NULL;
diff --git a/kern/src/env.c b/kern/src/env.c
index 0623f3e..bca490e 100644
--- a/kern/src/env.c
+++ b/kern/src/env.c
@@ -42,33 +42,38 @@
e->env_cr3 = arch_pgdir_get_cr3(e->env_pgdir);
/* These need to be contiguous, so the kernel can alias them. Note the
- * pages return with a refcnt, but it's okay to insert them since we free
- * them manually when the process is cleaned up. */
- if (!(e->procinfo = kpages_alloc(PROCINFO_NUM_PAGES * PGSIZE, MEM_WAIT)))
+ * pages return with a refcnt, but it's okay to insert them since we
+ * free them manually when the process is cleaned up. */
+ if (!(e->procinfo = kpages_alloc(PROCINFO_NUM_PAGES * PGSIZE,
+ MEM_WAIT)))
goto env_setup_vm_error_i;
- if (!(e->procdata = kpages_alloc(PROCDATA_NUM_PAGES * PGSIZE, MEM_WAIT)))
+ if (!(e->procdata = kpages_alloc(PROCDATA_NUM_PAGES * PGSIZE,
+ MEM_WAIT)))
goto env_setup_vm_error_d;
/* Normally we would 0 the pages here. We handle it in proc_init_proc*.
* Do not start the process without calling those. */
for (int i = 0; i < PROCINFO_NUM_PAGES; i++) {
- if (page_insert(e->env_pgdir, kva2page((void*)e->procinfo + i *
- PGSIZE), (void*)(UINFO + i*PGSIZE), PTE_USER_RO) < 0)
+ if (page_insert(e->env_pgdir,
+ kva2page((void*)e->procinfo + i * PGSIZE),
+ (void*)(UINFO + i * PGSIZE), PTE_USER_RO) < 0)
goto env_setup_vm_error;
}
for (int i = 0; i < PROCDATA_NUM_PAGES; i++) {
- if (page_insert(e->env_pgdir, kva2page((void*)e->procdata + i *
- PGSIZE), (void*)(UDATA + i*PGSIZE), PTE_USER_RW) < 0)
+ if (page_insert(e->env_pgdir,
+ kva2page((void*)e->procdata + i * PGSIZE),
+ (void*)(UDATA + i * PGSIZE), PTE_USER_RW) < 0)
goto env_setup_vm_error;
}
for (int i = 0; i < PROCGINFO_NUM_PAGES; i++) {
if (page_insert(e->env_pgdir,
- kva2page((void*)&__proc_global_info + i * PGSIZE),
+ kva2page((void*)&__proc_global_info
+ + i * PGSIZE),
(void*)(UGINFO + i * PGSIZE), PTE_USER_RO) < 0)
goto env_setup_vm_error;
}
- /* Finally, set up the Global Shared Data page for all processes. Can't be
- * trusted, but still very useful at this stage for us. Consider removing
- * when we have real processes (TODO).
+ /* Finally, set up the Global Shared Data page for all processes. Can't
+ * be trusted, but still very useful at this stage for us. Consider
+ * removing when we have real processes (TODO).
*
* Note the page is alloced only the first time through, and its ref is
* stored in shared_page. */
@@ -76,7 +81,8 @@
if (upage_alloc(e, &shared_page, 1) < 0)
goto env_setup_vm_error;
}
- if (page_insert(e->env_pgdir, shared_page, (void*)UGDATA, PTE_USER_RW) < 0)
+ if (page_insert(e->env_pgdir, shared_page, (void*)UGDATA, PTE_USER_RW)
+ < 0)
goto env_setup_vm_error;
return 0;
@@ -94,7 +100,7 @@
/* Frees (decrefs) all memory mapped in the given range */
void env_user_mem_free(env_t* e, void* start, size_t len)
{
- assert((uintptr_t)start + len <= UVPT); //since this keeps fucking happening
+ assert((uintptr_t)start + len <= UVPT);
int user_page_free(env_t* e, pte_t pte, void* va, void* arg)
{
if (!pte_is_mapped(pte))
@@ -102,9 +108,10 @@
page_t *page = pa2page(pte_get_paddr(pte));
pte_clear(pte);
page_decref(page);
- /* TODO: consider other states here (like !P, yet still tracking a page,
- * for VM tricks, page map stuff, etc. Should be okay: once we're
- * freeing, everything else about this proc is dead. */
+ /* TODO: consider other states here (like !P, yet still tracking
+ * a page, for VM tricks, page map stuff, etc. Should be okay:
+ * once we're freeing, everything else about this proc is dead.
+ * */
return 0;
}
@@ -139,7 +146,8 @@
error(EINVAL, "New username is NULL");
if (strlen(name) > sizeof(u->name) - 1)
- error(EINVAL, "New username for process more than %d chars long",
+ error(EINVAL,
+ "New username for process more than %d chars long",
sizeof(u->name) - 1);
// 'backward' copy since reads aren't protected
diff --git a/kern/src/err.c b/kern/src/err.c
index d4ae123..7ff3b23 100644
--- a/kern/src/err.c
+++ b/kern/src/err.c
@@ -27,7 +27,7 @@
* 0, and we'll set cur_eb to slot 0. When we leave, curindex is set to the
* next free slot. */
struct errbuf *errpush(struct errbuf *errstack, int stacksize, int *curindex,
- struct errbuf **prev_errbuf)
+ struct errbuf **prev_errbuf)
{
struct errbuf *cbuf;
@@ -52,9 +52,9 @@
* When we enter, curindex is the slot of the next *free* errstack (the one we'd
* push into if we were pushing. When we leave, it will be decreased by one,
* and will still point to the next free errstack (the one we are popping).
- * */
+ */
struct errbuf *errpop(struct errbuf *errstack, int stacksize, int *curindex,
- struct errbuf *prev_errbuf)
+ struct errbuf *prev_errbuf)
{
struct errbuf *cbuf;
@@ -62,8 +62,9 @@
/* curindex now points to the slot we are popping*/
*curindex = *curindex - 1;
/* We still need to advertise the previous slot, which is one back from
- * curindex. If curindex is 0, that means the next free slot is the first
- * of our errstack. In this case, we need to advertise the prev. */
+ * curindex. If curindex is 0, that means the next free slot is the
+ * first of our errstack. In this case, we need to advertise the prev.
+ */
if (*curindex < 0)
panic("Error stack underflow");
diff --git a/kern/src/event.c b/kern/src/event.c
index 91243aa..b578d00 100644
--- a/kern/src/event.c
+++ b/kern/src/event.c
@@ -77,21 +77,22 @@
static void post_ev_msg(struct proc *p, struct event_mbox *mbox,
struct event_msg *msg, int ev_flags)
{
- printd("[kernel] Sending event type %d to mbox %p\n", msg->ev_type, mbox);
+ printd("[kernel] Sending event type %d to mbox %p\n",
+ msg->ev_type, mbox);
/* Sanity check */
assert(p);
switch (mbox->type) {
- case (EV_MBOX_UCQ):
- send_ucq_msg(&mbox->ucq, p, msg);
- break;
- case (EV_MBOX_BITMAP):
- send_evbitmap_msg(&mbox->evbm, msg);
- break;
- case (EV_MBOX_CEQ):
- send_ceq_msg(&mbox->ceq, p, msg);
- break;
- default:
- printk("[kernel] Unknown mbox type %d!\n", mbox->type);
+ case (EV_MBOX_UCQ):
+ send_ucq_msg(&mbox->ucq, p, msg);
+ break;
+ case (EV_MBOX_BITMAP):
+ send_evbitmap_msg(&mbox->evbm, msg);
+ break;
+ case (EV_MBOX_CEQ):
+ send_ceq_msg(&mbox->ceq, p, msg);
+ break;
+ default:
+ printk("[kernel] Unknown mbox type %d!\n", mbox->type);
}
}
@@ -104,10 +105,11 @@
{
struct preempt_data *vcpd = &__procdata.vcore_preempt_data[vcoreid];
post_ev_msg(p, ev_mbox, ev_msg, ev_flags);
- /* Set notif pending so userspace doesn't miss the message while yielding */
+ /* Set notif pending so userspace doesn't miss the message while
+ * yielding */
wmb(); /* Ensure ev_msg write is before notif_pending */
- /* proc_notify() also sets this, but the ev_q might not have requested an
- * IPI, so we have to do it here too. */
+ /* proc_notify() also sets this, but the ev_q might not have requested
+ * an IPI, so we have to do it here too. */
vcpd->notif_pending = TRUE;
}
@@ -135,11 +137,12 @@
static bool try_spam_vcore(struct proc *p, uint32_t vcoreid,
struct event_msg *ev_msg, int ev_flags)
{
- /* Not sure if we can or not, so check before spamming. Technically, the
- * only critical part is that we __alert, then check can_alert. */
+ /* Not sure if we can or not, so check before spamming. Technically,
+ * the only critical part is that we __alert, then check can_alert. */
if (can_msg_vcore(vcoreid)) {
spam_vcore(p, vcoreid, ev_msg, ev_flags);
- wrmb(); /* prev write (notif_pending) must come before following reads*/
+ /* prev write (notif_pending) must come before following reads*/
+ wrmb();
if (can_msg_vcore(vcoreid))
return TRUE;
}
@@ -160,33 +163,37 @@
uint32_t vcoreid;
int loops = 0;
vc = TAILQ_FIRST(list);
- /* If the list appears empty, we'll bail out (failing) after the loop. */
+ /* If the list appears empty, we'll bail out (failing) after the loop.
+ */
while (vc) {
vcoreid = vcore2vcoreid(p, vc);
- /* post the alert. Not using the try_spam_vcore() helper since I want
- * something more customized for the lists. */
+ /* post the alert. Not using the try_spam_vcore() helper since
+ * I want something more customized for the lists. */
spam_vcore(p, vcoreid, ev_msg, ev_flags);
- wrmb(); /* prev write (notif_pending) must come before following reads*/
- /* I used to check can_msg_vcore(vcoreid) here, but that would make
- * spamming list members unusable for MUST_RUN scenarios.
+ /* prev write (notif_pending) must come before following reads*/
+ wrmb();
+ /* I used to check can_msg_vcore(vcoreid) here, but that would
+ * make spamming list members unusable for MUST_RUN scenarios.
*
- * Regardless, if they are still the first on the list, then they are
- * still going to get the message. For the online list, proc_yield()
- * will return them to userspace (where they will get the message)
- * because __alert_vcore() set notif_pending. For the BP list, they
- * will either be turned on later, or have a preempt message sent about
- * their demise.
+ * Regardless, if they are still the first on the list, then
+ * they are still going to get the message. For the online
+ * list, proc_yield() will return them to userspace (where they
+ * will get the message) because __alert_vcore() set
+ * notif_pending. For the BP list, they will either be turned
+ * on later, or have a preempt message sent about their demise.
*
- * We race on list membership (and not exclusively VC_CAN_RCV_MSG, so
- * that when it fails we can get a new vcore to try (or know WHP there
- * are none). */
+ * We race on list membership (and not exclusively
+ * VC_CAN_RCV_MSG, so that when it fails we can get a new vcore
+ * to try (or know WHP there are none). */
vc_first = TAILQ_FIRST(list);
if (vc == vc_first)
return TRUE;
- /* At this point, the list has changed and the vcore we tried yielded,
- * so we try the *new* list head. Track loops for sanity reasons. */
+ /* At this point, the list has changed and the vcore we tried
+ * yielded, so we try the *new* list head. Track loops for
+ * sanity reasons. */
if (loops++ > 10) {
- warn("Too many (%d) attempts to find a vcore, failing!", loops);
+ warn("Too many (%d) attempts to find a vcore, failing!",
+ loops);
return FALSE; /* always safe to fail! */
}
/* Get set up for your attack run! */
@@ -217,7 +224,7 @@
* we try to send_event() (in theory, there isn't code that can send that event
* yet). Someone else will get the event and wake up the preempted vcore. */
static void spam_public_msg(struct proc *p, struct event_msg *ev_msg,
- uint32_t vcoreid, int ev_flags)
+ uint32_t vcoreid, int ev_flags)
{
struct vcore *vc;
if (!__proc_is_mcp(p)) {
@@ -225,11 +232,15 @@
return;
}
if (ev_flags & EVENT_VCORE_MUST_RUN) {
- /* Could check for waiting and skip these spams, which will fail. Could
- * also skip trying for vcoreid, and just spam any old online VC. */
- if (vcore_is_mapped(p, vcoreid)) { /* check, signal, check again */
+ /* Could check for waiting and skip these spams, which will
+ * fail. Could also skip trying for vcoreid, and just spam any
+ * old online VC. */
+ if (vcore_is_mapped(p, vcoreid)) {
+ /* check, signal, check again */
spam_vcore(p, vcoreid, ev_msg, ev_flags);
- wrmb(); /* notif_pending write must come before following read */
+ /* notif_pending write must come before following read
+ */
+ wrmb();
if (vcore_is_mapped(p, vcoreid))
return;
}
@@ -244,8 +255,8 @@
if (p->state == PROC_WAITING)
goto ultimate_fallback;
/* If we're here, the desired vcore is unreachable, but the process is
- * probably RUNNING_M (online_vs) or RUNNABLE_M (bulk preempted or recently
- * woken up), so we'll need to find another vcore. */
+ * probably RUNNING_M (online_vs) or RUNNABLE_M (bulk preempted or
+ * recently woken up), so we'll need to find another vcore. */
if (spam_list_member(&p->online_vcs, p, ev_msg, ev_flags))
return;
if (spam_list_member(&p->bulk_preempted_vcs, p, ev_msg, ev_flags))
@@ -257,55 +268,57 @@
vc = TAILQ_FIRST(&p->inactive_vcs);
if (vc) { /* might be none in rare circumstances */
if (try_spam_vcore(p, vcore2vcoreid(p, vc), ev_msg, ev_flags)) {
- /* It's possible that we're WAITING here. EVENT_WAKEUP will handle
- * it. One way for this to happen is if a normal vcore was
- * preempted right as another vcore was yielding, and the preempted
- * message was sent after the last vcore yielded (which caused us to
- * be WAITING). */
+ /* It's possible that we're WAITING here. EVENT_WAKEUP
+ * will handle it. One way for this to happen is if a
+ * normal vcore was preempted right as another vcore was
+ * yielding, and the preempted message was sent after
+ * the last vcore yielded (which caused us to be
+ * WAITING). */
return;
}
}
ultimate_fallback:
/* At this point, we can't find one. This could be due to a (hopefully
- * rare) weird yield/request storm, or more commonly because the lists were
- * empty and the process is simply WAITING (yielded all of its vcores and is
- * waiting on an event). Time for the ultimate fallback: locking. Note
- * that when we __alert_vcore(), there is a chance we need to mmap, which
- * grabs the vmr_lock and pte_lock. */
+ * rare) weird yield/request storm, or more commonly because the lists
+ * were empty and the process is simply WAITING (yielded all of its
+ * vcores and is waiting on an event). Time for the ultimate fallback:
+ * locking. Note that when we __alert_vcore(), there is a chance we
+ * need to mmap, which grabs the vmr_lock and pte_lock. */
spin_lock(&p->proc_lock);
if (p->state != PROC_WAITING) {
- /* We need to check the online and bulk_preempt lists again, now that we
- * are sure no one is messing with them. If we're WAITING, we can skip
- * these (or assert they are empty!). */
+ /* We need to check the online and bulk_preempt lists again, now
+ * that we are sure no one is messing with them. If we're
+ * WAITING, we can skip these (or assert they are empty!). */
vc = TAILQ_FIRST(&p->online_vcs);
if (vc) {
- /* there's an online vcore, so just alert it (we know it isn't going
- * anywhere), and return */
+ /* there's an online vcore, so just alert it (we know it
+ * isn't going anywhere), and return */
spam_vcore(p, vcore2vcoreid(p, vc), ev_msg, ev_flags);
spin_unlock(&p->proc_lock);
return;
}
vc = TAILQ_FIRST(&p->bulk_preempted_vcs);
if (vc) {
- /* the process is bulk preempted, similar deal to above */
+ /* the process is bulk preempted, similar deal to above
+ */
spam_vcore(p, vcore2vcoreid(p, vc), ev_msg, ev_flags);
spin_unlock(&p->proc_lock);
return;
}
}
- /* At this point, we're sure all vcores are yielded, though we might not be
- * WAITING. Post to the first on the inactive list (which is the one that
- * will definitely be woken up) */
+ /* At this point, we're sure all vcores are yielded, though we might not
+ * be WAITING. Post to the first on the inactive list (which is the one
+ * that will definitely be woken up) */
vc = TAILQ_FIRST(&p->inactive_vcs);
assert(vc);
spam_vcore(p, vcore2vcoreid(p, vc), ev_msg, ev_flags);
- /* Set the vcore's alertable flag, to short circuit our last ditch effort
- * above */
+ /* Set the vcore's alertable flag, to short circuit our last ditch
+ * effort above */
set_vcore_msgable(vcore2vcoreid(p, vc));
- /* The first event to catch the process with no online/bp vcores will need
- * to wake it up, which is handled elsewhere if they requested EVENT_WAKEUP.
- * We could be RUNNABLE_M here if another event already woke us and we
- * didn't get lucky with the penultimate fallback. */
+ /* The first event to catch the process with no online/bp vcores will
+ * need to wake it up, which is handled elsewhere if they requested
+ * EVENT_WAKEUP. We could be RUNNABLE_M here if another event already
+ * woke us and we didn't get lucky with the penultimate fallback. */
spin_unlock(&p->proc_lock);
}
@@ -314,11 +327,11 @@
uint32_t vcoreid)
{
struct event_msg local_msg = {0};
- /* If an alert is already pending and they don't want repeats, just return.
- * One of the few uses of NOTHROTTLE will be for preempt_msg ev_qs. Ex: an
- * INDIR was already sent to the preempted vcore, then alert throttling
- * would stop another vcore from getting the message about the original
- * vcore. */
+ /* If an alert is already pending and they don't want repeats, just
+ * return. One of the few uses of NOTHROTTLE will be for preempt_msg
+ * ev_qs. Ex: an INDIR was already sent to the preempted vcore, then
+ * alert throttling would stop another vcore from getting the message
+ * about the original vcore. */
if (!(ev_q->ev_flags & EVENT_NOTHROTTLE) && (ev_q->ev_alert_pending))
return;
/* We'll eventually get an INDIR through, so don't send any more til
@@ -326,24 +339,25 @@
* eventually send an alert that causes userspace to turn throttling off
* again (before handling all of the ev_q's events).
*
- * This will also squelch IPIs, since there's no reason to send the IPI if
- * the INDIR is still un-acknowledged. The vcore is either in vcore
- * context, attempting to deal with the INDIR, or offline. This statement
- * is probably true. */
+ * This will also squelch IPIs, since there's no reason to send the IPI
+ * if the INDIR is still un-acknowledged. The vcore is either in vcore
+ * context, attempting to deal with the INDIR, or offline. This
+ * statement is probably true. */
ev_q->ev_alert_pending = TRUE;
wmb(); /* force this write to happen before any event writes */
local_msg.ev_type = EV_EVENT;
local_msg.ev_arg3 = ev_q;
/* If we're not spamming indirs, just send and be done with it.
*
- * It's possible that the user does not want to poll their evq and wants an
- * INDIR, but also doesn't care about sleeping or otherwise not getting the
- * message right away. The INDIR could sit in the VCPD of a vcore that
- * doesn't run for a while. Perhaps if the app always made sure VC 0 was
- * on when it was running at all, and sent the INDIR there. Or there was a
- * per-vc evq that only needed to be handled when the VC turned on. This
- * gets at another aspect of INDIRs, other than it's need for "only once"
- * operation: maybe the mbox type isn't a UCQ (like the VCPD mboxes). */
+ * It's possible that the user does not want to poll their evq and wants
+ * an INDIR, but also doesn't care about sleeping or otherwise not
+ * getting the message right away. The INDIR could sit in the VCPD of a
+ * vcore that doesn't run for a while. Perhaps if the app always made
+ * sure VC 0 was on when it was running at all, and sent the INDIR
+ * there. Or there was a per-vc evq that only needed to be handled when
+ * the VC turned on. This gets at another aspect of INDIRs, other than
+ * it's need for "only once" operation: maybe the mbox type isn't a UCQ
+ * (like the VCPD mboxes). */
if (!(ev_q->ev_flags & EVENT_SPAM_INDIR)) {
spam_vcore(p, vcoreid, &local_msg, ev_q->ev_flags);
return;
@@ -375,16 +389,17 @@
* address space */
old_proc = switch_to(p);
/* Get the vcoreid that we'll message (if appropriate). For INDIR and
- * SPAMMING, this is the first choice of a vcore, but other vcores might get
- * it. Common case is !APPRO and !ROUNDROBIN. Note we are clobbering the
- * vcoreid parameter. */
+ * SPAMMING, this is the first choice of a vcore, but other vcores might
+ * get it. Common case is !APPRO and !ROUNDROBIN. Note we are
+ * clobbering the vcoreid parameter. */
if (!(ev_q->ev_flags & EVENT_VCORE_APPRO))
vcoreid = ev_q->ev_vcore; /* use the ev_q's vcoreid */
/* Note that RR overwrites APPRO */
if (ev_q->ev_flags & EVENT_ROUNDROBIN) {
- /* Pick a vcore, round-robin style. Assuming ev_vcore was the previous
- * one used. Note that round-robin overrides the passed-in vcoreid.
- * Also note this may be 'wrong' if num_vcores changes. */
+ /* Pick a vcore, round-robin style. Assuming ev_vcore was the
+ * previous one used. Note that round-robin overrides the
+ * passed-in vcoreid. Also note this may be 'wrong' if
+ * num_vcores changes. */
vcoreid = (ev_q->ev_vcore + 1) % p->procinfo->num_vcores;
ev_q->ev_vcore = vcoreid;
}
@@ -393,30 +408,32 @@
printk("[kernel] Vcoreid %d unsafe! (too big?)\n", vcoreid);
goto out;
}
- /* If we're a SPAM_PUBLIC, they just want us to spam the message. Note we
- * don't care about the mbox, since it'll go to VCPD public mboxes, and
- * we'll prefer to send it to whatever vcoreid we determined at this point
- * (via APPRO or whatever). */
+ /* If we're a SPAM_PUBLIC, they just want us to spam the message. Note
+ * we don't care about the mbox, since it'll go to VCPD public mboxes,
+ * and we'll prefer to send it to whatever vcoreid we determined at this
+ * point (via APPRO or whatever). */
if (ev_q->ev_flags & EVENT_SPAM_PUBLIC) {
spam_public_msg(p, msg, vcoreid, ev_q->ev_flags);
goto wakeup;
}
/* We aren't spamming and we know the default vcore, and now we need to
- * figure out which mbox to use. If they provided an mbox, we'll use it.
- * If not, we'll use a VCPD mbox (public or private, depending on the
- * flags). */
+ * figure out which mbox to use. If they provided an mbox, we'll use
+ * it. If not, we'll use a VCPD mbox (public or private, depending on
+ * the flags). */
ev_mbox = ev_q->ev_mbox;
if (!ev_mbox)
ev_mbox = get_vcpd_mbox(vcoreid, ev_q->ev_flags);
- /* At this point, we ought to have the right mbox to send the msg to, and
- * which vcore to alert (IPI/INDIR) (if applicable). The mbox could be the
- * vcore's vcpd ev_mbox. */
+ /* At this point, we ought to have the right mbox to send the msg to,
+ * and which vcore to alert (IPI/INDIR) (if applicable). The mbox could
+ * be the vcore's vcpd ev_mbox. */
if (!ev_mbox) {
- /* This shouldn't happen any more, this is more for sanity's sake */
+ /* This shouldn't happen any more, this is more for sanity's
+ * sake */
warn("[kernel] ought to have an mbox by now!");
goto out;
}
- /* Even if we're using an mbox in procdata (VCPD), we want a user pointer */
+ /* Even if we're using an mbox in procdata (VCPD), we want a user
+ * pointer */
if (!is_user_rwaddr(ev_mbox, sizeof(struct event_mbox))) {
/* Ought to kill them, just warn for now */
printk("[kernel] Illegal addr for ev_mbox\n");
diff --git a/kern/src/ex_table.c b/kern/src/ex_table.c
index 079f951..e5054e4 100644
--- a/kern/src/ex_table.c
+++ b/kern/src/ex_table.c
@@ -58,7 +58,8 @@
const struct extable_ip_fixup *last = __stop___ex_table;
while (first <= last) {
- const struct extable_ip_fixup *x = first + ((last - first) >> 1);
+ const struct extable_ip_fixup *x =
+ first + ((last - first) >> 1);
uintptr_t insn = ex_insn_addr(x);
if (insn < xip)
diff --git a/kern/src/fdtap.c b/kern/src/fdtap.c
index 540fc4d..e8edaca 100644
--- a/kern/src/fdtap.c
+++ b/kern/src/fdtap.c
@@ -15,6 +15,7 @@
static void tap_min_release(struct kref *kref)
{
struct fd_tap *tap = container_of(kref, struct fd_tap, kref);
+
cclose(tap->chan);
kfree(tap);
}
@@ -22,6 +23,7 @@
static void tap_full_release(struct kref *kref)
{
struct fd_tap *tap = container_of(kref, struct fd_tap, kref);
+
devtab[tap->chan->type].tapfd(tap->chan, tap, FDTAP_CMD_REM);
tap_min_release(kref);
}
@@ -51,7 +53,8 @@
tap->ev_id = tap_req->ev_id;
tap->data = tap_req->data;
if (!is_user_rwaddr(tap->ev_q, sizeof(struct event_queue))) {
- set_error(EINVAL, "Tap request with bad event_queue %p", tap->ev_q);
+ set_error(EINVAL, "Tap request with bad event_queue %p",
+ tap->ev_q);
kfree(tap);
return -1;
}
@@ -82,35 +85,36 @@
* could come in and close the FD and the chan, once we unlock */
chan_incref(chan);
tap->chan = chan;
- /* One for the FD table, one for us to keep the removal of *this* tap from
- * happening until we've attempted to register with the device. */
+ /* One for the FD table, one for us to keep the removal of *this* tap
+ * from happening until we've attempted to register with the device. */
kref_init(&tap->kref, tap_full_release, 2);
fdt->fd[fd].fd_tap = tap;
- /* As soon as we unlock, another thread can come in and remove our old tap
- * from the table and decref it. Our ref keeps us from removing it yet,
- * as well as keeps the memory safe. However, a new tap can be installed
- * and registered with the device before we even attempt to register. The
- * devices should be able to handle multiple, distinct taps, even if they
- * happen to have the same {proc, fd} tuple. */
+ /* As soon as we unlock, another thread can come in and remove our old
+ * tap from the table and decref it. Our ref keeps us from removing it
+ * yet, as well as keeps the memory safe. However, a new tap can be
+ * installed and registered with the device before we even attempt to
+ * register. The devices should be able to handle multiple, distinct
+ * taps, even if they happen to have the same {proc, fd} tuple. */
spin_unlock(&fdt->lock);
/* For refcnting fans, the tap ref is weak/uncounted. We'll protect the
* memory and call the device when tap is being released. */
ret = devtab[chan->type].tapfd(chan, tap, FDTAP_CMD_ADD);
if (ret) {
- /* we failed, so we need to make sure *our* tap is removed. We haven't
- * decreffed, so we know our tap pointer is unique. */
+ /* we failed, so we need to make sure *our* tap is removed. We
+ * haven't decreffed, so we know our tap pointer is unique. */
spin_lock(&fdt->lock);
if (fdt->fd[fd].fd_tap == tap) {
fdt->fd[fd].fd_tap = 0;
- /* normally we can't decref a tap while holding a lock, but we
- * know we have another reference so this won't trigger a release */
+ /* normally we can't decref a tap while holding a lock,
+ * but we know we have another reference so this won't
+ * trigger a release */
kref_put(&tap->kref);
}
spin_unlock(&fdt->lock);
- /* Regardless of whether someone else removed it or not, *we* are the
- * only ones that know that registration failed and that we shouldn't
- * remove it. Since we still hold a ref, we can change the release
- * method to skip the device dereg. */
+ /* Regardless of whether someone else removed it or not, *we*
+ * are the only ones that know that registration failed and that
+ * we shouldn't remove it. Since we still hold a ref, we can
+ * change the release method to skip the device dereg. */
tap->kref.release = tap_min_release;
}
kref_put(&tap->kref);
@@ -154,16 +158,17 @@
if (!fire_filt)
return 0;
if (waserror()) {
- /* The process owning the tap could trigger a kernel PF, as with any
- * send_event() call. Eventually we'll catch that with waserror. */
- warn("Tap for proc %d, fd %d, threw %s", tap->proc->pid, tap->fd,
- current_errstr());
+ /* The process owning the tap could trigger a kernel PF, as with
+ * any send_event() call. Eventually we'll catch that with
+ * waserror. */
+ warn("Tap for proc %d, fd %d, threw %s", tap->proc->pid,
+ tap->fd, current_errstr());
poperror();
return -1;
}
ev_msg.ev_type = tap->ev_id; /* e.g. CEQ idx */
- ev_msg.ev_arg2 = fire_filt; /* e.g. CEQ coalesce */
- ev_msg.ev_arg3 = tap->data; /* e.g. CEQ data */
+ ev_msg.ev_arg2 = fire_filt; /* e.g. CEQ coalesce */
+ ev_msg.ev_arg3 = tap->data; /* e.g. CEQ data */
send_event(tap->proc, tap->ev_q, &ev_msg, 0);
poperror();
return 0;
diff --git a/kern/src/hashtable.c b/kern/src/hashtable.c
index 1465f2a..73782c4 100644
--- a/kern/src/hashtable.c
+++ b/kern/src/hashtable.c
@@ -7,15 +7,15 @@
* - Merges the iterator code with the main hash table code, mostly to avoid
* externing the hentry cache. */
-#include <ros/common.h>
-#include <hashtable.h>
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-#include <slab.h>
-#include <kmalloc.h>
-#include <hash.h>
#include <arch/types.h>
+#include <assert.h>
+#include <hash.h>
+#include <hashtable.h>
+#include <kmalloc.h>
+#include <ros/common.h>
+#include <slab.h>
+#include <stdio.h>
+#include <string.h>
/*
Credit for primes table: Aaron Krowne
@@ -23,18 +23,13 @@
http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
*/
static const unsigned int primes[] = {
-53, 97, 193, 389,
-769, 1543, 3079, 6151,
-12289, 24593, 49157, 98317,
-196613, 393241, 786433, 1572869,
-3145739, 6291469, 12582917, 25165843,
-50331653, 100663319, 201326611, 402653189,
-805306457, 1610612741
-};
-const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]);
-#define APPLY_MAX_LOAD_FACTOR(size) \
- ((size * 13)/20)
-//const float max_load_factor = 0.65;
+ 53, 97, 193, 389, 769, 1543, 3079,
+ 6151, 12289, 24593, 49157, 98317, 196613, 393241,
+ 786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653,
+ 100663319, 201326611, 402653189, 805306457, 1610612741};
+const unsigned int prime_table_length = sizeof(primes) / sizeof(primes[0]);
+#define APPLY_MAX_LOAD_FACTOR(size) ((size * 13) / 20)
+// const float max_load_factor = 0.65;
struct kmem_cache *hentry_cache;
@@ -59,201 +54,210 @@
}
/*****************************************************************************/
-hashtable_t *
-create_hashtable(size_t minsize,
- size_t (*hashf) (void*),
- ssize_t (*eqf) (void*,void*))
+hashtable_t *create_hashtable(size_t minsize, size_t (*hashf)(void *),
+ ssize_t (*eqf)(void *, void *))
{
- hashtable_t *h;
- size_t pindex, size = primes[0];
- /* Check requested hashtable isn't too large */
- if (minsize > (1u << 30)) return NULL;
- /* Enforce size as prime */
- for (pindex=0; pindex < prime_table_length; pindex++) {
- if (primes[pindex] > minsize) { size = primes[pindex]; break; }
- }
- h = (hashtable_t *)kmalloc(sizeof(hashtable_t), 0);
- if (NULL == h) return NULL; /*oom*/
- h->table = (hash_entry_t **)kmalloc(sizeof(hash_entry_t*) * size, 0);
- if (NULL == h->table) { kfree(h); return NULL; } /*oom*/
- memset(h->table, 0, size * sizeof(hash_entry_t *));
- h->tablelength = size;
- h->primeindex = pindex;
- h->entrycount = 0;
- h->hashfn = hashf;
- h->eqfn = eqf;
- h->loadlimit = APPLY_MAX_LOAD_FACTOR(size);
- return h;
+ hashtable_t *h;
+ size_t pindex, size = primes[0];
+
+ /* Check requested hashtable isn't too large */
+ if (minsize > (1u << 30))
+ return NULL;
+ /* Enforce size as prime */
+ for (pindex = 0; pindex < prime_table_length; pindex++) {
+ if (primes[pindex] > minsize) {
+ size = primes[pindex];
+ break;
+ }
+ }
+ h = (hashtable_t *)kmalloc(sizeof(hashtable_t), 0);
+ if (NULL == h)
+ return NULL; /*oom*/
+ h->table = (hash_entry_t **)kmalloc(sizeof(hash_entry_t *) * size, 0);
+ if (NULL == h->table) {
+ kfree(h);
+ return NULL;
+ } /*oom*/
+ memset(h->table, 0, size * sizeof(hash_entry_t *));
+ h->tablelength = size;
+ h->primeindex = pindex;
+ h->entrycount = 0;
+ h->hashfn = hashf;
+ h->eqfn = eqf;
+ h->loadlimit = APPLY_MAX_LOAD_FACTOR(size);
+ return h;
}
/*****************************************************************************/
-static size_t
-hash(hashtable_t *h, void *k)
+static size_t hash(hashtable_t *h, void *k)
{
- /* Aim to protect against poor hash functions by adding logic here
- * - logic taken from java 1.4 hashtable source */
- size_t i = h->hashfn(k);
- i += ~(i << 9);
- i ^= ((i >> 14) | (i << 18)); /* >>> */
- i += (i << 4);
- i ^= ((i >> 10) | (i << 22)); /* >>> */
- return i;
+ /* Aim to protect against poor hash functions by adding logic here
+ * - logic taken from java 1.4 hashtable source */
+ size_t i = h->hashfn(k);
+
+ i += ~(i << 9);
+ i ^= ((i >> 14) | (i << 18)); /* >>> */
+ i += (i << 4);
+ i ^= ((i >> 10) | (i << 22)); /* >>> */
+ return i;
}
/*****************************************************************************/
-static ssize_t
-hashtable_expand(hashtable_t *h)
+static ssize_t hashtable_expand(hashtable_t *h)
{
- /* Double the size of the table to accomodate more entries */
- hash_entry_t **newtable;
- hash_entry_t *e;
- hash_entry_t **pE;
- size_t newsize, i, index;
- /* Check we're not hitting max capacity */
- if (h->primeindex == (prime_table_length - 1)) return 0;
- newsize = primes[++(h->primeindex)];
+ /* Double the size of the table to accomodate more entries */
+ hash_entry_t **newtable;
+ hash_entry_t *e;
+ hash_entry_t **pE;
+ size_t newsize, i, index;
- newtable = (hash_entry_t **)kmalloc(sizeof(hash_entry_t*) * newsize, 0);
- if (NULL != newtable)
- {
- memset(newtable, 0, newsize * sizeof(hash_entry_t*));
- /* This algorithm is not 'stable'. ie. it reverses the list
- * when it transfers entries between the tables */
- for (i = 0; i < h->tablelength; i++) {
- while (NULL != (e = h->table[i])) {
- h->table[i] = e->next;
- index = indexFor(newsize,e->h);
- e->next = newtable[index];
- newtable[index] = e;
- }
- }
- kfree(h->table);
- h->table = newtable;
- }
- /* Plan B: realloc instead */
- else
- {
- newtable = (hash_entry_t**)
- krealloc(h->table, newsize*sizeof(hash_entry_t*), 0);
- if (NULL == newtable) { (h->primeindex)--; return 0; }
- h->table = newtable;
- memset(newtable[h->tablelength], 0, newsize - h->tablelength);
- for (i = 0; i < h->tablelength; i++) {
- for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
- index = indexFor(newsize,e->h);
- if (index == i)
- {
- pE = &(e->next);
- }
- else
- {
- *pE = e->next;
- e->next = newtable[index];
- newtable[index] = e;
- }
- }
- }
- }
- h->tablelength = newsize;
- h->loadlimit = APPLY_MAX_LOAD_FACTOR(newsize);
- return -1;
+ /* Check we're not hitting max capacity */
+ if (h->primeindex == (prime_table_length - 1))
+ return 0;
+ newsize = primes[++(h->primeindex)];
+
+ newtable =
+ (hash_entry_t **)kmalloc(sizeof(hash_entry_t *) * newsize, 0);
+ if (NULL != newtable) {
+ memset(newtable, 0, newsize * sizeof(hash_entry_t *));
+ /* This algorithm is not 'stable'. ie. it reverses the list
+ * when it transfers entries between the tables */
+ for (i = 0; i < h->tablelength; i++) {
+ while (NULL != (e = h->table[i])) {
+ h->table[i] = e->next;
+ index = indexFor(newsize, e->h);
+ e->next = newtable[index];
+ newtable[index] = e;
+ }
+ }
+ kfree(h->table);
+ h->table = newtable;
+ }
+ /* Plan B: realloc instead */
+ else {
+ newtable = (hash_entry_t **)krealloc(
+ h->table, newsize * sizeof(hash_entry_t *), 0);
+ if (NULL == newtable) {
+ (h->primeindex)--;
+ return 0;
+ }
+ h->table = newtable;
+ memset(newtable[h->tablelength], 0, newsize - h->tablelength);
+ for (i = 0; i < h->tablelength; i++) {
+ for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
+ index = indexFor(newsize, e->h);
+ if (index == i) {
+ pE = &(e->next);
+ } else {
+ *pE = e->next;
+ e->next = newtable[index];
+ newtable[index] = e;
+ }
+ }
+ }
+ }
+ h->tablelength = newsize;
+ h->loadlimit = APPLY_MAX_LOAD_FACTOR(newsize);
+ return -1;
}
/*****************************************************************************/
-size_t
-hashtable_count(hashtable_t *h)
+size_t hashtable_count(hashtable_t *h)
{
- return h->entrycount;
+ return h->entrycount;
}
/*****************************************************************************/
-ssize_t
-hashtable_insert(hashtable_t *h, void *k, void *v)
+ssize_t hashtable_insert(hashtable_t *h, void *k, void *v)
{
- /* This method allows duplicate keys - but they shouldn't be used */
- size_t index;
- hash_entry_t *e;
- if (++(h->entrycount) > h->loadlimit)
- {
- /* Ignore the return value. If expand fails, we should
- * still try cramming just this value into the existing table
- * -- we may not have memory for a larger table, but one more
- * element may be ok. Next time we insert, we'll try expanding again.*/
- hashtable_expand(h);
- }
- e = (hash_entry_t *)kmem_cache_alloc(hentry_cache, 0);
- if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
- e->h = hash(h,k);
- index = indexFor(h->tablelength,e->h);
- e->k = k;
- e->v = v;
- e->next = h->table[index];
- h->table[index] = e;
- return -1;
+ /* This method allows duplicate keys - but they shouldn't be used */
+ size_t index;
+ hash_entry_t *e;
+
+ if (++(h->entrycount) > h->loadlimit) {
+ /* Ignore the return value. If expand fails, we should
+ * still try cramming just this value into the existing table
+ * -- we may not have memory for a larger table, but one more
+ * element may be ok. Next time we insert, we'll try expanding
+ * again.*/
+ hashtable_expand(h);
+ }
+ e = (hash_entry_t *)kmem_cache_alloc(hentry_cache, 0);
+ if (NULL == e) {
+ --(h->entrycount);
+ return 0;
+ } /*oom*/
+ e->h = hash(h, k);
+ index = indexFor(h->tablelength, e->h);
+ e->k = k;
+ e->v = v;
+ e->next = h->table[index];
+ h->table[index] = e;
+ return -1;
}
/*****************************************************************************/
-void * /* returns value associated with key */
-hashtable_search(hashtable_t *h, void *k)
+/* returns value associated with key */
+void *hashtable_search(hashtable_t *h, void *k)
{
- hash_entry_t *e;
- size_t hashvalue, index;
- hashvalue = hash(h,k);
- index = indexFor(h->tablelength,hashvalue);
- e = h->table[index];
- while (NULL != e)
- {
- /* Check hash value to short circuit heavier comparison */
- if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
- e = e->next;
- }
- return NULL;
+ hash_entry_t *e;
+ size_t hashvalue, index;
+
+ hashvalue = hash(h, k);
+ index = indexFor(h->tablelength, hashvalue);
+ e = h->table[index];
+ while (NULL != e) {
+ /* Check hash value to short circuit heavier comparison */
+ if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+ return e->v;
+ e = e->next;
+ }
+ return NULL;
}
/*****************************************************************************/
-void * /* returns value associated with key */
-hashtable_remove(hashtable_t *h, void *k)
+/* returns value associated with key */
+void *hashtable_remove(hashtable_t *h, void *k)
{
- /* TODO: consider compacting the table when the load factor drops enough,
- * or provide a 'compact' method. */
+ /* TODO: consider compacting the table when the load factor drops
+ * enough, or provide a 'compact' method. */
- hash_entry_t *e;
- hash_entry_t **pE;
- void *v;
- size_t hashvalue, index;
+ hash_entry_t *e;
+ hash_entry_t **pE;
+ void *v;
+ size_t hashvalue, index;
- hashvalue = hash(h,k);
- index = indexFor(h->tablelength,hash(h,k));
- pE = &(h->table[index]);
- e = *pE;
- while (NULL != e)
- {
- /* Check hash value to short circuit heavier comparison */
- if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
- {
- *pE = e->next;
- h->entrycount--;
- v = e->v;
+ hashvalue = hash(h, k);
+ index = indexFor(h->tablelength, hash(h, k));
+ pE = &(h->table[index]);
+ e = *pE;
+ while (NULL != e) {
+ /* Check hash value to short circuit heavier comparison */
+ if ((hashvalue == e->h) && (h->eqfn(k, e->k))) {
+ *pE = e->next;
+ h->entrycount--;
+ v = e->v;
kmem_cache_free(hentry_cache, e);
- return v;
- }
- pE = &(e->next);
- e = e->next;
- }
- return NULL;
+ return v;
+ }
+ pE = &(e->next);
+ e = e->next;
+ }
+ return NULL;
}
/*****************************************************************************/
/* destroy */
-void
-hashtable_destroy(hashtable_t *h)
+void hashtable_destroy(hashtable_t *h)
{
if (hashtable_count(h))
- warn("Destroying a non-empty hashtable, clean up after yourself!\n");
+ warn("Destroying a non-empty hashtable, clean up after "
+ "yourself!\n");
- size_t i;
- hash_entry_t *e, *f;
- hash_entry_t **table = h->table;
+ size_t i;
+ hash_entry_t *e, *f;
+ hash_entry_t **table = h->table;
+
for (i = 0; i < h->tablelength; i++) {
e = table[i];
while (NULL != e) {
@@ -262,8 +266,8 @@
kmem_cache_free(hentry_cache, f);
}
}
- kfree(h->table);
- kfree(h);
+ kfree(h->table);
+ kfree(h);
}
/*****************************************************************************/
@@ -272,83 +276,83 @@
*
* If the htable isn't empty, e and index will refer to the first entry. */
-hashtable_itr_t *
-hashtable_iterator(hashtable_t *h)
+hashtable_itr_t *hashtable_iterator(hashtable_t *h)
{
- size_t i, tablelength;
- hashtable_itr_t *itr = (hashtable_itr_t *)
- kmalloc(sizeof(hashtable_itr_t), 0);
- if (NULL == itr) return NULL;
- itr->h = h;
- itr->e = NULL;
- itr->parent = NULL;
- tablelength = h->tablelength;
- itr->index = tablelength;
- if (0 == h->entrycount) return itr;
+ size_t i, tablelength;
+ hashtable_itr_t *itr =
+ (hashtable_itr_t *)kmalloc(sizeof(hashtable_itr_t), 0);
- for (i = 0; i < tablelength; i++)
- {
- if (NULL != h->table[i])
- {
- itr->e = h->table[i];
- itr->index = i;
- break;
- }
- }
- return itr;
+ if (NULL == itr)
+ return NULL;
+ itr->h = h;
+ itr->e = NULL;
+ itr->parent = NULL;
+ tablelength = h->tablelength;
+ itr->index = tablelength;
+ if (0 == h->entrycount)
+ return itr;
+
+ for (i = 0; i < tablelength; i++) {
+ if (NULL != h->table[i]) {
+ itr->e = h->table[i];
+ itr->index = i;
+ break;
+ }
+ }
+ return itr;
}
/*****************************************************************************/
/* key - return the key of the (key,value) pair at the current position */
-/* value - return the value of the (key,value) pair at the current position */
+/* value - return the value of the (key,value) pair at the current position
+ */
-void *
-hashtable_iterator_key(hashtable_itr_t *i)
-{ return i->e->k; }
+void *hashtable_iterator_key(hashtable_itr_t *i)
+{
+ return i->e->k;
+}
-void *
-hashtable_iterator_value(hashtable_itr_t *i)
-{ return i->e->v; }
+void *hashtable_iterator_value(hashtable_itr_t *i)
+{
+ return i->e->v;
+}
/*****************************************************************************/
/* advance - advance the iterator to the next element
* returns zero if advanced to end of table */
-ssize_t
-hashtable_iterator_advance(hashtable_itr_t *itr)
+ssize_t hashtable_iterator_advance(hashtable_itr_t *itr)
{
- size_t j,tablelength;
- hash_entry_t **table;
- hash_entry_t *next;
- if (NULL == itr->e) return 0; /* stupidity check */
+ size_t j, tablelength;
+ hash_entry_t **table;
+ hash_entry_t *next;
- next = itr->e->next;
- if (NULL != next)
- {
- itr->parent = itr->e;
- itr->e = next;
- return -1;
- }
- tablelength = itr->h->tablelength;
- itr->parent = NULL;
- if (tablelength <= (j = ++(itr->index)))
- {
- itr->e = NULL;
- return 0;
- }
- table = itr->h->table;
- while (NULL == (next = table[j]))
- {
- if (++j >= tablelength)
- {
- itr->index = tablelength;
- itr->e = NULL;
- return 0;
- }
- }
- itr->index = j;
- itr->e = next;
- return -1;
+ if (NULL == itr->e)
+ return 0; /* stupidity check */
+
+ next = itr->e->next;
+ if (NULL != next) {
+ itr->parent = itr->e;
+ itr->e = next;
+ return -1;
+ }
+ tablelength = itr->h->tablelength;
+ itr->parent = NULL;
+ if (tablelength <= (j = ++(itr->index))) {
+ itr->e = NULL;
+ return 0;
+ }
+ table = itr->h->table;
+ while (NULL == (next = table[j])) {
+ if (++j >= tablelength) {
+ itr->index = tablelength;
+ itr->e = NULL;
+ return 0;
+ }
+ }
+ itr->index = j;
+ itr->e = next;
+ return -1;
}
/*****************************************************************************/
@@ -359,66 +363,63 @@
* beware memory leaks if you don't.
* Returns zero if end of iteration. */
-ssize_t
-hashtable_iterator_remove(hashtable_itr_t *itr)
+ssize_t hashtable_iterator_remove(hashtable_itr_t *itr)
{
- hash_entry_t *remember_e, *remember_parent;
- ssize_t ret;
+ hash_entry_t *remember_e, *remember_parent;
+ ssize_t ret;
- /* Do the removal */
- if (NULL == (itr->parent))
- {
- /* element is head of a chain */
- itr->h->table[itr->index] = itr->e->next;
- } else {
- /* element is mid-chain */
- itr->parent->next = itr->e->next;
- }
- /* itr->e is now outside the hashtable */
- remember_e = itr->e;
- itr->h->entrycount--;
+ /* Do the removal */
+ if (NULL == (itr->parent)) {
+ /* element is head of a chain */
+ itr->h->table[itr->index] = itr->e->next;
+ } else {
+ /* element is mid-chain */
+ itr->parent->next = itr->e->next;
+ }
+ /* itr->e is now outside the hashtable */
+ remember_e = itr->e;
+ itr->h->entrycount--;
- /* Advance the iterator, correcting the parent */
- remember_parent = itr->parent;
- ret = hashtable_iterator_advance(itr);
- if (itr->parent == remember_e) { itr->parent = remember_parent; }
+ /* Advance the iterator, correcting the parent */
+ remember_parent = itr->parent;
+ ret = hashtable_iterator_advance(itr);
+ if (itr->parent == remember_e) {
+ itr->parent = remember_parent;
+ }
kmem_cache_free(hentry_cache, remember_e);
- return ret;
+ return ret;
}
/*****************************************************************************/
-ssize_t /* returns zero if not found */
-hashtable_iterator_search(hashtable_itr_t *itr,
- hashtable_t *h, void *k)
+/* returns zero if not found */
+ssize_t hashtable_iterator_search(hashtable_itr_t *itr, hashtable_t *h, void *k)
{
- hash_entry_t *e, *parent;
- size_t hashvalue, index;
+ hash_entry_t *e, *parent;
+ size_t hashvalue, index;
- hashvalue = hash(h,k);
- index = indexFor(h->tablelength,hashvalue);
+ hashvalue = hash(h, k);
+ index = indexFor(h->tablelength, hashvalue);
- e = h->table[index];
- parent = NULL;
- while (NULL != e)
- {
- /* Check hash value to short circuit heavier comparison */
- if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
- {
- itr->index = index;
- itr->e = e;
- itr->parent = parent;
- itr->h = h;
- return -1;
- }
- parent = e;
- e = e->next;
- }
- return 0;
+ e = h->table[index];
+ parent = NULL;
+ while (NULL != e) {
+ /* Check hash value to short circuit heavier comparison */
+ if ((hashvalue == e->h) && (h->eqfn(k, e->k))) {
+ itr->index = index;
+ itr->e = e;
+ itr->parent = parent;
+ itr->h = h;
+ return -1;
+ }
+ parent = e;
+ e = e->next;
+ }
+ return 0;
}
/* Runs func on each member of the hash table */
void hash_for_each(struct hashtable *hash, void func(void *, void *),
- void *opaque)
+ void *opaque)
{
if (hashtable_count(hash)) {
struct hashtable_itr *iter = hashtable_iterator(hash);
@@ -433,7 +434,7 @@
/* Runs func on each member of the hash table, removing the item after
* processing it. Make sure func frees the item, o/w you'll leak. */
void hash_for_each_remove(struct hashtable *hash, void func(void *, void *),
- void *opaque)
+ void *opaque)
{
if (hashtable_count(hash)) {
struct hashtable_itr *iter = hashtable_iterator(hash);
@@ -476,4 +477,4 @@
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
+ */
diff --git a/kern/src/hexdump.c b/kern/src/hexdump.c
index 547979a..19493c4 100644
--- a/kern/src/hexdump.c
+++ b/kern/src/hexdump.c
@@ -57,7 +57,8 @@
printk(" %02x", m[i + j]);
printk(" ");
for (j = 0; j < 16; j++)
- printk("%c", isprint(m[i + j]) ? m[i + j] : '.');
+ printk("%c", isprint(m[i + j]) ? m[i + j] :
+ '.');
printk("\n");
} else if (all_zero == 2) {
printk("...\n");
@@ -82,14 +83,15 @@
if (buflen < 1)
return ret;
buf[ret++] = '\'';
- /* we want 2 bytes left in the buf (which is ret < buflen - 1), one for the
- * char, and one for the \' after the loop. */
+ /* we want 2 bytes left in the buf (which is ret < buflen - 1), one for
+ * the char, and one for the \' after the loop. */
while (ix < numprint && ret < (buflen - 1)) {
if (isprint(data[ix])) {
buf[ret++] = data[ix];
} else if (ret < buflen - 4) {
/* guarantee there is room for a \xxx sequence */
- ret += snprintf(&buf[ret], buflen-ret, "\\%03o", data[ix]);
+ ret += snprintf(&buf[ret], buflen-ret, "\\%03o",
+ data[ix]);
} else {
break;
}
diff --git a/kern/src/init.c b/kern/src/init.c
index 01aeb02..e9030fc 100644
--- a/kern/src/init.c
+++ b/kern/src/init.c
@@ -41,13 +41,13 @@
#define MAX_BOOT_CMDLINE_SIZE 4096
-#define ASSIGN_PTRVAL(prm, top, val) \
- do { \
- if (prm && (prm < top)) { \
- *prm = val; \
- prm++; \
- } \
- } while (0)
+#define ASSIGN_PTRVAL(prm, top, val) \
+do { \
+ if (prm && (prm < top)) { \
+ *prm = val; \
+ prm++; \
+ } \
+} while (0)
bool booting = TRUE;
struct proc_global_info __proc_global_info;
@@ -58,7 +58,7 @@
static int run_init_script(void);
const char *get_boot_option(const char *base, const char *option, char *param,
- size_t max_param)
+ size_t max_param)
{
size_t optlen = strlen(option);
char *ptop = param + max_param - 1;
@@ -103,10 +103,9 @@
if (mbi && (mbi->flags & MULTIBOOT_INFO_CMDLINE) && mbi->cmdline) {
const char *cmdln = (const char *) KADDR(mbi->cmdline);
- /* We need to copy the command line in a permanent buffer, since the
- * multiboot memory where it is currently residing will be part of the
- * free boot memory later on in the boot process.
- */
+ /* We need to copy the command line in a permanent buffer, since
+ * the multiboot memory where it is currently residing will be
+ * part of the free boot memory later on in the boot process. */
strlcpy(boot_cmdline, cmdln, sizeof(boot_cmdline));
}
}
@@ -118,10 +117,10 @@
extern char __start_bss[], __stop_bss[];
memset(__start_bss, 0, __stop_bss - __start_bss);
- /* mboot_info is a physical address. while some arches currently have the
- * lower memory mapped, everyone should have it mapped at kernbase by now.
- * also, it might be in 'free' memory, so once we start dynamically using
- * memory, we may clobber it. */
+ /* mboot_info is a physical address. while some arches currently have
+ * the lower memory mapped, everyone should have it mapped at kernbase
+ * by now. also, it might be in 'free' memory, so once we start
+ * dynamically using memory, we may clobber it. */
multiboot_kaddr = (struct multiboot_info*)((physaddr_t)mboot_info
+ KERNBASE);
extract_multiboot_cmdline(multiboot_kaddr);
@@ -141,7 +140,7 @@
acpiinit();
topology_init();
percpu_init();
- kthread_init(); /* might need to tweak when this happens */
+ kthread_init(); /* might need to tweak when this happens */
vmr_init();
page_check();
idt_init();
@@ -158,8 +157,8 @@
rcu_init();
enable_irq();
run_linker_funcs();
- /* reset/init devtab after linker funcs 3 and 4. these run NIC and medium
- * pre-inits, which need to happen before devether. */
+ /* reset/init devtab after linker funcs 3 and 4. these run NIC and
+ * medium pre-inits, which need to happen before devether. */
devtabreset();
devtabinit();
@@ -171,7 +170,7 @@
#ifdef CONFIG_RUN_INIT_SCRIPT
if (run_init_script()) {
- printk("Configured to run init script, but no script specified!\n");
+ printk("Told to run init script, but no script specified\n");
manager();
}
#else
@@ -187,7 +186,8 @@
int vargs = 0;
char *sptr = &CONFIG_INIT_SCRIPT_PATH_AND_ARGS[0];
- /* Figure out how many arguments there are, by finding the spaces */
+ /* Figure out how many arguments there are, by finding the
+ * spaces */
/* TODO: consider rewriting this stuff with parsecmd */
while (*sptr != '\0') {
if (*(sptr++) != ' ') {
@@ -197,8 +197,8 @@
}
}
- /* Initialize l_argv with its first three arguments, but allocate space
- * for all arguments as calculated above */
+ /* Initialize l_argv with its first three arguments, but
+ * allocate space for all arguments as calculated above */
int static_args = 2;
int total_args = vargs + static_args;
char *l_argv[total_args];
@@ -207,6 +207,7 @@
/* Initialize l_argv with the rest of the arguments */
int i = static_args;
+
sptr = &CONFIG_INIT_SCRIPT_PATH_AND_ARGS[0];
while (*sptr != '\0') {
if (*sptr != ' ') {
@@ -272,26 +273,29 @@
}
printk("\n");
- /* If we're here, we panicked and currently hold the print_lock. We might
- * have panicked recursively. We must unlock unconditionally, since the
- * initial panic (which grabbed the lock) will never run again. */
+ /* If we're here, we panicked and currently hold the print_lock. We
+ * might have panicked recursively. We must unlock unconditionally,
+ * since the initial panic (which grabbed the lock) will never run
+ * again. */
panic_printing = false;
print_unlock_force();
/* And we have to clear the depth, so that we lock again next time in.
- * Otherwise, we'd be unlocking without locking (which is another panic). */
+ * Otherwise, we'd be unlocking without locking (which is another
+ * panic). */
PERCPU_VAR(panic_depth) = 0;
- /* Let's wait long enough for other printers to finish before entering the
- * monitor. */
+ /* Let's wait long enough for other printers to finish before entering
+ * the monitor. */
do {
udelay(500000);
cmb();
} while (panic_printing);
/* Yikes! We're claiming to be not in IRQ/trap ctx and not holding any
- * locks. Obviously we could be wrong, and could easily deadlock. We could
- * be in an IRQ handler, an unhandled kernel fault, or just a 'normal' panic
- * in a syscall - any of which can involve unrestore invariants. */
+ * locks. Obviously we could be wrong, and could easily deadlock. We
+ * could be in an IRQ handler, an unhandled kernel fault, or just a
+ * 'normal' panic in a syscall - any of which can involve unrestore
+ * invariants. */
pcpui->__ctx_depth = 0;
pcpui->lock_depth = 0;
/* And keep this off, for good measure. */
@@ -327,8 +331,8 @@
static void run_links(linker_func_t *linkstart, linker_func_t *linkend)
{
/* Unlike with devtab, our linker sections for the function pointers are
- * 8 byte aligned (4 on 32 bit) (done by the linker/compiler), so we don't
- * have to worry about that. */
+ * 8 byte aligned (4 on 32 bit) (done by the linker/compiler), so we
+ * don't have to worry about that. */
printd("linkstart %p, linkend %p\n", linkstart, linkend);
for (int i = 0; &linkstart[i] < linkend; i++) {
printd("i %d, linkfunc %p\n", i, linkstart[i]);
diff --git a/kern/src/kdebug.c b/kern/src/kdebug.c
index d320144..5a16a44 100644
--- a/kern/src/kdebug.c
+++ b/kern/src/kdebug.c
@@ -19,9 +19,10 @@
{
struct symtab_entry *i, *prev = 0, *found = 0;
- /* Table is in ascending order. As soon as we get to an entry greater than
- * us, we were in the previous one. This is only true if we were given a
- * good PC. Random addresses will just find the previous symbol. */
+ /* Table is in ascending order. As soon as we get to an entry greater
+ * than us, we were in the previous one. This is only true if we were
+ * given a good PC. Random addresses will just find the previous
+ * symbol. */
for (i = &gbl_symtab[0]; i->name; i++) {
if (i->addr > pc) {
found = prev;
@@ -38,6 +39,7 @@
uintptr_t get_symbol_addr(char *sym)
{
struct symtab_entry *i;
+
for (i = &gbl_symtab[0]; i->name; i++) {
if (strcmp(i->name, sym) == 0)
return i->addr;
@@ -106,7 +108,8 @@
if (is_ktask(pcpui->cur_kthread)) {
printk("%10s:", pcpui->cur_kthread->name);
} else {
- printk("PID %3d :", pcpui->cur_proc ? pcpui->cur_proc->pid : 0);
+ printk("PID %3d :", pcpui->cur_proc ?
+ pcpui->cur_proc->pid : 0);
}
}
}
@@ -149,21 +152,22 @@
void set_printx(int mode)
{
switch (mode) {
- case 0:
- printx_on = FALSE;
- break;
- case 1:
- printx_on = TRUE;
- break;
- case 2:
- printx_on = !printx_on;
- break;
+ case 0:
+ printx_on = FALSE;
+ break;
+ case 1:
+ printx_on = TRUE;
+ break;
+ case 2:
+ printx_on = !printx_on;
+ break;
}
}
void debug_addr_proc(struct proc *p, unsigned long addr)
{
struct vm_region *vmr;
+
spin_lock(&p->vmr_lock);
TAILQ_FOREACH(vmr, &p->vm_regions, vm_link) {
if ((vmr->vm_base <= addr) && (addr < vmr->vm_end))
@@ -198,8 +202,10 @@
#define BT_FMT "#%02d [<%p>] in %s\n"
-void print_backtrace_list(uintptr_t *pcs, size_t nr_pcs,
- void (*pfunc)(void *, const char *), void *opaque)
+void print_backtrace_list(uintptr_t *pcs, size_t nr_pcs, void (*pfunc)(void *,
+ const
+ char *),
+ void *opaque)
{
char bt_line[128];
@@ -274,7 +280,8 @@
void backtrace_user_frame(uintptr_t eip, uintptr_t ebp)
{
uintptr_t pcs[MAX_BT_DEPTH];
- /* TODO: this assumes we have the user's address space loaded (current). */
+ /* TODO: this assumes we have the user's address space loaded (current).
+ */
size_t nr_pcs = backtrace_user_list(eip, ebp, pcs, MAX_BT_DEPTH);
print_lock();
@@ -283,7 +290,7 @@
/* This formatting is consumed by scripts/bt-akaros.sh. */
for (int i = 0; i < nr_pcs; i++) {
printk("#%02d ", i + 1);
- /* TODO: user backtraces all assume we're working on 'current' */
+ /* TODO: user backtraces all assume we're working on 'current'*/
debug_addr_proc(current, pcs[i]);
}
print_unlock();
diff --git a/kern/src/kmalloc.c b/kern/src/kmalloc.c
index 7581fbd..9ac859b 100644
--- a/kern/src/kmalloc.c
+++ b/kern/src/kmalloc.c
@@ -27,17 +27,19 @@
{
char kc_name[KMC_NAME_SZ];
- /* we want at least a 16 byte alignment of the tag so that the bufs kmalloc
- * returns are 16 byte aligned. we used to check the actual size == 16,
- * since we adjusted the KMALLOC_SMALLEST based on that. */
+ /* we want at least a 16 byte alignment of the tag so that the bufs
+ * kmalloc returns are 16 byte aligned. we used to check the actual
+ * size == 16, since we adjusted the KMALLOC_SMALLEST based on that. */
static_assert(ALIGNED(sizeof(struct kmalloc_tag), 16));
- /* build caches of common sizes. this size will later include the tag and
- * the actual returned buffer. */
+ /* build caches of common sizes. this size will later include the tag
+ * and the actual returned buffer. */
size_t ksize = KMALLOC_SMALLEST;
+
for (int i = 0; i < NUM_KMALLOC_CACHES; i++) {
snprintf(kc_name, KMC_NAME_SZ, "kmalloc_%d", ksize);
- kmalloc_caches[i] = kmem_cache_create(kc_name, ksize, KMALLOC_ALIGNMENT,
- 0, NULL, 0, 0, NULL);
+ kmalloc_caches[i] = kmem_cache_create(kc_name, ksize,
+ KMALLOC_ALIGNMENT, 0,
+ NULL, 0, 0, NULL);
ksize <<= 1;
}
}
@@ -55,9 +57,10 @@
cache_id = LOG2_UP(ksize) - LOG2_UP(KMALLOC_SMALLEST);
// if we don't have a cache to handle it, alloc cont pages
if (cache_id >= NUM_KMALLOC_CACHES) {
- /* The arena allocator will round up too, but we want to know in advance
- * so that krealloc can avoid extra allocations. */
- size_t amt_alloc = ROUNDUP(size + sizeof(struct kmalloc_tag), PGSIZE);
+ /* The arena allocator will round up too, but we want to know in
+ * advance so that krealloc can avoid extra allocations. */
+ size_t amt_alloc = ROUNDUP(size + sizeof(struct kmalloc_tag),
+ PGSIZE);
buf = kpages_alloc(amt_alloc, flags);
if (!buf)
@@ -86,6 +89,7 @@
void *kzmalloc(size_t size, int flags)
{
void *v = kmalloc(size, flags);
+
if (!v)
return v;
memset(v, 0, size);
@@ -96,11 +100,12 @@
{
void *addr, *retaddr;
int *tag_flags, offset;
- /* alignment requests must be a multiple of long, even though we only need
- * int in the current code. */
+
+ /* alignment requests must be a multiple of long, even though we only
+ * need int in the current code. */
assert(ALIGNED(align, sizeof(long)));
- /* must fit in the space reserved for the offset amount, which is at most
- * 'align'. */
+ /* must fit in the space reserved for the offset amount, which is at
+ * most 'align'. */
assert(align < (1 << (32 - KMALLOC_ALIGN_SHIFT)));
assert(IS_PWR2(align));
addr = kmalloc(size + align, flags);
@@ -111,8 +116,8 @@
retaddr = ROUNDUP(addr, align);
offset = retaddr - addr;
assert(offset < align);
- /* we might not have room for a full tag. we might have only 8 bytes. but
- * we'll at least have room for the flags part. */
+ /* we might not have room for a full tag. we might have only 8 bytes.
+ * but we'll at least have room for the flags part. */
tag_flags = (int*)(retaddr - sizeof(int));
*tag_flags = (offset << KMALLOC_ALIGN_SHIFT) | KMALLOC_TAG_UNALIGN;
return retaddr;
@@ -121,6 +126,7 @@
void *kzmalloc_align(size_t size, int flags, size_t align)
{
void *v = kmalloc_align(size, flags, align);
+
if (!v)
return v;
memset(v, 0, size);
@@ -129,10 +135,10 @@
static struct kmalloc_tag *__get_km_tag(void *buf)
{
- struct kmalloc_tag *tag = (struct kmalloc_tag*)(buf -
- sizeof(struct kmalloc_tag));
+ struct kmalloc_tag *tag =
+ (struct kmalloc_tag*)(buf - sizeof(struct kmalloc_tag));
if (tag->canary != KMALLOC_CANARY){
- printk("__get_km_tag bad canary: %08lx@%p, buf %p, expected %08lx\n",
+ printk("kmalloc bad canary: %08lx@%p, buf %p, expected %08lx\n",
tag->canary, &tag->canary, buf, KMALLOC_CANARY);
hexdump((void *)(buf - sizeof(struct kmalloc_tag)), 256);
panic("Bad canary");
@@ -148,6 +154,7 @@
static void *__get_unaligned_orig_buf(void *buf)
{
int *tag_flags = (int*)(buf - sizeof(int));
+
if ((*tag_flags & KMALLOC_FLAG_MASK) == KMALLOC_TAG_UNALIGN)
return (buf - (*tag_flags >> KMALLOC_ALIGN_SHIFT));
else
@@ -164,11 +171,13 @@
if (__get_unaligned_orig_buf(buf))
panic("krealloc of a kmalloc_align not supported");
tag = __get_km_tag(buf);
- /* whatever we got from either a slab or the page allocator is meant for
- * both the buf+size as well as the kmalloc tag */
+ /* whatever we got from either a slab or the page allocator is
+ * meant for both the buf+size as well as the kmalloc tag */
if ((tag->flags & KMALLOC_FLAG_MASK) == KMALLOC_TAG_CACHE) {
- osize = tag->my_cache->obj_size - sizeof(struct kmalloc_tag);
- } else if ((tag->flags & KMALLOC_FLAG_MASK) == KMALLOC_TAG_PAGES) {
+ osize = tag->my_cache->obj_size
+ - sizeof(struct kmalloc_tag);
+ } else if ((tag->flags & KMALLOC_FLAG_MASK)
+ == KMALLOC_TAG_PAGES) {
osize = tag->amt_alloc - sizeof(struct kmalloc_tag);
} else {
panic("Probably a bad tag, flags %p\n", tag->flags);
@@ -202,15 +211,17 @@
void kmalloc_incref(void *buf)
{
void *orig_buf = __get_unaligned_orig_buf(buf);
+
buf = orig_buf ? orig_buf : buf;
- /* if we want a smaller tag, we can extract the code from kref and manually
- * set the release method in kfree. */
+ /* if we want a smaller tag, we can extract the code from kref and
+ * manually set the release method in kfree. */
kref_get(&__get_km_tag(buf)->kref, 1);
}
int kmalloc_refcnt(void *buf)
{
void *orig_buf = __get_unaligned_orig_buf(buf);
+
buf = orig_buf ? orig_buf : buf;
return kref_refcnt(&__get_km_tag(buf)->kref);
}
@@ -218,6 +229,7 @@
static void __kfree_release(struct kref *kref)
{
struct kmalloc_tag *tag = container_of(kref, struct kmalloc_tag, kref);
+
if ((tag->flags & KMALLOC_FLAG_MASK) == KMALLOC_TAG_CACHE)
kmem_cache_free(tag->my_cache, tag);
else if ((tag->flags & KMALLOC_FLAG_MASK) == KMALLOC_TAG_PAGES)
@@ -238,10 +250,11 @@
void kmalloc_canary_check(char *str)
{
+ struct kmalloc_tag *tag;
+
if (!debug_canary)
return;
- struct kmalloc_tag *tag = (struct kmalloc_tag*)(debug_canary -
- sizeof(struct kmalloc_tag));
+ tag = (struct kmalloc_tag*)(debug_canary - sizeof(struct kmalloc_tag));
if (tag->canary != KMALLOC_CANARY)
panic("\t\t KMALLOC CANARY CHECK FAILED %s\n", str);
}
diff --git a/kern/src/ktest/ktest.c b/kern/src/ktest/ktest.c
index 1b3c683..d485d7c 100644
--- a/kern/src/ktest/ktest.c
+++ b/kern/src/ktest/ktest.c
@@ -17,6 +17,7 @@
void run_registered_ktest_suites()
{
struct ktest_suite *suite = NULL;
+
SLIST_FOREACH(suite, &ktest_suiteq, link) {
run_ktest_suite(suite);
}
@@ -34,12 +35,14 @@
uint64_t end = read_tsc();
uint64_t et_us = tsc2usec(end - start) % 1000000;
uint64_t et_s = tsc2sec(end - start);
-
char fmt[] = "\t%s [%s](%llu.%06llus) %s\n";
+
if (result) {
- printk(fmt, "PASSED", test->name, et_s, et_us, "");
+ printk(fmt, "PASSED", test->name, et_s, et_us,
+ "");
} else {
- printk(fmt, "FAILED", test->name, et_s, et_us, ktest_msg);
+ printk(fmt, "FAILED", test->name, et_s, et_us,
+ ktest_msg);
}
/* Some older tests disable IRQs */
enable_irq();
@@ -50,4 +53,3 @@
printk("<-- END_KERNEL_%s_TESTS -->\n", suite->name);
}
-
diff --git a/kern/src/ktest/net_ktests.c b/kern/src/ktest/net_ktests.c
index ca33079..19ef811 100644
--- a/kern/src/ktest/net_ktests.c
+++ b/kern/src/ktest/net_ktests.c
@@ -81,9 +81,9 @@
}
static struct ktest ktests[] = {
- KTEST_REG(ptclbsum, CONFIG_TEST_ptclbsum),
- KTEST_REG(simplesum_bench, CONFIG_TEST_simplesum_bench),
- KTEST_REG(ptclbsum_bench, CONFIG_TEST_ptclbsum_bench),
+ KTEST_REG(ptclbsum, CONFIG_TEST_ptclbsum),
+ KTEST_REG(simplesum_bench, CONFIG_TEST_simplesum_bench),
+ KTEST_REG(ptclbsum_bench, CONFIG_TEST_ptclbsum_bench),
};
static int num_ktests = sizeof(ktests) / sizeof(struct ktest);
diff --git a/kern/src/ktest/pb_ktests.c b/kern/src/ktest/pb_ktests.c
index 397a759..9049d16 100644
--- a/kern/src/ktest/pb_ktests.c
+++ b/kern/src/ktest/pb_ktests.c
@@ -122,7 +122,7 @@
{
cprintf("Core 0 initializing barrier\n");
init_barrier(&test_cpu_array, num_cores);
- cprintf("Core 0 asking all cores to print ids, barrier, rinse, repeat\n");
+ printk("Core 0 asking all cores to print ids, barrier, etc\n");
smp_call_function_all(test_barrier_handler, NULL, 0);
return true;
@@ -133,6 +133,7 @@
bool test_interrupts_irqsave(void)
{
int8_t state = 0;
+
printd("Testing Nesting Enabling first, turning ints off:\n");
disable_irq();
printd("Interrupts are: %x\n", irq_is_enabled());
@@ -319,12 +320,14 @@
bool test_smp_call_functions(void)
{
int i;
+
atomic_init(&a, 0);
atomic_init(&b, 0);
atomic_init(&c, 0);
- handler_wrapper_t *waiter0 = 0, *waiter1 = 0, *waiter2 = 0, *waiter3 = 0,
- *waiter4 = 0, *waiter5 = 0;
+ handler_wrapper_t *waiter0 = 0, *waiter1 = 0, *waiter2 = 0,
+ *waiter3 = 0, *waiter4 = 0, *waiter5 = 0;
uint8_t me = core_id();
+
printk("\nCore %d: SMP Call Self (nowait):\n", me);
printk("---------------------\n");
smp_call_function_self(test_hello_world_handler, NULL, 0);
@@ -339,7 +342,8 @@
printk("---------------------\n");
smp_call_function_all(test_hello_world_handler, NULL, &waiter0);
smp_call_wait(waiter0);
- printk("\nCore %d: SMP Call All-Else Individually, in order (nowait):\n", me);
+ printk("\nCore %d: SMP Call All-Else Individually, in order (nowait):\n",
+ me);
printk("---------------------\n");
for(i = 1; i < num_cores; i++)
smp_call_function_single(i, test_hello_world_handler, NULL, 0);
@@ -347,36 +351,49 @@
printk("---------------------\n");
smp_call_function_self(test_hello_world_handler, NULL, &waiter0);
smp_call_wait(waiter0);
- printk("\nCore %d: SMP Call All-Else Individually, in order (wait):\n", me);
+ printk("\nCore %d: SMP Call All-Else Individually, in order (wait):\n",
+ me);
printk("---------------------\n");
for(i = 1; i < num_cores; i++)
{
- smp_call_function_single(i, test_hello_world_handler, NULL, &waiter0);
+ smp_call_function_single(i, test_hello_world_handler, NULL,
+ &waiter0);
smp_call_wait(waiter0);
}
printk("\nTesting to see if any IPI-functions are dropped when not waiting:\n");
- printk("A: %d, B: %d, C: %d (should be 0,0,0)\n", atomic_read(&a), atomic_read(&b), atomic_read(&c));
+ printk("A: %d, B: %d, C: %d (should be 0,0,0)\n", atomic_read(&a),
+ atomic_read(&b), atomic_read(&c));
smp_call_function_all(test_incrementer_handler, &a, 0);
smp_call_function_all(test_incrementer_handler, &b, 0);
smp_call_function_all(test_incrementer_handler, &c, 0);
// if i can clobber a previous IPI, the interleaving might do it
- smp_call_function_single(1 % num_cores, test_incrementer_handler, &a, 0);
- smp_call_function_single(2 % num_cores, test_incrementer_handler, &b, 0);
- smp_call_function_single(3 % num_cores, test_incrementer_handler, &c, 0);
- smp_call_function_single(4 % num_cores, test_incrementer_handler, &a, 0);
- smp_call_function_single(5 % num_cores, test_incrementer_handler, &b, 0);
- smp_call_function_single(6 % num_cores, test_incrementer_handler, &c, 0);
+ smp_call_function_single(1 % num_cores, test_incrementer_handler, &a,
+ 0);
+ smp_call_function_single(2 % num_cores, test_incrementer_handler, &b,
+ 0);
+ smp_call_function_single(3 % num_cores, test_incrementer_handler, &c,
+ 0);
+ smp_call_function_single(4 % num_cores, test_incrementer_handler, &a,
+ 0);
+ smp_call_function_single(5 % num_cores, test_incrementer_handler, &b,
+ 0);
+ smp_call_function_single(6 % num_cores, test_incrementer_handler, &c,
+ 0);
smp_call_function_all(test_incrementer_handler, &a, 0);
- smp_call_function_single(3 % num_cores, test_incrementer_handler, &c, 0);
+ smp_call_function_single(3 % num_cores, test_incrementer_handler, &c,
+ 0);
smp_call_function_all(test_incrementer_handler, &b, 0);
- smp_call_function_single(1 % num_cores, test_incrementer_handler, &a, 0);
+ smp_call_function_single(1 % num_cores, test_incrementer_handler, &a,
+ 0);
smp_call_function_all(test_incrementer_handler, &c, 0);
- smp_call_function_single(2 % num_cores, test_incrementer_handler, &b, 0);
+ smp_call_function_single(2 % num_cores, test_incrementer_handler, &b,
+ 0);
// wait, so we're sure the others finish before printing.
// without this, we could (and did) get 19,18,19, since the B_inc
// handler didn't finish yet
smp_call_function_self(test_null_handler, NULL, &waiter0);
- // need to grab all 5 handlers (max), since the code moves to the next free.
+ // need to grab all 5 handlers (max), since the code moves to the next
+ // free.
smp_call_function_self(test_null_handler, NULL, &waiter1);
smp_call_function_self(test_null_handler, NULL, &waiter2);
smp_call_function_self(test_null_handler, NULL, &waiter3);
@@ -386,7 +403,8 @@
smp_call_wait(waiter2);
smp_call_wait(waiter3);
smp_call_wait(waiter4);
- printk("A: %d, B: %d, C: %d (should be 19,19,19)\n", atomic_read(&a), atomic_read(&b), atomic_read(&c));
+ printk("A: %d, B: %d, C: %d (should be 19,19,19)\n", atomic_read(&a),
+ atomic_read(&b), atomic_read(&c));
printk("Attempting to deadlock by smp_calling with an outstanding wait:\n");
smp_call_function_self(test_null_handler, NULL, &waiter0);
printk("Sent one\n");
@@ -441,7 +459,8 @@
udelay(5000000);
printk("IPIs received (should be %d): %d\n", a, NUM_IPI);
// KT_ASSERT_M("IPIs received should be 100000", (NUM_IPI == a));
- // hopefully that handler never fires again. leaving it registered for now.
+ // hopefully that handler never fires again. leaving it registered for
+ // now.
return true;
}
@@ -517,7 +536,8 @@
for (int i = 0; i < 5; i++) {
FOR_CIRC_BUFFER(i, 5, j)
- printk("Starting with current = %d, each value = %d\n", i, j);
+ printk("Starting with current = %d, each value = %d\n",
+ i, j);
}
return true;
@@ -587,7 +607,7 @@
KT_ASSERT_M("It should be possible to insert items to a hashtable",
hashtable_insert(h, (void*)k, v));
v = NULL;
- KT_ASSERT_M("It should be possible to find inserted stuff in a hashtable",
+ KT_ASSERT_M("should be possible to find inserted stuff in a hashtable",
(v = hashtable_search(h, (void*)k)));
KT_ASSERT_M("The extracted element should be the same we inserted",
@@ -595,10 +615,10 @@
v = NULL;
- KT_ASSERT_M("It should be possible to remove an existing element",
+ KT_ASSERT_M("should be possible to remove an existing element",
(v = hashtable_remove(h, (void*)k)));
- KT_ASSERT_M("An element should not remain in a hashtable after deletion",
+ KT_ASSERT_M("element should not remain in a hashtable after deletion",
!(v = hashtable_search(h, (void*)k)));
/* Testing a bunch of items, insert, search, and removal */
@@ -697,10 +717,11 @@
size_t len = snprintf(buf, sizeof(buf), "%lu\n", i);
KT_ASSERT_M("Circular buffer write failed",
- circular_buffer_write(&cb, buf, len) == len);
+ circular_buffer_write(&cb, buf, len) == len);
}
cnum = off = 0;
- while ((csize = circular_buffer_read(&cb, buf, sizeof(buf), off)) != 0) {
+ while ((csize = circular_buffer_read(&cb, buf, sizeof(buf), off)) != 0)
+ {
char *top = buf + csize;
char *ptr = buf;
char *pnl;
@@ -722,11 +743,12 @@
memset(buf, (int) i, sizeof(buf));
KT_ASSERT_M("Circular buffer write failed",
- circular_buffer_write(&cb, buf,
- sizeof(buf)) == sizeof(buf));
+ circular_buffer_write(&cb, buf, sizeof(buf)) ==
+ sizeof(buf));
}
cnum = off = 0;
- while ((csize = circular_buffer_read(&cb, buf, sizeof(buf), off)) != 0) {
+ while ((csize = circular_buffer_read(&cb, buf, sizeof(buf), off)) != 0)
+ {
size_t num = buf[0];
KT_ASSERT_M("Invalid record read size", csize == sizeof(buf));
@@ -743,7 +765,7 @@
mxsize = circular_buffer_max_write_size(&cb);
KT_ASSERT_M("Circular buffer max write failed",
- circular_buffer_write(&cb, bigbuf, mxsize) == mxsize);
+ circular_buffer_write(&cb, bigbuf, mxsize) == mxsize);
memset(bigbuf, 17, cbsize);
csize = circular_buffer_read(&cb, bigbuf, mxsize, 0);
@@ -867,13 +889,14 @@
printk("Running the alarm handler!\n");
printk("NR msg per page: %d\n", NR_MSG_PER_PAGE);
- /* might not be mmaped yet, if not, abort. We used to user_mem_check,
- * but now we just touch it and PF. */
+ /* might not be mmaped yet, if not, abort. We used to
+ * user_mem_check, but now we just touch it and PF. */
char touch = *(char*)ucq;
asm volatile ("" : : "r"(touch));
/* load their address space */
old_proc = switch_to(p);
- /* So it's mmaped, see if it is ready (note that this is dangerous) */
+ /* So it's mmaped, see if it is ready (note that this is
+ * dangerous) */
if (!ucq->ucq_ready) {
printk("Not ready yet\n");
switch_back(p, old_proc);
@@ -887,8 +910,8 @@
msg.ev_arg2 = 0xdeadbeef;
send_ucq_msg(ucq, p, &msg);
printk("nr_pages: %d\n", atomic_read(&ucq->nr_extra_pgs));
- /* 2: Send a bunch. In a VM, this causes one swap, and then a bunch of
- * mmaps. */
+ /* 2: Send a bunch. In a VM, this causes one swap, and then a
+ * bunch of mmaps. */
printk("[kernel] #2 \n");
for (int i = 0; i < 5000; i++) {
msg.ev_type = i;
@@ -904,7 +927,8 @@
printk("nr_pages: %d\n", atomic_read(&ucq->nr_extra_pgs));
/* other things we could do:
* - concurrent producers / consumers... ugh.
- * - would require a kmsg to another core, instead of a local alarm
+ * - would require a kmsg to another core, instead of a local
+ * alarm
*/
/* done, switch back and free things */
switch_back(p, old_proc);
@@ -930,14 +954,15 @@
program);
struct proc *p = proc_create(program, NULL, NULL);
+
proc_wakeup(p);
- /* instead of getting rid of the reference created in proc_create, we'll put
- * it in the awaiter */
+ /* instead of getting rid of the reference created in proc_create, we'll
+ * put it in the awaiter */
waiter->data = p;
foc_decref(program);
- /* Should never return from schedule (env_pop in there) also note you may
- * not get the process you created, in the event there are others floating
- * around that are runnable */
+ /* Should never return from schedule (env_pop in there) also note you
+ * may not get the process you created, in the event there are others
+ * floating around that are runnable */
run_scheduler();
smp_idle();
@@ -968,10 +993,11 @@
bool test_kthreads(void)
{
struct semaphore sem = SEMAPHORE_INITIALIZER(sem, 1);
+
printk("We're a kthread! Stacktop is %p. Testing suspend, etc...\n",
get_stack_top());
- /* So we have something that will wake us up. Routine messages won't get
- * serviced in the kernel right away. */
+ /* So we have something that will wake us up. Routine messages won't
+ * get serviced in the kernel right away. */
send_kernel_message(core_id(), __test_up_sem, (long)&sem, 0, 0,
KMSG_ROUTINE);
/* Actually block (or try to) */
@@ -1183,7 +1209,8 @@
for (int i = 0; i < nr_msgs; i++) {
int cpu = (i % (num_cores - 1)) + 1;
if (atomic_read(&counter) % 5)
- send_kernel_message(cpu, __test_cv_waiter, 0, 0, 0, KMSG_ROUTINE);
+ send_kernel_message(cpu, __test_cv_waiter, 0, 0, 0,
+ KMSG_ROUTINE);
else
send_kernel_message(cpu, __test_cv_signal, 0, 0, 0, KMSG_ROUTINE);
}
@@ -1192,31 +1219,35 @@
cpu_relax();
cv_broadcast(cv);
udelay(1000000);
- kthread_yield(); /* run whatever messages we sent to ourselves */
+ kthread_yield();/* run whatever messages we sent to ourselves */
}
KT_ASSERT(!cv->nr_waiters);
printk("test_cv: massive message storm complete\n");
- /* Test 3: basic one signaller, one receiver. we want to vary the amount of
- * time the sender and receiver delays, starting with (1ms, 0ms) and ending
- * with (0ms, 1ms). At each extreme, such as with the sender waiting 1ms,
- * the receiver/waiter should hit the "check and wait" point well before the
- * sender/signaller hits the "change state and signal" point. */
+ /* Test 3: basic one signaller, one receiver. we want to vary the
+ * amount of time the sender and receiver delays, starting with (1ms,
+ * 0ms) and ending with (0ms, 1ms). At each extreme, such as with the
+ * sender waiting 1ms, the receiver/waiter should hit the "check and
+ * wait" point well before the sender/signaller hits the "change state
+ * and signal" point. */
for (int i = 0; i < 1000; i++) {
- for (int j = 0; j < 10; j++) { /* some extra chances at each point */
+ /* some extra chances at each point */
+ for (int j = 0; j < 10; j++) {
state = FALSE;
- atomic_init(&counter, 1); /* signal that the client is done */
+ /* signal that the client is done */
+ atomic_init(&counter, 1);
/* client waits for i usec */
- send_kernel_message(2, __test_cv_waiter_t3, i, 0, 0, KMSG_ROUTINE);
+ send_kernel_message(2, __test_cv_waiter_t3, i, 0, 0,
+ KMSG_ROUTINE);
cmb();
udelay(1000 - i); /* senders wait time: 1000..0 */
state = TRUE;
cv_signal(cv);
/* signal might have unblocked a kthread, let it run */
kthread_yield();
- /* they might not have run at all yet (in which case they lost the
- * race and don't need the signal). but we need to wait til they're
- * done */
+ /* they might not have run at all yet (in which case
+ * they lost the race and don't need the signal). but
+ * we need to wait til they're done */
while (atomic_read(&counter))
cpu_relax();
KT_ASSERT(!cv->nr_waiters);
@@ -1244,8 +1275,8 @@
#define ASSRT_SIZE 64
char *assrt_msg = (char*) kmalloc(ASSRT_SIZE, 0);
snprintf(assrt_msg, ASSRT_SIZE,
- "Char %d is %c (%02x), should be %c (%02x)", i, *c, *c,
- x, x);
+ "Char %d is %c (%02x), should be %c (%02x)", i,
+ *c, *c, x, x);
KT_ASSERT_M(assrt_msg, (*c == x));
c++;
}
@@ -1285,17 +1316,17 @@
}
// TODO: Add assertions.
-bool test_setjmp()
+bool test_setjmp(void)
{
struct jmpbuf jb;
printk("Starting: %s\n", __FUNCTION__);
if (setjmp(&jb)) {
printk("After second setjmp return: %s\n", __FUNCTION__);
- }
- else {
- printk("After first setjmp return: %s\n", __FUNCTION__);
- __longjmp_wrapper(&jb);
- }
+ }
+ else {
+ printk("After first setjmp return: %s\n", __FUNCTION__);
+ __longjmp_wrapper(&jb);
+ }
printk("Exiting: %s\n", __FUNCTION__);
return true;
@@ -1326,10 +1357,13 @@
for (int i = 0; i < MAX_BATCH + 1; i++) {
count_todo = i;
while (count_todo) {
- ret = apipe_write(&test_pipe, &local_str, count_todo);
- /* Shouldn't break, based on the loop counters */
+ ret = apipe_write(&test_pipe, &local_str,
+ count_todo);
+ /* Shouldn't break, based on the loop counters
+ */
if (!ret) {
- printk("Writer breaking with %d left\n", count_todo);
+ printk("Writer breaking with %d left\n",
+ count_todo);
break;
}
total += ret;
@@ -1349,9 +1383,11 @@
for (int i = MAX_BATCH; i >= 0; i--) {
count_todo = i;
while (count_todo) {
- ret = apipe_read(&test_pipe, &local_str, count_todo);
+ ret = apipe_read(&test_pipe, &local_str,
+ count_todo);
if (!ret) {
- printk("Reader breaking with %d left\n", count_todo);
+ printk("Reader breaking with %d left\n",
+ count_todo);
break;
}
total += ret;
@@ -1391,8 +1427,8 @@
send_kernel_message(1, __test_apipe_writer, 0, 0, 0, KMSG_ROUTINE);
__test_apipe_reader(0, 0, 0, 0);
/* We could be on core 1 now. If we were called from core0, our caller
- * might expect us to return while being on core 0 (like if we were kfunc'd
- * from the monitor. Be careful if you copy this code. */
+ * might expect us to return while being on core 0 (like if we were
+ * kfunc'd from the monitor. Be careful if you copy this code. */
return true;
}
@@ -1420,20 +1456,20 @@
int rand = read_tsc() & 0xff;
for (int i = 0; i < 10000; i++) {
switch ((rand * i) % 5) {
- case 0:
- case 1:
- rlock(rwl);
+ case 0:
+ case 1:
+ rlock(rwl);
+ runlock(rwl);
+ break;
+ case 2:
+ case 3:
+ if (canrlock(rwl))
runlock(rwl);
- break;
- case 2:
- case 3:
- if (canrlock(rwl))
- runlock(rwl);
- break;
- case 4:
- wlock(rwl);
- wunlock(rwl);
- break;
+ break;
+ case 4:
+ wlock(rwl);
+ wunlock(rwl);
+ break;
}
}
/* signal to allow core 0 to finish */
@@ -1444,7 +1480,8 @@
atomic_init(&rwlock_counter, (num_cores - 1) * 4);
for (int i = 1; i < num_cores; i++)
for (int j = 0; j < 4; j++)
- send_kernel_message(i, __test_rwlock, 0, 0, 0, KMSG_ROUTINE);
+ send_kernel_message(i, __test_rwlock, 0, 0, 0,
+ KMSG_ROUTINE);
while (atomic_read(&rwlock_counter))
cpu_relax();
printk("rwlock test complete\n");
@@ -1500,7 +1537,8 @@
atomic_init(&counter, nr_msgs);
state = FALSE;
for (int i = 1; i < num_cores; i++)
- send_kernel_message(i, __test_rv_sleeper, 0, 0, 0, KMSG_ROUTINE);
+ send_kernel_message(i, __test_rv_sleeper, 0, 0, 0,
+ KMSG_ROUTINE);
udelay(1000000);
cmb();
state = TRUE;
@@ -1518,12 +1556,15 @@
atomic_init(&counter, nr_msgs);
for (int i = 0; i < nr_msgs; i++) {
int cpu = (i % (num_cores - 1)) + 1;
- /* timeouts from 0ms ..5000ms (enough that they should wake via cond */
+
+ /* timeouts from 0ms ..5000ms (enough that they should wake via
+ * cond */
if (atomic_read(&counter) % 5)
- send_kernel_message(cpu, __test_rv_sleeper_timeout, i * 4000, 0, 0,
- KMSG_ROUTINE);
+ send_kernel_message(cpu, __test_rv_sleeper_timeout, i *
+ 4000, 0, 0, KMSG_ROUTINE);
else
- send_kernel_message(cpu, __test_rv_sleeper, 0, 0, 0, KMSG_ROUTINE);
+ send_kernel_message(cpu, __test_rv_sleeper, 0, 0, 0,
+ KMSG_ROUTINE);
}
kthread_yield(); /* run whatever messages we sent to ourselves */
state = TRUE;
@@ -1531,7 +1572,7 @@
cpu_relax();
rendez_wakeup(rv);
udelay(1000000);
- kthread_yield(); /* run whatever messages we sent to ourselves */
+ kthread_yield();/* run whatever messages we sent to ourselves */
}
KT_ASSERT(!rv->cv.nr_waiters);
printk("test_rv: lots of sleepers/timeouts complete\n");
@@ -1609,8 +1650,8 @@
KT_ASSERT(!__get_unaligned_orig_buf(b1));
b1tag = (struct kmalloc_tag*)(b1 - sizeof(struct kmalloc_tag));
- /* realigned case. alloc'd before b1's test, so we know we get different
- * buffers. */
+ /* realigned case. alloc'd before b1's test, so we know we get
+ * different buffers. */
b2 = kmalloc_align(55, 0, 64);
b2o = __get_unaligned_orig_buf(b2);
KT_ASSERT(b2o);
@@ -1648,8 +1689,8 @@
t[i] = p;
}
numalloc = i;
- // free them at random. With luck, we don't get too many duplicate
- // hits.
+ // free them at random. With luck, we don't get too many
+ // duplicate hits.
for (y = i = 0; i < numalloc; y++) {
/* could read genrand, but that could be offline */
int f = (uint16_t)read_tsc() % numalloc;
@@ -1764,38 +1805,36 @@
static bool uaccess_unmapped(void *addr, char *buf, char *buf2)
{
KT_ASSERT_M("Copy to user (u8) to not mapped address should fail",
- copy_to_user(addr, buf, 1) == -EFAULT);
+ copy_to_user(addr, buf, 1) == -EFAULT);
KT_ASSERT_M("Copy to user (u16) to not mapped address should fail",
- copy_to_user(addr, buf, 2) == -EFAULT);
+ copy_to_user(addr, buf, 2) == -EFAULT);
KT_ASSERT_M("Copy to user (u32) to not mapped address should fail",
- copy_to_user(addr, buf, 4) == -EFAULT);
+ copy_to_user(addr, buf, 4) == -EFAULT);
KT_ASSERT_M("Copy to user (u64) to not mapped address should fail",
- copy_to_user(addr, buf, 8) == -EFAULT);
+ copy_to_user(addr, buf, 8) == -EFAULT);
KT_ASSERT_M("Copy to user (mem) to not mapped address should fail",
- copy_to_user(addr, buf, sizeof(buf)) == -EFAULT);
+ copy_to_user(addr, buf, sizeof(buf)) == -EFAULT);
KT_ASSERT_M("Copy from user (u8) to not mapped address should fail",
- copy_from_user(buf, addr, 1) == -EFAULT);
+ copy_from_user(buf, addr, 1) == -EFAULT);
KT_ASSERT_M("Copy from user (u16) to not mapped address should fail",
- copy_from_user(buf, addr, 2) == -EFAULT);
+ copy_from_user(buf, addr, 2) == -EFAULT);
KT_ASSERT_M("Copy from user (u32) to not mapped address should fail",
- copy_from_user(buf, addr, 4) == -EFAULT);
+ copy_from_user(buf, addr, 4) == -EFAULT);
KT_ASSERT_M("Copy from user (u64) to not mapped address should fail",
- copy_from_user(buf, addr, 8) == -EFAULT);
+ copy_from_user(buf, addr, 8) == -EFAULT);
KT_ASSERT_M("Copy from user (mem) to not mapped address should fail",
- copy_from_user(buf, addr, sizeof(buf)) == -EFAULT);
+ copy_from_user(buf, addr, sizeof(buf)) == -EFAULT);
- KT_ASSERT_M(
- "String copy to user to not mapped address should fail",
- strcpy_to_user(NULL, addr, "Akaros") == -EFAULT);
- KT_ASSERT_M(
- "String copy from user to not mapped address should fail",
- strcpy_from_user(NULL, buf, addr) == -EFAULT);
+ KT_ASSERT_M("String copy to user to not mapped address should fail",
+ strcpy_to_user(NULL, addr, "Akaros") == -EFAULT);
+ KT_ASSERT_M("String copy from user to not mapped address should fail",
+ strcpy_from_user(NULL, buf, addr) == -EFAULT);
KT_ASSERT_M("Copy from user with kernel side source pointer should fail",
- copy_from_user(buf, buf2, sizeof(buf)) == -EFAULT);
+ copy_from_user(buf, buf2, sizeof(buf)) == -EFAULT);
KT_ASSERT_M("Copy to user with kernel side source pointer should fail",
- copy_to_user(buf, buf2, sizeof(buf)) == -EFAULT);
+ copy_to_user(buf, buf2, sizeof(buf)) == -EFAULT);
return TRUE;
}
@@ -1813,10 +1852,12 @@
err = proc_alloc(&tmp, 0, 0);
KT_ASSERT_M("Failed to alloc a temp proc", err == 0);
- /* Tell everyone we're ready in case some ops don't work on PROC_CREATED */
+ /* Tell everyone we're ready in case some ops don't work on PROC_CREATED
+ */
__proc_set_state(tmp, PROC_RUNNABLE_S);
switch_tmp = switch_to(tmp);
- addr = mmap(tmp, 0, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, -1, 0);
+ addr = mmap(tmp, 0, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, -1,
+ 0);
if (addr == MAP_FAILED)
goto out;
passed = uaccess_mapped(addr, buf, buf2);
@@ -1875,17 +1916,17 @@
const char *opt;
char param[128];
- /* Note that the get_boot_option() API should be passed NULL the first time
- * it is called, in normal cases, and should be passed the value returned by
- * previous call to get_boot_option(), in case multiple options with same
- * name have to be fetched.
- */
+ /* Note that the get_boot_option() API should be passed NULL the first
+ * time it is called, in normal cases, and should be passed the value
+ * returned by previous call to get_boot_option(), in case multiple
+ * options with same name have to be fetched. */
opt = get_boot_option(fake_cmdline, "-root", param, sizeof(param));
KT_ASSERT_M("Unable to parse -root option", opt);
KT_ASSERT_M("Invalid -root option value", strcmp(param, "/foo") == 0);
opt = get_boot_option(fake_cmdline, "-root", NULL, 0);
- KT_ASSERT_M("Unable to parse -root option when param not provided", opt);
+ KT_ASSERT_M("Unable to parse -root option when param not provided",
+ opt);
opt = get_boot_option(fake_cmdline, "-simple", param, sizeof(param));
KT_ASSERT_M("Unable to parse -simple option", opt);
@@ -1897,11 +1938,13 @@
opt = get_boot_option(fake_cmdline, "-quoted", param, sizeof(param));
KT_ASSERT_M("Unable to parse -quoted option", opt);
- KT_ASSERT_M("Invalid -quoted option value", strcmp(param, "abc '") == 0);
+ KT_ASSERT_M("Invalid -quoted option value", strcmp(param, "abc '") ==
+ 0);
opt = get_boot_option(fake_cmdline, "-dup", param, sizeof(param));
KT_ASSERT_M("Unable to parse -dup option", opt);
- KT_ASSERT_M("Invalid -dup option first value", strcmp(param, "311") == 0);
+ KT_ASSERT_M("Invalid -dup option first value", strcmp(param, "311") ==
+ 0);
opt = get_boot_option(opt, "-dup", param, sizeof(param));
KT_ASSERT_M("Unable to parse -dup option", opt);
@@ -1910,7 +1953,8 @@
opt = get_boot_option(fake_cmdline, "-inner", param, sizeof(param));
KT_ASSERT_M("Unable to parse -inner option", opt);
- KT_ASSERT_M("Invalid -inner option value", strcmp(param, "-outer") == 0);
+ KT_ASSERT_M("Invalid -inner option value", strcmp(param, "-outer") ==
+ 0);
opt = get_boot_option(opt, "-inner", param, sizeof(param));
KT_ASSERT_M("Should not be parsing -inner as value", !opt);
@@ -1955,8 +1999,9 @@
KT_ASSERT(__pcpu_ptr_is_dyn(u64));
KT_ASSERT(__pcpu_ptr_is_dyn(u32));
- /* The order here is a bit hokey too - the first alloc is usually 16 byte
- * aligned, so if we did a packed alloc, the u64 wouldn't be aligned. */
+ /* The order here is a bit hokey too - the first alloc is usually 16
+ * byte aligned, so if we did a packed alloc, the u64 wouldn't be
+ * aligned. */
KT_ASSERT(ALIGNED(u8, __alignof__(*u8)));
KT_ASSERT(ALIGNED(u64, __alignof__(*u64)));
KT_ASSERT(ALIGNED(u32, __alignof__(*u32)));
@@ -1968,8 +2013,8 @@
_PERCPU_VAR(*u64, i) = i;
for_each_core(i)
KT_ASSERT(_PERCPU_VAR(*u64, i) == i);
- /* If we free and realloc, we're likely to get the same one. This is due
- * to the ARENA_BESTFIT policy with xalloc. */
+ /* If we free and realloc, we're likely to get the same one. This is
+ * due to the ARENA_BESTFIT policy with xalloc. */
old_u64 = u64;
percpu_free(u64);
u64 = percpu_zalloc(uint64_t, MEM_WAIT);
@@ -2003,8 +2048,8 @@
atomic_set(&check_in, num_cores);
for_each_core(i)
- send_kernel_message(i, __inc_foo, (long)foos, (long)&check_in, 0,
- KMSG_IMMEDIATE);
+ send_kernel_message(i, __inc_foo, (long)foos, (long)&check_in,
+ 0, KMSG_IMMEDIATE);
while (atomic_read(&check_in))
cpu_relax();
for_each_core(i)
diff --git a/kern/src/kthread.c b/kern/src/kthread.c
index 394a9ba..ca4b726 100644
--- a/kern/src/kthread.c
+++ b/kern/src/kthread.c
@@ -30,10 +30,10 @@
if (!stackbot)
return -1;
if (map_vmap_segment((uintptr_t)blob, 0x123456000, KSTACK_NR_GUARD_PGS,
- PTE_NONE))
+ PTE_NONE))
goto error;
if (map_vmap_segment((uintptr_t)blob + KSTACK_GUARD_SZ, PADDR(stackbot),
- KSTKSIZE / PGSIZE, PTE_KERN_RW))
+ KSTKSIZE / PGSIZE, PTE_KERN_RW))
goto error;
return 0;
error:
@@ -90,14 +90,15 @@
__alignof__(struct kthread), 0,
NULL, 0, 0, NULL);
kstack_cache = kmem_cache_create("kstack", KSTKSIZE + KSTACK_GUARD_SZ,
- PGSIZE, 0, vmap_arena, kstack_ctor,
- kstack_dtor, NULL);
+ PGSIZE, 0, vmap_arena, kstack_ctor,
+ kstack_dtor, NULL);
}
/* Used by early init routines (smp_boot, etc) */
struct kthread *__kthread_zalloc(void)
{
struct kthread *kthread;
+
kthread = kmem_cache_alloc(kthread_kcache, 0);
assert(kthread);
memset(kthread, 0, sizeof(struct kthread));
@@ -132,10 +133,11 @@
/* Avoid messy complications. The kthread will enable_irqsave() when it
* comes back up. */
disable_irq();
- /* Free any spare, since we need the current to become the spare. Without
- * the spare, we can't free our current kthread/stack (we could free the
- * kthread, but not the stack, since we're still on it). And we can't free
- * anything after popping kthread, since we never return. */
+ /* Free any spare, since we need the current to become the spare.
+ * Without the spare, we can't free our current kthread/stack (we could
+ * free the kthread, but not the stack, since we're still on it). And
+ * we can't free anything after popping kthread, since we never return.
+ * */
if (pcpui->spare) {
put_kstack(pcpui->spare->stacktop);
kmem_cache_free(kthread_kcache, pcpui->spare);
@@ -148,26 +150,31 @@
/* When a kthread runs, its stack is the default kernel stack */
set_stack_top(kthread->stacktop);
pcpui->cur_kthread = kthread;
- /* Only change current if we need to (the kthread was in process context) */
+ /* Only change current if we need to (the kthread was in process
+ * context) */
if (kthread->proc) {
if (kthread->proc == pcpui->cur_proc) {
- /* We're already loaded, but we do need to drop the extra ref stored
- * in kthread->proc. */
+ /* We're already loaded, but we do need to drop the
+ * extra ref stored in kthread->proc. */
proc_decref(kthread->proc);
kthread->proc = 0;
} else {
- /* Load our page tables before potentially decreffing cur_proc.
+ /* Load our page tables before potentially decreffing
+ * cur_proc.
*
- * We don't need to do an EPT flush here. The EPT is flushed and
- * managed in sync with the VMCS. We won't run a different VM (and
- * thus *need* a different EPT) without first removing the old GPC,
- * which ultimately will result in a flushed EPT (on x86, this
- * actually happens when we clear_owning_proc()). */
+ * We don't need to do an EPT flush here. The EPT is
+ * flushed and managed in sync with the VMCS. We won't
+ * run a different VM (and thus *need* a different EPT)
+ * without first removing the old GPC, which ultimately
+ * will result in a flushed EPT (on x86, this actually
+ * happens when we clear_owning_proc()). */
lcr3(kthread->proc->env_cr3);
- /* Might have to clear out an existing current. If they need to be
- * set later (like in restartcore), it'll be done on demand. */
+ /* Might have to clear out an existing current. If they
+ * need to be set later (like in restartcore), it'll be
+ * done on demand. */
old_proc = pcpui->cur_proc;
- /* Transfer our counted ref from kthread->proc to cur_proc. */
+ /* Transfer our counted ref from kthread->proc to
+ * cur_proc. */
pcpui->cur_proc = kthread->proc;
kthread->proc = 0;
if (old_proc)
@@ -187,19 +194,20 @@
struct proc *cur_proc = pcpui->cur_proc;
if (pcpui->owning_proc && pcpui->owning_proc != kthread->proc) {
- /* Some process should be running here that is not the same as the
- * kthread. This means the _M is getting interrupted or otherwise
- * delayed. If we want to do something other than run it (like send the
- * kmsg to another pcore, or ship the context from here to somewhere
- * else/deschedule it (like for an _S)), do it here.
+ /* Some process should be running here that is not the same as
+ * the kthread. This means the _M is getting interrupted or
+ * otherwise delayed. If we want to do something other than run
+ * it (like send the kmsg to another pcore, or ship the context
+ * from here to somewhere else/deschedule it (like for an _S)),
+ * do it here.
*
- * If you want to do something here, call out to the ksched, then
- * abandon_core(). */
+ * If you want to do something here, call out to the ksched,
+ * then abandon_core(). */
cmb(); /* do nothing/placeholder */
}
- /* o/w, just run the kthread. any trapframes that are supposed to run or
- * were interrupted will run whenever the kthread smp_idles() or otherwise
- * finishes. */
+ /* o/w, just run the kthread. any trapframes that are supposed to run
+ * or were interrupted will run whenever the kthread smp_idles() or
+ * otherwise finishes. */
restart_kthread(kthread);
assert(0);
}
@@ -237,6 +245,7 @@
void kthread_yield(void)
{
struct semaphore local_sem, *sem = &local_sem;
+
sem_init(sem, 0);
run_as_rkm(sem_up, sem);
sem_down(sem);
@@ -245,7 +254,8 @@
void kthread_usleep(uint64_t usec)
{
ERRSTACK(1);
- /* TODO: classic ksched issue: where do we want the wake up to happen? */
+ /* TODO: classic ksched issue: where do we want the wake up to happen?
+ */
struct timer_chain *tchain = &per_cpu_info[core_id()].tchain;
struct rendez rv;
@@ -269,10 +279,11 @@
void *arg = (void*)a1;
char *name = (char*)a2;
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+
assert(is_ktask(pcpui->cur_kthread));
pcpui->cur_kthread->name = name;
- /* There are some rendezs out there that aren't wrapped. Though no one can
- * abort them. Yet. */
+ /* There are some rendezs out there that aren't wrapped. Though no one
+ * can abort them. Yet. */
if (waserror()) {
printk("Ktask %s threw error %s\n", name, current_errstr());
goto out;
@@ -356,7 +367,8 @@
struct per_cpu_info *pcpui = this_pcpui_ptr();
assert(can_block(pcpui));
- /* Make sure we aren't holding any locks (only works if SPINLOCK_DEBUG) */
+ /* Make sure we aren't holding any locks (only works if SPINLOCK_DEBUG)
+ */
if (pcpui->lock_depth > nr_locks)
panic("Kthread tried to sleep, with lockdepth %d\n", pcpui->lock_depth);
@@ -369,7 +381,8 @@
struct per_cpu_info *pcpui = this_pcpui_ptr();
assert(pcpui->cur_kthread);
- /* We're probably going to sleep, so get ready. We'll check again later. */
+ /* We're probably going to sleep, so get ready. We'll check again
+ * later. */
kthread = pcpui->cur_kthread;
/* We need to have a spare slot for restart, so we also use it when
* sleeping. Right now, we need a new kthread to take over if/when our
@@ -381,10 +394,11 @@
new_kthread = pcpui->spare;
new_stacktop = new_kthread->stacktop;
pcpui->spare = 0;
- /* The old flags could have KTH_IS_KTASK set. The reason is that the
- * launching of blocked kthreads also uses PRKM, and that KMSG
- * (__launch_kthread) doesn't return. Thus the soon-to-be spare
- * kthread, that is launching another, has flags & KTH_IS_KTASK set. */
+ /* The old flags could have KTH_IS_KTASK set. The reason is
+ * that the launching of blocked kthreads also uses PRKM, and
+ * that KMSG (__launch_kthread) doesn't return. Thus the
+ * soon-to-be spare kthread, that is launching another, has
+ * flags & KTH_IS_KTASK set. */
new_kthread->flags = KTH_DEFAULT_FLAGS;
new_kthread->proc = 0;
new_kthread->name = 0;
@@ -397,20 +411,21 @@
/* Set the core's new default stack and kthread */
set_stack_top(new_stacktop);
pcpui->cur_kthread = new_kthread;
- /* Kthreads that are ktasks are not related to any process, and do not need
- * to work in a process's address space. They can operate in any address
- * space that has the kernel mapped (like boot_pgdir, or any pgdir). Some
- * ktasks may switch_to, at which point they do care about the address
- * space and must maintain a reference.
+ /* Kthreads that are ktasks are not related to any process, and do not
+ * need to work in a process's address space. They can operate in any
+ * address space that has the kernel mapped (like boot_pgdir, or any
+ * pgdir). Some ktasks may switch_to, at which point they do care about
+ * the address space and must maintain a reference.
*
- * Normal kthreads need to stay in the process context, but we want the core
- * (which could be a vcore) to stay in the context too. */
+ * Normal kthreads need to stay in the process context, but we want the
+ * core (which could be a vcore) to stay in the context too. */
if ((kthread->flags & KTH_SAVE_ADDR_SPACE) && current) {
kthread->proc = current;
- /* In the future, we could check owning_proc. If it isn't set, we could
- * clear current and transfer the refcnt to kthread->proc. If so, we'll
- * need to reset the cr3 to something (boot_cr3 or owning_proc's cr3),
- * which might not be worth the potentially excessive TLB flush. */
+ /* In the future, we could check owning_proc. If it isn't set,
+ * we could clear current and transfer the refcnt to
+ * kthread->proc. If so, we'll need to reset the cr3 to
+ * something (boot_cr3 or owning_proc's cr3), which might not be
+ * worth the potentially excessive TLB flush. */
proc_incref(kthread->proc, 1);
} else {
assert(kthread->proc == 0);
@@ -445,8 +460,8 @@
pre_block_check(0);
- /* Try to down the semaphore. If there is a signal there, we can skip all
- * of the sleep prep and just return. */
+ /* Try to down the semaphore. If there is a signal there, we can skip
+ * all of the sleep prep and just return. */
#ifdef CONFIG_SEM_SPINWAIT
for (int i = 0; i < CONFIG_SEM_SPINWAIT_NR_LOOPS; i++) {
if (sem_trydown(sem))
@@ -467,13 +482,14 @@
if (sem->nr_signals < 0) {
TAILQ_INSERT_TAIL(&sem->waiters, kthread, link);
db_blocked_kth(&sem->db);
- /* At this point, we know we'll sleep and change stacks. Once we unlock
- * the sem, we could have the kthread restarted (possibly on another
- * core), so we need to leave the old stack before unlocking. If we
- * don't and we stay on the stack, then if we take an IRQ or NMI (NMI
- * that doesn't change stacks, unlike x86_64), we'll be using the stack
- * at the same time as the kthread. We could just disable IRQs, but
- * that wouldn't protect us from NMIs that don't change stacks. */
+ /* At this point, we know we'll sleep and change stacks. Once
+ * we unlock the sem, we could have the kthread restarted
+ * (possibly on another core), so we need to leave the old stack
+ * before unlocking. If we don't and we stay on the stack, then
+ * if we take an IRQ or NMI (NMI that doesn't change stacks,
+ * unlike x86_64), we'll be using the stack at the same time as
+ * the kthread. We could just disable IRQs, but that wouldn't
+ * protect us from NMIs that don't change stacks. */
__reset_stack_pointer(sem, current_kthread->stacktop,
__sem_unlock_and_idle);
assert(0);
@@ -484,24 +500,25 @@
block_return_path:
printd("[kernel] Returning from being 'blocked'! at %llu\n", read_tsc());
- /* restart_kthread and longjmp did not reenable IRQs. We need to make sure
- * irqs are on if they were on when we started to block. If they were
- * already on and we short-circuited the block, it's harmless to reenable
- * them. */
+ /* restart_kthread and longjmp did not reenable IRQs. We need to make
+ * sure irqs are on if they were on when we started to block. If they
+ * were already on and we short-circuited the block, it's harmless to
+ * reenable them. */
if (irqs_were_on)
enable_irq();
}
void sem_down_bulk(struct semaphore *sem, int nr_signals)
{
- /* This is far from ideal. Our current sem code expects a 1:1 pairing of
- * signals to waiters. For instance, if we have 10 waiters of -1 each or 1
- * waiter of -10, we can't tell from looking at the overall structure. We'd
- * need to track the desired number of signals per waiter.
+ /* This is far from ideal. Our current sem code expects a 1:1 pairing
+ * of signals to waiters. For instance, if we have 10 waiters of -1
+ * each or 1 waiter of -10, we can't tell from looking at the overall
+ * structure. We'd need to track the desired number of signals per
+ * waiter.
*
* Note that if there are a bunch of signals available, sem_down will
- * quickly do a try_down and return, so we won't block repeatedly. But if
- * we do block, we could wake up N times. */
+ * quickly do a try_down and return, so we won't block repeatedly. But
+ * if we do block, we could wake up N times. */
for (int i = 0; i < nr_signals; i++)
sem_down(sem);
}
@@ -525,9 +542,10 @@
assert(TAILQ_EMPTY(&sem->waiters));
}
spin_unlock(&sem->lock);
- /* Note that once we call kthread_runnable(), we cannot touch the sem again.
- * Some sems are on stacks. The caller can touch sem, if it knows about the
- * memory/usage of the sem. Likewise, we can't touch the kthread either. */
+ /* Note that once we call kthread_runnable(), we cannot touch the sem
+ * again. Some sems are on stacks. The caller can touch sem, if it
+ * knows about the memory/usage of the sem. Likewise, we can't touch
+ * the kthread either. */
if (kthread) {
kthread_runnable(kthread);
return TRUE;
@@ -876,14 +894,18 @@
static void __abort_and_release_cle(struct cv_lookup_elm *cle)
{
int8_t irq_state = 0;
- /* At this point, we have a handle on the syscall that we want to abort (via
- * the cle), and we know none of the memory will disappear on us (deregers
- * wait on the flag). So we'll signal ABORT, which rendez will pick up next
- * time it is awake. Then we make sure it is awake with a broadcast. */
+
+ /* At this point, we have a handle on the syscall that we want to abort
+ * (via the cle), and we know none of the memory will disappear on us
+ * (deregers wait on the flag). So we'll signal ABORT, which rendez
+ * will pick up next time it is awake. Then we make sure it is awake
+ * with a broadcast. */
atomic_or(&cle->sysc->flags, SC_ABORT);
- cmb(); /* flags write before signal; atomic op provided CPU mb */
+ /* flags write before signal; atomic op provided CPU mb */
+ cmb();
cv_broadcast_irqsave(cle->cv, &irq_state);
- cmb(); /* broadcast writes before abort flag; atomic op provided CPU mb */
+ /* broadcast writes before abort flag; atomic op provided CPU mb */
+ cmb();
atomic_dec(&cle->abort_in_progress);
}
@@ -910,8 +932,8 @@
spin_lock_irqsave(&p->abort_list_lock);
TAILQ_FOREACH(cle, &p->abortable_sleepers, link) {
if ((uintptr_t)cle->sysc == sysc) {
- /* Note: we could have multiple aborters, so we need to use a
- * numeric refcnt instead of a flag. */
+ /* Note: we could have multiple aborters, so we need to
+ * use a numeric refcnt instead of a flag. */
atomic_inc(&cle->abort_in_progress);
break;
}
@@ -944,9 +966,9 @@
int ret = 0;
/* Concerns: we need to not remove them from their original list, since
- * concurrent wake ups will cause a dereg, which will remove from the list.
- * We also can't touch freed memory, so we need a refcnt to keep cles
- * around. */
+ * concurrent wake ups will cause a dereg, which will remove from the
+ * list. We also can't touch freed memory, so we need a refcnt to keep
+ * cles around. */
TAILQ_INIT(&abortall_list);
spin_lock_irqsave(&p->abort_list_lock);
TAILQ_FOREACH(cle, &p->abortable_sleepers, link) {
@@ -1007,6 +1029,7 @@
void __reg_abortable_cv(struct cv_lookup_elm *cle, struct cond_var *cv)
{
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+
cle->cv = cv;
cle->kthread = pcpui->cur_kthread;
/* Could be a ktask. Can build in support for aborting these later */
@@ -1035,8 +1058,8 @@
spin_lock_irqsave(&cle->proc->abort_list_lock);
TAILQ_REMOVE(&cle->proc->abortable_sleepers, cle, link);
spin_unlock_irqsave(&cle->proc->abort_list_lock);
- /* If we won the race and yanked it out of the list before abort claimed it,
- * this will already be FALSE. */
+ /* If we won the race and yanked it out of the list before abort claimed
+ * it, this will already be FALSE. */
while (atomic_read(&cle->abort_in_progress))
cpu_relax();
}
@@ -1075,9 +1098,9 @@
if (is_ktask(kth))
return 0;
- /* We leave the SAVE_ADDR_SPACE flag on. Now we're basically a ktask that
- * cares about its addr space, since we need to return to it (not that we're
- * leaving). */
+ /* We leave the SAVE_ADDR_SPACE flag on. Now we're basically a ktask
+ * that cares about its addr space, since we need to return to it (not
+ * that we're leaving). */
kth->flags |= KTH_IS_KTASK;
return 1;
}
diff --git a/kern/src/manager.c b/kern/src/manager.c
index a5d5766..8d09e86 100644
--- a/kern/src/manager.c
+++ b/kern/src/manager.c
@@ -53,54 +53,54 @@
char *p_argv[] = {0, 0, 0};
/* Helper macro for quickly running a process. Pass it a string, *file, and a
* *proc. */
-#define quick_proc_run(x, p, f) \
- (f) = do_file_open((x), O_READ, 0); \
- assert((f)); \
- p_argv[0] = file_name((f)); \
- (p) = proc_create((f), p_argv, NULL); \
- kref_put(&(f)->f_kref); \
- spin_lock(&(p)->proc_lock); \
- __proc_set_state((p), PROC_RUNNABLE_S); \
- spin_unlock(&(p)->proc_lock); \
- proc_run_s((p)); \
+#define quick_proc_run(x, p, f) \
+ (f) = do_file_open((x), O_READ, 0); \
+ assert((f)); \
+ p_argv[0] = file_name((f)); \
+ (p) = proc_create((f), p_argv, NULL); \
+ kref_put(&(f)->f_kref); \
+ spin_lock(&(p)->proc_lock); \
+ __proc_set_state((p), PROC_RUNNABLE_S); \
+ spin_unlock(&(p)->proc_lock); \
+ proc_run_s((p)); \
proc_decref((p));
-#define quick_proc_create(x, p, f) \
- (f) = do_file_open((x), O_READ, 0); \
- assert((f)); \
- p_argv[0] = file_name((f)); \
- (p) = proc_create((f), p_argv, NULL); \
- kref_put(&(f)->f_kref); \
- spin_lock(&(p)->proc_lock); \
- __proc_set_state((p), PROC_RUNNABLE_S); \
+#define quick_proc_create(x, p, f) \
+ (f) = do_file_open((x), O_READ, 0); \
+ assert((f)); \
+ p_argv[0] = file_name((f)); \
+ (p) = proc_create((f), p_argv, NULL); \
+ kref_put(&(f)->f_kref); \
+ spin_lock(&(p)->proc_lock); \
+ __proc_set_state((p), PROC_RUNNABLE_S); \
spin_unlock(&(p)->proc_lock);
-#define quick_proc_color_run(x, p, c, f) \
- (f) = do_file_open((x), O_READ, 0); \
- assert((f)); \
- p_argv[0] = file_name((f)); \
- (p) = proc_create((f), p_argv, NULL); \
- kref_put(&(f)->f_kref); \
- spin_lock(&(p)->proc_lock); \
- __proc_set_state((p), PROC_RUNNABLE_S); \
- spin_unlock(&(p)->proc_lock); \
- p->cache_colors_map = cache_colors_map_alloc(); \
- for (int i = 0; i < (c); i++) \
- cache_color_alloc(llc_cache, p->cache_colors_map); \
- proc_run_s((p)); \
+#define quick_proc_color_run(x, p, c, f) \
+ (f) = do_file_open((x), O_READ, 0); \
+ assert((f)); \
+ p_argv[0] = file_name((f)); \
+ (p) = proc_create((f), p_argv, NULL); \
+ kref_put(&(f)->f_kref); \
+ spin_lock(&(p)->proc_lock); \
+ __proc_set_state((p), PROC_RUNNABLE_S); \
+ spin_unlock(&(p)->proc_lock); \
+ p->cache_colors_map = cache_colors_map_alloc(); \
+ for (int i = 0; i < (c); i++) \
+ cache_color_alloc(llc_cache, p->cache_colors_map); \
+ proc_run_s((p)); \
proc_decref((p));
-#define quick_proc_color_create(x, p, c, f) \
- (f) = do_file_open((x), O_READ, 0); \
- assert((f)); \
- p_argv[0] = file_name((f)); \
- (p) = proc_create((f), p_argv, NULL); \
- kref_put(&(f)->f_kref); \
- spin_lock(&(p)->proc_lock); \
- __proc_set_state((p), PROC_RUNNABLE_S); \
- spin_unlock(&(p)->proc_lock); \
- p->cache_colors_map = cache_colors_map_alloc(); \
- for (int i = 0; i < (c); i++) \
+#define quick_proc_color_create(x, p, c, f) \
+ (f) = do_file_open((x), O_READ, 0); \
+ assert((f)); \
+ p_argv[0] = file_name((f)); \
+ (p) = proc_create((f), p_argv, NULL); \
+ kref_put(&(f)->f_kref); \
+ spin_lock(&(p)->proc_lock); \
+ __proc_set_state((p), PROC_RUNNABLE_S); \
+ spin_unlock(&(p)->proc_lock); \
+ p->cache_colors_map = cache_colors_map_alloc(); \
+ for (int i = 0; i < (c); i++) \
cache_color_alloc(llc_cache, p->cache_colors_map);
void manager_brho(void)
@@ -123,97 +123,11 @@
/* just idle, and deal with things via interrupts. or via face. */
smp_idle();
/* whatever we do in the manager, keep in mind that we need to not do
- * anything too soon (like make processes), since we'll drop in here during
- * boot if the boot sequence required any I/O (like EXT2), and we need to
- * PRKM() */
+ * anything too soon (like make processes), since we'll drop in here
+ * during boot if the boot sequence required any I/O (like EXT2), and we
+ * need to PRKM() */
assert(0);
-#if 0 /* ancient tests below: (keeping around til we ditch the manager) */
- // for testing taking cores, check in case 1 for usage
- uint32_t corelist[MAX_NUM_CORES];
- uint32_t num = 3;
- struct file *temp_f;
- static struct proc *p;
-
- static uint8_t RACY progress = 0; /* this will wrap around. */
- switch (progress++) {
- case 0:
- printk("Top of the manager to ya!\n");
- /* 124 is half of the available boxboro colors (with the kernel
- * getting 8) */
- //quick_proc_color_run("msr_dumb_while", p, 124, temp_f);
- quick_proc_run("/bin/hello", p, temp_f);
- #if 0
- // this is how you can transition to a parallel process manually
- // make sure you don't proc run first
- __proc_set_state(p, PROC_RUNNING_S);
- __proc_set_state(p, PROC_RUNNABLE_M);
- p->resources[RES_CORES].amt_wanted = 5;
- spin_unlock(&p->proc_lock);
- core_request(p);
- panic("This is okay");
- #endif
- break;
- case 1:
- #if 0
- udelay(10000000);
- // this is a ghetto way to test restarting an _M
- printk("\nattempting to ghetto preempt...\n");
- spin_lock(&p->proc_lock);
- proc_take_allcores(p, __death);
- __proc_set_state(p, PROC_RUNNABLE_M);
- spin_unlock(&p->proc_lock);
- udelay(5000000);
- printk("\nattempting to restart...\n");
- core_request(p); // proc still wants the cores
- panic("This is okay");
- // this tests taking some cores, and later killing an _M
- printk("taking 3 cores from p\n");
- for (int i = 0; i < num; i++)
- corelist[i] = 7-i; // 7, 6, and 5
- spin_lock(&p->proc_lock);
- proc_take_cores(p, corelist, &num, __death);
- spin_unlock(&p->proc_lock);
- udelay(5000000);
- printk("Killing p\n");
- proc_destroy(p);
- printk("Killed p\n");
- panic("This is okay");
-
- envs[0] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
- __proc_set_state(envs[0], PROC_RUNNABLE_S);
- proc_run(envs[0]);
- warn("DEPRECATED");
- break;
- #endif
- case 2:
- /*
- test_smp_call_functions();
- test_checklists();
- test_barrier();
- test_print_info();
- test_lapic_status_bit();
- test_ipi_sending();
- test_pit();
- */
- default:
- printd("Manager Progress: %d\n", progress);
- // delay if you want to test rescheduling an MCP that yielded
- //udelay(15000000);
- run_scheduler();
- }
- panic("If you see me, then you probably screwed up");
- monitor(0);
-
- /*
- printk("Servicing syscalls from Core 0:\n\n");
- while (1) {
- process_generic_syscalls(&envs[0], 1);
- cpu_relax();
- }
- */
- return;
-#endif
}
void manager_jenkins()
@@ -233,7 +147,8 @@
struct file *program = do_file_open(exec, O_READ, 0);
struct proc *p = proc_create(program, p_argv, NULL);
proc_wakeup(p);
- proc_decref(p); /* let go of the reference created in proc_create() */
+ /* let go of the reference created in proc_create() */
+ proc_decref(p);
kref_put(&program->f_kref);
run_scheduler();
// Need a way to wait for p to finish
@@ -266,6 +181,7 @@
void manager_waterman()
{
static bool first = true;
+
if (first)
mon_shell(0, 0, 0);
smp_idle();
diff --git a/kern/src/mm.c b/kern/src/mm.c
index 8d51536..7bc6ca9 100644
--- a/kern/src/mm.c
+++ b/kern/src/mm.c
@@ -29,7 +29,7 @@
/* These are the only mmap flags that are saved in the VMR. If we implement
* more of the mmap interface, we may need to grow this. */
-#define MAP_PERSIST_FLAGS (MAP_SHARED | MAP_PRIVATE | MAP_ANONYMOUS)
+#define MAP_PERSIST_FLAGS (MAP_SHARED | MAP_PRIVATE | MAP_ANONYMOUS)
struct kmem_cache *vmr_kcache;
@@ -85,7 +85,8 @@
if (!qid_is_file(foc->chan->qid))
return -1;
if (!waserror())
- ret = devtab[foc->chan->type].read(foc->chan, buf, amt, off);
+ ret = devtab[foc->chan->type].read(foc->chan, buf, amt,
+ off);
poperror();
return ret;
}
@@ -108,10 +109,11 @@
static void foc_release(struct kref *kref)
{
- struct file_or_chan *foc = container_of(kref, struct file_or_chan, kref);
+ struct file_or_chan *foc = container_of(kref, struct file_or_chan,
+ kref);
- /* A lot of places decref while holding a spinlock, but we can't free then,
- * since the cclose() might block. */
+ /* A lot of places decref while holding a spinlock, but we can't free
+ * then, since the cclose() might block. */
call_rcu(&foc->rcu, __foc_free_rcu);
}
@@ -227,7 +229,8 @@
set_error(ENODEV, "device does not support mmap");
return -1;
}
- foc->fsf = devtab[foc->chan->type].mmap(foc->chan, vmr, prot, flags);
+ foc->fsf = devtab[foc->chan->type].mmap(foc->chan, vmr, prot,
+ flags);
return foc->fsf ? 0 : -1;
}
panic("unknown F_OR_C type, %d", foc->type);
@@ -287,13 +290,15 @@
continue;
/* Find a gap that is big enough */
if (gap_end - vm_i->vm_end >= len) {
- /* if we can put it at va, let's do that. o/w, put it so it
- * fits */
- if ((gap_end >= va + len) && (va >= vm_i->vm_end))
+ /* if we can put it at va, let's do that. o/w,
+ * put it so it fits */
+ if ((gap_end >= va + len) &&
+ (va >= vm_i->vm_end))
vmr->vm_base = va;
else
vmr->vm_base = vm_i->vm_end;
- TAILQ_INSERT_AFTER(&p->vm_regions, vm_i, vmr, vm_link);
+ TAILQ_INSERT_AFTER(&p->vm_regions, vm_i, vmr,
+ vm_link);
ret = true;
break;
}
@@ -305,7 +310,8 @@
vmr->vm_end = vmr->vm_base + len;
}
if (!ret)
- warn("Not making a VMR, wanted %p, + %p = %p", va, len, va + len);
+ warn("Not making a VMR, wanted %p, + %p = %p", va, len, va +
+ len);
return ret;
}
@@ -378,8 +384,9 @@
static struct vm_region *merge_me(struct vm_region *vmr)
{
struct vm_region *vmr_temp;
- /* Merge will fail if it cannot do it. If it succeeds, the second VMR is
- * destroyed, so we need to be a bit careful. */
+
+ /* Merge will fail if it cannot do it. If it succeeds, the second VMR
+ * is destroyed, so we need to be a bit careful. */
vmr_temp = TAILQ_PREV(vmr, vmr_tailq, vm_link);
if (vmr_temp)
if (!merge_vmr(vmr_temp, vmr))
@@ -420,6 +427,7 @@
static struct vm_region *find_vmr(struct proc *p, uintptr_t va)
{
struct vm_region *vmr;
+
/* ugly linear seach */
TAILQ_FOREACH(vmr, &p->vm_regions, vm_link) {
if ((vmr->vm_base <= va) && (vmr->vm_end > va))
@@ -433,6 +441,7 @@
static struct vm_region *find_first_vmr(struct proc *p, uintptr_t va)
{
struct vm_region *vmr;
+
/* ugly linear seach */
TAILQ_FOREACH(vmr, &p->vm_regions, vm_link) {
if ((vmr->vm_base <= va) && (vmr->vm_end > va))
@@ -458,19 +467,22 @@
void unmap_and_destroy_vmrs(struct proc *p)
{
struct vm_region *vmr_i, *vmr_temp;
+
/* this only gets called from __proc_free, so there should be no sync
* concerns. still, better safe than sorry. */
spin_lock(&p->vmr_lock);
p->vmr_history++;
spin_lock(&p->pte_lock);
TAILQ_FOREACH(vmr_i, &p->vm_regions, vm_link) {
- /* note this CB sets the PTE = 0, regardless of if it was P or not */
+ /* note this CB sets the PTE = 0, regardless of if it was P or
+ * not */
env_user_mem_walk(p, (void*)vmr_i->vm_base,
- vmr_i->vm_end - vmr_i->vm_base, __vmr_free_pgs, 0);
+ vmr_i->vm_end - vmr_i->vm_base,
+ __vmr_free_pgs, 0);
}
spin_unlock(&p->pte_lock);
- /* need the safe style, since destroy_vmr modifies the list. also, we want
- * to do this outside the pte lock, since it grabs the pm lock. */
+ /* need the safe style, since destroy_vmr modifies the list. also, we
+ * want to do this outside the pte lock, since it grabs the pm lock. */
TAILQ_FOREACH_SAFE(vmr_i, &p->vm_regions, vm_link, vmr_temp)
destroy_vmr(vmr_i);
spin_unlock(&p->vmr_lock);
@@ -488,7 +500,7 @@
* Check for: alignment, wraparound, or userspace addresses */
if ((PGOFF(va_start)) ||
(PGOFF(va_end)) ||
- (va_end < va_start) || /* now, start > UMAPTOP -> end > UMAPTOP */
+ (va_end < va_start) ||/* now, start > UMAPTOP -> end > UMAPTOP */
(va_end > UMAPTOP)) {
warn("VMR mapping is probably screwed up (%p - %p)", va_start,
va_end);
@@ -497,32 +509,36 @@
int copy_page(struct proc *p, pte_t pte, void *va, void *arg) {
struct proc *new_p = (struct proc*)arg;
struct page *pp;
+
if (pte_is_unmapped(pte))
return 0;
- /* pages could be !P, but right now that's only for file backed VMRs
- * undergoing page removal, which isn't the caller of copy_pages. */
+ /* pages could be !P, but right now that's only for file backed
+ * VMRs undergoing page removal, which isn't the caller of
+ * copy_pages. */
if (pte_is_mapped(pte)) {
/* TODO: check for jumbos */
if (upage_alloc(new_p, &pp, 0))
return -ENOMEM;
memcpy(page2kva(pp), KADDR(pte_get_paddr(pte)), PGSIZE);
- if (page_insert(new_p->env_pgdir, pp, va, pte_get_settings(pte))) {
+ if (page_insert(new_p->env_pgdir, pp, va,
+ pte_get_settings(pte))) {
page_decref(pp);
return -ENOMEM;
}
} else if (pte_is_paged_out(pte)) {
- /* TODO: (SWAP) will need to either make a copy or CoW/refcnt the
- * backend store. For now, this PTE will be the same as the
- * original PTE */
+ /* TODO: (SWAP) will need to either make a copy or
+ * CoW/refcnt the backend store. For now, this PTE will
+ * be the same as the original PTE */
panic("Swapping not supported!");
} else {
- panic("Weird PTE %p in %s!", pte_print(pte), __FUNCTION__);
+ panic("Weird PTE %p in %s!", pte_print(pte),
+ __FUNCTION__);
}
return 0;
}
spin_lock(&p->pte_lock); /* walking and changing PTEs */
- ret = env_user_mem_walk(p, (void*)va_start, va_end - va_start, ©_page,
- new_p);
+ ret = env_user_mem_walk(p, (void*)va_start, va_end - va_start,
+ ©_page, new_p);
spin_unlock(&p->pte_lock);
return ret;
}
@@ -536,15 +552,17 @@
assert(!(vmr->vm_flags & MAP_SHARED));
ret = copy_pages(p, new_p, vmr->vm_base, vmr->vm_end);
} else {
- /* non-private file, i.e. page cacheable. we have to honor MAP_LOCKED,
- * (but we might be able to ignore MAP_POPULATE). */
+ /* non-private file, i.e. page cacheable. we have to honor
+ * MAP_LOCKED, (but we might be able to ignore MAP_POPULATE). */
if (vmr->vm_flags & MAP_LOCKED) {
- /* need to keep the file alive in case we unlock/block */
+ /* need to keep the file alive in case we unlock/block
+ */
foc_incref(vmr->__vm_foc);
/* math is a bit nasty if vm_base isn't page aligned */
assert(!PGOFF(vmr->vm_base));
ret = populate_pm_va(new_p, vmr->vm_base,
- (vmr->vm_end - vmr->vm_base) >> PGSHIFT,
+ (vmr->vm_end - vmr->vm_base) >>
+ PGSHIFT,
vmr->vm_prot, vmr_to_pm(vmr),
vmr->vm_foff, vmr->vm_flags,
vmr->vm_prot & PROT_EXEC);
@@ -618,9 +636,8 @@
print_unlock();
}
-void enumerate_vmrs(struct proc *p,
- void (*func)(struct vm_region *vmr, void *opaque),
- void *opaque)
+void enumerate_vmrs(struct proc *p, void (*func)(struct vm_region *vmr,
+ void *opaque), void *opaque)
{
struct vm_region *vmr;
@@ -653,8 +670,8 @@
void *result;
offset <<= PGSHIFT;
- printd("mmap(addr %x, len %x, prot %x, flags %x, fd %x, off %x)\n", addr,
- len, prot, flags, fd, offset);
+ printd("mmap(addr %x, len %x, prot %x, flags %x, fd %x, off %x)\n",
+ addr, len, prot, flags, fd, offset);
if (!mmap_flags_priv_ok(flags)) {
set_errno(EINVAL);
return MAP_FAILED;
@@ -671,17 +688,18 @@
goto out_ref;
}
}
- /* Check for overflow. This helps do_mmap and populate_va, among others. */
+ /* Check for overflow. This helps do_mmap and populate_va, among
+ * others. */
if (offset + len < offset) {
set_errno(EINVAL);
result = MAP_FAILED;
goto out_ref;
}
- /* If they don't care where to put it, we'll start looking after the break.
- * We could just have userspace handle this (in glibc's mmap), so we don't
- * need to know about BRK_END, but this will work for now (and may avoid
- * bugs). Note that this limits mmap(0) a bit. Keep this in sync with
- * do_mmap()'s check. (Both are necessary). */
+ /* If they don't care where to put it, we'll start looking after the
+ * break. We could just have userspace handle this (in glibc's mmap),
+ * so we don't need to know about BRK_END, but this will work for now
+ * (and may avoid bugs). Note that this limits mmap(0) a bit. Keep
+ * this in sync with do_mmap()'s check. (Both are necessary). */
if (addr == 0)
addr = BRK_END;
/* Still need to enforce this: */
@@ -716,6 +734,7 @@
int prot)
{
pte_t pte;
+
spin_lock(&p->pte_lock); /* walking and changing PTEs */
/* find offending PTE (prob don't read this in). This might alloc an
* intermediate page table page. */
@@ -726,21 +745,22 @@
page_decref(page);
return -ENOMEM;
}
- /* a spurious, valid PF is possible due to a legit race: the page might have
- * been faulted in by another core already (and raced on the memory lock),
- * in which case we should just return. */
+ /* a spurious, valid PF is possible due to a legit race: the page might
+ * have been faulted in by another core already (and raced on the memory
+ * lock), in which case we should just return. */
if (pte_is_present(pte)) {
spin_unlock(&p->pte_lock);
if (!page_is_pagemap(page))
page_decref(page);
return 0;
}
- /* I used to allow clobbering an old entry (contrary to the documentation),
- * but it's probably a sign of another bug. */
+ /* I used to allow clobbering an old entry (contrary to the
+ * documentation), but it's probably a sign of another bug. */
assert(!pte_is_mapped(pte));
/* preserve the dirty bit - pm removal could be looking concurrently */
prot |= (pte_is_dirty(pte) ? PTE_D : 0);
- /* We have a ref to page (for non PMs), which we are storing in the PTE */
+ /* We have a ref to page (for non PMs), which we are storing in the PTE
+ */
pte_write(pte, page2pa(page), prot);
spin_unlock(&p->pte_lock);
return 0;
@@ -751,6 +771,7 @@
static int __copy_and_swap_pmpg(struct proc *p, struct page **pp)
{
struct page *new_page, *old_page = *pp;
+
if (upage_alloc(p, &new_page, FALSE))
return -ENOMEM;
memcpy(page2kva(new_page), page2kva(old_page), PGSIZE);
@@ -766,6 +787,7 @@
{
struct page *page;
int ret;
+
for (long i = 0; i < nr_pgs; i++) {
if (upage_alloc(p, &page, TRUE))
return -ENOMEM;
@@ -787,13 +809,13 @@
int vmr_history = ACCESS_ONCE(p->vmr_history);
struct page *page;
- /* This is a racy check - see the comments in fs_file.c. Also, we're not
- * even attempting to populate the va, though we could do a partial if
- * necessary. */
+ /* This is a racy check - see the comments in fs_file.c. Also, we're
+ * not even attempting to populate the va, though we could do a partial
+ * if necessary. */
if (pm_idx0 + nr_pgs > nr_pages(fs_file_get_length(pm->pm_file)))
return -ESPIPE;
- /* locking rules: start the loop holding the vmr lock, enter and exit the
- * entire func holding the lock. */
+ /* locking rules: start the loop holding the vmr lock, enter and exit
+ * the entire func holding the lock. */
for (long i = 0; i < nr_pgs; i++) {
ret = pm_load_page_nowait(pm, pm_idx0 + i, &page);
if (ret) {
@@ -805,10 +827,12 @@
spin_lock(&p->vmr_lock);
if (ret)
break;
- /* while we were sleeping, the VMRs could have changed on us. */
+ /* while we were sleeping, the VMRs could have changed
+ * on us. */
if (vmr_history != ACCESS_ONCE(p->vmr_history)) {
pm_put_page(page);
- printk("[kernel] FYI: VMR changed during populate\n");
+ printk("[kernel] "
+ "FYI: VMR changed during populate\n");
break;
}
}
@@ -824,7 +848,8 @@
* TODO: is this still needed? andrew put this in a while ago*/
if (exec)
icache_flush_page(0, page2kva(page));
- /* The page could be either in the PM, or a private, now-anon page. */
+ /* The page could be either in the PM, or a private, now-anon
+ * page. */
ret = map_page_at_addr(p, page, va + i * PGSIZE, pte_prot);
if (page_is_pagemap(page))
pm_put_page(page);
@@ -844,15 +869,16 @@
vmr = vmr_zalloc();
/* Sanity check, for callers that bypass mmap(). We want addr for anon
- * memory to start above the break limit (BRK_END), but not 0. Keep this in
- * sync with BRK_END in mmap(). */
+ * memory to start above the break limit (BRK_END), but not 0. Keep
+ * this in sync with BRK_END in mmap(). */
if (addr == 0)
addr = BRK_END;
assert(!PGOFF(offset));
- /* MCPs will need their code and data pinned. This check will start to fail
- * after uthread_slim_init(), at which point userspace should have enough
- * control over its mmaps (i.e. no longer done by LD or load_elf) that it
- * can ask for pinned and populated pages. Except for dl_opens(). */
+ /* MCPs will need their code and data pinned. This check will start to
+ * fail after uthread_slim_init(), at which point userspace should have
+ * enough control over its mmaps (i.e. no longer done by LD or load_elf)
+ * that it can ask for pinned and populated pages. Except for
+ * dl_opens(). */
struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[0];
if (file && (atomic_read(&vcpd->flags) & VC_SCP_NOVCCTX))
@@ -863,8 +889,9 @@
/* We grab the file early, so we can block. This is all hokey. The VMR
* isn't ready yet, so the PM code will ignore it. */
if (file) {
- /* Prep the FS and make sure it can mmap the file. The device/FS checks
- * perms, and does whatever else it needs to make the mmap work. */
+ /* Prep the FS and make sure it can mmap the file. The
+ * device/FS checks perms, and does whatever else it needs to
+ * make the mmap work. */
if (foc_dev_mmap(file, vmr, prot, flags & MAP_PERSIST_FLAGS)) {
vmr_free(vmr);
set_errno(EACCES); /* not quite */
@@ -874,25 +901,27 @@
pm_add_vmr(foc_to_pm(file), vmr);
foc_incref(file);
vmr->__vm_foc = file;
- /* TODO: consider locking the file while checking (not as manadatory as
- * in handle_page_fault() */
+ /* TODO: consider locking the file while checking (not as
+ * manadatory as in handle_page_fault() */
if (nr_pages(offset + len) > nr_pages(foc_get_len(file))) {
- /* We're allowing them to set up the VMR, though if they attempt to
- * fault in any pages beyond the file's limit, they'll fail. Since
- * they might not access the region, we need to make sure POPULATE
- * is off. FYI, 64 bit glibc shared libs map in an extra 2MB of
- * unaligned space between their RO and RW sections, but then
- * immediately mprotect it to PROT_NONE. */
+ /* We're allowing them to set up the VMR, though if they
+ * attempt to fault in any pages beyond the file's
+ * limit, they'll fail. Since they might not access the
+ * region, we need to make sure POPULATE is off. FYI,
+ * 64 bit glibc shared libs map in an extra 2MB of
+ * unaligned space between their RO and RW sections, but
+ * then immediately mprotect it to PROT_NONE. */
flags &= ~MAP_POPULATE;
}
}
/* read/write vmr lock (will change the tree) */
spin_lock(&p->vmr_lock);
p->vmr_history++;
- /* Need to make sure nothing is in our way when we want a FIXED location.
- * We just need to split on the end points (if they exist), and then remove
- * everything in between. __do_munmap() will do this. Careful, this means
- * an mmap can be an implied munmap() (not my call...). */
+ /* Need to make sure nothing is in our way when we want a FIXED
+ * location. We just need to split on the end points (if they exist),
+ * and then remove everything in between. __do_munmap() will do this.
+ * Careful, this means an mmap can be an implied munmap() (not my
+ * call...). */
if (flags & MAP_FIXED)
__do_munmap(p, addr, len);
if (!vmr_insert(vmr, p, addr, len)) {
@@ -903,8 +932,8 @@
}
vmr_free(vmr);
set_error(ENOMEM, "probably tried to mmap beyond UMAPTOP");
- /* Slightly weird semantics: if we fail and had munmapped the space,
- * they will have a hole in their VM now. */
+ /* Slightly weird semantics: if we fail and had munmapped the
+ * space, they will have a hole in their VM now. */
return MAP_FAILED;
}
addr = vmr->vm_base;
@@ -920,16 +949,18 @@
if (!file) {
ret = populate_anon_va(p, addr, nr_pgs, pte_prot);
} else {
- /* Note: this will unlock if it blocks. our refcnt on the file
- * keeps the pm alive when we unlock */
- ret = populate_pm_va(p, addr, nr_pgs, pte_prot, foc_to_pm(file),
- offset, flags, prot & PROT_EXEC);
+ /* Note: this will unlock if it blocks. our refcnt on
+ * the file keeps the pm alive when we unlock */
+ ret = populate_pm_va(p, addr, nr_pgs, pte_prot,
+ foc_to_pm(file), offset, flags,
+ prot & PROT_EXEC);
}
if (ret == -ENOMEM) {
spin_unlock(&p->vmr_lock);
printk("[kernel] ENOMEM, killing %d\n", p->pid);
proc_destroy(p);
- return MAP_FAILED; /* will never make it back to userspace */
+ /* this will never make it back to userspace */
+ return MAP_FAILED;
}
}
spin_unlock(&p->vmr_lock);
@@ -975,26 +1006,29 @@
int pte_prot = (prot & PROT_WRITE) ? PTE_USER_RW :
(prot & (PROT_READ|PROT_EXEC)) ? PTE_USER_RO : PTE_NONE;
- /* TODO: this is aggressively splitting, when we might not need to if the
- * prots are the same as the previous. Plus, there are three excessive
- * scans. */
+ /* TODO: this is aggressively splitting, when we might not need to if
+ * the prots are the same as the previous. Plus, there are three
+ * excessive scans. */
isolate_vmrs(p, addr, len);
vmr = find_first_vmr(p, addr);
while (vmr && vmr->vm_base < addr + len) {
if (vmr->vm_prot == prot)
goto next_vmr;
- if (vmr_has_file(vmr) && !check_foc_perms(vmr, vmr->__vm_foc, prot)) {
+ if (vmr_has_file(vmr) &&
+ !check_foc_perms(vmr, vmr->__vm_foc, prot)) {
file_access_failure = TRUE;
goto next_vmr;
}
vmr->vm_prot = prot;
spin_lock(&p->pte_lock); /* walking and changing PTEs */
- /* TODO: use a memwalk. At a minimum, we need to change every existing
- * PTE that won't trigger a PF (meaning, present PTEs) to have the new
- * prot. The others will fault on access, and we'll change the PTE
- * then. In the off chance we have a mapped but not present PTE, we
- * might as well change it too, since we're already here. */
- for (uintptr_t va = vmr->vm_base; va < vmr->vm_end; va += PGSIZE) {
+ /* TODO: use a memwalk. At a minimum, we need to change every
+ * existing PTE that won't trigger a PF (meaning, present PTEs)
+ * to have the new prot. The others will fault on access, and
+ * we'll change the PTE then. In the off chance we have a
+ * mapped but not present PTE, we might as well change it too,
+ * since we're already here. */
+ for (uintptr_t va = vmr->vm_base; va < vmr->vm_end;
+ va += PGSIZE) {
pte = pgdir_walk(p->env_pgdir, (void*)va, 0);
if (pte_walk_okay(pte) && pte_is_mapped(pte)) {
pte_replace_perm(pte, pte_prot);
@@ -1003,11 +1037,11 @@
}
spin_unlock(&p->pte_lock);
next_vmr:
- /* Note that this merger could cause us to not look at the next one,
- * since we merged with it. That's ok, since in that case, the next one
- * already has the right prots. Also note that every VMR in the region,
- * including the ones at the endpoints, attempted to merge left and
- * right. */
+ /* Note that this merger could cause us to not look at the next
+ * one, since we merged with it. That's ok, since in that case,
+ * the next one already has the right prots. Also note that
+ * every VMR in the region, including the ones at the endpoints,
+ * attempted to merge left and right. */
vmr = merge_me(vmr);
next_vmr = TAILQ_NEXT(vmr, vm_link);
vmr = next_vmr;
@@ -1051,7 +1085,7 @@
struct page *page;
/* could put in some checks here for !P and also !0 */
- if (!pte_is_present(pte)) /* unmapped (== 0) *ptes are also not PTE_P */
+ if (!pte_is_present(pte)) /* unmapped (== 0) *ptes are also not PTE_P */
return 0;
if (pte_is_dirty(pte)) {
page = pa2page(pte_get_paddr(pte));
@@ -1099,25 +1133,29 @@
vmr = first_vmr;
spin_lock(&p->pte_lock); /* changing PTEs */
while (vmr && vmr->vm_base < addr + len) {
- /* It's important that we call __munmap_pte and sync the PG_DIRTY bit
- * before we unhook the VMR from the PM (in destroy_vmr). */
- env_user_mem_walk(p, (void*)vmr->vm_base, vmr->vm_end - vmr->vm_base,
- __munmap_pte, &shootdown_needed);
+ /* It's important that we call __munmap_pte and sync the
+ * PG_DIRTY bit before we unhook the VMR from the PM (in
+ * destroy_vmr). */
+ env_user_mem_walk(p, (void*)vmr->vm_base,
+ vmr->vm_end - vmr->vm_base, __munmap_pte,
+ &shootdown_needed);
vmr = TAILQ_NEXT(vmr, vm_link);
}
spin_unlock(&p->pte_lock);
- /* we haven't freed the pages yet; still using the PTEs to store the them.
- * There should be no races with inserts/faults, since we still hold the mm
- * lock since the previous CB. */
+ /* we haven't freed the pages yet; still using the PTEs to store the
+ * them. There should be no races with inserts/faults, since we still
+ * hold the mm lock since the previous CB. */
if (shootdown_needed)
proc_tlbshootdown(p, addr, addr + len);
vmr = first_vmr;
while (vmr && vmr->vm_base < addr + len) {
- /* there is rarely more than one VMR in this loop. o/w, we'll need to
- * gather up the vmrs and destroy outside the pte_lock. */
+ /* there is rarely more than one VMR in this loop. o/w, we'll
+ * need to gather up the vmrs and destroy outside the pte_lock.
+ */
spin_lock(&p->pte_lock); /* changing PTEs */
- env_user_mem_walk(p, (void*)vmr->vm_base, vmr->vm_end - vmr->vm_base,
- __vmr_free_pgs, 0);
+ env_user_mem_walk(p, (void*)vmr->vm_base,
+ vmr->vm_end - vmr->vm_base, __vmr_free_pgs,
+ 0);
spin_unlock(&p->pte_lock);
next_vmr = TAILQ_NEXT(vmr, vm_link);
destroy_vmr(vmr);
@@ -1144,37 +1182,37 @@
bool wake_scp = FALSE;
spin_lock(&p->proc_lock);
switch (p->state) {
- case (PROC_RUNNING_S):
- wake_scp = TRUE;
- __proc_set_state(p, PROC_WAITING);
- /* it's possible for HPF to loop a few times; we can only save the
- * first time, o/w we could clobber. */
- if (first) {
- __proc_save_context_s(p);
- __proc_save_fpu_s(p);
- /* We clear the owner, since userspace doesn't run here
- * anymore, but we won't abandon since the fault handler
- * still runs in our process. */
- clear_owning_proc(coreid);
- }
- /* other notes: we don't currently need to tell the ksched
- * we switched from running to waiting, though we probably
- * will later for more generic scheds. */
- break;
- case (PROC_RUNNABLE_M):
- case (PROC_RUNNING_M):
- spin_unlock(&p->proc_lock);
- return -EAGAIN; /* will get reflected back to userspace */
- case (PROC_DYING):
- case (PROC_DYING_ABORT):
- spin_unlock(&p->proc_lock);
- return -EINVAL;
- default:
- /* shouldn't have any waitings, under the current yield style. if
- * this becomes an issue, we can branch on is_mcp(). */
- printk("HPF unexpectecd state(%s)", procstate2str(p->state));
- spin_unlock(&p->proc_lock);
- return -EINVAL;
+ case (PROC_RUNNING_S):
+ wake_scp = TRUE;
+ __proc_set_state(p, PROC_WAITING);
+ /* it's possible for HPF to loop a few times; we can only save
+ * the first time, o/w we could clobber. */
+ if (first) {
+ __proc_save_context_s(p);
+ __proc_save_fpu_s(p);
+ /* We clear the owner, since userspace doesn't run here
+ * anymore, but we won't abandon since the fault handler
+ * still runs in our process. */
+ clear_owning_proc(coreid);
+ }
+ /* other notes: we don't currently need to tell the ksched
+ * we switched from running to waiting, though we probably
+ * will later for more generic scheds. */
+ break;
+ case (PROC_RUNNABLE_M):
+ case (PROC_RUNNING_M):
+ spin_unlock(&p->proc_lock);
+ return -EAGAIN; /* will get reflected back to userspace */
+ case (PROC_DYING):
+ case (PROC_DYING_ABORT):
+ spin_unlock(&p->proc_lock);
+ return -EINVAL;
+ default:
+ /* shouldn't have any waitings, under the current yield style.
+ * if this becomes an issue, we can branch on is_mcp(). */
+ printk("HPF unexpectecd state(%s)", procstate2str(p->state));
+ spin_unlock(&p->proc_lock);
+ return -EINVAL;
}
spin_unlock(&p->proc_lock);
ret = pm_load_page(pm, idx, page);
@@ -1212,12 +1250,12 @@
spin_lock(&p->vmr_lock);
/* Check the vmr's protection */
vmr = find_vmr(p, va);
- if (!vmr) { /* not mapped at all */
+ if (!vmr) { /* not mapped at all */
printd("fault: %p not mapped\n", va);
ret = -EFAULT;
goto out;
}
- if (!(vmr->vm_prot & prot)) { /* wrong prots for this vmr */
+ if (!(vmr->vm_prot & prot)) { /* wrong prots for this vmr */
ret = -EPERM;
goto out;
}
@@ -1233,16 +1271,17 @@
goto out;
}
file = vmr->__vm_foc;
- /* If this fails, either something got screwed up with the VMR, or the
- * permissions changed after mmap/mprotect. Either way, I want to know
- * (though it's not critical). */
+ /* If this fails, either something got screwed up with the VMR,
+ * or the permissions changed after mmap/mprotect. Either way,
+ * I want to know (though it's not critical). */
if (!check_foc_perms(vmr, file, prot))
- printk("[kernel] possible issue with VMR prots on file %s!\n",
+ printk("[kernel] "
+ "possible issue with VMR prots on file %s!\n",
foc_to_name(file));
/* Load the file's page in the page cache.
- * TODO: (BLK) Note, we are holding the mem lock! We need to rewrite
- * this stuff so we aren't hold the lock as excessively as we are, and
- * such that we can block and resume later. */
+ * TODO: (BLK) Note, we are holding the mem lock! We need to
+ * rewrite this stuff so we aren't hold the lock as excessively
+ * as we are, and such that we can block and resume later. */
assert(!PGOFF(va - vmr->vm_base + vmr->vm_foff));
f_idx = (va - vmr->vm_base + vmr->vm_foff) >> PGSHIFT;
/* This is a racy check - see the comments in fs_file.c */
@@ -1257,39 +1296,40 @@
/* keep the file alive after we unlock */
foc_incref(file);
spin_unlock(&p->vmr_lock);
- ret = __hpf_load_page(p, foc_to_pm(file), f_idx, &a_page,
- first);
+ ret = __hpf_load_page(p, foc_to_pm(file), f_idx,
+ &a_page, first);
first = FALSE;
foc_decref(file);
if (ret)
return ret;
goto refault;
}
- /* If we want a private map, we'll preemptively give you a new page. We
- * used to just care if it was private and writable, but were running
- * into issues with libc changing its mapping (map private, then
- * mprotect to writable...) In the future, we want to CoW this anyway,
- * so it's not a big deal. */
+ /* If we want a private map, we'll preemptively give you a new
+ * page. We used to just care if it was private and writable,
+ * but were running into issues with libc changing its mapping
+ * (map private, then mprotect to writable...) In the future,
+ * we want to CoW this anyway, so it's not a big deal. */
if ((vmr->vm_flags & MAP_PRIVATE)) {
ret = __copy_and_swap_pmpg(p, &a_page);
if (ret)
goto out_put_pg;
}
- /* if this is an executable page, we might have to flush the instruction
- * cache if our HW requires it. */
+ /* if this is an executable page, we might have to flush the
+ * instruction cache if our HW requires it. */
if (vmr->vm_prot & PROT_EXEC)
icache_flush_page((void*)va, page2kva(a_page));
}
- /* update the page table TODO: careful with MAP_PRIVATE etc. might do this
- * separately (file, no file) */
+ /* update the page table TODO: careful with MAP_PRIVATE etc. might do
+ * this separately (file, no file) */
int pte_prot = (vmr->vm_prot & PROT_WRITE) ? PTE_USER_RW :
(vmr->vm_prot & (PROT_READ|PROT_EXEC)) ? PTE_USER_RO : 0;
ret = map_page_at_addr(p, a_page, va, pte_prot);
/* fall through, even for errors */
out_put_pg:
- /* the VMR's existence in the PM (via the mmap) allows us to have PTE point
- * to a_page without it magically being reallocated. For non-PM memory
- * (anon memory or private pages) we transferred the ref to the PTE. */
+ /* the VMR's existence in the PM (via the mmap) allows us to have PTE
+ * point to a_page without it magically being reallocated. For non-PM
+ * memory (anon memory or private pages) we transferred the ref to the
+ * PTE. */
if (page_is_pagemap(a_page))
pm_put_page(a_page);
out:
@@ -1320,8 +1360,8 @@
int ret;
/* we can screw around with ways to limit the find_vmr calls (can do the
- * next in line if we didn't unlock, etc., but i don't expect us to do this
- * for more than a single VMR in most cases. */
+ * next in line if we didn't unlock, etc., but i don't expect us to do
+ * this for more than a single VMR in most cases. */
spin_lock(&p->vmr_lock);
while (nr_pgs) {
vmr = find_vmr(p, va);
@@ -1330,28 +1370,33 @@
if (vmr->vm_prot == PROT_NONE)
break;
pte_prot = (vmr->vm_prot & PROT_WRITE) ? PTE_USER_RW :
- (vmr->vm_prot & (PROT_READ|PROT_EXEC)) ? PTE_USER_RO : 0;
+ (vmr->vm_prot & (PROT_READ|PROT_EXEC)) ? PTE_USER_RO
+ : 0;
nr_pgs_this_vmr = MIN(nr_pgs, (vmr->vm_end - va) >> PGSHIFT);
if (!vmr_has_file(vmr)) {
- if (populate_anon_va(p, va, nr_pgs_this_vmr, pte_prot)) {
- /* on any error, we can just bail. we might be underestimating
- * nr_filled. */
+ if (populate_anon_va(p, va, nr_pgs_this_vmr, pte_prot))
+ {
+ /* on any error, we can just bail. we might be
+ * underestimating nr_filled. */
break;
}
} else {
file = vmr->__vm_foc;
- /* need to keep the file alive in case we unlock/block */
+ /* need to keep the file alive in case we unlock/block
+ */
foc_incref(file);
- /* Regarding foff + (va - base): va - base < len, and foff + len
- * does not over flow */
+ /* Regarding foff + (va - base): va - base < len, and
+ * foff + len does not over flow */
ret = populate_pm_va(p, va, nr_pgs_this_vmr, pte_prot,
foc_to_pm(file),
vmr->vm_foff + (va - vmr->vm_base),
- vmr->vm_flags, vmr->vm_prot & PROT_EXEC);
+ vmr->vm_flags,
+ vmr->vm_prot & PROT_EXEC);
foc_decref(file);
if (ret) {
- /* we might have failed if the underlying file doesn't cover the
- * mmap window, depending on how we'll deal with truncation. */
+ /* we might have failed if the underlying file
+ * doesn't cover the mmap window, depending on
+ * how we'll deal with truncation. */
break;
}
}
@@ -1369,8 +1414,8 @@
struct arena *vmap_arena;
static spinlock_t vmap_lock = SPINLOCK_INITIALIZER;
struct vmap_free_tracker {
- void *addr;
- size_t nr_bytes;
+ void *addr;
+ size_t nr_bytes;
};
static struct vmap_free_tracker *vmap_to_free;
static size_t vmap_nr_to_free;
@@ -1388,8 +1433,8 @@
spin_lock(&vmap_lock);
/* All objs get *unmapped* immediately, but we'll shootdown later. Note
- * that it is OK (but slightly dangerous) for the kernel to reuse the paddrs
- * pointed to by the vaddrs before a TLB shootdown. */
+ * that it is OK (but slightly dangerous) for the kernel to reuse the
+ * paddrs pointed to by the vaddrs before a TLB shootdown. */
unmap_segment(boot_pgdir, (uintptr_t)obj, size);
if (vmap_nr_to_free < VMAP_MAX_TO_FREE) {
vft = &vmap_to_free[vmap_nr_to_free++];
@@ -1414,14 +1459,14 @@
vmap_addr_arena = arena_create("vmap_addr", (void*)KERN_DYN_BOT,
KERN_DYN_TOP - KERN_DYN_BOT,
PGSIZE, NULL, NULL, NULL, 0, MEM_WAIT);
- vmap_arena = arena_create("vmap", NULL, 0, PGSIZE, arena_alloc, __vmap_free,
- vmap_addr_arena, 0, MEM_WAIT);
- vmap_to_free = kmalloc(sizeof(struct vmap_free_tracker) * VMAP_MAX_TO_FREE,
- MEM_WAIT);
- /* This ensures the boot_pgdir's top-most PML (PML4) has entries pointing to
- * PML3s that cover the dynamic mapping range. Now, it's safe to create
- * processes that copy from boot_pgdir and still dynamically change the
- * kernel mappings. */
+ vmap_arena = arena_create("vmap", NULL, 0, PGSIZE, arena_alloc,
+ __vmap_free, vmap_addr_arena, 0, MEM_WAIT);
+ vmap_to_free = kmalloc(sizeof(struct vmap_free_tracker)
+ * VMAP_MAX_TO_FREE, MEM_WAIT);
+ /* This ensures the boot_pgdir's top-most PML (PML4) has entries
+ * pointing to PML3s that cover the dynamic mapping range. Now, it's
+ * safe to create processes that copy from boot_pgdir and still
+ * dynamically change the kernel mappings. */
arch_add_intermediate_pts(boot_pgdir, KERN_DYN_BOT,
KERN_DYN_TOP - KERN_DYN_BOT);
}
@@ -1476,8 +1521,8 @@
warn("Unable to get a vmap segment"); /* probably a bug */
return 0;
}
- /* it's not strictly necessary to drop paddr's pgoff, but it might save some
- * vmap heartache in the future. */
+ /* it's not strictly necessary to drop paddr's pgoff, but it might save
+ * some vmap heartache in the future. */
if (map_vmap_segment(vaddr, PG_ADDR(paddr), nr_pages,
PTE_KERN_RW | flags)) {
warn("Unable to map a vmap segment"); /* probably a bug */
diff --git a/kern/src/monitor.c b/kern/src/monitor.c
index 8c137fd..79cd19d 100644
--- a/kern/src/monitor.c
+++ b/kern/src/monitor.c
@@ -99,18 +99,22 @@
{
extern char _start[], etext[], end[];
- cprintf("Special kernel symbols:\n");
- cprintf(" _start %016x (virt) %016x (phys)\n", _start, (uintptr_t)(_start - KERNBASE));
- cprintf(" etext %016x (virt) %016x (phys)\n", etext, (uintptr_t)(etext - KERNBASE));
- cprintf(" end %016x (virt) %016x (phys)\n", end, (uintptr_t)(end - KERNBASE));
- cprintf("Kernel executable memory footprint: %dKB\n",
- (uint32_t)(end-_start+1023)/1024);
+ printk("Special kernel symbols:\n");
+ printk(" _start %016x (virt) %016x (phys)\n", _start,
+ (uintptr_t)(_start - KERNBASE));
+ printk(" etext %016x (virt) %016x (phys)\n", etext,
+ (uintptr_t)(etext - KERNBASE));
+ printk(" end %016x (virt) %016x (phys)\n", end,
+ (uintptr_t)(end - KERNBASE));
+ printk("Kernel executable memory footprint: %dKB\n",
+ (uint32_t)(end-_start + 1023)/1024);
return 0;
}
static int __backtrace(int argc, char **argv, struct hw_trapframe *hw_tf)
{
uintptr_t pc, fp;
+
if (argc == 1) {
backtrace();
return 0;
@@ -122,7 +126,8 @@
pc = strtol(argv[1], 0, 16);
fp = strtol(argv[2], 0, 16);
print_lock();
- printk("Backtrace from instruction %p, with frame pointer %p\n", pc, fp);
+ printk("Backtrace from instruction %p, with frame pointer %p\n", pc,
+ fp);
backtrace_frame(pc, fp);
print_unlock();
return 0;
@@ -152,7 +157,7 @@
pid_t pid;
if (argc < 3) {
- printk("Shows virtual -> physical mappings for a virt addr range.\n");
+ printk("Shows virt -> phys mappings for a virt addr range.\n");
printk("Usage: showmapping PID START_ADDR [END_ADDR]\n");
printk(" PID == 0 for the boot pgdir\n");
return 1;
@@ -253,8 +258,8 @@
int mon_nanwan(int argc, char **argv, struct hw_trapframe *hw_tf)
{
/* Borrowed with love from http://www.geocities.com/SoHo/7373/zoo.htm
- * (http://www.ascii-art.com/). Slightly modified to make it 25 lines tall.
- */
+ * (http://www.ascii-art.com/). Slightly modified to make it 25 lines
+ * tall. */
print_lock();
printk("\n");
printk(" .-. .-.\n");
@@ -304,12 +309,13 @@
printk("No such program!\n");
return 1;
}
- char **p_argv = kmalloc(sizeof(char*) * argc, 0); /* bin_run's argc */
+ char **p_argv = kmalloc(sizeof(char*) * argc, 0); /* bin_run's argc */
for (int i = 0; i < argc - 1; i++)
p_argv[i] = argv[i + 1];
p_argv[argc - 1] = 0;
- /* super ugly: we need to stash current, so that proc_create doesn't pick up
- * on random processes running here and assuming they are the parent */
+ /* super ugly: we need to stash current, so that proc_create doesn't
+ * pick up on random processes running here and assuming they are the
+ * parent */
struct proc *old_cur = current;
current = 0;
struct proc *p = proc_create(program, p_argv, NULL);
@@ -318,8 +324,9 @@
proc_wakeup(p);
proc_decref(p); /* let go of the reference created in proc_create() */
foc_decref(program);
- /* Make a scheduling decision. You might not get the process you created,
- * in the event there are others floating around that are runnable */
+ /* Make a scheduling decision. You might not get the process you
+ * created, in the event there are others floating around that are
+ * runnable */
run_scheduler();
/* want to idle, so we un the process we just selected. this is a bit
* hackish, but so is the monitor. */
@@ -433,8 +440,8 @@
printk("Function not found.\n");
return 1;
}
- /* Not elegant, but whatever. maybe there's a better syntax, or we can do
- * it with asm magic. */
+ /* Not elegant, but whatever. maybe there's a better syntax, or we can
+ * do it with asm magic. */
switch (argc) {
case 2: /* have to fake one arg */
ret = func((void*)0);
@@ -540,22 +547,24 @@
}
begin = start_timing();
#ifdef CONFIG_APPSERVER
- printk("Warning: this will be inaccurate due to the appserver.\n");
- end_refcnt = kref_refcnt(&p->p_kref) - p->procinfo->num_vcores - 1;
+ printk("Warning: inaccurate due to the appserver.\n");
+ end_refcnt = kref_refcnt(&p->p_kref) - p->procinfo->num_vcores
+ - 1;
#endif /* CONFIG_APPSERVER */
proc_destroy(p);
proc_decref(p);
#ifdef CONFIG_APPSERVER
- /* Won't be that accurate, since it's not actually going through the
- * __proc_free() path. */
+ /* Won't be that accurate, since it's not actually going through
+ * the __proc_free() path. */
spin_on(kref_refcnt(&p->p_kref) != end_refcnt);
#else
- /* this is a little ghetto. it's not fully free yet, but we are also
- * slowing it down by messing with it, esp with the busy waiting on a
- * hyperthreaded core. */
+ /* this is a little ghetto. it's not fully free yet, but we are
+ * also slowing it down by messing with it, esp with the busy
+ * waiting on a hyperthreaded core. */
spin_on(p->env_cr3);
#endif /* CONFIG_APPSERVER */
- /* No noticeable difference using stop_timing instead of read_tsc() */
+ /* No noticeable difference using stop_timing instead of
+ * read_tsc() */
diff = stop_timing(begin);
} else if (!strcmp(argv[1], "preempt")) {
if (argc < 3) {
@@ -567,19 +576,25 @@
printk("No such proc\n");
return 1;
}
- if (argc == 4) { /* single core being preempted, warned but no delay */
+ if (argc == 4) {
+ /* single core being preempted, warned but no delay */
uint32_t pcoreid = strtol(argv[3], 0, 0);
+
begin = start_timing();
if (proc_preempt_core(p, pcoreid, 1000000)) {
__sched_put_idle_core(p, pcoreid);
- /* done when unmapped (right before abandoning) */
+ /* done when unmapped (right before abandoning)
+ * */
spin_on(p->procinfo->pcoremap[pcoreid].valid);
} else {
- printk("Core %d was not mapped to proc\n", pcoreid);
+ printk("Core %d was not mapped to proc\n",
+ pcoreid);
}
diff = stop_timing(begin);
- } else { /* preempt all cores, warned but no delay */
- end_refcnt = kref_refcnt(&p->p_kref) - p->procinfo->num_vcores;
+ } else {
+ /* preempt all cores, warned but no delay */
+ end_refcnt = kref_refcnt(&p->p_kref)
+ - p->procinfo->num_vcores;
begin = start_timing();
proc_preempt_all(p, 1000000);
/* a little ghetto, implies no one is using p */
@@ -593,15 +608,20 @@
return 1;
}
struct proc *p = pid2proc(strtol(argv[2], 0, 0));
+
if (!p) {
printk("No such proc\n");
return 1;
}
- printk("Careful: if this hangs, then the process isn't responding.\n");
- if (argc == 4) { /* single core being preempted-warned */
+ printk("if this hangs, then the process isn't responding.\n");
+ if (argc == 4) {
+ /* single core being preempted-warned */
uint32_t pcoreid = strtol(argv[3], 0, 0);
+
spin_lock(&p->proc_lock);
- uint32_t vcoreid = p->procinfo->pcoremap[pcoreid].vcoreid;
+ uint32_t vcoreid =
+ p->procinfo->pcoremap[pcoreid].vcoreid;
+
if (!p->procinfo->pcoremap[pcoreid].valid) {
printk("Pick a mapped pcore\n");
spin_unlock(&p->proc_lock);
@@ -613,14 +633,15 @@
/* done when unmapped (right before abandoning) */
spin_on(p->procinfo->pcoremap[pcoreid].valid);
diff = stop_timing(begin);
- } else { /* preempt-warn all cores */
- printk("Warning, this won't work if they can't yield their "
- "last vcore, will stop at 1!\n");
+ } else {
+ /* preempt-warn all cores */
+ printk("this won't work if they can't yield their last vcore, will stop at 1!\n");
spin_lock(&p->proc_lock);
begin = start_timing();
__proc_preempt_warnall(p, 1000000);
spin_unlock(&p->proc_lock);
- /* target cores do the unmapping / changing of the num_vcores */
+ /* target cores do the unmapping / changing of the
+ * num_vcores */
spin_on(p->procinfo->num_vcores > 1);
diff = stop_timing(begin);
}
@@ -635,8 +656,10 @@
printk("No such proc\n");
return 1;
}
- if (argc == 4) { /* single core preempted, no warning or waiting */
+ if (argc == 4) {
+ /* single core preempted, no warning or waiting */
uint32_t pcoreid = strtol(argv[3], 0, 0);
+
spin_lock(&p->proc_lock);
if (!p->procinfo->pcoremap[pcoreid].valid) {
printk("Pick a mapped pcore\n");
@@ -648,16 +671,20 @@
if (!p->procinfo->num_vcores)
__proc_set_state(p, PROC_RUNNABLE_M);
spin_unlock(&p->proc_lock);
- /* ghetto, since the ksched should be calling all of this */
+ /* ghetto, since the ksched should be calling all of
+ * this */
__sched_put_idle_core(p, pcoreid);
/* done when unmapped (right before abandoning) */
spin_on(p->procinfo->pcoremap[pcoreid].valid);
diff = stop_timing(begin);
- } else { /* preempt all cores, no warning or waiting */
+ } else {
+ /* preempt all cores, no warning or waiting */
spin_lock(&p->proc_lock);
uint32_t pc_arr[p->procinfo->num_vcores];
uint32_t num_revoked;
- end_refcnt = kref_refcnt(&p->p_kref) - p->procinfo->num_vcores;
+
+ end_refcnt = kref_refcnt(&p->p_kref)
+ - p->procinfo->num_vcores;
begin = start_timing();
num_revoked = __proc_preempt_all(p, pc_arr);
__proc_set_state(p, PROC_RUNNABLE_M);
@@ -708,8 +735,8 @@
{
if (!PERCPU_VAR(mon_nmi_trace))
return;
- /* To prevent a spew of output during a lot of perf NMIs, we'll turn off the
- * monitor output as soon as any NMI hits our core. */
+ /* To prevent a spew of output during a lot of perf NMIs, we'll turn off
+ * the monitor output as soon as any NMI hits our core. */
PERCPU_VAR(mon_nmi_trace) = FALSE;
print_lock();
if (type == ROS_HW_CTX)
@@ -772,11 +799,13 @@
udelay(1000000);
} else if (!strcmp(argv[1], "pcpui")) {
int pcpui_type, pcpui_coreid;
+
if (argc >= 3)
pcpui_type = strtol(argv[2], 0, 0);
else
pcpui_type = 0;
- printk("\nRunning PCPUI Trace Ring handlers for type %d\n", pcpui_type);
+ printk("\nRunning PCPUI Trace Ring handlers for type %d\n",
+ pcpui_type);
if (argc >= 4) {
pcpui_coreid = strtol(argv[3], 0, 0);
pcpui_tr_foreach(pcpui_coreid, pcpui_type);
@@ -788,7 +817,7 @@
printk("\nResetting all PCPUI Trace Rings\n");
pcpui_tr_reset_all();
} else {
- printk("\nResetting and clearing all PCPUI Trace Rings\n");
+ printk("\nResetting/clearing all PCPUI Trace Rings\n");
pcpui_tr_reset_and_clear_all();
}
} else if (!strcmp(argv[1], "verbose")) {
@@ -858,7 +887,8 @@
// Parse the command buffer into whitespace-separated arguments
argc = 0;
argv[argc] = 0;
- /* Discard initial 'm ', which is a common mistake when using 'm' a lot */
+ /* Discard initial 'm ', which is a common mistake when using 'm' a lot
+ */
if ((buf[0] == 'm') && (buf[1] == ' '))
buf += 2;
while (1) {
@@ -900,9 +930,11 @@
/* they are always disabled, since we have this irqsave lock */
if (irq_is_enabled())
- printk("Entering Nanwan's Dungeon on Core %d (Ints on):\n", coreid);
+ printk("Entering Nanwan's Dungeon on Core %d (Ints on):\n",
+ coreid);
else
- printk("Entering Nanwan's Dungeon on Core %d (Ints off):\n", coreid);
+ printk("Entering Nanwan's Dungeon on Core %d (Ints off):\n",
+ coreid);
printk("Type 'help' for a list of commands.\n");
if (hw_tf != NULL)
@@ -910,9 +942,11 @@
while (1) {
/* on occasion, the kernel monitor can migrate (like if you run
- * something that blocks / syncs and wakes up on another core) */
+ * something that blocks / syncs and wakes up on another core)
+ */
cmb();
- cnt = readline(buf, MON_CMD_LENGTH, "ROS(Core %d)> ", core_id_early());
+ cnt = readline(buf, MON_CMD_LENGTH, "ROS(Core %d)> ",
+ core_id_early());
if (cnt > 0) {
buf[cnt] = 0;
if (runcmd(buf, hw_tf) < 0)
@@ -948,6 +982,7 @@
int core = core_id();
uint64_t val;
uint32_t msr = *(uint32_t *)v;
+
val = read_msr(msr);
printk("%d: %08x: %016llx\n", core, msr, val);
}
@@ -963,6 +998,7 @@
struct set *s = v;
uint32_t msr = s->msr;
uint64_t val = s->val;
+
write_msr(msr, val);
val = read_msr(msr);
printk("%d: %08x: %016llx\n", core, msr, val);
@@ -976,6 +1012,7 @@
#else
uint64_t val;
uint32_t msr;
+
if (argc < 2 || argc > 3) {
printk("Usage: msr register [value]\n");
return 1;
@@ -1006,7 +1043,7 @@
if (argc < 2) {
printk("Usage: db OPTION\n");
printk("\tblk [PID]: print all blocked kthreads\n");
- printk("\taddr PID 0xADDR: for PID lookup ADDR's file/vmr info\n");
+ printk("\taddr PID 0xADDR: lookup ADDR's file/vmr info\n");
printk("\trv WAITER: backtrace rendez alarm waiter\n");
return 1;
}
@@ -1025,7 +1062,8 @@
printk("Usage: db rv 0xWAITER\n");
return 1;
}
- rendez_debug_waiter((struct alarm_waiter*)strtoul(argv[2], 0, 16));
+ rendez_debug_waiter((struct alarm_waiter*)strtoul(argv[2], 0,
+ 16));
} else {
printk("Bad option\n");
return 1;
@@ -1069,8 +1107,8 @@
printk("Usage: kpfret HW_TF\n");
return 1;
}
- /* the hw_tf passed in is the one we got from monitor, which is 0 from
- * panics. */
+ /* the hw_tf passed in is the one we got from monitor, which is
+ * 0 from panics. */
hw_tf = (struct hw_trapframe*)strtol(argv[1], 0, 16);
}
@@ -1159,9 +1197,10 @@
pcpui->owning_vcoreid != 0xdeadbeef ? pcpui->owning_vcoreid : 0);
kth = pcpui->cur_kthread;
if (kth) {
- /* kth->proc is only used when the kthread is sleeping. when it's
- * running, we care about cur_proc. if we're here, proc should be 0
- * unless the kth is concurrently sleeping (we called this remotely) */
+ /* kth->proc is only used when the kthread is sleeping. when
+ * it's running, we care about cur_proc. if we're here, proc
+ * should be 0 unless the kth is concurrently sleeping (we
+ * called this remotely) */
printk("\tkthread %p (%s), sysc %p (%d)\n", kth, kth->name,
kth->sysc, kth->sysc ? kth->sysc->num : -1);
} else {
diff --git a/kern/src/multiboot.c b/kern/src/multiboot.c
index 2803eeb..b1e8a33 100644
--- a/kern/src/multiboot.c
+++ b/kern/src/multiboot.c
@@ -46,22 +46,22 @@
size_t basemem;
size_t extmem;
if (!(mbi->flags & MULTIBOOT_INFO_MEMORY)) {
- printk("No BIOS memory info from multiboot, crash impending!\n");
+ printk("No BIOS memory info from multiboot, crash impending\n");
return;
}
- /* mem_lower and upper are measured in KB. They are 32 bit values, so we're
- * limited to 4TB total. */
+ /* mem_lower and upper are measured in KB. They are 32 bit values, so
+ * we're limited to 4TB total. */
basemem = ROUNDDOWN((size_t)mbi->mem_lower * 1024, PGSIZE);
- /* On 32 bit, This shift << 10 could cause us to lose some memory, but we
- * weren't going to access it anyways (won't go beyond ~1GB) */
+ /* On 32 bit, This shift << 10 could cause us to lose some memory, but
+ * we weren't going to access it anyways (won't go beyond ~1GB) */
extmem = ROUNDDOWN((size_t)mbi->mem_upper * 1024, PGSIZE);
- /* Calculate the maximum physical address based on whether or not there is
- * any extended memory. */
+ /* Calculate the maximum physical address based on whether or not there
+ * is any extended memory. */
if (extmem) {
max_bios_mem = EXTPHYSMEM + extmem;
- /* On 32 bit, if we had enough RAM that adding a little wrapped us
- * around, we'll back off a little and run with just extmem amount (in
- * essence, subtracing 1MB). */
+ /* On 32 bit, if we had enough RAM that adding a little wrapped
+ * us around, we'll back off a little and run with just extmem
+ * amount (in essence, subtracing 1MB). */
if (max_bios_mem < extmem)
max_bios_mem = extmem;
} else {
@@ -72,8 +72,8 @@
extmem / 1024);
printk("Maximum directly addressable base and extended memory: %luK\n",
max_bios_addr / 1024);
- /* Take a first stab at the max pmem, in case there are no memory mappings
- * (like in riscv) */
+ /* Take a first stab at the max pmem, in case there are no memory
+ * mappings (like in riscv) */
max_pmem = max_bios_mem;
}
@@ -85,16 +85,18 @@
printd("No memory mapping info from multiboot\n");
return;
}
- mmap_b = (struct multiboot_mmap_entry*)((size_t)mbi->mmap_addr + KERNBASE);
- mmap_e = (struct multiboot_mmap_entry*)((size_t)mbi->mmap_addr + KERNBASE
- + mbi->mmap_length);
+ mmap_b = (struct multiboot_mmap_entry*)((size_t)mbi->mmap_addr +
+ KERNBASE);
+ mmap_e = (struct multiboot_mmap_entry*)((size_t)mbi->mmap_addr +
+ KERNBASE + mbi->mmap_length);
printd("mmap_addr = %p, mmap_length = %p\n", mbi->mmap_addr,
mbi->mmap_length);
/* Note when we incremement mmap_i, we add in the value of size... */
for (mmap_i = mmap_b;
mmap_i < mmap_e;
- mmap_i = (struct multiboot_mmap_entry*)((void*)mmap_i + mmap_i->size
- + sizeof(mmap_i->size))) {
+ mmap_i = (struct multiboot_mmap_entry*)((void*)mmap_i +
+ mmap_i->size +
+ sizeof(mmap_i->size))) {
func(mmap_i, data);
}
}
@@ -117,15 +119,13 @@
bool mboot_region_collides(struct multiboot_info *mbi, uintptr_t base,
uintptr_t end)
{
- if (regions_collide_unsafe((uintptr_t)mbi,
- (uintptr_t)mbi + sizeof(struct multiboot_info),
- base, end))
+ if (regions_collide_unsafe((uintptr_t)mbi, (uintptr_t)mbi +
+ sizeof(struct multiboot_info), base, end))
return TRUE;
if (mboot_has_mmaps(mbi)) {
if (regions_collide_unsafe((uintptr_t)mbi->mmap_addr + KERNBASE,
- (uintptr_t)mbi->mmap_addr + KERNBASE
- + mbi->mmap_length,
- base, end))
+ (uintptr_t)mbi->mmap_addr + KERNBASE
+ + mbi->mmap_length, base, end))
return TRUE;
}
return FALSE;
diff --git a/kern/src/net/arp.c b/kern/src/net/arp.c
index 2dbbabe..cff13bb 100644
--- a/kern/src/net/arp.c
+++ b/kern/src/net/arp.c
@@ -319,9 +319,9 @@
a->utime = NOW;
bp = a->hold;
a->hold = NULL;
- /* brho: it looks like we return the entire hold list, though it might be
- * purged by now via some other crazy arp list management. our callers
- * can't handle the arp's b->list stuff. */
+ /* brho: it looks like we return the entire hold list, though it might
+ * be purged by now via some other crazy arp list management. our
+ * callers can't handle the arp's b->list stuff. */
assert(!bp->list);
qunlock(&arp->qlock);
@@ -407,7 +407,8 @@
nexterror();
}
if (ifc->m != NULL)
- ifc->m->bwrite(ifc, bp, version, ip);
+ ifc->m->bwrite(ifc, bp, version,
+ ip);
else
freeb(bp);
runlock(&ifc->rwlock);
@@ -484,7 +485,8 @@
else
r = v6lookup(fs, ip, NULL);
if (r == NULL)
- error(EHOSTUNREACH, "Destination unreachable");
+ error(EHOSTUNREACH,
+ "Destination unreachable");
m = r->rt.ifc->m;
n = parsemac(mac, f[2], m->maclen);
break;
@@ -573,7 +575,8 @@
len--;
left--;
qlock(&arp->qlock);
- amt = snprintf(p + n, left, aformat, a->type->name, arpstate[a->state],
+ amt = snprintf(p + n, left, aformat, a->type->name,
+ arpstate[a->state],
a->ip, a->mac);
n += amt;
left -= amt;
diff --git a/kern/src/net/devip.c b/kern/src/net/devip.c
index 21cf1f8..d1f79b2 100644
--- a/kern/src/net/devip.c
+++ b/kern/src/net/devip.c
@@ -46,7 +46,7 @@
}
enum {
- Qtopdir = 1, /* top level directory */
+ Qtopdir = 1, /* top level directory */
Qtopbase,
Qarp = Qtopbase,
Qndb,
@@ -110,8 +110,8 @@
}
static inline int founddevdir(struct chan *c, struct qid q, char *n,
- int64_t length, char *user, long perm,
- struct dir *db)
+ int64_t length, char *user, long perm,
+ struct dir *db)
{
devdir(c, q, n, length, user, perm, db);
return 1;
@@ -120,6 +120,7 @@
static int topdirgen(struct chan *c, struct dir *dp)
{
struct qid q;
+
mkqid(&q, QID(0, 0, Qtopdir), 0, QTDIR);
snprintf(get_cur_genbuf(), GENBUF_SZ, "#%s%lu", devname(), c->dev);
return founddevdir(c, q, get_cur_genbuf(), 0, network, 0555, dp);
@@ -135,20 +136,21 @@
perm = cv->perm;
/* If there is ever a listener, then it's readable. Ideally, we'd only
* report this on the Qlisten file (which we also do). The socket crap
- * should never use a listening socket for data, so there shouldn't be any
- * confusion when a Qdata shows up as readable. */
+ * should never use a listening socket for data, so there shouldn't be
+ * any confusion when a Qdata shows up as readable. */
perm |= cv->incall ? DMREADABLE : 0;
/* For connectable convs, they need to be both connected and qio
- * readable/writable. The way to think about this is that the convs are not
- * truly writable/readable until they are connected. Conveniently, this
- * means that when select polls Qdata for non-blocking connect(), a
+ * readable/writable. The way to think about this is that the convs are
+ * not truly writable/readable until they are connected. Conveniently,
+ * this means that when select polls Qdata for non-blocking connect(), a
* connected conversation pops up as writable (the qio is writable too).
*
- * Note that a conversation can be 'Connected' even if it failed to connect.
- * At least that's what the 9ns TCP code does. It's more like "the protocol
- * did what it needed and the connectctlmsg call (or its non-blocking
- * equivalent) is done". For instance, TCP has a few reasons to call
- * Fsconnected, such as when we send the SYN and get a RST. */
+ * Note that a conversation can be 'Connected' even if it failed to
+ * connect. At least that's what the 9ns TCP code does. It's more like
+ * "the protocol did what it needed and the connectctlmsg call (or its
+ * non-blocking equivalent) is done". For instance, TCP has a few
+ * reasons to call Fsconnected, such as when we send the SYN and get a
+ * RST. */
if (!cv->p->connect || connected(cv)) {
perm |= qreadable(cv->rq) ? DMREADABLE : 0;
perm |= qwritable(cv->wq) ? DMWRITABLE : 0;
@@ -169,40 +171,39 @@
mkqid(&q, QID(PROTO(c->qid), CONV(c->qid), i), 0, QTFILE);
switch (i) {
- default:
+ default:
+ return -1;
+ case Qctl:
+ return founddevdir(c, q, "ctl", 0, cv->owner, cv->perm, dp);
+ case Qdata:
+ perm = qdata_stat_perm(cv);
+ return founddevdir(c, q, "data", qlen(cv->rq), cv->owner, perm,
+ dp);
+ case Qerr:
+ perm = cv->perm;
+ perm |= qreadable(cv->eq) ? DMREADABLE : 0;
+ return founddevdir(c, q, "err", qlen(cv->eq), cv->owner, perm,
+ dp);
+ case Qlisten:
+ perm = cv->perm;
+ perm |= cv->incall ? DMREADABLE : 0;
+ return founddevdir(c, q, "listen", 0, cv->owner, perm, dp);
+ case Qlocal:
+ p = "local";
+ break;
+ case Qremote:
+ p = "remote";
+ break;
+ case Qsnoop:
+ if (strcmp(cv->p->name, "ipifc") != 0)
return -1;
- case Qctl:
- return founddevdir(c, q, "ctl", 0,
- cv->owner, cv->perm, dp);
- case Qdata:
- perm = qdata_stat_perm(cv);
- return founddevdir(c, q, "data", qlen(cv->rq),
- cv->owner, perm, dp);
- case Qerr:
- perm = cv->perm;
- perm |= qreadable(cv->eq) ? DMREADABLE : 0;
- return founddevdir(c, q, "err", qlen(cv->eq),
- cv->owner, perm, dp);
- case Qlisten:
- perm = cv->perm;
- perm |= cv->incall ? DMREADABLE : 0;
- return founddevdir(c, q, "listen", 0, cv->owner, perm, dp);
- case Qlocal:
- p = "local";
- break;
- case Qremote:
- p = "remote";
- break;
- case Qsnoop:
- if (strcmp(cv->p->name, "ipifc") != 0)
- return -1;
- perm = 0400;
- perm |= qreadable(cv->sq) ? DMREADABLE : 0;
- return founddevdir(c, q, "snoop", qlen(cv->sq),
- cv->owner, perm, dp);
- case Qstatus:
- p = "status";
- break;
+ perm = 0400;
+ perm |= qreadable(cv->sq) ? DMREADABLE : 0;
+ return founddevdir(c, q, "snoop", qlen(cv->sq), cv->owner, perm,
+ dp);
+ case Qstatus:
+ p = "status";
+ break;
}
return founddevdir(c, q, p, 0, cv->owner, 0444, dp);
}
@@ -210,12 +211,13 @@
static int ip2gen(struct chan *c, int i, struct dir *dp)
{
struct qid q;
+
mkqid(&q, QID(PROTO(c->qid), 0, i), 0, QTFILE);
switch (i) {
- case Qclone:
- return founddevdir(c, q, "clone", 0, network, 0666, dp);
- case Qstats:
- return founddevdir(c, q, "stats", 0, network, 0444, dp);
+ case Qclone:
+ return founddevdir(c, q, "clone", 0, network, 0666, dp);
+ case Qstats:
+ return founddevdir(c, q, "stats", 0, network, 0444, dp);
}
return -1;
}
@@ -234,29 +236,29 @@
prot = 0666;
mkqid(&q, QID(0, 0, i), 0, QTFILE);
switch (i) {
- default:
- return -1;
- case Qarp:
- p = "arp";
- break;
- case Qndb:
- p = "ndb";
- len = strlen(f->ndb);
- q.vers = f->ndbvers;
- break;
- case Qiproute:
- p = "iproute";
- break;
- case Qipselftab:
- p = "ipselftab";
- prot = 0444;
- break;
- case Qiprouter:
- p = "iprouter";
- break;
- case Qlog:
- p = "log";
- break;
+ default:
+ return -1;
+ case Qarp:
+ p = "arp";
+ break;
+ case Qndb:
+ p = "ndb";
+ len = strlen(f->ndb);
+ q.vers = f->ndbvers;
+ break;
+ case Qiproute:
+ p = "iproute";
+ break;
+ case Qipselftab:
+ p = "ipselftab";
+ prot = 0444;
+ break;
+ case Qiprouter:
+ p = "iprouter";
+ break;
+ case Qlog:
+ p = "log";
+ break;
}
devdir(c, q, p, len, network, prot, dp);
if (i == Qndb && f->ndbmtime > kerndate)
@@ -264,9 +266,8 @@
return 1;
}
-static int
-ipgen(struct chan *c, char *unused_char_p_t, struct dirtab *d, int unused_int,
- int s, struct dir *dp)
+static int ipgen(struct chan *c, char *unused_char_p_t, struct dirtab *d,
+ int unused_int, int s, struct dir *dp)
{
struct qid q;
struct conv *cv;
@@ -275,56 +276,58 @@
f = ipfs[c->dev];
switch (TYPE(c->qid)) {
- case Qtopdir:
- if (s == DEVDOTDOT)
- return topdirgen(c, dp);
- if (s < f->np) {
- if (f->p[s]->connect == NULL)
- return 0; /* protocol with no user interface */
- mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR);
- return founddevdir(c, q, f->p[s]->name, 0, network, 0555, dp);
- }
- s -= f->np;
- return ip1gen(c, s + Qtopbase, dp);
- case Qarp:
- case Qndb:
- case Qlog:
- case Qiproute:
- case Qiprouter:
- case Qipselftab:
- return ip1gen(c, TYPE(c->qid), dp);
- case Qprotodir:
- if (s == DEVDOTDOT)
- return topdirgen(c, dp);
- else if (s < f->p[PROTO(c->qid)]->ac) {
- cv = f->p[PROTO(c->qid)]->conv[s];
- snprintf(get_cur_genbuf(), GENBUF_SZ, "%d", s);
- mkqid(&q, QID(PROTO(c->qid), s, Qconvdir), 0, QTDIR);
- return
- founddevdir(c, q, get_cur_genbuf(), 0, cv->owner, 0555, dp);
- }
- s -= f->p[PROTO(c->qid)]->ac;
- return ip2gen(c, s + Qprotobase, dp);
- case Qclone:
- case Qstats:
- return ip2gen(c, TYPE(c->qid), dp);
- case Qconvdir:
- if (s == DEVDOTDOT) {
- s = PROTO(c->qid);
- mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR);
- devdir(c, q, f->p[s]->name, 0, network, 0555, dp);
- return 1;
- }
- return ip3gen(c, s + Qconvbase, dp);
- case Qctl:
- case Qdata:
- case Qerr:
- case Qlisten:
- case Qlocal:
- case Qremote:
- case Qstatus:
- case Qsnoop:
- return ip3gen(c, TYPE(c->qid), dp);
+ case Qtopdir:
+ if (s == DEVDOTDOT)
+ return topdirgen(c, dp);
+ if (s < f->np) {
+ /* protocol with no user interface */
+ if (f->p[s]->connect == NULL)
+ return 0;
+ mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR);
+ return founddevdir(c, q, f->p[s]->name, 0, network,
+ 0555, dp);
+ }
+ s -= f->np;
+ return ip1gen(c, s + Qtopbase, dp);
+ case Qarp:
+ case Qndb:
+ case Qlog:
+ case Qiproute:
+ case Qiprouter:
+ case Qipselftab:
+ return ip1gen(c, TYPE(c->qid), dp);
+ case Qprotodir:
+ if (s == DEVDOTDOT)
+ return topdirgen(c, dp);
+ else if (s < f->p[PROTO(c->qid)]->ac) {
+ cv = f->p[PROTO(c->qid)]->conv[s];
+ snprintf(get_cur_genbuf(), GENBUF_SZ, "%d", s);
+ mkqid(&q, QID(PROTO(c->qid), s, Qconvdir), 0, QTDIR);
+ return founddevdir(c, q, get_cur_genbuf(), 0, cv->owner,
+ 0555, dp);
+ }
+ s -= f->p[PROTO(c->qid)]->ac;
+ return ip2gen(c, s + Qprotobase, dp);
+ case Qclone:
+ case Qstats:
+ return ip2gen(c, TYPE(c->qid), dp);
+ case Qconvdir:
+ if (s == DEVDOTDOT) {
+ s = PROTO(c->qid);
+ mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR);
+ devdir(c, q, f->p[s]->name, 0, network, 0555, dp);
+ return 1;
+ }
+ return ip3gen(c, s + Qconvbase, dp);
+ case Qctl:
+ case Qdata:
+ case Qerr:
+ case Qlisten:
+ case Qlocal:
+ case Qremote:
+ case Qstatus:
+ case Qsnoop:
+ return ip3gen(c, TYPE(c->qid), dp);
}
return -1;
}
@@ -450,162 +453,166 @@
f = ipfs[c->dev];
switch (TYPE(c->qid)) {
- default:
- break;
- case Qndb:
- if (omode & (O_WRITE | O_TRUNC) && !iseve())
- error(EPERM, ERROR_FIXME);
- if ((omode & (O_WRITE | O_TRUNC)) == (O_WRITE | O_TRUNC))
- f->ndb[0] = 0;
- break;
- case Qlog:
- netlogopen(f);
- break;
- case Qiprouter:
- iprouteropen(f);
- break;
- case Qiproute:
- c->synth_buf = kpages_zalloc(IPROUTE_LEN, MEM_WAIT);
- routeread(f, c->synth_buf, 0, IPROUTE_LEN);
- break;
- case Qtopdir:
- case Qprotodir:
- case Qconvdir:
- case Qstatus:
- case Qremote:
- case Qlocal:
- case Qstats:
- case Qipselftab:
- if (omode & O_WRITE)
- error(EPERM, ERROR_FIXME);
- break;
- case Qsnoop:
- if (omode & O_WRITE)
- error(EPERM, ERROR_FIXME);
- /* might be racy. note the lack of a proto lock, unlike Qdata */
- p = f->p[PROTO(c->qid)];
- cv = p->conv[CONV(c->qid)];
- if (strcmp(ATTACHER(c), cv->owner) != 0 && !iseve())
- error(EPERM, ERROR_FIXME);
- atomic_inc(&cv->snoopers);
- break;
- case Qclone:
- p = f->p[PROTO(c->qid)];
- qlock(&p->qlock);
- if (waserror()) {
- qunlock(&p->qlock);
- nexterror();
- }
- cv = Fsprotoclone(p, ATTACHER(c));
+ default:
+ break;
+ case Qndb:
+ if (omode & (O_WRITE | O_TRUNC) && !iseve())
+ error(EPERM, ERROR_FIXME);
+ if ((omode & (O_WRITE | O_TRUNC)) == (O_WRITE | O_TRUNC))
+ f->ndb[0] = 0;
+ break;
+ case Qlog:
+ netlogopen(f);
+ break;
+ case Qiprouter:
+ iprouteropen(f);
+ break;
+ case Qiproute:
+ c->synth_buf = kpages_zalloc(IPROUTE_LEN, MEM_WAIT);
+ routeread(f, c->synth_buf, 0, IPROUTE_LEN);
+ break;
+ case Qtopdir:
+ case Qprotodir:
+ case Qconvdir:
+ case Qstatus:
+ case Qremote:
+ case Qlocal:
+ case Qstats:
+ case Qipselftab:
+ if (omode & O_WRITE)
+ error(EPERM, ERROR_FIXME);
+ break;
+ case Qsnoop:
+ if (omode & O_WRITE)
+ error(EPERM, ERROR_FIXME);
+ /* might be racy. note the lack of a proto lock, unlike Qdata */
+ p = f->p[PROTO(c->qid)];
+ cv = p->conv[CONV(c->qid)];
+ if (strcmp(ATTACHER(c), cv->owner) != 0 && !iseve())
+ error(EPERM, ERROR_FIXME);
+ atomic_inc(&cv->snoopers);
+ break;
+ case Qclone:
+ p = f->p[PROTO(c->qid)];
+ qlock(&p->qlock);
+ if (waserror()) {
qunlock(&p->qlock);
- poperror();
- if (cv == NULL) {
- error(ENODEV, "Null conversation from Fsprotoclone");
- break;
- }
- mkqid(&c->qid, QID(p->x, cv->x, Qctl), 0, QTFILE);
+ nexterror();
+ }
+ cv = Fsprotoclone(p, ATTACHER(c));
+ qunlock(&p->qlock);
+ poperror();
+ if (cv == NULL) {
+ error(ENODEV, "Null conversation from Fsprotoclone");
break;
- case Qdata:
- case Qctl:
- case Qerr:
- p = f->p[PROTO(c->qid)];
- qlock(&p->qlock);
- cv = p->conv[CONV(c->qid)];
- qlock(&cv->qlock);
- if (waserror()) {
- qunlock(&cv->qlock);
- qunlock(&p->qlock);
- nexterror();
- }
- if ((perm & (cv->perm >> 6)) != perm) {
- if (strcmp(ATTACHER(c), cv->owner) != 0)
- error(EPERM, ERROR_FIXME);
- if ((perm & cv->perm) != perm)
- error(EPERM, ERROR_FIXME);
-
- }
- cv->inuse++;
- if (cv->inuse == 1) {
- kstrdup(&cv->owner, ATTACHER(c));
- cv->perm = 0660;
- }
+ }
+ mkqid(&c->qid, QID(p->x, cv->x, Qctl), 0, QTFILE);
+ break;
+ case Qdata:
+ case Qctl:
+ case Qerr:
+ p = f->p[PROTO(c->qid)];
+ qlock(&p->qlock);
+ cv = p->conv[CONV(c->qid)];
+ qlock(&cv->qlock);
+ if (waserror()) {
qunlock(&cv->qlock);
qunlock(&p->qlock);
- poperror();
- break;
- case Qlisten:
- cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)];
- /* No permissions or Announce checks required. We'll see if that's
- * a good idea or not. (the perm check would do nothing, as is,
- * since an O_PATH perm is 0).
- *
- * But we probably want to incref to keep the conversation around
- * until this FD/chan is closed. #ip is a little weird in that
- * objects never really go away (high water mark for convs, you can
- * always find them in the ns). I think it is possible to
- * namec/ipgen a chan, then have that conv close, then have that
- * chan be opened. You can probably do this with a data file. */
- if (omode & O_PATH) {
- qlock(&cv->qlock);
- cv->inuse++;
- qunlock(&cv->qlock);
- break;
- }
- if ((perm & (cv->perm >> 6)) != perm) {
- if (strcmp(ATTACHER(c), cv->owner) != 0)
- error(EPERM, ERROR_FIXME);
- if ((perm & cv->perm) != perm)
- error(EPERM, ERROR_FIXME);
+ nexterror();
+ }
+ if ((perm & (cv->perm >> 6)) != perm) {
+ if (strcmp(ATTACHER(c), cv->owner) != 0)
+ error(EPERM, ERROR_FIXME);
+ if ((perm & cv->perm) != perm)
+ error(EPERM, ERROR_FIXME);
- }
-
- if (cv->state != Announced)
- error(EFAIL, "not announced");
-
- if (waserror()) {
- closeconv(cv);
- nexterror();
- }
+ }
+ cv->inuse++;
+ if (cv->inuse == 1) {
+ kstrdup(&cv->owner, ATTACHER(c));
+ cv->perm = 0660;
+ }
+ qunlock(&cv->qlock);
+ qunlock(&p->qlock);
+ poperror();
+ break;
+ case Qlisten:
+ cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)];
+ /* No permissions or Announce checks required. We'll see if
+ * that's a good idea or not. (the perm check would do nothing,
+ * as is, since an O_PATH perm is 0).
+ *
+ * But we probably want to incref to keep the conversation
+ * around until this FD/chan is closed. #ip is a little weird
+ * in that objects never really go away (high water mark for
+ * convs, you can always find them in the ns). I think it is
+ * possible to namec/ipgen a chan, then have that conv close,
+ * then have that chan be opened. You can probably do this with
+ * a data file. */
+ if (omode & O_PATH) {
qlock(&cv->qlock);
cv->inuse++;
qunlock(&cv->qlock);
+ break;
+ }
+ if ((perm & (cv->perm >> 6)) != perm) {
+ if (strcmp(ATTACHER(c), cv->owner) != 0)
+ error(EPERM, ERROR_FIXME);
+ if ((perm & cv->perm) != perm)
+ error(EPERM, ERROR_FIXME);
- nc = NULL;
- while (nc == NULL) {
- /* give up if we got a hangup */
- if (qisclosed(cv->rq))
- error(EFAIL, "listen hungup");
+ }
- qlock(&cv->listenq);
- if (waserror()) {
- qunlock(&cv->listenq);
- nexterror();
- }
- /* we can peek at incall without grabbing the cv qlock. if
- * anything is there, it'll remain there until we dequeue it.
- * no one else can, since we hold the listenq lock */
- if ((c->flag & O_NONBLOCK) && !cv->incall)
- error(EAGAIN, "listen queue empty");
- /* wait for a connect */
- rendez_sleep(&cv->listenr, should_wake, cv);
+ if (cv->state != Announced)
+ error(EFAIL, "not announced");
- /* if there is a concurrent hangup, they will hold the qlock
- * until the hangup is complete, including closing the cv->rq */
- qlock(&cv->qlock);
- nc = cv->incall;
- if (nc != NULL) {
- cv->incall = nc->next;
- mkqid(&c->qid, QID(PROTO(c->qid), nc->x, Qctl), 0, QTFILE);
- kstrdup(&cv->owner, ATTACHER(c));
- }
- qunlock(&cv->qlock);
-
- qunlock(&cv->listenq);
- poperror();
- }
+ if (waserror()) {
closeconv(cv);
+ nexterror();
+ }
+ qlock(&cv->qlock);
+ cv->inuse++;
+ qunlock(&cv->qlock);
+
+ nc = NULL;
+ while (nc == NULL) {
+ /* give up if we got a hangup */
+ if (qisclosed(cv->rq))
+ error(EFAIL, "listen hungup");
+
+ qlock(&cv->listenq);
+ if (waserror()) {
+ qunlock(&cv->listenq);
+ nexterror();
+ }
+ /* we can peek at incall without grabbing the cv qlock.
+ * if anything is there, it'll remain there until we
+ * dequeue it. no one else can, since we hold the
+ * listenq lock */
+ if ((c->flag & O_NONBLOCK) && !cv->incall)
+ error(EAGAIN, "listen queue empty");
+ /* wait for a connect */
+ rendez_sleep(&cv->listenr, should_wake, cv);
+
+ /* if there is a concurrent hangup, they will hold the
+ * qlock until the hangup is complete, including closing
+ * the cv->rq */
+ qlock(&cv->qlock);
+ nc = cv->incall;
+ if (nc != NULL) {
+ cv->incall = nc->next;
+ mkqid(&c->qid, QID(PROTO(c->qid), nc->x, Qctl),
+ 0, QTFILE);
+ kstrdup(&cv->owner, ATTACHER(c));
+ }
+ qunlock(&cv->qlock);
+
+ qunlock(&cv->listenq);
poperror();
- break;
+ }
+ closeconv(cv);
+ poperror();
+ break;
}
c->mode = openmode(omode);
c->flag |= COPEN;
@@ -623,12 +630,12 @@
f = ipfs[c->dev];
switch (TYPE(c->qid)) {
- default:
- error(EPERM, ERROR_FIXME);
- break;
- case Qctl:
- case Qdata:
- break;
+ default:
+ error(EPERM, ERROR_FIXME);
+ break;
+ case Qctl:
+ case Qdata:
+ break;
}
d = kzmalloc(sizeof(*d) + n, 0);
@@ -663,44 +670,45 @@
f = ipfs[ch->dev];
switch (TYPE(ch->qid)) {
- default:
- ret = "Unknown type";
- break;
- case Qdata:
- proto = f->p[PROTO(ch->qid)];
- conv = proto->conv[CONV(ch->qid)];
- snprintf(ret, ret_l,
- "Qdata, %s, proto %s, conv idx %d, rq len %d, wq len %d, total read %llu",
- SLIST_EMPTY(&conv->data_taps) ? "untapped" : "tapped",
- proto->name, conv->x, qlen(conv->rq), qlen(conv->wq),
- q_bytes_read(conv->rq));
- break;
- case Qarp:
- ret = "Qarp";
- break;
- case Qiproute:
- ret = "Qiproute";
- break;
- case Qlisten:
- proto = f->p[PROTO(ch->qid)];
- conv = proto->conv[CONV(ch->qid)];
- snprintf(ret, ret_l,
- "Qlisten, %s proto %s, conv idx %d, has %sincalls",
- SLIST_EMPTY(&conv->listen_taps) ? "untapped" : "tapped",
- proto->name, conv->x, conv->incall ? "" : "no ");
- break;
- case Qlog:
- ret = "Qlog";
- break;
- case Qndb:
- ret = "Qndb";
- break;
- case Qctl:
- proto = f->p[PROTO(ch->qid)];
- conv = proto->conv[CONV(ch->qid)];
- snprintf(ret, ret_l, "Qctl, proto %s, conv idx %d", proto->name,
- conv->x);
- break;
+ default:
+ ret = "Unknown type";
+ break;
+ case Qdata:
+ proto = f->p[PROTO(ch->qid)];
+ conv = proto->conv[CONV(ch->qid)];
+ snprintf(ret, ret_l,
+ "Qdata, %s, proto %s, conv idx %d, rq len %d, wq len %d, total read %llu",
+ SLIST_EMPTY(&conv->data_taps) ? "untapped" : "tapped",
+ proto->name, conv->x, qlen(conv->rq), qlen(conv->wq),
+ q_bytes_read(conv->rq));
+ break;
+ case Qarp:
+ ret = "Qarp";
+ break;
+ case Qiproute:
+ ret = "Qiproute";
+ break;
+ case Qlisten:
+ proto = f->p[PROTO(ch->qid)];
+ conv = proto->conv[CONV(ch->qid)];
+ snprintf(ret, ret_l,
+ "Qlisten, %s proto %s, conv idx %d, has %sincalls",
+ SLIST_EMPTY(&conv->listen_taps) ? "untapped"
+ : "tapped",
+ proto->name, conv->x, conv->incall ? "" : "no ");
+ break;
+ case Qlog:
+ ret = "Qlog";
+ break;
+ case Qndb:
+ ret = "Qndb";
+ break;
+ case Qctl:
+ proto = f->p[PROTO(ch->qid)];
+ conv = proto->conv[CONV(ch->qid)];
+ snprintf(ret, ret_l, "Qctl, proto %s, conv idx %d", proto->name,
+ conv->x);
+ break;
}
return ret;
}
@@ -750,33 +758,33 @@
f = ipfs[c->dev];
switch (TYPE(c->qid)) {
- default:
- break;
- case Qlog:
- if (c->flag & COPEN)
- netlogclose(f);
- break;
- case Qiprouter:
- if (c->flag & COPEN)
- iprouterclose(f);
- break;
- case Qdata:
- case Qctl:
- case Qerr:
- case Qlisten:
- if (c->flag & COPEN)
- closeconv(f->p[PROTO(c->qid)]->conv[CONV(c->qid)]);
- break;
- case Qsnoop:
- if (c->flag & COPEN)
- atomic_dec(&f->p[PROTO(c->qid)]->conv[CONV(c->qid)]->snoopers);
- break;
- case Qiproute:
- if (c->flag & COPEN) {
- kpages_free(c->synth_buf, IPROUTE_LEN);
- c->synth_buf = NULL;
- }
- break;
+ default:
+ break;
+ case Qlog:
+ if (c->flag & COPEN)
+ netlogclose(f);
+ break;
+ case Qiprouter:
+ if (c->flag & COPEN)
+ iprouterclose(f);
+ break;
+ case Qdata:
+ case Qctl:
+ case Qerr:
+ case Qlisten:
+ if (c->flag & COPEN)
+ closeconv(f->p[PROTO(c->qid)]->conv[CONV(c->qid)]);
+ break;
+ case Qsnoop:
+ if (c->flag & COPEN)
+ atomic_dec(&f->p[PROTO(c->qid)]->conv[CONV(c->qid)]->snoopers);
+ break;
+ case Qiproute:
+ if (c->flag & COPEN) {
+ kpages_free(c->synth_buf, IPROUTE_LEN);
+ c->synth_buf = NULL;
+ }
+ break;
}
kfree(((struct IPaux *)c->aux)->owner);
kfree(c->aux);
@@ -799,88 +807,89 @@
p = a;
switch (TYPE(ch->qid)) {
- default:
- error(EPERM, ERROR_FIXME);
- case Qtopdir:
- case Qprotodir:
- case Qconvdir:
- return devdirread(ch, a, n, 0, 0, ipgen);
- case Qarp:
- return arpread(f->arp, a, offset, n);
- case Qndb:
- return readstr(offset, a, n, f->ndb);
- case Qiproute:
- return readmem(offset, a, n, ch->synth_buf, IPROUTE_LEN);
- case Qiprouter:
- return iprouterread(f, a, n);
- case Qipselftab:
- return ipselftabread(f, a, offset, n);
- case Qlog:
- return netlogread(f, a, offset, n);
- case Qctl:
- snprintf(get_cur_genbuf(), GENBUF_SZ, "%lu", CONV(ch->qid));
- return readstr(offset, p, n, get_cur_genbuf());
- case Qremote:
- buf = kzmalloc(Statelen, 0);
- x = f->p[PROTO(ch->qid)];
- c = x->conv[CONV(ch->qid)];
- if (x->remote == NULL) {
- snprintf(buf, Statelen, "%I!%d\n", c->raddr, c->rport);
- } else {
- (*x->remote) (c, buf, Statelen - 2);
- }
- rv = readstr(offset, p, n, buf);
- kfree(buf);
- return rv;
- case Qlocal:
- buf = kzmalloc(Statelen, 0);
- x = f->p[PROTO(ch->qid)];
- c = x->conv[CONV(ch->qid)];
- if (x->local == NULL) {
- snprintf(buf, Statelen, "%I!%d\n", c->laddr, c->lport);
- } else {
- (*x->local) (c, buf, Statelen - 2);
- }
- rv = readstr(offset, p, n, buf);
- kfree(buf);
- return rv;
- case Qstatus:
- /* this all is a bit screwed up since the size of some state's
- * buffers will change from one invocation to another. a reader
- * will come in and read the entire buffer. then it will come again
- * and read from the next offset, expecting EOF. if the buffer
- * changed sizes, it'll reprint the end of the buffer slightly. */
- buf = kzmalloc(Statelen, 0);
- x = f->p[PROTO(ch->qid)];
- c = x->conv[CONV(ch->qid)];
- if (c->state == Bypass)
- snprintf(buf, Statelen, "Bypassed\n");
- else
- (*x->state)(c, buf, Statelen - 2);
- rv = readstr(offset, p, n, buf);
- kfree(buf);
- return rv;
- case Qdata:
- c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
- if (ch->flag & O_NONBLOCK)
- return qread_nonblock(c->rq, a, n);
- else
- return qread(c->rq, a, n);
- case Qerr:
- c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
- return qread(c->eq, a, n);
- case Qsnoop:
- c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
- return qread(c->sq, a, n);
- case Qstats:
- x = f->p[PROTO(ch->qid)];
- if (x->stats == NULL)
- error(EFAIL, "stats not implemented");
- buf = kzmalloc(Statelen, 0);
- (*x->stats) (x, buf, Statelen);
- rv = readstr(offset, p, n, buf);
- kfree(buf);
- return rv;
+ default:
+ error(EPERM, ERROR_FIXME);
+ case Qtopdir:
+ case Qprotodir:
+ case Qconvdir:
+ return devdirread(ch, a, n, 0, 0, ipgen);
+ case Qarp:
+ return arpread(f->arp, a, offset, n);
+ case Qndb:
+ return readstr(offset, a, n, f->ndb);
+ case Qiproute:
+ return readmem(offset, a, n, ch->synth_buf, IPROUTE_LEN);
+ case Qiprouter:
+ return iprouterread(f, a, n);
+ case Qipselftab:
+ return ipselftabread(f, a, offset, n);
+ case Qlog:
+ return netlogread(f, a, offset, n);
+ case Qctl:
+ snprintf(get_cur_genbuf(), GENBUF_SZ, "%lu", CONV(ch->qid));
+ return readstr(offset, p, n, get_cur_genbuf());
+ case Qremote:
+ buf = kzmalloc(Statelen, 0);
+ x = f->p[PROTO(ch->qid)];
+ c = x->conv[CONV(ch->qid)];
+ if (x->remote == NULL) {
+ snprintf(buf, Statelen, "%I!%d\n", c->raddr, c->rport);
+ } else {
+ (*x->remote) (c, buf, Statelen - 2);
+ }
+ rv = readstr(offset, p, n, buf);
+ kfree(buf);
+ return rv;
+ case Qlocal:
+ buf = kzmalloc(Statelen, 0);
+ x = f->p[PROTO(ch->qid)];
+ c = x->conv[CONV(ch->qid)];
+ if (x->local == NULL) {
+ snprintf(buf, Statelen, "%I!%d\n", c->laddr, c->lport);
+ } else {
+ (*x->local) (c, buf, Statelen - 2);
+ }
+ rv = readstr(offset, p, n, buf);
+ kfree(buf);
+ return rv;
+ case Qstatus:
+ /* this all is a bit screwed up since the size of some state's
+ * buffers will change from one invocation to another. a reader
+ * will come in and read the entire buffer. then it will come
+ * again and read from the next offset, expecting EOF. if the
+ * buffer changed sizes, it'll reprint the end of the buffer
+ * slightly. */
+ buf = kzmalloc(Statelen, 0);
+ x = f->p[PROTO(ch->qid)];
+ c = x->conv[CONV(ch->qid)];
+ if (c->state == Bypass)
+ snprintf(buf, Statelen, "Bypassed\n");
+ else
+ (*x->state)(c, buf, Statelen - 2);
+ rv = readstr(offset, p, n, buf);
+ kfree(buf);
+ return rv;
+ case Qdata:
+ c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
+ if (ch->flag & O_NONBLOCK)
+ return qread_nonblock(c->rq, a, n);
+ else
+ return qread(c->rq, a, n);
+ case Qerr:
+ c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
+ return qread(c->eq, a, n);
+ case Qsnoop:
+ c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
+ return qread(c->sq, a, n);
+ case Qstats:
+ x = f->p[PROTO(ch->qid)];
+ if (x->stats == NULL)
+ error(EFAIL, "stats not implemented");
+ buf = kzmalloc(Statelen, 0);
+ (*x->stats) (x, buf, Statelen);
+ rv = readstr(offset, p, n, buf);
+ kfree(buf);
+ return rv;
}
}
@@ -889,14 +898,14 @@
struct conv *c;
switch (TYPE(ch->qid)) {
- case Qdata:
- c = chan2conv(ch);
- if (ch->flag & O_NONBLOCK)
- return qbread_nonblock(c->rq, n);
- else
- return qbread(c->rq, n);
- default:
- return devbread(ch, n, offset);
+ case Qdata:
+ c = chan2conv(ch);
+ if (ch->flag & O_NONBLOCK)
+ return qbread_nonblock(c->rq, n);
+ else
+ return qbread(c->rq, n);
+ default:
+ return devbread(ch, n, offset);
}
}
@@ -959,10 +968,10 @@
/*
* Fsproto initialises p->nextport to 0 and the restricted
* ports (p->nextrport) to 600.
- * Restricted ports must lie between 600 and 1024.
- * For the initial condition or if the unrestricted port number
- * has wrapped round, select a random port between 5000 and 1<<15
- * to start at.
+ * Restricted ports must lie between 600 and 1024. For the
+ * initial condition or if the unrestricted port number has
+ * wrapped round, select a random port between 5000 and 1<<15 to
+ * start at.
*/
if (c->restricted) {
if (*pp >= 1024)
@@ -1064,17 +1073,17 @@
void Fsstdconnect(struct conv *c, char *argv[], int argc)
{
switch (argc) {
- default:
- error(EINVAL, "bad args to %s", __func__);
- case 2:
- setraddrport(c, argv[1]);
- setladdr(c);
- setlport(c);
- break;
- case 3:
- setraddrport(c, argv[1]);
- setladdrport(c, argv[2], 0);
- break;
+ default:
+ error(EINVAL, "bad args to %s", __func__);
+ case 2:
+ setraddrport(c, argv[1]);
+ setladdr(c);
+ setlport(c);
+ break;
+ case 3:
+ setraddrport(c, argv[1]);
+ setladdrport(c, argv[2], 0);
+ break;
}
/* TODO: why is an IPnoaddr (in v6 format, equivalent to v6Unspecified),
@@ -1111,20 +1120,20 @@
c->cerr[0] = '\0';
if (x->connect == NULL)
error(EFAIL, "connect not supported");
- /* It's up to the proto connect method to not block the kthread. This is
- * currently the case for e.g. TCP. */
+ /* It's up to the proto connect method to not block the kthread. This
+ * is currently the case for e.g. TCP. */
x->connect(c, cb->f, cb->nf);
- /* This is notionally right before the rendez_sleep: either we block or we
- * kick back to userspace. We do this before the unlock to avoid races with
- * c->state (rendez's internal lock deals with its race with the waker) and
- * to avoid the excessive unlock and relock.
+ /* This is notionally right before the rendez_sleep: either we block or
+ * we kick back to userspace. We do this before the unlock to avoid
+ * races with c->state (rendez's internal lock deals with its race with
+ * the waker) and to avoid the excessive unlock and relock.
*
* Also, it's important that we don't do anything important for the
- * functionality of the conv after the rendez sleep. The non-blocking style
- * won't call back into the kernel - it just wants the event. I considered
- * allowing multiple connect calls, where we just return if it was already
- * connected, but that would break UDP, which allows multiple different
- * connect calls. */
+ * functionality of the conv after the rendez sleep. The non-blocking
+ * style won't call back into the kernel - it just wants the event. I
+ * considered allowing multiple connect calls, where we just return if
+ * it was already connected, but that would break UDP, which allows
+ * multiple different connect calls. */
if ((chan->flag & O_NONBLOCK) && !connected(c))
error(EINPROGRESS, "connection not ready yet");
qunlock(&c->qlock);
@@ -1148,11 +1157,11 @@
memset(c->raddr, 0, sizeof(c->raddr));
c->rport = 0;
switch (argc) {
- default:
- error(EINVAL, "bad args to announce");
- case 2:
- setladdrport(c, argv[1], 1);
- break;
+ default:
+ error(EINVAL, "bad args to announce");
+ case 2:
+ setladdrport(c, argv[1], 1);
+ break;
}
}
@@ -1196,11 +1205,11 @@
void Fsstdbind(struct conv *c, char *argv[], int argc)
{
switch (argc) {
- default:
- error(EINVAL, "bad args to bind");
- case 2:
- setladdrport(c, argv[1], 0);
- break;
+ default:
+ error(EINVAL, "bad args to bind");
+ case 2:
+ setladdrport(c, argv[1], 0);
+ break;
}
}
@@ -1257,13 +1266,15 @@
case IP_VER4:
bp = pullupblock(bp, IPV4HDR_LEN);
if (!bp)
- error(EINVAL, "Proto bypass unable to pullup v4 header");
+ error(EINVAL,
+ "Proto bypass unable to pullup v4 header");
ipoput4(f, bp, FALSE, MAXTTL, DFLTTOS, NULL);
break;
case IP_VER6:
bp = pullupblock(bp, IPV6HDR_LEN);
if (!bp)
- error(EINVAL, "Proto bypass unable to pullup v6 header");
+ error(EINVAL,
+ "Proto bypass unable to pullup v6 header");
ipoput6(f, bp, FALSE, MAXTTL, DFLTTOS, NULL);
break;
default:
@@ -1334,9 +1345,9 @@
{
if (!x->bypass)
error(EFAIL, "Protocol %s does not support bypass", x->name);
- /* The protocol needs to set the port (usually by calling Fsstdbypass) and
- * then do whatever it needs to make sure it can find the conv again during
- * receive (usually by adding to a hash table). */
+ /* The protocol needs to set the port (usually by calling Fsstdbypass)
+ * and then do whatever it needs to make sure it can find the conv again
+ * during receive (usually by adding to a hash table). */
x->bypass(cv, cb->f, cb->nf);
setup_proto_qio_bypass(cv);
cv->state = Bypass;
@@ -1414,87 +1425,90 @@
f = ipfs[ch->dev];
switch (TYPE(ch->qid)) {
- default:
- error(EPERM, ERROR_FIXME);
- case Qdata:
- x = f->p[PROTO(ch->qid)];
- c = x->conv[CONV(ch->qid)];
- /* connection-less protocols (UDP) can write without manually
- * binding. */
- if (c->lport == 0)
- autobind(c);
- if (ch->flag & O_NONBLOCK)
- qwrite_nonblock(c->wq, a, n);
- else
- qwrite(c->wq, a, n);
- break;
- case Qarp:
- return arpwrite(f, a, n);
- case Qiproute:
- return routewrite(f, ch, a, n);
- case Qlog:
- netlogctl(f, a, n);
- return n;
- case Qndb:
- return ndbwrite(f, a, off, n);
- case Qctl:
- x = f->p[PROTO(ch->qid)];
- c = x->conv[CONV(ch->qid)];
- cb = parsecmd(a, n);
+ default:
+ error(EPERM, ERROR_FIXME);
+ case Qdata:
+ x = f->p[PROTO(ch->qid)];
+ c = x->conv[CONV(ch->qid)];
+ /* connection-less protocols (UDP) can write without manually
+ * binding. */
+ if (c->lport == 0)
+ autobind(c);
+ if (ch->flag & O_NONBLOCK)
+ qwrite_nonblock(c->wq, a, n);
+ else
+ qwrite(c->wq, a, n);
+ break;
+ case Qarp:
+ return arpwrite(f, a, n);
+ case Qiproute:
+ return routewrite(f, ch, a, n);
+ case Qlog:
+ netlogctl(f, a, n);
+ return n;
+ case Qndb:
+ return ndbwrite(f, a, off, n);
+ case Qctl:
+ x = f->p[PROTO(ch->qid)];
+ c = x->conv[CONV(ch->qid)];
+ cb = parsecmd(a, n);
- qlock(&c->qlock);
- if (waserror()) {
- qunlock(&c->qlock);
- kfree(cb);
- nexterror();
- }
- if (cb->nf < 1)
- error(EFAIL, "short control request");
- if (strcmp(cb->f[0], "connect") == 0)
- connectctlmsg(x, c, cb, ch);
- else if (strcmp(cb->f[0], "announce") == 0)
- announcectlmsg(x, c, cb);
- else if (strcmp(cb->f[0], "bind") == 0)
- bindctlmsg(x, c, cb);
- else if (strcmp(cb->f[0], "bypass") == 0)
- bypassctlmsg(x, c, cb);
- else if (strcmp(cb->f[0], "shutdown") == 0)
- shutdownctlmsg(c, cb);
- else if (strcmp(cb->f[0], "ttl") == 0)
- ttlctlmsg(c, cb);
- else if (strcmp(cb->f[0], "tos") == 0)
- tosctlmsg(c, cb);
- else if (strcmp(cb->f[0], "ignoreadvice") == 0)
- c->ignoreadvice = 1;
- else if (strcmp(cb->f[0], "addmulti") == 0) {
- if (cb->nf < 2)
- error(EFAIL, "addmulti needs interface address");
- if (cb->nf == 2) {
- if (!ipismulticast(c->raddr))
- error(EFAIL, "addmulti for a non multicast address");
- parseip(ia, cb->f[1]);
- ipifcaddmulti(c, c->raddr, ia);
- } else {
- parseip(ma, cb->f[2]);
- if (!ipismulticast(ma))
- error(EFAIL, "addmulti for a non multicast address");
- parseip(ia, cb->f[1]);
- ipifcaddmulti(c, ma, ia);
- }
- } else if (strcmp(cb->f[0], "remmulti") == 0) {
- if (cb->nf < 2)
- error(EFAIL, "remmulti needs interface address");
- if (!ipismulticast(c->raddr))
- error(EFAIL, "remmulti for a non multicast address");
- parseip(ia, cb->f[1]);
- ipifcremmulti(c, c->raddr, ia);
- } else if (x->ctl != NULL) {
- x->ctl(c, cb->f, cb->nf);
- } else
- error(EFAIL, "unknown control request");
+ qlock(&c->qlock);
+ if (waserror()) {
qunlock(&c->qlock);
kfree(cb);
- poperror();
+ nexterror();
+ }
+ if (cb->nf < 1)
+ error(EFAIL, "short control request");
+ if (strcmp(cb->f[0], "connect") == 0)
+ connectctlmsg(x, c, cb, ch);
+ else if (strcmp(cb->f[0], "announce") == 0)
+ announcectlmsg(x, c, cb);
+ else if (strcmp(cb->f[0], "bind") == 0)
+ bindctlmsg(x, c, cb);
+ else if (strcmp(cb->f[0], "bypass") == 0)
+ bypassctlmsg(x, c, cb);
+ else if (strcmp(cb->f[0], "shutdown") == 0)
+ shutdownctlmsg(c, cb);
+ else if (strcmp(cb->f[0], "ttl") == 0)
+ ttlctlmsg(c, cb);
+ else if (strcmp(cb->f[0], "tos") == 0)
+ tosctlmsg(c, cb);
+ else if (strcmp(cb->f[0], "ignoreadvice") == 0)
+ c->ignoreadvice = 1;
+ else if (strcmp(cb->f[0], "addmulti") == 0) {
+ if (cb->nf < 2)
+ error(EFAIL,
+ "addmulti needs interface address");
+ if (cb->nf == 2) {
+ if (!ipismulticast(c->raddr))
+ error(EFAIL, "addmulti for a non multicast address");
+ parseip(ia, cb->f[1]);
+ ipifcaddmulti(c, c->raddr, ia);
+ } else {
+ parseip(ma, cb->f[2]);
+ if (!ipismulticast(ma))
+ error(EFAIL, "addmulti for a non multicast address");
+ parseip(ia, cb->f[1]);
+ ipifcaddmulti(c, ma, ia);
+ }
+ } else if (strcmp(cb->f[0], "remmulti") == 0) {
+ if (cb->nf < 2)
+ error(EFAIL,
+ "remmulti needs interface address");
+ if (!ipismulticast(c->raddr))
+ error(EFAIL,
+ "remmulti for a non multicast address");
+ parseip(ia, cb->f[1]);
+ ipifcremmulti(c, c->raddr, ia);
+ } else if (x->ctl != NULL) {
+ x->ctl(c, cb->f, cb->nf);
+ } else
+ error(EFAIL, "unknown control request");
+ qunlock(&c->qlock);
+ kfree(cb);
+ poperror();
}
return n;
}
@@ -1505,18 +1519,18 @@
size_t n;
switch (TYPE(ch->qid)) {
- case Qdata:
- c = chan2conv(ch);
- if (bp->next)
- bp = concatblock(bp);
- n = BLEN(bp);
- if (ch->flag & O_NONBLOCK)
- qbwrite_nonblock(c->wq, bp);
- else
- qbwrite(c->wq, bp);
- return n;
- default:
- return devbwrite(ch, bp, offset);
+ case Qdata:
+ c = chan2conv(ch);
+ if (bp->next)
+ bp = concatblock(bp);
+ n = BLEN(bp);
+ if (ch->flag & O_NONBLOCK)
+ qbwrite_nonblock(c->wq, bp);
+ else
+ qbwrite(c->wq, bp);
+ return n;
+ default:
+ return devbwrite(ch, bp, offset);
}
}
@@ -1527,17 +1541,17 @@
/* At this point, we have an event we want to send to our taps (if any).
* The lock protects list integrity and the existence of the tap.
*
- * Previously, I thought of using the conv qlock. That actually breaks, due
- * to weird usages of the qlock (someone holds it for a long time, blocking
- * the inbound wakeup from etherread4).
+ * Previously, I thought of using the conv qlock. That actually breaks,
+ * due to weird usages of the qlock (someone holds it for a long time,
+ * blocking the inbound wakeup from etherread4).
*
* I opted for a spinlock for a couple reasons:
- * - fire_tap should not block. ideally it'll be fast too (it's mostly a
- * send_event).
+ * - fire_tap should not block. ideally it'll be fast too (it's mostly
+ * a send_event).
* - our callers might not want to block. A lot of network wakeups will
* come network processes (etherread4) or otherwise unrelated to this
- * particular conversation. I'd rather do something like fire off a KMSG
- * than block those.
+ * particular conversation. I'd rather do something like fire off a
+ * KMSG than block those.
* - if fire_tap takes a while, holding the lock only slows down other
* events on this *same* conversation, or other tap registration. not a
* huge deal. */
@@ -1553,9 +1567,9 @@
/* For these two, we want to ignore events on the opposite end of the
* queues. For instance, we want to know when the WQ is writable. Our
- * writes will actually make it readable - we don't want to trigger a tap
- * for that. However, qio doesn't know how/why we are using a queue, or
- * even who the ends are (hence the callbacks) */
+ * writes will actually make it readable - we don't want to trigger a
+ * tap for that. However, qio doesn't know how/why we are using a
+ * queue, or even who the ends are (hence the callbacks) */
if ((filter & FDTAP_FILT_READABLE) && (q == conv->wq))
return;
if ((filter & FDTAP_FILT_WRITABLE) && (q == conv->rq))
@@ -1568,75 +1582,77 @@
struct conv *conv = chan2conv(chan);
int ret;
- #define DEVIP_LEGAL_DATA_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_WRITABLE | \
- FDTAP_FILT_HANGUP | FDTAP_FILT_PRIORITY | \
- FDTAP_FILT_ERROR)
- #define DEVIP_LEGAL_LISTEN_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_HANGUP)
+#define DEVIP_LEGAL_DATA_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_WRITABLE | \
+ FDTAP_FILT_HANGUP | FDTAP_FILT_PRIORITY | \
+ FDTAP_FILT_ERROR)
+#define DEVIP_LEGAL_LISTEN_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_HANGUP)
switch (TYPE(chan->qid)) {
- case Qdata:
- if (tap->filter & ~DEVIP_LEGAL_DATA_TAPS) {
- set_errno(ENOSYS);
- set_errstr("Unsupported #%s data tap %p, must be %p", devname(),
- tap->filter, DEVIP_LEGAL_DATA_TAPS);
- return -1;
+ case Qdata:
+ if (tap->filter & ~DEVIP_LEGAL_DATA_TAPS) {
+ set_errno(ENOSYS);
+ set_errstr("Unsupported #%s data tap %p, must be %p",
+ devname(), tap->filter,
+ DEVIP_LEGAL_DATA_TAPS);
+ return -1;
+ }
+ spin_lock(&conv->tap_lock);
+ switch (cmd) {
+ case (FDTAP_CMD_ADD):
+ if (SLIST_EMPTY(&conv->data_taps)) {
+ qio_set_wake_cb(conv->rq, ip_wake_cb, conv);
+ qio_set_wake_cb(conv->wq, ip_wake_cb, conv);
}
- spin_lock(&conv->tap_lock);
- switch (cmd) {
- case (FDTAP_CMD_ADD):
- if (SLIST_EMPTY(&conv->data_taps)) {
- qio_set_wake_cb(conv->rq, ip_wake_cb, conv);
- qio_set_wake_cb(conv->wq, ip_wake_cb, conv);
- }
- SLIST_INSERT_HEAD(&conv->data_taps, tap, link);
- ret = 0;
- break;
- case (FDTAP_CMD_REM):
- SLIST_REMOVE(&conv->data_taps, tap, fd_tap, link);
- if (SLIST_EMPTY(&conv->data_taps)) {
- qio_set_wake_cb(conv->rq, 0, conv);
- qio_set_wake_cb(conv->wq, 0, conv);
- }
- ret = 0;
- break;
- default:
- set_errno(ENOSYS);
- set_errstr("Unsupported #%s data tap command %p",
- devname(), cmd);
- ret = -1;
+ SLIST_INSERT_HEAD(&conv->data_taps, tap, link);
+ ret = 0;
+ break;
+ case (FDTAP_CMD_REM):
+ SLIST_REMOVE(&conv->data_taps, tap, fd_tap, link);
+ if (SLIST_EMPTY(&conv->data_taps)) {
+ qio_set_wake_cb(conv->rq, 0, conv);
+ qio_set_wake_cb(conv->wq, 0, conv);
}
- spin_unlock(&conv->tap_lock);
- return ret;
- case Qlisten:
- if (tap->filter & ~DEVIP_LEGAL_LISTEN_TAPS) {
- set_errno(ENOSYS);
- set_errstr("Unsupported #%s listen tap %p, must be %p",
- devname(), tap->filter, DEVIP_LEGAL_LISTEN_TAPS);
- return -1;
- }
- spin_lock(&conv->tap_lock);
- switch (cmd) {
- case (FDTAP_CMD_ADD):
- SLIST_INSERT_HEAD(&conv->listen_taps, tap, link);
- ret = 0;
- break;
- case (FDTAP_CMD_REM):
- SLIST_REMOVE(&conv->listen_taps, tap, fd_tap, link);
- ret = 0;
- break;
- default:
- set_errno(ENOSYS);
- set_errstr("Unsupported #%s listen tap command %p",
- devname(), cmd);
- ret = -1;
- }
- spin_unlock(&conv->tap_lock);
- return ret;
+ ret = 0;
+ break;
default:
set_errno(ENOSYS);
- set_errstr("Can't tap #%s file type %d", devname(),
- TYPE(chan->qid));
+ set_errstr("Unsupported #%s data tap command %p",
+ devname(), cmd);
+ ret = -1;
+ }
+ spin_unlock(&conv->tap_lock);
+ return ret;
+ case Qlisten:
+ if (tap->filter & ~DEVIP_LEGAL_LISTEN_TAPS) {
+ set_errno(ENOSYS);
+ set_errstr("Unsupported #%s listen tap %p, must be %p",
+ devname(), tap->filter,
+ DEVIP_LEGAL_LISTEN_TAPS);
return -1;
+ }
+ spin_lock(&conv->tap_lock);
+ switch (cmd) {
+ case (FDTAP_CMD_ADD):
+ SLIST_INSERT_HEAD(&conv->listen_taps, tap, link);
+ ret = 0;
+ break;
+ case (FDTAP_CMD_REM):
+ SLIST_REMOVE(&conv->listen_taps, tap, fd_tap, link);
+ ret = 0;
+ break;
+ default:
+ set_errno(ENOSYS);
+ set_errstr("Unsupported #%s listen tap command %p",
+ devname(), cmd);
+ ret = -1;
+ }
+ spin_unlock(&conv->tap_lock);
+ return ret;
+ default:
+ set_errno(ENOSYS);
+ set_errstr("Can't tap #%s file type %d", devname(),
+ TYPE(chan->qid));
+ return -1;
}
}
@@ -1735,7 +1751,8 @@
qlock_init(&c->listenq);
rendez_init(&c->cr);
rendez_init(&c->listenr);
- SLIST_INIT(&c->data_taps); /* already = 0; set to be futureproof */
+ /* already = 0; set to be futureproof */
+ SLIST_INIT(&c->data_taps);
SLIST_INIT(&c->listen_taps);
spinlock_init(&c->tap_lock);
qlock(&c->qlock);
@@ -1762,7 +1779,8 @@
* make sure both processes and protocol
* are done with this Conv
*/
- if (c->inuse == 0 && (p->inuse == NULL || (*p->inuse) (c) == 0))
+ if (c->inuse == 0 && (p->inuse == NULL ||
+ (*p->inuse)(c) == 0))
break;
qunlock(&c->qlock);
@@ -1843,8 +1861,8 @@
/*
* called with protocol locked
*/
-struct conv *Fsnewcall(struct conv *c, uint8_t * raddr, uint16_t rport,
- uint8_t * laddr, uint16_t lport, uint8_t version)
+struct conv *Fsnewcall(struct conv *c, uint8_t *raddr, uint16_t rport,
+ uint8_t *laddr, uint16_t lport, uint8_t version)
{
struct conv *nc;
struct conv **l;
diff --git a/kern/src/net/dial.c b/kern/src/net/dial.c
index a5bf39e..35787df 100644
--- a/kern/src/net/dial.c
+++ b/kern/src/net/dial.c
@@ -54,7 +54,7 @@
char *netdir;
char *proto;
char *rem;
- char *local; /* other args */
+ char *local; /* other args */
char *dir;
int *cfdp;
};
@@ -382,8 +382,8 @@
/*
* perform the identity translation (in case we can't reach cs)
*/
-static int
-identtrans(char *netdir, char *addr, char *naddr, int na, char *file, int nf)
+static int identtrans(char *netdir, char *addr, char *naddr, int na, char *file,
+ int nf)
{
char proto[Maxpath];
char *p;
diff --git a/kern/src/net/eipconv.c b/kern/src/net/eipconv.c
index ba388fb..9c19ba3 100644
--- a/kern/src/net/eipconv.c
+++ b/kern/src/net/eipconv.c
@@ -147,7 +147,7 @@
void printchan(void (*putch) (int, void **), void **putdat, struct chan *c)
{
- if (! c)
+ if (!c)
return;
printfmt(putch, putdat, "(%p): ", c);
printfmt(putch, putdat, "%slocked ", spin_locked(&c->lock) ? "":"un");
@@ -173,7 +173,8 @@
printfmt(putch, putdat, "mountid %p ", c->mountid);
printfmt(putch, putdat, "mntcache %p ", c->mcp);
printfmt(putch, putdat, "mux %p ", c->mux);
- if (c->mux && c->mux->c) printfmt(putch, putdat, "mux->c %p ", c->mux->c);
+ if (c->mux && c->mux->c)
+ printfmt(putch, putdat, "mux->c %p ", c->mux->c);
printfmt(putch, putdat, "aux %p ", c->aux);
printfmt(putch, putdat, "mchan %p ", c->mchan);
printfmt(putch, putdat, "mqid %p ");
diff --git a/kern/src/net/ethermedium.c b/kern/src/net/ethermedium.c
index 127ed97..c96f463 100644
--- a/kern/src/net/ethermedium.c
+++ b/kern/src/net/ethermedium.c
@@ -59,11 +59,11 @@
static void etherbind(struct Ipifc *ifc, int argc, char **argv);
static void etherunbind(struct Ipifc *ifc);
static void etherbwrite(struct Ipifc *ifc, struct block *bp, int version,
- uint8_t * ip);
+ uint8_t *ip);
static void etheraddmulti(struct Ipifc *ifc, uint8_t * a, uint8_t * ia);
static void etherremmulti(struct Ipifc *ifc, uint8_t * a, uint8_t * ia);
static struct block *multicastarp(struct Fs *f, struct arpent *a,
- struct medium *, uint8_t * mac);
+ struct medium *m, uint8_t *mac);
static void sendarp(struct Ipifc *ifc, struct arpent *a);
static void sendgarp(struct Ipifc *ifc, uint8_t * unused_uint8_p_t);
static int multicastea(uint8_t * ea, uint8_t * ip);
@@ -105,12 +105,12 @@
typedef struct Etherrock Etherrock;
struct Etherrock {
- struct Fs *f; /* file system we belong to */
- struct proc *arpp; /* arp process */
+ struct Fs *f; /* file system we belong to */
+ struct proc *arpp; /* arp process */
struct proc *read4p; /* reading process (v4) */
struct proc *read6p; /* reading process (v6) */
struct chan *mchan4; /* Data channel for v4 */
- struct chan *achan; /* Arp channel */
+ struct chan *achan; /* Arp channel */
struct chan *cchan4; /* Control channel for v4 */
struct chan *mchan6; /* Data channel for v6 */
struct chan *cchan6; /* Control channel for v6 */
@@ -356,8 +356,8 @@
/*
* called by ipoput with a single block to write with ifc rlock'd
*/
-static void
-etherbwrite(struct Ipifc *ifc, struct block *bp, int version, uint8_t * ip)
+static void etherbwrite(struct Ipifc *ifc, struct block *bp, int version,
+ uint8_t *ip)
{
Etherhdr *eh;
struct arpent *a;
@@ -372,8 +372,9 @@
* not, sendarp or resolveaddr6 unlocked it for us. yikes. */
a = arpget(er->f->arp, bp, version, ifc, ip, mac);
if (a) {
- /* check for broadcast or multicast. if it is either, this sorts that
- * out and returns the bp for the first packet on the arp's hold list.*/
+ /* check for broadcast or multicast. if it is either, this
+ * sorts that out and returns the bp for the first packet on the
+ * arp's hold list.*/
bp = multicastarp(er->f, a, ifc->m, mac);
if (bp == NULL) {
switch (version) {
@@ -384,7 +385,8 @@
resolveaddr6(ifc, a);
break;
default:
- panic("etherbwrite: version %d", version);
+ panic("etherbwrite: version %d",
+ version);
}
return;
}
@@ -397,21 +399,22 @@
eh = (Etherhdr *) bp->rp;
/* copy in mac addresses and ether type */
- etherfilladdr((uint16_t *)bp->rp, (uint16_t *)mac, (uint16_t *)ifc->mac);
+ etherfilladdr((uint16_t *)bp->rp, (uint16_t *)mac,
+ (uint16_t *)ifc->mac);
switch (version) {
- case V4:
- eh->t[0] = 0x08;
- eh->t[1] = 0x00;
- devtab[er->mchan4->type].bwrite(er->mchan4, bp, 0);
- break;
- case V6:
- eh->t[0] = 0x86;
- eh->t[1] = 0xDD;
- devtab[er->mchan6->type].bwrite(er->mchan6, bp, 0);
- break;
- default:
- panic("etherbwrite2: version %d", version);
+ case V4:
+ eh->t[0] = 0x08;
+ eh->t[1] = 0x00;
+ devtab[er->mchan4->type].bwrite(er->mchan4, bp, 0);
+ break;
+ case V6:
+ eh->t[0] = 0x86;
+ eh->t[1] = 0xDD;
+ devtab[er->mchan6->type].bwrite(er->mchan6, bp, 0);
+ break;
+ default:
+ panic("etherbwrite2: version %d", version);
}
ifc->out++;
}
@@ -512,14 +515,14 @@
version = multicastea(mac, a);
snprintf(buf, sizeof(buf), "addmulti %E", mac);
switch (version) {
- case V4:
- devtab[er->cchan4->type].write(er->cchan4, buf, strlen(buf), 0);
- break;
- case V6:
- devtab[er->cchan6->type].write(er->cchan6, buf, strlen(buf), 0);
- break;
- default:
- panic("etheraddmulti: version %d", version);
+ case V4:
+ devtab[er->cchan4->type].write(er->cchan4, buf, strlen(buf), 0);
+ break;
+ case V6:
+ devtab[er->cchan6->type].write(er->cchan6, buf, strlen(buf), 0);
+ break;
+ default:
+ panic("etheraddmulti: version %d", version);
}
}
@@ -533,14 +536,14 @@
version = multicastea(mac, a);
snprintf(buf, sizeof(buf), "remmulti %E", mac);
switch (version) {
- case V4:
- devtab[er->cchan4->type].write(er->cchan4, buf, strlen(buf), 0);
- break;
- case V6:
- devtab[er->cchan6->type].write(er->cchan6, buf, strlen(buf), 0);
- break;
- default:
- panic("etherremmulti: version %d", version);
+ case V4:
+ devtab[er->cchan4->type].write(er->cchan4, buf, strlen(buf), 0);
+ break;
+ case V6:
+ devtab[er->cchan6->type].write(er->cchan6, buf, strlen(buf), 0);
+ break;
+ default:
+ panic("etherremmulti: version %d", version);
}
}
@@ -556,17 +559,18 @@
Etherarp *e;
Etherrock *er = ifc->arg;
- /* don't do anything if it's been less than a second since the last. ctime
- * is set to 0 for the first time through. we hold the f->arp qlock, so
- * there shouldn't be a problem with another arp request for this same
- * arpent coming down til we update ctime again. */
+ /* don't do anything if it's been less than a second since the last.
+ * ctime is set to 0 for the first time through. we hold the f->arp
+ * qlock, so there shouldn't be a problem with another arp request for
+ * this same arpent coming down til we update ctime again. */
if (NOW - a->ctime < 1000) {
arprelease(er->f->arp, a);
return;
}
- /* remove all but the last message. brho: this might be unnecessary. we'll
- * eventually send them. but they should be quite stale at this point. */
+ /* remove all but the last message. brho: this might be unnecessary.
+ * we'll eventually send them. but they should be quite stale at this
+ * point. */
while ((bp = a->hold) != NULL) {
if (bp == a->last)
break;
@@ -695,88 +699,89 @@
e = (Etherarp *) ebp->rp;
switch (nhgets(e->op)) {
- default:
- break;
+ default:
+ break;
- case ARPREPLY:
- /* check for machine using my ip address */
- v4tov6(ip, e->spa);
- if (iplocalonifc(ifc, ip) || ipproxyifc(er->f, ifc, ip)) {
- if (memcmp(e->sha, ifc->mac, sizeof(e->sha)) != 0) {
- printd("arprep: 0x%E/0x%E also has ip addr %V\n",
- e->s, e->sha, e->spa);
- break;
- }
- }
-
- /* make sure we're not entering broadcast addresses */
- if (ipcmp(ip, ipbroadcast) == 0 ||
- !memcmp(e->sha, etherbroadcast, sizeof(e->sha))) {
- printd
- ("arprep: 0x%E/0x%E cannot register broadcast address %I\n",
- e->s, e->sha, e->spa);
+ case ARPREPLY:
+ /* check for machine using my ip address */
+ v4tov6(ip, e->spa);
+ if (iplocalonifc(ifc, ip) || ipproxyifc(er->f, ifc, ip)) {
+ if (memcmp(e->sha, ifc->mac, sizeof(e->sha)) != 0) {
+ printd("arprep: 0x%E/0x%E also has ip addr %V\n",
+ e->s, e->sha, e->spa);
break;
}
+ }
- arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), 0);
+ /* make sure we're not entering broadcast addresses */
+ if (ipcmp(ip, ipbroadcast) == 0 ||
+ !memcmp(e->sha, etherbroadcast, sizeof(e->sha))) {
+ printd("arprep: 0x%E/0x%E cannot register broadcast address %I\n",
+ e->s, e->sha, e->spa);
+ break;
+ }
+
+ arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), 0);
+ break;
+
+ case ARPREQUEST:
+ /* don't answer arps till we know who we are */
+ if (ifc->lifc == 0)
break;
- case ARPREQUEST:
- /* don't answer arps till we know who we are */
- if (ifc->lifc == 0)
- break;
-
- /* check for machine using my ip or ether address */
- v4tov6(ip, e->spa);
- if (iplocalonifc(ifc, ip) || ipproxyifc(er->f, ifc, ip)) {
- if (memcmp(e->sha, ifc->mac, sizeof(e->sha)) != 0) {
- if (memcmp(eprinted, e->spa, sizeof(e->spa))) {
- /* print only once */
- printd("arpreq: 0x%E also has ip addr %V\n", e->sha,
- e->spa);
- memmove(eprinted, e->spa, sizeof(e->spa));
- }
- }
- } else {
- if (memcmp(e->sha, ifc->mac, sizeof(e->sha)) == 0) {
- printd("arpreq: %V also has ether addr %E\n", e->spa,
- e->sha);
- break;
+ /* check for machine using my ip or ether address */
+ v4tov6(ip, e->spa);
+ if (iplocalonifc(ifc, ip) || ipproxyifc(er->f, ifc, ip)) {
+ if (memcmp(e->sha, ifc->mac, sizeof(e->sha)) != 0) {
+ if (memcmp(eprinted, e->spa, sizeof(e->spa))) {
+ /* print only once */
+ printd("arpreq: 0x%E also has ip addr %V\n",
+ e->sha, e->spa);
+ memmove(eprinted, e->spa,
+ sizeof(e->spa));
}
}
+ } else {
+ if (memcmp(e->sha, ifc->mac, sizeof(e->sha)) == 0) {
+ printd("arpreq: %V also has ether addr %E\n",
+ e->spa, e->sha);
+ break;
+ }
+ }
- /* refresh what we know about sender */
- arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), 1);
+ /* refresh what we know about sender */
+ arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), 1);
- /* answer only requests for our address or systems we're proxying for */
- v4tov6(ip, e->tpa);
- if (!iplocalonifc(ifc, ip))
- if (!ipproxyifc(er->f, ifc, ip))
- break;
+ /* answer only requests for our address or systems we're
+ * proxying for */
+ v4tov6(ip, e->tpa);
+ if (!iplocalonifc(ifc, ip))
+ if (!ipproxyifc(er->f, ifc, ip))
+ break;
- n = sizeof(Etherarp);
- if (n < ifc->mintu)
- n = ifc->mintu;
- rbp = block_alloc(n, MEM_WAIT);
- r = (Etherarp *) rbp->rp;
- memset(r, 0, sizeof(Etherarp));
- hnputs(r->type, ETARP);
- hnputs(r->hrd, 1);
- hnputs(r->pro, ETIP4);
- r->hln = sizeof(r->sha);
- r->pln = sizeof(r->spa);
- hnputs(r->op, ARPREPLY);
- memmove(r->tha, e->sha, sizeof(r->tha));
- memmove(r->tpa, e->spa, sizeof(r->tpa));
- memmove(r->sha, ifc->mac, sizeof(r->sha));
- memmove(r->spa, e->tpa, sizeof(r->spa));
- memmove(r->d, e->sha, sizeof(r->d));
- memmove(r->s, ifc->mac, sizeof(r->s));
- rbp->wp += n;
+ n = sizeof(Etherarp);
+ if (n < ifc->mintu)
+ n = ifc->mintu;
+ rbp = block_alloc(n, MEM_WAIT);
+ r = (Etherarp *) rbp->rp;
+ memset(r, 0, sizeof(Etherarp));
+ hnputs(r->type, ETARP);
+ hnputs(r->hrd, 1);
+ hnputs(r->pro, ETIP4);
+ r->hln = sizeof(r->sha);
+ r->pln = sizeof(r->spa);
+ hnputs(r->op, ARPREPLY);
+ memmove(r->tha, e->sha, sizeof(r->tha));
+ memmove(r->tpa, e->spa, sizeof(r->tpa));
+ memmove(r->sha, ifc->mac, sizeof(r->sha));
+ memmove(r->spa, e->tpa, sizeof(r->spa));
+ memmove(r->d, e->sha, sizeof(r->d));
+ memmove(r->s, ifc->mac, sizeof(r->s));
+ rbp->wp += n;
- n = devtab[er->achan->type].bwrite(er->achan, rbp, 0);
- if (n < 0)
- printd("arp: write: %r\n");
+ n = devtab[er->achan->type].bwrite(er->achan, rbp, 0);
+ if (n < 0)
+ printd("arp: write: %r\n");
}
freeb(ebp);
}
@@ -804,22 +809,22 @@
int x;
switch (x = ipismulticast(ip)) {
- case V4:
- ea[0] = 0x01;
- ea[1] = 0x00;
- ea[2] = 0x5e;
- ea[3] = ip[13] & 0x7f;
- ea[4] = ip[14];
- ea[5] = ip[15];
- break;
- case V6:
- ea[0] = 0x33;
- ea[1] = 0x33;
- ea[2] = ip[12];
- ea[3] = ip[13];
- ea[4] = ip[14];
- ea[5] = ip[15];
- break;
+ case V4:
+ ea[0] = 0x01;
+ ea[1] = 0x00;
+ ea[2] = 0x5e;
+ ea[3] = ip[13] & 0x7f;
+ ea[4] = ip[14];
+ ea[5] = ip[15];
+ break;
+ case V6:
+ ea[0] = 0x33;
+ ea[1] = 0x33;
+ ea[2] = ip[12];
+ ea[3] = ip[13];
+ ea[4] = ip[14];
+ ea[5] = ip[15];
+ break;
}
return x;
}
@@ -829,26 +834,25 @@
* addresses. Return the first queued packet for the
* IP address.
*/
-static struct block *multicastarp(struct Fs *f,
- struct arpent *a, struct medium *medium,
- uint8_t * mac)
+static struct block *multicastarp(struct Fs *f, struct arpent *a,
+ struct medium *medium, uint8_t *mac)
{
/* is it broadcast? */
switch (ipforme(f, a->ip)) {
- case Runi:
- return NULL;
- case Rbcast:
- memset(mac, 0xff, 6);
- return arpresolve(f->arp, a, medium, mac);
- default:
- break;
+ case Runi:
+ return NULL;
+ case Rbcast:
+ memset(mac, 0xff, 6);
+ return arpresolve(f->arp, a, medium, mac);
+ default:
+ break;
}
/* if multicast, fill in mac */
switch (multicastea(mac, a->ip)) {
- case V4:
- case V6:
- return arpresolve(f->arp, a, medium, mac);
+ case V4:
+ case V6:
+ return arpresolve(f->arp, a, medium, mac);
}
/* let arp take care of it */
diff --git a/kern/src/net/icmp.c b/kern/src/net/icmp.c
index 4403d9e..486cfdb 100644
--- a/kern/src/net/icmp.c
+++ b/kern/src/net/icmp.c
@@ -69,7 +69,7 @@
uint8_t data[1];
} Icmp;
-enum { /* Packet Types */
+enum { /* Packet Types */
EchoReply = 0,
Unreachable = 3,
SrcQuench = 4,
@@ -88,7 +88,7 @@
};
enum {
- MinAdvise = 24, /* minimum needed for us to advise another protocol */
+ MinAdvise = 24, /* minimum needed for us to advise another protocol */
};
char *icmpnames[Maxtype + 1] = {
@@ -158,9 +158,8 @@
extern int icmpstate(struct conv *c, char *state, int n)
{
- return snprintf(state, n, "%s qin %d qout %d\n",
- "Datagram",
- c->rq ? qlen(c->rq) : 0, c->wq ? qlen(c->wq) : 0);
+ return snprintf(state, n, "%s qin %d qout %d\n", "Datagram",
+ c->rq ? qlen(c->rq) : 0, c->wq ? qlen(c->wq) : 0);
}
void icmpannounce(struct conv *c, char **argv, int argc)
@@ -205,8 +204,8 @@
ipriv->stats[OutMsgs]++;
netlog(c->p->f, Logicmp,
"icmp output: Type %s (%d,%d), To %V, TTL %d, ID %d, SEQ %d\n",
- icmpnames[MIN(p->type, Maxtype)],
- p->type, p->code, p->dst, p->ttl, nhgets(p->icmpid), nhgets(p->seq));
+ icmpnames[MIN(p->type, Maxtype)], p->type, p->code, p->dst,
+ p->ttl, nhgets(p->icmpid), nhgets(p->seq));
ipoput4(c->p->f, bp, 0, c->ttl, c->tos, NULL);
}
@@ -218,7 +217,8 @@
p = (Icmp *) bp->rp;
netlog(f, Logicmp, "sending icmpttlexceeded -> %V\n", p->src);
- nbp = block_alloc(ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8, MEM_WAIT);
+ nbp = block_alloc(ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8,
+ MEM_WAIT);
nbp->wp += ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8;
np = (Icmp *) nbp->rp;
np->vihl = IP_VER4;
@@ -231,7 +231,8 @@
hnputs(np->icmpid, 0);
hnputs(np->seq, 0);
memset(np->cksum, 0, sizeof(np->cksum));
- hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE, blocklen(nbp) - ICMP_IPSIZE));
+ hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE,
+ blocklen(nbp) - ICMP_IPSIZE));
ipoput4(f, nbp, 0, MAXTTL, DFLTTOS, NULL);
}
@@ -259,7 +260,8 @@
* unreachable. But we might not be UDP, due to how the code is built.
* Check the UDP netlog if you see this. */
netlog(f, Logicmp, "sending icmpnoconv -> %V\n", p->src);
- nbp = block_alloc(ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8, MEM_WAIT);
+ nbp = block_alloc(ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8,
+ MEM_WAIT);
nbp->wp += ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8;
np = (Icmp *) nbp->rp;
np->vihl = IP_VER4;
@@ -272,7 +274,8 @@
hnputs(np->icmpid, 0);
hnputs(np->seq, seq);
memset(np->cksum, 0, sizeof(np->cksum));
- hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE, blocklen(nbp) - ICMP_IPSIZE));
+ hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE,
+ blocklen(nbp) - ICMP_IPSIZE));
ipoput4(f, nbp, 0, MAXTTL, DFLTTOS, NULL);
}
@@ -315,9 +318,10 @@
Icmp *q;
uint8_t ip[4];
- /* we're repurposing bp to send it back out. we need to remove any inbound
- * checksum flags (which were saying the HW did the checksum) and any other
- * metadata. We might need to fill in some of the metadata too. */
+ /* we're repurposing bp to send it back out. we need to remove any
+ * inbound checksum flags (which were saying the HW did the checksum)
+ * and any other metadata. We might need to fill in some of the
+ * metadata too. */
block_reset_metadata(bp);
q = (Icmp *) bp->rp;
q->vihl = IP_VER4;
@@ -361,14 +365,15 @@
ipriv->stats[InMsgs]++;
p = (Icmp *) bp->rp;
- /* The ID and SEQ are only for Echo Request and Reply, but close enough. */
+ /* The ID and SEQ are only for Echo Request and Reply, but close enough.
+ */
netlog(icmp->f, Logicmp,
"icmp input: Type %s (%d,%d), From %V, TTL %d, ID %d, SEQ %d\n",
- icmpnames[MIN(p->type, Maxtype)],
- p->type, p->code, p->src, p->ttl, nhgets(p->icmpid), nhgets(p->seq));
+ icmpnames[MIN(p->type, Maxtype)], p->type, p->code, p->src,
+ p->ttl, nhgets(p->icmpid), nhgets(p->seq));
n = blocklen(bp);
if (n < ICMP_IPSIZE + ICMP_HDRSIZE) {
- /* pullupblock should fail if dlen < size. b->len >= b->dlen. */
+ /* pullupblock should fail if dlen < size. b->len >= b->dlen */
panic("We did a pullupblock and thought we had enough!");
ipriv->stats[InErrors]++;
ipriv->stats[HlenErrs]++;
@@ -392,18 +397,37 @@
ipriv->in[p->type]++;
switch (p->type) {
- case EchoRequest:
- if (iplen < n)
- bp = trimblock(bp, 0, iplen);
- r = mkechoreply(icmp, bp);
- ipriv->out[EchoReply]++;
- ipoput4(icmp->f, r, 0, MAXTTL, DFLTTOS, NULL);
- break;
- case Unreachable:
- if (p->code > 5)
- msg = unreachcode[1];
- else
- msg = unreachcode[p->code];
+ case EchoRequest:
+ if (iplen < n)
+ bp = trimblock(bp, 0, iplen);
+ r = mkechoreply(icmp, bp);
+ ipriv->out[EchoReply]++;
+ ipoput4(icmp->f, r, 0, MAXTTL, DFLTTOS, NULL);
+ break;
+ case Unreachable:
+ if (p->code > 5)
+ msg = unreachcode[1];
+ else
+ msg = unreachcode[p->code];
+
+ bp->rp += ICMP_IPSIZE + ICMP_HDRSIZE;
+ if (blocklen(bp) < MinAdvise) {
+ ipriv->stats[LenErrs]++;
+ goto raise;
+ }
+ p = (Icmp *) bp->rp;
+ pr = Fsrcvpcolx(icmp->f, p->proto);
+ if (pr != NULL && pr->advise != NULL) {
+ (*pr->advise) (pr, bp, msg);
+ return;
+ }
+
+ bp->rp -= ICMP_IPSIZE + ICMP_HDRSIZE;
+ goticmpkt(icmp, bp);
+ break;
+ case TimeExceed:
+ if (p->code == 0) {
+ snprintf(m2, sizeof(m2), "ttl exceeded at %V", p->src);
bp->rp += ICMP_IPSIZE + ICMP_HDRSIZE;
if (blocklen(bp) < MinAdvise) {
@@ -413,36 +437,17 @@
p = (Icmp *) bp->rp;
pr = Fsrcvpcolx(icmp->f, p->proto);
if (pr != NULL && pr->advise != NULL) {
- (*pr->advise) (pr, bp, msg);
+ (*pr->advise) (pr, bp, m2);
return;
}
-
bp->rp -= ICMP_IPSIZE + ICMP_HDRSIZE;
- goticmpkt(icmp, bp);
- break;
- case TimeExceed:
- if (p->code == 0) {
- snprintf(m2, sizeof(m2), "ttl exceeded at %V", p->src);
+ }
- bp->rp += ICMP_IPSIZE + ICMP_HDRSIZE;
- if (blocklen(bp) < MinAdvise) {
- ipriv->stats[LenErrs]++;
- goto raise;
- }
- p = (Icmp *) bp->rp;
- pr = Fsrcvpcolx(icmp->f, p->proto);
- if (pr != NULL && pr->advise != NULL) {
- (*pr->advise) (pr, bp, m2);
- return;
- }
- bp->rp -= ICMP_IPSIZE + ICMP_HDRSIZE;
- }
-
- goticmpkt(icmp, bp);
- break;
- default:
- goticmpkt(icmp, bp);
- break;
+ goticmpkt(icmp, bp);
+ break;
+ default:
+ goticmpkt(icmp, bp);
+ break;
}
return;
@@ -486,10 +491,11 @@
p = seprintf(p, e, "%s: %u\n", statnames[i], priv->stats[i]);
for (i = 0; i <= Maxtype; i++) {
if (icmpnames[i])
- p = seprintf(p, e, "%s: %u %u\n", icmpnames[i], priv->in[i],
- priv->out[i]);
+ p = seprintf(p, e, "%s: %u %u\n", icmpnames[i],
+ priv->in[i], priv->out[i]);
else
- p = seprintf(p, e, "%d: %u %u\n", i, priv->in[i], priv->out[i]);
+ p = seprintf(p, e, "%d: %u %u\n", i, priv->in[i],
+ priv->out[i]);
}
return p - buf;
}
diff --git a/kern/src/net/icmp6.c b/kern/src/net/icmp6.c
index 1005f2b..741ea18 100644
--- a/kern/src/net/icmp6.c
+++ b/kern/src/net/icmp6.c
@@ -51,10 +51,10 @@
Ip6hdr;
ICMPpkt;
*/
- uint8_t vcf[4]; // version:4, traffic class:8, flow label:20
- uint8_t ploadlen[2]; // payload length: packet length - 40
- uint8_t proto; // next header type
- uint8_t ttl; // hop limit
+ uint8_t vcf[4]; // version:4, traffic class:8, flow label:20
+ uint8_t ploadlen[2]; // payload length: packet length - 40
+ uint8_t proto; // next header type
+ uint8_t ttl; // hop limit
uint8_t src[IPaddrlen];
uint8_t dst[IPaddrlen];
uint8_t type;
@@ -67,10 +67,10 @@
struct NdiscC {
//IPICMP;
- uint8_t vcf[4]; // version:4, traffic class:8, flow label:20
- uint8_t ploadlen[2]; // payload length: packet length - 40
- uint8_t proto; // next header type
- uint8_t ttl; // hop limit
+ uint8_t vcf[4]; // version:4, traffic class:8, flow label:20
+ uint8_t ploadlen[2]; // payload length: packet length - 40
+ uint8_t proto; // next header type
+ uint8_t ttl; // hop limit
uint8_t src[IPaddrlen];
uint8_t dst[IPaddrlen];
uint8_t type;
@@ -84,10 +84,10 @@
struct Ndpkt {
//NdiscC;
- uint8_t vcf[4]; // version:4, traffic class:8, flow label:20
- uint8_t ploadlen[2]; // payload length: packet length - 40
- uint8_t proto; // next header type
- uint8_t ttl; // hop limit
+ uint8_t vcf[4]; // version:4, traffic class:8, flow label:20
+ uint8_t ploadlen[2]; // payload length: packet length - 40
+ uint8_t proto; // next header type
+ uint8_t ttl; // hop limit
uint8_t src[IPaddrlen];
uint8_t dst[IPaddrlen];
uint8_t type;
@@ -99,9 +99,9 @@
uint8_t target[IPaddrlen];
uint8_t otype;
- uint8_t olen; // length in units of 8 octets(incl type, code),
+ uint8_t olen; // length in units of 8 octets(incl type, code),
// 1 for IEEE 802 addresses
- uint8_t lnaddr[6]; // link-layer address
+ uint8_t lnaddr[6]; // link-layer address
};
enum {
@@ -253,6 +253,7 @@
static struct block *newIPICMP(int packetlen)
{
struct block *nbp;
+
nbp = block_alloc(packetlen, MEM_WAIT);
nbp->wp += packetlen;
memset(nbp->rp, 0, packetlen);
@@ -389,10 +390,8 @@
* and tuni == TARG_UNI => neighbor reachability.
*/
-void icmpns(struct Fs *f,
- uint8_t *src, int suni,
- uint8_t *targ, int tuni,
- uint8_t *mac)
+void icmpns(struct Fs *f, uint8_t *src, int suni, uint8_t *targ, int tuni,
+ uint8_t *mac)
{
struct block *nbp;
struct Ndpkt *np;
@@ -489,9 +488,11 @@
rlock(&ifc->rwlock);
if (ipv6anylocal(ifc, np->src)) {
- netlog(f, Logicmp, "send icmphostunr -> s%I d%I\n", p->src, p->dst);
+ netlog(f, Logicmp, "send icmphostunr -> s%I d%I\n",
+ p->src, p->dst);
} else {
- netlog(f, Logicmp, "icmphostunr fail -> s%I d%I\n", p->src, p->dst);
+ netlog(f, Logicmp, "icmphostunr fail -> s%I d%I\n",
+ p->src, p->dst);
runlock(&ifc->rwlock);
freeblist(nbp);
goto freebl;
@@ -536,11 +537,11 @@
np = (struct IPICMP *)nbp->rp;
if (ipv6anylocal(ifc, np->src)) {
- netlog(f, Logicmp, "send icmpttlexceeded6 -> s%I d%I\n", p->src,
- p->dst);
+ netlog(f, Logicmp, "send icmpttlexceeded6 -> s%I d%I\n",
+ p->src, p->dst);
} else {
- netlog(f, Logicmp, "icmpttlexceeded6 fail -> s%I d%I\n", p->src,
- p->dst);
+ netlog(f, Logicmp, "icmpttlexceeded6 fail -> s%I d%I\n",
+ p->src, p->dst);
return;
}
@@ -575,10 +576,12 @@
np = (struct IPICMP *)nbp->rp;
if (!ipv6anylocal(ifc, np->src)) {
- netlog(f, Logicmp, "icmppkttoobig6 fail -> s%I d%I\n", p->src, p->dst);
+ netlog(f, Logicmp, "icmppkttoobig6 fail -> s%I d%I\n",
+ p->src, p->dst);
return;
}
- netlog(f, Logicmp, "send icmppkttoobig6 -> s%I d%I\n", p->src, p->dst);
+ netlog(f, Logicmp, "send icmppkttoobig6 -> s%I d%I\n",
+ p->src, p->dst);
memmove(np->dst, p->src, IPaddrlen);
np->type = PacketTooBigV6;
@@ -652,78 +655,81 @@
}
switch (p->type) {
- case NbrSolicit:
- case NbrAdvert:
- np = (struct Ndpkt *)p;
- if (isv6mcast(np->target)) {
- ipriv->stats[TargetErrs6]++;
- goto err;
- }
- if (optexsts(np) && (np->olen == 0)) {
- ipriv->stats[OptlenErrs6]++;
- goto err;
- }
+ case NbrSolicit:
+ case NbrAdvert:
+ np = (struct Ndpkt *)p;
+ if (isv6mcast(np->target)) {
+ ipriv->stats[TargetErrs6]++;
+ goto err;
+ }
+ if (optexsts(np) && (np->olen == 0)) {
+ ipriv->stats[OptlenErrs6]++;
+ goto err;
+ }
- if (p->type == NbrSolicit) {
- if (ipcmp(np->src, v6Unspecified) == 0) {
- if (!issmcast(np->dst) || optexsts(np)) {
- ipriv->stats[AddrmxpErrs6]++;
- goto err;
- }
- }
- }
-
- if (p->type == NbrAdvert) {
- if ((isv6mcast(np->dst)) && (nhgets(np->icmpid) & Sflag)) {
+ if (p->type == NbrSolicit) {
+ if (ipcmp(np->src, v6Unspecified) == 0) {
+ if (!issmcast(np->dst) || optexsts(np))
+ {
ipriv->stats[AddrmxpErrs6]++;
goto err;
}
}
- break;
+ }
- case RouterAdvert:
- if (pktsz - sizeof(struct ip6hdr) < 16) {
- ipriv->stats[HlenErrs6]++;
+ if (p->type == NbrAdvert) {
+ if ((isv6mcast(np->dst)) &&
+ (nhgets(np->icmpid) & Sflag)) {
+ ipriv->stats[AddrmxpErrs6]++;
goto err;
}
- if (!islinklocal(p->src)) {
- ipriv->stats[RouterAddrErrs6]++;
- goto err;
- }
- sz = sizeof(struct IPICMP) + 8;
- while ((sz + 1) < pktsz) {
- osz = *(packet + sz + 1);
- if (osz <= 0) {
- ipriv->stats[OptlenErrs6]++;
- goto err;
- }
- sz += 8 * osz;
- }
- break;
+ }
+ break;
- case RouterSolicit:
- if (pktsz - sizeof(struct ip6hdr) < 8) {
- ipriv->stats[HlenErrs6]++;
- goto err;
- }
- unsp = (ipcmp(p->src, v6Unspecified) == 0);
- sz = sizeof(struct IPICMP) + 8;
- while ((sz + 1) < pktsz) {
- osz = *(packet + sz + 1);
- if ((osz <= 0) || (unsp && (*(packet + sz) == slladd))) {
- ipriv->stats[OptlenErrs6]++;
- goto err;
- }
- sz += 8 * osz;
- }
- break;
-
- case RedirectV6:
- //to be filled in
- break;
-
- default:
+ case RouterAdvert:
+ if (pktsz - sizeof(struct ip6hdr) < 16) {
+ ipriv->stats[HlenErrs6]++;
goto err;
+ }
+ if (!islinklocal(p->src)) {
+ ipriv->stats[RouterAddrErrs6]++;
+ goto err;
+ }
+ sz = sizeof(struct IPICMP) + 8;
+ while ((sz + 1) < pktsz) {
+ osz = *(packet + sz + 1);
+ if (osz <= 0) {
+ ipriv->stats[OptlenErrs6]++;
+ goto err;
+ }
+ sz += 8 * osz;
+ }
+ break;
+
+ case RouterSolicit:
+ if (pktsz - sizeof(struct ip6hdr) < 8) {
+ ipriv->stats[HlenErrs6]++;
+ goto err;
+ }
+ unsp = (ipcmp(p->src, v6Unspecified) == 0);
+ sz = sizeof(struct IPICMP) + 8;
+ while ((sz + 1) < pktsz) {
+ osz = *(packet + sz + 1);
+ if ((osz <= 0) ||
+ (unsp && (*(packet + sz) == slladd))) {
+ ipriv->stats[OptlenErrs6]++;
+ goto err;
+ }
+ sz += 8 * osz;
+ }
+ break;
+
+ case RedirectV6:
+ //to be filled in
+ break;
+
+ default:
+ goto err;
}
}
@@ -780,17 +786,37 @@
goto raise;
switch (p->type) {
- case EchoRequestV6:
- r = mkechoreply6(bp);
- ipriv->out[EchoReply]++;
- ipoput6(icmp->f, r, 0, MAXTTL, DFLTTOS, NULL);
- break;
+ case EchoRequestV6:
+ r = mkechoreply6(bp);
+ ipriv->out[EchoReply]++;
+ ipoput6(icmp->f, r, 0, MAXTTL, DFLTTOS, NULL);
+ break;
- case UnreachableV6:
- if (p->code > 4)
- msg = unreachcode[icmp6_unkn_code];
- else
- msg = unreachcode[p->code];
+ case UnreachableV6:
+ if (p->code > 4)
+ msg = unreachcode[icmp6_unkn_code];
+ else
+ msg = unreachcode[p->code];
+
+ bp->rp += sizeof(struct IPICMP);
+ if (blocklen(bp) < 8) {
+ ipriv->stats[LenErrs6]++;
+ goto raise;
+ }
+ p = (struct IPICMP *)bp->rp;
+ pr = Fsrcvpcolx(icmp->f, p->proto);
+ if (pr != NULL && pr->advise != NULL) {
+ (*pr->advise) (pr, bp, msg);
+ return;
+ }
+
+ bp->rp -= sizeof(struct IPICMP);
+ goticmpkt6(icmp, bp, 0);
+ break;
+
+ case TimeExceedV6:
+ if (p->code == 0) {
+ snprintf(m2, sizeof(m2), "ttl exceeded at %I", p->src);
bp->rp += sizeof(struct IPICMP);
if (blocklen(bp) < 8) {
@@ -800,100 +826,82 @@
p = (struct IPICMP *)bp->rp;
pr = Fsrcvpcolx(icmp->f, p->proto);
if (pr != NULL && pr->advise != NULL) {
- (*pr->advise) (pr, bp, msg);
+ (*pr->advise) (pr, bp, m2);
return;
}
-
bp->rp -= sizeof(struct IPICMP);
- goticmpkt6(icmp, bp, 0);
- break;
+ }
- case TimeExceedV6:
- if (p->code == 0) {
- snprintf(m2, sizeof(m2), "ttl exceeded at %I", p->src);
+ goticmpkt6(icmp, bp, 0);
+ break;
- bp->rp += sizeof(struct IPICMP);
- if (blocklen(bp) < 8) {
- ipriv->stats[LenErrs6]++;
- goto raise;
+ case RouterAdvert:
+ case RouterSolicit:
+ /* using lsrc as a temp, munge hdr for goticmp6
+ memmove(lsrc, p->src, IPaddrlen);
+ memmove(p->src, p->dst, IPaddrlen);
+ memmove(p->dst, lsrc, IPaddrlen); */
+
+ goticmpkt6(icmp, bp, p->type);
+ break;
+
+ case NbrSolicit:
+ np = (struct Ndpkt *)p;
+ pktflags = 0;
+ switch (targettype(icmp->f, ipifc, np->target)) {
+ case t_unirany:
+ pktflags |= Oflag;
+ /* fall through */
+
+ case t_uniproxy:
+ if (ipcmp(np->src, v6Unspecified) != 0) {
+ arpenter(icmp->f, V6, np->src,
+ np->lnaddr, 8 * np->olen - 2,
+ 0);
+ pktflags |= Sflag;
}
- p = (struct IPICMP *)bp->rp;
- pr = Fsrcvpcolx(icmp->f, p->proto);
- if (pr != NULL && pr->advise != NULL) {
- (*pr->advise) (pr, bp, m2);
- return;
- }
- bp->rp -= sizeof(struct IPICMP);
- }
-
- goticmpkt6(icmp, bp, 0);
- break;
-
- case RouterAdvert:
- case RouterSolicit:
- /* using lsrc as a temp, munge hdr for goticmp6
- memmove(lsrc, p->src, IPaddrlen);
- memmove(p->src, p->dst, IPaddrlen);
- memmove(p->dst, lsrc, IPaddrlen); */
-
- goticmpkt6(icmp, bp, p->type);
- break;
-
- case NbrSolicit:
- np = (struct Ndpkt *)p;
- pktflags = 0;
- switch (targettype(icmp->f, ipifc, np->target)) {
- case t_unirany:
- pktflags |= Oflag;
- /* fall through */
-
- case t_uniproxy:
- if (ipcmp(np->src, v6Unspecified) != 0) {
- arpenter(icmp->f, V6, np->src, np->lnaddr,
- 8 * np->olen - 2, 0);
- pktflags |= Sflag;
- }
- if (ipv6local(ipifc, lsrc)) {
- icmpna(icmp->f, lsrc,
- (ipcmp(np->src, v6Unspecified) ==
- 0) ? v6allnodesL : np->src, np->target,
- ipifc->mac, pktflags);
- } else
- freeblist(bp);
- break;
-
- case t_unitent:
- /* not clear what needs to be done. send up
- * an icmp mesg saying don't use this address? */
-
- default:
+ if (ipv6local(ipifc, lsrc)) {
+ icmpna(icmp->f, lsrc,
+ (ipcmp(np->src, v6Unspecified)
+ == 0) ? v6allnodesL : np->src,
+ np->target, ipifc->mac,
+ pktflags);
+ } else
freeblist(bp);
- }
+ break;
- break;
+ case t_unitent:
+ /* not clear what needs to be done. send up an
+ * icmp mesg saying don't use this address? */
- case NbrAdvert:
- np = (struct Ndpkt *)p;
+ default:
+ freeblist(bp);
+ }
- /* if the target address matches one of the local interface
- * address and the local interface address has tentative bit set,
- * then insert into ARP table. this is so the duplication address
- * detection part of ipconfig can discover duplication through
- * the arp table
- */
- lifc = iplocalonifc(ipifc, np->target);
- if (lifc && lifc->tentative)
- refresh = 0;
- arpenter(icmp->f, V6, np->target, np->lnaddr, 8 * np->olen - 2,
- refresh);
- freeblist(bp);
- break;
+ break;
- case PacketTooBigV6:
+ case NbrAdvert:
+ np = (struct Ndpkt *)p;
- default:
- goticmpkt6(icmp, bp, 0);
- break;
+ /* if the target address matches one of the local interface
+ * address and the local interface address has tentative bit
+ * set, then insert into ARP table. this is so the duplication
+ * address detection part of ipconfig can discover duplication
+ * through the arp table
+ */
+ lifc = iplocalonifc(ipifc, np->target);
+ if (lifc && lifc->tentative)
+ refresh = 0;
+ arpenter(icmp->f, V6, np->target, np->lnaddr, 8 * np->olen - 2,
+ refresh);
+ freeblist(bp);
+ break;
+
+ case PacketTooBigV6:
+
+ default:
+ goticmpkt6(icmp, bp, 0);
+ break;
}
return;
@@ -915,10 +923,11 @@
p = seprintf(p, e, "%s: %u\n", statnames6[i], priv->stats[i]);
for (i = 0; i <= Maxtype6; i++) {
if (icmpnames6[i])
- p = seprintf(p, e, "%s: %u %u\n", icmpnames6[i], priv->in[i],
- priv->out[i]);
+ p = seprintf(p, e, "%s: %u %u\n", icmpnames6[i],
+ priv->in[i], priv->out[i]);
else
- p = seprintf(p, e, "%d: %u %u\n", i, priv->in[i], priv->out[i]);
+ p = seprintf(p, e, "%d: %u %u\n", i, priv->in[i],
+ priv->out[i]);
}
return p - buf;
}
diff --git a/kern/src/net/ip.c b/kern/src/net/ip.c
index a0a4072..afb47f9 100644
--- a/kern/src/net/ip.c
+++ b/kern/src/net/ip.c
@@ -44,12 +44,12 @@
typedef struct Ipfrag Ipfrag;
enum {
- IP4HDR = 20, /* sizeof(Ip4hdr) */
- IP6HDR = 40, /* sizeof(Ip6hdr) */
+ IP4HDR = 20, /* sizeof(Ip4hdr) */
+ IP6HDR = 40, /* sizeof(Ip6hdr) */
IP_HLEN4 = 0x05, /* Header length in words */
- IP_DF = 0x4000, /* Don't fragment */
- IP_MF = 0x2000, /* More fragments */
- IP6FHDR = 8, /* sizeof(Fraghdr6) */
+ IP_DF = 0x4000, /* Don't fragment */
+ IP_MF = 0x2000, /* More fragments */
+ IP6FHDR = 8, /* sizeof(Fraghdr6) */
IP_MAX = 64 * 1024, /* Maximum Internet packet size */
};
@@ -118,7 +118,7 @@
struct fragment6 *fragfree6;
int id6;
- int iprouting; /* true if we route like a gateway */
+ int iprouting; /* true if we route like a gateway */
};
static char *statnames[] = {
@@ -151,8 +151,8 @@
#define BKFG(xp) ((struct Ipfrag*)((xp)->base))
uint16_t ipcsum(uint8_t * unused_uint8_p_t);
-struct block *ip4reassemble(struct IP *, int unused_int,
- struct block *, struct Ip4hdr *);
+struct block *ip4reassemble(struct IP *, int unused_int, struct block *,
+ struct Ip4hdr *);
void ipfragfree4(struct IP *, struct fragment4 *);
struct fragment4 *ipfragallo4(struct IP *);
@@ -186,7 +186,7 @@
struct fragment6 *fq6, *eq6;
ip->fragfree4 =
- (struct fragment4 *)kzmalloc(sizeof(struct fragment4) * size, 0);
+ (struct fragment4 *)kzmalloc(sizeof(struct fragment4) * size, 0);
if (ip->fragfree4 == NULL)
panic("initfrag");
@@ -197,7 +197,7 @@
ip->fragfree4[size - 1].next = NULL;
ip->fragfree6 =
- (struct fragment6 *)kzmalloc(sizeof(struct fragment6) * size, 0);
+ (struct fragment6 *)kzmalloc(sizeof(struct fragment6) * size, 0);
if (ip->fragfree6 == NULL)
panic("initfrag");
@@ -230,9 +230,8 @@
f->ip->stats[Forwarding] = 1;
}
-int
-ipoput4(struct Fs *f,
- struct block *bp, int gating, int ttl, int tos, struct conv *c)
+int ipoput4(struct Fs *f, struct block *bp, int gating, int ttl, int tos, struct
+ conv *c)
{
ERRSTACK(1);
struct Ipifc *ifc;
@@ -455,7 +454,8 @@
hl = (h->vihl & 0xF) << 2;
if (hl < (IP_HLEN4 << 2)) {
ip->stats[InHdrErrors]++;
- netlog(f, Logip, "ip: %V bad hivl 0x%x\n", h->src, h->vihl);
+ netlog(f, Logip, "ip: %V bad hivl 0x%x\n", h->src,
+ h->vihl);
freeblist(bp);
return;
}
@@ -592,7 +592,7 @@
* find a reassembly queue for this fragment
*/
for (f = ip->flisthead4; f; f = fnext) {
- fnext = f->next; /* because ipfragfree4 changes the list */
+ fnext = f->next;/* because ipfragfree4 changes the list */
if (f->src == src && f->dst == dst && f->id == id)
break;
if (f->age < NOW) {
diff --git a/kern/src/net/ipaux.c b/kern/src/net/ipaux.c
index 5af22f6..35be18a 100644
--- a/kern/src/net/ipaux.c
+++ b/kern/src/net/ipaux.c
@@ -385,23 +385,23 @@
p++;
}
switch (CLASS(to)) {
- case 0: /* class A - 1 uint8_t net */
- case 1:
- if (i == 3) {
- to[3] = to[2];
- to[2] = to[1];
- to[1] = 0;
- } else if (i == 2) {
- to[3] = to[1];
- to[1] = 0;
- }
- break;
- case 2: /* class B - 2 uint8_t net */
- if (i == 3) {
- to[3] = to[2];
- to[2] = 0;
- }
- break;
+ case 0: /* class A - 1 uint8_t net */
+ case 1:
+ if (i == 3) {
+ to[3] = to[2];
+ to[2] = to[1];
+ to[1] = 0;
+ } else if (i == 2) {
+ to[3] = to[1];
+ to[1] = 0;
+ }
+ break;
+ case 2: /* class B - 2 uint8_t net */
+ if (i == 3) {
+ to[3] = to[2];
+ to[2] = 0;
+ }
+ break;
}
return p;
}
@@ -599,6 +599,7 @@
uint32_t iphash(uint8_t * sa, uint16_t sp, uint8_t * da, uint16_t dp)
{
uint32_t ret;
+
ret = (sa[IPaddrlen - 1] << 24) ^ (sp << 16) ^ (da[IPaddrlen - 1] << 8)
^ dp;
ret %= Nhash;
@@ -674,7 +675,7 @@
continue;
c = h->c;
if (sp == c->rport && dp == c->lport
- && ipcmp(sa, c->raddr) == 0 && ipcmp(da, c->laddr) == 0) {
+ && ipcmp(sa, c->raddr) == 0 && ipcmp(da, c->laddr) == 0) {
spin_unlock(&ht->lock);
return c;
}
@@ -739,7 +740,8 @@
for (h = ht->tab[i]; h != NULL; h = h->next) {
c = h->c;
printk("Conv proto %s, idx %d: local %I:%d, remote %I:%d\n",
- c->p->name, c->x, c->laddr, c->lport, c->raddr, c->rport);
+ c->p->name, c->x, c->laddr, c->lport, c->raddr,
+ c->rport);
}
}
spin_unlock(&ht->lock);
diff --git a/kern/src/net/ipifc.c b/kern/src/net/ipifc.c
index 3116508..cbf133e 100644
--- a/kern/src/net/ipifc.c
+++ b/kern/src/net/ipifc.c
@@ -60,7 +60,7 @@
struct Ipself *hnext; /* next address in the hash table */
struct Iplink *link; /* binding twixt Ipself and Ipifc */
uint32_t expire;
- uint8_t type; /* type of address */
+ uint8_t type; /* type of address */
int ref;
struct Ipself *next; /* free list */
};
@@ -68,7 +68,7 @@
struct Ipselftab {
qlock_t qlock;
int inited;
- int acceptall; /* true if an interface has the null address */
+ int acceptall; /* true if an interface has the null address */
struct Ipself *hash[NHASH]; /* hash chains */
};
@@ -89,13 +89,13 @@
static char tifc[] = "ifc ";
static void addselfcache(struct Fs *f, struct Ipifc *ifc, struct Iplifc *lifc,
- uint8_t * a, int type);
-static void remselfcache(struct Fs *f,
- struct Ipifc *ifc, struct Iplifc *lifc, uint8_t * a);
+ uint8_t *a, int type);
+static void remselfcache(struct Fs *f, struct Ipifc *ifc, struct Iplifc *lifc,
+ uint8_t *a);
static void ipifcjoinmulti(struct Ipifc *ifc, char **argv, int argc);
static void ipifcleavemulti(struct Ipifc *ifc, char **argv, int argc);
static void ipifcregisterproxy(struct Fs *, struct Ipifc *,
- uint8_t * unused_uint8_p_t);
+ uint8_t *unused_uint8_p_t);
static void ipifcremlifc(struct Ipifc *, struct Iplifc *);
static void ipifcaddpref6(struct Ipifc *ifc, char **argv, int argc);
@@ -247,18 +247,18 @@
ifc = (struct Ipifc *)c->ptcl;
- m = snprintf(state, n, sfixedformat,
- ifc->dev, ifc->maxtu, ifc->sendra6, ifc->recvra6,
- ifc->rp.mflag, ifc->rp.oflag, ifc->rp.maxraint,
- ifc->rp.minraint, ifc->rp.linkmtu, ifc->rp.reachtime,
- ifc->rp.rxmitra, ifc->rp.ttl, ifc->rp.routerlt,
- ifc->in, ifc->out, ifc->inerr, ifc->outerr, ifc->tracedrop);
+ m = snprintf(state, n, sfixedformat, ifc->dev, ifc->maxtu, ifc->sendra6,
+ ifc->recvra6, ifc->rp.mflag, ifc->rp.oflag,
+ ifc->rp.maxraint, ifc->rp.minraint, ifc->rp.linkmtu,
+ ifc->rp.reachtime, ifc->rp.rxmitra, ifc->rp.ttl,
+ ifc->rp.routerlt, ifc->in, ifc->out, ifc->inerr,
+ ifc->outerr, ifc->tracedrop);
rlock(&ifc->rwlock);
for (lifc = ifc->lifc; lifc && n > m; lifc = lifc->next)
- m += snprintf(state + m, n - m, slineformat,
- lifc->local, lifc->mask, lifc->remote,
- lifc->validlt, lifc->preflt);
+ m += snprintf(state + m, n - m, slineformat, lifc->local,
+ lifc->mask, lifc->remote, lifc->validlt,
+ lifc->preflt);
if (ifc->lifc == NULL)
m += snprintf(state + m, n - m, "\n");
runlock(&ifc->rwlock);
@@ -280,7 +280,8 @@
for (lifc = ifc->lifc; lifc; lifc = lifc->next) {
m += snprintf(state + m, n - m, "%-40.40I ->", lifc->local);
for (link = lifc->link; link; link = link->lifclink)
- m += snprintf(state + m, n - m, " %-40.40I", link->self->a);
+ m += snprintf(state + m, n - m, " %-40.40I",
+ link->self->a);
m += snprintf(state + m, n - m, "\n");
}
runlock(&ifc->rwlock);
@@ -342,8 +343,9 @@
ifc->m = NULL;
ifc->reassemble = 0;
rwinit(&ifc->rwlock);
- /* These are never used, but we might need them if we ever do "unbind on the
- * fly" (see ip.h). Not sure where the code went that used these vars. */
+ /* These are never used, but we might need them if we ever do "unbind on
+ * the fly" (see ip.h). Not sure where the code went that used these
+ * vars. */
spinlock_init(&ifc->idlock);
rendez_init(&ifc->wait);
}
@@ -405,35 +407,35 @@
memset(mask, 0, IPaddrlen);
memset(rem, 0, IPaddrlen);
switch (argc) {
- case 6:
- if (strcmp(argv[5], "proxy") == 0)
- type |= Rproxy;
- /* fall through */
- case 5:
- mtu = strtoul(argv[4], 0, 0);
- if (mtu >= ifc->m->mintu && mtu <= ifc->m->maxtu)
- ifc->maxtu = mtu;
- /* fall through */
- case 4:
- parseip(ip, argv[1]);
- parseipmask(mask, argv[2]);
- parseip(rem, argv[3]);
- maskip(rem, mask, net);
- break;
- case 3:
- parseip(ip, argv[1]);
- parseipmask(mask, argv[2]);
- maskip(ip, mask, rem);
- maskip(rem, mask, net);
- break;
- case 2:
- parseip(ip, argv[1]);
- memmove(mask, defmask(ip), IPaddrlen);
- maskip(ip, mask, rem);
- maskip(rem, mask, net);
- break;
- default:
- error(EINVAL, "Bad arg num to %s", __func__);
+ case 6:
+ if (strcmp(argv[5], "proxy") == 0)
+ type |= Rproxy;
+ /* fall through */
+ case 5:
+ mtu = strtoul(argv[4], 0, 0);
+ if (mtu >= ifc->m->mintu && mtu <= ifc->m->maxtu)
+ ifc->maxtu = mtu;
+ /* fall through */
+ case 4:
+ parseip(ip, argv[1]);
+ parseipmask(mask, argv[2]);
+ parseip(rem, argv[3]);
+ maskip(rem, mask, net);
+ break;
+ case 3:
+ parseip(ip, argv[1]);
+ parseipmask(mask, argv[2]);
+ maskip(ip, mask, rem);
+ maskip(rem, mask, net);
+ break;
+ case 2:
+ parseip(ip, argv[1]);
+ memmove(mask, defmask(ip), IPaddrlen);
+ maskip(ip, mask, rem);
+ maskip(rem, mask, net);
+ break;
+ default:
+ error(EINVAL, "Bad arg num to %s", __func__);
}
if (isv4(ip))
tentative = 0;
@@ -486,13 +488,14 @@
*l = lifc;
/* check for point-to-point interface */
- if (ipcmp(ip, v6loopback)) /* skip v6 loopback, it's a special address */
+ if (ipcmp(ip, v6loopback))/* skip v6 loopback, it's a special address */
if (ipcmp(mask, IPallbits) == 0)
type |= Rptpt;
/* add local routes */
if (isv4(ip))
- v4addroute(f, tifc, rem + IPv4off, mask + IPv4off, rem + IPv4off, type);
+ v4addroute(f, tifc, rem + IPv4off, mask + IPv4off, rem +
+ IPv4off, type);
else
v6addroute(f, tifc, rem, mask, rem, type);
@@ -533,15 +536,16 @@
addselfcache(f, ifc, lifc, v6allnodesN, Rmulti);
/* add route for all node multicast */
- v6addroute(f, tifc, v6allnodesN, v6allnodesNmask, v6allnodesN,
- Rmulti);
+ v6addroute(f, tifc, v6allnodesN, v6allnodesNmask,
+ v6allnodesN, Rmulti);
}
/* add all nodes multicast address */
addselfcache(f, ifc, lifc, v6allnodesL, Rmulti);
/* add route for all nodes multicast */
- v6addroute(f, tifc, v6allnodesL, v6allnodesLmask, v6allnodesL, Rmulti);
+ v6addroute(f, tifc, v6allnodesL, v6allnodesLmask, v6allnodesL,
+ Rmulti);
/* add solicited-node multicast address */
ipv62smcast(bcast, ip);
@@ -651,9 +655,8 @@
* distribute routes to active interfaces like the
* TRIP linecards
*/
-void
-ipifcaddroute(struct Fs *f, int vers, uint8_t * addr, uint8_t * mask,
- uint8_t * gate, int type)
+void ipifcaddroute(struct Fs *f, int vers, uint8_t *addr, uint8_t *mask,
+ uint8_t *gate, int type)
{
struct medium *m;
struct conv **cp, **e;
@@ -730,7 +733,8 @@
i = 1;
if (argsleft % 2 != 0)
- error(EINVAL, "Non-even number of args (%d) to %s", argc, __func__);
+ error(EINVAL, "Non-even number of args (%d) to %s", argc,
+ __func__);
while (argsleft > 1) {
if (strcmp(argv[i], "recvra") == 0)
@@ -866,8 +870,8 @@
ipifc->nc = Maxmedia;
ipifc->ptclsize = sizeof(struct Ipifc);
- f->ipifc = ipifc; /* hack for ipifcremroute, findipifc, ... */
- f->self = kzmalloc(sizeof(struct Ipselftab), 0); /* hack for ipforme */
+ f->ipifc = ipifc; /* hack for ipifcremroute, findipifc, ... */
+ f->self = kzmalloc(sizeof(struct Ipselftab), 0); /* hack for ipforme */
qlock_init(&f->self->qlock);
Fsproto(f, ipifc);
@@ -888,9 +892,8 @@
* add to self routing cache
* called with c locked
*/
-static void
-addselfcache(struct Fs *f, struct Ipifc *ifc,
- struct Iplifc *lifc, uint8_t * a, int type)
+static void addselfcache(struct Fs *f, struct Ipifc *ifc,
+ struct Iplifc *lifc, uint8_t *a, int type)
{
struct Ipself *p;
struct Iplink *lp;
@@ -935,8 +938,8 @@
/* add to routing table */
if (isv4(a))
- v4addroute(f, tifc, a + IPv4off, IPallbits + IPv4off, a + IPv4off,
- type);
+ v4addroute(f, tifc, a + IPv4off, IPallbits + IPv4off,
+ a + IPv4off, type);
else
v6addroute(f, tifc, a, IPallbits, a, type);
@@ -1001,8 +1004,8 @@
* Unlink from selftab if this is the last ref.
* called with c locked
*/
-static void
-remselfcache(struct Fs *f, struct Ipifc *ifc, struct Iplifc *lifc, uint8_t *a)
+static void remselfcache(struct Fs *f, struct Ipifc *ifc, struct Iplifc *lifc,
+ uint8_t *a)
{
struct Ipself *p, **l;
struct Iplink *link, **l_self, **l_lifc;
@@ -1323,45 +1326,46 @@
/* find ifc address closest to the gateway to use */
switch (version) {
- case V4:
- for (lifc = ifc->lifc; lifc; lifc = lifc->next) {
- maskip(gate, lifc->mask, gnet);
- if (ipcmp(gnet, lifc->net) == 0) {
- ipmove(local, lifc->local);
- goto out;
- }
- }
- break;
- case V6:
- for (lifc = ifc->lifc; lifc; lifc = lifc->next) {
- atypel = v6addrtype(lifc->local);
- maskip(gate, lifc->mask, gnet);
- if (ipcmp(gnet, lifc->net) == 0)
- if (atypel > atype)
- if (v6addrcurr(lifc)) {
- ipmove(local, lifc->local);
- atype = atypel;
- if (atype == globalv6)
- break;
- }
- }
- if (atype > unspecifiedv6)
+ case V4:
+ for (lifc = ifc->lifc; lifc; lifc = lifc->next) {
+ maskip(gate, lifc->mask, gnet);
+ if (ipcmp(gnet, lifc->net) == 0) {
+ ipmove(local, lifc->local);
goto out;
- break;
- default:
- panic("findlocalip: version %d", version);
+ }
+ }
+ break;
+ case V6:
+ for (lifc = ifc->lifc; lifc; lifc = lifc->next) {
+ atypel = v6addrtype(lifc->local);
+ maskip(gate, lifc->mask, gnet);
+ if (ipcmp(gnet, lifc->net) == 0)
+ if (atypel > atype)
+ if (v6addrcurr(lifc)) {
+ ipmove(local,
+ lifc->local);
+ atype = atypel;
+ if (atype == globalv6)
+ break;
+ }
+ }
+ if (atype > unspecifiedv6)
+ goto out;
+ break;
+ default:
+ panic("findlocalip: version %d", version);
}
}
switch (version) {
- case V4:
- findprimaryipv4(f, local);
- break;
- case V6:
- findprimaryipv6(f, local);
- break;
- default:
- panic("findlocalip2: version %d", version);
+ case V4:
+ findprimaryipv4(f, local);
+ break;
+ case V6:
+ findprimaryipv6(f, local);
+ break;
+ default:
+ panic("findlocalip2: version %d", version);
}
out:
@@ -1623,9 +1627,12 @@
}
for (lifc = nifc->lifc; lifc; lifc = lifc->next) {
maskip(ip, lifc->mask, net);
- if (ipcmp(net, lifc->remote) == 0) { /* add solicited-node multicast address */
+ if (ipcmp(net, lifc->remote) == 0) {
+ /* add solicited-node multicast address
+ */
ipv62smcast(net, ip);
- addselfcache(f, nifc, lifc, net, Rmulti);
+ addselfcache(f, nifc, lifc, net,
+ Rmulti);
arpenter(f, V6, ip, nifc->mac, 6, 0);
//(*m->addmulti)(nifc, net, ip);
break;
@@ -1667,9 +1674,10 @@
r = v6lookup(f, v6Unspecified, NULL);
if (r != NULL)
- if (!(force) && (strcmp(r->rt.tag, "ra") != 0)) // route entries generated
- return; // by all other means take
- // precedence over router annc
+ if (!(force) && (strcmp(r->rt.tag, "ra") != 0))
+ return;
+ // route entries generated by all other means take precedence over
+ // router annc
v6delroute(f, v6Unspecified, v6Unspecified, 1);
v6addroute(f, "ra", v6Unspecified, v6Unspecified, gate, 0);
@@ -1693,29 +1701,28 @@
char *params[3];
switch (argc) {
- case 7:
- preflt = atoi(argv[6]);
- /* fall through */
- case 6:
- validlt = atoi(argv[5]);
- /* fall through */
- case 5:
- autoflag = atoi(argv[4]);
- /* fall through */
- case 4:
- onlink = atoi(argv[3]);
- /* fall through */
- case 3:
- plen = atoi(argv[2]);
- case 2:
- break;
- default:
- error(EINVAL, "Bad arg num to %s", __func__);
+ case 7:
+ preflt = atoi(argv[6]);
+ /* fall through */
+ case 6:
+ validlt = atoi(argv[5]);
+ /* fall through */
+ case 5:
+ autoflag = atoi(argv[4]);
+ /* fall through */
+ case 4:
+ onlink = atoi(argv[3]);
+ /* fall through */
+ case 3:
+ plen = atoi(argv[2]);
+ case 2:
+ break;
+ default:
+ error(EINVAL, "Bad arg num to %s", __func__);
}
- if ((parseip(prefix, argv[1]) != 6) ||
- (validlt < preflt) || (plen < 0) || (plen > 64) || (islinklocal(prefix))
- )
+ if ((parseip(prefix, argv[1]) != 6) || (validlt < preflt) || (plen < 0)
+ || (plen > 64) || (islinklocal(prefix)))
error(EFAIL, "IP parsing failed");
lifc = kzmalloc(sizeof(struct Iplifc), 0);
diff --git a/kern/src/net/iproute.c b/kern/src/net/iproute.c
index 78000f1..482113c 100644
--- a/kern/src/net/iproute.c
+++ b/kern/src/net/iproute.c
@@ -282,40 +282,40 @@
}
switch (rangecompare(new, p)) {
- case Rpreceeds:
- addnode(f, &p->rt.left, new);
- break;
- case Rfollows:
- addnode(f, &p->rt.right, new);
- break;
- case Rcontains:
- /*
- * if new node is superset
- * of tree node,
- * replace tree node and
- * queue tree node to be
- * merged into root.
- */
- *cur = new;
- new->rt.depth = 1;
- addqueue(&f->queue, p);
- break;
- case Requals:
- /*
- * supercede the old entry if the old one isn't
- * a local interface.
- */
- if ((p->rt.type & Rifc) == 0) {
- p->rt.type = new->rt.type;
- p->rt.ifcid = -1;
- copygate(p, new);
- } else if (new->rt.type & Rifc)
- kref_get(&p->rt.kref, 1);
- freeroute(new);
- break;
- case Rcontained:
- addnode(f, &p->rt.mid, new);
- break;
+ case Rpreceeds:
+ addnode(f, &p->rt.left, new);
+ break;
+ case Rfollows:
+ addnode(f, &p->rt.right, new);
+ break;
+ case Rcontains:
+ /*
+ * if new node is superset
+ * of tree node,
+ * replace tree node and
+ * queue tree node to be
+ * merged into root.
+ */
+ *cur = new;
+ new->rt.depth = 1;
+ addqueue(&f->queue, p);
+ break;
+ case Requals:
+ /*
+ * supercede the old entry if the old one isn't
+ * a local interface.
+ */
+ if ((p->rt.type & Rifc) == 0) {
+ p->rt.type = new->rt.type;
+ p->rt.ifcid = -1;
+ copygate(p, new);
+ } else if (new->rt.type & Rifc)
+ kref_get(&p->rt.kref, 1);
+ freeroute(new);
+ break;
+ case Rcontained:
+ addnode(f, &p->rt.mid, new);
+ break;
}
balancetree(cur);
@@ -323,9 +323,8 @@
#define V4H(a) ((a&0x07ffffff)>>(32-Lroot-5))
-void
-v4addroute(struct Fs *f, char *tag, uint8_t * a, uint8_t * mask,
- uint8_t * gate, int type)
+void v4addroute(struct Fs *f, char *tag, uint8_t *a, uint8_t *mask,
+ uint8_t *gate, int type)
{
struct route *p;
uint32_t sa;
@@ -362,9 +361,8 @@
#define V6H(a) (((a)[IPllen-1] & 0x07ffffff)>>(32-Lroot-5))
#define ISDFLT(a, mask, tag) ((ipcmp((a),v6Unspecified)==0) && (ipcmp((mask),v6Unspecified)==0) && (strcmp((tag), "ra")!=0))
-void
-v6addroute(struct Fs *f, char *tag, uint8_t * a, uint8_t * mask,
- uint8_t * gate, int type)
+void v6addroute(struct Fs *f, char *tag, uint8_t *a, uint8_t *mask,
+ uint8_t *gate, int type)
{
struct route *p;
uint32_t sa[IPllen], ea[IPllen];
@@ -415,24 +413,24 @@
return 0;
switch (rangecompare(r, p)) {
- case Rcontains:
- return 0;
- case Rpreceeds:
- cur = &p->rt.left;
- break;
- case Rfollows:
- cur = &p->rt.right;
- break;
- case Rcontained:
- cur = &p->rt.mid;
- break;
- case Requals:
- return cur;
+ case Rcontains:
+ return 0;
+ case Rpreceeds:
+ cur = &p->rt.left;
+ break;
+ case Rfollows:
+ cur = &p->rt.right;
+ break;
+ case Rcontained:
+ cur = &p->rt.mid;
+ break;
+ case Requals:
+ return cur;
}
}
}
-void v4delroute(struct Fs *f, uint8_t * a, uint8_t * mask, int dolock)
+void v4delroute(struct Fs *f, uint8_t *a, uint8_t *mask, int dolock)
{
struct route **r, *p;
struct route rt;
@@ -451,9 +449,10 @@
r = looknode(&f->v4root[h], &rt);
if (r) {
p = *r;
- /* TODO: bad usage of kref (maybe use a release). I didn't change
- * this one, since it looks like the if code is when we want to
- * release. btw, use better code reuse btw v4 and v6... */
+ /* TODO: bad usage of kref (maybe use a release). I
+ * didn't change this one, since it looks like the if
+ * code is when we want to release. btw, use better
+ * code reuse btw v4 and v6... */
if (kref_put(&p->rt.kref)) {
*r = 0;
addqueue(&f->queue, p->rt.left);
@@ -497,9 +496,10 @@
r = looknode(&f->v6root[h], &rt);
if (r) {
p = *r;
- /* TODO: bad usage of kref (maybe use a release). I didn't change
- * this one, since it looks like the if code is when we want to
- * release. btw, use better code reuse btw v4 and v6... */
+ /* TODO: bad usage of kref (maybe use a release). I
+ * didn't change this one, since it looks like the if
+ * code is when we want to release. btw, use better
+ * code reuse btw v4 and v6... */
if (kref_put(&p->rt.kref)) {
*r = 0;
addqueue(&f->queue, p->rt.left);
@@ -658,9 +658,8 @@
char *rformat = "%-15I %-4M %-15I %4.4s %4.4s %3s\n";
-void
-convroute(struct route *r, uint8_t * addr, uint8_t * mask,
- uint8_t * gate, char *t, int *nifc)
+void convroute(struct route *r, uint8_t *addr, uint8_t *mask, uint8_t *gate,
+ char *t, int *nifc)
{
int i;
@@ -674,7 +673,8 @@
} else {
for (i = 0; i < IPllen; i++) {
hnputl(addr + 4 * i, r->v6.address[i]);
- hnputl(mask + 4 * i, ~(r->v6.endaddress[i] ^ r->v6.address[i]));
+ hnputl(mask + 4 * i,
+ ~(r->v6.endaddress[i] ^ r->v6.address[i]));
}
memmove(gate, r->v6.gate, IPaddrlen);
}
@@ -703,7 +703,8 @@
iname = ifbuf;
snprintf(ifbuf, sizeof ifbuf, "%d", nifc);
}
- p = seprintf(rw->p, rw->e, rformat, addr, mask, gate, t, r->rt.tag, iname);
+ p = seprintf(rw->p, rw->e, rformat, addr, mask, gate, t, r->rt.tag,
+ iname);
if (rw->o < 0) {
n = p - rw->p;
if (n > -rw->o) {
@@ -807,7 +808,8 @@
if (routeflush(f, r->rt.right, tag))
return 1;
if ((r->rt.type & Rifc) == 0) {
- if (tag == NULL || strncmp(tag, r->rt.tag, sizeof(r->rt.tag)) == 0) {
+ if (tag == NULL ||
+ strncmp(tag, r->rt.tag, sizeof(r->rt.tag)) == 0) {
delroute(f, r, 0);
return 1;
}
@@ -869,8 +871,8 @@
tag = a->tag;
}
if (memcmp(addr, v4prefix, IPv4off) == 0)
- v4addroute(f, tag, addr + IPv4off, mask + IPv4off, gate + IPv4off,
- 0);
+ v4addroute(f, tag, addr + IPv4off, mask + IPv4off,
+ gate + IPv4off, 0);
else
v6addroute(f, tag, addr, mask, gate, 0);
} else if (strcmp(cb->f[0], "tag") == 0) {
diff --git a/kern/src/net/ipv6.c b/kern/src/net/ipv6.c
index 163b533..a05db98 100644
--- a/kern/src/net/ipv6.c
+++ b/kern/src/net/ipv6.c
@@ -32,12 +32,12 @@
#include <kmalloc.h>
enum {
- IP4HDR = 20, /* sizeof(Ip4hdr) */
- IP6HDR = 40, /* sizeof(Ip6hdr) */
+ IP4HDR = 20, /* sizeof(Ip4hdr) */
+ IP6HDR = 40, /* sizeof(Ip6hdr) */
IP_HLEN4 = 0x05, /* Header length in words */
- IP_DF = 0x4000, /* Don't fragment */
- IP_MF = 0x2000, /* More fragments */
- IP6FHDR = 8, /* sizeof(Fraghdr6) */
+ IP_DF = 0x4000, /* Don't fragment */
+ IP_MF = 0x2000, /* More fragments */
+ IP6FHDR = 8, /* sizeof(Fraghdr6) */
IP_MAX = (32 * 1024), /* Maximum Internet packet size */
};
@@ -142,7 +142,7 @@
struct fragment6 *fragfree6;
int id6;
- int iprouting; /* true if we route like a gateway */
+ int iprouting; /* true if we route like a gateway */
};
int ipoput6(struct Fs *f, struct block *bp,
@@ -176,7 +176,8 @@
tentative = iptentative(f, eh->src);
if (tentative) {
- netlog(f, Logip, "reject tx of packet with tentative src address\n");
+ netlog(f, Logip,
+ "reject tx of packet with tentative src address\n");
goto free;
}
@@ -250,13 +251,14 @@
if (gating)
if (ifc->reassemble <= 0) {
/*
- * v6 intermediate nodes are not supposed to fragment pkts;
- * we fragment if ifc->reassemble is turned on; an exception
- * needed for nat.
+ * v6 intermediate nodes are not supposed to fragment
+ * pkts; we fragment if ifc->reassemble is turned on; an
+ * exception needed for nat.
*/
ip->stats[OutDiscards]++;
icmppkttoobig6(f, ifc, bp);
- netlog(f, Logip, "%I: gated pkts not fragmented\n", eh->dst);
+ netlog(f, Logip, "%I: gated pkts not fragmented\n",
+ eh->dst);
goto raise;
}
@@ -393,7 +395,8 @@
/* Check header version */
if (BLKIPVER(bp) != IP_VER6) {
ip->stats[InHdrErrors]++;
- netlog(f, Logip, "ip: bad version 0x%x\n", (h->vcf[0] & 0xF0) >> 2);
+ netlog(f, Logip, "ip: bad version 0x%x\n",
+ (h->vcf[0] & 0xF0) >> 2);
freeblist(bp);
return;
}
@@ -529,10 +532,10 @@
return bp;
}
-/* returns length of "Unfragmentable part", i.e., sum of lengths of ipv6 hdr,
- * hop-by-hop & routing headers if present; *nexthdr is set to nexthdr value
- * of the last header in the "Unfragmentable part"; if setfh != 0, nexthdr
- * field of the last header in the "Unfragmentable part" is set to FH.
+/* returns length of "Unfragmentable part", i.e., sum of lengths of ipv6 hdr,
+ * hop-by-hop & routing headers if present; *nexthdr is set to nexthdr value of
+ * the last header in the "Unfragmentable part"; if setfh != 0, nexthdr field of
+ * the last header in the "Unfragmentable part" is set to FH.
*/
int unfraglen(struct block *bp, uint8_t * nexthdr, int setfh)
{
@@ -540,7 +543,7 @@
int ufl, hs;
p = bp->rp;
- q = p + 6; /* proto, = p+sizeof(Ip6hdr.vcf)+sizeof(Ip6hdr.ploadlen) */
+ q = p + 6; /* proto, = p+sizeof(Ip6hdr.vcf)+sizeof(Ip6hdr.ploadlen) */
*nexthdr = *q;
ufl = IP6HDR;
p += ufl;
@@ -603,7 +606,8 @@
*/
for (f = ip->flisthead6; f; f = fnext) {
fnext = f->next;
- if (ipcmp(f->src, src) == 0 && ipcmp(f->dst, dst) == 0 && f->id == id)
+ if (ipcmp(f->src, src) == 0 && ipcmp(f->dst, dst) == 0
+ && f->id == id)
break;
if (f->age < NOW) {
ip->stats[ReasmTimeout]++;
@@ -720,7 +724,8 @@
memmove(bl->rp + IP6FHDR, bl->rp, uflen);
bl->rp += IP6FHDR;
- len = nhgets(((struct ip6hdr *)(bl->rp))->ploadlen) - IP6FHDR;
+ len = nhgets(((struct ip6hdr *)(bl->rp))->ploadlen) -
+ IP6FHDR;
bl->wp = bl->rp + len + IP6HDR;
/* Pullup all the fragment headers and
diff --git a/kern/src/net/loopbackmedium.c b/kern/src/net/loopbackmedium.c
index 81537cf..4cdf617 100644
--- a/kern/src/net/loopbackmedium.c
+++ b/kern/src/net/loopbackmedium.c
@@ -51,8 +51,8 @@
static void loopbackread(void *a);
-static void
-loopbackbind(struct Ipifc *ifc, int unused_int, char **unused_char_pp_t)
+static void loopbackbind(struct Ipifc *ifc, int unused_int,
+ char **unused_char_pp_t)
{
LB *lb;
@@ -85,9 +85,8 @@
kfree(lb);
}
-static void
-loopbackbwrite(struct Ipifc *ifc, struct block *bp, int unused_int,
- uint8_t * unused_uint8_p_t)
+static void loopbackbwrite(struct Ipifc *ifc, struct block *bp, int unused_int,
+ uint8_t *unused_uint8_p_t)
{
LB *lb;
diff --git a/kern/src/net/netif.c b/kern/src/net/netif.c
index 3e4c15b..20ecac2 100644
--- a/kern/src/net/netif.c
+++ b/kern/src/net/netif.c
@@ -42,8 +42,8 @@
static int openfile(struct ether *, int);
static char *matchtoken(char *unused_char_p_t, char *);
static char *netmulti(struct ether *, struct netfile *,
- uint8_t * unused_uint8_p_t, int);
-static int parseaddr(uint8_t * unused_uint8_p_t, char *unused_char_p_t, int);
+ uint8_t *unused_uint8_p_t, int);
+static int parseaddr(uint8_t *unused_uint8_p_t, char *unused_char_p_t, int);
/*
* set up a new network interface
@@ -64,9 +64,8 @@
/*
* generate a 3 level directory
*/
-static int
-netifgen(struct chan *c, char *unused_char_p_t, struct dirtab *vp,
- int unused_int, int i, struct dir *dp)
+static int netifgen(struct chan *c, char *unused_char_p_t, struct dirtab *vp,
+ int unused_int, int i, struct dir *dp)
{
struct qid q;
struct ether *nif = (struct ether *)vp;
@@ -80,19 +79,19 @@
/* top level directory contains the name of the network */
if (c->qid.path == 0) {
switch (i) {
- case DEVDOTDOT:
- q.path = 0;
- q.type = QTDIR;
- devdir(c, q, ".", 0, eve.name, 0555, dp);
- break;
- case 0:
- q.path = N2ndqid;
- q.type = QTDIR;
- strlcpy(get_cur_genbuf(), nif->name, GENBUF_SZ);
- devdir(c, q, get_cur_genbuf(), 0, eve.name, 0555, dp);
- break;
- default:
- return -1;
+ case DEVDOTDOT:
+ q.path = 0;
+ q.type = QTDIR;
+ devdir(c, q, ".", 0, eve.name, 0555, dp);
+ break;
+ case 0:
+ q.path = N2ndqid;
+ q.type = QTDIR;
+ strlcpy(get_cur_genbuf(), nif->name, GENBUF_SZ);
+ devdir(c, q, get_cur_genbuf(), 0, eve.name, 0555, dp);
+ break;
+ default:
+ return -1;
}
return 1;
}
@@ -100,33 +99,33 @@
/* second level contains clone plus all the conversations.
*
* This ancient comment is from plan9. Inferno and nxm both had issues
- * here. You couldn't ls /net/ether0/ when it didn't have any convs. There
- * were also issues with nxm where you couldn't stat ether0/x/stats
- * properly.
+ * here. You couldn't ls /net/ether0/ when it didn't have any convs.
+ * There were also issues with nxm where you couldn't stat
+ * ether0/x/stats properly.
*
- * The issue is that if we handle things like Nstatqid, then we will never
- * pass it down to the third level. And since we just set the path ==
- * Nstatqid, we won't have the NETID muxed in. If someone isn't trying to
- * generate a chan, but instead is looking it up (devwalk generates, devstat
- * already has the chan), then they are also looking for a devdir with path
- * containing ID << 5. So if you stat ether0/1/ifstats, devstat is looking
- * for path 41, but we return path 9 (41 = 32 + 9). (these numbers are
- * before we tracked NETID + 1).
+ * The issue is that if we handle things like Nstatqid, then we will
+ * never pass it down to the third level. And since we just set the path
+ * == Nstatqid, we won't have the NETID muxed in. If someone isn't
+ * trying to generate a chan, but instead is looking it up (devwalk
+ * generates, devstat already has the chan), then they are also looking
+ * for a devdir with path containing ID << 5. So if you stat
+ * ether0/1/ifstats, devstat is looking for path 41, but we return path
+ * 9 (41 = 32 + 9). (these numbers are before we tracked NETID + 1).
*
- * We (akaros and plan9) had a big if here, that would catch things that do
- * not exist in the subdirs of a netif. Things like clone make sense here.
- * I guess addr too, though that seems to be added since the original
- * comment. You can see what the 3rd level was expecting to parse by looking
- * farther down in the code.
+ * We (akaros and plan9) had a big if here, that would catch things that
+ * do not exist in the subdirs of a netif. Things like clone make sense
+ * here. I guess addr too, though that seems to be added since the
+ * original comment. You can see what the 3rd level was expecting to
+ * parse by looking farther down in the code.
*
* The root of the problem was that the old code couldn't tell the
- * difference between no netid and netid 0. Now, we determine if we're at
- * the second level by the lack of a netid, instead of trying to enumerate
- * the qid types that the second level could have. The latter approach
- * allowed for something like ether0/1/stats, but we couldn't actually
- * devstat ether0/stats directly. It's worth noting that there is no
- * difference to the content of ether0/stats and ether0/x/stats (when you
- * read), but they have different chan qids.
+ * difference between no netid and netid 0. Now, we determine if we're
+ * at the second level by the lack of a netid, instead of trying to
+ * enumerate the qid types that the second level could have. The latter
+ * approach allowed for something like ether0/1/stats, but we couldn't
+ * actually devstat ether0/stats directly. It's worth noting that there
+ * is no difference to the content of ether0/stats and ether0/x/stats
+ * (when you read), but they have different chan qids.
*
* Here's the old if block:
t = NETTYPE(c->qid.path);
@@ -134,38 +133,39 @@
*/
if (NETID(c->qid.path) == -1) {
switch (i) {
- case DEVDOTDOT:
- q.type = QTDIR;
- q.path = 0;
- devdir(c, q, ".", 0, eve.name, DMDIR | 0555, dp);
- break;
- case 0:
- q.path = Ncloneqid;
- devdir(c, q, "clone", 0, eve.name, 0666, dp);
- break;
- case 1:
- q.path = Naddrqid;
- devdir(c, q, "addr", 0, eve.name, 0666, dp);
- break;
- case 2:
- q.path = Nstatqid;
- devdir(c, q, "stats", 0, eve.name, 0444, dp);
- break;
- case 3:
- q.path = Nifstatqid;
- devdir(c, q, "ifstats", 0, eve.name, 0444, dp);
- break;
- default:
- i -= 4;
- if (i >= nif->nfile)
- return -1;
- if (nif->f[i] == 0)
- return 0;
- q.type = QTDIR;
- q.path = NETQID(i, N3rdqid);
- snprintf(get_cur_genbuf(), GENBUF_SZ, "%d", i);
- devdir(c, q, get_cur_genbuf(), 0, eve.name, DMDIR | 0555, dp);
- break;
+ case DEVDOTDOT:
+ q.type = QTDIR;
+ q.path = 0;
+ devdir(c, q, ".", 0, eve.name, DMDIR | 0555, dp);
+ break;
+ case 0:
+ q.path = Ncloneqid;
+ devdir(c, q, "clone", 0, eve.name, 0666, dp);
+ break;
+ case 1:
+ q.path = Naddrqid;
+ devdir(c, q, "addr", 0, eve.name, 0666, dp);
+ break;
+ case 2:
+ q.path = Nstatqid;
+ devdir(c, q, "stats", 0, eve.name, 0444, dp);
+ break;
+ case 3:
+ q.path = Nifstatqid;
+ devdir(c, q, "ifstats", 0, eve.name, 0444, dp);
+ break;
+ default:
+ i -= 4;
+ if (i >= nif->nfile)
+ return -1;
+ if (nif->f[i] == 0)
+ return 0;
+ q.type = QTDIR;
+ q.path = NETQID(i, N3rdqid);
+ snprintf(get_cur_genbuf(), GENBUF_SZ, "%d", i);
+ devdir(c, q, get_cur_genbuf(), 0, eve.name,
+ DMDIR | 0555, dp);
+ break;
}
return 1;
}
@@ -182,34 +182,34 @@
perm = 0666;
}
switch (i) {
- case DEVDOTDOT:
- q.type = QTDIR;
- q.path = N2ndqid;
- strlcpy(get_cur_genbuf(), nif->name, GENBUF_SZ);
- devdir(c, q, get_cur_genbuf(), 0, eve.name, DMDIR | 0555, dp);
- break;
- case 0:
- q.path = NETQID(NETID(c->qid.path), Ndataqid);
- devdir(c, q, "data", 0, o, perm, dp);
- break;
- case 1:
- q.path = NETQID(NETID(c->qid.path), Nctlqid);
- devdir(c, q, "ctl", 0, o, perm, dp);
- break;
- case 2:
- q.path = NETQID(NETID(c->qid.path), Nstatqid);
- devdir(c, q, "stats", 0, eve.name, 0444, dp);
- break;
- case 3:
- q.path = NETQID(NETID(c->qid.path), Ntypeqid);
- devdir(c, q, "type", 0, eve.name, 0444, dp);
- break;
- case 4:
- q.path = NETQID(NETID(c->qid.path), Nifstatqid);
- devdir(c, q, "ifstats", 0, eve.name, 0444, dp);
- break;
- default:
- return -1;
+ case DEVDOTDOT:
+ q.type = QTDIR;
+ q.path = N2ndqid;
+ strlcpy(get_cur_genbuf(), nif->name, GENBUF_SZ);
+ devdir(c, q, get_cur_genbuf(), 0, eve.name, DMDIR | 0555, dp);
+ break;
+ case 0:
+ q.path = NETQID(NETID(c->qid.path), Ndataqid);
+ devdir(c, q, "data", 0, o, perm, dp);
+ break;
+ case 1:
+ q.path = NETQID(NETID(c->qid.path), Nctlqid);
+ devdir(c, q, "ctl", 0, o, perm, dp);
+ break;
+ case 2:
+ q.path = NETQID(NETID(c->qid.path), Nstatqid);
+ devdir(c, q, "stats", 0, eve.name, 0444, dp);
+ break;
+ case 3:
+ q.path = NETQID(NETID(c->qid.path), Ntypeqid);
+ devdir(c, q, "type", 0, eve.name, 0444, dp);
+ break;
+ case 4:
+ q.path = NETQID(NETID(c->qid.path), Nifstatqid);
+ devdir(c, q, "ifstats", 0, eve.name, 0444, dp);
+ break;
+ default:
+ return -1;
}
return 1;
}
@@ -231,26 +231,26 @@
error(EPERM, ERROR_FIXME);
} else {
switch (NETTYPE(c->qid.path)) {
- case Ndataqid:
- case Nctlqid:
- id = NETID(c->qid.path);
- openfile(nif, id);
- break;
- case Ncloneqid:
- id = openfile(nif, -1);
- c->qid.path = NETQID(id, Nctlqid);
- break;
- default:
- if (omode & O_WRITE)
- error(EINVAL, ERROR_FIXME);
+ case Ndataqid:
+ case Nctlqid:
+ id = NETID(c->qid.path);
+ openfile(nif, id);
+ break;
+ case Ncloneqid:
+ id = openfile(nif, -1);
+ c->qid.path = NETQID(id, Nctlqid);
+ break;
+ default:
+ if (omode & O_WRITE)
+ error(EINVAL, ERROR_FIXME);
}
switch (NETTYPE(c->qid.path)) {
- case Ndataqid:
- case Nctlqid:
- f = nif->f[id];
- if (netown(f, current->user.name, omode & 7) < 0)
- error(EPERM, ERROR_FIXME);
- break;
+ case Ndataqid:
+ case Nctlqid:
+ f = nif->f[id];
+ if (netown(f, current->user.name, omode & 7) < 0)
+ error(EPERM, ERROR_FIXME);
+ break;
}
}
c->mode = openmode(omode);
@@ -282,9 +282,8 @@
return sofar;
}
-long
-netifread(struct ether *nif, struct chan *c, void *a, long n,
- uint32_t offset)
+long netifread(struct ether *nif, struct chan *c, void *a, long n,
+ uint32_t offset)
{
int i, j;
struct netfile *f;
@@ -294,62 +293,67 @@
return devdirread(c, a, n, (struct dirtab *)nif, 0, netifgen);
switch (NETTYPE(c->qid.path)) {
- case Ndataqid:
- f = nif->f[NETID(c->qid.path)];
- return qread(f->in, a, n);
- case Nctlqid:
- return readnum(offset, a, n, NETID(c->qid.path), NUMSIZE);
- case Nstatqid:
- p = kzmalloc(READSTR, 0);
- if (p == NULL)
- return 0;
- j = 0;
- j += snprintf(p + j, READSTR - j, "driver: %s\n", nif->drv_name);
- j += snprintf(p + j, READSTR - j, "in: %d\n", nif->inpackets);
- j += snprintf(p + j, READSTR - j, "link: %d\n", nif->link);
- j += snprintf(p + j, READSTR - j, "out: %d\n", nif->outpackets);
- j += snprintf(p + j, READSTR - j, "crc errs: %d\n", nif->crcs);
- j += snprintf(p + j, READSTR - j, "overflows: %d\n",
- nif->overflows);
- j += snprintf(p + j, READSTR - j, "soft overflows: %d\n",
- nif->soverflows);
- j += snprintf(p + j, READSTR - j, "framing errs: %d\n",
- nif->frames);
- j += snprintf(p + j, READSTR - j, "buffer errs: %d\n", nif->buffs);
- j += snprintf(p + j, READSTR - j, "output errs: %d\n", nif->oerrs);
- j += snprintf(p + j, READSTR - j, "prom: %d\n", nif->prom);
- j += snprintf(p + j, READSTR - j, "mbps: %d\n", nif->mbps);
- j += snprintf(p + j, READSTR - j, "addr: ");
- for (i = 0; i < nif->alen; i++)
- j += snprintf(p + j, READSTR - j, "%02.2x", nif->addr[i]);
- j += snprintf(p + j, READSTR - j, "\n");
-
- j += snprintf(p + j, READSTR - j, "feat: ");
- j = feature_appender(nif->feat, p, j);
- j += snprintf(p + j, READSTR - j, "\n");
-
- j += snprintf(p + j, READSTR - j, "hw_features: ");
- j = feature_appender(nif->hw_features, p, j);
- j += snprintf(p + j, READSTR - j, "\n");
-
- n = readstr(offset, a, n, p);
- kfree(p);
- return n;
- case Naddrqid:
- p = kzmalloc(READSTR, 0);
- if (p == NULL)
- return 0;
- j = 0;
- for (i = 0; i < nif->alen; i++)
- j += snprintf(p + j, READSTR - j, "%02.2x", nif->addr[i]);
- n = readstr(offset, a, n, p);
- kfree(p);
- return n;
- case Ntypeqid:
- f = nif->f[NETID(c->qid.path)];
- return readnum(offset, a, n, f->type, NUMSIZE);
- case Nifstatqid:
+ case Ndataqid:
+ f = nif->f[NETID(c->qid.path)];
+ return qread(f->in, a, n);
+ case Nctlqid:
+ return readnum(offset, a, n, NETID(c->qid.path), NUMSIZE);
+ case Nstatqid:
+ p = kzmalloc(READSTR, 0);
+ if (p == NULL)
return 0;
+ j = 0;
+ j += snprintf(p + j, READSTR - j, "driver: %s\n",
+ nif->drv_name);
+ j += snprintf(p + j, READSTR - j, "in: %d\n", nif->inpackets);
+ j += snprintf(p + j, READSTR - j, "link: %d\n", nif->link);
+ j += snprintf(p + j, READSTR - j, "out: %d\n", nif->outpackets);
+ j += snprintf(p + j, READSTR - j, "crc errs: %d\n", nif->crcs);
+ j += snprintf(p + j, READSTR - j, "overflows: %d\n",
+ nif->overflows);
+ j += snprintf(p + j, READSTR - j, "soft overflows: %d\n",
+ nif->soverflows);
+ j += snprintf(p + j, READSTR - j, "framing errs: %d\n",
+ nif->frames);
+ j += snprintf(p + j, READSTR - j, "buffer errs: %d\n",
+ nif->buffs);
+ j += snprintf(p + j, READSTR - j, "output errs: %d\n",
+ nif->oerrs);
+ j += snprintf(p + j, READSTR - j, "prom: %d\n", nif->prom);
+ j += snprintf(p + j, READSTR - j, "mbps: %d\n", nif->mbps);
+ j += snprintf(p + j, READSTR - j, "addr: ");
+ for (i = 0; i < nif->alen; i++)
+ j += snprintf(p + j, READSTR - j, "%02.2x",
+ nif->addr[i]);
+ j += snprintf(p + j, READSTR - j, "\n");
+
+ j += snprintf(p + j, READSTR - j, "feat: ");
+ j = feature_appender(nif->feat, p, j);
+ j += snprintf(p + j, READSTR - j, "\n");
+
+ j += snprintf(p + j, READSTR - j, "hw_features: ");
+ j = feature_appender(nif->hw_features, p, j);
+ j += snprintf(p + j, READSTR - j, "\n");
+
+ n = readstr(offset, a, n, p);
+ kfree(p);
+ return n;
+ case Naddrqid:
+ p = kzmalloc(READSTR, 0);
+ if (p == NULL)
+ return 0;
+ j = 0;
+ for (i = 0; i < nif->alen; i++)
+ j += snprintf(p + j, READSTR - j, "%02.2x",
+ nif->addr[i]);
+ n = readstr(offset, a, n, p);
+ kfree(p);
+ return n;
+ case Ntypeqid:
+ f = nif->f[NETID(c->qid.path)];
+ return readnum(offset, a, n, f->type, NUMSIZE);
+ case Nifstatqid:
+ return 0;
}
error(EINVAL, ERROR_FIXME);
return -1; /* not reached */
@@ -413,10 +417,10 @@
f = nif->f[NETID(c->qid.path)];
if ((p = matchtoken(buf, "connect")) != 0) {
/* We'd like to not use the NIC until it has come up fully -
- * auto-negotiation is done and packets will get sent out. This is
- * about the best place to do it. */
+ * auto-negotiation is done and packets will get sent out. This
+ * is about the best place to do it. */
netif_wait_for_carrier(nif);
- type = strtol(p, 0, 0); /* allows any base, though usually hex */
+ type = strtol(p, 0, 0);
if (typeinuse(nif, type))
error(EBUSY, ERROR_FIXME);
f->type = type;
@@ -424,9 +428,11 @@
nif->all++;
} else if (matchtoken(buf, "promiscuous")) {
if (f->prom == 0) {
- /* Note that promisc has two meanings: put the NIC into promisc
- * mode, and record our outbound traffic. See etheroq(). */
- /* TODO: consider porting linux's interface for set_rx_mode. */
+ /* Note that promisc has two meanings: put the NIC into
+ * promisc mode, and record our outbound traffic. See
+ * etheroq(). */
+ /* TODO: consider porting linux's interface for
+ * set_rx_mode. */
if (nif->prom == 0 && nif->promiscuous != NULL)
nif->promiscuous(nif->arg, 1);
f->prom = 1;
@@ -435,7 +441,7 @@
} else if ((p = matchtoken(buf, "scanbs")) != 0) {
/* scan for base stations */
if (f->scan == 0) {
- type = strtol(p, 0, 0); /* allows any base, though usually hex */
+ type = strtol(p, 0, 0);
if (type < 5)
type = 5;
if (nif->scanbs != NULL)
@@ -566,12 +572,12 @@
spin_lock(&netlock);
if (*p->owner) {
- if (strncmp(o, p->owner, KNAMELEN) == 0) /* User */
+ if (strncmp(o, p->owner, KNAMELEN) == 0)
mode = p->mode;
- else if (strncmp(o, eve.name, KNAMELEN) == 0) /* Bootes is group */
+ else if (strncmp(o, eve.name, KNAMELEN) == 0)
mode = p->mode << 3;
else
- mode = p->mode << 6; /* Other */
+ mode = p->mode << 6;
rwx = omode_to_rwx(omode);
if ((rwx & mode) == rwx) {
@@ -620,7 +626,8 @@
f = kzmalloc(sizeof(struct netfile), 0);
if (f == 0)
exhausted("memory");
- /* since we lock before netifinit (if we ever call that...) */
+ /* since we lock before netifinit (if we ever call
+ * that...) */
qlock_init(&f->qlock);
f->in = qopen(nif->limit, Qmsg, 0, 0);
if (f->in == NULL) {
@@ -692,7 +699,7 @@
return 0;
}
-static int parseaddr(uint8_t * to, char *from, int alen)
+static int parseaddr(uint8_t *to, char *from, int alen)
{
char nip[4];
char *p;
@@ -717,8 +724,8 @@
/*
* keep track of multicast addresses
*/
-static char *netmulti(struct ether *nif, struct netfile *f, uint8_t * addr,
- int add)
+static char *netmulti(struct ether *nif, struct netfile *f, uint8_t *addr,
+ int add)
{
struct netaddr **l, *ap;
int i;
@@ -738,8 +745,8 @@
if (add) {
if (ap == 0) {
- /* TODO: AFAIK, this never gets freed. if we fix that, we can use a
- * kref too (instead of int ap->ref). */
+ /* TODO: AFAIK, this never gets freed. if we fix that,
+ * we can use a kref too (instead of int ap->ref). */
*l = ap = kzmalloc(sizeof(*ap), 0);
memmove(ap->addr, addr, nif->alen);
ap->next = 0;
@@ -808,7 +815,8 @@
sofar += snprintf(p + sofar, READSTR - sofar, "\n");
sofar += snprintf(p + sofar, READSTR - sofar,
- "rx length errors : %lu\n", stats->rx_length_errors);
+ "rx length errors : %lu\n",
+ stats->rx_length_errors);
sofar += snprintf(p + sofar, READSTR - sofar,
"rx over errors : %lu\n", stats->rx_over_errors);
sofar += snprintf(p + sofar, READSTR - sofar,
@@ -818,19 +826,24 @@
sofar += snprintf(p + sofar, READSTR - sofar,
"rx fifo errors : %lu\n", stats->rx_fifo_errors);
sofar += snprintf(p + sofar, READSTR - sofar,
- "rx missed errors : %lu\n", stats->rx_missed_errors);
+ "rx missed errors : %lu\n",
+ stats->rx_missed_errors);
sofar += snprintf(p + sofar, READSTR - sofar, "\n");
sofar += snprintf(p + sofar, READSTR - sofar,
- "tx aborted errors : %lu\n", stats->tx_aborted_errors);
+ "tx aborted errors : %lu\n",
+ stats->tx_aborted_errors);
sofar += snprintf(p + sofar, READSTR - sofar,
- "tx carrier errors : %lu\n", stats->tx_carrier_errors);
+ "tx carrier errors : %lu\n",
+ stats->tx_carrier_errors);
sofar += snprintf(p + sofar, READSTR - sofar,
"tx fifo errors : %lu\n", stats->tx_fifo_errors);
sofar += snprintf(p + sofar, READSTR - sofar,
- "tx heartbeat errors: %lu\n", stats->tx_heartbeat_errors);
+ "tx heartbeat errors: %lu\n",
+ stats->tx_heartbeat_errors);
sofar += snprintf(p + sofar, READSTR - sofar,
- "tx window errors : %lu\n", stats->tx_window_errors);
+ "tx window errors : %lu\n",
+ stats->tx_window_errors);
sofar += snprintf(p + sofar, READSTR - sofar, "\n");
sofar += snprintf(p + sofar, READSTR - sofar,
diff --git a/kern/src/net/netlog.c b/kern/src/net/netlog.c
index 3da4fab..cac8ff5 100644
--- a/kern/src/net/netlog.c
+++ b/kern/src/net/netlog.c
@@ -53,7 +53,7 @@
char *rptr;
int len;
- int logmask; /* mask of things to debug */
+ int logmask; /* mask of things to debug */
uint8_t iponly[IPaddrlen]; /* ip address to print debugging for */
int iponlyset;
@@ -92,8 +92,7 @@
CMonly,
};
-static
-struct cmdtab routecmd[] = {
+static struct cmdtab routecmd[] = {
{CMset, "set", 0},
{CMclear, "clear", 0},
{CMonly, "only", 0},
@@ -214,26 +213,26 @@
ct = lookupcmd(cb, routecmd, ARRAY_SIZE(routecmd));
switch (ct->index) {
- case CMset:
- set = 1;
- break;
+ case CMset:
+ set = 1;
+ break;
- case CMclear:
- set = 0;
- break;
+ case CMclear:
+ set = 0;
+ break;
- case CMonly:
- parseip(f->alog->iponly, cb->f[1]);
- if (ipcmp(f->alog->iponly, IPnoaddr) == 0)
- f->alog->iponlyset = 0;
- else
- f->alog->iponlyset = 1;
- kfree(cb);
- poperror();
- return;
+ case CMonly:
+ parseip(f->alog->iponly, cb->f[1]);
+ if (ipcmp(f->alog->iponly, IPnoaddr) == 0)
+ f->alog->iponlyset = 0;
+ else
+ f->alog->iponlyset = 1;
+ kfree(cb);
+ poperror();
+ return;
- default:
- cmderror(cb, "unknown ip control message");
+ default:
+ cmderror(cb, "unknown ip control message");
}
for (i = 1; i < cb->nf; i++) {
@@ -281,7 +280,8 @@
f->alog->len -= i;
f->alog->rptr += i;
if (f->alog->rptr >= f->alog->end)
- f->alog->rptr = f->alog->buf + (f->alog->rptr - f->alog->end);
+ f->alog->rptr = f->alog->buf + (f->alog->rptr -
+ f->alog->end);
}
t = f->alog->rptr + f->alog->len;
fp = buf;
diff --git a/kern/src/net/nullmedium.c b/kern/src/net/nullmedium.c
index fded7c4..a43adff 100644
--- a/kern/src/net/nullmedium.c
+++ b/kern/src/net/nullmedium.c
@@ -49,7 +49,7 @@
}
static void nullbwrite(struct Ipifc *unused_ipifc, struct block *b,
- int unused_int, uint8_t * unused_uint8_p_t)
+ int unused_int, uint8_t *unused_uint8_p_t)
{
error(EFAIL, "nullbwrite");
}
diff --git a/kern/src/net/pktmedium.c b/kern/src/net/pktmedium.c
index 815e418..3cd3945 100644
--- a/kern/src/net/pktmedium.c
+++ b/kern/src/net/pktmedium.c
@@ -41,7 +41,7 @@
static void pktbind(struct Ipifc *i, int unused_int, char **unused_char_pp_t);
static void pktunbind(struct Ipifc *i);
static void pktbwrite(struct Ipifc *i, struct block *, int unused_int,
- uint8_t * unused_uint8_p_t);
+ uint8_t *unused_uint8_p_t);
static void pktin(struct Fs *f, struct Ipifc *i, struct block *b);
struct medium pktmedium = {
diff --git a/kern/src/net/tcp.c b/kern/src/net/tcp.c
index f4970c5..7e32d6c 100644
--- a/kern/src/net/tcp.c
+++ b/kern/src/net/tcp.c
@@ -46,8 +46,8 @@
"Closing", "Last_ack", "Time_wait"
};
-static int tcp_irtt = DEF_RTT; /* Initial guess at round trip time */
-static uint16_t tcp_mss = DEF_MSS; /* Maximum segment size to be sent */
+static int tcp_irtt = DEF_RTT; /* Initial guess at round trip time */
+static uint16_t tcp_mss = DEF_MSS; /* Maximum segment size to be sent */
/* Must correspond to the enumeration in tcp.h */
static char *statnames[] = {
@@ -104,7 +104,7 @@
static void limborexmit(struct Proto *);
static void limbo(struct conv *, uint8_t *unused_uint8_p_t, uint8_t *, Tcp *,
- int);
+ int);
static void tcpsetstate(struct conv *s, uint8_t newstate)
{
@@ -127,19 +127,19 @@
/**
print( "%d/%d %s->%s CurrEstab=%d\n", s->lport, s->rport,
- tcpstates[oldstate], tcpstates[newstate], tpriv->tstats.tcpCurrEstab );
+ tcpstates[oldstate], tcpstates[newstate], tpriv->tstats.tcpCurrEstab );
**/
switch (newstate) {
- case Closed:
- qclose(s->rq);
- qclose(s->wq);
- qclose(s->eq);
- break;
+ case Closed:
+ qclose(s->rq);
+ qclose(s->wq);
+ qclose(s->eq);
+ break;
- case Close_wait: /* Remote closes */
- qhangup(s->rq, NULL);
- break;
+ case Close_wait: /* Remote closes */
+ qhangup(s->rq, NULL);
+ break;
}
tcb->state = newstate;
@@ -161,14 +161,14 @@
s = (Tcpctl *) (c->ptcl);
return snprintf(state, n,
- "%s qin %d qout %d srtt %d mdev %d cwin %u swin %u>>%d rwin %u>>%d timer.start %llu timer.count %llu rerecv %d katimer.start %d katimer.count %d\n",
- tcpstates[s->state],
- c->rq ? qlen(c->rq) : 0,
- c->wq ? qlen(c->wq) : 0,
- s->srtt, s->mdev,
- s->cwind, s->snd.wnd, s->rcv.scale, s->rcv.wnd,
- s->snd.scale, s->timer.start, s->timer.count, s->rerecv,
- s->katimer.start, s->katimer.count);
+ "%s qin %d qout %d srtt %d mdev %d cwin %u swin %u>>%d rwin %u>>%d timer.start %llu timer.count %llu rerecv %d katimer.start %d katimer.count %d\n",
+ tcpstates[s->state],
+ c->rq ? qlen(c->rq) : 0,
+ c->wq ? qlen(c->wq) : 0,
+ s->srtt, s->mdev,
+ s->cwind, s->snd.wnd, s->rcv.scale, s->rcv.wnd,
+ s->snd.scale, s->timer.start, s->timer.count, s->rerecv,
+ s->katimer.start, s->katimer.count);
}
static int tcpinuse(struct conv *c)
@@ -202,8 +202,9 @@
if (how == SHUT_RD)
return;
/* Sends a FIN. If we're in another state (like Listen), we'll run into
- * issues, since we'll never send the FIN. We'll be shutdown on our end,
- * but we'll never tell the distant end. Might just be an app issue. */
+ * issues, since we'll never send the FIN. We'll be shutdown on our
+ * end, but we'll never tell the distant end. Might just be an app
+ * issue. */
switch (tcb->state) {
case Established:
tcb->flgcnt++;
@@ -228,28 +229,28 @@
qflush(c->rq);
switch (tcb->state) {
- case Listen:
- /*
- * reset any incoming calls to this listener
- */
- Fsconnected(c, "Hangup");
+ case Listen:
+ /*
+ * reset any incoming calls to this listener
+ */
+ Fsconnected(c, "Hangup");
- localclose(c, NULL);
- break;
- case Closed:
- case Syn_sent:
- localclose(c, NULL);
- break;
- case Established:
- tcb->flgcnt++;
- tcpsetstate(c, Finwait1);
- tcpoutput(c);
- break;
- case Close_wait:
- tcb->flgcnt++;
- tcpsetstate(c, Last_ack);
- tcpoutput(c);
- break;
+ localclose(c, NULL);
+ break;
+ case Closed:
+ case Syn_sent:
+ localclose(c, NULL);
+ break;
+ case Established:
+ tcb->flgcnt++;
+ tcpsetstate(c, Finwait1);
+ tcpoutput(c);
+ break;
+ case Close_wait:
+ tcb->flgcnt++;
+ tcpsetstate(c, Last_ack);
+ tcpoutput(c);
+ break;
}
}
@@ -268,18 +269,18 @@
}
switch (tcb->state) {
- case Syn_sent:
- case Established:
- case Close_wait:
- /*
- * Push data
- */
- tcprcvwin(s);
- tcpoutput(s);
- break;
- default:
- localclose(s, "Hangup");
- break;
+ case Syn_sent:
+ case Established:
+ case Close_wait:
+ /*
+ * Push data
+ */
+ tcprcvwin(s);
+ tcpoutput(s);
+ break;
+ default:
+ localclose(s, "Hangup");
+ break;
}
qunlock(&s->qlock);
@@ -299,17 +300,18 @@
/* RFC 813: Avoid SWS. We'll always reduce the window (because the qio
* increased - that's legit), and we'll always advertise the window
- * increases (corresponding to qio drains) when those are greater than MSS.
- * But we don't advertise increases less than MSS.
+ * increases (corresponding to qio drains) when those are greater than
+ * MSS. But we don't advertise increases less than MSS.
*
* Note we don't shrink the window at all - that'll result in tcptrim()
* dropping packets that were sent before the sender gets our update. */
if ((w < tcb->rcv.wnd) || (w >= tcb->mss))
tcb->rcv.wnd = w;
/* We've delayed sending an update to rcv.wnd, and we might never get
- * another ACK to drive the TCP stack after the qio is drained. We could
- * replace this stuff with qio kicks or callbacks, but that might be
- * trickier with the MSS limitation. (and 'edge' isn't empty or not). */
+ * another ACK to drive the TCP stack after the qio is drained. We
+ * could replace this stuff with qio kicks or callbacks, but that might
+ * be trickier with the MSS limitation. (and 'edge' isn't empty or
+ * not). */
if (w < tcb->mss)
tcb->rcv.blocked = 1;
}
@@ -339,8 +341,9 @@
static void tcpcreate(struct conv *c)
{
- /* We don't use qio limits. Instead, TCP manages flow control on its own.
- * We only use qpassnolim(). Note for qio that 0 doesn't mean no limit. */
+ /* We don't use qio limits. Instead, TCP manages flow control on its
+ * own. We only use qpassnolim(). Note for qio that 0 doesn't mean no
+ * limit. */
c->rq = qopen(0, Qcoalesce, 0, 0);
c->wq = qopen(8 * QMAX, Qkick, tcpkick, c);
}
@@ -494,17 +497,19 @@
int mtu;
switch (version) {
- default:
- case V4:
- mtu = DEF_MSS;
- if (ifc != NULL)
- mtu = ifc->maxtu - ifc->m->hsize - (TCP4_PKT + TCP4_HDRSIZE);
- break;
- case V6:
- mtu = DEF_MSS6;
- if (ifc != NULL)
- mtu = ifc->maxtu - ifc->m->hsize - (TCP6_PKT + TCP6_HDRSIZE);
- break;
+ default:
+ case V4:
+ mtu = DEF_MSS;
+ if (ifc != NULL)
+ mtu = ifc->maxtu - ifc->m->hsize - (TCP4_PKT +
+ TCP4_HDRSIZE);
+ break;
+ case V6:
+ mtu = DEF_MSS6;
+ if (ifc != NULL)
+ mtu = ifc->maxtu - ifc->m->hsize - (TCP6_PKT +
+ TCP6_HDRSIZE);
+ break;
}
*scale = HaveWS | 7;
@@ -557,27 +562,27 @@
findlocalip(s->p->f, s->laddr, s->raddr);
switch (s->ipversion) {
- case V4:
- h4 = &tcb->protohdr.tcp4hdr;
- memset(h4, 0, sizeof(*h4));
- h4->proto = IP_TCPPROTO;
- hnputs(h4->tcpsport, s->lport);
- hnputs(h4->tcpdport, s->rport);
- v6tov4(h4->tcpsrc, s->laddr);
- v6tov4(h4->tcpdst, s->raddr);
- break;
- case V6:
- h6 = &tcb->protohdr.tcp6hdr;
- memset(h6, 0, sizeof(*h6));
- h6->proto = IP_TCPPROTO;
- hnputs(h6->tcpsport, s->lport);
- hnputs(h6->tcpdport, s->rport);
- ipmove(h6->tcpsrc, s->laddr);
- ipmove(h6->tcpdst, s->raddr);
- mss = DEF_MSS6;
- break;
- default:
- panic("inittcpctl: version %d", s->ipversion);
+ case V4:
+ h4 = &tcb->protohdr.tcp4hdr;
+ memset(h4, 0, sizeof(*h4));
+ h4->proto = IP_TCPPROTO;
+ hnputs(h4->tcpsport, s->lport);
+ hnputs(h4->tcpdport, s->rport);
+ v6tov4(h4->tcpsrc, s->laddr);
+ v6tov4(h4->tcpdst, s->raddr);
+ break;
+ case V6:
+ h6 = &tcb->protohdr.tcp6hdr;
+ memset(h6, 0, sizeof(*h6));
+ h6->proto = IP_TCPPROTO;
+ hnputs(h6->tcpsport, s->lport);
+ hnputs(h6->tcpdport, s->rport);
+ ipmove(h6->tcpsrc, s->laddr);
+ ipmove(h6->tcpdst, s->raddr);
+ mss = DEF_MSS6;
+ break;
+ default:
+ panic("inittcpctl: version %d", s->ipversion);
}
}
@@ -623,19 +628,19 @@
iphtadd(&tpriv->ht, s);
switch (mode) {
- case TCP_LISTEN:
- tpriv->stats[PassiveOpens]++;
- tcb->flags |= CLONE;
- tcpsetstate(s, Listen);
- break;
+ case TCP_LISTEN:
+ tpriv->stats[PassiveOpens]++;
+ tcb->flags |= CLONE;
+ tcpsetstate(s, Listen);
+ break;
- case TCP_CONNECT:
- tpriv->stats[ActiveOpens]++;
- tcb->flags |= ACTIVE;
- tcpsndsyn(s, tcb);
- tcpsetstate(s, Syn_sent);
- tcpoutput(s);
- break;
+ case TCP_CONNECT:
+ tpriv->stats[ActiveOpens]++;
+ tcb->flags |= ACTIVE;
+ tcpsndsyn(s, tcb);
+ tcpsetstate(s, Syn_sent);
+ tcpoutput(s);
+ break;
}
}
@@ -686,7 +691,8 @@
}
if (tcp_seg_has_ts(tcph)) {
hdrlen += TS_LENGTH;
- /* SYNs have other opts, don't do the PREPAD NOOP optimization. */
+ /* SYNs have other opts, don't do the PREPAD NOOP optimization.
+ */
if (!(tcph->flags & SYN))
hdrlen += TS_SEND_PREPAD;
}
@@ -730,7 +736,8 @@
/* Setting TSval, our time */
hnputl(opt, milliseconds());
opt += 4;
- /* Setting TSecr, the time we last saw from them, stored in ts_val */
+ /* Setting TSecr, the time we last saw from them, stored in
+ * ts_val */
hnputl(opt, tcph->ts_val);
opt += 4;
}
@@ -781,7 +788,8 @@
data = alloc_or_pad_block(data, hdrlen + TCP6_PKT);
if (data == NULL)
return NULL;
- /* relative to the block start (bp->rp). Note TCP structs include IP. */
+ /* relative to the block start (bp->rp). Note TCP structs include IP.
+ */
data->network_offset = 0;
data->transport_offset = offsetof(Tcp6hdr, tcpsport);
@@ -806,7 +814,8 @@
if (tcb != NULL && tcb->nochecksum) {
h->tcpcksum[0] = h->tcpcksum[1] = 0;
} else {
- csum = ptclcsum(data, TCP6_IPLEN, hdrlen + dlen + TCP6_PHDRSIZE);
+ csum = ptclcsum(data, TCP6_IPLEN, hdrlen + dlen +
+ TCP6_PHDRSIZE);
hnputs(h->tcpcksum, csum);
}
@@ -832,7 +841,7 @@
data = alloc_or_pad_block(data, hdrlen + TCP4_PKT);
if (data == NULL)
return NULL;
- /* relative to the block start (bp->rp). Note TCP structs include IP. */
+ /* relative to the block start (bp->rp). Note TCP structs include IP.*/
data->network_offset = 0;
data->transport_offset = offsetof(Tcp4hdr, tcpsport);
@@ -901,27 +910,27 @@
if (optlen < 2 || optlen > optsize)
break;
switch (*opt) {
- case MSSOPT:
- if (optlen == MSS_LENGTH)
- tcph->mss = nhgets(opt + 2);
- break;
- case WSOPT:
- if (optlen == WS_LENGTH && *(opt + 2) <= MAX_WS_VALUE)
- tcph->ws = HaveWS | *(opt + 2);
- break;
- case SACK_OK_OPT:
- if (optlen == SACK_OK_LENGTH)
- tcph->sack_ok = TRUE;
- break;
- case SACK_OPT:
- parse_inbound_sacks(tcph, opt, optlen);
- break;
- case TS_OPT:
- if (optlen == TS_LENGTH) {
- tcph->ts_val = nhgetl(opt + 2);
- tcph->ts_ecr = nhgetl(opt + 6);
- }
- break;
+ case MSSOPT:
+ if (optlen == MSS_LENGTH)
+ tcph->mss = nhgets(opt + 2);
+ break;
+ case WSOPT:
+ if (optlen == WS_LENGTH && *(opt + 2) <= MAX_WS_VALUE)
+ tcph->ws = HaveWS | *(opt + 2);
+ break;
+ case SACK_OK_OPT:
+ if (optlen == SACK_OK_LENGTH)
+ tcph->sack_ok = TRUE;
+ break;
+ case SACK_OPT:
+ parse_inbound_sacks(tcph, opt, optlen);
+ break;
+ case TS_OPT:
+ if (optlen == TS_LENGTH) {
+ tcph->ts_val = nhgetl(opt + 2);
+ tcph->ts_ecr = nhgetl(opt + 6);
+ }
+ break;
}
optsize -= optlen;
opt += optlen;
@@ -1045,28 +1054,28 @@
/* make pseudo header */
switch (version) {
- case V4:
- memset(&ph4, 0, sizeof(ph4));
- ph4.vihl = IP_VER4;
- v6tov4(ph4.tcpsrc, dest);
- v6tov4(ph4.tcpdst, source);
- ph4.proto = IP_TCPPROTO;
- hnputs(ph4.tcplen, TCP4_HDRSIZE);
- hnputs(ph4.tcpsport, seg->dest);
- hnputs(ph4.tcpdport, seg->source);
- break;
- case V6:
- memset(&ph6, 0, sizeof(ph6));
- ph6.vcf[0] = IP_VER6;
- ipmove(ph6.tcpsrc, dest);
- ipmove(ph6.tcpdst, source);
- ph6.proto = IP_TCPPROTO;
- hnputs(ph6.ploadlen, TCP6_HDRSIZE);
- hnputs(ph6.tcpsport, seg->dest);
- hnputs(ph6.tcpdport, seg->source);
- break;
- default:
- panic("sndrst: version %d", version);
+ case V4:
+ memset(&ph4, 0, sizeof(ph4));
+ ph4.vihl = IP_VER4;
+ v6tov4(ph4.tcpsrc, dest);
+ v6tov4(ph4.tcpdst, source);
+ ph4.proto = IP_TCPPROTO;
+ hnputs(ph4.tcplen, TCP4_HDRSIZE);
+ hnputs(ph4.tcpsport, seg->dest);
+ hnputs(ph4.tcpdport, seg->source);
+ break;
+ case V6:
+ memset(&ph6, 0, sizeof(ph6));
+ ph6.vcf[0] = IP_VER6;
+ ipmove(ph6.tcpsrc, dest);
+ ipmove(ph6.tcpdst, source);
+ ph6.proto = IP_TCPPROTO;
+ hnputs(ph6.ploadlen, TCP6_HDRSIZE);
+ hnputs(ph6.tcpsport, seg->dest);
+ hnputs(ph6.tcpdport, seg->source);
+ break;
+ default:
+ panic("sndrst: version %d", version);
}
tpriv->stats[OutRsts]++;
@@ -1095,20 +1104,20 @@
seg->nr_sacks = 0;
/* seg->ts_val is already set with their timestamp */
switch (version) {
- case V4:
- hbp = htontcp4(seg, NULL, &ph4, NULL);
- if (hbp == NULL)
- return;
- ipoput4(tcp->f, hbp, 0, MAXTTL, DFLTTOS, NULL);
- break;
- case V6:
- hbp = htontcp6(seg, NULL, &ph6, NULL);
- if (hbp == NULL)
- return;
- ipoput6(tcp->f, hbp, 0, MAXTTL, DFLTTOS, NULL);
- break;
- default:
- panic("sndrst2: version %d", version);
+ case V4:
+ hbp = htontcp4(seg, NULL, &ph4, NULL);
+ if (hbp == NULL)
+ return;
+ ipoput4(tcp->f, hbp, 0, MAXTTL, DFLTTOS, NULL);
+ break;
+ case V6:
+ hbp = htontcp6(seg, NULL, &ph6, NULL);
+ if (hbp == NULL)
+ return;
+ ipoput6(tcp->f, hbp, 0, MAXTTL, DFLTTOS, NULL);
+ break;
+ default:
+ panic("sndrst2: version %d", version);
}
}
@@ -1140,18 +1149,20 @@
seg.nr_sacks = 0;
seg.ts_val = tcb->ts_recent;
switch (s->ipversion) {
- case V4:
- tcb->protohdr.tcp4hdr.vihl = IP_VER4;
- hbp = htontcp4(&seg, NULL, &tcb->protohdr.tcp4hdr, tcb);
- ipoput4(s->p->f, hbp, 0, s->ttl, s->tos, s);
- break;
- case V6:
- tcb->protohdr.tcp6hdr.vcf[0] = IP_VER6;
- hbp = htontcp6(&seg, NULL, &tcb->protohdr.tcp6hdr, tcb);
- ipoput6(s->p->f, hbp, 0, s->ttl, s->tos, s);
- break;
- default:
- panic("tcphangup: version %d", s->ipversion);
+ case V4:
+ tcb->protohdr.tcp4hdr.vihl = IP_VER4;
+ hbp = htontcp4(&seg, NULL,
+ &tcb->protohdr.tcp4hdr, tcb);
+ ipoput4(s->p->f, hbp, 0, s->ttl, s->tos, s);
+ break;
+ case V6:
+ tcb->protohdr.tcp6hdr.vcf[0] = IP_VER6;
+ hbp = htontcp6(&seg, NULL,
+ &tcb->protohdr.tcp6hdr, tcb);
+ ipoput6(s->p->f, hbp, 0, s->ttl, s->tos, s);
+ break;
+ default:
+ panic("tcphangup: version %d", s->ipversion);
}
}
poperror();
@@ -1173,28 +1184,28 @@
/* make pseudo header */
switch (lp->version) {
- case V4:
- memset(&ph4, 0, sizeof(ph4));
- ph4.vihl = IP_VER4;
- v6tov4(ph4.tcpsrc, lp->laddr);
- v6tov4(ph4.tcpdst, lp->raddr);
- ph4.proto = IP_TCPPROTO;
- hnputs(ph4.tcplen, TCP4_HDRSIZE);
- hnputs(ph4.tcpsport, lp->lport);
- hnputs(ph4.tcpdport, lp->rport);
- break;
- case V6:
- memset(&ph6, 0, sizeof(ph6));
- ph6.vcf[0] = IP_VER6;
- ipmove(ph6.tcpsrc, lp->laddr);
- ipmove(ph6.tcpdst, lp->raddr);
- ph6.proto = IP_TCPPROTO;
- hnputs(ph6.ploadlen, TCP6_HDRSIZE);
- hnputs(ph6.tcpsport, lp->lport);
- hnputs(ph6.tcpdport, lp->rport);
- break;
- default:
- panic("sndrst: version %d", lp->version);
+ case V4:
+ memset(&ph4, 0, sizeof(ph4));
+ ph4.vihl = IP_VER4;
+ v6tov4(ph4.tcpsrc, lp->laddr);
+ v6tov4(ph4.tcpdst, lp->raddr);
+ ph4.proto = IP_TCPPROTO;
+ hnputs(ph4.tcplen, TCP4_HDRSIZE);
+ hnputs(ph4.tcpsport, lp->lport);
+ hnputs(ph4.tcpdport, lp->rport);
+ break;
+ case V6:
+ memset(&ph6, 0, sizeof(ph6));
+ ph6.vcf[0] = IP_VER6;
+ ipmove(ph6.tcpsrc, lp->laddr);
+ ipmove(ph6.tcpdst, lp->raddr);
+ ph6.proto = IP_TCPPROTO;
+ hnputs(ph6.ploadlen, TCP6_HDRSIZE);
+ hnputs(ph6.tcpsport, lp->lport);
+ hnputs(ph6.tcpdport, lp->rport);
+ break;
+ default:
+ panic("sndrst: version %d", lp->version);
}
lp->ifc = findipifc(tcp->f, lp->laddr, 0);
@@ -1221,20 +1232,20 @@
seg.sack_ok = FALSE;
switch (lp->version) {
- case V4:
- hbp = htontcp4(&seg, NULL, &ph4, NULL);
- if (hbp == NULL)
- return -1;
- ipoput4(tcp->f, hbp, 0, MAXTTL, DFLTTOS, NULL);
- break;
- case V6:
- hbp = htontcp6(&seg, NULL, &ph6, NULL);
- if (hbp == NULL)
- return -1;
- ipoput6(tcp->f, hbp, 0, MAXTTL, DFLTTOS, NULL);
- break;
- default:
- panic("sndsnack: version %d", lp->version);
+ case V4:
+ hbp = htontcp4(&seg, NULL, &ph4, NULL);
+ if (hbp == NULL)
+ return -1;
+ ipoput4(tcp->f, hbp, 0, MAXTTL, DFLTTOS, NULL);
+ break;
+ case V6:
+ hbp = htontcp6(&seg, NULL, &ph6, NULL);
+ if (hbp == NULL)
+ return -1;
+ ipoput6(tcp->f, hbp, 0, MAXTTL, DFLTTOS, NULL);
+ break;
+ default:
+ panic("sndsnack: version %d", lp->version);
}
lp->lastsend = NOW;
return 0;
@@ -1325,7 +1336,8 @@
for (l = &tpriv->lht[h]; *l != NULL && seen < tpriv->nlimbo;) {
lp = *l;
seen++;
- if (now - lp->lastsend < (lp->rexmits + 1) * SYNACK_RXTIMER)
+ if (now - lp->lastsend <
+ (lp->rexmits + 1) * SYNACK_RXTIMER)
continue;
/* time it out after 1 second */
@@ -1336,7 +1348,8 @@
continue;
}
- /* if we're being attacked, don't bother resending SYN ACK's */
+ /* if we're being attacked, don't bother resending SYN
+ * ACK's */
if (tpriv->nlimbo > 100)
continue;
@@ -1430,9 +1443,10 @@
h = hashipa(src, segp->source);
for (l = &tpriv->lht[h]; (lp = *l) != NULL; l = &lp->next) {
netlog(s->p->f, Logtcp,
- "tcpincoming s %I!%d/%I!%d d %I!%d/%I!%d v %d/%d\n", src,
- segp->source, lp->raddr, lp->rport, dst, segp->dest, lp->laddr,
- lp->lport, version, lp->version);
+ "tcpincoming s %I!%d/%I!%d d %I!%d/%I!%d v %d/%d\n",
+ src, segp->source, lp->raddr, lp->rport, dst,
+ segp->dest, lp->laddr, lp->lport, version,
+ lp->version);
if (lp->lport != segp->dest || lp->rport != segp->source
|| lp->version != version)
@@ -1444,8 +1458,9 @@
/* we're assuming no data with the initial SYN */
if (segp->seq != lp->irs + 1 || segp->ack != lp->iss + 1) {
- netlog(s->p->f, Logtcp, "tcpincoming s 0x%lx/0x%lx a 0x%lx 0x%lx\n",
- segp->seq, lp->irs + 1, segp->ack, lp->iss + 1);
+ netlog(s->p->f, Logtcp,
+ "tcpincoming s 0x%lx/0x%lx a 0x%lx 0x%lx\n",
+ segp->seq, lp->irs + 1, segp->ack, lp->iss + 1);
lp = NULL;
} else {
tpriv->nlimbo--;
@@ -1485,17 +1500,18 @@
tcb->flgcnt = 0;
tcb->flags |= SYNACK;
- /* our sending max segment size cannot be bigger than what he asked for */
+ /* our sending max segment size cannot be bigger than what he asked for
+ */
if (lp->mss != 0 && lp->mss < tcb->mss) {
tcb->mss = lp->mss;
tcb->typical_mss = tcb->mss;
}
adjust_typical_mss_for_opts(segp, tcb);
- /* Here's where we record the previously-decided header options. They were
- * actually decided on when we agreed to them in the SYNACK we sent. We
- * didn't create an actual TCB until now, so we can copy those decisions out
- * of the limbo tracker and into the TCB. */
+ /* Here's where we record the previously-decided header options. They
+ * were actually decided on when we agreed to them in the SYNACK we
+ * sent. We didn't create an actual TCB until now, so we can copy those
+ * decisions out of the limbo tracker and into the TCB. */
tcb->ifc = lp->ifc;
tcb->sack_ok = lp->sack_ok;
/* window scaling */
@@ -1513,26 +1529,26 @@
/* set up proto header */
switch (version) {
- case V4:
- h4 = &tcb->protohdr.tcp4hdr;
- memset(h4, 0, sizeof(*h4));
- h4->proto = IP_TCPPROTO;
- hnputs(h4->tcpsport, new->lport);
- hnputs(h4->tcpdport, new->rport);
- v6tov4(h4->tcpsrc, dst);
- v6tov4(h4->tcpdst, src);
- break;
- case V6:
- h6 = &tcb->protohdr.tcp6hdr;
- memset(h6, 0, sizeof(*h6));
- h6->proto = IP_TCPPROTO;
- hnputs(h6->tcpsport, new->lport);
- hnputs(h6->tcpdport, new->rport);
- ipmove(h6->tcpsrc, dst);
- ipmove(h6->tcpdst, src);
- break;
- default:
- panic("tcpincoming: version %d", new->ipversion);
+ case V4:
+ h4 = &tcb->protohdr.tcp4hdr;
+ memset(h4, 0, sizeof(*h4));
+ h4->proto = IP_TCPPROTO;
+ hnputs(h4->tcpsport, new->lport);
+ hnputs(h4->tcpdport, new->rport);
+ v6tov4(h4->tcpsrc, dst);
+ v6tov4(h4->tcpdst, src);
+ break;
+ case V6:
+ h6 = &tcb->protohdr.tcp6hdr;
+ memset(h6, 0, sizeof(*h6));
+ h6->proto = IP_TCPPROTO;
+ hnputs(h6->tcpsport, new->lport);
+ hnputs(h6->tcpdport, new->rport);
+ ipmove(h6->tcpsrc, dst);
+ ipmove(h6->tcpdst, src);
+ break;
+ default:
+ panic("tcpincoming: version %d", new->ipversion);
}
tcpsetstate(new, Established);
@@ -1572,18 +1588,19 @@
Tcpctl *tcb = (Tcpctl *) s->ptcl;
size_t ideal_limit = tcb->cwind * 2;
- /* This is called for every ACK, and it's not entirely free to update the
- * limit (locks, CVs, taps). Updating in chunks of mss seems reasonable.
- * During SS, we'll update this on most ACKs (given each ACK increased the
- * cwind by > MSS).
+ /* This is called for every ACK, and it's not entirely free to update
+ * the limit (locks, CVs, taps). Updating in chunks of mss seems
+ * reasonable. During SS, we'll update this on most ACKs (given each
+ * ACK increased the cwind by > MSS).
*
- * We also don't want a lot of tiny blocks from the user, but the way qio
- * works, you can put in as much as you want (Maxatomic) and then get
- * flow-controlled. */
+ * We also don't want a lot of tiny blocks from the user, but the way
+ * qio works, you can put in as much as you want (Maxatomic) and then
+ * get flow-controlled. */
if (qgetlimit(s->wq) + tcb->typical_mss < ideal_limit)
qsetlimit(s->wq, ideal_limit);
- /* TODO: we could shrink the qio limit too, if we had a better idea what the
- * actual threshold was. We want the limit to be the 'stable' cwnd * 2. */
+ /* TODO: we could shrink the qio limit too, if we had a better idea what
+ * the actual threshold was. We want the limit to be the 'stable' cwnd
+ * times 2. */
}
/* Attempts to merge later sacks into sack 'into' (index in the array) */
@@ -1604,8 +1621,8 @@
if (shift) {
memmove(tcb->snd.sacks + into + 1,
tcb->snd.sacks + into + 1 + shift,
- sizeof(struct sack_block) * (tcb->snd.nr_sacks - into - 1
- - shift));
+ sizeof(struct sack_block) * (tcb->snd.nr_sacks - into -
+ 1 - shift));
tcb->snd.nr_sacks -= shift;
}
}
@@ -1649,17 +1666,18 @@
for (int i = 0; i < tcb->snd.nr_sacks; i++) {
tcb_sack = &tcb->snd.sacks[i];
- /* Checking invariants: snd.rtx is never inside a sack, sacks are always
- * mutually exclusive. */
+ /* Checking invariants: snd.rtx is never inside a sack, sacks
+ * are always mutually exclusive. */
if (sack_contains(tcb_sack, tcb->snd.rtx) ||
- ((i + 1 < tcb->snd.nr_sacks) && seq_ge(tcb_sack->right,
- (tcb_sack + 1)->left))) {
+ ((i + 1 < tcb->snd.nr_sacks) &&
+ seq_ge(tcb_sack->right, (tcb_sack + 1)->left))) {
printk("SACK ASSERT ERROR at %s\n", str);
printk("rtx %u una %u nxt %u, sack [%u, %u)\n",
- tcb->snd.rtx, tcb->snd.una, tcb->snd.nxt, tcb_sack->left,
- tcb_sack->right);
+ tcb->snd.rtx, tcb->snd.una, tcb->snd.nxt,
+ tcb_sack->left, tcb_sack->right);
for (int i = 0; i < tcb->snd.nr_sacks; i++)
- printk("\t %d: [%u, %u)\n", i, tcb->snd.sacks[i].left,
+ printk("\t %d: [%u, %u)\n", i,
+ tcb->snd.sacks[i].left,
tcb->snd.sacks[i].right);
backtrace();
panic("");
@@ -1671,31 +1689,34 @@
static void sack_has_changed(struct conv *s, Tcpctl *tcb,
struct sack_block *tcb_sack)
{
- /* Due to the change, snd.rtx might be in the middle of this sack. Advance
- * it to the right edge. */
+ /* Due to the change, snd.rtx might be in the middle of this sack.
+ * Advance it to the right edge. */
if (sack_contains(tcb_sack, tcb->snd.rtx))
tcb->snd.rtx = tcb_sack->right;
- /* This is a sack for something we retransed and we think it means there was
- * another loss. Instead of waiting for the RTO, we can take action. */
+ /* This is a sack for something we retransed and we think it means there
+ * was another loss. Instead of waiting for the RTO, we can take
+ * action. */
if (sack_hints_at_loss(tcb, tcb_sack)) {
if (++tcb->snd.sack_loss_hint == TCPREXMTTHRESH) {
netlog(s->p->f, Logtcprxmt,
"%I.%d -> %I.%d: sack rxmit loss: snd.rtx %u, sack [%u,%u), una %u, recovery_pt %u\n",
s->laddr, s->lport, s->raddr, s->rport,
- tcb->snd.rtx, tcb_sack->left, tcb_sack->right, tcb->snd.una,
- tcb->snd.recovery_pt);
- /* Redo retrans, but keep the sacks and recovery point */
+ tcb->snd.rtx, tcb_sack->left, tcb_sack->right,
+ tcb->snd.una, tcb->snd.recovery_pt);
+ /* Redo retrans, but keep the sacks and recovery point*/
tcp_loss_event(s, tcb);
tcb->snd.rtx = tcb->snd.una;
tcb->snd.sack_loss_hint = 0;
- /* Act like an RTO. We just detected it earlier. This prevents us
- * from getting another sack hint loss this recovery period and from
- * advancing the opportunistic right edge. */
+ /* Act like an RTO. We just detected it earlier. This
+ * prevents us from getting another sack hint loss this
+ * recovery period and from advancing the opportunistic
+ * right edge. */
tcb->snd.recovery = RTO_RETRANS_RECOVERY;
- /* We didn't actually time out yet and we expect to keep getting
- * sacks, so we don't want to flush or worry about in_flight. If we
- * messed something up, the RTO will still fire. */
+ /* We didn't actually time out yet and we expect to keep
+ * getting sacks, so we don't want to flush or worry
+ * about in_flight. If we messed something up, the RTO
+ * will still fire. */
set_in_flight(tcb);
}
}
@@ -1721,9 +1742,11 @@
for (int i = 0; i < tcb->snd.nr_sacks; i++) {
tcb_sack = &tcb->snd.sacks[i];
if (seq_lt(tcb_sack->left, seg_sack->left)) {
- /* This includes adjacent (which I've seen!) and overlap. */
+ /* This includes adjacent (which I've seen!) and
+ * overlap. */
if (seq_le(seg_sack->left, tcb_sack->right)) {
- update_right_edge(s, tcb, tcb_sack, seg_sack->right);
+ update_right_edge(s, tcb, tcb_sack,
+ seg_sack->right);
return;
}
continue;
@@ -1736,18 +1759,22 @@
/* Found our slot */
if (seq_gt(tcb_sack->left, seg_sack->left)) {
if (tcb->snd.nr_sacks == MAX_NR_SND_SACKS) {
- /* Out of room, but it is possible this sack overlaps later
- * sacks, including the max sack's right edge. */
+ /* Out of room, but it is possible this sack
+ * overlaps later sacks, including the max
+ * sack's right edge. */
if (seq_ge(seg_sack->right, tcb_sack->left)) {
/* Take over the sack */
tcb_sack->left = seg_sack->left;
- update_right_edge(s, tcb, tcb_sack, seg_sack->right);
+ update_right_edge(s, tcb, tcb_sack,
+ seg_sack->right);
}
return;
}
- /* O/W, it's our slot and we have room (at least one spot). */
+ /* O/W, it's our slot and we have room (at least one
+ * spot). */
memmove(&tcb->snd.sacks[i + 1], &tcb->snd.sacks[i],
- sizeof(struct sack_block) * (tcb->snd.nr_sacks - i));
+ sizeof(struct sack_block) * (tcb->snd.nr_sacks -
+ i));
tcb_sack->left = seg_sack->left;
tcb_sack->right = seg_sack->right;
tcb->snd.nr_sacks++;
@@ -1759,7 +1786,8 @@
if (tcb->snd.nr_sacks == MAX_NR_SND_SACKS) {
/* We didn't find space in the sack array. */
tcb_sack = &tcb->snd.sacks[MAX_NR_SND_SACKS - 1];
- /* Need to always maintain the rightmost sack, discarding the prev */
+ /* Need to always maintain the rightmost sack, discarding the
+ * prev */
if (seq_gt(seg_sack->right, tcb_sack->right)) {
tcb_sack->left = seg_sack->left;
tcb_sack->right = seg_sack->right;
@@ -1798,16 +1826,17 @@
for (int i = 0; i < tcb->snd.nr_sacks; i++) {
tcb_sack = &tcb->snd.sacks[i];
- /* For the equality case, if they acked up to, but not including an old
- * sack, they must have reneged it. Otherwise they would have acked
- * beyond the sack. */
+ /* For the equality case, if they acked up to, but not including
+ * an old sack, they must have reneged it. Otherwise they would
+ * have acked beyond the sack. */
if (seq_lt(seg->ack, tcb_sack->left))
break;
prune++;
}
if (prune) {
memmove(tcb->snd.sacks, tcb->snd.sacks + prune,
- sizeof(struct sack_block) * (tcb->snd.nr_sacks - prune));
+ sizeof(struct sack_block) * (tcb->snd.nr_sacks -
+ prune));
tcb->snd.nr_sacks -= prune;
}
for (int i = 0; i < seg->nr_sacks; i++) {
@@ -1845,9 +1874,10 @@
tcb_sack = &tcb->snd.sacks[tcb->snd.nr_sacks - 1];
in_flight += tcb->snd.nxt - tcb_sack->right;
- /* Everything retransed (from una to snd.rtx, minus sacked regions. Note
- * we only retrans at most the last sack's left edge. snd.rtx will be
- * advanced to the right edge of some sack (possibly the last one). */
+ /* Everything retransed (from una to snd.rtx, minus sacked regions.
+ * Note we only retrans at most the last sack's left edge. snd.rtx will
+ * be advanced to the right edge of some sack (possibly the last one).
+ * */
from = tcb->snd.una;
for (int i = 0; i < tcb->snd.nr_sacks; i++) {
tcb_sack = &tcb->snd.sacks[i];
@@ -1962,16 +1992,18 @@
update_sacks(s, tcb, seg);
set_in_flight(tcb);
- /* We treat either a dupack or forward SACKs as a hint that there is a loss.
- * The RFCs suggest three dupacks before treating it as a loss (alternative
- * is reordered packets). We'll treat three SACKs the same way. */
+ /* We treat either a dupack or forward SACKs as a hint that there is a
+ * loss. The RFCs suggest three dupacks before treating it as a loss
+ * (alternative is reordered packets). We'll treat three SACKs the same
+ * way. */
if (is_potential_loss(tcb, seg) && !tcb->snd.recovery) {
tcb->snd.loss_hint++;
if (tcb->snd.loss_hint == TCPREXMTTHRESH) {
netlog(s->p->f, Logtcprxmt,
"%I.%d -> %I.%d: loss hint thresh, nr sacks %u, nxt %u, una %u, cwnd %u\n",
s->laddr, s->lport, s->raddr, s->rport,
- tcb->snd.nr_sacks, tcb->snd.nxt, tcb->snd.una, tcb->cwind);
+ tcb->snd.nr_sacks, tcb->snd.nxt, tcb->snd.una,
+ tcb->cwind);
tcp_loss_event(s, tcb);
tcb->snd.recovery_pt = tcb->snd.nxt;
if (tcb->snd.nr_sacks) {
@@ -2003,7 +2035,8 @@
tcb->backedoff = MAXBACKMS / 4;
return;
}
- /* At this point, they have acked something new. (positive ack, ack > una).
+ /* At this point, they have acked something new. (positive ack, ack >
+ * una).
*
* If we hadn't reached the threshold for recovery yet, the positive ACK
* will reset our loss_hint count. */
@@ -2023,19 +2056,21 @@
/* slow start as long as we're not recovering from lost packets */
if (tcb->cwind < tcb->snd.wnd && !tcb->snd.recovery) {
if (tcb->cwind < tcb->ssthresh) {
- /* We increase the cwind by every byte we receive. We want to
- * increase the cwind by one MSS for every MSS that gets ACKed.
- * Note that multiple MSSs can be ACKed in a single ACK. If we had
- * a remainder of acked / MSS, we'd add just that remainder - not 0
- * or 1 MSS. */
+ /* We increase the cwind by every byte we receive. We
+ * want to increase the cwind by one MSS for every MSS
+ * that gets ACKed. Note that multiple MSSs can be
+ * ACKed in a single ACK. If we had a remainder of
+ * acked / MSS, we'd add just that remainder - not 0 or
+ * 1 MSS. */
expand = acked;
} else {
- /* Every RTT, which consists of CWND bytes, we're supposed to expand
- * by MSS bytes. The classic algorithm was
- * expand = (tcb->mss * tcb->mss) / tcb->cwind;
- * which assumes the ACK was for MSS bytes. Instead, for every
- * 'acked' bytes, we increase the window by acked / CWND (in units
- * of MSS). */
+ /* Every RTT, which consists of CWND bytes, we're
+ * supposed to expand by MSS bytes. The classic
+ * algorithm was
+ * expand = (tcb->mss * tcb->mss) / tcb->cwind;
+ * which assumes the ACK was for MSS bytes. Instead,
+ * for every 'acked' bytes, we increase the window by
+ * acked / CWND (in units of MSS). */
expand = MAX(acked, tcb->typical_mss) * tcb->typical_mss
/ tcb->cwind;
}
@@ -2057,8 +2092,10 @@
tcphalt(tpriv, &tcb->rtt_timer);
if (!tcb->snd.recovery) {
rtt = tcb->rtt_timer.start - tcb->rtt_timer.count;
- if (rtt == 0)
- rtt = 1; /* o/w all close systems will rexmit in 0 time */
+ if (rtt == 0) {
+ /* o/w all close systems will rxmit in 0 time */
+ rtt = 1;
+ }
rtt *= MSPTICK;
update_rtt(tcb, rtt, 1);
}
@@ -2068,9 +2105,10 @@
if (qdiscard(s->wq, acked) < acked) {
tcb->flgcnt--;
/* This happened due to another bug where acked was very large
- * (negative), which was interpreted as "hey, one less flag, since they
- * acked one of our flags (like a SYN). If flgcnt goes negative,
- * get_xmit_segment() will attempt to send out large packets. */
+ * (negative), which was interpreted as "hey, one less flag,
+ * since they acked one of our flags (like a SYN). If flgcnt
+ * goes negative, get_xmit_segment() will attempt to send out
+ * large packets. */
assert(tcb->flgcnt >= 0);
}
@@ -2089,9 +2127,9 @@
static void update_tcb_ts(Tcpctl *tcb, Tcp *seg)
{
/* Get timestamp info from the tcp header. Even though the timestamps
- * aren't sequence numbers, we still need to protect for wraparound. Though
- * if the values were 0, assume that means we need an update. We could have
- * an initial ts_val that appears negative (signed). */
+ * aren't sequence numbers, we still need to protect for wraparound.
+ * Though if the values were 0, assume that means we need an update. We
+ * could have an initial ts_val that appears negative (signed). */
if (!tcb->ts_recent || !tcb->last_ack_sent ||
(seq_ge(seg->ts_val, tcb->ts_recent) &&
seq_le(seg->seq, tcb->last_ack_sent)))
@@ -2142,8 +2180,8 @@
return;
}
}
- /* We can discard the last sack (right shift) - we should have sent it at
- * least once by now. If not, oh well. */
+ /* We can discard the last sack (right shift) - we should have sent it
+ * at least once by now. If not, oh well. */
memmove(tcb->rcv.sacks + 1, tcb->rcv.sacks, sizeof(struct sack_block) *
MIN(MAX_NR_RCV_SACKS - 1, tcb->rcv.nr_sacks));
tcb->rcv.sacks[0] = *sack;
@@ -2163,7 +2201,8 @@
/* Moving up to or past the left is enough to drop it. */
if (seq_ge(tcb->rcv.nxt, tcb_sack->left)) {
memmove(tcb->rcv.sacks + i, tcb->rcv.sacks + i + 1,
- sizeof(struct sack_block) * (tcb->rcv.nr_sacks - i - 1));
+ sizeof(struct sack_block) * (tcb->rcv.nr_sacks -
+ i - 1));
tcb->rcv.nr_sacks--;
i--;
}
@@ -2201,12 +2240,13 @@
v4tov6(dest, h4->tcpdst);
v4tov6(source, h4->tcpsrc);
- /* ttl isn't part of the xsum pseudo header, but bypass needs it. */
+ /* ttl isn't part of the xsum pseudo header, but bypass needs
+ * it. */
ttl = h4->Unused;
h4->Unused = 0;
hnputs(h4->tcplen, length - TCP4_PKT);
- if (!(bp->flag & Btcpck) && (h4->tcpcksum[0] || h4->tcpcksum[1]) &&
- ptclcsum(bp, TCP4_IPLEN, length - TCP4_IPLEN)) {
+ if (!(bp->flag & Btcpck) && (h4->tcpcksum[0] || h4->tcpcksum[1])
+ && ptclcsum(bp, TCP4_IPLEN, length - TCP4_IPLEN)) {
tpriv->stats[CsumErrs]++;
tpriv->stats[InErrs]++;
netlog(f, Logtcp, "bad tcp proto cksum\n");
@@ -2289,10 +2329,12 @@
/* s, the conv matching the n-tuple, was set above */
if (s == NULL) {
- netlog(f, Logtcpreset, "iphtlook failed: src %I:%u, dst %I:%u\n",
+ netlog(f, Logtcpreset,
+ "iphtlook failed: src %I:%u, dst %I:%u\n",
source, seg.source, dest, seg.dest);
reset:
- sndrst(tcp, source, dest, length, &seg, version, "no conversation");
+ sndrst(tcp, source, dest, length, &seg, version,
+ "no conversation");
freeblist(bp);
return;
}
@@ -2319,7 +2361,8 @@
return;
}
- /* if there's a matching call in limbo, tcpincoming will return it */
+ /* if there's a matching call in limbo, tcpincoming will return
+ * it */
s = tcpincoming(s, &seg, source, dest, version);
if (s == NULL) {
qunlock(&tcp->qlock);
@@ -2347,57 +2390,59 @@
tcpsetkacounter(tcb);
switch (tcb->state) {
- case Closed:
- sndrst(tcp, source, dest, length, &seg, version,
- "sending to Closed");
- goto raise;
- case Syn_sent:
- if (seg.flags & ACK) {
- if (!seq_within(seg.ack, tcb->iss + 1, tcb->snd.nxt)) {
- sndrst(tcp, source, dest, length, &seg, version,
- "bad seq in Syn_sent");
- goto raise;
- }
+ case Closed:
+ sndrst(tcp, source, dest, length, &seg, version,
+ "sending to Closed");
+ goto raise;
+ case Syn_sent:
+ if (seg.flags & ACK) {
+ if (!seq_within(seg.ack, tcb->iss + 1,
+ tcb->snd.nxt)) {
+ sndrst(tcp, source, dest, length, &seg,
+ version, "bad seq in Syn_sent");
+ goto raise;
}
- if (seg.flags & RST) {
- if (seg.flags & ACK)
- localclose(s, "connection refused");
+ }
+ if (seg.flags & RST) {
+ if (seg.flags & ACK)
+ localclose(s, "connection refused");
+ goto raise;
+ }
+
+ if (seg.flags & SYN) {
+ procsyn(s, &seg);
+ if (seg.flags & ACK) {
+ update(s, &seg);
+ tcpsynackrtt(s);
+ tcpsetstate(s, Established);
+ /* Here's where we get the results of
+ * header option negotiations for
+ * connections we started. (SYNACK has
+ * the response) */
+ tcpsetscale(s, tcb, seg.ws, tcb->scale);
+ tcb->sack_ok = seg.sack_ok;
+ } else {
+ sndrst(tcp, source, dest, length, &seg,
+ version, "Got SYN with no ACK");
goto raise;
}
- if (seg.flags & SYN) {
- procsyn(s, &seg);
- if (seg.flags & ACK) {
- update(s, &seg);
- tcpsynackrtt(s);
- tcpsetstate(s, Established);
- /* Here's where we get the results of header option
- * negotiations for connections we started. (SYNACK has the
- * response) */
- tcpsetscale(s, tcb, seg.ws, tcb->scale);
- tcb->sack_ok = seg.sack_ok;
- } else {
- sndrst(tcp, source, dest, length, &seg, version,
- "Got SYN with no ACK");
- goto raise;
- }
+ if (length != 0 || (seg.flags & FIN))
+ break;
- if (length != 0 || (seg.flags & FIN))
- break;
+ freeblist(bp);
+ goto output;
+ } else
+ freeblist(bp);
- freeblist(bp);
- goto output;
- } else
- freeblist(bp);
-
- qunlock(&s->qlock);
- poperror();
- return;
+ qunlock(&s->qlock);
+ poperror();
+ return;
}
/*
- * One DOS attack is to open connections to us and then forget about them,
- * thereby tying up a conv at no long term cost to the attacker.
+ * One DOS attack is to open connections to us and then forget about
+ * them, thereby tying up a conv at no long term cost to the attacker.
* This is an attempt to defeat these stateless DOS attacks. See
* corresponding code in tcpsendka().
*/
@@ -2406,8 +2451,9 @@
&& seq_within(seg.ack, tcb->snd.una - (1 << 31),
tcb->snd.una - (1 << 29))) {
printd("stateless hog %I.%d->%I.%d f 0x%x 0x%lx - 0x%lx - 0x%lx\n",
- source, seg.source, dest, seg.dest, seg.flags,
- tcb->snd.una - (1 << 31), seg.ack, tcb->snd.una - (1 << 29));
+ source, seg.source, dest, seg.dest, seg.flags,
+ tcb->snd.una - (1 << 31), seg.ack,
+ tcb->snd.una - (1 << 29));
localclose(s, "stateless hog");
}
}
@@ -2436,7 +2482,8 @@
/* Cannot accept so answer with a rst */
if (length && tcb->state == Closed) {
- sndrst(tcp, source, dest, length, &seg, version, "sending to Closed");
+ sndrst(tcp, source, dest, length, &seg, version,
+ "sending to Closed");
goto raise;
}
@@ -2447,8 +2494,8 @@
if (length != 0 || (seg.flags & (SYN | FIN))) {
update(s, &seg);
if (addreseq(tcb, tpriv, &seg, bp, length) < 0)
- printd("reseq %I.%d -> %I.%d\n", s->raddr, s->rport, s->laddr,
- s->lport);
+ printd("reseq %I.%d -> %I.%d\n", s->raddr,
+ s->rport, s->laddr, s->lport);
tcb->flags |= FORCE;
goto output;
}
@@ -2462,10 +2509,9 @@
if (tcb->state == Established) {
tpriv->stats[EstabResets]++;
if (tcb->rcv.nxt != seg.seq)
- printd
- ("out of order RST rcvd: %I.%d -> %I.%d, rcv.nxt 0x%lx seq 0x%lx\n",
- s->raddr, s->rport, s->laddr, s->lport, tcb->rcv.nxt,
- seg.seq);
+ printd("out of order RST rcvd: %I.%d -> %I.%d, rcv.nxt 0x%lx seq 0x%lx\n",
+ s->raddr, s->rport, s->laddr,
+ s->lport, tcb->rcv.nxt, seg.seq);
}
localclose(s, "connection refused");
goto raise;
@@ -2475,47 +2521,47 @@
goto raise;
switch (tcb->state) {
- case Established:
- case Close_wait:
- update(s, &seg);
- break;
- case Finwait1:
- update(s, &seg);
- if (qlen(s->wq) + tcb->flgcnt == 0) {
- tcphalt(tpriv, &tcb->rtt_timer);
- tcphalt(tpriv, &tcb->acktimer);
- tcpsetkacounter(tcb);
- tcb->time = NOW;
- tcpsetstate(s, Finwait2);
- tcb->katimer.start = MSL2 * (1000 / MSPTICK);
- tcpgo(tpriv, &tcb->katimer);
- }
- break;
- case Finwait2:
- update(s, &seg);
- break;
- case Closing:
- update(s, &seg);
- if (qlen(s->wq) + tcb->flgcnt == 0) {
- tcphalt(tpriv, &tcb->rtt_timer);
- tcphalt(tpriv, &tcb->acktimer);
- tcphalt(tpriv, &tcb->katimer);
- tcpsetstate(s, Time_wait);
- tcb->timer.start = MSL2 * (1000 / MSPTICK);
- tcpgo(tpriv, &tcb->timer);
- }
- break;
- case Last_ack:
- update(s, &seg);
- if (qlen(s->wq) + tcb->flgcnt == 0) {
- localclose(s, NULL);
- goto raise;
- }
- case Time_wait:
- if (seg.flags & FIN)
- tcb->flags |= FORCE;
- if (tcb->timer.state != TcptimerON)
- tcpgo(tpriv, &tcb->timer);
+ case Established:
+ case Close_wait:
+ update(s, &seg);
+ break;
+ case Finwait1:
+ update(s, &seg);
+ if (qlen(s->wq) + tcb->flgcnt == 0) {
+ tcphalt(tpriv, &tcb->rtt_timer);
+ tcphalt(tpriv, &tcb->acktimer);
+ tcpsetkacounter(tcb);
+ tcb->time = NOW;
+ tcpsetstate(s, Finwait2);
+ tcb->katimer.start = MSL2 * (1000 / MSPTICK);
+ tcpgo(tpriv, &tcb->katimer);
+ }
+ break;
+ case Finwait2:
+ update(s, &seg);
+ break;
+ case Closing:
+ update(s, &seg);
+ if (qlen(s->wq) + tcb->flgcnt == 0) {
+ tcphalt(tpriv, &tcb->rtt_timer);
+ tcphalt(tpriv, &tcb->acktimer);
+ tcphalt(tpriv, &tcb->katimer);
+ tcpsetstate(s, Time_wait);
+ tcb->timer.start = MSL2 * (1000 / MSPTICK);
+ tcpgo(tpriv, &tcb->timer);
+ }
+ break;
+ case Last_ack:
+ update(s, &seg);
+ if (qlen(s->wq) + tcb->flgcnt == 0) {
+ localclose(s, NULL);
+ goto raise;
+ }
+ case Time_wait:
+ if (seg.flags & FIN)
+ tcb->flags |= FORCE;
+ if (tcb->timer.state != TcptimerON)
+ tcpgo(tpriv, &tcb->timer);
}
if ((seg.flags & URG) && seg.urg) {
@@ -2531,63 +2577,64 @@
freeblist(bp);
} else {
switch (tcb->state) {
- default:
- /* Ignore segment text */
- if (bp != NULL)
- freeblist(bp);
- break;
+ default:
+ /* Ignore segment text */
+ if (bp != NULL)
+ freeblist(bp);
+ break;
- case Established:
- case Finwait1:
- /* If we still have some data place on
- * receive queue
- */
- if (bp) {
- bp = packblock(bp);
- if (bp == NULL)
- panic("tcp packblock");
- qpassnolim(s->rq, bp);
- bp = NULL;
-
- /*
- * Force an ack every 2 data messages. This is
- * a hack for rob to make his home system run
- * faster.
- *
- * this also keeps the standard TCP congestion
- * control working since it needs an ack every
- * 2 max segs worth. This is not quite that,
- * but under a real stream is equivalent since
- * every packet has a max seg in it.
- */
- if (++(tcb->rcv.una) >= 2)
- tcb->flags |= FORCE;
- }
- tcb->rcv.nxt += length;
- drop_old_rcv_sacks(tcb);
+ case Established:
+ case Finwait1:
+ /* If we still have some data place on
+ * receive queue
+ */
+ if (bp) {
+ bp = packblock(bp);
+ if (bp == NULL)
+ panic("tcp packblock");
+ qpassnolim(s->rq, bp);
+ bp = NULL;
/*
- * update our rcv window
+ * Force an ack every 2 data messages.
+ * This is a hack for rob to make his
+ * home system run faster.
+ *
+ * this also keeps the standard TCP
+ * congestion control working since it
+ * needs an ack every 2 max segs worth.
+ * This is not quite that, but under a
+ * real stream is equivalent since every
+ * packet has a max seg in it.
*/
- tcprcvwin(s);
+ if (++(tcb->rcv.una) >= 2)
+ tcb->flags |= FORCE;
+ }
+ tcb->rcv.nxt += length;
+ drop_old_rcv_sacks(tcb);
- /*
- * turn on the acktimer if there's something
- * to ack
- */
- if (tcb->acktimer.state != TcptimerON)
- tcpgo(tpriv, &tcb->acktimer);
+ /*
+ * update our rcv window
+ */
+ tcprcvwin(s);
- break;
- case Finwait2:
- /* no process to read the data, send a reset */
- if (bp != NULL)
- freeblist(bp);
- sndrst(tcp, source, dest, length, &seg, version,
- "send to Finwait2");
- qunlock(&s->qlock);
- poperror();
- return;
+ /*
+ * turn on the acktimer if there's something
+ * to ack
+ */
+ if (tcb->acktimer.state != TcptimerON)
+ tcpgo(tpriv, &tcb->acktimer);
+
+ break;
+ case Finwait2:
+ /* no process to read the data, send a reset */
+ if (bp != NULL)
+ freeblist(bp);
+ sndrst(tcp, source, dest, length, &seg, version,
+ "send to Finwait2");
+ qunlock(&s->qlock);
+ poperror();
+ return;
}
}
@@ -2595,38 +2642,39 @@
tcb->flags |= FORCE;
switch (tcb->state) {
- case Established:
- tcb->rcv.nxt++;
- tcpsetstate(s, Close_wait);
- break;
- case Finwait1:
- tcb->rcv.nxt++;
- if (qlen(s->wq) + tcb->flgcnt == 0) {
- tcphalt(tpriv, &tcb->rtt_timer);
- tcphalt(tpriv, &tcb->acktimer);
- tcphalt(tpriv, &tcb->katimer);
- tcpsetstate(s, Time_wait);
- tcb->timer.start = MSL2 * (1000 / MSPTICK);
- tcpgo(tpriv, &tcb->timer);
- } else
- tcpsetstate(s, Closing);
- break;
- case Finwait2:
- tcb->rcv.nxt++;
+ case Established:
+ tcb->rcv.nxt++;
+ tcpsetstate(s, Close_wait);
+ break;
+ case Finwait1:
+ tcb->rcv.nxt++;
+ if (qlen(s->wq) + tcb->flgcnt == 0) {
tcphalt(tpriv, &tcb->rtt_timer);
tcphalt(tpriv, &tcb->acktimer);
tcphalt(tpriv, &tcb->katimer);
tcpsetstate(s, Time_wait);
- tcb->timer.start = MSL2 * (1000 / MSPTICK);
+ tcb->timer.start = MSL2 * (1000 /
+ MSPTICK);
tcpgo(tpriv, &tcb->timer);
- break;
- case Close_wait:
- case Closing:
- case Last_ack:
- break;
- case Time_wait:
- tcpgo(tpriv, &tcb->timer);
- break;
+ } else
+ tcpsetstate(s, Closing);
+ break;
+ case Finwait2:
+ tcb->rcv.nxt++;
+ tcphalt(tpriv, &tcb->rtt_timer);
+ tcphalt(tpriv, &tcb->acktimer);
+ tcphalt(tpriv, &tcb->katimer);
+ tcpsetstate(s, Time_wait);
+ tcb->timer.start = MSL2 * (1000 / MSPTICK);
+ tcpgo(tpriv, &tcb->timer);
+ break;
+ case Close_wait:
+ case Closing:
+ case Last_ack:
+ break;
+ case Time_wait:
+ tcpgo(tpriv, &tcb->timer);
+ break;
}
}
@@ -2667,8 +2715,8 @@
if (tcb->ts_recent) {
opt_size += TS_LENGTH;
- /* Note that when we're a SYN, we overestimate slightly. This is safe,
- * and not really a problem. */
+ /* Note that when we're a SYN, we overestimate slightly. This
+ * is safe, and not really a problem. */
opt_size += TS_SEND_PREPAD;
}
if (tcb->rcv.nr_sacks)
@@ -2690,8 +2738,9 @@
if (ssize > 32 * 1024)
ssize = 32 * 1024;
if (!retrans) {
- /* Clamp xmit to an integral MSS to avoid ragged tail segments
- * causing poor link utilization. */
+ /* Clamp xmit to an integral MSS to avoid ragged
+ * tail segments causing poor link utilization.
+ */
ssize = ROUNDDOWN(ssize, payload_mss);
}
}
@@ -2724,17 +2773,18 @@
usable -= tcb->snd.in_flight;
else
usable = 0;
- /* Avoid Silly Window Syndrome. This is a little different thant RFC
- * 813. I took their additional enhancement of "< MSS" as an AND, not
- * an OR. 25% of a large snd.wnd is pretty large, and our main goal is
- * to avoid packets smaller than MSS. I still use the 25% threshold,
- * because it is important that there is *some* data in_flight. If
- * usable < MSS because snd.wnd is very small (but not 0), we might
- * never get an ACK and would need to set up a timer.
+ /* Avoid Silly Window Syndrome. This is a little different
+ * thant RFC 813. I took their additional enhancement of "<
+ * MSS" as an AND, not an OR. 25% of a large snd.wnd is pretty
+ * large, and our main goal is to avoid packets smaller than
+ * MSS. I still use the 25% threshold, because it is important
+ * that there is *some* data in_flight. If usable < MSS because
+ * snd.wnd is very small (but not 0), we might never get an ACK
+ * and would need to set up a timer.
*
- * Also, I'm using 'ssize' as a proxy for a PSH point. If there's just
- * a small blob in the qio (or retrans!), then we might as well just
- * send it. */
+ * Also, I'm using 'ssize' as a proxy for a PSH point. If
+ * there's just a small blob in the qio (or retrans!), then we
+ * might as well just send it. */
if ((usable < tcb->typical_mss) && (usable < tcb->snd.wnd >> 2)
&& (usable < ssize)) {
return FALSE;
@@ -2784,22 +2834,23 @@
for (int i = 0; i < tcb->snd.nr_sacks; i++) {
tcb_sack = &tcb->snd.sacks[i];
if (seq_lt(tcb->snd.rtx, tcb_sack->left)) {
- /* So ssize is supposed to include any *new* flags to flgcnt, which
- * at this point would be a FIN.
+ /* So ssize is supposed to include any *new* flags to
+ * flgcnt, which at this point would be a FIN.
*
- * It might be possible that flgcnt is incremented so we send a FIN,
- * even for an intermediate sack retrans. Perhaps the user closed
- * the conv.
+ * It might be possible that flgcnt is incremented so we
+ * send a FIN, even for an intermediate sack retrans.
+ * Perhaps the user closed the conv.
*
- * However, the way the "flgcnt for FIN" works is that it inflates
- * the desired amount we'd like to send (qlen + flgcnt).
- * Eventually, we reach the end of the queue and fail to extract all
- * of dsize. At that point, we put on the FIN, and that's where the
- * extra 'byte' comes from.
+ * However, the way the "flgcnt for FIN" works is that
+ * it inflates the desired amount we'd like to send
+ * (qlen + flgcnt). Eventually, we reach the end of the
+ * queue and fail to extract all of dsize. At that
+ * point, we put on the FIN, and that's where the extra
+ * 'byte' comes from.
*
- * For sack retrans, since we're extracting from parts of the qio
- * that aren't the right-most edge, we don't need to consider flgcnt
- * when setting ssize. */
+ * For sack retrans, since we're extracting from parts
+ * of the qio that aren't the right-most edge, we don't
+ * need to consider flgcnt when setting ssize. */
from_seq = tcb->snd.rtx;
sent = from_seq - tcb->snd.una;
ssize = tcb_sack->left - from_seq;
@@ -2807,15 +2858,15 @@
break;
}
}
- /* SACK holes have first dibs, but we can still opportunisitically send new
- * data.
+ /* SACK holes have first dibs, but we can still opportunisitically send
+ * new data.
*
- * During other types of recovery, we'll just send from the retrans point.
- * If we're in an RTO while we still have sacks, we could be resending data
- * that wasn't lost. Consider a sack that is still growing (usually the
- * right-most), but we haven't received the ACK yet. rxt may be included in
- * that area. Given we had two losses or otherwise timed out, I'm not too
- * concerned.
+ * During other types of recovery, we'll just send from the retrans
+ * point. If we're in an RTO while we still have sacks, we could be
+ * resending data that wasn't lost. Consider a sack that is still
+ * growing (usually the right-most), but we haven't received the ACK
+ * yet. rxt may be included in that area. Given we had two losses or
+ * otherwise timed out, I'm not too concerned.
*
* Note that Fast and RTO can send data beyond nxt. If we change that,
* change the accounting below. */
@@ -2831,18 +2882,19 @@
break;
}
sent = from_seq - tcb->snd.una;
- /* qlen + flgcnt is every seq we want to have sent, including unack'd
- * data, unacked flags, and new flags. */
+ /* qlen + flgcnt is every seq we want to have sent, including
+ * unack'd data, unacked flags, and new flags. */
ssize = qlen(s->wq) + tcb->flgcnt - sent;
}
if (!throttle_ssize(s, tcb, &ssize, payload_mss, sack_retrans))
return FALSE;
- /* This counts flags, which is a little hokey, but it's okay since in_flight
- * gets reset on each ACK */
+ /* This counts flags, which is a little hokey, but it's okay since
+ * in_flight gets reset on each ACK */
tcb->snd.in_flight += ssize;
- /* Log and track rxmit. This covers both SACK (retrans) and fast rxmit. */
+ /* Log and track rxmit. This covers both SACK (retrans) and fast rxmit.
+ */
if (ssize && seq_lt(tcb->snd.rtx, tcb->snd.nxt)) {
netlog(f, Logtcpverbose,
"%I.%d -> %I.%d: rxmit: rtx %u amt %u, nxt %u\n",
@@ -2852,31 +2904,34 @@
tpriv->stats[RetransSegs]++;
}
if (sack_retrans) {
- /* If we'll send up to the left edge, advance snd.rtx to the right.
+ /* If we'll send up to the left edge, advance snd.rtx to the
+ * right.
*
- * This includes the largest sack. It might get removed later, in which
- * case we'll underestimate the amount in-flight. The alternative is to
- * not count the rightmost sack, but when it gets removed, we'll retrans
- * it anyway. No matter what, we'd count it. */
+ * This includes the largest sack. It might get removed later,
+ * in which case we'll underestimate the amount in-flight. The
+ * alternative is to not count the rightmost sack, but when it
+ * gets removed, we'll retrans it anyway. No matter what, we'd
+ * count it. */
tcb->snd.rtx += ssize;
if (tcb->snd.rtx == tcb_sack->left)
tcb->snd.rtx = tcb_sack->right;
- /* RFC 6675 says we MAY rearm the RTO timer on each retrans, since we
- * might not be getting ACKs for a while. */
+ /* RFC 6675 says we MAY rearm the RTO timer on each retrans,
+ * since we might not be getting ACKs for a while. */
tcpsettimer(tcb);
} else {
switch (tcb->snd.recovery) {
default:
- /* under normal op, we drag rtx along with nxt. this prevents us
- * from sending sacks too early (up above), since rtx doesn't get
- * reset to una until we have a loss (e.g. 3 dupacks/sacks). */
+ /* under normal op, we drag rtx along with nxt. this
+ * prevents us from sending sacks too early (up above),
+ * since rtx doesn't get reset to una until we have a
+ * loss (e.g. 3 dupacks/sacks). */
tcb->snd.nxt += ssize;
tcb->snd.rtx = tcb->snd.nxt;
break;
case SACK_RETRANS_RECOVERY:
- /* We explicitly do not want to increase rtx here. We might still
- * need it to fill in a sack gap below nxt if we get new, higher
- * sacks. */
+ /* We explicitly do not want to increase rtx here. We
+ * might still need it to fill in a sack gap below nxt
+ * if we get new, higher sacks. */
tcb->snd.nxt += ssize;
break;
case FAST_RETRANS_RECOVERY:
@@ -2921,10 +2976,10 @@
tcb = (Tcpctl *) s->ptcl;
switch (tcb->state) {
- case Listen:
- case Closed:
- case Finwait2:
- return;
+ case Listen:
+ case Closed:
+ case Finwait2:
+ return;
}
/* force an ack when a window has opened up */
@@ -2937,13 +2992,14 @@
if (tcb->snd.nxt != tcb->iss && (tcb->flags & SYNACK) == 0)
break;
- /* payload_mss is the actual amount of data in the packet, which is the
- * advertised (mss - header opts). This varies from packet to packet,
- * based on the options that might be present (e.g. always timestamps,
- * sometimes SACKs) */
+ /* payload_mss is the actual amount of data in the packet, which
+ * is the advertised (mss - header opts). This varies from
+ * packet to packet, based on the options that might be present
+ * (e.g. always timestamps, sometimes SACKs) */
payload_mss = derive_payload_mss(tcb);
- if (!get_xmit_segment(s, tcb, payload_mss, &from_seq, &sent, &ssize))
+ if (!get_xmit_segment(s, tcb, payload_mss, &from_seq, &sent,
+ &ssize))
break;
dsize = ssize;
@@ -2956,9 +3012,9 @@
tcb->flags &= ~FORCE;
tcprcvwin(s);
- /* By default we will generate an ack, so we can normally turn off the
- * timer. If we're blocked, we'll want the timer so we can send a
- * window update. */
+ /* By default we will generate an ack, so we can normally turn
+ * off the timer. If we're blocked, we'll want the timer so we
+ * can send a window update. */
if (!tcb->rcv.blocked)
tcphalt(tpriv, &tcb->acktimer);
tcb->rcv.una = 0;
@@ -2969,11 +3025,13 @@
seg.ws = 0;
seg.sack_ok = FALSE;
seg.nr_sacks = 0;
- /* When outputting, Syn_sent means "send the Syn", for connections we
- * initiate. SYNACKs are sent from sndsynack directly. */
+ /* When outputting, Syn_sent means "send the Syn", for
+ * connections we initiate. SYNACKs are sent from sndsynack
+ * directly. */
if (tcb->state == Syn_sent) {
seg.flags = 0;
- seg.sack_ok = SACK_SUPPORTED; /* here's where we advertise SACK */
+ /* here's where we advertise SACK */
+ seg.sack_ok = SACK_SUPPORTED;
if (tcb->snd.nxt - ssize == tcb->iss) {
seg.flags |= SYN;
dsize--;
@@ -2995,10 +3053,11 @@
if (dsize != 0) {
bp = qcopy(s->wq, dsize, sent);
if (BLEN(bp) != dsize) {
- /* Here's where the flgcnt kicked in. Note dsize is
- * decremented, but ssize isn't. Not that we use ssize for much
- * anymore. Decrementing dsize prevents us from sending a PSH
- * with the FIN. */
+ /* Here's where the flgcnt kicked in. Note
+ * dsize is decremented, but ssize isn't. Not
+ * that we use ssize for much anymore.
+ * Decrementing dsize prevents us from sending a
+ * PSH with the FIN. */
seg.flags |= FIN;
dsize--;
}
@@ -3013,25 +3072,25 @@
/* Build header, link data and compute cksum */
switch (version) {
- case V4:
- tcb->protohdr.tcp4hdr.vihl = IP_VER4;
- hbp = htontcp4(&seg, bp, &tcb->protohdr.tcp4hdr, tcb);
- if (hbp == NULL) {
- freeblist(bp);
- return;
- }
- break;
- case V6:
- tcb->protohdr.tcp6hdr.vcf[0] = IP_VER6;
- hbp = htontcp6(&seg, bp, &tcb->protohdr.tcp6hdr, tcb);
- if (hbp == NULL) {
- freeblist(bp);
- return;
- }
- break;
- default:
- hbp = NULL; /* to suppress a warning */
- panic("tcpoutput: version %d", version);
+ case V4:
+ tcb->protohdr.tcp4hdr.vihl = IP_VER4;
+ hbp = htontcp4(&seg, bp, &tcb->protohdr.tcp4hdr, tcb);
+ if (hbp == NULL) {
+ freeblist(bp);
+ return;
+ }
+ break;
+ case V6:
+ tcb->protohdr.tcp6hdr.vcf[0] = IP_VER6;
+ hbp = htontcp6(&seg, bp, &tcb->protohdr.tcp6hdr, tcb);
+ if (hbp == NULL) {
+ freeblist(bp);
+ return;
+ }
+ break;
+ default:
+ hbp = NULL; /* to suppress a warning */
+ panic("tcpoutput: version %d", version);
}
/* Start the transmission timers if there is new data and we
@@ -3041,8 +3100,8 @@
if (tcb->timer.state != TcptimerON)
tcpgo(tpriv, &tcb->timer);
- if (!tcb->ts_recent && (tcb->rtt_timer.state != TcptimerON)) {
- /* If round trip timer isn't running, start it. */
+ if (!tcb->ts_recent && (tcb->rtt_timer.state !=
+ TcptimerON)) {
tcpgo(tpriv, &tcb->rtt_timer);
tcb->rttseq = from_seq + ssize;
}
@@ -3054,29 +3113,30 @@
tcpgo(tpriv, &tcb->katimer);
switch (version) {
- case V4:
- if (ipoput4(f, hbp, 0, s->ttl, s->tos, s) < 0) {
- /* a negative return means no route */
- localclose(s, "no route");
- }
- break;
- case V6:
- if (ipoput6(f, hbp, 0, s->ttl, s->tos, s) < 0) {
- /* a negative return means no route */
- localclose(s, "no route");
- }
- break;
- default:
- panic("tcpoutput2: version %d", version);
+ case V4:
+ if (ipoput4(f, hbp, 0, s->ttl, s->tos, s) < 0) {
+ /* a negative return means no route */
+ localclose(s, "no route");
+ }
+ break;
+ case V6:
+ if (ipoput6(f, hbp, 0, s->ttl, s->tos, s) < 0) {
+ /* a negative return means no route */
+ localclose(s, "no route");
+ }
+ break;
+ default:
+ panic("tcpoutput2: version %d", version);
}
if (ssize) {
- /* The outer loop thinks we sent one packet. If we used TSO, we
- * might have sent several. Minus one for the loop increment. */
+ /* The outer loop thinks we sent one packet. If we used
+ * TSO, we might have sent several. Minus one for the
+ * loop increment. */
msgs += DIV_ROUND_UP(ssize, payload_mss) - 1;
}
- /* Old Plan 9 tidbit - yield every four messages. We want to break out
- * and unlock so we can process inbound ACKs which might do things like
- * say "slow down". */
+ /* Old Plan 9 tidbit - yield every four messages. We want to
+ * break out and unlock so we can process inbound ACKs which
+ * might do things like say "slow down". */
if (msgs >= next_yield) {
next_yield = msgs + 4;
qunlock(&s->qlock);
@@ -3292,38 +3352,38 @@
nexterror();
}
switch (tcb->state) {
- default:
- tcb->backoff++;
- if (tcb->state == Syn_sent)
- maxback = MAXBACKMS / 2;
- else
- maxback = MAXBACKMS;
- tcb->backedoff += tcb->timer.start * MSPTICK;
- if (tcb->backedoff >= maxback) {
- localclose(s, "connection timed out");
- break;
- }
- netlog(s->p->f, Logtcprxmt,
- "%I.%d -> %I.%d: timeout rxmit una %u, rtx %u, nxt %u, in_flight %u, timer.start %u\n",
- s->laddr, s->lport, s->raddr, s->rport,
- tcb->snd.una, tcb->snd.rtx, tcb->snd.nxt, tcb->snd.in_flight,
- tcb->timer.start);
- tcpsettimer(tcb);
- tcp_loss_event(s, tcb);
- /* Advance the recovery point. Any dupacks/sacks below this won't
- * trigger a new loss, since we won't reset_recovery() until we ack
- * past recovery_pt. */
- tcb->snd.recovery = RTO_RETRANS_RECOVERY;
- tcb->snd.recovery_pt = tcb->snd.nxt;
- timeout_handle_sacks(tcb);
- tcprxmit(s);
- tpriv->stats[RetransTimeouts]++;
+ default:
+ tcb->backoff++;
+ if (tcb->state == Syn_sent)
+ maxback = MAXBACKMS / 2;
+ else
+ maxback = MAXBACKMS;
+ tcb->backedoff += tcb->timer.start * MSPTICK;
+ if (tcb->backedoff >= maxback) {
+ localclose(s, "connection timed out");
break;
- case Time_wait:
- localclose(s, NULL);
- break;
- case Closed:
- break;
+ }
+ netlog(s->p->f, Logtcprxmt,
+ "%I.%d -> %I.%d: timeout rxmit una %u, rtx %u, nxt %u, in_flight %u, timer.start %u\n",
+ s->laddr, s->lport, s->raddr, s->rport,
+ tcb->snd.una, tcb->snd.rtx, tcb->snd.nxt,
+ tcb->snd.in_flight, tcb->timer.start);
+ tcpsettimer(tcb);
+ tcp_loss_event(s, tcb);
+ /* Advance the recovery point. Any dupacks/sacks below this
+ * won't trigger a new loss, since we won't reset_recovery()
+ * until we ack past recovery_pt. */
+ tcb->snd.recovery = RTO_RETRANS_RECOVERY;
+ tcb->snd.recovery_pt = tcb->snd.nxt;
+ timeout_handle_sacks(tcb);
+ tcprxmit(s);
+ tpriv->stats[RetransTimeouts]++;
+ break;
+ case Time_wait:
+ localclose(s, NULL);
+ break;
+ case Closed:
+ break;
}
qunlock(&s->qlock);
poperror();
@@ -3348,7 +3408,8 @@
tcb->rcv.urg = tcb->rcv.nxt;
tcb->irs = seg->seq;
- /* our sending max segment size cannot be bigger than what he asked for */
+ /* our sending max segment size cannot be bigger than what he asked for
+ */
if (seg->mss != 0 && seg->mss < tcb->mss) {
tcb->mss = seg->mss;
tcb->typical_mss = tcb->mss;
@@ -3466,7 +3527,8 @@
accept++;
else if (len != 0) {
if (inwindow(tcb, seg->seq + len - 1) ||
- seq_within(tcb->rcv.nxt, seg->seq, seg->seq + len - 1))
+ seq_within(tcb->rcv.nxt, seg->seq,
+ seg->seq + len - 1))
accept++;
}
}
@@ -3541,21 +3603,19 @@
for (p = tcp->conv; *p; p++) {
s = *p;
tcb = (Tcpctl *) s->ptcl;
- if (s->rport == pdest)
- if (s->lport == psource)
- if (tcb->state != Closed)
- if (ipcmp(s->raddr, dest) == 0)
- if (ipcmp(s->laddr, source) == 0) {
- qlock(&s->qlock);
- switch (tcb->state) {
- case Syn_sent:
- localclose(s, msg);
- break;
- }
- qunlock(&s->qlock);
- freeblist(bp);
- return;
- }
+ if ((s->rport == pdest) && (s->lport == psource)
+ && (tcb->state != Closed) && (ipcmp(s->raddr, dest) == 0)
+ && (ipcmp(s->laddr, source) == 0)) {
+ qlock(&s->qlock);
+ switch (tcb->state) {
+ case Syn_sent:
+ localclose(s, msg);
+ break;
+ }
+ qunlock(&s->qlock);
+ freeblist(bp);
+ return;
+ }
}
freeblist(bp);
}
@@ -3642,7 +3702,8 @@
x = backoff(tcb->backoff) * (tcb->srtt + MAX(4 * tcb->mdev, MSPTICK));
x = DIV_ROUND_UP(x, MSPTICK);
- /* Bounded twixt 1/2 and 64 seconds. RFC 6298 suggested min is 1 second. */
+ /* Bounded twixt 1/2 and 64 seconds. RFC 6298 suggested min is 1
+ * second. */
if (x < 500 / MSPTICK)
x = 500 / MSPTICK;
else if (x > (64000 / MSPTICK))
diff --git a/kern/src/net/udp.c b/kern/src/net/udp.c
index d47a32d..c3e901b 100644
--- a/kern/src/net/udp.c
+++ b/kern/src/net/udp.c
@@ -75,21 +75,21 @@
typedef struct Udp4hdr Udp4hdr;
struct Udp4hdr {
/* ip header */
- uint8_t vihl; /* Version and header length */
- uint8_t tos; /* Type of service */
- uint8_t length[2]; /* packet length */
- uint8_t id[2]; /* Identification */
- uint8_t frag[2]; /* Fragment information */
+ uint8_t vihl; /* Version and header length */
+ uint8_t tos; /* Type of service */
+ uint8_t length[2]; /* packet length */
+ uint8_t id[2]; /* Identification */
+ uint8_t frag[2]; /* Fragment information */
uint8_t Unused;
- uint8_t udpproto; /* Protocol */
- uint8_t udpplen[2]; /* Header plus data length */
+ uint8_t udpproto; /* Protocol */
+ uint8_t udpplen[2]; /* Header plus data length */
uint8_t udpsrc[IPv4addrlen]; /* Ip source */
uint8_t udpdst[IPv4addrlen]; /* Ip destination */
/* udp header */
uint8_t udpsport[2]; /* Source port */
uint8_t udpdport[2]; /* Destination port */
- uint8_t udplen[2]; /* data length */
+ uint8_t udplen[2]; /* data length */
uint8_t udpcksum[2]; /* Checksum */
};
@@ -105,7 +105,7 @@
/* udp header */
uint8_t udpsport[2]; /* Source port */
uint8_t udpdport[2]; /* Destination port */
- uint8_t udplen[2]; /* data length */
+ uint8_t udplen[2]; /* data length */
uint8_t udpcksum[2]; /* Checksum */
};
@@ -126,8 +126,8 @@
Udpstats ustats;
/* non-MIB stats */
- uint32_t csumerr; /* checksum errors */
- uint32_t lenerr; /* short packet */
+ uint32_t csumerr; /* checksum errors */
+ uint32_t lenerr; /* short packet */
};
void (*etherprofiler) (char *name, int qlen);
@@ -164,8 +164,8 @@
static int udpstate(struct conv *c, char *state, int n)
{
return snprintf(state, n, "%s qin %d qout %d\n",
- c->inuse ? "Open" : "Closed",
- c->rq ? qlen(c->rq) : 0, c->wq ? qlen(c->wq) : 0);
+ c->inuse ? "Open" : "Closed",
+ c->rq ? qlen(c->rq) : 0, c->wq ? qlen(c->wq) : 0);
}
static void udpannounce(struct conv *c, char **argv, int argc)
@@ -239,40 +239,40 @@
ucb = (Udpcb *) c->ptcl;
switch (ucb->headers) {
- case 7:
- /* get user specified addresses */
- bp = pullupblock(bp, UDP_USEAD7);
- if (bp == NULL)
- return;
- ipmove(raddr, bp->rp);
- bp->rp += IPaddrlen;
- ipmove(laddr, bp->rp);
- bp->rp += IPaddrlen;
- /* pick interface closest to dest */
- if (ipforme(f, laddr) != Runi)
- findlocalip(f, laddr, raddr);
- bp->rp += IPaddrlen; /* Ignore ifc address */
- rport = nhgets(bp->rp);
- bp->rp += 2 + 2; /* Ignore local port */
- break;
- case 6:
- /* get user specified addresses */
- bp = pullupblock(bp, UDP_USEAD6);
- if (bp == NULL)
- return;
- ipmove(raddr, bp->rp);
- bp->rp += IPaddrlen;
- ipmove(laddr, bp->rp);
- bp->rp += IPaddrlen;
- /* pick interface closest to dest */
- if (ipforme(f, laddr) != Runi)
- findlocalip(f, laddr, raddr);
- rport = nhgets(bp->rp);
- bp->rp += 2 + 2; /* Ignore local port */
- break;
- default:
- rport = 0;
- break;
+ case 7:
+ /* get user specified addresses */
+ bp = pullupblock(bp, UDP_USEAD7);
+ if (bp == NULL)
+ return;
+ ipmove(raddr, bp->rp);
+ bp->rp += IPaddrlen;
+ ipmove(laddr, bp->rp);
+ bp->rp += IPaddrlen;
+ /* pick interface closest to dest */
+ if (ipforme(f, laddr) != Runi)
+ findlocalip(f, laddr, raddr);
+ bp->rp += IPaddrlen; /* Ignore ifc address */
+ rport = nhgets(bp->rp);
+ bp->rp += 2 + 2; /* Ignore local port */
+ break;
+ case 6:
+ /* get user specified addresses */
+ bp = pullupblock(bp, UDP_USEAD6);
+ if (bp == NULL)
+ return;
+ ipmove(raddr, bp->rp);
+ bp->rp += IPaddrlen;
+ ipmove(laddr, bp->rp);
+ bp->rp += IPaddrlen;
+ /* pick interface closest to dest */
+ if (ipforme(f, laddr) != Runi)
+ findlocalip(f, laddr, raddr);
+ rport = nhgets(bp->rp);
+ bp->rp += 2 + 2; /* Ignore local port */
+ break;
+ default:
+ rport = 0;
+ break;
}
if (ucb->headers) {
@@ -294,89 +294,89 @@
/* fill in pseudo header and compute checksum */
switch (version) {
- case V4:
- bp = padblock(bp, UDP4_IPHDR_SZ + UDP_UDPHDR_SZ);
- if (bp == NULL)
- return;
+ case V4:
+ bp = padblock(bp, UDP4_IPHDR_SZ + UDP_UDPHDR_SZ);
+ if (bp == NULL)
+ return;
- uh4 = (Udp4hdr *) (bp->rp);
- ptcllen = dlen + UDP_UDPHDR_SZ;
- uh4->Unused = 0;
- uh4->udpproto = IP_UDPPROTO;
- uh4->frag[0] = 0;
- uh4->frag[1] = 0;
- hnputs(uh4->udpplen, ptcllen);
- if (ucb->headers) {
- v6tov4(uh4->udpdst, raddr);
- hnputs(uh4->udpdport, rport);
- v6tov4(uh4->udpsrc, laddr);
- rc = NULL;
- } else {
- v6tov4(uh4->udpdst, c->raddr);
- hnputs(uh4->udpdport, c->rport);
- if (ipcmp(c->laddr, IPnoaddr) == 0)
- findlocalip(f, c->laddr, c->raddr);
- v6tov4(uh4->udpsrc, c->laddr);
- rc = c;
- }
- hnputs(uh4->udpsport, c->lport);
- hnputs(uh4->udplen, ptcllen);
- uh4->udpcksum[0] = 0;
- uh4->udpcksum[1] = 0;
- bp->network_offset = 0;
- bp->transport_offset = offsetof(Udp4hdr, udpsport);
- assert(bp->transport_offset == UDP4_IPHDR_SZ);
- hnputs(uh4->udpcksum,
- ~ptclcsum(bp, UDP4_PHDR_OFF, UDP4_PHDR_SZ));
- bp->tx_csum_offset = uh4->udpcksum - uh4->udpsport;
- bp->flag |= Budpck;
- uh4->vihl = IP_VER4;
- ipoput4(f, bp, 0, c->ttl, c->tos, rc);
- break;
+ uh4 = (Udp4hdr *) (bp->rp);
+ ptcllen = dlen + UDP_UDPHDR_SZ;
+ uh4->Unused = 0;
+ uh4->udpproto = IP_UDPPROTO;
+ uh4->frag[0] = 0;
+ uh4->frag[1] = 0;
+ hnputs(uh4->udpplen, ptcllen);
+ if (ucb->headers) {
+ v6tov4(uh4->udpdst, raddr);
+ hnputs(uh4->udpdport, rport);
+ v6tov4(uh4->udpsrc, laddr);
+ rc = NULL;
+ } else {
+ v6tov4(uh4->udpdst, c->raddr);
+ hnputs(uh4->udpdport, c->rport);
+ if (ipcmp(c->laddr, IPnoaddr) == 0)
+ findlocalip(f, c->laddr, c->raddr);
+ v6tov4(uh4->udpsrc, c->laddr);
+ rc = c;
+ }
+ hnputs(uh4->udpsport, c->lport);
+ hnputs(uh4->udplen, ptcllen);
+ uh4->udpcksum[0] = 0;
+ uh4->udpcksum[1] = 0;
+ bp->network_offset = 0;
+ bp->transport_offset = offsetof(Udp4hdr, udpsport);
+ assert(bp->transport_offset == UDP4_IPHDR_SZ);
+ hnputs(uh4->udpcksum,
+ ~ptclcsum(bp, UDP4_PHDR_OFF, UDP4_PHDR_SZ));
+ bp->tx_csum_offset = uh4->udpcksum - uh4->udpsport;
+ bp->flag |= Budpck;
+ uh4->vihl = IP_VER4;
+ ipoput4(f, bp, 0, c->ttl, c->tos, rc);
+ break;
- case V6:
- bp = padblock(bp, UDP6_IPHDR_SZ + UDP_UDPHDR_SZ);
- if (bp == NULL)
- return;
+ case V6:
+ bp = padblock(bp, UDP6_IPHDR_SZ + UDP_UDPHDR_SZ);
+ if (bp == NULL)
+ return;
- // using the v6 ip header to create pseudo header
- // first then reset it to the normal ip header
- uh6 = (Udp6hdr *) (bp->rp);
- memset(uh6, 0, 8);
- ptcllen = dlen + UDP_UDPHDR_SZ;
- hnputl(uh6->viclfl, ptcllen);
- uh6->hoplimit = IP_UDPPROTO;
- if (ucb->headers) {
- ipmove(uh6->udpdst, raddr);
- hnputs(uh6->udpdport, rport);
- ipmove(uh6->udpsrc, laddr);
- rc = NULL;
- } else {
- ipmove(uh6->udpdst, c->raddr);
- hnputs(uh6->udpdport, c->rport);
- if (ipcmp(c->laddr, IPnoaddr) == 0)
- findlocalip(f, c->laddr, c->raddr);
- ipmove(uh6->udpsrc, c->laddr);
- rc = c;
- }
- hnputs(uh6->udpsport, c->lport);
- hnputs(uh6->udplen, ptcllen);
- uh6->udpcksum[0] = 0;
- uh6->udpcksum[1] = 0;
- hnputs(uh6->udpcksum,
- ptclcsum(bp, UDP6_PHDR_OFF,
- dlen + UDP_UDPHDR_SZ + UDP6_PHDR_SZ));
- memset(uh6, 0, 8);
- bp->network_offset = 0;
- bp->transport_offset = offsetof(Udp6hdr, udpsport);
- uh6->viclfl[0] = IP_VER6;
- hnputs(uh6->len, ptcllen);
- uh6->nextheader = IP_UDPPROTO;
- ipoput6(f, bp, 0, c->ttl, c->tos, rc);
- break;
+ // using the v6 ip header to create pseudo header
+ // first then reset it to the normal ip header
+ uh6 = (Udp6hdr *) (bp->rp);
+ memset(uh6, 0, 8);
+ ptcllen = dlen + UDP_UDPHDR_SZ;
+ hnputl(uh6->viclfl, ptcllen);
+ uh6->hoplimit = IP_UDPPROTO;
+ if (ucb->headers) {
+ ipmove(uh6->udpdst, raddr);
+ hnputs(uh6->udpdport, rport);
+ ipmove(uh6->udpsrc, laddr);
+ rc = NULL;
+ } else {
+ ipmove(uh6->udpdst, c->raddr);
+ hnputs(uh6->udpdport, c->rport);
+ if (ipcmp(c->laddr, IPnoaddr) == 0)
+ findlocalip(f, c->laddr, c->raddr);
+ ipmove(uh6->udpsrc, c->laddr);
+ rc = c;
+ }
+ hnputs(uh6->udpsport, c->lport);
+ hnputs(uh6->udplen, ptcllen);
+ uh6->udpcksum[0] = 0;
+ uh6->udpcksum[1] = 0;
+ hnputs(uh6->udpcksum,
+ ptclcsum(bp, UDP6_PHDR_OFF, dlen + UDP_UDPHDR_SZ +
+ UDP6_PHDR_SZ));
+ memset(uh6, 0, 8);
+ bp->network_offset = 0;
+ bp->transport_offset = offsetof(Udp6hdr, udpsport);
+ uh6->viclfl[0] = IP_VER6;
+ hnputs(uh6->len, ptcllen);
+ uh6->nextheader = IP_UDPPROTO;
+ ipoput6(f, bp, 0, c->ttl, c->tos, rc);
+ break;
- default:
- panic("udpkick: version %d", version);
+ default:
+ panic("udpkick: version %d", version);
}
upriv->ustats.udpOutDatagrams++;
}
@@ -408,59 +408,59 @@
* (remember old values for icmpnoconv())
*/
switch (version) {
- case V4:
- ottl = uh4->Unused;
- uh4->Unused = 0;
- len = nhgets(uh4->udplen);
- olen = nhgets(uh4->udpplen);
- hnputs(uh4->udpplen, len);
+ case V4:
+ ottl = uh4->Unused;
+ uh4->Unused = 0;
+ len = nhgets(uh4->udplen);
+ olen = nhgets(uh4->udpplen);
+ hnputs(uh4->udpplen, len);
- v4tov6(raddr, uh4->udpsrc);
- v4tov6(laddr, uh4->udpdst);
- lport = nhgets(uh4->udpdport);
- rport = nhgets(uh4->udpsport);
+ v4tov6(raddr, uh4->udpsrc);
+ v4tov6(laddr, uh4->udpdst);
+ lport = nhgets(uh4->udpdport);
+ rport = nhgets(uh4->udpsport);
- if (!(bp->flag & Budpck) &&
- (uh4->udpcksum[0] || uh4->udpcksum[1]) &&
- ptclcsum(bp, UDP4_PHDR_OFF, len + UDP4_PHDR_SZ)) {
- upriv->ustats.udpInErrors++;
- netlog(f, Logudp, "udp: checksum error %I\n",
- raddr);
- printd("udp: checksum error %I\n", raddr);
- freeblist(bp);
- return;
- }
- uh4->Unused = ottl;
- hnputs(uh4->udpplen, olen);
- break;
- case V6:
- uh6 = (Udp6hdr *) (bp->rp);
- len = nhgets(uh6->udplen);
- oviclfl = nhgetl(uh6->viclfl);
- olen = nhgets(uh6->len);
- ottl = uh6->hoplimit;
- ipmove(raddr, uh6->udpsrc);
- ipmove(laddr, uh6->udpdst);
- lport = nhgets(uh6->udpdport);
- rport = nhgets(uh6->udpsport);
- memset(uh6, 0, 8);
- hnputl(uh6->viclfl, len);
- uh6->hoplimit = IP_UDPPROTO;
- if (ptclcsum(bp, UDP6_PHDR_OFF, len + UDP6_PHDR_SZ)) {
- upriv->ustats.udpInErrors++;
- netlog(f, Logudp, "udp: checksum error %I\n", raddr);
- printd("udp: checksum error %I\n", raddr);
- freeblist(bp);
- return;
- }
- hnputl(uh6->viclfl, oviclfl);
- hnputs(uh6->len, olen);
- uh6->nextheader = IP_UDPPROTO;
- uh6->hoplimit = ottl;
- break;
- default:
- panic("udpiput: version %d", version);
- return; /* to avoid a warning */
+ if (!(bp->flag & Budpck) &&
+ (uh4->udpcksum[0] || uh4->udpcksum[1]) &&
+ ptclcsum(bp, UDP4_PHDR_OFF, len + UDP4_PHDR_SZ)) {
+ upriv->ustats.udpInErrors++;
+ netlog(f, Logudp, "udp: checksum error %I\n",
+ raddr);
+ printd("udp: checksum error %I\n", raddr);
+ freeblist(bp);
+ return;
+ }
+ uh4->Unused = ottl;
+ hnputs(uh4->udpplen, olen);
+ break;
+ case V6:
+ uh6 = (Udp6hdr *) (bp->rp);
+ len = nhgets(uh6->udplen);
+ oviclfl = nhgetl(uh6->viclfl);
+ olen = nhgets(uh6->len);
+ ottl = uh6->hoplimit;
+ ipmove(raddr, uh6->udpsrc);
+ ipmove(laddr, uh6->udpdst);
+ lport = nhgets(uh6->udpdport);
+ rport = nhgets(uh6->udpsport);
+ memset(uh6, 0, 8);
+ hnputl(uh6->viclfl, len);
+ uh6->hoplimit = IP_UDPPROTO;
+ if (ptclcsum(bp, UDP6_PHDR_OFF, len + UDP6_PHDR_SZ)) {
+ upriv->ustats.udpInErrors++;
+ netlog(f, Logudp, "udp: checksum error %I\n", raddr);
+ printd("udp: checksum error %I\n", raddr);
+ freeblist(bp);
+ return;
+ }
+ hnputl(uh6->viclfl, oviclfl);
+ hnputs(uh6->len, olen);
+ uh6->nextheader = IP_UDPPROTO;
+ uh6->hoplimit = ottl;
+ break;
+ default:
+ panic("udpiput: version %d", version);
+ return; /* to avoid a warning */
}
c = iphtlook(&upriv->ht, raddr, rport, laddr, lport);
@@ -471,14 +471,14 @@
laddr, lport);
switch (version) {
- case V4:
- icmpnoconv(f, bp);
- break;
- case V6:
- icmphostunr(f, ifc, bp, icmp6_port_unreach, 0);
- break;
- default:
- panic("udpiput2: version %d", version);
+ case V4:
+ icmpnoconv(f, bp);
+ break;
+ case V6:
+ icmphostunr(f, ifc, bp, icmp6_port_unreach, 0);
+ break;
+ default:
+ panic("udpiput2: version %d", version);
}
freeblist(bp);
@@ -497,14 +497,14 @@
/* create a new conversation */
if (ipforme(f, laddr) != Runi) {
switch (version) {
- case V4:
- v4tov6(laddr, ifc->lifc->local);
- break;
- case V6:
- ipmove(laddr, ifc->lifc->local);
- break;
- default:
- panic("udpiput3: version %d", version);
+ case V4:
+ v4tov6(laddr, ifc->lifc->local);
+ break;
+ case V6:
+ ipmove(laddr, ifc->lifc->local);
+ break;
+ default:
+ panic("udpiput3: version %d", version);
}
}
qlock(&udp->qlock);
@@ -526,15 +526,15 @@
*/
len -= UDP_UDPHDR_SZ;
switch (version) {
- case V4:
- bp = trimblock(bp, UDP4_IPHDR_SZ + UDP_UDPHDR_SZ, len);
- break;
- case V6:
- bp = trimblock(bp, UDP6_IPHDR_SZ + UDP_UDPHDR_SZ, len);
- break;
- default:
- bp = NULL;
- panic("udpiput4: version %d", version);
+ case V4:
+ bp = trimblock(bp, UDP4_IPHDR_SZ + UDP_UDPHDR_SZ, len);
+ break;
+ case V6:
+ bp = trimblock(bp, UDP6_IPHDR_SZ + UDP_UDPHDR_SZ, len);
+ break;
+ default:
+ bp = NULL;
+ panic("udpiput4: version %d", version);
}
if (bp == NULL) {
qunlock(&c->qlock);
@@ -548,32 +548,32 @@
laddr, lport, len);
switch (ucb->headers) {
- case 7:
- /* pass the src address */
- bp = padblock(bp, UDP_USEAD7);
- p = bp->rp;
- ipmove(p, raddr);
- p += IPaddrlen;
- ipmove(p, laddr);
- p += IPaddrlen;
- ipmove(p, ifc->lifc->local);
- p += IPaddrlen;
- hnputs(p, rport);
- p += 2;
- hnputs(p, lport);
- break;
- case 6:
- /* pass the src address */
- bp = padblock(bp, UDP_USEAD6);
- p = bp->rp;
- ipmove(p, raddr);
- p += IPaddrlen;
- ipmove(p, ipforme(f, laddr) == Runi ? laddr : ifc->lifc->local);
- p += IPaddrlen;
- hnputs(p, rport);
- p += 2;
- hnputs(p, lport);
- break;
+ case 7:
+ /* pass the src address */
+ bp = padblock(bp, UDP_USEAD7);
+ p = bp->rp;
+ ipmove(p, raddr);
+ p += IPaddrlen;
+ ipmove(p, laddr);
+ p += IPaddrlen;
+ ipmove(p, ifc->lifc->local);
+ p += IPaddrlen;
+ hnputs(p, rport);
+ p += 2;
+ hnputs(p, lport);
+ break;
+ case 6:
+ /* pass the src address */
+ bp = padblock(bp, UDP_USEAD6);
+ p = bp->rp;
+ ipmove(p, raddr);
+ p += IPaddrlen;
+ ipmove(p, ipforme(f, laddr) == Runi ? laddr : ifc->lifc->local);
+ p += IPaddrlen;
+ hnputs(p, rport);
+ p += 2;
+ hnputs(p, lport);
+ break;
}
if (bp->next)
@@ -617,22 +617,22 @@
version = ((h4->vihl & 0xF0) == IP_VER6) ? V6 : V4;
switch (version) {
- case V4:
- v4tov6(dest, h4->udpdst);
- v4tov6(source, h4->udpsrc);
- psource = nhgets(h4->udpsport);
- pdest = nhgets(h4->udpdport);
- break;
- case V6:
- h6 = (Udp6hdr *) (bp->rp);
- ipmove(dest, h6->udpdst);
- ipmove(source, h6->udpsrc);
- psource = nhgets(h6->udpsport);
- pdest = nhgets(h6->udpdport);
- break;
- default:
- panic("udpadvise: version %d", version);
- return; /* to avoid a warning */
+ case V4:
+ v4tov6(dest, h4->udpdst);
+ v4tov6(source, h4->udpsrc);
+ psource = nhgets(h4->udpsport);
+ pdest = nhgets(h4->udpdport);
+ break;
+ case V6:
+ h6 = (Udp6hdr *) (bp->rp);
+ ipmove(dest, h6->udpdst);
+ ipmove(source, h6->udpsrc);
+ psource = nhgets(h6->udpsport);
+ pdest = nhgets(h6->udpdport);
+ break;
+ default:
+ panic("udpadvise: version %d", version);
+ return; /* to avoid a warning */
}
/* Look for a connection */
diff --git a/kern/src/ns/allocb.c b/kern/src/ns/allocb.c
index f02ae7a..bd9b998 100644
--- a/kern/src/ns/allocb.c
+++ b/kern/src/ns/allocb.c
@@ -86,15 +86,15 @@
b->lim = ((uint8_t*)b) + msize(b);
* See use of n in commented code below
*/
- b->lim =
- ((uint8_t *) b) + sizeof(struct block) + size + Hdrspc + (BLOCKALIGN -
- 1);
+ b->lim = ((uint8_t *) b) + sizeof(struct block) + size + Hdrspc +
+ (BLOCKALIGN - 1);
b->rp = b->base;
/* TODO: support this */
- /* n is supposed to be Hdrspc + rear padding + extra reserved memory, but
- * since we don't currently support checking how much memory was actually
- * reserved, this is always Hdrspc + rear padding. After rounding that down
- * to BLOCKALIGN, it's always Hdrpsc since the padding is < BLOCKALIGN.
+ /* n is supposed to be Hdrspc + rear padding + extra reserved memory,
+ * but since we don't currently support checking how much memory was
+ * actually reserved, this is always Hdrspc + rear padding. After
+ * rounding that down to BLOCKALIGN, it's always Hdrpsc since the
+ * padding is < BLOCKALIGN.
n = b->lim - b->base - size;
b->rp += n & ~(BLOCKALIGN - 1);
*/
@@ -200,8 +200,8 @@
{
struct extra_bdata *ebd;
- /* assuming our release method is kfree, which will change when we support
- * user buffers */
+ /* assuming our release method is kfree, which will change when we
+ * support user buffers */
for (int i = 0; i < b->nr_extra_bufs; i++) {
ebd = &b->extra_data[i];
if (ebd->base)
@@ -210,7 +210,7 @@
b->extra_len = 0;
b->nr_extra_bufs = 0;
kfree(b->extra_data); /* harmless if it is 0 */
- b->extra_data = 0; /* in case the block is reused by a free override */
+ b->extra_data = 0; /* in case the block is reused by a free override */
}
/* Frees a block, returning its size (len, not alloc) */
@@ -291,8 +291,8 @@
msg, i, ebd->off, ebd->len);
if (ebd->base) {
if (!kmalloc_refcnt((void*)ebd->base))
- panic("checkb %s: buf %d, base %p has no refcnt!\n", msg, i,
- ebd->base);
+ panic("checkb %s: buf %d, base %p has no refcnt!\n",
+ msg, i, ebd->base);
extra_len += ebd->len;
}
}
diff --git a/kern/src/ns/chan.c b/kern/src/ns/chan.c
index de0694f..3929813 100644
--- a/kern/src/ns/chan.c
+++ b/kern/src/ns/chan.c
@@ -65,7 +65,7 @@
typedef struct Elemlist Elemlist;
struct Elemlist {
- char *name; /* copy of name, so '/' can be overwritten */
+ char *name; /* copy of name, so '/' can be overwritten */
int ARRAY_SIZEs;
char **elems;
int *off;
@@ -108,7 +108,8 @@
char *t, *prev;
n = strlen(s) + 1;
- /* if it's a user, we can wait for memory; if not, something's very wrong */
+ /* if it's a user, we can wait for memory; if not, something's very
+ * wrong */
if (current) {
t = kzmalloc(n, 0);
} else {
@@ -160,8 +161,8 @@
ERRSTACK(1);
/* We can be called from RCU callbacks, but close methods can block. In
- * those cases, and any other context that cannot block, we need to defer
- * our work to a kernel message. */
+ * those cases, and any other context that cannot block, we need to
+ * defer our work to a kernel message. */
if (!can_block(this_pcpui_ptr())) {
run_as_rkm(chan_release, kref);
return;
@@ -201,8 +202,8 @@
qlock_init(&c->umqlock);
}
- /* if you get an error before associating with a dev, cclose skips calling
- * the dev's close */
+ /* if you get an error before associating with a dev, cclose skips
+ * calling the dev's close */
c->type = -1;
c->flag = 0;
kref_init(&c->ref, chan_release, 1);
@@ -279,7 +280,8 @@
n->s = t;
n->alen = a;
}
- if (n->len > 0 && n->s[n->len - 1] != '/' && s[0] != '/') /* don't insert extra slash if one is present */
+ /* don't insert extra slash if one is present */
+ if (n->len > 0 && n->s[n->len - 1] != '/' && s[0] != '/')
n->s[n->len++] = '/';
memmove(n->s + n->len, s, i + 1);
n->len += i;
@@ -391,6 +393,7 @@
static void mh_release(struct kref *kref)
{
struct mhead *mh = container_of(kref, struct mhead, ref);
+
mh->mount = (struct mount *)0xCafeBeef;
kfree(mh);
}
@@ -423,8 +426,8 @@
struct mhead *m, **l, *mh;
struct mount *nm, *f, *um, **h;
- /* Can bind anything onto a symlink's name. Otherwise, both the old and the
- * new must agree on whether or not it is a directory. */
+ /* Can bind anything onto a symlink's name. Otherwise, both the old and
+ * the new must agree on whether or not it is a directory. */
if (!(old->qid.type & QTSYMLINK) &&
(QTDIR & (old->qid.type ^ new->qid.type)))
error(EINVAL, ERROR_FIXME);
@@ -648,9 +651,8 @@
return false;
}
-int
-findmount(struct chan **cp,
- struct mhead **mp, int type, int dev, struct qid qid)
+int findmount(struct chan **cp, struct mhead **mp, int type, int dev,
+ struct qid qid)
{
struct pgrp *pg;
struct mhead *m;
@@ -718,12 +720,14 @@
for (t = f->mount; t; t = t->next) {
if (eqchan(c, t->to, 1)) {
/*
- * We want to come out on the left hand side of the mount
- * point using the element of the union that we entered on.
- * To do this, find the element that has a from name of
- * c->name->s.
+ * We want to come out on the left hand
+ * side of the mount point using the
+ * element of the union that we entered
+ * on. To do this, find the element
+ * that has a from name of c->name->s.
*/
- if (strcmp(t->head->from->name->s, name->s) != 0)
+ if (strcmp(t->head->from->name->s,
+ name->s) != 0)
continue;
nc = t->head->from;
chan_incref(nc);
@@ -762,15 +766,17 @@
/*
* While we haven't gotten all the way down the path:
* 1. step through a mount point, if any
- * 2. send a walk request for initial dotdot or initial prefix without dotdot
+ * 2. send a walk request for initial dotdot or initial prefix
+ * without dotdot
* 3. move to the first mountpoint along the way.
* 4. repeat.
*
- * An invariant is that each time through the loop, c is on the undomount
- * side of the mount point, and c's name is cname.
+ * An invariant is that each time through the loop, c is on the
+ * undomount side of the mount point, and c's name is cname.
*/
for (nhave = 0; nhave < nnames; nhave += n) {
- /* We only allow symlink when they are first and it's .. (see below) */
+ /* We only allow symlink when they are first and it's .. (see
+ * below) */
if ((c->qid.type & (QTDIR | QTSYMLINK)) == 0) {
if (nerror)
*nerror = nhave;
@@ -806,7 +812,8 @@
type = c->type;
dev = c->dev;
- if ((wq = devtab[type].walk(c, NULL, names + nhave, ntry)) == NULL) {
+ if ((wq = devtab[type].walk(c, NULL, names + nhave, ntry)) ==
+ NULL) {
/* try a union mount, if any */
if (mh && wh->can_mount) {
/*
@@ -815,8 +822,12 @@
rlock(&mh->lock);
for (f = mh->mount->next; f; f = f->next)
if ((wq =
- devtab[f->to->type].walk(f->to, NULL, names + nhave,
- ntry)) != NULL)
+ devtab[f->to->type].walk(f->to,
+ NULL,
+ names +
+ nhave,
+ ntry)) !=
+ NULL)
break;
runlock(&mh->lock);
if (f != NULL) {
@@ -847,20 +858,27 @@
nc = NULL;
if (wh->can_mount)
for (i = 0; i < wq->nqid && i < ntry - 1; i++)
- if (findmount(&nc, &nmh, type, dev, wq->qid[i]))
+ if (findmount(&nc, &nmh, type, dev,
+ wq->qid[i]))
break;
if (nc == NULL) { /* no mount points along path */
if (wq->clone == NULL) {
cclose(c);
cnameclose(cname);
- if (wq->nqid == 0 || (wq->qid[wq->nqid - 1].type & QTDIR)) {
+ if (wq->nqid == 0 ||
+ (wq->qid[wq->nqid - 1].type &
+ QTDIR)) {
if (nerror)
- *nerror = nhave + wq->nqid + 1;
- set_error(ENOENT, "walk failed");
+ *nerror = nhave +
+ wq->nqid + 1;
+ set_error(ENOENT,
+ "walk failed");
} else {
if (nerror)
- *nerror = nhave + wq->nqid;
- set_error(ENOTDIR, "walk failed");
+ *nerror = nhave +
+ wq->nqid;
+ set_error(ENOTDIR,
+ "walk failed");
}
kfree(wq);
if (mh != NULL)
@@ -869,12 +887,15 @@
}
n = wq->nqid;
if (wq->clone->qid.type & QTSYMLINK) {
- nc = walk_symlink(wq->clone, wh, nnames - nhave - n);
+ nc = walk_symlink(wq->clone, wh, nnames
+ - nhave - n);
if (!nc) {
- /* walk_symlink() set error. This seems to be the
- * standard walk() error-cleanup. */
+ /* walk_symlink() set error.
+ * This seems to be the standard
+ * walk() error-cleanup. */
if (nerror)
- *nerror = nhave + wq->nqid;
+ *nerror = nhave +
+ wq->nqid;
cclose(c);
cclose(wq->clone);
cnameclose(cname);
@@ -1115,8 +1136,9 @@
if (e.ARRAY_SIZEs == 0)
error(EEXIST, ERROR_FIXME);
e.ARRAY_SIZEs--;
- /* We're dropping the last element, which O_NOFOLLOW applied to. Not
- * sure if there are any legit reasons to have O_NOFOLLOW with create.*/
+ /* We're dropping the last element, which O_NOFOLLOW applied to.
+ * Not sure if there are any legit reasons to have O_NOFOLLOW
+ * with create.*/
omode &= ~O_NOFOLLOW;
break;
case Arename:
@@ -1125,7 +1147,8 @@
e.ARRAY_SIZEs--;
omode &= ~O_NOFOLLOW;
break;
- /* the difference for stat and lstat (Aaccess) are handled in sysfile.c */
+ /* the difference for stat and lstat (Aaccess) are handled in sysfile.c
+ */
case Abind:
case Amount:
case Aremove:
@@ -1141,26 +1164,29 @@
printd("namec %s walk error npath=%d\n", aname, npath);
error(EFAIL, "walk failed");
}
- /* Old plan 9 errors would jump here for the magic error parsing. */
+ /* Old plan 9 errors would jump here for the magic error
+ * parsing. */
NameError:
if (current_errstr()[0]) {
- /* errstr is set, we'll just stick with it and error out */
+ /* errstr is set, just stick with it and error out */
error_jmp();
} else {
error(EFAIL, "Name to chan lookup failed");
}
- /* brho: skipping the namec custom error string business, since it hides
- * the underlying failure. implement this if you want the old stuff. */
+ /* brho: skipping the namec custom error string business, since
+ * it hides the underlying failure. implement this if you want
+ * the old stuff. */
#if 0
strlcpy(tmperrbuf, current->errstr, sizeof(tmperrbuf));
- len = prefix + e.off[npath]; // prefix was name - aname, the start pt
- if (len < ERRMAX / 3 || (name = memrchr(aname, '/', len)) == NULL
- || name == aname)
- snprintf(get_cur_genbuf(), sizeof current->genbuf, "%.*s", len,
- aname);
+ // prefix was name - aname, the start pt
+ len = prefix + e.off[npath];
+ if (len < ERRMAX / 3 || (name = memrchr(aname, '/', len)) ==
+ NULL || name == aname)
+ snprintf(get_cur_genbuf(), sizeof current->genbuf,
+ "%.*s", len, aname);
else
- snprintf(get_cur_genbuf(), sizeof current->genbuf, "...%.*s",
- (int)(len - (name - aname)), name);
+ snprintf(get_cur_genbuf(), sizeof current->genbuf,
+ "...%.*s", (int)(len - (name - aname)), name);
snprintf(current->errstr, ERRMAX, "%#q %s", get_cur_genbuf(),
tmperrbuf);
#endif
@@ -1177,123 +1203,220 @@
}
switch (amode) {
- case Aaccess:
- if (wh->can_mount)
- domount(&c, NULL);
- break;
+ case Aaccess:
+ if (wh->can_mount)
+ domount(&c, NULL);
+ break;
- case Abind:
- m = NULL;
- if (wh->can_mount)
- domount(&c, &m);
- if (c->umh != NULL)
- putmhead(c->umh);
- c->umh = m;
- break;
+ case Abind:
+ m = NULL;
+ if (wh->can_mount)
+ domount(&c, &m);
+ if (c->umh != NULL)
+ putmhead(c->umh);
+ c->umh = m;
+ break;
- case Aremove:
- case Aopen:
+ case Aremove:
+ case Aopen:
Open:
- /* save the name; domount might change c */
- cname = c->name;
- kref_get(&cname->ref, 1);
- m = NULL;
- if (wh->can_mount)
- domount(&c, &m);
+ /* save the name; domount might change c */
+ cname = c->name;
+ kref_get(&cname->ref, 1);
+ m = NULL;
+ if (wh->can_mount)
+ domount(&c, &m);
- /* our own copy to open or remove */
- c = cunique(c);
+ /* our own copy to open or remove */
+ c = cunique(c);
- /* now it's our copy anyway, we can put the name back */
- cnameclose(c->name);
- c->name = cname;
+ /* now it's our copy anyway, we can put the name back */
+ cnameclose(c->name);
+ c->name = cname;
- switch (amode) {
- case Aremove:
- putmhead(m);
- break;
+ switch (amode) {
+ case Aremove:
+ putmhead(m);
+ break;
- case Aopen:
- case Acreate:
- if (c->umh != NULL) {
- printd("cunique umh\n");
- putmhead(c->umh);
- c->umh = NULL;
- }
-
- /* only save the mount head if it's a multiple element union */
- if (m && m->mount && m->mount->next)
- c->umh = m;
- else
- putmhead(m);
- /* here is where convert omode/vfs flags to c->flags.
- * careful, O_CLOEXEC and O_REMCLO are in there. might need
- * to change that. */
- c->flag |= omode & CEXTERNAL_FLAGS;
- c = devtab[c->type].open(c,
- omode & ~O_CLOEXEC);
- /* if you get this from a dev, in the dev's open, you are
- * probably saving mode directly, without passing it through
- * openmode. */
- if (c->mode & O_TRUNC)
- error(EFAIL, "Device %s open failed to clear O_TRUNC",
- devtab[c->type].name);
- break;
+ case Aopen:
+ case Acreate:
+ if (c->umh != NULL) {
+ printd("cunique umh\n");
+ putmhead(c->umh);
+ c->umh = NULL;
}
- break;
- case Atodir:
- /*
- * Directories (e.g. for cd) are left before the mount point,
- * so one may mount on / or . and see the effect.
- */
- if (!(c->qid.type & QTDIR))
- error(ENOTDIR, ERROR_FIXME);
+ /* only save the mount head if it's a multiple element
+ * union */
+ if (m && m->mount && m->mount->next)
+ c->umh = m;
+ else
+ putmhead(m);
+ /* here is where convert omode/vfs flags to c->flags.
+ * careful, O_CLOEXEC and O_REMCLO are in there. might
+ * need to change that. */
+ c->flag |= omode & CEXTERNAL_FLAGS;
+ c = devtab[c->type].open(c,
+ omode & ~O_CLOEXEC);
+ /* if you get this from a dev, in the dev's open, you
+ * are probably saving mode directly, without passing it
+ * through openmode. */
+ if (c->mode & O_TRUNC)
+ error(EFAIL,
+ "Device %s open failed to clear O_TRUNC",
+ devtab[c->type].name);
break;
+ }
+ break;
- case Amount:
- /*
- * When mounting on an already mounted upon directory,
- * one wants subsequent mounts to be attached to the
- * original directory, not the replacement. Don't domount.
- */
- break;
+ case Atodir:
+ /*
+ * Directories (e.g. for cd) are left before the mount point,
+ * so one may mount on / or . and see the effect.
+ */
+ if (!(c->qid.type & QTDIR))
+ error(ENOTDIR, ERROR_FIXME);
+ break;
- case Arename:
- /* We already walked to the parent of new_path, which is in c.
- * We're a lot like create here - need to find mounts, etc. On the
- * way out, we putmhead if we have an m, and clean up our chans. On
- * success, c becomes cnew (thus close the old c). On failure, we
- * just close cnew. */
- e.ARRAY_SIZEs++;
- m = NULL;
- cnew = NULL;
- if (waserror()) {
- /* rename or createdir failed */
- cclose(cnew);
- if (m)
- putmhead(m);
- nexterror(); /* safe since we're in a waserror() */
- }
- if (wh->can_mount && findmount(&cnew, &m, c->type, c->dev,
- c->qid)) {
+ case Amount:
+ /*
+ * When mounting on an already mounted upon directory,
+ * one wants subsequent mounts to be attached to the
+ * original directory, not the replacement. Don't domount.
+ */
+ break;
+
+ case Arename:
+ /* We already walked to the parent of new_path, which is in c.
+ * We're a lot like create here - need to find mounts, etc. On
+ * the way out, we putmhead if we have an m, and clean up our
+ * chans. On success, c becomes cnew (thus close the old c).
+ * On failure, we just close cnew. */
+ e.ARRAY_SIZEs++;
+ m = NULL;
+ cnew = NULL;
+ if (waserror()) {
+ /* rename or createdir failed */
+ cclose(cnew);
+ if (m)
+ putmhead(m);
+ nexterror(); /* safe since we're in a waserror() */
+ }
+ if (wh->can_mount && findmount(&cnew, &m, c->type, c->dev,
+ c->qid)) {
+ cnew = createdir(cnew, m);
+ } else {
+ cnew = c;
+ chan_incref(cnew);
+ }
+ cnew = cunique(cnew);
+ cnameclose(cnew->name);
+ cnew->name = c->name;
+ kref_get(&cnew->name->ref, 1);
+ /* At this point, we have our new_path parent chan (cnew) and
+ * the renamee chan */
+ renamee = ext;
+ if (cnew->type != renamee->type)
+ error(EXDEV, "can't rename across device types");
+
+ devtab[cnew->type].rename(renamee, cnew,
+ e.elems[e.ARRAY_SIZEs - 1], 0);
+ poperror();
+
+ if (m)
+ putmhead(m);
+ cclose(c);
+ c = cnew;
+ c->name = addelem(c->name, e.elems[e.ARRAY_SIZEs - 1]);
+ break;
+
+ case Acreate:
+ /*
+ * We've already walked all but the last element.
+ * If the last exists, try to open it OTRUNC.
+ * If omode&OEXCL is set, just give up.
+ */
+ e.ARRAY_SIZEs++;
+ if (walk(&c, e.elems + e.ARRAY_SIZEs - 1, 1, wh, NULL) == 0) {
+ if (omode & O_EXCL)
+ error(EEXIST, ERROR_FIXME);
+ omode |= O_TRUNC;
+ goto Open;
+ }
+
+ /*
+ * The semantics of the create(2) system call are that if the
+ * file exists and can be written, it is to be opened with
+ * truncation. On the other hand, the create(5) message fails
+ * if the file exists.
+ *
+ * If we get two create(2) calls happening simultaneously, they
+ * might both get here and send create(5) messages, but only one
+ * of the messages will succeed. To provide the expected
+ * create(2) semantics, the call with the failed message needs
+ * to try the above walk again, opening for truncation. This
+ * correctly solves the create/create race, in the sense that
+ * any observable outcome can be explained as one happening
+ * before the other. The create/create race is quite common.
+ * For example, it happens when two rc subshells simultaneously
+ * update the same environment variable.
+ *
+ * The implementation still admits a create/create/remove race:
+ * (A) walk to file, fails
+ * (B) walk to file, fails
+ * (A) create file, succeeds, returns
+ * (B) create file, fails
+ * (A) remove file, succeeds, returns
+ * (B) walk to file, return failure.
+ *
+ * This is hardly as common as the create/create race, and is
+ * really not too much worse than what might happen if (B) got a
+ * hold of a file descriptor and then the file was removed --
+ * either way (B) can't do anything with the result of the
+ * create call. So we don't care about this race.
+ *
+ * Applications that care about more fine-grained decision of
+ * the races can use the OEXCL flag to get at the underlying
+ * create(5) semantics; by default we provide the common case.
+ *
+ * We need to stay behind the mount point in case we
+ * need to do the first walk again (should the create fail).
+ *
+ * We also need to cross the mount point and find the directory
+ * in the union in which we should be creating.
+ *
+ * The channel staying behind is c, the one moving forward is
+ * cnew.
+ */
+ m = NULL;
+ cnew = NULL; /* is this assignment necessary? */
+ /* discard error */
+ if (!waserror()) { /* try create */
+ if (wh->can_mount &&
+ findmount(&cnew, &m, c->type, c->dev, c->qid))
cnew = createdir(cnew, m);
- } else {
+ else {
cnew = c;
chan_incref(cnew);
}
+
+ /*
+ * We need our own copy of the Chan because we're about
+ * to send a create, which will move it. Once we have
+ * our own copy, we can fix the name, which might be
+ * wrong if findmount gave us a new Chan.
+ */
cnew = cunique(cnew);
cnameclose(cnew->name);
cnew->name = c->name;
kref_get(&cnew->name->ref, 1);
- /* At this point, we have our new_path parent chan (cnew) and the
- * renamee chan */
- renamee = ext;
- if (cnew->type != renamee->type)
- error(EXDEV, "can't rename across device types");
- devtab[cnew->type].rename(renamee, cnew,
- e.elems[e.ARRAY_SIZEs - 1], 0);
+ cnew->flag |= omode & CEXTERNAL_FLAGS;
+ devtab[cnew->type].create(cnew,
+ e.elems[e.ARRAY_SIZEs - 1],
+ omode & ~(O_EXCL | O_CLOEXEC),
+ perm, ext);
poperror();
if (m)
@@ -1302,127 +1425,38 @@
c = cnew;
c->name = addelem(c->name, e.elems[e.ARRAY_SIZEs - 1]);
break;
+ }
- case Acreate:
- /*
- * We've already walked all but the last element.
- * If the last exists, try to open it OTRUNC.
- * If omode&OEXCL is set, just give up.
- */
- e.ARRAY_SIZEs++;
- if (walk(&c, e.elems + e.ARRAY_SIZEs - 1, 1, wh, NULL) == 0) {
- if (omode & O_EXCL)
- error(EEXIST, ERROR_FIXME);
- omode |= O_TRUNC;
- goto Open;
- }
+ /* create failed */
+ cclose(cnew);
+ if (m)
+ putmhead(m);
+ if (omode & O_EXCL)
+ nexterror(); /* safe since we're in a waserror() */
+ poperror(); /* matching the if(!waserror) */
- /*
- * The semantics of the create(2) system call are that if the
- * file exists and can be written, it is to be opened with truncation.
- * On the other hand, the create(5) message fails if the file exists.
- * If we get two create(2) calls happening simultaneously,
- * they might both get here and send create(5) messages, but only
- * one of the messages will succeed. To provide the expected create(2)
- * semantics, the call with the failed message needs to try the above
- * walk again, opening for truncation. This correctly solves the
- * create/create race, in the sense that any observable outcome can
- * be explained as one happening before the other.
- * The create/create race is quite common. For example, it happens
- * when two rc subshells simultaneously update the same
- * environment variable.
- *
- * The implementation still admits a create/create/remove race:
- * (A) walk to file, fails
- * (B) walk to file, fails
- * (A) create file, succeeds, returns
- * (B) create file, fails
- * (A) remove file, succeeds, returns
- * (B) walk to file, return failure.
- *
- * This is hardly as common as the create/create race, and is really
- * not too much worse than what might happen if (B) got a hold of a
- * file descriptor and then the file was removed -- either way (B) can't do
- * anything with the result of the create call. So we don't care about this race.
- *
- * Applications that care about more fine-grained decision of the races
- * can use the OEXCL flag to get at the underlying create(5) semantics;
- * by default we provide the common case.
- *
- * We need to stay behind the mount point in case we
- * need to do the first walk again (should the create fail).
- *
- * We also need to cross the mount point and find the directory
- * in the union in which we should be creating.
- *
- * The channel staying behind is c, the one moving forward is cnew.
- */
- m = NULL;
- cnew = NULL; /* is this assignment necessary? */
- /* discard error */
- if (!waserror()) { /* try create */
- if (wh->can_mount && findmount(&cnew, &m, c->type, c->dev,
- c->qid))
- cnew = createdir(cnew, m);
- else {
- cnew = c;
- chan_incref(cnew);
- }
+ /* save error, so walk doesn't clobber our existing errstr */
+ strlcpy(tmperrbuf, current_errstr(), sizeof(tmperrbuf));
+ saved_errno = get_errno();
+ /* note: we depend that walk does not error */
+ if (walk(&c, e.elems + e.ARRAY_SIZEs - 1, 1, wh, NULL) < 0) {
+ set_errno(saved_errno);
+ /* Report the error we had originally */
+ error(EFAIL, tmperrbuf);
+ }
+ strlcpy(current_errstr(), tmperrbuf, MAX_ERRSTR_LEN);
+ omode |= O_TRUNC;
+ goto Open;
- /*
- * We need our own copy of the Chan because we're
- * about to send a create, which will move it. Once we have
- * our own copy, we can fix the name, which might be wrong
- * if findmount gave us a new Chan.
- */
- cnew = cunique(cnew);
- cnameclose(cnew->name);
- cnew->name = c->name;
- kref_get(&cnew->name->ref, 1);
-
- cnew->flag |= omode & CEXTERNAL_FLAGS;
- devtab[cnew->type].create(cnew, e.elems[e.ARRAY_SIZEs - 1],
- omode & ~(O_EXCL | O_CLOEXEC),
- perm, ext);
- poperror();
-
- if (m)
- putmhead(m);
- cclose(c);
- c = cnew;
- c->name = addelem(c->name, e.elems[e.ARRAY_SIZEs - 1]);
- break;
- }
-
- /* create failed */
- cclose(cnew);
- if (m)
- putmhead(m);
- if (omode & O_EXCL)
- nexterror(); /* safe since we're in a waserror() */
- poperror(); /* matching the if(!waserror) */
-
- /* save error, so walk doesn't clobber our existing errstr */
- strlcpy(tmperrbuf, current_errstr(), sizeof(tmperrbuf));
- saved_errno = get_errno();
- /* note: we depend that walk does not error */
- if (walk(&c, e.elems + e.ARRAY_SIZEs - 1, 1, wh, NULL) < 0) {
- set_errno(saved_errno);
- /* Report the error we had originally */
- error(EFAIL, tmperrbuf);
- }
- strlcpy(current_errstr(), tmperrbuf, MAX_ERRSTR_LEN);
- omode |= O_TRUNC;
- goto Open;
-
- default:
- panic("unknown namec access %d\n", amode);
+ default:
+ panic("unknown namec access %d\n", amode);
}
poperror();
if (e.ARRAY_SIZEs > 0)
- strlcpy(get_cur_genbuf(), e.elems[e.ARRAY_SIZEs - 1], GENBUF_SZ);
+ strlcpy(get_cur_genbuf(), e.elems[e.ARRAY_SIZEs - 1],
+ GENBUF_SZ);
else
strlcpy(get_cur_genbuf(), ".", GENBUF_SZ);
@@ -1449,70 +1483,71 @@
* evaluate starting there.
*/
switch (name[0]) {
- case '/':
- if (current)
- c = current->slash;
- else
- c = kern_slash;
- chan_incref(c);
- break;
+ case '/':
+ if (current)
+ c = current->slash;
+ else
+ c = kern_slash;
+ chan_incref(c);
+ break;
- case '#':
- wh.can_mount = false;
- devname = get_cur_genbuf();
- devname[0] = '\0';
- n = 0;
- name++; /* drop the # */
- while ((*name != '\0') && (*name != '/')) {
- if (n >= GENBUF_SZ - 1)
- error(ENAMETOOLONG, ERROR_FIXME);
- devname[n++] = *name++;
- }
- devname[n] = '\0';
- /* for a name #foo.spec, devname = foo\0, devspec = spec\0.
- * genbuf contains foo\0spec\0. for no spec, devspec = \0 */
- devspec = strchr(devname, '.');
- if (devspec) {
- *devspec = '\0';
- devspec++;
- } else {
- devspec = &devname[n];
- }
- /* These devices have special attach functions that treat the char *
- * as a blob pointer */
- if (!strcmp(devname, "mnt"))
- error(EINVAL, "can't namec-attach #mnt");
- if (!strcmp(devname, "gtfs"))
- error(EINVAL, "can't namec-attach #gtfs");
- /* TODO: deal with this "nodevs" business. */
- #if 0
- /*
- * the nodevs exceptions are
- * | it only gives access to pipes you create
- * e this process's environment
- * s private file2chan creation space
- * D private secure sockets name space
- * a private TLS name space
- */
- if (current->pgrp->nodevs &&
- // (utfrune("|esDa", r) == NULL
- ((strchr("|esDa", get_cur_genbuf()[1]) == NULL)
- || (get_cur_genbuf()[1] == 's' // || r == 's'
- && get_cur_genbuf()[n] != '\0')))
- error(EINVAL, ERROR_FIXME);
- #endif
- devtype = devno(devname, 1);
- if (devtype == -1)
- error(EFAIL, "Unknown #device %s (spec %s)", devname, devspec);
- c = devtab[devtype].attach(devspec);
- break;
- default:
- /* this case also covers \0 */
- c = current->dot;
- if (!c)
- panic("no dot!");
- chan_incref(c);
- break;
+ case '#':
+ wh.can_mount = false;
+ devname = get_cur_genbuf();
+ devname[0] = '\0';
+ n = 0;
+ name++; /* drop the # */
+ while ((*name != '\0') && (*name != '/')) {
+ if (n >= GENBUF_SZ - 1)
+ error(ENAMETOOLONG, ERROR_FIXME);
+ devname[n++] = *name++;
+ }
+ devname[n] = '\0';
+ /* for a name #foo.spec, devname = foo\0, devspec = spec\0.
+ * genbuf contains foo\0spec\0. for no spec, devspec = \0 */
+ devspec = strchr(devname, '.');
+ if (devspec) {
+ *devspec = '\0';
+ devspec++;
+ } else {
+ devspec = &devname[n];
+ }
+ /* These devices have special attach functions that treat the
+ * char * as a blob pointer */
+ if (!strcmp(devname, "mnt"))
+ error(EINVAL, "can't namec-attach #mnt");
+ if (!strcmp(devname, "gtfs"))
+ error(EINVAL, "can't namec-attach #gtfs");
+ /* TODO: deal with this "nodevs" business. */
+ #if 0
+ /*
+ * the nodevs exceptions are
+ * | it only gives access to pipes you create
+ * e this process's environment
+ * s private file2chan creation space
+ * D private secure sockets name space
+ * a private TLS name space
+ */
+ if (current->pgrp->nodevs &&
+ // (utfrune("|esDa", r) == NULL
+ ((strchr("|esDa", get_cur_genbuf()[1]) == NULL)
+ || (get_cur_genbuf()[1] == 's' // || r == 's'
+ && get_cur_genbuf()[n] != '\0')))
+ error(EINVAL, ERROR_FIXME);
+ #endif
+ devtype = devno(devname, 1);
+ if (devtype == -1)
+ error(EFAIL, "Unknown #device %s (spec %s)", devname,
+ devspec);
+ c = devtab[devtype].attach(devspec);
+ break;
+ default:
+ /* this case also covers \0 */
+ c = current->dot;
+ if (!c)
+ panic("no dot!");
+ chan_incref(c);
+ break;
}
return __namec_from(c, name, amode, omode, perm, &wh, ext);
}
@@ -1584,7 +1619,8 @@
} else {
if (isfrog[c])
if (!slashok || c != '/') {
- error(EINVAL, "%s (%p), at char %c", aname, aname, c);
+ error(EINVAL, "%s (%p), at char %c",
+ aname, aname, c);
}
name++;
}
diff --git a/kern/src/ns/cleanname.c b/kern/src/ns/cleanname.c
index c12b941..465405e 100644
--- a/kern/src/ns/cleanname.c
+++ b/kern/src/ns/cleanname.c
@@ -64,7 +64,8 @@
else if (p[0] == '.' && SEP(p[1])) {
if (p == name)
erasedprefix = 1;
- p += 1; /* don't count the separator in case it is nul */
+ /* don't count the separator in case it is nul */
+ p += 1;
} else if (p[0] == '.' && p[1] == '.' && SEP(p[2])) {
p += 2;
if (q > dotdot) { /* can backtrack */
@@ -76,8 +77,9 @@
*q++ = '.';
dotdot = q;
}
+ /* erased entire path via dotdot */
if (q == name)
- erasedprefix = 1; /* erased entire path via dotdot */
+ erasedprefix = 1;
} else { /* real path element */
if (q != name + rooted)
*q++ = '/';
@@ -89,7 +91,8 @@
*q++ = '.';
*q = '\0';
if (erasedprefix && name[0] == '#') {
- /* this was not a #x device path originally - make it not one now */
+ /* this was not a #x device path originally - make it not one
+ * now */
memmove(name + 2, name, strlen(name) + 1);
name[0] = '.';
name[1] = '/';
diff --git a/kern/src/ns/convM2D.c b/kern/src/ns/convM2D.c
index 0024aab..9c4c3de 100644
--- a/kern/src/ns/convM2D.c
+++ b/kern/src/ns/convM2D.c
@@ -66,7 +66,8 @@
buf += BIT16SZ + GBIT16(buf);
}
/* Legacy 9p stats are OK
- * TODO: consider removing this. We get them from userspace, e.g. mkdir. */
+ * TODO: consider removing this. We get them from userspace, e.g.
+ * mkdir. */
if (buf == ebuf)
return;
@@ -99,9 +100,9 @@
if (nbuf < STAT_FIX_LEN_9P)
return 0;
- /* This M might not have all the fields we expect. We'll ensure the strings
- * have the right values later. We still need to initialize all of the
- * non-string extended fields. */
+ /* This M might not have all the fields we expect. We'll ensure the
+ * strings have the right values later. We still need to initialize all
+ * of the non-string extended fields. */
init_empty_dir(d);
p = buf;
@@ -129,9 +130,10 @@
if ((int32_t)d->mtime.tv_sec == -1)
d->mtime.tv_sec = ~0;
- /* Anything beyond the legacy 9p strings might not be supported. Though if
- * you have more, you probably have at least EVH's 9p2000.u extensions.
- * Once we get all of the legacy strings, we have a good stat. */
+ /* Anything beyond the legacy 9p strings might not be supported. Though
+ * if you have more, you probably have at least EVH's 9p2000.u
+ * extensions. Once we get all of the legacy strings, we have a good
+ * stat. */
for (i = 0; i < STAT_NR_STRINGS_AK; i++) {
if (i == STAT_NR_STRINGS_9P)
good_stat = true;
diff --git a/kern/src/ns/convM2S.c b/kern/src/ns/convM2S.c
index c0f9491..c02faa0 100644
--- a/kern/src/ns/convM2S.c
+++ b/kern/src/ns/convM2S.c
@@ -38,8 +38,7 @@
#include <smp.h>
#include <net/ip.h>
-static
-uint8_t *gstring(uint8_t * p, uint8_t * ep, char **s)
+static uint8_t *gstring(uint8_t *p, uint8_t *ep, char **s)
{
unsigned int n;
@@ -57,8 +56,7 @@
return p;
}
-static
-uint8_t *gqid(uint8_t * p, uint8_t * ep, struct qid *q)
+static uint8_t *gqid(uint8_t *p, uint8_t *ep, struct qid *q)
{
if (p + QIDSZ > ep)
return NULL;
@@ -94,8 +92,8 @@
d->btime.tv_sec = ~0;
d->ctime.tv_sec = ~0;
d->mtime.tv_sec = ~0;
- /* We don't look at tv_nsec to determine whether or not the field is "don't
- * touch". This way, all nsecs are normal. */
+ /* We don't look at tv_nsec to determine whether or not the field is
+ * "don't touch". This way, all nsecs are normal. */
d->atime.tv_nsec = 0;
d->btime.tv_nsec = 0;
d->ctime.tv_nsec = 0;
@@ -112,7 +110,7 @@
* main switch statement checks range and also can fall through
* to test at end of routine.
*/
-unsigned int convM2S(uint8_t * ap, unsigned int nap, struct fcall *f)
+unsigned int convM2S(uint8_t *ap, unsigned int nap, struct fcall *f)
{
uint8_t *p, *ep;
unsigned int i, size;
@@ -134,240 +132,240 @@
p += BIT16SZ;
switch (f->type) {
- default:
+ default:
+ return 0;
+
+ case Tversion:
+ if (p + BIT32SZ > ep)
return 0;
+ f->msize = GBIT32(p);
+ p += BIT32SZ;
+ p = gstring(p, ep, &f->version);
+ break;
- case Tversion:
- if (p + BIT32SZ > ep)
- return 0;
- f->msize = GBIT32(p);
- p += BIT32SZ;
- p = gstring(p, ep, &f->version);
+ case Tflush:
+ if (p + BIT16SZ > ep)
+ return 0;
+ f->oldtag = GBIT16(p);
+ p += BIT16SZ;
+ break;
+
+ case Tauth:
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->afid = GBIT32(p);
+ p += BIT32SZ;
+ p = gstring(p, ep, &f->uname);
+ if (p == NULL)
break;
-
- case Tflush:
- if (p + BIT16SZ > ep)
- return 0;
- f->oldtag = GBIT16(p);
- p += BIT16SZ;
+ p = gstring(p, ep, &f->aname);
+ if (p == NULL)
break;
+ break;
- case Tauth:
- if (p + BIT32SZ > ep)
- return 0;
- f->afid = GBIT32(p);
- p += BIT32SZ;
- p = gstring(p, ep, &f->uname);
+ case Tattach:
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->afid = GBIT32(p);
+ p += BIT32SZ;
+ p = gstring(p, ep, &f->uname);
+ if (p == NULL)
+ break;
+ p = gstring(p, ep, &f->aname);
+ if (p == NULL)
+ break;
+ break;
+
+ case Twalk:
+ if (p + BIT32SZ + BIT32SZ + BIT16SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ f->newfid = GBIT32(p);
+ p += BIT32SZ;
+ f->nwname = GBIT16(p);
+ p += BIT16SZ;
+ if (f->nwname > MAXWELEM)
+ return 0;
+ for (i = 0; i < f->nwname; i++) {
+ p = gstring(p, ep, &f->wname[i]);
if (p == NULL)
break;
- p = gstring(p, ep, &f->aname);
- if (p == NULL)
- break;
- break;
+ }
+ break;
- case Tattach:
- if (p + BIT32SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- if (p + BIT32SZ > ep)
- return 0;
- f->afid = GBIT32(p);
- p += BIT32SZ;
- p = gstring(p, ep, &f->uname);
- if (p == NULL)
- break;
- p = gstring(p, ep, &f->aname);
- if (p == NULL)
- break;
- break;
+ case Topen:
+ if (p + BIT32SZ + BIT8SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ f->mode = GBIT8(p);
+ p += BIT8SZ;
+ break;
- case Twalk:
- if (p + BIT32SZ + BIT32SZ + BIT16SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- f->newfid = GBIT32(p);
- p += BIT32SZ;
- f->nwname = GBIT16(p);
- p += BIT16SZ;
- if (f->nwname > MAXWELEM)
- return 0;
- for (i = 0; i < f->nwname; i++) {
- p = gstring(p, ep, &f->wname[i]);
- if (p == NULL)
- break;
- }
+ case Tcreate:
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ p = gstring(p, ep, &f->name);
+ if (p == NULL)
break;
+ if (p + BIT32SZ + BIT8SZ > ep)
+ return 0;
+ f->perm = GBIT32(p);
+ p += BIT32SZ;
+ f->mode = GBIT8(p);
+ p += BIT8SZ;
+ break;
- case Topen:
- if (p + BIT32SZ + BIT8SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- f->mode = GBIT8(p);
- p += BIT8SZ;
- break;
+ case Tread:
+ if (p + BIT32SZ + BIT64SZ + BIT32SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ f->offset = GBIT64(p);
+ p += BIT64SZ;
+ f->count = GBIT32(p);
+ p += BIT32SZ;
+ break;
- case Tcreate:
- if (p + BIT32SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- p = gstring(p, ep, &f->name);
- if (p == NULL)
- break;
- if (p + BIT32SZ + BIT8SZ > ep)
- return 0;
- f->perm = GBIT32(p);
- p += BIT32SZ;
- f->mode = GBIT8(p);
- p += BIT8SZ;
- break;
+ case Twrite:
+ if (p + BIT32SZ + BIT64SZ + BIT32SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ f->offset = GBIT64(p);
+ p += BIT64SZ;
+ f->count = GBIT32(p);
+ p += BIT32SZ;
+ if (p + f->count > ep)
+ return 0;
+ f->data = (char *)p;
+ p += f->count;
+ break;
- case Tread:
- if (p + BIT32SZ + BIT64SZ + BIT32SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- f->offset = GBIT64(p);
- p += BIT64SZ;
- f->count = GBIT32(p);
- p += BIT32SZ;
- break;
+ case Tclunk:
+ case Tremove:
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ break;
- case Twrite:
- if (p + BIT32SZ + BIT64SZ + BIT32SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- f->offset = GBIT64(p);
- p += BIT64SZ;
- f->count = GBIT32(p);
- p += BIT32SZ;
- if (p + f->count > ep)
- return 0;
- f->data = (char *)p;
- p += f->count;
- break;
+ case Tstat:
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ break;
- case Tclunk:
- case Tremove:
- if (p + BIT32SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- break;
-
- case Tstat:
- if (p + BIT32SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- break;
-
- case Twstat:
- if (p + BIT32SZ + BIT16SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- f->nstat = GBIT16(p);
- p += BIT16SZ;
- if (p + f->nstat > ep)
- return 0;
- f->stat = p;
- p += f->nstat;
- break;
+ case Twstat:
+ if (p + BIT32SZ + BIT16SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ f->nstat = GBIT16(p);
+ p += BIT16SZ;
+ if (p + f->nstat > ep)
+ return 0;
+ f->stat = p;
+ p += f->nstat;
+ break;
/*
*/
- case Rversion:
- if (p + BIT32SZ > ep)
- return 0;
- f->msize = GBIT32(p);
- p += BIT32SZ;
- p = gstring(p, ep, &f->version);
- break;
+ case Rversion:
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->msize = GBIT32(p);
+ p += BIT32SZ;
+ p = gstring(p, ep, &f->version);
+ break;
- case Rerror:
- p = gstring(p, ep, &f->ename);
- break;
+ case Rerror:
+ p = gstring(p, ep, &f->ename);
+ break;
- case Rflush:
- break;
+ case Rflush:
+ break;
- case Rauth:
- p = gqid(p, ep, &f->aqid);
+ case Rauth:
+ p = gqid(p, ep, &f->aqid);
+ if (p == NULL)
+ break;
+ break;
+
+ case Rattach:
+ p = gqid(p, ep, &f->qid);
+ if (p == NULL)
+ break;
+ break;
+
+ case Rwalk:
+ if (p + BIT16SZ > ep)
+ return 0;
+ f->nwqid = GBIT16(p);
+ p += BIT16SZ;
+ if (f->nwqid > MAXWELEM)
+ return 0;
+ for (i = 0; i < f->nwqid; i++) {
+ p = gqid(p, ep, &f->wqid[i]);
if (p == NULL)
break;
- break;
+ }
+ break;
- case Rattach:
- p = gqid(p, ep, &f->qid);
- if (p == NULL)
- break;
+ case Ropen:
+ case Rcreate:
+ p = gqid(p, ep, &f->qid);
+ if (p == NULL)
break;
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->iounit = GBIT32(p);
+ p += BIT32SZ;
+ break;
- case Rwalk:
- if (p + BIT16SZ > ep)
- return 0;
- f->nwqid = GBIT16(p);
- p += BIT16SZ;
- if (f->nwqid > MAXWELEM)
- return 0;
- for (i = 0; i < f->nwqid; i++) {
- p = gqid(p, ep, &f->wqid[i]);
- if (p == NULL)
- break;
- }
- break;
+ case Rread:
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->count = GBIT32(p);
+ p += BIT32SZ;
+ if (p + f->count > ep)
+ return 0;
+ f->data = (char *)p;
+ p += f->count;
+ break;
- case Ropen:
- case Rcreate:
- p = gqid(p, ep, &f->qid);
- if (p == NULL)
- break;
- if (p + BIT32SZ > ep)
- return 0;
- f->iounit = GBIT32(p);
- p += BIT32SZ;
- break;
+ case Rwrite:
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->count = GBIT32(p);
+ p += BIT32SZ;
+ break;
- case Rread:
- if (p + BIT32SZ > ep)
- return 0;
- f->count = GBIT32(p);
- p += BIT32SZ;
- if (p + f->count > ep)
- return 0;
- f->data = (char *)p;
- p += f->count;
- break;
+ case Rclunk:
+ case Rremove:
+ break;
- case Rwrite:
- if (p + BIT32SZ > ep)
- return 0;
- f->count = GBIT32(p);
- p += BIT32SZ;
- break;
+ case Rstat:
+ if (p + BIT16SZ > ep)
+ return 0;
+ f->nstat = GBIT16(p);
+ p += BIT16SZ;
+ if (p + f->nstat > ep)
+ return 0;
+ f->stat = p;
+ p += f->nstat;
+ break;
- case Rclunk:
- case Rremove:
- break;
-
- case Rstat:
- if (p + BIT16SZ > ep)
- return 0;
- f->nstat = GBIT16(p);
- p += BIT16SZ;
- if (p + f->nstat > ep)
- return 0;
- f->stat = p;
- p += f->nstat;
- break;
-
- case Rwstat:
- break;
+ case Rwstat:
+ break;
}
if (p == NULL || p > ep)
diff --git a/kern/src/ns/convM2kdirent.c b/kern/src/ns/convM2kdirent.c
index 321afb0..4345e70 100644
--- a/kern/src/ns/convM2kdirent.c
+++ b/kern/src/ns/convM2kdirent.c
@@ -17,8 +17,8 @@
#include <net/ip.h>
/* Special akaros edition. */
-unsigned int convM2kdirent(uint8_t * buf, unsigned int nbuf, struct kdirent *kd,
- char *strs)
+unsigned int convM2kdirent(uint8_t *buf, unsigned int nbuf, struct kdirent *kd,
+ char *strs)
{
struct dir *dir;
size_t conv_sz, name_sz;
@@ -29,8 +29,8 @@
conv_sz = convM2D(buf, nbuf, dir, (char*)&dir[1]);
kd->d_ino = dir->qid.path;
- kd->d_off = 0; /* ignored for 9ns readdir */
- kd->d_type = 0; /* TODO: might need this; never used this in the VFS */
+ kd->d_off = 0; /* ignored for 9ns readdir */
+ kd->d_type = 0; /* TODO: might need this; never used this in the VFS */
name_sz = dir->name ? strlen(dir->name) : 0;
kd->d_reclen = name_sz;
/* Our caller should have made sure kd was big enough... */
diff --git a/kern/src/ns/convS2M.c b/kern/src/ns/convS2M.c
index b70cb0f..287fc60 100644
--- a/kern/src/ns/convS2M.c
+++ b/kern/src/ns/convS2M.c
@@ -38,8 +38,7 @@
#include <smp.h>
#include <net/ip.h>
-static
-uint8_t *pstring(uint8_t * p, char *s)
+static uint8_t *pstring(uint8_t *p, char *s)
{
unsigned int n;
@@ -57,8 +56,7 @@
return p;
}
-static
-uint8_t *pqid(uint8_t * p, struct qid *q)
+static uint8_t *pqid(uint8_t *p, struct qid *q)
{
PBIT8(p, q->type);
p += BIT8SZ;
@@ -69,8 +67,7 @@
return p;
}
-static
-unsigned int stringsz(char *s)
+static unsigned int stringsz(char *s)
{
if (s == NULL)
return BIT16SZ;
@@ -89,134 +86,134 @@
n += BIT16SZ; /* tag */
switch (f->type) {
- default:
- return 0;
+ default:
+ return 0;
- case Tversion:
- n += BIT32SZ;
- n += stringsz(f->version);
- break;
+ case Tversion:
+ n += BIT32SZ;
+ n += stringsz(f->version);
+ break;
- case Tflush:
- n += BIT16SZ;
- break;
+ case Tflush:
+ n += BIT16SZ;
+ break;
- case Tauth:
- n += BIT32SZ;
- n += stringsz(f->uname);
- n += stringsz(f->aname);
- break;
+ case Tauth:
+ n += BIT32SZ;
+ n += stringsz(f->uname);
+ n += stringsz(f->aname);
+ break;
- case Tattach:
- n += BIT32SZ;
- n += BIT32SZ;
- n += stringsz(f->uname);
- n += stringsz(f->aname);
- break;
+ case Tattach:
+ n += BIT32SZ;
+ n += BIT32SZ;
+ n += stringsz(f->uname);
+ n += stringsz(f->aname);
+ break;
- case Twalk:
- n += BIT32SZ;
- n += BIT32SZ;
- n += BIT16SZ;
- for (i = 0; i < f->nwname; i++)
- n += stringsz(f->wname[i]);
- break;
+ case Twalk:
+ n += BIT32SZ;
+ n += BIT32SZ;
+ n += BIT16SZ;
+ for (i = 0; i < f->nwname; i++)
+ n += stringsz(f->wname[i]);
+ break;
- case Topen:
- n += BIT32SZ;
- n += BIT8SZ;
- break;
+ case Topen:
+ n += BIT32SZ;
+ n += BIT8SZ;
+ break;
- case Tcreate:
- n += BIT32SZ;
- n += stringsz(f->name);
- n += BIT32SZ;
- n += BIT8SZ;
- break;
+ case Tcreate:
+ n += BIT32SZ;
+ n += stringsz(f->name);
+ n += BIT32SZ;
+ n += BIT8SZ;
+ break;
- case Tread:
- n += BIT32SZ;
- n += BIT64SZ;
- n += BIT32SZ;
- break;
+ case Tread:
+ n += BIT32SZ;
+ n += BIT64SZ;
+ n += BIT32SZ;
+ break;
- case Twrite:
- n += BIT32SZ;
- n += BIT64SZ;
- n += BIT32SZ;
- n += f->count;
- break;
+ case Twrite:
+ n += BIT32SZ;
+ n += BIT64SZ;
+ n += BIT32SZ;
+ n += f->count;
+ break;
- case Tclunk:
- case Tremove:
- n += BIT32SZ;
- break;
+ case Tclunk:
+ case Tremove:
+ n += BIT32SZ;
+ break;
- case Tstat:
- n += BIT32SZ;
- break;
+ case Tstat:
+ n += BIT32SZ;
+ break;
- case Twstat:
- n += BIT32SZ;
- n += BIT16SZ;
- n += f->nstat;
- break;
-/*
- */
+ case Twstat:
+ n += BIT32SZ;
+ n += BIT16SZ;
+ n += f->nstat;
+ break;
- case Rversion:
- n += BIT32SZ;
- n += stringsz(f->version);
- break;
- case Rerror:
- n += stringsz(f->ename);
- break;
- case Rflush:
- break;
+ case Rversion:
+ n += BIT32SZ;
+ n += stringsz(f->version);
+ break;
- case Rauth:
- n += QIDSZ;
- break;
+ case Rerror:
+ n += stringsz(f->ename);
+ break;
- case Rattach:
- n += QIDSZ;
- break;
+ case Rflush:
+ break;
- case Rwalk:
- n += BIT16SZ;
- n += f->nwqid * QIDSZ;
- break;
+ case Rauth:
+ n += QIDSZ;
+ break;
- case Ropen:
- case Rcreate:
- n += QIDSZ;
- n += BIT32SZ;
- break;
+ case Rattach:
+ n += QIDSZ;
+ break;
- case Rread:
- n += BIT32SZ;
- n += f->count;
- break;
+ case Rwalk:
+ n += BIT16SZ;
+ n += f->nwqid * QIDSZ;
+ break;
- case Rwrite:
- n += BIT32SZ;
- break;
+ case Ropen:
+ case Rcreate:
+ n += QIDSZ;
+ n += BIT32SZ;
+ break;
- case Rclunk:
- break;
+ case Rread:
+ n += BIT32SZ;
+ n += f->count;
+ break;
- case Rremove:
- break;
+ case Rwrite:
+ n += BIT32SZ;
+ break;
- case Rstat:
- n += BIT16SZ;
- n += f->nstat;
- break;
+ case Rclunk:
+ break;
- case Rwstat:
- break;
+ case Rremove:
+ break;
+
+ case Rstat:
+ n += BIT16SZ;
+ n += f->nstat;
+ break;
+
+ case Rwstat:
+ break;
}
return n;
}
@@ -242,172 +239,172 @@
p += BIT16SZ;
switch (f->type) {
- default:
+ default:
+ return 0;
+
+ case Tversion:
+ PBIT32(p, f->msize);
+ p += BIT32SZ;
+ p = pstring(p, f->version);
+ break;
+
+ case Tflush:
+ PBIT16(p, f->oldtag);
+ p += BIT16SZ;
+ break;
+
+ case Tauth:
+ PBIT32(p, f->afid);
+ p += BIT32SZ;
+ p = pstring(p, f->uname);
+ p = pstring(p, f->aname);
+ break;
+
+ case Tattach:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ PBIT32(p, f->afid);
+ p += BIT32SZ;
+ p = pstring(p, f->uname);
+ p = pstring(p, f->aname);
+ break;
+
+ case Twalk:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ PBIT32(p, f->newfid);
+ p += BIT32SZ;
+ PBIT16(p, f->nwname);
+ p += BIT16SZ;
+ if (f->nwname > MAXWELEM)
return 0;
+ for (i = 0; i < f->nwname; i++)
+ p = pstring(p, f->wname[i]);
+ break;
- case Tversion:
- PBIT32(p, f->msize);
- p += BIT32SZ;
- p = pstring(p, f->version);
- break;
+ case Topen:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ PBIT8(p, f->mode);
+ p += BIT8SZ;
+ break;
- case Tflush:
- PBIT16(p, f->oldtag);
- p += BIT16SZ;
- break;
+ case Tcreate:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ p = pstring(p, f->name);
+ PBIT32(p, f->perm);
+ p += BIT32SZ;
+ PBIT8(p, f->mode);
+ p += BIT8SZ;
+ break;
- case Tauth:
- PBIT32(p, f->afid);
- p += BIT32SZ;
- p = pstring(p, f->uname);
- p = pstring(p, f->aname);
- break;
+ case Tread:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ PBIT64(p, f->offset);
+ p += BIT64SZ;
+ PBIT32(p, f->count);
+ p += BIT32SZ;
+ break;
- case Tattach:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- PBIT32(p, f->afid);
- p += BIT32SZ;
- p = pstring(p, f->uname);
- p = pstring(p, f->aname);
- break;
+ case Twrite:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ PBIT64(p, f->offset);
+ p += BIT64SZ;
+ PBIT32(p, f->count);
+ p += BIT32SZ;
+ memmove(p, f->data, f->count);
+ p += f->count;
+ break;
- case Twalk:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- PBIT32(p, f->newfid);
- p += BIT32SZ;
- PBIT16(p, f->nwname);
- p += BIT16SZ;
- if (f->nwname > MAXWELEM)
- return 0;
- for (i = 0; i < f->nwname; i++)
- p = pstring(p, f->wname[i]);
- break;
+ case Tclunk:
+ case Tremove:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ break;
- case Topen:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- PBIT8(p, f->mode);
- p += BIT8SZ;
- break;
+ case Tstat:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ break;
- case Tcreate:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- p = pstring(p, f->name);
- PBIT32(p, f->perm);
- p += BIT32SZ;
- PBIT8(p, f->mode);
- p += BIT8SZ;
- break;
+ case Twstat:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ PBIT16(p, f->nstat);
+ p += BIT16SZ;
+ memmove(p, f->stat, f->nstat);
+ p += f->nstat;
+ break;
- case Tread:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- PBIT64(p, f->offset);
- p += BIT64SZ;
- PBIT32(p, f->count);
- p += BIT32SZ;
- break;
- case Twrite:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- PBIT64(p, f->offset);
- p += BIT64SZ;
- PBIT32(p, f->count);
- p += BIT32SZ;
- memmove(p, f->data, f->count);
- p += f->count;
- break;
- case Tclunk:
- case Tremove:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- break;
+ case Rversion:
+ PBIT32(p, f->msize);
+ p += BIT32SZ;
+ p = pstring(p, f->version);
+ break;
- case Tstat:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- break;
+ case Rerror:
+ p = pstring(p, f->ename);
+ break;
- case Twstat:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- PBIT16(p, f->nstat);
- p += BIT16SZ;
- memmove(p, f->stat, f->nstat);
- p += f->nstat;
- break;
-/*
- */
+ case Rflush:
+ break;
- case Rversion:
- PBIT32(p, f->msize);
- p += BIT32SZ;
- p = pstring(p, f->version);
- break;
+ case Rauth:
+ p = pqid(p, &f->aqid);
+ break;
- case Rerror:
- p = pstring(p, f->ename);
- break;
+ case Rattach:
+ p = pqid(p, &f->qid);
+ break;
- case Rflush:
- break;
+ case Rwalk:
+ PBIT16(p, f->nwqid);
+ p += BIT16SZ;
+ if (f->nwqid > MAXWELEM)
+ return 0;
+ for (i = 0; i < f->nwqid; i++)
+ p = pqid(p, &f->wqid[i]);
+ break;
- case Rauth:
- p = pqid(p, &f->aqid);
- break;
+ case Ropen:
+ case Rcreate:
+ p = pqid(p, &f->qid);
+ PBIT32(p, f->iounit);
+ p += BIT32SZ;
+ break;
- case Rattach:
- p = pqid(p, &f->qid);
- break;
+ case Rread:
+ PBIT32(p, f->count);
+ p += BIT32SZ;
+ memmove(p, f->data, f->count);
+ p += f->count;
+ break;
- case Rwalk:
- PBIT16(p, f->nwqid);
- p += BIT16SZ;
- if (f->nwqid > MAXWELEM)
- return 0;
- for (i = 0; i < f->nwqid; i++)
- p = pqid(p, &f->wqid[i]);
- break;
+ case Rwrite:
+ PBIT32(p, f->count);
+ p += BIT32SZ;
+ break;
- case Ropen:
- case Rcreate:
- p = pqid(p, &f->qid);
- PBIT32(p, f->iounit);
- p += BIT32SZ;
- break;
+ case Rclunk:
+ break;
- case Rread:
- PBIT32(p, f->count);
- p += BIT32SZ;
- memmove(p, f->data, f->count);
- p += f->count;
- break;
+ case Rremove:
+ break;
- case Rwrite:
- PBIT32(p, f->count);
- p += BIT32SZ;
- break;
+ case Rstat:
+ PBIT16(p, f->nstat);
+ p += BIT16SZ;
+ memmove(p, f->stat, f->nstat);
+ p += f->nstat;
+ break;
- case Rclunk:
- break;
-
- case Rremove:
- break;
-
- case Rstat:
- PBIT16(p, f->nstat);
- p += BIT16SZ;
- memmove(p, f->stat, f->nstat);
- p += f->nstat;
- break;
-
- case Rwstat:
- break;
+ case Rwstat:
+ break;
}
if (size != p - ap)
return 0;
diff --git a/kern/src/ns/dev.c b/kern/src/ns/dev.c
index f041e67..2795df2 100644
--- a/kern/src/ns/dev.c
+++ b/kern/src/ns/dev.c
@@ -81,8 +81,8 @@
db->gid = eve.name;
db->muid = user;
db->ext = NULL;
- /* TODO: once we figure out what to do for uid/gid, then we can try to tie
- * that to the n_uid. Or just ignore it, and only use that as a
+ /* TODO: once we figure out what to do for uid/gid, then we can try to
+ * tie that to the n_uid. Or just ignore it, and only use that as a
* pass-through for 9p2000.u. */
db->n_uid = 0;
db->n_gid = 0;
@@ -115,14 +115,13 @@
*
* The comment about genning a file's siblings needs a grain of salt too. Look
* through ipgen(). I think it's what I call "direct genning." */
-int
-devgen(struct chan *c, char *unused_name, struct dirtab *tab, int ntab,
- int i, struct dir *dp)
+int devgen(struct chan *c, char *unused_name, struct dirtab *tab, int ntab,
+ int i, struct dir *dp)
{
if (tab == NULL)
return -1;
if (i != DEVDOTDOT) {
- /* Skip over the first element, that for the directory itself. */
+ /* Skip over the first element, that for the directory itself */
i++;
if (i < 0 || ntab <= i)
return -1;
@@ -170,21 +169,22 @@
{
struct chan *nc;
- /* In plan 9, you couldn't clone an open chan. We're allowing it, possibly
- * foolishly. The new chan is a non-open, "kernel internal" chan. Note
- * that c->flag isn't set, for instance. c->mode is, which might be a
- * problem. The newchan should eventually have a device's open called on
- * it, at which point it upgrades from a kernel internal chan to one that
- * can refer to an object in the device (e.g. grab a refcnt on a
- * conversation in #ip).
+ /* In plan 9, you couldn't clone an open chan. We're allowing it,
+ * possibly foolishly. The new chan is a non-open, "kernel internal"
+ * chan. Note that c->flag isn't set, for instance. c->mode is, which
+ * might be a problem. The newchan should eventually have a device's
+ * open called on it, at which point it upgrades from a kernel internal
+ * chan to one that can refer to an object in the device (e.g. grab a
+ * refcnt on a conversation in #ip).
*
- * Either we allow devclones of open chans, or O_PATH walks do not open a
- * file. It's nice to allow the device to do something for O_PATH, but
- * perhaps that is not critical. However, if we can't clone an opened chan,
- * then we can *only* openat from an FD that is O_PATH, which is not the
- * spec (and not as useful). */
+ * Either we allow devclones of open chans, or O_PATH walks do not open
+ * a file. It's nice to allow the device to do something for O_PATH,
+ * but perhaps that is not critical. However, if we can't clone an
+ * opened chan, then we can *only* openat from an FD that is O_PATH,
+ * which is not the spec (and not as useful). */
if ((c->flag & COPEN) && !(c->flag & O_PATH))
- panic("clone of non-O_PATH open file type %s\n", devtab[c->type].name);
+ panic("clone of non-O_PATH open file type %s\n",
+ devtab[c->type].name);
nc = newchan();
nc->type = c->type;
@@ -200,13 +200,12 @@
return nc;
}
-struct walkqid *devwalk(struct chan *c,
- struct chan *nc, char **name, int nname,
- struct dirtab *tab, int ntab, Devgen * gen)
+struct walkqid *devwalk(struct chan *c, struct chan *nc, char **name, int nname,
+ struct dirtab *tab, int ntab, Devgen * gen)
{
ERRSTACK(1);
int i, j;
- volatile int alloc; /* to keep waserror from optimizing this out */
+ volatile int alloc; /* to keep waserror from optimizing this out */
struct walkqid *wq;
char *n;
struct dir dir;
@@ -226,8 +225,8 @@
}
if (nc == NULL) {
nc = devclone(c);
- /* inferno was setting this to 0, assuming it was devroot. lining up
- * with chanrelease and newchan */
+ /* inferno was setting this to 0, assuming it was devroot.
+ * lining up with chanrelease and newchan */
nc->type = -1; /* device doesn't know about this channel yet */
alloc = 1;
}
@@ -264,27 +263,28 @@
dir.qid.path = 0;
for (i = 0;; i++) {
switch ((*gen) (nc, n, tab, ntab, i, &dir)) {
- case -1:
- printd("DEVWALK -1, i was %d, want path %p\n", i,
- c->qid.path);
+ case -1:
+ printd("DEVWALK -1, i was %d, want path %p\n",
+ i, c->qid.path);
Notfound:
- set_error(ENOENT, "could not find name %s, dev %s", n,
- c->type == -1 ? "no dev" : devtab[c->type].name);
- if (j == 0)
- error_jmp();
- goto Done;
- case 0:
- printd("DEVWALK continue, i was %d\n", i);
- continue;
- case 1:
- printd
- ("DEVWALK gen returns path %p name %s, want path %p\n",
- dir.qid.path, dir.name, c->qid.path);
- if (strcmp(n, dir.name) == 0) {
- nc->qid = dir.qid;
- goto Accept;
- }
- continue;
+ set_error(ENOENT,
+ "could not find name %s, dev %s", n,
+ c->type == -1 ? "no dev" :
+ devtab[c->type].name);
+ if (j == 0)
+ error_jmp();
+ goto Done;
+ case 0:
+ printd("DEVWALK continue, i was %d\n", i);
+ continue;
+ case 1:
+ printd("DEVWALK gen returns path %p name %s, want path %p\n",
+ dir.qid.path, dir.name, c->qid.path);
+ if (strcmp(n, dir.name) == 0) {
+ nc->qid = dir.qid;
+ goto Accept;
+ }
+ continue;
}
}
}
@@ -331,41 +331,42 @@
dir.qid.path = 0;
for (i = 0;; i++)
switch ((*gen) (c, NULL, tab, ntab, i, &dir)) {
- case -1:
- if (c->qid.type & QTDIR) {
- printd("DEVSTAT got a dir: %llu\n", c->qid.path);
- if (c->name == NULL)
- elem = "???";
- else if (strcmp(c->name->s, "/") == 0)
- elem = "/";
- else
- for (elem = p = c->name->s; *p; p++)
- if (*p == '/')
- elem = p + 1;
- devdir(c, c->qid, elem, 0, eve.name, DMDIR | 0555, &dir);
- n = convD2M(&dir, db, n);
- if (n == 0)
- error(EINVAL, ERROR_FIXME);
- return n;
- }
- printd("DEVSTAT fails:%s %llu\n", devtab[c->type].name,
- c->qid.path);
- error(ENOENT, ERROR_FIXME);
- case 0:
- printd("DEVSTAT got 0\n");
- break;
- case 1:
- printd("DEVSTAT gen returns path %p name %s, want path %p\n",
- dir.qid.path, dir.name, c->qid.path);
- if (c->qid.path == dir.qid.path)
- return dev_make_stat(c, &dir, db, n);
- break;
+ case -1:
+ if (c->qid.type & QTDIR) {
+ printd("DEVSTAT got a dir: %llu\n",
+ c->qid.path);
+ if (c->name == NULL)
+ elem = "???";
+ else if (strcmp(c->name->s, "/") == 0)
+ elem = "/";
+ else
+ for (elem = p = c->name->s; *p; p++)
+ if (*p == '/')
+ elem = p + 1;
+ devdir(c, c->qid, elem, 0, eve.name, DMDIR |
+ 0555, &dir);
+ n = convD2M(&dir, db, n);
+ if (n == 0)
+ error(EINVAL, ERROR_FIXME);
+ return n;
+ }
+ printd("DEVSTAT fails:%s %llu\n", devtab[c->type].name,
+ c->qid.path);
+ error(ENOENT, ERROR_FIXME);
+ case 0:
+ printd("DEVSTAT got 0\n");
+ break;
+ case 1:
+ printd("DEVSTAT gen returns path %p name %s, want path %p\n",
+ dir.qid.path, dir.name, c->qid.path);
+ if (c->qid.path == dir.qid.path)
+ return dev_make_stat(c, &dir, db, n);
+ break;
}
}
-long
-devdirread(struct chan *c, char *d, long n,
- struct dirtab *tab, int ntab, Devgen * gen)
+long devdirread(struct chan *c, char *d, long n, struct dirtab *tab, int ntab,
+ Devgen * gen)
{
long m, dsz;
/* this is gross. Make it 2 so we have room at the end for
@@ -376,25 +377,26 @@
dir[0].qid.path = 0;
for (m = 0; m < n; c->dri++) {
switch ((*gen) (c, NULL, tab, ntab, c->dri, &dir[0])) {
- case -1:
- printd("DEVDIRREAD got -1, asked for s = %d\n", c->dri);
+ case -1:
+ printd("DEVDIRREAD got -1, asked for s = %d\n", c->dri);
+ return m;
+
+ case 0:
+ printd("DEVDIRREAD got 0, asked for s = %d\n", c->dri);
+ break;
+
+ case 1:
+ printd("DEVDIRREAD got 1, asked for s = %d\n", c->dri);
+ dsz = convD2M(&dir[0], (uint8_t *) d, n - m);
+ /* <= not < because this isn't stat; read is stuck */
+ if (dsz <= BIT16SZ) {
+ if (m == 0)
+ error(ENODATA, ERROR_FIXME);
return m;
-
- case 0:
- printd("DEVDIRREAD got 0, asked for s = %d\n", c->dri);
- break;
-
- case 1:
- printd("DEVDIRREAD got 1, asked for s = %d\n", c->dri);
- dsz = convD2M(&dir[0], (uint8_t *) d, n - m);
- if (dsz <= BIT16SZ) { /* <= not < because this isn't stat; read is stuck */
- if (m == 0)
- error(ENODATA, ERROR_FIXME);
- return m;
- }
- m += dsz;
- d += dsz;
- break;
+ }
+ m += dsz;
+ d += dsz;
+ break;
}
}
@@ -420,22 +422,23 @@
dir.qid.path = 0;
for (i = 0;; i++) {
switch ((*gen) (c, NULL, tab, ntab, i, &dir)) {
- case -1:
+ case -1:
+ goto Return;
+ case 0:
+ break;
+ case 1:
+ if (c->qid.path == dir.qid.path) {
+ devpermcheck(dir.uid, dir.mode, omode);
goto Return;
- case 0:
- break;
- case 1:
- if (c->qid.path == dir.qid.path) {
- devpermcheck(dir.uid, dir.mode, omode);
- goto Return;
- }
- break;
+ }
+ break;
}
}
Return:
c->offset = 0;
if ((c->qid.type & QTDIR) && (omode & O_WRITE))
- error(EACCES, "Tried opening dir with non-read-only mode %o", omode);
+ error(EACCES, "Tried opening dir with non-read-only mode %o",
+ omode);
c->mode = openmode(omode);
c->flag |= COPEN;
return c;
diff --git a/kern/src/ns/devtab.c b/kern/src/ns/devtab.c
index 95a23b1..e88df66 100644
--- a/kern/src/ns/devtab.c
+++ b/kern/src/ns/devtab.c
@@ -16,7 +16,7 @@
#include <event.h>
#include <umem.h>
-void devtabreset()
+void devtabreset(void)
{
ERRSTACK(1);
volatile int i;
@@ -33,7 +33,7 @@
poperror();
}
-void devtabinit()
+void devtabinit(void)
{
ERRSTACK(1);
volatile int i;
@@ -44,16 +44,17 @@
return;
}
for (i = 0; &devtab[i] < __devtabend; i++) {
- /* if we have errors, check the align of struct dev and objdump */
+ /* if we have errors, check the align of struct dev and objdump
+ */
printd("i %d, '%s', dev %p, init %p\n", i, devtab[i].name,
- &devtab[i], devtab[i].init);
+ &devtab[i], devtab[i].init);
if (devtab[i].init)
devtab[i].init();
}
poperror();
}
-void devtabshutdown()
+void devtabshutdown(void)
{
int i;
@@ -70,6 +71,7 @@
struct dev *devtabget(const char *name, int user)
{
int i = devno(name, user);
+
if (i > 0)
return &devtab[i];
diff --git a/kern/src/ns/fs_file.c b/kern/src/ns/fs_file.c
index d1a4086..105064e 100644
--- a/kern/src/ns/fs_file.c
+++ b/kern/src/ns/fs_file.c
@@ -22,10 +22,10 @@
qlock_init(&f->qlock);
fs_file_set_basename(f, name);
f->ops = ops;
- /* TODO: consider holding off on initializing the PM, since only walked and
- * opened entries could use it. pm == NULL means no PM yet. Negative
- * entries will never be used in this manner. Doing it now avoids races,
- * though it's mostly zeroing cache-hot fields. */
+ /* TODO: consider holding off on initializing the PM, since only walked
+ * and opened entries could use it. pm == NULL means no PM yet.
+ * Negative entries will never be used in this manner. Doing it now
+ * avoids races, though it's mostly zeroing cache-hot fields. */
f->pm = &f->static_pm;
pm_init(f->pm, (struct page_map_operations*)ops, f);
}
@@ -84,14 +84,14 @@
dir->qid.type |= QTEXCL;
if (perm & DMSYMLINK)
dir->qid.type |= QTSYMLINK;
- /* dir->mode stores all the DM bits, but note that userspace can only affect
- * the permissions (S_PMASK) bits. */
+ /* dir->mode stores all the DM bits, but note that userspace can only
+ * affect the permissions (S_PMASK) bits. */
dir->mode = perm;
__set_acmtime(f, FSF_ATIME | FSF_BTIME | FSF_MTIME | FSF_CTIME);
dir->length = 0;
- /* TODO: this is a mess if you use anything other than eve. If you use a
- * process, that memory is sitting in the proc struct, but we have weak refs
- * on it. What happens when that proc exits? Disaster. */
+ /* TODO: this is a mess if you use anything other than eve. If you use
+ * a process, that memory is sitting in the proc struct, but we have
+ * weak refs on it. What happens when that proc exits? Disaster. */
assert(user == &eve);
dir->uid = user->name;
dir->gid = user->name;
@@ -116,9 +116,9 @@
{
memcpy(&f->dir, dir, sizeof(struct dir));
fs_file_set_basename(f, dir->name);
- /* TODO: sort out usernames. Not only are these just eve, but they are not
- * struct user or something and they ignore whatever the name was from the
- * remote end. */
+ /* TODO: sort out usernames. Not only are these just eve, but they are
+ * not struct user or something and they ignore whatever the name was
+ * from the remote end. */
f->dir.uid = eve.name;
f->dir.gid = eve.name;
f->dir.muid = eve.name;
@@ -129,8 +129,8 @@
{
if (f->dir.name != f->static_name)
kfree(f->dir.name);
- /* TODO: Not sure if these will be refcounted objects in the future. Keep
- * this in sync with other code that manages/sets uid/gid/muid. */
+ /* TODO: Not sure if these will be refcounted objects in the future.
+ * Keep this in sync with other code that manages/sets uid/gid/muid. */
f->dir.uid = NULL;
f->dir.gid = NULL;
f->dir.muid = NULL;
@@ -289,8 +289,8 @@
assert((long)end >= 0);
if (end <= begin)
return;
- /* We're punching for the range [begin, end), but inclusive for the pages:
- * [first_pg_idx, last_pg_idx]. */
+ /* We're punching for the range [begin, end), but inclusive for the
+ * pages: [first_pg_idx, last_pg_idx]. */
first_pg_idx = LA2PPN(begin);
last_pg_idx = LA2PPN(ROUNDUP(end, PGSIZE)) - 1;
nr_pages = last_pg_idx - first_pg_idx + 1;
@@ -308,8 +308,8 @@
return;
}
if (PGOFF(end)) {
- /* if this unaligned end is beyond the EOF, we might pull in a page of
- * zeros, then zero the first part of it. */
+ /* if this unaligned end is beyond the EOF, we might pull in a
+ * page of zeros, then zero the first part of it. */
error = pm_load_page(f->pm, last_pg_idx, &page);
if (error)
error(-error, "punch_hole pm_load_page failed");
@@ -322,10 +322,11 @@
return;
}
pm_remove_or_zero_pages(f->pm, first_pg_idx, nr_pages);
- /* After we removed the pages from the PM, but before we tell the backend,
- * someone could load a backend page. Note that we only tell the backend
- * about the intermediate pages - we already dealt with the edge pages
- * above, and the PM has the latest, dirty version of them. */
+ /* After we removed the pages from the PM, but before we tell the
+ * backend, someone could load a backend page. Note that we only tell
+ * the backend about the intermediate pages - we already dealt with the
+ * edge pages above, and the PM has the latest, dirty version of them.
+ * */
f->ops->punch_hole(f, first_pg_idx << PGSHIFT,
(first_pg_idx + nr_pages) << PGSHIFT);
}
@@ -339,8 +340,8 @@
error(EINVAL, "can't grow file to %lu bytes", to);
write_metadata(f, to, true);
if (to < old_len) {
- /* Round up the old_len to avoid making an unnecessary partial page of
- * zeros at the end of the file. */
+ /* Round up the old_len to avoid making an unnecessary partial
+ * page of zeros at the end of the file. */
fs_file_punch_hole(f, to, ROUNDUP(old_len, PGSIZE));
}
}
@@ -370,8 +371,8 @@
nexterror();
}
while (buf < buf_end) {
- /* Check early, so we don't load pages beyond length needlessly. The
- * PM/FSF op might just create zeroed pages when asked. */
+ /* Check early, so we don't load pages beyond length needlessly.
+ * The PM/FSF op might just create zeroed pages when asked. */
if (offset + so_far >= fs_file_get_length(f))
break;
pg_off = PGOFF(offset + so_far);
@@ -380,8 +381,9 @@
if (error)
error(-error, "read pm_load_page failed");
copy_amt = MIN(PGSIZE - pg_off, buf_end - buf);
- /* Lockless peak. Check the len so we don't read beyond EOF. We have a
- * page, but we don't necessarily have access to all of it. */
+ /* Lockless peak. Check the len so we don't read beyond EOF.
+ * We have a page, but we don't necessarily have access to all
+ * of it. */
total_remaining = fs_file_get_length(f) - (offset + so_far);
if (copy_amt > total_remaining) {
copy_amt = total_remaining;
@@ -423,7 +425,8 @@
};
if (offset + count > fs_file_get_length(f)) {
if (!f->ops->can_grow_to(f, offset + count))
- error(EINVAL, "can't write file to %lu bytes", offset + count);
+ error(EINVAL, "can't write file to %lu bytes", offset +
+ count);
}
while (buf < buf_end) {
pg_off = PGOFF(offset + so_far);
@@ -455,8 +458,8 @@
assert(count == so_far);
/* We set the len *after* writing for our lockless reads. If we set len
* before, then read() could start as soon as we loaded the page (all
- * zeros), but before we wrote the actual data. They'd get zeros instead of
- * what we added. */
+ * zeros), but before we wrote the actual data. They'd get zeros
+ * instead of what we added. */
write_metadata(f, offset + so_far, false);
poperror();
return so_far;
@@ -474,8 +477,8 @@
}
if (!caller_is_username(f->dir.uid))
error(EPERM, "wrong user for wstat, need %s", f->dir.uid);
- /* Only allowing changes in permissions, not random stuff like whether it is
- * a directory or symlink. */
+ /* Only allowing changes in permissions, not random stuff like whether
+ * it is a directory or symlink. */
static_assert(!(DMMODE_BITS & S_PMASK));
mode = (f->dir.mode & ~S_PMASK) | (new_mode & S_PMASK);
WRITE_ONCE(f->dir.mode, mode);
@@ -489,9 +492,10 @@
struct dir *m_dir;
size_t m_sz;
- /* common trick in wstats. we want the dir and any strings in the M. the
- * strings are smaller than the entire M (which is strings plus the real dir
- * M). the strings will be placed right after the dir (dir[1]) */
+ /* common trick in wstats. we want the dir and any strings in the M.
+ * the strings are smaller than the entire M (which is strings plus the
+ * real dir M). the strings will be placed right after the dir
+ * (dir[1]). */
m_dir = kzmalloc(sizeof(struct dir) + m_buf_sz, MEM_WAIT);
m_sz = convM2D(m_buf, m_buf_sz, &m_dir[0], (char*)&m_dir[1]);
if (!m_sz) {
diff --git a/kern/src/ns/parse.c b/kern/src/ns/parse.c
index 9b6c5e2..ceba3f8 100644
--- a/kern/src/ns/parse.c
+++ b/kern/src/ns/parse.c
@@ -54,7 +54,8 @@
ep = p + n;
white = 1; /* first text will start field */
while (p < ep) {
- nwhite = (strchr(" \t\r\n", *p++ & 0xFF) != 0); /* UTF is irrelevant */
+ /* UTF is irrelevant */
+ nwhite = (strchr(" \t\r\n", *p++ & 0xFF) != 0);
if (white && !nwhite) /* beginning of field */
nf++;
white = nwhite;
@@ -74,7 +75,8 @@
nf = ncmdfield(p, n);
- /* allocate Cmdbuf plus string pointers plus copy of string including \0 */
+ /* allocate Cmdbuf plus string pointers plus copy of string including \0
+ */
sp = kzmalloc(sizeof(*cb) + nf * sizeof(char *) + n + 1, 0);
cb = (struct cmdbuf *)sp;
cb->f = (char **)(&cb[1]);
diff --git a/kern/src/ns/qio.c b/kern/src/ns/qio.c
index 3debe27..791fa0c 100644
--- a/kern/src/ns/qio.c
+++ b/kern/src/ns/qio.c
@@ -69,19 +69,19 @@
struct block *bfirst; /* buffer */
struct block *blast;
- int dlen; /* data bytes in queue */
- int limit; /* max bytes in queue */
- int inilim; /* initial limit */
+ int dlen; /* data bytes in queue */
+ int limit; /* max bytes in queue */
+ int inilim; /* initial limit */
int state;
- int eof; /* number of eofs read by user */
+ int eof; /* number of eofs read by user */
size_t bytes_read;
void (*kick) (void *); /* restart output */
- void (*bypass) (void *, struct block *); /* bypass queue altogether */
- void *arg; /* argument to kick */
+ void (*bypass) (void *, struct block *); /* bypass queue altogether */
+ void *arg; /* argument to kick */
- struct rendez rr; /* process waiting to read */
- struct rendez wr; /* process waiting to write */
+ struct rendez rr; /* process waiting to read */
+ struct rendez wr; /* process waiting to write */
qio_wake_cb_t wake_cb; /* callbacks for qio wakeups */
void *wake_data;
@@ -91,11 +91,11 @@
enum {
Maxatomic = 64 * 1024,
QIO_CAN_ERR_SLEEP = (1 << 0), /* can throw errors or block/sleep */
- QIO_LIMIT = (1 << 1), /* respect q->limit */
- QIO_DROP_OVERFLOW = (1 << 2), /* alternative to setting qdropoverflow */
+ QIO_LIMIT = (1 << 1), /* respect q->limit */
+ QIO_DROP_OVERFLOW = (1 << 2), /* alternative to qdropoverflow */
QIO_JUST_ONE_BLOCK = (1 << 3), /* when qbreading, just get one block */
- QIO_NON_BLOCK = (1 << 4), /* throw EAGAIN instead of blocking */
- QIO_DONT_KICK = (1 << 5), /* don't kick when waking */
+ QIO_NON_BLOCK = (1 << 4), /* throw EAGAIN instead of blocking */
+ QIO_DONT_KICK = (1 << 5), /* don't kick when waking */
};
unsigned int qiomaxatomic = Maxatomic;
@@ -251,7 +251,8 @@
ebd = &bp->extra_data[i];
if (!ebd->base || !ebd->len)
continue;
- amt = copy_to_block_body(newb, (void*)ebd->base + ebd->off, ebd->len);
+ amt = copy_to_block_body(newb, (void*)ebd->base + ebd->off,
+ ebd->len);
assert(amt == ebd->len);
}
block_copy_metadata(newb, bp);
@@ -290,20 +291,22 @@
if (BHLEN(bp) >= n)
return bp;
- /* If there's no chance, just bail out now. This might be slightly wasteful
- * if there's a long blist that does have enough data. */
+ /* If there's no chance, just bail out now. This might be slightly
+ * wasteful if there's a long blist that does have enough data. */
if (n > blocklen(bp))
return 0;
/* a start at explicit main-body / header management */
if (bp->extra_len) {
if (n > bp->lim - bp->rp) {
- /* would need to realloc a new block and copy everything over. */
+ /* would need to realloc a new block and copy everything
+ * over. */
panic("can't pullup %d bytes, no place to put it: bp->lim %p, bp->rp %p, bp->lim-bp->rp %d\n",
- n, bp->lim, bp->rp, bp->lim-bp->rp);
+ n, bp->lim, bp->rp, bp->lim-bp->rp);
}
len = n - BHLEN(bp);
- /* Would need to recursively call this, or otherwise pull from later
- * blocks and put chunks of their data into the block we're building. */
+ /* Would need to recursively call this, or otherwise pull from
+ * later blocks and put chunks of their data into the block
+ * we're building. */
if (len > bp->extra_len)
panic("pullup more than extra (%d, %d, %d)\n",
n, BHLEN(bp), bp->extra_len);
@@ -555,7 +558,8 @@
}
/* Grow with extra data buffers. */
buf = kzmalloc(len - BLEN(bp), MEM_WAIT);
- block_append_extra(bp, (uintptr_t)buf, 0, len - BLEN(bp), MEM_WAIT);
+ block_append_extra(bp, (uintptr_t)buf, 0, len - BLEN(bp),
+ MEM_WAIT);
QDEBUG checkb(bp, "adjustblock 3");
return bp;
}
@@ -656,8 +660,9 @@
if (copy_amt) {
copy_amt = copy_to_block_body(to, from->rp, copy_amt);
from->rp += copy_amt;
- /* We only change dlen, (data len), not q->len, since the q still has
- * the same block memory allocation (no kfrees happened) */
+ /* We only change dlen, (data len), not q->len, since the q
+ * still has the same block memory allocation (no kfrees
+ * happened) */
q->dlen -= copy_amt;
q->bytes_read += copy_amt;
}
@@ -670,12 +675,15 @@
if (len >= ebd->len) {
amt = move_ebd(ebd, to, from, q);
if (!amt) {
- /* our internal alloc could have failed. this ebd is now the
- * last one we'll consider. let's handle it separately and put
- * it in the main body. */
+ /* our internal alloc could have failed. this
+ * ebd is now the last one we'll consider.
+ * let's handle it separately and put it in the
+ * main body. */
if (copy_amt)
return copy_amt;
- copy_amt = copy_to_block_body(to, (void*)ebd->base + ebd->off,
+ copy_amt = copy_to_block_body(to,
+ (void*)ebd->base +
+ ebd->off,
ebd->len);
block_and_q_lost_extra(from, q, copy_amt);
break;
@@ -684,12 +692,12 @@
copy_amt += amt;
continue;
} else {
- /* If we're here, we reached our final ebd, which we'll need to
- * split to get anything from it. */
+ /* If we're here, we reached our final ebd, which we'll
+ * need to split to get anything from it. */
if (copy_amt)
return copy_amt;
- copy_amt = copy_to_block_body(to, (void*)ebd->base + ebd->off,
- len);
+ copy_amt = copy_to_block_body(to, (void*)ebd->base +
+ ebd->off, len);
ebd->off += copy_amt;
ebd->len -= copy_amt;
block_and_q_lost_extra(from, q, copy_amt);
@@ -736,11 +744,12 @@
return QBR_FAIL;
}
}
- /* We need to check before adjusting q->len. We're checking the writer's
- * sleep condition / tap condition. When set, we *might* be making an edge
- * transition (from unwritable to writable), which needs to wake and fire
- * taps. But, our read might not drain the queue below q->lim. We'll check
- * again later to see if we should really wake them. */
+ /* We need to check before adjusting q->len. We're checking the
+ * writer's sleep condition / tap condition. When set, we *might* be
+ * making an edge transition (from unwritable to writable), which needs
+ * to wake and fire taps. But, our read might not drain the queue below
+ * q->lim. We'll check again later to see if we should really wake
+ * them. */
was_unwritable = !qwritable(q);
blen = BLEN(first);
if ((q->state & Qcoalesce) && (blen == 0)) {
@@ -749,20 +758,22 @@
/* Need to retry to make sure we have a first block */
return QBR_AGAIN;
}
- /* Qmsg: just return the first block. Be careful, since our caller might
- * not read all of the block and thus drop bytes. Similar to SOCK_DGRAM. */
+ /* Qmsg: just return the first block. Be careful, since our caller
+ * might not read all of the block and thus drop bytes. Similar to
+ * SOCK_DGRAM. */
if (q->state & Qmsg) {
ret = pop_first_block(q);
goto out_ok;
}
- /* Let's get at least something first - makes the code easier. This way,
- * we'll only ever split the block once. */
+ /* Let's get at least something first - makes the code easier. This
+ * way, we'll only ever split the block once. */
if (blen <= len) {
ret = pop_first_block(q);
len -= blen;
} else {
- /* need to split the block. we won't actually take the first block out
- * of the queue - we're just extracting a little bit. */
+ /* need to split the block. we won't actually take the first
+ * block out of the queue - we're just extracting a little bit.
+ */
if (!spare) {
/* We have nothing and need a spare block. Retry! */
spin_unlock_irqsave(&q->lock);
@@ -772,8 +783,8 @@
ret = spare;
goto out_ok;
}
- /* At this point, we just grabbed the first block. We can try to grab some
- * more, up to len (if they want). */
+ /* At this point, we just grabbed the first block. We can try to grab
+ * some more, up to len (if they want). */
if (qio_flags & QIO_JUST_ONE_BLOCK)
goto out_ok;
ret_last = ret;
@@ -785,11 +796,12 @@
continue;
}
if (blen > len) {
- /* We could try to split the block, but that's a huge pain. For
- * instance, we might need to move the main body of b into an
- * extra_data of ret_last. lots of ways for that to fail, and lots
- * of cases to consider. Easier to just bail out. This is why I
- * did the first block above: we don't need to worry about this. */
+ /* We could try to split the block, but that's a huge
+ * pain. For instance, we might need to move the main
+ * body of b into an extra_data of ret_last. lots of
+ * ways for that to fail, and lots of cases to consider.
+ * Easier to just bail out. This is why I did the first
+ * block above: we don't need to worry about this. */
break;
}
ret_last->next = pop_first_block(q);
@@ -842,24 +854,28 @@
goto out_ret;
case QBR_SPARE:
assert(!spare);
- /* Due to some nastiness, we need a fresh block so we can read out
- * anything from the queue. 'len' seems like a reasonable amount.
- * Maybe we can get away with less. */
+ /* Due to some nastiness, we need a fresh block so we
+ * can read out anything from the queue. 'len' seems
+ * like a reasonable amount. Maybe we can get away with
+ * less. */
spare = block_alloc(len, mem_flags);
if (!spare) {
- /* Careful here: a memory failure (possible with MEM_ATOMIC)
- * could look like 'no data in the queue' (QBR_FAIL). The only
- * one who does is this qget(), who happens to know that we
- * won't need a spare, due to the len argument. Spares are only
- * needed when we need to split a block. */
+ /* Careful here: a memory failure (possible with
+ * MEM_ATOMIC) could look like 'no data in the
+ * queue' (QBR_FAIL). The only one who does is
+ * this qget(), who happens to know that we
+ * won't need a spare, due to the len argument.
+ * Spares are only needed when we need to split
+ * a block. */
ret = 0;
goto out_ret;
}
break;
case QBR_AGAIN:
- /* if the first block is 0 and we are Qcoalesce, then we'll need to
- * try again. We bounce out of __try so we can perform the "is
- * there a block" logic again from the top. */
+ /* if the first block is 0 and we are Qcoalesce, then
+ * we'll need to try again. We bounce out of __try so
+ * we can perform the "is there a block" logic again
+ * from the top. */
break;
}
}
@@ -893,8 +909,8 @@
size_t removed_amt;
size_t sofar = 0;
- /* This is racy. There could be multiple qdiscarders or other consumers,
- * where the consumption could be interleaved. */
+ /* This is racy. There could be multiple qdiscarders or other
+ * consumers, where the consumption could be interleaved. */
while (qlen(q) && len) {
blist = __qbread(q, len, QIO_DONT_KICK, MEM_WAIT);
removed_amt = freeblist(blist);
@@ -1006,22 +1022,24 @@
uint8_t *first_main_body = 0;
ssize_t sofar = 0;
- /* find the first block; keep offset relative to the latest b in the list */
+ /* find the first block; keep offset relative to the latest b in the
+ * list */
for (b = blist; b; b = b->next) {
if (BLEN(b) > offset)
break;
offset -= BLEN(b);
}
- /* qcopy semantics: if you asked for an offset outside the block list, you
- * get an empty block back */
+ /* qcopy semantics: if you asked for an offset outside the block list,
+ * you get an empty block back */
if (!b)
return 0;
first = b;
- sofar -= offset; /* don't count the remaining offset in the first b */
+ sofar -= offset; /* don't count the remaining offset in the first b */
/* upper bound for how many buffers we'll need in newb */
for (/* b is set*/; b; b = b->next) {
nr_bufs += BHLEN(b) ? 1 : 0;
- nr_bufs += b->nr_extra_bufs; /* still assuming nr_extra == nr_valid */
+ /* still assuming nr_extra == nr_valid */
+ nr_bufs += b->nr_extra_bufs;
sofar += BLEN(b);
if (sofar > len)
break;
@@ -1036,33 +1054,39 @@
if (offset) {
if (offset < BHLEN(b)) {
/* off is in the main body */
- len -= point_to_body(b, b->rp + offset, newb, newb_idx, len);
+ len -= point_to_body(b, b->rp + offset, newb,
+ newb_idx, len);
newb_idx++;
} else {
- /* off is in one of the buffers (or just past the last one).
- * we're not going to point to b's main body at all. */
+ /* off is in one of the buffers (or just past
+ * the last one). we're not going to point to
+ * b's main body at all. */
offset -= BHLEN(b);
assert(b->extra_data);
- /* assuming these extrabufs are packed, or at least that len
- * isn't gibberish */
+ /* assuming these extrabufs are packed, or at
+ * least that len isn't gibberish */
while (b->extra_data[b_idx].len <= offset) {
offset -= b->extra_data[b_idx].len;
b_idx++;
}
- /* now offset is set to our offset in the b_idx'th buf */
- len -= point_to_buf(b, b_idx, offset, newb, newb_idx, len);
+ /* now offset is set to our offset in the
+ * b_idx'th buf */
+ len -= point_to_buf(b, b_idx, offset, newb,
+ newb_idx, len);
newb_idx++;
b_idx++;
}
offset = 0;
} else {
if (BHLEN(b)) {
- len -= point_to_body(b, b->rp, newb, newb_idx, len);
+ len -= point_to_body(b, b->rp, newb, newb_idx,
+ len);
newb_idx++;
}
}
- /* knock out all remaining bufs. we only did one point_to_ op by now,
- * and any point_to_ could be our last if it consumed all of len. */
+ /* knock out all remaining bufs. we only did one point_to_ op
+ * by now, and any point_to_ could be our last if it consumed
+ * all of len. */
for (int i = b_idx; (i < b->nr_extra_bufs) && len; i++) {
len -= point_to_buf(b, i, 0, newb, newb_idx, len);
newb_idx++;
@@ -1076,6 +1100,7 @@
{
int ret;
struct block *newb = block_alloc(header_len, MEM_WAIT);
+
do {
ret = __blist_clone_to(blist, newb, len, offset);
if (ret)
@@ -1095,7 +1120,7 @@
/* the while loop should rarely be used: it would require someone
* concurrently adding to the queue. */
do {
- /* TODO: RCU: protecting the q list (b->next) (need read lock) */
+ /* TODO: RCU protect the q list (b->next) (need read lock) */
spin_lock_irqsave(&q->lock);
ret = __blist_clone_to(q->bfirst, newb, len, offset);
spin_unlock_irqsave(&q->lock);
@@ -1230,7 +1255,8 @@
if (q->state & Qclosed) {
if (++q->eof > 3) {
spin_unlock_irqsave(&q->lock);
- error(EPIPE, "multiple reads on a closed queue");
+ error(EPIPE,
+ "multiple reads on a closed queue");
}
if (q->err[0]) {
spin_unlock_irqsave(&q->lock);
@@ -1243,18 +1269,20 @@
error(EAGAIN, "queue empty");
}
spin_unlock_irqsave(&q->lock);
- /* As with the producer side, we check for a condition while holding the
- * q->lock, decide to sleep, then unlock. It's like the "check, signal,
- * check again" pattern, but we do it conditionally. Both sides agree
- * synchronously to do it, and those decisions are made while holding
- * q->lock. I think this is OK.
+ /* As with the producer side, we check for a condition while
+ * holding the q->lock, decide to sleep, then unlock. It's like
+ * the "check, signal, check again" pattern, but we do it
+ * conditionally. Both sides agree synchronously to do it, and
+ * those decisions are made while holding q->lock. I think this
+ * is OK.
*
- * The invariant is that no reader sleeps when the queue has data.
- * While holding the rendez lock, if we see there's no data, we'll
- * sleep. Since we saw there was no data, the next writer will see (or
- * already saw) no data, and then the writer decides to rendez_wake,
- * which will grab the rendez lock. If the writer already did that,
- * then we'll see notempty when we do our check-again. */
+ * The invariant is that no reader sleeps when the queue has
+ * data. While holding the rendez lock, if we see there's no
+ * data, we'll sleep. Since we saw there was no data, the next
+ * writer will see (or already saw) no data, and then the writer
+ * decides to rendez_wake, which will grab the rendez lock. If
+ * the writer already did that, then we'll see notempty when we
+ * do our check-again. */
rendez_sleep(&q->rr, notempty, q);
}
}
@@ -1292,20 +1320,21 @@
retval += copy_amt;
for (int i = 0; (i < b->nr_extra_bufs) && amt; i++) {
ebd = &b->extra_data[i];
- /* skip empty entires. if we track this in the struct block, we can
- * just start the for loop early */
+ /* skip empty entires. if we track this in the struct block, we
+ * can just start the for loop early */
if (!ebd->base || !ebd->len)
continue;
copy_amt = MIN(ebd->len, amt);
memcpy(to, (void*)(ebd->base + ebd->off), copy_amt);
- /* we're actually consuming the entries, just like how we advance rp up
- * above, and might only consume part of one. */
+ /* we're actually consuming the entries, just like how we
+ * advance rp up above, and might only consume part of one. */
ebd->len -= copy_amt;
ebd->off += copy_amt;
b->extra_len -= copy_amt;
if (!ebd->len) {
- /* we don't actually have to decref here. it's also done in
- * freeb(). this is the earliest we can free. */
+ /* we don't actually have to decref here. it's also
+ * done in freeb(). this is the earliest we can free.
+ */
kfree((void*)ebd->base);
ebd->base = ebd->off = 0;
}
@@ -1419,7 +1448,8 @@
*/
struct block *qbread(struct queue *q, size_t len)
{
- return __qbread(q, len, QIO_JUST_ONE_BLOCK | QIO_CAN_ERR_SLEEP, MEM_WAIT);
+ return __qbread(q, len, QIO_JUST_ONE_BLOCK | QIO_CAN_ERR_SLEEP,
+ MEM_WAIT);
}
struct block *qbread_nonblock(struct queue *q, size_t len)
@@ -1440,8 +1470,8 @@
size_t qread_nonblock(struct queue *q, void *va, size_t len)
{
- struct block *blist = __qbread(q, len, QIO_CAN_ERR_SLEEP | QIO_NON_BLOCK,
- MEM_WAIT);
+ struct block *blist = __qbread(q, len, QIO_CAN_ERR_SLEEP |
+ QIO_NON_BLOCK, MEM_WAIT);
if (!blist)
return 0;
@@ -1502,14 +1532,16 @@
}
if ((qio_flags & QIO_LIMIT) && (q->dlen >= q->limit)) {
/* drop overflow takes priority over regular non-blocking */
- if ((qio_flags & QIO_DROP_OVERFLOW) || (q->state & Qdropoverflow)) {
+ if ((qio_flags & QIO_DROP_OVERFLOW)
+ || (q->state & Qdropoverflow)) {
spin_unlock_irqsave(&q->lock);
freeb(b);
return -1;
}
- /* People shouldn't set NON_BLOCK without CAN_ERR, but we can be nice
- * and catch it. */
- if ((qio_flags & QIO_CAN_ERR_SLEEP) && (qio_flags & QIO_NON_BLOCK)) {
+ /* People shouldn't set NON_BLOCK without CAN_ERR, but we can be
+ * nice and catch it. */
+ if ((qio_flags & QIO_CAN_ERR_SLEEP)
+ && (qio_flags & QIO_NON_BLOCK)) {
spin_unlock_irqsave(&q->lock);
freeb(b);
error(EAGAIN, "queue full");
@@ -1519,15 +1551,17 @@
QDEBUG checkb(b, "__qbwrite");
spin_unlock_irqsave(&q->lock);
/* TODO: not sure if the usage of a kick is mutually exclusive with a
- * wakeup, meaning that actual users either want a kick or have qreaders. */
+ * wakeup, meaning that actual users either want a kick or have
+ * qreaders. */
if (q->kick && (was_unreadable || (q->state & Qkick)))
q->kick(q->arg);
if (was_unreadable) {
- /* Unlike the read side, there's no double-check to make sure the queue
- * transitioned across an edge. We know we added something, so that's
- * enough. We wake if the queue was empty. Both sides are the same, in
- * that the condition for which we do the rendez_wakeup() is the same as
- * the condition done for the rendez_sleep(). */
+ /* Unlike the read side, there's no double-check to make sure
+ * the queue transitioned across an edge. We know we added
+ * something, so that's enough. We wake if the queue was empty.
+ * Both sides are the same, in that the condition for which we
+ * do the rendez_wakeup() is the same as the condition done for
+ * the rendez_sleep(). */
rendez_wakeup(&q->rr);
qwake_cb(q, FDTAP_FILT_READABLE);
}
@@ -1545,26 +1579,27 @@
*/
if ((qio_flags & QIO_CAN_ERR_SLEEP) &&
!(q->state & Qdropoverflow) && !(qio_flags & QIO_NON_BLOCK)) {
- /* This is a racy peek at the q status. If we accidentally block, our
- * rendez will return. The rendez's peak (qwriter_should_wake) is also
- * racy w.r.t. the q's spinlock (that lock protects writes, but not
- * reads).
+ /* This is a racy peek at the q status. If we accidentally
+ * block, our rendez will return. The rendez's peak
+ * (qwriter_should_wake) is also racy w.r.t. the q's spinlock
+ * (that lock protects writes, but not reads).
*
- * Here's the deal: when holding the rendez lock, if we see the sleep
- * condition, the consumer will wake us. The condition will only ever
- * be changed by the next qbread() (consumer, changes q->dlen). That
- * code will do a rendez wake, which will spin on the rendez lock,
- * meaning it won't procede until we either see the new state (and
- * return) or put ourselves on the rendez, and wake up.
+ * Here's the deal: when holding the rendez lock, if we see the
+ * sleep condition, the consumer will wake us. The condition
+ * will only ever be changed by the next qbread() (consumer,
+ * changes q->dlen). That code will do a rendez wake, which
+ * will spin on the rendez lock, meaning it won't procede until
+ * we either see the new state (and return) or put ourselves on
+ * the rendez, and wake up.
*
- * The pattern is one side writes mem, then signals. Our side checks
- * the signal, then reads the mem. The goal is to not miss seeing the
- * signal AND missing the memory write. In this specific case, the
- * signal is actually synchronous (the rendez lock) and not basic shared
- * memory.
+ * The pattern is one side writes mem, then signals. Our side
+ * checks the signal, then reads the mem. The goal is to not
+ * miss seeing the signal AND missing the memory write. In this
+ * specific case, the signal is actually synchronous (the rendez
+ * lock) and not basic shared memory.
*
- * Oh, and we spin in case we woke early and someone else filled the
- * queue, mesa-style. */
+ * Oh, and we spin in case we woke early and someone else filled
+ * the queue, mesa-style. */
while (!qwriter_should_wake(q))
rendez_sleep(&q->wr, qwriter_should_wake, q);
}
@@ -1596,9 +1631,9 @@
struct block *b;
void *ext_buf;
- /* If len is small, we don't need to bother with the extra_data. But until
- * the whole stack can handle extd blocks, we'll use them unconditionally.
- * */
+ /* If len is small, we don't need to bother with the extra_data. But
+ * until the whole stack can handle extd blocks, we'll use them
+ * unconditionally. */
#ifdef CONFIG_BLOCK_EXTRAS
/* allocb builds in 128 bytes of header space to all blocks, but this is
* only available via padblock (to the left). we also need some space
@@ -1642,18 +1677,20 @@
uint8_t *p = vp;
void *ext_buf;
- /* Only some callers can throw. Others might be in a context where waserror
- * isn't safe. */
+ /* Only some callers can throw. Others might be in a context where
+ * waserror isn't safe. */
if ((qio_flags & QIO_CAN_ERR_SLEEP) && waserror()) {
- /* Any error (EAGAIN for nonblock, syscall aborted, even EPIPE) after
- * some data has been sent should be treated as a partial write. */
+ /* Any error (EAGAIN for nonblock, syscall aborted, even EPIPE)
+ * after some data has been sent should be treated as a partial
+ * write. */
if (sofar)
goto out_ok;
nexterror();
}
do {
n = len - sofar;
- /* This is 64K, the max amount per single block. Still a good value? */
+ /* This is 64K, the max amount per single block. Still a good
+ * value? */
if (n > Maxatomic)
n = Maxatomic;
b = build_block(p + sofar, n, mem_flags);
diff --git a/kern/src/ns/sysfile.c b/kern/src/ns/sysfile.c
index 34e65f0..8ea6680 100644
--- a/kern/src/ns/sysfile.c
+++ b/kern/src/ns/sysfile.c
@@ -43,10 +43,14 @@
* like it's the size of a common-case stat. */
enum {
DIRSIZE = STAT_FIX_LEN_AK + 32 * STAT_NR_STRINGS_AK,
- DIRREADLIM = 2048, /* should handle the largest reasonable directory entry */
- DIRREADSIZE=8192, /* Just read a lot. Memory is cheap, lots of bandwidth,
- * and RPCs are very expensive. At the same time,
- * let's not yet exceed a common MSIZE. */
+
+ /* should handle the largest reasonable directory entry */
+ DIRREADLIM = 2048,
+
+ /* Just read a lot. Memory is cheap, lots of bandwidth, and RPCs are
+ * very expensive. At the same time, let's not yet exceed a common
+ * MSIZE. */
+ DIRREADSIZE = 8192,
};
int newfd(struct chan *c, int low_fd, int oflags, bool must_use_low)
@@ -66,8 +70,8 @@
c = lookup_fd(fdt, fd, iref);
if (!c) {
- /* We lost the info about why there was a problem (we used to track file
- * group closed too, can add that in later). */
+ /* We lost the info about why there was a problem (we used to
+ * track file group closed too, can add that in later). */
error(EBADF, ERROR_FIXME);
}
if (chkmnt && (c->flag & CMSG)) {
@@ -118,13 +122,14 @@
/* GIANT WARNING: if this ever throws, ipopen (and probably many others) will
* screw up refcnts of Qctl, err, data, etc */
#if 0
- /* this is the old plan9 style. i think they want to turn exec into read,
- * and strip off anything higher, and just return the RD/WR style bits. not
- * stuff like ORCLOSE. the lack of OEXCL might be a bug on their part (it's
- * the only one of their non-RW-related flags that isn't masked out).
+ /* this is the old plan9 style. i think they want to turn exec into
+ * read, and strip off anything higher, and just return the RD/WR style
+ * bits. not stuff like ORCLOSE. the lack of OEXCL might be a bug on
+ * their part (it's the only one of their non-RW-related flags that
+ * isn't masked out).
*
- * Note that we no longer convert OEXEC/O_EXEC to O_READ, and instead return
- * just the O_ACCMODE bits. */
+ * Note that we no longer convert OEXEC/O_EXEC to O_READ, and instead
+ * return just the O_ACCMODE bits. */
if (o >= (OTRUNC | OCEXEC | ORCLOSE | OEXEC))
error(EINVAL, ERROR_FIXME);
o &= ~(OTRUNC | OCEXEC | ORCLOSE);
@@ -134,8 +139,8 @@
return OREAD;
return o;
#endif
- /* no error checking (we have a shitload of flags anyway), and we return the
- * basic access modes (RD/WR/ETC) */
+ /* no error checking (we have a shitload of flags anyway), and we return
+ * the basic access modes (RD/WR/ETC) */
return omode & O_ACCMODE;
}
@@ -181,12 +186,12 @@
poperror();
/* This is a little hokey. Ideally, we'd only allow O_PATH fds to be
- * fchdir'd. Linux/POSIX lets you do arbitrary FDs. Luckily, we stored the
- * name when we walked (__namec_from), so we should be able to recreate the
- * chan. Using namec() with channame() is a more heavy-weight cclone(), but
- * also might have issues if the chan has since been removed or the
- * namespace is otherwise different from when the original fd/chan was first
- * created. */
+ * fchdir'd. Linux/POSIX lets you do arbitrary FDs. Luckily, we stored
+ * the name when we walked (__namec_from), so we should be able to
+ * recreate the chan. Using namec() with channame() is a more
+ * heavy-weight cclone(), but also might have issues if the chan has
+ * since been removed or the namespace is otherwise different from when
+ * the original fd/chan was first created. */
if (c->flag & O_PATH) {
set_dot(target, c);
return 0;
@@ -293,8 +298,8 @@
error(EPERM, ERROR_FIXME);
}
ret = insert_obj_fdt(&to_proc->open_files, c, to_fd, 0, TRUE);
- /* drop the ref from fdtochan. if insert succeeded, there is one other ref
- * stored in the FDT */
+ /* drop the ref from fdtochan. if insert succeeded, there is one other
+ * ref stored in the FDT */
cclose(c);
if (ret < 0)
error(EFAIL, "Can't insert FD %d into FDG", to_fd);
@@ -591,10 +596,10 @@
if ((path[0] == '/') || (fromfd == AT_FDCWD)) {
c = namec(path, Aopen, vfs_flags, 0, NULL);
} else {
- /* We don't cclose from. namec_from will convert it to the new chan
- * during the walk process (c). It'll probably close from internally,
- * and give us something new for c. On error, namec_from will cclose
- * from. */
+ /* We don't cclose from. namec_from will convert it to the new
+ * chan during the walk process (c). It'll probably close from
+ * internally, and give us something new for c. On error,
+ * namec_from will cclose from. */
from = fdtochan(¤t->open_files, fromfd, -1, FALSE, TRUE);
if (!(from->flag & O_PATH))
error(EINVAL, "Cannot openat from a non-O_PATH FD");
@@ -635,8 +640,9 @@
while (mount != NULL) {
/* Error causes component of union to be skipped */
if (mount->to) {
- /* normally we want to discard the error, but for our ghetto kdirent
- * hack, we need to repeat unionread if we saw a ENODATA */
+ /* normally we want to discard the error, but for our
+ * ghetto kdirent hack, we need to repeat unionread if
+ * we saw a ENODATA */
if (waserror()) {
if (get_errno() == ENODATA) {
runlock(&m->lock);
@@ -647,11 +653,13 @@
} else {
if (c->umc == NULL) {
c->umc = cclone(mount->to);
- c->umc = devtab[c->umc->type].open(c->umc,
- O_READ);
+ c->umc =
+ devtab[c->umc->type].open(c->umc,
+ O_READ);
}
- nr = devtab[c->umc->type].read(c->umc, va, n, c->umc->offset);
+ nr = devtab[c->umc->type].read(c->umc, va, n,
+ c->umc->offset);
if (nr < 0)
nr = 0; /* dev.c can return -1 */
c->umc->offset += nr;
@@ -733,7 +741,8 @@
}
/* debugging */
if (waserror()) {
- printk("Well, sysread of a dir sucks.%s \n", current_errstr());
+ printk("Well, sysread of a dir sucks.%s \n",
+ current_errstr());
nexterror();
}
va = c->buf + c->bufused;
@@ -745,7 +754,7 @@
n = unionread(c, va, n);
else {
if (offp == NULL) {
- spin_lock(&c->lock); /* lock for int64_t assignment */
+ spin_lock(&c->lock); /* lock for int64_t assignment */
off = c->offset;
spin_unlock(&c->lock);
} else
@@ -871,17 +880,17 @@
return -1;
}
renamee = namec(from_path, Aremove, 0, 0, NULL);
- /* We might need to support wstat for 'short' rename (intra-directory, with
- * no slashes). Til then, we can just go with EXDEV. */
+ /* We might need to support wstat for 'short' rename (intra-directory,
+ * with no slashes). Til then, we can just go with EXDEV. */
if (!devtab[renamee->type].rename)
error(EXDEV, "device does not support rename");
parent_chan = namec(to_path, Arename, 0, 0, (char*)renamee);
- /* When we're done, renamee still points to the file, but it's in the new
- * location. Its cname is still the old location, similar to remove. If
- * anyone cares, we can change it. parent_chan still points to the parent -
- * it didn't get moved like create does. Though it does have the name of
- * the new location. If we want, we can hand that to renamee. It's a moot
- * point, since they are both getting closed. */
+ /* When we're done, renamee still points to the file, but it's in the
+ * new location. Its cname is still the old location, similar to
+ * remove. If anyone cares, we can change it. parent_chan still points
+ * to the parent - it didn't get moved like create does. Though it does
+ * have the name of the new location. If we want, we can hand that to
+ * renamee. It's a moot point, since they are both getting closed. */
cclose(renamee);
cclose(parent_chan);
poperror();
@@ -905,49 +914,49 @@
nexterror();
}
switch (whence) {
- case 0:
- if (c->qid.type & QTDIR) {
- if (off != 0)
- error(EISDIR, ERROR_FIXME);
- unionrewind(c);
- } else if (off < 0)
- error(EINVAL, ERROR_FIXME);
- spin_lock(&c->lock); /* lock for int64_t assignment */
- c->offset = off;
- spin_unlock(&c->lock);
- break;
-
- case 1:
- if (c->qid.type & QTDIR)
+ case 0:
+ if (c->qid.type & QTDIR) {
+ if (off != 0)
error(EISDIR, ERROR_FIXME);
- spin_lock(&c->lock); /* lock for read/write update */
- off += c->offset;
- if (off < 0) {
- spin_unlock(&c->lock);
- error(EINVAL, ERROR_FIXME);
- }
- c->offset = off;
- spin_unlock(&c->lock);
- break;
-
- case 2:
- if (c->qid.type & QTDIR)
- error(EISDIR, ERROR_FIXME);
- dir = chandirstat(c);
- if (dir == NULL)
- error(EFAIL, "internal error: stat error in seek");
- off += dir->length;
- kfree(dir);
- if (off < 0)
- error(EINVAL, ERROR_FIXME);
- spin_lock(&c->lock); /* lock for read/write update */
- c->offset = off;
- spin_unlock(&c->lock);
- break;
-
- default:
+ unionrewind(c);
+ } else if (off < 0)
error(EINVAL, ERROR_FIXME);
- break;
+ spin_lock(&c->lock); /* lock for int64_t assignment */
+ c->offset = off;
+ spin_unlock(&c->lock);
+ break;
+
+ case 1:
+ if (c->qid.type & QTDIR)
+ error(EISDIR, ERROR_FIXME);
+ spin_lock(&c->lock); /* lock for read/write update */
+ off += c->offset;
+ if (off < 0) {
+ spin_unlock(&c->lock);
+ error(EINVAL, ERROR_FIXME);
+ }
+ c->offset = off;
+ spin_unlock(&c->lock);
+ break;
+
+ case 2:
+ if (c->qid.type & QTDIR)
+ error(EISDIR, ERROR_FIXME);
+ dir = chandirstat(c);
+ if (dir == NULL)
+ error(EFAIL, "internal error: stat error in seek");
+ off += dir->length;
+ kfree(dir);
+ if (off < 0)
+ error(EINVAL, ERROR_FIXME);
+ spin_lock(&c->lock); /* lock for read/write update */
+ c->offset = off;
+ spin_unlock(&c->lock);
+ break;
+
+ default:
+ error(EINVAL, ERROR_FIXME);
+ break;
}
poperror();
c->dri = 0;
@@ -1012,6 +1021,7 @@
int n = 4096;
uint8_t *buf;
+
buf = kmalloc(n, MEM_WAIT);
n = sysfstat(fd, buf, n);
if (n > 0) {
@@ -1061,6 +1071,7 @@
int n = 4096;
uint8_t *buf;
+
buf = kmalloc(n, MEM_WAIT);
n = __stat(path, buf, n, flags);
if (n > 0) {
@@ -1095,13 +1106,14 @@
error(EINVAL, ERROR_FIXME);
if (offp == NULL) {
- /* append changes the offset to the end, and even if we fail later, this
- * change will persist */
+ /* append changes the offset to the end, and even if we fail
+ * later, this change will persist */
if (c->flag & O_APPEND) {
dir = chandirstat(c);
if (!dir)
- error(EFAIL, "internal error: stat error in append write");
- spin_lock(&c->lock); /* legacy lock for int64 assignment */
+ error(EFAIL, "stat error in append write");
+ /* legacy lock for int64 assignment */
+ spin_lock(&c->lock);
c->offset = dir->length;
spin_unlock(&c->lock);
kfree(dir);
@@ -1197,7 +1209,8 @@
kfree(d);
return NULL;
}
- nd = GBIT16((uint8_t *) buf) + BIT16SZ; /* size needed to store whole stat buffer including count */
+ /* size needed to store whole stat buffer including count */
+ nd = GBIT16((uint8_t *) buf) + BIT16SZ;
if (nd <= n) {
convM2D(buf, n, d, (char *)&d[1]);
return d;
@@ -1307,7 +1320,8 @@
}
/*
- * first find number of all stats, check they look like stats, & size all associated strings
+ * first find number of all stats, check they look like stats, & size
+ * all associated strings
*/
ss = 0;
n = 0;
@@ -1330,7 +1344,8 @@
for (i = 0; i < ts; i += m) {
m = BIT16SZ + GBIT16((uint8_t *) & buf[i]);
/* Note 's' is ignored by convM2kdirent */
- if (nn >= n || /*convM2D */ convM2kdirent(&buf[i], m, *d + nn, s) != m) {
+ if (nn >= n || /*convM2D */ convM2kdirent(&buf[i], m, *d + nn,
+ s) != m) {
kfree(*d);
*d = NULL;
error(EFAIL, "bad directory entry");
@@ -1400,7 +1415,8 @@
c->name ? c->name->s : "no cname",
kref_refcnt(&c->ref),
has_dev ? devtab[c->type].name : "no dev",
- has_chaninfo ? devtab[c->type].chaninfo(c, buf, sizeof(buf)) : "");
+ has_chaninfo ? devtab[c->type].chaninfo(c, buf, sizeof(buf))
+ : "");
if (!has_chaninfo)
printk("qid.path: %p\n", c->qid.path);
printk("\n");
@@ -1422,8 +1438,8 @@
return -1;
}
if (!parent) {
- /* We are probably spawned by the kernel directly, and have no parent to
- * inherit from. */
+ /* We are probably spawned by the kernel directly, and have no
+ * parent to inherit from. */
new_proc->pgrp = newpgrp();
new_proc->slash = namec("#kfs", Atodir, 0, 0, NULL);
if (!new_proc->slash)
@@ -1438,7 +1454,8 @@
/* Shared semantics */
kref_get(&parent->pgrp->ref, 1);
new_proc->pgrp = parent->pgrp;
- /* copy semantics on / and . (doesn't make a lot of sense in akaros o/w) */
+ /* copy semantics on / and . (doesn't make a lot of sense in akaros
+ * o/w). */
/* / should never disappear while we hold a ref to parent */
chan_incref(parent->slash);
new_proc->slash = parent->slash;
@@ -1545,7 +1562,8 @@
}
if (!devtab[c->type].chan_ctl)
- error(EINVAL, "%s has no chan_ctl, can't %d", chan_dev_name(c), cmd);
+ error(EINVAL, "%s has no chan_ctl, can't %d", chan_dev_name(c),
+ cmd);
/* Some commands require 9ns support in addition to the device ctl. */
switch (cmd) {
@@ -1586,7 +1604,8 @@
contents = kmalloc(size, MEM_WAIT);
cpy_amt = kread_file(file, contents, size);
if (cpy_amt < 0) {
- printk("Error %d reading file %s\n", get_errno(), foc_to_name(file));
+ printk("Error %d reading file %s\n", get_errno(),
+ foc_to_name(file));
kfree(contents);
return 0;
}
@@ -1617,8 +1636,8 @@
}
if (fd < fdt->max_fdset) {
if (GET_BITMASK_BIT(fdt->open_fds->fds_bits, fd)) {
- /* while max_files and max_fdset might not line up, we should never
- * have a valid fdset higher than files */
+ /* while max_files and max_fdset might not line up, we
+ * should never have a valid fdset higher than files */
assert(fd < fdt->max_files);
retval = fdt->fd[fd].fd_chan;
if (incref)
@@ -1635,16 +1654,18 @@
int n;
struct file_desc *nfd, *ofd;
- /* Only update open_fds once. If currently pointing to open_fds_init, then
- * update it to point to a newly allocated fd_set with space for
+ /* Only update open_fds once. If currently pointing to open_fds_init,
+ * then update it to point to a newly allocated fd_set with space for
* NR_FILE_DESC_MAX */
- if (open_files->open_fds == (struct fd_set*)&open_files->open_fds_init) {
+ if (open_files->open_fds == (struct fd_set*)&open_files->open_fds_init)
+ {
open_files->open_fds = kzmalloc(sizeof(struct fd_set), 0);
memmove(open_files->open_fds, &open_files->open_fds_init,
sizeof(struct small_fd_set));
}
- /* Grow the open_files->fd array in increments of NR_OPEN_FILES_DEFAULT */
+ /* Grow the open_files->fd array in increments of NR_OPEN_FILES_DEFAULT
+ */
n = open_files->max_files + NR_OPEN_FILES_DEFAULT;
if (n > NR_FILE_DESC_MAX)
return -EMFILE;
@@ -1661,7 +1682,7 @@
open_files->max_files = n;
open_files->max_fdset = n;
- /* Only free the old one if it wasn't pointing to open_files->fd_array */
+ /* Only free the old one if it wasn't pointing to open_files->fd_array*/
if (ofd != open_files->fd_array)
kfree(ofd);
return 0;
@@ -1672,16 +1693,19 @@
{
void *free_me;
- if (open_files->open_fds != (struct fd_set*)&open_files->open_fds_init) {
+ if (open_files->open_fds != (struct fd_set*)&open_files->open_fds_init)
+ {
assert(open_files->fd != open_files->fd_array);
- /* need to reset the pointers to the internal addrs, in case we take a
- * look while debugging. 0 them out, since they have old data. our
- * current versions should all be closed. */
- memset(&open_files->open_fds_init, 0, sizeof(struct small_fd_set));
+ /* need to reset the pointers to the internal addrs, in case we
+ * take a look while debugging. 0 them out, since they have old
+ * data. our current versions should all be closed. */
+ memset(&open_files->open_fds_init, 0,
+ sizeof(struct small_fd_set));
memset(&open_files->fd_array, 0, sizeof(open_files->fd_array));
free_me = open_files->open_fds;
- open_files->open_fds = (struct fd_set*)&open_files->open_fds_init;
+ open_files->open_fds =
+ (struct fd_set*)&open_files->open_fds_init;
kfree(free_me);
free_me = open_files->fd;
@@ -1702,8 +1726,8 @@
spin_lock(&fdt->lock);
if (fd < fdt->max_fdset) {
if (GET_BITMASK_BIT(fdt->open_fds->fds_bits, fd)) {
- /* while max_files and max_fdset might not line up, we should never
- * have a valid fdset higher than files */
+ /* while max_files and max_fdset might not line up, we
+ * should never have a valid fdset higher than files */
assert(fd < fdt->max_files);
chan = fdt->fd[fd].fd_chan;
tap = fdt->fd[fd].fd_tap;
@@ -1733,23 +1757,25 @@
return -EINVAL;
if (open_files->closed)
return -EINVAL; /* won't matter, they are dying */
- if (must_use_low && GET_BITMASK_BIT(open_files->open_fds->fds_bits, low_fd))
+ if (must_use_low
+ && GET_BITMASK_BIT(open_files->open_fds->fds_bits, low_fd))
return -ENFILE;
if (low_fd > open_files->hint_min_fd)
update_hint = FALSE;
else
low_fd = open_files->hint_min_fd;
- /* Loop until we have a valid slot (we grow the fd_array at the bottom of
- * the loop if we haven't found a slot in the current array */
+ /* Loop until we have a valid slot (we grow the fd_array at the bottom
+ * of the loop if we haven't found a slot in the current array */
while (slot == -1) {
for (low_fd; low_fd < open_files->max_fdset; low_fd++) {
- if (GET_BITMASK_BIT(open_files->open_fds->fds_bits, low_fd))
+ if (GET_BITMASK_BIT(open_files->open_fds->fds_bits,
+ low_fd))
continue;
slot = low_fd;
SET_BITMASK_BIT(open_files->open_fds->fds_bits, slot);
assert(slot < open_files->max_files &&
open_files->fd[slot].fd_chan == 0);
- /* We know slot >= hint, since we started with the hint */
+ /* We know slot >= hint, since we started with hint */
if (update_hint)
open_files->hint_min_fd = slot + 1;
break;
@@ -1813,8 +1839,8 @@
}
for (int i = 0; i < fdt->max_fdset; i++) {
if (GET_BITMASK_BIT(fdt->open_fds->fds_bits, i)) {
- /* while max_files and max_fdset might not line up, we should never
- * have a valid fdset higher than files */
+ /* while max_files and max_fdset might not line up, we
+ * should never have a valid fdset higher than files */
assert(i < fdt->max_files);
if (cloexec && !(fdt->fd[i].fd_flags & FD_CLOEXEC))
continue;
@@ -1833,9 +1859,9 @@
fdt->closed = TRUE;
}
spin_unlock(&fdt->lock);
- /* We go through some hoops to close/decref outside the lock. Nice for not
- * holding the lock for a while; critical in case the decref/cclose sleeps
- * (it can) */
+ /* We go through some hoops to close/decref outside the lock. Nice for
+ * not holding the lock for a while; critical in case the decref/cclose
+ * sleeps (it can) */
for (int i = 0; i < idx; i++) {
cclose(to_close[i].fd_chan);
if (to_close[i].fd_tap)
@@ -1873,8 +1899,8 @@
}
for (int i = 0; i < src->max_fdset; i++) {
if (GET_BITMASK_BIT(src->open_fds->fds_bits, i)) {
- /* while max_files and max_fdset might not line up, we should never
- * have a valid fdset higher than files */
+ /* while max_files and max_fdset might not line up, we
+ * should never have a valid fdset higher than files */
assert(i < src->max_files);
chan = src->fd[i].fd_chan;
assert(i < dst->max_files && dst->fd[i].fd_chan == 0);
@@ -1899,7 +1925,8 @@
spin_unlock(&fdt->lock);
return -1;
}
- if ((fd < fdt->max_fdset) && GET_BITMASK_BIT(fdt->open_fds->fds_bits, fd))
+ if ((fd < fdt->max_fdset)
+ && GET_BITMASK_BIT(fdt->open_fds->fds_bits, fd))
ret = fdt->fd[fd].fd_flags;
spin_unlock(&fdt->lock);
if (ret == -1)
@@ -1918,7 +1945,8 @@
spin_unlock(&fdt->lock);
return -1;
}
- if ((fd < fdt->max_fdset) && GET_BITMASK_BIT(fdt->open_fds->fds_bits, fd))
+ if ((fd < fdt->max_fdset)
+ && GET_BITMASK_BIT(fdt->open_fds->fds_bits, fd))
fdt->fd[fd].fd_flags = new_fl;
spin_unlock(&fdt->lock);
if (ret == -1)
diff --git a/kern/src/ns/tokenize.c b/kern/src/ns/tokenize.c
index 50f97f5..9ceac6a 100644
--- a/kern/src/ns/tokenize.c
+++ b/kern/src/ns/tokenize.c
@@ -47,7 +47,8 @@
quoting = 0;
t = s; /* s is output string, t is input string */
- while (*t != '\0' && (quoting || /*utfrune */ strchr(qsep, *t) == NULL)) {
+ while (*t != '\0' && (quoting || /*utfrune */ strchr(qsep, *t) == NULL))
+ {
if (*t != '\'') {
*s++ = *t++;
continue;
diff --git a/kern/src/ns/tree_file.c b/kern/src/ns/tree_file.c
index a630163..16e0b3a 100644
--- a/kern/src/ns/tree_file.c
+++ b/kern/src/ns/tree_file.c
@@ -93,10 +93,10 @@
}
cleanup_fs_file((struct fs_file*)tf);
kfree(tf);
- /* the reason for decreffing the parent now is for convenience on releasing.
- * When we unlink the child from the LRU pruner, we don't want to release
- * the parent immediately while we hold the parent's qlock (and other
- * locks). */
+ /* the reason for decreffing the parent now is for convenience on
+ * releasing. When we unlink the child from the LRU pruner, we don't
+ * want to release the parent immediately while we hold the parent's
+ * qlock (and other locks). */
if (parent)
tf_kref_put(parent);
}
@@ -122,16 +122,17 @@
return;
}
if (!(tf->flags & (TF_F_DISCONNECTED | TF_F_IS_ROOT))) {
- /* It's possible that we paused before locking, then another thread
- * upped, downed, and put it on the LRU list already. The helper deals
- * with that. */
+ /* It's possible that we paused before locking, then another
+ * thread upped, downed, and put it on the LRU list already.
+ * The helper deals with that. */
__add_to_lru(tf);
spin_unlock(&tf->lifetime);
return;
}
spin_unlock(&tf->lifetime);
- /* Need RCU, since we could have had a reader who saw the object and still
- * needs to try to kref (and fail). call_rcu, since we can't block. */
+ /* Need RCU, since we could have had a reader who saw the object and
+ * still needs to try to kref (and fail). call_rcu, since we can't
+ * block. */
call_rcu(&tf->rcu, __tf_free_rcu);
}
@@ -178,15 +179,16 @@
bucket = &wc->ht[hash_val % wc->hh.nr_hash_bits];
hlist_for_each_entry_rcu(i, bucket, hash) {
- /* Note 'i' is an rcu protected pointer. That deref is safe. i->parent
- * is also a pointer that in general we want to protect. In this case,
- * even though we don't dereference it, we want a pointer that is good
- * enough to dereference so we can do the comparison. */
+ /* Note 'i' is an rcu protected pointer. That deref is safe.
+ * i->parent is also a pointer that in general we want to
+ * protect. In this case, even though we don't dereference it,
+ * we want a pointer that is good enough to dereference so we
+ * can do the comparison. */
if (rcu_dereference(i->parent) != parent)
continue;
- /* The file's name should never change while it is in the table, so no
- * need for a seq-reader. Can't assert though, since there are valid
- * reasons for other seq lockers. */
+ /* The file's name should never change while it is in the table,
+ * so no need for a seq-reader. Can't assert though, since
+ * there are valid reasons for other seq lockers. */
if (!strcmp(tree_file_to_name(i), name))
return i;
}
@@ -200,11 +202,11 @@
unsigned long hash_val = hash_string(tree_file_to_name(child));
struct hlist_head *bucket;
- assert(child->parent == parent); /* catch bugs from our callers */
- /* TODO: consider bucket locks and/or growing the HT. Prob need a seq_ctr
- * in the WC, used on the read side during resizing. Removal probably would
- * need something other than the bucket lock too (confusion about which
- * bucket during the op). */
+ assert(child->parent == parent); /* catch bugs from our callers */
+ /* TODO: consider bucket locks and/or growing the HT. Prob need a
+ * seq_ctr in the WC, used on the read side during resizing. Removal
+ * probably would need something other than the bucket lock too
+ * (confusion about which bucket during the op). */
spin_lock(&wc->ht_lock);
bucket = &wc->ht[hash_val % wc->hh.nr_hash_bits];
hlist_add_head_rcu(&child->hash, bucket);
@@ -216,7 +218,7 @@
{
struct walk_cache *wc = &parent->tfs->wc;
- assert(child->parent == parent); /* catch bugs from our callers */
+ assert(child->parent == parent); /* catch bugs from our callers */
spin_lock(&wc->ht_lock);
hlist_del_rcu(&child->hash);
spin_unlock(&wc->ht_lock);
@@ -254,9 +256,9 @@
if (!parent)
return NULL;
qlock(&parent->file.qlock);
- /* Checking the parent == child->parent isn't enough here. That works for
- * rename, but not removal/unlink. Older versions of TF code cleared
- * child->parent, but now that's dealt with in tf_free.
+ /* Checking the parent == child->parent isn't enough here. That works
+ * for rename, but not removal/unlink. Older versions of TF code
+ * cleared child->parent, but now that's dealt with in tf_free.
*
* We're doing a lockless peek at child's flags. We hold the potential
* parent's lock, so if they are ours, no one will be messing with the
@@ -313,8 +315,8 @@
fs_file_init((struct fs_file*)tf, name, &tfs->fs_ops);
kref_init(&tf->kref, tf_release, 0);
spinlock_init(&tf->lifetime);
- /* Need to set the parent early on, even if the child isn't linked yet, so
- * that the TFS ops know who the parent is. */
+ /* Need to set the parent early on, even if the child isn't linked yet,
+ * so that the TFS ops know who the parent is. */
tf->parent = parent;
if (parent)
kref_get(&parent->kref, 1);
@@ -327,12 +329,12 @@
/* Callers must hold the parent's qlock. */
static void __link_child(struct tree_file *parent, struct tree_file *child)
{
- /* Devices may have already increffed ("+1 for existing"). Those that don't
- * need to be on the LRU. We haven't linked to the parent yet, so we hold
- * the only ref. Once we unlock in __add_to_lru, we're discoverable via
- * that list, even though we're not linked. The lru pruner is careful to
- * not muck with the parent's or wc linkage without qlocking the parent,
- * which we currently hold. */
+ /* Devices may have already increffed ("+1 for existing"). Those that
+ * don't need to be on the LRU. We haven't linked to the parent yet, so
+ * we hold the only ref. Once we unlock in __add_to_lru, we're
+ * discoverable via that list, even though we're not linked. The lru
+ * pruner is careful to not muck with the parent's or wc linkage without
+ * qlocking the parent, which we currently hold. */
if (kref_refcnt(&child->kref) == 0)
__add_to_lru(child);
/* This was set in tree_file_alloc */
@@ -353,7 +355,7 @@
continue;
spin_lock(&child->lifetime);
assert(kref_refcnt(&child->kref) == 0);
- /* This mark prevents new lookups. We'll disconnect it shortly. */
+ /* This mark prevents new lookups; will disconnect it shortly */
child->flags |= TF_F_DISCONNECTED;
spin_unlock(&child->lifetime);
assert(child->parent == dir);
@@ -369,8 +371,8 @@
error(ENOTEMPTY, "can't remove dir with children");
}
dir->can_have_children = false;
- /* Even if we don't have real children, we might have some negatives. Those
- * aren't a reason to abort an rmdir, we just need to drop them. */
+ /* Even if we don't have real children, we might have some negatives.
+ * Those aren't a reason to abort an rmdir, we just need to drop them.*/
__prune_dir_negatives(dir);
qunlock(&dir->file.qlock);
}
@@ -383,8 +385,8 @@
static void __unlink_child(struct tree_file *parent, struct tree_file *child)
{
/* Need to make sure concurrent creates/renames do not add children to
- * directories that are unlinked. Note we don't undo the neutering if the
- * backend fails. */
+ * directories that are unlinked. Note we don't undo the neutering if
+ * the backend fails. */
if (tree_file_is_dir(child))
neuter_directory(child);
/* The ramfs backend will probably decref the "+1 for existing" ref.
@@ -414,8 +416,8 @@
qlock(&parent->file.qlock);
child = wc_lookup_child(parent, name);
if (child) {
- /* Since we last looked, but before we qlocked, someone else added our
- * entry. */
+ /* Since we last looked, but before we qlocked, someone else
+ * added our entry. */
rcu_read_lock();
qunlock(&parent->file.qlock);
return child;
@@ -426,8 +428,9 @@
}
child = tree_file_alloc(parent->tfs, parent, name);
if (waserror()) {
- /* child wasn't fully created, so freeing it may be tricky, esp on the
- * device ops side (might see something they never created). */
+ /* child wasn't fully created, so freeing it may be tricky, esp
+ * on the device ops side (might see something they never
+ * created). */
__tf_free(child);
qunlock(&parent->file.qlock);
nexterror();
@@ -462,19 +465,19 @@
wq = kzmalloc(sizeof(struct walkqid) + nname * sizeof(struct qid),
MEM_WAIT);
/* A walk with zero names means "make me a copy." If we go through the
- * regular walker, our usual tf_kref_get will fail - similar to failing if
- * we got a walk for "foo/../" during a concurrent removal of ourselves.
- * We'll let a walk of zero names work, but if you provide any names, the
- * actual walk must happen.
+ * regular walker, our usual tf_kref_get will fail - similar to failing
+ * if we got a walk for "foo/../" during a concurrent removal of
+ * ourselves. We'll let a walk of zero names work, but if you provide
+ * any names, the actual walk must happen.
*
- * This is tricky, and confused me a little. We're returning a *TF* through
- * wq->clone, not a chan, and that is refcounted. Normally for chans that
- * end up with wq->clone == c, we do not incref the object hanging off the
- * chan (see k/d/d/eventfd.c), since there is just one chan with a kreffed
- * object hanging off e.g. c->aux. But here, wq->clone is considered a
- * distinct refcnt to some TF, and it might be 'from.' Our *caller* needs
- * to deal with the "wq->clone == from_chan", since they deal with chans.
- * We deal with tree files. */
+ * This is tricky, and confused me a little. We're returning a *TF*
+ * through wq->clone, not a chan, and that is refcounted. Normally for
+ * chans that end up with wq->clone == c, we do not incref the object
+ * hanging off the chan (see k/d/d/eventfd.c), since there is just one
+ * chan with a kreffed object hanging off e.g. c->aux. But here,
+ * wq->clone is considered a distinct refcnt to some TF, and it might be
+ * 'from.' Our *caller* needs to deal with the "wq->clone ==
+ * from_chan", since they deal with chans. We deal with tree files. */
if (!nname) {
kref_get(&from->kref, 1);
wq->clone = (struct chan*)from;
@@ -488,24 +491,26 @@
rcu_read_lock();
at = from;
for (int i = 0; i < nname; i++) {
- /* Walks end if we reach a regular file, i.e. you can't walk through a
- * file, only a dir. But even if there are more names, the overall walk
- * might succeed. E.g. a directory could be mounted on top of the
- * current file we're at. That's just not our job. */
+ /* Walks end if we reach a regular file, i.e. you can't walk
+ * through a file, only a dir. But even if there are more
+ * names, the overall walk might succeed. E.g. a directory
+ * could be mounted on top of the current file we're at. That's
+ * just not our job. */
if (tree_file_is_file(at)) {
if (i == 0)
error(ENOTDIR, "initial walk from a file");
break;
}
- /* Normally, symlinks stop walks, and namec's walk() will deal with it.
- * We allow walks 'through' symlinks, but only for .. and only for the
- * first name. This is for relative lookups so we can find the parent
- * of a symlink. */
+ /* Normally, symlinks stop walks, and namec's walk() will deal
+ * with it. We allow walks 'through' symlinks, but only for ..
+ * and only for the first name. This is for relative lookups so
+ * we can find the parent of a symlink. */
if (tree_file_is_symlink(at)) {
if (i != 0)
break;
if (strcmp(name[i], ".."))
- error(ELOOP, "walk from a symlink that wasn't ..");
+ error(ELOOP,
+ "walk from a symlink that wasn't ..");
}
if (!caller_has_tf_perms(at, O_READ)) {
if (i == 0)
@@ -520,30 +525,37 @@
next = rcu_dereference(at->parent);
if (!next) {
if (tree_file_is_root(at)) {
- wq->qid[wq->nqid++] = tree_file_to_qid(at);
- /* I think namec should never give us DOTDOT that isn't at
- * the end of the names array. Though devwalk() seems to
- * expect it. */
+ wq->qid[wq->nqid++] =
+ tree_file_to_qid(at);
+ /* I think namec should never give us
+ * DOTDOT that isn't at the end of the
+ * names array. Though devwalk() seems
+ * to expect it. */
if (i != nname - 1)
- warn("Possible namec DOTDOT bug, call for help!");
+ warn("namec DOTDOT bug?");
continue;
}
- /* We lost our parent due to a removal/rename. We might have
- * walked enough for our walk to succeed (e.g. there's a mount
- * point in the WQ), so we can return what we have. Though if
- * we've done nothing, it's a failure.
+ /* We lost our parent due to a removal/rename.
+ * We might have walked enough for our walk to
+ * succeed (e.g. there's a mount point in the
+ * WQ), so we can return what we have. Though
+ * if we've done nothing, it's a failure.
*
- * Note the removal could have happened a long time ago:
- * consider an O_PATH open, then namec_from().
+ * Note the removal could have happened a long
+ * time ago: consider an O_PATH open, then
+ * namec_from().
*
- * We also could walk up and see the *new* parent during
- * rename(). For instance, /src/x/../y could get the old /src/y
- * or the new /dst/y. If we want to avoid that, then we'll need
- * some sort of sync with rename to make sure we don't get the
- * new one. Though this can happen with namec_from(), so I'm
- * not sure I care. */
+ * We also could walk up and see the *new*
+ * parent during rename(). For instance,
+ * /src/x/../y could get the old /src/y or the
+ * new /dst/y. If we want to avoid that, then
+ * we'll need some sort of sync with rename to
+ * make sure we don't get the new one. Though
+ * this can happen with namec_from(), so I'm not
+ * sure I care. */
if (i == 0)
- error(ENOENT, "file lost its parent during lookup");
+ error(ENOENT,
+ "file lost its parent during lookup");
break;
}
at = next;
@@ -552,46 +564,51 @@
}
next = wc_lookup_child(at, name[i]);
if (!next) {
- /* TFSs with no backend have the entire tree in the WC HT. */
+ /* TFSs with no backend have the entire tree in the WC
+ * HT. */
if (!tfs->tf_ops.lookup) {
if (i == 0)
error(ENOENT, "file does not exist");
break;
}
- /* Need to hold a kref on 'at' before we rcu_read_unlock(). Our
- * TFS op might block. */
+ /* Need to hold a kref on 'at' before we
+ * rcu_read_unlock(). Our TFS op might block. */
if (!tf_kref_get(at)) {
if (i == 0)
- error(ENOENT, "file was removed during lookup");
- /* WQ has a qid for 'at' from a previous loop. We can't grab a
- * ref, so it's being removed/renamed. Yet it's still OK to
- * report this as part of the wq, since we could fail for other
- * reasons (thus not getting nnames) and have the same race,
- * which we handle below (i.e. we only get a ref when it was the
- * last name). Here we're just *noticing* the race. */
+ error(ENOENT,
+ "file was removed during lookup");
+ /* WQ has a qid for 'at' from a previous loop.
+ * We can't grab a ref, so it's being
+ * removed/renamed. Yet it's still OK to report
+ * this as part of the wq, since we could fail
+ * for other reasons (thus not getting nnames)
+ * and have the same race, which we handle below
+ * (i.e. we only get a ref when it was the last
+ * name). Here we're just *noticing* the race.
+ */
break;
}
rcu_read_unlock();
- /* propagate the error only on the first name. Note we run the
- * 'else' case, and run the poperror case for non-errors and
- * non-name=0-errors. */
+ /* propagate the error only on the first name. Note we
+ * run the 'else' case, and run the poperror case for
+ * non-errors and non-name=0-errors. */
if (waserror()) {
tf_kref_put(at);
if (i == 0)
nexterror();
- /* In this case, we're discarding the waserror, same as in the
- * other i != 0 cases. */
+ /* In this case, we're discarding the waserror,
+ * same as in the other i != 0 cases. */
poperror();
break;
}
- /* This returns with an rcu_read_lock protecting 'next' */
+ /* returns with an rcu_read_lock protecting 'next' */
next = lookup_child_entry(at, name[i]);
tf_kref_put(at);
poperror();
assert(next);
}
if (tree_file_is_negative(next)) {
- /* lockless peek. other flag users aren't atomic, etc. */
+ /* lockless peek. other flag users aren't atomic. */
if (!(next->flags & TF_F_HAS_BEEN_USED)) {
spin_lock(&next->lifetime);
next->flags |= TF_F_HAS_BEEN_USED;
@@ -606,13 +623,13 @@
}
if (wq->nqid == nname || tree_file_is_symlink(at)) {
if (!tf_kref_get(at)) {
- /* We need to undo our last result as if we never saw it. */
+ /* need to undo our last result as if we never saw it.*/
wq->nqid--;
if (wq->nqid == 0)
error(ENOENT, "file was removed during lookup");
} else {
- /* Hanging the refcounted TF off the wq->clone, which is cheating.
- * Our walker shim knows to expect this. */
+ /* Hanging the refcounted TF off the wq->clone, which is
+ * cheating. Our walker shim knows to expect this. */
wq->clone = (struct chan*)at;
}
}
@@ -636,13 +653,15 @@
return wq;
if (!nc)
nc = devclone(c);
- /* Not sure if callers that specify nc must have a chan from our device */
+ /* Not sure if callers that specify nc must have a chan from our device.
+ */
assert(nc->type == c->type);
to = (struct tree_file*)wq->clone;
nc->qid = tree_file_to_qid(to);
chan_set_tree_file(nc, to);
wq->clone = nc;
- /* We might be returning the same chan, so there's actually just one ref */
+ /* We might be returning the same chan, so there's actually just one
+ * ref. */
if (wq->clone == c)
tf_kref_put(chan_to_tree_file(c));
return wq;
@@ -669,13 +688,13 @@
error(ENOENT, "create failed, parent dir being removed");
child = wc_lookup_child(parent, name);
if (child) {
- /* The create(5) message fails if the file exists, which differs from
- * the syscall. namec() handles this. */
+ /* The create(5) message fails if the file exists, which differs
+ * from the syscall. namec() handles this. */
if (!tree_file_is_negative(child))
error(EEXIST, "file exists");
- /* future lookups that find no entry will qlock. concurrent ones that
- * see the child, even if disconnected, will see it was negative and
- * fail. */
+ /* future lookups that find no entry will qlock. concurrent
+ * ones that see the child, even if disconnected, will see it
+ * was negative and fail. */
__disconnect_child(parent, child);
}
child = tree_file_alloc(parent->tfs, parent, name);
@@ -683,8 +702,8 @@
__tf_free(child);
nexterror();
}
- /* Backend will need to know the ext for its create. This gets cleaned up
- * on error. */
+ /* Backend will need to know the ext for its create. This gets cleaned
+ * up on error. */
if (perm & DMSYMLINK)
kstrdup(&child->file.dir.ext, ext);
/* Backend will need to fill in dir, except for name. */
@@ -696,7 +715,7 @@
/* At this point, the child is visible, so it must be ready to go */
__link_child(parent, child);
got_ref = tf_kref_get(child);
- assert(got_ref); /* we hold the qlock, no one should have removed */
+ assert(got_ref); /* we hold the qlock, no one should have removed */
__set_acmtime_to(&parent->file, FSF_CTIME | FSF_MTIME, &now);
qunlock(&parent->file.qlock);
poperror();
@@ -726,9 +745,10 @@
if (c->qid.type & QTSYMLINK)
error(ELOOP, "can't open a symlink");
tree_file_perm_check(tf, omode);
- /* TODO: if we want to support DMEXCL on dir.mode, we'll need to lock/sync
- * on the fs_file (have a flag for FSF_IS_OPEN, handle in close). We'll
- * also need a way to pass it in to the dir.mode during create/wstat/etc. */
+ /* TODO: if we want to support DMEXCL on dir.mode, we'll need to
+ * lock/sync on the fs_file (have a flag for FSF_IS_OPEN, handle in
+ * close). We'll also need a way to pass it in to the dir.mode during
+ * create/wstat/etc. */
if (omode & O_TRUNC)
fs_file_truncate(&tf->file, 0);
c->mode = openmode(omode);
@@ -771,9 +791,9 @@
ERRSTACK(1);
struct tree_file *tf = chan_to_tree_file(c);
- /* sysremove expects a chan that is disconnected from the device, regardless
- * of whether or not we fail. See sysremove(); it will clear type, ensuring
- * our close is never called. */
+ /* sysremove expects a chan that is disconnected from the device,
+ * regardless of whether or not we fail. See sysremove(); it will clear
+ * type, ensuring our close is never called. */
if (waserror()) {
chan_set_tree_file(c, NULL);
tf_kref_put(tf); /* The ref from the original walk */
@@ -843,9 +863,9 @@
old_parent = __tf_get_potential_parent(tf);
if (!old_parent)
error(ENOENT, "renamed file had no parent");
- /* global mtx helps with a variety of weird races, including the "can't move
- * to a subdirectory of yourself" case and the lock ordering of parents
- * (locks flow from parent->child). */
+ /* global mtx helps with a variety of weird races, including the "can't
+ * move to a subdirectory of yourself" case and the lock ordering of
+ * parents (locks flow from parent->child). */
qlock(&tf->tfs->rename_mtx);
qlock_tree_files(old_parent, new_parent);
if (waserror()) {
@@ -874,38 +894,42 @@
if (tree_file_is_dir(prev_dst)) {
if (!tree_file_is_dir(tf))
error(EISDIR, "can't rename a file onto a dir");
- /* We need to ensure prev_dst is childless and remains so. That
- * requires grabbing its qlock, but there's a potential lock
- * ordering issue with old_parent. We could have this:
- * new_parent/dst/x/y/z/old_parent/src. That will fail, but we need
- * to check for that case instead of grabbing prev_dst's qlock. */
+ /* We need to ensure prev_dst is childless and remains
+ * so. That requires grabbing its qlock, but there's a
+ * potential lock ordering issue with old_parent. We
+ * could have this: new_parent/dst/x/y/z/old_parent/src.
+ * That will fail, but we need to check for that case
+ * instead of grabbing prev_dst's qlock. */
if (is_descendant_of(prev_dst, old_parent))
- error(ENOTEMPTY, "old_parent descends from dst");
+ error(ENOTEMPTY,
+ "old_parent descends from dst");
neuter_directory(prev_dst);
} else {
if (tree_file_is_dir(tf))
- error(ENOTDIR, "can't rename a dir onto a file");
+ error(ENOTDIR,
+ "can't rename a dir onto a file");
}
}
- /* We check with the backend first, so that it has a chance to fail early.
- * Once we make the changes to the front end, lookups can see the effects of
- * the change, which we can't roll back. Since we hold the parents' qlocks,
- * no one should be able to get the info from the backend either (lookups
- * that require the backend, readdir, etc). */
+ /* We check with the backend first, so that it has a chance to fail
+ * early. Once we make the changes to the front end, lookups can see
+ * the effects of the change, which we can't roll back. Since we hold
+ * the parents' qlocks, no one should be able to get the info from the
+ * backend either (lookups that require the backend, readdir, etc). */
tf->tfs->tf_ops.rename(tf, old_parent, new_parent, name, flags);
- /* Similar to __disconnect_child, we don't clear tf->parent. rcu readers at
- * TF will be able to walk up (with ..). Same with namec_from an FD. If we
- * atomically replace tf->parent, we should be good. See tree_file_walk().
+ /* Similar to __disconnect_child, we don't clear tf->parent. rcu
+ * readers at TF will be able to walk up (with ..). Same with
+ * namec_from an FD. If we atomically replace tf->parent, we should be
+ * good. See tree_file_walk().
*
- * Further, we don't mark the tf disconnected. Someone might lookup from
- * the old location, and that's fine. We just don't want issues with
- * decrefs. */
+ * Further, we don't mark the tf disconnected. Someone might lookup
+ * from the old location, and that's fine. We just don't want issues
+ * with decrefs. */
__remove_from_parent_list(old_parent, tf);
wc_remove_child(old_parent, tf);
synchronize_rcu();
- /* Now, no new lookups will find it at the old location. That change is not
- * atomic wrt src, but it will be wrt dst. Importantly, no one will see
- * /path/to/old_parent/new_basename */
+ /* Now, no new lookups will find it at the old location. That change is
+ * not atomic wrt src, but it will be wrt dst. Importantly, no one will
+ * see /path/to/old_parent/new_basename */
fs_file_change_basename((struct fs_file*)tf, name);
/* We're clobbering the old_parent ref, which we'll drop later */
rcu_assign_pointer(tf->parent, new_parent);
@@ -913,37 +937,38 @@
__add_to_parent_list(new_parent, tf);
wc_insert_child(new_parent, tf);
/* Now both the prev_dst (if it existed) or the tf file are in the walk
- * cache / HT and either could have been looked up by a concurrent reader.
- * Readers will always get one or the other, but never see nothing. This is
- * the atomic guarantee of rename. */
+ * cache / HT and either could have been looked up by a concurrent
+ * reader. Readers will always get one or the other, but never see
+ * nothing. This is the atomic guarantee of rename. */
if (prev_dst) {
__remove_from_parent_list(new_parent, prev_dst);
wc_remove_child(new_parent, prev_dst);
synchronize_rcu();
- /* Now no one can find prev_dst. Someone might still have a ref, or it
- * might be on the LRU list (if kref == 0). Now we can mark
- * disconnected. Had we disconnected earlier, then lookup code would
- * see that and treat it as a failure. Using rcu and putting the
- * complexity in rename was easier and simpler than changing lookup.
+ /* Now no one can find prev_dst. Someone might still have a
+ * ref, or it might be on the LRU list (if kref == 0). Now we
+ * can mark disconnected. Had we disconnected earlier, then
+ * lookup code would see that and treat it as a failure. Using
+ * rcu and putting the complexity in rename was easier and
+ * simpler than changing lookup.
*
- * We still need RCU here for freeing the prev_dst. We could have had
- * an LRU pruner, etc, looking. The synchronize_rcu above only dealt
- * with lookups via parent in this function. */
+ * We still need RCU here for freeing the prev_dst. We could
+ * have had an LRU pruner, etc, looking. The synchronize_rcu
+ * above only dealt with lookups via parent in this function. */
if (__mark_disconnected(prev_dst))
call_rcu(&prev_dst->rcu, __tf_free_rcu);
}
now = nsec2timespec(epoch_nsec());
__set_acmtime_to(&old_parent->file, FSF_CTIME | FSF_MTIME, &now);
__set_acmtime_to(&new_parent->file, FSF_CTIME | FSF_MTIME, &now);
- /* Can we unlock earlier? No. We need to at least hold new_parent's qlock,
- * which was the parent of old_dst, until old_dst is marked disconnected.
- * Even though old_dst is removed from new_parent's HT, it is still in the
- * LRU list. */
+ /* Can we unlock earlier? No. We need to at least hold new_parent's
+ * qlock, which was the parent of old_dst, until old_dst is marked
+ * disconnected. Even though old_dst is removed from new_parent's HT,
+ * it is still in the LRU list. */
qunlock_tree_files(old_parent, new_parent);
qunlock(&tf->tfs->rename_mtx);
poperror();
- tf_kref_put(old_parent); /* the original tf->parent ref we clobbered */
- tf_kref_put(old_parent); /* the one we grabbed when we started */
+ tf_kref_put(old_parent); /* the original tf->parent ref we clobbered */
+ tf_kref_put(old_parent); /* the one we grabbed when we started */
}
void tree_chan_rename(struct chan *c, struct chan *new_p_c, const char *name,
@@ -1033,10 +1058,10 @@
{
struct fs_file *f = &chan_to_tree_file(c)->file;
- /* TODO: In the future, we'll check the prot, establish hooks with the VMR,
- * and other things, mostly in something like fs_file_mmap, which will be
- * able to handle mmaping something that doesn't use the page cache. For
- * now, I'm aggressively qlocking to catch bugs. */
+ /* TODO: In the future, we'll check the prot, establish hooks with the
+ * VMR, and other things, mostly in something like fs_file_mmap, which
+ * will be able to handle mmaping something that doesn't use the page
+ * cache. For now, I'm aggressively qlocking to catch bugs. */
qlock(&f->qlock);
if ((prot & PROT_WRITE) && (flags & MAP_SHARED))
f->flags |= FSF_DIRTY;
@@ -1051,13 +1076,14 @@
switch (op) {
case CCTL_DEBUG:
print_lock();
- printk("Dumping tree_file info (frontend), dev %s, chan %s:\n\n",
+ printk("Dumping tree_file info (frontend), dev %s chan %s:\n\n",
chan_dev_name(c), channame(c));
__tfs_dump_tf(chan_to_tree_file(c));
print_unlock();
return 0;
default:
- error(EINVAL, "%s does not support chanctl %d", chan_dev_name(c), op);
+ error(EINVAL, "%s does not support chanctl %d",
+ chan_dev_name(c), op);
}
}
@@ -1104,17 +1130,17 @@
if (tree_file_is_dir(tf)) {
qlock(&tf->file.qlock);
/* Note we don't have a kref on our child's TF - we have a weak
- * reference (the list membership). We hold the parent's qlock, which
- * prevents removal/unlinking/disconnecting/etc. The child's membership
- * on the LRU list can change repeatedly.
+ * reference (the list membership). We hold the parent's qlock,
+ * which prevents removal/unlinking/disconnecting/etc. The
+ * child's membership on the LRU list can change repeatedly.
*
- * If we want to avoid holding the parent's qlock, we could grab a kref
- * on the child. However, our list walk would be in jeopardy - both
- * child and temp could be removed from the list. So we'd need to qlock
- * the parent, grab krefs on all children, and put them on a local list.
- * Also, grabbing krefs on our children will muck with the LRU list;
- * when we're done, it would be like we sorted the LRU list in the DFS
- * order. */
+ * If we want to avoid holding the parent's qlock, we could grab
+ * a kref on the child. However, our list walk would be in
+ * jeopardy - both child and temp could be removed from the
+ * list. So we'd need to qlock the parent, grab krefs on all
+ * children, and put them on a local list. Also, grabbing krefs
+ * on our children will muck with the LRU list; when we're done,
+ * it would be like we sorted the LRU list in the DFS order. */
list_for_each_entry(child, &tf->children, siblings)
tf_dfs_cb(child, cb);
qunlock(&tf->file.qlock);
@@ -1150,17 +1176,19 @@
if (tree_file_is_dir(tf)) {
qlock(&tf->file.qlock);
- /* Note we don't have a kref on TF, and one of our children should
- * decref *us* to 0. We aren't disconnected yet, and we can't be
- * removed (parent's qlock is held), so we'll just end up on the LRU
- * list, which is OK.
+ /* Note we don't have a kref on TF, and one of our children
+ * should decref *us* to 0. We aren't disconnected yet, and we
+ * can't be removed (parent's qlock is held), so we'll just end
+ * up on the LRU list, which is OK.
*
- * Our child should remove itself from our list, so we need the _safe.
+ * Our child should remove itself from our list, so we need the
+ * _safe.
*
- * Also note that the child decrefs us in a call_rcu. CB can block, and
- * technically so can qlock, so we might run RCU callbacks while
- * qlocked. We'll need to rcu_barrier so that our children's decrefs
- * occur before we remove ourselves from our parent. */
+ * Also note that the child decrefs us in a call_rcu. CB can
+ * block, and technically so can qlock, so we might run RCU
+ * callbacks while qlocked. We'll need to rcu_barrier so that
+ * our children's decrefs occur before we remove ourselves from
+ * our parent. */
list_for_each_entry_safe(child, temp, &tf->children, siblings)
tf_dfs_purge(child, cb);
qunlock(&tf->file.qlock);
@@ -1170,8 +1198,8 @@
if (!tree_file_is_negative(tf))
cb(tf);
spin_lock(&tf->lifetime);
- /* should be unused, with no children. we have a ref on root, to keep the
- * TFS around while we destroy the tree. */
+ /* should be unused, with no children. we have a ref on root, to keep
+ * the TFS around while we destroy the tree. */
assert(kref_refcnt(&tf->kref) == 0 || tree_file_is_root(tf));
/* This mark prevents new lookups. We'll disconnect it shortly. */
tf->flags |= TF_F_DISCONNECTED;
@@ -1210,8 +1238,9 @@
tf->file.dir.qid.path,
kref_refcnt(&tf->kref),
tf->file.dir.uid,
- tree_file_is_dir(tf) ? 'd' :
- tf->file.dir.mode & DMSYMLINK ? 'l' : '-',
+ tree_file_is_dir(tf) ? 'd'
+ : tf->file.dir.mode & DMSYMLINK ? 'l'
+ : '-',
tf->file.dir.mode & S_PMASK,
tf->file.dir.mode & DMSYMLINK ? tf->file.dir.ext : ""
);
@@ -1271,14 +1300,16 @@
struct tree_file *tf, *temp, *parent;
size_t nr_tfs = 0;
- /* We can have multiple LRU workers in flight, though a given TF will be on
- * only one CB list at a time. */
+ /* We can have multiple LRU workers in flight, though a given TF will be
+ * on only one CB list at a time. */
spin_lock(&wc->lru_lock);
list_for_each_entry_safe(tf, temp, &wc->lru, lru) {
- /* lockless peak at the flag. once it's NEGATIVE, it never goes back */
+ /* lockless peak at the flag. once it's NEGATIVE, it never goes
+ * back */
if (tree_file_is_negative(tf))
continue;
- /* Normal lock order is TF -> LRU. Best effort is fine for LRU. */
+ /* Normal lock order is TF -> LRU.
+ * Best effort is fine for LRU. */
if (!spin_trylock(&tf->lifetime))
continue;
/* Can't be disconnected and on LRU */
@@ -1287,9 +1318,9 @@
tf->flags &= ~TF_F_ON_LRU;
list_del(&tf->lru);
__kref_get(&tf->kref, 1);
- /* The 'used' bit is the what allows us to detect a user in between our
- * callback and the disconnection/freeing. It's a moot point if the CB
- * returns false. */
+ /* The 'used' bit is the what allows us to detect a user in
+ * between our callback and the disconnection/freeing. It's a
+ * moot point if the CB returns false. */
tf->flags &= ~TF_F_HAS_BEEN_USED;
spin_unlock(&tf->lifetime);
list_add_tail(&tf->lru, &work);
@@ -1299,9 +1330,9 @@
spin_unlock(&wc->lru_lock);
/* We have a snapshot of the LRU list. As soon as we unlocked a file,
- * someone could incref it (e.g. to something > 1), and they'll set the used
- * bit. That won't abort the CB. New TFs could be added to the LRU list.
- * Those are ignored for this pass. */
+ * someone could incref it (e.g. to something > 1), and they'll set the
+ * used bit. That won't abort the CB. New TFs could be added to the
+ * LRU list. Those are ignored for this pass. */
list_for_each_entry_safe(tf, temp, &work, lru) {
if (!cb(tf)) {
list_del(&tf->lru);
@@ -1310,8 +1341,8 @@
}
}
- /* Now we have a list of victims to be removed, so long as they haven't been
- * used since. */
+ /* Now we have a list of victims to be removed, so long as they haven't
+ * been used since. */
list_for_each_entry_safe(tf, temp, &work, lru) {
parent = get_locked_and_kreffed_parent(tf);
if (!parent) {
@@ -1329,20 +1360,21 @@
continue;
}
tf->flags |= TF_F_DISCONNECTED;
- /* We hold a ref, so it shouldn't have found its way back on LRU */
+ /* We hold a ref, so it shouldn't have found its way back on
+ * LRU. */
assert(!(tf->flags & TF_F_ON_LRU));
spin_unlock(&tf->lifetime);
__remove_from_parent_list(parent, tf);
wc_remove_child(parent, tf);
- /* If we get tired of unlocking and relocking, we could see if the next
- * parent is the current parent before unlocking. */
+ /* If we get tired of unlocking and relocking, we could see if
+ * the next parent is the current parent before unlocking. */
qunlock(&parent->file.qlock);
tf_kref_put(parent);
}
- /* Now we have a list of refs that are all disconnected, kref == 1 (because
- * no one used them since we increffed them when they were LRU, which was
- * when the refcnt was 0). Each TF has a ref on its parent btw, so parents
- * will never be on the LRU list. (leaves only).
+ /* Now we have a list of refs that are all disconnected, kref == 1
+ * (because no one used them since we increffed them when they were LRU,
+ * which was when the refcnt was 0). Each TF has a ref on its parent
+ * btw, so parents will never be on the LRU list. (leaves only).
*
* We need to synchronize_rcu() too, since we could have had lockless
* lookups that have pointers to TF and are waiting to notice that it is
@@ -1351,8 +1383,9 @@
list_for_each_entry_safe(tf, temp, &work, lru) {
assert(kref_refcnt(&tf->kref) == 1);
list_del(&tf->lru);
- /* We could decref, but instead we can directly free. We know the ref
- * == 1 and it is disconnected. Directly freeing bypasses call_rcu. */
+ /* We could decref, but instead we can directly free. We know
+ * the ref == 1 and it is disconnected. Directly freeing
+ * bypasses call_rcu. */
__tf_free(tf);
}
}
@@ -1378,7 +1411,7 @@
spin_unlock(&tf->lifetime);
continue;
}
- rcu_read_lock(); /* holding a spinlock, but just to be clear. */
+ rcu_read_lock(); /* holding a spinlock, but just to be clear. */
parent = rcu_dereference(tf->parent);
/* Again, inverting the lock order, so best effort trylock */
if (!canqlock(&parent->file.qlock)) {
@@ -1389,8 +1422,9 @@
__remove_from_parent_list(parent, tf);
wc_remove_child(parent, tf);
qunlock(&parent->file.qlock);
- /* We're off the list, but our kref == 0 still. We can break that
- * invariant since we have the only ref and are about to free the TF. */
+ /* We're off the list, but our kref == 0 still. We can break
+ * that invariant since we have the only ref and are about to
+ * free the TF. */
tf->flags &= ~TF_F_ON_LRU;
list_del(&tf->lru);
spin_unlock(&tf->lifetime);
@@ -1402,8 +1436,8 @@
* (because they are negatives).
*
* We need to synchronize_rcu() too, since we could have had lockless
- * lookups that have pointers to TF, and they may even mark HAS_BEEN_USED.
- * Too late. */
+ * lookups that have pointers to TF, and they may even mark
+ * HAS_BEEN_USED. Too late. */
synchronize_rcu();
list_for_each_entry_safe(tf, temp, &work, lru) {
assert(kref_refcnt(&tf->kref) == 0);
diff --git a/kern/src/ns/util.c b/kern/src/ns/util.c
index 4946be4..682ebd6 100644
--- a/kern/src/ns/util.c
+++ b/kern/src/ns/util.c
@@ -25,6 +25,7 @@
unsigned long val, size_t size, const char *fmt)
{
char tmp[64];
+
size = MIN(sizeof(tmp), size);
/* we really need the %* format. */
size = snprintf(tmp, size, fmt, val);
@@ -77,6 +78,7 @@
[O_WRITE | O_EXEC] = 0300,
[O_WRITE] = 0200,
[O_EXEC] = 0100 };
+
return rwx_opts[open_flags & O_ACCMODE];
}
@@ -95,6 +97,7 @@
[O_READ] = 0,
[0] = 0 /* we can't express no permissions */
};
+
return acc_opts[open_flags & O_ACCMODE];
}
@@ -135,8 +138,8 @@
else
perm <<= 6;
/* translate omode into things like S_IRUSR (just one set of rwx------).
- * Plan 9 originally only returned 0400 0200 0600 and 0100 here; it didn't
- * seem to handle O_EXEC being mixed readable or writable. */
+ * Plan 9 originally only returned 0400 0200 0600 and 0100 here; it
+ * didn't seem to handle O_EXEC being mixed readable or writable. */
rwx = omode_to_rwx(omode);
return (rwx & perm) == rwx;
}
diff --git a/kern/src/pagemap.c b/kern/src/pagemap.c
index 5adbb8f..836d4c5 100644
--- a/kern/src/pagemap.c
+++ b/kern/src/pagemap.c
@@ -16,10 +16,10 @@
void pm_add_vmr(struct page_map *pm, struct vm_region *vmr)
{
- /* note that the VMR being reverse-mapped by the PM is protected by the PM's
- * lock. we clearly need a write lock here, but removal also needs a write
- * lock, so later when removal holds this, it delays munmaps and keeps the
- * VMR connected. */
+ /* note that the VMR being reverse-mapped by the PM is protected by the
+ * PM's lock. we clearly need a write lock here, but removal also needs
+ * a write lock, so later when removal holds this, it delays munmaps and
+ * keeps the VMR connected. */
spin_lock(&pm->pm_lock);
TAILQ_INSERT_TAIL(&pm->pm_vmrs, vmr, vm_pm_link);
spin_unlock(&pm->pm_lock);
@@ -106,16 +106,17 @@
void *old_slot_val, *slot_val;
struct page *page = 0;
- /* We use rcu to protect our radix walk, specifically the tree_slot pointer.
- * We get our own 'pm refcnt' on the slot itself, which doesn't need RCU. */
+ /* We use rcu to protect our radix walk, specifically the tree_slot
+ * pointer. We get our own 'pm refcnt' on the slot itself, which
+ * doesn't need RCU. */
rcu_read_lock();
- /* We're syncing with removal. The deal is that if we grab the page (and
- * we'd only do that if the page != 0), we up the slot ref and clear
- * removal. A remover will only remove it if removal is still set. If we
- * grab and release while removal is in progress, even though we no longer
- * hold the ref, we have unset removal. Also, to prevent removal where we
- * get a page well before the removal process, the removal won't even bother
- * when the slot refcnt is upped. */
+ /* We're syncing with removal. The deal is that if we grab the page
+ * (and we'd only do that if the page != 0), we up the slot ref and
+ * clear removal. A remover will only remove it if removal is still
+ * set. If we grab and release while removal is in progress, even
+ * though we no longer hold the ref, we have unset removal. Also, to
+ * prevent removal where we get a page well before the removal process,
+ * the removal won't even bother when the slot refcnt is upped. */
tree_slot = radix_lookup_slot(&pm->pm_tree, index);
if (!tree_slot)
goto out;
@@ -125,7 +126,7 @@
page = pm_slot_get_page(slot_val);
if (!page)
goto out;
- slot_val = pm_slot_inc_refcnt(slot_val); /* not a page kref */
+ slot_val = pm_slot_inc_refcnt(slot_val); /* not a page kref */
} while (!atomic_cas_ptr(tree_slot, old_slot_val, slot_val));
assert(page->pg_tree_slot == tree_slot);
out:
@@ -151,8 +152,9 @@
page->pg_mapping = pm; /* debugging */
page->pg_index = index;
- /* no one should be looking at the tree slot til we stop write locking. the
- * only other one who looks is removal, who requires a PM write lock. */
+ /* no one should be looking at the tree slot til we stop write locking.
+ * the only other one who looks is removal, who requires a PM write
+ * lock. */
page->pg_tree_slot = (void*)0xdeadbeef; /* poison */
slot_val = pm_slot_inc_refcnt(slot_val);
/* passing the page ref from the caller to the slot */
@@ -194,29 +196,30 @@
while (!page) {
if (kpage_alloc(&page))
return -ENOMEM;
- /* important that UP_TO_DATE is not set. once we put it in the PM,
- * others can find it, and we still need to fill it. */
+ /* important that UP_TO_DATE is not set. once we put it in the
+ * PM, others can find it, and we still need to fill it. */
atomic_set(&page->pg_flags, PG_LOCKED | PG_PAGEMAP);
- /* The sem needs to be initted before anyone can try to lock it, meaning
- * before it is in the page cache. We also want it locked preemptively,
- * by setting signals = 0. */
+ /* The sem needs to be initted before anyone can try to lock it,
+ * meaning before it is in the page cache. We also want it
+ * locked preemptively, by setting signals = 0. */
sem_init(&page->pg_sem, 0);
error = pm_insert_page(pm, index, page);
switch (error) {
- case 0:
- goto load_locked_page;
- break;
- case -EEXIST:
- /* the page was mapped already (benign race), just get rid of
- * our page and try again (the only case that uses the while) */
- atomic_set(&page->pg_flags, 0);
- page_decref(page);
- page = pm_find_page(pm, index);
- break;
- default:
- atomic_set(&page->pg_flags, 0);
- page_decref(page);
- return error;
+ case 0:
+ goto load_locked_page;
+ break;
+ case -EEXIST:
+ /* the page was mapped already (benign race), just get
+ * rid of our page and try again (the only case that
+ * uses the while) */
+ atomic_set(&page->pg_flags, 0);
+ page_decref(page);
+ page = pm_find_page(pm, index);
+ break;
+ default:
+ atomic_set(&page->pg_flags, 0);
+ page_decref(page);
+ return error;
}
}
assert(page);
@@ -229,9 +232,9 @@
return 0;
}
lock_page(page);
- /* double-check. if we we blocked on lock_page, it was probably for someone
- * else loading. plus, we can't load a page more than once (it could
- * clobber newer writes) */
+ /* double-check. if we we blocked on lock_page, it was probably for
+ * someone else loading. plus, we can't load a page more than once (it
+ * could clobber newer writes) */
if (atomic_read(&page->pg_flags) & PG_UPTODATE) {
unlock_page(page);
*pp = page;
@@ -253,6 +256,7 @@
struct page **pp)
{
struct page *page = pm_find_page(pm, index);
+
if (!page)
return -EAGAIN;
if (!(atomic_read(&page->pg_flags) & PG_UPTODATE)) {
@@ -290,8 +294,8 @@
start_va = vmr->vm_base + (file_off - vmr->vm_foff);
if (start_va < vmr->vm_base) {
- warn("wraparound! %p %p %p %p", start_va, vmr->vm_base, vmr->vm_foff,
- pg_idx);
+ warn("wraparound! %p %p %p %p", start_va, vmr->vm_base,
+ vmr->vm_foff, pg_idx);
return;
}
if (start_va >= vmr->vm_end)
@@ -343,9 +347,10 @@
memset(page2kva(page), 0, PGSIZE);
return false;
}
- /* We yanked the page out. The radix tree still has an item until we return
- * true, but this is fine. Future lock-free lookups will now fail (since
- * the page is 0), and insertions will block on the write lock. */
+ /* We yanked the page out. The radix tree still has an item until we
+ * return true, but this is fine. Future lock-free lookups will now
+ * fail (since the page is 0), and insertions will block on the write
+ * lock. */
atomic_set(&page->pg_flags, 0); /* cause/catch bugs */
page_decref(page);
return true;
@@ -391,9 +396,10 @@
TAILQ_FOREACH(vmr_i, &pm->pm_vmrs, vm_pm_link) {
if (!(vmr_i->vm_prot & PROT_WRITE))
continue;
- /* Only care about shared mappings, not private. Private mappings have
- * a reference to the file, but the pages are not in the page cache -
- * they hang directly off the PTEs (for now). */
+ /* Only care about shared mappings, not private. Private
+ * mappings have a reference to the file, but the pages are not
+ * in the page cache - they hang directly off the PTEs (for
+ * now). */
if (!(vmr_i->vm_flags & MAP_SHARED))
continue;
spin_lock(&vmr_i->vm_proc->pte_lock);
@@ -407,10 +413,10 @@
{
struct vm_region *vmr_i;
- /* The VMR flag shootdown_needed is owned by the PM. Each VMR is hooked to
- * at most one file, so there's no issue there. We might have a proc that
- * has multiple non-private VMRs in the same file, but it shouldn't be a big
- * enough issue to worry about. */
+ /* The VMR flag shootdown_needed is owned by the PM. Each VMR is hooked
+ * to at most one file, so there's no issue there. We might have a proc
+ * that has multiple non-private VMRs in the same file, but it shouldn't
+ * be a big enough issue to worry about. */
spin_lock(&pm->pm_lock);
TAILQ_FOREACH(vmr_i, &pm->pm_vmrs, vm_pm_link) {
if (vmr_i->vm_shootdown_needed) {
@@ -431,8 +437,9 @@
* bunch outstanding, we'll send them. */
static void queue_writeback(struct page_map *pm, struct page *page)
{
- /* TODO (WB): add a bulk op (instead of only writepage()), collect extents,
- * and send them to the device. Probably do something similar for reads. */
+ /* TODO (WB): add a bulk op (instead of only writepage()), collect
+ * extents, and send them to the device. Probably do something similar
+ * for reads. */
pm->pm_op->writepage(pm, page);
}
@@ -479,31 +486,32 @@
slot_val = pm_slot_set_page(slot_val, NULL);
if (!atomic_cas_ptr(slot, old_slot_val, slot_val))
return false;
- /* At this point, we yanked the page. any concurrent wait-free users that
- * want to get this page will fail (pm_find_page / pm_load_page_nowait).
- * They will block on the qlock that we hold when they try to insert a page
- * (as part of pm_load_page, for both reading or writing). We can still
- * bail out and everything will be fine, so long as we put the page back.
+ /* At this point, we yanked the page. any concurrent wait-free users
+ * that want to get this page will fail (pm_find_page /
+ * pm_load_page_nowait). They will block on the qlock that we hold when
+ * they try to insert a page (as part of pm_load_page, for both reading
+ * or writing). We can still bail out and everything will be fine, so
+ * long as we put the page back.
*
- * We can't tell from looking at the page if it was actually faulted into
- * the VMR; we just know it was possible. (currently). Also, we need to do
- * this check after removing the page from the PM slot, since the mm
- * faulting code (hpf) will attempt a non-blocking PM lookup. */
+ * We can't tell from looking at the page if it was actually faulted
+ * into the VMR; we just know it was possible. (currently). Also, we
+ * need to do this check after removing the page from the PM slot, since
+ * the mm faulting code (hpf) will attempt a non-blocking PM lookup. */
if (pm_has_vmr_with_page(pm, tree_idx)) {
slot_val = pm_slot_set_page(slot_val, page);
- /* No one should be writing to it. We hold the qlock, and any readers
- * should not have increffed while the page was NULL. */
+ /* No one should be writing to it. We hold the qlock, and any
+ * readers should not have increffed while the page was NULL. */
WRITE_ONCE(*slot, slot_val);
return false;
}
- /* Need to check PG_DIRTY *after* checking VMRs. o/w we could check, PAUSE,
- * see no VMRs. But in the meantime, we had a VMR that munmapped and
- * wrote-back the dirty flag. */
+ /* Need to check PG_DIRTY *after* checking VMRs. o/w we could check,
+ * PAUSE, see no VMRs. But in the meantime, we had a VMR that munmapped
+ * and wrote-back the dirty flag. */
if (atomic_read(&page->pg_flags) & PG_DIRTY) {
- /* If we want to batch these, we'll also have to batch the freeing,
- * which isn't a big deal. Just do it before freeing and before
- * unlocking the PM; we don't want someone to load the page from the
- * backing store and get an old value. */
+ /* If we want to batch these, we'll also have to batch the
+ * freeing, which isn't a big deal. Just do it before freeing
+ * and before unlocking the PM; we don't want someone to load
+ * the page from the backing store and get an old value. */
pm->pm_op->writepage(pm, page);
}
/* All clear - the page is unused and (now) clean. */
@@ -550,8 +558,8 @@
TAILQ_FOREACH(vmr_i, &pm->pm_vmrs, vm_pm_link) {
printk("\tVMR proc %d: (%p - %p): 0x%08x, 0x%08x, %p, %p\n",
vmr_i->vm_proc->pid, vmr_i->vm_base, vmr_i->vm_end,
- vmr_i->vm_prot, vmr_i->vm_flags, foc_pointer(vmr_i->__vm_foc),
- vmr_i->vm_foff);
+ vmr_i->vm_prot, vmr_i->vm_flags,
+ foc_pointer(vmr_i->__vm_foc), vmr_i->vm_foff);
}
spin_unlock(&pm->pm_lock);
}
diff --git a/kern/src/percpu.c b/kern/src/percpu.c
index 12af818..cd45cf4 100644
--- a/kern/src/percpu.c
+++ b/kern/src/percpu.c
@@ -1,5 +1,6 @@
-/* Copyright (c) 2015 Google Inc
+/* Copyright (c) 2015, 2018 Google Inc
* Davide Libenzi <dlibenzi@google.com>
+ * Barret Rhoden <brho@google.com>
* See LICENSE for details.
*/
@@ -24,7 +25,8 @@
if (PERCPU_INIT_START_VAR) {
void (**pfunc)(void) = (void (**)(void)) PERCPU_INIT_START_VAR;
- void (**pfunc_top)(void) = (void (**)(void)) PERCPU_INIT_STOP_VAR;
+ void (**pfunc_top)(void) =
+ (void (**)(void)) PERCPU_INIT_STOP_VAR;
for (; pfunc < pfunc_top; pfunc++)
(*pfunc)();
@@ -41,10 +43,11 @@
memcpy(percpu_base + i * PERCPU_SIZE, PERCPU_START_VAR,
PERCPU_STATIC_SIZE);
}
- /* We hand out addresses starting right above the static section, which ends
- * at PERCPU_STOP_VAR. */
- pcpu_dyn_arena = arena_create("pcpu_dyn", PERCPU_STOP_VAR, PERCPU_DYN_SIZE,
- 1, NULL, NULL, NULL, 0, MEM_WAIT);
+ /* We hand out addresses starting right above the static section, which
+ * ends at PERCPU_STOP_VAR. */
+ pcpu_dyn_arena = arena_create("pcpu_dyn", PERCPU_STOP_VAR,
+ PERCPU_DYN_SIZE, 1, NULL, NULL, NULL, 0,
+ MEM_WAIT);
assert(pcpu_dyn_arena);
run_init_functions();
}
diff --git a/kern/src/pmap.c b/kern/src/pmap.c
index 9935287..ebdc1e8 100644
--- a/kern/src/pmap.c
+++ b/kern/src/pmap.c
@@ -23,9 +23,9 @@
#include <arena.h>
#include <init.h>
-physaddr_t max_pmem = 0; /* Total amount of physical memory (bytes) */
-physaddr_t max_paddr = 0; /* Maximum addressable physical address */
-size_t max_nr_pages = 0; /* Number of addressable physical memory pages */
+physaddr_t max_pmem = 0; /* Total amount of physical memory (bytes) */
+physaddr_t max_paddr = 0; /* Maximum addressable physical address */
+size_t max_nr_pages = 0; /* Number of addressable physical memory pages */
struct page *pages = 0;
struct multiboot_info *multiboot_kaddr = 0;
uintptr_t boot_freemem = 0;
@@ -68,11 +68,11 @@
{
mboot_detect_memory(mbi);
mboot_print_mmap(mbi);
- /* adjust the max memory based on the mmaps, since the old detection doesn't
- * help much on 64 bit systems */
+ /* adjust the max memory based on the mmaps, since the old detection
+ * doesn't help much on 64 bit systems */
mboot_foreach_mmap(mbi, adjust_max_pmem, 0);
- /* KERN_VMAP_TOP - KERNBASE is the max amount of virtual addresses we can
- * use for the physical memory mapping (aka - the KERNBASE mapping).
+ /* KERN_VMAP_TOP - KERNBASE is the max amount of virtual addresses we
+ * can use for the physical memory mapping (aka - the KERNBASE mapping).
* Should't be an issue on 64b, but is usually for 32 bit. */
max_paddr = MIN(max_pmem, KERN_VMAP_TOP - KERNBASE);
/* Note not all of this memory is free. */
@@ -80,13 +80,15 @@
printk("Max physical RAM (appx, bytes): %lu\n", max_pmem);
printk("Max addressable physical RAM (appx): %lu\n", max_paddr);
printk("Highest page number (including reserved): %lu\n", max_nr_pages);
- /* We should init the page structs, but zeroing happens to work, except for
- * the sems. Those are init'd by the page cache before they are used. */
+ /* We should init the page structs, but zeroing happens to work, except
+ * for the sems. Those are init'd by the page cache before they are
+ * used. */
pages = (struct page*)boot_zalloc(max_nr_pages * sizeof(struct page),
PGSIZE);
base_arena_init(mbi);
- /* kpages will use some of the basic slab caches. kmem_cache_init needs to
- * not do memory allocations (which it doesn't, and it can base_alloc()). */
+ /* kpages will use some of the basic slab caches. kmem_cache_init needs
+ * to not do memory allocations (which it doesn't, and it can
+ * base_alloc()). */
kmem_cache_init();
kpages_arena_init();
printk("Base arena total mem: %lu\n", arena_amt_total(base_arena));
@@ -132,13 +134,16 @@
mboot_foreach_mmap(multiboot_kaddr, set_largest_freezone, &boot_zone);
if (boot_zone) {
boot_zone_start = (uintptr_t)KADDR(boot_zone->addr);
- /* one issue for 32b is that the boot_zone_end could be beyond max_paddr
- * and even wrap-around. Do the min check as a uint64_t. The result
- * should be a safe, unwrapped 32/64b when cast to physaddr_t. */
- boot_zone_end = (uintptr_t)KADDR(MIN(boot_zone->addr + boot_zone->len,
- (uint64_t)max_paddr));
- /* using KERNBASE (kva, btw) which covers the kernel and anything before
- * it (like the stuff below EXTPHYSMEM on x86) */
+ /* one issue for 32b is that the boot_zone_end could be beyond
+ * max_paddr and even wrap-around. Do the min check as a
+ * uint64_t. The result should be a safe, unwrapped 32/64b when
+ * cast to physaddr_t. */
+ boot_zone_end = (uintptr_t)KADDR(MIN(boot_zone->addr +
+ boot_zone->len,
+ (uint64_t)max_paddr));
+ /* using KERNBASE (kva, btw) which covers the kernel and
+ * anything before it (like the stuff below EXTPHYSMEM on x86)
+ */
if (regions_collide_unsafe(KERNBASE, end_kva,
boot_zone_start, boot_zone_end))
boot_freemem = end_kva;
@@ -149,8 +154,8 @@
boot_freemem = end_kva;
boot_freelimit = max_paddr + KERNBASE;
}
- printd("boot_zone: %p, paddr base: 0x%llx, paddr len: 0x%llx\n", boot_zone,
- boot_zone ? boot_zone->addr : 0,
+ printd("boot_zone: %p, paddr base: 0x%llx, paddr len: 0x%llx\n",
+ boot_zone, boot_zone ? boot_zone->addr : 0,
boot_zone ? boot_zone->len : 0);
printd("boot_freemem: %p, boot_freelimit %p\n", boot_freemem,
boot_freelimit);
@@ -178,7 +183,7 @@
printd("boot alloc from %p to %p\n", retval, boot_freemem);
/* multiboot info probably won't ever conflict with our boot alloc */
if (mboot_region_collides(multiboot_kaddr, retval, boot_freemem))
- panic("boot allocation could clobber multiboot info! Get help!");
+ panic("boot allocation could clobber multiboot info!");
return (void*)retval;
}
@@ -227,6 +232,7 @@
int page_insert(pgdir_t pgdir, struct page *page, void *va, int perm)
{
pte_t pte = pgdir_walk(pgdir, va, 1);
+
if (!pte_walk_okay(pte))
return -ENOMEM;
/* Leftover from older times, but we no longer suppor this: */
@@ -247,7 +253,8 @@
*
* @param[in] pgdir the page directory from which we should do the lookup
* @param[in] va the virtual address of the page we are looking up
- * @param[out] pte_store the address of the page table entry for the returned page
+ * @param[out] pte_store the address of the page table entry for the returned
+ * page
*
* @return PAGE the page mapped at virtual address 'va'
* @return NULL No mapping exists at virtual address 'va', or it's paged out
@@ -255,6 +262,7 @@
page_t *page_lookup(pgdir_t pgdir, void *va, pte_t *pte_store)
{
pte_t pte = pgdir_walk(pgdir, va, 0);
+
if (!pte_walk_okay(pte) || !pte_is_mapped(pte))
return 0;
if (pte_store)
@@ -294,9 +302,9 @@
return;
if (pte_is_mapped(pte)) {
- /* TODO: (TLB) need to do a shootdown, inval sucks. And might want to
- * manage the TLB / free pages differently. (like by the caller).
- * Careful about the proc/memory lock here. */
+ /* TODO: (TLB) need to do a shootdown, inval sucks. And might
+ * want to manage the TLB / free pages differently. (like by the
+ * caller). Careful about the proc/memory lock here. */
page = pa2page(pte_get_paddr(pte));
pte_clear(pte);
tlb_invalidate(pgdir, va);
@@ -337,9 +345,9 @@
tlb_flush_global();
if (booting)
return;
- /* TODO: consider a helper for broadcast messages, though note that we're
- * doing our flush immediately, which our caller expects from us before it
- * returns. */
+ /* TODO: consider a helper for broadcast messages, though note that
+ * we're doing our flush immediately, which our caller expects from us
+ * before it returns. */
for (int i = 0; i < num_cores; i++) {
if (i == core_id())
continue;
diff --git a/kern/src/printfmt.c b/kern/src/printfmt.c
index b64625e..7e37b25 100644
--- a/kern/src/printfmt.c
+++ b/kern/src/printfmt.c
@@ -17,6 +17,7 @@
{
unsigned long long temp = num;
int nr_digits = 1;
+
/* Determine how many leading zeros we need.
* For every digit/nibble beyond base, we do one less width padding */
while ((temp /= base)) {
@@ -38,7 +39,8 @@
void printfmt(void (*putch)(int, void**), void **putdat, const char *fmt, ...);
-void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_list ap)
+void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt,
+ va_list ap)
{
register const char *p;
const char *last_fmt;
@@ -145,7 +147,8 @@
uint32_t hostfmt;
for(i = 0; i < 4; i++){
hnputl(&hostfmt, lp[i]);
- printfmt(putch, putdat, "%08lx", hostfmt);
+ printfmt(putch, putdat, "%08lx",
+ hostfmt);
}
}
break;
@@ -170,9 +173,14 @@
if ((p = va_arg(ap, char *)) == NULL)
p = "(null)";
if (width > 0 && padc != '-')
- for (width -= strnlen(p, precision); width > 0; width--)
+ for (width -= strnlen(p, precision);
+ width > 0;
+ width--)
putch(padc, putdat);
- for (; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width--) {
+ for (;
+ (ch = *p) != '\0' && (precision < 0
+ || --precision >= 0);
+ width--) {
if (altflag && (ch < ' ' || ch > '~'))
putch('?', putdat);
else
@@ -219,9 +227,11 @@
case 'p':
putch('0', putdat);
putch('x', putdat);
- /* automatically zero-pad pointers, out to the length of a ptr */
+ /* automatically zero-pad pointers, out to the length of
+ * a ptr */
padc = '0';
- width = sizeof(void*) * 2; /* 8 bits per byte / 4 bits per char */
+ /* 8 bits per byte / 4 bits per char */
+ width = sizeof(void*) * 2;
num = (unsigned long long)
(uintptr_t) va_arg(ap, void *);
base = 16;
@@ -284,10 +294,10 @@
* snprintf(), e.g.:
* len += snprintf(buf + len, bufsz - len, "foo");
* len += snprintf(buf + len, bufsz - len, "bar");
- * If len > bufsz, that will appear as a large value. This is not quite the
- * glibc semantics (we aren't returning the size we would have printed), but
- * it short circuits the rest of the function and avoids potential errors in
- * the putch() functions. */
+ * If len > bufsz, that will appear as a large value. This is not quite
+ * the glibc semantics (we aren't returning the size we would have
+ * printed), but it short circuits the rest of the function and avoids
+ * potential errors in the putch() functions. */
if (!n || (n > INT32_MAX))
return 0;
diff --git a/kern/src/process.c b/kern/src/process.c
index 7197e11..e47968b 100644
--- a/kern/src/process.c
+++ b/kern/src/process.c
@@ -67,7 +67,7 @@
}
spin_unlock(&pid_bmask_lock);
if (!my_pid)
- warn("Shazbot! Unable to find a PID! You need to deal with this!\n");
+ warn("Unable to find a PID! You need to deal with this!\n");
return my_pid;
}
@@ -90,6 +90,7 @@
void vcore_account_online(struct proc *p, uint32_t vcoreid)
{
struct vcore *vc = &p->procinfo->vcoremap[vcoreid];
+
vc->resume_ticks = read_tsc();
}
@@ -102,6 +103,7 @@
uint64_t vcore_account_gettotal(struct proc *p, uint32_t vcoreid)
{
struct vcore *vc = &p->procinfo->vcoremap[vcoreid];
+
return vc->total_ticks;
}
@@ -130,46 +132,49 @@
* RGM -> D
* D -> DA
*
- * These ought to be implemented later (allowed, not thought through yet).
+ * These ought to be implemented later (allowed, not thought through
+ * yet).
* RBS -> D
* RBM -> D
*/
#if 1 // some sort of correctness flag
switch (curstate) {
- case PROC_CREATED:
- if (!(state & (PROC_RUNNABLE_S | PROC_DYING)))
- panic("Invalid State Transition! PROC_CREATED to %02x", state);
- break;
- case PROC_RUNNABLE_S:
- if (!(state & (PROC_RUNNING_S | PROC_DYING)))
- panic("Invalid State Transition! PROC_RUNNABLE_S to %02x", state);
- break;
- case PROC_RUNNING_S:
- if (!(state & (PROC_RUNNABLE_S | PROC_RUNNABLE_M | PROC_WAITING |
- PROC_DYING)))
- panic("Invalid State Transition! PROC_RUNNING_S to %02x", state);
- break;
- case PROC_WAITING:
- if (!(state & (PROC_RUNNABLE_S | PROC_RUNNING_S | PROC_RUNNABLE_M |
- PROC_DYING)))
- panic("Invalid State Transition! PROC_WAITING to %02x", state);
- break;
- case PROC_DYING:
- if (state != PROC_DYING_ABORT)
- panic("Invalid State Transition! PROC_DYING to %02x", state);
- break;
- case PROC_DYING_ABORT:
- panic("Invalid State Transition! PROC_DYING to %02x", state);
- break;
- case PROC_RUNNABLE_M:
- if (!(state & (PROC_RUNNING_M | PROC_DYING)))
- panic("Invalid State Transition! PROC_RUNNABLE_M to %02x", state);
- break;
- case PROC_RUNNING_M:
- if (!(state & (PROC_RUNNABLE_S | PROC_RUNNABLE_M | PROC_WAITING |
- PROC_DYING)))
- panic("Invalid State Transition! PROC_RUNNING_M to %02x", state);
- break;
+ case PROC_CREATED:
+ if (!(state & (PROC_RUNNABLE_S | PROC_DYING)))
+ goto invalid_state_transition;
+ break;
+ case PROC_RUNNABLE_S:
+ if (!(state & (PROC_RUNNING_S | PROC_DYING)))
+ goto invalid_state_transition;
+ break;
+ case PROC_RUNNING_S:
+ if (!(state & (PROC_RUNNABLE_S | PROC_RUNNABLE_M | PROC_WAITING
+ | PROC_DYING)))
+ goto invalid_state_transition;
+ break;
+ case PROC_WAITING:
+ if (!(state & (PROC_RUNNABLE_S | PROC_RUNNING_S |
+ PROC_RUNNABLE_M | PROC_DYING)))
+ goto invalid_state_transition;
+ break;
+ case PROC_DYING:
+ if (state != PROC_DYING_ABORT)
+ goto invalid_state_transition;
+ break;
+ case PROC_DYING_ABORT:
+ goto invalid_state_transition;
+ case PROC_RUNNABLE_M:
+ if (!(state & (PROC_RUNNING_M | PROC_DYING)))
+ goto invalid_state_transition;
+ break;
+ case PROC_RUNNING_M:
+ if (!(state & (PROC_RUNNABLE_S | PROC_RUNNABLE_M | PROC_WAITING
+ | PROC_DYING)))
+ goto invalid_state_transition;
+ break;
+invalid_state_transition:
+ panic("Invalid State Transition! %s to %02x",
+ procstate2str(state), state);
}
#endif
p->state = state;
@@ -186,6 +191,7 @@
{
spin_lock(&pid_hash_lock);
struct proc *p = hashtable_search(pid_hash, (void*)(long)pid);
+
if (p)
if (!kref_get_not_zero(&p->p_kref, 1))
p = 0;
@@ -287,8 +293,8 @@
if (name == NULL)
name = DEFAULT_PROGNAME;
- /* might have an issue if a dentry name isn't null terminated, and we'd get
- * extra junk up to progname_sz. Or crash. */
+ /* might have an issue if a dentry name isn't null terminated, and we'd
+ * get extra junk up to progname_sz. Or crash. */
strlcpy(p->progname, name, PROC_PROGNAME_SZ);
}
@@ -318,15 +324,17 @@
p->procinfo->coremap_seqctr = SEQCTR_INITIALIZER;
/* It's a bug in the kernel if we let them ask for more than max */
for (int i = 0; i < p->procinfo->max_vcores; i++) {
- TAILQ_INSERT_TAIL(&p->inactive_vcs, &p->procinfo->vcoremap[i], list);
+ TAILQ_INSERT_TAIL(&p->inactive_vcs, &p->procinfo->vcoremap[i],
+ list);
}
}
void proc_init_procdata(struct proc *p)
{
memset(p->procdata, 0, sizeof(struct procdata));
- /* processes can't go into vc context on vc 0 til they unset this. This is
- * for processes that block before initing uthread code (like rtld). */
+ /* processes can't go into vc context on vc 0 til they unset this. This
+ * is for processes that block before initing uthread code (like rtld).
+ */
atomic_set(&p->procdata->vcore_preempt_data[0].flags, VC_SCP_NOVCCTX);
}
@@ -335,11 +343,11 @@
int fd;
struct proc *old_current = current;
- /* Due to the way the syscall helpers assume the target process is current,
- * we need to set current temporarily. We don't use switch_to, since that
- * actually loads the process's address space, which might be empty or
- * incomplete. These syscalls shouldn't access user memory, especially
- * considering how we're probably in the boot pgdir. */
+ /* Due to the way the syscall helpers assume the target process is
+ * current, we need to set current temporarily. We don't use switch_to,
+ * since that actually loads the process's address space, which might be
+ * empty or incomplete. These syscalls shouldn't access user memory,
+ * especially considering how we're probably in the boot pgdir. */
current = p;
fd = sysopenat(AT_FDCWD, "#cons/stdin", O_READ);
assert(fd == 0);
@@ -365,8 +373,8 @@
/* zero everything by default, other specific items are set below */
memset(p, 0, sizeof(*p));
- /* only one ref, which we pass back. the old 'existence' ref is managed by
- * the ksched */
+ /* only one ref, which we pass back. the old 'existence' ref is managed
+ * by the ksched */
kref_init(&p->p_kref, __proc_free, 1);
/* Initialize the address space */
if ((r = env_setup_vm(p)) < 0) {
@@ -382,31 +390,35 @@
/* Set the basic status variables. */
spinlock_init(&p->proc_lock);
spinlock_init(&p->user.name_lock);
- p->exitcode = 1337; /* so we can see processes killed by the kernel */
+ /* so we can see processes killed by the kernel */
+ p->exitcode = 1337;
if (parent) {
p->ppid = parent->pid;
proc_inherit_parent_username(p, parent);
proc_incref(p, 1); /* storing a ref in the parent */
- /* using the CV's lock to protect anything related to child waiting */
+ /* using the CV's lock to protect anything related to child
+ * waiting */
cv_lock(&parent->child_wait);
TAILQ_INSERT_TAIL(&parent->children, p, sibling_link);
cv_unlock(&parent->child_wait);
} else {
p->ppid = 0;
strlcpy(p->user.name, eve.name, sizeof(p->user.name));
- printk("Parentless process assigned username '%s'\n", p->user.name);
+ printk("Parentless process assigned username '%s'\n",
+ p->user.name);
}
TAILQ_INIT(&p->children);
cv_init(&p->child_wait);
- p->state = PROC_CREATED; /* shouldn't go through state machine for init */
+ /* shouldn't go through state machine for init */
+ p->state = PROC_CREATED;
p->env_flags = 0;
spinlock_init(&p->vmr_lock);
spinlock_init(&p->pte_lock);
TAILQ_INIT(&p->vm_regions); /* could init this in the slab */
p->vmr_history = 0;
/* Initialize the vcore lists, we'll build the inactive list so that it
- * includes all vcores when we initialize procinfo. Do this before initing
- * procinfo. */
+ * includes all vcores when we initialize procinfo. Do this before
+ * initing procinfo. */
TAILQ_INIT(&p->online_vcs);
TAILQ_INIT(&p->bulk_preempted_vcs);
TAILQ_INIT(&p->inactive_vcs);
@@ -423,7 +435,7 @@
/* Init FS structures TODO: cleanup (might pull this out) */
p->umask = parent ? parent->umask : S_IWGRP | S_IWOTH;
- memset(&p->open_files, 0, sizeof(p->open_files)); /* slightly ghetto */
+ memset(&p->open_files, 0, sizeof(p->open_files)); /* slightly ghetto */
spinlock_init(&p->open_files.lock);
p->open_files.max_files = NR_OPEN_FILES_DEFAULT;
p->open_files.max_fdset = NR_FILE_DESC_DEFAULT;
@@ -498,8 +510,10 @@
void *hash_ret;
physaddr_t pa;
- printd("[PID %d] freeing proc: %d\n", current ? current->pid : 0, p->pid);
- // All parts of the kernel should have decref'd before __proc_free is called
+ printd("[PID %d] freeing proc: %d\n", current ? current->pid : 0,
+ p->pid);
+ // All parts of the kernel should have decref'd before __proc_free is
+ // called
assert(kref_refcnt(&p->p_kref) == 0);
assert(TAILQ_EMPTY(&p->alarmset.list));
@@ -525,11 +539,11 @@
else
printd("[kernel] pid %d not in the PID hash in %s\n", p->pid,
__FUNCTION__);
- /* All memory below UMAPTOP should have been freed via the VMRs. The stuff
- * above is the global info/page and procinfo/procdata. We free procinfo
- * and procdata, but not the global memory - that's system wide. We could
- * clear the PTEs of the upper stuff (UMAPTOP to UVPT), but we shouldn't
- * need to. */
+ /* All memory below UMAPTOP should have been freed via the VMRs. The
+ * stuff above is the global info/page and procinfo/procdata. We free
+ * procinfo and procdata, but not the global memory - that's system
+ * wide. We could clear the PTEs of the upper stuff (UMAPTOP to UVPT),
+ * but we shouldn't need to. */
env_user_mem_walk(p, 0, UMAPTOP, __cb_assert_no_pg, 0);
kpages_free(p->procinfo, PROCINFO_NUM_PAGES * PGSIZE);
kpages_free(p->procdata, PROCDATA_NUM_PAGES * PGSIZE);
@@ -574,19 +588,19 @@
* incref internally when needed. */
static void __set_proc_current(struct proc *p)
{
- /* We use the pcpui to access 'current' to cut down on the core_id() calls,
- * though who know how expensive/painful they are. */
+ /* We use the pcpui to access 'current' to cut down on the core_id()
+ * calls, though who know how expensive/painful they are. */
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
struct proc *old_proc;
- /* If the process wasn't here, then we need to load its address space. */
+ /* If the process wasn't here, then we need to load its address space */
if (p != pcpui->cur_proc) {
proc_incref(p, 1);
lcr3(p->env_cr3);
- /* This is "leaving the process context" of the previous proc. The
- * previous lcr3 unloaded the previous proc's context. This should
- * rarely happen, since we usually proactively leave process context,
- * but this is the fallback. */
+ /* This is "leaving the process context" of the previous proc.
+ * The previous lcr3 unloaded the previous proc's context. This
+ * should rarely happen, since we usually proactively leave
+ * process context, but this is the fallback. */
old_proc = pcpui->cur_proc;
pcpui->cur_proc = p;
if (old_proc)
@@ -616,66 +630,72 @@
uint32_t coreid = core_id();
struct per_cpu_info *pcpui = &per_cpu_info[coreid];
struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[0];
+
spin_lock(&p->proc_lock);
switch (p->state) {
- case (PROC_DYING):
- case (PROC_DYING_ABORT):
- spin_unlock(&p->proc_lock);
- printk("[kernel] _S %d not starting due to async death\n", p->pid);
- return;
- case (PROC_RUNNABLE_S):
- __proc_set_state(p, PROC_RUNNING_S);
- /* SCPs don't have full vcores, but they act like they have vcore 0.
- * We map the vcore, since we will want to know where this process
- * is running, even if it is only in RUNNING_S. We can use the
- * vcoremap, which makes death easy. num_vcores is still 0, and we
- * do account the time online and offline. */
- __seq_start_write(&p->procinfo->coremap_seqctr);
- p->procinfo->num_vcores = 0;
- __map_vcore(p, 0, coreid);
- vcore_account_online(p, 0);
- __seq_end_write(&p->procinfo->coremap_seqctr);
- /* incref, since we're saving a reference in owning proc later */
- proc_incref(p, 1);
- /* lock was protecting the state and VC mapping, not pcpui stuff */
- spin_unlock(&p->proc_lock);
- /* redundant with proc_startcore, might be able to remove that one*/
- __set_proc_current(p);
- /* set us up as owning_proc. ksched bug if there is already one,
- * for now. can simply clear_owning if we want to. */
- assert(!pcpui->owning_proc);
- pcpui->owning_proc = p;
- pcpui->owning_vcoreid = 0;
- restore_vc_fp_state(vcpd);
- /* similar to the old __startcore, start them in vcore context if
- * they have notifs and aren't already in vcore context. o/w, start
- * them wherever they were before (could be either vc ctx or not) */
- if (!vcpd->notif_disabled && vcpd->notif_pending
- && scp_is_vcctx_ready(vcpd)) {
- vcpd->notif_disabled = TRUE;
- /* save the _S's ctx in the uthread slot, build and pop a new
- * one in actual/cur_ctx. */
- vcpd->uthread_ctx = p->scp_ctx;
- pcpui->cur_ctx = &pcpui->actual_ctx;
- memset(pcpui->cur_ctx, 0, sizeof(struct user_context));
- proc_init_ctx(pcpui->cur_ctx, 0, vcpd->vcore_entry,
- vcpd->vcore_stack, vcpd->vcore_tls_desc);
- } else {
- /* If they have no transition stack, then they can't receive
- * events. The most they are getting is a wakeup from the
- * kernel. They won't even turn off notif_pending, so we'll do
- * that for them. */
- if (!scp_is_vcctx_ready(vcpd))
- vcpd->notif_pending = FALSE;
- /* this is one of the few times cur_ctx != &actual_ctx */
- pcpui->cur_ctx = &p->scp_ctx;
- }
- /* When the calling core idles, it'll call restartcore and run the
- * _S process's context. */
- return;
- default:
- spin_unlock(&p->proc_lock);
- panic("Invalid process state %p in %s()!!", p->state, __FUNCTION__);
+ case (PROC_DYING):
+ case (PROC_DYING_ABORT):
+ spin_unlock(&p->proc_lock);
+ printk("[kernel] _S %d not starting: async death\n",
+ p->pid);
+ return;
+ case (PROC_RUNNABLE_S):
+ __proc_set_state(p, PROC_RUNNING_S);
+ /* SCPs don't have full vcores, but they act like they have
+ * vcore 0. We map the vcore, since we will want to know where
+ * this process is running, even if it is only in RUNNING_S. We
+ * can use the vcoremap, which makes death easy. num_vcores is
+ * still 0, and we do account the time online and offline. */
+ __seq_start_write(&p->procinfo->coremap_seqctr);
+ p->procinfo->num_vcores = 0;
+ __map_vcore(p, 0, coreid);
+ vcore_account_online(p, 0);
+ __seq_end_write(&p->procinfo->coremap_seqctr);
+ /* incref, since we're saving a reference in owning proc later*/
+ proc_incref(p, 1);
+ /* lock was protecting the state and VC mapping, not pcpui stuff
+ */
+ spin_unlock(&p->proc_lock);
+ /* redundant with proc_startcore, might be able to remove that
+ * one */
+ __set_proc_current(p);
+ /* set us up as owning_proc. ksched bug if there is already
+ * one, for now. can simply clear_owning if we want to. */
+ assert(!pcpui->owning_proc);
+ pcpui->owning_proc = p;
+ pcpui->owning_vcoreid = 0;
+ restore_vc_fp_state(vcpd);
+ /* similar to the old __startcore, start them in vcore context
+ * if they have notifs and aren't already in vcore context.
+ * o/w, start them wherever they were before (could be either vc
+ * ctx or not) */
+ if (!vcpd->notif_disabled && vcpd->notif_pending
+ && scp_is_vcctx_ready(vcpd)) {
+ vcpd->notif_disabled = TRUE;
+ /* save the _S's ctx in the uthread slot, build and pop
+ * a new one in actual/cur_ctx. */
+ vcpd->uthread_ctx = p->scp_ctx;
+ pcpui->cur_ctx = &pcpui->actual_ctx;
+ memset(pcpui->cur_ctx, 0, sizeof(struct user_context));
+ proc_init_ctx(pcpui->cur_ctx, 0, vcpd->vcore_entry,
+ vcpd->vcore_stack, vcpd->vcore_tls_desc);
+ } else {
+ /* If they have no transition stack, then they can't
+ * receive events. The most they are getting is a
+ * wakeup from the kernel. They won't even turn off
+ * notif_pending, so we'll do that for them. */
+ if (!scp_is_vcctx_ready(vcpd))
+ vcpd->notif_pending = FALSE;
+ /* this is one of the few times cur_ctx != &actual_ctx*/
+ pcpui->cur_ctx = &p->scp_ctx;
+ }
+ /* When the calling core idles, it'll call restartcore and run
+ * the _S process's context. */
+ return;
+ default:
+ spin_unlock(&p->proc_lock);
+ panic("Invalid process state %p in %s()!!", p->state,
+ __FUNCTION__);
}
}
@@ -685,23 +705,26 @@
{
struct vcore *vc_i, *vc_temp;
struct event_msg preempt_msg = {0};
- /* Whenever we send msgs with the proc locked, we need at least 1 online */
+
+ /* Whenever we send msgs with the proc locked, we need at least 1 online
+ */
assert(!TAILQ_EMPTY(&p->online_vcs));
- /* Send preempt messages for any left on the BP list. No need to set any
- * flags, it all was done on the real preempt. Now we're just telling the
- * process about any that didn't get restarted and are still preempted. */
+ /* Send preempt messages for any left on the BP list. No need to set
+ * any flags, it all was done on the real preempt. Now we're just
+ * telling the process about any that didn't get restarted and are still
+ * preempted. */
TAILQ_FOREACH_SAFE(vc_i, &p->bulk_preempted_vcs, list, vc_temp) {
- /* Note that if there are no active vcores, send_k_e will post to our
- * own vcore, the last of which will be put on the inactive list and be
- * the first to be started. We could have issues with deadlocking,
- * since send_k_e() could grab the proclock (if there are no active
- * vcores) */
+ /* Note that if there are no active vcores, send_k_e will post
+ * to our own vcore, the last of which will be put on the
+ * inactive list and be the first to be started. We could have
+ * issues with deadlocking, since send_k_e() could grab the
+ * proclock (if there are no active vcores) */
preempt_msg.ev_type = EV_VCORE_PREEMPT;
- preempt_msg.ev_arg2 = vcore2vcoreid(p, vc_i); /* arg2 is 32 bits */
+ preempt_msg.ev_arg2 = vcore2vcoreid(p, vc_i); /* arg2 32 bits */
send_kernel_event(p, &preempt_msg, 0);
- /* TODO: we may want a TAILQ_CONCAT_HEAD, or something that does that.
- * We need a loop for the messages, but not necessarily for the list
- * changes. */
+ /* TODO: we may want a TAILQ_CONCAT_HEAD, or something that does
+ * that. We need a loop for the messages, but not necessarily
+ * for the list changes. */
TAILQ_REMOVE(&p->bulk_preempted_vcs, vc_i, list);
TAILQ_INSERT_HEAD(&p->inactive_vcs, vc_i, list);
}
@@ -720,48 +743,51 @@
{
struct vcore *vc_i;
switch (p->state) {
- case (PROC_WAITING):
- case (PROC_DYING):
- case (PROC_DYING_ABORT):
- warn("ksched tried to run proc %d in state %s\n", p->pid,
- procstate2str(p->state));
- return;
- case (PROC_RUNNABLE_M):
- /* vcoremap[i] holds the coreid of the physical core allocated to
- * this process. It is set outside proc_run. */
- if (p->procinfo->num_vcores) {
- __send_bulkp_events(p);
- __proc_set_state(p, PROC_RUNNING_M);
- /* Up the refcnt, to avoid the n refcnt upping on the
- * destination cores. Keep in sync with __startcore */
- proc_incref(p, p->procinfo->num_vcores * 2);
- /* Send kernel messages to all online vcores (which were added
- * to the list and mapped in __proc_give_cores()), making them
- * turn online */
- TAILQ_FOREACH(vc_i, &p->online_vcs, list) {
- send_kernel_message(vc_i->pcoreid, __startcore, (long)p,
- (long)vcore2vcoreid(p, vc_i),
- (long)vc_i->nr_preempts_sent,
- KMSG_ROUTINE);
- }
- } else {
- warn("Tried to proc_run() an _M with no vcores!");
+ case (PROC_WAITING):
+ case (PROC_DYING):
+ case (PROC_DYING_ABORT):
+ warn("ksched tried to run proc %d in state %s\n", p->pid,
+ procstate2str(p->state));
+ return;
+ case (PROC_RUNNABLE_M):
+ /* vcoremap[i] holds the coreid of the physical core allocated
+ * to this process. It is set outside proc_run. */
+ if (p->procinfo->num_vcores) {
+ __send_bulkp_events(p);
+ __proc_set_state(p, PROC_RUNNING_M);
+ /* Up the refcnt, to avoid the n refcnt upping on the
+ * destination cores. Keep in sync with __startcore */
+ proc_incref(p, p->procinfo->num_vcores * 2);
+ /* Send kernel messages to all online vcores (which were
+ * added to the list and mapped in __proc_give_cores()),
+ * making them turn online */
+ TAILQ_FOREACH(vc_i, &p->online_vcs, list) {
+ send_kernel_message(vc_i->pcoreid, __startcore,
+ (long)p,
+ (long)vcore2vcoreid(p, vc_i),
+ (long)vc_i->nr_preempts_sent,
+ KMSG_ROUTINE);
}
- /* There a subtle race avoidance here (when we unlock after sending
- * the message). __proc_startcore can handle a death message, but
- * we can't have the startcore come after the death message.
- * Otherwise, it would look like a new process. So we hold the lock
- * til after we send our message, which prevents a possible death
- * message.
- * - Note there is no guarantee this core's interrupts were on, so
- * it may not get the message for a while... */
- return;
- case (PROC_RUNNING_M):
- return;
- default:
- /* unlock just so the monitor can call something that might lock*/
- spin_unlock(&p->proc_lock);
- panic("Invalid process state %p in %s()!!", p->state, __FUNCTION__);
+ } else {
+ warn("Tried to proc_run() an _M with no vcores!");
+ }
+ /* There a subtle race avoidance here (when we unlock after
+ * sending the message). __proc_startcore can handle a death
+ * message, but we can't have the startcore come after the death
+ * message. Otherwise, it would look like a new process. So we
+ * hold the lock til after we send our message, which prevents a
+ * possible death message.
+ * - Note there is no guarantee this core's interrupts were on,
+ * so it may not get the message for a while... */
+ return;
+ case (PROC_RUNNING_M):
+ return;
+ default:
+ /* unlock just so the monitor can call something that might
+ * lock*/
+ spin_unlock(&p->proc_lock);
+ panic("Invalid process state %p in %s()!!", p->state,
+ __FUNCTION__);
}
}
@@ -777,9 +803,10 @@
void __proc_startcore(struct proc *p, struct user_context *ctx)
{
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+
assert(!irq_is_enabled());
- /* Should never have ktask still set. If we do, future syscalls could try
- * to block later and lose track of our address space. */
+ /* Should never have ktask still set. If we do, future syscalls could
+ * try to block later and lose track of our address space. */
assert(!is_ktask(pcpui->cur_kthread));
__set_proc_current(p);
__set_cpu_state(pcpui, CPU_STATE_USER);
@@ -811,8 +838,8 @@
cv_lock(&parent->child_wait);
TAILQ_FOREACH_SAFE(child_i, &parent->children, sibling_link, temp) {
ret = __proc_disown_child(parent, child_i);
- /* should never fail, lock should cover the race. invariant: any child
- * on the list should have us as a parent */
+ /* should never fail, lock should cover the race. invariant:
+ * any child on the list should have us as a parent */
assert(!ret);
TAILQ_INSERT_TAIL(&todo, child_i, sibling_link);
}
@@ -850,69 +877,72 @@
struct proc *child_i, *temp;
spin_lock(&p->proc_lock);
- /* storage for pc_arr is alloced at decl, which is after grabbing the lock*/
+ /* storage for pc_arr is alloced at decl, which is after grabbing the
+ * lock*/
uint32_t pc_arr[p->procinfo->num_vcores];
switch (p->state) {
- case PROC_DYING: /* someone else killed this already. */
- case (PROC_DYING_ABORT):
- spin_unlock(&p->proc_lock);
- return;
- case PROC_CREATED:
- case PROC_RUNNABLE_S:
- case PROC_WAITING:
- break;
- case PROC_RUNNABLE_M:
- case PROC_RUNNING_M:
- /* Need to reclaim any cores this proc might have, even if it's not
- * running yet. Those running will receive a __death */
- nr_cores_revoked = __proc_take_allcores(p, pc_arr, FALSE);
- break;
- case PROC_RUNNING_S:
- #if 0
- // here's how to do it manually
- if (current == p) {
- lcr3(boot_cr3);
- current = NULL;
- proc_decref(p); /* this decref is for the cr3 */
- }
- #endif
- send_kernel_message(get_pcoreid(p, 0), __death, (long)p, 0, 0,
- KMSG_ROUTINE);
- __seq_start_write(&p->procinfo->coremap_seqctr);
- __unmap_vcore(p, 0);
- __seq_end_write(&p->procinfo->coremap_seqctr);
- /* If we ever have RUNNING_S run on non-mgmt cores, we'll need to
- * tell the ksched about this now-idle core (after unlocking) */
- break;
- default:
- warn("Weird state(%s) in %s()", procstate2str(p->state),
- __FUNCTION__);
- spin_unlock(&p->proc_lock);
- return;
+ case PROC_DYING: /* someone else killed this already. */
+ case (PROC_DYING_ABORT):
+ spin_unlock(&p->proc_lock);
+ return;
+ case PROC_CREATED:
+ case PROC_RUNNABLE_S:
+ case PROC_WAITING:
+ break;
+ case PROC_RUNNABLE_M:
+ case PROC_RUNNING_M:
+ /* Need to reclaim any cores this proc might have, even if it's
+ * not running yet. Those running will receive a __death */
+ nr_cores_revoked = __proc_take_allcores(p, pc_arr, FALSE);
+ break;
+ case PROC_RUNNING_S:
+ #if 0
+ // here's how to do it manually
+ if (current == p) {
+ lcr3(boot_cr3);
+ current = NULL;
+ proc_decref(p); /* this decref is for the cr3 */
+ }
+ #endif
+ send_kernel_message(get_pcoreid(p, 0), __death, (long)p, 0, 0,
+ KMSG_ROUTINE);
+ __seq_start_write(&p->procinfo->coremap_seqctr);
+ __unmap_vcore(p, 0);
+ __seq_end_write(&p->procinfo->coremap_seqctr);
+ /* If we ever have RUNNING_S run on non-mgmt cores, we'll need
+ * to tell the ksched about this now-idle core (after unlocking)
+ */
+ break;
+ default:
+ warn("Weird state(%s) in %s()", procstate2str(p->state),
+ __FUNCTION__);
+ spin_unlock(&p->proc_lock);
+ return;
}
/* At this point, a death IPI should be on its way, either from the
* RUNNING_S one, or from proc_take_cores with a __death. in general,
- * interrupts should be on when you call proc_destroy locally, but currently
- * aren't for all things (like traphandlers). */
+ * interrupts should be on when you call proc_destroy locally, but
+ * currently aren't for all things (like traphandlers). */
__proc_set_state(p, PROC_DYING);
spin_unlock(&p->proc_lock);
proc_disown_children(p);
/* Wake any of our kthreads waiting on children, so they can abort */
cv_broadcast(&p->child_wait);
/* we need to close files here, and not in free, since we could have a
- * refcnt indirectly related to one of our files. specifically, if we have
- * a parent sleeping on our pipe, that parent won't wake up to decref until
- * the pipe closes. And if the parent doesnt decref, we don't free.
- * Even if we send a SIGCHLD to the parent, that would require that the
- * parent to never ignores that signal (or we risk never reaping).
+ * refcnt indirectly related to one of our files. specifically, if we
+ * have a parent sleeping on our pipe, that parent won't wake up to
+ * decref until the pipe closes. And if the parent doesnt decref, we
+ * don't free. Even if we send a SIGCHLD to the parent, that would
+ * require that the parent to never ignores that signal (or we risk
+ * never reaping).
*
- * Also note that any mmap'd files will still be mmapped. You can close the
- * file after mmapping, with no effect. */
+ * Also note that any mmap'd files will still be mmapped. You can close
+ * the file after mmapping, with no effect. */
close_fdt(&p->open_files, FALSE);
- /* Abort any abortable syscalls. This won't catch every sleeper, but future
- * abortable sleepers are already prevented via the DYING_ABORT state.
- * (signalled DYING_ABORT, no new sleepers will block, and now we wake all
- * old sleepers). */
+ /* Abort any abortable syscalls. This won't catch every sleeper, but
+ * future abortable sleepers are already prevented via the DYING_ABORT
+ * state. (signalled DYING_ABORT, no new sleepers will block, and now
+ * we wake all old sleepers). */
__proc_set_state(p, PROC_DYING_ABORT);
abort_all_sysc(p);
/* Tell the ksched about our death, and which cores we freed up */
@@ -931,10 +961,11 @@
if (!parent)
return;
send_posix_signal(parent, SIGCHLD);
- /* there could be multiple kthreads sleeping for various reasons. even an
- * SCP could have multiple async syscalls. */
+ /* there could be multiple kthreads sleeping for various reasons. even
+ * an SCP could have multiple async syscalls. */
cv_broadcast(&parent->child_wait);
- /* if the parent was waiting, there's a __launch kthread KMSG out there */
+ /* if the parent was waiting, there's a __launch kthread KMSG out there
+ */
proc_decref(parent);
}
@@ -951,8 +982,8 @@
assert(child->ppid == parent->pid);
/* lock protects from concurrent inserts / removals from the list */
TAILQ_REMOVE(&parent->children, child, sibling_link);
- /* After this, the child won't be able to get more refs to us, but it may
- * still have some references in running code. */
+ /* After this, the child won't be able to get more refs to us, but it
+ * may still have some references in running code. */
child->ppid = 0;
return 0;
}
@@ -967,53 +998,54 @@
if (__proc_is_mcp(p))
goto error_out;
switch (p->state) {
- case (PROC_RUNNING_S):
- /* issue with if we're async or not (need to preempt it)
- * either of these should trip it. TODO: (ACR) async core req */
- if ((current != p) || (get_pcoreid(p, 0) != core_id()))
- panic("We don't handle async RUNNING_S core requests yet.");
- struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[0];
- assert(current_ctx);
- /* Copy uthread0's context to VC 0's uthread slot */
- copy_current_ctx_to(&vcpd->uthread_ctx);
- clear_owning_proc(core_id()); /* so we don't restart */
- save_vc_fp_state(vcpd);
- /* Userspace needs to not fuck with notif_disabled before
- * transitioning to _M. */
- if (vcpd->notif_disabled) {
- printk("[kernel] user bug: notifs disabled for vcore 0\n");
- vcpd->notif_disabled = FALSE;
- }
- /* in the async case, we'll need to remotely stop and bundle
- * vcore0's TF. this is already done for the sync case (local
- * syscall). */
- /* this process no longer runs on its old location (which is
- * this core, for now, since we don't handle async calls) */
- __seq_start_write(&p->procinfo->coremap_seqctr);
- // TODO: (ACR) will need to unmap remotely (receive-side)
- __unmap_vcore(p, 0);
- vcore_account_offline(p, 0);
- __seq_end_write(&p->procinfo->coremap_seqctr);
- /* change to runnable_m (it's TF is already saved) */
- __proc_set_state(p, PROC_RUNNABLE_M);
- p->procinfo->is_mcp = TRUE;
- spin_unlock(&p->proc_lock);
- /* Tell the ksched that we're a real MCP now! */
- __sched_proc_change_to_m(p);
- return 0;
- case (PROC_RUNNABLE_S):
- /* Issues: being on the runnable_list, proc_set_state not liking
- * it, and not clearly thinking through how this would happen.
- * Perhaps an async call that gets serviced after you're
- * descheduled? */
- warn("Not supporting RUNNABLE_S -> RUNNABLE_M yet.\n");
- goto error_out;
- case (PROC_DYING):
- case (PROC_DYING_ABORT):
- warn("Dying, core request coming from %d\n", core_id());
- goto error_out;
- default:
- goto error_out;
+ case (PROC_RUNNING_S):
+ /* issue with if we're async or not (need to preempt it)
+ * either of these should trip it. TODO: (ACR) async core req */
+ if ((current != p) || (get_pcoreid(p, 0) != core_id()))
+ panic("We don't handle async RUNNING_S core requests");
+ struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[0];
+
+ assert(current_ctx);
+ /* Copy uthread0's context to VC 0's uthread slot */
+ copy_current_ctx_to(&vcpd->uthread_ctx);
+ clear_owning_proc(core_id()); /* so we don't restart */
+ save_vc_fp_state(vcpd);
+ /* Userspace needs to not fuck with notif_disabled before
+ * transitioning to _M. */
+ if (vcpd->notif_disabled) {
+ printk("[kernel] user bug: notifs disabled for vcore 0\n");
+ vcpd->notif_disabled = FALSE;
+ }
+ /* in the async case, we'll need to remotely stop and bundle
+ * vcore0's TF. this is already done for the sync case (local
+ * syscall). */
+ /* this process no longer runs on its old location (which is
+ * this core, for now, since we don't handle async calls) */
+ __seq_start_write(&p->procinfo->coremap_seqctr);
+ // TODO: (ACR) will need to unmap remotely (receive-side)
+ __unmap_vcore(p, 0);
+ vcore_account_offline(p, 0);
+ __seq_end_write(&p->procinfo->coremap_seqctr);
+ /* change to runnable_m (it's TF is already saved) */
+ __proc_set_state(p, PROC_RUNNABLE_M);
+ p->procinfo->is_mcp = TRUE;
+ spin_unlock(&p->proc_lock);
+ /* Tell the ksched that we're a real MCP now! */
+ __sched_proc_change_to_m(p);
+ return 0;
+ case (PROC_RUNNABLE_S):
+ /* Issues: being on the runnable_list, proc_set_state not liking
+ * it, and not clearly thinking through how this would happen.
+ * Perhaps an async call that gets serviced after you're
+ * descheduled? */
+ warn("Not supporting RUNNABLE_S -> RUNNABLE_M yet.\n");
+ goto error_out;
+ case (PROC_DYING):
+ case (PROC_DYING_ABORT):
+ warn("Dying, core request coming from %d\n", core_id());
+ goto error_out;
+ default:
+ goto error_out;
}
error_out:
spin_unlock(&p->proc_lock);
@@ -1028,6 +1060,7 @@
{
struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[0];
uint32_t num_revoked;
+
/* Not handling vcore accounting. Do so if we ever use this */
printk("[kernel] trying to transition _M -> _S (deprecated)!\n");
assert(p->state == PROC_RUNNING_M); // TODO: (ACR) async core req
@@ -1107,6 +1140,7 @@
void __proc_save_fpu_s(struct proc *p)
{
struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[0];
+
save_vc_fp_state(vcpd);
}
@@ -1154,88 +1188,95 @@
struct per_cpu_info *pcpui = &per_cpu_info[pcoreid];
struct vcore *vc;
struct preempt_data *vcpd;
- /* Need to lock to prevent concurrent vcore changes (online, inactive, the
- * mapping, etc). This plus checking the nr_preempts is enough to tell if
- * our vcoreid and cur_ctx ought to be here still or if we should abort */
+
+ /* Need to lock to prevent concurrent vcore changes (online, inactive,
+ * the mapping, etc). This plus checking the nr_preempts is enough to
+ * tell if our vcoreid and cur_ctx ought to be here still or if we
+ * should abort */
spin_lock(&p->proc_lock); /* horrible scalability. =( */
switch (p->state) {
- case (PROC_RUNNING_S):
- if (!being_nice) {
- /* waiting for an event to unblock us */
- vcpd = &p->procdata->vcore_preempt_data[0];
- /* syncing with event's SCP code. we set waiting, then check
- * pending. they set pending, then check waiting. it's not
- * possible for us to miss the notif *and* for them to miss
- * WAITING. one (or both) of us will see and make sure the proc
- * wakes up. */
- __proc_set_state(p, PROC_WAITING);
- wrmb(); /* don't let the state write pass the notif read */
- if (vcpd->notif_pending) {
- __proc_set_state(p, PROC_RUNNING_S);
- /* they can't handle events, just need to prevent a yield.
- * (note the notif_pendings are collapsed). */
- if (!scp_is_vcctx_ready(vcpd))
- vcpd->notif_pending = FALSE;
- goto out_failed;
- }
- /* if we're here, we want to sleep. a concurrent event that
- * hasn't already written notif_pending will have seen WAITING,
- * and will be spinning while we do this. */
- __proc_save_context_s(p);
- spin_unlock(&p->proc_lock);
- } else {
- /* yielding to allow other processes to run. we're briefly
- * WAITING, til we are woken up */
- __proc_set_state(p, PROC_WAITING);
- __proc_save_context_s(p);
- spin_unlock(&p->proc_lock);
- /* immediately wake up the proc (makes it runnable) */
- proc_wakeup(p);
+ case (PROC_RUNNING_S):
+ if (!being_nice) {
+ /* waiting for an event to unblock us */
+ vcpd = &p->procdata->vcore_preempt_data[0];
+ /* syncing with event's SCP code. we set waiting, then
+ * check pending. they set pending, then check waiting.
+ * it's not possible for us to miss the notif *and* for
+ * them to miss WAITING. one (or both) of us will see
+ * and make sure the proc wakes up. */
+ __proc_set_state(p, PROC_WAITING);
+ /* don't let the state write pass the notif read */
+ wrmb();
+ if (vcpd->notif_pending) {
+ __proc_set_state(p, PROC_RUNNING_S);
+ /* they can't handle events, just need to
+ * prevent a yield. (note the notif_pendings
+ * are collapsed). */
+ if (!scp_is_vcctx_ready(vcpd))
+ vcpd->notif_pending = FALSE;
+ goto out_failed;
}
- goto out_yield_core;
- case (PROC_RUNNING_M):
- break; /* will handle this stuff below */
- case (PROC_DYING): /* incoming __death */
- case (PROC_DYING_ABORT):
- case (PROC_RUNNABLE_M): /* incoming (bulk) preempt/myield TODO:(BULK) */
- goto out_failed;
- default:
- panic("Weird state(%s) in %s()", procstate2str(p->state),
- __FUNCTION__);
+ /* if we're here, we want to sleep. a concurrent event
+ * that hasn't already written notif_pending will have
+ * seen WAITING, and will be spinning while we do this.
+ * */
+ __proc_save_context_s(p);
+ spin_unlock(&p->proc_lock);
+ } else {
+ /* yielding to allow other processes to run. we're
+ * briefly WAITING, til we are woken up */
+ __proc_set_state(p, PROC_WAITING);
+ __proc_save_context_s(p);
+ spin_unlock(&p->proc_lock);
+ /* immediately wake up the proc (makes it runnable) */
+ proc_wakeup(p);
+ }
+ goto out_yield_core;
+ case (PROC_RUNNING_M):
+ break; /* will handle this stuff below */
+ case (PROC_DYING): /* incoming __death */
+ case (PROC_DYING_ABORT):
+ case (PROC_RUNNABLE_M): /* incoming (bulk) preempt/myield TODO:(BULK) */
+ goto out_failed;
+ default:
+ panic("Weird state(%s) in %s()", procstate2str(p->state),
+ __FUNCTION__);
}
- /* This is which vcore this pcore thinks it is, regardless of any unmappings
- * that may have happened remotely (with __PRs waiting to run) */
+ /* This is which vcore this pcore thinks it is, regardless of any
+ * unmappings that may have happened remotely (with __PRs waiting to
+ * run) */
vcoreid = pcpui->owning_vcoreid;
vc = vcoreid2vcore(p, vcoreid);
vcpd = &p->procdata->vcore_preempt_data[vcoreid];
/* This is how we detect whether or not a __PR happened. */
if (vc->nr_preempts_sent != vc->nr_preempts_done)
goto out_failed;
- /* Sanity checks. If we were preempted or are dying, we should have noticed
- * by now. */
+ /* Sanity checks. If we were preempted or are dying, we should have
+ * noticed by now. */
assert(is_mapped_vcore(p, pcoreid));
assert(vcoreid == get_vcoreid(p, pcoreid));
/* no reason to be nice, return */
if (being_nice && !vc->preempt_pending)
goto out_failed;
/* At this point, AFAIK there should be no preempt/death messages on the
- * way, and we're on the online list. So we'll go ahead and do the yielding
- * business. */
- /* If there's a preempt pending, we don't need to preempt later since we are
- * yielding (nice or otherwise). If not, this is just a regular yield. */
+ * way, and we're on the online list. So we'll go ahead and do the
+ * yielding business. */
+ /* If there's a preempt pending, we don't need to preempt later since we
+ * are yielding (nice or otherwise). If not, this is just a regular
+ * yield. */
if (vc->preempt_pending) {
vc->preempt_pending = 0;
} else {
- /* Optional: on a normal yield, check to see if we are putting them
- * below amt_wanted (help with user races) and bail. */
+ /* Optional: on a normal yield, check to see if we are putting
+ * them below amt_wanted (help with user races) and bail. */
if (p->procdata->res_req[RES_CORES].amt_wanted >=
p->procinfo->num_vcores)
goto out_failed;
}
- /* Don't let them yield if they are missing a notification. Userspace must
- * not leave vcore context without dealing with notif_pending.
- * pop_user_ctx() handles leaving via uthread context. This handles leaving
- * via a yield.
+ /* Don't let them yield if they are missing a notification. Userspace
+ * must not leave vcore context without dealing with notif_pending.
+ * pop_user_ctx() handles leaving via uthread context. This handles
+ * leaving via a yield.
*
* This early check is an optimization. The real check is below when it
* works with the online_vcs list (syncing with event.c and INDIR/IPI
@@ -1254,8 +1295,9 @@
/* Note we need interrupts disabled, since a __notify can come in
* and set pending to FALSE */
if (vcpd->notif_pending) {
- /* We lost, put it back on the list and abort the yield. If we ever
- * build an myield, we'll need a way to deal with this for all vcores */
+ /* We lost, put it back on the list and abort the yield. If we
+ * ever build an myield, we'll need a way to deal with this for
+ * all vcores */
TAILQ_INSERT_TAIL(&p->online_vcs, vc, list); /* could go HEAD */
goto out_failed;
}
@@ -1279,14 +1321,15 @@
__proc_set_state(p, PROC_WAITING);
}
spin_unlock(&p->proc_lock);
- /* We discard the current context, but we still need to restore the core */
+ /* We discard the current context, but we still need to restore the core
+ */
arch_finalize_ctx(pcpui->cur_ctx);
/* Hand the now-idle core to the ksched */
__sched_put_idle_core(p, pcoreid);
goto out_yield_core;
out_failed:
- /* for some reason we just want to return, either to take a KMSG that cleans
- * us up, or because we shouldn't yield (ex: notif_pending). */
+ /* for some reason we just want to return, either to take a KMSG that
+ * cleans us up, or because we shouldn't yield (ex: notif_pending). */
spin_unlock(&p->proc_lock);
return;
out_yield_core: /* successfully yielded the core */
@@ -1309,27 +1352,29 @@
{
struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[vcoreid];
- /* If you're thinking about checking notif_pending and then returning if it
- * is already set, note that some callers (e.g. the event system) set
- * notif_pending when they deliver a message, regardless of whether there is
- * an IPI or not. Those callers assume that we don't care about
- * notif_pending, only notif_disabled. So don't change this without
- * changing them (probably can't without a lot of thought - that
- * notif_pending is about missing messages. It might be possible to say "no
- * IPI, but don't let me miss messages that were delivered." */
+ /* If you're thinking about checking notif_pending and then returning if
+ * it is already set, note that some callers (e.g. the event system) set
+ * notif_pending when they deliver a message, regardless of whether
+ * there is an IPI or not. Those callers assume that we don't care
+ * about notif_pending, only notif_disabled. So don't change this
+ * without changing them (probably can't without a lot of thought - that
+ * notif_pending is about missing messages. It might be possible to say
+ * "no IPI, but don't let me miss messages that were delivered." */
vcpd->notif_pending = TRUE;
wrmb(); /* must write notif_pending before reading notif_disabled */
if (!vcpd->notif_disabled) {
/* GIANT WARNING: we aren't using the proc-lock to protect the
- * vcoremap. We want to be able to use this from interrupt context,
- * and don't want the proc_lock to be an irqsave. Spurious
- * __notify() kmsgs are okay (it checks to see if the right receiver
- * is current). */
+ * vcoremap. We want to be able to use this from interrupt
+ * context, and don't want the proc_lock to be an irqsave.
+ * Spurious __notify() kmsgs are okay (it checks to see if the
+ * right receiver is current). */
if (vcore_is_mapped(p, vcoreid)) {
printd("[kernel] sending notif to vcore %d\n", vcoreid);
- /* This use of try_get_pcoreid is racy, might be unmapped */
- send_kernel_message(try_get_pcoreid(p, vcoreid), __notify, (long)p,
- 0, 0, KMSG_ROUTINE);
+ /* This use of try_get_pcoreid is racy, might be
+ * unmapped */
+ send_kernel_message(try_get_pcoreid(p, vcoreid),
+ __notify, (long)p, 0, 0,
+ KMSG_ROUTINE);
}
}
}
@@ -1353,28 +1398,30 @@
__sched_mcp_wakeup(p);
return;
} else {
- /* SCPs can wake up for a variety of reasons. the only times we need
- * to do something is if it was waiting or just created. other cases
- * are either benign (just go out), or potential bugs (_Ms) */
+ /* SCPs can wake up for a variety of reasons. the only times we
+ * need to do something is if it was waiting or just created.
+ * other cases are either benign (just go out), or potential
+ * bugs (_Ms) */
switch (p->state) {
- case (PROC_CREATED):
- case (PROC_WAITING):
- __proc_set_state(p, PROC_RUNNABLE_S);
- break;
- case (PROC_RUNNABLE_S):
- case (PROC_RUNNING_S):
- case (PROC_DYING):
- case (PROC_DYING_ABORT):
- spin_unlock(&p->proc_lock);
- return;
- case (PROC_RUNNABLE_M):
- case (PROC_RUNNING_M):
- warn("Weird state(%s) in %s()", procstate2str(p->state),
- __FUNCTION__);
- spin_unlock(&p->proc_lock);
- return;
+ case (PROC_CREATED):
+ case (PROC_WAITING):
+ __proc_set_state(p, PROC_RUNNABLE_S);
+ break;
+ case (PROC_RUNNABLE_S):
+ case (PROC_RUNNING_S):
+ case (PROC_DYING):
+ case (PROC_DYING_ABORT):
+ spin_unlock(&p->proc_lock);
+ return;
+ case (PROC_RUNNABLE_M):
+ case (PROC_RUNNING_M):
+ warn("Weird state(%s) in %s()", procstate2str(p->state),
+ __FUNCTION__);
+ spin_unlock(&p->proc_lock);
+ return;
}
- printd("[kernel] FYI, waking up an _S proc\n"); /* thanks, past brho! */
+ /* thanks, past brho! */
+ printd("[kernel] FYI, waking up an _S proc\n");
spin_unlock(&p->proc_lock);
__sched_scp_wakeup(p);
}
@@ -1384,13 +1431,15 @@
bool __proc_is_mcp(struct proc *p)
{
/* in lieu of using the amount of cores requested, or having a bunch of
- * states (like PROC_WAITING_M and _S), I'll just track it with a bool. */
+ * states (like PROC_WAITING_M and _S), I'll just track it with a bool.
+ */
return p->procinfo->is_mcp;
}
bool proc_is_vcctx_ready(struct proc *p)
{
struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[0];
+
return scp_is_vcctx_ready(vcpd);
}
@@ -1411,15 +1460,16 @@
void __proc_preempt_warn(struct proc *p, uint32_t vcoreid, uint64_t when)
{
struct event_msg local_msg = {0};
- /* danger with doing this unlocked: preempt_pending is set, but never 0'd,
- * since it is unmapped and not dealt with (TODO)*/
+
+ /* danger with doing this unlocked: preempt_pending is set, but never
+ * 0'd, since it is unmapped and not dealt with (TODO)*/
p->procinfo->vcoremap[vcoreid].preempt_pending = when;
/* Send the event (which internally checks to see how they want it) */
local_msg.ev_type = EV_PREEMPT_PENDING;
local_msg.ev_arg1 = vcoreid;
- /* Whenever we send msgs with the proc locked, we need at least 1 online.
- * Caller needs to make sure the core was online/mapped. */
+ /* Whenever we send msgs with the proc locked, we need at least 1
+ * online. Caller needs to make sure the core was online/mapped. */
assert(!TAILQ_EMPTY(&p->online_vcs));
send_kernel_event(p, &local_msg, vcoreid);
@@ -1451,10 +1501,10 @@
// expects a pcorelist. assumes pcore is mapped and running_m
__proc_take_corelist(p, &pcoreid, 1, TRUE);
/* Only send the message if we have an online core. o/w, it would fuck
- * us up (deadlock), and hey don't need a message. the core we just took
- * will be the first one to be restarted. It will look like a notif. in
- * the future, we could send the event if we want, but the caller needs to
- * do that (after unlocking). */
+ * us up (deadlock), and hey don't need a message. the core we just
+ * took will be the first one to be restarted. It will look like a
+ * notif. in the future, we could send the event if we want, but the
+ * caller needs to do that (after unlocking). */
if (!TAILQ_EMPTY(&p->online_vcs)) {
preempt_msg.ev_type = EV_VCORE_PREEMPT;
preempt_msg.ev_arg2 = vcoreid;
@@ -1467,8 +1517,10 @@
uint32_t __proc_preempt_all(struct proc *p, uint32_t *pc_arr)
{
struct vcore *vc_i;
- /* TODO:(BULK) PREEMPT - don't bother with this, set a proc wide flag, or
- * just make us RUNNABLE_M. Note this is also used by __map_vcore. */
+
+ /* TODO:(BULK) PREEMPT - don't bother with this, set a proc wide flag,
+ * or just make us RUNNABLE_M. Note this is also used by __map_vcore.
+ */
TAILQ_FOREACH(vc_i, &p->online_vcs, list)
vc_i->nr_preempts_sent++;
return __proc_take_allcores(p, pc_arr, TRUE);
@@ -1482,7 +1534,7 @@
uint64_t warn_time = read_tsc() + usec2tsc(usec);
bool retval = FALSE;
if (p->state != PROC_RUNNING_M) {
- /* more of an FYI for brho. should be harmless to just return. */
+ /* more of an FYI for brho. should be harmless to return. */
warn("Tried to preempt from a non RUNNING_M proc!");
return FALSE;
}
@@ -1505,9 +1557,12 @@
{
uint64_t warn_time = read_tsc() + usec2tsc(usec);
uint32_t num_revoked = 0;
+
spin_lock(&p->proc_lock);
- /* storage for pc_arr is alloced at decl, which is after grabbing the lock*/
+ /* storage for pc_arr is alloced at decl, which is after grabbing the
+ * lock*/
uint32_t pc_arr[p->procinfo->num_vcores];
+
/* DYING could be okay */
if (p->state != PROC_RUNNING_M) {
warn("Tried to preempt from a non RUNNING_M proc!");
@@ -1542,10 +1597,12 @@
uint32_t proc_get_vcoreid(struct proc *p)
{
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+
if (pcpui->owning_proc == p) {
return pcpui->owning_vcoreid;
} else {
- warn("Asked for vcoreid for %p, but %p is pwns", p, pcpui->owning_proc);
+ warn("Asked for vcoreid for %p, but %p is pwns", p,
+ pcpui->owning_proc);
return (uint32_t)-1;
}
}
@@ -1576,6 +1633,7 @@
struct vcore_tailq *vc_list, struct vcore **vc)
{
struct vcore *new_vc;
+
new_vc = TAILQ_FIRST(vc_list);
if (!new_vc)
return FALSE;
@@ -1595,15 +1653,17 @@
assert(p->state == PROC_RUNNABLE_M);
assert(num); /* catch bugs */
/* add new items to the vcoremap */
- __seq_start_write(&p->procinfo->coremap_seqctr);/* unncessary if offline */
+ /* unncessary if offline */
+ __seq_start_write(&p->procinfo->coremap_seqctr);
p->procinfo->num_vcores += num;
for (int i = 0; i < num; i++) {
/* Try from the bulk list first */
- if (__proc_give_a_pcore(p, pc_arr[i], &p->bulk_preempted_vcs, 0))
+ if (__proc_give_a_pcore(p, pc_arr[i], &p->bulk_preempted_vcs,
+ 0))
continue;
- /* o/w, try from the inactive list. at one point, i thought there might
- * be a legit way in which the inactive list could be empty, but that i
- * wanted to catch it via an assert. */
+ /* o/w, try from the inactive list. at one point, i thought
+ * there might be a legit way in which the inactive list could
+ * be empty, but that i wanted to catch it via an assert. */
assert(__proc_give_a_pcore(p, pc_arr[i], &p->inactive_vcs, 0));
}
__seq_end_write(&p->procinfo->coremap_seqctr);
@@ -1620,7 +1680,8 @@
p->procinfo->num_vcores += num;
assert(TAILQ_EMPTY(&p->bulk_preempted_vcs));
for (int i = 0; i < num; i++) {
- assert(__proc_give_a_pcore(p, pc_arr[i], &p->inactive_vcs, &vc_i));
+ assert(__proc_give_a_pcore(p, pc_arr[i], &p->inactive_vcs,
+ &vc_i));
send_kernel_message(pc_arr[i], __startcore, (long)p,
(long)vcore2vcoreid(p, vc_i),
(long)vc_i->nr_preempts_sent, KMSG_ROUTINE);
@@ -1649,24 +1710,24 @@
/* should never happen: */
assert(num + p->procinfo->num_vcores <= MAX_NUM_CORES);
switch (p->state) {
- case (PROC_RUNNABLE_S):
- case (PROC_RUNNING_S):
- warn("Don't give cores to a process in a *_S state!\n");
- return -1;
- case (PROC_DYING):
- case (PROC_DYING_ABORT):
- case (PROC_WAITING):
- /* can't accept, just fail */
- return -1;
- case (PROC_RUNNABLE_M):
- __proc_give_cores_runnable(p, pc_arr, num);
- break;
- case (PROC_RUNNING_M):
- __proc_give_cores_running(p, pc_arr, num);
- break;
- default:
- panic("Weird state(%s) in %s()", procstate2str(p->state),
- __FUNCTION__);
+ case (PROC_RUNNABLE_S):
+ case (PROC_RUNNING_S):
+ warn("Don't give cores to a process in a *_S state!\n");
+ return -1;
+ case (PROC_DYING):
+ case (PROC_DYING_ABORT):
+ case (PROC_WAITING):
+ /* can't accept, just fail */
+ return -1;
+ case (PROC_RUNNABLE_M):
+ __proc_give_cores_runnable(p, pc_arr, num);
+ break;
+ case (PROC_RUNNING_M):
+ __proc_give_cores_running(p, pc_arr, num);
+ break;
+ default:
+ panic("Weird state(%s) in %s()", procstate2str(p->state),
+ __FUNCTION__);
}
/* TODO: considering moving to the ksched (hard, due to yield) */
p->procinfo->res_grant[RES_CORES] += num;
@@ -1684,9 +1745,11 @@
/* Lock the vcore's state (necessary for preemption recovery) */
vcpd = &p->procdata->vcore_preempt_data[vcoreid];
atomic_or(&vcpd->flags, VC_K_LOCK);
- send_kernel_message(pcoreid, __preempt, (long)p, 0, 0, KMSG_ROUTINE);
+ send_kernel_message(pcoreid, __preempt, (long)p, 0, 0,
+ KMSG_ROUTINE);
} else {
- send_kernel_message(pcoreid, __death, (long)p, 0, 0, KMSG_ROUTINE);
+ send_kernel_message(pcoreid, __death, (long)p, 0, 0,
+ KMSG_ROUTINE);
}
}
@@ -1694,8 +1757,9 @@
static void __proc_revoke_allcores(struct proc *p, bool preempt)
{
struct vcore *vc_i;
- /* TODO: if we ever get broadcast messaging, use it here (still need to lock
- * the vcores' states for preemption) */
+
+ /* TODO: if we ever get broadcast messaging, use it here (still need to
+ * lock the vcores' states for preemption) */
TAILQ_FOREACH(vc_i, &p->online_vcs, list)
__proc_revoke_core(p, vcore2vcoreid(p, vc_i), preempt);
}
@@ -1729,13 +1793,14 @@
if (p->state == PROC_RUNNING_M)
__proc_revoke_core(p, vcoreid, preempt);
__unmap_vcore(p, vcoreid);
- /* Change lists for the vcore. Note, the vcore is already unmapped
- * and/or the messages are already in flight. The only code that looks
- * at the lists without holding the lock is event code. */
+ /* Change lists for the vcore. Note, the vcore is already
+ * unmapped and/or the messages are already in flight. The only
+ * code that looks at the lists without holding the lock is
+ * event code. */
vc = vcoreid2vcore(p, vcoreid);
TAILQ_REMOVE(&p->online_vcs, vc, list);
- /* even for single preempts, we use the inactive list. bulk preempt is
- * only used for when we take everything. */
+ /* even for single preempts, we use the inactive list. bulk
+ * preempt is only used for when we take everything. */
TAILQ_INSERT_HEAD(&p->inactive_vcs, vc, list);
}
p->procinfo->num_vcores -= num;
@@ -1765,7 +1830,8 @@
__proc_unmap_allcores(p);
/* Move the vcores from online to the head of the appropriate list */
TAILQ_FOREACH_SAFE(vc_i, &p->online_vcs, list, vc_temp) {
- /* TODO: we may want a TAILQ_CONCAT_HEAD, or something that does that */
+ /* TODO: we may want a TAILQ_CONCAT_HEAD, or something that does
+ * that */
TAILQ_REMOVE(&p->online_vcs, vc_i, list);
/* Put the cores on the appropriate list */
if (preempt)
@@ -1795,7 +1861,8 @@
* calling. */
void __unmap_vcore(struct proc *p, uint32_t vcoreid)
{
- p->procinfo->pcoremap[p->procinfo->vcoremap[vcoreid].pcoreid].valid = FALSE;
+ p->procinfo->pcoremap[p->procinfo->vcoremap[vcoreid].pcoreid].valid =
+ FALSE;
p->procinfo->vcoremap[vcoreid].valid = FALSE;
}
@@ -1809,8 +1876,10 @@
bool abandon_core(void)
{
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
- /* Syscalls that don't return will ultimately call abadon_core(), so we need
- * to make sure we don't think we are still working on a syscall. */
+
+ /* Syscalls that don't return will ultimately call abadon_core(), so we
+ * need to make sure we don't think we are still working on a syscall.
+ * */
pcpui->cur_kthread->sysc = 0;
pcpui->cur_kthread->errbuf = 0; /* just in case */
if (pcpui->cur_proc) {
@@ -1830,7 +1899,7 @@
__clear_owning_proc(coreid);
pcpui->owning_proc = 0;
pcpui->owning_vcoreid = 0xdeadbeef;
- pcpui->cur_ctx = 0; /* catch bugs for now (may go away) */
+ pcpui->cur_ctx = 0; /* catch bugs for now (may go away) */
if (p)
proc_decref(p);
}
@@ -1847,10 +1916,10 @@
struct proc *old_proc;
uintptr_t ret;
- old_proc = pcpui->cur_proc; /* uncounted ref */
+ old_proc = pcpui->cur_proc; /* uncounted ref */
/* If we aren't the proc already, then switch to it */
if (old_proc != new_p) {
- pcpui->cur_proc = new_p; /* uncounted ref */
+ pcpui->cur_proc = new_p; /* uncounted ref */
if (new_p)
lcr3(new_p->env_cr3);
else
@@ -1860,8 +1929,8 @@
if (is_ktask(kth)) {
if (!(kth->flags & KTH_SAVE_ADDR_SPACE)) {
kth->flags |= KTH_SAVE_ADDR_SPACE;
- /* proc pointers are aligned; we can use the lower bit as a signal
- * to turn off SAVE_ADDR_SPACE. */
+ /* proc pointers are aligned; we can use the lower bit
+ * as a signal to turn off SAVE_ADDR_SPACE. */
ret |= 0x1;
}
}
@@ -1904,33 +1973,37 @@
* immediate message. */
void proc_tlbshootdown(struct proc *p, uintptr_t start, uintptr_t end)
{
- /* TODO: need a better way to find cores running our address space. we can
- * have kthreads running syscalls, async calls, processes being created. */
+ /* TODO: need a better way to find cores running our address space. we
+ * can have kthreads running syscalls, async calls, processes being
+ * created. */
struct vcore *vc_i;
- /* TODO: we might be able to avoid locking here in the future (we must hit
- * all online, and we can check __mapped). it'll be complicated. */
+
+ /* TODO: we might be able to avoid locking here in the future (we must
+ * hit all online, and we can check __mapped). it'll be complicated. */
spin_lock(&p->proc_lock);
switch (p->state) {
- case (PROC_RUNNING_S):
+ case (PROC_RUNNING_S):
+ tlbflush();
+ break;
+ case (PROC_RUNNING_M):
+ /* TODO: (TLB) sanity checks and rounding on the ranges.
+ *
+ * We need to make sure that once a core that was online has
+ * been removed from the online list, then it must receive a TLB
+ * flush (abandon_core()) before running the process again.
+ * Either that, or make other decisions about who to
+ * TLB-shootdown. */
+ TAILQ_FOREACH(vc_i, &p->online_vcs, list) {
+ send_kernel_message(vc_i->pcoreid, __tlbshootdown,
+ start, end, 0, KMSG_IMMEDIATE);
+ }
+ break;
+ default:
+ /* TODO: til we fix shootdowns, there are some odd cases where
+ * we have the address space loaded, but the state is in
+ * transition. */
+ if (p == current)
tlbflush();
- break;
- case (PROC_RUNNING_M):
- /* TODO: (TLB) sanity checks and rounding on the ranges.
- *
- * We need to make sure that once a core that was online has been
- * removed from the online list, then it must receive a TLB flush
- * (abandon_core()) before running the process again. Either that,
- * or make other decisions about who to TLB-shootdown. */
- TAILQ_FOREACH(vc_i, &p->online_vcs, list) {
- send_kernel_message(vc_i->pcoreid, __tlbshootdown, start, end,
- 0, KMSG_IMMEDIATE);
- }
- break;
- default:
- /* TODO: til we fix shootdowns, there are some odd cases where we
- * have the address space loaded, but the state is in transition. */
- if (p == current)
- tlbflush();
}
spin_unlock(&p->proc_lock);
}
@@ -1944,34 +2017,37 @@
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[vcoreid];
struct vcore *vc = vcoreid2vcore(p, vcoreid);
- /* Spin until our vcore's old preemption is done. When __SC was sent, we
- * were told what the nr_preempts_sent was at that time. Once that many are
- * done, it is time for us to run. This forces a 'happens-before' ordering
- * on a __PR of our VC before this __SC of the VC. Note the nr_done should
- * not exceed old_nr_sent, since further __PR are behind this __SC in the
- * KMSG queue. */
+
+ /* Spin until our vcore's old preemption is done. When __SC was sent,
+ * we were told what the nr_preempts_sent was at that time. Once that
+ * many are done, it is time for us to run. This forces a
+ * 'happens-before' ordering on a __PR of our VC before this __SC of the
+ * VC. Note the nr_done should not exceed old_nr_sent, since further
+ * __PR are behind this __SC in the KMSG queue. */
while (old_nr_preempts_sent != vc->nr_preempts_done)
cpu_relax();
- cmb(); /* read nr_done before any other rd or wr. CPU mb in the atomic. */
+ /* read nr_done before any other rd or wr. CPU mb in the atomic. */
+ cmb();
/* Mark that this vcore as no longer preempted. No danger of clobbering
- * other writes, since this would get turned on in __preempt (which can't be
- * concurrent with this function on this core), and the atomic is just
- * toggling the one bit (a concurrent VC_K_LOCK will work) */
+ * other writes, since this would get turned on in __preempt (which
+ * can't be concurrent with this function on this core), and the atomic
+ * is just toggling the one bit (a concurrent VC_K_LOCK will work) */
atomic_and(&vcpd->flags, ~VC_PREEMPTED);
/* Once the VC is no longer preempted, we allow it to receive msgs. We
- * could let userspace do it, but handling it here makes it easier for them
- * to handle_indirs (when they turn this flag off). Note the atomics
- * provide the needed barriers (cmb and mb on flags). */
+ * could let userspace do it, but handling it here makes it easier for
+ * them to handle_indirs (when they turn this flag off). Note the
+ * atomics provide the needed barriers (cmb and mb on flags). */
atomic_or(&vcpd->flags, VC_CAN_RCV_MSG);
printd("[kernel] startcore on physical core %d for process %d's vcore %d\n",
core_id(), p->pid, vcoreid);
/* If notifs are disabled, the vcore was in vcore context and we need to
- * restart the vcore_ctx. o/w, we give them a fresh vcore (which is also
- * what happens the first time a vcore comes online). No matter what,
- * they'll restart in vcore context. It's just a matter of whether or not
- * it is the old, interrupted vcore context. */
+ * restart the vcore_ctx. o/w, we give them a fresh vcore (which is
+ * also what happens the first time a vcore comes online). No matter
+ * what, they'll restart in vcore context. It's just a matter of
+ * whether or not it is the old, interrupted vcore context. */
if (vcpd->notif_disabled) {
- /* copy-in the tf we'll pop, then set all security-related fields */
+ /* copy-in the tf we'll pop, then set all security-related
+ * fields */
pcpui->actual_ctx = vcpd->vcore_ctx;
proc_secure_ctx(&pcpui->actual_ctx);
} else { /* not restarting from a preemption, use a fresh vcore */
@@ -1981,19 +2057,19 @@
/* Disable/mask active notifications for fresh vcores */
vcpd->notif_disabled = TRUE;
}
- /* Regardless of whether or not we have a 'fresh' VC, we need to restore the
- * FPU state for the VC according to VCPD (which means either a saved FPU
- * state or a brand new init). Starting a fresh VC is just referring to the
- * GP context we run. The vcore itself needs to have the FPU state loaded
- * from when it previously ran and was saved (or a fresh FPU if it wasn't
- * saved). For fresh FPUs, the main purpose is for limiting info leakage.
- * I think VCs that don't need FPU state for some reason (like having a
- * current_uthread) can handle any sort of FPU state, since it gets sorted
- * when they pop their next uthread.
+ /* Regardless of whether or not we have a 'fresh' VC, we need to restore
+ * the FPU state for the VC according to VCPD (which means either a
+ * saved FPU state or a brand new init). Starting a fresh VC is just
+ * referring to the GP context we run. The vcore itself needs to have
+ * the FPU state loaded from when it previously ran and was saved (or a
+ * fresh FPU if it wasn't saved). For fresh FPUs, the main purpose is
+ * for limiting info leakage. I think VCs that don't need FPU state for
+ * some reason (like having a current_uthread) can handle any sort of
+ * FPU state, since it gets sorted when they pop their next uthread.
*
- * Note this can cause a GP fault on x86 if the state is corrupt. In lieu
- * of reading in the huge FP state and mucking with mxcsr_mask, we should
- * handle this like a KPF on user code. */
+ * Note this can cause a GP fault on x86 if the state is corrupt. In
+ * lieu of reading in the huge FP state and mucking with mxcsr_mask, we
+ * should handle this like a KPF on user code. */
restore_vc_fp_state(vcpd);
/* cur_ctx was built above (in actual_ctx), now use it */
pcpui->cur_ctx = &pcpui->actual_ctx;
@@ -2006,12 +2082,12 @@
* was preempted. Note we don't care about notif_pending.
*
* Will return:
- * 0 if we successfully changed to the target vcore.
- * -EBUSY if the target vcore is already mapped (a good kind of failure)
- * -EAGAIN if we failed for some other reason and need to try again. For
- * example, the caller could be preempted, and we never even attempted to
- * change.
- * -EINVAL some userspace bug */
+ * 0 if we successfully changed to the target vcore.
+ * -EBUSY if the target vcore is already mapped (a good kind of failure)
+ * -EAGAIN if we failed for some other reason and need to try again. For
+ * example, the caller could be preempted, and we never even attempted to
+ * change.
+ * -EINVAL some userspace bug */
int proc_change_to_vcore(struct proc *p, uint32_t new_vcoreid,
bool enable_my_notif)
{
@@ -2021,6 +2097,7 @@
struct vcore *caller_vc, *new_vc;
struct event_msg preempt_msg = {0};
int retval = -EAGAIN; /* by default, try again */
+
/* Need to not reach outside the vcoremap, which might be smaller in the
* future, but should always be as big as max_vcores */
if (new_vcoreid >= p->procinfo->max_vcores)
@@ -2035,70 +2112,76 @@
/* Need to make sure our vcore is allowed to switch. We might have a
* __preempt, __death, etc, coming in. Similar to yield. */
switch (p->state) {
- case (PROC_RUNNING_M):
- break; /* the only case we can proceed */
- case (PROC_RUNNING_S): /* user bug, just return */
- case (PROC_DYING): /* incoming __death */
- case (PROC_DYING_ABORT):
- case (PROC_RUNNABLE_M): /* incoming (bulk) preempt/myield TODO:(BULK) */
- goto out_locked;
- default:
- panic("Weird state(%s) in %s()", procstate2str(p->state),
- __FUNCTION__);
+ case (PROC_RUNNING_M):
+ break; /* the only case we can proceed */
+ case (PROC_RUNNING_S): /* user bug, just return */
+ case (PROC_DYING): /* incoming __death */
+ case (PROC_DYING_ABORT):
+ case (PROC_RUNNABLE_M): /* incoming (bulk) preempt/myield TODO:(BULK) */
+ goto out_locked;
+ default:
+ panic("Weird state(%s) in %s()", procstate2str(p->state),
+ __FUNCTION__);
}
- /* This is which vcore this pcore thinks it is, regardless of any unmappings
- * that may have happened remotely (with __PRs waiting to run) */
+ /* This is which vcore this pcore thinks it is, regardless of any
+ * unmappings that may have happened remotely (with __PRs waiting to
+ * run) */
caller_vcoreid = pcpui->owning_vcoreid;
caller_vc = vcoreid2vcore(p, caller_vcoreid);
caller_vcpd = &p->procdata->vcore_preempt_data[caller_vcoreid];
- /* This is how we detect whether or not a __PR happened. If it did, just
- * abort and handle the kmsg. No new __PRs are coming since we hold the
- * lock. This also detects a __PR followed by a __SC for the same VC. */
+ /* This is how we detect whether or not a __PR happened. If it did,
+ * just abort and handle the kmsg. No new __PRs are coming since we
+ * hold the lock. This also detects a __PR followed by a __SC for the
+ * same VC. */
if (caller_vc->nr_preempts_sent != caller_vc->nr_preempts_done)
goto out_locked;
- /* Sanity checks. If we were preempted or are dying, we should have noticed
- * by now. */
+ /* Sanity checks. If we were preempted or are dying, we should have
+ * noticed by now. */
assert(is_mapped_vcore(p, pcoreid));
assert(caller_vcoreid == get_vcoreid(p, pcoreid));
/* Should only call from vcore context */
if (!caller_vcpd->notif_disabled) {
retval = -EINVAL;
- printk("[kernel] You tried to change vcores from uthread ctx\n");
+ printk("[kernel] You tried to change vcores from uth ctx\n");
goto out_locked;
}
- /* Ok, we're clear to do the switch. Lets figure out who the new one is */
+ /* Ok, we're clear to do the switch. Lets figure out who the new one is
+ */
new_vc = vcoreid2vcore(p, new_vcoreid);
printd("[kernel] changing vcore %d to vcore %d\n", caller_vcoreid,
new_vcoreid);
/* enable_my_notif signals how we'll be restarted */
if (enable_my_notif) {
- /* if they set this flag, then the vcore can just restart from scratch,
- * and we don't care about either the uthread_ctx or the vcore_ctx. */
+ /* if they set this flag, then the vcore can just restart from
+ * scratch, and we don't care about either the uthread_ctx or
+ * the vcore_ctx. */
caller_vcpd->notif_disabled = FALSE;
- /* Don't need to save the FPU. There should be no uthread or other
- * reason to return to the FPU state. But we do need to finalize the
- * context, even though we are throwing it away. We need to return the
- * pcore to a state where it can run any context and not be bound to
- * the old context. */
+ /* Don't need to save the FPU. There should be no uthread or
+ * other reason to return to the FPU state. But we do need to
+ * finalize the context, even though we are throwing it away.
+ * We need to return the pcore to a state where it can run any
+ * context and not be bound to the old context. */
arch_finalize_ctx(pcpui->cur_ctx);
} else {
- /* need to set up the calling vcore's ctx so that it'll get restarted by
- * __startcore, to make the caller look like it was preempted. */
+ /* need to set up the calling vcore's ctx so that it'll get
+ * restarted by __startcore, to make the caller look like it was
+ * preempted. */
copy_current_ctx_to(&caller_vcpd->vcore_ctx);
save_vc_fp_state(caller_vcpd);
}
- /* Mark our core as preempted (for userspace recovery). Userspace checks
- * this in handle_indirs, and it needs to check the mbox regardless of
- * enable_my_notif. This does mean cores that change-to with no intent to
- * return will be tracked as PREEMPTED until they start back up (maybe
- * forever). */
+ /* Mark our core as preempted (for userspace recovery). Userspace
+ * checks this in handle_indirs, and it needs to check the mbox
+ * regardless of enable_my_notif. This does mean cores that change-to
+ * with no intent to return will be tracked as PREEMPTED until they
+ * start back up (maybe forever). */
atomic_or(&caller_vcpd->flags, VC_PREEMPTED);
/* Either way, unmap and offline our current vcore */
/* Move the caller from online to inactive */
TAILQ_REMOVE(&p->online_vcs, caller_vc, list);
/* We don't bother with the notif_pending race. note that notif_pending
- * could still be set. this was a preempted vcore, and userspace will need
- * to deal with missed messages (preempt_recover() will handle that) */
+ * could still be set. this was a preempted vcore, and userspace will
+ * need to deal with missed messages (preempt_recover() will handle
+ * that) */
TAILQ_INSERT_HEAD(&p->inactive_vcs, caller_vc, list);
/* Move the new one from inactive to online */
TAILQ_REMOVE(&p->inactive_vcs, new_vc, list);
@@ -2112,23 +2195,24 @@
/* Send either a PREEMPT msg or a CHECK_MSGS msg. If they said to
* enable_my_notif, then all userspace needs is to check messages, not a
* full preemption recovery. */
- preempt_msg.ev_type = (enable_my_notif ? EV_CHECK_MSGS : EV_VCORE_PREEMPT);
+ preempt_msg.ev_type = (enable_my_notif ? EV_CHECK_MSGS :
+ EV_VCORE_PREEMPT);
preempt_msg.ev_arg2 = caller_vcoreid; /* arg2 is 32 bits */
- /* Whenever we send msgs with the proc locked, we need at least 1 online.
- * In this case, it's the one we just changed to. */
+ /* Whenever we send msgs with the proc locked, we need at least 1
+ * online. In this case, it's the one we just changed to. */
assert(!TAILQ_EMPTY(&p->online_vcs));
send_kernel_event(p, &preempt_msg, new_vcoreid);
/* So this core knows which vcore is here. (cur_proc and owning_proc are
* already correct): */
pcpui->owning_vcoreid = new_vcoreid;
- /* Until we set_curctx, we don't really have a valid current tf. The stuff
- * in that old one is from our previous vcore, not the current
+ /* Until we set_curctx, we don't really have a valid current tf. The
+ * stuff in that old one is from our previous vcore, not the current
* owning_vcoreid. This matters for other KMSGS that will run before
* __set_curctx (like __notify). */
pcpui->cur_ctx = 0;
- /* Need to send a kmsg to finish. We can't set_curctx til the __PR is done,
- * but we can't spin right here while holding the lock (can't spin while
- * waiting on a message, roughly) */
+ /* Need to send a kmsg to finish. We can't set_curctx til the __PR is
+ * done, but we can't spin right here while holding the lock (can't spin
+ * while waiting on a message, roughly) */
send_kernel_message(pcoreid, __set_curctx, (long)p, (long)new_vcoreid,
(long)new_vc->nr_preempts_sent, KMSG_ROUTINE);
retval = 0;
@@ -2152,23 +2236,24 @@
assert(p_to_run);
/* Can not be any TF from a process here already */
assert(!pcpui->owning_proc);
- /* the sender of the kmsg increfed already for this saved ref to p_to_run */
+ /* the sender of the kmsg increfed already for this saved ref to
+ * p_to_run */
pcpui->owning_proc = p_to_run;
pcpui->owning_vcoreid = vcoreid;
- /* sender increfed again, assuming we'd install to cur_proc. only do this
- * if no one else is there. this is an optimization, since we expect to
- * send these __startcores to idles cores, and this saves a scramble to
- * incref when all of the cores restartcore/startcore later. Keep in sync
- * with __proc_give_cores() and __proc_run_m(). */
+ /* sender increfed again, assuming we'd install to cur_proc. only do
+ * this if no one else is there. this is an optimization, since we
+ * expect to send these __startcores to idles cores, and this saves a
+ * scramble to incref when all of the cores restartcore/startcore later.
+ * Keep in sync with __proc_give_cores() and __proc_run_m(). */
if (!pcpui->cur_proc) {
- pcpui->cur_proc = p_to_run; /* install the ref to cur_proc */
- lcr3(p_to_run->env_cr3); /* load the page tables to match cur_proc */
+ pcpui->cur_proc = p_to_run; /* install the ref to cur_proc */
+ lcr3(p_to_run->env_cr3);
} else {
- proc_decref(p_to_run); /* can't install, decref the extra one */
+ proc_decref(p_to_run);
}
/* Note we are not necessarily in the cr3 of p_to_run */
- /* Now that we sorted refcnts and know p / which vcore it should be, set up
- * pcpui->cur_ctx so that it will run that particular vcore */
+ /* Now that we sorted refcnts and know p / which vcore it should be, set
+ * up pcpui->cur_ctx so that it will run that particular vcore */
__set_curctx_to_vcoreid(p_to_run, vcoreid, old_nr_preempts_sent);
}
@@ -2196,15 +2281,16 @@
/* Not the right proc */
if (p != pcpui->owning_proc)
return;
- /* the core might be owned, but not have a valid cur_ctx (if we're in the
- * process of changing */
+ /* the core might be owned, but not have a valid cur_ctx (if we're in
+ * the process of changing */
if (!pcpui->cur_ctx)
return;
- /* Common cur_ctx sanity checks. Note cur_ctx could be an _S's scp_ctx */
+ /* Common cur_ctx sanity checks. Note cur_ctx could be an _S's scp_ctx
+ */
vcoreid = pcpui->owning_vcoreid;
vcpd = &p->procdata->vcore_preempt_data[vcoreid];
- /* for SCPs that haven't (and might never) call vc_event_init, like rtld.
- * this is harmless for MCPS to check this */
+ /* for SCPs that haven't (and might never) call vc_event_init, like
+ * rtld. this is harmless for MCPS to check this */
if (!scp_is_vcctx_ready(vcpd))
return;
printd("received active notification for proc %d's vcore %d on pcore %d\n",
@@ -2213,8 +2299,8 @@
if (vcpd->notif_disabled)
return;
vcpd->notif_disabled = TRUE;
- /* save the old ctx in the uthread slot, build and pop a new one. Note that
- * silly state isn't our business for a notification. */
+ /* save the old ctx in the uthread slot, build and pop a new one. Note
+ * that silly state isn't our business for a notification. */
copy_current_ctx_to(&vcpd->uthread_ctx);
memset(pcpui->cur_ctx, 0, sizeof(struct user_context));
proc_init_ctx(pcpui->cur_ctx, vcoreid, vcpd->vcore_entry,
@@ -2231,7 +2317,7 @@
assert(p);
if (p != pcpui->owning_proc) {
- panic("__preempt arrived for a process (%p) that was not owning (%p)!",
+ panic("__preempt arrived for proc (%p) that was not owning (%p)!",
p, pcpui->owning_proc);
}
/* Common cur_ctx sanity checks */
@@ -2241,22 +2327,22 @@
vcpd = &p->procdata->vcore_preempt_data[vcoreid];
printd("[kernel] received __preempt for proc %d's vcore %d on pcore %d\n",
p->procinfo->pid, vcoreid, coreid);
- /* if notifs are disabled, the vcore is in vcore context (as far as we're
- * concerned), and we save it in the vcore slot. o/w, we save the process's
- * cur_ctx in the uthread slot, and it'll appear to the vcore when it comes
- * back up the uthread just took a notification. */
+ /* if notifs are disabled, the vcore is in vcore context (as far as
+ * we're concerned), and we save it in the vcore slot. o/w, we save the
+ * process's cur_ctx in the uthread slot, and it'll appear to the vcore
+ * when it comes back up the uthread just took a notification. */
if (vcpd->notif_disabled)
copy_current_ctx_to(&vcpd->vcore_ctx);
else
copy_current_ctx_to(&vcpd->uthread_ctx);
/* Userspace in a preemption handler on another core might be copying FP
* state from memory (VCPD) at the moment, and if so we don't want to
- * clobber it. In this rare case, our current core's FPU state should be
- * the same as whatever is in VCPD, so this shouldn't be necessary, but the
- * arch-specific save function might do something other than write out
- * bit-for-bit the exact same data. Checking STEALING suffices, since we
- * hold the K_LOCK (preventing userspace from starting a fresh STEALING
- * phase concurrently). */
+ * clobber it. In this rare case, our current core's FPU state should
+ * be the same as whatever is in VCPD, so this shouldn't be necessary,
+ * but the arch-specific save function might do something other than
+ * write out bit-for-bit the exact same data. Checking STEALING
+ * suffices, since we hold the K_LOCK (preventing userspace from
+ * starting a fresh STEALING phase concurrently). */
if (!(atomic_read(&vcpd->flags) & VC_UTHREAD_STEALING))
save_vc_fp_state(vcpd);
/* Mark the vcore as preempted and unlock (was locked by the sender). */
@@ -2265,12 +2351,13 @@
/* either __preempt or proc_yield() ends the preempt phase. */
p->procinfo->vcoremap[vcoreid].preempt_pending = 0;
vcore_account_offline(p, vcoreid);
- wmb(); /* make sure everything else hits before we finish the preempt */
+ /* make sure everything else hits before we finish the preempt */
+ wmb();
/* up the nr_done, which signals the next __startcore for this vc */
p->procinfo->vcoremap[vcoreid].nr_preempts_done++;
- /* We won't restart the process later. current gets cleared later when we
- * notice there is no owning_proc and we have nothing to do (smp_idle,
- * restartcore, etc) */
+ /* We won't restart the process later. current gets cleared later when
+ * we notice there is no owning_proc and we have nothing to do
+ * (smp_idle, restartcore, etc) */
clear_owning_proc(coreid);
}
@@ -2286,9 +2373,10 @@
assert(p);
if (p != pcpui->owning_proc) {
- /* Older versions of Akaros thought it was OK to have a __death hit a
- * core that no longer had a process. I think it's a bug now. */
- panic("__death arrived for a process (%p) that was not owning (%p)!",
+ /* Older versions of Akaros thought it was OK to have a __death
+ * hit a core that no longer had a process. I think it's a bug
+ * now. */
+ panic("__death arrived for proc (%p) that was not owning (%p)!",
p, pcpui->owning_proc);
}
vcoreid = pcpui->owning_vcoreid;
@@ -2318,8 +2406,8 @@
assert(p);
/* this actually adds an extra space, since no progname is ever
* PROGNAME_SZ bytes, due to the \0 counted in PROGNAME. */
- printk("%8d %-*s %-10s %6d\n", p->pid, PROC_PROGNAME_SZ, p->progname,
- procstate2str(p->state), p->ppid);
+ printk("%8d %-*s %-10s %6d\n", p->pid, PROC_PROGNAME_SZ,
+ p->progname, procstate2str(p->state), p->ppid);
}
char dashes[PROC_PROGNAME_SZ];
memset(dashes, '-', PROC_PROGNAME_SZ);
@@ -2407,10 +2495,11 @@
printk("Flags: 0x%08x\n", p->env_flags);
printk("CR3(phys): %p\n", p->env_cr3);
printk("Num Vcores: %d\n", p->procinfo->num_vcores);
- printk("Vcore Lists (may be in flux w/o locking):\n----------------------\n");
+ printk("Vcore Lists (may be in flux w/o locking):\n----------------\n");
printk("Online:\n");
TAILQ_FOREACH(vc_i, &p->online_vcs, list)
- printk("\tVcore %d -> Pcore %d\n", vcore2vcoreid(p, vc_i), vc_i->pcoreid);
+ printk("\tVcore %d -> Pcore %d\n", vcore2vcoreid(p, vc_i),
+ vc_i->pcoreid);
printk("Bulk Preempted:\n");
TAILQ_FOREACH(vc_i, &p->bulk_preempted_vcs, list)
printk("\tVcore %d\n", vcore2vcoreid(p, vc_i));
@@ -2421,7 +2510,8 @@
printk("Nsec Online, up to the last offlining:\n");
printk("------------------------");
for (int i = 0; i < p->procinfo->max_vcores; i++) {
- uint64_t vc_time = tsc2nsec(vcore_account_gettotal(p, i));
+ uint64_t vc_time = tsc2nsec(vcore_account_gettotal(p,
+ i));
if (i % 4 == 0)
printk("\n");
@@ -2433,10 +2523,12 @@
}
printk("Resources:\n------------------------\n");
for (int i = 0; i < MAX_NUM_RESOURCES; i++)
- printk("\tRes type: %02d, amt wanted: %08d, amt granted: %08d\n", i,
- p->procdata->res_req[i].amt_wanted, p->procinfo->res_grant[i]);
+ printk("\tRes type: %02d, amt wanted: %08d amt granted: %08d\n",
+ i, p->procdata->res_req[i].amt_wanted,
+ p->procinfo->res_grant[i]);
printk("Open Files:\n");
struct fd_table *files = &p->open_files;
+
if (spin_locked(&files->lock)) {
spinlock_debug(&files->lock);
printk("FILE LOCK HELD, ABORTING\n");
@@ -2474,11 +2566,12 @@
assert(p);
spin_lock(&p->proc_lock);
TAILQ_FOREACH(vc_i, &p->online_vcs, list) {
- /* this isn't true, a __startcore could be on the way and we're
- * already "online" */
+ /* this isn't true, a __startcore could be on the way
+ * and we're already "online" */
if (vc_i->pcoreid == core_id()) {
- /* Immediate message was sent, we should get it when we enable
- * interrupts, which should cause us to skip cpu_halt() */
+ /* Immediate message was sent, we should get it
+ * when we enable interrupts, which should cause
+ * us to skip cpu_halt() */
if (!STAILQ_EMPTY(&pcpui->immed_amsgs))
continue;
printk("Owned pcore (%d) has no owner, by %p, vc %d!\n",
diff --git a/kern/src/profiler.c b/kern/src/profiler.c
index dada9c1..ede0abc 100644
--- a/kern/src/profiler.c
+++ b/kern/src/profiler.c
@@ -68,9 +68,9 @@
static inline char *vb_encode_uint64(char *data, uint64_t n)
{
- /* Classical variable bytes encoding. Encodes 7 bits at a time, using bit
- * number 7 in the byte, as indicator of end of sequence (when zero).
- */
+ /* Classical variable bytes encoding. Encodes 7 bits at a time, using
+ * bit number 7 in the byte, as indicator of end of sequence (when
+ * zero). */
for (; n >= 0x80; n >>= 7)
*data++ = (char) (n | 0x80);
*data++ = (char) n;
@@ -81,8 +81,9 @@
static struct block *profiler_buffer_write(struct profiler_cpu_context *cpu_buf,
struct block *b)
{
- /* qpass will drop b if the queue is over its limit. we're willing to lose
- * traces, but we won't lose 'control' events, such as MMAP and PID. */
+ /* qpass will drop b if the queue is over its limit. we're willing to
+ * lose traces, but we won't lose 'control' events, such as MMAP and
+ * PID. */
if (b) {
if (qpass(profiler_queue, b) < 0)
cpu_buf->dropped_data_cnt++;
@@ -259,7 +260,8 @@
{
struct proc *p = (struct proc *) opaque;
- profiler_notify_mmap(p, vmr->vm_base, vmr->vm_end - vmr->vm_base,
+ profiler_notify_mmap(p, vmr->vm_base,
+ vmr->vm_end - vmr->vm_base,
vmr->vm_prot, vmr->vm_flags, vmr->__vm_foc,
vmr->vm_foff);
}
@@ -297,14 +299,14 @@
{
ERRSTACK(1);
- /* It is very important that we enqueue and dequeue entire records at once.
- * If we leave partial records, the entire stream will be corrupt. Our
- * reader does its best to make sure it has room for complete records
- * (checks qlen()).
+ /* It is very important that we enqueue and dequeue entire records at
+ * once. If we leave partial records, the entire stream will be
+ * corrupt. Our reader does its best to make sure it has room for
+ * complete records (checks qlen()).
*
* If we ever get corrupt streams, try making this a Qmsg. Though it
- * doesn't help every situation - we have issues with writes greater than
- * Maxatomic regardless. */
+ * doesn't help every situation - we have issues with writes greater
+ * than Maxatomic regardless. */
profiler_queue = qopen(profiler_queue_limit, 0, NULL, NULL);
if (!profiler_queue)
error(ENOMEM, ERROR_FIXME);
@@ -499,10 +501,12 @@
uint64_t info)
{
if (kref_get_not_zero(&profiler_kref, 1)) {
- struct profiler_cpu_context *cpu_buf = profiler_get_cpu_ctx(core_id());
+ struct profiler_cpu_context *cpu_buf =
+ profiler_get_cpu_ctx(core_id());
if (profiler_percpu_ctx && cpu_buf->tracing)
- profiler_push_kernel_trace64(cpu_buf, pc_list, nr_pcs, info);
+ profiler_push_kernel_trace64(cpu_buf, pc_list, nr_pcs,
+ info);
kref_put(&profiler_kref);
}
}
@@ -512,10 +516,12 @@
{
if (kref_get_not_zero(&profiler_kref, 1)) {
struct proc *p = current;
- struct profiler_cpu_context *cpu_buf = profiler_get_cpu_ctx(core_id());
+ struct profiler_cpu_context *cpu_buf =
+ profiler_get_cpu_ctx(core_id());
if (profiler_percpu_ctx && cpu_buf->tracing)
- profiler_push_user_trace64(cpu_buf, p, pc_list, nr_pcs, info);
+ profiler_push_user_trace64(cpu_buf, p, pc_list, nr_pcs,
+ info);
kref_put(&profiler_kref);
}
}
@@ -536,10 +542,12 @@
if (kref_get_not_zero(&profiler_kref, 1)) {
if (foc && (prot & PROT_EXEC) && profiler_percpu_ctx) {
char path_buf[PROFILER_MAX_PRG_PATH];
- char *path = foc_abs_path(foc, path_buf, sizeof(path_buf));
+ char *path = foc_abs_path(foc, path_buf,
+ sizeof(path_buf));
if (likely(path))
- profiler_push_pid_mmap(p, addr, size, offset, path);
+ profiler_push_pid_mmap(p, addr, size, offset,
+ path);
}
kref_put(&profiler_kref);
}
diff --git a/kern/src/radix.c b/kern/src/radix.c
index c8cdec2..4c881d2 100644
--- a/kern/src/radix.c
+++ b/kern/src/radix.c
@@ -48,8 +48,8 @@
* slot. */
void radix_tree_destroy(struct radix_tree *tree)
{
- /* Currently, we may have a root node, even if all the elements were removed
- */
+ /* Currently, we may have a root node, even if all the elements were
+ * removed */
radix_for_each_slot(tree, __should_not_run_cb, NULL);
if (tree->root) {
kmem_cache_free(radix_kcache, tree->root);
@@ -68,24 +68,27 @@
struct radix_node *r_node;
void **slot;
- /* Is the tree tall enough? if not, it needs to grow a level. This will
- * also create the initial node (upper bound starts at 0). */
+ /* Is the tree tall enough? if not, it needs to grow a level. This
+ * will also create the initial node (upper bound starts at 0). */
while (key >= tree->upper_bound) {
r_node = kmem_cache_alloc(radix_kcache, MEM_WAIT);
memset(r_node, 0, sizeof(struct radix_node));
if (tree->root) {
- /* tree->root is the old root, now a child of the future root */
+ /* tree->root is the old root, now a child of the future
+ * root */
r_node->items[0] = tree->root;
tree->root->parent = r_node;
- tree->root->my_slot = (struct radix_node**)&r_node->items[0];
+ tree->root->my_slot =
+ (struct radix_node**)&r_node->items[0];
r_node->num_items = 1;
} else {
- /* if there was no root before, we're both the root and a leaf */
+ /* if there was no root before, we're both the root and
+ * a leaf */
r_node->leaf = TRUE;
r_node->parent = 0;
}
- /* Need to atomically change root, depth, and upper_bound for our
- * readers, who will check the seq ctr. */
+ /* Need to atomically change root, depth, and upper_bound for
+ * our readers, who will check the seq ctr. */
__seq_start_write(&tree->seq);
tree->root = r_node;
r_node->my_slot = &tree->root;
@@ -94,11 +97,11 @@
__seq_end_write(&tree->seq);
}
assert(tree->root);
- /* the tree now thinks it is tall enough, so find the last node, insert in
- * it, etc */
+ /* the tree now thinks it is tall enough, so find the last node, insert
+ * in it, etc */
/* This gives us an rcu-protected pointer, though we hold the lock. */
r_node = __radix_lookup_node(tree, key, TRUE);
- assert(r_node); /* we want an ENOMEM actually, but i want to see this */
+ assert(r_node); /* we want an ENOMEM actually, but i want to see this */
slot = &r_node->items[key & (NR_RNODE_SLOTS - 1)];
if (*slot)
return -EEXIST;
@@ -124,13 +127,13 @@
assert(*slot); /* make sure there is something there */
rcu_assign_pointer(*slot, NULL);
r_node->num_items--;
- /* this check excludes the root, but the if else handles it. For now, once
- * we have a root, we'll always keep it (will need some changing in
+ /* this check excludes the root, but the if else handles it. For now,
+ * once we have a root, we'll always keep it (will need some changing in
* radix_insert() */
if (!r_node->num_items && r_node->parent) {
if (r_node->parent)
__radix_remove_slot(r_node->parent, r_node->my_slot);
- else /* we're the last node, attached to the actual tree */
+ else /* we're the last node, attached to the actual tree */
*(r_node->my_slot) = 0;
call_rcu(&r_node->rcu, __rnode_free_rcu);
}
@@ -157,7 +160,8 @@
if (retval) {
__radix_remove_slot(r_node, (struct radix_node**)slot);
} else {
- /* it's okay to delete an empty, but i want to know about it for now */
+ /* it's okay to delete an empty, but i want to know about it for
+ * now */
warn("Tried to remove a non-existant item from a radix tree!");
}
return retval;
@@ -170,8 +174,9 @@
if (!slot)
return 0;
- /* slot was rcu-protected, pointing into the memory of an r_node. we also
- * want *slot, which is "void *item" to be an rcu-protected pointer. */
+ /* slot was rcu-protected, pointing into the memory of an r_node. we
+ * also want *slot, which is "void *item" to be an rcu-protected
+ * pointer. */
return rcu_dereference(*slot);
}
@@ -204,26 +209,30 @@
if (key >= upper_bound) {
if (extend)
- warn("Bound (%d) not set for key %d!\n", upper_bound, key);
+ warn("Bound (%d) not set for key %d!\n", upper_bound,
+ key);
return 0;
}
for (int i = depth; i > 1; i--) { /* i = ..., 4, 3, 2 */
- idx = (key >> (LOG_RNODE_SLOTS * (i - 1))) & (NR_RNODE_SLOTS - 1);
+ idx = (key >> (LOG_RNODE_SLOTS * (i - 1)))
+ & (NR_RNODE_SLOTS - 1);
/* There might not be a node at this part of the tree */
if (!r_node->items[idx]) {
if (!extend)
return 0;
child_node = kmem_cache_alloc(radix_kcache, MEM_WAIT);
memset(child_node, 0, sizeof(struct radix_node));
- /* when we are on the last iteration (i == 2), the child will be
- * a leaf. */
+ /* when we are on the last iteration (i == 2), the child
+ * will be a leaf. */
child_node->leaf = (i == 2) ? TRUE : FALSE;
child_node->parent = r_node;
- child_node->my_slot = (struct radix_node**)&r_node->items[idx];
+ child_node->my_slot =
+ (struct radix_node**)&r_node->items[idx];
r_node->num_items++;
rcu_assign_pointer(r_node->items[idx], child_node);
}
- r_node = (struct radix_node*)rcu_dereference(r_node->items[idx]);
+ r_node =
+ (struct radix_node*)rcu_dereference(r_node->items[idx]);
}
return r_node;
}
@@ -237,8 +246,8 @@
if (!r_node)
return 0;
key = key & (NR_RNODE_SLOTS - 1);
- /* r_node is rcu-protected. Our retval is too, since it's a pointer into
- * the same object as r_node. */
+ /* r_node is rcu-protected. Our retval is too, since it's a pointer
+ * into the same object as r_node. */
return &r_node->items[key];
}
@@ -290,26 +299,28 @@
{
unsigned int num_children = ACCESS_ONCE(r_node->num_items);
- /* The tree_idx we were passed was from our parent's perspective. We need
- * shift it over each time we walk down to put it in terms of our
- * level/depth. Or think of it as making room for our bits (the values of
- * i). */
+ /* The tree_idx we were passed was from our parent's perspective. We
+ * need shift it over each time we walk down to put it in terms of our
+ * level/depth. Or think of it as making room for our bits (the values
+ * of i). */
tree_idx <<= LOG_RNODE_SLOTS;
for (int i = 0; num_children && (i < NR_RNODE_SLOTS); i++) {
if (r_node->items[i]) {
- /* If we really care, we can try to abort the rest of the loop. Not
- * a big deal */
- if (!child_overlaps_range(tree_idx + i, depth, glb_start_idx,
- glb_end_idx))
+ /* If we really care, we can try to abort the rest of
+ * the loop. Not a big deal */
+ if (!child_overlaps_range(tree_idx + i, depth,
+ glb_start_idx, glb_end_idx))
continue;
if (depth > 1) {
- if (rnode_for_each(r_node->items[i], depth - 1, tree_idx + i,
- glb_start_idx, glb_end_idx, cb, arg))
+ if (rnode_for_each(r_node->items[i], depth - 1,
+ tree_idx + i, glb_start_idx,
+ glb_end_idx, cb, arg))
num_children--;
} else {
if (cb(&r_node->items[i], tree_idx + i, arg)) {
__radix_remove_slot(r_node,
- (struct radix_node**)&r_node->items[i]);
+ (struct radix_node**)
+ &r_node->items[i]);
num_children--;
}
}
@@ -402,13 +413,14 @@
for (int i = 0; i < depth; i++)
buf[i] = '\t';
printk("%sRnode %p, parent %p, myslot %p, %d items, leaf? %d\n",
- buf, r_node, r_node->parent, r_node->my_slot, r_node->num_items,
- r_node->leaf);
+ buf, r_node, r_node->parent, r_node->my_slot,
+ r_node->num_items, r_node->leaf);
for (int i = 0; i < NR_RNODE_SLOTS; i++) {
if (!r_node->items[i])
continue;
if (r_node->leaf)
- printk("\t%sRnode Item %d: %p\n", buf, i, r_node->items[i]);
+ printk("\t%sRnode Item %d: %p\n", buf, i,
+ r_node->items[i]);
else
print_rnode(r_node->items[i], depth + 1);
}
diff --git a/kern/src/rcu.c b/kern/src/rcu.c
index 4d90887..b543f7e 100644
--- a/kern/src/rcu.c
+++ b/kern/src/rcu.c
@@ -182,19 +182,21 @@
__early_call_rcu(head);
return 0;
}
- /* rsp->gpnum is the one we're either working on (if > completed) or the one
- * we already did. Either way, it's a GP that may have already been ACKed
- * during a core's QS, and that core could have started a read-side critical
- * section that must complete before CB runs. That requires another GP. */
+ /* rsp->gpnum is the one we're either working on (if > completed) or the
+ * one we already did. Either way, it's a GP that may have already been
+ * ACKed during a core's QS, and that core could have started a
+ * read-side critical section that must complete before CB runs. That
+ * requires another GP. */
head->gpnum = READ_ONCE(rsp->gpnum) + 1;
spin_lock_irqsave(&rpi->lock);
list_add_tail(&head->link, &rpi->cbs);
nr_cbs = ++rpi->nr_cbs;
spin_unlock_irqsave(&rpi->lock);
/* rcu_barrier requires that the write to ->nr_cbs be visible before any
- * future writes. unlock orders the write inside, but doesn't prevent other
- * writes from moving in. Technically, our lock implementations do that,
- * but it's not part of our definition. Maybe it should be. Til then: */
+ * future writes. unlock orders the write inside, but doesn't prevent
+ * other writes from moving in. Technically, our lock implementations
+ * do that, but it's not part of our definition. Maybe it should be.
+ * Til then: */
wmb();
return nr_cbs;
}
@@ -229,26 +231,27 @@
panic("Attempted %s() from an unblockable context!", __func__);
if (is_rcu_ktask(current_kthread))
panic("Attempted %s() from an RCU thread!", __func__);
- /* TODO: if we have concurrent rcu_barriers, we might be able to share the
- * CBs. Say we have 1 CB on a core, then N rcu_barriers. We'll have N
- * call_rcus in flight, though we could share. Linux does this with a mtx
- * and some accounting, I think. */
+ /* TODO: if we have concurrent rcu_barriers, we might be able to share
+ * the CBs. Say we have 1 CB on a core, then N rcu_barriers. We'll
+ * have N call_rcus in flight, though we could share. Linux does this
+ * with a mtx and some accounting, I think. */
b = kzmalloc(sizeof(struct sync_cb_blob) * num_cores, MEM_WAIT);
- /* Remember, you block when sem is <= 0. We'll get nr_sent ups, and we'll
- * down 1 for each. This is just like the synchronize_rcu() case; there,
- * nr_sent == 1. */
+ /* Remember, you block when sem is <= 0. We'll get nr_sent ups, and
+ * we'll down 1 for each. This is just like the synchronize_rcu() case;
+ * there, nr_sent == 1. */
sem_init(sem, 0);
- /* Order any signal we received from someone who called call_rcu() before
- * our rpi->nr_cbs reads. */
+ /* Order any signal we received from someone who called call_rcu()
+ * before our rpi->nr_cbs reads. */
rmb();
for_each_core(i) {
rpi = _PERCPU_VARPTR(rcu_pcpui, i);
/* Lockless peek at nr_cbs. Two things to note here:
- * - We look at nr_cbs and not the list, since there could be CBs on the
- * stack-local work list or that have blocked.
- * - The guarantee is that we wait for any CBs from call_rcus that can
- * be proved to happen before rcu_barrier. That means call_rcu had to
- * return, which means it had to set the nr_cbs. */
+ * - We look at nr_cbs and not the list, since there could be
+ * CBs on the stack-local work list or that have blocked.
+ * - The guarantee is that we wait for any CBs from call_rcus
+ * that can be proved to happen before rcu_barrier. That
+ * means call_rcu had to return, which means it had to set the
+ * nr_cbs. */
if (!rpi->nr_cbs)
continue;
init_rcu_head_on_stack(&b[i].h);
@@ -261,10 +264,10 @@
return;
}
wake_gp_ktask(rpi->rsp, true);
- /* sem_down_bulk is currently slow. Even with some fixes, we actually want
- * a barrier, which you could imagine doing with a tree. sem_down_bulk()
- * doesn't have the info that we have: that the wakeups are coming from N
- * cores on the leaves of the tree. */
+ /* sem_down_bulk is currently slow. Even with some fixes, we actually
+ * want a barrier, which you could imagine doing with a tree.
+ * sem_down_bulk() doesn't have the info that we have: that the wakeups
+ * are coming from N cores on the leaves of the tree. */
sem_down_bulk(sem, nr_sent);
kfree(b);
}
@@ -290,8 +293,8 @@
new_qsm = __sync_and_and_fetch(&rnp->qsmask, ~grpmask);
/* I don't fully understand this, but we need some form of transitive
- * barrier across the entire tree. Linux does this when they lock/unlock.
- * Our equivalent is the atomic op. */
+ * barrier across the entire tree. Linux does this when they
+ * lock/unlock. Our equivalent is the atomic op. */
smp_mb__after_unlock_lock();
/* Only one thread will get 0 back - the last one to check in */
if (new_qsm)
@@ -304,11 +307,12 @@
static void rcu_report_qs_rpi(struct rcu_state *rsp, struct rcu_pcpui *rpi)
{
- /* Note we don't check ->completed == ->gpnum (gp_in_progress()). We only
- * care if our core hasn't reported in for a GP. This time is a subset of
- * gp_in_progress. */
+ /* Note we don't check ->completed == ->gpnum (gp_in_progress()). We
+ * only care if our core hasn't reported in for a GP. This time is a
+ * subset of gp_in_progress. */
if (rpi->gp_acked == READ_ONCE(rsp->gpnum)) {
- /* If a GP starts right afterwards, oh well. Catch it next time. */
+ /* If a GP starts right afterwards, oh well. Catch it next
+ * time. */
return;
}
/* Lock ensures we only report a QS once per GP. */
@@ -317,14 +321,14 @@
spin_unlock_irqsave(&rpi->lock);
return;
}
- /* A gp can start concurrently, but once started, we should never be behind
- * by more than 1. */
+ /* A gp can start concurrently, but once started, we should never be
+ * behind by more than 1. */
assert(rpi->gp_acked + 1 == READ_ONCE(rsp->gpnum));
/* Up our gp_acked before actually marking it. I don't want to hold the
- * lock too long (e.g. some debug code in rendez_wakeup() calls call_rcu).
- * So we've unlocked, but haven't actually checked in yet - that's fine. No
- * one else will attempt to check in until the next GP, which can't happen
- * until after we check in for this GP. */
+ * lock too long (e.g. some debug code in rendez_wakeup() calls
+ * call_rcu). So we've unlocked, but haven't actually checked in yet -
+ * that's fine. No one else will attempt to check in until the next GP,
+ * which can't happen until after we check in for this GP. */
rpi->gp_acked++;
spin_unlock_irqsave(&rpi->lock);
__mark_qs(rsp, rpi->my_node, rpi->grpmask);
@@ -408,11 +412,11 @@
struct rcu_node *rnp;
assert(rsp->gpnum == rsp->completed);
- /* Initialize the tree for accumulating QSs. We know there are no users on
- * the tree. The only time a core looks at the tree is when reporting a QS
- * for a GP. The previous GP is done, thus all cores reported their GP
- * already (for the previous GP), and they won't try again until we
- * advertise the next GP. */
+ /* Initialize the tree for accumulating QSs. We know there are no users
+ * on the tree. The only time a core looks at the tree is when
+ * reporting a QS for a GP. The previous GP is done, thus all cores
+ * reported their GP already (for the previous GP), and they won't try
+ * again until we advertise the next GP. */
rcu_for_each_node_breadth_first(rsp, rnp)
rnp->qsmask = rnp->qsmaskinit;
/* Need the tree set for reporting QSs before advertising the GP */
@@ -421,20 +425,21 @@
/* At this point, the cores can start reporting in. */
/* Fake cores help test a tree larger than num_cores. */
rcu_report_qs_fake_cores(rsp);
- /* Expediting aggressively. We could also wait briefly and then check the
- * tardy cores. */
+ /* Expediting aggressively. We could also wait briefly and then check
+ * the tardy cores. */
rcu_report_qs_remote_cores(rsp);
- /* Note that even when we expedite the GP by checking remote cores, there's
- * a race where a core halted but we didn't see it. (they report QS, decide
- * to halt, pause, we start GP, see they haven't halted, etc. They could
- * report the QS after setting the state, but I didn't want to . */
+ /* Note that even when we expedite the GP by checking remote cores,
+ * there's a race where a core halted but we didn't see it. (they
+ * report QS, decide to halt, pause, we start GP, see they haven't
+ * halted, etc. They could report the QS after setting the state, but I
+ * didn't want to . */
do {
rendez_sleep_timeout(&rsp->gp_ktask_rv, root_qsmask_empty, rsp,
RCU_GP_TARDY_PERIOD);
rcu_report_qs_tardy_cores(rsp);
} while (!root_qsmask_empty(rsp));
- /* Not sure if we need any barriers here. Once we post 'completed', the CBs
- * can start running. But no one should touch the tree til gpnum is
+ /* Not sure if we need any barriers here. Once we post 'completed', the
+ * CBs can start running. But no one should touch the tree til gpnum is
* incremented. */
WRITE_ONCE(rsp->completed, rsp->gpnum);
}
@@ -465,11 +470,12 @@
rendez_sleep_timeout(&rsp->gp_ktask_rv, should_wake_ctl,
&rsp->gp_ktask_ctl, RCU_GP_MIN_PERIOD);
rsp->gp_ktask_ctl = 0;
- /* Our write of 0 must happen before starting the GP. If rcu_barrier's
- * CBs miss the start of the GP (and thus are in an unscheduled GP),
- * their write of 1 must happen after our write of 0 so that we rerun.
- * This is the post-and-poke pattern. It's not a huge deal, since we'll
- * catch it after the GP period timeout. */
+ /* Our write of 0 must happen before starting the GP. If
+ * rcu_barrier's CBs miss the start of the GP (and thus are in
+ * an unscheduled GP), their write of 1 must happen after our
+ * write of 0 so that we rerun. This is the post-and-poke
+ * pattern. It's not a huge deal, since we'll catch it after
+ * the GP period timeout. */
wmb();
rcu_run_gp(rsp);
wake_mgmt_ktasks(rsp);
@@ -484,15 +490,15 @@
int nr_cbs = 0;
unsigned long completed;
- /* We'll run the CBs for any GP completed so far, but not any GP that could
- * be completed concurrently. "CBs for a GP" means callbacks that must wait
- * for that GP to complete. */
+ /* We'll run the CBs for any GP completed so far, but not any GP that
+ * could be completed concurrently. "CBs for a GP" means callbacks that
+ * must wait for that GP to complete. */
completed = READ_ONCE(rsp->completed);
- /* This lockless peek is an optimization. We're guaranteed to not miss the
- * CB for the given GP: If the core had a CB for this GP, it must have
- * put it on the list before checking in, before the GP completes, and
- * before we run. */
+ /* This lockless peek is an optimization. We're guaranteed to not miss
+ * the CB for the given GP: If the core had a CB for this GP, it must
+ * have put it on the list before checking in, before the GP completes,
+ * and before we run. */
if (list_empty(&rpi->cbs))
return;
@@ -523,9 +529,9 @@
clear_cannot_block(this_pcpui_ptr());
/* We kept nr_cbs in place until the CBs, which could block, completed.
- * This allows other readers (rcu_barrier()) of our pcpui to tell if we have
- * any CBs pending. This relies on us being the only consumer/runner of CBs
- * for this core. */
+ * This allows other readers (rcu_barrier()) of our pcpui to tell if we
+ * have any CBs pending. This relies on us being the only
+ * consumer/runner of CBs for this core. */
spin_lock_irqsave(&rpi->lock);
rpi->nr_cbs -= nr_cbs;
spin_unlock_irqsave(&rpi->lock);
@@ -541,7 +547,8 @@
rendez_sleep(&rpi->mgmt_ktask_rv, should_wake_ctl,
&rpi->mgmt_ktask_ctl);
rpi->mgmt_ktask_ctl = 0;
- /* TODO: given the number of mgmt kthreads, we need to assign cores */
+ /* TODO: given the number of mgmt kthreads, we need to assign
+ * cores */
for_each_core(i)
run_rcu_cbs(rsp, i);
};
@@ -601,9 +608,9 @@
/* TODO: For each mgmt core */
ktask("rcu_mgmt_0", rcu_mgmt_ktask, _PERCPU_VARPTR(rcu_pcpui, 0));
- /* If we have a call_rcu before percpu_init, we might be using the spot in
- * the actual __percpu .section. We'd be core 0, so that'd be OK, since all
- * we're using it for is reading 'booted'. */
+ /* If we have a call_rcu before percpu_init, we might be using the spot
+ * in the actual __percpu .section. We'd be core 0, so that'd be OK,
+ * since all we're using it for is reading 'booted'. */
for_each_core(i) {
rpi = _PERCPU_VARPTR(rcu_pcpui, i);
rpi->booted = true;
diff --git a/kern/src/readline.c b/kern/src/readline.c
index 32548a6..7fc1051 100644
--- a/kern/src/readline.c
+++ b/kern/src/readline.c
@@ -31,11 +31,13 @@
}
continue;
} else if (c == '\n' || c == '\r') {
- /* sending a \n regardless, since the serial port gives us a \r for
- * carriage returns. (probably won't get a \r anymore) */
+ /* sending a \n regardless, since the serial port gives
+ * us a \r for carriage returns. (probably won't get a
+ * \r anymore) */
if (echoing)
cputchar('\n');
- assert(i <= buf_l - 1); /* never write to buf_l - 1 til the end */
+ assert(i <= buf_l - 1);
+ /* never write to buf_l - 1 til the end */
buf[i++] = c;
retval = i;
break;
diff --git a/kern/src/rendez.c b/kern/src/rendez.c
index 6d5de7c..f046556 100644
--- a/kern/src/rendez.c
+++ b/kern/src/rendez.c
@@ -24,10 +24,10 @@
struct cv_lookup_elm cle;
assert(can_block(this_pcpui_ptr()));
- /* Do a quick check before registering and sleeping. this is the 'check,
- * signal, check again' pattern, where the first check is an optimization.
- * Many rendezes will already be satisfied, so we want to avoid excessive
- * locking associated with reg/dereg. */
+ /* Do a quick check before registering and sleeping. this is the
+ * 'check, signal, check again' pattern, where the first check is an
+ * optimization. Many rendezes will already be satisfied, so we want to
+ * avoid excessive locking associated with reg/dereg. */
cv_lock_irqsave(&rv->cv, &irq_state);
if (cond(arg)) {
cv_unlock_irqsave(&rv->cv, &irq_state);
@@ -37,8 +37,8 @@
/* Mesa-style semantics, which is definitely what you want. See the
* discussion at the end of the URL above. */
while (!cond(arg)) {
- /* it's okay if we miss the ABORT flag; we hold the cv lock, so an
- * aborter's broadcast is waiting until we unlock. */
+ /* it's okay if we miss the ABORT flag; we hold the cv lock, so
+ * an aborter's broadcast is waiting until we unlock. */
if (should_abort(&cle)) {
cv_unlock_irqsave(&rv->cv, &irq_state);
dereg_abortable_cv(&cle);
@@ -91,8 +91,8 @@
assert(can_block(this_pcpui_ptr()));
if (!usec)
return;
- /* Doing this cond check early, but then unlocking again. Mostly just to
- * avoid weird issues with the CV lock and the alarm tchain lock. */
+ /* Doing this cond check early, but then unlocking again. Mostly just
+ * to avoid weird issues with the CV lock and the alarm tchain lock. */
cv_lock_irqsave(&rv->cv, &irq_state);
if (cond(arg)) {
cv_unlock_irqsave(&rv->cv, &irq_state);
@@ -105,16 +105,16 @@
init_awaiter(&awaiter, rendez_alarm_handler);
awaiter.data = rv;
set_awaiter_rel(&awaiter, usec);
- /* Set our alarm on this cpu's tchain. Note that when we sleep in cv_wait,
- * we could be migrated, and later on we could be unsetting the alarm
- * remotely. */
+ /* Set our alarm on this cpu's tchain. Note that when we sleep in
+ * cv_wait, we could be migrated, and later on we could be unsetting the
+ * alarm remotely. */
set_alarm(pcpui_tchain, &awaiter);
cv_lock_irqsave(&rv->cv, &irq_state);
__reg_abortable_cv(&cle, &rv->cv);
/* We could wake early for a few reasons. Legit wakeups after a changed
- * condition (and we should exit), other alarms with different timeouts (and
- * we should go back to sleep), etc. Note it is possible for our alarm to
- * fire immediately upon setting it: before we even cv_lock. */
+ * condition (and we should exit), other alarms with different timeouts
+ * (and we should go back to sleep), etc. Note it is possible for our
+ * alarm to fire immediately upon setting it: before we even cv_lock. */
while (!cond(arg) && !alarm_expired(&awaiter)) {
if (should_abort(&cle)) {
cv_unlock_irqsave(&rv->cv, &irq_state);
@@ -138,8 +138,10 @@
{
int8_t irq_state = 0;
bool ret;
- /* The plan9 style "one sleeper, one waker" could get by with a signal here.
- * But we want to make sure all potential waiters are woken up. */
+
+ /* The plan9 style "one sleeper, one waker" could get by with a signal
+ * here. But we want to make sure all potential waiters are woken up.
+ */
cv_lock_irqsave(&rv->cv, &irq_state);
ret = rv->cv.nr_waiters ? TRUE : FALSE;
__cv_broadcast(&rv->cv);
diff --git a/kern/src/rwlock.c b/kern/src/rwlock.c
index ffd4bd3..97b79ef 100644
--- a/kern/src/rwlock.c
+++ b/kern/src/rwlock.c
@@ -45,14 +45,16 @@
void rlock(struct rwlock *rw_lock)
{
- /* If we already have a reader, we can just increment and return. This is
- * the only access to nr_readers outside the lock. All locked uses need to
- * be aware that the nr could be concurrently increffed (unless it is 0). */
+ /* If we already have a reader, we can just increment and return. This
+ * is the only access to nr_readers outside the lock. All locked uses
+ * need to be aware that the nr could be concurrently increffed (unless
+ * it is 0). */
if (atomic_add_not_zero(&rw_lock->nr_readers, 1))
return;
- /* Here's an alternate style: the broadcaster (a writer) will up the readers
- * count and just wake us. All readers just proceed, instead of fighting to
- * lock and up the count. The writer 'passed' the rlock to us. */
+ /* Here's an alternate style: the broadcaster (a writer) will up the
+ * readers count and just wake us. All readers just proceed, instead of
+ * fighting to lock and up the count. The writer 'passed' the rlock to
+ * us. */
spin_lock(&rw_lock->lock);
if (rw_lock->writing) {
cv_wait_and_unlock(&rw_lock->readers);
@@ -79,10 +81,11 @@
void runlock(struct rwlock *rw_lock)
{
spin_lock(&rw_lock->lock);
- /* sub and test will tell us if we got the refcnt to 0, atomically. syncing
- * with the atomic_add_not_zero of new readers. Since we're passing the
- * lock, we need to make sure someone is sleeping. Contrast to the wunlock,
- * where we can just blindly broadcast and add (potentially == 0). */
+ /* sub and test will tell us if we got the refcnt to 0, atomically.
+ * syncing with the atomic_add_not_zero of new readers. Since we're
+ * passing the lock, we need to make sure someone is sleeping. Contrast
+ * to the wunlock, where we can just blindly broadcast and add
+ * (potentially == 0). */
if (atomic_sub_and_test(&rw_lock->nr_readers, 1) &&
rw_lock->writers.nr_waiters) {
/* passing the lock to the one writer we signal. */
diff --git a/kern/src/schedule.c b/kern/src/schedule.c
index 4804885..9313e62 100644
--- a/kern/src/schedule.c
+++ b/kern/src/schedule.c
@@ -87,11 +87,11 @@
{
/* TODO: imagine doing some accounting here */
run_scheduler();
- /* Set our alarm to go off, relative to now. This means we might lag a bit,
- * and our ticks won't match wall clock time. But if we do incremental,
- * we'll actually punish the next process because the kernel took too long
- * for the previous process. Ultimately, if we really care, we should
- * account for the actual time used. */
+ /* Set our alarm to go off, relative to now. This means we might lag a
+ * bit, and our ticks won't match wall clock time. But if we do
+ * incremental, we'll actually punish the next process because the
+ * kernel took too long for the previous process. Ultimately, if we
+ * really care, we should account for the actual time used. */
set_awaiter_rel(&ksched_waiter, TIMER_TICK_USEC);
set_alarm(&per_cpu_info[core_id()].tchain, &ksched_waiter);
}
@@ -106,8 +106,8 @@
spin_unlock(&sched_lock);
#ifdef CONFIG_ARSC_SERVER
- /* Most likely we'll have a syscall and a process that dedicates itself to
- * running this. Or if it's a kthread, we don't need a core. */
+ /* Most likely we'll have a syscall and a process that dedicates itself
+ * to running this. Or if it's a kthread, we don't need a core. */
#error "Find a way to get a core. Probably a syscall to run a server."
int arsc_coreid = get_any_idle_core();
assert(arsc_coreid >= 0);
@@ -159,9 +159,9 @@
* DYING */
void __sched_proc_register(struct proc *p)
{
- assert(!proc_is_dying(p)); /* shouldn't be able to happen yet */
+ assert(!proc_is_dying(p));
/* one ref for the proc's existence, cradle-to-grave */
- proc_incref(p, 1); /* need at least this OR the 'one for existing' */
+ proc_incref(p, 1); /* need at least this OR the 'one for existing' */
spin_lock(&sched_lock);
corealloc_proc_init(p);
add_to_list(p, &unrunnable_scps);
@@ -172,9 +172,9 @@
void __sched_proc_change_to_m(struct proc *p)
{
spin_lock(&sched_lock);
- /* Need to make sure they aren't dying. if so, we already dealt with their
- * list membership, etc (or soon will). taking advantage of the 'immutable
- * state' of dying (so long as refs are held). */
+ /* Need to make sure they aren't dying. if so, we already dealt with
+ * their list membership, etc (or soon will). taking advantage of the
+ * 'immutable state' of dying (so long as refs are held). */
if (proc_is_dying(p)) {
spin_unlock(&sched_lock);
return;
@@ -201,12 +201,12 @@
void __sched_proc_destroy(struct proc *p, uint32_t *pc_arr, uint32_t nr_cores)
{
spin_lock(&sched_lock);
- /* Unprovision any cores. Note this is different than track_core_dealloc.
- * The latter does bookkeeping when an allocation changes. This is a
- * bulk *provisioning* change. */
+ /* Unprovision any cores. Note this is different than
+ * track_core_dealloc. The latter does bookkeeping when an allocation
+ * changes. This is a bulk *provisioning* change. */
__unprovision_all_cores(p);
- /* Remove from whatever list we are on (if any - might not be on one if it
- * was in the middle of __run_mcp_sched) */
+ /* Remove from whatever list we are on (if any - might not be on one if
+ * it was in the middle of __run_mcp_sched) */
remove_from_any_list(p);
if (nr_cores)
__track_core_dealloc_bulk(p, pc_arr, nr_cores);
@@ -223,7 +223,8 @@
spin_unlock(&sched_lock);
return;
}
- /* could try and prioritize p somehow (move it to the front of the list). */
+ /* could try and prioritize p somehow (move it to the front of the
+ * list). */
spin_unlock(&sched_lock);
/* note they could be dying at this point too. */
poke(&ksched_poker, p);
@@ -241,17 +242,17 @@
remove_from_any_list(p);
add_to_list(p, &runnable_scps);
spin_unlock(&sched_lock);
- /* we could be on a CG core, and all the mgmt cores could be halted. if we
- * don't tell one of them about the new proc, they will sleep until the
- * timer tick goes off. */
+ /* we could be on a CG core, and all the mgmt cores could be halted. if
+ * we don't tell one of them about the new proc, they will sleep until
+ * the timer tick goes off. */
if (!management_core()) {
/* TODO: pick a better core and only send if halted.
*
- * ideally, we'd know if a specific mgmt core is sleeping and wake it
- * up. o/w, we could interrupt an already-running mgmt core that won't
- * get to our new proc anytime soon. also, by poking core 0, a
- * different mgmt core could remain idle (and this process would sleep)
- * until its tick goes off */
+ * ideally, we'd know if a specific mgmt core is sleeping and
+ * wake it up. o/w, we could interrupt an already-running mgmt
+ * core that won't get to our new proc anytime soon. also, by
+ * poking core 0, a different mgmt core could remain idle (and
+ * this process would sleep) until its tick goes off */
send_ipi(0, I_POKE_CORE);
}
}
@@ -286,24 +287,27 @@
struct proc *p;
uint32_t pcoreid = core_id();
struct per_cpu_info *pcpui = &per_cpu_info[pcoreid];
- /* if there are any runnables, run them here and put any currently running
- * SCP on the tail of the runnable queue. */
+
+ /* if there are any runnables, run them here and put any currently
+ * running SCP on the tail of the runnable queue. */
if ((p = TAILQ_FIRST(&runnable_scps))) {
/* someone is currently running, dequeue them */
if (pcpui->owning_proc) {
spin_lock(&pcpui->owning_proc->proc_lock);
- /* process might be dying, with a KMSG to clean it up waiting on
- * this core. can't do much, so we'll attempt to restart */
+ /* process might be dying, with a KMSG to clean it up
+ * waiting on this core. can't do much, so we'll
+ * attempt to restart */
if (proc_is_dying(pcpui->owning_proc)) {
run_as_rkm(run_scheduler);
spin_unlock(&pcpui->owning_proc->proc_lock);
return FALSE;
}
- printd("Descheduled %d in favor of %d\n", pcpui->owning_proc->pid,
- p->pid);
+ printd("Descheduled %d in favor of %d\n",
+ pcpui->owning_proc->pid, p->pid);
__proc_set_state(pcpui->owning_proc, PROC_RUNNABLE_S);
- /* Saving FP state aggressively. Odds are, the SCP was hit by an
- * IRQ and has a HW ctx, in which case we must save. */
+ /* Saving FP state aggressively. Odds are, the SCP was
+ * hit by an IRQ and has a HW ctx, in which case we must
+ * save. */
__proc_save_fpu_s(pcpui->owning_proc);
__proc_save_context_s(pcpui->owning_proc);
vcore_account_offline(pcpui->owning_proc, 0);
@@ -311,14 +315,17 @@
__unmap_vcore(p, 0);
__seq_end_write(&p->procinfo->coremap_seqctr);
spin_unlock(&pcpui->owning_proc->proc_lock);
- /* round-robin the SCPs (inserts at the end of the queue) */
- switch_lists(pcpui->owning_proc, &unrunnable_scps, &runnable_scps);
+ /* round-robin the SCPs (inserts at the end of the
+ * queue) */
+ switch_lists(pcpui->owning_proc, &unrunnable_scps,
+ &runnable_scps);
clear_owning_proc(pcoreid);
- /* Note we abandon core. It's not strictly necessary. If
- * we didn't, the TLB would still be loaded with the old
- * one, til we proc_run_s, and the various paths in
- * proc_run_s would pick it up. This way is a bit safer for
- * future changes, but has an extra (empty) TLB flush. */
+ /* Note we abandon core. It's not strictly necessary.
+ * If we didn't, the TLB would still be loaded with the
+ * old one, til we proc_run_s, and the various paths in
+ * proc_run_s would pick it up. This way is a bit safer
+ * for future changes, but has an extra (empty) TLB
+ * flush. */
abandon_core();
}
/* Run the new proc */
@@ -335,29 +342,33 @@
static uint32_t get_cores_needed(struct proc *p)
{
uint32_t amt_wanted, amt_granted;
+
amt_wanted = p->procdata->res_req[RES_CORES].amt_wanted;
- /* Help them out - if they ask for something impossible, give them 1 so they
- * can make some progress. (this is racy, and unnecessary). */
+ /* Help them out - if they ask for something impossible, give them 1 so
+ * they can make some progress. (this is racy, and unnecessary). */
if (amt_wanted > p->procinfo->max_vcores) {
- printk("[kernel] proc %d wanted more than max, wanted %d\n", p->pid,
- amt_wanted);
+ printk("[kernel] proc %d wanted more than max, wanted %d\n",
+ p->pid, amt_wanted);
p->procdata->res_req[RES_CORES].amt_wanted = 1;
amt_wanted = 1;
}
- /* There are a few cases where amt_wanted is 0, but they are still RUNNABLE
- * (involving yields, events, and preemptions). In these cases, give them
- * at least 1, so they can make progress and yield properly. If they are
- * not WAITING, they did not yield and may have missed a message. */
+ /* There are a few cases where amt_wanted is 0, but they are still
+ * RUNNABLE (involving yields, events, and preemptions). In these
+ * cases, give them at least 1, so they can make progress and yield
+ * properly. If they are not WAITING, they did not yield and may have
+ * missed a message. */
if (!amt_wanted) {
- /* could ++, but there could be a race and we don't want to give them
- * more than they ever asked for (in case they haven't prepped) */
+ /* could ++, but there could be a race and we don't want to give
+ * them more than they ever asked for (in case they haven't
+ * prepped) */
p->procdata->res_req[RES_CORES].amt_wanted = 1;
amt_wanted = 1;
}
- /* amt_granted is racy - they could be *yielding*, but currently they can't
- * be getting any new cores if the caller is in the mcp_ksched. this is
- * okay - we won't accidentally give them more cores than they *ever* wanted
- * (which could crash them), but our answer might be a little stale. */
+ /* amt_granted is racy - they could be *yielding*, but currently they
+ * can't be getting any new cores if the caller is in the mcp_ksched.
+ * this is okay - we won't accidentally give them more cores than they
+ * *ever* wanted (which could crash them), but our answer might be a
+ * little stale. */
amt_granted = p->procinfo->res_grant[RES_CORES];
/* Do not do an assert like this: it could fail (yield in progress): */
//assert(amt_granted == p->procinfo->num_vcores);
@@ -375,21 +386,24 @@
struct proc *p, *temp;
uint32_t amt_needed;
struct proc_list *temp_mcp_list;
+
/* locking to protect the MCP lists' integrity and membership */
spin_lock(&sched_lock);
- /* 2-pass scheme: check each proc on the primary list (FCFS). if they need
- * nothing, put them on the secondary list. if they need something, rip
- * them off the list, service them, and if they are still not dying, put
- * them on the secondary list. We cull the entire primary list, so that
- * when we start from the beginning each time, we aren't repeatedly checking
- * procs we looked at on previous waves.
+ /* 2-pass scheme: check each proc on the primary list (FCFS). if they
+ * need nothing, put them on the secondary list. if they need
+ * something, rip them off the list, service them, and if they are still
+ * not dying, put them on the secondary list. We cull the entire
+ * primary list, so that when we start from the beginning each time, we
+ * aren't repeatedly checking procs we looked at on previous waves.
*
- * TODO: we could modify this such that procs that we failed to service move
- * to yet another list or something. We can also move the WAITINGs to
- * another list and have wakeup move them back, etc. */
+ * TODO: we could modify this such that procs that we failed to service
+ * move to yet another list or something. We can also move the WAITINGs
+ * to another list and have wakeup move them back, etc. */
while (!TAILQ_EMPTY(primary_mcps)) {
- TAILQ_FOREACH_SAFE(p, primary_mcps, ksched_data.proc_link, temp) {
- if (p->state == PROC_WAITING) { /* unlocked peek at the state */
+ TAILQ_FOREACH_SAFE(p, primary_mcps, ksched_data.proc_link, temp)
+ {
+ /* unlocked peek at the state */
+ if (p->state == PROC_WAITING) {
switch_lists(p, primary_mcps, secondary_mcps);
continue;
}
@@ -400,30 +414,34 @@
}
/* o/w, we want to give cores to this proc */
remove_from_list(p, primary_mcps);
- /* now it won't die, but it could get removed from lists and have
- * its stuff unprov'd when we unlock */
+ /* now it won't die, but it could get removed from lists
+ * and have its stuff unprov'd when we unlock */
proc_incref(p, 1);
- /* GIANT WARNING: __core_req will unlock the sched lock for a bit.
- * It will return with it locked still. We could unlock before we
- * pass in, but they will relock right away. */
- // notionally_unlock(&ksched_lock); /* for mouse-eyed viewers */
+ /* GIANT WARNING: __core_req will unlock the sched lock
+ * for a bit. It will return with it locked still. We
+ * could unlock before we pass in, but they will relock
+ * right away. */
+ /* for mouse-eyed viewers */
+ // notionally_unlock(&ksched_lock);
__core_request(p, amt_needed);
// notionally_lock(&ksched_lock);
- /* Peeking at the state is okay, since we hold a ref. Once it is
- * DYING, it'll remain DYING until we decref. And if there is a
- * concurrent death, that will spin on the ksched lock (which we
- * hold, and which protects the proc lists). */
+ /* Peeking at the state is okay, since we hold a ref.
+ * Once it is DYING, it'll remain DYING until we decref.
+ * And if there is a concurrent death, that will spin on
+ * the ksched lock (which we hold, and which protects
+ * the proc lists). */
if (!proc_is_dying(p))
add_to_list(p, secondary_mcps);
- proc_decref(p); /* fyi, this may trigger __proc_free */
- /* need to break: the proc lists may have changed when we unlocked
- * in core_req in ways that the FOREACH_SAFE can't handle. */
+ proc_decref(p); /* fyi, this may trigger __proc_free */
+ /* need to break: the proc lists may have changed when
+ * we unlocked in core_req in ways that the FOREACH_SAFE
+ * can't handle. */
break;
}
}
/* at this point, we moved all the procs over to the secondary list, and
- * attempted to service the ones that wanted something. now just swap the
- * lists for the next invocation of the ksched. */
+ * attempted to service the ones that wanted something. now just swap
+ * the lists for the next invocation of the ksched. */
temp_mcp_list = primary_mcps;
primary_mcps = secondary_mcps;
secondary_mcps = temp_mcp_list;
@@ -439,8 +457,8 @@
* Don't call this from interrupt context (grabs proclocks). */
void run_scheduler(void)
{
- /* MCP scheduling: post work, then poke. for now, i just want the func to
- * run again, so merely a poke is sufficient. */
+ /* MCP scheduling: post work, then poke. for now, i just want the func
+ * to run again, so merely a poke is sufficient. */
poke(&ksched_poker, 0);
if (management_core()) {
spin_lock(&sched_lock);
@@ -454,8 +472,8 @@
* eventually gets around to looking at resource desires. */
void poke_ksched(struct proc *p, unsigned int res_type)
{
- /* ignoring res_type for now. could post that if we wanted (would need some
- * other structs/flags) */
+ /* ignoring res_type for now. could post that if we wanted (would need
+ * some other structs/flags) */
if (!__proc_is_mcp(p))
return;
poke(&ksched_poker, p);
@@ -473,14 +491,14 @@
spin_lock(&sched_lock);
new_proc = __schedule_scp();
spin_unlock(&sched_lock);
- /* if we just scheduled a proc, we need to manually restart it, instead of
- * returning. if we return, the core will halt. */
+ /* if we just scheduled a proc, we need to manually restart it, instead
+ * of returning. if we return, the core will halt. */
if (new_proc) {
proc_restartcore();
assert(0);
}
- /* Could drop into the monitor if there are no processes at all. For now,
- * the 'call of the giraffe' suffices. */
+ /* Could drop into the monitor if there are no processes at all. For
+ * now, the 'call of the giraffe' suffices. */
}
/* Available resources changed (plus or minus). Some parts of the kernel may
@@ -508,61 +526,76 @@
uint32_t pcoreid;
struct proc *proc_to_preempt;
bool success;
+
/* we come in holding the ksched lock, and we hold it here to protect
* allocations and provisioning. */
- /* get all available cores from their prov_not_alloc list. the list might
- * change when we unlock (new cores added to it, or the entire list emptied,
- * but no core allocations will happen (we hold the poke)). */
+ /* get all available cores from their prov_not_alloc list. the list
+ * might change when we unlock (new cores added to it, or the entire
+ * list emptied, but no core allocations will happen (we hold the
+ * poke)). */
while (nr_to_grant != amt_needed) {
/* Find the next best core to allocate to p. It may be a core
* provisioned to p, and it might not be. */
pcoreid = __find_best_core_to_alloc(p);
- /* If no core is returned, we know that there are no more cores to give
- * out, so we exit the loop. */
+ /* If no core is returned, we know that there are no more cores
+ * to give out, so we exit the loop. */
if (pcoreid == -1)
break;
- /* If the pcore chosen currently has a proc allocated to it, we know
- * it must be provisioned to p, but not allocated to it. We need to try
- * to preempt. After this block, the core will be track_dealloc'd and
- * on the idle list (regardless of whether we had to preempt or not) */
+ /* If the pcore chosen currently has a proc allocated to it, we
+ * know it must be provisioned to p, but not allocated to it. We
+ * need to try to preempt. After this block, the core will be
+ * track_dealloc'd and on the idle list (regardless of whether
+ * we had to preempt or not) */
if (get_alloc_proc(pcoreid)) {
proc_to_preempt = get_alloc_proc(pcoreid);
- /* would break both preemption and maybe the later decref */
+ /* would break both preemption and maybe the later
+ * decref */
assert(proc_to_preempt != p);
/* need to keep a valid, external ref when we unlock */
proc_incref(proc_to_preempt, 1);
spin_unlock(&sched_lock);
- /* sending no warning time for now - just an immediate preempt. */
- success = proc_preempt_core(proc_to_preempt, pcoreid, 0);
- /* reaquire locks to protect provisioning and idle lists */
+ /* sending no warning time for now - just an immediate
+ * preempt. */
+ success = proc_preempt_core(proc_to_preempt, pcoreid,
+ 0);
+ /* reaquire locks to protect provisioning and idle lists
+ */
spin_lock(&sched_lock);
if (success) {
- /* we preempted it before the proc could yield or die.
- * alloc_proc should not have changed (it'll change in death and
- * idle CBs). the core is not on the idle core list. (if we
- * ever have proc alloc lists, it'll still be on the old proc's
- * list). */
+ /* we preempted it before the proc could yield
+ * or die. alloc_proc should not have changed
+ * (it'll change in death and idle CBs). the
+ * core is not on the idle core list. (if we
+ * ever have proc alloc lists, it'll still be on
+ * the old proc's list). */
assert(get_alloc_proc(pcoreid));
- /* regardless of whether or not it is still prov to p, we need
- * to note its dealloc. we are doing some excessive checking of
- * p == prov_proc, but using this helper is a lot clearer. */
+ /* regardless of whether or not it is still prov
+ * to p, we need to note its dealloc. we are
+ * doing some excessive checking of p ==
+ * prov_proc, but using this helper is a lot
+ * clearer. */
__track_core_dealloc(proc_to_preempt, pcoreid);
} else {
- /* the preempt failed, which should only happen if the pcore was
- * unmapped (could be dying, could be yielding, but NOT
- * preempted). whoever unmapped it also triggered (or will soon
- * trigger) a track_core_dealloc and put it on the idle list.
- * Our signal for this is get_alloc_proc() being 0. We need to
- * spin and let whoever is trying to free the core grab the
- * ksched lock. We could use an 'ignore_next_idle' flag per
- * sched_pcore, but it's not critical anymore.
+ /* the preempt failed, which should only happen
+ * if the pcore was unmapped (could be dying,
+ * could be yielding, but NOT preempted).
+ * whoever unmapped it also triggered (or will
+ * soon trigger) a track_core_dealloc and put it
+ * on the idle list. Our signal for this is
+ * get_alloc_proc() being 0. We need to spin and
+ * let whoever is trying to free the core grab
+ * the ksched lock. We could use an
+ * 'ignore_next_idle' flag per sched_pcore, but
+ * it's not critical anymore.
*
- * Note, we're relying on us being the only preemptor - if the
- * core was unmapped by *another* preemptor, there would be no
- * way of knowing the core was made idle *yet* (the success
- * branch in another thread). likewise, if there were another
- * allocator, the pcore could have been put on the idle list and
- * then quickly removed/allocated. */
+ * Note, we're relying on us being the only
+ * preemptor - if the core was unmapped by
+ * *another* preemptor, there would be no way of
+ * knowing the core was made idle *yet* (the
+ * success branch in another thread). likewise,
+ * if there were another allocator, the pcore
+ * could have been put on the idle list and then
+ * quickly removed/allocated. */
cmb();
while (get_alloc_proc(pcoreid)) {
/* this loop should be very rare */
@@ -573,53 +606,59 @@
}
/* no longer need to keep p_to_pre alive */
proc_decref(proc_to_preempt);
- /* might not be prov to p anymore (rare race). pcoreid is idle - we
- * might get it later, or maybe we'll give it to its rightful proc*/
+ /* might not be prov to p anymore (rare race). pcoreid
+ * is idle - we might get it later, or maybe we'll give
+ * it to its rightful proc*/
if (get_prov_proc(pcoreid) != p)
continue;
}
- /* At this point, the pcore is idle, regardless of how we got here
- * (successful preempt, failed preempt, or it was idle in the first
- * place). We also know the core is still provisioned to us. Lets add
- * it to the corelist for p (so we can give it to p in bulk later), and
- * track its allocation with p (so our internal data structures stay in
- * sync). We rely on the fact that we are the only allocator (pcoreid is
- * still idle, despite (potentially) unlocking during the preempt
- * attempt above). It is guaranteed to be track_dealloc'd()
- * (regardless of how we got here). */
+ /* At this point, the pcore is idle, regardless of how we got
+ * here (successful preempt, failed preempt, or it was idle in
+ * the first place). We also know the core is still provisioned
+ * to us. Lets add it to the corelist for p (so we can give it
+ * to p in bulk later), and track its allocation with p (so our
+ * internal data structures stay in sync). We rely on the fact
+ * that we are the only allocator (pcoreid is still idle,
+ * despite (potentially) unlocking during the preempt attempt
+ * above). It is guaranteed to be track_dealloc'd() (regardless
+ * of how we got here). */
corelist[nr_to_grant] = pcoreid;
nr_to_grant++;
__track_core_alloc(p, pcoreid);
}
/* Now, actually give them out */
if (nr_to_grant) {
- /* Need to unlock before calling out to proc code. We are somewhat
- * relying on being the only one allocating 'thread' here, since another
- * allocator could have seen these cores (if they are prov to some proc)
- * and could be trying to give them out (and assuming they are already
- * on the idle list). */
+ /* Need to unlock before calling out to proc code. We are
+ * somewhat relying on being the only one allocating 'thread'
+ * here, since another allocator could have seen these cores (if
+ * they are prov to some proc) and could be trying to give them
+ * out (and assuming they are already on the idle list). */
spin_unlock(&sched_lock);
- /* give them the cores. this will start up the extras if RUNNING_M. */
+ /* give them the cores. this will start up the extras if
+ * RUNNING_M. */
spin_lock(&p->proc_lock);
- /* if they fail, it is because they are WAITING or DYING. we could give
- * the cores to another proc or whatever. for the current type of
- * ksched, we'll just put them back on the pile and return. Note, the
- * ksched could check the states after locking, but it isn't necessary:
- * just need to check at some point in the ksched loop. */
+ /* if they fail, it is because they are WAITING or DYING. we
+ * could give the cores to another proc or whatever. for the
+ * current type of ksched, we'll just put them back on the pile
+ * and return. Note, the ksched could check the states after
+ * locking, but it isn't necessary: just need to check at some
+ * point in the ksched loop. */
if (__proc_give_cores(p, corelist, nr_to_grant)) {
spin_unlock(&p->proc_lock);
- /* we failed, put the cores and track their dealloc. lock is
- * protecting those structures. */
+ /* we failed, put the cores and track their dealloc.
+ * lock is protecting those structures. */
spin_lock(&sched_lock);
__track_core_dealloc_bulk(p, corelist, nr_to_grant);
} else {
- /* at some point after giving cores, call proc_run_m() (harmless on
- * RUNNING_Ms). You can give small groups of cores, then run them
- * (which is more efficient than interleaving runs with the gives
- * for bulk preempted processes). */
+ /* at some point after giving cores, call proc_run_m()
+ * (harmless on RUNNING_Ms). You can give small groups
+ * of cores, then run them (which is more efficient than
+ * interleaving runs with the gives for bulk preempted
+ * processes). */
__proc_run_m(p);
spin_unlock(&p->proc_lock);
- /* main mcp_ksched wants this held (it came to __core_req held) */
+ /* main mcp_ksched wants this held (it came to
+ * __core_req held) */
spin_lock(&sched_lock);
}
}
@@ -630,8 +669,8 @@
* implemented in __provision_core, with a lock, error checking, etc. */
int provision_core(struct proc *p, uint32_t pcoreid)
{
- /* Make sure we aren't asking for something that doesn't exist (bounds check
- * on the pcore array) */
+ /* Make sure we aren't asking for something that doesn't exist (bounds
+ * check on the pcore array) */
if (!(pcoreid < num_cores)) {
set_errno(ENXIO);
return -1;
@@ -642,8 +681,8 @@
return -1;
}
/* Note the sched lock protects the tailqs for all procs in this code.
- * If we need a finer grained sched lock, this is one place where we could
- * have a different lock */
+ * If we need a finer grained sched lock, this is one place where we
+ * could have a different lock */
spin_lock(&sched_lock);
__provision_core(p, pcoreid);
spin_unlock(&sched_lock);
@@ -654,6 +693,7 @@
void sched_diag(void)
{
struct proc *p;
+
spin_lock(&sched_lock);
TAILQ_FOREACH(p, &runnable_scps, ksched_data.proc_link)
printk("Runnable _S PID: %d\n", p->pid);
@@ -673,8 +713,9 @@
printk("PID: %d\n", p->pid);
printk("--------------------\n");
for (int i = 0; i < MAX_NUM_RESOURCES; i++)
- printk("Res type: %02d, amt wanted: %08d, amt granted: %08d\n", i,
- p->procdata->res_req[i].amt_wanted, p->procinfo->res_grant[i]);
+ printk("Res type: %02d, amt wanted: %08d, amt granted: %08d\n",
+ i, p->procdata->res_req[i].amt_wanted,
+ p->procinfo->res_grant[i]);
}
void print_all_resources(void)
diff --git a/kern/src/slab.c b/kern/src/slab.c
index 807026e..520932d 100644
--- a/kern/src/slab.c
+++ b/kern/src/slab.c
@@ -106,7 +106,7 @@
qlock(&arenas_and_slabs_lock);
TAILQ_FOREACH(kc_i, &all_kmem_caches, all_kmc_link) {
if (!strcmp(kc->name, kc_i->name))
- warn("New KMC %s created, but one with that name exists!",
+ warn("Creatgin KMC %s, but one with that name exists!",
kc->name);
}
TAILQ_INSERT_TAIL(&all_kmem_caches, kc, all_kmc_link);
@@ -179,21 +179,21 @@
/* The lock is contended. When we finally get the lock, we'll up the
* contention count and see if we've had too many contentions over time.
*
- * The idea is that if there are bursts of contention worse than X contended
- * acquisitions in Y nsec, then we'll grow the magazines. This might not be
- * that great of an approach - every thread gets one count, regardless of
- * how long they take.
+ * The idea is that if there are bursts of contention worse than X
+ * contended acquisitions in Y nsec, then we'll grow the magazines.
+ * This might not be that great of an approach - every thread gets one
+ * count, regardless of how long they take.
*
- * We read the time before locking so that we don't artificially grow the
- * window too much. Say the lock is heavily contended and we take a long
- * time to get it. Perhaps X threads try to lock it immediately, but it
- * takes over Y seconds for the Xth thread to actually get the lock. We
- * might then think the burst wasn't big enough. */
+ * We read the time before locking so that we don't artificially grow
+ * the window too much. Say the lock is heavily contended and we take a
+ * long time to get it. Perhaps X threads try to lock it immediately,
+ * but it takes over Y seconds for the Xth thread to actually get the
+ * lock. We might then think the burst wasn't big enough. */
time = nsec();
spin_lock_irqsave(&depot->lock);
- /* If there are no not-empty mags, we're probably fighting for the lock not
- * because the magazines aren't big enough, but because there aren't enough
- * mags in the system yet. */
+ /* If there are no not-empty mags, we're probably fighting for the lock
+ * not because the magazines aren't big enough, but because there aren't
+ * enough mags in the system yet. */
if (!depot->nr_not_empty)
return;
if (time - depot->busy_start > resize_timeout_ns) {
@@ -204,8 +204,8 @@
if (depot->busy_count > resize_threshold) {
depot->busy_count = 0;
depot->magsize = MIN(KMC_MAG_MAX_SZ, depot->magsize + 1);
- /* That's all we do - the pccs will eventually notice and up their
- * magazine sizes. */
+ /* That's all we do - the pccs will eventually notice and up
+ * their magazine sizes. */
}
}
@@ -277,8 +277,10 @@
for (int i = 0; i < kmc_nr_pcpu_caches(); i++) {
pcc[i].irq_state = 0;
pcc[i].magsize = KMC_MAG_MIN_SZ;
- pcc[i].loaded = __kmem_alloc_from_slab(kmem_magazine_cache, MEM_WAIT);
- pcc[i].prev = __kmem_alloc_from_slab(kmem_magazine_cache, MEM_WAIT);
+ pcc[i].loaded = __kmem_alloc_from_slab(kmem_magazine_cache,
+ MEM_WAIT);
+ pcc[i].prev = __kmem_alloc_from_slab(kmem_magazine_cache,
+ MEM_WAIT);
pcc[i].nr_allocs_ever = 0;
}
return pcc;
@@ -304,7 +306,8 @@
panic("Cache %s object alignment is actually MIN(PGSIZE, align (%p))",
name, align);
kc->flags = flags;
- /* We might want some sort of per-call site NUMA-awareness in the future. */
+ /* We might want some sort of per-call site NUMA-awareness in the
+ * future. */
kc->source = source ? source : kpages_arena;
TAILQ_INIT(&kc->full_slab_list);
TAILQ_INIT(&kc->partial_slab_list);
@@ -318,16 +321,17 @@
hash_init_hh(&kc->hh);
for (int i = 0; i < kc->hh.nr_hash_lists; i++)
BSD_LIST_INIT(&kc->static_hash[i]);
- /* No touch must use bufctls, even for small objects, so that it does not
- * use the object as memory. Note that if we have an arbitrary source,
- * small objects, and we're 'pro-touch', the small allocation path will
- * assume we're importing from a PGSIZE-aligned source arena. */
+ /* No touch must use bufctls, even for small objects, so that it does
+ * not use the object as memory. Note that if we have an arbitrary
+ * source, small objects, and we're 'pro-touch', the small allocation
+ * path will assume we're importing from a PGSIZE-aligned source arena.
+ */
if ((obj_size > SLAB_LARGE_CUTOFF) || (flags & KMC_NOTOUCH))
kc->flags |= __KMC_USE_BUFCTL;
depot_init(&kc->depot);
kmem_trace_ht_init(&kc->trace_ht);
- /* We do this last, since this will all into the magazine cache - which we
- * could be creating on this call! */
+ /* We do this last, since this will all into the magazine cache - which
+ * we could be creating on this call! */
kc->pcpu_caches = build_pcpu_caches();
add_importing_slab(kc->source, kc);
kmc_track(kc);
@@ -343,8 +347,8 @@
void kmem_cache_init(void)
{
- /* magazine must be first - all caches, including mags, will do a slab alloc
- * from the mag cache. */
+ /* magazine must be first - all caches, including mags, will do a slab
+ * alloc from the mag cache. */
static_assert(sizeof(struct kmem_magazine) <= SLAB_LARGE_CUTOFF);
__kmem_cache_create(kmem_magazine_cache, "kmem_magazine",
sizeof(struct kmem_magazine),
@@ -378,8 +382,8 @@
{
struct kmem_cache *kc = kmem_cache_alloc(kmem_cache_cache, 0);
- __kmem_cache_create(kc, name, obj_size, align, flags, source, ctor, dtor,
- priv);
+ __kmem_cache_create(kc, name, obj_size, align, flags, source, ctor,
+ dtor, priv);
return kc;
}
@@ -427,10 +431,11 @@
void *buf_start = (void*)SIZE_MAX;
BSD_LIST_FOREACH_SAFE(i, &a_slab->bufctl_freelist, link, temp) {
- // Track the lowest buffer address, which is the start of the buffer
+ // Track the lowest buffer address, which is the start
+ // of the buffer
buf_start = MIN(buf_start, i->buf_addr);
- /* This is a little dangerous, but we can skip removing, since we
- * init the freelist when we reuse the slab. */
+ /* This is a little dangerous, but we can skip removing,
+ * since we init the freelist when we reuse the slab. */
kmem_cache_free(kmem_bufctl_cache, i);
}
arena_free(cp->source, buf_start, cp->import_amt);
@@ -451,9 +456,9 @@
spin_lock_irqsave(&cp->cache_lock);
assert(TAILQ_EMPTY(&cp->full_slab_list));
assert(TAILQ_EMPTY(&cp->partial_slab_list));
- /* Clean out the empty list. We can't use a regular FOREACH here, since the
- * link element is stored in the slab struct, which is stored on the page
- * that we are freeing. */
+ /* Clean out the empty list. We can't use a regular FOREACH here, since
+ * the link element is stored in the slab struct, which is stored on the
+ * page that we are freeing. */
a_slab = TAILQ_FIRST(&cp->empty_slab_list);
while (a_slab) {
next = TAILQ_NEXT(a_slab, link);
@@ -480,7 +485,8 @@
/* TODO: we only need to pull from base if our arena is a base or we are
* inside a kpages arena (keep in mind there could be more than one of
* those, depending on how we do NUMA allocs). This might help with
- * fragmentation. To know this, we'll need the caller to pass us a flag. */
+ * fragmentation. To know this, we'll need the caller to pass us a
+ * flag. */
new_tbl = base_zalloc(NULL, new_tbl_sz, ARENA_INSTANTFIT | MEM_ATOMIC);
if (!new_tbl)
return;
@@ -492,8 +498,10 @@
for (int i = 0; i < old_tbl_nr_lists; i++) {
while ((bc_i = BSD_LIST_FIRST(&old_tbl[i]))) {
BSD_LIST_REMOVE(bc_i, link);
- hash_idx = hash_ptr(bc_i->buf_addr, cp->hh.nr_hash_bits);
- BSD_LIST_INSERT_HEAD(&cp->alloc_hash[hash_idx], bc_i, link);
+ hash_idx = hash_ptr(bc_i->buf_addr,
+ cp->hh.nr_hash_bits);
+ BSD_LIST_INSERT_HEAD(&cp->alloc_hash[hash_idx], bc_i,
+ link);
}
}
hash_reset_load_limit(&cp->hh);
@@ -534,10 +542,11 @@
static void *__kmem_alloc_from_slab(struct kmem_cache *cp, int flags)
{
void *retval = NULL;
+
spin_lock_irqsave(&cp->cache_lock);
// look at partial list
struct kmem_slab *a_slab = TAILQ_FIRST(&cp->partial_slab_list);
- // if none, go to empty list and get an empty and make it partial
+ // if none, go to empty list and get an empty and make it partial
if (!a_slab) {
// TODO: think about non-sleeping flags
if (TAILQ_EMPTY(&cp->empty_slab_list) &&
@@ -556,12 +565,13 @@
// have a partial now (a_slab), get an item, return item
if (!__use_bufctls(cp)) {
retval = a_slab->free_small_obj;
- /* the next free_small_obj address is stored at the beginning of the
- * current free_small_obj. */
+ /* the next free_small_obj address is stored at the beginning of
+ * the current free_small_obj. */
a_slab->free_small_obj = *(uintptr_t**)(a_slab->free_small_obj);
} else {
// rip the first bufctl out of the partial slab's buf list
- struct kmem_bufctl *a_bufctl = BSD_LIST_FIRST(&a_slab->bufctl_freelist);
+ struct kmem_bufctl *a_bufctl =
+ BSD_LIST_FIRST(&a_slab->bufctl_freelist);
BSD_LIST_REMOVE(a_bufctl, link);
__track_alloc(cp, a_bufctl);
@@ -638,8 +648,9 @@
// find its slab
a_slab = (struct kmem_slab*)(ROUNDDOWN((uintptr_t)buf, PGSIZE) +
PGSIZE - sizeof(struct kmem_slab));
- /* write location of next free small obj to the space at the beginning
- * of the buffer, then list buf as the next free small obj */
+ /* write location of next free small obj to the space at the
+ * beginning of the buffer, then list buf as the next free small
+ * obj */
*(uintptr_t**)buf = a_slab->free_small_obj;
a_slab->free_small_obj = buf;
} else {
@@ -678,16 +689,16 @@
unlock_pcu_cache(pcc);
return;
}
- /* The paper checks 'is empty' here. But we actually just care if it has
- * room left, not that prev is completely empty. This could be the case due
- * to magazine resize. */
+ /* The paper checks 'is empty' here. But we actually just care if it
+ * has room left, not that prev is completely empty. This could be the
+ * case due to magazine resize. */
if (pcc->prev->nr_rounds < pcc->magsize) {
__swap_mags(pcc);
goto try_free;
}
lock_depot(depot);
- /* Here's where the resize magic happens. We'll start using it for the next
- * magazine. */
+ /* Here's where the resize magic happens. We'll start using it for the
+ * next magazine. */
pcc->magsize = depot->magsize;
mag = SLIST_FIRST(&depot->empty);
if (mag) {
@@ -702,11 +713,11 @@
unlock_depot(depot);
/* Need to unlock, in case we end up calling back into ourselves. */
unlock_pcu_cache(pcc);
- /* don't want to wait on a free. if this fails, we can still just give it
- * to the slab layer. */
+ /* don't want to wait on a free. if this fails, we can still just give
+ * it to the slab layer. */
mag = kmem_cache_alloc(kmem_magazine_cache, MEM_ATOMIC);
if (mag) {
- assert(mag->nr_rounds == 0); /* paranoia, can probably remove */
+ assert(mag->nr_rounds == 0);
lock_depot(depot);
SLIST_INSERT_HEAD(&depot->empty, mag, link);
depot->nr_empty++;
@@ -735,9 +746,10 @@
if (!__use_bufctls(cp)) {
void *a_page;
- /* Careful, this assumes our source is a PGSIZE-aligned allocator. We
- * could use xalloc to enforce the alignment, but that'll bypass the
- * qcaches, which we don't want. Caller beware. */
+ /* Careful, this assumes our source is a PGSIZE-aligned
+ * allocator. We could use xalloc to enforce the alignment, but
+ * that'll bypass the qcaches, which we don't want. Caller
+ * beware. */
a_page = arena_alloc(cp->source, PGSIZE, MEM_ATOMIC);
if (!a_page)
return FALSE;
@@ -749,9 +761,11 @@
cp->obj_size;
// TODO: consider staggering this IAW section 4.3
a_slab->free_small_obj = a_page;
- /* Walk and create the free list, which is circular. Each item stores
- * the location of the next one at the beginning of the block. */
+ /* Walk and create the free list, which is circular. Each item
+ * stores the location of the next one at the beginning of the
+ * block. */
void *buf = a_slab->free_small_obj;
+
for (int i = 0; i < a_slab->num_total_obj - 1; i++) {
*(uintptr_t**)buf = buf + cp->obj_size;
buf += cp->obj_size;
@@ -774,7 +788,8 @@
/* for each buffer, set up a bufctl and point to the buffer */
for (int i = 0; i < a_slab->num_total_obj; i++) {
a_bufctl = kmem_cache_alloc(kmem_bufctl_cache, 0);
- BSD_LIST_INSERT_HEAD(&a_slab->bufctl_freelist, a_bufctl, link);
+ BSD_LIST_INSERT_HEAD(&a_slab->bufctl_freelist, a_bufctl,
+ link);
a_bufctl->buf_addr = buf;
a_bufctl->my_slab = a_slab;
buf += cp->obj_size;
diff --git a/kern/src/smallidpool.c b/kern/src/smallidpool.c
index 6e6e8b9..f9ce294 100644
--- a/kern/src/smallidpool.c
+++ b/kern/src/smallidpool.c
@@ -15,6 +15,7 @@
struct u16_pool *create_u16_pool(unsigned int size)
{
struct u16_pool *id;
+
/* We could have size be a u16, but this might catch bugs where users
* tried to ask for more than 2^16 and had it succeed. */
if (size > MAX_U16_POOL_SZ)
@@ -43,6 +44,7 @@
int get_u16(struct u16_pool *id)
{
uint16_t v;
+
spin_lock_irqsave(&id->lock);
if (id->tos == id->size) {
spin_unlock_irqsave(&id->lock);
@@ -52,7 +54,8 @@
spin_unlock_irqsave(&id->lock);
/* v is ours, we can freely read and write its check field */
if (id->check[v] != 0xfe) {
- printk("BAD! %d is already allocated (0x%x)\n", v, id->check[v]);
+ printk("BAD! %d is already allocated (0x%x)\n", v,
+ id->check[v]);
return -1;
}
id->check[v] = 0x5a;
@@ -63,7 +66,8 @@
{
/* we could check for if v is in range before dereferencing. */
if (id->check[v] != 0x5a) {
- printk("BAD! freeing non-allocated: %d(0x%x)\n", v, id->check[v]);
+ printk("BAD! freeing non-allocated: %d(0x%x)\n", v,
+ id->check[v]);
return;
}
id->check[v] = 0xfe;
diff --git a/kern/src/smp.c b/kern/src/smp.c
index f9dbe2b..c3629b4 100644
--- a/kern/src/smp.c
+++ b/kern/src/smp.c
@@ -38,6 +38,7 @@
static void try_run_proc(void)
{
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+
/* There was a process running here, and we should return to it. */
if (pcpui->owning_proc) {
assert(!pcpui->cur_kthread->sysc);
@@ -45,12 +46,12 @@
__proc_startcore(pcpui->owning_proc, pcpui->cur_ctx);
assert(0);
} else {
- /* Make sure we have abandoned core. It's possible to have an owner
- * without a current (smp_idle, __startcore, __death).
+ /* Make sure we have abandoned core. It's possible to have an
+ * owner without a current (smp_idle, __startcore, __death).
*
- * If we had a current process, we might trigger __proc_free, which
- * could send us a KMSG. Since we're called after PRKM, let's just
- * restart the idle loop. */
+ * If we had a current process, we might trigger __proc_free,
+ * which could send us a KMSG. Since we're called after PRKM,
+ * let's just restart the idle loop. */
if (abandon_core())
smp_idle();
}
@@ -70,17 +71,17 @@
pcpui->cur_kthread->flags = KTH_DEFAULT_FLAGS;
while (1) {
- /* This might wake a kthread (the gp ktask), so be sure to run PRKM
- * after reporting the quiescent state. */
+ /* This might wake a kthread (the gp ktask), so be sure to run
+ * PRKM after reporting the quiescent state. */
rcu_report_qs();
/* If this runs an RKM, we'll call smp_idle from the top. */
process_routine_kmsg();
try_run_proc();
cpu_bored(); /* call out to the ksched */
/* cpu_halt() atomically turns on interrupts and halts the core.
- * Important to do this, since we could have a RKM come in via an
- * interrupt right while PRKM is returning, and we wouldn't catch
- * it. When it returns, IRQs are back off. */
+ * Important to do this, since we could have a RKM come in via
+ * an interrupt right while PRKM is returning, and we wouldn't
+ * catch it. When it returns, IRQs are back off. */
__set_cpu_state(pcpui, CPU_STATE_IDLE);
cpu_halt();
__set_cpu_state(pcpui, CPU_STATE_KERNEL);
@@ -108,11 +109,12 @@
__arch_pcpu_init(coreid);
/* init our kthread (tracks our currently running context) */
kthread = __kthread_zalloc();
- kthread->stacktop = get_stack_top(); /* assumes we're on the 1st page */
+ /* assumes we're on the 1st page */
+ kthread->stacktop = get_stack_top();
pcpui->cur_kthread = kthread;
- /* Treat the startup threads as ktasks. This will last until smp_idle when
- * they clear it, either in anticipation of being a user-backing kthread or
- * to handle an RKM. */
+ /* Treat the startup threads as ktasks. This will last until smp_idle
+ * when they clear it, either in anticipation of being a user-backing
+ * kthread or to handle an RKM. */
kthread->flags = KTH_KTASK_FLAGS;
per_cpu_info[coreid].spare = 0;
/* Init relevant lists */
@@ -129,8 +131,9 @@
for (int i = 0; i < NR_CPU_STATES; i++)
pcpui->state_ticks[i] = 0;
pcpui->last_tick_cnt = read_tsc();
- /* Core 0 is in the KERNEL state, called from smp_boot. The other cores are
- * too, at least on x86, where we were called from asm (woken by POKE). */
+ /* Core 0 is in the KERNEL state, called from smp_boot. The other cores
+ * are too, at least on x86, where we were called from asm (woken by
+ * POKE). */
pcpui->cpu_state = CPU_STATE_KERNEL;
/* Enable full lock debugging, after all pcpui work is done */
pcpui->__lock_checking_enabled = 1;
@@ -144,14 +147,16 @@
void __set_cpu_state(struct per_cpu_info *pcpui, int state)
{
uint64_t now_ticks;
+
assert(!irq_is_enabled());
/* TODO: could put in an option to enable/disable state tracking. */
now_ticks = read_tsc();
- pcpui->state_ticks[pcpui->cpu_state] += now_ticks - pcpui->last_tick_cnt;
+ pcpui->state_ticks[pcpui->cpu_state] += now_ticks -
+ pcpui->last_tick_cnt;
/* TODO: if the state was user, we could account for the vcore's time,
- * similar to the total_ticks in struct vcore. the difference is that the
- * total_ticks tracks the vcore's virtual time, while this tracks user time.
- * something like vcore->user_ticks. */
+ * similar to the total_ticks in struct vcore. the difference is that
+ * the total_ticks tracks the vcore's virtual time, while this tracks
+ * user time. something like vcore->user_ticks. */
pcpui->cpu_state = state;
pcpui->last_tick_cnt = now_ticks;
}
@@ -160,10 +165,11 @@
{
struct per_cpu_info *pcpui = &per_cpu_info[coreid];
uint64_t now_ticks;
+
if (coreid >= num_cores)
return;
- /* need to update last_tick_cnt, so the current value doesn't get added in
- * next time we update */
+ /* need to update last_tick_cnt, so the current value doesn't get added
+ * in next time we update */
now_ticks = read_tsc();
for (int i = 0; i < NR_CPU_STATES; i++) {
pcpui->state_ticks[i] = 0;
@@ -212,6 +218,7 @@
{
struct pcpu_trace_event *te = (struct pcpu_trace_event*)event;
int desired_type = (int)(long)data;
+
if (te->type >= PCPUI_NR_TYPES)
printk("Bad trace type %d\n", te->type);
/* desired_type == 0 means all types */
@@ -271,8 +278,9 @@
if (i == cpu)
func(opaque);
else
- send_kernel_message(i, smp_do_core_work, (long) &acw, 0, 0,
- KMSG_ROUTINE);
+ send_kernel_message(i, smp_do_core_work,
+ (long)&acw, 0, 0,
+ KMSG_ROUTINE);
}
}
completion_wait(&acw.comp);
diff --git a/kern/src/string.c b/kern/src/string.c
index 30a6986..4b84f40 100644
--- a/kern/src/string.c
+++ b/kern/src/string.c
@@ -5,8 +5,7 @@
#include <ros/memlayout.h>
#include <assert.h>
-int
-strlen(const char *s)
+int strlen(const char *s)
{
int n;
@@ -15,8 +14,7 @@
return n;
}
-int
-strnlen(const char *s, size_t size)
+int strnlen(const char *s, size_t size)
{
int n;
@@ -45,8 +43,7 @@
}
*/
-char *
-strncpy(char *dst, const char *src, size_t size) {
+char *strncpy(char *dst, const char *src, size_t size) {
size_t i;
char *ret;
@@ -60,8 +57,7 @@
return ret;
}
-size_t
-strlcpy(char *dst, const char *src, size_t size)
+size_t strlcpy(char *dst, const char *src, size_t size)
{
if (size > 0) {
while (--size > 0 && *src != '\0')
@@ -72,8 +68,7 @@
return strlen(src);
}
-size_t
-strlcat(char *dst, const char *src, size_t size)
+size_t strlcat(char *dst, const char *src, size_t size)
{
size_t rem; /* Buffer space remaining after null in dst. */
@@ -98,16 +93,14 @@
return (size - rem) + strlcpy(dst, src, rem);
}
-int
-strcmp(const char *p, const char *q)
+int strcmp(const char *p, const char *q)
{
while (*p && *p == *q)
p++, q++;
return (int) ((unsigned char) *p - (unsigned char) *q);
}
-int
-strncmp(const char *p, const char *q, size_t n)
+int strncmp(const char *p, const char *q, size_t n)
{
while (n > 0 && *p && *p == *q)
n--, p++, q++;
@@ -119,8 +112,7 @@
// Return a pointer to the first occurrence of 'c' in 's',
// or a null pointer if the string has no 'c'.
-char *
-strchr(const char *s, char c)
+char *strchr(const char *s, char c)
{
for (; *s; s++)
if (*s == c)
@@ -130,8 +122,7 @@
// Return a pointer to the last occurrence of 'c' in 's',
// or a null pointer if the string has no 'c'.
-char *
-strrchr(const char *s, char c)
+char *strrchr(const char *s, char c)
{
char *lastc = NULL;
for (; *s; s++)
@@ -153,8 +144,7 @@
// Return a pointer to the first occurrence of 'c' in 's',
// or a pointer to the string-ending null character if the string has no 'c'.
-char *
-strfind(const char *s, char c)
+char *strfind(const char *s, char c)
{
for (; *s; s++)
if (*s == c)
@@ -163,8 +153,7 @@
}
// memset aligned words.
-static inline void *
-memsetw(long* _v, long c, size_t n)
+static inline void *memsetw(long* _v, long c, size_t n)
{
long *start, *end, *v;
@@ -219,8 +208,7 @@
*dst++ = *src++; \
} while(0)
-void *
-memset(void *v, int c, size_t _n)
+void *memset(void *v, int c, size_t _n)
{
char *p;
size_t n0;
@@ -230,22 +218,19 @@
p = v;
- while (n > 0 && ((uintptr_t)p & (sizeof(long)-1)))
- {
+ while (n > 0 && ((uintptr_t)p & (sizeof(long)-1))) {
*p++ = c;
n--;
}
- if (n >= sizeof(long))
- {
+ if (n >= sizeof(long)) {
n0 = n / sizeof(long) * sizeof(long);
memsetw((long*)p, c, n0);
n -= n0;
p += n0;
}
- while (n > 0)
- {
+ while (n > 0) {
*p++ = c;
n--;
}
@@ -253,8 +238,7 @@
return v;
}
-void *
-memcpy(void* dst, const void* src, size_t _n)
+void *memcpy(void* dst, const void* src, size_t _n)
{
const char* s;
char* d;
@@ -265,18 +249,13 @@
s = src;
d = dst;
- if ((((uintptr_t)s | (uintptr_t)d) & (sizeof(long)-1)) == 0)
- {
+ if ((((uintptr_t)s | (uintptr_t)d) & (sizeof(long)-1)) == 0) {
n0 = n / sizeof(long) * sizeof(long);
memcpyw(long, d, s, n0);
- }
- else if ((((uintptr_t)s | (uintptr_t)d) & (sizeof(int)-1)) == 0)
- {
+ } else if ((((uintptr_t)s | (uintptr_t)d) & (sizeof(int)-1)) == 0) {
n0 = n / sizeof(int) * sizeof(int);
memcpyw(int, d, s, n0);
- }
- else if ((((uintptr_t)s | (uintptr_t)d) & (sizeof(short)-1)) == 0)
- {
+ } else if ((((uintptr_t)s | (uintptr_t)d) & (sizeof(short)-1)) == 0) {
n0 = n / sizeof(short) * sizeof(short);
memcpyw(short, d, s, n0);
}
@@ -291,8 +270,7 @@
return dst;
}
-void *
-memmove(void *dst, const void *src, size_t _n)
+void *memmove(void *dst, const void *src, size_t _n)
{
#ifdef CONFIG_X86
bcopy(src, dst, _n);
@@ -317,8 +295,7 @@
#endif
}
-int
-memcmp(const void *v1, const void *v2, size_t n)
+int memcmp(const void *v1, const void *v2, size_t n)
{
const uint8_t *s1 = (const uint8_t *) v1;
const uint8_t *s2 = (const uint8_t *) v2;
@@ -332,8 +309,7 @@
return 0;
}
-void *
-memfind(const void *_s, int c, size_t n)
+void *memfind(const void *_s, int c, size_t n)
{
const void *ends = (const char *) _s + n;
const void *s = _s;
@@ -343,8 +319,7 @@
return (void *)s;
}
-long
-strtol(const char *s, char **endptr, int base)
+long strtol(const char *s, char **endptr, int base)
{
int neg = 0;
long val = 0;
@@ -390,8 +365,7 @@
return (neg ? -val : val);
}
-unsigned long
-strtoul(const char *s, char **endptr, int base)
+unsigned long strtoul(const char *s, char **endptr, int base)
{
int neg = 0;
unsigned long val = 0;
diff --git a/kern/src/syscall.c b/kern/src/syscall.c
index a596f75..9099d2c 100644
--- a/kern/src/syscall.c
+++ b/kern/src/syscall.c
@@ -51,13 +51,13 @@
struct timespec ts_start = tsc2timespec(trace->start_timestamp);
struct timespec ts_end = tsc2timespec(trace->end_timestamp);
- /* Slightly different formats between entry and exit. Entry has retval set
- * to ---, and begins with E. Exit begins with X. */
+ /* Slightly different formats between entry and exit. Entry has retval
+ * set to ---, and begins with E. Exit begins with X. */
if (entry) {
len = snprintf(trace->pretty_buf, SYSTR_PRETTY_BUF_SZ - len,
- "E [%7d.%09d]-[%7d.%09d] Syscall %3d (%12s):(0x%llx, 0x%llx, "
- "0x%llx, 0x%llx, 0x%llx, 0x%llx) ret: --- proc: %d core: %2d "
- "vcore: %2d errno: --- data: ",
+ "E [%7d.%09d]-[%7d.%09d] Syscall %3d (%12s):(0x%llx, "
+ "0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx) ret: --- "
+ "proc: %d core: %2d vcore: %2d errno: --- data: ",
ts_start.tv_sec,
ts_start.tv_nsec,
ts_end.tv_sec,
@@ -75,9 +75,9 @@
trace->vcoreid);
} else {
len = snprintf(trace->pretty_buf, SYSTR_PRETTY_BUF_SZ - len,
- "X [%7d.%09d]-[%7d.%09d] Syscall %3d (%12s):(0x%llx, 0x%llx, "
- "0x%llx, 0x%llx, 0x%llx, 0x%llx) ret: 0x%llx proc: %d core: %2d "
- "vcore: -- errno: %3d data: ",
+ "X [%7d.%09d]-[%7d.%09d] Syscall %3d (%12s):(0x%llx, "
+ "0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx) ret: 0x%llx "
+ "proc: %d core: %2d vcore: -- errno: %3d data: ",
ts_start.tv_sec,
ts_start.tv_nsec,
ts_end.tv_sec,
@@ -98,7 +98,8 @@
len += printdump(trace->pretty_buf + len, trace->datalen,
SYSTR_PRETTY_BUF_SZ - len - 1,
trace->data);
- len += snprintf(trace->pretty_buf + len, SYSTR_PRETTY_BUF_SZ - len, "\n");
+ len += snprintf(trace->pretty_buf + len, SYSTR_PRETTY_BUF_SZ - len,
+ "\n");
return len;
}
@@ -136,16 +137,17 @@
ERRSTACK(1);
size_t pretty_len;
- /* qio ops can throw, especially the blocking qwrite. I had it block on the
- * outbound path of sys_proc_destroy(). The rendez immediately throws. */
+ /* qio ops can throw, especially the blocking qwrite. I had it block on
+ * the outbound path of sys_proc_destroy(). The rendez immediately
+ * throws. */
if (waserror()) {
poperror();
return;
}
pretty_len = systrace_fill_pretty_buf(trace, entry);
if (strace) {
- /* At this point, we're going to emit the exit trace. It's just a
- * question of whether or not we block while doing it. */
+ /* At this point, we're going to emit the exit trace. It's just
+ * a question of whether or not we block while doing it. */
if (strace->drop_overflow || !sysc_can_block(trace->syscallno))
qiwrite(strace->q, trace->pretty_buf, pretty_len);
else
@@ -231,7 +233,8 @@
atomic_inc(&p->strace->nr_drops);
return;
}
- /* Avoiding the atomic op. We sacrifice accuracy for less overhead. */
+ /* Avoiding the atomic op. We sacrifice accuracy for less
+ * overhead. */
p->strace->appx_nr_sysc++;
} else {
if (!trace)
@@ -306,14 +309,17 @@
break;
case SYS_tap_fds:
for (size_t i = 0; i < (size_t)sysc->arg1; i++) {
- struct fd_tap_req *tap_reqs = (struct fd_tap_req*)sysc->arg0;
+ struct fd_tap_req *tap_reqs = (struct
+ fd_tap_req*)sysc->arg0;
int fd, cmd, filter;
tap_reqs += i;
copy_from_user(&fd, &tap_reqs->fd, sizeof(fd));
copy_from_user(&cmd, &tap_reqs->cmd, sizeof(cmd));
- copy_from_user(&filter, &tap_reqs->filter, sizeof(filter));
- snprintf_to_trace(trace, "%d (%d 0x%x), ", fd, cmd, filter);
+ copy_from_user(&filter, &tap_reqs->filter,
+ sizeof(filter));
+ snprintf_to_trace(trace, "%d (%d 0x%x), ", fd, cmd,
+ filter);
if (trace_data_full(trace))
break;
}
@@ -337,7 +343,8 @@
trace->end_timestamp = read_tsc();
trace->retval = retval;
trace->coreid = core_id();
- /* Can't trust the vcoreid of an exit record. This'll be ignored later. */
+ /* Can't trust the vcoreid of an exit record. This'll be ignored later.
+ */
trace->vcoreid = -1;
trace->errno = get_errno();
trace->datalen = 0;
@@ -360,7 +367,8 @@
case SYS_readlink:
if (retval <= 0)
break;
- copy_tracedata_from_user(trace, trace->arg0, trace->arg1);
+ copy_tracedata_from_user(trace, trace->arg0,
+ trace->arg1);
snprintf_to_trace(trace, " -> ");
copy_tracedata_from_user(trace, trace->arg2, retval);
break;
@@ -392,10 +400,11 @@
#define sysc_save_str(...) \
{ \
- struct per_cpu_info *pcpui = this_pcpui_ptr(); \
+ struct per_cpu_info *pcpui = this_pcpui_ptr(); \
\
- if (pcpui->cur_kthread->name) \
- snprintf(pcpui->cur_kthread->name, SYSCALL_STRLEN, __VA_ARGS__); \
+ if (pcpui->cur_kthread->name) \
+ snprintf(pcpui->cur_kthread->name, SYSCALL_STRLEN, \
+ __VA_ARGS__); \
}
#else
@@ -416,11 +425,11 @@
static void finish_sysc(struct syscall *sysc, struct proc *p, long retval)
{
sysc->retval = retval;
- /* Atomically turn on the LOCK and SC_DONE flag. The lock tells userspace
- * we're messing with the flags and to not proceed. We use it instead of
- * CASing with userspace. We need the atomics since we're racing with
- * userspace for the event_queue registration. The 'lock' tells userspace
- * to not muck with the flags while we're signalling. */
+ /* Atomically turn on the LOCK and SC_DONE flag. The lock tells
+ * userspace we're messing with the flags and to not proceed. We use it
+ * instead of CASing with userspace. We need the atomics since we're
+ * racing with userspace for the event_queue registration. The 'lock'
+ * tells userspace to not muck with the flags while we're signalling. */
atomic_or(&sysc->flags, SC_K_LOCK | SC_DONE);
__signal_syscall(sysc, p);
atomic_and(&sysc->flags, ~SC_K_LOCK);
@@ -556,6 +565,7 @@
static struct proc *get_controllable_proc(struct proc *p, pid_t pid)
{
struct proc *target = pid2proc(pid);
+
if (!target) {
set_error(ESRCH, "no proc for pid %d", pid);
return 0;
@@ -664,7 +674,8 @@
* overflow). */
if (waserror()) {
krem = tsc2timespec(read_tsc() - tsc);
- if (rem && memcpy_to_user(p, rem, &krem, sizeof(struct timespec)))
+ if (rem &&
+ memcpy_to_user(p, rem, &krem, sizeof(struct timespec)))
set_errno(EFAULT);
poperror();
return -1;
@@ -748,14 +759,14 @@
set_error(EINVAL, "Failed to copy in the args");
goto error_with_file;
}
- /* Unpack the argenv array into more usable variables. Integrity checking
- * done along side this as well. */
+ /* Unpack the argenv array into more usable variables. Integrity
+ * checking done along side this as well. */
if (unpack_argenv(kargenv, argenv_l, &argc, &argv, &envc, &envp)) {
set_error(EINVAL, "Failed to unpack the args");
goto error_with_kargenv;
}
- /* TODO: need to split the proc creation, since you must load after setting
- * args/env, since auxp gets set up there. */
+ /* TODO: need to split the proc creation, since you must load after
+ * setting args/env, since auxp gets set up there. */
//new_p = proc_create(program, 0, 0);
if (proc_alloc(&new_p, current, flags)) {
set_error(ENOMEM, "Failed to alloc new proc");
@@ -777,13 +788,14 @@
__proc_ready(new_p);
pid = new_p->pid;
profiler_notify_new_process(new_p);
- proc_decref(new_p); /* give up the reference created in proc_create() */
+ /* give up the reference created in proc_create() */
+ proc_decref(new_p);
return pid;
error_with_proc:
/* proc_destroy will decref once, which is for the ref created in
* proc_create(). We don't decref again (the usual "+1 for existing"),
- * since the scheduler, which usually handles that, hasn't heard about the
- * process (via __proc_ready()). */
+ * since the scheduler, which usually handles that, hasn't heard about
+ * the process (via __proc_ready()). */
proc_destroy(new_p);
error_with_kargenv:
user_memdup_free(p, kargenv);
@@ -794,11 +806,13 @@
return -1;
}
-/* Makes process PID runnable. Consider moving the functionality to process.c */
+/* Makes process PID runnable. Consider moving the functionality to process.c
+ */
static error_t sys_proc_run(struct proc *p, unsigned pid)
{
error_t retval = 0;
struct proc *target = get_controllable_proc(p, pid);
+
if (!target)
return -1;
if (target->state != PROC_CREATED) {
@@ -806,8 +820,8 @@
proc_decref(target);
return -1;
}
- /* Note a proc can spam this for someone it controls. Seems safe - if it
- * isn't we can change it. */
+ /* Note a proc can spam this for someone it controls. Seems safe - if
+ * it isn't we can change it. */
proc_wakeup(target);
proc_decref(target);
return 0;
@@ -825,9 +839,10 @@
return -1;
if (p_to_die == p) {
p->exitcode = exitcode;
- printd("[PID %d] proc exiting gracefully (code %d)\n", p->pid,exitcode);
+ printd("[PID %d] proc exiting gracefully (code %d)\n",
+ p->pid,exitcode);
} else {
- p_to_die->exitcode = exitcode; /* so its parent has some clue */
+ p_to_die->exitcode = exitcode;
printd("[%d] destroying proc %d\n", p->pid, p_to_die->pid);
}
proc_destroy(p_to_die);
@@ -837,8 +852,9 @@
static int sys_proc_yield(struct proc *p, bool being_nice)
{
- /* proc_yield() often doesn't return - we need to finish the syscall early.
- * If it doesn't return, it expects to eat our reference (for now). */
+ /* proc_yield() often doesn't return - we need to finish the syscall
+ * early. If it doesn't return, it expects to eat our reference (for
+ * now). */
finish_current_sysc(0);
proc_incref(p, 1);
proc_yield(p, being_nice);
@@ -852,7 +868,8 @@
bool enable_my_notif)
{
/* Note retvals can be negative, but we don't mess with errno in case
- * callers use this in low-level code and want to extract the 'errno'. */
+ * callers use this in low-level code and want to extract the 'errno'.
+ */
return proc_change_to_vcore(p, vcoreid, enable_my_notif);
}
@@ -867,6 +884,7 @@
return -1;
}
env_t* env;
+
ret = proc_alloc(&env, current, PROC_DUP_FGRP);
assert(!ret);
assert(env != NULL);
@@ -882,18 +900,19 @@
assert(current == this_pcpui_var(owning_proc));
copy_current_ctx_to(&env->scp_ctx);
- /* Make the new process have the same VMRs as the older. This will copy the
- * contents of non MAP_SHARED pages to the new VMRs. */
+ /* Make the new process have the same VMRs as the older. This will copy
+ * the contents of non MAP_SHARED pages to the new VMRs. */
if (duplicate_vmrs(e, env)) {
- proc_destroy(env); /* this is prob what you want, not decref by 2 */
+ proc_destroy(env);
proc_decref(env);
set_errno(ENOMEM);
return -1;
}
/* Switch to the new proc's address space and finish the syscall. We'll
- * never naturally finish this syscall for the new proc, since its memory
- * is cloned before we return for the original process. If we ever do CoW
- * for forked memory, this will be the first place that gets CoW'd. */
+ * never naturally finish this syscall for the new proc, since its
+ * memory is cloned before we return for the original process. If we
+ * ever do CoW for forked memory, this will be the first place that gets
+ * CoW'd. */
temp = switch_to(env);
finish_sysc(current_kthread->sysc, env, 0);
switch_back(env, temp);
@@ -903,8 +922,8 @@
inherit_strace(e, env);
- /* In general, a forked process should be a fresh process, and we copy over
- * whatever stuff is needed between procinfo/procdata. */
+ /* In general, a forked process should be a fresh process, and we copy
+ * over whatever stuff is needed between procinfo/procdata. */
*env->procdata = *e->procdata;
env->procinfo->program_end = e->procinfo->program_end;
@@ -914,13 +933,13 @@
// don't decref the new process.
// that will happen when the parent waits for it.
- // TODO: if the parent doesn't wait, we need to change the child's parent
- // when the parent dies, or at least decref it
+ // TODO: if the parent doesn't wait, we need to change the child's
+ // parent when the parent dies, or at least decref it
printd("[PID %d] fork PID %d\n", e->pid, env->pid);
ret = env->pid;
profiler_notify_new_process(env);
- proc_decref(env); /* give up the reference created in proc_alloc() */
+ proc_decref(env); /* give up the reference created in proc_alloc() */
return ret;
}
@@ -952,18 +971,20 @@
* arguments. Please, don't suggest a cpp macro. Thank you. */
/* Check the size of the argenv array, error out if too large. */
if ((argenv_l < sizeof(struct argenv)) || (argenv_l > ARG_MAX)) {
- s = seprintf(s, e, "The argenv array has an invalid size: %lu\n",
- argenv_l);
+ s = seprintf(s, e,
+ "The argenv array has an invalid size: %lu\n",
+ argenv_l);
return s - d;
}
/* Copy the argenv array into a kernel buffer. */
kargenv = user_memdup_errno(p, argenv, argenv_l);
if (!kargenv) {
- s = seprintf(s, e, "Failed to copy in the args and environment");
+ s = seprintf(s, e,
+ "Failed to copy in the args and environment");
return s - d;
}
- /* Unpack the argenv array into more usable variables. Integrity checking
- * done along side this as well. */
+ /* Unpack the argenv array into more usable variables. Integrity
+ * checking done along side this as well. */
if (unpack_argenv(kargenv, argenv_l, &argc, &argv, &envc, &envp)) {
s = seprintf(s, e, "Failed to unpack the args");
user_memdup_free(p, kargenv);
@@ -1014,31 +1035,32 @@
}
assert(current_ctx);
/* Before this, we shouldn't have blocked (maybe with strace, though we
- * explicitly don't block exec for strace). The owning proc, cur_proc, and
- * cur_ctx checks should catch that. After this, we might still block, such
- * as on accessing the filesystem.
+ * explicitly don't block exec for strace). The owning proc, cur_proc,
+ * and cur_ctx checks should catch that. After this, we might still
+ * block, such as on accessing the filesystem.
*
* After this point, we're treated like a yield - we're waiting until
- * something wakes us. The kthread might block, error and fail, or succeed.
- * We shouldn't return to userspace before one of those. The only way out
- * of this function is via smp_idle, not returning the way we came.
+ * something wakes us. The kthread might block, error and fail, or
+ * succeed. We shouldn't return to userspace before one of those. The
+ * only way out of this function is via smp_idle, not returning the way
+ * we came.
*
- * Under normal situations, the only thing that will wake us is this kthread
- * completing. I think you can trigger wakeups with events and async
- * syscalls started before the exec. I'm not sure if that could trigger
- * more bugs or if that would hurt the kernel. If so, we could add an
- * EXEC_LIMBO state.
+ * Under normal situations, the only thing that will wake us is this
+ * kthread completing. I think you can trigger wakeups with events and
+ * async syscalls started before the exec. I'm not sure if that could
+ * trigger more bugs or if that would hurt the kernel. If so, we could
+ * add an EXEC_LIMBO state.
*
- * Note that we will 'hard block' if we block at all. We can't return to
- * userspace and then asynchronously finish the exec later. */
+ * Note that we will 'hard block' if we block at all. We can't return
+ * to userspace and then asynchronously finish the exec later. */
spin_lock(&p->proc_lock);
/* We only need the context for the error case. We have to save it now,
- * since once we leave this core, such as when the kthread blocks, the old
- * SCP's context will be gone. */
+ * since once we leave this core, such as when the kthread blocks, the
+ * old SCP's context will be gone. */
__proc_save_context_s(p);
/* We are no longer owning, but we are still current, like any
- * kthread-that-blocked-on-behalf of a process. I think one invariant for
- * SCPs is: "RUNNING_S <==> is the owning proc". */
+ * kthread-that-blocked-on-behalf of a process. I think one invariant
+ * for SCPs is: "RUNNING_S <==> is the owning proc". */
clear_owning_proc(core_id());
__proc_set_state(p, PROC_WAITING);
spin_unlock(&p->proc_lock);
@@ -1049,8 +1071,8 @@
set_error(EINVAL, "Failed to copy in the args and environment");
goto out_error;
}
- /* Unpack the argenv array into more usable variables. Integrity checking
- * done along side this as well. */
+ /* Unpack the argenv array into more usable variables. Integrity
+ * checking done along side this as well. */
if (unpack_argenv(kargenv, argenv_l, &argc, &argv, &envc, &envp)) {
set_error(EINVAL, "Failed to unpack the args");
goto out_error_kargenv;
@@ -1068,8 +1090,8 @@
goto out_error_program;
}
- /* This is the point of no return for the process. Any errors here lead to
- * destruction. */
+ /* This is the point of no return for the process. Any errors here lead
+ * to destruction. */
/* progname is argv0, which accounts for symlinks */
proc_replace_binary_path(p, t_path);
@@ -1086,16 +1108,19 @@
env_user_mem_free(p, 0, UMAPTOP);
if (load_elf(p, program, argc, argv, envc, envp)) {
set_error(EINVAL, "Failed to load elf");
- /* At this point, we destroyed memory and can't return to the app. We
- * can't use the error cases, since they assume we'll return. */
+ /* At this point, we destroyed memory and can't return to the
+ * app. We can't use the error cases, since they assume we'll
+ * return. */
foc_decref(program);
user_memdup_free(p, kargenv);
- /* We finish the trace and not the sysc, since the sysc is gone. */
+ /* We finish the trace and not the sysc, since the sysc is gone.
+ */
systrace_finish_trace(current_kthread, -1);
- /* Note this is an inedible reference, but proc_destroy now returns */
+ /* Note this is an inedible reference, but proc_destroy now
+ * returns */
proc_destroy(p);
- /* We don't want to do anything else - we just need to not accidentally
- * return to the user (hence the all_out) */
+ /* We don't want to do anything else - we just need to not
+ * accidentally return to the user (hence the all_out) */
goto all_out;
}
printd("[PID %d] exec %s\n", p->pid, foc_to_name(program));
@@ -1119,16 +1144,16 @@
proc_wakeup(p);
all_out:
- /* This free and setting sysc = NULL may happen twice (early errors do it),
- * but they are idempotent. */
+ /* This free and setting sysc = NULL may happen twice (early errors do
+ * it), but they are idempotent. */
free_sysc_str(current_kthread);
current_kthread->sysc = NULL;
/* we can't return, since we'd write retvals to the old location of the
- * syscall struct (which has been freed and is in the old userspace) (or has
- * already been written to).*/
- disable_irq(); /* abandon_core/clear_own wants irqs disabled */
+ * syscall struct (which has been freed and is in the old userspace) (or
+ * has already been written to).*/
+ disable_irq(); /* abandon_core/clear_own wants irqs disabled */
abandon_core();
- smp_idle(); /* will reenable interrupts */
+ smp_idle(); /* will reenable interrupts */
}
/* Helper, will attempt a particular wait on a proc. Returns the pid of the
@@ -1141,19 +1166,21 @@
int *ret_status, int options)
{
if (proc_is_dying(child)) {
- /* Disown returns -1 if it's already been disowned or we should o/w
- * abort. This can happen if we have concurrent waiters, both with
- * pointers to the child (only one should reap). Note that if we don't
- * do this, we could go to sleep and never receive a cv_signal. */
+ /* Disown returns -1 if it's already been disowned or we should
+ * o/w abort. This can happen if we have concurrent waiters,
+ * both with pointers to the child (only one should reap). Note
+ * that if we don't do this, we could go to sleep and never
+ * receive a cv_signal. */
if (__proc_disown_child(parent, child))
return -1;
- /* despite disowning, the child won't be freed til we drop this ref
- * held by this function, so it is safe to access the memory.
+ /* despite disowning, the child won't be freed til we drop this
+ * ref held by this function, so it is safe to access the
+ * memory.
*
- * Note the exit code one byte in the 0xff00 spot. Check out glibc's
- * posix/sys/wait.h and bits/waitstatus.h for more info. If we ever
- * deal with signalling and stopping, we'll need to do some more work
- * here.*/
+ * Note the exit code one byte in the 0xff00 spot. Check out
+ * glibc's posix/sys/wait.h and bits/waitstatus.h for more info.
+ * If we ever deal with signalling and stopping, we'll need to
+ * do some more work here.*/
*ret_status = (child->exitcode & 0xff) << 8;
return child->pid;
}
@@ -1173,11 +1200,13 @@
if (TAILQ_EMPTY(&parent->children))
return -1;
- /* Could have concurrent waiters mucking with the tailq, caller must lock */
+ /* Could have concurrent waiters mucking with the tailq, caller must
+ * lock */
TAILQ_FOREACH_SAFE(i, &parent->children, sibling_link, temp) {
retval = __try_wait(parent, i, ret_status, options);
- /* This catches a thread causing a wait to fail but not taking the
- * child off the list before unlocking. Should never happen. */
+ /* This catches a thread causing a wait to fail but not taking
+ * the child off the list before unlocking. Should never
+ * happen. */
assert(retval != -1);
/* Succeeded, return the pid of the child we waited on */
if (retval) {
@@ -1205,13 +1234,13 @@
while (!retval) {
cpu_relax();
cv_wait(&parent->child_wait);
- /* If we're dying, then we don't need to worry about waiting. We don't
- * do this yet, but we'll need this outlet when we deal with orphaned
- * children and having init inherit them. */
+ /* If we're dying, then we don't need to worry about waiting.
+ * We don't do this yet, but we'll need this outlet when we deal
+ * with orphaned children and having init inherit them. */
if (proc_is_dying(parent))
goto out_unlock;
- /* Any child can wake us up, but we check for the particular child we
- * care about */
+ /* Any child can wake us up, but we check for the particular
+ * child we care about */
retval = __try_wait(parent, child, ret_status, options);
}
if (retval == -1) {
@@ -1244,8 +1273,9 @@
cv_wait(&parent->child_wait);
if (proc_is_dying(parent))
goto out_unlock;
- /* Any child can wake us up from the CV. This is a linear __try_wait
- * scan. If we have a lot of children, we could optimize this. */
+ /* Any child can wake us up from the CV. This is a linear
+ * __try_wait scan. If we have a lot of children, we could
+ * optimize this. */
retval = __try_wait_any(parent, ret_status, options, &child);
}
if (retval == -1)
@@ -1342,15 +1372,15 @@
long res_val)
{
switch (res_type) {
- case (RES_CORES):
- /* in the off chance we have a kernel scheduler that can't
- * provision, we'll need to change this. */
- return provision_core(target, res_val);
- default:
- printk("[kernel] received provisioning for unknown resource %d\n",
- res_type);
- set_errno(ENOENT); /* or EINVAL? */
- return -1;
+ case (RES_CORES):
+ /* in the off chance we have a kernel scheduler that can't
+ * provision, we'll need to change this. */
+ return provision_core(target, res_val);
+ default:
+ printk("[kernel] got provisioning for unknown resource %d\n",
+ res_type);
+ set_errno(ENOENT); /* or EINVAL? */
+ return -1;
}
}
@@ -1360,6 +1390,7 @@
{
struct proc *target = pid2proc(target_pid);
int retval;
+
if (!target) {
if (target_pid == 0)
return prov_resource(0, res_type, res_val);
@@ -1381,11 +1412,13 @@
{
struct event_msg local_msg = {0};
struct proc *target = get_controllable_proc(p, target_pid);
+
if (!target)
return -1;
/* if the user provided an ev_msg, copy it in and use that */
if (u_msg) {
- if (memcpy_from_user(p, &local_msg, u_msg, sizeof(struct event_msg))) {
+ if (memcpy_from_user(p, &local_msg, u_msg,
+ sizeof(struct event_msg))) {
proc_decref(target);
set_errno(EINVAL);
return -1;
@@ -1406,9 +1439,11 @@
bool priv)
{
struct event_msg local_msg = {0};
+
/* if the user provided an ev_msg, copy it in and use that */
if (u_msg) {
- if (memcpy_from_user(p, &local_msg, u_msg, sizeof(struct event_msg))) {
+ if (memcpy_from_user(p, &local_msg, u_msg,
+ sizeof(struct event_msg))) {
set_errno(EINVAL);
return -1;
}
@@ -1416,13 +1451,15 @@
local_msg.ev_type = ev_type;
}
if (local_msg.ev_type >= MAX_NR_EVENT) {
- printk("[kernel] received self-notify for vcoreid %d, ev_type %d, "
- "u_msg %p, u_msg->type %d\n", vcoreid, ev_type, u_msg,
- u_msg ? u_msg->ev_type : 0);
+ printk("[kernel] received self-notify for vcoreid %d, "
+ "ev_type %d, u_msg %p, u_msg->type %d\n", vcoreid,
+ ev_type, u_msg, u_msg ? u_msg->ev_type : 0);
return -1;
}
- /* this will post a message and IPI, regardless of wants/needs/debutantes.*/
- post_vcore_event(p, &local_msg, vcoreid, priv ? EVENT_VCORE_PRIVATE : 0);
+ /* this will post a message and IPI, regardless of
+ * wants/needs/debutantes.*/
+ post_vcore_event(p, &local_msg, vcoreid,
+ priv ? EVENT_VCORE_PRIVATE : 0);
proc_notify(p, vcoreid);
return 0;
}
@@ -1496,12 +1533,13 @@
return 0;
}
vcpd = &p->procdata->vcore_preempt_data[pcpui->owning_vcoreid];
- /* We pretend to not be in vcore context so other cores will send us IPIs
- * (__notify). If we do get a __notify, we'll have set notif_disabled back
- * on before we handle the message, since it's a routine KMSG. Note that
- * other vcores will think we are not in vcore context. This is no
- * different to when we pop contexts: 'briefly' leave VC ctx, check
- * notif_pending, and (possibly) abort and set notif_disabled. */
+ /* We pretend to not be in vcore context so other cores will send us
+ * IPIs (__notify). If we do get a __notify, we'll have set
+ * notif_disabled back on before we handle the message, since it's a
+ * routine KMSG. Note that other vcores will think we are not in vcore
+ * context. This is no different to when we pop contexts: 'briefly'
+ * leave VC ctx, check notif_pending, and (possibly) abort and set
+ * notif_disabled. */
vcpd->notif_disabled = false;
cpu_halt_notif_pending(vcpd);
__set_cpu_state(pcpui, CPU_STATE_KERNEL);
@@ -1517,6 +1555,7 @@
static int sys_change_to_m(struct proc *p)
{
int retval = proc_change_to_m(p);
+
/* convert the kernel error code into (-1, errno) */
if (retval) {
set_errno(-retval);
@@ -1542,21 +1581,23 @@
int vcoreid = pcpui->owning_vcoreid;
struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[vcoreid];
- /* With change_to, there's a bunch of concerns about changing the vcore map,
- * since the kernel may have already locked and sent preempts, deaths, etc.
+ /* With change_to, there's a bunch of concerns about changing the vcore
+ * map, since the kernel may have already locked and sent preempts,
+ * deaths, etc.
*
* In this case, we don't care as much. Other than notif_pending and
* notif_disabled, it's more like we're just changing a few registers in
- * cur_ctx. We can safely order-after any kernel messages or other changes,
- * as if the user had done all of the changes we'll make and then did a
- * no-op syscall.
+ * cur_ctx. We can safely order-after any kernel messages or other
+ * changes, as if the user had done all of the changes we'll make and
+ * then did a no-op syscall.
*
* Since we are mucking with current_ctx, it is important that we don't
* block before or during this syscall. */
arch_finalize_ctx(pcpui->cur_ctx);
if (copy_from_user(pcpui->cur_ctx, ctx, sizeof(struct user_context))) {
- /* The 2LS isn't really in a position to handle errors. At the very
- * least, we can print something and give them a fresh vc ctx. */
+ /* The 2LS isn't really in a position to handle errors. At the
+ * very least, we can print something and give them a fresh vc
+ * ctx. */
printk("[kernel] unable to copy user_ctx, 2LS bug\n");
memset(pcpui->cur_ctx, 0, sizeof(struct user_context));
proc_init_ctx(pcpui->cur_ctx, vcoreid, vcpd->vcore_entry,
@@ -1564,12 +1605,13 @@
return -1;
}
proc_secure_ctx(pcpui->cur_ctx);
- /* The caller leaves vcore context no matter what. We'll put them back in
- * if they missed a message. */
+ /* The caller leaves vcore context no matter what. We'll put them back
+ * in if they missed a message. */
vcpd->notif_disabled = FALSE;
wrmb(); /* order disabled write before pending read */
if (vcpd->notif_pending)
- send_kernel_message(pcoreid, __notify, (long)p, 0, 0, KMSG_ROUTINE);
+ send_kernel_message(pcoreid, __notify, (long)p, 0, 0,
+ KMSG_ROUTINE);
return 0;
}
@@ -1641,7 +1683,8 @@
break;
case VMM_CTL_SET_FLAGS:
if (arg1 & ~VMM_CTL_ALL_FLAGS)
- error(EINVAL, "Bad vmm_ctl flags. Got 0x%lx, allowed 0x%lx\n",
+ error(EINVAL,
+ "Bad vmm_ctl flags. Got 0x%lx, allowed 0x%lx\n",
arg1, VMM_CTL_ALL_FLAGS);
vmm->flags = arg1;
ret = 0;
@@ -1666,6 +1709,7 @@
{
struct proc *target;
int retval = 0;
+
if (!target_pid) {
poke_ksched(p, res_type);
return 0;
@@ -1693,8 +1737,8 @@
static int sys_abort_sysc_fd(struct proc *p, int fd)
{
- /* Consider checking for a bad fd. Doesn't matter now, since we only look
- * for actual syscalls blocked that had used fd. */
+ /* Consider checking for a bad fd. Doesn't matter now, since we only
+ * look for actual syscalls blocked that had used fd. */
return abort_all_sysc_fd(p, fd);
}
@@ -1736,7 +1780,8 @@
printd("File %s Open attempt oflag %x mode %x\n", path, oflag, mode);
if ((oflag & O_PATH) && (oflag & O_ACCMODE)) {
- set_error(EINVAL, "Cannot open O_PATH with any I/O perms (O%o)", oflag);
+ set_error(EINVAL, "Cannot open O_PATH with any I/O perms (O%o)",
+ oflag);
return -1;
}
t_path = copy_in_path(p, path, path_l);
@@ -1783,7 +1828,8 @@
kfree(kbuf);
return -1;
}
- /* TODO: UMEM: pin the memory, copy directly, and skip the kernel buffer */
+ /* TODO: UMEM: pin the memory, copy directly, and skip the kernel buffer
+ */
if (memcpy_to_user_errno(p, u_stat, kbuf, sizeof(struct kstat))) {
kfree(kbuf);
return -1;
@@ -1813,7 +1859,8 @@
retval = sysstatakaros(t_path, (struct kstat *)kbuf, flags);
if (retval < 0)
goto out_with_kbuf;
- /* TODO: UMEM: pin the memory, copy directly, and skip the kernel buffer */
+ /* TODO: UMEM: pin the memory, copy directly, and skip the kernel buffer
+ */
if (memcpy_to_user_errno(p, u_stat, kbuf, sizeof(struct kstat)))
retval = -1;
/* Fall-through */
@@ -1881,7 +1928,8 @@
dir = sysdirstat(t_path);
if (!dir)
goto out;
- if ((mode == F_OK) || caller_has_dir_perms(dir, access_bits_to_omode(mode)))
+ if ((mode == F_OK) ||
+ caller_has_dir_perms(dir, access_bits_to_omode(mode)))
retval = 0;
kfree(dir);
out:
@@ -1924,9 +1972,11 @@
{
int ret;
char *t_oldpath = copy_in_path(p, old_path, old_l);
+
if (t_oldpath == NULL)
return -1;
char *t_newpath = copy_in_path(p, new_path, new_l);
+
if (t_newpath == NULL) {
free_path(p, t_oldpath);
return -1;
@@ -1955,9 +2005,11 @@
{
int ret;
char *t_oldpath = copy_in_path(p, old_path, old_l);
+
if (t_oldpath == NULL)
return -1;
char *t_newpath = copy_in_path(p, new_path, new_l);
+
if (t_newpath == NULL) {
free_path(p, t_oldpath);
return -1;
@@ -2100,6 +2152,7 @@
/* TODO: actually support this call on tty FDs. Right now, we just fake
* what my linux box reports for a bash pty. */
struct termios *kbuf = kmalloc(sizeof(struct termios), 0);
+
kbuf->c_iflag = 0x2d02;
kbuf->c_oflag = 0x0005;
kbuf->c_cflag = 0x04bf;
@@ -2181,14 +2234,17 @@
{
int ret;
char *t_srcpath = copy_in_path(p, src_path, src_l);
+
if (t_srcpath == NULL) {
printd("srcpath dup failed ptr %p size %d\n", src_path, src_l);
return -1;
}
char *t_ontopath = copy_in_path(p, onto_path, onto_l);
+
if (t_ontopath == NULL) {
free_path(p, t_srcpath);
- printd("ontopath dup failed ptr %p size %d\n", onto_path, onto_l);
+ printd("ontopath dup failed ptr %p size %d\n", onto_path,
+ onto_l);
return -1;
}
printd("sys_nbind: %s -> %s flag %d\n", t_srcpath, t_ontopath, flag);
@@ -2213,6 +2269,7 @@
afd = -1;
char *t_ontopath = copy_in_path(p, onto_path, onto_l);
+
if (t_ontopath == NULL)
return -1;
ret = sysmount(fd, afd, t_ontopath, flag, /* spec or auth */"/");
@@ -2233,6 +2290,7 @@
{
int ret;
char *t_ontopath, *t_srcpath;
+
t_ontopath = copy_in_path(p, onto_path, onto_l);
if (t_ontopath == NULL)
return -1;
@@ -2355,13 +2413,13 @@
static int handle_tap_req(struct proc *p, struct fd_tap_req *req)
{
switch (req->cmd) {
- case (FDTAP_CMD_ADD):
- return add_fd_tap(p, req);
- case (FDTAP_CMD_REM):
- return remove_fd_tap(p, req->fd);
- default:
- set_error(ENOSYS, "FD Tap Command %d not supported", req->cmd);
- return -1;
+ case (FDTAP_CMD_ADD):
+ return add_fd_tap(p, req);
+ case (FDTAP_CMD_REM):
+ return remove_fd_tap(p, req->fd);
+ default:
+ set_error(ENOSYS, "FD Tap Command %d not supported", req->cmd);
+ return -1;
}
}
@@ -2480,8 +2538,10 @@
ERRSTACK(1);
if (sc_num > max_syscall || syscall_table[sc_num].call == NULL) {
- printk("[kernel] Invalid syscall %d for proc %d\n", sc_num, p->pid);
- printk("\tArgs: %p, %p, %p, %p, %p, %p\n", a0, a1, a2, a3, a4, a5);
+ printk("[kernel] Invalid syscall %d for proc %d\n", sc_num,
+ p->pid);
+ printk("\tArgs: %p, %p, %p, %p, %p, %p\n", a0, a1, a2, a3, a4,
+ a5);
print_user_ctx(this_pcpui_var(cur_ctx));
return -1;
}
@@ -2500,7 +2560,8 @@
ret = syscall_table[sc_num].call(p, a0, a1, a2, a3, a4, a5);
//printd("after syscall errstack base %p\n", get_cur_errbuf());
if (get_cur_errbuf() != &errstack[0]) {
- /* Can't trust coreid and vcoreid anymore, need to check the trace */
+ /* Can't trust coreid and vcoreid anymore, need to check the
+ * trace */
printk("[%16llu] Syscall %3d (%12s):(%p, %p, %p, %p, "
"%p, %p) proc: %d\n", read_tsc(),
sc_num, syscall_table[sc_num].name, a0, a1, a2, a3,
@@ -2518,20 +2579,21 @@
struct proc *p = pcpui->cur_proc;
long retval;
- /* In lieu of pinning, we just check the sysc and will PF on the user addr
- * later (if the addr was unmapped). Which is the plan for all UMEM. */
+ /* In lieu of pinning, we just check the sysc and will PF on the user
+ * addr later (if the addr was unmapped). Which is the plan for all
+ * UMEM. */
if (!is_user_rwaddr(sysc, sizeof(struct syscall))) {
- printk("[kernel] bad user addr %p (+%p) in %s (user bug)\n", sysc,
- sizeof(struct syscall), __FUNCTION__);
+ printk("[kernel] bad user addr %p (+%p) in %s (user bug)\n",
+ sysc, sizeof(struct syscall), __FUNCTION__);
return;
}
- pcpui->cur_kthread->sysc = sysc; /* let the core know which sysc it is */
+ pcpui->cur_kthread->sysc = sysc;/* let the core know which sysc it is */
unset_errno();
systrace_start_trace(pcpui->cur_kthread, sysc);
pcpui = this_pcpui_ptr(); /* reload again */
alloc_sysc_str(pcpui->cur_kthread);
- /* syscall() does not return for exec and yield, so put any cleanup in there
- * too. */
+ /* syscall() does not return for exec and yield, so put any cleanup in
+ * there too. */
retval = syscall(pcpui->cur_proc, sysc->num, sysc->arg0, sysc->arg1,
sysc->arg2, sysc->arg3, sysc->arg4, sysc->arg5);
finish_current_sysc(retval);
@@ -2550,8 +2612,8 @@
/* For all after the first call, send ourselves a KMSG (TODO). */
if (nr_syscs != 1)
warn("Only one supported (Debutante calls: %d)\n", nr_syscs);
- /* Call the first one directly. (we already checked to make sure there is
- * 1) */
+ /* Call the first one directly. (we already checked to make sure there
+ * is 1) */
run_local_syscall(sysc);
}
@@ -2564,7 +2626,9 @@
{
struct event_queue *ev_q;
struct event_msg local_msg;
- /* User sets the ev_q then atomically sets the flag (races with SC_DONE) */
+
+ /* User sets the ev_q then atomically sets the flag (races with SC_DONE)
+ */
if (atomic_read(&sysc->flags) & SC_UEVENT) {
rmb(); /* read the ev_q after reading the flag */
ev_q = sysc->ev_q;
@@ -2585,30 +2649,31 @@
bool syscall_uses_fd(struct syscall *sysc, int fd)
{
switch (sysc->num) {
- case (SYS_read):
- case (SYS_write):
- case (SYS_close):
- case (SYS_fstat):
- case (SYS_fcntl):
- case (SYS_llseek):
- case (SYS_nmount):
- case (SYS_fd2path):
- if (sysc->arg0 == fd)
- return TRUE;
- return FALSE;
- case (SYS_mmap):
- /* mmap always has to be special. =) */
- if (sysc->arg4 == fd)
- return TRUE;
- return FALSE;
- default:
- return FALSE;
+ case (SYS_read):
+ case (SYS_write):
+ case (SYS_close):
+ case (SYS_fstat):
+ case (SYS_fcntl):
+ case (SYS_llseek):
+ case (SYS_nmount):
+ case (SYS_fd2path):
+ if (sysc->arg0 == fd)
+ return TRUE;
+ return FALSE;
+ case (SYS_mmap):
+ /* mmap always has to be special. =) */
+ if (sysc->arg4 == fd)
+ return TRUE;
+ return FALSE;
+ default:
+ return FALSE;
}
}
void print_sysc(struct proc *p, struct syscall *sysc)
{
uintptr_t old_p = switch_to(p);
+
printk("SYS_%d, flags %p, a0 %p, a1 %p, a2 %p, a3 %p, a4 %p, a5 %p\n",
sysc->num, atomic_read(&sysc->flags),
sysc->arg0, sysc->arg1, sysc->arg2, sysc->arg3, sysc->arg4,
diff --git a/kern/src/taskqueue.c b/kern/src/taskqueue.c
index 0588afa..05bfd91 100644
--- a/kern/src/taskqueue.c
+++ b/kern/src/taskqueue.c
@@ -51,14 +51,15 @@
static void send_work(int coreid, struct work_struct *work)
{
- send_kernel_message(coreid, __wq_wrapper, (long)work, 0, 0, KMSG_ROUTINE);
+ send_kernel_message(coreid, __wq_wrapper, (long)work, 0, 0,
+ KMSG_ROUTINE);
}
static void send_work_delay(int coreid, struct delayed_work *work,
unsigned long delay)
{
- send_kernel_message(coreid, __wq_wrapper_delay, (long)work, (long)delay, 0,
- KMSG_ROUTINE);
+ send_kernel_message(coreid, __wq_wrapper_delay, (long)work, (long)delay,
+ 0, KMSG_ROUTINE);
}
bool queue_work(struct workqueue_struct *wq, struct work_struct *work)
diff --git a/kern/src/time.c b/kern/src/time.c
index 2515803..6dfb2b4 100644
--- a/kern/src/time.c
+++ b/kern/src/time.c
@@ -19,11 +19,11 @@
uint64_t time, diff;
int8_t irq_state = 0;
- /* Reset this, in case we run it again. The use of start/stop to determine
- * the overhead relies on timing_overhead being 0. */
+ /* Reset this, in case we run it again. The use of start/stop to
+ * determine the overhead relies on timing_overhead being 0. */
__proc_global_info.tsc_overhead = 0;
- /* timing might use cpuid, in which case we warm it up to avoid some extra
- * variance */
+ /* timing might use cpuid, in which case we warm it up to avoid some
+ * extra variance */
time = start_timing();
diff = stop_timing(time);
time = start_timing();
@@ -39,8 +39,8 @@
}
enable_irqsave(&irq_state);
__proc_global_info.tsc_overhead = min_overhead;
- printk("TSC overhead (Min: %llu, Max: %llu)\n", min_overhead, max_overhead);
-}
+ printk("TSC overhead (Min: %llu, Max: %llu)\n", min_overhead,
+ max_overhead); }
/* Convenience wrapper called when a core's timer interrupt goes off. Not to be
* confused with global timers (like the PIC). Do not put your code here. If
diff --git a/kern/src/trap.c b/kern/src/trap.c
index ea474b3..7c01660 100644
--- a/kern/src/trap.c
+++ b/kern/src/trap.c
@@ -27,7 +27,8 @@
if (!proc_is_vcctx_ready(p))
printk("Unhandled user trap from early SCP\n");
else if (vcpd->notif_disabled)
- printk("Unhandled user trap in vcore context from VC %d\n", vcoreid);
+ printk("Unhandled user trap in vcore context from VC %d\n",
+ vcoreid);
print_user_ctx(ctx);
printk("err 0x%x (for PFs: User 4, Wr 2, Rd 1), aux %p\n", err, aux);
debug_addr_proc(p, get_user_ctx_pc(ctx));
@@ -83,11 +84,11 @@
assert(p);
assert(pcpui->cur_ctx && (pcpui->cur_ctx->type == ROS_HW_CTX));
- /* need to store trap_nr, err code, and aux into the tf so that it can get
- * extracted on the other end, and we need to flag the TF in some way so we
- * can tell it was reflected. for example, on a PF, we need some number (14
- * on x86), the prot violation (write, read, etc), and the virt addr (aux).
- * parlib will know how to extract this info. */
+ /* need to store trap_nr, err code, and aux into the tf so that it can
+ * get extracted on the other end, and we need to flag the TF in some
+ * way so we can tell it was reflected. for example, on a PF, we need
+ * some number (14 on x86), the prot violation (write, read, etc), and
+ * the virt addr (aux). parlib will know how to extract this info. */
__arch_reflect_trap_hwtf(&pcpui->cur_ctx->tf.hw_tf, trap_nr, err, aux);
printx_unhandled_trap(p, pcpui->cur_ctx, trap_nr, err, aux);
if (reflect_current_context()) {
@@ -101,8 +102,8 @@
{
struct user_context *cur_ctx = current_ctx;
- /* Be sure to finalize into cur_ctx, not the to_ctx. o/w the arch could get
- * confused by other calls to finalize. */
+ /* Be sure to finalize into cur_ctx, not the to_ctx. o/w the arch could
+ * get confused by other calls to finalize. */
arch_finalize_ctx(cur_ctx);
*to_ctx = *cur_ctx;
}
@@ -130,22 +131,23 @@
k_msg->arg1 = arg1;
k_msg->arg2 = arg2;
switch (type) {
- case KMSG_IMMEDIATE:
- spin_lock_irqsave(&per_cpu_info[dst].immed_amsg_lock);
- STAILQ_INSERT_TAIL(&per_cpu_info[dst].immed_amsgs, k_msg, link);
- spin_unlock_irqsave(&per_cpu_info[dst].immed_amsg_lock);
- break;
- case KMSG_ROUTINE:
- spin_lock_irqsave(&per_cpu_info[dst].routine_amsg_lock);
- STAILQ_INSERT_TAIL(&per_cpu_info[dst].routine_amsgs, k_msg, link);
- spin_unlock_irqsave(&per_cpu_info[dst].routine_amsg_lock);
- break;
- default:
- panic("Unknown type of kernel message!");
+ case KMSG_IMMEDIATE:
+ spin_lock_irqsave(&per_cpu_info[dst].immed_amsg_lock);
+ STAILQ_INSERT_TAIL(&per_cpu_info[dst].immed_amsgs, k_msg, link);
+ spin_unlock_irqsave(&per_cpu_info[dst].immed_amsg_lock);
+ break;
+ case KMSG_ROUTINE:
+ spin_lock_irqsave(&per_cpu_info[dst].routine_amsg_lock);
+ STAILQ_INSERT_TAIL(&per_cpu_info[dst].routine_amsgs, k_msg, link);
+ spin_unlock_irqsave(&per_cpu_info[dst].routine_amsg_lock);
+ break;
+ default:
+ panic("Unknown type of kernel message!");
}
- /* since we touched memory the other core will touch (the lock), we don't
- * need an wmb_f() */
- /* if we're sending a routine message locally, we don't want/need an IPI */
+ /* since we touched memory the other core will touch (the lock), we
+ * don't need an wmb_f() */
+ /* if we're sending a routine message locally, we don't want/need an IPI
+ */
if ((dst != k_msg->srcid) || (type == KMSG_IMMEDIATE))
send_ipi(dst, I_KERNEL_MSG);
return 0;
@@ -167,12 +169,14 @@
/* Avoid locking if the list appears empty (lockless peek is okay) */
if (STAILQ_EMPTY(&pcpui->immed_amsgs))
return;
- /* The lock serves as a cmb to force a re-read of the head of the list */
+ /* The lock serves as a cmb to force a re-read of the head of the list*/
spin_lock_irqsave(&pcpui->immed_amsg_lock);
STAILQ_FOREACH_SAFE(kmsg_i, &pcpui->immed_amsgs, link, temp) {
pcpui_trace_kmsg(pcpui, (uintptr_t)kmsg_i->pc);
- kmsg_i->pc(kmsg_i->srcid, kmsg_i->arg0, kmsg_i->arg1, kmsg_i->arg2);
- STAILQ_REMOVE(&pcpui->immed_amsgs, kmsg_i, kernel_message, link);
+ kmsg_i->pc(kmsg_i->srcid, kmsg_i->arg0, kmsg_i->arg1,
+ kmsg_i->arg2);
+ STAILQ_REMOVE(&pcpui->immed_amsgs, kmsg_i, kernel_message,
+ link);
kmem_cache_free(kernel_msg_cache, (void*)kmsg_i);
}
spin_unlock_irqsave(&pcpui->immed_amsg_lock);
@@ -190,6 +194,7 @@
static kernel_message_t *get_next_rkmsg(struct per_cpu_info *pcpui)
{
struct kernel_message *kmsg;
+
/* Avoid locking if the list appears empty (lockless peek is okay) */
if (STAILQ_EMPTY(&pcpui->routine_amsgs))
return 0;
@@ -214,9 +219,10 @@
struct per_cpu_info *pcpui = &per_cpu_info[pcoreid];
struct kernel_message msg_cp, *kmsg;
- /* Important that callers have IRQs disabled when checking for RKMs. When
- * sending cross-core RKMs, the IPI is used to keep the core from going to
- * sleep - even though RKMs aren't handled in the kmsg handler. */
+ /* Important that callers have IRQs disabled when checking for RKMs.
+ * When sending cross-core RKMs, the IPI is used to keep the core from
+ * going to sleep - even though RKMs aren't handled in the kmsg handler.
+ * */
assert(!irq_is_enabled());
kmsg = get_next_rkmsg(pcpui);
if (!kmsg)
@@ -224,11 +230,12 @@
msg_cp = *kmsg;
kmem_cache_free(kernel_msg_cache, kmsg);
assert(msg_cp.dstid == pcoreid);
- /* The kmsg could block. If it does, we want the kthread code to know it's
- * not running on behalf of a process, and we're actually spawning a kernel
- * task. While we do have a syscall that does work in an RKM (change_to),
- * it's not really the rest of the syscall context. When we return or
- * otherwise call smp_idle, smp_idle will reset these flags. */
+ /* The kmsg could block. If it does, we want the kthread code to know
+ * it's not running on behalf of a process, and we're actually spawning
+ * a kernel task. While we do have a syscall that does work in an RKM
+ * (change_to), it's not really the rest of the syscall context. When
+ * we return or otherwise call smp_idle, smp_idle will reset these
+ * flags. */
pcpui->cur_kthread->flags = KTH_KTASK_FLAGS;
pcpui_trace_kmsg(pcpui, (uintptr_t)msg_cp.pc);
msg_cp.pc(msg_cp.srcid, msg_cp.arg0, msg_cp.arg1, msg_cp.arg2);
@@ -245,8 +252,8 @@
struct kernel_message *kmsg_i;
STAILQ_FOREACH(kmsg_i, list, link) {
- printk("%s KMSG on %d from %d to run %p(%s)(%p, %p, %p)\n", type,
- kmsg_i->dstid, kmsg_i->srcid, kmsg_i->pc,
+ printk("%s KMSG on %d from %d to run %p(%s)(%p, %p, %p)\n",
+ type, kmsg_i->dstid, kmsg_i->srcid, kmsg_i->pc,
get_fn_name((long)kmsg_i->pc),
kmsg_i->arg0, kmsg_i->arg1, kmsg_i->arg2);
}
@@ -265,6 +272,7 @@
{
struct kernel_message *kmsg;
bool immed_emp, routine_emp;
+
for (int i = 0; i < num_cores; i++) {
spin_lock_irqsave(&per_cpu_info[i].immed_amsg_lock);
immed_emp = STAILQ_EMPTY(&per_cpu_info[i].immed_amsgs);
@@ -272,8 +280,8 @@
spin_lock_irqsave(&per_cpu_info[i].routine_amsg_lock);
routine_emp = STAILQ_EMPTY(&per_cpu_info[i].routine_amsgs);
spin_unlock_irqsave(&per_cpu_info[i].routine_amsg_lock);
- printk("Core %d's immed_emp: %d, routine_emp %d\n", i, immed_emp,
- routine_emp);
+ printk("Core %d's immed_emp: %d, routine_emp %d\n", i,
+ immed_emp, routine_emp);
if (!immed_emp) {
kmsg = STAILQ_FIRST(&per_cpu_info[i].immed_amsgs);
printk("Immed msg on core %d:\n", i);
@@ -305,8 +313,8 @@
if (!str)
str = "(none)";
- printk("%s: Core %d, irq depth %d, ktrap depth %d, irqon %d\n", str, coreid,
- irq_depth(pcpui), ktrap_depth(pcpui), irq_is_enabled());
+ printk("%s: Core %d, irq depth %d, ktrap depth %d, irqon %d\n", str,
+ coreid, irq_depth(pcpui), ktrap_depth(pcpui), irq_is_enabled());
}
void print_user_ctx(struct user_context *ctx)
diff --git a/kern/src/ucq.c b/kern/src/ucq.c
index fc456f4..354a558 100644
--- a/kern/src/ucq.c
+++ b/kern/src/ucq.c
@@ -22,7 +22,8 @@
/* So we can try to send ucqs to _Ss before they initialize */
if (!ucq->ucq_ready) {
if (__proc_is_mcp(p))
- warn("proc %d is _M with an uninitialized ucq %p\n", p->pid, ucq);
+ warn("proc %d is _M with an uninitialized ucq %p\n",
+ p->pid, ucq);
return;
}
/* Bypass fetching/incrementing the counter if we're overflowing, helps
@@ -37,10 +38,10 @@
ucq->prod_overflow = TRUE;
/* Sanity check */
if (PGOFF(my_slot) > 3000)
- warn("Abnormally high counter, there's probably something wrong!");
+ warn("Abnormally high counter, something is wrong!");
grab_lock:
- /* Lock, for this proc/ucq. Using an irqsave, since we may want to send ucq
- * messages from irq context. */
+ /* Lock, for this proc/ucq. Using an irqsave, since we may want to send
+ * ucq messages from irq context. */
hash_lock_irqsave(p->ucq_hashlock, (long)ucq);
/* Grab a potential slot (again, preventing another DoS) */
my_slot = (uintptr_t)atomic_fetch_and_add(&ucq->prod_idx, 1);
@@ -51,8 +52,8 @@
* user-malfeasance or neglect.
*
* The is_user_rwaddr() check on old_page might catch addresses below
- * MMAP_LOWEST_VA, and we can also handle a PF, but we'll explicitly check
- * for 0 just to be sure (and it's a likely error). */
+ * MMAP_LOWEST_VA, and we can also handle a PF, but we'll explicitly
+ * check for 0 just to be sure (and it's a likely error). */
old_page = (struct ucq_page*)PTE_ADDR(my_slot);
if (!is_user_rwaddr(old_page, PGSIZE) || !old_page)
goto error_addr_unlock;
@@ -61,20 +62,24 @@
new_page = (struct ucq_page*)atomic_swap(&ucq->spare_pg, 0);
if (!new_page) {
/* Warn if we have a ridiculous amount of pages in the ucq */
- if (atomic_fetch_and_add(&ucq->nr_extra_pgs, 1) > UCQ_WARN_THRESH)
- warn("Over %d pages in ucq %p for pid %d!\n", UCQ_WARN_THRESH,
- ucq, p->pid);
- /* Giant warning: don't ask for anything other than anonymous memory at
- * a non-fixed location. o/w, it may cause a TLB shootdown, which grabs
- * the proc_lock, and potentially deadlock the system. */
+ if (atomic_fetch_and_add(&ucq->nr_extra_pgs, 1) >
+ UCQ_WARN_THRESH)
+ warn("Over %d pages in ucq %p for pid %d!\n",
+ UCQ_WARN_THRESH, ucq, p->pid);
+ /* Giant warning: don't ask for anything other than anonymous
+ * memory at a non-fixed location. o/w, it may cause a TLB
+ * shootdown, which grabs the proc_lock, and potentially
+ * deadlock the system. */
new_page = (struct ucq_page*)do_mmap(p, 0, PGSIZE,
PROT_READ | PROT_WRITE,
- MAP_ANONYMOUS | MAP_POPULATE |
- MAP_PRIVATE, NULL, 0);
+ MAP_ANONYMOUS |
+ MAP_POPULATE | MAP_PRIVATE,
+ NULL, 0);
assert(new_page);
assert(!PGOFF(new_page));
} else {
- /* If we're using the user-supplied new_page, we need to check it */
+ /* If we're using the user-supplied new_page, we need to check
+ * it */
if (!is_user_rwaddr(new_page, PGSIZE) || PGOFF(new_page))
goto error_addr_unlock;
}
@@ -91,9 +96,9 @@
unlock_lock:
/* Clear the overflow, so new producers will try to get a slot */
ucq->prod_overflow = FALSE;
- /* At this point, any normal (non-locking) producers can succeed in getting
- * a slot. The ones that failed earlier will fight for the lock, then
- * quickly proceed when they get a good slot */
+ /* At this point, any normal (non-locking) producers can succeed in
+ * getting a slot. The ones that failed earlier will fight for the
+ * lock, then quickly proceed when they get a good slot */
hash_unlock_irqsave(p->ucq_hashlock, (long)ucq);
/* Fall through to having a slot */
have_slot:
@@ -108,8 +113,8 @@
/* Finally write the message */
my_msg->ev_msg = *msg;
wmb();
- /* Now that the write is done, signal to the consumer that they can consume
- * our message (they could have been spinning on it) */
+ /* Now that the write is done, signal to the consumer that they can
+ * consume our message (they could have been spinning on it) */
my_msg->ready = TRUE;
return;
error_addr_unlock:
@@ -120,11 +125,10 @@
/* Fall-through to normal error out */
error_addr:
warn("Invalid user address, not sending a message");
- /* TODO: consider killing the process here. For now, just catch it. For
- * some cases, we have a slot that we never fill in, though if we had a bad
- * addr, none of this will work out and the kernel just needs to protect
- * itself. */
- return;
+ /* TODO: consider killing the process here. For now, just catch it.
+ * For some cases, we have a slot that we never fill in, though if we
+ * had a bad addr, none of this will work out and the kernel just needs
+ * to protect itself. */
}
/* Debugging */
@@ -149,13 +153,15 @@
/* only attempt to print messages on the same page */
if (PTE_ADDR(i) != PTE_ADDR(atomic_read(&ucq->prod_idx)))
break;
- printk("Prod idx %p message ready is %p\n", i, slot2msg(i)->ready);
+ printk("Prod idx %p message ready is %p\n", i,
+ slot2msg(i)->ready);
}
/* look at the chain, starting from cons_idx */
ucq_pg = (struct ucq_page*)PTE_ADDR(atomic_read(&ucq->cons_idx));
for (int i = 0; i < 10 && ucq_pg; i++) {
printk("#%02d: Cons page: %p, nr_cons: %d, next page: %p\n", i,
- ucq_pg, ucq_pg->header.nr_cons, ucq_pg->header.cons_next_pg);
+ ucq_pg, ucq_pg->header.nr_cons,
+ ucq_pg->header.cons_next_pg);
ucq_pg = (struct ucq_page*)(ucq_pg->header.cons_next_pg);
}
switch_back(p, old_proc);
diff --git a/kern/src/umem.c b/kern/src/umem.c
index fea17ad..5863ffe 100644
--- a/kern/src/umem.c
+++ b/kern/src/umem.c
@@ -147,6 +147,7 @@
void *user_memdup(struct proc *p, const void *va, int len)
{
void* kva = NULL;
+
if (len < 0 || (kva = kmalloc(len, 0)) == NULL)
return ERR_PTR(-ENOMEM);
if (memcpy_from_user(p, kva, va, len)) {
@@ -159,6 +160,7 @@
void *user_memdup_errno(struct proc *p, const void *va, int len)
{
void *kva = user_memdup(p, va, len);
+
if (IS_ERR(kva)) {
set_errno(-PTR_ERR(kva));
return NULL;
@@ -179,6 +181,7 @@
char *user_strdup(struct proc *p, const char *u_string, size_t strlen)
{
char *k_string = user_memdup(p, u_string, strlen + 1);
+
if (!IS_ERR(k_string))
k_string[strlen] = '\0';
return k_string;
@@ -198,6 +201,7 @@
void *kmalloc_errno(int len)
{
void *kva = NULL;
+
if (len < 0 || (kva = kmalloc(len, 0)) == NULL)
set_errno(ENOMEM);
return kva;
@@ -210,6 +214,7 @@
{
struct page *u_page;
assert(kva); /* catch bugs */
+
/* Check offsets first */
if (PGOFF(uva) != PGOFF(kva))
return FALSE;
@@ -227,6 +232,7 @@
{
struct page *u_page;
uintptr_t offset = PGOFF(uva);
+
if (!p)
return 0;
if (prot & PROT_WRITE) {
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index ba26859..8a08894 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -11,7 +11,7 @@
# Copyright (c) 2015 Google Inc
# Barret Rhoden <brho@cs.berkeley.edu>
#
-# - Added a tab_length parameter, set it to 4
+# - Added a tab_length parameter, set it to 8
# - Set tree = 0, since we do not have a Linux kernel tree
# - No KERN_ checks for printk
# - ENOSYS can be used in more places
@@ -79,7 +79,7 @@
my $typedefsfile = "";
my $color = "auto";
my $allow_c99_comments = 1;
-my $tab_length = 4;
+my $tab_length = 8;
sub help {
my ($exitcode) = @_;
@@ -3434,28 +3434,28 @@
# Checks which may be anchored in the context.
#
-## Check for switch () and associated case and default
-## statements should be at the same indent.
-# if ($line=~/\bswitch\s*\(.*\)/) {
-# my $err = '';
-# my $sep = '';
-# my @ctx = ctx_block_outer($linenr, $realcnt);
-# shift(@ctx);
-# for my $ctx (@ctx) {
-# my ($clen, $cindent) = line_stats($ctx);
-# if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
-# $indent != $cindent) {
-# $err .= "$sep$ctx\n";
-# $sep = '';
-# } else {
-# $sep = "[...]\n";
-# }
-# }
-# if ($err ne '') {
-# ERROR("SWITCH_CASE_INDENT_LEVEL",
-# "switch and case should be at the same indent\n$hereline$err");
-# }
-# }
+# Check for switch () and associated case and default
+# statements should be at the same indent.
+ if ($line=~/\bswitch\s*\(.*\)/) {
+ my $err = '';
+ my $sep = '';
+ my @ctx = ctx_block_outer($linenr, $realcnt);
+ shift(@ctx);
+ for my $ctx (@ctx) {
+ my ($clen, $cindent) = line_stats($ctx);
+ if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
+ $indent != $cindent) {
+ $err .= "$sep$ctx\n";
+ $sep = '';
+ } else {
+ $sep = "[...]\n";
+ }
+ }
+ if ($err ne '') {
+ ERROR("SWITCH_CASE_INDENT_LEVEL",
+ "switch and case should be at the same indent\n$hereline$err");
+ }
+ }
# if/while/etc brace do not go on next line, unless defining a do while loop,
# or if that brace on the next line is for something else
diff --git a/scripts/lindent b/scripts/lindent
index 560f600..641d1ae 100755
--- a/scripts/lindent
+++ b/scripts/lindent
@@ -1,5 +1,5 @@
#!/bin/sh
-PARAM="-npro -kr -i4 -ts4 -sob -l80 -ss -ncs -cp1 -cli4 -c0"
+PARAM="-npro -kr -i8 -ts8 -sob -l80 -ss -ncs -cp1 -cli0 -c0 -linux"
RES=`indent --version`
V1=`echo $RES | cut -d' ' -f3 | cut -d'.' -f1`
V2=`echo $RES | cut -d' ' -f3 | cut -d'.' -f2`
diff --git a/scripts/parse_errno.sh b/scripts/parse_errno.sh
index 1fe3b46..4c26b91 100755
--- a/scripts/parse_errno.sh
+++ b/scripts/parse_errno.sh
@@ -6,7 +6,7 @@
# #define ENOENT 2 /* No such file or directory */
# #define ESRCH 3 /* No such process */
# #define EINTR 4 /* Interrupted system call */
-# #define EIO 5 /* I/O error */
+# #define EIO 5 /* I/O error */
#
# And output them as:
#
diff --git a/tests/alarm.c b/tests/alarm.c
index 62b1d4d..f6f8586 100644
--- a/tests/alarm.c
+++ b/tests/alarm.c
@@ -39,8 +39,8 @@
perror("Alarm setup");
exit(-1);
}
- /* Since we're doing SPAM_PUBLIC later, we actually don't need a big ev_q.
- * But someone might copy/paste this and change a flag. */
+ /* Since we're doing SPAM_PUBLIC later, we actually don't need a big
+ * ev_q. But someone might copy/paste this and change a flag. */
register_ev_handler(EV_ALARM, handle_alarm, 0);
if (!(ev_q = get_eventq(EV_MBOX_UCQ))) {
perror("Failed ev_q"); /* it'll actually PF if malloc fails */
@@ -48,8 +48,8 @@
}
ev_q->ev_vcore = 0;
/* I think this is all the flags we need; gotta write that dissertation
- * chapter (and event how-to)! We may get more than one event per alarm, if
- * we have concurrent preempts/yields. */
+ * chapter (and event how-to)! We may get more than one event per
+ * alarm, if we have concurrent preempts/yields. */
ev_q->ev_flags = EVENT_IPI | EVENT_SPAM_PUBLIC | EVENT_WAKEUP;
/* Register the ev_q for our alarm */
if (devalarm_set_evq(timerfd, ev_q, 0xdeadbeef)) {
@@ -74,8 +74,8 @@
}
uthread_sleep(2);
close(ctlfd);
- /* get crazy: post the timerfd to #srv, then sleep (or even try to exit), and
- * then echo into it remotely! A few limitations:
+ /* get crazy: post the timerfd to #srv, then sleep (or even try to
+ * exit), and then echo into it remotely! A few limitations:
* - if the process is DYING, you won't be able to send an event to it.
* - the process won't leave DYING til the srv file is removed. */
srvfd = open("#srv/alarmtest", O_WRONLY | O_CREAT | O_EXCL, 0666);
@@ -89,7 +89,7 @@
perror("Failed to post timerfd");
exit(-1);
}
- printf("Sleeping for 10 sec, try to echo 111 > '#srv/alarmtest' now!\n");
+ printf("Sleeping for 10 sec, try to echo 111 > '#srv/alarmtest' now\n");
uthread_sleep(10);
ret = unlink("#srv/alarmtest");
if (ret < 0) {
diff --git a/tests/bind.c b/tests/bind.c
index 25e8eb1..944b89d 100644
--- a/tests/bind.c
+++ b/tests/bind.c
@@ -13,7 +13,7 @@
#include <ros/syscall.h>
/* The naming for the args in bind is messy historically. We do:
- * bind src_path onto_path
+ * bind src_path onto_path
* plan9 says bind NEW OLD, where new is *src*, and old is *onto*.
* Linux says mount --bind OLD NEW, where OLD is *src* and NEW is *onto*. */
int main(int argc, char *argv[])
diff --git a/tests/block_test.c b/tests/block_test.c
index b25dd16..180be3f 100644
--- a/tests/block_test.c
+++ b/tests/block_test.c
@@ -23,7 +23,8 @@
{
assert(!in_vcore_context());
for (int i = 0; i < NUM_TEST_LOOPS; i++) {
- printf_safe("[A] pthread %d on vcore %d\n", pthread_self()->id, vcore_id());
+ printf_safe("[A] pthread %d on vcore %d\n", pthread_self()->id,
+ vcore_id());
sys_block(5000 + pthread_self()->id);
}
return (void*)(long)pthread_self()->id;
@@ -32,6 +33,7 @@
int main(int argc, char** argv)
{
struct timeval tv = {0};
+
if (gettimeofday(&tv, 0))
perror("Time error...");
printf("Start time: %dsec %dusec\n", tv.tv_sec, tv.tv_usec);
@@ -42,8 +44,8 @@
for (int i = 0; i < NUM_TEST_THREADS; i++) {
printf_safe("[A] About to join on thread %d\n", i);
pthread_join(my_threads[i], &my_retvals[i]);
- printf_safe("[A] Successfully joined on thread %d (retval: %p)\n", i,
- my_retvals[i]);
+ printf_safe("[A] Successful join on thread %d (retval: %p)\n",
+ i, my_retvals[i]);
}
if (gettimeofday(&tv, 0))
perror("Time error...");
diff --git a/tests/childfdmap.c b/tests/childfdmap.c
index 98092af..33d0c60 100644
--- a/tests/childfdmap.c
+++ b/tests/childfdmap.c
@@ -46,9 +46,9 @@
}
printd("pipe [%d, %d]\n", talk[0], talk[1]);
- /* parent will read and write on talk[0], and the child does the same for
- * talk[1]. internally, writing to talk 0 gets read on talk 1. the child
- * gets talk1 mapped for both stdin (fd 0) and stdout (fd 1). */
+ /* parent will read and write on talk[0], and the child does the same
+ * for talk[1]. internally, writing to talk 0 gets read on talk 1. the
+ * child gets talk1 mapped for both stdin (fd 0) and stdout (fd 1). */
childfdmap[0].parentfd = talk[1];
childfdmap[0].childfd = 0;
childfdmap[1].parentfd = talk[1];
@@ -56,7 +56,7 @@
sprintf(filename, "/bin/%s", argv[0]);
child_argv[0] = filename;
- child_argv[1] = "1"; /* dummy arg, signal so we know they're the child */
+ child_argv[1] = "1"; /* dummy arg, signal so we know they're the child*/
child_argv[2] = 0;
kid = sys_proc_create(filename, strlen(filename), child_argv, NULL, 0);
@@ -71,9 +71,9 @@
exit(2);
}
- /* close the pipe endpoint that we duped in the child. it doesn't matter
- * for this test, but after the child exits, the pipe will still be open
- * unless we close our side of it. */
+ /* close the pipe endpoint that we duped in the child. it doesn't
+ * matter for this test, but after the child exits, the pipe will still
+ * be open unless we close our side of it. */
close(talk[1]);
sys_proc_run(kid);
diff --git a/tests/cs.c b/tests/cs.c
index 50252ef..f5724b5 100644
--- a/tests/cs.c
+++ b/tests/cs.c
@@ -202,7 +202,8 @@
static void usage(void)
{
- fprintf(stderr, "CS:usage: %s [-dn] [-f ndb-file] [-x netmtpt]\n", argv0);
+ fprintf(stderr, "CS:usage: %s [-dn] [-f ndb-file] [-x netmtpt]\n",
+ argv0);
fprintf(stderr, "CS:usage");
evexit(1);
}
@@ -498,9 +499,8 @@
pthread_attr_t pth_attr;
/*
- * each request is handled via a thread. Somewhat less efficient than the
- * old
- * cs but way cleaner.
+ * each request is handled via a thread. Somewhat less efficient than
+ * the old cs but way cleaner.
*/
pthread_attr_init(&pth_attr);
@@ -513,9 +513,10 @@
if (convM2S(mdata, n, &job->request) != n) {
fprintf(stderr,
"convM2S went south: format error %ux %ux %ux %ux %ux",
- mdata[0], mdata[1], mdata[2], mdata[3], mdata[4]);
- error(1, 0, "format error %ux %ux %ux %ux %ux", mdata[0], mdata[1],
- mdata[2], mdata[3], mdata[4]);
+ mdata[0], mdata[1], mdata[2], mdata[3],
+ mdata[4]);
+ error(1, 0, "format error %ux %ux %ux %ux %ux",
+ mdata[0], mdata[1], mdata[2], mdata[3], mdata[4]);
freejob(job);
continue;
}
@@ -609,7 +610,8 @@
err = "not a directory";
break;
}
- if (strcmp(elems[i], "..") == 0 || strcmp(elems[i], ".") == 0) {
+ if (strcmp(elems[i], "..") == 0
+ || strcmp(elems[i], ".") == 0) {
qid.type = QTDIR;
qid.path = Qdir;
Found:
@@ -832,7 +834,8 @@
if (debug)
fprintf(stderr, "CS:write %s", job->request.data);
if (paranoia)
- fprintf(stderr, "CS:write %s by %s", job->request.data, mf->user);
+ fprintf(stderr, "CS:write %s by %s", job->request.data,
+ mf->user);
/*
* break up name
@@ -926,7 +929,8 @@
job->reply.tag = job->request.tag;
n = convS2M(&job->reply, mdata, sizeof(mdata));
if (n == 1) {
- fprintf(stderr, "CS:sendmsg convS2M of %F returns 0", &job->reply);
+ fprintf(stderr, "CS:sendmsg convS2M of %F returns 0",
+ &job->reply);
abort();
}
spinlock_lock(&joblock);
@@ -993,7 +997,8 @@
*/
if (mysysname == 0 && netdb != NULL) {
ndbreopen(netdb);
- for (tt = t = ndbparse(netdb); t != NULL; t = t->entry) {
+ for (tt = t = ndbparse(netdb); t != NULL; t = t->entry)
+ {
if (strcmp(t->attr, "sys") == 0) {
mysysname = strdup(t->val);
break;
@@ -1002,19 +1007,24 @@
ndbfree(tt);
}
- /* next network database, ip address, and ether address to find a name
+ /* next network database, ip address, and ether address to find
+ * a name
*/
if (mysysname == 0) {
t = NULL;
if (isvalidip(ipa))
- free(ndbgetvalue(db, &s, "ip", ipaddr, "sys", &t));
+ free(ndbgetvalue(db, &s, "ip", ipaddr, "sys",
+ &t));
if (t == NULL) {
for (f = 0; f < 3; f++) {
- snprintf(buf, sizeof(buf), "%s/ether%d", mntpt, f);
+ snprintf(buf, sizeof(buf), "%s/ether%d",
+ mntpt, f);
if (myetheraddr(addr, buf) < 0)
continue;
- snprintf(eaddr, sizeof(eaddr), "%E", addr);
- free(ndbgetvalue(db, &s, "ether", eaddr, "sys", &t));
+ snprintf(eaddr, sizeof(eaddr), "%E",
+ addr);
+ free(ndbgetvalue(db, &s, "ether", eaddr,
+ "sys", &t));
if (t != NULL)
break;
}
@@ -1083,7 +1093,8 @@
ipid();
if (debug)
- fprintf(stderr, logfile, "CS:mysysname %s eaddr %s ipaddr %s ipa %I\n",
+ fprintf(stderr, logfile,
+ "CS:mysysname %s eaddr %s ipaddr %s ipa %I\n",
mysysname ? mysysname : "???", eaddr, ipaddr, ipa);
}
@@ -1154,9 +1165,11 @@
nt = (*np->lookup)(np, mf->host, mf->serv, 1);
if (nt == NULL)
continue;
- hack = np->fasttimeouthack && !lookforproto(nt, np->net);
+ hack = np->fasttimeouthack && !lookforproto(nt,
+ np->net);
for (t = nt; mf->nreply < Nreply && t; t = t->entry) {
- cp = (*np->trans)(t, np, mf->serv, mf->rem, hack);
+ cp = (*np->trans)(t, np, mf->serv, mf->rem,
+ hack);
if (!cp)
continue;
/* avoid duplicates */
@@ -1213,8 +1226,8 @@
* not a known network, don't translate host or service
*/
if (mf->serv)
- snprintf(reply, sizeof(reply), "%s/%s/clone %s!%s", mntpt, mf->net,
- mf->host, mf->serv);
+ snprintf(reply, sizeof(reply), "%s/%s/clone %s!%s", mntpt,
+ mf->net, mf->host, mf->serv);
else
snprintf(reply, sizeof(reply), "%s/%s/clone %s", mntpt, mf->net,
mf->host);
@@ -1446,11 +1459,11 @@
*x = 0;
if (*t->val == '*')
- snprintf(reply, sizeof(reply), "%s/%s/clone %s%s", mntpt, np->net, ts,
- x);
+ snprintf(reply, sizeof(reply), "%s/%s/clone %s%s", mntpt,
+ np->net, ts, x);
else
- snprintf(reply, sizeof(reply), "%s/%s/clone %s!%s%s%s", mntpt, np->net,
- t->val, ts, x, hack ? "!fasttimeout" : "");
+ snprintf(reply, sizeof(reply), "%s/%s/clone %s!%s%s%s", mntpt,
+ np->net, t->val, ts, x, hack ? "!fasttimeout" : "");
return strdup(reply);
}
@@ -1489,11 +1502,11 @@
else
*x = 0;
if (serv)
- snprintf(reply, sizeof(reply), "%s/%s/clone %s!%s%s", mntpt, np->net,
- t->val, serv, x);
+ snprintf(reply, sizeof(reply), "%s/%s/clone %s!%s%s", mntpt,
+ np->net, t->val, serv, x);
else
- snprintf(reply, sizeof(reply), "%s/%s/clone %s%s", mntpt, np->net,
- t->val, x);
+ snprintf(reply, sizeof(reply), "%s/%s/clone %s%s", mntpt,
+ np->net, t->val, x);
return strdup(reply);
}
@@ -1591,7 +1604,8 @@
found = 0;
for (nt = t; nt; nt = nt->entry)
if (strcmp(attr[i], nt->attr) == 0)
- if (strcmp(val[i], "*") == 0 || strcmp(val[i], nt->val) == 0) {
+ if (strcmp(val[i], "*") == 0 ||
+ strcmp(val[i], nt->val) == 0) {
found = 1;
break;
}
@@ -1685,7 +1699,8 @@
}
/* give dns a chance */
- if ((strcmp(attr[0], "dom") == 0 || strcmp(attr[0], "ip") == 0) && val[0]) {
+ if ((strcmp(attr[0], "dom") == 0 || strcmp(attr[0], "ip") == 0)
+ && val[0]) {
t = dnsiplookup(val[0], &s);
if (t) {
if (qmatch(t, attr, val, n)) {
diff --git a/tests/csquery.c b/tests/csquery.c
index 9f1a944..1c536d3 100644
--- a/tests/csquery.c
+++ b/tests/csquery.c
@@ -40,9 +40,12 @@
error(1, 0, "cannot open %s: %r", server);
amt = write(fd, addr, strlen(addr));
if (amt != strlen(addr)) {
- printf("CSQUERY:Tried to write %d to fd %d, only wrote %d\n", strlen(addr),fd,amt);
+ printf("CSQUERY:Tried to write %d to fd %d, only wrote %d\n",
+ strlen(addr), fd, amt);
if (!statusonly)
- fprintf(stderr, "CSQUERY:Writing request: translating %s: %r\n", addr);
+ fprintf(stderr,
+ "CSQUERY:Writing request: translating %s: %r\n",
+ addr);
status = "errors";
close(fd);
return;
diff --git a/tests/daemonize.c b/tests/daemonize.c
index 3ff9b77..960f31c 100644
--- a/tests/daemonize.c
+++ b/tests/daemonize.c
@@ -28,7 +28,8 @@
register_ev_handler(EV_USER_IPI, ev_handler, 0);
evq = get_eventq(EV_MBOX_UCQ);
- evq->ev_flags = EVENT_IPI | EVENT_INDIR | EVENT_SPAM_INDIR | EVENT_WAKEUP;
+ evq->ev_flags = EVENT_IPI | EVENT_INDIR | EVENT_SPAM_INDIR |
+ EVENT_WAKEUP;
register_kevent_q(evq, EV_USER_IPI);
pid = create_child_with_stdfds(argv[1], argc - 1, argv + 1, envp);
diff --git a/tests/draw_nanwan.c b/tests/draw_nanwan.c
index 16f6663..4a8690f 100644
--- a/tests/draw_nanwan.c
+++ b/tests/draw_nanwan.c
@@ -3,8 +3,8 @@
int main(int argc, char** argv)
{
/* Borrowed with love from http://www.geocities.com/SoHo/7373/zoo.htm
- * (http://www.ascii-art.com/). Slightly modified to make it 25 lines tall.
- */
+ * (http://www.ascii-art.com/). Slightly modified to make it 25 lines
+ * tall. */
printf("\n");
printf(" .-. .-.\n");
printf(" | \\/ |\n");
diff --git a/tests/dune/dune.c b/tests/dune/dune.c
index 94e0f90..3e7a78b 100644
--- a/tests/dune/dune.c
+++ b/tests/dune/dune.c
@@ -147,8 +147,7 @@
{0, 0, 0, 0}
};
-static void
-usage(void)
+static void usage(void)
{
// Sadly, the getopt_long struct does
// not have a pointer to help text.
@@ -167,8 +166,7 @@
exit(0);
}
-static struct elf_aux *
-getextra(int *auxc, char *_s)
+static struct elf_aux *getextra(int *auxc, char *_s)
{
struct elf_aux *auxv;
char *s = strdup(_s);
@@ -200,15 +198,15 @@
auxv[i].v[0] = t;
auxv[i].v[1] = v;
if (dune_debug)
- fprintf(stderr, "Adding aux pair 0x%x:0x%x\n", auxv[i].v[0],
- auxv[i].v[1]);
+ fprintf(stderr, "Adding aux pair 0x%x:0x%x\n",
+ auxv[i].v[0], auxv[i].v[1]);
}
return auxv;
}
-static struct elf_aux *
-buildaux(struct elf_aux *base, int basec, struct elf_aux *extra, int extrac)
+static struct elf_aux *buildaux(struct elf_aux *base, int basec,
+ struct elf_aux *extra, int extrac)
{
int total = basec + extrac;
struct elf_aux *ret;
@@ -301,7 +299,8 @@
mmap_memory(&vm, memstart, memsize);
if (dune_debug)
- fprintf(stderr, "mmap guest physical memory at %p for 0x%lx bytes\n",
+ fprintf(stderr,
+ "mmap guest physical memory at %p for 0x%lx bytes\n",
memstart, memsize);
// TODO: find out why we can't use memstart + memsize as TOS.
@@ -333,7 +332,8 @@
fprintf(stderr, "Test: Populate stack at %p\n", tos);
tos = populate_stack(tos, ac, av, envc, environ, auxc, auxv);
if (dune_debug)
- fprintf(stderr, "populated stack at %p; argc %d, envc %d, auxc %d\n",
+ fprintf(stderr,
+ "populated stack at %p; argc %d, envc %d, auxc %d\n",
tos, ac, envc, auxc);
if (dune_debug)
diff --git a/tests/epoll_server.c b/tests/epoll_server.c
index b3b71e9..c1059f1 100644
--- a/tests/epoll_server.c
+++ b/tests/epoll_server.c
@@ -46,18 +46,18 @@
char adir[40], ldir[40];
int n;
char buf[256];
- /* We'll use this to see if we actually did epoll_waits instead of blocking
- * calls. It's not 100%, but with a human on the other end, it should be
- * fine. */
+ /* We'll use this to see if we actually did epoll_waits instead of
+ * blocking calls. It's not 100%, but with a human on the other end, it
+ * should be fine. */
bool has_epolled = FALSE;
#ifdef PLAN9NET
printf("Using Plan 9's networking stack\n");
- /* This clones a conversation (opens /net/tcp/clone), then reads the cloned
- * fd (which is the ctl) to givure out the conv number (the line), then
- * writes "announce [addr]" into ctl. This "announce" command often has a
- * "bind" in it too. plan9 bind just sets the local addr/port. TCP
- * announce also does this. Returns the ctlfd. */
+ /* This clones a conversation (opens /net/tcp/clone), then reads the
+ * cloned fd (which is the ctl) to givure out the conv number (the
+ * line), then writes "announce [addr]" into ctl. This "announce"
+ * command often has a "bind" in it too. plan9 bind just sets the local
+ * addr/port. TCP announce also does this. Returns the ctlfd. */
afd = announce9("tcp!*!23", adir, 0);
if (afd < 0) {
@@ -74,8 +74,8 @@
srv.sin_port = htons(23);
socklen_t socksize = sizeof(struct sockaddr_in);
- /* Equiv to cloning a converstation in plan 9. The shim returns the data FD
- * for the conversation. */
+ /* Equiv to cloning a converstation in plan 9. The shim returns the
+ * data FD for the conversation. */
srv_socket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
if (srv_socket < 0) {
perror("Socket failure");
@@ -84,7 +84,8 @@
/* bind + listen is equiv to announce() in plan 9. Note that the "bind"
* command is used, unlike in the plan9 announce. */
/* Binds our socket to the given addr/port in srv. */
- ret = bind(srv_socket, (struct sockaddr*)&srv, sizeof(struct sockaddr_in));
+ ret = bind(srv_socket, (struct sockaddr*)&srv,
+ sizeof(struct sockaddr_in));
if (ret < 0) {
perror("Bind failure");
return -1;
@@ -98,8 +99,8 @@
printf("Listened on port %d\n", ntohs(srv.sin_port));
#endif
- /* at this point, the server has done all the prep necessary to be able to
- * sleep/block/wait on an incoming connection. */
+ /* at this point, the server has done all the prep necessary to be able
+ * to sleep/block/wait on an incoming connection. */
#define EP_SET_SZ 10 /* this is actually the ID of the largest FD */
int epfd = epoll_create(EP_SET_SZ);
struct epoll_event ep_ev;
@@ -120,10 +121,11 @@
return -1;
}
/* This is a little subtle. We're putting a tap on the listen file /
- * listen_fd. When this fires, we get an event because of that listen_fd.
- * But we don't actually listen or do anything to that listen_fd. It's
- * solely for monitoring. We open a path, below, and we'll reattempt to do
- * *that* operation when someone tells us that our listen tap fires. */
+ * listen_fd. When this fires, we get an event because of that
+ * listen_fd. But we don't actually listen or do anything to that
+ * listen_fd. It's solely for monitoring. We open a path, below, and
+ * we'll reattempt to do *that* operation when someone tells us that our
+ * listen tap fires. */
ep_ev.data.fd = listen_fd;
if (epoll_ctl(epfd, EPOLL_CTL_ADD, listen_fd, &ep_ev)) {
perror("epoll_ctl_add listen");
@@ -131,13 +133,15 @@
}
has_epolled = FALSE;
while (1) {
- /* Opens the conversation's listen file. This blocks til someone
- * connects. When they do, a new conversation is created, and that open
- * returned an FD for the new conv's ctl. listen() reads that to find
- * out the conv number (the line) for this new conv. listen() returns
- * the ctl for this new conv.
+ /* Opens the conversation's listen file. This blocks til
+ * someone connects. When they do, a new conversation is
+ * created, and that open returned an FD for the new conv's ctl.
+ * listen() reads that to find out the conv number (the line)
+ * for this new conv. listen() returns the ctl for this new
+ * conv.
*
- * Non-block is for the act of listening, and applies to lcfd. */
+ * Non-block is for the act of listening, and applies to lcfd.
+ */
lcfd = listen9(adir, ldir, O_NONBLOCK);
if (lcfd >= 0)
break;
@@ -163,9 +167,9 @@
}
close(listen_fd);
- /* Writes "accept [NUM]" into the ctlfd, then opens the conv's data file and
- * returns that fd. Writing "accept" is a noop for most of our protocols.
- * */
+ /* Writes "accept [NUM]" into the ctlfd, then opens the conv's data file
+ * and returns that fd. Writing "accept" is a noop for most of our
+ * protocols. */
dfd = accept9(lcfd, ldir);
if (dfd < 0) {
perror("Accept failure");
@@ -251,7 +255,7 @@
#ifdef PLAN9NET
close(dfd); /* data fd for the new conv, from listen */
- close(lcfd); /* ctl fd for the new conv, from listen */
+ close(lcfd); /* ctl fd for the new conv, from listen */
close(afd); /* ctl fd for the listening conv */
#else
close(dfd); /* new connection socket, from accept */
diff --git a/tests/evq_block.c b/tests/evq_block.c
index 49a050e..c8ec603 100644
--- a/tests/evq_block.c
+++ b/tests/evq_block.c
@@ -14,6 +14,7 @@
static struct event_queue *get_ectlr_evq(void)
{
struct event_queue *ev_q = get_eventq(EV_MBOX_UCQ);
+
evq_attach_wakeup_ctlr(ev_q);
return ev_q;
}
@@ -32,6 +33,7 @@
/* these need to just exist somewhere. don't free them. */
struct event_queue *evq1 = get_ectlr_evq();
struct event_queue *evq2 = get_ectlr_evq();
+
evq1->ev_flags |= EVENT_INDIR | EVENT_SPAM_INDIR | EVENT_WAKEUP;
evq2->ev_flags |= EVENT_INDIR | EVENT_SPAM_INDIR | EVENT_WAKEUP;
/* hack in our own handler for debugging */
@@ -55,12 +57,13 @@
if (devalarm_set_time(timerfd2, now + sec2tsc(2)))
return -1;
- /* if we remove this, two will fire first and wake us up. if we don't exit
- * right away, one will eventually fire and do nothing. */
+ /* if we remove this, two will fire first and wake us up. if we don't
+ * exit right away, one will eventually fire and do nothing. */
uthread_sleep(5);
/* then the actual usage: */
struct event_msg msg;
struct event_queue *which;
+
uth_blockon_evqs(&msg, &which, 2, evq1, evq2);
printf("Got message type %d on evq %s (%p)\n", msg.ev_type,
which == evq1 ? "one" : "two", which);
diff --git a/tests/file_test.c b/tests/file_test.c
index f87c358..b0f3738 100644
--- a/tests/file_test.c
+++ b/tests/file_test.c
@@ -15,6 +15,7 @@
int main()
{
FILE *file;
+
file = fopen("/dir1/f1.txt","w+b");
if (file == NULL)
printf ("Failed to open file \n");
@@ -24,6 +25,7 @@
int fd = open("../../..//////dir1/test.txt", O_RDWR | O_CREAT );
char rbuf[256] = {0}, wbuf[256] = {0};
int retval;
+
retval = read(fd, rbuf, 16);
printf("Tried to read, got %d bytes of buf: %s\n", retval, rbuf);
strcpy(wbuf, DUMMY_STR);
@@ -55,6 +57,7 @@
printf("WARNING! Access error for f1.txt!\n");
struct stat st = {0};
+ //
//retval = stat("/bin/mhello", &st);
retval = fstat(fd, &st);
printf("Tried to stat, was told %d\n", retval);
@@ -178,8 +181,8 @@
printf("WARNING! failed to open hello.txt!\n");
retval = fchdir(fd);
if (!retval || errno != ENOTDIR)
- printf("WARNING! didn't fail to fchdir to hello.txt %d %d\n", retval,
- errno);
+ printf("WARNING! didn't fail to fchdir to hello.txt %d %d\n",
+ retval, errno);
close(fd);
/* Try a chmod() */
@@ -200,5 +203,6 @@
if (retval < 0)
printf("WARNING! rmdir failed with %d!\n", errno);
breakpoint();
+ return 0;
}
diff --git a/tests/futex_timeout.c b/tests/futex_timeout.c
index 370bb0f..dc5e4fe 100644
--- a/tests/futex_timeout.c
+++ b/tests/futex_timeout.c
@@ -8,15 +8,17 @@
#define NUM_THREADS 10
pthread_t thandlers[NUM_THREADS];
-void *handler(void *arg) {
+void *handler(void *arg)
+{
int id = pthread_self()->id;
int var = 0;
- struct timespec timeout = {
+ struct timespec timeout = {
.tv_sec = id,
.tv_nsec = 0
};
+
printf("Begin thread: %d\n", id);
- futex(&var, FUTEX_WAIT, 0, &timeout, NULL, 0);
+ futex(&var, FUTEX_WAIT, 0, &timeout, NULL, 0);
printf("End thread: %d\n", id);
return 0;
}
diff --git a/tests/gai.c b/tests/gai.c
index 7792a8c..cc78c39 100644
--- a/tests/gai.c
+++ b/tests/gai.c
@@ -16,11 +16,14 @@
static void print_gai(struct addrinfo *ai, const char *info)
{
struct sockaddr_in *ipv4sa;
+
printf("%s: fam %d, sock %d, prot %d ", info, ai->ai_family,
ai->ai_socktype, ai->ai_protocol);
char buf[128];
+
ipv4sa = (struct sockaddr_in*)ai->ai_addr;
const char *ipv4n = inet_ntop(AF_INET, &ipv4sa->sin_addr, buf, 128);
+
assert(buf == ipv4n);
printf("addr %s, port %d\n", buf, ntohs(ipv4sa->sin_port));
}
@@ -30,8 +33,10 @@
{
struct addrinfo *_ai_res;
int ret = getaddrinfo(node, serv, hints, &_ai_res);
+
if (ret) {
- printf("%s: GAI failed, %d, %d %s\n", info, ret, errno, errstr());
+ printf("%s: GAI failed, %d, %d %s\n", info, ret, errno,
+ errstr());
} else {
print_gai(_ai_res, info);
freeaddrinfo(_ai_res);
diff --git a/tests/get_html.c b/tests/get_html.c
index 43a3a58..f1e24e2 100644
--- a/tests/get_html.c
+++ b/tests/get_html.c
@@ -48,7 +48,8 @@
exit(-1);
}
/* short get style */
- snprintf(buf, sizeof(buf), "GET /%s\r\nConnection: close\r\n\r\n", page);
+ snprintf(buf, sizeof(buf), "GET /%s\r\nConnection: close\r\n\r\n",
+ page);
ret = write(dfd, buf, strlen(buf));
if (ret < 0) {
perror("Write");
diff --git a/tests/getifaddrs.c b/tests/getifaddrs.c
index e3982ae..d8e3e36 100644
--- a/tests/getifaddrs.c
+++ b/tests/getifaddrs.c
@@ -47,8 +47,8 @@
printf("\tAddr: %s\n", inet_ntop(AF_INET, &sa_in->sin_addr, buf,
sizeof(buf)));
if (mask_in)
- printf("\tMask: %s\n", inet_ntop(AF_INET, &mask_in->sin_addr, buf,
- sizeof(buf)));
+ printf("\tMask: %s\n", inet_ntop(AF_INET, &mask_in->sin_addr,
+ buf, sizeof(buf)));
}
static void print_inet6(struct ifaddrs *ifa)
diff --git a/tests/interference.c b/tests/interference.c
index 093ad68..8196ff7 100644
--- a/tests/interference.c
+++ b/tests/interference.c
@@ -32,15 +32,15 @@
struct sample_stats {
int (*get_sample)(void **data, int i, int j, uint64_t *sample);
- uint64_t avg_time;
- uint64_t var_time;
- uint64_t max_time;
- uint64_t min_time;
- unsigned int lat_50;
- unsigned int lat_75;
- unsigned int lat_90;
- unsigned int lat_99;
- uint64_t total_samples;
+ uint64_t avg_time;
+ uint64_t var_time;
+ uint64_t max_time;
+ uint64_t min_time;
+ unsigned int lat_50;
+ unsigned int lat_75;
+ unsigned int lat_90;
+ unsigned int lat_99;
+ uint64_t total_samples;
};
void compute_stats(void **data, int nr_i, int nr_j, struct sample_stats *stats)
@@ -90,8 +90,8 @@
int nr_samples = 1000;
uint64_t deadline = sec2tsc(5); /* assumes TSC and cycles are close */
- /* Normally we'd use a 2D array, but since we're just one thread, we just
- * need our first thread's array. */
+ /* Normally we'd use a 2D array, but since we're just one thread, we
+ * just need our first thread's array. */
delays = malloc(sizeof(uint64_t) * nr_samples);
os_init();
pcoreid = get_pcoreid();
diff --git a/tests/linux-lock-hacks.h b/tests/linux-lock-hacks.h
index 4ba7c72..8596443 100644
--- a/tests/linux-lock-hacks.h
+++ b/tests/linux-lock-hacks.h
@@ -54,7 +54,7 @@
typedef struct mcs_lock
{
- mcs_lock_qnode_t* lock;
+ mcs_lock_qnode_t *lock;
} mcs_lock_t;
void __attribute__((noinline)) mcs_lock_init(struct mcs_lock *lock)
@@ -78,8 +78,8 @@
qnode->locked = 1;
wmb();
predecessor->next = qnode;
- /* no need for a wrmb(), since this will only get unlocked after they
- * read our previous write */
+ /* no need for a wrmb(), since this will only get unlocked
+ * after they read our previous write */
while (qnode->locked)
cpu_relax();
}
@@ -91,34 +91,40 @@
{
/* Check if someone is already waiting on us to unlock */
if (qnode->next == 0) {
- cmb(); /* no need for CPU mbs, since there's an atomic_swap() */
+ cmb(); /* no need for CPU mbs, since there's an atomic_swap() */
/* Unlock it */
mcs_lock_qnode_t *old_tail = mcs_qnode_swap(&lock->lock,0);
- /* no one else was already waiting, so we successfully unlocked and can
- * return */
+ /* no one else was already waiting, so we successfully unlocked
+ * and can return */
if (old_tail == qnode)
return;
- /* someone else was already waiting on the lock (last one on the list),
- * and we accidentally took them off. Try and put it back. */
- mcs_lock_qnode_t *usurper = mcs_qnode_swap(&lock->lock,old_tail);
- /* since someone else was waiting, they should have made themselves our
- * next. spin (very briefly!) til it happens. */
+ /* someone else was already waiting on the lock (last one on
+ * the list), and we accidentally took them off. Try and put
+ * it back. */
+ mcs_lock_qnode_t *usurper = mcs_qnode_swap(&lock->lock,
+ old_tail);
+ /* since someone else was waiting, they should have made
+ * themselves our next. spin (very briefly!) til it happens.
+ * */
while (qnode->next == 0)
cpu_relax();
if (usurper) {
- /* an usurper is someone who snuck in before we could put the old
- * tail back. They now have the lock. Let's put whoever is
- * supposed to be next as their next one. */
+ /* an usurper is someone who snuck in before we could
+ * put the old tail back. They now have the lock.
+ * Let's put whoever is supposed to be next as their
+ * next one. */
usurper->next = qnode->next;
} else {
- /* No usurper meant we put things back correctly, so we should just
- * pass the lock / unlock whoever is next */
+ /* No usurper meant we put things back correctly, so we
+ * should just pass the lock / unlock whoever is next */
qnode->next->locked = 0;
}
} else {
/* mb()s necessary since we didn't call an atomic_swap() */
- wmb(); /* need to make sure any previous writes don't pass unlocking */
- rwmb(); /* need to make sure any reads happen before the unlocking */
+ /* need to make sure any previous writes don't pass unlocking */
+ wmb();
+ /* need to make sure any reads happen before the unlocking */
+ rwmb();
/* simply unlock whoever is next */
qnode->next->locked = 0;
}
@@ -132,12 +138,14 @@
/* Check if someone is already waiting on us to unlock */
if (qnode->next == 0) {
cmb(); /* no need for CPU mbs, since there's an atomic_cas() */
- /* If we're still the lock, just swap it with 0 (unlock) and return */
+ /* If we're still the lock, just swap it with 0 (unlock) and
+ * return */
if (__sync_bool_compare_and_swap((void**)&lock->lock, qnode, 0))
return;
- /* We failed, someone is there and we are some (maybe a different)
- * thread's pred. Since someone else was waiting, they should have made
- * themselves our next. Spin (very briefly!) til it happens. */
+ /* We failed, someone is there and we are some (maybe a
+ * different) thread's pred. Since someone else was waiting,
+ * they should have made themselves our next. Spin (very
+ * briefly!) til it happens. */
while (qnode->next == 0)
cpu_relax();
/* Alpha wants a read_barrier_depends() here */
@@ -145,8 +153,10 @@
qnode->next->locked = 0;
} else {
/* mb()s necessary since we didn't call an atomic_swap() */
- wmb(); /* need to make sure any previous writes don't pass unlocking */
- rwmb(); /* need to make sure any reads happen before the unlocking */
+ /* need to make sure any previous writes don't pass unlocking */
+ wmb();
+ /* need to make sure any reads happen before the unlocking */
+ rwmb();
/* simply unlock whoever is next */
qnode->next->locked = 0;
}
diff --git a/tests/listen1.c b/tests/listen1.c
index 5421175..6aa1d3f 100644
--- a/tests/listen1.c
+++ b/tests/listen1.c
@@ -101,7 +101,8 @@
case 0:
fd = accept9(nctl, ndir);
if(fd < 0){
- fprintf(stderr, "accept %s: can't open %s/data: %r\n",
+ fprintf(stderr,
+ "accept %s: can't open %s/data: %r\n",
argv[0], ndir);
exit(1);
}
diff --git a/tests/listener.c b/tests/listener.c
index c5787a4..9847f0a 100644
--- a/tests/listener.c
+++ b/tests/listener.c
@@ -51,11 +51,11 @@
#ifdef PLAN9NET
printf("Using Plan 9's networking stack\n");
- /* This clones a conversation (opens /net/tcp/clone), then reads the cloned
- * fd (which is the ctl) to givure out the conv number (the line), then
- * writes "announce [addr]" into ctl. This "announce" command often has a
- * "bind" in it too. plan9 bind just sets the local addr/port. TCP
- * announce also does this. Returns the ctlfd. */
+ /* This clones a conversation (opens /net/tcp/clone), then reads the
+ * cloned fd (which is the ctl) to givure out the conv number (the
+ * line), then writes "announce [addr]" into ctl. This "announce"
+ * command often has a "bind" in it too. plan9 bind just sets the local
+ * addr/port. TCP announce also does this. Returns the ctlfd. */
afd = announce9("tcp!*!23", adir, 0);
if (afd < 0) {
@@ -65,15 +65,17 @@
printf("Announced on line %s\n", adir);
#else
printf("Using the BSD socket shims over Plan 9's networking stack\n");
+
int srv_socket, con_socket;
struct sockaddr_in dest, srv = {0};
+
srv.sin_family = AF_INET;
srv.sin_addr.s_addr = htonl(INADDR_ANY);
srv.sin_port = htons(23);
socklen_t socksize = sizeof(struct sockaddr_in);
- /* Equiv to cloning a converstation in plan 9. The shim returns the data FD
- * for the conversation. */
+ /* Equiv to cloning a converstation in plan 9. The shim returns the
+ * data FD for the conversation. */
srv_socket = socket(AF_INET, SOCK_STREAM, 0);
if (srv_socket < 0) {
perror("Socket failure");
@@ -83,7 +85,8 @@
/* bind + listen is equiv to announce() in plan 9. Note that the "bind"
* command is used, unlike in the plan9 announce. */
/* Binds our socket to the given addr/port in srv. */
- ret = bind(srv_socket, (struct sockaddr*)&srv, sizeof(struct sockaddr_in));
+ ret = bind(srv_socket, (struct sockaddr*)&srv,
+ sizeof(struct sockaddr_in));
if (ret < 0) {
perror("Bind failure");
return -1;
@@ -96,15 +99,15 @@
}
#endif
- /* at this point, the server has done all the prep necessary to be able to
- * sleep/block/wait on an incoming connection. */
+ /* at this point, the server has done all the prep necessary to be able
+ * to sleep/block/wait on an incoming connection. */
#ifdef PLAN9NET
- /* Opens the conversation's listen file. This blocks til someone connects.
- * When they do, a new conversation is created, and that open returned an FD
- * for the new conv's ctl. listen() reads that to find out the conv number
- * (the line) for this new conv. listen() returns the ctl for this new
- * conv. */
+ /* Opens the conversation's listen file. This blocks til someone
+ * connects. When they do, a new conversation is created, and that open
+ * returned an FD for the new conv's ctl. listen() reads that to find
+ * out the conv number (the line) for this new conv. listen() returns
+ * the ctl for this new conv. */
lcfd = listen9(adir, ldir, 0);
if (lcfd < 0) {
@@ -113,9 +116,9 @@
}
printf("Listened and got line %s\n", ldir);
- /* Writes "accept [NUM]" into the ctlfd, then opens the conv's data file and
- * returns that fd. Writing "accept" is a noop for most of our protocols.
- * */
+ /* Writes "accept [NUM]" into the ctlfd, then opens the conv's data file
+ * and returns that fd. Writing "accept" is a noop for most of our
+ * protocols. */
dfd = accept9(lcfd, ldir);
if (dfd < 0) {
perror("Accept failure");
diff --git a/tests/lock_test.c b/tests/lock_test.c
index 6072153..e1a985d 100644
--- a/tests/lock_test.c
+++ b/tests/lock_test.c
@@ -63,7 +63,8 @@
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(i, &cpuset);
- pthread_setaffinity_np(worker_threads[i], sizeof(cpu_set_t), &cpuset);
+ pthread_setaffinity_np(worker_threads[i], sizeof(cpu_set_t),
+ &cpuset);
}
}
@@ -79,369 +80,377 @@
* months).
*
* BUGS / COMMENTARY
- * Occasional deadlocks when preempting and not giving back!
- * - with the new PDRs style, though that doesn't mean the older styles
- * don't have this problem
- * - shouldn't be any weaker than PDR. they all check pred_vc to see
- * if they are running, and if not, they make sure someone runs
- * - could be weaker if we have an old value for the lockholder,
- * someone outside the chain, and we made sure they ran, and they do
- * nothing (spin in the 2LS or something?)
- * no, they should have gotten a msg about us being preempted,
- * since whoever we turn into gets the message about us swapping.
- * - anyway, it's not clear if this is with MCSPDR, event delivery,
- * preemption handling, or just an artifact of the test (less likely)
- * why aren't MCS locks in uth_ctx getting dealt with?
- * - because the event is handled, but the lock holder isn't run. the
- * preemption was dealt with, but nothing saved the lock holder
- * - any uthread_ctx lockholder that gets preempted will get
- * interrupted, and other cores will handle the preemption. but that
- * uthread won't run again without 2LS support. either all spinners
- * need to be aware of the 'lockholder' (PDR-style), or the 2LS needs
- * to know when a uthread becomes a 'lockholder' to make sure it runs
- * via user-level preempts. If the latter, this needs to happen
- * atomically with grabbing the lock, or else be able to handle lots of
- * fake 'lockholders' (like round-robin among all of them)
- * why is the delay more than the expected delay?
- * because it takes ~2ms to spawn and run a process
- * could do this in a separate process, instead of a script
- * could also consider not using pth_test and changing prov, but
- * driving it by yields and requests. would also test the
- * alarm/wakeup code (process sets alarm, goes to sleep, wakes up
- * and requests X cores)
- * why do we get occasional preempt-storms? (lots of change_tos)
- * due to the MCS-PDR chain, which i tried fixing by adjusting the
- * number of workers down to the number of vcores
- * why isn't the worker adaptation working?
- * - it actually was working, and nr_workers == nr_vcores. that
- * just wasn't the root cause.
- * - was expecting it to cut down on PDR kernel traffic
- * - still get periods of low perf
- * like O(100) preempt msgs per big preempt/prov
- * does it really take that much to work out an MCS-PDR?
- * - one thing is that if we fake vc ctx, we never receive preemption
- * events. might be a bad idea.
- * - in general, yeah. faking VC and turning off events can really
- * muck with things
- * - these events aren't necessarily delivered to a VC who will
- * check events any time soon (might be the last one in the chain)
- * - the core of the issue is that we have the right amount of
- * workers and vcores, but that the system isn't given a chance to
- * stabilize itself. also, if we have some VCs that are just
- * sitting around, spinning in the 2LS, if those get preempted, no
- * one notices or cares (when faking vc_ctx / getting no events)
- * - there is a slight race where we might make someone run who isn't a
- * lockholder. logically, its okay. worst case, it would act like an
- * extra preempt and different startcore, which shouldn't be too bad.
+ * Occasional deadlocks when preempting and not giving back!
+ * - with the new PDRs style, though that doesn't mean the older styles
+ * don't have this problem
+ * - shouldn't be any weaker than PDR. they all check pred_vc to see
+ * if they are running, and if not, they make sure someone runs
+ * - could be weaker if we have an old value for the lockholder,
+ * someone outside the chain, and we made sure they ran, and they do
+ * nothing (spin in the 2LS or something?)
+ * no, they should have gotten a msg about us being preempted,
+ * since whoever we turn into gets the message about us swapping.
+ * - anyway, it's not clear if this is with MCSPDR, event delivery,
+ * preemption handling, or just an artifact of the test (less likely)
+ * why aren't MCS locks in uth_ctx getting dealt with?
+ * - because the event is handled, but the lock holder isn't run. the
+ * preemption was dealt with, but nothing saved the lock holder
+ * - any uthread_ctx lockholder that gets preempted will get
+ * interrupted, and other cores will handle the preemption. but that
+ * uthread won't run again without 2LS support. either all spinners
+ * need to be aware of the 'lockholder' (PDR-style), or the 2LS needs
+ * to know when a uthread becomes a 'lockholder' to make sure it runs
+ * via user-level preempts. If the latter, this needs to happen
+ * atomically with grabbing the lock, or else be able to handle lots of
+ * fake 'lockholders' (like round-robin among all of them)
+ * why is the delay more than the expected delay?
+ * because it takes ~2ms to spawn and run a process
+ * could do this in a separate process, instead of a script
+ * could also consider not using pth_test and changing prov, but
+ * driving it by yields and requests. would also test the
+ * alarm/wakeup code (process sets alarm, goes to sleep, wakes up
+ * and requests X cores)
+ * why do we get occasional preempt-storms? (lots of change_tos)
+ * due to the MCS-PDR chain, which i tried fixing by adjusting the number
+ * of workers down to the number of vcores
+ * why isn't the worker adaptation working?
+ * - it actually was working, and nr_workers == nr_vcores. that
+ * just wasn't the root cause.
+ * - was expecting it to cut down on PDR kernel traffic
+ * - still get periods of low perf
+ * like O(100) preempt msgs per big preempt/prov
+ * does it really take that much to work out an MCS-PDR?
+ * - one thing is that if we fake vc ctx, we never receive preemption
+ * events. might be a bad idea.
+ * - in general, yeah. faking VC and turning off events can really
+ * muck with things
+ * - these events aren't necessarily delivered to a VC who will
+ * check events any time soon (might be the last one in the chain)
+ * - the core of the issue is that we have the right amount of
+ * workers and vcores, but that the system isn't given a chance to
+ * stabilize itself. also, if we have some VCs that are just
+ * sitting around, spinning in the 2LS, if those get preempted, no
+ * one notices or cares (when faking vc_ctx / getting no events)
+ * - there is a slight race where we might make someone run who isn't a
+ * lockholder. logically, its okay. worst case, it would act like an
+ * extra preempt and different startcore, which shouldn't be too bad.
*
- * sanity check: does throughput match latency? (2.5GHz TSC, MCS lock)
- * ex: 5000 locks/ms = 5 locks/us = 200ns/lock = 500 ticks / lock
- * 500 ticks * 31 workers (queue) = 15000 ticks
- * avg acquire time was around 14K. seems fine..
- * when our MCSPDR throughput tanks (during preempts), it's around
- * 400-500 locks/ms, which is around 2us/lock.
- * when the locker on a preempted chain shows up, it needs to
- * change to the next one in line.
- * - though that should be in parallel with the other
- * lockholders letting go. shouldn't be that bad
- * - no, it is probably at the head of the chain very soon,
- * such that it is the bottleneck for the actual lock. 2us
- * seems possible
+ * sanity check: does throughput match latency? (2.5GHz TSC, MCS lock)
+ * ex: 5000 locks/ms = 5 locks/us = 200ns/lock = 500 ticks / lock
+ * 500 ticks * 31 workers (queue) = 15000 ticks
+ * avg acquire time was around 14K. seems fine..
+ * when our MCSPDR throughput tanks (during preempts), it's around
+ * 400-500 locks/ms, which is around 2us/lock.
+ * when the locker on a preempted chain shows up, it needs to
+ * change to the next one in line.
+ * - though that should be in parallel with the other
+ * lockholders letting go. shouldn't be that bad
+ * - no, it is probably at the head of the chain very soon,
+ * such that it is the bottleneck for the actual lock. 2us
+ * seems possible
*
- * what does it take to get out of a preemption with (old) MCS-PDR?
- * - these are now called pdro locks (old)
- * - for a single preempt, it will take 1..n-1 changes. avg n/2
- * - for multiple preempts, it's nr_pre * that (avg np/2, worst np)
- * - for every unlock/reacquire cycle (someone unlocks, then rejoins
- * the list), its nr_preempts (aka, nr_workers - nr_vcores)
- * - if we need to have a specific worker get out of the chain, on
- * average, it'd take n/2 cycles (p*n/2 changes) worst: np
- * - if we want to get multiple workers out, the worst case is still
- * np, but as p increases, we're more likely to approach n cycles
- * - so the current model is np for the initial hit (to move the
- * offline VCs to the end of the chain) and another np to get our
- * specific workers out of the chain and yielding (2np)
+ * what does it take to get out of a preemption with (old) MCS-PDR?
+ * - these are now called pdro locks (old)
+ * - for a single preempt, it will take 1..n-1 changes. avg n/2
+ * - for multiple preempts, it's nr_pre * that (avg np/2, worst np)
+ * - for every unlock/reacquire cycle (someone unlocks, then rejoins
+ * the list), its nr_preempts (aka, nr_workers - nr_vcores)
+ * - if we need to have a specific worker get out of the chain, on
+ * average, it'd take n/2 cycles (p*n/2 changes) worst: np
+ * - if we want to get multiple workers out, the worst case is still
+ * np, but as p increases, we're more likely to approach n cycles
+ * - so the current model is np for the initial hit (to move the
+ * offline VCs to the end of the chain) and another np to get our
+ * specific workers out of the chain and yielding (2np)
*
- * - but even with 1 preempt, we're getting 80-200 changes per
+ * - but even with 1 preempt, we're getting 80-200 changes per
*
- * - it shouldn't matter that the sys_change_to is really slow, should
- * be the same amount of changes. however, the preempted ones are
- * never really at the tail end of the chain - they should end up right
- * before the lockholder often. while the sys_change_tos are slowly
- * moving towards the back of the chain, the locking code is quickly
- * removing (online) nodes from the head and putting them on the back.
+ * - it shouldn't matter that the sys_change_to is really slow, should
+ * be the same amount of changes. however, the preempted ones are
+ * never really at the tail end of the chain - they should end up right
+ * before the lockholder often. while the sys_change_tos are slowly
+ * moving towards the back of the chain, the locking code is quickly
+ * removing (online) nodes from the head and putting them on the back.
*
- * - end result: based on lock hold time and lock delay time, a
- * preempted VC stays in the MCS chain (swaps btw VC/nodes), and when
- * it is inside the chain, someone is polling to make them run. with
- * someone polling, it is extremely unlikely that someone outside the
- * chain will win the race and be able to change_to before the in-chain
- * poller. to clarify:
- * - hold time and delay time matter, since the longer they are,
- * the greater the amount of time the change_to percolation has to
- * get the preempted VCs to the end of the chain (where no one
- * polls them).
- * - at least one vcore is getting the event to handle the
- * preemption of the in-chain, offline VC. we could change it so
- * every VC polls the preempt_evq, or just wait til whoever is
- * getting the messages eventually checks their messages (VC0)
- * - if there is an in-chain poller, they will notice the instant
- * the VC map changes, and then immediately change_to (and spin on
- * the proclock in the kernel). there's almost no chance of a
- * normal preempt event handler doing that faster. (would require
- * some IRQ latency or something serious).
- * - adding in any hold time trashes our microbenchmark's perf, but a
- * little delay time actually helps: (all with no preempts going on)
- * - mcspdr, no delay: 4200-4400 (-w31 -l10000, no faking, etc)
- * - mcspdr, d = 1: 4400-4800
- * - mcspdr, d = 2: 4200-5200
- * - as you add delay, it cuts down on contention for the
- * lock->lock cacheline. but if you add in too much, you'll tank
- * throughput (since there is no contention at all).
- * - as we increase the delay, we cut down on the chance of the
- * preempt storm / preempt-stuck-in-the-chain, though it can still
- * happen, even with a delay of 10us
- * - maybe add in the lockholder again? (removed in 73701d6bfb)
- * - massively cuts performance, like 2x throughput, without
- * preempts
- * - it's ability to help depends on impl:
- * in one version (old style), it didn't help much at all
- * - in another (optimized lockholder setting), i can't even
- * see the throughput hit, it recovered right away, with O(5)
- * messages
- * - the diff was having the lockholder assign the vcoreid
- * before passing off to the next in the chain, so that there
- * is less time with having "no lockholder". (there's a brief
- * period where the lockholder says it is the next person, who
- * still spins. they'll have to make sure their pred runs)
- * -adj workers doesn't matter either...
- * - the 2LS and preemption handling might be doing this
- * automatically, when handle_vc_preempt() does a
- * thread_paused() on its current_uthread.
- * - adj_workers isn't critical if we're using some locks
- * that check notif_pending. eventually someone hears
- * about preempted VCs (assuming we can keep up)
+ * - end result: based on lock hold time and lock delay time, a
+ * preempted VC stays in the MCS chain (swaps btw VC/nodes), and when
+ * it is inside the chain, someone is polling to make them run. with
+ * someone polling, it is extremely unlikely that someone outside the
+ * chain will win the race and be able to change_to before the in-chain
+ * poller. to clarify:
+ * - hold time and delay time matter, since the longer they are,
+ * the greater the amount of time the change_to percolation has to
+ * get the preempted VCs to the end of the chain (where no one
+ * polls them).
+ * - at least one vcore is getting the event to handle the
+ * preemption of the in-chain, offline VC. we could change it so
+ * every VC polls the preempt_evq, or just wait til whoever is
+ * getting the messages eventually checks their messages (VC0)
+ * - if there is an in-chain poller, they will notice the instant
+ * the VC map changes, and then immediately change_to (and spin on
+ * the proclock in the kernel). there's almost no chance of a
+ * normal preempt event handler doing that faster. (would require
+ * some IRQ latency or something serious).
+ * - adding in any hold time trashes our microbenchmark's perf, but a
+ * little delay time actually helps: (all with no preempts going on)
+ * - mcspdr, no delay: 4200-4400 (-w31 -l10000, no faking, etc)
+ * - mcspdr, d = 1: 4400-4800
+ * - mcspdr, d = 2: 4200-5200
+ * - as you add delay, it cuts down on contention for the
+ * lock->lock cacheline. but if you add in too much, you'll tank
+ * throughput (since there is no contention at all).
+ * - as we increase the delay, we cut down on the chance of the
+ * preempt storm / preempt-stuck-in-the-chain, though it can still
+ * happen, even with a delay of 10us
+ * - maybe add in the lockholder again? (removed in 73701d6bfb)
+ * - massively cuts performance, like 2x throughput, without
+ * preempts
+ * - it's ability to help depends on impl:
+ * in one version (old style), it didn't help much at all
+ * - in another (optimized lockholder setting), i can't
+ * even see the throughput hit, it recovered right away,
+ * with O(5) messages
+ * - the diff was having the lockholder assign the vcoreid
+ * before passing off to the next in the chain, so that
+ * there is less time with having "no lockholder".
+ * (there's a brief period where the lockholder says it is
+ * the next person, who still
+ * spins. they'll have to make
+ * sure their pred runs)
+ * -adj workers doesn't matter either...
+ * - the 2LS and preemption handling might be doing this
+ * automatically, when handle_vc_preempt() does a
+ * thread_paused() on its current_uthread.
+ * - adj_workers isn't critical if we're using some locks
+ * that check notif_pending. eventually someone hears
+ * about preempted VCs (assuming we can keep up)
*
- * What about delays? both hold and delay should make it easier to get
- * the preempted vcore to the end of the chain. but do they have to be
- * too big to be reasonable?
- * - yes. hold doesn't really help much until everything is
- * slower. even with a hold of around 1.2us, we still have the
- * change_to-storms and lowered throughput.
- * - doing a combo helps too. if you hold for 1ns (quite a bit
- * more actually, due to the overhead of ndelay, but sufficient to
- * be "doing work"), and delaying for around 7us before rejoining,
- * there's only about a 1/5 chance of a single preempt messing us
- * up
- * - though having multiple preempts outstanding make this less
- * likely to work.
- * - and it seems like if we get into the storm scenario, we
- * never really get out. either we do quickly or never do.
- * depending on the workload, this could be a matter of luck
+ * What about delays? both hold and delay should make it easier to get
+ * the preempted vcore to the end of the chain. but do they have to be
+ * too big to be reasonable?
+ * - yes. hold doesn't really help much until everything is
+ * slower. even with a hold of around 1.2us, we still have the
+ * change_to-storms and lowered throughput.
+ * - doing a combo helps too. if you hold for 1ns (quite a bit
+ * more actually, due to the overhead of ndelay, but sufficient to
+ * be "doing work"), and delaying for around 7us before rejoining,
+ * there's only about a 1/5 chance of a single preempt messing us
+ * up
+ * - though having multiple preempts outstanding make this less
+ * likely to work.
+ * - and it seems like if we get into the storm scenario, we
+ * never really get out. either we do quickly or never do.
+ * depending on the workload, this could be a matter of luck
*
- * So we could try tracking the lockholder, but only looking at it when
- * we know someone was preempted in the chain - specifically, when our
- * pred is offline. when that happens, we don't change to them, we
- * make sure the lockholder is running.
- * - tracking takes us from 4200->2800 throughput or so for MCS
- * - 5200 -> 3700 or so for MCS in vc_ctx (__MCSPDR)
- * - main spike seems to be in the hold time. bimodal distrib,
- * with most below 91 (the usual is everything packed below 70) and
- * a big spike around 320
+ * So we could try tracking the lockholder, but only looking at it when
+ * we know someone was preempted in the chain - specifically, when our
+ * pred is offline. when that happens, we don't change to them, we
+ * make sure the lockholder is running.
+ * - tracking takes us from 4200->2800 throughput or so for MCS
+ * - 5200 -> 3700 or so for MCS in vc_ctx (__MCSPDR)
+ * - main spike seems to be in the hold time. bimodal distrib,
+ * with most below 91 (the usual is everything packed below 70) and
+ * a big spike around 320
*
- * Summary:
- * So we need to have someone outside the chain change_to the one in the
- * chain o/w, someone will always be in the chain. Right now, it's always
- * the next in line who is doing the changing, so a preempted vcore is
- * always still in the chain.
+ * Summary:
*
- * If the locking workload has some delaying, such as while holding the
- * lock or before reacquiring, the "change_to" storm might not be a
- * problem. If it is, the only alternative I have so far is to check the
- * lockholder (which prevents a chain member from always ensuring their
- * pred runs). This hurts the lock's scalability/performance when we
- * aren't being preempted. On the otherhand, based on what you're doing
- * with the lock, one more cache miss might not be as big of a deal as in
- * lock_test. Especially if when you get stormed, your throughput could be
- * terrible and never recover.
+ * So we need to have someone outside the chain change_to the one in the
+ * chain o/w, someone will always be in the chain. Right now, it's always
+ * the next in line who is doing the changing, so a preempted vcore is
+ * always still in the chain.
*
- * Similar point: you can use spinpdr locks. They have the PDR-benefits,
- * and won't induce the storm of change_tos. However, this isn't much
- * better for contended locks. They perform 2-3x worse (on c89) without
- * preemption. Arguably, if you were worried about the preempt storms and
- * want scalability, you might want to use mcspdr with lockholders.
+ * If the locking workload has some delaying, such as while holding the
+ * lock or before reacquiring, the "change_to" storm might not be a
+ * problem. If it is, the only alternative I have so far is to check the
+ * lockholder (which prevents a chain member from always ensuring their
+ * pred runs). This hurts the lock's scalability/performance when we
+ * aren't being preempted. On the otherhand, based on what you're doing
+ * with the lock, one more cache miss might not be as big of a deal as in
+ * lock_test. Especially if when you get stormed, your throughput could be
+ * terrible and never recover.
*
- * The MCSPDRS (now just callced MCSPDR, these are default) locks can avoid
- * the storm, but at the cost of a little more in performance. mcspdrs
- * style is about the same when not getting preempted from uth ctx compared
- * to mcspdr (slight drop). When in vc ctx, it's about 10-20% perf hit
- * (PDRS gains little from --vc_ctx).
+ * Similar point: you can use spinpdr locks. They have the PDR-benefits,
+ * and won't induce the storm of change_tos. However, this isn't much
+ * better for contended locks. They perform 2-3x worse (on c89) without
+ * preemption. Arguably, if you were worried about the preempt storms and
+ * want scalability, you might want to use mcspdr with lockholders.
*
- * Turns out there is a perf hit to PDRS (and any non-stack based qnode)
- * when running on c89. The issue is that after shuffling the vcores
- * around, they are no longer mapped nicely to pcores (VC0->PC1, VC1->PC2).
- * This is due to some 'false sharing' of the cachelines, caused mostly by
- * aggressive prefetching (notably the intel adjacent cacheline prefetcher,
- * which grabs two CLs at a time!). Basically, stack-based qnodes are
- * qnodes that are very far apart in memory. Cranking up the padding in
- * qnodes in the "qnodes-in-locks" style replicates this.
+ * The MCSPDRS (now just callced MCSPDR, these are default) locks can avoid
+ * the storm, but at the cost of a little more in performance. mcspdrs
+ * style is about the same when not getting preempted from uth ctx compared
+ * to mcspdr (slight drop). When in vc ctx, it's about 10-20% perf hit
+ * (PDRS gains little from --vc_ctx).
*
- * For some info on the prefetching:
- * http://software.intel.com/en-us/articles/optimizing-application-performance-on-intel-coret-microarchitecture-using-hardware-implemented-prefetchers/
- * http://software.intel.com/en-us/forums/topic/341769
+ * Turns out there is a perf hit to PDRS (and any non-stack based qnode)
+ * when running on c89. The issue is that after shuffling the vcores
+ * around, they are no longer mapped nicely to pcores (VC0->PC1, VC1->PC2).
+ * This is due to some 'false sharing' of the cachelines, caused mostly by
+ * aggressive prefetching (notably the intel adjacent cacheline prefetcher,
+ * which grabs two CLs at a time!). Basically, stack-based qnodes are
+ * qnodes that are very far apart in memory. Cranking up the padding in
+ * qnodes in the "qnodes-in-locks" style replicates this.
*
- * Here's some rough numbers of the different styles for qnodes on c89.
- * 'in order' is VCn->PC(n+1) (0->1, 1->2). Worst order is with even VCs
- * on one socket, odds on the other. the number of CLs is the size of a
- * qnode. mcspdr is the new style (called mcspdrs in some places in this
- * document), with lock-based qnodes. mcspdr2 is the same, but with
- * stack-based qnodes. mcspdro is the old style (bad a recovery), stack
- * based, sometimes just called mcs-pdr
+ * For some info on the prefetching:
+ * http://software.intel.com/en-us/articles/optimizing-application-performance-on-intel-coret-microarchitecture-using-hardware-implemented-prefetchers/
+ * http://software.intel.com/en-us/forums/topic/341769
*
- * with prefetchers disabled (MCS and DCU)
- * mcspdr 1CL 4.8-5.4 in order, 3.8-4.2 worst order
- * mcspdr 2CL in order, worst order
- * mcspdr 4CL 5.2-6.0 in order, 4.7-5.3 worst order
- * mcspdr 8CL 5.4-6.7 in order, 5.2-6.2 worst order
- * mcspdr 16CL 5.1-5.8 in order, 5.2-6.8 worst order
- * mcspdr2 stck in order, worst order
- * mcspdro stck 4-3.4.3 in order, 4.2-4.5 worst order
- * mcspdro-vcctx 4.8-7.0 in order, 5.3-6.7 worst order
- * can we see the 2 humps?
- * mcspdr 1CL yes but less, varied, etc
- * mcspdr2 no
+ * Here's some rough numbers of the different styles for qnodes on c89.
+ * 'in order' is VCn->PC(n+1) (0->1, 1->2). Worst order is with even VCs
+ * on one socket, odds on the other. the number of CLs is the size of a
+ * qnode. mcspdr is the new style (called mcspdrs in some places in this
+ * document), with lock-based qnodes. mcspdr2 is the same, but with
+ * stack-based qnodes. mcspdro is the old style (bad a recovery), stack
+ * based, sometimes just called mcs-pdr
*
- * test again with worst order with prefetchers enabled
- * mcspdr 1CL 3.8-4.0 in order, 2.6-2.7 worst order
- * mcspdr 2CL 4.2-4.4 in order, 3.8-3.9 worst order
- * mcspdr 4CL 4.5-5.2 in order, 4.0-4.2 worst order
- * mcspdr 8CL 4.4-5.1 in order, 4.3-4.7 worst order
- * mcspdr 16CL 4.4-4.8 in order, 4.4-5.3 worst order
- * mcspdr2 stck 3.0-3.0 in order, 2.9-3.0 worst order
- * mcspdro stck 4.2-4.3 in order, 4.2-4.4 worst order
- * mcspdro-vcctx 5.2-6.4 in order, 5.0-5.9 worst order
- * can we see the 2 humps?
- * mcspdrs 1CL yes, clearly
- * mcspdr2 no
+ * with prefetchers disabled (MCS and DCU)
+ * mcspdr 1CL 4.8-5.4 in order, 3.8-4.2 worst order
+ * mcspdr 2CL in order, worst order
+ * mcspdr 4CL 5.2-6.0 in order, 4.7-5.3 worst order
+ * mcspdr 8CL 5.4-6.7 in order, 5.2-6.2 worst order
+ * mcspdr 16CL 5.1-5.8 in order, 5.2-6.8 worst order
+ * mcspdr2 stck in order, worst order
+ * mcspdro stck 4-3.4.3 in order, 4.2-4.5 worst order
+ * mcspdro-vcctx 4.8-7.0 in order, 5.3-6.7 worst order
+ * can we see the 2 humps?
+ * mcspdr 1CL yes but less, varied, etc
+ * mcspdr2 no
+ *
+ * test again with worst order with prefetchers enabled
+ * mcspdr 1CL 3.8-4.0 in order, 2.6-2.7 worst order
+ * mcspdr 2CL 4.2-4.4 in order, 3.8-3.9 worst order
+ * mcspdr 4CL 4.5-5.2 in order, 4.0-4.2 worst order
+ * mcspdr 8CL 4.4-5.1 in order, 4.3-4.7 worst order
+ * mcspdr 16CL 4.4-4.8 in order, 4.4-5.3 worst order
+ * mcspdr2 stck 3.0-3.0 in order, 2.9-3.0 worst order
+ * mcspdro stck 4.2-4.3 in order, 4.2-4.4 worst order
+ * mcspdro-vcctx 5.2-6.4 in order, 5.0-5.9 worst order
+ * can we see the 2 humps?
+ * mcspdrs 1CL yes, clearly
+ * mcspdr2 no
*
* PROGRAM FEATURES
- * - verbosity? vcoremap, preempts, the throughput and latency histograms?
- * - have a max workers option (0?) == max vcores
- * - would like to randomize (within bounds) the hold/delay times
- * - help avoid convoys with MCS locks
+ * - verbosity? vcoremap, preempts, the throughput and latency histograms?
+ * - have a max workers option (0?) == max vcores
+ * - would like to randomize (within bounds) the hold/delay times
+ * - help avoid convoys with MCS locks
*
* PERFORMANCE:
- * pcore control? (hyperthreading, core 0, cross socket?)
- * want some options for controlling which threads run where, or which
- * vcores are even used (like turning off hyperthreading)?
- * implement ticket spinlocks? (more fair, more effects of preempts)
- * no simple way to do PDR either, other than 'check everyone'
- * MCS vs MCSPDR vs __MCSPDR
- * MCS seems slightly better than __MCSPDR (and it should)
- * MCSPDR is a bit worse than __MCSPDR
- * - the uth_disable/enable code seems to make a difference.
- * - i see why the latencies are worse, since they have extra work
- * to do, but the internal part that contends with other cores
- * shouldn't be affected, unless there's some other thing going on.
- * Or perhaps there isn't always someone waiting for the lock?
- * - faking VC ctx mostly negates the cost of MCSPDR vs __MCSPDR
- * things that made a big diff: CL aligning the qnodes, putting qnodes
- * on stacks, reading in the vcoreid once before ensuring()
- * both MCS CAS unlocks could use some branch prediction work
- * spinpdr locks are 2-3x faster than spinlocks...
- * test, test&set vs the existing test&set, plus lots of asserts
*
- * some delay (like 10us) lowers latency while maintaining throughput
- * - makes sense esp with MCS. if you join the queue at the last
- * second, you'll measure lower latency than attempting right away
- * - also true for spinlocks
- * - we can probably figure out the max throughput (TP = f(delay)) for
- * each lock type
+ * pcore control? (hyperthreading, core 0, cross socket?)
+ * want some options for controlling which threads run where, or
+ * which vcores are even used (like turning off hyperthreading)?
+ * implement ticket spinlocks? (more fair, more effects of preempts)
+ * no simple way to do PDR either, other than 'check everyone'
+ * MCS vs MCSPDR vs __MCSPDR
+ * MCS seems slightly better than __MCSPDR (and it should)
+ * MCSPDR is a bit worse than __MCSPDR
+ * - the uth_disable/enable code seems to make a
+ * difference.
+ * - i see why the latencies are worse, since they have
+ * extra work to do, but the internal part that contends
+ * with other cores shouldn't be affected, unless there's
+ * some other thing going on. Or perhaps there isn't
+ * always someone waiting for the lock?
+ * - faking VC ctx mostly negates the cost of MCSPDR vs
+ * __MCSPDR things that made a big diff: CL aligning the
+ * qnodes, putting qnodes
+ * on stacks, reading in the vcoreid once before ensuring()
+ * both MCS CAS unlocks could use some branch prediction work
+ * spinpdr locks are 2-3x faster than spinlocks...
+ * test, test&set vs the existing test&set, plus lots of asserts
*
- * hard to get steady numbers with MCS - different runs of the same test
- * will vary in throughput by around 15-30% (e.g., MCS varying from 3k-4k
- * L/ms)
- * - happens on c89 (NUMA) and hossin (UMA)
- * - spinlocks seem a little steadier.
- * - for MCS locks, the order in which they line up across the pcores
- * will matter. like if on one run, i regularly hand off between cores
- * in the same socket and only do one cross-socket step
- * - run a lot of shorter ones to get a trend, for now
- * - might be correllated with spikes in held times (last bin)
- * - can't turn off legacy USB on c89 (SMM) - interferes with PXE
+ * some delay (like 10us) lowers latency while maintaining throughput
+ * - makes sense esp with MCS. if you join the queue at the last
+ * second, you'll measure lower latency than attempting right away
+ * - also true for spinlocks
+ * - we can probably figure out the max throughput (TP = f(delay))
+ * for each lock type
+ *
+ * hard to get steady numbers with MCS - different runs of the same test
+ * will vary in throughput by around 15-30% (e.g., MCS varying from 3k-4k
+ * L/ms)
+ * - happens on c89 (NUMA) and hossin (UMA)
+ * - spinlocks seem a little steadier.
+ * - for MCS locks, the order in which they line up across the
+ * pcores will matter. like if on one run, i regularly hand off
+ * between cores
+ * in the same socket and only do one cross-socket step
+ * - run a lot of shorter ones to get a trend, for now
+ * - might be correllated with spikes in held times (last bin)
+ * - can't turn off legacy USB on c89 (SMM) - interferes with PXE
*
* PREEMPTS:
- * better preempt record tracking?
- * i just hacked some event-intercept and timestamp code together
- * maybe put it in the event library?
- * the timestamps definitely helped debugging
+ * better preempt record tracking?
+ * i just hacked some event-intercept and timestamp code together
+ * maybe put it in the event library?
+ * the timestamps definitely helped debugging
*
- * is it true that if uthread code never spins outside a PDR lock, then it
- * doesn't need preemption IPIs? (just someone checks the event at some
- * point).
- * think so: so long as you make progress and when you aren't, you
- * check events (like if a uthread blocks on something and enters VC
- * ctx)
- * adjusting the number of workers, whether vcores or uthreads
- * - if you have more lockers than cores:
- * - spinpdr a worker will get starved (akaros) (without 2LS support)
- * - running this from uth context will cause a handle_events
- * - mcspdr will require the kernel to switch (akaros)
- * - spin (akaros) might DL (o/w nothing), (linux) poor perf
- * - mcs (akaros) will DL, (linux) poor perf
- * - poor perf (latency spikes) comes from running the wrong thread
- * sometimes
- * - deadlock comes from the lack of kernel-level context switching
- * - if we scale workers down to the number of active vcores:
- * - two things: the initial hit, and the steady state. during the
- * initial hit, we can still deadlock, since we have more lockers than
- * cores
- * - non-pdr (akaros) could deadlock in the initial hit
- * - (akaros) steady state, everything is normal (just fewer cores)
- * - how can we adjust this in linux?
- * - if know how many cores you have, then futex wait the others
- * - need some way to wake them back up
- * - if you do this in userspace, you might need something PDR-like
- * to handle when the "2LS" code gets preempted
- * - as mentioned above, the problem in akaros is that the lock/unlock
- * might be happening too fast to get into the steady-state and recover
- * from the initial preemption
- * - one of our benefits is that we can adapt in userspace, with userspace
- * knowledge, under any circumstance.
- * - we have the deadlock windows (forcing PDR).
- * - in return, we can do this adaptation in userspace
- * - and (arguably) anyone who does this in userspace will need PDR
+ * is it true that if uthread code never spins outside a PDR lock, then it
+ * doesn't need preemption IPIs? (just someone checks the event at some
+ * point).
+ * think so: so long as you make progress and when you aren't, you
+ * check events (like if a uthread blocks on something and enters VC
+ * ctx)
+ * adjusting the number of workers, whether vcores or uthreads
+ * - if you have more lockers than cores:
+ * - spinpdr a worker will get starved (akaros) (without 2LS support)
+ * - running this from uth context will cause a handle_events
+ * - mcspdr will require the kernel to switch (akaros)
+ * - spin (akaros) might DL (o/w nothing), (linux) poor perf
+ * - mcs (akaros) will DL, (linux) poor perf
+ * - poor perf (latency spikes) comes from running the wrong thread
+ * sometimes
+ * - deadlock comes from the lack of kernel-level context switching
+ * - if we scale workers down to the number of active vcores:
+ * - two things: the initial hit, and the steady state. during the
+ * initial hit, we can still deadlock, since we have more lockers than
+ * cores
+ * - non-pdr (akaros) could deadlock in the initial hit
+ * - (akaros) steady state, everything is normal (just fewer cores)
+ * - how can we adjust this in linux?
+ * - if know how many cores you have, then futex wait the others
+ * - need some way to wake them back up
+ * - if you do this in userspace, you might need something PDR-like
+ * to handle when the "2LS" code gets preempted
+ * - as mentioned above, the problem in akaros is that the lock/unlock
+ * might be happening too fast to get into the steady-state and recover
+ * from the initial preemption
+ * - one of our benefits is that we can adapt in userspace, with userspace
+ * knowledge, under any circumstance.
+ * - we have the deadlock windows (forcing PDR).
+ * - in return, we can do this adaptation in userspace
+ * - and (arguably) anyone who does this in userspace will need PDR
*
* MEASUREMENT (user/parlib/measure.c)
- * extract into its own library, for linux apps
- * print out raw TSC times? might help sync up diff timelines
- * Need more latency bins, spinlocks vary too much
- * maybe we need better high/low too, since this hist looks bad too
- * or not center on the average?
- * for printing, its hard to know without already binning.
- * maybe bin once (latency?), then use that to adjust the hist?
+ * extract into its own library, for linux apps
+ * print out raw TSC times? might help sync up diff timelines
+ * Need more latency bins, spinlocks vary too much
+ * maybe we need better high/low too, since this hist looks bad too
+ * or not center on the average?
+ * for printing, its hard to know without already binning.
+ * maybe bin once (latency?), then use that to adjust the hist?
*
- * Had this on a spinlock:
- * [ 32 - 35656] 1565231:
- * (less than 200 intermediate)
- * [ 286557 - 20404788] 65298: *
+ * Had this on a spinlock:
+ * [ 32 - 35656] 1565231:
+ * (less than 200 intermediate)
+ * [ 286557 - 20404788] 65298: *
*
- * Samples per dot: 34782
- * Total samples: 1640606
- * Avg time : 96658
- * Stdev time : 604064.440882
- * Coef Var : 6.249503
- * High coeff of var with serious outliers, adjusted bins
- * 50/75/90/99: 33079 / 33079 / 33079 / 290219 (-<860)
- * Min / Max : 32 / 20404788
- * was 50/75/90 really within 860 of each other?
+ * Samples per dot: 34782
+ * Total samples: 1640606
+ * Avg time : 96658
+ * Stdev time : 604064.440882
+ * Coef Var : 6.249503
+ * High coeff of var with serious outliers, adjusted bins
+ * 50/75/90/99: 33079 / 33079 / 33079 / 290219 (-<860)
+ * Min / Max : 32 / 20404788
+ * was 50/75/90 really within 860 of each other?
*
- * when we are preempted and don't even attempt anything, say for 10ms, it
- * actually doesn't hurt our 50/75/90/99 too much. we have a ridiculous
- * stddev and max, and high average, but there aren't any additional
- * attempts at locking to mess with the attempt-latency. Only nr_vcores
- * requests are in flight during the preemption, but we can spit out around
- * 5000 per ms when we aren't preempted.
+ * when we are preempted and don't even attempt anything, say for 10ms, it
+ * actually doesn't hurt our 50/75/90/99 too much. we have a ridiculous
+ * stddev and max, and high average, but there aren't any additional
+ * attempts at locking to mess with the attempt-latency. Only nr_vcores
+ * requests are in flight during the preemption, but we can spit out around
+ * 5000 per ms when we aren't preempted.
*
*/
@@ -455,11 +464,11 @@
#define OPT_ADJ_WORKERS 2
static struct argp_option options[] = {
- {"workers", 'w', "NUM", OPTION_NO_USAGE, "Number of threads/cores"},
+ {"workers", 'w', "NUM", OPTION_NO_USAGE, "Number of threads/cores"},
{0, 0, 0, 0, ""},
- {"loops", 'l', "NUM", OPTION_NO_USAGE, "Number of loops per worker"},
+ {"loops", 'l', "NUM", OPTION_NO_USAGE, "Number of loops per worker"},
{0, 0, 0, 0, ""},
- {"type", 't', "LOCK",OPTION_NO_USAGE, "Type of lock to use. "
+ {"type", 't', "LOCK",OPTION_NO_USAGE, "Type of lock to use. "
"Options:\n"
"\tmcs\n"
"\tmcscas\n"
@@ -469,27 +478,28 @@
"\tspin\n"
"\tspinpdr"},
{0, 0, 0, 0, "Other options (not mandatory):"},
- {"adj_workers", OPT_ADJ_WORKERS, 0, 0, "Adjust workers such that the "
+ {"adj_workers", OPT_ADJ_WORKERS, 0, 0,
+ "Adjust workers such that the "
"number of workers equals the "
"number of vcores"},
- {"vc_ctx", OPT_VC_CTX, 0, 0, "Run threads in mock-vcore context"},
+ {"vc_ctx", OPT_VC_CTX, 0, 0, "Run threads in mock-vcore context"},
{0, 0, 0, 0, ""},
- {"hold", 'h', "NSEC", 0, "nsec to hold the lock"},
- {"delay", 'd', "NSEC", 0, "nsec to delay between grabs"},
- {"print", 'p', "ROWS", 0, "Print ROWS of optional measurements"},
- {"outfile", 'o', "FILE", 0, "Print ROWS of optional measurements"},
+ {"hold", 'h', "NSEC", 0, "nsec to hold the lock"},
+ {"delay", 'd', "NSEC", 0, "nsec to delay between grabs"},
+ {"print", 'p', "ROWS", 0, "Print ROWS of optional measurements"},
+ {"outfile", 'o', "FILE", 0, "Print ROWS of optional measurements"},
{ 0 }
};
struct prog_args {
- int nr_threads;
- int nr_loops;
- int hold_time;
- int delay_time;
- int nr_print_rows;
- bool fake_vc_ctx;
- bool adj_workers;
- char *outfile_path;
+ int nr_threads;
+ int nr_loops;
+ int hold_time;
+ int delay_time;
+ int nr_print_rows;
+ bool fake_vc_ctx;
+ bool adj_workers;
+ char *outfile_path;
void *(*lock_type)(void *arg);
};
struct prog_args pargs = {0};
@@ -511,83 +521,83 @@
#define lock_func(lock_name, lock_cmd, unlock_cmd) \
void *lock_name##_thread(void *arg) \
{ \
- long thread_id = (long)arg; \
- int hold_time = ACCESS_ONCE(pargs.hold_time); \
- int delay_time = ACCESS_ONCE(pargs.delay_time); \
- int nr_loops = ACCESS_ONCE(pargs.nr_loops); \
- bool fake_vc_ctx = ACCESS_ONCE(pargs.fake_vc_ctx); \
- bool adj_workers = ACCESS_ONCE(pargs.adj_workers); \
- uint64_t pre_lock, acq_lock, un_lock; \
- struct time_stamp *this_time; \
- struct mcs_lock_qnode mcs_qnode = MCS_QNODE_INIT; \
- struct mcs_pdro_qnode pdro_qnode = MCSPDRO_QNODE_INIT; \
- int i; \
+ long thread_id = (long)arg; \
+ int hold_time = ACCESS_ONCE(pargs.hold_time); \
+ int delay_time = ACCESS_ONCE(pargs.delay_time); \
+ int nr_loops = ACCESS_ONCE(pargs.nr_loops); \
+ bool fake_vc_ctx = ACCESS_ONCE(pargs.fake_vc_ctx); \
+ bool adj_workers = ACCESS_ONCE(pargs.adj_workers); \
+ uint64_t pre_lock, acq_lock, un_lock; \
+ struct time_stamp *this_time; \
+ struct mcs_lock_qnode mcs_qnode = MCS_QNODE_INIT; \
+ struct mcs_pdro_qnode pdro_qnode = MCSPDRO_QNODE_INIT; \
+ int i; \
/* guessing a unique vcoreid for vcoreid for the __mcspdr test. if the
- * program gets preempted for that test, things may go nuts */ \
- pdro_qnode.vcoreid = thread_id + 1 % pargs.nr_threads; \
- /* Wait til all threads are created. Ideally, I'd like to busywait unless
- * absolutely critical to yield */ \
- pthread_barrier_wait(&start_test); \
- if (fake_vc_ctx) { \
- /* tells the kernel / other vcores we're in vc ctx */ \
- uth_disable_notifs(); \
- /* tricks ourselves into believing we're in vc ctx */ \
- __vcore_context = TRUE; \
- } \
- for (i = 0; i < nr_loops; i++) { \
- if (!run_locktest) \
- break; \
- pre_lock = read_tsc_serialized(); \
+ * program gets preempted for that test, things may go nuts */ \
+ pdro_qnode.vcoreid = thread_id + 1 % pargs.nr_threads; \
+ /* Wait til all threads are created. Ideally, I'd like to busywait
+ * unless absolutely critical to yield */ \
+ pthread_barrier_wait(&start_test); \
+ if (fake_vc_ctx) { \
+ /* tells the kernel / other vcores we're in vc ctx */ \
+ uth_disable_notifs(); \
+ /* tricks ourselves into believing we're in vc ctx */ \
+ __vcore_context = TRUE; \
+ } \
+ for (i = 0; i < nr_loops; i++) { \
+ if (!run_locktest) \
+ break; \
+ pre_lock = read_tsc_serialized(); \
\
- lock_cmd \
+ lock_cmd \
\
- acq_lock = read_tsc_serialized(); \
- if (hold_time) \
- ndelay(hold_time); \
+ acq_lock = read_tsc_serialized(); \
+ if (hold_time) \
+ ndelay(hold_time); \
\
- unlock_cmd \
+ unlock_cmd \
\
- un_lock = read_tsc_serialized(); \
- this_time = ×[thread_id][i]; \
- this_time->pre = pre_lock; \
- this_time->acq = acq_lock; \
- this_time->un = un_lock; \
- /* Can turn these on or off to control which samples we gather */ \
- this_time->valid = TRUE; \
- /* this_time->valid = (num_vcores() == max_vcores()); */ \
+ un_lock = read_tsc_serialized(); \
+ this_time = ×[thread_id][i]; \
+ this_time->pre = pre_lock; \
+ this_time->acq = acq_lock; \
+ this_time->un = un_lock; \
+ /* Can turn these on/off to control which samples we gather */ \
+ this_time->valid = TRUE; \
+ /* this_time->valid = (num_vcores() == max_vcores()); */ \
\
- if (delay_time) \
- ndelay(delay_time); \
- /* worker thread ids are 0..n-1. if we're one of the threads that's
- * beyond the VC count, we yield. */ \
- if (adj_workers && num_vcores() < thread_id + 1) { \
- if (fake_vc_ctx) { \
- __vcore_context = FALSE; \
- uth_enable_notifs(); \
- } \
- /* we'll come back up once we have enough VCs running */ \
- pthread_yield(); \
- if (fake_vc_ctx) { \
- uth_disable_notifs(); \
- __vcore_context = TRUE; \
- } \
- } \
- cmb(); \
- } \
- /* First thread to finish stops the test */ \
- run_locktest = FALSE; \
- if (fake_vc_ctx) { \
- __vcore_context = FALSE; \
- uth_enable_notifs(); \
- } \
- return (void*)(long)i; \
+ if (delay_time) \
+ ndelay(delay_time); \
+ /* worker thread ids are 0..n-1. if we're one of the threads
+ * that's beyond the VC count, we yield. */ \
+ if (adj_workers && num_vcores() < thread_id + 1) { \
+ if (fake_vc_ctx) { \
+ __vcore_context = FALSE; \
+ uth_enable_notifs(); \
+ } \
+ /* we'll come back up once we have enough VCs running*/\
+ pthread_yield(); \
+ if (fake_vc_ctx) { \
+ uth_disable_notifs(); \
+ __vcore_context = TRUE; \
+ } \
+ } \
+ cmb(); \
+ } \
+ /* First thread to finish stops the test */ \
+ run_locktest = FALSE; \
+ if (fake_vc_ctx) { \
+ __vcore_context = FALSE; \
+ uth_enable_notifs(); \
+ } \
+ return (void*)(long)i; \
}
#define fake_lock_func(lock_name, x1, x2) \
void *lock_name##_thread(void *arg) \
{ \
- printf("Lock " #lock_name " not supported!\n"); \
- exit(-1); \
+ printf("Lock " #lock_name " not supported!\n"); \
+ exit(-1); \
}
spinlock_t spin_lock = SPINLOCK_INITIALIZER;
@@ -681,6 +691,7 @@
void *data)
{
unsigned long my_slot = atomic_fetch_and_add(&preempt_idx, 1);
+
if (my_slot < MAX_NR_EVENT_TRACES)
preempts[my_slot] = read_tsc();
atomic_inc(&preempt_cnt);
@@ -689,6 +700,7 @@
static void trace_indir(struct event_msg *ev_msg, unsigned int ev_type,
void *data)
{
+
unsigned long my_slot = atomic_fetch_and_add(&indir_idx, 1);
if (my_slot < MAX_NR_EVENT_TRACES)
indirs[my_slot] = read_tsc();
@@ -699,6 +711,7 @@
static void print_preempt_trace(uint64_t starttsc, int nr_print_rows)
{
/* reusing nr_print_rows for the nr preempt/indirs rows as well */
+
int preempt_rows = MIN(MAX_NR_EVENT_TRACES, nr_print_rows);
if (pargs.fake_vc_ctx) {
printf("No preempt trace available when faking vc ctx\n");
@@ -711,13 +724,13 @@
printf("Preempt/Indir events:\n-----------------\n");
for (int i = 0; i < preempt_rows; i++) {
if (preempts[i])
- printf("Preempt %3d at %6llu\n", i, tsc2msec(preempts[i]
- - starttsc));
+ printf("Preempt %3d at %6llu\n",
+ i, tsc2msec(preempts[i] - starttsc));
}
for (int i = 0; i < preempt_rows; i++) {
if (indirs[i])
- printf("Indir %3d at %6llu\n", i, tsc2msec(indirs[i]
- - starttsc));
+ printf("Indir %3d at %6llu\n",
+ i, tsc2msec(indirs[i] - starttsc));
}
}
@@ -735,12 +748,12 @@
atomic_init(&indir_cnt, 0);
parlib_never_yield = TRUE;
pthread_need_tls(FALSE);
- pthread_mcp_init(); /* gives us one vcore */
+ pthread_mcp_init(); /* gives us one vcore */
register_ev_handler(EV_VCORE_PREEMPT, trace_preempt, 0);
register_ev_handler(EV_CHECK_MSGS, trace_indir, 0);
if (pargs.fake_vc_ctx) {
- /* need to disable events when faking vc ctx. since we're looping and
- * not handling events, we could run OOM */
+ /* need to disable events when faking vc ctx. since we're
+ * looping and not handling events, we could run OOM */
clear_kevent_q(EV_VCORE_PREEMPT);
clear_kevent_q(EV_CHECK_MSGS);
}
@@ -762,105 +775,106 @@
static error_t parse_opt (int key, char *arg, struct argp_state *state)
{
struct prog_args *pargs = state->input;
+
switch (key) {
- case 'w':
- pargs->nr_threads = atoi(arg);
- if (pargs->nr_threads < 0) {
- printf("Negative nr_threads...\n\n");
- argp_usage(state);
- }
+ case 'w':
+ pargs->nr_threads = atoi(arg);
+ if (pargs->nr_threads < 0) {
+ printf("Negative nr_threads...\n\n");
+ argp_usage(state);
+ }
+ break;
+ case 'l':
+ pargs->nr_loops = atoi(arg);
+ if (pargs->nr_loops < 0) {
+ printf("Negative nr_loops...\n\n");
+ argp_usage(state);
+ }
+ break;
+ case OPT_ADJ_WORKERS:
+ pargs->adj_workers = TRUE;
+ break;
+ case OPT_VC_CTX:
+ pargs->fake_vc_ctx = TRUE;
+ break;
+ case 'h':
+ pargs->hold_time = atoi(arg);
+ if (pargs->hold_time < 0) {
+ printf("Negative hold_time...\n\n");
+ argp_usage(state);
+ }
+ break;
+ case 'd':
+ pargs->delay_time = atoi(arg);
+ if (pargs->delay_time < 0) {
+ printf("Negative delay_time...\n\n");
+ argp_usage(state);
+ }
+ break;
+ case 'o':
+ pargs->outfile_path = arg;
+ break;
+ case 'p':
+ pargs->nr_print_rows = atoi(arg);
+ if (pargs->nr_print_rows < 0) {
+ printf("Negative print_rows...\n\n");
+ argp_usage(state);
+ }
+ break;
+ case 't':
+ if (!strcmp("mcs", arg)) {
+ pargs->lock_type = mcs_thread;
break;
- case 'l':
- pargs->nr_loops = atoi(arg);
- if (pargs->nr_loops < 0) {
- printf("Negative nr_loops...\n\n");
- argp_usage(state);
- }
+ }
+ if (!strcmp("mcscas", arg)) {
+ pargs->lock_type = mcscas_thread;
break;
- case OPT_ADJ_WORKERS:
- pargs->adj_workers = TRUE;
+ }
+ if (!strcmp("mcspdr", arg)) {
+ pargs->lock_type = mcspdr_thread;
break;
- case OPT_VC_CTX:
- pargs->fake_vc_ctx = TRUE;
+ }
+ if (!strcmp("mcspdro", arg)) {
+ pargs->lock_type = mcspdro_thread;
break;
- case 'h':
- pargs->hold_time = atoi(arg);
- if (pargs->hold_time < 0) {
- printf("Negative hold_time...\n\n");
- argp_usage(state);
- }
+ }
+ if (!strcmp("__mcspdro", arg)) {
+ pargs->lock_type = __mcspdro_thread;
break;
- case 'd':
- pargs->delay_time = atoi(arg);
- if (pargs->delay_time < 0) {
- printf("Negative delay_time...\n\n");
- argp_usage(state);
- }
+ }
+ if (!strcmp("spin", arg)) {
+ pargs->lock_type = spin_thread;
break;
- case 'o':
- pargs->outfile_path = arg;
+ }
+ if (!strcmp("spinpdr", arg)) {
+ pargs->lock_type = spinpdr_thread;
break;
- case 'p':
- pargs->nr_print_rows = atoi(arg);
- if (pargs->nr_print_rows < 0) {
- printf("Negative print_rows...\n\n");
- argp_usage(state);
- }
- break;
- case 't':
- if (!strcmp("mcs", arg)) {
- pargs->lock_type = mcs_thread;
- break;
- }
- if (!strcmp("mcscas", arg)) {
- pargs->lock_type = mcscas_thread;
- break;
- }
- if (!strcmp("mcspdr", arg)) {
- pargs->lock_type = mcspdr_thread;
- break;
- }
- if (!strcmp("mcspdro", arg)) {
- pargs->lock_type = mcspdro_thread;
- break;
- }
- if (!strcmp("__mcspdro", arg)) {
- pargs->lock_type = __mcspdro_thread;
- break;
- }
- if (!strcmp("spin", arg)) {
- pargs->lock_type = spin_thread;
- break;
- }
- if (!strcmp("spinpdr", arg)) {
- pargs->lock_type = spinpdr_thread;
- break;
- }
- printf("Unknown locktype %s\n\n", arg);
+ }
+ printf("Unknown locktype %s\n\n", arg);
+ argp_usage(state);
+ break;
+ case ARGP_KEY_ARG:
+ printf("Warning, extra argument %s ignored\n\n", arg);
+ break;
+ case ARGP_KEY_END:
+ if (!pargs->nr_threads) {
+ printf("Must select a number of threads.\n\n");
argp_usage(state);
break;
- case ARGP_KEY_ARG:
- printf("Warning, extra argument %s ignored\n\n", arg);
+ }
+ if (!pargs->nr_loops) {
+ printf("Must select a number of loops.\n\n");
+ argp_usage(state);
break;
- case ARGP_KEY_END:
- if (!pargs->nr_threads) {
- printf("Must select a number of threads.\n\n");
- argp_usage(state);
- break;
- }
- if (!pargs->nr_loops) {
- printf("Must select a number of loops.\n\n");
- argp_usage(state);
- break;
- }
- if (!pargs->lock_type) {
- printf("Must select a type of lock.\n\n");
- argp_usage(state);
- break;
- }
+ }
+ if (!pargs->lock_type) {
+ printf("Must select a type of lock.\n\n");
+ argp_usage(state);
break;
- default:
- return ARGP_ERR_UNKNOWN;
+ }
+ break;
+ default:
+ return ARGP_ERR_UNKNOWN;
}
return 0;
}
@@ -902,8 +916,8 @@
perror("loops_done malloc failed");
exit(-1);
}
- printf("Making %d workers of %d loops each, %sadapting workers to vcores, "
- "and %sfaking vcore context\n", nr_threads, nr_loops,
+ printf("Making %d workers, %d loops each, %sadapting workers to vcores, and %sfaking vcore context\n",
+ nr_threads, nr_loops,
pargs.adj_workers ? "" : "not ",
pargs.fake_vc_ctx ? "" : "not ");
pthread_barrier_init(&start_test, NULL, nr_threads);
@@ -920,7 +934,7 @@
}
printf("Record tracking takes %ld bytes of memory\n",
nr_threads * nr_loops * sizeof(struct time_stamp));
- os_prep_work(worker_threads, nr_threads); /* ensure we have enough VCs */
+ os_prep_work(worker_threads, nr_threads);/* ensure we have enough VCs */
/* Doing this in MCP ctx, so we might have been getting a few preempts
* already. Want to read start before the threads pass their barrier */
starttsc = read_tsc();
@@ -968,7 +982,8 @@
printf("Average number of loops done, per thread: %ld\n",
total_loops / nr_threads);
for (int i = 0; i < nr_threads; i++)
- printf("\tThread %d performed %lu loops\n", i, (long)loops_done[i]);
+ printf("\tThread %d performed %lu loops\n",
+ i, (long)loops_done[i]);
if (pargs.outfile_path) {
fprintf(outfile, "#");
@@ -977,18 +992,20 @@
fprintf(outfile, "\n");
fprintf(outfile, "# thread_id attempt pre acq(uire) un(lock) "
"tsc_overhead\n");
- fprintf(outfile, "# acquire latency: acq - pre - tsc_overhead\n");
+ fprintf(outfile,
+ "# acquire latency: acq - pre - tsc_overhead\n");
fprintf(outfile, "# hold time: un - acq - tsc_overhead\n");
fprintf(outfile, "# tsc_frequency %llu\n", get_tsc_freq());
- fprintf(outfile, "# tsc_overhead is 0 on linux, hard code it with a "
- "value from akaros\n");
+ fprintf(outfile,
+ "# tsc_overhead is 0 on linux, hard code it with a value from akaros\n");
for (int i = 0; i < nr_threads; i++) {
for (int j = 0; j < nr_loops; j++) {
struct time_stamp *ts = ×[i][j];
if (!ts->pre)
break; /* empty record */
- fprintf(outfile, "%d %d %llu %llu %llu %llu\n", i, j, ts->pre,
- ts->acq, ts->un, get_tsc_overhead());
+ fprintf(outfile, "%d %d %llu %llu %llu %llu\n",
+ i, j, ts->pre, ts->acq, ts->un,
+ get_tsc_overhead());
}
}
fclose(outfile);
diff --git a/tests/microb_test.c b/tests/microb_test.c
index 7bb1eea..fb076bf 100644
--- a/tests/microb_test.c
+++ b/tests/microb_test.c
@@ -7,12 +7,12 @@
*
* To use this, define a function of the form:
*
- * void my_test(unsigned long nr_loops)
+ * void my_test(unsigned long nr_loops)
*
* Which does some computation you wish to measure inside a loop that run
* nr_loops times. Then in microb_test(), add your function in a line such as:
*
- * test_time_ns(my_test, 100000);
+ * test_time_ns(my_test, 100000);
*
* This macro will run your test and print the results. Pick a loop amount that
* is reasonable for your operation. You can also use test_time_us() for longer
@@ -62,11 +62,12 @@
void *vctls = get_vcpd_tls_desc(vcoreid);
segdesc_t tmp = SEG(STA_W, (uint32_t)vctls, 0xffffffff, 3);
uint32_t gs = (vcoreid << 3) | 0x07;
- for (int i = 0; i < nr_loops; i++) {
+
+ for (int i = 0; i < nr_loops; i++) {
__procdata.ldt[vcoreid] = tmp;
cmb();
asm volatile("movl %0,%%gs" : : "r" (gs) : "memory");
- }
+ }
set_tls_desc(mytls);
#endif
}
@@ -75,57 +76,64 @@
void loop_overhead(unsigned long nr_loops)
{
- for (int i = 0; i < nr_loops; i++) {
+ for (int i = 0; i < nr_loops; i++) {
cmb();
- }
+ }
}
/* Runs func(loops) and returns the usec elapsed */
#define __test_time_us(func, loops) \
({ \
- struct timeval start_tv = {0}; \
- struct timeval end_tv = {0}; \
- if (gettimeofday(&start_tv, 0)) \
- perror("Start time error..."); \
- (func)((loops)); \
- if (gettimeofday(&end_tv, 0)) \
- perror("End time error..."); \
- ((end_tv.tv_sec - start_tv.tv_sec) * 1000000 + \
- (end_tv.tv_usec - start_tv.tv_usec)); \
+ struct timeval start_tv = {0}; \
+ struct timeval end_tv = {0}; \
+ \
+ if (gettimeofday(&start_tv, 0)) \
+ perror("Start time error..."); \
+ (func)((loops)); \
+ if (gettimeofday(&end_tv, 0)) \
+ perror("End time error..."); \
+ ((end_tv.tv_sec - start_tv.tv_sec) * 1000000 + \
+ (end_tv.tv_usec - start_tv.tv_usec)); \
})
/* Runs func(loops) and returns the nsec elapsed */
#define __test_time_ns(func, loops) \
({ \
- (__test_time_us((func), (loops)) * 1000); \
+ (__test_time_us((func), (loops)) * 1000); \
})
/* Runs func(loops), subtracts the loop overhead, and prints the result */
#define test_time_us(func, loops) \
({ \
- unsigned long long usec_diff; \
- usec_diff = __test_time_us((func), (loops)) - nsec_per_loop * loops / 1000;\
- printf("\"%s\" total: %lluus, per iteration: %lluus\n", #func, usec_diff, \
- usec_diff / (loops)); \
+ unsigned long long usec_diff; \
+ \
+ usec_diff = __test_time_us((func), \
+ (loops)) - nsec_per_loop * loops / 1000; \
+ printf("\"%s\" total: %lluus, per iteration: %lluus\n", #func, \
+ usec_diff, \
+ usec_diff / (loops)); \
})
/* Runs func(loops), subtracts the loop overhead, and prints the result */
#define test_time_ns(func, loops) \
({ \
- unsigned long long nsec_diff; \
- nsec_diff = __test_time_ns((func), (loops)) - nsec_per_loop * (loops); \
- printf("\"%s\" total: %lluns, per iteration: %lluns\n", #func, nsec_diff, \
- nsec_diff / (loops)); \
+ unsigned long long nsec_diff; \
+ \
+ nsec_diff = __test_time_ns((func), (loops)) - nsec_per_loop * (loops); \
+ printf("\"%s\" total: %lluns, per iteration: %lluns\n", #func, \
+ nsec_diff, \
+ nsec_diff / (loops)); \
})
static void microb_test(void)
{
unsigned long long nsec_per_loop;
+
printf("We are %sin MCP mode, running on vcore %d, pcore %d\n",
(in_multi_mode() ? "" : "not "), vcore_id(),
__get_pcoreid());
- /* We divide the overhead by loops, and later we multiply again, which drops
- * off some accuracy at the expense of usability (can do different
+ /* We divide the overhead by loops, and later we multiply again, which
+ * drops off some accuracy at the expense of usability (can do different
* iterations for different tests without worrying about recomputing the
* loop overhead). */
nsec_per_loop = __test_time_ns(loop_overhead, 100000) / 100000;
@@ -145,6 +153,7 @@
{
pthread_t child;
void *child_ret;
+
microb_test();
printf("Spawning worker thread, etc...\n");
pthread_create(&child, NULL, &worker_thread, NULL);
diff --git a/tests/misc-compat.h b/tests/misc-compat.h
index 168d1fb..08f472f 100644
--- a/tests/misc-compat.h
+++ b/tests/misc-compat.h
@@ -24,9 +24,9 @@
#define udelay(usec) usleep(usec)
#define ndelay(nsec) \
{ \
- struct timespec ts = {0, 0}; \
- ts.tv_nsec = (nsec); \
- nanosleep(&ts, 0); \
+ struct timespec ts = {0, 0}; \
+ ts.tv_nsec = (nsec); \
+ nanosleep(&ts, 0); \
}
/* not quite a normal relax, which also pauses, but this works for all archs */
diff --git a/tests/mmap.c b/tests/mmap.c
index 9f852e1..11497ce 100644
--- a/tests/mmap.c
+++ b/tests/mmap.c
@@ -67,7 +67,8 @@
exit(-1);
}
nr_pgs = MIN(nr_pgs, (ROUNDUP(statbuf.st_size, PGSIZE) >> PGSHIFT));
- addr = mmap(0, nr_pgs * PGSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ addr = mmap(0, nr_pgs * PGSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
+ 0);
if (addr == MAP_FAILED) {
perror("mmap failed");
exit(-1);
diff --git a/tests/mmap_file_vmm.c b/tests/mmap_file_vmm.c
index 418c07a..e1166b1 100644
--- a/tests/mmap_file_vmm.c
+++ b/tests/mmap_file_vmm.c
@@ -87,7 +87,7 @@
void *loc = (void*) 0x1000000;
addr = mmap(loc, nr_pgs * PGSIZE, PROT_WRITE | PROT_READ | PROT_EXEC,
- MAP_SHARED, fd, 0);
+ MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
perror("mmap failed");
exit(-1);
diff --git a/tests/mount.c b/tests/mount.c
index e22c9db..6b39ab0 100644
--- a/tests/mount.c
+++ b/tests/mount.c
@@ -40,7 +40,8 @@
}
if (argc < 2) {
- fprintf(stderr, "usage: mount [-a|-b|-c|-C] channel onto_path\n");
+ fprintf(stderr,
+ "usage: mount [-a|-b|-c|-C] channel onto_path\n");
exit(-1);
}
fd = open(argv[0], O_RDWR);
diff --git a/tests/netstat.c b/tests/netstat.c
index 99fca5a..867abfd 100644
--- a/tests/netstat.c
+++ b/tests/netstat.c
@@ -49,37 +49,37 @@
argc--, argv++;
while (argc > 0 && *argv[0] == '-') {
switch (argv[0][1]) {
- case 'i':
- justinterfaces = 1;
- break;
- case 'n':
- notrans = 1;
- break;
- case 'p':
- if (nproto >= maxproto){
- fprintf(stderr, "too many protos");
- exit(1);
- }
- if (argc < 2)
- usage("netstat");
- argc--, argv++;
- proto[nproto++] = argv[0];
- break;
- default:
+ case 'i':
+ justinterfaces = 1;
+ break;
+ case 'n':
+ notrans = 1;
+ break;
+ case 'p':
+ if (nproto >= maxproto){
+ fprintf(stderr, "too many protos");
+ exit(1);
+ }
+ if (argc < 2)
usage("netstat");
+ argc--, argv++;
+ proto[nproto++] = argv[0];
+ break;
+ default:
+ usage("netstat");
}
argc--, argv++;
}
netroot = "/net";
switch (argc) {
- case 0:
- break;
- case 1:
- netroot = argv[0];
- break;
- default:
- usage("netstat");
+ case 0:
+ break;
+ case 1:
+ netroot = argv[0];
+ break;
+ default:
+ usage("netstat");
}
if (justinterfaces) {
@@ -100,7 +100,8 @@
while ((d = readdir(dir))) {
if (strcmp(d->d_name, "ipifc") == 0)
continue;
- snprintf(buf, sizeof buf, "%s/%s/0/local", netroot, d->d_name);
+ snprintf(buf, sizeof buf, "%s/%s/0/local", netroot,
+ d->d_name);
/* access is bogus for now. */
if (1 || access(buf, 0) >= 0)
nstat(d->d_name, pip);
@@ -136,7 +137,8 @@
strncpy(port, p, sizeof(port) - 1);
port[sizeof(port) - 1] = 0;
- if (1) //if(notrans || (p = csgetvalue(netroot, "port", p, net, nil)) == nil)
+ //if(notrans || (p = csgetvalue(netroot, "port", p, net, nil)) == nil)
+ if (1)
return port;
strncpy(port, p, sizeof(port) - 1);
port[sizeof(port) - 1] = 0;
@@ -251,8 +253,9 @@
for (nip = ip; nip; nip = nip->next) {
for (lifc = nip->lifc; lifc; lifc = lifc->next)
fprintf(out, "%-12s %5d %-*I %5M %-*I %8lud %8lud %8lud %8lud\n",
- nip->dev, nip->mtu,
- l, lifc->ip, lifc->mask, l, lifc->net,
- nip->pktin, nip->pktout, nip->errin, nip->errout);
+ nip->dev, nip->mtu,
+ l, lifc->ip, lifc->mask, l, lifc->net,
+ nip->pktin, nip->pktout, nip->errin,
+ nip->errout);
}
}
diff --git a/tests/notify.c b/tests/notify.c
index df550d6..c05fe44 100644
--- a/tests/notify.c
+++ b/tests/notify.c
@@ -10,7 +10,8 @@
int pid, ev_type;
if (argc < 3) {
- printf("Usage: %s PID EV_NUM [Arg1 Arg2 0xArg3 Arg4]\n", argv[0]);
+ printf("Usage: %s PID EV_NUM [Arg1 Arg2 0xArg3 Arg4]\n",
+ argv[0]);
exit(-1);
}
pid = strtol(argv[1], 0, 10);
diff --git a/tests/peek.c b/tests/peek.c
index 2554c43..f01b04b 100644
--- a/tests/peek.c
+++ b/tests/peek.c
@@ -1,12 +1,12 @@
#include <stdio.h>
#include <stdlib.h>
-void
-main(int argc, char *argv[])
+void main(int argc, char *argv[])
{
argc--,argv++;
while (argc > 0) {
unsigned char *p = (void *)strtoul(argv[0], 0, 0);
+
printf("%p shows %02x\n", p, *p);
argc--,argv++;
}
diff --git a/tests/ping.c b/tests/ping.c
index c3386a5..71853c9 100644
--- a/tests/ping.c
+++ b/tests/ping.c
@@ -75,8 +75,7 @@
void lost(Req*, void*);
void reply(Req*, void*);
-static void
-usage(void)
+static void usage(void)
{
fprintf(stderr,
"usage: %s [-6alq] [-s msgsize] [-i millisecs] [-n #pings] dest\n",
@@ -84,24 +83,21 @@
exit(1);
}
-static void
-prlost4(uint16_t seq, void *v)
+static void prlost4(uint16_t seq, void *v)
{
struct ip4hdr *ip4 = v;
printf("lost %u: %i -> %i\n", seq, ip4->src, ip4->dst);
}
-static void
-prlost6(uint16_t seq, void *v)
+static void prlost6(uint16_t seq, void *v)
{
struct ip6hdr *ip6 = v;
printf("lost %u: %i -> %i\n", seq, ip6->src, ip6->dst);
}
-static void
-prreply4(Req *r, void *v)
+static void prreply4(Req *r, void *v)
{
struct ip4hdr *ip4 = v;
@@ -110,8 +106,7 @@
r->ttl);
}
-static void
-prreply6(Req *r, void *v)
+static void prreply6(Req *r, void *v)
{
struct ip6hdr *ip6 = v;
@@ -136,16 +131,14 @@
static struct proto *proto = &v4pr;
-struct icmphdr *
-geticmp(void *v)
+struct icmphdr *geticmp(void *v)
{
char *p = v;
return (struct icmphdr *)(p + proto->iphdrsz);
}
-void
-clean(uint16_t seq, int64_t now, void *v)
+void clean(uint16_t seq, int64_t now, void *v)
{
int ttl;
Req **l, *r;
@@ -200,8 +193,7 @@
* that isn't the friggin loopback address.
* deprecate link-local and multicast addresses.
*/
-static int
-myipvnaddr(uint8_t *ip, struct proto *proto, char *net)
+static int myipvnaddr(uint8_t *ip, struct proto *proto, char *net)
{
int ipisv4, wantv4;
struct ipifc *nifc;
@@ -232,8 +224,7 @@
return ipcmp(ip, IPnoaddr) == 0? -1: 0;
}
-void
-sender(int fd, int msglen, int interval, int n)
+void sender(int fd, int msglen, int interval, int n)
{
int i, extra;
uint16_t seq;
@@ -298,8 +289,7 @@
done = 1;
}
-void
-rcvr(int fd, int msglen, int interval, int nmsg)
+void rcvr(int fd, int msglen, int interval, int nmsg)
{
int i, n, munged;
uint16_t x;
@@ -316,7 +306,8 @@
while(lostmsgs+rcvdmsgs < nmsg){
/* arm to wake ourselves if the read doesn't connect in time */
set_awaiter_rel(&waiter, 1000 *
- ((nmsg - lostmsgs - rcvdmsgs) * interval + waittime));
+ ((nmsg - lostmsgs - rcvdmsgs) * interval
+ + waittime));
set_alarm(&waiter);
n = read(fd, buf, BUFSIZE);
/* cancel immediately, so future syscalls don't get aborted */
@@ -324,9 +315,10 @@
now = read_tsc();
if(n <= 0){ /* read interrupted - time to go */
- /* Faking time being a minute in the future, so clean marks our
- * message as lost. Note this will also end up cancelling any other
- * pending replies that would have expired by then. Whatever. */
+ /* Faking time being a minute in the future, so clean
+ * marks our message as lost. Note this will also end
+ * up cancelling any other pending replies that would
+ * have expired by then. Whatever. */
clean(0, now + MINUTETSC, NULL);
continue;
}
@@ -343,7 +335,7 @@
printf("corrupted reply\n");
x = nhgets(icmp->seq);
if(icmp->type != proto->echoreply || icmp->code != 0) {
- printf("bad type/code/sequence %d/%d/%d (want %d/%d/%d)\n",
+ printf("bad type/code/seq %d/%d/%d (want %d/%d/%d)\n",
icmp->type, icmp->code, x,
proto->echoreply, 0, x);
continue;
@@ -620,8 +612,7 @@
* receive loop, blocking all future receivers, so that their times include the
* printf time. This isn't a huge issue, since the sender sleeps between each
* one, and hopefully the print is done when the sender fires again. */
-void
-reply(Req *r, void *v)
+void reply(Req *r, void *v)
{
r->rtt /= 1000LL;
sum += r->rtt;
@@ -632,12 +623,12 @@
(*proto->prreply)(r, v);
else
printf("%3d: rtt %5lld usec, avg rtt %5lld usec, ttl = %d\n",
- r->seq - firstseq, r->rtt, sum/rcvdmsgs, r->ttl);
+ r->seq - firstseq, r->rtt, sum/rcvdmsgs,
+ r->ttl);
r->replied = 1;
}
-void
-lost(Req *r, void *v)
+void lost(Req *r, void *v)
{
if(!quiet)
if(addresses && v != NULL)
diff --git a/tests/pipetest.c b/tests/pipetest.c
index 5cec515..71ed712 100644
--- a/tests/pipetest.c
+++ b/tests/pipetest.c
@@ -7,6 +7,7 @@
void child_handler(int readfd, int writefd)
{
char c;
+
read(readfd, &c, 1);
close(readfd);
printf("Child read from pipe0\n");
@@ -23,6 +24,7 @@
sched_yield();
char c;
+
printf("Parent writing to pipe0\n");
write(writefd, "", 1);
close(writefd);
@@ -36,6 +38,7 @@
{
int pipe0[2];
int pipe1[2];
+
pipe(pipe0);
pipe(pipe1);
pid_t child = fork();
diff --git a/tests/printf-ext.c b/tests/printf-ext.c
index cc94863..1995465 100644
--- a/tests/printf-ext.c
+++ b/tests/printf-ext.c
@@ -38,6 +38,7 @@
int main(int argc, char **argv)
{
int ret;
+
if (register_printf_specifier('i', printf_ipaddr, printf_ipaddr_info))
printf("Failed to register 'i'\n");
if (register_printf_specifier('M', printf_ipmask, printf_ipmask_info))
diff --git a/tests/prov.c b/tests/prov.c
index ef2ee64..8e9cb8e 100644
--- a/tests/prov.c
+++ b/tests/prov.c
@@ -35,89 +35,90 @@
{ 0 }
};
-#define PROV_MODE_PID 1
-#define PROV_MODE_CMD 2
-#define PROV_MODE_SHOW 3
+#define PROV_MODE_PID 1
+#define PROV_MODE_CMD 2
+#define PROV_MODE_SHOW 3
struct prog_args {
- char **cmd_argv;
- int cmd_argc;
- int mode; /* PROV_MODE_ETC */
- pid_t pid;
- char res_type; /* cores (c), ram (m), etc */
- char *res_val; /* type-specific value, unparsed */
- struct core_set cores;
- bool max;
- int dummy_val_flag;
+ char **cmd_argv;
+ int cmd_argc;
+ int mode; /* PROV_MODE_ETC */
+ pid_t pid;
+ char res_type; /* cores (c), ram (m), etc */
+ char *res_val; /* type-specific value, unparsed */
+ struct core_set cores;
+ bool max;
+ int dummy_val_flag;
};
static error_t parse_opt (int key, char *arg, struct argp_state *state)
{
struct prog_args *pargs = state->input;
switch (key) {
- case 't':
- pargs->res_type = arg[0];
- if (arg[1] != '\0')
- printf("Warning, extra letters detected for -t's argument\n");
- break;
- case 'p':
- if (pargs->mode) {
- printf("Too many modes given (-p, -s, COMMAND, etc)\n\n");
- argp_usage(state);
- }
- pargs->mode = PROV_MODE_PID;
- pargs->pid = atoi(arg);
- break;
- case 's':
- if (pargs->mode) {
- printf("Too many modes given (-p, -s, COMMAND, etc)\n\n");
- argp_usage(state);
- }
- pargs->mode = PROV_MODE_SHOW;
- break;
- case 'c':
- case ARGP_KEY_ARG:
- if (pargs->mode) {
- printf("Too many modes given (-p, -s, COMMAND, etc)\n\n");
- argp_usage(state);
- }
- pargs->mode = PROV_MODE_CMD;
+ case 't':
+ pargs->res_type = arg[0];
+ if (arg[1] != '\0')
+ printf("Warning, extra letters detected for -t's argument\n");
+ break;
+ case 'p':
+ if (pargs->mode) {
+ printf("Too many modes given (-p, -s, CMD, etc)\n\n");
+ argp_usage(state);
+ }
+ pargs->mode = PROV_MODE_PID;
+ pargs->pid = atoi(arg);
+ break;
+ case 's':
+ if (pargs->mode) {
+ printf("Too many modes given (-p, -s, CMD, etc)\n\n");
+ argp_usage(state);
+ }
+ pargs->mode = PROV_MODE_SHOW;
+ break;
+ case 'c':
+ case ARGP_KEY_ARG:
+ if (pargs->mode) {
+ printf("Too many modes given (-p, -s, CMD, etc)\n\n");
+ argp_usage(state);
+ }
+ pargs->mode = PROV_MODE_CMD;
- pargs->cmd_argc = state->argc - state->next + 1;
- pargs->cmd_argv = malloc(sizeof(char*) * (pargs->cmd_argc + 1));
- assert(pargs->cmd_argv);
- pargs->cmd_argv[0] = arg;
- memcpy(&pargs->cmd_argv[1], &state->argv[state->next],
- sizeof(char*) * (pargs->cmd_argc - 1));
- pargs->cmd_argv[pargs->cmd_argc] = NULL;
- state->next = state->argc;
- break;
- case 'v':
- /* could also check to make sure we're not -s (and vice versa) */
- if (pargs->dummy_val_flag) {
- printf("Provide only -v or -m, not both\n\n");
- argp_usage(state);
- }
- pargs->dummy_val_flag = 1;
- pargs->res_val = arg;
- break;
- case 'm':
- if (pargs->dummy_val_flag) {
- printf("Provide only -v or -m, not both\n\n");
- argp_usage(state);
- }
- pargs->dummy_val_flag = 1;
- pargs->max = true;
- break;
- case ARGP_KEY_END:
- /* Make sure we selected a mode */
- if (!pargs->mode) {
- printf("No mode selected (-p, -s, etc).\n\n");
- argp_usage(state);
- }
- break;
- default:
- return ARGP_ERR_UNKNOWN;
+ pargs->cmd_argc = state->argc - state->next + 1;
+ pargs->cmd_argv = malloc(sizeof(char*) * (pargs->cmd_argc + 1));
+ assert(pargs->cmd_argv);
+ pargs->cmd_argv[0] = arg;
+ memcpy(&pargs->cmd_argv[1], &state->argv[state->next],
+ sizeof(char*) * (pargs->cmd_argc - 1));
+ pargs->cmd_argv[pargs->cmd_argc] = NULL;
+ state->next = state->argc;
+ break;
+ case 'v':
+ /* could also check to make sure we're not -s (and vice versa)
+ */
+ if (pargs->dummy_val_flag) {
+ printf("Provide only -v or -m, not both\n\n");
+ argp_usage(state);
+ }
+ pargs->dummy_val_flag = 1;
+ pargs->res_val = arg;
+ break;
+ case 'm':
+ if (pargs->dummy_val_flag) {
+ printf("Provide only -v or -m, not both\n\n");
+ argp_usage(state);
+ }
+ pargs->dummy_val_flag = 1;
+ pargs->max = true;
+ break;
+ case ARGP_KEY_END:
+ /* Make sure we selected a mode */
+ if (!pargs->mode) {
+ printf("No mode selected (-p, -s, etc).\n\n");
+ argp_usage(state);
+ }
+ break;
+ default:
+ return ARGP_ERR_UNKNOWN;
}
return 0;
}
@@ -128,28 +129,29 @@
static int prov_pid(pid_t pid, struct prog_args *pargs)
{
switch (pargs->res_type) {
- case ('c'):
- if (pargs->max) {
- parlib_get_all_core_set(&pargs->cores);
- } else {
- if (!pargs->res_val) {
- printf("Need a list of cores to provision\n");
- return -1;
- }
- parlib_parse_cores(pargs->res_val, &pargs->cores);
+ case ('c'):
+ if (pargs->max) {
+ parlib_get_all_core_set(&pargs->cores);
+ } else {
+ if (!pargs->res_val) {
+ printf("Need a list of cores to provision\n");
+ return -1;
}
- provision_core_set(pid, &pargs->cores);
- break;
- case ('m'):
- printf("Provisioning memory is not supported yet\n");
- return -1;
- break;
- default:
- if (!pargs->res_type)
- printf("No resource type selected. Use -t\n");
- else
- printf("Unsupported resource type %c\n", pargs->res_type);
- return -1;
+ parlib_parse_cores(pargs->res_val, &pargs->cores);
+ }
+ provision_core_set(pid, &pargs->cores);
+ break;
+ case ('m'):
+ printf("Provisioning memory is not supported yet\n");
+ return -1;
+ break;
+ default:
+ if (!pargs->res_type)
+ printf("No resource type selected. Use -t\n");
+ else
+ printf("Unsupported resource type %c\n",
+ pargs->res_type);
+ return -1;
}
return 0;
}
@@ -162,31 +164,32 @@
argp_parse(&argp, argc, argv, 0, 0, &pargs);
switch (pargs.mode) {
- case (PROV_MODE_PID):
- return prov_pid(pargs.pid, &pargs);
- break;
- case (PROV_MODE_CMD):
- pid = create_child_with_stdfds(pargs.cmd_argv[0], pargs.cmd_argc,
- pargs.cmd_argv, envp);
- if (pid < 0) {
- perror("Unable to spawn child");
- exit(-1);
- }
- if (prov_pid(pid, &pargs)) {
- perror("Unable to provision to child");
- sys_proc_destroy(pid, -1);
- exit(-1);
- }
- sys_proc_run(pid);
- waitpid(pid, NULL, 0);
- return 0;
- case (PROV_MODE_SHOW):
- printf("Show mode not supported yet, using ghetto interface\n\n");
- printf("Check 'dmesg' if you aren't on the console\n\n");
- sys_provision(-1, 0, 0);
- return 0;
- break;
- default:
- return -1;
+ case (PROV_MODE_PID):
+ return prov_pid(pargs.pid, &pargs);
+ break;
+ case (PROV_MODE_CMD):
+ pid = create_child_with_stdfds(pargs.cmd_argv[0],
+ pargs.cmd_argc, pargs.cmd_argv,
+ envp);
+ if (pid < 0) {
+ perror("Unable to spawn child");
+ exit(-1);
+ }
+ if (prov_pid(pid, &pargs)) {
+ perror("Unable to provision to child");
+ sys_proc_destroy(pid, -1);
+ exit(-1);
+ }
+ sys_proc_run(pid);
+ waitpid(pid, NULL, 0);
+ return 0;
+ case (PROV_MODE_SHOW):
+ printf("Show mode not supported, using ghetto interface\n\n");
+ printf("Check 'dmesg' if you aren't on the console\n\n");
+ sys_provision(-1, 0, 0);
+ return 0;
+ break;
+ default:
+ return -1;
}
}
diff --git a/tests/pthread_barrier_test.c b/tests/pthread_barrier_test.c
index dd2d303..c224324 100644
--- a/tests/pthread_barrier_test.c
+++ b/tests/pthread_barrier_test.c
@@ -20,7 +20,7 @@
{
while (!run_barriertest)
cpu_relax();
- for(int i = 0; i < nr_loops; i++) {
+ for (int i = 0; i < nr_loops; i++) {
pthread_barrier_wait(&barrier);
}
return (void*)(long)pthread_self()->id;
@@ -31,6 +31,7 @@
struct timeval start_tv = {0};
struct timeval end_tv = {0};
long usec_diff;
+
if (argc > 1)
nr_threads = strtol(argv[1], 0, 10);
if (argc > 2)
@@ -47,12 +48,12 @@
if (nr_vcores) {
/* Only do the vcore trickery if requested */
parlib_never_yield = TRUE;
- pthread_mcp_init(); /* gives us one vcore */
+ pthread_mcp_init(); /* gives us one vcore */
vcore_request_total(nr_vcores);
parlib_never_vc_request = TRUE;
for (int i = 0; i < nr_vcores; i++) {
printd("Vcore %d mapped to pcore %d\n", i,
- __procinfo.vcoremap[i].pcoreid);
+ __procinfo.vcoremap[i].pcoreid);
}
}
pthread_barrier_init(&barrier, NULL, nr_threads);
diff --git a/tests/pthread_cleanup_test.c b/tests/pthread_cleanup_test.c
index afe997d..d5c9a6b 100644
--- a/tests/pthread_cleanup_test.c
+++ b/tests/pthread_cleanup_test.c
@@ -12,16 +12,15 @@
static volatile int cleanup_pop_arg = 0;
static volatile int cnt = 0;
-static void
-cleanup_handler(void *arg)
+static void cleanup_handler(void *arg)
{
printf("Running Cleanup Handler\n");
}
-static void *
-thread_start(void *arg)
+static void *thread_start(void *arg)
{
time_t start, curr;
+
printf("Pushing Cleanup Handler\n");
pthread_cleanup_push(cleanup_handler, NULL);
while (!done)
@@ -31,8 +30,7 @@
return NULL;
}
-int
-main(int argc, char *argv[])
+int main(int argc, char *argv[])
{
pthread_t thr;
int s;
diff --git a/tests/pthread_switch.c b/tests/pthread_switch.c
index 6c013c4..d5bb46b 100644
--- a/tests/pthread_switch.c
+++ b/tests/pthread_switch.c
@@ -19,9 +19,9 @@
static void __pth_switch_cb(struct uthread *uthread, void *target)
{
- /* by not returning, this bypasses vcore entry and event checks, though when
- * we pop back out of the 2LS, we'll check notif pending. think about this
- * if you put this into your 2LS. */
+ /* by not returning, this bypasses vcore entry and event checks, though
+ * when we pop back out of the 2LS, we'll check notif pending. think
+ * about this if you put this into your 2LS. */
current_uthread = NULL;
run_uthread((struct uthread*)target);
assert(0);
@@ -44,12 +44,13 @@
pth_switch_to(other_thr);
}
if (pthread_self() == th1) {
- /* we need to break out of the switching cycle. when th2 runs again,
- * it'll know to stop. but th1 needs to both exit and switch to th2.
- * we do this by making th2 runnable by the pth schedop, then exiting */
+ /* we need to break out of the switching cycle. when th2 runs
+ * again, it'll know to stop. but th1 needs to both exit and
+ * switch to th2. we do this by making th2 runnable by the pth
+ * schedop, then exiting */
should_exit = TRUE;
- /* we also need to do this to th2 before it tries to exit, o/w we'll PF
- * in __pthread_generic_yield. */
+ /* we also need to do this to th2 before it tries to exit, o/w
+ * we'll PF in __pthread_generic_yield. */
sched_ops->thread_runnable((struct uthread*)th2);
}
return 0;
@@ -70,7 +71,7 @@
parlib_never_yield = TRUE;
parlib_never_vc_request = TRUE;
pthread_need_tls(FALSE);
- pthread_mcp_init(); /* gives us one vcore */
+ pthread_mcp_init(); /* gives us one vcore */
pthread_barrier_init(&barrier, NULL, 2);
/* each is passed the other's pthread_t. th1 starts the switching. */
diff --git a/tests/pthread_test.c b/tests/pthread_test.c
index 4eab654..e7f568d 100644
--- a/tests/pthread_test.c
+++ b/tests/pthread_test.c
@@ -45,12 +45,13 @@
/* Wait til all threads are created */
pthread_barrier_wait(&barrier);
for (int i = 0; i < nr_yield_loops; i++) {
- printf_safe("[A] pthread %d %p on vcore %d, itr: %d\n", pthread_id(),
- pthread_self(), vcore_id(), i);
- /* Fakes some work by spinning a bit. Amount varies per uth/vcore,
- * scaled by fake_work */
+ printf_safe("[A] pthread %d %p on vcore %d, itr: %d\n",
+ pthread_id(), pthread_self(), vcore_id(), i);
+ /* Fakes some work by spinning a bit. Amount varies per
+ * uth/vcore, scaled by fake_work */
if (amt_fake_work)
- udelay(amt_fake_work * (pthread_id() * (vcore_id() + 2)));
+ udelay(amt_fake_work * (pthread_id() * (vcore_id() +
+ 2)));
pthread_yield();
printf_safe("[A] pthread %p returned from yield on vcore %d, itr: %d\n",
pthread_self(), vcore_id(), i);
@@ -83,7 +84,7 @@
/* Only do the vcore trickery if requested */
parlib_never_yield = TRUE;
pthread_need_tls(FALSE);
- pthread_mcp_init(); /* gives us one vcore */
+ pthread_mcp_init(); /* gives us one vcore */
vcore_request_total(nr_vcores);
parlib_never_vc_request = TRUE;
for (int i = 0; i < nr_vcores; i++) {
@@ -115,10 +116,11 @@
uthread_join_arr(join_reqs, nr_yield_threads);
#else
for (int i = 0; i < nr_yield_threads; i++) {
- printf_safe("[A] About to join on thread %d(%p)\n", i, my_threads[i]);
+ printf_safe("[A] About to join on thread %d(%p)\n",
+ i, my_threads[i]);
pthread_join(my_threads[i], &my_retvals[i]);
- printf_safe("[A] Successfully joined on thread %d (retval: %p)\n", i,
- my_retvals[i]);
+ printf_safe("[A] Successful join on thread %d (retval: %p)\n",
+ i, my_retvals[i]);
}
#endif
if (gettimeofday(&end_tv, 0))
diff --git a/tests/query.c b/tests/query.c
index 7958a99..582d4c3 100644
--- a/tests/query.c
+++ b/tests/query.c
@@ -14,28 +14,28 @@
static int all, multiple;
char *argv0;
-#define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\
- argv[0] && argv[0][0]=='-' && argv[0][1];\
- argc--, argv++) {\
- char *_args, *_argt;\
- char _argc; \
- _args = &argv[0][1];\
- if(_args[0]=='-' && _args[1]==0){\
- argc--; argv++; break;\
- }\
- _argc = _args[0];\
- while(*_args && _args++)\
- switch(_argc)
-#define ARGEND /*SET(_argt);USED(_argt,_argc,_args);}USED(argv, argc);*/}
-#define ARGF() (_argt=_args, _args="",\
- (*_argt? _argt: argv[1]? (argc--, *++argv): 0))
-#define EARGF(x) (_argt=_args, _args="",\
- (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0)))
+#define ARGBEGIN \
+ for((argv0||(argv0=*argv)),argv++,argc--;\
+ argv[0] && argv[0][0]=='-' && argv[0][1];\
+ argc--, argv++) {\
+ char *_args, *_argt;\
+ char _argc; \
+ _args = &argv[0][1];\
+ if(_args[0]=='-' && _args[1]==0){\
+ argc--; argv++; break;\
+ }\
+ _argc = _args[0];\
+ while(*_args && _args++)\
+ switch(_argc)
+#define ARGEND /*SET(_argt);USED(_argt,_argc,_args);}USED(argv, argc);*/}
+#define ARGF() (_argt=_args, _args="",\
+ (*_argt? _argt: argv[1]? (argc--, *++argv): 0))
+#define EARGF(x)(_argt=_args, _args="",\
+ (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0)))
-#define ARGC() _argc
+#define ARGC() _argc
-void
-usage(void)
+void usage(void)
{
fprintf(stderr, "usage: query [-am] [-f ndbfile] attr value "
"[returned-attr [reps]]\n");
@@ -44,16 +44,14 @@
}
/* print values of nt's attributes matching rattr */
-static void
-prmatch(struct ndbtuple *nt, char *rattr)
+static void prmatch(struct ndbtuple *nt, char *rattr)
{
for(; nt; nt = nt->entry)
if (strcmp(nt->attr, rattr) == 0)
printf("%s\n", nt->val);
}
-void
-search(struct ndb *db, char *attr, char *val, char *rattr)
+void search(struct ndb *db, char *attr, char *val, char *rattr)
{
char *p;
struct ndbs s;
diff --git a/tests/select_server.c b/tests/select_server.c
index 0ef5e57..ec5dcaf 100644
--- a/tests/select_server.c
+++ b/tests/select_server.c
@@ -52,17 +52,17 @@
char buf[256];
/* We'll use this to see if we actually did a select instead of blocking
- * calls. It's not 100%, but with a human on the other end, it should be
- * fine. */
+ * calls. It's not 100%, but with a human on the other end, it should
+ * be fine. */
bool has_selected = FALSE;
#ifdef PLAN9NET
printf("Using Plan 9's networking stack\n");
- /* This clones a conversation (opens /net/tcp/clone), then reads the cloned
- * fd (which is the ctl) to givure out the conv number (the line), then
- * writes "announce [addr]" into ctl. This "announce" command often has a
- * "bind" in it too. plan9 bind just sets the local addr/port. TCP
- * announce also does this. Returns the ctlfd. */
+ /* This clones a conversation (opens /net/tcp/clone), then reads the
+ * cloned fd (which is the ctl) to givure out the conv number (the
+ * line), then writes "announce [addr]" into ctl. This "announce"
+ * command often has a "bind" in it too. plan9 bind just sets the local
+ * addr/port. TCP announce also does this. Returns the ctlfd. */
afd = announce9("tcp!*!23", adir, 0);
if (afd < 0) {
@@ -80,8 +80,8 @@
srv.sin_port = htons(23);
socklen_t socksize = sizeof(struct sockaddr_in);
- /* Equiv to cloning a converstation in plan 9. The shim returns the data FD
- * for the conversation. */
+ /* Equiv to cloning a converstation in plan 9. The shim returns the
+ * data FD for the conversation. */
srv_socket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
if (srv_socket < 0) {
perror("Socket failure");
@@ -90,7 +90,8 @@
/* bind + listen is equiv to announce() in plan 9. Note that the "bind"
* command is used, unlike in the plan9 announce. */
/* Binds our socket to the given addr/port in srv. */
- ret = bind(srv_socket, (struct sockaddr*)&srv, sizeof(struct sockaddr_in));
+ ret = bind(srv_socket, (struct sockaddr*)&srv, sizeof(struct
+ sockaddr_in));
if (ret < 0) {
perror("Bind failure");
return -1;
@@ -117,21 +118,24 @@
return -1;
}
/* This is a little subtle. We're putting a tap on the listen file /
- * listen_fd. When this fires, we get an event because of that listen_fd.
- * But we don't actually listen or do anything to that listen_fd. It's
- * solely for monitoring. We open a path, below, and we'll reattempt to do
- * *that* operation when someone tells us that our listen tap fires. */
+ * listen_fd. When this fires, we get an event because of that
+ * listen_fd. But we don't actually listen or do anything to that
+ * listen_fd. It's solely for monitoring. We open a path, below, and
+ * we'll reattempt to do *that* operation when someone tells us that our
+ * listen tap fires. */
FD_ZERO(&rfds);
FD_SET(listen_fd, &rfds);
has_selected = FALSE;
while (1) {
- /* Opens the conversation's listen file. This blocks til someone
- * connects. When they do, a new conversation is created, and that open
- * returned an FD for the new conv's ctl. listen() reads that to find
- * out the conv number (the line) for this new conv. listen() returns
- * the ctl for this new conv.
+ /* Opens the conversation's listen file. This blocks til
+ * someone connects. When they do, a new conversation is
+ * created, and that open returned an FD for the new conv's ctl.
+ * listen() reads that to find out the conv number (the line)
+ * for this new conv. listen() returns the ctl for this new
+ * conv.
*
- * Non-block is for the act of listening, and applies to lcfd. */
+ * Non-block is for the act of listening, and applies to lcfd.
+ * */
lcfd = listen9(adir, ldir, O_NONBLOCK);
if (lcfd >= 0)
break;
@@ -150,9 +154,9 @@
assert(has_selected);
/* No longer need listen_fd. */
close(listen_fd);
- /* Writes "accept [NUM]" into the ctlfd, then opens the conv's data file and
- * returns that fd. Writing "accept" is a noop for most of our protocols.
- * */
+ /* Writes "accept [NUM]" into the ctlfd, then opens the conv's data file
+ * and returns that fd. Writing "accept" is a noop for most of our
+ * protocols. */
dfd = accept9(lcfd, ldir);
if (dfd < 0) {
perror("Accept failure");
@@ -217,8 +221,8 @@
assert(FD_ISSET(dfd, &rfds));
/* you might get a HUP, but keep on reading! */
- /* Crazy fork tests. This will fork and let the child keep going with
- * the connection. */
+ /* Crazy fork tests. This will fork and let the child keep
+ * going with the connection. */
switch (fork()) {
case -1:
perror("Fork");
@@ -234,7 +238,7 @@
#ifdef PLAN9NET
close(dfd); /* data fd for the new conv, from listen */
- close(lcfd); /* ctl fd for the new conv, from listen */
+ close(lcfd); /* ctl fd for the new conv, from listen */
close(afd); /* ctl fd for the listening conv */
#else
close(dfd); /* new connection socket, from accept */
diff --git a/tests/signal_futex.c b/tests/signal_futex.c
index c651a1f..1ce80f8 100644
--- a/tests/signal_futex.c
+++ b/tests/signal_futex.c
@@ -16,14 +16,16 @@
// signal that comes through this handler will be noticed or processed by the
// thread.
int __sigpending = 0;
-void sig_handler(int signr) {
+void sig_handler(int signr)
+{
__sigpending = 1;
futex(&__sigpending, FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
}
// User level thread waiting on a futex to count signals
int count = 0;
-void *count_signals(void *arg) {
+void *count_signals(void *arg)
+{
while(1) {
futex(&__sigpending, FUTEX_WAIT, 0, NULL, NULL, 0);
__sync_fetch_and_add(&count, 1);
@@ -32,9 +34,11 @@
}
// Thread spamming us with signals
-void *sig_thread(void *arg) {
+void *sig_thread(void *arg)
+{
int *done = (int*)arg;
struct sigaction sigact = {.sa_handler = sig_handler, 0};
+
sigaction(SIGUSR1, &sigact, 0);
while(1) {
kill(getpid(), SIGUSR1);
@@ -46,14 +50,17 @@
int main(int argc, char **argv)
{
int done = false;
+
pthread_t pth_handle, pth_handle2;
// Spawn off a thread to spam us with signals
pthread_create(&pth_handle, NULL, &sig_thread, &done);
// Spawn off a thread to process those signals
pthread_create(&pth_handle2, NULL, &count_signals, NULL);
+
// Sleep for 3 seconds by timing out on a futex
int dummy = 0;
struct timespec timeout = {.tv_sec = 3, 0};
+
futex(&dummy, FUTEX_WAIT, 0, &timeout, NULL, 0);
// Force the signal tread to exit
cmb();
diff --git a/tests/stat.c b/tests/stat.c
index 81abf06..8a6c38a 100644
--- a/tests/stat.c
+++ b/tests/stat.c
@@ -10,12 +10,14 @@
int main(int argc, char *argv[])
{
int retval;
+
if (argc < 2) {
printf("Prints out stats for a file\n");
printf("Usage: stat FILENAME\n");
return -1;
}
struct stat st = {0};
+
retval = stat(argv[1], &st);
if (retval < 0) {
perror("Stat failed");
diff --git a/tests/strace.c b/tests/strace.c
index 40a56e7..576bb21 100644
--- a/tests/strace.c
+++ b/tests/strace.c
@@ -19,16 +19,16 @@
#include <parlib/bitmask.h>
struct strace_opts {
- FILE *outfile;
- char *trace_set;
- char **cmd_argv;
- int cmd_argc;
- int pid;
- bool follow_children;
- bool verbose;
- bool raw_output;
- bool with_time;
- bool drop_overflow;
+ FILE *outfile;
+ char *trace_set;
+ char **cmd_argv;
+ int cmd_argc;
+ int pid;
+ bool follow_children;
+ bool verbose;
+ bool raw_output;
+ bool with_time;
+ bool drop_overflow;
};
static struct strace_opts opts;
@@ -45,15 +45,15 @@
"Comma-separated list of syscalls by name (e.g. openat) and sets to trace. Use '!' to negate (might need to escape the '!'), and traces are handled in order (e.g. -e path,\\!openat)\n"
},
{" Available sets:", 0, 0, OPTION_DOC | OPTION_NO_USAGE,
- "\n"
- "- path: syscalls that take file paths\n"
- "- fd: syscalls that take FDs\n"
- "- file: path and fd sets\n"
- "- mem: memory related (mmap, shared mem)\n"
- "- life: process lifetime (create, fork)\n"
- "- proc: anything process related (yields, pop_ctxs, life)\n"
- "- sched: requests or yields to the kernel (all resources)\n"
- "- vmm: syscalls mostly for VMs\n"
+ "\n"
+ "- path: syscalls that take file paths\n"
+ "- fd: syscalls that take FDs\n"
+ "- file: path and fd sets\n"
+ "- mem: memory related (mmap, shared mem)\n"
+ "- life: process lifetime (create, fork)\n"
+ "- proc: anything process related (yields, pop_ctxs, life)\n"
+ "- sched: requests or yields to the kernel (all resources)\n"
+ "- vmm: syscalls mostly for VMs\n"
},
{0, 0, 0, 0, ""},
{"drop", 'd', 0, 0, "Drop syscalls on overflow"},
@@ -64,8 +64,8 @@
};
struct trace_set {
- char *name;
- unsigned int syscs[];
+ char *name;
+ unsigned int syscs[];
};
/* To add a trace set, create one here, add it to all_trace_sets, and update the
@@ -251,8 +251,9 @@
case 'o':
s_opts->outfile = fopen(arg, "wb");
if (!s_opts->outfile) {
- fprintf(stderr, "Unable to open file '%s' for writing: %s\n",
- arg, strerror(errno));
+ fprintf(stderr,
+ "Unable to open file '%s' for writing: %s\n",
+ arg, strerror(errno));
exit(1);
}
break;
@@ -283,7 +284,8 @@
if (s_opts->pid)
argp_error(state, "PID already set, can't launch a process too");
s_opts->cmd_argc = state->argc - state->next + 1;
- s_opts->cmd_argv = malloc(sizeof(char*) * (s_opts->cmd_argc + 1));
+ s_opts->cmd_argv = malloc(sizeof(char*) * (s_opts->cmd_argc
+ + 1));
assert(s_opts->cmd_argv);
s_opts->cmd_argv[0] = arg;
memcpy(&s_opts->cmd_argv[1], &state->argv[state->next],
@@ -294,8 +296,9 @@
case ARGP_KEY_END:
if (!(s_opts->cmd_argc || s_opts->pid))
argp_error(state, "Need either -p or a command to run");
- /* Note we never fclose outfile. It'll flush when we exit. o/w, we'll
- * need to be careful whether we're closing stderr or not. */
+ /* Note we never fclose outfile. It'll flush when we exit.
+ * o/w, we'll need to be careful whether we're closing stderr or
+ * not. */
if (!s_opts->outfile)
s_opts->outfile = stderr;
break;
@@ -380,9 +383,9 @@
continue;
if (handle_raw_syscall(tok, clear))
continue;
- /* You could imaging continuing, but this error would probably be
- * missed in the output stream and we'd be wondering why we weren't
- * getting a syscall, due to a typo. */
+ /* You could imaging continuing, but this error would probably
+ * be missed in the output stream and we'd be wondering why we
+ * weren't getting a syscall, due to a typo. */
fprintf(stderr, "Unknown trace_set argument %s, aborting!\n",
tok);
exit(-1);
@@ -402,8 +405,9 @@
{
char *close_brace;
- /* Format: E [ 13655.986589401]-[ 0.000000000] Syscall. The seconds
- * field may vary in size, so we need to find the second ']'. */
+ /* Format: E [ 13655.986589401]-[ 0.000000000] Syscall.
+ * The seconds field may vary in size, so we need to find the second
+ * ']'. */
close_brace = strchr(full_line, ']');
if (!close_brace)
return full_line;
@@ -436,12 +440,13 @@
_line = remove_timestamps(_line);
fprintf(opts.outfile, "%s", _line);
}
- /* This is a little hokey. If the process exited, then the qio hung up and
- * we got a status message from the kernel. This was the errstr of the last
- * failed read. However, if we're doing a -p and someone kills *us*, we'll
- * never see this. And catching the signal doesn't help either. The
- * process needs to exit (strace_shutdown). Either that, or change the
- * kernel to set_errstr() on close(), and coordinate with a sighandler. */
+ /* This is a little hokey. If the process exited, then the qio hung up
+ * and we got a status message from the kernel. This was the errstr of
+ * the last failed read. However, if we're doing a -p and someone kills
+ * *us*, we'll never see this. And catching the signal doesn't help
+ * either. The process needs to exit (strace_shutdown). Either that,
+ * or change the kernel to set_errstr() on close(), and coordinate with
+ * a sighandler. */
if (opts.verbose)
fprintf(stderr, "%r\n");
free(line);
@@ -466,9 +471,9 @@
perror("Unable to spawn child");
exit(-1);
}
- /* We need to wait on the child asynchronously. If we hold a ref (as
- * the parent), the child won't proc_free and that won't hangup/wake us
- * from a read. */
+ /* We need to wait on the child asynchronously. If we hold a
+ * ref (as the parent), the child won't proc_free and that won't
+ * hangup/wake us from a read. */
syscall_async(&sysc, SYS_waitpid, pid, NULL, 0, 0, 0, 0);
} else {
pid = opts.pid;
@@ -520,8 +525,9 @@
}
if (opts.cmd_argc) {
- /* now that we've set up the tracing, we can run the process. isn't it
- * great that the process doesn't immediately start when you make it? */
+ /* now that we've set up the tracing, we can run the process.
+ * isn't it great that the process doesn't immediately start
+ * when you make it? */
sys_proc_run(pid);
}
diff --git a/tests/testclone.c b/tests/testclone.c
index b79a0b7..714b00b 100644
--- a/tests/testclone.c
+++ b/tests/testclone.c
@@ -17,6 +17,7 @@
{
int iter = 1000;
char *name = "/net/tcp/clone";
+
if (argc > 1)
iter = atoi(argv[1]);
if (argc > 2)
diff --git a/tests/timerfd.c b/tests/timerfd.c
index 0c34887..53535e1 100644
--- a/tests/timerfd.c
+++ b/tests/timerfd.c
@@ -286,7 +286,8 @@
ret = read(tfd, &uticks, sizeof(uticks));
unset_alarm(&waiter);
if (ret > 0) {
- fprintf(stdout, "Failed to block when we should have!\n");
+ fprintf(stdout,
+ "Failed to block when we should have!\n");
exit(-1);
}
fprintf(stdout, "done (still success)\n");
diff --git a/tests/trandom.c b/tests/trandom.c
index ad21112..abf1b50 100644
--- a/tests/trandom.c
+++ b/tests/trandom.c
@@ -44,10 +44,11 @@
}
if (gettimeofday(&end_tv, 0))
perror("End time error...");
- usecs = (end_tv.tv_sec - start_tv.tv_sec)*1000000 + (end_tv.tv_usec - start_tv.tv_usec);
+ usecs = (end_tv.tv_sec - start_tv.tv_sec) * 1000000
+ + (end_tv.tv_usec - start_tv.tv_usec);
printf("Read %d bytes of random in %d microseconds\n", amt, usecs);
for(i = 0; i < 4; i++)
printf("%08x ", data[i]);
printf("\n");
-
+ return 0;
}
diff --git a/tests/ttcp.c b/tests/ttcp.c
index cd25622..aa5e502 100644
--- a/tests/ttcp.c
+++ b/tests/ttcp.c
@@ -59,6 +59,7 @@
{
int cnt, rlen = 0;
char *b = buf;
+
for (;;) {
cnt = read(fd, b, len);
ncalls++;
@@ -77,6 +78,7 @@
{
int cnt, rlen = 0;
char *b = buf;
+
for (;;) {
cnt = write(fd, b, len);
ncalls++;
@@ -96,6 +98,7 @@
int i;
char ch = ' ';
char *b = buf;
+
for (i = 0; i < buflen; i++) {
*b++ = ch++;
if (ch == 127)
@@ -146,7 +149,8 @@
fprintf(stderr, "ttcp-r: buflen=%d, nbuf=%d, port=%s %s\n",
buflen, nbuf, port, udp ? "udp" : "tcp");
- ds = netmkaddr(addr, udp ? "udp" : "tcp", port, ds_store, sizeof(ds_store));
+ ds = netmkaddr(addr, udp ? "udp" : "tcp", port, ds_store,
+ sizeof(ds_store));
acfd = announce9(ds, adir, 0);
if (acfd < 0)
sysfatal("announce: %r");
@@ -171,13 +175,15 @@
while ((cnt = nread(fd, buf, buflen)) > 0)
nbytes += cnt;
} else {
- while ((cnt = nread(fd, buf, buflen)) > 0 && write(1, buf, cnt) == cnt)
+ while ((cnt = nread(fd, buf, buflen)) > 0
+ && write(1, buf, cnt) == cnt)
nbytes += cnt;
}
elapsed = (nsec() - now) / 1E9;
tput = rate(nbytes, elapsed); /* also sets 'unit' */
- fprintf(stderr, "ttcp-r: %lld bytes in %.2f real seconds = %.2f %s/sec\n",
+ fprintf(stderr,
+ "ttcp-r: %lld bytes in %.2f real seconds = %.2f %s/sec\n",
nbytes, elapsed, tput, unit);
}
@@ -210,13 +216,15 @@
while (nbuf-- && nwrite(fd, buf, buflen) == buflen)
nbytes += buflen;
} else {
- while ((cnt = read(0, buf, buflen)) > 0 && nwrite(fd, buf, cnt) == cnt)
+ while ((cnt = read(0, buf, buflen)) > 0
+ && nwrite(fd, buf, cnt) == cnt)
nbytes += cnt;
}
elapsed = (nsec() - now) / 1E9;
tput = rate(nbytes, elapsed); /* also sets 'unit' */
- fprintf(stderr, "ttcp-t: %lld bytes in %.2f real seconds = %.2f %s/sec\n",
+ fprintf(stderr,
+ "ttcp-t: %lld bytes in %.2f real seconds = %.2f %s/sec\n",
nbytes, elapsed, tput, unit);
}
diff --git a/tests/turbo.c b/tests/turbo.c
index 80e39db..57978c1 100644
--- a/tests/turbo.c
+++ b/tests/turbo.c
@@ -35,14 +35,14 @@
{ 0 }
};
-#define PROG_CMD_ENABLE 1
-#define PROG_CMD_DISABLE 2
-#define PROG_CMD_STATUS 3
+#define PROG_CMD_ENABLE 1
+#define PROG_CMD_DISABLE 2
+#define PROG_CMD_STATUS 3
#define PROG_CMD_PRINT_RATIO 4
-#define PROG_CMD_ZERO_RATIO 5
+#define PROG_CMD_ZERO_RATIO 5
struct prog_opts {
- int cmd;
+ int cmd;
};
static int num_cores;
@@ -54,35 +54,35 @@
switch (key) {
case 'e':
if (p_opts->cmd) {
- fprintf(stderr, "Too many commands; just one allowed.\n\n");
+ fprintf(stderr, "Too many commands; one allowed.\n\n");
argp_usage(state);
}
p_opts->cmd = PROG_CMD_ENABLE;
break;
case 'd':
if (p_opts->cmd) {
- fprintf(stderr, "Too many commands; just one allowed.\n\n");
+ fprintf(stderr, "Too many commands; one allowed.\n\n");
argp_usage(state);
}
p_opts->cmd = PROG_CMD_DISABLE;
break;
case 's':
if (p_opts->cmd) {
- fprintf(stderr, "Too many commands; just one allowed.\n\n");
+ fprintf(stderr, "Too many commands; one allowed.\n\n");
argp_usage(state);
}
p_opts->cmd = PROG_CMD_STATUS;
break;
case 'r':
if (p_opts->cmd) {
- fprintf(stderr, "Too many commands; just one allowed.\n\n");
+ fprintf(stderr, "Too many commands; one allowed.\n\n");
argp_usage(state);
}
p_opts->cmd = PROG_CMD_PRINT_RATIO;
break;
case 'z':
if (p_opts->cmd) {
- fprintf(stderr, "Too many commands; just one allowed.\n\n");
+ fprintf(stderr, "Too many commands; one allowed.\n\n");
argp_usage(state);
}
p_opts->cmd = PROG_CMD_ZERO_RATIO;
@@ -136,8 +136,8 @@
perror("pread MSR_PERF_CTL");
exit(-1);
}
- /* The assumption here is that all cores have the same MSR value. Changing
- * this would require changing the wrmsr kernel interface. */
+ /* The assumption here is that all cores have the same MSR value.
+ * Changing this would require changing the wrmsr kernel interface. */
msr_val = buf[0];
if (enable)
msr_val &= ~(1ULL << 32);
@@ -148,7 +148,8 @@
perror("pwrite MSR_PERF_CTL");
exit(-1);
}
- printf("%s turbo mode for all cores\n", enable ? "Enabled" : "Disabled");
+ printf("%s turbo mode for all cores\n",
+ enable ? "Enabled" : "Disabled");
free(buf);
close(fd);
return 0;
@@ -172,8 +173,8 @@
perror("pread MSR_PERF_CTL");
exit(-1);
}
- /* The assumption here is that all cores have the same MSR value. Changing
- * this would require changing the wrmsr kernel interface. */
+ /* The assumption here is that all cores have the same MSR value.
+ * Changing this would require changing the wrmsr kernel interface. */
msr_val = buf[0];
printf("Turbo mode is %s for all cores\n", msr_val & (1ULL << 32) ?
"disabled" : "enabled");
@@ -207,7 +208,8 @@
mperf_buf = malloc(buf_sz);
aperf_buf = malloc(buf_sz);
assert(mperf_buf && aperf_buf);
- /* ideally these reads happen with no interference/interrupts in between */
+ /* ideally these reads happen with no interference/interrupts in between
+ */
ret = pread(fd, mperf_buf, buf_sz, MSR_IA32_MPERF);
if (ret < 0) {
perror("pread MSR_MPERF");
@@ -219,7 +221,8 @@
exit(-1);
}
for (int i = 0; i < num_cores; i++)
- printf("Core %3d: %4f%\n", i, 100.0 * aperf_buf[i] / mperf_buf[i]);
+ printf("Core %3d: %4f%\n", i,
+ 100.0 * aperf_buf[i] / mperf_buf[i]);
free(mperf_buf);
free(aperf_buf);
close(fd);
@@ -269,7 +272,7 @@
case PROG_CMD_ZERO_RATIO:
return zero_turbo_ratio();
default:
- fprintf(stderr, "Unhandled options (argp should catch this)!\n");
+ fprintf(stderr, "Unhandled cmd (argp should catch this)!\n");
return -1;
};
}
diff --git a/tests/usleep.c b/tests/usleep.c
index 8e2a4b4..946e2a4 100644
--- a/tests/usleep.c
+++ b/tests/usleep.c
@@ -5,6 +5,7 @@
int main(int argc, char **argv)
{
int sleep_time;
+
if (argc < 2) {
printf("Usage: %s MICROSEC\n", argv[0]);
exit(-1);
diff --git a/tests/vmm/vmrunkernel.c b/tests/vmm/vmrunkernel.c
index 9b73173..7934257 100644
--- a/tests/vmm/vmrunkernel.c
+++ b/tests/vmm/vmrunkernel.c
@@ -361,7 +361,8 @@
void init_timer_alarms(void)
{
for (uint64_t i = 0; i < vm->nr_gpcs; i++) {
- struct alarm_waiter *timer_alarm = malloc(sizeof(struct alarm_waiter));
+ struct alarm_waiter *timer_alarm =
+ malloc(sizeof(struct alarm_waiter));
struct guest_thread *gth = gpcid_to_gth(vm, i);
/* TODO: consider a struct to bundle a bunch of things, not just
@@ -463,7 +464,8 @@
case 'g': /* greedy */
parlib_never_yield = TRUE;
if (is_scp) {
- fprintf(stderr, "Can't be both greedy and an SCP\n");
+ fprintf(stderr,
+ "Can't be both greedy and an SCP\n");
exit(1);
}
is_greedy = TRUE;
@@ -471,7 +473,8 @@
case 's': /* scp */
parlib_wants_to_be_mcp = FALSE;
if (is_greedy) {
- fprintf(stderr, "Can't be both greedy and an SCP\n");
+ fprintf(stderr,
+ "Can't be both greedy and an SCP\n");
exit(1);
}
is_scp = TRUE;
@@ -485,7 +488,8 @@
case 'k': /* specify file to get cmdline args from */
cmdline_fd = open(optarg, O_RDONLY);
if (cmdline_fd < 0) {
- fprintf(stderr, "failed to open file: %s\n", optarg);
+ fprintf(stderr, "failed to open file: %s\n",
+ optarg);
exit(1);
}
if (stat(optarg, &stat_result) == -1) {
@@ -519,7 +523,8 @@
// Sadly, the getopt_long struct does
// not have a pointer to help text.
for (int i = 0;
- i < sizeof(long_options)/sizeof(long_options[0]) - 1;
+ i <
+ sizeof(long_options) / sizeof(long_options[0]) - 1;
i++) {
struct option *l = &long_options[i];
@@ -531,12 +536,14 @@
}
if (strlen(cmdline_default) == 0) {
- fprintf(stderr, "WARNING: No command line parameter file specified.\n");
+ fprintf(stderr,
+ "WARNING: No command line parameter file specified.\n");
}
argc -= optind;
argv += optind;
if (argc < 1) {
- fprintf(stderr, "Usage: %s vmimage [-n (no vmcall printf)]\n", argv[0]);
+ fprintf(stderr, "Usage: %s vmimage [-n (no vmcall printf)]\n",
+ argv[0]);
exit(1);
}
@@ -572,7 +579,8 @@
if (initrd) {
initrd_start = ROUNDUP(kernel_max_address, PGSIZE);
- fprintf(stderr, "kernel_max_address is %#p; Load initrd @ %#p\n",
+ fprintf(stderr,
+ "kernel_max_address is %#p; Load initrd @ %#p\n",
kernel_max_address, initrd_start);
initrd_size = setup_initrd(initrd, (void *)initrd_start,
memend - initrd_start + 1);
@@ -593,8 +601,8 @@
* unbacked EPT page: accesses to this page will cause a page fault that
* traps to the host, which will examine the fault, see it was for the
* known MMIO address, and fulfill the MMIO read or write on the guest's
- * behalf accordingly. We place the virtio space at 512 GB higher than the
- * guest physical memory to avoid a full page table walk. */
+ * behalf accordingly. We place the virtio space at 512 GB higher than
+ * the guest physical memory to avoid a full page table walk. */
uintptr_t virtio_mmio_base_addr_hint;
uintptr_t virtio_mmio_base_addr;
@@ -603,7 +611,8 @@
bp->e820_map[bp->e820_entries - 1].size),
PML4_PTE_REACH);
- /* mmap with prot_none so we don't accidentally mmap something else here.
+ /* mmap with prot_none so we don't accidentally mmap something else
+ * here.
* We give space for 512 devices right now.
* TODO(ganshun): Make it dynamic based on number of virtio devices. */
virtio_mmio_base_addr =
@@ -611,7 +620,8 @@
PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (!virtio_mmio_base_addr || virtio_mmio_base_addr >= BRK_START) {
- /* Either we were unable to mmap at all or we mapped it too high. */
+ /* Either we were unable to mmap at all or we mapped it too
+ * high. */
panic("Unable to mmap protect space for virtio devices, got 0x%016x",
virtio_mmio_base_addr);
}
@@ -656,9 +666,8 @@
/* Append all the virtio mmio base addresses. */
- /* Since the lower number irqs are no longer being used, the irqs
- * can now be assigned starting from 0.
- */
+ /* Since the lower number irqs are no longer being used, the
+ * irqs can now be assigned starting from 0. */
vm->virtio_mmio_devices[i]->irq = i;
len = snprintf(cmdlinep, cmdlinesz,
"\n virtio_mmio.device=1K@0x%llx:%lld",
@@ -677,7 +686,8 @@
"\n maxcpus=%lld\n possible_cpus=%lld", vm->nr_gpcs,
vm->nr_gpcs);
if (len >= cmdlinesz) {
- fprintf(stderr, "Too many arguments to the linux command line.");
+ fprintf(stderr,
+ "Too many arguments to the linux command line.");
exit(1);
}
cmdlinesz -= len;
diff --git a/tests/xmm.c b/tests/xmm.c
index 298eb30..27d917d 100644
--- a/tests/xmm.c
+++ b/tests/xmm.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2014 The Regents of the University of California
- * Kevin KLues <klueska@cs.berkeley.edu>
+ * Kevin Klues <klueska@cs.berkeley.edu>
* See LICENSE for details.
*
* xmm_test: test the reading/writing of the xmm registers */
@@ -15,7 +15,7 @@
static void read_xmm(int id)
{
char array[16*16] __attribute__((aligned(128))) = {0};
- asm volatile (
+ asm volatile (
"movdqa %%xmm0, %0;"
"movdqa %%xmm1, %1;"
"movdqa %%xmm2, %2;"
@@ -49,12 +49,13 @@
"=m"(array[14*16]),
"=m"(array[15*16])
:
- :
- );
+ :
+ );
for (int i=0; i<16; i++) {
int *addr = (int*)(array + i*16);
if (*addr != id) {
- printf("ERROR: xmm%d, id: %d, *addr: %d\n", i, id, *addr);
+ printf("ERROR: xmm%d, id: %d, *addr: %d\n",
+ i, id, *addr);
abort();
}
}
@@ -63,6 +64,7 @@
static void write_xmm(int __id)
{
char id[16] __attribute__((aligned(128)));
+
*((int*)id) = __id;
asm volatile (
"movdqa %0, %%xmm0;"
@@ -83,7 +85,7 @@
"movdqa %0, %%xmm15;"
:
:"m"(id[0])
- :"%xmm0","%xmm1","%xmm2","%xmm3",
+ :"%xmm0","%xmm1","%xmm2","%xmm3",
"%xmm4","%xmm5","%xmm6","%xmm7",
"%xmm8","%xmm9","%xmm10","%xmm11",
"%xmm12","%xmm13","%xmm14","%xmm15"
@@ -105,7 +107,8 @@
enable_pvcalarms(PVCALARM_REAL, 10000, nothing);
for (int i=0; i<NUM_THREADS; i++)
- pthread_create(&children[i], NULL, &worker_thread, (void*)(long)i+2);
+ pthread_create(&children[i], NULL, &worker_thread,
+ (void*)(long)i + 2);
worker_thread((void*)(long)1);
return 0;
}
diff --git a/tools/apps/ipconfig/dhcp.h b/tools/apps/ipconfig/dhcp.h
index 3dfa5be..782533f 100644
--- a/tools/apps/ipconfig/dhcp.h
+++ b/tools/apps/ipconfig/dhcp.h
@@ -9,13 +9,13 @@
// Dynamic Host Configuration Protocol / BOOTP
enum {
- OfferTimeout = 60, // when an offer times out
- MaxLease = 60 * 60, // longest lease for dynamic binding
- MinLease = 15 * 60, // shortest lease for dynamic binding
+ OfferTimeout = 60, // when an offer times out
+ MaxLease = 60 * 60, // longest lease for dynamic binding
+ MinLease = 15 * 60, // shortest lease for dynamic binding
StaticLease = 30 * 60, // lease for static binding
- IPUDPHDRSIZE = 28, // size of an IP plus UDP header
- MINSUPPORTED = 576, // biggest IP message the client must support
+ IPUDPHDRSIZE = 28, // size of an IP plus UDP header
+ MINSUPPORTED = 576, // biggest IP message the client must support
// lengths of some bootp fields
Maxhwlen = 16,
@@ -153,20 +153,20 @@
// Udphdr (included because of structure alignment on the alpha)
uint8_t udphdr[Udphdrsize];
- uint8_t op; // opcode
- uint8_t htype; // hardware type
- uint8_t hlen; // hardware address len
- uint8_t hops; // hops
- uint8_t xid[4]; // a random number
- uint8_t secs[2]; // elapsed since client started booting
+ uint8_t op; // opcode
+ uint8_t htype; // hardware type
+ uint8_t hlen; // hardware address len
+ uint8_t hops; // hops
+ uint8_t xid[4]; // a random number
+ uint8_t secs[2]; // elapsed since client started booting
uint8_t flags[2];
- uint8_t ciaddr[IPv4addrlen]; // client IP address (client tells server)
- uint8_t yiaddr[IPv4addrlen]; // client IP address (server tells client)
+ uint8_t ciaddr[IPv4addrlen]; // client IP address (client tells server)
+ uint8_t yiaddr[IPv4addrlen]; // client IP address (server tells client)
uint8_t siaddr[IPv4addrlen]; // server IP address
uint8_t giaddr[IPv4addrlen]; // gateway IP address
- uint8_t chaddr[Maxhwlen]; // client hardware address
- char sname[64]; // server host name (optional)
- char file[Maxfilelen]; // boot file name
+ uint8_t chaddr[Maxhwlen]; // client hardware address
+ char sname[64]; // server host name (optional)
+ char file[Maxfilelen]; // boot file name
uint8_t optmagic[4];
uint8_t optdata[Maxoptlen];
};
diff --git a/tools/apps/ipconfig/ipconfig.h b/tools/apps/ipconfig/ipconfig.h
index f34620d..b593aca 100644
--- a/tools/apps/ipconfig/ipconfig.h
+++ b/tools/apps/ipconfig/ipconfig.h
@@ -12,10 +12,10 @@
char *type;
char *dev;
char mpoint[32];
- int cfd; // ifc control channel
- int dfd; // ifc data channel (for ppp)
+ int cfd; // ifc control channel
+ int dfd; // ifc data channel (for ppp)
char *cputype;
- uint8_t hwa[32]; // hardware address
+ uint8_t hwa[32]; // hardware address
int hwatype;
int hwalen;
uint8_t cid[32];
@@ -42,10 +42,10 @@
char hostname[32];
char domainname[64];
uint8_t server[IPaddrlen]; // server IP address
- uint32_t offered; // offered lease time
- uint32_t lease; // lease time
- uint32_t resend; // # of resends for current state
- uint32_t timeout; // time to timeout - seconds
+ uint32_t offered; // offered lease time
+ uint32_t lease; // lease time
+ uint32_t resend; // # of resends for current state
+ uint32_t timeout; // time to timeout - seconds
//
// IPv6
@@ -59,25 +59,25 @@
uint8_t recvra;
uint8_t mflag;
uint8_t oflag;
- int maxraint; // rfc2461, p.39:
- // 4sec ≤ maxraint ≤ 1800sec, def 600
- int minraint; // 3sec ≤ minraint ≤ 0.75*maxraint
+ int maxraint; // rfc2461, p.39:
+ // 4sec ≤ maxraint ≤ 1800sec, def 600
+ int minraint; // 3sec ≤ minraint ≤ 0.75*maxraint
int linkmtu;
- int reachtime; // 3,600,000 msec, default 0
- int rxmitra; // default 0
- int ttl; // default 0 (unspecified)
+ int reachtime; // 3,600,000 msec, default 0
+ int rxmitra; // default 0
+ int ttl; // default 0 (unspecified)
// default gateway params
uint8_t v6gaddr[IPaddrlen];
- int routerlt; // router life time
+ int routerlt; // router life time
// prefix related
uint8_t v6pref[IPaddrlen];
int prefixlen;
- uint8_t onlink; // flag: address is `on-link'
- uint8_t autoflag; // flag: autonomous
- uint32_t validlt; // valid lifetime (seconds)
- uint32_t preflt; // preferred lifetime (seconds)
+ uint8_t onlink; // flag: address is `on-link'
+ uint8_t autoflag; // flag: autonomous
+ uint32_t validlt; // valid lifetime (seconds)
+ uint32_t preflt; // preferred lifetime (seconds)
};
struct ctl {
@@ -199,10 +199,10 @@
};
struct routersol {
- uint8_t vcf[4]; // version:4, traffic class:8, flow label:20
- uint8_t ploadlen[2]; // payload length: packet length - 40
- uint8_t proto; // next header type
- uint8_t ttl; // hop limit
+ uint8_t vcf[4]; // version:4, traffic class:8, flow label:20
+ uint8_t ploadlen[2]; // payload length: packet length - 40
+ uint8_t proto; // next header type
+ uint8_t ttl; // hop limit
uint8_t src[IPaddrlen];
uint8_t dst[IPaddrlen];
uint8_t type;
@@ -212,10 +212,10 @@
};
struct routeradv {
- uint8_t vcf[4]; // version:4, traffic class:8, flow label:20
- uint8_t ploadlen[2]; // payload length: packet length - 40
- uint8_t proto; // next header type
- uint8_t ttl; // hop limit
+ uint8_t vcf[4]; // version:4, traffic class:8, flow label:20
+ uint8_t ploadlen[2]; // payload length: packet length - 40
+ uint8_t proto; // next header type
+ uint8_t ttl; // hop limit
uint8_t src[IPaddrlen];
uint8_t dst[IPaddrlen];
uint8_t type;
diff --git a/tools/apps/ipconfig/ipv6.c b/tools/apps/ipconfig/ipv6.c
index fe60a26..58143fd 100644
--- a/tools/apps/ipconfig/ipv6.c
+++ b/tools/apps/ipconfig/ipv6.c
@@ -218,7 +218,8 @@
switch (otype) {
default:
- n += snprintf(buf + n, size - n, " option=%s ", optname(otype));
+ n += snprintf(buf + n, size - n, " option=%s ",
+ optname(otype));
case V6nd_srclladdr:
case V6nd_targlladdr:
if (pktsz < osz || osz != 8) {
@@ -284,7 +285,8 @@
switch (h->type) {
case RouterSolicit:
ps += 8;
- n += snprintf(buf + n, size - n, " unused=%1.1d ", NetL(a) != 0);
+ n += snprintf(buf + n, size - n, " unused=%1.1d ",
+ NetL(a) != 0);
opt_sprint(ps, pe, buf + n, size - n);
break;
case RouterAdvert:
@@ -319,10 +321,12 @@
evexit(-1);
}
- n = snprintf(cmsg, sizeof(cmsg), "connect %R!%d!r %d", dst, dport, dport);
+ n = snprintf(cmsg, sizeof(cmsg), "connect %R!%d!r %d", dst, dport,
+ dport);
m = write(cfd, cmsg, n);
if (m < n) {
- fprintf(stderr, "dialicmp: can't write %s to %s: %r", cmsg, name);
+ fprintf(stderr, "dialicmp: can't write %s to %s: %r", cmsg,
+ name);
evexit(-1);
}
@@ -344,7 +348,8 @@
n = sizeof(hdrs) - 1;
if (write(cfd, hdrs, n) < n) {
- fprintf(stderr, "dialicmp: can't write `%s' to %s: %r", hdrs, name);
+ fprintf(stderr, "dialicmp: can't write `%s' to %s: %r", hdrs,
+ name);
evexit(-1);
}
*ctlfd = cfd;
@@ -363,7 +368,8 @@
if (autoconf) {
// create link-local addr
if (myetheraddr(ethaddr, conf.dev) < 0) {
- fprintf(stderr, "myetheraddr w/ %s failed: %r", conf.dev);
+ fprintf(stderr, "myetheraddr w/ %s failed: %r",
+ conf.dev);
evexit(-1);
}
ea2lla(conf.laddr, ethaddr);
@@ -381,7 +387,8 @@
if (validip(conf.raddr)) {
n += snprintf(buf + n, sizeof(buf) - n, " %R", conf.raddr);
if (conf.mtu != 0)
- n += snprintf(buf + n, sizeof(buf) - n, " %d", conf.mtu);
+ n += snprintf(buf + n, sizeof(buf) - n, " %d",
+ conf.mtu);
}
if (write(conf.cfd, buf, n) < 0) {
@@ -422,11 +429,14 @@
if (dupfound)
doremove();
else {
- n = snprintf(buf, sizeof(buf), "add %R %M", conf.laddr, conf.mask);
+ n = snprintf(buf, sizeof(buf), "add %R %M", conf.laddr,
+ conf.mask);
if (validip(conf.raddr)) {
- n += snprintf(buf + n, sizeof(buf) - n, " %R", conf.raddr);
+ n += snprintf(buf + n, sizeof(buf) - n, " %R",
+ conf.raddr);
if (conf.mtu != 0)
- n += snprintf(buf + n, sizeof(buf) - n, " %d", conf.mtu);
+ n += snprintf(buf + n, sizeof(buf) - n, " %d",
+ conf.mtu);
}
write(conf.cfd, buf, n);
}
@@ -463,8 +473,8 @@
if (write(fd, rs, sizeof(buff)) < sizeof(buff))
ralog("sendrs: write failed, pkt size %d", sizeof(buff));
else
- ralog("sendrs: sent solicitation to %R from %R on %s", rs->dst, rs->src,
- conf.dev);
+ ralog("sendrs: sent solicitation to %R from %R on %s", rs->dst,
+ rs->src, conf.dev);
}
/*
@@ -507,7 +517,8 @@
snprintf(cfg, sizeof(cfg),
"ra6 sendra %d recvra %d maxraint %d minraint %d linkmtu %d",
- cf->sendra, cf->recvra, cf->maxraint, cf->minraint, cf->linkmtu);
+ cf->sendra, cf->recvra, cf->maxraint, cf->minraint,
+ cf->linkmtu);
ewrite(cf->cfd, cfg);
}
@@ -571,15 +582,16 @@
snprintf(abuf, sizeof(abuf), "%s/arp", conf.mpoint);
arpfd = open(abuf, O_WRONLY);
if (arpfd < 0) {
- ralog("recvrahost: couldn't open %s to write: %r", abuf);
+ ralog("recvrahost: couldn't open %s to write: %r",
+ abuf);
return;
}
- n = snprintf(abuf, sizeof(abuf), "add ether %R %E", ra->src,
- llao->lladdr);
+ n = snprintf(abuf, sizeof(abuf), "add ether %R %E",
+ ra->src, llao->lladdr);
if (write(arpfd, abuf, n) < n)
- ralog("recvrahost: couldn't write to %s/arp", conf.mpoint);
- close(arpfd);
+ ralog("recvrahost: couldn't write to %s/arp",
+ conf.mpoint); close(arpfd);
break;
case V6nd_targlladdr:
case V6nd_redirhdr:
@@ -596,7 +608,8 @@
prfo = (struct prefixopt *)&buf[m];
m += 8 * prfo->len;
if (prfo->len != 4) {
- ralog("illegal len (%d) for prefix option", prfo->len);
+ ralog("illegal len (%d) for prefix option",
+ prfo->len);
return;
}
memmove(conf.v6pref, prfo->pref, IPaddrlen);
@@ -608,8 +621,8 @@
issueadd6(&conf);
if (first) {
first = 0;
- ralog("got initial RA from %R on %s; pfx %R", ra->src, conf.dev,
- prfo->pref);
+ ralog("got initial RA from %R on %s; pfx %R",
+ ra->src, conf.dev, prfo->pref);
}
break;
default:
@@ -680,8 +693,8 @@
if (sendrscnt == 0) {
sendrscnt--;
sleepfor = 0;
- ralog("recvra6: no router advs after %d sols on %s", Maxv6rss,
- conf.dev);
+ ralog("recvra6: no router advs after %d sols on %s",
+ Maxv6rss, conf.dev);
}
continue;
}
@@ -700,7 +713,8 @@
close(fd);
evexit(0);
default:
- ralog("recvra6: unable to read router status on %s", conf.dev);
+ ralog("recvra6: unable to read router status on %s",
+ conf.dev);
break;
}
}
@@ -745,7 +759,8 @@
}
llao = (struct lladdropt *)&buf[n];
- n = snprintf(abuf, sizeof(abuf), "add ether %R %E", rs->src, llao->lladdr);
+ n = snprintf(abuf, sizeof(abuf), "add ether %R %E", rs->src,
+ llao->lladdr);
if (write(arpfd, abuf, n) < n) {
ralog("recvrs: can't write to %s/arp: %r", conf.mpoint);
close(arpfd);
@@ -799,7 +814,8 @@
/* global unicast address? */
if (!ISIPV6LINKLOCAL(lifc->ip) && !ISIPV6MCAST(lifc->ip) &&
memcmp(lifc->ip, IPnoaddr, IPaddrlen) != 0 &&
- memcmp(lifc->ip, v6loopback, IPaddrlen) != 0 && !isv4(lifc->ip)) {
+ memcmp(lifc->ip, v6loopback, IPaddrlen) != 0 &&
+ !isv4(lifc->ip)) {
memmove(prfo->pref, lifc->net, IPaddrlen);
/* hack to find prefix length */
@@ -877,7 +893,8 @@
ifc = readipifc(conf.mpoint, ifc, myifc);
if (ifc == NULL) {
- ralog("sendra6: can't read router params on %s", conf.mpoint);
+ ralog("sendra6: can't read router params on %s",
+ conf.mpoint);
continue;
}
@@ -888,7 +905,8 @@
sleepfor = Minv6interradelay + jitter();
continue;
} else {
- ralog("sendra6: sendra off, quitting on %s", conf.dev);
+ ralog("sendra6: sendra off, quitting on %s",
+ conf.dev);
evexit(0);
}
}
@@ -904,7 +922,8 @@
if (now - lastra < Minv6interradelay) {
/* too close, skip */
- sleepfor = lastra + Minv6interradelay + jitter() - now;
+ sleepfor = lastra + Minv6interradelay + jitter()
+ - now;
continue;
}
usleep(jitter() * 1000);
diff --git a/tools/apps/ipconfig/main.c b/tools/apps/ipconfig/main.c
index 286c3aa..33c5a5e 100644
--- a/tools/apps/ipconfig/main.c
+++ b/tools/apps/ipconfig/main.c
@@ -353,9 +353,11 @@
if (register_printf_specifier('E', printf_ethaddr,
printf_ethaddr_info) != 0)
fprintf(stderr, "Installing 'E' failed\n");
- if (register_printf_specifier('R', printf_ipaddr, printf_ipaddr_info) != 0)
+ if (register_printf_specifier('R', printf_ipaddr, printf_ipaddr_info) !=
+ 0)
fprintf(stderr, "Installing 'R' failed\n");
- if (register_printf_specifier('M', printf_ipmask, printf_ipmask_info) != 0)
+ if (register_printf_specifier('M', printf_ipmask, printf_ipmask_info) !=
+ 0)
fprintf(stderr, "Installing 'M' failed\n");
setnetmtpt(conf.mpoint, sizeof(conf).mpoint, NULL);
@@ -420,7 +422,8 @@
case Vtorus:
case Vtree:
case Vpkt:
- fprintf(stderr, "medium %s already specified\n", conf.type);
+ fprintf(stderr, "medium %s already specified\n",
+ conf.type);
evexit(-1);
case Vadd:
case Vremove:
@@ -664,9 +667,11 @@
for (lifc = nifc->lifc; lifc != NULL; lifc = lifc->next) {
if (ipcmp(conf.laddr, lifc->ip) != 0)
continue;
- if (validip(conf.mask) && ipcmp(conf.mask, lifc->mask) != 0)
+ if (validip(conf.mask) && ipcmp(conf.mask, lifc->mask)
+ != 0)
continue;
- if (validip(conf.raddr) && ipcmp(conf.raddr, lifc->net) != 0)
+ if (validip(conf.raddr) && ipcmp(conf.raddr, lifc->net)
+ != 0)
continue;
snprintf(file, sizeof(file), "%s/ipifc/%d/ctl",
@@ -676,7 +681,8 @@
warning("can't open %s: %r", conf.mpoint);
continue;
}
- snprintf(buf, sizeof(buf), "remove %R %M", lifc->ip, lifc->mask);
+ snprintf(buf, sizeof(buf), "remove %R %M", lifc->ip,
+ lifc->mask);
if (write(cfd, buf, strlen(buf)) != strlen(buf))
warning("can't remove %R %M from %s: %r",
lifc->ip, lifc->mask, file);
@@ -731,7 +737,8 @@
/* create a client id */
void mkclientid(void)
{
- if ((strcmp(conf.type, "ether") == 0) || (strcmp(conf.type, "gbe") == 0)) {
+ if ((strcmp(conf.type, "ether") == 0) ||
+ (strcmp(conf.type, "gbe") == 0)) {
if (myetheraddr(conf.hwa, conf.dev) == 0) {
conf.hwalen = 6;
conf.hwatype = 1;
@@ -740,8 +747,8 @@
conf.cidlen = conf.hwalen + 1;
} else {
conf.hwatype = -1;
- snprintf((char *)conf.cid, sizeof(conf).cid, "plan9_%ld.%d",
- lrand48(), getpid());
+ snprintf((char *)conf.cid, sizeof(conf).cid,
+ "plan9_%ld.%d", lrand48(), getpid());
conf.cidlen = strlen((char *)conf.cid);
}
}
@@ -797,19 +804,22 @@
snprintf(buf, sizeof(buf), "%s/ipifc/clone", conf.mpoint);
conf.cfd = open(buf, O_RDWR);
if (conf.cfd < 0) {
- fprintf(stderr, "opening %s/ipifc/clone: %r\n", conf.mpoint);
+ fprintf(stderr, "opening %s/ipifc/clone: %r\n",
+ conf.mpoint);
evexit(-1);
}
/* specify medium as ethernet, bind the interface to it */
snprintf(buf, sizeof(buf), "bind %s %s", conf.type, conf.dev);
if (write(conf.cfd, buf, strlen(buf)) != strlen(buf)) {
- fprintf(stderr, "%s: bind %s %s: %r\n", buf, conf.type, conf.dev);
+ fprintf(stderr, "%s: bind %s %s: %r\n", buf, conf.type,
+ conf.dev);
evexit(-1);
}
} else {
/* open the old interface */
- snprintf(buf, sizeof(buf), "%s/ipifc/%d/ctl", conf.mpoint, myifc);
+ snprintf(buf, sizeof(buf), "%s/ipifc/%d/ctl", conf.mpoint,
+ myifc);
conf.cfd = open(buf, O_RDWR);
if (conf.cfd < 0) {
fprintf(stderr, "open %s: %r\n", buf);
@@ -837,7 +847,8 @@
if (validip(conf.raddr)) {
n += snprintf(buf + n, sizeof(buf) - n, " %R", conf.raddr);
if (conf.mtu != 0)
- n += snprintf(buf + n, sizeof(buf) - n, " %d", conf.mtu);
+ n += snprintf(buf + n, sizeof(buf) - n, " %d",
+ conf.mtu);
}
if (write(conf.cfd, buf, n) < 0) {
@@ -928,8 +939,8 @@
}
enum {
- // This was an hour, but needs to be less for the ARM/GS1 until the timer
- // code has been cleaned up (pb).
+ // This was an hour, but needs to be less for the ARM/GS1 until the
+ // timer code has been cleaned up (pb).
Maxsleep = 450,
};
@@ -1191,7 +1202,8 @@
* The All_Aboard NAT package from Internet Share
* doesn't give a lease time, so we have to assume one.
*/
- warning("Offer with %lud lease, using %d", lease, MinLease);
+ warning("Offer with %lud lease, using %d", lease,
+ MinLease);
lease = MinLease;
}
DEBUG("lease=%lud ", lease);
@@ -1223,7 +1235,8 @@
* The All_Aboard NAT package from Internet Share
* doesn't give a lease time, so we have to assume one.
*/
- warning("Ack with %lud lease, using %d", lease, MinLease);
+ warning("Ack with %lud lease, using %d", lease,
+ MinLease);
lease = MinLease;
}
DEBUG("lease=%lud ", lease);
@@ -1245,7 +1258,8 @@
DEBUG("ipgw=%R ", conf.gaddr);
} else if (optgetaddr(bp->optdata, OBrouter, conf.gaddr)) {
DEBUG("ipgw=%R ", conf.gaddr);
- } else if (memcmp(bp->giaddr, IPnoaddr + IPv4off, IPv4addrlen) != 0) {
+ } else if (memcmp(bp->giaddr, IPnoaddr + IPv4off, IPv4addrlen)
+ != 0) {
v4tov6(conf.gaddr, bp->giaddr);
DEBUG("giaddr=%R ", conf.gaddr);
}
@@ -1274,13 +1288,15 @@
getoptions(bp->optdata);
/* get plan9-specific options */
- n = optgetvec(bp->optdata, OBvendorinfo, vopts, sizeof(vopts) - 1);
+ n = optgetvec(bp->optdata, OBvendorinfo, vopts,
+ sizeof(vopts) - 1);
if (n > 0 && parseoptions(vopts, n) == 0) {
n = 1;
if (!validip(conf.fs) || !Oflag) {
n = optgetp9addrs(vopts, OP9fs, conf.fs, 2);
if (n == 0)
- n = optgetaddrs(vopts, OP9fsv4, conf.fs, 2);
+ n = optgetaddrs(vopts, OP9fsv4, conf.fs,
+ 2);
}
for (i = 0; i < n; i++)
DEBUG("fs=%R ", conf.fs + i * IPaddrlen);
@@ -1289,7 +1305,8 @@
if (!validip(conf.auth) || !Oflag) {
n = optgetp9addrs(vopts, OP9auth, conf.auth, 2);
if (n == 0)
- n = optgetaddrs(vopts, OP9authv4, conf.auth, 2);
+ n = optgetaddrs(vopts, OP9authv4,
+ conf.auth, 2);
}
for (i = 0; i < n; i++)
DEBUG("auth=%R ", conf.auth + i * IPaddrlen);
@@ -1684,17 +1701,20 @@
append = 1;
else {
append = 0;
- n += snprintf(buf + n, sizeof(buf) - n, "ip=%R ipmask=%M ipgw=%R\n",
+ n += snprintf(buf + n, sizeof(buf) - n,
+ "ip=%R ipmask=%M ipgw=%R\n",
conf.laddr, conf.mask, conf.gaddr);
}
np = strchr(conf.hostname, '.');
if (np != NULL) {
if (*conf.domainname == 0)
- snprintf(conf.domainname, sizeof(conf).domainname, "%s", np + 1);
+ snprintf(conf.domainname, sizeof(conf).domainname, "%s",
+ np + 1);
*np = 0;
}
if (*conf.hostname)
- n += snprintf(buf + n, sizeof(buf) - n, "\tsys=%s\n", conf.hostname);
+ n += snprintf(buf + n, sizeof(buf) - n, "\tsys=%s\n",
+ conf.hostname);
if (*conf.domainname)
n += snprintf(buf + n, sizeof(buf) - n, "\tdom=%s.%s\n",
conf.hostname, conf.domainname);
@@ -1816,8 +1836,8 @@
fprintf(stderr, "can't open ndb: %r\n");
evexit(-1);
}
- if ((strcmp(conf.type, "ether") != 0 && strcmp(conf.type, "gbe") != 0) ||
- myetheraddr(conf.hwa, conf.dev) != 0) {
+ if ((strcmp(conf.type, "ether") != 0 && strcmp(conf.type, "gbe") != 0)
+ || myetheraddr(conf.hwa, conf.dev) != 0) {
fprintf(stderr, "can't read hardware address\n");
evexit(-1);
}
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/accept4.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/accept4.c
index 7aa659f..ede4b4c 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/accept4.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/accept4.c
@@ -41,98 +41,102 @@
}
switch (r->domain) {
- case PF_INET:
- switch (r->stype) {
- case SOCK_DGRAM:
- net = "udp";
- break;
- case SOCK_STREAM:
- net = "tcp";
- break;
- }
- /* at this point, our FD is for the data file. we need to open the
- * listen file. */
- _sock_get_conv_filename(r, "listen", listen);
+ case PF_INET:
+ switch (r->stype) {
+ case SOCK_DGRAM:
+ net = "udp";
+ break;
+ case SOCK_STREAM:
+ net = "tcp";
+ break;
+ }
+ /* at this point, our FD is for the data file. we need to open
+ * the listen file. */
+ _sock_get_conv_filename(r, "listen", listen);
+ open_flags = O_RDWR;
+ /* This is for the listen - maybe don't block on open */
+ open_flags |= (r->sopts & SOCK_NONBLOCK ? O_NONBLOCK : 0);
+ /* This is for the ctl we get back - maybe CLOEXEC, based on
+ * what accept4 wants for the child */
+ open_flags |= (a4_flags & SOCK_CLOEXEC ? O_CLOEXEC : 0);
+ lcfd = open(listen, open_flags);
+ if (lcfd < 0)
+ return -1;
+ /* at this point, we have a new conversation, and lcfd is its
+ * ctl fd. nfd will be the FD for that conv's data file.
+ * sock_data will store our lcfd in the rock and return the data
+ * file fd.
+ *
+ * Note, we pass the listen socket's stype, but not it's sopts.
+ * The sopts (e.g. SOCK_NONBLOCK) apply to the original socket,
+ * not to the new one. Instead, we pass the accept4 flags,
+ * which are the sopts for the new socket. Note that this is
+ * just the sopts. Both the listen socket and the new socket
+ * have the same stype. */
+ nfd = _sock_data(lcfd, net, r->domain, a4_flags | r->stype,
+ r->protocol, &nr);
+ if (nfd < 0)
+ return -1;
+
+ /* get remote address */
+ ip = (struct sockaddr_in *)&nr->raddr;
+ _sock_ingetaddr(nr, ip, &n, "remote");
+ if (addr.__sockaddr__) {
+ memmove(addr.__sockaddr_in__, ip,
+ sizeof(struct sockaddr_in));
+ *alen = sizeof(struct sockaddr_in);
+ }
+
+ return nfd;
+ case PF_UNIX:
+ if (r->other >= 0) {
+ errno = EINVAL; // was EGREG
+ return -1;
+ }
+
+ for (;;) {
+ /* read path to new connection */
+ n = read(fd, name, sizeof(name) - 1);
+ if (n < 0)
+ return -1;
+ if (n == 0)
+ continue;
+ name[n] = 0;
+
+ /* open new connection */
+ _sock_srvname(file, name);
open_flags = O_RDWR;
/* This is for the listen - maybe don't block on open */
- open_flags |= (r->sopts & SOCK_NONBLOCK ? O_NONBLOCK : 0);
- /* This is for the ctl we get back - maybe CLOEXEC, based on what
- * accept4 wants for the child */
+ open_flags |= (r->sopts &
+ SOCK_NONBLOCK ? O_NONBLOCK : 0);
+ /* This is for the ctl we get back - maybe CLOEXEC,
+ * based on what accept4 wants for the child */
open_flags |= (a4_flags & SOCK_CLOEXEC ? O_CLOEXEC : 0);
- lcfd = open(listen, open_flags);
- if (lcfd < 0)
- return -1;
- /* at this point, we have a new conversation, and lcfd is its ctl
- * fd. nfd will be the FD for that conv's data file. sock_data
- * will store our lcfd in the rock and return the data file fd.
- *
- * Note, we pass the listen socket's stype, but not it's sopts. The
- * sopts (e.g. SOCK_NONBLOCK) apply to the original socket, not to
- * the new one. Instead, we pass the accept4 flags, which are the
- * sopts for the new socket. Note that this is just the sopts.
- * Both the listen socket and the new socket have the same stype. */
- nfd = _sock_data(lcfd, net, r->domain, a4_flags | r->stype,
- r->protocol, &nr);
+ nfd = open(file, open_flags);
if (nfd < 0)
- return -1;
+ continue;
- /* get remote address */
- ip = (struct sockaddr_in *)&nr->raddr;
- _sock_ingetaddr(nr, ip, &n, "remote");
- if (addr.__sockaddr__) {
- memmove(addr.__sockaddr_in__, ip, sizeof(struct sockaddr_in));
- *alen = sizeof(struct sockaddr_in);
- }
+ /* confirm opening on new connection */
+ if (write(nfd, name, strlen(name)) > 0)
+ break;
- return nfd;
- case PF_UNIX:
- if (r->other >= 0) {
- errno = EINVAL; // was EGREG
- return -1;
- }
+ close(nfd);
+ }
- for (;;) {
- /* read path to new connection */
- n = read(fd, name, sizeof(name) - 1);
- if (n < 0)
- return -1;
- if (n == 0)
- continue;
- name[n] = 0;
-
- /* open new connection */
- _sock_srvname(file, name);
- open_flags = O_RDWR;
- /* This is for the listen - maybe don't block on open */
- open_flags |= (r->sopts & SOCK_NONBLOCK ? O_NONBLOCK : 0);
- /* This is for the ctl we get back - maybe CLOEXEC, based on
- * what accept4 wants for the child */
- open_flags |= (a4_flags & SOCK_CLOEXEC ? O_CLOEXEC : 0);
- nfd = open(file, open_flags);
- if (nfd < 0)
- continue;
-
- /* confirm opening on new connection */
- if (write(nfd, name, strlen(name)) > 0)
- break;
-
- close(nfd);
- }
-
- nr = _sock_newrock(nfd);
- if (nr == 0) {
- close(nfd);
- return -1;
- }
- nr->domain = r->domain;
- nr->stype = r->stype;
- nr->sopts = a4_flags;
- nr->protocol = r->protocol;
-
- return nfd;
- default:
- errno = EOPNOTSUPP;
+ nr = _sock_newrock(nfd);
+ if (nr == 0) {
+ close(nfd);
return -1;
+ }
+ nr->domain = r->domain;
+ nr->stype = r->stype;
+ nr->sopts = a4_flags;
+ nr->protocol = r->protocol;
+
+ return nfd;
+ default:
+ errno = EOPNOTSUPP;
+ return -1;
}
}
weak_alias(__libc_accept4, accept4)
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/bind.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/bind.c
index 0170493..492d479 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/bind.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/bind.c
@@ -62,11 +62,12 @@
}
if (lip->sin_port <= 0)
_sock_ingetaddr(r, lip, &len, "local");
- /* UDP sockets are in headers mode, and need to be announced. This isn't a
- * full announce, in that the kernel UDP stack doesn't expect someone to
- * open the listen file or anything like that. */
+ /* UDP sockets are in headers mode, and need to be announced. This
+ * isn't a full announce, in that the kernel UDP stack doesn't expect
+ * someone to open the listen file or anything like that. */
if ((r->domain == PF_INET) && (r->stype == SOCK_DGRAM)) {
- n = snprintf(msg, sizeof(msg), "announce *!%d", ntohs(lip->sin_port));
+ n = snprintf(msg, sizeof(msg), "announce *!%d",
+ ntohs(lip->sin_port));
n = write(r->ctl_fd, msg, n);
if (n < 0) {
perror("bind-announce failed");
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/bits/libc-lock.h b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/bits/libc-lock.h
index adcb6fb..9b08b0c 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/bits/libc-lock.h
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/bits/libc-lock.h
@@ -127,11 +127,12 @@
{
if (atomic_read(&vcpd_of(0)->flags) & VC_SCP_NOVCCTX)
return (void*)0xf00baa;
- /* We can't use TLS related to parlib (in_vcore_context() / vcore_id() will
- * crash. current_uthread won't link.). We *can* find our thread
+ /* We can't use TLS related to parlib (in_vcore_context() / vcore_id()
+ * will crash. current_uthread won't link.). We *can* find our thread
* descriptor, which disambiguates any callers (including between vcore
- * context (which probably shouldn't be in here) and uthreads, so long as
- * uthreads have TLS - which they must if they are making glibc calls. */
+ * context (which probably shouldn't be in here) and uthreads, so long
+ * as uthreads have TLS - which they must if they are making glibc
+ * calls. */
return THREAD_SELF;
}
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/connect.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/connect.c
index 0d1d4ff..aff60bb 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/connect.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/connect.c
@@ -50,72 +50,72 @@
memmove(&r->raddr, addr.__sockaddr__, alen);
switch (r->domain) {
- case PF_INET:
- /* UDP sockets are already announced (during bind), so we can't
- * issue a connect message. Either connect or announce, not both.
- * All sends will later do a sendto, based off the contents of
- * r->raddr, so we're already done here */
- if (r->stype == SOCK_DGRAM)
- return 0;
- /* whatever .. */
- rip = (struct sockaddr_in *)addr.__sockaddr_in__;
- lip = (struct sockaddr_in *)&r->addr;
- if (lip->sin_port)
- snprintf(msg, sizeof msg, "connect %s!%d%s %d",
- inet_ntoa(rip->sin_addr), ntohs(rip->sin_port),
- r->reserved ? "!r" : "", ntohs(lip->sin_port));
- else
- snprintf(msg, sizeof msg, "connect %s!%d%s",
- inet_ntoa(rip->sin_addr), ntohs(rip->sin_port),
- r->reserved ? "!r" : "");
- n = write(r->ctl_fd, msg, strlen(msg));
- if (n < 0)
- return -1;
+ case PF_INET:
+ /* UDP sockets are already announced (during bind), so we can't
+ * issue a connect message. Either connect or announce, not
+ * both. All sends will later do a sendto, based off the
+ * contents of r->raddr, so we're already done here */
+ if (r->stype == SOCK_DGRAM)
return 0;
- case PF_UNIX:
- /* null terminate the address */
- if (alen == sizeof(r->raddr))
- alen--;
- *(((char *)&r->raddr) + alen) = 0;
-
- if (r->other < 0) {
- errno = EINVAL; //EGREG;
- return -1;
- }
-
- /* put far end of our pipe in /srv */
- snprintf(msg, sizeof msg, "UD.%d.%d", getpid(), vers++);
- if (_sock_srv(msg, r->other) < 0) {
- r->other = -1;
- return -1;
- }
- r->other = -1;
-
- /* tell server the /srv file to open */
- runix = (struct sockaddr_un *)&r->raddr;
- _sock_srvname(file, runix->sun_path);
- open_flags = O_RDWR;
- open_flags |= (r->sopts & SOCK_CLOEXEC ? O_CLOEXEC : 0);
- nfd = open(file, open_flags);
- if (nfd < 0) {
- unlink(msg);
- return -1;
- }
- if (write(nfd, msg, strlen(msg)) < 0) {
- close(nfd);
- unlink(msg);
- return -1;
- }
- close(nfd);
-
- /* wait for server to open it and then remove it */
- read(fd, file, sizeof(file));
- _sock_srvname(file, msg);
- unlink(file);
- return 0;
- default:
- errno = EAFNOSUPPORT;
+ /* whatever .. */
+ rip = (struct sockaddr_in *)addr.__sockaddr_in__;
+ lip = (struct sockaddr_in *)&r->addr;
+ if (lip->sin_port)
+ snprintf(msg, sizeof msg, "connect %s!%d%s %d",
+ inet_ntoa(rip->sin_addr), ntohs(rip->sin_port),
+ r->reserved ? "!r" : "", ntohs(lip->sin_port));
+ else
+ snprintf(msg, sizeof msg, "connect %s!%d%s",
+ inet_ntoa(rip->sin_addr), ntohs(rip->sin_port),
+ r->reserved ? "!r" : "");
+ n = write(r->ctl_fd, msg, strlen(msg));
+ if (n < 0)
return -1;
+ return 0;
+ case PF_UNIX:
+ /* null terminate the address */
+ if (alen == sizeof(r->raddr))
+ alen--;
+ *(((char *)&r->raddr) + alen) = 0;
+
+ if (r->other < 0) {
+ errno = EINVAL; //EGREG;
+ return -1;
+ }
+
+ /* put far end of our pipe in /srv */
+ snprintf(msg, sizeof msg, "UD.%d.%d", getpid(), vers++);
+ if (_sock_srv(msg, r->other) < 0) {
+ r->other = -1;
+ return -1;
+ }
+ r->other = -1;
+
+ /* tell server the /srv file to open */
+ runix = (struct sockaddr_un *)&r->raddr;
+ _sock_srvname(file, runix->sun_path);
+ open_flags = O_RDWR;
+ open_flags |= (r->sopts & SOCK_CLOEXEC ? O_CLOEXEC : 0);
+ nfd = open(file, open_flags);
+ if (nfd < 0) {
+ unlink(msg);
+ return -1;
+ }
+ if (write(nfd, msg, strlen(msg)) < 0) {
+ close(nfd);
+ unlink(msg);
+ return -1;
+ }
+ close(nfd);
+
+ /* wait for server to open it and then remove it */
+ read(fd, file, sizeof(file));
+ _sock_srvname(file, msg);
+ unlink(file);
+ return 0;
+ default:
+ errno = EAFNOSUPPORT;
+ return -1;
}
}
weak_alias(__connect, connect)
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/convM2D.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/convM2D.c
index 657e3b6..d715514 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/convM2D.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/convM2D.c
@@ -36,8 +36,8 @@
static char nullstring[] = "";
-unsigned int
-convM2D(uint8_t * buf, unsigned int nbuf, struct dir *d, char *strs)
+unsigned int convM2D(uint8_t * buf, unsigned int nbuf, struct dir *d, char
+ *strs)
{
uint8_t *p, *ebuf;
char *sv[4];
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/convM2S.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/convM2S.c
index fa72621..9ed055b 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/convM2S.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/convM2S.c
@@ -10,8 +10,7 @@
#include <string.h>
#include <fcall.h>
-static
-uint8_t *gstring(uint8_t * p, uint8_t * ep, char **s)
+static uint8_t *gstring(uint8_t * p, uint8_t * ep, char **s)
{
unsigned int n;
@@ -29,8 +28,7 @@
return p;
}
-static
-uint8_t *gqid(uint8_t * p, uint8_t * ep, struct qid *q)
+static uint8_t *gqid(uint8_t * p, uint8_t * ep, struct qid *q)
{
if (p + QIDSZ > ep)
return NULL;
@@ -92,240 +90,240 @@
p += BIT16SZ;
switch (f->type) {
- default:
+ default:
+ return 0;
+
+ case Tversion:
+ if (p + BIT32SZ > ep)
return 0;
+ f->msize = GBIT32(p);
+ p += BIT32SZ;
+ p = gstring(p, ep, &f->version);
+ break;
- case Tversion:
- if (p + BIT32SZ > ep)
- return 0;
- f->msize = GBIT32(p);
- p += BIT32SZ;
- p = gstring(p, ep, &f->version);
+ case Tflush:
+ if (p + BIT16SZ > ep)
+ return 0;
+ f->oldtag = GBIT16(p);
+ p += BIT16SZ;
+ break;
+
+ case Tauth:
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->afid = GBIT32(p);
+ p += BIT32SZ;
+ p = gstring(p, ep, &f->uname);
+ if (p == NULL)
break;
-
- case Tflush:
- if (p + BIT16SZ > ep)
- return 0;
- f->oldtag = GBIT16(p);
- p += BIT16SZ;
+ p = gstring(p, ep, &f->aname);
+ if (p == NULL)
break;
+ break;
- case Tauth:
- if (p + BIT32SZ > ep)
- return 0;
- f->afid = GBIT32(p);
- p += BIT32SZ;
- p = gstring(p, ep, &f->uname);
+ case Tattach:
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->afid = GBIT32(p);
+ p += BIT32SZ;
+ p = gstring(p, ep, &f->uname);
+ if (p == NULL)
+ break;
+ p = gstring(p, ep, &f->aname);
+ if (p == NULL)
+ break;
+ break;
+
+ case Twalk:
+ if (p + BIT32SZ + BIT32SZ + BIT16SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ f->newfid = GBIT32(p);
+ p += BIT32SZ;
+ f->nwname = GBIT16(p);
+ p += BIT16SZ;
+ if (f->nwname > MAXWELEM)
+ return 0;
+ for (i = 0; i < f->nwname; i++) {
+ p = gstring(p, ep, &f->wname[i]);
if (p == NULL)
break;
- p = gstring(p, ep, &f->aname);
+ }
+ break;
+
+ case Topen:
+ if (p + BIT32SZ + BIT8SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ f->mode = GBIT8(p);
+ p += BIT8SZ;
+ break;
+
+ case Tcreate:
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ p = gstring(p, ep, &f->name);
+ if (p == NULL)
+ break;
+ if (p + BIT32SZ + BIT8SZ > ep)
+ return 0;
+ f->perm = GBIT32(p);
+ p += BIT32SZ;
+ f->mode = GBIT8(p);
+ p += BIT8SZ;
+ break;
+
+ case Tread:
+ if (p + BIT32SZ + BIT64SZ + BIT32SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ f->offset = GBIT64(p);
+ p += BIT64SZ;
+ f->count = GBIT32(p);
+ p += BIT32SZ;
+ break;
+
+ case Twrite:
+ if (p + BIT32SZ + BIT64SZ + BIT32SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ f->offset = GBIT64(p);
+ p += BIT64SZ;
+ f->count = GBIT32(p);
+ p += BIT32SZ;
+ if (p + f->count > ep)
+ return 0;
+ f->data = (char *)p;
+ p += f->count;
+ break;
+
+ case Tclunk:
+ case Tremove:
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ break;
+
+ case Tstat:
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ break;
+
+ case Twstat:
+ if (p + BIT32SZ + BIT16SZ > ep)
+ return 0;
+ f->fid = GBIT32(p);
+ p += BIT32SZ;
+ f->nstat = GBIT16(p);
+ p += BIT16SZ;
+ if (p + f->nstat > ep)
+ return 0;
+ f->stat = p;
+ p += f->nstat;
+ break;
+
+
+
+ case Rversion:
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->msize = GBIT32(p);
+ p += BIT32SZ;
+ p = gstring(p, ep, &f->version);
+ break;
+
+ case Rerror:
+ p = gstring(p, ep, &f->ename);
+ break;
+
+ case Rflush:
+ break;
+
+ case Rauth:
+ p = gqid(p, ep, &f->aqid);
+ if (p == NULL)
+ break;
+ break;
+
+ case Rattach:
+ p = gqid(p, ep, &f->qid);
+ if (p == NULL)
+ break;
+ break;
+
+ case Rwalk:
+ if (p + BIT16SZ > ep)
+ return 0;
+ f->nwqid = GBIT16(p);
+ p += BIT16SZ;
+ if (f->nwqid > MAXWELEM)
+ return 0;
+ for (i = 0; i < f->nwqid; i++) {
+ p = gqid(p, ep, &f->wqid[i]);
if (p == NULL)
break;
- break;
+ }
+ break;
- case Tattach:
- if (p + BIT32SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- if (p + BIT32SZ > ep)
- return 0;
- f->afid = GBIT32(p);
- p += BIT32SZ;
- p = gstring(p, ep, &f->uname);
- if (p == NULL)
- break;
- p = gstring(p, ep, &f->aname);
- if (p == NULL)
- break;
+ case Ropen:
+ case Rcreate:
+ p = gqid(p, ep, &f->qid);
+ if (p == NULL)
break;
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->iounit = GBIT32(p);
+ p += BIT32SZ;
+ break;
- case Twalk:
- if (p + BIT32SZ + BIT32SZ + BIT16SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- f->newfid = GBIT32(p);
- p += BIT32SZ;
- f->nwname = GBIT16(p);
- p += BIT16SZ;
- if (f->nwname > MAXWELEM)
- return 0;
- for (i = 0; i < f->nwname; i++) {
- p = gstring(p, ep, &f->wname[i]);
- if (p == NULL)
- break;
- }
- break;
+ case Rread:
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->count = GBIT32(p);
+ p += BIT32SZ;
+ if (p + f->count > ep)
+ return 0;
+ f->data = (char *)p;
+ p += f->count;
+ break;
- case Topen:
- if (p + BIT32SZ + BIT8SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- f->mode = GBIT8(p);
- p += BIT8SZ;
- break;
+ case Rwrite:
+ if (p + BIT32SZ > ep)
+ return 0;
+ f->count = GBIT32(p);
+ p += BIT32SZ;
+ break;
- case Tcreate:
- if (p + BIT32SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- p = gstring(p, ep, &f->name);
- if (p == NULL)
- break;
- if (p + BIT32SZ + BIT8SZ > ep)
- return 0;
- f->perm = GBIT32(p);
- p += BIT32SZ;
- f->mode = GBIT8(p);
- p += BIT8SZ;
- break;
+ case Rclunk:
+ case Rremove:
+ break;
- case Tread:
- if (p + BIT32SZ + BIT64SZ + BIT32SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- f->offset = GBIT64(p);
- p += BIT64SZ;
- f->count = GBIT32(p);
- p += BIT32SZ;
- break;
+ case Rstat:
+ if (p + BIT16SZ > ep)
+ return 0;
+ f->nstat = GBIT16(p);
+ p += BIT16SZ;
+ if (p + f->nstat > ep)
+ return 0;
+ f->stat = p;
+ p += f->nstat;
+ break;
- case Twrite:
- if (p + BIT32SZ + BIT64SZ + BIT32SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- f->offset = GBIT64(p);
- p += BIT64SZ;
- f->count = GBIT32(p);
- p += BIT32SZ;
- if (p + f->count > ep)
- return 0;
- f->data = (char *)p;
- p += f->count;
- break;
-
- case Tclunk:
- case Tremove:
- if (p + BIT32SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- break;
-
- case Tstat:
- if (p + BIT32SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- break;
-
- case Twstat:
- if (p + BIT32SZ + BIT16SZ > ep)
- return 0;
- f->fid = GBIT32(p);
- p += BIT32SZ;
- f->nstat = GBIT16(p);
- p += BIT16SZ;
- if (p + f->nstat > ep)
- return 0;
- f->stat = p;
- p += f->nstat;
- break;
-
-/*
- */
- case Rversion:
- if (p + BIT32SZ > ep)
- return 0;
- f->msize = GBIT32(p);
- p += BIT32SZ;
- p = gstring(p, ep, &f->version);
- break;
-
- case Rerror:
- p = gstring(p, ep, &f->ename);
- break;
-
- case Rflush:
- break;
-
- case Rauth:
- p = gqid(p, ep, &f->aqid);
- if (p == NULL)
- break;
- break;
-
- case Rattach:
- p = gqid(p, ep, &f->qid);
- if (p == NULL)
- break;
- break;
-
- case Rwalk:
- if (p + BIT16SZ > ep)
- return 0;
- f->nwqid = GBIT16(p);
- p += BIT16SZ;
- if (f->nwqid > MAXWELEM)
- return 0;
- for (i = 0; i < f->nwqid; i++) {
- p = gqid(p, ep, &f->wqid[i]);
- if (p == NULL)
- break;
- }
- break;
-
- case Ropen:
- case Rcreate:
- p = gqid(p, ep, &f->qid);
- if (p == NULL)
- break;
- if (p + BIT32SZ > ep)
- return 0;
- f->iounit = GBIT32(p);
- p += BIT32SZ;
- break;
-
- case Rread:
- if (p + BIT32SZ > ep)
- return 0;
- f->count = GBIT32(p);
- p += BIT32SZ;
- if (p + f->count > ep)
- return 0;
- f->data = (char *)p;
- p += f->count;
- break;
-
- case Rwrite:
- if (p + BIT32SZ > ep)
- return 0;
- f->count = GBIT32(p);
- p += BIT32SZ;
- break;
-
- case Rclunk:
- case Rremove:
- break;
-
- case Rstat:
- if (p + BIT16SZ > ep)
- return 0;
- f->nstat = GBIT16(p);
- p += BIT16SZ;
- if (p + f->nstat > ep)
- return 0;
- f->stat = p;
- p += f->nstat;
- break;
-
- case Rwstat:
- break;
+ case Rwstat:
+ break;
}
if (p == NULL || p > ep)
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/convS2M.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/convS2M.c
index a1a0afa..de93a50 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/convS2M.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/convS2M.c
@@ -64,134 +64,134 @@
n += BIT16SZ; /* tag */
switch (f->type) {
- default:
- return 0;
+ default:
+ return 0;
- case Tversion:
- n += BIT32SZ;
- n += stringsz(f->version);
- break;
+ case Tversion:
+ n += BIT32SZ;
+ n += stringsz(f->version);
+ break;
- case Tflush:
- n += BIT16SZ;
- break;
+ case Tflush:
+ n += BIT16SZ;
+ break;
- case Tauth:
- n += BIT32SZ;
- n += stringsz(f->uname);
- n += stringsz(f->aname);
- break;
+ case Tauth:
+ n += BIT32SZ;
+ n += stringsz(f->uname);
+ n += stringsz(f->aname);
+ break;
- case Tattach:
- n += BIT32SZ;
- n += BIT32SZ;
- n += stringsz(f->uname);
- n += stringsz(f->aname);
- break;
+ case Tattach:
+ n += BIT32SZ;
+ n += BIT32SZ;
+ n += stringsz(f->uname);
+ n += stringsz(f->aname);
+ break;
- case Twalk:
- n += BIT32SZ;
- n += BIT32SZ;
- n += BIT16SZ;
- for (i = 0; i < f->nwname; i++)
- n += stringsz(f->wname[i]);
- break;
+ case Twalk:
+ n += BIT32SZ;
+ n += BIT32SZ;
+ n += BIT16SZ;
+ for (i = 0; i < f->nwname; i++)
+ n += stringsz(f->wname[i]);
+ break;
- case Topen:
- n += BIT32SZ;
- n += BIT8SZ;
- break;
+ case Topen:
+ n += BIT32SZ;
+ n += BIT8SZ;
+ break;
- case Tcreate:
- n += BIT32SZ;
- n += stringsz(f->name);
- n += BIT32SZ;
- n += BIT8SZ;
- break;
+ case Tcreate:
+ n += BIT32SZ;
+ n += stringsz(f->name);
+ n += BIT32SZ;
+ n += BIT8SZ;
+ break;
- case Tread:
- n += BIT32SZ;
- n += BIT64SZ;
- n += BIT32SZ;
- break;
+ case Tread:
+ n += BIT32SZ;
+ n += BIT64SZ;
+ n += BIT32SZ;
+ break;
- case Twrite:
- n += BIT32SZ;
- n += BIT64SZ;
- n += BIT32SZ;
- n += f->count;
- break;
+ case Twrite:
+ n += BIT32SZ;
+ n += BIT64SZ;
+ n += BIT32SZ;
+ n += f->count;
+ break;
- case Tclunk:
- case Tremove:
- n += BIT32SZ;
- break;
+ case Tclunk:
+ case Tremove:
+ n += BIT32SZ;
+ break;
- case Tstat:
- n += BIT32SZ;
- break;
+ case Tstat:
+ n += BIT32SZ;
+ break;
- case Twstat:
- n += BIT32SZ;
- n += BIT16SZ;
- n += f->nstat;
- break;
-/*
- */
+ case Twstat:
+ n += BIT32SZ;
+ n += BIT16SZ;
+ n += f->nstat;
+ break;
- case Rversion:
- n += BIT32SZ;
- n += stringsz(f->version);
- break;
- case Rerror:
- n += stringsz(f->ename);
- break;
- case Rflush:
- break;
+ case Rversion:
+ n += BIT32SZ;
+ n += stringsz(f->version);
+ break;
- case Rauth:
- n += QIDSZ;
- break;
+ case Rerror:
+ n += stringsz(f->ename);
+ break;
- case Rattach:
- n += QIDSZ;
- break;
+ case Rflush:
+ break;
- case Rwalk:
- n += BIT16SZ;
- n += f->nwqid * QIDSZ;
- break;
+ case Rauth:
+ n += QIDSZ;
+ break;
- case Ropen:
- case Rcreate:
- n += QIDSZ;
- n += BIT32SZ;
- break;
+ case Rattach:
+ n += QIDSZ;
+ break;
- case Rread:
- n += BIT32SZ;
- n += f->count;
- break;
+ case Rwalk:
+ n += BIT16SZ;
+ n += f->nwqid * QIDSZ;
+ break;
- case Rwrite:
- n += BIT32SZ;
- break;
+ case Ropen:
+ case Rcreate:
+ n += QIDSZ;
+ n += BIT32SZ;
+ break;
- case Rclunk:
- break;
+ case Rread:
+ n += BIT32SZ;
+ n += f->count;
+ break;
- case Rremove:
- break;
+ case Rwrite:
+ n += BIT32SZ;
+ break;
- case Rstat:
- n += BIT16SZ;
- n += f->nstat;
- break;
+ case Rclunk:
+ break;
- case Rwstat:
- break;
+ case Rremove:
+ break;
+
+ case Rstat:
+ n += BIT16SZ;
+ n += f->nstat;
+ break;
+
+ case Rwstat:
+ break;
}
return n;
}
@@ -217,172 +217,172 @@
p += BIT16SZ;
switch (f->type) {
- default:
+ default:
+ return 0;
+
+ case Tversion:
+ PBIT32(p, f->msize);
+ p += BIT32SZ;
+ p = pstring(p, f->version);
+ break;
+
+ case Tflush:
+ PBIT16(p, f->oldtag);
+ p += BIT16SZ;
+ break;
+
+ case Tauth:
+ PBIT32(p, f->afid);
+ p += BIT32SZ;
+ p = pstring(p, f->uname);
+ p = pstring(p, f->aname);
+ break;
+
+ case Tattach:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ PBIT32(p, f->afid);
+ p += BIT32SZ;
+ p = pstring(p, f->uname);
+ p = pstring(p, f->aname);
+ break;
+
+ case Twalk:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ PBIT32(p, f->newfid);
+ p += BIT32SZ;
+ PBIT16(p, f->nwname);
+ p += BIT16SZ;
+ if (f->nwname > MAXWELEM)
return 0;
+ for (i = 0; i < f->nwname; i++)
+ p = pstring(p, f->wname[i]);
+ break;
- case Tversion:
- PBIT32(p, f->msize);
- p += BIT32SZ;
- p = pstring(p, f->version);
- break;
+ case Topen:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ PBIT8(p, f->mode);
+ p += BIT8SZ;
+ break;
- case Tflush:
- PBIT16(p, f->oldtag);
- p += BIT16SZ;
- break;
+ case Tcreate:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ p = pstring(p, f->name);
+ PBIT32(p, f->perm);
+ p += BIT32SZ;
+ PBIT8(p, f->mode);
+ p += BIT8SZ;
+ break;
- case Tauth:
- PBIT32(p, f->afid);
- p += BIT32SZ;
- p = pstring(p, f->uname);
- p = pstring(p, f->aname);
- break;
+ case Tread:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ PBIT64(p, f->offset);
+ p += BIT64SZ;
+ PBIT32(p, f->count);
+ p += BIT32SZ;
+ break;
- case Tattach:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- PBIT32(p, f->afid);
- p += BIT32SZ;
- p = pstring(p, f->uname);
- p = pstring(p, f->aname);
- break;
+ case Twrite:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ PBIT64(p, f->offset);
+ p += BIT64SZ;
+ PBIT32(p, f->count);
+ p += BIT32SZ;
+ memmove(p, f->data, f->count);
+ p += f->count;
+ break;
- case Twalk:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- PBIT32(p, f->newfid);
- p += BIT32SZ;
- PBIT16(p, f->nwname);
- p += BIT16SZ;
- if (f->nwname > MAXWELEM)
- return 0;
- for (i = 0; i < f->nwname; i++)
- p = pstring(p, f->wname[i]);
- break;
+ case Tclunk:
+ case Tremove:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ break;
- case Topen:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- PBIT8(p, f->mode);
- p += BIT8SZ;
- break;
+ case Tstat:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ break;
- case Tcreate:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- p = pstring(p, f->name);
- PBIT32(p, f->perm);
- p += BIT32SZ;
- PBIT8(p, f->mode);
- p += BIT8SZ;
- break;
+ case Twstat:
+ PBIT32(p, f->fid);
+ p += BIT32SZ;
+ PBIT16(p, f->nstat);
+ p += BIT16SZ;
+ memmove(p, f->stat, f->nstat);
+ p += f->nstat;
+ break;
- case Tread:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- PBIT64(p, f->offset);
- p += BIT64SZ;
- PBIT32(p, f->count);
- p += BIT32SZ;
- break;
- case Twrite:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- PBIT64(p, f->offset);
- p += BIT64SZ;
- PBIT32(p, f->count);
- p += BIT32SZ;
- memmove(p, f->data, f->count);
- p += f->count;
- break;
- case Tclunk:
- case Tremove:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- break;
+ case Rversion:
+ PBIT32(p, f->msize);
+ p += BIT32SZ;
+ p = pstring(p, f->version);
+ break;
- case Tstat:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- break;
+ case Rerror:
+ p = pstring(p, f->ename);
+ break;
- case Twstat:
- PBIT32(p, f->fid);
- p += BIT32SZ;
- PBIT16(p, f->nstat);
- p += BIT16SZ;
- memmove(p, f->stat, f->nstat);
- p += f->nstat;
- break;
-/*
- */
+ case Rflush:
+ break;
- case Rversion:
- PBIT32(p, f->msize);
- p += BIT32SZ;
- p = pstring(p, f->version);
- break;
+ case Rauth:
+ p = pqid(p, &f->aqid);
+ break;
- case Rerror:
- p = pstring(p, f->ename);
- break;
+ case Rattach:
+ p = pqid(p, &f->qid);
+ break;
- case Rflush:
- break;
+ case Rwalk:
+ PBIT16(p, f->nwqid);
+ p += BIT16SZ;
+ if (f->nwqid > MAXWELEM)
+ return 0;
+ for (i = 0; i < f->nwqid; i++)
+ p = pqid(p, &f->wqid[i]);
+ break;
- case Rauth:
- p = pqid(p, &f->aqid);
- break;
+ case Ropen:
+ case Rcreate:
+ p = pqid(p, &f->qid);
+ PBIT32(p, f->iounit);
+ p += BIT32SZ;
+ break;
- case Rattach:
- p = pqid(p, &f->qid);
- break;
+ case Rread:
+ PBIT32(p, f->count);
+ p += BIT32SZ;
+ memmove(p, f->data, f->count);
+ p += f->count;
+ break;
- case Rwalk:
- PBIT16(p, f->nwqid);
- p += BIT16SZ;
- if (f->nwqid > MAXWELEM)
- return 0;
- for (i = 0; i < f->nwqid; i++)
- p = pqid(p, &f->wqid[i]);
- break;
+ case Rwrite:
+ PBIT32(p, f->count);
+ p += BIT32SZ;
+ break;
- case Ropen:
- case Rcreate:
- p = pqid(p, &f->qid);
- PBIT32(p, f->iounit);
- p += BIT32SZ;
- break;
+ case Rclunk:
+ break;
- case Rread:
- PBIT32(p, f->count);
- p += BIT32SZ;
- memmove(p, f->data, f->count);
- p += f->count;
- break;
+ case Rremove:
+ break;
- case Rwrite:
- PBIT32(p, f->count);
- p += BIT32SZ;
- break;
+ case Rstat:
+ PBIT16(p, f->nstat);
+ p += BIT16SZ;
+ memmove(p, f->stat, f->nstat);
+ p += f->nstat;
+ break;
- case Rclunk:
- break;
-
- case Rremove:
- break;
-
- case Rstat:
- PBIT16(p, f->nstat);
- p += BIT16SZ;
- memmove(p, f->stat, f->nstat);
- p += f->nstat;
- break;
-
- case Rwstat:
- break;
+ case Rwstat:
+ break;
}
if (size != p - ap)
return 0;
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/dl-execstack.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/dl-execstack.c
index f819c38..1a10fe6 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/dl-execstack.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/dl-execstack.c
@@ -34,7 +34,8 @@
GL(dl_stack_flags) |= PF_X;
int size = USTACK_NUM_PAGES*PGSIZE;
- void* bottom = USTACKTOP-size;
+ void *bottom = USTACKTOP-size;
+
return mprotect(bottom,size,PROT_READ|PROT_WRITE|PROT_EXEC);
}
rtld_hidden_def (_dl_make_stack_executable)
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/eventfd.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/eventfd.c
index 38f3240..942640d 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/eventfd.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/eventfd.c
@@ -46,6 +46,7 @@
{
int ret;
char num64[32];
+
ret = read(efd, num64, sizeof(num64));
if (ret <= 0)
return -1;
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/execve.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/execve.c
index 0b386cc..d7a45c6 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/execve.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/execve.c
@@ -41,6 +41,7 @@
}
int ret = ros_syscall(SYS_exec, path, strlen(path), sd->buf, sd->len, 0, 0);
+
// if we got here, then exec better have failed...
assert(ret == -1);
free_serialized_data(sd);
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/fcall.h b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/fcall.h
index 6e527d5..51928b4 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/fcall.h
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/fcall.h
@@ -39,10 +39,10 @@
uint32_t atime; /* last read time */
uint32_t mtime; /* last write time */
int64_t length; /* file length: see <u.h> */
- char *name; /* last element of path */
- char *uid; /* owner name */
- char *gid; /* group name */
- char *muid; /* last modifier name */
+ char *name; /* last element of path */
+ char *uid; /* owner name */
+ char *gid; /* group name */
+ char *muid; /* last modifier name */
};
#define VERSION9P "9P2000"
@@ -78,7 +78,7 @@
};
struct {
uint32_t perm; /* Tcreate */
- char *name; /* Tcreate */
+ char *name; /* Tcreate */
uint8_t mode; /* Tcreate, Topen */
};
struct {
@@ -93,7 +93,7 @@
struct {
int64_t offset; /* Tread, Twrite */
uint32_t count; /* Tread, Twrite, Rread */
- char *data; /* Twrite, Rread */
+ char *data; /* Twrite, Rread */
};
struct {
uint16_t nstat; /* Twstat, Rstat */
@@ -102,23 +102,23 @@
};
};
-#define GBIT8(p) ((p)[0])
-#define GBIT16(p) ((p)[0]|((p)[1]<<8))
-#define GBIT32(p) ((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24))
-#define GBIT64(p) ((uint32_t)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)) |\
- ((int64_t)((p)[4]|((p)[5]<<8)|((p)[6]<<16)|((p)[7]<<24)) << 32))
+#define GBIT8(p) ((p)[0])
+#define GBIT16(p) ((p)[0]|((p)[1]<<8))
+#define GBIT32(p) ((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24))
+#define GBIT64(p) ((uint32_t)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)) |\
+ ((int64_t)((p)[4]|((p)[5]<<8)|((p)[6]<<16)|((p)[7]<<24)) << 32))
-#define PBIT8(p,v) (p)[0]=(v)
-#define PBIT16(p,v) (p)[0]=(v);(p)[1]=(v)>>8
-#define PBIT32(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24
-#define PBIT64(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24;\
- (p)[4]=(v)>>32;(p)[5]=(v)>>40;(p)[6]=(v)>>48;(p)[7]=(v)>>56
+#define PBIT8(p,v) (p)[0]=(v)
+#define PBIT16(p,v) (p)[0]=(v);(p)[1]=(v)>>8
+#define PBIT32(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24
+#define PBIT64(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24;\
+ (p)[4]=(v)>>32;(p)[5]=(v)>>40;(p)[6]=(v)>>48;(p)[7]=(v)>>56
#define BIT8SZ 1
#define BIT16SZ 2
#define BIT32SZ 4
#define BIT64SZ 8
-#define QIDSZ (BIT8SZ+BIT32SZ+BIT64SZ)
+#define QIDSZ (BIT8SZ+BIT32SZ+BIT64SZ)
/* STATFIXLEN includes leading 16-bit count */
/* The count, however, excludes itself; total size is BIT16SZ+count */
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/fcntl.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/fcntl.c
index d80d5ea..e6ff2ac 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/fcntl.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/fcntl.c
@@ -23,40 +23,40 @@
long a1, a2, a3, a4;
switch (cmd) {
- case F_GETFD:
- case F_SYNC:
- ret = ros_syscall(SYS_fcntl, fd, cmd, 0, 0, 0, 0);
- break;
- case F_DUPFD:
- case F_SETFD:
- case F_GETFL:
- arg = va_arg(vl, int);
- ret = ros_syscall(SYS_fcntl, fd, cmd, arg, 0, 0, 0);
- break;
- case F_SETFL:
- arg = va_arg(vl, int);
- ret = ros_syscall(SYS_fcntl, fd, cmd, arg, 0, 0, 0);
- /* For SETFL, we mirror the operation on all of the Rocks FDs. If
- * the others fail, we won't hear about it. Similarly, we only
- * GETFL for the data FD. */
- _sock_mirror_fcntl(fd, cmd, arg);
- break;
- case F_ADVISE:
- offset = va_arg(vl, __off64_t);
- len = va_arg(vl, __off64_t);
- advise = va_arg(vl, int);
- ret = ros_syscall(SYS_fcntl, fd, cmd, offset, len, advise, 0);
- break;
- default:
- /* We don't know the number of arguments for generic calls. We'll
- * just yank whatever arguments there could be from the ABI and
- * send them along. */
- a1 = va_arg(vl, long);
- a2 = va_arg(vl, long);
- a3 = va_arg(vl, long);
- a4 = va_arg(vl, long);
- ret = ros_syscall(SYS_fcntl, fd, cmd, a1, a2, a3, a4);
- break;
+ case F_GETFD:
+ case F_SYNC:
+ ret = ros_syscall(SYS_fcntl, fd, cmd, 0, 0, 0, 0);
+ break;
+ case F_DUPFD:
+ case F_SETFD:
+ case F_GETFL:
+ arg = va_arg(vl, int);
+ ret = ros_syscall(SYS_fcntl, fd, cmd, arg, 0, 0, 0);
+ break;
+ case F_SETFL:
+ arg = va_arg(vl, int);
+ ret = ros_syscall(SYS_fcntl, fd, cmd, arg, 0, 0, 0);
+ /* For SETFL, we mirror the operation on all of the Rocks FDs.
+ * If the others fail, we won't hear about it. Similarly, we
+ * only GETFL for the data FD. */
+ _sock_mirror_fcntl(fd, cmd, arg);
+ break;
+ case F_ADVISE:
+ offset = va_arg(vl, __off64_t);
+ len = va_arg(vl, __off64_t);
+ advise = va_arg(vl, int);
+ ret = ros_syscall(SYS_fcntl, fd, cmd, offset, len, advise, 0);
+ break;
+ default:
+ /* We don't know the number of arguments for generic calls.
+ * We'll just yank whatever arguments there could be from the
+ * ABI and send them along. */
+ a1 = va_arg(vl, long);
+ a2 = va_arg(vl, long);
+ a3 = va_arg(vl, long);
+ a4 = va_arg(vl, long);
+ ret = ros_syscall(SYS_fcntl, fd, cmd, a1, a2, a3, a4);
+ break;
}
return ret;
}
@@ -67,6 +67,7 @@
{
int ret;
va_list vl;
+
va_start(vl, cmd);
ret = __vfcntl(fd, cmd, vl);
va_end(vl);
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getaddrinfo.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getaddrinfo.c
index b9632d2..d087ca8 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getaddrinfo.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getaddrinfo.c
@@ -24,7 +24,8 @@
{
char *strtoul_end = 0;
unsigned long port = 0; /* uninitialized, up to the main caller */
- int protocol = 0; /* any protocol, will assume TCP and UDP later */
+ int protocol = 0; /* any protocol, will assume TCP/UDP later */
+
if (serv) {
if (serv[0] == '\0')
return EAI_NONAME;
@@ -34,9 +35,10 @@
if (hints->ai_flags & AI_NUMERICSERV)
return EAI_NONAME;
/* CS lookup */
- /* TODO: get a port, maybe a protocol. If we have a restriction on
- * the protocol from hints, check that here. Probably need to
- * rework this a bit if we have multiple protocols. */
+ /* TODO: get a port, maybe a protocol. If we have a
+ * restriction on the protocol from hints, check that
+ * here. Probably need to rework this a bit if we have
+ * multiple protocols. */
return EAI_NONAME;
}
}
@@ -108,14 +110,14 @@
static int proto_to_socktype(int protocol)
{
switch (protocol) {
- case IPPROTO_IP:
- case IPPROTO_TCP:
- return SOCK_STREAM;
- case IPPROTO_ICMP:
- case IPPROTO_UDP:
- return SOCK_DGRAM;
- case IPPROTO_RAW:
- return SOCK_RAW;
+ case IPPROTO_IP:
+ case IPPROTO_TCP:
+ return SOCK_STREAM;
+ case IPPROTO_ICMP:
+ case IPPROTO_UDP:
+ return SOCK_DGRAM;
+ case IPPROTO_RAW:
+ return SOCK_RAW;
}
return -1;
}
@@ -123,12 +125,12 @@
static int socktype_to_proto(int socktype)
{
switch (socktype) {
- case SOCK_STREAM:
- return IPPROTO_TCP;
- case SOCK_DGRAM:
- return IPPROTO_UDP;
- case SOCK_RAW:
- return IPPROTO_RAW;
+ case SOCK_STREAM:
+ return IPPROTO_TCP;
+ case SOCK_DGRAM:
+ return IPPROTO_UDP;
+ case SOCK_RAW:
+ return IPPROTO_RAW;
}
return -1;
}
@@ -164,10 +166,11 @@
ai->ai_addr = malloc(sizeof(struct sockaddr_storage));
memset(ai->ai_addr, 0, sizeof(struct sockaddr_storage));
- /* Only supporting TCP and UDP for now. If protocol is 0, later we'll make
- * addrinfos for both (TODO). Likewise, we only support DGRAM or STREAM for
- * socktype. */
- if ((ret = serv_get_portprotocol(serv, &port, &protocol, &local_hints))) {
+ /* Only supporting TCP and UDP for now. If protocol is 0, later we'll
+ * make addrinfos for both (TODO). Likewise, we only support DGRAM or
+ * STREAM for socktype. */
+ if ((ret = serv_get_portprotocol(serv, &port, &protocol, &local_hints)))
+ {
freeaddrinfo(ai);
return ret;
}
@@ -178,9 +181,9 @@
/* We have a mostly full addrinfo. Still missing ai_protocol, socktype,
* flags (already 0) and canonname (already 0).
*
- * We might have restrictions on our protocol from the hints or from what
- * serv specifies. If we don't have a protocol yet (== 0), that means we
- * have no restrictions from serv. */
+ * We might have restrictions on our protocol from the hints or from
+ * what serv specifies. If we don't have a protocol yet (== 0), that
+ * means we have no restrictions from serv. */
if (local_hints.ai_protocol) {
if (protocol && protocol != local_hints.ai_protocol) {
/* requested protocol wasn't available */
@@ -195,8 +198,8 @@
} else {
/* no serv restrictions, no preferences */
ai->ai_protocol = IPPROTO_TCP;
- /* TODO: consider building a second addrinfo for UDP. while you're at
- * it, support IPv6 and a bunch of other options! */
+ /* TODO: consider building a second addrinfo for UDP. while
+ * you're at it, support IPv6 and a bunch of other options! */
}
if (ai->ai_protocol == -1) {
freeaddrinfo(ai);
@@ -218,6 +221,7 @@
void freeaddrinfo(struct addrinfo *ai)
{
struct addrinfo *next;
+
if (!ai)
return;
free(ai->ai_addr);
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/gethstbynm2.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/gethstbynm2.c
index a97bdde..a319333 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/gethstbynm2.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/gethstbynm2.c
@@ -9,7 +9,8 @@
int herrno_p, ret_r;
struct hostent *ret;
- ret_r = gethostbyname2_r(name, af, &h, buf, sizeof(buf), &ret, &herrno_p);
+ ret_r = gethostbyname2_r(name, af, &h, buf, sizeof(buf), &ret,
+ &herrno_p);
if (ret_r) {
/* _r method returns -ERROR on error. not sure who wants it. */
__set_errno(-ret_r);
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/gethstbynm2_r.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/gethstbynm2_r.c
index c3f35d7..f38cbdd 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/gethstbynm2_r.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/gethstbynm2_r.c
@@ -77,24 +77,24 @@
/* construct the query, always expect an ip# back */
switch (t) {
- case Tsys:
- csmsg_len = snprintf(buf, buflen, "!sys=%s ip=*", name);
- break;
- case Tdom:
- csmsg_len = snprintf(buf, buflen, "!dom=%s ip=*", name);
- break;
- case Tip:
- csmsg_len = snprintf(buf, buflen, "!ip=%s", name);
- break;
- default:
- /* we can't get here, but want to be safe for changes to
- * _sock_ipattr() */
- close(fd);
- *result = 0;
- return -EINVAL;
+ case Tsys:
+ csmsg_len = snprintf(buf, buflen, "!sys=%s ip=*", name);
+ break;
+ case Tdom:
+ csmsg_len = snprintf(buf, buflen, "!dom=%s ip=*", name);
+ break;
+ case Tip:
+ csmsg_len = snprintf(buf, buflen, "!ip=%s", name);
+ break;
+ default:
+ /* we can't get here, but want to be safe for changes to
+ * _sock_ipattr() */
+ close(fd);
+ *result = 0;
+ return -EINVAL;
}
- /* we don't update buflen, since we're just going to reuse the space after
- * our nptr/aptr/addr/etc. */
+ /* we don't update buflen, since we're just going to reuse the space
+ * after our nptr/aptr/addr/etc. */
if (csmsg_len >= buflen) {
close(fd);
*result = 0;
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getpeername.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getpeername.c
index 634b25e..c3b69bf 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getpeername.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getpeername.c
@@ -39,20 +39,20 @@
}
switch (r->domain) {
- case PF_INET:
- rip = (struct sockaddr_in *)&r->raddr;
- memmove(addr.__sockaddr_in__, rip, sizeof(struct sockaddr_in));
- *alen = sizeof(struct sockaddr_in);
- break;
- case PF_UNIX:
- runix = (struct sockaddr_un *)&r->raddr;
- i = &runix->sun_path[strlen(runix->sun_path)] - (char *)runix;
- memmove(addr.__sockaddr_un__, runix, i);
- *alen = i;
- break;
- default:
- errno = EAFNOSUPPORT;
- return -1;
+ case PF_INET:
+ rip = (struct sockaddr_in *)&r->raddr;
+ memmove(addr.__sockaddr_in__, rip, sizeof(struct sockaddr_in));
+ *alen = sizeof(struct sockaddr_in);
+ break;
+ case PF_UNIX:
+ runix = (struct sockaddr_un *)&r->raddr;
+ i = &runix->sun_path[strlen(runix->sun_path)] - (char *)runix;
+ memmove(addr.__sockaddr_un__, runix, i);
+ *alen = i;
+ break;
+ default:
+ errno = EAFNOSUPPORT;
+ return -1;
}
return 0;
}
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsockname.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsockname.c
index ec31ab4..840e236 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsockname.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsockname.c
@@ -38,19 +38,19 @@
}
switch (r->domain) {
- case PF_INET:
- lip = addr.__sockaddr_in__;
- _sock_ingetaddr(r, lip, alen, "local");
- break;
- case PF_UNIX:
- lunix = (struct sockaddr_un *)&r->addr;
- i = &lunix->sun_path[strlen(lunix->sun_path)] - (char *)lunix;
- memmove(addr.__sockaddr_un__, lunix, i);
- *alen = i;
- break;
- default:
- errno = EAFNOSUPPORT;
- return -1;
+ case PF_INET:
+ lip = addr.__sockaddr_in__;
+ _sock_ingetaddr(r, lip, alen, "local");
+ break;
+ case PF_UNIX:
+ lunix = (struct sockaddr_un *)&r->addr;
+ i = &lunix->sun_path[strlen(lunix->sun_path)] - (char *)lunix;
+ memmove(addr.__sockaddr_un__, lunix, i);
+ *alen = i;
+ break;
+ default:
+ errno = EAFNOSUPPORT;
+ return -1;
}
return 0;
}
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsockopt.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsockopt.c
index 47fbaae..859e3f5 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsockopt.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsockopt.c
@@ -28,13 +28,13 @@
if (!p)
return -1;
*p = 0;
- /* The first word in a connected TCP conv status file is 'Established'. For
- * UDP it is 'Open'.
+ /* The first word in a connected TCP conv status file is 'Established'.
+ * For UDP it is 'Open'.
*
- * For now, we'll default to no socket error, and only set the error if we
- * know we aren't Established/Open. If we want, we can parse the different
- * string values, like Established, Syn_sent, and return custom error
- * messages. But just ECONNREFUSED is fine for now. */
+ * For now, we'll default to no socket error, and only set the error if
+ * we know we aren't Established/Open. If we want, we can parse the
+ * different string values, like Established, Syn_sent, and return
+ * custom error messages. But just ECONNREFUSED is fine for now. */
ret = 0;
switch (r->stype) {
case SOCK_DGRAM:
@@ -54,19 +54,19 @@
static int sol_socket_gso(Rock *r, int optname, void *optval, socklen_t *optlen)
{
switch (optname) {
- case (SO_TYPE):
- if (*optlen < 4) {
- __set_errno(EINVAL);
- return -1;
- }
- *(int*)optval = r->stype;
- *optlen = 4;
- break;
- case (SO_ERROR):
- return sol_socket_error_gso(r, optval, optlen);
- default:
- __set_errno(ENOPROTOOPT);
+ case (SO_TYPE):
+ if (*optlen < 4) {
+ __set_errno(EINVAL);
return -1;
+ }
+ *(int*)optval = r->stype;
+ *optlen = 4;
+ break;
+ case (SO_ERROR):
+ return sol_socket_error_gso(r, optval, optlen);
+ default:
+ __set_errno(ENOPROTOOPT);
+ return -1;
};
return 0;
}
@@ -75,17 +75,18 @@
socklen_t *optlen)
{
Rock *r = _sock_findrock(sockfd, 0);
+
if (!r) {
/* could be EBADF too, we can't tell */
__set_errno(ENOTSOCK);
return -1;
}
switch (level) {
- case (SOL_SOCKET):
- return sol_socket_gso(r, optname, optval, optlen);
- default:
- __set_errno(ENOPROTOOPT);
- return -1;
+ case (SOL_SOCKET):
+ return sol_socket_gso(r, optname, optval, optlen);
+ default:
+ __set_errno(ENOPROTOOPT);
+ return -1;
};
}
weak_alias(__getsockopt, getsockopt)
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsrvbypt_r.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsrvbypt_r.c
index 96890f6..393bbcf 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsrvbypt_r.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsrvbypt_r.c
@@ -27,6 +27,7 @@
snprintf(port_buf, sizeof(port_buf), "%d", port);
/* the plan 9 version can handle a port or a name */
- return getservbyname_r(port_buf, proto, result_buf, buf, buflen, result);
+ return getservbyname_r(port_buf, proto, result_buf, buf, buflen,
+ result);
}
weak_alias(__getservbyport_r, getservbyport_r);
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/kill.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/kill.c
index b2d22c1..bad558a 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/kill.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/kill.c
@@ -28,6 +28,7 @@
int __kill (int pid, int sig)
{
struct event_msg local_msg = {0};
+
if (pid <= 0) {
errno = ENOSYS;
return -1;
@@ -36,6 +37,7 @@
return ros_syscall(SYS_proc_destroy, pid, 0, 0, 0, 0, 0);
local_msg.ev_type = EV_POSIX_SIGNAL;
local_msg.ev_arg1 = sig;
- return ros_syscall(SYS_notify, pid, EV_POSIX_SIGNAL, &local_msg, 0, 0, 0);
+ return ros_syscall(SYS_notify, pid, EV_POSIX_SIGNAL, &local_msg, 0, 0,
+ 0);
}
weak_alias (__kill, kill)
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/listen.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/listen.c
index 9586eef..987ea76 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/listen.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/listen.c
@@ -43,37 +43,38 @@
}
switch (r->domain) {
- case PF_INET:
- lip = (struct sockaddr_in *)&r->addr;
- if (lip->sin_port >= 0) {
- if (write(r->ctl_fd, "bind 0", 6) < 0) {
- errno = EINVAL; //EGREG;
- return -1;
- }
- snprintf(msg, sizeof msg, "announce %d", ntohs(lip->sin_port));
- } else
- strcpy(msg, "announce *");
- n = write(r->ctl_fd, msg, strlen(msg));
- if (n < 0) {
- errno = EOPNOTSUPP; /* Improve error reporting!!! */
- return -1;
- }
- return 0;
- case PF_UNIX:
- if (r->other < 0) {
+ case PF_INET:
+ lip = (struct sockaddr_in *)&r->addr;
+ if (lip->sin_port >= 0) {
+ if (write(r->ctl_fd, "bind 0", 6) < 0) {
errno = EINVAL; //EGREG;
return -1;
}
- lunix = (struct sockaddr_un *)&r->addr;
- if (_sock_srv(lunix->sun_path, r->other) < 0) {
- r->other = -1;
- return -1;
- }
- r->other = -1;
- return 0;
- default:
- errno = EAFNOSUPPORT;
+ snprintf(msg, sizeof msg, "announce %d",
+ ntohs(lip->sin_port));
+ } else
+ strcpy(msg, "announce *");
+ n = write(r->ctl_fd, msg, strlen(msg));
+ if (n < 0) {
+ errno = EOPNOTSUPP; /* Improve error reporting!!! */
return -1;
+ }
+ return 0;
+ case PF_UNIX:
+ if (r->other < 0) {
+ errno = EINVAL; //EGREG;
+ return -1;
+ }
+ lunix = (struct sockaddr_un *)&r->addr;
+ if (_sock_srv(lunix->sun_path, r->other) < 0) {
+ r->other = -1;
+ return -1;
+ }
+ r->other = -1;
+ return 0;
+ default:
+ errno = EAFNOSUPPORT;
+ return -1;
}
}
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/lseek.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/lseek.c
index c6f0091..7c7ac2f 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/lseek.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/lseek.c
@@ -11,6 +11,7 @@
off_t hi = 0;
off_t lo = 0;
off_t ret;
+
if (fd < 0) {
__set_errno (EBADF);
return -1;
@@ -24,8 +25,8 @@
__set_errno (EINVAL);
return -1;
}
- /* get the high and low part, regardless of whether offset was already 64
- * bits or not (casting to avoid warnings) */
+ /* get the high and low part, regardless of whether offset was already
+ * 64 bits or not (casting to avoid warnings) */
hi = (loff_t)offset >> 32;
lo = offset & 0xffffffff;
ret = ros_syscall(SYS_llseek, fd, hi, lo, &retoff, whence, 0);
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/lseek64.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/lseek64.c
index c1286c4..11f67ef 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/lseek64.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/lseek64.c
@@ -35,13 +35,13 @@
return -1;
}
switch (whence) {
- case SEEK_SET:
- case SEEK_CUR:
- case SEEK_END:
- break;
- default:
- __set_errno (EINVAL);
- return -1;
+ case SEEK_SET:
+ case SEEK_CUR:
+ case SEEK_END:
+ break;
+ default:
+ __set_errno (EINVAL);
+ return -1;
}
hi = offset >> 32;
lo = offset & 0xffffffff;
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/malloc-machine.h b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/malloc-machine.h
index be8060e..119e7fe 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/malloc-machine.h
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/malloc-machine.h
@@ -37,10 +37,10 @@
#include <bits/libc-tsd.h>
typedef void* tsd_key_t; /* no key data structure, libc magic does it */
-__libc_tsd_define (static, void *, MALLOC) /* declaration/common definition */
-#define tsd_key_create(key, destr) ((void) (key))
-#define tsd_setspecific(key, data) __libc_tsd_set (void *, MALLOC, (data))
-#define tsd_getspecific(key, vptr) ((vptr) = __libc_tsd_get (void *, MALLOC))
+__libc_tsd_define (static, void *, MALLOC) /* declaration/common definition */
+#define tsd_key_create(key, destr) ((void) (key))
+#define tsd_setspecific(key, data) __libc_tsd_set (void *, MALLOC, (data))
+#define tsd_getspecific(key, vptr) ((vptr) = __libc_tsd_get (void *, MALLOC))
/* TODO: look into pthread's version. We might need this, and it could be that
* glibc has the fork_cbs already. */
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/nanosleep.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/nanosleep.c
index 94c2d14..0ad88e6 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/nanosleep.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/nanosleep.c
@@ -23,7 +23,8 @@
int __libc_nanosleep(const struct timespec *requested_time,
struct timespec *remaining)
{
- return ros_syscall(SYS_nanosleep, requested_time, remaining, 0, 0, 0, 0);
+ return ros_syscall(SYS_nanosleep, requested_time, remaining, 0, 0, 0,
+ 0);
}
weak_alias(__libc_nanosleep, __nanosleep)
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/parlib-compat.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/parlib-compat.c
index bef8997..0d1f072 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/parlib-compat.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/parlib-compat.c
@@ -120,8 +120,8 @@
void __uthread_sched_yield(void)
{
- /* In the off-chance we're called before parlib is available, we'll do the
- * single-threaded, SCP yield. */
+ /* In the off-chance we're called before parlib is available, we'll do
+ * the single-threaded, SCP yield. */
ros_syscall(SYS_proc_yield, TRUE, 0, 0, 0, 0, 0);
}
weak_alias(__uthread_sched_yield, uthread_sched_yield)
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/plan9_sockets.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/plan9_sockets.c
index ceb065a..4d175b1 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/plan9_sockets.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/plan9_sockets.c
@@ -337,8 +337,8 @@
open_flags = O_PATH;
open_flags |= (r->sopts & SOCK_CLOEXEC ? O_CLOEXEC : 0);
ret = open(listen_file, open_flags);
- /* Probably a bug in the rock code (or the kernel!) if we couldn't walk to
- * our listen. */
+ /* Probably a bug in the rock code (or the kernel!) if we couldn't walk
+ * to our listen. */
assert(ret >= 0);
r->listen_fd = ret;
r->has_listen_fd = TRUE;
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/recvfrom.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/recvfrom.c
index 3e449bd..a44ceb4 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/recvfrom.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/recvfrom.c
@@ -36,8 +36,8 @@
real_iov[0].iov_len = P9_UDP_HDR_SZ;
memcpy(real_iov + 1, iov, iovcnt * sizeof(struct iovec));
ret = readv(fd, real_iov, iovcnt + 1);
- /* Subtracting before the check, so that we error out if we got less than
- * the headers needed */
+ /* Subtracting before the check, so that we error out if we got less
+ * than the headers needed */
ret -= P9_UDP_HDR_SZ;
if (ret < 0)
return -1;
@@ -75,9 +75,8 @@
/* Read N bytes into BUF through socket FD from peer at address FROM (which is
* FROMLEN bytes long). Returns the number read or -1 for errors. */
-ssize_t __recvfrom(int fd, void *__restrict buf, size_t n,
- int flags, __SOCKADDR_ARG from,
- socklen_t * __restrict fromlen)
+ssize_t __recvfrom(int fd, void *__restrict buf, size_t n, int flags,
+ __SOCKADDR_ARG from, socklen_t * __restrict fromlen)
{
struct iovec iov[1];
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sbrk.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sbrk.c
index dbc17d5..d814cdb 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sbrk.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sbrk.c
@@ -74,12 +74,13 @@
{
if(real_new_brk > BRK_END)
return -1;
- // calling mmap directly to avoid referencing errno before it is initialized.
+ // calling mmap directly to avoid referencing errno before it is
+ // initialized.
if ((void*)__ros_syscall_noerrno(SYS_mmap, (long)real_brk,
- real_new_brk-real_brk,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE,
- -1, 0) != (void*)real_brk)
+ real_new_brk-real_brk, PROT_READ |
+ PROT_WRITE | PROT_EXEC, MAP_FIXED |
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)
+ != (void*)real_brk)
return -1;
}
else if(real_new_brk < real_brk)
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sendmsg.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sendmsg.c
index c998eb7..240a6ab 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sendmsg.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sendmsg.c
@@ -16,7 +16,7 @@
* sent, or -1 for errors. */
ssize_t __sendmsg(int fd, const struct msghdr *msg, int flags)
{
- return __sendto_iov(fd, msg->msg_iov, msg->msg_iovlen, flags, msg->msg_name,
- msg->msg_namelen);
+ return __sendto_iov(fd, msg->msg_iov, msg->msg_iovlen, flags,
+ msg->msg_name, msg->msg_namelen);
}
weak_alias(__sendmsg, sendmsg)
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sendto.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sendto.c
index a36cb24..bfe10f5 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sendto.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sendto.c
@@ -40,8 +40,8 @@
/* Might not have a to if we were called from send() */
if (!to.__sockaddr__) {
- /* if they didn't connect yet, then there's no telling what raddr
- * will be. TODO: check a state flag or something? */
+ /* if they didn't connect yet, then there's no telling what
+ * raddr will be. TODO: check a state flag or something? */
to.__sockaddr__ = (struct sockaddr *)(&r->raddr);
}
remote_addr = (to.__sockaddr_in__)->sin_addr.s_addr;
@@ -83,8 +83,8 @@
/* Send N bytes of BUF on socket FD to peer at address TO (which is TOLEN bytes
* long). Returns the number sent, or -1 for errors. */
-ssize_t __sendto(int fd, const void *buf, size_t n,
- int flags, __CONST_SOCKADDR_ARG to, socklen_t tolen)
+ssize_t __sendto(int fd, const void *buf, size_t n, int flags,
+ __CONST_SOCKADDR_ARG to, socklen_t tolen)
{
struct iovec iov[1];
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/serialize.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/serialize.c
index e494585..2185082 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/serialize.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/serialize.c
@@ -28,14 +28,16 @@
/* Reserve space in the buffer for each of our arguments (the +1 comes
* from the '\0' character) */
int arglens[argc];
+
for (int i = 0; i < argc; i++) {
arglens[i] = strlen(argv[i]) + 1;
bufsize += arglens[i];
}
- /* Reserve space in our buffer for each of our environment variables (the
- * +1 comes from the '\0' character) */
+ /* Reserve space in our buffer for each of our environment variables
+ * (the +1 comes from the '\0' character) */
int envlens[envc];
+
for (int i = 0; i < envc; i++) {
envlens[i] = strlen(envp[i]) + 1;
bufsize += envlens[i];
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/setsockopt.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/setsockopt.c
index 38bb7cb..462dd54 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/setsockopt.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/setsockopt.c
@@ -10,19 +10,19 @@
static int sol_socket_sso(Rock *r, int optname, void *optval, socklen_t optlen)
{
switch (optname) {
- #if 0
- /* We don't support setting any options yet */
- case (SO_FOO):
- if (optlen < foo_len) {
- __set_errno(EINVAL);
- return -1;
- }
- r->foo = *optval;
- break;
- #endif
- default:
- __set_errno(ENOPROTOOPT);
+ #if 0
+ /* We don't support setting any options yet */
+ case (SO_FOO):
+ if (optlen < foo_len) {
+ __set_errno(EINVAL);
return -1;
+ }
+ r->foo = *optval;
+ break;
+ #endif
+ default:
+ __set_errno(ENOPROTOOPT);
+ return -1;
};
return 0;
}
@@ -38,11 +38,11 @@
return -1;
}
switch (level) {
- case (SOL_SOCKET):
- return sol_socket_sso(r, optname, optval, optlen);
- default:
- __set_errno(ENOPROTOOPT);
- return -1;
+ case (SOL_SOCKET):
+ return sol_socket_sso(r, optname, optval, optlen);
+ default:
+ __set_errno(ENOPROTOOPT);
+ return -1;
};
}
weak_alias (__setsockopt, setsockopt)
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sigaction.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sigaction.c
index bf6760c..8adafb6 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sigaction.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sigaction.c
@@ -47,8 +47,9 @@
else
akaros_printf("No ctx for %s\n", __func__);
if (info) {
- /* ghetto, we don't have access to the PF err, since we only have a few
- * fields available in siginfo (e.g. there's no si_trapno). */
+ /* ghetto, we don't have access to the PF err, since we only
+ * have a few fields available in siginfo (e.g. there's no
+ * si_trapno). */
akaros_printf("Fault type %d at addr %p\n", info->si_errno,
info->si_addr);
} else {
@@ -117,10 +118,11 @@
if (sig_nr >= _NSIG || sig_nr < 0)
return;
action = &sigactions[sig_nr];
- /* Would like a switch/case here, but they are pointers. We can also get
- * away with this check early since sa_handler and sa_sigaction are macros
- * referencing the same union. The man page isn't specific about whether or
- * not you need to care about SA_SIGINFO when sending DFL/ERR/IGN. */
+ /* Would like a switch/case here, but they are pointers. We can also
+ * get away with this check early since sa_handler and sa_sigaction are
+ * macros referencing the same union. The man page isn't specific about
+ * whether or not you need to care about SA_SIGINFO when sending
+ * DFL/ERR/IGN. */
if (action->sa_handler == SIG_ERR)
return;
if (action->sa_handler == SIG_IGN)
@@ -137,15 +139,16 @@
if (info == NULL)
info = &s;
- /* Make sure the caller either already set singo in the info struct, or
- * if they didn't, make sure it has been zeroed out (i.e. not just some
- * garbage on the stack. */
+ /* Make sure the caller either already set singo in the info
+ * struct, or if they didn't, make sure it has been zeroed out
+ * (i.e. not just some garbage on the stack. */
assert(info->si_signo == sig_nr || info->si_signo == 0);
info->si_signo = sig_nr;
/* TODO: consider info->pid and whatnot */
- /* We assume that this function follows the proper calling convention
- * (i.e. it wasn't written in some crazy assembly function that
- * trashes all its registers, i.e GO's default runtime handler) */
+ /* We assume that this function follows the proper calling
+ * convention (i.e. it wasn't written in some crazy assembly
+ * function that trashes all its registers, i.e GO's default
+ * runtime handler) */
action->sa_sigaction(sig_nr, info, aux);
} else {
action->sa_handler(sig_nr);
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/socket.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/socket.c
index 9a29049..9b610ed 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/socket.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/socket.c
@@ -49,58 +49,58 @@
parlib_run_once(&once, socket_init, NULL);
switch (domain) {
- case PF_INET:
- open_flags = O_RDWR;
- open_flags |= (type & SOCK_CLOEXEC ? O_CLOEXEC : 0);
- /* get a free network directory */
- switch (_sock_strip_opts(type)) {
- case SOCK_DGRAM:
- net = "udp";
- cfd = open("/net/udp/clone", open_flags);
- /* All BSD UDP sockets are in 'headers' mode, where each
- * packet has the remote addr:port, local addr:port and
- * other info. */
- if (!(cfd < 0)) {
- n = snprintf(msg, sizeof(msg), "headers");
- n = write(cfd, msg, n);
- if (n < 0) {
- perror("UDP socket headers failed");
- return -1;
- }
- if (lseek(cfd, 0, SEEK_SET) != 0) {
- perror("UDP socket seek failed");
- return -1;
- }
- }
- break;
- case SOCK_STREAM:
- net = "tcp";
- cfd = open("/net/tcp/clone", open_flags);
- break;
- default:
- errno = EPROTONOSUPPORT;
+ case PF_INET:
+ open_flags = O_RDWR;
+ open_flags |= (type & SOCK_CLOEXEC ? O_CLOEXEC : 0);
+ /* get a free network directory */
+ switch (_sock_strip_opts(type)) {
+ case SOCK_DGRAM:
+ net = "udp";
+ cfd = open("/net/udp/clone", open_flags);
+ /* All BSD UDP sockets are in 'headers' mode, where each
+ * packet has the remote addr:port, local addr:port and
+ * other info. */
+ if (!(cfd < 0)) {
+ n = snprintf(msg, sizeof(msg), "headers");
+ n = write(cfd, msg, n);
+ if (n < 0) {
+ perror("UDP socket headers failed");
return -1;
+ }
+ if (lseek(cfd, 0, SEEK_SET) != 0) {
+ perror("UDP socket seek failed");
+ return -1;
+ }
}
- if (cfd < 0) {
- return -1;
- }
- return _sock_data(cfd, net, domain, type, protocol, 0);
- case PF_UNIX:
- open_flags = 0;
- open_flags |= (type & SOCK_CLOEXEC ? O_CLOEXEC : 0);
- open_flags |= (type & SOCK_NONBLOCK ? O_CLOEXEC : 0);
- if (pipe2(pfd, open_flags) < 0)
- return -1;
- r = _sock_newrock(pfd[0]);
- r->domain = domain;
- r->stype = _sock_strip_opts(type);
- r->sopts = _sock_get_opts(type);
- r->protocol = protocol;
- r->other = pfd[1];
- return pfd[0];
+ break;
+ case SOCK_STREAM:
+ net = "tcp";
+ cfd = open("/net/tcp/clone", open_flags);
+ break;
default:
errno = EPROTONOSUPPORT;
return -1;
+ }
+ if (cfd < 0) {
+ return -1;
+ }
+ return _sock_data(cfd, net, domain, type, protocol, 0);
+ case PF_UNIX:
+ open_flags = 0;
+ open_flags |= (type & SOCK_CLOEXEC ? O_CLOEXEC : 0);
+ open_flags |= (type & SOCK_NONBLOCK ? O_CLOEXEC : 0);
+ if (pipe2(pfd, open_flags) < 0)
+ return -1;
+ r = _sock_newrock(pfd[0]);
+ r->domain = domain;
+ r->stype = _sock_strip_opts(type);
+ r->sopts = _sock_get_opts(type);
+ r->protocol = protocol;
+ r->other = pfd[1];
+ return pfd[0];
+ default:
+ errno = EPROTONOSUPPORT;
+ return -1;
}
}
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/socketpair.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/socketpair.c
index 59adf62..c7cd9f5 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/socketpair.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/socketpair.c
@@ -25,10 +25,10 @@
int socketpair(int domain, int type, int protocol, int *sv)
{
switch (domain) {
- case PF_UNIX:
- return pipe(sv);
- default:
- errno = EOPNOTSUPP;
- return -1;
+ case PF_UNIX:
+ return pipe(sv);
+ default:
+ errno = EOPNOTSUPP;
+ return -1;
}
}
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/close_cb.h b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/close_cb.h
index 784a977..33727df 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/close_cb.h
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/close_cb.h
@@ -21,7 +21,7 @@
#pragma once
struct close_cb {
- struct close_cb *next;
+ struct close_cb *next;
void (*func)(int fd);
};
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/fork_cb.h b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/fork_cb.h
index 6735ce4..b7b1b5d 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/fork_cb.h
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/fork_cb.h
@@ -30,7 +30,7 @@
extern void (*post_fork_2ls)(pid_t ret);
struct fork_cb {
- struct fork_cb *next;
+ struct fork_cb *next;
void (*func)(void);
};
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/plan9_helpers.h b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/plan9_helpers.h
index 2c922a6..3d54db3 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/plan9_helpers.h
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/plan9_helpers.h
@@ -42,13 +42,13 @@
*/
struct Rock {
Rock *next;
- unsigned long dev; /* inode & dev of data file */
- unsigned long inode; /* ... */
- int domain; /* from socket call */
- int stype; /* socket type, from socket()'s type field */
- int sopts; /* socket options, from socket()'s type field */
- int protocol; /* ... */
- int reserved; /* use a priveledged port # (< 1024) */
+ unsigned long dev; /* inode & dev of data file */
+ unsigned long inode; /* ... */
+ int domain; /* from socket call */
+ int stype; /* socket type, from socket()'s type field */
+ int sopts; /* socket options, from socket()'s type field */
+ int protocol; /* ... */
+ int reserved; /* use a priveledged port # (< 1024) */
union {
struct sockaddr addr; /* address from bind */
struct sockaddr_storage addr_stor;
@@ -57,11 +57,11 @@
struct sockaddr raddr; /* peer address */
struct sockaddr_storage raddr_stor;
};
- char ctl[Ctlsize]; /* Only used for relative path lookups now */
- int ctl_fd; /* fd of the ctl file */
- int other; /* fd of the remote end for Unix domain */
- bool has_listen_fd; /* has set up a listen file, O_PATH */
- int listen_fd; /* fd of the listen file, if any */
+ char ctl[Ctlsize]; /* Only used for relative path lookups now */
+ int ctl_fd; /* fd of the ctl file */
+ int other; /* fd of the remote end for Unix domain */
+ bool has_listen_fd; /* has set up a listen file, O_PATH */
+ int listen_fd; /* fd of the listen file, if any */
};
extern Rock *_sock_findrock(int, struct stat *);
@@ -73,7 +73,7 @@
extern int _sock_ipattr(const char *);
extern void _sock_get_conv_filename(Rock *r, const char *name, char *retloc);
extern void _sock_ingetaddr(Rock *, struct sockaddr_in *, socklen_t *,
- const char *);
+ const char *);
extern int _sock_strip_opts(int type);
extern int _sock_get_opts(int type);
extern void _sock_lookup_rock_fds(int sock_fd, bool can_open_listen_fd,
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/user_fd.h b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/user_fd.h
index e0c3e25..9c80bea 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/user_fd.h
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/user_fd.h
@@ -28,8 +28,8 @@
* 'magic' can be whatever the client wants - it could be useful to make sure
* you have the right type of FD. */
struct user_fd {
- int magic;
- int fd;
+ int magic;
+ int fd;
void (*close)(struct user_fd *);
};
@@ -40,15 +40,15 @@
/* Given an FD, returns the user_fd struct. Returns 0 and sets errno if there's
* an error. There's no protection for concurrent closes, just like how you
* shouldn't attempt to use an FD after closing. So don't do stuff like:
- * foo = ufd_lookup(7);
- * close(7);
- * foo->whatever = 6; // foo could be free!
+ * foo = ufd_lookup(7);
+ * close(7);
+ * foo->whatever = 6; // foo could be free!
*
* or
- * close(7);
- * foo = ufd_lookup(7);
+ * close(7);
+ * foo = ufd_lookup(7);
* // this might succeed if it races with close()
- * foo->whatever = 6; // foo could be free!
+ * foo->whatever = 6; // foo could be free!
*/
struct user_fd *ufd_lookup(int fd);
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/syscall.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/syscall.c
index 6d69788..dfa87fc 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/syscall.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/syscall.c
@@ -44,17 +44,19 @@
int old_flags;
sysc->ev_q = ev_q;
wrmb(); /* don't let that write pass any future reads (flags) */
- /* Try and set the SC_UEVENT flag (so the kernel knows to look at ev_q) */
+ /* Try and set the SC_UEVENT flag (so the kernel knows to look at ev_q)
+ */
do {
/* no cmb() needed, the atomic_read will reread flags */
old_flags = atomic_read(&sysc->flags);
/* Spin if the kernel is mucking with syscall flags */
while (old_flags & SC_K_LOCK)
old_flags = atomic_read(&sysc->flags);
- /* If the kernel finishes while we are trying to sign up for an event,
- * we need to bail out */
+ /* If the kernel finishes while we are trying to sign up for an
+ * event, we need to bail out */
if (old_flags & (SC_DONE | SC_PROGRESS)) {
- sysc->ev_q = 0; /* not necessary, but might help with bugs */
+ /* not necessary, but might help with bugs */
+ sysc->ev_q = 0;
return FALSE;
}
} while (!atomic_cas(&sysc->flags, old_flags, old_flags | SC_UEVENT));
@@ -73,23 +75,26 @@
* we drop into VC ctx, clear notif pending, and yield. */
void __ros_early_syscall_blockon(struct syscall *sysc)
{
- /* For early SCPs, notif_pending will probably be false anyways. For SCPs
- * in VC ctx, it might be set. Regardless, when we pop back up,
+ /* For early SCPs, notif_pending will probably be false anyways. For
+ * SCPs in VC ctx, it might be set. Regardless, when we pop back up,
* notif_pending will be set (for a full SCP in VC ctx). */
__procdata.vcore_preempt_data[0].notif_pending = FALSE;
- /* order register after clearing notif_pending, handled by register_evq */
- /* Ask for a SYSCALL event when the sysc is done. We don't need a handler,
- * we just need the kernel to restart us from proc_yield. If register
- * fails, we're already done. */
+ /* order register after clearing notif_pending, handled by register_evq
+ */
+ /* Ask for a SYSCALL event when the sysc is done. We don't need a
+ * handler, we just need the kernel to restart us from proc_yield. If
+ * register fails, we're already done. */
if (register_evq(sysc, &__ros_scp_simple_evq)) {
- /* Sending false for now - we want to signal proc code that we want to
- * wait (piggybacking on the MCP meaning of this variable). If
- * notif_pending is set, the kernel will immediately return us. */
+ /* Sending false for now - we want to signal proc code that we
+ * want to wait (piggybacking on the MCP meaning of this
+ * variable). If notif_pending is set, the kernel will
+ * immediately return us. */
__ros_syscall_noerrno(SYS_proc_yield, FALSE, 0, 0, 0, 0, 0);
}
- /* For early SCPs, the kernel turns off notif_pending for us. For SCPs in
- * vcore context that blocked (should be rare!), it'll still be set. Other
- * VC ctx code must handle it later. (could have coalesced notifs) */
+ /* For early SCPs, the kernel turns off notif_pending for us. For SCPs
+ * in vcore context that blocked (should be rare!), it'll still be set.
+ * Other VC ctx code must handle it later. (could have coalesced notifs)
+ */
}
/* Function pointer for the blockon function. MCPs need to switch to the parlib
@@ -100,13 +105,13 @@
static inline void __ros_syscall_sync(struct syscall *sysc)
{
/* There is only one syscall in the syscall array when we want to do it
- * synchronously */
+ * synchronously */
__ros_arch_syscall((long)sysc, 1);
/* Don't proceed til we are done */
while (!(atomic_read(&sysc->flags) & SC_DONE))
ros_syscall_blockon(sysc);
- /* Need to wait til it is unlocked. It's not really done until SC_DONE &
- * !SC_K_LOCK. */
+ /* Need to wait til it is unlocked. It's not really done until SC_DONE
+ * & !SC_K_LOCK. */
while (atomic_read(&sysc->flags) & SC_K_LOCK)
cpu_relax();
}
@@ -132,7 +137,7 @@
sysc.arg3 = _a3;
sysc.arg4 = _a4;
sysc.arg5 = _a5;
- __ros_syscall_sync(&sysc);
+ __ros_syscall_sync(&sysc);
return sysc;
}
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/time.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/time.c
index 8abf8ac..e614e02 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/time.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/time.c
@@ -43,7 +43,8 @@
if (minuend->tv_nsec < subtrahend->tv_nsec)
borrow_amt = 1000000000;
diff->tv_nsec = borrow_amt + minuend->tv_nsec - subtrahend->tv_nsec;
- diff->tv_sec = minuend->tv_sec - subtrahend->tv_sec - (borrow_amt ? 1 : 0);
+ diff->tv_sec = minuend->tv_sec - subtrahend->tv_sec
+ - (borrow_amt ? 1 : 0);
}
/* Declared in parlib/timing.h */
@@ -62,8 +63,9 @@
uint64_t epoch_nsec(void)
{
- /* in case we get called before the constructor. it's a little racy, but
- * this all happens when we're single threaded. for those curious, this
- * seems to happen a lot due to the proliferation of gettimeofday calls. */
+ /* in case we get called before the constructor. it's a little racy,
+ * but this all happens when we're single threaded. for those curious,
+ * this seems to happen a lot due to the proliferation of gettimeofday
+ * calls. */
return tsc_to_epoch_nsec(read_tsc());
}
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/timerfd.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/timerfd.c
index 093eb44..eb7f437 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/timerfd.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/timerfd.c
@@ -83,20 +83,21 @@
if (read(timerfd, buf, sizeof(buf) <= 0))
return -1;
timer_tsc = strtoul(buf, 0, 0);
- /* If 0 (disabled), we'll return 0 for 'it_value'. o/w we need to return
- * the relative time. */
+ /* If 0 (disabled), we'll return 0 for 'it_value'. o/w we need to
+ * return the relative time. */
if (timer_tsc) {
now_tsc = read_tsc();
if (timer_tsc > now_tsc) {
timer_tsc -= now_tsc;
} else {
- /* it's possible that timer_tsc is in the past, and that we lost the
- * race. The alarm fired since we looked at it, and it might be
- * disabled. It might have fired multiple times too. */
+ /* it's possible that timer_tsc is in the past, and that
+ * we lost the race. The alarm fired since we looked at
+ * it, and it might be disabled. It might have fired
+ * multiple times too. */
if (!period_tsc) {
- /* if there was no period and the alarm fired, then it should be
- * disabled. This is racy, if there are other people setting
- * the timer. */
+ /* if there was no period and the alarm fired,
+ * then it should be disabled. This is racy, if
+ * there are other people setting the timer. */
timer_tsc = 0;
} else {
while (timer_tsc < now_tsc)
@@ -140,16 +141,17 @@
ret = set_period(periodfd, period);
if (ret < 0)
goto out;
- /* So the caller is asking for timespecs in wall-clock time (depending on
- * the clock, actually, (TODO)), and the kernel expects TSC ticks from boot.
- * If !ABSTIME, then it's just relative to now. If it is ABSTIME, then they
- * are asking in terms of real-world time, which means ABS - NOW to get the
- * rel time, then convert to tsc ticks. */
+ /* So the caller is asking for timespecs in wall-clock time (depending
+ * on the clock, actually, (TODO)), and the kernel expects TSC ticks
+ * from boot. If !ABSTIME, then it's just relative to now. If it is
+ * ABSTIME, then they are asking in terms of real-world time, which
+ * means ABS - NOW to get the rel time, then convert to tsc ticks. */
if (flags & TFD_TIMER_ABSTIME) {
ret = clock_gettime(CLOCK_MONOTONIC, &now_timespec);
if (ret < 0)
goto out;
- subtract_timespecs(&rel_timespec, &new_value->it_value, &now_timespec);
+ subtract_timespecs(&rel_timespec, &new_value->it_value,
+ &now_timespec);
} else {
rel_timespec = new_value->it_value;
}
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/tls.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/tls.c
index d50acab..3fc3e5c 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/tls.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/tls.c
@@ -21,10 +21,10 @@
if (!tcb)
return 0;
#ifdef TLS_TCB_AT_TP
- /* Make sure the TLS is set up properly - its tcb pointer points to itself.
- * Keep this in sync with sysdeps/akaros/XXX/tls.h. For whatever reason,
- * dynamically linked programs do not need this to be redone, but statics
- * do. */
+ /* Make sure the TLS is set up properly - its tcb pointer points to
+ * itself. Keep this in sync with sysdeps/akaros/XXX/tls.h. For
+ * whatever reason, dynamically linked programs do not need this to be
+ * redone, but statics do. */
tcbhead_t *head = (tcbhead_t*)tcb;
head->tcb = tcb;
head->self = tcb;
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/user_fd.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/user_fd.c
index 10afc59..22d0855 100644
--- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/user_fd.c
+++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/user_fd.c
@@ -30,21 +30,24 @@
int fd;
if (!ufds) {
- nr_ufds = 1 << (sizeof(int) * 8 - LOG2_UP(NR_FILE_DESC_MAX) - 1);
- /* Two things: instead of worrying about growing and reallocing (which
- * would need a lock), let's just alloc the entire 2^15 bytes (32KB).
- * Also, it's unlikely, but we might have two threads trying to init at
- * once. First one wins, second one aborts (and frees). */
+ nr_ufds = 1 << (sizeof(int) * 8 - LOG2_UP(NR_FILE_DESC_MAX)
+ - 1);
+ /* Two things: instead of worrying about growing and reallocing
+ * (which would need a lock), let's just alloc the entire 2^15
+ * bytes (32KB). Also, it's unlikely, but we might have two
+ * threads trying to init at once. First one wins, second one
+ * aborts (and frees). */
new_ufds = malloc(sizeof(struct user_fd*) * nr_ufds);
memset(new_ufds, 0, sizeof(struct user_fd*) * nr_ufds);
if (!atomic_cas_ptr((void**)&ufds, 0, new_ufds))
free(new_ufds);
cmb();
}
- /* At this point, ufds is set. Just do a linear search for an empty slot.
- * We're not actually bound to return the lowest number available, so in the
- * future we could do things like partition the space based on vcoreid so we
- * start in different areas, or maintain a 'last used' hint FD. */
+ /* At this point, ufds is set. Just do a linear search for an empty
+ * slot. We're not actually bound to return the lowest number
+ * available, so in the future we could do things like partition the
+ * space based on vcoreid so we start in different areas, or maintain a
+ * 'last used' hint FD. */
for (int i = 0; i < nr_ufds; i++) {
if (!ufds[i]) {
if (atomic_cas_ptr((void**)&ufds[i], 0, ufd)) {
@@ -61,15 +64,15 @@
/* Given an FD, returns the user_fd struct. Returns 0 and sets errno if there's
* an error. There's no protection for concurrent closes, just like how you
* shouldn't attempt to use an FD after closing. So don't do stuff like:
- * foo = ufd_lookup(7);
- * close(7);
- * foo->whatever = 6; // foo could be free!
+ * foo = ufd_lookup(7);
+ * close(7);
+ * foo->whatever = 6; // foo could be free!
*
* or
- * close(7);
- * foo = ufd_lookup(7);
- * // this might succeed if it races with close()
- * foo->whatever = 6; // foo could be free!
+ * close(7);
+ * foo = ufd_lookup(7);
+ * // this might succeed if it races with close()
+ * foo->whatever = 6; // foo could be free!
*/
struct user_fd *ufd_lookup(int fd)
{
diff --git a/tools/dev-util/perf/perf.c b/tools/dev-util/perf/perf.c
index 6116af3..1938fcf 100644
--- a/tools/dev-util/perf/perf.c
+++ b/tools/dev-util/perf/perf.c
@@ -26,7 +26,7 @@
/* Helpers */
static void run_process_and_wait(int argc, char *argv[],
- const struct core_set *cores);
+ const struct core_set *cores);
/* For communicating with perf_create_context() */
static struct perf_context_config perf_cfg = {
@@ -40,24 +40,24 @@
extern char **environ; /* POSIX envp */
struct perf_opts {
- FILE *outfile;
- const char *events;
- char **cmd_argv;
- int cmd_argc;
- struct core_set cores;
- bool got_cores;
- bool verbose;
- bool sampling;
- bool stat_bignum;
- bool record_quiet;
- unsigned long record_period;
+ FILE *outfile;
+ const char *events;
+ char **cmd_argv;
+ int cmd_argc;
+ struct core_set cores;
+ bool got_cores;
+ bool verbose;
+ bool sampling;
+ bool stat_bignum;
+ bool record_quiet;
+ unsigned long record_period;
};
static struct perf_opts opts;
struct perf_cmd {
- char *name;
- char *desc;
- char *opts;
+ char *name;
+ char *desc;
+ char *opts;
int (*func)(struct perf_cmd *, int, char **);
};
@@ -108,11 +108,12 @@
for (int i = 0; i < COUNT_OF(perf_cmds); i++) {
if (!strcmp(perf_cmds[i].name, argv[1])) {
if (perf_cmds[i].opts) {
- fprintf(stdout, "perf %s %s\n", perf_cmds[i].name,
- perf_cmds[i].opts);
+ fprintf(stdout, "perf %s %s\n",
+ perf_cmds[i].name, perf_cmds[i].opts);
fprintf(stdout, "\t%s\n", perf_cmds[i].desc);
} else {
- /* For argp subcommands, call their help directly. */
+ /* For argp subcommands, call their help
+ * directly. */
sub_argv[0] = xstrdup(perf_cmds[i].name);
sub_argv[1] = xstrdup("--help");
perf_cmds[i].func(&perf_cmds[i], 2, sub_argv);
@@ -151,9 +152,9 @@
"PERF.counters_x_proc = %u\n"
"PERF.bits_x_fix_counter = %u\n"
"PERF.fix_counters_x_proc = %u\n",
- pai->perfmon_version, pai->proc_arch_events, pai->bits_x_counter,
- pai->counters_x_proc, pai->bits_x_fix_counter,
- pai->fix_counters_x_proc);
+ pai->perfmon_version, pai->proc_arch_events,
+ pai->bits_x_counter, pai->counters_x_proc,
+ pai->bits_x_fix_counter, pai->fix_counters_x_proc);
return 0;
}
@@ -197,7 +198,8 @@
break;
case ARGP_KEY_ARG:
p_opts->cmd_argc = state->argc - state->next + 1;
- p_opts->cmd_argv = xmalloc(sizeof(char*) * (p_opts->cmd_argc + 1));
+ p_opts->cmd_argv = xmalloc(sizeof(char*) *
+ (p_opts->cmd_argc + 1));
p_opts->cmd_argv[0] = arg;
memcpy(&p_opts->cmd_argv[1], &state->argv[state->next],
sizeof(char*) * (p_opts->cmd_argc - 1));
@@ -228,7 +230,7 @@
const char *fmt = "perf %s";
size_t cmd_sz = strlen(cmd->name) + strlen(fmt) + 1;
- /* Rewrite the command name from foo to perf foo for the --help output */
+ /* Rewrite the command name from foo to perf foo for the --help output*/
cmd_name = xmalloc(cmd_sz);
snprintf(cmd_name, cmd_sz, fmt, cmd->name);
cmd_name[cmd_sz - 1] = '\0';
@@ -246,7 +248,7 @@
dup_evts = xstrdup(opts->events);
for (tok = strtok_r(dup_evts, ",", &tok_save);
tok;
- tok = strtok_r(NULL, ",", &tok_save)) {
+ tok = strtok_r(NULL, ",", &tok_save)) {
sel = perf_parse_event(tok);
PMEV_SET_INTEN(sel->ev.event, opts->sampling);
@@ -285,14 +287,16 @@
switch (key) {
case 'c':
if (p_opts->record_period)
- argp_error(state, "Period set. Only use at most one of -c -F");
+ argp_error(state,
+ "Period set. Only use at most one of -c -F");
p_opts->record_period = atol(arg);
break;
case 'F':
if (p_opts->record_period)
- argp_error(state, "Period set. Only use at most one of -c -F");
- /* TODO: when we properly support freq, multiple events will have the
- * same freq but different, dynamic, periods. */
+ argp_error(state,
+ "Period set. Only use at most one of -c -F");
+ /* TODO: when we properly support freq, multiple events will
+ * have the same freq but different, dynamic, periods. */
p_opts->record_period = freq_to_period(atol(arg));
break;
case 'g':
@@ -326,8 +330,9 @@
collect_argp(cmd, argc, argv, children, &opts);
opts.sampling = TRUE;
- /* Once a perf event is submitted, it'll start counting and firing the IRQ.
- * However, we can control whether or not the samples are collected. */
+ /* Once a perf event is submitted, it'll start counting and firing the
+ * IRQ. However, we can control whether or not the samples are
+ * collected. */
submit_events(&opts);
perf_start_sampling(pctx);
run_process_and_wait(opts.cmd_argc, opts.cmd_argv,
@@ -335,8 +340,8 @@
perf_stop_sampling(pctx);
if (opts.verbose)
perf_context_show_events(pctx, stdout);
- /* The events are still counting and firing IRQs. Let's be nice and turn
- * them off to minimize our impact. */
+ /* The events are still counting and firing IRQs. Let's be nice and
+ * turn them off to minimize our impact. */
perf_stop_events(pctx);
/* Generate the Linux perf file format with the traces which have been
* created during this operation. */
@@ -367,7 +372,7 @@
case ARGP_KEY_END:
if (!p_opts->events)
p_opts->events = "cache-misses,cache-references,"
- "branch-misses,branches,instructions,cycles";
+ "branch-misses,branches,instructions,cycles";
if (!p_opts->outfile)
p_opts->outfile = stdout;
break;
@@ -378,8 +383,8 @@
}
struct stat_val {
- char *name;
- uint64_t count;
+ char *name;
+ uint64_t count;
};
/* Helper, given a name, fetches its value as a float. */
@@ -398,8 +403,8 @@
{
float sec = get_count_for("nsec", all_vals, nr_vals) / 1000000000;
- /* We should never have a time of 0, but in case something went wrong, don't
- * hand back 0 (divide by 0 errors). */
+ /* We should never have a time of 0, but in case something went wrong,
+ * don't hand back 0 (divide by 0 errors). */
return sec != 0.0 ? sec : 1.0;
}
@@ -431,20 +436,23 @@
/* Everyone gets the same front part of the printout */
fprintf(out, "%18llu %-25s #", val->count, val->name);
- /* Based on the particular event and what other events we know, we may print
- * something different to the summary bit after the #. */
+ /* Based on the particular event and what other events we know, we may
+ * print something different to the summary bit after the #. */
if (!strcmp(val->name, "instructions")) {
float cycles = get_count_for("cycles", all_vals, nr_vals);
if (cycles != 0.0)
- fprintf(out, "%9.3f insns per cycle\n", val->count / cycles);
+ fprintf(out, "%9.3f insns per cycle\n",
+ val->count / cycles);
else
print_default_rate(out, val, all_vals, nr_vals);
} else if (!strcmp(val->name, "cache-misses")) {
- float cache_ref = get_count_for("cache-references", all_vals, nr_vals);
+ float cache_ref = get_count_for("cache-references", all_vals,
+ nr_vals);
if (cache_ref != 0.0)
- fprintf(out, "%8.2f%% of all refs\n", val->count * 100 / cache_ref);
+ fprintf(out, "%8.2f%% of all refs\n",
+ val->count * 100 / cache_ref);
else
print_default_rate(out, val, all_vals, nr_vals);
} else if (!strcmp(val->name, "branch-misses")) {
@@ -506,10 +514,10 @@
opts.sampling = FALSE;
out = opts.outfile;
- /* As soon as we submit one event, that event is being tracked, meaning that
- * the setup/teardown of perf events is also tracked. Each event (including
- * the clock measurement) will roughly account for either the start or stop
- * of every other event. */
+ /* As soon as we submit one event, that event is being tracked, meaning
+ * that the setup/teardown of perf events is also tracked. Each event
+ * (including the clock measurement) will roughly account for either the
+ * start or stop of every other event. */
clock_gettime(CLOCK_REALTIME, &start);
submit_events(&opts);
run_process_and_wait(opts.cmd_argc, opts.cmd_argv,
@@ -522,7 +530,8 @@
fprintf(out, "\nPerformance counter stats for '%s':\n\n", cmd_string);
free(cmd_string);
for (int i = 0; i < pctx->event_count; i++)
- stat_print_val(out, &stat_vals[i], stat_vals, pctx->event_count + 1);
+ stat_print_val(out, &stat_vals[i], stat_vals,
+ pctx->event_count + 1);
fprintf(out, "\n%8llu.%09llu seconds time elapsed\n\n", diff.tv_sec,
diff.tv_nsec);
fclose(out);
@@ -531,7 +540,7 @@
}
static void run_process_and_wait(int argc, char *argv[],
- const struct core_set *cores)
+ const struct core_set *cores)
{
int pid, status;
@@ -578,7 +587,8 @@
fprintf(stderr, " Usage: perf COMMAND [ARGS]\n");
fprintf(stderr, "\n Available commands:\n\n");
for (int i = 0; i < COUNT_OF(perf_cmds); i++)
- fprintf(stderr, " \t%s: %s\n", perf_cmds[i].name, perf_cmds[i].desc);
+ fprintf(stderr, " \t%s: %s\n", perf_cmds[i].name,
+ perf_cmds[i].desc);
exit(-1);
}
@@ -588,7 +598,8 @@
save_cmdline(argc, argv);
- /* Common inits. Some functions don't need these, but it doesn't hurt. */
+ /* Common inits. Some functions don't need these, but it doesn't hurt.
+ */
perf_initialize();
pctx = perf_create_context(&perf_cfg);
cctx = perfconv_create_context(pctx);
@@ -597,7 +608,8 @@
global_usage();
for (i = 0; i < COUNT_OF(perf_cmds); i++) {
if (!strcmp(perf_cmds[i].name, argv[1])) {
- ret = perf_cmds[i].func(&perf_cmds[i], argc - 1, argv + 1);
+ ret = perf_cmds[i].func(&perf_cmds[i], argc - 1,
+ argv + 1);
break;
}
}
diff --git a/tools/dev-util/perf/perf_core.c b/tools/dev-util/perf/perf_core.c
index 4143c9c..2da37a5 100644
--- a/tools/dev-util/perf/perf_core.c
+++ b/tools/dev-util/perf/perf_core.c
@@ -29,9 +29,9 @@
#include "elf.h"
struct perf_generic_event {
- char *name;
- uint32_t type;
- uint32_t config;
+ char *name;
+ uint32_t type;
+ uint32_t config;
};
struct perf_generic_event generic_events[] = {
@@ -82,8 +82,8 @@
ZERO_DATA(ainfo);
ainfo.size = sizeof(ainfo);
pfm_for_each_event_attr(i, einfo) {
- pfm_err_t err = pfm_get_event_attr_info(einfo->idx, i, PFM_OS_NONE,
- &ainfo);
+ pfm_err_t err = pfm_get_event_attr_info(einfo->idx, i,
+ PFM_OS_NONE, &ainfo);
if (err != PFM_SUCCESS) {
fprintf(stderr, "Failed to get attribute info: %s\n",
@@ -170,7 +170,8 @@
strlcpy(sel->fq_str, ptr, MAX_FQSTR_SZ);
free(ptr);
if (encode.count == 0) {
- fprintf(stderr, "Found event %s, but it had no codes!\n", sel->fq_str);
+ fprintf(stderr, "Found event %s, but it had no codes!\n",
+ sel->fq_str);
return FALSE;
}
sel->ev.event = encode.codes[0];
@@ -248,13 +249,17 @@
break;
case 'c':
if (tok[1] != '=') {
- fprintf(stderr, "Bad cmask tok %s, ignoring\n", tok);
+ fprintf(stderr, "Bad cmask tok %s, ignoring\n",
+ tok);
break;
}
errno = 0;
- PMEV_SET_CMASK(sel->ev.event, strtoul(&tok[2], NULL, 0));
+ PMEV_SET_CMASK(sel->ev.event,
+ strtoul(&tok[2], NULL, 0));
if (errno)
- fprintf(stderr, "Bad cmask tok %s, trying anyway\n", tok);
+ fprintf(stderr,
+ "Bad cmask tok %s, trying anyway\n",
+ tok);
break;
}
}
@@ -276,9 +281,9 @@
colon = strchr(str, ':');
if (colon)
parse_modifiers(colon + 1, sel);
- /* Note that we do not call x86_handle_pseudo_encoding here. We'll submit
- * exactly what the user asked us for - which also means no fixed counters
- * for them (unless we want a :f: token or something). */
+ /* Note that we do not call x86_handle_pseudo_encoding here. We'll
+ * submit exactly what the user asked us for - which also means no fixed
+ * counters for them (unless we want a :f: token or something). */
sel->type = PERF_TYPE_RAW;
sel->config = (PMEV_GET_MASK(sel->ev.event) << 8) |
PMEV_GET_EVENT(sel->ev.event);
@@ -290,8 +295,8 @@
static bool generic_str_get_code(const char *str, struct perf_eventsel *sel)
{
char *colon = strchr(str, ':');
- /* if there was no :, we compare as far as we can. generic_events.name is a
- * string literal, so strcmp() is fine. */
+ /* if there was no :, we compare as far as we can. generic_events.name
+ * is a string literal, so strcmp() is fine. */
size_t len = colon ? colon - str : SIZE_MAX;
for (int i = 0; i < COUNT_OF(generic_events); i++) {
@@ -430,7 +435,7 @@
}
static int perf_open_event(int perf_fd, const struct core_set *cores,
- const struct perf_eventsel *sel)
+ const struct perf_eventsel *sel)
{
uint8_t cmdbuf[1 + 3 * sizeof(uint64_t) + sizeof(uint32_t) +
CORE_SET_SIZE];
@@ -448,7 +453,8 @@
for (i = CORE_SET_SIZE - 1; (i >= 0) && !cores->core_set[i]; i--)
;
if (i < 0) {
- fprintf(stderr, "Performance event CPU set must not be empty\n");
+ fprintf(stderr,
+ "Performance event CPU set must not be empty\n");
exit(1);
}
wptr = put_le_u32(wptr, i + 1);
@@ -481,14 +487,16 @@
rsize = pread(perf_fd, cmdbuf, bufsize, 0);
if (rsize < (sizeof(uint32_t))) {
- fprintf(stderr, "Invalid read size while fetching event status: %ld\n",
- rsize);
+ fprintf(stderr,
+ "Invalid read size while fetching event status: %ld\n",
+ rsize);
exit(1);
}
rptr = get_le_u32(rptr, &n);
if (((rptr - cmdbuf) + n * sizeof(uint64_t)) > rsize) {
- fprintf(stderr, "Invalid read size while fetching event status: %ld\n",
- rsize);
+ fprintf(stderr,
+ "Invalid read size while fetching event status: %ld\n",
+ rsize);
exit(1);
}
values = xmalloc(n * sizeof(uint64_t));
@@ -533,9 +541,9 @@
pctx->cfg = cfg;
pctx->perf_fd = xopen(cfg->perf_file, O_RDWR, 0);
- /* perf record needs kpctl_fd, but other perf subcommands might not. We'll
- * delay the opening of kpctl until we need it, since kprof is picky about
- * multiple users of kpctl. */
+ /* perf record needs kpctl_fd, but other perf subcommands might not.
+ * We'll delay the opening of kpctl until we need it, since kprof is
+ * picky about multiple users of kpctl. */
pctx->kpctl_fd = -1;
perf_get_arch_info(pctx->perf_fd, &pctx->pai);
@@ -551,22 +559,22 @@
}
void perf_context_event_submit(struct perf_context *pctx,
- const struct core_set *cores,
- const struct perf_eventsel *sel)
+ const struct core_set *cores,
+ const struct perf_eventsel *sel)
{
struct perf_event *pevt = pctx->events + pctx->event_count;
if (pctx->event_count >= COUNT_OF(pctx->events)) {
- fprintf(stderr, "Too many open events: %d\n", pctx->event_count);
- exit(1);
+ fprintf(stderr, "Too many open events: %d\n",
+ pctx->event_count); exit(1);
}
pctx->event_count++;
pevt->cores = *cores;
pevt->sel = *sel;
pevt->ped = perf_open_event(pctx->perf_fd, cores, sel);
if (pevt->ped < 0) {
- fprintf(stderr, "Unable to submit event \"%s\": %s\n", sel->fq_str,
- errstr());
+ fprintf(stderr, "Unable to submit event \"%s\": %s\n",
+ sel->fq_str, errstr());
exit(1);
}
}
@@ -642,7 +650,7 @@
/* Ported from libpfm4 */
static void perf_show_event_info(const pfm_event_info_t *info,
- const pfm_pmu_info_t *pinfo, FILE *file)
+ const pfm_pmu_info_t *pinfo, FILE *file)
{
static const char * const srcs[PFM_ATTR_CTRL_MAX] = {
[PFM_ATTR_CTRL_UNKNOWN] = "???",
@@ -673,8 +681,8 @@
pfm_for_each_event_attr(i, info) {
const char *src;
- pfm_err_t err = pfm_get_event_attr_info(info->idx, i, PFM_OS_NONE,
- &ainfo);
+ pfm_err_t err = pfm_get_event_attr_info(info->idx, i,
+ PFM_OS_NONE, &ainfo);
if (err != PFM_SUCCESS) {
fprintf(stderr, "Failed to get attribute info: %s\n",
@@ -683,39 +691,45 @@
}
if (ainfo.ctrl >= PFM_ATTR_CTRL_MAX) {
- fprintf(stderr, "event: %s has unsupported attribute source %d",
- info->name, ainfo.ctrl);
+ fprintf(stderr,
+ "event: %s has unsupported attribute source %d",
+ info->name, ainfo.ctrl);
ainfo.ctrl = PFM_ATTR_CTRL_UNKNOWN;
}
src = srcs[ainfo.ctrl];
switch (ainfo.type) {
- case PFM_ATTR_UMASK:
- fprintf(file, "Umask-%02u : 0x%02"PRIx64" : %s : [%s] : ",
- um, ainfo.code, src, ainfo.name);
- perf_print_attr_flags(&ainfo, file);
- fputc(':', file);
- if (ainfo.equiv)
- fprintf(file, " Alias to %s", ainfo.equiv);
- else
- fprintf(file, " %s", ainfo.desc);
- fputc('\n', file);
- um++;
- break;
- case PFM_ATTR_MOD_BOOL:
- fprintf(file, "Modif-%02u : 0x%02"PRIx64" : %s : [%s] : "
- "%s (boolean)\n", mod, ainfo.code, src, ainfo.name,
- ainfo.desc);
- mod++;
- break;
- case PFM_ATTR_MOD_INTEGER:
- fprintf(file, "Modif-%02u : 0x%02"PRIx64" : %s : [%s] : "
- "%s (integer)\n", mod, ainfo.code, src, ainfo.name,
- ainfo.desc);
- mod++;
- break;
- default:
- fprintf(file, "Attr-%02u : 0x%02"PRIx64" : %s : [%s] : %s\n",
- i, ainfo.code, ainfo.name, src, ainfo.desc);
+ case PFM_ATTR_UMASK:
+ fprintf(file,
+ "Umask-%02u : 0x%02"PRIx64" : %s : [%s] : ",
+ um, ainfo.code, src, ainfo.name);
+ perf_print_attr_flags(&ainfo, file);
+ fputc(':', file);
+ if (ainfo.equiv)
+ fprintf(file, " Alias to %s",
+ ainfo.equiv);
+ else
+ fprintf(file, " %s", ainfo.desc);
+ fputc('\n', file);
+ um++;
+ break;
+ case PFM_ATTR_MOD_BOOL:
+ fprintf(file,
+ "Modif-%02u : 0x%02"PRIx64" : %s : [%s] : "
+ "%s (boolean)\n", mod, ainfo.code, src,
+ ainfo.name, ainfo.desc);
+ mod++;
+ break;
+ case PFM_ATTR_MOD_INTEGER:
+ fprintf(file,
+ "Modif-%02u : 0x%02"PRIx64" : %s : [%s] : "
+ "%s (integer)\n", mod, ainfo.code, src,
+ ainfo.name, ainfo.desc);
+ mod++;
+ break;
+ default:
+ fprintf(file,
+ "Attr-%02u : 0x%02"PRIx64" : %s : [%s] : %s\n",
+ i, ainfo.code, ainfo.name, src, ainfo.desc);
}
}
}
@@ -733,10 +747,10 @@
exit(1);
}
- ZERO_DATA(pinfo);
- pinfo.size = sizeof(pinfo);
- ZERO_DATA(info);
- info.size = sizeof(info);
+ ZERO_DATA(pinfo);
+ pinfo.size = sizeof(pinfo);
+ ZERO_DATA(info);
+ info.size = sizeof(info);
pfm_for_all_pmus(pmu) {
pfm_err_t err = pfm_get_pmu_info(pmu, &pinfo);
@@ -744,15 +758,17 @@
if (err != PFM_SUCCESS || !pinfo.is_present)
continue;
- for (int i = pinfo.first_event; i != -1; i = pfm_get_event_next(i)) {
+ for (int i = pinfo.first_event; i != -1;
+ i = pfm_get_event_next(i)) {
err = pfm_get_event_info(i, PFM_OS_NONE, &info);
if (err != PFM_SUCCESS) {
- fprintf(stderr, "Failed to get event info: %s\n",
- pfm_strerror(err));
+ fprintf(stderr,
+ "Failed to get event info: %s\n",
+ pfm_strerror(err));
exit(1);
}
- snprintf(fullname, sizeof(fullname), "%s::%s", pinfo.name,
- info.name);
+ snprintf(fullname, sizeof(fullname), "%s::%s",
+ pinfo.name, info.name);
if (!rx || regexec(&crx, fullname, 0, NULL, 0) == 0)
perf_show_event_info(&info, &pinfo, file);
}
diff --git a/tools/dev-util/perf/perf_core.h b/tools/dev-util/perf/perf_core.h
index 42e7419..4c61408 100644
--- a/tools/dev-util/perf/perf_core.h
+++ b/tools/dev-util/perf/perf_core.h
@@ -62,8 +62,8 @@
struct perf_context *perf_create_context(struct perf_context_config *cfg);
void perf_free_context(struct perf_context *pctx);
void perf_context_event_submit(struct perf_context *pctx,
- const struct core_set *cores,
- const struct perf_eventsel *sel);
+ const struct core_set *cores,
+ const struct perf_eventsel *sel);
void perf_stop_events(struct perf_context *pctx);
void perf_start_sampling(struct perf_context *pctx);
void perf_stop_sampling(struct perf_context *pctx);
@@ -71,7 +71,7 @@
void perf_context_show_events(struct perf_context *pctx, FILE *file);
void perf_show_events(const char *rx, FILE *file);
void perf_convert_trace_data(struct perfconv_context *cctx, const char *input,
- FILE *outfile);
+ FILE *outfile);
static inline const struct perf_arch_info *perf_context_get_arch_info(
const struct perf_context *pctx)
diff --git a/tools/dev-util/perf/perf_format.h b/tools/dev-util/perf/perf_format.h
index f355aa1..68e0f32 100644
--- a/tools/dev-util/perf/perf_format.h
+++ b/tools/dev-util/perf/perf_format.h
@@ -188,20 +188,20 @@
* # is fixed relative to header.
* #
*
- * { u64 id; } && PERF_SAMPLE_IDENTIFIER
- * { u64 ip; } && PERF_SAMPLE_IP
- * { u32 pid, tid; } && PERF_SAMPLE_TID
- * { u64 time; } && PERF_SAMPLE_TIME
- * { u64 addr; } && PERF_SAMPLE_ADDR
- * { u64 id; } && PERF_SAMPLE_ID
- * { u64 stream_id;} && PERF_SAMPLE_STREAM_ID
- * { u32 cpu, res; } && PERF_SAMPLE_CPU
- * { u64 period; } && PERF_SAMPLE_PERIOD
+ * { u64 id; } && PERF_SAMPLE_IDENTIFIER
+ * { u64 ip; } && PERF_SAMPLE_IP
+ * { u32 pid, tid; } && PERF_SAMPLE_TID
+ * { u64 time; } && PERF_SAMPLE_TIME
+ * { u64 addr; } && PERF_SAMPLE_ADDR
+ * { u64 id; } && PERF_SAMPLE_ID
+ * { u64 stream_id;} && PERF_SAMPLE_STREAM_ID
+ * { u32 cpu, res; } && PERF_SAMPLE_CPU
+ * { u64 period; } && PERF_SAMPLE_PERIOD
*
* { struct read_format values; } && PERF_SAMPLE_READ
*
- * { u64 nr,
- * u64 ips[nr]; } && PERF_SAMPLE_CALLCHAIN
+ * { u64 nr,
+ * u64 ips[nr]; } && PERF_SAMPLE_CALLCHAIN
*
* #
* # The RAW record below is opaque data wrt the ABI
@@ -214,24 +214,24 @@
* # In other words, PERF_SAMPLE_RAW contents are not an ABI.
* #
*
- * { u32 size;
- * char data[size];}&& PERF_SAMPLE_RAW
+ * { u32 size;
+ * char data[size];}&& PERF_SAMPLE_RAW
*
- * { u64 nr;
- * { u64 from, to, flags } lbr[nr];} && PERF_SAMPLE_BRANCH_STACK
+ * { u64 nr;
+ * { u64 from, to, flags } lbr[nr];} && PERF_SAMPLE_BRANCH_STACK
*
- * { u64 abi; # enum perf_sample_regs_abi
- * u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_USER
+ * { u64 abi; # enum perf_sample_regs_abi
+ * u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_USER
*
- * { u64 size;
- * char data[size];
- * u64 dyn_size; } && PERF_SAMPLE_STACK_USER
+ * { u64 size;
+ * char data[size];
+ * u64 dyn_size; } && PERF_SAMPLE_STACK_USER
*
- * { u64 weight; } && PERF_SAMPLE_WEIGHT
- * { u64 data_src; } && PERF_SAMPLE_DATA_SRC
- * { u64 transaction; } && PERF_SAMPLE_TRANSACTION
- * { u64 abi; # enum perf_sample_regs_abi
- * u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_INTR
+ * { u64 weight; } && PERF_SAMPLE_WEIGHT
+ * { u64 data_src; } && PERF_SAMPLE_DATA_SRC
+ * { u64 transaction; } && PERF_SAMPLE_TRANSACTION
+ * { u64 abi; # enum perf_sample_regs_abi
+ * u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_INTR
* };
*/
PERF_RECORD_SAMPLE = 9,
@@ -263,30 +263,30 @@
#define PERF_MAX_STACK_DEPTH 127
enum perf_callchain_context {
- PERF_CONTEXT_HV = (__uint64_t) -32,
- PERF_CONTEXT_KERNEL = (__uint64_t) -128,
- PERF_CONTEXT_USER = (__uint64_t) -512,
+ PERF_CONTEXT_HV = (__uint64_t) -32,
+ PERF_CONTEXT_KERNEL = (__uint64_t) -128,
+ PERF_CONTEXT_USER = (__uint64_t) -512,
- PERF_CONTEXT_GUEST = (__uint64_t) -2048,
+ PERF_CONTEXT_GUEST = (__uint64_t) -2048,
PERF_CONTEXT_GUEST_KERNEL = (__uint64_t) -2176,
PERF_CONTEXT_GUEST_USER = (__uint64_t) -2560,
- PERF_CONTEXT_MAX = (__uint64_t) -4095,
+ PERF_CONTEXT_MAX = (__uint64_t) -4095,
};
/*
* attr.type
*/
enum perf_type_id {
- PERF_TYPE_HARDWARE = 0,
- PERF_TYPE_SOFTWARE = 1,
- PERF_TYPE_TRACEPOINT = 2,
- PERF_TYPE_HW_CACHE = 3,
- PERF_TYPE_RAW = 4,
- PERF_TYPE_BREAKPOINT = 5,
- PERF_TYPE_INTEL_CQM = 6,
+ PERF_TYPE_HARDWARE = 0,
+ PERF_TYPE_SOFTWARE = 1,
+ PERF_TYPE_TRACEPOINT = 2,
+ PERF_TYPE_HW_CACHE = 3,
+ PERF_TYPE_RAW = 4,
+ PERF_TYPE_BREAKPOINT = 5,
+ PERF_TYPE_INTEL_CQM = 6,
- PERF_TYPE_MAX, /* non-ABI */
+ PERF_TYPE_MAX, /* non-ABI */
};
/*
@@ -298,18 +298,18 @@
/*
* Common hardware events, generalized by the kernel:
*/
- PERF_COUNT_HW_CPU_CYCLES = 0,
- PERF_COUNT_HW_INSTRUCTIONS = 1,
- PERF_COUNT_HW_CACHE_REFERENCES = 2,
- PERF_COUNT_HW_CACHE_MISSES = 3,
- PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4,
- PERF_COUNT_HW_BRANCH_MISSES = 5,
- PERF_COUNT_HW_BUS_CYCLES = 6,
+ PERF_COUNT_HW_CPU_CYCLES = 0,
+ PERF_COUNT_HW_INSTRUCTIONS = 1,
+ PERF_COUNT_HW_CACHE_REFERENCES = 2,
+ PERF_COUNT_HW_CACHE_MISSES = 3,
+ PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4,
+ PERF_COUNT_HW_BRANCH_MISSES = 5,
+ PERF_COUNT_HW_BUS_CYCLES = 6,
PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 7,
PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 8,
- PERF_COUNT_HW_REF_CPU_CYCLES = 9,
+ PERF_COUNT_HW_REF_CPU_CYCLES = 9,
- PERF_COUNT_HW_MAX, /* non-ABI */
+ PERF_COUNT_HW_MAX, /* non-ABI */
};
/* We can output a bunch of different versions of perf_event_attr. The oldest
@@ -398,7 +398,7 @@
exclude_callchain_kernel : 1, /* exclude kernel callchains */
exclude_callchain_user : 1, /* exclude user callchains */
- mmap2 : 1, /* include mmap with inode data */
+ mmap2 : 1, /* include mmap with inode data */
__reserved_1 : 40;
@@ -484,7 +484,7 @@
uint64_t size; /* Size of the section */
} __attribute__((packed));
-#define PERF_STRING_ALIGN 64
+#define PERF_STRING_ALIGN 64
struct perf_header_string {
uint32_t len;
@@ -497,15 +497,15 @@
};
struct nr_cpus {
- uint32_t nr_cpus_online;
- uint32_t nr_cpus_available;
+ uint32_t nr_cpus_online;
+ uint32_t nr_cpus_available;
};
struct build_id_event {
- struct perf_event_header header;
- pid_t pid;
- uint8_t build_id[24]; /* BUILD_ID_SIZE aligned u64 */
- char filename[];
+ struct perf_event_header header;
+ pid_t pid;
+ uint8_t build_id[24]; /* BUILD_ID_SIZE aligned u64 */
+ char filename[];
};
#define MAX_EVENT_NAME 64
@@ -525,14 +525,14 @@
static const uint64_t PERF_MAGIC2 = 0x32454c4946524550ULL;
struct perf_pipe_file_header {
- uint64_t magic; /* PERFILE2 */
+ uint64_t magic; /* PERFILE2 */
uint64_t size;
};
struct perf_header {
- uint64_t magic; /* PERFILE2 */
- uint64_t size; /* Size of the header */
- uint64_t attr_size; /* size of an attribute in attrs */
+ uint64_t magic; /* PERFILE2 */
+ uint64_t size; /* Size of the header */
+ uint64_t attr_size; /* size of an attribute in attrs */
struct perf_file_section attrs;
struct perf_file_section data;
struct perf_file_section event_types;
diff --git a/tools/dev-util/perf/perfconv.c b/tools/dev-util/perf/perfconv.c
index abc6379..b93ac14 100644
--- a/tools/dev-util/perf/perfconv.c
+++ b/tools/dev-util/perf/perfconv.c
@@ -7,9 +7,9 @@
* Converts kprof profiler files into Linux perf ones. The Linux Perf file
* format has bee illustrated here:
*
- * https://lwn.net/Articles/644919/
- * https://openlab-mu-internal.web.cern.ch/openlab-mu-internal/03_Documents/
- * 3_Technical_Documents/Technical_Reports/2011/Urs_Fassler_report.pdf
+ * https://lwn.net/Articles/644919/
+ * https://openlab-mu-internal.web.cern.ch/openlab-mu-internal/03_Documents/
+ * 3_Technical_Documents/Technical_Reports/2011/Urs_Fassler_report.pdf
*
*/
@@ -78,8 +78,8 @@
vb_fdecode_uint64(file, &pr->size) == EOF)
return EOF;
if (pr->size > MAX_PERF_RECORD_SIZE) {
- fprintf(stderr, "Invalid record size: type=%lu size=%lu\n", pr->type,
- pr->size);
+ fprintf(stderr, "Invalid record size: type=%lu size=%lu\n",
+ pr->type, pr->size);
exit(1);
}
if (pr->size > sizeof(pr->buffer))
@@ -199,11 +199,14 @@
mm->pid = -1; /* Linux HOST_KERNEL_ID == -1 */
mm->tid = 0; /* Default thread: swapper */
mm->header_misc = PERF_RECORD_MISC_KERNEL;
- /* Linux sets addr = 0, size = 0xffffffff9fffffff, off = 0xffffffff81000000
- * Their mmap record is also called [kernel.kallsyms]_text (I think). They
- * also have a _text symbol in kallsyms at ffffffff81000000 (equiv to our
- * KERN_LOAD_ADDR (which is 0xffffffffc0000000)). Either way, this seems to
- * work for us; we'll see. It's also arch-independent (for now). */
+ /* Linux sets addr = 0, size = 0xffffffff9fffffff, off =
+ * 0xffffffff81000000
+ *
+ * Their mmap record is also called [kernel.kallsyms]_text (I think).
+ * They also have a _text symbol in kallsyms at ffffffff81000000 (equiv
+ * to our KERN_LOAD_ADDR (which is 0xffffffffc0000000)). Either way,
+ * this seems to work for us; we'll see. It's also arch-independent
+ * (for now). */
mm->addr = 0;
mm->size = 0xffffffffffffffff;
mm->offset = 0x0;
@@ -241,8 +244,9 @@
struct mem_block *mb;
size_t mb_sz;
- /* For each header, we need a perf_file_section. These header file sections
- * are right after the main perf header, and they point to actual header. */
+ /* For each header, we need a perf_file_section. These header file
+ * sections are right after the main perf header, and they point to
+ * actual header. */
for (int i = 0; i < HEADER_FEAT_BITS; i++)
if (hdrs->headers[i])
nr_hdrs++;
@@ -253,8 +257,8 @@
hdr_off = sizeof(struct perf_file_section) * nr_hdrs;
file_sec = header_file_secs;
- /* Spit out the perf_file_sections first and track relocations for all of
- * the offsets. */
+ /* Spit out the perf_file_sections first and track relocations for all
+ * of the offsets. */
for (int i = 0; i < HEADER_FEAT_BITS; i++) {
mb = hdrs->headers[i];
if (!mb)
@@ -266,13 +270,14 @@
mb_sz += mb->wptr - mb->base;
}
file_sec->size = mb_sz;
- file_sec->offset = hdr_off; /* offset rel to this memfile */
- /* When we sync the memfile, we'll need to relocate each of the offsets
- * so that they are relative to the final file. mem_file_write()
- * should be returning the location of where it wrote our file section
- * within the memfile. that's the offset that we'll reloc later. */
+ file_sec->offset = hdr_off; /* offset rel to this memfile */
+ /* When we sync the memfile, we'll need to relocate each of the
+ * offsets so that they are relative to the final file.
+ * mem_file_write() should be returning the location of where it
+ * wrote our file section within the memfile. that's the offset
+ * that we'll reloc later. */
file_sec_reloc = mem_file_write(mf, file_sec,
- sizeof(struct perf_file_section), 0);
+ sizeof(struct perf_file_section), 0);
assert(file_sec->size == file_sec_reloc->size);
assert(file_sec->offset == file_sec_reloc->offset);
mem_file_add_reloc(mf, &file_sec_reloc->offset);
@@ -302,9 +307,9 @@
PERF_STRING_ALIGN);
mb = mem_block_alloc(hdr_sz);
- /* Manually writing to the block to avoid another alloc. I guess I could do
- * two writes (len and string) and try to not screw it up, but that'd be a
- * mess. */
+ /* Manually writing to the block to avoid another alloc. I guess I
+ * could do two writes (len and string) and try to not screw it up, but
+ * that'd be a mess. */
hdr = (struct perf_header_string*)mb->wptr;
mb->wptr += hdr_sz;
hdr->len = str_sz;
@@ -415,7 +420,7 @@
b_evt = (struct build_id_event*)mb->base;
b_evt_path_sz = b_evt->header.size -
offsetof(struct build_id_event, filename);
- /* ignoring the last byte since we forced it to be \0 earlier. */
+ /* ignoring the last byte since we forced it to be \0 earlier.*/
if (!strncmp(b_evt->filename, path, b_evt_path_sz - 1))
return TRUE;
mb = mb->next;
@@ -556,7 +561,7 @@
* If this is the first time we've seen 'raw_info', we'll also add an attribute
* to the perf ctx. There is one attr per 'id' / event stream. */
static uint64_t perfconv_get_event_id(struct perfconv_context *cctx,
- uint64_t raw_info)
+ uint64_t raw_info)
{
struct perf_eventsel *sel = (struct perf_eventsel*)raw_info;
struct perf_event_attr attr;
@@ -591,7 +596,8 @@
struct static_mmap64 *mm;
for (mm = cctx->static_mmaps; mm; mm = mm->next) {
- size_t size = sizeof(struct perf_record_mmap) + strlen(mm->path) + 1;
+ size_t size = sizeof(struct perf_record_mmap)
+ + strlen(mm->path) + 1;
struct perf_record_mmap *xrec = xzmalloc(size);
xrec->header.type = PERF_RECORD_MMAP;
@@ -628,9 +634,10 @@
}
static void emit_pid_mmap64(struct perf_record *pr,
- struct perfconv_context *cctx)
+ struct perfconv_context *cctx)
{
- struct proftype_pid_mmap64 *rec = (struct proftype_pid_mmap64 *) pr->data;
+ struct proftype_pid_mmap64 *rec =
+ (struct proftype_pid_mmap64 *) pr->data;
size_t size = sizeof(struct perf_record_mmap) +
strlen((char*)rec->path) + 1;
struct perf_record_mmap *xrec = xzmalloc(size);
@@ -652,7 +659,7 @@
}
static void emit_kernel_trace64(struct perf_record *pr,
- struct perfconv_context *cctx)
+ struct perfconv_context *cctx)
{
struct proftype_kern_trace64 *rec = (struct proftype_kern_trace64 *)
pr->data;
@@ -665,8 +672,8 @@
xrec->header.size = size;
xrec->ip = rec->trace[0];
/* TODO: -1 means "not a process". We could track ktasks with IDs, emit
- * COMM events for them (probably!) and report them as the tid. For now,
- * tid of 0 means [swapper] to Linux. */
+ * COMM events for them (probably!) and report them as the tid. For
+ * now, tid of 0 means [swapper] to Linux. */
if (rec->pid == -1) {
xrec->pid = -1;
xrec->tid = 0;
@@ -679,7 +686,8 @@
xrec->identifier = perfconv_get_event_id(cctx, rec->info);
xrec->cpu = rec->cpu;
xrec->nr = rec->num_traces - 1;
- memcpy(xrec->ips, rec->trace + 1, (rec->num_traces - 1) * sizeof(uint64_t));
+ memcpy(xrec->ips, rec->trace + 1,
+ (rec->num_traces - 1) * sizeof(uint64_t));
mem_file_write(&cctx->data, xrec, size, 0);
@@ -687,7 +695,7 @@
}
static void emit_user_trace64(struct perf_record *pr,
- struct perfconv_context *cctx)
+ struct perfconv_context *cctx)
{
struct proftype_user_trace64 *rec = (struct proftype_user_trace64 *)
pr->data;
@@ -705,7 +713,8 @@
xrec->identifier = perfconv_get_event_id(cctx, rec->info);
xrec->cpu = rec->cpu;
xrec->nr = rec->num_traces - 1;
- memcpy(xrec->ips, rec->trace + 1, (rec->num_traces - 1) * sizeof(uint64_t));
+ memcpy(xrec->ips, rec->trace + 1,
+ (rec->num_traces - 1) * sizeof(uint64_t));
mem_file_write(&cctx->data, xrec, size, 0);
@@ -713,9 +722,10 @@
}
static void emit_new_process(struct perf_record *pr,
- struct perfconv_context *cctx)
+ struct perfconv_context *cctx)
{
- struct proftype_new_process *rec = (struct proftype_new_process *) pr->data;
+ struct proftype_new_process *rec =
+ (struct proftype_new_process *) pr->data;
const char *comm;
hdr_add_buildid(cctx, (char*)rec->path, rec->pid);
@@ -730,7 +740,8 @@
struct perfconv_context *perfconv_create_context(struct perf_context *pctx)
{
- struct perfconv_context *cctx = xzmalloc(sizeof(struct perfconv_context));
+ struct perfconv_context *cctx =
+ xzmalloc(sizeof(struct perfconv_context));
cctx->pctx = pctx;
perf_header_init(&cctx->ph);
@@ -752,7 +763,7 @@
}
void perfconv_process_input(struct perfconv_context *cctx, FILE *input,
- FILE *output)
+ FILE *output)
{
size_t processed_records = 0;
uint64_t offset;
@@ -781,8 +792,8 @@
emit_new_process(&pr, cctx);
break;
default:
- fprintf(stderr, "Unknown record: type=%lu size=%lu\n", pr.type,
- pr.size);
+ fprintf(stderr, "Unknown record: type=%lu size=%lu\n",
+ pr.type, pr.size);
processed_records--;
}
@@ -795,8 +806,8 @@
/* attrs, events, and data will come after attr_ids. */
offset = sizeof(cctx->ph) + cctx->attr_ids.size;
- /* These are the perf_file_sections in the main perf header. We need this
- * sorted out before we emit the PH. */
+ /* These are the perf_file_sections in the main perf header. We need
+ * this sorted out before we emit the PH. */
cctx->ph.event_types.offset = offset;
cctx->ph.event_types.size = cctx->event_types.size;
offset += cctx->event_types.size;
@@ -812,8 +823,8 @@
xfwrite(&cctx->ph, sizeof(cctx->ph), output);
/* attr_ids comes right after the cctx->ph. We need to put it before
- * attrs, since attrs needs to know the offset of the base of attrs_ids for
- * its relocs. */
+ * attrs, since attrs needs to know the offset of the base of attrs_ids
+ * for its relocs. */
assert(ftell(output) == attr_ids_off);
mem_file_sync(&cctx->attr_ids, output, OFFSET_NORELOC);
mem_file_sync(&cctx->event_types, output, OFFSET_NORELOC);
@@ -821,10 +832,11 @@
mem_file_sync(&cctx->attrs, output, attr_ids_off);
/* Keep data last, so we can append the feature headers.*/
mem_file_sync(&cctx->data, output, OFFSET_NORELOC);
- /* The feature headers must be right after the data section. I didn't see
- * anything in the ABI about this, but Linux's perf has this line:
+ /* The feature headers must be right after the data section. I didn't
+ * see anything in the ABI about this, but Linux's perf has this line:
*
- * ph->feat_offset = header->data.offset + header->data.size;
+ * ph->feat_offset = header->data.offset +
+ * header->data.size;
*/
mem_file_sync(&cctx->fhdrs, output,
cctx->ph.data.offset + cctx->ph.data.size);
diff --git a/tools/dev-util/perf/perfconv.h b/tools/dev-util/perf/perfconv.h
index 107ce92..a6c4a11 100644
--- a/tools/dev-util/perf/perfconv.h
+++ b/tools/dev-util/perf/perfconv.h
@@ -5,9 +5,9 @@
* Converts kprof profiler files into Linux perf ones. The Linux Perf file
* format has bee illustrated here:
*
- * https://lwn.net/Articles/644919/
- * https://openlab-mu-internal.web.cern.ch/openlab-mu-internal/03_Documents/
- * 3_Technical_Documents/Technical_Reports/2011/Urs_Fassler_report.pdf
+ * https://lwn.net/Articles/644919/
+ * https://openlab-mu-internal.web.cern.ch/openlab-mu-internal/03_Documents/
+ * 3_Technical_Documents/Technical_Reports/2011/Urs_Fassler_report.pdf
*
*/
@@ -75,4 +75,4 @@
void perfconv_add_kernel_mmap(struct perfconv_context *cctx);
void perfconv_add_kernel_buildid(struct perfconv_context *cctx);
void perfconv_process_input(struct perfconv_context *cctx, FILE *input,
- FILE *output);
+ FILE *output);
diff --git a/tools/dev-util/perf/xlib.c b/tools/dev-util/perf/xlib.c
index 1eb83f5..6d46e6b 100644
--- a/tools/dev-util/perf/xlib.c
+++ b/tools/dev-util/perf/xlib.c
@@ -84,8 +84,9 @@
FILE *file = fdopen(fd, mode);
if (!file) {
- fprintf(stderr, "Unable to reopen fd '%d' for mode '%s': %s\n", fd,
- mode, strerror(errno));
+ fprintf(stderr,
+ "Unable to reopen fd '%d' for mode '%s': %s\n", fd,
+ mode, strerror(errno));
exit(1);
}
@@ -122,10 +123,12 @@
if (fseeko(file, offset, whence)) {
int error = errno;
- fprintf(stderr, "Unable to seek at offset %ld from %s (fpos=%ld): %s\n",
- offset, whence == SEEK_SET ? "beginning of file" :
- (whence == SEEK_END ? "end of file" : "current position"),
- ftell(file), strerror(error));
+ fprintf(stderr,
+ "Unable to seek at offset %ld from %s (fpos=%ld): %s\n",
+ offset, whence == SEEK_SET ? "beginning of file" :
+ (whence == SEEK_END ? "end of file" :
+ "current position"),
+ ftell(file), strerror(error));
exit(1);
}
}
diff --git a/tools/dev-util/perf/xlib.h b/tools/dev-util/perf/xlib.h
index 6793f26..8d593e1 100644
--- a/tools/dev-util/perf/xlib.h
+++ b/tools/dev-util/perf/xlib.h
@@ -15,20 +15,20 @@
#include <unistd.h>
#include <fcntl.h>
-#define min(a, b) \
+#define min(a, b) \
({ __typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a < _b ? _a : _b; })
-#define max(a, b) \
+#define max(a, b) \
({ __typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a > _b ? _a : _b; })
-#define always_assert(c) \
- do { \
- if (!(c)) \
- fprintf(stderr, "%s: %d: Assertion failed: " #c "\n", \
- __FILE__, __LINE__); \
- } while (0)
+#define always_assert(c) \
+do { \
+ if (!(c)) \
+ fprintf(stderr, "%s: %d: Assertion failed: " #c "\n", \
+ __FILE__, __LINE__); \
+} while (0)
int xopen(const char *path, int flags, mode_t mode);
void xwrite(int fd, const void *data, size_t size);
@@ -52,9 +52,8 @@
{
uint32_t eax, ebx, ecx, edx;
- asm volatile("cpuid"
- : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
- : "a" (ieax), "c" (iecx));
+ asm volatile("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
+ : "a" (ieax), "c" (iecx));
if (eaxp)
*eaxp = eax;
if (ebxp)
diff --git a/user/benchutil/include/benchutil/measure.h b/user/benchutil/include/benchutil/measure.h
index 9132a8f..dcd8a10 100644
--- a/user/benchutil/include/benchutil/measure.h
+++ b/user/benchutil/include/benchutil/measure.h
@@ -22,15 +22,15 @@
struct sample_stats {
int (*get_sample)(void **data, int i, int j, uint64_t *sample);
- uint64_t avg_time;
- uint64_t var_time;
- uint64_t max_time;
- uint64_t min_time;
- unsigned int lat_50;
- unsigned int lat_75;
- unsigned int lat_90;
- unsigned int lat_99;
- uint64_t total_samples;
+ uint64_t avg_time;
+ uint64_t var_time;
+ uint64_t max_time;
+ uint64_t min_time;
+ unsigned int lat_50;
+ unsigned int lat_75;
+ unsigned int lat_90;
+ unsigned int lat_99;
+ uint64_t total_samples;
};
/* Computes basic stats and prints histograms, stats returned via *stats */
diff --git a/user/benchutil/measure.c b/user/benchutil/measure.c
index 707f0db..85a5cda 100644
--- a/user/benchutil/measure.c
+++ b/user/benchutil/measure.c
@@ -48,9 +48,9 @@
float accum_samples = 0.0, coef_var;
unsigned int *hist_times;
unsigned int *lat_times;
- unsigned int nr_hist_bins = 75; /* looks reasonable when printed */
- unsigned int nr_lat_bins = 500; /* affects granularity of lat perc */
- unsigned int max_dots_per_row = 45; /* looks good with 80-wide col */
+ unsigned int nr_hist_bins = 75; /* looks reasonable when printed */
+ unsigned int nr_lat_bins = 500; /* affects granularity of lat perc */
+ unsigned int max_dots_per_row = 45; /* looks good with 80-wide col */
unsigned int max_hist_bin = 0;
#define HI_COEF_VAR 1.0
@@ -58,15 +58,17 @@
/* First pass, figure out the min, max, avg, etc. */
for (int i = 0; i < nr_i; i++) {
for (int j = 0; j < nr_j; j++) {
- /* get_sample returns 0 on success. o/w, skip the sample */
+ /* get_sample returns 0 on success. o/w, skip the
+ * sample */
+ /* depending on semantics, we could break */
if (stats->get_sample(data, i, j, &sample_time))
- continue; /* depending on semantics, we could break */
+ continue;
stats->total_samples++;
stats->avg_time += sample_time;
- stats->max_time = sample_time > stats->max_time ? sample_time
- : stats->max_time;
- stats->min_time = sample_time < stats->min_time ? sample_time
- : stats->min_time;
+ stats->max_time = sample_time > stats->max_time ?
+ sample_time : stats->max_time;
+ stats->min_time = sample_time < stats->min_time ?
+ sample_time : stats->min_time;
}
}
if (stats->total_samples < 2) {
@@ -87,27 +89,29 @@
}
}
stats->var_time /= stats->total_samples - 1;
- /* We have two histogram structures. The main one is for printing, and the
- * other is for computing latency percentiles. The only real diff btw the
- * two is the number of bins. The latency one has a lot more, for finer
- * granularity, and the regular one has fewer for better printing.
+ /* We have two histogram structures. The main one is for printing, and
+ * the other is for computing latency percentiles. The only real diff
+ * btw the two is the number of bins. The latency one has a lot more,
+ * for finer granularity, and the regular one has fewer for better
+ * printing.
*
- * Both have the same max and min bin values. Any excesses get put in the
- * smallest or biggest bin. This keeps the granularity reasonable in the
- * face of very large outliers. Normally, I trim off anything outside 3
- * stddev.
+ * Both have the same max and min bin values. Any excesses get put in
+ * the smallest or biggest bin. This keeps the granularity reasonable
+ * in the face of very large outliers. Normally, I trim off anything
+ * outside 3 stddev.
*
* High variation will throw off our histogram bins, so we adjust. A
- * coef_var > 1 is considered high variance. The numbers I picked are just
- * heuristics to catch SMM interference and make the output look nice. */
+ * coef_var > 1 is considered high variance. The numbers I picked are
+ * just heuristics to catch SMM interference and make the output look
+ * nice. */
coef_var = sqrt(stats->var_time) / stats->avg_time;
if (coef_var > HI_COEF_VAR) {
hist_max_time = stats->avg_time * 3;
hist_min_time = stats->avg_time / 3;
} else { /* 'normal' data */
- /* trimming the printable hist at 3 stddevs, which for normal data is
- * 99.7% of the data. For most any data, it gets 89% (Chebyshev's
- * inequality) */
+ /* trimming the printable hist at 3 stddevs, which for normal
+ * data is 99.7% of the data. For most any data, it gets 89%
+ * (Chebyshev's inequality) */
hist_max_time = stats->avg_time + 3 * sqrt(stats->var_time);
hist_min_time = stats->avg_time - 3 * sqrt(stats->var_time);
if (hist_min_time > hist_max_time)
@@ -132,9 +136,9 @@
for (int j = 0; j < nr_j; j++) {
if (stats->get_sample(data, i, j, &sample_time))
continue;
- /* need to shift, offset by min_time. anything too small is 0 and
- * will go into the first bin. anything too large will go into the
- * last bin. */
+ /* need to shift, offset by min_time. anything too
+ * small is 0 and will go into the first bin. anything
+ * too large will go into the last bin. */
lat_idx = sample_time < lat_min_time
? 0
: (sample_time - lat_min_time) / lat_bin_sz;
@@ -142,7 +146,8 @@
lat_times[lat_idx]++;
hist_idx = sample_time < hist_min_time
? 0
- : (sample_time - hist_min_time) / hist_bin_sz;
+ : (sample_time - hist_min_time) /
+ hist_bin_sz;
hist_idx = MIN(hist_idx, nr_hist_bins - 1);
hist_times[hist_idx]++;
/* useful for formatting the ***s */
@@ -155,18 +160,23 @@
for (int i = 0; i < nr_lat_bins; i++) {
accum_samples += lat_times[i];
/* (i + 1), since we've just accumulated one bucket's worth */
- if (!stats->lat_50 && accum_samples / stats->total_samples > 0.50)
+ if (!stats->lat_50 &&
+ accum_samples / stats->total_samples > 0.50)
stats->lat_50 = (i + 1) * lat_bin_sz + lat_min_time;
- if (!stats->lat_75 && accum_samples / stats->total_samples > 0.75)
+ if (!stats->lat_75 &&
+ accum_samples / stats->total_samples > 0.75)
stats->lat_75 = (i + 1) * lat_bin_sz + lat_min_time;
- if (!stats->lat_90 && accum_samples / stats->total_samples > 0.90)
+ if (!stats->lat_90 &&
+ accum_samples / stats->total_samples > 0.90)
stats->lat_90 = (i + 1) * lat_bin_sz + lat_min_time;
- if (!stats->lat_99 && accum_samples / stats->total_samples > 0.99)
+ if (!stats->lat_99 &&
+ accum_samples / stats->total_samples > 0.99)
stats->lat_99 = (i + 1) * lat_bin_sz + lat_min_time;
}
for (int i = 0; i < nr_hist_bins; i++) {
uint64_t interval_start = i * hist_bin_sz + hist_min_time;
uint64_t interval_end = (i + 1) * hist_bin_sz + hist_min_time;
+
/* customize the first and last entries */
if (i == 0)
interval_start = MIN(interval_start, stats->min_time);
@@ -175,11 +185,12 @@
/* but not at the sake of formatting! (8 spaces) */
interval_end = MIN(interval_end, 99999999);
}
- printf(" [%8llu - %8llu] %7d: ", interval_start, interval_end,
- hist_times[i]);
+ printf(" [%8llu - %8llu] %7d: ", interval_start,
+ interval_end, hist_times[i]);
/* nr_dots = hist_times[i] * nr_dots_per_sample
* = hist_times[i] * (max_num_dots / max_hist_bin) */
int nr_dots = hist_times[i] * max_dots_per_row / max_hist_bin;
+
for (int j = 0; j < nr_dots; j++)
printf("*");
printf("\n");
@@ -191,7 +202,8 @@
printf("Stdev time : %f\n", sqrt(stats->var_time));
printf("Coef Var : %f\n", coef_var);
if (coef_var > HI_COEF_VAR)
- printf("\tHigh coeff of var with serious outliers, adjusted bins\n");
+ printf(
+ "\tHigh coeff of var with serious outliers, adjusted bins\n");
/* numbers are overestimates by at most a lat bin */
printf("50/75/90/99: %d / %d / %d / %d (-<%ld)\n", stats->lat_50,
stats->lat_75, stats->lat_90, stats->lat_99, lat_bin_sz);
@@ -222,7 +234,7 @@
unsigned int *next_sample;
unsigned int *step_events;
unsigned int most_step_events = 1;
- unsigned int max_dots_per_row = 45; /* looks good with 80-wide col */
+ unsigned int max_dots_per_row = 45; /* looks good with 80-wide col */
unsigned int total_events = 0;
if (!nr_steps)
@@ -253,15 +265,19 @@
}
for (int k = 0; k < nr_steps; k++) {
time_now += interval;
- /* for every 'thread', we'll figure out how many events occurred, and
- * advance next_sample to track the next one to consider */
+ /* for every 'thread', we'll figure out how many events
+ * occurred, and advance next_sample to track the next one to
+ * consider */
for (int i = 0; i < nr_i; i++) {
- /* count nr locks that have happened, advance per thread tracker */
+ /* count nr locks that have happened, advance per thread
+ * tracker */
for ( ; next_sample[i] < nr_j; next_sample[i]++) {
/* skip this thread if it has no more data */
- if (get_sample(data, i, next_sample[i], &sample))
+ if (get_sample(data, i, next_sample[i],
+ &sample))
continue;
- /* break when we found one that hasn't happened yet */
+ /* break when we found one that hasn't happened
+ * yet */
if (!(sample <= time_now))
break;
step_events[k]++;
@@ -272,7 +288,8 @@
most_step_events = MAX(most_step_events, step_events[k]);
}
if (nr_print_steps)
- printf("Events per dot: %d\n", most_step_events / max_dots_per_row);
+ printf("Events per dot: %d\n",
+ most_step_events / max_dots_per_row);
for (int k = 0; k < nr_print_steps; k++) {
/* Last step isn't accurate, will only be partially full */
if (k == nr_steps - 1)
@@ -280,8 +297,9 @@
printf("%6d: ", k);
printf("%6d ", step_events[k]);
/* nr_dots = step_events[k] * nr_dots_per_event
- * = step_events[k] * (max_dots_per_row / most_step_events) */
- int nr_dots = step_events[k] * max_dots_per_row / most_step_events;
+ * = step_events[k] * (max_dots_per_row / most_step_events) */
+ int nr_dots = step_events[k] * max_dots_per_row /
+ most_step_events;
for (int i = 0; i < nr_dots; i++)
printf("*");
printf("\n");
diff --git a/user/electric-fence/efence.c b/user/electric-fence/efence.c
index 655135a..57fefbf 100644
--- a/user/electric-fence/efence.c
+++ b/user/electric-fence/efence.c
@@ -333,7 +333,8 @@
if (size > allocationListSize) {
slot[1].internalAddress = slot[1].userAddress =
((char *)slot[0].internalAddress) + slot[0].internalSize;
- slot[1].internalSize = slot[1].userSize = size - slot[0].internalSize;
+ slot[1].internalSize = slot[1].userSize
+ = size - slot[0].internalSize;
slot[1].mode = FREE;
}
@@ -476,9 +477,11 @@
for (slot = allocationList, count = slotCount; count > 0; count--) {
if (slot->mode == FREE && slot->internalSize >= internalSize) {
- if (!fullSlot || slot->internalSize < fullSlot->internalSize) {
+ if (!fullSlot || slot->internalSize <
+ fullSlot->internalSize) {
fullSlot = slot;
- if (slot->internalSize == internalSize && emptySlots[0])
+ if (slot->internalSize == internalSize &&
+ emptySlots[0])
break; /* All done, */
}
} else if (slot->mode == NOT_IN_USE) {
@@ -486,7 +489,8 @@
emptySlots[0] = slot;
else if (!emptySlots[1])
emptySlots[1] = slot;
- else if (fullSlot && fullSlot->internalSize == internalSize)
+ else if (fullSlot && fullSlot->internalSize ==
+ internalSize)
break; /* All done. */
}
slot++;
@@ -537,7 +541,8 @@
* a free buffer containing the surplus memory.
*/
if (fullSlot->internalSize > internalSize) {
- emptySlots[0]->internalSize = fullSlot->internalSize - internalSize;
+ emptySlots[0]->internalSize =
+ fullSlot->internalSize - internalSize;
emptySlots[0]->internalAddress =
((char *)fullSlot->internalAddress) + internalSize;
emptySlots[0]->mode = FREE;
@@ -641,7 +646,8 @@
register size_t count = slotCount;
for (; count > 0; count--) {
- if (((char *)slot->internalAddress) + slot->internalSize == address)
+ if (((char *)slot->internalAddress) + slot->internalSize ==
+ address)
return slot;
slot++;
}
@@ -705,7 +711,8 @@
slot = previousSlot;
unUsedSlots++;
}
- if (nextSlot && (nextSlot->mode == FREE || nextSlot->mode == PROTECTED)) {
+ if (nextSlot && (nextSlot->mode == FREE || nextSlot->mode == PROTECTED))
+ {
/* Coalesce next slot with this one. */
slot->internalSize += nextSlot->internalSize;
nextSlot->internalAddress = nextSlot->userAddress = 0;
@@ -748,8 +755,8 @@
slot = slotForUserAddress(oldBuffer);
if (slot == 0)
- EF_Abort("realloc(%a, %d): address not from malloc().", oldBuffer,
- newSize);
+ EF_Abort("realloc(%a, %d): address not from malloc().",
+ oldBuffer, newSize);
if (newSize < (size = slot->userSize))
size = newSize;
diff --git a/user/electric-fence/eftest.c b/user/electric-fence/eftest.c
index d185f3f..be67d54 100644
--- a/user/electric-fence/eftest.c
+++ b/user/electric-fence/eftest.c
@@ -46,8 +46,8 @@
if (sigsetjmp(env, 1) == 0) {
int status;
- signal(PAGE_PROTECTION_VIOLATED_SIGNAL, segmentationFaultHandler);
- status = (*test)();
+ signal(PAGE_PROTECTION_VIOLATED_SIGNAL,
+ segmentationFaultHandler); status = (*test)();
signal(PAGE_PROTECTION_VIOLATED_SIGNAL, SIG_DFL);
return status;
} else
diff --git a/user/electric-fence/print.c b/user/electric-fence/print.c
index 7ce8597..50f1bc9 100644
--- a/user/electric-fence/print.c
+++ b/user/electric-fence/print.c
@@ -65,7 +65,8 @@
* it is large enough to contain all of the
* bits of a void pointer.
*/
- printNumber((ef_number)va_arg(args, void *), 0x10);
+ printNumber((ef_number)va_arg(args, void *),
+ 0x10);
break;
case 's': {
const char *string;
@@ -89,7 +90,8 @@
case 'x':
printNumber(va_arg(args, u_int), 0x10);
break;
- case 'c': { /*Cast used, since char gets promoted to int in ... */
+ case 'c': {
+ /*Cast used, since char gets promoted to int in ... */
char c = (char)va_arg(args, int);
(void)write(2, &c, 1);
diff --git a/user/iplib/dial.c b/user/iplib/dial.c
index b38c441..e141f69 100644
--- a/user/iplib/dial.c
+++ b/user/iplib/dial.c
@@ -45,12 +45,14 @@
p = strrchr(clone, '/');
*p = 0;
if (dir)
- sprintf(dir, "%.*s/%.*s", 2 * NAMELEN + 1, clone, NAMELEN, name);
+ sprintf(dir, "%.*s/%.*s", 2 * NAMELEN + 1, clone, NAMELEN,
+ name);
sprintf(data, "%.*s/%.*s/data", 2 * NAMELEN + 1, clone, NAMELEN, name);
/* set local side (port number, for example) if we need to */
if (local)
- sprintf(name, "connect %.*s %.*s", 2 * NAMELEN, dest, NAMELEN, local);
+ sprintf(name, "connect %.*s %.*s", 2 * NAMELEN, dest, NAMELEN,
+ local);
else
sprintf(name, "connect %.*s", 2 * NAMELEN, dest);
/* connect */
diff --git a/user/iplib/epoll.c b/user/iplib/epoll.c
index f415cb2..9338327 100644
--- a/user/iplib/epoll.c
+++ b/user/iplib/epoll.c
@@ -6,25 +6,25 @@
*
* TODO: There are a few incompatibilities with Linux's epoll, some of which are
* artifacts of the implementation, and other issues:
- * - you can't epoll on an epoll fd (or any user fd). you can only epoll on a
- * kernel FD that accepts your FD taps.
- * - there's no EPOLLONESHOT or level-triggered support.
- * - you can only tap one FD at a time, so you can't add the same FD to
- * multiple epoll sets.
- * - closing the epoll is a little dangerous, if there are outstanding INDIR
- * events. this will only pop up if you're yielding cores, maybe getting
- * preempted, and are unlucky.
- * - epoll_create1 does not support CLOEXEC. That'd need some work in glibc's
- * exec and flags in struct user_fd.
- * - EPOLL_CTL_MOD is just a DEL then an ADD. There might be races associated
- * with that.
- * - epoll_pwait is probably racy.
- * - You can't dup an epoll fd (same as other user FDs).
- * - If you add a BSD socket FD to an epoll set, you'll get taps on both the
- * data FD and the listen FD.
- * - If you add the same BSD socket listener to multiple epoll sets, you will
- * likely fail. This is in addition to being able to tap only one FD at a
- * time.
+ * - you can't epoll on an epoll fd (or any user fd). you can only epoll on a
+ * kernel FD that accepts your FD taps.
+ * - there's no EPOLLONESHOT or level-triggered support.
+ * - you can only tap one FD at a time, so you can't add the same FD to
+ * multiple epoll sets.
+ * - closing the epoll is a little dangerous, if there are outstanding INDIR
+ * events. this will only pop up if you're yielding cores, maybe getting
+ * preempted, and are unlucky.
+ * - epoll_create1 does not support CLOEXEC. That'd need some work in glibc's
+ * exec and flags in struct user_fd.
+ * - EPOLL_CTL_MOD is just a DEL then an ADD. There might be races associated
+ * with that.
+ * - epoll_pwait is probably racy.
+ * - You can't dup an epoll fd (same as other user FDs).
+ * - If you add a BSD socket FD to an epoll set, you'll get taps on both the
+ * data FD and the listen FD.
+ * - If you add the same BSD socket listener to multiple epoll sets, you will
+ * likely fail. This is in addition to being able to tap only one FD at a
+ * time.
* */
#include <sys/epoll.h>
@@ -55,17 +55,17 @@
* INDIRs and RCU-style grace periods. Not a big deal, since the number of
* these is the number of threads that concurrently do epoll timeouts. */
struct ep_alarm {
- struct event_queue *alarm_evq;
- struct syscall sysc;
+ struct event_queue *alarm_evq;
+ struct syscall sysc;
};
static struct kmem_cache *ep_alarms_cache;
struct epoll_ctlr {
TAILQ_ENTRY(epoll_ctlr) link;
- struct event_queue *ceq_evq;
- uth_mutex_t *mtx;
- struct user_fd ufd;
+ struct event_queue *ceq_evq;
+ uth_mutex_t *mtx;
+ struct user_fd ufd;
};
TAILQ_HEAD(epoll_ctlrs, epoll_ctlr);
@@ -79,15 +79,16 @@
* If we ever do not maintain a 1:1 mapping from FDs to CEQ IDs, we can use this
* to track the CEQ ID and FD. */
struct ep_fd_data {
- struct epoll_event ep_event;
- int fd;
- int filter;
+ struct epoll_event ep_event;
+ int fd;
+ int filter;
};
/* Converts epoll events to FD taps. */
static int ep_events_to_taps(uint32_t ep_ev)
{
int taps = 0;
+
if (ep_ev & EPOLLIN)
taps |= FDTAP_FILT_READABLE;
if (ep_ev & EPOLLOUT)
@@ -108,6 +109,7 @@
static uint32_t taps_to_ep_events(int taps)
{
uint32_t ep_ev = 0;
+
if (taps & FDTAP_FILT_READABLE)
ep_ev |= EPOLLIN;
if (taps & FDTAP_FILT_WRITABLE)
@@ -138,6 +140,7 @@
static struct epoll_ctlr *fd_to_cltr(int fd)
{
struct user_fd *ufd = ufd_lookup(fd);
+
if (!ufd)
return 0;
if (ufd->magic != EPOLL_UFD_MAGIC) {
@@ -151,6 +154,7 @@
static struct event_queue *ep_get_ceq_evq(unsigned int ceq_ring_sz)
{
struct event_queue *ceq_evq = get_eventq_raw();
+
ceq_evq->ev_mbox->type = EV_MBOX_CEQ;
ceq_init(&ceq_evq->ev_mbox->ceq, CEQ_OR, NR_FILE_DESC_MAX, ceq_ring_sz);
ceq_evq->ev_flags = EVENT_INDIR | EVENT_SPAM_INDIR | EVENT_WAKEUP;
@@ -162,6 +166,7 @@
{
/* Don't care about the actual message, just using it for a wakeup */
struct event_queue *alarm_evq = get_eventq(EV_MBOX_BITMAP);
+
alarm_evq->ev_flags = EVENT_INDIR | EVENT_SPAM_INDIR | EVENT_WAKEUP;
evq_attach_wakeup_ctlr(alarm_evq);
return alarm_evq;
@@ -213,10 +218,11 @@
tap_req_i->cmd = FDTAP_CMD_REM;
free(ep_fd_i);
}
- /* Requests could fail if the tapped files are already closed. We need to
- * skip the failed one (the +1) and untap the rest. */
+ /* Requests could fail if the tapped files are already closed. We need
+ * to skip the failed one (the +1) and untap the rest. */
do {
- nr_done += sys_tap_fds(tap_reqs + nr_done, nr_tap_req - nr_done);
+ nr_done += sys_tap_fds(tap_reqs + nr_done,
+ nr_tap_req - nr_done);
nr_done += 1; /* nr_done could be more than nr_tap_req now */
} while (nr_done < nr_tap_req);
free(tap_reqs);
@@ -235,8 +241,8 @@
ep->mtx = uth_mutex_alloc();
ep->ufd.magic = EPOLL_UFD_MAGIC;
ep->ufd.close = epoll_close;
- /* Size is a hint for the CEQ concurrency. We can actually handle as many
- * kernel FDs as is possible. */
+ /* Size is a hint for the CEQ concurrency. We can actually handle as
+ * many kernel FDs as is possible. */
ep->ceq_evq = ep_get_ceq_evq(ROUNDUPPWR2(size));
return 0;
}
@@ -267,9 +273,9 @@
struct ep_alarm *ep_a = (struct ep_alarm*)obj;
/* TODO: (RCU/SLAB). Somehow the slab allocator is trying to reap our
- * objects. Note that when we update userspace to use magazines, the dtor
- * will fire earlier (when the object is given to the slab layer). We'll
- * need to be careful about the final freeing of the ev_q. */
+ * objects. Note that when we update userspace to use magazines, the
+ * dtor will fire earlier (when the object is given to the slab layer).
+ * We'll need to be careful about the final freeing of the ev_q. */
panic("Epoll alarms should never be destroyed!");
ep_put_alarm_evq(ep_a->alarm_evq);
}
@@ -281,9 +287,9 @@
register_close_cb(&epoll_close_cb);
ctlrs_mtx = uth_mutex_alloc();
ep_alarms_cache = kmem_cache_create("epoll alarms",
- sizeof(struct ep_alarm),
- __alignof__(sizeof(struct ep_alarm)), 0,
- ep_alarm_ctor, ep_alarm_dtor, NULL);
+ sizeof(struct ep_alarm),
+ __alignof__(sizeof(struct ep_alarm)), 0,
+ ep_alarm_ctor, ep_alarm_dtor, NULL);
assert(ep_alarms_cache);
}
@@ -316,8 +322,9 @@
int epoll_create1(int flags)
{
- /* TODO: we're supposed to support CLOEXEC. Our FD is a user_fd, so that'd
- * require some support in glibc's exec to close our epoll ctlr. */
+ /* TODO: we're supposed to support CLOEXEC. Our FD is a user_fd, so
+ * that'd require some support in glibc's exec to close our epoll ctlr.
+ * */
return epoll_create(1);
}
@@ -397,8 +404,8 @@
int ret, sock_listen_fd, sock_ctl_fd;
struct epoll_event listen_event;
- /* Only support ET. Also, we just ignore EPOLLONESHOT. That might work,
- * logically, just with spurious events firing. */
+ /* Only support ET. Also, we just ignore EPOLLONESHOT. That might
+ * work, logically, just with spurious events firing. */
if (!(event->events & EPOLLET)) {
errno = EPERM;
werrstr("Epoll level-triggered not supported");
@@ -409,20 +416,20 @@
werrstr("Epoll one-shot not supported");
return -1;
}
- /* The sockets-to-plan9 networking shims are a bit inconvenient. The user
- * asked us to epoll on an FD, but that FD is actually a Qdata FD. We might
- * need to actually epoll on the listen_fd. Further, we don't know yet
- * whether or not they want the listen FD. They could epoll on the socket,
- * then listen later and want to wake up on the listen.
+ /* The sockets-to-plan9 networking shims are a bit inconvenient. The
+ * user asked us to epoll on an FD, but that FD is actually a Qdata FD.
+ * We might need to actually epoll on the listen_fd. Further, we don't
+ * know yet whether or not they want the listen FD. They could epoll on
+ * the socket, then listen later and want to wake up on the listen.
*
* So in the case we have a socket FD, we'll actually open the listen FD
* regardless (glibc handles this), and we'll epoll on both FDs.
- * Technically, either FD could fire and they'd get an epoll event for it,
- * but I think socket users will use only listen or data.
+ * Technically, either FD could fire and they'd get an epoll event for
+ * it, but I think socket users will use only listen or data.
*
* As far as tracking the FD goes for epoll_wait() reporting, if the app
- * wants to track the FD they think we are using, then they already passed
- * that in event->data. */
+ * wants to track the FD they think we are using, then they already
+ * passed that in event->data. */
_sock_lookup_rock_fds(fd, TRUE, &sock_listen_fd, &sock_ctl_fd);
if (sock_listen_fd >= 0) {
listen_event.events = EPOLLET | EPOLLIN | EPOLLHUP;
@@ -454,8 +461,8 @@
assert(ep_fd->fd == fd);
tap_req.fd = fd;
tap_req.cmd = FDTAP_CMD_REM;
- /* ignoring the return value; we could have failed to remove it if the FD
- * has already closed and the kernel removed the tap. */
+ /* ignoring the return value; we could have failed to remove it if the
+ * FD has already closed and the kernel removed the tap. */
sys_tap_fds(&tap_req, 1);
ceq_ev->user_data = 0;
free(ep_fd);
@@ -467,20 +474,22 @@
{
int sock_listen_fd, sock_ctl_fd;
- /* If we were dealing with a socket shim FD, we tapped both the listen and
- * the data file and need to untap both of them.
+ /* If we were dealing with a socket shim FD, we tapped both the listen
+ * and the data file and need to untap both of them.
*
- * We could be called from a close_cb, and we already closed the listen FD.
- * In that case, we don't want to try and open it. If the listen FD isn't
- * open, then we know it isn't in an epoll set. We also know the data FD
- * isn't epolled either, since we always epoll both FDs for rocks. */
+ * We could be called from a close_cb, and we already closed the listen
+ * FD. In that case, we don't want to try and open it. If the listen
+ * FD isn't open, then we know it isn't in an epoll set. We also know
+ * the data FD isn't epolled either, since we always epoll both FDs for
+ * rocks. */
_sock_lookup_rock_fds(fd, FALSE, &sock_listen_fd, &sock_ctl_fd);
if (sock_listen_fd >= 0) {
- /* It's possible to fail here. Even though we tapped it already, if the
- * deletion was triggered from close callbacks, it's possible for the
- * sock_listen_fd to be closed first, which would have triggered an
- * epoll_ctl_del. When we get around to closing the Rock FD, the listen
- * FD was already closed. */
+ /* It's possible to fail here. Even though we tapped it
+ * already, if the deletion was triggered from close callbacks,
+ * it's possible for the sock_listen_fd to be closed first,
+ * which would have triggered an epoll_ctl_del. When we get
+ * around to closing the Rock FD, the listen FD was already
+ * closed. */
__epoll_ctl_del_raw(ep, sock_listen_fd, event);
}
return __epoll_ctl_del_raw(ep, fd, event);
@@ -501,25 +510,25 @@
}
uth_mutex_lock(ep->mtx);
switch (op) {
- case (EPOLL_CTL_MOD):
- /* In lieu of a proper MOD, just remove and readd. The errors might
- * not work out well, and there could be a missed event in the
- * middle. Not sure what the guarantees are, but we can fake a
- * poke. (TODO). */
- ret = __epoll_ctl_del(ep, fd, 0);
- if (ret)
- break;
- ret = __epoll_ctl_add(ep, fd, event);
+ case (EPOLL_CTL_MOD):
+ /* In lieu of a proper MOD, just remove and readd. The errors
+ * might not work out well, and there could be a missed event in
+ * the middle. Not sure what the guarantees are, but we can
+ * fake a poke. (TODO). */
+ ret = __epoll_ctl_del(ep, fd, 0);
+ if (ret)
break;
- case (EPOLL_CTL_ADD):
- ret = __epoll_ctl_add(ep, fd, event);
- break;
- case (EPOLL_CTL_DEL):
- ret = __epoll_ctl_del(ep, fd, event);
- break;
- default:
- errno = EINVAL;
- ret = -1;
+ ret = __epoll_ctl_add(ep, fd, event);
+ break;
+ case (EPOLL_CTL_ADD):
+ ret = __epoll_ctl_add(ep, fd, event);
+ break;
+ case (EPOLL_CTL_DEL):
+ ret = __epoll_ctl_del(ep, fd, event);
+ break;
+ default:
+ errno = EINVAL;
+ ret = -1;
}
uth_mutex_unlock(ep->mtx);
return ret;
@@ -588,22 +597,25 @@
return nr_ret;
if (timeout == 0)
return 0;
- /* From here on down, we're going to block until there is some activity */
+ /* From here on down, we're going to block until there is some activity
+ */
if (timeout != -1) {
ep_a = kmem_cache_alloc(ep_alarms_cache, 0);
assert(ep_a);
syscall_async_evq(&ep_a->sysc, ep_a->alarm_evq, SYS_block,
timeout * 1000);
- uth_blockon_evqs(&msg, &which_evq, 2, ep->ceq_evq, ep_a->alarm_evq);
+ uth_blockon_evqs(&msg, &which_evq, 2, ep->ceq_evq,
+ ep_a->alarm_evq);
if (which_evq == ep_a->alarm_evq) {
kmem_cache_free(ep_alarms_cache, ep_a);
return 0;
}
- /* The alarm sysc may or may not have finished yet. This will force it
- * to *start* to finish iff it is still a submitted syscall. */
+ /* The alarm sysc may or may not have finished yet. This will
+ * force it to *start* to finish iff it is still a submitted
+ * syscall. */
sys_abort_sysc(&ep_a->sysc);
- /* But we still need to wait until the syscall completed. Need a
- * dummy msg, since we don't want to clobber the real msg. */
+ /* But we still need to wait until the syscall completed. Need
+ * a dummy msg, since we don't want to clobber the real msg. */
uth_blockon_evqs(&dummy_msg, 0, 1, ep_a->alarm_evq);
kmem_cache_free(ep_alarms_cache, ep_a);
} else {
@@ -613,13 +625,13 @@
if (get_ep_event_from_msg(ep, &msg, &events[0]))
nr_ret = 1;
uth_mutex_unlock(ep->mtx);
- /* We had to extract one message already as part of the blocking process.
- * We might be able to get more. */
+ /* We had to extract one message already as part of the blocking
+ * process. We might be able to get more. */
nr_ret += __epoll_wait_poll(ep, events + nr_ret, maxevents - nr_ret);
/* This is a little nasty and hopefully a rare race. We still might not
- * have a ret, but we expected to block until we had something. We didn't
- * time out yet, but we spuriously woke up. We need to try again (ideally,
- * we'd subtract the time left from the original timeout). */
+ * have a ret, but we expected to block until we had something. We
+ * didn't time out yet, but we spuriously woke up. We need to try again
+ * (ideally, we'd subtract the time left from the original timeout). */
if (!nr_ret)
return __epoll_wait(ep, events, maxevents, timeout);
return nr_ret;
@@ -648,6 +660,7 @@
{
int ready;
sigset_t origmask;
+
/* TODO: this is probably racy */
sigprocmask(SIG_SETMASK, sigmask, &origmask);
ready = epoll_wait(epfd, events, maxevents, timeout);
diff --git a/user/iplib/ifaddrs.c b/user/iplib/ifaddrs.c
index 09a159f..af3338d 100644
--- a/user/iplib/ifaddrs.c
+++ b/user/iplib/ifaddrs.c
@@ -46,7 +46,8 @@
addr_fd = open(path, O_RDONLY);
if (addr_fd < 0)
continue;
- if (read(addr_fd, etheraddr, sizeof(etheraddr)) < sizeof(etheraddr)) {
+ if (read(addr_fd, etheraddr,
+ sizeof(etheraddr)) < sizeof(etheraddr)) {
fprintf(stderr, "Read addr from %s: %r", d->d_name);
close(addr_fd);
continue;
@@ -64,8 +65,8 @@
sa_ll = calloc(sizeof(struct sockaddr_ll), 1);
ifa->ifa_addr = (struct sockaddr*)sa_ll;
sa_ll->sll_family = AF_PACKET;
- /* TODO: could set protocol and hatype, if we ever get the headers for
- * the options. Probably not worth it. */
+ /* TODO: could set protocol and hatype, if we ever get the
+ * headers for the options. Probably not worth it. */
sa_ll->sll_ifindex = atoi(&ifa->ifa_name[SIZE_OF_ETHER]);
sa_ll->sll_halen = 6;
for (int i = 0; i < 6; i++)
@@ -124,8 +125,8 @@
struct ipifc *ifc, *ifc_i;
struct iplifc *lifc_i;
- /* This gives us a list of ipifcs (actual interfaces), each of which has a
- * list of lifcs (local interface, including the IP addr). */
+ /* This gives us a list of ipifcs (actual interfaces), each of which has
+ * a list of lifcs (local interface, including the IP addr). */
ifc = readipifc(NULL, NULL, -1);
for (ifc_i = ifc; ifc_i; ifc_i = ifc_i->next) {
for (lifc_i = ifc_i->lifc; lifc_i; lifc_i = lifc_i->next)
diff --git a/user/iplib/include/iplib/iplib.h b/user/iplib/include/iplib/iplib.h
index 3d28dba..d19a705 100644
--- a/user/iplib/include/iplib/iplib.h
+++ b/user/iplib/include/iplib/iplib.h
@@ -14,9 +14,9 @@
enum
{
- ETH_HDR_LEN = 14,
- ETH_OFF_DST = 0,
- ETH_OFF_SRC = 6,
+ ETH_HDR_LEN = 14,
+ ETH_OFF_DST = 0,
+ ETH_OFF_SRC = 6,
ETH_OFF_ETYPE = 12,
ETH_ADDR_LEN = 6,
@@ -27,7 +27,7 @@
IPV4_HDR_LEN = 20,
IPV4_OFF_LEN = 2,
- IPV4_OFF_ID = 4,
+ IPV4_OFF_ID = 4,
IPV4_OFF_TTL = 8,
IPV4_OFF_PROTO = 9,
IPV4_OFF_XSUM = 10,
@@ -37,39 +37,39 @@
IPV4_ADDR_LEN = 4,
IP_ICMPPROTO = 1,
IP_IGMPPROTO = 2,
- IP_TCPPROTO = 6,
- IP_UDPPROTO = 17,
- IP_ILPROTO = 40,
+ IP_TCPPROTO = 6,
+ IP_UDPPROTO = 17,
+ IP_ILPROTO = 40,
- UDP_HDR_LEN = 8,
+ UDP_HDR_LEN = 8,
UDP_OFF_SRC_PORT = 0,
UDP_OFF_DST_PORT = 2,
- UDP_OFF_LEN = 4,
+ UDP_OFF_LEN = 4,
UDP_OFF_XSUM = 6,
- TCP_HDR_LEN = 20,
+ TCP_HDR_LEN = 20,
TCP_OFF_SRC_PORT = 0,
TCP_OFF_DST_PORT = 2,
- TCP_OFF_SEQ = 4,
- TCP_OFF_ACK = 8,
+ TCP_OFF_SEQ = 4,
+ TCP_OFF_ACK = 8,
TCP_OFF_DATA = 12,
- TCP_OFF_FL = 12,
- TCP_OFF_WIN = 14,
+ TCP_OFF_FL = 12,
+ TCP_OFF_WIN = 14,
TCP_OFF_XSUM = 16,
- ARP_PKT_LEN = 28,
+ ARP_PKT_LEN = 28,
ARP_OFF_HTYPE = 0,
ARP_OFF_PTYPE = 2,
ARP_OFF_HLEN = 4,
ARP_OFF_PLEN = 5,
- ARP_OFF_OP = 6,
- ARP_OFF_SHA = 8,
- ARP_OFF_SPA = 14,
- ARP_OFF_THA = 18,
- ARP_OFF_TPA = 24,
+ ARP_OFF_OP = 6,
+ ARP_OFF_SHA = 8,
+ ARP_OFF_SPA = 14,
+ ARP_OFF_THA = 18,
+ ARP_OFF_TPA = 24,
- ARP_OP_REQ = 1,
- ARP_OP_RSP = 2,
+ ARP_OP_REQ = 1,
+ ARP_OP_RSP = 2,
IPaddrlen= 16,
IPv4addrlen= 4,
@@ -238,39 +238,39 @@
uint8_t lport[2]; /* local port */
};
-uint8_t* defmask(uint8_t*);
-void maskip(uint8_t*, uint8_t*, uint8_t*);
-//int eipfmt(Fmt*);
-int isv4(uint8_t*);
-int64_t parseip(uint8_t*, char*);
-int64_t parseipmask(uint8_t*, char*);
-char* v4parseip(uint8_t*, char*);
-char* v4parsecidr(uint8_t*, uint8_t*, char*);
-int parseether(uint8_t*, char*);
-int myipaddr(uint8_t*, char*);
+uint8_t *defmask(uint8_t*);
+void maskip(uint8_t*, uint8_t*, uint8_t*);
+//int eipfmt(Fmt*);
+int isv4(uint8_t*);
+int64_t parseip(uint8_t*, char*);
+int64_t parseipmask(uint8_t*, char*);
+char *v4parseip(uint8_t*, char*);
+char *v4parsecidr(uint8_t*, uint8_t*, char*);
+int parseether(uint8_t*, char*);
+int myipaddr(uint8_t*, char*);
int my_router_addr(uint8_t *addr, char *net);
-int myetheraddr(uint8_t*, char*);
-int equivip4(uint8_t*, uint8_t*);
-int equivip6(uint8_t*, uint8_t*);
+int myetheraddr(uint8_t*, char*);
+int equivip4(uint8_t*, uint8_t*);
+int equivip6(uint8_t*, uint8_t*);
struct ipifc *readipifc(char *net, struct ipifc *to_free, int index);
struct iplifc *get_first_noloop_iplifc(char *net, struct ipifc **ifc);
void free_ipifc(struct ipifc *ifc);
-void hnputv(void*, uint64_t);
-void hnputl(void*, unsigned int);
-void hnputs(void*, uint16_t);
-uint64_t nhgetv(void*);
-unsigned int nhgetl(void*);
-uint16_t nhgets(void*);
-uint16_t ptclbsum(uint8_t*, int);
+void hnputv(void*, uint64_t);
+void hnputl(void*, unsigned int);
+void hnputs(void*, uint16_t);
+uint64_t nhgetv(void*);
+unsigned int nhgetl(void*);
+uint16_t nhgets(void*);
+uint16_t ptclbsum(uint8_t*, int);
uint16_t ip_calc_xsum(uint8_t *addr, size_t len);
-int v6tov4(uint8_t*, uint8_t*);
-void v4tov6(uint8_t*, uint8_t*);
+int v6tov4(uint8_t*, uint8_t*);
+void v4tov6(uint8_t*, uint8_t*);
-#define ipcmp(x, y) memcmp(x, y, IPaddrlen)
-#define ipmove(x, y) memmove(x, y, IPaddrlen)
+#define ipcmp(x, y) memcmp(x, y, IPaddrlen)
+#define ipmove(x, y) memmove(x, y, IPaddrlen)
extern uint8_t IPv4bcast[IPaddrlen];
extern uint8_t IPv4bcastobs[IPaddrlen];
diff --git a/user/iplib/netmkaddr.c b/user/iplib/netmkaddr.c
index 277ef8c..90fe107 100644
--- a/user/iplib/netmkaddr.c
+++ b/user/iplib/netmkaddr.c
@@ -35,12 +35,14 @@
if (cp == 0) {
if (defnet == 0) {
if (defsrv)
- snprintf(buf, buf_sz, "net!%s!%s", linear, defsrv);
+ snprintf(buf, buf_sz, "net!%s!%s", linear,
+ defsrv);
else
snprintf(buf, buf_sz, "net!%s", linear);
} else {
if (defsrv)
- snprintf(buf, buf_sz, "%s!%s!%s", defnet, linear, defsrv);
+ snprintf(buf, buf_sz, "%s!%s!%s", defnet,
+ linear, defsrv);
else
snprintf(buf, buf_sz, "%s!%s", defnet, linear);
}
diff --git a/user/iplib/parseip.c b/user/iplib/parseip.c
index 973cd0d..e28317e 100644
--- a/user/iplib/parseip.c
+++ b/user/iplib/parseip.c
@@ -129,7 +129,8 @@
return -1; /* parse error */
}
if (i < IPaddrlen) {
- memmove(&to[elipsis + IPaddrlen - i], &to[elipsis], i - elipsis);
+ memmove(&to[elipsis + IPaddrlen - i], &to[elipsis],
+ i - elipsis);
memset(&to[elipsis], 0, IPaddrlen - i);
}
if (v4) {
@@ -195,8 +196,8 @@
if (*p == '/') {
/* as a number of prefix bits */
i = strtoul(p + 1, &p, 0);
- /* We might have been passed a v6 mask - the signal for that will be
- * having more than 32 bits. */
+ /* We might have been passed a v6 mask - the signal for that
+ * will be having more than 32 bits. */
if (i >= 32)
i -= 128 - 32;
memset(mask, 0, IPv4addrlen);
diff --git a/user/iplib/poll.c b/user/iplib/poll.c
index 0b41264..7b86d47 100644
--- a/user/iplib/poll.c
+++ b/user/iplib/poll.c
@@ -57,9 +57,10 @@
FD_SET(i, &rd_fds);
if (fds[i].events & POLLOUT)
FD_SET(i, &wr_fds);
- /* TODO: We should be also asking for exceptions on all FDs. But select
- * is spurious, so it will actually tell us we had errors on all of our
- * FDs, which will probably confuse programs. */
+ /* TODO: We should be also asking for exceptions on all FDs.
+ * But select is spurious, so it will actually tell us we had
+ * errors on all of our FDs, which will probably confuse
+ * programs. */
}
ret = pselect(max_fd_plus_one, &rd_fds, &wr_fds, &ex_fds, timeout_ts,
sigmask);
diff --git a/user/iplib/readipifc.c b/user/iplib/readipifc.c
index 606fd32..bd0b785 100644
--- a/user/iplib/readipifc.c
+++ b/user/iplib/readipifc.c
@@ -221,7 +221,8 @@
continue;
if (strcmp(de->d_name, "stats") == 0)
continue;
- snprintf(buf, sizeof(buf), "%s/%s/status", directory, de->d_name);
+ snprintf(buf, sizeof(buf), "%s/%s/status", directory,
+ de->d_name);
l = _readipifc(buf, l, atoi(de->d_name));
}
closedir(d);
diff --git a/user/iplib/select.c b/user/iplib/select.c
index 322d91a..2584116 100644
--- a/user/iplib/select.c
+++ b/user/iplib/select.c
@@ -80,12 +80,12 @@
static void select_fd_closed(int fd)
{
- /* Slightly racy, but anything concurrently added will be closed later, and
- * after it is_set. */
+ /* Slightly racy, but anything concurrently added will be closed later,
+ * and after it is_set. */
if (!fd_is_set(fd, &all_fds))
return;
- /* We just need to stop tracking FD. We do not need to remove it from the
- * epoll set, since that will happen automatically on close(). */
+ /* We just need to stop tracking FD. We do not need to remove it from
+ * the epoll set, since that will happen automatically on close(). */
uth_mutex_lock(epoll_mtx);
FD_CLR(fd, &all_fds);
uth_mutex_unlock(epoll_mtx);
@@ -98,11 +98,13 @@
uth_mutex_lock(epoll_mtx);
for (int i = 0; i < FD_SETSIZE; i++) {
if (fd_is_set(i, &all_fds)) {
- ep_ev.events = EPOLLET | EPOLLIN | EPOLLOUT | EPOLLHUP | EPOLLERR;
+ ep_ev.events = EPOLLET | EPOLLIN | EPOLLOUT | EPOLLHUP |
+ EPOLLERR;
ep_ev.data.fd = i;
- /* Discard error. The underlying tap is gone, and the epoll ctlr
- * might also have been emptied. We just want to make sure there is
- * no epoll/tap so that a future CTL_ADD doesn't fail. */
+ /* Discard error. The underlying tap is gone, and the
+ * epoll ctlr might also have been emptied. We just
+ * want to make sure there is no epoll/tap so that a
+ * future CTL_ADD doesn't fail. */
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, i, &ep_ev);
FD_CLR(i, &all_fds);
}
@@ -148,8 +150,8 @@
struct stat stat_buf;
int ret;
- /* Avoid the stat call on FDs we're not tracking (which should trigger an
- * error, or give us the stat for FD 0). */
+ /* Avoid the stat call on FDs we're not tracking (which should trigger
+ * an error, or give us the stat for FD 0). */
if (!(fd_is_set(fd, readfds) || fd_is_set(fd, writefds)))
return 0;
ret = fstat(fd, &stat_buf);
@@ -215,44 +217,49 @@
!fd_is_set(i, &all_fds)) {
FD_SET(i, &all_fds);
- /* FDs that we track for *any* reason with select will be
- * tracked for *all* reasons with epoll. */
- ep_ev.events = EPOLLET | EPOLLIN | EPOLLOUT | EPOLLHUP | EPOLLERR;
+ /* FDs that we track for *any* reason with select will
+ * be tracked for *all* reasons with epoll. */
+ ep_ev.events = EPOLLET | EPOLLIN | EPOLLOUT | EPOLLHUP |
+ EPOLLERR;
ep_ev.data.fd = i;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, i, &ep_ev)) {
- /* We might have failed because we tried to set up too many
- * FD tap types. Listen FDs, for instance, can only be
- * tapped for READABLE and HANGUP. Let's try for one of
- * those. */
+ /* We might have failed because we tried to set
+ * up too many FD tap types. Listen FDs, for
+ * instance, can only be tapped for READABLE and
+ * HANGUP. Let's try for one of those. */
if (errno == ENOSYS) {
- ep_ev.events = EPOLLET | EPOLLIN | EPOLLHUP;
- if (!epoll_ctl(epoll_fd, EPOLL_CTL_ADD, i, &ep_ev))
+ ep_ev.events = EPOLLET | EPOLLIN |
+ EPOLLHUP;
+ if (!epoll_ctl(epoll_fd, EPOLL_CTL_ADD,
+ i, &ep_ev))
continue;
}
- /* Careful to unlock before calling perror. perror calls
- * close, which calls our CB, which grabs the lock. */
+ /* Careful to unlock before calling perror.
+ * perror calls close, which calls our CB, which
+ * grabs the lock. */
uth_mutex_unlock(epoll_mtx);
perror("select epoll_ctl failed");
return -1;
}
}
}
- /* Since we just added some FDs to our tracking set, we don't know if they
- * are readable or not. We'll only catch edge-triggered changes in the
- * future.
+ /* Since we just added some FDs to our tracking set, we don't know if
+ * they are readable or not. We'll only catch edge-triggered changes in
+ * the future.
*
* Similarly, it is legal to select on a readable FD even if you didn't
* consume all of the data yet; similarly for writers on non-full FDs.
*
- * Additionally, since there is a global epoll set, we could have multiple
- * threads epolling concurrently and one thread could consume the events
- * that should wake another thread. Also, keep in mind we could also have a
- * single thread that selects multiple times on separate FD sets.
+ * Additionally, since there is a global epoll set, we could have
+ * multiple threads epolling concurrently and one thread could consume
+ * the events that should wake another thread. Also, keep in mind we
+ * could also have a single thread that selects multiple times on
+ * separate FD sets.
*
* Due to any of these cases, we need to check every FD this select call
* cares about (i.e. in an fd_set) to see if it is actionable. We do it
- * while holding the mutex to prevent other threads from consuming our epoll
- * events. */
+ * while holding the mutex to prevent other threads from consuming our
+ * epoll events. */
ret = 0;
FD_ZERO(&working_read_fds);
FD_ZERO(&working_write_fds);
@@ -277,16 +284,19 @@
return -1;
}
ep_ret = epoll_wait(epoll_fd, ep_results, FD_SETSIZE, ep_timeout);
- /* We need to hold the mtx during all of this processing since we're using
- * the global working_ fds sets. We can't modify the
+ /* We need to hold the mtx during all of this processing since we're
+ * using the global working_ fds sets. We can't modify the
* readfds/writefds/exceptfds until we're sure we are done. */
ret = 0;
- /* Note that ret can be > ep_ret. An FD that is both readable and writable
- * counts as one event for epoll, but as two bits for select. */
+ /* Note that ret can be > ep_ret. An FD that is both readable and
+ * writable counts as one event for epoll, but as two bits for select.
+ * */
for (int i = 0; i < ep_ret; i++) {
- ret += extract_bits_for_events(&ep_results[i], EPOLLIN | EPOLLHUP,
+ ret += extract_bits_for_events(&ep_results[i],
+ EPOLLIN | EPOLLHUP,
readfds, &working_read_fds);
- ret += extract_bits_for_events(&ep_results[i], EPOLLOUT | EPOLLHUP,
+ ret += extract_bits_for_events(&ep_results[i],
+ EPOLLOUT | EPOLLHUP,
writefds, &working_write_fds);
ret += extract_bits_for_events(&ep_results[i], EPOLLERR,
exceptfds, &working_except_fds);
@@ -305,11 +315,11 @@
* (POSIX). */
if (ret)
return ret;
- /* If we have no rets at this point, there are a few options: we could have
- * timed out (if requested), or we could have consumed someone else's event.
- * No one could have consumed our event, since we were the only epoller
- * (while holding the mtx). In the latter case, we'll need to try again,
- * but with an updated timeout. */
+ /* If we have no rets at this point, there are a few options: we could
+ * have timed out (if requested), or we could have consumed someone
+ * else's event. No one could have consumed our event, since we were
+ * the only epoller (while holding the mtx). In the latter case, we'll
+ * need to try again, but with an updated timeout. */
if (timeout) {
gettimeofday(end_tv, NULL);
timersub(end_tv, start_tv, end_tv); /* diff in end_tv */
diff --git a/user/ndblib/dnsquery.c b/user/ndblib/dnsquery.c
index fb93573..78b4621 100755
--- a/user/ndblib/dnsquery.c
+++ b/user/ndblib/dnsquery.c
@@ -156,8 +156,9 @@
n = read(fd, buf, sizeof(buf)-2);
if(n <= 0)
break;
+ /* ndbparsline needs a trailing new line */
if(buf[n-1] != '\n')
- buf[n++] = '\n'; /* ndbparsline needs a trailing new line */
+ buf[n++] = '\n';
buf[n] = 0;
/* check for the error condition */
diff --git a/user/ndblib/include/ndblib/ndb.h b/user/ndblib/include/ndblib/ndb.h
index 4c9ba5d..ef8632f 100644
--- a/user/ndblib/include/ndblib/ndb.h
+++ b/user/ndblib/include/ndblib/ndb.h
@@ -25,19 +25,19 @@
*/
struct ndb
{
- struct ndb *next;
+ struct ndb *next;
- FILE *b; /* buffered input file */
+ FILE *b; /* buffered input file */
uint8_t buf[256]; /* and its buffer */
- uint32_t mtime; /* mtime of db file */
- struct qid qid; /* qid of db file */
- char file[128];/* path name of db file */
- uint32_t length; /* length of db file */
- int isopen; /* true if the file is open */
+ uint32_t mtime; /* mtime of db file */
+ struct qid qid; /* qid of db file */
+ char file[128]; /* path name of db file */
+ uint32_t length; /* length of db file */
+ int isopen; /* true if the file is open */
int nohash; /* don't look for hash files */
- struct ndbhf *hf; /* open hash files */
+ struct ndbhf *hf; /* open hash files */
int ncache; /* size of tuple cache */
struct ndbcache *cache; /* cached entries */
@@ -48,12 +48,12 @@
*/
struct ndbtuple
{
- char attr[Ndbalen]; /* attribute name */
- char *val; /* value(s) */
- struct ndbtuple *entry; /* next tuple in this entry */
- struct ndbtuple *line; /* next tuple on this line */
- uint32_t ptr; /* (for the application - starts 0) */
- char valbuf[Ndbvlen]; /* initial allocation for value */
+ char attr[Ndbalen]; /* attribute name */
+ char *val; /* value(s) */
+ struct ndbtuple *entry; /* next tuple in this entry */
+ struct ndbtuple *line; /* next tuple on this line */
+ uint32_t ptr; /* (for the application - starts 0) */
+ char valbuf[Ndbvlen];/* initial allocation for value */
};
/*
@@ -99,7 +99,7 @@
{
struct ndb *db; /* data base file being searched */
struct ndbhf *hf; /* hash file being searched */
- int type;
+ int type;
uint32_t ptr; /* current pointer */
uint32_t ptr1; /* next pointer */
struct ndbtuple *t; /* last attribute value pair found */
@@ -110,7 +110,7 @@
struct ndbcache *next;
char *attr;
char *val;
- struct ndbs s;
+ struct ndbs s;
struct ndbtuple *t;
};
@@ -135,41 +135,40 @@
#define NDB_IPlen 16
-struct ndbtuple* csgetval(char*, char*, char*, char*, char*);
-char* csgetvalue(char*, char*, char*, char*, struct ndbtuple**);
-struct ndbtuple* csipinfo(char*, char*, char*, char**, int);
-struct ndbtuple* dnsquery(char*, char*, char*);
-char* ipattr(char*);
-struct ndb* ndbcat(struct ndb*, struct ndb*);
-int ndbchanged(struct ndb*);
-void ndbclose(struct ndb*);
-struct ndbtuple* ndbconcatenate(struct ndbtuple*, struct ndbtuple*);
-struct ndbtuple* ndbdiscard(struct ndbtuple*, struct ndbtuple*);
-void ndbfree(struct ndbtuple*);
-struct ndbtuple* ndbgetipaddr(struct ndb*, char*);
-struct ndbtuple* ndbgetval(struct ndb*,
- struct ndbs*, char*, char*, char*, char*);
-char* ndbgetvalue(struct ndb*, struct ndbs*, char*, char*, char*,
- struct ndbtuple**);
-struct ndbtuple* ndbfindattr(struct ndbtuple*, struct ndbtuple*, char*);
-uint32_t ndbhash(char*, int);
-struct ndbtuple* ndbipinfo(struct ndb*, char*, char*, char**, int);
-struct ndbtuple* ndblookval(struct ndbtuple*,
- struct ndbtuple*, char*, char*);
-struct ndbtuple* ndbnew(char*, char*);
-struct ndb* ndbopen(char*);
-struct ndbtuple* ndbparse(struct ndb*);
-int ndbreopen(struct ndb*);
-struct ndbtuple* ndbreorder(struct ndbtuple*, struct ndbtuple*);
-struct ndbtuple* ndbsearch(struct ndb*, struct ndbs*, char*, char*);
-void ndbsetval(struct ndbtuple*, char*, int);
-struct ndbtuple* ndbsnext(struct ndbs*, char*, char*);
-struct ndbtuple* ndbsubstitute(struct ndbtuple*, struct ndbtuple*,
- struct ndbtuple*);
-char*_ndbparsetuple(char *cp, struct ndbtuple **tp);
-struct ndbtuple*_ndbparseline(char *cp);
-//void ndbsetmalloctag(struct ndbtuple*, uintptr_t);
-static inline void ndbsetmalloctag(struct ndbtuple*t, uintptr_t v){}
+struct ndbtuple *csgetval(char*, char*, char*, char*, char*);
+char *csgetvalue(char*, char*, char*, char*, struct ndbtuple**);
+struct ndbtuple *csipinfo(char*, char*, char*, char**, int);
+struct ndbtuple *dnsquery(char*, char*, char*);
+char *ipattr(char*);
+struct ndb *ndbcat(struct ndb*, struct ndb*);
+int ndbchanged(struct ndb*);
+void ndbclose(struct ndb*);
+struct ndbtuple *ndbconcatenate(struct ndbtuple*, struct ndbtuple*);
+struct ndbtuple *ndbdiscard(struct ndbtuple*, struct ndbtuple*);
+void ndbfree(struct ndbtuple*);
+struct ndbtuple *ndbgetipaddr(struct ndb*, char*);
+struct ndbtuple *ndbgetval(struct ndb*, struct ndbs*, char*, char*, char*,
+ char*);
+char *ndbgetvalue(struct ndb*, struct ndbs*, char*, char*, char*,
+ struct ndbtuple**);
+struct ndbtuple *ndbfindattr(struct ndbtuple*, struct ndbtuple*, char*);
+uint32_t ndbhash(char*, int);
+struct ndbtuple *ndbipinfo(struct ndb*, char*, char*, char**, int);
+struct ndbtuple *ndblookval(struct ndbtuple*, struct ndbtuple*, char*, char*);
+struct ndbtuple *ndbnew(char*, char*);
+struct ndb *ndbopen(char*);
+struct ndbtuple *ndbparse(struct ndb*);
+int ndbreopen(struct ndb*);
+struct ndbtuple *ndbreorder(struct ndbtuple*, struct ndbtuple*);
+struct ndbtuple *ndbsearch(struct ndb*, struct ndbs*, char*, char*);
+void ndbsetval(struct ndbtuple*, char*, int);
+struct ndbtuple *ndbsnext(struct ndbs*, char*, char*);
+struct ndbtuple *ndbsubstitute(struct ndbtuple*, struct ndbtuple*,
+ struct ndbtuple*);
+char *_ndbparsetuple(char *cp, struct ndbtuple **tp);
+struct ndbtuple *_ndbparseline(char *cp);
+//void ndbsetmalloctag(struct ndbtuple*, uintptr_t);
+static inline void ndbsetmalloctag(struct ndbtuple*t, uintptr_t v){}
static inline uintptr_t getcallerpc(void *v){return 0;}
static inline void setmalloctag(void *v){}
diff --git a/user/ndblib/include/ndblib/ndbhf.h b/user/ndblib/include/ndblib/ndbhf.h
index ee56cad..241536b 100644
--- a/user/ndblib/include/ndblib/ndbhf.h
+++ b/user/ndblib/include/ndblib/ndbhf.h
@@ -16,18 +16,18 @@
{
struct ndbhf *next;
- int fd;
+ int fd;
uint32_t dbmtime; /* mtime of data base */
- int hlen; /* length (in entries) of hash table */
- char attr[Ndbalen]; /* attribute hashed */
+ int hlen; /* length (in entries) of hash table */
+ char attr[Ndbalen]; /* attribute hashed */
- uint8_t buf[256]; /* hash file buffer */
- long off; /* offset of first byte of buffer */
- int len; /* length of valid data in buffer */
+ uint8_t buf[256]; /* hash file buffer */
+ long off; /* offset of first byte of buffer */
+ int len; /* length of valid data in buffer */
};
-char* _ndbparsetuple(char*, struct ndbtuple**);
-struct ndbtuple* _ndbparseline(char*);
+char *_ndbparsetuple(char*, struct ndbtuple**);
+struct ndbtuple *_ndbparseline(char*);
#define ISWHITE(x) ((x) == ' ' || (x) == '\t' || (x) == '\r')
#define EATWHITE(x) while(ISWHITE(*(x)))(x)++
@@ -35,10 +35,10 @@
extern struct ndbtuple *_ndbtfree;
/* caches */
-void _ndbcacheflush(struct ndb *db);
-int _ndbcachesearch(struct ndb *db, struct ndbs *s, char *attr, char *val,
+void _ndbcacheflush(struct ndb *db);
+int _ndbcachesearch(struct ndb *db, struct ndbs *s, char *attr, char *val,
struct ndbtuple **t);
-struct ndbtuple* _ndbcacheadd(struct ndb *db, struct ndbs *s, char *attr, char *val,
- struct ndbtuple *t);
+struct ndbtuple* _ndbcacheadd(struct ndb *db, struct ndbs *s, char *attr,
+ char *val, struct ndbtuple *t);
__END_DECLS
diff --git a/user/ndblib/ndbcat.c b/user/ndblib/ndbcat.c
index 7122a90..105dbff 100755
--- a/user/ndblib/ndbcat.c
+++ b/user/ndblib/ndbcat.c
@@ -16,14 +16,13 @@
#include <iplib/iplib.h>
#include <ndblib/ndb.h>
-struct ndb*
-ndbcat(struct ndb *a, struct ndb *b)
+struct ndb *ndbcat(struct ndb *a, struct ndb *b)
{
struct ndb *db = a;
- if(a == NULL)
+ if (a == NULL)
return b;
- while(a->next != NULL)
+ while (a->next != NULL)
a = a->next;
a->next = b;
return db;
diff --git a/user/ndblib/ndbfree.c b/user/ndblib/ndbfree.c
index 41cf017..3ae7008 100755
--- a/user/ndblib/ndbfree.c
+++ b/user/ndblib/ndbfree.c
@@ -19,8 +19,7 @@
/*
* free a parsed entry
*/
-void
-ndbfree(struct ndbtuple *t)
+void ndbfree(struct ndbtuple *t)
{
struct ndbtuple *tn;
@@ -36,8 +35,7 @@
/*
* set a value in a tuple
*/
-void
-ndbsetval(struct ndbtuple *t, char *val, int n)
+void ndbsetval(struct ndbtuple *t, char *val, int n)
{
if(n < Ndbvlen){
if(t->val != t->valbuf){
@@ -61,8 +59,7 @@
/*
* allocate a tuple
*/
-struct ndbtuple*
-ndbnew(char *attr, char *val)
+struct ndbtuple *ndbnew(char *attr, char *val)
{
struct ndbtuple *t;
diff --git a/user/ndblib/ndbgetipaddr.c b/user/ndblib/ndbgetipaddr.c
index 1959b4e..8c45e05 100755
--- a/user/ndblib/ndbgetipaddr.c
+++ b/user/ndblib/ndbgetipaddr.c
@@ -17,8 +17,7 @@
#include <ndblib/ndb.h>
/* return list of ip addresses for a name */
-struct ndbtuple*
-ndbgetipaddr(struct ndb *db, char *val)
+struct ndbtuple *ndbgetipaddr(struct ndb *db, char *val)
{
char *attr, *p;
struct ndbtuple *it, *first, *last, *next;
diff --git a/user/ndblib/ndbipinfo.c b/user/ndblib/ndbipinfo.c
index b40c1fc..262a0e5 100755
--- a/user/ndblib/ndbipinfo.c
+++ b/user/ndblib/ndbipinfo.c
@@ -48,8 +48,8 @@
first = t;
last = t;
p = *argv++;
- if(*p == '@'){ /* @attr=val ? */
- t->ptr |= Faddr; /* return resolved address(es) */
+ if (*p == '@'){ /* @attr=val ? */
+ t->ptr |= Faddr;/* return resolved address(es) */
p++;
}
strncpy(t->attr, p, sizeof(t->attr)-1);
@@ -94,15 +94,19 @@
/* look through filter */
for(nf = f; nf != NULL; nf = nf->entry){
- if(!(nf->ptr&Fignore) && strcmp(nt->attr, nf->attr) == 0)
+ if (!(nf->ptr&Fignore) && strcmp(nt->attr, nf->attr) ==
+ 0)
break;
}
if(nf == NULL){
/* remove nt from t */
t = ndbdiscard(t, nt);
} else {
- if(nf->ptr & Faddr)
- t = ndbsubstitute(t, nt, setattr(ndbgetipaddr(db, nt->val), nt->attr));
+ if (nf->ptr & Faddr)
+ t = ndbsubstitute(t, nt,
+ setattr(ndbgetipaddr(db,
+ nt->val),
+ nt->attr));
nf->ptr |= Ffound;
}
}
diff --git a/user/parlib/alarm.c b/user/parlib/alarm.c
index 36948a3..cf678a1 100644
--- a/user/parlib/alarm.c
+++ b/user/parlib/alarm.c
@@ -129,9 +129,10 @@
tchain->earliest_time = ALARM_POISON_TIME;
tchain->latest_time = ALARM_POISON_TIME;
} else {
- tchain->earliest_time = TAILQ_FIRST(&tchain->waiters)->wake_up_time;
+ tchain->earliest_time =
+ TAILQ_FIRST(&tchain->waiters)->wake_up_time;
tchain->latest_time =
- TAILQ_LAST(&tchain->waiters, awaiters_tailq)->wake_up_time;
+ TAILQ_LAST(&tchain->waiters, awaiters_tailq)->wake_up_time;
}
}
@@ -139,7 +140,8 @@
{
close(global_tchain.ctlfd);
close(global_tchain.timerfd);
- if (devalarm_get_fds(&global_tchain.ctlfd, &global_tchain.timerfd, NULL))
+ if (devalarm_get_fds(&global_tchain.ctlfd, &global_tchain.timerfd,
+ NULL))
perror("Useralarm on fork");
}
@@ -161,8 +163,8 @@
perror("Useralarm: devalarm_get_fds");
return;
}
- /* Since we're doing SPAM_PUBLIC later, we actually don't need a big ev_q.
- * But someone might copy/paste this and change a flag. */
+ /* Since we're doing SPAM_PUBLIC later, we actually don't need a big
+ * ev_q. But someone might copy/paste this and change a flag. */
register_ev_handler(EV_ALARM, handle_user_alarm, 0);
if (!(ev_q = get_eventq(EV_MBOX_UCQ))) {
perror("Useralarm: Failed ev_q");
@@ -170,15 +172,16 @@
}
ev_q->ev_vcore = 0;
/* We could get multiple events for a single alarm. It's okay, since
- * __trigger can handle spurious upcalls. If it ever is not okay, then use
- * an INDIR (probably with SPAM_INDIR too) instead of SPAM_PUBLIC. */
+ * __trigger can handle spurious upcalls. If it ever is not okay, then
+ * use an INDIR (probably with SPAM_INDIR too) instead of SPAM_PUBLIC.
+ */
ev_q->ev_flags = EVENT_IPI | EVENT_SPAM_PUBLIC | EVENT_WAKEUP;
if (devalarm_set_evq(timerfd, ev_q, alarmid)) {
perror("set_alarm_evq");
return;
}
- /* now the alarm is all set, just need to write the timer whenever we want
- * it to go off. */
+ /* now the alarm is all set, just need to write the timer whenever we
+ * want it to go off. */
global_tchain.alarmid = alarmid;
global_tchain.ctlfd = ctlfd;
global_tchain.timerfd = timerfd;
@@ -215,10 +218,11 @@
void set_awaiter_rel(struct alarm_waiter *waiter, uint64_t usleep)
{
uint64_t now, then;
+
now = read_tsc();
then = now + usec2tsc(usleep);
- /* This will go off if we wrap-around the TSC. It'll never happen for legit
- * values, but this might catch some bugs with large usleeps. */
+ /* This will go off if we wrap-around the TSC. It'll never happen for
+ * legit values, but this might catch some bugs with large usleeps. */
assert(now <= then);
__set_awaiter_abs(waiter, then);
}
@@ -348,25 +352,26 @@
/* Need to turn on the timer interrupt later */
return TRUE;
}
- /* If not, either we're first, last, or in the middle. Reset the interrupt
- * and adjust the tchain's times accordingly. */
+ /* If not, either we're first, last, or in the middle. Reset the
+ * interrupt and adjust the tchain's times accordingly. */
if (waiter->wake_up_time < tchain->earliest_time) {
tchain->earliest_time = waiter->wake_up_time;
TAILQ_INSERT_HEAD(&tchain->waiters, waiter, next);
- /* Changed the first entry; we'll need to reset the interrupt later */
+ /* Changed the first entry; we'll need to reset the interrupt
+ * later */
return TRUE;
}
- /* If there is a tie for last, the newer one will really go last. We need
- * to handle equality here since the loop later won't catch it. */
+ /* If there is a tie for last, the newer one will really go last. We
+ * need to handle equality here since the loop later won't catch it. */
if (waiter->wake_up_time >= tchain->latest_time) {
tchain->latest_time = waiter->wake_up_time;
/* Proactively put it at the end if we know we're last */
TAILQ_INSERT_TAIL(&tchain->waiters, waiter, next);
return FALSE;
}
- /* Insert before the first one you are earlier than. This won't scale well
- * (TODO) if we have a lot of inserts. The proactive insert_tail up above
- * will help a bit. */
+ /* Insert before the first one you are earlier than. This won't scale
+ * well (TODO) if we have a lot of inserts. The proactive insert_tail
+ * up above will help a bit. */
TAILQ_FOREACH_SAFE(i, &tchain->waiters, next, temp) {
if (waiter->wake_up_time < i->wake_up_time) {
TAILQ_INSERT_BEFORE(i, waiter, next);
@@ -395,18 +400,20 @@
struct alarm_waiter *waiter)
{
struct alarm_waiter *temp;
- bool reset_int = FALSE; /* whether or not to reset the interrupt */
+ bool reset_int = FALSE; /* whether or not to reset the interrupt */
- /* Need to make sure earliest and latest are set, in case we're mucking with
- * the first and/or last element of the chain. */
+ /* Need to make sure earliest and latest are set, in case we're mucking
+ * with the first and/or last element of the chain. */
if (TAILQ_FIRST(&tchain->waiters) == waiter) {
temp = TAILQ_NEXT(waiter, next);
- tchain->earliest_time = (temp) ? temp->wake_up_time : ALARM_POISON_TIME;
- reset_int = TRUE; /* we'll need to reset the timer later */
+ tchain->earliest_time = (temp) ? temp->wake_up_time :
+ ALARM_POISON_TIME;
+ reset_int = TRUE; /* we'll need to reset the timer later */
}
if (TAILQ_LAST(&tchain->waiters, awaiters_tailq) == waiter) {
temp = TAILQ_PREV(waiter, awaiters_tailq, next);
- tchain->latest_time = (temp) ? temp->wake_up_time : ALARM_POISON_TIME;
+ tchain->latest_time = (temp) ? temp->wake_up_time :
+ ALARM_POISON_TIME;
}
TAILQ_REMOVE(&tchain->waiters, waiter, next);
waiter->on_tchain = FALSE;
@@ -480,15 +487,17 @@
if (uth->sysc && sys_abort_sysc(uth->sysc))
return;
/* There are a bunch of reasons why we didn't abort the syscall. The
- * syscall might not have been issued or blocked at all, so uth->sysc would
- * be NULL. The syscall might have blocked, but at a non-abortable location
- * - picture blocking on a qlock, then unblocking and blocking later on a
- * rendez. If you try to abort in between, abort_sysc will fail, then we'll
- * get blocked on the rendez until the next abort. Finally, the syscall
- * might have completed, but the uthread hasn't cancelled the alarm yet.
+ * syscall might not have been issued or blocked at all, so uth->sysc
+ * would be NULL. The syscall might have blocked, but at a
+ * non-abortable location
+ * - picture blocking on a qlock, then unblocking and blocking later on
+ * a rendez. If you try to abort in between, abort_sysc will fail,
+ * then we'll get blocked on the rendez until the next abort.
+ * Finally, the syscall might have completed, but the uthread hasn't
+ * cancelled the alarm yet.
*
- * It's always safe to rearm the alarm - the uthread will unset it and break
- * us out of the rearm loop. */
+ * It's always safe to rearm the alarm - the uthread will unset it and
+ * break us out of the rearm loop. */
set_awaiter_rel(awaiter, 10000);
set_alarm(awaiter);
}
diff --git a/user/parlib/asynccall.c b/user/parlib/asynccall.c
index f9c18bd..579907e 100644
--- a/user/parlib/asynccall.c
+++ b/user/parlib/asynccall.c
@@ -28,7 +28,8 @@
FRONT_RING_INIT(&ac->sysfr, ac->ring_page, SYSCALLRINGSIZE);
//BACK_RING_INIT(&syseventbackring, &(__procdata.syseventring), SYSEVENTRINGSIZE);
- //TODO: eventually rethink about desc pools, they are here but no longer necessary
+ //TODO: eventually rethink about desc pools, they are here but no longer
+ //necessary
POOL_INIT(&syscall_desc_pool, MAX_SYSCALLS);
POOL_INIT(&async_desc_pool, MAX_ASYNCCALLS);
}
@@ -48,11 +49,12 @@
while (!(TAILQ_EMPTY(&desc->syslist))) {
d = TAILQ_FIRST(&desc->syslist);
err = waiton_syscall(d);
- // TODO: processing the retval out of rsp here. might be specific to
- // the async call. do we want to accumulate? return any negative
- // values? depends what we want from the return value, so we might
- // have to pass in a function that is used to do the processing and
- // pass the answer back out in rsp.
+ // TODO: processing the retval out of rsp here. might be
+ // specific to the async call. do we want to accumulate?
+ // return any negative values? depends what we want from the
+ // return value, so we might have to pass in a function that is
+ // used to do the processing and pass the answer back out in
+ // rsp.
//rsp->retval += syscall_rsp.retval; // For example
retval = MIN(retval, err);
// remove from the list and free the syscall desc
@@ -117,17 +119,20 @@
// TODO: right now there is one channel (remote), in the future, the caller
// may specify local which will cause it to give up the core to do the work.
// creation of additional remote channel also allows the caller to prioritize
-// work, because the default policy for the kernel is to roundrobin between them.
+// work, because the default policy for the kernel is to roundrobin between
+// them.
int async_syscall(arsc_channel_t* chan, syscall_req_t* req, syscall_desc_t** desc_ptr2)
{
// Note that this assumes one global frontring (TODO)
- // abort if there is no room for our request. ring size is currently 64.
- // we could spin til it's free, but that could deadlock if this same thread
- // is supposed to consume the requests it is waiting on later.
+ // abort if there is no room for our request. ring size is currently
+ // 64. we could spin til it's free, but that could deadlock if this
+ // same thread is supposed to consume the requests it is waiting on
+ // later.
syscall_desc_t* desc = malloc(sizeof (syscall_desc_t));
desc->channel = chan;
syscall_front_ring_t *fr = &(desc->channel->sysfr);
- //TODO: can do it locklessly using CAS, but could change with local async calls
+ //TODO: can do it locklessly using CAS, but could change with local
+ //async calls
struct mcs_lock_qnode local_qn = {0};
mcs_lock_lock(&(chan->aclock), &local_qn);
if (RING_FULL(fr)) {
@@ -145,8 +150,9 @@
memcpy(r, req, sizeof(syscall_req_t));
r->status = REQ_ready;
// push our updates to syscallfrontring.req_prod_pvt
- // note: it is ok to push without protection since it is atomic and kernel
- // won't process any requests until they are marked REQ_ready (also atomic)
+ // note: it is ok to push without protection since it is atomic and
+ // kernel won't process any requests until they are marked REQ_ready
+ // (also atomic)
RING_PUSH_REQUESTS(fr);
//cprintf("DEBUG: sring->req_prod: %d, sring->rsp_prod: %d\n",
mcs_lock_unlock(&desc->channel->aclock, &local_qn);
@@ -192,7 +198,8 @@
return -1;
}
// Make sure we were given a desc with a non-NULL frontring. This could
- // happen if someone forgot to check the error code on the paired syscall.
+ // happen if someone forgot to check the error code on the paired
+ // syscall.
syscall_front_ring_t *fr = &desc->channel->sysfr;
if (!fr){
@@ -207,9 +214,9 @@
cpu_relax();
// memcpy(rsp, rsp_inring, sizeof(*rsp));
- // run a cleanup function for this desc, if available
- if (rsp->cleanup)
- rsp->cleanup(rsp->data);
+ // run a cleanup function for this desc, if available
+ if (rsp->cleanup)
+ rsp->cleanup(rsp->data);
if (RSP_ERRNO(rsp)){
errno = RSP_ERRNO(rsp);
retval = -1;
diff --git a/user/parlib/ceq.c b/user/parlib/ceq.c
index 610ac76..cdc9d49 100644
--- a/user/parlib/ceq.c
+++ b/user/parlib/ceq.c
@@ -33,9 +33,9 @@
void ceq_init(struct ceq *ceq, uint8_t op, unsigned int nr_events,
size_t ring_sz)
{
- /* In case they already had an mbox initialized, cleanup whatever was there
- * so we don't leak memory. They better not have asked for events before
- * doing this init call... */
+ /* In case they already had an mbox initialized, cleanup whatever was
+ * there so we don't leak memory. They better not have asked for events
+ * before doing this init call... */
ceq_cleanup(ceq);
ceq->events = mmap(NULL, sizeof(struct ceq_event) * nr_events,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
@@ -52,7 +52,8 @@
atomic_init(&ceq->prod_idx, 0);
atomic_init(&ceq->cons_pub_idx, 0);
atomic_init(&ceq->cons_pvt_idx, 0);
- parlib_static_assert(sizeof(struct spin_pdr_lock) <= sizeof(ceq->u_lock));
+ parlib_static_assert(sizeof(struct spin_pdr_lock) <=
+ sizeof(ceq->u_lock));
spin_pdr_init((struct spin_pdr_lock*)&ceq->u_lock);
}
@@ -64,30 +65,31 @@
{
long pvt_idx, prod_idx;
int32_t ret;
+
do {
prod_idx = atomic_read(&ceq->prod_idx);
pvt_idx = atomic_read(&ceq->cons_pvt_idx);
if (__ring_empty(prod_idx, pvt_idx))
return -1;
} while (!atomic_cas(&ceq->cons_pvt_idx, pvt_idx, pvt_idx + 1));
- /* We claimed our slot, which is pvt_idx. The new cons_pvt_idx is advanced
- * by 1 for the next consumer. Now we need to wait on the kernel to fill
- * the value: */
+ /* We claimed our slot, which is pvt_idx. The new cons_pvt_idx is
+ * advanced by 1 for the next consumer. Now we need to wait on the
+ * kernel to fill the value: */
while ((ret = ceq->ring[pvt_idx & (ceq->ring_sz - 1)]) == -1)
cpu_relax();
/* Set the value back to -1 for the next time the slot is used */
ceq->ring[pvt_idx & (ceq->ring_sz - 1)] = -1;
- /* We now have our entry. We need to make sure the pub_idx is updated. All
- * consumers are doing this. We can just wait on all of them to update the
- * cons_pub to our location, then we update it to the next.
+ /* We now have our entry. We need to make sure the pub_idx is updated.
+ * All consumers are doing this. We can just wait on all of them to
+ * update the cons_pub to our location, then we update it to the next.
*
* We're waiting on other vcores, but we don't know which one(s). */
while (atomic_read(&ceq->cons_pub_idx) != pvt_idx)
cpu_relax_any();
- /* This is the only time we update cons_pub. We also know no one else is
- * updating it at this moment; the while loop acts as a lock, such that
- * no one gets to this point until pub == their pvt_idx, all of which are
- * unique. */
+ /* This is the only time we update cons_pub. We also know no one else
+ * is updating it at this moment; the while loop acts as a lock, such
+ * that no one gets to this point until pub == their pvt_idx, all of
+ * which are unique. */
/* No rwmb needed, it's the same variable (con_pub) */
atomic_set(&ceq->cons_pub_idx, pvt_idx + 1);
return ret;
@@ -105,19 +107,20 @@
static bool extract_ceq_msg(struct ceq *ceq, int32_t idx, struct event_msg *msg)
{
struct ceq_event *ceq_ev = &ceq->events[idx];
+
if (!ceq_ev->idx_posted)
return FALSE;
/* Once we clear this flag, any new coalesces will trigger another ring
- * event, so we don't need to worry about missing anything. It is possible
- * that this CEQ event will get those new coalesces as part of this message,
- * and future messages will have nothing. That's fine. */
+ * event, so we don't need to worry about missing anything. It is
+ * possible that this CEQ event will get those new coalesces as part of
+ * this message, and future messages will have nothing. That's fine. */
ceq_ev->idx_posted = FALSE;
cmb(); /* order the read after the flag write. swap provides cpu_mb */
/* We extract the existing coals and reset the collection to 0; now the
* collected events are in our msg. */
msg->ev_arg2 = atomic_swap(&ceq_ev->coalesce, 0);
- /* if the user wants access to user_data, they can peak in the event array
- * via ceq->events[msg->ev_type].user_data. */
+ /* if the user wants access to user_data, they can peak in the event
+ * array via ceq->events[msg->ev_type].user_data. */
msg->ev_type = idx;
msg->ev_arg3 = (void*)ceq_ev->blob_data;
ceq_ev->blob_data = 0; /* racy, but there are no blob guarantees */
@@ -132,49 +135,57 @@
int32_t idx = get_ring_idx(ceq);
if (idx == -1) {
- /* We didn't get anything via the ring, but if we're overflowed, then we
- * need to look in the array directly. Note that we only handle
- * overflow when we failed to get something. Eventually, we'll deal
- * with overflow (which should be very rare). Also note that while we
- * are dealing with overflow, the kernel could be producing and using
- * the ring, and we could have consumers consuming from the ring.
+ /* We didn't get anything via the ring, but if we're overflowed,
+ * then we need to look in the array directly. Note that we
+ * only handle overflow when we failed to get something.
+ * Eventually, we'll deal with overflow (which should be very
+ * rare). Also note that while we are dealing with overflow,
+ * the kernel could be producing and using the ring, and we
+ * could have consumers consuming from the ring.
*
- * Overall, we need to clear the overflow flag, then check every event.
- * If we find an event, we need to make sure the *next* consumer
- * continues our recovery, hence the overflow_recovery field. We could
- * do the check for recovery immediately, but that adds complexity and
- * there's no stated guarantee of CEQ message ordering (you don't have
- * it with the ring, either, technically (consider a coalesce)). So
- * we're fine by having *a* consumer finish the recovery, but not
- * necesarily the *next* consumer. So long as no one thinks the CEQ is
- * empty when there actually are old messages, then we're okay. */
+ * Overall, we need to clear the overflow flag, then check every
+ * event. If we find an event, we need to make sure the *next*
+ * consumer continues our recovery, hence the overflow_recovery
+ * field. We could do the check for recovery immediately, but
+ * that adds complexity and there's no stated guarantee of CEQ
+ * message ordering (you don't have it with the ring, either,
+ * technically (consider a coalesce)). So we're fine by having
+ * *a* consumer finish the recovery, but not necesarily the
+ * *next* consumer. So long as no one thinks the CEQ is empty
+ * when there actually are old messages, then we're okay. */
if (!ceq->ring_overflowed && !ceq->overflow_recovery)
return FALSE;
spin_pdr_lock((struct spin_pdr_lock*)&ceq->u_lock);
if (!ceq->overflow_recovery) {
ceq->overflow_recovery = TRUE;
- wmb(); /* set recovery before clearing overflow */
+ /* set recovery before clearing overflow */
+ wmb();
ceq->ring_overflowed = FALSE;
ceq->last_recovered = 0;
- wrmb(); /* clear overflowed before reading event entries */
+ /* clear overflowed before reading event entries */
+ wrmb();
}
for (int i = ceq->last_recovered;
i <= atomic_read(&ceq->max_event_ever);
i++) {
- /* Regardles of whether there's a msg here, we checked it. */
+ /* Regardles of whether there's a msg here, we checked
+ * it. */
ceq->last_recovered++;
if (extract_ceq_msg(ceq, i, msg)) {
- /* We found something. There might be more, but a future
- * consumer will have to deal with it, or verify there isn't. */
- spin_pdr_unlock((struct spin_pdr_lock*)&ceq->u_lock);
+ /* We found something. There might be more, but
+ * a future consumer will have to deal with it,
+ * or verify there isn't. */
+ spin_pdr_unlock(
+ (struct spin_pdr_lock*)&ceq->u_lock);
return TRUE;
}
}
ceq->overflow_recovery = FALSE;
- /* made it to the end, looks like there was no overflow left. there
- * could be new ones added behind us (they'd be in the ring or overflow
- * would be turned on again), but those message were added after we
- * started consuming, and therefore not our obligation to extract. */
+ /* made it to the end, looks like there was no overflow left.
+ * there could be new ones added behind us (they'd be in the
+ * ring or overflow would be turned on again), but those message
+ * were added after we started consuming, and therefore not our
+ * obligation to extract. */
spin_pdr_unlock((struct spin_pdr_lock*)&ceq->u_lock);
return FALSE;
}
diff --git a/user/parlib/core_set.c b/user/parlib/core_set.c
index 8c41245..8cb32ea 100644
--- a/user/parlib/core_set.c
+++ b/user/parlib/core_set.c
@@ -92,15 +92,19 @@
exit(1);
}
if (fcpu >= parlib_nr_total_cores()) {
- fprintf(stderr, "CPU number out of bound: %u\n", fcpu);
+ fprintf(stderr, "CPU number out of bound: %u\n",
+ fcpu);
exit(1);
}
if (ncpu >= parlib_nr_total_cores()) {
- fprintf(stderr, "CPU number out of bound: %u\n", ncpu);
+ fprintf(stderr, "CPU number out of bound: %u\n",
+ ncpu);
exit(1);
}
if (fcpu > ncpu) {
- fprintf(stderr, "CPU range is backwards: %u-%u\n", fcpu, ncpu);
+ fprintf(stderr,
+ "CPU range is backwards: %u-%u\n",
+ fcpu, ncpu);
exit(1);
}
for (; fcpu <= ncpu; fcpu++)
@@ -109,7 +113,7 @@
fcpu = atoi(tok);
if (fcpu >= parlib_nr_total_cores()) {
fprintf(stderr, "CPU number out of bound: %u\n",
- fcpu);
+ fcpu);
exit(1);
}
parlib_set_core(cores, fcpu);
@@ -136,7 +140,8 @@
{
size_t max_cores = parlib_nr_total_cores();
- for (size_t i = 0; (max_cores > 0) && (i < sizeof(dcs->core_set)); i++) {
+ for (size_t i = 0; (max_cores > 0) && (i < sizeof(dcs->core_set)); i++)
+ {
size_t nb = (max_cores >= CHAR_BIT) ? CHAR_BIT : max_cores;
dcs->core_set[i] = (~dcs->core_set[i]) & ((1 << nb) - 1);
diff --git a/user/parlib/debug.c b/user/parlib/debug.c
index 08c79a3..e4d1a32 100644
--- a/user/parlib/debug.c
+++ b/user/parlib/debug.c
@@ -52,7 +52,8 @@
void toggle_print_func(void)
{
print = !print;
- printf("Func entry/exit printing is now %sabled\n", print ? "en" : "dis");
+ printf("Func entry/exit printing is now %sabled\n", print ? "en" :
+ "dis");
}
static spinlock_t lock = {0};
@@ -64,7 +65,7 @@
if (is_blacklisted(func))
return;
spinlock_lock(&lock);
- printd("Vcore %2d", vcore_id()); /* helps with multicore output */
+ printd("Vcore %2d", vcore_id()); /* helps with multicore output */
for (int i = 0; i < tab_depth; i++)
printf("\t");
printf("%s() in %s\n", func, file);
diff --git a/user/parlib/dtls.c b/user/parlib/dtls.c
index ea0e74c..e869105 100644
--- a/user/parlib/dtls.c
+++ b/user/parlib/dtls.c
@@ -71,12 +71,14 @@
/* Initialize the global cache of dtls_keys */
__dtls_keys_cache =
kmem_cache_create("dtls_keys_cache", sizeof(struct dtls_key),
- __alignof__(struct dtls_key), 0, NULL, NULL, NULL);
+ __alignof__(struct dtls_key), 0, NULL, NULL,
+ NULL);
/* Initialize the global cache of dtls_values */
__dtls_values_cache =
kmem_cache_create("dtls_values_cache", sizeof(struct dtls_value),
- __alignof__(struct dtls_value), 0, NULL, NULL, NULL);
+ __alignof__(struct dtls_value), 0, NULL, NULL,
+ NULL);
return 0;
}
@@ -185,15 +187,15 @@
v = TAILQ_FIRST(&dtls_data->list);
while (v != NULL) {
key = v->key;
- /* The dtor must be called outside of a spinlock so that it can call
- * code that may deschedule it for a while (i.e. a mutex). Probably a
- * good idea anyway since it can be arbitrarily long and is written by
- * the user. Note, there is a small race here on the valid field,
- * whereby we may run a destructor on an invalid key. At least the keys
- * memory wont be deleted though, as protected by the ref count. Any
- * reasonable usage of this interface should safeguard that a key is
- * never destroyed before all of the threads that use it have exited
- * anyway. */
+ /* The dtor must be called outside of a spinlock so that it can
+ * call code that may deschedule it for a while (i.e. a mutex).
+ * Probably a good idea anyway since it can be arbitrarily long
+ * and is written by the user. Note, there is a small race here
+ * on the valid field, whereby we may run a destructor on an
+ * invalid key. At least the keys memory wont be deleted though,
+ * as protected by the ref count. Any reasonable usage of this
+ * interface should safeguard that a key is never destroyed
+ * before all of the threads that use it have exited anyway. */
if (key->valid && key->dtor) {
dtls = v->dtls;
v->dtls = NULL;
@@ -201,9 +203,10 @@
}
n = TAILQ_NEXT(v, link);
TAILQ_REMOVE(&dtls_data->list, v, link);
- /* Free both the key (which is v->key) and v *after* removing v from the
- * list. It's possible that free() will call back into the DTLS (e.g.
- * pthread_getspecific()), and v must be off the list by then.
+ /* Free both the key (which is v->key) and v *after* removing v
+ * from the list. It's possible that free() will call back into
+ * the DTLS (e.g. pthread_getspecific()), and v must be off the
+ * list by then.
*
* For a similar, hilarious bug in glibc, check out:
* https://sourceware.org/bugzilla/show_bug.cgi?id=3317 */
diff --git a/user/parlib/evbitmap.c b/user/parlib/evbitmap.c
index 1affd39..69ea7b8 100644
--- a/user/parlib/evbitmap.c
+++ b/user/parlib/evbitmap.c
@@ -31,7 +31,7 @@
for (int i = 0; i < MAX_NR_EVENT; i++) {
if (GET_BITMASK_BIT(evbm->bitmap, i)) {
CLR_BITMASK_BIT_ATOMIC(evbm->bitmap, i);
- /* bit messages are empty except for the type. */
+ /* bit messages are empty except for the type */
memset(ev_msg, 0, sizeof(struct event_msg));
ev_msg->ev_type = i;
return TRUE;
@@ -39,7 +39,8 @@
}
/* If we made it here, then the bitmap might be empty. */
evbm->check_bits = FALSE;
- wrmb(); /* check_bits written before we check for it being clear */
+ /* check_bits written before we check for it being clear */
+ wrmb();
if (BITMASK_IS_CLEAR(evbm->bitmap, MAX_NR_EVENT))
return FALSE;
cmb();
diff --git a/user/parlib/event.c b/user/parlib/event.c
index bcc8e49..0655c07 100644
--- a/user/parlib/event.c
+++ b/user/parlib/event.c
@@ -67,18 +67,18 @@
{
ev_mbox->type = mbox_type;
switch (ev_mbox->type) {
- case (EV_MBOX_UCQ):
- ucq_init(&ev_mbox->ucq);
- break;
- case (EV_MBOX_BITMAP):
- evbitmap_init(&ev_mbox->evbm);
- break;
- case (EV_MBOX_CEQ):
- ceq_init(&ev_mbox->ceq, CEQ_OR, CEQ_DEFAULT_SZ, CEQ_DEFAULT_SZ);
- break;
- default:
- printf("Unknown mbox type %d!\n", ev_mbox->type);
- break;
+ case (EV_MBOX_UCQ):
+ ucq_init(&ev_mbox->ucq);
+ break;
+ case (EV_MBOX_BITMAP):
+ evbitmap_init(&ev_mbox->evbm);
+ break;
+ case (EV_MBOX_CEQ):
+ ceq_init(&ev_mbox->ceq, CEQ_OR, CEQ_DEFAULT_SZ, CEQ_DEFAULT_SZ);
+ break;
+ default:
+ printf("Unknown mbox type %d!\n", ev_mbox->type);
+ break;
}
}
@@ -86,9 +86,9 @@
* aren't in use (unregistered, etc). (TODO: consider some checks for this) */
void put_eventq_raw(struct event_queue *ev_q)
{
- /* if we use something other than malloc, we'll need to be aware that ev_q
- * is actually an event_queue_big. One option is to use the flags, though
- * this could be error prone. */
+ /* if we use something other than malloc, we'll need to be aware that
+ * ev_q is actually an event_queue_big. One option is to use the flags,
+ * though this could be error prone. */
free(ev_q);
}
@@ -101,18 +101,18 @@
void event_mbox_cleanup(struct event_mbox *ev_mbox)
{
switch (ev_mbox->type) {
- case (EV_MBOX_UCQ):
- ucq_free_pgs(&ev_mbox->ucq);
- break;
- case (EV_MBOX_BITMAP):
- evbitmap_cleanup(&ev_mbox->evbm);
- break;
- case (EV_MBOX_CEQ):
- ceq_cleanup(&ev_mbox->ceq);
- break;
- default:
- printf("Unknown mbox type %d!\n", ev_mbox->type);
- break;
+ case (EV_MBOX_UCQ):
+ ucq_free_pgs(&ev_mbox->ucq);
+ break;
+ case (EV_MBOX_BITMAP):
+ evbitmap_cleanup(&ev_mbox->evbm);
+ break;
+ case (EV_MBOX_CEQ):
+ ceq_cleanup(&ev_mbox->ceq);
+ break;
+ default:
+ printf("Unknown mbox type %d!\n", ev_mbox->type);
+ break;
}
}
@@ -140,8 +140,8 @@
void put_eventq_slim(struct event_queue *ev_q)
{
- /* if we use something other than malloc, we'll need to be aware that ev_q
- * is not an event_queue_big. */
+ /* if we use something other than malloc, we'll need to be aware that
+ * ev_q is not an event_queue_big. */
free(ev_q);
}
@@ -161,6 +161,7 @@
struct event_queue *clear_kevent_q(unsigned int ev_type)
{
struct event_queue *ev_q = __procdata.kernel_evts[ev_type];
+
__procdata.kernel_evts[ev_type] = 0;
return ev_q;
}
@@ -175,6 +176,7 @@
void enable_kevent(unsigned int ev_type, uint32_t vcoreid, int ev_flags)
{
struct event_queue *ev_q = get_eventq_vcpd(vcoreid, ev_flags);
+
ev_q->ev_flags = ev_flags;
ev_q->ev_vcore = vcoreid;
ev_q->ev_handler = 0;
@@ -215,19 +217,22 @@
bool register_evq(struct syscall *sysc, struct event_queue *ev_q)
{
int old_flags;
+
sysc->ev_q = ev_q;
wrmb(); /* don't let that write pass any future reads (flags) */
- /* Try and set the SC_UEVENT flag (so the kernel knows to look at ev_q) */
+ /* Try and set the SC_UEVENT flag (so the kernel knows to look at ev_q)
+ */
do {
/* no cmb() needed, the atomic_read will reread flags */
old_flags = atomic_read(&sysc->flags);
/* Spin if the kernel is mucking with syscall flags */
while (old_flags & SC_K_LOCK)
old_flags = atomic_read(&sysc->flags);
- /* If the kernel finishes while we are trying to sign up for an event,
- * we need to bail out */
+ /* If the kernel finishes while we are trying to sign up for an
+ * event, we need to bail out */
if (old_flags & (SC_DONE | SC_PROGRESS)) {
- sysc->ev_q = 0; /* not necessary, but might help with bugs */
+ /* not necessary, but might help with bugs */
+ sysc->ev_q = 0;
return FALSE;
}
} while (!atomic_cas(&sysc->flags, old_flags, old_flags | SC_UEVENT));
@@ -248,6 +253,7 @@
void deregister_evq(struct syscall *sysc)
{
int old_flags;
+
sysc->ev_q = 0;
wrmb(); /* don't let that write pass any future reads (flags) */
/* Try and unset the SC_UEVENT flag */
@@ -257,8 +263,8 @@
/* Spin if the kernel is mucking with syscall flags */
while (old_flags & SC_K_LOCK)
old_flags = atomic_read(&sysc->flags);
- /* Note we don't care if the SC_DONE flag is getting set. We just need
- * to avoid clobbering flags */
+ /* Note we don't care if the SC_DONE flag is getting set. We
+ * just need to avoid clobbering flags */
} while (!atomic_cas(&sysc->flags, old_flags, old_flags & ~SC_UEVENT));
}
@@ -298,6 +304,7 @@
static void run_ev_handlers(unsigned int ev_type, struct event_msg *ev_msg)
{
struct ev_handler *handler;
+
/* TODO: RCU read lock */
handler = ev_handlers[ev_type];
while (handler) {
@@ -311,15 +318,15 @@
bool extract_one_mbox_msg(struct event_mbox *ev_mbox, struct event_msg *ev_msg)
{
switch (ev_mbox->type) {
- case (EV_MBOX_UCQ):
- return get_ucq_msg(&ev_mbox->ucq, ev_msg);
- case (EV_MBOX_BITMAP):
- return get_evbitmap_msg(&ev_mbox->evbm, ev_msg);
- case (EV_MBOX_CEQ):
- return get_ceq_msg(&ev_mbox->ceq, ev_msg);
- default:
- printf("Unknown mbox type %d!\n", ev_mbox->type);
- return FALSE;
+ case (EV_MBOX_UCQ):
+ return get_ucq_msg(&ev_mbox->ucq, ev_msg);
+ case (EV_MBOX_BITMAP):
+ return get_evbitmap_msg(&ev_mbox->evbm, ev_msg);
+ case (EV_MBOX_CEQ):
+ return get_ceq_msg(&ev_mbox->ceq, ev_msg);
+ default:
+ printf("Unknown mbox type %d!\n", ev_mbox->type);
+ return FALSE;
}
}
@@ -328,6 +335,7 @@
{
struct event_msg local_msg;
unsigned int ev_type;
+
/* extract returns TRUE on success, we return 1. */
if (!extract_one_mbox_msg(ev_mbox, &local_msg))
return 0;
@@ -344,7 +352,8 @@
int handle_mbox(struct event_mbox *ev_mbox)
{
int retval = 0;
- printd("[event] handling ev_mbox %08p on vcore %d\n", ev_mbox, vcore_id());
+ printd("[event] handling ev_mbox %08p on vcore %d\n", ev_mbox,
+ vcore_id());
/* Some stack-smashing bugs cause this to fail */
assert(ev_mbox);
/* Handle all full messages, tracking if we do at least one. */
@@ -357,15 +366,15 @@
bool mbox_is_empty(struct event_mbox *ev_mbox)
{
switch (ev_mbox->type) {
- case (EV_MBOX_UCQ):
- return ucq_is_empty(&ev_mbox->ucq);
- case (EV_MBOX_BITMAP):
- return evbitmap_is_empty(&ev_mbox->evbm);
- case (EV_MBOX_CEQ):
- return ceq_is_empty(&ev_mbox->ceq);
- default:
- printf("Unknown mbox type %d!\n", ev_mbox->type);
- return FALSE;
+ case (EV_MBOX_UCQ):
+ return ucq_is_empty(&ev_mbox->ucq);
+ case (EV_MBOX_BITMAP):
+ return evbitmap_is_empty(&ev_mbox->evbm);
+ case (EV_MBOX_CEQ):
+ return ceq_is_empty(&ev_mbox->ceq);
+ default:
+ printf("Unknown mbox type %d!\n", ev_mbox->type);
+ return FALSE;
}
}
@@ -373,20 +382,22 @@
void handle_ev_ev(struct event_msg *ev_msg, unsigned int ev_type, void *data)
{
struct event_queue *ev_q;
- /* EV_EVENT can't handle not having a message / being a bit. If we got a
- * bit message, it's a bug somewhere */
+
+ /* EV_EVENT can't handle not having a message / being a bit. If we got
+ * a bit message, it's a bug somewhere */
assert(ev_msg);
ev_q = ev_msg->ev_arg3;
- /* Same deal, a null ev_q is probably a bug, or someone being a jackass */
+ /* Same deal, a null ev_q is probably a bug, or someone being a jackass
+ */
assert(ev_q);
- /* Clear pending, so we can start getting INDIRs and IPIs again. We must
- * set this before (compared to handle_events, then set it, then handle
- * again), since there is no guarantee handle_event_q() will return. If
- * there is a pending preemption, the vcore quickly yields and will deal
- * with the remaining events in the future - meaning it won't return to
- * here. */
+ /* Clear pending, so we can start getting INDIRs and IPIs again. We
+ * must set this before (compared to handle_events, then set it, then
+ * handle again), since there is no guarantee handle_event_q() will
+ * return. If there is a pending preemption, the vcore quickly yields
+ * and will deal with the remaining events in the future - meaning it
+ * won't return to here. */
ev_q->ev_alert_pending = FALSE;
- wmb(); /* don't let the pending write pass the signaling of an ev recv */
+ wmb();/* don't let the pending write pass the signaling of an ev recv */
handle_event_q(ev_q);
}
@@ -402,6 +413,7 @@
{
struct preempt_data *vcpd = vcpd_of(vcoreid);
int retval = 0;
+
vcpd->notif_pending = FALSE;
wrmb(); /* prevent future reads from happening before notif_p write */
retval += handle_mbox(&vcpd->ev_mbox_private);
@@ -422,7 +434,8 @@
}
/* Raw ev_qs that haven't been connected to an mbox, user bug: */
assert(ev_q->ev_mbox);
- /* The "default" ev_handler, common enough that I don't want a func ptr */
+ /* The "default" ev_handler, common enough that I don't want a func ptr
+ */
handle_mbox(ev_q->ev_mbox);
}
@@ -434,12 +447,13 @@
void send_self_vc_msg(struct event_msg *ev_msg)
{
// TODO: try to use UCQs (requires additional support)
- /* ev_type actually gets ignored currently. ev_msg is what matters if it is
- * non-zero. FALSE means it's going to the public mbox */
+ /* ev_type actually gets ignored currently. ev_msg is what matters if
+ * it is non-zero. FALSE means it's going to the public mbox */
sys_self_notify(vcore_id(), ev_msg->ev_type, ev_msg, FALSE);
}
-/* Helper: makes the current core handle a remote vcore's VCPD public mbox events.
+/* Helper: makes the current core handle a remote vcore's VCPD public mbox
+ * events.
*
* Both cases (whether we are handling someone else's already or not) use some
* method of telling our future self what to do. When we aren't already
@@ -462,7 +476,7 @@
uint32_t vcoreid = vcore_id();
struct preempt_data *vcpd = vcpd_of(vcoreid);
struct event_msg local_msg = {0};
- assert(vcoreid != rem_vcoreid); /* this shouldn't happen */
+ assert(vcoreid != rem_vcoreid);
/* If they are empty, then we're done */
if (mbox_is_empty(&vcpd_of(rem_vcoreid)->ev_mbox_public))
return;
@@ -470,8 +484,8 @@
/* we might be already handling them, in which case, abort */
if (__vc_rem_vcoreid == rem_vcoreid)
return;
- /* Already handling message for someone, need to send ourselves a
- * message to check rem_vcoreid, which we'll process later. */
+ /* Already handling message for someone, need to send ourselves
+ * a message to check rem_vcoreid, which we'll process later. */
local_msg.ev_type = EV_CHECK_MSGS;
local_msg.ev_arg2 = rem_vcoreid; /* 32bit arg */
send_self_vc_msg(&local_msg);
@@ -494,9 +508,10 @@
{
if (__vc_handle_an_mbox) {
handle_mbox(&vcpd_of(__vc_rem_vcoreid)->ev_mbox_public);
- /* only clear the flag when we have returned from handling messages. if
- * an event handler (like preempt_recover) doesn't return, we'll clear
- * this flag elsewhere. (it's actually not a big deal if we don't). */
+ /* only clear the flag when we have returned from handling
+ * messages. if an event handler (like preempt_recover) doesn't
+ * return, we'll clear this flag elsewhere. (it's actually not a
+ * big deal if we don't). */
cmb();
__vc_handle_an_mbox = FALSE;
}
@@ -517,16 +532,19 @@
struct event_msg local_msg = {0};
bool were_handling_remotes = FALSE;
if (__vc_handle_an_mbox) {
- /* slight chance we finished with their mbox (were on the last one) */
- if (!mbox_is_empty(&vcpd_of(__vc_rem_vcoreid)->ev_mbox_public)) {
+ /* slight chance we finished with their mbox (were on the last
+ * one) */
+ if (!mbox_is_empty(&vcpd_of(__vc_rem_vcoreid)->ev_mbox_public))
+ {
/* But we aren't, so we'll need to send a message */
local_msg.ev_type = EV_CHECK_MSGS;
local_msg.ev_arg2 = __vc_rem_vcoreid; /* 32bit arg */
send_self_vc_msg(&local_msg);
}
- /* Either way, we're not working on this one now. Note this is more of
- * an optimization - it'd be harmless (I think) to poll another vcore's
- * pub mbox once when we pop up in vc_entry in the future */
+ /* Either way, we're not working on this one now. Note this is
+ * more of an optimization - it'd be harmless (I think) to poll
+ * another vcore's pub mbox once when we pop up in vc_entry in
+ * the future */
__vc_handle_an_mbox = FALSE;
return TRUE;
}
@@ -595,11 +613,11 @@
* written to by handlers. The tailq is only used by the uthread. blocked is
* never concurrently *written*; see __uth_wakeup_poke() for details. */
struct uth_sleep_ctlr {
- struct uthread *uth;
+ struct uthread *uth;
struct spin_pdr_lock in_use;
- bool check_evqs;
- bool blocked;
- struct poke_tracker poker;
+ bool check_evqs;
+ bool blocked;
+ struct poke_tracker poker;
struct wait_link_tailq evqs;
};
@@ -626,14 +644,15 @@
static void __uth_wakeup_poke(void *arg)
{
struct uth_sleep_ctlr *uctlr = arg;
+
/* There are no concurrent writes to 'blocked'. Blocked is only ever
* written when the uth sleeps and only ever cleared here. Once the uth
* writes it, it does not write it again until after we clear it.
*
- * This is still racy - we could see !blocked, then blocked gets set. In
- * that case, the poke failed, and that is harmless. The uth will see
- * 'check_evqs', which was set before poke, which would be before writing
- * blocked, and the uth checks 'check_evqs' after writing. */
+ * This is still racy - we could see !blocked, then blocked gets set.
+ * In that case, the poke failed, and that is harmless. The uth will
+ * see 'check_evqs', which was set before poke, which would be before
+ * writing blocked, and the uth checks 'check_evqs' after writing. */
if (uctlr->blocked) {
uctlr->blocked = FALSE;
cmb(); /* clear blocked before starting the uth */
@@ -665,10 +684,11 @@
{
struct evq_wakeup_ctlr *ectlr = ev_q->ev_udata;
struct evq_wait_link *i;
+
assert(ectlr);
spin_pdr_lock(&ectlr->lock);
- /* Note we wake up all sleepers, even though only one is likely to get the
- * message. See the notes in unlink_ectlr() for more info. */
+ /* Note we wake up all sleepers, even though only one is likely to get
+ * the message. See the notes in unlink_ectlr() for more info. */
TAILQ_FOREACH(i, &ectlr->waiters, link_evq) {
i->uth_ctlr->check_evqs = TRUE;
cmb(); /* order check write before poke (poke has atomic) */
@@ -681,6 +701,7 @@
void evq_attach_wakeup_ctlr(struct event_queue *ev_q)
{
struct evq_wakeup_ctlr *ectlr = malloc(sizeof(struct evq_wakeup_ctlr));
+
memset(ectlr, 0, sizeof(struct evq_wakeup_ctlr));
spin_pdr_init(&ectlr->lock);
TAILQ_INIT(&ectlr->waiters);
@@ -702,7 +723,8 @@
/* No lock needed for the uctlr; we're the only one modifying evqs */
link->uth_ctlr = uctlr;
TAILQ_INSERT_HEAD(&uctlr->evqs, link, link_uth);
- /* Once we add ourselves to the ectrl list, we could start getting poked */
+ /* Once we add ourselves to the ectrl list, we could start getting poked
+ */
link->evq_ctlr = ectlr;
spin_pdr_lock(&ectlr->lock);
TAILQ_INSERT_HEAD(&ectlr->waiters, link, link_evq);
@@ -723,6 +745,7 @@
static void unlink_ectlr(struct evq_wait_link *link)
{
struct evq_wakeup_ctlr *ectlr = link->evq_ctlr;
+
spin_pdr_lock(&ectlr->lock);
TAILQ_REMOVE(&ectlr->waiters, link, link_evq);
spin_pdr_unlock(&ectlr->lock);
@@ -737,6 +760,7 @@
{
struct event_queue *evq_i;
bool ret = FALSE;
+
/* We need to have notifs disabled when extracting messages from some
* mboxes. Many mboxes have some form of busy waiting between consumers
* (userspace). If we're just a uthread, we could wind up on a runqueue
@@ -764,8 +788,8 @@
cmb(); /* actually block before saying 'blocked' */
uctlr->blocked = TRUE; /* can be woken up now */
wrmb(); /* write 'blocked' before read 'check_evqs' */
- /* If someone set check_evqs, we should wake up. We're competing with other
- * wakers via poke (we may have already woken up!). */
+ /* If someone set check_evqs, we should wake up. We're competing with
+ * other wakers via poke (we may have already woken up!). */
if (uctlr->check_evqs)
poke(&uctlr->poker, uctlr);
/* Once we say we're blocked, we could be woken up (possibly by our poke
@@ -783,9 +807,9 @@
struct uth_sleep_ctlr uctlr;
struct evq_wait_link linkage[nr_evqs];
- /* Catch user mistakes. If they lack a handler, they didn't attach. They
- * are probably using our evq_wakeup_handler, but they might have their own
- * wrapper function. */
+ /* Catch user mistakes. If they lack a handler, they didn't attach.
+ * They are probably using our evq_wakeup_handler, but they might have
+ * their own wrapper function. */
for (int i = 0; i < nr_evqs; i++)
assert(evqs[i]->ev_handler);
/* Check for activity on the evqs before going through the hassle of
@@ -795,30 +819,35 @@
uth_sleep_ctlr_init(&uctlr, current_uthread);
memset(linkage, 0, sizeof(struct evq_wait_link) * nr_evqs);
for (int i = 0; i < nr_evqs; i++)
- link_uctlr_ectlr(&uctlr, (struct evq_wakeup_ctlr*)evqs[i]->ev_udata,
+ link_uctlr_ectlr(&uctlr,
+ (struct evq_wakeup_ctlr*)evqs[i]->ev_udata,
&linkage[i]);
- /* Mesa-style sleep until we get a message. Mesa helps a bit here, since we
- * can just deregister from them all when we're done. o/w it is tempting to
- * have us deregister from *the* one in the handler and extract the message
- * there; which can be tricky and harder to reason about. */
+ /* Mesa-style sleep until we get a message. Mesa helps a bit here,
+ * since we can just deregister from them all when we're done. o/w it
+ * is tempting to have us deregister from *the* one in the handler and
+ * extract the message there; which can be tricky and harder to reason
+ * about. */
while (1) {
- /* We need to make sure only one 'version/ctx' of this thread is active
- * at a time. Later on, we'll unlock in vcore ctx on the other side of
- * a yield. We could restart from the yield, return, and free the uctlr
- * before that ctx has a chance to finish. */
+ /* We need to make sure only one 'version/ctx' of this thread is
+ * active at a time. Later on, we'll unlock in vcore ctx on the
+ * other side of a yield. We could restart from the yield,
+ * return, and free the uctlr before that ctx has a chance to
+ * finish. */
spin_pdr_lock(&uctlr.in_use);
- /* We're signed up. We might already have been told to check the evqs,
- * or there could be messages still sitting in the evqs. check_evqs is
- * only ever cleared here, and only ever set in evq handlers. */
+ /* We're signed up. We might already have been told to check
+ * the evqs, or there could be messages still sitting in the
+ * evqs. check_evqs is only ever cleared here, and only ever
+ * set in evq handlers. */
uctlr.check_evqs = FALSE;
cmb(); /* look for messages after clearing check_evqs */
if (extract_evqs_msg(evqs, nr_evqs, ev_msg, which_evq))
break;
uthread_yield(TRUE, __uth_blockon_evq_cb, &uctlr);
}
- /* On the one hand, it's not necessary to unlock, since the memory will be
- * freed. But we do need to go through the process to turn on notifs and
- * adjust the notif_disabled_depth for the case where we don't yield. */
+ /* On the one hand, it's not necessary to unlock, since the memory will
+ * be freed. But we do need to go through the process to turn on notifs
+ * and adjust the notif_disabled_depth for the case where we don't
+ * yield. */
spin_pdr_unlock(&uctlr.in_use);
for (int i = 0; i < nr_evqs; i++)
unlink_ectlr(&linkage[i]);
@@ -833,6 +862,7 @@
{
struct event_queue *evqs[nr_evqs];
va_list va;
+
va_start(va, nr_evqs);
for (int i = 0; i < nr_evqs; i++)
evqs[i] = va_arg(va, struct event_queue *);
@@ -849,6 +879,7 @@
{
struct event_queue *evqs[nr_evqs];
va_list va;
+
va_start(va, nr_evqs);
for (int i = 0; i < nr_evqs; i++)
evqs[i] = va_arg(va, struct event_queue *);
diff --git a/user/parlib/hexdump.c b/user/parlib/hexdump.c
index 3c45fad..f6c0f9f 100644
--- a/user/parlib/hexdump.c
+++ b/user/parlib/hexdump.c
@@ -54,7 +54,8 @@
fprintf(f," %02x", m[i + j]);
fprintf(f," ");
for (j = 0; j < 16; j++)
- fprintf(f,"%c", isprint(m[i + j]) ? m[i + j] : '.');
+ fprintf(f, "%c",
+ isprint(m[i + j]) ? m[i + j] : '.');
fprintf(f,"\n");
} else if (all_zero == 2) {
fprintf(f,"...\n");
diff --git a/user/parlib/include/parlib/alarm.h b/user/parlib/include/parlib/alarm.h
index bf41131..b5eb904 100644
--- a/user/parlib/include/parlib/alarm.h
+++ b/user/parlib/include/parlib/alarm.h
@@ -49,27 +49,27 @@
/* Specifc waiter, per alarm */
struct alarm_waiter {
- uint64_t wake_up_time; /* tsc time */
+ uint64_t wake_up_time; /* tsc time */
void (*func) (struct alarm_waiter *waiter);
- void *data;
+ void *data;
TAILQ_ENTRY(alarm_waiter) next;
- bool on_tchain;
+ bool on_tchain;
};
-TAILQ_HEAD(awaiters_tailq, alarm_waiter); /* ideally not a LL */
+TAILQ_HEAD(awaiters_tailq, alarm_waiter); /* ideally not a LL */
typedef void (*alarm_handler)(struct alarm_waiter *waiter);
/* Sorted collection of alarms. */
struct timer_chain {
struct awaiters_tailq waiters;
- struct alarm_waiter *running;
- uint64_t earliest_time;
- uint64_t latest_time;
- struct uth_cond_var cv;
- int ctlfd;
- int timerfd;
- int alarmid;
- struct event_queue *ev_q;
+ struct alarm_waiter *running;
+ uint64_t earliest_time;
+ uint64_t latest_time;
+ struct uth_cond_var cv;
+ int ctlfd;
+ int timerfd;
+ int alarmid;
+ struct event_queue *ev_q;
};
/* For fresh alarm waiters. func == 0 for kthreads */
diff --git a/user/parlib/include/parlib/assert.h b/user/parlib/include/parlib/assert.h
index 6caa7d4..1eb02d3 100644
--- a/user/parlib/include/parlib/assert.h
+++ b/user/parlib/include/parlib/assert.h
@@ -16,21 +16,21 @@
#define panic(...) _panic(__FILE__, __LINE__, __VA_ARGS__)
-#define assert(x) \
- do { \
- if (!(x)) \
- _assert_failed(__FILE__, __LINE__, #x); \
- } while (0)
+#define assert(x) \
+do { \
+ if (!(x)) \
+ _assert_failed(__FILE__, __LINE__, #x); \
+} while (0)
/* This is better than glibc's assert_perror(), but in the interest of not
* causing confusion, I'll rename ours. */
#define parlib_assert_perror(x) \
- do { \
- if (!(x)) { \
- perror(""); \
- _assert_failed(__FILE__, __LINE__, #x); \
- } \
- } while (0)
+do { \
+ if (!(x)) { \
+ perror(""); \
+ _assert_failed(__FILE__, __LINE__, #x); \
+ } \
+} while (0)
// parlib_static_assert(x) will generate a compile-time error if 'x' is false.
#define parlib_static_assert(x) switch (x) case 0: case (x):
diff --git a/user/parlib/include/parlib/bitmask.h b/user/parlib/include/parlib/bitmask.h
index 3e48247..f18867b 100644
--- a/user/parlib/include/parlib/bitmask.h
+++ b/user/parlib/include/parlib/bitmask.h
@@ -10,7 +10,7 @@
size_t i;
for (i = beg; i < end; i++) {
- if(!GET_BITMASK_BIT(m, i))
+ if (!GET_BITMASK_BIT(m, i))
return FALSE;
}
return TRUE;
@@ -22,7 +22,7 @@
size_t i;
for (i = beg; i < end; i++) {
- if(GET_BITMASK_BIT(m, i))
+ if (GET_BITMASK_BIT(m, i))
return FALSE;
}
return TRUE;
@@ -54,14 +54,14 @@
* overheads. */
#define BITMASK_FOREACH_SET(name, size, work_fn, clear) \
{ \
- int i; \
- for (i = 0; i < (size); i++) { \
- bool present = GET_BITMASK_BIT((name), i); \
- if (present && (clear)) \
- CLR_BITMASK_BIT_ATOMIC((name), i); \
- if (present) \
- (work_fn)(i); \
- } \
+ int i; \
+ for (i = 0; i < (size); i++) { \
+ bool present = GET_BITMASK_BIT((name), i); \
+ if (present && (clear)) \
+ CLR_BITMASK_BIT_ATOMIC((name), i); \
+ if (present) \
+ (work_fn)(i); \
+ } \
}
__END_DECLS
diff --git a/user/parlib/include/parlib/event.h b/user/parlib/include/parlib/event.h
index d93f680..3759b55 100644
--- a/user/parlib/include/parlib/event.h
+++ b/user/parlib/include/parlib/event.h
@@ -43,9 +43,9 @@
typedef void (*handle_event_t)(struct event_msg *ev_msg, unsigned int ev_type,
void *data);
struct ev_handler {
- struct ev_handler *next;
- handle_event_t func;
- void *data;
+ struct ev_handler *next;
+ handle_event_t func;
+ void *data;
};
extern struct ev_handler *ev_handlers[];
int register_ev_handler(unsigned int ev_type, handle_event_t handler,
diff --git a/user/parlib/include/parlib/kref.h b/user/parlib/include/parlib/kref.h
index 4d4d80a..642d076 100644
--- a/user/parlib/include/parlib/kref.h
+++ b/user/parlib/include/parlib/kref.h
@@ -33,7 +33,8 @@
if (!old_ref)
return FALSE;
new_ref = old_ref + inc;
- } while (!__sync_bool_compare_and_swap(&kref->refcnt, old_ref, new_ref));
+ } while (!__sync_bool_compare_and_swap(&kref->refcnt, old_ref,
+ new_ref));
return TRUE;
}
diff --git a/user/parlib/include/parlib/parlib.h b/user/parlib/include/parlib/parlib.h
index 447b4c2..4b985a1 100644
--- a/user/parlib/include/parlib/parlib.h
+++ b/user/parlib/include/parlib/parlib.h
@@ -30,42 +30,42 @@
extern const char *const __syscall_tbl[];
extern int __syscall_tbl_sz;
-int sys_null(void);
-size_t sys_getpcoreid(void);
-int sys_proc_destroy(int pid, int exitcode);
-void sys_yield(bool being_nice);
-int sys_proc_create(const char *path, size_t path_l, char *const argv[],
- char *const envp[], int flags);
-int sys_proc_run(int pid);
-ssize_t sys_shared_page_alloc(void **addr, pid_t p2,
- int p1_flags, int p2_flags);
-ssize_t sys_shared_page_free(void *addr, pid_t p2);
-void sys_reboot();
-void *sys_mmap(void *addr, size_t length, int prot, int flags,
- int fd, size_t offset);
-int sys_provision(int pid, unsigned int res_type, long res_val);
-int sys_notify(int pid, unsigned int ev_type, struct event_msg *u_msg);
-int sys_self_notify(uint32_t vcoreid, unsigned int ev_type,
- struct event_msg *u_msg, bool priv);
-int sys_send_event(struct event_queue *ev_q, struct event_msg *ev_msg,
- uint32_t vcoreid);
-int sys_halt_core(unsigned long usec);
-void* sys_init_arsc();
-int sys_block(unsigned long usec);
-int sys_change_vcore(uint32_t vcoreid, bool enable_my_notif);
-int sys_change_to_m(void);
-int sys_poke_ksched(int pid, unsigned int res_type);
-int sys_abort_sysc(struct syscall *sysc);
-int sys_abort_sysc_fd(int fd);
-int sys_tap_fds(struct fd_tap_req *tap_reqs, size_t nr_reqs);
+int sys_null(void);
+size_t sys_getpcoreid(void);
+int sys_proc_destroy(int pid, int exitcode);
+void sys_yield(bool being_nice);
+int sys_proc_create(const char *path, size_t path_l, char *const argv[],
+ char *const envp[], int flags);
+int sys_proc_run(int pid);
+ssize_t sys_shared_page_alloc(void **addr, pid_t p2, int p1_flags,
+ int p2_flags);
+ssize_t sys_shared_page_free(void *addr, pid_t p2);
+void sys_reboot();
+void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
+ size_t offset);
+int sys_provision(int pid, unsigned int res_type, long res_val);
+int sys_notify(int pid, unsigned int ev_type, struct event_msg *u_msg);
+int sys_self_notify(uint32_t vcoreid, unsigned int ev_type,
+ struct event_msg *u_msg, bool priv);
+int sys_send_event(struct event_queue *ev_q, struct event_msg *ev_msg,
+ uint32_t vcoreid);
+int sys_halt_core(unsigned long usec);
+void *sys_init_arsc(void);
+int sys_block(unsigned long usec);
+int sys_change_vcore(uint32_t vcoreid, bool enable_my_notif);
+int sys_change_to_m(void);
+int sys_poke_ksched(int pid, unsigned int res_type);
+int sys_abort_sysc(struct syscall *sysc);
+int sys_abort_sysc_fd(int fd);
+int sys_tap_fds(struct fd_tap_req *tap_reqs, size_t nr_reqs);
-void syscall_async(struct syscall *sysc, unsigned long num, ...);
-void syscall_async_evq(struct syscall *sysc, struct event_queue *evq,
- unsigned long num, ...);
+void syscall_async(struct syscall *sysc, unsigned long num, ...);
+void syscall_async_evq(struct syscall *sysc, struct event_queue *evq, unsigned
+ long num, ...);
/* Control variables */
extern bool parlib_wants_to_be_mcp; /* instructs the 2LS to be an MCP */
-extern bool parlib_never_yield; /* instructs the 2LS to not yield vcores */
+extern bool parlib_never_yield; /* instructs the 2LS to not yield vcores */
extern bool parlib_never_vc_request;/* 2LS: do not request vcores */
/* Process Management */
@@ -89,14 +89,16 @@
void (*init_fn)(void *), void *arg)
{
if (!once_ctl->ran_once) {
- /* fetch and set TRUE, without a header or test_and_set weirdness */
+ /* fetch and set TRUE, without a header or test_and_set
+ * weirdness */
if (!__sync_fetch_and_or(&once_ctl->is_running, TRUE)) {
/* we won the race and get to run the func */
init_fn(arg);
- wmb(); /* don't let the ran_once write pass previous writes */
+ /* don't let the ran_once write pass previous writes */
+ wmb();
once_ctl->ran_once = TRUE;
} else {
- /* someone else won, wait til they are done to break out */
+ /* someone else won */
while (!once_ctl->ran_once)
cpu_relax_any();
}
@@ -123,11 +125,11 @@
* multiple sources but should only execute once. */
#define parlib_init_once_racy(retcmd) \
do { \
- static bool initialized = FALSE; \
- if (initialized) { \
- retcmd; \
- } \
- initialized = TRUE; \
+ static bool initialized = FALSE; \
+ if (initialized) { \
+ retcmd; \
+ } \
+ initialized = TRUE; \
} while (0)
__END_DECLS
diff --git a/user/parlib/include/parlib/pool.h b/user/parlib/include/parlib/pool.h
index c4365b5..f004618 100644
--- a/user/parlib/include/parlib/pool.h
+++ b/user/parlib/include/parlib/pool.h
@@ -7,66 +7,68 @@
__BEGIN_DECLS
-#define POOL_TYPE_DEFINE(_type, p, sz) \
-typedef struct struct_##p { \
+#define POOL_TYPE_DEFINE(_type, p, sz) \
+typedef struct struct_##p { \
uint32_t size; \
uint32_t free; \
uint32_t index; \
- _type *queue[(sz)]; \
- _type pool[(sz)]; \
+ _type* queue[(sz)]; \
+ _type pool[(sz)]; \
} p##_t;
#define POOL_INIT(p, sz) \
({ \
- (p)->size = (sz); \
- (p)->free = (sz); \
- (p)->index = 0; \
- memset((p)->pool, 0, (sz) * sizeof((p)->pool[0])); \
- for(int i=0; i<(p)->size; i++) { \
- (p)->queue[i] = &((p)->pool[i]); \
- } \
+ (p)->size = (sz); \
+ (p)->free = (sz); \
+ (p)->index = 0; \
+ memset((p)->pool, 0, (sz) * sizeof((p)->pool[0])); \
+ for(int i=0; i<(p)->size; i++) { \
+ (p)->queue[i] = &((p)->pool[i]); \
+ } \
})
+
// removed unnecessary (p)->queue[(p)->index] = NULL;
-#define POOL_GET(p) \
-({ \
- void* rval = NULL; \
- if((p)->free) { \
- rval = (p)->queue[(p)->index]; \
- (p)->free--; \
- (p)->index++; \
- if((p)->index == (p)->size) { \
- (p)->index = 0; \
- } \
- } \
- rval; \
+#define POOL_GET(p) \
+({ \
+ void* rval = NULL; \
+ if((p)->free) { \
+ rval = (p)->queue[(p)->index]; \
+ (p)->free--; \
+ (p)->index++; \
+ if((p)->index == (p)->size) { \
+ (p)->index = 0; \
+ } \
+ } \
+ rval; \
})
-// emptyIndex is also the first element that has been allocated, iterate thru to index-1
+// emptyIndex is also the first element that has been allocated, iterate thru to
+// index-1
-#define POOL_FOR_EACH(p, func) \
-({ \
- int emptyIndex = ((p)->index + (p)->free); \
- if (emptyIndex >= (p)->size) { \
- emptyIndex -= (p)->size; \
- } \
- for(int _i = emptyIndex; _i < (p)->index; _i++){ \
- func((p)->queue[_i]); \
- } \
-}) \
+#define POOL_FOR_EACH(p, func) \
+({ \
+ int emptyIndex = ((p)->index + (p)->free); \
+ if (emptyIndex >= (p)->size) { \
+ emptyIndex -= (p)->size; \
+ } \
+ for(int _i = emptyIndex; _i < (p)->index; _i++){ \
+ func((p)->queue[_i]); \
+ } \
+})
#define POOL_PUT(p, val) \
({ \
- int rval = -1; \
- if((p)->free < (p)->size) { \
+ int rval = -1; \
+ if((p)->free < (p)->size) { \
int emptyIndex = ((p)->index + (p)->free); \
if (emptyIndex >= (p)->size) { \
emptyIndex -= (p)->size; \
} \
(p)->queue[emptyIndex] = val; \
(p)->free++; \
- rval = 1; \
+ rval = 1; \
} \
- rval; \
+ rval; \
})
#define POOL_EMPTY(p) ((p)->free == 0)
diff --git a/user/parlib/include/parlib/printf-ext.h b/user/parlib/include/parlib/printf-ext.h
index b99410a..b4c8b93 100644
--- a/user/parlib/include/parlib/printf-ext.h
+++ b/user/parlib/include/parlib/printf-ext.h
@@ -6,7 +6,7 @@
* (in early init code), and the others need to be requested.
*
* To register, for example %i for ipaddr, call:
- * register_printf_specifier('i', printf_ipaddr, printf_ipaddr_info);
+ * register_printf_specifier('i', printf_ipaddr, printf_ipaddr_info);
*/
#pragma once
diff --git a/user/parlib/include/parlib/riscv/arch.h b/user/parlib/include/parlib/riscv/arch.h
index e24bd36..c3cd68c 100644
--- a/user/parlib/include/parlib/riscv/arch.h
+++ b/user/parlib/include/parlib/riscv/arch.h
@@ -48,7 +48,8 @@
cpu_relax(void)
{
long ctr;
- asm volatile("li %0, 8; 1: addi %0, %0, -1; bnez %0, 1b" : "=r"(ctr) : : "memory");
+ asm volatile("li %0, 8; 1: addi %0, %0, -1; bnez %0, 1b" : "=r"(ctr)
+ : : "memory");
}
static inline void save_fp_state(struct ancillary_state* silly)
diff --git a/user/parlib/include/parlib/riscv/atomic.h b/user/parlib/include/parlib/riscv/atomic.h
index 994deb4..8943ac5 100644
--- a/user/parlib/include/parlib/riscv/atomic.h
+++ b/user/parlib/include/parlib/riscv/atomic.h
@@ -81,8 +81,8 @@
{
uintptr_t offset = (uintptr_t)number & 3;
uint32_t wmask = (1<<(8*offset+8)) - (1<<(8*offset));
- wmask = ~wmask | ((uint32_t)mask << (8*offset));
+ wmask = ~wmask | ((uint32_t)mask << (8*offset));
__sync_fetch_and_and((uint32_t*)((uintptr_t)number & ~3), wmask);
}
diff --git a/user/parlib/include/parlib/riscv/vcore.h b/user/parlib/include/parlib/riscv/vcore.h
index 4ef222e..a3b7c32 100644
--- a/user/parlib/include/parlib/riscv/vcore.h
+++ b/user/parlib/include/parlib/riscv/vcore.h
@@ -21,7 +21,8 @@
/* Register saves and restores happen in asm. */
typedef void (*helper_fn)(struct hw_trapframe*, struct preempt_data*, uint32_t);
void __pop_ros_tf_regs(struct hw_trapframe *tf, struct preempt_data* vcpd,
- uint32_t vcoreid, helper_fn helper) __attribute__((noreturn));
+ uint32_t vcoreid, helper_fn helper)
+ __attribute__((noreturn));
void __save_ros_tf_regs(struct hw_trapframe *tf) __attribute__((returns_twice));
/* Helper function that may handle notifications after re-enabling them. */
diff --git a/user/parlib/include/parlib/signal.h b/user/parlib/include/parlib/signal.h
index e4546ec..97963b5 100644
--- a/user/parlib/include/parlib/signal.h
+++ b/user/parlib/include/parlib/signal.h
@@ -28,10 +28,11 @@
struct signal_ops {
/* Standard ops */
int (*sigaltstack)(__const struct sigaltstack *__restrict,
- struct sigaltstack *__restrict);
+ struct sigaltstack *__restrict);
int (*siginterrupt)(int, int);
int (*sigpending)(sigset_t *);
- int (*sigprocmask)(int, __const sigset_t *__restrict, sigset_t *__restrict);
+ int (*sigprocmask)(int, __const sigset_t *__restrict,
+ sigset_t *__restrict);
int (*sigqueue)(__pid_t, int, __const union sigval);
int (*sigreturn)(struct sigcontext *__scp);
int (*sigstack)(struct sigstack *, struct sigstack *);
diff --git a/user/parlib/include/parlib/stdio.h b/user/parlib/include/parlib/stdio.h
index c2b6f10..44e7cc0 100644
--- a/user/parlib/include/parlib/stdio.h
+++ b/user/parlib/include/parlib/stdio.h
@@ -75,36 +75,38 @@
#define vfprintf(f_stream, fmt, ...) \
({ \
- int __parlib_safe_print_ret; \
- \
- if (__safe_to_printf()) \
- __parlib_safe_print_ret = vfprintf(f_stream, fmt, __VA_ARGS__); \
- else \
- __parlib_safe_print_ret = __vc_ctx_vfprintf(f_stream, fmt, \
- __VA_ARGS__); \
- __parlib_safe_print_ret; \
+ int __parlib_safe_print_ret; \
+ \
+ if (__safe_to_printf()) \
+ __parlib_safe_print_ret = vfprintf(f_stream, fmt, __VA_ARGS__);\
+ else \
+ __parlib_safe_print_ret = __vc_ctx_vfprintf(f_stream, fmt, \
+ __VA_ARGS__); \
+ __parlib_safe_print_ret; \
})
#define fprintf(f_stream, ...) \
({ \
- int __parlib_safe_print_ret; \
- \
- if (__safe_to_printf()) \
- __parlib_safe_print_ret = fprintf(f_stream, __VA_ARGS__); \
- else \
- __parlib_safe_print_ret = __vc_ctx_fprintf(f_stream, __VA_ARGS__); \
- __parlib_safe_print_ret; \
+ int __parlib_safe_print_ret; \
+ \
+ if (__safe_to_printf()) \
+ __parlib_safe_print_ret = fprintf(f_stream, __VA_ARGS__); \
+ else \
+ __parlib_safe_print_ret = __vc_ctx_fprintf(f_stream, \
+ __VA_ARGS__); \
+ __parlib_safe_print_ret; \
})
#define printf(...) \
({ \
- int __parlib_safe_print_ret; \
- \
- if (__safe_to_printf()) \
- __parlib_safe_print_ret = printf(__VA_ARGS__); \
- else \
- __parlib_safe_print_ret = __vc_ctx_fprintf(stdout, __VA_ARGS__); \
- __parlib_safe_print_ret; \
+ int __parlib_safe_print_ret; \
+ \
+ if (__safe_to_printf()) \
+ __parlib_safe_print_ret = printf(__VA_ARGS__); \
+ else \
+ __parlib_safe_print_ret = __vc_ctx_fprintf(stdout, \
+ __VA_ARGS__); \
+ __parlib_safe_print_ret; \
})
#define debug_fprintf(f, ...) __vc_ctx_fprintf(f, __VA_ARGS__)
@@ -112,16 +114,16 @@
#define printx(...) \
do { \
- if (__procdata.printx_on) \
- debug_fprintf(stderr, __VA_ARGS__); \
+ if (__procdata.printx_on) \
+ debug_fprintf(stderr, __VA_ARGS__); \
} while (0);
int trace_printf(const char *fmt, ...);
#define trace_printx(...) \
do { \
- if (__procdata.printx_on) \
- trace_printf(__VA_ARGS__); \
+ if (__procdata.printx_on) \
+ trace_printf(__VA_ARGS__); \
} while (0);
#define I_AM_HERE __vc_ctx_fprintf(stderr, \
diff --git a/user/parlib/include/parlib/tsc-compat.h b/user/parlib/include/parlib/tsc-compat.h
index 47c9c59..a124de9 100644
--- a/user/parlib/include/parlib/tsc-compat.h
+++ b/user/parlib/include/parlib/tsc-compat.h
@@ -53,6 +53,7 @@
static inline uint64_t read_tsc(void)
{
uint64_t tsc;
+
asm volatile("rdtsc" : "=A" (tsc));
return tsc;
}
@@ -60,6 +61,7 @@
static inline uint64_t read_tsc_serialized(void)
{
uint64_t tsc;
+
asm volatile("lfence; rdtsc" : "=A" (tsc));
return tsc;
}
@@ -69,6 +71,7 @@
static inline uint64_t read_tsc(void)
{
uint32_t lo, hi;
+
/* We cannot use "=A", since this would use %rax on x86_64 */
asm volatile("rdtsc" : "=a" (lo), "=d" (hi));
return (uint64_t)hi << 32 | lo;
@@ -77,6 +80,7 @@
static inline uint64_t read_tsc_serialized(void)
{
uint32_t lo, hi;
+
asm volatile("lfence; rdtsc" : "=a" (lo), "=d" (hi));
return (uint64_t)hi << 32 | lo;
}
@@ -90,14 +94,17 @@
struct timeval prev;
struct timeval curr;
uint64_t beg = read_tsc_serialized();
+
gettimeofday(&prev, 0);
while (1) {
gettimeofday(&curr, 0);
if (curr.tv_sec > (prev.tv_sec + 1) ||
- (curr.tv_sec > prev.tv_sec && curr.tv_usec > prev.tv_usec))
+ (curr.tv_sec > prev.tv_sec && curr.tv_usec >
+ prev.tv_usec))
break;
}
uint64_t end = read_tsc_serialized();
+
return end - beg;
}
diff --git a/user/parlib/include/parlib/uthread.h b/user/parlib/include/parlib/uthread.h
index 01a4170..c0e5c9f 100644
--- a/user/parlib/include/parlib/uthread.h
+++ b/user/parlib/include/parlib/uthread.h
@@ -11,38 +11,38 @@
__BEGIN_DECLS
-#define UTHREAD_DONT_MIGRATE 0x001 /* don't move to another vcore */
-#define UTHREAD_SAVED 0x002 /* uthread's state is in utf */
-#define UTHREAD_FPSAVED 0x004 /* uthread's FP state is in uth->as */
-#define UTHREAD_IS_THREAD0 0x008 /* thread0: glibc's main() thread */
+#define UTHREAD_DONT_MIGRATE 0x001 /* don't move to another vcore */
+#define UTHREAD_SAVED 0x002 /* uthread's state is in utf */
+#define UTHREAD_FPSAVED 0x004 /* uthread's FP state is in uth->as */
+#define UTHREAD_IS_THREAD0 0x008 /* thread0: glibc's main() thread */
/* Thread States */
#define UT_RUNNING 1
-#define UT_NOT_RUNNING 2
+#define UT_NOT_RUNNING 2
/* Externally blocked thread reasons (for uthread_has_blocked()) */
-#define UTH_EXT_BLK_MUTEX 1
-#define UTH_EXT_BLK_EVENTQ 2
-#define UTH_EXT_BLK_YIELD 3
-#define UTH_EXT_BLK_MISC 4
+#define UTH_EXT_BLK_MUTEX 1
+#define UTH_EXT_BLK_EVENTQ 2
+#define UTH_EXT_BLK_YIELD 3
+#define UTH_EXT_BLK_MISC 4
/* One per joiner, usually kept on the stack. */
struct uth_join_kicker {
- struct kref kref;
- struct uthread *joiner;
+ struct kref kref;
+ struct uthread *joiner;
};
/* Join states, stored in the join_ctl */
-#define UTH_JOIN_DETACHED 1
-#define UTH_JOIN_JOINABLE 2
-#define UTH_JOIN_HAS_JOINER 3
-#define UTH_JOIN_EXITED 4
+#define UTH_JOIN_DETACHED 1
+#define UTH_JOIN_JOINABLE 2
+#define UTH_JOIN_HAS_JOINER 3
+#define UTH_JOIN_EXITED 4
/* One per uthread, to encapsulate all the join fields. */
struct uth_join_ctl {
- atomic_t state;
- void *retval;
- void **retval_loc;
+ atomic_t state;
+ void *retval;
+ void **retval_loc;
struct uth_join_kicker *kicker;
};
@@ -60,7 +60,7 @@
int notif_disabled_depth;
TAILQ_ENTRY(uthread) sync_next;
struct syscall *sysc; /* syscall we're blocking on, if any */
- struct syscall local_sysc; /* for when we don't want to use the stack */
+ struct syscall local_sysc; /* for when we don't want to use the stack */
void (*yield_func)(struct uthread*, void*);
void *yield_arg;
int err_no;
@@ -82,7 +82,7 @@
* of the toolchain. libgomp and probably c++ threads care about the size of
* objects that contain uth_sync_t. */
typedef struct __uth_sync_opaque {
- uint8_t foo[sizeof(uintptr_t) * 2];
+ uint8_t foo[sizeof(uintptr_t) * 2];
} __attribute__ ((aligned(sizeof(uintptr_t)))) uth_sync_t;
/* 2LS-independent synchronization code (e.g. uthread mutexes) uses these
@@ -140,13 +140,13 @@
* retvals, etc). */
struct uth_thread_attr {
- bool want_tls; /* default, no */
- bool detached; /* default, no */
+ bool want_tls; /* default, no */
+ bool detached; /* default, no */
};
struct uth_join_request {
- struct uthread *uth;
- void **retval_loc;
+ struct uthread *uth;
+ void **retval_loc;
};
/* uthread_init() does the uthread initialization of a uthread that the caller
@@ -218,19 +218,19 @@
#define uthread_set_tls_var(uth, name, val) \
({ \
- typeof(val) __val = val; \
- begin_access_tls_vars(((struct uthread*)(uth))->tls_desc); \
- name = __val; \
- end_access_tls_vars(); \
+ typeof(val) __val = val; \
+ begin_access_tls_vars(((struct uthread*)(uth))->tls_desc); \
+ name = __val; \
+ end_access_tls_vars(); \
})
#define uthread_get_tls_var(uth, name) \
({ \
- typeof(name) val; \
- begin_access_tls_vars(((struct uthread*)(uth))->tls_desc); \
- val = name; \
- end_access_tls_vars(); \
- val; \
+ typeof(name) val; \
+ begin_access_tls_vars(((struct uthread*)(uth))->tls_desc); \
+ val = name; \
+ end_access_tls_vars(); \
+ val; \
})
/* Uthread Mutexes / CVs / etc. */
@@ -242,36 +242,36 @@
typedef struct uth_rwlock uth_rwlock_t;
struct uth_semaphore {
- parlib_once_t once_ctl;
- unsigned int count;
+ parlib_once_t once_ctl;
+ unsigned int count;
struct spin_pdr_lock lock;
- uth_sync_t sync_obj;
+ uth_sync_t sync_obj;
};
#define UTH_SEMAPHORE_INIT(n) { PARLIB_ONCE_INIT, (n) }
#define UTH_MUTEX_INIT { PARLIB_ONCE_INIT }
struct uth_recurse_mutex {
- parlib_once_t once_ctl;
- uth_mutex_t mtx;
- struct uthread *lockholder;
- unsigned int count;
+ parlib_once_t once_ctl;
+ uth_mutex_t mtx;
+ struct uthread *lockholder;
+ unsigned int count;
};
#define UTH_RECURSE_MUTEX_INIT { PARLIB_ONCE_INIT }
struct uth_cond_var {
- parlib_once_t once_ctl;
+ parlib_once_t once_ctl;
struct spin_pdr_lock lock;
- uth_sync_t sync_obj;
+ uth_sync_t sync_obj;
};
#define UTH_COND_VAR_INIT { PARLIB_ONCE_INIT }
struct uth_rwlock {
- parlib_once_t once_ctl;
+ parlib_once_t once_ctl;
struct spin_pdr_lock lock;
- unsigned int nr_readers;
- bool has_writer;
- uth_sync_t readers;
- uth_sync_t writers;
+ unsigned int nr_readers;
+ bool has_writer;
+ uth_sync_t readers;
+ uth_sync_t writers;
};
#define UTH_RWLOCK_INIT { PARLIB_ONCE_INIT }
diff --git a/user/parlib/include/parlib/vcore.h b/user/parlib/include/parlib/vcore.h
index 43ae52b..9eec752 100644
--- a/user/parlib/include/parlib/vcore.h
+++ b/user/parlib/include/parlib/vcore.h
@@ -16,7 +16,7 @@
void __attribute__((noreturn)) vcore_entry(void);
extern __thread bool __vcore_context;
extern __thread int __vcoreid;
-extern __thread struct syscall __vcore_one_sysc; /* see sys_change_vcore */
+extern __thread struct syscall __vcore_one_sysc; /* see sys_change_vcore */
/* Arch specific entry from the kernel */
void __attribute__((noreturn)) __kernel_vcore_entry(void);
@@ -62,9 +62,9 @@
/* This works so long as we don't dlopen parlib (which we never do) */
#define get_tlsvar_linaddr(_vcoreid, _var) \
({ \
- uintptr_t vc_tls_desc = (uintptr_t)get_vcpd_tls_desc(_vcoreid); \
- uintptr_t var_off = (uintptr_t)&_var - (uintptr_t)get_tls_desc(); \
- (typeof(_var) *)(vc_tls_desc + var_off); \
+ uintptr_t vc_tls_desc = (uintptr_t)get_vcpd_tls_desc(_vcoreid); \
+ uintptr_t var_off = (uintptr_t)&_var - (uintptr_t)get_tls_desc(); \
+ (typeof(_var) *)(vc_tls_desc + var_off); \
})
/* Static inlines */
@@ -118,6 +118,7 @@
static inline bool vcore_is_preempted(uint32_t vcoreid)
{
struct preempt_data *vcpd = vcpd_of(vcoreid);
+
return atomic_read(&vcpd->flags) & VC_PREEMPTED;
}
@@ -183,6 +184,7 @@
uint64_t resume = __procinfo.vcoremap[vcoreid].resume_ticks;
uint64_t total = __procinfo.vcoremap[vcoreid].total_ticks;
uint64_t now = read_tsc();
+
return now - resume + total;
}
@@ -233,12 +235,12 @@
* of a "TLS cmb()". */
#define begin_safe_access_tls_vars() \
{ \
- void __attribute__((noinline, optimize("O0"))) \
- safe_access_tls_var_internal() { \
- asm(""); \
+ void __attribute__((noinline, optimize("O0"))) \
+ safe_access_tls_var_internal() { \
+ asm(""); \
#define end_safe_access_tls_vars() \
- } safe_access_tls_var_internal(); \
+ } safe_access_tls_var_internal(); \
}
#endif // __PIC__
@@ -247,79 +249,81 @@
* uthread or vcore context. Pairs with end_access_tls_vars(). */
#define begin_access_tls_vars(tls_desc) \
{ \
- struct uthread *caller; \
- uint32_t vcoreid; \
- void *temp_tls_desc; \
- bool invcore = in_vcore_context(); \
- if (!invcore) { \
- caller = current_uthread; \
- /* If you have no current_uthread, you might be called too early in the
- * process's lifetime. Make sure something like uthread_slim_init() has
- * been run. */ \
- assert(caller); \
- /* We need to disable notifs here (in addition to not migrating), since
- * we could get interrupted when we're in the other TLS, and when the
- * vcore restarts us, it will put us in our old TLS, not the one we were
- * in when we were interrupted. We need to not migrate, since once we
- * know the vcoreid, we depend on being on the same vcore throughout.*/\
- caller->flags |= UTHREAD_DONT_MIGRATE; \
- /* Not concerned about cross-core memory ordering, so no CPU mbs needed.
- * The cmb is to prevent the compiler from issuing the vcore read before
- * the DONT_MIGRATE write. */ \
- cmb(); \
- vcoreid = vcore_id(); \
- disable_notifs(vcoreid); \
- } else { /* vcore context */ \
- vcoreid = vcore_id(); \
- } \
- temp_tls_desc = get_tls_desc(); \
- set_tls_desc(tls_desc); \
+ struct uthread *caller; \
+ uint32_t vcoreid; \
+ void *temp_tls_desc; \
+ bool invcore = in_vcore_context(); \
+ if (!invcore) { \
+ caller = current_uthread; \
+ /* If you have no current_uthread, you might be called too early
+ * in the process's lifetime. Make sure something like
+ * uthread_slim_init() has been run. */ \
+ assert(caller); \
+ /* We need to disable notifs here (in addition to not
+ * migrating), since we could get interrupted when we're in the
+ * other TLS, and when the vcore restarts us, it will put us in
+ * our old TLS, not the one we were in when we were interrupted.
+ * We need to not migrate, since once we know the vcoreid, we
+ * depend on being on the same vcore throughout.*/ \
+ caller->flags |= UTHREAD_DONT_MIGRATE; \
+ /* Not concerned about cross-core memory ordering, so no CPU mbs
+ * needed. The cmb is to prevent the compiler from issuing the
+ * vcore read before the DONT_MIGRATE write. */ \
+ cmb(); \
+ vcoreid = vcore_id(); \
+ disable_notifs(vcoreid); \
+ } else { /* vcore context */ \
+ vcoreid = vcore_id(); \
+ } \
+ temp_tls_desc = get_tls_desc(); \
+ set_tls_desc(tls_desc); \
begin_safe_access_tls_vars();
#define end_access_tls_vars() \
- end_safe_access_tls_vars(); \
- set_tls_desc(temp_tls_desc); \
- if (!invcore) { \
- /* Note we reenable migration before enabling notifs, which is reverse
- * from how we disabled notifs. We must enabling migration before
- * enabling notifs. See 6c7fb12 and 5e4825eb4 for details. */ \
- caller->flags &= ~UTHREAD_DONT_MIGRATE; \
- cmb(); /* turn off DONT_MIGRATE before enabling notifs */ \
- enable_notifs(vcoreid); \
- } \
+ end_safe_access_tls_vars(); \
+ set_tls_desc(temp_tls_desc); \
+ if (!invcore) { \
+ /* Note we reenable migration before enabling notifs, which is
+ * reverse from how we disabled notifs. We must enabling
+ * migration before enabling notifs. See 6c7fb12 and 5e4825eb4
+ * for details. */ \
+ caller->flags &= ~UTHREAD_DONT_MIGRATE; \
+ cmb(); /* turn off DONT_MIGRATE before enabling notifs */ \
+ enable_notifs(vcoreid); \
+ } \
}
#define safe_set_tls_var(name, val) \
({ \
- begin_safe_access_tls_vars(); \
- name = val; \
- end_safe_access_tls_vars(); \
+ begin_safe_access_tls_vars(); \
+ name = val; \
+ end_safe_access_tls_vars(); \
})
#define safe_get_tls_var(name) \
({ \
- typeof(name) __val; \
- begin_safe_access_tls_vars(); \
- __val = name; \
- end_safe_access_tls_vars(); \
- __val; \
+ typeof(name) __val; \
+ begin_safe_access_tls_vars(); \
+ __val = name; \
+ end_safe_access_tls_vars(); \
+ __val; \
})
#define vcore_set_tls_var(name, val) \
({ \
- typeof(val) __val = val; \
- begin_access_tls_vars(get_vcpd_tls_desc(vcoreid)); \
- name = __val; \
- end_access_tls_vars(); \
+ typeof(val) __val = val; \
+ begin_access_tls_vars(get_vcpd_tls_desc(vcoreid)); \
+ name = __val; \
+ end_access_tls_vars(); \
})
#define vcore_get_tls_var(name) \
({ \
- typeof(name) val; \
- begin_access_tls_vars(get_vcpd_tls_desc(vcoreid)); \
- val = name; \
- end_access_tls_vars(); \
- val; \
+ typeof(name) val; \
+ begin_access_tls_vars(get_vcpd_tls_desc(vcoreid)); \
+ val = name; \
+ end_access_tls_vars(); \
+ val; \
})
__END_DECLS
diff --git a/user/parlib/include/parlib/waitfreelist.h b/user/parlib/include/parlib/waitfreelist.h
index da527c8..27d9a60 100644
--- a/user/parlib/include/parlib/waitfreelist.h
+++ b/user/parlib/include/parlib/waitfreelist.h
@@ -14,13 +14,13 @@
__BEGIN_DECLS
struct wfl_entry {
- struct wfl_entry *next;
- void *data;
+ struct wfl_entry *next;
+ void *data;
};
struct wfl {
- struct wfl_entry *head;
- struct wfl_entry first;
+ struct wfl_entry *head;
+ struct wfl_entry first;
};
#define WFL_INITIALIZER(list) {&(list).first, {0, 0}}
diff --git a/user/parlib/include/parlib/x86/arch.h b/user/parlib/include/parlib/x86/arch.h
index 6899887..9106e5d 100644
--- a/user/parlib/include/parlib/x86/arch.h
+++ b/user/parlib/include/parlib/x86/arch.h
@@ -11,24 +11,24 @@
#ifdef __x86_64__
#define internal_function
-#define X86_REG_BP "rbp"
-#define X86_REG_SP "rsp"
-#define X86_REG_IP "rip"
-#define X86_REG_AX "rax"
-#define X86_REG_BX "rbx"
-#define X86_REG_CX "rcx"
-#define X86_REG_DX "rdx"
+#define X86_REG_BP "rbp"
+#define X86_REG_SP "rsp"
+#define X86_REG_IP "rip"
+#define X86_REG_AX "rax"
+#define X86_REG_BX "rbx"
+#define X86_REG_CX "rcx"
+#define X86_REG_DX "rdx"
#else /* 32 bit */
#define internal_function __attribute ((regparm (3), stdcall))
-#define X86_REG_BP "ebp"
-#define X86_REG_SP "esp"
-#define X86_REG_IP "eip"
-#define X86_REG_AX "eax"
-#define X86_REG_BX "ebx"
-#define X86_REG_CX "ecx"
-#define X86_REG_DX "edx"
+#define X86_REG_BP "ebp"
+#define X86_REG_SP "esp"
+#define X86_REG_IP "eip"
+#define X86_REG_AX "eax"
+#define X86_REG_BX "ebx"
+#define X86_REG_CX "ecx"
+#define X86_REG_DX "edx"
#endif /* 64bit / 32bit */
@@ -38,7 +38,8 @@
static inline void __attribute__((always_inline))
set_stack_pointer(void *sp)
{
- asm volatile("mov %0,%%"X86_REG_SP"" : : "r"(sp) : "memory", X86_REG_SP);
+ asm volatile("mov %0,%%"X86_REG_SP"" : : "r"(sp)
+ : "memory", X86_REG_SP);
}
static inline unsigned long get_stack_pointer(void)
@@ -57,6 +58,7 @@
static inline uint64_t read_tsc(void)
{
uint32_t edx, eax;
+
asm volatile("rdtsc" : "=d"(edx), "=a"(eax));
return (uint64_t)edx << 32 | eax;
}
@@ -79,43 +81,48 @@
uint32_t eax, edx;
/* PLEASE NOTE:
- * AMD CPUs ignore the FOP/FIP/FDP fields when there is
- * no pending exception. When you are on AMD, we zero these fields in the
- * ancillary_state argument before saving. This way, if you are on AMD and
- * re-using an ancillary_state memory region, an old save's information
- * won't leak into your new data. The side-effect of this is that you can't
- * trust these fields to report accurate information on AMD unless an
- * exception was pending. Granted, AMD says that only exception handlers
- * should care about FOP/FIP/FDP, so that's probably okay.
+ * AMD CPUs ignore the FOP/FIP/FDP fields when there is no pending
+ * exception. When you are on AMD, we zero these fields in the
+ * ancillary_state argument before saving. This way, if you are on AMD
+ * and re-using an ancillary_state memory region, an old save's
+ * information won't leak into your new data. The side-effect of this is
+ * that you can't trust these fields to report accurate information on
+ * AMD unless an exception was pending. Granted, AMD says that only
+ * exception handlers should care about FOP/FIP/FDP, so that's probably
+ * okay.
*
- * You should also note that on newer Intel 64 processors, while the value
- * of the FOP is always saved and restored, it contains the opcode of the
- * most recent x87 FPU instruction that triggered an unmasked exception,
- * rather than simply the most recent opcode. Some older Xeons and P4s had
- * the fopcode compatibility mode feature, which you could use to make the
- * FOP update on every x87 non-control instruction, but that has been
- * eliminated in newer hardware.
+ * You should also note that on newer Intel 64 processors, while the
+ * value of the FOP is always saved and restored, it contains the opcode
+ * of the most recent x87 FPU instruction that triggered an unmasked
+ * exception, rather than simply the most recent opcode. Some older
+ * Xeons and P4s had the fopcode compatibility mode feature, which you
+ * could use to make the FOP update on every x87 non-control
+ * instruction, but that has been eliminated in newer hardware.
*
*/
if (cpu_has_feat(CPU_FEAT_X86_VENDOR_AMD)) {
silly->fp_head_64d.fop = 0x0;
silly->fp_head_64d.fpu_ip = 0x0;
silly->fp_head_64d.cs = 0x0;
- silly->fp_head_64d.padding1 = 0x0; // padding1 is FIP or rsvd, proc dep.
+ // padding1 is FIP or rsvd, proc dep.
+ silly->fp_head_64d.padding1 = 0x0;
silly->fp_head_64d.fpu_dp = 0x0;
silly->fp_head_64d.ds = 0x0;
- silly->fp_head_64d.padding2 = 0x0; // padding2 is FDP or rsvd, proc dep.
+ // padding2 is FDP or rsvd, proc dep.
+ silly->fp_head_64d.padding2 = 0x0;
}
if (cpu_has_feat(CPU_FEAT_X86_XSAVEOPT)) {
edx = x86_default_xcr0 >> 32;
eax = x86_default_xcr0;
- asm volatile("xsaveopt64 %0" : : "m"(*silly), "a"(eax), "d"(edx));
+ asm volatile("xsaveopt64 %0"
+ : : "m"(*silly), "a"(eax), "d"(edx));
} else if (cpu_has_feat(CPU_FEAT_X86_XSAVE)) {
edx = x86_default_xcr0 >> 32;
eax = x86_default_xcr0;
- asm volatile("xsave64 %0" : : "m"(*silly), "a"(eax), "d"(edx));
+ asm volatile("xsave64 %0"
+ : : "m"(*silly), "a"(eax), "d"(edx));
} else {
asm volatile("fxsave64 %0" : : "m"(*silly));
}
@@ -142,7 +149,8 @@
* We check for a pending exception by checking FSW.ES (bit 7)
*
* FNINIT clears FIP and FDP and, even though it is technically a
- * control instruction, it clears FOP because it is initializing the FPU.
+ * control instruction, it clears FOP because it is initializing the
+ * FPU.
*
* NOTE: This might not be the most efficient way to do things, and
* could be an optimization target for context switch performance
diff --git a/user/parlib/include/parlib/x86/atomic.h b/user/parlib/include/parlib/x86/atomic.h
index bc9b9f8..f6e7647 100644
--- a/user/parlib/include/parlib/x86/atomic.h
+++ b/user/parlib/include/parlib/x86/atomic.h
@@ -29,6 +29,7 @@
static inline long atomic_read(atomic_t *number)
{
long val;
+
asm volatile("mov %1,%0" : "=r"(val) : "m"(*number));
return val;
}
diff --git a/user/parlib/include/parlib/x86/trap.h b/user/parlib/include/parlib/x86/trap.h
index 26a8ac5..cf4306a 100644
--- a/user/parlib/include/parlib/x86/trap.h
+++ b/user/parlib/include/parlib/x86/trap.h
@@ -24,7 +24,8 @@
case ROS_SW_CTX:
return FALSE;
case ROS_VM_CTX:
- return ctx->tf.vm_tf.tf_flags & VMCTX_FL_HAS_FAULT ? TRUE : FALSE;
+ return ctx->tf.vm_tf.tf_flags & VMCTX_FL_HAS_FAULT ? TRUE :
+ FALSE;
}
assert(0);
}
diff --git a/user/parlib/include/parlib/x86/vcore.h b/user/parlib/include/parlib/x86/vcore.h
index 2b2aca2..9e65bc2 100644
--- a/user/parlib/include/parlib/x86/vcore.h
+++ b/user/parlib/include/parlib/x86/vcore.h
@@ -44,7 +44,7 @@
"mov %%rbx, 0x10(%0); "
"1: " /* where this tf will restart */
: "=D"(dummy) /* force clobber for rdi */
- : "D"(sw_tf)
+ : "D"(sw_tf)
: "rax", "rcx", "rdx", "rsi", "r8", "r9", "r10", "r11",
"memory", "cc");
} __attribute__((always_inline, returns_twice))
@@ -68,7 +68,7 @@
"leaq 1f, %%rax; " /* get future rip */
"movq %%rax, (%1); " /* store future rip */
"popq %%rax; " /* restore rax */
- "movq %2, %%rsp; " /* move to the rax slot of the tf */
+ "movq %2, %%rsp; " /* move to the TF's rax slot */
"addl $0x78,%%esp; " /* move to just past r15 */
"pushq %%r15; " /* save regs */
"pushq %%r14; "
@@ -100,10 +100,11 @@
ctx->type = ROS_SW_CTX;
/* Stack pointers in a fresh stackframe need to be such that adding or
- * subtracting 8 will result in 16 byte alignment (AMD64 ABI). The reason
- * is so that input arguments (on the stack) are 16 byte aligned. The
- * extra 8 bytes is the retaddr, pushed on the stack. Compilers know they
- * can subtract 8 to get 16 byte alignment for instructions like movaps. */
+ * subtracting 8 will result in 16 byte alignment (AMD64 ABI). The
+ * reason is so that input arguments (on the stack) are 16 byte aligned.
+ * The extra 8 bytes is the retaddr, pushed on the stack. Compilers
+ * know they can subtract 8 to get 16 byte alignment for instructions
+ * like movaps. */
sw_tf->tf_rsp = ROUNDDOWN(stack_top, 16) - 8;
sw_tf->tf_rip = entry_pt;
sw_tf->tf_rbp = 0; /* for potential backtraces */
diff --git a/user/parlib/mcs.c b/user/parlib/mcs.c
index a2bea67..bd174ae 100644
--- a/user/parlib/mcs.c
+++ b/user/parlib/mcs.c
@@ -28,8 +28,8 @@
qnode->locked = 1;
wmb();
predecessor->next = qnode;
- /* no need for a wrmb(), since this will only get unlocked after they
- * read our previous write */
+ /* no need for a wrmb(), since this will only get unlocked after
+ * they read our previous write */
while (qnode->locked)
cpu_relax();
}
@@ -40,34 +40,38 @@
{
/* Check if someone is already waiting on us to unlock */
if (qnode->next == 0) {
- cmb(); /* no need for CPU mbs, since there's an atomic_swap() */
+ cmb(); /* no need for CPU mbs, since there's an atomic_swap() */
/* Unlock it */
mcs_lock_qnode_t *old_tail = mcs_qnode_swap(&lock->lock,0);
- /* no one else was already waiting, so we successfully unlocked and can
- * return */
+ /* no one else was already waiting, so we successfully unlocked
+ * and can return */
if (old_tail == qnode)
return;
- /* someone else was already waiting on the lock (last one on the list),
- * and we accidentally took them off. Try and put it back. */
+ /* someone else was already waiting on the lock (last one on the
+ * list), and we accidentally took them off. Try and put it
+ * back. */
mcs_lock_qnode_t *usurper = mcs_qnode_swap(&lock->lock,old_tail);
- /* since someone else was waiting, they should have made themselves our
- * next. spin (very briefly!) til it happens. */
+ /* since someone else was waiting, they should have made
+ * themselves our next. spin (very briefly!) til it happens. */
while (qnode->next == 0)
cpu_relax();
if (usurper) {
- /* an usurper is someone who snuck in before we could put the old
- * tail back. They now have the lock. Let's put whoever is
- * supposed to be next as their next one. */
+ /* an usurper is someone who snuck in before we could
+ * put the old tail back. They now have the lock.
+ * Let's put whoever is supposed to be next as their
+ * next one. */
usurper->next = qnode->next;
} else {
- /* No usurper meant we put things back correctly, so we should just
- * pass the lock / unlock whoever is next */
+ /* No usurper meant we put things back correctly, so we
+ * should just pass the lock / unlock whoever is next */
qnode->next->locked = 0;
}
} else {
/* mb()s necessary since we didn't call an atomic_swap() */
- wmb(); /* need to make sure any previous writes don't pass unlocking */
- rwmb(); /* need to make sure any reads happen before the unlocking */
+ /* need to make sure any previous writes don't pass unlocking */
+ wmb();
+ /* need to make sure any reads happen before the unlocking */
+ rwmb();
/* simply unlock whoever is next */
qnode->next->locked = 0;
}
@@ -80,12 +84,14 @@
/* Check if someone is already waiting on us to unlock */
if (qnode->next == 0) {
cmb(); /* no need for CPU mbs, since there's an atomic_cas() */
- /* If we're still the lock, just swap it with 0 (unlock) and return */
+ /* If we're still the lock, just swap it with 0 (unlock) and
+ * return */
if (atomic_cas_ptr((void**)&lock->lock, qnode, 0))
return;
- /* We failed, someone is there and we are some (maybe a different)
- * thread's pred. Since someone else was waiting, they should have made
- * themselves our next. Spin (very briefly!) til it happens. */
+ /* We failed, someone is there and we are some (maybe a
+ * different) thread's pred. Since someone else was waiting,
+ * they should have made themselves our next. Spin (very
+ * briefly!) til it happens. */
while (qnode->next == 0)
cpu_relax();
/* Alpha wants a read_barrier_depends() here */
@@ -93,8 +99,10 @@
qnode->next->locked = 0;
} else {
/* mb()s necessary since we didn't call an atomic_swap() */
- wmb(); /* need to make sure any previous writes don't pass unlocking */
- rwmb(); /* need to make sure any reads happen before the unlocking */
+ /* need to make sure any previous writes don't pass unlocking */
+ wmb();
+ /* need to make sure any reads happen before the unlocking */
+ rwmb();
/* simply unlock whoever is next */
qnode->next->locked = 0;
}
@@ -146,26 +154,27 @@
{
struct mcs_pdro_qnode *predecessor;
uint32_t pred_vcoreid;
- /* Now the actual lock */
+
qnode->next = 0;
cmb(); /* swap provides a CPU mb() */
predecessor = atomic_swap_ptr((void**)&lock->lock, qnode);
if (predecessor) {
qnode->locked = 1;
- /* Read-in the vcoreid before releasing them. We won't need to worry
- * about their qnode memory being freed/reused (they can't til we fill
- * in the 'next' slot), which is a bit of a performance win. This also
- * cuts down on cache-line contention when we ensure they run, which
- * helps a lot too. */
+ /* Read-in the vcoreid before releasing them. We won't need to
+ * worry about their qnode memory being freed/reused (they can't
+ * til we fill in the 'next' slot), which is a bit of a
+ * performance win. This also cuts down on cache-line
+ * contention when we ensure they run, which helps a lot too. */
pred_vcoreid = ACCESS_ONCE(predecessor->vcoreid);
wmb(); /* order the locked write before the next write */
predecessor->next = qnode;
- /* no need for a wrmb(), since this will only get unlocked after they
- * read our previous write */
+ /* no need for a wrmb(), since this will only get unlocked after
+ * they read our previous write */
while (qnode->locked) {
- /* We don't know who the lock holder is (it hurts performance via
- * 'true' sharing to track it) Instead we'll make sure our pred is
- * running, which trickles up to the lock holder. */
+ /* We don't know who the lock holder is (it hurts
+ * performance via 'true' sharing to track it) Instead
+ * we'll make sure our pred is running, which trickles
+ * up to the lock holder. */
ensure_vcore_runs(pred_vcoreid);
cpu_relax();
}
@@ -180,19 +189,23 @@
/* Check if someone is already waiting on us to unlock */
if (qnode->next == 0) {
cmb(); /* no need for CPU mbs, since there's an atomic_cas() */
- /* If we're still the lock, just swap it with 0 (unlock) and return */
+ /* If we're still the lock, just swap it with 0 (unlock) and
+ * return */
if (atomic_cas_ptr((void**)&lock->lock, qnode, 0))
return;
- /* Read in the tail (or someone who recently was the tail, but could now
- * be farther up the chain), in prep for our spinning. */
+ /* Read in the tail (or someone who recently was the tail, but
+ * could now be farther up the chain), in prep for our spinning.
+ */
a_tail_vcoreid = ACCESS_ONCE(lock->lock->vcoreid);
- /* We failed, someone is there and we are some (maybe a different)
- * thread's pred. Since someone else was waiting, they should have made
- * themselves our next. Spin (very briefly!) til it happens. */
+ /* We failed, someone is there and we are some (maybe a
+ * different) thread's pred. Since someone else was waiting,
+ * they should have made themselves our next. Spin (very
+ * briefly!) til it happens. */
while (qnode->next == 0) {
- /* We need to get our next to run, but we don't know who they are.
- * If we make sure a tail is running, that will percolate up to make
- * sure our qnode->next is running */
+ /* We need to get our next to run, but we don't know who
+ * they are. If we make sure a tail is running, that
+ * will percolate up to make sure our qnode->next is
+ * running */
ensure_vcore_runs(a_tail_vcoreid);
cpu_relax();
}
@@ -201,8 +214,10 @@
qnode->next->locked = 0;
} else {
/* mb()s necessary since we didn't call an atomic_swap() */
- wmb(); /* need to make sure any previous writes don't pass unlocking */
- rwmb(); /* need to make sure any reads happen before the unlocking */
+ /* need to make sure any previous writes don't pass unlocking */
+ wmb();
+ /* need to make sure any reads happen before the unlocking */
+ rwmb();
/* simply unlock whoever is next */
qnode->next->locked = 0;
}
@@ -233,53 +248,59 @@
struct mcs_pdro_qnode *qnode)
{
struct mcs_pdro_qnode *old_tail, *usurper;
+
/* Check if someone is already waiting on us to unlock */
if (qnode->next == 0) {
- cmb(); /* no need for CPU mbs, since there's an atomic_swap() */
+ cmb(); /* no need for CPU mbs, since there's an atomic_swap() */
/* Unlock it */
old_tail = atomic_swap_ptr((void**)&lock->lock, 0);
- /* no one else was already waiting, so we successfully unlocked and can
- * return */
+ /* no one else was already waiting, so we successfully unlocked
+ * and can return */
if (old_tail == qnode)
return;
- /* someone else was already waiting on the lock (last one on the list),
- * and we accidentally took them off. Try and put it back. */
+ /* someone else was already waiting on the lock (last one on the
+ * list), and we accidentally took them off. Try and put it
+ * back. */
usurper = atomic_swap_ptr((void*)&lock->lock, old_tail);
- /* since someone else was waiting, they should have made themselves our
- * next. spin (very briefly!) til it happens. */
+ /* since someone else was waiting, they should have made
+ * themselves our next. spin (very briefly!) til it happens. */
while (qnode->next == 0) {
- /* make sure old_tail isn't preempted. best we can do for now is
- * to make sure all vcores run, and thereby get our next. */
+ /* make sure old_tail isn't preempted. best we can do
+ * for now is to make sure all vcores run, and thereby
+ * get our next. */
for (int i = 0; i < max_vcores(); i++)
ensure_vcore_runs(i);
cpu_relax();
}
if (usurper) {
- /* an usurper is someone who snuck in before we could put the old
- * tail back. They now have the lock. Let's put whoever is
- * supposed to be next as their next one.
+ /* an usurper is someone who snuck in before we could
+ * put the old tail back. They now have the lock.
+ * Let's put whoever is supposed to be next as their
+ * next one.
*
- * First, we need to change our next's pred. There's a slight race
- * here, so our next will need to make sure both us and pred are
- * done */
- /* I was trying to do something so we didn't need to ensure all
- * vcores run, using more space in the qnode to figure out who our
- * pred was a lock time (guessing actually, since there's a race,
- * etc). */
+ * First, we need to change our next's pred. There's a
+ * slight race here, so our next will need to make sure
+ * both us and pred are done */
+ /* I was trying to do something so we didn't need to
+ * ensure all vcores run, using more space in the qnode
+ * to figure out who our pred was a lock time (guessing
+ * actually, since there's a race, etc). */
//qnode->next->pred = usurper;
//wmb();
usurper->next = qnode->next;
- /* could imagine another wmb() and a flag so our next knows to no
- * longer check us too. */
+ /* could imagine another wmb() and a flag so our next
+ * knows to no longer check us too. */
} else {
- /* No usurper meant we put things back correctly, so we should just
- * pass the lock / unlock whoever is next */
+ /* No usurper meant we put things back correctly, so we
+ * should just pass the lock / unlock whoever is next */
qnode->next->locked = 0;
}
} else {
/* mb()s necessary since we didn't call an atomic_swap() */
- wmb(); /* need to make sure any previous writes don't pass unlocking */
- rwmb(); /* need to make sure any reads happen before the unlocking */
+ /* need to make sure any previous writes don't pass unlocking */
+ wmb();
+ /* need to make sure any reads happen before the unlocking */
+ rwmb();
/* simply unlock whoever is next */
qnode->next->locked = 0;
}
@@ -298,6 +319,7 @@
void mcs_pdr_init(struct mcs_pdr_lock *lock)
{
int ret;
+
lock->lock = 0;
lock->lockholder_vcoreid = MCSPDR_NO_LOCKHOLDER;
ret = posix_memalign((void**)&lock->qnodes,
@@ -347,34 +369,40 @@
predecessor = atomic_swap_ptr((void**)&lock->lock, qnode);
if (predecessor) {
qnode->locked = 1;
- pred_vcoreid = predecessor - qnode0; /* can compute this whenever */
+ /* can compute this whenever */
+ pred_vcoreid = predecessor - qnode0;
wmb(); /* order the locked write before the next write */
predecessor->next = qnode;
seq = ACCESS_ONCE(__procinfo.coremap_seqctr);
- /* no need for a wrmb(), since this will only get unlocked after they
- * read our pred->next write */
+ /* no need for a wrmb(), since this will only get unlocked after
+ * they read our pred->next write */
while (qnode->locked) {
- /* Check to see if anything is amiss. If someone in the chain is
- * preempted, then someone will notice. Simply checking our pred
- * isn't that great of an indicator of preemption. The reason is
- * that the offline vcore is most likely the lockholder (under heavy
- * lock contention), and we want someone farther back in the chain
- * to notice (someone that will stay preempted long enough for a
- * vcore outside the chain to recover them). Checking the seqctr
- * will tell us of any preempts since we started, so if a storm
- * starts while we're spinning, we can join in and try to save the
+ /* Check to see if anything is amiss. If someone in the
+ * chain is preempted, then someone will notice. Simply
+ * checking our pred isn't that great of an indicator of
+ * preemption. The reason is that the offline vcore is
+ * most likely the lockholder (under heavy lock
+ * contention), and we want someone farther back in the
+ * chain to notice (someone that will stay preempted
+ * long enough for a vcore outside the chain to recover
+ * them). Checking the seqctr will tell us of any
+ * preempts since we started, so if a storm starts while
+ * we're spinning, we can join in and try to save the
* lockholder before its successor gets it.
*
- * Also, if we're the lockholder, then we need to let our pred run
- * so they can hand us the lock. */
+ * Also, if we're the lockholder, then we need to let
+ * our pred run so they can hand us the lock. */
if (vcore_is_preempted(pred_vcoreid) ||
seq != __procinfo.coremap_seqctr) {
- /* Note that we don't normally ensure our *pred* runs. */
- if (lock->lockholder_vcoreid == MCSPDR_NO_LOCKHOLDER ||
+ /* Note that we don't normally ensure our *pred*
+ * runs. */
+ if (lock->lockholder_vcoreid ==
+ MCSPDR_NO_LOCKHOLDER ||
lock->lockholder_vcoreid == vcore_id())
ensure_vcore_runs(pred_vcoreid);
else
- ensure_vcore_runs(lock->lockholder_vcoreid);
+ ensure_vcore_runs(
+ lock->lockholder_vcoreid);
}
cpu_relax();
}
@@ -387,33 +415,39 @@
{
uint32_t a_tail_vcoreid;
struct mcs_pdr_qnode *qnode0 = qnode - vcore_id();
+
/* Check if someone is already waiting on us to unlock */
if (qnode->next == 0) {
cmb(); /* no need for CPU mbs, since there's an atomic_cas() */
- /* If we're still the lock, just swap it with 0 (unlock) and return */
+ /* If we're still the lock, just swap it with 0 (unlock) and
+ * return */
if (atomic_cas_ptr((void**)&lock->lock, qnode, 0)) {
- /* This is racy with the new lockholder. it's possible that we'll
- * clobber their legit write, though it doesn't actually hurt
- * correctness. it'll get sorted out on the next unlock. */
+ /* This is racy with the new lockholder. it's possible
+ * that we'll clobber their legit write, though it
+ * doesn't actually hurt correctness. it'll get sorted
+ * out on the next unlock. */
lock->lockholder_vcoreid = MCSPDR_NO_LOCKHOLDER;
return;
}
- /* Get the tail (or someone who recently was the tail, but could now
- * be farther up the chain), in prep for our spinning. Could do an
- * ACCESS_ONCE on lock->lock */
+ /* Get the tail (or someone who recently was the tail, but could
+ * now be farther up the chain), in prep for our spinning.
+ * Could do an ACCESS_ONCE on lock->lock */
a_tail_vcoreid = lock->lock - qnode0;
- /* We failed, someone is there and we are some (maybe a different)
- * thread's pred. Since someone else was waiting, they should have made
- * themselves our next. Spin (very briefly!) til it happens. */
+ /* We failed, someone is there and we are some (maybe a
+ * different) thread's pred. Since someone else was waiting,
+ * they should have made themselves our next. Spin (very
+ * briefly!) til it happens. */
while (qnode->next == 0) {
- /* We need to get our next to run, but we don't know who they are.
- * If we make sure a tail is running, that will percolate up to make
- * sure our qnode->next is running.
+ /* We need to get our next to run, but we don't know who
+ * they are. If we make sure a tail is running, that
+ * will percolate up to make sure our qnode->next is
+ * running.
*
- * But first, we need to tell everyone that there is no specific
- * lockholder. lockholder_vcoreid is a short-circuit on the "walk
- * the chain" PDR. Normally, that's okay. But now we need to make
- * sure everyone is walking the chain from a_tail up to our pred. */
+ * But first, we need to tell everyone that there is no
+ * specific lockholder. lockholder_vcoreid is a
+ * short-circuit on the "walk the chain" PDR. Normally,
+ * that's okay. But now we need to make sure everyone
+ * is walking the chain from a_tail up to our pred. */
lock->lockholder_vcoreid = MCSPDR_NO_LOCKHOLDER;
ensure_vcore_runs(a_tail_vcoreid);
cpu_relax();
@@ -423,14 +457,16 @@
wmb(); /* order the vcoreid write before the unlock */
qnode->next->locked = 0;
} else {
- /* Note we're saying someone else is the lockholder, though we still are
- * the lockholder until we unlock the next qnode. Our next knows that
- * if it sees itself is the lockholder, that it needs to make sure we
- * run. */
+ /* Note we're saying someone else is the lockholder, though we
+ * still are the lockholder until we unlock the next qnode. Our
+ * next knows that if it sees itself is the lockholder, that it
+ * needs to make sure we run. */
lock->lockholder_vcoreid = qnode->next - qnode0;
/* mb()s necessary since we didn't call an atomic_swap() */
- wmb(); /* need to make sure any previous writes don't pass unlocking */
- rwmb(); /* need to make sure any reads happen before the unlocking */
+ /* need to make sure any previous writes don't pass unlocking */
+ wmb();
+ /* need to make sure any reads happen before the unlocking */
+ rwmb();
/* simply unlock whoever is next */
qnode->next->locked = 0;
}
diff --git a/user/parlib/mutex.c b/user/parlib/mutex.c
index 95dc7aa..430b8b1 100644
--- a/user/parlib/mutex.c
+++ b/user/parlib/mutex.c
@@ -13,9 +13,9 @@
#include <malloc.h>
struct timeout_blob {
- bool timed_out;
- struct uthread *uth;
- uth_sync_t *sync_ptr;
+ bool timed_out;
+ struct uthread *uth;
+ uth_sync_t *sync_ptr;
struct spin_pdr_lock *lock_ptr;
};
@@ -62,8 +62,9 @@
spin_pdr_init(&sem->lock);
__uth_sync_init(&sem->sync_obj);
- /* If we used a static initializer for a semaphore, count is already set.
- * o/w it will be set by _alloc() or _init() (via uth_semaphore_init()). */
+ /* If we used a static initializer for a semaphore, count is already
+ * set. o/w it will be set by _alloc() or _init() (via
+ * uth_semaphore_init()). */
}
/* Initializes a sem acquired from somewhere else. POSIX's sem_init() needs
@@ -103,8 +104,8 @@
struct uth_semaphore *sem = (struct uth_semaphore*)arg;
/* We need to tell the 2LS that its thread blocked. We need to do this
- * before unlocking the sem, since as soon as we unlock, the sem could be
- * released and our thread restarted.
+ * before unlocking the sem, since as soon as we unlock, the sem could
+ * be released and our thread restarted.
*
* Also note the lock-ordering rule. The sem lock is grabbed before any
* locks the 2LS might grab. */
@@ -123,9 +124,10 @@
parlib_run_once(&sem->once_ctl, __uth_semaphore_init, sem);
spin_pdr_lock(&sem->lock);
if (sem->count > 0) {
- /* Only down if we got one. This means a sem with no more counts is 0,
- * not negative (where -count == nr_waiters). Doing it this way means
- * our timeout function works for sems and CVs. */
+ /* Only down if we got one. This means a sem with no more
+ * counts is 0, not negative (where -count == nr_waiters).
+ * Doing it this way means our timeout function works for sems
+ * and CVs. */
sem->count--;
spin_pdr_unlock(&sem->lock);
return TRUE;
@@ -134,13 +136,13 @@
set_timeout_blob(blob, &sem->sync_obj, &sem->lock);
set_timeout_alarm(waiter, blob, abs_timeout);
}
- /* the unlock and sync enqueuing is done in the yield callback. as always,
- * we need to do this part in vcore context, since as soon as we unlock the
- * uthread could restart. (atomically yield and unlock). */
+ /* the unlock and sync enqueuing is done in the yield callback. as
+ * always, we need to do this part in vcore context, since as soon as we
+ * unlock the uthread could restart. (atomically yield and unlock). */
uthread_yield(TRUE, __semaphore_cb, sem);
if (abs_timeout) {
- /* We're guaranteed the alarm will either be cancelled or the handler
- * complete when unset_alarm() returns. */
+ /* We're guaranteed the alarm will either be cancelled or the
+ * handler complete when unset_alarm() returns. */
unset_alarm(waiter);
return blob->timed_out ? FALSE : TRUE;
}
@@ -171,7 +173,8 @@
{
struct uthread *uth;
- /* once-ing the 'up', unlike mtxs 'unlock', since sems can be special. */
+ /* once-ing the 'up', unlike mtxs 'unlock', since sems can be special.
+ */
parlib_run_once(&sem->once_ctl, __uth_semaphore_init, sem);
spin_pdr_lock(&sem->lock);
uth = __uth_sync_get_next(&sem->sync_obj);
@@ -251,9 +254,9 @@
struct uth_recurse_mutex *r_mtx = (struct uth_recurse_mutex*)arg;
__uth_mutex_init(&r_mtx->mtx);
- /* Since we always manually call __uth_mutex_init(), there's no reason to
- * mess with the regular mutex's static initializer. Just say it's been
- * done. */
+ /* Since we always manually call __uth_mutex_init(), there's no reason
+ * to mess with the regular mutex's static initializer. Just say it's
+ * been done. */
parlib_set_ran_once(&r_mtx->mtx.once_ctl);
r_mtx->lockholder = NULL;
r_mtx->count = 0;
@@ -272,7 +275,8 @@
uth_recurse_mutex_t *uth_recurse_mutex_alloc(void)
{
- struct uth_recurse_mutex *r_mtx = malloc(sizeof(struct uth_recurse_mutex));
+ struct uth_recurse_mutex *r_mtx =
+ malloc(sizeof(struct uth_recurse_mutex));
assert(r_mtx);
uth_recurse_mutex_init(r_mtx);
@@ -290,10 +294,10 @@
{
assert_can_block();
parlib_run_once(&r_mtx->once_ctl, __uth_recurse_mutex_init, r_mtx);
- /* We don't have to worry about races on current_uthread or count. They are
- * only written by the initial lockholder, and this check will only be true
- * for the initial lockholder, which cannot concurrently call this function
- * twice (a thread is single-threaded).
+ /* We don't have to worry about races on current_uthread or count. They
+ * are only written by the initial lockholder, and this check will only
+ * be true for the initial lockholder, which cannot concurrently call
+ * this function twice (a thread is single-threaded).
*
* A signal handler running for a thread should not attempt to grab a
* recursive mutex (that's probably a bug). If we need to support that,
@@ -401,15 +405,16 @@
__uth_sync_enqueue(uth, &cv->sync_obj);
spin_pdr_unlock(&cv->lock);
/* This looks dangerous, since both the CV and MTX could use the
- * uth->sync_next TAILQ_ENTRY (or whatever the 2LS uses), but the uthread
- * never sleeps on both at the same time. We *hold* the mtx - we aren't
- * *sleeping* on it. Sleeping uses the sync_next. Holding it doesn't.
+ * uth->sync_next TAILQ_ENTRY (or whatever the 2LS uses), but the
+ * uthread never sleeps on both at the same time. We *hold* the mtx -
+ * we aren't *sleeping* on it. Sleeping uses the sync_next. Holding it
+ * doesn't.
*
* Next, consider what happens as soon as we unlock the CV. Our thread
- * could get woken up, and then immediately try to grab the mtx and go to
- * sleep! (see below). If that happens, the uthread is no longer sleeping
- * on the CV, and the sync_next is free. The invariant is that a uthread
- * can only sleep on one sync_object at a time. */
+ * could get woken up, and then immediately try to grab the mtx and go
+ * to sleep! (see below). If that happens, the uthread is no longer
+ * sleeping on the CV, and the sync_next is free. The invariant is that
+ * a uthread can only sleep on one sync_object at a time. */
if (mtx)
uth_mutex_unlock(mtx);
}
@@ -432,14 +437,14 @@
* Note that signal/broadcasters do not *need* to hold the mutex, in general,
* but they do in the basic wake-up flag scenario. If not, the race is this:
*
- * Sleeper: Waker:
+ * Sleeper: Waker:
* -----------------------------------------------------------------
* Hold mutex
* See flag is False
* Decide to sleep
- * Set flag True
- * PAUSE! Grab CV lock
- * See list is empty, unlock
+ * Set flag True
+ * PAUSE! Grab CV lock
+ * See list is empty, unlock
*
* Grab CV lock
* Get put on list
@@ -481,8 +486,8 @@
struct timeout_blob blob[1];
bool ret = TRUE;
- /* We're holding the CV PDR lock, so we lose the ability to detect blocking
- * violations. */
+ /* We're holding the CV PDR lock, so we lose the ability to detect
+ * blocking violations. */
if (mtx)
assert_can_block();
parlib_run_once(&cv->once_ctl, __uth_cond_var_init, cv);
@@ -530,7 +535,8 @@
r_mtx->lockholder = NULL;
r_mtx->count = 0;
ret = uth_cond_var_timed_wait(cv, &r_mtx->mtx, abs_timeout);
- /* Now we hold the internal mutex again. Need to restore the tracking. */
+ /* Now we hold the internal mutex again. Need to restore the tracking.
+ */
r_mtx->lockholder = current_uthread;
r_mtx->count = old_count;
return ret;
diff --git a/user/parlib/net.c b/user/parlib/net.c
index 5e780d3..1a084ca 100644
--- a/user/parlib/net.c
+++ b/user/parlib/net.c
@@ -21,7 +21,7 @@
{
int ret, ctlfd, datafd, conv_id;
char *prefix;
- char *hostname; /* including !port */
+ char *hostname; /* including !port */
size_t buf_len = strlen(addr) + 30; /* 30 should be enough extra */
char *buf = malloc(buf_len);
if (!buf) {
diff --git a/user/parlib/panic.c b/user/parlib/panic.c
index f82d542..65a913d 100644
--- a/user/parlib/panic.c
+++ b/user/parlib/panic.c
@@ -11,16 +11,16 @@
return;
/* This isn't ideal, since it might affect some stdout streams where our
* parent tried to do something else. Note that isatty() always returns
- * TRUE, due to how we fake tcgetattr(), and that doesn't affect whatever
- * our shells are doing to set us up. */
+ * TRUE, due to how we fake tcgetattr(), and that doesn't affect
+ * whatever our shells are doing to set us up. */
setlinebuf(stdout);
}
static void __attribute__((noreturn)) fatal_backtrace(void)
{
/* This will cause the kernel to print out a backtrace to the console.
- * Short of reading /proc/self/maps or other stuff, userspace would have a
- * hard time backtracing itself. */
+ * Short of reading /proc/self/maps or other stuff, userspace would have
+ * a hard time backtracing itself. */
breakpoint();
abort();
}
diff --git a/user/parlib/parlib.c b/user/parlib/parlib.c
index d4dd71a..4f06efe 100644
--- a/user/parlib/parlib.c
+++ b/user/parlib/parlib.c
@@ -28,10 +28,11 @@
return kid;
/* Here's how we avoid infinite recursion. We can only have ENOENT the
- * first time through without bailing out, since all errno paths set exe to
- * begin with '/'. That includes calls from ENOEXEC, since sh_path begins
- * with /. To avoid repeated calls to ENOEXEC, we just look for sh_path as
- * the exe, so if we have consecutive ENOEXECs, we'll bail out. */
+ * first time through without bailing out, since all errno paths set exe
+ * to begin with '/'. That includes calls from ENOEXEC, since sh_path
+ * begins with /. To avoid repeated calls to ENOEXEC, we just look for
+ * sh_path as the exe, so if we have consecutive ENOEXECs, we'll bail
+ * out. */
switch (errno) {
case ENOENT:
if (exe[0] == '/')
@@ -49,17 +50,17 @@
/* In case someone replaces /bin/sh with a non-elf. */
if (!strcmp(sh_path, exe))
return -1;
- /* We want enough space for the original argv, plus one entry at the
- * front for sh_path. When we grab the original argv, we also need the
- * trailing NULL, which is at argv[argc]. That means we really want
- * argc + 1 entries from argv. */
+ /* We want enough space for the original argv, plus one entry at
+ * the front for sh_path. When we grab the original argv, we
+ * also need the trailing NULL, which is at argv[argc]. That
+ * means we really want argc + 1 entries from argv. */
sh_argv = malloc(sizeof(char *) * (argc + 2));
if (!sh_argv)
return -1;
memcpy(&sh_argv[1], argv, sizeof(char *) * (argc + 1));
sh_argv[0] = (char*)sh_path;
- /* Replace the original argv[0] with the path to exe, which might have
- * been edited to include /bin/ */
+ /* Replace the original argv[0] with the path to exe, which
+ * might have been edited to include /bin/ */
sh_argv[1] = (char*)exe;
kid = create_child(sh_path, argc + 1, sh_argv, envp);
free(sh_argv);
diff --git a/user/parlib/poke.c b/user/parlib/poke.c
index da97be0..ba70b44 100644
--- a/user/parlib/poke.c
+++ b/user/parlib/poke.c
@@ -37,30 +37,35 @@
atomic_set(&tracker->need_to_run, TRUE);
/* will need to repeatedly do it if someone keeps posting work */
do {
- /* want an wrmb() btw posting work/need_to_run and in_progress. the
- * swap provides the HW mb. just need a cmb, which we do in the loop to
- * cover the iterations (even though i can't imagine the compiler
- * reordering the check it needed to do for the branch).. */
+ /* want an wrmb() btw posting work/need_to_run and in_progress.
+ * the swap provides the HW mb. just need a cmb, which we do in
+ * the loop to cover the iterations (even though i can't imagine
+ * the compiler reordering the check it needed to do for the
+ * branch).. */
cmb();
- /* poke / make sure someone does it. if we get a TRUE (1) back, someone
- * is already running and will deal with the posted work. (probably on
- * their next loop). if we got a 0 back, we won the race and have the
- * 'lock'. */
+ /* poke / make sure someone does it. if we get a TRUE (1) back,
+ * someone is already running and will deal with the posted
+ * work. (probably on their next loop). if we got a 0 back, we
+ * won the race and have the 'lock'. */
if (atomic_swap(&tracker->run_in_progress, TRUE))
return;
- /* if we're here, then we're the one who needs to run the func. */
- /* clear the 'need to run', since we're running it now. new users will
- * set it again. this write needs to be wmb()'d after in_progress. the
- * swap provided the HW mb(). */
+ /* if we're here, then we're the one who needs to run the func.
+ * */
+ /* clear the 'need to run', since we're running it now. new
+ * users will set it again. this write needs to be wmb()'d
+ * after in_progress. the swap provided the HW mb(). */
cmb();
- atomic_set(&tracker->need_to_run, FALSE); /* no internal HW mb */
- /* run the actual function. the poke sync makes sure only one caller is
- * in that func at a time. */
+ /* no internal HW mb */
+ atomic_set(&tracker->need_to_run, FALSE);
+ /* run the actual function. the poke sync makes sure only one
+ * caller is in that func at a time. */
assert(tracker->func);
tracker->func(arg);
- wmb(); /* ensure the in_prog write comes after the run_again. */
- atomic_set(&tracker->run_in_progress, FALSE); /* no internal HW mb */
+ /* ensure the in_prog write comes after the run_again. */
+ wmb();
+ /* no internal HW mb */
+ atomic_set(&tracker->run_in_progress, FALSE);
/* in_prog write must come before run_again read */
wrmb();
- } while (atomic_read(&tracker->need_to_run)); /* while there's more work*/
+ } while (atomic_read(&tracker->need_to_run));
}
diff --git a/user/parlib/printf-ext.c b/user/parlib/printf-ext.c
index db59e5e..bb51f5d 100644
--- a/user/parlib/printf-ext.c
+++ b/user/parlib/printf-ext.c
@@ -6,7 +6,7 @@
* (in early init code), and the others need to be requested.
*
* To register, for example %i for ipaddr, call:
- * register_printf_specifier('i', printf_ipaddr, printf_ipaddr_info);
+ * register_printf_specifier('i', printf_ipaddr, printf_ipaddr_info);
*
* __printf_ipaddr, printf_ipmask, and printf_ethaddr adapted from Inferno's
* eipconvtest.c. Their copyright:
@@ -105,7 +105,8 @@
argtypes[0] = PA_POINTER;
size[0] = sizeof(uint8_t*);
}
- /* returns the nr of args required by the format string, no matter what */
+ /* returns the nr of args required by the format string, no matter what
+ */
return 1;
}
@@ -160,10 +161,11 @@
const void *const *args)
{
uint8_t *e = *(uint8_t**)args[0];
+
if (!e)
e = "\0\0\0\0\0\0";
- return fprintf(stream, "%02x:%02x:%02x:%02x:%02x:%02x", e[0], e[1], e[2],
- e[3], e[4], e[5]);
+ return fprintf(stream, "%02x:%02x:%02x:%02x:%02x:%02x",
+ e[0], e[1], e[2], e[3], e[4], e[5]);
}
int printf_ethaddr_info(const struct printf_info* info, size_t n, int *argtypes,
diff --git a/user/parlib/pvcalarm.c b/user/parlib/pvcalarm.c
index 698adc3..3609134 100644
--- a/user/parlib/pvcalarm.c
+++ b/user/parlib/pvcalarm.c
@@ -69,7 +69,8 @@
global_pvcalarm.handler = NULL;
/* Preemptively setup timers for all possible vcores */
- global_pvcalarm.data = malloc(max_vcores() * sizeof(struct pvcalarm_data));
+ global_pvcalarm.data = malloc(max_vcores() *
+ sizeof(struct pvcalarm_data));
for (int i=0; i<max_vcores(); i++) {
init_pvcalarm(&global_pvcalarm.data[i], i);
}
@@ -136,7 +137,8 @@
/* Start the timer on all vcores to go off after interval usecs */
for (int i=0; i<max_vcores(); i++) {
- start_pvcalarm(&global_pvcalarm.data[i], global_pvcalarm.interval);
+ start_pvcalarm(&global_pvcalarm.data[i],
+ global_pvcalarm.interval);
}
atomic_set(&global_pvcalarm.state, S_ENABLED);
@@ -196,8 +198,8 @@
perror("Pvcalarm: Failed to set evq");
return;
}
- /* now the alarm is all set, just need to write the timer whenever we want
- * it to go off. */
+ /* now the alarm is all set, just need to write the timer whenever we
+ * want it to go off. */
pvcalarm_data->alarmid = alarmid;
pvcalarm_data->ctlfd = ctlfd;
pvcalarm_data->timerfd = timerfd;
@@ -215,7 +217,8 @@
int state;
assert(in_vcore_context());
__sync_fetch_and_add(&global_pvcalarm.busy_count, 1);
- cmb(); /* order the state read after the incref. __sync provides cpu mb */
+ /* order the state read after the incref. __sync provides cpu mb */
+ cmb();
state = atomic_read(&global_pvcalarm.state);
if (state == S_DISABLED || state == S_DISABLING)
goto disabled;
@@ -252,7 +255,8 @@
void *data)
{
global_pvcalarm.callback();
- start_pvcalarm(&global_pvcalarm.data[vcore_id()], global_pvcalarm.interval);
+ start_pvcalarm(&global_pvcalarm.data[vcore_id()],
+ global_pvcalarm.interval);
}
/* The pvcalarm handler for the PROF policy. Account for any time the vcore
diff --git a/user/parlib/riscv/vcore.c b/user/parlib/riscv/vcore.c
index c08130d..02c4bac 100644
--- a/user/parlib/riscv/vcore.c
+++ b/user/parlib/riscv/vcore.c
@@ -13,10 +13,11 @@
#ifndef __x86_64__
set_tls_desc(vcpd_of(id)->vcore_tls_desc);
#endif
- /* Every time the vcore comes up, it must set that it is in vcore context.
- * uthreads may share the same TLS as their vcore (when uthreads do not have
- * their own TLS), and if a uthread was preempted, __vcore_context == FALSE,
- * and that will continue to be true the next time the vcore pops up. */
+ /* Every time the vcore comes up, it must set that it is in vcore
+ * context. uthreads may share the same TLS as their vcore (when
+ * uthreads do not have their own TLS), and if a uthread was preempted,
+ * __vcore_context == FALSE, and that will continue to be true the next
+ * time the vcore pops up. */
__vcore_context = TRUE;
vcore_entry();
fprintf(stderr, "vcore_entry() should never return!\n");
diff --git a/user/parlib/signal.c b/user/parlib/signal.c
index 34d4acc..4fee3fe 100644
--- a/user/parlib/signal.c
+++ b/user/parlib/signal.c
@@ -7,22 +7,22 @@
* will get this mixed in. Mostly just registration of signal handlers.
*
* POSIX signal handling caveats:
- * - We don't copy signal handling tables or anything across forks or execs
- * - We don't send meaningful info in the siginfos, nor do we pass pid/uids on
- * signals coming from a kill. This is especially pertinent for sigqueue,
- * which needs a payload (value) and sending PID
- * - We run handlers in vcore context, so any blocking syscall will spin.
- * Regular signals have restrictions on their syscalls too, though not this
- * great. We could spawn off a uthread to run the handler, given that we have
- * a 2LS (which we don't for SCPs).
- * - We don't do anything with signal blocking/masking. When in a signal
- * handler, you won't get interrupted with another signal handler (so long as
- * you run it in vcore context!). With uthreads, you could get interrupted.
- * There is also no process wide signal blocking yet (sigprocmask()). If this
- * is desired, we can abort certain signals when we h_p_signal(),
- * - Likewise, we don't do waiting for particular signals yet. Just about the
- * only thing we do is allow the registration of signal handlers.
- * - Check each function for further notes. */
+ * - We don't copy signal handling tables or anything across forks or execs
+ * - We don't send meaningful info in the siginfos, nor do we pass pid/uids on
+ * signals coming from a kill. This is especially pertinent for sigqueue,
+ * which needs a payload (value) and sending PID
+ * - We run handlers in vcore context, so any blocking syscall will spin.
+ * Regular signals have restrictions on their syscalls too, though not this
+ * great. We could spawn off a uthread to run the handler, given that we have
+ * a 2LS (which we don't for SCPs).
+ * - We don't do anything with signal blocking/masking. When in a signal
+ * handler, you won't get interrupted with another signal handler (so long as
+ * you run it in vcore context!). With uthreads, you could get interrupted.
+ * There is also no process wide signal blocking yet (sigprocmask()). If this
+ * is desired, we can abort certain signals when we h_p_signal(),
+ * - Likewise, we don't do waiting for particular signals yet. Just about the
+ * only thing we do is allow the registration of signal handlers.
+ * - Check each function for further notes. */
// Needed for sigmask functions...
#define _GNU_SOURCE
@@ -90,14 +90,16 @@
assert(ev_msg);
sig_nr = ev_msg->ev_arg1;
/* We're handling a process-wide signal, but signal handlers will want a
- * user context. They operate on the model that some thread got the signal,
- * but that didn't happen on Akaros. If we happen to have a current
- * uthread, we can use that - perhaps that's what the user wants. If not,
- * we'll build a fake one representing our current call stack. */
+ * user context. They operate on the model that some thread got the
+ * signal, but that didn't happen on Akaros. If we happen to have a
+ * current uthread, we can use that - perhaps that's what the user
+ * wants. If not, we'll build a fake one representing our current call
+ * stack. */
if (current_uthread) {
trigger_posix_signal(sig_nr, &info, get_cur_uth_ctx());
} else {
- init_user_ctx(&fake_uctx, (uintptr_t)handle_event, get_stack_pointer());
+ init_user_ctx(&fake_uctx, (uintptr_t)handle_event,
+ get_stack_pointer());
trigger_posix_signal(sig_nr, &info, &fake_uctx);
}
}
@@ -167,16 +169,19 @@
case ROS_HW_CTX:
case ROS_VM_CTX:
assert(uthread->flags & UTHREAD_FPSAVED);
- /* We need to save the already-saved FP state into the sigstate space.
- * The sig handler is taking over the uthread and its GP and FP spaces.
+ /* We need to save the already-saved FP state into the sigstate
+ * space. The sig handler is taking over the uthread and its GP
+ * and FP spaces.
*
- * If we ever go back to not aggressively saving the FP state, then for
- * HW and VM ctxs, the state is in hardware. Regardless, we still need
- * to save it in ->as, with something like:
- * save_fp_state(&uthread->sigstate.data->as);
- * Either way, when we're done with this entire function, the *uthread*
- * will have ~UTHREAD_FPSAVED, since we will be talking about the SW
- * context that is running the signal handler. */
+ * If we ever go back to not aggressively saving the FP state,
+ * then for HW and VM ctxs, the state is in hardware.
+ * Regardless, we still need to save it in ->as, with something
+ * like: save_fp_state(&uthread->sigstate.data->as);
+ *
+ * Either way, when we're done with this entire function, the
+ * *uthread* will have ~UTHREAD_FPSAVED, since we will be
+ * talking about the SW context that is running the signal
+ * handler. */
uthread->sigstate.data->as = uthread->as;
uthread->flags &= ~UTHREAD_FPSAVED;
break;
@@ -191,9 +196,9 @@
stack = uthread->sigstate.sigalt_stacktop;
init_user_ctx(&uthread->sigstate.data->u_ctx, (uintptr_t)entry, stack);
- /* The uthread may or may not be UTHREAD_SAVED. That depends on whether the
- * uthread was in that state initially. We're swapping into the location of
- * 'ctx', which is either in VCPD or the uth itself. */
+ /* The uthread may or may not be UTHREAD_SAVED. That depends on whether
+ * the uthread was in that state initially. We're swapping into the
+ * location of 'ctx', which is either in VCPD or the uth itself. */
swap_user_contexts(ctx, &uthread->sigstate.data->u_ctx);
}
@@ -249,7 +254,8 @@
for (int i = 1; i < _NSIG; i++) {
if (__sigismember(&andset, i)) {
__sigdelset(&uthread->sigstate.pending, i);
- trigger_posix_signal(i, NULL, &uthread->sigstate.data->u_ctx);
+ trigger_posix_signal(i, NULL,
+ &uthread->sigstate.data->u_ctx);
}
}
uthread_yield(FALSE, __exit_sighandler_cb, 0);
@@ -287,8 +293,10 @@
struct siginfo info = {0};
if (uth_is_handling_sigs(uthread)) {
- printf("Uthread sighandler faulted, signal: %d\n", signo);
- /* uthread.c already copied out the faulting ctx into the uth */
+ printf("Uthread sighandler faulted, signal: %d\n",
+ signo);
+ /* uthread.c already copied out the faulting ctx into
+ * the uth */
print_user_context(&uthread->u_ctx);
exit(-1);
}
@@ -339,12 +347,12 @@
{
sigset_t *sigmask;
- /* Signal handlers might call sigprocmask, with the intent of affecting the
- * uthread's sigmask. Process-wide signal handlers run on behalf of the
- * entire process and aren't bound to a uthread, which means sigprocmask
- * won't work. We can tell we're running one of these handlers since we are
- * in vcore context. Uthread signals (e.g. pthread_kill()) run from uthread
- * context. */
+ /* Signal handlers might call sigprocmask, with the intent of affecting
+ * the uthread's sigmask. Process-wide signal handlers run on behalf of
+ * the entire process and aren't bound to a uthread, which means
+ * sigprocmask won't work. We can tell we're running one of these
+ * handlers since we are in vcore context. Uthread signals (e.g.
+ * pthread_kill()) run from uthread context. */
if (in_vcore_context()) {
errno = ENOENT;
return -1;
diff --git a/user/parlib/slab.c b/user/parlib/slab.c
index 7d31652..385e2bb 100644
--- a/user/parlib/slab.c
+++ b/user/parlib/slab.c
@@ -77,15 +77,18 @@
* kmem_cache_cache. */
__kmem_cache_create(&kmem_cache_cache, "kmem_cache",
sizeof(struct kmem_cache),
- __alignof__(struct kmem_cache), 0, NULL, NULL, NULL);
+ __alignof__(struct kmem_cache), 0, NULL, NULL,
+ NULL);
/* Build the slab and bufctl caches */
kmem_slab_cache = kmem_cache_alloc(&kmem_cache_cache, 0);
- __kmem_cache_create(kmem_slab_cache, "kmem_slab", sizeof(struct kmem_slab),
+ __kmem_cache_create(kmem_slab_cache, "kmem_slab",
+ sizeof(struct kmem_slab),
__alignof__(struct kmem_slab), 0, NULL, NULL, NULL);
kmem_bufctl_cache = kmem_cache_alloc(&kmem_cache_cache, 0);
__kmem_cache_create(kmem_bufctl_cache, "kmem_bufctl",
sizeof(struct kmem_bufctl),
- __alignof__(struct kmem_bufctl), 0, NULL, NULL, NULL);
+ __alignof__(struct kmem_bufctl), 0, NULL, NULL,
+ NULL);
}
/* Cache management */
@@ -120,10 +123,11 @@
struct kmem_bufctl *i;
void *page_start = (void*)-1;
/* compute how many pages are allocated, same as in grow */
- size_t nr_pgs = ROUNDUP(NUM_BUF_PER_SLAB * a_slab->obj_size, PGSIZE) /
- PGSIZE;
+ size_t nr_pgs = ROUNDUP(NUM_BUF_PER_SLAB * a_slab->obj_size,
+ PGSIZE) / PGSIZE;
TAILQ_FOREACH(i, &a_slab->bufctl_freelist, link) {
- // Track the lowest buffer address, which is the start of the buffer
+ // Track the lowest buffer address, which is the start
+ // of the buffer
page_start = MIN(page_start, i->buf_addr);
/* Deconstruct all the objects, if necessary */
if (cp->dtor) // TODO: (BUF)
@@ -146,9 +150,9 @@
spin_pdr_lock(&cp->cache_lock);
assert(TAILQ_EMPTY(&cp->full_slab_list));
assert(TAILQ_EMPTY(&cp->partial_slab_list));
- /* Clean out the empty list. We can't use a regular FOREACH here, since the
- * link element is stored in the slab struct, which is stored on the page
- * that we are freeing. */
+ /* Clean out the empty list. We can't use a regular FOREACH here, since
+ * the link element is stored in the slab struct, which is stored on the
+ * page that we are freeing. */
a_slab = TAILQ_FIRST(&cp->empty_slab_list);
while (a_slab) {
next = TAILQ_NEXT(a_slab, link);
@@ -169,6 +173,7 @@
spin_pdr_lock(&cp->cache_lock);
// look at partial list
struct kmem_slab *a_slab = TAILQ_FIRST(&cp->partial_slab_list);
+
// if none, go to empty list and get an empty and make it partial
if (!a_slab) {
if (TAILQ_EMPTY(&cp->empty_slab_list))
@@ -182,13 +187,14 @@
// have a partial now (a_slab), get an item, return item
if (cp->obj_size <= SLAB_LARGE_CUTOFF) {
retval = a_slab->free_small_obj;
- /* adding the size of the cache_obj to get to the pointer at end of the
- * buffer pointing to the next free_small_obj */
+ /* adding the size of the cache_obj to get to the pointer at end
+ * of the buffer pointing to the next free_small_obj */
a_slab->free_small_obj = *(uintptr_t**)(a_slab->free_small_obj +
cp->obj_size);
} else {
// rip the first bufctl out of the partial slab's buf list
- struct kmem_bufctl *a_bufctl = TAILQ_FIRST(&a_slab->bufctl_freelist);
+ struct kmem_bufctl *a_bufctl =
+ TAILQ_FIRST(&a_slab->bufctl_freelist);
TAILQ_REMOVE(&a_slab->bufctl_freelist, a_bufctl, link);
retval = a_bufctl->buf_addr;
}
@@ -219,8 +225,8 @@
// find its slab
a_slab = (struct kmem_slab*)(ROUNDDOWN((uintptr_t)buf, PGSIZE) +
PGSIZE - sizeof(struct kmem_slab));
- /* write location of next free small obj to the space at the end of the
- * buffer, then list buf as the next free small obj */
+ /* write location of next free small obj to the space at the end
+ * of the buffer, then list buf as the next free small obj */
*(uintptr_t**)(buf + cp->obj_size) = a_slab->free_small_obj;
a_slab->free_small_obj = buf;
} else {
@@ -262,28 +268,34 @@
if (cp->obj_size <= SLAB_LARGE_CUTOFF) {
// Just get a single page for small slabs
a_page = mmap(0, PGSIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE, -1,
+ 0);
assert(a_page != MAP_FAILED);
// the slab struct is stored at the end of the page
a_slab = (struct kmem_slab*)(a_page + PGSIZE -
sizeof(struct kmem_slab));
- // Need to add room for the next free item pointer in the object buffer.
- a_slab->obj_size = ROUNDUP(cp->obj_size + sizeof(uintptr_t), cp->align);
+ // Need to add room for the next free item pointer in the object
+ // buffer.
+ a_slab->obj_size = ROUNDUP(cp->obj_size + sizeof(uintptr_t),
+ cp->align);
a_slab->num_busy_obj = 0;
a_slab->num_total_obj = (PGSIZE - sizeof(struct kmem_slab)) /
a_slab->obj_size;
// TODO: consider staggering this IAW section 4.3
a_slab->free_small_obj = a_page;
- /* Walk and create the free list, which is circular. Each item stores
- * the location of the next one at the end of the block. */
+ /* Walk and create the free list, which is circular. Each item
+ * stores the location of the next one at the end of the block.
+ */
void *buf = a_slab->free_small_obj;
+
for (int i = 0; i < a_slab->num_total_obj - 1; i++) {
// Initialize the object, if necessary
if (cp->ctor) {
ctor_ret = cp->ctor(buf, cp->priv, 0);
assert(!ctor_ret);
}
- *(uintptr_t**)(buf + cp->obj_size) = buf + a_slab->obj_size;
+ *(uintptr_t**)(buf + cp->obj_size) = buf +
+ a_slab->obj_size;
buf += a_slab->obj_size;
}
/* Initialize the final object (note the -1 in the for loop). */
@@ -295,14 +307,17 @@
} else {
a_slab = kmem_cache_alloc(kmem_slab_cache, 0);
// TODO: hash table for back reference (BUF)
- a_slab->obj_size = ROUNDUP(cp->obj_size + sizeof(uintptr_t), cp->align);
- /* Need at least nr_pgs to hold NUM_BUF objects. Note we don't round up
- * to the next higher order (power of 2) number of pages, like we do in
- * the kernel. */
- size_t nr_pgs = ROUNDUP(NUM_BUF_PER_SLAB * a_slab->obj_size, PGSIZE) /
- PGSIZE;
- void *buf = mmap(0, nr_pgs * PGSIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ a_slab->obj_size = ROUNDUP(cp->obj_size + sizeof(uintptr_t),
+ cp->align);
+ /* Need at least nr_pgs to hold NUM_BUF objects. Note we don't
+ * round up to the next higher order (power of 2) number of
+ * pages, like we do in the kernel. */
+ size_t nr_pgs = ROUNDUP(NUM_BUF_PER_SLAB * a_slab->obj_size,
+ PGSIZE) / PGSIZE;
+ void *buf = mmap(0, nr_pgs * PGSIZE, PROT_READ | PROT_WRITE |
+ PROT_EXEC, MAP_POPULATE | MAP_ANONYMOUS |
+ MAP_PRIVATE, -1, 0);
+
assert(buf != MAP_FAILED);
a_slab->num_busy_obj = 0;
a_slab->num_total_obj = nr_pgs * PGSIZE / a_slab->obj_size;
@@ -315,10 +330,12 @@
assert(!ctor_ret);
}
a_bufctl = kmem_cache_alloc(kmem_bufctl_cache, 0);
- TAILQ_INSERT_HEAD(&a_slab->bufctl_freelist, a_bufctl, link);
+ TAILQ_INSERT_HEAD(&a_slab->bufctl_freelist, a_bufctl,
+ link);
a_bufctl->buf_addr = buf;
a_bufctl->my_slab = a_slab;
- // TODO: (BUF) write the bufctl reference at the bottom of the buffer.
+ // TODO: (BUF) write the bufctl reference at the bottom
+ // of the buffer.
*(struct kmem_bufctl**)(buf + cp->obj_size) = a_bufctl;
buf += a_slab->obj_size;
}
@@ -372,8 +389,8 @@
printf("Free Small obj: 0x%08x\n", slab->free_small_obj);
void *buf = slab->free_small_obj;
for (int i = 0; i < slab->num_total_obj; i++) {
- printf("Addr of buf: 0x%08x, Addr of next: 0x%08x\n", buf,
- *((uintptr_t**)buf));
+ printf("Addr of buf: 0x%08x, Addr of next: 0x%08x\n",
+ buf, *((uintptr_t**)buf));
buf += slab->obj_size;
}
} else {
diff --git a/user/parlib/spinlock.c b/user/parlib/spinlock.c
index a833ab8..6efe50e 100644
--- a/user/parlib/spinlock.c
+++ b/user/parlib/spinlock.c
@@ -68,7 +68,7 @@
{
/* could make an arch-dependent 'release barrier' out of these */
wmb(); /* Need to prevent the compiler from reordering older stores. */
- rwmb(); /* And no old reads passing either. x86 makes both mbs a cmb() */
+ rwmb(); /* No old reads passing either. x86 makes both mbs a cmb() */
pdr_lock->lock = SPINPDR_UNLOCKED;
}
diff --git a/user/parlib/syscall.c b/user/parlib/syscall.c
index aaf3a1c..4e18d51 100644
--- a/user/parlib/syscall.c
+++ b/user/parlib/syscall.c
@@ -18,15 +18,13 @@
int sys_null(void)
{
- return ros_syscall(SYS_null, 0, 0, 0, 0, 0, 0);
+ return ros_syscall(SYS_null, 0, 0, 0, 0, 0, 0);
}
-ssize_t sys_shared_page_alloc(void** addr, pid_t p2,
- int p1_flags, int p2_flags
- )
+ssize_t sys_shared_page_alloc(void** addr, pid_t p2, int p1_flags, int p2_flags)
{
- return ros_syscall(SYS_shared_page_alloc, addr,
- p2, p1_flags, p2_flags, 0, 0);
+ return ros_syscall(SYS_shared_page_alloc, addr, p2, p1_flags, p2_flags,
+ 0, 0);
}
ssize_t sys_shared_page_free(void* addr, pid_t p2)
@@ -48,6 +46,7 @@
char *const envp[], int flags)
{
struct serialized_data *sd = serialize_argv_envp(argv, envp);
+
if (!sd) {
errno = ENOMEM;
return -1;
@@ -63,10 +62,11 @@
return ros_syscall(SYS_proc_run, pid, 0, 0, 0, 0, 0);
}
-void *sys_mmap(void *addr, size_t length, int prot, int flags,
- int fd, size_t offset)
+void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
+ size_t offset)
{
- return (void*)ros_syscall(SYS_mmap, addr, length, prot, flags, fd, offset);
+ return (void*)ros_syscall(SYS_mmap, addr, length, prot, flags, fd,
+ offset);
}
int sys_provision(int pid, unsigned int res_type, long res_val)
@@ -82,7 +82,8 @@
int sys_self_notify(uint32_t vcoreid, unsigned int ev_type,
struct event_msg *u_msg, bool priv)
{
- return ros_syscall(SYS_self_notify, vcoreid, ev_type, u_msg, priv, 0, 0);
+ return ros_syscall(SYS_self_notify, vcoreid, ev_type, u_msg, priv, 0,
+ 0);
}
int sys_send_event(struct event_queue *ev_q, struct event_msg *ev_msg,
@@ -96,7 +97,7 @@
return ros_syscall(SYS_halt_core, usec, 0, 0, 0, 0, 0);
}
-void* sys_init_arsc()
+void *sys_init_arsc()
{
return (void*)ros_syscall(SYS_init_arsc, 0, 0, 0, 0, 0, 0);
}
@@ -114,26 +115,28 @@
* example of this is in mcs_pdr_locks.
*
* Will return:
- * 0 if we successfully changed to the target vcore.
- * -EBUSY if the target vcore is already mapped (a good kind of failure)
- * -EAGAIN if we failed for some other reason and need to try again. For
- * example, the caller could be preempted, and we never even attempted to
- * change.
- * -EINVAL some userspace bug */
+ * 0 if we successfully changed to the target vcore.
+ * -EBUSY if the target vcore is already mapped (a good kind of failure)
+ * -EAGAIN if we failed for some other reason and need to try again. For
+ * example, the caller could be preempted, and we never even attempted to
+ * change.
+ * -EINVAL some userspace bug */
int sys_change_vcore(uint32_t vcoreid, bool enable_my_notif)
{
/* Since we might be asking to start up on a fresh stack (if
* enable_my_notif), we need to use some non-stack memory for the struct
- * sysc. Our vcore could get restarted before the syscall finishes (after
- * unlocking the proc, before finish_sysc()), and the act of finishing would
- * write onto our stack. Thus we use the per-vcore struct. */
+ * sysc. Our vcore could get restarted before the syscall finishes
+ * (after unlocking the proc, before finish_sysc()), and the act of
+ * finishing would write onto our stack. Thus we use the per-vcore
+ * struct. */
int flags;
- /* Sanity check. Uthreads can call this, but only when notifs disabled. */
+ /* Sanity check. Uthreads can call this, but only when notifs disabled.
+ */
assert(!notif_is_enabled(vcore_id()));
- /* Need to wait while a previous syscall is not done or locked. Since this
- * should only be called from VC ctx, we'll just spin. Should be extremely
- * rare. Note flags is initialized to SC_DONE. */
+ /* Need to wait while a previous syscall is not done or locked. Since
+ * this should only be called from VC ctx, we'll just spin. Should be
+ * extremely rare. Note flags is initialized to SC_DONE. */
do {
cpu_relax();
flags = atomic_read(&__vcore_one_sysc.flags);
@@ -144,8 +147,8 @@
/* keep in sync with glibc sysdeps/ros/syscall.c */
__ros_arch_syscall((long)&__vcore_one_sysc, 1);
/* If we returned, either we wanted to (!enable_my_notif) or we failed.
- * Need to wait til the sysc is finished to find out why. Again, its okay
- * to just spin. */
+ * Need to wait til the sysc is finished to find out why. Again, its
+ * okay to just spin. */
do {
cpu_relax();
flags = atomic_read(&__vcore_one_sysc.flags);
@@ -185,8 +188,8 @@
sysc->num = num;
sysc->flags = 0;
sysc->ev_q = 0; /* not necessary, but good for debugging */
- /* This is a little dangerous, since we'll usually pull more args than were
- * passed in, ultimately reading gibberish off the stack. */
+ /* This is a little dangerous, since we'll usually pull more args than
+ * were passed in, ultimately reading gibberish off the stack. */
va_start(args, num);
sysc->arg0 = va_arg(args, long);
sysc->arg1 = va_arg(args, long);
@@ -206,8 +209,8 @@
sysc->num = num;
atomic_set(&sysc->flags, SC_UEVENT);
sysc->ev_q = evq;
- /* This is a little dangerous, since we'll usually pull more args than were
- * passed in, ultimately reading gibberish off the stack. */
+ /* This is a little dangerous, since we'll usually pull more args than
+ * were passed in, ultimately reading gibberish off the stack. */
va_start(args, num);
sysc->arg0 = va_arg(args, long);
sysc->arg1 = va_arg(args, long);
diff --git a/user/parlib/thread0_sched.c b/user/parlib/thread0_sched.c
index ca1d0a0..51399cf 100644
--- a/user/parlib/thread0_sched.c
+++ b/user/parlib/thread0_sched.c
@@ -64,7 +64,7 @@
* don't actually attach this mgmt info to it. But since we just have one
* thread, it doesn't matter. */
struct thread0_info {
- bool is_blocked;
+ bool is_blocked;
};
static struct thread0_info thread0_info;
static struct event_queue *sysc_evq;
@@ -90,7 +90,8 @@
ret = posix_memalign((void**)&thread0_uth, __alignof__(struct uthread),
sizeof(struct uthread));
assert(!ret);
- memset(thread0_uth, 0, sizeof(struct uthread)); /* aggressively 0 for bugs*/
+ /* aggressively 0 for bugs*/
+ memset(thread0_uth, 0, sizeof(struct uthread));
memset(&thread0_info, 0, sizeof(thread0_info));
/* we don't care about the message, so don't bother with a UCQ */
sysc_evq = get_eventq(EV_MBOX_BITMAP);
@@ -207,8 +208,9 @@
static struct uthread *thread0_sync_get_next(uth_sync_t *s)
{
if (thread0_info.is_blocked) {
- /* Note we don't clear is_blocked. Runnable does that, which should be
- * called before the next get_next (since we have only one thread). */
+ /* Note we don't clear is_blocked. Runnable does that, which
+ * should be called before the next get_next (since we have only
+ * one thread). */
return thread0_uth;
} else {
return NULL;
diff --git a/user/parlib/ucq.c b/user/parlib/ucq.c
index 42628fb..b439fc0 100644
--- a/user/parlib/ucq.c
+++ b/user/parlib/ucq.c
@@ -26,14 +26,15 @@
printd("[user] initializing ucq %08p for proc %d\n", ucq, getpid());
assert(!PGOFF(pg1));
assert(!PGOFF(pg2));
- /* Prod and cons both start on the first page, slot 0. When they are equal,
- * the ucq is empty. */
+ /* Prod and cons both start on the first page, slot 0. When they are
+ * equal, the ucq is empty. */
atomic_set(&ucq->prod_idx, pg1);
atomic_set(&ucq->cons_idx, pg1);
ucq->prod_overflow = FALSE;
atomic_set(&ucq->nr_extra_pgs, 0);
atomic_set(&ucq->spare_pg, pg2);
- parlib_static_assert(sizeof(struct spin_pdr_lock) <= sizeof(ucq->u_lock));
+ parlib_static_assert(sizeof(struct spin_pdr_lock) <=
+ sizeof(ucq->u_lock));
spin_pdr_init((struct spin_pdr_lock*)(&ucq->u_lock));
ucq->ucq_ready = TRUE;
}
@@ -58,6 +59,7 @@
{
uintptr_t pg1 = atomic_read(&ucq->prod_idx);
uintptr_t pg2 = atomic_read(&ucq->spare_pg);
+
assert(pg1 && pg2);
munmap((void*)pg1, PGSIZE);
munmap((void*)pg2, PGSIZE);
@@ -77,13 +79,13 @@
loop_top:
cmb();
my_idx = atomic_read(&ucq->cons_idx);
- /* The ucq is empty if the consumer and producer are on the same 'next'
- * slot. */
+ /* The ucq is empty if the consumer and producer are on the same
+ * 'next' slot. */
if (my_idx == atomic_read(&ucq->prod_idx))
return FALSE;
- /* Is the slot we want good? If not, we're going to need to try and
- * move on to the next page. If it is, we bypass all of this and try to
- * CAS on us getting my_idx. */
+ /* Is the slot we want good? If not, we're going to need to try
+ * and move on to the next page. If it is, we bypass all of
+ * this and try to CAS on us getting my_idx. */
if (slot_is_good(my_idx))
goto claim_slot;
/* Slot is bad, let's try and fix it */
@@ -92,40 +94,44 @@
* were waiting/fighting for the lock */
my_idx = atomic_read(&ucq->cons_idx);
if (slot_is_good(my_idx)) {
- /* Someone else fixed it already, let's just try to get out */
+ /* Someone else fixed it already, let's just try to get
+ * out */
spin_pdr_unlock(ucq_lock);
- /* Make sure this new slot has a producer (ucq isn't empty) */
+ /* Make sure this new slot has a producer (ucq isn't
+ * empty) */
if (my_idx == atomic_read(&ucq->prod_idx))
return FALSE;
goto claim_slot;
}
- /* At this point, the slot is bad, and all other possible consumers are
- * spinning on the lock. Time to fix things up: Set the counter to the
- * next page, and free the old one. */
- /* First, we need to wait and make sure the kernel has posted the next
- * page. Worst case, we know that the kernel is working on it, since
- * prod_idx != cons_idx */
+ /* At this point, the slot is bad, and all other possible
+ * consumers are spinning on the lock. Time to fix things up:
+ * Set the counter to the next page, and free the old one. */
+ /* First, we need to wait and make sure the kernel has posted
+ * the next page. Worst case, we know that the kernel is
+ * working on it, since prod_idx != cons_idx */
old_page = (struct ucq_page*)PTE_ADDR(my_idx);
while (!old_page->header.cons_next_pg)
cpu_relax();
/* Now set the counter to the next page */
assert(!PGOFF(old_page->header.cons_next_pg));
atomic_set(&ucq->cons_idx, old_page->header.cons_next_pg);
- /* Side note: at this point, any *new* consumers coming in will grab
- * slots based off the new counter index (cons_idx) */
- /* Now free up the old page. Need to make sure all other consumers are
- * done. We spin til enough are done, like an inverted refcnt. */
- while (atomic_read(&old_page->header.nr_cons) < NR_MSG_PER_PAGE) {
- /* spinning on userspace here, specifically, another vcore and we
- * don't know who it is. This will spin a bit, then make sure they
- * aren't preeempted */
+ /* Side note: at this point, any *new* consumers coming in will
+ * grab slots based off the new counter index (cons_idx) */
+ /* Now free up the old page. Need to make sure all other
+ * consumers are done. We spin til enough are done, like an
+ * inverted refcnt. */
+ while (atomic_read(&old_page->header.nr_cons) < NR_MSG_PER_PAGE)
+ {
+ /* spinning on userspace here, specifically, another
+ * vcore and we don't know who it is. This will spin a
+ * bit, then make sure they aren't preeempted */
cpu_relax_any();
}
/* Now the page is done. 0 its metadata and give it up. */
old_page->header.cons_next_pg = 0;
atomic_set(&old_page->header.nr_cons, 0);
- /* We want to "free" the page. We'll try and set it as the spare. If
- * there is already a spare, we'll free that one. */
+ /* We want to "free" the page. We'll try and set it as the
+ * spare. If there is already a spare, we'll free that one. */
other_page = (struct ucq_page*)atomic_swap(&ucq->spare_pg,
(long)old_page);
assert(!PGOFF(other_page));
@@ -133,15 +139,15 @@
munmap(other_page, PGSIZE);
atomic_dec(&ucq->nr_extra_pgs);
}
- /* All fixed up, unlock. Other consumers may lock and check to make
- * sure things are done. */
+ /* All fixed up, unlock. Other consumers may lock and check to
+ * make sure things are done. */
spin_pdr_unlock(ucq_lock);
/* Now that everything is fixed, try again from the top */
goto loop_top;
claim_slot:
cmb(); /* so we can goto claim_slot */
- /* If we're still here, my_idx is good, and we'll try to claim it. If
- * we fail, we need to repeat the whole process. */
+ /* If we're still here, my_idx is good, and we'll try to claim
+ * it. If we fail, we need to repeat the whole process. */
} while (!atomic_cas(&ucq->cons_idx, my_idx, my_idx + 1));
assert(slot_is_good(my_idx));
/* Now we have a good slot that we can consume */
diff --git a/user/parlib/uthread.c b/user/parlib/uthread.c
index 9f133c4..71feb4a 100644
--- a/user/parlib/uthread.c
+++ b/user/parlib/uthread.c
@@ -37,7 +37,7 @@
static void uthread_init_thread0(struct uthread *uthread)
{
assert(uthread);
- /* Save a pointer to thread0's tls region (the glibc one) into its tcb */
+ /* Save a pointer to thread0's tls region (the glibc one) into its tcb*/
uthread->tls_desc = get_tls_desc();
/* Save a pointer to the uthread in its own TLS */
current_uthread = uthread;
@@ -85,43 +85,45 @@
parlib_init_once_racy(return);
/* Doing this after the init_once check, since we don't want to let the
- * process/2LS change their mind about being an MCP or not once they have
- * multiple threads.
+ * process/2LS change their mind about being an MCP or not once they
+ * have multiple threads.
*
* The reason is that once you set "MCP please" on, you could get
* interrupted into VC ctx, say for a syscall completion, and then make
* decisions based on the fact that you're an MCP (e.g., unblocking a
* uthread, asking for vcores, etc), even though you are not an MCP.
- * Arguably, these things could happen for signals too, but all of this is
- * less likely than if we have multiple threads.
+ * Arguably, these things could happen for signals too, but all of this
+ * is less likely than if we have multiple threads.
*
* Also, we could just abort here, since they shouldn't be calling
* mcp_init() if they don't want to be an MCP. */
if (!parlib_wants_to_be_mcp)
return;
- /* Receive preemption events. Note that this merely tells the kernel how to
- * send the messages, and does not necessarily provide storage space for the
- * messages. What we're doing is saying that all PREEMPT and CHECK_MSGS
- * events should be spammed to vcores that are running, preferring whatever
- * the kernel thinks is appropriate. And IPI them.
+ /* Receive preemption events. Note that this merely tells the kernel
+ * how to send the messages, and does not necessarily provide storage
+ * space for the messages. What we're doing is saying that all PREEMPT
+ * and CHECK_MSGS events should be spammed to vcores that are running,
+ * preferring whatever the kernel thinks is appropriate. And IPI them.
*
* It is critical that these are either SPAM_PUB or INDIR|SPAM_INDIR, so
* that yielding vcores do not miss the preemption messages. */
register_ev_handler(EV_VCORE_PREEMPT, handle_vc_preempt, 0);
register_ev_handler(EV_CHECK_MSGS, handle_vc_indir, 0);
- preempt_ev_q = get_eventq_slim(); /* small ev_q, mostly a vehicle for flags */
- preempt_ev_q->ev_flags = EVENT_IPI | EVENT_SPAM_PUBLIC | EVENT_VCORE_APPRO |
- EVENT_VCORE_MUST_RUN | EVENT_WAKEUP;
- /* Tell the kernel to use the ev_q (it's settings) for the two types. Note
- * that we still have two separate handlers. We just want the events
- * delivered in the same way. If we ever want to have a big_event_q with
- * INDIRs, we could consider using separate ones. */
+ /* small ev_q, mostly a vehicle for flags */
+ preempt_ev_q = get_eventq_slim();
+ preempt_ev_q->ev_flags = EVENT_IPI | EVENT_SPAM_PUBLIC |
+ EVENT_VCORE_APPRO | EVENT_VCORE_MUST_RUN |
+ EVENT_WAKEUP;
+ /* Tell the kernel to use the ev_q (it's settings) for the two types.
+ * Note that we still have two separate handlers. We just want the
+ * events delivered in the same way. If we ever want to have a
+ * big_event_q with INDIRs, we could consider using separate ones. */
register_kevent_q(preempt_ev_q, EV_VCORE_PREEMPT);
register_kevent_q(preempt_ev_q, EV_CHECK_MSGS);
printd("[user] registered %08p (flags %08p) for preempt messages\n",
preempt_ev_q, preempt_ev_q->ev_flags);
- /* Get ourselves into _M mode. Could consider doing this elsewhere... */
+ /* Get ourselves into _M mode. Could consider doing this elsewhere. */
vcore_change_to_m();
}
@@ -131,6 +133,7 @@
{
struct preempt_data *vcpd = vcpd_of(0);
long old_flags;
+
/* the CAS is a bit overkill; keeping it around in case people use this
* code in other situations. */
do {
@@ -169,18 +172,19 @@
return;
/* Need to make sure vcore_lib_init() runs first */
vcore_lib_init();
- /* Instead of relying on ctors for the specific 2LS, we make sure they are
- * called next. They will call uthread_2ls_init().
+ /* Instead of relying on ctors for the specific 2LS, we make sure they
+ * are called next. They will call uthread_2ls_init().
*
- * The potential issue here is that C++ ctors might make use of the GCC/C++
- * threading callbacks, which require the full 2LS. There's no linkage
- * dependency between C++ and the specific 2LS, so there's no way to be
- * sure the 2LS actually turned on before we started calling into it.
+ * The potential issue here is that C++ ctors might make use of the
+ * GCC/C++ threading callbacks, which require the full 2LS. There's no
+ * linkage dependency between C++ and the specific 2LS, so there's no
+ * way to be sure the 2LS actually turned on before we started calling
+ * into it.
*
- * Hopefully, the uthread ctor was called in time, since the GCC threading
- * functions link against parlib. Note that, unlike parlib-compat.c, there
- * are no stub functions available to GCC that could get called by
- * accident and prevent the linkage. */
+ * Hopefully, the uthread ctor was called in time, since the GCC
+ * threading functions link against parlib. Note that, unlike
+ * parlib-compat.c, there are no stub functions available to GCC that
+ * could get called by accident and prevent the linkage. */
sched_ops->sched_init();
}
@@ -240,14 +244,14 @@
ros_errstr_loc = __ros_errstr_loc;
register_ev_handler(EV_EVENT, handle_ev_ev, 0);
cmb();
- /* Now that we're ready (I hope) to operate as a full process, we tell the
- * kernel. We must set vcctx and blockon atomically with respect to
+ /* Now that we're ready (I hope) to operate as a full process, we tell
+ * the kernel. We must set vcctx and blockon atomically with respect to
* syscalls, meaning no syscalls in between. */
scp_vcctx_ready();
- /* Change our blockon from glibc's internal one to the regular one, which
- * uses vcore context and works for SCPs (with or without 2LS) and MCPs.
- * Now that we told the kernel we are ready to utilize vcore context, we
- * need our blocking syscalls to utilize it as well. */
+ /* Change our blockon from glibc's internal one to the regular one,
+ * which uses vcore context and works for SCPs (with or without 2LS) and
+ * MCPs. Now that we told the kernel we are ready to utilize vcore
+ * context, we need our blocking syscalls to utilize it as well. */
ros_syscall_blockon = __ros_uth_syscall_blockon;
cmb();
init_posix_signals();
@@ -266,41 +270,44 @@
/* Should always have notifications disabled when coming in here. */
assert(!notif_is_enabled(vcoreid));
assert(in_vcore_context());
- /* It's possible to have our FPSAVED already, e.g. any vcore reentry (refl
- * fault, some preemption handling, etc) if cur_uth wasn't reset. In those
- * cases, the FP state should be the same in the processor and in the uth,
- * so we might be able to drop the FPSAVED check/branch. */
+ /* It's possible to have our FPSAVED already, e.g. any vcore reentry
+ * (refl fault, some preemption handling, etc) if cur_uth wasn't reset.
+ * In those cases, the FP state should be the same in the processor and
+ * in the uth, so we might be able to drop the FPSAVED check/branch. */
if (current_uthread && !(current_uthread->flags & UTHREAD_FPSAVED) &&
!cur_uth_is_sw_ctx()) {
save_fp_state(¤t_uthread->as);
current_uthread->flags |= UTHREAD_FPSAVED;
}
- /* If someone is stealing our uthread (from when we were preempted before),
- * we can't touch our uthread. But we might be the last vcore around, so
- * we'll handle preemption events (spammed to our public mbox).
+ /* If someone is stealing our uthread (from when we were preempted
+ * before), we can't touch our uthread. But we might be the last vcore
+ * around, so we'll handle preemption events (spammed to our public
+ * mbox).
*
- * It's important that we only check/handle one message per loop, otherwise
- * we could get stuck in a ping-pong scenario with a recoverer (maybe). */
+ * It's important that we only check/handle one message per loop,
+ * otherwise we could get stuck in a ping-pong scenario with a recoverer
+ * (maybe). */
while (atomic_read(&vcpd->flags) & VC_UTHREAD_STEALING) {
- /* Note we're handling INDIRs and other public messages while someone
- * is stealing our uthread. Remember that those event handlers cannot
- * touch cur_uth, as it is "vcore business". */
+ /* Note we're handling INDIRs and other public messages while
+ * someone is stealing our uthread. Remember that those event
+ * handlers cannot touch cur_uth, as it is "vcore business". */
handle_one_mbox_msg(&vcpd->ev_mbox_public);
cpu_relax();
}
- /* If we have a current uthread that is DONT_MIGRATE, pop it real quick and
- * let it disable notifs (like it wants to). Other than dealing with
- * preemption events (or other INDIRs), we shouldn't do anything in vc_ctx
- * when we have a DONT_MIGRATE uthread. */
+ /* If we have a current uthread that is DONT_MIGRATE, pop it real quick
+ * and let it disable notifs (like it wants to). Other than dealing
+ * with preemption events (or other INDIRs), we shouldn't do anything in
+ * vc_ctx when we have a DONT_MIGRATE uthread. */
if (current_uthread && (current_uthread->flags & UTHREAD_DONT_MIGRATE))
__run_current_uthread_raw();
- /* Check and see if we wanted ourselves to handle a remote VCPD mbox. Want
- * to do this after we've handled STEALING and DONT_MIGRATE. */
+ /* Check and see if we wanted ourselves to handle a remote VCPD mbox.
+ * Want to do this after we've handled STEALING and DONT_MIGRATE. */
try_handle_remote_mbox();
/* Otherwise, go about our usual vcore business (messages, etc). */
handle_events(vcoreid);
__check_preempt_pending(vcoreid);
- assert(in_vcore_context()); /* double check, in case an event changed it */
+ /* double check, in case an event changed it */
+ assert(in_vcore_context());
sched_ops->sched_entry();
assert(0); /* 2LS sched_entry should never return */
}
@@ -323,12 +330,13 @@
new_thread->flags = 0;
new_thread->sysc = NULL;
/* the utf holds the GP context of the uthread (set by the 2LS earlier).
- * There is no FP context to be restored yet. We only save the FPU when we
- * were interrupted off a core. */
+ * There is no FP context to be restored yet. We only save the FPU when
+ * we were interrupted off a core. */
new_thread->flags |= UTHREAD_SAVED;
new_thread->notif_disabled_depth = 0;
- /* TODO: on a reinit, if they changed whether or not they want TLS, we'll
- * have issues (checking tls_desc, assert in allocate_tls, maybe more). */
+ /* TODO: on a reinit, if they changed whether or not they want TLS,
+ * we'll have issues (checking tls_desc, assert in allocate_tls, maybe
+ * more). */
if (attr && attr->want_tls) {
/* Get a TLS. If we already have one, reallocate/refresh it */
if (new_thread->tls_desc)
@@ -338,9 +346,9 @@
assert(!ret);
begin_access_tls_vars(new_thread->tls_desc);
current_uthread = new_thread;
- /* ctypes stores locale info in TLS. we need this only once per TLS, so
- * we don't have to do it here, but it is convenient since we already
- * loaded the uthread's TLS. */
+ /* ctypes stores locale info in TLS. we need this only once per
+ * TLS, so we don't have to do it here, but it is convenient
+ * since we already loaded the uthread's TLS. */
extern void __ctype_init(void);
__ctype_init();
end_access_tls_vars();
@@ -387,9 +395,9 @@
{
/* Call out to the 2LS to let it know the uthread was paused for some
* reason, but it is ok to resume it now. */
- assert(uthread->state == UT_NOT_RUNNING);
- assert(sched_ops->thread_paused);
- sched_ops->thread_paused(uthread);
+ assert(uthread->state == UT_NOT_RUNNING);
+ assert(sched_ops->thread_paused);
+ sched_ops->thread_paused(uthread);
}
/* Need to have this as a separate, non-inlined function since we clobber the
@@ -406,8 +414,8 @@
uthread->flags &= ~UTHREAD_DONT_MIGRATE;
uthread->state = UT_NOT_RUNNING;
/* Any locks that were held before the yield must be unlocked in the
- * callback. That callback won't get a chance to update our disabled depth.
- * This sets us up for the next time the uthread runs. */
+ * callback. That callback won't get a chance to update our disabled
+ * depth. This sets us up for the next time the uthread runs. */
assert(uthread->notif_disabled_depth <= 1);
uthread->notif_disabled_depth = 0;
/* Do whatever the yielder wanted us to do */
@@ -415,7 +423,8 @@
uthread->yield_func(uthread, uthread->yield_arg);
/* Make sure you do not touch uthread after that func call */
/* Leave the current vcore completely */
- /* TODO: if the yield func can return a failure, we can abort the yield */
+ /* TODO: if the yield func can return a failure, we can abort the yield
+ */
current_uthread = NULL;
/* Go back to the entry point, where we can handle notifications or
* reschedule someone. */
@@ -435,65 +444,76 @@
void *yield_arg)
{
struct uthread *uthread = current_uthread;
- volatile bool yielding = TRUE; /* signal to short circuit when restarting */
+ volatile bool yielding = TRUE; /* signal to short circuit on restart */
assert(!in_vcore_context());
assert(uthread->state == UT_RUNNING);
- /* Pass info to ourselves across the uth_yield -> __uth_yield transition. */
+ /* Pass info to ourselves across the uth_yield -> __uth_yield
+ * transition. */
uthread->yield_func = yield_func;
uthread->yield_arg = yield_arg;
- /* Don't migrate this thread to another vcore, since it depends on being on
- * the same vcore throughout (once it disables notifs). The race is that we
- * read vcoreid, then get interrupted / migrated before disabling notifs. */
+ /* Don't migrate this thread to another vcore, since it depends on being
+ * on the same vcore throughout (once it disables notifs). The race is
+ * that we read vcoreid, then get interrupted / migrated before
+ * disabling notifs. */
uthread->flags |= UTHREAD_DONT_MIGRATE;
cmb(); /* don't let DONT_MIGRATE write pass the vcoreid read */
uint32_t vcoreid = vcore_id();
+
printd("[U] Uthread %08p is yielding on vcore %d\n", uthread, vcoreid);
struct preempt_data *vcpd = vcpd_of(vcoreid);
- /* once we do this, we might miss a notif_pending, so we need to enter vcore
- * entry later. Need to disable notifs so we don't get in weird loops with
- * save_user_ctx() and pop_user_ctx(). */
+
+ /* once we do this, we might miss a notif_pending, so we need to enter
+ * vcore entry later. Need to disable notifs so we don't get in weird
+ * loops with save_user_ctx() and pop_user_ctx(). */
disable_notifs(vcoreid);
/* take the current state and save it into t->utf when this pthread
- * restarts, it will continue from right after this, see yielding is false,
- * and short ciruit the function. Don't do this if we're dying. */
+ * restarts, it will continue from right after this, see yielding is
+ * false, and short ciruit the function. Don't do this if we're dying.
+ * */
if (save_state) {
- /* Need to signal this before we actually save, since save_user_ctx
- * returns() twice (once now, once when woken up) */
+ /* Need to signal this before we actually save, since
+ * save_user_ctx returns() twice (once now, once when woken up)
+ */
uthread->flags |= UTHREAD_SAVED;
save_user_ctx(&uthread->u_ctx);
}
- cmb(); /* Force reread of yielding. Technically save_user_ctx() suffices*/
+ /* Force reread of yielding. Technically save_user_ctx() suffices*/
+ cmb();
/* Restart path doesn't matter if we're dying */
if (!yielding)
goto yield_return_path;
- /* From here on down is only executed on the save path (not the wake up) */
+ /* From here on down is only executed on the save path (not the wake up)
+ */
yielding = FALSE; /* for when it starts back up */
/* TODO: remove this when all arches support SW contexts */
if (save_state && (uthread->u_ctx.type != ROS_SW_CTX)) {
save_fp_state(&uthread->as);
uthread->flags |= UTHREAD_FPSAVED;
}
- /* Change to the transition context (both TLS (if applicable) and stack). */
+ /* Change to the transition context (both TLS (if applicable) and
+ * stack). */
if (__uthread_has_tls(uthread)) {
set_tls_desc(get_vcpd_tls_desc(vcoreid));
begin_safe_access_tls_vars();
assert(current_uthread == uthread);
- /* If this assert fails, see the note in uthread_track_thread0 */
+ /* If this assert fails, see the note in uthread_track_thread0
+ */
assert(in_vcore_context());
end_safe_access_tls_vars();
} else {
- /* Since uthreads and vcores share TLS (it's always the vcore's TLS, the
- * uthread one just bootstraps from it), we need to change our state at
- * boundaries between the two 'contexts' */
+ /* Since uthreads and vcores share TLS (it's always the vcore's
+ * TLS, the uthread one just bootstraps from it), we need to
+ * change our state at boundaries between the two 'contexts' */
__vcore_context = TRUE;
}
- /* After this, make sure you don't use local variables. Also, make sure the
- * compiler doesn't use them without telling you (TODO).
+ /* After this, make sure you don't use local variables. Also, make sure
+ * the compiler doesn't use them without telling you (TODO).
*
- * In each arch's set_stack_pointer, make sure you subtract off as much room
- * as you need to any local vars that might be pushed before calling the
- * next function, or for whatever other reason the compiler/hardware might
- * walk up the stack a bit when calling a noreturn function. */
+ * In each arch's set_stack_pointer, make sure you subtract off as much
+ * room as you need to any local vars that might be pushed before
+ * calling the next function, or for whatever other reason the
+ * compiler/hardware might walk up the stack a bit when calling a
+ * noreturn function. */
set_stack_pointer((void*)vcpd->vcore_stack);
/* Finish exiting in another function. */
__uthread_yield();
@@ -536,8 +556,9 @@
void uthread_cleanup(struct uthread *uthread)
{
printd("[U] thread %08p on vcore %d is DYING!\n", uthread, vcore_id());
- /* we alloc and manage the TLS, so lets get rid of it, except for thread0.
- * glibc owns it. might need to keep it around for a full exit() */
+ /* we alloc and manage the TLS, so lets get rid of it, except for
+ * thread0. glibc owns it. might need to keep it around for a full
+ * exit() */
if (__uthread_has_tls(uthread) && !(uthread->flags & UTHREAD_IS_THREAD0))
__uthread_free_tls(uthread);
}
@@ -567,9 +588,9 @@
__ros_vcore_ctx_syscall_blockon(sysc);
return;
}
- /* At this point, we know we're a uthread. If we're a DONT_MIGRATE uthread,
- * then it's disabled notifs and is basically in vcore context, enough so
- * that it can't call into the 2LS. */
+ /* At this point, we know we're a uthread. If we're a DONT_MIGRATE
+ * uthread, then it's disabled notifs and is basically in vcore context,
+ * enough so that it can't call into the 2LS. */
assert(current_uthread);
if (current_uthread->flags & UTHREAD_DONT_MIGRATE) {
assert(!notif_is_enabled(vcore_id())); /* catch bugs */
@@ -596,8 +617,8 @@
{
assert(in_vcore_context());
uth->sysc = &uth->local_sysc;
- /* If a DONT_MIGRATE issued a syscall that blocks, we gotta spin, same as
- * with the usual blockon. */
+ /* If a DONT_MIGRATE issued a syscall that blocks, we gotta spin, same
+ * as with the usual blockon. */
if (uth->flags & UTHREAD_DONT_MIGRATE) {
__ros_vcore_ctx_syscall_blockon(uth->sysc);
uth->sysc = 0;
@@ -613,6 +634,7 @@
void highjack_current_uthread(struct uthread *uthread)
{
uint32_t vcoreid = vcore_id();
+
assert(uthread != current_uthread);
current_uthread->state = UT_NOT_RUNNING;
uthread->state = UT_RUNNING;
@@ -666,7 +688,8 @@
uth->u_ctx = vcpd->uthread_ctx;
uth->flags |= UTHREAD_SAVED;
}
- if ((uth->u_ctx.type != ROS_SW_CTX) && !(uth->flags & UTHREAD_FPSAVED)) {
+ if ((uth->u_ctx.type != ROS_SW_CTX) && !(uth->flags & UTHREAD_FPSAVED))
+ {
save_fp_state(&uth->as);
uth->flags |= UTHREAD_FPSAVED;
}
@@ -688,9 +711,9 @@
assert(current_uthread->state == UT_RUNNING);
/* Uth was already running, should not have been saved */
assert(!(current_uthread->flags & UTHREAD_SAVED));
- /* SW CTX FP wasn't saved, but HW/VM was. There might be some case where
- * a VMTF hadn't run yet, and thus wasn't interrupted, but it shouldn't have
- * made it to be current_uthread. */
+ /* SW CTX FP wasn't saved, but HW/VM was. There might be some case
+ * where a VMTF hadn't run yet, and thus wasn't interrupted, but it
+ * shouldn't have made it to be current_uthread. */
if (cur_uth_is_sw_ctx())
assert(!(current_uthread->flags & UTHREAD_FPSAVED));
else
@@ -699,12 +722,13 @@
current_uthread);
if (has_refl_fault(&vcpd->uthread_ctx)) {
clear_refl_fault(&vcpd->uthread_ctx);
- /* we preemptively copy out and make non-running, so that there is a
- * consistent state for the handler. it can then block the uth or
- * whatever. */
+ /* we preemptively copy out and make non-running, so that there
+ * is a consistent state for the handler. it can then block the
+ * uth or whatever. */
uth = stop_current_uthread();
handle_refl_fault(uth, &vcpd->uthread_ctx);
- /* we abort no matter what. up to the 2LS to reschedule the thread */
+ /* we abort no matter what. up to the 2LS to reschedule the
+ * thread */
set_stack_pointer((void*)vcpd->vcore_stack);
vcore_entry();
}
@@ -739,8 +763,8 @@
assert(!current_uthread);
assert(uthread->state == UT_NOT_RUNNING);
assert(uthread->flags & UTHREAD_SAVED);
- /* For HW CTX, FPSAVED must match UTH SAVE (and both be on here). For SW,
- * FP should never be saved. */
+ /* For HW CTX, FPSAVED must match UTH SAVE (and both be on here). For
+ * SW, FP should never be saved. */
switch (uthread->u_ctx.type) {
case ROS_HW_CTX:
assert(uthread->flags & UTHREAD_FPSAVED);
@@ -749,27 +773,30 @@
assert(!(uthread->flags & UTHREAD_FPSAVED));
break;
case ROS_VM_CTX:
- /* Don't care. This gives it the state of the vcore when it starts up.
- * If we care about leaking FPU / XMM state, we can create a new one for
- * every VM TF (or vthread reuse). */
+ /* Don't care. This gives it the state of the vcore when it
+ * starts up. If we care about leaking FPU / XMM state, we can
+ * create a new one for every VM TF (or vthread reuse). */
break;
}
if (has_refl_fault(&uthread->u_ctx)) {
clear_refl_fault(&uthread->u_ctx);
handle_refl_fault(uthread, &uthread->u_ctx);
- /* we abort no matter what. up to the 2LS to reschedule the thread */
+ /* we abort no matter what. up to the 2LS to reschedule the
+ * thread */
set_stack_pointer((void*)vcpd->vcore_stack);
vcore_entry();
}
uthread->state = UT_RUNNING;
- /* Save a ptr to the uthread we'll run in the transition context's TLS */
+ /* Save a ptr to the uthread we'll run in the transition context's TLS
+ */
current_uthread = uthread;
if (uthread->flags & UTHREAD_FPSAVED) {
uthread->flags &= ~UTHREAD_FPSAVED;
restore_fp_state(&uthread->as);
}
set_uthread_tls(uthread, vcoreid);
- /* the uth's context will soon be in the cpu (or VCPD), no longer saved */
+ /* the uth's context will soon be in the cpu (or VCPD), no longer saved
+ */
uthread->flags &= ~UTHREAD_SAVED;
pop_user_ctx(&uthread->u_ctx, vcoreid);
assert(0);
@@ -782,12 +809,13 @@
{
uint32_t vcoreid = vcore_id();
struct preempt_data *vcpd = vcpd_of(vcoreid);
+
if (has_refl_fault(&vcpd->uthread_ctx)) {
printf("Raw / DONT_MIGRATE uthread took a fault, exiting.\n");
exit(-1);
}
- /* We need to manually say we have a notif pending, so we eventually return
- * to vcore context. (note the kernel turned it off for us) */
+ /* We need to manually say we have a notif pending, so we eventually
+ * return to vcore context. (note the kernel turned it off for us) */
vcpd->notif_pending = TRUE;
assert(!(current_uthread->flags & UTHREAD_SAVED));
if (current_uthread->flags & UTHREAD_FPSAVED) {
@@ -837,24 +865,25 @@
uthread->u_ctx = vcpd->uthread_ctx;
uthread->flags |= UTHREAD_SAVED;
printd("VC %d copying out uthread %08p\n", vcore_id(), uthread);
- /* Software contexts do not need FP state, nor should we think it has any */
+ /* Software contexts do not need FP state, nor should we think it has
+ * any */
if (uthread->u_ctx.type == ROS_SW_CTX) {
assert(!(uthread->flags & UTHREAD_FPSAVED));
return;
}
- /* We might have aggressively saved for non-SW ctx in vc_entry before we got
- * to the event handler. */
+ /* We might have aggressively saved for non-SW ctx in vc_entry before we
+ * got to the event handler. */
if (uthread->flags & UTHREAD_FPSAVED) {
- /* If this fails, we're remote. But the target vcore should not be in
- * uth context (which is when we'd be stealing a uthread) with FPSAVED,
- * just like how it shouldn't have GP saved. */
+ /* If this fails, we're remote. But the target vcore should not
+ * be in uth context (which is when we'd be stealing a uthread)
+ * with FPSAVED, just like how it shouldn't have GP saved. */
assert(vcore_local);
return;
}
/* When we're dealing with the uthread running on our own vcore, the FP
- * state is in the actual FPU, not VCPD. It might also be in VCPD, but it
- * will always be in the FPU (the kernel maintains this for us, in the event
- * we were preempted since the uthread was last running). */
+ * state is in the actual FPU, not VCPD. It might also be in VCPD, but
+ * it will always be in the FPU (the kernel maintains this for us, in
+ * the event we were preempted since the uthread was last running). */
if (vcore_local)
save_fp_state(&uthread->as);
else
@@ -897,18 +926,19 @@
retval = TRUE;
if (sched_ops->preempt_pending)
sched_ops->preempt_pending();
- /* If we still have a cur_uth, copy it out and hand it back to the 2LS
- * before yielding. */
+ /* If we still have a cur_uth, copy it out and hand it back to
+ * the 2LS before yielding. */
if (current_uthread) {
- __uthread_pause(vcpd_of(vcoreid), current_uthread, TRUE);
+ __uthread_pause(vcpd_of(vcoreid), current_uthread,
+ TRUE);
current_uthread = 0;
}
- /* vcore_yield tries to yield, and will pop back up if this was a spurious
- * preempt_pending or if it handled an event. For now, we'll just keep
- * trying to yield so long as a preempt is coming in. Eventually, we'll
- * handle all of our events and yield, or else the preemption will hit
- * and someone will recover us (at which point we'll break out of the
- * loop) */
+ /* vcore_yield tries to yield, and will pop back up if this was
+ * a spurious preempt_pending or if it handled an event. For
+ * now, we'll just keep trying to yield so long as a preempt is
+ * coming in. Eventually, we'll handle all of our events and
+ * yield, or else the preemption will hit and someone will
+ * recover us (at which point we'll break out of the loop) */
while (__procinfo.vcoremap[vcoreid].preempt_pending) {
vcore_yield(TRUE);
cpu_relax();
@@ -927,7 +957,9 @@
if (current_uthread->notif_disabled_depth++)
goto out;
current_uthread->flags |= UTHREAD_DONT_MIGRATE;
- cmb(); /* don't issue the flag write before the vcore_id() read */
+ /* don't issue the flag write before the vcore_id() read
+ */
+ cmb();
}
disable_notifs(vcore_id());
}
@@ -1001,10 +1033,10 @@
{
long old_flags;
struct preempt_data *rem_vcpd = vcpd_of(rem_vcoreid);
- /* Turn off their message reception if they are still preempted. If they
- * are no longer preempted, we do nothing - they will handle their own
- * messages. Turning off CAN_RCV will route this vcore's messages to
- * fallback vcores (if those messages were 'spammed'). */
+ /* Turn off their message reception if they are still preempted. If
+ * they are no longer preempted, we do nothing - they will handle their
+ * own messages. Turning off CAN_RCV will route this vcore's messages
+ * to fallback vcores (if those messages were 'spammed'). */
do {
old_flags = atomic_read(&rem_vcpd->flags);
while (old_flags & VC_K_LOCK)
@@ -1037,47 +1069,48 @@
static void change_to_vcore(struct preempt_data *vcpd, uint32_t rem_vcoreid)
{
bool were_handling_remotes;
+
/* Unlikely, but if we have no uthread we can just change. This is the
- * check, sync, then really check pattern: we can only really be sure about
- * current_uthread after we check STEALING. */
+ * check, sync, then really check pattern: we can only really be sure
+ * about current_uthread after we check STEALING. */
if (!current_uthread) {
- /* there might be an issue with doing this while someone is recovering.
- * once they 0'd it, we should be good to yield. just a bit dangerous.
- * */
+ /* there might be an issue with doing this while someone is
+ * recovering. once they 0'd it, we should be good to yield.
+ * just a bit dangerous. */
were_handling_remotes = ev_might_not_return();
- __change_vcore(rem_vcoreid, TRUE); /* noreturn on success */
+ __change_vcore(rem_vcoreid, TRUE);/* noreturn on success */
goto out_we_returned;
}
- /* Note that the reason we need to check STEALING is because we can get into
- * vcore context and slip past that check in vcore_entry when we are
- * handling a preemption message. Anytime preemption recovery cares about
- * the calling vcore's cur_uth, it needs to be careful about STEALING. But
- * it is safe to do the check up above (if it's 0, it won't concurrently
- * become non-zero).
+ /* Note that the reason we need to check STEALING is because we can get
+ * into vcore context and slip past that check in vcore_entry when we
+ * are handling a preemption message. Anytime preemption recovery cares
+ * about the calling vcore's cur_uth, it needs to be careful about
+ * STEALING. But it is safe to do the check up above (if it's 0, it
+ * won't concurrently become non-zero).
*
* STEALING might be turned on at any time. Whoever turns it on will do
* nothing if we are online or were in vc_ctx. So if it is on, we can't
- * touch current_uthread til it is turned off (not sure what state they saw
- * us in). We could spin here til they unset STEALING (since they will
- * soon), but there is a chance they were preempted, so we need to make
- * progress by doing a sys_change_vcore(). */
+ * touch current_uthread til it is turned off (not sure what state they
+ * saw us in). We could spin here til they unset STEALING (since they
+ * will soon), but there is a chance they were preempted, so we need to
+ * make progress by doing a sys_change_vcore(). */
/* Crap, someone is stealing (unlikely). All we can do is change. */
if (atomic_read(&vcpd->flags) & VC_UTHREAD_STEALING) {
__change_vcore(rem_vcoreid, FALSE); /* returns on success */
return;
}
cmb();
- /* Need to recheck, in case someone stole it and finished before we checked
- * VC_UTHREAD_STEALING. */
+ /* Need to recheck, in case someone stole it and finished before we
+ * checked VC_UTHREAD_STEALING. */
if (!current_uthread) {
were_handling_remotes = ev_might_not_return();
- __change_vcore(rem_vcoreid, TRUE); /* noreturn on success */
+ __change_vcore(rem_vcoreid, TRUE); /* noreturn on success*/
goto out_we_returned;
}
- /* Need to make sure we don't have a DONT_MIGRATE (very rare, someone would
- * have to steal from us to get us to handle a preempt message, and then had
- * to finish stealing (and fail) fast enough for us to miss the previous
- * check). */
+ /* Need to make sure we don't have a DONT_MIGRATE (very rare, someone
+ * would have to steal from us to get us to handle a preempt message,
+ * and then had to finish stealing (and fail) fast enough for us to miss
+ * the previous check). */
if (current_uthread->flags & UTHREAD_DONT_MIGRATE) {
__change_vcore(rem_vcoreid, FALSE); /* returns on success */
return;
@@ -1087,7 +1120,7 @@
__uthread_pause(vcpd, current_uthread, TRUE);
current_uthread = 0;
were_handling_remotes = ev_might_not_return();
- __change_vcore(rem_vcoreid, TRUE); /* noreturn on success */
+ __change_vcore(rem_vcoreid, TRUE); /* noreturn on success*/
/* Fall-through to out_we_returned */
out_we_returned:
ev_we_returned(were_handling_remotes);
@@ -1107,15 +1140,15 @@
bool cant_migrate = FALSE;
assert(in_vcore_context());
- /* Just drop messages about ourselves. They are old. If we happen to be
- * getting preempted right now, there's another message out there about
- * that. */
+ /* Just drop messages about ourselves. They are old. If we happen to
+ * be getting preempted right now, there's another message out there
+ * about that. */
if (rem_vcoreid == vcoreid)
return;
printd("Vcore %d was preempted (i'm %d), it's flags %08p!\n",
ev_msg->ev_arg2, vcoreid, rem_vcpd->flags);
- /* Spin til the kernel is done with flags. This is how we avoid handling
- * the preempt message before the preemption. */
+ /* Spin til the kernel is done with flags. This is how we avoid
+ * handling the preempt message before the preemption. */
while (atomic_read(&rem_vcpd->flags) & VC_K_LOCK)
cpu_relax();
/* If they aren't preempted anymore, just return (optimization). */
@@ -1129,20 +1162,21 @@
change_to_vcore(vcpd, rem_vcoreid);
return; /* in case it returns. we've done our job recovering */
}
- /* So now it looks like they were not in vcore context. We want to steal
- * the uthread. Set stealing, then doublecheck everything. If stealing
- * fails, someone else is stealing and we can just leave. That other vcore
- * who is stealing will check the VCPD/INDIRs when it is done. */
+ /* So now it looks like they were not in vcore context. We want to
+ * steal the uthread. Set stealing, then doublecheck everything. If
+ * stealing fails, someone else is stealing and we can just leave. That
+ * other vcore who is stealing will check the VCPD/INDIRs when it is
+ * done. */
if (!start_uth_stealing(rem_vcpd))
return;
- /* Now we're stealing. Double check everything. A change in preempt status
- * or notif_disable status means the vcore has since restarted. The vcore
- * may or may not have started after we set STEALING. If it didn't, we'll
- * need to bail out (but still check messages, since above we assumed the
- * uthread stealer handles the VCPD/INDIRs). Since the vcore is running, we
- * don't need to worry about handling the message any further. Future
- * preemptions will generate another message, so we can ignore getting the
- * uthread or anything like that. */
+ /* Now we're stealing. Double check everything. A change in preempt
+ * status or notif_disable status means the vcore has since restarted.
+ * The vcore may or may not have started after we set STEALING. If it
+ * didn't, we'll need to bail out (but still check messages, since above
+ * we assumed the uthread stealer handles the VCPD/INDIRs). Since the
+ * vcore is running, we don't need to worry about handling the message
+ * any further. Future preemptions will generate another message, so we
+ * can ignore getting the uthread or anything like that. */
printd("VC %d recovering %d, trying to steal uthread\n", vcoreid,
rem_vcoreid);
if (!(atomic_read(&rem_vcpd->flags) & VC_PREEMPTED))
@@ -1150,14 +1184,14 @@
/* Might be preempted twice quickly, and the second time had notifs
* disabled.
*
- * Also note that the second preemption event had another
- * message sent, which either we or someone else will deal with. And also,
- * we don't need to worry about how we are stealing still and plan to
- * abort. If another vcore handles that second preemption message, either
- * the original vcore is in vc ctx or not. If so, we bail out and the
+ * Also note that the second preemption event had another message sent,
+ * which either we or someone else will deal with. And also, we don't
+ * need to worry about how we are stealing still and plan to abort. If
+ * another vcore handles that second preemption message, either the
+ * original vcore is in vc ctx or not. If so, we bail out and the
* second preemption handling needs to change_to. If not, we aren't
- * bailing out, and we'll handle the preemption as normal, and the second
- * handler will bail when it fails to steal. */
+ * bailing out, and we'll handle the preemption as normal, and the
+ * second handler will bail when it fails to steal. */
if (rem_vcpd->notif_disabled)
goto out_stealing;
/* At this point, we're clear to try and steal the uthread. We used to
@@ -1166,22 +1200,23 @@
rem_cur_uth = get_tlsvar_linaddr(rem_vcoreid, current_uthread);
uthread_to_steal = *rem_cur_uth;
if (uthread_to_steal) {
- /* Extremely rare: they have a uthread, but it can't migrate. So we'll
- * need to change to them. */
+ /* Extremely rare: they have a uthread, but it can't migrate.
+ * So we'll need to change to them. */
if (uthread_to_steal->flags & UTHREAD_DONT_MIGRATE) {
- printd("VC %d recovering %d, can't migrate uthread!\n", vcoreid,
- rem_vcoreid);
+ printd("VC %d recovering %d, can't migrate uthread!\n",
+ vcoreid, rem_vcoreid);
stop_uth_stealing(rem_vcpd);
change_to_vcore(vcpd, rem_vcoreid);
- return; /* in case it returns. we've done our job recovering */
+ /* in case it returns. we've done our job recovering */
+ return;
} else {
*rem_cur_uth = 0;
/* we're clear to steal it */
- printd("VC %d recovering %d, uthread %08p stolen\n", vcoreid,
- rem_vcoreid, uthread_to_steal);
+ printd("VC %d recovering %d, uthread %08p stolen\n",
+ vcoreid, rem_vcoreid, uthread_to_steal);
__uthread_pause(rem_vcpd, uthread_to_steal, FALSE);
- /* can't let the cur_uth = 0 write and any writes from __uth_pause()
- * to pass stop_uth_stealing. */
+ /* can't let the cur_uth = 0 write and any writes from
+ * __uth_pause() to pass stop_uth_stealing. */
wmb();
}
}
@@ -1241,8 +1276,8 @@
bool uth_2ls_is_multithreaded(void)
{
- /* thread 0 is single threaded. For the foreseeable future, every other 2LS
- * will be multithreaded. */
+ /* thread 0 is single threaded. For the foreseeable future, every other
+ * 2LS will be multithreaded. */
extern struct schedule_ops thread0_2ls_ops;
return sched_ops != &thread0_2ls_ops;
@@ -1258,9 +1293,9 @@
*
* What are the valid state changes?
*
- * JOINABLE -> DETACHED (only by detach())
- * JOINABLE -> HAS_JOINER (only by join())
- * JOINABLE -> EXITED (only by uth_2ls_thread_exit())
+ * JOINABLE -> DETACHED (only by detach())
+ * JOINABLE -> HAS_JOINER (only by join())
+ * JOINABLE -> EXITED (only by uth_2ls_thread_exit())
*
* That's it. The initial state is either JOINABLE or DETACHED. */
void uthread_detach(struct uthread *uth)
@@ -1277,7 +1312,8 @@
case UTH_JOIN_DETACHED:
panic("Uth %p has already been detached!", uth);
case UTH_JOIN_HAS_JOINER:
- panic("Uth %p has a pending joiner, can't detach!", uth);
+ panic("Uth %p has a pending joiner, can't detach!",
+ uth);
};
assert(old_state == UTH_JOIN_JOINABLE);
} while (!atomic_cas(&jc->state, old_state, UTH_JOIN_DETACHED));
@@ -1317,17 +1353,18 @@
sched_ops->thread_exited(uth);
return;
case UTH_JOIN_JOINABLE:
- /* This write is harmless and idempotent; we can lose the race and
- * still be safe. Assuming we don't, the joiner will look here for
- * the retval. It's temporary storage since we don't know the final
- * retval location (since join hasn't happened yet). */
+ /* This write is harmless and idempotent; we can lose
+ * the race and still be safe. Assuming we don't, the
+ * joiner will look here for the retval. It's temporary
+ * storage since we don't know the final retval location
+ * (since join hasn't happened yet). */
jc->retval = retval;
break;
};
assert(old_state == UTH_JOIN_JOINABLE);
} while (!atomic_cas(&jc->state, old_state, UTH_JOIN_EXITED));
- /* We were joinable, now we have exited. A detacher or joiner will trigger
- * thread_exited. */
+ /* We were joinable, now we have exited. A detacher or joiner will
+ * trigger thread_exited. */
}
/* 2LSs call this when their threads are exiting. The 2LS will regain control
@@ -1349,8 +1386,8 @@
long old_state;
/* We can safely write to the join_ctl, even if we don't end up setting
- * HAS_JOINER. There's only supposed to be one joiner, and if not, we'll
- * catch the bad state. */
+ * HAS_JOINER. There's only supposed to be one joiner, and if not,
+ * we'll catch the bad state. */
jc->retval_loc = retval_loc;
jc->kicker = jk;
do {
@@ -1383,7 +1420,8 @@
static void kicker_release(struct kref *k)
{
- struct uth_join_kicker *jk = container_of(k, struct uth_join_kicker, kref);
+ struct uth_join_kicker *jk = container_of(k, struct uth_join_kicker,
+ kref);
uthread_runnable(jk->joiner);
}
@@ -1423,8 +1461,9 @@
void uthread_sched_yield(void)
{
if (!uth_2ls_is_multithreaded()) {
- /* We're an SCP with no other threads, so we want to yield to other
- * processes. For SCPs, this will yield to the OS/other procs. */
+ /* We're an SCP with no other threads, so we want to yield to
+ * other processes. For SCPs, this will yield to the OS/other
+ * procs. */
syscall(SYS_proc_yield, TRUE);
return;
}
diff --git a/user/parlib/vcore.c b/user/parlib/vcore.c
index c431680..2adf8ef 100644
--- a/user/parlib/vcore.c
+++ b/user/parlib/vcore.c
@@ -30,6 +30,7 @@
void __attribute__((noreturn)) __vcore_entry(void)
{
extern void uthread_vcore_entry(void);
+
uthread_vcore_entry();
fprintf(stderr, "vcore_entry() should never return!\n");
abort();
@@ -41,8 +42,9 @@
static void free_transition_tls(int id)
{
if (get_vcpd_tls_desc(id)) {
- /* Note we briefly have no TLS desc in VCPD. This is fine so long as
- * that vcore doesn't get started fresh before we put in a new desc */
+ /* Note we briefly have no TLS desc in VCPD. This is fine so
+ * long as that vcore doesn't get started fresh before we put in
+ * a new desc */
free_tls(get_vcpd_tls_desc(id));
set_vcpd_tls_desc(id, NULL);
}
@@ -50,24 +52,28 @@
static int allocate_transition_tls(int id)
{
- /* Libc function to initialize TLS-based locale info for ctype functions. */
+ /* Libc function to initialize TLS-based locale info for ctype
+ * functions. */
extern void __ctype_init(void);
- /* We want to free and then reallocate the tls rather than simply
- * reinitializing it because its size may have changed. TODO: not sure if
- * this is right. 0-ing is one thing, but freeing and reallocating can be
- * expensive, esp if syscalls are involved. Check out glibc's
+ /* We want to free and then reallocate the tls rather than simply
+ * reinitializing it because its size may have changed. TODO: not sure
+ * if this is right. 0-ing is one thing, but freeing and reallocating
+ * can be expensive, esp if syscalls are involved. Check out glibc's
* allocatestack.c for what might work. */
free_transition_tls(id);
void *tcb = allocate_tls();
+
if (!tcb) {
errno = ENOMEM;
return -1;
}
- /* Setup some intitial TLS data for the newly allocated transition tls. */
+ /* Setup some intitial TLS data for the newly allocated transition tls.
+ */
void *temp_tcb = get_tls_desc();
+
set_tls_desc(tcb);
begin_safe_access_tls_vars();
__vcoreid = id;
@@ -89,14 +95,16 @@
static int allocate_vcore_stack(int id)
{
struct preempt_data *vcpd = vcpd_of(id);
+
if (vcpd->vcore_stack)
return 0; // reuse old stack
void* stackbot = mmap(0, TRANSITION_STACK_SIZE,
PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE, -1,
+ 0);
- if(stackbot == MAP_FAILED)
+ if (stackbot == MAP_FAILED)
return -1; // errno set by mmap
vcpd->vcore_stack = (uintptr_t)stackbot + TRANSITION_STACK_SIZE;
@@ -165,9 +173,9 @@
static void vcore_libc_init(void)
{
register_printf_specifier('r', printf_errstr, printf_errstr_info);
- /* TODO: register for other kevents/signals and whatnot (can probably reuse
- * the simple ev_q). Could also do this via explicit functions from the
- * program. */
+ /* TODO: register for other kevents/signals and whatnot (can probably
+ * reuse the simple ev_q). Could also do this via explicit functions
+ * from the program. */
}
/* We need to separate the guts of vcore_lib_ctor() into a separate function,
@@ -179,13 +187,13 @@
void vcore_lib_init(void)
{
/* Note this is racy, but okay. The first time through, we are _S.
- * Also, this is the "lowest" level constructor for now, so we don't need
- * to call any other init functions after our run_once() call. This may
- * change in the future. */
+ * Also, this is the "lowest" level constructor for now, so we don't
+ * need to call any other init functions after our run_once() call. This
+ * may change in the future. */
parlib_init_once_racy(return);
- /* Need to alloc vcore0's transition stuff here (technically, just the TLS)
- * so that schedulers can use vcore0's transition TLS before it comes up in
- * vcore_entry() */
+ /* Need to alloc vcore0's transition stuff here (technically, just the
+ * TLS) so that schedulers can use vcore0's transition TLS before it
+ * comes up in vcore_entry() */
prep_vcore_0();
assert(!in_vcore_context());
vcore_libc_init();
@@ -200,22 +208,21 @@
/* Helper functions used to reenter at the top of a vcore's stack for an
* arbitrary function */
-static void __attribute__((noinline, noreturn))
-__vcore_reenter()
+static void __attribute__((noinline, noreturn)) __vcore_reenter()
{
- __vcore_reentry_func();
- assert(0);
+ __vcore_reentry_func();
+ assert(0);
}
void vcore_reenter(void (*entry_func)(void))
{
- assert(in_vcore_context());
- struct preempt_data *vcpd = vcpd_of(vcore_id());
-
- __vcore_reentry_func = entry_func;
- set_stack_pointer((void*)vcpd->vcore_stack);
- cmb();
- __vcore_reenter();
+ assert(in_vcore_context());
+ struct preempt_data *vcpd = vcpd_of(vcore_id());
+
+ __vcore_reentry_func = entry_func;
+ set_stack_pointer((void*)vcpd->vcore_stack);
+ cmb();
+ __vcore_reenter();
}
/* Helper, picks some sane defaults and changes the process into an MCP */
@@ -238,8 +245,9 @@
{
long nr_vcores_wanted = *(long*)nr_vc_wanted;
- /* We init'd up to max_vcores() VCs during init. This assumes the kernel
- * doesn't magically change that value (which it should not do). */
+ /* We init'd up to max_vcores() VCs during init. This assumes the
+ * kernel doesn't magically change that value (which it should not do).
+ * */
nr_vcores_wanted = MIN(nr_vcores_wanted, max_vcores());
if (nr_vcores_wanted > __procdata.res_req[RES_CORES].amt_wanted)
__procdata.res_req[RES_CORES].amt_wanted = nr_vcores_wanted;
@@ -269,8 +277,8 @@
if (nr_vcores_wanted == __procdata.res_req[RES_CORES].amt_wanted)
return;
- /* We race to "post our work" here. Whoever handles the poke will get the
- * latest value written here. */
+ /* We race to "post our work" here. Whoever handles the poke will get
+ * the latest value written here. */
nr_vc_wanted = nr_vcores_wanted;
poke(&vc_req_poke, &nr_vc_wanted);
}
@@ -307,39 +315,41 @@
return;
__sync_fetch_and_and(&vcpd->flags, ~VC_CAN_RCV_MSG);
/* no wrmb() necessary, handle_events() has an mb() if it is checking */
- /* Clears notif pending and tries to handle events. This is an optimization
- * to avoid the yield syscall if we have an event pending. If there is one,
- * we want to unwind and return to the 2LS loop, where we may not want to
- * yield anymore.
- * Note that the kernel only cares about CAN_RCV_MSG for the desired vcore;
- * when spamming, it relies on membership of lists within the kernel. Look
- * at spam_list_member() for more info (k/s/event.c). */
+ /* Clears notif pending and tries to handle events. This is an
+ * optimization to avoid the yield syscall if we have an event pending.
+ * If there is one, we want to unwind and return to the 2LS loop, where
+ * we may not want to yield anymore.
+ *
+ * Note that the kernel only cares about CAN_RCV_MSG for the desired
+ * vcore; when spamming, it relies on membership of lists within the
+ * kernel. Look at spam_list_member() for more info (k/s/event.c). */
if (handle_events(vcoreid)) {
__sync_fetch_and_or(&vcpd->flags, VC_CAN_RCV_MSG);
return;
}
- /* If we are yielding since we don't want the core, tell the kernel we want
- * one less vcore (vc_yield assumes a dumb 2LS).
+ /* If we are yielding since we don't want the core, tell the kernel we
+ * want one less vcore (vc_yield assumes a dumb 2LS).
*
* If yield fails (slight race), we may end up having more vcores than
* amt_wanted for a while, and might lose one later on (after a
* preempt/timeslicing) - the 2LS will have to notice eventually if it
- * actually needs more vcores (which it already needs to do). amt_wanted
- * could even be 0.
+ * actually needs more vcores (which it already needs to do).
+ * amt_wanted could even be 0.
*
* In general, any time userspace decrements or sets to 0, it could get
- * preempted, so the kernel will still give us at least one, until the last
- * vcore properly yields without missing a message (and becomes a WAITING
- * proc, which the ksched will not give cores to).
+ * preempted, so the kernel will still give us at least one, until the
+ * last vcore properly yields without missing a message (and becomes a
+ * WAITING proc, which the ksched will not give cores to).
*
- * I think it's possible for userspace to do this (lock, read amt_wanted,
- * check all message queues for all vcores, subtract amt_wanted (not set to
- * 0), unlock) so long as every event handler +1s the amt wanted, but that's
- * a huge pain, and we already have event handling code making sure a
- * process can't sleep (transition to WAITING) if a message arrives (can't
- * yield if notif_pending, can't go WAITING without yielding, and the event
- * posting the notif_pending will find the online VC or be delayed by
- * spinlock til the proc is WAITING). */
+ * I think it's possible for userspace to do this (lock, read
+ * amt_wanted, check all message queues for all vcores, subtract
+ * amt_wanted (not set to 0), unlock) so long as every event handler +1s
+ * the amt wanted, but that's a huge pain, and we already have event
+ * handling code making sure a process can't sleep (transition to
+ * WAITING) if a message arrives (can't yield if notif_pending, can't go
+ * WAITING without yielding, and the event posting the notif_pending
+ * will find the online VC or be delayed by spinlock til the proc is
+ * WAITING). */
if (!preempt_pending) {
do {
old_nr = __procdata.res_req[RES_CORES].amt_wanted;
@@ -349,8 +359,8 @@
&__procdata.res_req[RES_CORES].amt_wanted,
old_nr, old_nr - 1));
}
- /* We can probably yield. This may pop back up if notif_pending became set
- * by the kernel after we cleared it and we lost the race. */
+ /* We can probably yield. This may pop back up if notif_pending became
+ * set by the kernel after we cleared it and we lost the race. */
sys_yield(preempt_pending);
__sync_fetch_and_or(&vcpd->flags, VC_CAN_RCV_MSG);
}
@@ -363,9 +373,9 @@
{
__enable_notifs(vcoreid);
wrmb(); /* need to read after the write that enabled notifs */
- /* Note we could get migrated before executing this. If that happens, our
- * vcore had gone into vcore context (which is what we wanted), and this
- * self_notify to our old vcore is spurious and harmless. */
+ /* Note we could get migrated before executing this. If that happens,
+ * our vcore had gone into vcore context (which is what we wanted), and
+ * this self_notify to our old vcore is spurious and harmless. */
if (vcpd_of(vcoreid)->notif_pending)
sys_self_notify(vcoreid, EV_NONE, 0, TRUE);
}
@@ -392,24 +402,25 @@
void vcore_idle(void)
{
uint32_t vcoreid = vcore_id();
- /* Once we enable notifs, the calling context will be treated like a uthread
- * (saved into the uth slot). We don't want to ever run it again, so we
- * need to make sure there's no cur_uth. */
+
+ /* Once we enable notifs, the calling context will be treated like a
+ * uthread (saved into the uth slot). We don't want to ever run it
+ * again, so we need to make sure there's no cur_uth. */
assert(!current_uthread);
/* This clears notif_pending (check, signal, check again pattern). */
if (handle_events(vcoreid))
return;
- /* This enables notifs, but also checks notif pending. At this point, any
- * new notifs will restart the vcore from the top. */
+ /* This enables notifs, but also checks notif pending. At this point,
+ * any new notifs will restart the vcore from the top. */
enable_notifs(vcoreid);
- /* From now, til we get into the kernel, any notifs will permanently destroy
- * this context and start the VC from the top.
+ /* From now, til we get into the kernel, any notifs will permanently
+ * destroy this context and start the VC from the top.
*
* Once we're in the kernel, any messages (__notify, __preempt), will be
* RKMs. halt will need to check for those atomically. Checking for
- * notif_pending in the kernel (sleep only if not set) is not enough, since
- * not all reasons for the kernel to stay awak set notif_pending (e.g.,
- * __preempts and __death).
+ * notif_pending in the kernel (sleep only if not set) is not enough,
+ * since not all reasons for the kernel to stay awak set notif_pending
+ * (e.g., __preempts and __death).
*
* At this point, we're out of VC ctx, so anyone who sets notif_pending
* should also send an IPI / __notify */
@@ -423,13 +434,16 @@
static void __ensure_vcore_runs(uint32_t vcoreid)
{
if (vcore_is_preempted(vcoreid)) {
- printd("[vcore]: VC %d changing to VC %d\n", vcore_id(), vcoreid);
- /* Note that at this moment, the vcore could still be mapped (we're
- * racing with __preempt. If that happens, we'll just fail the
- * sys_change_vcore(), and next time __ensure runs we'll get it. */
- /* We want to recover them from preemption. Since we know they have
- * notifs disabled, they will need to be directly restarted, so we can
- * skip the other logic and cut straight to the sys_change_vcore() */
+ printd("[vcore]: VC %d changing to VC %d\n", vcore_id(),
+ vcoreid);
+ /* Note that at this moment, the vcore could still be mapped
+ * (we're racing with __preempt. If that happens, we'll just
+ * fail the sys_change_vcore(), and next time __ensure runs
+ * we'll get it. */
+ /* We want to recover them from preemption. Since we know they
+ * have notifs disabled, they will need to be directly
+ * restarted, so we can skip the other logic and cut straight to
+ * the sys_change_vcore() */
sys_change_vcore(vcoreid, FALSE);
}
}
@@ -505,7 +519,8 @@
{
uint32_t kvcoreid = get_vcoreid();
if (vcoreid != kvcoreid) {
- printf("%s: VC %d thought it was VC %d\n", str, kvcoreid, vcoreid);
+ printf("%s: VC %d thought it was VC %d\n", str, kvcoreid,
+ vcoreid);
return FALSE;
}
return TRUE;
@@ -517,7 +532,8 @@
struct preempt_data *vcpd = vcpd_of(vcore_id());
vcore_yield(FALSE);
- /* If vcore_yield returns, we have an event. Just restart vcore context. */
+ /* If vcore_yield returns, we have an event. Just restart vcore
+ * context. */
set_stack_pointer((void*)vcpd->vcore_stack);
vcore_entry();
}
diff --git a/user/parlib/vcore_tick.c b/user/parlib/vcore_tick.c
index 7df2e5f..6c23abe 100644
--- a/user/parlib/vcore_tick.c
+++ b/user/parlib/vcore_tick.c
@@ -23,12 +23,12 @@
};
struct vcore_tick {
- int state;
- int ctl_fd;
- int timer_fd;
- uint64_t next_deadline;
- uint64_t period_ticks;
- struct event_queue *ev_q;
+ int state;
+ int ctl_fd;
+ int timer_fd;
+ uint64_t next_deadline;
+ uint64_t period_ticks;
+ struct event_queue *ev_q;
};
static struct vcore_tick *__vc_ticks;
@@ -131,34 +131,36 @@
evbm = &vc_tick->ev_q->ev_mbox->evbm;
if (!GET_BITMASK_BIT(evbm->bitmap, EV_ALARM)) {
- /* It might be possible that the virtual time has passed, but the alarm
- * hasn't arrived yet.
+ /* It might be possible that the virtual time has passed, but
+ * the alarm hasn't arrived yet.
*
- * We assume that if the bit is not set and the tick is enabled that
- * the kernel still has an alarm set for us. It is possible for the bit
- * to be set more than expected (disable an alarm, but fail to cancel
- * the alarm before it goes off, then enable it, and then we'll have the
- * bit set before the alarm expired). However, it is not possible that
- * the bit is clear and there is no alarm pending at this point. This
- * is because the only time we clear the bit is below, and then right
- * after that we set an alarm. (The bit is also clear at init time, and
- * we start the alarm when we enable the tick).
+ * We assume that if the bit is not set and the tick is enabled
+ * that the kernel still has an alarm set for us. It is
+ * possible for the bit to be set more than expected (disable an
+ * alarm, but fail to cancel the alarm before it goes off, then
+ * enable it, and then we'll have the bit set before the alarm
+ * expired). However, it is not possible that the bit is clear
+ * and there is no alarm pending at this point. This is because
+ * the only time we clear the bit is below, and then right after
+ * that we set an alarm. (The bit is also clear at init time,
+ * and we start the alarm when we enable the tick).
*
- * Anyway, the alarm should be arriving shortly. In this case, as in
- * the case where the bit gets set right after we check, we missed
- * polling for the event. The kernel will still __notify us, setting
- * notif_pending, and we'll notice the next time we attempt to leave
- * vcore context. */
+ * Anyway, the alarm should be arriving shortly. In this case,
+ * as in the case where the bit gets set right after we check,
+ * we missed polling for the event. The kernel will still
+ * __notify us, setting notif_pending, and we'll notice the next
+ * time we attempt to leave vcore context. */
uth_enable_notifs();
return 0;
}
/* Don't care about clobbering neighboring bits (non-atomic op) */
CLR_BITMASK_BIT(evbm->bitmap, EV_ALARM);
- /* As mentioned above, it is possible to still have an active alarm in the
- * kernel. We can still set a new time for the alarm, and it will just
- * update the kernel's awaiter. And if that alarm has fired, then we'll
- * just have a spurious setting of the bit. This does not affect our return
- * value, which is based on virtual time, not alarm resets. */
+ /* As mentioned above, it is possible to still have an active alarm in
+ * the kernel. We can still set a new time for the alarm, and it will
+ * just update the kernel's awaiter. And if that alarm has fired, then
+ * we'll just have a spurious setting of the bit. This does not affect
+ * our return value, which is based on virtual time, not alarm resets.
+ * */
virtual_now = vcore_account_uptime_ticks(vcore_id());
/* It's possible that we've fallen multiple ticks behind virtual now.
* In that case, we'll just jump ahead a bit */
@@ -167,9 +169,9 @@
vc_tick->next_deadline += vc_tick->period_ticks;
}
/* There's a slight chance we miss an alarm if the period is very small.
- * virtual_now is a little old. If the period is so small that this is a
- * problem and if we updated virtual now in the while loop, then we'd also
- * get caught in the while loop forever. */
+ * virtual_now is a little old. If the period is so small that this is
+ * a problem and if we updated virtual now in the while loop, then we'd
+ * also get caught in the while loop forever. */
from_now = vc_tick->next_deadline - virtual_now;
__vcore_tick_start(vc_tick, from_now);
uth_enable_notifs();
diff --git a/user/parlib/waitfreelist.c b/user/parlib/waitfreelist.c
index 133c4ef..1071834 100644
--- a/user/parlib/waitfreelist.c
+++ b/user/parlib/waitfreelist.c
@@ -11,37 +11,40 @@
void wfl_init(struct wfl *list)
{
- list->first.next = NULL;
- list->first.data = NULL;
- list->head = &list->first;
+ list->first.next = NULL;
+ list->first.data = NULL;
+ list->head = &list->first;
}
void wfl_destroy(struct wfl *list)
{
- assert(list->first.data == NULL);
- struct wfl_entry *p = list->first.next; // don't free the first element
- while (p != NULL) {
- assert(p->data == NULL);
- struct wfl_entry *tmp = p;
- p = p->next;
- free(tmp);
- }
+ assert(list->first.data == NULL);
+ struct wfl_entry *p = list->first.next; // don't free the first element
+
+ while (p != NULL) {
+ assert(p->data == NULL);
+ struct wfl_entry *tmp = p;
+ p = p->next;
+ free(tmp);
+ }
}
size_t wfl_capacity(struct wfl *list)
{
- size_t res = 0;
- for (struct wfl_entry *p = list->head; p != NULL; p = p->next)
- res++;
- return res;
+ size_t res = 0;
+
+ for (struct wfl_entry *p = list->head; p != NULL; p = p->next)
+ res++;
+ return res;
}
size_t wfl_size(struct wfl *list)
{
- size_t res = 0;
- for (struct wfl_entry *p = list->head; p != NULL; p = p->next)
- res += p->data != NULL;
- return res;
+ size_t res = 0;
+
+ for (struct wfl_entry *p = list->head; p != NULL; p = p->next)
+ res += p->data != NULL;
+ return res;
}
#if 0
@@ -82,50 +85,55 @@
void wfl_insert(struct wfl *list, void *data)
{
- struct wfl_entry *p = list->head; // list head is never null
- while (1) {
- if (p->data == NULL) {
- if (__sync_bool_compare_and_swap(&p->data, NULL, data))
- return;
- }
+ struct wfl_entry *p = list->head; // list head is never null
+
+ while (1) {
+ if (p->data == NULL) {
+ if (__sync_bool_compare_and_swap(&p->data, NULL, data))
+ return;
+ }
+
+ if (p->next == NULL)
+ break;
+
+ p = p->next;
+ }
+
+ struct wfl_entry *new_entry = malloc(sizeof(struct wfl_entry));
- if (p->next == NULL)
- break;
+ if (new_entry == NULL)
+ abort();
+ new_entry->data = data;
+ new_entry->next = NULL;
+
+ wmb();
+
+ struct wfl_entry *next;
- p = p->next;
- }
-
- struct wfl_entry *new_entry = malloc(sizeof(struct wfl_entry));
- if (new_entry == NULL)
- abort();
- new_entry->data = data;
- new_entry->next = NULL;
-
- wmb();
-
- struct wfl_entry *next;
- while ((next = __sync_val_compare_and_swap(&p->next, NULL, new_entry)))
- p = next;
+ while ((next = __sync_val_compare_and_swap(&p->next, NULL, new_entry)))
+ p = next;
}
void *wfl_remove(struct wfl *list)
{
- for (struct wfl_entry *p = list->head; p != NULL; p = p->next) {
- if (p->data != NULL) {
- void *data = atomic_swap_ptr(&p->data, 0);
- if (data != NULL)
- return data;
- }
- }
- return NULL;
+ for (struct wfl_entry *p = list->head; p != NULL; p = p->next) {
+ if (p->data != NULL) {
+ void *data = atomic_swap_ptr(&p->data, 0);
+
+ if (data != NULL)
+ return data;
+ }
+ }
+ return NULL;
}
size_t wfl_remove_all(struct wfl *list, void *data)
{
- size_t n = 0;
- for (struct wfl_entry *p = list->head; p != NULL; p = p->next) {
- if (p->data == data)
- n += __sync_bool_compare_and_swap(&p->data, data, NULL);
- }
- return n;
+ size_t n = 0;
+
+ for (struct wfl_entry *p = list->head; p != NULL; p = p->next) {
+ if (p->data == data)
+ n += __sync_bool_compare_and_swap(&p->data, data, NULL);
+ }
+ return n;
}
diff --git a/user/parlib/x86/vcore.c b/user/parlib/x86/vcore.c
index 32243d4..1b4dca3 100644
--- a/user/parlib/x86/vcore.c
+++ b/user/parlib/x86/vcore.c
@@ -44,12 +44,12 @@
/* Helper for writing the info we need later to the u_tf's stack. Also, note
* this goes backwards, since memory reads up the stack. */
struct restart_helper {
- void *notif_disab_loc;
- void *notif_pend_loc;
- struct syscall *sysc;
- uint64_t rdi_save;
- uint64_t rflags;
- uint64_t rip;
+ void *notif_disab_loc;
+ void *notif_pend_loc;
+ struct syscall *sysc;
+ uint64_t rdi_save;
+ uint64_t rflags;
+ uint64_t rip;
};
/* Static syscall, used for self-notifying. We never wait on it, and we
@@ -74,12 +74,12 @@
static void pop_hw_tf(struct hw_trapframe *tf, uint32_t vcoreid)
{
- #define X86_RED_ZONE_SZ 128
+ #define X86_RED_ZONE_SZ 128
struct restart_helper *rst;
struct preempt_data *vcpd = &__procdata.vcore_preempt_data[vcoreid];
- /* The stuff we need to write will be below the current stack and red zone
- * of the utf */
+ /* The stuff we need to write will be below the current stack and red
+ * zone of the utf */
rst = (struct restart_helper*)((void*)tf->tf_rsp - X86_RED_ZONE_SZ -
sizeof(struct restart_helper));
/* Fill in the info we'll need later */
@@ -106,37 +106,38 @@
"popq %%r13; "
"popq %%r14; "
"popq %%r15; "
- "addq $0x28, %%rsp; " /* move to the rsp slot in the tf */
+ "addq $0x28, %%rsp; " /* move to rsp slot in the tf */
"popq %%rsp; " /* change to the utf's %rsp */
"subq %[red], %%rsp; " /* jump over the redzone */
- "subq $0x10, %%rsp; " /* move rsp to below rdi's slot */
+ "subq $0x10, %%rsp; " /* move rsp to below rdi's slot*/
"pushq %%rdi; " /* save rdi, will clobber soon */
"subq $0x18, %%rsp; " /* move to notif_dis_loc slot */
"popq %%rdi; " /* load notif_disabled addr */
"movb $0x00, (%%rdi); " /* enable notifications */
- /* Need a wrmb() here so the write of enable_notif can't pass
- * the read of notif_pending (racing with a potential
- * cross-core call with proc_notify()). */
- "lock addb $0, (%%rdi);" /* LOCK is a CPU mb() */
- /* From here down, we can get interrupted and restarted */
- "popq %%rdi; " /* get notif_pending status loc */
+ /* Need a wrmb() here so the write of enable_notif can't
+ * pass the read of notif_pending (racing with a potential
+ * cross-core call with proc_notify()). */
+ "lock addb $0, (%%rdi);" /* LOCK is a CPU mb() */
+ /* From here down, we can get interrupted and restarted */
+ "popq %%rdi; " /* get notif_pending status loc*/
"testb $0x01, (%%rdi); " /* test if a notif is pending */
- "jz 1f; " /* if not pending, skip syscall */
- /* Actual syscall. Note we don't wait on the async call */
+ "jz 1f; " /* if not pending skip syscall */
+ /* Actual syscall. Note we don't wait on the async call */
"popq %%rdi; " /* &sysc, trap arg0 */
"pushq %%rsi; " /* save rax, will be trap arg1 */
"pushq %%rax; " /* save rax, will be trap ret */
- "movq $0x1, %%rsi; " /* sending one async syscall: arg1 */
+ "movq $0x1, %%rsi; " /* send one async syscall: arg1*/
"int %1; " /* fire the syscall */
"popq %%rax; " /* restore regs after syscall */
"popq %%rsi; "
"jmp 2f; " /* skip 1:, already popped */
- "1: addq $0x08, %%rsp; " /* discard &sysc (on non-sc path) */
- "2: popq %%rdi; " /* restore tf's %rdi (both paths) */
- "popfq; " /* restore utf's rflags */
- "ret %[red]; " /* return to the new PC, skip red */
+ "1: addq $0x08, %%rsp; " /* discard &sysc on non-sc path*/
+ "2: popq %%rdi; " /* restore tf's %rdi both paths*/
+ "popfq; " /* restore utf's rflags */
+ "ret %[red]; " /* ret to the new PC, skip red */
:
- : "g"(&tf->tf_rax), "i"(T_SYSCALL), [red]"i"(X86_RED_ZONE_SZ)
+ : "g"(&tf->tf_rax), "i"(T_SYSCALL),
+ [red]"i"(X86_RED_ZONE_SZ)
: "memory");
}
@@ -150,17 +151,17 @@
*
* The main issue here is that while our context was saved in an
* ABI-complaint manner, we may be starting up on a somewhat random FPU
- * state. Having gibberish in registers isn't a big deal, but some of the
- * FP environment settings could cause trouble. If fnclex; emms isn't
- * enough, we could also save/restore the entire FP env with fldenv, or do
- * an fninit before fldcw. */
+ * state. Having gibberish in registers isn't a big deal, but some of
+ * the FP environment settings could cause trouble. If fnclex; emms
+ * isn't enough, we could also save/restore the entire FP env with
+ * fldenv, or do an fninit before fldcw. */
asm volatile ("ldmxcsr %0" : : "m"(sw_tf->tf_mxcsr));
asm volatile ("fnclex; emms; fldcw %0" : : "m"(sw_tf->tf_fpucw));
- /* Basic plan: restore all regs, off rcx as the sw_tf. Switch to the new
- * stack, save the PC so we can jump to it later. Use clobberably
- * registers for the locations of sysc, notif_dis, and notif_pend. Once on
- * the new stack, we enable notifs, check if we missed one, and if so, self
- * notify. Note the syscall clobbers rax. */
+ /* Basic plan: restore all regs, off rcx as the sw_tf. Switch to the
+ * new stack, save the PC so we can jump to it later. Use clobberably
+ * registers for the locations of sysc, notif_dis, and notif_pend. Once
+ * on the new stack, we enable notifs, check if we missed one, and if
+ * so, self notify. Note the syscall clobbers rax. */
asm volatile ("movq 0x00(%0), %%rbx; " /* restore regs */
"movq 0x08(%0), %%rbp; "
"movq 0x10(%0), %%r12; "
@@ -170,16 +171,16 @@
"movq 0x30(%0), %%r8; " /* save rip in r8 */
"movq 0x38(%0), %%rsp; " /* jump to future stack */
"movb $0x00, (%2); " /* enable notifications */
- /* Need a wrmb() here so the write of enable_notif can't pass
- * the read of notif_pending (racing with a potential
+ /* Need a wrmb() here so the write of enable_notif can't
+ * pass the read of notif_pending (racing with a potential
* cross-core call with proc_notify()). */
"lock addb $0, (%2); " /* LOCK is a CPU mb() */
/* From here down, we can get interrupted and restarted */
"testb $0x01, (%3); " /* test if a notif is pending */
- "jz 1f; " /* if not pending, skip syscall */
+ "jz 1f; " /* if not pending, skip syscall*/
/* Actual syscall. Note we don't wait on the async call.
* &vc_entry is already in rdi (trap arg0). */
- "movq $0x1, %%rsi; " /* sending one async syscall: arg1 */
+ "movq $0x1, %%rsi; " /* send one async syscall: arg1*/
"int %4; " /* fire the syscall */
"1: jmp *%%r8; " /* ret saved earlier */
:
@@ -207,18 +208,20 @@
struct preempt_data *vcpd = vcpd_of(vcoreid);
/* We check early for notif_pending, since if we deal with it during
- * pop_hw_tf, we grow the stack slightly. If a thread consistently fails to
- * restart due to notif pending, it will eventually run off the bottom of
- * its stack. By performing the check here, we shrink that window. You'd
- * have to have a notif come after this check, but also *not* before this
- * check. If you PF in pop_user_ctx, this all failed. */
+ * pop_hw_tf, we grow the stack slightly. If a thread consistently
+ * fails to restart due to notif pending, it will eventually run off the
+ * bottom of its stack. By performing the check here, we shrink that
+ * window. You'd have to have a notif come after this check, but also
+ * *not* before this check. If you PF in pop_user_ctx, this all failed.
+ * */
if (vcpd->notif_pending) {
- /* if pop_user_ctx fails (and resets the vcore), the ctx contents must
- * be in VCPD (due to !UTHREAD_SAVED). it might already be there. */
+ /* if pop_user_ctx fails (and resets the vcore), the ctx
+ * contents must be in VCPD (due to !UTHREAD_SAVED). it might
+ * already be there. */
if (ctx != &vcpd->uthread_ctx)
vcpd->uthread_ctx = *ctx;
- /* To restart the vcore, we must have the right TLS, stack pointer, and
- * vc_ctx = TRUE. */
+ /* To restart the vcore, we must have the right TLS, stack
+ * pointer, and vc_ctx = TRUE. */
set_tls_desc((void*)vcpd->vcore_tls_desc);
begin_safe_access_tls_vars()
__vcore_context = TRUE;
@@ -256,7 +259,8 @@
struct preempt_data *vcpd = &__procdata.vcore_preempt_data[vcoreid];
assert(ctx->type == ROS_HW_CTX);
- /* The stuff we need to write will be below the current stack of the utf */
+ /* The stuff we need to write will be below the current stack of the utf
+ */
rst = (struct restart_helper*)((void*)tf->tf_rsp -
sizeof(struct restart_helper));
/* Fill in the info we'll need later */
@@ -281,20 +285,20 @@
"popq %%r13; "
"popq %%r14; "
"popq %%r15; "
- "addq $0x28, %%rsp; " /* move to the rsp slot in the tf */
+ "addq $0x28, %%rsp; " /* move to rsp slot in the tf */
"popq %%rsp; " /* change to the utf's %rsp */
- "subq $0x10, %%rsp; " /* move rsp to below rdi's slot */
+ "subq $0x10, %%rsp; " /* move rsp to below rdi's slot*/
"pushq %%rdi; " /* save rdi, will clobber soon */
"subq $0x18, %%rsp; " /* move to notif_dis_loc slot */
"popq %%rdi; " /* load notif_disabled addr */
"movb $0x00, (%%rdi); " /* enable notifications */
- /* Here's where we differ from the regular pop_user_ctx().
- * We need to adjust rsp and whatnot, but don't do test,
- * clear notif_pending, or call a syscall. */
- /* From here down, we can get interrupted and restarted */
+ /* Here's where we differ from the regular pop_user_ctx().
+ * We need to adjust rsp and whatnot, but don't do test,
+ * clear notif_pending, or call a syscall. */
+ /* From here down, we can get interrupted and restarted */
"addq $0x10, %%rsp; " /* move to rdi save slot */
"popq %%rdi; " /* restore tf's %rdi */
- "popfq; " /* restore utf's rflags */
+ "popfq; " /* restore utf's rflags */
"ret; " /* return to the new PC */
:
: "g"(&tf->tf_rax)
@@ -417,10 +421,11 @@
#ifndef __x86_64__
set_tls_desc(vcpd_of(id)->vcore_tls_desc);
#endif
- /* Every time the vcore comes up, it must set that it is in vcore context.
- * uthreads may share the same TLS as their vcore (when uthreads do not have
- * their own TLS), and if a uthread was preempted, __vcore_context == FALSE,
- * and that will continue to be true the next time the vcore pops up. */
+ /* Every time the vcore comes up, it must set that it is in vcore
+ * context. uthreads may share the same TLS as their vcore (when
+ * uthreads do not have their own TLS), and if a uthread was preempted,
+ * __vcore_context == FALSE, and that will continue to be true the next
+ * time the vcore pops up. */
__vcore_context = TRUE;
vcore_entry();
fprintf(stderr, "vcore_entry() should never return!\n");
diff --git a/user/pthread/pthread.c b/user/pthread/pthread.c
index e2e3bbb..0e635e5 100644
--- a/user/pthread/pthread.c
+++ b/user/pthread/pthread.c
@@ -98,8 +98,8 @@
{
uint32_t vcoreid = vcore_id();
if (current_uthread) {
- /* Prep the pthread to run any pending posix signal handlers registered
- * via pthread_kill once it is restored. */
+ /* Prep the pthread to run any pending posix signal handlers
+ * registered via pthread_kill once it is restored. */
uthread_prep_pending_signals(current_uthread);
/* Run the thread itself */
run_current_uthread();
@@ -107,9 +107,11 @@
}
/* no one currently running, so lets get someone from the ready queue */
struct pthread_tcb *new_thread = NULL;
- /* Try to get a thread. If we get one, we'll break out and run it. If not,
- * we'll try to yield. vcore_yield() might return, if we lost a race and
- * had a new event come in, one that may make us able to get a new_thread */
+
+ /* Try to get a thread. If we get one, we'll break out and run it. If
+ * not, we'll try to yield. vcore_yield() might return, if we lost a
+ * race and had a new event come in, one that may make us able to get a
+ * new_thread */
do {
handle_events(vcoreid);
__check_preempt_pending(vcoreid);
@@ -127,8 +129,9 @@
threads_active++;
threads_ready--;
mcs_pdr_unlock(&queue_lock);
- /* If you see what looks like the same uthread running in multiple
- * places, your list might be jacked up. Turn this on. */
+ /* If you see what looks like the same uthread running
+ * in multiple places, your list might be jacked up.
+ * Turn this on. */
printd("[P] got uthread %08p on vc %d state %08p flags %08p\n",
new_thread, vcoreid,
((struct uthread*)new_thread)->state,
@@ -138,12 +141,12 @@
mcs_pdr_unlock(&queue_lock);
/* no new thread, try to yield */
printd("[P] No threads, vcore %d is yielding\n", vcore_id());
- /* TODO: you can imagine having something smarter here, like spin for a
- * bit before yielding. */
+ /* TODO: you can imagine having something smarter here, like
+ * spin for a bit before yielding. */
vcore_yield(FALSE);
} while (1);
/* Prep the pthread to run any pending posix signal handlers registered
- * via pthread_kill once it is restored. */
+ * via pthread_kill once it is restored. */
uthread_prep_pending_signals((struct uthread*)new_thread);
/* Run the thread itself */
run_uthread((struct uthread*)new_thread);
@@ -162,33 +165,36 @@
static void pth_thread_runnable(struct uthread *uthread)
{
struct pthread_tcb *pthread = (struct pthread_tcb*)uthread;
- /* At this point, the 2LS can see why the thread blocked and was woken up in
- * the first place (coupling these things together). On the yield path, the
- * 2LS was involved and was able to set the state. Now when we get the
- * thread back, we can take a look. */
- printd("pthread %08p runnable, state was %d\n", pthread, pthread->state);
+
+ /* At this point, the 2LS can see why the thread blocked and was woken
+ * up in the first place (coupling these things together). On the yield
+ * path, the 2LS was involved and was able to set the state. Now when
+ * we get the thread back, we can take a look. */
+ printd("pthread %08p runnable, state was %d\n", pthread,
+ pthread->state);
switch (pthread->state) {
- case (PTH_CREATED):
- case (PTH_BLK_YIELDING):
- case (PTH_BLK_SYSC):
- case (PTH_BLK_PAUSED):
- case (PTH_BLK_MUTEX):
- case (PTH_BLK_MISC):
- /* can do whatever for each of these cases */
- break;
- default:
- panic("Odd state %d for pthread %08p\n", pthread->state, pthread);
+ case (PTH_CREATED):
+ case (PTH_BLK_YIELDING):
+ case (PTH_BLK_SYSC):
+ case (PTH_BLK_PAUSED):
+ case (PTH_BLK_MUTEX):
+ case (PTH_BLK_MISC):
+ /* can do whatever for each of these cases */
+ break;
+ default:
+ panic("Odd state %d for pthread %08p\n", pthread->state,
+ pthread);
}
pthread->state = PTH_RUNNABLE;
- /* Insert the newly created thread into the ready queue of threads.
- * It will be removed from this queue later when vcore_entry() comes up */
+ /* Insert the newly created thread into the ready queue of threads. It
+ * will be removed from this queue later when vcore_entry() comes up */
mcs_pdr_lock(&queue_lock);
/* Again, GIANT WARNING: if you change this, change batch wakeup code */
TAILQ_INSERT_TAIL(&ready_queue, pthread, tq_next);
threads_ready++;
mcs_pdr_unlock(&queue_lock);
- /* Smarter schedulers should look at the num_vcores() and how much work is
- * going on to make a decision about how many vcores to request. */
+ /* Smarter schedulers should look at the num_vcores() and how much work
+ * is going on to make a decision about how many vcores to request. */
vcore_request_more(threads_ready);
}
@@ -209,9 +215,9 @@
__pthread_generic_yield(pthread);
/* communicate to pth_thread_runnable */
pthread->state = PTH_BLK_PAUSED;
- /* At this point, you could do something clever, like put it at the front of
- * the runqueue, see if it was holding a lock, do some accounting, or
- * whatever. */
+ /* At this point, you could do something clever, like put it at the
+ * front of the runqueue, see if it was holding a lock, do some
+ * accounting, or whatever. */
pth_thread_runnable(uthread);
}
@@ -236,14 +242,16 @@
struct syscall *sysc;
assert(in_vcore_context());
/* if we just got a bit (not a msg), it should be because the process is
- * still an SCP and hasn't started using the MCP ev_q yet (using the simple
- * ev_q and glibc's blockon) or because the bit is still set from an old
- * ev_q (blocking syscalls from before we could enter vcore ctx). Either
- * way, just return. Note that if you screwed up the pth ev_q and made it
- * NO_MSG, you'll never notice (we used to assert(ev_msg)). */
+ * still an SCP and hasn't started using the MCP ev_q yet (using the
+ * simple ev_q and glibc's blockon) or because the bit is still set from
+ * an old ev_q (blocking syscalls from before we could enter vcore ctx).
+ * Either way, just return. Note that if you screwed up the pth ev_q
+ * and made it NO_MSG, you'll never notice (we used to assert(ev_msg)).
+ * */
if (!ev_msg)
return;
- /* It's a bug if we don't have a msg (we're handling a syscall bit-event) */
+ /* It's a bug if we don't have a msg (we're handling a syscall
+ * bit-event) */
assert(ev_msg);
/* Get the sysc from the message and just restart it */
sysc = ev_msg->ev_arg3;
@@ -268,8 +276,8 @@
sysc->u_data = uthread;
/* Register our vcore's syscall ev_q to hear about this syscall. */
if (!register_evq(sysc, sysc_mgmt[vcoreid].ev_q)) {
- /* Lost the race with the call being done. The kernel won't send the
- * event. Just restart him. */
+ /* Lost the race with the call being done. The kernel won't
+ * send the event. Just restart him. */
restart_thread(sysc);
}
/* GIANT WARNING: do not touch the thread after this point. */
@@ -280,8 +288,8 @@
struct pthread_tcb *pthread = (struct pthread_tcb*)uthread;
__pthread_generic_yield(pthread);
- /* Whatever we do here, we are mostly communicating to our future selves in
- * pth_thread_runnable(), which gets called by whoever triggered this
+ /* Whatever we do here, we are mostly communicating to our future selves
+ * in pth_thread_runnable(), which gets called by whoever triggered this
* callback */
switch (flags) {
case UTH_EXT_BLK_YIELD:
@@ -456,9 +464,9 @@
uthread_cleanup(uth);
/* Cleanup, mirroring pthread_create() */
__pthread_free_stack(pthread);
- /* If we were the last pthread, we exit for the whole process. Keep in mind
- * that thread0 is counted in this, so this will only happen if that thread
- * calls pthread_exit(). */
+ /* If we were the last pthread, we exit for the whole process. Keep in
+ * mind that thread0 is counted in this, so this will only happen if
+ * that thread calls pthread_exit(). */
if ((atomic_fetch_and_add(&threads_total, -1) == 1))
exit(0);
}
@@ -573,7 +581,7 @@
}
int pthread_attr_getstack(const pthread_attr_t *__restrict __attr,
- void **__stackaddr, size_t *__stacksize)
+ void **__stackaddr, size_t *__stacksize)
{
*__stackaddr = __attr->stackaddr;
*__stacksize = __attr->stacksize;
@@ -606,11 +614,13 @@
if (in_multi_mode())
panic("Tried to fork from an MCP!");
pth_0->fork_generation = fork_generation + 1;
- cmb(); /* in case we get interrupted after incrementing the global gen */
- /* We're single-core and thread0 here, so we can modify fork_generation */
+ /* in case we get interrupted after incrementing the global gen */
+ cmb();
+ /* We're single-core and thread0 here, so we can modify fork_generation
+ */
fork_generation++;
- /* At this point, whether we come back as the child or the parent, no old
- * thread (from the previous generation) will run. */
+ /* At this point, whether we come back as the child or the parent, no
+ * old thread (from the previous generation) will run. */
}
static void pth_post_fork(pid_t ret)
@@ -637,7 +647,8 @@
ret = posix_memalign((void**)&t, __alignof__(struct pthread_tcb),
sizeof(struct pthread_tcb));
assert(!ret);
- memset(t, 0, sizeof(struct pthread_tcb)); /* aggressively 0 for bugs */
+ /* aggressively 0 for bugs */
+ memset(t, 0, sizeof(struct pthread_tcb));
t->id = get_next_pid();
t->fork_generation = fork_generation;
t->stacksize = USTACK_NUM_PAGES * PGSIZE;
@@ -651,12 +662,13 @@
threads_active++;
TAILQ_INSERT_TAIL(&active_queue, t, tq_next);
mcs_pdr_unlock(&queue_lock);
- /* Tell the kernel where and how we want to receive events. This is just an
- * example of what to do to have a notification turned on. We're turning on
- * USER_IPIs, posting events to vcore 0's vcpd, and telling the kernel to
- * send to vcore 0. Note sys_self_notify will ignore the vcoreid and
- * private preference. Also note that enable_kevent() is just an example,
- * and you probably want to use parts of event.c to do what you want. */
+ /* Tell the kernel where and how we want to receive events. This is
+ * just an example of what to do to have a notification turned on.
+ * We're turning on USER_IPIs, posting events to vcore 0's vcpd, and
+ * telling the kernel to send to vcore 0. Note sys_self_notify will
+ * ignore the vcoreid and private preference. Also note that
+ * enable_kevent() is just an example, and you probably want to use
+ * parts of event.c to do what you want. */
enable_kevent(EV_USER_IPI, 0, EVENT_IPI | EVENT_VCORE_PRIVATE);
/* Set up the per-vcore structs to track outstanding syscalls */
sysc_mgmt = malloc(sizeof(struct sysc_mgmt) * max_vcores());
@@ -668,8 +680,8 @@
MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE,
-1, 0);
assert(mmap_block);
- /* Could be smarter and do this on demand (in case we don't actually want
- * max_vcores()). */
+ /* Could be smarter and do this on demand (in case we don't actually
+ * want max_vcores()). */
for (int i = 0; i < max_vcores(); i++) {
/* Each vcore needs to point to a non-VCPD ev_q */
sysc_mgmt[i].ev_q = get_eventq_raw();
@@ -686,9 +698,10 @@
#endif
#if 0 /* One global ev_mbox, separate ev_q per vcore */
struct event_mbox *sysc_mbox = malloc(sizeof(struct event_mbox));
- uintptr_t two_pages = (uintptr_t)mmap(0, PGSIZE * 2, PROT_WRITE | PROT_READ,
- MAP_POPULATE | MAP_ANONYMOUS |
- MAP_PRIVATE, -1, 0);
+ uintptr_t two_pages = (uintptr_t)mmap(0, PGSIZE * 2, PROT_WRITE |
+ PROT_READ, MAP_POPULATE |
+ MAP_ANONYMOUS | MAP_PRIVATE, -1,
+ 0);
printd("Global ucq: %08p\n", &sysc_mbox->ev_msgs);
assert(sysc_mbox);
assert(two_pages);
@@ -716,9 +729,9 @@
parlib_init_once_racy(return);
uthread_mcp_init();
- /* From here forward we are an MCP running on vcore 0. Could consider doing
- * other pthread specific initialization based on knowing we are an mcp
- * after this point. */
+ /* From here forward we are an MCP running on vcore 0. Could consider
+ * doing other pthread specific initialization based on knowing we are
+ * an mcp after this point. */
}
int __pthread_create(pthread_t *thread, const pthread_attr_t *attr,
@@ -729,16 +742,17 @@
struct pthread_tcb *pthread;
int ret;
- /* For now, unconditionally become an mcp when creating a pthread (if not
- * one already). This may change in the future once we support 2LSs in an
- * SCP. */
+ /* For now, unconditionally become an mcp when creating a pthread (if
+ * not one already). This may change in the future once we support 2LSs
+ * in an SCP. */
pthread_mcp_init();
parent = (struct pthread_tcb*)current_uthread;
ret = posix_memalign((void**)&pthread, __alignof__(struct pthread_tcb),
sizeof(struct pthread_tcb));
assert(!ret);
- memset(pthread, 0, sizeof(struct pthread_tcb)); /* aggressively 0 for bugs*/
+ /* aggressively 0 for bugs*/
+ memset(pthread, 0, sizeof(struct pthread_tcb));
pthread->stacksize = PTHREAD_STACK_SIZE; /* default */
pthread->state = PTH_CREATED;
pthread->id = get_next_pid();
@@ -746,7 +760,7 @@
SLIST_INIT(&pthread->cr_stack);
/* Respect the attributes */
if (attr) {
- if (attr->stacksize) /* don't set a 0 stacksize */
+ if (attr->stacksize) /* don't set a 0 stacksize */
pthread->stacksize = attr->stacksize;
if (attr->detachstate == PTHREAD_CREATE_DETACHED)
uth_attr.detached = TRUE;
@@ -755,8 +769,8 @@
if (__pthread_allocate_stack(pthread))
printf("We're fucked\n");
/* Set the u_tf to start up in __pthread_run, which will call the real
- * start_routine and pass it the arg. Note those aren't set until later in
- * pthread_create(). */
+ * start_routine and pass it the arg. Note those aren't set until later
+ * in pthread_create(). */
init_user_ctx(&pthread->uthread.u_ctx, (uintptr_t)&__pthread_run,
(uintptr_t)(pthread->stacktop));
pthread->start_routine = start_routine;
@@ -831,6 +845,7 @@
{
struct pthread_tcb *p = pthread_self();
struct pthread_cleanup_routine *r = malloc(sizeof(*r));
+
r->routine = routine;
r->arg = arg;
SLIST_INSERT_HEAD(&p->cr_stack, r, cr_next);
@@ -840,6 +855,7 @@
{
struct pthread_tcb *p = pthread_self();
struct pthread_cleanup_routine *r = SLIST_FIRST(&p->cr_stack);
+
if (r) {
SLIST_REMOVE_HEAD(&p->cr_stack, cr_next);
if (execute)
@@ -992,7 +1008,8 @@
{
if (a) {
if (a->pshared != PTHREAD_PROCESS_PRIVATE)
- fprintf(stderr, "pthreads only supports private condvars");
+ fprintf(stderr,
+ "pthreads only supports private condvars");
/* We also ignore clock_id */
}
uth_cond_var_init(c);
@@ -1141,17 +1158,18 @@
int pthread_equal(pthread_t t1, pthread_t t2)
{
- return t1 == t2;
+ return t1 == t2;
}
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
{
- /* pthread_once's init routine doesn't take an argument, like parlibs. This
- * means the func will be run with an argument passed to it, but it'll be
- * ignored. */
+ /* pthread_once's init routine doesn't take an argument, like parlibs.
+ * This means the func will be run with an argument passed to it, but
+ * it'll be ignored. */
parlib_run_once(once_control, (void (*)(void *))init_routine, NULL);
- /* The return for pthread_once isn't an error from the function, it's just
- * an overall error. Note pthread's init_routine() has no return value. */
+ /* The return for pthread_once isn't an error from the function, it's
+ * just an overall error. Note pthread's init_routine() has no return
+ * value. */
return 0;
}
@@ -1168,19 +1186,19 @@
}
struct barrier_junk {
- pthread_barrier_t *b;
- int ls;
+ pthread_barrier_t *b;
+ int ls;
};
/* Helper for spinning sync, returns TRUE if it is okay to keep spinning.
*
* Alternatives include:
- * old_count <= num_vcores() (barrier code, pass in old_count as *state,
- * but this only works if every awake pthread
- * will belong to the barrier).
- * just spin for a bit (use *state to track spins)
- * FALSE (always is safe)
- * etc...
+ * old_count <= num_vcores() (barrier code, pass in old_count as *state,
+ * but this only works if every awake pthread
+ * will belong to the barrier).
+ * just spin for a bit (use *state to track spins)
+ * FALSE (always is safe)
+ * etc...
* 'threads_ready' isn't too great since sometimes it'll be non-zero when it is
* about to become 0. We really want "I have no threads waiting to run that
* aren't going to run on their on unless this core yields instead of spins". */
@@ -1199,7 +1217,8 @@
uthread_has_blocked(uthread, UTH_EXT_BLK_MUTEX);
/* TODO: if we used a trylock, we could bail as soon as we see sense */
spin_pdr_lock(&b->lock);
- /* If sense is ls (our free value), we lost the race and shouldn't sleep */
+ /* If sense is ls (our free value), we lost the race and shouldn't sleep
+ */
if (b->sense == ls) {
spin_pdr_unlock(&b->lock);
uthread_runnable(uthread);
@@ -1228,7 +1247,8 @@
int pthread_barrier_wait(pthread_barrier_t *b)
{
unsigned int spin_state = 0;
- int ls = !b->sense; /* when b->sense is the value we read, then we're free*/
+ /* when b->sense is the value we read, then we're free*/
+ int ls = !b->sense;
uth_sync_t restartees;
struct uthread *uth_i;
struct barrier_junk local_junk;
@@ -1236,12 +1256,13 @@
long old_count = atomic_fetch_and_add(&b->count, -1);
if (old_count == 1) {
- /* TODO: we might want to grab the lock right away, so a few short
- * circuit faster? */
+ /* TODO: we might want to grab the lock right away, so a few
+ * short circuit faster? */
atomic_set(&b->count, b->total_threads);
- /* we still need to maintain ordering btw count and sense, in case
- * another thread doesn't sleep (if we wrote sense first, they could
- * break out, race around, and muck with count before it is time) */
+ /* we still need to maintain ordering btw count and sense, in
+ * case another thread doesn't sleep (if we wrote sense first,
+ * they could break out, race around, and muck with count before
+ * it is time) */
/* wmb(); handled by the spin lock */
spin_pdr_lock(&b->lock);
/* Sense is only protected in addition to decisions to sleep */
@@ -1258,7 +1279,8 @@
__uth_sync_wake_all(&restartees);
return PTHREAD_BARRIER_SERIAL_THREAD;
} else {
- /* Spin if there are no other threads to run. No sense sleeping */
+ /* Spin if there are no other threads to run. No sense sleeping
+ */
do {
if (b->sense == ls)
return 0;
@@ -1342,8 +1364,8 @@
{
/* The set of acceptable priorities are based on the scheduling policy.
* We'll just accept any old number, since we might not know the policy
- * yet. I didn't see anything in the man pages saying attr had to have a
- * policy set before setting priority. */
+ * yet. I didn't see anything in the man pages saying attr had to have
+ * a policy set before setting priority. */
attr->sched_priority = param->sched_priority;
return 0;
}
diff --git a/user/pthread/pthread.h b/user/pthread/pthread.h
index 64d38a5..d85742e 100644
--- a/user/pthread/pthread.h
+++ b/user/pthread/pthread.h
@@ -15,14 +15,14 @@
__BEGIN_DECLS
/* Pthread states. These are mostly examples for other 2LSs */
-#define PTH_CREATED 1
+#define PTH_CREATED 1
#define PTH_RUNNABLE 2
-#define PTH_RUNNING 3
-#define PTH_EXITING 4
-#define PTH_BLK_YIELDING 5 /* brief state btw pth_yield and pth_runnable */
+#define PTH_RUNNING 3
+#define PTH_EXITING 4
+#define PTH_BLK_YIELDING 5 /* btw pth_yield and pth_runnable */
#define PTH_BLK_SYSC 6 /* blocked on a syscall */
-#define PTH_BLK_MUTEX 7 /* blocked externally, possibly on a mutex */
-#define PTH_BLK_PAUSED 8 /* handed back to us from uthread code */
+#define PTH_BLK_MUTEX 7 /* blocked externally */
+#define PTH_BLK_PAUSED 8 /* handed back from uthread code */
#define PTH_BLK_MISC 9 /* catch-all from uthread code */
/* Entry for a pthread_cleanup_routine on the stack of cleanup handlers. */
@@ -55,7 +55,7 @@
* kernel to signal us. We don't need a lock since this is per-vcore and
* accessed in vcore context. */
struct sysc_mgmt {
- struct event_queue *ev_q;
+ struct event_queue *ev_q;
};
#define PTHREAD_ONCE_INIT PARLIB_ONCE_INIT
@@ -72,17 +72,17 @@
} pthread_mutexattr_t;
typedef struct {
- int type;
- uth_mutex_t mtx;
- uth_recurse_mutex_t r_mtx;
+ int type;
+ uth_mutex_t mtx;
+ uth_recurse_mutex_t r_mtx;
} pthread_mutex_t;
#define PTHREAD_MUTEX_INITIALIZER { PTHREAD_MUTEX_DEFAULT, UTH_MUTEX_INIT, \
UTH_RECURSE_MUTEX_INIT }
typedef int clockid_t;
typedef struct {
- int pshared;
- clockid_t clock;
+ int pshared;
+ clockid_t clock;
} pthread_condattr_t;
#define PTHREAD_COND_INITIALIZER UTH_COND_VAR_INIT
@@ -98,12 +98,13 @@
typedef struct
{
- int total_threads;
- volatile int sense; /* state of barrier, flips btw runs */
- atomic_t count;
+ int total_threads;
+ /* state of barrier, flips btw runs */
+ volatile int sense;
+ atomic_t count;
struct spin_pdr_lock lock;
- uth_sync_t waiters;
- int nr_waiters;
+ uth_sync_t waiters;
+ int nr_waiters;
} pthread_barrier_t;
/* Detach state. */
diff --git a/user/pthread/semaphore.h b/user/pthread/semaphore.h
index 6ac6177..6778e06 100644
--- a/user/pthread/semaphore.h
+++ b/user/pthread/semaphore.h
@@ -26,7 +26,7 @@
#define SEM_FAILED ((sem_t *) 0)
typedef struct {
- uth_semaphore_t real_sem;
+ uth_semaphore_t real_sem;
} sem_t;
int sem_init(sem_t *__sem, int __pshared, unsigned int __value);
diff --git a/user/utest/alarm.c b/user/utest/alarm.c
index 07d2d27..ce17f62 100644
--- a/user/utest/alarm.c
+++ b/user/utest/alarm.c
@@ -40,7 +40,6 @@
int num_utests = sizeof(utests) / sizeof(struct utest);
int main(int argc, char *argv[]) {
- // Run test suite passing it all the args as whitelist of what tests to run.
char **whitelist = &argv[1];
int whitelist_len = argc - 1;
RUN_TEST_SUITE(utests, num_utests, whitelist, whitelist_len);
diff --git a/user/utest/atexit.c b/user/utest/atexit.c
index 118a838..d32a9bf 100644
--- a/user/utest/atexit.c
+++ b/user/utest/atexit.c
@@ -32,8 +32,8 @@
static void main_atexit(void)
{
/* Using the non-UT assert, since the test_atexit_threads() has already
- * returned. Also, since the child called atexit() after main, its handler
- * should run first, according to the man page. */
+ * returned. Also, since the child called atexit() after main, its
+ * handler should run first, according to the man page. */
assert(child_ran_atexit);
}
@@ -57,7 +57,6 @@
int main(int argc, char *argv[])
{
- // Run test suite passing it all the args as whitelist of what tests to run.
char **whitelist = &argv[1];
int whitelist_len = argc - 1;
diff --git a/user/utest/cv.c b/user/utest/cv.c
index 5a56eb9..a271955 100644
--- a/user/utest/cv.c
+++ b/user/utest/cv.c
@@ -12,11 +12,11 @@
/* <--- Begin definition of test cases ---> */
struct common_args {
- uth_cond_var_t *cv;
- uth_mutex_t *mtx;
- bool flag;
- unsigned int wait_sleep;
- unsigned int sig_sleep;
+ uth_cond_var_t *cv;
+ uth_mutex_t *mtx;
+ bool flag;
+ unsigned int wait_sleep;
+ unsigned int sig_sleep;
};
#define PTH_TEST_TRUE (void*)1
@@ -41,9 +41,9 @@
args->flag = TRUE;
uth_mutex_unlock(args->mtx);
/* We can actually signal outside the mutex if we want. Remember the
- * invariant: whenever the flag is set from FALSE to TRUE, all waiters that
- * saw FALSE are on the CV's waitqueue. That's true even after we unlock
- * the mutex. */
+ * invariant: whenever the flag is set from FALSE to TRUE, all waiters
+ * that saw FALSE are on the CV's waitqueue. That's true even after we
+ * unlock the mutex. */
uth_cond_var_signal(args->cv);
return PTH_TEST_TRUE;
}
@@ -57,9 +57,9 @@
args->flag = TRUE;
uth_mutex_unlock(args->mtx);
/* We can actually signal outside the mutex if we want. Remember the
- * invariant: whenever the flag is set from FALSE to TRUE, all waiters that
- * saw FALSE are on the CV's waitqueue. That's true even after we unlock
- * the mutex. */
+ * invariant: whenever the flag is set from FALSE to TRUE, all waiters
+ * that saw FALSE are on the CV's waitqueue. That's true even after we
+ * unlock the mutex. */
uth_cond_var_broadcast(args->cv);
return PTH_TEST_TRUE;
}
@@ -203,7 +203,8 @@
ret = pthread_create(&waiter, 0, __cv_waiter_no_mutex, args);
UT_ASSERT(!ret);
- ret = pthread_create(&signaller, 0, __cv_signaller_no_mutex, args);
+ ret = pthread_create(&signaller, 0, __cv_signaller_no_mutex,
+ args);
UT_ASSERT(!ret);
ret = pthread_join(waiter, &wait_join);
UT_ASSERT(!ret);
@@ -231,7 +232,8 @@
args->sig_sleep = 1000;
for (int i = 0; i < NR_WAITERS; i++) {
- ret = pthread_create(&waiters[i], 0, __cv_waiter_no_mutex, args);
+ ret = pthread_create(&waiters[i], 0, __cv_waiter_no_mutex,
+ args);
UT_ASSERT(!ret);
}
ret = pthread_create(&bcaster, 0, __cv_broadcaster_no_mutex, args);
@@ -372,7 +374,8 @@
got_it = uth_semaphore_timed_down(&sem, timeout);
UT_ASSERT(got_it);
- /* Second time we still hold the sem and would block and should time out. */
+ /* Second time we still hold the sem and would block and should time
+ * out. */
UT_ASSERT(sem.count == 0);
ret = clock_gettime(CLOCK_REALTIME, timeout);
UT_ASSERT(!ret);
@@ -427,7 +430,8 @@
UT_ASSERT(r_mtx.count == 3);
UT_ASSERT(r_mtx.mtx.count == 0);
- /* Unlock our three locks, then make sure the semaphore/mtx is unlocked. */
+ /* Unlock our three locks, then make sure the semaphore/mtx is unlocked.
+ */
uth_recurse_mutex_unlock(&r_mtx);
uth_recurse_mutex_unlock(&r_mtx);
uth_recurse_mutex_unlock(&r_mtx);
@@ -532,7 +536,6 @@
int main(int argc, char *argv[])
{
- // Run test suite passing it all the args as whitelist of what tests to run.
char **whitelist = &argv[1];
int whitelist_len = argc - 1;
diff --git a/user/utest/dtls.c b/user/utest/dtls.c
index 294f378..14fe450 100644
--- a/user/utest/dtls.c
+++ b/user/utest/dtls.c
@@ -49,7 +49,8 @@
key = dtls_key_create(0);
set_dtls(key, set_val);
got_val = get_dtls(key);
- UT_ASSERT_FMT("Expected %p, got %p", got_val == set_val, set_val, got_val);
+ UT_ASSERT_FMT("Expected %p, got %p", got_val == set_val, set_val,
+ got_val);
destroy_dtls();
return TRUE;
}
@@ -101,7 +102,6 @@
int main(int argc, char *argv[])
{
- // Run test suite passing it all the args as whitelist of what tests to run.
char **whitelist = &argv[1];
int whitelist_len = argc - 1;
diff --git a/user/utest/efence.c b/user/utest/efence.c
index b1b6229..09ce647 100644
--- a/user/utest/efence.c
+++ b/user/utest/efence.c
@@ -64,7 +64,7 @@
bool test_catching_fault(void)
{
- pthread_yield(); /* link in pth for intra-thread signals (SIGSEGV) */
+ pthread_yield();/* link in pth for intra-thread signals (SIGSEGV) */
sigaction(SIGSEGV, &sigact, 0);
blob = malloc(PGSIZE);
if (!setjmp(save)) {
@@ -89,7 +89,6 @@
int main(int argc, char *argv[])
{
- // Run test suite passing it all the args as whitelist of what tests to run.
char **whitelist = &argv[1];
int whitelist_len = argc - 1;
diff --git a/user/utest/example.c b/user/utest/example.c
index e2094d5..bc07464 100644
--- a/user/utest/example.c
+++ b/user/utest/example.c
@@ -29,9 +29,9 @@
int num_utests = sizeof(utests) / sizeof(struct utest);
int main(int argc, char *argv[]) {
- // Run test suite passing it all the args as whitelist of what tests to run.
char **whitelist = &argv[1];
int whitelist_len = argc - 1;
+
RUN_TEST_SUITE(utests, num_utests, whitelist, whitelist_len);
}
diff --git a/user/utest/file-posix.c b/user/utest/file-posix.c
index 1aab4fe..26659ec 100644
--- a/user/utest/file-posix.c
+++ b/user/utest/file-posix.c
@@ -85,8 +85,8 @@
int main(int argc, char *argv[])
{
- // Run test suite passing it all the args as whitelist of what tests to run.
char **whitelist = &argv[1];
int whitelist_len = argc - 1;
+
RUN_TEST_SUITE(utests, num_utests, whitelist, whitelist_len);
}
diff --git a/user/utest/include/utest.h b/user/utest/include/utest.h
index 1a4e03a..627c2bf 100644
--- a/user/utest/include/utest.h
+++ b/user/utest/include/utest.h
@@ -19,38 +19,39 @@
/*
* Macros for assertions.
*/
-#define UT_ASSERT(test, ...) \
+#define UT_ASSERT(test, ...) \
UT_ASSERT_M(#test, test, __VA_ARGS__)
-#define UT_ASSERT_M(message, test, ...) \
- do { \
- if (!(test)) { \
- char fmt[] = "Assertion failure in %s() at %s:%d: %s"; \
- sprintf(utest_msg, fmt, __FUNCTION__, __FILE__, __LINE__, message); \
- __VA_ARGS__; \
- return false; \
- } \
- } while (0)
+#define UT_ASSERT_M(message, test, ...) \
+do { \
+ if (!(test)) { \
+ char fmt[] = "Assertion failure in %s() at %s:%d: %s"; \
+ sprintf(utest_msg, fmt, __FUNCTION__, __FILE__, __LINE__, \
+ message); \
+ __VA_ARGS__; \
+ return false; \
+ } \
+} while (0)
/* If 'test' fails, Sets an assert message, which can be a format string, and
* returns false. */
#define UT_ASSERT_FMT(message, test, ...) \
- do { \
- if (!(test)) { \
- char fmt[] = "Assertion failure in %s() at %s:%d: " #message; \
- sprintf(utest_msg, fmt, __func__, __FILE__, __LINE__, \
- ##__VA_ARGS__); \
- return false; \
- } \
- } while (0)
+do { \
+ if (!(test)) { \
+ char fmt[] = "Assertion failure in %s() at %s:%d: " #message; \
+ sprintf(utest_msg, fmt, __func__, __FILE__, __LINE__, \
+ ##__VA_ARGS__); \
+ return false; \
+ } \
+} while (0)
/*
* Structs and macros for registering test cases.
*/
struct utest {
char name[256]; // Name of the test function.
- bool (*func)(void); // Name of the test function, should be equal to 'name'.
+ bool (*func)(void); // Name of the test function, should be = to 'name'.
bool enabled; // Whether or not to run the test.
};
@@ -61,22 +62,24 @@
/*
* Creates all the runnable code for a test suite.
*/
-#define TEST_SUITE(__suite_name) \
- char utest_msg[1024]; \
+#define TEST_SUITE(__suite_name) \
+ char utest_msg[1024]; \
char suite_name[] = __suite_name;
-#define RUN_TEST_SUITE(utests, num_utests, whitelist, whitelist_len) \
- do { \
- if (whitelist_len > 0) \
- apply_whitelist(whitelist, whitelist_len, utests, num_utests); \
- run_utests(suite_name, utests, num_utests); \
- } while (0)
+#define RUN_TEST_SUITE(utests, num_utests, whitelist, whitelist_len) \
+do { \
+ if (whitelist_len > 0) \
+ apply_whitelist(whitelist, whitelist_len, utests, num_utests); \
+ run_utests(suite_name, utests, num_utests); \
+} while (0)
/* Disables all the tests not passed through a whitelist. */
static void apply_whitelist(char *whitelist[], int whitelist_len,
- struct utest tests[], int num_tests) {
- for (int i=0; i<num_tests; i++) {
+ struct utest tests[], int num_tests)
+{
+ for (int i = 0; i < num_tests; i++) {
struct utest *test = &tests[i];
+
if (test->enabled) {
for (int j = 0; j < whitelist_len; ++j) {
test->enabled = false;
@@ -105,9 +108,11 @@
char fmt[] = "\t%s [%s](%llu.%06llus) %s\n";
if (result) {
- printf(fmt, "PASSED", test->name, et_s, et_us, "");
+ printf(fmt, "PASSED", test->name, et_s, et_us,
+ "");
} else {
- printf(fmt, "FAILED", test->name, et_s, et_us, utest_msg);
+ printf(fmt, "FAILED", test->name, et_s, et_us,
+ utest_msg);
}
} else {
printf("\tDISABLED [%s]\n", test->name);
diff --git a/user/utest/mmap_pf.c b/user/utest/mmap_pf.c
index 7d0295a..7b59242 100644
--- a/user/utest/mmap_pf.c
+++ b/user/utest/mmap_pf.c
@@ -65,7 +65,6 @@
int main(int argc, char *argv[])
{
- // Run test suite passing it all the args as whitelist of what tests to run.
char **whitelist = &argv[1];
int whitelist_len = argc - 1;
diff --git a/user/utest/pthread.c b/user/utest/pthread.c
index e84f79a..e24931c 100644
--- a/user/utest/pthread.c
+++ b/user/utest/pthread.c
@@ -24,7 +24,6 @@
int main(int argc, char *argv[])
{
- // Run test suite passing it all the args as whitelist of what tests to run.
char **whitelist = &argv[1];
int whitelist_len = argc - 1;
diff --git a/user/utest/pvcalarm.c b/user/utest/pvcalarm.c
index 7160a88..f878bf3 100644
--- a/user/utest/pvcalarm.c
+++ b/user/utest/pvcalarm.c
@@ -18,20 +18,21 @@
pthread_mcp_init();
vcore_request_total(max_vcores());
parlib_never_vc_request = TRUE;
- for (int i=0; i<max_vcores(); i++)
+ for (int i = 0; i < max_vcores(); i++)
count[i] = 0;
uint64_t now, then;
now = tsc2usec(read_tsc());
enable_pvcalarms(PVCALARM_PROF, INTERVAL, pvcalarm_callback);
- for (int i=0; i<max_vcores(); i++)
+ for (int i = 0; i < max_vcores(); i++)
while(count[i] < ITERS)
cpu_relax();
disable_pvcalarms();
then = tsc2usec(read_tsc());
UT_ASSERT_M("Alarms finished too soon", then > (now + INTERVAL*ITERS));
- UT_ASSERT_M("Alarms finished too late", then < (now + 2*INTERVAL*ITERS));
+ UT_ASSERT_M("Alarms finished too late", then < (now +
+ 2*INTERVAL*ITERS));
return true;
}
@@ -53,8 +54,10 @@
pthread_sigmask(SIG_UNBLOCK, &s, NULL);
int old_count = 0, new_count = 0;
while(1) {
- while((new_count = atomic_read((atomic_t)__count)) <= old_count);
- if (new_count >= ITERATIONS) break;
+ while ((new_count = atomic_read((atomic_t)__count)) <=
+ old_count);
+ if (new_count >= ITERATIONS)
+ break;
old_count = new_count;
pthread_yield();
}
@@ -74,16 +77,17 @@
sigaddset(&s, SIGPROF);
pthread_sigmask(SIG_BLOCK, &s, NULL);
struct sigaction sigact = {.sa_handler = signal_handler, 0};
+
sigaction(SIGPROF, &sigact, 0);
- for (int i=0; i<NUM_PTHREADS; i++)
+ for (int i = 0; i < NUM_PTHREADS; i++)
count[i] = 0;
enable_profalarm(INTERVAL);
- for (int i=0; i<NUM_PTHREADS; i++)
+ for (int i = 0; i < NUM_PTHREADS; i++)
pthread_create(&threads[i], NULL, thread_handler, &count[i]);
- for (int i=0; i<NUM_PTHREADS; i++)
- while(count[i] < ITERATIONS)
+ for (int i = 0; i < NUM_PTHREADS; i++)
+ while (count[i] < ITERATIONS)
cpu_relax();
disable_pvcalarms();
@@ -99,8 +103,8 @@
int num_utests = sizeof(utests) / sizeof(struct utest);
int main(int argc, char *argv[]) {
- // Run test suite passing it all the args as whitelist of what tests to run.
char **whitelist = &argv[1];
int whitelist_len = argc - 1;
+
RUN_TEST_SUITE(utests, num_utests, whitelist, whitelist_len);
}
diff --git a/user/utest/qio.c b/user/utest/qio.c
index c16371f..9b86b1f 100644
--- a/user/utest/qio.c
+++ b/user/utest/qio.c
@@ -46,19 +46,19 @@
} while (ret > 0);
UT_ASSERT_FMT("Didn't get EAGAIN, got %d", errno == EAGAIN, errno);
- /* The way qio works is we accept the last block, and won't accept future
- * blocks until we drop below the limit. Let's drain until we get there.
- * Should be only one or two. */
+ /* The way qio works is we accept the last block, and won't accept
+ * future blocks until we drop below the limit. Let's drain until we
+ * get there. Should be only one or two. */
while (!fd_is_writable(pipefd[1])) {
ret = read(pipefd[0], buf, 1024);
UT_ASSERT_FMT("Failed to read from pipe with data", ret > 0);
}
/* Now we have a little room. If we send in a very large write, greater
- * than Maxatomic, we should get a partial write. If we get -1 back, then
- * the kernel said it was writable, but we couldn't write. This happened
- * once when the kernel would write some, then get EAGAIN and throw -
- * ignoring the successful initial write. */
+ * than Maxatomic, we should get a partial write. If we get -1 back,
+ * then the kernel said it was writable, but we couldn't write. This
+ * happened once when the kernel would write some, then get EAGAIN and
+ * throw - ignoring the successful initial write. */
ret = write(pipefd[1], buf, buf_sz);
UT_ASSERT_FMT("write error %d, errno %d", ret > 0, ret, errno);
UT_ASSERT_FMT("wrote %d >= %d buf_sz", ret < buf_sz, ret, buf_sz);
@@ -79,7 +79,6 @@
int main(int argc, char *argv[])
{
- // Run test suite passing it all the args as whitelist of what tests to run.
char **whitelist = &argv[1];
int whitelist_len = argc - 1;
diff --git a/user/utest/signal.c b/user/utest/signal.c
index 9656d8e..c78c1e5 100644
--- a/user/utest/signal.c
+++ b/user/utest/signal.c
@@ -5,7 +5,8 @@
/* <--- Begin definition of test cases ---> */
-bool test_sigmask(void) {
+bool test_sigmask(void)
+{
int count = 0;
pthread_t sigphandle;
void *thread_handler(void *arg)
@@ -37,7 +38,8 @@
pthread_join(phandle, NULL);
UT_ASSERT_M("Should only receive one signal", count == 1);
- UT_ASSERT_M("Signal handler run on wrong thread", sigphandle == phandle);
+ UT_ASSERT_M("Signal handler run on wrong thread", sigphandle ==
+ phandle);
return true;
}
@@ -49,9 +51,9 @@
int num_utests = sizeof(utests) / sizeof(struct utest);
int main(int argc, char *argv[]) {
- // Run test suite passing it all the args as whitelist of what tests to run.
char **whitelist = &argv[1];
int whitelist_len = argc - 1;
+
RUN_TEST_SUITE(utests, num_utests, whitelist, whitelist_len);
}
diff --git a/user/vmm/apic.c b/user/vmm/apic.c
index 82ffe9b..169e1da 100644
--- a/user/vmm/apic.c
+++ b/user/vmm/apic.c
@@ -121,10 +121,12 @@
uint32_t low;
- DPRINTF("apic_read offset %s 0x%x\n", apicregs[offset].name, (int)offset);
+ DPRINTF("apic_read offset %s 0x%x\n", apicregs[offset].name,
+ (int)offset);
if (! apicregs[offset].mode & 1) {
- fprintf(stderr, "Attempt to read %s, which is %s\n", apicregs[offset].name,
+ fprintf(stderr, "Attempt to read %s, which is %s\n",
+ apicregs[offset].name,
apicregs[offset].mode == 0 ? "reserved" : "writeonly");
// panic? what to do?
return (uint32_t) -1;
@@ -133,7 +135,8 @@
// no special cases yet.
switch (offset) {
default:
- DPRINTF("%s: return %08x\n", apicregs[offset].name, apicregs[offset].value);
+ DPRINTF("%s: return %08x\n", apicregs[offset].name,
+ apicregs[offset].value);
return apicregs[offset].value;
break;
}
@@ -145,10 +148,12 @@
uint64_t val64;
uint32_t low, high;
- DPRINTF("apic_write offset %s 0x%x value 0x%x\n", apicregs[offset].name, (int)offset, value);
+ DPRINTF("apic_write offset %s 0x%x value 0x%x\n", apicregs[offset].name,
+ (int)offset, value);
if (! apicregs[offset].mode & 2) {
- fprintf(stderr, "Attempt to write %s, which is %s\n", apicregs[offset].name,
+ fprintf(stderr, "Attempt to write %s, which is %s\n",
+ apicregs[offset].name,
apicregs[offset].mode == 0 ? "reserved" : "readonly");
// panic? what to do?
return;
@@ -180,16 +185,19 @@
}
offset >>= 4;
if (offset > APIC_CONFIG) {
- DPRINTF("Bad register offset: 0x%x and max is 0x%x\n", gpa, gpa + APIC_CONFIG);
+ DPRINTF("Bad register offset: 0x%x and max is 0x%x\n", gpa, gpa
+ + APIC_CONFIG);
return -1;
}
if (store) {
apic_write(offset, *regp);
- DPRINTF("Write: mov %s to %s @%p val %p\n", regname(destreg), apicregs[offset].name, gpa, *regp);
+ DPRINTF("Write: mov %s to %s @%p val %p\n", regname(destreg),
+ apicregs[offset].name, gpa, *regp);
} else {
*regp = apic_read(offset);
- DPRINTF("Read: Set %s from %s @%p to %p\n", regname(destreg), apicregs[offset].name, gpa, *regp);
+ DPRINTF("Read: Set %s from %s @%p to %p\n", regname(destreg),
+ apicregs[offset].name, gpa, *regp);
}
return 0;
}
@@ -198,6 +206,7 @@
{
uint32_t *p = (uint32_t *)vapic;
int i;
+
fprintf(f, "-- BEGIN APIC STATUS DUMP --\n");
for (i = 0x100/sizeof(*p); i < 0x180/sizeof(*p); i+=4) {
fprintf(f, "VISR : 0x%x: 0x%08x\n", i, p[i]);
diff --git a/user/vmm/biostables.c b/user/vmm/biostables.c
index 2d6b481..4b3a5c6 100644
--- a/user/vmm/biostables.c
+++ b/user/vmm/biostables.c
@@ -78,11 +78,11 @@
.id = 0, .address = 0xfec00000, .global_irq_base = 0};
struct acpi_madt_interrupt_override isor[] = {
- /* From the ACPI Specification Version 6.1: For example, if your machine has
- * the ISA Programmable Interrupt Timer (PIT) connected to ISA IRQ 0, but in
- * APIC mode, it is connected to I/O APIC interrupt input 2, then you would
- * need an Interrupt Source Override where the source entry is ‘0’
- * and the Global System Interrupt is ‘2.’ */
+ /* From the ACPI Specification Version 6.1: For example, if your machine
+ * has the ISA Programmable Interrupt Timer (PIT) connected to ISA IRQ
+ * 0, but in APIC mode, it is connected to I/O APIC interrupt input 2,
+ * then you would need an Interrupt Source Override where the source
+ * entry is ‘0’ and the Global System Interrupt is ‘2.’ */
};
void lowmem(void)
@@ -112,6 +112,7 @@
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,
@@ -181,8 +182,8 @@
// The low 1m is so we can fill in bullshit like ACPI.
- // And, sorry, due to the STUPID format of the RSDP for now we need the low
- // 1M.
+ // And, sorry, due to the STUPID format of the RSDP for now we need the
+ // low 1M.
low1m = mmap((int*)4096, MiB-4096, PROT_READ | PROT_WRITE,
MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (low1m != (void *)4096) {
@@ -221,7 +222,7 @@
/* Check extended checksum if table version >= 2 */
gencsum(&r->extended_checksum, r, ACPI_RSDP_XCHECKSUM_LENGTH);
if ((rsdp.revision >= 2) &&
- (acpi_tb_checksum((uint8_t *) r, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) {
+ (acpi_tb_checksum((uint8_t*)r, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) {
fprintf(stderr, "RSDP has bad checksum v2\n");
exit(1);
}
diff --git a/user/vmm/decode.c b/user/vmm/decode.c
index f12765d..614e4d9 100644
--- a/user/vmm/decode.c
+++ b/user/vmm/decode.c
@@ -49,16 +49,18 @@
static char *modrmreg[] = {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"};
-// Since we at most have to decode less than half of each instruction, I'm trying to be dumb here.
+// Since we at most have to decode less than half of each instruction, I'm
+// trying to be dumb here.
// Fortunately, for me, that's not hard.
-// I'm trying to avoid the whole Big Fun of full instruction decode, and in most of these
-// cases we only have to know register, address, operation size, and instruction length.
+// I'm trying to avoid the whole Big Fun of full instruction decode, and in most
+// of these cases we only have to know register, address, operation size, and
+// instruction length.
// The ugly messiness of the SIB and all that are not yet needed. Maybe they
// never will be.
// Target size -- 1, 2, 4, or 8 bytes. We have yet to see 64 bytes.
-// TODO: if we ever see it, test the prefix. Since this only supports the low 1M,
-// that's not likely.
+// TODO: if we ever see it, test the prefix. Since this only supports the low
+// 1M, that's not likely.
static int target(void *insn, int *store)
{
*store = 0;
@@ -84,18 +86,19 @@
break;
case 0x89:
case 0x8b:
- // TODO: To really know, for sure, that this is 32 bit, we'd likely have
- // to check the segment descriptor for the guest's current code
- // segment in it's GDT. The D flag (bit 22) determines whether the
- // instruction is using 32 or 16-bit operand size. I'm just going
- // to assume the flag is set (meaning 32 bit operands) for now, in
- // order to make virtio work. But really we should check if we
- // want to know for sure. Note that this hack (changing the below
- // line) only applies to mov instructions.
+ // TODO: To really know, for sure, that this is 32 bit, we'd
+ // likely have to check the segment descriptor for the guest's
+ // current code segment in it's GDT. The D flag (bit 22)
+ // determines whether the instruction is using 32 or 16-bit
+ // operand size. I'm just going to assume the flag is set
+ // (meaning 32 bit operands) for now, in order to make virtio
+ // work. But really we should check if we want to know for sure.
+ // Note that this hack (changing the below line) only applies to
+ // mov instructions.
//
- // And I think there's also a prefix you can use to switch the
- // instruction to 16-bit addressing
- // (address-size override prefix?)
+ // And I think there's also a prefix you can use to switch
+ // the instruction to 16-bit addressing (address-size
+ // override prefix?)
s = 4;
break;
case 0x81:
@@ -107,8 +110,9 @@
s = 2;
break;
default:
- fprintf(stderr, "can't get size of %02x/%04x @ %p\n", *byte,
- *word, byte);
+ fprintf(stderr,
+ "can't get size of %02x/%04x @ %p\n",
+ *byte, *word, byte);
return -1;
}
break;
@@ -144,7 +148,8 @@
*store = !(*byte & 2);
break;
default:
- fprintf(stderr, "%s: Can't happen. rip is: %p\n", __func__, byte);
+ fprintf(stderr, "%s: Can't happen. rip is: %p\n", __func__,
+ byte);
break;
}
return s;
@@ -207,12 +212,14 @@
return advance;
}
-// This is a very limited function. It's only here to manage virtio-mmio and low memory
-// pointer loads. I am hoping it won't grow with time. The intent is that we enter it with
-// and EPT fault from a region that is deliberately left unbacked by any memory. We return
-// enough info to let you emulate the operation if you want. Because we have the failing physical
-// address (gpa) the decode is far simpler because we only need to find the register, how many bytes
-// to move, and how big the instruction is. I thought about bringing in emulate.c from kvm from xen,
+// This is a very limited function. It's only here to manage virtio-mmio and low
+// memory pointer loads. I am hoping it won't grow with time. The intent is that
+// we enter it with and EPT fault from a region that is deliberately left
+// unbacked by any memory.
+// We return enough info to let you emulate the operation if you want. Because
+// we have the failing physical address (gpa) the decode is far simpler because
+// we only need to find the register, how many bytes to move, and how big the
+// instruction is. I thought about bringing in emulate.c from kvm from xen,
// but it has way more stuff than we need.
// gpa is a pointer to the gpa.
// int is the reg index which we can use for printing info.
@@ -251,7 +258,8 @@
*advance = insize(rip_gpa);
uint16_t ins = *(uint16_t *)(rip_gpa +
- ((rip_gpa[0] == 0x44) || (rip_gpa[0] == 0x0f) || (rip_gpa[0] == 0x41)));
+ ((rip_gpa[0] == 0x44) || (rip_gpa[0] == 0x0f) || (rip_gpa[0] ==
+ 0x41)));
DPRINTF("ins is %04x\n", ins);
@@ -314,12 +322,13 @@
/* Handle movz{b,w}X. Zero the destination. */
if ((rip_gpa[0] == 0x0f) && (rip_gpa[1] == 0xb6)) {
/* movzb.
- * TODO: figure out if the destination size is 16 or 32 bits. Linux
- * doesn't call this yet, so it's not urgent. */
+ * TODO: figure out if the destination size is 16 or 32 bits.
+ * Linux doesn't call this yet, so it's not urgent. */
return -1;
}
if ((rip_gpa[0] == 0x0f) && (rip_gpa[1] == 0xb7)) {
- /* movzwl. Destination is 32 bits, unless we had the rex prefix */
+ /* movzwl. Destination is 32 bits, unless we had the rex prefix
+ * */
**regp &= ~((1ULL << 32) - 1);
}
return 0;
diff --git a/user/vmm/include/vmm/net.h b/user/vmm/include/vmm/net.h
index 17046ce..91c0a71 100644
--- a/user/vmm/include/vmm/net.h
+++ b/user/vmm/include/vmm/net.h
@@ -19,9 +19,9 @@
/* Style of IP addressing, default off (qemu)
*
* For qemu-style networking:
- * guest_ip = 10.0.2.15, mask = 255.255.255.0, router = 10.0.2.2.
+ * guest_ip = 10.0.2.15, mask = 255.255.255.0, router = 10.0.2.2.
* For real-addr networking:
- * guest_ip = host_v4, mask = host_mask, router = host_router
+ * guest_ip = host_v4, mask = host_mask, router = host_router
* In either case, the guest sees the *real* DNS server. */
extern bool vnet_real_ip_addrs;
diff --git a/user/vmm/include/vmm/sched.h b/user/vmm/include/vmm/sched.h
index efe95ce..c8fb675 100644
--- a/user/vmm/include/vmm/sched.h
+++ b/user/vmm/include/vmm/sched.h
@@ -17,56 +17,56 @@
* controllers are 1:1 (via *buddy). Task threads are for the VMM itself, such
* as a console thread. */
-#define VMM_THREAD_GUEST 1
-#define VMM_THREAD_CTLR 2
-#define VMM_THREAD_TASK 3
+#define VMM_THREAD_GUEST 1
+#define VMM_THREAD_CTLR 2
+#define VMM_THREAD_TASK 3
-#define VMM_THR_STACKSIZE (4 * PGSIZE)
+#define VMM_THR_STACKSIZE (4 * PGSIZE)
struct guest_thread;
struct ctlr_thread;
struct task_thread;
struct guest_thread {
- struct uthread uthread;
- struct ctlr_thread *buddy;
- unsigned int gpc_id;
- uth_mutex_t *halt_mtx;
- uth_cond_var_t *halt_cv;
- unsigned long nr_vmexits;
+ struct uthread uthread;
+ struct ctlr_thread *buddy;
+ unsigned int gpc_id;
+ uth_mutex_t *halt_mtx;
+ uth_cond_var_t *halt_cv;
+ unsigned long nr_vmexits;
struct vmm_gpcore_init gpci;
- void *user_data;
+ void *user_data;
};
struct ctlr_thread {
- struct uthread uthread;
- struct guest_thread *buddy;
- size_t stacksize;
- void *stacktop;
+ struct uthread uthread;
+ struct guest_thread *buddy;
+ size_t stacksize;
+ void *stacktop;
};
struct task_thread {
- struct uthread uthread;
- void *(*func)(void *);
- void *arg;
- size_t stacksize;
- void *stacktop;
+ struct uthread uthread;
+ void *(*func)(void *);
+ void *arg;
+ size_t stacksize;
+ void *stacktop;
};
-struct virtual_machine; /* in vmm/vmm.h */
+struct virtual_machine; /* in vmm/vmm.h */
struct vmm_thread {
union {
- struct guest_thread guest;
- struct ctlr_thread ctlr;
- struct task_thread task;
+ struct guest_thread guest;
+ struct ctlr_thread ctlr;
+ struct task_thread task;
};
- int type;
+ int type;
TAILQ_ENTRY(vmm_thread) tq_next;
struct virtual_machine *vm;
/* Sched stats */
- int prev_vcoreid;
- unsigned long nr_runs;
- unsigned long nr_resched;
+ int prev_vcoreid;
+ unsigned long nr_runs;
+ unsigned long nr_resched;
};
TAILQ_HEAD(vmm_thread_tq, vmm_thread);
diff --git a/user/vmm/include/vmm/virtio_balloon.h b/user/vmm/include/vmm/virtio_balloon.h
index 9b44cdd..549a80e 100644
--- a/user/vmm/include/vmm/virtio_balloon.h
+++ b/user/vmm/include/vmm/virtio_balloon.h
@@ -13,17 +13,19 @@
* 3. Neither the name of IBM nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE. */
+ * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#pragma once
+
#include <stdint.h>
#include <vmm/virtio_ids.h>
#include <vmm/virtio_config.h>
diff --git a/user/vmm/include/vmm/virtio_config.h b/user/vmm/include/vmm/virtio_config.h
index 2d752d5..85cafdd 100644
--- a/user/vmm/include/vmm/virtio_config.h
+++ b/user/vmm/include/vmm/virtio_config.h
@@ -13,17 +13,16 @@
* 3. Neither the name of IBM nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE. */
+ * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/* Virtio devices use a standardized configuration space to define their
* features and pass configuration information, but each implementation can
diff --git a/user/vmm/include/vmm/virtio_lguest_helpers.h b/user/vmm/include/vmm/virtio_lguest_helpers.h
index 21499c8..4d69621 100644
--- a/user/vmm/include/vmm/virtio_lguest_helpers.h
+++ b/user/vmm/include/vmm/virtio_lguest_helpers.h
@@ -39,7 +39,7 @@
// and sizes of the buffers it describes to an iovec to make them easy to use.
// Based on wait_for_vq_desc in Linux lguest.c
uint32_t virtio_next_avail_vq_desc(struct virtio_vq *vq, struct iovec iov[],
- uint32_t *olen, uint32_t *ilen);
+ uint32_t *olen, uint32_t *ilen);
// After the driver tells us that a queue is ready for processing,
// we use this to validate the addresses on the vring it gave us.
diff --git a/user/vmm/include/vmm/virtio_mmio.h b/user/vmm/include/vmm/virtio_mmio.h
index 835e1aa..e8b2f6a 100644
--- a/user/vmm/include/vmm/virtio_mmio.h
+++ b/user/vmm/include/vmm/virtio_mmio.h
@@ -187,10 +187,12 @@
// we save the same value here as we report to guest via kernel cmd line
uint64_t addr;
- // Reads from vqdev.dev_feat are performed starting at bit 32 * dev_feat_sel
+ // Reads from vqdev.dev_feat are performed starting at bit 32 *
+ // dev_feat_sel
uint32_t dev_feat_sel;
- // Writes to vqdev.dri_feat are performed starting at bit 32 * dri_feat_sel
+ // Writes to vqdev.dri_feat are performed starting at bit 32 *
+ // dri_feat_sel
uint32_t dri_feat_sel;
// Reads and writes to queue-specific registers target vqdev->vqs[qsel]
@@ -199,8 +201,9 @@
// Interrupt status register
uint32_t isr;
- // This utility function will be called when the device needs to interrupt
- // the guest. You can have it do whatever you want, but it is required.
+ // This utility function will be called when the device needs to
+ // interrupt the guest. You can have it do whatever you want, but it is
+ // required.
void (*poke_guest)(uint8_t vec, uint32_t dest);
// Status flags for the device
diff --git a/user/vmm/include/vmm/virtio_pci.h b/user/vmm/include/vmm/virtio_pci.h
index ce44ed8..4d4b53c 100644
--- a/user/vmm/include/vmm/virtio_pci.h
+++ b/user/vmm/include/vmm/virtio_pci.h
@@ -23,17 +23,16 @@
* 3. Neither the name of IBM nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
diff --git a/user/vmm/include/vmm/virtio_ring.h b/user/vmm/include/vmm/virtio_ring.h
index 09bce1a..b5fa129 100644
--- a/user/vmm/include/vmm/virtio_ring.h
+++ b/user/vmm/include/vmm/virtio_ring.h
@@ -17,17 +17,16 @@
* 3. Neither the name of IBM nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Copyright Rusty Russell IBM Corporation 2007. */
diff --git a/user/vmm/include/vmm/virtio_scsi.h b/user/vmm/include/vmm/virtio_scsi.h
index 0e1e860..5acae34 100644
--- a/user/vmm/include/vmm/virtio_scsi.h
+++ b/user/vmm/include/vmm/virtio_scsi.h
@@ -1,3 +1,5 @@
+#pragma once
+
/*
* This header is BSD licensed so anyone can use the definitions to implement
* compatible drivers/servers.
@@ -24,9 +26,7 @@
* SUCH DAMAGE.
*/
-#pragma once
-
- #include <stdint.h>
+#include <stdint.h>
/* Default values of the CDB and sense data size configuration fields */
#define VIRTIO_SCSI_CDB_DEFAULT_SIZE 32
diff --git a/user/vmm/include/vmm/vmm.h b/user/vmm/include/vmm/vmm.h
index 0cb0fb0..5a8d91f 100644
--- a/user/vmm/include/vmm/vmm.h
+++ b/user/vmm/include/vmm/vmm.h
@@ -47,39 +47,38 @@
/* Structure to encapsulate all of the bookkeeping for a VM. */
struct virtual_machine {
/* Big mutext for pagetables and __gths/ nr_gpcs */
- uth_mutex_t mtx;
- struct guest_thread **__gths;
- unsigned int gth_array_elem;
- unsigned int nr_gpcs;
- /* up_gpcs should not need synchronization. only the BSP should be making
- * startup vmcalls. For security's sake we might still want to lock in the
- * future. TODO(ganshun)
- * up_gpcs refers to the number of guest pcores that have
- * been started so far. */
- unsigned int up_gpcs;
+ uth_mutex_t mtx;
+ struct guest_thread **__gths;
+ unsigned int gth_array_elem;
+ unsigned int nr_gpcs;
+ /* up_gpcs should not need synchronization. only the BSP should be
+ * making startup vmcalls. For security's sake we might still want to
+ * lock in the future. TODO(ganshun)
+ * up_gpcs refers to the number of guest pcores that have been started
+ * so far. */
+ unsigned int up_gpcs;
/* 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];
+ * 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];
- /* minimum and maximum physical memory addresses. When we set up the initial
- * default page tables we use this range. Note that even if the "physical"
- * memory has holes, we'll create PTEs for it. This seems enough for now but
- * we shall see. */
- uintptr_t minphys;
- uintptr_t maxphys;
+ /* minimum and maximum physical memory addresses. When we set up the
+ * initial default page tables we use this range. Note that even if the
+ * "physical" memory has holes, we'll create PTEs for it. This seems
+ * enough for now but we shall see. */
+ uintptr_t minphys;
+ uintptr_t maxphys;
- /* 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. setup_paging now updates this to point to the initial set of
- * page tables for the guest. */
- void *root;
+ /* 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. setup_paging now updates this to
+ * point to the initial set of page tables for the guest. */
+ void *root;
/* Default value for whether guest threads halt on an exit. */
- bool halt_exit;
+ bool halt_exit;
/* Override for vmcall (vthreads) */
bool (*vmcall)(struct guest_thread *gth, struct vm_trapframe *);
};
diff --git a/user/vmm/include/vmm/vthread.h b/user/vmm/include/vmm/vthread.h
index 4de09ab..51f8fb1 100644
--- a/user/vmm/include/vmm/vthread.h
+++ b/user/vmm/include/vmm/vthread.h
@@ -12,12 +12,13 @@
* vthread_alloc. You're on your own there. Using this is a sign that we may
* need our own 2LS for vthreads. */
struct vthread_info {
- uintptr_t stacktop;
+ uintptr_t stacktop;
};
struct vthread {
- struct guest_thread gth;
- /* Don't add to this structure without changing how these are allocated. */
+ struct guest_thread gth;
+ /* Don't add to this structure without changing how these are allocated.
+ */
};
static struct vm_trapframe *vth_to_vmtf(struct vthread *vth)
@@ -62,8 +63,8 @@
asm volatile("vmcall"
: "=a"(ret)
- : "a"(vmcall_nr), "D"(arg0), "S"(arg1), "d"(arg2), "c"(arg3),
- "r"(r8));
+ : "a"(vmcall_nr), "D"(arg0), "S"(arg1), "d"(arg2),
+ "c"(arg3), "r"(r8));
return ret;
}
diff --git a/user/vmm/io.c b/user/vmm/io.c
index 54b98da..34e9253 100644
--- a/user/vmm/io.c
+++ b/user/vmm/io.c
@@ -38,9 +38,9 @@
static uint32_t cf8;
static uint32_t allones = (uint32_t)-1;
-/* Return a pointer to the 32-bit "register" in the "pcibus" give an address. Use cf8.
- * only for readonly access.
- * this will fail if we ever want to do writes, but we don't.
+/* Return a pointer to the 32-bit "register" in the "pcibus" give an address.
+ * Use cf8. only for readonly access. this will fail if we ever want to do
+ * writes, but we don't.
*/
void regp(uint32_t **reg)
{
@@ -114,11 +114,10 @@
int io(struct guest_thread *vm_thread)
{
- /* Get a pointer to the memory at %rip. This is quite messy and part of the
- * reason we don't want to do this at all. It sucks. Would have been nice
- * had linux had an option to ONLY do mmio config space access, but no such
- * luck.
- */
+ /* Get a pointer to the memory at %rip. This is quite messy and part of
+ * the reason we don't want to do this at all. It sucks. Would have been
+ * nice had linux had an option to ONLY do mmio config space access, but
+ * no such luck. */
uint8_t *ip8 = NULL;
uint16_t *ip16;
uintptr_t ip;
@@ -163,7 +162,8 @@
* confused people into thinking we were running
* Windows 98, not Linux.
*/
- printf("(out rax, edx): unhandled IO address dx @%p is 0x%x\n", ip8, edx);
+ printf("(out rax, edx): unhandled IO address dx @%p is 0x%x\n",
+ ip8, edx);
return 0;
}
/* TODO: sort out these various OUT operations */
@@ -183,10 +183,10 @@
// on real hardware, an outb to 0xcf9 with bit 2 set is
// about as hard a reset as you can get. It yanks the
// reset on everything, including all the cores. It
- // usually happens after the kernel has done lots of work
- // to carefully quiesce the machine but, once it happens,
- // game is over. Hence, an exit(0) is most appropriate,
- // since it's not an error.
+ // usually happens after the kernel has done lots of
+ // work to carefully quiesce the machine but, once it
+ // happens, game is over. Hence, an exit(0) is most
+ // appropriate, since it's not an error.
if (eax & (1 << 2)) {
printf("outb to PCI reset port with bit 2 set: time to die\n");
exit(0);
@@ -194,9 +194,10 @@
return 0;
}
- /* Another case where we print a message but it's not an error. */
- printf("out al, dx: unhandled IO address dx @%p is 0x%x\n", ip8, edx);
- return 0;
+ /* Another case where we print a message but it's not an error.
+ * */
+ printf("out al, dx: unhandled IO address dx @%p is 0x%x\n", ip8,
+ edx); return 0;
}
/* Silently accept OUT imm8, al */
if (*ip8 == 0xe6) {
diff --git a/user/vmm/ioapic.c b/user/vmm/ioapic.c
index 39351e5..4f86ea0 100644
--- a/user/vmm/ioapic.c
+++ b/user/vmm/ioapic.c
@@ -61,25 +61,23 @@
switch (reg) {
case 0:
return ioapic[ix].id;
- break;
case 1:
return 0x170011;
- break;
case 2:
return ioapic[ix].arbid;
- break;
default:
if (reg >= 0 && reg < (IOAPIC_NUM_PINS*2 + 0x10)) {
//bx_io_redirect_entry_t *entry = ioredtbl + index;
- //data = (ioregsel&1) ? entry->get_hi_part() : entry->get_lo_part();
+ //data = (ioregsel&1) ? entry->get_hi_part()
+ // : entry->get_lo_part();
ret = ioapic[ix].value[reg];
- DPRINTF("IOAPIC_READ %x: %x return %08x\n", ix, reg, ret);
+ DPRINTF("IOAPIC_READ %x: %x return %08x\n", ix, reg,
+ ret);
return ret;
} else {
DPRINTF("IOAPIC READ: %x BAD INDEX 0x%x\n", ix, reg);
}
return ret;
- break;
}
return 0;
}
@@ -102,9 +100,9 @@
if (vm->virtio_mmio_devices[i] == NULL)
continue;
- /* The first IRQ register starts at 0x10, and there are two 32-bit
- * registers for each IRQ. The first 8 bits of the value assigned to
- * 'reg' is the interrupt vector. */
+ /* The first IRQ register starts at 0x10, and there are two
+ * 32-bit registers for each IRQ. The first 8 bits of the value
+ * assigned to 'reg' is the interrupt vector. */
irqreg = (vm->virtio_mmio_devices[i]->irq) * 2 + 0x10;
if (reg == irqreg && (value & 0xff) != 0) {
vm->virtio_mmio_devices[i]->vec = value & 0xff;
@@ -133,7 +131,8 @@
default:
if (reg >= 0 && reg < (IOAPIC_NUM_PINS*2 + 0x10)) {
ioapic[ix].value[reg] = value;
- DPRINTF("IOAPIC %x: set %08x to %016x\n", ix, reg, value);
+ DPRINTF("IOAPIC %x: set %08x to %016x\n", ix, reg,
+ value);
} else {
DPRINTF("IOAPIC WRITE: %x BAD INDEX 0x%x\n", ix, reg);
}
@@ -149,10 +148,12 @@
int ix = 0;
uint32_t offset = gpa & 0xfffff;
/* basic sanity tests. */
- DPRINTF("%s: %p 0x%x %p %s\n", __func__, (void *)gpa, destreg, regp, store ? "write" : "read");
+ DPRINTF("%s: %p 0x%x %p %s\n", __func__, (void *)gpa, destreg, regp,
+ store ? "write" : "read");
if ((offset != 0) && (offset != 0x10)) {
- DPRINTF("Bad register offset: 0x%x and has to be 0x0 or 0x10\n", offset);
+ DPRINTF("Bad register offset: 0x%x and has to be 0x0 or 0x10\n",
+ offset);
return -1;
}
diff --git a/user/vmm/linuxemu.c b/user/vmm/linuxemu.c
index 46e17d7..bf703ed 100644
--- a/user/vmm/linuxemu.c
+++ b/user/vmm/linuxemu.c
@@ -100,7 +100,8 @@
int len1 = strlen(path);
if (len1 == 0) {
- fprintf(stderr, "get_absolute_path_from_fd: suffix is empty.\n");
+ fprintf(stderr,
+ "get_absolute_path_from_fd: suffix is empty.\n");
return false;
}
@@ -118,7 +119,8 @@
uth_mutex_lock(fd_table_lock);
if (!openfd_filenames[fd]) {
uth_mutex_unlock(fd_table_lock);
- fprintf(stderr, "get_absolute_path_from_fd: no file open at fd.\n");
+ fprintf(stderr,
+ "get_absolute_path_from_fd: no file open at fd.\n");
return false;
}
@@ -175,8 +177,8 @@
otherstuff |= O_RDWR;
break;
default:
- // TODO(ganshun): We panic here for now if they are trying behavior we
- // do not expect
+ // TODO(ganshun): We panic here for now if they are trying
+ // behavior we do not expect
panic("linuxemu, convert_open_flags_ltoa: unknown open flags provided\n");
break;
}
@@ -199,8 +201,8 @@
otherstuff |= 2;
break;
default:
- // TODO(ganshun): We panic here for now if they are trying behavior we
- // do not expect
+ // TODO(ganshun): We panic here for now if they are trying
+ // behavior we do not expect
panic("linuxemu, convert_open_flags_atol: unknown open flags provided\n");
break;
}
@@ -336,7 +338,8 @@
bool dune_sys_read(struct vm_trapframe *tf)
{
- ssize_t retval = read(tf->tf_rdi, (void*) tf->tf_rsi, (size_t) tf->tf_rdx);
+ ssize_t retval = read(tf->tf_rdi, (void*) tf->tf_rsi,
+ (size_t) tf->tf_rdx);
int err = errno;
if (retval == -1) {
@@ -396,7 +399,8 @@
// Getpid always suceeds
int retval = getpid();
- lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false, "SUCCESS %d\n", retval);
+ lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false, "SUCCESS %d\n",
+ retval);
tf->tf_rax = retval;
return true;
}
@@ -458,7 +462,8 @@
//Umask always succeeds
int retval = umask((mode_t) tf->tf_rdi);
- lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false, "SUCCESS %d\n", retval);
+ lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false, "SUCCESS %d\n",
+ retval);
tf->tf_rax = retval;
return true;
}
@@ -525,7 +530,8 @@
// Gettid always succeeds
int retval = tf->tf_guest_pcoreid;
- lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false, "SUCCESS %d\n", retval);
+ lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false, "SUCCESS %d\n",
+ retval);
tf->tf_rax = retval;
return true;
}
@@ -578,7 +584,8 @@
// where we'd want to recover and return EBADF or ENOTDIR
if (!get_absolute_path_from_fd(fd, s, &s_absolute)) {
panic("[TID %d] %s: ERROR in getting absolute path fd was %d, suffix was %s\n",
- tf->tf_guest_pcoreid, dune_syscall_table[tf->tf_rax].name, fd, s);
+ tf->tf_guest_pcoreid, dune_syscall_table[tf->tf_rax].name,
+ fd, s);
}
flags = convert_open_flags_ltoa(flags);
@@ -622,8 +629,8 @@
if (!get_absolute_path_from_fd(fd, s, &s_absolute)) {
panic("[TID %d] %s: ERROR in getting absolute path fd was %d, suffix was %s\n",
- tf->tf_guest_pcoreid, dune_syscall_table[tf->tf_rax].name, fd,
- s);
+ tf->tf_guest_pcoreid, dune_syscall_table[tf->tf_rax].name,
+ fd, s);
}
lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
@@ -654,8 +661,8 @@
if (!get_absolute_path_from_fd(fd, s, &s_absolute)) {
panic("[TID %d] %s: ERROR in getting absolute path fd was %d, suffix was %s\n",
- tf->tf_guest_pcoreid, dune_syscall_table[tf->tf_rax].name, fd,
- s);
+ tf->tf_guest_pcoreid, dune_syscall_table[tf->tf_rax].name,
+ fd, s);
}
lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
@@ -805,7 +812,7 @@
if (offset + len >= st.st_size) {
// Panic here as we cannot support changing the size of the file
// right now.
- panic("dune_fallocate: we would write over the size of the file!");
+ panic("dune_fallocate: would write over the size of the file!");
}
if (S_ISFIFO(st.st_mode)) {
errno = ESPIPE;
@@ -816,7 +823,8 @@
return -1;
}
- // TODO(ganshun): For punch hole, we just write zeros to the file for now
+ // TODO(ganshun): For punch hole, we just write zeros to the file for
+ // now
if ((mode & FALLOC_FL_PUNCH_HOLE) && (mode & FALLOC_FL_KEEP_SIZE)) {
const size_t buffer_size = 0x100000;
int pos;
@@ -893,8 +901,8 @@
const sigset_t *sigmask = (const sigset_t *) tf->tf_r9;
// Check if process wants to sleep
- if (nfds == 0 && readfds == NULL && writefds == NULL && exceptfds == NULL
- && timeout != NULL) {
+ if (nfds == 0 && readfds == NULL && writefds == NULL &&
+ exceptfds == NULL && timeout != NULL) {
lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
"Sleeping for %ld seconds, %ld nanoseconds\n",
timeout->tv_sec, timeout->tv_nsec);
@@ -933,8 +941,8 @@
if (fd == -1) {
lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
- "ERROR opening random source %s, errno=%d\n", random_source,
- err);
+ "ERROR opening random source %s, errno=%d\n",
+ random_source, err);
return false;
}
@@ -1441,7 +1449,8 @@
}
if (dlopen("liblinuxemu_extend.so", RTLD_NOW) == NULL) {
- fprintf(stderr, "Not using any syscall extensions\n Reason: %s\n",
+ fprintf(stderr,
+ "Not using any syscall extensions\n Reason: %s\n",
dlerror());
return false;
}
@@ -1503,8 +1512,7 @@
* call, and in many cases we have to rearrange arguments
* since Linux and Akaros don't share signatures, so this
* gets tricky. */
-bool
-linuxemu(struct guest_thread *gth, struct vm_trapframe *tf)
+bool linuxemu(struct guest_thread *gth, struct vm_trapframe *tf)
{
bool ret = false;
diff --git a/user/vmm/load_elf.c b/user/vmm/load_elf.c
index 4f9601b..a88b597 100644
--- a/user/vmm/load_elf.c
+++ b/user/vmm/load_elf.c
@@ -12,9 +12,8 @@
* We assume that memory is set up correctly, and it will go hard
* with you if it is not. The reference parameter records the highest
* address we wrote. The initrd can go there.*/
-uintptr_t
-load_elf(char *filename, uint64_t offset, uint64_t *highest,
- Elf64_Ehdr *ehdr_out)
+uintptr_t load_elf(char *filename, uint64_t offset, uint64_t *highest,
+ Elf64_Ehdr *ehdr_out)
{
Elf64_Ehdr *ehdr;
Elf *elf;
@@ -33,7 +32,8 @@
elf = elf_begin(fd, ELF_C_READ, NULL);
if (elf == NULL) {
- fprintf(stderr, "%s: cannot read %s ELF file.\n", __func__, filename);
+ fprintf(stderr, "%s: cannot read %s ELF file.\n", __func__,
+ filename);
close(fd);
return 0;
}
@@ -88,8 +88,8 @@
i, h->p_offset, pa, h->p_paddr, h->p_filesz);
tot = 0;
while (tot < h->p_filesz) {
- int amt = pread(fd, (void *)(pa + tot + offset), h->p_filesz - tot,
- h->p_offset + tot);
+ int amt = pread(fd, (void *)(pa + tot + offset),
+ h->p_filesz - tot, h->p_offset + tot);
if (amt < 1)
break;
diff --git a/user/vmm/memory.c b/user/vmm/memory.c
index 25c4466..25c9c4c 100644
--- a/user/vmm/memory.c
+++ b/user/vmm/memory.c
@@ -67,7 +67,8 @@
if (memstart < RESERVED) {
bp->e820_map[bp->e820_entries].addr = memstart;
if (memstart + memsize > RESERVED)
- bp->e820_map[bp->e820_entries].size = RESERVED - memstart;
+ bp->e820_map[bp->e820_entries].size = RESERVED -
+ memstart;
else
bp->e820_map[bp->e820_entries].size = memsize;
lowmem = bp->e820_map[bp->e820_entries].size;
@@ -146,7 +147,8 @@
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (r1 != (void *)memstart) {
- fprintf(stderr, "Low region: Could not mmap 0x%lx bytes at 0x%lx\n",
+ fprintf(stderr,
+ "Low region: Could not mmap 0x%lx bytes at 0x%lx\n",
memsize, memstart);
exit(1);
}
@@ -198,7 +200,7 @@
int envc, char *envp[],
int auxc, struct elf_aux auxv[])
{
- /* Function to get the lengths of the argument and environment strings. */
+ /* Func to get the lengths of the argument and environment strings. */
int get_lens(int argc, char *argv[], int arg_lens[])
{
int total = 0;
@@ -234,9 +236,9 @@
return offset;
}
- /* Start tracking the size of the buffer necessary to hold all of our data
- * on the stack. Preallocate space for argc, argv, envp, and auxv in this
- * buffer. */
+ /* Start tracking the size of the buffer necessary to hold all of our
+ * data on the stack. Preallocate space for argc, argv, envp, and auxv
+ * in this buffer. */
int bufsize = 0;
bufsize += 1 * sizeof(size_t);
@@ -254,7 +256,8 @@
fprintf(stderr, "Bufsize for pointers, argc, and strings is %d\n",
bufsize);
- /* Adjust bufsize so that our buffer will ultimately be 16 byte aligned. */
+ /* Adjust bufsize so that our buffer will ultimately be 16 byte aligned.
+ */
bufsize = (bufsize + 15) & ~0xf;
fprintf(stderr,
"Bufsize for pointers, argc, and strings is rounded is %d\n",
diff --git a/user/vmm/nat.c b/user/vmm/nat.c
index 07ae488..f8a1fd1 100644
--- a/user/vmm/nat.c
+++ b/user/vmm/nat.c
@@ -75,13 +75,13 @@
* dealt with, but it's subtle. There also might be races with FD taps
* firing, the fdtap_watcher not putting items on the list, and the thread
* then not putting it on the list. Specifically:
- * fdtap_watcher: __poll_inbound:
+ * fdtap_watcher: __poll_inbound:
* -------------------------------------------------------
- * yanks map off list
- * map tracked as "on inbound"
- * unlock mtx
- * readv, get -1 EAGAIN
- * decide to drop the item
+ * yanks map off list
+ * map tracked as "on inbound"
+ * unlock mtx
+ * readv, get -1 EAGAIN
+ * decide to drop the item
* packet arrives
* FD tap fires
* send event
@@ -89,9 +89,9 @@
* see map is "on inbound"
* ignore event
* unlock mtx
- * lock mtx
- * clear "on inbound"
- * unlock + sleep on CV
+ * lock mtx
+ * clear "on inbound"
+ * unlock + sleep on CV
* The FD has data, but we lost the event, and we'll never read it.
*
* - Why is the fdtap_watcher its own thread? You can't kick a CV from vcore
@@ -188,16 +188,16 @@
struct ip_nat_map {
TAILQ_ENTRY(ip_nat_map) lookup_tuple;
TAILQ_ENTRY(ip_nat_map) lookup_fd;
- struct kref kref;
- uint8_t protocol;
- uint16_t guest_port;
- uint16_t host_port;
- int host_data_fd;
- bool is_static;
- bool is_stale;
+ struct kref kref;
+ uint8_t protocol;
+ uint16_t guest_port;
+ uint16_t host_port;
+ int host_data_fd;
+ bool is_static;
+ bool is_stale;
/* These fields are protected by the rx mutex */
TAILQ_ENTRY(ip_nat_map) inbound;
- bool is_on_inbound;
+ bool is_on_inbound;
};
#define NR_VNET_HASH 128
@@ -216,8 +216,8 @@
* responses) into the guest via receive_packet. */
struct buf_pkt {
STAILQ_ENTRY(buf_pkt) next;
- uint8_t *buf;
- size_t sz;
+ uint8_t *buf;
+ size_t sz;
};
STAILQ_HEAD(buf_pkt_stailq, buf_pkt);
@@ -255,7 +255,8 @@
spin_pdr_lock(&maps_lock);
TAILQ_FOREACH(i, list_hash_tuple(protocol, guest_port), lookup_tuple) {
- if ((i->protocol == protocol) && (i->guest_port == guest_port)) {
+ if ((i->protocol == protocol) &&
+ (i->guest_port == guest_port)) {
kref_get(&i->kref, 1);
break;
}
@@ -331,7 +332,8 @@
default:
panic("get_map for unsupported protocol %d!", protocol);
}
- snprintf(dialstring, sizeof(dialstring), "%s!*!%s", proto_str, host_port);
+ snprintf(dialstring, sizeof(dialstring), "%s!*!%s", proto_str,
+ host_port);
bypass_fd = bypass9(dialstring, conv_dir, 0);
if (bypass_fd < 0) {
@@ -381,16 +383,20 @@
spin_pdr_lock(&maps_lock);
/* Only need to scan one map_hash, might as well be the tuple */
for (int j = 0; j < NR_VNET_HASH; j++) {
- TAILQ_FOREACH_SAFE(i, &map_hash_tuple[j], lookup_tuple, temp) {
+ TAILQ_FOREACH_SAFE(i, &map_hash_tuple[j], lookup_tuple,
+ temp) {
if (i->is_static)
continue;
if (!i->is_stale) {
i->is_stale = TRUE;
continue;
}
- /* Remove from both lists, hashing for the FD list */
- TAILQ_REMOVE(&map_hash_tuple[j], i, lookup_tuple);
- TAILQ_REMOVE(list_hash_fd(i->host_data_fd), i, lookup_fd);
+ /* Remove from both lists, hashing for the FD
+ * list */
+ TAILQ_REMOVE(&map_hash_tuple[j], i,
+ lookup_tuple);
+ TAILQ_REMOVE(list_hash_fd(i->host_data_fd), i,
+ lookup_fd);
/* Use the lookup_tuple for the temp list */
TAILQ_INSERT_HEAD(&to_release, i, lookup_tuple);
}
@@ -411,8 +417,9 @@
for (int j = 0; j < NR_VNET_HASH; j++) {
TAILQ_FOREACH(i, &map_hash_tuple[j], lookup_tuple) {
fprintf(stderr, "\tproto %2d, host %5d, guest %5d, FD %4d, stale %d, static %d, ref %d\n",
- i->protocol, i->host_port, i->guest_port, i->host_data_fd,
- i->is_stale, i->is_static, i->kref.refcnt);
+ i->protocol, i->host_port, i->guest_port,
+ i->host_data_fd, i->is_stale, i->is_static,
+ i->kref.refcnt);
}
}
spin_pdr_unlock(&maps_lock);
@@ -488,12 +495,13 @@
/* for each short: HC' = ~(~HC + ~m + m') (' == new, ~ == ones-comp) */
for (int i = 0; i < amt / 2; i++, old += 2, new += 2) {
xsum = ones_comp(xsum) + ones_comp(nhgets(old)) + nhgets(new);
- /* Need to deal with the carry for any additions, before the outer ~()
- * operation. (Not mentioned in the RFC, determined manually...) */
+ /* Need to deal with the carry for any additions, before the
+ * outer ~() operation. (Not mentioned in the RFC, determined
+ * manually...) */
while (xsum >> 16)
xsum = (xsum & 0xffff) + (xsum >> 16);
- /* Yes, next time around the loop we ones comp right back. Not worth
- * optimizing. */
+ /* Yes, next time around the loop we ones comp right back. Not
+ * worth optimizing. */
xsum = ones_comp(xsum);
}
iov_put_be16(iov, iovcnt, xsum_off, xsum);
@@ -551,7 +559,8 @@
lifc = get_first_noloop_iplifc(NULL, &to_free);
if (!lifc) {
- fprintf(stderr, "IP addr lookup failed (%r), no VM networking\n");
+ fprintf(stderr,
+ "IP addr lookup failed (%r), no VM networking\n");
return;
}
snprintf(my_ip_str, sizeof(my_ip_str), "%i", lifc->ip);
@@ -561,7 +570,8 @@
ret = my_router_addr(router_ip, NULL);
if (ret) {
- fprintf(stderr, "Router lookup failed (%r), no VM networking\n");
+ fprintf(stderr,
+ "Router lookup failed (%r), no VM networking\n");
return;
}
v6tov4(host_v4_router, router_ip);
@@ -573,7 +583,8 @@
}
nt = ndbipinfo(ndb, "ip", my_ip_str, &dns, 1);
if (!nt) {
- fprintf(stderr, "DNS server lookup failed (%r), no VM networking\n");
+ fprintf(stderr,
+ "DNS server lookup failed (%r), no VM networking\n");
return;
}
v4parseip(host_v4_dns, nt->val);
@@ -649,7 +660,8 @@
while (1) {
uth_blockon_evqs(msg, NULL, 1, inbound_evq);
map = lookup_map_by_hostfd(msg->ev_type);
- /* Could get an event for an FD/map that has since been reaped. */
+ /* Could get an event for an FD/map that has since been reaped.
+ */
if (!map)
continue;
uth_mutex_lock(rx_mtx);
@@ -672,11 +684,13 @@
ceq = get_eventq_raw();
ceq->ev_mbox->type = EV_MBOX_CEQ;
ceq_init(&ceq->ev_mbox->ceq, CEQ_OR, NR_FILE_DESC_MAX, 128);
- /* As far as flags go, we might not want IPI in the future. Depends on some
- * longer range VMM/2LS changes. Regarding INDIR, if you want to find out
- * about the event (i.e. not poll) for non-VCPD mboxes (like this evq's
- * mbox), then you need INDIR. We need that for the wakeup/blockon. */
- ceq->ev_flags = EVENT_INDIR | EVENT_SPAM_INDIR | EVENT_WAKEUP | EVENT_IPI;
+ /* As far as flags go, we might not want IPI in the future. Depends on
+ * some longer range VMM/2LS changes. Regarding INDIR, if you want to
+ * find out about the event (i.e. not poll) for non-VCPD mboxes (like
+ * this evq's mbox), then you need INDIR. We need that for the
+ * wakeup/blockon. */
+ ceq->ev_flags = EVENT_INDIR | EVENT_SPAM_INDIR | EVENT_WAKEUP |
+ EVENT_IPI;
evq_attach_wakeup_ctlr(ceq);
return ceq;
}
@@ -731,8 +745,8 @@
#define DHCP_RSP_LEN (DHCP_MAIN_BODY_LEN + DHCP_MAX_OPT_LEN)
#define DHCP_LEASE_TIME 3600
-#define DHCP_OP_REQ 1
-#define DHCP_OP_RSP 2
+#define DHCP_OP_REQ 1
+#define DHCP_OP_RSP 2
#define DHCP_MSG_DISCOVER 1
#define DHCP_MSG_OFFER 2
@@ -760,7 +774,8 @@
static int get_dhcp_req_type(struct iovec *iov, int iovcnt)
{
- size_t idx = ETH_HDR_LEN + IPV4_HDR_LEN + UDP_HDR_LEN + DHCP_MAIN_BODY_LEN;
+ size_t idx = ETH_HDR_LEN + IPV4_HDR_LEN + UDP_HDR_LEN
+ + DHCP_MAIN_BODY_LEN;
if (!iov_has_bytes(iov, iovcnt, idx + 4)) {
fprintf(stderr, "DHCP request too short!\n");
@@ -774,9 +789,9 @@
fprintf(stderr, "DHCP request didn't have magic cookie!\n");
return -1;
}
- /* Some clients might ask us to look in sname or other locations, which is
- * communicated by an option. So far, the clients I've seen just use the
- * main options to communicate the message type. */
+ /* Some clients might ask us to look in sname or other locations, which
+ * is communicated by an option. So far, the clients I've seen just use
+ * the main options to communicate the message type. */
idx += 4;
while (1) {
if (!iov_has_bytes(iov, iovcnt, idx + 1)) {
@@ -801,7 +816,8 @@
fprintf(stderr, "DHCP request too short!\n");
return -1;
}
- /* idx + 1 is size of the payload. Skip the opt, size, payload. */
+ /* idx + 1 is size of the payload. Skip the opt, size,
+ * payload. */
idx += 2 + iov_get_byte(iov, iovcnt, idx + 1);
break;
}
@@ -818,8 +834,8 @@
*p++ = ETH_ADDR_LEN;
*p++ = 0x00; /* hops */
/* TODO: copies XID; assumes the inbound packet had standard headers */
- iov_memcpy_from(iov, iovcnt, ETH_HDR_LEN + IPV4_HDR_LEN + UDP_HDR_LEN + 4,
- p, 4);
+ iov_memcpy_from(iov, iovcnt,
+ ETH_HDR_LEN + IPV4_HDR_LEN + UDP_HDR_LEN + 4, p, 4);
p += 4;
p += 8; /* secs, flags, CIADDR */
memcpy(p, guest_v4_addr, IPV4_ADDR_LEN);
@@ -836,9 +852,9 @@
req_type = get_dhcp_req_type(iov, iovcnt);
- /* DHCP options: Technically, we should be responding with whatever fields
- * they asked for in their incoming message. For the most part, there are a
- * bunch of standard things we can just respond with. */
+ /* DHCP options: Technically, we should be responding with whatever
+ * fields they asked for in their incoming message. For the most part,
+ * there are a bunch of standard things we can just respond with. */
*p++ = DHCP_MAGIC_COOKIE_1;
*p++ = DHCP_MAGIC_COOKIE_2;
@@ -910,8 +926,8 @@
p += 2;
hnputs(p, payload_sz + UDP_HDR_LEN);
p += 2;
- /* For v4, we don't need to do the xsum. It's a minor pain too, since they
- * xsum parts of the IP header too. */
+ /* For v4, we don't need to do the xsum. It's a minor pain too, since
+ * they xsum parts of the IP header too. */
hnputs(p, 0);
p += 2;
@@ -981,10 +997,11 @@
case DHCP_MSG_INFORM:
return;
}
- bpkt = zalloc_bpkt(ETH_HDR_LEN + IPV4_HDR_LEN + UDP_HDR_LEN + DHCP_RSP_LEN);
+ bpkt = zalloc_bpkt(ETH_HDR_LEN + IPV4_HDR_LEN + UDP_HDR_LEN +
+ DHCP_RSP_LEN);
- payload_sz = build_dhcp_response(iov, iovcnt, bpkt->buf + ETH_HDR_LEN
- + IPV4_HDR_LEN + UDP_HDR_LEN);
+ payload_sz = build_dhcp_response(iov, iovcnt, bpkt->buf + ETH_HDR_LEN +
+ IPV4_HDR_LEN + UDP_HDR_LEN);
payload_sz = build_udp_response(iov, iovcnt,
bpkt->buf + ETH_HDR_LEN + IPV4_HDR_LEN,
payload_sz, 67, 68);
@@ -992,8 +1009,8 @@
* 255.255.255.255 (bcast). For renewals, it seems like that that also
* suffices, which seems reasonable. */
payload_sz = build_ip_response(iov, iovcnt, bpkt->buf + ETH_HDR_LEN,
- payload_sz, guest_v4_router, bcast_v4_addr,
- IP_UDPPROTO);
+ payload_sz, guest_v4_router,
+ bcast_v4_addr, IP_UDPPROTO);
payload_sz = build_eth_response(iov, iovcnt, bpkt->buf, payload_sz,
ETH_TYPE_IPV4);
@@ -1018,13 +1035,16 @@
memcpy(p, host_eth_addr, ETH_ADDR_LEN);
p += ETH_ADDR_LEN;
/* SPA: addr they are looking for, which was the request TPA */
- iov_memcpy_from(iov, iovcnt, ETH_HDR_LEN + ARP_OFF_TPA, p, IPV4_ADDR_LEN);
+ iov_memcpy_from(iov, iovcnt, ETH_HDR_LEN + ARP_OFF_TPA, p,
+ IPV4_ADDR_LEN);
p += IPV4_ADDR_LEN;
/* THA was the SHA of the request */
- iov_memcpy_from(iov, iovcnt, ETH_HDR_LEN + ARP_OFF_SHA, p, ETH_ADDR_LEN);
+ iov_memcpy_from(iov, iovcnt, ETH_HDR_LEN + ARP_OFF_SHA, p,
+ ETH_ADDR_LEN);
p += ETH_ADDR_LEN;
/* TPA was the SPA of the request */
- iov_memcpy_from(iov, iovcnt, ETH_HDR_LEN + ARP_OFF_SPA, p, IPV4_ADDR_LEN);
+ iov_memcpy_from(iov, iovcnt, ETH_HDR_LEN + ARP_OFF_SPA, p,
+ IPV4_ADDR_LEN);
p += IPV4_ADDR_LEN;
return p - buf;
@@ -1121,8 +1141,8 @@
size_t icmp_off)
{
/* TODO: we could respond to pings sent to us (router_ip). For anything
- * else, we'll need to work with the bypass (if possible, maybe ID it with
- * the Identifier field and map that to the bypassed conv)). */
+ * else, we'll need to work with the bypass (if possible, maybe ID it
+ * with the Identifier field and map that to the bypassed conv)). */
return NULL;
}
@@ -1187,8 +1207,8 @@
fprintf(stderr, "Short IPv4 header, dropping!\n");
return;
}
- /* It's up to each protocol to give us the ip_nat_map matching the packet
- * and to change the packet's src port. */
+ /* It's up to each protocol to give us the ip_nat_map matching the
+ * packet and to change the packet's src port. */
protocol = iov_get_byte(iov, iovcnt, ip_off + IPV4_OFF_PROTO);
proto_hdr_off = ipv4_get_proto_off(iov, iovcnt, ip_off);
switch (protocol) {
@@ -1202,21 +1222,21 @@
map = handle_icmp_tx(iov, iovcnt, proto_hdr_off);
break;
}
- /* If the protocol handler already dealt with it (e.g. via emulation), we
- * bail out. o/w, they gave us the remapping we should use to rewrite and
- * send the packet. */
+ /* If the protocol handler already dealt with it (e.g. via emulation),
+ * we bail out. o/w, they gave us the remapping we should use to
+ * rewrite and send the packet. */
if (!map)
return;
- /* At this point, we have a refcnted map, which will keep the map alive and
- * its FD open. */
+ /* At this point, we have a refcnted map, which will keep the map alive
+ * and its FD open. */
iov_memcpy_from(iov, iovcnt, ip_off + IPV4_OFF_SRC, src_addr,
IPV4_ADDR_LEN);
iov_memcpy_from(iov, iovcnt, ip_off + IPV4_OFF_DST, dst_addr,
IPV4_ADDR_LEN);
- /* If the destination is the ROUTER_IP, then it's really meant to go to the
- * host (loopback). In that case, we also need the src to be loopback, so
- * that the *host's* IP stack recognizes the connection (necessary for
- * host-initiated connections via static maps). */
+ /* If the destination is the ROUTER_IP, then it's really meant to go to
+ * the host (loopback). In that case, we also need the src to be
+ * loopback, so that the *host's* IP stack recognizes the connection
+ * (necessary for host-initiated connections via static maps). */
if (!memcmp(dst_addr, guest_v4_router, IPV4_ADDR_LEN)) {
ipv4_change_addr(iov, iovcnt, ip_off, protocol, proto_hdr_off,
dst_addr, loopback_v4_addr, IPV4_OFF_DST);
@@ -1228,15 +1248,15 @@
}
/* We didn't change the size of the packet, just a few fields. So we
* shouldn't need to worry about iov[] being too big. This is different
- * than the receive case, where the guest should give us an MTU-sized iov.
- * Here, they just gave us whatever they wanted to send.
+ * than the receive case, where the guest should give us an MTU-sized
+ * iov. Here, they just gave us whatever they wanted to send.
*
- * However, we still need to drop the ethernet header from the front of the
- * packet, and just send the IP header + payload. */
+ * However, we still need to drop the ethernet header from the front of
+ * the packet, and just send the IP header + payload. */
iov_strip_bytes(iov, iovcnt, ETH_HDR_LEN);
- /* As far as blocking goes, this is like blasting out a raw IP packet. It
- * shouldn't block, preferring to drop, though there might be some cases
- * where a qlock is grabbed or the medium/NIC blocks. */
+ /* As far as blocking goes, this is like blasting out a raw IP packet.
+ * It shouldn't block, preferring to drop, though there might be some
+ * cases where a qlock is grabbed or the medium/NIC blocks. */
writev(map->host_data_fd, iov, iovcnt);
map->is_stale = FALSE;
kref_put(&map->kref);
@@ -1254,7 +1274,8 @@
if (vnet_snoop)
writev(snoop_fd, iov, iovcnt);
if (!iov_has_bytes(iov, iovcnt, ETH_HDR_LEN)) {
- fprintf(stderr, "Short ethernet frame from the guest, dropping!\n");
+ fprintf(stderr,
+ "Short ethernet frame from the guest, dropping!\n");
return -1;
}
ether_type = iov_get_be16(iov, iovcnt, ETH_OFF_ETYPE);
@@ -1269,7 +1290,8 @@
handle_ipv6_tx(iov, iovcnt);
break;
default:
- fprintf(stderr, "Unknown ethertype 0x%x, dropping!\n", ether_type);
+ fprintf(stderr, "Unknown ethertype 0x%x, dropping!\n",
+ ether_type);
return -1;
};
return 0;
@@ -1353,22 +1375,25 @@
/* If the src was the host (loopback), the guest thinks the remote is
* ROUTER_IP. */
if (!memcmp(src_addr, loopback_v4_addr, IPV4_ADDR_LEN)) {
- ipv4_change_addr(iov, iovcnt, ip_off, map->protocol, proto_hdr_off,
- src_addr, guest_v4_router, IPV4_OFF_SRC);
+ ipv4_change_addr(iov, iovcnt, ip_off, map->protocol,
+ proto_hdr_off, src_addr, guest_v4_router,
+ IPV4_OFF_SRC);
}
- /* Interesting case. If we rewrite it to guest_v4_router, when the guest
- * responds, *that* packet will get rewritten to loopback. If we ignore it,
- * and it's qemu mode, it'll actually work. If it's real addr mode, the
- * guest won't send an IP packet out that it thinks is for itself. */
- if (vnet_real_ip_addrs && !memcmp(src_addr, host_v4_addr, IPV4_ADDR_LEN)) {
+ /* Interesting case. If we rewrite it to guest_v4_router, when the
+ * guest responds, *that* packet will get rewritten to loopback. If we
+ * ignore it, and it's qemu mode, it'll actually work. If it's real
+ * addr mode, the guest won't send an IP packet out that it thinks is
+ * for itself. */
+ if (vnet_real_ip_addrs && !memcmp(src_addr, host_v4_addr,
+ IPV4_ADDR_LEN)) {
fprintf(stderr, "VNET received packet from host_v4_addr. Not translating, the guest cannot respond!\n");
}
/* Regardless, the dst changes from HOST_IP/loopback to GUEST_IP */
ipv4_change_addr(iov, iovcnt, ip_off, map->protocol, proto_hdr_off,
dst_addr, guest_v4_addr, IPV4_OFF_DST);
- /* Note we did the incremental xsum for the IP header, but also do a final
- * xsum. We need the final xsum in case the kernel's networking stack
- * messed up the header. */
+ /* Note we did the incremental xsum for the IP header, but also do a
+ * final xsum. We need the final xsum in case the kernel's networking
+ * stack messed up the header. */
xsum_ipv4_header(iov, iovcnt, ip_off);
}
@@ -1388,8 +1413,8 @@
uint8_t version;
uint16_t ether_type;
- /* The conv is reading from a Qmsg queue. We should always receive at least
- * an IPv4 header from the kernel. */
+ /* The conv is reading from a Qmsg queue. We should always receive at
+ * least an IPv4 header from the kernel. */
assert(len >= IPV4_HDR_LEN + ETH_HDR_LEN);
version = ipv4_get_version(iov, iovcnt, ip_off);
switch (version) {
@@ -1428,9 +1453,9 @@
ssize_t pkt_sz = 0;
struct iovec iov_copy[iovcnt];
- /* We're going to readv ETH_HDR_LEN bytes into the iov. To do so, we'll use
- * a separate iov to track this offset. The iov and iov_copy both point to
- * the same memory (minus the stripping). */
+ /* We're going to readv ETH_HDR_LEN bytes into the iov. To do so, we'll
+ * use a separate iov to track this offset. The iov and iov_copy both
+ * point to the same memory (minus the stripping). */
memcpy(iov_copy, iov, sizeof(struct iovec) * iovcnt);
iov_strip_bytes(iov_copy, iovcnt, ETH_HDR_LEN);
TAILQ_FOREACH_SAFE(i, &inbound_todo, inbound, temp) {
diff --git a/user/vmm/pagetables.c b/user/vmm/pagetables.c
index 63a62e5..7e6707d 100644
--- a/user/vmm/pagetables.c
+++ b/user/vmm/pagetables.c
@@ -63,16 +63,18 @@
aligned_end = ALIGN(end, PAGE_RESOLUTION);
cur_page = aligned_start;
- /* We always do end-1 because end from /proc/self/maps is not inclusive */
+ /* We always do end-1 because end from /proc/self/maps is not inclusive
+ * */
for (pml4 = PML4(start); pml4 <= PML4(end - 1); pml4++) {
struct ptp *p1 = p512 + pml4 + 1;
- /* Create the PML4 entry. Rather than check, I just overwrite it. */
+ /* Create the PML4 entry. Rather than check, I just overwrite
+ * it. */
p512->pte[pml4] = (uintptr_t) p1 | PTE_KERN_RW;
- for (pml3 = PML3(cur_page); pml3 < NPTENTRIES &&
- cur_page < aligned_end; pml3++, cur_page += PML3_PTE_REACH) {
-
+ for (pml3 = PML3(cur_page);
+ pml3 < NPTENTRIES && cur_page < aligned_end;
+ pml3++, cur_page += PML3_PTE_REACH) {
/* Create the PML3 entry. */
p1->pte[pml3] = cur_page | PTE_KERN_RW | PTE_PS;
}
@@ -96,10 +98,10 @@
uintptr_t first, second;
/* How many page table pages do we need?
- * If we create 1G PTEs for the whole space, it just takes 2M + 4k worth of
- * memory. Perhaps we should just identity map the whole space upfront.
- * Right now we don't MAP_POPULATE because we don't expect all the PTEs
- * to be used. */
+ * If we create 1G PTEs for the whole space, it just takes 2M + 4k worth
+ * of memory. Perhaps we should just identity map the whole space
+ * upfront. Right now we don't MAP_POPULATE because we don't expect all
+ * the PTEs to be used. */
if (!vm->root)
vm->root = mmap((void *)PAGE_TABLE_ROOT_START, 0x201000,
PROT_READ | PROT_WRITE,
diff --git a/user/vmm/sched.c b/user/vmm/sched.c
index 32c420e..280e39e 100644
--- a/user/vmm/sched.c
+++ b/user/vmm/sched.c
@@ -103,8 +103,8 @@
{
struct syscall *sysc;
- /* I think we can make this assert now. If not, check pthread.c. (concern
- * was having old ev_qs firing and running this handler). */
+ /* I think we can make this assert now. If not, check pthread.c.
+ * (concern was having old ev_qs firing and running this handler). */
assert(ev_msg);
sysc = ev_msg->ev_arg3;
assert(sysc);
@@ -124,7 +124,8 @@
-1, 0);
evq = get_eventq_raw();
assert(mmap_block && evq);
- evq->ev_flags = EVENT_IPI | EVENT_INDIR | EVENT_SPAM_INDIR | EVENT_WAKEUP;
+ evq->ev_flags = EVENT_IPI | EVENT_INDIR | EVENT_SPAM_INDIR |
+ EVENT_WAKEUP;
evq->ev_vcore = vcoreid;
evq->ev_mbox->type = EV_MBOX_UCQ;
ucq_init_raw(&evq->ev_mbox->ucq, mmap_block, mmap_block + PGSIZE);
@@ -148,8 +149,8 @@
task_thread_cache = kmem_cache_create("task threads",
sizeof(struct vmm_thread),
__alignof__(struct vmm_thread), 0,
- task_thread_ctor, task_thread_dtor,
- NULL);
+ task_thread_ctor,
+ task_thread_dtor, NULL);
}
/* The scheduling policy is encapsulated in the next few functions (from here
@@ -160,8 +161,9 @@
/* Sanity checks on our accounting. */
assert(atomic_read(&nr_unblk_guests) >= 0);
assert(atomic_read(&nr_unblk_tasks) >= 0);
- /* Lockless peak. This is always an estimate. Some of our tasks busy-wait,
- * so it's not enough to just give us one vcore for all tasks, yet. */
+ /* Lockless peak. This is always an estimate. Some of our tasks
+ * busy-wait, so it's not enough to just give us one vcore for all
+ * tasks, yet. */
return atomic_read(&nr_unblk_guests) + atomic_read(&nr_unblk_tasks);
}
@@ -261,9 +263,11 @@
}
/* This races with enqueue_vmm_thread, which can run on another core.
* Here are the rules:
- * - set when runnable (race free, only one state for the thread at a time)
+ * - set when runnable (race free, only one state for the thread at a
+ * time)
* - cleared when we run it (race free, we're the only runners)
- * - if we take an interrupt, we'll just run_current_uthread and not check
+ * - if we take an interrupt, we'll just run_current_uthread and not
+ * check
* - if we vmexit, we'll run the buddy directly */
assert(vcore_id() <= current_vm->nr_gpcs);
vth = greedy_rnbl_guests[vcore_id() - 1];
@@ -300,12 +304,14 @@
if (sched_is_greedy()) {
vth = sched_pick_thread_greedy();
if (!vth) {
- /* sys_halt_core will return, but we need to restart the vcore. We
- * might have woke due to an event, and we'll need to handle_events
- * and other things dealt with by uthreads. */
+ /* sys_halt_core will return, but we need to restart the
+ * vcore. We might have woke due to an event, and we'll
+ * need to handle_events and other things dealt with by
+ * uthreads. */
if (vcore_id() == 0)
sys_halt_core(0);
- /* In greedy mode, yield will abort and we'll just restart */
+ /* In greedy mode, yield will abort and we'll just
+ * restart */
vcore_yield_or_restart();
}
} else {
@@ -327,8 +333,8 @@
static void vmm_thread_paused(struct uthread *uth)
{
- /* The thread stopped for some reason, usually a preemption. We'd like to
- * just run it whenever we get a chance. Note that it didn't become
+ /* The thread stopped for some reason, usually a preemption. We'd like
+ * to just run it whenever we get a chance. Note that it didn't become
* 'blocked' - it's still runnable. */
enqueue_vmm_thread((struct vmm_thread*)uth);
}
@@ -340,8 +346,8 @@
acct_thread_blocked((struct vmm_thread*)uth);
sysc->u_data = uth;
if (!register_evq(sysc, sysc_evq)) {
- /* Lost the race with the call being done. The kernel won't send the
- * event. Just restart him. */
+ /* Lost the race with the call being done. The kernel won't
+ * send the event. Just restart him. */
restart_thread(sysc);
}
/* GIANT WARNING: do not touch the thread after this point. */
@@ -349,10 +355,10 @@
static void vmm_thread_has_blocked(struct uthread *uth, int flags)
{
- /* The thread blocked on something like a mutex. It's not runnable, so we
- * don't need to put it on a list, but we do need to account for it not
- * running. We'll find out (via thread_runnable) when it starts up again.
- */
+ /* The thread blocked on something like a mutex. It's not runnable, so
+ * we don't need to put it on a list, but we do need to account for it
+ * not running. We'll find out (via thread_runnable) when it starts up
+ * again. */
acct_thread_blocked((struct vmm_thread*)uth);
}
@@ -397,8 +403,8 @@
{
struct ctlr_thread *cth = (struct ctlr_thread*)uth;
- /* We just immediately run our buddy. The ctlr and the guest are accounted
- * together ("pass the token" back and forth). */
+ /* We just immediately run our buddy. The ctlr and the guest are
+ * accounted together ("pass the token" back and forth). */
current_uthread = NULL;
stats_run_vth((struct vmm_thread*)cth->buddy);
run_uthread((struct uthread*)cth->buddy);
@@ -417,7 +423,8 @@
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,
+ "Note: this may be a kernel module, not the kernel\n");
fprintf(stderr, "RSP was %p, ", (void *)vm_tf->tf_rsp);
fprintf(stderr, "RIP was %p:\n", (void *)vm_tf->tf_rip);
/* TODO: properly walk the kernel page tables to map the tf_rip
@@ -428,8 +435,8 @@
showstatus(stderr, cth->buddy);
exit(0);
}
- /* We want to atomically yield and start/reenqueue our buddy. We do so in
- * vcore context on the other side of the yield. */
+ /* We want to atomically yield and start/reenqueue our buddy. We do so
+ * in vcore context on the other side of the yield. */
uthread_yield(FALSE, __swap_to_gth, 0);
}
@@ -443,8 +450,8 @@
cth->uthread.flags |= UTHREAD_SAVED;
init_user_ctx(&cth->uthread.u_ctx, (uintptr_t)&__ctlr_entry,
(uintptr_t)(cth->stacktop));
- /* We just immediately run our buddy. The ctlr and the guest are accounted
- * together ("pass the token" back and forth). */
+ /* We just immediately run our buddy. The ctlr and the guest are
+ * accounted together ("pass the token" back and forth). */
current_uthread = NULL;
stats_run_vth((struct vmm_thread*)cth);
run_uthread((struct uthread*)cth);
@@ -576,16 +583,16 @@
gth = gpcid_to_gth(vm, i);
cth = gth->buddy;
fprintf(stderr, "\tGPC %2d: %lu resched, %lu gth runs, %lu ctl runs, %lu user-handled vmexits\n",
- i,
+ i,
((struct vmm_thread*)gth)->nr_resched,
((struct vmm_thread*)gth)->nr_runs,
((struct vmm_thread*)cth)->nr_runs,
gth->nr_vmexits);
if (reset) {
- ((struct vmm_thread*)gth)->nr_resched = 0;
- ((struct vmm_thread*)gth)->nr_runs = 0;
- ((struct vmm_thread*)cth)->nr_runs = 0;
- gth->nr_vmexits = 0;
+ ((struct vmm_thread*)gth)->nr_resched = 0;
+ ((struct vmm_thread*)gth)->nr_runs = 0;
+ ((struct vmm_thread*)cth)->nr_runs = 0;
+ gth->nr_vmexits = 0;
}
}
fprintf(stderr, "\n\tNr unblocked gpc %lu, Nr unblocked tasks %lu\n",
@@ -632,7 +639,8 @@
uthread_mcp_init();
register_ev_handler(EV_FREE_APPLE_PIE, ev_handle_diag, NULL);
if (sched_is_greedy()) {
- greedy_rnbl_guests = calloc(vm->nr_gpcs, sizeof(struct vmm_thread *));
+ greedy_rnbl_guests = calloc(vm->nr_gpcs,
+ sizeof(struct vmm_thread *));
assert(greedy_rnbl_guests);
vcore_request_total(sched_nr_greedy_cores());
syscall(SYS_vmm_ctl, VMM_CTL_SET_EXITS,
diff --git a/user/vmm/util.c b/user/vmm/util.c
index 63a6b07..4b09033 100644
--- a/user/vmm/util.c
+++ b/user/vmm/util.c
@@ -66,13 +66,13 @@
guest_pc = vm_tf->tf_rip;
guest_fp = vm_tf->tf_rbp;
- /* The BT should work for any code using frame pointers. Most of the time,
- * this will be vmlinux, and calling it that helps our backtrace. This
- * spits out the format that is parsed by bt-akaros.sh. */
+ /* The BT should work for any code using frame pointers. Most of the
+ * time, this will be vmlinux, and calling it that helps our backtrace.
+ * This spits out the format that is parsed by bt-akaros.sh. */
fprintf(f, "Backtracing guest, vmlinux is assumed, but check addrs\n");
for (int i = 1; i < 30; i++) {
- fprintf(f, "#%02d Addr %p is in vmlinux at offset %p\n", i, guest_pc,
- guest_pc);
+ fprintf(f, "#%02d Addr %p is in vmlinux at offset %p\n", i,
+ guest_pc, guest_pc);
if (!guest_fp)
break;
if (gva2gpa(vm_thread, guest_fp, &host_fp))
diff --git a/user/vmm/virtio.c b/user/vmm/virtio.c
index 42e30c1..1b446c8 100644
--- a/user/vmm/virtio.c
+++ b/user/vmm/virtio.c
@@ -29,20 +29,20 @@
// as soon as possible, so that they don't skip this when they
// implement new devices.
switch (vqdev->dev_id) {
- case VIRTIO_ID_CONSOLE:
- // No interdependent features for the console.
- break;
- case VIRTIO_ID_NET:
- // There is no "mandatory" feature bit that we always want to have,
- // either the device can set its own MAC Address (as it does now)
- // or the driver can set it using a controller thread.
- break;
- case VIRTIO_ID_BLOCK:
- break;
- case 0:
- return "Invalid device id (0x0)! On the MMIO transport, this value indicates that the device is a system memory map with placeholder devices at static, well known addresses. In any case, this is not something you validate features for.";
- default:
- return "Validation not implemented for this device type! You MUST implement validation for this device! You should add your new code to the virtio_validate_feat function in vmm/virtio.c.";
+ case VIRTIO_ID_CONSOLE:
+ // No interdependent features for the console.
+ break;
+ case VIRTIO_ID_NET:
+ // There is no "mandatory" feature bit that we always want to
+ // have, either the device can set its own MAC Address (as it
+ // does now) or the driver can set it using a controller thread.
+ break;
+ case VIRTIO_ID_BLOCK:
+ break;
+ case 0:
+ return "Invalid device id (0x0)! On the MMIO transport, this value indicates that the device is a system memory map with placeholder devices at static, well known addresses. In any case, this is not something you validate features for.";
+ default:
+ return "Validation not implemented for this device type! You MUST implement validation for this device! You should add your new code to the virtio_validate_feat function in vmm/virtio.c.";
}
// Validate common features
diff --git a/user/vmm/virtio_blk.c b/user/vmm/virtio_blk.c
index 071fb55..b031886 100644
--- a/user/vmm/virtio_blk.c
+++ b/user/vmm/virtio_blk.c
@@ -12,11 +12,11 @@
int debug_virtio_blk;
#define DPRINTF(fmt, ...) \
- do { \
- if (debug_virtio_blk) { \
- fprintf(stderr, "virtio_blk: " fmt, ##__VA_ARGS__); \
- } \
- } while (0)
+do { \
+ if (debug_virtio_blk) { \
+ fprintf(stderr, "virtio_blk: " fmt, ##__VA_ARGS__); \
+ } \
+} while (0)
/* TODO(ganshun): multiple disks */
static int diskfd;
@@ -30,7 +30,8 @@
diskfd = open(filename, O_RDWR);
if (diskfd < 0)
- VIRTIO_DEV_ERRX(vqdev, "Could not open disk image file %s", filename);
+ VIRTIO_DEV_ERRX(vqdev, "Could not open disk image file %s",
+ filename);
if (stat(filename, &stat_result) == -1)
VIRTIO_DEV_ERRX(vqdev, "Could not stat file %s", filename);
@@ -64,12 +65,12 @@
if (!dev->poke_guest)
VIRTIO_DEV_ERRX(vq->vqdev,
- "The 'poke_guest' function pointer was not set.");
+ "The 'poke_guest' function pointer was not set.");
iov = malloc(vq->qnum_max * sizeof(struct iovec));
if (iov == NULL)
VIRTIO_DEV_ERRX(vq->vqdev,
- "malloc returned null trying to allocate iov.\n");
+ "malloc returned null trying to allocate iov.\n");
for (;;) {
head = virtio_next_avail_vq_desc(vq, iov, &olen, &ilen);
@@ -96,7 +97,8 @@
if (out->type & VIRTIO_BLK_T_OUT) {
if ((offset + iov[1].iov_len) > (cfg->capacity * 512))
- VIRTIO_DEV_ERRX(vq->vqdev, "write past end of file!\n");
+ VIRTIO_DEV_ERRX(vq->vqdev,
+ "write past end of file!\n");
ret = writev(diskfd, &iov[1], 1);
@@ -120,7 +122,8 @@
char *pf = "";
for (int i = 0; i < iov[olen].iov_len; i += 2) {
- uint8_t *p = (uint8_t *)iov[olen].iov_base + i;
+ uint8_t *p =
+ (uint8_t*)iov[olen].iov_base + i;
fprintf(stderr, "%s%02x", pf, *(p + 1));
fprintf(stderr, "%02x", *p);
diff --git a/user/vmm/virtio_lguest_console.c b/user/vmm/virtio_lguest_console.c
index fb84ae9..4624233 100644
--- a/user/vmm/virtio_lguest_console.c
+++ b/user/vmm/virtio_lguest_console.c
@@ -52,9 +52,10 @@
// NOTE: The virtio_next_avail_vq_desc will not write more than
// vq->vring.num entries to iov, and the device implementation
- // (virtio_mmio.c) will not allow the driver to set vq->vring.num to a
- // value greater than QueueNumMax (vq->qnum_max), so you are safe as
- // long as your iov is at least vq->qnum_max iovecs in size.
+ // (virtio_mmio.c) will not allow the driver to set vq->vring.num
+ // to a value greater than QueueNumMax (vq->qnum_max), so you are
+ // safe as long as your iov is at least vq->qnum_max iovecs in
+ // size.
iov = malloc(vq->qnum_max * sizeof(struct iovec));
if (vq->qready == 0x0)
@@ -69,7 +70,8 @@
head = virtio_next_avail_vq_desc(vq, iov, &olen, &ilen);
if (olen) {
- // virtio-v1.0-cs04 s5.3.6.1 Device Operation (console section)
+ // virtio-v1.0-cs04 s5.3.6.1 Device Operation (console
+ // section)
VIRTIO_DRI_ERRX(vq->vqdev,
"The driver placed a device-readable buffer in the console device's receiveq.\n"
" See virtio-v1.0-cs04 s5.3.6.1 Device Operation");
@@ -77,7 +79,8 @@
// TODO: We may want to add some sort of console abort
// (e.g. type q and enter to quit)
- // readv from stdin as much as we can (to end of bufs or end of input)
+ // readv from stdin as much as we can (to end of bufs or end of
+ // input)
num_read = readv(0, iov, ilen);
if (num_read < 0)
VIRTIO_DEV_ERRX(vq->vqdev,
@@ -123,9 +126,10 @@
// NOTE: The virtio_next_avail_vq_desc will not write more than
// vq->vring.num entries to iov, and the device implementation
- // (virtio_mmio.c) will not allow the driver to set vq->vring.num to a
- // value greater than QueueNumMax (vq->qnum_max), so you are safe as
- // long as your iov is at least vq->qnum_max iovecs in size.
+ // (virtio_mmio.c) will not allow the driver to set vq->vring.num
+ // to a value greater than QueueNumMax (vq->qnum_max), so you are
+ // safe as long as your iov is at least vq->qnum_max iovecs in
+ // size.
iov = malloc(vq->qnum_max * sizeof(struct iovec));
if (vq->qready == 0x0)
@@ -138,7 +142,8 @@
head = virtio_next_avail_vq_desc(vq, iov, &olen, &ilen);
if (ilen) {
- // virtio-v1.0-cs04 s5.3.6.1 Device Operation (console section)
+ // virtio-v1.0-cs04 s5.3.6.1 Device Operation (console
+ // section)
VIRTIO_DRI_ERRX(vq->vqdev,
"The driver placed a device-writeable buffer in the console device's transmitq.\n"
" See virtio-v1.0-cs04 s5.3.6.1 Device Operation");
diff --git a/user/vmm/virtio_lguest_helpers.c b/user/vmm/virtio_lguest_helpers.c
index 00a8fd6..801d5cf 100644
--- a/user/vmm/virtio_lguest_helpers.c
+++ b/user/vmm/virtio_lguest_helpers.c
@@ -50,10 +50,10 @@
void *virtio_check_pointer(struct virtio_vq *vq, uint64_t addr,
uint32_t size, char *file, uint32_t line)
{
- // We check that the pointer + the size doesn't wrap around, and that the
- // pointer + the size isn't past the top of the guest's address space.
- // UVPT is the top of the guest's address space, and is included from
- // ros/arch/mmu64.h via ros/arch/mmu.h.
+ // We check that the pointer + the size doesn't wrap around, and that
+ // the pointer + the size isn't past the top of the guest's address
+ // space. UVPT is the top of the guest's address space, and is included
+ // from ros/arch/mmu64.h via ros/arch/mmu.h.
if ((addr + size) < addr || (addr + size) > UVPT)
VIRTIO_DRI_ERRX(vq->vqdev,
"Driver provided an invalid address or size (addr:0x%x sz:%u).\n"
@@ -79,19 +79,22 @@
if (!(desc[i].flags & VRING_DESC_F_NEXT))
return max;
- // TODO: Closely audit the decision to use ACCESS_ONCE() instead of wmb().
- // If we encounter strange problems in the future, it might be worth
- // changing it back to a wmb() to see what happens. For the record,
- // the virtio console doesn't seem to have any issues running without
- // the ACCESS_ONCE() or the wmb(). But they had a barrier here, so
- // I'm hesitant to do anything less than ACCESS_ONCE().
+ // TODO: Closely audit the decision to use ACCESS_ONCE() instead of
+ // wmb().
+ // If we encounter strange problems in the future, it might be
+ // worth changing it back to a wmb() to see what happens. For the
+ // record, the virtio console doesn't seem to have any issues
+ // running without the ACCESS_ONCE() or the wmb(). But they had a
+ // barrier here, so I'm hesitant to do anything less than
+ // ACCESS_ONCE().
// Based on the original comment from lguest:
// "Make sure compiler knows to grab that: we don't want it changing!",
// it seems that they used a memory barrier after `next = desc[i].next`
// to prevent the compiler from returning a `next` that differs from
// the `next` that is compared to max. An ACCESS_ONCE() should suffice
- // to prevent this (see ros/common.h and http://lwn.net/Articles/508991/).
+ // to prevent this (see ros/common.h and
+ // http://lwn.net/Articles/508991/).
next = ACCESS_ONCE(desc[i].next);
if (next >= max)
@@ -124,7 +127,8 @@
vq->vring.used->ring[vq->vring.used->idx % vq->vring.num].len = len;
// virtio-v1.0-cs04 s2.4.8.2 The Virtqueue Used Ring
- // TODO: Take note, Barret is thinking about renaming our wmb() to wwmb()
+ // TODO: Take note, Barret is thinking about renaming our wmb() to
+ // wwmb()
// The device MUST set len prior to updating the used idx, hence wmb()
wmb();
vq->vring.used->idx++;
@@ -151,21 +155,21 @@
eventfd_t event;
while (vq->last_avail == vq->vring.avail->idx) {
- // We know the ring has updated when idx advances. We check == because
- // idx is allowed to wrap around eventually.
+ // We know the ring has updated when idx advances. We check ==
+ // because idx is allowed to wrap around eventually.
- // NOTE: lguest kicks the guest with an irq before they wait on the
- // eventfd. Instead, I delegate that responsibility to the
- // queue service functions.
+ // NOTE: lguest kicks the guest with an irq before they wait on
+ // the eventfd. Instead, I delegate that responsibility to the
+ // queue service functions.
- // We're about to wait on the eventfd, so we need to tell the guest
- // that we want a notification when it adds new buffers for
- // us to process.
+ // We're about to wait on the eventfd, so we need to tell the
+ // guest that we want a notification when it adds new buffers
+ // for us to process.
vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
- // If the guest added an available buffer while we were unsetting
- // the VRING_USED_F_NO_NOTIFY flag, we'll break out here and process
- // the new buffer.
+ // If the guest added an available buffer while we were
+ // unsetting the VRING_USED_F_NO_NOTIFY flag, we'll break out
+ // here and process the new buffer.
wrmb();
if (vq->last_avail != vq->vring.avail->idx) {
vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
@@ -194,7 +198,8 @@
if ((uint16_t)(vq->vring.avail->idx - vq->last_avail) > vq->vring.num)
VIRTIO_DRI_ERRX(vq->vqdev,
"vq index increased from %u to %u, exceeded capacity %u\n",
- vq->last_avail, vq->vring.avail->idx, vq->vring.num);
+ vq->last_avail, vq->vring.avail->idx,
+ vq->vring.num);
// lguest says here:
/*
@@ -237,22 +242,25 @@
// is used to index into desc.
do {
- // If it's an indirect descriptor, it points at a table of descriptors
- // provided by the guest driver. The descriptors in that table are
- // still chained, so we can ultimately handle them the same way as
- // direct descriptors.
+ // If it's an indirect descriptor, it points at a table of
+ // descriptors provided by the guest driver. The descriptors in
+ // that table are still chained, so we can ultimately handle
+ // them the same way as direct descriptors.
if (desc[i].flags & VRING_DESC_F_INDIRECT) {
// virtio-v1.0-cs04 s2.4.5.3.1 Indirect Descriptors
- if (!(vq->vqdev->dri_feat & (1<<VIRTIO_RING_F_INDIRECT_DESC)))
+ if (!(vq->vqdev->dri_feat &
+ (1<<VIRTIO_RING_F_INDIRECT_DESC)))
VIRTIO_DRI_ERRX(vq->vqdev,
"The driver must not set the INDIRECT flag on a descriptor if the INDIRECT_DESC feature was not negotiated.\n"
" See virtio-v1.0-cs04 s2.4.5.3.1 Indirect Descriptors");
- // NOTE: desc is only modified when we detect an indirect
- // descriptor, so our implementation works whether there is an
- // indirect descriptor at the very beginning OR at the very
- // end of the chain (virtio-v1.0-cs04 s2.4.5.3.2 compliant)
+ // NOTE: desc is only modified when we detect an
+ // indirect descriptor, so our implementation works
+ // whether there is an indirect descriptor at the very
+ // beginning OR at the very end of the chain
+ // (virtio-v1.0-cs04 s2.4.5.3.2 compliant)
+ //
// virtio-v1.0-cs04 s2.4.5.3.1 Indirect Descriptors
if (desc != vq->vring.desc)
VIRTIO_DRI_ERRX(vq->vqdev,
@@ -270,16 +278,19 @@
VIRTIO_DRI_ERRX(vq->vqdev,
"The size of a vring descriptor does not evenly divide the length of the indirect table provided by the driver. Bad table size.");
- // NOTE: virtio-v1.0-cs04 s2.4.5.3.2 Indirect Descriptors
- // says that the device MUST ignore the write-only flag in the
- // descriptor that refers to an indirect table. So we ignore.
+ // NOTE: virtio-v1.0-cs04 s2.4.5.3.2 Indirect
+ // Descriptors says that the device MUST ignore the
+ // write-only flag in the descriptor that refers to an
+ // indirect table. So we ignore.
max = desc[i].len / sizeof(struct vring_desc);
- desc = virtio_check_pointer(vq, desc[i].addr, desc[i].len,
- __FILE__, __LINE__);
+ desc = virtio_check_pointer(vq, desc[i].addr,
+ desc[i].len, __FILE__,
+ __LINE__);
- // Now that desc is pointing at the table of indirect descriptors,
- // we set i to 0 so that we can start walking that table
+ // Now that desc is pointing at the table of indirect
+ // descriptors, we set i to 0 so that we can start
+ // walking that table
i = 0;
// virtio-v1.0-cs04 s2.4.5.3.1 Indirect Descriptors
@@ -290,11 +301,14 @@
}
}
- // Now build the scatterlist of buffers for the device to process
+ // Now build the scatterlist of buffers for the device to
+ // process
iov[*olen + *ilen].iov_len = desc[i].len;
- iov[*olen + *ilen].iov_base = virtio_check_pointer(vq, desc[i].addr,
- desc[i].len,
- __FILE__, __LINE__);
+ iov[*olen + *ilen].iov_base = virtio_check_pointer(vq,
+ desc[i].addr,
+ desc[i].len,
+ __FILE__,
+ __LINE__);
if (desc[i].flags & VRING_DESC_F_WRITE) {
// input descriptor, increment *ilen
diff --git a/user/vmm/virtio_mmio.c b/user/vmm/virtio_mmio.c
index 7c30741..477aac8 100644
--- a/user/vmm/virtio_mmio.c
+++ b/user/vmm/virtio_mmio.c
@@ -33,6 +33,8 @@
* https://github.com/qemu/qemu/blob/v2.5.0/hw/virtio/virtio-mmio.c
* most recent hash on the file as of v2.5.0 tag:
* ab223c9518e8c7eb542ef3133de1a34475b69790
+ *
+ * TODO: This needs major refactoring/reformatting.
*/
#include <stdio.h>
@@ -73,9 +75,10 @@
else
memset(mmio_dev->vqdev->cfg, 0x0, mmio_dev->vqdev->cfg_sz);
- // Increment the ConfigGeneration, since the config space just got reset.
- // We can't simply set it to 0, because we must ensure that it changes when
- // the config space changes and it might currently be set to 0.
+ // Increment the ConfigGeneration, since the config space just got
+ // reset. We can't simply set it to 0, because we must ensure that it
+ // changes when the config space changes and it might currently be set
+ // to 0.
mmio_dev->cfg_gen++;
}
@@ -90,7 +93,8 @@
if (!mmio_dev->vqdev)
return;
- fprintf(stderr, "virtio mmio device reset: %s\n", mmio_dev->vqdev->name);
+ fprintf(stderr, "virtio mmio device reset: %s\n",
+ mmio_dev->vqdev->name);
// Clear any driver-activated feature bits
mmio_dev->vqdev->dri_feat = 0;
@@ -110,9 +114,9 @@
if (mmio_dev->vqdev->vqs[i].srv_th) {
// FIXME! PLEASE, FIXME!
// TODO: For now we are going to make device resets an error
- // once service threads exist on the queues. This is obviously
- // not sustainable, because the driver needs to be able
- // to reset the device after certain errors occur.
+ // once service threads exist on the queues. This is obviously
+ // not sustainable, because the driver needs to be able to reset
+ // the device after certain errors occur.
//
// In the future, when we actually decide how we want
// to clean up the threads, the sequence might look
@@ -165,15 +169,15 @@
"Attempt to read from a register not MagicValue, Version, or DeviceID on a device whose DeviceID is 0x0\n"
" See virtio-v1.0-cs04 s4.2.3.1.1 Device Initialization");
- // Now we know that the host provided a vqdev. As soon as the driver tries
- // to read the magic number, we know it's considering the device. This is
- // a great time to validate the features the host is providing. The host
- // must provide a valid combination of features, or we crash here
- // until the offered feature combination is made valid.
+ // Now we know that the host provided a vqdev. As soon as the driver
+ // tries to read the magic number, we know it's considering the device.
+ // This is a great time to validate the features the host is providing.
+ // The host must provide a valid combination of features, or we crash
+ // here until the offered feature combination is made valid.
if (offset == VIRTIO_MMIO_MAGIC_VALUE) {
- // NOTE: If you ever decide to change this to a warning instead of an
- // error, you might want to return an invalid magic value here
- // to tell the driver that it is poking at a bad device.
+ // NOTE: If you ever decide to change this to a warning instead
+ // of an error, you might want to return an invalid magic value
+ // here to tell the driver that it is poking at a bad device.
err = virtio_validate_feat(mmio_dev->vqdev,
mmio_dev->vqdev->dev_feat);
if (err)
@@ -226,24 +230,24 @@
// will have to do it for every virtio device you
// want to use in the future.
switch (size) {
- case 1:
- return *((uint8_t*)target);
- case 2:
- if ((uint64_t)target % 2 != 0)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "The driver must use 16 bit aligned reads for reading from 16 bit values in the device-specific configuration space.\n"
- " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout");
- return *((uint16_t*)target);
- case 4:
- if ((uint64_t)target % 4 != 0)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "The driver must use 32 bit aligned reads for reading from 32 or 64 bit values in the device-specific configuration space.\n"
- " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout");
- return *((uint32_t*)target);
- default:
+ case 1:
+ return *((uint8_t*)target);
+ case 2:
+ if ((uint64_t)target % 2 != 0)
VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "The driver must use 8, 16, or 32 bit wide and aligned reads for reading from the device-specific configuration space.\n"
+ "The driver must use 16 bit aligned reads for reading from 16 bit values in the device-specific configuration space.\n"
" See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout");
+ return *((uint16_t*)target);
+ case 4:
+ if ((uint64_t)target % 4 != 0)
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "The driver must use 32 bit aligned reads for reading from 32 or 64 bit values in the device-specific configuration space.\n"
+ " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout");
+ return *((uint32_t*)target);
+ default:
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "The driver must use 8, 16, or 32 bit wide and aligned reads for reading from the device-specific configuration space.\n"
+ " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout");
}
}
@@ -256,99 +260,99 @@
// virtio-v1.0-cs04 Table 4.1
switch (offset) {
- // Magic value
- // 0x74726976 (a Little Endian equivalent of the “virt” string).
- case VIRTIO_MMIO_MAGIC_VALUE:
- return VIRT_MAGIC;
+ // Magic value
+ // 0x74726976 (a Little Endian equivalent of the “virt” string).
+ case VIRTIO_MMIO_MAGIC_VALUE:
+ return VIRT_MAGIC;
- // Device version number
- // 0x2. Note: Legacy devices (see 4.2.4 Legacy interface) used 0x1.
- case VIRTIO_MMIO_VERSION:
- return VIRT_MMIO_VERSION;
+ // Device version number
+ // 0x2. Note: Legacy devices (see 4.2.4 Legacy interface) used 0x1.
+ case VIRTIO_MMIO_VERSION:
+ return VIRT_MMIO_VERSION;
- // Virtio Subsystem Device ID (see virtio-v1.0-cs04 sec. 5 for values)
- // Value 0x0 is used to define a system memory map with placeholder
- // devices at static, well known addresses.
- case VIRTIO_MMIO_DEVICE_ID:
- return mmio_dev->vqdev->dev_id;
+ // Virtio Subsystem Device ID (see virtio-v1.0-cs04 sec. 5 for values)
+ // Value 0x0 is used to define a system memory map with placeholder
+ // devices at static, well known addresses.
+ case VIRTIO_MMIO_DEVICE_ID:
+ return mmio_dev->vqdev->dev_id;
- // Virtio Subsystem Vendor ID
- case VIRTIO_MMIO_VENDOR_ID:
- return VIRT_MMIO_VENDOR;
+ // Virtio Subsystem Vendor ID
+ case VIRTIO_MMIO_VENDOR_ID:
+ return VIRT_MMIO_VENDOR;
- // Flags representing features the device supports
- case VIRTIO_MMIO_DEVICE_FEATURES:
- if (!(mmio_dev->status & VIRTIO_CONFIG_S_DRIVER))
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Attempt to read device features before setting the DRIVER status bit.\n"
- " See virtio-v1.0-cs04 s3.1.1 Device Initialization");
-
- // high 32 bits requested
- if (mmio_dev->dev_feat_sel)
- return mmio_dev->vqdev->dev_feat >> 32;
- return mmio_dev->vqdev->dev_feat; // low 32 bits requested
-
- // Maximum virtual queue size
- // Returns the maximum size (number of elements) of the queue the device
- // is ready to process or zero (0x0) if the queue is not available.
- // Applies to the queue selected by writing to QueueSel.
- case VIRTIO_MMIO_QUEUE_NUM_MAX:
- // TODO: Are there other cases that count as "queue not available"?
- // NOTE: !qready does not count as "queue not available".
- if (mmio_dev->qsel >= mmio_dev->vqdev->num_vqs)
- return 0;
- return mmio_dev->vqdev->vqs[mmio_dev->qsel].qnum_max;
-
- // Virtual queue ready bit
- // Applies to the queue selected by writing to QueueSel.
- case VIRTIO_MMIO_QUEUE_READY:
- if (mmio_dev->qsel >= mmio_dev->vqdev->num_vqs)
- return 0;
- return mmio_dev->vqdev->vqs[mmio_dev->qsel].qready;
-
- // Interrupt status
- // Bit mask of events that caused the device interrupt to be asserted.
- // bit 0: Used Ring Update
- // bit 1: Configuration Change
- case VIRTIO_MMIO_INTERRUPT_STATUS:
- return mmio_dev->isr;
-
- // Device status
- case VIRTIO_MMIO_STATUS:
- return mmio_dev->status;
-
- // Configuration atomicity value
- // Contains a version for the device-specific configuration space
- // The driver checks this version before and after accessing the config
- // space, and if the values don't match it repeats the access.
- case VIRTIO_MMIO_CONFIG_GENERATION:
- return mmio_dev->cfg_gen;
-
- // Write-only register offsets:
- case VIRTIO_MMIO_DEVICE_FEATURES_SEL:
- case VIRTIO_MMIO_DRIVER_FEATURES:
- case VIRTIO_MMIO_DRIVER_FEATURES_SEL:
- case VIRTIO_MMIO_QUEUE_SEL:
- case VIRTIO_MMIO_QUEUE_NUM:
- case VIRTIO_MMIO_QUEUE_NOTIFY:
- case VIRTIO_MMIO_INTERRUPT_ACK:
- case VIRTIO_MMIO_QUEUE_DESC_LOW:
- case VIRTIO_MMIO_QUEUE_DESC_HIGH:
- case VIRTIO_MMIO_QUEUE_AVAIL_LOW:
- case VIRTIO_MMIO_QUEUE_AVAIL_HIGH:
- case VIRTIO_MMIO_QUEUE_USED_LOW:
- case VIRTIO_MMIO_QUEUE_USED_HIGH:
- // Read of write-only register
+ // Flags representing features the device supports
+ case VIRTIO_MMIO_DEVICE_FEATURES:
+ if (!(mmio_dev->status & VIRTIO_CONFIG_S_DRIVER))
VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Attempt to read write-only device register offset 0x%x.",
- offset);
+ "Attempt to read device features before setting the DRIVER status bit.\n"
+ " See virtio-v1.0-cs04 s3.1.1 Device Initialization");
+
+ // high 32 bits requested
+ if (mmio_dev->dev_feat_sel)
+ return mmio_dev->vqdev->dev_feat >> 32;
+ return mmio_dev->vqdev->dev_feat; // low 32 bits requested
+
+ // Maximum virtual queue size
+ // Returns the maximum size (number of elements) of the queue the device
+ // is ready to process or zero (0x0) if the queue is not available.
+ // Applies to the queue selected by writing to QueueSel.
+ case VIRTIO_MMIO_QUEUE_NUM_MAX:
+ // TODO: Are there other cases that count as "queue not available"?
+ // NOTE: !qready does not count as "queue not available".
+ if (mmio_dev->qsel >= mmio_dev->vqdev->num_vqs)
return 0;
- default:
- // Bad register offset
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Attempt to read invalid device register offset 0x%x.",
- offset);
+ return mmio_dev->vqdev->vqs[mmio_dev->qsel].qnum_max;
+
+ // Virtual queue ready bit
+ // Applies to the queue selected by writing to QueueSel.
+ case VIRTIO_MMIO_QUEUE_READY:
+ if (mmio_dev->qsel >= mmio_dev->vqdev->num_vqs)
return 0;
+ return mmio_dev->vqdev->vqs[mmio_dev->qsel].qready;
+
+ // Interrupt status
+ // Bit mask of events that caused the device interrupt to be asserted.
+ // bit 0: Used Ring Update
+ // bit 1: Configuration Change
+ case VIRTIO_MMIO_INTERRUPT_STATUS:
+ return mmio_dev->isr;
+
+ // Device status
+ case VIRTIO_MMIO_STATUS:
+ return mmio_dev->status;
+
+ // Configuration atomicity value
+ // Contains a version for the device-specific configuration space
+ // The driver checks this version before and after accessing the config
+ // space, and if the values don't match it repeats the access.
+ case VIRTIO_MMIO_CONFIG_GENERATION:
+ return mmio_dev->cfg_gen;
+
+ // Write-only register offsets:
+ case VIRTIO_MMIO_DEVICE_FEATURES_SEL:
+ case VIRTIO_MMIO_DRIVER_FEATURES:
+ case VIRTIO_MMIO_DRIVER_FEATURES_SEL:
+ case VIRTIO_MMIO_QUEUE_SEL:
+ case VIRTIO_MMIO_QUEUE_NUM:
+ case VIRTIO_MMIO_QUEUE_NOTIFY:
+ case VIRTIO_MMIO_INTERRUPT_ACK:
+ case VIRTIO_MMIO_QUEUE_DESC_LOW:
+ case VIRTIO_MMIO_QUEUE_DESC_HIGH:
+ case VIRTIO_MMIO_QUEUE_AVAIL_LOW:
+ case VIRTIO_MMIO_QUEUE_AVAIL_HIGH:
+ case VIRTIO_MMIO_QUEUE_USED_LOW:
+ case VIRTIO_MMIO_QUEUE_USED_HIGH:
+ // Read of write-only register
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Attempt to read write-only device register offset 0x%x.",
+ offset);
+ return 0;
+ default:
+ // Bad register offset
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Attempt to read invalid device register offset 0x%x.",
+ offset);
+ return 0;
}
return 0;
@@ -376,8 +380,8 @@
"Attempt to write to a device whose DeviceID is 0x0.\n"
" See virtio-v1.0-cs04 s4.2.3.1.1 Device Initialization");
- // Warn if FAILED and trying to do something that is definitely not a reset.
- // virtio-v1.0-cs04 s2.1.1 Device Status Field
+ // Warn if FAILED and trying to do something that is definitely not a
+ // reset. virtio-v1.0-cs04 s2.1.1 Device Status Field
if (offset != VIRTIO_MMIO_STATUS
&& (mmio_dev->status & VIRTIO_CONFIG_S_FAILED))
VIRTIO_DRI_WARNX(mmio_dev->vqdev,
@@ -388,9 +392,10 @@
// specific config space, because I was limited to seeing what
// the guest driver for the console device would do. You may
// run into issues when you implement virtio-net, since that
- // does more with the device-specific config. (In fact, I don't think
- // the guest driver ever even tried to write the device-specific
- // config space for the console, so this section is entirely untested)
+ // does more with the device-specific config. (In fact, I don't
+ // think the guest driver ever even tried to write the
+ // device-specific config space for the console, so this section
+ // is entirely untested)
if (offset >= VIRTIO_MMIO_CONFIG) {
offset -= VIRTIO_MMIO_CONFIG;
@@ -422,27 +427,27 @@
// will have to do it for every virtio device you
// want to use in the future.
switch (size) {
- case 1:
- *((uint8_t*)target) = *((uint8_t*)value);
- break;
- case 2:
- if ((uint64_t)target % 2 != 0)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "The driver must use 16 bit aligned writes for writing to 16 bit values in the device-specific configuration space.\n"
- " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout");
- *((uint16_t*)target) = *((uint16_t*)value);
- break;
- case 4:
- if ((uint64_t)target % 4 != 0)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "The driver must use 32 bit aligned writes for writing to 32 or 64 bit values in the device-specific configuration space.\n"
- " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout");
- *((uint32_t*)target) = *((uint32_t*)value);
- break;
- default:
+ case 1:
+ *((uint8_t*)target) = *((uint8_t*)value);
+ break;
+ case 2:
+ if ((uint64_t)target % 2 != 0)
VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "The driver must use 8, 16, or 32 bit wide and aligned writes for writing to the device-specific configuration space.\n"
+ "The driver must use 16 bit aligned writes for writing to 16 bit values in the device-specific configuration space.\n"
" See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout");
+ *((uint16_t*)target) = *((uint16_t*)value);
+ break;
+ case 4:
+ if ((uint64_t)target % 4 != 0)
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "The driver must use 32 bit aligned writes for writing to 32 or 64 bit values in the device-specific configuration space.\n"
+ " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout");
+ *((uint32_t*)target) = *((uint32_t*)value);
+ break;
+ default:
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "The driver must use 8, 16, or 32 bit wide and aligned writes for writing to the device-specific configuration space.\n"
+ " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout");
}
// Increment cfg_gen because the device-specific config changed
@@ -466,471 +471,488 @@
// virtio-v1.0-cs04 Table 4.1
switch (offset) {
- // Device (host) features word selection.
- case VIRTIO_MMIO_DEVICE_FEATURES_SEL:
- mmio_dev->dev_feat_sel = *value;
- break;
+ // Device (host) features word selection.
+ case VIRTIO_MMIO_DEVICE_FEATURES_SEL:
+ mmio_dev->dev_feat_sel = *value;
+ break;
- // Device feature flags activated by the driver
- case VIRTIO_MMIO_DRIVER_FEATURES:
- // virtio-v1.0-cs04 s3.1.1 Device Initialization
- if (mmio_dev->status & VIRTIO_CONFIG_S_FEATURES_OK) {
- // NOTE: The spec just says the driver isn't allowed to accept
- // NEW feature bits after setting FEATURES_OK. Although
- // the language makes it seem like it might be fine to
- // let the driver un-accept features after it sets
- // FEATURES_OK, this would require very careful handling,
- // so for now we just don't allow the driver to write to
- // the DriverFeatures register after FEATURES_OK is set.
+ // Device feature flags activated by the driver
+ case VIRTIO_MMIO_DRIVER_FEATURES:
+ // virtio-v1.0-cs04 s3.1.1 Device Initialization
+ if (mmio_dev->status & VIRTIO_CONFIG_S_FEATURES_OK) {
+ // NOTE: The spec just says the driver isn't allowed to
+ // accept NEW feature bits after setting FEATURES_OK.
+ // Although the language makes it seem like it might be
+ // fine to let the driver un-accept features after it
+ // sets FEATURES_OK, this would require very careful
+ // handling, so for now we just don't allow the driver
+ // to write to the DriverFeatures register after
+ // FEATURES_OK is set.
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "The driver may not accept (i.e. activate) new feature bits offered by the device after setting FEATURES_OK.\n"
+ " See virtio-v1.0-cs04 s3.1.1 Device Initialization");
+ } else if (mmio_dev->dri_feat_sel) {
+ // clear high 32 bits
+ mmio_dev->vqdev->dri_feat &= 0xffffffff;
+ // write high 32 bits
+ mmio_dev->vqdev->dri_feat |= ((uint64_t)(*value) << 32);
+ } else {
+ // clear low 32 bits
+ mmio_dev->vqdev->dri_feat &= ((uint64_t)0xffffffff <<
+ 32);
+ // write low 32 bits
+ mmio_dev->vqdev->dri_feat |= *value;
+ }
+ break;
+
+ // Activated (guest) features word selection
+ case VIRTIO_MMIO_DRIVER_FEATURES_SEL:
+ mmio_dev->dri_feat_sel = *value;
+ break;
+
+ // Virtual queue index
+ // Selects the virtual queue that QueueNumMax, QueueNum, QueueReady,
+ // QueueDescLow, QueueDescHigh, QueueAvailLow, QueueAvailHigh,
+ // QueueUsedLow and QueueUsedHigh apply to. The index number of the
+ // first queue is zero (0x0).
+ case VIRTIO_MMIO_QUEUE_SEL:
+ // NOTE: We must allow the driver to write whatever they want to
+ // QueueSel, because QueueNumMax contians 0x0 for invalid
+ // QueueSel indices.
+ mmio_dev->qsel = *value;
+ break;
+
+ // Virtual queue size
+ // The queue size is the number of elements in the queue, thus in the
+ // Descriptor Table, the Available Ring and the Used Ring. Writes
+ // notify the device what size queue the driver will use.
+ // This applies to the queue selected by writing to QueueSel.
+ case VIRTIO_MMIO_QUEUE_NUM:
+ if (mmio_dev->qsel < mmio_dev->vqdev->num_vqs) {
+ // virtio-v1.0-cs04 4.2.2.2 MMIO Device Register Layout
+ if (*value <=
+ mmio_dev->vqdev->vqs[mmio_dev->qsel].qnum_max)
+ mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.num =
+ *value;
+ else if ((*value != 0) && (*value & ((*value) - 1)))
VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "The driver may not accept (i.e. activate) new feature bits offered by the device after setting FEATURES_OK.\n"
- " See virtio-v1.0-cs04 s3.1.1 Device Initialization");
- } else if (mmio_dev->dri_feat_sel) {
- // clear high 32 bits
- mmio_dev->vqdev->dri_feat &= 0xffffffff;
- // write high 32 bits
- mmio_dev->vqdev->dri_feat |= ((uint64_t)(*value) << 32);
- } else {
- // clear low 32 bits
- mmio_dev->vqdev->dri_feat &= ((uint64_t)0xffffffff << 32);
- // write low 32 bits
- mmio_dev->vqdev->dri_feat |= *value;
- }
- break;
+ "The driver may only write powers of 2 to the QueueNum register.\n"
+ " See virtio-v1.0-cs04 s2.4 Virtqueues");
+ else
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Attempt to write value greater than QueueNumMax to QueueNum register.");
+ } else {
+ VIRTIO_DRI_WARNX(mmio_dev->vqdev,
+ "Attempt to write QueueNum register for invalid QueueSel. QueueSel was %u, but the number of queues is %u.",
+ mmio_dev->qsel, mmio_dev->vqdev->num_vqs);
+ }
+ break;
- // Activated (guest) features word selection
- case VIRTIO_MMIO_DRIVER_FEATURES_SEL:
- mmio_dev->dri_feat_sel = *value;
- break;
+ // Virtual queue ready bit
+ // Writing one (0x1) to this register notifies the device that it can
+ // execute requests from the virtual queue selected by QueueSel.
+ case VIRTIO_MMIO_QUEUE_READY:
+ if (mmio_dev->qsel < mmio_dev->vqdev->num_vqs) {
+ // NOTE: For now, anything that is not a toggle between
+ // 0x1 and 0x0 will bounce with no effect whatsoever.
+ if (mmio_dev->vqdev->vqs[mmio_dev->qsel].qready == 0x0
+ && *value == 0x1) {
+ // Driver is trying to write 0x1 QueueReady when
+ // the queue is currently disabled (QueueReady
+ // is 0x0). We validate the vring the driver
+ // provided, set up an eventfd for the queue,
+ // set qready on the queue to 0x1, and then
+ // launch the service thread for the queue.
- // Virtual queue index
- // Selects the virtual queue that QueueNumMax, QueueNum, QueueReady,
- // QueueDescLow, QueueDescHigh, QueueAvailLow, QueueAvailHigh,
- // QueueUsedLow and QueueUsedHigh apply to. The index number of the
- // first queue is zero (0x0).
- case VIRTIO_MMIO_QUEUE_SEL:
- // NOTE: We must allow the driver to write whatever they want to
- // QueueSel, because QueueNumMax contians 0x0 for invalid
- // QueueSel indices.
- mmio_dev->qsel = *value;
- break;
-
- // Virtual queue size
- // The queue size is the number of elements in the queue, thus in the
- // Descriptor Table, the Available Ring and the Used Ring. Writes
- // notify the device what size queue the driver will use.
- // This applies to the queue selected by writing to QueueSel.
- case VIRTIO_MMIO_QUEUE_NUM:
- if (mmio_dev->qsel < mmio_dev->vqdev->num_vqs) {
- // virtio-v1.0-cs04 4.2.2.2 MMIO Device Register Layout
- if (*value <= mmio_dev->vqdev->vqs[mmio_dev->qsel].qnum_max)
- mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.num = *value;
- else if ((*value != 0) && (*value & ((*value) - 1)))
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "The driver may only write powers of 2 to the QueueNum register.\n"
- " See virtio-v1.0-cs04 s2.4 Virtqueues");
- else
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Attempt to write value greater than QueueNumMax to QueueNum register.");
- } else {
- VIRTIO_DRI_WARNX(mmio_dev->vqdev,
- "Attempt to write QueueNum register for invalid QueueSel. QueueSel was %u, but the number of queues is %u.",
- mmio_dev->qsel, mmio_dev->vqdev->num_vqs);
- }
- break;
-
- // Virtual queue ready bit
- // Writing one (0x1) to this register notifies the device that it can
- // execute requests from the virtual queue selected by QueueSel.
- case VIRTIO_MMIO_QUEUE_READY:
- if (mmio_dev->qsel < mmio_dev->vqdev->num_vqs) {
- // NOTE: For now, anything that is not a toggle between
- // 0x1 and 0x0 will bounce with no effect whatsoever.
- if (mmio_dev->vqdev->vqs[mmio_dev->qsel].qready == 0x0
- && *value == 0x1) {
- // Driver is trying to write 0x1 QueueReady when the queue
- // is currently disabled (QueueReady is 0x0). We validate
- // the vring the driver provided, set up an eventfd for the
- // queue, set qready on the queue to 0x1, and then launch
- // the service thread for the queue.
-
- // Check that the host actually provided a service function
- if (!mmio_dev->vqdev->vqs[mmio_dev->qsel].srv_fn) {
- VIRTIO_DEV_ERRX(mmio_dev->vqdev,
- "The host must provide a service function for each queue on the device before the driver writes 0x1 to QueueReady. No service function found for queue %u."
- , mmio_dev->qsel);
- }
-
- virtio_check_vring(&mmio_dev->vqdev->vqs[mmio_dev->qsel]);
-
- mmio_dev->vqdev->vqs[mmio_dev->qsel].eventfd = eventfd(0, 0);
- mmio_dev->vqdev->vqs[mmio_dev->qsel].qready = 0x1;
-
- mmio_dev->vqdev->vqs[mmio_dev->qsel].srv_th =
- vmm_run_task(vm,
- mmio_dev->vqdev->vqs[mmio_dev->qsel].srv_fn,
- &mmio_dev->vqdev->vqs[mmio_dev->qsel]);
- if (!mmio_dev->vqdev->vqs[mmio_dev->qsel].srv_th) {
- VIRTIO_DEV_ERRX(mmio_dev->vqdev,
- "vm_run_task failed when trying to start service thread after driver wrote 0x1 to QueueReady.");
- }
- } else if (mmio_dev->vqdev->vqs[mmio_dev->qsel].qready == 0x1
- && *value == 0x0) {
- // Driver is trying to revoke QueueReady while the queue is
- // currently enabled (QueueReady is 0x1).
- // TODO: For now we are going to just make this an error.
- // In the future, when we actually decide how we want
- // to clean up the threads, the sequence might look
- // something like this:
- // 1. Ask the queue's service thread to exit and wait
- // for it to finish and exit.
- // 2. Once it has exited, close the queue's eventfd
- // and set both the eventfd and srv_th fields to 0.
- // 3. Finally, write 0x0 to QueueReady.
+ // Check that the host actually provided a
+ // service function
+ if (!mmio_dev->vqdev->vqs[mmio_dev->qsel].srv_fn) {
VIRTIO_DEV_ERRX(mmio_dev->vqdev,
- "Our (Akaros) MMIO device does not currently allow the driver to revoke QueueReady (i.e. change QueueReady from 0x1 to 0x0). The driver tried to revoke it, so whatever you are doing might require this ability.");
+ "The host must provide a service function for each queue on the device before the driver writes 0x1 to QueueReady. No service function found for queue %u."
+ , mmio_dev->qsel);
}
- } else {
- VIRTIO_DRI_WARNX(mmio_dev->vqdev,
- "Attempt to write QueueReady register for invalid QueueSel. QueueSel was %u, but the number of queues is %u.",
- mmio_dev->qsel, mmio_dev->vqdev->num_vqs);
- }
- break;
+ virtio_check_vring(
+ &mmio_dev->vqdev->vqs[mmio_dev->qsel]);
- // Queue notifier
- // Writing a queue index to this register notifies the device that
- // there are new buffers to process in that queue.
- case VIRTIO_MMIO_QUEUE_NOTIFY:
- if (!(mmio_dev->status & VIRTIO_CONFIG_S_DRIVER_OK))
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Attempt to notify the device before setting the DRIVER_OK status bit.\n"
- " See virtio-v1.0-cs04 s3.1.1 Device Initialization");
- else if (*value < mmio_dev->vqdev->num_vqs) {
- notified_queue = &mmio_dev->vqdev->vqs[*value];
+ mmio_dev->vqdev->vqs[mmio_dev->qsel].eventfd =
+ eventfd(0, 0);
+ mmio_dev->vqdev->vqs[mmio_dev->qsel].qready =
+ 0x1;
- // kick the queue's service thread
- if (notified_queue->eventfd > 0)
- eventfd_write(notified_queue->eventfd, 1);
- else
+ mmio_dev->vqdev->vqs[mmio_dev->qsel].srv_th =
+ vmm_run_task(vm,
+ mmio_dev->vqdev->vqs[mmio_dev->qsel].srv_fn,
+ &mmio_dev->vqdev->vqs[mmio_dev->qsel]);
+ if (!mmio_dev->vqdev->vqs[mmio_dev->qsel].srv_th) {
VIRTIO_DEV_ERRX(mmio_dev->vqdev,
- "You need to provide a valid eventfd on your virtio_vq so that it can be kicked when the driver writes to QueueNotify.");
- }
- break;
-
- // Interrupt acknowledge
- // Writing a value with bits set as defined in InterruptStatus to this
- // register notifies the device that events causing the interrupt have
- // been handled.
- case VIRTIO_MMIO_INTERRUPT_ACK:
- if (*value & ~0x3)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Attempt to set undefined bits in InterruptACK register.\n"
- " See virtio-v1.0-cs04 s4.2.2.1 MMIO Device Register Layout");
- mmio_dev->isr &= ~(*value);
- break;
-
- // Device status
- // Writing non-zero values to this register sets the status flags.
- // Writing zero (0x0) to this register triggers a device reset.
- case VIRTIO_MMIO_STATUS:
- if (*value == 0)
- virtio_mmio_reset(mmio_dev);
- else if (mmio_dev->status & ~(*value)) {
- // virtio-v1.0-cs04 s2.1.1. driver must NOT clear a status bit
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "The driver must not clear any device status bits, except as a result of resetting the device.\n"
- " See virtio-v1.0-cs04 s2.1.1 Device Status Field");
- } else if (mmio_dev->status & VIRTIO_CONFIG_S_FAILED
- && mmio_dev->status != *value) {
- // virtio-v1.0-cs04 s2.1.1. MUST reset before re-init if FAILED
- // NOTE: This fails if the driver tries to *change* the status
- // after the FAILED bit is set. The driver can set the
- // same status again all it wants.
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "The driver must reset the device after setting the FAILED status bit, before attempting to re-initialize the device.\n"
- " See virtio-v1.0-cs04 s2.1.1 Device Status Field");
- }
-
- // NOTE: If a bit is not set in value, then at this point it
- // CANNOT be set in status either, because if it were
- // set in status, we would have just crashed with an
- // error due to the attempt to clear a status bit.
-
- // Now we check that status bits are set in the correct
- // sequence during device initialization as described
- // in virtio-v1.0-cs04 s3.1.1 Device Initialization
-
- else if ((*value & VIRTIO_CONFIG_S_DRIVER)
- && !(*value & VIRTIO_CONFIG_S_ACKNOWLEDGE)) {
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Tried to set DRIVER status bit before setting ACKNOWLEDGE feature bit.\n"
- " See virtio-v1.0-cs04 s3.1.1 Device Initialization");
- } else if ((*value & VIRTIO_CONFIG_S_FEATURES_OK)
- && !((*value & VIRTIO_CONFIG_S_ACKNOWLEDGE)
- && (*value & VIRTIO_CONFIG_S_DRIVER))) {
- // All those parentheses... Lisp must be making a comeback.
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Tried to set FEATURES_OK status bit before setting both ACKNOWLEDGE and DRIVER status bits.\n"
- " See virtio-v1.0-cs04 s3.1.1 Device Initialization");
- } else if ((*value & VIRTIO_CONFIG_S_DRIVER_OK)
- && !((*value & VIRTIO_CONFIG_S_ACKNOWLEDGE)
- && (*value & VIRTIO_CONFIG_S_DRIVER)
- && (*value & VIRTIO_CONFIG_S_FEATURES_OK))) {
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Tried to set DRIVER_OK status bit before setting all of ACKNOWLEDGE, DRIVER, and FEATURES_OK status bits.\n"
- " See virtio-v1.0-cs04 s3.1.1 Device Initialization");
- }
-
- // NOTE: For now, we allow the driver to set all status bits up
- // through FEATURES_OK in one fell swoop. The driver is,
- // however, required to re-read FEATURES_OK after setting it
- // to be sure that the driver-activated features are a subset
- // of those supported by the device, so it must make an
- // additional write to set DRIVER_OK.
-
- else if ((*value & VIRTIO_CONFIG_S_DRIVER_OK)
- && !(mmio_dev->status & VIRTIO_CONFIG_S_FEATURES_OK)) {
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "The driver may not set FEATURES_OK and DRIVER_OK status bits simultaneously. It must read back FEATURES_OK after setting it to ensure that its activated features are supported by the device before setting DRIVER_OK.\n"
- " See virtio-v1.0-cs04 s3.1.1 Device Initialization");
- } else {
- // NOTE: Don't set the FEATURES_OK bit unless the driver
- // activated a valid subset of the supported features
- // prior to attempting to set FEATURES_OK.
- if (!(mmio_dev->status & VIRTIO_CONFIG_S_FEATURES_OK)
- && (*value & VIRTIO_CONFIG_S_FEATURES_OK)) {
-
- err = virtio_validate_feat(mmio_dev->vqdev,
- mmio_dev->vqdev->dri_feat);
-
- if ((mmio_dev->vqdev->dri_feat
- & ~mmio_dev->vqdev->dev_feat)) {
- VIRTIO_DRI_WARNX(mmio_dev->vqdev,
- "The driver did not accept (e.g. activate) a subset of the features offered by the device prior to attempting to set the FEATURES_OK status bit. The bit will remain unset.\n"
- " See virtio-v1.0-cs04 s3.1.1 Device Initialization");
- *value &= ~VIRTIO_CONFIG_S_FEATURES_OK;
- } else if (err) {
- VIRTIO_DRI_WARNX(mmio_dev->vqdev,
- "The driver did not accept (e.g. activate) a valid combination of the features offered by the device prior to attempting to set the FEATURES_OK status bit. The bit will remain unset.\n"
- " See virtio-v1.0-cs04 s3.1.1 Device Initialization\n"
- " Validation Error: %s", err);
- *value &= ~VIRTIO_CONFIG_S_FEATURES_OK;
- }
+ "vm_run_task failed when trying to start service thread after driver wrote 0x1 to QueueReady.");
}
- // Device status is only a byte wide.
- mmio_dev->status = *value & 0xff;
+ } else if (mmio_dev->vqdev->vqs[mmio_dev->qsel].qready == 0x1
+ && *value == 0x0) {
+ // Driver is trying to revoke QueueReady while
+ // the queue is currently enabled (QueueReady is
+ // 0x1).
+ // TODO: For now we are going to just make this
+ // an error. In the future, when we actually
+ // decide how we want to clean up the threads,
+ // the sequence might look something like this:
+ // 1. Ask the queue's service thread to
+ // exit and wait for it to finish and
+ // exit.
+ // 2. Once it has exited, close the
+ // queue's eventfd and set both the
+ // eventfd and srv_th fields to 0.
+ // 3. Finally, write 0x0 to QueueReady.
+ VIRTIO_DEV_ERRX(mmio_dev->vqdev,
+ "Our (Akaros) MMIO device does not currently allow the driver to revoke QueueReady (i.e. change QueueReady from 0x1 to 0x0). The driver tried to revoke it, so whatever you are doing might require this ability.");
}
- break;
- // Queue's Descriptor Table 64 bit long physical address, low 32
- case VIRTIO_MMIO_QUEUE_DESC_LOW:
- if (mmio_dev->qsel < mmio_dev->vqdev->num_vqs) {
- if (mmio_dev->vqdev->vqs[mmio_dev->qsel].qready != 0)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Attempt to access QueueDescLow on queue %d, which has nonzero QueueReady.\n"
- " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout"
- , mmio_dev->qsel);
+ } else {
+ VIRTIO_DRI_WARNX(mmio_dev->vqdev,
+ "Attempt to write QueueReady register for invalid QueueSel. QueueSel was %u, but the number of queues is %u.",
+ mmio_dev->qsel, mmio_dev->vqdev->num_vqs);
+ }
+ break;
- // clear low bits
- temp_ptr = (void *)
- ((uint64_t)mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.desc
- & ((uint64_t)0xffffffff << 32));
- // write low bits
- temp_ptr = (void *) ((uint64_t)temp_ptr | *value);
-
- // virtio-v1.0-cs04 s2.4 Virtqueues
- if ((uint64_t)temp_ptr % 16)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Physical address of guest's descriptor table (%p) is misaligned. Address should be a multiple of 16.\n"
- " See virtio-v1.0-cs04 s2.4 Virtqueues");
-
- // assign the new value to the queue desc
- mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.desc = temp_ptr;
- } else {
- VIRTIO_DRI_WARNX(mmio_dev->vqdev,
- "Attempt to write QueueDescLow register for invalid QueueSel. QueueSel was %u, but the number of queues is %u.",
- mmio_dev->qsel, mmio_dev->vqdev->num_vqs);
- }
- break;
-
- // Queue's Descriptor Table 64 bit long physical address, high 32
- case VIRTIO_MMIO_QUEUE_DESC_HIGH:
- if (mmio_dev->qsel < mmio_dev->vqdev->num_vqs) {
- if (mmio_dev->vqdev->vqs[mmio_dev->qsel].qready != 0)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Attempt to access QueueDescHigh on queue %d, which has nonzero QueueReady.\n"
- " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout"
- , mmio_dev->qsel);
-
- // clear high bits
- temp_ptr = (void *)
- ((uint64_t)mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.desc
- & ((uint64_t)0xffffffff));
- // write high bits
- temp_ptr = (void *) ((uint64_t)temp_ptr
- | ((uint64_t)(*value) << 32));
-
- // virtio-v1.0-cs04 s2.4 Virtqueues
- if ((uint64_t)temp_ptr % 16)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Physical address of guest's descriptor table (%p) is misaligned. Address should be a multiple of 16.\n"
- " See virtio-v1.0-cs04 s2.4 Virtqueues");
-
- // assign the new value to the queue desc
- mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.desc = temp_ptr;
- } else {
- VIRTIO_DRI_WARNX(mmio_dev->vqdev,
- "Attempt to write QueueDescHigh register for invalid QueueSel. QueueSel was %u, but the number of queues is %u."
- , mmio_dev->qsel, mmio_dev->vqdev->num_vqs);
- }
- break;
-
- // Queue's Available Ring 64 bit long physical address, low 32
- case VIRTIO_MMIO_QUEUE_AVAIL_LOW:
- if (mmio_dev->qsel < mmio_dev->vqdev->num_vqs) {
- if (mmio_dev->vqdev->vqs[mmio_dev->qsel].qready != 0)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Attempt to access QueueAvailLow on queue %d, which has nonzero QueueReady.\n"
- " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout"
- , mmio_dev->qsel);
-
- // clear low bits
- temp_ptr = (void *)
- ((uint64_t)mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.avail
- & ((uint64_t)0xffffffff << 32));
- // write low bits
- temp_ptr = (void *) ((uint64_t)temp_ptr | *value);
-
- // virtio-v1.0-cs04 s2.4 Virtqueues
- if ((uint64_t)temp_ptr % 2)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Physical address of guest's available ring (%p) is misaligned. Address should be a multiple of 2.\n"
- " See virtio-v1.0-cs04 s2.4 Virtqueues");
-
- // assign the new value to the queue avail
- mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.avail = temp_ptr;
- } else {
- VIRTIO_DRI_WARNX(mmio_dev->vqdev,
- "Attempt to write QueueAvailLow register for invalid QueueSel. QueueSel was %u, but the number of queues is %u."
- , mmio_dev->qsel, mmio_dev->vqdev->num_vqs);
- }
- break;
-
- // Queue's Available Ring 64 bit long physical address, high 32
- case VIRTIO_MMIO_QUEUE_AVAIL_HIGH:
- if (mmio_dev->qsel < mmio_dev->vqdev->num_vqs) {
- if (mmio_dev->vqdev->vqs[mmio_dev->qsel].qready != 0)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Attempt to access QueueAvailHigh on queue %d, which has nonzero QueueReady.\n"
- " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout"
- , mmio_dev->qsel);
-
- // clear high bits
- temp_ptr = (void *)
- ((uint64_t)mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.avail
- & ((uint64_t)0xffffffff));
- // write high bits
- temp_ptr = (void *) ((uint64_t)temp_ptr
- | ((uint64_t)(*value) << 32));
-
- // virtio-v1.0-cs04 s2.4 Virtqueues
- if ((uint64_t)temp_ptr % 2)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Physical address of guest's available ring (%p) is misaligned. Address should be a multiple of 2.\n"
- " See virtio-v1.0-cs04 s2.4 Virtqueues");
-
- // assign the new value to the queue avail
- mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.avail = temp_ptr;
- } else {
- VIRTIO_DRI_WARNX(mmio_dev->vqdev,
- "Attempt to write QueueAvailHigh register for invalid QueueSel. QueueSel was %u, but the number of queues is %u."
- , mmio_dev->qsel, mmio_dev->vqdev->num_vqs);
- }
- break;
-
- // Queue's Used Ring 64 bit long physical address, low 32
- case VIRTIO_MMIO_QUEUE_USED_LOW:
- if (mmio_dev->qsel < mmio_dev->vqdev->num_vqs) {
- if (mmio_dev->vqdev->vqs[mmio_dev->qsel].qready != 0)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Attempt to access QueueUsedLow on queue %d, which has nonzero QueueReady.\n"
- " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout"
- , mmio_dev->qsel);
-
- // clear low bits
- temp_ptr = (void *)
- ((uint64_t)mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.used
- & ((uint64_t)0xffffffff << 32));
- // write low bits
- temp_ptr = (void *) ((uint64_t)temp_ptr | *value);
-
- // virtio-v1.0-cs04 s2.4 Virtqueues
- if ((uint64_t)temp_ptr % 4)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Physical address of guest's used ring (%p) is misaligned. Address should be a multiple of 4.\n"
- " See virtio-v1.0-cs04 s2.4 Virtqueues");
-
- // assign the new value to the queue used
- mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.used = temp_ptr;
- } else {
- VIRTIO_DRI_WARNX(mmio_dev->vqdev,
- "Attempt to write QueueUsedLow register for invalid QueueSel. QueueSel was %u, but the number of queues is %u."
- , mmio_dev->qsel, mmio_dev->vqdev->num_vqs);
- }
- break;
-
- // Queue's Used Ring 64 bit long physical address, high 32
- case VIRTIO_MMIO_QUEUE_USED_HIGH:
- if (mmio_dev->qsel < mmio_dev->vqdev->num_vqs) {
- if (mmio_dev->vqdev->vqs[mmio_dev->qsel].qready != 0)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Attempt to access QueueUsedHigh on queue %d, which has nonzero QueueReady.\n"
- " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout"
- , mmio_dev->qsel);
-
- // clear high bits
- temp_ptr = (void *)
- ((uint64_t)mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.used
- & ((uint64_t)0xffffffff));
- // write high bits
- temp_ptr = (void *) ((uint64_t)temp_ptr
- | ((uint64_t)(*value) << 32));
-
- // virtio-v1.0-cs04 s2.4 Virtqueues
- if ((uint64_t)temp_ptr % 4)
- VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Physical address of guest's used ring (%p) is misaligned. Address should be a multiple of 4.\n"
- " See virtio-v1.0-cs04 s2.4 Virtqueues");
-
- // assign the new value to the queue used
- mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.used = temp_ptr;
- } else {
- VIRTIO_DRI_WARNX(mmio_dev->vqdev,
- "Attempt to write QueueUsedHigh register for invalid QueueSel. QueueSel was %u, but the number of queues is %u."
- , mmio_dev->qsel, mmio_dev->vqdev->num_vqs);
- }
- break;
-
- // Read-only register offsets:
- case VIRTIO_MMIO_MAGIC_VALUE:
- case VIRTIO_MMIO_VERSION:
- case VIRTIO_MMIO_DEVICE_ID:
- case VIRTIO_MMIO_VENDOR_ID:
- case VIRTIO_MMIO_DEVICE_FEATURES:
- case VIRTIO_MMIO_QUEUE_NUM_MAX:
- case VIRTIO_MMIO_INTERRUPT_STATUS:
- case VIRTIO_MMIO_CONFIG_GENERATION:
- // Write to read-only register
+ // Queue notifier
+ // Writing a queue index to this register notifies the device that
+ // there are new buffers to process in that queue.
+ case VIRTIO_MMIO_QUEUE_NOTIFY:
+ if (!(mmio_dev->status & VIRTIO_CONFIG_S_DRIVER_OK))
VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Attempt to write read-only device register offset 0x%x.",
- offset);
- break;
- default:
- // Bad register offset
+ "Attempt to notify the device before setting the DRIVER_OK status bit.\n"
+ " See virtio-v1.0-cs04 s3.1.1 Device Initialization");
+ else if (*value < mmio_dev->vqdev->num_vqs) {
+ notified_queue = &mmio_dev->vqdev->vqs[*value];
+
+ // kick the queue's service thread
+ if (notified_queue->eventfd > 0)
+ eventfd_write(notified_queue->eventfd, 1);
+ else
+ VIRTIO_DEV_ERRX(mmio_dev->vqdev,
+ "You need to provide a valid eventfd on your virtio_vq so that it can be kicked when the driver writes to QueueNotify.");
+ }
+ break;
+
+ // Interrupt acknowledge
+ // Writing a value with bits set as defined in InterruptStatus to this
+ // register notifies the device that events causing the interrupt have
+ // been handled.
+ case VIRTIO_MMIO_INTERRUPT_ACK:
+ if (*value & ~0x3)
VIRTIO_DRI_ERRX(mmio_dev->vqdev,
- "Attempt to write invalid device register offset 0x%x.",
- offset);
- break;
+ "Attempt to set undefined bits in InterruptACK register.\n"
+ " See virtio-v1.0-cs04 s4.2.2.1 MMIO Device Register Layout");
+ mmio_dev->isr &= ~(*value);
+ break;
+
+ // Device status
+ // Writing non-zero values to this register sets the status flags.
+ // Writing zero (0x0) to this register triggers a device reset.
+ case VIRTIO_MMIO_STATUS:
+ if (*value == 0)
+ virtio_mmio_reset(mmio_dev);
+ else if (mmio_dev->status & ~(*value)) {
+ // virtio-v1.0-cs04 s2.1.1. driver must NOT clear a
+ // status bit
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "The driver must not clear any device status bits, except as a result of resetting the device.\n"
+ " See virtio-v1.0-cs04 s2.1.1 Device Status Field");
+ } else if (mmio_dev->status & VIRTIO_CONFIG_S_FAILED
+ && mmio_dev->status != *value) {
+ // virtio-v1.0-cs04 s2.1.1. MUST reset before re-init if
+ // FAILED
+ // NOTE: This fails if the driver tries to *change* the
+ // status after the FAILED bit is set. The driver can
+ // set the same status again all it wants.
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "The driver must reset the device after setting the FAILED status bit, before attempting to re-initialize the device.\n"
+ " See virtio-v1.0-cs04 s2.1.1 Device Status Field");
+ }
+
+ // NOTE: If a bit is not set in value, then at this point it
+ // CANNOT be set in status either, because if it were
+ // set in status, we would have just crashed with an
+ // error due to the attempt to clear a status bit.
+
+ // Now we check that status bits are set in the correct
+ // sequence during device initialization as described
+ // in virtio-v1.0-cs04 s3.1.1 Device Initialization
+
+ else if ((*value & VIRTIO_CONFIG_S_DRIVER)
+ && !(*value & VIRTIO_CONFIG_S_ACKNOWLEDGE)) {
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Tried to set DRIVER status bit before setting ACKNOWLEDGE feature bit.\n"
+ " See virtio-v1.0-cs04 s3.1.1 Device Initialization");
+ } else if ((*value & VIRTIO_CONFIG_S_FEATURES_OK)
+ && !((*value & VIRTIO_CONFIG_S_ACKNOWLEDGE)
+ && (*value & VIRTIO_CONFIG_S_DRIVER))) {
+ // All those parentheses... Lisp must be making a
+ // comeback.
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Tried to set FEATURES_OK status bit before setting both ACKNOWLEDGE and DRIVER status bits.\n"
+ " See virtio-v1.0-cs04 s3.1.1 Device Initialization");
+ } else if ((*value & VIRTIO_CONFIG_S_DRIVER_OK)
+ && !((*value & VIRTIO_CONFIG_S_ACKNOWLEDGE)
+ && (*value & VIRTIO_CONFIG_S_DRIVER)
+ && (*value & VIRTIO_CONFIG_S_FEATURES_OK))) {
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Tried to set DRIVER_OK status bit before setting all of ACKNOWLEDGE, DRIVER, and FEATURES_OK status bits.\n"
+ " See virtio-v1.0-cs04 s3.1.1 Device Initialization");
+ }
+
+ // NOTE: For now, we allow the driver to set all status bits up
+ // through FEATURES_OK in one fell swoop. The driver is,
+ // however, required to re-read FEATURES_OK after setting
+ // it to be sure that the driver-activated features are a
+ // subset of those supported by the device, so it must
+ // make an additional write to set DRIVER_OK.
+
+ else if ((*value & VIRTIO_CONFIG_S_DRIVER_OK)
+ && !(mmio_dev->status & VIRTIO_CONFIG_S_FEATURES_OK)) {
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "The driver may not set FEATURES_OK and DRIVER_OK status bits simultaneously. It must read back FEATURES_OK after setting it to ensure that its activated features are supported by the device before setting DRIVER_OK.\n"
+ " See virtio-v1.0-cs04 s3.1.1 Device Initialization");
+ } else {
+ // NOTE: Don't set the FEATURES_OK bit unless the driver
+ // activated a valid subset of the supported
+ // features prior to attempting to set
+ // FEATURES_OK.
+ if (!(mmio_dev->status & VIRTIO_CONFIG_S_FEATURES_OK)
+ && (*value & VIRTIO_CONFIG_S_FEATURES_OK)) {
+
+ err = virtio_validate_feat(mmio_dev->vqdev,
+ mmio_dev->vqdev->dri_feat);
+
+ if ((mmio_dev->vqdev->dri_feat
+ & ~mmio_dev->vqdev->dev_feat)) {
+ VIRTIO_DRI_WARNX(mmio_dev->vqdev,
+ "The driver did not accept (e.g. activate) a subset of the features offered by the device prior to attempting to set the FEATURES_OK status bit. The bit will remain unset.\n"
+ " See virtio-v1.0-cs04 s3.1.1 Device Initialization");
+ *value &= ~VIRTIO_CONFIG_S_FEATURES_OK;
+ } else if (err) {
+ VIRTIO_DRI_WARNX(mmio_dev->vqdev,
+ "The driver did not accept (e.g. activate) a valid combination of the features offered by the device prior to attempting to set the FEATURES_OK status bit. The bit will remain unset.\n"
+ " See virtio-v1.0-cs04 s3.1.1 Device Initialization\n"
+ " Validation Error: %s", err);
+ *value &= ~VIRTIO_CONFIG_S_FEATURES_OK;
+ }
+ }
+ // Device status is only a byte wide.
+ mmio_dev->status = *value & 0xff;
+ }
+ break;
+
+ // Queue's Descriptor Table 64 bit long physical address, low 32
+ case VIRTIO_MMIO_QUEUE_DESC_LOW:
+ if (mmio_dev->qsel < mmio_dev->vqdev->num_vqs) {
+ if (mmio_dev->vqdev->vqs[mmio_dev->qsel].qready != 0)
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Attempt to access QueueDescLow on queue %d, which has nonzero QueueReady.\n"
+ " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout"
+ , mmio_dev->qsel);
+
+ // clear low bits
+ temp_ptr = (void *)
+ ((uint64_t)mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.desc
+ & ((uint64_t)0xffffffff << 32));
+ // write low bits
+ temp_ptr = (void *) ((uint64_t)temp_ptr | *value);
+
+ // virtio-v1.0-cs04 s2.4 Virtqueues
+ if ((uint64_t)temp_ptr % 16)
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Physical address of guest's descriptor table (%p) is misaligned. Address should be a multiple of 16.\n"
+ " See virtio-v1.0-cs04 s2.4 Virtqueues");
+
+ // assign the new value to the queue desc
+ mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.desc =
+ temp_ptr;
+ } else {
+ VIRTIO_DRI_WARNX(mmio_dev->vqdev,
+ "Attempt to write QueueDescLow register for invalid QueueSel. QueueSel was %u, but the number of queues is %u.",
+ mmio_dev->qsel, mmio_dev->vqdev->num_vqs);
+ }
+ break;
+
+ // Queue's Descriptor Table 64 bit long physical address, high 32
+ case VIRTIO_MMIO_QUEUE_DESC_HIGH:
+ if (mmio_dev->qsel < mmio_dev->vqdev->num_vqs) {
+ if (mmio_dev->vqdev->vqs[mmio_dev->qsel].qready != 0)
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Attempt to access QueueDescHigh on queue %d, which has nonzero QueueReady.\n"
+ " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout"
+ , mmio_dev->qsel);
+
+ // clear high bits
+ temp_ptr = (void *)
+ ((uint64_t)mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.desc
+ & ((uint64_t)0xffffffff));
+ // write high bits
+ temp_ptr = (void *) ((uint64_t)temp_ptr
+ | ((uint64_t)(*value) << 32));
+
+ // virtio-v1.0-cs04 s2.4 Virtqueues
+ if ((uint64_t)temp_ptr % 16)
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Physical address of guest's descriptor table (%p) is misaligned. Address should be a multiple of 16.\n"
+ " See virtio-v1.0-cs04 s2.4 Virtqueues");
+
+ // assign the new value to the queue desc
+ mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.desc = temp_ptr;
+ } else {
+ VIRTIO_DRI_WARNX(mmio_dev->vqdev,
+ "Attempt to write QueueDescHigh register for invalid QueueSel. QueueSel was %u, but the number of queues is %u."
+ , mmio_dev->qsel, mmio_dev->vqdev->num_vqs);
+ }
+ break;
+
+ // Queue's Available Ring 64 bit long physical address, low 32
+ case VIRTIO_MMIO_QUEUE_AVAIL_LOW:
+ if (mmio_dev->qsel < mmio_dev->vqdev->num_vqs) {
+ if (mmio_dev->vqdev->vqs[mmio_dev->qsel].qready != 0)
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Attempt to access QueueAvailLow on queue %d, which has nonzero QueueReady.\n"
+ " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout"
+ , mmio_dev->qsel);
+
+ // clear low bits
+ temp_ptr = (void *)
+ ((uint64_t)mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.avail
+ & ((uint64_t)0xffffffff << 32));
+ // write low bits
+ temp_ptr = (void *) ((uint64_t)temp_ptr | *value);
+
+ // virtio-v1.0-cs04 s2.4 Virtqueues
+ if ((uint64_t)temp_ptr % 2)
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Physical address of guest's available ring (%p) is misaligned. Address should be a multiple of 2.\n"
+ " See virtio-v1.0-cs04 s2.4 Virtqueues");
+
+ // assign the new value to the queue avail
+ mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.avail = temp_ptr;
+ } else {
+ VIRTIO_DRI_WARNX(mmio_dev->vqdev,
+ "Attempt to write QueueAvailLow register for invalid QueueSel. QueueSel was %u, but the number of queues is %u."
+ , mmio_dev->qsel, mmio_dev->vqdev->num_vqs);
+ }
+ break;
+
+ // Queue's Available Ring 64 bit long physical address, high 32
+ case VIRTIO_MMIO_QUEUE_AVAIL_HIGH:
+ if (mmio_dev->qsel < mmio_dev->vqdev->num_vqs) {
+ if (mmio_dev->vqdev->vqs[mmio_dev->qsel].qready != 0)
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Attempt to access QueueAvailHigh on queue %d, which has nonzero QueueReady.\n"
+ " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout"
+ , mmio_dev->qsel);
+
+ // clear high bits
+ temp_ptr = (void *)
+ ((uint64_t)mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.avail
+ & ((uint64_t)0xffffffff));
+ // write high bits
+ temp_ptr = (void *) ((uint64_t)temp_ptr
+ | ((uint64_t)(*value) << 32));
+
+ // virtio-v1.0-cs04 s2.4 Virtqueues
+ if ((uint64_t)temp_ptr % 2)
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Physical address of guest's available ring (%p) is misaligned. Address should be a multiple of 2.\n"
+ " See virtio-v1.0-cs04 s2.4 Virtqueues");
+
+ // assign the new value to the queue avail
+ mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.avail = temp_ptr;
+ } else {
+ VIRTIO_DRI_WARNX(mmio_dev->vqdev,
+ "Attempt to write QueueAvailHigh register for invalid QueueSel. QueueSel was %u, but the number of queues is %u."
+ , mmio_dev->qsel, mmio_dev->vqdev->num_vqs);
+ }
+ break;
+
+ // Queue's Used Ring 64 bit long physical address, low 32
+ case VIRTIO_MMIO_QUEUE_USED_LOW:
+ if (mmio_dev->qsel < mmio_dev->vqdev->num_vqs) {
+ if (mmio_dev->vqdev->vqs[mmio_dev->qsel].qready != 0)
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Attempt to access QueueUsedLow on queue %d, which has nonzero QueueReady.\n"
+ " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout"
+ , mmio_dev->qsel);
+
+ // clear low bits
+ temp_ptr = (void *)
+ ((uint64_t)mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.used
+ & ((uint64_t)0xffffffff << 32));
+ // write low bits
+ temp_ptr = (void *) ((uint64_t)temp_ptr | *value);
+
+ // virtio-v1.0-cs04 s2.4 Virtqueues
+ if ((uint64_t)temp_ptr % 4)
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Physical address of guest's used ring (%p) is misaligned. Address should be a multiple of 4.\n"
+ " See virtio-v1.0-cs04 s2.4 Virtqueues");
+
+ // assign the new value to the queue used
+ mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.used = temp_ptr;
+ } else {
+ VIRTIO_DRI_WARNX(mmio_dev->vqdev,
+ "Attempt to write QueueUsedLow register for invalid QueueSel. QueueSel was %u, but the number of queues is %u."
+ , mmio_dev->qsel, mmio_dev->vqdev->num_vqs);
+ }
+ break;
+
+ // Queue's Used Ring 64 bit long physical address, high 32
+ case VIRTIO_MMIO_QUEUE_USED_HIGH:
+ if (mmio_dev->qsel < mmio_dev->vqdev->num_vqs) {
+ if (mmio_dev->vqdev->vqs[mmio_dev->qsel].qready != 0)
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Attempt to access QueueUsedHigh on queue %d, which has nonzero QueueReady.\n"
+ " See virtio-v1.0-cs04 s4.2.2.2 MMIO Device Register Layout"
+ , mmio_dev->qsel);
+
+ // clear high bits
+ temp_ptr = (void *)
+ ((uint64_t)mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.used
+ & ((uint64_t)0xffffffff));
+ // write high bits
+ temp_ptr = (void *) ((uint64_t)temp_ptr
+ | ((uint64_t)(*value) << 32));
+
+ // virtio-v1.0-cs04 s2.4 Virtqueues
+ if ((uint64_t)temp_ptr % 4)
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Physical address of guest's used ring (%p) is misaligned. Address should be a multiple of 4.\n"
+ " See virtio-v1.0-cs04 s2.4 Virtqueues");
+
+ // assign the new value to the queue used
+ mmio_dev->vqdev->vqs[mmio_dev->qsel].vring.used = temp_ptr;
+ } else {
+ VIRTIO_DRI_WARNX(mmio_dev->vqdev,
+ "Attempt to write QueueUsedHigh register for invalid QueueSel. QueueSel was %u, but the number of queues is %u."
+ , mmio_dev->qsel, mmio_dev->vqdev->num_vqs);
+ }
+ break;
+
+ // Read-only register offsets:
+ case VIRTIO_MMIO_MAGIC_VALUE:
+ case VIRTIO_MMIO_VERSION:
+ case VIRTIO_MMIO_DEVICE_ID:
+ case VIRTIO_MMIO_VENDOR_ID:
+ case VIRTIO_MMIO_DEVICE_FEATURES:
+ case VIRTIO_MMIO_QUEUE_NUM_MAX:
+ case VIRTIO_MMIO_INTERRUPT_STATUS:
+ case VIRTIO_MMIO_CONFIG_GENERATION:
+ // Write to read-only register
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Attempt to write read-only device register offset 0x%x.",
+ offset);
+ break;
+ default:
+ // Bad register offset
+ VIRTIO_DRI_ERRX(mmio_dev->vqdev,
+ "Attempt to write invalid device register offset 0x%x.",
+ offset);
+ break;
}
}
diff --git a/user/vmm/virtio_net.c b/user/vmm/virtio_net.c
index 9c617cc..96ef5e6 100644
--- a/user/vmm/virtio_net.c
+++ b/user/vmm/virtio_net.c
@@ -89,9 +89,9 @@
" See virtio-v1.0-cs04 s5.3.6.1 Device Operation");
}
- /* The virtio_net header comes first. We'll assume they didn't break
- * the header across IOVs, but earlier versions of Linux did break out
- * the payload into the second IOV. */
+ /* The virtio_net header comes first. We'll assume they didn't
+ * break the header across IOVs, but earlier versions of Linux
+ * did break out the payload into the second IOV. */
net_header = iov[0].iov_base;
assert(iov[0].iov_len >= VIRTIO_HEADER_SIZE);
iov_strip_bytes(iov, ilen, VIRTIO_HEADER_SIZE);
@@ -103,8 +103,8 @@
"Encountered an error trying to read input from the ethernet device.");
}
- /* See virtio spec virtio-v1.0-cs04 s5.1.6.3.2 Device Requirements:
- * Setting Up Receive Buffers
+ /* See virtio spec virtio-v1.0-cs04 s5.1.6.3.2 Device
+ * Requirements: Setting Up Receive Buffers
*
* VIRTIO_NET_F_MRG_RXBUF is not currently negotiated.
* num_buffers will always be 1 if VIRTIO_NET_F_MRG_RXBUF is not
@@ -139,7 +139,7 @@
if (!dev->poke_guest) {
free(iov);
VIRTIO_DEV_ERRX(vq->vqdev,
- "The 'poke_guest' function pointer was not set.");
+ "The 'poke_guest' function pointer was not set.");
}
for (;;) {
diff --git a/user/vmm/vmexit.c b/user/vmm/vmexit.c
index 3517ebc..22832f9 100644
--- a/user/vmm/vmexit.c
+++ b/user/vmm/vmexit.c
@@ -14,7 +14,8 @@
static bool pir_notif_is_set(struct vmm_gpcore_init *gpci)
{
- return GET_BITMASK_BIT(gpci->posted_irq_desc, VMX_POSTED_OUTSTANDING_NOTIF);
+ return GET_BITMASK_BIT(gpci->posted_irq_desc,
+ VMX_POSTED_OUTSTANDING_NOTIF);
}
/* Returns true if the hardware will trigger an IRQ for the guest. These
@@ -25,9 +26,9 @@
struct vmm_gpcore_init *gpci = gth_to_gpci(gth);
uint8_t rvi, vppr;
- /* Currently, the lower 4 bits are various ways to block IRQs, e.g. blocking
- * by STI. The other bits are must be 0. Presumably any new bits are types
- * of IRQ blocking. */
+ /* Currently, the lower 4 bits are various ways to block IRQs, e.g.
+ * blocking by STI. The other bits are must be 0. Presumably any new
+ * bits are types of IRQ blocking. */
if (gth_to_vmtf(gth)->tf_intrinfo1)
return false;
vppr = read_mmreg32((uintptr_t)gth_to_gpci(gth)->vapic_addr + 0xa0);
@@ -41,31 +42,32 @@
{
struct vmm_gpcore_init *gpci = gth_to_gpci(gth);
- /* The invariant is that if an IRQ is posted, but not delivered, we will not
- * sleep. Anyone who posts an IRQ must signal after setting it.
+ /* The invariant is that if an IRQ is posted, but not delivered, we will
+ * not sleep. Anyone who posts an IRQ must signal after setting it.
* vmm_interrupt_guest() does this. If we use alternate sources of IRQ
- * posting, we'll need to revist this. For more details, see the notes in
- * the kernel IPI-IRC fast path.
+ * posting, we'll need to revist this. For more details, see the notes
+ * in the kernel IPI-IRC fast path.
*
* Although vmm_interrupt_guest() only writes OUTSTANDING_NOTIF, it's
* possible that the hardware attempted to post the interrupt. In SDM
- * parlance, the processor could have "recognized" the virtual IRQ, but not
- * delivered it yet. This could happen if the guest had executed "sti", but
- * not "hlt" yet. The IRQ was posted and recognized, but not delivered
- * ("sti blocking"). Then the guest executes "hlt", and vmexits.
- * OUTSTANDING_NOTIF will be clear in this case. RVI should be set - at
- * least to the vector we just sent, but possibly to a greater vector if
- * multiple were sent. RVI should only be cleared after virtual IRQs were
- * actually delivered. So checking OUTSTANDING_NOTIF and RVI should
- * suffice.
+ * parlance, the processor could have "recognized" the virtual IRQ, but
+ * not delivered it yet. This could happen if the guest had executed
+ * "sti", but not "hlt" yet. The IRQ was posted and recognized, but not
+ * delivered ("sti blocking"). Then the guest executes "hlt", and
+ * vmexits. OUTSTANDING_NOTIF will be clear in this case. RVI should
+ * be set - at least to the vector we just sent, but possibly to a
+ * greater vector if multiple were sent. RVI should only be cleared
+ * after virtual IRQs were actually delivered. So checking
+ * OUTSTANDING_NOTIF and RVI should suffice.
*
- * Note that when we see a notif or pending virtual IRQ, we don't actually
- * deliver the IRQ, we'll just restart the guest and the hardware will
- * deliver the virtual IRQ at the appropriate time.
+ * Note that when we see a notif or pending virtual IRQ, we don't
+ * actually deliver the IRQ, we'll just restart the guest and the
+ * hardware will deliver the virtual IRQ at the appropriate time.
*
- * The more traditional race here is if the halt starts concurrently with
- * the post; that's why we sync with the mutex to make sure there is an
- * ordering between the actual halt (this function) and the posting. */
+ * The more traditional race here is if the halt starts concurrently
+ * with the post; that's why we sync with the mutex to make sure there
+ * is an ordering between the actual halt (this function) and the
+ * posting. */
uth_mutex_lock(gth->halt_mtx);
while (!(pir_notif_is_set(gpci) || virtual_irq_is_pending(gth)))
uth_cond_var_wait(gth->halt_cv, gth->halt_mtx);
@@ -73,8 +75,8 @@
}
enum {
- CPUID_0B_LEVEL_SMT = 0,
- CPUID_0B_LEVEL_CORE
+ CPUID_0B_LEVEL_SMT = 0,
+ CPUID_0B_LEVEL_CORE
};
static bool handle_cpuid(struct guest_thread *gth)
@@ -120,7 +122,8 @@
int ret;
if (vm_tf->tf_flags & VMCTX_FL_EPT_VMR_BACKED) {
- ret = ros_syscall(SYS_populate_va, vm_tf->tf_guest_pa, 1, 0, 0, 0, 0);
+ ret = ros_syscall(SYS_populate_va, vm_tf->tf_guest_pa, 1, 0, 0,
+ 0, 0);
if (ret <= 0)
panic("[user] handle_ept_fault: populate_va failed: ret = %d\n",
ret);
@@ -140,19 +143,21 @@
}
assert(size >= 0);
- /* TODO use helpers for some of these addr checks. the fee/fec ones might
- * be wrong too. */
+ /* TODO use helpers for some of these addr checks. the fee/fec ones
+ * might be wrong too. */
for (int i = 0; i < VIRTIO_MMIO_MAX_NUM_DEV; i++) {
if (vm->virtio_mmio_devices[i] == NULL)
continue;
if (PG_ADDR(gpa) != vm->virtio_mmio_devices[i]->addr)
continue;
- /* TODO: can the guest cause us to spawn off infinite threads? */
+ /* TODO: can the guest cause us to spawn off infinite threads?
+ */
if (store)
- virtio_mmio_wr(vm, vm->virtio_mmio_devices[i], gpa, size,
- (uint32_t *)regp);
+ virtio_mmio_wr(vm, vm->virtio_mmio_devices[i], gpa,
+ size, (uint32_t *)regp);
else
- *regp = virtio_mmio_rd(vm, vm->virtio_mmio_devices[i], gpa, size);
+ *regp = virtio_mmio_rd(vm, vm->virtio_mmio_devices[i],
+ gpa, size);
vm_tf->tf_rip += advance;
return TRUE;
}
@@ -194,7 +199,8 @@
struct virtual_machine *vm = gth_to_vm(gth);
int cur_pcores = vm->up_gpcs;
- /* Check if we're guest pcore 0. Only the BSP is allowed to start APs. */
+ /* Check if we're guest pcore 0. Only the BSP is allowed to start APs.
+ */
if (vm_tf->tf_guest_pcoreid != 0) {
fprintf(stderr,
"Only guest pcore 0 is allowed to start APs. core was %ld\n",
@@ -286,7 +292,8 @@
trace_printf("ExitQl 0x%08x\n", vm_tf->tf_exit_qual);
trace_printf("Intr1 0x%016lx\n", vm_tf->tf_intrinfo1);
trace_printf("Intr2 0x%016lx\n", vm_tf->tf_intrinfo2);
- trace_printf("GIntr 0x----%04x\n", vm_tf->tf_guest_intr_status);
+ trace_printf("GIntr 0x----%04x\n",
+ vm_tf->tf_guest_intr_status);
trace_printf("GVA 0x%016lx\n", vm_tf->tf_guest_va);
trace_printf("GPA 0x%016lx\n", vm_tf->tf_guest_pa);
retval = true;
@@ -321,9 +328,9 @@
struct vm_trapframe *vm_tf = gth_to_vmtf(gth);
if (msrio(gth, gth_to_gpci(gth), vm_tf->tf_exit_reason)) {
- /* Use event injection through vmctl to send a general protection fault
- * vmctl.interrupt gets written to the VM-Entry Interruption-Information
- * Field by vmx */
+ /* Use event injection through vmctl to send a general
+ * protection fault vmctl.interrupt gets written to the VM-Entry
+ * Interruption-Information Field by vmx */
vm_tf->tf_trap_inject = VM_TRAP_VALID
| VM_TRAP_ERROR_CODE
| VM_TRAP_HARDWARE
@@ -357,8 +364,9 @@
if (vm->halt_exit)
return FALSE;
- /* It's possible the guest disabled IRQs and halted, perhaps waiting on an
- * NMI or something. If we need to support that, we can change this. */
+ /* It's possible the guest disabled IRQs and halted, perhaps waiting on
+ * an NMI or something. If we need to support that, we can change this.
+ */
sleep_til_irq(gth);
vm_tf->tf_rip += 1;
return TRUE;
@@ -410,7 +418,8 @@
/* TODO: just ignore these? */
return TRUE;
default:
- fprintf(stderr, "VMM library: don't know how to handle exit %d\n",
+ fprintf(stderr,
+ "VMM library: don't know how to handle exit %d\n",
vm_tf->tf_exit_reason);
fprintf(stderr, "RIP %p, shutdown 0x%x\n", vm_tf->tf_rip,
vm_tf->tf_exit_reason);
diff --git a/user/vmm/vmm.c b/user/vmm/vmm.c
index 0af8b69..0a3a1d3 100644
--- a/user/vmm/vmm.c
+++ b/user/vmm/vmm.c
@@ -32,16 +32,17 @@
VMX_POSTED_OUTSTANDING_NOTIF - 1);
return -1;
}
- /* Syncing with halting guest threads. The Mutex protects changes to the
- * posted irq descriptor. */
+ /* Syncing with halting guest threads. The Mutex protects changes to
+ * the posted irq descriptor. */
uth_mutex_lock(gth->halt_mtx);
SET_BITMASK_BIT_ATOMIC(gpci->posted_irq_desc, vector);
/* Atomic op provides the mb() btw writing the vector and mucking with
* OUTSTANDING_NOTIF.
*
- * If we set notif, it's on us to inject the IRQ. Either way, notif will be
- * set and we must kick the CV, unconditionally. */
- if (!GET_BITMASK_BIT(gpci->posted_irq_desc, VMX_POSTED_OUTSTANDING_NOTIF)) {
+ * If we set notif, it's on us to inject the IRQ. Either way, notif
+ * will be set and we must kick the CV, unconditionally. */
+ if (!GET_BITMASK_BIT(gpci->posted_irq_desc,
+ VMX_POSTED_OUTSTANDING_NOTIF)) {
SET_BITMASK_BIT_ATOMIC(gpci->posted_irq_desc,
VMX_POSTED_OUTSTANDING_NOTIF);
ros_syscall(SYS_vmm_poke_guest, gpcoreid, 0, 0, 0, 0, 0);
diff --git a/user/vmm/vmx.c b/user/vmm/vmx.c
index f3f285b..75c602d 100644
--- a/user/vmm/vmx.c
+++ b/user/vmm/vmx.c
@@ -31,9 +31,11 @@
{
struct vm_trapframe *vm_tf = gth_to_vmtf(vm_thread);
int shutdown = vm_tf->tf_exit_reason;
- char *when = shutdown & VMX_EXIT_REASONS_FAILED_VMENTRY ? "entry" : "exit";
- shutdown &= ~VMX_EXIT_REASONS_FAILED_VMENTRY;
+ char *when = shutdown & VMX_EXIT_REASONS_FAILED_VMENTRY ? "entry"
+ : "exit";
char *reason = "UNKNOWN";
+
+ shutdown &= ~VMX_EXIT_REASONS_FAILED_VMENTRY;
if (shutdown < COUNT_OF(vmxexit) && vmxexit[shutdown])
reason = vmxexit[shutdown];
fprintf(f, "Shutdown: core %d, %s due to %s(0x%x); ret code 0x%x\n",
@@ -51,7 +53,9 @@
uint64_t *ptptr = (uint64_t *)vm_tf->tf_cr3;
uint64_t entry;
- for (int shift = PML4_SHIFT; shift >= PML1_SHIFT; shift -= BITS_PER_PML) {
+ for (int shift = PML4_SHIFT;
+ shift >= PML1_SHIFT;
+ shift -= BITS_PER_PML) {
entry = ptptr[PMLx(va, shift)];
/* bit 63 can be NX. Bits 62:52 are ignored (for PML4) */
entry &= 0x000fffffffffffff;
diff --git a/user/vmm/vmxmsr.c b/user/vmm/vmxmsr.c
index f4d8f62..9c8e982 100644
--- a/user/vmm/vmxmsr.c
+++ b/user/vmm/vmxmsr.c
@@ -179,8 +179,8 @@
break;
case 0x5: /* INIT */
case 0x6: /* SIPI */
- /* We don't use INIT/SIPI for SMP boot. The guest is still allowed to
- * try to make them for now. */
+ /* We don't use INIT/SIPI for SMP boot. The guest is still
+ * allowed to try to make them for now. */
break;
default:
fprintf(stderr, "Unsupported IPI type %d!\n", type);
@@ -215,9 +215,9 @@
timer_waiter = (struct alarm_waiter*)gth->user_data;
/* This is a precaution on my part, in case the guest tries to look at
- * the current count on the lapic. I wanted it to be something other than
- * 0 just in case. The current count will never be right short of us
- * properly emulating it. */
+ * the current count on the lapic. I wanted it to be something other
+ * than 0 just in case. The current count will never be right short of
+ * us properly emulating it. */
((uint32_t *)(gpci->vapic_addr))[0x39] = initial_count;
if (!timer_waiter)
@@ -247,11 +247,14 @@
if (opcode == EXIT_REASON_MSR_READ) {
if (vm_tf->tf_rcx != MSR_LAPIC_ICR) {
- vm_tf->tf_rax = ((uint32_t *)(gpci->vapic_addr))[apic_offset];
+ vm_tf->tf_rax =
+ ((uint32_t*)(gpci->vapic_addr))[apic_offset];
vm_tf->tf_rdx = 0;
} else {
- vm_tf->tf_rax = ((uint32_t *)(gpci->vapic_addr))[apic_offset];
- vm_tf->tf_rdx = ((uint32_t *)(gpci->vapic_addr))[apic_offset + 1];
+ vm_tf->tf_rax =
+ ((uint32_t*)(gpci->vapic_addr))[apic_offset];
+ vm_tf->tf_rdx =
+ ((uint32_t*)(gpci->vapic_addr))[apic_offset +1];
}
} else {
switch (vm_tf->tf_rcx) {
@@ -267,7 +270,7 @@
break;
default:
((uint32_t *)(gpci->vapic_addr))[apic_offset] =
- (uint32_t)(vm_tf->tf_rax);
+ (uint32_t)(vm_tf->tf_rax);
}
}
return 0;
diff --git a/user/vmm/vthread.c b/user/vmm/vthread.c
index 8c82b13..aef0c2e 100644
--- a/user/vmm/vthread.c
+++ b/user/vmm/vthread.c
@@ -40,8 +40,8 @@
{
uint8_t *p;
- /* Technically, we don't need these pages for the all guests. Currently, the
- * kernel requires them. */
+ /* Technically, we don't need these pages for the all guests. Currently,
+ * the kernel requires them. */
p = pages(3);
if (!p)
panic("Can't allocate 3 pages for guest: %r");
@@ -197,8 +197,8 @@
}
stacktop = alloc_stacktop(vth_to_vm(vth));
assert(stacktop);
- /* Yes, an evil part of me thought of using the top of the stack for this
- * struct's storage. */
+ /* Yes, an evil part of me thought of using the top of the stack for
+ * this struct's storage. */
gth->user_data = malloc(sizeof(struct vthread_info));
assert(gth->user_data);
info = (struct vthread_info*)gth->user_data;
@@ -216,7 +216,8 @@
vth = vthread_alloc(vm, gpci);
if (!vth)
return NULL;
- vthread_init_ctx(vth, (uintptr_t)entry, (uintptr_t)arg, vth_get_stack(vth));
+ vthread_init_ctx(vth, (uintptr_t)entry, (uintptr_t)arg,
+ vth_get_stack(vth));
vthread_run(vth);
return vth;
}