void s390_cpu_recompute_watchpoints(CPUState *cs) { const int wp_flags = BP_CPU | BP_MEM_WRITE | BP_STOP_BEFORE_ACCESS; S390CPU *cpu = S390_CPU(cs); CPUS390XState *env = &cpu->env; /* We are called when the watchpoints have changed. First remove them all. */ cpu_watchpoint_remove_all(cs, BP_CPU); /* Return if PER is not enabled */ if (!(env->psw.mask & PSW_MASK_PER)) { return; } /* Return if storage-alteration event is not enabled. */ if (!(env->cregs[9] & PER_CR9_EVENT_STORE)) { return; } if (env->cregs[10] == 0 && env->cregs[11] == -1LL) { /* We can't create a watchoint spanning the whole memory range, so split it in two parts. */ cpu_watchpoint_insert(cs, 0, 1ULL << 63, wp_flags, NULL); cpu_watchpoint_insert(cs, 1ULL << 63, 1ULL << 63, wp_flags, NULL); } else if (env->cregs[10] > env->cregs[11]) { /* The address range loops, create two watchpoints. */ cpu_watchpoint_insert(cs, env->cregs[10], -env->cregs[10], wp_flags, NULL); cpu_watchpoint_insert(cs, 0, env->cregs[11] + 1, wp_flags, NULL); } else { /* Default case, create a single watchpoint. */ cpu_watchpoint_insert(cs, env->cregs[10], env->cregs[11] - env->cregs[10] + 1, wp_flags, NULL); } }
static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type) { CPUState *cpu; CPUArchState *env; int err = 0; if (kvm_enabled()) { return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type); } switch (type) { case GDB_BREAKPOINT_SW: case GDB_BREAKPOINT_HW: for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { env = cpu->env_ptr; err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL); if (err) break; } return err; #ifndef CONFIG_USER_ONLY case GDB_WATCHPOINT_WRITE: case GDB_WATCHPOINT_READ: case GDB_WATCHPOINT_ACCESS: for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { env = cpu->env_ptr; err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type], NULL); if (err) break; } return err; #endif default: return -ENOSYS; } }
static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type) { CPUState *cpu; int err = 0; if (kvm_enabled()) { return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type); } switch (type) { case GDB_BREAKPOINT_SW: case GDB_BREAKPOINT_HW: CPU_FOREACH(cpu) { err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL); if (err) { break; } } return err; #ifndef CONFIG_USER_ONLY case GDB_WATCHPOINT_WRITE: case GDB_WATCHPOINT_READ: case GDB_WATCHPOINT_ACCESS: CPU_FOREACH(cpu) { err = cpu_watchpoint_insert(cpu, addr, len, xlat_gdb_type(cpu, type), NULL); if (err) { break; } } return err; #endif default: return -ENOSYS; } }