diff options
Diffstat (limited to 'tools')
37 files changed, 620 insertions, 122 deletions
diff --git a/tools/power/cpupower/debug/i386/dump_psb.c b/tools/power/cpupower/debug/i386/dump_psb.c index 8d6a47514253..2c768cf70128 100644 --- a/tools/power/cpupower/debug/i386/dump_psb.c +++ b/tools/power/cpupower/debug/i386/dump_psb.c @@ -134,7 +134,7 @@ next_one: } static struct option info_opts[] = { - {.name = "numpst", .has_arg=no_argument, .flag=NULL, .val='n'}, + {"numpst", no_argument, NULL, 'n'}, }; void print_help(void) diff --git a/tools/power/cpupower/man/cpupower-idle-set.1 b/tools/power/cpupower/man/cpupower-idle-set.1 index 3e6799d7a79f..580c4e3ea92a 100644 --- a/tools/power/cpupower/man/cpupower-idle-set.1 +++ b/tools/power/cpupower/man/cpupower-idle-set.1 @@ -20,7 +20,9 @@ Disable a specific processor sleep state. Enable a specific processor sleep state. .TP \fB\-D\fR \fB\-\-disable-by-latency\fR <LATENCY> -Disable all idle states with a equal or higher latency than <LATENCY> +Disable all idle states with a equal or higher latency than <LATENCY>. + +Enable all idle states with a latency lower than <LATENCY>. .TP \fB\-E\fR \fB\-\-enable-all\fR Enable all idle states if not enabled already. diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c index b4b90a97662c..0e6764330241 100644 --- a/tools/power/cpupower/utils/cpufreq-info.c +++ b/tools/power/cpupower/utils/cpufreq-info.c @@ -536,21 +536,21 @@ static int get_latency(unsigned int cpu, unsigned int human) } static struct option info_opts[] = { - { .name = "debug", .has_arg = no_argument, .flag = NULL, .val = 'e'}, - { .name = "boost", .has_arg = no_argument, .flag = NULL, .val = 'b'}, - { .name = "freq", .has_arg = no_argument, .flag = NULL, .val = 'f'}, - { .name = "hwfreq", .has_arg = no_argument, .flag = NULL, .val = 'w'}, - { .name = "hwlimits", .has_arg = no_argument, .flag = NULL, .val = 'l'}, - { .name = "driver", .has_arg = no_argument, .flag = NULL, .val = 'd'}, - { .name = "policy", .has_arg = no_argument, .flag = NULL, .val = 'p'}, - { .name = "governors", .has_arg = no_argument, .flag = NULL, .val = 'g'}, - { .name = "related-cpus", .has_arg = no_argument, .flag = NULL, .val = 'r'}, - { .name = "affected-cpus",.has_arg = no_argument, .flag = NULL, .val = 'a'}, - { .name = "stats", .has_arg = no_argument, .flag = NULL, .val = 's'}, - { .name = "latency", .has_arg = no_argument, .flag = NULL, .val = 'y'}, - { .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'}, - { .name = "human", .has_arg = no_argument, .flag = NULL, .val = 'm'}, - { .name = "no-rounding", .has_arg = no_argument, .flag = NULL, .val = 'n'}, + {"debug", no_argument, NULL, 'e'}, + {"boost", no_argument, NULL, 'b'}, + {"freq", no_argument, NULL, 'f'}, + {"hwfreq", no_argument, NULL, 'w'}, + {"hwlimits", no_argument, NULL, 'l'}, + {"driver", no_argument, NULL, 'd'}, + {"policy", no_argument, NULL, 'p'}, + {"governors", no_argument, NULL, 'g'}, + {"related-cpus", no_argument, NULL, 'r'}, + {"affected-cpus", no_argument, NULL, 'a'}, + {"stats", no_argument, NULL, 's'}, + {"latency", no_argument, NULL, 'y'}, + {"proc", no_argument, NULL, 'o'}, + {"human", no_argument, NULL, 'm'}, + {"no-rounding", no_argument, NULL, 'n'}, { }, }; diff --git a/tools/power/cpupower/utils/cpufreq-set.c b/tools/power/cpupower/utils/cpufreq-set.c index 4e213576381e..0fbd1a22c0a9 100644 --- a/tools/power/cpupower/utils/cpufreq-set.c +++ b/tools/power/cpupower/utils/cpufreq-set.c @@ -22,11 +22,11 @@ #define NORM_FREQ_LEN 32 static struct option set_opts[] = { - { .name = "min", .has_arg = required_argument, .flag = NULL, .val = 'd'}, - { .name = "max", .has_arg = required_argument, .flag = NULL, .val = 'u'}, - { .name = "governor", .has_arg = required_argument, .flag = NULL, .val = 'g'}, - { .name = "freq", .has_arg = required_argument, .flag = NULL, .val = 'f'}, - { .name = "related", .has_arg = no_argument, .flag = NULL, .val='r'}, + {"min", required_argument, NULL, 'd'}, + {"max", required_argument, NULL, 'u'}, + {"governor", required_argument, NULL, 'g'}, + {"freq", required_argument, NULL, 'f'}, + {"related", no_argument, NULL, 'r'}, { }, }; diff --git a/tools/power/cpupower/utils/cpuidle-info.c b/tools/power/cpupower/utils/cpuidle-info.c index 75e66de7e7a7..750c1d82c3f7 100644 --- a/tools/power/cpupower/utils/cpuidle-info.c +++ b/tools/power/cpupower/utils/cpuidle-info.c @@ -126,8 +126,8 @@ static void proc_cpuidle_cpu_output(unsigned int cpu) } static struct option info_opts[] = { - { .name = "silent", .has_arg = no_argument, .flag = NULL, .val = 's'}, - { .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'}, + {"silent", no_argument, NULL, 's'}, + {"proc", no_argument, NULL, 'o'}, { }, }; diff --git a/tools/power/cpupower/utils/cpuidle-set.c b/tools/power/cpupower/utils/cpuidle-set.c index d45d8d775c02..d6b6ae44b8c2 100644 --- a/tools/power/cpupower/utils/cpuidle-set.c +++ b/tools/power/cpupower/utils/cpuidle-set.c @@ -13,15 +13,11 @@ #include "helpers/sysfs.h" static struct option info_opts[] = { - { .name = "disable", - .has_arg = required_argument, .flag = NULL, .val = 'd'}, - { .name = "enable", - .has_arg = required_argument, .flag = NULL, .val = 'e'}, - { .name = "disable-by-latency", - .has_arg = required_argument, .flag = NULL, .val = 'D'}, - { .name = "enable-all", - .has_arg = no_argument, .flag = NULL, .val = 'E'}, - { }, + {"disable", required_argument, NULL, 'd'}, + {"enable", required_argument, NULL, 'e'}, + {"disable-by-latency", required_argument, NULL, 'D'}, + {"enable-all", no_argument, NULL, 'E'}, + { }, }; @@ -148,14 +144,21 @@ int cmd_idle_set(int argc, char **argv) (cpu, idlestate); state_latency = sysfs_get_idlestate_latency (cpu, idlestate); - printf("CPU: %u - idlestate %u - state_latency: %llu - latency: %llu\n", - cpu, idlestate, state_latency, latency); - if (disabled == 1 || latency > state_latency) + if (disabled == 1) { + if (latency > state_latency){ + ret = sysfs_idlestate_disable + (cpu, idlestate, 0); + if (ret == 0) + printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu); + } continue; - ret = sysfs_idlestate_disable - (cpu, idlestate, 1); - if (ret == 0) + } + if (latency <= state_latency){ + ret = sysfs_idlestate_disable + (cpu, idlestate, 1); + if (ret == 0) printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu); + } } break; case 'E': diff --git a/tools/power/cpupower/utils/cpupower-info.c b/tools/power/cpupower/utils/cpupower-info.c index 136d979e9586..10299f2e9d2a 100644 --- a/tools/power/cpupower/utils/cpupower-info.c +++ b/tools/power/cpupower/utils/cpupower-info.c @@ -17,8 +17,8 @@ #include "helpers/sysfs.h" static struct option set_opts[] = { - { .name = "perf-bias", .has_arg = optional_argument, .flag = NULL, .val = 'b'}, - { }, + {"perf-bias", optional_argument, NULL, 'b'}, + { }, }; static void print_wrong_arg_exit(void) diff --git a/tools/power/cpupower/utils/cpupower-set.c b/tools/power/cpupower/utils/cpupower-set.c index 573c75f8e3f5..3e6f374f8dd7 100644 --- a/tools/power/cpupower/utils/cpupower-set.c +++ b/tools/power/cpupower/utils/cpupower-set.c @@ -18,7 +18,7 @@ #include "helpers/bitmask.h" static struct option set_opts[] = { - { .name = "perf-bias", .has_arg = required_argument, .flag = NULL, .val = 'b'}, + {"perf-bias", required_argument, NULL, 'b'}, { }, }; diff --git a/tools/power/cpupower/utils/helpers/topology.c b/tools/power/cpupower/utils/helpers/topology.c index cea398c176e7..9cbb7fd75171 100644 --- a/tools/power/cpupower/utils/helpers/topology.c +++ b/tools/power/cpupower/utils/helpers/topology.c @@ -73,18 +73,22 @@ int get_cpu_topology(struct cpupower_topology *cpu_top) for (cpu = 0; cpu < cpus; cpu++) { cpu_top->core_info[cpu].cpu = cpu; cpu_top->core_info[cpu].is_online = sysfs_is_cpu_online(cpu); - if (!cpu_top->core_info[cpu].is_online) - continue; if(sysfs_topology_read_file( cpu, "physical_package_id", - &(cpu_top->core_info[cpu].pkg)) < 0) - return -1; + &(cpu_top->core_info[cpu].pkg)) < 0) { + cpu_top->core_info[cpu].pkg = -1; + cpu_top->core_info[cpu].core = -1; + continue; + } if(sysfs_topology_read_file( cpu, "core_id", - &(cpu_top->core_info[cpu].core)) < 0) - return -1; + &(cpu_top->core_info[cpu].core)) < 0) { + cpu_top->core_info[cpu].pkg = -1; + cpu_top->core_info[cpu].core = -1; + continue; + } } qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info), @@ -95,12 +99,15 @@ int get_cpu_topology(struct cpupower_topology *cpu_top) done by pkg value. */ last_pkg = cpu_top->core_info[0].pkg; for(cpu = 1; cpu < cpus; cpu++) { - if(cpu_top->core_info[cpu].pkg != last_pkg) { + if (cpu_top->core_info[cpu].pkg != last_pkg && + cpu_top->core_info[cpu].pkg != -1) { + last_pkg = cpu_top->core_info[cpu].pkg; cpu_top->pkgs++; } } - cpu_top->pkgs++; + if (!cpu_top->core_info[0].pkg == -1) + cpu_top->pkgs++; /* Intel's cores count is not consecutively numbered, there may * be a core_id of 3, but none of 2. Assume there always is 0 diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c index c4bae9203a69..05f953f0f0a0 100644 --- a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c +++ b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c @@ -143,6 +143,9 @@ void print_results(int topology_depth, int cpu) /* Be careful CPUs may got resorted for pkg value do not just use cpu */ if (!bitmask_isbitset(cpus_chosen, cpu_top.core_info[cpu].cpu)) return; + if (!cpu_top.core_info[cpu].is_online && + cpu_top.core_info[cpu].pkg == -1) + return; if (topology_depth > 2) printf("%4d|", cpu_top.core_info[cpu].pkg); @@ -191,7 +194,8 @@ void print_results(int topology_depth, int cpu) * It's up to the monitor plug-in to check .is_online, this one * is just for additional info. */ - if (!cpu_top.core_info[cpu].is_online) { + if (!cpu_top.core_info[cpu].is_online && + cpu_top.core_info[cpu].pkg != -1) { printf(_(" *is offline\n")); return; } else @@ -388,6 +392,9 @@ int cmd_monitor(int argc, char **argv) return EXIT_FAILURE; } + if (!cpu_top.core_info[0].is_online) + printf("WARNING: at least one cpu is offline\n"); + /* Default is: monitor all CPUs */ if (bitmask_isallclear(cpus_chosen)) bitmask_setall(cpus_chosen); diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index bde0ef1a63df..d8e4b20b6d54 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -75,6 +75,7 @@ unsigned int aperf_mperf_multiplier = 1; int do_smi; double bclk; double base_hz; +unsigned int has_base_hz; double tsc_tweak = 1.0; unsigned int show_pkg; unsigned int show_core; @@ -96,6 +97,7 @@ unsigned int do_ring_perf_limit_reasons; unsigned int crystal_hz; unsigned long long tsc_hz; int base_cpu; +double discover_bclk(unsigned int family, unsigned int model); #define RAPL_PKG (1 << 0) /* 0x610 MSR_PKG_POWER_LIMIT */ @@ -511,9 +513,13 @@ int format_counters(struct thread_data *t, struct core_data *c, } /* Bzy_MHz */ - if (has_aperf) - outp += sprintf(outp, "%8.0f", - 1.0 * t->tsc * tsc_tweak / units * t->aperf / t->mperf / interval_float); + if (has_aperf) { + if (has_base_hz) + outp += sprintf(outp, "%8.0f", base_hz / units * t->aperf / t->mperf); + else + outp += sprintf(outp, "%8.0f", + 1.0 * t->tsc / units * t->aperf / t->mperf / interval_float); + } /* TSC_MHz */ outp += sprintf(outp, "%8.0f", 1.0 * t->tsc/units/interval_float); @@ -1158,12 +1164,6 @@ int phi_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, static void calculate_tsc_tweak() { - unsigned long long msr; - unsigned int base_ratio; - - get_msr(base_cpu, MSR_NHM_PLATFORM_INFO, &msr); - base_ratio = (msr >> 8) & 0xFF; - base_hz = base_ratio * bclk * 1000000; tsc_tweak = base_hz / tsc_hz; } @@ -1440,7 +1440,7 @@ dump_config_tdp(void) get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr); fprintf(stderr, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr); - fprintf(stderr, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0xEF); + fprintf(stderr, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0x7F); fprintf(stderr, " lock=%d", (unsigned int)(msr >> 31) & 1); fprintf(stderr, ")\n"); } @@ -1821,6 +1821,7 @@ void check_permissions() int probe_nhm_msrs(unsigned int family, unsigned int model) { unsigned long long msr; + unsigned int base_ratio; int *pkg_cstate_limits; if (!genuine_intel) @@ -1829,6 +1830,8 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) if (family != 6) return 0; + bclk = discover_bclk(family, model); + switch (model) { case 0x1A: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */ case 0x1E: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */ @@ -1871,9 +1874,13 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) return 0; } get_msr(base_cpu, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr); - pkg_cstate_limit = pkg_cstate_limits[msr & 0xF]; + get_msr(base_cpu, MSR_NHM_PLATFORM_INFO, &msr); + base_ratio = (msr >> 8) & 0xFF; + + base_hz = base_ratio * bclk * 1000000; + has_base_hz = 1; return 1; } int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model) @@ -2780,7 +2787,6 @@ void process_cpuid() do_skl_residency = has_skl_msrs(family, model); do_slm_cstates = is_slm(family, model); do_knl_cstates = is_knl(family, model); - bclk = discover_bclk(family, model); rapl_probe(family, model); perf_limit_reasons_probe(family, model); diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c index 021e6f97f33e..40ab4476c80a 100644 --- a/tools/testing/nvdimm/test/nfit.c +++ b/tools/testing/nvdimm/test/nfit.c @@ -17,8 +17,10 @@ #include <linux/vmalloc.h> #include <linux/device.h> #include <linux/module.h> +#include <linux/mutex.h> #include <linux/ndctl.h> #include <linux/sizes.h> +#include <linux/list.h> #include <linux/slab.h> #include <nfit.h> #include <nd.h> @@ -44,6 +46,15 @@ * +------+ | blk5.0 | pm1.0 | 3 region5 * +-------------------------+----------+-+-------+ * + * +--+---+ + * | cpu1 | + * +--+---+ (Hotplug DIMM) + * | +----------------------------------------------+ + * +--+---+ | blk6.0/pm7.0 | 4 region6/7 + * | imc0 +--+----------------------------------------------+ + * +------+ + * + * * *) In this layout we have four dimms and two memory controllers in one * socket. Each unique interface (BLK or PMEM) to DPA space * is identified by a region device with a dynamically assigned id. @@ -85,8 +96,8 @@ * reference an NVDIMM. */ enum { - NUM_PM = 2, - NUM_DCR = 4, + NUM_PM = 3, + NUM_DCR = 5, NUM_BDW = NUM_DCR, NUM_SPA = NUM_PM + NUM_DCR + NUM_BDW, NUM_MEM = NUM_DCR + NUM_BDW + 2 /* spa0 iset */ + 4 /* spa1 iset */, @@ -115,6 +126,7 @@ static u32 handle[NUM_DCR] = { [1] = NFIT_DIMM_HANDLE(0, 0, 0, 0, 1), [2] = NFIT_DIMM_HANDLE(0, 0, 1, 0, 0), [3] = NFIT_DIMM_HANDLE(0, 0, 1, 0, 1), + [4] = NFIT_DIMM_HANDLE(0, 1, 0, 0, 0), }; struct nfit_test { @@ -138,6 +150,7 @@ struct nfit_test { dma_addr_t *dcr_dma; int (*alloc)(struct nfit_test *t); void (*setup)(struct nfit_test *t); + int setup_hotplug; }; static struct nfit_test *to_nfit_test(struct device *dev) @@ -428,6 +441,10 @@ static int nfit_test0_alloc(struct nfit_test *t) if (!t->spa_set[1]) return -ENOMEM; + t->spa_set[2] = test_alloc_coherent(t, SPA0_SIZE, &t->spa_set_dma[2]); + if (!t->spa_set[2]) + return -ENOMEM; + for (i = 0; i < NUM_DCR; i++) { t->dimm[i] = test_alloc(t, DIMM_SIZE, &t->dimm_dma[i]); if (!t->dimm[i]) @@ -950,6 +967,126 @@ static void nfit_test0_setup(struct nfit_test *t) flush->hint_count = 1; flush->hint_address[0] = t->flush_dma[3]; + if (t->setup_hotplug) { + offset = offset + sizeof(struct acpi_nfit_flush_address) * 4; + /* dcr-descriptor4 */ + dcr = nfit_buf + offset; + dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; + dcr->header.length = sizeof(struct acpi_nfit_control_region); + dcr->region_index = 4+1; + dcr->vendor_id = 0xabcd; + dcr->device_id = 0; + dcr->revision_id = 1; + dcr->serial_number = ~handle[4]; + dcr->windows = 1; + dcr->window_size = DCR_SIZE; + dcr->command_offset = 0; + dcr->command_size = 8; + dcr->status_offset = 8; + dcr->status_size = 4; + + offset = offset + sizeof(struct acpi_nfit_control_region); + /* bdw4 (spa/dcr4, dimm4) */ + bdw = nfit_buf + offset; + bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION; + bdw->header.length = sizeof(struct acpi_nfit_data_region); + bdw->region_index = 4+1; + bdw->windows = 1; + bdw->offset = 0; + bdw->size = BDW_SIZE; + bdw->capacity = DIMM_SIZE; + bdw->start_address = 0; + + offset = offset + sizeof(struct acpi_nfit_data_region); + /* spa10 (dcr4) dimm4 */ + spa = nfit_buf + offset; + spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS; + spa->header.length = sizeof(*spa); + memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16); + spa->range_index = 10+1; + spa->address = t->dcr_dma[4]; + spa->length = DCR_SIZE; + + /* + * spa11 (single-dimm interleave for hotplug, note storage + * does not actually alias the related block-data-window + * regions) + */ + spa = nfit_buf + offset + sizeof(*spa); + spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS; + spa->header.length = sizeof(*spa); + memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16); + spa->range_index = 11+1; + spa->address = t->spa_set_dma[2]; + spa->length = SPA0_SIZE; + + /* spa12 (bdw for dcr4) dimm4 */ + spa = nfit_buf + offset + sizeof(*spa) * 2; + spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS; + spa->header.length = sizeof(*spa); + memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16); + spa->range_index = 12+1; + spa->address = t->dimm_dma[4]; + spa->length = DIMM_SIZE; + + offset = offset + sizeof(*spa) * 3; + /* mem-region14 (spa/dcr4, dimm4) */ + memdev = nfit_buf + offset; + memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; + memdev->header.length = sizeof(*memdev); + memdev->device_handle = handle[4]; + memdev->physical_id = 4; + memdev->region_id = 0; + memdev->range_index = 10+1; + memdev->region_index = 4+1; + memdev->region_size = 0; + memdev->region_offset = 0; + memdev->address = 0; + memdev->interleave_index = 0; + memdev->interleave_ways = 1; + + /* mem-region15 (spa0, dimm4) */ + memdev = nfit_buf + offset + + sizeof(struct acpi_nfit_memory_map); + memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; + memdev->header.length = sizeof(*memdev); + memdev->device_handle = handle[4]; + memdev->physical_id = 4; + memdev->region_id = 0; + memdev->range_index = 11+1; + memdev->region_index = 4+1; + memdev->region_size = SPA0_SIZE; + memdev->region_offset = t->spa_set_dma[2]; + memdev->address = 0; + memdev->interleave_index = 0; + memdev->interleave_ways = 1; + + /* mem-region16 (spa/dcr4, dimm4) */ + memdev = nfit_buf + offset + + sizeof(struct acpi_nfit_memory_map) * 2; + memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; + memdev->header.length = sizeof(*memdev); + memdev->device_handle = handle[4]; + memdev->physical_id = 4; + memdev->region_id = 0; + memdev->range_index = 12+1; + memdev->region_index = 4+1; + memdev->region_size = 0; + memdev->region_offset = 0; + memdev->address = 0; + memdev->interleave_index = 0; + memdev->interleave_ways = 1; + + offset = offset + sizeof(struct acpi_nfit_memory_map) * 3; + /* flush3 (dimm4) */ + flush = nfit_buf + offset; + flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; + flush->header.length = sizeof(struct acpi_nfit_flush_address); + flush->device_handle = handle[4]; + flush->hint_count = 1; + flush->hint_address[0] = t->flush_dma[4]; + } + acpi_desc = &t->acpi_desc; set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_dsm_force_en); set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en); @@ -998,7 +1135,7 @@ static void nfit_test1_setup(struct nfit_test *t) memdev->interleave_ways = 1; memdev->flags = ACPI_NFIT_MEM_SAVE_FAILED | ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED | ACPI_NFIT_MEM_HEALTH_OBSERVED - | ACPI_NFIT_MEM_ARMED; + | ACPI_NFIT_MEM_NOT_ARMED; offset += sizeof(*memdev); /* dcr-descriptor0 */ @@ -1108,6 +1245,29 @@ static int nfit_test_probe(struct platform_device *pdev) if (!acpi_desc->nvdimm_bus) return -ENXIO; + INIT_LIST_HEAD(&acpi_desc->spa_maps); + INIT_LIST_HEAD(&acpi_desc->spas); + INIT_LIST_HEAD(&acpi_desc->dcrs); + INIT_LIST_HEAD(&acpi_desc->bdws); + INIT_LIST_HEAD(&acpi_desc->idts); + INIT_LIST_HEAD(&acpi_desc->flushes); + INIT_LIST_HEAD(&acpi_desc->memdevs); + INIT_LIST_HEAD(&acpi_desc->dimms); + mutex_init(&acpi_desc->spa_map_mutex); + mutex_init(&acpi_desc->init_mutex); + + rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_size); + if (rc) { + nvdimm_bus_unregister(acpi_desc->nvdimm_bus); + return rc; + } + + if (nfit_test->setup != nfit_test0_setup) + return 0; + + nfit_test->setup_hotplug = 1; + nfit_test->setup(nfit_test); + rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_size); if (rc) { nvdimm_bus_unregister(acpi_desc->nvdimm_bus); diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 4b4957b8df4e..c8edff6803d1 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -14,6 +14,7 @@ TARGETS += mount TARGETS += mqueue TARGETS += net TARGETS += powerpc +TARGETS += pstore TARGETS += ptrace TARGETS += seccomp TARGETS += size @@ -66,6 +67,9 @@ clean_hotplug: make -C $$TARGET clean; \ done; +run_pstore_crash: + make -C pstore run_crash + INSTALL_PATH ?= install INSTALL_PATH := $(abspath $(INSTALL_PATH)) ALL_SCRIPT := $(INSTALL_PATH)/run_kselftest.sh diff --git a/tools/testing/selftests/breakpoints/Makefile b/tools/testing/selftests/breakpoints/Makefile index d27108b4f208..c0d957015f52 100644 --- a/tools/testing/selftests/breakpoints/Makefile +++ b/tools/testing/selftests/breakpoints/Makefile @@ -6,7 +6,7 @@ ifeq ($(ARCH),x86) TEST_PROGS := breakpoint_test endif -all: +all: $(TEST_PROGS) include ../lib.mk diff --git a/tools/testing/selftests/efivarfs/.gitignore b/tools/testing/selftests/efivarfs/.gitignore new file mode 100644 index 000000000000..33618493562b --- /dev/null +++ b/tools/testing/selftests/efivarfs/.gitignore @@ -0,0 +1,2 @@ +create-read +open-unlink diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/add_and_remove.tc b/tools/testing/selftests/ftrace/test.d/kprobe/add_and_remove.tc index a5a426211129..c3843ed49bf6 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/add_and_remove.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/add_and_remove.tc @@ -5,7 +5,7 @@ echo 0 > events/enable echo > kprobe_events -echo p:myevent do_fork > kprobe_events +echo p:myevent _do_fork > kprobe_events grep myevent kprobe_events test -d events/kprobes/myevent echo > kprobe_events diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/busy_check.tc b/tools/testing/selftests/ftrace/test.d/kprobe/busy_check.tc index d8c7bb6581fe..74507db8bbc8 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/busy_check.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/busy_check.tc @@ -5,7 +5,7 @@ echo 0 > events/enable echo > kprobe_events -echo p:myevent do_fork > kprobe_events +echo p:myevent _do_fork > kprobe_events test -d events/kprobes/myevent echo 1 > events/kprobes/myevent/enable echo > kprobe_events && exit 1 # this must fail diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args.tc index c45ee2761354..64949d4eda69 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args.tc @@ -5,7 +5,7 @@ echo 0 > events/enable echo > kprobe_events -echo 'p:testprobe do_fork $stack $stack0 +0($stack)' > kprobe_events +echo 'p:testprobe _do_fork $stack $stack0 +0($stack)' > kprobe_events grep testprobe kprobe_events test -d events/kprobes/testprobe echo 1 > events/kprobes/testprobe/enable diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_ftrace.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_ftrace.tc index ab41d2b29841..d6f2f4965697 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_ftrace.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_ftrace.tc @@ -6,31 +6,31 @@ grep function available_tracers || exit_unsupported # this is configurable # prepare echo nop > current_tracer -echo do_fork > set_ftrace_filter +echo _do_fork > set_ftrace_filter echo 0 > events/enable echo > kprobe_events -echo 'p:testprobe do_fork' > kprobe_events +echo 'p:testprobe _do_fork' > kprobe_events # kprobe on / ftrace off echo 1 > events/kprobes/testprobe/enable echo > trace ( echo "forked") grep testprobe trace -! grep 'do_fork <-' trace +! grep '_do_fork <-' trace # kprobe on / ftrace on echo function > current_tracer echo > trace ( echo "forked") grep testprobe trace -grep 'do_fork <-' trace +grep '_do_fork <-' trace # kprobe off / ftrace on echo 0 > events/kprobes/testprobe/enable echo > trace ( echo "forked") ! grep testprobe trace -grep 'do_fork <-' trace +grep '_do_fork <-' trace # kprobe on / ftrace on echo 1 > events/kprobes/testprobe/enable @@ -38,14 +38,14 @@ echo function > current_tracer echo > trace ( echo "forked") grep testprobe trace -grep 'do_fork <-' trace +grep '_do_fork <-' trace # kprobe on / ftrace off echo nop > current_tracer echo > trace ( echo "forked") grep testprobe trace -! grep 'do_fork <-' trace +! grep '_do_fork <-' trace # cleanup echo nop > current_tracer diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_args.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_args.tc index 31717985acc7..0d09546258fd 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_args.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_args.tc @@ -5,7 +5,7 @@ echo 0 > events/enable echo > kprobe_events -echo 'r:testprobe2 do_fork $retval' > kprobe_events +echo 'r:testprobe2 _do_fork $retval' > kprobe_events grep testprobe2 kprobe_events test -d events/kprobes/testprobe2 echo 1 > events/kprobes/testprobe2/enable diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile index 3e7eb7972511..fd396ac811b6 100644 --- a/tools/testing/selftests/memfd/Makefile +++ b/tools/testing/selftests/memfd/Makefile @@ -4,16 +4,16 @@ CFLAGS += -I../../../../include/uapi/ CFLAGS += -I../../../../include/ CFLAGS += -I../../../../usr/include/ -all: - $(CC) $(CFLAGS) memfd_test.c -o memfd_test - TEST_PROGS := memfd_test +all: $(TEST_PROGS) + include ../lib.mk -build_fuse: - $(CC) $(CFLAGS) fuse_mnt.c `pkg-config fuse --cflags --libs` -o fuse_mnt - $(CC) $(CFLAGS) fuse_test.c -o fuse_test +build_fuse: fuse_mnt fuse_test + +fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags) +fuse_mnt: LDFLAGS += $(shell pkg-config fuse --libs) run_fuse: build_fuse @./run_fuse_test.sh || echo "fuse_test: [FAIL]" diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c index 0b9eafb7ab7b..26546892cd54 100644 --- a/tools/testing/selftests/memfd/memfd_test.c +++ b/tools/testing/selftests/memfd/memfd_test.c @@ -15,10 +15,11 @@ #include <sys/mman.h> #include <sys/stat.h> #include <sys/syscall.h> +#include <sys/wait.h> #include <unistd.h> #define MFD_DEF_SIZE 8192 -#define STACK_SIZE 65535 +#define STACK_SIZE 65536 static int sys_memfd_create(const char *name, unsigned int flags) diff --git a/tools/testing/selftests/memfd/run_fuse_test.sh b/tools/testing/selftests/memfd/run_fuse_test.sh index 69b930e1e041..69b930e1e041 100644..100755 --- a/tools/testing/selftests/memfd/run_fuse_test.sh +++ b/tools/testing/selftests/memfd/run_fuse_test.sh diff --git a/tools/testing/selftests/mqueue/mq_open_tests.c b/tools/testing/selftests/mqueue/mq_open_tests.c index 9c1a5d359055..e0a74bd207a5 100644 --- a/tools/testing/selftests/mqueue/mq_open_tests.c +++ b/tools/testing/selftests/mqueue/mq_open_tests.c @@ -31,6 +31,7 @@ #include <sys/resource.h> #include <sys/stat.h> #include <mqueue.h> +#include <error.h> static char *usage = "Usage:\n" diff --git a/tools/testing/selftests/mqueue/mq_perf_tests.c b/tools/testing/selftests/mqueue/mq_perf_tests.c index 8519e9ee97e3..8188f72de93c 100644 --- a/tools/testing/selftests/mqueue/mq_perf_tests.c +++ b/tools/testing/selftests/mqueue/mq_perf_tests.c @@ -37,6 +37,7 @@ #include <sys/stat.h> #include <mqueue.h> #include <popt.h> +#include <error.h> static char *usage = "Usage:\n" diff --git a/tools/testing/selftests/pstore/Makefile b/tools/testing/selftests/pstore/Makefile new file mode 100644 index 000000000000..bd7abe24ea08 --- /dev/null +++ b/tools/testing/selftests/pstore/Makefile @@ -0,0 +1,15 @@ +# Makefile for pstore selftests. +# Expects pstore backend is registered. + +all: + +TEST_PROGS := pstore_tests pstore_post_reboot_tests +TEST_FILES := common_tests pstore_crash_test + +include ../lib.mk + +run_crash: + @sh pstore_crash_test || { echo "pstore_crash_test: [FAIL]"; exit 1; } + +clean: + rm -rf logs/* *uuid diff --git a/tools/testing/selftests/pstore/common_tests b/tools/testing/selftests/pstore/common_tests new file mode 100755 index 000000000000..3ea64d7cf1cd --- /dev/null +++ b/tools/testing/selftests/pstore/common_tests @@ -0,0 +1,83 @@ +#!/bin/sh + +# common_tests - Shell script commonly used by pstore test scripts +# +# Copyright (C) Hitachi Ltd., 2015 +# Written by Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com> +# +# Released under the terms of the GPL v2. + +# Utilities +errexit() { # message + echo "Error: $1" 1>&2 + exit 1 +} + +absdir() { # file_path + (cd `dirname $1`; pwd) +} + +show_result() { # result_value + if [ $1 -eq 0 ]; then + prlog "ok" + else + prlog "FAIL" + rc=1 + fi +} + +check_files_exist() { # type of pstorefs file + if [ -e ${1}-${backend}-0 ]; then + prlog "ok" + for f in `ls ${1}-${backend}-*`; do + prlog -e "\t${f}" + done + else + prlog "FAIL" + rc=1 + fi +} + +operate_files() { # tested value, files, operation + if [ $1 -eq 0 ]; then + prlog + for f in $2; do + prlog -ne "\t${f} ... " + # execute operation + $3 $f + show_result $? + done + else + prlog " ... FAIL" + rc=1 + fi +} + +# Parameters +TEST_STRING_PATTERN="Testing pstore: uuid=" +UUID=`cat /proc/sys/kernel/random/uuid` +TOP_DIR=`absdir $0` +LOG_DIR=$TOP_DIR/logs/`date +%Y%m%d-%H%M%S`_${UUID}/ +REBOOT_FLAG=$TOP_DIR/reboot_flag + +# Preparing logs +LOG_FILE=$LOG_DIR/`basename $0`.log +mkdir -p $LOG_DIR || errexit "Failed to make a log directory: $LOG_DIR" +date > $LOG_FILE +prlog() { # messages + /bin/echo "$@" | tee -a $LOG_FILE +} + +# Starting tests +rc=0 +prlog "=== Pstore unit tests (`basename $0`) ===" +prlog "UUID="$UUID + +prlog -n "Checking pstore backend is registered ... " +backend=`cat /sys/module/pstore/parameters/backend` +show_result $? +prlog -e "\tbackend=${backend}" +prlog -e "\tcmdline=`cat /proc/cmdline`" +if [ $rc -ne 0 ]; then + exit 1 +fi diff --git a/tools/testing/selftests/pstore/pstore_crash_test b/tools/testing/selftests/pstore/pstore_crash_test new file mode 100755 index 000000000000..1a4afe5c12b6 --- /dev/null +++ b/tools/testing/selftests/pstore/pstore_crash_test @@ -0,0 +1,30 @@ +#!/bin/sh + +# pstore_crash_test - Pstore test shell script which causes crash and reboot +# +# Copyright (C) Hitachi Ltd., 2015 +# Written by Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com> +# +# Released under the terms of the GPL v2. + +# exit if pstore backend is not registered +. ./common_tests + +prlog "Causing kernel crash ..." + +# enable all functions triggered by sysrq +echo 1 > /proc/sys/kernel/sysrq +# setting to reboot in 3 seconds after panic +echo 3 > /proc/sys/kernel/panic + +# save uuid file by different name because next test execution will replace it. +mv $TOP_DIR/uuid $TOP_DIR/prev_uuid + +# create a file as reboot flag +touch $REBOOT_FLAG +sync + +# cause crash +# Note: If you use kdump and want to see kmesg-* files after reboot, you should +# specify 'crash_kexec_post_notifiers' in 1st kernel's cmdline. +echo c > /proc/sysrq-trigger diff --git a/tools/testing/selftests/pstore/pstore_post_reboot_tests b/tools/testing/selftests/pstore/pstore_post_reboot_tests new file mode 100755 index 000000000000..6ccb154cb4aa --- /dev/null +++ b/tools/testing/selftests/pstore/pstore_post_reboot_tests @@ -0,0 +1,77 @@ +#!/bin/sh + +# pstore_post_reboot_tests - Check pstore's behavior after crash/reboot +# +# Copyright (C) Hitachi Ltd., 2015 +# Written by Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com> +# +# Released under the terms of the GPL v2. + +. ./common_tests + +if [ -e $REBOOT_FLAG ]; then + rm $REBOOT_FLAG +else + prlog "pstore_crash_test has not been executed yet. we skip further tests." + exit 0 +fi + +prlog -n "Mounting pstore filesystem ... " +mount_info=`grep pstore /proc/mounts` +if [ $? -eq 0 ]; then + mount_point=`echo ${mount_info} | cut -d' ' -f2 | head -n1` + prlog "ok" +else + mount none /sys/fs/pstore -t pstore + if [ $? -eq 0 ]; then + mount_point=`grep pstore /proc/mounts | cut -d' ' -f2 | head -n1` + prlog "ok" + else + prlog "FAIL" + exit 1 + fi +fi + +cd ${mount_point} + +prlog -n "Checking dmesg files exist in pstore filesystem ... " +check_files_exist dmesg + +prlog -n "Checking console files exist in pstore filesystem ... " +check_files_exist console + +prlog -n "Checking pmsg files exist in pstore filesystem ... " +check_files_exist pmsg + +prlog -n "Checking dmesg files contain oops end marker" +grep_end_trace() { + grep -q "\---\[ end trace" $1 +} +files=`ls dmesg-${backend}-*` +operate_files $? "$files" grep_end_trace + +prlog -n "Checking console file contains oops end marker ... " +grep -q "\---\[ end trace" console-${backend}-0 +show_result $? + +prlog -n "Checking pmsg file properly keeps the content written before crash ... " +prev_uuid=`cat $TOP_DIR/prev_uuid` +if [ $? -eq 0 ]; then + nr_matched=`grep -c "$TEST_STRING_PATTERN" pmsg-${backend}-0` + if [ $nr_matched -eq 1 ]; then + grep -q "$TEST_STRING_PATTERN"$prev_uuid pmsg-${backend}-0 + show_result $? + else + prlog "FAIL" + rc=1 + fi +else + prlog "FAIL" + rc=1 +fi + +prlog -n "Removing all files in pstore filesystem " +files=`ls *-${backend}-*` +operate_files $? "$files" rm + +exit $rc diff --git a/tools/testing/selftests/pstore/pstore_tests b/tools/testing/selftests/pstore/pstore_tests new file mode 100755 index 000000000000..f25d2a349a60 --- /dev/null +++ b/tools/testing/selftests/pstore/pstore_tests @@ -0,0 +1,30 @@ +#!/bin/sh + +# pstore_tests - Check pstore's behavior before crash/reboot +# +# Copyright (C) Hitachi Ltd., 2015 +# Written by Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com> +# +# Released under the terms of the GPL v2. + +. ./common_tests + +prlog -n "Checking pstore console is registered ... " +dmesg | grep -q "console \[pstore" +show_result $? + +prlog -n "Checking /dev/pmsg0 exists ... " +test -e /dev/pmsg0 +show_result $? + +prlog -n "Writing unique string to /dev/pmsg0 ... " +if [ -e "/dev/pmsg0" ]; then + echo "${TEST_STRING_PATTERN}""$UUID" > /dev/pmsg0 + show_result $? + echo "$UUID" > $TOP_DIR/uuid +else + prlog "FAIL" + rc=1 +fi + +exit $rc diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 770f47adf295..e38cc54942db 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -19,15 +19,19 @@ #include <linux/prctl.h> #include <linux/ptrace.h> #include <linux/seccomp.h> -#include <poll.h> #include <pthread.h> #include <semaphore.h> #include <signal.h> #include <stddef.h> #include <stdbool.h> #include <string.h> +#include <time.h> #include <linux/elf.h> #include <sys/uio.h> +#include <sys/utsname.h> +#include <sys/fcntl.h> +#include <sys/mman.h> +#include <sys/times.h> #define _GNU_SOURCE #include <unistd.h> @@ -428,14 +432,16 @@ TEST_SIGNAL(KILL_one, SIGSYS) TEST_SIGNAL(KILL_one_arg_one, SIGSYS) { + void *fatal_address; struct sock_filter filter[] = { BPF_STMT(BPF_LD|BPF_W|BPF_ABS, offsetof(struct seccomp_data, nr)), - BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0), + BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_times, 1, 0), BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), /* Only both with lower 32-bit for now. */ BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(0)), - BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x0C0FFEE, 0, 1), + BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, + (unsigned long)&fatal_address, 0, 1), BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL), BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), }; @@ -445,7 +451,8 @@ TEST_SIGNAL(KILL_one_arg_one, SIGSYS) }; long ret; pid_t parent = getppid(); - pid_t pid = getpid(); + struct tms timebuf; + clock_t clock = times(&timebuf); ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); ASSERT_EQ(0, ret); @@ -454,17 +461,22 @@ TEST_SIGNAL(KILL_one_arg_one, SIGSYS) ASSERT_EQ(0, ret); EXPECT_EQ(parent, syscall(__NR_getppid)); - EXPECT_EQ(pid, syscall(__NR_getpid)); - /* getpid() should never return. */ - EXPECT_EQ(0, syscall(__NR_getpid, 0x0C0FFEE)); + EXPECT_LE(clock, syscall(__NR_times, &timebuf)); + /* times() should never return. */ + EXPECT_EQ(0, syscall(__NR_times, &fatal_address)); } TEST_SIGNAL(KILL_one_arg_six, SIGSYS) { +#ifndef __NR_mmap2 + int sysno = __NR_mmap; +#else + int sysno = __NR_mmap2; +#endif struct sock_filter filter[] = { BPF_STMT(BPF_LD|BPF_W|BPF_ABS, offsetof(struct seccomp_data, nr)), - BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0), + BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, sysno, 1, 0), BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), /* Only both with lower 32-bit for now. */ BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(5)), @@ -478,7 +490,8 @@ TEST_SIGNAL(KILL_one_arg_six, SIGSYS) }; long ret; pid_t parent = getppid(); - pid_t pid = getpid(); + int fd; + void *map1, *map2; ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); ASSERT_EQ(0, ret); @@ -486,10 +499,22 @@ TEST_SIGNAL(KILL_one_arg_six, SIGSYS) ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog); ASSERT_EQ(0, ret); + fd = open("/dev/zero", O_RDONLY); + ASSERT_NE(-1, fd); + EXPECT_EQ(parent, syscall(__NR_getppid)); - EXPECT_EQ(pid, syscall(__NR_getpid)); - /* getpid() should never return. */ - EXPECT_EQ(0, syscall(__NR_getpid, 1, 2, 3, 4, 5, 0x0C0FFEE)); + map1 = (void *)syscall(sysno, + NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, PAGE_SIZE); + EXPECT_NE(MAP_FAILED, map1); + /* mmap2() should never return. */ + map2 = (void *)syscall(sysno, + NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, 0x0C0FFEE); + EXPECT_EQ(MAP_FAILED, map2); + + /* The test failed, so clean up the resources. */ + munmap(map1, PAGE_SIZE); + munmap(map2, PAGE_SIZE); + close(fd); } /* TODO(wad) add 64-bit versus 32-bit arg tests. */ @@ -1247,8 +1272,8 @@ void change_syscall(struct __test_metadata *_metadata, ret = ptrace(PTRACE_GETREGSET, tracee, NT_PRSTATUS, &iov); EXPECT_EQ(0, ret); -#if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \ - defined(__powerpc__) || defined(__s390__) +#if defined(__x86_64__) || defined(__i386__) || defined(__powerpc__) || \ + defined(__s390__) { regs.SYSCALL_NUM = syscall; } @@ -1262,6 +1287,18 @@ void change_syscall(struct __test_metadata *_metadata, EXPECT_EQ(0, ret); } +#elif defined(__aarch64__) +# ifndef NT_ARM_SYSTEM_CALL +# define NT_ARM_SYSTEM_CALL 0x404 +# endif + { + iov.iov_base = &syscall; + iov.iov_len = sizeof(syscall); + ret = ptrace(PTRACE_SETREGSET, tracee, NT_ARM_SYSTEM_CALL, + &iov); + EXPECT_EQ(0, ret); + } + #else ASSERT_EQ(1, 0) { TH_LOG("How is the syscall changed on this architecture?"); @@ -1272,6 +1309,8 @@ void change_syscall(struct __test_metadata *_metadata, if (syscall == -1) regs.SYSCALL_RET = 1; + iov.iov_base = ®s; + iov.iov_len = sizeof(regs); ret = ptrace(PTRACE_SETREGSET, tracee, NT_PRSTATUS, &iov); EXPECT_EQ(0, ret); } @@ -2005,20 +2044,25 @@ TEST(syscall_restart) BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 5, 0), BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_exit, 4, 0), BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_rt_sigreturn, 3, 0), - BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_poll, 4, 0), + BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_nanosleep, 4, 0), BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_restart_syscall, 4, 0), /* Allow __NR_write for easy logging. */ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_write, 0, 1), BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL), - BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x100), /* poll */ - BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x200), /* restart */ + /* The nanosleep jump target. */ + BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x100), + /* The restart_syscall jump target. */ + BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x200), }; struct sock_fprog prog = { .len = (unsigned short)ARRAY_SIZE(filter), .filter = filter, }; +#if defined(__arm__) + struct utsname utsbuf; +#endif ASSERT_EQ(0, pipe(pipefd)); @@ -2027,10 +2071,7 @@ TEST(syscall_restart) if (child_pid == 0) { /* Child uses EXPECT not ASSERT to deliver status correctly. */ char buf = ' '; - struct pollfd fds = { - .fd = pipefd[0], - .events = POLLIN, - }; + struct timespec timeout = { }; /* Attach parent as tracer and stop. */ EXPECT_EQ(0, ptrace(PTRACE_TRACEME)); @@ -2054,10 +2095,11 @@ TEST(syscall_restart) TH_LOG("Failed to get sync data from read()"); } - /* Start poll to be interrupted. */ + /* Start nanosleep to be interrupted. */ + timeout.tv_sec = 1; errno = 0; - EXPECT_EQ(1, poll(&fds, 1, -1)) { - TH_LOG("Call to poll() failed (errno %d)", errno); + EXPECT_EQ(0, nanosleep(&timeout, NULL)) { + TH_LOG("Call to nanosleep() failed (errno %d)", errno); } /* Read final sync from parent. */ @@ -2082,14 +2124,14 @@ TEST(syscall_restart) ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0)); ASSERT_EQ(1, write(pipefd[1], ".", 1)); - /* Wait for poll() to start. */ + /* Wait for nanosleep() to start. */ ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0)); ASSERT_EQ(true, WIFSTOPPED(status)); ASSERT_EQ(SIGTRAP, WSTOPSIG(status)); ASSERT_EQ(PTRACE_EVENT_SECCOMP, (status >> 16)); ASSERT_EQ(0, ptrace(PTRACE_GETEVENTMSG, child_pid, NULL, &msg)); ASSERT_EQ(0x100, msg); - EXPECT_EQ(__NR_poll, get_syscall(_metadata, child_pid)); + EXPECT_EQ(__NR_nanosleep, get_syscall(_metadata, child_pid)); /* Might as well check siginfo for sanity while we're here. */ ASSERT_EQ(0, ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &info)); @@ -2100,7 +2142,7 @@ TEST(syscall_restart) /* Verify signal delivery came from child (seccomp-triggered). */ EXPECT_EQ(child_pid, info.si_pid); - /* Interrupt poll with SIGSTOP (which we'll need to handle). */ + /* Interrupt nanosleep with SIGSTOP (which we'll need to handle). */ ASSERT_EQ(0, kill(child_pid, SIGSTOP)); ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0)); ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0)); @@ -2110,7 +2152,7 @@ TEST(syscall_restart) ASSERT_EQ(0, ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &info)); EXPECT_EQ(getpid(), info.si_pid); - /* Restart poll with SIGCONT, which triggers restart_syscall. */ + /* Restart nanosleep with SIGCONT, which triggers restart_syscall. */ ASSERT_EQ(0, kill(child_pid, SIGCONT)); ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0)); ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0)); @@ -2124,16 +2166,25 @@ TEST(syscall_restart) ASSERT_EQ(SIGTRAP, WSTOPSIG(status)); ASSERT_EQ(PTRACE_EVENT_SECCOMP, (status >> 16)); ASSERT_EQ(0, ptrace(PTRACE_GETEVENTMSG, child_pid, NULL, &msg)); + ASSERT_EQ(0x200, msg); ret = get_syscall(_metadata, child_pid); #if defined(__arm__) - /* FIXME: ARM does not expose true syscall in registers. */ - EXPECT_EQ(__NR_poll, ret); -#else - EXPECT_EQ(__NR_restart_syscall, ret); + /* + * FIXME: + * - native ARM registers do NOT expose true syscall. + * - compat ARM registers on ARM64 DO expose true syscall. + */ + ASSERT_EQ(0, uname(&utsbuf)); + if (strncmp(utsbuf.machine, "arm", 3) == 0) { + EXPECT_EQ(__NR_nanosleep, ret); + } else #endif + { + EXPECT_EQ(__NR_restart_syscall, ret); + } - /* Write again to end poll. */ + /* Write again to end test. */ ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0)); ASSERT_EQ(1, write(pipefd[1], "!", 1)); EXPECT_EQ(0, close(pipefd[1])); diff --git a/tools/testing/selftests/static_keys/test_static_keys.sh b/tools/testing/selftests/static_keys/test_static_keys.sh index 1261e3fa1e3a..1261e3fa1e3a 100644..100755 --- a/tools/testing/selftests/static_keys/test_static_keys.sh +++ b/tools/testing/selftests/static_keys/test_static_keys.sh diff --git a/tools/testing/selftests/timers/nanosleep.c b/tools/testing/selftests/timers/nanosleep.c index 8a3c29de7d49..ff942ff7c9b3 100644 --- a/tools/testing/selftests/timers/nanosleep.c +++ b/tools/testing/selftests/timers/nanosleep.c @@ -19,6 +19,7 @@ * GNU General Public License for more details. */ +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <time.h> diff --git a/tools/testing/selftests/timers/rtctest.c b/tools/testing/selftests/timers/rtctest.c index d80ae852334d..624bce51b27d 100644 --- a/tools/testing/selftests/timers/rtctest.c +++ b/tools/testing/selftests/timers/rtctest.c @@ -61,7 +61,7 @@ int main(int argc, char **argv) /* Turn on update interrupts (one per second) */ retval = ioctl(fd, RTC_UIE_ON, 0); if (retval == -1) { - if (errno == ENOTTY) { + if (errno == EINVAL) { fprintf(stderr, "\n...Update IRQs not supported.\n"); goto test_READ; diff --git a/tools/testing/selftests/vm/mlock2-tests.c b/tools/testing/selftests/vm/mlock2-tests.c index 4431994aade2..02ca5e0177c5 100644 --- a/tools/testing/selftests/vm/mlock2-tests.c +++ b/tools/testing/selftests/vm/mlock2-tests.c @@ -1,3 +1,4 @@ +#define _GNU_SOURCE #include <sys/mman.h> #include <stdint.h> #include <stdio.h> @@ -276,8 +277,8 @@ out: return ret; } -#define PRESENT_BIT 0x8000000000000000 -#define PFN_MASK 0x007FFFFFFFFFFFFF +#define PRESENT_BIT 0x8000000000000000ULL +#define PFN_MASK 0x007FFFFFFFFFFFFFULL #define UNEVICTABLE_BIT (1UL << 18) static int lock_check(char *map) diff --git a/tools/testing/selftests/vm/run_vmtests b/tools/testing/selftests/vm/run_vmtests index 2df21b3bb26d..e11968b3677e 100755 --- a/tools/testing/selftests/vm/run_vmtests +++ b/tools/testing/selftests/vm/run_vmtests @@ -20,13 +20,26 @@ done < /proc/meminfo if [ -n "$freepgs" ] && [ -n "$pgsize" ]; then nr_hugepgs=`cat /proc/sys/vm/nr_hugepages` needpgs=`expr $needmem / $pgsize` - if [ $freepgs -lt $needpgs ]; then + tries=2 + while [ $tries -gt 0 ] && [ $freepgs -lt $needpgs ]; do lackpgs=$(( $needpgs - $freepgs )) + echo 3 > /proc/sys/vm/drop_caches echo $(( $lackpgs + $nr_hugepgs )) > /proc/sys/vm/nr_hugepages if [ $? -ne 0 ]; then echo "Please run this test as root" exit 1 fi + while read name size unit; do + if [ "$name" = "HugePages_Free:" ]; then + freepgs=$size + fi + done < /proc/meminfo + tries=$((tries - 1)) + done + if [ $freepgs -lt $needpgs ]; then + printf "Not enough huge pages available (%d < %d)\n" \ + $freepgs $needpgs + exit 1 fi else echo "no hugetlbfs support in kernel?" diff --git a/tools/thermal/tmon/Makefile b/tools/thermal/tmon/Makefile index 2e83dd3655a2..3a961e998281 100644 --- a/tools/thermal/tmon/Makefile +++ b/tools/thermal/tmon/Makefile @@ -22,6 +22,9 @@ TMON_LIBS += $(shell pkg-config --libs $(STATIC) panelw ncursesw 2> /dev/null || pkg-config --libs $(STATIC) panel ncurses 2> /dev/null || \ echo -lpanel -lncurses) +CFLAGS += $(shell pkg-config --cflags $(STATIC) panelw ncursesw 2> /dev/null || \ + pkg-config --cflags $(STATIC) panel ncurses 2> /dev/null) + OBJS = tmon.o tui.o sysfs.o pid.o OBJS += |