/* * Copyright (C) 2016 Google, Inc. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Original Code by Pavel Labath * * Code modified by Pratyush Anand * for testing different byte select for each access size. * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../kselftest.h" static volatile uint8_t var[96] __attribute__((__aligned__(32))); static void child(int size, int wr) { volatile uint8_t *addr = &var[32 + wr]; if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) != 0) { perror("ptrace(PTRACE_TRACEME) failed"); _exit(1); } if (raise(SIGSTOP) != 0) { perror("raise(SIGSTOP) failed"); _exit(1); } if ((uintptr_t) addr % size) { perror("Wrong address write for the given size\n"); _exit(1); } switch (size) { case 1: *addr = 47; break; case 2: *(uint16_t *)addr = 47; break; case 4: *(uint32_t *)addr = 47; break; case 8: *(uint64_t *)addr = 47; break; case 16: __asm__ volatile ("stp x29, x30, %0" : "=m" (addr[0])); break; case 32: __asm__ volatile ("stp q29, q30, %0" : "=m" (addr[0])); break; } _exit(0); } static bool set_watchpoint(pid_t pid, int size, int wp) { const volatile uint8_t *addr = &var[32 + wp]; const int offset = (uintptr_t)addr % 8; const unsigned int byte_mask = ((1 << size) - 1) << offset; const unsigned int type = 2; /* Write */ const unsigned int enable = 1; const unsigned int control = byte_mask << 5 | type << 3 | enable; struct user_hwdebug_state dreg_state; struct iovec iov; memset(&dreg_state, 0, sizeof(dreg_state)); dreg_state.dbg_regs[0].addr = (uintptr_t)(addr - offset); dreg_state.dbg_regs[0].ctrl = control; iov.iov_base = &dreg_state; iov.iov_len = offsetof(struct user_hwdebug_state, dbg_regs) + sizeof(dreg_state.dbg_regs[0]); if (ptrace(PTRACE_SETREGSET, pid, NT_ARM_HW_WATCH, &iov) == 0) return true; if (errno == EIO) { printf("ptrace(PTRACE_SETREGSET, NT_ARM_HW_WATCH) " "not supported on this hardware\n"); ksft_exit_skip(); } perror("ptrace(PTRACE_SETREGSET, NT_ARM_HW_WATCH) failed"); return false; } static bool run_test(int wr_size, int wp_size, int wr, int wp) { int status; siginfo_t siginfo; pid_t pid = fork(); pid_t wpid; if (pid < 0) { perror("fork() failed"); return false; } if (pid == 0) child(wr_size, wr); wpid = waitpid(pid, &status, __WALL); if (wpid != pid) { perror("waitpid() failed"); return false; } if (!WIFSTOPPED(status)) { printf("child did not stop\n"); return false; } if (WSTOPSIG(status) != SIGSTOP) { printf("child did not stop with SIGSTOP\n"); return false; } if (!set_watchpoint(pid, wp_size, wp)) return false; if (ptrace(PTRACE_CONT, pid, NULL, NULL) < 0) { perror("ptrace(PTRACE_SINGLESTEP) failed"); return false; } alarm(3); wpid = waitpid(pid, &status, __WALL); if (wpid != pid) { perror("waitpid() failed"); return false; } alarm(0); if (WIFEXITED(status)) { printf("child did not single-step\t"); return false; } if (!WIFSTOPPED(status)) { printf("child did not stop\n"); return false; } if (WSTOPSIG(status) != SIGTRAP) { printf("child did not stop with SIGTRAP\n"); return false; } if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo) != 0) { perror("ptrace(PTRACE_GETSIGINFO)"); return false; } if (siginfo.si_code != TRAP_HWBKPT) { printf("Unexpected si_code %d\n", siginfo.si_code); return false; } kill(pid, SIGKILL); wpid = waitpid(pid, &status, 0); if (wpid != pid) { perror("waitpid() failed"); return false; } return true; } static void sigalrm(int sig) { } int main(int argc, char **argv) { int opt; bool succeeded = true; struct sigaction act; int wr, wp, size; bool result; act.sa_handler = sigalrm; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGALRM, &act, NULL); for (size = 1; size <= 32; size = size*2) { for (wr = 0; wr <= 32; wr = wr + size) { for (wp = wr - size; wp <= wr + size; wp = wp + size) { printf("Test size = %d write offset = %d watchpoint offset = %d\t", size, wr, wp); result = run_test(size, MIN(size, 8), wr, wp); if ((result && wr == wp) || (!result && wr != wp)) { printf("[OK]\n"); ksft_inc_pass_cnt(); } else { printf("[FAILED]\n"); ksft_inc_fail_cnt(); succeeded = false; } } } } for (size = 1; size <= 32; size = size*2) { printf("Test size = %d write offset = %d watchpoint offset = -8\t", size, -size); if (run_test(size, 8, -size, -8)) { printf("[OK]\n"); ksft_inc_pass_cnt(); } else { printf("[FAILED]\n"); ksft_inc_fail_cnt(); succeeded = false; } } ksft_print_cnts(); if (succeeded) ksft_exit_pass(); else ksft_exit_fail(); } 573b8d2e28e5b3291f09c5 (patch) tree364c81aaa0645ddfb817e4676744dea5b1b34255 /sound/pci/intel8x0m.c parentb84f02795e3bcf197ae13a7e3ac6cc9d66d2feaa (diff)parent0e0694ff1a7791274946b7f51bae692da0001a08 (diff)
Merge tag 'media/v4.10-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media fixes from Mauro Carvalho Chehab: - fix a regression on tvp5150 causing failures at input selection and image glitches - CEC was moved out of staging for v4.10. Fix some bugs on it while not too late - fix a regression on pctv452e caused by VM stack changes - fix suspend issued with smiapp - fix a regression on cobalt driver - fix some warnings and Kconfig issues with some random configs. * tag 'media/v4.10-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: [media] s5k4ecgx: select CRC32 helper [media] dvb: avoid warning in dvb_net [media] v4l: tvp5150: Don't override output pinmuxing at stream on/off time [media] v4l: tvp5150: Fix comment regarding output pin muxing [media] v4l: tvp5150: Reset device at probe time, not in get/set format handlers [media] pctv452e: move buffer to heap, no mutex [media] media/cobalt: use pci_irq_allocate_vectors [media] cec: fix race between configuring and unconfiguring [media] cec: move cec_report_phys_addr into cec_config_thread_func [media] cec: replace cec_report_features by cec_fill_msg_report_features [media] cec: update log_addr[] before finishing configuration [media] cec: CEC_MSG_GIVE_FEATURES should abort for CEC version < 2 [media] cec: when canceling a message, don't overwrite old status info [media] cec: fix report_current_latency [media] smiapp: Make suspend and resume functions __maybe_unused [media] smiapp: Implement power-on and power-off sequences without runtime PM
Diffstat (limited to 'sound/pci/intel8x0m.c')