diff options
Diffstat (limited to 'kernel/trace/trace_kprobe.c')
-rw-r--r-- | kernel/trace/trace_kprobe.c | 196 |
1 files changed, 73 insertions, 123 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 465b36bef4ca..505c92273b1a 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -91,11 +91,6 @@ static __kprobes unsigned long fetch_memory(struct pt_regs *regs, void *addr) | |||
91 | return retval; | 91 | return retval; |
92 | } | 92 | } |
93 | 93 | ||
94 | static __kprobes unsigned long fetch_argument(struct pt_regs *regs, void *num) | ||
95 | { | ||
96 | return regs_get_argument_nth(regs, (unsigned int)((unsigned long)num)); | ||
97 | } | ||
98 | |||
99 | static __kprobes unsigned long fetch_retvalue(struct pt_regs *regs, | 94 | static __kprobes unsigned long fetch_retvalue(struct pt_regs *regs, |
100 | void *dummy) | 95 | void *dummy) |
101 | { | 96 | { |
@@ -231,9 +226,7 @@ static int probe_arg_string(char *buf, size_t n, struct fetch_func *ff) | |||
231 | { | 226 | { |
232 | int ret = -EINVAL; | 227 | int ret = -EINVAL; |
233 | 228 | ||
234 | if (ff->func == fetch_argument) | 229 | if (ff->func == fetch_register) { |
235 | ret = snprintf(buf, n, "$arg%lu", (unsigned long)ff->data); | ||
236 | else if (ff->func == fetch_register) { | ||
237 | const char *name; | 230 | const char *name; |
238 | name = regs_query_register_name((unsigned int)((long)ff->data)); | 231 | name = regs_query_register_name((unsigned int)((long)ff->data)); |
239 | ret = snprintf(buf, n, "%%%s", name); | 232 | ret = snprintf(buf, n, "%%%s", name); |
@@ -489,14 +482,6 @@ static int parse_probe_vars(char *arg, struct fetch_func *ff, int is_return) | |||
489 | } | 482 | } |
490 | } else | 483 | } else |
491 | ret = -EINVAL; | 484 | ret = -EINVAL; |
492 | } else if (strncmp(arg, "arg", 3) == 0 && isdigit(arg[3])) { | ||
493 | ret = strict_strtoul(arg + 3, 10, ¶m); | ||
494 | if (ret || param > PARAM_MAX_ARGS) | ||
495 | ret = -EINVAL; | ||
496 | else { | ||
497 | ff->func = fetch_argument; | ||
498 | ff->data = (void *)param; | ||
499 | } | ||
500 | } else | 485 | } else |
501 | ret = -EINVAL; | 486 | ret = -EINVAL; |
502 | return ret; | 487 | return ret; |
@@ -611,7 +596,6 @@ static int create_trace_probe(int argc, char **argv) | |||
611 | * - Add kprobe: p[:[GRP/]EVENT] KSYM[+OFFS]|KADDR [FETCHARGS] | 596 | * - Add kprobe: p[:[GRP/]EVENT] KSYM[+OFFS]|KADDR [FETCHARGS] |
612 | * - Add kretprobe: r[:[GRP/]EVENT] KSYM[+0] [FETCHARGS] | 597 | * - Add kretprobe: r[:[GRP/]EVENT] KSYM[+0] [FETCHARGS] |
613 | * Fetch args: | 598 | * Fetch args: |
614 | * $argN : fetch Nth of function argument. (N:0-) | ||
615 | * $retval : fetch return value | 599 | * $retval : fetch return value |
616 | * $stack : fetch stack address | 600 | * $stack : fetch stack address |
617 | * $stackN : fetch Nth of stack (N:0-) | 601 | * $stackN : fetch Nth of stack (N:0-) |
@@ -958,7 +942,7 @@ static const struct file_operations kprobe_profile_ops = { | |||
958 | }; | 942 | }; |
959 | 943 | ||
960 | /* Kprobe handler */ | 944 | /* Kprobe handler */ |
961 | static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) | 945 | static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) |
962 | { | 946 | { |
963 | struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp); | 947 | struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp); |
964 | struct kprobe_trace_entry *entry; | 948 | struct kprobe_trace_entry *entry; |
@@ -978,7 +962,7 @@ static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) | |||
978 | event = trace_current_buffer_lock_reserve(&buffer, call->id, size, | 962 | event = trace_current_buffer_lock_reserve(&buffer, call->id, size, |
979 | irq_flags, pc); | 963 | irq_flags, pc); |
980 | if (!event) | 964 | if (!event) |
981 | return 0; | 965 | return; |
982 | 966 | ||
983 | entry = ring_buffer_event_data(event); | 967 | entry = ring_buffer_event_data(event); |
984 | entry->nargs = tp->nr_args; | 968 | entry->nargs = tp->nr_args; |
@@ -988,11 +972,10 @@ static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) | |||
988 | 972 | ||
989 | if (!filter_current_check_discard(buffer, call, entry, event)) | 973 | if (!filter_current_check_discard(buffer, call, entry, event)) |
990 | trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); | 974 | trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); |
991 | return 0; | ||
992 | } | 975 | } |
993 | 976 | ||
994 | /* Kretprobe handler */ | 977 | /* Kretprobe handler */ |
995 | static __kprobes int kretprobe_trace_func(struct kretprobe_instance *ri, | 978 | static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri, |
996 | struct pt_regs *regs) | 979 | struct pt_regs *regs) |
997 | { | 980 | { |
998 | struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp); | 981 | struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp); |
@@ -1011,7 +994,7 @@ static __kprobes int kretprobe_trace_func(struct kretprobe_instance *ri, | |||
1011 | event = trace_current_buffer_lock_reserve(&buffer, call->id, size, | 994 | event = trace_current_buffer_lock_reserve(&buffer, call->id, size, |
1012 | irq_flags, pc); | 995 | irq_flags, pc); |
1013 | if (!event) | 996 | if (!event) |
1014 | return 0; | 997 | return; |
1015 | 998 | ||
1016 | entry = ring_buffer_event_data(event); | 999 | entry = ring_buffer_event_data(event); |
1017 | entry->nargs = tp->nr_args; | 1000 | entry->nargs = tp->nr_args; |
@@ -1022,8 +1005,6 @@ static __kprobes int kretprobe_trace_func(struct kretprobe_instance *ri, | |||
1022 | 1005 | ||
1023 | if (!filter_current_check_discard(buffer, call, entry, event)) | 1006 | if (!filter_current_check_discard(buffer, call, entry, event)) |
1024 | trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); | 1007 | trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); |
1025 | |||
1026 | return 0; | ||
1027 | } | 1008 | } |
1028 | 1009 | ||
1029 | /* Event entry printers */ | 1010 | /* Event entry printers */ |
@@ -1230,137 +1211,67 @@ static int set_print_fmt(struct trace_probe *tp) | |||
1230 | return 0; | 1211 | return 0; |
1231 | } | 1212 | } |
1232 | 1213 | ||
1233 | #ifdef CONFIG_EVENT_PROFILE | 1214 | #ifdef CONFIG_PERF_EVENTS |
1234 | 1215 | ||
1235 | /* Kprobe profile handler */ | 1216 | /* Kprobe profile handler */ |
1236 | static __kprobes int kprobe_profile_func(struct kprobe *kp, | 1217 | static __kprobes void kprobe_profile_func(struct kprobe *kp, |
1237 | struct pt_regs *regs) | 1218 | struct pt_regs *regs) |
1238 | { | 1219 | { |
1239 | struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp); | 1220 | struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp); |
1240 | struct ftrace_event_call *call = &tp->call; | 1221 | struct ftrace_event_call *call = &tp->call; |
1241 | struct kprobe_trace_entry *entry; | 1222 | struct kprobe_trace_entry *entry; |
1242 | struct trace_entry *ent; | 1223 | int size, __size, i; |
1243 | int size, __size, i, pc, __cpu; | ||
1244 | unsigned long irq_flags; | 1224 | unsigned long irq_flags; |
1245 | char *trace_buf; | ||
1246 | char *raw_data; | ||
1247 | int rctx; | 1225 | int rctx; |
1248 | 1226 | ||
1249 | pc = preempt_count(); | ||
1250 | __size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args); | 1227 | __size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args); |
1251 | size = ALIGN(__size + sizeof(u32), sizeof(u64)); | 1228 | size = ALIGN(__size + sizeof(u32), sizeof(u64)); |
1252 | size -= sizeof(u32); | 1229 | size -= sizeof(u32); |
1253 | if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE, | 1230 | if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE, |
1254 | "profile buffer not large enough")) | 1231 | "profile buffer not large enough")) |
1255 | return 0; | 1232 | return; |
1256 | |||
1257 | /* | ||
1258 | * Protect the non nmi buffer | ||
1259 | * This also protects the rcu read side | ||
1260 | */ | ||
1261 | local_irq_save(irq_flags); | ||
1262 | 1233 | ||
1263 | rctx = perf_swevent_get_recursion_context(); | 1234 | entry = ftrace_perf_buf_prepare(size, call->id, &rctx, &irq_flags); |
1264 | if (rctx < 0) | 1235 | if (!entry) |
1265 | goto end_recursion; | 1236 | return; |
1266 | |||
1267 | __cpu = smp_processor_id(); | ||
1268 | |||
1269 | if (in_nmi()) | ||
1270 | trace_buf = rcu_dereference(perf_trace_buf_nmi); | ||
1271 | else | ||
1272 | trace_buf = rcu_dereference(perf_trace_buf); | ||
1273 | |||
1274 | if (!trace_buf) | ||
1275 | goto end; | ||
1276 | |||
1277 | raw_data = per_cpu_ptr(trace_buf, __cpu); | ||
1278 | |||
1279 | /* Zero dead bytes from alignment to avoid buffer leak to userspace */ | ||
1280 | *(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL; | ||
1281 | entry = (struct kprobe_trace_entry *)raw_data; | ||
1282 | ent = &entry->ent; | ||
1283 | 1237 | ||
1284 | tracing_generic_entry_update(ent, irq_flags, pc); | ||
1285 | ent->type = call->id; | ||
1286 | entry->nargs = tp->nr_args; | 1238 | entry->nargs = tp->nr_args; |
1287 | entry->ip = (unsigned long)kp->addr; | 1239 | entry->ip = (unsigned long)kp->addr; |
1288 | for (i = 0; i < tp->nr_args; i++) | 1240 | for (i = 0; i < tp->nr_args; i++) |
1289 | entry->args[i] = call_fetch(&tp->args[i].fetch, regs); | 1241 | entry->args[i] = call_fetch(&tp->args[i].fetch, regs); |
1290 | perf_tp_event(call->id, entry->ip, 1, entry, size); | ||
1291 | 1242 | ||
1292 | end: | 1243 | ftrace_perf_buf_submit(entry, size, rctx, entry->ip, 1, irq_flags); |
1293 | perf_swevent_put_recursion_context(rctx); | ||
1294 | end_recursion: | ||
1295 | local_irq_restore(irq_flags); | ||
1296 | |||
1297 | return 0; | ||
1298 | } | 1244 | } |
1299 | 1245 | ||
1300 | /* Kretprobe profile handler */ | 1246 | /* Kretprobe profile handler */ |
1301 | static __kprobes int kretprobe_profile_func(struct kretprobe_instance *ri, | 1247 | static __kprobes void kretprobe_profile_func(struct kretprobe_instance *ri, |
1302 | struct pt_regs *regs) | 1248 | struct pt_regs *regs) |
1303 | { | 1249 | { |
1304 | struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp); | 1250 | struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp); |
1305 | struct ftrace_event_call *call = &tp->call; | 1251 | struct ftrace_event_call *call = &tp->call; |
1306 | struct kretprobe_trace_entry *entry; | 1252 | struct kretprobe_trace_entry *entry; |
1307 | struct trace_entry *ent; | 1253 | int size, __size, i; |
1308 | int size, __size, i, pc, __cpu; | ||
1309 | unsigned long irq_flags; | 1254 | unsigned long irq_flags; |
1310 | char *trace_buf; | ||
1311 | char *raw_data; | ||
1312 | int rctx; | 1255 | int rctx; |
1313 | 1256 | ||
1314 | pc = preempt_count(); | ||
1315 | __size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args); | 1257 | __size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args); |
1316 | size = ALIGN(__size + sizeof(u32), sizeof(u64)); | 1258 | size = ALIGN(__size + sizeof(u32), sizeof(u64)); |
1317 | size -= sizeof(u32); | 1259 | size -= sizeof(u32); |
1318 | if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE, | 1260 | if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE, |
1319 | "profile buffer not large enough")) | 1261 | "profile buffer not large enough")) |
1320 | return 0; | 1262 | return; |
1321 | |||
1322 | /* | ||
1323 | * Protect the non nmi buffer | ||
1324 | * This also protects the rcu read side | ||
1325 | */ | ||
1326 | local_irq_save(irq_flags); | ||
1327 | |||
1328 | rctx = perf_swevent_get_recursion_context(); | ||
1329 | if (rctx < 0) | ||
1330 | goto end_recursion; | ||
1331 | |||
1332 | __cpu = smp_processor_id(); | ||
1333 | |||
1334 | if (in_nmi()) | ||
1335 | trace_buf = rcu_dereference(perf_trace_buf_nmi); | ||
1336 | else | ||
1337 | trace_buf = rcu_dereference(perf_trace_buf); | ||
1338 | |||
1339 | if (!trace_buf) | ||
1340 | goto end; | ||
1341 | |||
1342 | raw_data = per_cpu_ptr(trace_buf, __cpu); | ||
1343 | 1263 | ||
1344 | /* Zero dead bytes from alignment to avoid buffer leak to userspace */ | 1264 | entry = ftrace_perf_buf_prepare(size, call->id, &rctx, &irq_flags); |
1345 | *(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL; | 1265 | if (!entry) |
1346 | entry = (struct kretprobe_trace_entry *)raw_data; | 1266 | return; |
1347 | ent = &entry->ent; | ||
1348 | 1267 | ||
1349 | tracing_generic_entry_update(ent, irq_flags, pc); | ||
1350 | ent->type = call->id; | ||
1351 | entry->nargs = tp->nr_args; | 1268 | entry->nargs = tp->nr_args; |
1352 | entry->func = (unsigned long)tp->rp.kp.addr; | 1269 | entry->func = (unsigned long)tp->rp.kp.addr; |
1353 | entry->ret_ip = (unsigned long)ri->ret_addr; | 1270 | entry->ret_ip = (unsigned long)ri->ret_addr; |
1354 | for (i = 0; i < tp->nr_args; i++) | 1271 | for (i = 0; i < tp->nr_args; i++) |
1355 | entry->args[i] = call_fetch(&tp->args[i].fetch, regs); | 1272 | entry->args[i] = call_fetch(&tp->args[i].fetch, regs); |
1356 | perf_tp_event(call->id, entry->ret_ip, 1, entry, size); | ||
1357 | |||
1358 | end: | ||
1359 | perf_swevent_put_recursion_context(rctx); | ||
1360 | end_recursion: | ||
1361 | local_irq_restore(irq_flags); | ||
1362 | 1273 | ||
1363 | return 0; | 1274 | ftrace_perf_buf_submit(entry, size, rctx, entry->ret_ip, 1, irq_flags); |
1364 | } | 1275 | } |
1365 | 1276 | ||
1366 | static int probe_profile_enable(struct ftrace_event_call *call) | 1277 | static int probe_profile_enable(struct ftrace_event_call *call) |
@@ -1388,7 +1299,7 @@ static void probe_profile_disable(struct ftrace_event_call *call) | |||
1388 | disable_kprobe(&tp->rp.kp); | 1299 | disable_kprobe(&tp->rp.kp); |
1389 | } | 1300 | } |
1390 | } | 1301 | } |
1391 | #endif /* CONFIG_EVENT_PROFILE */ | 1302 | #endif /* CONFIG_PERF_EVENTS */ |
1392 | 1303 | ||
1393 | 1304 | ||
1394 | static __kprobes | 1305 | static __kprobes |
@@ -1398,10 +1309,10 @@ int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs) | |||
1398 | 1309 | ||
1399 | if (tp->flags & TP_FLAG_TRACE) | 1310 | if (tp->flags & TP_FLAG_TRACE) |
1400 | kprobe_trace_func(kp, regs); | 1311 | kprobe_trace_func(kp, regs); |
1401 | #ifdef CONFIG_EVENT_PROFILE | 1312 | #ifdef CONFIG_PERF_EVENTS |
1402 | if (tp->flags & TP_FLAG_PROFILE) | 1313 | if (tp->flags & TP_FLAG_PROFILE) |
1403 | kprobe_profile_func(kp, regs); | 1314 | kprobe_profile_func(kp, regs); |
1404 | #endif /* CONFIG_EVENT_PROFILE */ | 1315 | #endif |
1405 | return 0; /* We don't tweek kernel, so just return 0 */ | 1316 | return 0; /* We don't tweek kernel, so just return 0 */ |
1406 | } | 1317 | } |
1407 | 1318 | ||
@@ -1412,10 +1323,10 @@ int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs) | |||
1412 | 1323 | ||
1413 | if (tp->flags & TP_FLAG_TRACE) | 1324 | if (tp->flags & TP_FLAG_TRACE) |
1414 | kretprobe_trace_func(ri, regs); | 1325 | kretprobe_trace_func(ri, regs); |
1415 | #ifdef CONFIG_EVENT_PROFILE | 1326 | #ifdef CONFIG_PERF_EVENTS |
1416 | if (tp->flags & TP_FLAG_PROFILE) | 1327 | if (tp->flags & TP_FLAG_PROFILE) |
1417 | kretprobe_profile_func(ri, regs); | 1328 | kretprobe_profile_func(ri, regs); |
1418 | #endif /* CONFIG_EVENT_PROFILE */ | 1329 | #endif |
1419 | return 0; /* We don't tweek kernel, so just return 0 */ | 1330 | return 0; /* We don't tweek kernel, so just return 0 */ |
1420 | } | 1331 | } |
1421 | 1332 | ||
@@ -1446,7 +1357,7 @@ static int register_probe_event(struct trace_probe *tp) | |||
1446 | call->regfunc = probe_event_enable; | 1357 | call->regfunc = probe_event_enable; |
1447 | call->unregfunc = probe_event_disable; | 1358 | call->unregfunc = probe_event_disable; |
1448 | 1359 | ||
1449 | #ifdef CONFIG_EVENT_PROFILE | 1360 | #ifdef CONFIG_PERF_EVENTS |
1450 | call->profile_enable = probe_profile_enable; | 1361 | call->profile_enable = probe_profile_enable; |
1451 | call->profile_disable = probe_profile_disable; | 1362 | call->profile_disable = probe_profile_disable; |
1452 | #endif | 1363 | #endif |
@@ -1507,28 +1418,67 @@ static int kprobe_trace_selftest_target(int a1, int a2, int a3, | |||
1507 | 1418 | ||
1508 | static __init int kprobe_trace_self_tests_init(void) | 1419 | static __init int kprobe_trace_self_tests_init(void) |
1509 | { | 1420 | { |
1510 | int ret; | 1421 | int ret, warn = 0; |
1511 | int (*target)(int, int, int, int, int, int); | 1422 | int (*target)(int, int, int, int, int, int); |
1423 | struct trace_probe *tp; | ||
1512 | 1424 | ||
1513 | target = kprobe_trace_selftest_target; | 1425 | target = kprobe_trace_selftest_target; |
1514 | 1426 | ||
1515 | pr_info("Testing kprobe tracing: "); | 1427 | pr_info("Testing kprobe tracing: "); |
1516 | 1428 | ||
1517 | ret = command_trace_probe("p:testprobe kprobe_trace_selftest_target " | 1429 | ret = command_trace_probe("p:testprobe kprobe_trace_selftest_target " |
1518 | "$arg1 $arg2 $arg3 $arg4 $stack $stack0"); | 1430 | "$stack $stack0 +0($stack)"); |
1519 | if (WARN_ON_ONCE(ret)) | 1431 | if (WARN_ON_ONCE(ret)) { |
1520 | pr_warning("error enabling function entry\n"); | 1432 | pr_warning("error on probing function entry.\n"); |
1433 | warn++; | ||
1434 | } else { | ||
1435 | /* Enable trace point */ | ||
1436 | tp = find_probe_event("testprobe", KPROBE_EVENT_SYSTEM); | ||
1437 | if (WARN_ON_ONCE(tp == NULL)) { | ||
1438 | pr_warning("error on getting new probe.\n"); | ||
1439 | warn++; | ||
1440 | } else | ||
1441 | probe_event_enable(&tp->call); | ||
1442 | } | ||
1521 | 1443 | ||
1522 | ret = command_trace_probe("r:testprobe2 kprobe_trace_selftest_target " | 1444 | ret = command_trace_probe("r:testprobe2 kprobe_trace_selftest_target " |
1523 | "$retval"); | 1445 | "$retval"); |
1524 | if (WARN_ON_ONCE(ret)) | 1446 | if (WARN_ON_ONCE(ret)) { |
1525 | pr_warning("error enabling function return\n"); | 1447 | pr_warning("error on probing function return.\n"); |
1448 | warn++; | ||
1449 | } else { | ||
1450 | /* Enable trace point */ | ||
1451 | tp = find_probe_event("testprobe2", KPROBE_EVENT_SYSTEM); | ||
1452 | if (WARN_ON_ONCE(tp == NULL)) { | ||
1453 | pr_warning("error on getting new probe.\n"); | ||
1454 | warn++; | ||
1455 | } else | ||
1456 | probe_event_enable(&tp->call); | ||
1457 | } | ||
1458 | |||
1459 | if (warn) | ||
1460 | goto end; | ||
1526 | 1461 | ||
1527 | ret = target(1, 2, 3, 4, 5, 6); | 1462 | ret = target(1, 2, 3, 4, 5, 6); |
1528 | 1463 | ||
1529 | cleanup_all_probes(); | 1464 | ret = command_trace_probe("-:testprobe"); |
1465 | if (WARN_ON_ONCE(ret)) { | ||
1466 | pr_warning("error on deleting a probe.\n"); | ||
1467 | warn++; | ||
1468 | } | ||
1469 | |||
1470 | ret = command_trace_probe("-:testprobe2"); | ||
1471 | if (WARN_ON_ONCE(ret)) { | ||
1472 | pr_warning("error on deleting a probe.\n"); | ||
1473 | warn++; | ||
1474 | } | ||
1530 | 1475 | ||
1531 | pr_cont("OK\n"); | 1476 | end: |
1477 | cleanup_all_probes(); | ||
1478 | if (warn) | ||
1479 | pr_cont("NG: Some tests are failed. Please check them.\n"); | ||
1480 | else | ||
1481 | pr_cont("OK\n"); | ||
1532 | return 0; | 1482 | return 0; |
1533 | } | 1483 | } |
1534 | 1484 | ||