Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some information to /proc/cpuinfo #7

Merged
merged 3 commits into from
Sep 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions arch/lkl/include/uapi/asm/host_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ struct ucontext;
* the function that will eventually call longjmp here
*
* @jmp_buf_longjmp - perform a jump back to the saved jump buffer
*
* @cpuinfo_get - Returns the /proc/cpuinfo string. It needs to be provided a
* pointer to the destination buffer and its size, and it returns the total
* length of the string. As the string may be longer than the provided buffer,
* the returned value may be bigger than the buffer size. The string will be
* cropped in that case.
*/
struct lkl_host_operations {
const char *virtio_devices;
Expand Down Expand Up @@ -159,6 +165,8 @@ struct lkl_host_operations {

void (*jmp_buf_set)(struct lkl_jmp_buf *jmpb, void (*f)(void));
void (*jmp_buf_longjmp)(struct lkl_jmp_buf *jmpb, int val);

unsigned int (*cpuinfo_get)(char *buffer, unsigned int buffer_len);
};

/**
Expand Down
104 changes: 56 additions & 48 deletions arch/lkl/kernel/proc.c
Original file line number Diff line number Diff line change
@@ -1,69 +1,77 @@

#include <asm/host_ops.h>
#include <linux/printk.h>
#include <linux/seq_file.h>
#include <linux/slab.h>

#ifdef CONFIG_PROC_FS

/*
* TODO: This currently just hard-codes some output for /proc/cpuinfo that is
* plausible and can be parsed by an application. Note though that CPU features,
* the virtual CPU core count and socket count are wrong.
*/
static char *cpuinfo_buf;
static unsigned int cpuinfo_len;

static int show_cpuinfo(struct seq_file *m, void *v)
{
seq_printf(m, "processor : 0\n"
"cpu family : 6\n"
"model : 158\n"
"model name : Intel(R) Xeon(R) CPU E3-1280 v6 @ 3.90GHz\n"
"stepping : 9\n"
"microcode : 0xb4\n"
"cpu MHz : 800.063\n"
"cache size : 8192 KB\n"
"physical id : 0\n"
"siblings : 4\n"
"core id : 0\n"
"cpu cores : 4\n"
"apicid : 0\n"
"initial apicid : 0\n"
"fpu : yes\n"
"fpu_exception : yes\n"
"cpuid level : 22\n"
"wp : yes\n"
"flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d\n"
"bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs\n"
"bogomips : 7824.00\n"
"clflush size : 64\n"
"cache_alignment : 64\n"
"address sizes : 39 bits physical, 48 bits virtual\n"
"power management: \n");

seq_puts(m, "\n\n");

return 0;
}
loff_t *spos = v;

if (*spos >= cpuinfo_len)
return 0;

seq_putc(m, cpuinfo_buf[*spos]);

int __cpuinfo_accessed = 0;
return 0;
}

static void *c_start(struct seq_file *m, loff_t *pos)
{
// TODO: missing correct implementation

// Only output information once
if (__cpuinfo_accessed)
return NULL;

__cpuinfo_accessed = 1;
return (void*)1;
unsigned int buf_size;
loff_t *spos;

if (cpuinfo_buf == NULL) {

/* How big is the buffer that we need? */
cpuinfo_len = lkl_ops->cpuinfo_get(NULL, 0);
buf_size = cpuinfo_len + 1;

cpuinfo_buf = kmalloc(buf_size, GFP_KERNEL);
if (cpuinfo_buf == NULL) {
printk("cpuinfo: Not enough memory (%u bytes needed)\n", buf_size);
return NULL;
}

/* Print cpuinfo to the buffer we have allocated */
cpuinfo_len = lkl_ops->cpuinfo_get(cpuinfo_buf, buf_size);
}

spos = kmalloc(sizeof(loff_t), GFP_KERNEL);
if (spos == NULL) {
printk("cpuinfo: Not enough memory (%lu bytes needed)\n",
sizeof(loff_t));
return NULL;
}

if (*pos >= cpuinfo_len)
return NULL;

*spos = *pos;
return spos;
}

static void *c_next(struct seq_file *m, void *v, loff_t *pos)
{
// TODO: missing implementation
return NULL;
loff_t *spos = v;

*spos = *spos + 1;
*pos = *spos;

if (*spos >= cpuinfo_len)
return NULL;

return spos;
}

static void c_stop(struct seq_file *m, void *v)
{
// TODO: missing implementation
kfree(v);
}

const struct seq_operations cpuinfo_op = {
Expand All @@ -73,4 +81,4 @@ const struct seq_operations cpuinfo_op = {
.show = show_cpuinfo,
};

#endif
#endif
1 change: 1 addition & 0 deletions tools/lkl/Targets
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ LDLIBS_cptofs-y := -larchive
LDLIBS_cptofs-$(LKL_HOST_CONFIG_NEEDS_LARGP) += -largp

progs-y += tests/boot
progs-y += tests/cpuinfo
progs-y += tests/disk
progs-y += tests/net-test

38 changes: 38 additions & 0 deletions tools/lkl/lib/posix-host.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <assert.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdint.h>
Expand Down Expand Up @@ -311,6 +312,42 @@ static long _gettid(void)
#endif
}

static unsigned int cpuinfo_get(char *buffer, unsigned int buffer_len)
{
/* TODO: The output of this function is hardcoded for now. */
int len;

len = snprintf(buffer, buffer_len,
AntonioND marked this conversation as resolved.
Show resolved Hide resolved
"processor : 0\n"
"cpu family : 6\n"
"model : 158\n"
"model name : Intel(R) Xeon(R) CPU E3-1280 v6 @ 3.90GHz\n"
"stepping : 9\n"
"microcode : 0xb4\n"
"cpu MHz : 800.063\n"
"cache size : 8192 KB\n"
"physical id : 0\n"
"siblings : 1\n"
"core id : 0\n"
"cpu cores : 1\n"
"apicid : 0\n"
"initial apicid : 0\n"
"fpu : yes\n"
"fpu_exception : yes\n"
"cpuid level : 22\n"
"wp : yes\n"
"flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse3 clflush dts ac pi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bt rep_good nopl x topology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm aabm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d\n"
"bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs\n"
"bogomips : 7824.00\n"
"clflush size : 64\n"
"cache_alignment : 64\n"
"address sizes : 39 bits physical, 48 bits virtual\n"
"power management: \n"
"\n");

return len;
}

struct lkl_host_operations lkl_host_ops = {
.panic = panic,
.thread_create = thread_create,
Expand Down Expand Up @@ -344,6 +381,7 @@ struct lkl_host_operations lkl_host_ops = {
.gettid = _gettid,
.jmp_buf_set = jmp_buf_set,
.jmp_buf_longjmp = jmp_buf_longjmp,
.cpuinfo_get = cpuinfo_get,
};

static int fd_get_capacity(struct lkl_disk disk, unsigned long long *res)
Expand Down
1 change: 1 addition & 0 deletions tools/lkl/tests/Build
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
boot-y += boot.o test.o
cpuinfo-y += cpuinfo.o test.o
disk-y += disk.o cla.o test.o
net-test-y += net-test.o cla.o test.o
116 changes: 116 additions & 0 deletions tools/lkl/tests/cpuinfo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <lkl.h>
#include <lkl_host.h>

#include "test.h"

LKL_TEST_CALL(start_kernel, lkl_start_kernel, 0, &lkl_host_ops,
"mem=16M loglevel=8");

static int lkl_test_cpuinfo(void)
{
/* The buffer size must be a multiple of the read sizes */
#define BUF_SIZE (64 * 1024)
#define READ_SIZE_1 16
#define READ_SIZE_2 32

int ret;
int err;
int f1, f2;
static char buf1[BUF_SIZE], buf2[BUF_SIZE];
long read1, read2;
int done1, done2;
long totalread1, totalread2;

ret = TEST_FAILURE;

err = lkl_mount_fs("proc");
if (err < 0) {
lkl_test_logf("failed to mount /proc\n");
return TEST_FAILURE;
}

f1 = lkl_sys_open("/proc/cpuinfo", LKL_O_RDONLY, 0);
if (f1 < 0) {
lkl_test_logf("failed to open /proc/cpuinfo (f1): %s\n",
lkl_strerror(f1));
return TEST_FAILURE;
}

f2 = lkl_sys_open("/proc/cpuinfo", LKL_O_RDONLY, 0);
if (f2 < 0) {
lkl_sys_close(f1);
lkl_test_logf("failed to open /proc/cpuinfo (f2): %s\n",
lkl_strerror(f2));
return TEST_FAILURE;
}

totalread1 = 0;
totalread2 = 0;

done1 = 0;
done2 = 0;

while (!done1 || !done2) {
if (totalread1 >= (BUF_SIZE - READ_SIZE_1)) {
lkl_test_logf("file is too big\n");
totalread1 = 0;
break;
}

if (totalread2 >= (BUF_SIZE - READ_SIZE_2)) {
lkl_test_logf("file is too big\n");
totalread2 = 0;
break;
}

if (!done1) {
read1 = lkl_sys_read(f1, &(buf1[totalread1]),
READ_SIZE_1);
if (read1 <= 0)
done1 = 1;
totalread1 += read1;
}

if (!done2) {
read2 = lkl_sys_read(f2, &(buf2[totalread2]),
READ_SIZE_2);
if (read2 <= 0)
done2 = 1;
totalread2 += read2;
}
}

lkl_sys_close(f1);
lkl_sys_close(f2);

if (totalread1 == 0) {
lkl_test_logf("file is empty\n");
} else if (totalread1 != totalread2) {
lkl_test_logf("sizes don't match: %lu != %lu\n",
totalread1, totalread2);
} else {
if (memcmp(buf1, buf2, totalread1) == 0)
ret = TEST_SUCCESS;
else
lkl_test_logf("read contents don't match");
}

return ret;
}

struct lkl_test tests[] = {
LKL_TEST(start_kernel),
LKL_TEST(cpuinfo),
};

int main(int argc, const char **argv)
{
lkl_host_ops.print = lkl_test_log;

return lkl_test_run(tests, sizeof(tests)/sizeof(struct lkl_test),
"cpuinfo");
}
8 changes: 8 additions & 0 deletions tools/lkl/tests/cpuinfo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash

script_dir=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
source $script_dir/test.sh

lkl_test_plan 1 "cpuinfo"
lkl_test_run 1
lkl_test_exec $script_dir/cpuinfo
1 change: 1 addition & 0 deletions tools/lkl/tests/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def end(self, obj):

tests = [
'boot.sh',
'cpuinfo.sh',
'disk.sh -t ext4',
'disk.sh -t btrfs',
'disk.sh -t vfat',
Expand Down