Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
The MSCC bug fix in 'net' had to be slightly adjusted because the register accesses are done slightly differently in net-next. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -19,7 +19,7 @@ void test_mmap(void)
|
||||
const size_t map_sz = roundup_page(sizeof(struct map_data));
|
||||
const int zero = 0, one = 1, two = 2, far = 1500;
|
||||
const long page_size = sysconf(_SC_PAGE_SIZE);
|
||||
int err, duration = 0, i, data_map_fd, data_map_id, tmp_fd;
|
||||
int err, duration = 0, i, data_map_fd, data_map_id, tmp_fd, rdmap_fd;
|
||||
struct bpf_map *data_map, *bss_map;
|
||||
void *bss_mmaped = NULL, *map_mmaped = NULL, *tmp1, *tmp2;
|
||||
struct test_mmap__bss *bss_data;
|
||||
@@ -37,6 +37,17 @@ void test_mmap(void)
|
||||
data_map = skel->maps.data_map;
|
||||
data_map_fd = bpf_map__fd(data_map);
|
||||
|
||||
rdmap_fd = bpf_map__fd(skel->maps.rdonly_map);
|
||||
tmp1 = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, rdmap_fd, 0);
|
||||
if (CHECK(tmp1 != MAP_FAILED, "rdonly_write_mmap", "unexpected success\n")) {
|
||||
munmap(tmp1, 4096);
|
||||
goto cleanup;
|
||||
}
|
||||
/* now double-check if it's mmap()'able at all */
|
||||
tmp1 = mmap(NULL, 4096, PROT_READ, MAP_SHARED, rdmap_fd, 0);
|
||||
if (CHECK(tmp1 == MAP_FAILED, "rdonly_read_mmap", "failed: %d\n", errno))
|
||||
goto cleanup;
|
||||
|
||||
/* get map's ID */
|
||||
memset(&map_info, 0, map_info_sz);
|
||||
err = bpf_obj_get_info_by_fd(data_map_fd, &map_info, &map_info_sz);
|
||||
|
@@ -7,6 +7,14 @@
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_ARRAY);
|
||||
__uint(max_entries, 4096);
|
||||
__uint(map_flags, BPF_F_MMAPABLE | BPF_F_RDONLY_PROG);
|
||||
__type(key, __u32);
|
||||
__type(value, char);
|
||||
} rdonly_map SEC(".maps");
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_ARRAY);
|
||||
__uint(max_entries, 512 * 4); /* at least 4 pages of data */
|
||||
|
@@ -300,7 +300,7 @@ test_uc_aware()
|
||||
local i
|
||||
|
||||
for ((i = 0; i < attempts; ++i)); do
|
||||
if $ARPING -c 1 -I $h1 -b 192.0.2.66 -q -w 0.1; then
|
||||
if $ARPING -c 1 -I $h1 -b 192.0.2.66 -q -w 1; then
|
||||
((passes++))
|
||||
fi
|
||||
|
||||
|
@@ -264,6 +264,8 @@ trap_policer_test()
|
||||
local packets_t0
|
||||
local packets_t1
|
||||
|
||||
RET=0
|
||||
|
||||
if [ $(devlink_trap_policers_num_get) -eq 0 ]; then
|
||||
check_err 1 "Failed to dump policers"
|
||||
fi
|
||||
@@ -328,6 +330,8 @@ trap_group_check_policer()
|
||||
|
||||
trap_policer_bind_test()
|
||||
{
|
||||
RET=0
|
||||
|
||||
devlink trap group set $DEVLINK_DEV group l2_drops policer 1
|
||||
check_err $? "Failed to bind a valid policer"
|
||||
if [ $(devlink_trap_group_policer_get "l2_drops") -ne 1 ]; then
|
||||
|
@@ -54,6 +54,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/vmx_dirty_log_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/xss_msr_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/debug_regs
|
||||
TEST_GEN_PROGS_x86_64 += clear_dirty_log_test
|
||||
TEST_GEN_PROGS_x86_64 += demand_paging_test
|
||||
TEST_GEN_PROGS_x86_64 += dirty_log_test
|
||||
|
@@ -143,6 +143,8 @@ struct kvm_run *vcpu_state(struct kvm_vm *vm, uint32_t vcpuid);
|
||||
void vcpu_run(struct kvm_vm *vm, uint32_t vcpuid);
|
||||
int _vcpu_run(struct kvm_vm *vm, uint32_t vcpuid);
|
||||
void vcpu_run_complete_io(struct kvm_vm *vm, uint32_t vcpuid);
|
||||
void vcpu_set_guest_debug(struct kvm_vm *vm, uint32_t vcpuid,
|
||||
struct kvm_guest_debug *debug);
|
||||
void vcpu_set_mp_state(struct kvm_vm *vm, uint32_t vcpuid,
|
||||
struct kvm_mp_state *mp_state);
|
||||
void vcpu_regs_get(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_regs *regs);
|
||||
|
@@ -1201,6 +1201,15 @@ void vcpu_run_complete_io(struct kvm_vm *vm, uint32_t vcpuid)
|
||||
ret, errno);
|
||||
}
|
||||
|
||||
void vcpu_set_guest_debug(struct kvm_vm *vm, uint32_t vcpuid,
|
||||
struct kvm_guest_debug *debug)
|
||||
{
|
||||
struct vcpu *vcpu = vcpu_find(vm, vcpuid);
|
||||
int ret = ioctl(vcpu->fd, KVM_SET_GUEST_DEBUG, debug);
|
||||
|
||||
TEST_ASSERT(ret == 0, "KVM_SET_GUEST_DEBUG failed: %d", ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* VM VCPU Set MP State
|
||||
*
|
||||
|
202
tools/testing/selftests/kvm/x86_64/debug_regs.c
Normal file
202
tools/testing/selftests/kvm/x86_64/debug_regs.c
Normal file
@@ -0,0 +1,202 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* KVM guest debug register tests
|
||||
*
|
||||
* Copyright (C) 2020, Red Hat, Inc.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "kvm_util.h"
|
||||
#include "processor.h"
|
||||
|
||||
#define VCPU_ID 0
|
||||
|
||||
#define DR6_BD (1 << 13)
|
||||
#define DR7_GD (1 << 13)
|
||||
|
||||
/* For testing data access debug BP */
|
||||
uint32_t guest_value;
|
||||
|
||||
extern unsigned char sw_bp, hw_bp, write_data, ss_start, bd_start;
|
||||
|
||||
static void guest_code(void)
|
||||
{
|
||||
/*
|
||||
* Software BP tests.
|
||||
*
|
||||
* NOTE: sw_bp need to be before the cmd here, because int3 is an
|
||||
* exception rather than a normal trap for KVM_SET_GUEST_DEBUG (we
|
||||
* capture it using the vcpu exception bitmap).
|
||||
*/
|
||||
asm volatile("sw_bp: int3");
|
||||
|
||||
/* Hardware instruction BP test */
|
||||
asm volatile("hw_bp: nop");
|
||||
|
||||
/* Hardware data BP test */
|
||||
asm volatile("mov $1234,%%rax;\n\t"
|
||||
"mov %%rax,%0;\n\t write_data:"
|
||||
: "=m" (guest_value) : : "rax");
|
||||
|
||||
/* Single step test, covers 2 basic instructions and 2 emulated */
|
||||
asm volatile("ss_start: "
|
||||
"xor %%rax,%%rax\n\t"
|
||||
"cpuid\n\t"
|
||||
"movl $0x1a0,%%ecx\n\t"
|
||||
"rdmsr\n\t"
|
||||
: : : "rax", "ecx");
|
||||
|
||||
/* DR6.BD test */
|
||||
asm volatile("bd_start: mov %%dr0, %%rax" : : : "rax");
|
||||
GUEST_DONE();
|
||||
}
|
||||
|
||||
#define CLEAR_DEBUG() memset(&debug, 0, sizeof(debug))
|
||||
#define APPLY_DEBUG() vcpu_set_guest_debug(vm, VCPU_ID, &debug)
|
||||
#define CAST_TO_RIP(v) ((unsigned long long)&(v))
|
||||
#define SET_RIP(v) do { \
|
||||
vcpu_regs_get(vm, VCPU_ID, ®s); \
|
||||
regs.rip = (v); \
|
||||
vcpu_regs_set(vm, VCPU_ID, ®s); \
|
||||
} while (0)
|
||||
#define MOVE_RIP(v) SET_RIP(regs.rip + (v));
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct kvm_guest_debug debug;
|
||||
unsigned long long target_dr6, target_rip;
|
||||
struct kvm_regs regs;
|
||||
struct kvm_run *run;
|
||||
struct kvm_vm *vm;
|
||||
struct ucall uc;
|
||||
uint64_t cmd;
|
||||
int i;
|
||||
/* Instruction lengths starting at ss_start */
|
||||
int ss_size[4] = {
|
||||
3, /* xor */
|
||||
2, /* cpuid */
|
||||
5, /* mov */
|
||||
2, /* rdmsr */
|
||||
};
|
||||
|
||||
if (!kvm_check_cap(KVM_CAP_SET_GUEST_DEBUG)) {
|
||||
print_skip("KVM_CAP_SET_GUEST_DEBUG not supported");
|
||||
return 0;
|
||||
}
|
||||
|
||||
vm = vm_create_default(VCPU_ID, 0, guest_code);
|
||||
vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid());
|
||||
run = vcpu_state(vm, VCPU_ID);
|
||||
|
||||
/* Test software BPs - int3 */
|
||||
CLEAR_DEBUG();
|
||||
debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP;
|
||||
APPLY_DEBUG();
|
||||
vcpu_run(vm, VCPU_ID);
|
||||
TEST_ASSERT(run->exit_reason == KVM_EXIT_DEBUG &&
|
||||
run->debug.arch.exception == BP_VECTOR &&
|
||||
run->debug.arch.pc == CAST_TO_RIP(sw_bp),
|
||||
"INT3: exit %d exception %d rip 0x%llx (should be 0x%llx)",
|
||||
run->exit_reason, run->debug.arch.exception,
|
||||
run->debug.arch.pc, CAST_TO_RIP(sw_bp));
|
||||
MOVE_RIP(1);
|
||||
|
||||
/* Test instruction HW BP over DR[0-3] */
|
||||
for (i = 0; i < 4; i++) {
|
||||
CLEAR_DEBUG();
|
||||
debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP;
|
||||
debug.arch.debugreg[i] = CAST_TO_RIP(hw_bp);
|
||||
debug.arch.debugreg[7] = 0x400 | (1UL << (2*i+1));
|
||||
APPLY_DEBUG();
|
||||
vcpu_run(vm, VCPU_ID);
|
||||
target_dr6 = 0xffff0ff0 | (1UL << i);
|
||||
TEST_ASSERT(run->exit_reason == KVM_EXIT_DEBUG &&
|
||||
run->debug.arch.exception == DB_VECTOR &&
|
||||
run->debug.arch.pc == CAST_TO_RIP(hw_bp) &&
|
||||
run->debug.arch.dr6 == target_dr6,
|
||||
"INS_HW_BP (DR%d): exit %d exception %d rip 0x%llx "
|
||||
"(should be 0x%llx) dr6 0x%llx (should be 0x%llx)",
|
||||
i, run->exit_reason, run->debug.arch.exception,
|
||||
run->debug.arch.pc, CAST_TO_RIP(hw_bp),
|
||||
run->debug.arch.dr6, target_dr6);
|
||||
}
|
||||
/* Skip "nop" */
|
||||
MOVE_RIP(1);
|
||||
|
||||
/* Test data access HW BP over DR[0-3] */
|
||||
for (i = 0; i < 4; i++) {
|
||||
CLEAR_DEBUG();
|
||||
debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP;
|
||||
debug.arch.debugreg[i] = CAST_TO_RIP(guest_value);
|
||||
debug.arch.debugreg[7] = 0x00000400 | (1UL << (2*i+1)) |
|
||||
(0x000d0000UL << (4*i));
|
||||
APPLY_DEBUG();
|
||||
vcpu_run(vm, VCPU_ID);
|
||||
target_dr6 = 0xffff0ff0 | (1UL << i);
|
||||
TEST_ASSERT(run->exit_reason == KVM_EXIT_DEBUG &&
|
||||
run->debug.arch.exception == DB_VECTOR &&
|
||||
run->debug.arch.pc == CAST_TO_RIP(write_data) &&
|
||||
run->debug.arch.dr6 == target_dr6,
|
||||
"DATA_HW_BP (DR%d): exit %d exception %d rip 0x%llx "
|
||||
"(should be 0x%llx) dr6 0x%llx (should be 0x%llx)",
|
||||
i, run->exit_reason, run->debug.arch.exception,
|
||||
run->debug.arch.pc, CAST_TO_RIP(write_data),
|
||||
run->debug.arch.dr6, target_dr6);
|
||||
/* Rollback the 4-bytes "mov" */
|
||||
MOVE_RIP(-7);
|
||||
}
|
||||
/* Skip the 4-bytes "mov" */
|
||||
MOVE_RIP(7);
|
||||
|
||||
/* Test single step */
|
||||
target_rip = CAST_TO_RIP(ss_start);
|
||||
target_dr6 = 0xffff4ff0ULL;
|
||||
vcpu_regs_get(vm, VCPU_ID, ®s);
|
||||
for (i = 0; i < (sizeof(ss_size) / sizeof(ss_size[0])); i++) {
|
||||
target_rip += ss_size[i];
|
||||
CLEAR_DEBUG();
|
||||
debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP;
|
||||
debug.arch.debugreg[7] = 0x00000400;
|
||||
APPLY_DEBUG();
|
||||
vcpu_run(vm, VCPU_ID);
|
||||
TEST_ASSERT(run->exit_reason == KVM_EXIT_DEBUG &&
|
||||
run->debug.arch.exception == DB_VECTOR &&
|
||||
run->debug.arch.pc == target_rip &&
|
||||
run->debug.arch.dr6 == target_dr6,
|
||||
"SINGLE_STEP[%d]: exit %d exception %d rip 0x%llx "
|
||||
"(should be 0x%llx) dr6 0x%llx (should be 0x%llx)",
|
||||
i, run->exit_reason, run->debug.arch.exception,
|
||||
run->debug.arch.pc, target_rip, run->debug.arch.dr6,
|
||||
target_dr6);
|
||||
}
|
||||
|
||||
/* Finally test global disable */
|
||||
CLEAR_DEBUG();
|
||||
debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP;
|
||||
debug.arch.debugreg[7] = 0x400 | DR7_GD;
|
||||
APPLY_DEBUG();
|
||||
vcpu_run(vm, VCPU_ID);
|
||||
target_dr6 = 0xffff0ff0 | DR6_BD;
|
||||
TEST_ASSERT(run->exit_reason == KVM_EXIT_DEBUG &&
|
||||
run->debug.arch.exception == DB_VECTOR &&
|
||||
run->debug.arch.pc == CAST_TO_RIP(bd_start) &&
|
||||
run->debug.arch.dr6 == target_dr6,
|
||||
"DR7.GD: exit %d exception %d rip 0x%llx "
|
||||
"(should be 0x%llx) dr6 0x%llx (should be 0x%llx)",
|
||||
run->exit_reason, run->debug.arch.exception,
|
||||
run->debug.arch.pc, target_rip, run->debug.arch.dr6,
|
||||
target_dr6);
|
||||
|
||||
/* Disable all debug controls, run to the end */
|
||||
CLEAR_DEBUG();
|
||||
APPLY_DEBUG();
|
||||
|
||||
vcpu_run(vm, VCPU_ID);
|
||||
TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, "KVM_EXIT_IO");
|
||||
cmd = get_ucall(vm, VCPU_ID, &uc);
|
||||
TEST_ASSERT(cmd == UCALL_DONE, "UCALL_DONE");
|
||||
|
||||
kvm_vm_free(vm);
|
||||
|
||||
return 0;
|
||||
}
|
1
tools/testing/selftests/vm/.gitignore
vendored
1
tools/testing/selftests/vm/.gitignore
vendored
@@ -6,6 +6,7 @@ map_populate
|
||||
thuge-gen
|
||||
compaction_test
|
||||
mlock2-tests
|
||||
mremap_dontunmap
|
||||
on-fault-limit
|
||||
transhuge-stress
|
||||
userfaultfd
|
||||
|
@@ -74,8 +74,6 @@ int main(int argc, char **argv)
|
||||
int write = 0;
|
||||
int reserve = 1;
|
||||
|
||||
unsigned long i;
|
||||
|
||||
if (signal(SIGINT, sig_handler) == SIG_ERR)
|
||||
err(1, "\ncan't catch SIGINT\n");
|
||||
|
||||
|
@@ -44,7 +44,7 @@ endef
|
||||
$(eval $(call tar_download,MUSL,musl,1.2.0,.tar.gz,https://musl.libc.org/releases/,c6de7b191139142d3f9a7b5b702c9cae1b5ee6e7f57e582da9328629408fd4e8))
|
||||
$(eval $(call tar_download,IPERF,iperf,3.7,.tar.gz,https://downloads.es.net/pub/iperf/,d846040224317caf2f75c843d309a950a7db23f9b44b94688ccbe557d6d1710c))
|
||||
$(eval $(call tar_download,BASH,bash,5.0,.tar.gz,https://ftp.gnu.org/gnu/bash/,b4a80f2ac66170b2913efbfb9f2594f1f76c7b1afd11f799e22035d63077fb4d))
|
||||
$(eval $(call tar_download,IPROUTE2,iproute2,5.4.0,.tar.xz,https://www.kernel.org/pub/linux/utils/net/iproute2/,fe97aa60a0d4c5ac830be18937e18dc3400ca713a33a89ad896ff1e3d46086ae))
|
||||
$(eval $(call tar_download,IPROUTE2,iproute2,5.6.0,.tar.xz,https://www.kernel.org/pub/linux/utils/net/iproute2/,1b5b0e25ce6e23da7526ea1da044e814ad85ba761b10dd29c2b027c056b04692))
|
||||
$(eval $(call tar_download,IPTABLES,iptables,1.8.4,.tar.bz2,https://www.netfilter.org/projects/iptables/files/,993a3a5490a544c2cbf2ef15cf7e7ed21af1845baf228318d5c36ef8827e157c))
|
||||
$(eval $(call tar_download,NMAP,nmap,7.80,.tar.bz2,https://nmap.org/dist/,fcfa5a0e42099e12e4bf7a68ebe6fde05553383a682e816a7ec9256ab4773faa))
|
||||
$(eval $(call tar_download,IPUTILS,iputils,s20190709,.tar.gz,https://github.com/iputils/iputils/archive/s20190709.tar.gz/#,a15720dd741d7538dd2645f9f516d193636ae4300ff7dbc8bfca757bf166490a))
|
||||
|
Reference in New Issue
Block a user