aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-08-24 16:32:24 -0400
committerIngo Molnar <mingo@kernel.org>2014-08-24 16:32:24 -0400
commit83bc90e11576f9c100f8ef4ba2bcd0b89212e3fb (patch)
treee59186b4d315c80255851e0d204143ecc21399a0 /tools
parente21ded5ecc531a64d6fc0c1693285e890b4e9569 (diff)
parent451fd72219dd6f3355e2d036c598544c760ee532 (diff)
Merge branch 'linus' into perf/core, to fix conflicts
Conflicts: arch/x86/kernel/cpu/perf_event_intel_uncore*.c Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/hv/hv_fcopy_daemon.c3
-rw-r--r--tools/power/acpi/Makefile5
-rw-r--r--tools/power/acpi/common/cmfsize.c20
-rw-r--r--tools/power/acpi/common/getopt.c14
-rw-r--r--tools/power/acpi/os_specific/service_layers/oslibcfs.c214
-rw-r--r--tools/power/acpi/os_specific/service_layers/oslinuxtbl.c48
-rw-r--r--tools/power/acpi/os_specific/service_layers/osunixxf.c1311
-rw-r--r--tools/power/acpi/tools/acpidump/acpidump.h3
-rw-r--r--tools/power/acpi/tools/acpidump/apdump.c108
-rw-r--r--tools/power/acpi/tools/acpidump/apfiles.c92
-rw-r--r--tools/power/acpi/tools/acpidump/apmain.c96
-rw-r--r--tools/power/cpupower/bench/parse.c39
-rw-r--r--tools/power/cpupower/utils/cpufreq-set.c11
-rw-r--r--tools/power/cpupower/utils/helpers/sysfs.c2
-rw-r--r--tools/power/cpupower/utils/idle_monitor/mperf_monitor.c2
-rw-r--r--tools/power/x86/turbostat/turbostat.c80
-rw-r--r--tools/testing/selftests/Makefile21
-rw-r--r--tools/testing/selftests/README.txt27
-rw-r--r--tools/testing/selftests/cpu-hotplug/Makefile3
-rw-r--r--tools/testing/selftests/cpu-hotplug/on-off-test.sh52
-rw-r--r--tools/testing/selftests/firmware/Makefile27
-rw-r--r--tools/testing/selftests/firmware/fw_filesystem.sh62
-rw-r--r--tools/testing/selftests/firmware/fw_userhelper.sh89
-rw-r--r--tools/testing/selftests/kcmp/kcmp_test.c2
-rw-r--r--tools/testing/selftests/memfd/.gitignore4
-rw-r--r--tools/testing/selftests/memfd/Makefile41
-rw-r--r--tools/testing/selftests/memfd/fuse_mnt.c110
-rw-r--r--tools/testing/selftests/memfd/fuse_test.c311
-rw-r--r--tools/testing/selftests/memfd/memfd_test.c913
-rw-r--r--tools/testing/selftests/memfd/run_fuse_test.sh14
-rw-r--r--tools/testing/selftests/memory-hotplug/Makefile3
-rw-r--r--tools/testing/selftests/memory-hotplug/on-off-test.sh8
-rw-r--r--tools/testing/selftests/mount/Makefile17
-rw-r--r--tools/testing/selftests/mount/unprivileged-remount-test.c242
-rw-r--r--tools/testing/selftests/mqueue/Makefile4
-rw-r--r--tools/testing/selftests/mqueue/mq_open_tests.c20
-rw-r--r--tools/testing/selftests/mqueue/mq_perf_tests.c40
-rw-r--r--tools/testing/selftests/powerpc/Makefile10
-rw-r--r--tools/testing/selftests/powerpc/pmu/Makefile19
-rw-r--r--tools/testing/selftests/powerpc/pmu/count_instructions.c30
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/Makefile5
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/busy_loop.S271
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c91
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/ebb.c261
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/ebb.h1
-rw-r--r--tools/testing/selftests/powerpc/pmu/l3_bank_test.c48
-rw-r--r--tools/testing/selftests/powerpc/pmu/lib.c50
-rw-r--r--tools/testing/selftests/powerpc/pmu/lib.h1
-rw-r--r--tools/testing/selftests/powerpc/pmu/per_event_excludes.c114
-rw-r--r--tools/testing/selftests/ptrace/peeksiginfo.c4
-rwxr-xr-xtools/time/udelay_test.sh66
-rw-r--r--tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c39
-rw-r--r--tools/usb/ffs-aio-example/multibuff/host_app/test.c27
-rw-r--r--tools/usb/ffs-aio-example/simple/device_app/aio_simple.c39
-rw-r--r--tools/usb/ffs-aio-example/simple/host_app/test.c27
55 files changed, 4601 insertions, 560 deletions
diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c
index fba1c75aa484..8f96b3ee0724 100644
--- a/tools/hv/hv_fcopy_daemon.c
+++ b/tools/hv/hv_fcopy_daemon.c
@@ -88,7 +88,8 @@ static int hv_start_fcopy(struct hv_start_fcopy *smsg)
88 } 88 }
89 } 89 }
90 90
91 target_fd = open(target_fname, O_RDWR | O_CREAT | O_CLOEXEC, 0744); 91 target_fd = open(target_fname,
92 O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0744);
92 if (target_fd == -1) { 93 if (target_fd == -1) {
93 syslog(LOG_INFO, "Open Failed: %s", strerror(errno)); 94 syslog(LOG_INFO, "Open Failed: %s", strerror(errno));
94 goto done; 95 goto done;
diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile
index e5a3c4be2a10..3d1537b93c64 100644
--- a/tools/power/acpi/Makefile
+++ b/tools/power/acpi/Makefile
@@ -108,13 +108,18 @@ DUMP_OBJS = \
108 apmain.o\ 108 apmain.o\
109 osunixdir.o\ 109 osunixdir.o\
110 osunixmap.o\ 110 osunixmap.o\
111 osunixxf.o\
111 tbprint.o\ 112 tbprint.o\
112 tbxfroot.o\ 113 tbxfroot.o\
113 utbuffer.o\ 114 utbuffer.o\
115 utdebug.o\
114 utexcep.o\ 116 utexcep.o\
117 utglobal.o\
115 utmath.o\ 118 utmath.o\
119 utprint.o\
116 utstring.o\ 120 utstring.o\
117 utxferror.o\ 121 utxferror.o\
122 oslibcfs.o\
118 oslinuxtbl.o\ 123 oslinuxtbl.o\
119 cmfsize.o\ 124 cmfsize.o\
120 getopt.o 125 getopt.o
diff --git a/tools/power/acpi/common/cmfsize.c b/tools/power/acpi/common/cmfsize.c
index 5140e5edae1f..f4b953354ff7 100644
--- a/tools/power/acpi/common/cmfsize.c
+++ b/tools/power/acpi/common/cmfsize.c
@@ -58,44 +58,46 @@ ACPI_MODULE_NAME("cmfsize")
58 * RETURN: File Size. On error, -1 (ACPI_UINT32_MAX) 58 * RETURN: File Size. On error, -1 (ACPI_UINT32_MAX)
59 * 59 *
60 * DESCRIPTION: Get the size of a file. Uses seek-to-EOF. File must be open. 60 * DESCRIPTION: Get the size of a file. Uses seek-to-EOF. File must be open.
61 * Does not disturb the current file pointer. Uses perror for 61 * Does not disturb the current file pointer.
62 * error messages.
63 * 62 *
64 ******************************************************************************/ 63 ******************************************************************************/
65u32 cm_get_file_size(FILE * file) 64u32 cm_get_file_size(ACPI_FILE file)
66{ 65{
67 long file_size; 66 long file_size;
68 long current_offset; 67 long current_offset;
68 acpi_status status;
69 69
70 /* Save the current file pointer, seek to EOF to obtain file size */ 70 /* Save the current file pointer, seek to EOF to obtain file size */
71 71
72 current_offset = ftell(file); 72 current_offset = acpi_os_get_file_offset(file);
73 if (current_offset < 0) { 73 if (current_offset < 0) {
74 goto offset_error; 74 goto offset_error;
75 } 75 }
76 76
77 if (fseek(file, 0, SEEK_END)) { 77 status = acpi_os_set_file_offset(file, 0, ACPI_FILE_END);
78 if (ACPI_FAILURE(status)) {
78 goto seek_error; 79 goto seek_error;
79 } 80 }
80 81
81 file_size = ftell(file); 82 file_size = acpi_os_get_file_offset(file);
82 if (file_size < 0) { 83 if (file_size < 0) {
83 goto offset_error; 84 goto offset_error;
84 } 85 }
85 86
86 /* Restore original file pointer */ 87 /* Restore original file pointer */
87 88
88 if (fseek(file, current_offset, SEEK_SET)) { 89 status = acpi_os_set_file_offset(file, current_offset, ACPI_FILE_BEGIN);
90 if (ACPI_FAILURE(status)) {
89 goto seek_error; 91 goto seek_error;
90 } 92 }
91 93
92 return ((u32)file_size); 94 return ((u32)file_size);
93 95
94offset_error: 96offset_error:
95 perror("Could not get file offset"); 97 acpi_log_error("Could not get file offset");
96 return (ACPI_UINT32_MAX); 98 return (ACPI_UINT32_MAX);
97 99
98seek_error: 100seek_error:
99 perror("Could not seek file"); 101 acpi_log_error("Could not set file offset");
100 return (ACPI_UINT32_MAX); 102 return (ACPI_UINT32_MAX);
101} 103}
diff --git a/tools/power/acpi/common/getopt.c b/tools/power/acpi/common/getopt.c
index a302f52e4fd3..2f0f34a36db4 100644
--- a/tools/power/acpi/common/getopt.c
+++ b/tools/power/acpi/common/getopt.c
@@ -51,14 +51,12 @@
51 * "f|" - Option has required single-char sub-options 51 * "f|" - Option has required single-char sub-options
52 */ 52 */
53 53
54#include <stdio.h>
55#include <string.h>
56#include <acpi/acpi.h> 54#include <acpi/acpi.h>
57#include "accommon.h" 55#include "accommon.h"
58#include "acapps.h" 56#include "acapps.h"
59 57
60#define ACPI_OPTION_ERROR(msg, badchar) \ 58#define ACPI_OPTION_ERROR(msg, badchar) \
61 if (acpi_gbl_opterr) {fprintf (stderr, "%s%c\n", msg, badchar);} 59 if (acpi_gbl_opterr) {acpi_log_error ("%s%c\n", msg, badchar);}
62 60
63int acpi_gbl_opterr = 1; 61int acpi_gbl_opterr = 1;
64int acpi_gbl_optind = 1; 62int acpi_gbl_optind = 1;
@@ -113,7 +111,7 @@ int acpi_getopt_argument(int argc, char **argv)
113 * PARAMETERS: argc, argv - from main 111 * PARAMETERS: argc, argv - from main
114 * opts - options info list 112 * opts - options info list
115 * 113 *
116 * RETURN: Option character or EOF 114 * RETURN: Option character or ACPI_OPT_END
117 * 115 *
118 * DESCRIPTION: Get the next option 116 * DESCRIPTION: Get the next option
119 * 117 *
@@ -128,10 +126,10 @@ int acpi_getopt(int argc, char **argv, char *opts)
128 if (acpi_gbl_optind >= argc || 126 if (acpi_gbl_optind >= argc ||
129 argv[acpi_gbl_optind][0] != '-' || 127 argv[acpi_gbl_optind][0] != '-' ||
130 argv[acpi_gbl_optind][1] == '\0') { 128 argv[acpi_gbl_optind][1] == '\0') {
131 return (EOF); 129 return (ACPI_OPT_END);
132 } else if (strcmp(argv[acpi_gbl_optind], "--") == 0) { 130 } else if (ACPI_STRCMP(argv[acpi_gbl_optind], "--") == 0) {
133 acpi_gbl_optind++; 131 acpi_gbl_optind++;
134 return (EOF); 132 return (ACPI_OPT_END);
135 } 133 }
136 } 134 }
137 135
@@ -142,7 +140,7 @@ int acpi_getopt(int argc, char **argv, char *opts)
142 /* Make sure that the option is legal */ 140 /* Make sure that the option is legal */
143 141
144 if (current_char == ':' || 142 if (current_char == ':' ||
145 (opts_ptr = strchr(opts, current_char)) == NULL) { 143 (opts_ptr = ACPI_STRCHR(opts, current_char)) == NULL) {
146 ACPI_OPTION_ERROR("Illegal option: -", current_char); 144 ACPI_OPTION_ERROR("Illegal option: -", current_char);
147 145
148 if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') { 146 if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
diff --git a/tools/power/acpi/os_specific/service_layers/oslibcfs.c b/tools/power/acpi/os_specific/service_layers/oslibcfs.c
new file mode 100644
index 000000000000..c13ff9c51d74
--- /dev/null
+++ b/tools/power/acpi/os_specific/service_layers/oslibcfs.c
@@ -0,0 +1,214 @@
1/******************************************************************************
2 *
3 * Module Name: oslibcfs - C library OSL for file I/O
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include <stdio.h>
46#include <stdarg.h>
47
48#define _COMPONENT ACPI_OS_SERVICES
49ACPI_MODULE_NAME("oslibcfs")
50
51/*******************************************************************************
52 *
53 * FUNCTION: acpi_os_open_file
54 *
55 * PARAMETERS: path - File path
56 * modes - File operation type
57 *
58 * RETURN: File descriptor.
59 *
60 * DESCRIPTION: Open a file for reading (ACPI_FILE_READING) or/and writing
61 * (ACPI_FILE_WRITING).
62 *
63 ******************************************************************************/
64ACPI_FILE acpi_os_open_file(const char *path, u8 modes)
65{
66 ACPI_FILE file;
67 u32 i = 0;
68 char modes_str[4];
69
70 if (modes & ACPI_FILE_READING) {
71 modes_str[i++] = 'r';
72 }
73 if (modes & ACPI_FILE_WRITING) {
74 modes_str[i++] = 'w';
75 }
76 if (modes & ACPI_FILE_BINARY) {
77 modes_str[i++] = 'b';
78 }
79
80 modes_str[i++] = '\0';
81
82 file = fopen(path, modes_str);
83 if (!file) {
84 perror("Could not open file");
85 }
86
87 return (file);
88}
89
90/*******************************************************************************
91 *
92 * FUNCTION: acpi_os_close_file
93 *
94 * PARAMETERS: file - An open file descriptor
95 *
96 * RETURN: None.
97 *
98 * DESCRIPTION: Close a file opened via acpi_os_open_file.
99 *
100 ******************************************************************************/
101
102void acpi_os_close_file(ACPI_FILE file)
103{
104 fclose(file);
105}
106
107/*******************************************************************************
108 *
109 * FUNCTION: acpi_os_read_file
110 *
111 * PARAMETERS: file - An open file descriptor
112 * buffer - Data buffer
113 * size - Data block size
114 * count - Number of data blocks
115 *
116 * RETURN: Number of bytes actually read.
117 *
118 * DESCRIPTION: Read from a file.
119 *
120 ******************************************************************************/
121
122int
123acpi_os_read_file(ACPI_FILE file, void *buffer, acpi_size size, acpi_size count)
124{
125 int length;
126
127 length = fread(buffer, size, count, file);
128 if (length < 0) {
129 perror("Error reading file");
130 }
131
132 return (length);
133}
134
135/*******************************************************************************
136 *
137 * FUNCTION: acpi_os_write_file
138 *
139 * PARAMETERS: file - An open file descriptor
140 * buffer - Data buffer
141 * size - Data block size
142 * count - Number of data blocks
143 *
144 * RETURN: Number of bytes actually written.
145 *
146 * DESCRIPTION: Write to a file.
147 *
148 ******************************************************************************/
149
150int
151acpi_os_write_file(ACPI_FILE file,
152 void *buffer, acpi_size size, acpi_size count)
153{
154 int length;
155
156 length = fwrite(buffer, size, count, file);
157 if (length < 0) {
158 perror("Error writing file");
159 }
160
161 return (length);
162}
163
164/*******************************************************************************
165 *
166 * FUNCTION: acpi_os_get_file_offset
167 *
168 * PARAMETERS: file - An open file descriptor
169 *
170 * RETURN: Current file pointer position.
171 *
172 * DESCRIPTION: Get current file offset.
173 *
174 ******************************************************************************/
175
176long acpi_os_get_file_offset(ACPI_FILE file)
177{
178 long offset;
179
180 offset = ftell(file);
181 return (offset);
182}
183
184/*******************************************************************************
185 *
186 * FUNCTION: acpi_os_set_file_offset
187 *
188 * PARAMETERS: file - An open file descriptor
189 * offset - New file offset
190 * from - From begin/end of file
191 *
192 * RETURN: Status
193 *
194 * DESCRIPTION: Set current file offset.
195 *
196 ******************************************************************************/
197
198acpi_status acpi_os_set_file_offset(ACPI_FILE file, long offset, u8 from)
199{
200 int ret = 0;
201
202 if (from == ACPI_FILE_BEGIN) {
203 ret = fseek(file, offset, SEEK_SET);
204 }
205 if (from == ACPI_FILE_END) {
206 ret = fseek(file, offset, SEEK_END);
207 }
208
209 if (ret < 0) {
210 return (AE_ERROR);
211 } else {
212 return (AE_OK);
213 }
214}
diff --git a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
index 28c52008e854..0dc2485dedf5 100644
--- a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
+++ b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
@@ -77,6 +77,9 @@ osl_map_table(acpi_size address,
77 77
78static void osl_unmap_table(struct acpi_table_header *table); 78static void osl_unmap_table(struct acpi_table_header *table);
79 79
80static acpi_physical_address
81osl_find_rsdp_via_efi_by_keyword(FILE * file, const char *keyword);
82
80static acpi_physical_address osl_find_rsdp_via_efi(void); 83static acpi_physical_address osl_find_rsdp_via_efi(void);
81 84
82static acpi_status osl_load_rsdp(void); 85static acpi_status osl_load_rsdp(void);
@@ -417,6 +420,38 @@ acpi_os_get_table_by_index(u32 index,
417 420
418/****************************************************************************** 421/******************************************************************************
419 * 422 *
423 * FUNCTION: osl_find_rsdp_via_efi_by_keyword
424 *
425 * PARAMETERS: keyword - Character string indicating ACPI GUID version
426 * in the EFI table
427 *
428 * RETURN: RSDP address if found
429 *
430 * DESCRIPTION: Find RSDP address via EFI using keyword indicating the ACPI
431 * GUID version.
432 *
433 *****************************************************************************/
434
435static acpi_physical_address
436osl_find_rsdp_via_efi_by_keyword(FILE * file, const char *keyword)
437{
438 char buffer[80];
439 unsigned long long address = 0;
440 char format[32];
441
442 snprintf(format, 32, "%s=%s", keyword, "%llx");
443 fseek(file, 0, SEEK_SET);
444 while (fgets(buffer, 80, file)) {
445 if (sscanf(buffer, format, &address) == 1) {
446 break;
447 }
448 }
449
450 return ((acpi_physical_address) (address));
451}
452
453/******************************************************************************
454 *
420 * FUNCTION: osl_find_rsdp_via_efi 455 * FUNCTION: osl_find_rsdp_via_efi
421 * 456 *
422 * PARAMETERS: None 457 * PARAMETERS: None
@@ -430,20 +465,19 @@ acpi_os_get_table_by_index(u32 index,
430static acpi_physical_address osl_find_rsdp_via_efi(void) 465static acpi_physical_address osl_find_rsdp_via_efi(void)
431{ 466{
432 FILE *file; 467 FILE *file;
433 char buffer[80]; 468 acpi_physical_address address = 0;
434 unsigned long address = 0;
435 469
436 file = fopen(EFI_SYSTAB, "r"); 470 file = fopen(EFI_SYSTAB, "r");
437 if (file) { 471 if (file) {
438 while (fgets(buffer, 80, file)) { 472 address = osl_find_rsdp_via_efi_by_keyword(file, "ACPI20");
439 if (sscanf(buffer, "ACPI20=0x%lx", &address) == 1) { 473 if (!address) {
440 break; 474 address =
441 } 475 osl_find_rsdp_via_efi_by_keyword(file, "ACPI");
442 } 476 }
443 fclose(file); 477 fclose(file);
444 } 478 }
445 479
446 return ((acpi_physical_address) (address)); 480 return (address);
447} 481}
448 482
449/****************************************************************************** 483/******************************************************************************
diff --git a/tools/power/acpi/os_specific/service_layers/osunixxf.c b/tools/power/acpi/os_specific/service_layers/osunixxf.c
new file mode 100644
index 000000000000..60b58cd18410
--- /dev/null
+++ b/tools/power/acpi/os_specific/service_layers/osunixxf.c
@@ -0,0 +1,1311 @@
1/******************************************************************************
2 *
3 * Module Name: osunixxf - UNIX OSL interfaces
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44/*
45 * These interfaces are required in order to compile the ASL compiler and the
46 * various ACPICA tools under Linux or other Unix-like system.
47 */
48#include <acpi/acpi.h>
49#include "accommon.h"
50#include "amlcode.h"
51#include "acparser.h"
52#include "acdebug.h"
53
54#include <stdio.h>
55#include <stdlib.h>
56#include <stdarg.h>
57#include <unistd.h>
58#include <sys/time.h>
59#include <semaphore.h>
60#include <pthread.h>
61#include <errno.h>
62
63#define _COMPONENT ACPI_OS_SERVICES
64ACPI_MODULE_NAME("osunixxf")
65
66u8 acpi_gbl_debug_timeout = FALSE;
67
68/* Upcalls to acpi_exec */
69
70void
71ae_table_override(struct acpi_table_header *existing_table,
72 struct acpi_table_header **new_table);
73
74typedef void *(*PTHREAD_CALLBACK) (void *);
75
76/* Buffer used by acpi_os_vprintf */
77
78#define ACPI_VPRINTF_BUFFER_SIZE 512
79#define _ASCII_NEWLINE '\n'
80
81/* Terminal support for acpi_exec only */
82
83#ifdef ACPI_EXEC_APP
84#include <termios.h>
85
86struct termios original_term_attributes;
87int term_attributes_were_set = 0;
88
89acpi_status acpi_ut_read_line(char *buffer, u32 buffer_length, u32 *bytes_read);
90
91static void os_enter_line_edit_mode(void);
92
93static void os_exit_line_edit_mode(void);
94
95/******************************************************************************
96 *
97 * FUNCTION: os_enter_line_edit_mode, os_exit_line_edit_mode
98 *
99 * PARAMETERS: None
100 *
101 * RETURN: None
102 *
103 * DESCRIPTION: Enter/Exit the raw character input mode for the terminal.
104 *
105 * Interactive line-editing support for the AML debugger. Used with the
106 * common/acgetline module.
107 *
108 * readline() is not used because of non-portability. It is not available
109 * on all systems, and if it is, often the package must be manually installed.
110 *
111 * Therefore, we use the POSIX tcgetattr/tcsetattr and do the minimal line
112 * editing that we need in acpi_os_get_line.
113 *
114 * If the POSIX tcgetattr/tcsetattr interfaces are unavailable, these
115 * calls will also work:
116 * For os_enter_line_edit_mode: system ("stty cbreak -echo")
117 * For os_exit_line_edit_mode: system ("stty cooked echo")
118 *
119 *****************************************************************************/
120
121static void os_enter_line_edit_mode(void)
122{
123 struct termios local_term_attributes;
124
125 /* Get and keep the original attributes */
126
127 if (tcgetattr(STDIN_FILENO, &original_term_attributes)) {
128 fprintf(stderr, "Could not get terminal attributes!\n");
129 return;
130 }
131
132 /* Set the new attributes to enable raw character input */
133
134 memcpy(&local_term_attributes, &original_term_attributes,
135 sizeof(struct termios));
136
137 local_term_attributes.c_lflag &= ~(ICANON | ECHO);
138 local_term_attributes.c_cc[VMIN] = 1;
139 local_term_attributes.c_cc[VTIME] = 0;
140
141 if (tcsetattr(STDIN_FILENO, TCSANOW, &local_term_attributes)) {
142 fprintf(stderr, "Could not set terminal attributes!\n");
143 return;
144 }
145
146 term_attributes_were_set = 1;
147}
148
149static void os_exit_line_edit_mode(void)
150{
151
152 if (!term_attributes_were_set) {
153 return;
154 }
155
156 /* Set terminal attributes back to the original values */
157
158 if (tcsetattr(STDIN_FILENO, TCSANOW, &original_term_attributes)) {
159 fprintf(stderr, "Could not restore terminal attributes!\n");
160 }
161}
162
163#else
164
165/* These functions are not needed for other ACPICA utilities */
166
167#define os_enter_line_edit_mode()
168#define os_exit_line_edit_mode()
169#endif
170
171/******************************************************************************
172 *
173 * FUNCTION: acpi_os_initialize, acpi_os_terminate
174 *
175 * PARAMETERS: None
176 *
177 * RETURN: Status
178 *
179 * DESCRIPTION: Initialize and terminate this module.
180 *
181 *****************************************************************************/
182
183acpi_status acpi_os_initialize(void)
184{
185 acpi_status status;
186
187 acpi_gbl_output_file = stdout;
188
189 os_enter_line_edit_mode();
190
191 status = acpi_os_create_lock(&acpi_gbl_print_lock);
192 if (ACPI_FAILURE(status)) {
193 return (status);
194 }
195
196 return (AE_OK);
197}
198
199acpi_status acpi_os_terminate(void)
200{
201
202 os_exit_line_edit_mode();
203 return (AE_OK);
204}
205
206#ifndef ACPI_USE_NATIVE_RSDP_POINTER
207/******************************************************************************
208 *
209 * FUNCTION: acpi_os_get_root_pointer
210 *
211 * PARAMETERS: None
212 *
213 * RETURN: RSDP physical address
214 *
215 * DESCRIPTION: Gets the ACPI root pointer (RSDP)
216 *
217 *****************************************************************************/
218
219acpi_physical_address acpi_os_get_root_pointer(void)
220{
221
222 return (0);
223}
224#endif
225
226/******************************************************************************
227 *
228 * FUNCTION: acpi_os_predefined_override
229 *
230 * PARAMETERS: init_val - Initial value of the predefined object
231 * new_val - The new value for the object
232 *
233 * RETURN: Status, pointer to value. Null pointer returned if not
234 * overriding.
235 *
236 * DESCRIPTION: Allow the OS to override predefined names
237 *
238 *****************************************************************************/
239
240acpi_status
241acpi_os_predefined_override(const struct acpi_predefined_names * init_val,
242 acpi_string * new_val)
243{
244
245 if (!init_val || !new_val) {
246 return (AE_BAD_PARAMETER);
247 }
248
249 *new_val = NULL;
250 return (AE_OK);
251}
252
253/******************************************************************************
254 *
255 * FUNCTION: acpi_os_table_override
256 *
257 * PARAMETERS: existing_table - Header of current table (probably
258 * firmware)
259 * new_table - Where an entire new table is returned.
260 *
261 * RETURN: Status, pointer to new table. Null pointer returned if no
262 * table is available to override
263 *
264 * DESCRIPTION: Return a different version of a table if one is available
265 *
266 *****************************************************************************/
267
268acpi_status
269acpi_os_table_override(struct acpi_table_header * existing_table,
270 struct acpi_table_header ** new_table)
271{
272
273 if (!existing_table || !new_table) {
274 return (AE_BAD_PARAMETER);
275 }
276
277 *new_table = NULL;
278
279#ifdef ACPI_EXEC_APP
280
281 ae_table_override(existing_table, new_table);
282 return (AE_OK);
283#else
284
285 return (AE_NO_ACPI_TABLES);
286#endif
287}
288
289/******************************************************************************
290 *
291 * FUNCTION: acpi_os_physical_table_override
292 *
293 * PARAMETERS: existing_table - Header of current table (probably firmware)
294 * new_address - Where new table address is returned
295 * (Physical address)
296 * new_table_length - Where new table length is returned
297 *
298 * RETURN: Status, address/length of new table. Null pointer returned
299 * if no table is available to override.
300 *
301 * DESCRIPTION: Returns AE_SUPPORT, function not used in user space.
302 *
303 *****************************************************************************/
304
305acpi_status
306acpi_os_physical_table_override(struct acpi_table_header * existing_table,
307 acpi_physical_address * new_address,
308 u32 *new_table_length)
309{
310
311 return (AE_SUPPORT);
312}
313
314/******************************************************************************
315 *
316 * FUNCTION: acpi_os_redirect_output
317 *
318 * PARAMETERS: destination - An open file handle/pointer
319 *
320 * RETURN: None
321 *
322 * DESCRIPTION: Causes redirect of acpi_os_printf and acpi_os_vprintf
323 *
324 *****************************************************************************/
325
326void acpi_os_redirect_output(void *destination)
327{
328
329 acpi_gbl_output_file = destination;
330}
331
332/******************************************************************************
333 *
334 * FUNCTION: acpi_os_printf
335 *
336 * PARAMETERS: fmt, ... - Standard printf format
337 *
338 * RETURN: None
339 *
340 * DESCRIPTION: Formatted output. Note: very similar to acpi_os_vprintf
341 * (performance), changes should be tracked in both functions.
342 *
343 *****************************************************************************/
344
345void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *fmt, ...)
346{
347 va_list args;
348 u8 flags;
349
350 flags = acpi_gbl_db_output_flags;
351 if (flags & ACPI_DB_REDIRECTABLE_OUTPUT) {
352
353 /* Output is directable to either a file (if open) or the console */
354
355 if (acpi_gbl_debug_file) {
356
357 /* Output file is open, send the output there */
358
359 va_start(args, fmt);
360 vfprintf(acpi_gbl_debug_file, fmt, args);
361 va_end(args);
362 } else {
363 /* No redirection, send output to console (once only!) */
364
365 flags |= ACPI_DB_CONSOLE_OUTPUT;
366 }
367 }
368
369 if (flags & ACPI_DB_CONSOLE_OUTPUT) {
370 va_start(args, fmt);
371 vfprintf(acpi_gbl_output_file, fmt, args);
372 va_end(args);
373 }
374}
375
376/******************************************************************************
377 *
378 * FUNCTION: acpi_os_vprintf
379 *
380 * PARAMETERS: fmt - Standard printf format
381 * args - Argument list
382 *
383 * RETURN: None
384 *
385 * DESCRIPTION: Formatted output with argument list pointer. Note: very
386 * similar to acpi_os_printf, changes should be tracked in both
387 * functions.
388 *
389 *****************************************************************************/
390
391void acpi_os_vprintf(const char *fmt, va_list args)
392{
393 u8 flags;
394 char buffer[ACPI_VPRINTF_BUFFER_SIZE];
395
396 /*
397 * We build the output string in a local buffer because we may be
398 * outputting the buffer twice. Using vfprintf is problematic because
399 * some implementations modify the args pointer/structure during
400 * execution. Thus, we use the local buffer for portability.
401 *
402 * Note: Since this module is intended for use by the various ACPICA
403 * utilities/applications, we can safely declare the buffer on the stack.
404 * Also, This function is used for relatively small error messages only.
405 */
406 vsnprintf(buffer, ACPI_VPRINTF_BUFFER_SIZE, fmt, args);
407
408 flags = acpi_gbl_db_output_flags;
409 if (flags & ACPI_DB_REDIRECTABLE_OUTPUT) {
410
411 /* Output is directable to either a file (if open) or the console */
412
413 if (acpi_gbl_debug_file) {
414
415 /* Output file is open, send the output there */
416
417 fputs(buffer, acpi_gbl_debug_file);
418 } else {
419 /* No redirection, send output to console (once only!) */
420
421 flags |= ACPI_DB_CONSOLE_OUTPUT;
422 }
423 }
424
425 if (flags & ACPI_DB_CONSOLE_OUTPUT) {
426 fputs(buffer, acpi_gbl_output_file);
427 }
428}
429
430#ifndef ACPI_EXEC_APP
431/******************************************************************************
432 *
433 * FUNCTION: acpi_os_get_line
434 *
435 * PARAMETERS: buffer - Where to return the command line
436 * buffer_length - Maximum length of Buffer
437 * bytes_read - Where the actual byte count is returned
438 *
439 * RETURN: Status and actual bytes read
440 *
441 * DESCRIPTION: Get the next input line from the terminal. NOTE: For the
442 * acpi_exec utility, we use the acgetline module instead to
443 * provide line-editing and history support.
444 *
445 *****************************************************************************/
446
447acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read)
448{
449 int input_char;
450 u32 end_of_line;
451
452 /* Standard acpi_os_get_line for all utilities except acpi_exec */
453
454 for (end_of_line = 0;; end_of_line++) {
455 if (end_of_line >= buffer_length) {
456 return (AE_BUFFER_OVERFLOW);
457 }
458
459 if ((input_char = getchar()) == EOF) {
460 return (AE_ERROR);
461 }
462
463 if (!input_char || input_char == _ASCII_NEWLINE) {
464 break;
465 }
466
467 buffer[end_of_line] = (char)input_char;
468 }
469
470 /* Null terminate the buffer */
471
472 buffer[end_of_line] = 0;
473
474 /* Return the number of bytes in the string */
475
476 if (bytes_read) {
477 *bytes_read = end_of_line;
478 }
479
480 return (AE_OK);
481}
482#endif
483
484#ifndef ACPI_USE_NATIVE_MEMORY_MAPPING
485/******************************************************************************
486 *
487 * FUNCTION: acpi_os_map_memory
488 *
489 * PARAMETERS: where - Physical address of memory to be mapped
490 * length - How much memory to map
491 *
492 * RETURN: Pointer to mapped memory. Null on error.
493 *
494 * DESCRIPTION: Map physical memory into caller's address space
495 *
496 *****************************************************************************/
497
498void *acpi_os_map_memory(acpi_physical_address where, acpi_size length)
499{
500
501 return (ACPI_TO_POINTER((acpi_size) where));
502}
503
504/******************************************************************************
505 *
506 * FUNCTION: acpi_os_unmap_memory
507 *
508 * PARAMETERS: where - Logical address of memory to be unmapped
509 * length - How much memory to unmap
510 *
511 * RETURN: None.
512 *
513 * DESCRIPTION: Delete a previously created mapping. Where and Length must
514 * correspond to a previous mapping exactly.
515 *
516 *****************************************************************************/
517
518void acpi_os_unmap_memory(void *where, acpi_size length)
519{
520
521 return;
522}
523#endif
524
525/******************************************************************************
526 *
527 * FUNCTION: acpi_os_allocate
528 *
529 * PARAMETERS: size - Amount to allocate, in bytes
530 *
531 * RETURN: Pointer to the new allocation. Null on error.
532 *
533 * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
534 *
535 *****************************************************************************/
536
537void *acpi_os_allocate(acpi_size size)
538{
539 void *mem;
540
541 mem = (void *)malloc((size_t) size);
542 return (mem);
543}
544
545#ifdef USE_NATIVE_ALLOCATE_ZEROED
546/******************************************************************************
547 *
548 * FUNCTION: acpi_os_allocate_zeroed
549 *
550 * PARAMETERS: size - Amount to allocate, in bytes
551 *
552 * RETURN: Pointer to the new allocation. Null on error.
553 *
554 * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS.
555 *
556 *****************************************************************************/
557
558void *acpi_os_allocate_zeroed(acpi_size size)
559{
560 void *mem;
561
562 mem = (void *)calloc(1, (size_t) size);
563 return (mem);
564}
565#endif
566
567/******************************************************************************
568 *
569 * FUNCTION: acpi_os_free
570 *
571 * PARAMETERS: mem - Pointer to previously allocated memory
572 *
573 * RETURN: None.
574 *
575 * DESCRIPTION: Free memory allocated via acpi_os_allocate
576 *
577 *****************************************************************************/
578
579void acpi_os_free(void *mem)
580{
581
582 free(mem);
583}
584
585#ifdef ACPI_SINGLE_THREADED
586/******************************************************************************
587 *
588 * FUNCTION: Semaphore stub functions
589 *
590 * DESCRIPTION: Stub functions used for single-thread applications that do
591 * not require semaphore synchronization. Full implementations
592 * of these functions appear after the stubs.
593 *
594 *****************************************************************************/
595
596acpi_status
597acpi_os_create_semaphore(u32 max_units,
598 u32 initial_units, acpi_handle * out_handle)
599{
600 *out_handle = (acpi_handle) 1;
601 return (AE_OK);
602}
603
604acpi_status acpi_os_delete_semaphore(acpi_handle handle)
605{
606 return (AE_OK);
607}
608
609acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
610{
611 return (AE_OK);
612}
613
614acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
615{
616 return (AE_OK);
617}
618
619#else
620/******************************************************************************
621 *
622 * FUNCTION: acpi_os_create_semaphore
623 *
624 * PARAMETERS: initial_units - Units to be assigned to the new semaphore
625 * out_handle - Where a handle will be returned
626 *
627 * RETURN: Status
628 *
629 * DESCRIPTION: Create an OS semaphore
630 *
631 *****************************************************************************/
632
633acpi_status
634acpi_os_create_semaphore(u32 max_units,
635 u32 initial_units, acpi_handle * out_handle)
636{
637 sem_t *sem;
638
639 if (!out_handle) {
640 return (AE_BAD_PARAMETER);
641 }
642#ifdef __APPLE__
643 {
644 char *semaphore_name = tmpnam(NULL);
645
646 sem =
647 sem_open(semaphore_name, O_EXCL | O_CREAT, 0755,
648 initial_units);
649 if (!sem) {
650 return (AE_NO_MEMORY);
651 }
652 sem_unlink(semaphore_name); /* This just deletes the name */
653 }
654
655#else
656 sem = acpi_os_allocate(sizeof(sem_t));
657 if (!sem) {
658 return (AE_NO_MEMORY);
659 }
660
661 if (sem_init(sem, 0, initial_units) == -1) {
662 acpi_os_free(sem);
663 return (AE_BAD_PARAMETER);
664 }
665#endif
666
667 *out_handle = (acpi_handle) sem;
668 return (AE_OK);
669}
670
671/******************************************************************************
672 *
673 * FUNCTION: acpi_os_delete_semaphore
674 *
675 * PARAMETERS: handle - Handle returned by acpi_os_create_semaphore
676 *
677 * RETURN: Status
678 *
679 * DESCRIPTION: Delete an OS semaphore
680 *
681 *****************************************************************************/
682
683acpi_status acpi_os_delete_semaphore(acpi_handle handle)
684{
685 sem_t *sem = (sem_t *) handle;
686
687 if (!sem) {
688 return (AE_BAD_PARAMETER);
689 }
690
691 if (sem_destroy(sem) == -1) {
692 return (AE_BAD_PARAMETER);
693 }
694
695 return (AE_OK);
696}
697
698/******************************************************************************
699 *
700 * FUNCTION: acpi_os_wait_semaphore
701 *
702 * PARAMETERS: handle - Handle returned by acpi_os_create_semaphore
703 * units - How many units to wait for
704 * msec_timeout - How long to wait (milliseconds)
705 *
706 * RETURN: Status
707 *
708 * DESCRIPTION: Wait for units
709 *
710 *****************************************************************************/
711
712acpi_status
713acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 msec_timeout)
714{
715 acpi_status status = AE_OK;
716 sem_t *sem = (sem_t *) handle;
717#ifndef ACPI_USE_ALTERNATE_TIMEOUT
718 struct timespec time;
719 int ret_val;
720#endif
721
722 if (!sem) {
723 return (AE_BAD_PARAMETER);
724 }
725
726 switch (msec_timeout) {
727 /*
728 * No Wait:
729 * --------
730 * A zero timeout value indicates that we shouldn't wait - just
731 * acquire the semaphore if available otherwise return AE_TIME
732 * (a.k.a. 'would block').
733 */
734 case 0:
735
736 if (sem_trywait(sem) == -1) {
737 status = (AE_TIME);
738 }
739 break;
740
741 /* Wait Indefinitely */
742
743 case ACPI_WAIT_FOREVER:
744
745 if (sem_wait(sem)) {
746 status = (AE_TIME);
747 }
748 break;
749
750 /* Wait with msec_timeout */
751
752 default:
753
754#ifdef ACPI_USE_ALTERNATE_TIMEOUT
755 /*
756 * Alternate timeout mechanism for environments where
757 * sem_timedwait is not available or does not work properly.
758 */
759 while (msec_timeout) {
760 if (sem_trywait(sem) == 0) {
761
762 /* Got the semaphore */
763 return (AE_OK);
764 }
765
766 if (msec_timeout >= 10) {
767 msec_timeout -= 10;
768 usleep(10 * ACPI_USEC_PER_MSEC); /* ten milliseconds */
769 } else {
770 msec_timeout--;
771 usleep(ACPI_USEC_PER_MSEC); /* one millisecond */
772 }
773 }
774 status = (AE_TIME);
775#else
776 /*
777 * The interface to sem_timedwait is an absolute time, so we need to
778 * get the current time, then add in the millisecond Timeout value.
779 */
780 if (clock_gettime(CLOCK_REALTIME, &time) == -1) {
781 perror("clock_gettime");
782 return (AE_TIME);
783 }
784
785 time.tv_sec += (msec_timeout / ACPI_MSEC_PER_SEC);
786 time.tv_nsec +=
787 ((msec_timeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC);
788
789 /* Handle nanosecond overflow (field must be less than one second) */
790
791 if (time.tv_nsec >= ACPI_NSEC_PER_SEC) {
792 time.tv_sec += (time.tv_nsec / ACPI_NSEC_PER_SEC);
793 time.tv_nsec = (time.tv_nsec % ACPI_NSEC_PER_SEC);
794 }
795
796 while (((ret_val = sem_timedwait(sem, &time)) == -1)
797 && (errno == EINTR)) {
798 continue;
799 }
800
801 if (ret_val != 0) {
802 if (errno != ETIMEDOUT) {
803 perror("sem_timedwait");
804 }
805 status = (AE_TIME);
806 }
807#endif
808 break;
809 }
810
811 return (status);
812}
813
814/******************************************************************************
815 *
816 * FUNCTION: acpi_os_signal_semaphore
817 *
818 * PARAMETERS: handle - Handle returned by acpi_os_create_semaphore
819 * units - Number of units to send
820 *
821 * RETURN: Status
822 *
823 * DESCRIPTION: Send units
824 *
825 *****************************************************************************/
826
827acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
828{
829 sem_t *sem = (sem_t *) handle;
830
831 if (!sem) {
832 return (AE_BAD_PARAMETER);
833 }
834
835 if (sem_post(sem) == -1) {
836 return (AE_LIMIT);
837 }
838
839 return (AE_OK);
840}
841
842#endif /* ACPI_SINGLE_THREADED */
843
844/******************************************************************************
845 *
846 * FUNCTION: Spinlock interfaces
847 *
848 * DESCRIPTION: Map these interfaces to semaphore interfaces
849 *
850 *****************************************************************************/
851
852acpi_status acpi_os_create_lock(acpi_spinlock * out_handle)
853{
854
855 return (acpi_os_create_semaphore(1, 1, out_handle));
856}
857
858void acpi_os_delete_lock(acpi_spinlock handle)
859{
860 acpi_os_delete_semaphore(handle);
861}
862
863acpi_cpu_flags acpi_os_acquire_lock(acpi_handle handle)
864{
865 acpi_os_wait_semaphore(handle, 1, 0xFFFF);
866 return (0);
867}
868
869void acpi_os_release_lock(acpi_spinlock handle, acpi_cpu_flags flags)
870{
871 acpi_os_signal_semaphore(handle, 1);
872}
873
874/******************************************************************************
875 *
876 * FUNCTION: acpi_os_install_interrupt_handler
877 *
878 * PARAMETERS: interrupt_number - Level handler should respond to.
879 * isr - Address of the ACPI interrupt handler
880 * except_ptr - Where status is returned
881 *
882 * RETURN: Handle to the newly installed handler.
883 *
884 * DESCRIPTION: Install an interrupt handler. Used to install the ACPI
885 * OS-independent handler.
886 *
887 *****************************************************************************/
888
889u32
890acpi_os_install_interrupt_handler(u32 interrupt_number,
891 acpi_osd_handler service_routine,
892 void *context)
893{
894
895 return (AE_OK);
896}
897
898/******************************************************************************
899 *
900 * FUNCTION: acpi_os_remove_interrupt_handler
901 *
902 * PARAMETERS: handle - Returned when handler was installed
903 *
904 * RETURN: Status
905 *
906 * DESCRIPTION: Uninstalls an interrupt handler.
907 *
908 *****************************************************************************/
909
910acpi_status
911acpi_os_remove_interrupt_handler(u32 interrupt_number,
912 acpi_osd_handler service_routine)
913{
914
915 return (AE_OK);
916}
917
918/******************************************************************************
919 *
920 * FUNCTION: acpi_os_stall
921 *
922 * PARAMETERS: microseconds - Time to sleep
923 *
924 * RETURN: Blocks until sleep is completed.
925 *
926 * DESCRIPTION: Sleep at microsecond granularity
927 *
928 *****************************************************************************/
929
930void acpi_os_stall(u32 microseconds)
931{
932
933 if (microseconds) {
934 usleep(microseconds);
935 }
936}
937
938/******************************************************************************
939 *
940 * FUNCTION: acpi_os_sleep
941 *
942 * PARAMETERS: milliseconds - Time to sleep
943 *
944 * RETURN: Blocks until sleep is completed.
945 *
946 * DESCRIPTION: Sleep at millisecond granularity
947 *
948 *****************************************************************************/
949
950void acpi_os_sleep(u64 milliseconds)
951{
952
953 /* Sleep for whole seconds */
954
955 sleep(milliseconds / ACPI_MSEC_PER_SEC);
956
957 /*
958 * Sleep for remaining microseconds.
959 * Arg to usleep() is in usecs and must be less than 1,000,000 (1 second).
960 */
961 usleep((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC);
962}
963
964/******************************************************************************
965 *
966 * FUNCTION: acpi_os_get_timer
967 *
968 * PARAMETERS: None
969 *
970 * RETURN: Current time in 100 nanosecond units
971 *
972 * DESCRIPTION: Get the current system time
973 *
974 *****************************************************************************/
975
976u64 acpi_os_get_timer(void)
977{
978 struct timeval time;
979
980 /* This timer has sufficient resolution for user-space application code */
981
982 gettimeofday(&time, NULL);
983
984 /* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */
985
986 return (((u64)time.tv_sec * ACPI_100NSEC_PER_SEC) +
987 ((u64)time.tv_usec * ACPI_100NSEC_PER_USEC));
988}
989
990/******************************************************************************
991 *
992 * FUNCTION: acpi_os_read_pci_configuration
993 *
994 * PARAMETERS: pci_id - Seg/Bus/Dev
995 * pci_register - Device Register
996 * value - Buffer where value is placed
997 * width - Number of bits
998 *
999 * RETURN: Status
1000 *
1001 * DESCRIPTION: Read data from PCI configuration space
1002 *
1003 *****************************************************************************/
1004
1005acpi_status
1006acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id,
1007 u32 pci_register, u64 *value, u32 width)
1008{
1009
1010 *value = 0;
1011 return (AE_OK);
1012}
1013
1014/******************************************************************************
1015 *
1016 * FUNCTION: acpi_os_write_pci_configuration
1017 *
1018 * PARAMETERS: pci_id - Seg/Bus/Dev
1019 * pci_register - Device Register
1020 * value - Value to be written
1021 * width - Number of bits
1022 *
1023 * RETURN: Status.
1024 *
1025 * DESCRIPTION: Write data to PCI configuration space
1026 *
1027 *****************************************************************************/
1028
1029acpi_status
1030acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id,
1031 u32 pci_register, u64 value, u32 width)
1032{
1033
1034 return (AE_OK);
1035}
1036
1037/******************************************************************************
1038 *
1039 * FUNCTION: acpi_os_read_port
1040 *
1041 * PARAMETERS: address - Address of I/O port/register to read
1042 * value - Where value is placed
1043 * width - Number of bits
1044 *
1045 * RETURN: Value read from port
1046 *
1047 * DESCRIPTION: Read data from an I/O port or register
1048 *
1049 *****************************************************************************/
1050
1051acpi_status acpi_os_read_port(acpi_io_address address, u32 *value, u32 width)
1052{
1053
1054 switch (width) {
1055 case 8:
1056
1057 *value = 0xFF;
1058 break;
1059
1060 case 16:
1061
1062 *value = 0xFFFF;
1063 break;
1064
1065 case 32:
1066
1067 *value = 0xFFFFFFFF;
1068 break;
1069
1070 default:
1071
1072 return (AE_BAD_PARAMETER);
1073 }
1074
1075 return (AE_OK);
1076}
1077
1078/******************************************************************************
1079 *
1080 * FUNCTION: acpi_os_write_port
1081 *
1082 * PARAMETERS: address - Address of I/O port/register to write
1083 * value - Value to write
1084 * width - Number of bits
1085 *
1086 * RETURN: None
1087 *
1088 * DESCRIPTION: Write data to an I/O port or register
1089 *
1090 *****************************************************************************/
1091
1092acpi_status acpi_os_write_port(acpi_io_address address, u32 value, u32 width)
1093{
1094
1095 return (AE_OK);
1096}
1097
1098/******************************************************************************
1099 *
1100 * FUNCTION: acpi_os_read_memory
1101 *
1102 * PARAMETERS: address - Physical Memory Address to read
1103 * value - Where value is placed
1104 * width - Number of bits (8,16,32, or 64)
1105 *
1106 * RETURN: Value read from physical memory address. Always returned
1107 * as a 64-bit integer, regardless of the read width.
1108 *
1109 * DESCRIPTION: Read data from a physical memory address
1110 *
1111 *****************************************************************************/
1112
1113acpi_status
1114acpi_os_read_memory(acpi_physical_address address, u64 *value, u32 width)
1115{
1116
1117 switch (width) {
1118 case 8:
1119 case 16:
1120 case 32:
1121 case 64:
1122
1123 *value = 0;
1124 break;
1125
1126 default:
1127
1128 return (AE_BAD_PARAMETER);
1129 }
1130 return (AE_OK);
1131}
1132
1133/******************************************************************************
1134 *
1135 * FUNCTION: acpi_os_write_memory
1136 *
1137 * PARAMETERS: address - Physical Memory Address to write
1138 * value - Value to write
1139 * width - Number of bits (8,16,32, or 64)
1140 *
1141 * RETURN: None
1142 *
1143 * DESCRIPTION: Write data to a physical memory address
1144 *
1145 *****************************************************************************/
1146
1147acpi_status
1148acpi_os_write_memory(acpi_physical_address address, u64 value, u32 width)
1149{
1150
1151 return (AE_OK);
1152}
1153
1154/******************************************************************************
1155 *
1156 * FUNCTION: acpi_os_readable
1157 *
1158 * PARAMETERS: pointer - Area to be verified
1159 * length - Size of area
1160 *
1161 * RETURN: TRUE if readable for entire length
1162 *
1163 * DESCRIPTION: Verify that a pointer is valid for reading
1164 *
1165 *****************************************************************************/
1166
1167u8 acpi_os_readable(void *pointer, acpi_size length)
1168{
1169
1170 return (TRUE);
1171}
1172
1173/******************************************************************************
1174 *
1175 * FUNCTION: acpi_os_writable
1176 *
1177 * PARAMETERS: pointer - Area to be verified
1178 * length - Size of area
1179 *
1180 * RETURN: TRUE if writable for entire length
1181 *
1182 * DESCRIPTION: Verify that a pointer is valid for writing
1183 *
1184 *****************************************************************************/
1185
1186u8 acpi_os_writable(void *pointer, acpi_size length)
1187{
1188
1189 return (TRUE);
1190}
1191
1192/******************************************************************************
1193 *
1194 * FUNCTION: acpi_os_signal
1195 *
1196 * PARAMETERS: function - ACPI A signal function code
1197 * info - Pointer to function-dependent structure
1198 *
1199 * RETURN: Status
1200 *
1201 * DESCRIPTION: Miscellaneous functions. Example implementation only.
1202 *
1203 *****************************************************************************/
1204
1205acpi_status acpi_os_signal(u32 function, void *info)
1206{
1207
1208 switch (function) {
1209 case ACPI_SIGNAL_FATAL:
1210
1211 break;
1212
1213 case ACPI_SIGNAL_BREAKPOINT:
1214
1215 break;
1216
1217 default:
1218
1219 break;
1220 }
1221
1222 return (AE_OK);
1223}
1224
1225/* Optional multi-thread support */
1226
1227#ifndef ACPI_SINGLE_THREADED
1228/******************************************************************************
1229 *
1230 * FUNCTION: acpi_os_get_thread_id
1231 *
1232 * PARAMETERS: None
1233 *
1234 * RETURN: Id of the running thread
1235 *
1236 * DESCRIPTION: Get the ID of the current (running) thread
1237 *
1238 *****************************************************************************/
1239
1240acpi_thread_id acpi_os_get_thread_id(void)
1241{
1242 pthread_t thread;
1243
1244 thread = pthread_self();
1245 return (ACPI_CAST_PTHREAD_T(thread));
1246}
1247
1248/******************************************************************************
1249 *
1250 * FUNCTION: acpi_os_execute
1251 *
1252 * PARAMETERS: type - Type of execution
1253 * function - Address of the function to execute
1254 * context - Passed as a parameter to the function
1255 *
1256 * RETURN: Status.
1257 *
1258 * DESCRIPTION: Execute a new thread
1259 *
1260 *****************************************************************************/
1261
1262acpi_status
1263acpi_os_execute(acpi_execute_type type,
1264 acpi_osd_exec_callback function, void *context)
1265{
1266 pthread_t thread;
1267 int ret;
1268
1269 ret =
1270 pthread_create(&thread, NULL, (PTHREAD_CALLBACK) function, context);
1271 if (ret) {
1272 acpi_os_printf("Create thread failed");
1273 }
1274 return (0);
1275}
1276
1277#else /* ACPI_SINGLE_THREADED */
1278acpi_thread_id acpi_os_get_thread_id(void)
1279{
1280 return (1);
1281}
1282
1283acpi_status
1284acpi_os_execute(acpi_execute_type type,
1285 acpi_osd_exec_callback function, void *context)
1286{
1287
1288 function(context);
1289
1290 return (AE_OK);
1291}
1292
1293#endif /* ACPI_SINGLE_THREADED */
1294
1295/******************************************************************************
1296 *
1297 * FUNCTION: acpi_os_wait_events_complete
1298 *
1299 * PARAMETERS: None
1300 *
1301 * RETURN: None
1302 *
1303 * DESCRIPTION: Wait for all asynchronous events to complete. This
1304 * implementation does nothing.
1305 *
1306 *****************************************************************************/
1307
1308void acpi_os_wait_events_complete(void)
1309{
1310 return;
1311}
diff --git a/tools/power/acpi/tools/acpidump/acpidump.h b/tools/power/acpi/tools/acpidump/acpidump.h
index 46f519597fe5..a2d37d610639 100644
--- a/tools/power/acpi/tools/acpidump/acpidump.h
+++ b/tools/power/acpi/tools/acpidump/acpidump.h
@@ -47,7 +47,6 @@
47#ifdef _DECLARE_GLOBALS 47#ifdef _DECLARE_GLOBALS
48#define EXTERN 48#define EXTERN
49#define INIT_GLOBAL(a,b) a=b 49#define INIT_GLOBAL(a,b) a=b
50#define DEFINE_ACPI_GLOBALS 1
51#else 50#else
52#define EXTERN extern 51#define EXTERN extern
53#define INIT_GLOBAL(a,b) a 52#define INIT_GLOBAL(a,b) a
@@ -69,7 +68,7 @@ EXTERN u8 INIT_GLOBAL(gbl_verbose_mode, FALSE);
69EXTERN u8 INIT_GLOBAL(gbl_binary_mode, FALSE); 68EXTERN u8 INIT_GLOBAL(gbl_binary_mode, FALSE);
70EXTERN u8 INIT_GLOBAL(gbl_dump_customized_tables, FALSE); 69EXTERN u8 INIT_GLOBAL(gbl_dump_customized_tables, FALSE);
71EXTERN u8 INIT_GLOBAL(gbl_do_not_dump_xsdt, FALSE); 70EXTERN u8 INIT_GLOBAL(gbl_do_not_dump_xsdt, FALSE);
72EXTERN FILE INIT_GLOBAL(*gbl_output_file, NULL); 71EXTERN ACPI_FILE INIT_GLOBAL(gbl_output_file, NULL);
73EXTERN char INIT_GLOBAL(*gbl_output_filename, NULL); 72EXTERN char INIT_GLOBAL(*gbl_output_filename, NULL);
74EXTERN u64 INIT_GLOBAL(gbl_rsdp_base, 0); 73EXTERN u64 INIT_GLOBAL(gbl_rsdp_base, 0);
75 74
diff --git a/tools/power/acpi/tools/acpidump/apdump.c b/tools/power/acpi/tools/acpidump/apdump.c
index 3cac12378366..53cee781e24e 100644
--- a/tools/power/acpi/tools/acpidump/apdump.c
+++ b/tools/power/acpi/tools/acpidump/apdump.c
@@ -69,17 +69,16 @@ u8 ap_is_valid_header(struct acpi_table_header *table)
69 /* Make sure signature is all ASCII and a valid ACPI name */ 69 /* Make sure signature is all ASCII and a valid ACPI name */
70 70
71 if (!acpi_ut_valid_acpi_name(table->signature)) { 71 if (!acpi_ut_valid_acpi_name(table->signature)) {
72 fprintf(stderr, 72 acpi_log_error("Table signature (0x%8.8X) is invalid\n",
73 "Table signature (0x%8.8X) is invalid\n", 73 *(u32 *)table->signature);
74 *(u32 *)table->signature);
75 return (FALSE); 74 return (FALSE);
76 } 75 }
77 76
78 /* Check for minimum table length */ 77 /* Check for minimum table length */
79 78
80 if (table->length < sizeof(struct acpi_table_header)) { 79 if (table->length < sizeof(struct acpi_table_header)) {
81 fprintf(stderr, "Table length (0x%8.8X) is invalid\n", 80 acpi_log_error("Table length (0x%8.8X) is invalid\n",
82 table->length); 81 table->length);
83 return (FALSE); 82 return (FALSE);
84 } 83 }
85 } 84 }
@@ -116,8 +115,8 @@ u8 ap_is_valid_checksum(struct acpi_table_header *table)
116 } 115 }
117 116
118 if (ACPI_FAILURE(status)) { 117 if (ACPI_FAILURE(status)) {
119 fprintf(stderr, "%4.4s: Warning: wrong checksum in table\n", 118 acpi_log_error("%4.4s: Warning: wrong checksum in table\n",
120 table->signature); 119 table->signature);
121 } 120 }
122 121
123 return (AE_OK); 122 return (AE_OK);
@@ -196,12 +195,13 @@ ap_dump_table_buffer(struct acpi_table_header *table,
196 * Note: simplest to just always emit a 64-bit address. acpi_xtract 195 * Note: simplest to just always emit a 64-bit address. acpi_xtract
197 * utility can handle this. 196 * utility can handle this.
198 */ 197 */
199 printf("%4.4s @ 0x%8.8X%8.8X\n", table->signature, 198 acpi_ut_file_printf(gbl_output_file, "%4.4s @ 0x%8.8X%8.8X\n",
200 ACPI_FORMAT_UINT64(address)); 199 table->signature, ACPI_FORMAT_UINT64(address));
201 200
202 acpi_ut_dump_buffer(ACPI_CAST_PTR(u8, table), table_length, 201 acpi_ut_dump_buffer_to_file(gbl_output_file,
203 DB_BYTE_DISPLAY, 0); 202 ACPI_CAST_PTR(u8, table), table_length,
204 printf("\n"); 203 DB_BYTE_DISPLAY, 0);
204 acpi_ut_file_printf(gbl_output_file, "\n");
205 return (0); 205 return (0);
206} 206}
207 207
@@ -239,20 +239,20 @@ int ap_dump_all_tables(void)
239 if (status == AE_LIMIT) { 239 if (status == AE_LIMIT) {
240 return (0); 240 return (0);
241 } else if (i == 0) { 241 } else if (i == 0) {
242 fprintf(stderr, 242 acpi_log_error
243 "Could not get ACPI tables, %s\n", 243 ("Could not get ACPI tables, %s\n",
244 acpi_format_exception(status)); 244 acpi_format_exception(status));
245 return (-1); 245 return (-1);
246 } else { 246 } else {
247 fprintf(stderr, 247 acpi_log_error
248 "Could not get ACPI table at index %u, %s\n", 248 ("Could not get ACPI table at index %u, %s\n",
249 i, acpi_format_exception(status)); 249 i, acpi_format_exception(status));
250 continue; 250 continue;
251 } 251 }
252 } 252 }
253 253
254 table_status = ap_dump_table_buffer(table, instance, address); 254 table_status = ap_dump_table_buffer(table, instance, address);
255 free(table); 255 ACPI_FREE(table);
256 256
257 if (table_status) { 257 if (table_status) {
258 break; 258 break;
@@ -288,22 +288,22 @@ int ap_dump_table_by_address(char *ascii_address)
288 288
289 status = acpi_ut_strtoul64(ascii_address, 0, &long_address); 289 status = acpi_ut_strtoul64(ascii_address, 0, &long_address);
290 if (ACPI_FAILURE(status)) { 290 if (ACPI_FAILURE(status)) {
291 fprintf(stderr, "%s: Could not convert to a physical address\n", 291 acpi_log_error("%s: Could not convert to a physical address\n",
292 ascii_address); 292 ascii_address);
293 return (-1); 293 return (-1);
294 } 294 }
295 295
296 address = (acpi_physical_address) long_address; 296 address = (acpi_physical_address) long_address;
297 status = acpi_os_get_table_by_address(address, &table); 297 status = acpi_os_get_table_by_address(address, &table);
298 if (ACPI_FAILURE(status)) { 298 if (ACPI_FAILURE(status)) {
299 fprintf(stderr, "Could not get table at 0x%8.8X%8.8X, %s\n", 299 acpi_log_error("Could not get table at 0x%8.8X%8.8X, %s\n",
300 ACPI_FORMAT_UINT64(address), 300 ACPI_FORMAT_UINT64(address),
301 acpi_format_exception(status)); 301 acpi_format_exception(status));
302 return (-1); 302 return (-1);
303 } 303 }
304 304
305 table_status = ap_dump_table_buffer(table, 0, address); 305 table_status = ap_dump_table_buffer(table, 0, address);
306 free(table); 306 ACPI_FREE(table);
307 return (table_status); 307 return (table_status);
308} 308}
309 309
@@ -329,24 +329,24 @@ int ap_dump_table_by_name(char *signature)
329 acpi_status status; 329 acpi_status status;
330 int table_status; 330 int table_status;
331 331
332 if (strlen(signature) != ACPI_NAME_SIZE) { 332 if (ACPI_STRLEN(signature) != ACPI_NAME_SIZE) {
333 fprintf(stderr, 333 acpi_log_error
334 "Invalid table signature [%s]: must be exactly 4 characters\n", 334 ("Invalid table signature [%s]: must be exactly 4 characters\n",
335 signature); 335 signature);
336 return (-1); 336 return (-1);
337 } 337 }
338 338
339 /* Table signatures are expected to be uppercase */ 339 /* Table signatures are expected to be uppercase */
340 340
341 strcpy(local_signature, signature); 341 ACPI_STRCPY(local_signature, signature);
342 acpi_ut_strupr(local_signature); 342 acpi_ut_strupr(local_signature);
343 343
344 /* To be friendly, handle tables whose signatures do not match the name */ 344 /* To be friendly, handle tables whose signatures do not match the name */
345 345
346 if (ACPI_COMPARE_NAME(local_signature, "FADT")) { 346 if (ACPI_COMPARE_NAME(local_signature, "FADT")) {
347 strcpy(local_signature, ACPI_SIG_FADT); 347 ACPI_STRCPY(local_signature, ACPI_SIG_FADT);
348 } else if (ACPI_COMPARE_NAME(local_signature, "MADT")) { 348 } else if (ACPI_COMPARE_NAME(local_signature, "MADT")) {
349 strcpy(local_signature, ACPI_SIG_MADT); 349 ACPI_STRCPY(local_signature, ACPI_SIG_MADT);
350 } 350 }
351 351
352 /* Dump all instances of this signature (to handle multiple SSDTs) */ 352 /* Dump all instances of this signature (to handle multiple SSDTs) */
@@ -362,14 +362,14 @@ int ap_dump_table_by_name(char *signature)
362 return (0); 362 return (0);
363 } 363 }
364 364
365 fprintf(stderr, 365 acpi_log_error
366 "Could not get ACPI table with signature [%s], %s\n", 366 ("Could not get ACPI table with signature [%s], %s\n",
367 local_signature, acpi_format_exception(status)); 367 local_signature, acpi_format_exception(status));
368 return (-1); 368 return (-1);
369 } 369 }
370 370
371 table_status = ap_dump_table_buffer(table, instance, address); 371 table_status = ap_dump_table_buffer(table, instance, address);
372 free(table); 372 ACPI_FREE(table);
373 373
374 if (table_status) { 374 if (table_status) {
375 break; 375 break;
@@ -409,43 +409,21 @@ int ap_dump_table_from_file(char *pathname)
409 /* File must be at least as long as the table length */ 409 /* File must be at least as long as the table length */
410 410
411 if (table->length > file_size) { 411 if (table->length > file_size) {
412 fprintf(stderr, 412 acpi_log_error
413 "Table length (0x%X) is too large for input file (0x%X) %s\n", 413 ("Table length (0x%X) is too large for input file (0x%X) %s\n",
414 table->length, file_size, pathname); 414 table->length, file_size, pathname);
415 goto exit; 415 goto exit;
416 } 416 }
417 417
418 if (gbl_verbose_mode) { 418 if (gbl_verbose_mode) {
419 fprintf(stderr, 419 acpi_log_error
420 "Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n", 420 ("Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n",
421 pathname, table->signature, file_size, file_size); 421 pathname, table->signature, file_size, file_size);
422 } 422 }
423 423
424 table_status = ap_dump_table_buffer(table, 0, 0); 424 table_status = ap_dump_table_buffer(table, 0, 0);
425 425
426exit: 426exit:
427 free(table); 427 ACPI_FREE(table);
428 return (table_status); 428 return (table_status);
429} 429}
430
431/******************************************************************************
432 *
433 * FUNCTION: acpi_os* print functions
434 *
435 * DESCRIPTION: Used for linkage with ACPICA modules
436 *
437 ******************************************************************************/
438
439void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *fmt, ...)
440{
441 va_list args;
442
443 va_start(args, fmt);
444 vfprintf(stdout, fmt, args);
445 va_end(args);
446}
447
448void acpi_os_vprintf(const char *fmt, va_list args)
449{
450 vfprintf(stdout, fmt, args);
451}
diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c
index 4488accc010b..d470046a6d81 100644
--- a/tools/power/acpi/tools/acpidump/apfiles.c
+++ b/tools/power/acpi/tools/acpidump/apfiles.c
@@ -44,6 +44,27 @@
44#include "acpidump.h" 44#include "acpidump.h"
45#include "acapps.h" 45#include "acapps.h"
46 46
47/* Local prototypes */
48
49static int ap_is_existing_file(char *pathname);
50
51static int ap_is_existing_file(char *pathname)
52{
53#ifndef _GNU_EFI
54 struct stat stat_info;
55
56 if (!stat(pathname, &stat_info)) {
57 acpi_log_error("Target path already exists, overwrite? [y|n] ");
58
59 if (getchar() != 'y') {
60 return (-1);
61 }
62 }
63#endif
64
65 return 0;
66}
67
47/****************************************************************************** 68/******************************************************************************
48 * 69 *
49 * FUNCTION: ap_open_output_file 70 * FUNCTION: ap_open_output_file
@@ -59,25 +80,19 @@
59 80
60int ap_open_output_file(char *pathname) 81int ap_open_output_file(char *pathname)
61{ 82{
62 struct stat stat_info; 83 ACPI_FILE file;
63 FILE *file;
64 84
65 /* If file exists, prompt for overwrite */ 85 /* If file exists, prompt for overwrite */
66 86
67 if (!stat(pathname, &stat_info)) { 87 if (ap_is_existing_file(pathname) != 0) {
68 fprintf(stderr, 88 return (-1);
69 "Target path already exists, overwrite? [y|n] ");
70
71 if (getchar() != 'y') {
72 return (-1);
73 }
74 } 89 }
75 90
76 /* Point stdout to the file */ 91 /* Point stdout to the file */
77 92
78 file = freopen(pathname, "w", stdout); 93 file = acpi_os_open_file(pathname, ACPI_FILE_WRITING);
79 if (!file) { 94 if (!file) {
80 perror("Could not open output file"); 95 acpi_log_error("Could not open output file: %s\n", pathname);
81 return (-1); 96 return (-1);
82 } 97 }
83 98
@@ -106,7 +121,7 @@ int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance)
106{ 121{
107 char filename[ACPI_NAME_SIZE + 16]; 122 char filename[ACPI_NAME_SIZE + 16];
108 char instance_str[16]; 123 char instance_str[16];
109 FILE *file; 124 ACPI_FILE file;
110 size_t actual; 125 size_t actual;
111 u32 table_length; 126 u32 table_length;
112 127
@@ -130,35 +145,37 @@ int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance)
130 /* Handle multiple SSDts - create different filenames for each */ 145 /* Handle multiple SSDts - create different filenames for each */
131 146
132 if (instance > 0) { 147 if (instance > 0) {
133 sprintf(instance_str, "%u", instance); 148 acpi_ut_snprintf(instance_str, sizeof(instance_str), "%u",
134 strcat(filename, instance_str); 149 instance);
150 ACPI_STRCAT(filename, instance_str);
135 } 151 }
136 152
137 strcat(filename, ACPI_TABLE_FILE_SUFFIX); 153 ACPI_STRCAT(filename, ACPI_TABLE_FILE_SUFFIX);
138 154
139 if (gbl_verbose_mode) { 155 if (gbl_verbose_mode) {
140 fprintf(stderr, 156 acpi_log_error
141 "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n", 157 ("Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n",
142 table->signature, filename, table->length, 158 table->signature, filename, table->length, table->length);
143 table->length);
144 } 159 }
145 160
146 /* Open the file and dump the entire table in binary mode */ 161 /* Open the file and dump the entire table in binary mode */
147 162
148 file = fopen(filename, "wb"); 163 file = acpi_os_open_file(filename,
164 ACPI_FILE_WRITING | ACPI_FILE_BINARY);
149 if (!file) { 165 if (!file) {
150 perror("Could not open output file"); 166 acpi_log_error("Could not open output file: %s\n", filename);
151 return (-1); 167 return (-1);
152 } 168 }
153 169
154 actual = fwrite(table, 1, table_length, file); 170 actual = acpi_os_write_file(file, table, 1, table_length);
155 if (actual != table_length) { 171 if (actual != table_length) {
156 perror("Error writing binary output file"); 172 acpi_log_error("Error writing binary output file: %s\n",
157 fclose(file); 173 filename);
174 acpi_os_close_file(file);
158 return (-1); 175 return (-1);
159 } 176 }
160 177
161 fclose(file); 178 acpi_os_close_file(file);
162 return (0); 179 return (0);
163} 180}
164 181
@@ -179,15 +196,16 @@ struct acpi_table_header *ap_get_table_from_file(char *pathname,
179 u32 *out_file_size) 196 u32 *out_file_size)
180{ 197{
181 struct acpi_table_header *buffer = NULL; 198 struct acpi_table_header *buffer = NULL;
182 FILE *file; 199 ACPI_FILE file;
183 u32 file_size; 200 u32 file_size;
184 size_t actual; 201 size_t actual;
185 202
186 /* Must use binary mode */ 203 /* Must use binary mode */
187 204
188 file = fopen(pathname, "rb"); 205 file =
206 acpi_os_open_file(pathname, ACPI_FILE_READING | ACPI_FILE_BINARY);
189 if (!file) { 207 if (!file) {
190 perror("Could not open input file"); 208 acpi_log_error("Could not open input file: %s\n", pathname);
191 return (NULL); 209 return (NULL);
192 } 210 }
193 211
@@ -195,27 +213,25 @@ struct acpi_table_header *ap_get_table_from_file(char *pathname,
195 213
196 file_size = cm_get_file_size(file); 214 file_size = cm_get_file_size(file);
197 if (file_size == ACPI_UINT32_MAX) { 215 if (file_size == ACPI_UINT32_MAX) {
198 fprintf(stderr, 216 acpi_log_error("Could not get input file size: %s\n", pathname);
199 "Could not get input file size: %s\n", pathname);
200 goto cleanup; 217 goto cleanup;
201 } 218 }
202 219
203 /* Allocate a buffer for the entire file */ 220 /* Allocate a buffer for the entire file */
204 221
205 buffer = calloc(1, file_size); 222 buffer = ACPI_ALLOCATE_ZEROED(file_size);
206 if (!buffer) { 223 if (!buffer) {
207 fprintf(stderr, 224 acpi_log_error("Could not allocate file buffer of size: %u\n",
208 "Could not allocate file buffer of size: %u\n", 225 file_size);
209 file_size);
210 goto cleanup; 226 goto cleanup;
211 } 227 }
212 228
213 /* Read the entire file */ 229 /* Read the entire file */
214 230
215 actual = fread(buffer, 1, file_size, file); 231 actual = acpi_os_read_file(file, buffer, 1, file_size);
216 if (actual != file_size) { 232 if (actual != file_size) {
217 fprintf(stderr, "Could not read input file: %s\n", pathname); 233 acpi_log_error("Could not read input file: %s\n", pathname);
218 free(buffer); 234 ACPI_FREE(buffer);
219 buffer = NULL; 235 buffer = NULL;
220 goto cleanup; 236 goto cleanup;
221 } 237 }
@@ -223,6 +239,6 @@ struct acpi_table_header *ap_get_table_from_file(char *pathname,
223 *out_file_size = file_size; 239 *out_file_size = file_size;
224 240
225cleanup: 241cleanup:
226 fclose(file); 242 acpi_os_close_file(file);
227 return (buffer); 243 return (buffer);
228} 244}
diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c
index 51e8d638db18..853b4da22c3e 100644
--- a/tools/power/acpi/tools/acpidump/apmain.c
+++ b/tools/power/acpi/tools/acpidump/apmain.c
@@ -72,7 +72,7 @@ static void ap_display_usage(void);
72 72
73static int ap_do_options(int argc, char **argv); 73static int ap_do_options(int argc, char **argv);
74 74
75static void ap_insert_action(char *argument, u32 to_be_done); 75static int ap_insert_action(char *argument, u32 to_be_done);
76 76
77/* Table for deferred actions from command line options */ 77/* Table for deferred actions from command line options */
78 78
@@ -104,7 +104,7 @@ static void ap_display_usage(void)
104 ACPI_OPTION("-v", "Display version information"); 104 ACPI_OPTION("-v", "Display version information");
105 ACPI_OPTION("-z", "Verbose mode"); 105 ACPI_OPTION("-z", "Verbose mode");
106 106
107 printf("\nTable Options:\n"); 107 ACPI_USAGE_TEXT("\nTable Options:\n");
108 108
109 ACPI_OPTION("-a <Address>", "Get table via a physical address"); 109 ACPI_OPTION("-a <Address>", "Get table via a physical address");
110 ACPI_OPTION("-f <BinaryFile>", "Get table via a binary file"); 110 ACPI_OPTION("-f <BinaryFile>", "Get table via a binary file");
@@ -112,9 +112,9 @@ static void ap_display_usage(void)
112 ACPI_OPTION("-x", "Do not use but dump XSDT"); 112 ACPI_OPTION("-x", "Do not use but dump XSDT");
113 ACPI_OPTION("-x -x", "Do not use or dump XSDT"); 113 ACPI_OPTION("-x -x", "Do not use or dump XSDT");
114 114
115 printf("\n" 115 ACPI_USAGE_TEXT("\n"
116 "Invocation without parameters dumps all available tables\n" 116 "Invocation without parameters dumps all available tables\n"
117 "Multiple mixed instances of -a, -f, and -n are supported\n\n"); 117 "Multiple mixed instances of -a, -f, and -n are supported\n\n");
118} 118}
119 119
120/****************************************************************************** 120/******************************************************************************
@@ -124,13 +124,13 @@ static void ap_display_usage(void)
124 * PARAMETERS: argument - Pointer to the argument for this action 124 * PARAMETERS: argument - Pointer to the argument for this action
125 * to_be_done - What to do to process this action 125 * to_be_done - What to do to process this action
126 * 126 *
127 * RETURN: None. Exits program if action table becomes full. 127 * RETURN: Status
128 * 128 *
129 * DESCRIPTION: Add an action item to the action table 129 * DESCRIPTION: Add an action item to the action table
130 * 130 *
131 ******************************************************************************/ 131 ******************************************************************************/
132 132
133static void ap_insert_action(char *argument, u32 to_be_done) 133static int ap_insert_action(char *argument, u32 to_be_done)
134{ 134{
135 135
136 /* Insert action and check for table overflow */ 136 /* Insert action and check for table overflow */
@@ -140,10 +140,12 @@ static void ap_insert_action(char *argument, u32 to_be_done)
140 140
141 current_action++; 141 current_action++;
142 if (current_action > AP_MAX_ACTIONS) { 142 if (current_action > AP_MAX_ACTIONS) {
143 fprintf(stderr, "Too many table options (max %u)\n", 143 acpi_log_error("Too many table options (max %u)\n",
144 AP_MAX_ACTIONS); 144 AP_MAX_ACTIONS);
145 exit(-1); 145 return (-1);
146 } 146 }
147
148 return (0);
147} 149}
148 150
149/****************************************************************************** 151/******************************************************************************
@@ -166,7 +168,8 @@ static int ap_do_options(int argc, char **argv)
166 168
167 /* Command line options */ 169 /* Command line options */
168 170
169 while ((j = acpi_getopt(argc, argv, AP_SUPPORTED_OPTIONS)) != EOF) 171 while ((j =
172 acpi_getopt(argc, argv, AP_SUPPORTED_OPTIONS)) != ACPI_OPT_END)
170 switch (j) { 173 switch (j) {
171 /* 174 /*
172 * Global options 175 * Global options
@@ -185,12 +188,12 @@ static int ap_do_options(int argc, char **argv)
185 case '?': 188 case '?':
186 189
187 ap_display_usage(); 190 ap_display_usage();
188 exit(0); 191 return (1);
189 192
190 case 'o': /* Redirect output to a single file */ 193 case 'o': /* Redirect output to a single file */
191 194
192 if (ap_open_output_file(acpi_gbl_optarg)) { 195 if (ap_open_output_file(acpi_gbl_optarg)) {
193 exit(-1); 196 return (-1);
194 } 197 }
195 continue; 198 continue;
196 199
@@ -200,10 +203,10 @@ static int ap_do_options(int argc, char **argv)
200 acpi_ut_strtoul64(acpi_gbl_optarg, 0, 203 acpi_ut_strtoul64(acpi_gbl_optarg, 0,
201 &gbl_rsdp_base); 204 &gbl_rsdp_base);
202 if (ACPI_FAILURE(status)) { 205 if (ACPI_FAILURE(status)) {
203 fprintf(stderr, 206 acpi_log_error
204 "%s: Could not convert to a physical address\n", 207 ("%s: Could not convert to a physical address\n",
205 acpi_gbl_optarg); 208 acpi_gbl_optarg);
206 exit(-1); 209 return (-1);
207 } 210 }
208 continue; 211 continue;
209 212
@@ -223,13 +226,13 @@ static int ap_do_options(int argc, char **argv)
223 226
224 case 'v': /* Revision/version */ 227 case 'v': /* Revision/version */
225 228
226 printf(ACPI_COMMON_SIGNON(AP_UTILITY_NAME)); 229 acpi_os_printf(ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
227 exit(0); 230 return (1);
228 231
229 case 'z': /* Verbose mode */ 232 case 'z': /* Verbose mode */
230 233
231 gbl_verbose_mode = TRUE; 234 gbl_verbose_mode = TRUE;
232 fprintf(stderr, ACPI_COMMON_SIGNON(AP_UTILITY_NAME)); 235 acpi_log_error(ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
233 continue; 236 continue;
234 237
235 /* 238 /*
@@ -237,32 +240,40 @@ static int ap_do_options(int argc, char **argv)
237 */ 240 */
238 case 'a': /* Get table by physical address */ 241 case 'a': /* Get table by physical address */
239 242
240 ap_insert_action(acpi_gbl_optarg, 243 if (ap_insert_action
241 AP_DUMP_TABLE_BY_ADDRESS); 244 (acpi_gbl_optarg, AP_DUMP_TABLE_BY_ADDRESS)) {
245 return (-1);
246 }
242 break; 247 break;
243 248
244 case 'f': /* Get table from a file */ 249 case 'f': /* Get table from a file */
245 250
246 ap_insert_action(acpi_gbl_optarg, 251 if (ap_insert_action
247 AP_DUMP_TABLE_BY_FILE); 252 (acpi_gbl_optarg, AP_DUMP_TABLE_BY_FILE)) {
253 return (-1);
254 }
248 break; 255 break;
249 256
250 case 'n': /* Get table by input name (signature) */ 257 case 'n': /* Get table by input name (signature) */
251 258
252 ap_insert_action(acpi_gbl_optarg, 259 if (ap_insert_action
253 AP_DUMP_TABLE_BY_NAME); 260 (acpi_gbl_optarg, AP_DUMP_TABLE_BY_NAME)) {
261 return (-1);
262 }
254 break; 263 break;
255 264
256 default: 265 default:
257 266
258 ap_display_usage(); 267 ap_display_usage();
259 exit(-1); 268 return (-1);
260 } 269 }
261 270
262 /* If there are no actions, this means "get/dump all tables" */ 271 /* If there are no actions, this means "get/dump all tables" */
263 272
264 if (current_action == 0) { 273 if (current_action == 0) {
265 ap_insert_action(NULL, AP_DUMP_ALL_TABLES); 274 if (ap_insert_action(NULL, AP_DUMP_ALL_TABLES)) {
275 return (-1);
276 }
266 } 277 }
267 278
268 return (0); 279 return (0);
@@ -280,7 +291,11 @@ static int ap_do_options(int argc, char **argv)
280 * 291 *
281 ******************************************************************************/ 292 ******************************************************************************/
282 293
294#ifndef _GNU_EFI
283int ACPI_SYSTEM_XFACE main(int argc, char *argv[]) 295int ACPI_SYSTEM_XFACE main(int argc, char *argv[])
296#else
297int ACPI_SYSTEM_XFACE acpi_main(int argc, char *argv[])
298#endif
284{ 299{
285 int status = 0; 300 int status = 0;
286 struct ap_dump_action *action; 301 struct ap_dump_action *action;
@@ -288,11 +303,17 @@ int ACPI_SYSTEM_XFACE main(int argc, char *argv[])
288 u32 i; 303 u32 i;
289 304
290 ACPI_DEBUG_INITIALIZE(); /* For debug version only */ 305 ACPI_DEBUG_INITIALIZE(); /* For debug version only */
306 acpi_os_initialize();
307 gbl_output_file = ACPI_FILE_OUT;
291 308
292 /* Process command line options */ 309 /* Process command line options */
293 310
294 if (ap_do_options(argc, argv)) { 311 status = ap_do_options(argc, argv);
295 return (-1); 312 if (status > 0) {
313 return (0);
314 }
315 if (status < 0) {
316 return (status);
296 } 317 }
297 318
298 /* Get/dump ACPI table(s) as requested */ 319 /* Get/dump ACPI table(s) as requested */
@@ -322,9 +343,8 @@ int ACPI_SYSTEM_XFACE main(int argc, char *argv[])
322 343
323 default: 344 default:
324 345
325 fprintf(stderr, 346 acpi_log_error("Internal error, invalid action: 0x%X\n",
326 "Internal error, invalid action: 0x%X\n", 347 action->to_be_done);
327 action->to_be_done);
328 return (-1); 348 return (-1);
329 } 349 }
330 350
@@ -333,18 +353,18 @@ int ACPI_SYSTEM_XFACE main(int argc, char *argv[])
333 } 353 }
334 } 354 }
335 355
336 if (gbl_output_file) { 356 if (gbl_output_filename) {
337 if (gbl_verbose_mode) { 357 if (gbl_verbose_mode) {
338 358
339 /* Summary for the output file */ 359 /* Summary for the output file */
340 360
341 file_size = cm_get_file_size(gbl_output_file); 361 file_size = cm_get_file_size(gbl_output_file);
342 fprintf(stderr, 362 acpi_log_error
343 "Output file %s contains 0x%X (%u) bytes\n\n", 363 ("Output file %s contains 0x%X (%u) bytes\n\n",
344 gbl_output_filename, file_size, file_size); 364 gbl_output_filename, file_size, file_size);
345 } 365 }
346 366
347 fclose(gbl_output_file); 367 acpi_os_close_file(gbl_output_file);
348 } 368 }
349 369
350 return (status); 370 return (status);
diff --git a/tools/power/cpupower/bench/parse.c b/tools/power/cpupower/bench/parse.c
index 543bba14ae2c..f503fb53824e 100644
--- a/tools/power/cpupower/bench/parse.c
+++ b/tools/power/cpupower/bench/parse.c
@@ -158,14 +158,15 @@ struct config *prepare_default_config()
158int prepare_config(const char *path, struct config *config) 158int prepare_config(const char *path, struct config *config)
159{ 159{
160 size_t len = 0; 160 size_t len = 0;
161 char *opt, *val, *line = NULL; 161 char opt[16], val[32], *line = NULL;
162 FILE *configfile = fopen(path, "r"); 162 FILE *configfile;
163 163
164 if (config == NULL) { 164 if (config == NULL) {
165 fprintf(stderr, "error: config is NULL\n"); 165 fprintf(stderr, "error: config is NULL\n");
166 return 1; 166 return 1;
167 } 167 }
168 168
169 configfile = fopen(path, "r");
169 if (configfile == NULL) { 170 if (configfile == NULL) {
170 perror("fopen"); 171 perror("fopen");
171 fprintf(stderr, "error: unable to read configfile\n"); 172 fprintf(stderr, "error: unable to read configfile\n");
@@ -174,52 +175,54 @@ int prepare_config(const char *path, struct config *config)
174 } 175 }
175 176
176 while (getline(&line, &len, configfile) != -1) { 177 while (getline(&line, &len, configfile) != -1) {
177 if (line[0] == '#' || line[0] == ' ') 178 if (line[0] == '#' || line[0] == ' ' || line[0] == '\n')
178 continue; 179 continue;
179 180
180 sscanf(line, "%as = %as", &opt, &val); 181 if (sscanf(line, "%14s = %30s", opt, val) < 2)
182 continue;
181 183
182 dprintf("parsing: %s -> %s\n", opt, val); 184 dprintf("parsing: %s -> %s\n", opt, val);
183 185
184 if (strncmp("sleep", opt, strlen(opt)) == 0) 186 if (strcmp("sleep", opt) == 0)
185 sscanf(val, "%li", &config->sleep); 187 sscanf(val, "%li", &config->sleep);
186 188
187 else if (strncmp("load", opt, strlen(opt)) == 0) 189 else if (strcmp("load", opt) == 0)
188 sscanf(val, "%li", &config->load); 190 sscanf(val, "%li", &config->load);
189 191
190 else if (strncmp("load_step", opt, strlen(opt)) == 0) 192 else if (strcmp("load_step", opt) == 0)
191 sscanf(val, "%li", &config->load_step); 193 sscanf(val, "%li", &config->load_step);
192 194
193 else if (strncmp("sleep_step", opt, strlen(opt)) == 0) 195 else if (strcmp("sleep_step", opt) == 0)
194 sscanf(val, "%li", &config->sleep_step); 196 sscanf(val, "%li", &config->sleep_step);
195 197
196 else if (strncmp("cycles", opt, strlen(opt)) == 0) 198 else if (strcmp("cycles", opt) == 0)
197 sscanf(val, "%u", &config->cycles); 199 sscanf(val, "%u", &config->cycles);
198 200
199 else if (strncmp("rounds", opt, strlen(opt)) == 0) 201 else if (strcmp("rounds", opt) == 0)
200 sscanf(val, "%u", &config->rounds); 202 sscanf(val, "%u", &config->rounds);
201 203
202 else if (strncmp("verbose", opt, strlen(opt)) == 0) 204 else if (strcmp("verbose", opt) == 0)
203 sscanf(val, "%u", &config->verbose); 205 sscanf(val, "%u", &config->verbose);
204 206
205 else if (strncmp("output", opt, strlen(opt)) == 0) 207 else if (strcmp("output", opt) == 0)
206 config->output = prepare_output(val); 208 config->output = prepare_output(val);
207 209
208 else if (strncmp("cpu", opt, strlen(opt)) == 0) 210 else if (strcmp("cpu", opt) == 0)
209 sscanf(val, "%u", &config->cpu); 211 sscanf(val, "%u", &config->cpu);
210 212
211 else if (strncmp("governor", opt, 14) == 0) 213 else if (strcmp("governor", opt) == 0) {
212 strncpy(config->governor, val, 14); 214 strncpy(config->governor, val,
215 sizeof(config->governor));
216 config->governor[sizeof(config->governor) - 1] = '\0';
217 }
213 218
214 else if (strncmp("priority", opt, strlen(opt)) == 0) { 219 else if (strcmp("priority", opt) == 0) {
215 if (string_to_prio(val) != SCHED_ERR) 220 if (string_to_prio(val) != SCHED_ERR)
216 config->prio = string_to_prio(val); 221 config->prio = string_to_prio(val);
217 } 222 }
218 } 223 }
219 224
220 free(line); 225 free(line);
221 free(opt);
222 free(val);
223 226
224 return 0; 227 return 0;
225} 228}
diff --git a/tools/power/cpupower/utils/cpufreq-set.c b/tools/power/cpupower/utils/cpufreq-set.c
index a416de80c55e..f656e585ed45 100644
--- a/tools/power/cpupower/utils/cpufreq-set.c
+++ b/tools/power/cpupower/utils/cpufreq-set.c
@@ -320,12 +320,11 @@ int cmd_freq_set(int argc, char **argv)
320 320
321 printf(_("Setting cpu: %d\n"), cpu); 321 printf(_("Setting cpu: %d\n"), cpu);
322 ret = do_one_cpu(cpu, &new_pol, freq, policychange); 322 ret = do_one_cpu(cpu, &new_pol, freq, policychange);
323 if (ret) 323 if (ret) {
324 break; 324 print_error();
325 return ret;
326 }
325 } 327 }
326 328
327 if (ret) 329 return 0;
328 print_error();
329
330 return ret;
331} 330}
diff --git a/tools/power/cpupower/utils/helpers/sysfs.c b/tools/power/cpupower/utils/helpers/sysfs.c
index 851c7a16ca49..09afe5d87f2b 100644
--- a/tools/power/cpupower/utils/helpers/sysfs.c
+++ b/tools/power/cpupower/utils/helpers/sysfs.c
@@ -81,7 +81,7 @@ int sysfs_is_cpu_online(unsigned int cpu)
81 close(fd); 81 close(fd);
82 82
83 value = strtoull(linebuf, &endp, 0); 83 value = strtoull(linebuf, &endp, 0);
84 if (value > 1 || value < 0) 84 if (value > 1)
85 return -EINVAL; 85 return -EINVAL;
86 86
87 return value; 87 return value;
diff --git a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
index 5650ab5a2c20..90a8c4f071e7 100644
--- a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
+++ b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
@@ -237,7 +237,7 @@ static int init_maxfreq_mode(void)
237 unsigned long long hwcr; 237 unsigned long long hwcr;
238 unsigned long min; 238 unsigned long min;
239 239
240 if (!cpupower_cpu_info.caps & CPUPOWER_CAP_INV_TSC) 240 if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_INV_TSC))
241 goto use_sysfs; 241 goto use_sysfs;
242 242
243 if (cpupower_cpu_info.vendor == X86_VENDOR_AMD) { 243 if (cpupower_cpu_info.vendor == X86_VENDOR_AMD) {
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index d0396af99fa0..5b1b807265a1 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -267,90 +267,90 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr)
267/* 267/*
268 * Example Format w/ field column widths: 268 * Example Format w/ field column widths:
269 * 269 *
270 * Package Core CPU Avg_MHz Bzy_MHz TSC_MHz SMI %Busy CPU_%c1 CPU_%c3 CPU_%c6 CPU_%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt 270 * Package Core CPU Avg_MHz Bzy_MHz TSC_MHz SMI %Busy CPU_%c1 CPU_%c3 CPU_%c6 CPU_%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt
271 * 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 271 * 123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678
272 */ 272 */
273 273
274void print_header(void) 274void print_header(void)
275{ 275{
276 if (show_pkg) 276 if (show_pkg)
277 outp += sprintf(outp, "Package "); 277 outp += sprintf(outp, " Package");
278 if (show_core) 278 if (show_core)
279 outp += sprintf(outp, " Core "); 279 outp += sprintf(outp, " Core");
280 if (show_cpu) 280 if (show_cpu)
281 outp += sprintf(outp, " CPU "); 281 outp += sprintf(outp, " CPU");
282 if (has_aperf) 282 if (has_aperf)
283 outp += sprintf(outp, "Avg_MHz "); 283 outp += sprintf(outp, " Avg_MHz");
284 if (do_nhm_cstates) 284 if (do_nhm_cstates)
285 outp += sprintf(outp, " %%Busy "); 285 outp += sprintf(outp, " %%Busy");
286 if (has_aperf) 286 if (has_aperf)
287 outp += sprintf(outp, "Bzy_MHz "); 287 outp += sprintf(outp, " Bzy_MHz");
288 outp += sprintf(outp, "TSC_MHz "); 288 outp += sprintf(outp, " TSC_MHz");
289 if (do_smi) 289 if (do_smi)
290 outp += sprintf(outp, " SMI "); 290 outp += sprintf(outp, " SMI");
291 if (extra_delta_offset32) 291 if (extra_delta_offset32)
292 outp += sprintf(outp, " count 0x%03X ", extra_delta_offset32); 292 outp += sprintf(outp, " count 0x%03X", extra_delta_offset32);
293 if (extra_delta_offset64) 293 if (extra_delta_offset64)
294 outp += sprintf(outp, " COUNT 0x%03X ", extra_delta_offset64); 294 outp += sprintf(outp, " COUNT 0x%03X", extra_delta_offset64);
295 if (extra_msr_offset32) 295 if (extra_msr_offset32)
296 outp += sprintf(outp, " MSR 0x%03X ", extra_msr_offset32); 296 outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset32);
297 if (extra_msr_offset64) 297 if (extra_msr_offset64)
298 outp += sprintf(outp, " MSR 0x%03X ", extra_msr_offset64); 298 outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64);
299 if (do_nhm_cstates) 299 if (do_nhm_cstates)
300 outp += sprintf(outp, " CPU%%c1 "); 300 outp += sprintf(outp, " CPU%%c1");
301 if (do_nhm_cstates && !do_slm_cstates) 301 if (do_nhm_cstates && !do_slm_cstates)
302 outp += sprintf(outp, " CPU%%c3 "); 302 outp += sprintf(outp, " CPU%%c3");
303 if (do_nhm_cstates) 303 if (do_nhm_cstates)
304 outp += sprintf(outp, " CPU%%c6 "); 304 outp += sprintf(outp, " CPU%%c6");
305 if (do_snb_cstates) 305 if (do_snb_cstates)
306 outp += sprintf(outp, " CPU%%c7 "); 306 outp += sprintf(outp, " CPU%%c7");
307 307
308 if (do_dts) 308 if (do_dts)
309 outp += sprintf(outp, "CoreTmp "); 309 outp += sprintf(outp, " CoreTmp");
310 if (do_ptm) 310 if (do_ptm)
311 outp += sprintf(outp, " PkgTmp "); 311 outp += sprintf(outp, " PkgTmp");
312 312
313 if (do_snb_cstates) 313 if (do_snb_cstates)
314 outp += sprintf(outp, "Pkg%%pc2 "); 314 outp += sprintf(outp, " Pkg%%pc2");
315 if (do_nhm_cstates && !do_slm_cstates) 315 if (do_nhm_cstates && !do_slm_cstates)
316 outp += sprintf(outp, "Pkg%%pc3 "); 316 outp += sprintf(outp, " Pkg%%pc3");
317 if (do_nhm_cstates && !do_slm_cstates) 317 if (do_nhm_cstates && !do_slm_cstates)
318 outp += sprintf(outp, "Pkg%%pc6 "); 318 outp += sprintf(outp, " Pkg%%pc6");
319 if (do_snb_cstates) 319 if (do_snb_cstates)
320 outp += sprintf(outp, "Pkg%%pc7 "); 320 outp += sprintf(outp, " Pkg%%pc7");
321 if (do_c8_c9_c10) { 321 if (do_c8_c9_c10) {
322 outp += sprintf(outp, "Pkg%%pc8 "); 322 outp += sprintf(outp, " Pkg%%pc8");
323 outp += sprintf(outp, "Pkg%%pc9 "); 323 outp += sprintf(outp, " Pkg%%pc9");
324 outp += sprintf(outp, "Pk%%pc10 "); 324 outp += sprintf(outp, " Pk%%pc10");
325 } 325 }
326 326
327 if (do_rapl && !rapl_joules) { 327 if (do_rapl && !rapl_joules) {
328 if (do_rapl & RAPL_PKG) 328 if (do_rapl & RAPL_PKG)
329 outp += sprintf(outp, "PkgWatt "); 329 outp += sprintf(outp, " PkgWatt");
330 if (do_rapl & RAPL_CORES) 330 if (do_rapl & RAPL_CORES)
331 outp += sprintf(outp, "CorWatt "); 331 outp += sprintf(outp, " CorWatt");
332 if (do_rapl & RAPL_GFX) 332 if (do_rapl & RAPL_GFX)
333 outp += sprintf(outp, "GFXWatt "); 333 outp += sprintf(outp, " GFXWatt");
334 if (do_rapl & RAPL_DRAM) 334 if (do_rapl & RAPL_DRAM)
335 outp += sprintf(outp, "RAMWatt "); 335 outp += sprintf(outp, " RAMWatt");
336 if (do_rapl & RAPL_PKG_PERF_STATUS) 336 if (do_rapl & RAPL_PKG_PERF_STATUS)
337 outp += sprintf(outp, " PKG_%% "); 337 outp += sprintf(outp, " PKG_%%");
338 if (do_rapl & RAPL_DRAM_PERF_STATUS) 338 if (do_rapl & RAPL_DRAM_PERF_STATUS)
339 outp += sprintf(outp, " RAM_%% "); 339 outp += sprintf(outp, " RAM_%%");
340 } else { 340 } else {
341 if (do_rapl & RAPL_PKG) 341 if (do_rapl & RAPL_PKG)
342 outp += sprintf(outp, " Pkg_J "); 342 outp += sprintf(outp, " Pkg_J");
343 if (do_rapl & RAPL_CORES) 343 if (do_rapl & RAPL_CORES)
344 outp += sprintf(outp, " Cor_J "); 344 outp += sprintf(outp, " Cor_J");
345 if (do_rapl & RAPL_GFX) 345 if (do_rapl & RAPL_GFX)
346 outp += sprintf(outp, " GFX_J "); 346 outp += sprintf(outp, " GFX_J");
347 if (do_rapl & RAPL_DRAM) 347 if (do_rapl & RAPL_DRAM)
348 outp += sprintf(outp, " RAM_W "); 348 outp += sprintf(outp, " RAM_W");
349 if (do_rapl & RAPL_PKG_PERF_STATUS) 349 if (do_rapl & RAPL_PKG_PERF_STATUS)
350 outp += sprintf(outp, " PKG_%% "); 350 outp += sprintf(outp, " PKG_%%");
351 if (do_rapl & RAPL_DRAM_PERF_STATUS) 351 if (do_rapl & RAPL_DRAM_PERF_STATUS)
352 outp += sprintf(outp, " RAM_%% "); 352 outp += sprintf(outp, " RAM_%%");
353 outp += sprintf(outp, " time "); 353 outp += sprintf(outp, " time");
354 354
355 } 355 }
356 outp += sprintf(outp, "\n"); 356 outp += sprintf(outp, "\n");
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index e66e710cc595..36ff2e4c7b6f 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -2,8 +2,10 @@ TARGETS = breakpoints
2TARGETS += cpu-hotplug 2TARGETS += cpu-hotplug
3TARGETS += efivarfs 3TARGETS += efivarfs
4TARGETS += kcmp 4TARGETS += kcmp
5TARGETS += memfd
5TARGETS += memory-hotplug 6TARGETS += memory-hotplug
6TARGETS += mqueue 7TARGETS += mqueue
8TARGETS += mount
7TARGETS += net 9TARGETS += net
8TARGETS += ptrace 10TARGETS += ptrace
9TARGETS += timers 11TARGETS += timers
@@ -11,6 +13,10 @@ TARGETS += vm
11TARGETS += powerpc 13TARGETS += powerpc
12TARGETS += user 14TARGETS += user
13TARGETS += sysctl 15TARGETS += sysctl
16TARGETS += firmware
17
18TARGETS_HOTPLUG = cpu-hotplug
19TARGETS_HOTPLUG += memory-hotplug
14 20
15all: 21all:
16 for TARGET in $(TARGETS); do \ 22 for TARGET in $(TARGETS); do \
@@ -22,6 +28,21 @@ run_tests: all
22 make -C $$TARGET run_tests; \ 28 make -C $$TARGET run_tests; \
23 done; 29 done;
24 30
31hotplug:
32 for TARGET in $(TARGETS_HOTPLUG); do \
33 make -C $$TARGET; \
34 done;
35
36run_hotplug: hotplug
37 for TARGET in $(TARGETS_HOTPLUG); do \
38 make -C $$TARGET run_full_test; \
39 done;
40
41clean_hotplug:
42 for TARGET in $(TARGETS_HOTPLUG); do \
43 make -C $$TARGET clean; \
44 done;
45
25clean: 46clean:
26 for TARGET in $(TARGETS); do \ 47 for TARGET in $(TARGETS); do \
27 make -C $$TARGET clean; \ 48 make -C $$TARGET clean; \
diff --git a/tools/testing/selftests/README.txt b/tools/testing/selftests/README.txt
index 5e2faf9c55d3..2660d5ff9179 100644
--- a/tools/testing/selftests/README.txt
+++ b/tools/testing/selftests/README.txt
@@ -4,8 +4,15 @@ The kernel contains a set of "self tests" under the tools/testing/selftests/
4directory. These are intended to be small unit tests to exercise individual 4directory. These are intended to be small unit tests to exercise individual
5code paths in the kernel. 5code paths in the kernel.
6 6
7Running the selftests 7On some systems, hot-plug tests could hang forever waiting for cpu and
8===================== 8memory to be ready to be offlined. A special hot-plug target is created
9to run full range of hot-plug tests. In default mode, hot-plug tests run
10in safe mode with a limited scope. In limited mode, cpu-hotplug test is
11run on a single cpu as opposed to all hotplug capable cpus, and memory
12hotplug test is run on 2% of hotplug capable memory instead of 10%.
13
14Running the selftests (hotplug tests are run in limited mode)
15=============================================================
9 16
10To build the tests: 17To build the tests:
11 18
@@ -18,14 +25,26 @@ To run the tests:
18 25
19- note that some tests will require root privileges. 26- note that some tests will require root privileges.
20 27
21 28To run only tests targeted for a single subsystem: (including
22To run only tests targetted for a single subsystem: 29hotplug targets in limited mode)
23 30
24 $ make -C tools/testing/selftests TARGETS=cpu-hotplug run_tests 31 $ make -C tools/testing/selftests TARGETS=cpu-hotplug run_tests
25 32
26See the top-level tools/testing/selftests/Makefile for the list of all possible 33See the top-level tools/testing/selftests/Makefile for the list of all possible
27targets. 34targets.
28 35
36Running the full range hotplug selftests
37========================================
38
39To build the tests:
40
41 $ make -C tools/testing/selftests hotplug
42
43To run the tests:
44
45 $ make -C tools/testing/selftests run_hotplug
46
47- note that some tests will require root privileges.
29 48
30Contributing new tests 49Contributing new tests
31====================== 50======================
diff --git a/tools/testing/selftests/cpu-hotplug/Makefile b/tools/testing/selftests/cpu-hotplug/Makefile
index 790c23a9db44..e9c28d8dc84b 100644
--- a/tools/testing/selftests/cpu-hotplug/Makefile
+++ b/tools/testing/selftests/cpu-hotplug/Makefile
@@ -3,4 +3,7 @@ all:
3run_tests: 3run_tests:
4 @/bin/bash ./on-off-test.sh || echo "cpu-hotplug selftests: [FAIL]" 4 @/bin/bash ./on-off-test.sh || echo "cpu-hotplug selftests: [FAIL]"
5 5
6run_full_test:
7 @/bin/bash ./on-off-test.sh -a || echo "cpu-hotplug selftests: [FAIL]"
8
6clean: 9clean:
diff --git a/tools/testing/selftests/cpu-hotplug/on-off-test.sh b/tools/testing/selftests/cpu-hotplug/on-off-test.sh
index bdde7cf428bb..98b1d6565f2c 100644
--- a/tools/testing/selftests/cpu-hotplug/on-off-test.sh
+++ b/tools/testing/selftests/cpu-hotplug/on-off-test.sh
@@ -11,6 +11,8 @@ prerequisite()
11 exit 0 11 exit 0
12 fi 12 fi
13 13
14 taskset -p 01 $$
15
14 SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` 16 SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
15 17
16 if [ ! -d "$SYSFS" ]; then 18 if [ ! -d "$SYSFS" ]; then
@@ -22,6 +24,19 @@ prerequisite()
22 echo $msg cpu hotplug is not supported >&2 24 echo $msg cpu hotplug is not supported >&2
23 exit 0 25 exit 0
24 fi 26 fi
27
28 echo "CPU online/offline summary:"
29 online_cpus=`cat $SYSFS/devices/system/cpu/online`
30 online_max=${online_cpus##*-}
31 echo -e "\t Cpus in online state: $online_cpus"
32
33 offline_cpus=`cat $SYSFS/devices/system/cpu/offline`
34 if [[ "a$offline_cpus" = "a" ]]; then
35 offline_cpus=0
36 else
37 offline_max=${offline_cpus##*-}
38 fi
39 echo -e "\t Cpus in offline state: $offline_cpus"
25} 40}
26 41
27# 42#
@@ -113,15 +128,25 @@ offline_cpu_expect_fail()
113} 128}
114 129
115error=-12 130error=-12
131allcpus=0
116priority=0 132priority=0
133online_cpus=0
134online_max=0
135offline_cpus=0
136offline_max=0
117 137
118while getopts e:hp: opt; do 138while getopts e:ahp: opt; do
119 case $opt in 139 case $opt in
120 e) 140 e)
121 error=$OPTARG 141 error=$OPTARG
122 ;; 142 ;;
143 a)
144 allcpus=1
145 ;;
123 h) 146 h)
124 echo "Usage $0 [ -e errno ] [ -p notifier-priority ]" 147 echo "Usage $0 [ -a ] [ -e errno ] [ -p notifier-priority ]"
148 echo -e "\t default offline one cpu"
149 echo -e "\t run with -a option to offline all cpus"
125 exit 150 exit
126 ;; 151 ;;
127 p) 152 p)
@@ -138,6 +163,29 @@ fi
138prerequisite 163prerequisite
139 164
140# 165#
166# Safe test (default) - offline and online one cpu
167#
168if [ $allcpus -eq 0 ]; then
169 echo "Limited scope test: one hotplug cpu"
170 echo -e "\t (leaves cpu in the original state):"
171 echo -e "\t online to offline to online: cpu $online_max"
172 offline_cpu_expect_success $online_max
173 online_cpu_expect_success $online_max
174
175 if [[ $offline_cpus -gt 0 ]]; then
176 echo -e "\t offline to online to offline: cpu $offline_max"
177 online_cpu_expect_success $offline_max
178 offline_cpu_expect_success $offline_max
179 fi
180 exit 0
181else
182 echo "Full scope test: all hotplug cpus"
183 echo -e "\t online all offline cpus"
184 echo -e "\t offline all online cpus"
185 echo -e "\t online all offline cpus"
186fi
187
188#
141# Online all hot-pluggable CPUs 189# Online all hot-pluggable CPUs
142# 190#
143for cpu in `hotplaggable_offline_cpus`; do 191for cpu in `hotplaggable_offline_cpus`; do
diff --git a/tools/testing/selftests/firmware/Makefile b/tools/testing/selftests/firmware/Makefile
new file mode 100644
index 000000000000..e23cce0bbc3a
--- /dev/null
+++ b/tools/testing/selftests/firmware/Makefile
@@ -0,0 +1,27 @@
1# Makefile for firmware loading selftests
2
3# No binaries, but make sure arg-less "make" doesn't trigger "run_tests"
4all:
5
6fw_filesystem:
7 @if /bin/sh ./fw_filesystem.sh ; then \
8 echo "fw_filesystem: ok"; \
9 else \
10 echo "fw_filesystem: [FAIL]"; \
11 exit 1; \
12 fi
13
14fw_userhelper:
15 @if /bin/sh ./fw_userhelper.sh ; then \
16 echo "fw_userhelper: ok"; \
17 else \
18 echo "fw_userhelper: [FAIL]"; \
19 exit 1; \
20 fi
21
22run_tests: all fw_filesystem fw_userhelper
23
24# Nothing to clean up.
25clean:
26
27.PHONY: all clean run_tests fw_filesystem fw_userhelper
diff --git a/tools/testing/selftests/firmware/fw_filesystem.sh b/tools/testing/selftests/firmware/fw_filesystem.sh
new file mode 100644
index 000000000000..3fc6c10c2479
--- /dev/null
+++ b/tools/testing/selftests/firmware/fw_filesystem.sh
@@ -0,0 +1,62 @@
1#!/bin/sh
2# This validates that the kernel will load firmware out of its list of
3# firmware locations on disk. Since the user helper does similar work,
4# we reset the custom load directory to a location the user helper doesn't
5# know so we can be sure we're not accidentally testing the user helper.
6set -e
7
8modprobe test_firmware
9
10DIR=/sys/devices/virtual/misc/test_firmware
11
12OLD_TIMEOUT=$(cat /sys/class/firmware/timeout)
13OLD_FWPATH=$(cat /sys/module/firmware_class/parameters/path)
14
15FWPATH=$(mktemp -d)
16FW="$FWPATH/test-firmware.bin"
17
18test_finish()
19{
20 echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout
21 echo -n "$OLD_PATH" >/sys/module/firmware_class/parameters/path
22 rm -f "$FW"
23 rmdir "$FWPATH"
24}
25
26trap "test_finish" EXIT
27
28# Turn down the timeout so failures don't take so long.
29echo 1 >/sys/class/firmware/timeout
30# Set the kernel search path.
31echo -n "$FWPATH" >/sys/module/firmware_class/parameters/path
32
33# This is an unlikely real-world firmware content. :)
34echo "ABCD0123" >"$FW"
35
36NAME=$(basename "$FW")
37
38# Request a firmware that doesn't exist, it should fail.
39echo -n "nope-$NAME" >"$DIR"/trigger_request
40if diff -q "$FW" /dev/test_firmware >/dev/null ; then
41 echo "$0: firmware was not expected to match" >&2
42 exit 1
43else
44 echo "$0: timeout works"
45fi
46
47# This should succeed via kernel load or will fail after 1 second after
48# being handed over to the user helper, which won't find the fw either.
49if ! echo -n "$NAME" >"$DIR"/trigger_request ; then
50 echo "$0: could not trigger request" >&2
51 exit 1
52fi
53
54# Verify the contents are what we expect.
55if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
56 echo "$0: firmware was not loaded" >&2
57 exit 1
58else
59 echo "$0: filesystem loading works"
60fi
61
62exit 0
diff --git a/tools/testing/selftests/firmware/fw_userhelper.sh b/tools/testing/selftests/firmware/fw_userhelper.sh
new file mode 100644
index 000000000000..6efbade12139
--- /dev/null
+++ b/tools/testing/selftests/firmware/fw_userhelper.sh
@@ -0,0 +1,89 @@
1#!/bin/sh
2# This validates that the kernel will fall back to using the user helper
3# to load firmware it can't find on disk itself. We must request a firmware
4# that the kernel won't find, and any installed helper (e.g. udev) also
5# won't find so that we can do the load ourself manually.
6set -e
7
8modprobe test_firmware
9
10DIR=/sys/devices/virtual/misc/test_firmware
11
12OLD_TIMEOUT=$(cat /sys/class/firmware/timeout)
13
14FWPATH=$(mktemp -d)
15FW="$FWPATH/test-firmware.bin"
16
17test_finish()
18{
19 echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout
20 rm -f "$FW"
21 rmdir "$FWPATH"
22}
23
24load_fw()
25{
26 local name="$1"
27 local file="$2"
28
29 # This will block until our load (below) has finished.
30 echo -n "$name" >"$DIR"/trigger_request &
31
32 # Give kernel a chance to react.
33 local timeout=10
34 while [ ! -e "$DIR"/"$name"/loading ]; do
35 sleep 0.1
36 timeout=$(( $timeout - 1 ))
37 if [ "$timeout" -eq 0 ]; then
38 echo "$0: firmware interface never appeared" >&2
39 exit 1
40 fi
41 done
42
43 echo 1 >"$DIR"/"$name"/loading
44 cat "$file" >"$DIR"/"$name"/data
45 echo 0 >"$DIR"/"$name"/loading
46
47 # Wait for request to finish.
48 wait
49}
50
51trap "test_finish" EXIT
52
53# This is an unlikely real-world firmware content. :)
54echo "ABCD0123" >"$FW"
55NAME=$(basename "$FW")
56
57# Test failure when doing nothing (timeout works).
58echo 1 >/sys/class/firmware/timeout
59echo -n "$NAME" >"$DIR"/trigger_request
60if diff -q "$FW" /dev/test_firmware >/dev/null ; then
61 echo "$0: firmware was not expected to match" >&2
62 exit 1
63else
64 echo "$0: timeout works"
65fi
66
67# Put timeout high enough for us to do work but not so long that failures
68# slow down this test too much.
69echo 4 >/sys/class/firmware/timeout
70
71# Load this script instead of the desired firmware.
72load_fw "$NAME" "$0"
73if diff -q "$FW" /dev/test_firmware >/dev/null ; then
74 echo "$0: firmware was not expected to match" >&2
75 exit 1
76else
77 echo "$0: firmware comparison works"
78fi
79
80# Do a proper load, which should work correctly.
81load_fw "$NAME" "$FW"
82if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
83 echo "$0: firmware was not loaded" >&2
84 exit 1
85else
86 echo "$0: user helper firmware loading works"
87fi
88
89exit 0
diff --git a/tools/testing/selftests/kcmp/kcmp_test.c b/tools/testing/selftests/kcmp/kcmp_test.c
index fa4f1b37e045..dbba4084869c 100644
--- a/tools/testing/selftests/kcmp/kcmp_test.c
+++ b/tools/testing/selftests/kcmp/kcmp_test.c
@@ -81,7 +81,7 @@ int main(int argc, char **argv)
81 /* Compare with self */ 81 /* Compare with self */
82 ret = sys_kcmp(pid1, pid1, KCMP_VM, 0, 0); 82 ret = sys_kcmp(pid1, pid1, KCMP_VM, 0, 0);
83 if (ret) { 83 if (ret) {
84 printf("FAIL: 0 expected but %li returned (%s)\n", 84 printf("FAIL: 0 expected but %d returned (%s)\n",
85 ret, strerror(errno)); 85 ret, strerror(errno));
86 ret = -1; 86 ret = -1;
87 } else 87 } else
diff --git a/tools/testing/selftests/memfd/.gitignore b/tools/testing/selftests/memfd/.gitignore
new file mode 100644
index 000000000000..afe87c40ac80
--- /dev/null
+++ b/tools/testing/selftests/memfd/.gitignore
@@ -0,0 +1,4 @@
1fuse_mnt
2fuse_test
3memfd_test
4memfd-test-file
diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile
new file mode 100644
index 000000000000..6816c491c5ff
--- /dev/null
+++ b/tools/testing/selftests/memfd/Makefile
@@ -0,0 +1,41 @@
1uname_M := $(shell uname -m 2>/dev/null || echo not)
2ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/)
3ifeq ($(ARCH),i386)
4 ARCH := X86
5endif
6ifeq ($(ARCH),x86_64)
7 ARCH := X86
8endif
9
10CFLAGS += -D_FILE_OFFSET_BITS=64
11CFLAGS += -I../../../../arch/x86/include/generated/uapi/
12CFLAGS += -I../../../../arch/x86/include/uapi/
13CFLAGS += -I../../../../include/uapi/
14CFLAGS += -I../../../../include/
15
16all:
17ifeq ($(ARCH),X86)
18 gcc $(CFLAGS) memfd_test.c -o memfd_test
19else
20 echo "Not an x86 target, can't build memfd selftest"
21endif
22
23run_tests: all
24ifeq ($(ARCH),X86)
25 gcc $(CFLAGS) memfd_test.c -o memfd_test
26endif
27 @./memfd_test || echo "memfd_test: [FAIL]"
28
29build_fuse:
30ifeq ($(ARCH),X86)
31 gcc $(CFLAGS) fuse_mnt.c `pkg-config fuse --cflags --libs` -o fuse_mnt
32 gcc $(CFLAGS) fuse_test.c -o fuse_test
33else
34 echo "Not an x86 target, can't build memfd selftest"
35endif
36
37run_fuse: build_fuse
38 @./run_fuse_test.sh || echo "fuse_test: [FAIL]"
39
40clean:
41 $(RM) memfd_test fuse_test
diff --git a/tools/testing/selftests/memfd/fuse_mnt.c b/tools/testing/selftests/memfd/fuse_mnt.c
new file mode 100644
index 000000000000..feacf1280fcd
--- /dev/null
+++ b/tools/testing/selftests/memfd/fuse_mnt.c
@@ -0,0 +1,110 @@
1/*
2 * memfd test file-system
3 * This file uses FUSE to create a dummy file-system with only one file /memfd.
4 * This file is read-only and takes 1s per read.
5 *
6 * This file-system is used by the memfd test-cases to force the kernel to pin
7 * pages during reads(). Due to the 1s delay of this file-system, this is a
8 * nice way to test race-conditions against get_user_pages() in the kernel.
9 *
10 * We use direct_io==1 to force the kernel to use direct-IO for this
11 * file-system.
12 */
13
14#define FUSE_USE_VERSION 26
15
16#include <fuse.h>
17#include <stdio.h>
18#include <string.h>
19#include <errno.h>
20#include <fcntl.h>
21#include <unistd.h>
22
23static const char memfd_content[] = "memfd-example-content";
24static const char memfd_path[] = "/memfd";
25
26static int memfd_getattr(const char *path, struct stat *st)
27{
28 memset(st, 0, sizeof(*st));
29
30 if (!strcmp(path, "/")) {
31 st->st_mode = S_IFDIR | 0755;
32 st->st_nlink = 2;
33 } else if (!strcmp(path, memfd_path)) {
34 st->st_mode = S_IFREG | 0444;
35 st->st_nlink = 1;
36 st->st_size = strlen(memfd_content);
37 } else {
38 return -ENOENT;
39 }
40
41 return 0;
42}
43
44static int memfd_readdir(const char *path,
45 void *buf,
46 fuse_fill_dir_t filler,
47 off_t offset,
48 struct fuse_file_info *fi)
49{
50 if (strcmp(path, "/"))
51 return -ENOENT;
52
53 filler(buf, ".", NULL, 0);
54 filler(buf, "..", NULL, 0);
55 filler(buf, memfd_path + 1, NULL, 0);
56
57 return 0;
58}
59
60static int memfd_open(const char *path, struct fuse_file_info *fi)
61{
62 if (strcmp(path, memfd_path))
63 return -ENOENT;
64
65 if ((fi->flags & 3) != O_RDONLY)
66 return -EACCES;
67
68 /* force direct-IO */
69 fi->direct_io = 1;
70
71 return 0;
72}
73
74static int memfd_read(const char *path,
75 char *buf,
76 size_t size,
77 off_t offset,
78 struct fuse_file_info *fi)
79{
80 size_t len;
81
82 if (strcmp(path, memfd_path) != 0)
83 return -ENOENT;
84
85 sleep(1);
86
87 len = strlen(memfd_content);
88 if (offset < len) {
89 if (offset + size > len)
90 size = len - offset;
91
92 memcpy(buf, memfd_content + offset, size);
93 } else {
94 size = 0;
95 }
96
97 return size;
98}
99
100static struct fuse_operations memfd_ops = {
101 .getattr = memfd_getattr,
102 .readdir = memfd_readdir,
103 .open = memfd_open,
104 .read = memfd_read,
105};
106
107int main(int argc, char *argv[])
108{
109 return fuse_main(argc, argv, &memfd_ops, NULL);
110}
diff --git a/tools/testing/selftests/memfd/fuse_test.c b/tools/testing/selftests/memfd/fuse_test.c
new file mode 100644
index 000000000000..67908b18f035
--- /dev/null
+++ b/tools/testing/selftests/memfd/fuse_test.c
@@ -0,0 +1,311 @@
1/*
2 * memfd GUP test-case
3 * This tests memfd interactions with get_user_pages(). We require the
4 * fuse_mnt.c program to provide a fake direct-IO FUSE mount-point for us. This
5 * file-system delays _all_ reads by 1s and forces direct-IO. This means, any
6 * read() on files in that file-system will pin the receive-buffer pages for at
7 * least 1s via get_user_pages().
8 *
9 * We use this trick to race ADD_SEALS against a write on a memfd object. The
10 * ADD_SEALS must fail if the memfd pages are still pinned. Note that we use
11 * the read() syscall with our memory-mapped memfd object as receive buffer to
12 * force the kernel to write into our memfd object.
13 */
14
15#define _GNU_SOURCE
16#define __EXPORTED_HEADERS__
17
18#include <errno.h>
19#include <inttypes.h>
20#include <limits.h>
21#include <linux/falloc.h>
22#include <linux/fcntl.h>
23#include <linux/memfd.h>
24#include <sched.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <signal.h>
28#include <string.h>
29#include <sys/mman.h>
30#include <sys/stat.h>
31#include <sys/syscall.h>
32#include <sys/wait.h>
33#include <unistd.h>
34
35#define MFD_DEF_SIZE 8192
36#define STACK_SIZE 65535
37
38static int sys_memfd_create(const char *name,
39 unsigned int flags)
40{
41 return syscall(__NR_memfd_create, name, flags);
42}
43
44static int mfd_assert_new(const char *name, loff_t sz, unsigned int flags)
45{
46 int r, fd;
47
48 fd = sys_memfd_create(name, flags);
49 if (fd < 0) {
50 printf("memfd_create(\"%s\", %u) failed: %m\n",
51 name, flags);
52 abort();
53 }
54
55 r = ftruncate(fd, sz);
56 if (r < 0) {
57 printf("ftruncate(%llu) failed: %m\n", (unsigned long long)sz);
58 abort();
59 }
60
61 return fd;
62}
63
64static __u64 mfd_assert_get_seals(int fd)
65{
66 long r;
67
68 r = fcntl(fd, F_GET_SEALS);
69 if (r < 0) {
70 printf("GET_SEALS(%d) failed: %m\n", fd);
71 abort();
72 }
73
74 return r;
75}
76
77static void mfd_assert_has_seals(int fd, __u64 seals)
78{
79 __u64 s;
80
81 s = mfd_assert_get_seals(fd);
82 if (s != seals) {
83 printf("%llu != %llu = GET_SEALS(%d)\n",
84 (unsigned long long)seals, (unsigned long long)s, fd);
85 abort();
86 }
87}
88
89static void mfd_assert_add_seals(int fd, __u64 seals)
90{
91 long r;
92 __u64 s;
93
94 s = mfd_assert_get_seals(fd);
95 r = fcntl(fd, F_ADD_SEALS, seals);
96 if (r < 0) {
97 printf("ADD_SEALS(%d, %llu -> %llu) failed: %m\n",
98 fd, (unsigned long long)s, (unsigned long long)seals);
99 abort();
100 }
101}
102
103static int mfd_busy_add_seals(int fd, __u64 seals)
104{
105 long r;
106 __u64 s;
107
108 r = fcntl(fd, F_GET_SEALS);
109 if (r < 0)
110 s = 0;
111 else
112 s = r;
113
114 r = fcntl(fd, F_ADD_SEALS, seals);
115 if (r < 0 && errno != EBUSY) {
116 printf("ADD_SEALS(%d, %llu -> %llu) didn't fail as expected with EBUSY: %m\n",
117 fd, (unsigned long long)s, (unsigned long long)seals);
118 abort();
119 }
120
121 return r;
122}
123
124static void *mfd_assert_mmap_shared(int fd)
125{
126 void *p;
127
128 p = mmap(NULL,
129 MFD_DEF_SIZE,
130 PROT_READ | PROT_WRITE,
131 MAP_SHARED,
132 fd,
133 0);
134 if (p == MAP_FAILED) {
135 printf("mmap() failed: %m\n");
136 abort();
137 }
138
139 return p;
140}
141
142static void *mfd_assert_mmap_private(int fd)
143{
144 void *p;
145
146 p = mmap(NULL,
147 MFD_DEF_SIZE,
148 PROT_READ | PROT_WRITE,
149 MAP_PRIVATE,
150 fd,
151 0);
152 if (p == MAP_FAILED) {
153 printf("mmap() failed: %m\n");
154 abort();
155 }
156
157 return p;
158}
159
160static int global_mfd = -1;
161static void *global_p = NULL;
162
163static int sealing_thread_fn(void *arg)
164{
165 int sig, r;
166
167 /*
168 * This thread first waits 200ms so any pending operation in the parent
169 * is correctly started. After that, it tries to seal @global_mfd as
170 * SEAL_WRITE. This _must_ fail as the parent thread has a read() into
171 * that memory mapped object still ongoing.
172 * We then wait one more second and try sealing again. This time it
173 * must succeed as there shouldn't be anyone else pinning the pages.
174 */
175
176 /* wait 200ms for FUSE-request to be active */
177 usleep(200000);
178
179 /* unmount mapping before sealing to avoid i_mmap_writable failures */
180 munmap(global_p, MFD_DEF_SIZE);
181
182 /* Try sealing the global file; expect EBUSY or success. Current
183 * kernels will never succeed, but in the future, kernels might
184 * implement page-replacements or other fancy ways to avoid racing
185 * writes. */
186 r = mfd_busy_add_seals(global_mfd, F_SEAL_WRITE);
187 if (r >= 0) {
188 printf("HURRAY! This kernel fixed GUP races!\n");
189 } else {
190 /* wait 1s more so the FUSE-request is done */
191 sleep(1);
192
193 /* try sealing the global file again */
194 mfd_assert_add_seals(global_mfd, F_SEAL_WRITE);
195 }
196
197 return 0;
198}
199
200static pid_t spawn_sealing_thread(void)
201{
202 uint8_t *stack;
203 pid_t pid;
204
205 stack = malloc(STACK_SIZE);
206 if (!stack) {
207 printf("malloc(STACK_SIZE) failed: %m\n");
208 abort();
209 }
210
211 pid = clone(sealing_thread_fn,
212 stack + STACK_SIZE,
213 SIGCHLD | CLONE_FILES | CLONE_FS | CLONE_VM,
214 NULL);
215 if (pid < 0) {
216 printf("clone() failed: %m\n");
217 abort();
218 }
219
220 return pid;
221}
222
223static void join_sealing_thread(pid_t pid)
224{
225 waitpid(pid, NULL, 0);
226}
227
228int main(int argc, char **argv)
229{
230 static const char zero[MFD_DEF_SIZE];
231 int fd, mfd, r;
232 void *p;
233 int was_sealed;
234 pid_t pid;
235
236 if (argc < 2) {
237 printf("error: please pass path to file in fuse_mnt mount-point\n");
238 abort();
239 }
240
241 /* open FUSE memfd file for GUP testing */
242 printf("opening: %s\n", argv[1]);
243 fd = open(argv[1], O_RDONLY | O_CLOEXEC);
244 if (fd < 0) {
245 printf("cannot open(\"%s\"): %m\n", argv[1]);
246 abort();
247 }
248
249 /* create new memfd-object */
250 mfd = mfd_assert_new("kern_memfd_fuse",
251 MFD_DEF_SIZE,
252 MFD_CLOEXEC | MFD_ALLOW_SEALING);
253
254 /* mmap memfd-object for writing */
255 p = mfd_assert_mmap_shared(mfd);
256
257 /* pass mfd+mapping to a separate sealing-thread which tries to seal
258 * the memfd objects with SEAL_WRITE while we write into it */
259 global_mfd = mfd;
260 global_p = p;
261 pid = spawn_sealing_thread();
262
263 /* Use read() on the FUSE file to read into our memory-mapped memfd
264 * object. This races the other thread which tries to seal the
265 * memfd-object.
266 * If @fd is on the memfd-fake-FUSE-FS, the read() is delayed by 1s.
267 * This guarantees that the receive-buffer is pinned for 1s until the
268 * data is written into it. The racing ADD_SEALS should thus fail as
269 * the pages are still pinned. */
270 r = read(fd, p, MFD_DEF_SIZE);
271 if (r < 0) {
272 printf("read() failed: %m\n");
273 abort();
274 } else if (!r) {
275 printf("unexpected EOF on read()\n");
276 abort();
277 }
278
279 was_sealed = mfd_assert_get_seals(mfd) & F_SEAL_WRITE;
280
281 /* Wait for sealing-thread to finish and verify that it
282 * successfully sealed the file after the second try. */
283 join_sealing_thread(pid);
284 mfd_assert_has_seals(mfd, F_SEAL_WRITE);
285
286 /* *IF* the memfd-object was sealed at the time our read() returned,
287 * then the kernel did a page-replacement or canceled the read() (or
288 * whatever magic it did..). In that case, the memfd object is still
289 * all zero.
290 * In case the memfd-object was *not* sealed, the read() was successfull
291 * and the memfd object must *not* be all zero.
292 * Note that in real scenarios, there might be a mixture of both, but
293 * in this test-cases, we have explicit 200ms delays which should be
294 * enough to avoid any in-flight writes. */
295
296 p = mfd_assert_mmap_private(mfd);
297 if (was_sealed && memcmp(p, zero, MFD_DEF_SIZE)) {
298 printf("memfd sealed during read() but data not discarded\n");
299 abort();
300 } else if (!was_sealed && !memcmp(p, zero, MFD_DEF_SIZE)) {
301 printf("memfd sealed after read() but data discarded\n");
302 abort();
303 }
304
305 close(mfd);
306 close(fd);
307
308 printf("fuse: DONE\n");
309
310 return 0;
311}
diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c
new file mode 100644
index 000000000000..3634c909b1b0
--- /dev/null
+++ b/tools/testing/selftests/memfd/memfd_test.c
@@ -0,0 +1,913 @@
1#define _GNU_SOURCE
2#define __EXPORTED_HEADERS__
3
4#include <errno.h>
5#include <inttypes.h>
6#include <limits.h>
7#include <linux/falloc.h>
8#include <linux/fcntl.h>
9#include <linux/memfd.h>
10#include <sched.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <signal.h>
14#include <string.h>
15#include <sys/mman.h>
16#include <sys/stat.h>
17#include <sys/syscall.h>
18#include <unistd.h>
19
20#define MFD_DEF_SIZE 8192
21#define STACK_SIZE 65535
22
23static int sys_memfd_create(const char *name,
24 unsigned int flags)
25{
26 return syscall(__NR_memfd_create, name, flags);
27}
28
29static int mfd_assert_new(const char *name, loff_t sz, unsigned int flags)
30{
31 int r, fd;
32
33 fd = sys_memfd_create(name, flags);
34 if (fd < 0) {
35 printf("memfd_create(\"%s\", %u) failed: %m\n",
36 name, flags);
37 abort();
38 }
39
40 r = ftruncate(fd, sz);
41 if (r < 0) {
42 printf("ftruncate(%llu) failed: %m\n", (unsigned long long)sz);
43 abort();
44 }
45
46 return fd;
47}
48
49static void mfd_fail_new(const char *name, unsigned int flags)
50{
51 int r;
52
53 r = sys_memfd_create(name, flags);
54 if (r >= 0) {
55 printf("memfd_create(\"%s\", %u) succeeded, but failure expected\n",
56 name, flags);
57 close(r);
58 abort();
59 }
60}
61
62static __u64 mfd_assert_get_seals(int fd)
63{
64 long r;
65
66 r = fcntl(fd, F_GET_SEALS);
67 if (r < 0) {
68 printf("GET_SEALS(%d) failed: %m\n", fd);
69 abort();
70 }
71
72 return r;
73}
74
75static void mfd_assert_has_seals(int fd, __u64 seals)
76{
77 __u64 s;
78
79 s = mfd_assert_get_seals(fd);
80 if (s != seals) {
81 printf("%llu != %llu = GET_SEALS(%d)\n",
82 (unsigned long long)seals, (unsigned long long)s, fd);
83 abort();
84 }
85}
86
87static void mfd_assert_add_seals(int fd, __u64 seals)
88{
89 long r;
90 __u64 s;
91
92 s = mfd_assert_get_seals(fd);
93 r = fcntl(fd, F_ADD_SEALS, seals);
94 if (r < 0) {
95 printf("ADD_SEALS(%d, %llu -> %llu) failed: %m\n",
96 fd, (unsigned long long)s, (unsigned long long)seals);
97 abort();
98 }
99}
100
101static void mfd_fail_add_seals(int fd, __u64 seals)
102{
103 long r;
104 __u64 s;
105
106 r = fcntl(fd, F_GET_SEALS);
107 if (r < 0)
108 s = 0;
109 else
110 s = r;
111
112 r = fcntl(fd, F_ADD_SEALS, seals);
113 if (r >= 0) {
114 printf("ADD_SEALS(%d, %llu -> %llu) didn't fail as expected\n",
115 fd, (unsigned long long)s, (unsigned long long)seals);
116 abort();
117 }
118}
119
120static void mfd_assert_size(int fd, size_t size)
121{
122 struct stat st;
123 int r;
124
125 r = fstat(fd, &st);
126 if (r < 0) {
127 printf("fstat(%d) failed: %m\n", fd);
128 abort();
129 } else if (st.st_size != size) {
130 printf("wrong file size %lld, but expected %lld\n",
131 (long long)st.st_size, (long long)size);
132 abort();
133 }
134}
135
136static int mfd_assert_dup(int fd)
137{
138 int r;
139
140 r = dup(fd);
141 if (r < 0) {
142 printf("dup(%d) failed: %m\n", fd);
143 abort();
144 }
145
146 return r;
147}
148
149static void *mfd_assert_mmap_shared(int fd)
150{
151 void *p;
152
153 p = mmap(NULL,
154 MFD_DEF_SIZE,
155 PROT_READ | PROT_WRITE,
156 MAP_SHARED,
157 fd,
158 0);
159 if (p == MAP_FAILED) {
160 printf("mmap() failed: %m\n");
161 abort();
162 }
163
164 return p;
165}
166
167static void *mfd_assert_mmap_private(int fd)
168{
169 void *p;
170
171 p = mmap(NULL,
172 MFD_DEF_SIZE,
173 PROT_READ,
174 MAP_PRIVATE,
175 fd,
176 0);
177 if (p == MAP_FAILED) {
178 printf("mmap() failed: %m\n");
179 abort();
180 }
181
182 return p;
183}
184
185static int mfd_assert_open(int fd, int flags, mode_t mode)
186{
187 char buf[512];
188 int r;
189
190 sprintf(buf, "/proc/self/fd/%d", fd);
191 r = open(buf, flags, mode);
192 if (r < 0) {
193 printf("open(%s) failed: %m\n", buf);
194 abort();
195 }
196
197 return r;
198}
199
200static void mfd_fail_open(int fd, int flags, mode_t mode)
201{
202 char buf[512];
203 int r;
204
205 sprintf(buf, "/proc/self/fd/%d", fd);
206 r = open(buf, flags, mode);
207 if (r >= 0) {
208 printf("open(%s) didn't fail as expected\n");
209 abort();
210 }
211}
212
213static void mfd_assert_read(int fd)
214{
215 char buf[16];
216 void *p;
217 ssize_t l;
218
219 l = read(fd, buf, sizeof(buf));
220 if (l != sizeof(buf)) {
221 printf("read() failed: %m\n");
222 abort();
223 }
224
225 /* verify PROT_READ *is* allowed */
226 p = mmap(NULL,
227 MFD_DEF_SIZE,
228 PROT_READ,
229 MAP_PRIVATE,
230 fd,
231 0);
232 if (p == MAP_FAILED) {
233 printf("mmap() failed: %m\n");
234 abort();
235 }
236 munmap(p, MFD_DEF_SIZE);
237
238 /* verify MAP_PRIVATE is *always* allowed (even writable) */
239 p = mmap(NULL,
240 MFD_DEF_SIZE,
241 PROT_READ | PROT_WRITE,
242 MAP_PRIVATE,
243 fd,
244 0);
245 if (p == MAP_FAILED) {
246 printf("mmap() failed: %m\n");
247 abort();
248 }
249 munmap(p, MFD_DEF_SIZE);
250}
251
252static void mfd_assert_write(int fd)
253{
254 ssize_t l;
255 void *p;
256 int r;
257
258 /* verify write() succeeds */
259 l = write(fd, "\0\0\0\0", 4);
260 if (l != 4) {
261 printf("write() failed: %m\n");
262 abort();
263 }
264
265 /* verify PROT_READ | PROT_WRITE is allowed */
266 p = mmap(NULL,
267 MFD_DEF_SIZE,
268 PROT_READ | PROT_WRITE,
269 MAP_SHARED,
270 fd,
271 0);
272 if (p == MAP_FAILED) {
273 printf("mmap() failed: %m\n");
274 abort();
275 }
276 *(char *)p = 0;
277 munmap(p, MFD_DEF_SIZE);
278
279 /* verify PROT_WRITE is allowed */
280 p = mmap(NULL,
281 MFD_DEF_SIZE,
282 PROT_WRITE,
283 MAP_SHARED,
284 fd,
285 0);
286 if (p == MAP_FAILED) {
287 printf("mmap() failed: %m\n");
288 abort();
289 }
290 *(char *)p = 0;
291 munmap(p, MFD_DEF_SIZE);
292
293 /* verify PROT_READ with MAP_SHARED is allowed and a following
294 * mprotect(PROT_WRITE) allows writing */
295 p = mmap(NULL,
296 MFD_DEF_SIZE,
297 PROT_READ,
298 MAP_SHARED,
299 fd,
300 0);
301 if (p == MAP_FAILED) {
302 printf("mmap() failed: %m\n");
303 abort();
304 }
305
306 r = mprotect(p, MFD_DEF_SIZE, PROT_READ | PROT_WRITE);
307 if (r < 0) {
308 printf("mprotect() failed: %m\n");
309 abort();
310 }
311
312 *(char *)p = 0;
313 munmap(p, MFD_DEF_SIZE);
314
315 /* verify PUNCH_HOLE works */
316 r = fallocate(fd,
317 FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
318 0,
319 MFD_DEF_SIZE);
320 if (r < 0) {
321 printf("fallocate(PUNCH_HOLE) failed: %m\n");
322 abort();
323 }
324}
325
326static void mfd_fail_write(int fd)
327{
328 ssize_t l;
329 void *p;
330 int r;
331
332 /* verify write() fails */
333 l = write(fd, "data", 4);
334 if (l != -EPERM) {
335 printf("expected EPERM on write(), but got %d: %m\n", (int)l);
336 abort();
337 }
338
339 /* verify PROT_READ | PROT_WRITE is not allowed */
340 p = mmap(NULL,
341 MFD_DEF_SIZE,
342 PROT_READ | PROT_WRITE,
343 MAP_SHARED,
344 fd,
345 0);
346 if (p != MAP_FAILED) {
347 printf("mmap() didn't fail as expected\n");
348 abort();
349 }
350
351 /* verify PROT_WRITE is not allowed */
352 p = mmap(NULL,
353 MFD_DEF_SIZE,
354 PROT_WRITE,
355 MAP_SHARED,
356 fd,
357 0);
358 if (p != MAP_FAILED) {
359 printf("mmap() didn't fail as expected\n");
360 abort();
361 }
362
363 /* Verify PROT_READ with MAP_SHARED with a following mprotect is not
364 * allowed. Note that for r/w the kernel already prevents the mmap. */
365 p = mmap(NULL,
366 MFD_DEF_SIZE,
367 PROT_READ,
368 MAP_SHARED,
369 fd,
370 0);
371 if (p != MAP_FAILED) {
372 r = mprotect(p, MFD_DEF_SIZE, PROT_READ | PROT_WRITE);
373 if (r >= 0) {
374 printf("mmap()+mprotect() didn't fail as expected\n");
375 abort();
376 }
377 }
378
379 /* verify PUNCH_HOLE fails */
380 r = fallocate(fd,
381 FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
382 0,
383 MFD_DEF_SIZE);
384 if (r >= 0) {
385 printf("fallocate(PUNCH_HOLE) didn't fail as expected\n");
386 abort();
387 }
388}
389
390static void mfd_assert_shrink(int fd)
391{
392 int r, fd2;
393
394 r = ftruncate(fd, MFD_DEF_SIZE / 2);
395 if (r < 0) {
396 printf("ftruncate(SHRINK) failed: %m\n");
397 abort();
398 }
399
400 mfd_assert_size(fd, MFD_DEF_SIZE / 2);
401
402 fd2 = mfd_assert_open(fd,
403 O_RDWR | O_CREAT | O_TRUNC,
404 S_IRUSR | S_IWUSR);
405 close(fd2);
406
407 mfd_assert_size(fd, 0);
408}
409
410static void mfd_fail_shrink(int fd)
411{
412 int r;
413
414 r = ftruncate(fd, MFD_DEF_SIZE / 2);
415 if (r >= 0) {
416 printf("ftruncate(SHRINK) didn't fail as expected\n");
417 abort();
418 }
419
420 mfd_fail_open(fd,
421 O_RDWR | O_CREAT | O_TRUNC,
422 S_IRUSR | S_IWUSR);
423}
424
425static void mfd_assert_grow(int fd)
426{
427 int r;
428
429 r = ftruncate(fd, MFD_DEF_SIZE * 2);
430 if (r < 0) {
431 printf("ftruncate(GROW) failed: %m\n");
432 abort();
433 }
434
435 mfd_assert_size(fd, MFD_DEF_SIZE * 2);
436
437 r = fallocate(fd,
438 0,
439 0,
440 MFD_DEF_SIZE * 4);
441 if (r < 0) {
442 printf("fallocate(ALLOC) failed: %m\n");
443 abort();
444 }
445
446 mfd_assert_size(fd, MFD_DEF_SIZE * 4);
447}
448
449static void mfd_fail_grow(int fd)
450{
451 int r;
452
453 r = ftruncate(fd, MFD_DEF_SIZE * 2);
454 if (r >= 0) {
455 printf("ftruncate(GROW) didn't fail as expected\n");
456 abort();
457 }
458
459 r = fallocate(fd,
460 0,
461 0,
462 MFD_DEF_SIZE * 4);
463 if (r >= 0) {
464 printf("fallocate(ALLOC) didn't fail as expected\n");
465 abort();
466 }
467}
468
469static void mfd_assert_grow_write(int fd)
470{
471 static char buf[MFD_DEF_SIZE * 8];
472 ssize_t l;
473
474 l = pwrite(fd, buf, sizeof(buf), 0);
475 if (l != sizeof(buf)) {
476 printf("pwrite() failed: %m\n");
477 abort();
478 }
479
480 mfd_assert_size(fd, MFD_DEF_SIZE * 8);
481}
482
483static void mfd_fail_grow_write(int fd)
484{
485 static char buf[MFD_DEF_SIZE * 8];
486 ssize_t l;
487
488 l = pwrite(fd, buf, sizeof(buf), 0);
489 if (l == sizeof(buf)) {
490 printf("pwrite() didn't fail as expected\n");
491 abort();
492 }
493}
494
495static int idle_thread_fn(void *arg)
496{
497 sigset_t set;
498 int sig;
499
500 /* dummy waiter; SIGTERM terminates us anyway */
501 sigemptyset(&set);
502 sigaddset(&set, SIGTERM);
503 sigwait(&set, &sig);
504
505 return 0;
506}
507
508static pid_t spawn_idle_thread(unsigned int flags)
509{
510 uint8_t *stack;
511 pid_t pid;
512
513 stack = malloc(STACK_SIZE);
514 if (!stack) {
515 printf("malloc(STACK_SIZE) failed: %m\n");
516 abort();
517 }
518
519 pid = clone(idle_thread_fn,
520 stack + STACK_SIZE,
521 SIGCHLD | flags,
522 NULL);
523 if (pid < 0) {
524 printf("clone() failed: %m\n");
525 abort();
526 }
527
528 return pid;
529}
530
531static void join_idle_thread(pid_t pid)
532{
533 kill(pid, SIGTERM);
534 waitpid(pid, NULL, 0);
535}
536
537/*
538 * Test memfd_create() syscall
539 * Verify syscall-argument validation, including name checks, flag validation
540 * and more.
541 */
542static void test_create(void)
543{
544 char buf[2048];
545 int fd;
546
547 /* test NULL name */
548 mfd_fail_new(NULL, 0);
549
550 /* test over-long name (not zero-terminated) */
551 memset(buf, 0xff, sizeof(buf));
552 mfd_fail_new(buf, 0);
553
554 /* test over-long zero-terminated name */
555 memset(buf, 0xff, sizeof(buf));
556 buf[sizeof(buf) - 1] = 0;
557 mfd_fail_new(buf, 0);
558
559 /* verify "" is a valid name */
560 fd = mfd_assert_new("", 0, 0);
561 close(fd);
562
563 /* verify invalid O_* open flags */
564 mfd_fail_new("", 0x0100);
565 mfd_fail_new("", ~MFD_CLOEXEC);
566 mfd_fail_new("", ~MFD_ALLOW_SEALING);
567 mfd_fail_new("", ~0);
568 mfd_fail_new("", 0x80000000U);
569
570 /* verify MFD_CLOEXEC is allowed */
571 fd = mfd_assert_new("", 0, MFD_CLOEXEC);
572 close(fd);
573
574 /* verify MFD_ALLOW_SEALING is allowed */
575 fd = mfd_assert_new("", 0, MFD_ALLOW_SEALING);
576 close(fd);
577
578 /* verify MFD_ALLOW_SEALING | MFD_CLOEXEC is allowed */
579 fd = mfd_assert_new("", 0, MFD_ALLOW_SEALING | MFD_CLOEXEC);
580 close(fd);
581}
582
583/*
584 * Test basic sealing
585 * A very basic sealing test to see whether setting/retrieving seals works.
586 */
587static void test_basic(void)
588{
589 int fd;
590
591 fd = mfd_assert_new("kern_memfd_basic",
592 MFD_DEF_SIZE,
593 MFD_CLOEXEC | MFD_ALLOW_SEALING);
594
595 /* add basic seals */
596 mfd_assert_has_seals(fd, 0);
597 mfd_assert_add_seals(fd, F_SEAL_SHRINK |
598 F_SEAL_WRITE);
599 mfd_assert_has_seals(fd, F_SEAL_SHRINK |
600 F_SEAL_WRITE);
601
602 /* add them again */
603 mfd_assert_add_seals(fd, F_SEAL_SHRINK |
604 F_SEAL_WRITE);
605 mfd_assert_has_seals(fd, F_SEAL_SHRINK |
606 F_SEAL_WRITE);
607
608 /* add more seals and seal against sealing */
609 mfd_assert_add_seals(fd, F_SEAL_GROW | F_SEAL_SEAL);
610 mfd_assert_has_seals(fd, F_SEAL_SHRINK |
611 F_SEAL_GROW |
612 F_SEAL_WRITE |
613 F_SEAL_SEAL);
614
615 /* verify that sealing no longer works */
616 mfd_fail_add_seals(fd, F_SEAL_GROW);
617 mfd_fail_add_seals(fd, 0);
618
619 close(fd);
620
621 /* verify sealing does not work without MFD_ALLOW_SEALING */
622 fd = mfd_assert_new("kern_memfd_basic",
623 MFD_DEF_SIZE,
624 MFD_CLOEXEC);
625 mfd_assert_has_seals(fd, F_SEAL_SEAL);
626 mfd_fail_add_seals(fd, F_SEAL_SHRINK |
627 F_SEAL_GROW |
628 F_SEAL_WRITE);
629 mfd_assert_has_seals(fd, F_SEAL_SEAL);
630 close(fd);
631}
632
633/*
634 * Test SEAL_WRITE
635 * Test whether SEAL_WRITE actually prevents modifications.
636 */
637static void test_seal_write(void)
638{
639 int fd;
640
641 fd = mfd_assert_new("kern_memfd_seal_write",
642 MFD_DEF_SIZE,
643 MFD_CLOEXEC | MFD_ALLOW_SEALING);
644 mfd_assert_has_seals(fd, 0);
645 mfd_assert_add_seals(fd, F_SEAL_WRITE);
646 mfd_assert_has_seals(fd, F_SEAL_WRITE);
647
648 mfd_assert_read(fd);
649 mfd_fail_write(fd);
650 mfd_assert_shrink(fd);
651 mfd_assert_grow(fd);
652 mfd_fail_grow_write(fd);
653
654 close(fd);
655}
656
657/*
658 * Test SEAL_SHRINK
659 * Test whether SEAL_SHRINK actually prevents shrinking
660 */
661static void test_seal_shrink(void)
662{
663 int fd;
664
665 fd = mfd_assert_new("kern_memfd_seal_shrink",
666 MFD_DEF_SIZE,
667 MFD_CLOEXEC | MFD_ALLOW_SEALING);
668 mfd_assert_has_seals(fd, 0);
669 mfd_assert_add_seals(fd, F_SEAL_SHRINK);
670 mfd_assert_has_seals(fd, F_SEAL_SHRINK);
671
672 mfd_assert_read(fd);
673 mfd_assert_write(fd);
674 mfd_fail_shrink(fd);
675 mfd_assert_grow(fd);
676 mfd_assert_grow_write(fd);
677
678 close(fd);
679}
680
681/*
682 * Test SEAL_GROW
683 * Test whether SEAL_GROW actually prevents growing
684 */
685static void test_seal_grow(void)
686{
687 int fd;
688
689 fd = mfd_assert_new("kern_memfd_seal_grow",
690 MFD_DEF_SIZE,
691 MFD_CLOEXEC | MFD_ALLOW_SEALING);
692 mfd_assert_has_seals(fd, 0);
693 mfd_assert_add_seals(fd, F_SEAL_GROW);
694 mfd_assert_has_seals(fd, F_SEAL_GROW);
695
696 mfd_assert_read(fd);
697 mfd_assert_write(fd);
698 mfd_assert_shrink(fd);
699 mfd_fail_grow(fd);
700 mfd_fail_grow_write(fd);
701
702 close(fd);
703}
704
705/*
706 * Test SEAL_SHRINK | SEAL_GROW
707 * Test whether SEAL_SHRINK | SEAL_GROW actually prevents resizing
708 */
709static void test_seal_resize(void)
710{
711 int fd;
712
713 fd = mfd_assert_new("kern_memfd_seal_resize",
714 MFD_DEF_SIZE,
715 MFD_CLOEXEC | MFD_ALLOW_SEALING);
716 mfd_assert_has_seals(fd, 0);
717 mfd_assert_add_seals(fd, F_SEAL_SHRINK | F_SEAL_GROW);
718 mfd_assert_has_seals(fd, F_SEAL_SHRINK | F_SEAL_GROW);
719
720 mfd_assert_read(fd);
721 mfd_assert_write(fd);
722 mfd_fail_shrink(fd);
723 mfd_fail_grow(fd);
724 mfd_fail_grow_write(fd);
725
726 close(fd);
727}
728
729/*
730 * Test sharing via dup()
731 * Test that seals are shared between dupped FDs and they're all equal.
732 */
733static void test_share_dup(void)
734{
735 int fd, fd2;
736
737 fd = mfd_assert_new("kern_memfd_share_dup",
738 MFD_DEF_SIZE,
739 MFD_CLOEXEC | MFD_ALLOW_SEALING);
740 mfd_assert_has_seals(fd, 0);
741
742 fd2 = mfd_assert_dup(fd);
743 mfd_assert_has_seals(fd2, 0);
744
745 mfd_assert_add_seals(fd, F_SEAL_WRITE);
746 mfd_assert_has_seals(fd, F_SEAL_WRITE);
747 mfd_assert_has_seals(fd2, F_SEAL_WRITE);
748
749 mfd_assert_add_seals(fd2, F_SEAL_SHRINK);
750 mfd_assert_has_seals(fd, F_SEAL_WRITE | F_SEAL_SHRINK);
751 mfd_assert_has_seals(fd2, F_SEAL_WRITE | F_SEAL_SHRINK);
752
753 mfd_assert_add_seals(fd, F_SEAL_SEAL);
754 mfd_assert_has_seals(fd, F_SEAL_WRITE | F_SEAL_SHRINK | F_SEAL_SEAL);
755 mfd_assert_has_seals(fd2, F_SEAL_WRITE | F_SEAL_SHRINK | F_SEAL_SEAL);
756
757 mfd_fail_add_seals(fd, F_SEAL_GROW);
758 mfd_fail_add_seals(fd2, F_SEAL_GROW);
759 mfd_fail_add_seals(fd, F_SEAL_SEAL);
760 mfd_fail_add_seals(fd2, F_SEAL_SEAL);
761
762 close(fd2);
763
764 mfd_fail_add_seals(fd, F_SEAL_GROW);
765 close(fd);
766}
767
768/*
769 * Test sealing with active mmap()s
770 * Modifying seals is only allowed if no other mmap() refs exist.
771 */
772static void test_share_mmap(void)
773{
774 int fd;
775 void *p;
776
777 fd = mfd_assert_new("kern_memfd_share_mmap",
778 MFD_DEF_SIZE,
779 MFD_CLOEXEC | MFD_ALLOW_SEALING);
780 mfd_assert_has_seals(fd, 0);
781
782 /* shared/writable ref prevents sealing WRITE, but allows others */
783 p = mfd_assert_mmap_shared(fd);
784 mfd_fail_add_seals(fd, F_SEAL_WRITE);
785 mfd_assert_has_seals(fd, 0);
786 mfd_assert_add_seals(fd, F_SEAL_SHRINK);
787 mfd_assert_has_seals(fd, F_SEAL_SHRINK);
788 munmap(p, MFD_DEF_SIZE);
789
790 /* readable ref allows sealing */
791 p = mfd_assert_mmap_private(fd);
792 mfd_assert_add_seals(fd, F_SEAL_WRITE);
793 mfd_assert_has_seals(fd, F_SEAL_WRITE | F_SEAL_SHRINK);
794 munmap(p, MFD_DEF_SIZE);
795
796 close(fd);
797}
798
799/*
800 * Test sealing with open(/proc/self/fd/%d)
801 * Via /proc we can get access to a separate file-context for the same memfd.
802 * This is *not* like dup(), but like a real separate open(). Make sure the
803 * semantics are as expected and we correctly check for RDONLY / WRONLY / RDWR.
804 */
805static void test_share_open(void)
806{
807 int fd, fd2;
808
809 fd = mfd_assert_new("kern_memfd_share_open",
810 MFD_DEF_SIZE,
811 MFD_CLOEXEC | MFD_ALLOW_SEALING);
812 mfd_assert_has_seals(fd, 0);
813
814 fd2 = mfd_assert_open(fd, O_RDWR, 0);
815 mfd_assert_add_seals(fd, F_SEAL_WRITE);
816 mfd_assert_has_seals(fd, F_SEAL_WRITE);
817 mfd_assert_has_seals(fd2, F_SEAL_WRITE);
818
819 mfd_assert_add_seals(fd2, F_SEAL_SHRINK);
820 mfd_assert_has_seals(fd, F_SEAL_WRITE | F_SEAL_SHRINK);
821 mfd_assert_has_seals(fd2, F_SEAL_WRITE | F_SEAL_SHRINK);
822
823 close(fd);
824 fd = mfd_assert_open(fd2, O_RDONLY, 0);
825
826 mfd_fail_add_seals(fd, F_SEAL_SEAL);
827 mfd_assert_has_seals(fd, F_SEAL_WRITE | F_SEAL_SHRINK);
828 mfd_assert_has_seals(fd2, F_SEAL_WRITE | F_SEAL_SHRINK);
829
830 close(fd2);
831 fd2 = mfd_assert_open(fd, O_RDWR, 0);
832
833 mfd_assert_add_seals(fd2, F_SEAL_SEAL);
834 mfd_assert_has_seals(fd, F_SEAL_WRITE | F_SEAL_SHRINK | F_SEAL_SEAL);
835 mfd_assert_has_seals(fd2, F_SEAL_WRITE | F_SEAL_SHRINK | F_SEAL_SEAL);
836
837 close(fd2);
838 close(fd);
839}
840
841/*
842 * Test sharing via fork()
843 * Test whether seal-modifications work as expected with forked childs.
844 */
845static void test_share_fork(void)
846{
847 int fd;
848 pid_t pid;
849
850 fd = mfd_assert_new("kern_memfd_share_fork",
851 MFD_DEF_SIZE,
852 MFD_CLOEXEC | MFD_ALLOW_SEALING);
853 mfd_assert_has_seals(fd, 0);
854
855 pid = spawn_idle_thread(0);
856 mfd_assert_add_seals(fd, F_SEAL_SEAL);
857 mfd_assert_has_seals(fd, F_SEAL_SEAL);
858
859 mfd_fail_add_seals(fd, F_SEAL_WRITE);
860 mfd_assert_has_seals(fd, F_SEAL_SEAL);
861
862 join_idle_thread(pid);
863
864 mfd_fail_add_seals(fd, F_SEAL_WRITE);
865 mfd_assert_has_seals(fd, F_SEAL_SEAL);
866
867 close(fd);
868}
869
870int main(int argc, char **argv)
871{
872 pid_t pid;
873
874 printf("memfd: CREATE\n");
875 test_create();
876 printf("memfd: BASIC\n");
877 test_basic();
878
879 printf("memfd: SEAL-WRITE\n");
880 test_seal_write();
881 printf("memfd: SEAL-SHRINK\n");
882 test_seal_shrink();
883 printf("memfd: SEAL-GROW\n");
884 test_seal_grow();
885 printf("memfd: SEAL-RESIZE\n");
886 test_seal_resize();
887
888 printf("memfd: SHARE-DUP\n");
889 test_share_dup();
890 printf("memfd: SHARE-MMAP\n");
891 test_share_mmap();
892 printf("memfd: SHARE-OPEN\n");
893 test_share_open();
894 printf("memfd: SHARE-FORK\n");
895 test_share_fork();
896
897 /* Run test-suite in a multi-threaded environment with a shared
898 * file-table. */
899 pid = spawn_idle_thread(CLONE_FILES | CLONE_FS | CLONE_VM);
900 printf("memfd: SHARE-DUP (shared file-table)\n");
901 test_share_dup();
902 printf("memfd: SHARE-MMAP (shared file-table)\n");
903 test_share_mmap();
904 printf("memfd: SHARE-OPEN (shared file-table)\n");
905 test_share_open();
906 printf("memfd: SHARE-FORK (shared file-table)\n");
907 test_share_fork();
908 join_idle_thread(pid);
909
910 printf("memfd: DONE\n");
911
912 return 0;
913}
diff --git a/tools/testing/selftests/memfd/run_fuse_test.sh b/tools/testing/selftests/memfd/run_fuse_test.sh
new file mode 100644
index 000000000000..69b930e1e041
--- /dev/null
+++ b/tools/testing/selftests/memfd/run_fuse_test.sh
@@ -0,0 +1,14 @@
1#!/bin/sh
2
3if test -d "./mnt" ; then
4 fusermount -u ./mnt
5 rmdir ./mnt
6fi
7
8set -e
9
10mkdir mnt
11./fuse_mnt ./mnt
12./fuse_test ./mnt/memfd
13fusermount -u ./mnt
14rmdir ./mnt
diff --git a/tools/testing/selftests/memory-hotplug/Makefile b/tools/testing/selftests/memory-hotplug/Makefile
index 058c76f5d102..d46b8d489cd2 100644
--- a/tools/testing/selftests/memory-hotplug/Makefile
+++ b/tools/testing/selftests/memory-hotplug/Makefile
@@ -1,6 +1,9 @@
1all: 1all:
2 2
3run_tests: 3run_tests:
4 @/bin/bash ./on-off-test.sh -r 2 || echo "memory-hotplug selftests: [FAIL]"
5
6run_full_test:
4 @/bin/bash ./on-off-test.sh || echo "memory-hotplug selftests: [FAIL]" 7 @/bin/bash ./on-off-test.sh || echo "memory-hotplug selftests: [FAIL]"
5 8
6clean: 9clean:
diff --git a/tools/testing/selftests/memory-hotplug/on-off-test.sh b/tools/testing/selftests/memory-hotplug/on-off-test.sh
index a2816f631542..6cddde0b96f8 100644
--- a/tools/testing/selftests/memory-hotplug/on-off-test.sh
+++ b/tools/testing/selftests/memory-hotplug/on-off-test.sh
@@ -142,10 +142,16 @@ fi
142 142
143prerequisite 143prerequisite
144 144
145echo "Test scope: $ratio% hotplug memory"
146echo -e "\t online all hotplug memory in offline state"
147echo -e "\t offline $ratio% hotplug memory in online state"
148echo -e "\t online all hotplug memory in offline state"
149
145# 150#
146# Online all hot-pluggable memory 151# Online all hot-pluggable memory
147# 152#
148for memory in `hotplaggable_offline_memory`; do 153for memory in `hotplaggable_offline_memory`; do
154 echo offline-online $memory
149 online_memory_expect_success $memory 155 online_memory_expect_success $memory
150done 156done
151 157
@@ -154,6 +160,7 @@ done
154# 160#
155for memory in `hotpluggable_online_memory`; do 161for memory in `hotpluggable_online_memory`; do
156 if [ $((RANDOM % 100)) -lt $ratio ]; then 162 if [ $((RANDOM % 100)) -lt $ratio ]; then
163 echo online-offline $memory
157 offline_memory_expect_success $memory 164 offline_memory_expect_success $memory
158 fi 165 fi
159done 166done
@@ -162,6 +169,7 @@ done
162# Online all hot-pluggable memory again 169# Online all hot-pluggable memory again
163# 170#
164for memory in `hotplaggable_offline_memory`; do 171for memory in `hotplaggable_offline_memory`; do
172 echo offline-online $memory
165 online_memory_expect_success $memory 173 online_memory_expect_success $memory
166done 174done
167 175
diff --git a/tools/testing/selftests/mount/Makefile b/tools/testing/selftests/mount/Makefile
new file mode 100644
index 000000000000..337d853c2b72
--- /dev/null
+++ b/tools/testing/selftests/mount/Makefile
@@ -0,0 +1,17 @@
1# Makefile for mount selftests.
2
3all: unprivileged-remount-test
4
5unprivileged-remount-test: unprivileged-remount-test.c
6 gcc -Wall -O2 unprivileged-remount-test.c -o unprivileged-remount-test
7
8# Allow specific tests to be selected.
9test_unprivileged_remount: unprivileged-remount-test
10 @if [ -f /proc/self/uid_map ] ; then ./unprivileged-remount-test ; fi
11
12run_tests: all test_unprivileged_remount
13
14clean:
15 rm -f unprivileged-remount-test
16
17.PHONY: all test_unprivileged_remount
diff --git a/tools/testing/selftests/mount/unprivileged-remount-test.c b/tools/testing/selftests/mount/unprivileged-remount-test.c
new file mode 100644
index 000000000000..1b3ff2fda4d0
--- /dev/null
+++ b/tools/testing/selftests/mount/unprivileged-remount-test.c
@@ -0,0 +1,242 @@
1#define _GNU_SOURCE
2#include <sched.h>
3#include <stdio.h>
4#include <errno.h>
5#include <string.h>
6#include <sys/types.h>
7#include <sys/mount.h>
8#include <sys/wait.h>
9#include <stdlib.h>
10#include <unistd.h>
11#include <fcntl.h>
12#include <grp.h>
13#include <stdbool.h>
14#include <stdarg.h>
15
16#ifndef CLONE_NEWNS
17# define CLONE_NEWNS 0x00020000
18#endif
19#ifndef CLONE_NEWUTS
20# define CLONE_NEWUTS 0x04000000
21#endif
22#ifndef CLONE_NEWIPC
23# define CLONE_NEWIPC 0x08000000
24#endif
25#ifndef CLONE_NEWNET
26# define CLONE_NEWNET 0x40000000
27#endif
28#ifndef CLONE_NEWUSER
29# define CLONE_NEWUSER 0x10000000
30#endif
31#ifndef CLONE_NEWPID
32# define CLONE_NEWPID 0x20000000
33#endif
34
35#ifndef MS_RELATIME
36#define MS_RELATIME (1 << 21)
37#endif
38#ifndef MS_STRICTATIME
39#define MS_STRICTATIME (1 << 24)
40#endif
41
42static void die(char *fmt, ...)
43{
44 va_list ap;
45 va_start(ap, fmt);
46 vfprintf(stderr, fmt, ap);
47 va_end(ap);
48 exit(EXIT_FAILURE);
49}
50
51static void write_file(char *filename, char *fmt, ...)
52{
53 char buf[4096];
54 int fd;
55 ssize_t written;
56 int buf_len;
57 va_list ap;
58
59 va_start(ap, fmt);
60 buf_len = vsnprintf(buf, sizeof(buf), fmt, ap);
61 va_end(ap);
62 if (buf_len < 0) {
63 die("vsnprintf failed: %s\n",
64 strerror(errno));
65 }
66 if (buf_len >= sizeof(buf)) {
67 die("vsnprintf output truncated\n");
68 }
69
70 fd = open(filename, O_WRONLY);
71 if (fd < 0) {
72 die("open of %s failed: %s\n",
73 filename, strerror(errno));
74 }
75 written = write(fd, buf, buf_len);
76 if (written != buf_len) {
77 if (written >= 0) {
78 die("short write to %s\n", filename);
79 } else {
80 die("write to %s failed: %s\n",
81 filename, strerror(errno));
82 }
83 }
84 if (close(fd) != 0) {
85 die("close of %s failed: %s\n",
86 filename, strerror(errno));
87 }
88}
89
90static void create_and_enter_userns(void)
91{
92 uid_t uid;
93 gid_t gid;
94
95 uid = getuid();
96 gid = getgid();
97
98 if (unshare(CLONE_NEWUSER) !=0) {
99 die("unshare(CLONE_NEWUSER) failed: %s\n",
100 strerror(errno));
101 }
102
103 write_file("/proc/self/uid_map", "0 %d 1", uid);
104 write_file("/proc/self/gid_map", "0 %d 1", gid);
105
106 if (setgroups(0, NULL) != 0) {
107 die("setgroups failed: %s\n",
108 strerror(errno));
109 }
110 if (setgid(0) != 0) {
111 die ("setgid(0) failed %s\n",
112 strerror(errno));
113 }
114 if (setuid(0) != 0) {
115 die("setuid(0) failed %s\n",
116 strerror(errno));
117 }
118}
119
120static
121bool test_unpriv_remount(int mount_flags, int remount_flags, int invalid_flags)
122{
123 pid_t child;
124
125 child = fork();
126 if (child == -1) {
127 die("fork failed: %s\n",
128 strerror(errno));
129 }
130 if (child != 0) { /* parent */
131 pid_t pid;
132 int status;
133 pid = waitpid(child, &status, 0);
134 if (pid == -1) {
135 die("waitpid failed: %s\n",
136 strerror(errno));
137 }
138 if (pid != child) {
139 die("waited for %d got %d\n",
140 child, pid);
141 }
142 if (!WIFEXITED(status)) {
143 die("child did not terminate cleanly\n");
144 }
145 return WEXITSTATUS(status) == EXIT_SUCCESS ? true : false;
146 }
147
148 create_and_enter_userns();
149 if (unshare(CLONE_NEWNS) != 0) {
150 die("unshare(CLONE_NEWNS) failed: %s\n",
151 strerror(errno));
152 }
153
154 if (mount("testing", "/tmp", "ramfs", mount_flags, NULL) != 0) {
155 die("mount of /tmp failed: %s\n",
156 strerror(errno));
157 }
158
159 create_and_enter_userns();
160
161 if (unshare(CLONE_NEWNS) != 0) {
162 die("unshare(CLONE_NEWNS) failed: %s\n",
163 strerror(errno));
164 }
165
166 if (mount("/tmp", "/tmp", "none",
167 MS_REMOUNT | MS_BIND | remount_flags, NULL) != 0) {
168 /* system("cat /proc/self/mounts"); */
169 die("remount of /tmp failed: %s\n",
170 strerror(errno));
171 }
172
173 if (mount("/tmp", "/tmp", "none",
174 MS_REMOUNT | MS_BIND | invalid_flags, NULL) == 0) {
175 /* system("cat /proc/self/mounts"); */
176 die("remount of /tmp with invalid flags "
177 "succeeded unexpectedly\n");
178 }
179 exit(EXIT_SUCCESS);
180}
181
182static bool test_unpriv_remount_simple(int mount_flags)
183{
184 return test_unpriv_remount(mount_flags, mount_flags, 0);
185}
186
187static bool test_unpriv_remount_atime(int mount_flags, int invalid_flags)
188{
189 return test_unpriv_remount(mount_flags, mount_flags, invalid_flags);
190}
191
192int main(int argc, char **argv)
193{
194 if (!test_unpriv_remount_simple(MS_RDONLY|MS_NODEV)) {
195 die("MS_RDONLY malfunctions\n");
196 }
197 if (!test_unpriv_remount_simple(MS_NODEV)) {
198 die("MS_NODEV malfunctions\n");
199 }
200 if (!test_unpriv_remount_simple(MS_NOSUID|MS_NODEV)) {
201 die("MS_NOSUID malfunctions\n");
202 }
203 if (!test_unpriv_remount_simple(MS_NOEXEC|MS_NODEV)) {
204 die("MS_NOEXEC malfunctions\n");
205 }
206 if (!test_unpriv_remount_atime(MS_RELATIME|MS_NODEV,
207 MS_NOATIME|MS_NODEV))
208 {
209 die("MS_RELATIME malfunctions\n");
210 }
211 if (!test_unpriv_remount_atime(MS_STRICTATIME|MS_NODEV,
212 MS_NOATIME|MS_NODEV))
213 {
214 die("MS_STRICTATIME malfunctions\n");
215 }
216 if (!test_unpriv_remount_atime(MS_NOATIME|MS_NODEV,
217 MS_STRICTATIME|MS_NODEV))
218 {
219 die("MS_RELATIME malfunctions\n");
220 }
221 if (!test_unpriv_remount_atime(MS_RELATIME|MS_NODIRATIME|MS_NODEV,
222 MS_NOATIME|MS_NODEV))
223 {
224 die("MS_RELATIME malfunctions\n");
225 }
226 if (!test_unpriv_remount_atime(MS_STRICTATIME|MS_NODIRATIME|MS_NODEV,
227 MS_NOATIME|MS_NODEV))
228 {
229 die("MS_RELATIME malfunctions\n");
230 }
231 if (!test_unpriv_remount_atime(MS_NOATIME|MS_NODIRATIME|MS_NODEV,
232 MS_STRICTATIME|MS_NODEV))
233 {
234 die("MS_RELATIME malfunctions\n");
235 }
236 if (!test_unpriv_remount(MS_STRICTATIME|MS_NODEV, MS_NODEV,
237 MS_NOATIME|MS_NODEV))
238 {
239 die("Default atime malfunctions\n");
240 }
241 return EXIT_SUCCESS;
242}
diff --git a/tools/testing/selftests/mqueue/Makefile b/tools/testing/selftests/mqueue/Makefile
index 218a122c7951..8056e2e68fa4 100644
--- a/tools/testing/selftests/mqueue/Makefile
+++ b/tools/testing/selftests/mqueue/Makefile
@@ -1,6 +1,6 @@
1all: 1all:
2 gcc -O2 -lrt mq_open_tests.c -o mq_open_tests 2 gcc -O2 mq_open_tests.c -o mq_open_tests -lrt
3 gcc -O2 -lrt -lpthread -lpopt -o mq_perf_tests mq_perf_tests.c 3 gcc -O2 -o mq_perf_tests mq_perf_tests.c -lrt -lpthread -lpopt
4 4
5run_tests: 5run_tests:
6 @./mq_open_tests /test1 || echo "mq_open_tests: [FAIL]" 6 @./mq_open_tests /test1 || echo "mq_open_tests: [FAIL]"
diff --git a/tools/testing/selftests/mqueue/mq_open_tests.c b/tools/testing/selftests/mqueue/mq_open_tests.c
index 711cc2923047..9c1a5d359055 100644
--- a/tools/testing/selftests/mqueue/mq_open_tests.c
+++ b/tools/testing/selftests/mqueue/mq_open_tests.c
@@ -80,7 +80,8 @@ void shutdown(int exit_val, char *err_cause, int line_no)
80 if (in_shutdown++) 80 if (in_shutdown++)
81 return; 81 return;
82 82
83 seteuid(0); 83 if (seteuid(0) == -1)
84 perror("seteuid() failed");
84 85
85 if (queue != -1) 86 if (queue != -1)
86 if (mq_close(queue)) 87 if (mq_close(queue))
@@ -292,8 +293,10 @@ int main(int argc, char *argv[])
292 /* Tell the user our initial state */ 293 /* Tell the user our initial state */
293 printf("\nInitial system state:\n"); 294 printf("\nInitial system state:\n");
294 printf("\tUsing queue path:\t\t%s\n", queue_path); 295 printf("\tUsing queue path:\t\t%s\n", queue_path);
295 printf("\tRLIMIT_MSGQUEUE(soft):\t\t%d\n", saved_limits.rlim_cur); 296 printf("\tRLIMIT_MSGQUEUE(soft):\t\t%ld\n",
296 printf("\tRLIMIT_MSGQUEUE(hard):\t\t%d\n", saved_limits.rlim_max); 297 (long) saved_limits.rlim_cur);
298 printf("\tRLIMIT_MSGQUEUE(hard):\t\t%ld\n",
299 (long) saved_limits.rlim_max);
297 printf("\tMaximum Message Size:\t\t%d\n", saved_max_msgsize); 300 printf("\tMaximum Message Size:\t\t%d\n", saved_max_msgsize);
298 printf("\tMaximum Queue Size:\t\t%d\n", saved_max_msgs); 301 printf("\tMaximum Queue Size:\t\t%d\n", saved_max_msgs);
299 if (default_settings) { 302 if (default_settings) {
@@ -308,8 +311,8 @@ int main(int argc, char *argv[])
308 validate_current_settings(); 311 validate_current_settings();
309 312
310 printf("Adjusted system state for testing:\n"); 313 printf("Adjusted system state for testing:\n");
311 printf("\tRLIMIT_MSGQUEUE(soft):\t\t%d\n", cur_limits.rlim_cur); 314 printf("\tRLIMIT_MSGQUEUE(soft):\t\t%ld\n", (long) cur_limits.rlim_cur);
312 printf("\tRLIMIT_MSGQUEUE(hard):\t\t%d\n", cur_limits.rlim_max); 315 printf("\tRLIMIT_MSGQUEUE(hard):\t\t%ld\n", (long) cur_limits.rlim_max);
313 printf("\tMaximum Message Size:\t\t%d\n", cur_max_msgsize); 316 printf("\tMaximum Message Size:\t\t%d\n", cur_max_msgsize);
314 printf("\tMaximum Queue Size:\t\t%d\n", cur_max_msgs); 317 printf("\tMaximum Queue Size:\t\t%d\n", cur_max_msgs);
315 if (default_settings) { 318 if (default_settings) {
@@ -454,7 +457,12 @@ int main(int argc, char *argv[])
454 else 457 else
455 printf("Queue open with total size > 2GB when euid = 0 " 458 printf("Queue open with total size > 2GB when euid = 0 "
456 "failed:\t\t\tPASS\n"); 459 "failed:\t\t\tPASS\n");
457 seteuid(99); 460
461 if (seteuid(99) == -1) {
462 perror("seteuid() failed");
463 exit(1);
464 }
465
458 attr.mq_maxmsg = cur_max_msgs; 466 attr.mq_maxmsg = cur_max_msgs;
459 attr.mq_msgsize = cur_max_msgsize; 467 attr.mq_msgsize = cur_max_msgsize;
460 if (test_queue_fail(&attr, &result)) 468 if (test_queue_fail(&attr, &result))
diff --git a/tools/testing/selftests/mqueue/mq_perf_tests.c b/tools/testing/selftests/mqueue/mq_perf_tests.c
index 2fadd4b97045..94dae65eea41 100644
--- a/tools/testing/selftests/mqueue/mq_perf_tests.c
+++ b/tools/testing/selftests/mqueue/mq_perf_tests.c
@@ -296,9 +296,9 @@ static inline void open_queue(struct mq_attr *attr)
296 printf("\n\tQueue %s created:\n", queue_path); 296 printf("\n\tQueue %s created:\n", queue_path);
297 printf("\t\tmq_flags:\t\t\t%s\n", result.mq_flags & O_NONBLOCK ? 297 printf("\t\tmq_flags:\t\t\t%s\n", result.mq_flags & O_NONBLOCK ?
298 "O_NONBLOCK" : "(null)"); 298 "O_NONBLOCK" : "(null)");
299 printf("\t\tmq_maxmsg:\t\t\t%d\n", result.mq_maxmsg); 299 printf("\t\tmq_maxmsg:\t\t\t%lu\n", result.mq_maxmsg);
300 printf("\t\tmq_msgsize:\t\t\t%d\n", result.mq_msgsize); 300 printf("\t\tmq_msgsize:\t\t\t%lu\n", result.mq_msgsize);
301 printf("\t\tmq_curmsgs:\t\t\t%d\n", result.mq_curmsgs); 301 printf("\t\tmq_curmsgs:\t\t\t%lu\n", result.mq_curmsgs);
302} 302}
303 303
304void *fake_cont_thread(void *arg) 304void *fake_cont_thread(void *arg)
@@ -440,7 +440,7 @@ void *perf_test_thread(void *arg)
440 shutdown(2, "clock_getres()", __LINE__); 440 shutdown(2, "clock_getres()", __LINE__);
441 441
442 printf("\t\tMax priorities:\t\t\t%d\n", mq_prio_max); 442 printf("\t\tMax priorities:\t\t\t%d\n", mq_prio_max);
443 printf("\t\tClock resolution:\t\t%d nsec%s\n", res.tv_nsec, 443 printf("\t\tClock resolution:\t\t%lu nsec%s\n", res.tv_nsec,
444 res.tv_nsec > 1 ? "s" : ""); 444 res.tv_nsec > 1 ? "s" : "");
445 445
446 446
@@ -454,20 +454,20 @@ void *perf_test_thread(void *arg)
454 recv_total.tv_nsec = 0; 454 recv_total.tv_nsec = 0;
455 for (i = 0; i < TEST1_LOOPS; i++) 455 for (i = 0; i < TEST1_LOOPS; i++)
456 do_send_recv(); 456 do_send_recv();
457 printf("\t\tSend msg:\t\t\t%d.%ds total time\n", 457 printf("\t\tSend msg:\t\t\t%ld.%lus total time\n",
458 send_total.tv_sec, send_total.tv_nsec); 458 send_total.tv_sec, send_total.tv_nsec);
459 nsec = ((unsigned long long)send_total.tv_sec * 1000000000 + 459 nsec = ((unsigned long long)send_total.tv_sec * 1000000000 +
460 send_total.tv_nsec) / TEST1_LOOPS; 460 send_total.tv_nsec) / TEST1_LOOPS;
461 printf("\t\t\t\t\t\t%d nsec/msg\n", nsec); 461 printf("\t\t\t\t\t\t%lld nsec/msg\n", nsec);
462 printf("\t\tRecv msg:\t\t\t%d.%ds total time\n", 462 printf("\t\tRecv msg:\t\t\t%ld.%lus total time\n",
463 recv_total.tv_sec, recv_total.tv_nsec); 463 recv_total.tv_sec, recv_total.tv_nsec);
464 nsec = ((unsigned long long)recv_total.tv_sec * 1000000000 + 464 nsec = ((unsigned long long)recv_total.tv_sec * 1000000000 +
465 recv_total.tv_nsec) / TEST1_LOOPS; 465 recv_total.tv_nsec) / TEST1_LOOPS;
466 printf("\t\t\t\t\t\t%d nsec/msg\n", nsec); 466 printf("\t\t\t\t\t\t%lld nsec/msg\n", nsec);
467 467
468 468
469 for (cur_test = test2; cur_test->desc != NULL; cur_test++) { 469 for (cur_test = test2; cur_test->desc != NULL; cur_test++) {
470 printf(cur_test->desc); 470 printf("%s:\n", cur_test->desc);
471 printf("\t\t(%d iterations)\n", TEST2_LOOPS); 471 printf("\t\t(%d iterations)\n", TEST2_LOOPS);
472 prio_out = 0; 472 prio_out = 0;
473 send_total.tv_sec = 0; 473 send_total.tv_sec = 0;
@@ -493,16 +493,16 @@ void *perf_test_thread(void *arg)
493 cur_test->func(&prio_out); 493 cur_test->func(&prio_out);
494 } 494 }
495 printf("done.\n"); 495 printf("done.\n");
496 printf("\t\tSend msg:\t\t\t%d.%ds total time\n", 496 printf("\t\tSend msg:\t\t\t%ld.%lus total time\n",
497 send_total.tv_sec, send_total.tv_nsec); 497 send_total.tv_sec, send_total.tv_nsec);
498 nsec = ((unsigned long long)send_total.tv_sec * 1000000000 + 498 nsec = ((unsigned long long)send_total.tv_sec * 1000000000 +
499 send_total.tv_nsec) / TEST2_LOOPS; 499 send_total.tv_nsec) / TEST2_LOOPS;
500 printf("\t\t\t\t\t\t%d nsec/msg\n", nsec); 500 printf("\t\t\t\t\t\t%lld nsec/msg\n", nsec);
501 printf("\t\tRecv msg:\t\t\t%d.%ds total time\n", 501 printf("\t\tRecv msg:\t\t\t%ld.%lus total time\n",
502 recv_total.tv_sec, recv_total.tv_nsec); 502 recv_total.tv_sec, recv_total.tv_nsec);
503 nsec = ((unsigned long long)recv_total.tv_sec * 1000000000 + 503 nsec = ((unsigned long long)recv_total.tv_sec * 1000000000 +
504 recv_total.tv_nsec) / TEST2_LOOPS; 504 recv_total.tv_nsec) / TEST2_LOOPS;
505 printf("\t\t\t\t\t\t%d nsec/msg\n", nsec); 505 printf("\t\t\t\t\t\t%lld nsec/msg\n", nsec);
506 printf("\t\tDraining queue..."); 506 printf("\t\tDraining queue...");
507 fflush(stdout); 507 fflush(stdout);
508 clock_gettime(clock, &start); 508 clock_gettime(clock, &start);
@@ -653,8 +653,10 @@ int main(int argc, char *argv[])
653 /* Tell the user our initial state */ 653 /* Tell the user our initial state */
654 printf("\nInitial system state:\n"); 654 printf("\nInitial system state:\n");
655 printf("\tUsing queue path:\t\t\t%s\n", queue_path); 655 printf("\tUsing queue path:\t\t\t%s\n", queue_path);
656 printf("\tRLIMIT_MSGQUEUE(soft):\t\t\t%d\n", saved_limits.rlim_cur); 656 printf("\tRLIMIT_MSGQUEUE(soft):\t\t\t%ld\n",
657 printf("\tRLIMIT_MSGQUEUE(hard):\t\t\t%d\n", saved_limits.rlim_max); 657 (long) saved_limits.rlim_cur);
658 printf("\tRLIMIT_MSGQUEUE(hard):\t\t\t%ld\n",
659 (long) saved_limits.rlim_max);
658 printf("\tMaximum Message Size:\t\t\t%d\n", saved_max_msgsize); 660 printf("\tMaximum Message Size:\t\t\t%d\n", saved_max_msgsize);
659 printf("\tMaximum Queue Size:\t\t\t%d\n", saved_max_msgs); 661 printf("\tMaximum Queue Size:\t\t\t%d\n", saved_max_msgs);
660 printf("\tNice value:\t\t\t\t%d\n", cur_nice); 662 printf("\tNice value:\t\t\t\t%d\n", cur_nice);
@@ -667,10 +669,10 @@ int main(int argc, char *argv[])
667 printf("\tRLIMIT_MSGQUEUE(soft):\t\t\t(unlimited)\n"); 669 printf("\tRLIMIT_MSGQUEUE(soft):\t\t\t(unlimited)\n");
668 printf("\tRLIMIT_MSGQUEUE(hard):\t\t\t(unlimited)\n"); 670 printf("\tRLIMIT_MSGQUEUE(hard):\t\t\t(unlimited)\n");
669 } else { 671 } else {
670 printf("\tRLIMIT_MSGQUEUE(soft):\t\t\t%d\n", 672 printf("\tRLIMIT_MSGQUEUE(soft):\t\t\t%ld\n",
671 cur_limits.rlim_cur); 673 (long) cur_limits.rlim_cur);
672 printf("\tRLIMIT_MSGQUEUE(hard):\t\t\t%d\n", 674 printf("\tRLIMIT_MSGQUEUE(hard):\t\t\t%ld\n",
673 cur_limits.rlim_max); 675 (long) cur_limits.rlim_max);
674 } 676 }
675 printf("\tMaximum Message Size:\t\t\t%d\n", cur_max_msgsize); 677 printf("\tMaximum Message Size:\t\t\t%d\n", cur_max_msgsize);
676 printf("\tMaximum Queue Size:\t\t\t%d\n", cur_max_msgs); 678 printf("\tMaximum Queue Size:\t\t\t%d\n", cur_max_msgs);
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index 54833a791a44..74a78cedce37 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -17,10 +17,10 @@ TARGETS = pmu copyloops mm tm
17 17
18endif 18endif
19 19
20all: 20all: $(TARGETS)
21 @for TARGET in $(TARGETS); do \ 21
22 $(MAKE) -C $$TARGET all; \ 22$(TARGETS):
23 done; 23 $(MAKE) -k -C $@ all
24 24
25run_tests: all 25run_tests: all
26 @for TARGET in $(TARGETS); do \ 26 @for TARGET in $(TARGETS); do \
@@ -36,4 +36,4 @@ clean:
36tags: 36tags:
37 find . -name '*.c' -o -name '*.h' | xargs ctags 37 find . -name '*.c' -o -name '*.h' | xargs ctags
38 38
39.PHONY: all run_tests clean tags 39.PHONY: all run_tests clean tags $(TARGETS)
diff --git a/tools/testing/selftests/powerpc/pmu/Makefile b/tools/testing/selftests/powerpc/pmu/Makefile
index b9ff0db42c79..c9f4263906a5 100644
--- a/tools/testing/selftests/powerpc/pmu/Makefile
+++ b/tools/testing/selftests/powerpc/pmu/Makefile
@@ -1,10 +1,12 @@
1noarg: 1noarg:
2 $(MAKE) -C ../ 2 $(MAKE) -C ../
3 3
4PROGS := count_instructions 4PROGS := count_instructions l3_bank_test per_event_excludes
5EXTRA_SOURCES := ../harness.c event.c 5EXTRA_SOURCES := ../harness.c event.c lib.c
6 6
7all: $(PROGS) sub_all 7SUB_TARGETS = ebb
8
9all: $(PROGS) $(SUB_TARGETS)
8 10
9$(PROGS): $(EXTRA_SOURCES) 11$(PROGS): $(EXTRA_SOURCES)
10 12
@@ -20,13 +22,8 @@ run_tests: all sub_run_tests
20clean: sub_clean 22clean: sub_clean
21 rm -f $(PROGS) loop.o 23 rm -f $(PROGS) loop.o
22 24
23 25$(SUB_TARGETS):
24SUB_TARGETS = ebb 26 $(MAKE) -k -C $@ all
25
26sub_all:
27 @for TARGET in $(SUB_TARGETS); do \
28 $(MAKE) -C $$TARGET all; \
29 done;
30 27
31sub_run_tests: all 28sub_run_tests: all
32 @for TARGET in $(SUB_TARGETS); do \ 29 @for TARGET in $(SUB_TARGETS); do \
@@ -38,4 +35,4 @@ sub_clean:
38 $(MAKE) -C $$TARGET clean; \ 35 $(MAKE) -C $$TARGET clean; \
39 done; 36 done;
40 37
41.PHONY: all run_tests clean sub_all sub_run_tests sub_clean 38.PHONY: all run_tests clean sub_run_tests sub_clean $(SUB_TARGETS)
diff --git a/tools/testing/selftests/powerpc/pmu/count_instructions.c b/tools/testing/selftests/powerpc/pmu/count_instructions.c
index 312b4f0fd27c..4622117b24c0 100644
--- a/tools/testing/selftests/powerpc/pmu/count_instructions.c
+++ b/tools/testing/selftests/powerpc/pmu/count_instructions.c
@@ -12,6 +12,7 @@
12 12
13#include "event.h" 13#include "event.h"
14#include "utils.h" 14#include "utils.h"
15#include "lib.h"
15 16
16extern void thirty_two_instruction_loop(u64 loops); 17extern void thirty_two_instruction_loop(u64 loops);
17 18
@@ -90,7 +91,7 @@ static u64 determine_overhead(struct event *events)
90 return overhead; 91 return overhead;
91} 92}
92 93
93static int count_instructions(void) 94static int test_body(void)
94{ 95{
95 struct event events[2]; 96 struct event events[2];
96 u64 overhead; 97 u64 overhead;
@@ -111,17 +112,23 @@ static int count_instructions(void)
111 overhead = determine_overhead(events); 112 overhead = determine_overhead(events);
112 printf("Overhead of null loop: %llu instructions\n", overhead); 113 printf("Overhead of null loop: %llu instructions\n", overhead);
113 114
114 /* Run for 1M instructions */ 115 /* Run for 1Mi instructions */
115 FAIL_IF(do_count_loop(events, 0x100000, overhead, true)); 116 FAIL_IF(do_count_loop(events, 1000000, overhead, true));
117
118 /* Run for 10Mi instructions */
119 FAIL_IF(do_count_loop(events, 10000000, overhead, true));
120
121 /* Run for 100Mi instructions */
122 FAIL_IF(do_count_loop(events, 100000000, overhead, true));
116 123
117 /* Run for 10M instructions */ 124 /* Run for 1Bi instructions */
118 FAIL_IF(do_count_loop(events, 0xa00000, overhead, true)); 125 FAIL_IF(do_count_loop(events, 1000000000, overhead, true));
119 126
120 /* Run for 100M instructions */ 127 /* Run for 16Bi instructions */
121 FAIL_IF(do_count_loop(events, 0x6400000, overhead, true)); 128 FAIL_IF(do_count_loop(events, 16000000000, overhead, true));
122 129
123 /* Run for 1G instructions */ 130 /* Run for 64Bi instructions */
124 FAIL_IF(do_count_loop(events, 0x40000000, overhead, true)); 131 FAIL_IF(do_count_loop(events, 64000000000, overhead, true));
125 132
126 event_close(&events[0]); 133 event_close(&events[0]);
127 event_close(&events[1]); 134 event_close(&events[1]);
@@ -129,6 +136,11 @@ static int count_instructions(void)
129 return 0; 136 return 0;
130} 137}
131 138
139static int count_instructions(void)
140{
141 return eat_cpu(test_body);
142}
143
132int main(void) 144int main(void)
133{ 145{
134 return test_harness(count_instructions, "count_instructions"); 146 return test_harness(count_instructions, "count_instructions");
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/Makefile b/tools/testing/selftests/powerpc/pmu/ebb/Makefile
index edbba2affc2c..3dc4332698cb 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/Makefile
+++ b/tools/testing/selftests/powerpc/pmu/ebb/Makefile
@@ -13,11 +13,12 @@ PROGS := reg_access_test event_attributes_test cycles_test \
13 close_clears_pmcc_test instruction_count_test \ 13 close_clears_pmcc_test instruction_count_test \
14 fork_cleanup_test ebb_on_child_test \ 14 fork_cleanup_test ebb_on_child_test \
15 ebb_on_willing_child_test back_to_back_ebbs_test \ 15 ebb_on_willing_child_test back_to_back_ebbs_test \
16 lost_exception_test no_handler_test 16 lost_exception_test no_handler_test \
17 cycles_with_mmcr2_test
17 18
18all: $(PROGS) 19all: $(PROGS)
19 20
20$(PROGS): ../../harness.c ../event.c ../lib.c ebb.c ebb_handler.S trace.c 21$(PROGS): ../../harness.c ../event.c ../lib.c ebb.c ebb_handler.S trace.c busy_loop.S
21 22
22instruction_count_test: ../loop.S 23instruction_count_test: ../loop.S
23 24
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/busy_loop.S b/tools/testing/selftests/powerpc/pmu/ebb/busy_loop.S
new file mode 100644
index 000000000000..c7e4093f1cd3
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/ebb/busy_loop.S
@@ -0,0 +1,271 @@
1/*
2 * Copyright 2014, Michael Ellerman, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#include <ppc-asm.h>
7
8 .text
9
10FUNC_START(core_busy_loop)
11 stdu %r1, -168(%r1)
12 std r14, 160(%r1)
13 std r15, 152(%r1)
14 std r16, 144(%r1)
15 std r17, 136(%r1)
16 std r18, 128(%r1)
17 std r19, 120(%r1)
18 std r20, 112(%r1)
19 std r21, 104(%r1)
20 std r22, 96(%r1)
21 std r23, 88(%r1)
22 std r24, 80(%r1)
23 std r25, 72(%r1)
24 std r26, 64(%r1)
25 std r27, 56(%r1)
26 std r28, 48(%r1)
27 std r29, 40(%r1)
28 std r30, 32(%r1)
29 std r31, 24(%r1)
30
31 li r3, 0x3030
32 std r3, -96(%r1)
33 li r4, 0x4040
34 std r4, -104(%r1)
35 li r5, 0x5050
36 std r5, -112(%r1)
37 li r6, 0x6060
38 std r6, -120(%r1)
39 li r7, 0x7070
40 std r7, -128(%r1)
41 li r8, 0x0808
42 std r8, -136(%r1)
43 li r9, 0x0909
44 std r9, -144(%r1)
45 li r10, 0x1010
46 std r10, -152(%r1)
47 li r11, 0x1111
48 std r11, -160(%r1)
49 li r14, 0x1414
50 std r14, -168(%r1)
51 li r15, 0x1515
52 std r15, -176(%r1)
53 li r16, 0x1616
54 std r16, -184(%r1)
55 li r17, 0x1717
56 std r17, -192(%r1)
57 li r18, 0x1818
58 std r18, -200(%r1)
59 li r19, 0x1919
60 std r19, -208(%r1)
61 li r20, 0x2020
62 std r20, -216(%r1)
63 li r21, 0x2121
64 std r21, -224(%r1)
65 li r22, 0x2222
66 std r22, -232(%r1)
67 li r23, 0x2323
68 std r23, -240(%r1)
69 li r24, 0x2424
70 std r24, -248(%r1)
71 li r25, 0x2525
72 std r25, -256(%r1)
73 li r26, 0x2626
74 std r26, -264(%r1)
75 li r27, 0x2727
76 std r27, -272(%r1)
77 li r28, 0x2828
78 std r28, -280(%r1)
79 li r29, 0x2929
80 std r29, -288(%r1)
81 li r30, 0x3030
82 li r31, 0x3131
83
84 li r3, 0
850: addi r3, r3, 1
86 cmpwi r3, 100
87 blt 0b
88
89 /* Return 1 (fail) unless we get through all the checks */
90 li r3, 1
91
92 /* Check none of our registers have been corrupted */
93 cmpwi r4, 0x4040
94 bne 1f
95 cmpwi r5, 0x5050
96 bne 1f
97 cmpwi r6, 0x6060
98 bne 1f
99 cmpwi r7, 0x7070
100 bne 1f
101 cmpwi r8, 0x0808
102 bne 1f
103 cmpwi r9, 0x0909
104 bne 1f
105 cmpwi r10, 0x1010
106 bne 1f
107 cmpwi r11, 0x1111
108 bne 1f
109 cmpwi r14, 0x1414
110 bne 1f
111 cmpwi r15, 0x1515
112 bne 1f
113 cmpwi r16, 0x1616
114 bne 1f
115 cmpwi r17, 0x1717
116 bne 1f
117 cmpwi r18, 0x1818
118 bne 1f
119 cmpwi r19, 0x1919
120 bne 1f
121 cmpwi r20, 0x2020
122 bne 1f
123 cmpwi r21, 0x2121
124 bne 1f
125 cmpwi r22, 0x2222
126 bne 1f
127 cmpwi r23, 0x2323
128 bne 1f
129 cmpwi r24, 0x2424
130 bne 1f
131 cmpwi r25, 0x2525
132 bne 1f
133 cmpwi r26, 0x2626
134 bne 1f
135 cmpwi r27, 0x2727
136 bne 1f
137 cmpwi r28, 0x2828
138 bne 1f
139 cmpwi r29, 0x2929
140 bne 1f
141 cmpwi r30, 0x3030
142 bne 1f
143 cmpwi r31, 0x3131
144 bne 1f
145
146 /* Load junk into all our registers before we reload them from the stack. */
147 li r3, 0xde
148 li r4, 0xad
149 li r5, 0xbe
150 li r6, 0xef
151 li r7, 0xde
152 li r8, 0xad
153 li r9, 0xbe
154 li r10, 0xef
155 li r11, 0xde
156 li r14, 0xad
157 li r15, 0xbe
158 li r16, 0xef
159 li r17, 0xde
160 li r18, 0xad
161 li r19, 0xbe
162 li r20, 0xef
163 li r21, 0xde
164 li r22, 0xad
165 li r23, 0xbe
166 li r24, 0xef
167 li r25, 0xde
168 li r26, 0xad
169 li r27, 0xbe
170 li r28, 0xef
171 li r29, 0xdd
172
173 ld r3, -96(%r1)
174 cmpwi r3, 0x3030
175 bne 1f
176 ld r4, -104(%r1)
177 cmpwi r4, 0x4040
178 bne 1f
179 ld r5, -112(%r1)
180 cmpwi r5, 0x5050
181 bne 1f
182 ld r6, -120(%r1)
183 cmpwi r6, 0x6060
184 bne 1f
185 ld r7, -128(%r1)
186 cmpwi r7, 0x7070
187 bne 1f
188 ld r8, -136(%r1)
189 cmpwi r8, 0x0808
190 bne 1f
191 ld r9, -144(%r1)
192 cmpwi r9, 0x0909
193 bne 1f
194 ld r10, -152(%r1)
195 cmpwi r10, 0x1010
196 bne 1f
197 ld r11, -160(%r1)
198 cmpwi r11, 0x1111
199 bne 1f
200 ld r14, -168(%r1)
201 cmpwi r14, 0x1414
202 bne 1f
203 ld r15, -176(%r1)
204 cmpwi r15, 0x1515
205 bne 1f
206 ld r16, -184(%r1)
207 cmpwi r16, 0x1616
208 bne 1f
209 ld r17, -192(%r1)
210 cmpwi r17, 0x1717
211 bne 1f
212 ld r18, -200(%r1)
213 cmpwi r18, 0x1818
214 bne 1f
215 ld r19, -208(%r1)
216 cmpwi r19, 0x1919
217 bne 1f
218 ld r20, -216(%r1)
219 cmpwi r20, 0x2020
220 bne 1f
221 ld r21, -224(%r1)
222 cmpwi r21, 0x2121
223 bne 1f
224 ld r22, -232(%r1)
225 cmpwi r22, 0x2222
226 bne 1f
227 ld r23, -240(%r1)
228 cmpwi r23, 0x2323
229 bne 1f
230 ld r24, -248(%r1)
231 cmpwi r24, 0x2424
232 bne 1f
233 ld r25, -256(%r1)
234 cmpwi r25, 0x2525
235 bne 1f
236 ld r26, -264(%r1)
237 cmpwi r26, 0x2626
238 bne 1f
239 ld r27, -272(%r1)
240 cmpwi r27, 0x2727
241 bne 1f
242 ld r28, -280(%r1)
243 cmpwi r28, 0x2828
244 bne 1f
245 ld r29, -288(%r1)
246 cmpwi r29, 0x2929
247 bne 1f
248
249 /* Load 0 (success) to return */
250 li r3, 0
251
2521: ld r14, 160(%r1)
253 ld r15, 152(%r1)
254 ld r16, 144(%r1)
255 ld r17, 136(%r1)
256 ld r18, 128(%r1)
257 ld r19, 120(%r1)
258 ld r20, 112(%r1)
259 ld r21, 104(%r1)
260 ld r22, 96(%r1)
261 ld r23, 88(%r1)
262 ld r24, 80(%r1)
263 ld r25, 72(%r1)
264 ld r26, 64(%r1)
265 ld r27, 56(%r1)
266 ld r28, 48(%r1)
267 ld r29, 40(%r1)
268 ld r30, 32(%r1)
269 ld r31, 24(%r1)
270 addi %r1, %r1, 168
271 blr
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c b/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c
new file mode 100644
index 000000000000..d43029b0800c
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c
@@ -0,0 +1,91 @@
1/*
2 * Copyright 2014, Michael Ellerman, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <stdbool.h>
9
10#include "ebb.h"
11
12
13/*
14 * Test of counting cycles while manipulating the user accessible bits in MMCR2.
15 */
16
17/* We use two values because the first freezes PMC1 and so we would get no EBBs */
18#define MMCR2_EXPECTED_1 0x4020100804020000UL /* (FC1P|FC2P|FC3P|FC4P|FC5P|FC6P) */
19#define MMCR2_EXPECTED_2 0x0020100804020000UL /* ( FC2P|FC3P|FC4P|FC5P|FC6P) */
20
21
22int cycles_with_mmcr2(void)
23{
24 struct event event;
25 uint64_t val, expected[2], actual;
26 int i;
27 bool bad_mmcr2;
28
29 event_init_named(&event, 0x1001e, "cycles");
30 event_leader_ebb_init(&event);
31
32 event.attr.exclude_kernel = 1;
33 event.attr.exclude_hv = 1;
34 event.attr.exclude_idle = 1;
35
36 FAIL_IF(event_open(&event));
37
38 ebb_enable_pmc_counting(1);
39 setup_ebb_handler(standard_ebb_callee);
40 ebb_global_enable();
41
42 FAIL_IF(ebb_event_enable(&event));
43
44 mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
45
46 /* XXX Set of MMCR2 must be after enable */
47 expected[0] = MMCR2_EXPECTED_1;
48 expected[1] = MMCR2_EXPECTED_2;
49 i = 0;
50 bad_mmcr2 = false;
51
52 /* Make sure we loop until we take at least one EBB */
53 while ((ebb_state.stats.ebb_count < 20 && !bad_mmcr2) ||
54 ebb_state.stats.ebb_count < 1)
55 {
56 mtspr(SPRN_MMCR2, expected[i % 2]);
57
58 FAIL_IF(core_busy_loop());
59
60 val = mfspr(SPRN_MMCR2);
61 if (val != expected[i % 2]) {
62 bad_mmcr2 = true;
63 actual = val;
64 }
65
66 i++;
67 }
68
69 ebb_global_disable();
70 ebb_freeze_pmcs();
71
72 count_pmc(1, sample_period);
73
74 dump_ebb_state();
75
76 event_close(&event);
77
78 FAIL_IF(ebb_state.stats.ebb_count == 0);
79
80 if (bad_mmcr2)
81 printf("Bad MMCR2 value seen is 0x%lx\n", actual);
82
83 FAIL_IF(bad_mmcr2);
84
85 return 0;
86}
87
88int main(void)
89{
90 return test_harness(cycles_with_mmcr2, "cycles_with_mmcr2");
91}
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb.c b/tools/testing/selftests/powerpc/pmu/ebb/ebb.c
index 1b46be94b64c..d7a72ce696b5 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/ebb.c
+++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb.c
@@ -224,6 +224,7 @@ void dump_ebb_hw_state(void)
224 224
225 printf("HW state:\n" \ 225 printf("HW state:\n" \
226 "MMCR0 0x%016x %s\n" \ 226 "MMCR0 0x%016x %s\n" \
227 "MMCR2 0x%016lx\n" \
227 "EBBHR 0x%016lx\n" \ 228 "EBBHR 0x%016lx\n" \
228 "BESCR 0x%016llx %s\n" \ 229 "BESCR 0x%016llx %s\n" \
229 "PMC1 0x%016lx\n" \ 230 "PMC1 0x%016lx\n" \
@@ -233,10 +234,11 @@ void dump_ebb_hw_state(void)
233 "PMC5 0x%016lx\n" \ 234 "PMC5 0x%016lx\n" \
234 "PMC6 0x%016lx\n" \ 235 "PMC6 0x%016lx\n" \
235 "SIAR 0x%016lx\n", 236 "SIAR 0x%016lx\n",
236 mmcr0, decode_mmcr0(mmcr0), mfspr(SPRN_EBBHR), bescr, 237 mmcr0, decode_mmcr0(mmcr0), mfspr(SPRN_MMCR2),
237 decode_bescr(bescr), mfspr(SPRN_PMC1), mfspr(SPRN_PMC2), 238 mfspr(SPRN_EBBHR), bescr, decode_bescr(bescr),
238 mfspr(SPRN_PMC3), mfspr(SPRN_PMC4), mfspr(SPRN_PMC5), 239 mfspr(SPRN_PMC1), mfspr(SPRN_PMC2), mfspr(SPRN_PMC3),
239 mfspr(SPRN_PMC6), mfspr(SPRN_SIAR)); 240 mfspr(SPRN_PMC4), mfspr(SPRN_PMC5), mfspr(SPRN_PMC6),
241 mfspr(SPRN_SIAR));
240} 242}
241 243
242void dump_ebb_state(void) 244void dump_ebb_state(void)
@@ -335,257 +337,6 @@ void event_leader_ebb_init(struct event *e)
335 e->attr.pinned = 1; 337 e->attr.pinned = 1;
336} 338}
337 339
338int core_busy_loop(void)
339{
340 int rc;
341
342 asm volatile (
343 "li 3, 0x3030\n"
344 "std 3, -96(1)\n"
345 "li 4, 0x4040\n"
346 "std 4, -104(1)\n"
347 "li 5, 0x5050\n"
348 "std 5, -112(1)\n"
349 "li 6, 0x6060\n"
350 "std 6, -120(1)\n"
351 "li 7, 0x7070\n"
352 "std 7, -128(1)\n"
353 "li 8, 0x0808\n"
354 "std 8, -136(1)\n"
355 "li 9, 0x0909\n"
356 "std 9, -144(1)\n"
357 "li 10, 0x1010\n"
358 "std 10, -152(1)\n"
359 "li 11, 0x1111\n"
360 "std 11, -160(1)\n"
361 "li 14, 0x1414\n"
362 "std 14, -168(1)\n"
363 "li 15, 0x1515\n"
364 "std 15, -176(1)\n"
365 "li 16, 0x1616\n"
366 "std 16, -184(1)\n"
367 "li 17, 0x1717\n"
368 "std 17, -192(1)\n"
369 "li 18, 0x1818\n"
370 "std 18, -200(1)\n"
371 "li 19, 0x1919\n"
372 "std 19, -208(1)\n"
373 "li 20, 0x2020\n"
374 "std 20, -216(1)\n"
375 "li 21, 0x2121\n"
376 "std 21, -224(1)\n"
377 "li 22, 0x2222\n"
378 "std 22, -232(1)\n"
379 "li 23, 0x2323\n"
380 "std 23, -240(1)\n"
381 "li 24, 0x2424\n"
382 "std 24, -248(1)\n"
383 "li 25, 0x2525\n"
384 "std 25, -256(1)\n"
385 "li 26, 0x2626\n"
386 "std 26, -264(1)\n"
387 "li 27, 0x2727\n"
388 "std 27, -272(1)\n"
389 "li 28, 0x2828\n"
390 "std 28, -280(1)\n"
391 "li 29, 0x2929\n"
392 "std 29, -288(1)\n"
393 "li 30, 0x3030\n"
394 "li 31, 0x3131\n"
395
396 "li 3, 0\n"
397 "0: "
398 "addi 3, 3, 1\n"
399 "cmpwi 3, 100\n"
400 "blt 0b\n"
401
402 /* Return 1 (fail) unless we get through all the checks */
403 "li 0, 1\n"
404
405 /* Check none of our registers have been corrupted */
406 "cmpwi 4, 0x4040\n"
407 "bne 1f\n"
408 "cmpwi 5, 0x5050\n"
409 "bne 1f\n"
410 "cmpwi 6, 0x6060\n"
411 "bne 1f\n"
412 "cmpwi 7, 0x7070\n"
413 "bne 1f\n"
414 "cmpwi 8, 0x0808\n"
415 "bne 1f\n"
416 "cmpwi 9, 0x0909\n"
417 "bne 1f\n"
418 "cmpwi 10, 0x1010\n"
419 "bne 1f\n"
420 "cmpwi 11, 0x1111\n"
421 "bne 1f\n"
422 "cmpwi 14, 0x1414\n"
423 "bne 1f\n"
424 "cmpwi 15, 0x1515\n"
425 "bne 1f\n"
426 "cmpwi 16, 0x1616\n"
427 "bne 1f\n"
428 "cmpwi 17, 0x1717\n"
429 "bne 1f\n"
430 "cmpwi 18, 0x1818\n"
431 "bne 1f\n"
432 "cmpwi 19, 0x1919\n"
433 "bne 1f\n"
434 "cmpwi 20, 0x2020\n"
435 "bne 1f\n"
436 "cmpwi 21, 0x2121\n"
437 "bne 1f\n"
438 "cmpwi 22, 0x2222\n"
439 "bne 1f\n"
440 "cmpwi 23, 0x2323\n"
441 "bne 1f\n"
442 "cmpwi 24, 0x2424\n"
443 "bne 1f\n"
444 "cmpwi 25, 0x2525\n"
445 "bne 1f\n"
446 "cmpwi 26, 0x2626\n"
447 "bne 1f\n"
448 "cmpwi 27, 0x2727\n"
449 "bne 1f\n"
450 "cmpwi 28, 0x2828\n"
451 "bne 1f\n"
452 "cmpwi 29, 0x2929\n"
453 "bne 1f\n"
454 "cmpwi 30, 0x3030\n"
455 "bne 1f\n"
456 "cmpwi 31, 0x3131\n"
457 "bne 1f\n"
458
459 /* Load junk into all our registers before we reload them from the stack. */
460 "li 3, 0xde\n"
461 "li 4, 0xad\n"
462 "li 5, 0xbe\n"
463 "li 6, 0xef\n"
464 "li 7, 0xde\n"
465 "li 8, 0xad\n"
466 "li 9, 0xbe\n"
467 "li 10, 0xef\n"
468 "li 11, 0xde\n"
469 "li 14, 0xad\n"
470 "li 15, 0xbe\n"
471 "li 16, 0xef\n"
472 "li 17, 0xde\n"
473 "li 18, 0xad\n"
474 "li 19, 0xbe\n"
475 "li 20, 0xef\n"
476 "li 21, 0xde\n"
477 "li 22, 0xad\n"
478 "li 23, 0xbe\n"
479 "li 24, 0xef\n"
480 "li 25, 0xde\n"
481 "li 26, 0xad\n"
482 "li 27, 0xbe\n"
483 "li 28, 0xef\n"
484 "li 29, 0xdd\n"
485
486 "ld 3, -96(1)\n"
487 "cmpwi 3, 0x3030\n"
488 "bne 1f\n"
489 "ld 4, -104(1)\n"
490 "cmpwi 4, 0x4040\n"
491 "bne 1f\n"
492 "ld 5, -112(1)\n"
493 "cmpwi 5, 0x5050\n"
494 "bne 1f\n"
495 "ld 6, -120(1)\n"
496 "cmpwi 6, 0x6060\n"
497 "bne 1f\n"
498 "ld 7, -128(1)\n"
499 "cmpwi 7, 0x7070\n"
500 "bne 1f\n"
501 "ld 8, -136(1)\n"
502 "cmpwi 8, 0x0808\n"
503 "bne 1f\n"
504 "ld 9, -144(1)\n"
505 "cmpwi 9, 0x0909\n"
506 "bne 1f\n"
507 "ld 10, -152(1)\n"
508 "cmpwi 10, 0x1010\n"
509 "bne 1f\n"
510 "ld 11, -160(1)\n"
511 "cmpwi 11, 0x1111\n"
512 "bne 1f\n"
513 "ld 14, -168(1)\n"
514 "cmpwi 14, 0x1414\n"
515 "bne 1f\n"
516 "ld 15, -176(1)\n"
517 "cmpwi 15, 0x1515\n"
518 "bne 1f\n"
519 "ld 16, -184(1)\n"
520 "cmpwi 16, 0x1616\n"
521 "bne 1f\n"
522 "ld 17, -192(1)\n"
523 "cmpwi 17, 0x1717\n"
524 "bne 1f\n"
525 "ld 18, -200(1)\n"
526 "cmpwi 18, 0x1818\n"
527 "bne 1f\n"
528 "ld 19, -208(1)\n"
529 "cmpwi 19, 0x1919\n"
530 "bne 1f\n"
531 "ld 20, -216(1)\n"
532 "cmpwi 20, 0x2020\n"
533 "bne 1f\n"
534 "ld 21, -224(1)\n"
535 "cmpwi 21, 0x2121\n"
536 "bne 1f\n"
537 "ld 22, -232(1)\n"
538 "cmpwi 22, 0x2222\n"
539 "bne 1f\n"
540 "ld 23, -240(1)\n"
541 "cmpwi 23, 0x2323\n"
542 "bne 1f\n"
543 "ld 24, -248(1)\n"
544 "cmpwi 24, 0x2424\n"
545 "bne 1f\n"
546 "ld 25, -256(1)\n"
547 "cmpwi 25, 0x2525\n"
548 "bne 1f\n"
549 "ld 26, -264(1)\n"
550 "cmpwi 26, 0x2626\n"
551 "bne 1f\n"
552 "ld 27, -272(1)\n"
553 "cmpwi 27, 0x2727\n"
554 "bne 1f\n"
555 "ld 28, -280(1)\n"
556 "cmpwi 28, 0x2828\n"
557 "bne 1f\n"
558 "ld 29, -288(1)\n"
559 "cmpwi 29, 0x2929\n"
560 "bne 1f\n"
561
562 /* Load 0 (success) to return */
563 "li 0, 0\n"
564
565 "1: mr %0, 0\n"
566
567 : "=r" (rc)
568 : /* no inputs */
569 : "3", "4", "5", "6", "7", "8", "9", "10", "11", "14",
570 "15", "16", "17", "18", "19", "20", "21", "22", "23",
571 "24", "25", "26", "27", "28", "29", "30", "31",
572 "memory"
573 );
574
575 return rc;
576}
577
578int core_busy_loop_with_freeze(void)
579{
580 int rc;
581
582 mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_FC);
583 rc = core_busy_loop();
584 mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_FC);
585
586 return rc;
587}
588
589int ebb_child(union pipe read_pipe, union pipe write_pipe) 340int ebb_child(union pipe read_pipe, union pipe write_pipe)
590{ 341{
591 struct event event; 342 struct event event;
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb.h b/tools/testing/selftests/powerpc/pmu/ebb/ebb.h
index e62bde05bf78..e44eee5d97ca 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/ebb.h
+++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb.h
@@ -70,7 +70,6 @@ int ebb_check_mmcr0(void);
70extern u64 sample_period; 70extern u64 sample_period;
71 71
72int core_busy_loop(void); 72int core_busy_loop(void);
73int core_busy_loop_with_freeze(void);
74int ebb_child(union pipe read_pipe, union pipe write_pipe); 73int ebb_child(union pipe read_pipe, union pipe write_pipe);
75int catch_sigill(void (*func)(void)); 74int catch_sigill(void (*func)(void));
76void write_pmc1(void); 75void write_pmc1(void);
diff --git a/tools/testing/selftests/powerpc/pmu/l3_bank_test.c b/tools/testing/selftests/powerpc/pmu/l3_bank_test.c
new file mode 100644
index 000000000000..77472f31441e
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/l3_bank_test.c
@@ -0,0 +1,48 @@
1/*
2 * Copyright 2014, Michael Ellerman, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8
9#include "event.h"
10#include "utils.h"
11
12#define MALLOC_SIZE (0x10000 * 10) /* Ought to be enough .. */
13
14/*
15 * Tests that the L3 bank handling is correct. We fixed it in commit e9aaac1.
16 */
17static int l3_bank_test(void)
18{
19 struct event event;
20 char *p;
21 int i;
22
23 p = malloc(MALLOC_SIZE);
24 FAIL_IF(!p);
25
26 event_init(&event, 0x84918F);
27
28 FAIL_IF(event_open(&event));
29
30 for (i = 0; i < MALLOC_SIZE; i += 0x10000)
31 p[i] = i;
32
33 event_read(&event);
34 event_report(&event);
35
36 FAIL_IF(event.result.running == 0);
37 FAIL_IF(event.result.enabled == 0);
38
39 event_close(&event);
40 free(p);
41
42 return 0;
43}
44
45int main(void)
46{
47 return test_harness(l3_bank_test, "l3_bank_test");
48}
diff --git a/tools/testing/selftests/powerpc/pmu/lib.c b/tools/testing/selftests/powerpc/pmu/lib.c
index 0f6a4731d546..9768dea37bf3 100644
--- a/tools/testing/selftests/powerpc/pmu/lib.c
+++ b/tools/testing/selftests/powerpc/pmu/lib.c
@@ -5,10 +5,15 @@
5 5
6#define _GNU_SOURCE /* For CPU_ZERO etc. */ 6#define _GNU_SOURCE /* For CPU_ZERO etc. */
7 7
8#include <elf.h>
8#include <errno.h> 9#include <errno.h>
10#include <fcntl.h>
11#include <link.h>
9#include <sched.h> 12#include <sched.h>
10#include <setjmp.h> 13#include <setjmp.h>
11#include <stdlib.h> 14#include <stdlib.h>
15#include <sys/stat.h>
16#include <sys/types.h>
12#include <sys/wait.h> 17#include <sys/wait.h>
13 18
14#include "utils.h" 19#include "utils.h"
@@ -177,8 +182,8 @@ struct addr_range libc, vdso;
177 182
178int parse_proc_maps(void) 183int parse_proc_maps(void)
179{ 184{
185 unsigned long start, end;
180 char execute, name[128]; 186 char execute, name[128];
181 uint64_t start, end;
182 FILE *f; 187 FILE *f;
183 int rc; 188 int rc;
184 189
@@ -250,3 +255,46 @@ out_close:
250out: 255out:
251 return rc; 256 return rc;
252} 257}
258
259static char auxv[4096];
260
261void *get_auxv_entry(int type)
262{
263 ElfW(auxv_t) *p;
264 void *result;
265 ssize_t num;
266 int fd;
267
268 fd = open("/proc/self/auxv", O_RDONLY);
269 if (fd == -1) {
270 perror("open");
271 return NULL;
272 }
273
274 result = NULL;
275
276 num = read(fd, auxv, sizeof(auxv));
277 if (num < 0) {
278 perror("read");
279 goto out;
280 }
281
282 if (num > sizeof(auxv)) {
283 printf("Overflowed auxv buffer\n");
284 goto out;
285 }
286
287 p = (ElfW(auxv_t) *)auxv;
288
289 while (p->a_type != AT_NULL) {
290 if (p->a_type == type) {
291 result = (void *)p->a_un.a_val;
292 break;
293 }
294
295 p++;
296 }
297out:
298 close(fd);
299 return result;
300}
diff --git a/tools/testing/selftests/powerpc/pmu/lib.h b/tools/testing/selftests/powerpc/pmu/lib.h
index ca5d72ae3be6..0f0339c8a6f6 100644
--- a/tools/testing/selftests/powerpc/pmu/lib.h
+++ b/tools/testing/selftests/powerpc/pmu/lib.h
@@ -29,6 +29,7 @@ extern int notify_parent(union pipe write_pipe);
29extern int notify_parent_of_error(union pipe write_pipe); 29extern int notify_parent_of_error(union pipe write_pipe);
30extern pid_t eat_cpu(int (test_function)(void)); 30extern pid_t eat_cpu(int (test_function)(void));
31extern bool require_paranoia_below(int level); 31extern bool require_paranoia_below(int level);
32extern void *get_auxv_entry(int type);
32 33
33struct addr_range { 34struct addr_range {
34 uint64_t first, last; 35 uint64_t first, last;
diff --git a/tools/testing/selftests/powerpc/pmu/per_event_excludes.c b/tools/testing/selftests/powerpc/pmu/per_event_excludes.c
new file mode 100644
index 000000000000..fddbbc9cae2f
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/per_event_excludes.c
@@ -0,0 +1,114 @@
1/*
2 * Copyright 2014, Michael Ellerman, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#define _GNU_SOURCE
7
8#include <elf.h>
9#include <limits.h>
10#include <stdio.h>
11#include <stdbool.h>
12#include <string.h>
13#include <sys/prctl.h>
14
15#include "event.h"
16#include "lib.h"
17#include "utils.h"
18
19/*
20 * Test that per-event excludes work.
21 */
22
23static int per_event_excludes(void)
24{
25 struct event *e, events[4];
26 char *platform;
27 int i;
28
29 platform = (char *)get_auxv_entry(AT_BASE_PLATFORM);
30 FAIL_IF(!platform);
31 SKIP_IF(strcmp(platform, "power8") != 0);
32
33 /*
34 * We need to create the events disabled, otherwise the running/enabled
35 * counts don't match up.
36 */
37 e = &events[0];
38 event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
39 PERF_TYPE_HARDWARE, "instructions");
40 e->attr.disabled = 1;
41
42 e = &events[1];
43 event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
44 PERF_TYPE_HARDWARE, "instructions(k)");
45 e->attr.disabled = 1;
46 e->attr.exclude_user = 1;
47 e->attr.exclude_hv = 1;
48
49 e = &events[2];
50 event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
51 PERF_TYPE_HARDWARE, "instructions(h)");
52 e->attr.disabled = 1;
53 e->attr.exclude_user = 1;
54 e->attr.exclude_kernel = 1;
55
56 e = &events[3];
57 event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
58 PERF_TYPE_HARDWARE, "instructions(u)");
59 e->attr.disabled = 1;
60 e->attr.exclude_hv = 1;
61 e->attr.exclude_kernel = 1;
62
63 FAIL_IF(event_open(&events[0]));
64
65 /*
66 * The open here will fail if we don't have per event exclude support,
67 * because the second event has an incompatible set of exclude settings
68 * and we're asking for the events to be in a group.
69 */
70 for (i = 1; i < 4; i++)
71 FAIL_IF(event_open_with_group(&events[i], events[0].fd));
72
73 /*
74 * Even though the above will fail without per-event excludes we keep
75 * testing in order to be thorough.
76 */
77 prctl(PR_TASK_PERF_EVENTS_ENABLE);
78
79 /* Spin for a while */
80 for (i = 0; i < INT_MAX; i++)
81 asm volatile("" : : : "memory");
82
83 prctl(PR_TASK_PERF_EVENTS_DISABLE);
84
85 for (i = 0; i < 4; i++) {
86 FAIL_IF(event_read(&events[i]));
87 event_report(&events[i]);
88 }
89
90 /*
91 * We should see that all events have enabled == running. That
92 * shows that they were all on the PMU at once.
93 */
94 for (i = 0; i < 4; i++)
95 FAIL_IF(events[i].result.running != events[i].result.enabled);
96
97 /*
98 * We can also check that the result for instructions is >= all the
99 * other counts. That's because it is counting all instructions while
100 * the others are counting a subset.
101 */
102 for (i = 1; i < 4; i++)
103 FAIL_IF(events[0].result.value < events[i].result.value);
104
105 for (i = 0; i < 4; i++)
106 event_close(&events[i]);
107
108 return 0;
109}
110
111int main(void)
112{
113 return test_harness(per_event_excludes, "per_event_excludes");
114}
diff --git a/tools/testing/selftests/ptrace/peeksiginfo.c b/tools/testing/selftests/ptrace/peeksiginfo.c
index d46558b1f58d..c34cd8ac8aaa 100644
--- a/tools/testing/selftests/ptrace/peeksiginfo.c
+++ b/tools/testing/selftests/ptrace/peeksiginfo.c
@@ -31,6 +31,10 @@ static int sys_ptrace(int request, pid_t pid, void *addr, void *data)
31#define TEST_SICODE_PRIV -1 31#define TEST_SICODE_PRIV -1
32#define TEST_SICODE_SHARE -2 32#define TEST_SICODE_SHARE -2
33 33
34#ifndef PAGE_SIZE
35#define PAGE_SIZE sysconf(_SC_PAGESIZE)
36#endif
37
34#define err(fmt, ...) \ 38#define err(fmt, ...) \
35 fprintf(stderr, \ 39 fprintf(stderr, \
36 "Error (%s:%d): " fmt, \ 40 "Error (%s:%d): " fmt, \
diff --git a/tools/time/udelay_test.sh b/tools/time/udelay_test.sh
new file mode 100755
index 000000000000..12d46b926917
--- /dev/null
+++ b/tools/time/udelay_test.sh
@@ -0,0 +1,66 @@
1#!/bin/bash
2
3# udelay() test script
4#
5# Test is executed by writing and reading to /sys/kernel/debug/udelay_test
6# and exercises a variety of delays to ensure that udelay() is delaying
7# at least as long as requested (as compared to ktime).
8#
9# Copyright (C) 2014 Google, Inc.
10#
11# This software is licensed under the terms of the GNU General Public
12# License version 2, as published by the Free Software Foundation, and
13# may be copied, distributed, and modified under those terms.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19
20MODULE_NAME=udelay_test
21UDELAY_PATH=/sys/kernel/debug/udelay_test
22
23setup()
24{
25 /sbin/modprobe -q $MODULE_NAME
26 tmp_file=`mktemp`
27}
28
29test_one()
30{
31 delay=$1
32 echo $delay > $UDELAY_PATH
33 tee -a $tmp_file < $UDELAY_PATH
34}
35
36cleanup()
37{
38 if [ -f $tmp_file ]; then
39 rm $tmp_file
40 fi
41 /sbin/modprobe -q -r $MODULE_NAME
42}
43
44trap cleanup EXIT
45setup
46
47# Delay for a variety of times.
48# 1..200, 200..500 (by 10), 500..2000 (by 100)
49for (( delay = 1; delay < 200; delay += 1 )); do
50 test_one $delay
51done
52for (( delay = 200; delay < 500; delay += 10 )); do
53 test_one $delay
54done
55for (( delay = 500; delay <= 2000; delay += 100 )); do
56 test_one $delay
57done
58
59# Search for failures
60count=`grep -c FAIL $tmp_file`
61if [ $? -eq "0" ]; then
62 echo "ERROR: $count delays failed to delay long enough"
63 retcode=1
64fi
65
66exit $retcode
diff --git a/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c b/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c
index 87216a0c4a8b..af4b0508be77 100644
--- a/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c
+++ b/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c
@@ -1,3 +1,30 @@
1/*
2 * This is free and unencumbered software released into the public domain.
3 *
4 * Anyone is free to copy, modify, publish, use, compile, sell, or
5 * distribute this software, either in source code form or as a compiled
6 * binary, for any purpose, commercial or non-commercial, and by any
7 * means.
8 *
9 * In jurisdictions that recognize copyright laws, the author or authors
10 * of this software dedicate any and all copyright interest in the
11 * software to the public domain. We make this dedication for the benefit
12 * of the public at large and to the detriment of our heirs and
13 * successors. We intend this dedication to be an overt act of
14 * relinquishment in perpetuity of all present and future rights to this
15 * software under copyright law.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * For more information, please refer to <http://unlicense.org/>
26 */
27
1#define _BSD_SOURCE /* for endian.h */ 28#define _BSD_SOURCE /* for endian.h */
2 29
3#include <endian.h> 30#include <endian.h>
@@ -27,7 +54,9 @@
27/******************** Descriptors and Strings *******************************/ 54/******************** Descriptors and Strings *******************************/
28 55
29static const struct { 56static const struct {
30 struct usb_functionfs_descs_head header; 57 struct usb_functionfs_descs_head_v2 header;
58 __le32 fs_count;
59 __le32 hs_count;
31 struct { 60 struct {
32 struct usb_interface_descriptor intf; 61 struct usb_interface_descriptor intf;
33 struct usb_endpoint_descriptor_no_audio bulk_sink; 62 struct usb_endpoint_descriptor_no_audio bulk_sink;
@@ -35,11 +64,12 @@ static const struct {
35 } __attribute__ ((__packed__)) fs_descs, hs_descs; 64 } __attribute__ ((__packed__)) fs_descs, hs_descs;
36} __attribute__ ((__packed__)) descriptors = { 65} __attribute__ ((__packed__)) descriptors = {
37 .header = { 66 .header = {
38 .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC), 67 .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2),
68 .flags = htole32(FUNCTIONFS_HAS_FS_DESC |
69 FUNCTIONFS_HAS_HS_DESC),
39 .length = htole32(sizeof(descriptors)), 70 .length = htole32(sizeof(descriptors)),
40 .fs_count = 3,
41 .hs_count = 3,
42 }, 71 },
72 .fs_count = htole32(3),
43 .fs_descs = { 73 .fs_descs = {
44 .intf = { 74 .intf = {
45 .bLength = sizeof(descriptors.fs_descs.intf), 75 .bLength = sizeof(descriptors.fs_descs.intf),
@@ -61,6 +91,7 @@ static const struct {
61 .bmAttributes = USB_ENDPOINT_XFER_BULK, 91 .bmAttributes = USB_ENDPOINT_XFER_BULK,
62 }, 92 },
63 }, 93 },
94 .hs_count = htole32(3),
64 .hs_descs = { 95 .hs_descs = {
65 .intf = { 96 .intf = {
66 .bLength = sizeof(descriptors.hs_descs.intf), 97 .bLength = sizeof(descriptors.hs_descs.intf),
diff --git a/tools/usb/ffs-aio-example/multibuff/host_app/test.c b/tools/usb/ffs-aio-example/multibuff/host_app/test.c
index b0ad8747d03f..daa3abe6bebd 100644
--- a/tools/usb/ffs-aio-example/multibuff/host_app/test.c
+++ b/tools/usb/ffs-aio-example/multibuff/host_app/test.c
@@ -1,3 +1,30 @@
1/*
2 * This is free and unencumbered software released into the public domain.
3 *
4 * Anyone is free to copy, modify, publish, use, compile, sell, or
5 * distribute this software, either in source code form or as a compiled
6 * binary, for any purpose, commercial or non-commercial, and by any
7 * means.
8 *
9 * In jurisdictions that recognize copyright laws, the author or authors
10 * of this software dedicate any and all copyright interest in the
11 * software to the public domain. We make this dedication for the benefit
12 * of the public at large and to the detriment of our heirs and
13 * successors. We intend this dedication to be an overt act of
14 * relinquishment in perpetuity of all present and future rights to this
15 * software under copyright law.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * For more information, please refer to <http://unlicense.org/>
26 */
27
1#include <libusb.h> 28#include <libusb.h>
2#include <stdio.h> 29#include <stdio.h>
3#include <string.h> 30#include <string.h>
diff --git a/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c b/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c
index f558664a3317..adc310a6d489 100644
--- a/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c
+++ b/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c
@@ -1,3 +1,30 @@
1/*
2 * This is free and unencumbered software released into the public domain.
3 *
4 * Anyone is free to copy, modify, publish, use, compile, sell, or
5 * distribute this software, either in source code form or as a compiled
6 * binary, for any purpose, commercial or non-commercial, and by any
7 * means.
8 *
9 * In jurisdictions that recognize copyright laws, the author or authors
10 * of this software dedicate any and all copyright interest in the
11 * software to the public domain. We make this dedication for the benefit
12 * of the public at large and to the detriment of our heirs and
13 * successors. We intend this dedication to be an overt act of
14 * relinquishment in perpetuity of all present and future rights to this
15 * software under copyright law.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * For more information, please refer to <http://unlicense.org/>
26 */
27
1#define _BSD_SOURCE /* for endian.h */ 28#define _BSD_SOURCE /* for endian.h */
2 29
3#include <endian.h> 30#include <endian.h>
@@ -25,7 +52,9 @@
25/******************** Descriptors and Strings *******************************/ 52/******************** Descriptors and Strings *******************************/
26 53
27static const struct { 54static const struct {
28 struct usb_functionfs_descs_head header; 55 struct usb_functionfs_descs_head_v2 header;
56 __le32 fs_count;
57 __le32 hs_count;
29 struct { 58 struct {
30 struct usb_interface_descriptor intf; 59 struct usb_interface_descriptor intf;
31 struct usb_endpoint_descriptor_no_audio bulk_sink; 60 struct usb_endpoint_descriptor_no_audio bulk_sink;
@@ -33,11 +62,12 @@ static const struct {
33 } __attribute__ ((__packed__)) fs_descs, hs_descs; 62 } __attribute__ ((__packed__)) fs_descs, hs_descs;
34} __attribute__ ((__packed__)) descriptors = { 63} __attribute__ ((__packed__)) descriptors = {
35 .header = { 64 .header = {
36 .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC), 65 .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2),
66 .flags = htole32(FUNCTIONFS_HAS_FS_DESC |
67 FUNCTIONFS_HAS_HS_DESC),
37 .length = htole32(sizeof(descriptors)), 68 .length = htole32(sizeof(descriptors)),
38 .fs_count = 3,
39 .hs_count = 3,
40 }, 69 },
70 .fs_count = htole32(3),
41 .fs_descs = { 71 .fs_descs = {
42 .intf = { 72 .intf = {
43 .bLength = sizeof(descriptors.fs_descs.intf), 73 .bLength = sizeof(descriptors.fs_descs.intf),
@@ -59,6 +89,7 @@ static const struct {
59 .bmAttributes = USB_ENDPOINT_XFER_BULK, 89 .bmAttributes = USB_ENDPOINT_XFER_BULK,
60 }, 90 },
61 }, 91 },
92 .hs_count = htole32(3),
62 .hs_descs = { 93 .hs_descs = {
63 .intf = { 94 .intf = {
64 .bLength = sizeof(descriptors.hs_descs.intf), 95 .bLength = sizeof(descriptors.hs_descs.intf),
diff --git a/tools/usb/ffs-aio-example/simple/host_app/test.c b/tools/usb/ffs-aio-example/simple/host_app/test.c
index 64b6a57d8ca3..acd6332811f3 100644
--- a/tools/usb/ffs-aio-example/simple/host_app/test.c
+++ b/tools/usb/ffs-aio-example/simple/host_app/test.c
@@ -1,3 +1,30 @@
1/*
2 * This is free and unencumbered software released into the public domain.
3 *
4 * Anyone is free to copy, modify, publish, use, compile, sell, or
5 * distribute this software, either in source code form or as a compiled
6 * binary, for any purpose, commercial or non-commercial, and by any
7 * means.
8 *
9 * In jurisdictions that recognize copyright laws, the author or authors
10 * of this software dedicate any and all copyright interest in the
11 * software to the public domain. We make this dedication for the benefit
12 * of the public at large and to the detriment of our heirs and
13 * successors. We intend this dedication to be an overt act of
14 * relinquishment in perpetuity of all present and future rights to this
15 * software under copyright law.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * For more information, please refer to <http://unlicense.org/>
26 */
27
1#include <libusb.h> 28#include <libusb.h>
2#include <stdio.h> 29#include <stdio.h>
3#include <string.h> 30#include <string.h>